/* ==========================================================================
   ZABA & ZINGO — Wahl-Oberflaeche, geteiltes Design-Modul (v9)

   EINE Quelle fuer die Vorwahl, die Klick-Variante und die Scroll-Variante.
   Kein Adapter definiert eigene Farben, Groessen oder Zeiten — wer eine neue
   Variante baut, benutzt diese Datei und setzt nur Inhalt.

   Herkunft (uebernommen, nicht nachgebaut):
   - Kamera-Rahmen  .cam/.cam-corner aus der ersten Zabazingo-Seite (v7.html)
   - Zeiger-Mechanik mix-blend-mode:difference, Nachlauf, aus derselben Quelle
   - Farben, Schriften, Gewichte aus 01-CI.md / 02-TYPOGRAPHY.md
   - Kurve und Dauern aus dem Bewegungssystem (zz-motion.css)
   ========================================================================== */

/* v10: Subset (Latin + Satzzeichen) als WOFF2 — 428,5 KB -> 11,7 KB. Und
   font-display:swap statt block: mit block stand bis zum Eintreffen der
   Datei NICHTS auf der Seite, und das nackte Wort IST die erste Stufe.
   Der Motor vermisst nach fonts.ready ohnehin neu, der Tausch ist gedeckt. */
@font-face{font-family:"NotoSerifDisplay";src:url("fonts/NotoSerifDisplay_ExtraCondensed-Regular.woff2") format("woff2"),url("fonts/NotoSerifDisplay_ExtraCondensed-Regular.ttf") format("truetype");font-weight:400;font-display:swap}
@font-face{font-family:"NotoSerifDisplay";src:url("fonts/NotoSerifDisplay_ExtraCondensed-Bold.ttf") format("truetype");font-weight:700;font-display:block}
@font-face{font-family:"PPNeue";src:url("fonts/PPNeueMontreal-Regular.woff2") format("woff2"),url("fonts/PPNeueMontreal-Regular.otf") format("opentype");font-weight:400;font-display:swap}
@font-face{font-family:"PPNeue";src:url("fonts/PPNeueMontreal-Semibold.otf") format("opentype");font-weight:600;font-display:swap}

:root{
  --bone:#F5F2EA;--ink:#16130F;--night:#141311;--night-ink:#F3EEE4;--signal:#C63A21;
  --mark:"NotoSerifDisplay",Didot,serif;--sans:"PPNeue",-apple-system,system-ui,sans-serif;

  /* Schnitt zwischen den Seiten, vom Motor gesetzt */
  --l:50%;

  /* Lesbarkeits-Boeden — eine Quelle fuer CSS und Motor. Der Motor liest sie
     aus und leitet daraus die maximale Kipp-Reichweite ab. */
  /* v10 nach R4 (Type-Scale Floor): Hilfstext nie unter 14 px. Die alten
     9,5 px trugen zwar den Kontrast (nachgerechnet 6,19:1 bzw. 7,81:1) —
     aber die GROESSE war das Problem, nicht die Farbe. Der Motor liest
     diese Werte aus und leitet daraus die maximale Kipp-Reichweite ab,
     die schmale Seite wird damit von selbst breiter. */
  --floor-name:16px;--floor-line:14px;--floor-pct:14px;

  /* Kamera-Rahmen */
  --frame:clamp(10px,2.2vw,30px);--frame-arm:clamp(16px,3vw,40px);

  /* Bewegungssystem: EINE Kurve, feste Dauern */
  --ease:cubic-bezier(.22,1,.36,1);
  --t-xs:180ms;--t-s:320ms;--t-m:560ms;--t-l:900ms;
}

*{box-sizing:border-box;margin:0}
html,body{height:100%}
/* BBE-STD-SCROLL-001: Scrollen aktiv, Balken unsichtbar */
html,body{scrollbar-width:none}::-webkit-scrollbar{display:none}
body{font-family:var(--sans);background:var(--night);color:var(--night-ink);
     overflow:hidden;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}
/* Scroll-Variante: das Dokument darf laufen, die Buehne bleibt stehen. */
html.mode-scroll,html.mode-scroll body{height:auto;overflow-x:hidden;overflow-y:auto}
/* Strecke fuer den Aufbau: eine Bildhoehe je Stufe plus eine zum Ankommen.
   Fuenf Stufen (Wort, Satz, Verdichtung, Signatur, Video) brauchen mehr Weg
   als vier — sonst liegen die Stufen so dicht, dass ein Wischen zwei nimmt. */
/* v10: svh statt vh. Mit vh rechnet das Telefon gegen die GROSSE Hoehe;
   klappt die Adressleiste ein, feuert resize und der Motor vermisst mitten
   im Scrollen neu. svh ist die kleine, stabile Hoehe. */
.scrolldrive{height:520vh;height:520svh;pointer-events:none}
a{color:inherit;text-decoration:none}

/* ---------- Buehne und Seiten ------------------------------------------- */
.stage{position:fixed;inset:0;display:flex;overflow:hidden;z-index:1}
/* container-type:size statt inline-size — die Schrift muss auch an der HOEHE
   der Seite haengen koennen, sonst laesst sich die Flaeche auf dem Telefon
   nicht waagerecht teilen. Beide Seiten haben in beiden Achsen ein festes Mass. */
.side{position:relative;display:flex;align-items:center;justify-content:center;
      min-width:0;min-height:0;overflow:hidden;outline:none;container-type:size;
      -webkit-tap-highlight-color:transparent}
.side:focus-visible{box-shadow:inset 0 0 0 2px var(--signal)}

/* GRUNDZUSTAND = quer geteilt, die Wahl steht uebereinander.
   v10 nach R6 (Mobile-First): vorher war nebeneinander der Grundzustand und
   die schmale Lage der Sonderfall — mit der Folge, dass jedes Geraet, das
   durch die 640-px-Weiche fiel, zwei gequetschte Spalten bekam. Auf dem iPad
   hoch waren das gemessen 313 px und 455 px in einem 1024 px hohen Bild.
   Jetzt ist die schmale Lage der Ausgangspunkt und die Breite die Zugabe. */
.stage{flex-direction:column}
#sideL{width:100%;height:var(--l)}
#sideR{width:100%;height:auto;flex:1 1 auto}
#sideL{background:var(--night);color:var(--night-ink)}
#sideR{background:var(--bone);color:var(--ink)}
.divider{position:fixed;left:0;right:0;top:var(--l);height:2px;margin-top:-1px;
         background:var(--signal);z-index:6;pointer-events:none}

/* ERWEITERUNG = laengs geteilt. Nur wo beide Seiten wirklich Breite haben:
   ab 641 px im Querformat (Telefon quer, Tablet quer) und ab 1025 px in
   jeder Lage. Ein Tablet im Hochformat bleibt damit gestapelt. */
@media (min-width:641px) and (orientation:landscape),(min-width:1025px){
  .stage{flex-direction:row}
  #sideL{width:var(--l);height:auto}
  #sideR{width:auto;flex:1 1 auto;height:auto}
  .divider{top:0;bottom:0;left:var(--l);right:auto;width:2px;height:auto;
           margin:0 0 0 -1px}
}

/* ---------- Kamera-Rahmen: je Ecke ein waagerechter und ein senkrechter
     Strich. Jede Seite zeichnet ihre eigenen zwei Ecken in ihrer eigenen
     Tinte — dadurch sitzen alle vier Ecken in den Bildkanten und tragen in
     beiden Haelften genug Kontrast. -------------------------------------- */
.cam{position:absolute;inset:0;pointer-events:none;z-index:4}
.cam span{position:absolute;width:var(--frame-arm);height:var(--frame-arm);
          border:0 solid currentColor;opacity:.5}
.cam .tl{top:var(--frame);left:var(--frame);border-top-width:1px;border-left-width:1px}
.cam .bl{bottom:var(--frame);left:var(--frame);border-bottom-width:1px;border-left-width:1px}
.cam .tr{top:var(--frame);right:var(--frame);border-top-width:1px;border-right-width:1px}
.cam .br{bottom:var(--frame);right:var(--frame);border-bottom-width:1px;border-right-width:1px}
/* Welche zwei Ecken eine Seite zeichnet, haengt an der Teilung: quer traegt
   die obere Seite die oberen, laengs traegt die linke Seite die linken. So
   sitzen die vier Klammern immer in den vier BILD-Kanten, nie in der
   Trennlinie. Grundzustand ist quer, passend zu R6. */
#sideL .cam .bl,#sideL .cam .br,#sideR .cam .tl,#sideR .cam .tr{display:none}
@media (min-width:641px) and (orientation:landscape),(min-width:1025px){
  #sideL .cam span,#sideR .cam span{display:block}
  #sideL .cam .tr,#sideL .cam .br,#sideR .cam .tl,#sideR .cam .bl{display:none}
}

/* ---------- Video-Ebene (letzte Stufe) ---------------------------------
     Muster uebernommen aus zaba/zingo hero-v: Video, darueber ein Schleier
     in der Grundfarbe der Seite, darueber der Satz. Der Schleier haelt den
     Kontrast unabhaengig vom Bildinhalt.
     `.on` traegt IMMER nur eine der beiden Seiten — die unter dem Zeiger.
     Gesetzt wird die Klasse ausschliesslich in videoSicht() (wahl.js); die
     erreichte Stufe allein macht kein Bild sichtbar, sie macht die Seite nur
     bereit (`data-bereit`). Wer das hier auf `[data-bereit]` umschreibt, holt
     die zwei gleichzeitig laufenden Filme zurueck. ---------------------- */
.vid{position:absolute;inset:0;z-index:1;opacity:0;pointer-events:none;
     transition:opacity var(--t-l) var(--ease)}
.vid.on{opacity:1}
.vid video{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.vid .veil{position:absolute;inset:0}
#sideL .vid .veil{background:rgba(20,19,17,.78)}
#sideR .vid .veil{background:rgba(245,242,234,.84)}

/* ---------- Satzblock --------------------------------------------------
     Alle Zeilen laufen auf EINE Breite: die der Wortmarke. Der Motor setzt
     .lock auf diese Breite und rechnet jede Zeile per Schriftgroesse plus
     Rest-Ausgleich exakt darauf — links und rechts buendig auf den Pixel.
     Weil kuerzerer Text auf gleicher Breite groesser wird, waechst die
     Schrift mit jeder Verdichtungsstufe von selbst. --------------------- */
.inner{position:relative;z-index:3;display:flex;flex-direction:column;
       align-items:center;justify-content:center;width:100%;min-width:0;
       padding-inline:clamp(3px,5cqw,56px)}
.lock{display:block;max-width:100%;text-align:center}
/* Zeile als Flex-Mitte, nicht als Text-Mitte: eine Inline-Box, die breiter als
   ihr Block ist, wird von text-align nicht mehr zentriert — der Ueberhang faellt
   dann einseitig an und die Zeile sitzt versetzt. In der Flex-Mitte laeuft er
   symmetrisch, die Zeile bleibt in jedem Fall auf der Achse. */
/* Der Abstand steht EINMAL als --gap. Hoehe, Deckkraft und Abstand einer
   Aufbau-Reihe haengen danach an derselben Zahl --rev (0..1) — so kann der
   Motor eine Reihe stufenlos aufblaettern, ohne eine zweite Wahrheit ueber
   den Abstand zu fuehren. */
.row{display:flex;justify-content:center;text-align:center;--gap:clamp(1px,.7cqw,.5rem)}
/* align-self ist Pflicht, nicht Kosmetik: als Flex-Kind wuerde die Zeile sonst
   auf die Hoehe ihrer Reihe gedehnt — und eine eingeklappte Reihe ist null hoch.
   So behaelt die Zeile ihre eigene Hoehe, die Reihe klappt darueber auf. */
.row>*{flex:0 0 auto;align-self:flex-start;min-width:0}
.row+.row{margin-top:var(--gap)}
.row.rev{height:0;opacity:0;overflow:hidden;margin-top:0;
         transition:height var(--t-l) var(--ease),opacity var(--t-m) linear,
                    margin-top var(--t-l) var(--ease)}
.row.rev.on{height:var(--h);opacity:1;margin-top:var(--gap)}
/* Vom Verweilen gefuehrt: der Motor setzt --rev je Bild selbst. Eine
   CSS-Zeit liefe dagegen und wuerde die Bewegung von der Hand entkoppeln —
   genau das soll sie nicht: sie soll AN der Hand haengen. */
.row.rev.grow{transition:none;height:calc(var(--h) * var(--rev,0));
              opacity:var(--rev,0);margin-top:calc(var(--gap) * var(--rev,0));
              /* Weiche Kante statt Schnittkante: eine halb aufgebaute Reihe
                 zeigt sonst oben heile Buchstaben und unten eine Guillotine.
                 Beim schnellen CSS-Uebergang faellt das nicht auf — beim
                 Verweilen steht der Zwischenstand still und muss tragen. */
              -webkit-mask-image:linear-gradient(to bottom,#000 calc(var(--rev,0) * 92%),transparent 100%);
              mask-image:linear-gradient(to bottom,#000 calc(var(--rev,0) * 92%),transparent 100%)}

/* Eine Schrift, EIN Gewicht — der Akzent laeuft ueber Groesse, nicht ueber
   Fettung (Operator 2026-07-28: das B von BELIEVE war zu fett). */
.ln{display:inline-block;font-family:var(--mark);font-weight:400;
    text-transform:uppercase;white-space:nowrap;line-height:1.02;
    transform-origin:50% 50%;opacity:calc(var(--base,1) * var(--fade,1));
    transition:opacity var(--t-s) linear}
/* v10: Deckel von 150 auf 260 px. Bei 150 wuchs die Komposition ab rund
   1100 px Seitenbreite nicht mehr mit — auf 2560x1440 gemessen: Seite
   1154 px breit, Marke 150 px = 13 % der Breite. Unter 1100 px aendert
   sich nichts, dort greift ohnehin min(17cqw,22cqh). */
.mark{--base:1;letter-spacing:-.04em;line-height:1}
.say{--base:.92;letter-spacing:.02em}
.cut{--base:.86;letter-spacing:.02em}
.sig{--base:1;letter-spacing:-.02em}

/* Mobile zuerst, jetzt auch in der Reihenfolge: quer geteilt ist die HOEHE
   der Seite das knappe Mass, nicht die Breite — deshalb darf die Wortmarke
   hier mehr von der Flaeche nehmen. */
.mark,.sig{font-size:clamp(var(--floor-name),min(24cqw,34cqh),260px)}
.say,.cut{font-size:clamp(var(--floor-line),min(6cqw,9cqh),27px)}
@media (min-width:641px) and (orientation:landscape),(min-width:1025px){
  .mark,.sig{font-size:clamp(var(--floor-name),min(17cqw,22cqh),260px)}
  .say,.cut{font-size:clamp(var(--floor-line),3.2cqw,27px)}
}
/* Telefon quer: viel Breite, sehr wenig Hoehe — dort fuehrt die Hoehe. */
@media (min-width:641px) and (max-width:860px){
  .mark,.sig{font-size:clamp(var(--floor-name),min(21cqw,22cqh),260px)}
}

/* Fuer Screenreader sichtbar, im Bild nicht: die Seite hatte bisher keine
   einzige Ueberschrift und damit keine Struktur. */
/* font:inherit ist Pflicht, nicht Kosmetik: eine h1 erbt sonst fette
   Schrift und zieht dafuer einen zweiten Schriftschnitt ueber das Netz —
   fuer Text, den niemand sieht. */
.vh{font:inherit;position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
    clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* ---------- Prozent und Eintritt --------------------------------------- */
.pct{font-family:var(--sans);font-size:clamp(var(--floor-pct),2.1cqw,16px);
     letter-spacing:clamp(.06em,.9cqw,.18em);margin-top:clamp(4px,3.4cqw,1.1rem);
     font-variant-numeric:tabular-nums;opacity:.68}
/* v10: Trefferflaeche. Gemessen auf 390x844 war der Eintritt 37x17 px —
   WCAG 2.5.8 und die Apple-Vorgabe verlangen 44x44. Die Flaeche kommt per
   ::after, die Optik bleibt Zeile mit Unterstrich. */
.enter{position:relative;display:inline-block;font-family:var(--sans);text-transform:uppercase;
       font-size:clamp(14px,1.5cqw,15px);letter-spacing:clamp(.12em,1.4cqw,.24em);
       margin-top:clamp(6px,4.6cqw,1.6rem);white-space:nowrap;
       border-bottom:1px solid currentColor;padding-bottom:.35rem;
       opacity:0;transform:translateY(4px);
       transition:opacity var(--t-s) var(--ease),transform var(--t-s) var(--ease)}
.enter::after{content:"";position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
              min-width:44px;min-height:44px;width:100%;height:100%}
.side:hover .enter,.side:focus-within .enter,.enter:focus-visible{opacity:.85;transform:none}
/* Ohne Zeiger gibt es kein Hover: auf dem Telefon steht der Eintritt offen. */
@media (pointer:coarse){.enter{opacity:.85;transform:none}}
/* Reine Scroll-Variante: der Eintritt kommt erst am Ende des Aufbaus.
   Die kombinierte Variante zeigt ihn von Anfang an — dort ist Klicken erlaubt. */
.stage[data-mode="scroll"] .enter{opacity:0;transform:translateY(4px)}
.stage[data-mode="scroll"].enter-on .enter{opacity:.85;transform:none}
@container (max-width:120px){.enter{display:none}}
@container (max-height:160px){.enter{display:none}}
@container (max-width:70px){.inner{padding-inline:1px}.pct{letter-spacing:.04em}}

/* Zweiter Weg unter dem Eintritt: hineingehen ODER weiterscrollen. Er steht
   nur, solange es noch etwas aufzubauen gibt — am Ende der Strecke fuehrt
   allein der Eintritt weiter, dann waere die Zeile eine Sackgasse.
   Deckkraft wie .pct (.68), weil dieser Wert auf beiden Haelften AA traegt. */
/* v10: Boden von 7,5 auf 9 px und weniger Laufweite — bei 7,5 px mit .2em
   zerfaellt das Wortbild. Kontrast war nie das Problem (nachgerechnet
   6,19:1 auf Knochen, 7,81:1 auf Nacht), die GROESSE war es. */
.also{display:none;font-family:var(--sans);text-transform:uppercase;
      font-size:14px;letter-spacing:clamp(.08em,1.1cqw,.16em);
      margin-top:clamp(4px,2.4cqw,.8rem);white-space:nowrap;
      opacity:0;transform:translateY(4px);
      transition:opacity var(--t-s) var(--ease),transform var(--t-s) var(--ease)}
.also .pf{display:inline-block;width:11px;height:11px;vertical-align:-1px;margin-left:.35em}
.also .pf svg{display:block;width:100%;height:100%}
/* Er gehoert zum Eintritt und kommt mit ihm — allein stehend haette die
   Zeile keinen Bezug und saehe aus wie ein verlorener Rest. */
.side:hover .also,.side:focus-within .also{opacity:.68;transform:none}
@media (pointer:coarse){.also{opacity:.68;transform:none}}
.stage.enter-on .also{opacity:0;transform:translateY(4px)}
/* Das "or" gehoert zum Eintritt. Im Scroll-Modus steht der Eintritt bis zur
   letzten Stufe auf 0 — dann ist "ODER weiterscrollen" ein Oder ohne erste
   Option. Solange der Eintritt fehlt, faellt nur das Wort "or" weg. */
.stage[data-mode="scroll"]:not(.enter-on) .alt{display:none}
/* Quer geteilt standen drei Anleitungen gleichzeitig auf 390 px: zweimal
   "or keep scrolling" plus der Hinweis am Bildrand. Der Hinweis genuegt —
   deshalb steht der zweite Weg erst, wenn die Flaeche laengs geteilt ist. */
@media (min-width:641px) and (orientation:landscape),(min-width:1025px){.also{display:block}}
@container (max-width:120px){.also{display:none}}
@container (max-height:160px){.also{display:none}}

/* ---------- Verweil-Anzeige --------------------------------------------
     Der Aufbau haengt am Zeiger: bleibt er auf einer Seite, blaettert sie
     sich auf; geht er weg, legt sie sich zurueck. Ohne Rueckmeldung wirkt
     das wie Zufall — diese Linie unter dem Block laeuft mit der Verweildauer
     aus der Mitte auf und macht die Ursache sichtbar. Sie ist Anzeige, keine
     Zierde: bei 0 ist sie nicht da, bei 1 kippt die Stufe. -------------- */
/* v10: Diese Linie ist die EINZIGE Rueckmeldung, die die Verweil-Mechanik
   erklaert — und sie war 1 px bei .55 Deckkraft, auf einem 3x-Schirm ein
   Haar. Am Finger 2 px, und kurz vor dem Kippen faerbt sie sich: dann
   sieht man die Stufe kommen, statt sie zu erleben. */
.dwell{width:clamp(34px,16cqw,120px);height:1px;background:currentColor;
       margin-top:clamp(4px,2.2cqw,14px);opacity:calc(.55 + var(--dw,0) * .35);
       transform:scaleX(var(--dw,0));transform-origin:50% 50%;
       transition:opacity var(--t-s) linear,background-color var(--t-s) linear}
@media (pointer:coarse){.dwell{height:2px}}
.side[data-nah="1"] .dwell{background:var(--signal)}
@container (max-height:160px){.dwell{display:none}}
@media (prefers-reduced-motion:reduce){.dwell{transition:none}}

/* ---------- Hinweis: wie die Seite bedient wird -------------------------
     Ohne ihn versteht die Scroll-Variante niemand. Er liegt ueber die volle
     BILD-Breite in jeder Seite — die Trennlinie schneidet die Zeile, und jede
     Haelfte zeichnet ihren Teil in ihrer eigenen Tinte. Dadurch traegt der
     Hinweis in beiden Haelften Kontrast, ohne Kasten und ohne Blendmodus.
     Muster und Bewegung uebernommen aus der ersten Zabazingo-Seite
     (.zoom-hint mit springendem Pfeil). ---------------------------------- */
.hint{position:absolute;width:100vw;text-align:center;pointer-events:none;z-index:5;
      bottom:calc(var(--frame) + var(--frame-arm) + clamp(10px,2vw,24px));
      font-family:var(--sans);text-transform:uppercase;
      font-size:clamp(14px,1.05vw,15px);letter-spacing:.18em;opacity:.72;
      transition:opacity var(--t-m) linear}
/* Grundzustand quer: die untere Seite liegt am Bildrand, dort steht der
   Hinweis — einmal, nicht zweimal. */
#sideL .hint{display:none}
#sideR .hint{right:auto;left:0;width:100%}
@media (min-width:641px) and (orientation:landscape),(min-width:1025px){
  #sideL .hint{display:block;left:0;width:100vw}
  #sideR .hint{right:0;left:auto;width:100vw}
}
/* v10 nach R2: kein Pseudo-Symbol aus dem Zeichensatz, sondern eine Form.
   Ein Pfeil-Glyph rendert je Betriebssystem anders und skaliert nicht mit. */
.hint .arw{display:block;margin:9px auto 0;width:14px;height:14px;
           animation:hintdown 2s var(--ease) infinite}
.hint .arw svg{display:block;width:100%;height:100%}
@keyframes hintdown{0%,100%{transform:translateY(0);opacity:.6}50%{transform:translateY(6px);opacity:1}}
/* Sobald der Nutzer angefangen hat, hat der Hinweis seine Arbeit getan. */
.stage.moved .hint{opacity:0}

@media (prefers-reduced-motion:reduce){.hint .arw{animation:none}}

/* ---------- Zeiger: ueber dem Satz wird er zur Signatur ----------------
     EFF auf der ZABA-Seite, DBE auf der ZINGO-Seite. mix-blend-mode
     difference haelt ihn in beiden Haelften und auf den Buchstaben lesbar. */
.cur{position:fixed;left:0;top:0;z-index:20;pointer-events:none;opacity:0;
     font-family:var(--mark);font-weight:400;text-transform:uppercase;
     letter-spacing:.06em;line-height:1;color:var(--bone);
     font-size:clamp(15px,1.7vw,26px);mix-blend-mode:difference;
     transition:opacity var(--t-s) linear;will-change:transform}
.cur.on{opacity:1}
@media (pointer:fine){.lock{cursor:none}.lock *{cursor:none}}
@media (pointer:coarse){.cur{display:none}}

/* ---------- Vorwahl KLICK / SCROLL ------------------------------------- */
.pick{position:fixed;inset:0;display:flex;flex-direction:column;
      align-items:center;justify-content:center;background:var(--night);
      color:var(--night-ink);container-type:inline-size;overflow:hidden}
.pick .lock{width:auto}
.pick .row{--gap:clamp(2px,1.1cqw,14px)}
.pick .ln{font-size:clamp(38px,min(21cqw,26vh),200px);letter-spacing:-.04em}
/* Ruhezustand ebenfalls AA-fest (BBE-STD-CONTRAST-001, beide Zustaende) */
.pick a{display:block;opacity:.58;transition:opacity var(--t-s) var(--ease)}
.pick a:hover,.pick a:focus-visible{opacity:1;outline:none}
.pick .kicker{font-family:var(--sans);text-transform:uppercase;
              font-size:clamp(9px,1.1cqw,11px);letter-spacing:.28em;opacity:.5;
              margin-bottom:clamp(14px,3cqw,34px)}

@media (prefers-reduced-motion:reduce){
  .row.rev,.vid,.enter,.cur,.pick a,.ln{transition-duration:1ms}
}

/* ==========================================================================
   v10 — UX-BAUFORMEN, je Fassung zuschaltbar

   Der Motor bleibt EINER. Was eine Fassung anders macht, haengt an einer
   Kennung auf <html> (ux-snap, ux-vt, ux-puls, ux-haptik, ux-gedaechtnis),
   gesetzt aus data-ux im Markup oder aus ?ux=... in der Adresse. Damit gibt
   es keine fuenf Abschriften dieser Datei, die auseinanderlaufen.
   ========================================================================== */

/* ---- Hinweis-Text: die Maus ruht, der Finger liegt. Zwei Woerter, eine
        Wahrheit im Markup — die Geraeteklasse waehlt aus. ------------------ */
.h-finger{display:none}
@media (pointer:coarse){.h-maus{display:none}.h-finger{display:inline}}

/* ---- ux-snap: die Stufen rasten ein ---------------------------------------
     Ohne Rasten landet ein Wisch zwischen zwei Staenden. Die Marken setzt der
     Motor aus DERSELBEN STOP-Liste, aus der er auch anfaehrt — nicht aus einer
     zweiten Zahl in dieser Datei. "proximity" statt "mandatory": die Seite
     zieht nach, sie reisst nicht. */
.scrolldrive{position:relative}
.snapmark{position:absolute;left:0;width:1px;height:1px;pointer-events:none;
          scroll-snap-align:start;scroll-snap-stop:normal}
@media (prefers-reduced-motion:reduce){html.ux-snap{scroll-snap-type:none}}

/* ---- ux-vt: der Eintritt ist ein Uebergang, kein Seitenwechsel -------------
     Die gewaehlte Haelfte laeuft auf und wird zur naechsten Seite. Der Motor
     faehrt --l dabei auf 0 bzw. 100 — es ist dieselbe Trennlinie, nur zu Ende
     gedacht. Faellt die Bewegung aus, navigiert der Verweis ganz normal. */
.stage.geht .inner{transition:opacity 300ms var(--ease),transform 460ms var(--ease)}
.stage.geht .side:not(.gewaehlt) .inner{opacity:0;transform:scale(.94)}
.stage.geht .side.gewaehlt .inner{transform:scale(1.08)}
.stage.geht .side.gewaehlt .enter,.stage.geht .side.gewaehlt .pct,
.stage.geht .side.gewaehlt .also,.stage.geht .side.gewaehlt .dwell{opacity:0;transition:opacity 200ms linear}
.stage.geht~.divider,.stage.geht .hint,.stage.geht .cam{opacity:0;transition:opacity 260ms linear}
@media (prefers-reduced-motion:reduce){.stage.geht .inner{transition-duration:1ms}}

/* ---- ux-puls: die Trennlinie traegt den Fortschritt ------------------------
     Kein Balken, kein Abzeichen, keine Anzeige von aussen: die rote Linie ist
     ohnehin das Leitelement der Seite, sie bekommt nur eine Aufgabe dazu.
     Ein heller Abschnitt waechst mit der Strecke. */
.divider{overflow:hidden}
.fuellung{position:absolute;inset:0;background:var(--night-ink);opacity:.92;
          transform:scaleY(var(--prog,0));transform-origin:50% 0;
          transition:transform 220ms var(--ease)}
@media (max-width:640px),(orientation:portrait) and (max-width:1024px){
  .fuellung{transform:scaleX(var(--prog,0));transform-origin:0 50%}
}
html:not(.ux-puls) .fuellung{display:none}
/* Kamera-Verschluss: beim Stufenwechsel ziehen sich die vier Klammern kurz zu. */
html.ux-puls .cam span{transition:transform 240ms var(--ease),opacity 240ms linear}
html.ux-puls .side.blinzelt .cam span{transform:scale(.86);opacity:.9}
@media (prefers-reduced-motion:reduce){
  html.ux-puls .cam span,.fuellung{transition-duration:1ms}
}

/* ---- ux-haptik: die kalte Seite tritt zurueck ------------------------------
     Bisher stand die kalte Seite nur still. Sie soll spuerbar zuruecktreten,
     damit die heisse Seite die Wahl IST und nicht nur die schnellere. */
html.ux-haptik .inner{transition:opacity var(--t-m) linear}
html.ux-haptik .side[data-kalt="1"] .inner{opacity:.55}
/* Die Signatur gibt es bisher nur unter der Maus. Am Finger blitzt sie an der
   Tippstelle auf — sonst fehlt auf dem Telefon die halbe Zeiger-Idee. */
.tipp{position:fixed;z-index:21;pointer-events:none;opacity:0;
      font-family:var(--mark);font-weight:400;text-transform:uppercase;
      letter-spacing:.06em;line-height:1;color:var(--bone);
      font-size:clamp(18px,7vw,40px);mix-blend-mode:difference;
      transform:translate(-50%,-50%) scale(.86);
      transition:opacity 520ms linear,transform 520ms var(--ease)}
.tipp.an{opacity:1;transform:translate(-50%,-50%) scale(1);transition-duration:120ms}
@media (prefers-reduced-motion:reduce){.tipp{transition-duration:1ms}}

/* ---- ux-gedaechtnis: die Zahl ist die Verweilverteilung, nicht die Geometrie
     Die Prozentzahl stand bisher fuer die Lage der Trennlinie. In dieser
     Bauform steht sie fuer das, was der Besucher tatsaechlich getan hat. Der
     Motor schreibt sie, diese Datei setzt nur die Schrift ein Haar fester,
     damit man merkt: das ist eine Aussage, keine Dekoration. */
html.ux-gedaechtnis .pct{opacity:.82;letter-spacing:clamp(.08em,1cqw,.2em)}
