/* ==========================================================================
   tupiano.ch — gemeinsames Stylesheet (Neubau, interne Vorschau)

   Farben und Schriften folgen dem CI-Basis-Dokument der Tupiano AG
   (Kernpalette Mokka/Espresso/Anthrazit/Sand/Creme, IBM Plex als Hausschrift,
   selbst gehostet). Layout, Raster, Abstände, Timings und Copy folgen dem
   Design-Handoff der Produkt-Onepager.

   Die Akzentfarbe setzt jede Seite in ihrem <head>: --acc
   ========================================================================== */

/* ---------- Schriften (lokal, keine Google-Fonts-CDN) ----------
   Die Pfade sind absolut ab Domainwurzel. Relativ gingen sie nur dort auf,
   wo das Cockpit die CSS ausliefert (cockpit.php liegt in der Wurzel); wer
   data/website/*.html direkt im Browser oeffnet, bekam Systemschriften.
   Absolut stimmt es in beiden Faellen und spaeter auch auf der Live-Seite. */
@font-face {
  font-family: 'IBM Plex Sans';
  src: url('/assets/fonts/ibm-plex-sans-var.woff2') format('woff2');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Serif';
  src: url('/assets/fonts/ibm-plex-serif-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Serif';
  src: url('/assets/fonts/ibm-plex-serif-700.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/assets/fonts/ibm-plex-mono-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('/assets/fonts/ibm-plex-mono-500.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ---------- Tokens ---------- */
:root {
  /* CI-Kernpalette */
  --mokka: #a67a64;
  --espresso: #6e4f42;
  --anthrazit: #353333;
  --sand: #e5d2c8;
  --creme: #f6f0eb;

  /* Flächen (Abstufungen des Handoffs, auf die CI-Palette gezogen) */
  --paper: #efe4d6;
  --band: #e7dbca;
  --card: #f7f1e9;
  --card-hi: #fbf8f3;
  --shell: #f3ebe0;
  --chip: #eee2d3;

  /* Linien */
  --line: #dccbb8;
  --line-soft: #d3bfa9;
  --line-strong: #c9b39b;
  --line-dash: #c2ab92;

  /* Text */
  --ink: #2b2724;          /* 11,8:1 */
  --ink-title: #5c4034;    /* 7,5:1 */
  --ink-2: #6b5a50;        /* 5,2:1 */
  --ink-3: #857267;        /* 3,64:1 – nur für Hinweise */
  --ink-4: #9c8a7e;

  /* Dunkelflächen */
  --dark: #33312f;
  --dark-net: #3a3a3d;
  --on-dark: #e6dcd2;
  --on-dark-2: #8e8983;

  /* Warnung / Abwehr */
  /* Werte gemessen: Wand und Beschriftung gegen den Grund #efe4d6,
     die Angaben im fremden Netz gegen #3a3a3d */
  --warn: #a8452b;         /* Linie, Punkt, Rahmen — 4,7:1 auf Grund */
  --warn-label: #8f3117;   /* 9,5px auf der Wand — 6,4:1 */
  --warn-text: #eeb9a6;    /* auf dunkel — 6,6:1 */
  --warn-icon: #f0b7a4;    /* auf dunkel — 6,5:1 */
  --warn-line: #a05a44;
  /* Schraffur der Hauswand – auf beiden Produktseiten dieselbe, damit die
     Grenze als dasselbe Element gelesen wird */
  --wall-hatch: repeating-linear-gradient(45deg, rgba(163, 67, 39, .4) 0 3px, transparent 3px 7px);

  /* Statusgrün des Punkts im Status-Badge – gedeckt und warm, damit es neben
     dem Mokka nicht als Fremdfarbe wirkt */
  --live: #5f8f63;

  /* Akzent — pro Seite überschrieben. --acc färbt Flächen, --acc-ink Text:
     das helle Blau von 2cloudAI_ erreicht als Schrift auf Beige kein AA,
     deshalb trägt dort das dunkle Blau der Produktgruppe die Schrift. */
  --acc: #a67a64;
  --acc-ink: #5c4034;
  /* Gewählte Bedienelemente (Menüpunkt, Reiter, Knöpfe, aktueller Schritt)
     und die Pseudonym-Kärtchen der wandernden Karte:
     --acc-fill ist die Fläche, --acc-fill-ink die Schrift darauf,
     --acc-fill-ink-2 der Nebentext. Sonst das dunkle --acc-ink mit Weiss; bei
     2cloudAI_ wäre das das Blau von 2AI_, die Seite sähe aus wie das
     Nachbarprodukt. Dort tragen sie das helle Produktblau, mit dunkler
     Schrift: Weiss käme darauf nur auf 3,0:1, --ink auf 4,9:1. Der Nebentext
     bleibt dort voll dunkel — mit 92 % Deckung fiele er unter 4,5:1. */
  --acc-fill: var(--acc-ink);
  --acc-fill-ink: #fff;
  --acc-fill-ink-2: rgba(255, 255, 255, .92);
  --acc-soft: color-mix(in oklab, var(--acc) 55%, white);
  --acc-tint: color-mix(in oklab, var(--acc) 16%, transparent);
  --acc-ring: color-mix(in oklab, var(--acc) 30%, transparent);

  /* Raster */
  --wrap: 1180px;
  --pad: 32px;

  /* Easing */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --ease-strong: cubic-bezier(.16, .84, .28, 1);
  --ease-over: cubic-bezier(.2, 1.5, .5, 1);
}

/* ---------- Grundlagen ---------- */
* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
  font-size: 16px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--acc-ink); text-decoration: none; }
a:hover { color: var(--espresso); text-decoration: underline; }

h1, h2, h3 {
  font-family: 'IBM Plex Serif', Georgia, serif;
  font-weight: 700;
  color: var(--ink-title);
  margin: 0;
  text-wrap: pretty;
}

/* Abschnittstitel ausgleichen statt die erste Zeile zu füllen: balance
   erzeugt nie eine Zeile mehr, verteilt nur um. Browser ohne balance
   behalten pretty [Hinweis Udo, 27.10.2026]. */
h2.rv-h2 { text-wrap: balance; }

/* Sinneinheit in einer Überschrift zusammenhalten. inline-block statt
   white-space: nowrap – passt die Einheit nicht mehr in die Spalte, bricht
   sie in sich um, statt seitlich herauszuragen (bei 320 px vier Titel). */
.nobr { display: inline-block; }

.mono { font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace; }
.serif { font-family: 'IBM Plex Serif', Georgia, serif; }
.acc { color: var(--acc-ink); }
.dim { color: var(--ink-3); }

.wrap {
  max-width: var(--wrap);
  margin: 0 auto;
  padding-left: var(--pad);
  padding-right: var(--pad);
}

section { position: relative; }
.band { background: var(--band); border-top: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.sec { padding-top: clamp(34px, 4.5vh, 54px); padding-bottom: clamp(34px, 4.5vh, 54px); }

/* ---------- Markenzeichen (Signet) ----------
   Eine Figur aus Kopfquadrat und Schulterblock, Standlinie 83 im Feld
   100 × 100, Inhaltsfeld 17–83. Jedes Zeichen stellt der Figur eine Zweitform
   daneben: die Dachmarke eine Kachel mit gerastertem Herz — Herz in der
   Maschine, der Raster nimmt ihm das Pathos; bei sozial ein Kind; bei 2AI_
   ein Serverturm aus drei Modulen mit Status-Punkt — der KI-Server im Haus;
   bei 2cloudAI_ die gerasterte Wolke über zwei Servermodulen — gerastert
   heisst pseudonymisiert, nur so verlassen Daten das Haus.

   »ko« sind Freistellungsformen in Kachelfarbe: sie legen eine Fuge zwischen
   Figur und Zweitform, ohne Kontur. »loch« sind Aussparungen in Kachelfarbe
   auf den Creme-Formen (Herzpixel, Status-Punkte der Module); die Wolkenpixel
   sind Creme und darum »form«.

   Beim Laden steigt die Figur auf, danach blendet die Zweitform auf.
   »tp-anim« startet beim Laden, »tp-wait« beim Einblenden des Blocks. */
.tpmark { display: block; flex: none; width: auto; height: auto; --d0: 0s; --mark-tile: var(--acc); }
.tpmark--dach { --mark-tile: var(--mokka); }
.tpmark .tile,
.tpmark .ko,
.tpmark .loch { fill: var(--mark-tile); }
.tpmark .form { fill: var(--creme); }
/* Armnaht und Freistellung von Kind/Wolke sind Konturen, nicht Flächen */
.tpmark .naht { fill: none; stroke: var(--mark-tile); }
.tpmark .kof  { fill: var(--mark-tile); stroke: var(--mark-tile); }
.tpmark .fig,
.tpmark .zweit { transform-box: fill-box; }
.tpmark .fig { transform-origin: 50% 100%; }
.tpmark .zweit { transform-origin: 50% 50%; }

.tpmark.tp-anim .tile { animation: tpMarkTile .5s var(--d0) var(--ease) both; }
.tpmark.tp-wait .fig,
.tpmark.tp-wait .zweit { opacity: 0; }
.tpmark.tp-anim .fig,
[data-reveal].in .tpmark.tp-wait .fig {
  animation: tpFigRise .6s calc(var(--d0) + .05s) var(--ease) both;
}
.tpmark.tp-anim .zweit,
[data-reveal].in .tpmark.tp-wait .zweit {
  animation: tpZweitAuf .45s calc(var(--d0) + .32s) var(--ease) both;
}

/* ---------- Kopfnavigation ---------- */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: color-mix(in oklab, var(--paper) 92%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--line);
}
/* Die Kopfzeile ist wieder auf die Inhaltsbreite gefasst und flach: Ueber die
   volle Fensterbreite standen Zeichen und Navigation im Vollbild zu weit
   auseinander, und mit dem Unterpunkt war die Leiste 90 px hoch
   [Entscheid Guido, 06.10.2026; ersetzt den vom 23.09.2026]. */
.topbar-in {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 6px var(--pad) 5px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}
/* Abstand Zeichen–Wortmarke A = ⅓ der Zeichengrösse (Reinzeichnung v1.0,
   _reinzeichnung.html, «Wort-Bild-Abstand»): 48 px → 16 px; unter 560 px
   34 px → 11 px (im Block @media (max-width: 560px)). */
.brand { display: flex; align-items: center; gap: 16px; flex: none; }
.brand img { height: 30px; width: auto; display: block; }
/* So hoch wie die zweizeilige Navigation rechts: Das Zeichen schliesst oben
   mit tupiano.2AI_ und unten mit dem Unterpunkt ab [Entscheid Guido, 07.10.2026]. */
.brand .tpmark { width: 48px; height: 48px; }
.brand .name { font-size: 19px; font-weight: 600; color: var(--espresso); }
.nav { display: flex; align-items: center; gap: 4px; margin-left: auto; flex-wrap: wrap; }
.nav a {
  font-family: 'IBM Plex Mono', ui-monospace, Menlo, monospace;
  font-size: 12.5px;
  color: var(--ink-2);
  padding: 3px 11px;
  border-radius: 2px;
  border: 1px solid transparent;
  transition: background .25s, color .25s, border-color .25s;
}
.nav a:hover { color: var(--espresso); background: var(--card); border-color: var(--line-soft); text-decoration: none; }
.nav a[aria-current="page"] { color: var(--acc-fill-ink); background: var(--acc-fill); border-color: var(--acc-fill); }
/* tupiano.2cloudAI_ ist Teil von tupiano.2AI_, kein drittes Produkt: Es steht
   als Unterpunkt in derselben Gruppe, angebunden mit einem Winkel
   [Vorschlag Udo, 06.10.2026]. */
.nav:has(.navgrp) { align-items: flex-start; }
.navgrp { display: flex; flex-direction: column; align-items: flex-start; }
.nav a.sub { font-size: 11px; padding: 0 8px 1px 14px; }
.nav a.sub::before { content: "└ "; color: var(--ink-4); }
.nav a.sub[aria-current="page"]::before { color: inherit; }

/* ---------- Hero ---------- */
.hero {
  max-width: var(--wrap);
  margin: 0 auto;
  padding: clamp(34px, 4.5vh, 58px) var(--pad) clamp(20px, 3vh, 36px);
  min-height: 68vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 18px;
}
.hero-brandrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  animation: tpRise .7s var(--ease) both; }
.hero-brandrow img { height: 26px; width: auto; display: block; flex: none; }
/* Produktzeichen, Produktname und Kicker stehen in einer Zeile. Das Zeichen ist
   bewusst klein: In der Kopfzeile darüber steht das Dachzeichen an derselben
   Fluchtlinie, und zwei gleich grosse Quadrate übereinander lasen sich wie ein
   Fehler [Entscheid Guido, 23.09.2026]. Klein neben Text liest es sich als
   Beschriftung. Die Säulen wachsen, nachdem die Zeile aufgestiegen ist. */
/* Gleich gross wie das Dachzeichen in der Kopfzeile (38 px). Das geht, seit
   die Kopfzeile ueber die volle Breite laeuft: Die beiden Zeichen stehen nicht
   mehr auf derselben Fluchtlinie [Entscheid Guido, 23.09.2026]. */
.hero-brandrow .tpmark { width: 38px; height: 38px; --d0: .2s; }
.hero-brandrow .sep { display: block; width: 1px; height: 18px; background: var(--line-soft); flex: none; }
.hero-brandrow .pname { font-family: 'IBM Plex Mono', monospace; font-size: 14px; color: var(--acc-ink); }
.hero-brandrow .txt { font-family: 'IBM Plex Mono', monospace; font-size: 13px;
  letter-spacing: .06em; color: var(--acc-ink); }

.kicker { display: flex; align-items: center; gap: 14px; }
.kicker .bar {
  display: block; width: 34px; height: 2px; flex: none;
  background: var(--acc); transform-origin: left;
}
.kicker .txt {
  font-family: 'IBM Plex Mono', monospace;
  font-size: 13px; letter-spacing: .06em; color: var(--acc-ink);
}
.hero .kicker { animation: tpRise .7s .08s var(--ease) both; }
.hero .kicker .bar { animation: tpWipe .6s .3s var(--ease) both; }

/* Hoechstens zwei Zeilen und gut die halbe Bildschirmbreite: Bei 92 px lief
   der Titel ueber drei Zeilen und liess sich nicht mehr auf einen Blick
   erfassen [Hinweis Udo, 06.10.2026]. */
.hero h1 {
  font-size: clamp(38px, 5vw, 68px);
  line-height: 1.05;
  letter-spacing: -.015em;
  text-wrap: balance;
}
.hero h1 span { display: block; }
.hero h1 span:nth-child(1) { animation: tpRise .8s .16s var(--ease) both; }
.hero h1 span:nth-child(2) { animation: tpRise .8s .3s var(--ease) both; }
.hero h1 span:nth-child(3) { animation: tpRise .8s .44s var(--ease) both; }

.lead {
  margin: 0; max-width: 720px;
  font-size: clamp(18px, 1.5vw, 22px); line-height: 1.55;
  color: var(--ink); text-wrap: pretty;
}
.hero .lead { animation: tpRise .8s .6s var(--ease) both; }

.scrollhint {
  display: flex; align-items: center; gap: 12px; margin-top: 10px;
  font-family: 'IBM Plex Mono', monospace; font-size: 13px; color: var(--ink-3);
  animation: tpRise .8s .8s var(--ease) both;
}
.scrollhint .arrow { animation: tpNudge 1.9s ease-in-out infinite; }

.status-badge {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: 'IBM Plex Mono', monospace; font-size: 12px;
  padding: 5px 11px; border-radius: 2px;
  border: 1px solid var(--acc); color: var(--acc-ink);
  background: var(--acc-tint);
}
/* Der Punkt atmet ruhig grün – Signal «hier entsteht etwas», bewusst so weich,
   dass er den Titel nicht überstrahlt (Variante A der internen Abnahme) */
.status-badge .pip {
  width: 7px; height: 7px; border-radius: 50%; background: var(--live); flex: none;
  animation: tpPipAtem 2.4s ease-in-out infinite;
}

/* ---------- Keyframes ---------- */
@keyframes tpRise { from { opacity: 0; transform: translateY(26px); } to { opacity: 1; transform: none; } }
@keyframes tpFigRise { from { opacity: 0; transform: translateY(9px); } to { opacity: 1; transform: none; } }
@keyframes tpZweitAuf { from { opacity: 0; transform: scale(.72); } to { opacity: 1; transform: none; } }
@keyframes tpMarkTile { from { opacity: 0; transform: scale(.9); } to { opacity: 1; transform: none; } }
@keyframes tpWipe { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes tpBlink { 0%, 45% { opacity: 1; } 50%, 100% { opacity: 0; } }
@keyframes tpNudge { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(7px); } }
@keyframes tpPipAtem { 0%, 100% { opacity: .32; } 50% { opacity: 1; } }
@keyframes tpDeny { 0%, 40% { opacity: .5; } 50%, 62% { opacity: 1; } 80%, 100% { opacity: .5; } }
@keyframes tpStatPulse {
  0%, 100% { border-color: var(--warn-line); box-shadow: 0 0 0 0 rgba(163, 67, 39, 0); }
  50% { border-color: var(--warn); box-shadow: 0 0 0 3px rgba(163, 67, 39, .18); }
}
/* Flug und Aufprall werden per Web-Animations-API in site.js gesteuert,
   nicht über Keyframes – siehe Kommentar dort. */

/* ---------- Reveal-System ---------- */
[data-reveal] {
  opacity: 0;
  transition: opacity .8s var(--ease), transform .8s var(--ease);
}
[data-reveal].rv-up { transform: translateY(28px); }
[data-reveal].rv-up-lg { transform: translateY(44px) scale(.97); transition-duration: .9s; transition-timing-function: var(--ease-strong); }
[data-reveal].rv-h2 { transform: translateY(40px); transition-duration: .85s; transition-timing-function: var(--ease-strong); }
[data-reveal].rv-small { transform: translateY(16px); transition-duration: .6s; }
[data-reveal].rv-left { transform: translateX(-52px) skewX(4deg); transition-timing-function: var(--ease-strong); }
[data-reveal].rv-left-sm { transform: translateX(-46px); transition-timing-function: var(--ease-strong); transition-duration: .75s; }
[data-reveal].rv-in-left { transform: translateX(-16px); transition-duration: .5s; }
[data-reveal].rv-pop { transform: translateY(14px) scale(.8); transition-duration: .5s; transition-timing-function: var(--ease-over); }
[data-reveal].rv-card { transform: translateY(38px) scale(.94) rotate(-1deg); }
[data-reveal].rv-step { transform: translateY(46px) scale(.93); transition-duration: .75s; transition-timing-function: var(--ease-strong); }
[data-reveal].in { opacity: 1; transform: none; }

[data-wipe] { transform: scaleX(0); transform-origin: left; transition: transform .55s .18s var(--ease); }
[data-wipe].in { transform: scaleX(1); }

/* ---------- Karten-Grid (Feature-Karten) ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px;
}
.card {
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 3px;
  padding: 20px 20px 22px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.card:hover { transform: translateY(-4px); background: var(--card-hi); }
.card .knum { font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; color: var(--acc-ink); }
.card h3 { font-size: 21px; }
.card p { margin: 0; font-size: 15.5px; line-height: 1.65; }
/* Fuenf gleichrangige Karten in einer Reihe. Mit dem normalen Mindestmass
   von 260 px waeren es vier, und die fuenfte stuende allein. */
.cards.cards-5 { grid-template-columns: repeat(auto-fit, minmax(205px, 1fr)); }

/* ---------- Startseite: zwei Register ----------
   Links gross das Hauptprodukt, rechts die KI, etwa 2 : 1. Die Ueberschrift
   bleibt bei hoechstens zwei Zeilen und halber Bildschirmbreite, damit man
   sie auf einen Blick erfasst. */
.hero.hero-reg { min-height: 0; justify-content: flex-start; }
.regs { display: flex; gap: 12px; align-items: stretch; }
.reg {
  position: relative; flex: 1 1 0; min-width: 0;
  display: flex; flex-direction: column; gap: 16px;
  border-radius: 3px; padding: clamp(22px, 2.6vw, 36px);
  animation: tpRise .8s .1s var(--ease) both;
  transition: flex-grow .45s var(--ease-strong), background .25s;
}
.reg.aktiv { flex-grow: 2.1; }
/* Das kleine Register ist als Ganzes der Schalter; der Knopf oben rechts
   macht dasselbe fuer die Tastatur. */
.reg:not(.aktiv) { cursor: pointer; }
.reg-auf {
  position: absolute; top: 10px; right: 10px;
  appearance: none; cursor: pointer; background: transparent;
  font-family: 'IBM Plex Mono', monospace; font-size: 10.5px;
  padding: 3px 8px; border-radius: 2px;
  border: 1px solid currentColor; color: inherit; opacity: .6;
}
.reg-auf::after { content: " ↔"; }
.reg:hover .reg-auf, .reg-auf:focus-visible { opacity: 1; }
.reg.aktiv .reg-auf { display: none; }
.reg:not(.aktiv) { padding-top: 44px; }
.hero .reg .rh {
  font-size: clamp(22px, 2.1vw, 28px); line-height: 1.2; letter-spacing: 0;
  transition: font-size .45s var(--ease-strong);
}
.hero .reg.aktiv .rh { font-size: clamp(32px, 3.8vw, 52px); line-height: 1.06; letter-spacing: -.015em; }
.reg .rh span { animation: none; }
/* klein: Überschrift und Einleitungssatz bleiben in beiden Registern stehen,
   nur die Zusätze klappen weg [Entscheid Guido, 07.10.2026] */
.reg:not(.aktiv) .lead { font-size: 15.5px; line-height: 1.65; }
.reg:not(.aktiv) .beleg,
.reg:not(.aktiv) .faelle, .reg:not(.aktiv) .produkt p, .reg:not(.aktiv) .tt { display: none; }

.reg-sozial { background: var(--card); border: 1px solid var(--line); border-top: 3px solid var(--pacc); }
.reg-sozial:not(.aktiv):hover { background: var(--card-hi); }
.reg-sozial .kicker .bar { background: var(--pacc); }
.reg-sozial .kicker .txt { color: var(--pacc-ink); }
.reg .lead { max-width: 600px; animation: none; }
.reg .beleg {
  margin: 0; max-width: 600px; padding-left: 14px; border-left: 2px solid var(--pacc);
  font-size: 15.5px; line-height: 1.65; color: var(--ink-2);
}
.reg .phead { display: flex; align-items: center; gap: 10px; }
.reg .tpmark { width: 32px; height: 32px; --mark-tile: var(--pacc, var(--acc)); }
.reg .pname { font-family: 'IBM Plex Mono', monospace; font-size: 14.5px; font-weight: 500; color: var(--pacc-ink); }
.reg .pstate {
  align-self: flex-start;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  padding: 4px 9px; border-radius: 2px;
  border: 1px solid var(--line-soft); color: var(--ink-2);
}
.reg .more { font-family: 'IBM Plex Mono', monospace; font-size: 13px; font-weight: 500; color: var(--pacc-ink); }
.regfoot { display: flex; flex-wrap: wrap; align-items: center; gap: 12px 18px; margin-top: auto; padding-top: 8px; }
.regfoot .pstate { align-self: center; }
.reg.aktiv .regfoot .more { margin-left: auto; }

.reg-ki {
  --ki: #7cc8ee;            /* Hellblau auf dunkel – 8,6:1 */
  background: var(--dark); color: var(--on-dark); animation-delay: .22s;
}
.reg-ki:not(.aktiv):hover { background: #3c3936; }
.reg-ki .kicker .bar { background: var(--ki); }
.reg-ki .kicker .txt { color: var(--ki); }
.reg-ki .rh { color: #fff; }
.reg-ki > p { margin: 0; max-width: 620px; font-size: 15.5px; line-height: 1.65; }
.reg-ki.aktiv > p { font-size: clamp(16px, 1.3vw, 19px); }
.reg-ki .more { color: var(--ki); margin-top: auto; }
.reg-ki .produkt {
  display: flex; flex-direction: column; gap: 9px;
  padding: 14px; border-radius: 3px;
  background: rgba(255, 255, 255, .06); border: 1px solid rgba(255, 255, 255, .16);
}
.reg-ki .produkt p { margin: 0; font-size: 15px; line-height: 1.55; }
.reg-ki .faelle { margin: 0; padding-left: 18px; font-size: 14px; line-height: 1.6; color: #cfc6bd; }
.reg-ki .teil .faelle { padding-left: 0; font-size: 13px; }
.reg-ki .pname { color: var(--ki); }
.reg-ki .produkt > .phead { --pacc: #00618c; }
.reg-ki .pstate { border-color: rgba(255, 255, 255, .28); color: var(--on-dark); }
.reg-ki .teil {
  display: flex; flex-direction: column; gap: 7px;
  margin: 4px 0 0 16px; padding: 10px 12px;
  border-left: 2px solid var(--ki); border-radius: 0 3px 3px 0;
  background: rgba(0, 158, 227, .12); color: var(--on-dark);
  --pacc: #009ee3;
}
.reg-ki .teil .tpmark { width: 26px; height: 26px; }
.reg-ki .teil .pname { font-size: 13px; }
.reg-ki .teil .tt { font-size: 13.5px; line-height: 1.5; }
.reg-ki a:hover { text-decoration: none; }
.reg-ki a.phead:hover .pname, .reg-ki .teil:hover .pname, .reg-ki .more:hover { text-decoration: underline; }

/* ---------- Fragen mit Antwort ----------
   Wer eine Frage anklickt, bekommt die Antwort und nicht bloss ein Formular
   [Hinweis Udo, 06.10.2026]. */
.faq { display: flex; flex-direction: column; max-width: 760px; border-top: 1px solid var(--line); }
.faq details { border-bottom: 1px solid var(--line); }
.faq summary {
  cursor: pointer; list-style: none;
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: 14px 2px;
  font-family: 'IBM Plex Serif', Georgia, serif; font-weight: 500; font-size: 19px; color: var(--ink-title);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-family: 'IBM Plex Mono', monospace; font-size: 18px; color: var(--acc-ink); flex: none; }
.faq details[open] summary::after { content: "–"; }
.faq summary:hover { color: var(--acc-ink); }
.faq summary:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }
.faq .fa { display: flex; flex-direction: column; gap: 10px; padding: 0 2px 18px; max-width: 680px; }
.faq .fa p, .faq .fa ul { margin: 0; font-size: 16px; line-height: 1.7; }
.faq .fa ul { padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.faq .fa .fn { font-size: 13.5px; color: var(--ink-2); }

/* Produktkarten der Startseite */
.prodcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 10px; }
.prodcard {
  display: flex; flex-direction: column; gap: 13px;
  background: var(--card); border: 1px solid var(--line);
  border-top: 3px solid var(--pacc, var(--acc));
  border-radius: 3px; padding: 22px 22px 24px;
  color: inherit;
}
.prodcard:hover { background: var(--card-hi); transform: translateY(-4px); text-decoration: none; }
.prodcard .phead { display: flex; align-items: center; gap: 12px; }
/* Eine Groesse fuer alle Zeichen: 38 px wie in der Kopfzeile und im Hero */
.prodcard .tpmark { width: 38px; height: 38px; }
.prodcard .tpmark { --mark-tile: var(--pacc, var(--acc)); }
.prodcard .pname {
  font-family: 'IBM Plex Mono', monospace; font-size: 15px;
  color: var(--pacc-ink, var(--acc-ink)); font-weight: 500;
}
.prodcard h3 { font-size: 22px; }
.prodcard p { margin: 0; font-size: 15.5px; line-height: 1.65; color: var(--ink); }
.prodcard .prow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 4px; }
.prodcard .pstate {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  padding: 4px 9px; border-radius: 2px;
  border: 1px solid var(--line-soft); color: var(--ink-2);
}
.prodcard .pstate.live { border-color: var(--pacc, var(--acc)); color: var(--pacc-ink, var(--acc-ink)); background: color-mix(in oklab, var(--pacc, var(--acc)) 12%, transparent); }
.prodcard .more { font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; color: var(--pacc-ink, var(--acc-ink)); }

/* ---------- Anwendungsfälle + Terminal ---------- */
/* min(): Unter 360 px Fensterbreite bleiben neben dem Rand keine 320 px,
   die Spalte ragte sonst 40 px hinaus und die Seite liess sich seitlich
   schieben. */
.two-col {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: clamp(26px, 3vw, 44px);
  align-items: start;
}
/* Die schmalere Spalte bräche die Titel schlechter um; mit 23 statt 26 px
   brechen sie bei 320 px wie vorher. !important gegen die Grösse im
   style-Attribut [Entscheid Guido, 27.10.2026, Variante D]. */
@media (max-width: 359px) {
  .two-col h2.rv-h2 { font-size: 23px !important; }
}
.uselist { display: flex; flex-direction: column; }
.uselist .row {
  display: flex; gap: 14px; align-items: baseline;
  padding: 10px 0; border-bottom: 1px dotted #d6c8ba;
  font-size: 16.5px;
}
.uselist .row:last-child { border-bottom: none; }
.uselist .row .arrow { color: var(--acc-ink); font-size: 15px; }

.terminal {
  background: var(--dark); border-radius: 3px; padding: 22px 20px;
  display: flex; flex-direction: column; gap: 11px;
  font-family: 'IBM Plex Mono', monospace; font-size: 14px; line-height: 1.6;
  align-self: start;
}
.terminal .t0 { color: var(--acc-soft); }
.terminal .tl { color: var(--on-dark); }
.terminal .tl .h { color: var(--acc-soft); }

/* ---------- Compliance-Tabelle ---------- */
.rows { display: flex; flex-direction: column; border-top: 1px solid var(--line); }
.rows .r {
  display: grid; grid-template-columns: 150px 1fr; gap: 20px;
  padding: 12px 0; border-bottom: 1px solid var(--line);
}
.rows .r:last-child { border-bottom: none; }
.rows .lbl { font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; color: var(--acc-ink); }
.rows .val { font-size: 15.5px; line-height: 1.6; }

/* ---------- Hinweisbox + Format-Chips ---------- */
.notebox {
  display: flex; flex-wrap: wrap; align-items: center; gap: 14px 24px;
  padding: 16px 20px; border: 1px dashed var(--line-dash); border-radius: 3px;
  background: var(--card);
}
.notebox .nb-txt { display: flex; align-items: center; gap: 14px; flex: 1 1 300px; }
.notebox .nb-txt .bar { display: block; width: 26px; height: 2px; flex: none; background: var(--acc); }
.notebox .nb-txt span.t { font-size: 16px; line-height: 1.6; text-wrap: pretty; }
.fchips { display: flex; flex-wrap: wrap; gap: 6px; }
.fchips span {
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  padding: 5px 9px; border-radius: 2px;
  border: 1px solid var(--line-soft); color: var(--ink-2);
}

.stepcards { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 10px; }
.stepcards .sc {
  background: var(--card); border: 1px solid var(--line); border-radius: 3px;
  padding: 18px 18px 20px; display: flex; flex-direction: column; gap: 10px;
}
.stepcards .sc .n { font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: var(--acc-ink); }

/* ---------- Angebotsfeld (tupiano.sozial) ----------
   Die Angebote erscheinen einzeln und in gleicher Auszeichnung — keines
   grösser, keines zuerst. Darunter die Schiene mit dem einen Ablauf: viele
   oben, einer unten. Die Aussage steckt in der Bewegung, der Text sagt sie
   nur noch einmal nach. */
.angebote { display: flex; flex-wrap: wrap; gap: 8px; max-width: 760px; }
.angebote .ang {
  font-family: 'IBM Plex Mono', monospace; font-size: 12.5px;
  padding: 8px 13px; border-radius: 2px;
  border: 1px solid var(--line); background: var(--card); color: var(--ink-2);
}
/* das offene Feld: hier steht das Angebot, das wir nicht aufgezählt haben */
.angebote .ang.eigen {
  border-style: dashed; border-color: var(--acc);
  color: var(--acc-ink); background: transparent;
}
.ang-trenner { height: 1px; background: var(--line); max-width: 760px; transform-origin: left; }
.ang-pfeil { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--acc-ink); margin: 0; }
/* Einrasten statt Einblenden: kurzer Weg von unten, leicht kleiner startend.
   Deutlicher als rv-up, weil hier die Staffelung die Aussage traegt. */
[data-reveal].rv-ang { opacity: 0; transform: translateY(14px) scale(.94);
  transition: opacity .42s var(--ease), transform .42s var(--ease-strong); }
[data-reveal].rv-ang.in { opacity: 1; transform: none; }
.stepcards .sc p { margin: 0; font-size: 15px; line-height: 1.6; }

.mono-note {
  margin: 0; max-width: 680px;
  font-family: 'IBM Plex Mono', monospace; font-size: 13.5px; line-height: 1.7;
  color: var(--ink-2);
}

/* ---------- Interaktives Fenster ---------- */
.iwin {
  background: var(--card-hi); border: 1px solid var(--line); border-radius: 3px;
  padding: 22px 22px 20px; display: flex; flex-direction: column; gap: 13px;
}
.iwin .ihead {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border-bottom: 1px dotted var(--line-soft); padding-bottom: 11px;
}
.iwin .ihead .l { font-family: 'IBM Plex Mono', monospace; font-size: 12px; letter-spacing: .05em; color: var(--ink-title); }
.iwin .ihead .c { font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: var(--acc-ink); transition: opacity .3s; }
.iwin .q { margin: 0; font-size: 15.5px; line-height: 1.75; text-wrap: pretty; }
.iwin .q em { font-style: normal; color: var(--ink-title); }
.srcs { display: flex; flex-direction: column; gap: 7px; }
.srcs .s {
  display: flex; align-items: baseline; gap: 10px;
  padding: 8px 10px; border-radius: 2px;
  background: var(--chip); border: 1px solid var(--line);
  transition: opacity .35s, background .35s, border-color .35s, filter .35s, transform .65s var(--ease-strong);
}
.srcs .s .qn { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; color: var(--acc-ink); flex: none; }
.srcs .s .qt { font-size: 14.5px; line-height: 1.5; }
.srcs .s.off { opacity: .4; background: transparent; border-color: #ebe0d5; filter: grayscale(1); text-decoration: line-through; }
.iwin .note {
  margin: 0; font-family: 'IBM Plex Mono', monospace; font-size: 11.5px; line-height: 1.6;
  color: var(--ink-2); transition: opacity .3s;
}
.iwin .ibtns {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  border-top: 1px dotted var(--line-soft); padding-top: 13px;
}
.pill {
  appearance: none; cursor: pointer;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px;
  padding: 6px 11px; border-radius: 2px;
  border: 1px solid var(--line-soft); background: transparent; color: var(--ink-2);
  transition: background .3s, color .3s, border-color .3s;
}
.pill:hover { border-color: var(--acc); color: var(--acc-ink); }
.pill.on { background: var(--acc-fill); border-color: var(--acc-fill); color: var(--acc-fill-ink); }
.ibtns .hint { font-family: 'IBM Plex Mono', monospace; font-size: 10.5px; color: var(--ink-4); margin-left: 4px; }

/* markierte Passagen im Prüf-Fenster */
.mark {
  display: inline-block; padding: 1px 6px; margin: 0 1px; border-radius: 2px;
  background: rgba(150, 120, 100, .16); color: var(--ink-title); font-weight: 500;
  transition: background .35s, color .35s, box-shadow .3s, opacity .35s, text-decoration-color .35s;
}
.mark.checked { background: var(--acc-tint); color: var(--acc-ink); box-shadow: 0 0 0 2px var(--acc); }
.mark.reworded { background: var(--chip); color: var(--ink-title); box-shadow: 0 0 0 1px var(--line-strong); }
.mark.excluded { opacity: .45; text-decoration: line-through; }

/* ==========================================================================
   Scroll-Bühne
   ========================================================================== */
/* 420vh: kürzerer Scrollweg als die früheren 600vh. Zusammen mit der
   Vorlauf-Stauchung in site.js (die ersten 20 % der Abfolge liegen auf den
   ersten 6 % des Weges) bewegt sich sofort etwas — vorher lief eine ganze
   Bildschirmhöhe ohne sichtbare Änderung. */
.track { position: relative; height: 420vh; background: var(--band); border-top: 1px solid var(--line); }
/* Abstand vor und nach der Bühne wie bei jedem Abschnitt (.sec), abzüglich
   der 8 bzw. 10 px, die .stagewrap schon oben und unten lässt. Die Polster
   liegen innerhalb der 420vh: Die Bühne klebt erst, wenn der obere Abstand
   durchgelaufen ist, und hält vor dem unteren an; das Band läuft dort weiter.
   site.js zieht beide vom Scrollweg ab, damit die Abfolge erst mit dem
   Ankleben beginnt und Schritt 4 vollständig steht, bevor die Bühne
   weiterrollt [Guido, 28.10.2026]. */
.track {
  padding-top: calc(clamp(34px, 4.5vh, 54px) - 8px);
  padding-bottom: calc(clamp(34px, 4.5vh, 54px) - 10px);
}
.track-sticky {
  position: sticky; top: 0; height: 100vh;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
/* Hülle: Kopf und Schrittleiste liegen aussen und werden nicht skaliert,
   damit ihre Schriftgrössen unabhängig von der Fensterhöhe stimmen. */
.stagewrap {
  width: min(var(--wrap), 100%);
  height: 100vh; padding: 8px var(--pad) 10px;
  display: flex; flex-direction: column; gap: 4px;
}
.stagebox {
  flex: 1 1 auto; min-height: 0;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
/* Breite fest, Höhe setzt site.js aus dem freien Platz: so füllt die Bühne
   die ganze Spaltenbreite, statt gleichmässig mitzuschrumpfen, und es bleibt
   kein Leerraum aus der Zentrierung übrig. */
.stage {
  width: 1180px; height: 820px; flex: none;
  display: flex; flex-direction: column; justify-content: flex-start; gap: 12px;
  transform-origin: center center;
}
.stage > * { flex: none; width: 1180px; }
/* Der Bühnenraum nimmt die Resthöhe auf */
.stage-main { flex: 1 1 auto; min-height: 0; }
/* Auf hohen Bildschirmen wuchs die Bühne mit dem Fenster (bei 2560×1350 über
   1000 px Bühnenraum), und der Titel lag hinter der 60 px hohen Kopfleiste.
   Ab 920 px Fensterhöhe ist der Block aus Titel, Bühne und Schritten 860 px
   hoch und steht mittig unter der Kopfleiste. Niedriger geht es nicht, sonst
   wird die längste Antwort (2AI_, Nachtdienst) unten abgeschnitten. In
   niedrigeren Fenstern bleibt alles wie bisher [Entscheid Guido, 27.10.2026,
   Variante A]. */
@media (min-width: 901px) and (min-height: 920px) {
  .track-sticky { top: calc(60px + (100vh - 920px) / 2); height: 860px; }
  .stagewrap { height: 100%; }
}

/* ---------- Erklärblock unter der Bühne ----------
   Zähler und Aufforderung als schmale Zeile, darunter die vier Schritte mit
   ihren Texten, und am Fuss der Fortschrittsbalken, der über den ganzen
   Ablauf mitläuft. Alles drei ist Teil desselben Blocks — der Ablauf wird
   dort gelesen, wo der Text steht. */
.stepsblock { flex: none; display: flex; flex-direction: column; }
.sb-top {
  display: flex; align-items: baseline; justify-content: space-between; gap: 14px;
  padding: 0 3px 5px; flex-wrap: wrap;
}
.sb-count {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; letter-spacing: .04em;
  color: var(--acc-ink);
}
.sb-hint { font-family: 'IBM Plex Mono', monospace; font-size: 12px; color: var(--ink-2); }
/* Solange Schritt 1 läuft, wippt die Aufforderung leicht */
.sb-hint.go { animation: tpNudge 1.9s ease-in-out infinite; }
.sb-prog {
  flex: none; height: 4px; background: var(--line-strong);
  border-radius: 0 0 3px 3px; overflow: hidden;
}
.sb-prog span {
  display: block; height: 4px; width: 0; background: var(--acc);
  transition: width .12s linear;
}

.stage-head { display: flex; align-items: baseline; gap: 16px; }
.stage-head .lbl { font-family: 'IBM Plex Mono', monospace; font-size: 13px; color: var(--acc-ink); }
.stage-title { font-family: 'IBM Plex Serif', Georgia, serif; font-weight: 700; font-size: 32px; color: var(--ink-title); }

.stage-tabbar { display: flex; align-items: center; justify-content: flex-start; gap: 20px; }
.stage-tabbar .lbl { font-family: 'IBM Plex Mono', monospace; font-size: 13px; color: var(--ink-3); }
.tabs { display: flex; gap: 8px; }
.tabs button {
  appearance: none; cursor: pointer;
  font-family: 'IBM Plex Mono', monospace; font-size: 11.5px; letter-spacing: .02em;
  padding: 6px 11px; border-radius: 2px;
  border: 1px solid var(--line-soft); background: transparent; color: var(--ink-2);
  transition: background .25s, color .25s, border-color .25s;
}
.tabs button.on { background: var(--acc-fill); border-color: var(--acc-fill); color: var(--acc-fill-ink); }

.stage-main { height: auto; display: flex; align-items: stretch; }

/* Haus-Hülle: der Rahmen, innerhalb dessen die Daten bleiben. Rechts offen –
   dort schliesst die Wand (.wall) das Haus ab. */
.house {
  min-width: 0;
  border: 2px solid var(--line-strong); border-right: none; border-radius: 4px 0 0 4px;
  background: var(--shell); padding: 26px 18px 18px;
}
/* 2AI_: Arbeitsplatz, Verbindung und Server liegen alle im Haus */
.house.full {
  flex: 1 1 auto; position: relative;
  display: grid; grid-template-columns: 1fr 172px 1fr; align-items: stretch;
}
/* 2cloudAI_: nur der Arbeitsplatz liegt im Haus, die Cloud steht draussen.
   Bewusst ohne position:relative – site.js vergleicht offsetLeft von Panel,
   Cloud-Panel und Transit-Karte; alle drei brauchen .flow als offsetParent. */
.house.work-only { padding: 26px 14px 16px; }

/* Ablauf 2cloudAI_: Haus, Wand und Cloud in einem Raster. Die Spalten sind
   explizit zugewiesen, weil Wand und Verbindungsspalte sich dieselbe Zelle
   teilen – ohne Angabe landete die Wand automatisch in Spalte 3. Die Mittel-
   spalte ist um die Wandbreite breiter als bei 2AI_, damit für die Labels
   dieselben 172px bleiben. */
.flow {
  flex: 1 1 auto; min-width: 0; position: relative;
  display: grid; grid-template-columns: 1fr 196px 1fr; align-items: stretch;
}
.flow > .house { grid-area: 1 / 1; }
.flow > .conn { grid-area: 1 / 2; padding-left: 24px; }
.flow > .wall { grid-area: 1 / 2; justify-self: start; }
.flow > .panel-dark { grid-area: 1 / 3; }
.house-label {
  position: absolute; top: -8px; left: 20px; padding: 0 9px;
  background: var(--band);
  font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .08em; color: var(--ink-2);
}

.panel {
  background: var(--card-hi); border: 1px solid var(--line); border-radius: 3px;
  padding: 24px; display: flex; flex-direction: column; gap: 16px;
  height: 100%; overflow: hidden; position: relative;
}
.panel-head {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  border-bottom: 1px dotted var(--line-soft); padding-bottom: 12px; flex: none;
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; letter-spacing: .05em;
  color: var(--ink-title);
}
.panel-head .tag { font-size: 11px; color: var(--acc-soft); letter-spacing: 0; }
.prompt { font-size: 14.5px; line-height: 1.5; flex: none; }
.answer-wrap { margin-top: auto; border-top: 1px dotted var(--line-soft); padding-top: 14px; flex: none; }
.answer-box { transition: opacity .2s linear; }
.answer-box .ahead { font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: var(--acc-ink); margin-bottom: 8px; }
.answer { font-size: 14px; line-height: 1.5; white-space: pre-line; }

/* Chips im Prompt / in der Antwort */
.seg {
  display: inline-block; padding: 1px 6px; margin: 0 1px; border-radius: 2px;
  background: rgba(150, 120, 100, .16); color: var(--ink-title); font-weight: 500;
  transition: background .35s, color .35s, box-shadow .3s, transform .3s;
}
.seg.on { background: var(--acc-tint); color: var(--acc-ink); }
/* Nur der Ring markiert den Übergang. Der frühere translateY/scale-Hüpfer
   flimmerte im skalierten Bühnenrahmen (Subpixel) und wirkte unruhig. */
.seg.hot { box-shadow: 0 0 0 2px var(--acc); }

/* Verbindungsspalte */
.conn { position: relative; display: flex; align-items: center; justify-content: center; }
.conn .ctop, .conn .cbot {
  position: absolute; left: 0; right: 0; text-align: center;
  font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .05em; color: var(--ink-3);
}
.conn .ctop { top: 0; }
.conn .cbot { bottom: 0; }
.conn .cline {
  position: absolute; left: 0; right: 0; top: 50%; height: 1px;
  background: repeating-linear-gradient(90deg, var(--line-dash) 0 5px, transparent 5px 11px);
}
/* Liegt über der ganzen Bühne (nicht in der Mittelspalte) und fährt vom
   Arbeitsplatz-Panel zum Server-/Cloud-Panel und zurück. */
.transit {
  position: absolute; top: 50%; left: 0; z-index: 6;
  will-change: transform;
  width: 208px; padding: 13px 14px 15px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 7px;
  background: var(--card-hi); border: 1px solid var(--line-soft); border-radius: 2px;
  /* Eine Lichtquelle, von oben: Schatten fallen nach unten (positiver
     y-Versatz); Ringe ohne Versatz sind keine Schatten. Einziger Schatten der
     Website. */
  box-shadow: 0 10px 30px rgba(0, 0, 0, .22);
  transition: opacity .2s linear;
}
.transit-rows { display: flex; flex-direction: column; gap: 7px; width: 100%; }
.transit .ttag { font-family: 'IBM Plex Mono', monospace; font-size: 9px; letter-spacing: .06em; color: var(--ink-3); flex: none; }
.transit .bar { height: 4px; flex: none; border-radius: 1px; background: #e2d6ca; }
.transit .tchip {
  flex: none; max-width: 100%;
  font-family: 'IBM Plex Mono', monospace; font-size: 10px; line-height: 1.3;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  padding: 3px 6px; border-radius: 2px;
  background: var(--acc-fill); color: var(--acc-fill-ink); border: 1px solid transparent;
  transition: background .35s, color .35s;
}
.transit .tchip.home { background: var(--chip); color: var(--ink-title); border-color: var(--acc); }

/* Server-/Cloud-Panel
   Nur Tokens, keine eigenen Töne [13.10.2026]. Linien auf dem Panel sind
   --line-strong in --dark gemischt, die Stärke folgt der Rolle: 14 % Kopflinie,
   19 % Rand der Boxen, 40 % Rand der Kärtchen. Die Boxen für Frage und Antwort
   liegen auf --ink, eine Stufe dunkler als das Panel (1,14:1) und durch ihren
   Rand abgesetzt; vorher stand dort das Braun der alten Fussleiste.
   Kontrast in der Box: --on-dark 11,0:1, Label --acc-soft 5,7:1 (2AI_) und
   8,5:1 (2cloudAI_); --on-dark auf --dark 9,6:1. */
.panel-dark {
  background: var(--dark); border: 1px solid var(--dark); border-radius: 3px;
  padding: clamp(16px, 2.6vh, 26px);
  display: flex; flex-direction: column; gap: clamp(10px, 2vh, 16px);
  height: 100%; min-height: 0; overflow: hidden;
  transition: opacity .2s linear;
}
.panel-dark .panel-head {
  border-bottom: 1px solid color-mix(in oklab, var(--line-strong) 14%, var(--dark));
  color: var(--on-dark);
}
.panel-dark .dot {
  width: 8px; height: 8px; border-radius: 50%; background: #5f5b57; flex: none;
  transition: background .3s, box-shadow .3s;
}
.panel-dark .dot.on { background: var(--acc); box-shadow: 0 0 0 5px var(--acc-ring); }
.term {
  font-family: 'IBM Plex Mono', monospace; font-size: 12px; line-height: 1.55;
  color: var(--on-dark); word-break: break-word; white-space: pre-line; flex: none;
}
/* Frage oben, Antwort unten – auf derselben Höhe wie im Arbeitsplatz-Fenster
   links. Dazwischen steht, womit das Modell arbeitet: bei 2AI_ die
   Fundstellen, bei 2cloudAI_ die Zufallsnamen [Entscheid Guido, 07.10.2026].
   Vorher standen Frage und Antwort nebeneinander. */
.panel-dark .term {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column; gap: 12px;
  color: var(--on-dark); font-size: 0.82rem; line-height: 1.6;
}
.term .tbox {
  background: var(--ink);
  border: 1px solid color-mix(in oklab, var(--line-strong) 19%, var(--dark));
  border-radius: 3px; padding: 10px 12px;
  transition: opacity .2s linear;
}
.term .p2 { margin-top: auto; }
.term .tlbl {
  display: block; margin-bottom: 4px;
  font-size: 10.5px; letter-spacing: .05em; color: var(--acc-soft);
}
.term .tmid { margin-top: auto; white-space: normal; transition: opacity .25s linear; }
.term .tchips { display: flex; flex-wrap: wrap; gap: 6px; }
.term .tchips span {
  font-size: 11px; line-height: 1.4; padding: 3px 8px; border-radius: 2px;
  border: 1px solid color-mix(in oklab, var(--line-strong) 40%, var(--dark));
  color: var(--on-dark);
}
.caret {
  display: inline-block; width: 7px; height: 15px; background: var(--acc);
  vertical-align: -2px; margin-left: 3px; animation: tpBlink 1s steps(1) infinite;
}
.term-foot {
  margin-top: auto; display: flex; flex-direction: column; gap: 5px;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: var(--on-dark-2); flex: none;
}
.term-foot .srcline { color: #a49d95; transition: opacity .3s linear; }

/* Hauswand: die Grenze zwischen Haus und fremdem Netz. Auf beiden Produkt-
   seiten dasselbe Element in zwei Zuständen – geschlossen (2AI_, es geht
   nichts durch) und mit Schleuse (2cloudAI_, es gehen nur Pseudonyme durch). */
.wall {
  flex: none; width: 20px; position: relative;
  border-left: 3px solid var(--warn); border-right: 1px solid #b09484;
  background: var(--wall-hatch);
  animation: tpDeny 3.4s ease-in-out infinite;
  z-index: 3;
}
/* Die Beschriftung sitzt auf einem eigenen Grund, sonst laufen die Streifen
   der Schraffur durch die Buchstaben — bei 9,5px entscheidend. */
.wall .wl {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%) rotate(-90deg);
  white-space: nowrap;
  font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; font-weight: 500;
  letter-spacing: .1em; color: var(--warn-label);
  background: var(--paper); padding: 2px 6px; border-radius: 2px;
}

/* Offene Wand: Wandstück oben, Wandstück unten, dazwischen die Schleuse.
   Die Schraffur sitzt in ::before/::after statt auf dem Element selbst, damit
   die Lücke eine echte Unterbrechung ist – auch von Rahmen und Puls. */
.wall.open {
  --gate: 56px;
  border: none; background: none; animation: none;
}
.wall.open::before, .wall.open::after {
  content: ''; position: absolute; left: 0; right: 0; height: calc(50% - var(--gate));
  border-left: 3px solid var(--warn); border-right: 1px solid #b09484;
  background: var(--wall-hatch);
  animation: tpDeny 3.4s ease-in-out infinite;
}
.wall.open::before { top: 0; }
.wall.open::after { bottom: 0; }
/* Der Durchlass trägt die Seitenfarbe, nicht das Warnrot: die Grenze ist
   fremdes Gebiet, der Durchgang dagegen kontrolliert. */
.wall.open .gate {
  position: absolute; left: 0; right: 0;
  top: calc(50% - var(--gate)); bottom: calc(50% - var(--gate));
  display: flex; align-items: center; justify-content: center;
  border-top: 2px solid var(--acc); border-bottom: 2px solid var(--acc);
  background: var(--acc-tint);
}
.wall.open .gl {
  white-space: nowrap; transform: rotate(-90deg);
  font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; letter-spacing: .1em; color: var(--acc-ink);
}

/* Fremdes Netz als eigene Zone (nur 2AI_) */
.outside { flex: none; width: 214px; display: flex; align-items: stretch; position: relative; }
.net {
  flex: 1 1 auto; min-width: 0; position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 13px; padding: 18px 15px 16px;
  border: 1px solid #b9b2a9; border-left: none; border-radius: 0 4px 4px 0;
  background: var(--dark-net);
}
.net .scan {
  position: absolute; inset: 0; pointer-events: none;
  background: repeating-linear-gradient(0deg, rgba(255, 255, 255, .035) 0 1px, transparent 1px 4px);
}
.net .nhead {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  border-bottom: 1px solid #504f52; padding-bottom: 10px; flex: none; position: relative;
  font-family: 'IBM Plex Mono', monospace; font-size: 11px; letter-spacing: .04em; color: #b5b0aa;
}
.net .nhead .rd {
  width: 7px; height: 7px; border-radius: 50%; background: var(--warn); flex: none;
  box-shadow: 0 0 0 4px rgba(163, 67, 39, .28);
}
.net .nlist {
  font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; line-height: 1.65;
  color: #b0aaa4; flex: none; position: relative;
}
.net .nfoot { margin-top: auto; display: flex; flex-direction: column; gap: 7px; flex: none; position: relative; }
.net .nstat {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px;
  font-family: 'IBM Plex Mono', monospace; font-size: 10px; letter-spacing: .04em;
  color: var(--warn-text); padding: 6px 8px;
  border: 1px solid var(--warn-line); border-radius: 2px; background: rgba(163, 67, 39, .2);
  /* atmet langsam, damit die Sperre auch im Stillstand sichtbar bleibt */
  animation: tpStatPulse 3.2s ease-in-out infinite;
}
.net .nstat .b { color: #dda491; }
.net .nnote { font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; line-height: 1.6; color: #b0aaa4; }
/* Liegt über Wand UND Internet-Panel, nicht darin: das Panel hat
   overflow:hidden und hätte die Objekte vor dem Aufprall abgeschnitten.
   Läuft auf eigenen Zeitgebern, unabhängig vom Scrollen. */
.attack-zone {
  position: absolute; left: 0; right: -4px; top: 78px; bottom: 58px;
  pointer-events: none; z-index: 4;
}
.attack {
  position: absolute; left: 0;
  display: flex; align-items: center; justify-content: center;
  border-radius: 2px; background: rgba(163, 67, 39, .24); border: 1px solid var(--warn);
  color: var(--warn-icon); will-change: transform, opacity;
}
/* Liegt deckungsgleich über der Angriffszone, damit „top" in Prozent für
   Flugobjekt und Einschlag denselben Bezugsrahmen hat. Nullpunkt links = Wand. */
.impacts { position: absolute; inset: 0; pointer-events: none; }
.impact-glow, .impact-spark { position: absolute; left: 0; pointer-events: none; opacity: 0; }
.impact-glow {
  border-radius: 50%;
  background: radial-gradient(circle, rgba(226, 132, 102, .8) 0%, rgba(163, 67, 39, 0) 70%);
}
.impact-spark { width: 22px; height: 2px; border-radius: 1px; background: var(--warn-icon); }

/* Schrittleiste — liegt aussen an der Bühne und wird nicht mitskaliert.
   Im Ablauf zeigt sie nur Nummer und Titel; die Beschreibung des aktuellen
   Schritts steht im Kopf, in Lesegrösse. Die Spalten sind anklickbar und
   springen an ihre Stelle im Ablauf. */
.steps {
  flex: none;
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 3px 3px 0 0; overflow: hidden;
}
.steps .step {
  background: var(--paper); color: var(--ink-3);
  padding: 9px 12px; display: flex; flex-direction: column; gap: 4px;
  transition: background .35s, color .35s;
  text-align: left; font: inherit; border: none; cursor: pointer;
}
.steps .step:hover { background: var(--card-hi); color: var(--ink-title); }
.steps .step:focus-visible { outline: 2px solid var(--acc); outline-offset: -2px; }
.steps .step .n { font-family: 'IBM Plex Mono', monospace; font-size: 13px; font-weight: 500; opacity: .8; }
.steps .step .l { font-size: 13px; font-weight: 500; line-height: 1.35; }
/* Der erklärende Text steht in voller Länge in seiner Spalte. Weil die Leiste
   aussen an der Bühne liegt und nicht mitskaliert wird, sind das echte 12,5px
   statt der früheren 11px, die durch die Bühnenskalierung auf etwa 8px
   zusammenfielen. Im aktiven Schritt steht er auf der Akzentfläche. */
.steps .step .d {
  font-size: 12.5px; line-height: 1.55; margin-top: 3px;
  color: var(--ink-2); transition: color .35s;
}
.steps .step.done .d { color: var(--ink-2); }
.steps .step.cur .d { color: var(--acc-fill-ink-2); }
.steps .step.done { background: var(--card); color: var(--ink-title); }
.steps .step.cur { background: var(--acc-fill); color: var(--acc-fill-ink); }
.steps .step.cur .n { opacity: 1; }
/* Auf der Akzentfläche verschwände ein Fokusrahmen in --acc (bei 2AI_ und
   2cloudAI_ ist er so farbig wie die Fläche); er nimmt die Schriftfarbe. */
.steps .step.cur:focus-visible { outline-color: currentColor; }

/* ---------- Bühne in niedrigen Fenstern ----------
   Auf Laptops wurde die Antwort unten abgeschnitten, bei 2AI_ in einem
   Fenster von 1366×657 um 140 px. Unter 920 px Fensterhöhe zeigt die
   Schrittleiste deshalb nur Nummer und Titel, die Erklärung des aktuellen
   Schritts steht als eine Zeile darunter, und die Fenster rücken enger
   zusammen. Reicht das nicht, verkleinert sich die Bühne, statt
   abzuschneiden: --buehne-min ist die Höhe, die der Inhalt braucht (site.js,
   measure). Die Regeln stehen nach den Grundregeln, damit sie greifen
   [Entscheid Guido, 27.10.2026, Variante D]. */
.track:has(.house.full) { --buehne-min: 630; }  /* 2AI_ */
.track:has(.flow) { --buehne-min: 590; }        /* 2cloudAI_ */
@media (min-width: 901px) and (max-height: 919px) {
  .stepsblock { position: relative; padding-bottom: 44px; }
  .steps .step { padding: 7px 12px; gap: 2px; }
  .steps .step .d { display: none; }
  /* zwei Zeilen à 12,5 px × 1,55 */
  .steps .step.cur .d {
    display: block; position: absolute; left: 3px; right: 3px; bottom: 0;
    height: 40px; margin: 0; overflow: hidden; color: var(--ink-2);
  }
  .house { padding: 18px 14px 12px; }
  .house.work-only { padding: 18px 12px 12px; }
  .panel { padding: 16px; gap: 10px; }
  .panel-head { padding-bottom: 8px; }
  .panel-dark { padding: 14px; gap: 8px; }
  .panel-dark .term { gap: 8px; }
  .term .tbox { padding: 8px 10px; }
  .answer-wrap { padding-top: 10px; }
}

/* ---------- Fussleiste ----------
   Eine ruhige Adresszeile auf dem Seitengrund, in der Leseschrift, mit einer
   Linie darüber [Udos Klick-Dummy, 06.10.2026]. Vorher stand hier die dunkle
   Terminal-Leiste der alten Startseite. Die Klasse heisst weiter .term, weil
   der Textexport die Fusszeile darüber findet; die Regeln hängen an footer.term,
   damit sie das Terminal der Bühne (.panel-dark .term) nicht mehr treffen. */
footer.term {
  /* flex, damit die Zeilenumbrüche im Markup rund um .term-in keine leeren
     Zeilenboxen erzeugen – die machten die Leiste sonst doppelt so hoch */
  display: flex;
  border-top: 1px solid var(--line);
  color: var(--ink-2); background: transparent;
  font-family: inherit; font-size: 13px; white-space: normal;
  line-height: 1.6;
}
.term-in {
  width: 100%; max-width: var(--wrap); margin: 0 auto; padding: 14px var(--pad);
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 11px;
}
footer.term .foot-logo { display: none; }
footer.term .adr strong { font-weight: 400; }
footer.term a { color: inherit; text-decoration: none; }
footer.term a:hover { color: var(--espresso); text-decoration: underline; }
footer.term nav { margin-left: auto; display: flex; flex-wrap: wrap; gap: 18px; }

/* ---------- Rechtsseiten (Impressum, Datenschutz) ----------
   Der Wortlaut stammt unverändert aus den bisherigen Seiten im
   Wurzelverzeichnis; hier nur die Gestalt: Lesespalte, Zwischentitel wie
   heading-card (Serif 22 px), Fliesstext wie body-long (16,5 px / 1,7). */
.recht { max-width: 680px; }
.recht h2 { font-size: 22px; line-height: 1.25; margin: 34px 0 10px; }
.recht h2:first-child { margin-top: 0; }
.recht p { font-size: 16.5px; line-height: 1.7; margin: 0 0 12px; }

/* ---------- Kontaktblock und Kontaktseite ----------
   Die Fragen im Block sind Verweise, keine Zierde: Ein Klick traegt die Frage
   in das Nachrichtenfeld der Kontaktseite. Darum hier nur der Zustand fuer
   Zeiger und Tastatur — die Form erbt das Angebotsfeld. */
.angebote a.ang {
  text-decoration: none; cursor: pointer;
  transition: border-color .25s, color .25s, background .25s;
}
.angebote a.ang:hover { border-color: var(--acc); color: var(--acc-ink); background: var(--card-hi); }
.angebote a.ang.eigen:hover { background: var(--acc-tint); }
.angebote a.ang:focus-visible { outline: 2px solid var(--acc); outline-offset: 2px; }

.kontaktmail {
  font-family: 'IBM Plex Mono', monospace; font-size: 13px;
  color: var(--acc-ink); text-decoration: none;
  border-bottom: 1px solid var(--line-strong); padding-bottom: 2px;
}
.kontaktmail:hover { border-bottom-color: var(--acc); }

/* ---- Formular ---- */
.kform { display: flex; flex-direction: column; gap: 18px; max-width: 560px; }
.kform .feld { display: flex; flex-direction: column; gap: 7px; }
.kform > .feld > label,
.kform .interessen > label:first-child {
  font-family: 'IBM Plex Mono', monospace; font-size: 12.5px; color: var(--acc-ink);
}
.kform input[type="text"], .kform input[type="email"], .kform textarea {
  font-family: inherit; font-size: 16px; line-height: 1.6; color: var(--ink);
  background: var(--card-hi); border: 1px solid var(--line); border-radius: 3px;
  padding: 11px 13px; width: 100%; box-sizing: border-box;
  transition: border-color .25s, background .25s;
}
.kform input:focus, .kform textarea:focus {
  outline: 2px solid var(--acc); outline-offset: 1px;
  border-color: var(--acc); background: #fff;
}
.kform textarea { resize: vertical; min-height: 140px; }
.kform .interessen { gap: 10px; }
.kform .chk { display: flex; gap: 10px; align-items: flex-start; font-size: 15.5px; line-height: 1.55; cursor: pointer; }
.kform .chk input { margin: 4px 0 0; flex: none; accent-color: var(--acc-ink); }
.kform .chk .prod { font-family: 'IBM Plex Mono', monospace; font-size: 13.5px; color: var(--acc-ink); }
.kform .anders-text { margin-top: 2px; }
/* Honigtopf: fuer Menschen unsichtbar, fuer Maschinen verlockend.
   Nicht display:none — manche Bots fuellen nur, was im Baum steht. */
.kform .hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.kf-send {
  appearance: none; cursor: pointer; align-self: flex-start;
  font-family: 'IBM Plex Mono', monospace; font-size: 13px; letter-spacing: .02em;
  padding: 12px 22px; border-radius: 2px;
  border: 1px solid var(--acc-ink); background: var(--acc-ink); color: #fff;
  transition: background .3s, border-color .3s, opacity .3s;
}
.kf-send:hover { background: var(--espresso); border-color: var(--espresso); }
.kf-send:disabled { opacity: .5; cursor: default; }
.kmeldung {
  margin: 0; min-height: 1.2em;
  font-family: 'IBM Plex Mono', monospace; font-size: 13px; line-height: 1.6;
}
.kmeldung.ok { color: var(--acc-ink); }
.kmeldung.err { color: var(--warn); }

/* ---------- Vorschau-Hinweis (nur im Cockpit) ---------- */
.previewbar {
  background: var(--espresso); color: #f6f0eb;
  font-family: 'IBM Plex Mono', monospace; font-size: 11.5px;
  padding: 7px var(--pad); text-align: center;
}
.previewbar a { color: #f0d9c8; text-decoration: underline; }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 900px) {
  /* Register stehen untereinander, das Hauptprodukt zuerst */
  .regs { flex-direction: column; }
  .reg, .reg.aktiv { flex: none; }
  .reg.aktiv .regfoot .more { margin-left: 0; }
  /* Bühne: statt Skalierung eine ruhige, statische Abfolge der vier Schritte */
  .track { height: auto; }
  /* Ohne klebende Bühne fehlen die Polster von .stagewrap: unten voller
     Abstand; oben übernimmt ihn die Bühne selbst (siehe .stage unten). */
  .track { padding-top: 0; padding-bottom: clamp(34px, 4.5vh, 54px); }
  .track-sticky { position: static; height: auto; display: block; overflow: visible; }
  /* max-width: Die Bühne ist ein flex:none-Kind und nähme sonst die Breite
     ihres längsten Titels an – die Seite liesse sich seitlich schieben. */
  .stage {
    width: auto; max-width: 100%; height: auto; transform: none !important;
    padding: clamp(28px, 5vh, 44px) var(--pad); gap: 20px;
    padding-top: clamp(34px, 4.5vh, 54px);   /* wie .sec */
  }
  .stage > * { width: auto; }
  .stage-main { display: none; }
  .stage-head { flex-direction: column; align-items: flex-start; gap: 8px; }
  .stage-title { font-size: 24px; }
  .stage-tabbar { display: none; }
  /* Ohne bewegte Bühne braucht es keinen Fortschrittskopf; die Schritte
     stehen als Liste mit ihren Beschreibungen. */
  .stagewrap { height: auto; padding: 0; }
  .stagebox { overflow: visible; }
  /* Ohne bewegte Bühne gibt es keinen Fortschritt zu zeigen */
  .sb-top, .sb-prog { display: none; }
  .steps { grid-template-columns: 1fr; border-radius: 3px; }
  .steps .step { cursor: default; }
  .steps .step, .steps .step.cur, .steps .step.done { background: var(--card); color: var(--ink-title); }
  .steps .step .d, .steps .step.cur .d { color: var(--ink-2); }
  .steps .step .n { color: var(--acc-ink); opacity: 1; }
}

@media (max-width: 560px) {
  :root { --pad: 20px; }
  .rows .r { grid-template-columns: 1fr; gap: 4px; }
  /* Die Produkte stehen bündig mit dem Zeichen: Der Innenabstand der Links
     (11 px) ragt nach links hinaus. */
  .nav { width: calc(100% + 11px); margin-left: -11px; }
  /* «Kontakt» rückt in die Markenzeile nach rechts, mittig zum 34-px-Zeichen
     (6 px Polster + 17 px). Alle drei Einträge brauchten nebeneinander 363 px,
     unter 414 px stand «Kontakt» allein in einer dritten Zeile
     [Entscheid Guido, 27.10.2026, Variante B]. */
  .topbar-in { position: relative; }
  .nav > a:last-child {
    position: absolute; right: calc(var(--pad) - 11px); top: calc(6px + 17px);
    transform: translateY(-50%);
  }
  /* Auf dem Telefon steht die Navigation unter dem Zeichen, nicht daneben;
     dort gibt es keine Höhe, an die es sich anlegen müsste */
  .brand { gap: 11px; }  /* ⅓ von 34 px (Reinzeichnung v1.0) */
  .brand .tpmark { width: 34px; height: 34px; }
  .brand .name { font-size: 13px; }  /* 0,39 × 34 px (Reinzeichnung v1.0) */
  .hero { min-height: auto; padding-top: 28px; }
  /* Die Markenzeile bricht hier um; der Trennstrich haenge sonst am Zeilenende */
  .hero-brandrow .sep { display: none; }
  .hero-brandrow { gap: 8px 10px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
  .caret { animation: none; }
  /* Punkt steht still und bleibt voll deckend grün */
  .status-badge .pip { animation: none; opacity: 1; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  [data-wipe] { transform: scaleX(1) !important; }
  [data-reveal].rv-ang { opacity: 1 !important; transform: none !important; }
  /* Figur und Zweitform stehen sofort, ohne Aufbau */
  .tpmark .fig, .tpmark .zweit { opacity: 1 !important; transform: none !important; }
}
