/* ==========================================================================
   ORVAIN — Haute Joaillerie
   Design System & Stylesheet
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Fonts
   -------------------------------------------------------------------------- */

@font-face {
  font-family: "Millionaire Roman";
  src: url("../fonts/millionaire-roman.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Millionaire Script";
  src: url("../fonts/millionaire-script.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  /* `block` statt `swap`: bis die Schrift da ist, wird nichts gezeichnet.
     Mit `swap` sprang macOS auf Snell Roundhand ein - auch eine
     Schreibschrift, aber mit anderen Maßen und einem laengeren Auslauf am
     "t". Das Wort stand dann kurz falsch und beschnitten da und ruckte
     beim Nachladen. Die Datei ist vorgeladen, das Fenster ist kurz. */
  font-display: block;
}

@font-face {
  font-family: "Akzidenz Grotesk";
  src: url("../fonts/akzidenz-grotesk-regular.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* Die Lauftext- und Bedienschrift. Sie loest Akzidenz Grotesk Regular ab;
   der breit laufende Schnitt (Ext) bleibt fuer die gesperrten Versalzeilen,
   weil Neue Helvetica keinen extended cut mitbringt und die Zeilen sonst
   ihren Charakter verlieren. */
@font-face {
  font-family: "Neue Helvetica";
  src: url("../fonts/neue-helvetica-45-light.woff2") format("woff2");
  font-weight: 300 400;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Akzidenz Grotesk Ext";
  src: url("../fonts/akzidenz-grotesk-extended.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

/* --------------------------------------------------------------------------
   2. Tokens
   -------------------------------------------------------------------------- */

:root {
  /* Farben */
  --ink: #0d1a2f;          /* Tiefes Navy: Text und dunkle Bänder */
  --ink-soft: #16243d;
  --ink-line: rgba(237, 239, 247, 0.18);

  --bone: #d7dbe6;         /* Periwinkle: Statement-Bänder */
  --paper: #edeff7;        /* Hellster Ton: Kopf, Fuß, Panels */
  --bone-line: rgba(13, 26, 47, 0.16);

  --gold: #b99a58;
  --gold-light: #e2cd9c;

  --muted-dark: rgba(13, 26, 47, 0.62);
  --muted-light: rgba(237, 239, 247, 0.62);

  /* Typografie */
  --f-display: "Millionaire Roman", "Times New Roman", serif;
  --f-script: "Millionaire Script", "Snell Roundhand", cursive;
  --f-sans: "Neue Helvetica", "Helvetica Neue", Helvetica, Arial, sans-serif;
  --f-ext: "Akzidenz Grotesk Ext", "Helvetica Neue", Helvetica, Arial, sans-serif;

  /* Raster */
  --pad: clamp(1.25rem, 4.5vw, 5rem);
  --maxw: 1560px;
  --rule: 1px;
  --head-h: 4.4rem;

  /* Bewegung */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-io: cubic-bezier(0.65, 0, 0.35, 1);
}

/* --------------------------------------------------------------------------
   3. Reset
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.0625rem);
  line-height: 1.72;
  font-kerning: normal;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

body.is-locked { overflow: hidden; }

img, svg { display: block; max-width: 100%; }
h1, h2, h3, h4, p, figure, blockquote { margin: 0; }

/* Keine erfundene Fettschrift.
   Millionaire Roman und Akzidenz Extended haben genau einen Schnitt,
   Neue Helvetica einen von 300 bis 400. Ueberall dort, wo ein Browser von
   sich aus fett setzt - h1 bis h6, th, dt, strong, b - findet er keinen
   fetten Schnitt und rechnet sich selbst einen aus: er verdickt die
   Buchstaben. Das ist kein Schriftschnitt, das ist Schmier, und es faellt
   genau bei der Hausschrift auf, weil ihre feinen Serifen dabei zulaufen.

   Gemessen am 2026-08-16: .pfaq__q stand auf 700 (14-mal allein auf den
   Haeufigen Fragen), .jgroup__h auf 700, .cc__h auf 700, dazu jedes h2 und
   h3 der Rechtstexte und jedes <strong> darin.

   Zwei Riegel: die Elemente bekommen ausdruecklich 400, und
   font-synthesis-weight verbietet dem Browser das Nachrechnen ueberhaupt.
   Damit kann auch eine kuenftige Regel mit 700 keinen Schmier mehr
   erzeugen - sie faellt still auf den vorhandenen Schnitt zurueck. */
html { font-synthesis-weight: none; }
h1, h2, h3, h4, h5, h6,
th, dt, strong, b { font-weight: 400; }
ul, ol { margin: 0; padding: 0; list-style: none; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
a { color: inherit; text-decoration: none; }

::selection { background: var(--gold); color: var(--ink); }

:focus-visible { outline: 1px solid var(--gold); outline-offset: 4px; }

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--ink);
  color: var(--paper);
  padding: 0.75rem 1.25rem;
  font-family: var(--f-ext);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* --------------------------------------------------------------------------
   4. Typografie-Bausteine
   -------------------------------------------------------------------------- */

.display {
  font-family: var(--f-display);
  font-weight: 400;
  /* 1.02 war fuer eine einzelne Zeile gedacht und stimmte dort. Sobald eine
     Ueberschrift umbricht, schlaegt die Unterlaenge in die Zeile darunter -
     das "g" von "Knowledge" in "the right decision", das "y" von "Stay" ins
     ORVAIN. Letzteres war schon einzeln geflickt; jetzt ist es an der
     Wurzel gedeckt. 1.1 ist immer noch eng, aber es beruehrt sich nichts
     mehr. Vorgabe 19.08.2026. */
  line-height: 1.1;
  letter-spacing: -0.012em;
  text-wrap: balance;
}

.d-xxl { font-size: clamp(2.9rem, 8.2vw, 8.8rem); }
.d-xl  { font-size: clamp(2.7rem, 6.6vw, 6.2rem); }
.d-l   { font-size: clamp(2.2rem, 4.6vw, 4.2rem); }
.d-m   { font-size: clamp(1.6rem, 2.6vw, 2.5rem); line-height: 1.1; }
.d-s   { font-size: clamp(1.25rem, 1.7vw, 1.65rem); line-height: 1.2; }

/* Die Script trägt genau ein Wort pro Abschnitt — die Signatur des Hauses. */
.script {
  font-family: var(--f-script);
  font-weight: 400;
  font-style: normal;
  color: inherit;
  letter-spacing: 0;
  line-height: 1;
  /* Schreibschriften laufen ueber ihre Buchstabenbreite hinaus. Am Canvas
     gemessen (19.08.2026): bei "Wearing it" ragt die Tinte des "t" um
     0.186em ueber den Vorschub - 12 px bei 66 px Schriftgroesse.
     Sichtbar wurde das erst durch die Einblendung: Safari legt ein
     transformiertes Element in eine eigene Ebene und schneidet ab, was aus
     der Box ragt. Nach der Animation faellt die Ebene weg und der Buchstabe
     ist wieder ganz da - genau das "haengt kurz und ist dann normal".

     0.22em deckt den gemessenen Wert mit Reserve. Beidseitig, damit die
     zentrierte Zeile nicht um das halbe Polster nach links rutscht. */
  padding-inline: 0.22em;
}
.script--gold { color: var(--gold); }

.eyebrow {
  font-family: var(--f-ext);
  font-size: clamp(0.6rem, 0.55rem + 0.16vw, 0.72rem);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  line-height: 1.6;
  color: var(--ink);
}
.eyebrow--gold { color: var(--gold); }
.eyebrow--light { color: var(--muted-light); }
.eyebrow--muted { color: var(--muted-dark); }

.lede {
  font-size: clamp(1rem, 0.93rem + 0.42vw, 1.28rem);
  line-height: 1.6;
}

.muted { color: var(--muted-dark); }
.on-dark .muted, .muted--light { color: var(--muted-light); }

.num {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.24em;
  color: var(--gold);
}

/* --------------------------------------------------------------------------
   5. Layout
   -------------------------------------------------------------------------- */

.shell {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--pad);
}

section[id], main[id] { scroll-margin-top: var(--head-h); }

.section { padding-block: clamp(5rem, 11vh + 3rem, 11rem); }
.section--tight { padding-block: clamp(3.5rem, 7vh + 2rem, 7rem); }

.on-dark { background: var(--ink); color: var(--paper); }
.on-dark .eyebrow { color: var(--muted-light); }
.on-paper { background: var(--paper); }
.on-bone { background: var(--bone); }

.rule { height: var(--rule); background: var(--bone-line); border: 0; margin: 0; }
.on-dark .rule { background: var(--ink-line); }

.grain { position: relative; isolation: isolate; }
.grain::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 3;
  pointer-events: none;
  opacity: 0.45;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.3'/%3E%3C/svg%3E");
}

/* --------------------------------------------------------------------------
   6. Buttons & Links
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--f-sans);
  font-size: 0.95rem;
  line-height: 1;
  padding: 1.05em 2.2em;
  border: var(--rule) solid rgba(13, 26, 47, 0.34);
  border-radius: 999px;
  color: var(--ink);
  background: transparent;
  transition: background 0.5s var(--ease), color 0.5s var(--ease),
              border-color 0.5s var(--ease);
}
.btn:hover { background: var(--ink); color: var(--paper); border-color: var(--ink); }

.btn--light { color: #fff; border-color: rgba(255, 255, 255, 0.5); }
.btn--light:hover { background: #fff; color: var(--ink); border-color: #fff; }

.btn--solid { background: var(--ink); color: var(--paper); border-color: var(--ink); }
/* Kein eigener Ueberfahr-Zustand mehr.

   Die Regel hiess `background: var(--gold); color: var(--ink);
   border-color: var(--gold)`. Beim Entfernen des Golds am 21.08.2026 sind
   nur die Gold-Zeilen gefallen - `color: var(--ink)` blieb stehen, und das
   ergab dunklen Text auf dunklem Grund: der Knopf war beim Ueberfahren
   leer. Gemeldet am 22.08.2026, betraf jeden vollen Knopf der Seite.

   Die Farbe gehoerte zum goldenen Grund und faellt mit ihm. Uebrig bleibt
   `.btn:hover` - dieselbe Tinte auf demselben Papier wie im Ruhezustand,
   also kein Wechsel. Das ist die Absicht: Gold sollte weg, ohne Ersatz. */

.tlink {
  position: relative;
  padding-top: 0.4em;
  font-family: var(--f-ext);
  font-size: 0.66rem;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  display: inline-block;
  padding-bottom: 0.5em;
  background-image: linear-gradient(currentColor, currentColor);
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: background-size 0.5s var(--ease), color 0.4s var(--ease);
}
.tlink:hover { background-size: 0 1px; background-position: 100% 100%; }

/* --------------------------------------------------------------------------
   7. Kopfzeile
   -------------------------------------------------------------------------- */

.header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 90;
  height: var(--head-h);
  display: flex;
  align-items: center;
  color: #fff;
  transition: background 0.6s var(--ease), color 0.6s var(--ease),
              transform 0.6s var(--ease), box-shadow 0.6s var(--ease);
}

.header__inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  width: 100%;
}

/* Die Linie lief nur zwischen den Seitenraendern und endete damit vor den
   Kanten. Ueber die volle Breite gezogen liegt sie wie bei einem gedruckten
   Bogen an. */
.header::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  /* currentColor statt festem Weiss: die Leiste steht mal auf dunklem Bild,
     mal auf Papier. Mit einem festen Weiss war die Linie auf hellem Grund
     unsichtbar, solange die Leiste nicht is-solid war - und dort, wo sie es
     war, kam sie aus einem box-shadow. Zwei Wege fuer eine Linie, und einer
     davon falsch. Jetzt folgt sie der Schriftfarbe, in derselben Staerke wie
     alle uebrigen Trennlinien. */
  background: currentColor;
  opacity: 0.16;
  transition: opacity 0.5s var(--ease);
}

.header.is-solid {
  background: var(--paper);
  color: var(--ink);
}
.header.on-light { color: var(--ink); }
.header.is-hidden { transform: translateY(-104%); }

.wordmark {
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  white-space: nowrap;
  justify-self: center;
  transition: opacity 0.4s var(--ease);
}
.wordmark:hover { opacity: 0.6; }

/* Marke in der Kopfzeile. Die Datei ist schwarz auf transparent; über dem
   dunklen Intro dreht der Filter sie ins Helle, statt eine zweite Datei
   auszuliefern. */
.mark {
  justify-self: center;
  display: block;
  transition: opacity 0.4s var(--ease);
}
.mark:hover { opacity: 0.6; }
.mark img {
  width: clamp(2.1rem, 3vw, 2.6rem);
  height: auto;
  filter: invert(1);
  transition: filter 0.6s var(--ease);
}
.header.on-light .mark img,
.header.is-solid .mark img { filter: none; }

/* Sprache, Konto und Warenkorb enger zusammen - Vorgabe 21.08.2026. Am
   Schirm standen 32 Pixel zwischen den dreien; das las sich als drei
   einzelne Dinge statt als eine Gruppe. Jetzt 20.

   Nur der Hoechstwert faellt, der Mindestwert bleibt bei 1rem: am Telefon
   war der Abstand ohnehin schon dort, die Aenderung wirkt also am Schirm,
   wo sie gemeint war.

   Weiter als 20 wollte ich nicht: die unsichtbaren Trefferflaechen der
   beiden Symbole sind je 2,75rem breit (`.icon-btn::after`) und stossen
   bei diesem Abstand genau aneinander, ohne sich zu ueberlappen. Enger
   und man trifft beim Zielen das falsche Zeichen. Nachgemessen. */
.nav { display: flex; align-items: center; gap: clamp(1rem, 1.3vw, 1.25rem); }
.nav--end { justify-self: end; }

.nav a, .nav span {
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
}
.nav a, .nav span { position: relative; padding-block: 0.4em; }
.nav a::before, .nav .is-current::before {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 2.5rem);
  height: 2.75rem;
  transform: translate(-50%, -50%);
}
/* Der Unterstrich gehoert zu den Textverweisen (DE / EN / Service). Die
   Symbolknoepfe liegen in derselben Navigation und bekamen ihn mit - unter
   einem Symbol sah das aus wie ein Strich, der dorthin verirrt ist. */
.nav a:not(.icon-btn)::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.5s var(--ease);
}
.nav a:not(.icon-btn):hover::after { transform: scaleX(1); transform-origin: left; }
.nav .is-current { opacity: 0.5; }

/* Sprachumschalter -------------------------------------------------------- */

.lang { position: relative; }

.lang__btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  white-space: nowrap;
  color: inherit;
  padding-block: 0.4em;
}
.lang__arrow {
  width: 0.5rem;
  height: 0.5rem;
  /* Der Pfeil sitzt optisch zu tief, weil die Versalien der Schrift keine
     Unterlaenge haben. Ein Hauch nach oben bringt ihn auf die Mittellinie. */
  margin-top: -0.1em;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.4s var(--ease);
}
.lang[data-open] .lang__arrow { transform: rotate(180deg); }

.lang__list {
  position: absolute;
  top: calc(100% + 0.85rem);
  right: 0;
  z-index: 60;
  min-width: 9.5rem;
  padding: 0.5rem 0;
  list-style: none;
  background: var(--paper);
  color: var(--ink);
  border: 1px solid rgba(13, 26, 47, 0.1);
  box-shadow: 0 18px 40px -24px rgba(13, 26, 47, 0.5);
}
.lang__list[hidden] { display: none; }

.lang__list a,
.lang__on {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  padding: 0.5rem 1rem;
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  color: inherit;
}
/* Der Unterstrich der Navigation gehoert hier nicht hin — im Menue liegen die
   Eintraege untereinander, ein Strich unter jedem sieht aus wie ein Raster. */
.lang__list a::after { content: none; }
/* Ebenso die unsichtbare Klickflaeche der Navigation: 2,75 rem hoch und
   mittig — im Menue ueberlappte sie den Nachbareintrag und fing dessen
   Klicks ab. Die Zeilen sind hier von sich aus gross genug. */
.lang__list a::before { content: none; }
.lang__list a:hover { background: var(--bone); }
.lang__on { opacity: 0.45; }
.lang__code { min-width: 1.6rem; opacity: 0.5; }

/* Klickfläche vergrößern, ohne die Optik zu verändern: ein unsichtbares
   Pseudo-Element dehnt das Ziel über die sichtbaren Maße hinaus. WCAG 2.5.8
   verlangt mindestens 24 × 24 px — die Symbole selbst bleiben unverändert. */
.hit { position: relative; }
.hit::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 2.75rem);
  height: max(100%, 2.75rem);
  transform: translate(-50%, -50%);
}

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
}
.icon-btn::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.75rem;
  height: 2.75rem;
  transform: translate(-50%, -50%);
}
/* flex: none ist noetig, nicht kosmetisch. Das Zeichen hat nur eine viewBox
   und keine eigene Breite; als schrumpfbares Flex-Kind loeste sich seine
   Breite gegen den Elternteil auf, der sich wiederum aus dem Inhalt ergibt -
   das Ergebnis war 0,1 px. Sichtbar blieb es nur, weil SVG ueber seinen
   Rahmen hinaus zeichnet; im Raster nahm es keinen Platz ein. */
.icon-btn svg {
  flex: none;
  width: 1.15rem;
  height: 1.15rem;
  /* `min-width` und `min-height` gehoeren dazu, nicht nur width/height.
     Ein inline-SVG ohne eigene Massangaben rechnet Safari in einem
     Flexkasten unter Umstaenden auf null - sichtbar blieb dann nur das
     Abzeichen am Warenkorb, und Personen- wie Korbsymbol fehlten ganz.
     Auf dem Telefon gemeldet am 20.08.2026, im Testbrowser nicht
     nachstellbar. Die Massangaben stehen jetzt zusaetzlich im Markup. */
  min-width: 1.15rem;
  min-height: 1.15rem;
  stroke: currentColor;
  fill: none;
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  overflow: visible;
}

/* Burger */
.burger {
  width: 2.2rem;
  height: 2.2rem;
  position: relative;
  justify-self: start;
}
.burger span {
  position: absolute;
  left: 50%;
  width: 1.1rem;
  height: 1px;
  background: currentColor;
  transform: translateX(-50%);
  transition: transform 0.5s var(--ease), opacity 0.3s var(--ease);
}
/* Drei Striche statt zwei, und schmaler: zwei Striche lesen sich eher als
   Gleichheitszeichen denn als Menue. Beim Oeffnen wird der mittlere
   unsichtbar, die aeusseren kreuzen sich. */
.burger span:nth-child(1) { top: 0.78rem; }
.burger span:nth-child(2) { top: 1.08rem; }
.burger span:nth-child(3) { top: 1.38rem; }
body.menu-open .burger span:nth-child(1) { transform: translateX(-50%) translateY(0.3rem) rotate(45deg); }
body.menu-open .burger span:nth-child(2) { opacity: 0; }
body.menu-open .burger span:nth-child(3) { transform: translateX(-50%) translateY(-0.3rem) rotate(-45deg); }

/* Vollbildmenü */
/* Zwei Spalten bis an den Rand: links Schrift mit Innenabstand, rechts die
   Aufnahme ohne. Der Innenabstand sitzt deshalb auf .menu__side und nicht
   auf .menu - sonst bliebe rechts ein Streifen Hintergrund stehen. */
.menu {
  position: fixed;
  inset: 0;
  z-index: 80;
  background: var(--ink);
  color: var(--paper);
  display: grid;
  /* Genau die Haelfte. 46vw teilte bei 54 Prozent - sichtbar daneben. */
  grid-template-columns: 1fr 1fr;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 0.85s var(--ease);
  visibility: hidden;
}
.menu__side {
  display: grid;
  grid-template-rows: 1fr auto;
  padding: 7rem clamp(2rem, 5vw, 5rem) 3rem;
  min-height: 0;
}
/* Die Liste steht mittig im Raum ueber der Fusszeile. Vorher war die Flaeche
   eine Flex-Spalte mit justify-content:center - wirkungslos, weil die
   Fusszeile mit margin-top:auto alles nach oben drueckte. */
.menu__side nav { align-self: center; }
body.menu-open .menu { clip-path: inset(0 0 0 0); visibility: visible; }

.menu__list a {
  font-family: var(--f-display);
  /* Zwei Pixel groesser an beiden Enden der Spanne, damit der Zuwachs auf
     jeder Fensterbreite ankommt und nicht nur im geklemmten Bereich. */
  font-size: clamp(1.58rem, 3.26vw, 2.48rem);
  line-height: 1.34;
  display: block;
  opacity: 0;
  transform: translateY(1rem);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease), color 0.4s var(--ease);
}
body.menu-open .menu__list a { opacity: 1; transform: none; }
/* Eine Verzoegerung je Eintrag. */
body.menu-open .menu__list li:nth-child(1) a { transition-delay: 0.18s; }
body.menu-open .menu__list li:nth-child(2) a { transition-delay: 0.23s; }
body.menu-open .menu__list li:nth-child(3) a { transition-delay: 0.28s; }
body.menu-open .menu__list li:nth-child(4) a { transition-delay: 0.33s; }
body.menu-open .menu__list li:nth-child(5) a { transition-delay: 0.38s; }

.menu__art {
  position: relative;
  overflow: hidden;
  background: #0b1119;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  transition-delay: 0.28s;
}
body.menu-open .menu__art { opacity: 1; }
.menu__video { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Die Aufnahme steht auch im Auftragsfeld der Sortimentseite; dort hat sie
   keinen Schleier und braucht eigene Masse. */
.split__art .aside__video { position: static; width: 100%; height: 100%;
                            object-fit: cover; opacity: 1; }

/* Derselbe Ton wie ueber der Flaeche auf der Startseite, aber schwaecher:
   dort traegt der Schleier weisse Schrift und muss auf 0,74 bis 0,86 gehen,
   hier steht keine Schrift darauf. Er stimmt die Aufnahme nur auf das
   Tintenblau des Menues ein. */
.menu__art::after {
  content: "";
  position: absolute; inset: 0;
  pointer-events: none;
  /* Genau derselbe Verlauf wie ueber der Flaeche auf der Startseite: 165
     Grad, 0,66 auf 0,78, zwei Stufen. Vorher standen hier drei Stufen mit
     einem harten Stopp bei 130 px - das war heller und hatte an der Stelle
     eine sichtbare Kante. Der Anfangswert 0,66 traegt zugleich die weissen
     Zeichen der durchsichtigen Kopfleiste. */
  background: linear-gradient(165deg, rgba(6, 10, 18, 0.66), rgba(3, 6, 11, 0.78));
}

/* Auf schmalen Fenstern steht die Schrift allein. Ein Video unter der
   Navigation waere ein Bild, das niemand sucht - und es laedt dort auch
   nicht, weil die Flaeche display:none traegt. */
@media (max-width: 900px) {
  .menu { grid-template-columns: 1fr; }
  .menu__art { display: none; }
}

.menu__foot {
  margin-top: auto;
  padding-top: 2.5rem;
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem 2rem;
  justify-content: space-between;
  border-top: var(--rule) solid var(--ink-line);
}

/* --------------------------------------------------------------------------
   8. Medienflächen
   Platzhalter für Film und Fotografie: dunkler Verlauf, Korn, Zeichnung.
   -------------------------------------------------------------------------- */

.media {
  position: relative;
  overflow: hidden;
  background:
    radial-gradient(78% 62% at 50% 38%, rgba(185, 154, 88, 0.24) 0%, transparent 66%),
    linear-gradient(165deg, #17202f 0%, #0c1424 58%, #070d18 100%);
  display: grid;
  place-items: center;
  isolation: isolate;
}
.media > img {
  width: min(58%, 30rem);
  position: relative;
  z-index: 2;
  animation: drift 22s var(--ease-io) infinite;
}
.media--wide > img { width: min(46%, 40rem); }

@keyframes drift {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.05); }
}

.media--hero {
  /* Volle Fensterhoehe, ohne Deckel: die erste Ansicht gehoert dem Bild.
     svh statt vh, damit die Adressleiste auf dem Telefon nicht abschneidet. */
  min-height: 100svh;
  background:
    radial-gradient(120% 80% at 74% 20%, rgba(185, 154, 88, 0.24) 0%, transparent 58%),
    radial-gradient(90% 70% at 14% 94%, rgba(185, 154, 88, 0.12) 0%, transparent 62%),
    linear-gradient(180deg, #141d2c 0%, #0b1322 55%, #05090f 100%);
}
.media--hero > img { width: min(78vw, 46rem); }

/* Kampagnenmotiv ueber die ganze erste Ansicht. Die Regel darueber gilt dem
   ornamentalen Platzhalter und wuerde das Foto auf 78 vw schrumpfen - daher
   eine eigene Klasse statt eines Ueberschreibens per Element. */
.media--hero .hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Die Armbaender liegen rechts der Mitte. Auf breiten Schirmen bleibt der
     Ausschnitt mittig; wird das Fenster schmaler, wandert er nach rechts,
     damit nicht die leere Flaeche uebrig bleibt und das Motiv wegfaellt. */
  object-position: 62% center;
  z-index: 0;
}
/* Der Banner fuellt die erste Ansicht immer vollstaendig - 100 svh, kein
   Deckel. Das heisst: der Ausschnitt haengt an der Fensterform, und das Bild
   wird je nach Rechner unterschiedlich beschnitten. Damit das nie stoert,
   muss das Motiv in der Mitte liegen und an allen vier Raendern Luft haben.
   Die Masse dafuer stehen in eingang/README.txt.

   Entscheidend ist die Ausrichtung, nicht die Breite: ein hochkant
   gehaltenes Tablet ist 1024 px breit und braucht trotzdem das Hochformat. */
@media (orientation: landscape) {
  .media--hero .hero__img { object-position: center; }
}
@media (orientation: portrait) {
  .media--hero .hero__img { object-position: center 42%; }
}
/* Der Schleier traegt allein den Scroll-Hinweis und die Kopfzeile darueber.
   Ohne ihn verschwindet beides im hellen Holz der Bildmitte. */
.hero__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to bottom, rgba(5, 9, 15, 0.55) 0%, rgba(5, 9, 15, 0) 26%),
    linear-gradient(to top, rgba(5, 9, 15, 0.6) 0%, rgba(5, 9, 15, 0) 34%);
}

/* Auf dem Telefon laeuft kein Video - dort steht das Standbild, und das ist
   heller als die Bewegung darueber je war. Die weisse Wortmarke der
   Kopfzeile stand darauf hart an der Lesegrenze. Der Schleier zieht hier
   deshalb kraeftiger an; am Schreibtisch bleibt er, wie er ist. */
@media (max-width: 900px) {
  .hero__veil {
    background:
      linear-gradient(to bottom,
        rgba(4, 7, 12, 0.62) 0%,
        rgba(4, 7, 12, 0.28) 26%,
        rgba(4, 7, 12, 0.22) 62%,
        rgba(4, 7, 12, 0.58) 100%);
  }
}
.media--hero .scroll-cue { z-index: 2; }

.media--band { min-height: clamp(24rem, 62vh, 40rem); }

/* Mittig ueber die ganze Breite statt ueber left:50% plus translateX(-50%).
   Der Versatz war die halbe Elementbreite - bei ungerader Breite also ein
   halber Bildpunkt, und Schrift auf einem halben Bildpunkt wird weich
   gerastert. Gemessen: -44,695 px. So gibt es keinen Versatz mehr, den man
   krumm bekommen koennte. */
.scroll-cue {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(1.6rem, 4vh, 3rem);
  margin-inline: auto;
  width: max-content;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.8rem;
  color: rgba(255, 255, 255, 0.7);
}
.scroll-cue i {
  display: block;
  width: 1px;
  height: 3rem;
  background: rgba(255, 255, 255, 0.25);
  position: relative;
  overflow: hidden;
}
.scroll-cue i::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--gold);
  animation: cue 2.6s var(--ease-io) infinite;
}
@keyframes cue {
  0%   { transform: translateY(-100%); }
  60%  { transform: translateY(100%); }
  100% { transform: translateY(100%); }
}

/* --------------------------------------------------------------------------
   9. Statement-Band
   -------------------------------------------------------------------------- */

.statement {
  background: var(--bone);
  text-align: center;
  padding-block: clamp(4.5rem, 12vh, 9rem);
}
.statement--paper { background: var(--paper); }

.statement__title { margin: clamp(1.2rem, 2.5vw, 2rem) 0 clamp(1.4rem, 3vw, 2.2rem); }
.statement__title .script { font-size: 1.12em; margin-right: 0.1em; }

/* Ein Kapitel unter einer Aufnahme braucht keine Schauzeile: die Aufnahme ist
   die Schau. Der Satz rueckt naeher zusammen und bleibt auf Bildunterschrift
   gestimmt, damit die grossen Zeilen dem Auftakt und dem Schluss gehoeren. */
.statement__satz { margin: clamp(0.9rem, 2vw, 1.4rem) 0 clamp(1.1rem, 2.2vw, 1.6rem); }

.statement p {
  max-width: 46ch;
  margin-inline: auto;
  color: var(--ink);
}
/* Zwei Absaetze hintereinander. Der Reset setzt jedes p auf margin 0, und
   bis zum 23.08.2026 trug keine dieser Flaechen mehr als einen Absatz -
   der zweite klebte damit am ersten. Kleiner als der Abstand zur Zeile
   darueber: es ist derselbe Gedanke, nur weitergefuehrt. */
.statement p + p { margin-top: clamp(0.8rem, 1.6vw, 1.15rem); }
.statement .btn { margin-top: clamp(2rem, 4vw, 3.2rem); }

/* --------------------------------------------------------------------------
   10. Doppelbild — Ikonen / Editionen
   -------------------------------------------------------------------------- */

.duo {
  display: flex;
  min-height: 92svh;
  background: var(--ink);
}
.duo__half {
  position: relative;
  flex: 1 1 50%;
  display: grid;
  place-items: center;
  overflow: hidden;
  transition: flex-basis 0.9s var(--ease);
}
.duo__half + .duo__half { border-left: var(--rule) solid rgba(255, 255, 255, 0.18); }
.duo:hover .duo__half { flex-basis: 42%; }
.duo__half:hover { flex-basis: 58%; }

.duo__art {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: grid;
  place-items: center;
  background:
    radial-gradient(70% 55% at 50% 45%, rgba(185, 154, 88, 0.2), transparent 70%),
    linear-gradient(160deg, #1a2231, #080d16);
}
.duo__art img {
  width: min(46%, 20rem);
  transition: transform 1.1s var(--ease);
}
.duo__half:hover .duo__art img { transform: scale(1.07); }

.duo__label {
  text-shadow: 0 2px 26px rgba(0, 0, 0, 0.6);
  position: relative;
  z-index: 2;
  font-family: var(--f-display);
  font-size: clamp(2.2rem, 5vw, 4.6rem);
  line-height: 1;
  color: #fff;
  text-align: center;
  padding-inline: 1rem;
}
.duo__sub {
  display: block;
  margin-top: 1.1rem;
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.66);
}

/* --------------------------------------------------------------------------
   11. Medienstreifen
   -------------------------------------------------------------------------- */

.strip { display: grid; grid-template-columns: repeat(3, 1fr); }
.strip .media { min-height: clamp(18rem, 44vh, 30rem); }
.strip .media + .media { border-left: var(--rule) solid rgba(255, 255, 255, 0.12); }
.strip .media > img { width: min(52%, 16rem); }

/* --------------------------------------------------------------------------
   12. Karte
   -------------------------------------------------------------------------- */

.map {
  background: var(--ink);
  color: var(--paper);
  padding-block: clamp(4rem, 10vh, 8rem);
  overflow: hidden;
}
.map__head { text-align: center; margin-bottom: clamp(2rem, 5vw, 4rem); }

.map__stage {
  position: relative;
  width: min(100%, 72rem);
  margin-inline: auto;
}
.map__stage > svg { width: 100%; height: auto; }
.map__land { fill: #9aa3b4; stroke: #9aa3b4; stroke-width: 7; stroke-linejoin: round; }

/* Der Pin ist ein Punkt ohne Ausdehnung — Linie und Schrift hängen daran,
   damit der Punkt exakt auf der Stadt sitzt. */
.pin {
  position: absolute;
  width: 0;
  height: 0;
  --pin-line: 7rem;
}
.pin__dot {
  position: absolute;
  left: 0;
  top: 0;
  width: 0.6rem;
  height: 0.6rem;
  margin: -0.3rem 0 0 -0.3rem;
  border-radius: 50%;
  background: var(--gold);
}
.pin__dot::after {
  content: "";
  position: absolute;
  inset: -0.45rem;
  border-radius: 50%;
  border: 1px solid rgba(185, 154, 88, 0.5);
  animation: ping 3.4s var(--ease-io) infinite;
}
@keyframes ping {
  0%, 100% { transform: scale(0.8); opacity: 0.8; }
  50%      { transform: scale(1.25); opacity: 0.2; }
}

.pin__line {
  position: absolute;
  top: 0;
  height: 1px;
  width: var(--pin-line);
  background: rgba(185, 154, 88, 0.55);
}
.pin__label {
  position: absolute;
  top: 0;
  transform: translateY(-50%);
  white-space: nowrap;
}
.pin__place {
  display: block;
  font-family: var(--f-script);
  font-size: clamp(1.4rem, 2.2vw, 2rem);
  line-height: 1;
  color: var(--paper);
}
.pin__house {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(237, 239, 247, 0.78);
}

/* Ersatz für schmale Fenster, per Media Query eingeblendet */
.map__list {
  display: none;
  gap: 1.6rem;
  margin-top: clamp(2rem, 6vw, 3rem);
  text-align: center;
}
.map__list .pin__place, .map__list .pin__house { display: block; }

.pin--right .pin__line { left: 0.5rem; }
.pin--right .pin__label { left: calc(0.5rem + var(--pin-line) + 0.9rem); }

.pin--left .pin__line { right: 0.5rem; }
.pin--left .pin__label { right: calc(0.5rem + var(--pin-line) + 0.9rem); text-align: right; }

/* --------------------------------------------------------------------------
   13. Häuser-Karussell
   -------------------------------------------------------------------------- */

.carousel { background: var(--bone); padding-block: clamp(3rem, 8vh, 6rem); overflow: hidden; }

.carousel__track {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1rem, 2.5vw, 2.5rem);
}

.house {
  position: relative;
  flex: 0 0 auto;
  width: clamp(11rem, 17vw, 17rem);
  aspect-ratio: 3 / 4;
  overflow: hidden;
  transition: width 0.8s var(--ease);
  background:
    radial-gradient(70% 55% at 50% 40%, rgba(185, 154, 88, 0.22), transparent 70%),
    linear-gradient(158deg, #1b2432, #080e18);
  color: #fff;
  cursor: pointer;
}
.house.is-active { width: clamp(18rem, 36vw, 36rem); cursor: default; }

.house__art {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}
.house__art img { width: 58%; opacity: 0.7; }
.house.is-active .house__art img { width: 46%; opacity: 0.42; }

/* Nur die vordere Karte trägt Schrift — wie in der Vorlage. */
.house__body {
  position: relative;
  z-index: 2;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  align-items: center;
  text-align: center;
  padding: clamp(2rem, 4vw, 3.6rem) 1.5rem;
  opacity: 0;
  transition: opacity 0.6s var(--ease);
}
.house.is-active .house__body { opacity: 1; transition-delay: 0.25s; }
.house:not(.is-active) .house__body { pointer-events: none; }

.house__name {
  font-family: var(--f-ext);
  font-size: clamp(1rem, 1.8vw, 1.7rem);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  line-height: 1.3;
}
.house__brand {
  display: block;
  margin-top: 0.9rem;
  font-family: var(--f-ext);
  font-size: 0.58rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.72);
}
.house__city {
  font-family: var(--f-ext);
  font-size: 0.72rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
}

.carousel__dots {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
}
.carousel__dots button {
  width: 2.2rem;
  height: 1px;
  background: rgba(13, 26, 47, 0.28);
  transition: background 0.4s var(--ease);
}
.carousel__dots button[aria-current="true"] { background: var(--ink); }

/* --------------------------------------------------------------------------
   14. Doppelpanel — Geschichte / Handwerk
   -------------------------------------------------------------------------- */

.panels { display: grid; grid-template-columns: 1fr 1fr; }
.panel {
  position: relative;
  min-height: clamp(30rem, 88svh, 52rem);
  display: flex;
  align-items: flex-end;
  padding: clamp(2rem, 4vw, 4rem);
  overflow: hidden;
  color: #fff;
  background:
    radial-gradient(70% 60% at 50% 40%, rgba(185, 154, 88, 0.18), transparent 72%),
    linear-gradient(160deg, #18212f, #070c15);
}
.panel + .panel { border-left: var(--rule) solid rgba(255, 255, 255, 0.14); }
/* Verlauf nach unten, damit die Schrift auf jedem Motiv trägt */
.panel::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background: linear-gradient(to top, rgba(5, 9, 16, 0.8) 0%, rgba(5, 9, 16, 0.2) 46%, transparent 72%);
}
.panel__art {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  opacity: 0.55;
}
.panel__art img { width: min(50%, 20rem); }
.panel__body { position: relative; z-index: 2; max-width: 34ch; }
.panel__title {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(2.2rem, 4.4vw, 4rem);
  line-height: 1;
}
.panel__body p { margin: 1.2rem 0 0; color: rgba(255, 255, 255, 0.76); }
.panel__body .btn { margin-top: 1.8rem; }

/* --------------------------------------------------------------------------
   15. Einladung
   -------------------------------------------------------------------------- */

/* Volle Fensterhoehe. Der Abschnitt ist der einzige Moment auf der Startseite,
   in dem ein Bild den Bildschirm allein fuellt - halbe Hoehe nimmt ihm genau
   das. svh statt vh, damit die Adressleiste des Telefons nicht abschneidet;
   die Obergrenze verhindert, dass der Text auf einem hohen Monitor in einer
   leeren Flaeche schwimmt. */
.invite {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  min-height: min(100svh, 62rem);
}
.invite__art {
  min-height: clamp(24rem, 70svh, 44rem);
  background:
    radial-gradient(65% 55% at 50% 45%, rgba(185, 154, 88, 0.22), transparent 72%),
    linear-gradient(150deg, #1a2331, #070d16);
  display: grid;
  place-items: center;
}
.invite__art img { width: min(58%, 22rem); }
.invite__body {
  background: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 1.4rem;
  padding: clamp(3rem, 7vw, 7rem) clamp(1.5rem, 5vw, 5rem);
}
/* Nur fuer die geteilte Fassung, wo der Text auf hellem Grund steht. Vorher
   galt die Regel fuer jedes <p> in jedem Einladungsabschnitt - auf dem
   vollflaechigen Motiv standen Kicker und Text dadurch in Tintenblau auf
   dunklem Bild. Abtrennen statt Spezifitaet dagegenstellen: sonst kaempfen
   zwei Regeln um dieselben Elemente und die naechste Aenderung kippt es
   wieder. */
/* Die geteilte Fassung ist seit dem 17.08.2026 ebenfalls ausgenommen. Sie
   setzt ihre Abstaende selbst und vollstaendig; dieses margin-top kam dort
   zum Flex-Abstand und zum Rand der Ueberschrift hinzu. */
.invite:not(.invite--full):not(.invite--geteilt) .invite__body p {
  max-width: 40ch;
  margin-top: 1.4rem;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   15b. Zwei Felder: Geschichte und Material
   -------------------------------------------------------------------------- */

/* Zwei bildfuellende Felder nebeneinander, Text darauf. Volle Fensterhoehe,
   damit das Bild den Bildschirm allein traegt - halbe Hoehe liest sich als
   Zierstreifen, nicht als Kapitel. */
.duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: min(100svh, 62rem);
}
/* Gestapelt wird ausschliesslich mit positiven Werten: Bild 0, Verlauf 1,
   Text 2. Mit negativen Werten lagen Bild und Verlauf hinter dem Hintergrund
   der Seite - sichtbar blieb weisse Schrift auf hellem Grund, also nichts. */
/* Der <picture>-Wrapper darf keine eigene Box bilden. Das Bild darin ist
   absolut positioniert, also blieb picture als Null-Element im Fluss stehen -
   und das verzoegerte Laden richtet sich nach der Lage im Layout. display:
   contents nimmt den Wrapper aus dem Fluss, ohne die Bildauswahl zu stoeren. */
.duo__panel picture, .media--hero picture, .pahero picture { display: contents; }

.duo__panel {
  position: relative;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
}
.duo__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Der Verlauf liegt nur ueber dem unteren Teil. Ein Schleier ueber dem
   ganzen Bild wuerde es truebe machen; hier traegt er allein die Schrift. */
.duo__panel::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 70%;
  z-index: 1;
  background: linear-gradient(to top,
    rgba(7, 13, 22, 0.82) 0%,
    rgba(7, 13, 22, 0.55) 38%,
    rgba(7, 13, 22, 0) 100%);
}
.duo__text {
  position: relative;
  z-index: 2;
  padding: clamp(2rem, 4vw, 4.5rem);
  color: #fff;
  max-width: 34rem;
  /* Ein festes Raster statt freiem Fluss: Kicker, Titel, Text und Knopf
     bekommen je eine Zeile im Raster. Damit stehen sie in beiden Feldern auf
     derselben Hoehe, auch wenn der Titel einmal umbricht und einmal nicht.
     Die Texte sind zusaetzlich gleich lang gehalten - beides zusammen haelt
     die Zeilen wirklich buendig. */
  display: grid;
  align-content: end;
  grid-template-rows: auto minmax(2.2em, auto) auto auto;
  gap: 0;
}
.duo__title { color: #fff; margin-top: 0.9rem; align-self: end; }
.duo__lede {
  margin-top: 1.1rem;
  /* Gleiche Zeilenzahl in beiden Feldern, unabhaengig von der Fensterbreite. */
  min-height: calc(2 * 1.7em);
  /* 34ch zwang den Materialsatz in drei Zeilen - bei rund hundert Zeichen
     braucht er 50 je Zeile, um in zwei zu passen. Vorgabe 19.08.2026. */
  max-width: 52ch;
  color: rgba(255, 255, 255, 0.86);
}
.duo__text .btn { margin-top: 1.8rem; }

/* Auf dem Telefon untereinander. Nebeneinander waere jedes Feld so schmal,
   dass die Ueberschrift in vier Zeilen bricht. */
@media (max-width: 900px) {
  .duo { grid-template-columns: 1fr; min-height: 0; }
  .duo__panel { min-height: 78svh; }
}

/* --------------------------------------------------------------------------
   16. Newsletter
   -------------------------------------------------------------------------- */

.news {
  background: var(--paper);
  text-align: center;
  padding-block: clamp(4rem, 10vh, 7rem);
}
.news p { max-width: 44ch; margin: 1.4rem auto 0; color: var(--ink); }

.news__form {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  margin-top: clamp(2rem, 4vw, 3rem);
}
.news__form input {
  width: min(100%, 26rem);
  font-family: var(--f-sans);
  font-size: 1rem;
  color: var(--ink);
  background: transparent;
  border: var(--rule) solid rgba(13, 26, 47, 0.3);
  border-radius: 0.3rem;
  /* Der Text sass zu hoch: 1rem oben und unten plus eine Zeilenhoehe, die
     groesser war als die Schrift. Feste Hoehe und mittige Ausrichtung setzen
     ihn genau in die Mitte, linksbuendig wie zuvor. */
  height: 3.4rem;
  padding: 0 1.3rem;
  /* line-height: 1 stand hier und war der Fehler: Eingabefelder zentrieren
     ihren Text von sich aus senkrecht, solange die Zeilenhoehe nicht
     festgenagelt ist. Mit 1 sass er im oberen Drittel. */
  line-height: normal;
  text-align: left;
}
.news__form input::placeholder { color: rgba(13, 26, 47, 0.45); }
.news__form input:focus { outline: none; border-color: var(--gold); }
.news__form .news__status {
  /* Spezifität muss über `.news p` liegen (0,1,1), sonst gewinnen dessen
     max-width und auto-Seitenränder: max-width verhindert den Umbruch,
     die auto-Margins schlucken den freien Raum und setzen damit
     justify-content der Zeile außer Kraft. */
  flex: 0 0 100%;
  max-width: none;
  margin: 0;
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  min-height: 1.2em;
}

/* --------------------------------------------------------------------------
   17. Fußzeile
   -------------------------------------------------------------------------- */

.footer { background: var(--paper); color: var(--ink); }

/* Der Schriftzug bekommt oben dieselbe Linie wie die Leiste darunter - sonst
   steht der Abschluss ohne Anfang im Raum. Die Linie laeuft ueber die volle
   Breite, deshalb traegt sie der Wrapper und nicht .footer__brand, das im
   .shell-Raster sitzt und dadurch eingerueckt waere. */
.footer__top { border-top: var(--rule) solid var(--bone-line); }
.footer__brand {
  text-align: center;
  padding-block: clamp(3rem, 7vw, 5.5rem);
}
.footer__logo {
  width: clamp(3.2rem, 5vw, 4.5rem);
  height: auto;
  margin: 0 auto clamp(1.4rem, 3vw, 2rem);
}
/* Dieselbe Schrift wie EN / DE im Kopf, nicht die Anzeigeschrift. Der
   Schriftzug ist eine Marke, kein Titel - und als Marke gehoert er in die
   schmale Grotesk, in der auch die Navigation steht. */
.footer__mark {
  font-family: var(--f-ext);
  /* Kleiner als zuvor. Ohne Zeichen darueber traegt der Schriftzug den
     Abschluss allein - dafuer muss er nicht gross sein, sondern ruhig. */
  font-size: clamp(0.95rem, 1.6vw, 1.25rem);
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  display: block;
}
.footer__sub {
  display: block;
  margin-top: 0.7rem;
  font-family: var(--f-ext);
  font-size: 0.6rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

.footer__bar { border-top: var(--rule) solid var(--bone-line); }
/* Der knappe Fuss der Kasse: eine umbrechende Reihe mit den
   Rechtsverweisen, darunter die Zeile mit dem Jahr. Sonst nichts.

   Grund: der Fuss war der einzige Grund, warum die Kasse ueberhaupt
   scrollte. Gemessen am 21.08.2026 auf 812 Pixeln Hoehe - die Kasse selbst
   endete bei 641, der volle Fuss mass 531 und schob die Seite auf 1204.
   Vorgabe an dem Tag: einmal nach unten scrollen ist einmal zu viel. */
.footer--knapp {
  border-top: var(--rule) solid var(--bone-line);
  padding-block: 1.1rem 1.3rem;
}
.footer__knapplinks {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1.1rem;
}
.footer__knapplinks a, .footer__knapplinks .footer__cc {
  font-size: 0.78rem;
  color: var(--muted-dark);
  padding: 0.3rem 0;
}
.footer--knapp .footer__copy {
  margin-top: 0.6rem;
  padding: 0;
  font-size: 0.74rem;
  color: var(--muted-dark);
}
/* Drei Spalten statt space-between: nur so liegen die Social-Icons wirklich
   in der Mitte der Leiste und nicht dort, wo die Nachbarn Platz lassen.
   Aussen gleich breit, damit die Mitte die Mitte bleibt. */
.footer__bar-inner {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1.2rem 2rem;
  padding-block: 1.4rem;
}
.footer__bar-inner > :last-child { justify-self: end; }
.footer__links { display: flex; flex-wrap: wrap; align-items: center;
                 gap: clamp(1rem, 2.5vw, 2.4rem); }
/* Der Cookie-Knopf ist ein <button>, sieht aber wie die Verweise daneben aus -
   sonst steht er als fetter Fremdkoerper am Rand. */
.footer__links a, .footer__link {
  font-family: inherit; font-size: 0.9rem; font-weight: inherit;
  color: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  transition: color 0.4s var(--ease);
}

.footer__social { display: flex; justify-content: center; gap: 1.1rem; }
.footer__social a {
  display: inline-flex;
  position: relative;
  transition: color 0.4s var(--ease);
}
.footer__social a::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 2.75rem;
  height: 2.75rem;
  transform: translate(-50%, -50%);
}
.footer__social svg { width: 1.1rem; height: 1.1rem; fill: none; stroke: currentColor; stroke-width: 1.3; }

.footer__copy {
  border-top: var(--rule) solid var(--bone-line);
  text-align: center;
  padding-block: 1.4rem;
  font-size: 0.85rem;
  color: var(--muted-dark);
}

/* --------------------------------------------------------------------------
   18. Unterseiten
   -------------------------------------------------------------------------- */

.page-head {
  padding-top: clamp(8rem, 18vh, 13rem);
  padding-bottom: clamp(3rem, 7vw, 6rem);
  background: linear-gradient(180deg, #131d2e, var(--ink));
  color: var(--paper);
  position: relative;
  overflow: hidden;
}
.page-head::before {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(60% 60% at 76% 24%, rgba(185, 154, 88, 0.2), transparent 62%);
}
.page-head .shell { position: relative; z-index: 2; }
.page-head__grid {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: end;
}

.sec-head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 1.5rem 3rem;
  padding-bottom: 2rem;
  border-bottom: var(--rule) solid var(--bone-line);
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.on-dark .sec-head { border-color: var(--ink-line); }
.sec-head__title { max-width: 20ch; }

.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 0.4rem;
  padding-block: 1.6rem;
  border-bottom: var(--rule) solid var(--bone-line);
  margin-bottom: clamp(2.5rem, 5vw, 4rem);
}
.filter {
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 0.75em 1.35em;
  border: var(--rule) solid var(--bone-line);
  border-radius: 999px;
  color: var(--muted-dark);
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease), background 0.4s var(--ease);
}
.filter:hover { color: var(--ink); border-color: var(--ink); }
.filter[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.pieces { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.5rem, 3vw, 3rem); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(1.5rem, 2.5vw, 2.5rem); }
.piece.is-out { display: none; }

.piece { display: block; position: relative; }
.piece__frame {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  background:
    radial-gradient(80% 60% at 50% 34%, rgba(185, 154, 88, 0.2), transparent 70%),
    linear-gradient(165deg, #1a2331 0%, #0c1322 62%, #070c15 100%);
}
.piece__frame img {
  position: absolute;
  inset: 0;
  margin: auto;
  width: 62%;
  transition: transform 1.1s var(--ease);
}
.piece:hover .piece__frame img { transform: scale(1.07) translateY(-1%); }

.piece__index { position: absolute; top: 1.3rem; left: 1.3rem; z-index: 2; }
.piece__tag {
  position: absolute;
  top: 1.15rem;
  right: 1.15rem;
  z-index: 2;
  font-family: var(--f-ext);
  font-size: 0.55rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--ink);
  background: var(--gold-light);
  padding: 0.42em 0.8em;
}
.piece__glow {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: radial-gradient(38% 30% at 50% 42%, rgba(226, 205, 156, 0.34), transparent 72%);
  opacity: 0;
  transition: opacity 0.9s var(--ease);
}
.piece:hover .piece__glow { opacity: 1; }

.piece__body {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding-top: 1.2rem;
  border-top: var(--rule) solid var(--bone-line);
  margin-top: 1.2rem;
}
.on-dark .piece__body { border-color: var(--ink-line); }
.piece__name { font-family: var(--f-display); font-size: clamp(1.2rem, 1.7vw, 1.55rem); line-height: 1.2; }
.piece__sub { display: block; margin-top: 0.35rem; color: var(--muted-dark); }
.piece__price { font-family: var(--f-ext); font-size: 0.66rem; letter-spacing: 0.16em; white-space: nowrap; }

.prose { max-width: 62ch; }
.prose p + p { margin-top: 1.5em; }
.prose h3 {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 2.4vw, 2.2rem);
  line-height: 1.14;
  margin: 2.4em 0 0.7em;
}

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2.5rem, 6vw, 6rem); align-items: center; }
.split__art {
  aspect-ratio: 4 / 5;
  display: grid;
  place-items: center;
  background:
    radial-gradient(70% 55% at 50% 45%, rgba(185, 154, 88, 0.2), transparent 70%),
    linear-gradient(150deg, #1a2331, #070d16);
}
.split__art img { width: 58%; }
/* Variante für Produktaufnahmen: heller Grund, damit multiply trägt */
.split__art--shot { background: var(--paper); }
.split__art--shot .shot { width: 86%; }

.steps { display: grid; grid-template-columns: repeat(4, 1fr); border-top: var(--rule) solid var(--ink-line); }
.step {
  padding: clamp(1.8rem, 3vw, 2.8rem) clamp(1.2rem, 2vw, 2.2rem) clamp(2.4rem, 4vw, 3.6rem);
  border-right: var(--rule) solid var(--ink-line);
  transition: background 0.6s var(--ease);
}
.step:last-child { border-right: 0; }
.step:hover { background: rgba(185, 154, 88, 0.07); }
.step h3 { font-family: var(--f-display); font-size: clamp(1.35rem, 2vw, 1.9rem); line-height: 1.1; margin: 1.6rem 0 0.9rem; }
.step p { color: var(--muted-light); font-size: 0.94rem; }

.timeline { border-top: var(--rule) solid var(--bone-line); }
.timeline li {
  display: grid;
  grid-template-columns: 9rem 1fr;
  gap: clamp(1rem, 3vw, 3rem);
  padding-block: clamp(1.6rem, 3vw, 2.4rem);
  border-bottom: var(--rule) solid var(--bone-line);
  transition: padding-left 0.6s var(--ease);
}
.timeline li:hover { padding-left: 0.8rem; }
.timeline h3 { font-family: var(--f-display); font-size: clamp(1.3rem, 2vw, 1.8rem); line-height: 1.14; margin-bottom: 0.5rem; }
.timeline .year { font-family: var(--f-display); font-size: clamp(1.3rem, 2vw, 1.8rem); color: var(--gold); }

.quote { text-align: center; max-width: 24ch; margin-inline: auto; }
.quote figcaption { margin-top: 2rem; }

.specs { border-top: var(--rule) solid var(--bone-line); }
.on-dark .specs { border-top-color: var(--ink-line); }
.specs li {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: 1rem;
  padding-block: 1.05rem;
  border-bottom: var(--rule) solid var(--bone-line);
}
.on-dark .specs li { border-bottom-color: var(--ink-line); }
.specs .k {
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.on-dark .specs .k { color: var(--muted-light); }
.specs .v { font-size: 0.98rem; }

/* Formular */
.form { display: grid; gap: 1.5rem; }
.form__row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.5rem; }
.field { position: relative; }
.field input, .field select, .field textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: var(--rule) solid var(--ink-line);
  color: var(--paper);
  font-family: var(--f-sans);
  font-size: 1rem;
  padding: 0.85rem 0 0.7rem;
  border-radius: 0;
  transition: border-color 0.5s var(--ease);
}
.field textarea { resize: vertical; min-height: 4.5rem; }
.field select { -webkit-appearance: none; appearance: none; cursor: pointer; }
.field select option { background: var(--ink); color: var(--paper); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--gold); }
.field label {
  font-family: var(--f-ext);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-light);
  display: block;
}
.field input::placeholder, .field textarea::placeholder { color: rgba(237, 239, 247, 0.35); }
.form__note { font-size: 0.78rem; color: var(--muted-light); }
.form__status {
  font-family: var(--f-ext);
  font-size: 0.65rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
  min-height: 1.2em;
}

/* --------------------------------------------------------------------------
   19. Scroll-Reveal
   -------------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(2rem);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
}
[data-reveal].is-in { opacity: 1; transform: none; }
[data-reveal][data-delay="1"] { transition-delay: 0.1s; }
[data-reveal][data-delay="2"] { transition-delay: 0.2s; }
[data-reveal][data-delay="3"] { transition-delay: 0.3s; }
[data-reveal][data-delay="4"] { transition-delay: 0.4s; }

/* --------------------------------------------------------------------------
   20. Responsive
   -------------------------------------------------------------------------- */

@media (max-width: 1100px) {
  .grid-4 { grid-template-columns: repeat(3, 1fr); }
  .steps { grid-template-columns: repeat(2, 1fr); }
  .step:nth-child(2) { border-right: 0; }
  .step:nth-child(-n+2) { border-bottom: var(--rule) solid var(--ink-line); }
  .strip { grid-template-columns: repeat(2, 1fr); }
  .strip .media:nth-child(3) { grid-column: 1 / -1; border-left: 0; }
}

@media (max-width: 900px) {
  :root { --head-h: 3.8rem; }
  .nav--end .nav-extra { display: none; }
  .split, .page-head__grid, .invite, .panels { grid-template-columns: 1fr; }
  .pieces { grid-template-columns: repeat(2, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .specs li { grid-template-columns: 8.5rem 1fr; }
  .panel + .panel { border-left: 0; border-top: var(--rule) solid rgba(255, 255, 255, 0.14); }
  .panel { min-height: 60svh; }

  .duo { flex-direction: column; min-height: 0; }
  .duo__half { min-height: 46svh; }
  .duo__half + .duo__half { border-left: 0; border-top: var(--rule) solid rgba(255, 255, 255, 0.18); }
  .duo:hover .duo__half, .duo__half:hover { flex-basis: auto; }

  .house { width: 68vw; }
  .house.is-active { width: 78vw; }

  /* Schmale Fenster: nur die Punkte auf der Karte, die Häuser darunter.
     Ohne Beschriftung wird der freie Rand links beschnitten. */
  .pin__label, .pin__line { display: none; }
  .map__list { display: grid; }
  .map__stage { width: 152%; margin: 0 0 0 -36%; }
}

@media (max-width: 640px) {
  .pieces, .grid-4 { grid-template-columns: 1fr; }
  .steps { grid-template-columns: 1fr; }
  .step { border-right: 0; border-bottom: var(--rule) solid var(--ink-line); }
  .form__row { grid-template-columns: 1fr; }
  .timeline li { grid-template-columns: 1fr; gap: 0.6rem; }
  .specs li { grid-template-columns: 1fr; gap: 0.2rem; }
  .strip { grid-template-columns: 1fr; }
  .strip .media + .media { border-left: 0; border-top: var(--rule) solid rgba(255, 255, 255, 0.12); }
  .footer__bar-inner { grid-template-columns: 1fr; justify-items: center; text-align: center; }
  .footer__bar-inner > :last-child { justify-self: center; }
  .footer__links { justify-content: center; }
  .news__form input { width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   21. Produktfotografie
   Die Aufnahmen liegen auf Weiß. `multiply` lässt den weißen Grund im
   Seitenton verschwinden, ohne dass die Aufnahmen freigestellt werden müssen.
   -------------------------------------------------------------------------- */

.shot { mix-blend-mode: multiply; width: 100%; height: auto; }

/* --------------------------------------------------------------------------
   Bildplatzhalter
   Steht dort, wo eine Aufnahme hingehört, die es noch nicht gibt. Benennt
   das fehlende Motiv, statt etwas zu zeigen, das es nicht gibt.
   -------------------------------------------------------------------------- */


/* Auf dunklen Flächen hell */


/* Liegt eine Überschrift darüber, rückt die Beschriftung in die Ecke,
   damit sie nicht mit ihr kollidiert. */


/* Jede Fläche, die eine Aufnahme trägt, braucht einen eigenen Hintergrund.
   Grund: die Reveal-Animation setzt opacity und transform, beides erzeugt
   einen Stacking Context. Darin blendet multiply nur noch gegen das, was
   innerhalb dieses Kontexts liegt — ohne Hintergrund also gegen nichts, und
   die Aufnahme zeigt kurz ihren weissen Grund. */
.card__frame,
.prod__frame,
.split__art--shot {
  display: block;
  /* Der Rahmen muss die Farbe des Abschnitts tragen, in dem er steht - nicht
     fest --paper. Die Aufnahmen haben weissen Grund und werden mit multiply
     eingeblendet; der Rahmen ist die Flaeche, gegen die geblendet wird. Steht
     dort eine andere Farbe als im Abschnitt, erscheint ein sichtbarer Kasten.
     Passiert genau so in .next, das auf --bone liegt. */
  background: var(--frame-bg, var(--paper));
}

/* Abschnitte, die nicht auf --paper liegen, geben ihre Farbe weiter. */
.next { --frame-bg: var(--bone); }

/* Produktreihe auf der Startseite */
.card { display: block; text-align: center; }
.card__frame { display: block; position: relative; overflow: hidden; }
/* Kein Zoom beim Ueberfahren. Vorgabe 22.08.2026: "keinen Effekt".
   Ein Bild, das unter dem Zeiger langsam waechst, ist eine Unruhe, die
   dem Stueck nichts hinzufuegt - und auf einer Seite, die von Ruhe
   lebt, faellt sie doppelt auf. Der Uebergang ist mitentfernt: eine
   Ueberblendung ohne Ausloeser kostet nur eine eigene Ebene im
   Zeichenwerk. */
.card__tag { display: block; margin-top: 0.4rem; font-size: 0.86rem; color: var(--muted-dark); }
.card__name {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--f-ext);
  font-size: clamp(0.72rem, 1vw, 0.9rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transition: color 0.4s var(--ease);
}

/* Helle Doppelfläche mit zwei Stücken */
.duo--light { background: var(--paper); }
.duo--light .duo__art { background: var(--paper); }
.duo--light .duo__art .shot { width: 78%; }
.duo--light .duo__label { color: var(--ink); text-shadow: none; }
.duo--light .duo__sub { color: var(--muted-dark); }
.duo--light .duo__half + .duo__half { border-left-color: var(--bone-line); }

/* --------------------------------------------------------------------------
   22. Kollektionsseite — feststehende Fläche, laufende Liste
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Laufende Bilder

   Beide Videos liegen ueber einem Standbild, nicht anstelle davon. Erscheint
   das Video nicht - kein JavaScript, Portrait, abbestellte Bewegung, ein
   Browser der das Format nicht kann - bleibt das Standbild stehen und die
   Flaeche ist nie leer.
   -------------------------------------------------------------------------- */

.hero__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
  pointer-events: none;
}
.hero__video.is-on { opacity: 1; }

/* Im Hochformat zeigt ein 16:9-Video nur einen schmalen senkrechten Streifen.
   Dort bleibt das Bild aus dem <picture>, und geladen wird gar nichts. */
@media (orientation: portrait), (max-width: 900px) {
  /* .hero__video stand hier bis zum 18.08.2026 auf display: none. Der Film
     laeuft jetzt auch auf dem Telefon; er kommt nur auf der Startseite vor,
     keine andere Seite ist davon beruehrt.

     Die Einblendung dauert hier 0,35 s statt 1,2. Am Schreibtisch faellt
     die lange Blende nicht auf, weil man selten neu laedt; auf dem Telefon
     landet man ueber das Zeichen staendig wieder auf der Startseite, und
     dann sah man jedes Mal ueber eine Sekunde lang das Standbild. */
  .hero__video { transition-duration: 0.35s; }
}

.aside__video {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  /* Muss die Regel .icons__aside > * ueberschreiben, die allen Kindern
     z-index 2 gibt - sonst laege das Video ueber Schleier und Schrift. */
  z-index: 0;
  opacity: 0;
  transition: opacity 1.2s var(--ease);
  pointer-events: none;
}
.aside__video.is-on { opacity: 1; }
/* Die Aufnahme ist hell, die Schrift darauf weiss. Ohne diesen Schleier waere
   sie unlesbar. Er liegt zwischen Video und Text.

   Bewusst ::before und nicht ::after: .grain::after ist bereits vergeben und
   traegt opacity 0.45 und mix-blend-mode: overlay. Auf ::after gelegt lief
   der Schleier deshalb mit knapp der Haelfte seiner Deckkraft und im
   Overlay-Modus - der dunkelt eine helle Aufnahme nicht ab, er erhoeht nur
   den Kontrast. Ausserdem war damit die Filmkoernung dieser Flaeche weg. */
.icons__aside::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  /* Eine Schicht, nicht zwei. Zwei Verlaeufe uebereinander multiplizieren
     sich: 0,74 und 0,86 ergeben zusammen 96 Prozent Schwarz, und davon bleibt
     vom Video nichts uebrig.

     0,74 bis 0,86 ist an den Einzelbildern des Videos gerechnet. Die hellste
     Stelle im Textbereich ist reines Weiss - die Glanzlichter der Kette. Sie
     landet damit bei 36 bis 66 von 255, weisse Schrift kommt auf 10:1 bis
     15:1. WCAG AAA verlangt 7:1. */
  background: linear-gradient(165deg, rgba(6, 10, 18, 0.66), rgba(3, 6, 11, 0.78));
}

@media (prefers-reduced-motion: reduce) {
  .hero__video, .aside__video { display: none; }
}

/* --------------------------------------------------------------------------
   Ganzflaechiges Band zwischen den Sortimentsbloecken

   PLATZHALTER: Der Grund ist ein Verlauf, weil noch keine Aufnahme vorliegt.
   Kommt eine, ersetzt sie background - Masse und Satz bleiben, wie sie sind.
   Ein sichtbarer leerer Rahmen steht hier bewusst nicht: auf einer
   Verkaufsseite ist ein ruhiger Verlauf ehrlicher als ein Loch.
   -------------------------------------------------------------------------- */

.band {
  position: relative;
  display: grid;
  place-items: center;
  min-height: min(86svh, 900px);
  padding: clamp(3rem, 8vw, 7rem) clamp(1.5rem, 5vw, 4rem);
  text-align: center;
  color: #fff;
  background:
    radial-gradient(65% 55% at 50% 42%, rgba(185, 154, 88, 0.16), transparent 74%),
    linear-gradient(168deg, #131c28 0%, #070c15 58%, #04070c 100%);
}


.band__inner { display: grid; justify-items: center; gap: 1.4rem; max-width: 46rem; }
.band .lede { color: rgba(255, 255, 255, 0.78); max-width: 34ch; }
.band .btn { margin-top: 0.6rem; }

.icons { display: grid; grid-template-columns: 1fr 1fr; align-items: start; }

.icons__aside {
  position: sticky;
  top: 0;
  height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(2rem, 5vw, 5rem);
  color: #fff;
  overflow: hidden;
  background:
    radial-gradient(70% 60% at 50% 40%, rgba(185, 154, 88, 0.2), transparent 72%),
    linear-gradient(160deg, #18212f, #070c15);
}
.icons__aside .panel__art { opacity: 0.5; }
.icons__aside > * { position: relative; z-index: 2; }
.icons__aside > .aside__video { position: absolute; z-index: 0; }
.icons__aside p { max-width: 34ch; margin-top: 1.4rem; color: rgba(255, 255, 255, 0.76); }

.icons__list { background: var(--paper); }
.prod {
  display: block;
  text-align: center;
  padding: clamp(1.6rem, 3.5vw, 3rem) clamp(1.5rem, 4vw, 4rem);
  border-bottom: var(--rule) solid var(--bone-line);
}
.prod:last-child { border-bottom: 0; }
/* Die Aufnahmen sind quadratisch, das Armband liegt aber als waagerechtes
   Band in der Mitte: gemessen ein Drittel leer oben, ein Drittel unten. Bei
   quadratischem Rahmen erschien das als grosse Luecke zwischen Bild und Name.
   Ein Rahmen im Verhaeltnis 2:1 schneidet genau diese leeren Baender weg -
   dem Inhalt bleiben rund acht Prozent Luft nach oben und unten. */
.prod__frame {
  display: block; position: relative; overflow: hidden;
  aspect-ratio: 2 / 1;
}
.prod__frame .shot {
  height: 100%;
  object-fit: cover;
}
.prod__tag { display: block; margin-top: 0.9rem; font-size: 0.9rem; color: var(--muted-dark); }
.prod__name {
  display: block;
  margin-top: 0.5rem;
  font-family: var(--f-ext);
  font-size: clamp(1rem, 1.6vw, 1.5rem);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  transition: color 0.4s var(--ease);
}

/* --------------------------------------------------------------------------
   Bannerflaeche der Produktseite

   Das Stueck gross, die Bezeichnung klein darueber, der Name in der
   Anzeigeschrift. Weisse Schrift geht hier nicht: die Aufnahmen haben hellen
   Hintergrund, ein dunkler Verlauf darunter wuerde grau. Also Tinte auf Bein.
   -------------------------------------------------------------------------- */

.phero {
  position: relative;
  display: grid;
  place-items: center;
  /* Volle Bildschirmhoehe, wie der Banner der Startseite. */
  min-height: 100svh;
  overflow: hidden;
  background: var(--bone);
}
.phero__art {
  position: absolute; inset: 0;
  /* place-items:center auf .phero macht auch aus dieser Flaeche ein
     Rasterelement und schrumpft sie auf Inhaltsgroesse - das inset:0 wird
     damit wirkungslos, und das Bild rutscht nach unten aus der Mitte.
     Gemessen: Bildmitte 772 statt 418. */
  place-self: stretch;
  display: grid; place-items: center;
}
.phero__art .shot {
  /* Das Armband fuellt nur das mittlere Drittel der quadratischen Aufnahme.
     Damit es im Banner ankommt, muss das Bild deutlich hoeher sein als die
     Flaeche - was oben und unten ueberlaeuft, ist ohnehin leer. */
  width: min(96%, 62rem);
  max-width: none;
}
/* Die Aufnahmen sind quadratisch, das Armband liegt als waagerechtes Band in
   der Mitte - ein Drittel oben und unten ist leer. Der Name sitzt deshalb im
   oberen Drittel und nicht in der Mitte, sonst laege er auf dem Stueck. */
.phero__text {
  position: relative; z-index: 2;
  align-self: start;
  margin-top: clamp(4rem, 14vh, 9rem);
  text-align: center;
  display: grid; gap: 0.9rem; justify-items: center;
  padding-inline: 1.5rem;
}
/* Der Name des Stuecks stand hier in der Script - als erstes von zehn
   Script-Woertern auf derselben Seite. Er ist aber kein Satz, sondern eine
   Bezeichnung: er gehoert in die Display, wie "Weitere Stuecke" und wie der
   Name in der Kaufspalte. Die Script bleibt den vier Aussagen vorbehalten
   (Auftakt, Material, Tragen, Form). */
.phero__name {
  font-family: var(--f-display);
  font-size: clamp(2.6rem, 6.5vw, 5.4rem);
  line-height: 1.05;
  letter-spacing: -0.012em;
  color: var(--ink);
}
/* Mit Kampagnenaufnahme: das Bild fuellt die Flaeche, darueber ein Schleier
   und weisse Schrift - derselbe Auftritt wie auf der Startseite. */
.phero--dunkel { background: #0b1119; color: #fff; }
/* <picture> ist von Haus aus display:inline. Ohne block loest height:100%
   am Bild nicht auf, und es faellt auf sein Seitenverhaeltnis zurueck -
   gemessen 720 statt 605 px, also 115 px Ueberlauf. */
.phero--dunkel .phero__art { place-self: stretch; display: block; }
.phero--dunkel .phero__art img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  /* Etwas dunkler im Ton. Nur brightness, kein Kontrast: an den Aufnahmen
     gerechnet reisst ein contrast von 1.08 die Schatten auf - bei cuban
     stiegen die reinen Schwarzflaechen von 22 auf 75 Prozent, das Bild waere
     ein schwarzes Feld mit einem hellen Tablett gewesen. Mit 0.82 wachsen sie
     bei cuban um neun, bei den uebrigen um zwei bis drei Punkte, und das
     Silber bleibt bei 206 bis 209 von 255. Nebenbei traegt die weisse Schrift
     dadurch besser: der hellste Punkt faellt von 253 auf 208. */
  filter: brightness(0.78) saturate(0.9);
}
.phero--dunkel::before {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  pointer-events: none;
  /* Oben und unten wie .hero__veil auf der Startseite, dazu ein sanfter
     Radial hinter der Schrift.

     Das Problem ist oertlich, nicht global: gemessen liegt das Textband bei
     cuban und santorini auf 5,3 und 5,5:1, weil Tablett und Treibholz genau
     dort hell sind - die uebrigen Baender liegen bei 12 bis 20:1. Weiter
     global abdunkeln haette die Schatten verloren, ohne die helle Stelle
     genug zu treffen. Mit 0,32 gehen alle vier auf 9,5:1 oder besser, AAA
     verlangt 7:1. Aussen bleibt das Bild offen. */
  background:
    radial-gradient(46% 30% at 50% 50%, rgba(5, 9, 15, 0.32), transparent 70%),
    linear-gradient(to bottom, rgba(5, 9, 15, 0.55) 0%, rgba(5, 9, 15, 0) 26%),
    linear-gradient(to top, rgba(5, 9, 15, 0.6) 0%, rgba(5, 9, 15, 0) 34%);
}
.phero--dunkel .phero__text,
.phero--dunkel .scroll-cue { z-index: 2; }
.phero--dunkel .phero__name {
  color: #fff;
  text-shadow: 0 0 28px rgba(5, 9, 15, 0.55), 0 1px 3px rgba(5, 9, 15, 0.4);
}
/* Kraeftiger als beim Namen: der Kicker ist klein und weit gesperrt, da
   traegt ein weicher Schein allein nicht. Zwei Schatten - einer weit fuer
   die Flaeche, einer eng fuer die Kante der Buchstaben. */
.phero--dunkel .eyebrow--light {
  text-shadow: 0 0 16px rgba(5, 9, 15, 0.85), 0 1px 2px rgba(5, 9, 15, 0.7);
}
.phero--dunkel .phero__text { align-self: center; margin-top: 0; }

.scroll-cue--ink { color: var(--ink); }
.scroll-cue--ink i { background: var(--ink); }

@media (max-width: 700px) {
  .phero { min-height: 100svh; }
  .phero__art .shot { width: 140%; }
}

/* --------------------------------------------------------------------------
   Produktseite — die Aussage unter dem Banner
   Erst eine ruhige, mittige Flaeche, dann der Handel. Wer vom Banner
   herunterscrollt, trifft nicht auf einen Preis, sondern auf die Form.
   -------------------------------------------------------------------------- */

.aussage {
  background: var(--paper);
  padding: clamp(4.5rem, 10vw, 9rem) clamp(1.2rem, 5vw, 3rem) clamp(4rem, 9vw, 8rem);
}

.aussage__inner {
  max-width: 62rem;
  margin: 0 auto;
  text-align: center;
}

.aussage__head {
  font-size: clamp(2.1rem, 5.4vw, 4.6rem);
  margin: clamp(0.9rem, 2vw, 1.5rem) 0 0;
}

/* Die Script sitzt tiefer auf der Grundlinie als die Display. Ohne den
   Ausgleich haengt das Wort sichtbar unter der Zeile. */
.aussage__head .script { font-size: 1.08em; line-height: 0.8; }

.aussage__art {
  width: min(22rem, 68vw);
  margin: clamp(2.6rem, 6vw, 4.5rem) auto clamp(2.2rem, 5vw, 3.5rem);
  aspect-ratio: 3 / 4;
  overflow: hidden;
}

/* Ist die Aufnahme das letzte Kind, trennt ihr unterer Abstand nichts mehr:
   er stapelt sich auf das Polster des Abschnitts. Gemessen am 21.08.2026 bei
   1920 Pixeln waren es 56 (Abstand) + 128 (Abschnitt) + 112 (Klappband) =
   296 Pixel Leere zwischen Bild und "Care" - der groesste Sprung der Seite,
   waehrend die uebrigen Abschnitte 210 bis 270 auseinanderliegen. Die 56
   sind der Ueberschuss, nicht der Abschnittsrhythmus; deshalb faellt nur
   dieser weg. Steht spaeter wieder etwas unter der Aufnahme, greift der
   Abstand von selbst. */
.aussage__art:last-child { margin-bottom: 0; }

.aussage__art .shot {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  /* Seit dem 19.08.2026 steht hier eine Modellaufnahme statt eines
     freigestellten Produktfotos. `.shot` traegt multiply - das ist der
     Trick, mit dem freigestellte Aufnahmen auf dem Untergrund sitzen, und
     bei Fotografie zieht es das Bild ins Beige. */
  mix-blend-mode: normal;
}

.aussage__text {
  max-width: 42rem;
  margin: 0 auto;
  color: var(--muted);
  font-size: clamp(0.95rem, 0.9rem + 0.2vw, 1.08rem);
  line-height: 1.75;
  text-wrap: pretty;
}

/* --------------------------------------------------------------------------
   23. Produktseite
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Produktseite — Galerie und Kaufbereich
   Zwei Spalten aus dem bestehenden Raster; die Galerie bleibt stehen,
   während der Kaufbereich mitläuft.
   -------------------------------------------------------------------------- */

/* --- Drei Spalten: Stueck, getragen, Kauf --------------------------------
   Vorgabe 21.08.2026 nach Hermes. Links das freigestellte Stueck mit seiner
   Bilderfolge, rechts daneben die getragene Aufnahme, dann die Kaufflaeche.

   Die beiden Bilder beantworten verschiedene Fragen - wie sieht es aus, wie
   wirkt es am Arm - und gehoeren deshalb nebeneinander, nicht nacheinander
   in dieselbe Folge.

   Am Telefon faellt die Modelspalte weg: dort ist die Breite fuer ein Bild
   da, nicht fuer zwei. */
.pdp__model { display: none; }

.pdp {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: start;
  background: var(--paper);
  padding-top: clamp(1.5rem, 4vh, 3rem);
}

.pdp__media { position: sticky; top: 0; padding: clamp(1rem, 3vw, 3rem); }

.pdp__stage { position: relative; aspect-ratio: 1; }
.pdp__frame {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  /* Etwas tiefer als die Seite. Die Aufnahmen sind zu 99 Prozent Studioweiss
     und werden mit multiply eingeblendet - gegen --paper geblendet blieb von
     der silbernen Kette fast nichts uebrig. Gegen --bone bekommt sie Kontur,
     und der Bildbereich hebt sich als Flaeche von der Seite ab. */
  background: var(--bone);
  opacity: 0;
  /* Aufloesung, keine Kreuzblende.

     Bis zum 21.08.2026 blendeten beide Aufnahmen gleichzeitig - die alte
     von 1 auf 0, die neue von 0 auf 1. In der Mitte stand jede bei 0,5,
     und weil jede Flaeche ihren eigenen Grund in --bone traegt, schlug in
     der Mitte der Grund durch: ein kurzer heller Schlag zwischen zwei
     Bildern. Beim Antippen faellt das kaum auf, weil man den Wechsel
     erwartet; laeuft die Folge von selbst, liest er sich als Sprung -
     gemeldet an dem Tag als "beim Klicken schoen, von selbst stur".

     Jetzt wartet die abgehende Aufnahme: sie bleibt volle Deckkraft
     stehen, bis die neue oben darueber fertig aufgeblendet hat, und
     verschwindet dann ohne eigene Blende - unsichtbar, weil sie zu dem
     Zeitpunkt schon verdeckt ist. `0s ... 0.6s` ist genau das: keine
     Dauer, aber die volle Verzoegerung der Blende darueber. */
  transition: opacity 0s linear 0.6s;
  pointer-events: none;
}
.pdp__frame.is-on {
  opacity: 1;
  pointer-events: auto;
  /* Das neue Bild liegt oben und blendet auf. */
  z-index: 1;
  transition: opacity 0.6s var(--ease);
}

/* Die Aufnahme selbst schaltet weiter (js/main.js setzt is-klickbar erst,
   wenn es wirklich mehr als ein Bild gibt - ohne Skript kein Zeigefinger,
   der nichts verspricht). */
.pdp__stage.is-klickbar { cursor: pointer; }

/* Bildwechsel ueber duenne Linien statt Abziehbilder. Die Linie sagt "es gibt
   noch mehr", ohne das Bild darueber im Kleinen zu wiederholen. Der Knopf ist
   2,5rem hoch, die sichtbare Linie 1px - das Ziel bleibt greifbar. */
.pdp__linien {
  display: flex;
  max-width: 100%;
  /* NICHT `stretch` - das ist der Standardwert im Flexkasten, und die
     Miniaturen zogen sich damit ueber die volle Hoehe des Behaelters: aus
     kleinen Quadraten wurden hohe schmale Streifen mit Kettenausschnitten
     darin. Gemeldet am 21.08.2026: "die Bracelet-Fotos sind kaputt". */
  align-items: flex-end;
  justify-content: center;
  gap: clamp(0.8rem, 2vw, 1.6rem);
  margin-top: clamp(1rem, 2.5vw, 2rem);
}
.pdp__linie {
  /* Mitschrumpfen statt feste Breite.

     Seit dem 21.08.2026 sind es fuenf Aufnahmen statt drei - mit
     `clamp(3.6rem, ...)` als Mindestbreite ergab das 5 x 57,6 Pixel plus
     vier Luecken plus Polster = 371 Pixel, und die Produktseite lief auf
     einem 320er Telefon seitlich ueber. Von `npm run breiten` gefangen,
     bevor es rausging.

     `flex: 1 1 0` mit `min-width: 0` laesst die Striche unter ihre
     Wunschbreite; `max-width` haelt sie oben fest, damit sie auf breiten
     Schirmen nicht auseinanderlaufen. */
  /* Miniaturen statt Striche: feste, kleine Quadrate wie im Vorbild. */
  flex: 0 0 auto;
  width: clamp(2.6rem, 4vw, 3.4rem);
  min-width: 0;
  height: auto;
  padding: 0;
  /* Der Grund gehoert an den Knopf, nicht an das Bild darin.

     Das Bild blendet mit `multiply`, und `multiply` mischt mit dem, was
     dahinter liegt. Dahinter liegt hier aber nicht die Bildflaeche: die
     Leiste `.pdp__linien` steht auf `position: absolute` mit `z-index: 2`
     und bildet damit einen eigenen Stapelzusammenhang - der schneidet die
     Mischung vom Grund darunter ab, und das Studioweiss blieb weiss.
     Gemessen 21.08.2026.

     Der Knopf selbst bildet keinen (position: relative, z-index: auto),
     sein Grund liegt also im selben Zusammenhang wie das Bild. Weiss mal
     --bone ergibt --bone, und der Kasten verschwindet. */
  background: var(--bone);
  border: 0;
  cursor: pointer;
  display: grid;
  align-items: center;
}
/* Die Miniatur im Knopf. Der Strich darunter sagt, welche gerade dran ist -
   wie im Vorbild, wo die aktive Miniatur unterstrichen ist. */
.pdp__linie img {
  display: block;
  width: 100%;
  /* `height: auto` ist Pflicht, sonst gewinnt das HTML-Attribut.

     Die Miniaturen tragen `width="800" height="800"` - richtig so, das
     spart den Sprung beim Laden. Beide Attribute sind aber zugleich eine
     Stilvorgabe des Browsers. `width: 100%` hier ueberschrieb nur die
     Breite; die Hoehe blieb bei 800 Pixeln, und `aspect-ratio` greift
     nicht mehr, wenn beide Masse feststehen. Aus den Quadraten wurden
     54 x 800 Pixel hohe Streifen mit Kettenausschnitten darin - genau das,
     was am 21.08.2026 als "die Bracelet-Fotos sind kaputt" gemeldet wurde.

     Der Versuch davor setzte `height: auto` auf `.pdp__linie`, den Knopf.
     Der war damit in Ordnung - das Bild darin nicht. */
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  background: var(--bone);
  /* Dieselbe Behandlung wie die grosse Aufnahme daneben: die Studio-
     aufnahmen sind zu 99 Prozent Weiss, und ohne `multiply` steht die
     Miniatur als weisser Kasten auf der Seite statt als Bild darin.
     `.pdp__frame` macht es genauso (Grund --bone, Bild multiply), und die
     Warenkorb-Miniatur `.co__thumb img` ebenfalls. Gemeldet 21.08.2026:
     "die kleinen Vorschaubilder haben einen weissen Hintergrund". */
  mix-blend-mode: multiply;
}
.pdp__linie::after {
  content: "";
  display: block;
  height: 2px;
  margin-top: 0.4rem;
  background: transparent;
  transition: background 0.35s var(--ease);
}
.pdp__linie:hover::after { background: var(--bone-line); }
.pdp__linie.is-on::after { background: var(--ink); }

/* Der Balken. Er waechst mit --lauf, das js/main.js je Bild von 0 auf 1
   zieht. scaleX statt width: das laeuft auf dem Compositor und kostet kein
   Layout je Bild.

   Er stand bis zum 21.08.2026 auf `position: absolute` ohne `top` oder
   `bottom`. Damit landete er auf seiner statischen Stelle - im Raster von
   `.pdp__linie` mit `align-items: center` also mitten auf dem Bild, als
   schwarzer Balken quer durch die Miniatur. Gemeldet an dem Tag: "dicke
   Striche ueber den Thumbnails".

   Jetzt laeuft er im Fluss: zweite Rasterzeile unter dem Bild, mit dem
   `margin-top` aus der Regel darueber. Kein `position` mehr - genau das
   war der Fehler. */
.pdp__linie::after {
  content: "";
  height: var(--rule);
  background: var(--ink);
  transform: scaleX(var(--lauf, 0));
  transform-origin: left center;
}
.pdp__linie { position: relative; --lauf: 0; }
/* Nur die aktive Linie fuellt sich; die uebrigen bleiben als ruhige Marke
   stehen. Ruht der Lauf (Ruhe-Einstellung, Tab im Hintergrund, Maus darauf),
   setzt js/main.js --lauf der aktiven Linie auf 1 - sonst zeigte nichts mehr
   an, wo man gerade ist. */

.pdp__buy {
  padding: clamp(2rem, 5vw, 5rem) clamp(1.5rem, 5vw, 5rem) clamp(3rem, 7vw, 6rem);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.pdp__name { margin: 0.9rem 0 0.6rem; }
/* Der Preis ist nicht mehr die Schlagzeile unter dem Namen, sondern eine
   ruhige Zeile ueber den Knoepfen - sichtbar, weil die Preisangabenverordnung
   das verlangt, aber ohne den Ton der Seite zu bestimmen. */
.pdp__preis {
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  color: var(--muted-dark);
}
/* Pflichtangaben zum Preis. Sie stehen direkt unter der Zahl, weil die
   Preisangabenverordnung raeumliche Naehe verlangt - aber sie sollen nicht
   mit ihr konkurrieren: eine Stufe kleiner, dieselbe gedaempfte Farbe, kein
   Kasten, kein Symbol. Wer den Preis liest, liest sie mit; wer die Form
   ansieht, uebersieht sie. */
.pdp__preishinweis {
  margin-top: 0.5rem;
  /* Keine eigene Breitenbegrenzung.
     Erst stand hier `max-width: 42ch` - und 42 Zeichen sind auf einem
     375 Pixel breiten Telefon SCHMALER als die Spalte selbst. Der Satz
     brach dadurch auf vier Zeilen und 88 Pixel um und schob den ersten
     Bildschirm sichtbar nach unten. Ohne die Grenze nimmt er die Spalte,
     die ohnehin da ist. */
  font-size: 0.76rem;
  line-height: 1.45;
  letter-spacing: 0.01em;
  color: var(--muted-dark);
}
.pdp__preishinweis a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.18em;
  text-decoration-thickness: from-font;
}

.pdp__lede {
  margin-top: 1.5rem;
  max-width: 40ch;
  color: var(--muted-dark);
  font-size: 1.02rem;
}

.pdp__variants { margin-top: 2rem; width: 100%; }
.pdp__opts { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.8rem; }
.pdp__opt {
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0.75em 1.3em;
  border: var(--rule) solid var(--bone-line);
  border-radius: 999px;
  transition: border-color 0.3s var(--ease), background 0.3s var(--ease),
              color 0.3s var(--ease);
}
.pdp__opt[aria-checked="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.pdp__opt[disabled] { opacity: 0.35; text-decoration: line-through; cursor: not-allowed; }

/* Warenkorb und Kasse stehen nebeneinander, abgesetzt durch einen Strich vom
   Text darueber. `pdp__buy` ist der Kasten, `pdp__cta` der Knopf darin -
   frueher trug der Knopf selbst pdp__buy und erbte dessen Innenabstand von
   bis zu 5rem, er war dadurch riesig. */
.pdp__aktion {
  display: flex;
  flex-wrap: wrap;
  gap: 0.8rem;
  width: 100%;
  max-width: 30rem;
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-top: clamp(1.8rem, 4vw, 2.6rem);
  border-top: var(--rule) solid var(--bone-line);
}
.pdp__buy .btn { margin-top: 1.8rem; width: min(100%, 22rem); }
/* Muss nach `.pdp__buy .btn` stehen: gleiche Spezifitaet (0,2,0), also
   entscheidet die Reihenfolge. Andersherum blieben beide Knoepfe 22rem breit
   und stuenden untereinander statt nebeneinander. */
.pdp__aktion .btn { flex: 1 1 11rem; margin-top: 0; width: auto; }
.pdp__buy .btn[disabled] { opacity: 0.45; cursor: not-allowed; }
.pdp__buy .btn[disabled]:hover { background: var(--ink); color: var(--paper); }

/* Vormerkung statt Kauf. Kein eigener Stil: die Zeile trägt dieselbe
   gesperrte Versalienschrift wie jedes andere Label der Seite, das Feld
   kommt aus .form--light. Untereinander statt nebeneinander, deshalb die
   Spalte — die Flex-Zeile darüber ist für zwei Knöpfe gebaut. */
.pdp__aktion--bald { flex-direction: column; gap: 1.2rem; }
.pdp__bald {
  font-family: var(--f-ext);
  font-size: clamp(0.6rem, 0.55rem + 0.16vw, 0.72rem);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}
.pdp__merk { width: 100%; max-width: 22rem; gap: 0.8rem; }
.pdp__merk .btn { width: 100%; }
/* Kleiner als die Formulare auf den eigenen Formularseiten. Dort ist das
   Feld die Hauptsache; hier steht es neben einem Produkt und soll nicht
   wie eine Anmeldung wirken. Nur Hoehe und Innenabstand, damit es dieselbe
   Schrift und denselben Rahmen behaelt.

   Drei Klassen, nicht zwei: `.form--light .field input` hat dieselbe
   Spezifitaet und steht weiter unten in dieser Datei - bei Gleichstand
   gewinnt die spaetere Regel. Mit `.pdp__aktion` davor ist der Fall
   entschieden, ohne dass jemand die Reihenfolge im Kopf behalten muss. */
.pdp__aktion .pdp__merk .field input { height: 2.8rem; padding: 0 0.9rem; }
.pdp__aktion .pdp__merk .field label { margin-bottom: 0.35rem; }
.pdp__aktion .pdp__merk .btn { padding-block: 0.85em; }

/* Die Dreispaltigkeit MUSS hinter der Grundregel stehen.

   Sie stand einmal davor - dann gewann `.pdp { grid-template-columns:
   1fr 1fr }` bei gleicher Spezifitaet, die Modelspalte lag in der zweiten
   Reihe und die Kaufflaeche darunter. Gemessen am 21.08.2026: Stueck
   0-720, Model 720-1440, Kauf 0-720. Das ist heute die fuenfte Stelle mit
   demselben Muster - wer hier etwas ergaenzt, sieht zuerst nach, wo die
   Grundregel steht.

   Am 21.08.2026 stand der Block trotzdem noch vor `.pdp__stage`,
   `.pdp__linien` und `.pdp__buy` - und verlor gegen alle drei:

     .pdp__stage  Grundregel `aspect-ratio: 1` schlug `aspect-ratio: auto`.
                  Die Flaeche nahm ihre Hoehe (826) auch als Breite und lag
                  300 Pixel ueber ihrer Spur - quer ueber dem Modelfoto.
     .pdp__buy    Grundregel `padding: ... 5rem` schlug die 1,8rem der
                  Karte. Bei 1920 waren das 80 Pixel Polster in einer 368
                  Pixel breiten Karte: 208 Pixel fuer den Text.
     .pdp__linien Grundregel `margin-top` und `justify-content: center`
                  schlugen `margin: 0` und `flex-start`.

   Deshalb steht der Block jetzt hinter dem GESAMTEN `.pdp`-Grundsatz, nicht
   nur hinter der ersten Regel. Wer hier etwas ergaenzt, haengt es hinten an
   - nicht zwischen die Grundregeln. */
@media (min-width: 1024px) {
  /* --- Zwei randlose Bildflaechen, die Kaufkarte darauf -----------------
     Vorgabe 21.08.2026, nachdem ich zuerst drei gleichberechtigte Spalten
     gebaut hatte und der Unterschied zum Vorbild benannt war:

       Vorbild: zwei Bilder randlos ueber die volle Breite, ohne Fuge,
                Hoehe bis unter die Falz, und die Kauffläche als Karte
                darauf. Die Bilder nehmen rund 90 Prozent der Breite.
       Vorher:  drei Spalten, jedes Bild in einem Kasten mit Polster,
                zusammen 64 Prozent - gemessen 473 und 450 Pixel bei 1440.

     Der Unterschied ist nicht die Anordnung, sondern dass die Kaufflaeche
     den Bildern keine Breite wegnimmt. Deshalb liegt sie jetzt darauf. */
  .pdp {
    position: relative;
    /* Die Modelspalte ist breiter als die Produktspalte - die Kaufkarte
       liegt darauf und muss Platz uebrig lassen. Bei zwei gleichen
       Haelften verdeckte sie 62 Prozent des Fotos; gemeldet am 21.08.2026
       mit "jetzt sieht man das Foto nicht". */
    /* Drei Spuren, die dritte bleibt leer.

       Im Vorbild enden die Bilder bei rund 90 Prozent der Breite - rechts
       bleibt ein freier Streifen, und die Kaufkarte ragt hinein. Bei uns
       liefen sie bis an den aeusseren Rand; das war der Grund, warum die
       Flaeche erschlagend wirkte und die Karte mitten im Bild sass.
       Gemeldet am 21.08.2026: "das Foto geht bei Hermes auch nicht bis
       ganz rechts durch".

       Die leere Spur ist kein Polster an .pdp: ein absolut gesetztes Kind
       misst sich am Polsterkasten, die Karte saesse dann innerhalb des
       Streifens statt darin hineinzuragen. */
    grid-template-columns: 0.78fr 1.12fr 0.24fr;
    padding-top: 0;
  }
  .pdp__media {
    position: static;
    padding: 0;
    /* `min-width: 0` ist Pflicht. Rasterkinder duerfen sonst breiter
       werden als ihre Spur, wenn ihr Inhalt es verlangt - die Aufnahme im
       Kasten tat genau das, und aus zwei gleichen Haelften wurden 826 zu
       614 Pixeln. Gemessen 21.08.2026. */
    min-width: 0;
    /* Bis knapp unter die Falz. `svh`, weil `vh` auf dem Telefon die
       groessere, zeitweise falsche Hoehe meint - hier zwar Schirm, aber
       dieselbe Einheit ueberall spart die naechste Ueberraschung. */
    height: calc(100svh - 4.6rem);
  }
  .pdp__stage { aspect-ratio: auto; height: 100%; }
  .pdp__model {
    display: block;
    padding: 0;
    min-width: 0;
    height: calc(100svh - 4.6rem);
  }
  .pdp__model .shot {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  /* Die Bildstriche liegen unten links auf der Flaeche, nicht darunter. */
  .pdp__linien {
    position: absolute;
    left: clamp(1.5rem, 3vw, 3rem);
    bottom: clamp(1.5rem, 3vh, 2.5rem);
    width: min(16rem, 22vw);
    margin: 0;
    justify-content: flex-start;
    z-index: 2;
  }
  /* Die Kaufkarte schwebt unten rechts auf dem zweiten Bild. Eigener
     Grund, sonst laege die Schrift auf der Aufnahme. */
  /* Die Kaufkarte: schmal, unten rechts, so wenig Bild wie moeglich
     verdeckend. Im Vorbild ist sie rund ein Drittel der Bildflaeche und
     sitzt in der Ecke - nicht ueber der ganzen Hoehe.

     Deshalb steht hier auch die Ueberschrift kleiner und die Beschreibung
     schmaler: die Karte ist so hoch, wie ihr Inhalt sie macht, und unser
     Inhalt ist laenger als der des Vorbilds (dort stehen Farbfelder und
     eine Groessenzeile, hier ein Beschreibungssatz). */
  .pdp__buy {
    position: absolute;
    right: clamp(1.2rem, 2vw, 2.5rem);
    bottom: clamp(1.2rem, 2.5vh, 2.5rem);
    width: min(23rem, 26vw);
    padding: clamp(1.3rem, 1.8vw, 1.8rem);
    background: var(--paper);
    z-index: 2;
  }
  .pdp__buy .pdp__name { font-size: clamp(1.8rem, 2.6vw, 2.6rem); }
  .pdp__buy .pdp__lede { font-size: 0.88rem; }
  .pdp__buy .pdp__aktion { margin-top: 1.1rem; }
  /* In der schmalen Karte stehen die beiden Kaufknoepfe untereinander.
     Nebeneinander blieben je rund 150 Pixel - "Add to cart" brach dort auf
     drei Zeilen. Gesehen am 21.08.2026, nachdem die Karte schmaler wurde,
     damit man das Foto daneben wieder sieht. */
  .pdp__buy .pdp__zwei { grid-template-columns: 1fr; gap: 0.5rem; }
}


/* Mobile Kaufleiste. Erscheint erst, wenn der Kaufbereich oben aus dem Bild
   gescrollt ist, und liegt unter dem Warenkorb-Overlay. */
.stickybar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 70;
  /* Der helle Grund ist zurueck - Vorgabe 21.08.2026, nachdem die Leiste
     ohne ihn ueber dem Seiteninhalt lag und der Text dahinter durchlief.
     Was weg bleibt, ist die harte Linie und der Schatten: der Grund allein
     traegt die Leiste, ohne sie als Kasten aufzublasen.

     Der alte Kommentar dazu, warum gar kein Grund: */
  background: var(--paper);

  /* Kein Streifen mehr, keine Linie, kein Schatten.

     Vorgabe 21.08.2026 mit Bildschirmfoto von Hermes: "dezent und sauber".
     Dort liegt kein Papierband ueber der Seite - links stehen Name und
     Preis auf dem Grund der Seite, rechts zwei eckige Knoepfe, sonst
     nichts. Das Band war das Lauteste an der Leiste: ein voller Streifen
     samt Linie und Schatten, nur damit zwei Knoepfe darauf stehen koennen.

     Lesbar bleibt es trotzdem: die Knoepfe tragen ihren eigenen Grund, und
     Name und Preis stehen am unteren Ende der Produktseite, wo Text auf
     Papier steht und kein Bild. */

  /* Bis zum 21.08.2026 fuhr die ganze Leiste als Block von unten herein -
     ein voller Streifen Papier, der ueber den Text schiebt. Das war
     Bewegung um der Bewegung willen und las sich billig.

     Jetzt blendet sie auf und hebt sich dabei um zwoelf Pixel: dieselbe
     Geste wie bei allem anderen auf der Seite, das erscheint. Der Knopf
     darin kommt eine Spur spaeter und eine Spur kleiner nach - er ist das
     Eigentliche, nicht der Streifen darunter.

     `visibility` statt nur `opacity`: eine durchsichtige Leiste faengt
     sonst weiter Beruehrungen ab. Sie wird beim Erscheinen sofort
     geschaltet und beim Verschwinden erst am Ende der Blende - deshalb
     die Verzoegerung nur in diesem Zustand. */
  /* Kein `visibility` mehr, sondern nur Durchsichtigkeit und
     `pointer-events`.

     Der Grund ist kein Geschmack: mit `visibility: hidden` lief die Blende
     beim ersten Erscheinen nicht - die Leiste stand einfach da. Erst wer
     hoch- und wieder herunterscrollte, sah sie kommen. Ein Uebergang
     braucht einen Ausgangszustand, den der Browser schon einmal gezeichnet
     hat; ein nie gezeichnetes Element springt beim ersten Mal auf seinen
     Zielwert. Durchsichtig gezeichnet wird die Leiste dagegen von der
     ersten Sekunde an.

     Dass sie in diesem Zustand keine Beruehrung abfaengt, uebernimmt
     `pointer-events` - sonst laege ein unsichtbarer Streifen ueber der
     ganzen unteren Kante. Fuer Vorlesegeraete setzt js/main.js zusaetzlich
     aria-hidden. */
  /* 0.001 statt 0, und das ist kein Vertipper.

     Gemeldet am 21.08.2026: die beiden Knoepfe kommen passend, aber der
     helle Grund darunter manchmal eine Spur spaeter. Der Grund ist, wie
     Safari malt: bei `opacity: 0` darf es das Element ueberspringen - es
     ist ja unsichtbar. Beginnt die Blende, muss es Grund UND Schatten in
     dem Augenblick erst anfertigen, und der Schatten ist teuer (40 Pixel
     Unschaerfe ueber die volle Breite). Die Knoepfe darin liegen wegen des
     runden Ausschnitts und des Stripe-Rahmens ohnehin auf eigenen Ebenen
     und sind laengst fertig - also sind sie zuerst da, und der Streifen
     kommt hinterher.

     Ein Hauch ueber null zwingt Safari, von Anfang an zu malen. Sichtbar
     ist der Unterschied nicht: ein Tausendstel Deckkraft auf hellem Grund
     ist kein Pixel. Angefasst wird nichts, dafuer sorgen `pointer-events`
     und das aria-hidden aus js/main.js.

     Dieselbe Familie wie der Hinweis weiter oben: ein Uebergang braucht
     einen Zustand, den der Browser schon einmal gezeichnet hat. */
  opacity: 0.001;
  pointer-events: none;
  /* Nur eine Blende, keine Bewegung mehr.

     Die Leiste hob sich beim Erscheinen um achtzehn Pixel. Das war als
     Lebenszeichen gedacht und las sich als Schubs - etwas, das von unten
     ins Bild draengt. Ein Kaufknopf muss nicht draengen.

     Wichtiger noch war die Kurve. `cubic-bezier(0.16, 1, 0.3, 1)` ist ein
     Expo-Ausklang und vorne steil: nach einem Zehntel der Zeit ist die
     Blende zu 49 Prozent durch, nach einem Fuenftel zu 75. Bei 0,8 s heisst
     das: die Leiste steht nach 160 ms zu drei Vierteln da und braucht die
     restlichen 640 ms fuer das letzte Viertel, das ohnehin niemand sieht.
     Nominell langsam, gefuehlt ein Schlag. Nachgerechnet am 21.08.2026,
     nachdem dreimal "zu schnell" gemeldet wurde und ich zweimal an der
     Dauer gedreht hatte statt an der Kurve.

     `cubic-bezier(0.45, 0, 0.25, 1)` steigt gemaechlich an: 2 Prozent nach
     einem Zehntel, 10 nach einem Fuenftel, 73 nach der Haelfte. Ueber eine
     Sekunde ist das ein Aufziehen, kein Erscheinen.

     `will-change` ist kein Aberglaube: die Leiste liegt fest ueber einem
     scrollenden Dokument. Ohne eigene Ebene rechnet Safari sie waehrend des
     Schwungscrollens im selben Durchgang wie die Seite und laesst die
     Blende dabei fallen. */
  will-change: opacity;
  transition: opacity 1s cubic-bezier(0.45, 0, 0.25, 1);
  /* Bis zum 20.08.2026 stand hier `display: none` und wurde erst unter
     900 px aufgehoben - die Leiste gab es also nur auf dem Telefon. Am
     Schirm scrollte man am Kaufknopf vorbei und hatte keinen zweiten.
     Jetzt ueberall; sichtbar wird sie ohnehin erst, wenn der obere Knopf
     aus dem Bild ist (js/main.js setzt is-on). */
  display: block;
}
/* Ein einziger Vorgang, ein einziges Element: die Leiste hebt sich um
   vierzehn Pixel und wird sichtbar, fertig. Der Knopf darin hat keine
   eigene Bewegung mehr - zwei gestaffelte Blenden auf zwei Ebenen lasen
   sich zappelig.

   Wann sie erscheinen darf, entscheidet js/main.js: die Beobachtung des
   Kaufbereichs beginnt erst, wenn feststeht, was in der Leiste steht.
   Frueher stand das als zweite Klasse hier in der Bedingung - das waren
   zwei Ausloeser fuer einen Vorgang, und welcher zuerst kam, hing vom Netz
   ab. */
.stickybar.is-on {
  opacity: 1;
  pointer-events: auto;
}
/* Muss zur Hoehe der Leiste passen, sonst verdeckt sie unten Inhalt.

   Mit dem groesseren Leistenbild (3,2rem, Vorgabe 21.08.2026) ist die
   Leiste 80 statt 75 Pixel hoch - das Bild ist damit hoeher als die 46
   Pixel der Knoepfe und gibt die Hoehe vor. Bei 4,8rem (76,8 Pixel)
   blieben 3 Pixel Inhalt darunter. Gemessen an dem Tag. */
body.has-sticky { padding-bottom: 5rem; }
.stickybar__inner {
  display: flex;
  align-items: center;
  /* Name und Preis nach links, die Knoepfe nach rechts - wie im Vorbild. */
  justify-content: space-between;
  gap: 1.5rem;
  padding-block: 0.9rem;
}
/* Das Stueck, um das es geht. Am Schirm gehoert es dazu: wer weit unten auf
   einer langen Seite steht, soll nicht raten muessen, was er da kauft. Auf
   dem Telefon ist kein Platz dafuer, und die Frage stellt sich auch nicht -
   dort ist die Seite kuerzer und der Name naeher. */
/* Bild links, Name daneben, Preis unter dem Namen - Vorgabe 21.08.2026
   nach der Logik der Hermes-Leiste. Raster statt Flexzeile, damit die
   Reihenfolge im HTML bleiben kann: das Bild spannt beide Zeilen der
   ersten Spalte, Name und Preis setzen sich von selbst darueber und
   darunter in die zweite. */
.stickybar__stueck {
  display: grid;
  grid-template-columns: auto auto;
  align-items: center;
  column-gap: 0.7rem;
  row-gap: 0.1rem;
  margin: 0;
  min-width: 0;
}
.stickybar__name {
  font-family: var(--f-ext);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.stickybar__preis { font-size: 0.86rem; color: var(--muted-dark); white-space: nowrap; }
/* Das Miniaturbild in der Leiste. Es sagt, um welches Stueck es geht - bei
   einer Leiste, die weit unten auf einer langen Seite erscheint, ist der
   Name allein duenn. Wie im Vorbild. */
.stickybar__bild {
  /* 3,2 statt 2,6 rem - Vorgabe 21.08.2026. Die Leiste bleibt dabei
     gleich hoch: sie misst sich an den 46 Pixeln der Knoepfe, und 3,2rem
     sind 51,2 Pixel Bild ueber zwei Zeilen, also weiter unter der Hoehe,
     die das Polster ohnehin vorgibt. */
  width: 3.2rem;
  height: 3.2rem;
  object-fit: cover;
  background: var(--bone);
  flex: none;
  align-self: center;
  /* Wie die Miniaturen an der Bildflaeche und die grosse Aufnahme: die
     Studioaufnahme ist Weiss, und ohne `multiply` sitzt ein weisser Kasten
     in der Leiste. Gemeldet 21.08.2026 ("kein weiss"). Hier reicht die
     Angabe allein - `.stickybar__stueck` bildet keinen eigenen
     Stapelzusammenhang, die Mischung erreicht also den Grund der Leiste. */
  mix-blend-mode: multiply;
  /* Ueber beide Zeilen, sonst stuende der Preis neben dem Bild statt unter
     dem Namen. */
  grid-row: 1 / span 2;
}
/* Ein Knopf, zwei Haelften - so wie es Hermes macht. Apple Pay links,
   Warenkorb rechts, dazwischen keine Luecke, aussen rund. Die beiden
   Kinder sind eigenstaendige Bedienteile; die Rundung kommt vom Rahmen
   und wird mit overflow beschnitten, sonst muesste jede Haelfte ihre
   eigenen Ecken kennen. Vorgabe 20.08.2026. */
/* Zwei eigenstaendige Knoepfe nebeneinander, nicht mehr ein geteilter.

   Der geteilte Knopf mit runden Aussenecken war die Auslegung vom
   20.08.2026 - Hermes macht es heute anders, und die Vorgabe vom 21.08.2026
   ist dieses Bild: zwei Rechtecke mit einer Fuge dazwischen, Apple Pay hell
   mit Rahmen, der Warenkorb schwarz. Damit braucht es auch kein
   `overflow: hidden` mehr, das die Rundung beschnitt.

   Nachtrag 21.08.2026: die Rechtecke sind wieder Pillen - siehe
   `.stickybar__b` unten. Die Fuge und die zwei eigenstaendigen Knoepfe
   bleiben, nur die Ecken nicht. */
/* Wieder ein Knopf statt zweier - Vorgabe 21.08.2026 mit Blick auf Hermes:
   links Apple Pay, rechts der Warenkorb, dazwischen ein Strich, aussen
   rund. Der Strich ist kein Rahmen an den Haelften, sondern eine 1 Pixel
   breite Fuge, durch die der Grund dieses Kastens scheint - damit liegt er
   ueber die volle Hoehe und aendert sich nicht beim Ueberfahren.

   `overflow: hidden` schneidet beide Haelften auf die Pille zu; deshalb
   duerfen sie innen keine eigenen Ecken haben (siehe `.stickybar__b` und
   `borderRadius` in js/main.js). */
.stickybar__akt {
  /* Raster, nicht Flex. Mit `flex-basis: 50%` an beiden Haelften hat der
     Kasten selbst keine Breite mehr, aus der die 50 Prozent kommen
     koennten - gemessen 21.08.2026: 128 Pixel gesamt, 63 je Haelfte, und
     "Add to cart" wurde vom `overflow: hidden` abgeschnitten.

     `1fr 1fr` misst dagegen die breiteste Haelfte und gibt beiden dieses
     Mass: 254 Pixel gesamt, 127 je Haelfte, ohne feste Zahl im Stil. */
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  /* Eine Kapsel, zwei Segmente - keine Fuge.

     Zwischenzeitlich stand hier `gap: 1px` mit einem hellen Grund, der als
     Trennstrich durchschien. Vorgabe 22.08.2026: die beiden Haelften sollen
     wieder aneinanderstossen, aussen eine durchgehende Rundung, in der
     Mitte eine saubere Naht. Die Farben trennen die Segmente ohnehin -
     Apple Pay schwarz, der Warenkorb in --ink. */
  gap: 0;
  border-radius: 999px;
  overflow: hidden;
}
/* Beide Haelften auf 50 % Basis statt 0. Bei `flex-basis: 0` verteilt der
   Flexkasten nur den freien Platz - die Innenpolsterung des Knopfes kommt
   obendrauf, und er wurde 213 breit gegen 177. Mit 50 % ist die Haelfte
   die Haelfte, Polster inbegriffen. Gemessen 20.08.2026. */
/* Haelfte, nicht 11rem. Fest gesetzt war Apple Pay 176 Pixel breit und der
   Warenkorb nur so breit wie sein Text - "das apple pay soll nicht so
   riesig sein im Gegensatz zu add to cart", 21.08.2026. */
.stickybar__ex {
  display: block;
  min-width: 0;
  /* Grund in der Farbe der Leiste, solange die Haelfte leer ist.

     Die Haelfte steht von Anfang an frei, damit der Warenkorbknopf nicht
     springt, wenn Apple Pay nachkommt. Ohne eigenen Grund schien darin der
     Grund des Elternteils durch - `rgba(255,255,255,0.38)`, der Weissschleier,
     aus dem der 1-Pixel-Trennstrich gemacht ist. Auf der ganzen Haelfte
     ergab das ein helles Rechteck neben dem Warenkorbknopf, und das war
     das eigentlich Auffaellige am Warten: gemeldet 22.08.2026 als "haengt
     echt hinterher".

     Mit `--paper` ist die leere Haelfte von der Leiste nicht zu
     unterscheiden - sichtbar bleibt nur die Fuge, so wie gedacht. Kommt
     der Knopf, legt er sich darueber. */
  background: var(--paper);
  /* `contain: inline-size` ist hier kein Feinschliff, sondern der Grund,
     warum die Leiste ihre Breite behaelt.

     Stripe setzt in diesen Kasten ein iframe. Ein iframe ohne eigene
     Breitenangabe bringt 300 Pixel Eigenbreite mit, und `1fr 1fr` misst
     die breiteste Haelfte: damit wurde aus 2 x 127 Pixeln 2 x 292, die
     Leiste 585 statt 254 Pixel breit. Stripes `min-width: 100%` am iframe
     hilft nicht - beim Ermitteln der Inhaltsbreite zaehlt der Eigenwert.

     In Chrome faellt das nie auf: dort gibt es kein Apple Pay, der Kasten
     traegt `hidden` und liegt auf `display: none`. Sichtbar wird es erst
     auf Safari und am Telefon. Gemessen am 21.08.2026, indem der Kasten
     von Hand sichtbar geschaltet wurde.

     Mit der Eindaemmung zaehlt der Inhalt fuer die Breite nicht mehr mit:
     die Spalte kommt vom Warenkorbknopf, das iframe folgt ihr. Die 4 Pixel,
     die es links und rechts uebersteht, sind Stripes durchsichtiges
     Polster (`margin: -4px` bei `width: calc(100% + 8px)`) - der sichtbare
     Knopf deckt sich genau mit seiner Haelfte, und `overflow: hidden` am
     Elternteil schneidet nur das Polster weg. */
  contain: inline-size;
}
.stickybar__ex[hidden] { display: none; }

/* --- Der Platz fuer Apple Pay steht von Anfang an ---------------------
   Vorgabe 22.08.2026, nach genauer Beobachtung: das Problem war nie, dass
   Apple Pay Zeit braucht - sondern dass sein Platz erst entsteht, wenn es
   da ist. Die Kaufkarte wuchs dabei um 58 Pixel.

   Drei Vorgaenge laufen nacheinander, und jeder brauchte bisher Platz, den
   es noch nicht gab: die Pruefung, ob das Geraet zahlen kann; das Laden von
   Stripe; das Einsetzen des Knopfes. Jetzt laufen alle drei INNERHALB einer
   Flaeche, die bereits ihre endgueltige Groesse hat.

   Deshalb steht am Kasten kein `hidden` mehr (build/site.py) und hier kein
   `display: none`. Die Flaeche ist im ersten gezeichneten Bild da, leer und
   in Endgroesse - Stripe fuellt sie nur noch.

   Was davor stand und weg ist: eine Klasse aus dem Kopf, die den Platz erst
   freigab, wenn `ApplePaySession.canMakePayments()` ja sagte. Beim Melder
   ist sie nie angesprungen, und der Grund liess sich von hier aus nicht
   feststellen. Eine Reservierung, die von einer Erkennung abhaengt, ist
   ohnehin die falsche Konstruktion: sie kann genau dann fehlen, wenn sie
   gebraucht wird.

   Und keine nachgebaute Pille mehr. Ein Knopf, den Apple nicht gezeichnet
   hat, gehoert dort nicht hin - die Flaeche bleibt leer, bis der echte
   kommt. */
.pdp__express { min-height: 50px; }

/* Meldet Stripe, dass es gar keine Brieftasche gibt, klappt der Platz zu.
   Das ist der einzige verbleibende Groessenwechsel - und er trifft nur
   Geraete, auf denen nie ein Knopf erschienen waere. */
.pdp__express[hidden], .stickybar__ex[hidden] { display: none; }

/* Der Warenkorbknopf in der Leiste.

   Diese Regel war am 22.08.2026 verschwunden - einer meiner Schnitte am
   Platzhalter-Block hat sie mitgenommen. Ohne sie fiel der Knopf auf `.btn`
   zurueck: 999px Rundung statt eckig, keine feste Hoehe, 0,95rem statt
   0,82. In der beschnittenen Kapsel ergab die Rundung eine Kerbe an der
   Naht. Wiederhergestellt mit denselben Werten wie vorher.

   Innen eckig, aussen rund: die Kapsel sitzt an `.stickybar__akt` und wird
   dort beschnitten. Haette die Haelfte eigene Ecken, laege eine Pille in
   einer Pille.

   Hoehe genau wie die Apple-Pay-Flaeche daneben (buttonHeight 46 in
   js/main.js) - sonst steht die Naht schief.

   `min-width: 0`, weil Rasterkinder sonst so breit werden wollen wie ihr
   Text; zwei Haelften sind nur dann Haelften, wenn beide unter ihre
   Inhaltsbreite duerfen.

   Keine Sperrung: die Kasse und der Kaufknopf oben laufen auf `normal`,
   nur die Leiste trug 0,06em und las sich auseinandergezogen. */
.stickybar__b {
  height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  border-radius: 0;
  padding-inline: 2em;
  font-size: 0.82rem;
  letter-spacing: normal;
  white-space: nowrap;
}

/* --- Auf dem Telefon bleiben nur die Knoepfe ---------------------------
   Name und Preis fallen weg: die Breite reicht nicht fuer beides, und der
   Name steht dort ohnehin dreimal ueber der Leiste. Die beiden Knoepfe
   teilen sich die volle Breite haelftig - so, wie es vorher war, nur eckig
   und ohne Band darunter. */
@media (max-width: 640px) {
  .stickybar__stueck { display: none; }
  .stickybar__akt { width: 100%; }
  .stickybar__ex { flex: 1 1 50%; }
  .stickybar__b { flex: 1 1 50%; padding-inline: 0.8em; }
}
.nur-m { display: none; }
@media (max-width: 640px) {
  .nur-m { display: inline; }
}
.stickybar__b[disabled] { opacity: 0.45; cursor: not-allowed; }

@media (max-width: 900px) {
  /* Eine Spalte statt zwei. Das ist der Umbruch der Anordnung und gilt ab
     hier; die Telefon-Optik steht weiter unten bei 640px und nicht hier -
     ein schmales Fenster am Rechner ist kein Telefon. Gemeldet am
     21.08.2026 bei 760 Pixeln Fensterbreite: dort wurden aus der randlosen
     Aufnahme zwei 760 x 760 grosse, fast leere Quadrate uebereinander. */
  .pdp { grid-template-columns: 1fr; padding-top: var(--head-h); }
  .pdp__media { position: static; }
  .pdp__buy { align-items: center; text-align: center; padding-top: 0; }
  .pdp__lede { margin-inline: auto; }
  .pdp__opts { justify-content: center; }
}

/* --- Wer in der Bilderfolge steht ---------------------------------------
   Im HTML stehen vier Aufnahmen: angle, model1, flat, macro. Je Breite
   faellt eine weg, damit es beide Male drei sind (siehe build/site.py).

     Telefon   alle vier - model1 ist Slide 2
     Schirm    drei - model1 steht in der eigenen Spalte

   js/main.js baut seine Liste aus den eingeblendeten Elementen; `display:
   none` genuegt hier also, es braucht keine zweite Stelle im Skript. */
@media (min-width: 641px) {
  [data-nur="handy"] { display: none; }
}
/* Die Modelaufnahme ist ein Foto, kein freigestelltes Stueck.

   `.shot` traegt `mix-blend-mode: multiply` - der Griff, mit dem die
   Studioaufnahmen auf dem Untergrund sitzen. Auf ein Foto gehoert er
   nicht, und im Rahmen faellt das hart aus: `.pdp__frame.is-on` traegt
   `z-index: 1` und bildet damit einen eigenen Stapelzusammenhang; die
   Mischung fand darin nichts vor und die Aufnahme blieb unsichtbar - eine
   leere Flaeche in --bone. Gemessen am 21.08.2026: Rahmen auf Deckkraft 1,
   Bild geladen, Bildpunkte dunkel (63,63,63) - und trotzdem nichts zu
   sehen.

   In der eigenen Spalte am Schirm faellt es nicht auf: dort gibt es keinen
   eigenen Stapelzusammenhang, und die Mischung laeuft gegen die Seite. */
.pdp__frame[data-nur="handy"] .shot { mix-blend-mode: normal; }

/* --- Telefon ------------------------------------------------------------
   Die Optik nach dem Vorbild, Vorgabe 21.08.2026. Sie hing zuerst an der
   900er-Grenze - das war falsch: dort bricht nur die Anordnung auf eine
   Spalte um, und das betrifft auch ein schmales Fenster am Rechner. Bei
   760 Pixeln standen dann zwei randlose 760 x 760 Quadrate uebereinander,
   in denen ein Armband verloren aussah.

   640px ist die Grenze, die die Kaufleiste schon fuer Name und Preis
   benutzt; damit gibt es eine Telefongrenze im Stil und nicht zwei. Die
   Grenze in js/main.js fuer die durchgehende Leiste muss dieselbe sein,
   sonst gibt es Breiten ganz ohne Kaufknopf. */
@media (max-width: 640px) {
  /* Randlos: die Aufnahme laeuft von Kante zu Kante, statt als Karte auf
     der Seite zu sitzen. */
  .pdp__media { padding-inline: 0; padding-top: 0; }

  /* --- Quadratisch, wie das Bild selbst --------------------------------
     Hier stand eine Hoehe, die sich vom Schirm ableitete
     (`calc(100svh - 15.7rem)`), damit "Objekt 01" unter die Falz rutscht.
     Der Preis dafuer war zu hoch: die Studioaufnahmen sind quadratisch, in
     einem hoeheren Feld standen sie mit `contain` zwischen zwei Baendern
     aus --bone. Auf dem Telefon las sich das als leerer Kasten zwischen
     Bild und Namen - gemeldet am 22.08.2026 als "randomer weisser Block",
     und die Punkte rutschten mit nach unten.

     Ein Feld, das genauso hoch ist wie das Bild darin, hat keine Baender.
     Deshalb zurueck zum Quadrat. Dass die Objektkennung damit auf grossen
     Telefonen wieder knapp ins erste Bild ragen kann, ist der bewusste
     Tausch: ein leerer Kasten ueber dem Produktnamen ist der groessere
     Fehler.

     Die Modelaufnahme fuellt das Quadrat mit `cover` - sie ist ein Foto im
     Hochformat, ein Beschnitt oben und unten ist dort richtig. */
  .pdp__frame[data-nur="handy"] .shot { height: 100%; object-fit: cover; }
  /* Nur die Punkte behalten den Satzspiegel. */
  .pdp__linien { padding-inline: var(--pad); }
  /* Links statt mittig - mittig gesetzte Flattersaetze sind auf 375 Pixeln
     der Grund, warum eine Seite unruhig wirkt. */
  .pdp__buy { align-items: flex-start; text-align: left; }
  .pdp__lede { margin-inline: 0; }
  .pdp__opts { justify-content: flex-start; }

  /* Preis direkt unter den Namen, nicht hinter die Beschreibung: erst was
     und was es kostet, dann warum. Ueber `order`, damit das HTML bleibt und
     der Schirm unberuehrt ist - dort steht der Preis bewusst als ruhige
     Zeile ueber den Knoepfen. Kindselektor, damit die Beschriftung im
     Groessenwaehler nicht mitzaehlt. */
  .pdp__buy > .pdp__name { order: 1; }
  .pdp__buy > .pdp__preis { order: 2; margin-top: 0.35rem; }
  /* Die Pflichtangaben gehoeren an den Preis, auch hier. Gleiche `order`
     wie er: bei gleichem Wert entscheidet die Reihenfolge im HTML, und dort
     stehen sie direkt darunter. Was sie an Hoehe kosten, nimmt die Zeile
     darunter wieder weg - siehe dort. */
  .pdp__buy > .pdp__preishinweis { order: 2; }
  /* Der Abstand ist hier kein Geschmack, sondern die Falz.

     Ueber ihm endet der erste Eindruck: Bild, Punkte, Name, Preis. Unter
     ihm faengt die Seite an. 3,5rem sorgen zusammen mit der Bildhoehe
     dafuer, dass "Object 01" auch auf einem grossen Telefon mit
     eingeklappter Safari-Leiste (rund 800 Pixel sichtbar) unter der
     Kaufleiste bleibt. */
  .pdp__buy > .eyebrow { order: 3; margin-top: 3.5rem; }
  .pdp__buy > .pdp__lede { order: 4; }
  .pdp__buy > .pdp__variants { order: 5; }
  .pdp__buy > .pdp__aktion { order: 6; }

  /* Der Name als Produktname, nicht als Schlagzeile.

     Er traegt `.display` und damit die Millionaire Roman in bis zu 4,6rem -
     richtig am Schirm, wo er die Ueberschrift der Seite ist. Im kurzen
     Kopfbereich am Telefon steht darunter nur noch der Preis, und dort
     wirkt dieselbe Schrift wie ein Zitat, nicht wie eine Bezeichnung.
     Vorgabe 21.08.2026: ruhig, klein, links, nicht dekorativ.

     `.pdp__buy .pdp__name` bringt (0,2,0) und schlaegt damit `.display`
     und `.d-l`, ohne dass irgendwo !important noetig waere. Andere Stellen
     mit `.display` bleiben unberuehrt. */
  .pdp__buy .pdp__name {
    font-family: var(--f-sans);
    font-size: 1.4rem;
    line-height: 1.25;
    letter-spacing: 0.005em;
    margin: 0;
  }

  /* Punkte statt Miniaturen. Am Schirm sagt eine Miniatur, was einen
     erwartet; am Telefon macht die Reihe aus einer ruhigen Folge eine
     Werkzeugleiste. Der Fortschrittsbalken faellt weg - an einem 7 Pixel
     grossen Punkt liest ihn niemand. */
  /* Der Punkt ist klein, der Knopf darf es nicht sein.

     Zuerst war der Knopf selbst der Punkt: 7 x 7 Pixel. `npm run mobil`
     hat das am 21.08.2026 gefangen - unter 24 Pixeln tippt man daneben,
     und drei Marken nebeneinander sind genau der Fall, in dem das zaehlt.
     Jetzt traegt der Knopf 24 x 24 unsichtbar, der Punkt sitzt als
     `::before` in seiner Mitte. `gap: 0`, weil die Trefferflaechen den
     Abstand schon mitbringen; sichtbar bleiben rund 17 Pixel zwischen den
     Punkten. */
  .pdp__linien { gap: 0; margin-top: 0.9rem; }
  .pdp__linie {
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 0;
    background: none;
    padding: 0;
    place-items: center;
  }
  .pdp__linie img { display: none; }
  .pdp__linie::after { display: none; }
  .pdp__linie::before {
    content: "";
    width: 0.44rem;
    height: 0.44rem;
    border-radius: 999px;
    background: var(--bone-line);
    transition: background 0.35s var(--ease);
  }
  .pdp__linie.is-on::before { background: var(--ink); }

  /* Die Modelaufnahme steht seit dem 21.08.2026 als Slide 2 IN der Folge,
     nicht mehr als eigener Block darunter (build/site.py). Die zweite
     Spalte bleibt hier also aus - sonst stuende dasselbe Bild zweimal. */

  /* Gekauft wird in der Leiste, die hier durchgehend steht (js/main.js).
     Zwei Stellen mit demselben Knopf sind eine zu viel.

     Verborgen wird nur `.pdp__zwei`, nicht der ganze `.pdp__aktion`: der
     Satz zu AGB und Widerrufsrecht steht darin und muss bleiben, die Leiste
     hat keinen eigenen. Er wird ohnehin von der Leisten-Instanz
     freigeschaltet - js/main.js sucht ihn global. Ist ein Stueck noch nicht
     kaeuflich, gibt es `.pdp__zwei` gar nicht; das Feld zum Vormerken
     bleibt unberuehrt. */
  .pdp__aktion .pdp__zwei { display: none; }

  /* Die Leiste ist hier kein Gast, der beim Scrollen erscheint, sondern
     Teil der Seite - also steht sie vom ersten Bild an.

     Bis zum 22.08.2026 hing auch am Telefon alles an js/main.js: erst
     musste Stripe geantwortet haben oder zweieinhalb Sekunden vergangen
     sein, dann lief eine Blende von einer Sekunde. Gemeldet als "erscheint
     viel zu spaet" - zu Recht: bis zu dreieinhalb Sekunden ohne
     Kaufmoeglichkeit, und die Knoepfe im Fluss gibt es hier ja nicht mehr.

     Im Stil statt im Skript, damit es keine Zeitfrage mehr ist: die Leiste
     ist im ersten gezeichneten Bild da. `transition: none`, weil eine
     Blende nur Sinn hat, wenn etwas erscheint - hier erscheint nichts, hier
     steht etwas. */
  .stickybar {
    opacity: 1;
    pointer-events: auto;
    transition: none;
  }

  /* Solange Apple Pay noch nicht feststeht, nimmt der Warenkorbknopf die
     ganze Breite. Ohne das sass er in der linken Haelfte und sprang nach
     rechts, sobald die Zahlflaeche kam - und auf Geraeten ganz ohne
     Brieftasche bliebe die eine Haelfte fuer immer leer. */
  .stickybar__akt:has(.stickybar__ex[hidden]) .stickybar__b {
    grid-column: 1 / -1;
  }
}


.p-hero {
  background: var(--paper);
  min-height: 100svh;
  display: grid;
  place-items: center;
  position: relative;
  padding-top: var(--head-h);
}
.p-hero__art { width: min(76vw, 40rem); }
.p-hero__title {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(2.5rem, 10vh, 7rem);
  text-align: center;
}
.p-hero__title .script { font-size: clamp(3rem, 8vw, 7rem); display: block; margin-top: 0.1em; }

.feature { display: grid; grid-template-columns: 1fr 1fr; align-items: stretch; }
.feature--flip .feature__media { order: 2; }
/* Gedeckelt: die beiden Kapitel tragen rund 350 px Text,
   eine volle Fensterhoehe daneben ist auf hohen Schirmen vor allem Leere. */
.feature__media {
  position: sticky;
  top: 0;
  height: min(100svh, 46rem);
  display: grid;
  place-items: center;
  background: var(--bone);
  overflow: hidden;
}
.feature__media .shot { width: min(86%, 34rem); }
/* Eine Modellaufnahme ist kein freigestelltes Produktfoto: sie fuellt die
   Flaeche und wird beschnitten, statt mittig darin zu schweben. Und ohne
   `normal` legte sich multiply ueber das Foto und zoege es ins Beige des
   Untergrunds - das ist fuer freigestellte Aufnahmen gedacht, nicht fuer
   Fotografie. Vorgabe 19.08.2026. */
.feature__media .shot--voll {
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: normal;
}
.feature__body {
  background: var(--paper);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 1.2rem;
  padding: clamp(4rem, 12vh, 9rem) clamp(1.5rem, 5vw, 5rem);
}
.feature__body p { max-width: 42ch; color: var(--ink); }
.feature__body .shot { width: min(76%, 22rem); margin-block: 0.5rem; }

/* Vier Kennwerte nebeneinander.

   Das ist die technische Flaeche der Seite, kein Kapitel: die Beschriftung
   klein in Versalien, der Wert darunter lesbar in der Display. Bis zum
   17.08.2026 war es umgekehrt - "Konstruktion", "Material", "Oberflaeche"
   und "Laenge" standen in der Script, so gross wie die Ueberschrift des
   Materialkapitels darunter. Vier Zierwoerter, die nichts sagen, ueber vier
   Angaben, die alles sagen.

   Der Abschnitt ist ausserdem enger gesetzt als die Kapitel um ihn herum -
   die Seite soll einen Takt haben und nicht ueberall gleich weit atmen. */
.facts { background: var(--paper); padding-block: clamp(3rem, 7vh, 5.5rem); }
/* Kennwerte und Klappen stehen seit dem 21.08.2026 in einem Abschnitt
   (`.pdetails`, siehe build/site.py). Der Abstand dazwischen ist das
   Einzige, was der Zusammenschluss an eigenem Stil braucht - Polster und
   Grund kommen von `.section--tight`, das Raster von `.facts__grid`, die
   Klappen von `.klapp`. */
.pdetails__klapp { margin-top: clamp(2.5rem, 5vw, 4rem); }
/* Volle Breite wie die Kennwerte darueber.

   Ohne diese Regel faellt die Liste auf `.klapp { max-width: 30rem }`
   zurueck - das Mass der Kaufspalte, fuer die sie urspruenglich gebaut
   wurde. Im gemeinsamen Abschnitt sah das am 21.08.2026 so aus: die
   Kennwerte ueber die volle Breite, die drei Klappen als schmale Saeule
   links darunter, rechts daneben nichts. Die Breitenregel hing bis dahin
   an `.klapp-band .klapp`, und diese Klasse ist mit dem Zusammenschluss
   weggefallen - mein Fehler beim Umstellen.

   Beide Teile stehen jetzt auf denselben Kanten; das ist das Einzige, was
   den Abschnitt als einen lesen laesst. */
.pdetails .klapp { max-width: none; width: 100%; margin: 0; }
/* Die Linie darf ueber die volle Breite laufen, die Zeile nicht: bei 1560
   Pixeln Schale waere der Antworttext sonst 1560 Pixel lang. 46rem ist das
   Mass, das die Klappen schon als eigener Abschnitt hatten. */
.pdetails .klapp__t { max-width: 46rem; }
.facts__e { text-align: center; }
.facts__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.5rem, 3vw, 3rem);
  margin-top: clamp(1.8rem, 3.5vw, 2.6rem);
}
.fact { text-align: center; }
.fact__k {
  display: block;
  font-family: var(--f-ext);
  font-size: clamp(0.58rem, 0.54rem + 0.14vw, 0.68rem);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  line-height: 1.5;
  color: var(--muted-dark);
}
.fact__v {
  display: block;
  margin-top: 0.65rem;
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 0.98rem + 0.4vw, 1.35rem);
  line-height: 1.25;
  color: var(--ink);
  text-wrap: balance;
}

/* Drei Spalten. Steht als <dl> im Markup: Sitz, Kombination und Pflege sind
   Begriff und Erklaerung, nicht drei beliebige Textbloecke. */
/* Drei Zeilen, nicht drei Spalten. Vorgabe 19.08.2026: der Block sah
   ungeordnet aus - und das lag nicht an der Schrift, sondern am Raster.
   In der halben Spalte einer feature-Sektion blieben je Spalte rund 110 px;
   darin standen drei Texte von einer, zwei und drei Zeilen nebeneinander
   und liessen unten eine Treppe stehen. Als Zeilen gelesen - Bezeichnung
   links, Satz rechts - ist die Kante gerade, egal wie lang die Saetze sind.

   Achtung beim Raster: die Eintraege stecken je in einem <div>, nicht als
   dt/dd nebeneinander. Ein Zweispalter auf .trio selbst greift deshalb auf
   die Wrapper und wirft den dritten Eintrag in die erste Spalte zurueck.
   Die Zeile ist der Wrapper, nicht die Liste. */
.trio {
  display: grid;
  grid-template-columns: 1fr;
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
  width: 100%;
  max-width: 34rem;
  /* Die Sektion ist zentriert, diese Liste nicht. Zentriert stuenden drei
     Saetze verschiedener Laenge mit drei verschiedenen linken Kanten
     untereinander - genau die Unordnung, die den Block ausgemacht hat. */
  text-align: left;
}
.trio > div {
  display: grid;
  grid-template-columns: minmax(5rem, 7rem) 1fr;
  column-gap: clamp(1rem, 2.5vw, 2rem);
  align-items: baseline;
  padding: 0.85rem 0;
  border-top: var(--rule) solid var(--bone-line);
}
.trio > div:first-child { border-top: 0; padding-top: 0; }
.trio > div:last-child { padding-bottom: 0; }

.trio__k {
  display: block;
  margin: 0;
  font-family: var(--f-ext);
  font-size: clamp(0.58rem, 0.54rem + 0.14vw, 0.68rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.trio__v {
  display: block;
  margin: 0;
  font-size: 0.92rem;
  line-height: 1.6;
  color: var(--ink);
  text-wrap: pretty;
}

/* Auf schmalen Schirmen untereinander - zwei Spalten waeren dort je 40
   Zeichen breit. */
@media (max-width: 520px) {
  .trio > div { grid-template-columns: 1fr; }
  .trio__v { margin-top: 0.4rem; }
}

.trio__btn { margin-top: clamp(2rem, 4vw, 2.6rem); }

/* Weitere Stücke */
.next { background: var(--bone); padding-block: clamp(3.5rem, 9vh, 7rem); text-align: center; }
.next__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 3vw, 3rem); margin-top: clamp(2rem, 4vw, 3rem); }

/* Die Zahl der Karten schwankt: Produktseiten zeigen drei Nachbarn, Artikel
   je nach Beitrag zwei oder vier genannte Stücke. Bei festen drei Spalten
   bliebe im Zweierfall eine Spalte leer, und vier Karten brächen zu 3 + 1 um.
   Die Kartenbreite von 408 px bleibt im Zweierfall erhalten, die Reihe wird
   nur zentriert — damit sieht das Modul überall gleich aus. */
@media (min-width: 641px) {
  .next__grid[data-count="2"] {
    grid-template-columns: repeat(2, minmax(0, 25.5rem));
    justify-content: center;
  }
  .next__grid[data-count="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@media (min-width: 641px) and (max-width: 900px) {
  .next__grid[data-count="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Katalogblatt statt Produktreihe.
   Die Aufnahmen sind Quadrate, in denen oben und unten je ein Drittel leer
   steht — im Raster liest sich das Stueck dadurch klein und die Reihe wie
   eine Liste im Handel. Der Rahmen schneidet auf 3:2 zu: beschnitten wird
   ausschliesslich der leere Grund, das Stueck sitzt zwischen 32 und 68
   Prozent der Hoehe und bleibt vollstaendig. Dazu ein engerer Abstand,
   damit die vier als ein Feld gelesen werden. */
.next--katalog .next__grid { gap: clamp(1.5rem, 3vw, 2.6rem); }
.next--katalog .card__frame { aspect-ratio: 3 / 2; }
.next--katalog .card__frame .shot { height: 100%; object-fit: cover; }
.next--katalog .card__tag { margin-top: 1.2rem; }

/* Der Knopf schliesst die Seite. Genug Abstand, dass er nicht an den
   Stuecken klebt - nicht so viel, dass er allein im Feld steht. */
.next--katalog .btn { margin-top: clamp(2.4rem, 4.5vw, 3.6rem); }

@media (max-width: 900px) {
  .icons, .feature { grid-template-columns: 1fr; }
  /* `static` war hier falsch. Das Video im Inneren liegt `absolute` mit
     inset: 0 und braucht dafuer einen positionierten Vorfahren. Am
     Schreibtisch ist das `sticky` und alles sitzt; auf dem Telefon fiel der
     Bezug weg, und das Video hing am Fenster statt an seinem Abschnitt.

     Sichtbar war das als schwarze Aufnahme ganz oben auf der Seite und als
     dunkler Balken an der Stelle, an der sie eigentlich haette stehen
     sollen - der Grund des Kastens, den nichts mehr fuellte.

     `relative` aendert am Fluss nichts und stellt den Bezug wieder her. */
  .feature__media { position: static; height: auto; min-height: 52svh; }
  /* Nur .icons__aside, nicht .feature__media: der Fehler steckt in diesem
     einen Bauteil, und an den Produktseiten ist nichts zu reparieren. */
  .icons__aside { position: relative; height: auto; min-height: 52svh; }
  /* Im gespiegelten Block steht die Liste zuerst im Markup, damit sie auf
     breiten Fenstern links liegt. Einspaltig stuenden die Stuecke damit vor
     ihrer eigenen Ueberschrift - deshalb hier zurueck nach oben. */
  .icons--flip .icons__aside { order: -1; }
  .feature--flip .feature__media { order: 0; }
  .facts__grid { grid-template-columns: repeat(2, 1fr); row-gap: 2.5rem; }
}

@media (max-width: 640px) {
  .trio, .next__grid { grid-template-columns: 1fr; }
  /* Bis zum 20.08.2026 blieben die Kennwerte hier zweispaltig, mit der
     Begruendung, einspaltig seien es vier Zeilen und damit ein halber
     Bildschirm fuer vier Angaben. Das stimmt - aber zweispaltig blieben je
     Spalte rund 185 px, und darin bricht "316L stainless steel" mitten im
     Wort um. Vier ruhige Zeilen sind besser zu lesen als vier zerhackte
     Halbe. Umgestellt auf Vorgabe. */
  .facts__grid { grid-template-columns: 1fr; column-gap: 1.2rem; row-gap: 1.6rem; }
  /* Linksbuendig, Vorgabe 20.08.2026. Untereinander gelesen ist eine
     gerade linke Kante die Ordnung; mittig stuenden vier Zeilen mit vier
     verschiedenen Anfaengen. */
  .facts__e { text-align: left; }
  .fact { text-align: left; }

  /* Kein einzelnes Wort auf einer Zeile.
     `pretty` zieht bei Bedarf ein Wort aus der vorletzten Zeile herunter,
     damit die letzte nicht allein dasteht - genau der Fall, der gemeldet
     wurde. Ueberschriften bleiben bei `balance`: dort sollen die Zeilen
     gleich lang sein, nicht nur die letzte gefuellt.
     Wo ein Browser das nicht kennt, aendert sich nichts - der Wert wird
     dann schlicht ignoriert. */
  p, li, dd, figcaption,
  .lede, .fact__v, .trio__v, .co__done, .pdp__lede, .aussage__t {
    text-wrap: pretty;
  }
}

/* --------------------------------------------------------------------------
   24. Preise
   -------------------------------------------------------------------------- */

.card__price {
  display: block;
  margin-top: 0.5rem;
  font-size: 0.92rem;
  color: var(--muted-dark);
}
.p-hero__price {
  margin-top: 0.6rem;
  font-size: 1.05rem;
  color: var(--muted-dark);
}

/* --------------------------------------------------------------------------
   25. Journal
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Library — Dreierreihe

   Drei hohe Bilder nebeneinander, darunter Titel und "Mehr lesen". Kein
   Kicker, keine Lesezeit, kein Anrisstext: die Karte soll aus einem Bild,
   einer Zeile und einem Weg bestehen, sonst wird sie eine Liste.

   Der Text steht unter dem Bild, nicht darauf. Solange die Beitragsaufnahmen
   weissen Hintergrund haben, ergibt Schrift mit Verlauf darueber Grau. Mit
   dunklen Aufnahmen kann er hinein.
   -------------------------------------------------------------------------- */

.cara { padding-block: clamp(3.5rem, 8vh, 6.5rem); background: var(--paper); }
.cara__head { display: grid; gap: 0.9rem; justify-items: start; }
.cara__head .tlink { margin-top: 0.4rem; }

.cara__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.2rem, 2.6vw, 2.6rem);
  margin-top: clamp(2.2rem, 5vw, 3.5rem);
}

.cara__card { display: flex; flex-direction: column; }
.cara__frame {
  display: block;
  aspect-ratio: 2 / 3;
  overflow: hidden;
  background: var(--bone);
}
.cara__frame img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}

.cara__title {
  display: block;
  margin-top: 1.4rem;
  font-family: var(--f-display);
  font-size: clamp(1.15rem, 1.55vw, 1.5rem);
  line-height: 1.2;
  color: var(--ink);
  transition: color 0.4s var(--ease);
}

/* Kein echter Knopf: die ganze Karte ist bereits der Link, ein zweites Ziel
   waere fuer die Tastatur derselbe Weg doppelt. */
.cara__go {
  align-self: flex-start;
  margin-top: 1rem;
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-dark);
  padding-bottom: 0.35em;
  border-bottom: var(--rule) solid var(--bone-line);
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.cara__card:hover .cara__go { border-color: currentColor; }

/* Zwei Spalten mit drei Karten lassen einen Nachzuegler in der zweiten Reihe.
   Das ist richtig so - die dritte Karte auszublenden waere ein Beitrag
   weniger, nur damit das Raster aufgeht. */
@media (max-width: 900px) { .cara__grid { grid-template-columns: repeat(2, 1fr); } }

/* --- Auf dem Telefon eine Wischreihe -------------------------------------
   Einspaltig untereinander war jede Karte 92 vw breit und im Verhältnis
   2:3 fast anderthalb Bildschirme hoch. Man sah einen Beitrag, scrollte
   an ihm vorbei, sah den nächsten — von einer Auswahl war nichts zu
   merken.

   Jetzt liegen die Karten nebeneinander und werden gewischt. Eine Karte
   nimmt 66 % der Breite ein, die nächste schaut am rechten Rand herein
   und sagt damit, dass es weitergeht. `scroll-snap` lässt sie einrasten,
   damit nie eine halbe Karte stehenbleibt.

   Die Reihe läuft bis an beide Ränder — das Wischen soll dort anfangen
   dürfen, wo der Daumen liegt. Der Innenabstand steckt deshalb in der
   Reihe selbst, nicht im Rahmen darum.                                   */
@media (max-width: 640px) {
  .cara__grid {
    grid-template-columns: none;
    grid-auto-flow: column;
    /* Schmaler als zuvor: bei 66 % blieb neben der zentrierten Karte kein
       Platz mehr für zwei Nachbarn. */
    --cara-karte: min(58vw, 15rem);
    grid-auto-columns: var(--cara-karte);
    gap: 0.85rem;

    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;

    /* Aus der Inhaltsbreite heraus bis an die Fensterkanten. */
    max-width: none;
    width: 100vw;
    margin-left: 50%;
    transform: translateX(-50%);
    padding-bottom: 0.4rem;

    /* Die aktive Karte steht in der Mitte, links und rechts schaut je eine
       Nachbarkarte herein. Der Innenabstand ist genau der halbe Rest neben
       der Karte — dadurch liegt schon die erste mittig, und die letzte
       kommt bis in die Mitte, statt am Rand zu kleben.

       Ohne das begann die Reihe bündig links: ein Scrollstreifen mit einem
       angeschnittenen Nachbarn rechts. Nicht dasselbe. */
    padding-inline: calc((100vw - var(--cara-karte)) / 2);
    scroll-padding-inline: calc((100vw - var(--cara-karte)) / 2);
  }
  /* Die Leiste selbst bleibt unsichtbar; gewischt wird mit dem Finger. */
  .cara__grid::-webkit-scrollbar { display: none; }
  .cara__grid { scrollbar-width: none; }

  .cara__card { scroll-snap-align: center; }
  /* 4:5 statt 2:3 — dasselbe Bild, deutlich weniger Höhe. */
  .cara__frame { aspect-ratio: 4 / 5; }
  .cara__title {
    margin-top: 0.75rem;
    font-size: 0.95rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  /* „Lesen" wiederholt nur, was die ganze Karte als Verweis schon ist. */
  .cara__go { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .cara__frame img { transition: none; }
}

/* --------------------------------------------------------------------------
   Philosophie

   Aufbau nach Aesop: links der Abschnittstitel, rechts der Inhalt. Dasselbe
   Raster in jedem Abschnitt, dazwischen eine feine Linie - die Seite darf
   lang sein, solange man von aussen sieht, wo man ist.

   Schriften bleiben: Titel in der Anzeigeschrift, Text in der Grotesk.
   -------------------------------------------------------------------------- */

.phil__body { max-width: 72rem; padding-block: clamp(2.5rem, 7vh, 5rem); }

/* Der Auftaktsatz steht ueber allem, mittig und gross. */
.phil__satz {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 3vw, 2.5rem);
  line-height: 1.24;
  text-align: center;
  max-width: 26ch;
  margin: 0 auto clamp(3rem, 8vh, 6rem);
}

.phil {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.7fr);
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-block: clamp(2.5rem, 6vw, 4.5rem);
  border-top: var(--rule) solid var(--bone-line);
}
.phil__seite h2 {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 2.6vw, 2.2rem);
  line-height: 1.15;
}
.phil__inhalt > * + * { margin-top: 1.4rem; }
.phil__inhalt p {
  font-size: clamp(1rem, 1.05vw, 1.08rem);
  line-height: 1.75;
  color: var(--muted-dark);
  max-width: 52ch;
}
.phil__inhalt h3 {
  font-family: var(--f-sans);
  font-size: 0.95rem;
  /* 500 lag ausserhalb des vorhandenen Bereichs (300-400) und wurde vom
     Browser nachgerechnet. Die Zwischenzeile unterscheidet sich ohnehin
     ueber Schriftart, Groesse und Farbe. */
  font-weight: 400;
  color: var(--ink);
  margin-top: 2.2rem;
}
.phil__inhalt h3 + p { margin-top: 0.5rem; }

/* Die Ankerliste steht unter dem ersten Titel und bleibt beim Scrollen
   stehen, solange links Platz ist. */
.phil__anker { display: grid; gap: 0.8rem; margin-top: 1.8rem; }
.phil__anker a {
  font-size: 0.92rem;
  color: var(--muted-dark);
  transition: color 0.4s var(--ease);
}

.phil__zahlen {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  padding: clamp(2.5rem, 6vw, 4rem) clamp(1.5rem, 4vw, 3rem);
  margin-block: clamp(1rem, 3vw, 2rem);
  background: var(--bone);
}
.phil__zahlen strong {
  display: block;
  font-family: var(--f-display);
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  font-weight: 400;
  line-height: 1.1;
}
.phil__zahlen span {
  display: block;
  margin-top: 0.7rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--muted-dark);
  max-width: 26ch;
}

.phil__raster {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.4rem, 3vw, 2.4rem);
  margin-top: 2rem;
}
.phil__raster h3 {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  margin-top: 0;
  padding-top: 0.9rem;
  border-top: var(--rule) solid var(--bone-line);
}
.phil__raster p { margin-top: 0.7rem; font-size: 0.94rem; }

.phil__weiter {
  display: flex; flex-wrap: wrap;
  gap: 0.6rem clamp(1.2rem, 3vw, 2.2rem);
  margin-top: 2rem;
}
.phil__weiter a {
  font-family: var(--f-ext); font-size: 0.64rem; letter-spacing: 0.26em;
  text-transform: uppercase; color: var(--ink);
  border-bottom: var(--rule) solid var(--bone-line); padding-bottom: 0.3em;
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.phil__weiter a:hover { border-color: currentColor; }

@media (max-width: 820px) {
  .phil { grid-template-columns: 1fr; gap: 1.2rem; }
  .phil__zahlen { grid-template-columns: 1fr; }
  .phil__raster { grid-template-columns: 1fr; }
}

/* Kopf mittig, wie der Satz darunter. */
.art__head--mitte { text-align: center; }
.art__head--mitte .shell { max-width: 44rem; }

.story__body {
  max-width: 46rem;
  text-align: center;
  padding-block: clamp(3rem, 9vh, 7rem);
}
.story__satz {
  font-family: var(--f-display);
  font-size: clamp(1.6rem, 3.1vw, 2.6rem);
  line-height: 1.24;
  margin-bottom: clamp(2rem, 5vw, 3.2rem);
}
.story__body p {
  font-size: clamp(1rem, 1.1vw, 1.12rem);
  line-height: 1.75;
  color: var(--muted-dark);
  max-width: 40ch;
  margin: 0 auto clamp(1.2rem, 2.5vw, 1.8rem);
}
.story__weiter {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: 0.6rem clamp(1.4rem, 3vw, 2.6rem);
  margin-top: clamp(2.4rem, 5vw, 3.5rem);
}
.story__weiter a {
  font-family: var(--f-ext); font-size: 0.64rem; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--ink);
  border-bottom: var(--rule) solid var(--bone-line); padding-bottom: 0.3em;
  transition: color 0.4s var(--ease), border-color 0.4s var(--ease);
}
.story__weiter a:hover { border-color: currentColor; }

.art__head {
  background: var(--bone);
  padding-top: calc(var(--head-h) + clamp(3.5rem, 10vh, 7rem));
  padding-bottom: clamp(2.5rem, 6vw, 4.5rem);
  text-align: center;
}
.art__head .lede { max-width: 52ch; margin: 1.4rem auto 0; }
.art__head h1 { max-width: 22ch; margin-inline: auto; }
.art__date {
  margin-top: 1.6rem;
  font-family: var(--f-ext);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

/* Lesetypografie.

   Akzidenz Grotesk traegt Navigation und kurze Texte gut, ist als Leseschrift
   fuer tausend Woerter aber anstrengend: enge Punzen, wenig Unterschied
   zwischen aehnlichen Buchstaben. Fuer die Library steht deshalb die
   Anzeigeschrift im Fliesstext - eine Antiqua mit Serifen, die das Auge von
   Zeile zu Zeile fuehrt. Genau dafuer ist sie gemacht.

   Die Lesebreite bleibt bei 66 Zeichen statt 74: das ist die Spanne, in der
   ein Leser die naechste Zeile ohne Suchen findet. */
.art__body {
  max-width: min(66ch, 700px);
  padding-block: clamp(3rem, 8vh, 6rem);
  font-family: var(--f-display);
  font-size: clamp(1.08rem, 1rem + 0.4vw, 1.28rem);
  line-height: 1.72;
  letter-spacing: 0.004em;
}
/* Listen, Tabellen und Bildunterschriften bleiben in der Grotesk - dort geht
   es um Erfassen, nicht um Lesen im Fluss. */
.art__body table, .art__body figcaption, .art__body .eyebrow {
  font-family: var(--f-sans);
}
.art__body > * + * { margin-top: 1.4em; }
.art__body h2 {
  font-family: var(--f-display);
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1.16;
  margin-top: 2.4em;
  letter-spacing: -0.01em;
}
.art__body a {
  background-image: linear-gradient(var(--gold), var(--gold));
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: 0 100%;
  transition: color 0.3s var(--ease);
}
/* --------------------------------------------------------------------------
   Dankeseite: drei Ausgaenge

   Kommt jemand aus einer Zahlung (`?payment_intent=` in der Adresse), setzt
   ein kurzes Skript im Kopf der Seite `zahlung-prueft` auf <html>. Solange
   die Klasse steht, ist der Erfolgstext weg und nur die Wartezeile da.

   Ohne das stuende eine Zehntelsekunde lang "Danke - Ihre Bestellung ist
   eingegangen" vor jemandem, dessen Karte gerade abgelehnt wurde. Die
   Antwort von /api/checkout/status braucht einen Moment, und in genau
   diesem Moment darf die Seite nichts behaupten.

   js/main.js nimmt die Klasse bei Erfolg wieder weg. In den anderen beiden
   Faellen bleibt sie stehen - dann ist der Erfolgstext auch dauerhaft
   falsch. Wer ohne Zahlung auf die Seite kommt, bekommt die Klasse nie und
   sieht die Seite unveraendert; das gilt auch ohne JavaScript.
   -------------------------------------------------------------------------- */
.art__warten { display: none; }
.zahlung-prueft .art__warten:not([hidden]) { display: block; }
.zahlung-prueft [data-danke-erfolg] { display: none; }

/* Bestellnummer und Lage stehen in der Grotesk: das sind Angaben zum
   Nachschlagen, kein Fliesstext. Die Nummer etwas kleiner und ruhiger - sie
   wird abgeschrieben, nicht gelesen. */
.art__nr {
  font-family: var(--f-sans);
  font-size: 0.9rem;
  letter-spacing: 0.04em;
  color: var(--muted-dark);
}
.art__zurueck { margin-top: 2em; }

/* --------------------------------------------------------------------------
   Credo — ein Satz, ein Zeichen

   Der ruhigste Abschnitt der Seite und deshalb der grosszuegigste. Kein
   Bild, keine Schaltflaeche, kein zweiter Gedanke: nur der Satz, darunter
   eine Linie, die das Zeichen traegt.

   Die Linie laeuft nicht durch, sie laeuft auf das Zeichen zu und hoert
   dort auf - links und rechts je eine, in der Mitte das Signet. Sie ist
   heller als jede andere Linie der Seite (Trennlinien liegen bei 0,14
   Deckkraft), weil sie nichts trennt, sondern nur ein Mass gibt.
   -------------------------------------------------------------------------- */
.credo {
  /* Reichlich. Der Abschnitt steht seit dem 22.08.2026 an der Stelle des
     alten Auftakts, also direkt hinter dem Film - dort hat er den Platz,
     den ein einzelner Satz braucht, um einer zu sein. Vorgabe an dem Tag:
     "wo mehr white space sein kann". */
  padding-block: clamp(9rem, 26vh, 19rem);
  text-align: center;
}
.credo__inner { margin-inline: auto; }
.credo__satz {
  font-family: var(--f-display);
  /* Eine Stufe kleiner und ruhiger (Vorgabe 22.08.2026: "etwas kleiner
     und dezenter"). Der Satz soll nicht rufen - ihn traegt der Raum um ihn
     herum, nicht seine Groesse. Die Zeilen stehen dafuer etwas weiter
     auseinander. */
  font-size: clamp(1.3rem, 0.9rem + 1.55vw, 2.35rem);
  line-height: 1.36;
  letter-spacing: -0.008em;
  text-wrap: balance;
  margin: 0 auto;
  /* Enger als der uebrige Satzspiegel: ein Satz ueber die volle Breite wird
     gelesen wie ein Absatz, auf gut 30 Zeichen je Zeile wie eine Inschrift.

     `em` und nicht `ch`, und hier und nicht am Container. Zuerst stand
     `max-width: 30ch` auf `.credo__inner` - und `ch` misst an der Schrift
     DIESES Elements, nicht an der des Textes darin. Der Container erbt die
     Grundschrift mit 16 Pixeln, 30ch waren also rund 250 Pixel breit, und
     der Satz brach bei 46 Pixeln Schriftgroesse auf ein Wort je Zeile um.
     `em` an der Zeile selbst haengt an ihrer eigenen Groesse und geht mit
     der Schrift mit. */
  max-width: 24em;
}
.credo__signum {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(1.4rem, 4vw, 2.6rem);
  margin-top: clamp(2.6rem, 6vh, 4.4rem);
}
.credo__linie {
  display: block;
  height: 1px;
  /* Nicht auf eine feste Breite gesetzt: die beiden Linien teilen sich, was
     neben dem Zeichen uebrig ist, und bleiben damit auf jedem Schirm gleich
     lang. */
  flex: 1 1 0;
  /* Laenger (Vorgabe 22.08.2026). Vorher 9rem - das las sich wie zwei
     Striche neben dem Zeichen, nicht wie eine Linie, auf der es sitzt. Sie
     teilen sich weiterhin, was neben dem Zeichen uebrig ist, und schrumpfen
     auf dem Telefon von selbst mit. */
  max-width: 22rem;
  background: currentColor;
  opacity: 0.22;
}
.credo__zeichen {
  flex: none;
  width: clamp(26px, 3.4vw, 38px);
  height: auto;
  opacity: 0.72;
}

/* Auf dem Telefon weniger, nicht mehr.
   `26vh` waechst mit der Hoehe des Fensters - und ein Telefon ist hoch und
   schmal. Gemessen am 22.08.2026: 242 Pixel Polster auf einem 932 Pixel
   hohen Schirm gegen 208 am Schreibtisch. Das Geraet mit dem wenigsten
   Platz bekam also den meisten Leerraum, und der Satz stand in 71 statt 60
   Prozent Nichts. Hier gilt deshalb ein eigener, kleinerer Wert - er trifft
   denselben Anteil wie am Schreibtisch. */
@media (max-width: 900px) {
  .credo { padding-block: clamp(5rem, 15vh, 9.5rem); }
}

.art__list { padding-left: 1.2em; }
.art__list li { position: relative; padding-left: 1em; }
.art__list li + li { margin-top: 0.6em; }
.art__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.78em;
  width: 0.4em;
  height: 1px;
  background: var(--gold);
}
.art__back { text-align: center; padding-bottom: clamp(3rem, 7vh, 5rem); }

/* Vergleichstabellen: Haarlinien statt Kästen, wie überall sonst */
.art__tablewrap { overflow-x: auto; }
.art__table { width: 100%; border-collapse: collapse; font-size: 0.94rem; }
.art__table th, .art__table td {
  text-align: left;
  padding: 0.85rem 1.2rem 0.85rem 0;
  border-bottom: var(--rule) solid var(--bone-line);
  vertical-align: top;
}
.art__table th {
  font-family: var(--f-ext);
  font-size: 0.6rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  font-weight: 400;
  color: var(--muted-dark);
}

/* Häufige Fragen */
.faq { padding-top: 0; }
.faq__item + .faq__item { margin-top: 2em; }
.faq__q {
  font-family: var(--f-display);
  font-size: clamp(1.15rem, 1.6vw, 1.4rem);
  line-height: 1.25;
  margin-bottom: 0.5em;
}
.faq__a { color: var(--muted-dark); }

/* --------------------------------------------------------------------------
   26. Warenkorb
   Liegt im Browser; an der Kasse übernimmt Shopify.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Breadcrumbs
   Haarlinie unter der Kopfzeile, gleiche Sperrung wie die Eyebrows.
   -------------------------------------------------------------------------- */

.crumbs {
  background: var(--paper);
  padding-top: var(--head-h);
  border-bottom: var(--rule) solid var(--bone-line);
}
.crumbs__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  padding-block: 0.9rem;
  font-family: var(--f-ext);
  font-size: 0.58rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.crumb + .crumb::before { content: "/"; margin-right: 0.5rem; opacity: 0.5; }
.crumb a { transition: color 0.3s var(--ease); }
.crumb:last-child { color: var(--ink); }
.crumb span {
  display: inline-block;
  max-width: 34ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* Honeypot: für Menschen unsichtbar, für Bots ein Köder */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

/* Formular auf hellem Grund */
.access { max-width: 34rem; margin-inline: auto; }
.access__back { margin-top: clamp(2rem, 5vw, 3rem); text-align: center; }
/* Helle Formulare stehen in Kaesten statt auf Unterstrichen: ein Rahmen sagt,
   wo das Feld anfaengt und aufhoert. Auf dunklem Grund bleibt es beim
   Unterstrich - dort traegt die Linie genug. */
.form--light .field input,
.form--light .field select,
.form--light .field textarea {
  border: var(--rule) solid var(--bone-line);
  border-radius: 0.3rem;
  padding: 0 1.1rem;
  height: 3.4rem;
  line-height: normal;
  color: var(--ink);
}
.form--light .field textarea { height: auto; padding: 1rem 1.1rem; }
.form--light .field input:focus,
.form--light .field select:focus,
.form--light .field textarea:focus { border-color: var(--ink); }
.form--light .field label { margin-bottom: 0.5rem; }
/* Der Absendeknopf nimmt die Breite der Spalte, wie die Felder darueber. */
.form--light > div:has(> [type=submit]) { width: 100%; }
.form--light [type=submit] { width: 100%; }
.form--light .field label { color: var(--muted-dark); }
.form--light .field input::placeholder { color: rgba(13, 26, 47, 0.4); }
.form--light .form__note { color: var(--muted-dark); }
.field--check {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
}
.field--check input { width: 1rem; height: 1rem; margin-top: 0.35rem; flex: 0 0 auto; }
.field--check label {
  font-family: var(--f-sans);
  font-size: 0.88rem;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.55;
}
.field--check a { text-decoration: underline; text-underline-offset: 0.2em; }

.cart-btn { position: relative; }
/* Muss `.nav a, .nav span` schlagen. Die Regel hat mit (0,1,1) mehr Gewicht
   als eine einzelne Klasse (0,1,0) - der Zaehler blieb dadurch im Textfluss
   statt in der Ecke zu sitzen, und weil er als Flex-Kind Platz beanspruchte,
   schrumpfte das Warenkorbzeichen daneben auf 0,1 px. Man sah zwei getrennte
   Zeichen nebeneinander statt einer Zahl am Korb.

   `.nav .cart-btn__n` bringt (0,2,0) und gewinnt. Die Schriftvorgaben aus
   derselben Regel - Sperrung, Versalien, Innenabstand - werden mit
   zurueckgesetzt, sonst stehen sie weiter in der Zahl. */
.nav .cart-btn__n {
  /* Freie Ziffer statt Abzeichen - Vorgabe 21.08.2026 nach Hermes.

     Vorher sass die Zahl in einem gefuellten Kreis in Tinte, oben rechts
     ueber dem Korb. Der Kreis war das Schwerste in der ganzen Kopfzeile:
     eine volle Flaeche neben lauter 1,2-Pixel-Strichen. Bei Hermes steht
     dort nur die Ziffer, unten rechts an der Tasche, und mehr braucht es
     nicht - eine Eins ist auch ohne Kreis eine Eins.

     Kein Grund, kein Rund, keine Mindestbreite: damit faellt auch die
     Rechnerei zur optischen Mitte der Ziffer im Kreis weg, die hier
     frueher stand. `currentColor` statt fester Tinte, damit die Zahl auf
     dem dunklen Banner mit dem Symbol hell wird statt zu verschwinden -
     der Kreis konnte das nicht. */
  position: absolute;
  /* An die Tasche geruckt, nicht daneben gestellt: bei -0.42rem stand die
     Ziffer 6 Pixel frei rechts vom Korb und las sich als zweites Zeichen.
     -0.1rem setzt sie an die Ecke - derselbe Wert, den die beiden Regeln
     fuer sehr schmale Geraete (max-width: 374px) schon tragen; damit ist
     die Ausnahme dort keine mehr.

     Kein `top` und kein `height`: zusammen mit `bottom` wuerden sie die
     Box aufspannen statt sie zu setzen - bei einem Versuch mit beiden war
     die Ziffer 25,5 statt 9,6 Pixel hoch und stand ueber dem Korb. */
  right: -0.1rem;
  bottom: 0;
  letter-spacing: 0;
  text-transform: none;
  padding: 0;
  background: none;
  border-radius: 0;
  color: currentColor;
  font-family: var(--f-ext);
  font-size: 0.6rem;
  line-height: 1;
}
/* Dieselbe Falle wie bei .co__done und .lang__list: eine Klassenregel mit
   `display` schlaegt das hidden-Attribut. Das Abzeichen stand deshalb mit
   einer "0" ueber dem Warenkorb - dunkles Rund auf hellem Umriss, und auf
   dem dunklen Banner war vom Symbol nichts mehr zu erkennen.
   Gemeldet und gemessen am 20.08.2026. */
.cart-btn__n[hidden] { display: none; }

.cart {
  position: fixed;
  inset: 0;
  z-index: 100;
  visibility: hidden;
}
body.cart-open .cart { visibility: visible; }

.cart__veil {
  position: absolute;
  inset: 0;
  background: rgba(13, 26, 47, 0.5);
  opacity: 0;
  transition: opacity 0.5s var(--ease);
}
body.cart-open .cart__veil { opacity: 1; }

.cart__panel {
  position: absolute;
  top: 0;
  right: 0;
  width: min(26rem, 100%);
  height: 100%;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  padding: clamp(1.25rem, 3vw, 2rem);
  transform: translateX(100%);
  transition: transform 0.6s var(--ease);
}
body.cart-open .cart__panel { transform: none; }

.cart__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: 1.2rem;
  border-bottom: var(--rule) solid var(--bone-line);
}
.cart__x { font-size: 1.6rem; line-height: 1; padding: 0 0.3rem; }

.cart__empty { padding-block: 2rem; color: var(--muted-dark); }

.cart__list { flex: 1; overflow-y: auto; }
.cart__item {
  display: grid;
  grid-template-columns: 1fr auto auto;
  align-items: center;
  gap: 1rem;
  padding-block: 1.1rem;
  border-bottom: var(--rule) solid var(--bone-line);
}
.cart__name {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.cart__qty { display: inline-flex; align-items: center; gap: 0.55rem; }
.cart__qty button {
  width: 1.5rem;
  height: 1.5rem;
  border: var(--rule) solid var(--bone-line);
  border-radius: 50%;
  line-height: 1;
  transition: border-color 0.3s var(--ease), color 0.3s var(--ease);
}
.cart__qty button:hover { border-color: var(--ink); }
.cart__n { min-width: 1ch; text-align: center; font-size: 0.9rem; }
.cart__price { font-size: 0.9rem; white-space: nowrap; }

.cart__foot { padding-top: 1.3rem; border-top: var(--rule) solid var(--bone-line); }
.cart__sum {
  display: flex;
  justify-content: space-between;
  font-family: var(--f-ext);
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin-bottom: 1.1rem;
}
.cart__go { width: 100%; }
.cart__note { margin-top: 0.9rem; font-size: 0.78rem; color: var(--muted-dark); text-align: center; }

@media (prefers-reduced-motion: reduce) {
  .cart__panel, .cart__veil { transition: none; }
}

/* --------------------------------------------------------------------------
   Sortimentseite — Sachtext
   -------------------------------------------------------------------------- */

.coll__text { max-width: 62ch; margin-inline: auto; padding-block: clamp(1rem, 3vw, 2rem); }
.coll__text h2 { margin-bottom: 1.4rem; }
.coll__text h3 {
  margin-top: 2.4rem;
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.coll__text p { margin-top: 1rem; }
/* Global gilt `a { text-decoration: none }`. Im Fliesstext muss ein Verweis
   aber als Verweis erkennbar sein - sonst findet ihn weder ein Leser noch
   klickt jemand auf die Ratgeber, auf die die Seite verlinkt. */
.coll__text a {
  color: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--bone-line);
  text-underline-offset: 0.22em;
  transition: color 0.3s var(--ease), text-decoration-color 0.3s var(--ease);
}

/* Maßtabelle auf der Sortimentseite. Sie kann breiter werden als der Text,
   deshalb scrollt sie in ihrem eigenen Kasten statt die Seite zu sprengen. */
.masse__wrap { overflow-x: auto; margin-top: 1.2rem; }
.masse { width: 100%; border-collapse: collapse; font-size: 0.92rem; }
.masse th, .masse td {
  padding: 0.7rem 0.9rem 0.7rem 0;
  text-align: left;
  border-bottom: var(--rule) solid var(--bone-line);
  white-space: nowrap;
}
.masse thead th {
  font-family: var(--f-ext);
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.masse tbody th { font-weight: 400; }
.masse tbody th a { text-decoration: underline; text-decoration-color: var(--bone-line);
                    text-underline-offset: 0.22em; }

/* ===========================================================================
   JOURNAL — Uebersicht, Artikelbausteine, mobile Leiste
   ===========================================================================
   Ruhig gehalten: kein Kasten mit Schatten, keine Signalfarben. Struktur
   entsteht ueber Weissraum, Haarlinien und die vorhandene Typografie.
   =========================================================================== */

/* Kategorien unter der Ueberschrift der Uebersicht */
.jcats {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.6rem 1.6rem;
  margin-top: clamp(2rem, 5vh, 3.5rem);
  padding-top: 1.4rem;
  border-top: var(--rule) solid var(--bone-line);
}
.jcats__h {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.jcat {
  font-size: 0.94rem;
  padding-bottom: 0.15em;
  border-bottom: var(--rule) solid transparent;
  transition: border-color 0.4s var(--ease), color 0.4s var(--ease);
}

/* Hervorgehobener Hauptartikel */
.jlead {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  align-items: center;
  gap: clamp(1.5rem, 4vw, 4rem);
  padding-top: clamp(2rem, 5vh, 3.5rem);
  border-top: var(--rule) solid var(--bone-line);
}
.jlead__f {
  display: block;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--bone);
}
.jlead__f img, .jcard__f img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1.1s var(--ease);
}
.jlead__c { display: flex; flex-direction: column; gap: 0.8rem; }
.jlead__t {
  font-family: var(--f-display);
  font-size: clamp(1.7rem, 3.2vw, 2.9rem);
  line-height: 1.1;
  letter-spacing: -0.01em;
  transition: color 0.4s var(--ease);
}
.jlead__d { color: var(--muted-dark); max-width: 46ch; }
.jlead__m, .jcard__m {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

/* Kategoriegruppen und Artikelraster */
.jgroup { padding-block: clamp(3rem, 7vh, 5.5rem); }
.jgroup__h {
  font-family: var(--f-display);
  font-size: clamp(1.4rem, 2.2vw, 2rem);
  padding-bottom: 1.2rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.5rem);
  border-bottom: var(--rule) solid var(--bone-line);
}
.jgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(1.5rem, 3vw, 3rem);
}
.jcard { display: flex; flex-direction: column; gap: 0.7rem; }
.jcard__f {
  display: block;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--bone);
  margin-bottom: 0.4rem;
}
.jcard__k {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}
.jcard__t {
  font-family: var(--f-display);
  font-size: clamp(1.15rem, 1.6vw, 1.45rem);
  line-height: 1.2;
  transition: color 0.4s var(--ease);
}
/* Hoechstens zwei Zeilen Beschreibung - keine Textwueste in der Karte. */
.jcard__d {
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--muted-dark);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Platzhalterflaeche, solange kein Bild produziert ist */
.jcard__f--todo, .jlead__f--todo, .art__hero--todo {
  background:
    repeating-linear-gradient(135deg, rgba(13, 26, 47, 0.05) 0 1px,
                              transparent 1px 14px), var(--bone);
}

/* Kollektion-CTA am Ende der Uebersicht */
.jcta {
  background: var(--bone);
  padding-block: clamp(3.5rem, 9vh, 6.5rem);
  text-align: center;
}
/* .jcta__h ist entfallen. Die Ueberschrift trug einen eigenen Schriftgrad
   ohne die Laufweite von .display (-0.012em) und ohne text-wrap: balance -
   sie lief damit als einzige Ueberschrift der Seite anders. Jetzt display
   d-m wie ueberall sonst. */
.jcta__t {
  color: var(--muted-dark);
  max-width: 52ch;
  margin: 0.9rem auto clamp(1.6rem, 3vw, 2.4rem);
}

/* --- Artikelseite --------------------------------------------------------- */

.art__hero {
  margin: 0;
  aspect-ratio: 8 / 5;
  overflow: hidden;
  background: var(--bone);
}
.art__hero img { width: 100%; height: 100%; object-fit: cover; }

/* Das Format der Vorlage. Die querformatigen Aufnahmen des Hauses liegen auf
   16:9; in 8:5 gestellt verlieren sie an beiden Seiten je fuenf Prozent, ohne
   dass die Flaeche dadurch etwas gewinnt. */
.art__hero--breit { aspect-ratio: 16 / 9; }

/* Flaches Band. Auf 16:9 fuellt eine randlose Aufnahme ein ganzes Fenster und
   verstellt die Seite; auf 21:9 bleibt sie der Auftritt und laesst darunter
   etwas stehen. Beschnitten werden nur oben und unten je zwoelf Prozent. */
.art__hero--kino { aspect-ratio: 21 / 9; }

/* Auf dem Telefon waeren 21:9 ein Streifen von 160 px — dort laeuft die
   Aufnahme im Format der Vorlage, beschnitten wird dann gar nichts. */
@media (max-width: 640px) {
  .art__hero--kino { aspect-ratio: 16 / 9; }
}
.art__draft {
  margin-top: 1.2rem;
  font-size: 0.86rem;
  color: var(--muted-dark);
  border-left: 2px solid var(--gold);
  padding-left: 0.9rem;
}

/* Kurzantwort - hervorgehoben ueber Flaeche und Linie, nicht ueber Signalfarbe */
.answer {
  background: var(--bone);
  border-left: 2px solid var(--gold);
  padding: clamp(1.2rem, 3vw, 1.9rem) clamp(1.2rem, 3vw, 2rem);
  margin-bottom: 2.4em;
}
.answer__h {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
  margin-bottom: 0.5rem;
}
.answer__t { font-size: 1.02em; line-height: 1.7; }

/* Inhaltsverzeichnis */
.toc {
  border-top: var(--rule) solid var(--bone-line);
  border-bottom: var(--rule) solid var(--bone-line);
  padding-block: 1.1rem;
  margin-bottom: 2.4em;
}
.toc__h {
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
  cursor: pointer;
  list-style: none;
}
.toc__h::-webkit-details-marker { display: none; }
.toc__l {
  margin: 1rem 0 0;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.5rem;
  font-size: 0.94rem;
}
.toc__l a { color: var(--muted-dark); transition: color 0.35s var(--ease); }
.toc__l a:hover, .toc__l a:focus-visible { color: var(--ink); }

/* Kontextbezogener Produkt-CTA im Text */
.acta {
  border-top: var(--rule) solid var(--bone-line);
  border-bottom: var(--rule) solid var(--bone-line);
  padding-block: clamp(1.4rem, 3vw, 2rem);
  margin-block: 2.6em;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 1rem 2rem;
}
.acta__t {
  font-family: var(--f-display);
  font-size: clamp(1.15rem, 1.8vw, 1.5rem);
  line-height: 1.2;
  margin: 0;
  max-width: 30ch;
}
.acta__b { flex: none; }

/* Produktmodul im Artikel - darf breiter sein als die Textspalte */
.pmod {
  margin-block: 3em;
  width: min(100vw - 2 * var(--pad), 1100px);
  margin-inline: calc(50% - min(50vw - var(--pad), 550px));
}
.pmod__h {
  font-family: var(--f-display);
  font-size: clamp(1.3rem, 2vw, 1.8rem);
  padding-bottom: 1rem;
  margin-bottom: 1.6rem;
  border-bottom: var(--rule) solid var(--bone-line);
}
.pmod__g {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1rem, 2.5vw, 2rem);
}
.pmod__g[data-count="1"] { grid-template-columns: minmax(0, 22rem); }
.pmod__g[data-count="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.pmod__g[data-count="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.pmod__i { display: flex; flex-direction: column; gap: 0.35rem; text-align: center; }
.pmod__f { display: block; overflow: hidden; }
.pmod__n {
  font-family: var(--f-display);
  font-size: 1.05rem;
  transition: color 0.4s var(--ease);
}
.pmod__p { font-size: 0.92rem; }
.pmod__s { font-size: 0.78rem; color: var(--muted-dark); line-height: 1.5; }

/* Passende Beitraege */
.rel { padding-block: clamp(3rem, 7vh, 5rem); border-top: var(--rule) solid var(--bone-line); }
.rel__h {
  font-family: var(--f-display);
  font-size: clamp(1.3rem, 2vw, 1.8rem);
  margin-bottom: clamp(1.4rem, 3vw, 2.2rem);
}
.rel__g { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.2rem, 3vw, 2.5rem); }
.rel__i {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  padding-top: 1.1rem;
  border-top: var(--rule) solid var(--bone-line);
}
.rel__k {
  font-family: var(--f-ext);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}
.rel__t {
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 1.4vw, 1.25rem);
  line-height: 1.22;
  transition: color 0.4s var(--ease);
}
.rel__m { font-size: 0.78rem; color: var(--muted-dark); }

/* Dezente feste Leiste auf dem Telefon */
.jbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: none;
  align-items: center;
  gap: 0.8rem;
  padding: 0.7rem clamp(0.9rem, 4vw, 1.4rem);
  padding-bottom: max(0.7rem, env(safe-area-inset-bottom));
  background: var(--paper);
  border-top: var(--rule) solid var(--bone-line);
  transform: translateY(110%);
  transition: transform 0.45s var(--ease);
}
.jbar.is-on { transform: none; }
.jbar__t {
  flex: 1;
  min-width: 0;
  font-family: var(--f-ext);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted-dark);
}
.jbar__b { flex: none; padding: 0.75em 1.3em; font-size: 0.82rem; }
.jbar__x {
  flex: none;
  width: 2rem;
  height: 2rem;
  font-size: 1.15rem;
  line-height: 1;
  color: var(--muted-dark);
  background: none;
  border: 0;
  cursor: pointer;
}

@media (max-width: 900px) {
  .jlead { grid-template-columns: 1fr; }
  .jgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rel__g { grid-template-columns: 1fr; }
  .pmod__g, .pmod__g[data-count="3"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .acta { flex-direction: column; align-items: flex-start; }
  /* Die Leiste erscheint erst per Skript, deshalb nur hier freigeschaltet. */
  .jbar[data-journal-bar] { display: flex; }
}
@media (max-width: 560px) {
  .jgrid { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .jlead__f img, .jcard__f img, .pmod__f .shot, .jbar { transition: none; }
}

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

/* Der Seitengrund ist selbst --paper. Ein Panel in --paper waere also
   unsichtbar - genau das war die Kasse bis zum 18.08.2026: Felder, die im
   Nichts standen. Zwei eigene Toene, nur hier: ein ruhiger Grund fuer den
   Kasten und ein hellerer fuer das, was darin ausgefuellt wird. */
.co { max-width: 68rem; margin-inline: auto;
      /* Kein Weiss. Die Kasse bleibt im Periwinkle der Marke: der Kasten
         eine Spur tiefer als die Seite, die Flaeche darin im Seitenton.
         Ein weisses Feld waere hier ein Fremdkoerper - es gibt sonst
         nirgends auf der Seite eine weisse Flaeche. Vorgabe 18.08.2026. */
      --co-panel: #dfe3ef;
      --co-card: var(--paper); }
/* Auf der Kasse ist die Ueberschrift kein Auftritt, sondern eine
   Ortsangabe. In voller Groesse frass sie ein Fuenftel des Bildausschnitts,
   den der erste Schritt braucht. */
.co h1 { font-size: clamp(2rem, 4.2vw, 3rem); margin-bottom: clamp(0.9rem, 1.8vw, 1.3rem); }
/* Auf flachen Bildschirmen zaehlt jede Zeile: dort schrumpfen Ueberschrift
   und Polster weiter, damit der offene Schritt ganz ins Bild passt. */
/* Achtung Reihenfolge: dieser Block steht im Stylesheet vor den Grundregeln
   der Schritte. Bei gleicher Spezifitaet gewinnt die spaetere Regel - die
   Selektoren tragen deshalb `.co` davor, sonst bliebe hier alles wirkungslos.
   Genau das ist am 18.08.2026 einmal passiert. */
@media (max-height: 860px) {
  .co h1 { font-size: clamp(1.8rem, 3.6vw, 2.4rem); margin-bottom: 0.8rem; }
  .co .co__stepbody { padding: 1.1rem 1.3rem; }
  .co .co__step { padding-block: 0.9rem; }
  /* Ein zugeklappter Schritt ist eine Zeile - er braucht kein Polster einer
     Arbeitsflaeche. */
  .co .co__step--zu { padding-block: 0.75rem; }
  .co .co__pay .field { margin-top: 0.8rem; }
  /* Eng, aber nicht gequetscht: oben bleibt Luft, unten reicht wenig. */
  .section--tight:has(.co) { padding: 2.2rem 0 1.2rem; }
}

/* --- Die Kasse endet an der Falz ------------------------------------------
   Vorgabe 18.08.2026: die Linie unter der Kasse soll genau dort sitzen, wo
   der erste Bildausschnitt aufhoert - nicht zweihundert Pixel darueber, mit
   einem leeren Streifen dazwischen.

   Abgezogen werden Kopfzeile und Brotkrume, die ueber der Sektion stehen
   (gemessen 70 + 46 Pixel). Nur auf breiten Fenstern: auf dem Telefon ist
   die Kasse ohnehin laenger als ein Bildausschnitt, und eine erzwungene
   Mindesthoehe erzeugte dort nur Leere.

   `svh` statt `vh`, weil auf dem Telefon die Adressleiste mitwandert und
   `vh` dort die groessere, zeitweise falsche Hoehe meint.              */
@media (min-width: 861px) {
  .section--tight:has(.co) {
    min-height: calc(100svh - 7.25rem);
    padding-top: clamp(2.5rem, 7vh, 5rem);
    /* Unten reicht wenig: die Mindesthoehe fuellt den Rest bis zur Falz.
       Bliebe hier das grosse Polster der uebrigen Seiten stehen, waere der
       Inhalt hoeher als die Mindesthoehe - und die Linie ruschte wieder
       unter den Bildausschnitt. */
    padding-bottom: clamp(1.5rem, 4vh, 3rem);
  }
}

/* Breit und flach zugleich - der haeufigste Laptop. Hier ist die Hoehe
   knapp, also faellt das Polster oben kleiner aus als auf hohen Schirmen.
   Ohne diesen Block gewaenne die Regel darueber (spaeter im Stylesheet)
   und der Inhalt waere hoeher als die Mindesthoehe: die Linie ruschte
   unter den Bildausschnitt. */
@media (min-width: 861px) and (max-height: 860px) {
  .section--tight:has(.co) { padding-top: 2rem; padding-bottom: 1rem; }
}
/* --- Der Weg durch die Bestellung ----------------------------------------
   Eine Linie, drei Punkte, Beschriftung darunter. Vorgabe 21.08.2026 nach
   Hermes.

   Nur am Schirm: auf dem Telefon zaehlen die Schritte selbst schon mit
   "1 / 3", und die Kasse dort passt genau in einen Bildausschnitt. Ein
   Balken darueber kostete den Platz, um den heute den ganzen Tag gerungen
   wurde. Deshalb steht die Anzeige unter 861 Pixeln auf `display: none`
   und nicht nur klein. */
.co__weg { display: none; }

@media (min-width: 861px) {
  .co__weg {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    position: relative;
    margin: 0 0 clamp(2rem, 4vh, 3rem);
    padding: 0;
    list-style: none;
  }
  /* Die durchgehende Linie liegt hinter den Punkten, auf ihrer Hoehe. */
  .co__weg::before {
    content: "";
    position: absolute;
    left: 0; right: 0;
    top: 5px;
    height: 1px;
    background: var(--bone-line);
  }
  .co__wegp {
    position: relative;
    z-index: 1;
    text-align: center;
    padding-top: 1.35rem;
    font-family: var(--f-ext);
    font-size: 0.62rem;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--muted-dark);
  }
  /* Der Punkt. Sein Grund ist der Grund der Seite, damit die Linie
     darunter nicht durchscheint. */
  .co__wegp::before {
    content: "";
    position: absolute;
    top: 0;
    left: 50%;
    width: 11px;
    height: 11px;
    margin-left: -5.5px;
    border-radius: 50%;
    background: var(--paper);
    border: 1px solid var(--bone-line);
    box-sizing: border-box;
  }
  /* Erledigt und aktuell sind beide gefuellt - der Unterschied steckt in
     der Schrift darunter, nicht in einer dritten Punktform. Drei
     Zustaende, die man auseinanderhalten muss, sind einer zu viel. */
  .co__wegp--durch::before,
  .co__wegp--jetzt::before {
    background: var(--ink);
    border-color: var(--ink);
  }
  .co__wegp--jetzt { color: var(--ink); }
}

.co__empty { color: var(--muted-dark); }
.co__empty a { text-decoration: underline; text-underline-offset: 0.22em; }

/* Links das Formular, rechts die Bestellung - nebeneinander, nicht
   nacheinander. Die Uebersicht bleibt beim Scrollen stehen: wer unten die
   Karte eintippt, sieht oben weiter, worueber er gerade entscheidet.       */
.co__grid { display: grid; grid-template-columns: minmax(0, 1.25fr) minmax(19rem, 1fr);
            gap: clamp(2rem, 4vw, 3.4rem); align-items: start; }
.co__main { min-width: 0; }

/* Die Zeilen stehen jetzt in der schmalen Spalte. Ein 5,5-rem-Bild waere
   dort die Haelfte der Breite - das Stueck ist hier Beleg, nicht Auslage. */
.co__line { display: grid; grid-template-columns: 3.4rem 1fr auto; gap: 0.9rem;
            align-items: center; padding-block: 0.9rem;
            border-bottom: var(--rule) solid var(--bone-line); }
.co__line:first-child { padding-top: 0.4rem; }
.co__thumb { display: block; background: var(--paper); }
.co__thumb img { width: 100%; height: auto; mix-blend-mode: multiply; }
.co__art { font-family: var(--f-ext); font-size: 0.6rem; letter-spacing: 0.22em;
           text-transform: uppercase; color: var(--muted-dark); }
.co__name { font-family: var(--f-display); font-size: 1rem; margin-top: 0.15rem; }
.co__qty { margin-top: 0.25rem; font-size: 0.82rem; color: var(--muted-dark); }
.co__sum { font-size: 0.9rem; white-space: nowrap; }

.co__side { background: var(--co-panel); padding: clamp(1.2rem, 2.4vw, 1.7rem);
            position: sticky; top: clamp(1rem, 8vh, 5.5rem); }
.co__h { font-family: var(--f-ext); font-size: 0.66rem; letter-spacing: 0.26em;
         text-transform: uppercase; color: var(--muted-dark); }
.co__totals { display: grid; grid-template-columns: 1fr auto; gap: 0.6rem 1rem; margin-top: 1.4rem; }
.co__totals dd { text-align: right; }
.co__totals .co__t { font-family: var(--f-display); font-size: 1.15rem; padding-top: 0.7rem;
                     border-top: var(--rule) solid var(--bone-line); }
.co__tax { margin-top: 0.6rem; font-size: 0.8rem; color: var(--muted-dark); }
.co__note { margin-top: 1.4rem; font-size: 0.86rem; color: var(--muted-dark); }
.co__note:empty { display: none; }

/* Auf dem Telefon untereinander - die Schritte zuerst, die Bestellung
   darunter.

   Bis zum 21.08.2026 stand die Bestellung oben: wer die Adresse eintippt,
   sollte vorher sehen, wofuer. Das galt, solange die Felder auf der Seite
   standen. Seit die Anschrift in einem Blatt darueber ausgefuellt wird,
   schob die Uebersicht nur noch den ersten Schritt aus dem Bild - gemessen
   bei 430 px: der Knopf "Weiter" lag 780 px unter der Oberkante, also
   ausserhalb des ersten Bildausschnitts. Eine Kasse, deren erster Schritt
   nicht im Bild steht, ist keine.

   Gesehen hat den Betrag ohnehin jeder: er steht im Warenkorb, aus dem man
   hierher kommt, und unmittelbar ueber dem Kaufknopf noch einmal.       */
@media (max-width: 860px) {
  .co__grid { grid-template-columns: 1fr; gap: 2rem; }
  .co__side { position: static; }
  .co__line { grid-template-columns: 4rem 1fr auto; }
}

/* --- Die drei Schritte ---------------------------------------------------
   Ein Schritt ist ein Kasten mit Kopfzeile. Der offene zeigt seine Felder,
   die geschlossenen nur Kopfzeile und - wenn sie schon durch sind - eine
   Zeile mit dem, was drinsteht, und einem Weg zurueck.

   Geschlossen wird mit `display: none` am Rumpf, nicht mit `hidden` am
   ganzen Kasten: die Werte bleiben im Formular stehen, und der Browser
   fuellt beim Zurueckgehen nichts neu.                                   */
/* Zeilen, keine Kaesten. Bis zum 21.08.2026 stand jeder Schritt in einem
   eigenen gefuellten Kasten mit Abstand zum naechsten - drei graue Bloecke
   untereinander, und dazwischen dreimal Luft. Das las sich wie ein
   Formular, das noch in Arbeit ist.

   Aesop macht es umgekehrt: die Schritte sind Zeilen auf dem Papier der
   Seite, getrennt durch je eine Haarlinie. Gefuellt ist nur, was gerade
   ausgefuellt wird, und die Bestellung. Das ist ruhiger und - nebenbei -
   rund 90 Pixel kuerzer, was auf dem Telefon ueber einen Bildausschnitt
   entscheidet. */
.co__step { background: none; padding: clamp(1rem, 2vw, 1.25rem) 0; margin: 0;
            border-top: var(--rule) solid var(--bone-line); }
.co__step:first-child { border-top: 0; }
.co__pay { border-top: var(--rule) solid var(--bone-line);
           border-bottom: var(--rule) solid var(--bone-line); }
/* Der offene Schritt setzt seine Felder auf eine eigene Flaeche mit Rahmen -
   sichtbar abgegrenzt von dem, was noch nicht dran ist. */
/* Der offene Schritt setzt seine Felder auf eine eigene Flaeche mit Rahmen.
   Der Rahmen ist deutlicher als die Trennlinien - er soll zeigen, wo gerade
   gearbeitet wird, nicht nur, dass hier etwas endet. */
.co__stepbody { background: var(--co-card); border: 1px solid rgba(13, 26, 47, 0.26);
                padding: clamp(1rem, 2.2vw, 1.4rem); margin-top: 0.9rem; }
.co__steph { display: flex; align-items: baseline; justify-content: space-between;
             gap: 1rem; margin: 0; }
.co__stept { font: inherit; letter-spacing: inherit; color: inherit; background: none;
             border: 0; padding: 0; text-align: left; cursor: default; }
.co__step--zu .co__stept { cursor: pointer; color: var(--muted-dark); }
.co__stepn { font-family: var(--f-ext); font-size: 0.6rem; letter-spacing: 0.2em;
             color: var(--muted-dark); white-space: nowrap; }
.co__step--zu .co__stepbody { display: none; }
.co__done { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.8rem;
            margin-top: 0.5rem; font-size: 0.86rem; color: var(--muted-dark); }
/* Eine Klassenregel mit `display` schlaegt das hidden-Attribut - der Browser
   haelt das Element fuer versteckt und zeichnet es trotzdem. Am 18.08.2026
   standen deshalb drei "Edit" auf der Kasse, an Schritten, die noch niemand
   ausgefuellt hatte. Dieselbe Falle wie bei .cc und .lang__list. */
.co__done[hidden] { display: none; }
.co__lines { background: var(--co-card); border: var(--rule) solid var(--bone-line);
             padding: clamp(0.9rem, 2vw, 1.2rem); margin-top: 0.9rem; }
.co__edit { font: inherit; color: var(--gold); background: none; border: 0; padding: 0;
            cursor: pointer; text-decoration: underline; text-underline-offset: 0.22em; }
.co__next { margin-top: 1.4rem; }

/* --- Am Schirm sind die Schritte Karten ----------------------------------
   Vorgabe 21.08.2026 nach Hermes: dort ist jeder Abschnitt eine eigene
   Flaeche mit Kopfzeile - Titel links, "Aendern" rechts, darunter eine
   Haarlinie und der Inhalt.

   Am Telefon bleibt es bei Zeilen auf dem Papier der Seite. Dort steht
   alles untereinander, und Kaesten waeren dieselben Linien, die heute
   frueh auf ausdrueckliche Vorgabe weggefallen sind. Der Unterschied ist
   nicht Geschmack: am Schirm steht der Schritt NEBEN der Bestellung, und
   die Karte sagt, wo das eine aufhoert und das andere anfaengt. */
@media (min-width: 861px) {
  .co__pay { border: 0; }
  .co__step {
    background: var(--co-card);
    border: var(--rule) solid var(--bone-line);
    border-top: var(--rule) solid var(--bone-line);
    padding: 0;
    margin-bottom: 0.7rem;
  }
  /* Die oberste Karte braucht ihre Deckellinie zurueck.

     `.co__step:first-child { border-top: 0 }` stammt aus der Fassung mit
     Zeilen statt Kaesten: dort waere die erste Linie eine Linie zu viel
     gewesen, direkt unter der Ueberschrift. Als Karte fehlte damit der
     Deckel - gemeldet am 21.08.2026 mit Bildschirmfoto: "die Linie bei
     Delivery ist weg". */
  .co .co__step:first-child { border-top: var(--rule) solid var(--bone-line); }
  .co__steph {
    padding: 0.95rem clamp(1rem, 2.2vw, 1.4rem);
    margin: 0;
  }
  /* Die Linie trennt Kopf und Inhalt - aber nur, wenn es einen Inhalt
     gibt. Unter einem zugeklappten Schritt haenge sie sonst frei. */
  .co__step:not(.co__step--zu) .co__steph,
  .co__step:has([data-step-done]:not([hidden])) .co__steph {
    border-bottom: var(--rule) solid var(--bone-line);
  }
  /* Der Rumpf sitzt jetzt IN der Karte - er braucht keinen zweiten
     Rahmen und keinen eigenen Grund mehr. */
  .co__stepbody {
    border: 0;
    background: none;
    margin-top: 0;
    padding: clamp(1rem, 2.2vw, 1.4rem);
  }
  .co__done { margin: 0; padding: clamp(0.9rem, 2vw, 1.2rem) clamp(1rem, 2.2vw, 1.4rem); }
  /* Die Zusammenfassung steht in der Karte - ohne eigenen Kasten darin.
     Ein Kasten im Kasten sind zwei Rahmen um dieselbe Angabe.

     `.co` davor ist Pflicht: die Grundregel fuer .co__karte--ruhig steht
     weiter unten im Stylesheet und gewaenne bei gleicher Spezifitaet. Das
     ist heute die dritte Stelle mit demselben Muster - erst bei den
     Feldbeschriftungen, dann beim Grund der Kerbe, jetzt hier. */
  .co .co__karte--ruhig { background: none; border: 0; padding: 0; }
}

/* --- Schrift in der Kasse -------------------------------------------------
   Ueberall sonst tragen Beschriftungen die gesperrte Grotesk in Versalien -
   das ist die Handschrift der Marke, und auf einer Produktseite traegt sie.
   In einem Formular traegt sie nicht: dort sind es zwoelf kurze Woerter
   hintereinander, und gesperrte Versalien lesen sich Buchstabe fuer
   Buchstabe. Vorgabe vom 18.08.2026.

   In der Kasse steht deshalb die ruhige Grotesk, gemischt geschrieben, ohne
   Sperrung. Was Marke ist, bleibt Marke: die Ueberschrift "Checkout", der
   Name des Stuecks und die Endsumme stehen weiter in der Antiqua.        */
.co .co__h,
.co .field label,
.co .co__art {
  font-family: var(--f-sans);
  letter-spacing: 0.01em;
  text-transform: none;
}
/* Ohne Sperrung und Versalien fehlt den Ueberschriften der Abstand zu den
   Feldbeschriftungen - beide waeren gleich laut. Den Unterschied tragen
   jetzt Groesse und Farbe: Ueberschrift in Tinte, Beschriftung gedaempft. */
.co .co__h { font-size: 0.95rem; color: var(--ink); }
.co .co__step--zu .co__stept { color: var(--muted-dark); }
.co .field label { font-size: 0.78rem; }
.co .co__art { font-size: 0.74rem; }
.co .co__stepn { font-family: var(--f-sans); font-size: 0.74rem; letter-spacing: 0.01em; }

/* Auch die Antiqua faellt hier weg - Vorgabe 21.08.2026. Sie stand noch an
   vier Stellen: die Ueberschrift der Seite, der Name des Stuecks in der
   Bestellung, die Endsumme und - auf dem Telefon - der Betrag im Kopf der
   zugeklappten Bestellung.

   Millionaire Roman ist eine Schrift mit Haltung: schmale Senkrechte, hohe
   Fahnen, ein "k", das aus der Feder kommt. Auf einem Umschlag traegt das.
   Ueber einem Formular liest es sich wie eine Handschrift ueber einem
   Antragsformular - und genau das war die Rueckmeldung. Auf der Kasse
   steht deshalb durchgehend die ruhige Grotesk. Was Marke ist, steht
   ueberall sonst; hier zaehlt, dass man es ohne Nachdenken liest. */
.co h1,
.co .co__name,
.co .co__totals .co__t,
.co .co__sidesumme {
  font-family: var(--f-sans);
  font-weight: 400;
  font-style: normal;
  letter-spacing: -0.01em;
}
/* Ohne die Schmalheit der Antiqua braucht die Ueberschrift weniger Groesse,
   um dieselbe Zeile zu fuellen - sonst sprengt "Zahlungsart" den Rand. */
.co h1 { line-height: 1.05; }

/* Die Versandwahl steht seit dem 18.08.2026 im Formular, zwischen Anschrift
   und Zahlung - nicht mehr neben der Bestellung. Sie ist ein Schritt, keine
   Angabe. */
.co__ship { border: 0; padding: 0; margin: 0; }
.co__ship legend { padding: 0; }
.co__pay .co__opt { padding: 0.7rem 0; border-bottom: var(--rule) solid var(--bone-line); }
.co__pay .co__opt:last-child { border-bottom: 0; }
.co__opt { display: grid; grid-template-columns: auto 1fr auto; gap: 0.7rem;
           align-items: center; margin-top: 0.8rem; }
.co__opt input { width: auto; margin: 0; }
.co__opt label { display: block; cursor: pointer; }
.co__optn { display: block; font-size: 0.94rem; }
.co__optd { display: block; font-size: 0.8rem; color: var(--muted-dark); }
.co__optp { font-size: 0.9rem; white-space: nowrap; }

/* Kein max-width mehr: das Formular fuellt seine Spalte. Und keine
   Abstaende, die eine Kasse zu einer Landingpage machen - Beschriftung,
   Feld, naechste Beschriftung. */
.co__pay { margin-top: 0; }
.co__pay .co__h { margin-top: 1.5rem; }
.co__pay .co__h:first-child { margin-top: 0; }
/* Nicht gequetscht. Lieber laenger als eng - Vorgabe 18.08.2026. Die
   Mindesthoehe weiter unten sorgt dafuer, dass die Linie trotzdem an der
   Falz sitzt, solange der Inhalt darunter bleibt. */
.co__pay .field { margin-top: 0.95rem; }
.co__pay label { display: block; font-size: 0.64rem; color: var(--muted-dark);
                 margin-bottom: 0.28rem; }
/* --- 16 Pixel, sonst zoomt das Telefon -------------------------------------
   Safari auf dem iPhone vergroessert die ganze Seite, sobald ein Feld
   angetippt wird, dessen Schrift kleiner als 16 Pixel ist. Genau das war
   hier: 0.95rem sind 15,2 Pixel. Es sprang also bei jedem Feld herein, und
   herausgezoomt hat es nie wieder von selbst - der Rest der Kasse stand
   danach halb ausserhalb des Bildes.

   Deshalb steht hier 16px und nicht 1rem: die Schranke von Safari ist in
   Pixeln gemessen, nicht in rem. Wer im Browser eine kleinere Grundschrift
   eingestellt hat, saehe mit rem wieder 15 Pixel - und wieder den Sprung.
   Vorgabe 21.08.2026.

   Dieselbe Zahl steht in js/main.js in AUSSEHEN; Stripe zeichnet seine
   Felder in einem eigenen Rahmen, an den dieses Stylesheet nicht kommt. */
.co__pay input[type="text"], .co__pay input[type="email"],
.co__pay input[type="tel"], .co__pay input:not([type]) {
  width: 100%; font-family: var(--f-sans); font-size: 16px; color: var(--ink);
  background: transparent; border: var(--rule) solid rgba(13, 26, 47, 0.3);
  border-radius: 0.3rem; padding: 0.62rem 0.8rem; line-height: 1.2;
  /* Ohne das setzt iOS eigene Rundungen und einen Innenschatten auf jedes
     Feld - dann sieht die E-Mail-Zeile anders aus als alles darunter. */
  -webkit-appearance: none; appearance: none;
}
/* Der Pfeil muss sein. `.field select` setzt projektweit `appearance: none`
   und nimmt damit den nativen Pfeil weg - ohne Ersatz sieht ein Auswahlfeld
   aus wie ein totes Textfeld, und niemand kommt auf die Idee zu klicken.
   Genau das ist am 19.08.2026 passiert. */
.co__pay select {
  width: 100%; font-family: var(--f-sans); font-size: 16px; color: var(--ink);
  background: transparent; border: var(--rule) solid rgba(13, 26, 47, 0.3);
  border-radius: 0.3rem; padding: 0.6rem 2.2rem 0.6rem 0.8rem;
  /* Leerzeichen im Datenpfad als %20 - unkodiert verwirft Safari das Bild
     stillschweigend, und der Pfeil bliebe wieder weg. */
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2012%208'%3E%3Cpath%20d='M1%201.5%206%206.5l5-5'%20fill='none'%20stroke='%230d1a2f'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.8rem center;
  background-size: 0.7rem;
}
.co__pay input:focus, .co__pay select:focus { outline: none; border-color: var(--gold); }
/* Zwei Spalten. Die erste Zeile teilt sich haelftig (E-Mail, Name), die
   Anschrift gibt dem Ort mehr Platz als der Postleitzahl. */
.co__element { margin-top: 0.9rem; }
.co__pay .field--check { display: flex; gap: 0.6rem; align-items: flex-start; margin-top: 0.7rem; }
.co__pay .field--check input { width: auto; margin-top: 0.2rem; flex: none; }
.co__pay .field--check label { margin: 0; font-size: 0.82rem; letter-spacing: 0;
                               text-transform: none; color: var(--ink); }
.co__duty { margin-top: 1.2rem; padding: 0.75rem 0.95rem; background: var(--paper);
            font-size: 0.82rem; }
.co__submit { width: 100%; margin-top: 0.8rem; justify-content: center; }
.co__err { margin-top: 0.8rem; font-size: 0.86rem; color: #a3283a; }
.co__err:empty { display: none; }

.legal__adr { margin: 1.4rem 0; padding-left: 1.2rem; border-left: 2px solid var(--bone-line); }
.legal__form { margin-top: 1.4rem; padding: 1.4rem; background: var(--paper); }
.legal__form p { margin-top: 0.9rem; }
.legal__form p:first-child { margin-top: 0; }
.legal__hint { font-size: 0.86rem; color: var(--muted-dark); font-style: italic; }

/* Versandtabelle. Vier Spalten sind auf einem Telefon zu viel; statt sie zu
   quetschen, darf die Tabelle in ihrem eigenen Kasten scrollen — die Seite
   selbst bleibt dabei stehen. */
.legal__tabwrap { margin: 1.6rem 0; overflow-x: auto; }
.legal__tab { width: 100%; min-width: 30rem; border-collapse: collapse; font-size: 0.92rem; }
.legal__tab th, .legal__tab td {
  text-align: left;
  padding: 0.7rem 1rem 0.7rem 0;
  border-bottom: var(--rule) solid var(--bone-line);
  vertical-align: top;
}
.legal__tab th {
  font-family: var(--f-ext);
  font-size: 0.63rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--muted-dark);
  font-weight: 400;
}
.legal__tab tbody tr:last-child td { border-bottom: 0; }

/* Express-Kauf (Apple Pay / Google Pay) ueber dem Kaufknopf. */
/* Express-Kauf und Warenkorb nebeneinander, Vorgabe 19.08.2026.
   Der Express-Kasten ist versteckt, solange Stripe nicht gemeldet hat, dass
   das Geraet Apple oder Google Pay kann - dann traegt der Warenkorbknopf die
   Reihe allein. Das regelt :has(), damit es keine zweite Wahrheit in JS gibt.

   [hidden] steht ausdruecklich dabei: eine Klassenregel mit `display` schlaegt
   sonst das Attribut, und der Kasten waere sichtbar, obwohl er versteckt ist.
   Dieselbe Falle wie bei .co__done. */
/* Zwei Haelften, fest. Vorgabe 19.08.2026: links Apple Pay, rechts der
   Warenkorb, sonst nichts. Kein Umschalten je nachdem, was das Geraet kann -
   wo kein Apple Pay ist, bleibt die linke Haelfte leer, und leer ist hier
   nichts als Weissraum. */
.pdp__zwei { display: grid; grid-template-columns: 1fr 1fr; gap: 0.7rem; margin-top: 1.8rem;
             max-width: 30rem; }
.pdp__express { width: 100%; }
.pdp__zwei .pdp__cta { min-height: 50px; }
/* .pdp__aktion ist ein Flexkasten, und .pdp__zwei war darin ein Kind ohne
   Wachstumsregel: es schrumpfte auf Inhaltsbreite. Auf dem Telefon standen
   die Kaufknoepfe dadurch 142 px breit in einer 382 px breiten Spalte -
   schmaler als der Text darueber. Gemessen am 20.08.2026. */
.pdp__aktion .pdp__zwei,
.pdp__aktion .pdp__exhint { flex: 1 1 100%; width: 100%; }
.pdp__exhint { margin-top: 0.7rem; font-size: 0.78rem; color: var(--muted-dark);
               max-width: 32rem;
               /* Gleich lange Zeilen statt einer langen und einem Rest.
                  Vorgabe 20.08.2026. */
               text-wrap: balance; }
.pdp__exhint[hidden] { display: none; }
.pdp__exhint a { text-decoration: underline; text-underline-offset: 0.2em; }
@media (max-width: 560px) { .pdp__zwei { grid-template-columns: 1fr; } }

/* Private Access, vollflaechig: ein Bild ueber die ganze Breite, Text mittig
   darauf. Die geteilte Flaeche davor gab dem Motiv nur eine halbe Seite und
   stellte den Text auf hellen Grund daneben - dadurch las sich der Abschnitt
   wie ein Kasten, nicht wie eine Einladung. */
.invite--full {
  position: relative;
  display: block;
  min-height: min(88svh, 54rem);
  overflow: hidden;
  isolation: isolate;
}
.invite--full .invite__img {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  display: block;
}
/* Gleichmaessiger Schleier statt Verlauf: der Text steht hier mittig, also
   gibt es keine ruhige Ecke, in die er ausweichen koennte. */
.invite--full .invite__veil {
  position: absolute;
  inset: 0;
  z-index: 1;
  background: rgba(5, 9, 15, 0.52);
}
.invite--full .invite__body {
  position: relative;
  z-index: 2;
  min-height: inherit;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0;
  background: none;
  padding: clamp(3rem, 8vw, 7rem) clamp(1.5rem, 5vw, 5rem);
}
.invite--full .invite__head { color: #fff; margin-top: 1rem; }
.invite--full .invite__lede {
  margin-top: 1.4rem;
  max-width: 46ch;
  color: rgba(255, 255, 255, 0.86);
}
.invite--full .btn { margin-top: 2.4rem; }

/* Private Access — echtes Motiv statt Platzhalter.
   Der Rahmen ist ein <span>; ohne display:block greift height:100% nicht und
   das Bild stand als schmaler Streifen in der Flaeche. */
.invite__art { display: block; position: relative; overflow: hidden; }
/* Spezifitaet muss ueber `.invite__art img` (0,1,1) liegen - die Regel gilt
   dem ornamentalen Platzhalter und wuerde das Motiv auf 58 % schrumpfen. */
.invite__art img.invite__img { position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; display: block; }

/* --------------------------------------------------------------------------
   Einwilligungsbanner
   -------------------------------------------------------------------------- */

.cc { position: fixed; inset: auto 0 0 0; z-index: 60; padding: clamp(1rem, 3vw, 1.6rem); }
.cc[hidden] { display: none; }
.cc__box {
  max-width: 46rem; margin-inline: auto;
  background: var(--paper); color: var(--ink);
  border: var(--rule) solid var(--bone-line);
  box-shadow: 0 12px 40px rgba(13, 26, 47, 0.16);
  padding: clamp(1.2rem, 3vw, 1.8rem);
}
.cc__h { font-family: var(--f-ext); font-size: 0.66rem; letter-spacing: 0.26em;
         text-transform: uppercase; color: var(--muted-dark); }
.cc__t { margin-top: 0.8rem; font-size: 0.9rem; max-width: 60ch; }
.cc__t a { text-decoration: underline; text-underline-offset: 0.22em; }
.cc__b { display: flex; flex-wrap: wrap; gap: 0.8rem; margin-top: 1.2rem; }
/* Beide Knoepfe gleich gross - Ablehnen darf nicht schwerer sein als Zustimmen. */
.cc__b .btn { flex: 1 1 12rem; justify-content: center; }


/* Sichtbare Luecke im Impressum: was fehlt, soll auffallen, nicht untergehen. */
.legal__luecke { padding: 0.9rem 1.1rem; background: rgba(185, 154, 88, 0.1);
                 border-left: 2px solid var(--gold); }

.story__claim { margin-top: 2.4rem; font-family: var(--f-display);
                font-size: clamp(1.1rem, 2vw, 1.4rem); line-height: 1.5; }

/* --------------------------------------------------------------------------
   Fußzeile — rechtliche Verweise hinter einem Pfeil
   Sieben Verweise nebeneinander brachen in zwei Zeilen um. Sichtbar bleibt
   der Datenschutz, der Rest klappt auf. Ohne JavaScript, <details> kann das.
   -------------------------------------------------------------------------- */

/* Der Pfeil steht jetzt neben seinem eigenen Wort statt allein in der Reihe.
   Damit entfaellt die negative Aussenkante, mit der er vorher an den
   Nachbarverweis herangezogen wurde. */
.footer__more { position: relative; }
.footer__more summary {
  list-style: none; cursor: pointer; display: flex;
  align-items: center; justify-content: center; gap: 0.45rem; padding: 0.35rem 0;
  font-size: 0.9rem;
  transition: color 0.4s var(--ease);
}
.footer__more summary::-webkit-details-marker { display: none; }
.footer__more summary:focus-visible { outline: 1px solid var(--gold); outline-offset: 3px; }

/* Ein um 45 Grad gedrehtes Quadrat hat seinen optischen Mittelpunkt nicht
   dort, wo die Box ihn hat - der alte Versatz von -1px/-1px zog ihn zusaetzlich
   aus der Zeile. Jetzt sitzt er in einer eigenen quadratischen Box, die
   flex mittig ausrichtet, und wird nur noch gedreht. Vorgabe 20.08.2026:
   mittig, auf dem Schirm wie auf dem Telefon. */
.footer__chev {
  width: 0.5rem; height: 0.5rem; display: block; flex: none;
  border-right: 1px solid currentColor; border-bottom: 1px solid currentColor;
  transform: rotate(45deg);
  position: relative; top: -0.12em;
  transition: transform 0.3s var(--ease), color 0.4s var(--ease);
}
.footer__more[open] .footer__chev { transform: rotate(-135deg); top: 0.06em; }

.footer__morelist {
  position: absolute; right: 0; bottom: calc(100% + 0.5rem); z-index: 20;
  display: grid; min-width: 14rem;
  padding: 0.6rem 0;
  background: var(--paper);
  border: var(--rule) solid var(--bone-line);
  box-shadow: 0 8px 28px rgba(13, 26, 47, 0.12);
}
/* Jede Zeile ist eine Flaeche, nicht nur Text - sonst sitzt der <button>
   anders als die Verweise daneben und der Kasten wirkt schief. */
.footer__morelist a, .footer__morelist .footer__link {
  display: flex; align-items: center; gap: 0.55em;
  width: 100%;
  padding: 0.6rem 1.2rem;
  font-size: 0.86rem; line-height: 1.3;
  text-align: left; white-space: nowrap;
  transition: background 0.25s var(--ease), color 0.25s var(--ease);
}
/* Der feine Pfeil hinter jeder Zeile. Als Maske und nicht als Hintergrundbild:
   so nimmt er die Textfarbe mit und wird beim Hover golden, ohne dass eine
   zweite Grafik noetig waere. */
.footer__morelist a::after,
.footer__morelist .footer__link::after {
  content: "";
  flex: none;
  width: 0.66em; height: 0.66em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.2 8.8 8.8 3.2'/%3E%3Cpath d='M4.6 3.2H8.8V7.4'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' fill='none' stroke='%23000' stroke-width='1' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3.2 8.8 8.8 3.2'/%3E%3Cpath d='M4.6 3.2H8.8V7.4'/%3E%3C/svg%3E") center / contain no-repeat;
}
.footer__morelist a:hover, .footer__morelist .footer__link:hover {
  background: rgba(13, 26, 47, 0.05); color: var(--ink);
}
/* Cookie-Einstellungen sind kein Rechtstext - eine feine Linie trennt sie. */
.footer__morelist .footer__link { border-top: var(--rule) solid var(--bone-line); margin-top: 0.4rem; padding-top: 0.7rem; }

/* Hier stand bis zum 18.08.2026 eine Regel, die das Ausklappfeld unter
   900 px auf seinem Ausloeser zentrierte. Gemeint war: im schmalen Fenster
   sitzt der Fuss mittig, also gehoert das Feld unter die Mitte.

   Der Ausloeser sitzt aber bei keiner einzigen Breite mittig - nachgemessen
   von 320 bis 1024 px. Ein 224 px breites Feld auf einem 87 px breiten
   Ausloeser zu zentrieren, der rechts steht, schob es bei 700, 768, 834 und
   900 px bis zu 68 px aus dem Fenster. Sichtbar war davon nichts: die Seite
   scrollt nicht waagerecht, das Feld war schlicht abgeschnitten.

   Ohne die Regel gilt `right: 0` aus dem Grundsatz darueber - die rechte
   Kante des Feldes liegt auf der rechten Kante des Ausloesers. Das ist die
   uebliche Anlage eines Ausklappmenues und bleibt bei jeder Breite drin,
   solange der Ausloeser drin ist. */

/* --------------------------------------------------------------------------
   404
   -------------------------------------------------------------------------- */

.nf { min-height: 62svh; display: grid; place-items: center; }
.nf__inner { text-align: center; max-width: 42rem; }
/* Die Versalien des Kickers und die Oberlaengen der Anzeigeschrift stossen
   sonst zusammen - im Grossgrad faellt schon ein halber Zeilenabstand auf. */
.nf__title { margin-top: 1.4rem; }
.nf__lede { margin: 1.4rem auto 0; max-width: 38ch; }
.nf__links {
  margin-top: 2.4rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem 2rem;
  align-items: center;
  justify-content: center;
}


/* --------------------------------------------------------------------------
   Private Access — Seitenkopf
   -------------------------------------------------------------------------- */

.pahero {
  position: relative;
  /* Keine feste Mindesthoehe. Vorher waren es 72 svh, der Text brauchte davon
     die Haelfte - darunter blieb eine leere dunkle Flaeche stehen und dann
     brach es hart ins Helle. Der Block ist jetzt so hoch wie sein Inhalt. */
  overflow: hidden;
  isolation: isolate;
  text-align: center;
  background:
    radial-gradient(120% 90% at 74% 16%, rgba(185, 154, 88, 0.20) 0%, transparent 60%),
    radial-gradient(90% 70% at 14% 96%, rgba(185, 154, 88, 0.10) 0%, transparent 62%),
    linear-gradient(180deg, #141d2c 0%, #0b1322 62%, #070d16 100%);
}
.pahero__c {
  position: relative;
  z-index: 2;
  /* Oben die Kopfzeile freihalten, unten so viel Luft, dass der Uebergang ins
     Formular als Wechsel liest und nicht als Abbruch. */
  padding-top: calc(var(--head-h) + clamp(3.5rem, 9vh, 6rem));
  padding-bottom: clamp(3.5rem, 9vh, 6rem);
}
.pahero__title { color: #fff; margin-top: 1rem; }
/* Die Kursive traegt hier weniger Gewicht als auf hellem Grund - Weiss auf
   Dunkel wirkt duenner. Eine Spur Gold holt sie zurueck. */
.pahero__title .script { color: var(--gold); }
.pahero__lede {
  margin: 1.6rem auto 0;
  max-width: 46ch;
  color: rgba(255, 255, 255, 0.86);
}

/* --------------------------------------------------------------------------
   Kopfzeichen: Schriftzug, dann Zeichen
   -------------------------------------------------------------------------- */

/* Beide Fassungen liegen uebereinander im selben Raster. So springt beim
   Wechsel nichts, und der Kopf behaelt seine Hoehe. */
.mark { display: grid; place-items: center; }
.mark img.mark__wort { display: none; }
.mark__word, .mark .mark__icon {
  grid-area: 1 / 1;
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.mark__word { display: block; text-align: center; white-space: nowrap; }
.mark__name {
  display: block;
  font-family: var(--f-ext);
  font-size: 0.86rem;
  letter-spacing: 0.42em;
  text-indent: 0.42em;
  text-transform: uppercase;
  line-height: 1;
}
.mark__place {
  display: block;
  margin-top: 0.32rem;
  font-family: var(--f-ext);
  font-size: 0.5rem;
  letter-spacing: 0.3em;
  text-indent: 0.3em;
  text-transform: uppercase;
  line-height: 1;
  opacity: 0.62;
}

/* Ausgangszustand: Schriftzug sichtbar, Zeichen wartet. */
.mark .mark__icon { opacity: 0; transform: scale(0.9); }
.header.is-compact .mark__word { opacity: 0; transform: scale(0.96); }
.header.is-compact .mark__icon { opacity: 1; transform: scale(1); }

/* Wer Bewegung reduziert haben will, sieht sofort das Zeichen - der Wechsel
   ist Zierde, kein Inhalt. */
@media (prefers-reduced-motion: reduce) {
  .mark__word { display: none; }
  .mark .mark__icon { opacity: 1; transform: none; }
  .mark__word, .mark .mark__icon { transition: none; }
}

/* --------------------------------------------------------------------------
   Fragen auf der Produktseite
   -------------------------------------------------------------------------- */

.pfaq__grid {
  margin-top: clamp(1.6rem, 3vw, 2.6rem);
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.8rem, 4vw, 3.2rem);
}
.pfaq__i { border-top: var(--rule) solid var(--bone-line); padding-top: 1.2rem; }
.pfaq__q {
  font-family: var(--f-display);
  font-size: clamp(1.05rem, 1.5vw, 1.3rem);
  line-height: 1.3;
  color: var(--ink);
}
.pfaq__a { margin-top: 0.7rem; font-size: 0.94rem; color: var(--muted-dark); max-width: 46ch; }
@media (max-width: 720px) { .pfaq__grid { grid-template-columns: 1fr; } }


/* --------------------------------------------------------------------------
   Produktseite — Geschichte und Profilreihe
   Beide Flaechen folgen dem Aufbau der Vorlage: eine haelftig geteilte Seite
   mit randloser Aufnahme links, und darunter vier Ausschnitte nebeneinander.
   -------------------------------------------------------------------------- */

.gesch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  background: var(--bone);
}

/* Buendig an der Kante, ueber die volle Bildschirmhoehe - aber gedeckelt.
   Ohne Deckel wuchs die Flaeche auf hohen Fenstern mit: auf 1080 px standen
   neben rund 350 px Text 1080 px Bild und darum herum Leere. Grosszuegig ist
   nicht dasselbe wie leer. */


.gesch__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  padding: clamp(3.5rem, 8vw, 7rem) clamp(1.5rem, 6vw, 6rem);
}

.gesch__h {
  font-size: clamp(2.2rem, 4.6vw, 4rem);
  margin: clamp(0.6rem, 1.5vw, 1.2rem) 0 clamp(1.8rem, 4vw, 2.8rem);
}
.gesch__h .script { font-size: 1.08em; line-height: 0.8; }

.gesch__body p:not(.eyebrow) {
  max-width: 40ch;
  margin-inline: auto;
  color: var(--muted-dark);
  line-height: 1.8;
}
.gesch__body p + p:not(.eyebrow) { margin-top: 1.4rem; }


/* "Drei Ansichten" ist die Ueberschrift eines Kapitels, keine Aussage - sie
   steht deshalb in der Display und nicht mehr in der Script. Etwas kleiner
   als die drei Aussagen der Seite, damit der Unterschied sichtbar ist. */


/* Aufnahme und Auftragsflaeche im selben Verhaeltnis. Die Reihe wirkt nur,
   wenn die drei Felder gleich hoch sind - auch solange erst eines davon eine
   echte Aufnahme traegt. */


/* Beschriftung, nicht Aussage: kleine Versalzeile wie DETAILS und MATERIAL. */


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

/* --------------------------------------------------------------------------
   Study I — die begriffliche Klammer über den vier Objekten
   -------------------------------------------------------------------------- */

.studkopf {
  background: var(--bone);
  padding: clamp(4rem, 10vw, 9rem) 0 clamp(3.5rem, 8vw, 7rem);
  text-align: center;
}
/* Etwas kleiner als d-xl: bei voller Groesse stiess die Zeile auf einem
   1280er Fenster an beide Raender. */
.studkopf__h {
  margin: clamp(0.8rem, 2vw, 1.4rem) auto 0;
  max-width: 20ch;
  font-size: clamp(2.2rem, 4.8vw, 4.2rem);
}
.studkopf__h .script { font-size: 1.08em; line-height: 0.8; }
.studkopf .lede { max-width: 46ch; margin: clamp(1.8rem, 4vw, 2.6rem) auto 0; }
.studkopf__reihe {
  margin-top: clamp(1.6rem, 3vw, 2.2rem);
  font-family: var(--f-ext);
  font-size: clamp(0.62rem, 0.58rem + 0.16vw, 0.76rem);
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--muted-dark);
}

.stud { background: var(--paper); padding: clamp(4rem, 9vw, 8rem) 0; }
.stud__h { text-align: center; margin-bottom: clamp(2.5rem, 6vw, 4rem); }
.stud__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.4rem, 3vw, 2.6rem);
}
.stud__k { display: block; text-align: center; }
/* Die Nummer trägt die Ausstellungslogik: 01 bis 04, nicht Preis zuerst. */
.stud__nr {
  display: block;
  font-family: var(--f-ext);
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  color: var(--muted-dark);
}
.stud__frame {
  display: block;
  margin: clamp(0.8rem, 2vw, 1.4rem) 0 clamp(1rem, 2.5vw, 1.6rem);
  background: var(--bone);
  aspect-ratio: 1;
  overflow: hidden;
}
.stud__frame .shot {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
.stud__name { display: block; font-family: var(--f-display); font-size: clamp(1.2rem, 1.7vw, 1.6rem); }
.stud__thema {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--f-script);
  font-size: clamp(1.15rem, 1.6vw, 1.5rem);
  color: var(--gold);
}
.stud__text {
  display: block;
  margin-top: 0.9rem;
  font-size: 0.86rem;
  line-height: 1.7;
  color: var(--muted-dark);
  text-wrap: pretty;
}
.stud__mehr { text-align: center; margin-top: clamp(2.5rem, 5vw, 3.5rem); }

@media (max-width: 900px) {
  .stud__grid { grid-template-columns: repeat(2, 1fr); row-gap: clamp(2.4rem, 6vw, 3.2rem); }
}
@media (max-width: 560px) {
  .stud__grid { grid-template-columns: 1fr; }
}

/* Hinweis unter den Anfrage-Knoepfen im Vorverkauf. */
.pdp__hinweis {
  margin-top: 1.1rem;
  max-width: 34ch;
  font-size: 0.86rem;
  line-height: 1.6;
  color: var(--muted-dark);
}

/* --------------------------------------------------------------------------
   Private Access — Aufnahme links, Text und Formular rechts
   Dieselbe Teilung wie bei der Geschichte auf der Objektseite, nur traegt die
   rechte Haelfte hier ein Formular und damit mehr Hoehe. Deshalb keine feste
   Mindesthoehe: die Aufnahme folgt der Spalte daneben.
   -------------------------------------------------------------------------- */

.pa {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  background: var(--paper);
  /* Die Flaeche beginnt unter der Kopfleiste, nicht dahinter. Durchlaufen
     lassen war der Fehler: die Aufnahme ist links fast schwarz, die Flaeche
     rechts hell - der mittige Schriftzug lag damit zur Haelfte auf Schwarz
     und war dort unsichtbar. Die Leiste steht jetzt als eigenes Band mit
     ihrer Trennlinie darueber. */
  padding-top: var(--head-h);
}
.pa__body { border-left: var(--rule) solid var(--bone-line); }

@media (max-width: 900px) {
  .pa__body { border-left: 0; border-top: var(--rule) solid var(--bone-line); }
}

/* Die Aufnahme fuellt die linke Seite immer ganz: mindestens bis zum unteren
   Bildschirmrand, und darueber hinaus so hoch wie die Spalte daneben. Vorher
   stand hier eine feste Mindesthoehe - war das Formular kuerzer als sie, blieb
   unten Papier stehen; war es laenger, zog die Aufnahme mit. Das sah je nach
   Fensterhoehe unterschiedlich aus. */
/* Die Aufnahme bleibt stehen, der Text daneben laeuft. Vorher war sie ein
   gedehntes Rasterkind: auf der Kontaktseite ist die rechte Spalte
   mehrere Bildschirme lang, und das Bild wurde entsprechend lang mitgezogen.
   align-self: start ist noetig - ohne das fuellt das Rasterkind die Zeile und
   sticky hat keinen Weg. */
.pa__media {
  position: sticky;
  top: var(--head-h);
  align-self: start;
  height: calc(100svh - var(--head-h));
}
.pa__media picture { display: block; height: 100%; }
.pa__media img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.pa__body {
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: clamp(3rem, 7vw, 6rem) clamp(1.5rem, 5vw, 5rem);
}

.pa__title {
  font-size: clamp(2.2rem, 4.4vw, 3.8rem);
  margin: clamp(0.6rem, 1.5vw, 1.1rem) 0 clamp(1.2rem, 2.5vw, 1.8rem);
}
.pa__title .script { font-size: 1.08em; line-height: 0.8; }

.pa__lede {
  max-width: 42ch;
  color: var(--muted-dark);
  line-height: 1.75;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

/* Das Formular erbt die Breite der Spalte statt der Seitenmitte. */
.pa__body .form { max-width: 34rem; }
.pa__body .access__back { margin-top: clamp(1.6rem, 3vw, 2.4rem); }

@media (max-width: 900px) {
  .pa { grid-template-columns: 1fr; }
  /* Einspaltig steht sie oben und laeuft mit - stehenbleiben ergaebe eine
     halbe Bildschirmhoehe, die den Text verdeckt. */
  .pa__media { position: relative; top: auto; height: clamp(16rem, 62vw, 26rem); }
}

/* --------------------------------------------------------------------------
   Dieselbe Teilung als geschlossene Seite
   Ohne Kopfleiste gibt es nichts, wovor die Flaeche zuruecktreten muesste:
   der Abstand oben faellt weg, die Aufnahme nimmt die volle Bildschirmhoehe.
   Die Seite ist so hoch wie der Bildschirm und laeuft nicht - deshalb steht
   sie hier fest statt klebend, sonst hinge sie an einem Weg, den es nicht
   gibt.
   -------------------------------------------------------------------------- */

.pa--zu {
  padding-top: 0;
  min-height: 100svh;
}
.pa--zu .pa__media { top: 0; height: 100svh; }

/* Der Takt richtet sich hier nach der Fensterhoehe, nicht nach der Breite.
   Auf den Inhaltsseiten ist das egal - dort darf gescrollt werden. Hier
   nicht: eine Wartetafel, bei der der Knopf unter der Kante liegt, sieht
   aus wie eine Seite, die nicht fertig geladen hat. Die Werte in vh sind
   deshalb keine Verzierung, sondern der Grund, dass alles hineinpasst. */
.pa--zu .pa__body { padding-block: clamp(2.2rem, 6vh, 4.5rem); }
/* Der Abstand unter "opens soon" ist der einzige Absatz auf dieser Seite -
   oben steht seit dem Wegfall des Kickers nichts mehr, was ihn setzen
   koennte. Er darf deshalb deutlich groesser sein als der Zeilenabstand
   der Ueberschrift, sonst kleben Satz und Zeile aneinander. */
.pa--zu .pa__title {
  font-size: clamp(2rem, 3.4vw, 3.2rem);
  margin: 0 0 clamp(1.8rem, 4.4vh, 3rem);
}
/* Zwei Zeilen, immer. Auf breiten Schirmen passte "Study I opens soon" in
   eine - und die Schreibschrift wirkt neben der Antiqua dann wie ein
   Zusatz statt wie die zweite Haelfte des Satzes. */
.pa--zu .pa__title .script { display: block; }
.pa--zu .pa__lede { margin-bottom: clamp(1.3rem, 3.4vh, 2.4rem); }
.pa--zu .form,
.pa--zu .form__row { gap: clamp(0.85rem, 2.2vh, 1.5rem); }

/* Flache Fenster - ein 13-Zoll-Rechner mit Browserleiste hat keine 800
   Punkte Hoehe. Dort werden zusaetzlich die Felder niedriger; darunter
   bliebe nur noch, die Schrift zu verkleinern, und das faengt an, billig
   auszusehen. */
@media (min-width: 901px) and (max-height: 820px) {
  .pa--zu .form--light .field input { height: 3rem; }
  .pa--zu .form--light .field label { margin-bottom: 0.3rem; }
  .pa--zu .form--light [type="submit"] { padding-block: 0.85em; }
}

/* Auf dem Telefon.
   Das Zeichen war hier eine halbe Bildschirmhoehe hoch - schoen, aber es
   schob die beiden Felder unter die Kante, und ein Formular, das man erst
   suchen muss, wird nicht ausgefuellt. Es steht jetzt als Band oben, und
   was zu tun ist, ist beim Aufschlagen zu sehen. */
@media (max-width: 900px) {
  .pa--zu { min-height: 0; }
  /* Nicht kleiner. Die Aufnahme ist hochkant, das Band schneidet sie oben
     und unten - unter dieser Hoehe fehlen dem Zeichen die vier Spitzen,
     und ein angeschnittenes Signet sieht nach Versehen aus, nicht nach
     Ausschnitt. Alles Weitere wird darunter gespart, nicht hier. */
  .pa--zu .pa__media { height: clamp(17rem, 36vh, 19rem); }
  .pa--zu .pa__body { padding-block: clamp(1.4rem, 3vh, 2.2rem); }
  .pa--zu .pa__title { margin-bottom: 1.2rem; }
  .pa--zu .pa__lede { margin-bottom: 1.4rem; }
  .pa--zu .form { gap: 1.15rem; }
  /* Daumengroesse. 54 Punkte hoch ist der Bereich, den man im Gehen
     trifft; der Knopf lag mit seinem Innenabstand darunter. */
  .pa--zu .form--light [type="submit"] { padding-block: 1.15em; }
}

/* --------------------------------------------------------------------------
   Die Einladung als Zweiteiler
   Dieselbe Teilung wie auf der Private-Access-Seite. Vorher lag die Aufnahme
   als Grund darunter und der Text mit einem Schleier darauf — bei einer so
   dunklen Aufnahme trug der Schleier nichts bei und nahm dem Bild die
   Zeichnung.
   -------------------------------------------------------------------------- */

.invite--geteilt {
  display: grid;
  grid-template-columns: 1fr 1fr;
  align-items: stretch;
  background: var(--paper);
  min-height: 0;
  padding: 0;
}
.invite--geteilt .invite__media { position: relative; min-height: 100svh; }
.invite--geteilt .invite__media picture { display: block; height: 100%; }
.invite--geteilt .invite__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
}
.invite--geteilt .invite__media img { object-fit: cover; display: block; }
.invite--geteilt .invite__body {
  position: static;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  text-align: left;
  color: var(--ink);
  padding: clamp(3rem, 7vw, 6rem) clamp(1.5rem, 5vw, 5rem);
  max-width: none;
}
/* An jeder Fuge dieses Blocks wirkten drei Abstaende gleichzeitig: der
   Flex-Abstand von .invite__body (1,4rem), der Rand der Ueberschrift und
   obendrein ein margin-top, das jeder Absatz in einer Einladung mitbringt.
   In einer Flex-Spalte fallen die nicht zusammen, sie addieren sich.

   Zwischen Ueberschrift und Absatz kam so heraus: 22,4 + 28,8 + 22,4 =
   73,6 px. Gemessen waren es 74. Der Text stand nicht auseinander, weil
   es jemand so wollte, sondern weil drei Regeln dasselbe wollten.

   Deshalb: der Flex-Abstand auf 0, jeder mitgebrachte Rand auf 0, und
   dann genau ein Abstand je Fuge. Eine Fuge, eine Regel, eine Stelle zum
   Nachsehen. Die Absatzregel weiter oben nimmt diese Fassung inzwischen
   ausdruecklich aus, statt dass hier Spezifitaet dagegensteht. */
.invite--geteilt .invite__body { gap: 0; }
.invite--geteilt .invite__body > * { margin-top: 0; margin-bottom: 0; }

.invite--geteilt .invite__head {
  font-size: clamp(2.2rem, 4.4vw, 3.8rem);
}
.invite--geteilt .invite__body > .eyebrow {
  margin-bottom: clamp(0.8rem, 1.6vw, 1.25rem);
}
.invite--geteilt .invite__body > .invite__head {
  margin-bottom: clamp(1rem, 1.9vw, 1.5rem);
}
.invite--geteilt .invite__body > .invite__lede {
  color: var(--muted-dark);
  max-width: 40ch;
  /* 1,75 war der Zeilenabstand einer Fliesstextspalte. Das hier sind drei
     Zeilen neben einem Bild; so weit auseinander lesen sie sich nicht als
     Absatz, sondern als drei einzelne Saetze. */
  line-height: 1.6;
  margin-bottom: clamp(1.6rem, 2.9vw, 2.25rem);
}

/* --- Abschluss der Produktseite -------------------------------------------
   Dieselbe Teilung wie die Einladung, die hier bis zum 17.08.2026 stand -
   nur mit einer Anmeldung statt einer Aufforderung, Zugang anzufragen. Kein
   neues Bauteil: .invite--geteilt traegt die Anlage, .news__form das
   Formular. Hier stehen nur die Abweichungen der linksbuendigen Spalte. */
/* Gedeckelt wie die uebrigen Kapitel der Produktseite. Die Startseite
   traegt dieselbe Teilung, bleibt aber bei voller Fensterhoehe - dort ist
   die Einladung der Schlussakkord der ganzen Seite, hier nur ihr Fuss. */
.invite--schluss .invite__media { min-height: min(100svh, 46rem); }

/* Die Ueberschrift ist die einzige der Seite, die ueber zwei Zeilen laeuft -
   alle anderen sind ein bis zwei Woerter und stehen auch auf 375 px noch in
   einer Zeile. Damit fiel hier zum ersten Mal auf, dass .display mit
   line-height 1.02 fuer zwei Zeilen zu eng ist: die Unterlaenge des "y" von
   "Stay" schnitt in das ORVAIN darunter. 1.02 ist fuer eine einzelne Zeile
   gedacht und bleibt dort; gedeckt wird nur der Fall, den es hier gibt. */
.invite--schluss .invite__head { line-height: 1.12; }
.invite--schluss .news__form {
  width: 100%;
  justify-content: flex-start;
  /* Kein eigener Abstand nach oben: den setzt der Absatz darueber. Zwei
     Abstaende an derselben Fuge addieren sich hier, sie fallen nicht
     zusammen - siehe die Regel bei .invite--geteilt .invite__body. */
  margin-top: 0;
}
.invite--schluss .news__form .feld,
.invite--schluss .news__form input { width: min(100%, 22rem); }

@media (max-width: 900px) {
  .invite--geteilt { grid-template-columns: 1fr; }
  .invite--geteilt .invite__media { min-height: clamp(18rem, 66vw, 28rem); }
  /* Die Auftragsflaeche traegt Text; auf schmalen Fenstern braucht sie
     mehr Hoehe als eine Aufnahme, sonst steht der Auftrag gedraengt. */
  .invite--schluss .invite__media { min-height: clamp(24rem, 96vw, 34rem); }
}


/* Der Zustimmungssatz stand als lange Zeile mit einem einzelnen Wort darunter.
   text-wrap: balance verteilt ihn auf zwei gleich lange Zeilen; die Breite
   begrenzt, wie viel er ueberhaupt einnehmen darf. */
.field--check label {
  max-width: 46ch;
  text-wrap: balance;
  line-height: 1.65;
}

/* --------------------------------------------------------------------------
   Fenster (natives <dialog>)
   -------------------------------------------------------------------------- */

.modal {
  border: 0;
  padding: 0;
  max-width: min(38rem, calc(100vw - 2rem));
  width: 100%;
  background: var(--paper);
  color: var(--ink);
  box-shadow: 0 2rem 5rem rgba(13, 26, 47, 0.28);
}
.modal::backdrop { background: rgba(13, 26, 47, 0.62); }
.modal__inner { padding: clamp(1.8rem, 5vw, 3.2rem); }
.modal__h {
  font-size: clamp(1.7rem, 3.2vw, 2.4rem);
  margin: 0.6rem 0 1rem;
}
.modal__lede {
  color: var(--muted-dark);
  line-height: 1.7;
  margin-bottom: clamp(1.6rem, 3vw, 2.2rem);
  max-width: 42ch;
}
.modal__zu { position: absolute; top: 0; right: 0; }
.modal__x {
  background: none;
  border: 0;
  font-size: 1.6rem;
  line-height: 1;
  padding: 0.8rem 1rem;
  color: var(--muted-dark);
  cursor: pointer;
}
.modal__x:hover { color: var(--ink); }
.modal .form { max-width: none; }

/* --------------------------------------------------------------------------
   Aufklappbare Zeilen auf der Objektseite
   Natives <details>/<summary>: klappt ohne JavaScript, ist mit der Tastatur
   bedienbar und wird von Vorlesern angesagt. Die Überschriften stehen in der
   gesperrten Versalschrift des Hauses, nicht in einer Monospace.
   -------------------------------------------------------------------------- */

/* Sitzt jetzt in der Kaufspalte statt in einem eigenen Abschnitt: dort wird
   entschieden, und dort werden die drei Fragen gestellt. */
.klapp { width: 100%; max-width: 30rem; margin-top: clamp(2rem, 4vw, 3rem); }

/* Eigener Abschnitt unter der Kaufspalte statt Anhang darin.
   Dort haben die drei Zeilen die Inhaltsbreite statt der 30 rem einer
   Spalte - eine schmale Saeule mitten in einem leeren Band saehe aus wie
   vergessen. Ohne eigenen Rand oben: die erste Zeile bringt ihre Linie
   selbst mit. */
.klapp-band .klapp {
  max-width: 46rem;
  margin-inline: auto;
  margin-top: 0;
}
.klapp__i { border-bottom: var(--rule) solid var(--bone-line); }
.klapp__i:first-child { border-top: var(--rule) solid var(--bone-line); }

/* Das <summary> behaelt seine Standarddarstellung. Wird ihm display: flex
   gegeben, verliert es in manchen Browsern seine Rolle als Aufklapper - das
   <details> zeigt dann seinen ganzen Inhalt, auch zugeklappt. Der Flex-Kasten
   sitzt deshalb darin, nicht darauf. */
.klapp__k {
  padding: clamp(1rem, 2.2vw, 1.4rem) 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--f-ext);
  font-size: clamp(0.62rem, 0.58rem + 0.16vw, 0.72rem);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--ink);
  transition: color 0.4s var(--ease);
}
/* Das Standarddreieck von Safari und Chrome abschalten. */
.klapp__k::-webkit-details-marker { display: none; }
.klapp__k::marker { content: ""; }
.klapp__z {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
}

/* Der Winkel wird aus zwei Strichen gebaut statt als Zeichen gesetzt: so
   trifft er die Strichstärke der übrigen Linien genau. */
.klapp__z i {
  flex: none;
  width: 0.62rem;
  height: 0.62rem;
  border-right: var(--rule) solid currentColor;
  border-bottom: var(--rule) solid currentColor;
  transform: rotate(45deg) translate(-0.12rem, -0.12rem);
  transition: transform 0.45s var(--ease);
}
.klapp__i[open] .klapp__z i { transform: rotate(-135deg) translate(-0.16rem, -0.16rem); }

.klapp__t {
  padding: 0 0 clamp(1.2rem, 2.5vw, 1.8rem);
  max-width: none;
  color: var(--muted-dark);
  /* Dieselbe Groesse wie .pdp__lede darueber - beide stehen in derselben
     Spalte, und der Unterschied von 0,02rem war sichtbar. */
  font-size: 1.02rem;
  line-height: 1.8;
}
.klapp__t p + p { margin-top: 1rem; }
.klapp__t strong { color: var(--ink); font-weight: 400; }

/* Die gemessenen Werte unter "Groesse und Sitz". Beschriftung und Wert in
   einer Zeile, mit einer Fuehrungslinie dazwischen - hier sucht jemand eine
   Zahl, nicht einen Satz. Es erscheinen nur Felder, die wirklich gemessen
   sind; ungemessene fehlen, statt als Strich dazustehen. */
.klapp__masse {
  margin: 1.1rem 0 0;
  display: grid;
  gap: 0.55rem;
}
.klapp__masse > div {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
}
.klapp__masse dt {
  font-family: var(--f-ext);
  font-size: 0.6rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted-dark);
  white-space: nowrap;
}
/* Die Linie fuellt, was zwischen Beschriftung und Wert frei bleibt. */
.klapp__masse > div::before {
  content: "";
  order: 1;
  flex: 1 1 auto;
  height: 0;
  border-top: var(--rule) solid var(--bone-line);
  transform: translateY(-0.2rem);
}
.klapp__masse dd {
  order: 2;
  margin: 0;
  color: var(--ink);
  font-size: 0.95rem;
  white-space: nowrap;
}
.klapp__masse + p { margin-top: 1.3rem; }

/* --------------------------------------------------------------------------
   Schwebendes Etikett
   Steht im Feld, solange nichts eingegeben ist, und rutscht beim Tippen oder
   Anklicken nach oben an die Kante. Ohne JavaScript: :placeholder-shown sagt,
   ob das Feld leer ist, :focus-within, ob es bedient wird.
   -------------------------------------------------------------------------- */

.feld { position: relative; display: block; width: min(100%, 26rem); }
.feld input { width: 100%; }

.feld__l {
  position: absolute;
  /* Waagerecht buendig mit dem Text im Feld: dessen Innenabstand betraegt
     1,3rem, das Etikett bringt selbst 0,35rem Polster mit. */
  left: calc(1.3rem - 0.35rem);
  top: 50%;
  transform: translateY(-50%);
  transform-origin: left center;
  pointer-events: none;
  color: rgba(13, 26, 47, 0.45);
  font-size: 1rem;
  /* line-height: 1 stand hier und liess den Text zu hoch sitzen: die Box ist
     dann genau schrifthoch, und die Grundlinie liegt darin bei rund 80
     Prozent - der optische Schwerpunkt der Schrift also oberhalb der
     Boxmitte. Die Box muss Ober- und Unterlaenge umfassen, damit
     translateY(-50%) das zentriert, was man sieht.

     1.25 statt normal, weil normal hier 19 px ergab - eine ungerade Zahl,
     und die Haelfte davon ist ein halber Bildpunkt. Schrift, die um einen
     halben Bildpunkt verschoben ist, wird weich gerastert; genau das war an
     diesem Etikett zu sehen. 1.25 ergibt glatte 20 px, der optische Sitz
     aendert sich dabei um einen halben Punkt. */
  line-height: 1.25;
  white-space: nowrap;
  background: var(--paper);
  padding: 0 0.35rem;
  /* Nur transform und Farbe wandern. Die Schriftgroesse mitzuanimieren war
     der Fehler: sie aendert die Etiketthoehe, und weil die Zentrierung mit
     translateY(-50%) genau auf dieser Hoehe steht, verschob sich der
     Bezugspunkt waehrend der Bewegung. Man sah zwei Spruenge statt einem.
     scale() aendert keine Layoutgroesse und laeuft auf dem Compositor. */
  transition: transform 0.3s var(--ease), color 0.3s var(--ease);
}
.feld input:focus + .feld__l,
.feld input:not(:placeholder-shown) + .feld__l {
  transform: translateY(-50%) translateY(-1.62rem) scale(0.72);
  color: var(--muted-dark);
}

@media (prefers-reduced-motion: reduce) {
  .feld__l { transition: none; }
}


/* ==========================================================================
   Haltungsseite — Bildbriefings und Kapitelanlagen

   Nur fuer "Our Philosophy". Die Seite steht als Gerüst: an jeder Stelle,
   an der spaeter eine Aufnahme haengt, steht eine Flaeche mit dem Auftrag
   dafuer. Die Flaeche ist kein Baustellenschild - sie traegt dieselben
   Farben, Schriften und Linien wie der Rest des Hauses, damit man die
   Seite schon jetzt beurteilen kann.
   ========================================================================== */

/* --- Das Briefing -------------------------------------------------------- */


/* Randlos: die senkrechten Linien saessen sonst am Fensterrand. */


/* Der Auftrag fuellt die Flaeche, die ihm die Anlage gibt, statt sein eigenes
   Verhaeltnis durchzusetzen. Gebraucht wird das in den halbseitigen
   Kapiteln der Produktseite: dort gibt die Spalte das Mass vor. Welches
   Verhaeltnis die spaetere Aufnahme haben soll, steht im Auftrag selbst. */


/* Ohne eigene Farbe erbt die Versalzeile .eyebrow die Tinte - auf dunklem
   Grund stuende sie damit unsichtbar. */


/* In der Inhaltsbreite, aber schmaler als die Schale. Eine randlose Flaeche
   ist 1440 breit und damit 900 hoch; dieselbe Aufnahme ueber die volle
   Schalenbreite waere fast ebenso hoch - der Unterschied zwischen den beiden
   Anlagen waere damit aufgehoben. */


/* --- 01 Auftakt ---------------------------------------------------------- */

/* Der Auftakt ist .media--hero, das Bauteil des Sammlungsbanners: volle
   Fensterhoehe, Hausverlauf, Kopfzeile darueber. Hier stehen nur die drei
   Abweichungen - der Satz in der Mitte, der Scroll-Hinweis im Fluss statt
   am Rand geklebt, und der Auftrag als Fuss. */
.auftakt {
  grid-template-rows: 1fr auto;
  place-items: stretch;
  text-align: center;
  color: var(--paper);
  padding-top: var(--head-h);
}
.auftakt > * { grid-column: 1; }
/* Zeile ausdruecklich zuweisen. Ohne das ruecken Satz und Hinweis eine
   Zeile nach unten und die erste bleibt leer - der Satz saesse dann in der
   unteren Haelfte statt dort, wo er stehen soll. */
.auftakt__text { grid-row: 1; }
.auftakt .scroll-cue { grid-row: 2; }
/* Die Aufnahme steht hinter allem und darf keine Zeile des Rasters
   beanspruchen - sonst nimmt sie den freien Platz, in dem der Satz
   mittig stehen soll. Das <img> darin ist ohnehin absolut gesetzt. */
.auftakt > picture { position: absolute; inset: 0; }
/* Der Satz steht links, nicht mittig.
   Die Aufnahme traegt selbst einen Schriftzug - er sitzt bei 54 bis 73
   Prozent der Breite und auf halber Hoehe, also genau dort, wo eine mittige
   Zeile laeuft. Mittig gesetzt schneidet "decoration." mitten durch
   "ORVAIN FRANKFURT". Links gesetzt stehen beide frei: die Aussage auf der
   einen Seite, das Zeichen auf der anderen. */
.auftakt__text {
  align-self: center;
  justify-self: start;
  z-index: 2;
  display: grid;
  justify-items: start;
  gap: clamp(0.9rem, 2vw, 1.6rem);
  /* .shell zentriert ueber margin-inline:auto - damit sass der Satz trotz
     justify-self weiterhin in der Mitte und lief wieder ins Zeichen. */
  margin-inline: 0;
  max-width: min(100%, 44rem);
  text-align: left;
  padding-block: clamp(2rem, 5vh, 4rem);
}
.auftakt__text .lede { max-width: 34ch; margin-inline: 0; color: var(--muted-light); }
/* Der Schleier bekommt eine dritte Bahn von links: dort liegt im Bild die
   helle Spiegelung, auf der weisse Schrift sonst absaeuft. */
.auftakt .hero__veil {
  background:
    linear-gradient(to bottom, rgba(5, 9, 15, 0.55) 0%, rgba(5, 9, 15, 0) 26%),
    linear-gradient(to top, rgba(5, 9, 15, 0.6) 0%, rgba(5, 9, 15, 0) 34%),
    linear-gradient(to right, rgba(5, 9, 15, 0.66) 0%, rgba(5, 9, 15, 0.2) 48%, rgba(5, 9, 15, 0) 66%);
}
/* Absolut gesetzt saesse er auf dem Auftragsband. Im Fluss steht er
   zwischen Satz und Band, wo er hingehoert. */
.auftakt .scroll-cue {
  position: static;
  justify-self: center;
  z-index: 2;
  margin-bottom: clamp(1.4rem, 3.5vh, 2.4rem);
}
/* Ohne eigenen Grund: die ganze erste Ansicht ist die Aufnahme, das Band
   ist ihre Bildunterschrift und kein zweites Feld darunter. Lesbar bleibt
   es ueber den Schleier, der den unteren Rand ohnehin abdunkelt. */
/* Hochkant zeigt ein 16:9-Bild nur noch ein Drittel seiner Breite - und
   vergroessert das Gezeigte dreifach. Der gravierte Schriftzug sitzt
   gemessen bei 54,1 bis 76,8 Prozent der Breite; mittig beschnitten fuellt
   er den halben Bildschirm und laeuft durch den Satz.

   Bei 12 Prozent liegt das Fenster links davon: 6,6 bis 51,6 Prozent im
   Verhaeltnis 4:5, 8,2 bis 39,9 bei 9:16. Zu sehen ist damit die
   Spiegelung und die weiche Bronze - die atmosphaerische Haelfte der
   Aufnahme, ohne Schrift darin. Genau dafuer nennt der Auftrag eine eigene
   Hochformatfassung; bis die da ist, traegt der Versatz. */
@media (orientation: portrait) {
  .auftakt .hero__img { object-position: 12% center; }
}

/* Hochkant gibt es keine linke Spalte. Der Satz rueckt nach oben, das
   Zeichen der Aufnahme bleibt darunter frei stehen. */
@media (max-width: 900px) {
  .auftakt__text {
    justify-self: stretch;
    justify-items: center;
    text-align: center;
    align-self: start;
    padding-top: clamp(2rem, 7vh, 5rem);
  }
  .auftakt__text .lede { max-width: 40ch; margin-inline: auto; }
  .auftakt .hero__veil {
    background:
      linear-gradient(to bottom, rgba(5, 9, 15, 0.72) 0%, rgba(5, 9, 15, 0.1) 46%),
      linear-gradient(to top, rgba(5, 9, 15, 0.66) 0%, rgba(5, 9, 15, 0) 38%);
  }
}

/* Der Fortbestand ist der Schluss des Gedankens und bekommt mehr Luft als
   die drei Kapitel davor - die Groesse der Flaeche gehoert zur Aussage. */
.statement--gross { padding-block: clamp(6rem, 15vh, 12rem); }

/* --- 02 Das Prinzip ------------------------------------------------------ */

.prinzip { background: var(--bone); padding-block: clamp(4.5rem, 11vh, 9rem); text-align: center; }
.prinzip__h { max-width: 20ch; margin-inline: auto; }
.prinzip__text {
  max-width: 34rem;
  margin: clamp(2.2rem, 5vh, 3.5rem) auto 0;
  color: var(--muted-dark);
}

/* --- 07 Tragen ----------------------------------------------------------- */

/* Die einzige geteilte Flaeche der Seite. Sie steht genau einmal, und die
   Achse liegt bei 57 Prozent, nicht bei 50 - halbe/halbe liest sich als
   Baukasten, diese Teilung als Satzspiegel. */
.tragen { padding-block: clamp(4rem, 10vh, 8rem); background: var(--bone); }
.tragen__grid {
  display: grid;
  grid-template-columns: 57fr 43fr;
  gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
.tragen__satz { display: grid; gap: 1.1rem; justify-items: start; max-width: 34ch; }
.tragen__satz p { color: var(--muted-dark); }

/* --- 10 Die Sammlung ----------------------------------------------------- */

.archiv { --frame-bg: var(--bone); background: var(--bone); padding-block: clamp(4.5rem, 11vh, 9rem); text-align: center; }
.archiv__zeile { margin-top: 1rem; color: var(--muted-dark); }
.archiv__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(1.2rem, 2.5vw, 2.2rem);
  margin-top: clamp(2.5rem, 6vw, 4rem);
}
/* Was fuer alle vier gilt, steht einmal unter der Reihe statt viermal
   darin - vier gleiche Absaetze nebeneinander sind Laerm, keine Angabe. */
.archiv .btn { margin-top: clamp(2.4rem, 4.5vw, 3.6rem); }

/* --- Telefon ------------------------------------------------------------- */

@media (max-width: 900px) {
  /* Gestapelt, die Aufnahme zuerst - auf dem Telefon fuehrt das Bild. */
  .tragen__grid { grid-template-columns: 1fr; gap: clamp(1.6rem, 5vw, 2.4rem); }
  .archiv__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 640px) {
  /* Hochformat statt Querformat: die Briefings nennen dafuer eigene Masse. */


}

/* --------------------------------------------------------------------------
   Fehlende Aufnahmen: einspaltig statt leere Haelfte

   Solange eine Aufnahme nicht vorliegt, entfaellt ihre Flaeche ganz. Die
   Abschnitte, die daneben Text tragen, laufen dann ueber die volle Breite -
   ein halb leeres Raster sieht nach Fehler aus, ein einspaltiger Abschnitt
   nicht. Sobald die Datei unter dem vorgesehenen Namen liegt, greift wieder
   die zweispaltige Anlage; hier ist nichts umzuschalten.
   -------------------------------------------------------------------------- */

.gesch--nurtext {
  grid-template-columns: 1fr;
  background: var(--bone);
}
.gesch--nurtext .gesch__body {
  padding-block: clamp(4.5rem, 10vw, 8rem);
}
.gesch--nurtext .gesch__body p:not(.eyebrow) { max-width: 46ch; }

.invite--schluss.invite--nurtext { grid-template-columns: 1fr; }
.invite--schluss.invite--nurtext .invite__body {
  padding-block: clamp(4rem, 9vw, 7rem);
  align-items: center;
  text-align: center;
}
.invite--schluss.invite--nurtext .news__form { justify-content: center; }

/* Die Tragen-Flaeche der Haltungsseite ist ein Zweispalter aus Aufnahme und
   Satz. Fehlt die Aufnahme, bleibt nur der Satz - und der steht mittig,
   nicht in einer 43-Prozent-Spalte am Rand. */
/* Der Abschnitt trug bis zum 18.08.2026 eine Aufnahme neben dem Satz, und
   diese Regel fing den Fall ab, dass sie fehlte - ueber :has(), also indirekt
   und abhaengig davon, was im Markup landet. Die Aufnahme kommt nicht mehr;
   einspaltig ist jetzt die Form. Eine Klasse sagt das geradeheraus. */
.tragen--nurtext .tragen__grid {
  grid-template-columns: 1fr;
  justify-items: center;
}
.tragen--nurtext .tragen__satz {
  justify-items: center;
  text-align: center;
  max-width: 46ch;
}

/* --- Bestaetigungsseite der Anmeldung -----------------------------------
   Eine Seite mit einem Satz. Sie braucht keine Gestaltung, nur Ruhe und
   genug Weissraum darum, damit der eine Satz nicht verloren wirkt.       */
.optin { padding: clamp(6rem, 16vh, 12rem) 0 clamp(5rem, 12vh, 9rem); }
.optin__inner { max-width: 46rem; }
.optin__satz {
  margin-top: 1.6rem; max-width: 34rem;
  font-size: clamp(1.05rem, 1.6vw, 1.2rem); line-height: 1.6;
  color: var(--muted-dark);
}
.optin__weiter { margin-top: 2.6rem; }

/* Das Liefergebiet steht an der Anschrift, nicht erst in den Rechtstexten -
   dort, wo jemand seine Adresse eintippt und es noch etwas nuetzt.        */
/* Der Satz gehoert unter die Ueberschrift der Anschrift und zieht sich
   deshalb an sie heran. Ohne Ueberschrift ueber ihm - wie kurzzeitig am
   18.08.2026 - landete er im Feld darueber. */
.co__gebiet {
  margin: -.4rem 0 1.2rem;
  font-size: .82rem; letter-spacing: .04em;
  color: var(--muted-dark);
}



/* --- Trefferflächen auf dem Telefon --------------------------------------
   Bei 375 px gemessen (Chromium, 375 × 812): die Verweise der Brotkrumen
   waren 9 px hoch, die im Inhaltsverzeichnis eines Beitrags 21, die in der
   Maßtabelle 15. Getroffen wird da mit dem
   Daumen nichts Zuverlässiges; WCAG 2.5.8 nennt 24 px als Untergrenze.

   Vergrößert wird die Fläche, nicht das Element: ein ::after legt sich
   unsichtbar darüber und fängt die Berührung ab. Die Zeile bleibt exakt so
   hoch wie vorher, die Gestaltung ändert sich um nichts. Denselben Weg geht
   .icon-btn seit jeher.

   Verweise mitten im Satz bleiben außen vor - WCAG nimmt sie ausdrücklich
   aus, und ein 24 px hoher Kasten in einem Absatz überdeckte die Zeile
   darüber.                                                                */
.crumb a,
.masse th a,
.masse td a,
.toc__l a { position: relative; }

.crumb a::after,
.masse th a::after,
.masse td a::after,
.toc__l a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1.5rem;
  transform: translateY(-50%);
}

/* --- Sehr schmale Geräte, unter 375 px ----------------------------------
   Gemessen bei 320 px: Seitenrand 40 + Menüknopf 35 + Wortmarke 157 +
   Navigation 119 + zwei Abstände 32 = 383 px. Die Kopfzeile brauchte also
   63 px mehr, als das Fenster hat, und die Seite scrollte seitlich.

   Aufgefallen ist das nie, weil bei 375 px alles auf den Punkt aufgeht —
   und 375 war die einzige Breite, die je gemessen wurde.

   Die 63 px kommen aus drei Stellen, keine davon ändert etwas oberhalb
   von 374 px: schmalerer Seitenrand, engerer Abstand zwischen den drei
   Feldern der Kopfzeile, und eine etwas weniger gesperrte Wortmarke.
   `minmax(0, 1fr)` erlaubt den äußeren Spalten außerdem, unter ihre
   Inhaltsbreite zu schrumpfen, statt das Raster aufzublähen.            */
@media (max-width: 374px) {
  /* Ueber die Variable, nicht ueber die Eigenschaft: andere Bauteile
     rechnen mit --pad, wenn sie aus der Inhaltsbreite herauslaufen (etwa
     die Zeilen des Fussbereichs). Wird nur .shell umgestellt, laufen die
     beiden Werte auseinander und die Zeilen ragen ueber den Rand. */
  :root { --pad: 0.85rem; }

  .header__inner {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 0.45rem;
  }
  .mark__name { letter-spacing: 0.26em; }
  .mark__place { letter-spacing: 0.14em; font-size: 0.46rem; }
  .nav { gap: 0.7rem; }

  /* Die Zahl am Warenkorb sitzt als Abzeichen über der rechten Kante des
     Knopfes. Ganz außen ragte sie damit über den Fensterrand. */
  .nav .cart-btn__n { right: -0.1rem; }

  /* Die Schriftskala hörte nach unten zu früh auf. `clamp` nimmt den
     größeren von Untergrenze und vw-Wert — bei 320 px liegt die Untergrenze
     von .d-xxl mit 46 px weit über den 26 px, die 8,2 vw ergäben. Die
     Überschrift wurde also nie kleiner, egal wie schmal das Gerät.

     Ein Wort wie „Handgelenk" in der Schreibschrift braucht bei 48 px
     314 px Platz; da sind 292 px. Die Untergrenzen sinken deshalb hier
     unten, und zwar nur hier: ab 375 px gilt die Skala unverändert. */
  .d-xxl { font-size: clamp(2.2rem, 11.5vw, 8.8rem); }
  .d-xl  { font-size: clamp(2.05rem, 10.5vw, 6.2rem); }
  .d-l   { font-size: clamp(1.75rem, 9vw, 4.2rem); }
}

/* Deutsche Komposita sind länger als englische, und ein Wort, das nicht
   umbrechen darf, zwingt seinem Kasten eine Mindestbreite auf — auch wenn
   das Fenster schmaler ist. Auf schmalen Geräten darf deshalb getrennt
   werden; die Silbentrennung greift nur, wenn es sonst nicht passt.

   `min-width: 0` erlaubt den Rasterfeldern außerdem, unter ihre
   Inhaltsbreite zu schrumpfen. Ohne das bläht ein einziges langes Wort das
   ganze Raster auf und die Seite scrollt seitlich. */
@media (max-width: 480px) {
  h1, h2, h3, p, li, figcaption, .display { overflow-wrap: break-word; }
  .band__inner, .gesch__body, .tragen__satz, .invite__body,
  .statement .shell, .prose { min-width: 0; }
}

/* Silbentrennung nur dort, wo sie wirklich gebraucht wird. Bei 480 px
   angesetzt trennte sie auch Überschriften, die ohne sie sauber umbrechen —
   „Ket-ten" in einer Zeile, die Platz hatte. Übergelaufen ist nichts
   oberhalb von 360 px; unter 375 fängt sie die langen Komposita ab. */
@media (max-width: 374px) {
  h1.display, h2.display, .gesch__h, .band__inner h2 { hyphens: auto; }
}

/* --- Trefferflächen auf dem Telefon --------------------------------------
   Bei 375 px gemessen (Chromium, 375 × 812): die Verweise der Brotkrumen
   waren 9 px hoch, die im Inhaltsverzeichnis eines Beitrags 21, die in der
   Maßtabelle 15. Getroffen wird da mit dem
   Daumen nichts Zuverlässiges; WCAG 2.5.8 nennt 24 px als Untergrenze.

   Vergrößert wird die Fläche, nicht das Element: ein ::after legt sich
   unsichtbar darüber und fängt die Berührung ab. Die Zeile bleibt exakt so
   hoch wie vorher, die Gestaltung ändert sich um nichts. Denselben Weg geht
   .icon-btn seit jeher.

   Verweise mitten im Satz bleiben außen vor - WCAG nimmt sie ausdrücklich
   aus, und ein 24 px hoher Kasten in einem Absatz überdeckte die Zeile
   darüber.                                                                */
.crumb a,
.masse th a,
.masse td a,
.toc__l a { position: relative; }

.crumb a::after,
.masse th a::after,
.masse td a::after,
.toc__l a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 1.5rem;
  transform: translateY(-50%);
}

/* --- Sehr schmale Geräte, unter 375 px ----------------------------------
   Gemessen bei 320 px: Seitenrand 40 + Menüknopf 35 + Wortmarke 157 +
   Navigation 119 + zwei Abstände 32 = 383 px. Die Kopfzeile brauchte also
   63 px mehr, als das Fenster hat, und die Seite scrollte seitlich.

   Aufgefallen ist das nie, weil bei 375 px alles auf den Punkt aufgeht —
   und 375 war die einzige Breite, die je gemessen wurde.

   Die 63 px kommen aus drei Stellen, keine davon ändert etwas oberhalb
   von 374 px: schmalerer Seitenrand, engerer Abstand zwischen den drei
   Feldern der Kopfzeile, und eine etwas weniger gesperrte Wortmarke.
   `minmax(0, 1fr)` erlaubt den äußeren Spalten außerdem, unter ihre
   Inhaltsbreite zu schrumpfen, statt das Raster aufzublähen.            */
@media (max-width: 374px) {
  .shell { padding-left: 0.85rem; padding-right: 0.85rem; }

  .header__inner {
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    gap: 0.45rem;
  }
  .mark__name { letter-spacing: 0.26em; }
  .mark__place { letter-spacing: 0.14em; font-size: 0.46rem; }
  .nav { gap: 0.7rem; }

  /* Die Zahl am Warenkorb sitzt als Abzeichen über der rechten Kante des
     Knopfes. Ganz außen ragte sie damit über den Fensterrand. */
  .nav .cart-btn__n { right: -0.1rem; }

  /* Die Schriftskala hörte nach unten zu früh auf. `clamp` nimmt den
     größeren von Untergrenze und vw-Wert — bei 320 px liegt die Untergrenze
     von .d-xxl mit 46 px weit über den 26 px, die 8,2 vw ergäben. Die
     Überschrift wurde also nie kleiner, egal wie schmal das Gerät.

     Ein Wort wie „Handgelenk" in der Schreibschrift braucht bei 48 px
     314 px Platz; da sind 292 px. Die Untergrenzen sinken deshalb hier
     unten, und zwar nur hier: ab 375 px gilt die Skala unverändert. */
  .d-xxl { font-size: clamp(2.2rem, 11.5vw, 8.8rem); }
  .d-xl  { font-size: clamp(2.05rem, 10.5vw, 6.2rem); }
  .d-l   { font-size: clamp(1.75rem, 9vw, 4.2rem); }
}

/* Deutsche Komposita sind länger als englische, und ein Wort, das nicht
   umbrechen darf, zwingt seinem Kasten eine Mindestbreite auf — auch wenn
   das Fenster schmaler ist. Auf schmalen Geräten darf deshalb getrennt
   werden; die Silbentrennung greift nur, wenn es sonst nicht passt.

   `min-width: 0` erlaubt den Rasterfeldern außerdem, unter ihre
   Inhaltsbreite zu schrumpfen. Ohne das bläht ein einziges langes Wort das
   ganze Raster auf und die Seite scrollt seitlich. */
@media (max-width: 480px) {
  h1, h2, h3, p, li, figcaption, .display { overflow-wrap: break-word; }
  .band__inner, .gesch__body, .tragen__satz, .invite__body,
  .statement .shell, .prose { min-width: 0; }
}

/* Silbentrennung nur dort, wo sie wirklich gebraucht wird. Bei 480 px
   angesetzt trennte sie auch Überschriften, die ohne sie sauber umbrechen —
   „Ket-ten" in einer Zeile, die Platz hatte. Übergelaufen ist nichts
   oberhalb von 360 px; unter 375 fängt sie die langen Komposita ab. */
@media (max-width: 374px) {
  h1.display, h2.display, .gesch__h, .band__inner h2 { hyphens: auto; }
}



/* --- Das braune Bild hinter dem Band, nur auf dem Telefon ---------------
   Der Abschnitt war ein reiner dunkelblauer Verlauf: 698 px Farbe mit
   einem Satz darin, mitten zwischen zwei hellen Produktreihen. Auf dem
   Telefon las sich das wie ein Block, der versehentlich stehengeblieben
   ist; dort liegt jetzt das Signet darunter.

   Am Schreibtisch bleibt der Verlauf. Über die volle Breite gezogen wird
   das Signet zu einem riesigen Ornament hinter der Zeile und nimmt ihr
   mehr, als es gibt - schmal gilt das nicht, da trägt die Textur nur.

   Das Bild wird oberhalb von 900 px gar nicht erst geladen: `display:
   none` auf dem <img> genügt dafür nicht immer, die Quelle steht aber in
   einem <picture> mit srcset, und der Browser wählt danach. Der
   Ladeaufwand bleibt damit auf dem Gerät, das es auch zeigt.           */
.band--bild { background: var(--ink); }
.band--bild .band__img { display: none; }
.band--bild .band__inner { position: relative; z-index: 2; }

@media (max-width: 900px) {
  .band--bild .band__img {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
  }
  .band--bild::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    background:
      radial-gradient(70% 60% at 50% 45%, rgba(0, 0, 0, 0.18), transparent 75%),
      linear-gradient(168deg, rgba(9, 14, 22, 0.72) 0%, rgba(4, 7, 12, 0.82) 100%);
  }
}

/* --- Zwei Abschnitte mit Bild (Study I) ----------------------------------
   Hier standen zwei nackte Textblöcke nebeneinander: Überschrift, Satz,
   Knopf — zweimal, ohne etwas dazwischen. Am Schreibtisch ging das durch,
   auf dem Telefon standen sie untereinander und lasen sich wie eine Liste
   von Verweisen.

   Jeder Block trägt jetzt eine vorhandene Aufnahme darüber. Nichts wurde
   dafür produziert: der gebürstete Stahl lag ungenutzt unter assets/story/,
   ebenso die Wand mit dem Schriftzug.                                      */
.zwei {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(2rem, 5vw, 4rem);
  align-items: start;
}
.zwei__k { display: grid; justify-items: start; gap: 0.9rem; }
.zwei__f {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--bone);
  margin-bottom: 0.6rem;
}
.zwei__img { width: 100%; height: 100%; object-fit: cover; display: block; }
.zwei__h { margin: 0; }
.zwei__t { color: var(--muted-dark); max-width: 38ch; }
.zwei .btn { margin-top: 0.4rem; }

@media (max-width: 760px) {
  .zwei { grid-template-columns: 1fr; gap: clamp(2.4rem, 8vw, 3.4rem); }
  .zwei__f { aspect-ratio: 16 / 10; }
}

/* --- Fußbereich auf schmalen Fenstern ------------------------------------
   Drei Spalten (1fr auto 1fr) brachen hier in Paare um: „Unsere
   Gemeinschaft  Kontakt" nebeneinander, darunter die Zeichen, darunter
   „Unsere Philosophie  Rechtliches". Ungleich lange Paare, ungleiche
   Abstände — der Block sah aus, als gehöre er nicht dazu.

   Jetzt eine Zeile je Eintrag, über die volle Breite, mittig, dazwischen
   je eine Haarlinie. Dieselben Verweise, dieselbe Reihenfolge, nur
   gestapelt.

   Die Linien sitzen auf den drei unmittelbaren Feldern des Rasters, nicht
   auf den Verweisen darin: nur die laufen zuverlässig über die volle
   Breite. Zwei Regeln außerhalb dieser Abfrage — `justify-items: center`
   und `justify-self: end` für das letzte Feld — halten die inneren sonst
   auf Inhaltsbreite, und die Linien endeten mitten im Fenster.          */
@media (max-width: 760px) {
  .footer__bar-inner {
    grid-template-columns: 1fr;
    gap: 0;
    padding-block: 0;
  }

  .footer__bar-inner > *,
  .footer__bar-inner > :last-child {
    justify-self: stretch;
    margin-inline: calc(var(--pad) * -1);
    padding-inline: var(--pad);
  }
  /* Die oberste Linie kommt schon von .footer__bar. */
  .footer__bar-inner > * + * { border-top: var(--rule) solid var(--bone-line); }

  .footer__links {
    display: grid;
    /* Ohne Spaltenangabe bleibt die einzige Spalte inhaltsbreit, und
       `justify-content: center` aus der Regel darueber schiebt sie in die
       Mitte: die Verweise standen 98 px breit in einem 430 px breiten
       Kasten, die Trennlinien entsprechend kurz. Gemessen 20.08.2026. */
    grid-template-columns: 1fr;
    justify-content: stretch;
    gap: 0;
    justify-items: stretch;
  }
  .footer__links > a {
    padding-block: 1.05rem;
    text-align: center;
  }
  /* Zwei Verweise in einem Feld brauchen dazwischen ebenfalls eine Linie. */
  .footer__links > a + a,
  .footer__links > a + .footer__more {
    border-top: var(--rule) solid var(--bone-line);
    margin-inline: calc(var(--pad) * -1);
    padding-inline: var(--pad);
  }

  .footer__more { padding-block: 1.05rem; }
  .footer__more > summary { justify-content: center; width: 100%; }

  /* „Rechtliches" klappte als schwebendes Feld von 14rem ueber der Zeile
     auf. Bei 320 px ragte es links heraus, und auf einem Telefon ist ein
     schwebendes Feld ohnehin die falsche Form: es klappt jetzt in den
     Fluss auf, ueber die volle Breite, wie eine Liste. */
  .footer__morelist {
    position: static;
    min-width: 0;
    width: 100%;
    border-inline: 0;
    border-bottom: 0;
    box-shadow: none;
    background: none;
    padding-block: 0.2rem 0.4rem;
  }
  .footer__morelist a,
  .footer__morelist .footer__link {
    justify-content: center;
    padding-block: 0.7rem;
    white-space: normal;
  }
  /* Der Pfeil hinter jeder Zeile faellt weg - in einer Liste ohne Rahmen
     zeigt er nicht mehr aus einem Feld heraus, sondern steht nur herum. */
  .footer__morelist a::after,
  .footer__morelist .footer__link::after { display: none; }

  .footer__social { padding-block: 1.15rem; gap: 1.6rem; }
  .footer__copy { padding-block: 1.3rem; }
}

/* --- Library: die kompakte Liste beginnt früher --------------------------
   Zwischen 640 und 900 px stand das Raster noch dreispaltig, und in eine
   Drittelspalte passt bei 700 px weder ein Bild noch eine Überschrift. Die
   Liste greift jetzt ab 900 px abwärts. Der Daumennagel wird dabei etwas
   größer, damit das Motiv erkennbar bleibt.                               */
@media (max-width: 900px) {
  .jgrid { gap: 0; }

  .jcard {
    display: grid;
    grid-template-columns: 6.25rem minmax(0, 1fr);
    grid-template-areas:
      "bild rubrik"
      "bild titel"
      "bild dauer";
    align-items: start;
    column-gap: 1.15rem;
    row-gap: 0.25rem;
    padding: 1.05rem 0;
    border-bottom: var(--rule) solid var(--bone-line);
  }
  .jcard:last-child { border-bottom: 0; }

  .jcard__f { grid-area: bild; aspect-ratio: 1; margin-bottom: 0; align-self: center; }
  .jcard__k { grid-area: rubrik; font-size: 0.6rem; letter-spacing: 0.17em; }
  .jcard__t {
    grid-area: titel;
    font-size: 1.05rem;
    line-height: 1.3;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  .jcard__d { display: none; }
  .jcard__m { grid-area: dauer; font-size: 0.64rem; opacity: 0.75; }

  .jgroup { padding-block: 1.6rem; }
  .jgroup__h {
    font-size: 1.28rem;
    padding-bottom: 0.7rem;
    margin-bottom: 0.4rem;
  }
}

/* --- Kopfzeile auf dem Telefon: Zeichen links, Werkzeug rechts ------------
   Bis zum 21.08.2026 stand das Zeichen auch auf dem Telefon in der Mitte,
   zwischen Menueknopf links und drei Eintraegen rechts. Mittig war es
   allerdings nur rechnerisch: die rechte Gruppe wiegt schwerer als der
   einzelne Menueknopf, und weil das Zeichen selbst breit baut, sass es
   sichtbar aus der Achse. Ein Zeichen, das fast mittig steht, liest sich
   als Fehler - eines, das an der linken Kante steht, als Absicht.

   Deshalb hier dieselbe Ordnung wie bei Aesop: Zeichen links an der Kante,
   rechts Konto, Warenkorb, Menue. Der Sprachwaehler wandert ins Vollbild-
   menue (siehe .menu__sprachen); vier Dinge rechts waeren eine Zeile zu
   voll. Am Schirm bleibt alles, wie es war - Vorgabe 21.08.2026.

   Flex statt Raster: die drei Felder des Rasters liegen in fester Ordnung,
   und der Menueknopf steht im Baum vor dem Zeichen. `order` bringt ihn ans
   Ende, ohne dass die Reihenfolge im Baum sich aendert - fuer Tastatur und
   Vorlesen bleibt sie damit die alte.                                    */
@media (max-width: 760px) {
  .header__inner {
    display: flex;
    align-items: center;
    gap: 0.75rem;
  }
  /* `margin-right: auto` schiebt alles Uebrige nach rechts. */
  .mark { order: 1; margin-right: auto; justify-self: auto; place-items: center start; }

  /* Auf dem Telefon steht der Schriftzug der Marke, sonst nichts: kein
     gesetzter Text, kein Wechsel aufs Zeichen. Der Uebergang war am Schirm
     eine Zierde und auf dem Telefon ein Zappeln - drei Zustaende in einer
     Kopfzeile, die 3,8 rem hoch ist. Vorgabe 21.08.2026. */
  .mark__word, .mark .mark__icon { display: none; }
  .mark img.mark__wort {
    display: block;
    grid-area: 1 / 1;
    width: 5.9rem;
    height: auto;
    /* Die Vorlage ist schwarz auf durchsichtig; ueber dunklen Aufnahmen
       dreht der Filter sie ins Helle. Dieselbe Regel wie beim Zeichen -
       .mark img traegt sie ohnehin, hier steht nur die Ausnahme fuer den
       Fall, dass der Kopf auf Papier steht. */
    opacity: 1;
    transform: none;
  }
  .nav--end { order: 2; justify-self: auto; gap: 0.9rem; }
  .burger { order: 3; justify-self: auto; flex: none; }
  /* Der Waehler im Kopf verschwindet, nicht die Sprachwahl: sie steht im
     Menue. Ohne `display: none` bliebe die Klappliste im Baum und oeffnete
     sich unsichtbar unter dem Rand. */
  .header .lang { display: none; }
}

/* Die Sprachen im Vollbildmenue: eine Zeile Kuerzel, kein Menue im Menue. */
.menu__sprachen { display: none; }
@media (max-width: 760px) {
  .menu__sprachen {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    margin-top: 2rem;
    padding-top: 1.4rem;
    border-top: var(--rule) solid rgba(255, 255, 255, 0.14);
  }
  .menu__sprache {
    font-family: var(--f-ext);
    font-size: 0.68rem;
    letter-spacing: 0.24em;
    text-transform: uppercase;
    color: var(--paper);
    opacity: 0.55;
    /* Trefferflaeche nach WCAG 2.5.8, ohne die Zeile hoeher zu machen. */
    position: relative;
    padding-block: 0.5rem;
  }
  .menu__sprache::after {
    content: "";
    position: absolute;
    top: 50%;
    left: -0.3rem;
    right: -0.3rem;
    height: 2.75rem;
    transform: translateY(-50%);
  }
  .menu__sprache.is-on { opacity: 1; color: var(--gold); }
}

/* --- Die Kasse: Karte, Blatt, Anschrift ----------------------------------
   Umbau vom 21.08.2026 nach dem Vorbild von Aesop (Vorgabe mit
   Bildschirmfotos). Die Kasse selbst bleibt kurz: zwei bis drei zugeklappte
   Zeilen und die Bestellung. Ausgefuellt wird in einem Blatt, das sich
   darueberlegt, nicht auf der Seite - so steht immer genau eine Frage im
   Bild, und niemand scrollt an der Zahlung vorbei.                       */

/* Die Karte im offenen Schritt: eine Angabe, ein Knopf. */
.co__karte { display: grid; gap: 0.25rem; }
.co__karteh { font-size: 0.98rem; }
.co__karted { font-size: 0.86rem; color: var(--muted-dark); }
.co__karte .btn { margin-top: 1.1rem; justify-content: center; }

/* Die Lieferzeile mit Auswahlknopf: Knopf links, Beschriftung daneben, der
   erklaerende Satz darunter auf derselben Flucht - nicht unter dem Knopf.
   Zwei Spalten, drei Zeilen; der Knopf am Ende laeuft ueber beide. */
.co__karte--wahl {
  grid-template-columns: auto 1fr;
  align-items: center;
  column-gap: 0.7rem;
}
.co__karteradio { width: auto; margin: 0; accent-color: var(--ink); justify-self: start; }
/* Groesse und Farbe ausdruecklich: `.co__pay label` setzt im Formular
   0.64rem in gedaempftem Ton - richtig fuer eine Feldbeschriftung, falsch
   fuer die Zeile, um die es hier geht. Ohne diese Zeile stuende die
   Lieferart kleiner da als ihre eigene Erlaeuterung. */
.co__karte--wahl .co__karteh {
  grid-column: 2;
  cursor: pointer;
  font-size: 0.98rem;
  color: var(--ink);
  margin-bottom: 0;
}
.co__karte--wahl .co__karted { grid-column: 2; margin: 0; }
.co__karte--wahl .btn { grid-column: 1 / -1; }
/* Die Karte des abgeschlossenen Schrittes: dieselbe Ordnung, nur ohne Knopf
   und auf ruhigem Grund. */
.co__karte--ruhig {
  background: var(--co-card);
  border: var(--rule) solid var(--bone-line);
  padding: clamp(0.85rem, 2vw, 1.15rem);
  gap: 0.15rem;
}
.co__karte--ruhig .co__karteh { color: var(--muted-dark); font-size: 0.86rem;
                                margin-bottom: 0.35rem; }
.co__karte--ruhig .co__karted { color: var(--ink); }

/* Kopfzeile eines Schrittes: rechts erst "Ändern", dann die Nummer. */
.co__stepakt { display: flex; align-items: baseline; gap: 0.7rem; white-space: nowrap; }
.co__stepakt .co__edit { font-size: 0.82rem; }
.co__stepakt .co__edit[hidden] { display: none; }
.co__done { display: block; }

/* Der Schritt, der noch nicht dran ist, ist keine Schaltflaeche. */
.co__step[hidden] { display: none; }

/* --- Die Anschriftsmaske auf der Seite ------------------------------------
   Hier lag bis zum 21.08.2026 das Blatt: ein Kasten, der sich ueber die
   Kasse legte. Vorgabe vom selben Tag: kein Aufklapper mehr, nirgends -
   alles steht auf der Seite. Damit fallen Schleier, Kasten, Kopf- und
   Fusszeile weg, und mit ihnen die ganze Sonderbehandlung der Sichtbarkeit,
   die Stripes Bezahlfeld dort brauchte. Es wird jetzt schlicht erst
   montiert, wenn sein Schritt aufgeht - siehe js/main.js.              */
/* --- Am Schirm auf der Seite, am Telefon ein Blatt ------------------------
   Der Grund steht im Markup ausfuehrlich: neun Felder samt Knopf messen rund
   900 Pixel, ein Telefon zeigt etwa 700. Auf der Seite hiesse das einmal
   scrollen, nur um zu sehen, was zu tun ist. Am Schirm ist Platz - dort
   bleibt die Maske, wo sie steht.

   Die Grenze ist dieselbe wie beim Raster der Kasse (860 px): darunter
   stehen Schritte und Bestellung untereinander, darueber nebeneinander. */
.co__anschrift { margin-top: 1.1rem; }
.co__anschrift[hidden] { display: none; }
.co__amaskkopf { display: none; }
.co__amaskfuss { margin-top: 1.2rem; }

@media (max-width: 860px) {
  /* --- Warum hier nicht `inset: 0` steht ---------------------------------
     Weil der Kaufknopf sonst hinter Safaris unterer Leiste sitzt.

     Ein Kasten mit `position: fixed` misst sich am Layout-Fenster. Auf dem
     iPhone ist das groesser als das, was man sieht: die Adress- und
     Werkzeugleiste liegen darueber. `inset: 0` heisst also "bis zur
     Unterkante des Layout-Fensters" - und die ist unter der Leiste. Mit
     `align-items: flex-end` landet der Fuss des Blattes genau dort.
     Gemeldet am 21.08.2026 mit Bildschirmfoto vom Geraet: "Diese Adresse
     verwenden" war zur Haelfte verdeckt.

     Im Browser-Bereich am Rechner faellt das nicht auf - dort gibt es keine
     wandernden Leisten, und die Messung sagte 812 von 812. Ein Blatt, das
     unten aufsitzt, muss auf dem Geraet gegengeprueft werden.

     Deshalb: oben verankern und die Hoehe aus dem *sichtbaren* Fenster
     nehmen. `100dvh` kennt die Leisten und schrumpft mit ihnen. `--sicht`
     setzt js/main.js aus window.visualViewport, wo es das gibt - das ist
     genauer, weil es auch die eingeblendete Tastatur mitzaehlt. Fehlt
     beides, bleibt `100vh`, und der alte Fehler waere zurueck; darum steht
     dvh davor und vh nur als letzter Halt. */
  .co__anschrift {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 100vh;
    height: 100dvh;
    height: var(--sicht, 100dvh);
    /* Verrutscht das sichtbare Fenster selbst - etwa bei offener
       Tastatur -, wandert das Blatt mit. Ohne visualViewport ist der
       Wert 0 und die Zeile wirkungslos. */
    transform: translateY(var(--sicht-oben, 0px));
    z-index: 90;
    margin: 0;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    background: rgba(13, 26, 47, 0.42);
  }
  /* Eine Klassenregel mit `display` schlaegt sonst das hidden-Attribut, und
     das Blatt laege von Anfang an ueber der Kasse. Dieselbe Falle wie bei
     .co__done und .lang__list. */
  .co__anschrift[hidden] { display: none; }

  /* Drei Zeilen: Kopf, Rumpf, Fuss. Nur der Rumpf scrollt - so bleibt der
     Knopf im Bild, egal wie lang die Maske wird. `dvh` statt `vh`, weil auf
     dem Telefon die Adressleiste mitwandert und `vh` dort die groessere,
     zeitweise falsche Hoehe meint. */
  .co__amaskbox {
    width: 100%;
    /* Der Rahmen darueber ist bereits genau so hoch wie das sichtbare
       Fenster - hier genuegt "so hoch wie er". Ein eigener dvh-Wert waere
       eine zweite Rechnung ueber dieselbe Hoehe. */
    max-height: 100%;
    display: grid;
    grid-template-rows: auto minmax(0, 1fr) auto;
    background: var(--co-panel);
    border-radius: 0.9rem 0.9rem 0 0;
    overflow: hidden;
  }
  .co__amaskkopf {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.6rem 1rem;
    border-bottom: var(--rule) solid var(--bone-line);
  }
  .co .co__amaskkopf .co__h { font-size: 1rem; color: var(--ink); }
  .co__amaskrumpf {
    padding: 0.6rem 1rem 0.5rem;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
  /* Der Satz "Wir liefern nach Deutschland und in die EU" faellt im Blatt
     weg. Nicht aus Platznot allein: die Laenderliste darueber zaehlt genau
     die 27 Laender auf, in die geliefert wird - sie IST die Auskunft, der
     Satz nur ihre Wiederholung. Zwei Zeilen dafuer sind auf einem kleinen
     Telefon der Unterschied zwischen "passt" und "einmal scrollen".
     Am Schirm bleibt er stehen, dort kostet er nichts. */
  .co__amaskrumpf .co__gebiet { display: none; }
  .co__amaskfuss {
    margin: 0;
    padding: 0.6rem 1rem;
    /* Der Fuss liegt auf der Kante des Geraets. Ohne diesen Zuschlag klebt
       der Knopf auf iPhones mit Balken auf dem Balken. */
    padding-bottom: calc(0.6rem + env(safe-area-inset-bottom, 0px));
    border-top: var(--rule) solid var(--bone-line);
    background: var(--co-panel);
  }
  .co__amaskfuss .co__err { margin: 0 0 0.7rem; }
  /* Bei offener Tastatur bleibt vom Blatt wenig uebrig - auf dem Geraet
     gemessen rund 350 Pixel, davon nahmen Kopf und Fuss ueber ein Drittel.
     Das Ergebnis war eine Maske, durch die man durch ein Guckloch tippt.
     Also weicht der Fuss, solange getippt wird: der Kaufknopf ist keinen
     Griff weit weg - die Tastatur zugehen lassen genuegt -, der Platz zum
     Ausfuellen dagegen ist genau dann knapp. */
  body.tastatur-auf .co__amaskfuss { display: none; }
  .co__weiter { margin-top: 0; padding-block: 0.8em; }
  /* Solange das Blatt offen ist, scrollt die Seite darunter nicht mit. */
  body.blatt-auf { overflow: hidden; }
}

/* --- Die Anschriftsmaske: neun Felder, alle sichtbar ---------------------
   Vorgabe 21.08.2026 mit Bildschirmfoto: Zeile fuer Zeile wie im Vorbild.

   Die Beschriftung sitzt in der Kerbe der Umrandung: im leeren Feld steht
   sie mittig darin wie ein Platzhalter, beim Tippen rutscht sie hoch auf die
   Linie und deckt sie mit ihrem eigenen Grund ab. Bei neun Feldern
   untereinander bleibt so lesbar, was worin steht, ohne dass ueber jedem
   Kasten eine Zeile Platz kostet.

   `placeholder=" "` an jedem Feld ist die Bedingung dafuer: nur damit greift
   `:placeholder-shown`, und nur daran erkennt die Regel ein leeres Feld. */
.co__pflicht { margin: 0 0 0.5rem; font-size: 0.75rem; color: var(--muted-dark); }
/* Der Abstand muss die hochgerutschte Beschriftung tragen. Sie sitzt auf der
   Oberkante des Feldes und ragt um ihre halbe Hoehe darueber hinaus - bei zu
   engem Abstand beruehrt sie das Feld darueber, sobald etwas eingetragen
   ist. Am Auswahlfeld "Land" faellt es zuerst auf, weil dessen Beschriftung
   immer oben steht; gefuellt gilt es fuer alle. */
.co__adrfelder { display: grid; gap: 0.5rem; }
/* Zwei Felder in einer Zeile: Vor- und Nachname haelftig, Postleitzahl und
   Ort im Verhaeltnis der Sache - eine PLZ ist fuenf Zeichen lang, ein
   Ortsname selten. */
.fld-reihe { display: grid; grid-template-columns: 1fr 1fr; gap: 0.4rem; }
.fld-reihe--ort { grid-template-columns: 0.62fr 1fr; }

.fld { position: relative; margin: 0; }
.fld input, .fld select {
  width: 100%;
  font-family: var(--f-sans);
  /* 16px, sonst zoomt Safari beim Antippen. */
  font-size: 16px;
  line-height: 1.2;
  color: var(--ink);
  background: transparent;
  border: var(--rule) solid rgba(13, 26, 47, 0.3);
  border-radius: 0.3rem;
  /* Enger gesetzt, damit die Maske auf dem Telefon ohne Scrollen auskommt -
     Vorgabe 21.08.2026. Gespart wird am Polster, NICHT an der Schrift:
     `font-size` bleibt bei 16 Pixeln. Darunter vergroessert Safari die
     ganze Seite, sobald ein Feld angetippt wird, und genau das war die
     allererste Beanstandung des Tages. Wer hier kleiner setzt, holt sie
     zurueck. */
  padding: 0.58rem 0.8rem;
  -webkit-appearance: none;
  appearance: none;
  transition: border-color 0.35s var(--ease);
}
.fld input:focus, .fld select:focus { outline: none; border-color: var(--gold); }
/* Rot erst, nachdem jemand abgeschickt hat - nicht beim Oeffnen der Seite. */
.co__adrfelder.is-geprueft input:invalid,
.co__adrfelder.is-geprueft select:invalid { border-color: #a3283a; }

/* Die Beschriftung liegt IM Feld. `.co__pay label` setzt projektweit
   `display: block` und eine eigene Groesse - beide Selektoren sind gleich
   spezifisch, diese Regeln stehen spaeter und gewinnen deshalb. Wer sie
   verschiebt, bekommt neun Beschriftungen unter statt in den Feldern;
   genau das ist am 21.08.2026 einmal passiert. */
.co .co__pay .fld label {
  position: absolute;
  left: 0.6rem;
  top: 50%;
  transform: translateY(-50%);
  margin: 0;
  padding-inline: 0.25rem;
  font-size: 16px;
  line-height: 1;
  text-transform: none;
  letter-spacing: 0.01em;
  color: var(--muted-dark);
  pointer-events: none;
  transition: top 0.18s var(--ease), font-size 0.18s var(--ease),
              color 0.18s var(--ease);
}
/* Hoch auf die Linie, sobald etwas drinsteht oder das Feld dran ist. Der
   eigene Grund deckt die Umrandung darunter ab - das ist die Kerbe. */
.co .co__pay .fld input:focus + label,
.co .co__pay .fld input:not(:placeholder-shown) + label,
.co .co__pay .fld select + label {
  top: 0;
  font-size: 0.72rem;
  background: var(--paper);
}
.co .co__pay .fld input:focus + label { color: var(--gold); }

/* Die Beschriftung deckt die Umrandung unter sich ab - dafuer muss ihr Grund
   der Grund der Flaeche sein, auf der sie liegt. Am Schirm ist das der Ton
   des Schrittes (--paper), im Blatt auf dem Telefon der des Blattes
   (--co-panel).

   Diese Regel MUSS hinter der Grundregel stehen und eine Klasse mehr tragen.
   Stand sie vorher im Medienblock weiter oben, gewann die spaetere Regel mit
   gleicher Spezifitaet - und hinter "Land" lag ein hellerer Fleck quer auf
   der Linie. Gesehen am 21.08.2026. */
@media (max-width: 860px) {
  .co .co__pay .co__anschrift .fld input:focus + label,
  .co .co__pay .co__anschrift .fld input:not(:placeholder-shown) + label,
  .co .co__pay .co__anschrift .fld select + label { background: var(--co-panel); }
}

/* Das Auswahlfeld traegt seine Beschriftung immer oben - es ist nie leer.
   Der Pfeil muss von Hand kommen, `appearance: none` nimmt den nativen. */
.fld--wahl select {
  padding-right: 2.2rem;
  cursor: pointer;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2012%208'%3E%3Cpath%20d='M1%201.5%206%206.5l5-5'%20fill='none'%20stroke='%230d1a2f'%20stroke-width='1.4'%20stroke-linecap='round'%20stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  background-size: 0.7rem;
}

/* Die Lupe an der Strassenzeile erscheint nur, wenn es die
   Vervollstaendigung wirklich gibt - js/main.js setzt das Merkmal, sobald
   Google Places geladen ist. Ein Sinnbild fuer eine Funktion, die nicht da
   ist, ist eine Luege aus Blech. */
.fld--suche[data-suche="1"] input { padding-left: 2.6rem; }
.co .co__pay .fld--suche[data-suche="1"] label { left: 2.35rem; }
.fld--suche[data-suche="1"]::before {
  content: "";
  position: absolute;
  left: 0.95rem;
  top: 50%;
  width: 1.05rem;
  height: 1.05rem;
  transform: translateY(-50%);
  background: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2020%2020'%3E%3Ccircle%20cx='8.5'%20cy='8.5'%20r='5.5'%20fill='none'%20stroke='%230d1a2f'%20stroke-width='1.6'/%3E%3Cpath%20d='M12.8%2012.8%2017%2017'%20fill='none'%20stroke='%230d1a2f'%20stroke-width='1.6'%20stroke-linecap='round'/%3E%3C/svg%3E") no-repeat center / contain;
  pointer-events: none;
}

/* Die Vorschlagsliste unter der Strassenzeile. */
/* Die Vorschlagsliste liegt FEST im Fenster, nicht im Feld.

   Sie lag bis zum 21.08.2026 `absolute` am Feld - und war damit unsichtbar,
   sobald es darauf ankam: der Rumpf des Blattes scrollt (`overflow-y: auto`)
   und der Kasten darum schneidet ab (`overflow: hidden`). Bei offener
   Tastatur steht das Strassenfeld ganz unten im geschrumpften Rumpf, die
   Liste erscheint darunter - also ausserhalb. Gemeldet vom Geraet mit
   Bildschirmfoto: "keine Adressenvorschlaege". Sie waren da, nur
   abgeschnitten.

   Ort und Breite setzt js/main.js aus der Lage des Feldes, jedes Mal neu.
   Passt sie unten nicht mehr, klappt sie nach oben. */
.co__vorschlaege {
  position: fixed;
  z-index: 95;
  margin: 0;
  background: var(--co-card);
  border: var(--rule) solid rgba(13, 26, 47, 0.3);
  border-radius: 0.3rem;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(13, 26, 47, 0.14);
}
.co__vorschlaege:empty { display: none; }
.co__vorschlag {
  display: block;
  width: 100%;
  text-align: left;
  padding: 0.7rem 0.85rem;
  font-size: 0.92rem;
  border-bottom: var(--rule) solid var(--bone-line);
}
.co__vorschlag:last-child { border-bottom: 0; }
.co__vorschlag:hover, .co__vorschlag.is-an { background: var(--co-panel); }
.co__anschrift[hidden] { display: none; }
.co__anschrift .co__gebiet { margin: 1rem 0 0; }
.co__weiter { width: 100%; justify-content: center; margin-top: 1.2rem; }
.co__karte[hidden] { display: none; }

/* Die Pflichtangaben nach § 312j BGB stehen unmittelbar ueber dem
   Kaufknopf - jetzt im Schritt, nicht mehr im Fuss eines Blattes. */
.co__duty {
  margin-top: 1.2rem;
  padding: 0.65rem 0.8rem;
  background: var(--co-card);
  border: var(--rule) solid var(--bone-line);
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted-dark);
}
.co__duty:empty { display: none; }

/* --- Am Telefon ohne Rahmen ----------------------------------------------
   Vorgabe 21.08.2026 mit Bildschirmfoto: die beiden Kaesten im
   Zahlungsschritt weg.

   Gemeint sind der Rahmen um den ganzen Schritt und der um die
   Pflichtangaben darin. Beide tragen denselben Grund wie die Seite - sie
   umrandeten also nichts, sie zogen nur Linien. Am Schirm ist das anders:
   dort steht der Schritt neben der Bestellung, und der Rahmen sagt, wo das
   eine aufhoert und das andere anfaengt. Auf dem Telefon steht ohnehin
   alles untereinander.

   Die Zahlungsarten behalten ihre Kaesten. Die sind eine Auswahl, keine
   Umrandung. */
@media (max-width: 860px) {
  /* `.co` davor, sonst gewinnt die Regel im Block fuer flache Bildschirme
     (`.co .co__stepbody { padding: 1.1rem 1.3rem }`) mit ihrer hoeheren
     Spezifitaet - Rahmen und Grund waren weg, das seitliche Polster von
     20,8 Pixeln blieb. Gemessen live am 21.08.2026. Vierte Stelle heute
     mit demselben Muster. */
  .co .co__stepbody {
    border: 0;
    background: none;
    padding-inline: 0;
    padding-block: 0;
    margin-top: 0.7rem;
  }
  /* Und die beiden Zusammenfassungen der erledigten Schritte - DAS waren
     die zwei Kaesten, die gemeint waren.

     Ich hatte am 21.08.2026 zuerst die falschen entfernt: den Rahmen um den
     Zahlungsschritt und den um die Pflichtangaben. Gemeint waren die Kaesten
     um "Lieferung nach Hause / Name / Anschrift" und um "Standardversand".
     Gesehen habe ich es erst, als ich die Live-Seite abgelichtet habe statt
     nur die errechneten Stile abzufragen - die sagten "Rahmen 0" fuer die
     Kaesten, die ich mir ausgesucht hatte, und schwiegen ueber die anderen.

     Am Schirm bleiben sie: dort sind die Schritte Karten, und die
     Zusammenfassung sitzt darin ohne eigenen Rahmen. */
  .co .co__karte--ruhig {
    background: none;
    border: 0;
    padding: 0;
  }
  .co__duty {
    border: 0;
    background: none;
    padding-inline: 0;
  }
  /* Ohne Rahmen braucht die Karte im ersten Schritt eine eigene Kante,
     sonst schwebt die Lieferart im Nichts. */
  .co__karte--wahl { padding-block: 0.2rem; }
}

/* Die Wahl der Versandart traegt die Farbe des Hauses, nicht das Blau des
   Browsers. */
.co__opt input[type="radio"], .co .field--check input[type="checkbox"] {
  accent-color: var(--ink);
}

/* --- Die Bestellung, zugeklappt ------------------------------------------
   Am Schirm ist der Kopf kein Knopf, sondern eine Ueberschrift: er hat dann
   keinen Zeiger, keinen Pfeil und faengt keine Beruehrung ab. Auf dem
   Telefon ist er beides - Zeile mit Betrag und Schalter.                 */
.co__sidekopf {
  display: flex;
  align-items: baseline;
  gap: 0.7rem;
  width: 100%;
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: default;
  pointer-events: none;
}
.co__sidekopf .co__h { flex: 1 1 auto; }
.co__sidesumme { display: none; }
.co__sidepfeil { display: none; }
.co__sidebody[hidden] { display: none; }

@media (max-width: 860px) {
  .co__sidekopf { cursor: pointer; pointer-events: auto; padding-block: 0.2rem; }
  .co__sidesumme {
    display: block;
    font-family: var(--f-display);
    font-size: 1.1rem;
    white-space: nowrap;
  }
  .co__sidepfeil {
    display: block;
    flex: none;
    width: 0.62rem;
    height: 0.62rem;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
    transition: transform 0.4s var(--ease);
  }
  .co__sidekopf[aria-expanded="true"] .co__sidepfeil { transform: rotate(180deg); }
  .co__sidebody { margin-top: 1.2rem; }
  /* Auf dem Telefon steht die Bestellung dicht unter den Schritten - der
     grosse Abstand des Rasters daneben waere hier eine Luecke. */
  .co__grid { gap: 1.4rem; }
}

/* Auf dem Telefon zaehlt jede Zeile: die Ueberschrift der Kasse steht
   knapper ueber dem ersten Schritt, und die Sektion beginnt frueher. */
@media (max-width: 640px) {
  .section--tight:has(.co) { padding-top: 1.6rem; padding-bottom: 2rem; }
  .co h1 { font-size: clamp(1.9rem, 9vw, 2.4rem); margin-bottom: 1rem; }
}

/* Weniger Bewegung: die Kaufleiste erscheint ohne Nachlauf. */
@media (prefers-reduced-motion: reduce) {
  .stickybar { transition-delay: 0s !important; }
}
