/* Gemeinsamer Bauplan fuer das Schaufenster.
   EINE Datei fuer Uebersicht (produkte.html) UND Produktseite (produkt.html) —
   nicht zweimal dasselbe CSS. Wer hier etwas aendert, aendert beide. */

/* --- Die Hausschrift wird hier GELADEN, nicht nur genannt --------------------
   Bis 2026-08-20 stand in dieser Datei fuenfmal `font-family:"Space Grotesk"`
   — und nirgends ein `@font-face`. Im Browser gemessen: `document.fonts.size`
   war 0, es wurde KEINE Schriftdatei geladen. Der Shop lief also auf jedem
   Rechner in der jeweiligen Systemschrift: Segoe UI, Helvetica, Roboto. Die
   Hausschrift existierte im Stylesheet, aber nicht auf dem Bildschirm.

   Die Dateien lagen die ganze Zeit im Repo — unter `demo/fonts/`, deklariert
   nur von `demo/css/styles.css`. Die Demo hatte ihre Schrift, das Schaufenster
   nicht.

   Selbst gehostet, nicht ueber ein fremdes CDN. Zwei Gruende: die CSP in
   `netlify.toml` laesst mit `default-src 'self'` gar keinen fremden Font-Host
   zu, und das LG Muenchen I hat am 20.01.2022 (3 O 17493/20) entschieden, dass
   die dynamische Einbindung von Google Fonts ohne Einwilligung gegen die DSGVO
   verstoesst. Seit Chrome 86 ist der geteilte CDN-Cache ohnehin nach Domain
   partitioniert — der frueher genannte Vorteil existiert nicht mehr.

   `swap`: der Text ist sofort lesbar und wird nachtraeglich ersetzt.
   `unicode-range`: nur Latein, alles andere wird gar nicht erst geholt. */
@font-face{font-family:"Space Grotesk";font-style:normal;font-weight:500;font-display:swap;
  src:url("assets/fonts/space-grotesk-latin-500-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Space Grotesk";font-style:normal;font-weight:600;font-display:swap;
  src:url("assets/fonts/space-grotesk-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:400;font-display:swap;
  src:url("assets/fonts/inter-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:500;font-display:swap;
  src:url("assets/fonts/inter-latin-500-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Inter";font-style:normal;font-weight:600;font-display:swap;
  src:url("assets/fonts/inter-latin-600-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* Nur fuer Zahlen, Kennungen, Codes — nie fuer Fliesstext. */
@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;
  src:url("assets/fonts/jetbrains-mono-latin-400-normal.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}

:root{
  --bg:#060b14; --bg2:#0a1120; --panel:#0d1626; --panel2:#101d33;
  --line:rgba(125,165,225,.16); --line2:rgba(125,165,225,.28);
  --ink:#e9f1fc; --muted:#93a7c7; --muted2:#6b7f9f;
  /* EIN Akzent. Das Violett ist weg — Entscheidung Johannes am 2026-08-20.
     Grund: eine Erhebung ueber 1.590 Landingpages hat Lila/Indigo-Akzente als
     haeufigstes Merkmal maschinell entworfener Seiten gemessen (10,7 %); die
     Ursache ist dokumentiert (Tailwinds Standardfarbe `indigo-500`, der Autor
     hat sich 2025 oeffentlich dafuer entschuldigt). Es sah nicht schlecht aus —
     es sah nach VOREINSTELLUNG aus statt nach Entscheidung, und das ist bei
     einem Hightech-Laden fuer Unternehmen das falsche Signal.
     Der Verlauf bleibt, aber innerhalb einer Farbfamilie: das gibt Flaechen
     Tiefe, ohne eine zweite Farbe zu behaupten. */
  --cyan:#38e1ff; --cyan-d:#1aa5c9;
  --ok:#37d6a6; --warn:#f5c65d;
  /* DREI Radien, mit fester Zuordnung — nicht vierzehn.
     Vorher standen hier 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 30 und 38 px
     nebeneinander. Radius ist bei den Seiten, die teuer wirken, eine TYPOLOGIE:
     man erkennt an der Geometrie, ob etwas ein Knopf, eine Karte oder eine
     Flaeche ist. Vierzehn Werte sagen gar nichts mehr — sie sehen nur zufaellig
     aus, besonders wenn 9 px und 11 px im selben Bild stehen.
     `--r-pille` bleibt fuer echte Pillen (Status, Umschalter), 50% fuer Kreise
     (Bildzeichen), und 38 px allein fuer die Handy-Attrappe — das ist ein
     abgebildeter Gegenstand, kein Bedienelement. */
  --r-s:8px;      /* Knopf, Eingabefeld, kleine Marke */
  --r-m:12px;     /* Karte, Kachel, Feld */
  --r-l:16px;     /* Flaeche, Panel, Fenster */
  --r-pille:999px;
  --radius:var(--r-l); --maxw:1120px;
  --grad:linear-gradient(120deg,var(--cyan),var(--cyan-d));
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{scroll-behavior:smooth}
body{margin:0;background:var(--bg);color:var(--ink);
  font-family:"Inter",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  /* Haelt die Ersatzschrift auf derselben x-Hoehe — kein Springen beim Tausch. */
  font-size-adjust:from-font;
  line-height:1.55;-webkit-font-smoothing:antialiased;overflow-x:hidden;min-height:100vh;
  display:flex;flex-direction:column}
/* Gewicht 600 ist der Deckel, nicht Zufall: wir liefern 500 und 600 aus.
   Ohne diese Zeile griff der Browser-Standard `bold` (700) und liess einen
   gefaelschten Fettschnitt aus der 600 rechnen — das sieht ausgefranst aus.
   Die Laufweite waechst mit der Groesse: bei 50px sind -.022em rund -1,1px,
   im Fliesstext bleibt sie bei 0. Grosse Schrift wird ohne diese
   Gegenrechnung optisch loechrig. */
h1,h2,h3{font-family:"Space Grotesk",-apple-system,"Segoe UI",sans-serif;font-weight:600;line-height:1.14;letter-spacing:-.022em;margin:0;text-wrap:balance}
a{color:inherit;text-decoration:none}
.wrap{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 20px}
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.dim{color:var(--muted2)}

/* --- Hintergrund-Ebenen ---------------------------------------------------
   Dieselbe Tiefe wie auf der Messenger-Seite: bewegtes Netz (Canvas), zwei
   weiche Lichter und ein feines Korn. ALLE liegen hinter dem Inhalt
   (z-index 0, pointer-events:none) und ueberlagern nie Text oder Knoepfe.
   Das Netz kommt aus `/messenger/mesh.js` — dieselbe Datei, nicht kopiert. */
.sx-mesh{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.55}
/* Ohne `filter:blur(90px)`. Der Weichzeichner lag auf zwei FIXIERTEN Flaechen
   von 520x520 und 560x560 px — der Compositor musste sie vorhalten und bei
   jedem Scroll-Bild neu zusammensetzen. Ein `radial-gradient` mit weichem
   Auslauf IST bereits weich; der Weichzeichner darueber war reine Rechenlast
   ohne sichtbaren Unterschied. Der Auslauf ist dafuer von 65% auf 72%
   gezogen und die Deckkraft leicht angehoben. */
.glow{position:fixed;z-index:0;opacity:.5;pointer-events:none;border-radius:50%}
.glow.a{width:520px;height:520px;background:radial-gradient(circle,rgba(56,225,255,.34),transparent 72%);top:-180px;left:-140px}
/* Dieses Licht war bis 2026-08-20 violett — `rgba(154,134,255,.3)`, also
   exakt `#9a86ff`. Die Regel „kein Violett" stand da schon, sie las aber nur
   Hex-Werte und ging an der `rgba()`-Schreibweise vorbei. Es war die
   GROESSTE violette Flaeche der Seite: 560x560 px, fest ueber dem ganzen
   Dokument. Jetzt ein tiefes Blau derselben Familie — die zwei Lichter geben
   der Flaeche weiter Tiefe, behaupten aber keine zweite Farbe. */
.glow.b{width:560px;height:560px;background:radial-gradient(circle,rgba(26,165,201,.28),transparent 72%);top:260px;right:-180px}
.grain{position:fixed;inset:0;z-index:0;pointer-events:none;opacity:.045;mix-blend-mode:overlay;
  background-image:radial-gradient(rgba(255,255,255,.7) .5px,transparent .5px);background-size:3px 3px}
@media(prefers-reduced-motion:reduce){.sx-mesh{opacity:.3}}
main,header,footer{position:relative;z-index:1}
main{flex:1}

.top{position:sticky;top:0;z-index:20;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  background:rgba(6,11,20,.78);border-bottom:1px solid var(--line)}
.top .wrap{display:flex;align-items:center;gap:18px;height:62px}
.logo{display:flex;align-items:center;gap:10px;font-family:"Space Grotesk",sans-serif;font-weight:600;font-size:17px;flex:0 0 auto}
.logo .mark{width:29px;height:29px;border-radius:var(--r-s);background:var(--grad);display:grid;place-items:center;
  color:#04121b;font-weight:600;flex:0 0 auto;
  /* War ein 20-px-Schein. Ein Leuchten um ein 29-px-Quadrat liest sich als
     Unschaerfe, nicht als Licht — auf jedem Bildschirm, der nicht sehr dunkel
     steht. Ein Ring sagt dasselbe schaerfer und kostet keine Compositor-Ebene. */
  outline:1px solid color-mix(in srgb,var(--cyan) 34%,transparent);outline-offset:2px}
.topnav{margin-left:auto;display:flex;gap:18px;font-size:14px;color:var(--muted);align-items:center;
  overflow-x:auto;scrollbar-width:none}
.topnav::-webkit-scrollbar{display:none}
/* --- Antippflaechen ------------------------------------------------------
   WCAG 2.5.8 (Stufe AA) verlangt 24x24 CSS-Pixel fuer jedes Bedienelement.
   Die Verweise hier standen bei 22px Hoehe — knapp darunter, und auf dem
   Handy heisst „knapp darunter" danebengetippt. Die Groesse kommt ueber
   senkrechte Polsterung, nicht ueber groessere Schrift: das Schriftbild der
   Leiste bleibt, die Flaeche waechst. Gemessen in
   `tests/webseiten-check.pw.js`, nicht geschaetzt. */
.topnav a{white-space:nowrap;display:inline-flex;align-items:center;min-height:24px;padding:2px 0}
.topnav a:hover,.topnav a.on{color:var(--ink)}

.hero{padding:52px 20px 20px;text-align:center}
.hero h1{font-size:clamp(32px,5.4vw,52px);margin-bottom:14px;letter-spacing:-.022em}
.hero h1 em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.hero .lead{color:var(--muted);font-size:16.5px;max-width:680px;margin:0 auto;line-height:1.6}
.eyebrow{font-size:11.5px;letter-spacing:.15em;text-transform:uppercase;color:var(--muted2);font-weight:600;
  margin-bottom:11px;display:inline-flex;align-items:center;gap:9px}
.eyebrow::before{content:"";width:26px;height:1px;background:linear-gradient(90deg,transparent,var(--cyan))}
.hero .eyebrow::after{content:"";width:26px;height:1px;background:linear-gradient(90deg,var(--cyan),transparent)}

/* --- Rondell: ganz oben unter der Leiste steht ein Geraet, kein Text ------
   Alle Produkte liegen gleichzeitig im Markup; sichtbar sind immer nur drei.
   Welches wo steht, sagt allein `data-pos` (mitte/links/rechts/fern) — das
   Skript baut nichts um, es setzt ein Attribut. `fern` wird auf
   visibility:hidden gestellt, damit die weichen Lichter der unsichtbaren
   Geraete den Browser nicht dauerhaft beschaeftigen. */
/* Die Nachbar-Geraete ragen absichtlich ueber die Spalte hinaus — das Rondell
   soll breiter wirken als die Textspalte. `overflow-x:clip` schneidet sie am
   Fensterrand ab, ohne einen waagerechten Rollbalken zu erzeugen (clip legt,
   anders als hidden, keinen Scroll-Container an; senkrecht bleibt alles sichtbar). */
/* --- Kopf-Film -------------------------------------------------------------
   Steht ganz oben, ueber dem Rondell. Feste Hoehe per `aspect-ratio`, damit
   beim Laden nichts springt — das Standbild (`poster`) fuellt den Platz schon,
   bevor ein einziges Byte Video da ist. Nach unten laeuft er weich aus, damit
   der Uebergang ins Rondell keine harte Kante bekommt. */
/* WICHTIG: KEIN max-height auf dem Kopf-Film. Ein Hoehen-Deckel auf einem
   100%-breiten Element zwingt den Rahmen BREITER als 16:9 zu werden — und
   `object-fit:cover` schneidet dann oben + unten weg. Genau so verschwanden im
   Desktop-Test (Screenfreigabe) das Logo (sitzt oben) und die Lampen aus dem
   Bild: nicht das Video war schuld (sauber 1920×1080), sondern der alte
   `max-height:min(74vh,620px)`. Der Kopf bleibt jetzt echtes 16:9 und fuellt
   die Breite randlos; auf grossen Screens wird er hoeher, zeigt dafuer aber
   IMMER das ganze Bild. (Handy: eigener 4:3-Block weiter unten.) */
.kopffilm{position:relative;width:100%;aspect-ratio:16/9;
  overflow:hidden;background:#04070f;isolation:isolate}
.kopffilm video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
/* Auslauf nach unten + leichte Abdunklung: der Film soll die Marke tragen,
   nicht mit dem Rondell darunter um Aufmerksamkeit streiten. */
.kopffilm-schutz{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(4,7,15,.30) 0%,rgba(4,7,15,0) 26%,rgba(4,7,15,0) 62%,var(--bg,#070b16) 100%)}

/* Der Ton-Knopf. Oben rechts, wie gewuenscht — mit Abstand zur sicheren Zone
   (Notch/abgerundete Ecken) und gross genug zum Treffen (44px). */
.kopfton{position:absolute;z-index:2;
  top:calc(14px + env(safe-area-inset-top,0px));
  right:calc(14px + env(safe-area-inset-right,0px));
  display:inline-flex;align-items:center;gap:7px;min-height:40px;padding:9px 14px;
  border:1px solid rgba(150,190,255,.30);border-radius:var(--r-pille);cursor:pointer;
  background:rgba(7,11,22,.62);-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);color:#dce6f5;
  font:inherit;font-size:12.5px;line-height:1;
  transition:background .18s ease,border-color .18s ease,transform .18s ease}
.kopfton:hover{background:rgba(7,11,22,.82);border-color:rgba(56,225,255,.55)}
.kopfton:active{transform:scale(.97)}
.kopfton:focus-visible{outline:2px solid var(--akz,#38e1ff);outline-offset:3px}
.kopfton svg{width:17px;height:17px;flex:none}
/* Genau EIN Symbol ist sichtbar — welches, sagt `aria-pressed`. So kann die
   Beschriftung nicht vom tatsaechlichen Zustand abweichen. */
.kopfton .ki-an{display:none}
.kopfton[aria-pressed="true"]{border-color:rgba(56,225,255,.55);color:#8ce9ff}
.kopfton[aria-pressed="true"] .ki-an{display:block}
.kopfton[aria-pressed="true"] .ki-aus{display:none}

/* Rueckfall, wenn der Browser das Anlaufen verweigert (Stromsparen, iOS-Modus,
   `prefers-reduced-motion`): dann steht hier ein Knopf statt eines toten Bildes. */
.kopfplay{position:absolute;z-index:2;left:50%;top:50%;transform:translate(-50%,-50%);
  padding:13px 22px;border-radius:var(--r-pille);border:1px solid rgba(150,190,255,.34);
  background:rgba(7,11,22,.72);-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);color:#eaf2ff;
  font:inherit;font-size:14px;cursor:pointer}
.kopfplay:hover{border-color:rgba(56,225,255,.55)}
.kopfplay[hidden]{display:none}

@media(max-width:700px){
  /* NACHGEZOGEN 2026-08-17. Hier stand `aspect-ratio:4/3;max-height:56vh` mit
     der Begruendung, 16:9 sei am Handy ein schmaler Streifen und das Logo werde
     briefmarkengross. Das stimmt — aber es war genau derselbe Fehler, den der
     Kasten oben fuer den Desktop beschreibt, nur eine Etage tiefer: ein Rahmen,
     der NICHT dem Film entspricht, plus `object-fit:cover` schneidet weg.
     Gemessen bei 412 px: Rahmen 1.33 gegen Film 1.78 -> nur **75 %** sichtbar,
     links und rechts ab. Der Desktop war repariert, das Handy nicht.
     Ein kleines VOLLSTAENDIGES Bild schlaegt ein grosses beschnittenes: Johannes
     wollte, dass Logo und Lampen zu sehen sind, nicht dass sie gross sind.
     `max-height` faellt gleich mit weg — ein Hoehen-Deckel auf einem 100 %
     breiten Element ist die Ursache von oben; auf einem quer gehaltenen Handy
     haette er wieder zugebissen. */
  .kopffilm{aspect-ratio:16/9}
  .kopfton{top:calc(10px + env(safe-area-inset-top,0px));right:calc(10px + env(safe-area-inset-right,0px));
    padding:8px 12px;font-size:12px}
  .kopfton-tx{display:none}   /* nur noch das Symbol — der Platz gehoert dem Film */
}
@media(prefers-reduced-motion:reduce){
  .kopfton,.kopffilm video{transition:none}
}

.rond{padding:26px 0 8px;overflow-x:clip;overflow-y:visible}
.rondgrid{display:grid;grid-template-columns:1fr .95fr;gap:36px;align-items:center}
.rondcopy{min-width:0}
.rondcopy h1{font-size:clamp(31px,4.6vw,50px);letter-spacing:-.022em;margin-bottom:13px}
.rondcopy h1 em{font-style:normal;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.rondcopy .lead{color:var(--muted);font-size:16.5px;line-height:1.6;margin:0 0 20px;max-width:52ch}

/* Das kurze Intro: drei Schritte, damit klar ist, wie das hier laeuft. */
.schritte{list-style:none;counter-reset:s;margin:0 0 22px;padding:0;display:grid;gap:11px;max-width:50ch}
.schritte li{counter-increment:s;position:relative;padding-left:40px;min-height:28px}
.schritte li::before{content:counter(s,decimal-leading-zero);position:absolute;left:0;top:1px;
  width:28px;height:28px;border-radius:var(--r-s);display:grid;place-items:center;
  font-family:"Space Grotesk",sans-serif;font-size:11.5px;font-weight:600;letter-spacing:.02em;
  color:var(--cyan);background:rgba(56,225,255,.11);border:1px solid rgba(56,225,255,.28)}
.schritte b{display:block;font-size:14.5px;line-height:1.35}
.schritte span{display:block;font-size:13.5px;color:var(--muted2);line-height:1.45}

.rondbuehne{position:relative;min-width:0}
/* `--rondh` setzt `rondell()` in `index.html` nach dem Bauen: die Hoehe des
   GROESSTEN Geraets. Die Zahlen hier sind nur noch der Boden, bis gemessen ist.

   ⚠️ WARUM: Die Platten liegen `absolute; inset:0`, tragen also NICHTS zur
   Hoehe bei. Ist ein Geraet hoeher als die Buehne, haengt es unten heraus und
   legt sich auf die Bildunterschrift. Genau das hat Johannes am 2026-08-18
   fotografiert: „SymmetryX Messenger ansehen" lag unter dem Telefon-Mockup.
   Gemessen auf 412 px: Buehne bis y=713, Geraet bis y=739, Link 727–749.
   Der vorhandene Groessen-Pruefstand sah es nicht — er misst bei 1280 px,
   und dort passt es. */
.rondell{position:relative;min-height:var(--rondh,492px);perspective:1700px}
.rondell .skel{position:absolute;inset:0;display:grid;place-items:center;text-align:center}
.rplatte{position:absolute;inset:0;display:grid;place-items:center;cursor:pointer;
  visibility:hidden;opacity:0;
  transition:transform .55s cubic-bezier(.32,.72,.3,1),opacity .45s ease,filter .45s ease,visibility 0s .55s}
.rplatte[data-pos="mitte"],.rplatte[data-pos="links"],.rplatte[data-pos="rechts"]{visibility:visible;transition-delay:0s}
.rplatte[data-pos="mitte"]{transform:none;opacity:1;z-index:3;cursor:default}
.rplatte[data-pos="links"]{transform:translateX(-40%) scale(.66) rotateY(20deg);opacity:.42;z-index:2;filter:saturate(.6) brightness(.72)}
.rplatte[data-pos="rechts"]{transform:translateX(40%) scale(.66) rotateY(-20deg);opacity:.42;z-index:2;filter:saturate(.6) brightness(.72)}
.rplatte[data-pos="fern"]{transform:scale(.5);z-index:1;pointer-events:none}
.rplatte[data-pos="links"]:hover,.rplatte[data-pos="rechts"]:hover{opacity:.72;filter:none}
/* Nur das vordere Geraet traegt die schwebenden Karten — sonst wird es Brei. */
.rplatte:not([data-pos="mitte"]) .schweb{opacity:0}
/* Die Buehne schrumpfte auf ihren Inhalt (`min-height:0`) und wurde von der
   Platte mittig gesetzt. Damit war jede Ausrichtung INNERHALB der Buehne
   wirkungslos — das Geraet sass immer in der Mitte der Platte, und weil die
   Geraete verschieden hoch sind, wanderte die Oberkante beim Weiterklicken um
   bis zu 90 px.
   Jetzt fuellt die Buehne die Platte aus; damit greift ihr eigenes
   `place-items:start center` (siehe `.buehne` weiter unten).
   NACHGEMESSEN: beide Zeilen zusammen sind noetig — `.buehne` allein reicht
   NICHT, diese hier allein auch nicht. Ein erster Entwurf hatte zusaetzlich
   `.rplatte{place-items:start center}`; die Gegenprobe zeigte, dass die
   dasselbe auf einem zweiten Weg tut. Zwei Wege zum selben Ziel sehen nach
   Sicherheit aus und sind in Wahrheit die Stelle, an der spaeter jemand den
   falschen entfernt und sich wundert, dass nichts passiert. */
.rplatte .buehne{min-height:100%;width:100%}

.rnav{position:absolute;top:44%;transform:translateY(-50%);z-index:6;cursor:pointer;
  width:42px;height:42px;border-radius:50%;display:grid;place-items:center;font-size:22px;line-height:1;
  color:var(--ink);background:rgba(10,20,36,.72);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border:1px solid var(--line2);transition:border-color .18s,background .18s,transform .18s}
.rnav:hover{border-color:var(--cyan-d);background:rgba(14,28,48,.9)}
.rnav.zurueck{left:-6px}
.rnav.weiter{right:-6px}
/* Zwei Produkte haben echte Bildschirmfotos und damit den Knopf
   „Reinschauen", sechs nicht. Der Fuss war deshalb mal 22 und mal 33 px hoch
   (auf dem Handy 38 gegen 69) — und beim Weiterklicken sprang die ganze
   Buehne. Der Platz wird jetzt IMMER freigehalten: die Zeile ist so hoch wie
   ihr hoechster Fall, ob der Knopf da ist oder nicht. */
.rjetzt{margin:6px 0 0;text-align:center;font-size:14.5px;font-weight:600;
  min-height:34px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px}
/* WCAG 2.5.8 (AA): 24x24 CSS-Pixel je Bedienelement. Gemessen wurde 22 —
   knapp darunter, und auf dem Handy heisst knapp darunter danebengetippt.
   Die Flaeche waechst ueber Polsterung, das Schriftbild bleibt. */
.rjetzt a{display:inline-flex;align-items:center;min-height:24px}
.rjetzt a{color:var(--akz,#38e1ff)}
.rjetzt a:hover{text-decoration:underline}

/* Sieben Reiter muessen nebeneinander in die Spalte passen — sonst faellt der
   siebte hinter den Rand und man haelt sechs Produkte fuer alle. Deshalb eng
   gesetzt; auf schmalen Geraeten wird die Reihe schiebbar. */
.rtabs{display:flex;flex-wrap:wrap;gap:6px;margin-top:16px;padding-bottom:4px}
.rtab{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;cursor:pointer;
  border:1px solid var(--line);background:rgba(13,22,38,.6);color:var(--muted);
  border-radius:var(--r-s);padding:5px 10px 5px 6px;font:inherit;font-size:12px;font-weight:600;
  white-space:nowrap;transition:border-color .18s,color .18s,background .18s}
.rtab:hover{color:var(--ink);border-color:var(--line2)}
.rtab[aria-selected="true"]{color:var(--ink);border-color:color-mix(in srgb,var(--akz,#38e1ff) 46%,transparent);
  background:color-mix(in srgb,var(--akz,#38e1ff) 11%,rgba(13,22,38,.6))}

/* Das Intro faehrt einmal weich herein — gestaffelt, damit man liest statt
   alles auf einmal zu sehen. Danach steht es still (both/forwards). */
@keyframes einblenden{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.rondcopy>*{animation:einblenden .55s cubic-bezier(.22,.7,.3,1) both}
.rondcopy>:nth-child(1){animation-delay:.04s}
.rondcopy>:nth-child(2){animation-delay:.12s}
.rondcopy>:nth-child(3){animation-delay:.2s}
.rondcopy>:nth-child(4){animation-delay:.28s}
.rondcopy>:nth-child(5){animation-delay:.36s}

@media(max-width:980px){
  .rondgrid{grid-template-columns:1fr;gap:14px}
  .rondbuehne{order:-1}
  .rondell{min-height:var(--rondh,430px)}
  .rondcopy .lead,.schritte{max-width:none}
}
@media(max-width:700px){
  /* Ein Handy neben zwei halben Handys ist auf 360px nur noch Gedraenge. */
  .rplatte[data-pos="links"],.rplatte[data-pos="rechts"]{opacity:0;visibility:hidden}
  .rondell{min-height:var(--rondh,396px)}
  .rplatte .geraet.desktop{width:min(520px,92%)}
  /* Auf dem Handy duerfen die Pfeile NICHT auf dem Geraet liegen — sie
     verdecken sonst genau das, was sie zeigen sollen. Sie ruecken neben den
     Link darunter, wo auch der Daumen ist. */
  .rnav{top:auto;bottom:0;transform:none;width:38px;height:38px;font-size:19px}
  .rnav.zurueck{left:0}
  .rnav.weiter{right:0}
  .rjetzt{min-height:70px;display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:8px;padding:0 46px}
  /* Auf dem Handy schiebbar statt umgebrochen — sieben Zeilen Reiter waeren
     mehr Seite als Produkt. */
  .rtabs{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
  .rtabs::-webkit-scrollbar{display:none}
}
@media(prefers-reduced-motion:reduce){
  .rplatte{transition:opacity .01s,visibility 0s}
  .rondcopy>*{animation:none}
}

/* --- Geraete-Buehne: EIN Bauteil, je Produkt andere Daten ----------------
   Bewusst KEIN zweites Handy-Markup je Seite. `renderGeraet()` fuellt es aus
   `produkte.json`; hier steht nur, wie es aussieht. Leicht angeschraegt und
   mit Glanzkante — es soll wie ein Geraet wirken, nicht wie ein Kasten. */
/* `place-items:center` hat jedes Geraet MITTIG gesetzt — und die Geraete sind
   verschieden hoch (gemessen am 2026-08-21: Handys 353-490 px, Fenster
   300-319 px auf derselben 496-px-Buehne). Mittig heisst dann: die Oberkante
   wandert bei jedem Weiterklicken um bis zu 90 px. Das ist der Grund, warum
   das Rondell unruhig wirkt — nicht die Formen, sondern der wandernde Anfang.
   Jetzt haengen alle an derselben Linie, mit einem festen weichen Abstand
   nach oben. Was kuerzer ist, laesst unten Luft; was hoeher ist, faengt
   trotzdem oben an. */
.buehne{position:relative;display:grid;place-items:start center;
  padding-top:var(--buehne-luft,20px);min-height:430px;perspective:1600px}
.buehne::before{content:"";position:absolute;width:min(560px,92%);height:min(560px,92%);border-radius:50%;
  background:radial-gradient(circle,color-mix(in srgb,var(--akz,#38e1ff) 34%,transparent),transparent 64%);
  filter:blur(52px);opacity:1}
.ring{position:absolute;border:1px solid color-mix(in srgb,var(--akz,#38e1ff) 22%,transparent);border-radius:50%;pointer-events:none}
.ring.a{width:min(460px,86%);aspect-ratio:1}
.ring.b{width:min(600px,104%);aspect-ratio:1;opacity:.5}

.geraet{position:relative;transform:rotateY(-13deg) rotateX(5deg) rotateZ(-1.2deg);transform-style:preserve-3d;
  box-shadow:0 44px 90px rgba(0,0,0,.6),0 0 0 1px rgba(255,255,255,.05);transition:transform .5s ease}
.buehne:hover .geraet{transform:rotateY(-8deg) rotateX(3deg) rotateZ(-.6deg)}
@media(prefers-reduced-motion:reduce){.geraet,.buehne:hover .geraet{transform:none;transition:none}}

/* Das abgebildete Handy hat zwei Rundungen, und sie haengen zusammen: aussen
   der Rahmen, innen das Glas, dazwischen die Polsterung. Beide Werte stehen
   deshalb als Token da und die innere wird GERECHNET — vorher standen 38 und
   29 als nackte Zahlen nebeneinander, und niemand sah, dass die eine aus der
   anderen folgt. Wer den Rahmen aendert, bekommt das Glas jetzt gratis
   mitgezogen. (Ein abgebildeter Gegenstand darf eigene Radien haben; die drei
   Token gelten fuer BEDIENELEMENTE.) */
.geraet.phone{--rahmen-r:38px;--rahmen-pad:9px;
  width:284px;border-radius:var(--rahmen-r);padding:var(--rahmen-pad);
  background:linear-gradient(158deg,#2b3446,#0a0f1a 42%,#161d2b)}
/* `--r-pille` (999px) stand hier bis zum 2026-08-21. Auf einem 266x418
   grossen Glas klemmt der Browser das auf die HALBE kurze Seite — also rund
   133 px. Das ist keine Handy-Rundung mehr, das ist ein Stadion: die oberen
   Ecken fressen die erste Zeile, und genau deshalb sah der Inhalt
   „nicht richtig dargestellt" aus (Johannes, 2026-08-21, mit Bildschirmfoto).
   Richtig ist die Rundung des RAHMENS minus seiner Polsterung: 38 - 9 = 29.
   So laeuft die innere Kante parallel zur aeusseren, wie bei einem echten
   Geraet. */
.geraet.phone .glas{position:relative;border-radius:calc(var(--rahmen-r) - var(--rahmen-pad));background:linear-gradient(178deg,#132241,#0b1526 60%,#0a1220);
  overflow:hidden;padding:13px 12px 14px;min-height:418px;
  box-shadow:inset 0 0 0 1px rgba(140,190,255,.09),inset 0 22px 44px rgba(90,160,255,.07)}
.geraet.phone .kerbe{position:absolute;top:9px;left:50%;transform:translateX(-50%);width:92px;height:20px;
  background:#05080f;border-radius:0 0 var(--r-m) var(--r-m);z-index:3}
.geraet.desktop{width:min(520px,100%);border-radius:var(--r-l);padding:0;overflow:hidden;
  background:linear-gradient(158deg,#2b3446,#0b1220)}
.geraet.desktop .glas{background:linear-gradient(178deg,#132241,#0b1526 62%,#0a1220);padding:0;min-height:296px;
  box-shadow:inset 0 0 0 1px rgba(140,190,255,.09)}
.geraet .leiste{display:flex;align-items:center;gap:6px;padding:11px 14px;border-bottom:1px solid var(--line);
  font-size:12px;color:var(--muted2)}
.geraet .leiste i{width:9px;height:9px;border-radius:50%;background:rgba(148,167,199,.32)}
.geraet .leiste span{margin-left:8px}
/* Glanzkante — das bisschen Hochglanz, das ein Kasten nicht hat. Die zweite
   Ebene ist der Holo-Schimmer: echtes Glas bricht Licht farbig, nicht grau. */
.geraet::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:
    linear-gradient(122deg,rgba(255,255,255,.16),rgba(255,255,255,0) 34%,rgba(255,255,255,0) 72%,rgba(255,255,255,.07)),
    linear-gradient(122deg,rgba(92,225,255,.13),transparent 34%,rgba(255,255,255,.07) 52%,
      transparent 68%,rgba(26,165,201,.11))}

.statuszeile{display:flex;justify-content:space-between;font-size:10.5px;color:var(--muted2);
  padding:12px 6px 10px;letter-spacing:.03em}
.gkopf{display:flex;align-items:center;gap:9px;padding:0 4px 11px;border-bottom:1px solid var(--line)}
.gkopf .av{width:31px;height:31px;border-radius:50%;flex:0 0 auto;display:grid;place-items:center;font-size:12px;font-weight:600;
  background:color-mix(in srgb,var(--akz,#38e1ff) 20%,transparent);color:var(--akz,#38e1ff);
  border:1px solid color-mix(in srgb,var(--akz,#38e1ff) 40%,transparent)}
.gkopf b{font-size:13.5px;display:block}
.gkopf small{font-size:11px;color:var(--muted2)}
.gliste{padding:11px 2px 0;display:grid;gap:8px}

/* Chat-Form (in/out/note) */
.gm{max-width:84%;padding:8px 11px;border-radius:var(--r-m);font-size:12px;line-height:1.45;
  background:rgba(163,186,222,.16);border:1px solid rgba(148,180,230,.2)}
.gm time{display:block;font-size:9.5px;color:var(--muted2);margin-top:4px}
.gm.out{margin-left:auto;background:color-mix(in srgb,var(--akz,#38e1ff) 16%,transparent);
  border-color:color-mix(in srgb,var(--akz,#38e1ff) 34%,transparent)}
.gnote{border:1px solid color-mix(in srgb,var(--akz,#38e1ff) 34%,transparent);border-radius:var(--r-m);padding:9px 11px;
  background:color-mix(in srgb,var(--akz,#38e1ff) 9%,transparent)}
.gnote small{display:block;font-size:9px;letter-spacing:.13em;font-weight:600;color:var(--akz,#38e1ff)}
.gnote b{font-size:12px;display:block;margin:2px 0 1px}
.gnote span{font-size:10.5px;color:var(--muted2)}

/* Listen-Form (Zeilen mit Marke, Titel, Unterzeile, Abzeichen) */
.gz{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--r-m);
  background:rgba(163,186,222,.11);border:1px solid rgba(148,180,230,.17);min-width:0}
.gz .mk{width:26px;height:26px;border-radius:var(--r-s);flex:0 0 auto;display:grid;place-items:center;font-size:12px;
  background:color-mix(in srgb,var(--akz,#38e1ff) 17%,transparent);color:var(--akz,#38e1ff)}
.gz .tx{flex:1;min-width:0}
.gz .tx b{display:block;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gz .tx small{display:block;font-size:10.5px;color:var(--muted2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gz em{font-style:normal;font-size:9.5px;font-weight:600;letter-spacing:.05em;padding:2px 7px;border-radius:var(--r-l);
  background:color-mix(in srgb,var(--akz,#38e1ff) 17%,transparent);color:var(--akz,#38e1ff);white-space:nowrap}

/* Schwebende Glas-Karte am Geraet */
.schweb{position:absolute;background:rgba(10,20,36,.82);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);border:1px solid var(--line2);
  border-radius:var(--r-m);padding:10px 12px;box-shadow:0 20px 50px rgba(0,0,0,.55);max-width:178px;z-index:4}
.schweb small{display:block;font-size:9px;letter-spacing:.13em;font-weight:600;color:var(--akz,#38e1ff);margin-bottom:3px}
.schweb b{display:block;font-size:12.5px}
.schweb span{display:block;font-size:10.5px;color:var(--muted2);margin-top:1px}
.schweb.o{top:19%;right:-6px}
.schweb.u{bottom:15%;left:4%}
@media(max-width:860px){.schweb{display:none}}

.cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(276px,1fr));gap:15px;padding-bottom:12px}
.card{background:linear-gradient(180deg,var(--panel2),var(--panel));border:1px solid var(--line);
  border-radius:var(--radius);padding:19px 20px;min-width:0}
.card.wide{grid-column:1/-1}
.card h3{font-size:17px;margin-bottom:4px}
/* Produktkarte: traegt die Akzentfarbe ihres Produkts. Sieben identische graue
   Kaesten sehen aus wie eine Tabelle, nicht wie ein Schaufenster. */
.card.prod{display:flex;flex-direction:column;position:relative;overflow:hidden;
  transition:transform .18s,border-color .2s,box-shadow .25s}
.card.prod::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;
  background:linear-gradient(90deg,var(--akz,#38e1ff),transparent 72%);opacity:.85}
/* Holo-Schleier: beim Ueberfahren legt sich ein schillernder Film ueber die
   Platte — Regenbogen leicht, Akzentfarbe fuehrend. Ohne ihn sehen sieben
   Karten gleich stumpf aus. */
.card.prod::after{content:"";position:absolute;inset:0;pointer-events:none;
  opacity:0;transition:opacity .28s ease;
  background:
    radial-gradient(210px 210px at 100% 0,color-mix(in srgb,var(--akz,#38e1ff) 24%,transparent),transparent 70%),
    linear-gradient(122deg,transparent 36%,rgba(255,255,255,.08) 50%,transparent 64%),
    conic-gradient(from 205deg at 76% 10%,transparent,
      color-mix(in srgb,var(--akz,#38e1ff) 30%,transparent) 24%,transparent 58%,
      rgba(255,255,255,.06) 74%,transparent)}
/* Kein Anheben beim Ueberfahren. Die Referenzseiten verbieten das ausdruecklich:
   Bewegung soll einen Zustandswechsel BESTAETIGEN, nicht ihn inszenieren.
   Der Zustand wird jetzt ueber Rand und Flaeche gesagt — das liest sich
   ruhiger und kostet kein Neuzeichnen der Karte. */
/* Der Schlagschatten (0 20px 52px) ist raus. Er tat so, als schwebe die Karte
   ueber der Seite — genau die Bild-Luege, die die Referenzmarken vermeiden:
   nichts schwebt, die Flaechen liegen in einer LEITER uebereinander. Der
   Zustand wird jetzt so gesagt, wie es dort auch geschieht: die Flaeche steigt
   EINE Stufe (panel -> panel2), und der Rand wird zur Haarlinie in der
   Produktfarbe. Das liest sich ruhiger und kostet kein Neuzeichnen. */
.card.prod:hover{border-color:color-mix(in srgb,var(--akz,#38e1ff) 34%,transparent);
  background:linear-gradient(180deg,var(--panel2),var(--panel2))}
.card.prod:hover::after{opacity:1}
.ch{display:flex;align-items:center;gap:11px;margin-bottom:8px;flex-wrap:wrap}
.ch h3{flex:1;min-width:0}

/* --- Holo-Marke -----------------------------------------------------------
   Die Produktmarke ist das einzige Bild auf einer Karte — sie darf nicht wie
   ein grauer Kasten aussehen. Drei Ebenen: Akzent-Verlauf (unten), langsam
   drehender Regenbogen im Dodge-Modus (Mitte), Glanzstreifen (oben). Das
   Zeichen selbst sitzt in `<i>` darueber, sonst waere es milchig.
   `isolation:isolate` haelt das Dodge-Blenden IN der Marke — sonst faerbt es
   die Karte darunter ein. */
.pmark{position:relative;isolation:isolate;overflow:hidden;
  width:36px;height:36px;border-radius:var(--r-s);flex:0 0 auto;display:grid;place-items:center;font-size:17px;
  color:var(--akz,#38e1ff);
  background:linear-gradient(152deg,color-mix(in srgb,var(--akz,#38e1ff) 30%,transparent),
    color-mix(in srgb,var(--akz,#38e1ff) 7%,transparent));
  border:1px solid color-mix(in srgb,var(--akz,#38e1ff) 38%,transparent);
  /* Nur noch die innenliegende Lichtkante. Der farbige Schein darunter
     (`0 5px 16px`) ist raus — er lag in der Produktfarbe unter einer Flaeche,
     die schon die Produktfarbe traegt, und machte aus einer sauberen Kante
     einen Hof. */
  box-shadow:inset 0 1px 0 rgba(255,255,255,.2)}
.pmark::before{content:"";position:absolute;inset:-45%;z-index:0;pointer-events:none;
  /* Vorher: ein Regenbogen aus sechs Farben, der sich in acht Sekunden endlos
     dreht — mit `filter:blur(5px)` darauf. Drei Dinge auf einmal, die gegen die
     Wirkung arbeiten: fuenf zusaetzliche bunte Werte, eine Dauerbewegung ohne
     Aussage (Bewegung soll einen Zustandswechsel bestaetigen, nicht laufen),
     und ein animierter Weichzeichner, der bei jedem Bild neu gerechnet wird.
     Jetzt ein ruhiger Schimmer in der Hausfarbe, der steht. */
  background:conic-gradient(from 210deg,transparent,color-mix(in srgb,var(--cyan) 55%,transparent) 30%,transparent 62%);
  mix-blend-mode:screen;opacity:.28}
.pmark::after{content:"";position:absolute;inset:0;z-index:1;pointer-events:none;
  background:linear-gradient(116deg,transparent 32%,rgba(255,255,255,.45) 47%,transparent 62%);
  transform:translateX(-140%);transition:transform .7s ease}
.pmark i{position:relative;z-index:2;font-style:normal;line-height:1;text-shadow:0 1px 5px rgba(0,0,0,.55)}
.pmark.sm{width:22px;height:22px;border-radius:var(--r-s);font-size:11.5px}

/* --- Marke MIT Logo: QUADRATISCH, ganzes Zeichen --------------------------
   Ansage Johannes 2026-08-17: „Die Logos muessen aber quadratisch angesetzt
   sein ueberall, dass sie voll zu sehen sind, Hintergrund ausgeschnitten und am
   besten mit 'nem pulsierenden Holoeffekt."

   Hier stand bis dahin `.pmark.breit` — ein breites Feld mit dem SCHRIFTBAND
   darin. Das war meine Entscheidung (ein hochkantes Diamant-Logo wird auf 36 px
   klein), und Johannes hat sie umgedreht: lieber das ganze Zeichen kleiner als
   nur ein Ausschnitt davon.

   Das Feld behaelt also die Quadratform aus `.pmark`; das Bild fuellt es per
   `object-fit:contain`, ohne beschnitten zu werden — bei einem hochkanten Logo
   (420x~520) heisst das: volle Hoehe, Luft an den Seiten. */
.pmark.hatlogo{padding:2px;background:linear-gradient(152deg,
    color-mix(in srgb,var(--akz,#38e1ff) 22%,transparent),
    color-mix(in srgb,var(--akz,#38e1ff) 5%,transparent))}
/* z-index 3, NICHT 1: der Glanzstreifen (`::after`, z-index 2) lag sonst UEBER
   dem Logo. Aufgefallen am 2026-08-17 — die Probe „Das Zeichen liegt ueber dem
   Holo" haette das gemeldet, kam aber nie dazu: sie stuerzte vorher ab, weil sie
   fest ein `<i>` suchte und Logo-Produkte ein `<img>` tragen. */
.pmark.hatlogo img{width:100%;height:100%;object-fit:contain;display:block;
  position:relative;z-index:3}
/* Der Schimmer bleibt AN (frueher `display:none` fuer Logos) und bekommt das
   Pulsieren dazu: `holodreh` dreht den Regenbogen, `holopuls` atmet ihn.
   Er liegt HINTER dem Logo — bei einem freigestellten PNG scheint er durch die
   freien Flaechen, und genau das ist der Effekt. */
.pmark.hatlogo::before{display:block;opacity:.34;
  animation:holodreh 8s linear infinite, holopuls 3.4s ease-in-out infinite}
.pmark.hatlogo::after{z-index:2;mix-blend-mode:screen;
  background:linear-gradient(116deg,transparent 34%,rgba(255,255,255,.34) 47%,transparent 60%)}
/* Marken, die es nur hell gibt (MediTune, CareTune): dunkle Schrift braucht
   eine helle Platte, sonst verschwindet sie auf der dunklen Karte. */
.pmark.hatlogo.hell{background:linear-gradient(180deg,#fdfefe,#eef4fa);
  box-shadow:0 4px 14px rgba(0,0,0,.32)}
/* Die kleine Fassung sitzt in der Reiter-Leiste und war 22 px. Ein hochkantes
   Zeichen (420x~520) waere darin ~18 px hoch — quadratisch zwar, aber nicht
   mehr „voll zu sehen". Etwas groesser, damit man erkennt, WELCHE Marke da
   steht. Das Ersatzzeichen (ohne Logo) bleibt bei 22 px. */
.pmark.sm.hatlogo{width:30px;height:30px;border-radius:var(--r-s)}

/* Das ganze Zeichen, wo Platz ist (Produktseite, Fensterkopf). */
.plogo{display:block;line-height:0}
.plogo img{display:block;width:auto;max-width:100%;height:auto;max-height:132px;object-fit:contain}
.plogo.hell{background:linear-gradient(180deg,#fdfefe,#eef4fa);border-radius:var(--r-m);padding:10px 14px;
  display:inline-block;box-shadow:0 8px 26px rgba(0,0,0,.34)}
/* Auf der Produktseite steht das Zeichen ueber der Ueberschrift. Traegt es den
   Produktnamen schon selbst, wird die Ueberschrift kleiner — sonst steht der
   Name zweimal gross untereinander. */
.plogo.hero{margin:2px 0 10px}
.plogo.hero img{max-height:118px}
.phead h1.mitlogo{font-size:clamp(20px,2.6vw,26px);color:var(--muted)}
@media(max-width:900px){.plogo.hero img{max-height:88px}}
.card.prod:hover .pmark::after,.rtab:hover .pmark::after,.rtab[aria-selected="true"] .pmark::after{transform:translateX(140%)}
@keyframes holodreh{to{transform:rotate(1turn)}}
/* Das Pulsieren aus Johannes' Ansage — der Schimmer atmet, statt nur zu drehen.
   Bewusst dezent (.22 bis .46): eine Marke soll leuchten, nicht blinken. */
@keyframes holopuls{0%,100%{opacity:.22}50%{opacity:.46}}
@media(prefers-reduced-motion:reduce){
  .pmark::before{animation:none}
  .pmark::after{transition:none}
}
.card.prod .more{color:var(--akz,#38e1ff)}
/* Die Kachel traegt zwei Wege. Der Link deckt die ganze Kachel ab (so bleibt
   „irgendwo hinklicken" moeglich), der Knopf liegt darueber. */
.cf{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:auto}
.card.prod .more::after{content:"";position:absolute;inset:0;z-index:1}
.reinschauen{position:relative;z-index:2;margin-left:auto;cursor:pointer;font:inherit;
  display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;
  color:var(--muted);background:rgba(13,22,38,.7);border:1px solid var(--line2);
  border-radius:var(--r-s);padding:6px 11px;transition:color .18s,border-color .18s,background .18s}
.reinschauen:hover{color:var(--ink);border-color:color-mix(in srgb,var(--akz,#38e1ff) 48%,transparent);
  background:color-mix(in srgb,var(--akz,#38e1ff) 12%,rgba(13,22,38,.7))}
.pacts .reinschauen{margin-left:0;font-size:14.5px;padding:11px 18px;min-height:46px;border-radius:var(--r-m)}
.rjetzt{display:flex;align-items:center;justify-content:center;gap:12px;flex-wrap:wrap}
.rjetzt .reinschauen{margin-left:0}
.kurz{color:var(--muted);font-size:14.5px;margin:0 0 12px;flex:1}
.ab{font-variant-numeric:tabular-nums;font-size:13.5px;color:var(--muted2);margin-bottom:12px}
.ab b{color:var(--ink);font-size:15px}
.more{font-size:13.5px;color:var(--cyan);font-weight:600;display:inline-flex;align-items:center;min-height:24px}

.pill{display:inline-flex;align-items:center;border-radius:var(--r-pille);padding:3px 10px;
  font-size:11px;font-weight:600;white-space:nowrap;flex:0 0 auto}
.pill.beta{background:rgba(245,198,93,.13);color:var(--warn);border:1px solid rgba(245,198,93,.3)}
.pill.bald{background:rgba(148,167,199,.12);color:var(--muted);border:1px solid var(--line2)}
.pill.live{background:rgba(55,214,166,.14);color:var(--ok);border:1px solid rgba(55,214,166,.3)}

.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;cursor:pointer;
  border:1px solid var(--line2);background:var(--panel2);color:var(--ink);border-radius:var(--r-m);
  padding:11px 18px;font:inherit;font-size:14.5px;font-weight:600;min-height:46px;
  transition:border-color .18s,transform .15s,box-shadow .2s}
.btn:hover{border-color:var(--cyan-d)}
/* Ohne den cyanfarbenen Schlagschein darunter. Ein farbiger Schein unter
   einem farbigen Knopf verdoppelt die Aussage und macht die Kante weich —
   der Knopf sah aus, als klebe er auf der Seite statt in ihr zu liegen. */
.btn.primary{background:var(--grad);color:#04121b;border:none}
.btn.sm{padding:8px 13px;font-size:13px;min-height:38px;border-radius:var(--r-s)}

.skel{color:var(--muted2);font-size:14.5px;padding:22px 0}
.foot{padding:26px 20px 50px}
.ft{border-top:1px solid var(--line);padding:20px 0;margin-top:20px}
.ft .wrap{display:flex;gap:16px;flex-wrap:wrap;justify-content:space-between;color:var(--muted2);font-size:13px}
.ft a{display:inline-flex;align-items:center;min-height:24px}
.ft a:hover{color:var(--ink)}
/* Die Fusszeile fuehrt seit 2026-08-22 alle Rechtswege einzeln — bis dahin
   stand dort EIN Link („Impressum & Datenschutz"), und AGB wie Widerruf
   waren von der Startseite aus gar nicht erreichbar, obwohl beide fertig
   in `legal.html` lagen. `/os/` fuehrte sie schon; `/` nicht. */
.ftnav{display:flex;gap:14px;flex-wrap:wrap;align-items:center}

/* ---- Produktseite ---- */
.pcrumb{padding:20px 20px 0;font-size:13.5px;color:var(--muted2)}
.pcrumb a{display:inline-flex;align-items:center;min-height:24px}
.pcrumb a:hover{color:var(--ink)}
/* Hero der Produktseite: Text links, Geraet rechts — nicht Text direkt unter
   der Menueleiste. Genau das liess die Seite vorher „blockig" wirken. */
.phero{display:grid;grid-template-columns:1fr .92fr;gap:34px;align-items:center;padding:10px 0 6px}
.pcopy{min-width:0}
.pvisual{min-width:0}
@media(max-width:900px){
  .phero{grid-template-columns:1fr;gap:16px}
  .pvisual{order:-1}
  .buehne{min-height:340px}
  .geraet.phone{width:238px}
  .geraet.phone .glas{min-height:360px}
}
.phead{padding:16px 20px 24px}
.phead .row{display:flex;align-items:center;gap:11px;flex-wrap:wrap;margin-bottom:10px}
.phead h1{font-size:clamp(26px,4.4vw,40px)}
.phead .lead{color:var(--muted);font-size:16px;max-width:680px;margin:0 0 20px}
.pacts{display:flex;gap:11px;flex-wrap:wrap}
.pgrid{display:grid;grid-template-columns:1.25fr .9fr;gap:18px;align-items:start;padding-bottom:14px}
/* Je Spalte ein Behaelter — sonst fuellt das Raster zellenweise und mischt
   linke und rechte Karten durcheinander (siehe Kommentar in produkt.html). */
.pcol{min-width:0;display:flex;flex-direction:column;gap:15px}
.pcol > *{margin-bottom:0}   /* der Abstand kommt aus `gap`, nicht doppelt */
.feat{list-style:none;margin:0;padding:0}
.feat li{position:relative;padding:0 0 0 26px;margin-bottom:10px;color:var(--muted);font-size:14.5px}
.feat li::before{content:"◆";position:absolute;left:0;top:0;color:var(--cyan);font-size:11px;line-height:1.7}
.paket{border:1px solid var(--line);border-radius:var(--r-m);padding:14px 15px;margin-bottom:10px;background:var(--panel)}
.paket.top{border-color:rgba(56,225,255,.4);box-shadow:0 0 0 1px rgba(56,225,255,.12) inset}
.paket .pn{display:flex;align-items:center;gap:8px;font-weight:600;font-size:15px;margin-bottom:2px}
/* Tabellenziffern. In einem Laden ist das kein Feinschliff: ohne sie ist eine
   1 schmaler als eine 8, und untereinanderstehende Preise fluchten nicht —
   „29,99" und „119,00" rutschen gegeneinander. Genau daran erkennt man auf
   den Seiten, die teuer wirken, die Sorgfalt; Stripe verbietet ausdruecklich,
   Geldbetraege ohne `tnum` zu setzen. */
.paket .pp{font-size:17px;font-family:"Space Grotesk",sans-serif;font-variant-numeric:tabular-nums;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.paket .pd{color:var(--muted2);font-size:13px;margin-top:3px}
.tagbest{font-size:10.5px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;
  color:#04121b;background:var(--grad);border-radius:var(--r-pille);padding:2px 8px}
.note{border:1px solid rgba(245,198,93,.3);background:rgba(245,198,93,.08);color:#ffeec2;
  border-radius:var(--r-m);padding:13px 15px;font-size:14px;margin:0 0 18px}
.pnote{color:var(--muted2);font-size:12.5px;margin-top:10px;line-height:1.5}

/* --- Der ausgebaute Teil der Produktseite ---------------------------------
   Bis 2026-08-16 bestand eine Produktseite aus Kopf, EINER Aufzaehlung und
   viel Nichts; die rechte Spalte blieb bei MagnaX OS sogar ganz leer, weil das
   Produkt seine Preise auf der Kaufseite fuehrt. Johannes dazu: „bisschen
   duenn beschrieben … gar nicht ausgearbeitet."

   Dazugekommen sind drei Baender: die Bildstrecke (dieselben echten
   Bildschirmfotos, die vorher nur hinter „Reinschauen" lagen), der
   Fliesstext (`abschnitte`) und die Editionen. Jedes Band blendet sich
   selbst aus, wenn es fuer ein Produkt kein Material gibt — lieber eine
   kuerzere Seite als eine Ueberschrift ohne Inhalt. */
.ph2{font-size:clamp(20px,2.6vw,26px);margin:0 0 6px}
.psub{color:var(--muted);font-size:15px;max-width:70ch;margin:0 0 16px}

.pbilder{padding:10px 20px 26px}
.pbilder .pfen-gruppen{margin-bottom:12px}

/* Der Text steht in zwei Spalten, solange Platz ist: ein Fliesstext ueber die
   ganze Breite eines 1280er Bildschirms liest sich nicht — das Auge verliert
   beim Zeilensprung die Zeile. Enger wird daraus von selbst eine Spalte. */
.ptext{padding:6px 20px 8px;display:grid;grid-template-columns:repeat(auto-fit,minmax(330px,1fr));
  gap:8px 40px;align-items:start}
.pabs{padding:14px 0 10px;border-top:1px solid var(--line)}
.pabs h2{font-size:18px;margin:0 0 8px;color:var(--ink)}
.pabs p{color:var(--muted);font-size:15px;line-height:1.65;margin:0 0 11px;max-width:62ch}
.pabs p:last-child{margin-bottom:0}
.pabs strong{color:var(--ink);font-weight:600}

.ped{padding:16px 20px 10px}
.ped .card{display:flex;flex-direction:column}
.ped .card h3{font-size:19px}
.ped .card .kurz{color:var(--muted2);font-size:13.5px;margin:0 0 8px}
.ped .card p{color:var(--muted);font-size:14.5px;line-height:1.6;margin:0 0 10px}
/* `align-self` ist hier kein Feinschliff, sondern noetig: die Karte ist ein
   Flex-Behaelter in Spaltenrichtung, und ein Kind darin wird quer dazu
   standardmaessig auf die volle Breite GEZOGEN. Das Zeichen stand dadurch
   491 px breit bei 44 px Hoehe in der Karte — zu einem Streifen verzerrt,
   obwohl `width:auto` daransteht. */
.ped .pedmark{--sxmh:44px;align-self:flex-start;margin-bottom:10px;opacity:.95}

@media(max-width:820px){ .pgrid{grid-template-columns:1fr} }
@media(max-width:560px){
  .wrap{padding:0 15px}
  .top .wrap{height:58px;gap:12px}
  .hero{padding:34px 15px 20px}
  .cards{grid-template-columns:1fr}
  .pacts .btn{flex:1 1 auto}
}

/* --- Produktfenster: reinschauen, ohne die Seite zu verlassen --------------
   Ein Fenster je Seite, gefuellt von `produktfenster.js`. Es traegt die
   Bildergalerie (`ausschnitte.js`), bei MagnaX OS Company die Branchenwahl,
   und die Live-Widgets (Geraete-Buehne, Merkmale, Pakete). */
.pfen{position:fixed;inset:0;z-index:240;display:grid;place-items:center;padding:20px}
.pfen[hidden]{display:none!important}
.pfen-hg{position:absolute;inset:0;background:rgba(3,7,14,.82);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);cursor:zoom-out}
body.pfen-offen{overflow:hidden}
.pfen-blatt{position:relative;width:min(1080px,100%);max-height:92vh;overflow-y:auto;overscroll-behavior:contain;
  background:linear-gradient(180deg,var(--panel2),var(--panel));border:1px solid var(--line2);
  border-radius:var(--r-l);padding:22px 24px 24px}
.pfen-blatt::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;border-radius:var(--r-l) var(--r-l) 0 0;
  background:linear-gradient(90deg,var(--akz,#38e1ff),color-mix(in srgb,var(--akz,#38e1ff) 40%,var(--cyan-d)) 42%,transparent 82%)}
.pfen-zu{position:absolute;top:14px;right:14px;z-index:3;cursor:pointer;width:36px;height:36px;border-radius:var(--r-s);
  display:grid;place-items:center;font-size:15px;color:var(--muted);background:rgba(10,20,36,.8);
  border:1px solid var(--line2);transition:color .18s,border-color .18s}
.pfen-zu:hover{color:var(--ink);border-color:var(--cyan-d)}
.pfen-kopf{display:flex;align-items:center;gap:13px;padding-right:44px;margin-bottom:16px}
.pfen-titel{flex:1;min-width:0}
.pfen-kopf h2{font-size:clamp(20px,3vw,27px)}
.pfen-kopf p{margin:2px 0 0;color:var(--muted);font-size:14.5px}
.pmark.gross{width:52px;height:52px;border-radius:var(--r-m);font-size:25px}
/* Ein echtes Logo fuellt die Platte; das Ersatzzeichen bleibt mittig. */
.pmark.hatlogo{background:linear-gradient(152deg,color-mix(in srgb,var(--akz,#38e1ff) 18%,transparent),transparent)}
.pmark i img{display:block;width:100%;height:100%;object-fit:contain}
.pmark.gross i{width:34px;height:34px}
.pmark i{display:grid;place-items:center}
.pmark.hatlogo i{width:72%;height:72%}

.pfen-h{font-size:17px;margin:0 0 3px}
.pfen-sub{color:var(--muted);font-size:14px;margin:0 0 12px;max-width:70ch}
.pfen-gruppen{display:flex;flex-wrap:wrap;gap:7px;margin-bottom:6px}
.pfen-gruppe{display:inline-flex;align-items:center;gap:7px;cursor:pointer;font:inherit;font-size:12.5px;font-weight:600;
  color:var(--muted);background:rgba(13,22,38,.6);border:1px solid var(--line);border-radius:var(--r-s);padding:6px 11px;
  transition:color .18s,border-color .18s,background .18s}
.pfen-gruppe:hover{color:var(--ink)}
.pfen-gruppe[aria-selected="true"]{color:var(--ink);border-color:color-mix(in srgb,var(--bc,#38e1ff) 52%,transparent);
  background:color-mix(in srgb,var(--bc,#38e1ff) 13%,rgba(13,22,38,.6))}
.pfen-galerie{margin-top:4px}
.pfen-galerie.shots{margin-top:10px}
.pfen-keine{color:var(--muted2);font-size:14px;border:1px solid var(--line);border-radius:var(--r-m);
  padding:12px 14px;background:rgba(148,167,199,.06);margin:0 0 4px}

.pfen-widgets{display:grid;grid-template-columns:1fr 1.05fr;gap:20px;align-items:start;margin-top:20px}
.pfen-buehne .buehne{min-height:400px}
.pfen-spalte{display:grid;gap:13px;min-width:0}
/* `safe-area-inset-bottom` = die Gesten-/Systemleiste des Geraets. Ohne den
   Zuschlag klebt der letzte Knopf genau dort, wo das Telefon selbst schon
   etwas zeichnet — treffbar ist er dann nicht mehr zuverlaessig. */
.pfen-fuss{display:flex;gap:11px;flex-wrap:wrap;margin-top:20px;padding-top:16px;
  padding-bottom:env(safe-area-inset-bottom,0px);border-top:1px solid var(--line)}

@media(max-width:820px){
  .pfen{padding:0}
  /* ⚠️ HIER STAND `height:100vh` — und genau das hat die zwei Knoepfe unten
     abgeschnitten (Johannes' Bildschirmfoto vom 2026-08-18, „fast so'n
     versteckt unter der Handyleiste").

     `vh` ist auf dem Telefon die GROSSE Ansicht: gerechnet wird, als waere die
     Adressleiste eingefahren. Sichtbar ist aber weniger. Das Blatt wurde also
     hoeher als das Fenster, und was ganz unten liegt — die Fusszeile mit
     „Details ansehen" und „Reinschauen" — verschwand hinter der Browser- bzw.
     Systemleiste. Kein Scrollen half: das Blatt endete dort, wo man nicht mehr
     hinsieht.

     `dvh` ist die Ansicht, die WIRKLICH da ist, und schrumpft mit der
     eingeblendeten Leiste mit. `vh` bleibt als Rueckfall fuer alte Browser
     davor stehen — die Reihenfolge ist Absicht, nicht Doppelung. */
  .pfen-blatt{max-height:100vh;height:100vh;
    max-height:100dvh;height:100dvh;border-radius:0;width:100%}
  .pfen-widgets{grid-template-columns:1fr}
  .pfen-buehne .buehne{min-height:330px}
  .pfen-fuss .btn{flex:1 1 auto}
}
@media(prefers-reduced-motion:reduce){.pfen-hg{-webkit-backdrop-filter:none;backdrop-filter:none}}

/* --- Die Marke ------------------------------------------------------------
   EIN Aussehen fuer die echte Marke, egal wo sie steht: Kopfleiste,
   Fenster-Ecke, Fusszeile. Vorher stand an drei Stellen ein handgebautes
   Ersatzstueck („M" im Kaestchen + Schrift); das ist ersetzt.

   Das Pulsieren ist bewusst LEISE — ein Schimmer, der ueber das Zeichen
   wandert, kein Blinken. Auf einer Verkaufsseite soll die Marke leben, nicht
   um Aufmerksamkeit betteln. Wer weniger Bewegung eingestellt hat, bekommt
   sie ruhig (`prefers-reduced-motion` ganz unten).

   Bemessen wird ueber die HOEHE, nie ueber die Breite. Die Kopfleiste ist
   62 px hoch (58 px auf dem Telefon); eine ueber die Breite bemessene Marke
   haengt bei jedem anderen Seitenverhaeltnis oben heraus — genau das ist beim
   ersten Einbau passiert. Ueber die Hoehe kann das nicht mehr schiefgehen,
   egal welches Zeichen kommt.

   ZWEI FORMEN, ZWEI ZWECKE — und warum im Kopf das Zeichen steht
   Die Bilddatei gibt es als ganzes Zeichen (Raute mit Schriftzug darin) und
   als Schriftband allein. Naheliegend waere das Schriftband fuer die
   Kopfleiste. Es funktioniert dort aber nicht: der Schriftzug hat drei Zeilen
   (SYMMETRYX / TECHNOLOGIES / ONE), und in 42 px Hoehe wird die mittlere Zeile
   zu einem grauen Strich. Dazu schneidet jeder rechteckige Ausschnitt des
   Schriftbands zwangslaeufig die Raute an — sie ist genau auf Schrifthoehe am
   breitesten. Es sah aus wie ein abgerutschtes Bild.

   Also steht im Kopf das ZEICHEN (klein erkennbar, weil es eine Form ist und
   keine Schrift) und daneben der Name als echter Text — dieselbe Aufteilung,
   die die Kaufseite `/os/` schon immer hatte. Das ist kein Ersatzzeichen: das
   Zeichen ist die Originaldatei, unveraendert. Nur der Name daneben ist Text
   statt Pixel, und der ist damit scharf, vorlesbar und durchsuchbar. */
.sxmarke{display:block;width:auto;height:var(--sxmh,42px);
  filter:drop-shadow(0 0 10px rgba(56,225,255,.22))}
.logo .sxzeichen{--sxmh:40px}
.logoschrift{font-family:"Space Grotesk",sans-serif;font-weight:600;font-size:17px;white-space:nowrap}
@media(max-width:720px){.logo .sxzeichen{--sxmh:34px}.logoschrift{font-size:15.5px}}

/* Der Schimmer laeuft ueber das Zeichen, nicht darunter: die Marke ist
   freigestellt, eine Flaeche dahinter waere als Kasten sichtbar. */
.sxmarke-puls{position:relative;display:inline-block;isolation:isolate;line-height:0}
.sxmarke-puls::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(140,233,255,.45) 50%,transparent 62%);
  background-size:260% 100%;mix-blend-mode:screen;
  -webkit-mask:var(--sxmaske) center/contain no-repeat;mask:var(--sxmaske) center/contain no-repeat;
  animation:sxschimmer 7s ease-in-out infinite}
@keyframes sxschimmer{
  0%,72%   {background-position:180% 0;opacity:0}
  76%      {opacity:1}
  92%,100% {background-position:-80% 0;opacity:0}
}

@media(prefers-reduced-motion:reduce){
  .sxmarke-puls::after{animation:none;opacity:0}
}

/* Die Marke im Fenster: oben links, VOR dem Produktkopf, damit sofort klar
   ist, aus wessen Haus dieses Fenster kommt. Klein gehalten — sie weist aus,
   sie draengt sich nicht vor das Produkt. Rechts bleibt Platz fuer das ✕. */
.pfen-marke{display:flex;align-items:center;gap:9px;margin:-2px 0 14px;padding-right:44px}
.pfen-marke .sxzeichen{--sxmh:30px}
.pfen-marke .logoschrift{font-size:14.5px;letter-spacing:.2px;opacity:.92}

/* ===========================================================================
   FUTURISTISCHE SCHICHT
   ===========================================================================

   Zwei Dinge, die eine Mehrseiten-Website wie eine Anwendung wirken lassen —
   beide vom Browser selbst gerechnet, ohne eine einzige Zeile JavaScript und
   ohne Fremdbibliothek:

     1. Seitenwechsel als Uebergang statt als Weissblitz (`@view-transition`)
     2. Inhalte, die beim Scrollen erscheinen (`animation-timeline: view()`)

   WARUM NICHT MIT JAVASCRIPT: der uebliche Weg dafuer ist ein
   `IntersectionObserver`, der Klassen setzt. Der laeuft im Hauptstrang, also
   genau dort, wo beim Scrollen ohnehin schon gerechnet wird, und er setzt die
   Startzustaende ERST, wenn das Skript geladen ist — bis dahin blitzt der
   fertige Inhalt einmal auf. Die Zeitachse `view()` laeuft im Compositor und
   braucht kein Skript.

   DIE GEFAHR, DIE DABEI IMMER LAUERT — und der Grund fuer die `@supports`-
   Klammer: wer `opacity:0` als Startzustand setzt und die Bewegung dann nicht
   ankommt, hat eine LEERE SEITE. Deshalb steht die Null AUSSCHLIESSLICH
   innerhalb der Abfrage, die beide benoetigten Eigenschaften prueft. Kennt
   der Browser sie nicht, wird nie etwas versteckt; er zeigt schlicht die
   fertige Seite. Das ist kein Nachteil, sondern der Normalfall fuer alle,
   die kein Chromium fahren.
   -------------------------------------------------------------------------- */

/* --- 1) Seitenwechsel ------------------------------------------------------
   Der Shop ist bewusst eine Mehrseiten-Website: jede Produktseite hat eine
   eigene Adresse, ist teilbar und wird von Suchmaschinen einzeln gelesen. Der
   Preis dafuer war bisher der harte Schnitt bei jedem Klick. `@view-transition`
   nimmt ihn weg, ohne dass daraus eine Einseiten-Anwendung wird — wir behalten
   die Adressen UND bekommen den weichen Wechsel.

   Browser, die es nicht koennen, ignorieren die Regel vollstaendig und
   navigieren wie bisher. Es gibt nichts zu prüfen und nichts zu laden. */
@view-transition { navigation: auto; }

/* Kopfleiste und Marke sollen beim Wechsel STEHEN BLEIBEN statt mitzublenden.
   Ohne eigenen Namen behandelt der Browser die ganze Seite als ein Bild und
   blendet auch die Leiste durch sich selbst — das sieht aus wie ein Flackern
   an einer Stelle, an der sich gar nichts geaendert hat. */
/* `header.top`, NICHT `.top`. Die Klasse `top` traegt auch das empfohlene
   Preispaket (`.paket.top`) — mit dem blossen `.top` bekamen auf jeder
   Produktseite mit Empfehlung ZWEI Elemente denselben Uebergangs-Namen, und
   ein doppelter Name laesst den Seitenwechsel komplett ausfallen. Lautlos:
   man sieht dann genau das, was man vorher hatte, und haelt die Sache fuer
   nicht unterstuetzt. */
header.top { view-transition-name: kopfleiste; }
.logo { view-transition-name: hausmarke; }

::view-transition-old(root),
::view-transition-new(root) { animation-duration: .28s; }
/* Die Leiste bewegt sich nicht — sie ist auf beiden Seiten dieselbe. */
::view-transition-old(kopfleiste),
::view-transition-new(kopfleiste),
::view-transition-old(hausmarke),
::view-transition-new(hausmarke) { animation: none; mix-blend-mode: normal; }

/* --- 2) Erscheinen beim Scrollen -------------------------------------------
   Bewegung soll einen Zustandswechsel BESTAETIGEN, nicht ihn inszenieren —
   dieselbe Regel, nach der oben das Anheben beim Ueberfahren rausgeflogen ist.
   Deshalb ist das hier bewusst klein: 10 Pixel und eine Blende, einmal, beim
   Hereinkommen. Kein Zoom, kein Versatz von der Seite, kein Nacheinander mit
   Verzoegerung je Kachel. Wer das gross macht, baut eine Seite, die man beim
   zweiten Besuch nicht mehr sehen will.

   `animation-range: entry 0% cover 22%` heisst: der Vorgang ist abgeschlossen,
   wenn das Element gut ein Fuenftel im Bild ist — nicht erst in der Mitte.
   Sonst liest man an einer Karte vorbei, die noch halb durchsichtig ist. */
@supports (animation-timeline: view()) and (animation-range: entry 0% cover 22%) {
  @media (prefers-reduced-motion: no-preference) {
    @keyframes sxherein {
      from { opacity: 0; transform: translateY(10px); }
      to   { opacity: 1; transform: none; }
    }
    /* Genau die vier Bausteine, die es WIRKLICH gibt: die Produktkacheln im
       Schaufenster, die Karten der Editionen, die Textabschnitte der
       Produktseite (`.pabs`, erzeugt in `produkt.html` -> `langtext()`) und
       die Preispakete. Im ersten Entwurf stand hier `.pabschnitt` — eine
       Klasse, die es nirgends gibt. Ein toter Selektor faellt nie auf: die
       Seite sieht richtig aus, der Abschnitt erscheint nur eben nicht, und
       niemand vermisst etwas, das er nie gesehen hat. */
    .card.prod,
    .ped .card,
    .pabs,
    .paket {
      animation: sxherein linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 22%;
    }
  }
}

/* --- Eingabefelder auf Touch-Geraeten -------------------------------------
   Dieselbe Grenze wie in der Demo, hier fuer den ganzen Shop: unter 16px zoomt
   iOS Safari beim Antippen hinein. Das trifft jedes Formular — Anmeldung,
   Konto, Kasse. Ein Kunde, der beim Tippen der E-Mail-Adresse ploetzlich in
   einer vergroesserten Ansicht steht, haelt die Seite fuer kaputt. */
@media (pointer: coarse) {
  /* `!important` mit Absicht — und das ist hier kein Holzhammer, sondern der
     einzige Weg, der wirkt: die Feld-Groessen stehen in KOMPONENTEN-Regeln
     (`.chatinput input`, `.addtask input`, …), und die sind spezifischer als
     ein blosses `input`. Der erste Entwurf dieser Regel stand ohne
     `!important` da, hat nichts geaendert und sah trotzdem nach Loesung aus.
     Eine Barrierefreiheits-Untergrenze darf nicht davon abhaengen, wer
     spezifischer geschrieben hat. */
  input, select, textarea { font-size: max(16px, 1em) !important; }
}
