:root {
  /* Farbwelt: ans Logo-Gold angeglichen, Elfenbein statt kaltem Weiß */
  --gold: #bf9c5a;
  --gold-bright: #e3c88f;
  --ink: #f3eee2;
  --muted: rgba(240, 232, 216, 0.62);
  --bg: #050505;

  /* Bedienelemente: ein Satz Werte für Felder, Auswahl und Knöpfe. Steht hier,
     weil sonst jede der rund zwanzig Formularregeln ihre eigene Rundung und ihr
     eigenes Tempo mitbringt — und die Oberfläche genau dadurch zusammen-
     gestückelt wirkt. Die Kurve ist dieselbe, die Hero und Kollektion nutzen. */
  --field-radius: 10px;
  --control-radius: 6px;
  --button-radius: 12px;
  --field-bg: rgba(255, 255, 255, 0.04);
  --field-border: rgba(228, 205, 158, 0.16);
  --ease: 0.28s cubic-bezier(0.2, 0.7, 0.2, 1);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

/* ══════════════════════════════════════════════════════════════════════
   KNÖPFE — ein Satz Regeln für die ganze Anwendung
   ══════════════════════════════════════════════════════════════════════
   Vorher hatte jeder Bereich seinen eigenen Knopf: sechs Klassen, drei
   Rundungen, zwei davon ganz eckig, fünf Buchstabenabstände und vier
   Übergangszeiten. Das ist der Grund, warum die Oberfläche zusammen-
   gestückelt wirkte.

   Jetzt gibt es vier Rollen, und jede Klasse gehört zu genau einer:

     Hauptweg     .iq-btn  .ap-btn  .login-btn      gefüllt, goldener Verlauf
     Zweitrangig  .ap-btn-ghost                     Fläche mit feiner Kante
     Leise        .shop-back                        nur Schrift, Fläche beim Zeigen
     Filter       .filter-btn                   klein, gemischt geschrieben

   Die Anmutung heisst „Mattes Metall": eine feine Lichtkante an der
   Oberseite, wie sie ein gebürstetes Gehäuse fängt. Sie steckt in
   --knopf-kante und ist der einzige Grund, warum hier box-shadow steht.

   Neue Knöpfe bekommen eine dieser Klassen — es wird kein siebter Stil
   angelegt. */

:root {
  --knopf-radius: 12px;
  --knopf-kante: inset 0 1px 0 rgba(255, 255, 255, 0.07);
  --knopf-kante-hell: inset 0 1px 0 rgba(255, 255, 255, 0.12);
  --knopf-kante-gold: inset 0 1px 0 rgba(255, 255, 255, 0.35);
}

/* ---- Gemeinsame Grundlage ---- */
.iq-btn,
.ap-btn,
.ap-btn-ghost,
.login-btn,
.shop-ankauf,
.shop-back,
.filter-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  font-family: var(--font-sans), sans-serif;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 1.6px;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  background-color: rgba(255, 255, 255, 0.045);
  border: 1px solid rgba(228, 205, 158, 0.14);
  border-radius: var(--knopf-radius);
  box-shadow: var(--knopf-kante);
  padding: 14px 30px;
  cursor: pointer;
  transition:
    background-color var(--ease),
    border-color var(--ease),
    color var(--ease),
    box-shadow var(--ease),
    transform var(--ease);
}

.iq-btn:not(:disabled):hover,
.ap-btn:not(:disabled):hover,
.ap-btn-ghost:not(:disabled):hover,
.login-btn:not(:disabled):hover,
.filter-btn:not(:disabled):hover {
  background-color: rgba(255, 255, 255, 0.075);
  border-color: rgba(228, 205, 158, 0.34);
  box-shadow: var(--knopf-kante-hell), 0 6px 20px -8px rgba(0, 0, 0, 0.9);
  transform: translateY(-1px);
}

.iq-btn:focus-visible,
.ap-btn:focus-visible,
.ap-btn-ghost:focus-visible,
.shop-ankauf:focus-visible,
.login-btn:focus-visible,
.shop-back:focus-visible,
.filter-btn:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

.iq-btn:disabled,
.ap-btn:disabled,
.ap-btn-ghost:disabled,
.login-btn:disabled,
.filter-btn:disabled {
  opacity: 0.45;
  cursor: default;
  transform: none;
}

/* ---- Hauptweg: der eine Knopf, der die Sache abschliesst ----
   Ein Verlauf statt einer flachen Fläche — sonst wirkt Gold auf Schwarz
   wie ein Aufkleber. */
.iq-btn,
.ap-btn,
.login-btn,
.shop-ankauf {
  color: #0a0a0a;
  background: linear-gradient(180deg, #d3b070, var(--gold));
  border-color: rgba(227, 200, 143, 0.5);
  box-shadow: var(--knopf-kante-gold);
}
.iq-btn:not(:disabled):hover,
.ap-btn:not(:disabled):hover,
.login-btn:not(:disabled):hover,
.shop-ankauf:hover {
  color: #0a0a0a;
  background: linear-gradient(180deg, var(--gold-bright), #cba767);
  border-color: rgba(227, 200, 143, 0.7);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45),
              0 8px 24px -10px rgba(191, 156, 90, 0.7);
}
/* Der Anmeldeknopf trägt die ganze Breite des Formulars. */
.login-btn { width: 100%; margin-top: 4px; }
/* Wirkt nur, wo .iq-btn in einem Flex-Container sitzt (Anfrage- und
   Kaufformular). Im Ankaufformular ist der Elternteil ein Grid, dort läuft der
   Knopf weiterhin über die volle Formularbreite — so war es vorher auch, und
   für den einen Knopf, der die Sache abschliesst, ist das richtig. */
.iq-btn { align-self: flex-start; }

/* ---- Leise: der Rückweg, der niemandem im Weg steht ----
   Ohne Fläche und ohne Rand, bis der Zeiger darauf liegt. */
.shop-back {
  background: none;
  border-color: transparent;
  box-shadow: none;
  color: var(--muted);
  font-size: 11px;
  letter-spacing: 2.6px;
  padding: 14px 22px;
}
.shop-back:hover {
  background-color: rgba(255, 255, 255, 0.05);
  border-color: rgba(228, 205, 158, 0.2);
  color: var(--ink);
  box-shadow: none;
  transform: translateY(-1px);
}

/* ---- Filter: gemischt geschrieben, damit Zahlen lesbar bleiben ---- */
.filter-btn {
  font-size: 11.5px;
  letter-spacing: 0.4px;
  text-transform: none;
  color: var(--muted);
  padding: 8px 15px;
  border-radius: 10px;
}
.filter-btn:not(:disabled):hover { color: var(--ink); }
.filter-btn span {
  color: var(--gold-bright);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}
.filter-btn.is-active {
  color: #0a0a0a;
  background: linear-gradient(180deg, #d3b070, var(--gold));
  border-color: rgba(227, 200, 143, 0.5);
  box-shadow: var(--knopf-kante-gold);
}
.filter-btn.is-active span { color: rgba(10, 10, 10, 0.72); }

@media (prefers-reduced-motion: reduce) {
  .iq-btn, .ap-btn, .ap-btn-ghost, .login-btn,
  .shop-ankauf, .shop-back, .filter-btn {
    transition: background-color var(--ease), border-color var(--ease), color var(--ease);
  }
  .iq-btn:not(:disabled):hover,
  .ap-btn:not(:disabled):hover,
  .ap-btn-ghost:not(:disabled):hover,
  .login-btn:not(:disabled):hover,
  .shop-back:hover,
  .filter-btn:not(:disabled):hover { transform: none; }
}

/* ---- Kleine Aktionen in Listen und Karten ----
   „Bearbeiten", „Löschen", „Angebot senden": dieselbe Sprache wie oben, nur
   auf Listengrösse. Vorher waren die in .admin-item-actions ganz eckig und
   die in .ank-actions auf 6 px gerundet — zwei Stile für dieselbe Sache. */
.admin-item-actions button,
.col-item-actions button,
.inq-actions button,
.ank-actions button,
.ap-logout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: var(--font-sans), sans-serif;
  font-weight: 500;
  font-size: 10.5px;
  letter-spacing: 1.2px;
  text-transform: uppercase;
  color: var(--muted);
  background-color: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(228, 205, 158, 0.14);
  border-radius: 10px;
  box-shadow: var(--knopf-kante);
  padding: 8px 15px;
  cursor: pointer;
  transition:
    background-color var(--ease),
    border-color var(--ease),
    color var(--ease),
    box-shadow var(--ease),
    transform var(--ease);
}
.admin-item-actions button:not(:disabled):hover,
.col-item-actions button:not(:disabled):hover,
.inq-actions button:not(:disabled):hover,
.ank-actions button:not(:disabled):hover,
.ap-logout:hover {
  color: var(--ink);
  background-color: rgba(255, 255, 255, 0.075);
  border-color: rgba(228, 205, 158, 0.34);
  box-shadow: var(--knopf-kante-hell), 0 6px 20px -8px rgba(0, 0, 0, 0.9);
  transform: translateY(-1px);
}
.admin-item-actions button:focus-visible,
.col-item-actions button:focus-visible,
.inq-actions button:focus-visible,
.ank-actions button:focus-visible,
.ap-logout:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}
.ank-actions button:disabled,
.col-item-actions button:disabled,
.inq-actions button:disabled,
.admin-item-actions button:disabled {
  opacity: 0.45;
  cursor: default;
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  .admin-item-actions button:not(:disabled):hover,
  .col-item-actions button:not(:disabled):hover,
  .inq-actions button:not(:disabled):hover,
  .ank-actions button:not(:disabled):hover,
  .ap-logout:hover { transform: none; }
}
/* Steht als Block am Fuss der Seitenleiste. */
.ap-logout { width: 100%; }

/* ═══════════════════════ Ende Knöpfe ═══════════════════════ */


html {
  scroll-behavior: auto;
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-sans), sans-serif;
  overflow-x: hidden;
}
body.locked {
  overflow: hidden;
}

/* ---------- Video-Bühne ---------- */
.stage {
  position: fixed;
  inset: 0;
  z-index: 0;
  background: #000;
}
.stage video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* dezente Abdunklung für Textlesbarkeit an den Rändern */
.stage-grade {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 30%),
    linear-gradient(to bottom, rgba(0, 0, 0, 0.4), transparent 22%),
    linear-gradient(to right, rgba(0, 0, 0, 0.45), transparent 42%);
  pointer-events: none;
}

/* ---------- fixed chrome ---------- */
.chrome {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 20;
}
.chrome header {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 26px 44px;
}
.brand {
  display: flex;
  align-items: center;
  gap: 14px;
}
.brand-mark {
  height: 52px;
  width: auto;
  display: block;
  filter: drop-shadow(0 2px 10px rgba(0, 0, 0, 0.6));
}
.brand-text {
  font-size: 13px;
  letter-spacing: 7px;
  text-transform: uppercase;
  color: var(--ink);
}
.brand-text em {
  font-style: normal;
  color: var(--gold);
}
.brand-text span {
  display: block;
  font-size: 8px;
  letter-spacing: 4px;
  color: var(--muted);
  margin-top: 4px;
}
/* Fasst „Ankauf" und den Korb zusammen, damit .chrome header per
   space-between weiterhin nur zwei Kinder sieht: Marke links, beides
   rechts als eine Gruppe.

   `pointer-events: auto`, weil .chrome selbst durchlässig ist — sonst liesse
   sich hier nichts anklicken. Das trug vorher die Knopfklasse. */
.chrome .chrome-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  pointer-events: auto;
}

/* Über der Knopfzeile, nicht auf ihr (08.09.2026).

   Er stand auf `bottom: 26px` — genau der Zeile, auf der seit dem 06.09. der
   feste Hauptweg sitzt. Auf dem Telefon überlappten beide gemessen 134px,
   und das seit dem 06.09.; auf 1024px kam mit dem Weg nach innen (Task 0092)
   dieselbe Überschneidung auf dem Schreibtisch dazu.

   Von den beiden weicht der Hinweis: Er ist das flüchtige Element — ab 1,5 %
   Scroll-Fortschritt ist er fort — der Knopf das bleibende. 92px lassen dem
   Puls seine 6px Weg nach unten und halten trotzdem Abstand zur Oberkante
   des Knopfes. Die Rechnung: Knopf-Unterkante + Knopfhoehe + 24px Luft, auf
   dem Schreibtisch also 56 + 42 + 24 = 122. Wandert der Knopf, wandert diese
   Zahl mit — auf dem Telefon steht er tiefer (20px ab Unterkante, 33px hoch)
   und bekommt dadurch von selbst mehr Abstand. */
.scroll-hint {
  position: fixed;
  bottom: 122px;
  left: 50%;
  transform: translateX(-50%);
  font-size: 9px;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--muted);
  z-index: 15;
  animation: hintPulse 2.6s ease-in-out infinite;
}
@keyframes hintPulse {
  0%, 100% { opacity: 0.35; transform: translate(-50%, 0); }
  50% { opacity: 0.9; transform: translate(-50%, 6px); }
}
/* Nach dem ersten Scrollen verschwindet der Hinweis. Die Pulsation muss dabei
   ausdruecklich abgeschaltet werden: Eine laufende CSS-Animation setzt sich
   gegen jede Deckkraft durch, auch gegen eine direkt am Element gesetzte. */
.scroll-hint.ist-weg {
  animation: none;
  opacity: 0;
  transform: translate(-50%, 6px);
  transition: opacity 0.5s ease, transform 0.5s ease;
  pointer-events: none;
}

/* ---------- loader ---------- */
.loader {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: #050505;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 30px;
  /* Kürzer als früher (1,1 s): Ohne Klick ist die Ausblende Teil der
     Wartezeit, nicht mehr die Belohnung für einen Klick. */
  transition: opacity 0.8s ease, visibility 0.8s;
}
.loader.hidden {
  opacity: 0;
  visibility: hidden;
}
/* ---------- Logo-Intro „Luxury Gold Reveal" ---------- */

/* 1 — leiser Gold-Schimmer in der Mitte, blendet auf und atmet dezent */
.lx-aura {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(168px, 26.4vw);
  height: min(168px, 26.4vw);
  transform: translate(-50%, -54%);
  background: radial-gradient(
    circle,
    rgba(211, 174, 106, 0.20),
    rgba(191, 156, 90, 0.06) 38%,
    transparent 68%
  );
  filter: blur(8px);
  opacity: 0;
  pointer-events: none;
  animation:
    lxAura 0.9s ease both,
    lxBreath 4s ease-in-out 0.9s infinite;
}
@keyframes lxAura {
  from { opacity: 0; }
  to { opacity: 1; }
}
@keyframes lxBreath {
  0%, 100% { opacity: 0.72; }
  50% { opacity: 1; }
}

/* Bühne für Ring, Siegel und Emblem. Alle Ebenen liegen deckungsgleich
   übereinander und teilen sich die Bildkoordinaten des Emblems (929 x 858) —
   deshalb sind die Zahlen unten und in Loader.tsx direkt gemessene Bildpunkte
   und keine Umrechnungen.
   overflow:hidden + isolation:isolate halten Licht-Reflex und Screen-Blend
   strikt in der Bühne — sonst „geistern" sie über den restlichen Screen. */
.lx-stage {
  position: relative;
  width: min(126px, 23.4vw);
  aspect-ratio: 929 / 858;
  display: block;
  overflow: hidden;
  isolation: isolate;
}

/* 4 — das Emblem blendet hinter dem wachsenden Ring auf */
.lx-emblem {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  opacity: 0;
  animation: lxEmblemIn 0.75s cubic-bezier(0.2, 0.7, 0.2, 1) 1.55s both;
}
@keyframes lxEmblemIn {
  0%   { opacity: 0; filter: brightness(0.3) blur(8px); transform: scale(0.965); }
  60%  { opacity: 1; }
  100% { opacity: 1; filter: brightness(1) blur(0); transform: scale(1); }
}

/* 6 — Lichtatem: dieselbe Bildquelle ein zweites Mal, aber nur dort sichtbar,
   wo hinter der Figur das Licht steht (Schwerpunkt bei 43 % / 69 % gemessen,
   Abfall über rund 13 % der Breite). `screen` hellt die Goldpixel auf und
   lässt Schwarz unangetastet — es entsteht kein Grauschleier. */
.lx-breath {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
  mix-blend-mode: screen;
  pointer-events: none;
  opacity: 0;
  -webkit-mask-image: radial-gradient(
    circle at 43% 69%,
    #000 0%,
    rgba(0, 0, 0, 0.55) 10%,
    transparent 24%
  );
  mask-image: radial-gradient(
    circle at 43% 69%,
    #000 0%,
    rgba(0, 0, 0, 0.55) 10%,
    transparent 24%
  );
  animation:
    lxGlowIn 0.9s ease 2.25s both,
    lxGlow 6s ease-in-out 3.15s infinite;
}
@keyframes lxGlowIn {
  to { opacity: 0.3; }
}
@keyframes lxGlow {
  0%, 100% { opacity: 0.3; }
  50%      { opacity: 0.55; }
}

/* 3 — Siegel OHNE seinen Ring, konzentrisch zum Ring daneben. Die 45,8 % sind
   die vermessene Mitte der hinteren Zifferblatt-Scheibe: Siegel und Ring
   wachsen später um exakt denselben Punkt. */
.lx-seal {
  position: absolute;
  left: 50%;
  top: 45.8%;
  width: 36%;
  display: block;
  opacity: 0;
  animation:
    lxSealIn 0.6s ease 0.6s both,
    lxSealOut 0.35s ease 1.45s forwards;
}
@keyframes lxSealIn {
  0% {
    opacity: 0;
    filter: brightness(0.32) blur(5px);
    transform: translate(-50%, -50%) scale(0.985);
  }
  60% { opacity: 1; }
  100% {
    opacity: 1;
    filter: brightness(1) blur(0);
    transform: translate(-50%, -50%) scale(1);
  }
}
@keyframes lxSealOut {
  to { opacity: 0; }
}

/* 2 + 5 — Bühne des Rings, in den Bildkoordinaten des Emblems */
.lx-vec {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  pointer-events: none;
}

/* Der eine Ring: zeichnet sich mit Licht, wächst auf die Lünette des Emblems
   und geht dort in ihr auf. Ab da ist der einzige Ring im Bild der gemalte
   Rand des Zifferblatts — es liegen nie zwei übereinander.
   Radius und Strichstärke stehen in Bildkoordinaten: 1 Einheit = 1 Pixel der
   Emblemvorlage. Dadurch stimmt die Landung bei jeder Anzeigegröße, ohne dass
   irgendwo ein Faktor nachgeführt werden müsste. */
.lx-ring {
  fill: none;
  stroke: url(#lx-gold);
  stroke-linecap: round;
  stroke-dasharray: 100;
  stroke-dashoffset: 100;
  /* Zeichenbeginn von 3 Uhr auf 12 Uhr drehen */
  transform: rotate(-90deg);
  transform-origin: 464px 393px;
  transform-box: view-box;
  filter: drop-shadow(0 0 5px rgba(227, 200, 143, 0.55));
  animation:
    lxRingDraw 0.95s cubic-bezier(0.35, 0, 0.2, 1) 0.1s both,
    lxRingGrow 0.8s cubic-bezier(0.4, 0, 0.2, 1) 1.45s both,
    lxRingLand 0.3s ease 2.15s forwards;
}
@keyframes lxRingDraw {
  to { stroke-dashoffset: 0; }
}
@keyframes lxRingGrow {
  /* 126,6 = Radius des Siegelrings bei 36 % Bühnenbreite; 382 = Lünette.
     Die Strichstärke geht von der des Siegelrings auf die der Lünette. */
  from { r: 126.6px; stroke-width: 16.3; }
  to   { r: 382px;   stroke-width: 12; }
}
@keyframes lxRingLand {
  to { opacity: 0; }
}

/* 8 — dezenter metallischer Kanten-Reflex, fährt einmal über das Emblem */
.lx-shine {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    115deg,
    transparent 40%,
    rgba(255, 240, 202, 0.7) 50%,
    transparent 60%
  );
  /* overlay: hellt nur die Gold-Pixel auf, Schwarz bleibt schwarz */
  mix-blend-mode: overlay;
  transform: translateX(-135%);
  pointer-events: none;
  /* fährt erst, wenn der Ring gelandet und das Emblem stehengeblieben ist */
  animation: lxShine 1s ease-in-out 2.4s both;

  /* Weiche radiale Maske: der Lichtbalken blendet zum Rand hin sanft aus,
     statt an der harten Box-Kante abgeschnitten zu werden. Dadurch ist der
     rechteckige „Rahmen" während des Schimmerns nicht mehr sichtbar.
     Mittelpunkt auf der Zifferblatt-Mitte (50 % / 45,8 %), Ausdehnung so
     gewählt, dass der Bodenteller am unteren Rand mit ausläuft. */
  -webkit-mask-image: radial-gradient(
    ellipse 54% 52% at 50% 46%,
    #000 44%,
    rgba(0, 0, 0, 0.35) 70%,
    transparent 88%
  );
  mask-image: radial-gradient(
    ellipse 54% 52% at 50% 46%,
    #000 44%,
    rgba(0, 0, 0, 0.35) 70%,
    transparent 88%
  );
}
@keyframes lxShine {
  to { transform: translateX(135%); }
}

/* 9 — Wortmarke steigt ruhig von unten auf (ein Block, kein Springen) */
.lx-word {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  opacity: 0;
  animation: lxRise 0.75s cubic-bezier(0.2, 0.7, 0.2, 1) 2.5s both;
}
@keyframes lxRise {
  from { opacity: 0; transform: translateY(20px); filter: blur(3px); }
  to   { opacity: 1; transform: translateY(0);    filter: blur(0); }
}
/* Hier steht die Wortmarke als Bild statt als gesetzter Text: der Loader ist
   der Logo-Moment, dort zählt die Original-Typografie. Kopfzeilen und
   Verwaltung behalten den gesetzten Text — der bleibt in kleinen Größen
   scharf und ist auswählbar. */
.lx-word-mark {
  width: min(340px, 70vw);
  height: auto;
  display: block;
}
.lx-word-sub {
  font-family: var(--font-sans), sans-serif;
  font-weight: 300;
  font-size: 11px;
  letter-spacing: 7px;
  text-transform: uppercase;
  color: var(--muted);
}

/* Schmuckdetail: Haarlinien + kleiner goldener Stern */
.lx-jewel {
  display: flex;
  align-items: center;
  gap: 16px;
  opacity: 0;
  animation: lxFade 0.6s ease 2.7s both;
}
.lx-hair {
  width: 70px;
  height: 1px;
}
.lx-hair-l { background: linear-gradient(90deg, transparent, var(--gold)); }
.lx-hair-r { background: linear-gradient(90deg, var(--gold), transparent); }
/* 4-zackiger Gold-Stern aus zwei schmalen Rhomben */
.lx-star {
  position: relative;
  width: 12px;
  height: 12px;
  flex: none;
}
.lx-star::before,
.lx-star::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 50%, var(--gold-bright), var(--gold) 70%);
}
.lx-star::before { clip-path: polygon(50% 0, 58% 50%, 50% 100%, 42% 50%); }
.lx-star::after  { clip-path: polygon(0 50%, 50% 42%, 100% 50%, 50% 58%); }
@keyframes lxFade {
  to { opacity: 1; }
}

/* Ladebalken: läuft golden durch, dann öffnet sich die Seite von selbst.
   min-height hält die vertikale Rhythmik des Loaders stabil. */
.lx-cta {
  min-height: 52px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.lx-bar {
  position: relative;
  width: min(220px, 56vw);
  height: 1.5px;
  border-radius: 2px;
  background: rgba(240, 232, 216, 0.1);
  overflow: hidden;
  opacity: 0;
  /* erscheint zuletzt — wenn Wortmarke und Schmuckdetail stehen */
  animation: lxFade 0.5s ease 2.85s both;
}
/* Füllung wird skaliert statt in der Breite animiert: keine Layout-Arbeit
   pro Frame. Die kurze Transition glättet die rAF-Schritte aus page.tsx. */
.lx-bar-fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.18s linear;
  background: linear-gradient(90deg, rgba(201, 163, 94, 0.35), var(--gold-bright));
  box-shadow: 0 0 12px -2px rgba(227, 200, 143, 0.8);
}
/* helle Spitze am vorderen Ende — dieselbe Bildsprache wie der mit Licht
   nachgezogene Ring darüber */
.lx-bar-fill::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  width: 14px;
  background: linear-gradient(90deg, transparent, rgba(255, 244, 214, 0.95));
}

/* Bewegung reduziert? Direkt den Ruhezustand zeigen: das Emblem, wie es nach
   der Landung des Rings dasteht. */
@media (prefers-reduced-motion: reduce) {
  .lx-emblem, .lx-word, .lx-jewel, .lx-bar {
    animation: none !important;
    opacity: 1;
    transform: none;
    filter: none;
  }
  /* Die Aura ist über transform zentriert (top/left 50 % + translate). Ein
     pauschales transform:none würde sie in die untere rechte Ecke werfen —
     hier entfällt nur die Animation. */
  .lx-aura {
    animation: none !important;
    opacity: 1;
  }
  /* Ring und Siegel sind Teil des Weges dorthin, nicht des Ziels — nach der
     Choreografie sind beide ohnehin verschwunden. Der gemalte Rand der Uhr
     trägt das Bild allein. */
  .lx-ring, .lx-seal, .lx-shine { display: none; }
  /* Das Licht hinter der Figur bleibt — als fester Wert ist es Farbe, keine
     Bewegung. Volle Deckkraft würde die Mitte ausbrennen. */
  .lx-breath {
    animation: none !important;
    opacity: 0.34;
  }
  /* Der Balken bleibt — er ist Information, keine Zierde. Nur die
     Glättung entfällt, damit nichts nachläuft. Die scaleX-Füllung darf
     hier NICHT auf transform:none gesetzt werden. */
  .lx-bar-fill { transition: none; }
}

/* ---------- Video-Kapitel ---------- */
.vch {
  position: fixed;
  z-index: 10;
  opacity: 0;
  max-width: 480px;
  will-change: opacity, transform;
  pointer-events: none;
}

/* ---------- Text-Einlauf (gestaffelt) ---------- */
/* Vier Stellschrauben mit den bisherigen Werten als Vorgabe. Wer nichts setzt,
   bekommt exakt den alten Einlauf — Hero, Markenliste und Finale sind deshalb
   unberührt. Die Editorial-Kapitel setzen sie um (siehe „Drei Kapitel, drei
   Handschriften" weiter unten); nur dafür gibt es sie.

   Der Vorlauf von 60 ms ist bewusst KEINE fünfte: Kein Kapitel dreht daran,
   und eine Stellschraube, die niemand anfasst, ist nur eine Zahl mehr, die
   man beim Lesen nachschlagen muss.

   Der Einlauf steht bewusst NICHT als Variable in :root: Er gehört dem
   Kapitel, das ihn setzt, und erbt von dort an seine Zeilen. */
.gl {
  opacity: 0;
  transform: translateY(18px);
  filter: blur(6px);
  will-change: opacity, transform, filter;
}
.vch.is-in .gl {
  animation: var(--gl-anim, glIn) var(--gl-dur, 0.92s)
             var(--gl-ease, cubic-bezier(0.2, 0.7, 0.2, 1)) both;
  animation-delay: calc(var(--i, 0) * var(--gl-step, 95ms) + 60ms);
}
@keyframes glIn {
  from {
    opacity: 0;
    transform: translateY(18px);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}
@media (prefers-reduced-motion: reduce) {
  .gl {
    opacity: 1;
    transform: none;
    filter: none;
    /* Kapitel 03 legt seine Zeilen mit einer Maske frei. Ohne diese Zeile
       bliebe der Ruhezustand `inset(100% …)` stehen — der Text wäre
       vollständig weggeschnitten statt bloß unbewegt. */
    clip-path: none;
  }
  .vch.is-in .gl {
    animation: none;
  }
}
.vch .num {
  font-family: var(--font-sans), sans-serif;
  font-size: 10px;
  font-weight: 400;
  text-transform: uppercase;
  color: var(--gold);
  letter-spacing: 5px;
  margin-bottom: 16px;
}
/* feine Gold-Haarlinie als Handwerks-Signal */
.vch .num::before {
  content: '';
  display: block;
  width: 36px;
  height: 1px;
  margin-bottom: 14px;
  background: linear-gradient(90deg, var(--gold), transparent);
}
.vch h2 {
  font-family: var(--font-serif), serif;
  font-weight: 300;
  font-size: clamp(38px, 4.4vw, 60px);
  line-height: 1.12;
  color: var(--ink);
  margin-bottom: 20px;
}
.vch h2 em {
  font-style: italic;
  font-weight: 400;
  color: var(--gold-bright);
}
.vch p {
  max-width: 380px;
  font-size: 13px;
  font-weight: 300;
  letter-spacing: 0.5px;
  line-height: 2.05;
  color: rgba(240, 232, 216, 0.78);
}
/* Editorial-Hero: Vollbild, zentriert */
.vch-hero {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  max-width: none;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 24px;
}
/* Scrim: dunkelt nur den Textbereich sanft ab, Uhr bleibt sichtbar */
.hero-scrim {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 72% 58% at 50% 46%,
    rgba(0, 0, 0, 0.58),
    rgba(0, 0, 0, 0.28) 46%,
    transparent 72%
  );
}
/* Der große Titel — Jost, warmes Elfenbein.
   Bis zum 06.09.2026 stand die erste Zeile in Archivo Black. Der
   Auftraggeber wollte die Schrift dünner; an Archivo Black war das nicht zu
   haben, denn diese Schrift hat genau EINEN Schnitt — es gibt daran nichts
   herunterzudrehen. Also der Wechsel auf Jost, das ohnehin schon die zweite
   Zeile und den Claim darunter trägt.
   Gewählt wurde Vorschlag 2 von vieren: 300 über 200, also der bisherige
   Aufbau ohne das Schwarz. */
.hero-title {
  font-family: var(--font-sans), sans-serif;
  font-weight: 300;
  color: var(--ink);
  line-height: 0.9;
  text-transform: uppercase;
  text-shadow: 0 6px 40px rgba(0, 0, 0, 0.55);
}
/* ⚠ Die Laufweite steht hier und NICHT auf .hero-title, und das ist kein
   Geschmacksurteil.

   `em` rechnet immer gegen die Schriftgröße DES ELEMENTS, an dem die Regel
   steht — und .hero-title trägt selbst gar keine Größe, es erbt 32px. Die
   Angabe auf .hero-title ergab deshalb 0,96px, obwohl die Buchstaben 141px
   hoch sind: rund ein Viertel des Gewollten. Weiter unten ändert das nichts,
   denn letter-spacing wird als fertige Länge vererbt, nicht als em.
   Am 06.09.2026 im Browser nachgemessen.

   Hier steht die Größe, also rechnet 0,03em gegen 141px = 4,2px — und auf
   dem Telefon gegen 34-56px entsprechend weniger. Die Laufweite skaliert
   damit endlich mit dem Titel.

   Ins Plus gedreht (vorher -0,01em): Eine dünne Schrift braucht in dieser
   Größe Luft zwischen den Buchstaben, sonst laufen die Haarstriche optisch
   zusammen. Bei Archivo Black war das Gegenteil richtig.

   --out (0 = voll sichtbar, 1 = ausgeblendet, aus VideoHero) öffnet die
   Laufweite beim Wegscrollen weiter — der Titel „atmet aus". Auch dieser
   Teil wirkt jetzt in voller Größe; vorher waren es 1,4px, jetzt rund 6px.
   Wer das leiser will, dreht die 0.045em herunter — nicht den ersten Wert. */
.hero-title .hl-line {
  display: block;
  font-size: clamp(64px, 12vw, 172px);
  letter-spacing: calc(0.03em + var(--out, 0) * 0.045em);
}
/* Zweite Zeile („WATCHES") tritt hinter die erste zurück. Seit beide Zeilen
   dieselbe Schrift tragen, macht das nur noch eine Stufe Gewicht — 200 gegen
   300 — und vor allem die Farbe: das warme --gold gegen das Elfenbein
   darüber, dieselbe Farbe wie im Claim direkt darunter.
   Schrift und Laufweite werden geerbt; die Laufweite muss geerbt bleiben,
   damit sich auch diese Zeile beim Wegscrollen über --out mit öffnet. */
.hero-title .hl-line:last-child {
  font-weight: 200;
  color: var(--gold);
}

/* Buchstaben-Kaskade: jeder Letter blendet einzeln gestaffelt ein —
   ruhiges Tempo, Versatz in em, damit die Bewegung mit der Letter-Größe
   mitskaliert. Startet über .is-in (Hysterese in VideoHero) → spielt bei
   jedem Vorbeiscrollen erneut. */
.hero-title .hl {
  display: inline-block;
  opacity: 0;
  transform: translateY(0.22em);
  filter: blur(6px);
  will-change: opacity, transform, filter;
}
.vch.is-in .hero-title .hl {
  animation: hlIn 1.15s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(var(--i, 0) * 75ms + 60ms);
}
@keyframes hlIn {
  from {
    opacity: 0;
    transform: translateY(0.22em);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}
/* Claim folgt erst, wenn die Kaskade weitgehend steht */
.vch-hero.is-in .hero-claim.gl {
  animation-delay: 1.35s;
}

/* ---- Der eine Weg in den Shop ----
   Steht im Hero-Kapitel und verschwindet deshalb beim Scrollen mit dem Titel
   zusammen — das erledigt die Kapitel-Mechanik in home.js, nicht eine eigene
   Regel hier.

   Rolle „Hauptweg" (.iq-btn), unverändert: Es ist derselbe Knopf wie „In den
   Warenkorb" und „Zahlungspflichtig bestellen". Hier steht nur, was die Bühne
   zusätzlich verlangt. */
.hero-tuer {
  /* Fest unten links, den ganzen Film über (06.09.2026, Auftrag des
     Auftraggebers). Vorher lief er mit dem Hero-Kapitel aus und war nach
     rund anderthalb Bildschirmen fort.

     Er sitzt in .chrome, das bereits `position: fixed; inset: 0` trägt —
     hier genügen deshalb die beiden Kanten. `pointer-events: auto` ist
     nötig, weil .chrome sie für alle Kinder abschaltet und jedes bedienbare
     Element sie einzeln zurückholt (siehe .chrome-nav).

     ⚠ Er stand bis zum 08.09.2026 bündig unter dem Signet (44px, der
     Seitenrand aus `.chrome header { padding: 26px 44px }`). Diese Kante ist
     jetzt bewusst AUFGEGEBEN — Auftrag des Auftraggebers: in der Ecke stand
     er „richtig versteckt". Wer die Bündigkeit zurückholen will, holt sich
     die Ecke mit zurück.

     22vw statt eines festen Wertes, damit der Weg nach innen mit dem Fenster
     wächst; 44px als Boden (unter 200px Fensterbreite bliebe sonst nichts
     übrig), 320px als Deckel — weiter innen liefe er auf breiten Schirmen in
     die Bildmitte und damit unter die Uhr.

     Die Mitte selbst ist bewusst NICHT genommen: dort sitzt `.scroll-hint`
     („Scrollen, um zu entdecken") auf `bottom: 26px; left: 50%`, also auf
     genau dieser Zeile. Beide zugleich ginge nur, wenn der Hinweis weicht.

     56px statt der fruehreren 26px (08.09.2026, Auftrag des Auftraggebers:
     "bisschen hoeher, dann passt es"). Damit ist auch die zweite Symmetrie
     zur Kopfzeile aufgegeben — er sass unten so tief, wie das Signet oben
     hoch sitzt. Wer sie zurueckholt, holt den Knopf wieder an die Kante.

     ⚠ Der Wert haengt an zwei Nachbarn, die mitwandern muessen: `.scroll-hint`
     darueber (dort steht die Rechnung) und die Kapitelspalten darunter —
     gemessen bleiben nach dem Anheben 85px (1440x900) bis 52px (1200x720).
     Auf dem Telefon bleibt es bei 20px, siehe unten: dort steht der Knopf
     unter dem Kapitelband, jeder Pixel hoeher nimmt Text weg. */
  position: absolute;
  left: clamp(44px, 22vw, 320px);
  bottom: 56px;
  pointer-events: auto;
  /* Zurückgenommen (24.08.2026): vorher 16px/38px und 2.2px Laufweite. Auf
     der Bühne wirkte er wie ein Formularknopf, der sich verlaufen hat. */
  padding: 12px 26px;
  font-size: 11px;
  letter-spacing: 1.8px;
  /* Auf bewegtem Bild braucht Gold einen echten Schlagschatten, sonst
     flimmert die Kante mit dem Film mit. Versatz und weiche Streuung, kein
     farbiger Hof. */
  box-shadow: var(--knopf-kante-gold), 0 14px 38px -14px rgba(0, 0, 0, 0.95);
  /* Der Einlauf hing vorher an der Kapitel-Mechanik (.gl). Ausserhalb des
     Kapitels gäbe es die nicht mehr — ohne eigene Regel bliebe der Knopf
     unsichtbar. Er kommt jetzt mit dem Intro: `locked` fällt in home.js,
     sobald die Bühne offen ist. */
  opacity: 1;
  transform: none;
  transition: opacity 0.7s ease 0.9s, transform 0.7s cubic-bezier(0.16, 1, 0.3, 1) 0.9s,
              background-color var(--ease), border-color var(--ease),
              color var(--ease), box-shadow var(--ease);
}
body.locked .hero-tuer {
  opacity: 0;
  transform: translateY(10px);
  transition: none;
}
.hero-tuer:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45),
              0 16px 40px -12px rgba(191, 156, 90, 0.55),
              0 14px 38px -14px rgba(0, 0, 0, 0.95);
}


@media (max-width: 760px) {
  /* 20px statt 44px: derselbe Seitenrand, den die Kopfzeile hier annimmt.
     Eine Nummer kompakter als auf dem Schreibtisch — unter ihm steht auf dem
     Telefon das Kapitelband, und jeder Pixel Knopfhöhe ist ein Pixel weniger
     Text. Höhe zusammen 33px; die Zahl steht in der Reservierung des Bandes
     weiter oben. */
  .hero-tuer { padding: 10px 20px; letter-spacing: 1.4px; font-size: 10px; left: 20px; bottom: 20px; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-title .hl {
    opacity: 1;
    transform: none;
    filter: none;
  }
  .vch.is-in .hero-title .hl {
    animation: none;
  }
}
/* Gleiche Schrift wie die Unterzeilen im Split-Kapitel (.it-cap): gesperrte
   Groteske in Versalien, gold. Etwas größer als dort, weil die Zeile hier
   allein unter dem Hero-Titel steht — die Sperrung ist dafür minimal
   reduziert, sonst wird die lange Zeile auf schmalen Fenstern zu breit. */
.hero-claim {
  font-family: var(--font-sans), sans-serif;
  font-weight: 400;
  font-size: clamp(10px, 1.05vw, 13px);
  letter-spacing: 3.5px;
  text-transform: uppercase;
  color: var(--gold);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85), 0 2px 20px rgba(0, 0, 0, 0.7);
}
.hero-claim em {
  font-style: normal;
  color: var(--gold-bright);
}
/* Auf schmalen Geräten brach die Zeile so um, dass „Stille" allein unten
   stand. `balance` verteilt sie auf zwei etwa gleich lange Hälften. */
.hero-claim { text-wrap: balance; }

/* Display-Statements in Archivo Black — genutzt vom Split-Kapitel und den
   Flanken-Kapiteln.
   ⚠ Seit dem 06.09.2026 ist das NICHT mehr die Schrift des Hero-Titels: Der
   steht jetzt in Jost 300 (siehe .hero-title). Die Kapitel darunter sind
   bewusst unverändert geblieben — der Auftrag galt dem Titel. Wer die
   Durchgängigkeit über die ganze Strecke wiederherstellen will, muss diese
   drei Stellen mitnehmen (.it-text, .vch-final .final h2, die Kapitelziffer)
   und nicht nur eine davon. */
.it-text {
  position: absolute;
  font-family: var(--font-display), sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  line-height: 0.92;
  letter-spacing: -0.01em;
  color: var(--ink);
  font-size: clamp(36px, 4.8vw, 80px);
  text-shadow: 0 6px 40px rgba(0, 0, 0, 0.6);
}
/* Vertikal in der Bildmitte, damit die Aussage auf einer Linie mit der Uhr
   liegt. Der zweite translateY ist die Parallaxe-Drift nach oben — beide
   Verschiebungen addieren sich, die Zentrierung bleibt dabei erhalten.
   Der Text bleibt seitlich stehen und wandert nie in die Uhr hinein. */
.it-left {
  left: clamp(28px, 7vw, 120px);
  top: 50%;
  transform: translateY(-50%) translateY(calc((0.5 - var(--seg, 0)) * 4vh));
}
/* Dezente Vertrauens-Unterzeile unter einem Statement. .it-cap steht im
   Split-Kapitel unter der Aussage und übernimmt deren Ausrichtung,
   .ed-cap ist das Gegenstück in den Editorial-Kapiteln (dort absolut
   gesetzt, siehe unten) — gleiche Typografie, damit die Seite eine
   einzige Schrift-Logik hat. */
.it-cap,
.ed-cap,
.ed-lt,
.it-bt {
  font-family: var(--font-sans), sans-serif;
  /* 12.5px/2.6px statt 10px/4px (08.09.2026, Auftrag des Auftraggebers: auch
     im Split-Kapitel sei der Text zu klein, „der Nutzer wird Schwierigkeiten
     haben das sauber zu lesen").

     Am 06.09. bekamen nur die beiden Kapitel-Labels diese Werte, per eigener
     Regel weiter unten; dort stand als Bedingung: wer die anderen beiden
     nachzieht, tut es in DIESER Gruppe — dann aber alle vier. Genau das ist
     jetzt geschehen, und die Sonderregel unten ist damit auf das
     zusammengeschrumpft, was sie wirklich unterscheidet: den Schatten.

     4px Sperrung auf 10px Schrift ist fast ein halber Buchstabe Abstand —
     das zerlegt das Wort in Einzelzeichen, und ueber einem laufenden Film
     liest sich das muehsam. Groesser UND enger ist deshalb kein Widerspruch,
     sondern dieselbe Massnahme. */
  font-size: 12.5px;
  font-weight: 400;
  letter-spacing: 2.6px;
  text-transform: uppercase;
  color: var(--gold);
  /* Zwei Schatten statt einem: ein enger fuer die Kante, ein weiter fuer die
     Flaeche (08.09.2026, aus der frueheren Sonderregel der Kapitel-Labels
     hierher gezogen).

     Diese vier Zeilen sind die einzigen, die GOLD auf dem Film liegen — und
     der Film zeigt eine roségoldene Uhr. Gold auf Gold traegt keinen
     Kontrast; was hilft, ist nicht mehr Farbe, sondern ein dunkler Grund
     direkt hinter der Schrift.

     ⚠ Fuer `.it-cap` und `.it-bt` wiegt das schwerer als fuer die beiden
     anderen: Das Split-Kapitel hat als einziges KEINEN `.ed-scrim`, seine
     Zeilen liegen ohne jede Abdunklung auf dem Bild. */
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 2px 14px rgba(0, 0, 0, 0.85);
}
.it-cap {
  display: block;
  margin-top: 18px;
}

/* Markenspalte als Gegengewicht zur Aussage links. Die Drift läuft mit 6vh
   gegen die 4vh links — das ist die „Parallaxe in zwei Geschwindigkeiten",
   die der Kommentar oben beschreibt und die seit dem Entfernen des alten
   rechten Blocks gefehlt hat.
   Bewusst nur Namen, keine Herstellerlogos: Die Nennung einer Marke beim
   Weiterverkauf echter Ware ist zulässig, das Zeigen fremder Bildmarken auf
   der Startseite erweckt dagegen den Eindruck einer Handelsbeziehung. */
.it-brands {
  position: absolute;
  right: clamp(28px, 7vw, 120px);
  top: 50%;
  text-align: right;
  transform: translateY(-50%) translateY(calc((0.5 - var(--seg, 0)) * 6vh));
}
.it-bt {
  display: block;
}
.it-b-rule {
  height: 1px;
  margin: 13px 0 17px;
  background: rgba(240, 232, 216, 0.16);
}
.it-blist {
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 0;
  padding: 0;
}
.it-blist li {
  font-family: var(--font-sans), sans-serif;
  /* 15px/400 statt 13px/300 (08.09.2026). Dasselbe wie bei der Schrittliste
     der Kapitel: Ueber bewegtem Bild ist das GEWICHT der Punkt, nicht die
     Groesse — 300 ist eine Haarschrift und verliert die Kante am Film.
     Sperrung 3 → 2.6px, damit die Namen als Namen zusammenhaengen. */
  font-size: 15px;
  font-weight: 400;
  letter-spacing: 2.6px;
  text-transform: uppercase;
  /* Schwächer als die Headline links: die Marken belegen die Aussage,
     sie sind nicht selbst die Aussage. */
  color: rgba(240, 232, 216, 0.75);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9);
}
/* Einlauf-Versatz im CSS statt fünfmal inline im Markup. */
.it-blist li:nth-child(1) { --i: 1; }
.it-blist li:nth-child(2) { --i: 2; }
.it-blist li:nth-child(3) { --i: 3; }
.it-blist li:nth-child(4) { --i: 4; }
.it-blist li:nth-child(5) { --i: 5; }

@media (max-width: 760px) {
  .it-text { font-size: clamp(30px, 9vw, 46px); }
  /* top bleibt bei 50 % — nur der Einzug wird schmaler. */
  .it-left { left: 20px; }
  /* Kein Platz neben der Aussage; die Marken stehen ohnehin an jeder Uhr
     im Shop. */
  .it-brands { display: none; }
}

/* Finale (Endframe, Uhr rechts): professioneller Shop-Abschluss als linke
   Spalte, vertikal zentriert (Zentrierung via translateY(-50%) in JS). */
.vch-final {
  left: clamp(28px, 7vw, 120px);
  top: 50%;
  max-width: min(460px, 42vw);
}
/* Schluss-Statement in derselben Display-Schrift wie Hero und Kapitel.
   Selektor bewusst (0,2,1): .vch-final h2 wäre (0,1,1) und stünde mit
   .vch h2 gleichauf — es gewänne nur über die Reihenfolge im Quelltext. */
.vch-final .final h2 {
  font-family: var(--font-display), sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  font-size: clamp(30px, 3.4vw, 50px);
  line-height: 0.95;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 24px rgba(0, 0, 0, 0.7);
}
/* Archivo Black hat keinen Kursivschnitt — das em trägt nur noch Gold. */
.vch-final .final h2 em {
  font-style: normal;
  font-weight: 400;
  color: var(--gold-bright);
}
/* Dezenter Boutique-Button (Rahmen, Gold, Hover füllt) */
/* Abwärts-Hinweis statt Verkaufsknopf: Die Kollektion liegt unmittelbar
   darunter — das wird angekündigt, nicht beworben. */
.final-cue {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  margin-top: 34px;
  padding-bottom: 7px;
  font-family: var(--font-sans), sans-serif;
  font-size: 10px;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--gold-bright);
  text-decoration: none;
  border-bottom: 1px solid rgba(191, 156, 90, 0.45);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.9);
  transition:
    color 0.35s ease,
    border-color 0.35s ease,
    gap 0.35s ease;
}
.final-cue:hover,
.final-cue:focus-visible {
  color: var(--ink);
  border-color: var(--gold-bright);
  gap: 18px;
}
/* Vertrauenszeile: klein, gesperrt, mit Gold-Haarlinie darüber */
.final-trust {
  margin-top: 40px;
  font-family: var(--font-sans), sans-serif;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}
.final-trust::before {
  content: '';
  display: block;
  width: 40px;
  height: 1px;
  margin-bottom: 20px;
  background: linear-gradient(90deg, var(--gold), transparent);
}
/* Signatur-Wortmarke wie im Header. .brand-text setzt keine Schrift und
   erbt damit Jost bei 7px Sperrung — hier war vorher Cormorant bei 6px,
   also weder dieselbe Schrift noch derselbe Rhythmus. */
.final-sign {
  margin-top: 40px;
  font-family: var(--font-sans), sans-serif;
  font-size: 13px;
  letter-spacing: 7px;
  text-transform: uppercase;
  color: rgba(240, 232, 216, 0.6);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.85);
}
.final-sign em {
  font-style: normal;
  color: var(--gold);
}

/* Split-Kapitel: full-bleed, ein Display-Statement links neben der Uhr
   (Positionierung über .it-left, identisch zum Interlude). */
.vch-split {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  max-width: none;
}
/* Etwas kleiner als der Interlude-Default: „Ausgewählte" ist elf Zeichen
   breit und darf auch auf schmalen Fenstern nicht in die zentrale Uhr ragen. */
.vch-split .it-text {
  font-size: clamp(24px, 3.3vw, 52px);
}

/* Editorial-Kapitel (Magazin-Raster): große Display-Headline oben links ·
   Haarlinie · Gold-Kapitälchen · Überschrift + Fließtext + Link rechts
   unten. Die Uhr steht mittig frei, die Diagonale oben-links →
   unten-rechts ist dieselbe wie im Split-Kapitel.

   Alle Maße hängen an --ed-hs: Die Schriftgröße skaliert mit vw, feste
   Prozentwerte skalieren mit der HÖHE — bei breiten, flachen Fenstern
   (1920x900) schnitte eine Haarlinie bei festen 23% mitten durch die
   zweite Headline-Zeile. 1.84 ist die Höhe des zweizeiligen
   Satzblocks in em (2 x 0.92 Zeilenhöhe). */
.vch-ed {
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  max-width: none;
  --ed-x: clamp(28px, 7vw, 120px); /* Einzug wie .it-left */
  --ed-top: 9%;
  /* Knapp unter .it-text (clamp(36px,4.8vw,80px)): bei 4.8vw stieß die
     zweite Zeile von „02 Vertrauen" auf 1280px-Fenstern 11px in den
     Zifferblattrand. Nachgemessen bleiben so überall ≥20px Luft. */
  --ed-hs: clamp(34px, 4.4vw, 76px);
  --ed-gap: 24px;
  --ed-band: calc(var(--ed-top) + var(--ed-hs) * 1.84 + var(--ed-gap));
}
/* Abdunkler: Headline und Datenzeile liegen über Band und Gehäuse, die
   Spalten über den dunklen Rändern — oben/unten etwas kräftiger.

   Die seitlichen Verläufe haben eine Haltestufe (08.09.2026). Vorher liefen
   sie von 0.62 auf null bei 30% Fensterbreite; das sind bei 1440px 432px.
   Die Spalten stehen aber bei x = 101…409 — ihre INNERE Hälfte lag damit
   praktisch auf dem blanken Video, am rechten Spaltenrand gemessen 3%
   Deckkraft. Genau dort stand der Text, der nicht zu erkennen war.

   Was hilft, ist nicht mehr Deckkraft am Rand, sondern ein späterer Abfall:
   0.72 an der Kante, bei 18% noch 0.42, aus bei 34%. Bei 1440px liegt die
   ganze Spalte damit auf mindestens 0.16 statt auf 0.03.

   34% und nicht mehr: Das Zifferblatt beginnt bei 50vw − 31vh, bei 1440×900
   also bei 441px = 30.6%. Der Auslauf greift damit nur noch mit wenigen
   Prozent Deckkraft an den Gehäuserand — sichtbar wird davon nichts. */
.ed-scrim {
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(0, 0, 0, 0.78), transparent 34%),
    linear-gradient(to top, rgba(0, 0, 0, 0.55), transparent 26%),
    linear-gradient(to right, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.42) 18%, transparent 34%),
    linear-gradient(to left, rgba(0, 0, 0, 0.72), rgba(0, 0, 0, 0.42) 18%, transparent 34%);
}
/* Headline in der Hero-Schrift — zweizeilig per <br>. Einzeilig geht
   nicht: Archivo Black ist 1.83x breiter als eine Serife, „01 ANKAUF &
   VERKAUF" wären bei 1440px Fensterbreite 1604px gegen 1339px Platz. */
.ed-head {
  position: absolute;
  left: var(--ed-x);
  /* Startet unterhalb der Kopfzeile — bei 5% lag die Ziffer hinter dem Logo. */
  top: var(--ed-top);
  right: var(--ed-x);
  font-family: var(--font-display), sans-serif;
  font-weight: 400;
  font-size: var(--ed-hs);
  line-height: 0.92;
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--ink);
  text-shadow: 0 6px 40px rgba(0, 0, 0, 0.6);
}
/* Gedämpft: in Archivo Black ist „01" bei 80px ein 105px breiter
   Goldblock — auf voller Sättigung zieht die Ziffer alles an sich. */
.ed-n {
  color: rgba(191, 156, 90, 0.8);
  margin-right: 0.12em;
}
.ed-rule {
  position: absolute;
  left: var(--ed-x);
  right: var(--ed-x);
  top: var(--ed-band);
  height: 1px;
  background: rgba(240, 232, 216, 0.16);
}
/* Rechte Spalte: Breite an die Bühne gekoppelt (Video 2206x946, cover,
   Uhr bis ~+31vh neben der Bildmitte) — sie wächst nie ins Zifferblatt,
   max() hält sie lesbar. Bei top:52% ist das Zifferblatt an seiner
   breitesten Stelle, daher 32px Puffer statt 24px. */
.ed-r {
  position: absolute;
  top: 52%;
  right: var(--ed-x);
  max-width: max(240px, min(400px, calc(50vw - 31vh - var(--ed-x) - 32px)));
}
/* Linke Spalte: Spiegel von .ed-r auf gleicher Höhe. Dieselbe Breitenformel —
   sie misst den Abstand zwischen Fensterrand und Zifferblatt und ist damit
   seitenunabhängig. Beide Spalten flankieren die Uhr unter dem Headline-Band. */
.ed-l {
  position: absolute;
  top: 52%;
  left: var(--ed-x);
  max-width: max(240px, min(400px, calc(50vw - 31vh - var(--ed-x) - 32px)));
}
/* Label in Gold-Kapitälchen (Typografie kommt aus der .it-cap-Gruppe oben),
   darunter eine kurze Haarlinie als Absatz zur Schrittliste. */
.ed-lt {
  display: block;
}

/* Hier stand vom 06.09. bis zum 08.09.2026 eine Sonderregel fuer `.ed-cap`
   und `.ed-lt` (Groesse, Sperrung, Schatten). Sie ist ersatzlos entfallen:
   Alle vier Labels der Gruppe weiter oben tragen jetzt dieselben Werte, und
   eine zweite Stelle mit denselben Zahlen waere nur die, die beim naechsten
   Mal vergessen wird. */
.ed-l-rule {
  height: 1px;
  margin: 13px 0 17px;
  background: rgba(240, 232, 216, 0.16);
}
/* Die Ziffern kommen aus einem CSS-Counter statt aus dem Markup: bei drei
   Kapiteln à vier Schritten wären das zwölf handgeschriebene Nummern, die
   beim Umsortieren stillschweigend falsch würden. */
.ed-steps {
  counter-reset: step;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 13px;
  margin: 0;
  padding: 0;
}
.ed-steps li {
  display: flex;
  gap: 14px;
  font-family: var(--font-sans), sans-serif;
  /* 17px statt 15px statt ursprünglich 13px (08.09. nach 06.09.2026). Beim
     ersten Anlauf wurde angenommen, der Platz sei knapp; nachgemessen liegen
     unter der längsten Spalte 156px brach (1440×900: Unterkante 676px,
     Kollektions-Knopf ab 832px). Die Höhe war nie die Grenze.

     Das GEWICHT ist der eigentliche Punkt: 300 ist eine Haarschrift, und
     über einem laufenden Film verliert sie die Kante — daher „fast nicht zu
     erkennen" trotz normaler Grösse. 400 kostet keinen Platz und bringt hier
     mehr als jeder weitere Pixel.

     Die Zeilenhöhe geht mit dem Grad leicht zurück (1.62 → 1.58): Grössere
     Schrift braucht relativ weniger Durchschuss, sonst zerfällt der Schritt
     in Einzelzeilen. Die Sperrung bleibt aus — sie half bei 13px der Kontur
     und zöge die schmale Spalte nur in die Breite. */
  font-size: 17px;
  font-weight: 400;
  line-height: 1.58;
  /* Eine Spur schwächer als .ed-p (0.92): die rechte Spalte bleibt die
     Hauptaussage, die Schritte sind der Beleg dazu. Beide sind mit der
     Vergrösserung mit heraufgesetzt — dünne Schrift auf Film braucht den
     Kontrast, sonst nimmt die Vergrösserung allein nichts zurück. */
  color: rgba(240, 232, 216, 0.88);
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.92);
}
.ed-steps li::before {
  counter-increment: step;
  content: counter(step, decimal-leading-zero);
  flex: none;
  /* 28px statt 26px statt 22px: Die Ziffer wächst mit dem Schritt mit und
     stiesse sonst an den Text. */
  width: 28px;
  padding-top: 4px;
  font-size: 12px;
  letter-spacing: 2px;
  /* Gedämpft wie die Ziffer in der Headline — sonst zieht die Nummer mehr
     Aufmerksamkeit als der Schritt, den sie zählt. Der Schatten aus
     demselben Grund wie bei .ed-cap: Gold liegt hier auf einer goldenen
     Uhr. */
  color: rgba(191, 156, 90, 0.85);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.95), 0 2px 12px rgba(0, 0, 0, 0.8);
}
/* Der Einlauf-Versatz steht hier statt inline im Markup: zwölf gleichartige
   Listenpunkte mit je einem --i im JSX wären reine Wiederholung. */
.ed-steps li:nth-child(1) { --i: 4; }
.ed-steps li:nth-child(2) { --i: 5; }
.ed-steps li:nth-child(3) { --i: 6; }
.ed-steps li:nth-child(4) { --i: 7; }

/* .vch h2 setzt Serifen — hier bewusst überschrieben (höhere Spezifität),
   die rechte Überschrift ist wie in der Vorlage eine Grotesk.

   Wächst am 08.09.2026 mit dem Fliesstext darunter mit (22–31 → 25–35): Sie
   ist dessen Kopf, und bliebe sie stehen, rückte der Absatz ihr auf. */
.vch .ed-t {
  font-family: var(--font-sans), sans-serif;
  font-weight: 400;
  font-size: clamp(25px, 2.3vw, 35px);
  line-height: 1.22;
  letter-spacing: 0.2px;
  color: var(--ink);
  margin: 0 0 16px;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.85);
}
/* .vch p ist (0,1,1) — als bloßes .ed-p (0,1,0) hätte hier nichts
   gegriffen und der Fließtext liefe weiter mit 13px/2.05. */
.vch .ed-p {
  /* 18px statt 16px statt 14px, Gewicht 400 statt 300 — die Begründung
     steht vollständig bei `.ed-steps li`: der Platz war da, und das Gewicht
     war das eigentliche Problem. Eine Nummer grösser als die Schrittliste,
     weil die rechte Spalte die Hauptaussage trägt und die linke den Beleg. */
  font-size: 18px;
  font-weight: 400;
  line-height: 1.65;
  color: rgba(240, 232, 216, 0.92);
  max-width: none;
  margin: 0;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.92);
}
/* Gold-Kapitälchen-Zeile unter der Haarlinie — bewusst ein eigenes
   Element und kein Kind von .ed-head: dort erbte sie line-height 0.92
   eines 80px-Elternteils (9px Zeilenkasten um 14px Schrift) und
   verlöre ihren eigenen Einblend-Schritt. */
.ed-cap {
  position: absolute;
  left: var(--ed-x);
  right: var(--ed-x);
  top: calc(var(--ed-band) + 16px);
}

/* ══════════════════════════════════════════════════════════════════════
   DREI KAPITEL, DREI HANDSCHRIFTEN

   Bis zum 30.08.2026 liefen alle drei Kapitel identisch ein: von unten, aus
   der Unschärfe, gleiche Staffelung. Sie unterschieden sich im Wortlaut,
   nicht in der Bewegung — dreimal dieselbe Geste hintereinander.

   Jedes Kapitel setzt jetzt die Stellschrauben aus `.vch.is-in .gl` neu.
   Was es nicht setzt, bleibt die alte Vorgabe; deshalb steht hier nur der
   Unterschied, nicht die ganze Animation.
   ══════════════════════════════════════════════════════════════════════ */

/* ---- 01 Ankauf & Verkauf — der Tausch ----
   Die beiden Spalten kommen aufeinander zu und begegnen sich über der Uhr:
   links das Verfahren, rechts das Versprechen. Kopfzeile, Haarlinie und
   Kapitälchen behalten den Einlauf von unten — sie sind die Klammer, unter
   der sich die Begegnung abspielt, und dürften nicht selbst mitwandern.

   Etwas engere Staffel als die Vorgabe: Es laufen zwei Seiten gleichzeitig,
   bei 95 ms zöge sich der Auftritt spürbar in die Länge. */
.vch-ed.ed-tausch {
  --gl-step: 70ms;
  /* Der Weg bleibt unter dem Seitenrand (`--ed-x`, mindestens 28px) —
     sonst liefe die Schrift im Anlauf über die Kante hinaus. Er steht NUR
     hier und im Mobilblock; die Keyframes lesen ihn, setzen ihn nicht. Ein
     Rückfallwert dort hätte dieselbe Zahl an eine dritte Stelle geschrieben. */
  --gl-weg: 26px;
}
.ed-tausch .ed-l { --gl-anim: glVonLinks; }
.ed-tausch .ed-r { --gl-anim: glVonRechts; }

/* Auf flachen Fenstern rücken beide Spalten höher.

   Die 52% sind für hohe Fenster gerechnet. Seit die Schrifttexte grösser sind
   (06.09.2026) und der Hauptweg fest unten links steht, wird es darunter eng:
   bei 1024×700 gemessen nur noch 11px zwischen der letzten Zeile der
   Schrittliste und der Oberkante des Knopfes. Es überlappte zwar nicht, aber
   ein goldener Knopf elf Pixel unter dem letzten Listenpunkt liest sich wie
   ein fünfter Listenpunkt.

   Die Höhe, nicht die Breite ist der Auslöser — deshalb `max-height` und
   nicht `max-width`. Beide Spalten wandern gemeinsam, sonst stünden sie
   nicht mehr auf einer Linie. */
@media (max-height: 800px) and (min-width: 901px) {
  .ed-l,
  .ed-r { top: 45%; }
}

/* Schmal UND flach — der engste Fall auf dem Schreibtisch (08.09.2026).

   Mit den groesseren Graden aus Task 0092 wird die Schrittliste hoch genug,
   dass die 45%-Stufe darueber nicht mehr reicht. Gemessen: 14px auf 1024x700
   und 25px auf 1200x720 zwischen letztem Listenpunkt und dem festen
   Kollektions-Knopf. Das ueberlappt zwar nicht, aber ein goldener Knopf so
   dicht unter der Liste liest sich als fuenfter Listenpunkt — derselbe Grund
   wie eine Stufe hoeher, nur schaerfer.

   ⚠ Ausloeser ist die HOEHE, nicht die Breite. Ein erster Anlauf deckelte
   zusaetzlich bei 1180px Breite (Gedanke: schmale Spalte = mehr Umbrueche =
   hoehere Liste). 1200x720 faellt genau daneben und stand dann bei 25px.
   Deshalb haengt die Stufe allein an `max-height`.

   Zurueckgenommen wird der senkrechte Rhythmus, nicht der Schriftgrad: Der
   sollte gerade lesbarer werden, ihn hier wieder einzudampfen hiesse, den
   Auftrag ausgerechnet auf dem flachsten Schreibtisch-Fenster zurueckzunehmen.
   Die Spalten ruecken zusaetzlich hoeher — ueber ihnen stand ungenutzter
   Platz zwischen Kapitaelchen und Spaltenkopf. */
@media (min-width: 901px) and (max-height: 780px) {
  .ed-l,
  .ed-r { top: 40%; }
  .ed-steps { gap: 9px; }
  .ed-l-rule { margin: 9px 0 12px; }
}

/* Die 4px nach unten sind kein Rest der alten Animation, sondern Absicht:
   rein waagerecht wirkt der Einlauf wie ein Schiebeschritt, mit der Spur
   Senkung wie ein Zulegen. */
@keyframes glVonLinks {
  from {
    opacity: 0;
    transform: translate3d(calc(var(--gl-weg) * -1), 4px, 0);
    filter: blur(5px);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
}
@keyframes glVonRechts {
  from {
    opacity: 0;
    transform: translate3d(var(--gl-weg), 4px, 0);
    filter: blur(5px);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
    filter: blur(0);
  }
}

/* ---- 02 Vertrauen — die Prüfung ----
   Kein Versatz, nur Schärfe: Das Kapitel wird scharf gestellt, nicht
   eingeschoben. Dazu eine sehr enge Staffel — die Zeilen stehen dadurch
   fast zusammen und lesen sich als ein Block statt als Aufzählung. Genau
   das behauptet der Text: geöffnet, geprüft, dokumentiert — ein Vorgang.

   Länger als die Vorgabe (1,15 s statt 0,92 s): Ein reiner Schärfezug ohne
   Weg braucht Zeit, sonst ist er ein Blitz und keine Prüfung. */
.vch-ed.ed-pruefung {
  --gl-anim: glSchaerfe;
  --gl-dur: 1.15s;
  --gl-ease: cubic-bezier(0.16, 0.84, 0.28, 1);
  --gl-step: 34ms;
}
/* 1.035 und nicht mehr: Das Kapitel soll scharf werden, nicht zoomen. */
@keyframes glSchaerfe {
  from {
    opacity: 0;
    transform: scale(1.035);
    filter: blur(10px);
  }
  to {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
}

/* ---- 03 Die Auswahl — das Aussortieren ----
   Jede Zeile wird von unten freigelegt statt hereingeschoben: Eine Maske
   wandert nach oben und gibt frei, was schon dasteht. Betont nacheinander
   (130 ms statt 95 ms) — man sieht Stück für Stück etwas auftauchen, so wie
   das Kapitel vom Aussortieren erzählt.

   Die Deckkraft bleibt in beiden Keyframes bei 1: Die Maske übernimmt das
   Verbergen allein. Ein zusätzliches Einblenden machte aus dem Freilegen
   wieder das gewöhnliche Aufscheinen der anderen Kapitel. */
.vch-ed.ed-auswahl {
  --gl-anim: glFreilegen;
  --gl-dur: 0.8s;
  --gl-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --gl-step: 130ms;
}
/* `.gl` kündigt Deckkraft, Transform und Filter an — hier bewegt sich
   stattdessen die Maske. */
.vch-ed.ed-auswahl .gl {
  will-change: clip-path;
}
/* Die negativen Werte an den drei übrigen Kanten sind kein Spielraum,
   sondern Notwendigkeit: `.ed-head` trägt einen Schlagschatten mit 40 px
   Streuung, `inset(… 0 0 0)` schnitte ihn an der Textkante ab und die
   Headline stünde nach dem Einlauf ohne ihren Halt auf dem Film. */
@keyframes glFreilegen {
  from {
    opacity: 1;
    transform: none;
    filter: none;
    clip-path: inset(100% -12% -30% -12%);
  }
  to {
    opacity: 1;
    transform: none;
    filter: none;
    clip-path: inset(-30% -12% -30% -12%);
  }
}

/* ---------- Mobile ---------- */
/* ══════════════════════════════════════════════════════════════════════════
   TELEFON — die Buehne ist hier ein Band, kein Vollbild.

   hero.mp4 ist 2206x946 (2,33:1), ein Telefon 430x932 (0,46:1). Mit
   object-fit:cover blieben davon 19,8 % der Bildbreite uebrig — genau die
   Mitte, in der die Uhr steht. Die schwarzen Raender, auf denen der Text
   liegen soll, fielen weg; gemessen 1,6:1 Kontrast fuer weisse Schrift.

   Stattdessen laeuft hier hero-mobile.mp4 (720x486), auf die Uhr geschnitten
   und unten weich ins Schwarz auslaufend. Es sitzt als Band oben, darunter
   traegt der Seitengrund. Der Text steht auf reinem Schwarz: 21:1.

   --band-oben und --band-hoehe sind die einzigen zwei Zahlen, an denen die
   Aufteilung haengt; alles darunter rechnet gegen sie.
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 760px) {
  :root {
    --band-oben: clamp(30px, 7.5vh, 74px);
    /* 67,5 vw ist das echte Seitenverhaeltnis der Mobilfassung (486/720).
       Der 30-vh-Deckel haelt den Text von Kapitel 01 und 02 frei: Auf einem
       iPhone SE (667 px hoch) blieben sonst 47 px zu wenig.

       ⚠ Der Deckel greift NICHT nur auf kurzen Schirmen, sondern sobald die
       Hoehe unter dem 2,25-Fachen der Breite liegt — also auf praktisch jedem
       Telefon (390x844: 253 statt 263 px; Safari mit Leisten: 226 px). Faellt
       das Band unter sein Seitenverhaeltnis, darf das Bild deshalb nicht
       schrumpfen, sondern wird unten beschnitten (siehe .stage video). */
    --band-hoehe: min(67.5vw, 30vh);
    --band-unten: calc(var(--band-oben) + var(--band-hoehe));
    --text-x: 22px;
  }

  /* Volle Breite, immer (01.10.2026). Vorher stand hier object-fit:contain,
     in der Annahme, die Raender seien „schwarz auf schwarz, unsichtbar". Sie
     sind es nicht: Die Nahaufnahme reicht bis an den rechten Bildrand, und
     mit contain schrumpfte das Bild auf 375 von 390 px (Safari: 335) — eine
     harte senkrechte Kante mitten im Armband.

     cover: Die Breite stimmt immer, beschnitten wird in der Hoehe.

     Verankert bei 23 %, nicht oben und nicht mittig. Die Zahl ist am Film
     gemessen (ffmpeg, 4 Bilder je Sekunde): Metall und Brillanten liegen
     ueber die ganze Laufzeit zwischen 5,7 % (Nahaufnahme bei 2,5 s) und
     81,1 % der Bildhoehe. Frei sind also oben 5,7 und unten 18,9 Punkte —
     der Beschnitt wird in genau diesem Verhaeltnis verteilt (5,7 / 24,6).
     Damit bleibt alles Helle im Bild, solange der Beschnitt unter 24,6 %
     liegt; der schlimmste gemessene Fall (390x664) hat 24 %.

     Zwei Fehlversuche, damit sie niemand wiederholt: „center top" schnitt
     in der Totale die unteren Bandanstoesse samt Brillanten ab (im echten
     Mobil-Safari gesehen, 21 % Beschnitt); 40 % kappte die Luenette der
     Nahaufnahme. Oben und unten faellt jetzt nur Armband weg. */
  .stage video {
    position: absolute;
    top: var(--band-oben);
    left: 0;
    width: 100%;
    height: var(--band-hoehe);
    object-fit: cover;
    object-position: center 23%;
  }
  /* Der Beschnitt nimmt dem Film seinen eigenen weichen Auslauf. Dieser
     Schleier gibt ihn zurueck: nur ueber dem Band, nur am unteren Rand, ins
     selbe Schwarz wie der Grund darunter.

     2 px hoeher als das Band und die untersten 3 px deckend schwarz: Video
     und Schleier rechnen beide aus vh und vw und runden unabhaengig. Im
     Mobil-Safari schaute sonst die letzte Pixelzeile des Films als helle
     Haarlinie unter dem Verlauf hervor. */
  .stage-grade {
    inset: var(--band-oben) 0 auto 0;
    height: calc(var(--band-hoehe) + 2px);
    background: linear-gradient(to top, #000 0, #000 3px, transparent 22%);
  }
  /* Dunkelte die Bildmitte ab, damit der Titel ueber der Uhr lesbar blieb.
     Der Titel steht jetzt unter dem Band auf Schwarz — der Schleier wuerde
     dieses Schwarz nur aufhellen. */
  .hero-scrim { display: none; }
  /* Lief auf schmalen Schirmen zweizeilig um. Ausgeblendet wird er nach dem
     ersten Scrollen — das steuert home.js. */
  .scroll-hint {
    white-space: nowrap;
    font-size: 8.5px;
    letter-spacing: 3.2px;
  }

  /* Alle Kapitel: ein Block unter dem Band, von oben nach unten gelesen.
     Absolute Positionen sind hier falsch — sie rechnen gegen Bildschirmhoehen
     zwischen 667 px und 932 px. */
  .vch-split, .vch-ed, .vch-final {
    position: fixed;
    top: var(--band-unten);
    left: var(--text-x);
    right: var(--text-x);
    bottom: 0;
    max-width: none;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    padding-top: clamp(20px, 4.4vh, 40px);
    padding-bottom: 24px;
    text-align: left;
  }
  .vch-split > *, .vch-ed > *, .vch-final > * { position: static; }

  /* ---- 01/02/03 — Editorial-Kapitel ---- */
  .vch-ed { gap: 0; }
  .ed-scrim { display: none; }
  .ed-head {
    inset: auto;
    font-size: clamp(30px, 8.6vw, 42px);
    line-height: 0.94;
    text-shadow: none;
  }
  .ed-rule { inset: auto; margin: clamp(14px, 2.2vh, 22px) 0 0; width: 100%; }
  .ed-cap { inset: auto; margin-top: 12px; font-size: 9.5px; letter-spacing: 2.4px; }
  /* Die drei folgenden Werte halten den Stand vom 06.09.2026 fest. Task 0092
     hat am 08.09. die Breitbild-Fassung vergroessert und von Haarschrift auf
     Normalschnitt gestellt; beides griff ueber die gemeinsamen Regeln auch
     hier durch, obwohl der Auftrag ausdruecklich nur Breitbild betraf.

     Gemessen war das kein Schoenheitsfehler: Auf 390x667 stiess der letzte
     Absatz damit 2px IN den festen Kollektions-Knopf. Auf dem Telefon steht
     der Text ausserdem auf schwarzem Band statt auf laufendem Film — das
     Gewicht 300 hat dort nie das Problem gehabt, gegen das 400 auf Breitbild
     hilft. */
  .ed-lt { font-size: 11.5px; letter-spacing: 3px; }
  /* Die Schrittliste war auf Telefonen ausgeblendet, weil ueber dem Vollbild
     kein Platz war. Unter dem Band ist er da. */
  .ed-l { inset: auto; display: block; max-width: none; margin-top: clamp(18px, 3vh, 30px); }
  .ed-l-rule { margin: 10px 0 14px; }
  .ed-steps { gap: clamp(8px, 1.3vh, 13px); }
  .ed-steps li { font-size: 12.5px; font-weight: 300; line-height: 1.5; text-shadow: none; }
  .ed-steps li::before { width: 20px; font-size: 9px; }
  .ed-r { inset: auto; max-width: none; margin-top: clamp(18px, 3vh, 30px); }
  /* Im Band stehen die beiden Spalten untereinander statt nebeneinander —
     aus dem Aufeinanderzu wird ein Wechselschritt. Der Weg muss dafür unter
     den Seitenrand (`--text-x`, 22px), sonst schöbe die Schrift im Anlauf
     über die Kante. */
  .vch-ed.ed-tausch { --gl-weg: 14px; }
  .vch .ed-t { font-size: clamp(17px, 4.6vw, 21px); margin-bottom: 9px; text-shadow: none; }
  .vch .ed-p { font-size: 13.5px; font-weight: 300; line-height: 1.7; text-shadow: none; }
}

/* ---- Kleine Telefone: Platz für den festen Hauptweg ----
   Seit dem 06.09.2026 steht der Weg in die Kollektion fest unten links und
   liegt als Teil von .chrome ÜBER dem Kapitelband. Er nimmt 57px (20px
   Unterkante + 37px Höhe).

   Auf 390×844 bleiben trotzdem 26px Luft. Auf 390×667 nicht: Dort stiess der
   letzte Absatz gemessen auf -1px an den Knopf.

   Eine Polsterung unten hilft NICHT — das Band füllt sich von oben, sein
   unterer Rand wird nie erreicht. Was hilft, ist der senkrechte Rhythmus.
   Und zwar er und nicht die Schriftgrösse: Die sollte gerade lesbarer
   werden, sie wieder einzudampfen hiesse, den Auftrag rückgängig zu machen.
   Enger stehen dürfen die Abstände, nicht die Buchstaben. */
@media (max-width: 900px) and (max-height: 720px) {
  .vch-split, .vch-ed, .vch-final { padding-top: 20px; }
  .ed-steps { gap: 7px; }
  .ed-l, .ed-r { margin-top: 14px; }

  /* ---- „Ausgewaehlte Zeitstuecke" ---- */
  .it-text { font-size: clamp(30px, 9vw, 44px); line-height: 0.98; }
  .it-cap { margin-top: 14px; }
  /* Stand absolut auf halber Hoehe mit Parallaxe — beides gehoert zur
     Vollbild-Fassung. Im Band-Layout flieszt sie als erster Block. */
  .it-left { position: static; left: auto; top: auto; transform: none; }
  /* Eine fruehere Regel blendet die Marken auf Telefonen aus, weil neben der
     Aussage kein Platz war. Unter dem Band ist er da. */
  .it-brands {
    position: static;
    display: block;
    transform: none;
    text-align: left;
    margin-top: clamp(22px, 4vh, 38px);
  }
  .it-blist { gap: 9px; }
  .it-blist li { font-size: 11.5px; letter-spacing: 2.4px; text-shadow: none; }

  /* ---- Finale ---- */
  .vch-final { justify-content: center; }
  .vch-final .final { display: block; }

  /* ---- Hero-Titel: zentriert, aber unter dem Band ---- */
  .vch-hero {
    top: var(--band-unten);
    bottom: 0;
    left: 0;
    right: 0;
    max-width: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
  }
}

/* Kurze Telefone (iPhone SE & Co., 667 px hoch). Die Editorial-Kapitel sind
   die einzigen mit vier Inhaltsbloecken; dort blieben nur 6 px Luft. Hier
   wird die Vertikale zusammengezogen, nicht der Inhalt gestrichen. */
@media (max-width: 760px) and (max-height: 720px) {
  .ed-head { font-size: clamp(25px, 7.4vw, 33px); }
  .ed-steps { gap: 7px; }
  .ed-steps li { font-size: 12px; line-height: 1.42; }
  .vch .ed-t { font-size: 16.5px; margin-bottom: 7px; }
  .vch .ed-p { font-size: 12.5px; line-height: 1.58; }
  .it-blist { gap: 7px; }
  /* Der Hero-Block zentrierte sich bis zur Unterkante — der Scroll-Hinweis
     sitzt aber fest bei bottom:122px und lag dadurch auf dem Untertitel
     (320×568: 29px Überlappung, 390×664: 7px; gemessen 28.09., Task 0105).
     Jetzt zentriert er sich nur im Raum ÜBER dem Hinweis. Darüber, ab
     721px Höhe, greift ein anderer Aufbau mit genug Luft — dort nicht
     setzen, sonst rutscht der Titel ins Videoband (412×740: −41px). */
  .vch-hero { bottom: 150px; }
}

@media (max-width: 760px) {
  .chrome header { padding: 18px 20px; gap: 14px; }
  /* Flex-Überlauf: Ohne min-width:0 schrumpft die Wortmarke nicht und schiebt
     die Gruppe aus dem Kopf hinaus — auf 320 px ragte sie 35 px heraus. */
  .chrome .brand { min-width: 0; flex-shrink: 1; }
  /* Der Schriftzug wird kompakter. „Luxury Timepieces" entfällt auf dieser
     Breite: Es ist die längste Zeile und trieb die Marke auf sechs Zeilen.
     Ab 761 px ist alles wieder da. */
  .chrome .brand-text { font-size: 9px; letter-spacing: 2px; }
  .chrome .brand-text span { display: none; }
  /* Seit dem 24.08.2026 stehen rechts nur noch ein Mikro-Verweis und ein
     Zeichen. Der frühere Umbruch in eine zweite Zeile ist damit entfallen —
     es passt auf 320 px in eine Zeile. */
  .chrome .chrome-nav { flex-shrink: 0; gap: 16px; }
  .brand { font-size: 11px; letter-spacing: 5px; }
  .vch { max-width: calc(100vw - 40px); }
  /* Die Vollbild-Kapitel setzen max-width:none — gleiche Spezifität wie
     die .vch-Zeile darüber, die aber später steht und deshalb gewann.
     Folge: die Sektion wurde ein 360px-Kasten am linken Rand, alle
     Kindpositionen rechneten gegen 360px statt gegen das Fenster (auf
     einem 430px-Telefon 70px tote Fläche rechts). */
  .vch-hero, .vch-split, .vch-ed { max-width: none; }
  .vch h2 { font-size: 32px; }
  .vch-hero { padding: 0 18px; gap: 18px; }
  /* 11,5vw statt 14vw: „TIMEWALKER" ist zehn Buchstaben breit (~7,5em) und
     würde sonst auf schmalen Geräten über den 18px-Rand hinauslaufen. */
  .hero-title .hl-line { font-size: clamp(34px, 11.5vw, 56px); }
  .hero-claim { font-size: 9px; letter-spacing: 2px; }
  .hero-logo { width: 68vw; }
}

/* ---------- Shop / Kollektion ---------- */
.shop {
  min-height: 100vh;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(191, 156, 90, 0.10), transparent 60%),
    var(--bg);
  padding: 0 clamp(20px, 6vw, 96px) 96px;
}
.shop-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 26px 0;
  border-bottom: 1px solid rgba(228, 205, 158, 0.10);
}
.shop-brand {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
  color: var(--ink);
  font-size: 13px;
  letter-spacing: 7px;
  text-transform: uppercase;
}
.shop-brand-mark {
  height: 44px;
  width: auto;
  display: block;
}
.shop-brand em {
  font-style: normal;
  color: var(--gold);
}

.shop-kicker {
  font-size: 11px;
  letter-spacing: 6px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 20px;
}
/* Dieselbe Kurve wie .detail-model (Uhrenname) und .legal-title: eine Schrift,
   ein Skalierungsfaktor, nur die Deckel unterscheiden die Rangfolge. Vorher
   lief dieser Titel mit 8vw auf 76px und war damit auf mittleren Breiten fast
   doppelt so groß wie jede andere Überschrift. */
.shop-title {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: clamp(34px, 5vw, 60px);
  line-height: 1.04;
  color: var(--ink);
}
.shop-title em {
  font-style: italic;
  color: var(--gold-bright);
}
/* ---------- Die Kollektions-Seite ---------- */
/* Der Kopf behält den Seitenrand; die Sektion bringt ihren eigenen mit. */
.shop--collection {
  padding-left: 0;
  padding-right: 0;
}
.shop--collection .shop-head {
  padding-left: clamp(20px, 6vw, 96px);
  padding-right: clamp(20px, 6vw, 96px);
}
/* Die Fußzeile hatte hier keinen Seitenrand — auf dem Telefon stand
   „© 2026" bei x = 0 (Task 0105). Breite statt Innenabstand: So bleibt sie
   auf breiten Schirmen genau so breit und mittig wie auf jeder anderen
   Seite (Deckel 1180px aus .site-footer). */
.shop--collection .site-footer {
  width: min(1180px, calc(100% - 2 * clamp(20px, 6vw, 96px)));
}

/* ---------- Kollektion: ruhiges Raster ---------- */
/* Eigener Grund, weil die Sektion auf der Startseite über der fixierten
   Video-Bühne liegt und diese abdecken muss. */
.collection-section {
  background: var(--bg);
  padding: clamp(56px, 8vw, 104px) clamp(20px, 6vw, 96px)
    clamp(56px, 8vw, 96px);
}
.collection-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 10px 24px;
  max-width: 1180px;
  margin: 0 auto clamp(32px, 5vw, 56px);
  padding-bottom: 22px;
  border-bottom: 1px solid rgba(191, 156, 90, 0.28);
}
/* Der Kicker steht über beiden Spalten, Titel und Zähler teilen sich die Zeile. */
.collection-head .shop-kicker {
  grid-column: 1 / -1;
  margin-bottom: 0;
}
.collection-count {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
  padding-bottom: 8px;
}
/* auto-fill + minmax ergibt von selbst 3 Spalten am Desktop, 2 am Tablet,
   1 am Handy — ohne feste Haltepunkte. */
.collection-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(18px, 2.4vw, 32px);
  max-width: 1180px;
  margin: 0 auto;
}

/* Einlauf der Kollektion. Eigene Klasse statt .gl, weil .gl im Video an die
   scroll-getriebene Kapitel-Steuerung gekoppelt ist. Keyframes werden
   geteilt. */
.collection-section .cr {
  opacity: 0;
  transform: translateY(18px);
  filter: blur(6px);
  will-change: opacity, transform, filter;
}
.collection-section.is-in .cr {
  animation: glIn 0.92s cubic-bezier(0.2, 0.7, 0.2, 1) both;
  animation-delay: calc(var(--i, 0) * 70ms + 60ms);
}
/* .is-in muss hier ausdrücklich mitgenannt werden: Ohne das hätte die Regel
   darüber die höhere Spezifität und würde trotz reduzierter Bewegung
   animieren. */
@media (prefers-reduced-motion: reduce) {
  .collection-section .cr,
  .collection-section.is-in .cr {
    opacity: 1;
    transform: none;
    filter: none;
    animation: none;
  }
}

.collection-card {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  position: relative;
  /* Kein Kartenkörper: Die Uhren stehen frei auf dem Seitengrund. Den
     Schatten trägt das Foto selbst (.collection-photo), er folgt damit der
     Silhouette der Uhr statt einem Rechteck. */
  transition: transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.collection-card:hover {
  transform: translateY(-6px);
  z-index: 2;
}
.collection-card:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}

/* Reserviert und verkauft: im Foto zurückgenommen, damit die verfügbaren
   Uhren vorn stehen. Bleiben vollwertige Links; bei Hover und Tastatur-Fokus
   kommt das Foto zurück. Das Platzhalter-Monogramm (.collection-mark) ist
   davon ausgenommen — es ist ohnehin schon fast durchsichtig. */
.collection-card.is-unavailable .collection-photo {
  opacity: 0.55;
  transition:
    opacity 0.4s ease,
    transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1),
    filter 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.collection-card.is-unavailable:hover .collection-photo,
.collection-card.is-unavailable:focus-visible .collection-photo {
  opacity: 1;
}

.collection-media {
  position: relative;
  /* 3:4 statt 4:5 (Task 0109): das Format von Handyfotos. Ein Foto mit
     Hintergrund füllt die Fläche so ohne schwarze Streifen. */
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
}
.collection-photo {
  /* Absolut in der Fläche: Sonst gibt `aspect-ratio` der Fläche nach, sobald
     das Bild höher ist — ein hochformatiges Titelbild zog seine Karte live
     auf 540 statt 465 px, die Karten standen ungleich hoch (Task 0109).
     overflow: hidden ginge auch, schnitte aber Schatten und Hover-Zoom ab. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 18px;
  display: block;
  filter: drop-shadow(0 26px 30px rgba(0, 0, 0, 0.55));
  transition:
    transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1),
    filter 0.6s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: transform, filter;
  -webkit-user-drag: none;
  user-select: none;
}
/* Hover: Die Uhr hebt leicht ab. Kein Beschnitt mehr, deshalb fällt der Zoom
   kleiner aus als zu Zeiten der Karte — sonst ragte sie in die Nachbarn. */
.collection-card:hover .collection-photo {
  transform: scale(1.06);
  filter: drop-shadow(0 34px 40px rgba(0, 0, 0, 0.62));
}
/* Foto mit Hintergrund (Task 0109). Innenabstand und Schwebeschatten sind für
   freigestellte Uhren gedacht; um ein Foto herum ergaben sie einen hellen
   Kasten mit schwarzem Rand („um das Bild ist schwarz"). Jetzt füllt es die
   Fläche vollständig — `contain`, damit nichts abgeschnitten wird. */
.collection-photo.ist-foto {
  padding: 0;
  filter: none;
  border-radius: 14px;
}
.collection-card:hover .collection-photo.ist-foto {
  transform: scale(1.02);
  filter: none;
}
.collection-mark {
  width: 44%;
  opacity: 0.14;
  -webkit-user-drag: none;
}

.cc-badge {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 2;
}
.cc-kind {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
}

.collection-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 18px 8px 4px;
  text-align: center;
}
.collection-name {
  font-family: var(--font-serif), serif;
  font-size: 18px;
  letter-spacing: 0.5px;
  color: var(--ink);
}
.collection-meta {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
}
.collection-price {
  margin-top: 4px;
  font-family: var(--font-serif), serif;
  font-size: 16px;
  color: var(--gold-bright);
}

@media (prefers-reduced-motion: reduce) {
  .collection-card,
  .collection-photo {
    transition: none;
  }
  .collection-card:hover {
    transform: none;
  }
  .collection-card:hover .collection-photo {
    transform: none;
  }
}

/* Leerer Zustand */
.shop-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 22px;
  padding: 60px 0 40px;
  text-align: center;
}
.shop-empty-mark {
  width: 92px;
  opacity: 0.2;
}
.shop-empty-text {
  font-size: 14px;
  letter-spacing: 1px;
  color: var(--muted);
}
.shop-cta,
.detail-edit {
  display: inline-block;
  font-size: 11px;
  letter-spacing: 5px;
  text-transform: uppercase;
  color: var(--gold-bright);
  text-decoration: none;
  border: 1px solid rgba(191, 156, 90, 0.55);
  padding: 15px 40px;
  transition: all 0.4s ease;
}
.shop-cta:hover,
.detail-edit:hover {
  background: var(--gold);
  border-color: var(--gold);
  color: #0a0a0a;
  letter-spacing: 7px;
}

/* ---------- Detailseite ---------- */
.detail {
  display: grid;
  /* minmax(0, …): Eine fr-Spalte wird sonst nie schmaler als ihr Inhalt —
     die ungebrochene Vorschauzeile (Task 0112) drückte bei 1024 px die Seite
     149 px quer über den Rand. */
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: clamp(28px, 5vw, 72px);
  max-width: 1120px;
  /* Luft unter dem Kopf wie auf den übrigen Unterseiten (Task 0105). */
  margin: clamp(28px, 5vw, 64px) auto 0;
  /* Oben bündig statt mittig: Mittig begann das Foto neben einer langen
     rechten Spalte 300px tiefer als der Titel (Task 0105). Die Galerie
     bleibt beim Lesen stehen, siehe unten. */
  align-items: start;
}
@media (min-width: 861px) {
  .detail .gallery { position: sticky; top: 24px; }
}
.detail-media {
  /* 3:4 wie die Kollektion (Task 0109). */
  aspect-ratio: 3 / 4;
  border: 1px solid rgba(228, 205, 158, 0.12);
  border-radius: 20px;
  background: radial-gradient(80% 70% at 50% 40%, rgba(191, 156, 90, 0.08), transparent 70%);
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.detail-photo {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 22px;
}
/* Foto mit Hintergrund: ohne Innenabstand, damit es die Fläche füllt. Die
   runden Ecken kommen vom Rahmen (overflow: hidden). */
.detail-photo.ist-foto {
  padding: 0;
}
.detail-mark {
  width: 42%;
  opacity: 0.16;
}
.detail-eyebrow {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 12px;
}
.detail-brand {
  font-size: 12px;
  letter-spacing: 6px;
  text-transform: uppercase;
  color: var(--gold);
}
.detail-eyebrow .detail-brand {
  margin-bottom: 0;
}

/* Neu / Pre-owned — Herkunfts-Label (aus dem Zustand abgeleitet) */
.kind-chip {
  display: inline-flex;
  align-items: center;
  font-size: 9px;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  padding: 4px 11px;
  border-radius: 20px;
  border: 1px solid;
  white-space: nowrap;
}
.kind-new {
  color: #0a0a0a;
  background: var(--gold-bright);
  border-color: var(--gold-bright);
}
.kind-used {
  color: var(--muted);
  border-color: rgba(228, 205, 158, 0.3);
  background: rgba(228, 205, 158, 0.06);
}
.detail-model {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: clamp(34px, 5vw, 60px);
  line-height: 1.04;
  color: var(--ink);
}
.detail-specs {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 40px;
  margin: 30px 0;
  padding: 24px 0;
  border-top: 1px solid rgba(228, 205, 158, 0.10);
  border-bottom: 1px solid rgba(228, 205, 158, 0.10);
}
.detail-specs dt {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 5px;
}
.detail-specs dd {
  font-family: var(--font-serif), serif;
  font-size: 18px;
  color: var(--ink);
}
.detail-price {
  font-family: var(--font-serif), serif;
  font-size: 26px;
  color: var(--gold-bright);
  /* Steht seit Task 0105 direkt unter dem Titel (das Datenblatt ist unter
     den Kaufweg gewandert) — der Abstand nach oben kam vorher von dort. */
  margin: 22px 0 18px;
}
.detail-desc {
  font-size: 14px;
  line-height: 1.9;
  color: var(--muted);
  margin-bottom: 30px;
  max-width: 460px;
}

/* ---------- Verwaltung ---------- */

/* Im Dashboard trägt eine einzige Schrift alles: Plus Jakarta Sans.
   Überschriften, Kennzahlen, Uhrennamen, Beschriftungen, Eingaben.
   Das Panel ist Werkzeug, nicht Schaufenster — es soll sich von der
   Verkaufsseite unterscheiden.

   Umgesetzt über die beiden Schrift-Variablen statt über die rund vierzig
   font-family-Regeln darunter: Die lösen dadurch von selbst auf Jakarta
   auf, und weil die Umdefinition nur an .ap und .login hängt, kann sie
   bauartbedingt nicht auf Startseite, Shop oder Rechtstexte durchschlagen.

   Die font-family-Zeile ist NICHT überflüssig neben den beiden Variablen:
   Elemente ohne eigene font-family-Regel erben den Wert von body — und dort
   wurde var(--font-sans) bereits zu Jost aufgelöst. Eine Variable wird an
   der Stelle ersetzt, an der die Deklaration steht, nicht beim Erben. Ohne
   diese Zeile bliebe z. B. .login-kicker auf Jost stehen.

   .ap    ist die Wurzel des Panels (app/views/admin/layout.php)
   .login trägt Anmeldung, Passwort-vergessen und Passwort-zurücksetzen */
.ap,
.login {
  --font-serif: var(--font-ui);
  --font-sans: var(--font-ui);
  font-family: var(--font-ui), sans-serif;
}

.admin {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(24px, 4vw, 56px);
  max-width: 1180px;
  margin: 0 auto;
  align-items: start;
}
.admin-form,
.admin-list {
  border: 1px solid rgba(228, 205, 158, 0.12);
  border-radius: 20px;
  background: linear-gradient(160deg, rgba(46, 39, 28, 0.24), rgba(12, 11, 9, 0.20));
  padding: clamp(22px, 3vw, 34px);
}
.admin-form-title {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: 22px;
  color: var(--ink);
  margin-bottom: 22px;
  display: flex;
  align-items: center;
  gap: 12px;
}
.admin-count {
  font-family: var(--font-sans), sans-serif;
  font-size: 11px;
  letter-spacing: 2px;
  color: var(--gold);
  border: 1px solid rgba(191, 156, 90, 0.4);
  border-radius: 20px;
  padding: 2px 12px;
}

/* Bild-Upload */
.admin-image {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 3 / 2;
  border: 1px dashed rgba(228, 205, 158, 0.30);
  border-radius: 14px;
  cursor: pointer;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.25);
  transition: border-color 0.3s ease;
}
.admin-image:hover {
  border-color: rgba(228, 205, 158, 0.55);
}
.admin-image-preview {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 10px;
}
.admin-image-hint {
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
}
.admin-image-remove {
  align-self: flex-start;
  margin: 10px 0 4px;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  cursor: pointer;
  text-decoration: underline;
}
.admin-image-remove:hover {
  color: var(--gold-bright);
}

/* Felder */
.admin-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin-top: 16px;
}
.admin-field {
  display: flex;
  flex-direction: column;
  gap: 7px;
  margin-top: 16px;
}
.admin-row .admin-field {
  margin-top: 0;
}
.admin-field span {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
}
.admin-field input,
.admin-field textarea {
  font-family: var(--font-sans), sans-serif;
  font-size: 14px;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.30);
  border: 1px solid rgba(228, 205, 158, 0.16);
  border-radius: 10px;
  padding: 12px 14px;
  transition: border-color 0.3s ease;
  resize: vertical;
}
.admin-field input:focus,
.admin-field textarea:focus {
  outline: none;
  border-color: rgba(227, 200, 143, 0.6);
}
.admin-field input::placeholder,
.admin-field textarea::placeholder {
  color: rgba(240, 232, 216, 0.32);
}

.admin-error {
  margin-top: 16px;
  font-size: 12px;
  letter-spacing: 1px;
  color: #e0a0a0;
}
.admin-actions {
  display: flex;
  gap: 14px;
  margin-top: 24px;
}
.admin-save {
  font-family: var(--font-sans), sans-serif;
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: #0a0a0a;
  background: var(--gold);
  border: 1px solid var(--gold);
  padding: 15px 34px;
  cursor: pointer;
  transition: all 0.4s ease;
}
.admin-save:hover {
  background: var(--gold-bright);
  border-color: var(--gold-bright);
}
.admin-save:disabled {
  opacity: 0.5;
  cursor: default;
}
.admin-cancel {
  font-family: var(--font-sans), sans-serif;
  font-size: 11px;
  letter-spacing: 4px;
  text-transform: uppercase;
  color: var(--muted);
  background: none;
  border: 1px solid rgba(228, 205, 158, 0.22);
  padding: 15px 28px;
  cursor: pointer;
  transition: all 0.3s ease;
}
.admin-cancel:hover {
  color: var(--ink);
  border-color: rgba(228, 205, 158, 0.4);
}

/* Liste */
.admin-empty {
  font-size: 13px;
  color: var(--muted);
  padding: 10px 0;
}
.admin-item {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 14px 0;
  border-top: 1px solid rgba(228, 205, 158, 0.08);
}
.admin-item:first-of-type {
  border-top: none;
}
.admin-item.is-editing {
  outline: 1px solid rgba(191, 156, 90, 0.4);
  outline-offset: 8px;
  border-radius: 6px;
}
.admin-item-thumb {
  flex: none;
  width: 62px;
  height: 62px;
  border-radius: 10px;
  overflow: hidden;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid rgba(228, 205, 158, 0.10);
  display: flex;
  align-items: center;
  justify-content: center;
}
.admin-item-thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: 6px;
}
.admin-item-thumb .admin-item-mark {
  opacity: 0.25;
}
.admin-item-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.admin-item-name {
  font-family: var(--font-serif), serif;
  font-size: 16px;
  color: var(--ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.admin-item-meta {
  font-size: 11px;
  letter-spacing: 1px;
  color: var(--muted);
}
.admin-item-actions {
  display: flex;
  gap: 8px;
  flex: none;
}
.admin-item-actions .is-danger:hover {
  color: #e0a0a0;
  border-color: rgba(224, 160, 160, 0.5);
}

@media (max-width: 860px) {
  .detail { grid-template-columns: minmax(0, 1fr); }
  .admin { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 760px) {
  .shop-brand span { font-size: 11px; letter-spacing: 5px; }
  .admin-row { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .admin-item { flex-wrap: wrap; }
}

/* ---------- Login (Verwaltung) ---------- */
.login {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background:
    radial-gradient(120% 90% at 50% -10%, rgba(191, 156, 90, 0.10), transparent 60%),
    var(--bg);
}
.login-card {
  width: 100%;
  max-width: 380px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  text-align: center;
  border: 1px solid rgba(228, 205, 158, 0.12);
  border-radius: 22px;
  padding: 48px 40px;
  background: linear-gradient(160deg, rgba(46, 39, 28, 0.24), rgba(12, 11, 9, 0.20));
}
.login-mark { width: 68px; opacity: 0.9; }
.login-kicker {
  font-size: 11px;
  letter-spacing: 6px;
  text-transform: uppercase;
  color: var(--gold);
}
.login-title {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: 30px;
  color: var(--ink);
  margin-bottom: 6px;
}
.login-input {
  width: 100%;
  text-align: center;
  font-family: var(--font-sans), sans-serif;
  font-size: 15px;
  letter-spacing: 2px;
  color: var(--ink);
  background: rgba(0, 0, 0, 0.30);
  border: 1px solid rgba(228, 205, 158, 0.18);
  border-radius: 10px;
  padding: 14px 16px;
}
.login-input:focus {
  outline: none;
  border-color: rgba(227, 200, 143, 0.6);
}
.login-error {
  font-size: 12px;
  letter-spacing: 1px;
  color: #e0a0a0;
}
.login-forgot {
  font-size: 12px;
  letter-spacing: 1px;
  color: var(--muted);
  text-decoration: none;
  margin-top: -4px;
}
.login-forgot:hover {
  color: var(--gold-bright);
}
.login-hint {
  font-size: 13px;
  line-height: 1.6;
  color: var(--ink);
}

/* Bild-Upload: Hinweiszeile (Auto-Freistellen) + Entfernen-Button */
.admin-image-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 10px 2px 4px;
}
.admin-image-note {
  font-size: 10px;
  letter-spacing: 1px;
  color: var(--muted);
}
.admin-image-foot .admin-image-remove {
  margin: 0;
  align-self: auto;
  flex: none;
}

/* ================= Admin-Panel ================= */
.ap { display: flex; min-height: 100vh; background: var(--bg); }

/* Sidebar */
.ap-side {
  width: 250px; flex: none; position: sticky; top: 0; align-self: flex-start;
  height: 100vh; display: flex; flex-direction: column;
  padding: 30px 20px; border-right: 1px solid rgba(228,205,158,0.10);
  background: linear-gradient(180deg, rgba(20,17,12,0.6), rgba(8,8,8,0.6));
}
.ap-brand { display: flex; align-items: center; gap: 12px; padding: 0 8px 26px; }
.ap-brand img { height: 40px; width: auto; }
.ap-brand span { font-size: 12px; letter-spacing: 5px; text-transform: uppercase; color: var(--ink); }
.ap-brand em { font-style: normal; color: var(--gold); }
.ap-nav { display: flex; flex-direction: column; gap: 4px; flex: 1; }
.ap-nav-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 12px 16px; border-radius: 10px; text-decoration: none;
  font-size: 13px; letter-spacing: 1px; color: var(--muted); transition: all .25s ease;
}
.ap-nav-item:hover { color: var(--ink); background: rgba(255,255,255,0.03); }
.ap-nav-item.is-active { color: var(--ink); background: rgba(227,200,143,0.10); box-shadow: inset 2px 0 0 var(--gold); }
.ap-badge {
  font-size: 10px; min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
  background: var(--gold); color: #0a0a0a; display: inline-flex; align-items: center; justify-content: center;
}
.ap-side-foot { display: flex; flex-direction: column; gap: 10px; padding-top: 18px; border-top: 1px solid rgba(228,205,158,0.08); }
.ap-side-link { font-size: 11px; letter-spacing: 1px; color: var(--muted); text-decoration: none; padding: 6px 8px; }
.ap-side-link:hover { color: var(--gold-bright); }

/* Main */
.ap-main { flex: 1; min-width: 0; }
.ap-page { padding: clamp(24px, 4vw, 48px); max-width: 1200px; }
/* Die Kollektionsverwaltung zeigt Liste und Formular jeweils über die ganze
   Breite und braucht sie auch: Die Liste schnitt bei 1200px lange Uhrennamen
   ab, und das Titelbild soll gross stehen dürfen.
   Dashboard, Anfragen und Einstellungen behalten ihre 1200px: Ein
   Einstellungsformular über 1700px zu ziehen macht es nicht lesbarer. */
.ap-page-wide { max-width: none; }
.ap-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 16px; margin-bottom: 30px; }
.ap-kicker { font-size: 11px; letter-spacing: 5px; text-transform: uppercase; color: var(--gold); margin-bottom: 8px; }
.ap-title { font-family: var(--font-serif), serif; font-weight: 400; font-size: clamp(30px, 4vw, 44px); color: var(--ink); line-height: 1; }
.ap-count { font-size: 12px; letter-spacing: 2px; color: var(--muted); }


.ap-card {
  border: 1px solid rgba(228,205,158,0.12); border-radius: 18px; padding: clamp(20px, 3vw, 30px);
  background: linear-gradient(160deg, rgba(46,39,28,0.22), rgba(12,11,9,0.18));
}
.ap-card-title { font-family: var(--font-serif), serif; font-weight: 400; font-size: 20px; color: var(--ink); margin-bottom: 20px; }
.ap-empty { font-size: 13px; color: var(--muted); }
.ap-note { font-size: 11px; letter-spacing: .5px; color: var(--muted); margin: 8px 2px 18px; }
.ap-error { font-size: 12px; color: #e0a0a0; margin-top: 14px; }
.ap-success { font-size: 12px; color: #a7d3a0; margin-top: 14px; }
.ap-actions { display: flex; gap: 12px; margin-top: 24px; }

/* Felder */
.ap-field { display: flex; flex-direction: column; gap: 7px; margin-top: 16px; }
.ap-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin-top: 16px; }
.ap-row .ap-field { margin-top: 0; }
.ap-field span { font-size: 10px; letter-spacing: 3px; text-transform: uppercase; color: var(--muted); }
.ap-hint { font-size: 11px; letter-spacing: 0.3px; text-transform: none; color: var(--muted); line-height: 1.5; }
.ap-hint em { font-style: normal; color: var(--gold-bright); }
.ap-field input, .ap-field select, .ap-field textarea {
  font-family: var(--font-sans), sans-serif; font-size: 14px; color: var(--ink);
  background: rgba(0,0,0,0.30); border: 1px solid rgba(228,205,158,0.16); border-radius: 10px;
  padding: 12px 14px; transition: border-color .3s ease; resize: vertical;
}
.ap-field input:focus, .ap-field select:focus, .ap-field textarea:focus { outline: none; border-color: rgba(227,200,143,0.6); }
/* Ein Feld, das nur dasteht, damit klar ist worauf sich die Seite bezieht —
   etwa der Zugang über dem Passwortwechsel. Es soll nicht aussehen wie eine
   Einladung zum Tippen. */
.ap-field input[readonly] {
  color: var(--muted); cursor: default;
  background: rgba(255, 255, 255, 0.015);
  border-style: dashed;
}
.ap-field input[readonly]:focus { border-color: var(--field-border); }
.ap-field input::placeholder, .ap-field textarea::placeholder { color: rgba(240,232,216,0.32); }
.ap-field select option { background: #14110c; }

/* KPIs */
.dash-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 16px; margin-bottom: 22px; }
.kpi { border: 1px solid rgba(228,205,158,0.12); border-radius: 16px; padding: 22px; background: linear-gradient(160deg, rgba(46,39,28,0.20), rgba(12,11,9,0.16)); }
.kpi.is-accent { border-color: rgba(227,200,143,0.35); background: linear-gradient(160deg, rgba(191,156,90,0.14), rgba(12,11,9,0.16)); }
a.kpi { display: block; text-decoration: none; transition: border-color .3s ease; }
a.kpi:hover { border-color: rgba(227,200,143,0.55); }
.kpi-value { display: block; font-family: var(--font-serif), serif; font-size: 40px; line-height: 1; color: var(--ink); }
.kpi-label { display: block; margin-top: 8px; font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }

/* Dashboard-Grid */
.dash-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.dash-card-title { font-size: 13px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); margin-bottom: 20px; }
.dash-chart { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
.donut { width: 160px; height: 160px; flex: none; }
.donut-num { fill: var(--ink); font-family: var(--font-serif), serif; font-size: 24px; text-anchor: middle; }
.donut-cap { fill: var(--muted); font-size: 8px; letter-spacing: 2px; text-anchor: middle; text-transform: uppercase; }
.dash-legend { list-style: none; display: flex; flex-direction: column; gap: 12px; flex: 1; min-width: 150px; }
.dash-legend li { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--ink); }
.dash-legend .dot { width: 10px; height: 10px; border-radius: 3px; flex: none; }
.dash-legend-label { flex: 1; color: var(--muted); }
.dash-legend-val { color: var(--ink); }
.dash-recent { list-style: none; display: flex; flex-direction: column; gap: 4px; }
.dash-recent li { display: flex; align-items: center; gap: 14px; padding: 10px 0; border-top: 1px solid rgba(228,205,158,0.07); }
.dash-recent li:first-child { border-top: none; }
.dash-recent-thumb { width: 46px; height: 46px; flex: none; border-radius: 8px; overflow: hidden; background: rgba(0,0,0,0.3); border: 1px solid rgba(228,205,158,0.10); display: flex; align-items: center; justify-content: center; }
.dash-recent-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 5px; }
.dash-recent-thumb img.is-mark { opacity: .25; }
.dash-recent-name { flex: 1; font-family: var(--font-serif), serif; font-size: 15px; color: var(--ink); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Badges */
.badge { display: inline-flex; align-items: center; font-size: 9px; letter-spacing: 2px; text-transform: uppercase; padding: 4px 10px; border-radius: 20px; border: 1px solid; white-space: nowrap; }
.badge-published { color: var(--gold-bright); border-color: rgba(227,200,143,0.4); background: rgba(227,200,143,0.08); }
.badge-reserved { color: #d9b978; border-color: rgba(191,156,90,0.5); background: rgba(191,156,90,0.12); }
.badge-sold { color: var(--muted); border-color: rgba(240,232,216,0.25); background: rgba(240,232,216,0.05); }
.badge-draft { color: var(--muted); border-color: rgba(240,232,216,0.22); background: transparent; border-style: dashed; }

/* ══════════════════════════════════════════════════════════════════════
   KOLLEKTION — Liste und Formular
   ══════════════════════════════════════════════════════════════════════
   Zwei Ansichten auf einer Seite: erst die Liste über die volle Breite, auf
   Wunsch das Formular über die volle Breite. Umgeschaltet wird mit `hidden`
   in kollektion.js — hier steht nur, wie die beiden aussehen.

   Bis zum 30.08.2026 standen sie nebeneinander. Dem Formular blieb damit die
   halbe Seite, und die Bilder mussten in 92-px-Kacheln passen — auch das
   Titelbild, also genau das Bild, das der Kunde später zuerst sieht. */

/* Der Wechsel zwischen Liste und Formular ist ein Ansichtswechsel, kein
   Seitenwechsel — ohne den kurzen Anflug wirkt er wie ein Sprung. */
.col-view { animation: col-view-ein 0.3s cubic-bezier(0.2, 0.7, 0.2, 1); }
@keyframes col-view-ein { from { opacity: 0; transform: translateY(6px); } }

.col-head-actions { display: flex; align-items: center; gap: 20px; }
/* Steht jetzt neben der Überschrift, nicht darüber — siehe kollektion.php. */
.col-back { flex: none; }
.col-flash { font-size: 12px; letter-spacing: 0.4px; color: var(--gold-bright); margin: -14px 0 18px; }

.col-internal { margin-top: 6px; padding-top: 14px; border-top: 1px dashed rgba(228,205,158,0.14); }
.col-internal-title { font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }

/* ---- Abschnitte des Formulars ----
   Medien · Produkt · Details · Preis · Nur intern · Veröffentlichung.
   Eine Haarlinie je Abschnitt statt einer Karte je Abschnitt: Sechs Kästen
   untereinander wären lauter als das, was in ihnen steht. */
.col-section { margin-top: clamp(30px, 3.4vw, 46px); padding-top: clamp(28px, 3.2vw, 42px); border-top: 1px solid rgba(228,205,158,0.09); }
.col-section:first-of-type { margin-top: 0; padding-top: 0; border-top: none; }
.col-section-title { font-size: 11px; letter-spacing: 4px; text-transform: uppercase; color: var(--gold); font-weight: 400; margin-bottom: 18px; }

/* ---- Medien ----
   Links das Titelbild, rechts die echten Aufnahmen, dazwischen eine Linie.
   Die Trennung ist keine Gestaltungsfrage: Das Titelbild DARF freigestellt
   werden, die echten Aufnahmen werden NIE verändert. Wer das im Raster nicht
   sieht, hält den Freistellen-Schalter für einen Schalter über beide. */
.col-media { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: clamp(26px, 3vw, 46px); align-items: start; }
/* min-width: 0 ist hier kein Zierrat — ohne das weigert sich eine Rasterspalte,
   kleiner als ihr Inhalt zu werden, und ein breites Bild schiebt die Seite auf. */
.col-media-main, .col-media-side { min-width: 0; }
.col-media-side { border-left: 1px solid rgba(228,205,158,0.09); padding-left: clamp(26px, 3vw, 46px); }
.col-label { font-size: 10px; letter-spacing: 3px; text-transform: uppercase; color: var(--ink); }
.col-label-count { color: var(--muted); letter-spacing: 1px; }
.col-label-note { font-size: 11px; color: var(--muted); line-height: 1.5; margin-top: 6px; }
.col-inline-error { font-size: 12px; color: #e0a0a0; line-height: 1.5; margin-top: 10px; }

/* ---- Titelbild ----
   Alle Zustände liegen in derselben Rasterzelle übereinander; welcher zu
   sehen ist, entscheidet `data-state` weiter unten. */
.cover-stage {
  position: relative; display: grid; place-items: center;
  /* Das Seitenverhaeltnis gibt die Buehne vor, nicht das Bild. Ohne diese
     Zeile bestimmte ein quadratisches Foto die Hoehe — bei 600px Spaltenbreite
     also 600px Buehne, und das Formular begann erst darunter.
     Auf dem Desktop tritt weiter unten die Bildschirmhoehe an diese Stelle.

     `width: 100%` ist dabei kein Zierrat: Ohne die Zeile rechnet die Buehne
     bei jeder Hoehenvorgabe ihre BREITE aus dem Verhaeltnis zurueck. Auf
     390px griff `min-height: 260px`, und aus 260 wurden 347px Breite in einer
     339px breiten Spalte — die Seite scrollte waagerecht. */
  width: 100%;
  aspect-ratio: 4 / 3; min-height: 260px; max-height: 58vh;
  margin-top: 10px;
  border: 1px solid var(--field-border); border-radius: var(--field-radius);
  background:
    radial-gradient(120% 90% at 50% 28%, rgba(228,205,158,0.05), transparent 68%),
    rgba(0,0,0,0.30);
  transition: background-color var(--ease), box-shadow var(--ease), border-color var(--ease);
}
/* Leerzustand und Meldung teilen sich eine Rasterzelle; das Bild liegt
   absolut darueber (siehe .cover-img). */
.cover-empty, .cover-status { grid-area: 1 / 1; }

.cover-empty {
  width: 100%; height: 100%;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;
  border: none; background: none; font: inherit; color: var(--muted); cursor: pointer;
  transition: color var(--ease);
}
.cover-empty:hover { color: var(--gold-bright); }
.cover-empty:focus-visible { outline: 1px solid rgba(191,156,90,0.55); outline-offset: -6px; border-radius: var(--field-radius); }
.cover-empty-mark { width: 30px; height: 30px; color: var(--gold); transition: transform var(--ease), color var(--ease); }
.cover-empty-text { font-size: 14px; color: var(--ink); }
.cover-empty-sub { font-size: 12.5px; color: var(--muted); line-height: 1.5; }

/* contain und viel Polsterung: Die Uhr steht frei, sie füllt keine Kachel.
   Die echten Aufnahmen darunter machen es genau umgekehrt — auch daran soll
   man die beiden Arten unterscheiden. */
/* Absolut statt als Rasterelement, und das ist kein Geschmacksurteil:
   Als Rasterelement loeste weder `height: 100%` noch `max-height: 100%` gegen
   die Buehnenhoehe auf — ein quadratisches Foto wurde 595px hoch in einer
   446px hohen Buehne und schob sich in den Schalter darunter. Mit `inset: 0`
   gibt die Buehne die Groesse vor, `contain` haelt das Seitenverhaeltnis. */
/* ⚠ `pointer-events: none` ist hier kein Feinschliff, sondern die Bedingung
   dafuer, dass die Ablageflaeche ueberhaupt anklickbar ist.

   Das Bild liegt absolut ueber der ganzen Buehne — auch im Leerzustand, wo es
   mit `opacity: 0` unsichtbar ist. Unsichtbar heisst aber NICHT durchlaessig:
   Es fing jeden Klick ab, bevor er den Knopf darunter erreichte. Der
   Dateidialog ging deshalb nie auf, und auch der Zeiger wechselte nicht.
   Gemerkt hat es keine Pruefung, weil `element.click()` die Trefferpruefung
   des Browsers ueberspringt. */
.cover-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; padding: clamp(22px, 4vw, 54px); opacity: 0; pointer-events: none; transition: opacity var(--ease); }
/* Ohne Bild hat es auf der Buehne ohnehin nichts zu suchen. */
.cover-stage[data-state="leer"] .cover-img { display: none; }
/* Damit die Meldung ueber dem abgedunkelten Bild steht und nicht darunter. */
.cover-status { position: relative; z-index: 1; }

/* ---- Der Ladezustand ----
   Ein Kreis, darunter zwei Zeilen: was gerade geschieht und welcher Schritt
   gerade laeuft. Keine Megabyte mehr — die Zahl gehoerte dem Programm, nicht
   dem Haendler. Und weiter keine Zeitschaetzung: Was der Kreis zeigt, ist
   gemessen (die Rechnung steht in kollektion.js). */
/* Senkrecht knapper als waagerecht: Auf einem flachen Fenster ist die Buehne
   nur 220px hoch (siehe die Hoehenregel weiter unten), und Kreis, Zeile und
   Schritt muessen zusammen hineinpassen. */
.cover-status { display: none; flex-direction: column; align-items: center; gap: 18px; padding: 20px 28px; text-align: center; width: min(320px, 78%); }
.cover-status-phase { font-size: 11px; letter-spacing: 2.5px; text-transform: uppercase; color: var(--ink); }
.cover-status-schritt { font-size: 11.5px; color: var(--muted); line-height: 1.5; min-height: 1.5em; margin-top: -8px; }

.cover-ring { position: relative; width: 72px; height: 72px; }
/* Ein weicher dunkler Grund unter dem Kreis.
   Ohne ihn liegt die blasse Spur auf dem Foto, das gerade verarbeitet wird —
   und auf einem hellen Zifferblatt verschwindet sie. Dann sieht ein Kreis bei
   70 % aus wie ein Bogen ohne Anfang und Ende, und die Zahl steht in der
   Luft. Weich auslaufend, damit es keine Platte wird. */
.cover-ring::before {
  content: ''; position: absolute; inset: -12px; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(10,9,7,0.78), rgba(10,9,7,0));
}
/* Gedreht, damit der Kreis oben anfaengt und nicht auf drei Uhr. */
.cover-ring-scheibe { position: relative; display: block; width: 100%; height: 100%; transform: rotate(-90deg); }
.cover-ring-spur, .cover-ring-wert { fill: none; stroke-width: 2.5; }
.cover-ring-spur { stroke: rgba(228,205,158,0.22); }
.cover-ring-wert {
  stroke: var(--gold-bright); stroke-linecap: round;
  /* Der Umfang ist per pathLength auf 100 Einheiten normiert; der Rest ist
     schlicht `100 - Prozent`. Kein Radius, der in zwei Dateien stimmen muss. */
  stroke-dasharray: 100; stroke-dashoffset: 100;
  transition: stroke-dashoffset 0.45s cubic-bezier(0.2, 0.7, 0.2, 1);
}
/* Tabellenziffern: Sonst zappelt die Zahl im Kreis bei jedem Wechsel von
   9 auf 10, weil die Eins schmaler ist als die Null. */
.cover-ring-zahl {
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: 14px; color: var(--ink); font-variant-numeric: tabular-nums;
}

.cover-tools { display: none; position: absolute; right: 14px; bottom: 14px; }
.cover-action {
  width: 36px; height: 36px; border-radius: 50%;
  border: 1px solid rgba(228,205,158,0.18); background: rgba(10,9,7,0.72);
  color: var(--muted); font-size: 13px; line-height: 1; cursor: pointer;
  transition: color var(--ease), border-color var(--ease), background var(--ease);
}
.cover-action:hover, .cover-action[aria-expanded="true"] { color: var(--gold-bright); border-color: rgba(227,200,143,0.5); background: rgba(10,9,7,0.92); }
.cover-action:focus-visible { outline: 1px solid rgba(191,156,90,0.55); outline-offset: 2px; }

.cover-menu, .shot-menu {
  position: absolute; z-index: 4; min-width: 186px; padding: 6px;
  display: flex; flex-direction: column;
  border: 1px solid var(--field-border); border-radius: var(--field-radius);
  background: #100e0b; box-shadow: 0 18px 40px rgba(0,0,0,0.55);
}
.cover-menu { right: 0; bottom: 46px; }
.cover-menu button, .shot-menu button {
  text-align: left; padding: 9px 12px; border: none; background: none;
  font: inherit; font-size: 12px; color: var(--ink);
  border-radius: var(--control-radius); cursor: pointer;
  transition: background var(--ease), color var(--ease);
}
.cover-menu button:hover, .shot-menu button:hover { background: rgba(228,205,158,0.08); color: var(--gold-bright); }

/* ---- Das Bild in Arbeit ----
   Es liegt unter dem Kreis: noch mit Hintergrund, gedaempft und leicht
   unscharf. Kein Schmuck, sondern das Vorher zum Nachher — sonst erschiene
   die freigestellte Uhr am Ende aus dem Nichts.

   `pointer-events: none` aus demselben Grund wie bei .cover-img: Eine
   unsichtbare Ebene ueber der ganzen Buehne faengt sonst jeden Klick ab,
   bevor er die Ablageflaeche erreicht. */
.cover-roh {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: contain; padding: clamp(22px, 4vw, 54px);
  opacity: 0; pointer-events: none;
  filter: blur(3px) saturate(0.55);
  transition: opacity 0.5s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.cover-stage[data-state="leer"] .cover-roh { display: none; }

/* ---- Die Enthuellung ----
   Der Moment, auf den die ganze Verarbeitung hinauslaeuft: Die Uhr steht
   frei. Er bekommt genau eine Bewegung — das freigestellte Bild tritt aus
   der Unschaerfe nach vorn, waehrend der Hintergrund darunter weggeht, und
   ein einmaliger Schein hebt es dabei kurz an. Nur nach einer Verarbeitung,
   nicht beim Oeffnen einer gespeicherten Uhr; die Klasse setzt
   kollektion.js. */
.cover-stage.ist-enthuellt .cover-img {
  animation: cover-enthuellen 0.75s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.cover-stage.ist-enthuellt::after {
  content: ''; position: absolute; inset: 0; border-radius: inherit;
  pointer-events: none;
  background: radial-gradient(58% 46% at 50% 46%, rgba(228,205,158,0.22), transparent 70%);
  animation: cover-schein 0.95s ease-out both;
}
@keyframes cover-enthuellen {
  from { opacity: 0; transform: scale(0.965); filter: blur(10px); }
  to   { opacity: 1; transform: scale(1);     filter: blur(0); }
}
@keyframes cover-schein {
  0%   { opacity: 0; }
  30%  { opacity: 1; }
  100% { opacity: 0; }
}

/* Die Zustände. Sie stehen bewusst zusammen an einer Stelle. */
.cover-stage[data-state="laden"] .cover-empty { display: none; }
.cover-stage[data-state="laden"] .cover-status { display: flex; }
.cover-stage[data-state="laden"] .cover-img { opacity: 0.16; }
.cover-stage[data-state="laden"] .cover-roh { opacity: 0.28; }
.cover-stage[data-state="bereit"] .cover-empty { display: none; }
.cover-stage[data-state="bereit"] .cover-img { opacity: 1; }
.cover-stage[data-state="bereit"] .cover-roh { opacity: 0; }
.cover-stage[data-state="bereit"] .cover-tools { display: block; }

/* ---- Der Medienblock ist der erste Bildschirm ----
   Wer eine Uhr anlegt, fängt mit dem Bild an. Es soll ohne Scrollen ganz zu
   sehen sein — und der erste Scroll soll dann das Formular bringen, nicht
   den Rest eines halb abgeschnittenen Bildes.

   Deshalb bekommt die Bühne hier ihre Höhe von der Bildschirmhöhe statt vom
   Seitenverhältnis. Der Abzug ist gemessen, nicht geschätzt:

     Kopfzeile der Verwaltung          65
     Seitenpolsterung oben             48
     Kopf des Formulars mit Abstand    74   (einzeilig, siehe kollektion.php)
     „MEDIEN" mit Abstand              32
     „Titelbild" und Abstand darüber   23
     Schalter darunter mit Abstand     83
     Aktionsleiste mit Abstand        107
                                    -----
                                      432

   Der Boden von 220px gilt für sehr flache Fenster: Dort ist ein Bildschirm
   ohne Scrollen nicht zu haben, und ein auf 60px gequetschtes Titelbild wäre
   die schlechtere Antwort.

   ⚠ Die Regel MUSS hinter der Grundregel von .cover-stage stehen. Stand sie
   davor, gewann dort `aspect-ratio: 4/3` — und die Bühne rechnete sich aus
   der neuen Höhe eine Breite von 624px in einer 595px breiten Spalte. */
@media (min-width: 901px) {
  .cover-stage {
    aspect-ratio: auto;
    height: clamp(220px, calc(100vh - 432px), 520px);
    height: clamp(220px, calc(100dvh - 432px), 520px);
    max-height: none;
  }
}

/* ---- Ablageflächen ----
   Solange die Fläche leer ist, trägt sie die gestrichelte Kante des Ankaufs
   (.ak-drop) — dieselbe Machart, damit „hier kann etwas hin" in der ganzen
   Anwendung gleich aussieht. Liegt ein Bild darin, verschwindet sie: Ein
   fertiges Titelbild ist keine Aufforderung mehr. */
.cover-stage[data-state="leer"] {
  --ak-drop-strich: rgba(228, 205, 158, 0.3);
  border-color: transparent;
  background-image:
    repeating-linear-gradient(0deg,   var(--ak-drop-strich) 0 7px, transparent 7px 15px),
    repeating-linear-gradient(90deg,  var(--ak-drop-strich) 0 7px, transparent 7px 15px),
    repeating-linear-gradient(180deg, var(--ak-drop-strich) 0 7px, transparent 7px 15px),
    repeating-linear-gradient(270deg, var(--ak-drop-strich) 0 7px, transparent 7px 15px);
  background-size: 1px 100%, 100% 1px, 1px 100%, 100% 1px;
  background-position: 0 0, 0 0, 100% 0, 0 100%;
  background-repeat: no-repeat;
}
.cover-stage[data-state="leer"]:hover { --ak-drop-strich: rgba(228, 205, 158, 0.5); }
.cover-empty:hover .cover-empty-mark { color: var(--gold-bright); transform: translateY(-2px); }

/* Sobald irgendwo im Fenster eine Datei gezogen wird, heben sich BEIDE
   Flächen leise hervor. Ohne diesen Hinweis zielt man auf gut Glück — und
   hier zielt man auf zwei Dinge, die sich unterschiedlich verhalten. */
.col-form.zieht .cover-stage,
.col-form.zieht .shot-add {
  --ak-drop-strich: rgba(228, 205, 158, 0.55);
  background-color: rgba(255, 255, 255, 0.05);
  border-color: rgba(228,205,158,0.4);
}
/* Und direkt darüber deutlich: hier trifft es. */
.cover-stage.ist-ziel, .shots-grid.ist-ziel {
  background-color: rgba(191, 156, 90, 0.14);
  box-shadow: inset 0 0 0 1px var(--gold), 0 0 0 4px rgba(191, 156, 90, 0.14);
}
.cover-stage.ist-ziel .cover-empty-mark { color: var(--gold-bright); transform: translateY(-3px); }

/* Der Schalter gehört zum Bild darüber und zu nichts anderem. */
.cover-toggle {
  display: flex; align-items: flex-start; gap: 12px;
  margin-top: 16px; padding: 14px 16px;
  border: 1px solid var(--field-border); border-radius: var(--field-radius);
  background: var(--field-bg); cursor: pointer;
  transition: border-color var(--ease);
}
.cover-toggle:hover { border-color: rgba(227,200,143,0.34); }
.cover-toggle input { flex: none; width: 15px; height: 15px; margin-top: 2px; accent-color: var(--gold); cursor: pointer; }
.cover-toggle-body { display: flex; flex-direction: column; gap: 4px; }
.cover-toggle-name { font-size: 13px; color: var(--ink); }
.cover-toggle-note { font-size: 11px; color: var(--muted); line-height: 1.5; }

/* ---- Echte Aufnahmen ----
   Kein Freistellen, kein Beschneiden, keine Verarbeitung. Deshalb gibt es
   hier auch keinen Verarbeitungszustand — nur einen Upload je Kachel. */
.shots-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 12px; margin-top: 12px;
              border-radius: var(--field-radius); transition: background-color var(--ease), box-shadow var(--ease); }
.shot { position: relative; aspect-ratio: 1; border: 1px solid var(--field-border); border-radius: var(--field-radius); background: rgba(0,0,0,0.3); }
/* Ohne das Anheben verschwindet ein geöffnetes Menü unter der nächsten Kachel. */
.shot:hover, .shot:focus-within { z-index: 5; }
.shot.is-neu { animation: shot-ein 0.32s cubic-bezier(0.2, 0.7, 0.2, 1); }
@keyframes shot-ein { from { opacity: 0; transform: scale(0.97); } }
/* cover statt contain: Diese Bilder leben von ihrem Hintergrund. */
.shot-img { display: block; width: 100%; height: 100%; object-fit: cover; border-radius: calc(var(--field-radius) - 1px); }

.shot-tools { position: absolute; top: 8px; right: 8px; opacity: 0; transition: opacity var(--ease); }
.shot:hover .shot-tools, .shot:focus-within .shot-tools { opacity: 1; }
.shot-action { width: 26px; height: 26px; border-radius: 50%; border: 1px solid rgba(228,205,158,0.2); background: rgba(10,9,7,0.78); color: var(--ink); font-size: 12px; line-height: 1; cursor: pointer; transition: color var(--ease), border-color var(--ease); }
.shot-action:hover, .shot-action[aria-expanded="true"] { color: var(--gold-bright); border-color: rgba(227,200,143,0.5); }
.shot-action:focus-visible { outline: 1px solid rgba(191,156,90,0.55); outline-offset: 2px; }
/* Bezugspunkt ist .shot, nicht .shot-tools — siehe kollektion.js. */
.shot-menu { top: 40px; right: 8px; }

.shot.is-laedt { background: rgba(0,0,0,0.45); }
.shot-bar { position: absolute; left: 16px; right: 16px; bottom: 16px; height: 2px; border-radius: 2px; background: rgba(228,205,158,0.14); overflow: hidden; }
.shot-bar::after { content: ''; position: absolute; top: 0; bottom: 0; width: 40%; border-radius: 2px; background: linear-gradient(90deg, transparent, var(--gold), transparent); animation: shot-lauf 1.2s ease-in-out infinite; }
@keyframes shot-lauf { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

.shot.is-fehler { border-color: rgba(224,160,160,0.4); }
.shot-fehler { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; padding: 12px; text-align: center; }
.shot-fehler-text { font-size: 11px; color: #e0a0a0; line-height: 1.45; }
.shot-retry { border: none; background: none; font: inherit; font-size: 11px; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; cursor: pointer; padding: 2px 4px; transition: color var(--ease); }
.shot-retry:hover { color: var(--gold-bright); }

.shot-add {
  aspect-ratio: 1;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  border: 1px dashed rgba(228,205,158,0.3); border-radius: var(--field-radius);
  background: rgba(0,0,0,0.2); font: inherit; color: var(--muted); cursor: pointer;
  transition: border-color var(--ease), color var(--ease);
}
.shot-add:hover { border-color: rgba(227,200,143,0.55); color: var(--gold-bright); }
.shot-add:focus-visible { outline: 1px solid rgba(191,156,90,0.55); outline-offset: 2px; }
.shot-add-mark { font-size: 20px; line-height: 1; }
.shot-add-text { font-size: 10px; letter-spacing: 2px; text-transform: uppercase; }

/* ---- Aktionsleiste ----
   Bleibt auf dem Desktop am unteren Rand stehen. Das Formular ist rund sechs
   Bildschirmhöhen lang; ohne die Leiste wäre jedes Speichern ein Scrollweg. */
.col-bar { position: sticky; bottom: 0; z-index: 6; margin-top: clamp(30px, 4vw, 48px); padding-top: 16px; background: linear-gradient(to top, var(--bg) 62%, rgba(5,5,5,0)); }
.col-bar-inner {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
  padding: 14px 18px;
  border: 1px solid var(--field-border); border-radius: var(--field-radius);
  background: rgba(16,14,11,0.94);
}
.col-bar-note { font-size: 12px; color: var(--muted); }
.col-bar-error { margin-top: 0; }
.col-bar-actions { margin-left: auto; display: flex; gap: 12px; }

/* Kollektions-Liste */
/* Die ganze Zeile ist anklickbar und oeffnet die Uhr im Formular. Der
   negative Aussenabstand zieht die Hover-Flaeche ueber die Kartenpolsterung
   hinaus, damit sie bis an den Rand reicht statt als schmaler Streifen in der
   Mitte zu stehen. */
.col-item { display: flex; align-items: flex-start; gap: 12px; padding: 14px 10px; margin: 0 -10px; border-top: 1px solid rgba(228,205,158,0.08); border-radius: 8px; cursor: pointer; transition: background .18s ease; }
.col-item:hover { background: rgba(228,205,158,0.055); }
.col-item:focus-visible { outline: 1px solid rgba(191,156,90,0.55); outline-offset: -1px; }
/* Beim Ueberfahren wird der Titel golden — das Signal, dass hier etwas passiert,
   ohne dass ein zusaetzlicher Knopf noetig waere. */
.col-item:hover .col-item-name { color: var(--gold-bright); }
.col-item:first-of-type { border-top: none; }
.col-item-name { transition: color .18s ease; }
.col-item.is-editing { outline: 1px solid rgba(191,156,90,0.4); outline-offset: 6px; border-radius: 6px; }
.col-item-thumb { width: 54px; height: 54px; flex: none; border-radius: 8px; overflow: hidden; background: rgba(0,0,0,0.3); border: 1px solid rgba(228,205,158,0.10); display: flex; align-items: center; justify-content: center; }
.col-item-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 5px; }
.col-item-thumb img.is-mark { opacity: .25; }
/* Zweizeilig: Titelzeile mit Statuspunkt, darunter Metadaten, darunter die
   Aktionen. Vorher standen alle fuenf Bloecke in EINER Flex-Zeile — fest belegt
   waren rund 383px, auf einem 1440er-Laptop blieben dem Namen ~140px, weshalb
   er per ellipsis abgeschnitten wurde. */
.col-item-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.col-item-top { display: flex; align-items: baseline; gap: 12px; }
/* Kein nowrap/ellipsis mehr: lieber zweizeilig als abgeschnitten. */
.col-item-name { flex: 1; min-width: 0; font-family: var(--font-serif), serif; font-size: 15px; line-height: 1.3; color: var(--ink); }
.col-item-meta { font-size: 11px; color: var(--muted); }
.col-item-actions { display: flex; gap: 6px; justify-content: flex-end; margin-top: 3px; }
/* Nur in der Verwaltungsliste: Punkt statt Pille. Als gerahmtes Abzeichen las
   sich der Status wie ein Knopf und drueckte den Titel zusammen. `.badge`
   selbst bleibt unveraendert — es traegt auch den oeffentlichen Shop. */
.col-item-badge { flex: none; gap: 6px; border: none; background: none; padding: 0; letter-spacing: 1.5px; }
.col-item-badge::before { content: ''; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.col-item-actions .is-danger:hover, .inq-actions .is-danger:hover, .ank-actions .is-danger:hover { color: #e0a0a0; border-color: rgba(224,160,160,0.5); }
.ank-actions button.is-confirm { color: #f3d1d1; border-color: rgba(224,160,160,0.7); background: rgba(224,160,160,0.14); }

/* Posteingang */
.inbox { display: flex; flex-direction: column; gap: 14px; }
.inq { border: 1px solid rgba(228,205,158,0.12); border-radius: 16px; padding: 20px 24px; background: linear-gradient(160deg, rgba(46,39,28,0.20), rgba(12,11,9,0.16)); }
.inq.is-read { opacity: .7; }
.inq-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.inq-who { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.inq-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--gold); flex: none; }
.inq-name { font-family: var(--font-serif), serif; font-size: 17px; color: var(--ink); }
.inq-email { font-size: 12px; color: var(--gold); text-decoration: none; }
.inq-email:hover { text-decoration: underline; }
.inq-date { font-size: 11px; color: var(--muted); flex: none; }
.inq-watch { font-size: 12px; color: var(--muted); margin-top: 8px; }
.inq-watch strong { color: var(--ink); font-weight: 500; }

/* Welche Uhr gemeint ist (Task 0130). Bild und Angaben stehen nebeneinander
   in einem eigenen Feld, nicht als Zeile im Text: Beim Durchsehen des
   Posteingangs sucht das Auge die Bilder, nicht die Zeilen. */
.inq-uhr { display: flex; align-items: center; gap: 12px; margin-top: 12px; padding: 10px 12px;
  /* Nur so breit wie die Angaben: Über die ganze Karte gezogen wäre das
     Feld zu drei Vierteln leer und sähe aus wie ein Eingabefeld. */
  width: fit-content; max-width: 100%; border: 1px solid rgba(228,205,158,0.10); border-radius: 12px; background: rgba(0,0,0,0.18); }
.inq-uhr-bild { width: 56px; height: 56px; flex: none; border-radius: 8px; overflow: hidden; background: rgba(0,0,0,0.3); display: flex; align-items: center; justify-content: center; }
.inq-uhr-bild img { width: 100%; height: 100%; object-fit: contain; padding: 4px; }
.inq-uhr-signet { opacity: .25; }
.inq-uhr-text { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.inq-uhr-kicker { font-size: 10px; letter-spacing: 1.6px; text-transform: uppercase; color: var(--muted); }
.inq-uhr-name { font-family: var(--font-serif), serif; font-size: 16px; line-height: 1.3; color: var(--ink); }
.inq-uhr-name a { color: inherit; text-decoration: none; }
.inq-uhr-name a:hover { color: var(--gold); text-decoration: underline; }
/* Die Referenz ist das Merkmal, das eine Submariner von der nächsten
   unterscheidet — deshalb Ziffernbreite fest, damit sie sich ablesen lässt. */
.inq-uhr-kennung { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }
.inq-msg { font-size: 14px; line-height: 1.7; color: var(--ink); margin-top: 10px; white-space: pre-wrap; }
.inq-actions { display: flex; gap: 8px; margin-top: 16px; }

.set-form { max-width: 460px; }

/* Öffentliche Galerie + Anfrage */
.gallery { display: flex; flex-direction: column; gap: 14px; }
.gallery-thumbs { display: flex; gap: 10px; flex-wrap: wrap; }

/* Hauptbild und Vorschaubilder auf einen Blick (Task 0112).
   Gemessen vorher: auf 1440×900, 1366×768, iPad und allen iPhones war KEIN
   Vorschaubild ohne Scrollen zu sehen — das 3:4-Bild war so breit wie seine
   Spalte und damit höher als der Bildschirm, darunter brachen neun
   Vorschaubilder auf zwei Zeilen um.

   Jetzt richtet sich die Breite AUCH nach der Höhe des Fensters: so breit,
   dass Bild + Vorschauzeile unter die Oberkante passen, höchstens so breit
   wie die Spalte, mindestens 220 px. Das 3:4-Format bleibt, das Bild füllt
   seine Fläche weiter vollständig. Darunter die Kachelzeile (Task 0114).

   --galerie-oben ist die gemessene Oberkante der Bildfläche ohne Scrollen
   (Kopf + Abstand), --galerie-rest die Vorschauzeile samt Abstand und Luft.
   Ändert sich der Kopf, müssen diese Werte mit. */
.gallery {
  --galerie-oben: 163px;
  --galerie-rest: 102px;
  --galerie-breite: min(100%, max(220px, calc((100vh - var(--galerie-oben) - var(--galerie-rest)) * 3 / 4)));
}
/* svh: die Höhe bei eingeblendeter Browserleiste auf dem Telefon — sonst
   rutschte die Vorschauzeile dort unter die Leiste. */
@supports (height: 100svh) {
  .gallery {
    --galerie-breite: min(100%, max(220px, calc((100svh - var(--galerie-oben) - var(--galerie-rest)) * 3 / 4)));
  }
}
.detail .detail-media { width: var(--galerie-breite); }
/* Vorschaubilder: 5 gleich grosse Kacheln, bündig unter dem Hauptbild —
   auf allen Breiten (Task 0114). Vorher stand am Desktop eine wischbare
   Zeile, deren Rand-Bilder angeschnitten waren; das sah nach Fehler aus.
   Mehr als 5 Bilder: 4 Vorschaubilder + „+N", aufgeklappt alle in Reihen
   zu 5. */
.gallery-thumbs {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 8px;
  width: var(--galerie-breite);
}
/* Nebeneinander: an den Text heranrücken statt mittig in der Spalte — sonst
   klaffte zwischen schmalerem Bild und Beschreibung eine Lücke. */
@media (min-width: 861px) { .gallery { align-items: flex-end; } }
@media (max-width: 860px) { .gallery { --galerie-oben: 140px; align-items: center; } }

/* Ab Tablet wächst die Kachelzeile mit dem Bild (Kachel ≈ Breite/5).
   Aufgelöst nach der Breite: B = (Höhe − oben − 40) · 3/4 − B/5 · 3/4
   → B = (Höhe − oben − 40) · 0,652. 40 px = Abstand + Luft. */
@media (min-width: 761px) {
  .gallery {
    --galerie-breite: min(100%, max(220px, calc((100vh - var(--galerie-oben) - 40px) * 0.652)));
  }
}

@media (max-width: 760px) {
  /* Vorschauzeile (bis ~70 px) + 14 Abstand + Luft. */
  .gallery { --galerie-oben: 183px; --galerie-rest: 100px; }

  /* Auf sehr schmalen Telefonen mindestens 280 px breit — sonst würden die
     Kacheln kleiner als eine Fingerkuppe (iPhone SE: 40 statt 51 px). */
  .gallery-thumbs {
    gap: 6px;
    width: max(var(--galerie-breite), min(100%, 280px));
  }
}
/* Doppelte Klasse mit Absicht: Die feste Grösse `.gallery-thumb` (68 px)
   steht weiter unten im Stylesheet und gewann sonst — die Kacheln blieben
   68 px und liefen über die Zeile hinaus. */
.gallery-thumbs .gallery-thumb,
.gallery-thumbs .gallery-mehr {
  width: auto;
  height: auto;
  aspect-ratio: 1;
}
.gallery-mehr { display: none; }
.gallery-thumbs.hat-mehr:not(.ist-offen) .gallery-thumb:nth-child(n+5) { display: none; }
.gallery-thumbs.hat-mehr:not(.ist-offen) .gallery-mehr { display: block; }
.gallery-mehr {
  position: relative;
  padding: 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid rgba(228, 205, 158, 0.16);
  background: rgba(0, 0, 0, 0.3);
  cursor: pointer;
}
.gallery-mehr img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Das nächste Bild abgedunkelt dahinter, die Zahl darüber — man sieht,
   dass dahinter mehr kommt, und wie viel. */
.gallery-mehr span {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(5, 5, 5, 0.62);
  color: var(--ink);
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0.5px;
}
.gallery-mehr:hover span { background: rgba(5, 5, 5, 0.45); }
.gallery-mehr:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }
.gallery-thumb { width: 68px; height: 68px; border-radius: 10px; overflow: hidden; border: 1px solid rgba(228,205,158,0.16); background: rgba(0,0,0,0.3); cursor: pointer; padding: 0; transition: border-color .3s ease; }
.gallery-thumb img { width: 100%; height: 100%; object-fit: contain; padding: 6px; }
/* Fotos füllen ihr Vorschauquadrat (Task 0110) — mit Innenabstand standen sie
   klein zwischen dunklen Streifen. Freigestellte Uhren bleiben ganz sichtbar. */
.gallery-thumb[data-foto="1"] img { object-fit: cover; padding: 0; }
.gallery-thumb.is-active { border-color: var(--gold); }
.card-badge { position: absolute; top: 14px; left: 14px; z-index: 2; }
.detail-badge { margin-bottom: 18px; }

.iq { margin-top: 34px; padding-top: 26px; border-top: 1px solid rgba(228,205,158,0.12); display: flex; flex-direction: column; gap: 12px; }
.iq-title { font-size: 12px; letter-spacing: 4px; text-transform: uppercase; color: var(--gold); }
.iq-row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.iq input, .iq textarea {
  font-family: var(--font-sans), sans-serif; font-size: 14px; color: var(--ink);
  background: rgba(0,0,0,0.30); border: 1px solid rgba(228,205,158,0.16); border-radius: 10px; padding: 12px 14px; resize: vertical;
}
.iq input:focus, .iq textarea:focus { outline: none; border-color: rgba(227,200,143,0.6); }
.iq input::placeholder, .iq textarea::placeholder { color: rgba(240,232,216,0.32); }
/* Wird an zwei Stellen benutzt: „Unverbindlich anfragen" auf /ankauf und
   „Anfrage senden" auf der Uhrenseite. Änderungen wirken auf beide — gewollt,
   sonst laufen die zwei Formulare optisch auseinander.
   Die Sperrung war mit 4px so weit, dass die Beschriftung gesperrt statt
   gesetzt wirkte; 2.5px trägt die Marke, ohne zu zerfallen. Statt `all` nur die
   Eigenschaften, die sich wirklich ändern — `all` animiert sonst auch
   Rahmenbreite und Innenabstand mit. */
.iq-err { font-size: 12px; color: #e0a0a0; }
.iq-done { margin-top: 34px; padding-top: 26px; border-top: 1px solid rgba(228,205,158,0.12); font-size: 14px; color: var(--gold-bright); }

@media (max-width: 900px) {
  .ap { flex-direction: column; }
  /* Sidebar wird zur Kopfzeile: Logo + Aktionen oben, Nav als eigene,
     geordnete Reihe darunter — statt frei umbrechendem Flex-Wirrwarr. */
  .ap-side {
    position: static; width: 100%; height: auto;
    display: flex; flex-direction: row; flex-wrap: wrap; align-items: center;
    gap: 10px 16px; padding: 16px 18px 14px;
  }
  .ap-brand { order: 1; flex: 1; padding: 0; }
  .ap-brand img { height: 32px; }
  .ap-side-foot {
    order: 2; flex-direction: row; align-items: center; gap: 16px;
    padding-top: 0; border-top: none;
  }
  .ap-nav {
    order: 3; flex-basis: 100%;
    display: flex; flex-direction: row; flex-wrap: nowrap; gap: 6px;
    overflow-x: auto; -webkit-overflow-scrolling: touch;
    margin: 0 -18px; padding: 0 18px 4px;
    scrollbar-width: none;
  }
  .ap-nav::-webkit-scrollbar { display: none; }
  .ap-nav-item {
    flex: none; padding: 9px 15px; font-size: 12px;
    border: 1px solid rgba(228,205,158,0.14); border-radius: 20px; gap: 6px;
  }
  .ap-nav-item.is-active { box-shadow: none; border-color: rgba(227,200,143,0.5); }
  .ap-page { padding: 20px 18px 40px; }
  .dash-grid { grid-template-columns: minmax(0, 1fr); }
  .ap-row, .iq-row { grid-template-columns: minmax(0, 1fr); }

  /* Kollektion: Titelbild und echte Aufnahmen untereinander. Die Trennlinie
     wandert dabei von links nach oben — sie darf nicht verschwinden, sie ist
     der sichtbare Unterschied zwischen den beiden Bildarten. */
  .col-media { grid-template-columns: minmax(0, 1fr); }
  .col-media-side {
    border-left: none; padding-left: 0;
    border-top: 1px solid rgba(228,205,158,0.09);
    padding-top: clamp(24px, 4vw, 34px);
  }
  .col-head-actions { flex: 1; justify-content: space-between; }
  /* „Neue Uhr anlegen" und „Zurück zur Kollektion" sind rund 250px breit —
     neben einer Überschrift passt das auf 375px nicht mehr nebeneinander, und
     ohne Umbruch schob der Knopf die ganze Seite waagerecht auf. */
  .col-view .ap-head { flex-wrap: wrap; }
  /* Statt sticky: Eine eingeblendete Leiste verdeckt auf dem Telefon die
     halbe Tastatur, sobald ein Feld den Fokus hat. */
  .col-bar { position: static; background: none; padding-top: 0; }

  /* Die Umsortierung von früher entfällt: .col-item-body stapelt Titel,
     Metadaten und Aktionen ohnehin untereinander. Auf schmalen Geräten darf
     nur noch die Titelzeile umbrechen, damit der Statuspunkt nicht den Namen
     zusammendrückt. */
  .col-item-top { flex-wrap: wrap; row-gap: 4px; }

  /* Anfragen-Kopf: bei langem Namen/E-Mail rutscht das Datum in eine eigene
     Zeile, statt am rechten Rand abgeschnitten zu werden. */
  .inq-head { flex-wrap: wrap; }
  .inq-date { flex-basis: 100%; }

  /* Das Uhrenfeld bleibt zweispaltig — Bild und Angaben nebeneinander lesen
     sich auf dem Telefon schneller als gestapelt. Nur das Bild wird kleiner,
     damit die Bezeichnung auf 390px nicht auf drei Zeilen bricht. */
  .inq-uhr { padding: 9px 10px; gap: 10px; }
  .inq-uhr-bild { width: 46px; height: 46px; }
  .inq-uhr-name { font-size: 15px; }
}

@media (max-width: 560px) {
  /* Zwei Spalten statt „so viele wie passen": Bei 390px stünden sonst drei
     Kacheln von 100px nebeneinander, und die Aktion in der Ecke wäre mit dem
     Finger nicht mehr sicher zu treffen. */
  .shots-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Das Kachelmenue haengt sonst rechts an der Kachel und ragt 186px nach
     links — bei zwei Spalten auf 390px also aus der Seite heraus. Hier ist
     es genau so breit wie seine Kachel; „Als Titelbild verwenden" bricht um. */
  .shot-menu { left: 0; right: 0; top: 36px; min-width: 0; }
  .col-bar-inner { flex-direction: column; align-items: stretch; }
  .col-bar-actions { margin-left: 0; }
  .col-bar-actions .ap-btn, .col-bar-actions .ap-btn-ghost { flex: 1; }
  .col-head-actions { flex-wrap: wrap; gap: 12px; }
}

@media (max-width: 420px) {
  .ap-side-foot { gap: 12px; }
  .ap-side-link { padding: 6px 0; }
}

/* Ruhig heisst hier: gar nicht. Ein Spinner, der sich nicht dreht, ist immer
   noch ein Zeichen dafuer, dass etwas laeuft — die Meldung daneben sagt es. */
@media (prefers-reduced-motion: reduce) {
  .col-view, .shot.is-neu { animation: none; }
  .hero-tuer, body.locked .hero-tuer { opacity: 1; transform: none; transition: none; }
  .cover-ring-wert { transition: none; }
  .cover-img, .cover-roh { transition: none; }
  /* Die Enthuellung entfaellt; das Bild ist trotzdem da. */
  .cover-stage.ist-enthuellt .cover-img { animation: none; }
  .cover-stage.ist-enthuellt::after { animation: none; opacity: 0; }
  .shot-bar::after { animation: none; width: 100%; opacity: 0.45; }
}

/* ---------- Footer (Shop-Seiten) ---------- */
.site-footer {
  max-width: 1180px;
  margin: clamp(48px, 8vw, 96px) auto 0;
  padding: 22px 0 4px;
  border-top: 1px solid rgba(228, 205, 158, 0.10);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.site-footer-brand {
  font-size: 10px;
  letter-spacing: 2px;
  color: var(--muted);
}
.site-footer-links {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
}
/* flex-basis:100% zwingt den Hinweis in eine eigene Zeile unter Marke und
   Links — der Fuß ist ein Flex-Container mit space-between. */
.site-footer-note {
  flex-basis: 100%;
  margin: 12px 0 0;
  max-width: 760px;
  font-size: 9.5px;
  line-height: 1.75;
  letter-spacing: 0.5px;
  color: rgba(240, 232, 216, 0.42);
}
.site-footer-links a {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
  text-decoration: none;
  transition: color 0.3s ease;
}
.site-footer-links a:hover {
  color: var(--gold-bright);
}

/* „Vertrag widerrufen" sieht aus wie die uebrigen Fusszeilen-Links
   (Entscheidung des Auftraggebers, 01.10.2026). Bis dahin stand er in Gold
   und unterstrichen, weil § 356a Abs. 1 BGB die Widerrufsfunktion
   „hervorgehoben platziert" verlangt.

   ⚠ Die Pflicht greift, sobald online verkauft wird. Vor dem Livegang des
   Kaufs (Task 0029) muss hier wieder eine Hervorhebung stehen — die Klasse
   `.site-footer-widerruf` haengt dafuer weiter am Link. */

/* Footer auf der Startseite: liegt im normalen Fluss UNTER dem Scroll-Raum
   der Video-Bühne. Eigener Grund + z-index, weil .stage fixiert ist und sonst
   durchscheinen würde. */
/* Alles unterhalb der Video-Bühne. z-index 20 liegt über den fixierten
   Kapiteln (.vch, z-index 10) — vorher schwebte deren Text über dem Footer,
   weil dieser nur auf z-index 3 lag. Bewusst OHNE eigenen Hintergrund: Der
   Schleier in .home-veil braucht die Durchsicht auf die Bühne. */
.home-below {
  position: relative;
  z-index: 20;
}

/* Die weiche Übergabe vom Video in die Kollektion.
   Der Verlauf schiebt sich beim Scrollen über die fixierte Bühne UND über
   das Finale-Kapitel und dunkelt beide gleichzeitig zur Kollektion hin ab.
   Reines Layout — deshalb bildgenau, ohne Scroll-Rechnerei und ohne Ruckeln.

   Nicht über den Scroll-Fortschritt in VideoHero gelöst: p erreicht dort 1
   exakt dann, wenn die Kollektion erst zu erscheinen beginnt. Für die
   Überblendung stünde kein Fortschritt mehr zur Verfügung, ohne den
   Scroll-Raum zu verlängern und die Kapitel-Choreografie neu zu kalibrieren.

   pointer-events: none, damit der Abwärts-Hinweis im Finale darunter
   anklickbar bleibt. */
.home-veil {
  height: 55vh;
  background: linear-gradient(
    to bottom,
    rgba(5, 5, 5, 0) 0%,
    rgba(5, 5, 5, 0.55) 42%,
    rgba(5, 5, 5, 0.88) 72%,
    var(--bg) 100%
  );
  pointer-events: none;
}
.home-footer {
  background: var(--bg);
  padding: 0 clamp(20px, 5vw, 56px) clamp(28px, 5vw, 48px);
}
.home-footer .site-footer {
  margin-top: 0;
}

/* ---------- Rechtstexte (Impressum / Datenschutz / AGB) ---------- */
.legal {
  min-height: 100vh;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(191, 156, 90, 0.10), transparent 60%),
    var(--bg);
  padding: 0 clamp(20px, 6vw, 96px) 96px;
}
.legal-body {
  max-width: 720px;
  margin: 0 auto;
  padding: clamp(48px, 8vw, 80px) 0 0;
}
.legal-kicker {
  font-size: 11px;
  letter-spacing: 6px;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 18px;
}
.legal-title {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: clamp(32px, 5vw, 48px);
  color: var(--ink);
  margin-bottom: clamp(32px, 5vw, 48px);
}
.legal-body h2 {
  font-family: var(--font-serif), serif;
  font-weight: 400;
  font-size: 21px;
  color: var(--ink);
  margin: 40px 0 14px;
}
.legal-body h2:first-of-type {
  margin-top: 0;
}
.legal-body p {
  font-size: 14px;
  line-height: 1.9;
  color: var(--muted);
  margin-bottom: 10px;
}
.legal-body a {
  color: var(--gold-bright);
}
/* Ein Knopf bleibt ein Knopf. Die Regel darüber färbte auch `.iq-btn` golden
   — goldene Schrift auf goldenem Grund, auf /widerruf („Vertrag widerrufen",
   § 356a BGB verlangt „gut lesbar") ebenso wie auf der Dankeseite. */
.legal-body a.iq-btn,
.legal-body a.iq-btn:hover {
  color: #0a0a0a;
}
/* Aufzählungen in den Rechtstexten. Bisher trug nur § 4 der AGB eine Liste und
   lief auf den Vorgaben des Browsers; seit der Überarbeitung vom 25.08.2026
   stehen dort der Bestellablauf (nummeriert) und die möglichen Abweichungen
   (Punkte). Beide brauchen denselben Zeilenfall wie der Fliesstext daneben —
   sonst sitzt der wichtigste Teil der AGB enger als der Rest. */
.legal-body ul,
.legal-body ol {
  margin: 0 0 10px;
  padding-left: 22px;
  font-size: 14px;
  line-height: 1.9;
  color: var(--muted);
}
.legal-body li {
  margin-bottom: 6px;
}
.legal-placeholder {
  color: var(--gold-bright);
  font-style: italic;
}
.legal-note {
  margin-top: 48px;
  padding: 16px 20px;
  border: 1px dashed rgba(228, 205, 158, 0.3);
  border-radius: 10px;
  font-size: 12.5px;
  line-height: 1.8;
  color: var(--muted);
}

/* ==========================================================================
   Ergänzungen der PHP-Fassung
   ==========================================================================
   Zwei Regeln, die es vorher nicht brauchte, weil React sie als Inline-Style
   gesetzt hat, plus das versteckte Honeypot-Feld des Anfrageformulars.
   -------------------------------------------------------------------------- */

/* Das hidden-Attribut muss gewinnen.
   In der React-Fassung wurden ein- und ausblendbare Teile gar nicht erst
   gerendert. Hier stehen sie im Markup und werden über `hidden` geschaltet —
   und dessen display:none aus dem Browser-Standard verliert gegen jede
   eigene display-Regel (.iq { display: flex } etc.). Ohne diese Zeile bliebe
   z. B. das abgeschickte Anfrageformular neben der Dankesmeldung stehen. */
[hidden] {
  display: none !important;
}

/* Scroll-Raum des Video-Heros: 14 Bildschirmhöhen. Steuert die gesamte
   Kapitel-Choreografie — wer hier etwas ändert, verschiebt jede data-from/
   data-to-Marke im Markup mit. */
.hero-scrollspace {
  height: 1197vh;
}

/* Honeypot: für Menschen unsichtbar, für Bots ein normales Textfeld.
   Bewusst nicht display:none — manche Bots überspringen versteckte Felder. */
.iq-hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   Kopfzeile der Verwaltung: Burger links, Glocke und Profil rechts.
   ═══════════════════════════════════════════════════════════════════════ */

.ap-top {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 14px clamp(18px, 4vw, 48px);
  border-bottom: 1px solid rgba(228,205,158,0.08);
  background: rgba(10,10,10,0.55);
  position: sticky; top: 0; z-index: 40;
  backdrop-filter: blur(10px);
}
.ap-top-right { display: flex; align-items: center; gap: 8px; margin-left: auto; }

/* ── Burger ─────────────────────────────────────────────────────────────
   Auf breiten Bildschirmen steht die Seitenleiste ohnehin da — der Knopf
   erscheint erst unter 900px (siehe Mobil-Block weiter unten). */
.ap-burger {
  display: none;
  flex-direction: column; justify-content: center; gap: 4px;
  width: 38px; height: 38px; padding: 0 9px;
  border: 1px solid rgba(228,205,158,0.18); border-radius: 9px;
  background: none; cursor: pointer;
}
.ap-burger span {
  display: block; height: 1.5px; background: var(--ink); border-radius: 2px;
  transition: transform .25s ease, opacity .2s ease;
}
/* Aufgeklappt wird aus den drei Strichen ein Kreuz. */
.ap-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.ap-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.ap-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* ── Glocke ─────────────────────────────────────────────────────────── */
/* Ein <button>, kein <a>: Der Grund und der Rahmen des Browsers müssen
   deshalb ausdrücklich weg — sonst sitzt in der dunklen Kopfzeile ein weisses
   Kästchen, in dem die Glocke nicht mehr zu erkennen ist. */
.ap-bell {
  position: relative; display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0; border-radius: 9px;
  border: 1px solid transparent; background: none; cursor: pointer;
  color: var(--muted); font-family: inherit; text-decoration: none;
  transition: color .2s ease, background .2s ease, border-color .2s ease;
}
.ap-bell[aria-expanded="true"] { color: var(--ink); border-color: rgba(228,205,158,0.22); }
.ap-bell:hover { color: var(--ink); background: rgba(255,255,255,0.04); }
.ap-bell svg { width: 19px; height: 19px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.ap-bell-dot {
  position: absolute; top: 5px; right: 4px;
  min-width: 15px; height: 15px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; font-weight: 500; line-height: 1;
  color: #0a0a0a; background: var(--gold); border-radius: 8px;
}

/* ── Profil mit Aufklappmenü ────────────────────────────────────────── */
.ap-profile { position: relative; }
.ap-profile-btn {
  display: flex; align-items: center; gap: 9px;
  padding: 4px; border-radius: 50%;
  border: 1px solid transparent; background: none; cursor: pointer;
  color: var(--muted); font-family: inherit; font-size: 12px;
  transition: color .2s ease, background .2s ease, border-color .2s ease;
}
.ap-profile-btn:hover { color: var(--ink); background: rgba(255,255,255,0.04); }
.ap-profile-btn[aria-expanded="true"] { color: var(--ink); border-color: rgba(228,205,158,0.22); }
.ap-avatar {
  width: 28px; height: 28px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 10px; letter-spacing: .5px; color: var(--gold-bright);
  background: rgba(227,200,143,0.12); border: 1px solid rgba(228,205,158,0.28);
}

.ap-menu {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 210px; padding: 6px;
  border: 1px solid rgba(228,205,158,0.16); border-radius: 12px;
  background: #14110c; box-shadow: 0 18px 44px rgba(0,0,0,0.6);
}
.ap-menu[hidden] { display: none; }
.ap-menu-head { padding: 9px 11px 11px; border-bottom: 1px solid rgba(228,205,158,0.10); margin-bottom: 5px; }
.ap-menu-name { display: block; font-size: 12.5px; color: var(--ink); }
.ap-menu-mail { display: block; font-size: 10.5px; color: var(--muted); margin-top: 3px; word-break: break-all; }
.ap-menu-item {
  display: block; width: 100%; text-align: left;
  padding: 9px 11px; border: none; border-radius: 8px; background: none;
  font-family: inherit; font-size: 12px; color: var(--muted);
  text-decoration: none; cursor: pointer;
  transition: color .18s ease, background .18s ease;
}
.ap-menu-item:hover { color: var(--ink); background: rgba(255,255,255,0.05); }
.ap-menu-item.is-danger:hover { color: #e0a0a0; }

/* Das Profilbild füllt denselben Kreis wie die Initialen. */
.ap-avatar-bild { object-fit: cover; padding: 0; }

/* ── Die Glocke und ihre Liste ──────────────────────────────────────────
   Dasselbe Aufklappmenü wie beim Profil, nur breiter und mit einer Liste
   darin. Deshalb dieselben Klassen (.ap-menu, .ap-menu-head) plus die
   Ergänzungen hier — kein zweiter Menüstil. */
.ap-glocke { position: relative; }

.ap-menu-breit {
  min-width: 320px;
  max-width: min(360px, calc(100vw - 28px));
}
.ap-menu-head-reihe { display: flex; align-items: center; justify-content: space-between; gap: 14px; }

/* „Alle gelesen": bewusst kein Knopfstil aus der Knopffamilie — er sitzt in
   einer Menüzeile und soll dort nicht wie ein Knopf hervorstehen. */
.ap-menu-klein {
  border: none; background: none; padding: 0; cursor: pointer;
  font-family: inherit; font-size: 10.5px; letter-spacing: .3px;
  color: var(--muted); transition: color .18s ease;
}
.ap-menu-klein:hover { color: var(--gold-bright); }
.ap-menu-klein:disabled { opacity: .45; cursor: default; }

/* Die Liste bekommt eine Höhengrenze: Bei zwanzig Meldungen soll das Menü
   nicht über den halben Bildschirm laufen. */
.ap-melde-liste { max-height: 336px; overflow-y: auto; }

.ap-melde {
  display: flex; align-items: flex-start; gap: 9px;
  padding: 9px 11px; border-radius: 8px;
  text-decoration: none; color: var(--muted);
  transition: background .18s ease;
}
.ap-melde:hover { background: rgba(255,255,255,0.05); }

/* Der Punkt steht immer da und hält die Zeile ausgerichtet — sichtbar wird
   er nur bei einer ungelesenen Meldung. */
.ap-melde-punkt {
  flex: none; width: 6px; height: 6px; margin-top: 6px;
  border-radius: 50%; background: transparent;
}
.ap-melde.is-neu .ap-melde-punkt { background: var(--gold); }

.ap-melde-text { flex: 1; min-width: 0; }
.ap-melde-titel { display: block; font-size: 12px; color: var(--muted); }
.ap-melde.is-neu .ap-melde-titel { color: var(--ink); }
.ap-melde-sub {
  display: block; margin-top: 2px; font-size: 10.5px; line-height: 1.45;
  color: rgba(240,232,216,0.45);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ap-melde-zeit { flex: none; font-size: 9.5px; color: rgba(240,232,216,0.35); padding-top: 2px; }
.ap-melde-leer { padding: 14px 11px; font-size: 11.5px; color: var(--muted); }

/* ── Profilbild in den Einstellungen ────────────────────────────────── */
.set-avatar { display: flex; align-items: center; gap: 20px; flex-wrap: wrap; }
.ap-avatar-gross {
  width: 72px; height: 72px; font-size: 20px; letter-spacing: 1px;
}
.set-avatar-knoepfe { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }

/* Das Dateifeld ist optisch versteckt (.ak-datei-feld), aber weiter im
   Tabulatorweg. Der Fokusring wird deshalb auf das Label daneben gezeichnet —
   sonst läge er auf einem unsichtbaren Element. */
.ak-datei-feld:focus-visible + .set-avatar-waehlen {
  outline: 2px solid var(--gold-bright); outline-offset: 3px;
}

/* ── Verdunklung hinter der mobilen Seitenleiste ────────────────────── */
.ap-scrim { display: none; }

@media (max-width: 900px) {
  .ap-burger { display: flex; }

  /* Seitenleiste wird zum einschiebbaren Panel statt zur umbrechenden
     Kopfzeile: Sie liegt links außerhalb des Bildes und fährt auf Knopfdruck
     herein. Der Inhalt darunter bleibt dabei ruhig stehen. */
  .ap-side {
    position: fixed; top: 0; left: 0; z-index: 50;
    width: min(280px, 82vw); height: 100vh;
    flex-direction: column; flex-wrap: nowrap;
    padding: 26px 18px;
    transform: translateX(-100%);
    transition: transform .28s cubic-bezier(.2,.7,.2,1);
    border-right: 1px solid rgba(228,205,158,0.12);
    background: #100e0a;
  }
  .ap-side.is-open { transform: translateX(0); }

  .ap-brand { order: 0; flex: none; padding: 0 8px 22px; }
  .ap-nav { order: 1; flex-direction: column; flex-wrap: nowrap; overflow: visible; margin: 0; padding: 0; }
  .ap-side-foot { order: 2; flex-direction: column; align-items: stretch; padding-top: 18px; border-top: 1px solid rgba(228,205,158,0.08); }

  .ap-scrim {
    display: block; position: fixed; inset: 0; z-index: 45;
    background: rgba(0,0,0,0.55); backdrop-filter: blur(2px);
  }
  .ap-scrim[hidden] { display: none; }
}

/* Auf schmalen Geräten passt die Glockenliste nicht mehr unter ihren Knopf:
   Sie ist 320px breit, der Knopf sitzt rechts, und `right: 0` schöbe sie über
   den linken Rand hinaus — der Kopf des Menüs war dort abgeschnitten. Deshalb
   hängt sie hier nicht mehr am Knopf, sondern am Bildschirm.
   `position: fixed` ist richtig, nicht absolute: Die Kopfzeile klebt oben
   (position: sticky), das Menü soll mit ihr stehen bleiben. */
@media (max-width: 560px) {
  .ap-menu-breit {
    position: fixed; top: 64px; left: 12px; right: 12px;
    min-width: 0; max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ap-side { transition: none; }
  .ap-burger span { transition: none; }
}

/* ---------- Kopfzeile: Ankauf-Verweis neben dem Zurück-Knopf ---------- */
.shop-actions { display: flex; align-items: center; gap: 18px; }
/* Der Ankauf-Knopf trägt seit dem 06.09.2026 dieselbe Goldform wie der
   Hauptweg (.iq-btn) — auf Wunsch des Auftraggebers. Vorher war er ein
   stiller Mikro-Verweis in Grau; in der Kopfzeile über dem Film hat ihn
   praktisch niemand als Weg gelesen.

   Verlauf, Kante, Hover und Tastaturring stehen NICHT hier, sondern in den
   Selektorgruppen ganz oben — dort, wo sie für alle Knöpfe der Seite
   gemeinsam stehen. Hier steht nur, was die Kopfzeile zusätzlich verlangt:
   eine Nummer kleiner als ein Knopf im Fliesstext, denn er sitzt neben dem
   Signet und darf ihm nicht die Waage nehmen. */
.shop-ankauf {
  padding: 9px 20px;
  font-size: 10px;
  letter-spacing: 2.4px;
  /* Der Film läuft darunter durch — dieselbe weiche Streuung wie am
     Hauptweg auf der Bühne, sonst flimmert die Kante mit. */
  box-shadow: var(--knopf-kante-gold), 0 10px 26px -12px rgba(0, 0, 0, 0.9);
}
.shop-ankauf:hover {
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.45),
              0 12px 30px -12px rgba(191, 156, 90, 0.55),
              0 10px 26px -12px rgba(0, 0, 0, 0.9);
}

/* ---------- Ankauf ---------- */
/* Abstand nach oben wie `.legal-body`: Ohne ihn klebte die Überzeile auf
   Warenkorb, Kasse, Ankauf und Widerruf mit 0px an der Linie unter dem
   Kopf, während die Rechtsseiten 50–80px Luft hatten (Task 0105). */
.ak-kopf { max-width: 62ch; margin: 0 0 clamp(32px, 6vh, 64px); padding-top: clamp(48px, 8vw, 80px); }

/* Fliesstext im Kopfbereich eines Formulars. Bisher brauchte ihn nur die
   Widerrufsfunktion (§ 356a BGB): Dort steht vor dem ersten Feld, was
   passiert, wenn man den Knopf drückt. Der Ankauf führt stattdessen mit
   .ak-schritte ein. */
.ak-intro { margin: 24px 0 0; font-size: 14px; font-weight: 300; line-height: 1.7;
            color: rgba(240, 232, 216, 0.82); }

/* Der Nachsatz unter der Widerrufsfunktion. Er nutzt die Textgestaltung der
   Rechtsseiten, darf sich aber nicht wie dort zentrieren — daneben steht ein
   linksbündiges Formular. */
.widerruf-wege { margin: 0; max-width: 760px; padding-top: clamp(32px, 6vh, 64px); }

/* Die vier Schritte, nummeriert wie im Kapitel 01 der Startseite. */
.ak-schritte { list-style: none; margin: 28px 0 0; padding: 0; display: grid; gap: 12px; }
.ak-schritte li { display: flex; gap: 14px; font-size: 13px; font-weight: 300;
                  color: rgba(240, 232, 216, 0.82); }
.ak-schritte span { flex: none; width: 22px; font-size: 10px; letter-spacing: 2px;
                    color: rgba(191, 156, 90, 0.75); padding-top: 3px; }

.ak-form { max-width: 760px; display: grid; gap: clamp(28px, 5vh, 48px); }
.ak-block { border: 0; margin: 0; padding: 0; display: grid; gap: 16px; }
.ak-block legend { font-size: 10px; letter-spacing: 4px; text-transform: uppercase;
                   color: var(--gold); padding: 0 0 14px;
                   border-bottom: 1px solid rgba(228, 205, 158, 0.10); width: 100%; }

.ak-zwei { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.ak-feld { display: grid; gap: 7px; }
.ak-feld label { font-size: 11px; letter-spacing: 1.5px; text-transform: uppercase;
                 color: rgba(240, 232, 216, 0.62); }
.ak-feld label span { text-transform: none; letter-spacing: 0; opacity: 0.6; }

/* Einlauf der Formularabschnitte. Bewusst am fieldset selbst statt an jedem
   Kind: ein Formular ist Arbeitsfläche, kein Schaufenster — was beim Ausfüllen
   noch nachwackelt, ist ärgerlich. Der Abschnitt erscheint einmal, danach
   bewegt sich nichts mehr. Keyframes und Kurve sind dieselben wie bei der
   Kollektion.

   Die Startwerte hängen an .einlauf-bereit, das ERST das Skript setzt. Ohne
   diese Kopplung stünde ein Formular auf opacity:0, sobald der Beobachter aus
   irgendeinem Grund nicht feuert — beim Prüfen genau das erlebt: Chrome drosselt
   IntersectionObserver in Hintergrund-Tabs. Ein unsichtbares Formular ist ein
   Totalausfall, eine ausbleibende Animation nur ein fehlender Schnörkel. */
.ak-form.einlauf-bereit .ak-block {
  opacity: 0;
  transform: translateY(16px);
  filter: blur(5px);
  will-change: opacity, transform, filter;
}
.ak-form.einlauf-bereit .ak-block.is-in {
  animation: glIn 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) both;
}
/* .is-in ausdrücklich mitgenannt, sonst hätte die Regel darüber die höhere
   Spezifität und würde trotz reduzierter Bewegung animieren. */
@media (prefers-reduced-motion: reduce) {
  .ak-form.einlauf-bereit .ak-block,
  .ak-form.einlauf-bereit .ak-block.is-in {
    opacity: 1;
    transform: none;
    filter: none;
    animation: none;
  }
}

/* Beide Kundenformulare laufen in der Schrift der Verwaltung. Derselbe Weg wie
   dort (.ap, .login): die Variablen im Geltungsbereich überschreiben, statt
   font-family in zwanzig Einzelregeln zu setzen. Weil die Felder `font: inherit`
   tragen und die Knöpfe `var(--font-sans)`, greift das überall von selbst —
   Beschriftungen, Auswahl, Knöpfe und die Zwischenüberschriften der fieldsets.
   --font-serif wird mit umgestellt, damit kein Element in Cormorant zurückbleibt.
   Ausserhalb der Formulare ändert sich nichts: Seitenüberschrift, Uhrenname und
   Preis stehen nicht in diesen Behältern. */
.ak-form, .iq {
  --font-serif: var(--font-ui);
  --font-sans: var(--font-ui);
  font-family: var(--font-ui), sans-serif;
}
/* legend erbt die Schrift nicht in jedem Browser vom Formular. */
.ak-form legend { font-family: inherit; }

/* Felder wie im Anfrageformular der Detailseite — eine Formsprache, nicht zwei.
   Der Radius stand dort schon (.iq input: 10px), hier fehlte er — genau daran
   fiel diese Seite als eckig auf. Jetzt ziehen beide an derselben Variable. */
.ak-feld input, .ak-feld select, .ak-feld textarea {
  font: inherit; font-size: 14px; color: var(--ink);
  background-color: var(--field-bg);
  border: 1px solid var(--field-border);
  border-radius: var(--field-radius);
  padding: 12px 14px; width: 100%;
  transition:
    border-color var(--ease),
    background-color var(--ease),
    box-shadow var(--ease);
}
.ak-feld input::placeholder, .ak-feld textarea::placeholder {
  /* 0.32 (aus dem Anfrageformular übernommen) ergibt gegen die Feldfläche nur
     2.54:1 — als Text zu wenig. 0.55 liegt bei 5.30:1 und bleibt trotzdem
     deutlich zurückhaltender als der eingegebene Text (16.6:1). */
  color: rgba(240, 232, 216, 0.55);
}
.ak-feld textarea {
  /* Waagerecht ziehbar liefe das Feld aus seiner Spalte heraus. */
  resize: vertical;
  min-height: 96px;
}
/* Ohne appearance:none zeichnet das Betriebssystem seinen eigenen Pfeil — unter
   macOS blaugrau, unter Windows anders. Genau dieser Fremdkörper lässt ein
   Formular billig wirken. Das SVG steht als data-URI in der Datei: kein zweiter
   Abruf, und die Auslieferung als Artefakt erlaubt ohnehin keine fremden Hosts.
   Der rechte Innenabstand hält lange Einträge vom Pfeil fern. */
.ak-feld select {
  appearance: none;
  -webkit-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' fill='none' stroke='%23bf9c5a' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 15px center;
  padding-right: 42px;
  cursor: pointer;
}
.ak-feld input:focus, .ak-feld select:focus, .ak-feld textarea:focus {
  outline: none;
  border-color: rgba(227, 200, 143, 0.6);
  /* background-color, nicht background: Das Kurzschreiben würde das Pfeil-SVG
     der Auswahlfelder mit abräumen. */
  background-color: rgba(255, 255, 255, 0.07);
  /* Der Ring zeigt den Fokus als Form, nicht allein über den Goldton — wer
     Farben schlecht unterscheidet, erkennt ihn trotzdem. */
  box-shadow: 0 0 0 3px rgba(191, 156, 90, 0.16);
}
.ak-feld input[aria-invalid="true"], .ak-feld select[aria-invalid="true"],
.ak-feld textarea[aria-invalid="true"] { border-color: #e0a3a3; }

/* Meldung am Feld, statt einer Sammelzeile unter dem Formular — Kriterium 3. */
.ak-feld-fehler { font-size: 12px; color: #e0a3a3; margin: 0; }

.ak-radio, .ak-check { display: flex; gap: 11px; align-items: flex-start;
                       font-size: 13.5px; font-weight: 300; line-height: 1.6;
                       /* Das Label ist die Klickfläche — mit dem Innenabstand
                          kommt sie über 24 px, auch wenn der Knopf 20 px misst. */
                       padding: 3px 0; cursor: pointer; }
.ak-check a { color: var(--gold); }

/* ── Die gesonderte Vereinbarung in der Kasse (§ 476 Abs. 1 Satz 2 BGB) ────
   Sie steht als eigener Kasten zwischen den beiden gewöhnlichen Häkchen —
   und das ist der Punkt: Der Paragraph verlangt eine AUSDRÜCKLICHE und
   GESONDERTE Vereinbarung. Ein drittes Häkchen in derselben Reihe wie AGB
   und Widerrufsbelehrung wäre weder ausdrücklich noch gesondert; es sähe aus
   wie das übliche Kleingedruckte, das man wegklickt.

   Derselbe Goldstrich wie auf der Detailseite, damit der Kunde die Angabe
   wiedererkennt, die er dort schon gelesen hat. */
.kasse-abweichungen {
  padding: 18px 20px;
  border-left: 2px solid var(--gold);
  background: rgba(191, 156, 90, 0.06);
  border-radius: 0 var(--field-radius) var(--field-radius) 0;
  display: grid;
  gap: 10px;
}
.kasse-abweichungen-titel {
  margin: 0;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold-bright);
}
.kasse-abweichungen-uhr {
  margin: 0;
  font-size: 12px;
  font-weight: 300;
  color: var(--ink);
}
.kasse-abweichungen-liste {
  margin: 0;
  padding: 0 0 0 18px;
  display: grid;
  gap: 5px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ink);
}

/* Vertragssprache, Vertragstext und Berichtigung von Eingabefehlern —
   Pflichtangaben, die über dem Bestellknopf stehen müssen. Leise gesetzt,
   aber nicht versteckt. */
.kasse-pflichtangaben { margin: 0 0 4px; }
.kasse-pflichtangaben a { color: var(--gold); }

/* Auswahlknöpfe: Ohne appearance:none zeichnet sie das Betriebssystem — unter
   macOS leuchtend blau. In einer sonst durchgehend gold-schwarzen Oberfläche war
   das der auffälligste Bruch der ganzen Seite.
   Der Fokus läuft über outline, nicht über box-shadow: Letzteres trägt beim
   Radio bereits den inneren Punkt und würde ihn überschreiben. outline mit
   offset ist ausserdem das, was .collection-card und .iq-btn schon benutzen. */
.ak-radio input[type="radio"],
.ak-check input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-top: 1px;
  border: 1px solid var(--field-border);
  background-color: var(--field-bg);
  cursor: pointer;
  transition: border-color var(--ease), background-color var(--ease);
}
.ak-radio input[type="radio"] { border-radius: 50%; }
.ak-check input[type="checkbox"] { border-radius: var(--control-radius); }

.ak-radio input[type="radio"]:hover,
.ak-check input[type="checkbox"]:hover { border-color: rgba(227, 200, 143, 0.5); }

/* Der innere Ring in Hintergrundfarbe lässt die Mitte als Punkt stehen — ein
   Pseudoelement wäre auf einem input nicht verlässlich. */
.ak-radio input[type="radio"]:checked {
  border-color: var(--gold);
  background-color: var(--gold);
  box-shadow: inset 0 0 0 4px var(--bg);
}
.ak-check input[type="checkbox"]:checked {
  border-color: var(--gold);
  background-color: var(--gold);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='10' viewBox='0 0 12 10'%3E%3Cpath d='M1 5L4.5 8.5L11 1.5' fill='none' stroke='%23050505' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}

.ak-radio input[type="radio"]:focus-visible,
.ak-check input[type="checkbox"]:focus-visible {
  outline: 2px solid var(--gold-bright);
  outline-offset: 3px;
}
.ak-hinweis { font-size: 12.5px; font-weight: 300; line-height: 1.7;
              color: rgba(240, 232, 216, 0.62); margin: 0; }

/* Das Dateifeld ist nur optisch weg, nicht aus der Bedienung: `display:none`
   oder `hidden` nähme es aus der Tabulatorfolge, und die Fläche wäre für
   Tastaturnutzer nicht mehr erreichbar. Ein Bildpunkt Grösse mit clip-path
   statt width:0 — sonst überspringen manche Browser das Feld doch. */
.ak-datei-feld { position: absolute; width: 1px; height: 1px;
                 padding: 0; margin: -1px; border: 0; overflow: hidden;
                 clip-path: inset(50%); white-space: nowrap; }

/* ---- Ablagefläche für die Fotos ----
   Ein <label>, keine <div>: So öffnet der Klick den Dateidialog ohne eine
   Zeile JavaScript, und das Ziehen ist eine Zugabe statt die Voraussetzung.
   Der gestrichelte Rand liegt als background-image an, nicht als
   border-style: dashed — damit lässt sich die Strichlänge festlegen, und die
   Fläche springt beim Wechsel auf den durchgezogenen Rand nicht um einen
   Bildpunkt. */
.ak-drop {
  --ak-drop-strich: rgba(228, 205, 158, 0.3);
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 7px;
  padding: 34px 24px;
  border-radius: var(--button-radius);
  background-color: var(--field-bg);
  background-image: repeating-linear-gradient(0deg,   var(--ak-drop-strich) 0 7px, transparent 7px 15px),
                    repeating-linear-gradient(90deg,  var(--ak-drop-strich) 0 7px, transparent 7px 15px),
                    repeating-linear-gradient(180deg, var(--ak-drop-strich) 0 7px, transparent 7px 15px),
                    repeating-linear-gradient(270deg, var(--ak-drop-strich) 0 7px, transparent 7px 15px);
  background-size: 1px 100%, 100% 1px, 1px 100%, 100% 1px;
  background-position: 0 0, 0 0, 100% 0, 0 100%;
  background-repeat: no-repeat;
  text-align: center;
  cursor: pointer;
  transition: background-color var(--ease), transform var(--ease);
}
.ak-drop:hover { --ak-drop-strich: rgba(228, 205, 158, 0.5);
                 background-color: rgba(255, 255, 255, 0.055); }
.ak-datei-feld:focus-visible + .ak-drop {
  outline: 2px solid var(--gold-bright); outline-offset: 3px;
}
.ak-drop-zeichen { width: 26px; height: 26px; color: var(--gold);
                   transition: transform var(--ease), color var(--ease); }
.ak-drop-titel { font-size: 14px; color: var(--ink); }
.ak-drop-sub { font-size: 12.5px; color: var(--muted); line-height: 1.5; }
/* Sieht aus wie ein Verweis, ist aber Teil des Labels — ein echtes <a> darin
   würde den Dateidialog abfangen. */
.ak-drop-link { color: var(--gold-bright); text-decoration: underline;
                text-underline-offset: 3px; }

/* Beschriftung nach Eingabeart: Am Telefon gibt es kein Ziehen, dort wäre
   „hierher ziehen" eine Anweisung ins Leere. `pointer: coarse` zusammen mit
   `hover: none` trifft Finger-Bedienung und lässt Zeigergeräte mit
   Tastbildschirm in Ruhe. */
.ak-nur-tippen { display: none; }
@media (hover: none) and (pointer: coarse) {
  .ak-nur-zeiger { display: none; }
  .ak-nur-tippen { display: inline; }
}

/* Sobald irgendwo im Fenster eine Datei gezogen wird, hebt sich die Fläche
   leise hervor. Ohne diesen Hinweis zielt man auf gut Glück. */
.ak-form.ak-zieht .ak-drop { --ak-drop-strich: rgba(228, 205, 158, 0.55);
                             background-color: rgba(255, 255, 255, 0.06); }
/* Und direkt darüber deutlich: hier trifft es. */
.ak-drop.ist-ziel {
  --ak-drop-strich: transparent;
  background-color: rgba(191, 156, 90, 0.14);
  box-shadow: inset 0 0 0 1px var(--gold), 0 0 0 4px rgba(191, 156, 90, 0.14);
  transform: scale(1.006);
}
.ak-drop.ist-ziel .ak-drop-zeichen { color: var(--gold-bright); transform: translateY(-3px); }

.ak-drop-stand { margin: 10px 0 0; font-size: 12px; color: var(--muted); }
/* Die Fläche ist voll — sie bleibt sichtbar, nimmt aber nichts mehr an. */
.ak-drop.ist-voll { opacity: 0.45; pointer-events: none; }

@media (prefers-reduced-motion: reduce) {
  .ak-drop, .ak-drop-zeichen { transition: none; }
  .ak-drop.ist-ziel { transform: none; }
  .ak-drop.ist-ziel .ak-drop-zeichen { transform: none; }
}

.ak-vorschau { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.ak-kachel { position: relative; aspect-ratio: 1; overflow: hidden;
             background-color: var(--field-bg);
             border: 1px solid var(--field-border);
             border-radius: var(--field-radius);
             display: grid; place-items: center; }
.ak-kachel img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Das Bild steht sofort da — noch bevor der Server es bestätigt hat. Ein
   Schleier mit laufendem Ring sagt „unterwegs"; vorher stand hier nur ein
   Auslassungszeichen auf leerer Fläche, und man sah nicht, welches Bild
   gerade hochgeht. */
.ak-kachel.is-laedt img { opacity: 0.4; filter: saturate(0.6); }
.ak-kachel.is-laedt::after {
  content: '';
  position: absolute;
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 1.5px solid rgba(240, 232, 216, 0.25);
  border-top-color: var(--gold-bright);
  animation: akDreht 0.7s linear infinite;
}
@keyframes akDreht { to { transform: rotate(360deg); } }
/* Neue Kacheln legen sich ruhig an ihren Platz, statt zu erscheinen. */
.ak-kachel { animation: akKachelRein 0.32s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
@keyframes akKachelRein {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) {
  .ak-kachel { animation: none; }
  .ak-kachel.is-laedt::after { animation-duration: 2s; }
}
.ak-weg { position: absolute; top: 5px; right: 5px; width: 26px; height: 26px;
          font: inherit; font-size: 15px; line-height: 1; color: var(--ink);
          background-color: rgba(0, 0, 0, 0.72); border: 0; border-radius: 50%;
          cursor: pointer; transition: background-color var(--ease); }
.ak-weg:hover { background-color: rgba(0, 0, 0, 0.9); }
.ak-weg:focus-visible { outline: 2px solid var(--gold-bright); outline-offset: 2px; }

.ak-fehler { font-size: 13px; color: #e0a3a3; margin: 0; }

@media (max-width: 760px) {
  .ak-zwei { grid-template-columns: 1fr; }
  .ak-vorschau { grid-template-columns: repeat(3, 1fr); }
  .shop-actions { gap: 12px; }
  .shop-ankauf { padding: 8px 15px; letter-spacing: 1.6px; }
}

/* Auf schmalen Telefonen reicht die Zeile nicht für Marke, „Ankauf" und den
   Zurück-Knopf nebeneinander (besonders bei „Zur Kollektion" — länger als
   „Zurück"). Statt den Verweis auszublenden, rutscht die Aktionsleiste in
   eine eigene Zeile unter die Marke. */
@media (max-width: 480px) {
  .shop-head { flex-wrap: wrap; row-gap: 12px; }
  .shop-actions { flex-basis: 100%; justify-content: flex-end; }
}

/* ---------- Verwaltung: Ankauf ---------- */
.filter-leiste { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 22px; }

.ank-empty-filter { margin-bottom: 22px; }

.ank-list { display: flex; flex-direction: column; gap: 16px; }
.ank-card {
  border: 1px solid rgba(228,205,158,0.12); border-radius: 16px; padding: 22px 24px;
  background: linear-gradient(160deg, rgba(46,39,28,0.20), rgba(12,11,9,0.16));
}
.ank-card-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ank-card-head-main { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.ank-nummer { font-family: var(--font-serif), serif; font-size: 17px; color: var(--ink); }
.ank-alter { font-size: 11px; color: var(--muted); }

.ank-card-body { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-top: 16px; }
.ank-block-title { font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--gold); margin-bottom: 6px; }
.ank-block-main { font-family: var(--font-serif), serif; font-size: 16px; color: var(--ink); }
.ank-meta { list-style: none; display: flex; flex-direction: column; gap: 3px; margin-top: 6px; font-size: 12px; color: var(--muted); }
.ank-meta a { color: var(--gold); text-decoration: none; }
.ank-meta a:hover { text-decoration: underline; }
.ank-preis { font-size: 13px; color: var(--muted); margin-top: 8px; }
.ank-preis strong { color: var(--ink); font-weight: 500; }
.ank-nachricht {
  font-size: 13px; line-height: 1.7; color: var(--ink); margin-top: 10px; white-space: pre-wrap;
  /* Eine ausfuehrliche Kundennachricht darf die Karte nicht auf 1000 px
     aufblaehen — Status, Angebot und Knoepfe muessen im Blick bleiben. */
  max-height: 14em;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.ank-fotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(84px, 1fr)); gap: 8px; margin-top: 18px; }
.ank-fotos img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 8px; border: 1px solid rgba(228,205,158,0.14); background: rgba(0,0,0,0.3); }
/* Die Kachel ist ein Link aufs Original (Task 0133). Der Zeiger sagt, dass
   sich hier etwas oeffnet; der Rahmen hellt sich auf wie bei den Meta-Links. */
.ank-foto { display: block; cursor: zoom-in; border-radius: 8px; outline-offset: 2px; }
.ank-foto img { display: block; transition: border-color 0.2s ease, transform 0.2s ease; }
.ank-foto:hover img, .ank-foto:focus-visible img { border-color: var(--gold); transform: scale(1.03); }

/* Grossansicht: ein natives <dialog>, bildschirmfuellend, nichts als das
   Foto auf Schwarz. Die Knoepfe schweben darueber und sind so gross, dass
   man sie auf dem Telefon trifft. */
.ank-gross {
  position: fixed; inset: 0; width: 100vw; height: 100vh; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; background: rgba(0,0,0,0.94); color: var(--ink);
  display: none; align-items: center; justify-content: center;
}
.ank-gross[open] { display: flex; }
.ank-gross::backdrop { background: transparent; }
.ank-gross-bild {
  max-width: calc(100vw - 32px); max-height: calc(100vh - 32px);
  width: auto; height: auto; object-fit: contain; border-radius: 4px;
  box-shadow: 0 30px 80px rgba(0,0,0,0.6);
}
.ank-gross-knopf {
  position: absolute; display: grid; place-items: center; width: 48px; height: 48px;
  border-radius: 50%; border: 1px solid rgba(228,205,158,0.22); background: rgba(0,0,0,0.55);
  color: var(--ink); cursor: pointer; transition: border-color 0.2s ease, background 0.2s ease;
}
.ank-gross-knopf svg { width: 22px; height: 22px; }
.ank-gross-knopf:hover, .ank-gross-knopf:focus-visible { border-color: var(--gold); background: rgba(0,0,0,0.8); }
.ank-gross-zu { top: 18px; right: 18px; }
.ank-gross-zurueck { left: 18px; top: 50%; transform: translateY(-50%); }
.ank-gross-vor { right: 18px; top: 50%; transform: translateY(-50%); }
.ank-gross.is-einzeln .ank-gross-zurueck, .ank-gross.is-einzeln .ank-gross-vor { display: none; }
.ank-gross-zahl {
  position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%);
  font-size: 12px; letter-spacing: 2px; color: var(--muted); margin: 0;
}

.ank-fields { display: grid; grid-template-columns: 1fr 1fr 2fr; gap: 16px; margin-top: 20px; }
.ank-fields .ap-field { margin-top: 0; }
.ank-field-wide textarea { min-height: 44px; }

.ank-save-hint { font-size: 11px; color: var(--muted); margin-top: 8px; min-height: 14px; }
.ank-save-hint.is-error { color: #e0a0a0; }

.ank-composer { margin-top: 18px; padding-top: 18px; border-top: 1px dashed rgba(228,205,158,0.16); }
.ank-composer-title { font-size: 12px; color: var(--muted); margin-bottom: 10px; }
.ank-composer-text {
  width: 100%; min-height: 160px; font-family: var(--font-sans), sans-serif; font-size: 14px; color: var(--ink);
  background: rgba(0,0,0,0.30); border: 1px solid rgba(228,205,158,0.16); border-radius: 10px;
  padding: 12px 14px; resize: vertical;
}
.ank-composer-text:focus { outline: none; border-color: rgba(227,200,143,0.6); }

.ank-actions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }

@media (max-width: 860px) {
  .ank-card-body, .ank-fields { grid-template-columns: minmax(0, 1fr); }
}

/* ═══════════════════════════════════════════════════════ Onlinekauf
 *
 * Das Kaufformular übernimmt die Formsprache des Ankaufs (.ak-*) — dieselben
 * Felder, dieselben Häkchen, derselbe Knopf. Neu sind nur die Aufstellung der
 * Beträge und der Kaufknopf auf der Detailseite.
 */

/* Beträge: Bezeichnung links, Betrag rechts, Ziffern untereinander. */
.ak-summe { margin: 0 0 18px; display: grid; gap: 10px; }

.ak-summe > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 18px;
}

.ak-summe dt { color: var(--muted); }

.ak-summe dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Die Gesamtsumme ist die Zahl, auf die es ankommt — abgesetzt, nicht bunt. */
.ak-summe-gesamt {
  border-top: 1px solid var(--field-border);
  padding-top: 10px;
  font-size: 1.08rem;
}

.ak-summe-gesamt dt { color: var(--ink); }
.ak-summe-gesamt dd { color: var(--gold-bright); }

/* Kaufknopf auf der Detailseite. Steht über dem Anfrageformular und ist ein
   Link, kein Knopf: Er führt auf eine eigene Seite, er sendet nichts. */
.detail-kaufen {
  display: block;
  width: 100%;
  margin: 22px 0 8px;
  text-align: center;
  text-decoration: none;
}

.detail-kaufhinweis {
  margin: 0 0 26px;
  font-size: .84rem;
  line-height: 1.6;
  color: var(--muted);
}

/* Der Datenschutzhinweis unter den Absenden-Knöpfen (Task 0075).
   Leise wie ein Beipackzettel — er informiert, er wirbt nicht. Der Verweis
   trägt Gold statt des Browser-Blaus: Ohne diese Regel stand mitten im
   dunklen Formular ein hellblauer Link, und genau das fiel beim ersten Blick
   in den Browser auf. */
.datenschutz-hinweis {
  margin: 14px 0 0;
  max-width: 46ch;
  font-size: 12px;
  font-weight: 300;
  line-height: 1.65;
  color: rgba(240, 232, 216, 0.52);
}
.datenschutz-hinweis a {
  color: var(--gold);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.datenschutz-hinweis a:hover { color: var(--ink); }

/* ═══════════════════════════════════════════ Bestellungen (Verwaltung)
 *
 * Karten wie beim Ankauf. Die Liste wird vom Skript gefüllt, deshalb steht
 * hier nur, wie die Bausteine aussehen — nicht, wie viele es sind.
 */

.ap-liste { display: grid; gap: 16px; }

.ap-karte {
  border: 1px solid var(--field-border);
  background: var(--field-bg);
  padding: 18px 20px;
  display: grid;
  gap: 14px;
}

.ap-karte-kopf {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
}

.ap-karte-titel { margin: 0; font-size: 1.05rem; }

/* Status als Wort, nicht nur als Farbe: Farbe allein ist für einen Teil der
   Menschen keine Information. */
.ap-status {
  font-size: .74rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  padding: 3px 10px;
  border: 1px solid var(--field-border);
  white-space: nowrap;
}

.ap-status--bezahlt     { color: var(--gold-bright); border-color: var(--gold); }
.ap-status--versandt    { color: #7fc08f; }
.ap-status--offen       { color: var(--muted); }
.ap-status--angenommen  { color: var(--gold-bright); }
.ap-status--abgebrochen { color: var(--muted); }
.ap-status--erstattet   { color: #d99b83; }

/* Das Raster liegt auf der LISTE, nicht auf der einzelnen Zeile.
   Vorher war jede Zeile ihr eigenes Raster — `max-content` galt damit je
   Zeile, und lange Beschriftungen („Bestätigung verschickt", „Widerruf zur
   Kenntnis") schoben ihren Wert aus der Spalte der übrigen. So teilen sich
   alle Zeilen eine Beschriftungsspalte. */
.ap-daten {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(9rem, max-content) 1fr;
  gap: 4px 16px;
  align-items: baseline;
}

.ap-daten-zeile { display: contents; }

.ap-daten-zeile dt {
  font-size: .72rem;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
}

.ap-daten-zeile dd { margin: 0; word-break: break-word; }

.ap-versand, .ap-notiz {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
  padding-top: 12px;
  border-top: 1px solid var(--field-border);
}

.ap-versand .ap-field, .ap-notiz .ap-field { flex: 1 1 16rem; margin-top: 0; }

@media (max-width: 34rem) {
  /* Auf dem Telefon steht die Beschriftung über dem Wert: eine Spalte,
     `display: contents` lässt dt und dd von selbst untereinander fallen. */
  .ap-daten { grid-template-columns: 1fr; gap: 0; }
  .ap-daten-zeile dd { padding-bottom: 8px; }
}

/* Muster-Widerrufsformular: bewusst als vorformatierter Text. Es ist ein
   Formular zum Ausdrucken oder Kopieren, kein Fließtext — die Leerzeilen und
   Punktlinien tragen die Bedeutung. */
.legal-formular {
  white-space: pre-wrap;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: .86rem;
  line-height: 1.7;
  background: var(--field-bg);
  border: 1px solid var(--field-border);
  padding: 20px 22px;
  margin: 0 0 24px;
}

.legal-stand {
  margin-top: 34px;
  font-size: .82rem;
  color: var(--muted);
}

/* Steuerhinweis auf der Detailseite. Steht VOR dem Kaufknopf — ein Hinweis,
   den man erst hinter einer Schaltfläche findet, genügt nach der Rechtsprechung
   nicht (LG Hamburg, 30.03.2020, 327 O 84/20). */
.detail-steuer {
  margin: 18px 0 0;
  font-size: .84rem;
  line-height: 1.6;
  color: var(--muted);
}

/* ── Abweichungen vom erwartbaren Zustand ─────────────────────────────────
   Der einzige Kasten auf der Detailseite, der sich absichtlich vom ruhigen
   Rest abhebt. Grund ist nicht Gestaltung, sondern § 476 Abs. 1 Satz 2 BGB:
   Der Kunde muss „eigens" in Kenntnis gesetzt werden. Etwas, das aussieht wie
   der Fliesstext daneben, wird überlesen.

   Kein Rot und kein Warnzeichen: Eine ehrlich beschriebene Politur ist kein
   Fehler, sondern eine Angabe. Der Goldton der Marke, ein linker Strich, eine
   Spur heller Grund — sichtbar, ohne die Uhr schlechtzumachen. */
.detail-abweichungen {
  margin: 26px 0 0;
  max-width: 460px;
  padding: 18px 20px;
  border-left: 2px solid var(--gold);
  background: rgba(191, 156, 90, 0.06);
  border-radius: 0 var(--field-radius) var(--field-radius) 0;
}
.detail-abweichungen-titel {
  margin: 0;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--gold-bright);
  font-weight: 400;
}
.detail-abweichungen-text {
  margin: 10px 0 0;
  font-size: .84rem;
  line-height: 1.6;
  color: var(--muted);
}
.detail-abweichungen-liste {
  margin: 12px 0 0;
  padding: 0 0 0 18px;
  display: grid;
  gap: 6px;
  font-size: .9rem;
  line-height: 1.55;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Hinweis in der Verwaltung: der Onlinekauf ist gesperrt
   --------------------------------------------------------------------------
   Am 20.08.2026 dazugekommen, als der Entwurfshinweis von den Rechtsseiten
   des Shops verschwand. Er richtet sich jetzt an den Betreiber statt an den
   Besucher — und muss deshalb auffallen, ohne wie ein Fehler auszusehen. Es
   ist kein Defekt, sondern ein bewusst gesetzter Riegel.
   -------------------------------------------------------------------------- */
.ap-warnung {
  margin: 0 0 24px;
  padding: 14px 18px;
  border: 1px solid rgba(227, 200, 143, 0.35);
  border-left: 3px solid var(--gold-bright);
  border-radius: 10px;
  background: rgba(227, 200, 143, 0.06);
  font-size: 13px;
  line-height: 1.75;
  color: var(--muted);
}
.ap-warnung strong { color: var(--gold-bright); }
.ap-warnung code {
  padding: 1px 5px;
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.06);
  font-size: 12px;
}

/* ═══════════════════════════════════════════════════════════ Warenkorb ═══
   Task 0059. Bewusst wenig Neues: Der Korb benutzt die vorhandenen Klassen
   (.ak-block, .ak-summe, .iq-btn, .detail-steuer). Hier stehen nur die
   Stücke, für die es noch nichts gab — der Zähler in der Kopfzeile, die
   Positionszeile und der Hinweis auf herausgefallene Uhren. */

/* Der Warenkorb in der Kopfzeile: ein Zeichen, kein Wort.
   Bis zum 24.08.2026 stand hier ein Knopfkasten mit der Beschriftung
   „Warenkorb"; auf der Startseite waren das drei graue Pillen über dem
   Filmbild. Das Zeichen hat dieselbe Strichstärke wie das Monogramm daneben
   und erbt die Farbe des Verweises — deshalb braucht es keine eigene
   Hover-Regel. */
.shop-korb {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Die Trefferfläche bleibt fingerbreit, obwohl das Zeichen klein ist:
     44 px sind das Mass, unter dem man daneben tippt. */
  width: 44px; height: 44px; margin: -13px -12px;
  color: var(--muted);
  transition: color var(--ease);
}
.shop-korb:hover, .shop-korb:focus-visible { color: var(--gold); }

.korb-zeichen { width: 20px; height: 20px; display: block; }

/* Der Zähler steht nur da, wenn etwas drin ist — eine „0" wäre eine Zahl
   ohne Aussage.
   Er sitzt AUSSERHALB der Tasche an ihrer oberen rechten Ecke und berührt sie
   nur mit dem Rand. Die erste Fassung war 15 px breit auf einem 20-px-Zeichen
   und verdeckte die Zeichnung fast vollständig.
   Kein Ring in Hintergrundfarbe: Auf der Startseite steht die Kopfzeile über
   dem Filmbild, dort stanzte er ein schwarzes Loch. Eine dunkle Kante trennt
   ihn auf jedem Grund. */
.korb-zahl {
  position: absolute;
  top: 4px; right: 3px;
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 14px; height: 14px; padding: 0 3px;
  border-radius: 7px;
  background: var(--gold); color: #0b0b0b;
  border: 1px solid rgba(0, 0, 0, 0.55);
  font-size: 9px; font-weight: 700; letter-spacing: 0; line-height: 1;
  font-variant-numeric: tabular-nums;
}

/* Eine Position im Korb — auf der Seite wie in der Schublade dasselbe feste
   Raster: Foto über beide Zeilen, Titel oben, Preis oben rechts, „Entfernen"
   darunter. Vorher war es auf der Seite ein umbrechender Flex-Streifen; auf
   dem Telefon hing der Titel unten neben dem Foto und Preis und Entfernen
   rutschten ohne Ordnung darunter (Task 0105). */
.korb-zeile {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  column-gap: 18px;
  row-gap: 10px;
  align-items: start;
  padding: 18px 0; border-bottom: 1px solid var(--field-border);
}
.korb-zeile .korb-bild       { grid-row: 1 / span 2; width: 72px; height: 72px; }
.korb-zeile .korb-zeile-text { grid-column: 2; grid-row: 1; }
.korb-zeile .korb-zeile-preis { grid-column: 3; grid-row: 1; text-align: right; }
.korb-zeile .korb-weg        { grid-column: 2 / -1; grid-row: 2; justify-self: start; }
.korb-zeile:last-of-type { border-bottom: 0; }
.korb-zeile-text { min-width: 0; }
.korb-zeile-titel { margin: 0; font-size: 15px; font-weight: 300; }
.korb-zeile-titel a { color: var(--ink); text-decoration: none; transition: color var(--ease); }
.korb-zeile-titel a:hover, .korb-zeile-titel a:focus-visible { color: var(--gold); }
.korb-zeile-steuer { margin: 6px 0 0; font-size: 11px; font-weight: 300; color: var(--muted); }
.korb-zeile-preis { margin: 0; font-size: 15px; font-weight: 300; white-space: nowrap; }

/* „Entfernen" war ein stiller Verweis in 10px-Versalien — so still, dass er
   nicht als Knopf erkannt wurde („man kann nichts mehr entfernen", Task
   0105). Jetzt ein kleiner Umrissknopf mit ×: klar bedienbar, aber ohne
   Gold, damit er nicht mit dem Kaufknopf konkurriert. 40px Höhe als
   Trefferfläche für den Daumen. */
.korb-weg { margin: 0; }
.korb-weg-knopf {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 40px; padding: 0 14px 0 10px; margin-left: -2px;
  border: 1px solid var(--field-border); border-radius: 999px;
  background: none; cursor: pointer;
  font-family: inherit; font-size: 12px; letter-spacing: 1px;
  color: var(--ink);
  transition: color var(--ease), border-color var(--ease);
}
.korb-weg-knopf svg { width: 14px; height: 14px; flex: none; }
.korb-weg-knopf:hover, .korb-weg-knopf:focus-visible {
  color: var(--gold); border-color: rgba(227, 200, 143, 0.45);
}

/* Herausgefallene Uhren. Abgesetzt und ÜBER der Liste — wer die Summe prüft,
   soll den Grund für ihre Änderung schon gelesen haben. */
.korb-entfallen {
  /* Eine feine Kante ringsum und ein Hauch Goldgrund statt eines dicken
     Streifens an der linken Seite. Der Streifen war am 23.08. schneller
     hingeschrieben; er ist die auffälligste Angewohnheit generierter
     Oberflächen und trägt hier nichts, was die Kante nicht auch trägt. */
  border: 1px solid rgba(227, 200, 143, 0.28);
  border-radius: 10px;
  background: rgba(227, 200, 143, 0.05);
  padding: 14px 18px;
  /* Abstand nach unten, sonst klebt der Block an der Überschrift des
     folgenden Abschnitts und liest sich wie deren Vorspann. */
  margin-bottom: 28px;
}
.korb-entfallen p { margin: 0 0 8px; font-size: 13px; font-weight: 300; color: var(--muted); }
.korb-entfallen p:last-child { margin-bottom: 0; }
.korb-entfallen strong { color: var(--ink); font-weight: 400; }

/* Der leere Korb ist eine eigene Ansicht, keine leere Liste.
   Seit 06.10.2026 in Lesebreite, und der Weg zurück ist derselbe kleine
   Goldknopf wie „Ankauf" in der Kopfzeile (Wunsch des Auftraggebers) — kein
   Balken über die ganze Seite. `.ak-block` ist ein Grid: Ohne justify-self
   streckt es jedes Kind auf volle Breite. */
.korb-leer { max-width: 62ch; }
.korb-leer p { margin: 0 0 12px; font-weight: 300; }
.korb-leer .korb-leer-link { justify-self: start; margin-top: 12px; }

/* Korbseite: Liste in Lesebreite, der Kassenknopf in seiner eigenen Breite.
   In der Schublade bleibt er voll breit (.korb-fach .korb-weiter). */
.korb-block { max-width: 760px; }
.korb-block .korb-weiter { justify-self: start; }

.korb-weiter { margin-top: 20px; }

/* Auf der Detailseite: der Korbknopf. */
.detail-korb { margin: 0; }

@media (max-width: 560px) {
  .korb-zeile { grid-template-columns: 58px minmax(0, 1fr) auto; column-gap: 14px; }
  .korb-zeile .korb-bild { width: 58px; height: 58px; }
}

/* Verweise in den Hinweiszeilen der Formulare — sonst zeichnet der Browser
   sein Standardblau, und „Warenkorb ändern" leuchtet neben lauter Gold. */
.ak-hinweis a {
  color: var(--gold); text-decoration: none;
  border-bottom: 1px solid rgba(191, 156, 90, 0.4);
  transition: color var(--ease), border-color var(--ease);
}
.ak-hinweis a:hover, .ak-hinweis a:focus-visible {
  color: var(--gold-bright); border-bottom-color: var(--gold-bright);
}

/* Die Steuer-Kurzform neben dem Uhrentitel in der Kassenübersicht. */
.ak-summe dt small {
  display: block; margin-top: 3px;
  font-size: 11px; font-weight: 300; color: var(--muted);
}

/* ═══════════════════════════════════════════ Warenkorb-Schublade (0066) ═══
   Ein Fach am rechten Rand, das beim Hineinlegen aufgeht. Es zeigt dieselben
   Positionen wie /warenkorb — dasselbe Teilstück, nur enger gesetzt. Was hier
   steht, ist deshalb fast nur Rahmen und Bewegung. */

.korb-schublade { position: fixed; inset: 0; z-index: 60; }
.korb-schublade[hidden] { display: none; }

/* Der Vorhang. Kein reines Schwarz: Das Bild dahinter soll noch zu ahnen
   sein — man hat den Laden nicht verlassen, nur ein Fach geöffnet. */
.korb-vorhang {
  position: absolute; inset: 0;
  background: rgba(4, 4, 4, 0.72);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity 0.3s ease;
}
.korb-schublade.ist-offen .korb-vorhang { opacity: 1; }

.korb-fach {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: min(420px, 100vw);
  display: flex;
  flex-direction: column;
  background: #0b0a08;
  border-left: 1px solid rgba(228, 205, 158, 0.16);
  box-shadow: -30px 0 70px -30px rgba(0, 0, 0, 0.95);
  transform: translateX(100%);
  transition: transform 0.34s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.korb-schublade.ist-offen .korb-fach { transform: translateX(0); }

.korb-fach-kopf {
  display: flex; align-items: center; justify-content: space-between;
  gap: 16px;
  padding: 22px 26px 18px;
  border-bottom: 1px solid var(--field-border);
  flex: none;
}
.korb-fach-titel {
  margin: 0;
  font-family: var(--font-sans), sans-serif;
  font-size: 11px; font-weight: 500; letter-spacing: 4px;
  text-transform: uppercase; color: var(--ink);
}
.korb-fach-zu {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; margin: -10px -12px -10px 0;
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--muted);
  transition: color var(--ease);
}
.korb-fach-zu:hover, .korb-fach-zu:focus-visible { color: var(--gold); }
.korb-fach-zu svg { width: 20px; height: 20px; display: block; }

/* Nur die Positionen rollen, Kopf und Knopf bleiben stehen. */
.korb-fach-inhalt { flex: 1 1 auto; overflow-y: auto; padding: 6px 26px 26px; }
.korb-fach-laedt { color: var(--muted); font-size: 13px; font-weight: 300; }

/* Im Fach sitzt der Inhalt enger als auf der Seite: 420 px sind kein
   Bildschirm. Dieselben Elemente, andere Masse — deshalb steht das hier und
   nicht in einer zweiten Vorlage. Das Raster selbst steht seit Task 0105
   bei `.korb-zeile` und gilt für Seite und Fach gleich; hier nur die Masse. */
.korb-fach .korb-zeile {
  grid-template-columns: 58px minmax(0, 1fr) auto;
  column-gap: 14px;
  row-gap: 8px;
  padding: 16px 0;
}
.korb-fach .korb-zeile .korb-bild { width: 58px; height: 58px; }
.korb-fach .korb-zeile-titel { font-size: 13.5px; }
.korb-fach .korb-zeile-preis { font-size: 13.5px; }
.korb-fach .detail-steuer { font-size: 11px; }
.korb-fach .korb-weiter { width: 100%; }
.korb-fach .detail-kaufhinweis { font-size: 11px; }
.korb-fach .korb-leer { padding: 24px 0; }

/* Das Foto der Uhr. In einer Schublade, die beim Hineinlegen aufgeht, ist es
   die schnellste Bestätigung: Man erkennt die Uhr, bevor man den Titel
   gelesen hat. */
.korb-bild {
  flex: none;
  width: 58px; height: 58px;
  display: flex; align-items: center; justify-content: center;
  border: 1px solid var(--field-border);
  border-radius: 8px;
  background: rgba(255, 255, 255, 0.02);
  overflow: hidden;
}
.korb-bild img { width: 100%; height: 100%; object-fit: cover; display: block; }
.korb-bild .korb-bild-mark { width: 60%; height: 60%; object-fit: contain; opacity: 0.4; }

/* Die Seite darunter darf nicht mitrollen, während das Fach offen ist. */
body.korb-offen { overflow: hidden; }

@media (max-width: 520px) {
  .korb-fach { width: 100vw; border-left: 0; }
  .korb-fach-inhalt { padding: 6px 20px 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .korb-fach, .korb-vorhang { transition: none; }
}

/* ════════════════════════════════════════════════ Die Kasse (Task 0067) ═══
   Eine Seite, zwei Spalten: links die Schritte, rechts die Bestellübersicht.

   Die Übersicht steht im Quelltext VOR dem Formular. Das Raster holt sie auf
   breiten Schirmen nach rechts; auf dem Telefon bleibt sie, wo sie steht —
   oben. Beides erfüllt dieselbe Pflicht: Preise und Steuerhinweis stehen vor
   dem Bestellknopf. Die Reihenfolge im Quelltext ist deshalb nicht beliebig,
   und `order` in der anderen Richtung wäre hier ein Fehler. */

.kasse { display: grid; gap: clamp(28px, 4vw, 56px); align-items: start; }

@media (min-width: 900px) {
  .kasse { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); }
  .kasse-spalte     { grid-column: 1; grid-row: 1; }
  .kasse-uebersicht { grid-column: 2; grid-row: 1; position: sticky; top: 108px; }
}

.kasse-uebersicht {
  border: 1px solid var(--field-border);
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.018);
  padding: 22px 24px;
}
.kasse-uebersicht-liste { display: grid; gap: 4px; margin-bottom: 8px; }

.kasse-pos {
  display: grid;
  grid-template-columns: 52px 1fr auto;
  column-gap: 14px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid var(--field-border);
}
.kasse-pos:last-child { border-bottom: 0; }
.kasse-pos .korb-bild { width: 52px; height: 52px; }
.kasse-pos-text  { min-width: 0; }
.kasse-pos-titel { margin: 0; font-size: 13px; font-weight: 300; color: var(--ink); }
.kasse-pos-preis { margin: 0; font-size: 13px; font-weight: 300; white-space: nowrap; }

/* Die wesentlichen Eigenschaften unter dem Titel. Pflichtangabe (§ 312j
   Abs. 2 BGB), deshalb sichtbar — aber leiser als der Titel, sonst zerfällt
   die Übersicht in gleich laute Zeilen. */
.kasse-pos-merkmale { margin: 4px 0 0; font-size: 11px; line-height: 1.5;
                      font-weight: 300; color: var(--muted); }

/* Express-Zahlung. Bleibt verborgen, bis Stripe wirklich Knöpfe
   hineingezeichnet hat (Task 0068) — ein leerer Kasten mit der Überschrift
   „Express" wäre schlimmer als gar keiner. */
.kasse-express[hidden] { display: none; }
.kasse-express { display: grid; gap: 18px; margin-bottom: 6px; }

/* Die Trennlinie mit dem Wort in der Mitte. Zwei Linien links und rechts vom
   Text, gezeichnet über das Pseudo-Element — kein zusätzliches Markup. */
.kasse-oder {
  display: flex; align-items: center; gap: 16px;
  margin: 0;
  font-size: 10px; letter-spacing: 3px; text-transform: uppercase;
  color: var(--muted);
}
.kasse-oder::before, .kasse-oder::after {
  content: ''; flex: 1 1 auto; height: 1px; background: var(--field-border);
}

/* Die eine Versandart. Sieht aus wie eine getroffene Wahl, ist aber keine
   Auswahl — es gibt nur diese. */
.kasse-versand {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  column-gap: 14px;
  padding: 16px 18px;
  border: 1px solid rgba(228, 205, 158, 0.28);
  border-radius: 12px;
  background: rgba(227, 200, 143, 0.045);
}
.kasse-versand-haken { color: var(--gold); font-size: 13px; }
.kasse-versand-text  { display: grid; gap: 3px; font-size: 12px; font-weight: 300; color: var(--muted); }
.kasse-versand-text strong { font-size: 13.5px; font-weight: 400; color: var(--ink); }
.kasse-versand-preis { font-size: 13.5px; font-weight: 300; white-space: nowrap; }

/* Das Bezahlfeld von Stripe. Nur der Platz — was darin steht, zeichnet
   Stripe (Task 0068). Kein Rahmen: Das Element bringt seinen eigenen mit. */
.kasse-zahlfeld { min-height: 0; }
.kasse-zahlfeld:not(:empty) { margin-top: 6px; }

/* ── Vorschau des Kaufwegs (Task 0071) ─────────────────────────────────────
   Solange Stripe ruht, zeichnet die Seite Express-Block und Bezahlfeld
   selbst. Beides ist bewusst RUHIG gehalten: Es soll zeigen, wie die fertige
   Kasse aussieht, und nicht zum Draufdrücken einladen. */

.kasse-express-vorschau { gap: 14px; }

.kasse-express-titel {
  margin: 0;
  font-size: 10px; letter-spacing: 3px; text-transform: uppercase;
  color: var(--muted);
}

/* Drei nebeneinander, solange der Platz reicht — darunter untereinander.
   auto-fit statt fester Spalten: Kommt eine vierte Zahlart dazu, ordnet sich
   das von selbst. */
.kasse-express-knoepfe {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}

.kasse-express-knopf {
  display: flex; align-items: center; justify-content: center;
  min-height: 42px;
  padding: 0 14px;
  border: 1px solid var(--field-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.035);
  color: var(--ink);
  cursor: default;
}

/* Abgeschaltet, aber NICHT ausgegraut. Eine Deckkraft von 0,55 machte aus
   PayPal-Blau und Google-Grau einen einzigen Matsch — die Knöpfe waren nicht
   mehr auseinanderzuhalten. Die Zahlarten sollen erkennbar bleiben; dass hier
   noch nichts geht, sagt die eine Zeile unter dem Bestellknopf. */
.kasse-express-knopf[disabled] { cursor: default; }

.kasse-express-marke { display: flex; align-items: center; }
.kasse-express-marke svg { height: 18px; width: auto; display: block; }

/* PayPal trägt seine eigenen Farben, die beiden Gerätezahlungen sind
   einfarbig — so hält es auch Stripes echter Express-Block. */
.kasse-express-paypal { background: #fff; border-color: #fff; }
.kasse-express-apple  { background: #000; border-color: #000; color: #fff; }
.kasse-express-google { background: #fff; border-color: #fff; color: #3c4043; }

/* Der Karten-Platzhalter. Kein einziges Eingabefeld — niemand soll hier eine
   Kartennummer eintippen können, die nirgendwohin geht. */
.kasse-zahlfeld-vorschau {
  display: grid; gap: 10px;
  margin-top: 6px;
  padding: 14px 16px;
  border: 1px solid var(--field-border);
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.02);
}
.kasse-zahlzeile { display: grid; gap: 4px; }
.kasse-zahlzeile-zwei { grid-template-columns: 1fr 1fr; column-gap: 14px; }
.kasse-zahlzeile-zwei > span { display: grid; gap: 4px; }
.kasse-zahllabel {
  font-size: 10px; letter-spacing: 2px; text-transform: uppercase;
  color: var(--muted);
}
.kasse-zahlplatz {
  font-size: 13.5px; font-weight: 300;
  color: var(--muted);
  letter-spacing: 1px;
}

/* Auf dem Telefon einer pro Zeile. Ohne diese Regel griff auto-fit bei rund
   340 px Inhaltsbreite auf ZWEI Spalten: PayPal und Apple Pay nebeneinander,
   GPay allein darunter über die volle Breite — das liest sich wie ein
   Versehen, nicht wie eine Wahl. Nachgemessen, nicht geschätzt. */
@media (max-width: 479px) {
  .kasse-express-knoepfe { grid-template-columns: 1fr; }
}

/* Die eine Zeile, die für Express-Knöpfe UND Bestellknopf zugleich gilt. */
.kasse-vorschau-hinweis { margin-top: 10px; text-align: center; }

/* Der Bestellknopf trägt die Breite der Spalte — er schliesst die Sache ab. */
.kasse-knopf { width: 100%; align-self: stretch; margin-top: 4px; }
.kasse-knopf[disabled] { opacity: 0.5; cursor: default; }

@media (max-width: 899px) {
  /* Auf dem Telefon steht die Übersicht oben und darf nicht die halbe Seite
     einnehmen: Die Liste rollt, Summe und Steuerhinweis bleiben sichtbar. */
  .kasse-uebersicht-liste { max-height: 40vh; overflow-y: auto; }
}

/* ═══════════════════════════════════════ Anfrage-Fach (Task 0115) ═══
   Das Anfrageformular steht nicht mehr auf der Detailseite, sondern in
   einem Fach wie der Warenkorb — Rahmen, Vorhang und Bewegung kommen von
   `.korb-schublade`/`.korb-fach` oben. Hier nur, was anders ist.

   Sichtbar wird es auf zwei Wegen: mit Skript über `.ist-da`/`.ist-offen`
   (watch.js), ohne Skript über den Anker `#anfrage-fach` (`:target`).
   Sobald das Skript läuft (`.mit-skript`), gilt nur noch sein Weg — sonst
   hielte `:target` das Fach nach dem Schliessen offen. */
.anfrage-schublade { display: none; }
.anfrage-schublade.ist-da,
.anfrage-schublade:not(.mit-skript):target { display: block; }
.anfrage-schublade:not(.mit-skript):target .korb-vorhang { opacity: 1; }
.anfrage-schublade:not(.mit-skript):target .korb-fach { transform: translateX(0); }
.anfrage-schublade .korb-vorhang { display: block; cursor: default; }

/* Was angefragt wird, steht oben — man sieht die Uhr, bevor man tippt. */
.anfrage-uhr {
  display: flex; align-items: center; gap: 14px;
  padding: 18px 0;
  border-bottom: 1px solid var(--field-border);
}
.anfrage-uhr p { margin: 0; }
.anfrage-uhr-marke {
  font-size: 10px; letter-spacing: 3px; text-transform: uppercase;
  color: var(--gold);
}
.anfrage-uhr-name { margin-top: 3px !important; font-size: 14px; color: var(--ink); }
.anfrage-uhr-preis { margin-top: 2px !important; font-size: 13px; color: var(--muted); }

/* Im Fach braucht das Formular keine eigene Trennlinie mehr — die zieht
   schon die Zeile mit der Uhr darüber. */
.anfrage-schublade .iq,
.anfrage-schublade .iq-done { margin-top: 0; padding-top: 20px; border-top: 0; }
.anfrage-einleitung {
  margin: 0 0 4px;
  font-size: 13px; line-height: 1.6; font-weight: 300; color: var(--muted);
}
.anfrage-schublade .iq .iq-btn { align-self: stretch; }
.anfrage-schublade .iq-done p { margin: 0 0 18px; line-height: 1.6; }
.anfrage-fertig { display: block; text-align: center; text-decoration: none; }

/* Der leise Weg zum Fach, wenn oben schon der Korbknopf steht: eine Frage
   ist kein zweiter Kaufweg und soll nicht wie einer aussehen. */
.detail-frage {
  display: inline-block;
  margin: -12px 0 26px;
  font-size: .84rem;
  color: var(--gold-bright);
  text-decoration: underline;
  text-decoration-color: rgba(227, 200, 143, 0.35);
  text-underline-offset: 4px;
  transition: text-decoration-color var(--ease);
}
.detail-frage:hover, .detail-frage:focus-visible { text-decoration-color: currentColor; }

/* Telefon: 16px in den Feldern, sonst zoomt iOS beim Antippen hinein und
   das Fach verrutscht. */
@media (max-width: 520px) {
  .anfrage-schublade .iq input,
  .anfrage-schublade .iq textarea { font-size: 16px; }
  .anfrage-schublade .iq-row { grid-template-columns: minmax(0, 1fr); }
}

/* ---------- Bewertungen ----------
   Block „Stimmen" auf der Startseite (partials/bewertungen), die Sterne
   (partials/sterne, auch in Verwaltung und Danke-Seite) und das Formular, mit
   dem Kunden bewerten (shop/bewertung). Ein Abschnitt, weil alles dieselbe
   Sternzeichnung teilt. Nur Werte aus :root; Knöpfe bleiben bei .iq-btn. */

/* Eigener Grund wie .collection-section: Der Block liegt auf der Startseite
   über der fixierten Video-Bühne. Die Haarlinie oben trennt ihn von der
   Kollektion; Ränder und 1180-px-Deckel sind die der Kollektion. */
.bw-section {
  background: var(--bg);
  border-top: 1px solid rgba(191, 156, 90, 0.14);
  padding: clamp(56px, 8vw, 96px) clamp(20px, 6vw, 96px);
}
.bw-head {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: end;
  gap: 10px 24px;
  max-width: 1180px;
  margin: 0 auto clamp(32px, 5vw, 56px);
  padding-bottom: 22px;
  border-bottom: 1px solid rgba(191, 156, 90, 0.28);
}
.bw-head .shop-kicker {
  grid-column: 1 / -1;
  margin-bottom: 0;
}
.bw-schnitt {
  display: flex;
  align-items: center;
  gap: 10px;
  padding-bottom: 8px;
  white-space: nowrap;
}
.bw-schnitt-zahl {
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
}
/* Auf dem Telefon steht der Schnitt unter dem Titel statt daneben. */
@media (max-width: 640px) {
  .bw-head { grid-template-columns: minmax(0, 1fr); }
  .bw-schnitt { padding-bottom: 0; }
}

/* Wie .collection-grid: auto-fill + minmax ergibt 3 Spalten am Desktop,
   2 am Tablet, 1 am Handy. Die Zellen strecken sich, also sind die Karten
   je Reihe gleich hoch; das Zitat nimmt den Rest, damit die Fußzeilen der
   Karten auf einer Linie stehen. */
.bw-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 32px;
  max-width: 1180px;
  margin: 0 auto;
}
.bw-karte {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 32px 30px 28px;
  border: 1px solid rgba(191, 156, 90, 0.22);
  border-radius: var(--field-radius);
  background: rgba(255, 255, 255, 0.025);
}
.bw-zitat {
  flex-grow: 1;
  font-family: var(--font-serif), serif;
  font-style: italic;
  font-weight: 300;
  font-size: 24px;
  line-height: 1.35;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.bw-fuss {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-top: 18px;
  border-top: 1px solid rgba(191, 156, 90, 0.16);
}
.bw-name {
  font-size: 12px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--ink);
}
.bw-meta {
  font-size: 12px;
  color: var(--muted);
}
.bw-geprueft {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  font-size: 10px;
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--gold);
}
.bw-geprueft svg {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
}
.bw-hinweis {
  width: min(1180px, 100%);
  margin: 40px auto 0;
  font-size: 12px;
  color: var(--muted);
}
@media (max-width: 640px) {
  .bw-karte { padding: 24px 22px 22px; gap: 16px; }
  .bw-zitat { font-size: 21px; }
  .bw-fuss { padding-top: 14px; gap: 5px; }
  .bw-grid { gap: 20px; }
}

/* ---- Sterne (Anzeige) ----
   Gefüllt = Goldfläche, leer = nur die Kontur. Gleiche Zeichnung in drei
   Größen; die Einzelsterne erben die Farbe vom Behälter. */
.bw-sterne {
  display: inline-flex;
  gap: 4px;
  color: var(--gold);
}
.bw-stern {
  width: 16px;
  height: 16px;
  flex-shrink: 0;
  fill: currentColor;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
}
.bw-stern.is-leer { fill: none; }
.bw-sterne--klein { gap: 3px; }
.bw-sterne--klein .bw-stern { width: 14px; height: 14px; }

/* ---- Sternwahl im Formular ----
   Reines CSS. Die Radios stehen im DOM von 5 nach 1, row-reverse zeigt sie
   von 1 nach 5; so trifft `:checked ~ label` immer die kleineren Sterne
   (im DOM folgende Geschwister) und `:hover ~ label` ebenso. Die Radios sind
   nur unsichtbar, nicht display:none — sonst ließe sich die Wahl mit der
   Tastatur nicht mehr erreichen. */
.bw-wahl {
  border: 0;
  padding: 0;
  margin: 0;
  min-width: 0;
}
.bw-wahl-reihe {
  display: inline-flex;
  flex-direction: row-reverse;
  gap: 6px;
}
.bw-wahl-reihe input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.bw-wahl-reihe label {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--field-border);
  border-radius: var(--field-radius);
  background: var(--field-bg);
  color: var(--gold);
  cursor: pointer;
  transition:
    background-color var(--ease),
    border-color var(--ease);
}
.bw-wahl-reihe svg {
  width: 24px;
  height: 24px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linejoin: round;
  transition: fill var(--ease);
}
.bw-wahl-reihe input:checked ~ label svg,
.bw-wahl-reihe label:hover svg,
.bw-wahl-reihe label:hover ~ label svg {
  fill: currentColor;
}
.bw-wahl-reihe label:hover {
  border-color: rgba(228, 205, 158, 0.34);
}
/* Der Fokus liegt auf dem unsichtbaren Radio; sichtbar wird er am Label. */
.bw-wahl-reihe input:focus-visible + label {
  outline: 2px solid var(--gold-bright);
  outline-offset: 2px;
}

/* ---- Formular ---- */
.bw-form {
  display: flex;
  flex-direction: column;
  gap: 30px;
}
.bw-feld {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bw-label {
  display: block;
  padding: 0;
  margin-bottom: 14px;
  font-size: 11px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: rgba(240, 232, 216, 0.72);
}
.bw-feld .bw-label { margin-bottom: 0; }
.bw-hilfe {
  font-size: 12px;
  line-height: 1.6;
  color: var(--muted);
}
.bw-einwilligung {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  max-width: 62ch;
  font-size: 14px;
  line-height: 1.55;
  color: rgba(240, 232, 216, 0.86);
  cursor: pointer;
}
.bw-einwilligung input {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin: 2px 0 0;
  accent-color: var(--gold);
}
.bw-fehler {
  font-size: 13px;
  line-height: 1.5;
  color: #e0a0a0;
}
/* Auf dem Telefon 16 px in den Feldern: iOS zoomt sonst beim Antippen. */
@media (max-width: 520px) {
  .bw-form .iq input,
  .bw-form .iq textarea { font-size: 16px; }
}

/* ---------- Bewertungen in der Verwaltung (Task 0129) ----------
   Zweiter Entwurf vom 09.10.2026: Die Liste ist die Seite. Kompakte Karten
   mit kleinen Knöpfen rechts statt goldener Balken über die ganze Breite;
   eine Statuszeile im Kopf statt eines Erklärblocks; der Bewertungslink
   für Kunden ohne Shop-Bestellung zugeklappt hinter dem Knopf oben rechts.
   Knöpfe bleiben bei den vier Rollen aus dem Abschnitt KNÖPFE — .bwv-knopf
   macht sie nur kleiner. */

.bwv-kopf { align-items: flex-end; }
.bwv-stand {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 10px 0 0;
  font-size: 13px;
  color: rgba(240, 232, 216, 0.72);
}
.bwv-stand svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--gold-bright); }
.bwv-stand svg[hidden] { display: none; }

.bwv-knopf { padding: 10px 16px; font-size: 11px; letter-spacing: 2px; }
.ap-btn-ghost.is-active { color: var(--gold-bright); border-color: rgba(228, 205, 158, 0.4); background: rgba(255, 255, 255, 0.06); }

/* ---- Das zugeklappte Panel ---- */
.bwv-panel {
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px 28px;
  margin-bottom: 26px;
  border: 1px solid rgba(228, 205, 158, 0.2);
  border-radius: var(--field-radius);
  background: rgba(255, 255, 255, 0.03);
}
/* `display: flex` schlägt sonst das hidden-Attribut. */
.bwv-panel[hidden] { display: none; }
.bwv-panel-titel { margin-bottom: 6px; }
.bwv-panel-text { margin: 0; max-width: 70ch; font-size: 13px; line-height: 1.6; letter-spacing: 0; }
.bwv-link-form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px 20px;
  align-items: end;
}
.bwv-link-form .ap-field { margin-top: 0; }
.bwv-link-senden { display: flex; align-items: flex-end; }
.bwv-ergebnis {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 16px 18px;
  border: 1px solid rgba(191, 156, 90, 0.28);
  border-radius: var(--field-radius);
  background: rgba(191, 156, 90, 0.06);
}
.bwv-ergebnis[hidden] { display: none; }
.bwv-ergebnis-text { margin: 0; font-size: 12px; color: rgba(240, 232, 216, 0.72); }
.bwv-linkzeile { display: flex; gap: 10px; align-items: center; }
.bwv-linkzeile input {
  flex: 1 1 auto;
  min-width: 0;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
  padding: 11px 14px;
  background: rgba(0, 0, 0, 0.3);
  border: 1px solid var(--field-border);
  border-radius: var(--field-radius);
}
.bwv-linkzeile input:focus { outline: none; border-color: rgba(227, 200, 143, 0.6); }
.bwv-linkzeile .bwv-knopf { white-space: nowrap; }
.bwv-offen {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 6px;
  border-top: 1px solid rgba(191, 156, 90, 0.14);
}
.bwv-offen[hidden] { display: none; }
.bwv-offen-titel {
  margin: 8px 0 2px;
  font-size: 10px;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
}
.bwv-offen-zeile {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  padding: 8px 0;
  font-size: 13px;
}
.bwv-offen-text { color: var(--muted); }

/* ---- Die Karten ---- */
.bwv-liste { gap: 12px; }
.bwv-karte {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px 28px;
  align-items: start;
  padding: 20px 24px;
  border: 1px solid rgba(228, 205, 158, 0.3);
  border-radius: var(--field-radius);
  background: rgba(255, 255, 255, 0.035);
}
/* Sichtbare sind erledigt — sie treten zurück, Neues steht vorn. */
.bwv-karte--ruhig { border-color: rgba(228, 205, 158, 0.12); background: rgba(255, 255, 255, 0.02); }
.bwv-karte-kopf {
  display: flex;
  align-items: center;
  gap: 12px;
  font-size: 12px;
  color: var(--muted);
}
.bwv-zustand { font-size: 10px; letter-spacing: 2px; text-transform: uppercase; color: var(--muted); }
.bwv-datum { font-variant-numeric: tabular-nums; }
.bwv-zustand--neu { color: var(--gold-bright); }
/* Spalte ausdrücklich: Ein Element mit fester Zeile, aber freier Spalte wird
   vom Raster VOR den übrigen gesetzt und landete so links statt rechts. */
.bwv-aktionen {
  grid-column: 2;
  grid-row: 1 / span 3;
  align-self: center;
  display: flex;
  gap: 8px;
}
.bwv-karte-kopf, .bwv-zitat, .bwv-meta { grid-column: 1; }
.bwv-zitat {
  margin: 0;
  font-family: var(--font-serif), serif;
  font-style: italic;
  font-weight: 300;
  font-size: 21px;
  line-height: 1.35;
  color: var(--ink);
  overflow-wrap: anywhere;
}
.bwv-meta { margin: 0; font-size: 12px; color: var(--muted); overflow-wrap: anywhere; }
.bwv-name { color: var(--ink); }
.bwv-hinweis { margin-top: 18px; max-width: 72ch; letter-spacing: 0; color: rgba(240, 232, 216, 0.5); }

@media (max-width: 640px) {
  .bwv-karte { grid-template-columns: minmax(0, 1fr); }
  /* Auf dem Telefon unter Zitat und Meta-Zeile, nicht dazwischen. */
  .bwv-aktionen { grid-column: 1; grid-row: 4; align-self: start; }
  .bwv-link-form { grid-template-columns: minmax(0, 1fr); }
}
