/* einfachhochzeit / einfachfeier — Verleih-Buchung
   ---------------------------------------------------------------------------
   Kalender, Warenkorb und Kasse. Baut vollstaendig auf den Tokens aus
   style.css auf (--accent, --line, --radius, --serif ...), damit beide Marken
   dieselbe Datei benutzen koennen: einfachfeier setzt dieselben Variablen auf
   Terrakotta, und der Kalender geht ohne eine einzige Aenderung mit.

   Bewusst NICHT ueber den [id^="eh-"]-Adapter aus tools.css: der bildet die
   alten Rechner-Variablen (--gold, --cream) auf die Seitentokens ab. Die
   Buchung ist Kernseite und benutzt die Tokens direkt.

   Klassen sind mit .vl- praefixiert, damit nichts mit den Utility-Klassen der
   Seite kollidiert. */

/* --- Grundgeruest ------------------------------------------------------- */

.vl {
  --vl-frei: #6f7d5c;
  --vl-frei-flaeche: #edf0e6;
  --vl-knapp: #b0791f;
  --vl-knapp-flaeche: #fbf1dd;
  --vl-weg: #a4453c;
  --vl-weg-flaeche: #f7eceb;
  font-family: var(--sans);
  color: var(--ink);
}

.vl *,
.vl *::before,
.vl *::after { box-sizing: border-box; }

/* Feste Artikelliste vor dem Aufbau (index.html bzw. verleih/buchen.html):
   schlicht, weil sie meist nur einen Augenblick steht. */
.vl-statisch-liste { list-style: none; margin: 12px 0 0; padding: 0; }
.vl-statisch-liste li + li { border-top: 1px solid var(--line); }
.vl-statisch-liste a {
  display: flex; flex-direction: column; gap: 2px; padding: 12px 2px;
  color: var(--ink); text-decoration: none;
}
.vl-statisch-liste span { font-size: .9rem; color: var(--ink-soft); }
.vl-statisch-liste a:hover strong { color: var(--accent-deep); }
.vl-fehler + .vl-statisch .vl-lade { display: none; }

.vl-lade {
  display: flex; align-items: center; justify-content: center; gap: 10px;
  min-height: 220px; color: var(--muted); font-size: .95rem;
}

.vl-lade::before {
  content: ""; width: 18px; height: 18px; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--accent);
  animation: vl-dreh .8s linear infinite;
}

@keyframes vl-dreh { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .vl-lade::before { animation-duration: 3s; }
}

.vl-fehler {
  border: 1px solid var(--vl-weg); background: var(--vl-weg-flaeche);
  color: #7d302a; border-radius: var(--radius);
  padding: 14px 16px; font-size: .95rem; line-height: 1.5;
}

.vl-fehler strong { display: block; margin-bottom: 4px; }

/* --- Kalender ----------------------------------------------------------- */

.vl-kalender { --vl-zelle: 44px; }

.vl-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 14px;
}

.vl-monat {
  font-family: var(--serif); font-size: 1.15rem; font-weight: 600;
  margin: 0; text-align: center; flex: 1;
}

.vl-blaettern {
  width: 40px; height: 40px; flex: 0 0 auto;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); background: var(--surface);
  border-radius: 50%; cursor: pointer; color: var(--ink);
  font-size: 1.1rem; line-height: 1;
  transition: border-color .15s, background .15s;
}

.vl-blaettern:hover:not(:disabled) { border-color: var(--accent); background: var(--accent-soft); }
.vl-blaettern:disabled { opacity: .35; cursor: not-allowed; }
.vl-blaettern:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }

.vl-wochentage {
  display: grid; grid-template-columns: repeat(7, 1fr); gap: 4px;
  margin-bottom: 6px;
}

.vl-wochentage span {
  text-align: center; font-size: .72rem; letter-spacing: .08em;
  text-transform: uppercase; color: var(--muted); padding: 4px 0;
}

/* Ohne Abstand zwischen den Zellen, damit der gewaehlte Zeitraum als
   durchgehendes Band erscheinen kann statt als Reihe von Kacheln. */
.vl-raster { display: grid; grid-template-columns: repeat(7, 1fr); gap: 0; }

.vl-tag {
  aspect-ratio: 1; width: 100%; padding: 3px 0;
  display: block; border: 0; background: transparent;
  font: inherit; font-size: .95rem; cursor: pointer;
}
/* Die Farbe traegt die innere Flaeche, nicht der Knopf - so bleibt zwischen
   den Tagen Luft, waehrend das Band darunter durchlaeuft. */
.vl-tag > span:first-child {
  display: grid; place-items: center; width: 100%; height: 100%;
  border-radius: 10px; line-height: 1.1;
}

.vl-tag:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 2px; }

.vl-tag-zahl { font-variant-numeric: tabular-nums; line-height: 1; }

.vl-tag-rest {
  font-size: .6rem; line-height: 1; font-weight: 600;
  letter-spacing: .01em;
}

/* Zustaende. Die Restmenge erscheint, wenn es knapp wird - und an Tagen, die
   fuer die gewuenschte Stueckzahl nicht reichen, obwohl noch etwas da ist. An
   ruhigen Tagen verraet der Kalender die Auslastung des Betriebs weiterhin
   nicht. */

.vl-tag[data-status="frei"] > span:first-child { background: #d8ecc0; color: #37501f; }

.vl-tag[data-status="knapp"] > span:first-child { background: #f0f6e6; color: #5c7042; }
.vl-tag[data-status="knapp"] .vl-tag-rest { color: #5c7042; }

.vl-tag[data-status="ausgebucht"] > span:first-child { background: #e8e4da; color: #9a948a; cursor: not-allowed; }
.vl-tag[data-status="ausgebucht"] .vl-tag-zahl { text-decoration: line-through; opacity: .75; }
/* Die Zahl ist der Grund, warum der Tag ueberhaupt noch etwas sagt - sie
   darf nicht mit dem durchgestrichenen Datum verblassen. Deshalb eigene
   Farbe und volle Deckkraft, auch im gedimmten Tagesstreifen. */
.vl-tag[data-status="ausgebucht"] .vl-tag-rest {
  color: #6e6153; opacity: 1; text-decoration: none;
}

.vl-tag[data-status="zu_frueh"] > span:first-child,
.vl-tag[data-status="gesperrt"] > span:first-child {
  background: transparent; color: var(--muted); opacity: .5;
}

.vl-tag[disabled] { pointer-events: none; }

/* Tage der Nachbarmonate. Sie stehen mit im Raster, damit sich ein Zeitraum
   ueber die Monatsgrenze hinweg waehlen und ziehen laesst - blass, damit klar
   bleibt, welcher Monat gemeint ist. Die Deckkraft sitzt auf der inneren
   Flaeche, nicht auf dem Knopf: Der traegt das Band, und das soll nicht
   mitverblassen. */
.vl-tag[data-ausserhalb="ja"] > span:first-child { opacity: .4; }
.vl-tag[data-ausserhalb="ja"][data-im-zeitraum="ja"] > span:first-child { opacity: 1; }

/* --- Der gewaehlte Zeitraum als durchgehendes Band ----------------------
   Das Band liegt auf dem Knopf, die Tagesfarbe auf der inneren Flaeche.
   Rund wird es nur am Anfang und Ende des Zeitraums - und dort, wo die
   Woche umbricht, sonst haengt es an der Zeilenkante in der Luft. */

.vl-tag[data-im-zeitraum="ja"] { background: #4a5a34; border-radius: 0; }
.vl-tag[data-band-links="ja"]  { border-top-left-radius: 999px; border-bottom-left-radius: 999px; }
.vl-tag[data-band-rechts="ja"] { border-top-right-radius: 999px; border-bottom-right-radius: 999px; }
.vl-tag[data-im-zeitraum="ja"] > span:first-child { background: transparent; color: #eef2e6; }

/* Kein Ring um den Starttag: Im Papier-Stil markiert das Band den Zeitraum,
   und sein linkes Ende ist der Start. Ein zweiter Marker daneben stammt aus
   der alten Farbraster-Optik und sieht darin aus wie ein Fehler. */
.vl-tag[aria-pressed="true"] .vl-tag-rest { color: var(--accent-deep); }
.vl-tag[data-im-zeitraum="ja"] .vl-tag-rest { color: rgba(255,255,255,.85); }

.vl-tag[data-puffer="ja"]:not([data-im-zeitraum="ja"]) > span:first-child {
  background: repeating-linear-gradient(
    -45deg, var(--accent-soft), var(--accent-soft) 4px, #fff 4px, #fff 8px);
  color: var(--ink-soft);
}

/* --- Legende ------------------------------------------------------------ */

.vl-legende {
  display: flex; flex-wrap: wrap; gap: 6px 16px;
  margin-top: 14px; font-size: .8rem; color: var(--ink-soft);
}

.vl-legende span { display: inline-flex; align-items: center; gap: 6px; }

.vl-legende i {
  width: 12px; height: 12px; border-radius: 4px; border: 1px solid var(--line);
  display: inline-block; flex: 0 0 auto;
}

.vl-legende .vl-l-frei { background: var(--vl-frei-flaeche); border-color: #dbe3cf; }
.vl-legende .vl-l-knapp { background: var(--vl-knapp-flaeche); border-color: #e8d3a6; }
.vl-legende .vl-l-weg { background: var(--vl-weg-flaeche); border-color: #eddbd9; }
.vl-legende .vl-l-puffer {
  background: repeating-linear-gradient(
    -45deg, var(--accent-soft), var(--accent-soft) 3px, #fff 3px, #fff 6px);
}

/* --- Eingabezeilen ------------------------------------------------------ */

.vl-felder {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  margin-top: 20px;
}

/* Auf dem Handy stand jedes Feld fuer sich, und die Kasse war sechs
   Bildschirme hoch. Vorname/Nachname und Postleitzahl/Ort gehoeren paarweise
   in eine Zeile: Das sind zusammengehoerige Angaben, keins der vier braucht
   die volle Breite, und es spart rund 240 Pixel.

   Das Raster bleibt deshalb zweispaltig; Felder nehmen sich standardmaessig
   beide Spalten, nur die als Paar markierten teilen sich eine Zeile. */
@media (max-width: 520px) {
  .vl-felder { grid-template-columns: 1fr 1fr; column-gap: 10px; }
  .vl-felder > .vl-feld { grid-column: 1 / -1; }
  .vl-felder > .vl-feld--halb { grid-column: span 1; }
}

.vl-feld { display: flex; flex-direction: column; gap: 6px; }

/* Die Zeile unter Postleitzahl und Ort ---------------------------------------
   Sie stand frueher als <small> im Postleitzahlfeld und sah aus wie eine
   Fussnote - bei 69 Euro fuer Hin- und Rueckfahrt ist sie aber nach dem
   Mietwert der groesste Posten der Buchung. Jetzt laeuft sie ueber beide
   Spalten und traegt den Betrag rechts, wie jede Preiszeile dieser Seite.

   Drei Zustaende: ein leiser Hinweis, solange nichts feststeht; die
   Kostenkachel, sobald die Zone bekannt ist; eine Warnung ausserhalb des
   Liefergebiets. Bei Selbstabholung ist die Zeile ganz weg - das entscheidet
   das Skript, nicht das Stylesheet. */
.vl-zonezeile {
  grid-column: 1 / -1;
  margin-top: -4px;
  font-size: .82rem; color: var(--muted); line-height: 1.45;
}
.vl-zonezeile[hidden] { display: none; }

/* Rechnungszeile statt Kasten (25.09.2026): gestrichelte Linie darueber wie
   auf einem Beleg, kein Hintergrund, kein Rahmen - der gruene Kasten las
   sich unter den Eingabefeldern wie eine Fehlermeldung. */
.vl-zonezeile--wert {
  display: flex; align-items: center; gap: 10px;
  margin-top: 6px; padding: 12px 0 2px;
  border-top: 1px dashed var(--line); color: var(--ink);
}
.vl-zonezeile-symbol { flex: none; display: inline-flex; color: var(--accent); }
.vl-zonezeile-text { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.vl-zonezeile-text > span { font-size: .92rem; color: var(--ink); }
.vl-zonezeile-text small { font-size: .78rem; color: var(--muted); }
.vl-zonezeile--wert > strong {
  flex: none; font-size: 1rem; font-weight: 600; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}

.vl-zonezeile--warnung { color: var(--vl-weg); }

.vl-feld label { font-size: .85rem; font-weight: 600; color: var(--ink-soft); }
.vl-pflicht { font-weight: 400; color: var(--accent-deep); }   /* Stern wie auf der Kontaktseite */

/* Eingabefelder folgen NICHT der Fliesstextgroesse. Die waechst per clamp bis
   auf 18 Pixel, und bei 18 Pixeln passt "vorname.nachname@googlemail.com" in
   keines der Felder - der Kunde sieht beim Tippen nur einen Ausschnitt seiner
   eigenen Adresse und kann sie nicht mehr pruefen.

   Genau 16 Pixel, kein Pixel weniger: Darunter zoomt Safari auf dem iPhone
   beim Antippen selbsttaetig ins Feld hinein, und der Nutzer muss danach von
   Hand wieder herauszoomen. 16 ist die Grenze, an der das aufhoert. */
/* 44 statt 51 Pixel hoch (Noah, 25.09.2026 - "eher dick"): Die Hoehe kam
   vor allem aus der Zeilenhoehe des Fliesstexts, die die Felder erbten.
   44 ist die Untergrenze fuer ein sicheres Tippziel; die Schrift bleibt bei
   16 Pixeln, darunter zoomt iOS beim Antippen in die Seite. */
.vl-feld input,
.vl-feld select,
.vl-feld textarea {
  padding: 10px 13px; border: 1px solid var(--line); border-radius: 10px;
  font: inherit; font-size: 16px; line-height: 1.4; color: var(--ink); background: var(--surface);
  width: 100%; min-height: 44px;
}
.vl-feld textarea { line-height: 1.5; }

.vl-feld input:focus,
.vl-feld select:focus,
.vl-feld textarea:focus {
  outline: 2px solid var(--accent-deep); outline-offset: 1px; border-color: var(--accent);
}

.vl-feld small { font-size: .78rem; color: var(--muted); }

/* Pflichtfeld nach einem Klick auf "buchen" nicht ausgefuellt. Rot ist hier
   dasselbe --vl-weg wie im Kalender fuer "belegt" - eine Farbe fuer "geht so
   nicht". */
.vl-feld--fehler label { color: var(--vl-weg); }
.vl-feld.vl-feld--fehler input { border-color: var(--vl-weg); background: var(--vl-weg-flaeche); }
.vl-feld.vl-feld--fehler .vl-feldfehler { color: #7d302a; font-weight: 600; }
.vl-agb.vl-feld--fehler {
  outline: 1.5px solid var(--vl-weg); outline-offset: 6px;
  border-radius: 6px; background: var(--vl-weg-flaeche);
}

.vl-feld--voll { grid-column: 1 / -1; }

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

.vl-summe {
  margin-top: 18px; padding: 16px; border-radius: var(--radius);
  background: var(--accent-soft); border: 1px solid #dbe3cf;
}

.vl-zeile {
  display: flex; justify-content: space-between; gap: 12px;
  padding: 5px 0; font-size: .92rem; color: var(--ink-soft);
}

.vl-zeile span:last-child { font-variant-numeric: tabular-nums; white-space: nowrap; }

.vl-zeile--gesamt {
  border-top: 1px solid #dbe3cf; margin-top: 8px; padding-top: 12px;
  font-family: var(--serif); font-size: 1.2rem; font-weight: 600; color: var(--ink);
}

/* Abholung und Lieferung unter der Summe: keine Posten, sondern der
   Hinweis, was ohne Aufpreis geht und was sich noch dazubuchen laesst.
   Die erste Zeile traegt den Preis und steht deshalb kraeftiger. */
.vl-abwicklung {
  margin: 8px 0 0; font-size: .85rem; color: var(--ink-soft); line-height: 1.4;
  text-align: center;
}
.vl-abwicklung strong { color: var(--accent-deep); font-weight: 600; }
.vl-abwicklung--leise { margin-top: 1px; font-size: .8rem; color: var(--muted); }

/* Der Abzug ist die einzige Zeile mit einem Minus davor - sie darf sich
   farblich von den Aufschlaegen darueber unterscheiden. */
.vl-zeile--rabatt { color: var(--accent-deep); font-weight: 600; }

/* Rabattcode. Steht zwischen Summe und AGB-Haken und soll dort ruhig
   wirken: Wer keinen Code hat, soll nicht das Gefuehl bekommen, etwas zu
   verpassen. Deshalb kein Rahmen, keine Farbe, kein Ausrufezeichen. */
.vl-code { margin-top: 16px; }
.vl-code input { text-transform: uppercase; letter-spacing: .04em; }
.vl-code input::placeholder { text-transform: none; letter-spacing: normal; }

.vl-hinweis {
  margin: 10px 0 0; padding: 10px 12px; border-radius: 10px;
  background: var(--vl-knapp-flaeche); border: 1px solid #e8d3a6;
  color: #7d5510; font-size: .87rem; line-height: 1.45;
}
/* Gueltiger Rabattcode: Bestaetigung am Feld im Gruen der Kalender-
   Verfuegbarkeit statt im Gelb der Hinweise. */
.vl-code-hinweis--ok { background: var(--vl-frei-flaeche); border-color: #dbe3cf; color: var(--accent-deep); }
.vl-zeile-link { color: var(--accent-deep); text-decoration: underline; text-underline-offset: 3px; }

/* Eine Aussage je Zeile: Kern fett, Nachsatz darunter. Mehrere Hinweise
   trennt eine Linie - ein Aufzaehlungszeichen behauptet bei einem einzelnen
   eine Liste, die keine ist. */
.vl-hinweis-wert {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  margin: 0; font-weight: 600;
}
.vl-hinweis-wert strong { font-size: 1.02rem; font-variant-numeric: tabular-nums; }
.vl-hinweis-satz { margin: 2px 0 0; font-size: .82rem; opacity: .85; }
.vl-hinweis-wert + .vl-hinweis-satz { margin-top: 1px; }
.vl-hinweis-satz + .vl-hinweis-satz {
  margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(125, 85, 16, .18);
}

/* Alte Aufzaehlung: Die Kasse und der Warenkorb benutzen denselben Kasten. */
.vl-hinweis ul { margin: 4px 0 0; padding-left: 18px; }

.vl-aktionen { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }
.vl-aktionen .btn { flex: 1 1 200px; }

/* Gesperrt, aber anklickbar: Ein Knopf mit disabled nimmt keinen Klick an und
   kann deshalb nicht sagen, warum er nicht geht. Mit aria-disabled sieht er
   gesperrt aus, bleibt aber bedienbar - und antwortet mit dem Grund. */
.vl-aktionen .btn[aria-disabled="true"] {
  opacity: .5; box-shadow: none; cursor: not-allowed;
}
.vl-aktionen .btn[aria-disabled="true"]:hover { transform: none; }
.vl-aktionen .btn--primary[aria-disabled="true"]:hover { background: var(--accent-deep); }

.vl-aktionen-grund {
  flex: 1 1 100%; margin: 2px 0 0;
  font-size: .86rem; line-height: 1.45; color: #a4453c;
  text-align: center;
}
.vl-aktionen-grund[hidden] { display: none; }

/* --- Warenkorb ---------------------------------------------------------- */

/* Karte "Eure Auswahl" (Noah, 25.09.2026): dieselbe Sprache wie das
   Warenkorb-Panel im Seitenkopf - Zeitraum als Pille, Artikel mit Foto,
   Rechnung und Summe in einem hellen Fussbereich. */
.vl-korb {
  border: 1px solid var(--line); border-radius: 18px; background: var(--surface);
  box-shadow: 0 14px 40px rgba(34, 33, 29, .07); overflow: hidden;
}

.vl-korb-kopf {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 8px 10px; padding: 16px 18px 14px;
}
.vl-korb-kopf h3 { margin: 0; font-family: var(--serif); font-weight: 500; font-size: 1.15rem; }

.vl-korb-liste { padding: 0 18px; }
.vl-pos {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: 12px;
  padding: 12px 0; border-top: 1px solid var(--line);
}
/* Dieselbe Kachel wie im Panel: Die Produktfotos sind freigestellt und
   ueberwiegend weiss - ohne Hintergrund verschwinden Stuhl und Stehtisch. */
.vl-pos-bild {
  width: 48px; height: 48px; border-radius: 10px; background: var(--bg-2); overflow: hidden;
}
.vl-pos-bild img { width: 100%; height: 100%; object-fit: contain; display: block; }
.vl-pos-name { font-size: .92rem; font-weight: 600; line-height: 1.25; }
.vl-pos-detail {
  display: block; margin-top: 2px; font-weight: 400; font-size: .78rem; color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.vl-pos-preis {
  font-size: .92rem; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
}

.vl-weg-knopf {
  width: 26px; height: 26px; padding: 0; border: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: none; cursor: pointer; color: var(--muted); font-size: 1.1rem; line-height: 1;
  transition: background-color .15s ease, color .15s ease;
}
.vl-weg-knopf:hover { color: var(--ink); background: var(--bg-2); }
.vl-weg-knopf:focus-visible { outline: 2px solid var(--accent-deep); }
.vl-weg-knopf svg { width: 10px; height: 10px; display: block; }
/* Wie im Warenkorb des Seitenkopfs (style.css): am Rechner nur beim
   Darueberfahren, am Handy wird gewischt. */
@media (hover: hover) and (pointer: fine) {
  .vl-weg-knopf { opacity: 0; transition: opacity .15s ease, background-color .15s ease, color .15s ease; }
  .vl-pos:hover .vl-weg-knopf, .vl-weg-knopf:focus-visible { opacity: 1; }
}
@media not all and (hover: hover) and (pointer: fine) {
  .vl-pos { grid-template-columns: auto minmax(0, 1fr) auto; touch-action: pan-y; }
}
/* Platzhalter der entfernten Zeile - so hoch wie eine Artikelzeile. */
.vl-pos.vl-pos--entfernt {
  display: flex; justify-content: space-between; min-height: 73px;
  font-size: .86rem; color: var(--ink-soft);
}
.vl-zurueck-knopf {
  flex: none; padding: 6px 10px; margin-right: -10px;
  border: 0; border-radius: 999px; background: none; cursor: pointer;
  font: inherit; font-size: .86rem; font-weight: 600; color: var(--accent-deep);
  text-decoration: underline; text-underline-offset: 3px;
}
.vl-zurueck-knopf:hover { background: var(--bg); }
.vl-zurueck-knopf:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

.vl-korb-fuss { background: var(--bg); border-top: 1px solid var(--line); padding: 14px 18px 18px; }
.vl-korb-zeile {
  display: flex; justify-content: space-between; gap: 12px; margin: 0; padding: 3px 0;
  font-size: .84rem; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.vl-korb-zeile small { color: var(--muted); font-size: inherit; }
.vl-korb-summe {
  display: flex; justify-content: space-between; align-items: baseline; gap: 12px; margin: 0 0 14px;
}
.vl-korb-zeile + .vl-korb-summe { margin-top: 8px; padding-top: 10px; border-top: 1px dashed var(--line); }
.vl-korb-summe > span:first-child { font-weight: 600; }
.vl-korb-summe-betrag {
  font-family: var(--serif); font-weight: 500; font-size: 1.6rem; line-height: 1.1;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.vl-korb-fuss .vl-schwelle { margin: 0 0 12px; text-align: center; }

.vl-leer-text { padding: 28px 18px; text-align: center; color: var(--muted); }

/* --- Artikelliste auf der Buchungsseite --------------------------------- */

.vl-artikel {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 14px;
}

.vl-artikel-karte {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: 16px;
  display: flex; flex-direction: column; gap: 8px;
}

.vl-artikel-karte h3 { margin: 0; font-size: 1rem; }
.vl-artikel-karte .vl-preis { color: var(--accent-deep); font-weight: 600; }
.vl-artikel-karte p { margin: 0; font-size: .85rem; color: var(--ink-soft); line-height: 1.45; }
.vl-artikel-karte .vl-status { margin-top: auto; }

.vl-marke {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: .78rem; font-weight: 600; padding: 3px 9px; border-radius: 999px;
}

.vl-marke[data-status="frei"] { background: var(--vl-frei-flaeche); color: var(--accent-deep); }
.vl-marke[data-status="knapp"] { background: var(--vl-knapp-flaeche); color: #7d5510; }
.vl-marke[data-status="ausgebucht"] { background: var(--vl-weg-flaeche); color: #a4453c; }
.vl-marke[data-status="anfrage"] { background: var(--bg-2); color: var(--ink-soft); }

/* --- Kasse -------------------------------------------------------------- */

.vl-kasse { display: grid; grid-template-columns: 1.4fr 1fr; gap: clamp(20px, 3vw, 36px); align-items: start; }

@media (max-width: 900px) { .vl-kasse { grid-template-columns: 1fr; } }

.vl-block {
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); padding: clamp(18px, 2.5vw, 26px);
  margin-bottom: 18px;
}

.vl-block h3 { margin: 0 0 4px; font-size: 1.05rem; }
.vl-block > p { margin: 0 0 16px; font-size: .88rem; color: var(--muted); }
/* Ueberschrift mit der Legende zum Pflichtfeld-Stern rechts daneben. */
.vl-block-kopf {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin: 0 0 16px;
}
.vl-block-kopf h3 { margin: 0; }
.vl-pflicht-legende { flex: none; font-size: .8rem; color: var(--muted); white-space: nowrap; }

/* Die Zusammenfassung klebt beim Scrollen mit. Ist sie hoeher als das
   Fenster - viele Positionen im Korb oder ein flacher Laptopbildschirm -,
   schob sich ihr unteres Ende am Seitenende unter den Seitenkopf: Der Knopf
   "zahlungspflichtig buchen" lag dann halb hinter dem Glas des Kopfes. Die
   Hoehengrenze haelt den Kasten vollstaendig im Bild; passt er ohnehin,
   aendert sie nichts. */
.vl-seitlich {
  position: sticky; top: 90px;
  max-height: calc(100vh - 110px); overflow: auto;
}

/* Ohne Platz daneben klebt nichts mehr - und ohne Klebstoff braucht der
   Kasten auch keine Hoehengrenze. */
@media (max-width: 900px) {
  .vl-seitlich { position: static; max-height: none; overflow: visible; }
}

/* overflow: auto schneidet alles ab, was ueber den Rand der Spalte ragt -
   auch den Schatten der Korbkarte (14px nach unten, 40px weich). Unten
   endete er deshalb als harte Kante, die Karte wirkte abgeschnitten.
   Innenrand gibt dem Schatten Platz, der negative Aussenrand nimmt ihn
   wieder weg: Die Karte bleibt, wo sie war. Die Hoehengrenze waechst um
   denselben Innenrand, damit unten weiterhin 20px Luft bis zum Fensterrand
   bleiben. */
@media (min-width: 901px) {
  .vl-seitlich--korb {
    padding: 0 28px 56px; margin: 0 -28px -56px;
    max-height: calc(100vh - 54px);
  }
}

/* In der Kasse gleitet er mit - ohne Hoehengrenze und ohne eigenen
   Rollbalken.

   Die Zusammenfassung ist dort 800 bis 900 Pixel hoch. Mit der Hoehengrenze
   oben bekam sie auf jedem Laptop einen zweiten Rollbalken neben dem der
   Seite, deshalb klebte sie eine Zeit lang gar nicht. Seit 25.09.2026 setzt
   verleih-checkout.js (seitlichKleben) den Abstand: Passt der Kasten ins
   Fenster, klebt er unter dem Kopf; ist er hoeher, wird der Abstand negativ,
   der Kasten scrollt bis zum Buchen-Knopf mit und bleibt dann stehen.
   Nicht ueber .vl-kasse auswaehlen: Die Startseite benutzt denselben
   Wrapper, ihre Korbspalte traegt --korb und klebt nach der Regel oben. */
.vl-seitlich:not(.vl-seitlich--korb) {
  top: var(--kleben-oben, 90px);
  max-height: none; overflow: visible;
}
@media (max-width: 900px) {
  .vl-seitlich:not(.vl-seitlich--korb) { position: static; }
}

/* Handy: der Artikelblock wandert ans Ende der Spalte ------------------------
   Am Rechner stehen Korb und Rechnung nebeneinander, und die Rechnung rechts
   liest sich als Beleg zum Korb links. Unter 900 Pixeln klappt das Raster auf
   eine Spalte - dann liegen zwischen beiden Listen rund 2200 Pixel, knapp drei
   Bildschirmhoehen, und aus dem Nebeneinander wird eine Wiederholung.

   Also genau eine Artikelliste auf dem Handy, und zwar die brauchbare: die mit
   Bild, Mengenregler und Zeilenpreis. Sie steht unmittelbar ueber der
   Zusammenfassung mit dem Buchen-Knopf - dort, wo Paragraph 312j Absatz 2 BGB
   die wesentlichen Merkmale verlangt. Was der Korbsymbol-Weg dabei einbuesst -
   den Blick auf den Korb beim Ankommen - faengt die Preisleiste unten auf. */
@media (max-width: 900px) {
  .vl-haupt { display: flex; flex-direction: column; }
  .vl-block--artikel { order: 1; }
}

/* Die Positionen stehen in der Uebersicht ueberall, auch auf dem Handy: Sie
   sitzt unmittelbar ueber dem Buchen-Knopf, und dort verlangt Paragraph 312j
   Abs. 2 BGB die Artikel (Noah, 03.10.2026). Die Sammelzeile bleibt aus. */
.vl-zeile--warenwert { display: none; }

/* Die Preisleiste erbt Rahmen, Lage und Hoehenmeldung von .vl-korbleiste -
   sie traegt beide Klassen. Eigen ist ihr nur die rechte Haelfte: Die
   Korbleiste klappt auf, diese hier springt. */
.vl-preisleiste-hin {
  flex: none; font-size: .82rem; font-weight: 600;
  color: var(--accent-deep); white-space: nowrap;
}
.vl-preisleiste-hin::after { content: " \2193"; }

/* Einzeilig: nur "Gesamt 880,80 €" und der Sprung. Etwas flacher als die
   Korbleiste der Startseite, die zwei Zeilen und ein Aufklappen traegt. */
.vl-preisleiste .vl-korbleiste-kopf { padding-top: 12px; padding-bottom: 12px; }
.vl-preisleiste .vl-korbleiste-zahlen strong { white-space: nowrap; }

/* Der Seitenkopf klebt. Ohne diesen Abstand landet die Zusammenfassung beim
   Sprung zur Haelfte dahinter. */
#vl-uebersicht { scroll-margin-top: 84px; }
/* Menge geaendert, Preis noch beim Server: Summe und Leiste treten zurueck,
   bis die Antwort da ist - die Zeilenpreise springen schon vorher um. */
#vl-uebersicht, .vl-preisleiste .vl-korbleiste-zahlen { transition: opacity .15s ease; }
.vl-preis-laedt #vl-uebersicht,
.vl-preis-laedt .vl-preisleiste .vl-korbleiste-zahlen { opacity: .45; }
/* Ziel von "Auswahl ändern" und der Zeilenlinks im Warenkorb-Panel: Ohne
   Abstand landet der Anfang der Buchungsbox unter dem fixierten Seitenkopf. */
#eh-verleih-widget, .pdp-buybox { scroll-margin-top: 96px; }

/* Waehrend der neue Preis unterwegs ist, bleibt der alte stehen - nur
   blasser, damit man sieht, dass er gleich wechselt. */
.vl-zusammenfassung .vl-preis { transition: opacity .15s ease; }
.vl-zusammenfassung.ist-rechnend .vl-preis { opacity: .45; }
.vl-zusammenfassung.ist-rechnend .vl-aktionen .btn { cursor: progress; }

/* Abholung oder Lieferung: zwei Kacheln nebeneinander, auch auf dem Handy
   (Noah, 25.09.2026). Symbol, Titel, Ort, Preis; die gewaehlte bekommt
   Salbeirand und einen Haken. Der Auswahlpunkt bleibt im Label fuer
   Tastatur und Screenreader, ist aber unsichtbar - sein Browser-Blau passte
   nicht zur Seite. */
.vl-wahl { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.vl-wahl-kachel {
  position: relative; cursor: pointer; min-width: 0;
  -webkit-tap-highlight-color: transparent; /* kein grauer Kasten beim Antippen am Handy */
}
.vl-wahl-kachel input {
  position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
}
.vl-wahl-inhalt {
  display: flex; flex-direction: column; align-items: flex-start; gap: 1px; height: 100%;
  padding: 12px 12px 11px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); transition: border-color .15s, background .15s;
}
.vl-wahl-kachel:hover .vl-wahl-inhalt { border-color: var(--accent); }
.vl-wahl-kachel input:checked + .vl-wahl-inhalt {
  border: 1.5px solid var(--accent-deep); padding: 11.5px 11.5px 10.5px;
  background: var(--accent-soft);
}
.vl-wahl-kachel input:focus-visible + .vl-wahl-inhalt { outline: 2px solid var(--accent); outline-offset: 2px; }
.vl-wahl-symbol { display: inline-flex; color: var(--muted); margin-bottom: 4px; }
.vl-wahl-kachel input:checked + .vl-wahl-inhalt .vl-wahl-symbol { color: var(--accent-deep); }
.vl-wahl-titel { font-size: .92rem; font-weight: 600; color: var(--ink); line-height: 1.25; }
.vl-wahl-inhalt small { font-size: .78rem; color: var(--muted); }
.vl-wahl-betrag {
  margin-top: 6px; font-size: .85rem; font-weight: 600; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.vl-wahl-kachel input:checked + .vl-wahl-inhalt .vl-wahl-betrag { color: var(--accent-deep); }
.vl-wahl-haken {
  position: absolute; top: 9px; right: 9px; width: 20px; height: 20px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  background: var(--accent-deep); color: #fff;
}
.vl-wahl-kachel input:checked + .vl-wahl-inhalt .vl-wahl-haken { display: inline-flex; }
/* Noch nichts gewaehlt und schon auf "buchen" gedrueckt: beide Kacheln rot
   umrandet wie ein leeres Eingabefeld, der Satz darunter. */
.vl-wahl.vl-wahl--fehler .vl-wahl-inhalt { border-color: var(--vl-weg); background: var(--vl-weg-flaeche); }
.vl-wahl-fehler { display: block; margin-top: 8px; font-size: .82rem; color: #7d302a; font-weight: 600; }

.vl-agb {
  display: flex; gap: 11px; align-items: flex-start;
  font-size: .88rem; line-height: 1.5; color: var(--ink-soft);
}

.vl-agb input { margin-top: 3px; flex: 0 0 auto; width: 18px; height: 18px; accent-color: var(--accent-deep); }
.vl-agb a { color: var(--accent-deep); font-weight: 600; }

/* Die Werbeeinwilligung steht getrennt von den AGB und traegt keinen eigenen
   Rahmen - sie soll als freiwilliger Zusatz lesbar sein, nicht als weitere
   Pflicht. */
.vl-werbung { margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); }
/* Die Uebersicht steht seit 03.10.2026 unter Rabattcode und Haekchen, direkt
   ueber dem Knopf - eine Linie trennt sie von den Haekchen darueber. */
.vl-seitlich #vl-uebersicht { margin-top: 20px; padding-top: 8px; border-top: 1px solid var(--line); }
/* 12 px, nicht kleiner: Der Hinweis muss klar und deutlich sein (Paragraph 7
   Abs. 3 Nr. 4 UWG) - ein absichtlich winziger Text waere der Angriffspunkt. */
.vl-werbung-hinweis { display: block; margin-top: 4px; font-size: .75rem; color: var(--muted); }

/* Die Erklaerung zum vorzeitigen Beginn steht unter dem AGB-Haekchen - mit
   demselben Abstand, den das AGB-Haekchen nach oben hat. Ohne ihn lagen die
   roten Rahmen zweier fehlender Haekchen uebereinander: Der Rahmen steht
   6 px ausserhalb (outline-offset), beide zusammen brauchen mindestens 12. */
.vl-vorzeitig { margin-top: 18px; }

/* --- Abweichende Lieferadresse -------------------------------------------
   Kaestchen und Felder sind Kinder des Rasters #vl-lieferfelder und muessen
   ueber beide Spalten laufen - sonst stuende das Kaestchen in der linken
   Haelfte und die Anschrift daneben in der rechten. */
/* Ort passt nicht zur Postleitzahl. Warnfarbe, aber kein Kasten und keine
   Sperre - es ist ein Verdacht, kein Fehler. */
.vl-feld small.vl-ortwarnung { color: var(--vl-weg); font-weight: 600; }

.vl-adresse-gleich, .vl-lieferanschrift { grid-column: 1 / -1; }
/* Kein eigenes Schriftgewicht: Die Beschriftung war fett, solange ein
   Erklaersatz darunter stand und sie dessen Ueberschrift war. Ohne ihn ist
   es ein Kaestchen wie die fuer AGB und Werbung weiter unten - und die sind
   normal gesetzt. Fett fiel nicht nur auf, es machte die Zeile auch so breit,
   dass sie auf dem Handy in zwei zerfiel.
   Mittig statt oben ausgerichtet, weil hier nur eine Zeile steht. */
.vl-adresse-gleich { margin-top: 16px; align-items: center; }
/* Enger an das Kaestchen heran, das sie aufklappt - das eigene margin-top
   von .vl-felder risse hier eine Luecke, die nach Abschnittswechsel aussieht. */
.vl-lieferanschrift { margin-top: 12px; }

/* Die Wunschzeit folgt der Anschrift und ist ein eigener Gedanke - sie darf
   den Abstand haben, den der Adressblock darueber bewusst nicht hat. */
.vl-lieferzeit-feld { grid-column: 1 / -1; margin-top: 18px; }

/* Die Beschriftung des Absendeknopfs ist rechtlich vorgegeben
   (Paragraph 312j Absatz 3 BGB, Buttonloesung). Der Knopf darf nicht
   umbenannt werden, ohne die Rechtsfolge zu pruefen: bei unzulaessiger
   Beschriftung kommt der Vertrag gar nicht zustande. */
.vl-buchen { margin-top: 18px; }
.vl-pflichthinweis {
  margin: 0 0 12px; font-size: .9rem; font-weight: 600; color: #7d302a; line-height: 1.45;
}
.vl-buchen .btn { width: 100%; font-size: 1.02rem; padding: 15px 20px; }
.vl-buchen small { display: block; margin-top: 10px; font-size: .78rem; color: var(--muted); line-height: 1.5; }

/* --- Bestaetigung ------------------------------------------------------- */

.vl-nummer {
  font-family: var(--serif); font-size: clamp(1.6rem, 4vw, 2.2rem);
  letter-spacing: .04em; color: var(--accent-deep);
  padding: 14px 22px; border: 2px dashed var(--accent);
  border-radius: var(--radius); background: var(--accent-soft);
  display: inline-block; margin: 6px 0 4px;
}

/* --- Ablauf nach der Buchung: vier Schritte mit Zeitangabe --- */
.vl-ablauf { margin: 0; padding: 0; list-style: none; counter-reset: vl-schritt; }
.vl-ablauf li {
  counter-increment: vl-schritt;
  display: grid; grid-template-columns: 34px 1fr; gap: 4px 14px;
  padding: 0 0 22px 0; position: relative;
}
.vl-ablauf li::before {
  content: counter(vl-schritt);
  grid-row: 1 / span 3; width: 34px; height: 34px; border-radius: 50%;
  display: grid; place-items: center; font-family: var(--serif); font-size: 1rem;
  background: var(--accent-soft); color: var(--accent-deep);
  border: 1.5px solid var(--accent);
}
.vl-ablauf li:not(:last-child)::after {
  content: ""; position: absolute; left: 16.25px; top: 40px; bottom: 6px;
  width: 2px; background: var(--line);
}
.vl-ablauf li strong { font-family: var(--serif); font-weight: 500; font-size: 1.05rem; color: var(--ink); }
.vl-ablauf-wann {
  font-size: .74rem; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--accent);
}
.vl-ablauf li > span:last-child { font-size: .92rem; line-height: 1.6; color: var(--ink-soft); }

/* --- Schwellenhinweis im Warenkorb --- */
.vl-schwelle { margin: 0; font-size: .86rem; line-height: 1.5; padding: 10px 12px; border-radius: 12px; }
.vl-schwelle--knapp { background: #fbf1dd; color: #8a5f13; }
.vl-schwelle--frei  { background: var(--accent-soft); color: var(--accent-deep); }

/* ===========================================================================
   Verfügbarkeitsprüfung auf der Startseite
   Zwei Spalten: links die Eingabe, rechts die Antwort. Auf dem Handy
   untereinander — Eingabe zuerst, weil die Antwort ohne sie leer bleibt.
   =========================================================================== */
.planer-band {
  padding-block: 0 clamp(44px, 6vw, 76px);
  background: linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 340px);
}
.planer-huelle { transform: translateY(clamp(-72px, -6vw, -32px)); position: relative; z-index: 2; }

.vl.startcheck {
  border-radius: 26px !important;
  box-shadow: 0 30px 60px -34px rgba(74, 64, 48, .5) !important;
  display: grid; grid-template-columns: minmax(0, 1fr);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow); overflow: hidden;
}
@media (min-width: 900px) { .vl.startcheck { grid-template-columns: 1fr 440px; } }

.startcheck-eingabe { padding: clamp(22px, 3vw, 36px) clamp(20px, 3vw, 40px); }
.startcheck-eingabe h2 { margin: 6px 0 0; font-size: clamp(1.5rem, 3vw, 2rem); }
.startcheck-intro { margin: 10px 0 0; max-width: 46ch; color: var(--ink-soft); }

.startcheck-felder { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 20px; }
.startcheck-felder .vl-feld { flex: 1 1 190px; }
.startcheck-felder .startcheck-dauer { flex: 0 1 170px; }
.startcheck-vorlauf { margin: 10px 0 0; font-size: .82rem; color: var(--muted); }

.startcheck-zusagen {
  display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 20px 0 0; padding: 18px 0 0;
  list-style: none; border-top: 1px solid var(--line);
}
.startcheck-zusagen li {
  display: flex; align-items: center; gap: 8px; font-size: .88rem; color: var(--ink-soft);
}
.startcheck-zusagen li::before {
  content: ""; width: 14px; height: 9px; flex: none;
  border-left: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg) translateY(-2px);
}

.startcheck-ergebnis {
  padding: clamp(22px, 3vw, 34px); background: var(--bg-2);
  border-top: 1px solid var(--line);
}
@media (min-width: 900px) {
  .startcheck-ergebnis { border-top: 0; border-left: 1px solid var(--line); }
}

.startcheck-leer { color: var(--muted); }
.startcheck-leer p { margin: 0 0 8px; font-size: .95rem; line-height: 1.6; }
.startcheck-leer strong { color: var(--ink); }

.startcheck-kopf { display: flex; flex-direction: column; gap: 2px; margin-bottom: 16px; }
.startcheck-kopf strong { font-size: .95rem; color: var(--ink); }
.startcheck-kopf span { font-size: .82rem; color: var(--muted); }

.startcheck-liste { list-style: none; margin: 0; padding: 0; display: grid; gap: 11px; }
.startcheck-liste li {
  display: grid; grid-template-columns: 1fr auto; gap: 1px 12px; align-items: baseline;
  padding-bottom: 11px; border-bottom: 1px solid var(--line);
}
.startcheck-liste li:last-child { border-bottom: 0; padding-bottom: 0; }
.startcheck-name { font-size: .95rem; font-weight: 600; color: var(--ink); }
.startcheck-preis { font-size: .84rem; color: var(--muted); white-space: nowrap; }
.startcheck-marke { grid-column: 1 / -1; font-size: .82rem; font-weight: 600; }
.startcheck-liste .ist-frei  .startcheck-marke { color: var(--vl-frei); }
.startcheck-liste .ist-knapp .startcheck-marke { color: var(--vl-knapp); }
.startcheck-liste .ist-weg   .startcheck-marke { color: var(--vl-weg); }
.startcheck-liste .ist-unklar .startcheck-marke { color: var(--muted); }

.startcheck-fazit {
  margin: 16px 0; padding: 11px 13px; border-radius: var(--radius);
  font-size: .88rem; line-height: 1.5;
}
.startcheck-fazit.ist-frei { background: var(--vl-frei-flaeche); color: var(--accent-deep); }
.startcheck-fazit.ist-teilweise { background: var(--vl-knapp-flaeche); color: var(--vl-knapp); }
.startcheck-fuss { margin: 10px 0 0; font-size: .8rem; color: var(--muted); text-align: center; line-height: 1.5; }

/* ===========================================================================
   Sortimentsleiste unter dem Planer
   =========================================================================== */
.sortiment-leiste { margin-top: clamp(-16px, -1vw, 0px); }
.sortiment-kopf {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 24px; margin-bottom: 22px;
}
.sortiment-kopf h2 { font-size: clamp(1.4rem, 2.6vw, 1.9rem); margin: 0; }
.sortiment-kopf a { font-size: .95rem; font-weight: 600; white-space: nowrap; }

.sortiment-gitter {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
}

.sortiment-kachel {
  display: flex; flex-direction: column; overflow: hidden; color: inherit;
  transition: transform .15s ease, box-shadow .15s ease;
}
.sortiment-kachel:hover { transform: translateY(-2px); box-shadow: var(--shadow); color: inherit; }
.sortiment-bild {
  display: grid; place-items: center; height: 116px; padding: 12px;
  background: radial-gradient(circle at 50% 42%, #ffffff 0%, var(--accent-soft) 100%);
  border-bottom: 1px solid var(--line);
}
.sortiment-bild img {
  max-height: 84px; max-width: 100%; width: auto; object-fit: contain;
  filter: drop-shadow(0 8px 12px rgba(74, 64, 48, .2));
}
.sortiment-daten { padding: 13px 14px 15px; display: flex; flex-direction: column; gap: 3px; flex: 1; }
.sortiment-name { font-size: .88rem; font-weight: 600; color: var(--ink); line-height: 1.3; }
.sortiment-preis { font-family: var(--serif); font-size: 1.05rem; color: var(--accent-deep); }

/* ===========================================================================
   Artikelkarten auf der Buchungsseite — Freisteller oben, Mengenregler unten
   =========================================================================== */
.vl-artikel { display: grid; grid-template-columns: minmax(0, 1fr); gap: 18px; }
@media (min-width: 700px) { .vl-artikel { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 20px; } }

.vl-artikel-karte {
  position: relative;
  display: flex; flex-direction: column; overflow: hidden;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.vl-artikel-karte:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }

/* Die Kachel ist ein Link zur Produktseite; die Bedienelemente liegen
   darueber und fangen ihre Klicks selbst ab. */
.vl-karte-flaeche { position: absolute; inset: 0; z-index: 1; }
.vl-karte-flaeche:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: -3px; }
.vl-karte-fuss, .vl-mengenregler, .vl-mengenzahl,
.vl-artikel-karte .vl-zubehoer-block { position: relative; z-index: 2; }
.vl-karte-anfrage-text {
  display: block; margin-top: 10px; padding-top: 12px;
  border-top: 1px solid var(--line);
  font-size: .88rem; font-weight: 600; color: var(--accent-deep);
}
.vl-karte-bild {
  display: grid; place-items: center; height: 168px; padding: 14px;
  background: radial-gradient(circle at 50% 42%, #ffffff 0%, var(--accent-soft) 100%);
  border-bottom: 1px solid var(--line);
}
.vl-karte-bild img {
  max-height: 145px; max-width: 100%; width: auto; object-fit: contain;
  filter: drop-shadow(0 12px 18px rgba(74, 64, 48, .22));
}
.vl-karte-text { padding: 18px 20px 20px; display: flex; flex-direction: column; gap: 8px; flex: 1; }
.vl-karte-kopf { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; }
.vl-karte-kopf h3 { margin: 0; font-family: var(--serif); font-weight: 500; font-size: 1.18rem; }
.vl-karte-preis { font-family: var(--serif); font-size: 1.24rem; color: var(--accent-deep); white-space: nowrap; }
.vl-karte-einheit { font-size: .82rem; color: var(--muted); }
.vl-karte-satz { margin: 0; font-size: .88rem; flex: 1; }

.vl-karte-fuss {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin-top: 8px; padding-top: 14px; border-top: 1px solid var(--line);
}
/* Die Wahl (Sitzkissen dazu, nur Tisch, nur Baenke) steht ueber dem
   Mengenregler: erst was, dann wie viele, dann der Preis. Sie gehoert damit
   zur Beschreibung, nicht zur Rechenzeile - die Linie trennt sie nach unten
   ab, und die Fusszeile bringt sie ohnehin schon mit. Eine zweite Linie
   darueber laege zwei Zeilen daneben und traennte nichts mehr. */
.vl-artikel-karte .vl-zubehoer-block { margin-top: 12px; }
/* In der Kachel ohne Rahmen und Flaeche (Noah, 25.09.2026): So ist die Zeile
   genau so breit wie der Rest der Karte, die Checkbox steht buendig am
   Textrand und der Preis genau unter dem Artikelpreis. Angehakt zeigen es
   die gruene Checkbox und der gruene Hinweis. */
.vl-artikel-karte .vl-zubehoer-block .vl-zubehoer,
.vl-artikel-karte .vl-zubehoer-block .vl-zubehoer:has(input:checked) {
  margin: 0; padding: 4px 0; border: 0; border-radius: 0; background: none;
}
.vl-artikel-karte .vl-zubehoer-block .vl-zubehoer:hover .vl-zubehoer-name { color: var(--accent-deep); }
.vl-mengenregler { display: flex; align-items: center; gap: 8px; }
.vl-mengenregler .rund {
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line);
  background: #fff; color: var(--ink); font-size: 1.2rem; line-height: 1;
  cursor: pointer; font-family: inherit; flex: none;
}
.vl-mengenregler .rund:disabled { color: var(--muted); opacity: .45; cursor: default; }
/* Die Menge ist ein Eingabefeld, sieht aber aus wie eine Zahl zwischen den
   beiden Knoepfen — bis man sie antippt. */
.vl-mengenzahl {
  width: 62px; text-align: center; font-family: inherit;
  font-size: 1.1rem; font-weight: 600; font-variant-numeric: tabular-nums;
  color: var(--ink); background: transparent;
  border: 1px solid transparent; border-radius: 10px; padding: 6px 2px;
  -moz-appearance: textfield;
}
.vl-mengenzahl::-webkit-outer-spin-button,
.vl-mengenzahl::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.vl-mengenzahl:hover { border-color: var(--line); }
.vl-mengenzahl:focus {
  outline: none; background: var(--bg);
  border-color: var(--accent); box-shadow: 0 0 0 2px rgba(111,125,92,.18);
}
/* --- Preis in den Wahlzeilen der Kachel ----------------------------------
   Sitzkissen und die Einschraenkungen der Garnitur setzen ihren Preis dorthin,
   wo ihn der Kartenkopf auch hat: rechts auf Hoehe des Namens, Einheit
   darunter. Vorher stand er im Kleingedruckten mitten im Satz.

   Nur in der Kachel: Kaufbox und Warenkorb bauen dieselben Klassen mit
   anderer Struktur, dort haette flex: 1 die Zeile verschoben. */
.vl-artikel-karte .vl-zubehoer-text { flex: 1; }

.vl-wahl-kopf {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
}
/* Serif und Akzentfarbe wie der Artikelpreis, aber eine Stufe kleiner - die
   Zeile ist dem Artikel untergeordnet und soll ihm nicht die Schau stehlen. */
.vl-wahl-preis {
  font-family: var(--serif); font-size: 1.02rem; color: var(--accent-deep);
  white-space: nowrap;
}

.vl-karte-summe { font-size: 1rem; font-weight: 600; color: var(--ink); white-space: nowrap; }
.vl-karte-summe.ist-leer { color: var(--muted); font-weight: 500; }
.vl-karte-anfrage { width: 100%; margin-top: 8px; }

/* ===========================================================================
   Buchungsleiste am unteren Rand — nur auf schmalen Geraeten.
   Am Rechner steht der Korb rechts neben den Artikeln; auf dem Handy liegt er
   hinter allen Karten und ist beim Auswaehlen unsichtbar. Deshalb hier eine
   Kurzfassung, die klebt: Anzahl, Mietwert, Weiter-Knopf — und auf Wunsch die
   Positionen zum Aufklappen.
   =========================================================================== */
.vl-korbleiste { display: none; }
/* Dasselbe fuer die Leiste der Startseite: Ihr ganzer Stil steht unten im
   Handy-Bereich - ohne diese Zeile stand sie am Rechner ungestaltet unter
   den Artikeln (gefunden 25.09.2026). */
.vl-handykorb { display: none; }

@media (max-width: 900px) {
  /* Die ausfuehrliche Uebersicht steht auf dem Handy hinter allen Artikeln und
     wird von der Leiste unten vollstaendig ersetzt - inklusive Zeitraum,
     Positionen, Mietwert und Schwellenhinweis. Nur die Korbspalte der
     Buchungsseite: In derselben Spalte steckt auf der Kasse der einzige
     Absendeknopf, und der darf auf dem Handy nicht verschwinden. */
  .vl-seitlich--korb { display: none; }

  .vl-korbleiste {
    display: block; position: fixed; z-index: 45;
    left: 10px; right: 10px; bottom: 10px;
    background: var(--surface); border: 1px solid var(--line);
    border-radius: var(--radius); box-shadow: var(--shadow);
    padding-bottom: env(safe-area-inset-bottom);
  }
  .vl-korbleiste[hidden] { display: none; }

  .vl-korbleiste-kopf {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
    width: 100%; padding: 11px 14px; border: 0; background: transparent;
    font: inherit; text-align: left; cursor: pointer; color: var(--ink);
  }
  .vl-korbleiste-zahlen { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
  .vl-korbleiste-zahlen strong { font-size: .95rem; }
  .vl-korbleiste-zahlen span { font-size: .82rem; color: var(--ink-soft); }
  /* --- Leiste der Startseite am Handy (Noah, 25.09.2026) ---------------
     Zwei Zeilen: oben Zeitraum als Pille und "Artikel ansehen", darunter
     links der Preis, rechts ein kurzer Knopf. "Artikel ansehen" oeffnet
     darueber ein Blatt mit derselben Uebersicht wie die Karte am Rechner. */
  .vl-handykorb { display: block; }
  .vl-handykorb[hidden] { display: none; }
  .vl-handykorb-leiste {
    position: fixed; z-index: 46; left: 0; right: 0; bottom: 0;
    padding: 12px 14px calc(14px + env(safe-area-inset-bottom));
    background: var(--surface); border-radius: 18px 18px 0 0;
    box-shadow: 0 -10px 30px rgba(34, 33, 29, .1);
    transition: border-radius .2s ease, box-shadow .2s ease;
  }
  /* Aufgeklappt ist die Leiste der untere Teil des Blatts, keine zweite
     Karte davor (Noah, 30.09.2026): ohne Rundung und Schatten, nur eine
     feine Linie zur Liste. Die Linie als Schatten statt als Rand - ein Rand
     machte die Leiste 1 px hoeher, und die gemeldete Hoehe sprang mit. */
  .vl-handykorb.ist-offen .vl-handykorb-leiste {
    border-radius: 0; box-shadow: inset 0 1px 0 var(--line);
  }
  /* Korb leer, Rueckgaengig laeuft noch: Die Leiste hat nichts zu sagen. */
  .vl-handykorb-leiste.ist-leer > * { display: none; }
  .vl-handykorb-leiste.ist-leer { padding-top: 0; }
  @media (prefers-reduced-motion: reduce) {
    .vl-handykorb-leiste { transition: none; }
  }
  .vl-handykorb-oben {
    display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px;
  }
  .vl-handykorb-pille { display: flex; min-width: 0; }
  .vl-handykorb-auf {
    flex: none; display: inline-flex; align-items: center; gap: 4px; padding: 4px 0;
    border: 0; background: none; font: inherit; font-size: .8rem; font-weight: 600;
    color: var(--accent-deep); cursor: pointer; white-space: nowrap;
  }
  .vl-handykorb-auf svg { width: 14px; height: 14px; transition: transform .2s ease; }
  .vl-handykorb.ist-offen .vl-handykorb-auf svg { transform: rotate(180deg); }
  .vl-handykorb-auf:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 6px; }
  /* Preis links, kurzer Knopf rechts (Noah, 30.09.2026) - vorher stand
     der Preis im Knopf, und der Knopf fuellte die ganze Breite. */
  .vl-handykorb-weiter-platz {
    display: flex; align-items: center; justify-content: space-between; gap: 12px;
  }
  .vl-handykorb-summe { display: flex; flex-direction: column; min-width: 0; line-height: 1.15; }
  .vl-handykorb-summe small { font-size: .78rem; color: var(--ink-soft); }
  .vl-handykorb-preis {
    font-style: normal; white-space: nowrap; font-variant-numeric: tabular-nums;
    font-family: var(--serif); font-size: 1.3rem; font-weight: 600; color: var(--ink);
  }
  .vl-handykorb-weiter {
    flex: none; display: inline-flex; align-items: center; justify-content: center;
    min-height: 46px; padding: 0 22px; border: 0; border-radius: 999px;
    background: var(--accent-deep); color: #fff; font: inherit; font-size: .95rem; font-weight: 600;
    text-decoration: none; white-space: nowrap; cursor: pointer;
  }
  /* Noch nicht buchbar: derselbe Knopf, aber zurueckgenommen - er oeffnet
     das Blatt mit dem Grund. */
  .vl-handykorb-weiter--warten { background: var(--bg-2); color: var(--ink-soft); }

  .vl-handykorb-dimm {
    position: fixed; inset: 0; z-index: 44; background: rgba(34, 33, 29, .35);
  }
  .vl-handykorb-dimm[hidden], .vl-handykorb-blatt[hidden] { display: none; }
  /* Das Blatt steht ueber der Leiste und laesst sie frei - der Knopf bleibt
     auch aufgeklappt erreichbar. Die Hoehe der Leiste meldet
     verleih-buchen.js. */
  .vl-handykorb-blatt {
    position: fixed; z-index: 45; left: 0; right: 0; bottom: 0;
    max-height: calc(100vh - 80px); overflow-y: auto; overscroll-behavior: contain;
    padding-bottom: var(--handykorb-leiste, 124px);
    background: var(--surface); border-radius: 22px 22px 0 0;
    box-shadow: 0 -12px 40px rgba(34, 33, 29, .18);
  }
  .vl-handykorb-griff { position: relative; width: 38px; height: 4px; border-radius: 99px; background: var(--line); margin: 8px auto 0; }
  /* Der Strich ist nur 4 px hoch - unsichtbar vergroessert, damit der
     Daumen ihn zum Wischen trifft. touch-action: Griff und Kopfzeile
     gehoeren dem Wischen, nicht dem Scrollen der Seite. */
  .vl-handykorb-griff::before { content: ""; position: absolute; inset: -12px -60px; }
  .vl-handykorb-griff, .vl-handykorb-blatt .vl-korb-kopf { touch-action: none; }
  .vl-handykorb-blatt .vl-korb-kopf { padding: 12px 16px 10px; }
  .vl-handykorb-blatt .vl-korb-liste { padding: 0 16px; }
  .vl-handykorb-blatt .vl-pos-bild { width: 40px; height: 40px; border-radius: 9px; }
  /* Summe und Knopf nimmt verleih-buchen.js aus dem Blatt - sie stehen in
     der Leiste darunter. */
  .vl-handykorb-blatt .vl-korb-fuss { padding: 12px 16px 14px; }
  .vl-handykorb-blatt .vl-korb-fuss > p + p:not(.vl-korb-zeile) { margin-top: 12px !important; }

  /* Platz am Seitenende, exakt so hoch wie die Leiste gerade ist — den Wert
     meldet verleih-buchen.js. Ohne ihn liegt die Leiste auf dem Impressum. */
  body { padding-bottom: var(--korbleiste-hoehe, 0px); }
}

/* Handy: aus der hohen Karte wird eine Zeile ---------------------------------
   Freisteller oben plus Text plus Regler ergeben auf 375 Pixeln rund 740 Pixel
   je Artikel — fuenf Artikel waeren fast vier Bildschirme. Deshalb wandert das
   Bild nach links und wird klein; Name, Preis und Verfuegbarkeit stehen
   daneben, der Regler darunter. So passen drei Artikel auf einen Blick. */
@media (max-width: 600px) {
  .vl-artikel { gap: 12px; }
  .vl-artikel-karte {
    display: grid; grid-template-columns: 92px minmax(0, 1fr);
    align-items: start; column-gap: 12px; padding: 12px;
  }
  .vl-karte-bild {
    height: 92px; padding: 6px; border: 1px solid var(--line);
    border-radius: 12px; align-self: start;
    grid-row: 1 / span 3; grid-column: 1;
  }
  .vl-karte-bild img { max-height: 78px; filter: drop-shadow(0 6px 10px rgba(74, 64, 48, .18)); }
  /* Der Textkasten loest sich auf, damit Name, Preis und Status neben dem Bild
     stehen — die Fusszeile mit Regler und Summe aber ueber die volle Breite
     laeuft. Sonst wird der Zeilenpreis in der schmalen Spalte abgeschnitten. */
  .vl-karte-text { display: contents; }
  .vl-karte-kopf, .vl-karte-einheit, .vl-artikel-karte .vl-status { grid-column: 2; }
  .vl-artikel-karte .vl-status { margin-top: 4px; }
  .vl-karte-kopf { flex-wrap: wrap; gap: 2px 8px; }
  .vl-karte-kopf h3 { font-size: 1.02rem; }
  .vl-karte-preis { font-size: 1.02rem; }
  .vl-karte-einheit { font-size: .76rem; }
  /* Der Beschreibungssatz steht auch auf der Produktseite — hier kostet er
     nur Höhe. */
  .vl-karte-satz { display: none; }
  .vl-karte-fuss {
    grid-column: 1 / -1; margin-top: 10px; padding-top: 10px;
  }
  /* Wie die Fusszeile ueber die volle Breite: durch display:contents am
     Textkasten ist auch die Zubehoerzeile ein Rasterfeld der Kachel und
     landete sonst in der 92 Pixel schmalen Bildspalte. */
  .vl-artikel-karte .vl-zubehoer-block { grid-column: 1 / -1; }
  .vl-artikel-karte .vl-status-pille { font-size: .78rem; }
  .vl-mengenregler .rund { width: 36px; height: 36px; }
  .vl-karte-anfrage,
  .vl-karte-anfrage-text { grid-column: 1 / -1; }
  .vl-karte-anfrage-text { margin-top: 8px; padding-top: 10px; }
}

/* ===========================================================================
   Lieferpauschale auf der Produktseite
   =========================================================================== */
.lieferkarte {
  padding: clamp(20px, 2.6vw, 28px);
  display: grid; grid-template-columns: minmax(0, 1fr); gap: 22px; align-items: center;
}
@media (min-width: 820px) { .lieferkarte { grid-template-columns: 1fr 1fr; gap: 34px; } }
.lieferkarte-links { display: flex; flex-direction: column; gap: 10px; }
.lieferkarte-links h2 { margin: 0; font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
.lieferkarte-links p { font-size: .95rem; }
.lieferkarte-felder { display: flex; gap: 10px; margin-top: 4px; }
.lieferkarte-felder input {
  font-family: var(--sans); font-size: 1rem; color: var(--ink);
  padding: 12px 14px; border: 1.5px solid var(--line); border-radius: 12px;
  background: #fff; min-height: 48px; min-width: 0;
}
#lz-plz { width: 120px; flex: none; font-weight: 600; }
#lz-ort { flex: 1; background: var(--bg); color: var(--ink-soft); }
.lieferkarte-rechts { display: flex; flex-direction: column; gap: 12px; }
.lieferkarte-fuss { margin: 0; font-size: .82rem; color: var(--muted); line-height: 1.5; text-align: center; }

/* Handy: Der Ergebniskasten stellt Zone und Betrag untereinander - nebeneinander
   bricht der Zonentext auf drei Zeilen, waehrend rechts der Betrag allein steht. */
@media (max-width: 600px) {
  .lieferkarte { padding: 16px; gap: 14px; }
  .lieferkarte-links { gap: 8px; }
  .lieferkarte-links p { font-size: .9rem; }
  .lieferkarte-felder input { min-height: 44px; }
  .lieferkarte-fuss { font-size: .8rem; }
}

/* Ergebnis als schmale Leiste: Symbol und Satz links, Betrag rechts. */
.lieferzone-kasten {
  display: flex; align-items: center; gap: 8px;
  padding: 10px 14px; border-radius: 12px; font-size: .88rem; line-height: 1.4;
}
.lieferzone-kasten svg { width: 16px; height: 16px; flex: none; }
.lieferzone-satz { flex: 1; min-width: 0; }
.lieferzone-betrag {
  flex: none; font-family: var(--serif); font-size: 1.25rem; line-height: 1.2; white-space: nowrap;
}
/* Der Kasten steht ausserhalb von .vl, wo die --vl-Farben definiert sind -
   ohne Ersatzwert blieb er farblos (gefunden 25.09.2026). */
.lieferzone-kasten.ist-frei { background: var(--vl-frei-flaeche, #edf0e6); color: var(--accent-deep); }
.lieferzone-kasten.ist-weg  { background: var(--vl-weg-flaeche, #f7eceb); color: #7d302a; }
/* Noch kein Ergebnis: leichter, gestrichelter Hinweis statt eines Blocks -
   man sieht, dass hier gleich etwas erscheint. */
.lieferzone-kasten.ist-offen {
  gap: 10px; padding: 11px 14px; background: none;
  border: 1.5px dashed var(--line); color: var(--muted);
}
.lieferzone-kasten.ist-offen svg { width: 20px; height: 20px; color: var(--accent); }

.visuell-versteckt {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ===========================================================================
   Zeitraumleiste — liest sich wie ein Satz:
   "Euer Termin  [Datum] [3 Tage]   Sa 19  So 20  [Di 22 ... Do 24]"
   Kein Kasten je Tag - nur das gewaehlte Fenster traegt ein Band. Die
   Statuszeile darunter existiert nur, wenn sie etwas zu sagen hat.
   =========================================================================== */
.vl-zeitleiste {
  background: var(--surface); color: var(--ink);
  border-bottom: 1px solid var(--line); padding-block: 14px 12px;
}
.vl-zeit-innen { display: flex; flex-direction: column; gap: 4px; }

/* Platzhalter auf der Startseite (16.10.2026): Die Leiste entsteht erst,
   wenn die Einstellungen aus Supabase da sind, und schob dann das Sortiment
   um ihre ganze Hoehe nach unten - PageSpeed maß dafuer einen Layout Shift
   von 0,21 auf dem Handy. Die Hoehen sind die der fertigen Leiste ohne
   Auswahl; aendert sich ihr Aufbau, hier nachmessen. Gilt nur, solange das
   Geruest aus index.html drinsteht - beim Aufbau ersetzt das Skript es. */
.zeitraum-platz:has(> .zeitraum-geruest) {
  min-height: 175px;
  background: var(--surface); border-bottom: 1px solid var(--line);
}
@media (max-width: 920px) { .zeitraum-platz:has(> .zeitraum-geruest) { min-height: 302px; } }
@media (max-width: 600px) { .zeitraum-platz:has(> .zeitraum-geruest) { min-height: 264px; } }
.zeitraum-geruest { border-bottom: 0; }
.zeitraum-geruest input:disabled { background-color: var(--bg); color: var(--ink); opacity: 1; }

/* Oben ausgerichtet statt mittig: Sobald der Monat aufgeklappt ist, ist der
   rechte Block über 300 Pixel hoch - zentriert rutschten Frage und
   Datumsfelder dann auf halbe Höhe hinunter, weit weg von der Überschrift. */
.vl-zeit-zeile { display: flex; align-items: flex-start; gap: 16px; flex-wrap: wrap; }
/* Die Felder behalten ihre Höhe neben dem schmalen Streifen. */
.vl-zeit-zeile > .vl-zeit-frage { padding-top: 10px; }
.vl-zeit-frage {
  font-family: var(--serif); font-size: 1.1rem; line-height: 1.2; flex: none;
}

/* --- Von / Bis ---------------------------------------------------------- */
.vl-spanne { display: flex; align-items: flex-end; gap: 8px; flex: none; }
.vl-spanne label {
  display: flex; flex-direction: column; gap: 2px;
  font-size: .7rem; text-transform: uppercase; letter-spacing: .06em; color: var(--muted);
}
.vl-spanne input {
  font: inherit; font-size: .9rem; font-weight: 600; color: var(--ink);
  padding: 7px 10px; min-height: 38px;
  background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
}
.vl-spanne input:focus { outline: 2px solid var(--accent); outline-offset: 1px; }
.vl-spanne-strich { color: var(--muted); padding-bottom: 10px; }

/* --- Die beiden Datumsfelder --------------------------------------------
   Seit sie Textfelder sind, bringt der Browser weder Kalendersymbol noch
   feste Breite mit. Beides muss hier stehen: das Symbol, damit man dem Feld
   ansieht, dass ein Kalender daran haengt, und die Breite, damit die Zeile
   nicht springt, sobald aus "TT.MM.JJJJ" ein Datum wird. */
/* Die Breite steht bewusst schwach (eine Klasse): Weiter unten macht die
   Regel fuer schmale Bildschirme daraus width: 100%, und das soll sie
   duerfen. border-box, damit das Feld dabei nicht um Innenabstand und
   Rahmen zu breit wird. */
.vl-datumsfeld { width: 10.5em; box-sizing: border-box; }

/* Das Symbol dagegen muss staerker binden als ".vl-spanne input": Dort steht
   die Kurzform "background", und die setzt background-image auf none - ein
   Symbol in einer schwaecheren Regel waere unsichtbar, ohne dass man im
   Quelltext etwas Falsches faende. */
.vl-spanne .vl-datumsfeld {
  padding-right: 30px;
  background-color: var(--bg);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a8578' stroke-width='1.8' stroke-linecap='round'%3E%3Crect x='3' y='5' width='18' height='16' rx='3'/%3E%3Cpath d='M8 3v4M16 3v4M3 10h18'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 9px center;
  background-size: 16px 16px;
}
.vl-datumsfeld::placeholder { color: var(--muted); font-weight: 400; }

/* Eingabe, die sich nicht als Datum lesen liess. Der Rahmen erscheint fuer
   anderthalb Sekunden, danach steht wieder der letzte gueltige Wert im
   Feld - kein Fehlertext, keine Sperre, nur ein sichtbares "so nicht". */
.vl-datumsfeld.ist-ungueltig {
  border-color: #b4443a;
  box-shadow: 0 0 0 2px rgba(180, 68, 58, .16);
}

/* --- Tagesstreifen ------------------------------------------------------ */
.vl-tagesleiste { display: flex; align-items: stretch; gap: 4px; flex: 1; min-width: 260px; }
.vl-tagesleiste .vl-blaettern {
  flex: none; width: 28px; border: 0; background: transparent; cursor: pointer;
  color: var(--muted); font-family: inherit; font-size: 1rem; border-radius: 8px;
}
.vl-tagesleiste .vl-blaettern:hover { background: var(--bg-2); color: var(--ink); }

.vl-tage-halter { position: relative; flex: 1; min-width: 0; touch-action: pan-y; padding: 2px 0; }

/* Die Tage liegen UEBER dem Fenster - so legt sich keine Schicht ueber die
   Zahlen und hellt sie auf. Damit am Fenster trotzdem gezogen werden kann,
   nehmen sie keine Zeiger an; der Klick auf einen Tag laeuft ueber die
   Position im Streifen (siehe verleih-zeitraum.js). */
.vl-tage {
  position: relative; z-index: 2; pointer-events: none;
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
}
.vl-tagesleiste .vl-tag,
.vl-tage .vl-tag {
  aspect-ratio: auto; width: auto; min-width: 0; border: 0; border-radius: 10px;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 6px 0 7px; background: transparent; cursor: pointer;
  font-family: inherit; line-height: 1.15; color: var(--ink-soft);
}
/* .vl-tag gehoert auch dem Monatskalender, dessen erste Zelle eine farbige
   Flaeche traegt. Im Streifen ist die falsch — dort macht das Fenster die
   Flaeche. */
.vl-tage .vl-tag > span:first-child,
.vl-tage .vl-tag[data-status] > span:first-child {
  background: transparent; padding: 0; border-radius: 0;
}
/* Farbe statt opacity (16.10.2026): Mit opacity .7 lag der Kontrast bei
   .62rem unter 4,5 zu 1. --ink-soft sieht fast gleich aus und besteht. */
.vl-tag-wochentag {
  font-size: .62rem; text-transform: uppercase; letter-spacing: .04em; color: var(--ink-soft);
}
.vl-tag-zahl { font-size: .95rem; font-weight: 600; font-variant-numeric: tabular-nums; }
.vl-tage .vl-tag.ist-wochenende .vl-tag-wochentag {
  color: var(--accent-deep); opacity: 1; font-weight: 700;
}
.vl-tage .vl-tag.ist-im-fenster .vl-tag-zahl { color: var(--ink); font-weight: 700; }
.vl-tage .vl-tag.ist-im-fenster .vl-tag-wochentag {
  color: var(--accent-deep); opacity: 1; font-weight: 700;
}
.vl-tage.ist-belegt .vl-tag.ist-im-fenster .vl-tag-zahl { color: #9a5348; }
.vl-tage .vl-tag.ist-gesperrt { opacity: .35; }

/* Ampel: nur auf Produktseiten, dort ist der Punkt eindeutig. */
.vl-tag-punkt {
  width: 7px; height: 7px; border-radius: 50%; margin-top: 3px; background: var(--accent);
}
.vl-tag[data-status="knapp"] .vl-tag-punkt { background: #d8a24a; }
.vl-tag[data-status="ausgebucht"] .vl-tag-punkt { background: #c1796f; }
.vl-tag[data-status="unbekannt"] .vl-tag-punkt { background: var(--line); }
/* Ohne Legende trägt der Tag selbst die Aussage: ausgebucht heißt blass und
   durchgestrichen, alles andere ist buchbar. Deutlicher als vorher, weil
   daneben keine Farblegende mehr steht, die es erklärt. */
.vl-tage .vl-tag[data-status="ausgebucht"] { opacity: .42; }
.vl-tag[data-status="ausgebucht"] .vl-tag-zahl {
  color: var(--muted); text-decoration: line-through; text-decoration-thickness: 1.5px;
}
.vl-tage .vl-tag[data-status="ausgebucht"] .vl-tag-wochentag { color: var(--muted); }

/* --- Das weisse Fenster ------------------------------------------------- */
.vl-fenster {
  position: absolute; top: 0; bottom: 0; z-index: 1;
  border-radius: 14px; cursor: grab; touch-action: none; background: #fff;
  /* Weiss auf Weiss - deshalb traegt der Schatten die ganze Arbeit: eine
     harte Kante nah am Rand, eine mittlere fuer das Volumen, zwei weiche und
     tiefe fuer den Abstand zum Papier. */
  box-shadow: 0 1px 2px rgba(34, 33, 29, .16),
              0 4px 8px rgba(34, 33, 29, .16),
              0 10px 20px rgba(34, 33, 29, .20),
              0 22px 44px rgba(34, 33, 29, .20);
  transition: box-shadow .15s ease;
}
.vl-fenster:hover {
  box-shadow: 0 1px 2px rgba(34, 33, 29, .18),
              0 6px 12px rgba(34, 33, 29, .20),
              0 14px 28px rgba(34, 33, 29, .24),
              0 28px 56px rgba(34, 33, 29, .22);
}
.vl-fenster:focus-visible { outline: 2px solid var(--accent-deep); outline-offset: 3px; }
.vl-fenster.ist-gezogen { cursor: grabbing; transition: none; }
.vl-fenster.ist-belegt { background: #fff5f2; }

/* Griffe: schmal gezeichnet, breit anfassbar. */
.vl-griff {
  position: absolute; top: 0; bottom: 0; width: 26px; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  cursor: ew-resize; touch-action: none;
}
.vl-griff--links { left: -13px; }
.vl-griff--rechts { right: -13px; }
.vl-griff::before {
  content: ""; width: 3px; height: 18px; border-radius: 999px; background: var(--muted);
}
.vl-fenster[data-tage="1"] .vl-griff { width: 16px; }
.vl-fenster[data-tage="1"] .vl-griff--links { left: -8px; }
.vl-fenster[data-tage="1"] .vl-griff--rechts { right: -8px; }

/* --- Satz und Legende --------------------------------------------------- */
.vl-zeit-satz {
  display: flex; align-items: flex-start; gap: 8px;
  margin: 12px 0 0; font-size: .9rem; font-weight: 500;
}
.vl-zeit-satz[data-art="frei"] { color: var(--accent-deep); }
.vl-zeit-satz[data-art="weg"] { color: #9a5348; }
.vl-zeit-satz[data-art="offen"] { color: var(--ink-soft); font-weight: 400; }
.vl-satz-punkt {
  width: 18px; height: 18px; border-radius: 50%; flex: none; margin-top: 2px;
  display: grid; place-items: center; font-size: .7rem; color: #fff; background: var(--accent);
}
.vl-zeit-satz[data-art="weg"] .vl-satz-punkt { background: #b06a5f; }
.vl-zeit-satz[data-art="offen"] .vl-satz-punkt { display: none; }

.vl-status-knopf {
  font-family: inherit; font-size: .82rem; font-weight: 600; cursor: pointer;
  color: #eef2e6; background: var(--accent-deep);
  border: 0; border-radius: 999px; padding: 3px 12px; margin-left: 4px;
}
.vl-status-knopf:hover { background: var(--accent); }

.vl-zeit-legende {
  display: flex; gap: 16px; flex-wrap: wrap; margin: 6px 0 0;
  font-size: .78rem; color: var(--muted);
}
.vl-zeit-legende i {
  width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 5px;
}
.vl-zeit-legende i.ist-frei { background: var(--accent); }
.vl-zeit-legende i.ist-knapp { background: #d8a24a; }
.vl-zeit-legende i.ist-ausgebucht { background: #c1796f; }

@media (max-width: 900px) {
  .vl-zeit-frage { flex-basis: 100%; }
  .vl-spanne { flex: 1; }
  .vl-spanne label { flex: 1; }
  .vl-spanne input { width: 100%; }
  /* Der Streifen bekommt hier ebenfalls eine eigene Zeile - die Regel steht
     weiter unten bei .vl-streifen, siehe die Begruendung dort. */
}

/* Auf dem Handy steht die Leiste zwischen Kopf und Sortiment und darf keine
   Zeile verschenken: kleinere Frage, engere Abstaende, und der Satz mit dem
   Knopf bricht sauber untereinander statt nebeneinander zu klemmen. */
@media (max-width: 600px) {
  .vl-zeitleiste { padding-block: 10px 10px; }
  .vl-zeit-zeile { gap: 8px; }
  .vl-zeit-frage { font-size: .95rem; }
  .vl-spanne label { font-size: .64rem; }
  /* 40 Pixel als Tippflaeche - darunter trifft man das Feld mit dem Daumen
     nicht zuverlaessig. */
  .vl-spanne input { font-size: .88rem; padding: 8px 9px; min-height: 40px; }
  .vl-spanne-strich { padding-bottom: 8px; }
  .vl-tagesleiste { gap: 0; }
  /* Sichtbar bleiben die Pfeile schmal - jeder Pixel mehr fehlt den Tagen
     daneben. Die Tippflaeche waechst stattdessen nach AUSSEN, weg von den
     Tagen: 44 Pixel breit, am aeusseren Rand verankert. Nach innen zu
     wachsen waere falsch, dort laege sie ueber dem ersten und letzten Tag. */
  .vl-tagesleiste .vl-blaettern { width: 22px; position: relative; }
  /* 42 statt 44 Pixel breit: Der Pfeil sitzt 20 Pixel vor dem Bildschirm-
     rand, die Flaeche waechst 20 nach aussen und endet genau am Rand. Mit 44
     ragte sie 2 Pixel hinaus, und die Startseite liess sich am Handy seitlich
     verschieben (Klicktest 05.10.2026). */
  .vl-tagesleiste .vl-blaettern::after {
    content: ""; position: absolute; top: 50%; transform: translateY(-50%);
    width: 42px; height: 44px;
  }
  .vl-tagesleiste .vl-blaettern[data-schritt="-1"]::after { right: 0; }
  .vl-tagesleiste .vl-blaettern[data-schritt="1"]::after { left: 0; }
  .vl-tag-zahl { font-size: .88rem; }
  .vl-zeit-satz {
    flex-wrap: wrap; margin-top: 6px; font-size: .82rem; line-height: 1.4;
  }
  .vl-satz-punkt { width: 15px; height: 15px; font-size: .62rem; }
  .vl-status-knopf { margin: 4px 0 0; padding: 5px 11px; font-size: .78rem; }
  .vl-zeit-legende { gap: 10px; font-size: .72rem; margin-top: 4px; }
}


/* Kaufbox: Abstand, seit Felder und Kalender die Plaetze getauscht haben */
.pdp-widget .vl-kalender-halter { margin-top: 14px; }
.pdp-widget .vl-felder { margin-top: 0; }

/* ===========================================================================
   Kaufbox der Produktseite
   Reihenfolge wie im Entwurf: Preis, Status, Termin, (Kalender), Menge, Knopf.
   Der Kalender ist zugeklappt — wer nur den Preis sucht, soll ihn nicht
   erst wegscrollen muessen.
   =========================================================================== */
.kb-status {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line); color: var(--ink);
}
.kb-status-text { font-size: .95rem; font-weight: 600; }
.kb-punkt { width: 10px; height: 10px; border-radius: 50%; flex: none; background: var(--muted); }
.kb-status[data-zustand="frei"]  .kb-punkt { background: var(--accent); }
.kb-status[data-zustand="knapp"] .kb-punkt { background: var(--vl-knapp); }
.kb-status[data-zustand="weg"]   .kb-punkt { background: var(--vl-weg); }

.kb-termin {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 14px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 12px;
}
.kb-termin-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.kb-termin-label {
  font-size: .72rem; text-transform: uppercase; letter-spacing: .1em; color: var(--muted);
}
.kb-termin-wert { font-size: 1rem; font-weight: 600; color: var(--ink); }
.kb-aendern {
  flex: none; font-family: inherit; font-size: .88rem; font-weight: 600;
  color: var(--accent-deep); background: var(--accent-soft);
  border: 0; border-radius: 999px; padding: 9px 16px; cursor: pointer; min-height: 40px;
}
.kb-aendern:hover { background: #e2e8d7; }

.kb-kalender {
  display: flex; flex-direction: column; gap: 10px;
  padding: 14px; border: 1px solid var(--line); border-radius: 12px;
}
.kb-kalender[hidden] { display: none; }

.kb-menge { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.kb-menge-label { font-size: .95rem; font-weight: 600; }
.kb-stepper { display: flex; align-items: center; gap: 8px; }
.kb-stepper .rund {
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line);
  background: #fff; color: var(--ink); font-size: 1.2rem; line-height: 1;
  cursor: pointer; font-family: inherit; flex: none;
}
/* Am Anschlag ausgegraut - dieselbe Sprache wie der Regler in der Kasse.
   Beim Traubogen gibt es genau ein Stueck: Dort sind beide Knoepfe gesperrt,
   sahen aber unveraendert aus. Wer auf "-" drueckt, haelt ein stummes Feld
   fuer kaputt. */
.kb-stepper .rund:disabled {
  color: var(--muted); opacity: .45; cursor: default;
}
.kb-stepper .rund:disabled:hover { background: #fff; border-color: var(--line); }

.kb-stepper input {
  width: 70px; text-align: center; font-family: inherit; font-size: 1.05rem;
  font-weight: 600; font-variant-numeric: tabular-nums; color: var(--ink);
  padding: 10px 6px; border: 1.5px solid var(--line); border-radius: 12px;
  background: #fff; min-height: 44px;
}
.kb-stepper input::-webkit-outer-spin-button,
.kb-stepper input::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.kb-stepper input { -moz-appearance: textfield; }

/* Im Entwurf steht "Jetzt buchen" allein auf voller Breite, der
   Zweitknopf darunter - nicht nebeneinander. */
.pdp-widget .vl-aktionen { display: flex; flex-direction: column; gap: 10px; }
/* flex: 1 1 200px steht weiter oben fuer die Zeilenanordnung - in dieser
   Spalte wuerde daraus eine HOEHE von 200 Pixeln je Knopf, zusaetzlich
   gedehnt durch flex-grow. Beides hier zuruecknehmen. */
.pdp-widget .vl-aktionen .btn { width: 100%; flex: 0 0 auto; }
/* Beide Knoepfe gleich gross: Der Zweitweg war zehn Pixel flacher, kleiner
   gesetzt und nur von einem sehr hellen Rand umgeben - damit sah er nicht
   nach Nebenweg aus, sondern nach ausgegraut. Die Rangfolge steckt jetzt
   allein in der Farbe: gefuellte Flaeche gegen weisse mit sichtbarer Kontur. */
.pdp-widget .vl-aktionen .btn { min-height: 50px; font-size: 1rem; }
.pdp-widget .vl-aktionen .btn--ghost {
  border-color: color-mix(in srgb, var(--ink-soft) 50%, var(--line));
}

/* --- Korbsymbol im Kopf ---------------------------------------------------
   Steht seit dem 22.09.2026 in style.css, nicht mehr hier.

   Das Symbol haengt im Seitenkopf und damit auf jeder Seite - auch auf denen,
   die verleih.css gar nicht laden (Ratgeber, Tools, Impressum). Dort stand es
   unformatiert da: winziges Icon, die Zahl darunter statt darauf. Die Regeln
   gehoeren deshalb zur Datei, die jede Seite ohnehin laedt. */

/* --- Artikel in der Kasse -------------------------------------------------
   Erster Block der Kasse: sehen, pruefen, korrigieren. Auf schmalen Geraeten
   rutschen Regler und Summe unter den Namen, das Bild bleibt links stehen -
   sonst wird die Zeile so eng, dass die Knoepfe nicht mehr zu treffen sind. */

/* Jeder Artikel als eigene Karte (Noah, 25.09.2026, Entwurf A1): oben Bild,
   Name mit Stueckpreis und das Entfernen, darunter Regler und Summe,
   abgetrennt darunter die Wahl (Sitzkissen, Garnitur/Tisch/Baenke). Vorher
   war jede Zeile fast einen halben Handybildschirm hoch, und wo ein Artikel
   endete und der naechste anfing, zeigte nur eine duenne Linie. Gilt in
   allen Breiten - am Rechner steht der Block schmal neben der Zusammenfassung. */
.vl-korbzeilen { display: flex; flex-direction: column; gap: 8px; }
.vl-block--artikel { background: var(--bg); }
/* Vier Spalten: Der Name spannt Spalte 2 und 3, die Summe darunter 3 und 4 -
   so macht die Breite des Betrags die Namenszeile nicht schmal. Zeilenabstand
   ueber Raender statt gap: Leere Zeilen (keine Grenze, keine Wahl) liessen
   sonst ihren Abstand stehen, und Karten ohne Option hatten unten Luft. */
.vl-korbzeile {
  display: grid; align-items: center; gap: 0 12px;
  grid-template-columns: 52px minmax(0, 1fr) auto 32px;
  grid-template-areas:
    "bild   text   text  weg"
    "regler regler summe summe"
    "grenze grenze grenze grenze"
    "wahl   wahl   wahl  wahl";
  padding: 12px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 14px;
}
.vl-korbzeile .vl-zubehoer-block {
  grid-area: wahl; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--bg-2);
}
/* Bild wieder sichtbar (Noah, 25.09.2026) - dieselbe Zeile wie ueberall. */
.vl-korbzeile .vl-zubehoer-block .vl-zubehoer { margin-top: 0; }

/* Die Ueberschrift des Blocks rechnet mit einem erklaerenden Absatz darunter
   und haelt nur 4 Pixel Abstand. Hier folgt sofort der erste Artikel - dessen
   erste Zeile laesst ihr Innenabstand ebenfalls weg, und "Eure Artikel" klebte
   am Stuhlbild. */
.vl-block > h3 + .vl-korbzeilen { margin-top: 16px; }

/* Derselbe Fall bei "Abholung oder Lieferung": Der erklaerende Absatz ist dort
   entfallen, weil er dasselbe sagte wie die Auswahl darunter - und damit fiel
   auch sein Abstand weg. */
.vl-block > h3 + .vl-wahl { margin-top: 16px; }

/* "wird berechnet …" steht an der Stelle des Betrags, solange der Server den
   Preis mit den Zusatztagen noch nicht geliefert hat - es soll dort ruhiger
   wirken als eine Zahl, damit niemand es fuer einen Betrag haelt. */
.vl-rechnet { font-weight: 400; font-size: .85rem; color: var(--muted); }

/* --- Abhol- und Rueckgabetermin ------------------------------------------
   Hier standen zwei Klapplisten mit je genau einem Eintrag: Abholung und
   Rueckgabe haben pro Wochentag nur ein Zeitfenster, es gab also nichts zu
   waehlen. Jetzt sind es Terminzeilen; eine Auswahl erscheint nur, wenn fuer
   den Tag tatsaechlich mehrere Fenster hinterlegt sind - dann als Knoepfe
   nebeneinander, weil zwei oder drei Moeglichkeiten sich vergleichen lassen
   sollen, ohne sie erst aufzuklappen. */
/* --- Abholung und Rueckgabe ----------------------------------------------
   Zwei Zeilen ohne Rahmen, nicht zwei Kaesten. Sie stehen unter den beiden
   Knoepfen, mit denen man Abholung und Lieferung waehlt - trugen sie
   dieselbe Kante, sahen sie aus, als koennte man sie auch antippen. Kann man
   nicht: Fuer Abholung und Rueckgabe liegt je Wochentag genau ein
   Zeitfenster vor, hier gibt es nichts zu entscheiden.

   Drei Spalten fuer beide Zeilen gemeinsam: Art, Datum, Zeit. Die letzte
   nimmt den Rest, damit die ersten beiden nur so breit werden wie ihr
   laengster Eintrag - so stehen Datum unter Datum und Zeit unter Zeit.

   Eng gesetzt (6 statt 10 Pixel), weil zwei Textzeilen zusammengehoeren -
   der alte Abstand stammte von Kaesten, die ihn brauchten. */
/* Abhol- und Rueckgabetermin als Belegzeilen wie die Lieferpauschale
   (25.09.2026): gestrichelte Linie darueber, je Termin Symbol, links was und
   wo, rechts Datum mit der Uhrzeit als Marke darunter. */
.vl-termine { margin-top: 14px; border-top: 1px dashed var(--line); font-size: .9rem; }
.vl-terminzeile {
  display: flex; align-items: center; gap: 10px; padding: 11px 0;
}
.vl-terminzeile + .vl-terminzeile { border-top: 1px solid var(--bg-2); }
.vl-terminzeile-symbol { flex: none; display: inline-flex; color: var(--accent); }
.vl-terminzeile-art {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px;
  color: var(--ink); font-size: .92rem;
}
.vl-terminzeile-art small { font-size: .78rem; color: var(--muted); }
.vl-terminzeile-wann {
  flex: none; display: flex; flex-direction: column; align-items: flex-end; gap: 4px;
}
.vl-terminzeile-wann strong { font-size: .92rem; font-weight: 600; color: var(--ink); white-space: nowrap; }
/* Die Uhrzeit deutlich (Noah): als Marke in Salbei, nicht als graue Zeile. */
.vl-terminzeile-zeit {
  font-size: .82rem; font-weight: 600; color: var(--accent-deep); white-space: nowrap;
  background: var(--accent-soft); border-radius: 999px; padding: 2px 9px;
}

/* Derselbe Ton wie der Hinweis unter dem Lieferfeld - beide sagen dasselbe
   zu, einmal fuer die Abholung und einmal fuer die Fahrt. Ueber alle drei
   Spalten, sonst stuende er in der ersten und braeche nach jedem Wort um. */
.vl-termin-hinweis {
  grid-column: 1 / -1;
  margin: 6px 0 0; font-size: .78rem; line-height: 1.5; color: var(--muted);
  text-align: center;
}

.vl-termin {
  border: 1px solid var(--line); border-radius: 12px;
  padding: 12px 14px; background: var(--bg);
}
.vl-termin-kopf {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
}
.vl-termin-kopf > span {
  font-size: .72rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted);
}
.vl-termin-kopf > strong { font-size: .95rem; white-space: nowrap; }

/* Raster statt Flexfluss: Mit flex-grow fuellte der letzte Knopf die
   angebrochene Zeile allein aus - bei drei Fenstern standen oben zwei zu
   145 Pixeln und darunter einer zu 297. Drei Moeglichkeiten, drei Breiten,
   und die Reihe sah aus wie ein Versehen.

   Die Zahl der Spalten kommt aus --chips und damit aus der Zahl der Fenster:
   Passen sie nebeneinander, stehen sie in einer Reihe und lassen sich
   vergleichen; wird es eng, stapeln sie sich untereinander ueber die volle
   Breite - dort ist ein Knopf ohnehin leichter zu treffen. */
/* Wunschzeit als Umschalter in einer Zeile (Noah, 25.09.2026): alle
   Fenster nebeneinander in einer hellen Leiste, das gewaehlte als weisse
   Taste mit Salbeirand. Vorher drei grosse Kaesten untereinander, rund 150
   Pixel hoch und im selben Stil wie "Abholung oder Lieferung" - die
   Nebensache sah aus wie die Hauptentscheidung. Name und Uhrzeit stehen
   untereinander, damit drei Tasten auch auf 320 Pixeln nebeneinander passen. */
.vl-zeitwahl {
  display: grid; gap: 3px; margin-top: 8px; padding: 3px;
  grid-template-columns: repeat(var(--chips, 1), minmax(0, 1fr));
  background: var(--bg-2); border-radius: 12px;
}
/* Die Taste ist das Label - der Radiobutton selbst bleibt fuer die
   Tastatur erreichbar, aber unsichtbar. */
.vl-zeitchip { min-width: 0; }
.vl-zeitchip input {
  position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none;
}
.vl-zeitchip > span {
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  height: 100%; padding: 8px 4px; cursor: pointer; text-align: center;
  border: 1px solid transparent; border-radius: 9px; background: transparent;
  transition: border-color .15s ease, background .15s ease;
}
.vl-zeitchip > span:hover { background: color-mix(in srgb, var(--surface) 55%, transparent); }
.vl-zeitchip input:checked + span {
  background: var(--surface); border-color: var(--accent);
}
.vl-zeitchip input:focus-visible + span {
  outline: 2px solid var(--accent); outline-offset: 1px;
}
.vl-zeitchip strong {
  font-size: .86rem; font-weight: 500; color: var(--ink-soft);
  overflow: hidden; text-overflow: ellipsis; max-width: 100%;
}
.vl-zeitchip input:checked + span strong { font-weight: 600; color: var(--accent-deep); }
.vl-zeitchip small { font-size: .74rem; color: var(--muted); white-space: nowrap; }

/* --- Vorschlagsliste im Ortsfeld -----------------------------------------
   Ersetzt die native datalist, die der Browser selbst zeichnet: auf dem Handy
   eine Systemliste am Bildschirmrand, in fremder Schrift und nicht zu
   gestalten. Diese hier sitzt unter dem Feld, ueber die volle Breite seines
   Kastens - auf 375 Pixeln waere die Spalte des Ortsfeldes allein zu schmal
   zum Lesen. */
.vl-ortsliste {
  /* Rechts buendig und nach links wachsend: Das Ortsfeld steht in der
     halben Spalte rechts, links daneben ist Platz. top und max-width setzt
     verleih-ortsfeld.js beim Oeffnen. */
  position: absolute; right: 0; top: 100%; z-index: 40;
  width: max-content; min-width: 100%;
  margin: 4px 0 0; padding: 4px; list-style: none;
  max-height: 264px; overflow-y: auto;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 14px 34px rgba(43, 38, 30, .16);
}
.vl-ortsliste li {
  display: flex; align-items: baseline; justify-content: space-between; gap: 12px;
  /* Mindestens 44 Pixel hoch: Darunter trifft ein Daumen daneben. */
  min-height: 44px; padding: 10px 12px;
  border-radius: 8px; cursor: pointer;
  font-size: .95rem; line-height: 1.3;
}
.vl-ortsliste li:hover,
.vl-ortsliste li.ist-markiert { background: var(--bg-2); }
.vl-ortsliste-name { color: var(--ink); }
.vl-ortsliste-plz {
  color: var(--muted); font-size: .84rem; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* In der Lieferspalte steht der Block schon in einem Feld - dort traegt er
   keinen zweiten Rahmen. */
.vl-feld > .vl-termin { border: 0; padding: 0; background: none; }

/* Rahmen um die Kachel: Die Freisteller sind weiss auf hellem Grund und
   verlieren ohne Kante ihre Form - der Stuhl schwebt dann im Nichts. Dieselbe
   Linie wie an den Eingabefeldern daneben, damit es eine Kachel bleibt und
   kein Bilderrahmen wird. */
.vl-korbzeile-bild {
  grid-area: bild; align-self: start;
  width: 52px; height: 52px; border-radius: 10px; background: var(--bg-2);
  border: 1px solid var(--line);
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.vl-korbzeile-bild img { width: 100%; height: 100%; object-fit: contain; }

.vl-korbzeile-text { grid-area: text; display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.vl-korbzeile-text strong { font-size: .95rem; line-height: 1.3; }
.vl-korbzeile .vl-mengenregler { grid-area: regler; justify-self: start; gap: 4px; margin-top: 10px; }
.vl-korbzeile .vl-mengenregler .rund { width: 34px; height: 34px; font-size: 1.05rem; }
.vl-korbzeile .vl-mengenzahl { width: 52px; font-size: 1rem; padding: 4px 2px; }
.vl-korbzeile-text span { font-size: .84rem; color: var(--ink-soft); }

/* Eigene Spalte mit Mindestbreite und Abstand zum Regler: Direkt neben dem
   Plus las sich "99 + 396,00 €" wie eine Rechnung, Zahl und Preis liefen
   ineinander (Noah, 25.09.2026). */
.vl-korbzeile-summe {
  grid-area: summe; justify-self: end; margin-top: 10px;
  font-weight: 700; font-variant-numeric: tabular-nums; white-space: nowrap; text-align: right;
}

.vl-korbzeile-weg {
  grid-area: weg; justify-self: end; align-self: start; margin: -4px -4px 0 0;
  width: 32px; height: 32px; border: 0; border-radius: 999px;
  background: none; color: var(--ink-soft); cursor: pointer;
  font-size: 1.25rem; line-height: 1;
  transition: background .15s ease, color .15s ease;
}
.vl-korbzeile-weg:hover { background: var(--bg-2); color: var(--ink); }

/* --- Zubehoer -------------------------------------------------------------
   Sitzkissen zum Stuhl: eine Zeile unter der Kachel beziehungsweise unter der
   Mengenwahl auf der Produktseite. Das ganze Feld ist das Label, damit auf dem
   Handy nicht das 16-Pixel-Kaestchen getroffen werden muss. */

/* Zeile statt Kasten: Sie sitzt in der Kaufbox, die selbst schon Rahmen und
   Fläche hat — ein zweiter Kasten darin, mit einem dritten ums Bild, ergab
   drei Kanten für ein Häkchen. Eine Linie oben trennt genauso gut. */
/* Seit 25.09.2026 (Noah) eine eigene Zeile mit Rahmen: Bild auf heller
   Kachel, Name und Hinweis, rechts eine moderne Checkbox. Angehakt wird die
   ganze Zeile gruen. Ueberall gleich - Kachel, Kaufbox, Kasse. */
.vl-zubehoer {
  display: flex; align-items: center; gap: 12px;
  margin-top: 12px; padding: 10px 12px;
  border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); cursor: pointer;
  transition: border-color .15s ease, background-color .15s ease;
}
.vl-zubehoer:hover { border-color: var(--accent); }
.vl-zubehoer:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }

/* Moderne Checkbox: abgerundet, angehakt gruen gefuellt mit weissem Haken.
   Das echte Eingabefeld bleibt - nur sein Aussehen ist eigen, Tastatur und
   Screenreader bedienen es wie gewohnt. */
.vl-zubehoer input {
  /* 24 px: Mindestgroesse fuer Tippflaechen (WCAG 2.5.8, 16.10.2026) */
  order: 0; flex: 0 0 auto; width: 24px; height: 24px; margin: 0;
  appearance: none; -webkit-appearance: none;
  border: 1.5px solid #c9c1b3; border-radius: 7px; background: var(--surface) center / 14px no-repeat;
  cursor: pointer; transition: background-color .15s ease, border-color .15s ease;
}
.vl-zubehoer input:checked {
  border-color: var(--accent-deep); background-color: var(--accent-deep);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M5 12.5l4.5 4.5L19 7.5' fill='none' stroke='%23fff' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.vl-zubehoer input:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

.vl-zubehoer-bild {
  order: 1; width: 44px; height: 44px; flex: 0 0 auto; border-radius: 9px;
  overflow: hidden; background: var(--bg-2);
  display: flex; align-items: center; justify-content: center;
}
.vl-zubehoer-bild img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
/* In der Kasse am Handy ohne Bild (Noah, 03.10.2026): Neben Haken, Bild und
   Betrag blieben dem Text 88 px, "Sitzkissen dazu" und "+ 1,50 € je Stueck"
   brachen je in zwei Zeilen um. Ohne Bild passt beides in eine Zeile. */
@media (max-width: 520px) {
  .vl-korbzeile .vl-zubehoer-bild { display: none; }
}

.vl-zubehoer-text {
  order: 2; display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1;
  line-height: 1.25;
}
.vl-zubehoer-name { font-size: .88rem; font-weight: 600; color: var(--ink); }
.vl-zubehoer-text small { font-size: .74rem; color: var(--muted); font-variant-numeric: tabular-nums; }
.vl-zubehoer:has(input:checked) .vl-zubehoer-text small { color: var(--accent-deep); }

/* Checkbox links, Stueckpreis rechts (Noah, 25.09.2026). In der Kasse steht
   rechts statt des Stueckpreises der Zeilenbetrag - dort mit Zusatztagen. */
.vl-zubehoer-preis { order: 3; flex: none; margin-left: auto; white-space: nowrap; align-self: flex-start; }
.vl-zubehoer-summe {
  order: 3; margin-left: auto; font-weight: 700; font-size: .88rem;
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.vl-zubehoer-summe:empty { display: none; }

/* Zu wenig Zubehoer frei: sichtbar gesperrt, statt die Buchung erst beim
   Absenden scheitern zu lassen. */
.vl-zubehoer.ist-gesperrt {
  cursor: not-allowed; opacity: .62; background: var(--surface);
}
.vl-zubehoer.ist-gesperrt:hover { border-color: var(--line); }
.vl-zubehoer.ist-gesperrt input { cursor: not-allowed; }

/* Auf der Produktseite steht die Zeile fuer sich und darf mehr Luft haben. */
.pdp-widget .vl-zubehoer { margin-top: 14px; }

/* Produktseite ohne eigenes Widget: der Weg zum Hauptartikel. */
.pdp-verweis {
  padding: 18px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--bg-2);
}
.pdp-verweis p { margin: 0 0 14px; font-size: .95rem; line-height: 1.5; }

/* Paketauswahl: zwei gleichrangige Teile statt Hauptartikel plus Zusatz. */
.vl-paket-frage {
  margin: 14px 0 8px; font-size: .88rem; font-weight: 600; color: var(--ink);
}
.vl-zubehoer + .vl-zubehoer { margin-top: 0; border-top: 0; padding-top: 4px; }
/* Ein gesperrtes Kaestchen, das gesetzt ist, ist kein Fehler, sondern die
   letzte verbliebene Wahl - es darf nicht ausgegraut wirken. */
.vl-zubehoer.ist-gesperrt:has(input:checked) { opacity: 1; background: var(--bg-2); }

/* --- Auswahl bei Paketen: Garnitur / nur Tisch / nur Baenke --------------
   Ein Umschalter mit drei Feldern (K.teilWahlHtml, Noah 25.09.2026). Frueher
   zwei Kaestchen, die sich gegenseitig aufhoben - die haeufigste Wahl, die
   ganze Garnitur, stand dabei nirgends. */
.vl-teilwahl { display: block; margin-top: 4px; }
.vl-teilwahl-frage { display: block; margin: 0 0 6px; font-size: .74rem; color: var(--muted); }
.vl-teilwahl-felder {
  position: relative;
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 3px;
  padding: 3px; border-radius: 12px; background: var(--bg-2);
  box-shadow: inset 0 2px 4px rgba(34, 33, 29, .10);
}
/* Die weisse Flaeche ist ein eigenes Element unter den Feldern und gleitet
   zum gewaehlten Feld, statt im alten zu verschwinden und im neuen
   aufzutauchen (Noah, 13.10.2026). Sie steht wie ein Kissen ueber den Rand
   der eingelassenen Leiste hinaus (Entwurf 3): 3px breiter als das Feld auf
   jeder Seite, oben und unten bis an den Rand. Schritt = Feldbreite plus
   Luecke = eigene Breite minus 3px. */
.vl-teilwahl-felder::before {
  content: ""; position: absolute; top: 0; bottom: 0; left: 0;
  width: calc((100% - 12px) / 3 + 6px); border-radius: 11px;
  background: linear-gradient(var(--surface), #f8f5ef);
  border: 1px solid rgba(255, 255, 255, .95);
  box-shadow: 0 8px 16px -6px rgba(81, 93, 63, .35), 0 2px 4px rgba(34, 33, 29, .08);
  transition: transform .25s cubic-bezier(.3, .7, .4, 1), opacity .15s ease;
}
.vl-teilwahl-felder:not(:has(input:checked))::before { opacity: 0; }
.vl-teilwahl-felder:has(.vl-teilwahl-feld:nth-child(2) input:checked)::before { transform: translateX(calc(100% - 3px)); }
.vl-teilwahl-felder:has(.vl-teilwahl-feld:nth-child(3) input:checked)::before { transform: translateX(calc(200% - 6px)); }
/* Startpunkt nach einem Neuaufbau (K.teilWahlGleiten): fuer einen
   Augenblick steht die Flaeche am alten Feld. !important, weil die
   :has()-Regeln darueber spezifischer sind. */
.vl-teilwahl-felder[data-von]::before { transition: none !important; opacity: 1 !important; }
.vl-teilwahl-felder[data-von="0"]::before { transform: none !important; }
.vl-teilwahl-felder[data-von="1"]::before { transform: translateX(calc(100% - 3px)) !important; }
.vl-teilwahl-felder[data-von="2"]::before { transform: translateX(calc(200% - 6px)) !important; }
@media (prefers-reduced-motion: reduce) {
  .vl-teilwahl-felder::before { transition: none; }
}
.vl-teilwahl-feld {
  -webkit-tap-highlight-color: transparent; /* kein grauer Kasten beim Antippen am Handy */
  z-index: 1;
  position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 1px; min-height: 44px; padding: 6px 4px; border-radius: 9px;
  font-size: .78rem; font-weight: 600; line-height: 1.2; text-align: center;
  color: var(--ink-soft); cursor: pointer; transition: color .15s ease;
}
.vl-teilwahl-feld input { position: absolute; opacity: 0; width: 1px; height: 1px; margin: 0; pointer-events: none; }
.vl-teilwahl-feld small { font-size: .7rem; font-weight: 500; color: var(--muted); white-space: nowrap; }
.vl-teilwahl-inkl { font-size: .66rem; font-weight: 500; color: var(--muted); }
.vl-teilwahl-feld:hover { color: var(--ink); }
.vl-teilwahl-feld:has(input:checked) { color: var(--ink); }
.vl-teilwahl-feld:has(input:checked) small { color: var(--accent-deep); font-weight: 600; }
.vl-teilwahl-feld:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 1px; }
.vl-teilwahl-feld.ist-gesperrt { cursor: not-allowed; opacity: .5; }
.vl-teilwahl-feld.ist-gesperrt:hover { color: var(--ink-soft); }

/* In der Kachel liegt er ueber dem Flaechenlink - sonst oeffnete ein Tipp
   die Produktseite statt umzuschalten. */
.vl-artikel-karte .vl-teilwahl { position: relative; z-index: 2; }
/* Am Rechner so breit wie das Foto darueber statt nur wie die Textspalte:
   In 238 Pixeln brachen "Nur Biertisch" und "Nur Bierbaenke" auf zwei
   Zeilen (Noah, 25.09.2026). Am Handy steht die Karte anders und hat die
   Breite ohnehin. */
@media (min-width: 901px) {
  .vl-artikel-karte .vl-teilwahl-felder { margin-inline: -20px; }
  .vl-artikel-karte .vl-teilwahl-frage { margin-inline: -20px; }
  .vl-artikel-karte .vl-teilwahl-feld { padding-inline: 1px; font-size: .74rem; }
}

/* --- Zeitraumleiste im Buchungswidget -------------------------------------
   Auf der Startseite ist die Leiste ein Band ueber die volle Seitenbreite.
   Im Widget der Produktseite sitzt sie in einem Kasten, der schon einen
   Rahmen und Innenabstand mitbringt - beides hier zuruecknehmen, sonst
   entsteht ein Rahmen im Rahmen und die Leiste steht zu weit innen. */

.kb-zeitraum { margin-top: 12px; }
.kb-zeitraum .vl-zeitleiste {
  background: none; border: 0; padding: 0; margin: 0;
}
.kb-zeitraum .vl-zeit-innen {
  padding: 0; max-width: none; width: auto;
}
/* "Von wann bis wann?" entfaellt in der Kaufbox (Noah, 25.09.2026): Die
   Felder darunter heissen "Von" und "Bis" und tragen ein Kalendersymbol -
   die Frage sagte dasselbe noch einmal und kostete rund 40 Pixel. Auf der
   Startseite bleibt sie; dort steht der Terminwaehler ohne Preis und
   Ueberschrift allein und braucht die Einladung. */
.kb-zeitraum .vl-zeit-zeile { gap: 10px; }
.kb-zeitraum .vl-zeit-frage { display: none; }
/* Mittig unter dem Preis, wie die Tagesleiste darunter (Noah, 09.10.2026).
   Unter 900 Pixel fuellen die Felder ohnehin die ganze Breite. */
.kb-zeitraum .vl-spanne { flex: 1 1 100%; justify-content: center; }
.kb-zeitraum .vl-tagesleiste { flex: 1 1 100%; }

/* Der Satz der Leiste ist im Widget die einzige Bestaetigung, dass der
   gewaehlte Zeitraum frei ist: Der Statuskasten darueber ist im September 2026
   entfallen, weil er dasselbe sagte, und der Warnhinweis erscheint nur, wenn
   etwas nicht passt. */
/* Reichlich Abstand nach oben: Das weisse Fenster wirft einen Schatten bis
   34 Pixel nach unten, bei 6 Pixel Abstand stand der Satz mitten darin. */
.kb-zeitraum .vl-zeit-satz { margin-top: 14px; }

/* Der Verfuegbarkeitssatz gehoert zum Zeitraum, nicht zur Menge. Ohne
   eigenen Abstand las sich "130 verfuegbar" wie die Beschriftung des
   Zaehlers direkt darunter. */
.kb-zeitraum + .kb-menge { margin-top: 20px; }

/* --- Preis im Produktwidget ----------------------------------------------
   Loest den gruenen Zusammenfassungskasten ab. Er wiederholte Zeitraum,
   Stueckzahl und Artikelnamen, die alle unmittelbar darueber stehen - neu war
   nur der Betrag. Jetzt eine Zeile mit Trennlinie, ohne eigenen Kasten. */

.vl-preis {
  margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line);
}
/* Die Einzelposten erscheinen nur bei mehreren Positionen. */
.vl-preis .vl-zeile { padding: 3px 0; }
.vl-preis .vl-zeile--gesamt {
  border-top: 0; margin-top: 2px; padding-top: 4px;
  font-family: var(--sans); font-size: 1.15rem; font-weight: 700;
}
.vl-preis .vl-zeile--gesamt span:first-child {
  font-size: .92rem; font-weight: 600; color: var(--ink-soft);
  align-self: center;
}
.vl-preis-hinweis {
  margin: 4px 0 0; font-size: .8rem; color: var(--muted); line-height: 1.4;
}

/* Monat des sichtbaren Ausschnitts. Steht über dem Streifen und läuft beim
   Blättern mit — die Datumsfelder darüber zeigen die Auswahl, nicht den
   Ausschnitt, und ohne diese Zeile weiß nach drei Klicks niemand mehr,
   welcher Monat da steht. */
/* Monatszeile und Tagesstreifen gehören zusammen: Als getrennte Kinder der
   Flex-Zeile stand der Monat auf breiten Bildschirmen neben dem Streifen
   statt darüber. Als Block nimmt er dessen Platz ein und bricht mit ihm um. */
.vl-streifen { flex: 1 1 320px; min-width: 0; }

/* Ab hier eine eigene Zeile. Teilt sich der Streifen die Zeile mit den
   Datumsfeldern, schrumpfen die unter die Breite eines Datums: Auf dem iPad
   hochkant standen dort "30.09." und "04.10." - ohne Jahr, und das ist bei
   Terminen 12 bis 18 Monate im Voraus die halbe Auskunft.

   Die Regel stand bis zum 22.09.2026 weiter oben auf .vl-tagesleiste. Die
   sitzt innerhalb von .vl-streifen und ist damit kein Flex-Element dieser
   Zeile - flex-basis blieb dort wirkungslos. Unter etwa 460 Pixeln fiel es
   nicht auf, weil der Streifen schon an seiner Mindestbreite umbrach.

   Sie steht hier und nicht bei den uebrigen 900er-Regeln, weil die Kurzform
   "flex" eine Zeile darueber die Basis mitsetzt: Von zwei gleich starken
   Regeln gewinnt die spaetere, und eine Media Query aendert daran nichts. */
@media (max-width: 900px) {
  .vl-streifen { flex-basis: 100%; }
}

.vl-streifen-monat {
  margin: 0 0 2px; text-align: center;
  font-size: .78rem; font-weight: 600; letter-spacing: .02em;
  color: var(--ink-soft);
}

/* --- Monatsansicht im Streifen -------------------------------------------
   Aufklappbar unter dem Wochenstreifen. Bei Artikeln, die es nur einmal gibt,
   steht sie von Anfang an offen: Dort ist jede Buchung ein blockierter
   Termin, und die Frage lautet "wann geht es überhaupt" statt "wie viele
   bekomme ich". Optik wie der Streifen — weißes Papier, kein Farbraster. */

/* Beide sind Kinder der Flex-Zeile, in der auch die Felder und der Streifen
   liegen - ohne diese Angabe schrumpfen sie auf den Rest der Zeile statt die
   volle Breite zu nehmen. */
.vl-monat-schalter, .vl-monat-halter { flex: 1 1 100%; }

/* Als Textzeile statt als Knopf: Der Umschalter ist ein Nebenweg und stand
   als gerahmter Block über die volle Breite genauso laut da wie die Eingaben
   darüber. Die Fläche zum Antippen bleibt trotzdem groß genug — sie steckt im
   Innenabstand, nicht im Rahmen. */
.vl-monat-schalter {
  display: block; width: 100%;
  margin-top: 4px; padding: 7px 12px;
  border: 0; background: none;
  font: inherit; font-size: .8rem; font-weight: 600; color: var(--accent-deep);
  cursor: pointer; text-align: center;
  text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, var(--accent-deep) 35%, transparent);
  transition: text-decoration-color .15s ease;
}
.vl-monat-schalter:hover { text-decoration-color: var(--accent-deep); }

/* Ein Monatsraster wird nicht besser, wenn es breiter wird - es wird nur
   unhandlich. Es sitzt am Platz des Streifens und ist auf Kalenderblattbreite
   begrenzt; auf schmalen Geräten greift die Grenze ohnehin nicht. */
/* Rechts im Block, wo auch der Streifen endet - und der Umschalter darunter
   auf derselben Breite, damit seine Beschriftung mittig unter dem Kalender
   steht. */
.vl-monat-halter {
  margin-top: 6px; max-width: 340px; width: 100%; margin-left: auto;
}
/* Im Widget der Produktseite steht kein Streifen rechts, an dessen Kante der
   Monat sich ausrichten muesste - dort sitzen Kalender und Umschalter mittig
   im Kasten. */
.kb-zeitraum .vl-monat-halter,
.kb-zeitraum .vl-streifen.zeigt-monat .vl-monat-schalter {
  margin-left: auto; margin-right: auto;
}
.vl-streifen.zeigt-monat .vl-monat-schalter { max-width: 340px; margin-left: auto; }

/* Schwebendes Monatsblatt (breite Bildschirme, Band der Startseite).
   Vorher wuchs das Band beim Aufklappen um gut 300 Pixel und schob den
   Seiteninhalt nach unten; weil dabei die Wochenansicht wich, stand links
   neben dem Kalender eine leere Flaeche. Jetzt bleibt das Band, wie es ist,
   und der Monat legt sich als Blatt ueber den Abschnitt darunter - mittig
   unter dem Umschalter, der ihn geoeffnet hat. */
.vl-streifen { position: relative; }
.vl-zeitleiste:has(.vl-streifen.schwebt-monat) { position: relative; z-index: 30; }
/* Das Blatt beginnt oben am Streifen und legt sich ueber ihn (Noah,
   30.09.2026). Vorher hing es darunter, und weil der Streifen dafuer ganz
   weichen musste, schrumpfte das Band beim Aufklappen von 134 auf 89 Pixel -
   Umschalter und alles darunter sprangen nach oben. Jetzt bleibt der Streifen
   unsichtbar liegen und haelt die Hoehe; das Blatt deckt ihn zu, es gibt
   also weder eine Dopplung noch eine leere Flaeche. */
.vl-streifen.schwebt-monat .vl-monat-halter {
  position: absolute; top: -6px; left: 50%;
  transform: translateX(-50%);
  width: 340px; max-width: none; margin: 0; z-index: 30;
  padding: 16px 16px 8px; background: var(--surface);
  border: 1px solid var(--line); border-radius: 16px;
  box-shadow: 0 18px 44px rgba(43, 38, 30, .18);
}
/* Der Umschalter steht dann im Blatt, an dessen Fuss (verleih-zeitraum.js,
   schalterUmsetzen). */
.vl-streifen.schwebt-monat .vl-monat-schalter { max-width: none; margin: 6px 0 0; }
/* Den Platz, den der Umschalter im Band hatte (4 px Abstand plus 36 px
   Hoehe), haelt der Streifen selbst frei - sonst schrumpfte das Band
   trotzdem um diese 40 Pixel. Die Zeilenhoehe ist deshalb fest gesetzt. */
.vl-monat-schalter { line-height: 22px; }
.vl-streifen.schwebt-monat { padding-bottom: 40px; }

/* Wochenansicht und Monat zeigen denselben Zeitraum - beide gleichzeitig
   sichtbar ist eine Dopplung. Der Streifen wird deshalb unsichtbar, behaelt
   aber seinen Platz: Das Band bleibt so hoch wie zugeklappt. */
.vl-streifen.schwebt-monat > .vl-streifen-monat,
.vl-streifen.schwebt-monat > .vl-tagesleiste { visibility: hidden; }

/* Der Monatskalender selbst: weiße Tage statt farbiger Flächen, der gewählte
   Zeitraum als Band. */
.vl-monat-halter .vl-kalender { border: 0; padding: 0; background: none; }
.vl-monat-halter .vl-kopf {
  display: flex; align-items: center; justify-content: space-between;
  margin-bottom: 8px;
}
.vl-monat-halter .vl-monat {
  margin: 0; font-family: inherit; font-size: .9rem; font-weight: 600;
}
.vl-monat-halter .vl-tag > span:first-child { background: none; }
/* Dieselbe Abstufung wie im Streifen: freie Tage gedämpft, der gewählte
   Zeitraum dunkel und fett. Vorher waren im Monat alle Tage gleich dunkel -
   das war der Unterschied, den man sah, ohne ihn benennen zu können. */
.vl-monat-halter .vl-tag[data-status="frei"] > span:first-child,
.vl-monat-halter .vl-tag[data-status="knapp"] > span:first-child,
/* "offen" trägt der Kalender ohne Belegung — auf der Startseite, wo er nur
   ein Datum wählt. Er soll dort aussehen wie ein freier Tag, ohne einer zu
   behaupten zu sein. */
.vl-monat-halter .vl-tag[data-status="offen"] > span:first-child {
  background: none; color: var(--ink-soft);
}
.vl-monat-halter .vl-tag[data-status="ausgebucht"] > span:first-child {
  background: none; color: var(--muted); opacity: .5;
}

/* --- Band im Monatskalender ----------------------------------------------
   Dasselbe weiße Papier wie das Fenster im Streifen, nur über mehrere
   Wochenzeilen verteilt: je Zeile ein Segment. Rund wird ein Segment an den
   echten Enden des Zeitraums; wo die Woche umbricht, läuft es glatt aus. */

.vl-monat-halter .vl-raster { position: relative; }

.vl-monat-band {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
}
.vl-monat-band-teil {
  position: absolute; background: #fff; border-radius: 14px;
  cursor: grab; touch-action: none; pointer-events: auto;
  box-shadow: 0 1px 2px rgba(34, 33, 29, .16),
              0 4px 8px rgba(34, 33, 29, .16),
              0 10px 20px rgba(34, 33, 29, .20),
              0 18px 34px rgba(34, 33, 29, .10);
}
.vl-monat-band-teil:active { cursor: grabbing; }
/* Wo der Zeitraum in der nächsten Zeile weitergeht, bleibt die Kante gerade. */
.vl-monat-band-teil[data-offen-links="ja"] {
  border-top-left-radius: 0; border-bottom-left-radius: 0;
}
.vl-monat-band-teil[data-offen-rechts="ja"] {
  border-top-right-radius: 0; border-bottom-right-radius: 0;
}

/* Die Zahlen liegen über dem Papier, nicht darunter — wie im Streifen. */
.vl-monat-halter .vl-tag { position: relative; z-index: 3; }
/* Auf den Tagen des gewählten Zeitraums beginnt das Ziehen. Ohne diese Zeile
   deutet der Browser die Wischbewegung als Scrollen, bricht die Zeigerfolge
   mit pointercancel ab — und das Band bleibt stehen. Nur hier, damit sich die
   Seite über dem übrigen Kalender normal scrollen lässt. */
.vl-monat-halter .vl-tag[data-im-zeitraum="ja"] { touch-action: none; }
/* Läuft ein Zug, gilt das für den ganzen Monat: Der Finger wandert über Tage,
   die eben noch außerhalb des Zeitraums lagen. */
.vl-monat-halter .vl-raster.ist-im-zug,
.vl-monat-halter .vl-raster.ist-im-zug .vl-tag { touch-action: none; }
.vl-monat-halter .vl-raster.ist-im-zug .vl-tag { cursor: grabbing; }
/* Kein pointer-events: none - die Zellen muessen auffindbar bleiben. Beim
   Ziehen wird der Tag unter dem Finger gesucht, und was keine Zeigerereignisse
   annimmt, taucht in elementsFromPoint gar nicht erst auf. */
.vl-monat-halter .vl-tag[data-im-zeitraum="ja"] {
  background: none; box-shadow: none;
}
.vl-monat-halter .vl-tag[data-im-zeitraum="ja"] > span:first-child {
  background: none; color: var(--ink); font-weight: 700;
}

/* Griffe am Monatsband. Eigene Klasse, weil .vl-griff dem Fenster der
   Zeitleiste gehört — dieselbe Optik, aber unabhängig davon änderbar. */
.vl-bandgriff {
  position: absolute; top: 0; bottom: 0; width: 26px; z-index: 3;
  display: flex; align-items: center; justify-content: center;
  cursor: ew-resize; touch-action: none;
}
.vl-bandgriff--links { left: -13px; }
.vl-bandgriff--rechts { right: -13px; }
.vl-bandgriff::before {
  content: ""; width: 3px; height: 18px; border-radius: 999px; background: var(--muted);
}

/* ===========================================================================
   Passt dazu - Vorschlaege nach "In den Warenkorb" und in der Kasse
   ---------------------------------------------------------------------------
   Ruhig gehalten: helle Flaeche statt Rahmen, der Knopf als Umriss statt
   gefuellt. Der Hauptweg - Warenkorb, Kasse, Buchen - bleibt der einzige
   volle Knopf auf der Seite.
   =========================================================================== */
.vl-dazu-halter:empty { display: none; }
.vl-dazu-halter { margin-top: 18px; }
#vl-dazu-liefer { margin-top: 0; }
.vl-dazu {
  background: var(--bg); border: 1px solid var(--line); border-radius: 14px;
  padding: 14px 14px 4px;
}
/* Ueberschrift in der Serifenschrift wie "Oft zusammen gemietet" auf den
   Produktseiten - vorher klein und in Grossbuchstaben, das las sich wie eine
   Fussnote statt wie ein Angebot. */
.vl-dazu-titel {
  margin: 0 0 4px; font-family: var(--serif); font-size: 1.05rem; color: var(--ink);
}
.vl-dazu-satz { margin: 4px 0 8px; font-size: .9rem; color: var(--ink-soft); line-height: 1.45; }
.vl-dazu-satz strong { color: var(--ink); }
.vl-dazu > .vl-dazu-satz:only-child { margin: 0 0 8px; }
/* Lieferschwelle als feiner Balken - dieselbe Optik wie auf den
   Produktseiten (.pdp-schwelle in style.css), hier in verleih.css, weil die
   Kasse beiden Marken gehoert. */
.vl-dazu-satz .vl-schwelle-text {
  display: flex; justify-content: space-between; align-items: baseline; gap: 10px;
  margin: 0 0 8px; font-size: .86rem; color: var(--ink-soft);
}
.vl-schwelle-text b { color: var(--ink); font-weight: 600; }
.vl-schwelle-text small { flex: none; font-size: .74rem; color: var(--muted); white-space: nowrap; }
.vl-schwelle-bahn {
  display: block; height: 6px; border-radius: 99px; background: var(--bg-2); overflow: hidden;
  margin-bottom: 4px;
}
.vl-schwelle-bahn i {
  display: block; height: 100%; border-radius: 99px; background: var(--accent);
  transition: width .4s ease;
}
@media (prefers-reduced-motion: reduce) { .vl-schwelle-bahn i { transition: none; } }
.vl-dazu-liste { list-style: none; margin: 0; padding: 0; }
/* Je Artikel ein Raster: Bild links ueber beide Zeilen, der Name oben ueber
   die ganze restliche Breite, darunter Preis links und Mengenfeld rechts.
   Vorher standen Name, Preis und Regler nebeneinander - auf dem Handy blieb
   dem Namen so wenig Platz, dass "Profi-Partyzelt 4 x 6 m" ueber drei
   Zeilen brach (Noah, 25.09.2026). Das Mengenfeld ist die ganze Bedienung. */
.vl-dazu-zeile {
  display: grid; grid-template-columns: 48px minmax(0, 1fr) auto;
  grid-template-areas: "bild name name" "bild info regler" "grenze grenze grenze";
  column-gap: 12px; row-gap: 2px; align-items: center;
  padding: 11px 0; border-top: 1px solid var(--line);
}
.vl-dazu-titel + .vl-dazu-liste .vl-dazu-zeile:first-child,
.vl-dazu-satz + .vl-dazu-liste .vl-dazu-zeile:first-child { border-top: 0; }
.vl-dazu-bild {
  grid-area: bild; align-self: center; width: 48px; height: 48px; border-radius: 10px;
  background: var(--bg-2); overflow: hidden;
}
.vl-dazu-bild img { width: 100%; height: 100%; object-fit: contain; display: block; padding: 3px; }
.vl-dazu-text { display: contents; }
/* Oben Name und Preis wie auf der Startseite (.vl-karte-kopf): der Preis in
   der Serifenschrift rechts daneben, bei Platzmangel darunter. Darunter die
   Einheit und - nur wenn es etwas zu sagen gibt - der Zustand. Der Preis
   bleibt in jedem Zustand stehen (Noah, 30.09.2026). */
.vl-dazu-kopf {
  grid-area: name; align-self: end; display: flex; align-items: baseline;
  justify-content: space-between; flex-wrap: wrap; gap: 0 10px; min-width: 0;
}
.vl-dazu-kopf strong { font-size: .92rem; font-weight: 600; color: var(--ink); line-height: 1.3; }
.vl-dazu-preis {
  font-family: var(--serif); font-size: 1.02rem; color: var(--accent-deep); white-space: nowrap;
}
.vl-dazu-unter { grid-area: info; display: flex; flex-direction: column; min-width: 0; }
.vl-dazu-einheit { font-size: .8rem; color: var(--muted); line-height: 1.35; }
.vl-dazu-info { font-size: .8rem; color: var(--muted); line-height: 1.35; }
.vl-dazu-info.ist-drin { color: var(--accent-deep); font-weight: 600; }
.vl-dazu-regler { grid-area: regler; }

/* Der Regler der Kasse, eine Stufe kleiner: In der Zeile steht er neben
   Bild und Namen, nicht in einer eigenen Reihe. */
.vl-dazu-regler { flex: none; gap: 2px; }
.vl-dazu-regler .rund { width: 32px; height: 32px; font-size: 1rem; }
.vl-dazu-regler .rund:not(:disabled) { border-color: var(--accent); color: var(--accent-deep); }
.vl-dazu-regler .vl-mengenzahl { width: 36px; font-size: .98rem; padding: 4px 0; }
.vl-dazu-regler .vl-mengenzahl:disabled { color: var(--muted); background: transparent; }
.vl-dazu-grenze {
  grid-area: grenze; font-size: .8rem; font-weight: 600; color: var(--vl-weg); text-align: right;
}

/* Kasse: Ueberschrift ueber der Lieferanschrift, gleiche Form wie
   "Wunschzeit fuer Anlieferung" darunter. */
/* Der Lieferblock ist ein zweispaltiges Raster (PLZ | Ort) - Vorschlaege
   und Ueberschrift gehen ueber die ganze Breite. */
#vl-lieferfelder > .vl-dazu-halter,
.vl-lieferadresse-kopf { grid-column: 1 / -1; }
.vl-lieferadresse-kopf { margin: 4px 0 -4px; }

/* Kasse: Hinweis unter einer Artikelzeile, wenn die Menge ueber dem liegt,
   was im Zeitraum frei ist. */
.vl-korbzeile-grenze {
  grid-area: grenze; margin-top: 6px; font-size: .8rem; font-weight: 600; color: var(--vl-weg);
}

/* "Oft zusammen gemietet": Link (Bild, Name, Preis) links, Mengenfeld
   rechts - verleih-widget.js packt beides in eine .bundle-zeile. */
/* Eine Zeile, ein Raster - dasselbe wie "Dazu passt" in der Kasse:
     [Bild]  Name ................ Preis
             Einheit          (−) 0 (+)
             Zustand (nur bei Bedarf)
   Vorher standen Link und Regler als zwei Bloecke nebeneinander; der Preis
   hing zwischen Name und Regler, ohne gemeinsame Kante mit irgendetwas
   (Noah, 30.09.2026). Der Link bleibt ein Block (fuer Google und die
   Tastatur) und uebernimmt die Spalten der Zeile per subgrid - so steht der
   Preis buendig ueber der rechten Kante des Reglers. */
.pdp-bundle .bundle-zeile {
  display: grid; grid-template-columns: 52px minmax(0, 1fr) auto;
  column-gap: 12px; row-gap: 1px; align-items: center;
  padding: 10px 0; border-top: 1px solid var(--line);
}
.pdp-bundle .bundle-zeile > .bundle-item {
  grid-column: 1 / -1; grid-row: 1 / span 3;
  display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid;
  min-width: 0; padding: 0; border-top: 0;
}
.pdp-bundle .bundle-zeile .bundle-item img { grid-column: 1; grid-row: 1 / span 3; }
.pdp-bundle .bundle-zeile .bundle-kopf { grid-column: 2 / -1; grid-row: 1; }
.pdp-bundle .bundle-zeile .bundle-einheit { grid-column: 2; grid-row: 2; }
/* Der Zustand traegt .vl-dazu-info, deren Raster der Kasse eine grid-area
   "info" kennt, die es hier nicht gibt - ohne ausdrueckliche Lage legte der
   Browser leere Zusatzspalten an (Noah, 25.09.2026). */
.pdp-bundle .bundle-zeile .vl-dazu-info { grid-area: auto; grid-column: 2; grid-row: 3; }
/* Der Behaelter traegt .vl-dazu-zeile und damit das Raster der Kasse -
   hier steht nur der Regler, also kein eigenes Raster (Noah, 25.09.2026).
   Er liegt ueber der Flaeche des Links, in der Zeile der Einheit. */
.pdp-bundle .bundle-dazu {
  grid-column: 3; grid-row: 2 / span 2; align-self: center; justify-self: end;
  position: relative; display: block; padding: 0; border: 0;
}
.pdp-bundle .bundle-zeile > .vl-dazu-grenze { grid-column: 1 / -1; grid-row: 4; }
.pdp-bundle .bundle-dazu:empty { display: none; }
/* Ohne JavaScript stehen die Artikel direkt im Block (ohne .bundle-zeile) -
   dann nur die ersten zwei der Rangliste. Mit JavaScript waehlt
   verleih-widget.js, welche zwei. */
.pdp-bundle > .bundle-item:nth-of-type(n+3) { display: none; }
.bundle-ohne-zeitraum {
  margin: 4px 0 0; padding-top: 10px; border-top: 1px solid var(--line);
  font-size: .88rem; color: var(--ink-soft); line-height: 1.45;
}
.bundle-ohne-zeitraum button {
  font: inherit; font-weight: 600; color: var(--accent-deep); background: none;
  border: 0; padding: 0; cursor: pointer; text-decoration: underline;
  text-underline-offset: 2px;
}

/* Gedrueckt halten zaehlt weiter (verleih-core.js): Ohne das markiert das
   Handy beim langen Druecken Text oder zoomt beim schnellen Tippen. */
button.rund[data-schritt], .kb-stepper button[data-schritt] {
  touch-action: manipulation; user-select: none; -webkit-user-select: none;
  -webkit-touch-callout: none;
}

/* Plus und Minus gezeichnet statt geschrieben (Noah, 30.09.2026). Als
   Zeichen der Schrift sassen sie gut 1,5 px unter der Kreismitte - Inter
   setzt "+" und "−" auf die Hoehe der Kleinbuchstaben, nicht in die Mitte
   der Zeile. Die Striche sitzen mit inset/margin: auto exakt mittig. Alle
   Kreise haben gerade Innenmasse (40/36/34/32 minus Rand), dazu 12 x 2 px
   Striche - so landen sie auf ganzen Pixeln und bleiben scharf. Das Zeichen
   bleibt im Knopf, nur unsichtbar; vorgelesen wird ohnehin das aria-label. */
button.rund[data-schritt], .kb-stepper button[data-schritt] {
  /* !important, weil Warenkorb und Kasse die Schriftgroesse spezifischer
     setzen (.vl-korbzeile .vl-mengenregler .rund) - dort stuenden sonst
     Zeichen und Striche uebereinander. */
  position: relative; font-size: 0 !important;
}
button.rund[data-schritt]::before, .kb-stepper button[data-schritt]::before,
button.rund[data-schritt="1"]::after, .kb-stepper button[data-schritt="1"]::after {
  content: ""; position: absolute; inset: 0; margin: auto;
  width: 12px; height: 2px; border-radius: 1px; background: currentColor;
}
button.rund[data-schritt="1"]::after, .kb-stepper button[data-schritt="1"]::after {
  width: 2px; height: 12px;
}
