/* ═══════════════════════════════════════════════════════════════
   UMBRELLA ARMORY · LANDING PAGE
   Design-Sprache übernommen aus dem Storefront-Prototyp
   (count-app/design/proto/assets/tokens.css)
   ─────────────────────────────────────────────────────────────── */

:root {
  /* Surfaces */
  --ink:            #0d0d0e;
  /* Echtes Schwarz. Nur dort, wo eine Aufnahme auf #000 steht: #0d0d0e
     ist dann als hellerer Rahmen um das Motiv sichtbar. */
  --ink-true:       #000000;
  --ink-2:          #18181a;
  --ink-3:          #222224;
  --surface:        #ffffff;
  --bg:             #f1f1f1;
  --bg-alt:         #e7e6e6;

  /* Text */
  --text:           #2e2b28;
  --text-2:         #57534e;
  --text-mute:      #777270;
  --text-faint:     #a39e9b;
  --on-dark:        #ffffff;
  --on-dark-2:      #cccccc;
  --on-dark-mute:   #898684;

  /* Lines */
  --line:           #dedcd9;
  --line-strong:    #c5c2bf;
  --line-dark:      #2d2d2d;
  --line-dark-2:    #3a3a3a;

  /* Signal — bewusst auf ein Minimum reduziert: die Seite trägt Schwarz,
     Grau und Off-White. Das Marken-Orange erscheint nur noch dort, wo es
     eine Funktion hat: Fokus-Ringe (Tastaturbedienung) und das
     "Neu"-Badge. Für Hover, Flächen und Fließtext NICHT verwenden. */
  --signal:         #ff5b1f;

  --success:        #16a34a;

  /* Type */
  --ff-display: 'Orbitron', -apple-system, BlinkMacSystemFont, sans-serif;
  --ff-body:    'Barlow', -apple-system, BlinkMacSystemFont, sans-serif;
  --ff-mono:    'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  --ls-wide:    0.08em;
  --ls-widest:  0.18em;

  /* Space */
  --s-2: .5rem;  --s-3: .75rem; --s-4: 1rem;   --s-5: 1.25rem;
  --s-6: 1.5rem; --s-8: 2rem;   --s-10: 2.5rem; --s-12: 3rem;
  --s-16: 4rem;  --s-20: 5rem;  --s-24: 6rem;

  --r-2: 2px; --r-4: 4px; --r-8: 8px; --r-14: 14px;

  --maxw: 1280px;
  /* Seitenrand: der Abstand, auf dem der Inhalt ALLER Sektionen links
     und rechts steht — Ticker, Hero, Produktbereiche, Rails, Trust,
     CTA, Footer und Rechtsseiten. Auch die schwebende Kopfleiste setzt
     ihre Außenkante auf diese Linie. */
  --gutter: 40px;
  --ease: cubic-bezier(.2, .7, .3, 1);
  --t: 180ms;
  /* Der Wechsel der Kopfleiste läuft über eine ganze Fläche — mit 180 ms
     wirkt das abgehackt statt eingeblendet. */
  --t-hdr: 280ms;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--ff-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; display: block; }

a { color: inherit; }

h1, h2, h3 {
  font-family: var(--ff-display);
  font-weight: 800;
  line-height: 1.02;
  letter-spacing: -0.01em;
  margin: 0;
  text-transform: uppercase;
}

/* Orbitron trägt die Hausnummern — Hero und Sektionstitel. Auf der
   dritten Ebene (Produktnamen, Footer-Titel) wird sie eng und laut;
   dort steht die Grotesk. */
h3 {
  font-family: var(--ff-body);
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0;
}

/* Orbitron gibt es nur als latin-Subset — Diakritika wie Ł, ř, ő oder ș
   fielen in Überschriften zeichenweise auf die Systemschrift zurück und
   ergäben Buchstabensalat. Sprachen, deren Titel latin-ext brauchen,
   tragen sie deshalb geschlossen in der Grotesk (Barlow führt latin-ext).
   Die Liste kommt aus dem Glyphen-Audit über die gebauten Seiten; nach
   neuen Sprachen oder Textänderungen neu prüfen. da/et/fi/is/no/pt/sv
   kommen mit latin-1 aus und behalten Orbitron. */
:lang(cs) h1, :lang(cs) h2, :lang(hr) h1, :lang(hr) h2,
:lang(hu) h1, :lang(hu) h2, :lang(lt) h1, :lang(lt) h2,
:lang(lv) h1, :lang(lv) h2, :lang(pl) h1, :lang(pl) h2,
:lang(ro) h1, :lang(ro) h2, :lang(sk) h1, :lang(sk) h2,
:lang(sl) h1, :lang(sl) h2 {
  font-family: var(--ff-body);
  font-weight: 700;
  letter-spacing: 0;
}

.wrap {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* Utility: eyebrow label ─────────────────────────────────────── */
.eyebrow {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  /* Erbt die Textfarbe der Sektion und wird nur abgedunkelt — so
     funktioniert das Label auf hellem wie auf dunklem Grund, ohne dass
     eine zweite Farbe nötig wäre. */
  color: inherit;
  opacity: .72;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0 0 var(--s-4);
}
.eyebrow::before {
  content: "";
  width: 28px;
  height: 2px;
  background: currentColor;
  flex: none;
}

/* ── Skip link ────────────────────────────────────────────────── */
.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--ink);
  color: #fff;
  padding: var(--s-3) var(--s-5);
  z-index: 100;
  font-weight: 700;
}
.skip:focus { left: 0; }

/* ── Ticker ───────────────────────────────────────────────────── */
.ticker {
  background: var(--surface);
  color: var(--text-mute);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}
.ticker__inner {
  display: flex;
  gap: var(--s-6);
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
}
.ticker span { display: inline-flex; align-items: center; gap: var(--s-2); }
.ticker span::before {
  content: "";
  width: 6px; height: 6px;
  background: var(--line-strong);
  flex: none;
}

/* ── Header (frei schwebend) ──────────────────────────────────── */
/* Der Wrapper ist sticky und NULL Pixel hoch — dadurch beansprucht er
   keinen Platz im Fluss, der Hero beginnt direkt unter dem Ticker und
   die Leiste schwebt über dem gesamten Inhalt. Beim Scrollen bleibt sie
   oben kleben. */
.hdr {
  position: sticky;
  top: 0;
  z-index: 50;
  height: 0;
  /* flow-root verhindert, dass der obere Rand der Leiste aus dem
     nullhohen Wrapper ausbricht und den Hero nach unten schiebt. */
  display: flow-root;
  /* Nur die Leiste selbst soll Klicks abfangen, nicht der leere Streifen. */
  pointer-events: none;

  /* Abstand zwischen Viewportkante und Leiste, solange die Seite ganz oben
     steht — er stammt aus der Zeile über der Leiste. Beim Scrollen dockt die
     Leiste oben an und der Abstand fällt weg. Steht hier und nicht auf
     .hdr__inner, weil die Unschärfebahn daneben liegt und ihn mitrechnet. */
  --hdr-gap: var(--s-4);
  /* Höhe der Leiste — vom Skript gemessen (siehe headerScrollScript). */
  --hdr-bar-h: 0px;
  /* Unschärfe je Ebene der Verlaufsbahn; fünf Ebenen ergeben oben rund
     das Zweieinhalbfache davon. */
  --hdr-blur: 6px;
}

.hdr__inner {
  --hdr-slant: 34px;
  --hdr-radius: 14px;
  --hdr-tip-x: 4px;
  --hdr-tip-y: 8px;
  --hdr-tip-x2: 9px;
  /* Randbreite als Variable, weil die Kontur an der Schräge sie mitrechnen
     muss: die Kante liegt genau eine Randbreite außerhalb der padding-box. */
  --hdr-bw: 1px;

  /* Bezug für die beiden Konturstücke an der geschnittenen Kante. */
  position: relative;
  pointer-events: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-4) var(--s-6);
  /* zusätzlicher Raum rechts, damit der Button nicht in die Schräge läuft */
  padding-right: calc(var(--s-6) + var(--hdr-slant));
  /* Die Außenkante der Leiste liegt auf derselben Linie wie der Inhalt
     der Sektionen: Breite = Inhaltsbreite abzüglich der beiden
     Seitenränder. */
  width: calc(100% - 2 * var(--gutter));
  max-width: calc(var(--maxw) - 2 * var(--gutter));
  margin: var(--hdr-gap) auto 0;

  /* Weißes Glasmaterial: die Leiste bleibt durchlässig, der Inhalt
     dahinter ist als Unschärfe erkennbar. brightness() hellt auf, statt
     nur zu überdecken — über dem dunklen Hero bliebe die Fläche sonst
     mittelgrau und die schwarze Schrift darauf unlesbar. Die Kontur ist
     bewusst nur eine graue Haarlinie. */
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(28px) saturate(120%) brightness(1.25);
  -webkit-backdrop-filter: blur(28px) saturate(120%) brightness(1.25);
  border: var(--hdr-bw) solid var(--line-strong);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 10px 30px rgba(0, 0, 0, .12);

  /* Gewinkelte rechte Kante — clip-path schneidet den border dort weg,
     die Haarlinie an der Schräge kommt deshalb aus eigenen Flächen (unten).
     Fallback ohne shape(): eckige Schräge, border-radius greift dann nicht. */
  border-radius: var(--hdr-radius);
  clip-path: polygon(
    0 0,
    100% 0,
    calc(100% - var(--hdr-slant)) 100%,
    0 100%
  );
}

/* Ohne backdrop-filter gibt es nichts zu verwischen — dann trägt die Fläche
   den Kontrast allein, sonst stünde schwarze Schrift auf dem Hero-Foto. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hdr__inner {
    background: rgba(255, 255, 255, .96);
    border-color: var(--line-strong);
  }
}

/* Abgerundete Variante derselben Form: shape() darf px-Radien mit
   prozentualen Punkten mischen, polygon() kann keine Rundungen.
   --hdr-tip-* sind die Tangentenlängen der schrägen Kante, in x/y zerlegt;
   sie hängen an Schräge und Leistenhöhe und werden je Breakpoint gesetzt. */
@supports (clip-path: shape(from 0 0, line to 100% 100%, close)) {
  .hdr__inner {
    clip-path: shape(
      from var(--hdr-radius) 0,
      hline to calc(100% - var(--hdr-radius)),
      arc to 100% var(--hdr-radius) of var(--hdr-radius) cw,
      line to calc(100% - var(--hdr-slant) + var(--hdr-tip-x))
              calc(100% - var(--hdr-tip-y)),
      arc to calc(100% - var(--hdr-slant) - var(--hdr-tip-x2)) 100%
        of var(--hdr-radius) cw,
      hline to var(--hdr-radius),
      arc to 0 calc(100% - var(--hdr-radius)) of var(--hdr-radius) cw,
      vline to var(--hdr-radius),
      arc to var(--hdr-radius) 0 of var(--hdr-radius) cw,
      close
    );
  }
}

/* ── Haarlinie auf der Schräge ─────────────────────────────────
   Der border läuft rings um die Leiste, an der geschnittenen Kante fällt
   er dem clip-path zum Opfer. Ersatz ist eine Fläche, deren Diagonale von
   oben rechts nach unten links GENAU auf dieser Kante liegt: ein
   linear-gradient "to bottom right" legt seine 50-%-Marke per Definition
   auf die Verbindung der beiden Nachbarecken — also auf die Diagonale.
   Der Farbsprung sitzt eine Randbreite davor, damit die Linie innen liegt
   und außen sauber vom clip-path gekappt wird. */
.hdr__inner::after {
  content: "";
  position: absolute;
  /* Die Offsets zählen ab der padding-box, die Kante liegt eine
     Randbreite weiter außen. */
  top: calc(-1 * var(--hdr-bw));
  right: calc(-1 * var(--hdr-bw));
  bottom: calc(-1 * var(--hdr-bw));
  width: var(--hdr-slant);
  pointer-events: none;
  background: linear-gradient(
    to bottom right,
    transparent calc(50% - var(--hdr-bw)),
    var(--line-strong) calc(50% - var(--hdr-bw)),
    var(--line-strong) 50%,
    transparent 50%
  );
}

@supports (clip-path: shape(from 0 0, line to 100% 100%, close)) {
  /* Mit shape() beginnt die gerade Kante erst unter dem Bogen oben rechts
     und endet vor dem Bogen an der Spitze — die Fläche spannt genau
     zwischen diesen beiden Punkten. */
  .hdr__inner::after {
    top: calc(var(--hdr-radius) - var(--hdr-bw));
    bottom: calc(var(--hdr-tip-y) - var(--hdr-bw));
    width: calc(var(--hdr-slant) - var(--hdr-tip-x));
  }

  /* Der Bogen an der Spitze berührt die Unterkante — sein Mittelpunkt
     liegt also eine Radiuslänge darüber, senkrecht über dem Berührpunkt.
     Ein radial-gradient zeichnet den Kreisrand, das Kästchen zeigt davon
     nur das Stück zwischen den beiden Bogenenden. */
  .hdr__inner::before {
    content: "";
    position: absolute;
    right: calc(var(--hdr-slant) - var(--hdr-tip-x) - var(--hdr-bw));
    bottom: calc(-1 * var(--hdr-bw));
    width: calc(var(--hdr-tip-x) + var(--hdr-tip-x2));
    height: var(--hdr-tip-y);
    pointer-events: none;
    background: radial-gradient(
      circle var(--hdr-radius) at 0 calc(var(--hdr-tip-y) - var(--hdr-radius)),
      transparent calc(var(--hdr-radius) - var(--hdr-bw)),
      var(--line-strong) calc(var(--hdr-radius) - var(--hdr-bw)),
      var(--line-strong) var(--hdr-radius),
      transparent var(--hdr-radius)
    );
  }
}

@media (max-width: 700px) {
  .hdr__inner {
    --hdr-slant: 16px;
    /* flachere Schräge -> kürzere Tangenten an der Spitze */
    --hdr-tip-x: 3px;
    --hdr-tip-y: 10px;
    --hdr-tip-x2: 10px;
    /* Auch schmal bleibt die Außenkante auf dem Seitenrand. */
    width: calc(100% - 2 * var(--gutter));
  }
  .hdr { --hdr-gap: var(--s-3); }
}
/* Die Marke ist das Logo selbst — der Link ist nur noch sein Rahmen.
   Der Container ist ein Grid statt einer Zeile: das entfernt den
   Zeilenabstand unter dem Bild (sonst sitzt die Leiste ein paar Pixel
   schief) und legt beide Logofassungen ins selbe Feld. */
.hdr__brand {
  display: grid;
  align-items: center;
  justify-items: start;
  flex: none;
  text-decoration: none;
}
.hdr__brand img {
  grid-area: 1 / 1;
  display: block;
  height: 40px;
  width: auto;
  transition: opacity var(--t-hdr) var(--ease);
}
/* Ohne durchsichtige Leiste steht nur das dunkle Logo im Markup — die weiße
   Fassung ist bis zum Zustandswechsel unsichtbar. */
.hdr__logo--light { opacity: 0; }
.hdr__nav {
  display: none;
  gap: var(--s-5);
  font-family: var(--ff-mono);
  font-size: .75rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  /* Umbruch innerhalb eines Menüpunkts sieht nach Fehler aus —
     lieber das ganze Menü ausblenden, siehe Breakpoint unten. */
  white-space: nowrap;
}
.hdr__nav a {
  color: var(--text);
  text-decoration: none;
  transition: color var(--t) var(--ease);
}
.hdr__nav a:hover { color: var(--ink); }
/* Ab 900px passen die Kurzformen der Menüpunkte neben Sprachwahl und
   Shop-Knopf, ohne umzubrechen — dieselbe Schwelle, ab der der Burger
   verschwindet (siehe .hdr__menuBtn). Darunter bleibt der Burger die
   einzige Navigation. */
@media (min-width: 900px) { .hdr__nav { display: flex; } }

/* Auf schmalen Screens muss der Header-Block schrumpfen dürfen, sonst
   schiebt der nowrap-Button die Zeile über den Viewport hinaus.
   Wichtig: padding NICHT als Kurzform setzen — das würde die rechte
   Freihaltung für die Schräge überschreiben und den Button anschneiden. */
@media (max-width: 560px) {
  .hdr__inner {
    gap: 6px;
    padding-top: var(--s-3);
    padding-bottom: var(--s-3);
    /* Einzige Ausnahme vom 40-px-Rand: Logo, Sprachwahl, Shop-Knopf und
       Menü brauchen zusammen mehr als die dann verbleibenden ~310 px.
       Unterhalb von 560 px rückt die Leiste deshalb näher an den Rand;
       die Sektionen darunter bleiben auf der 40-px-Linie. */
    width: calc(100% - 2 * var(--s-4));
    padding-left: var(--s-3);
    padding-right: calc(var(--s-2) + var(--hdr-slant));
  }
  .hdr__brand img { height: 26px; }
  .hdr .btn { padding: var(--s-2) var(--s-3); font-size: .625rem; }
  .langsw { font-size: .6875rem; }
  .langsw a { padding: 3px 4px; }
  .ticker { padding: var(--s-2) 0; }
  .ticker__inner { gap: var(--s-3); }
  .ticker span:nth-child(3) { display: none; }
}

.hdr__right {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  flex: none;
}

/* ── Kopfleiste über dem Hero ─────────────────────────────────────
   Auf der Startseite trägt die Leiste `.hdr--ghost`. Sie hat dort gar keine
   eigene Fläche mehr: keine Füllung, keine Kontur, keinen Schatten. Was den
   Inhalt beim Scrollen lesbar hält, ist die Verlaufsunschärfe darunter
   (siehe nächster Block).

   Der Zustand hängt an der `.js`-Klasse des Dokuments: ohne Skript gäbe es
   nichts, was die Bahn je einblendet — die Leiste stünde ohne Grund da. Ohne
   JS bleibt deshalb die gefüllte Glasleiste, wie sie die Rechtsseiten tragen. */
.js .hdr--ghost .hdr__inner {
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  border-color: transparent;
  box-shadow: none;
}
/* Die beiden Konturstücke an der Schräge gehören zur Kontur und fallen mit
   ihr weg — ohne Fläche gäbe es nichts, was sie umranden. */
.js .hdr--ghost .hdr__inner::before,
.js .hdr--ghost .hdr__inner::after { display: none; }

/* ── Verlaufsunschärfe unter der Kopfleiste ──────────────────────
   Eine Bahn über die volle Viewportbreite, vom oberen Rand bis zur Unterkante
   der Leiste. Sie verwischt, was darunter durchläuft: an der Unterkante gar
   nicht, nach oben hin immer stärker.

   Ein einzelner backdrop-filter kann keinen Verlauf. Deshalb fünf
   deckungsgleiche Ebenen: jede verwischt das Ergebnis der darunter liegenden
   ein weiteres Mal und wird per Maske erst ab ihrer eigenen Höhe sichtbar.
   Ganz unten greift keine einzige, ganz oben alle fünf. */
.hdr__blur {
  position: absolute;
  top: 0;
  /* .hdr ist selbst so breit wie der Viewport — links/rechts auf 0 statt
     100vw, damit die Bahn keinen waagrechten Scrollbalken erzeugen kann. */
  left: 0;
  right: 0;
  /* Die Höhe der Leiste steht nicht fest (Logo, Knopf und Breakpoint
     bestimmen sie), das Skript misst sie in --hdr-bar-h. */
  height: calc(var(--hdr-gap) + var(--hdr-bar-h));
  /* Sie schrumpft mit, wenn die Leiste beim Scrollen oben andockt. */
  transition: height var(--t-hdr) var(--ease);
}

/* Weiße Fläche über den Unschärfe-Ebenen. Sie MUSS über ihnen liegen: ein
   Hintergrund auf .hdr__blur würde vor den Ebenen gezeichnet, die würden dann
   das Weiß verwischen statt den Seiteninhalt. ::after zählt als letztes Kind
   und wird deshalb zuletzt gezeichnet.

   Durchgehend gleich deckend und mit fester Unterkante: die Bahn ist genau so
   hoch wie die Leiste, der Inhalt sitzt also mit demselben Abstand nach oben
   wie nach unten darin. Nicht ganz deckend, damit die Unschärfe darunter noch
   durchkommt — der Verlauf steckt allein in ihr. */
.hdr__blur::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, .86);
  opacity: 0;
  transition: opacity var(--t-hdr) var(--ease);
}
.hdr__blur i {
  position: absolute;
  inset: 0;
  /* Ruhezustand ausdrücklich blur(0) statt none: nur zwischen zwei echten
     Filterlisten läuft der Übergang zuverlässig weich. */
  backdrop-filter: blur(0px);
  -webkit-backdrop-filter: blur(0px);
  transition:
    backdrop-filter var(--t-hdr) var(--ease),
    -webkit-backdrop-filter var(--t-hdr) var(--ease);
}
/* Jede Ebene blendet über ein Fünftel der Bahnhöhe ein und bleibt darüber
   voll wirksam — die Summe ergibt den stetigen Verlauf nach oben. */
.hdr__blur i:nth-child(1) {
  -webkit-mask-image: linear-gradient(to top, transparent 0%, #000 20%);
          mask-image: linear-gradient(to top, transparent 0%, #000 20%);
}
.hdr__blur i:nth-child(2) {
  -webkit-mask-image: linear-gradient(to top, transparent 20%, #000 40%);
          mask-image: linear-gradient(to top, transparent 20%, #000 40%);
}
.hdr__blur i:nth-child(3) {
  -webkit-mask-image: linear-gradient(to top, transparent 40%, #000 60%);
          mask-image: linear-gradient(to top, transparent 40%, #000 60%);
}
.hdr__blur i:nth-child(4) {
  -webkit-mask-image: linear-gradient(to top, transparent 60%, #000 80%);
          mask-image: linear-gradient(to top, transparent 60%, #000 80%);
}
.hdr__blur i:nth-child(5) {
  -webkit-mask-image: linear-gradient(to top, transparent 80%, #000 100%);
          mask-image: linear-gradient(to top, transparent 80%, #000 100%);
}
.js .hdr--ghost.is-scrolled .hdr__blur i {
  backdrop-filter: blur(var(--hdr-blur));
  -webkit-backdrop-filter: blur(var(--hdr-blur));
}
.js .hdr--ghost.is-scrolled .hdr__blur::after { opacity: 1; }

/* Angedockt: der Abstand aus der Zeile darüber fällt weg, die Leiste rückt an
   die Viewportkante und die Bahn wird um genau diesen Abstand kürzer. */
.hdr--ghost .hdr__inner { transition: margin-top var(--t-hdr) var(--ease); }
.js .hdr--ghost.is-scrolled .hdr__inner { margin-top: 0; }
.js .hdr--ghost.is-scrolled .hdr__blur { height: var(--hdr-bar-h); }

/* Ohne backdrop-filter gibt es nichts zu verwischen — dann trägt die weiße
   Fläche den Kontrast allein und deckt dafür etwas mehr. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .hdr__blur::after { background: rgba(255, 255, 255, .97); }
}

/* Logowechsel: oben die weiße Fassung, ab dem Scrollen wieder die dunkle. */
.js .hdr--ghost:not(.is-scrolled) .hdr__logo--dark { opacity: 0; }
.js .hdr--ghost:not(.is-scrolled) .hdr__logo--light { opacity: 1; }

/* Inhalte im durchsichtigen Zustand. Der Textschatten ist die Rückversicherung
   gegen helle Stellen des Fotos — der Scrim dunkelt den Kopfbereich zwar ab,
   trägt aber bei extremen Seitenverhältnissen nicht überall gleich weit. */
.js .hdr--ghost:not(.is-scrolled) .hdr__nav a,
.js .hdr--ghost:not(.is-scrolled) .langsw a {
  color: rgba(255, 255, 255, .88);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .55);
}
.js .hdr--ghost:not(.is-scrolled) .hdr__nav a:hover,
.js .hdr--ghost:not(.is-scrolled) .langsw a:hover { color: #fff; }
.js .hdr--ghost:not(.is-scrolled) .langsw a:hover {
  border-color: rgba(255, 255, 255, .6);
}
.js .hdr--ghost:not(.is-scrolled) .hdr__logo--light {
  filter: drop-shadow(0 1px 10px rgba(0, 0, 0, .45));
}

/* Der Shop-Knopf bleibt eine gefüllte Fläche, nur eben andersherum: weiß auf
   dem Foto statt schwarz auf dem Glas. Ein Umriss allein stünde über hellen
   Bildstellen zu schwach da — der Knopf ist die einzige Handlung der Leiste. */
.hdr--ghost .btn {
  transition:
    background var(--t) var(--ease),
    color var(--t) var(--ease),
    border-color var(--t) var(--ease),
    box-shadow var(--t) var(--ease),
    transform var(--t) var(--ease);
}
.js .hdr--ghost:not(.is-scrolled) .btn {
  background: #fff;
  color: var(--ink);
  border-color: #fff;
  box-shadow: 0 2px 18px rgba(0, 0, 0, .28);
}
.js .hdr--ghost:not(.is-scrolled) .btn:hover {
  background: rgba(255, 255, 255, .86);
  border-color: rgba(255, 255, 255, .86);
}

/* Burger: Umriss und Balken in Weiß. */
.js .hdr--ghost:not(.is-scrolled) .hdr__menuBtn {
  color: #fff;
  border-color: rgba(255, 255, 255, .55);
}
.js .hdr--ghost:not(.is-scrolled) .hdr__menuBtn:hover {
  color: #fff;
  border-color: #fff;
}

/* ── Sprachumschalter ─────────────────────────────────────────── */
/* Nur noch der No-JS-Fallback: mit Skript ersetzt ihn der Standortknopf.
   Sechs Sprachlinks dürfen deshalb umbrechen, statt auf schmalen Screens
   die Leiste zu sprengen — die Leiste wächst dann eben in die Höhe. */
.langsw {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--s-2);
  font-family: var(--ff-mono);
  font-size: .75rem;
  letter-spacing: var(--ls-wide);
}
.langsw a {
  /* --text-mute käme auf der leicht getönten Glasleiste nur auf 4,3:1 */
  color: var(--text-2);
  text-decoration: none;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: var(--r-2);
  transition: color var(--t) var(--ease), border-color var(--t) var(--ease);
}
/* Muss nach der display-Regel oben stehen: sobald das Skript den
   Standortknopf aufdeckt, blendet es die Links per hidden aus — ein
   gesetztes display schlaegt das Attribut sonst. */
.langsw[hidden] { display: none; }
.langsw a:hover { color: var(--ink); border-color: var(--line-strong); }
.langsw a:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ── Standort und Sprache ─────────────────────────────────────────
   Der Knopf in der Kopfleiste ("AT | DE") und der Dialog dahinter. Der
   Knopf steht erst da, wenn das Skript ihn aufdeckt — bis dahin trägt der
   Sprachumschalter darüber die Sprachwahl allein (siehe build.mjs). */
.locsw { display: flex; align-items: center; }

.locsw__trigger {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px;
  background: rgba(0, 0, 0, .05);
  border: 1px solid transparent;
  border-radius: 999px;
  color: var(--text-2);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  line-height: 1;
  cursor: pointer;
  white-space: nowrap;
  transition:
    color var(--t) var(--ease),
    background var(--t) var(--ease),
    border-color var(--t) var(--ease);
}
.locsw__trigger[hidden] { display: none; }
.locsw__trigger:hover { color: var(--ink); background: rgba(0, 0, 0, .08); }
.locsw__trigger:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.locsw__pin { width: 14px; height: 14px; flex: none; }
.locsw__sep { color: var(--text-faint); margin: 0 1px; }

/* Über dem Hero steht die Leiste auf dem Foto: dieselbe Pille in Weiß,
   passend zu Navigation und Shop-Knopf daneben. */
.js .hdr--ghost:not(.is-scrolled) .locsw__trigger {
  color: rgba(255, 255, 255, .92);
  background: rgba(255, 255, 255, .14);
  border-color: rgba(255, 255, 255, .35);
  text-shadow: 0 1px 10px rgba(0, 0, 0, .55);
}
.js .hdr--ghost:not(.is-scrolled) .locsw__trigger:hover {
  color: #fff;
  background: rgba(255, 255, 255, .24);
  border-color: rgba(255, 255, 255, .6);
}
.js .hdr--ghost:not(.is-scrolled) .locsw__sep { color: rgba(255, 255, 255, .6); }

@media (max-width: 560px) {
  .locsw__trigger { padding: 4px 7px; gap: 4px; font-size: .625rem; }
  .locsw__pin { width: 12px; height: 12px; }
}

/* ── Dialog ─────────────────────────────────────────────────────── */
.loc {
  position: fixed;
  inset: 0;
  /* Über dem Drilldown-Menü (120): der Knopf sitzt in der Kopfleiste, und
     die darf den Dialog nicht überdecken. */
  z-index: 130;
  display: grid;
  place-items: center;
  padding: var(--s-4);
}
/* Muss NACH der display-Regel stehen, sonst gewinnt display über hidden. */
.loc[hidden] { display: none; }

.loc__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .55);
  backdrop-filter: blur(3px);
}
.loc__panel {
  position: relative;
  z-index: 1;
  width: min(600px, 100%);
  max-height: 88svh;
  overflow-y: auto;
  padding: var(--s-8);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-14);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .4);
}
.loc__title {
  font-size: 1.125rem;
  /* Platz für den Schließen-Knopf in derselben Zeile. */
  padding-right: calc(36px + var(--s-3));
}
.loc__lead {
  margin: var(--s-3) 0 var(--s-4);
  color: var(--text-2);
  font-size: .875rem;
}
.loc__close {
  position: absolute;
  top: var(--s-4);
  right: var(--s-4);
  z-index: 2;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-2);
}
.loc__close:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.loc__close:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.loc__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Der aktuelle Standort steht auf eigener Fläche — er ist die Antwort auf
   "wo stehe ich gerade", nicht der erste Eintrag der Auswahl. */
.loc__list--current {
  padding: var(--s-2) var(--s-4);
  background: var(--bg);
  border-radius: var(--r-8);
}

.loc__group { margin-top: var(--s-6); border-top: 1px solid var(--line); }
.loc__groupHead { margin: 0; }
.loc__groupHead button {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  width: 100%;
  padding: var(--s-5) 0 var(--s-4);
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--ink);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
}
.loc__groupHead button:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.loc__chevron {
  width: 18px;
  height: 18px;
  flex: none;
  color: var(--text-mute);
  transition: transform var(--t) var(--ease);
}
.loc__groupHead button[aria-expanded="false"] .loc__chevron { transform: rotate(180deg); }

.loc__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--s-3);
  padding: 2px 0;
}
.loc__pick {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  /* Der Einzug des Knopfes läuft nach links aus dem Text heraus, damit die
     Namen aller Zeilen auf einer Kante stehen. */
  margin-left: -6px;
  padding: 6px;
  background: none;
  border: 0;
  border-radius: var(--r-4);
  cursor: pointer;
  color: var(--text);
  font-family: var(--ff-body);
  font-size: .9375rem;
  font-weight: 600;
  text-align: left;
  transition: background var(--t) var(--ease), color var(--t) var(--ease);
}
.loc__pick:hover { background: rgba(0, 0, 0, .05); color: var(--ink); }
.loc__pick:focus-visible { outline: 2px solid var(--signal); outline-offset: 1px; }
.loc__pin {
  width: 15px;
  height: 15px;
  flex: none;
  color: var(--text-faint);
}
.loc__name { min-width: 0; }
.loc__row.is-current .loc__pick { color: var(--ink); font-weight: 700; }
.loc__row.is-current .loc__pin { color: var(--ink); }

.loc__langs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-5);
  justify-content: flex-end;
}
.loc__lang {
  padding: 6px 2px;
  color: var(--text-2);
  font-size: .875rem;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: var(--line-strong);
  transition: color var(--t) var(--ease), text-decoration-color var(--t) var(--ease);
}
.loc__lang:hover { color: var(--ink); text-decoration-color: var(--ink); }
.loc__lang:focus-visible { outline: 2px solid var(--signal); outline-offset: 1px; }
/* Die Sprache, in der die Seite gerade steht — nur in der Zeile des
   aktuellen Standorts gesetzt. */
.loc__lang[aria-current] {
  color: var(--ink);
  font-weight: 700;
  text-decoration-color: var(--ink);
  text-decoration-thickness: 2px;
}

@media (max-width: 560px) {
  .loc__panel { padding: var(--s-6) var(--s-5); }
  .loc__title { font-size: 1rem; }
  .loc__list--current { padding: var(--s-2) var(--s-3); }
  /* Zu schmal für zwei Spalten: die Sprachen rücken unter den Ort und
     fluchten mit dessen Namen. */
  .loc__row {
    grid-template-columns: 1fr;
    gap: 0;
    padding: var(--s-2) 0;
  }
  .loc__langs { justify-content: flex-start; padding-left: calc(15px + var(--s-2)); }
}

/* ── Buttons ──────────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-6);
  /* Alle .btn stehen auf hellem Grund (Kopfleiste, Partnerband,
     CTA-Band) — deshalb dunkle Fläche mit heller Schrift. */
  background: var(--ink);
  color: var(--surface);
  font-family: var(--ff-mono);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-decoration: none;
  border: 1px solid var(--ink);
  border-radius: var(--r-2);
  transition: background var(--t) var(--ease), transform var(--t) var(--ease);
  white-space: nowrap;
}
.btn:hover { background: var(--ink-3); border-color: var(--ink-3); transform: translateY(-1px); }
.btn--lg { padding: var(--s-4) var(--s-8); font-size: .8125rem; }
/* Umrissvariante für dunkle Flächen — dort trägt die dunkle Standardfläche
   keinen Kontrast mehr. */
.btn--ghost {
  background: transparent;
  color: var(--on-dark);
  border-color: rgba(255, 255, 255, .45);
}
.btn--ghost:hover {
  background: var(--on-dark);
  border-color: var(--on-dark);
  color: var(--ink);
}

/* ── Hero ─────────────────────────────────────────────────────── */
.hero {
  background: var(--ink);
  color: var(--on-dark);
  position: relative;
  overflow: hidden;
  /* Die Kopfleiste schwebt über dem Hero (height:0), der obere Innenabstand
     muss sie daher selbst freihalten. Die Höhe ist bewusst knapp gehalten:
     die Folgesektion soll ohne Scrollen angeschnitten sichtbar sein. */
  /* unten zusätzlich Platz für die absolut sitzende Steuerleiste:
     --hero-foot ist ihre Bauhöhe plus Abstand zur Headline. */
  --hero-foot: 7rem;
  padding: var(--s-24) 0 var(--hero-foot);
  display: flex;
  align-items: center;
  min-height: 56svh;
}
@media (min-width: 900px) {
  .hero {
    /* oben: Höhe der schwebenden Leiste (rund 96 px) plus Abstand */
    padding: 8rem 0 var(--hero-foot);
    min-height: 62svh;
  }
}

/* Flache Fenster (Laptop im Vollbild, Landscape): der Hero darf den
   Bildschirm nicht allein füllen — die Folgesektion muss angeschnitten
   sichtbar bleiben. Der obere Abstand bleibt größer als die Kopfleiste. */
@media (min-width: 900px) and (max-height: 800px) {
  .hero {
    padding: 7.5rem 0 var(--hero-foot);
    min-height: 0;
  }
  .hero h1 { font-size: clamp(2.25rem, 5.5vw, 3.75rem); }
}

.hero__bg { position: absolute; inset: 0; z-index: 0; }
.hero__slides { position: absolute; inset: 0; }

/* Alle Slides liegen deckungsgleich übereinander und werden überblendet.
   Der Zuschnitt (object-position) steht als style-Attribut am Bild — er
   gehört zum Motiv, nicht zum Stylesheet. Ohne JS trägt nur der erste
   Slide is-active und bleibt damit als einziger sichtbar. */
.hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 800ms var(--ease);
}
.hero__img.is-active { opacity: 1; }
.hero--static .hero__img { transition: none; }

/* Overlay: ein leichter, farbloser Lichtkegel über dem Operator, darüber
   ein Scrim, der die helle Himmelsfläche links abdunkelt. Seit im Hero nur
   noch Eyebrow und Headline stehen, ist er bewusst schwach — das Foto soll
   dominieren, die Headline schützt zusätzlich ihr Textschatten. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    /* farbloser Lichtkegel, der den Operator vom Hintergrund abhebt */
    radial-gradient(50% 65% at 72% 45%, rgba(255, 255, 255, .07), transparent 70%),
    /* nur oben leicht (Header) und unten Übergang zur Folgesektion */
    linear-gradient(180deg, rgba(0, 0, 0, .40) 0%, transparent 22%,
                    transparent 68%, rgba(13, 13, 14, .94) 100%),
    /* Hauptscrim: links dunkel für den Text, rechts fast klar für das Foto */
    linear-gradient(90deg, rgba(0, 0, 0, .70) 0%, rgba(0, 0, 0, .58) 34%,
                    rgba(0, 0, 0, .34) 52%, rgba(0, 0, 0, .12) 72%,
                    rgba(0, 0, 0, .06) 86%, rgba(0, 0, 0, .22) 100%);
}
/* Einspaltig auf schmalen Screens: der Text liegt dann über der ganzen
   Breite, also muss der Scrim flächig statt seitlich abdunkeln. */
@media (max-width: 899px) {
  .hero__scrim {
    background:
      /* schwächer als auf Desktop: der Lichtkegel läge sonst direkt unter
         der Headline und würde deren Kontrast fressen */
      radial-gradient(70% 45% at 72% 22%, rgba(255, 255, 255, .05), transparent 70%),
      linear-gradient(180deg, rgba(0, 0, 0, .80) 0%, rgba(0, 0, 0, .56) 38%,
                      rgba(0, 0, 0, .52) 70%, rgba(13, 13, 14, .96) 100%);
  }
}

.hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
}
/* Alle vier Botschaften liegen im selben Rasterfeld übereinander: die Box
   ist damit so hoch wie die längste, beim Wechsel springt nichts. Nur die
   aktive ist sichtbar, überblendet wird wie beim Bild. */
.hero__content {
  max-width: 46rem;
  display: grid;
  /* Unten ausgerichtet: die Botschaften sind verschieden lang, die letzte
     Zeile steht so bei jedem Slide gleich weit über der Steuerleiste.
     Oben ausgerichtet risse eine unterschiedlich große Lücke darunter auf. */
  align-items: end;
}
.hero__msg {
  grid-area: 1 / 1;
  opacity: 0;
  /* etwas kürzer als die Bildüberblendung: der Text soll stehen, bevor das
     nächste Motiv voll da ist. */
  transition: opacity 600ms var(--ease);
  pointer-events: none;
}
.hero__msg.is-active { opacity: 1; }
.hero--static .hero__msg { transition: none; }
.hero h1 {
  /* Untergrenze knapp unter der Schriftgröße, ab der das längste Wort der
     vier Botschaften („Österreich") auf einem 360-px-Display nicht mehr in
     die Zeile passt — sonst schöbe es die Seite seitlich auf. */
  font-size: clamp(2.25rem, 6.5vw, 4.5rem);
  margin: 0;
  /* Schutz gegen die hellen Stellen des Fotos, falls der Scrim
     bei extremen Seitenverhältnissen verrutscht. */
  text-shadow: 0 2px 24px rgba(0, 0, 0, .55);
}
/* Zweistufiges Weiß statt Farbakzent: die erste Zeile tritt zurück,
   das Schlusswort steht in vollem Weiß. */
.hero h1 { color: rgba(255, 255, 255, .62); }
.hero h1 em {
  color: #fff;
  font-style: normal;
  display: block;
}

/* ── Hero-Slider: Steuerleiste ────────────────────────────────── */
/* Sitzt unten links auf derselben Fluchtlinie wie der übrige Inhalt
   (.wrap liefert den Seitenrand). Absolut positioniert, damit die
   zentrierte Headline davon unberührt bleibt. */
.hero__foot {
  position: absolute;
  left: 0;
  right: 0;
  bottom: var(--s-8);
  z-index: 1;
  pointer-events: none;
}
.hero__nav {
  width: min(360px, 100%);
  display: grid;
  gap: var(--s-2);
  color: var(--on-dark);
  pointer-events: auto;
}

/* Balkenreihe: zugleich Fortschritt und Sprungziel. Der Knopf ist nur
   Trefferfläche, die sichtbare Linie ist das innere span. */
.hero__bars { display: flex; gap: var(--s-3); }
.hero__bar {
  flex: 1 1 0;
  min-width: 0;
  padding: var(--s-3) 0;
  background: none;
  border: 0;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}
.hero__bar > span {
  display: block;
  position: relative;
  height: 2px;
  background: rgba(255, 255, 255, .28);
  overflow: hidden;
}
/* --p (0…1) setzt der Timer je Frame; abgespielte Balken stehen auf 1. */
.hero__bar > span::after {
  content: '';
  position: absolute;
  inset: 0;
  background: #fff;
  transform: scaleX(var(--p, 0));
  transform-origin: left center;
}
.hero__bar:hover > span { background: rgba(255, 255, 255, .5); }
.hero__bar:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.hero__ctrl {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.hero__arrow {
  width: 40px;
  height: 40px;
  margin: 0 -10px;   /* Ikone bündig zur Fluchtlinie, Trefferfläche darüber hinaus */
  display: grid;
  place-items: center;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  opacity: .75;
  transition: opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
.hero__arrow svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.hero__arrow:hover { opacity: 1; }
.hero__arrow[data-hero-dir="-1"]:hover { transform: translateX(-2px); }
.hero__arrow[data-hero-dir="1"]:hover { transform: translateX(2px); }
.hero__arrow:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; opacity: 1; }

.hero__count {
  margin: 0;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  font-family: var(--ff-mono);
  font-size: .8125rem;
  letter-spacing: var(--ls-wide);
  line-height: 1;
}
.hero__count-now { color: #fff; }
.hero__count-sep,
.hero__count-all { color: var(--on-dark-2); opacity: .7; }

@media (max-width: 899px) {
  .hero__foot { bottom: var(--s-6); }
  .hero__nav { width: 100%; }
}
/* ── Partner banner ───────────────────────────────────────────── */
.partner {
  background: var(--bg-alt);
  color: var(--text-2);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: var(--s-6) 0;
}
.partner__inner {
  display: flex;
  gap: var(--s-6);
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
}
.partner p { margin: 0; max-width: 68ch; font-size: .9375rem; }
.partner strong { color: var(--text); }

/* ── Section ──────────────────────────────────────────────────── */
/* Produktsektionen sind durchgehend weiß — siehe .tile__media. Getrennt
   wird über Weißraum und eine Haarlinie, nicht über Flächenwechsel. */
.sec {
  padding: var(--s-16) 0;
  background: var(--surface);
}
.sec + .sec { border-top: 1px solid var(--line); }
.sec__head {
  margin-bottom: var(--s-8);
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-6);
}
.sec__headText { max-width: 60ch; }
.sec__head h2 { font-size: clamp(1.75rem, 4vw, 2.75rem); margin-bottom: var(--s-4); }
.sec__head p { color: var(--text-2); margin: 0; font-size: 1.0625rem; }
/* Rechtlicher Hinweis unter einer Kategorie (z. B. Versandbeschränkung) */
.sec__note {
  margin-top: var(--s-3) !important;
  font-size: .875rem !important;
  color: var(--text-mute) !important;
}

/* ── Rail (horizontaler Slider) ───────────────────────────────── */
/* Die Rail bricht bewusst aus dem Container aus und läuft rechts aus
   dem Bild — das signalisiert "hier geht es weiter" ohne extra UI und
   spart gegenüber einem Grid deutlich vertikale Höhe. */
.rail {
  /* Einzug, der die erste Kachel bündig unter die Überschrift setzt.
     Bezug ist 100% (Breite der Sektion), NICHT 100vw: vw enthält die
     Breite einer klassischen Scrollbar und würde die Seite horizontal
     überlaufen lassen. */
  --rail-inset: max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter)));

  overflow-x: auto;
  overflow-y: hidden;
  /* Paint-Containment: ohne sie zaehlt Chromium den ueberstehenden Inhalt
     des Modellvergleichs zum Scrollbereich der SEITE, und die ganze Seite
     laesst sich horizontal schieben. Ausloeser ist display:contents an
     .cmp__col — dessen Zellen liegen als Grid-Items direkt im .cmp und
     werden dem Rail als Scroller nicht sauber zugerechnet. Die Rail
     schneidet ohnehin in beide Richtungen ab; sichtbar aendert sich also
     nichts, der Ueberhang bleibt nur da, wo er hingehoert. */
  contain: paint;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Bewusst OHNE scroll-snap: Snap rastet jeden programmatisch gesetzten
     Scrollwert sofort auf eine Kachelkante, wodurch die Pfeil-Animation
     springt statt zu gleiten. Freies Scrollen verhält sich hier besser. */
  /* Die Rail ist direktes Kind der Sektion und damit ohnehin schon so
     breit wie der Inhaltsbereich — sie braucht keine vw-Ausbruchbreite.
     Die linke Kante wird allein über den Einzug bündig zum .wrap gesetzt. */
  padding-left: var(--rail-inset);
  padding-right: var(--gutter);
  padding-bottom: var(--s-2);
}
.rail::-webkit-scrollbar { display: none; }
.rail:focus-visible { outline: 2px solid var(--signal); outline-offset: 4px; }

.rail__track {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--s-5);
}

.rail__nav { display: flex; gap: var(--s-2); flex: none; }
/* Runde, stille Knöpfe: die Pfeile sind Navigation, kein Angebot —
   Signalfarbe bleibt den Kaufwegen vorbehalten. */
.rail__btn {
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  background: var(--bg);
  border: 0;
  border-radius: 50%;
  color: var(--text);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
  transition: background var(--t) var(--ease), color var(--t) var(--ease),
              opacity var(--t) var(--ease);
}
.rail__btn:hover:not(:disabled) {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}
.rail__btn:disabled { opacity: .3; cursor: default; }
.rail__btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ── Tile ─────────────────────────────────────────────────────── */
.tile {
  flex: 0 0 auto;
  width: 260px;
}
@media (min-width: 700px) { .tile { width: 300px; } }

.tile__link {
  display: flex;
  flex-direction: column;
  text-decoration: none;
  color: inherit;
  height: 100%;
}
.tile__link:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

/* Rahmenlos: das Produkt steht frei auf der Sektionsfläche, keine Karte,
   kein Rand, kein Schatten. Setzt voraus, dass die Sektion weiß ist —
   die Händlerfotos sind JPEGs mit weißem Hintergrund und würden auf
   getöntem Grund sonst als weiße Rechtecke auffallen. */
.tile__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.tile__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 340ms var(--ease);
}
.tile__link:hover .tile__media img { transform: scale(1.06); }

.tile__name {
  display: block;
  font-family: var(--ff-body);
  font-size: .9375rem;
  font-weight: 700;
  text-transform: uppercase;
  line-height: 1.2;
  margin-top: var(--s-4);
  /* zwei Zeilen reservieren, damit die Specs über alle Kacheln
     einer Rail auf gleicher Höhe sitzen */
  min-height: calc(2 * 1.2em);
}
.tile__spec {
  display: block;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  margin-top: var(--s-2);
}

.badge {
  position: absolute;
  top: var(--s-3);
  left: var(--s-3);
  z-index: 1;
  background: var(--ink);
  color: #fff;
  font-family: var(--ff-mono);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  padding: 4px var(--s-3);
  border-radius: var(--r-2);
}
/* Einziger Farbakzent auf der Seite ausserhalb der Fokus-Ringe: das
   "Neu"-Badge. Genau ein Artikel traegt es. */
/* Dunkle Schrift auf dem Orange: Weiß käme hier nur auf 2,9:1. */
.badge--new { background: var(--signal); color: var(--ink); }


/* ── Modellvergleich (Komplette Builds) ───────────────────────── */
/* Karte und Merkmalszeilen liegen in EINEM Grid: die Spaltengruppen
   tragen `display: contents`, ihre Zellen sind damit direkte Grid-Kinder.
   Dadurch ist jede Zeile über alle Spalten gleich hoch und die
   Trennlinien laufen ohne Messerei in JS sauber durch. */
.cmp {
  --cmp-col: 300px;
  --cmp-gutter: 8px;

  display: grid;
  grid-template-rows: repeat(var(--cmp-rows, 8), auto);
  grid-auto-flow: column;
  /* Spaltenbreite enthält die Rinne — column-gap würde die Trennlinien
     an jeder Spaltengrenze aufreißen. */
  grid-auto-columns: calc(var(--cmp-col) + var(--cmp-gutter));
  column-gap: 0;
}
@media (max-width: 700px) { .cmp { --cmp-col: 250px; } }

.cmp__col { display: contents; }

.cmp__col > * { padding-right: var(--cmp-gutter); }

/* Ausnahme Bildfläche: bei den Merkmalszeilen soll die Rinne INNEN liegen,
   damit die Trennlinien über die Spaltengrenze durchlaufen. Das getönte
   Panel dagegen wird sonst bis an die Nachbarspalte gemalt und die
   Flächen laufen zu einem Band zusammen — hier also margin statt padding.
   Die Spaltenbreite bleibt gleich, das Panel wird um die Rinne schmaler. */
.cmp__col > .cmp__media {
  padding-right: 0;
  margin-right: var(--cmp-gutter);
}

/* Bildfläche: getöntes Panel statt freistehendem Produkt.
   `multiply` ist hier kein Notbehelf, sondern nötig: die Bilder sind nur
   am äußeren Rand freigestellt, eingeschlossene Flächen (Abzugsbügel,
   Skelettschaft, beim XF13 ein Block am Schaft) sind weiterhin deckend
   weiß. Auf weißem Grund fällt das nicht auf, auf getöntem sehr wohl.
   Multiply zieht diese Reste auf die Panelfarbe. */
.cmp__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--bg);
  border-radius: var(--r-8);
  overflow: hidden;
}
.cmp__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--s-2);
  mix-blend-mode: multiply;
  transition: transform 340ms var(--ease);
}
.cmp__media:hover img { transform: scale(1.04); }

.cmp__name {
  font-family: var(--ff-body);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
  margin: var(--s-5) 0 0;
  /* zwei Zeilen reservieren, damit Preis und Knopf über alle Spalten
     auf gleicher Höhe sitzen, auch wenn ein Name umbricht */
  min-height: calc(2 * 1.2em);
}

.cmp__price { margin-top: var(--s-4); }
.cmp__amount {
  display: block;
  font-size: 1.125rem;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
}

/* Der Knopf steht in derselben Stufung wie Name und Preis darüber; ohne
   eigenen Abstand klebte er direkt am Preis, während oben 16-20 px Luft
   stehen. Unten trennt das größere Polster zur Merkmalstabelle. */
.cmp__buy {
  margin-top: var(--s-4);
  padding-bottom: var(--s-8);
}

.cmp__cell {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-top: var(--s-4);
  padding-bottom: var(--s-4);
  border-top: 1px solid var(--line);
}

/* Eingeklappt stehen nur die ersten beiden Merkmalszeilen: die dritte läuft
   nach unten aus, alles darunter verliert seine Höhe. Die Klasse setzt erst
   das Skript — ohne JS bleibt die Tabelle vollständig.

   Bewusst kein display:none: das Raster fließt spaltenweise durch eine feste
   Zeilenzahl, eine fehlende Zelle würde die nächste Spalte nach oben ziehen.
   Die Zellen behalten deshalb ihren Platz und geben nur ihre Höhe ab. */
.cmp.is-fold .cmp__cell--peek {
  height: 3rem;
  overflow: hidden;
  /* Die Beschriftung bleibt oben noch voll lesbar, erst der Wert darunter
     läuft aus — ein durchgehender Verlauf ab Zeilenanfang sieht aus wie ein
     Darstellungsfehler statt nach "hier geht es weiter". */
  -webkit-mask-image: linear-gradient(to bottom, #000 40%, transparent);
  mask-image: linear-gradient(to bottom, #000 40%, transparent);
}
.cmp.is-fold .cmp__cell--rest {
  visibility: hidden;
  height: 0;
  padding-top: 0;
  padding-bottom: 0;
  border-top-width: 0;
  overflow: hidden;
}

/* Der Knopf steht unter der Tabelle, außerhalb der quer scrollenden Rail —
   er gehört zur Sektion, nicht zu einer einzelnen Spalte. */
.cmp__more {
  display: block;
  margin: var(--s-6) auto 0;
  padding: var(--s-3) var(--s-6);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2);
  color: var(--text);
  font-family: var(--ff-mono);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color var(--t) var(--ease), color var(--t) var(--ease);
}
.cmp__more[hidden] { display: none; }
.cmp__more:hover { border-color: var(--ink); }
.cmp__more:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.cmp__label {
  font-size: .75rem;
  color: var(--text-mute);
}
.cmp__value {
  font-size: 1rem;
  line-height: 1.3;
}
.cmp__cell--empty .cmp__value { color: var(--text-faint); }

/* Zeile über der Rail: Anzahl links, Pfeile rechts. */
.cmp__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-6);
}
.cmp__count {
  margin: 0;
  font-size: .875rem;
  color: var(--text-mute);
}

/* In dieser Sektion bewusst ohne Signalfarbe: die Produkte sollen die
   einzigen farbigen Flächen sein. */
.sec--cmp .eyebrow { color: var(--text-2); }
.sec--cmp .eyebrow::before { background: var(--text-faint); }
.cmp__media .badge {
  background: var(--ink);
  color: #fff;
}

/* Knopf über die volle Spaltenbreite, Pfeil rechts außen. */
.btn--block {
  display: flex;
  width: 100%;
  justify-content: space-between;
  padding: var(--s-4) var(--s-5);
  background: var(--ink);
  border-color: var(--ink);
}
.btn--block:hover {
  background: var(--ink-3);
  border-color: var(--ink-3);
  transform: none;
}
.btn__arrow { font-size: .875rem; }

/* Nur für Hilfsmittel: der Knopftext allein ("Zum Kauf") ist außerhalb
   der Spalte nicht eindeutig. */
.u-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ── Lauf-Systeme: Kacheln + Längen-Dialog ────────────────────── */
/* Die Ausbaustufen laufen in derselben horizontalen Liste wie die übrigen
   Produktbereiche — Layout und Pfeile kommen von .rail/.rail__track, hier
   stehen nur noch die Abweichungen der Kachel selbst. */

/* Die Kachel ist ein Button (öffnet den Dialog), soll aber wie die
   übrigen Produktkacheln aussehen. */
.pkg__trigger {
  width: 100%;
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  cursor: pointer;
  font: inherit;
  color: inherit;
}
.tile__more {
  display: block;
  margin-top: var(--s-3);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text);
  font-weight: 700;
}

/* ── Dialog ───────────────────────────────────────────────────── */
.pkg-open { overflow: hidden; }

.pkg__dialog {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: grid;
  place-items: center;
  padding: var(--s-4);
}
/* Muss NACH der display-Regel stehen: ein gesetztes display überschreibt
   sonst das hidden-Attribut, und alle Dialoge lägen offen übereinander. */
.pkg__dialog[hidden] { display: none; }
.pkg__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .68);
  backdrop-filter: blur(3px);
}
.pkg__panel {
  position: relative;
  z-index: 1;
  width: min(760px, 100%);
  max-height: 88svh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 30px 80px rgba(0, 0, 0, .4);
  display: grid;
  gap: var(--s-6);
  padding: var(--s-8);
  /* Gerade Kanten, nur die Ecken gerundet — keine Schräge wie im Header. */
  border-radius: var(--r-14);
}
@media (min-width: 700px) {
  .pkg__panel { grid-template-columns: 260px 1fr; align-items: start; }
  /* Zweispaltig steht die Überschrift oben rechts — dort sitzt der
     Schliessen-Knopf, also Platz für ihn freihalten. */
  .pkg__panelBody h3 { padding-right: calc(36px + var(--s-3)); }
}
.pkg__panelMedia img { width: 100%; height: auto; }
.pkg__panelBody h3 {
  font-size: 1.375rem;
  margin-bottom: var(--s-2);
}
.pkg__spec {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 var(--s-4);
}
.pkg__text {
  color: var(--text-2);
  margin: 0 0 var(--s-6);
  font-size: .9375rem;
}
.pkg__close {
  position: absolute;
  top: var(--s-3);
  right: var(--s-3);
  z-index: 2;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  background: transparent;
  border: 1px solid var(--line);
  border-radius: var(--r-2);
  font-size: 1.375rem;
  line-height: 1;
  cursor: pointer;
  color: var(--text-2);
}
.pkg__close:hover { background: var(--ink); border-color: var(--ink); color: #fff; }
.pkg__close:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* Länge, die der Shop derzeit nicht listet — sichtbar, aber nicht klickbar.
   Doppelte Klasse, damit die Regel unabhängig von der Reihenfolge gegenüber
   .chip gewinnt (gleiche Spezifität würde sonst von der späteren Regel
   überschrieben). */
.chip.chip--off {
  border-style: dashed;
  border-color: var(--line);
  color: var(--text-faint);
  background: transparent;
  cursor: default;
}
.chip.chip--off:hover {
  background: transparent;
  border-color: var(--line);
  color: var(--text-faint);
  transform: none;
}

/* ── Split-Sektion mit Größenauswahl ──────────────────────────── */
/* Für Produkte, die sich nur im Maß unterscheiden: ein Foto, eine
   Beschreibung, und die Größen als direkte Links — statt zehnmal
   dieselbe Kachel mit demselben Bild. */
.split {
  display: grid;
  gap: var(--s-8);
  align-items: center;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1fr 1fr; gap: var(--s-12); }
}
.split__media {
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.split__media img {
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.split__body h2 { font-size: clamp(1.75rem, 4vw, 2.75rem); margin-bottom: var(--s-4); }
.split__intro {
  color: var(--text-2);
  font-size: 1.0625rem;
  margin: 0 0 var(--s-8);
  max-width: 52ch;
}

.picker__label {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 var(--s-4);
}
.picker {
  list-style: none;
  margin: 0 0 var(--s-5);
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
}
.chip {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 84px;
  padding: var(--s-3) var(--s-4);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2);
  background: var(--surface);
  color: var(--text);
  font-family: var(--ff-mono);
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-decoration: none;
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease),
              color var(--t) var(--ease), transform var(--t) var(--ease);
}
.chip:hover {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
  transform: translateY(-1px);
}
.chip:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.picker__note {
  margin: 0;
  font-size: .875rem;
  color: var(--text-mute);
}

/* ── Rechtsseiten ─────────────────────────────────────────────── */
.legal { background: var(--surface); }
.legal__inner {
  max-width: 46rem;
  /* Diese Seiten haben keinen Hero — die schwebende Leiste würde sonst
     über der Überschrift liegen. */
  padding-top: calc(var(--s-16) + 5rem);
  padding-bottom: var(--s-20);
}
.legal h1 {
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  margin-bottom: var(--s-4);
}
.legal__lead {
  color: var(--text-2);
  font-size: 1.0625rem;
  margin: 0 0 var(--s-10);
}
.legal h2 {
  font-size: 1.125rem;
  margin: var(--s-10) 0 var(--s-3);
}
.legal p { margin: 0 0 var(--s-4); color: var(--text-2); }
.legal a { color: var(--text); text-decoration-color: var(--line-strong); }

.legal__table {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: var(--s-6);
}
.legal__table th,
.legal__table td {
  text-align: left;
  vertical-align: top;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}
.legal__table th {
  width: 38%;
  padding-right: var(--s-5);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 400;
}
.legal__table td { color: var(--text); }
@media (max-width: 560px) {
  .legal__table th, .legal__table td { display: block; width: auto; }
  .legal__table th { border-bottom: 0; padding-bottom: 0; }
}

/* ── Jubiläumsband ────────────────────────────────────────────── */
/* Zäsur zwischen Produktbereichen und Bildstrecke: eine dunkle Vollbreite,
   auf der nur die Jahreszahl steht. Der Grund ist bewusst gezeichnet statt
   fotografiert — die vorhandenen Motive stehen direkt darunter. */
.anniv {
  position: relative;
  overflow: hidden;
  background: var(--ink);
  color: var(--on-dark);
  padding: var(--s-20) 0;
  border-top: 1px solid var(--line-dark);
}
@media (min-width: 900px) {
  .anniv {
    padding: var(--s-24) 0;
    min-height: 60svh;
    display: flex;
    align-items: center;
  }
}

/* Zwei Schichten: weiches Licht (Verläufe) und darüber eine feine
   Schraffur, die der Fläche Struktur gibt, ohne den Text zu stören. */
.anniv__bg { position: absolute; inset: 0; z-index: 0; }
.anniv__bg::before,
.anniv__bg::after { content: ""; position: absolute; inset: 0; }
.anniv__bg::before {
  background:
    radial-gradient(80% 90% at 78% 18%, rgba(255, 255, 255, .16), transparent 62%),
    radial-gradient(60% 70% at 92% 62%, rgba(255, 255, 255, .07), transparent 66%),
    radial-gradient(52% 58% at 8% 104%, rgba(255, 91, 31, .13), transparent 68%),
    linear-gradient(115deg, #000 0%, #0d0d0e 46%, #17171a 74%, #232327 100%);
}
/* Schraffur in Blickrichtung der Verläufe; 4 % Deckung reicht, um die
   Fläche zu brechen — mehr würde unter der Headline flimmern. */
.anniv__bg::after {
  background: repeating-linear-gradient(115deg,
    rgba(255, 255, 255, .04) 0 1px, transparent 1px 7px);
  /* links, wo der Text steht, läuft die Struktur aus */
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 42%, #000 100%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 42%, #000 100%);
}

/* Die Sektion ist auf Desktop ein Flex-Container (vertikal zentriert) —
   ohne width:100% schrumpfte die Bahn auf ihre Inhaltsbreite und der
   Text stünde nicht mehr in der Gutterflucht der übrigen Sektionen. */
.anniv__inner { position: relative; z-index: 1; width: 100%; }
.anniv__content { max-width: 46rem; }
.anniv__eyebrow { opacity: .6; }
.anniv h2 {
  font-size: clamp(2rem, 5.5vw, 3.75rem);
  margin-bottom: var(--s-6);
  text-shadow: 0 2px 24px rgba(0, 0, 0, .55);
}
.anniv__lines {
  margin: 0 0 var(--s-8);
  color: var(--on-dark-2);
  font-size: 1.0625rem;
  line-height: 1.75;
}
.anniv__lines span { display: block; }

/* ── Werkstatt & Community ────────────────────────────────────── */
/* Dunkler Block zwischen den weißen Produktbereichen und dem Trust-Streifen:
   die Produktfotos sind freigestellt und sachlich, hier stehen dagegen
   Werkstatt, Feld und Detail — deshalb der Flächenwechsel. */
.brand {
  background: var(--bg);
  color: var(--text);
  padding: var(--s-16) 0;
  border-top: 1px solid var(--line);
}
.brand__head { max-width: 60ch; margin-bottom: var(--s-8); }
.brand__head h2 {
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  margin-bottom: var(--s-4);
}
.brand__text { color: var(--text-2); margin: 0; font-size: 1.0625rem; }

/* Bento: das Werkstattbild trägt zwei Reihen, rechts daneben Feld (breit)
   und darunter zwei Details. Unter 760px wird daraus eine Spalte. */
.brand__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-3);
}
.brand__tile {
  position: relative;
  margin: 0;
  overflow: hidden;
  border-radius: var(--r-4);
  background: var(--ink-3);
}
.brand__tile img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 420ms var(--ease);
}
.brand__tile:hover img { transform: scale(1.04); }

/* Beschriftung im Bild: ohne sie wären es hübsche Fotos ohne Aussage.
   Der Verlauf darunter hält sie auf jedem Motiv lesbar. */
.brand__tile figcaption {
  position: absolute;
  inset: auto 0 0 0;
  padding: var(--s-8) var(--s-4) var(--s-3);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, .72));
}
.brand__tile figcaption::before {
  content: "";
  display: inline-block;
  width: 14px;
  height: 2px;
  margin-right: var(--s-2);
  vertical-align: middle;
  background: currentColor;
  opacity: .7;
}

.brand__tile--1 { grid-column: span 2; grid-row: span 2; }
.brand__tile--2 { grid-column: span 2; aspect-ratio: 16 / 9; }
/* 4:3 statt quadratisch: die beiden kleinen Motive stammen aus dem alten
   Shop und sind nur 900 bzw. 433 px breit — ein quadratischer Anschnitt
   müsste sie sichtbar hochrechnen. */
.brand__tile--3,
.brand__tile--4 { aspect-ratio: 4 / 3; }

@media (max-width: 760px) {
  .brand__grid { grid-template-columns: 1fr; }
  .brand__tile--1 { grid-column: auto; grid-row: auto; aspect-ratio: 4 / 3; }
  .brand__tile--2 { grid-column: auto; }
  .brand__tile--3,
  .brand__tile--4 { aspect-ratio: 16 / 9; }
}

/* ── Community-Stimme ─────────────────────────────────────────── */
/* Dunkel zwischen der hellgrauen Bildstrecke und dem weissen Trust-Streifen.
   Der Flaechenwechsel ist hier nicht Dekoration, sondern Aussage: alles
   darueber ist unsere eigene Darstellung, dieser Block ist es nicht. */
.voice {
  background: var(--ink);
  color: var(--on-dark);
  padding: var(--s-16) 0;
}
.voice__head { max-width: 60ch; margin-bottom: var(--s-10); }
.voice__head h2 {
  font-size: clamp(1.75rem, 4vw, 2.75rem);
  margin-bottom: var(--s-4);
}
.voice__note { margin: 0; font-size: 1.0625rem; color: var(--on-dark-2); }

/* Eine Zeile, die rechts aus dem Bild laeuft — dieselbe Rail wie bei den
   Produktbereichen. Statt bei schmalem Schirm auf zwei und eine Spalte
   umzubrechen, bleibt die Reihe stehen und wird geschoben; die
   angeschnittene vierte Kachel zeigt von selbst, dass es weitergeht. */
/* Bewusst OHNE flex-wrap, genau wie .sec__head: umbricht der Kopf, rutschen
   die Pfeile unter den Text an die linke Kante statt an den rechten Rand zu
   bleiben, wo sie in jeder anderen Sektion stehen. */
.voice__head {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--s-6);
  margin-bottom: var(--s-8);
}
.voice__headText { max-width: 60ch; }
/* Die Pfeile stehen auf dunklem Grund — die helle Standardfuellung der
   Rail-Knoepfe waere hier der einzige weisse Fleck in der Sektion. */
.voice__head .rail__btn {
  background: transparent;
  border: 1px solid var(--line-dark-2);
  color: var(--on-dark);
}
.voice__head .rail__btn:hover:not(:disabled) {
  background: var(--on-dark);
  border-color: var(--on-dark);
  color: var(--ink);
}

.voice__cell { flex: 0 0 auto; width: 260px; display: flex; }
@media (min-width: 700px) { .voice__cell { width: 300px; } }

/* Die Karte ist ein Knopf, kein Link — sie oeffnet den Dialog auf dieser
   Seite. Deshalb sichtbarer Rahmen statt Unterstreichung: bei mehreren
   Zeilen Text ist die Flaeche das Ziel, nicht ein Wort darin. */
.voice__card {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  padding: 0;
  overflow: hidden;
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--ink-2);
  border: 1px solid var(--line-dark-2);
  border-radius: var(--r-4);
  cursor: pointer;
  transition: border-color var(--t) var(--ease), background var(--t) var(--ease);
}
.voice__card:hover,
.voice__card:focus-visible {
  border-color: var(--on-dark-mute);
  background: var(--ink-3);
}

/* Nur der Erfahrungsbericht bringt ein Foto mit. Fester Ausschnitt, damit
   er neben den drei textlichen Karten nicht aus der Reihe faellt — das
   Hochkantbild in voller Hoehe wuerde die Zeile sprengen. */
/* overflow ist hier nicht Kosmetik: ohne ihn waechst der Kasten auf die
   Eigenhoehe des hochkanten Fotos (418 statt 313 px bei 418 px Breite) und
   aspect-ratio bliebe wirkungslos. */
.voice__cardShot {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ink-3);
  border-bottom: 1px solid var(--line-dark-2);
}
.voice__cardShot img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Die Replik liegt in der oberen Bildhaelfte. */
  object-position: 50% 32%;
  transition: transform 420ms var(--ease);
}
.voice__card:hover .voice__cardShot img { transform: scale(1.04); }

/* Freigestellte Produktbilder brauchen Licht hinter sich: die Motive sind
   ueberwiegend schwarz und waeren auf der dunklen Sektionsflaeche nicht zu
   erkennen. Die Studioflaeche ist bewusst grau statt weiss — ein weisser
   Kasten waere in dieser Sektion der hellste Fleck der ganzen Seite. */
.voice__cardShot--cut {
  background: radial-gradient(circle at 50% 45%, #e9e9ec 0%, #c9c9ce 78%);
}
.voice__cardShot--cut img {
  object-fit: contain;
  padding: var(--s-5);
}

.voice__cardBody {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  flex: 1;
  padding: var(--s-5) var(--s-5) 0;
}
.voice__kind {
  display: block;
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--on-dark-mute);
}
.voice__cardTitle {
  display: block;
  font-family: var(--ff-body);
  font-weight: 700;
  font-size: 1.0625rem;
  line-height: 1.3;
  color: var(--on-dark);
}

/* Gekuerzt wird per CSS, nicht im Text: Karte und Dialog tragen denselben
   Satz, es gibt keine zweite Kurzfassung, die auseinanderlaufen koennte. */
.voice__summary {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  line-clamp: 3;
  overflow: hidden;
  font-size: .9375rem;
  color: var(--on-dark-2);
  /* Schiebt die Metazeile an den Kartenboden, damit sie ueber die ganze
     Reihe fluchtet — die Zusammenfassungen sind unterschiedlich lang. */
  flex: 1;
}
.voice__cardMeta {
  display: block;
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-wide);
  color: var(--on-dark-mute);
}
/* Sagt, dass ein Klick etwas oeffnet — ohne den Knopf als Link auszugeben. */
.voice__cardMore {
  display: block;
  padding: var(--s-3) var(--s-5) var(--s-5);
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--on-dark);
}
.voice__cardMore::after { content: " →"; }

/* ── Community: Dialog ────────────────────────────────────────── */
/* Mechanik, Backdrop und Schliessen-Knopf kommen von .pkg__dialog; hier
   steht nur, was der Inhalt anders braucht: dunkle Flaeche statt heller
   und ein Bild, das hochkant sein darf. */
.voice__panel {
  background: var(--ink-2);
  border-color: var(--line-dark-2);
  color: var(--on-dark);
  width: min(880px, 100%);
}
@media (min-width: 700px) {
  .voice__panel { grid-template-columns: 300px 1fr; }
  .voice__panelBody h3 { padding-right: calc(36px + var(--s-3)); }
}
/* Dialoge ohne Foto sind einspaltig — sonst klaffte links eine leere Spalte. */
.voice__panel:not(:has(.voice__panelMedia)) { grid-template-columns: 1fr; }
.voice__panel .pkg__close {
  border-color: var(--line-dark-2);
  color: var(--on-dark);
}
.voice__panel .pkg__close:hover {
  background: var(--on-dark);
  color: var(--ink);
}

.voice__panelMedia figure { margin: 0; }
/* Im Dialog dieselbe Studioflaeche wie auf der Kachel — sonst haette der
   Beitrag zwei verschiedene Bildwelten. */
.voice__panelMedia--cut {
  background: radial-gradient(circle at 50% 45%, #e9e9ec 0%, #c9c9ce 78%);
  border-radius: var(--r-2);
  padding: var(--s-4);
}
.voice__panelMedia--cut img { border-radius: 0; background: none; }
.voice__panelMedia img {
  width: 100%;
  height: auto;
  border-radius: var(--r-2);
  background: var(--ink-3);
}
.voice__panelMedia figcaption {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-3);
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}
.voice__caption { color: var(--on-dark-2); }
.voice__credit  { color: var(--on-dark-mute); }

.voice__panelBody h3 { font-size: 1.5rem; margin: var(--s-2) 0 var(--s-2); }
.voice__panelMeta {
  margin: 0 0 var(--s-5);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  color: var(--on-dark-mute);
}
.voice__panelText {
  margin: 0 0 var(--s-6);
  font-size: 1rem;
  color: var(--on-dark-2);
}

/* Das Zitat wird mit einer Haarlinie markiert statt mit einem gesetzten
   Anfuehrungszeichen: die Display-Schrift der Seite zeichnet das Zeichen
   als zwei fast quadratische Striche, und die Linie ist ohnehin die
   Sprache dieser Seite (Eyebrow-Strich, Trennlinien). */
.voice__quote {
  margin: 0 0 var(--s-6);
  padding: 0 0 var(--s-2) var(--s-5);
  border-left: 2px solid var(--line-dark-2);
  max-width: 44ch;
}
.voice__quote p {
  margin: 0;
  font-size: clamp(1.125rem, 2vw, 1.375rem);
  font-weight: 500;
  line-height: 1.4;
}
/* Die Uebersetzung ist eine Lesehilfe, nicht das Zitat — sie tritt in
   Groesse und Farbe zurueck und traegt ihre Beschriftung sichtbar mit. */
.voice__quote .voice__translation {
  margin-top: var(--s-3);
  font-size: .875rem;
  font-weight: 400;
  line-height: 1.6;
  color: var(--on-dark-mute);
}
.voice__translation span {
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  margin-right: var(--s-2);
}

/* Eigene Zusammenfassung der Eckpunkte — abgesetzt durch die Linie
   darueber, damit erkennbar bleibt, dass hier wieder wir reden. */
.voice__facts {
  display: grid;
  gap: var(--s-4);
  margin: 0 0 var(--s-6);
  padding: var(--s-5) 0 0;
  list-style: none;
  border-top: 1px solid var(--line-dark-2);
}
@media (min-width: 560px) {
  .voice__facts { grid-template-columns: repeat(3, 1fr); }
}
.voice__facts strong {
  display: block;
  margin-bottom: var(--s-2);
  font-family: var(--ff-mono);
  font-weight: 400;
  font-size: .625rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--on-dark-mute);
}
.voice__facts span { color: var(--on-dark-2); font-size: .875rem; }

.voice__source {
  margin: var(--s-4) 0 0;
  font-size: .75rem;
  color: var(--on-dark-mute);
}

/* ── Trust strip ──────────────────────────────────────────────── */
.trust {
  background: var(--surface);
  color: var(--text);
  padding: var(--s-16) 0;
  border-top: 1px solid var(--line);
}
.trust__grid {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.trust__item h3 {
  font-size: 1.0625rem;
  margin-bottom: var(--s-3);
  color: var(--text);
}
.trust__item p { color: var(--text-2); margin: 0; font-size: .9375rem; }
.trust__num {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-widest);
  color: var(--text-mute);
  display: block;
  margin-bottom: var(--s-3);
}

/* ── CTA band ─────────────────────────────────────────────────── */
.cta {
  /* Eine Stufe dunkler als der weiße Trust-Streifen darüber — das Band
     soll sich absetzen, ohne die Seite wieder dunkel zu machen. */
  background: var(--bg-alt);
  border-top: 1px solid var(--line);
  color: var(--text);
  padding: var(--s-16) 0;
  text-align: center;
}
.cta h2 { font-size: clamp(1.75rem, 5vw, 3rem); margin-bottom: var(--s-4); }
.cta p { margin: 0 auto var(--s-8); max-width: 52ch; font-size: 1.0625rem; opacity: .95; }
/* Der Knopf erbt die dunkle Standardfläche — auf dem hellen Band trägt
   sie den Kontrast von selbst. */

/* ── Footer ───────────────────────────────────────────────────── */
.ftr {
  background: #000;
  color: var(--on-dark-mute);
  padding: var(--s-12) 0 var(--s-8);
  font-size: .875rem;
}
.ftr__grid {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  padding-bottom: var(--s-8);
  border-bottom: 1px solid var(--line-dark);
}
.ftr__logo {
  display: block;
  width: 180px;
  height: auto;
  margin-bottom: var(--s-4);
}
.ftr h3 {
  font-size: .75rem;
  letter-spacing: var(--ls-widest);
  color: var(--on-dark);
  margin-bottom: var(--s-4);
  font-family: var(--ff-mono);
  font-weight: 700;
}
.ftr a { color: var(--on-dark-2); text-decoration: none; }
.ftr a:hover { color: var(--on-dark); }
.ftr ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--s-2); }
.ftr__bottom {
  padding-top: var(--s-6);
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  flex-wrap: wrap;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}
.ftr__todo {
  color: #6b6b6b;
  border: 1px dashed #3a3a3a;
  padding: var(--s-4);
  border-radius: var(--r-4);
  margin-top: var(--s-6);
  font-size: .8125rem;
  line-height: 1.5;
}
.ftr__todo b { color: var(--on-dark-2); }

/* ── Reduced motion ───────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}

/* Im Paket-Raster dürfen Namen unterschiedlich viele Zeilen brauchen
   ("V2 Rotary Drop-In Barrel System" bricht schmal dreizeilig um).
   Spec und CTA werden deshalb an den Kachelboden geheftet — dadurch
   fluchten sie über die ganze Reihe, unabhängig von der Namenslänge. */
.pkg__list .tile__link { height: 100%; }
.pkg__list .tile__name { min-height: 0; margin-bottom: auto; }
.pkg__list .tile__spec { margin-top: var(--s-3); }
/* Auf schmalen Kacheln bricht die Spec-Zeile unterschiedlich um ("R-Hop
   installiert" zwei-, "Edelstahl" einzeilig) — zwei Zeilen reservieren, damit
   sie zusammen mit dem CTA über die Reihe fluchtet. Ab 900px sind die zwei
   Spalten breit genug für eine Zeile, dort wäre die Reserve nur Leerraum. */
.pkg__list .tile__spec { min-height: calc(2 * 1.6em); }
@media (min-width: 900px) {
  .pkg__list .tile__spec { min-height: 0; }
}

/* Verweisliste auf die Vertragsbedingungen im Shop */
.legal__links { margin: 0 0 var(--s-6); padding-left: var(--s-5); }
.legal__links li { margin-bottom: var(--s-2); color: var(--text-2); }

/* ── Klappmenü der Kopfleiste (ab 900px) ──────────────────────────
   Jeder Punkt der Leiste trägt seine Artikel gleich mit: unter "Builds"
   die Waffen, unter "Läufe" die Laufsysteme mit allen Längen. Jeder
   Eintrag führt direkt zum Artikel im Shop.

   Die Bahn hängt als Geschwister UNTER .hdr__inner, nicht darin: die
   Leiste trägt einen clip-path für ihre schräge Kante und würde jede
   Tafel abschneiden. Sie steht im Fluss direkt hinter der Leiste — damit
   wandert sie beim Andocken der Leiste automatisch mit nach oben. */
.hdr__mega {
  position: relative;
  height: 0;
  pointer-events: none;
}

.mega {
  position: absolute;
  top: var(--s-2);
  left: 0;
  right: 0;
  margin: 0 auto;
  /* Dieselbe Außenkante wie die Leiste darüber. */
  width: calc(100% - 2 * var(--gutter));
  max-width: calc(var(--maxw) - 2 * var(--gutter));
  pointer-events: auto;

  /* Dasselbe Glasmaterial wie die Leiste — die Tafel ist ihre Fortsetzung
     nach unten, nicht ein fremdes Fenster. */
  background: rgba(255, 255, 255, .96);
  backdrop-filter: blur(28px) saturate(120%) brightness(1.25);
  -webkit-backdrop-filter: blur(28px) saturate(120%) brightness(1.25);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-14);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .9),
    0 24px 60px rgba(0, 0, 0, .18);

  opacity: 0;
  transform: translateY(-8px);
}
/* Ohne Skript hält das Attribut die Tafeln aus dem Weg. Sobald das Skript
   die Bahn übernommen hat (.is-ready), trägt die Sichtbarkeit den
   Zustand — nur so kann die Tafel auch ausblenden statt zu verschwinden.
   visibility nimmt sie dabei genauso aus der Tab-Reihenfolge wie zuvor
   das Attribut. */
.mega[hidden] { display: none; }
.hdr__mega.is-ready .mega {
  visibility: hidden;
  transition: opacity 220ms var(--ease), transform 220ms var(--ease),
              visibility 0s linear 220ms;
}
.hdr__mega.is-ready .mega.is-open {
  visibility: visible;
  opacity: 1;
  transform: none;
  transition-delay: 0s;
}

@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .mega { background: var(--surface); }
}

@media (prefers-reduced-motion: reduce) {
  .hdr__mega.is-ready .mega,
  .hdr__mega.is-ready .mega.is-open { transition: none; transform: none; }
}

/* Unter 900px ist die Leiste ausgeblendet und der Burger die einzige
   Navigation — die Tafeln haben dort nichts zu suchen. */
@media (max-width: 899px) {
  .hdr__mega { display: none; }
}

.mega__inner {
  display: grid;
  grid-template-columns: minmax(0, .34fr) minmax(0, 1fr);
  align-items: start;
}

/* Linke Hälfte: der Bereich selbst. Sie steht in jeder Tafel, damit auch
   eine Kategorie mit einem einzigen Artikel eine ausgewogene Tafel ergibt
   statt einer Kachel im leeren Raum. */
.mega__aside {
  padding: var(--s-6);
  border-right: 1px solid var(--line);
  min-height: 100%;
}
.mega__kicker {
  margin: 0;
  font-family: var(--ff-mono);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--signal);
}
.mega__label {
  margin: var(--s-2) 0 0;
  font-family: var(--ff-body);
  font-size: 1.0625rem;
  font-weight: 700;
  line-height: 1.15;
  text-transform: uppercase;
  color: var(--ink);
}
.mega__intro {
  margin: var(--s-3) 0 0;
  font-size: .8125rem;
  line-height: 1.5;
  color: var(--text-2);
  /* Die Einleitungen der Sektionen sind für die Tafel zu lang — vier
     Zeilen reichen als Vorschau, ganz steht sie im Bereich. */
  display: -webkit-box;
  -webkit-line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.mega__all {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-4);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 3px;
  transition: border-color var(--t) var(--ease), gap var(--t) var(--ease);
}
.mega__all svg { width: .9em; height: .9em; }
.mega__all:hover { border-color: var(--ink); gap: var(--s-3); }
.mega__all:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }
.mega__note {
  margin: var(--s-4) 0 0;
  font-size: .75rem;
  line-height: 1.45;
  color: var(--text-mute);
}

.mega__body { padding: var(--s-6); min-width: 0; }

/* ── Artikel als Kacheln ──────────────────────────────────────── */
/* Bild oben, Name darunter — nichts sonst. auto-fill statt fester
   Spaltenzahl: eine Kategorie mit einem einzigen Artikel bekommt so eine
   Kachel in Kachelgröße und keine, die sich über die halbe Tafel zieht.
   170px ergeben auf dem Schreibtisch vier Spalten — sechs Builds stehen
   damit 4 + 2 statt 5 + 1. */
.mega__grid {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
  gap: var(--s-2);
}
.mega__card {
  display: block;
  padding: var(--s-2);
  border: 1px solid transparent;
  border-radius: var(--r-4);
  text-decoration: none;
  color: inherit;
  transition: background var(--t) var(--ease), border-color var(--t) var(--ease);
}
.mega__card:hover { background: var(--bg); border-color: var(--line); }
.mega__card:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.mega__thumb {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
}
.mega__thumb img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: transform 340ms var(--ease);
}
.mega__card:hover .mega__thumb img { transform: scale(1.06); }

.mega__name {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--ff-body);
  font-size: .8125rem;
  font-weight: 700;
  line-height: 1.2;
  text-transform: uppercase;
  color: var(--ink);
}

/* ── Punkt der Leiste als Auslöser ────────────────────────────── */
.hdr__nav a.hdr__navLink {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
/* Zwischen 900px und 1100px ist die Leiste am engsten: fünf Punkte,
   Standortwahl und Shop-Knopf teilen sich den Platz. Der Pfeil kostet je
   Punkt rund zwölf Pixel — die holen die etwas engeren Abstände wieder
   herein, damit die Leiste wie bisher ab 900px steht und nicht erst ab
   1000. Die Untergrenze ist Pflicht: darunter gilt der eigene, noch
   engere Satz für schmale Screens weiter unten im Stylesheet. */
@media (min-width: 900px) and (max-width: 1099px) {
  .hdr__inner { gap: var(--s-4); }
  .hdr__nav { gap: var(--s-3); }
  .hdr__right { gap: var(--s-3); }
}
.hdr__navChev {
  width: .75em;
  height: .75em;
  opacity: .5;
  transition: transform var(--t) var(--ease), opacity var(--t) var(--ease);
}
.hdr__navLink:hover .hdr__navChev { opacity: 1; }
.hdr__navLink[aria-expanded="true"] { color: var(--ink); }
.hdr__navLink[aria-expanded="true"] .hdr__navChev { transform: rotate(180deg); opacity: 1; }
.hdr__navLink:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

/* Über dem Hero steht die Leiste hell auf dem Foto — der offene Punkt
   bleibt dort weiß, die Tafel darunter trägt ihr eigenes Weiß. */
.js .hdr--ghost:not(.is-scrolled) .hdr__navLink[aria-expanded="true"] { color: #fff; }

/* ── Menü-Knopf in der Kopfleiste ─────────────────────────────── */
/* Der Knopf gehört zu schmalen Screens. Unter 900px ist .hdr__nav
   ausgeblendet (Menüpunkte brächen um) und er ist die einzige Navigation;
   ab 900px trägt die waagrechte Leiste die Bereiche und der Burger
   verschwindet — siehe Medienabfrage unter dem Block. */
.hdr__menuBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2);
  color: var(--text);
  cursor: pointer;
  transition: border-color var(--t) var(--ease), color var(--t) var(--ease);
}
/* Muss NACH der display-Regel stehen, sonst überschreibt display das
   hidden-Attribut und der Knopf steht auch ohne Skript da. */
.hdr__menuBtn[hidden] { display: none; }
.hdr__menuBtn:hover { border-color: var(--ink); color: var(--ink); }
.hdr__menuBtn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
/* Ab der Breite, ab der die waagrechte Leiste steht, ist der Burger doppelt
   gemoppelt — dort navigiert die Leiste. */
@media (min-width: 900px) { .hdr__menuBtn, .hdr__menuBtn[hidden] { display: none; } }

.hdr__menuBars {
  position: relative;
  display: block;
  width: 1.125rem;
  height: 0.75rem;
}
.hdr__menuBars i {
  position: absolute;
  left: 0;
  width: 100%;
  height: 2px;
  background: currentColor;
  transition: transform var(--t) var(--ease), opacity var(--t) var(--ease);
}
.hdr__menuBars i:first-child { top: 1px; }
.hdr__menuBars i:last-child  { bottom: 1px; }
/* Offen: die beiden Balken werden zum Kreuz. */
.hdr__menuBtn[aria-expanded="true"] .hdr__menuBars i:first-child {
  transform: translateY(4px) rotate(45deg);
}
.hdr__menuBtn[aria-expanded="true"] .hdr__menuBars i:last-child {
  transform: translateY(-4px) rotate(-45deg);
}

/* ── Drilldown-Menü ───────────────────────────────────────────── */
.mnav {
  position: fixed;
  inset: 0;
  z-index: 120;
}
/* Wie beim Paket-Dialog: nach der Positionsregel, sonst gewinnt display
   gegen das hidden-Attribut. */
.mnav[hidden] { display: none; }

.mnav__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.mnav__panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  width: min(30rem, 100%);
  height: 100%;
  margin-right: auto;
  padding: var(--s-4) var(--s-5) var(--s-8);
  overflow-y: auto;
  /* Geometrie von main (Panel geht links auf, deshalb Kante und Schatten
     nach rechts), Farben aus der Hell-Umstellung — die Labels darin sind
     dunkel und stünden auf var(--ink) unlesbar. */
  background: var(--surface);
  border-right: 1px solid var(--line);
  box-shadow: 20px 0 60px rgba(0, 0, 0, .25);
}
.mnav__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--line);
}
.mnav__title {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-widest);
  text-transform: uppercase;
  color: var(--text-mute);
}
.mnav__close {
  flex: none;
  width: 2rem;
  height: 2rem;
  padding: 0;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2);
  color: var(--text);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  transition: border-color var(--t) var(--ease), color var(--t) var(--ease);
}
.mnav__close:hover { border-color: var(--ink); color: var(--ink); }
.mnav__close:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* Der Block, um dessen Mitte der Stapel atmet.
   Die Höhe ist in em ausgedrückt und wird deshalb per CSS-Transition
   bewegt — CSS rechnet Einheiten von sich aus um, eine Skript-Animation
   müsste sie erst in px zurücklesen.
   Der linke Innenabstand ist die Gasse für den Rückwärtspfeil. */
/* Die Gasse für den Rückwärtspfeil liegt als margin aussen, nicht als
   padding innen: absolut gesetzte Zeilen richten sich am Polsterrand aus,
   nicht am Inhaltsrand — ein padding-left verschöbe sie also gar nicht,
   sondern liesse den Pfeil bloss aus dem Panel herausragen. Aus demselben
   Grund darf hier kein senkrechtes padding stehen: es zöge bei
   border-box von der gesetzten Höhe ab. */
/* Auffangziel für den Fokus, wenn die fokussierte Zeile gerade geht —
   programmatisch gesetzt, deshalb ohne sichtbaren Rahmen. */
.mnav__stack:focus { outline: none; }
.mnav__stack {
  position: relative;
  margin: auto 0 auto 1.6em;
  font-size: clamp(.875rem, 4.4vw, 1.5rem);
  transition: height 300ms ease-out;
}

/* Zeilen liegen absolut auf dem Raster. Eine gehende Zeile nimmt damit
   keinen Platz mit — dahinter muss nichts umbrechen, und der Wechsel
   bleibt eine Überblendung statt eines Rücksprungs der ganzen Liste.
   Bewegt wird nur top: der Einzug hängt an der Tiefe des Eintrags, nicht
   daran, was offen ist, und ändert sich für eine Zeile daher nie. */
.mnav__row {
  position: absolute;
  transition: top 300ms var(--ease), left 300ms var(--ease);
}
.mnav__row.is-going { pointer-events: none; }

.mnav__label {
  position: relative;
  display: inline-block;
  max-width: 100%;
  padding: .14em .22em;
  background: none;
  border: 0;
  border-radius: .25em;
  font-family: var(--ff-body);
  font-size: inherit;
  font-weight: 500;
  line-height: 1.25;
  text-align: left;
  text-decoration: none;
  color: var(--text);
  cursor: pointer;
  transition: color var(--t) var(--ease), background-color var(--t) var(--ease);
}
.mnav__label:hover { background: rgba(0, 0, 0, .05); color: var(--ink); }
.mnav__label:focus-visible { outline: 2px solid var(--signal); outline-offset: 1px; }

/* Breadcrumb: dasselbe Wort in derselben Größe, nur grau. Die Strichstärke
   bleibt bewusst gleich — mit leichterem Schnitt würde die Beschriftung im
   Moment des Klicks ihre eigene Breite umbrechen. */
.mnav__row.is-trail .mnav__label { color: var(--text-mute); }
.mnav__row.is-trail .mnav__label:hover { color: var(--text-2); }

/* Nicht gelistete Länge: sichtbar, aber erkennbar nicht bestellbar —
   dasselbe gestrichelte Motiv wie .chip--off im Längen-Dialog.
   Der Strich ist ein Pseudo-Element, kein text-decoration: die Zeichen sind
   einzeln inline-block gesetzt, und dorthinein reicht keine Textdekoration
   des Elternelements. Grau allein würde ausserdem nicht genügen — so sehen
   Breadcrumb-Zeilen ebenfalls aus. */
.mnav__label[aria-disabled="true"] {
  color: var(--text-mute);
  opacity: .75;
  cursor: default;
}
.mnav__label[aria-disabled="true"]:hover {
  background: none;
  color: var(--text-mute);
}
.mnav__label[aria-disabled="true"] .mnav__chars { position: relative; }
.mnav__label[aria-disabled="true"] .mnav__chars::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 55%;
  border-top: 1px dashed currentColor;
  /* Kommt mit der Zeile, nicht vor ihr: sonst steht der Strich schon da,
     während die Zeichen darunter noch hereinskalieren. */
  opacity: 0;
  transition: opacity 160ms ease-out;
}
.mnav__row.is-in .mnav__label[aria-disabled="true"] .mnav__chars::after {
  opacity: 1;
  transition-duration: 300ms;
  transition-delay: 120ms;
}

/* Rückwärtspfeil in der Gasse links. Sein Zustand hängt an einer Klasse,
   nicht an einer Animation: er kippt um, während die Zeile stehen bleibt —
   genau der Fall, den eine laufende Animation nicht mehr neu auflöst. */
.mnav__arrow {
  position: absolute;
  inset-block: 0;
  right: 100%;
  display: flex;
  align-items: center;
  margin-right: .6em;
  opacity: 0;
  transform: translateX(-4px);
  transition: opacity 200ms ease-out, transform 200ms ease-out;
  pointer-events: none;
}
.mnav__arrow svg { width: .9em; height: .9em; }
.mnav__row.is-trail.is-in .mnav__arrow { opacity: 1; transform: none; }

/* Den Übergang trägt der Text. Jedes Zeichen skaliert und entschärft
   einzeln herein — und rückwärts, kürzer, wieder hinaus. */
.mnav__chars {
  display: inline-block;
  white-space: pre;
}
.mnav__char {
  display: inline-block;
  opacity: 0;
  transform: scale(0);
  filter: blur(4px);
  /* Hinaus ist ein Tween, keine Feder: der Ausklang einer Feder hielte die
     Zeile lange nach dem Verschwinden montiert. */
  transition: opacity 160ms cubic-bezier(.4, 0, 1, 1),
              transform 160ms cubic-bezier(.4, 0, 1, 1),
              filter 160ms cubic-bezier(.4, 0, 1, 1);
  transition-delay: calc((var(--cn) - 1 - var(--ci)) * 8ms);
}
.mnav__row.is-in .mnav__char {
  opacity: 1;
  transform: none;
  filter: blur(0);
  transition: opacity 420ms cubic-bezier(.34, 1.3, .64, 1),
              transform 420ms cubic-bezier(.34, 1.3, .64, 1),
              filter 420ms cubic-bezier(.34, 1.3, .64, 1);
  transition-delay: calc(var(--ci) * 15ms);
}

/* Der globale Reduced-Motion-Block oben kürzt nur die Dauer. Die Staffelung
   steckt hier aber in der Verzögerung: unangetastet erschienen die Zeichen
   weiterhin einzeln nacheinander, bei langen Namen über fast eine halbe
   Sekunde. Wer weniger Bewegung angefordert hat, bekommt die Zeile am Stück. */
@media (prefers-reduced-motion: reduce) {
  .mnav__char,
  .mnav__row.is-in .mnav__char,
  .mnav__label[aria-disabled="true"] .mnav__chars::after,
  .mnav__row.is-in .mnav__label[aria-disabled="true"] .mnav__chars::after {
    transition-delay: 0s !important;
  }
}

/* ── Produktkacheln: Hover-Fläche und eingeblendeter Button ───── */
/* Gilt für alle Kacheln — Slider wie Paket-Raster. Voraussetzung ist,
   dass jedes Produktbild einen Alphakanal hat, sonst stünde es als
   weißes Rechteck auf dem grauen Grund. Sicherzustellen mit
   scripts/cutout.py; geprüft wird es in der CI. */
.tile__link {
  /* Polster dauerhaft, nicht erst beim Hover: sonst springt der Inhalt. */
  padding: var(--s-4);
  border-radius: var(--r-4);
  background: transparent;
  transition: background var(--t) var(--ease);
}
.tile__link:hover,
.tile__link:focus-visible {
  background: var(--bg);
}

/* Der Button erscheint erst beim Hover. Über opacity statt display, damit
   der reservierte Platz bleibt und die Kacheln nicht springen. */
.pkg__list .tile__more {
  opacity: 0;
  transition: opacity var(--t) var(--ease);
}
.pkg__list .tile__link:hover .tile__more,
.pkg__list .tile__link:focus-visible .tile__more {
  opacity: 1;
}

/* Ohne Hover (Touch) gäbe es keinen Weg, den Hinweis je zu sehen. */
@media (hover: none) {
  .pkg__list .tile__more { opacity: 1; }
}


/* ── Produktseiten ────────────────────────────────────────────── */
/* Eine Seite je Produkt der Startseite (build.mjs → renderProduct).
   Aufbau: Kopf mit Bild und Kaufweg, danach Abschnitte in fester
   Reihenfolge — Daten, Technik, Teile, Messung, Fragen. Jeder Abschnitt
   fällt weg, wenn es dafür keine Angaben gibt; die Abstände dürfen
   deshalb nirgends an einer bestimmten Nachbarschaft hängen. */

.pdp { background: var(--surface); }

/* Die Kopfleiste schwebt — ohne diesen Vorlauf läge sie auf dem
   Brotkrumenpfad. Gleicher Wert wie bei den Rechtsseiten. */
.pdp__crumbs {
  padding-top: calc(var(--s-12) + 5rem);
  padding-bottom: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}
.pdp__crumbs a { color: var(--text-mute); text-decoration: none; }
.pdp__crumbs a:hover { color: var(--text); }
.pdp__crumbs [aria-current] { color: var(--text); }

.pdp__hero { padding-bottom: var(--s-16); }
.pdp__heroInner {
  display: grid;
  gap: var(--s-8);
  align-items: start;
}

/* Ab Desktop: die Galerie ist nicht mehr Teil des Rasters, sondern füllt
   full-bleed die linke Viewporthälfte — vom linken Rand bis unter die
   Detailbox. Die Box liegt darüber (z-index), der Slider bleibt hinter ihr
   bedienbar. Deshalb steht das Raster hier auf einer leeren ersten Spalte:
   sie hält nur den Platz frei, in dem die absolut gesetzte Galerie liegt. */
@media (min-width: 960px) {
  .pdp__hero {
    position: relative;
    overflow: hidden;
    padding-top: var(--s-8);
  }
  .pdp__heroInner {
    grid-template-columns: minmax(0, 1fr) minmax(360px, 30rem);
    gap: var(--s-12);
    min-height: 38rem;
    align-items: center;
  }
  .pdp__heroBody { grid-column: 2; z-index: 1; }
}

/* Galerie: schlichte weiße Fläche, kein Verlauf. `contain`, weil die Fotos
   unterschiedliche Seitenverhältnisse haben und nichts angeschnitten werden darf. */
.pdp__heroMedia {
  position: relative;
  border-radius: 16px;
  background: #fff;
  overflow: hidden;
}
.pdp__gallery { position: relative; width: 100%; height: 100%; }
.pdp__slidesViewport { width: 100%; height: 100%; overflow: hidden; }

/* Filmstrip: die Bilder liegen nebeneinander, der Streifen wird verschoben.
   Dadurch schaut das nächste Bild rechts hinter der Detailbox hervor. */
.pdp__slides {
  display: flex;
  height: 100%;
  transition: transform .55s var(--ease);
  will-change: transform;
}
.pdp__slide {
  flex: 0 0 var(--pdp-slide-w, 100%);
  width: var(--pdp-slide-w, 100%);
  height: 100%;
  object-fit: contain;
  padding: var(--s-6);
}
/* Ohne Slider (ein Bild) trägt die Fläche das Seitenverhältnis. */
.pdp__gallery:not(.is-slider) .pdp__slidesViewport { aspect-ratio: 4 / 3; }
.pdp__gallery.is-slider .pdp__slidesViewport { aspect-ratio: 4 / 3; }
/* Ab Desktop: Galerie full-bleed über die ganze Fläche, hinter der Detailbox.
   Steht bewusst NACH den Basisregeln, damit `position` nicht zurückfällt. */
@media (min-width: 960px) {
  .pdp__heroMedia {
    position: absolute;
    inset: 0;
    width: 100%;
    border-radius: 0;
    z-index: 0;
  }
  .pdp__gallery .pdp__slidesViewport { aspect-ratio: auto; height: 100%; min-height: 34rem; }
  /* Eine Bildbreite ≈ sichtbarer Bereich links neben der Detailbox; das
     nächste Bild ragt dadurch rechts hinter die Box. */
  .pdp__slides { --pdp-slide-w: 58vw; }
  .pdp__slide { padding: var(--s-10); }
}

/* Bedienleiste unten links: Pfeile + durchgehender Fortschrittsbalken. */
.pdp__galleryUi {
  position: absolute;
  left: var(--s-6);
  right: var(--s-6);
  bottom: var(--s-6);
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  pointer-events: none;
}
.pdp__galleryUi > * { pointer-events: auto; }
@media (min-width: 960px) {
  .pdp__galleryUi {
    /* Bündig mit der Inhaltsspalte (.wrap-Rinne), Balken endet vor der Box. */
    left: max(var(--gutter), calc((100% - var(--maxw)) / 2 + var(--gutter)));
    right: calc(100% - var(--pdp-ui-w, 56vw));
    bottom: var(--s-10);
  }
}
.pdp__progress {
  flex: 1 1 auto;
  height: 2px;
  background: var(--line);
  overflow: hidden;
  min-width: 4rem;
}
.pdp__progressBar {
  display: block;
  height: 100%;
  background: var(--ink);
  transition: transform .55s var(--ease);
}

/* Runde Pfeile in der Bedienleiste (wie im Referenzbild) */
.pdp__navBtn {
  flex: 0 0 auto;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: 999px;
  display: grid;
  place-items: center;
  background: var(--ink);
  color: var(--surface);
  border: 0;
  cursor: pointer;
  font-size: 1.35rem;
  line-height: 1;
  transition: transform var(--t) var(--ease), background var(--t) var(--ease);
}
.pdp__navBtn:hover { transform: translateY(-1px); background: var(--ink-3); }

/* Detail-Karte rechts (schwebt neben dem großen Bild). */
@media (min-width: 960px) {
  .pdp__heroBody {
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: 16px;
    padding: var(--s-8);
    box-shadow: 0 10px 40px rgba(0, 0, 0, .06);
    position: sticky;
    top: var(--s-8);
  }
}

/* „Konfigurierbar"-Chip neben dem Titel */
.pdp__cfgBadge {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  margin: 0 0 var(--s-4);
  padding: .32rem .7rem;
  border-radius: 999px;
  background: var(--bg);
  border: 1px solid var(--line);
  font-family: var(--ff-mono);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text);
}
.pdp__cfgBadge__dot,
.btn--configure__dot {
  width: .95rem;
  height: .95rem;
  border-radius: 999px;
  flex: 0 0 auto;
  background: conic-gradient(from 0deg, #ff5f6d, #ffc371, #47e0a0, #4d9fff, #a06bff, #ff5f6d);
}

/* Startbuilds: waagerechte Kachelreihe unter dem Hero. Nutzt das Rail-Muster
   der Seite; jede Kachel öffnet den Konfigurator mit ihrer Konfiguration. */
.pdp__builds { padding-top: var(--s-4); }
.buildTile {
  flex: 0 0 auto;
  width: 17rem;
  max-width: 78vw;
}
.buildTile__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  text-decoration: none;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  transition: border-color var(--t) var(--ease), transform var(--t) var(--ease),
              box-shadow var(--t) var(--ease);
}
.buildTile__link:hover {
  border-color: var(--ink);
  transform: translateY(-2px);
  box-shadow: 0 8px 26px rgba(0, 0, 0, .08);
}
.buildTile__media {
  display: block;
  background: #fff;
  padding: var(--s-4);
}
.buildTile__media img {
  display: block;
  width: 100%;
  height: 8.5rem;
  object-fit: contain;
}
.buildTile__body {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-4);
  border-top: 1px solid var(--line);
}
.buildTile__name {
  font-weight: 600;
  line-height: 1.3;
  overflow-wrap: anywhere;
}
.buildTile__cta {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}
.buildTile__link:hover .buildTile__cta { color: var(--ink); }

/* Prominenter Konfigurieren-Button (volle Breite in der Karte). */
.btn--configure {
  width: 100%;
  justify-content: flex-start;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-6);
  margin: 0 0 var(--s-4);
  text-transform: none;
  letter-spacing: normal;
  font-family: var(--ff-display);
  font-size: 1rem;
}
.btn--configure .btn__arrow { margin-left: auto; }
/* Kaufknopf in der Karte als Zweitaktion: volle Breite, Umriss. */
@media (min-width: 960px) {
  .pdp__hero--configurable .pdp__heroBody .pdp__price ~ .btn:not(.btn--configure) {
    width: 100%;
    justify-content: center;
    background: var(--surface);
    color: var(--ink);
    border-color: var(--line-strong);
  }
  .pdp__hero--configurable .pdp__heroBody .pdp__price ~ .btn:not(.btn--configure):hover {
    background: var(--bg);
    border-color: var(--ink);
  }
}

.pdp__title {
  font-size: clamp(2rem, 5.5vw, 3.25rem);
  margin-bottom: var(--s-3);
}
.pdp__claim {
  font-size: 1.25rem;
  line-height: 1.3;
  color: var(--text);
  margin: 0 0 var(--s-5);
}
.pdp__full {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 var(--s-5);
}
.pdp__lead {
  color: var(--text-2);
  font-size: 1.0625rem;
  margin: 0 0 var(--s-8);
  max-width: 52ch;
}
.pdp__price {
  font-family: var(--ff-display);
  font-weight: 800;
  font-size: 1.75rem;
  line-height: 1;
  margin: 0 0 var(--s-6);
}
.pdp__priceNote {
  font-size: .8125rem;
  color: var(--text-mute);
  margin: var(--s-4) 0 0;
  max-width: 46ch;
}

.pdp__sec {
  padding: var(--s-16) 0;
  border-top: 1px solid var(--line);
}
.pdp__sec--source { background: var(--bg); }
.pdp__secTitle {
  font-size: clamp(1.375rem, 3vw, 2rem);
  margin-bottom: var(--s-6);
}
.pdp__note {
  color: var(--text-mute);
  font-size: .875rem;
  margin: 0 0 var(--s-6);
  max-width: 60ch;
}
.pdp__back { color: var(--text); text-decoration-color: var(--line-strong); }

/* Beschriftung links, Wert rechts — dieselbe Form wie im Impressum,
   damit Datenblöcke überall gleich gelesen werden. */
.pdp__table {
  width: 100%;
  border-collapse: collapse;
  max-width: 46rem;
}
.pdp__table th,
.pdp__table td {
  text-align: left;
  vertical-align: top;
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}
.pdp__table tbody th {
  width: 40%;
  padding-right: var(--s-5);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 400;
}
.pdp__table td { color: var(--text); }

.pdp__table--cmp thead th {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 400;
  border-bottom: 1px solid var(--line-strong);
}
.pdp__table--cmp tbody th { width: 34%; }
.pdp__table--cmp td { width: 33%; padding-right: var(--s-4); }
.pdp__cellStrong { font-weight: 600; }

.pdp__highlights {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
}
.pdp__highlightNum {
  display: block;
  font-family: var(--ff-mono);
  font-size: .75rem;
  letter-spacing: var(--ls-wide);
  color: var(--text-faint);
  margin-bottom: var(--s-3);
}
.pdp__highlight h3 { font-size: 1rem; margin-bottom: var(--s-2); }
.pdp__highlight p { margin: 0; color: var(--text-2); font-size: .9375rem; }

.pdp__features {
  display: grid;
  gap: var(--s-10);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.pdp__feature h3 { font-size: 1.125rem; margin-bottom: var(--s-3); }
.pdp__feature p { margin: 0; color: var(--text-2); }
.pdp__bullets {
  list-style: none;
  margin: var(--s-4) 0 0;
  padding: 0;
  color: var(--text-2);
  font-size: .9375rem;
}
.pdp__bullets li {
  position: relative;
  padding-left: var(--s-5);
  margin-bottom: var(--s-2);
}
/* Kein list-style: der Strich sitzt auf der Grundlinie der ersten Zeile
   und läuft bei mehrzeiligen Punkten nicht mit nach unten. */
.pdp__bullets li::before {
  content: "—";
  position: absolute;
  left: 0;
  color: var(--text-faint);
}

.pdp__metrics {
  display: grid;
  gap: var(--s-6);
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  margin-bottom: var(--s-10);
}
.pdp__metricValue {
  display: block;
  font-family: var(--ff-display);
  font-weight: 800;
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  line-height: 1;
}
.pdp__metricLabel {
  display: block;
  margin-top: var(--s-2);
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}

/* Zwanzig Einzelschüsse. Als Liste, nicht als Tabelle: es ist eine
   Messreihe ohne Spaltenlogik, und in schmalen Fenstern bricht das
   Raster sauber um. */
.pdp__shots {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 1px;
  grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
  background: var(--line);
  border: 1px solid var(--line);
}
.pdp__shot {
  background: var(--surface);
  padding: var(--s-3) var(--s-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2) var(--s-3);
  align-items: baseline;
}
.pdp__shotNo {
  flex: 1 0 100%;
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-faint);
}
.pdp__shotV { font-weight: 600; }
.pdp__shotE { color: var(--text-mute); font-size: .875rem; }

.pdp__box {
  list-style: none;
  margin: 0;
  padding: 0;
  max-width: 46rem;
}
.pdp__box li {
  padding: var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}

.pdp__faq { max-width: 52rem; }
.pdp__q {
  border-bottom: 1px solid var(--line);
}
.pdp__q summary {
  cursor: pointer;
  padding: var(--s-4) 0;
  font-weight: 600;
  list-style: none;
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
}
.pdp__q summary::-webkit-details-marker { display: none; }
.pdp__q summary::after {
  content: "+";
  color: var(--text-mute);
  font-family: var(--ff-mono);
  flex: none;
}
.pdp__q[open] summary::after { content: "–"; }
.pdp__q summary:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }
.pdp__q p {
  margin: 0 0 var(--s-5);
  color: var(--text-2);
  max-width: 60ch;
}

/* Die Kacheln stammen aus tileHtml und setzen eine feste Breite in einer
   waagrechten Rail voraus. Hier stehen sie im Raster — Breite deshalb
   zurücknehmen, sonst bleibt rechts eine Lücke. */
.pdp__related {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
}
.pdp__related .tile { width: auto; flex: initial; }

/* Die dreispaltige Vergleichstabelle ist die einzige, die auf schmalen
   Geräten nicht in den Satzspiegel passt. Sie rollt deshalb in ihrem
   eigenen Rahmen — die Seite selbst bleibt schmal, sonst stünden Rand
   und Inhalt aller anderen Abschnitte plötzlich woanders. */
.pdp__scroll {
  overflow-x: auto;
  max-width: 46rem;
}
.pdp__scroll .pdp__table { min-width: 24rem; }
@media (max-width: 520px) {
  .pdp__table--cmp td { padding-right: var(--s-2); }
}

/* Der Modellname im Vergleich führt auf die Produktseite, wo es sie gibt.
   Bewusst ohne dauerhafte Unterstreichung: in der Vergleichstabelle stehen
   sechs davon nebeneinander, unterstrichen zerfiele die Kopfzeile. */
.cmp__nameLink {
  text-decoration: none;
  color: inherit;
}
.cmp__nameLink:hover { text-decoration: underline; text-underline-offset: 3px; }
.cmp__nameLink:focus-visible { outline: 2px solid var(--signal); outline-offset: 3px; }

/* Weg von der Bereichsvorstellung auf die Produktseite. Steht unter der
   Längenwahl, weil davor der Kaufweg kommt — erst kaufen können, dann
   nachlesen. */
.split__more {
  margin: var(--s-6) 0 0;
  font-size: .9375rem;
}

/* Die Längenwahl steht auf der Produktseite im Kopf statt in einem Dialog.
   Dort ist sie der Kaufweg und braucht denselben Abstand nach oben wie
   sonst der Preis. */
.pdp__heroBody .picker__label { margin-top: var(--s-2); }
.pdp__heroBody .picker__note { max-width: 46ch; }


/* Eigenständige Konfigurator-Seite (Full-Width, ohne Store-Chrome).
   Schlanke Leiste oben, darunter der Konfigurator über die ganze Fläche. */
.cfgpage {
  margin: 0;
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: #eaeaea;
}
.cfgpage__bar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: 0 var(--s-4);
  height: 3.25rem;
  background: #0d0d0e;
  color: #fff;
}
.cfgpage__back {
  color: #fff;
  text-decoration: none;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
}
.cfgpage__back:hover { text-decoration: underline; }
.cfgpage__title {
  margin-left: auto;
  opacity: .7;
  font-size: .95rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.cfgpage__main { flex: 1 1 auto; min-height: 0; }
.cfgpage__frame {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

/* ═══════════════════════════════════════════════════════════════
   404 — unbekannte Adresse
   ───────────────────────────────────────────────────────────────
   Bekommt planmäßig den Verkehr aus rund 7.600 abgeräumten Adressen
   des alten Shopify-Katalogs ab (docs/specs/altlasten-shopify-urls.md).
   Deshalb keine Sackgasse: die Sprachliste führt weiter, und zwar in
   allen 22 Sprachen, weil nicht absehbar ist, wer hier landet.
   ═══════════════════════════════════════════════════════════════ */

.nf {
  min-height: 100vh;
  min-height: 100svh;
  margin: 0;
  display: grid;
  place-items: center;
  padding: var(--s-8) var(--gutter);
  background: var(--ink);
  color: var(--on-dark);
}

.nf__box { max-width: 46rem; text-align: center; }

.nf__logo { height: 40px; width: auto; margin-bottom: var(--s-12); }

.nf__code {
  margin: 0;
  font-family: var(--ff-display);
  font-size: clamp(4rem, 18vw, 9rem);
  line-height: .9;
  letter-spacing: var(--ls-wide);
  color: var(--on-dark);
}

.nf__text {
  margin: var(--s-5) 0 var(--s-12);
  font-family: var(--ff-body);
  font-size: 1.0625rem;
  color: var(--on-dark-2);
}

.nf__langs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--s-2) var(--s-4);
  padding-top: var(--s-8);
  border-top: 1px solid var(--line-dark);
}

.nf__langs a {
  font-family: var(--ff-mono);
  font-size: .8125rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark-mute);
  text-decoration: none;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-2);
  transition: color .18s var(--ease), background-color .18s var(--ease);
}

.nf__langs a:hover { color: var(--on-dark); background: var(--ink-3); }
.nf__langs a:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ═══════════════════════════════════════════════════════════════
   Einwilligung zur Statistik
   ───────────────────────────────────────────────────────────────
   Erscheint nur, wenn in data/company.json eine Measurement-ID steht.
   Die beiden Knöpfe sind bewusst gleich groß und stehen nebeneinander:
   Ablehnen darf nicht mühsamer sein als Erlauben, sonst ist die
   Einwilligung nach DSGVO nicht wirksam. Unterschieden werden sie nur
   durch die Füllung, nicht durch Größe, Ort oder Zahl der Klicks.
   ═══════════════════════════════════════════════════════════════ */

.cns {
  position: fixed;
  z-index: 90;
  inset: auto 0 0 0;
  padding: var(--s-4) var(--gutter);
  background: var(--ink-2);
  border-top: 1px solid var(--line-dark);
  color: var(--on-dark-2);
  animation: cns-auf .28s var(--ease) both;
}

@keyframes cns-auf { from { transform: translateY(100%); } to { transform: none; } }
@media (prefers-reduced-motion: reduce) { .cns { animation: none; } }

.cns__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-4) var(--s-8);
}

.cns__body { flex: 1 1 28rem; }

.cns__title {
  margin: 0 0 var(--s-2);
  font-family: var(--ff-display);
  font-size: .875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark);
}

.cns__text {
  margin: 0;
  font-family: var(--ff-body);
  font-size: .875rem;
  line-height: 1.5;
  max-width: 78ch;
}

.cns__more { color: var(--on-dark); text-underline-offset: 3px; }

.cns__actions { display: flex; gap: var(--s-3); flex: 0 0 auto; }

.cns__btn {
  /* Gleiche Grundmaße für beide — der einzige Unterschied ist die Füllung. */
  min-width: 9.5rem;
  padding: var(--s-3) var(--s-5);
  font-family: var(--ff-display);
  font-size: .75rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark);
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2);
  cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease);
}

.cns__btn:hover { background: var(--ink-3); }
.cns__btn:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

.cns__btn--yes { background: var(--surface); color: var(--text); border-color: var(--surface); }
.cns__btn--yes:hover { background: var(--bg-alt); color: var(--text); }

@media (max-width: 640px) {
  .cns__actions { width: 100%; }
  .cns__btn { flex: 1 1 0; min-width: 0; }
}

/* Widerruf in der Fußzeile — sieht aus wie die Links daneben, ist aber ein
   Knopf, weil er schaltet statt zu navigieren. */
.ftr__revoke {
  padding: 0;
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
  text-align: left;
}

.ftr__revoke:hover { text-decoration: underline; }
.ftr__revoke:focus-visible { outline: 2px solid var(--signal); outline-offset: 2px; }

/* ── Serienseiten ─────────────────────────────────────────────── */
/* Eine Seite je Produktreihe (build.mjs → renderSeries). Sie verkauft
   nichts selbst, sondern erklärt die Plattform unter mehreren Modellen und
   führt von dort auf deren Produktseiten.

   Der Wechsel der Flächen folgt der Startseite: Sachliches steht auf Weiß,
   Erzählendes auf Schwarz, dazwischen der Grundton als Zäsur. Neue Farben
   kommen keine dazu — die Reihe hatte im alten Shop Neon in Blau, Gelb und
   Rot, das hier nichts zu suchen hat. */

.ser { background: var(--surface); }

/* ── Kopf ─────────────────────────────────────────────────────── */
/* Wie der Hero der Startseite: die Kopfleiste schwebt darüber (height:0),
   der obere Innenabstand muss sie selbst freihalten. */
.ser__hero {
  position: relative;
  overflow: hidden;
  background: var(--ink-true);
  color: var(--on-dark);
  padding: var(--s-24) 0 var(--s-16);
}
@media (min-width: 900px) {
  .ser__hero { padding: 9rem 0 var(--s-20); min-height: 62svh; display: flex; align-items: center; }
}

.ser__heroImg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Das Motiv liegt diagonal im Bild; der Zuschnitt hält den Receiver in
     der rechten Hälfte, wo der Scrim am hellsten ist. */
  object-position: 70% 50%;
}

/* Links dunkel für den Text, rechts fast klar für das Motiv — dieselbe
   Aufteilung wie im Hero der Startseite, nur ohne Lichtkegel: das Motiv
   ist freigestellt und bringt seinen eigenen Grund mit. */
.ser__heroScrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(180deg, rgba(0, 0, 0, .55) 0%, transparent 26%,
                    transparent 62%, rgba(0, 0, 0, .92) 100%),
    linear-gradient(90deg, rgba(0, 0, 0, .92) 0%, rgba(0, 0, 0, .78) 38%,
                    rgba(0, 0, 0, .42) 62%, rgba(0, 0, 0, .16) 100%);
}
@media (max-width: 899px) {
  .ser__heroScrim {
    background: linear-gradient(180deg, rgba(0, 0, 0, .84) 0%, rgba(0, 0, 0, .62) 42%,
                                rgba(0, 0, 0, .95) 100%);
  }
}

.ser__heroInner { position: relative; z-index: 1; width: 100%; }
.ser__heroInner > .eyebrow { margin-bottom: var(--s-4); }

/* Der Brotkrumenpfad steht im Kopf statt darüber: auf dunklem Grund
   braucht er keine eigene Bahn, und die Seite beginnt mit dem Motiv. */
.ser__crumbs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  align-items: center;
  margin-bottom: var(--s-6);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark-mute);
}
.ser__crumbs a { color: var(--on-dark-mute); text-decoration: none; }
.ser__crumbs a:hover { color: var(--on-dark); }
.ser__crumbs [aria-current] { color: var(--on-dark-2); }

.ser__title {
  font-size: clamp(2.25rem, 6vw, 4rem);
  max-width: 18ch;
  margin-bottom: var(--s-4);
  text-shadow: 0 2px 24px rgba(0, 0, 0, .55);
}
.ser__claim {
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: clamp(1rem, 2vw, 1.25rem);
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--on-dark-2);
  margin: 0 0 var(--s-5);
}
.ser__lead {
  max-width: 48ch;
  margin: 0 0 var(--s-8);
  color: var(--on-dark-2);
  font-size: 1.0625rem;
}

/* ── Abschnitte ───────────────────────────────────────────────── */
.ser__sec { padding: var(--s-16) 0; border-top: 1px solid var(--line); }
.ser__sec--tone { background: var(--bg); }
.ser__sec--source { background: var(--bg); }
/* Regel für die ganze Seite: wo die Aufnahmen auf schwarzem Grund stehen,
   steht auch die Sektion auf Schwarz. Sonst schwimmt ein schwarzer Kasten
   in einer hellen Fläche und die Sektion zerfällt in Bild und Text statt
   eine Fläche zu sein. Betrifft Kopf, Material, Antrieb, Herkunft und
   Fertigung; hell bleiben die Abschnitte mit freigestellten Produkten und
   den beiden Detailaufnahmen auf hellem Grund.

   Diese Flaechen stehen auf echtem Schwarz, nicht auf --ink: nachgemessen
   sind 88-100% des Bildrands unter #0a0a0a, das Motiv laeuft also auf #000
   aus. Gegen #0d0d0e zeichnet sich dabei die Bildkante als hellerer Rahmen
   ab. Hell bleiben Rundgang und Auslegungen: dort stehen die Aufnahmen auf
   hellem Grund bzw. die Renders sind freigestellt. */
.ser__sec--dark {
  background: var(--ink-true);
  color: var(--on-dark);
  border-top-color: var(--line-dark);
}
.ser__sec--dark + .ser__sec { border-top: 0; }

/* Auf Schwarz führen dieselben Bausteine ihre helle Fassung — Trennlinien,
   Nebentexte und der Umriss der Elementkacheln. */
.ser__sec--dark h3 { color: var(--on-dark); }
.ser__sec--dark .ser__el p,
.ser__sec--dark .ser__claim2 p,
.ser__sec--dark .ser__originText,
.ser__sec--dark .ser__tourItem p { color: var(--on-dark-2); }
.ser__sec--dark .ser__note { color: var(--on-dark-mute); }
.ser__sec--dark .ser__elBox { border-color: var(--on-dark); }
.ser__sec--dark .ser__elNum { color: var(--on-dark-2); }
.ser__sec--dark .ser__claims { border-top-color: var(--line-dark-2); }
.ser__sec--dark .ser__quote { border-left-color: var(--line-dark-2); }
.ser__sec--dark .ser__quote figcaption { color: var(--on-dark-mute); }

/* Die Sektion mit dem Bildband beginnt mit dem Motiv statt mit Weißraum:
   das Band ist der Auftakt der Sektion, nicht ein Streifen davor. */
.ser__sec--band { padding-top: 0; }
.ser__sec--band .wrap { padding-top: var(--s-16); }

/* Der Konfigurator der Reihe. Hell wie die Auslegungen darueber: die
   Renders sind freigestellt, ein schwarzer Grund haette hier nichts zu
   kaschieren. Der Knopf steht allein statt neben einem Preis — was das
   Ergebnis kostet, entscheidet sich erst im Konfigurator. */
.ser__cfg .ser__secLead { margin-bottom: var(--s-2); }
.ser__cfgModel {
  margin: 0 0 var(--s-6);
  font-family: var(--ff-mono);
  font-size: .8125rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}
/* Der Knopf kommt von der Produktseite, wo er die schmale Detailspalte
   fuellt (width:100%). Hier steht er in der vollen Seitenbreite und muss
   auf seine Textbreite zurueck, sonst ist er ein 1200px langer Balken. */
.ser__cfg .btn--configure { width: auto; }

.ser__cfgBuildsHead { margin-top: var(--s-12); }
.ser__cfgBuildsTitle {
  font-family: var(--ff-display);
  font-size: 1.0625rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}

.ser__secTitle { font-size: clamp(1.5rem, 3.4vw, 2.25rem); margin-bottom: var(--s-4); }
.ser__secLead {
  max-width: 60ch;
  margin: 0 0 var(--s-10);
  color: var(--text-2);
  font-size: 1.0625rem;
}
.ser__sec--dark .ser__secLead { color: var(--on-dark-2); }
.ser__note {
  margin: var(--s-6) 0 0;
  max-width: 60ch;
  font-size: .875rem;
  color: var(--text-mute);
}

/* ── Auslegungen ──────────────────────────────────────────────── */
/* Drei Spalten, rahmenlos wie die Produktkacheln: die Trennung übernimmt
   eine Haarlinie zwischen den Spalten, keine Karte. */
.ser__variants {
  display: grid;
  gap: var(--s-10) var(--s-12);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
}
/* Rahmenlos und ohne Trennlinien — wie die Produktkacheln der Startseite.
   Trennlinien hätten die Spalten unterschiedlich breit gemacht (die äußeren
   ohne Innenabstand zur Gutterflucht), und schon ein paar Pixel Unterschied
   verschieben die Bildkästen der drei Karten gegeneinander. */
.ser__variant { display: flex; flex-direction: column; }

.ser__variantRole {
  font-family: var(--ff-display);
  font-weight: 900;
  font-size: .875rem;
  letter-spacing: var(--ls-widest);
  color: var(--text-mute);
  margin: 0 0 var(--s-4);
}
.ser__variantMedia { display: block; aspect-ratio: 4 / 3; }
.ser__variantMedia img { width: 100%; height: 100%; object-fit: contain; }
.ser__variantName { font-size: 1.375rem; margin: var(--s-4) 0 var(--s-2); }
.ser__variantName a { text-decoration: none; }
.ser__variantName a:hover { text-decoration: underline; text-underline-offset: 3px; }
.ser__variantModel {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  margin: 0 0 var(--s-4);
}
.ser__variantText { color: var(--text-2); margin: 0 0 var(--s-6); font-size: .9375rem; }

/* Beschriftung über dem Wert statt daneben: in einer schmalen Spalte
   bliebe für zwei Sätze nebeneinander kein Platz. */
/* margin-top:auto — Merkmale, Preis und Weg zur Produktseite stehen in allen
   drei Karten auf gleicher Höhe, auch wenn die Beschreibungen darüber
   unterschiedlich lang sind. */
.ser__variantSpecs { margin: auto 0 var(--s-6); display: grid; gap: var(--s-3); }
.ser__variantSpecs div { border-top: 1px solid var(--line); padding-top: var(--s-2); }
.ser__variantSpecs dt {
  font-family: var(--ff-mono);
  font-size: .625rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}
.ser__variantSpecs dd { margin: 2px 0 0; font-size: .9375rem; }

.ser__variantPrice {
  font-family: var(--ff-display);
  font-weight: 800;
  font-size: 1.375rem;
  line-height: 1;
  margin: 0 0 var(--s-4);
}
.ser__variantCta {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-family: var(--ff-mono);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 3px;
  transition: border-color var(--t) var(--ease), gap var(--t) var(--ease);
}
.ser__variantCta:hover { border-color: var(--ink); gap: var(--s-3); }

/* ── Vergleich der drei ───────────────────────────────────────── */
/* Auf schmalen Screens läuft die Tabelle waagrecht — umbauen zu Karten
   hieße, dieselben Werte ein zweites Mal zu formen, und die Karten stehen
   direkt darüber schon. */
.ser__tableWrap { overflow-x: auto; }
.ser__table { width: 100%; border-collapse: collapse; min-width: 34rem; }
.ser__table th,
.ser__table td {
  text-align: left;
  vertical-align: top;
  padding: var(--s-3) var(--s-4) var(--s-3) 0;
  border-bottom: 1px solid var(--line);
}
.ser__table thead th {
  font-family: var(--ff-body);
  font-weight: 700;
  font-size: .9375rem;
  text-transform: none;
  letter-spacing: 0;
  border-bottom: 1px solid var(--line-strong);
}
.ser__table tbody th {
  width: 22%;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
  font-weight: 400;
}
.ser__table td { width: 26%; font-size: .9375rem; }
.ser__cell--empty { color: var(--text-faint); }

/* ── Material: Elementkacheln ─────────────────────────────────── */
.ser__material { display: grid; gap: var(--s-12); align-items: start; }
@media (min-width: 1000px) {
  .ser__material { grid-template-columns: 1.6fr 1fr; gap: var(--s-16); }
}
.ser__materialMedia { margin: 0; }
.ser__materialMedia img { width: 100%; height: auto; }

.ser__elements {
  list-style: none;
  margin: 0 0 var(--s-12);
  padding: 0;
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
/* Feste zwei Spalten, sobald Platz ist: auto-fit ergab in der linken
   Textspalte drei nebeneinander und ein viertes allein darunter. Vier
   Werkstoffe gehören als 2x2 zusammen. */
@media (min-width: 560px) {
  .ser__elements { grid-template-columns: repeat(2, 1fr); }
}
/* Die alte Seite zeigte hier Bilder aus dem Periodensystem. Gezeichnet
   statt fotografiert: Umriss, Ordnungszahl, Symbol — dieselbe Monospace,
   die auf der Seite ohnehin alle Kennzahlen trägt. */
.ser__elBox {
  display: block;
  width: 3.75rem;
  height: 3.75rem;
  margin-bottom: var(--s-4);
  padding: var(--s-2);
  border: 2px solid var(--text);
  border-radius: var(--r-8);
  font-family: var(--ff-mono);
  line-height: 1;
}
.ser__elNum { display: block; font-size: .625rem; color: var(--text-2); }
.ser__elSym {
  display: block;
  margin-top: .35rem;
  font-size: 1.5rem;
  font-weight: 700;
  letter-spacing: -0.02em;
}
.ser__elName { font-size: 1rem; margin-bottom: var(--s-2); }
.ser__el p { margin: 0; color: var(--text-2); font-size: .9375rem; }

.ser__claims {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  border-top: 1px solid var(--line-strong);
  padding-top: var(--s-8);
}
.ser__claim2 h3 { font-size: 1.0625rem; margin-bottom: var(--s-2); }
.ser__claim2 p { margin: 0; color: var(--text-2); font-size: .9375rem; }

/* ── Antrieb und Steuerung (dunkel) ───────────────────────────── */
.ser__drive {
  display: grid;
  gap: var(--s-12);
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.ser__driveItem img {
  width: 100%;
  max-width: 22rem;
  height: auto;
  margin-bottom: var(--s-6);
}
.ser__driveItem h3 { font-size: 1.25rem; margin-bottom: var(--s-3); color: var(--on-dark); }
.ser__driveItem p { margin: 0; color: var(--on-dark-2); }

/* ── Rundgang ─────────────────────────────────────────────────── */
.ser__tour { display: grid; gap: var(--s-10); }
.ser__tour--media {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  margin-bottom: var(--s-12);
}
/* Die vier Punkte ohne Aufnahme laufen schmaler: sie tragen weniger
   Gewicht als die drei mit Bild und sollen es auch zeigen. */
.ser__tour:not(.ser__tour--media) {
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  border-top: 1px solid var(--line);
  padding-top: var(--s-10);
}
/* Fester Kasten statt Eigenhöhe: die drei Aufnahmen haben unterschiedliche
   Seitenverhältnisse (Detailfotos 16:9, Produktaufnahme quadratisch) und
   sonst stünden die Beschriftungen darunter auf drei Höhen. */
.ser__tourImg {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: contain;
  margin-bottom: var(--s-5);
}
.ser__tourItem .eyebrow { margin-bottom: var(--s-2); color: var(--text-mute); }
.ser__tourItem h3 { font-size: 1.125rem; margin-bottom: var(--s-3); }
.ser__tourItem p { margin: 0; color: var(--text-2); font-size: .9375rem; }

/* ── Ausstattung ──────────────────────────────────────────────── */
.ser__features {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--s-3) var(--s-8);
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  color: var(--text-2);
}
/* Kein list-style: der Strich sitzt auf der Grundlinie der ersten Zeile
   und läuft bei mehrzeiligen Punkten nicht mit nach unten. */
.ser__features li {
  position: relative;
  padding: var(--s-2) 0 var(--s-2) var(--s-6);
  border-top: 1px solid var(--line);
}
.ser__features li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 1.05em;
  width: var(--s-3);
  height: 1px;
  background: var(--line-strong);
}

/* ── Bildband ─────────────────────────────────────────────────── */
/* Ein Seitenriss über die volle Breite als Auftakt der Herkunft-Sektion.
   Motiv und Sektion stehen beide auf Schwarz und gehen ineinander über —
   deshalb keine Kante, kein eigener Grund. */
.ser__band {
  display: block;
  width: 100%;
  height: auto;
}

/* ── Herkunft und Zitat ───────────────────────────────────────── */
.ser__origin { display: grid; gap: var(--s-12); align-items: start; }
@media (min-width: 900px) {
  .ser__origin { grid-template-columns: 1.4fr 1fr; gap: var(--s-16); }
}
.ser__originText { color: var(--text-2); max-width: 56ch; margin: 0 0 var(--s-5); }

.ser__quote { margin: 0; border-left: 2px solid var(--line-strong); padding-left: var(--s-6); }
.ser__quote blockquote {
  margin: 0 0 var(--s-4);
  font-family: var(--ff-display);
  font-weight: 700;
  font-size: clamp(1.125rem, 2.2vw, 1.5rem);
  line-height: 1.25;
  text-transform: uppercase;
}
.ser__quote figcaption {
  font-family: var(--ff-mono);
  font-size: .6875rem;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
  color: var(--text-mute);
}

/* ── Fertigung (dunkel) ───────────────────────────────────────── */
.ser__madeInner { display: grid; gap: var(--s-10); align-items: center; }
@media (min-width: 900px) {
  .ser__madeInner { grid-template-columns: 1fr 1.1fr; gap: var(--s-16); }
}
.ser__madeMedia { margin: 0; }
.ser__madeMedia img { width: 100%; height: auto; }
.ser__made .ser__secLead { margin-bottom: 0; }

/* ── Verweise auf die Serienseite ─────────────────────────────── */
/* Auf der Startseite unter der Bereichseinleitung, auf den drei
   Produktseiten unter dem Fließtext. Gleiche Form an beiden Stellen. */
.sec__link,
.pdp__series {
  margin: var(--s-4) 0 0;
  font-family: var(--ff-mono);
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: var(--ls-wide);
  text-transform: uppercase;
}
.pdp__series { margin-bottom: var(--s-8); }
.sec__link a,
.pdp__series a {
  text-decoration: none;
  border-bottom: 1px solid var(--line-strong);
  padding-bottom: 3px;
  transition: border-color var(--t) var(--ease);
}
.sec__link a:hover,
.pdp__series a:hover { border-color: var(--ink); }

/* Zweiter Link in der Spalte des Klappmenüs: die Serienseite steht UNTER
   dem Sprung in die Sektion. Ohne eigene Zeile setzte inline-flex beide
   nebeneinander und die Kurzformen liefen zusammen. */
.mega__all--series { display: flex; width: fit-content; margin-top: var(--s-3); }
