/*
Theme Name: puox
Theme URI: https://puox.de
Author: puox studio (Eduard Pflugfelder)
Description: Eigenes Theme fuer puox.de, Rebrand 2026 (Sphaere aus dem Logo).
  Klassisches Theme nach puox Architektur-Standard: duenne Templates + Gutenberg-Inhalt.
  Erzeugt von _build/wp.py aus puox-rebrand-3/index.html - nicht von Hand bearbeiten.
Version: 2.0.0
Requires at least: 6.1
Tested up to: 7.1
Requires PHP: 7.4
Text Domain: puox
*/
/* ==========================================================
   SCHRIFTEN - selbst gehostet, nichts von Google nachgeladen.
   Erzeugt von _build/fonts.py. Nicht von Hand bearbeiten.
   ========================================================== */

@font-face{
  font-family:'DM Sans';
  font-style:normal;
  font-weight:400 500;
  font-display:swap;
  src:url(fonts/dm-sans.woff2) format('woff2');
}

@font-face{
  font-family:'Plus Jakarta Sans';
  font-style:normal;
  font-weight:500 700;
  font-display:swap;
  src:url(fonts/plus-jakarta-sans.woff2) format('woff2');
}

@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:400 500;
  font-display:swap;
  src:url(fonts/jetbrains-mono.woff2) format('woff2');
}

/* ============================================================
   1 · TOKENS  (aus puox-rebrand-2/design-spec.md uebernommen)
   ============================================================ */
:root{
  --bg:#121514;
  --cream:#E9E1CF;
  --muted:rgba(233,225,207,.58);
  --faint:rgba(233,225,207,.52);   /* 4,7:1 auf dem Grund; .34 lag bei 2,7:1 */
  --mint:#21F1A8;
  --ink:#08120D;
  --border:rgba(233,225,207,.11);

  --font-sans:'DM Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  --font-display:'Plus Jakarta Sans',var(--font-sans);
  --font-mono:'JetBrains Mono','SF Mono',Consolas,monospace;

  --fs-body:1.0625rem;
  --fs-lead:clamp(.98rem,.92rem + .3vw,1.08rem);
  --fs-h3:1.28rem;
  --fs-h2:clamp(1.6rem,3.1vw,2.5rem);
  --fs-h1:clamp(2.1rem,4.2vw,3.4rem);   /* ein Zehntel groesser (Eddy, 2026-09-18) */

  /* 8er-Raster (Aurora, 2026-09-07): 4 · 8 · 16 · 24 · 32 */
  --space-2:4px; --space-3:8px; --space-4:16px; --space-5:24px; --space-6:32px;
  /* Seitlicher Rand von Kopf, Fuss und Panels -- ein Token statt viermal
     derselbe clamp() */
  --gutter:clamp(16px,3vw,32px);
  --gap-nav:clamp(16px,2vw,28px);
  --radius-xs:3px; --radius-md:8px;

  --ease-glide:cubic-bezier(.16,.84,.24,1);
  --ease-settle:cubic-bezier(.22,1,.36,1);

  --wrap:min(1680px, 92vw);   /* Panels nutzen die Bildschirmbreite */
  --header-h:72px;   /* 9 x 8, vorher 74 */

  /* REGEL: Die Sphaere liegt IMMER im Hintergrund -- eine einzige Ebene
     ganz unten, unter Leseschutz, Text und Chrome. Sie bekommt nie einen
     Teil vor den Inhalt gelegt; alles, was vorn wirken soll, wirkt ueber
     Farbe und Reihenfolge INNERHALB dieser Ebene. Darum auch nur ein
     Canvas: eine zweite, vordere Sphaerenebene wuerde die Regel brechen
     und die Tiefensortierung zerlegen.
     Der Leseschutz sitzt zwischen Sphaere und Panels (10 < 18 < 20). Nur so
     daempft er auch die vordersten Ringe und Ziffern; laege er darunter,
     waere jede Kontrastrechnung hinfaellig. Ausserhalb der Textzeilen
     bleibt die Sphaere unveraendert sichtbar. */
  --zi-far:-1;  /* fernes Sternenfeld: hinter allem Inhalt, nur vor dem Grund */
  --zi-stage:10; --zi-read:18; --zi-panel:20; --zi-chrome:800; --zi-loader:9000;
}

*{box-sizing:border-box}
/* Keine Rollleiste: die Seite ist eine Choreografie, kein Dokument. Die
   Funktion bleibt (Rad, Tasten, Touch), nur die Anzeige entfaellt. */
html{scrollbar-width:none;-ms-overflow-style:none}
html::-webkit-scrollbar{display:none}
body{
  margin:0;
  background:var(--bg);
  color:var(--cream);
  font-family:var(--font-sans);
  font-size:var(--fs-body);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
/* Waehrend Ladebildschirm und Autoexplosion bleibt die Seite stehen */
html.js:not(.ready),
html.js.autorun{overflow:hidden}

a{color:inherit}
h1,h2,h3{font-family:var(--font-display);text-wrap:balance;margin:0}
h1{font-size:var(--fs-h1);line-height:1.05;letter-spacing:-.025em;font-weight:700}
h2{font-size:var(--fs-h2);line-height:1.12;letter-spacing:-.025em;font-weight:700}
h3{font-size:var(--fs-h3);line-height:1.2;letter-spacing:-.01em;font-weight:600}
p{margin:0}

.lead{font-size:var(--fs-lead);color:var(--muted);max-width:52ch}
/* Auf der Buehne traegt der Lead volle Textfarbe: gedaempftes Grau
   liegt luminanzmaessig zu nah an einem mittelhellen Ring. */
html.motion .lead{color:var(--cream)}

/* ============================================================
   2 · BUEHNE
   ============================================================ */
#stage,#stage-read{
  position:fixed;
  inset:0;
  display:block;
  width:100%;
  height:100%;
  pointer-events:none;
}
#stage{z-index:var(--zi-stage)}
/* Nur am Seitenende nimmt die Buehne Zeiger an, sonst blieben
   Links und Buttons darunter unerreichbar. */
html.drehbar #stage{pointer-events:auto;cursor:grab}
html.drehbar #stage:active{cursor:grabbing}
/* Leseschutz: liegt ueber der Sphaere und unter dem Text.
   Er deckt nur die Zeilenflaechen ab, weich auslaufend -- ausserhalb
   davon bleibt die Sphaere in voller Farbe stehen. */
#stage-read{z-index:var(--zi-read)}

/* ============================================================
   3 · LADEBILDSCHIRM
   Kein deckender Grund: die Sphaere im Canvas ist bereits die
   echte Buehne, es gibt nichts zu ueberblenden.
   ============================================================ */
/* --- Tiefe im Hintergrund (Aurora, 2026-09-15). Zwei Ebenen, beide leise:
   das ferne Sternenfeld auf #far (Skript im Abschnitt TIEFE) und, ganz
   hinten, Vignette und Korn als Grund des Dokuments. Die Vignette laeuft
   ueber den Rand hinaus aus, damit kein Ring sichtbar wird; das Korn ist
   statisch und kostet nichts. --- */
/* Der Grund haengt am html-Element, nicht am body: #far liegt mit negativem
   z-index dahinter -- also hinter JEDEM Inhalt, auch hinter unpositionierten
   Bloecken (Eddy, 2026-09-15: "hinter allem anderen"). Ein Grund am body
   wuerde die Sterne verdecken; PUOX OS macht es aus demselben Grund so. */
html{background:var(--bg)}
body{background:transparent}
/* Korn und Vignette liegen auf einer eigenen festen Ebene statt als
   Dokumenthintergrund. Als Hintergrund mit background-attachment:fixed und
   einem Blend-Modus mussten sie bei jedem Scrollen neu gerastert werden; als
   Ebene werden sie einmal gezeichnet und danach nur noch verschoben
   (gemessen 2026-09-15). z-index -2: hinter dem Sternenfeld (-1), vor dem
   Grundton am html-Element. */
body::before{
  content:"";
  position:fixed;
  inset:0;
  z-index:-2;
  pointer-events:none;
  background:
    url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='128' height='128'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='1' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='128' height='128' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E") 0 0/128px 128px repeat,
    radial-gradient(circle at 50% 50%, rgba(0,0,0,0) 58%, rgba(0,0,0,.22) 140%),
    var(--bg);
  /* Der Grundton muss in der Ebene liegen, nicht nur am html-Element: overlay
     mischt gegen das, was IN derselben Hintergrundliste darunter steht. Ohne
     ihn mischt das Korn gegen die durchsichtige Mitte des Verlaufs und bleibt
     als helles Rauschen stehen (gemessen am Bild, 15.09.). */
  background-blend-mode:overlay,normal,normal;
}
#far{
  position:fixed;
  inset:0;
  width:100%;
  height:100%;
  z-index:var(--zi-far);
  pointer-events:none;
}
@media (max-width:620px){ #far{display:none} }

#loader{
  position:fixed;
  inset:0;
  z-index:var(--zi-loader);
  display:grid;
  grid-template-rows:1fr auto;
  pointer-events:none;
  transition:opacity .45s var(--ease-glide),visibility .45s;
}
html.ready #loader{opacity:0;visibility:hidden}

.load-bar-wrap{
  display:flex;
  flex-direction:column;
  align-items:center;
  gap:14px;
  padding:0 var(--space-6) clamp(40px,7vh,72px);
}
.load-bar{
  width:min(280px,52vw);
  height:1px;
  background:var(--border);
  position:relative;
  overflow:hidden;
}
.load-bar i{
  position:absolute;
  inset:0 auto 0 0;
  width:0%;
  background:var(--mint);
}
.load-num{
  font-family:var(--font-mono);
  font-size:.82rem;
  letter-spacing:.14em;
  /* --muted: 5,4:1 gegen den Grund, --faint (.52): 4,7:1 -- nachgerechnet 2026-09-07 */
  color:var(--muted);
  font-variant-numeric:tabular-nums;
}

/* ============================================================
   4 · KOPF UND FUSS  (liegen immer ueber der Sphaere)
   ============================================================ */
/* Kopf-Logo, alle Seiten: das Lockup "puox studio" als Bild, 40 px hoch.
   Breite explizit (Mistakes #294: width:auto mass im Flex-Kopf 0 breit) --
   40 x 1695,48 / 595,54 aus der viewBox der Datei; wp.py rechnet denselben
   Wert nach. */
/* Keine feste Hoehe am Link: die kommt vom Bild (40 px). Im Ladebildschirm
   der Unterseiten waechst das Bild auf Lockup-Breite (intro.js, .gross) und
   der Link muss mitwachsen -- mit height:40px stand er 40 px hoch um ein
   274 px hohes Bild, und die Mitte lag falsch (Sichtpruefung 16.09.). */
.brand{
  position:relative;
  display:flex;
  align-items:center;
  text-decoration:none;
  flex:none;
}
.brand--lockup .lockup{display:block;height:40px;width:113.9px;color:var(--cream)}
/* Die Wortmarke der Startseite liegt deckungsgleich auf ihrem Platz im
   Lockup-Bild: Textblock WORT_VB = x 718,68, y 50,35, Breite 976,80 im
   Lockup 1695,48 x 595,54 -> bei 40 px Hoehe 48,3 px von links, 65,6 px
   breit, senkrecht mittig (3,4 px Rand, genau wie align-items:center). So
   steht sie auf der Startseite genau dort, wo sie auf den Unterseiten im
   Lockup steht -- beim Wechsel wandert allein das Bildlogo in die Mitte und
   zurueck, die Wortmarke springt nicht mehr (vorher 104 px ganz links).
   Sie fliegt beim Auftakt (transform per JS, darum origin links und keine
   transform-Transition). */
.wordmark{
  position:absolute;
  left:48.3px;
  top:50%;
  transform-origin:left center;
  translate:0 -50%;
  width:65.6px;
  height:auto;
  color:var(--cream);
  /* will-change setzt placeIntro nur fuer den Flug und nimmt es bei der
     Landung wieder weg: eine dauerhaft eigene Ebene fuer ein ruhendes
     Element kostet nur Speicher. */
  transition:opacity .4s var(--ease-glide);
}
/* Startseite: das Bild ist nur der unsichtbare Platzhalter, der dem Link die
   Masse des Lockups gibt -- zu sehen ist allein die Wortmarke. Das Bildlogo
   steht dort als Sphaere in der Bildmitte, ein zweites im Kopf waere eine
   Doppelung (Eddy, 2026-09-16). An :not(.intro) gebunden: Unterseiten
   zeigen das Bild (Mistakes #323). */
html:not(.intro) .brand .lockup{visibility:hidden}
/* Erst ab .ready animieren: sonst gleitet die Wortmarke beim Seitenaufbau
   erst in das Lockup hinein, statt dort zu stehen. */
html.js:not(.ready) .brand{pointer-events:none}

.site-header{
  position:fixed;
  top:0;left:0;right:0;
  height:var(--header-h);
  z-index:var(--zi-chrome);
  display:flex;
  align-items:center;
  gap:var(--space-6);
  padding:0 var(--gutter);
  background:linear-gradient(to bottom,rgba(18,21,20,.92),rgba(18,21,20,0));
  backdrop-filter:blur(6px);
  -webkit-backdrop-filter:blur(6px);
}
.header-right{
  margin-left:auto;
  display:flex;
  align-items:center;
  gap:var(--gap-nav);
}
.nav{display:flex;gap:var(--gap-nav)}
.nav a{font-size:.92rem;text-decoration:none;color:var(--muted);transition:color .2s}
.nav a:hover,.nav a:focus-visible{color:var(--cream)}

/* --- Leistungen-Menue (Fassung B "Knotenfeld", Aurora 24.09.2026, eingebaut
   25.09.2026): eine Mint-Nabe waechst unter dem Wort, drei echte Ringe des
   Logos docken frei auf ihren Plaetzen an -- Webdesign N[2] (Anker 48, Kasten
   38 px), Website-Management N[0] (Anker 32, 27 px), E-Mail-Sicherheit N[7]
   (Anker 22, 20 px); Band = (R - r) + 2, Ringmitte auf (dx, dy). Ohne Kanten
   und ohne Chips (Eddy, 24./25.09.). Endlage ist der Grundzustand; die
   Bewegung liegt allein in der Media-Query, bei reduzierter Bewegung steht
   alles sofort. Unter 900 px gibt es keine Navigation, also auch kein Menue.
   Entwuerfe und Alternativen: leistungen-menue-entwuerfe.html (Grundverzeichnis). --- */
.menu{position:relative}
.menu summary{list-style:none;cursor:pointer;font-size:.92rem;color:var(--muted);transition:color .2s}
.menu summary::-webkit-details-marker{display:none}
.menu summary:hover,.menu summary:focus-visible,.menu[open] summary{color:var(--cream)}
/* --- Burger: nur unter 900 px sichtbar (Media-Query unten). Drei Striche,
   offen als X; oeffnet die Navigation als Tafel (Eddy, 25.09.2026: unter
   900 px war gar keine Navigation zu sehen). --- */
.burger{display:none;flex:none;flex-direction:column;justify-content:center;gap:5px;width:40px;height:40px;padding:9px;border:0;border-radius:var(--radius-xs);background:transparent;cursor:pointer}
.burger i{display:block;height:2px;width:100%;background:var(--cream);border-radius:1px;transition:transform .25s var(--ease-glide),opacity .2s}
.burger:hover i,.burger:focus-visible i{background:var(--mint)}
html.nav-offen .burger i:nth-child(1){transform:translateY(7px) rotate(45deg)}
html.nav-offen .burger i:nth-child(2){opacity:0}
html.nav-offen .burger i:nth-child(3){transform:translateY(-7px) rotate(-45deg)}
.kf-drop{position:absolute;left:50%;top:calc(100% + 4px);width:0;height:0}
.kf-hub{position:absolute;left:-4px;top:-4px;width:8px;height:8px;border-radius:50%;
       background:var(--mint);box-shadow:0 0 6px rgba(33,241,168,.5)}
/* --kb: Kastengroesse des Rings; der Rand haelt die Ringmitte auf (dx, dy) */
.kf-node{--dx:0px;--dy:0px;--kb:30px;position:absolute;left:0;top:0;margin:calc(var(--kb) / -2) 0 0 calc(var(--kb) / -2);
        display:flex;align-items:center;gap:8px;transform:translate(var(--dx),var(--dy));
        transition:opacity .18s}
.kf-node a{display:flex;align-items:center;gap:8px;text-decoration:none;color:var(--cream);
          font-family:var(--font-display);font-weight:600;font-size:.8rem;white-space:nowrap}
.kf-node a:focus-visible{outline:2px solid var(--mint);outline-offset:3px;border-radius:2px}
.kf-node:nth-of-type(1){--dx:-90px;--dy:30px;--kb:38px}
.kf-node:nth-of-type(2){--dx:88px;--dy:37px;--kb:27px}
.kf-node:nth-of-type(3){--dx:-28px;--dy:68px;--kb:20px}
@media (prefers-reduced-motion:no-preference){
  /* Auftritt: Nabe waechst, die Ringe docken versetzt an (160/230/300 ms).
     Schliessen (Klasse zu vom Kopf-Skript): Ringe zuerst, letzter zuerst,
     die Nabe zuletzt -- das Skript nimmt open erst nach 500 ms weg. */
  .menu[open] .kf-hub{animation:hubAuf .12s var(--ease-settle) both}
  .menu[open] .kf-node{animation:knotenAuf .3s var(--ease-glide) both}
  .menu[open] .kf-node:nth-of-type(1){animation-delay:.16s}
  .menu[open] .kf-node:nth-of-type(2){animation-delay:.23s}
  .menu[open] .kf-node:nth-of-type(3){animation-delay:.3s}
  .menu.zu .kf-node{animation:knotenZu .2s var(--ease-glide) both}
  .menu.zu .kf-node:nth-of-type(2){animation-delay:.05s}
  .menu.zu .kf-node:nth-of-type(1){animation-delay:.1s}
  .menu.zu .kf-hub{animation:hubAuf .12s var(--ease-glide) .28s reverse both}
}
@keyframes hubAuf{from{transform:scale(0)}to{transform:scale(1)}}
@keyframes knotenAuf{from{opacity:0;transform:translate(0,0) scale(.6)}to{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1)}}
@keyframes knotenZu{from{opacity:1;transform:translate(var(--dx),var(--dy)) scale(1)}to{opacity:0;transform:translate(0,0) scale(.6)}}

/* Inhalt, Menue und Fuss treten erst nach dem Ladebildschirm auf */
html.js:not(.ready) .header-right,
html.js:not(.ready) .site-footer{opacity:0}
.header-right,.site-footer{transition:opacity .6s var(--ease-glide) .35s}

.btn{
  display:inline-flex;
  align-items:center;
  gap:9px;
  font-family:var(--font-display);
  font-weight:600;
  font-size:.94rem;
  text-decoration:none;
  padding:12px 24px;
  border-radius:var(--radius-xs);
  transition:transform .2s var(--ease-settle),box-shadow .2s;
}
.btn--solid{background:var(--mint);color:var(--ink)}
.btn--solid:hover,.btn--solid:focus-visible{
  transform:translateY(-2px);
  box-shadow:0 8px 30px rgba(33,241,168,.34);
}
/* Der Lift zieht den Kasten unter dem Zeiger weg: 1 px ueber der Unterkante
   flackerte :hover (Knopf hebt, verliert den Zeiger, faellt, hebt ...) und
   seit dem Auswahl-Cue die Klammer mit (Skeptiker-Panel, 25.09.2026). Der
   Trefferbereich reicht darum so weit nach unten, wie der Lift hebt. */
.btn--solid{position:relative}
.btn--solid::after{content:"";position:absolute;left:0;right:0;top:0;bottom:-2px}
.btn--big{font-size:1.05rem;padding:16px var(--space-6)}
a:focus-visible,button:focus-visible{outline:2px solid var(--mint);outline-offset:3px}

.site-footer{
  position:relative;
  z-index:var(--zi-chrome);
  border-top:1px solid var(--border);
  background:rgba(18,21,20,.86);
  backdrop-filter:blur(8px);
  -webkit-backdrop-filter:blur(8px);
  font-size:.88rem;
  color:var(--muted);
}
.ft{
  max-width:var(--wrap);
  margin:0 auto;
  padding:var(--space-5) var(--gutter);
  display:flex;
  gap:var(--space-5);
  flex-wrap:wrap;
  align-items:center;
}
.ft nav{margin-left:auto;display:flex;gap:var(--space-5);flex-wrap:wrap}
/* Trefferflaeche 31 px hoch (WCAG 2.5.8, gemessen 23 px), Layout unveraendert. */
.ft a{text-decoration:none;padding:4px 0;margin:-4px 0}
.ft a:hover{color:var(--cream)}

/* ============================================================
   5 · PANELS
   ============================================================ */
/* 726 vh: Abschnitte 15 Prozent langsamer als urspruenglich, je rund
   0,75 Bildschirmhoehen Leerraum dazwischen -- und der Weg endet exakt,
   wenn der Schlussaufruf vollstaendig steht (kein toter Scroll danach). */
#scrolltrack{height:1152vh}  /* Leistungs-Fenster am Vollbild um die Haelfte laenger (Eddy, 2026-09-25, DEHN in der Engine): der Scrollweg (maxScroll = Track - 100 vh + Fuss) waechst um 1,063, also 1089 + 0,063 x (989 + Fuss) vh; nicht 1089 x 1,063, das traefe die Trackhoehe statt des Scrollwegs. Davor 871 x 1,25 (2026-09-18), 726 x 1,2 (2026-09-13) */
html:not(.motion) #scrolltrack{height:auto}

.panel{
  max-width:var(--wrap);
  margin:0 auto;
  padding:0 var(--gutter);
}
html.motion .panel{
  position:fixed;
  left:50%;
  top:50%;
  width:min(100%,var(--wrap));
  max-height:calc(100dvh - var(--header-h) - var(--space-6));
  /* hidden, nicht auto: ein Panel darf keine eigenen Rollbalken mitten im
     Bild aufziehen, der Scroll gehoert allein der Choreografie. */
  overflow:hidden;
  transform:translate(-50%,-50%);
  z-index:var(--zi-panel);
  opacity:0;
  visibility:hidden;
  pointer-events:none;
}
html.motion .panel.on{visibility:visible;pointer-events:auto}
/* Am Seitenende gehoert der Zeiger der Kugel: das Panel laesst ihn durch,
   nur Links und Knoepfe fangen ihn weiter. Sonst war die Kugel nur ober-
   und unterhalb des Textblocks zu greifen. */
html.drehbar .panel.on{pointer-events:none}
html.drehbar .panel.on a,html.drehbar .panel.on button{pointer-events:auto}

.panel-inner{position:relative;z-index:0}

/* Der Leseschutz steht nicht mehr im CSS: kein Kasten und kein Grund am
   Element. Er wird auf #stage-read gezeichnet, Zeile fuer Zeile und weit
   weichgezeichnet, damit keine Kante als Feld lesbar wird (paintRead).
   Die Zeilenmasse kommen aus measureRead. */

.stack{display:flex;flex-direction:column;gap:var(--space-5);max-width:60ch}
.stack .btn{align-self:flex-start;margin-top:var(--space-4)}

/* --- Messwerte: die Ringe der Sphaere docken hier an --- */
.gauges{
  display:grid;
  grid-template-columns:repeat(2,1fr);
  gap:clamp(24px,3vw,40px);
  margin-top:clamp(24px,5vh,56px);
}
/* Im Buehnenmodus stehen sie frei im Raum statt in einer Reihe */
html.motion [data-panel="messwerte"]{max-width:none;width:100%;padding:0}
html.motion [data-panel="messwerte"] .panel-inner{
  position:relative;
  height:calc(100dvh - var(--header-h) - 36px);
}
html.motion [data-panel="messwerte"] .stack{
  position:absolute;
  left:clamp(18px,4vw,60px);
  top:9%;
  max-width:30ch;
  z-index:2;
}
html.motion .gauges{
  position:absolute;
  inset:0;
  display:grid;
  grid-template-columns:repeat(4,1fr);
  align-items:center;
  justify-items:center;
  padding:15% 3% 7%;
  margin:0;
}
/* --gx/--gy meinen den Mittelpunkt: so laesst sich frei verteilen, ohne
   dass eine Gauge am Rand angeschnitten wird. */
/* Vier Spalten, jede Zelle einzeln in der Hoehe versetzt: wirkt frei
   verteilt, kann aber nicht aus dem Bild laufen. */
html.motion .gauge{
  position:static;
  width:min(100%,21ch);
  transform:translateY(var(--gy,0));
}
html.motion [data-panel="messwerte"] h2{font-size:clamp(1.6rem,3vw,2.4rem)}
/* Zwei Zeilen, ein Satz je Zeile (Eddy, 2026-09-18/20): der Umbruch sitzt im
   Markup (<br>), innerhalb eines Satzes wird nicht umbrochen -- die Spalte
   (30ch der Grundschrift) ist schmaler als der Satz in Ueberschriftgroesse. */
[data-panel="messwerte"] h2{white-space:nowrap}

.gauge{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-3)}
.g-txt{display:flex;flex-direction:column;align-items:center;text-align:center;gap:var(--space-2);width:100%}
/* Der Kreis kommt aus dem Canvas. Dieser Block haelt nur die Flaeche frei
   und meldet dem Canvas per Rect, wohin der Ring fahren soll. */
.gauge-ring{
  width:100%;
  max-width:var(--gw,138px);
  aspect-ratio:1;
  display:grid;
  place-items:center;
}
/* Ziffer exakt in der Ringmitte */
.gauge-num{
  font-family:var(--font-mono);
  font-size:clamp(1.1rem,2vw,1.6rem);
  font-weight:500;
  /* --gc folgt der Phase: erst der Vergleichswert in Warnfarbe, dann mint */
  color:var(--gc,var(--mint));
  font-variant-numeric:tabular-nums;
  line-height:1;
}
/* Zahl und Beschriftung gehoeren zum Ring, nicht zum Panel: sie kommen
   erst, wenn der Ring auf seinem Messplatz steht, und gehen wieder, bevor
   er ihn verlaesst. Sonst stuenden Titel und Quelle im leeren Raum,
   waehrend die Kreise noch unterwegs sind. */
html.motion .gauge .g-txt,
html.motion .gauge .gauge-num{opacity:var(--gt,0)}
.gauge h3{font-size:.95rem;font-weight:600;margin-top:4px}
.gauge .src{font-size:.7rem;color:var(--faint);font-family:var(--font-mono);margin-top:6px}

/* --- Tipptext: erst der Vergleichswert, dann der eigene --- */
.g-type{
  display:grid;
  /* Beide Zeilen sitzen in derselben Zelle und oben buendig, damit der
     Studienwert und der eigene Wert auf exakt gleicher Hoehe stehen. */
  align-items:start;
  justify-items:center;
  font-size:.82rem;
  line-height:1.4;
  color:var(--muted);
  min-height:2.8em;
  width:100%;
}
/* beide Zeilen in derselben Zelle, damit die Hoehe beim Wechsel nicht springt */
.g-type > *{grid-area:1/1}
.g-avg{opacity:var(--oa,0)}
.g-now{opacity:var(--ob,0)}
.tw-a,.tw{
  display:inline-block;
  overflow:hidden;
  white-space:nowrap;
  vertical-align:bottom;
  max-width:100%;
}
.tw-a{width:calc(var(--wa,0px) * var(--pa,0))}
.tw{width:calc(var(--wb,0px) * var(--pb,0))}
.cur{
  display:inline-block;
  width:.5em;
  height:1em;
  background:var(--mint);
  vertical-align:-.15em;
  margin-left:2px;
  visibility:hidden;
  animation:blink .9s steps(1) infinite;
}
@keyframes blink{0%,50%{opacity:1}50.01%,100%{opacity:0}}
.gauge[data-cur="a"] .cur-a{visibility:visible}
.gauge[data-cur="b"] .cur-b{visibility:visible}

/* --- Leistungen --- */
.cards{
  display:grid;
  grid-template-columns:repeat(3,1fr);
  /* Weiter auseinander als zuvor (14/1.8vw/26): die Kreise sitzen auf den
     Kartenmitten und brauchen sichtbar Luft zueinander. */
  gap:clamp(24px,2.6vw,40px);
  /* Mehr Luft zur Ueberschrift als bei den Messwerten, bewusst; auf dem
     Raster: 32 statt 30, 56 statt 60. */
  margin-top:clamp(32px,5vh,56px);
}
/* Rahmen und Flaeche der Karten zeichnet die Sphaere: drei ihrer Ringe fahren
   hierher und werden zu diesen Boxen. Das Element selbst bleibt durchsichtig,
   sonst laege sein Hintergrund ueber dem Canvas. */
.card{
  display:flex;
  flex-direction:column;
  gap:var(--space-3);
  padding:var(--space-6);
  background:transparent;
  border:0;
  border-radius:var(--radius-xs);
  text-decoration:none;
  transition:transform .25s var(--ease-settle);
}
html:not(.motion) .card:hover,
html:not(.motion) .card:focus-visible{transform:translateY(-4px)}
/* Der Karteninhalt haengt am Formfortschritt der Box, nicht am Panelfenster:
   Rahmen zuerst, Text danach. */
html.motion .card > *{opacity:var(--ct,0)}
/* Ohne Bewegung gibt es keine Sphaere, die den Rahmen zeichnet */
html:not(.motion) .card{
  background:rgba(31,37,35,.74);
  border:1px solid var(--border);
  border-radius:var(--radius-md);
}
html:not(.motion) .card:hover{border-color:var(--mint)}
/* Derselbe Lift wie beim Knopf (4 px): Trefferbereich haelt still */
html:not(.motion) .card{position:relative}
html:not(.motion) .card::after{content:"";position:absolute;left:0;right:0;top:0;bottom:-4px}
.card .num{font-family:var(--font-mono);font-size:.78rem;color:var(--mint);letter-spacing:.1em}
.card p{font-size:.92rem;color:var(--muted);line-height:1.55}
.card .go{margin-top:auto;padding-top:8px;font-size:.88rem;color:var(--mint)}

.close-panel .stack{max-width:46ch}
/* Ratgeber-Abschnitt (Test 2026-09-13): drei Artikel als Liste, Link auf alle */
.ratgeber-liste{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.ratgeber-liste a{display:block;padding:10px 0;color:var(--cream);text-decoration:none;border-bottom:1px solid var(--border);font-weight:600;transition:color .2s,border-color .2s}
.ratgeber-liste a:hover,.ratgeber-liste a:focus-visible{color:var(--mint);border-color:var(--mint)}
.ratgeber-mehr{color:var(--mint);text-decoration:none;font-size:.92rem}

/* Hero: die Kugel steht links, der Text rechts daneben. Beim Scrollen
   waechst die Kugel nach rechts und loest den Text von links her auf. */
html.motion .hero-panel .stack{margin:0 auto;max-width:52ch;text-align:center}
/* Der Hero-Text steht ein Zehntel groesser als der Rest (Eddy, 2026-09-18);
   die Ueberschrift ueber --fs-h1, der Absatz hier -- --fs-lead teilen sich
   die anderen Abschnitte. */
html.motion .hero-panel .lead{font-size:calc(var(--fs-lead) * 1.1)}
/* Woerter bleiben als Block zusammen, damit der Umbruch stimmt; jedes
   Zeichen bekommt seine gemessene Breite fest zugewiesen, damit beim
   Wechsel zu 0/1 nichts umspringt. */
.hw{display:inline-block;white-space:nowrap}
/* vertical-align:top: an der Grundlinie ausgerichtet verschob der Wechsel
   zu .zahl (andere Schrift, line-height 1) die Grundlinie des einen Kastens
   und damit die ganze Zeile um Pixel -- der Text sprang. Oben ausgerichtet
   bleibt jeder Kasten in seiner Zeile stehen. */
.hc{display:inline-block;vertical-align:top;text-align:center;transition:color .12s linear}
/* Kurz vor der Beruehrung wechselt das Zeichen in die Farbe der Sphaere */
/* Aufgenommene Zeichen behalten zunaechst die Schriftgroesse des Textes
   und schrumpfen dann per transform auf die Groesse der Kugelziffern,
   waehrend die Kante naeher kommt (eatHero setzt scale()). Blinkender
   Cursor davor. */
.hc.zahl{
  color:transparent;   /* der Buchstabe bleibt im Fluss und haelt die Zeile */
  position:relative;
  transform-origin:center;
}
/* Die Ziffer liegt als eigene Ebene mittig ueber dem Buchstabenkasten.
   Andere Schrift und Zeilenhoehe aendern so nichts am Textfluss -- als
   die Ziffer den Buchstaben ersetzte, sprang jedes Zeichen beim Wechsel
   um Pixel (Eddy, 2026-09-12). */
.hc.zahl::after{
  content:attr(data-z);
  position:absolute;
  inset:0;
  display:grid;
  place-items:center;
  color:var(--mint);
  font-family:'JetBrains Mono',Consolas,monospace;
  line-height:1;
}
.hc.zahl::before{
  content:"";
  position:absolute;
  /* Die Schreibmarke steht rechts vom Zeichen, das gerade zur Ziffer wird --
     dort, wo beim Tippen die Einfuegemarke steht (Eddy, 2026-09-18). */
  right:-3px;
  top:50%;
  width:2px;
  height:1.1em;
  transform:translateY(-50%);
  background:var(--mint);
  animation:blink .7s steps(1) infinite;
}


/* --- Seitenwechsel: die Karte oeffnet sich ueber den ganzen Bildschirm,
   ihr Text und dann das ganze Bild zerfallen in Nullen und Einsen, die
   Ziffern sammeln sich zum Logo, das Logo steht (seitenwechsel()). Alles
   auf der Ebene des Ladebildschirms, ueber dem Kopf: die Karte deckt das
   ganze Bild (Eddy, 2026-09-12). --- */
/* Kopf und Fuss ganz, nicht nur ihre Inhalte: beide tragen einen eigenen
   Grund (Verlauf oben, Flaeche unten) und wuerden das Sternenfeld sonst in
   einem Streifen verdecken (Eddy, 2026-09-15). Die geklickte .exit-card
   haengt zu diesem Zeitpunkt schon am body, sie bleibt also sichtbar --
   auch wenn sie aus dem Kopf kam (Menuepunkt, Knopf). */
html.exit #stage,html.exit #stage-read,
html.exit .site-header,html.exit .site-footer,
html.exit .panel .stack,html.exit .card:not(.exit-card){opacity:0!important;transition:opacity .3s}
/* Der Block (Leistungskarte oder Ratgeber-Text) bleibt an seiner Stelle
   stehen (fixed, alte Masse): sein Text wandert nicht, er kippt an Ort und
   Stelle in Ziffern. Was waechst, ist eine eigene Box darunter (#exit-box),
   die Rahmen und Grund traegt. */
html.exit .exit-card{
  position:fixed;
  margin:0;
  z-index:var(--zi-loader);
  background:transparent;
  border-color:transparent;
  clip-path:none!important;
  transform:none!important;
  transition:opacity .4s;
}
/* Nur die Startseite: Kopf (mit der Wortmarke) und Ladebalken bleiben
   unsichtbar, bis die Engine die Wortmarke ins Lockup gesetzt hat und ihr
   erstes Bild zeichnet (Klasse gesetzt, Engine-Start). So erscheinen Sphaere,
   Wortmarke und Balken in einem Bild, und bei ready wird nichts getauscht --
   vorher stand hier ein Logo-Bild ueber der Zeichnung, dessen Kanten beim
   Verschwinden kippten (Eddy, 25.09.2026). Unterseiten tragen seit dem
   fruehen motion-Schalter dieselbe Klasse -- ohne :not(.intro) verschwand
   dort das Logo des Ladebildschirms (Mistakes #323). */
html.motion:not(.intro):not(.gesetzt) .brand{opacity:0}
html.motion:not(.intro):not(.gesetzt) #loader{visibility:hidden}
#exit-box{position:fixed;z-index:var(--zi-loader);background:#1A201E;border:1px solid rgba(33,241,168,.85);border-radius:var(--radius-xs);pointer-events:none;transition:background .5s var(--ease-glide),border-color .5s var(--ease-glide)}
/* Der Karteninhalt haengt sonst am Formfortschritt (--ct) und waere beim
   Klick ausserhalb seines Textfensters unsichtbar (Mistakes #300). */
html.exit .exit-card > *{opacity:1!important}
/* Auch die Linien IM Block gehen mit: der Ratgeber-Textblock traegt
   Trennlinien zwischen den Artikeln, die stehen blieben, waehrend der Text
   schon zerfallen war -- das sah anders aus als bei den Leistungskarten
   (Eddy, 2026-09-16). Zerfallen kann nur Text; Linien blenden aus. */
html.exit .exit-card *{border-color:transparent;transition:border-color .35s}
/* Zerfaellt ein Knopf, faellt sein mintgruener Grund weg -- die dunkle
   Schrift stuende unsichtbar auf dem Seitengrund, bis sie kippt. */
html.exit .exit-card.btn{color:var(--cream)}
html.exit .exit-card.weg{opacity:0}
/* Ziffernfeld (Canvas, siehe sogFeld/sogMalen) auf eigenem Grund: die Karte
   darunter blendet aus, der Kopf darf nicht durchscheinen. Kein generischer
   Klassenname als Zusatz -- form/weit trafen .form des Kontaktformulars
   (Sichtpruefung 2026-09-12, Mistakes #298). */
.exit-feld{position:fixed;inset:0;width:100%;height:100%;z-index:var(--zi-loader);opacity:0;pointer-events:none}
.exit-feld.on{opacity:1}
/* Die Box traegt den Grund: erst Kartengrund mit Rand, ab dem Sog gar keinen
   mehr -- das Endbild steht auf dem Grund des Dokuments, und das Sternenfeld
   dahinter bleibt sichtbar (Eddy, 2026-09-15: Seitenwechsel auch mit Sternen).
   Der Grund ist derselbe Farbwert, das Bild aendert sich dadurch nicht. */
#exit-box.grund{background:transparent;border-color:transparent}
/* Kein blinkender Cursor an jeder Ziffer der Karte -- im Hero gilt er nur
   fuer das jeweils naechste Zeichen, hier kippen alle auf einmal. */
html.exit .exit-card .hc.zahl::before{display:none}

/* ============================================================
   6 · CURSOR  (Klammer -- Eddy, 2026-09-19; Einbau 2026-09-24)
   Eigener Zeiger nur mit Maus (hover:hover und pointer:fine), Touch
   behaelt den Systemzeiger. cursor:none erst, wenn die Form nachweislich
   im Bild steht -- die Klasse zeiger setzt das Skript im Kopf, nie das CSS
   von sich aus (Mistakes #61). Ebene ueber dem Ladebildschirm (9000):
   sonst verschwindet der Zeiger im Ziffernfeld des Seitenwechsels.
   Zustaende am html: zg-hot (ueber Auswaehlbarem: Link, Schaltflaeche,
   Karte, Menueknoten, Feld -- ganzer Kasten, je Bild ermittelt), zg-klick,
   zg-ueber (in der drehbaren Kugel), zg-greift (Kugel wird gezogen), zg-hell
   (Farbe: Creme, wo Mint oder Helles unter dem Zeiger liegt). Namen bewusst eigen: .cur ist die
   Tipp-Schreibmarke der Messwerte, eine gleichnamige Klasse am html legte
   deren Regeln auf die ganze Seite (Mistakes #298). Masse und Farben: cursor-varianten.md.
   ============================================================ */
html.zeiger,html.zeiger *{cursor:none!important}
#zeiger{position:fixed;left:0;top:0;z-index:9100;pointer-events:none;display:none}
html.zeiger #zeiger{display:block}
#zeiger b{position:absolute;left:0;top:0;pointer-events:none;will-change:transform}
/* Ziffern-Nachlauf: deckendes Creme mit Kante -- ohne Kante verschwinden die
   Ziffern auf den Ringen (gemessen 1,14:1, mit Kante 10,04:1). */
#zeiger .z{font-family:var(--font-mono);font-size:10px;color:var(--cream);
   filter:drop-shadow(0 0 1.5px var(--ink)) drop-shadow(0 0 1.5px var(--ink))}
/* Klammer: zwei Zeichen fassen die Stelle ein, die Mitte bleibt frei.
   Ruhe 16 px; ueber Auswaehlbarem und in der Kugel 22 px und 3 px auf,
   Klick und Ziehen schnappen zu. */
#zeiger .kl{width:18px;height:16px;margin:-8px 0 0 -9px;
    transition:height .16s var(--ease-glide),margin .16s var(--ease-glide)}
#zeiger .kl i{position:absolute;top:0;width:4px;height:100%;border:1px solid var(--mint);
      filter:drop-shadow(0 0 1.5px var(--ink)) drop-shadow(0 0 1.5px var(--ink));
      transition:transform .12s var(--ease-settle),border-color .16s linear}
#zeiger .kl i:first-child{left:0;border-right:0}
#zeiger .kl i:last-child{right:0;border-left:0}
/* Auswahl-Cue (Eddy, 25.09.2026): ueber jedem auswaehlbaren Element -- Link,
   Schaltflaeche, Karte, Menueknoten, Feld, ganzer Kasten -- gehen die
   Klammern auf wie ueber der Kugel (22 px, 3 px auf). Die Farbe haengt am
   Untergrund, nicht an der Form (zg-hell, unten). */
html.zg-hot #zeiger .kl,html.zg-ueber #zeiger .kl{height:22px;margin:-11px 0 0 -9px}
html.zg-hot #zeiger .kl i:first-child,html.zg-ueber #zeiger .kl i:first-child{transform:translateX(-3px)}
html.zg-hot #zeiger .kl i:last-child,html.zg-ueber #zeiger .kl i:last-child{transform:translateX(3px)}
/* Farbe (Eddy, 25.09.2026, live: "Kontrast nicht gegeben" -- das Auge schlaegt
   die Kantenmetrik, die Mint mit Schattensaum auf Mint 4,98:1 gab): Creme, wo
   unter dem Zeiger Mint oder Helles liegt, Mint nur auf dunklem Grund. zg-hell
   setzt das Skript je Bild; die Kugel am Seitenende behaelt ihr Creme. */
html.zg-ueber #zeiger .kl i,html.zg-hell #zeiger .kl i{border-color:var(--cream)}
/* Klick und Ziehen schnappen zu -- nach den Auf-Regeln, damit sie gewinnen */
html.zg-klick #zeiger .kl i:first-child,html.zg-greift #zeiger .kl i:first-child{transform:translateX(4px)}
html.zg-klick #zeiger .kl i:last-child,html.zg-greift #zeiger .kl i:last-child{transform:translateX(-4px)}
/* Die Bestandsregeln html.drehbar #stage{cursor:grab/grabbing} (Abschnitt 2)
   bleiben als Rueckfall stehen; laeuft der Cursor, deckt cursor:none sie. */
@media (prefers-reduced-motion:reduce){ #zeiger b{transition:none} }

/* ============================================================
   7 · SCHMALE VIEWPORTS
   ============================================================ */
@media (max-width:900px){
  .nav{display:none}
  .burger{display:flex}
  /* Offene Navigation: Tafel unter dem Kopf ueber der Seite. Die Leistungen
     stehen darin als Liste mit ihren Logo-Ringen (das Kopf-Skript oeffnet das
     details), darunter die uebrigen Punkte. Der Kopf selbst bleibt oben. */
  html.nav-offen{overflow:hidden}
  /* absolut zum Kopf, nicht fixed: der Kopf traegt backdrop-filter und ist damit
     der Bezug fuer fixed-Kinder -- bottom:0 laege sonst im 72-px-Kasten */
  html.nav-offen .nav{display:flex;flex-direction:column;gap:0;position:absolute;left:0;right:0;top:100%;height:calc(100dvh - var(--header-h));padding:16px var(--gutter) 40px;overflow:auto;
    background:rgba(18,21,20,.96);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);z-index:calc(var(--zi-chrome) - 1)}
  html.nav-offen .nav>a{font-family:var(--font-display);font-weight:600;font-size:1.35rem;color:var(--cream);padding:14px 0;border-top:1px solid var(--border)}
  html.nav-offen .menu{padding:6px 0 14px}
  html.nav-offen .menu summary{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);pointer-events:none}
  html.nav-offen .kf-drop{position:static;width:auto;height:auto;display:flex;flex-direction:column;gap:6px;margin-top:10px}
  html.nav-offen .kf-hub{display:none}
  html.nav-offen .kf-node{position:static;margin:0;transform:none!important;animation:none!important;opacity:1;padding:8px 0}
  html.nav-offen .kf-node a{font-size:1.2rem;gap:14px}
  .cards{grid-template-columns:1fr}
  /* Gestapelt muessen drei Karten samt Ueberschrift und Intro-Satz in
     eine Bildschirmhoehe passen: bei 822 px Hoehe standen 805 px Inhalt
     in 716 px Panel, die Ueberschrift war abgeschnitten. Enger gesetzt
     (Polster 32->20, Luecke 22->14, Abstand zur Ueberschrift 30->20)
     spart das rund 100 px. Unter ~760 px Fensterhoehe reicht auch das
     nicht -- dort braeuchte es statt Karten eine Liste (Nexus, Punkt 5). */
  .cards{gap:14px;margin-top:20px}
  .card{padding:20px}
  /* Das hohe Panel wird um die halbe Kopfzeile nach unten geschoben: mittig
     im Fenster laege seine Oberkante 11 px unter dem Kopfzeilenrand. */
  html.motion [data-panel="leistungen"]{top:calc(50% + var(--header-h) / 2)}
  #scrolltrack{height:1245vh}  /* 996 x 1,25 (Eddy, 2026-09-18) */
  /* Zu schmal fuer die freie Verteilung: zurueck ins Raster, sonst
     ueberlappen sich die vier Messwerte. */
  html.motion [data-panel="messwerte"]{max-width:var(--wrap);padding:0 var(--gutter)}
  html.motion [data-panel="messwerte"] .panel-inner{height:auto}
  html.motion [data-panel="messwerte"] .stack{position:static;max-width:none}
  html.motion .gauges{
    position:static;
    display:grid;
    grid-template-columns:repeat(2,1fr);
    gap:clamp(18px,4vw,30px);
    padding:0;
    margin-top:clamp(20px,4vh,36px);
  }
  html.motion .gauge{position:static;width:auto}
}
@media (max-width:520px){
  :root{--header-h:64px}
  .btn{padding:8px 16px;font-size:.86rem}
  /* 375 px: Logo 114 + Burger + Knopf passten mit --gap-nav nicht in eine Zeile,
     "Kostenlose Demo" brach um (Audit 25.09.2026, echter Browser). Kopfzeile
     gemessen (Chromium): Rand 16 + Logo 114 + Kopf-Abstand 16 + Burger 40 + 12 +
     Knopf 143 + Rand 16 = 357 px, einzeilig ab 360 px mit vollem Rand (Pruefung 2:
     mit Kopf-Abstand 32 und Polster 16 war der Knopf bei 360 px abgeschnitten). */
  .site-header{gap:16px}
  .header-right{gap:12px}
  .header-right .btn{white-space:nowrap;padding:8px 12px}
  .card{padding:var(--space-4)}   /* 16: monoton fallend 32 -> 20 -> 16 */
}
@media (max-width:359px){
  /* Schmaler als die Kopfzeile: lieber zweizeiliger Knopf als abgeschnitten. */
  .header-right .btn{white-space:normal}
  /* Ohne Bewegung stehen die vier Messringe als Raster im Textfluss; zwei Spalten
     wurden bei 320 px 350 px breit und zogen den fixierten Kopf mit
     (Live-Nachpruefung 25.09.2026). Mit Bewegung setzt die Engine die Plaetze. */
  html:not(.motion) .gauges{grid-template-columns:1fr}
}

/* Flache Fenster: Beiwerk faellt weg, damit Kopf und Werte im Bild bleiben */
@media (max-height:760px){
  html.motion .gauges{margin-top:clamp(14px,2.5vh,28px)}
  html.motion .gauge-ring{width:clamp(68px,7.5vw,104px)}
  html.motion .cards{margin-top:clamp(14px,2.5vh,26px)}
}
@media (max-height:600px){
  html.motion .gauge .src{display:none}
  html.motion .card p{font-size:.86rem}
}

/* ============================================================
   8 · OHNE BEWEGUNG  (gleicher Inhalt, keine Buehne)
   ============================================================ */
html:not(.motion) .panel{
  position:relative;
  z-index:var(--zi-panel);
  padding-top:clamp(90px,15vh,190px);
  padding-bottom:clamp(90px,15vh,190px);
}
html:not(.motion) .hero-panel{padding-top:calc(var(--header-h) + 44px)}
html:not(.motion) #stage{opacity:.3}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.001ms!important;transition-duration:.001ms!important}
}
/* ==========================================================
   WordPress-Zusatz (_build/parts/wp.css). In der Startseiten-Datei
   gibt es diese Elemente nicht: keine Adminleiste, kein Editor.
   ========================================================== */
body.admin-bar .site-header{top:32px}
@media screen and (max-width:782px){body.admin-bar .site-header{top:46px}}
.alignwide{max-width:1200px;margin-left:auto;margin-right:auto}
.alignfull{max-width:none}
.screen-reader-text{position:absolute!important;left:-9999px;width:1px;height:1px;overflow:hidden}
.screen-reader-text:focus{left:16px;top:16px;width:auto;height:auto;padding:8px 12px;background:#fff;color:#000;z-index:100000}

/* Platzhalter-Konvention der Rechtstexte: BITTE EINTRAGEN in eckigen Klammern,
   rot auf der Seite, gezaehlt vom Deploy-Gate (07_automation/site-build). */
.bitte-eintragen{color:#F24B4B;font-weight:600}

/* ==========================================================
   UNTERSEITEN  (_build/parts/page.css)
   Die Startseite ist eine Choreografie, jede andere Seite ein
   Dokument: gleiche Tokens, gleicher Kopf und Fuss, aber die
   Sphaere ist hier nur der Ladebildschirm (data-intro am Canvas,
   siehe introEnde() in der Engine). Kein 3D im Betrieb.
   ========================================================== */

/* Dokumentseiten zeigen ihre Rollleiste; die Startseite blendet sie aus. */
html.intro{scrollbar-width:auto}
html.intro::-webkit-scrollbar{display:block;width:10px}
html.intro::-webkit-scrollbar-thumb{background:rgba(233,225,207,.22);border-radius:5px}

/* Ladebildschirm (intro.js): erst wenn das Lockup oben links steht, tritt
   der Inhalt auf. */
html.js.intro:not(.intro-done) .page-main{opacity:0}
html.js.intro .page-main{transition:opacity .6s var(--ease-glide) .2s}
/* Kopf-Logo (40 px, Breite explizit): seit 2026-09-16 fuer alle Seiten in
   index.html definiert (.brand--lockup .lockup) -- hier nichts mehr dazu. */
/* Waehrend des Ladebildschirms steht das Logo in echter Groesse (intro.js
   setzt .gross, fixed und die Breite); das Bild fuellt den Link. */
html.intro .brand.gross .lockup{width:100%;height:auto}
/* Der Flug des Logos (intro.js) rechnet mit dem Ursprung links/mittig: Ziel
   sind die linke Kante und die senkrechte Mitte der Kopf-Lage. Ohne diese
   Regel skalierte der Browser um die Mitte -- das Logo landete rund 330 px zu
   weit rechts und sprang beim Loslassen an seinen Platz (Eddy, 2026-09-18,
   Punkt 9). Gilt fuer den Auftritt und den Abgang. */
html.intro .brand.gross{transform-origin:left center}
/* Abgang zu einer anderen Seite (intro.js, Klasse abgang): Inhalt, Kopf und
   Fuss blenden aus, waehrend das Logo in die Mitte faehrt. */
html.js.intro.abgang .page-main{opacity:0;transition:opacity .35s var(--ease-glide)}
html.abgang .header-right,html.abgang .site-footer{opacity:0;transition:opacity .3s var(--ease-glide)}
/* Auf der Buehne traegt der Lead volle Textfarbe; hier gibt es keine Buehne. */
html.intro .lead{color:var(--muted)}

.page-main{
  position:relative;
  z-index:var(--zi-panel);
  padding-top:calc(var(--header-h) + clamp(40px,8vh,96px));
}
.kicker{
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--mint);
}

/* --- Seitenkopf --- */
.phead{
  max-width:var(--wrap);
  margin:0 auto;
  padding:0 var(--gutter) clamp(32px,6vh,72px);
  display:flex;
  flex-direction:column;
  gap:var(--space-4);
}
.phead h1{max-width:22ch}
.phead .lead{max-width:56ch}
.chips{display:flex;flex-wrap:wrap;gap:var(--space-3)}
.chip{
  font-family:var(--font-mono);
  font-size:.72rem;
  letter-spacing:.06em;
  padding:6px 10px;
  border:1px solid var(--border);
  border-radius:var(--radius-xs);
  color:var(--muted);
}

/* --- Abschnitte --- */
.sec{max-width:var(--wrap);margin:0 auto;padding:clamp(40px,7vh,88px) var(--gutter)}
.sec--tight{padding-top:0}
.sec--line{border-top:1px solid var(--border)}
.sec > h2{margin-bottom:var(--space-5);max-width:26ch}
.sec > h2 + .lead{margin-top:calc(-1 * var(--space-3));margin-bottom:var(--space-6)}
.grid2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(24px,4vw,64px)}
.grid3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(16px,2.6vw,32px)}
.grid4{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(16px,2.6vw,32px)}
.prose{max-width:68ch}
.prose h3{margin-top:var(--space-5)}
.prose p+p,.prose h3+p{margin-top:var(--space-4)}
.list{list-style:none;padding:0;margin:var(--space-5) 0 0;display:grid;gap:var(--space-3)}
.list li{position:relative;padding-left:26px}
.list li::before{content:"";position:absolute;left:0;top:.7em;width:14px;height:1px;background:var(--mint)}
.grid2 > .list{margin-top:0}

/* Karten (statisch, ohne Sphaere -- die Rahmen zeichnet hier das CSS) */
.pcard{
  display:flex;
  flex-direction:column;
  gap:var(--space-3);
  padding:var(--space-6);
  background:rgba(31,37,35,.74);
  border:1px solid var(--border);
  border-radius:var(--radius-md);
  text-decoration:none;
}
.pcard--hi{border-color:rgba(33,241,168,.45)}
.pcard .num{font-family:var(--font-mono);font-size:.78rem;color:var(--mint);letter-spacing:.1em}
.pcard p{font-size:.95rem;color:var(--muted);line-height:1.55}
.pcard .list{margin-top:var(--space-3)}
.pcard .list li{font-size:.95rem}
.preis{font-family:var(--font-display);font-size:1.9rem;font-weight:700;letter-spacing:-.02em;line-height:1}
.preis small{font-family:var(--font-sans);font-size:.85rem;font-weight:400;color:var(--muted);margin-left:6px}

/* FAQ: native <details>, kein Skript */
.faq{max-width:68ch}
.faq details{border-top:1px solid var(--border)}
.faq details:last-child{border-bottom:1px solid var(--border)}
.faq summary{
  cursor:pointer;
  list-style:none;
  display:flex;
  justify-content:space-between;
  gap:var(--space-4);
  padding:var(--space-4) 0;
  font-family:var(--font-display);
  font-weight:600;
  font-size:1.02rem;
}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";font-family:var(--font-mono);color:var(--mint);flex:none;transition:transform .2s}
.faq details[open] summary::after{transform:rotate(45deg)}
.faq details p{padding:0 0 var(--space-4);color:var(--muted);max-width:60ch}

/* Schlussaufruf */
.cta .stack{max-width:52ch}

/* --- Kontakt --- */
.kontakt{display:grid;grid-template-columns:minmax(0,5fr) minmax(0,7fr);gap:clamp(32px,5vw,80px)}
.kdaten{display:grid;gap:var(--space-4);margin:var(--space-5) 0 0}
.kdaten dt{font-family:var(--font-mono);font-size:.7rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint)}
.kdaten dd{margin:4px 0 0;font-size:1.05rem}
.kdaten a{text-decoration:none;padding:2px 0}   /* inline: Trefferflaeche 26 px (WCAG 2.5.8), Zeile gleich */
.kdaten a:hover{color:var(--mint)}
.kontakt .kicker{margin-bottom:var(--space-3)}
.kontakt h2{margin-bottom:var(--space-4)}
.kontakt .form{margin-top:var(--space-5)}
.form{display:grid;gap:var(--space-4)}
.form .row2{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4)}
.field{display:grid;gap:var(--space-2)}
.field label{font-size:.85rem;color:var(--muted)}
.field input,.field select,.field textarea{
  width:100%;
  font:inherit;
  color:var(--cream);
  background:rgba(31,37,35,.74);
  border:1px solid var(--border);
  border-radius:var(--radius-xs);
  padding:12px 14px;
  transition:border-color .2s;
}
.field select option{background:#1f2523}
.field textarea{min-height:150px;resize:vertical}
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{
  outline:2px solid var(--mint);outline-offset:2px;border-color:var(--mint);
}
.check{display:flex;gap:10px;align-items:flex-start;font-size:.85rem;color:var(--muted)}
.check input{margin-top:4px;accent-color:var(--mint)}
.form .btn{justify-self:start;border:0;cursor:pointer}
.formmsg{scroll-margin-top:120px;
  padding:var(--space-4) var(--space-5);
  border:1px solid var(--border);
  border-left:3px solid var(--mint);
  border-radius:var(--radius-xs);
  background:rgba(31,37,35,.74);
  margin-bottom:var(--space-5);
}
.formmsg--err{border-left-color:#F2764B}
.formmsg p{margin:0}
.formmsg p+p{margin-top:4px;color:var(--muted);font-size:.92rem}
/* Honigtopf: im Layout, aber ausserhalb des Sichtfelds -- bewusst nicht
   display:none, manche Bots ueberspringen ausgeblendete Felder gezielt. */
.hp{position:absolute!important;left:-9999px!important;top:auto;width:1px;height:1px;overflow:hidden}
/* Frage nach der bestehenden Website: Pillen statt Radios; "Ja" wird zum
   Kreis, der Kreis zum Feld (Skript in formular.php), das Feld klappt ueber
   grid-template-rows auf, der Rest rutscht nach. */
.form{position:relative}
.wahl .flabel{font-size:.85rem;color:var(--muted)}
.wahl-opt{display:flex;gap:var(--space-3);flex-wrap:wrap}
.pill{
  position:relative;
  padding:9px 16px;
  border:1px solid var(--border);
  border-radius:var(--radius-xs);   /* wie die Felder: ein Eckradius fuer die ganze Site (Eddy, 2026-09-12) */
  font-size:.85rem;
  color:var(--cream);
  cursor:pointer;
  background:rgba(31,37,35,.74);
  transition:background .2s,color .2s,border-color .2s;
}
.pill input{position:absolute;opacity:0;width:1px;height:1px}
.pill:has(input:checked){background:var(--mint);color:var(--ink);border-color:var(--mint)}
.pill:has(input:focus-visible){outline:2px solid var(--mint);outline-offset:2px}
.feld-url{display:grid;grid-template-rows:0fr;transition:grid-template-rows .55s var(--ease-settle)}
.feld-url.open{grid-template-rows:1fr}
.feld-url > div{overflow:hidden;min-height:0;display:grid;gap:var(--space-2)}
.feld-url > div > label{margin-top:var(--space-4);font-size:.85rem;color:var(--muted)}
.feld-url input{transition:opacity .2s}
.ghost{
  position:absolute;
  z-index:2;
  pointer-events:none;
  display:grid;
  place-items:center;
  box-sizing:border-box;
  border:1px solid var(--mint);
  font-size:.85rem;
  overflow:hidden;
  white-space:nowrap;
}

/* --- Ratgeber --- */
.artikel-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(16px,2.6vw,32px)}
.artikel-karte{transition:border-color .2s,transform .25s var(--ease-settle)}
.artikel-karte:hover,.artikel-karte:focus-visible{border-color:var(--mint);transform:translateY(-3px)}
.artikel-karte h2{font-size:1.2rem}
.artikel-karte .go{margin-top:auto;padding-top:8px;font-size:.88rem;color:var(--mint)}
.artikel{
  display:grid;
  grid-template-columns:minmax(0,1fr) 300px;
  gap:clamp(32px,5vw,80px);
  max-width:var(--wrap);
  margin:0 auto;
  padding:0 var(--gutter) clamp(40px,7vh,88px);
}
.artikel-body{max-width:68ch;display:flow-root}
.artikel-body h1{margin:var(--space-3) 0 var(--space-4)}
.artikel-body h2{font-size:1.5rem;margin:var(--space-6) 0 var(--space-4)}
.artikel-body h3{margin:var(--space-5) 0 var(--space-3)}
.artikel-body p{margin:0 0 var(--space-4)}
.artikel-body .intro{font-size:var(--fs-lead);color:var(--muted);margin-bottom:var(--space-5)}
.artikel-body .list{margin:0 0 var(--space-5)}
.artikel-body table{width:100%;border-collapse:collapse;font-size:.95rem;margin:0 0 var(--space-5)}
.artikel-body th,.artikel-body td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--border);vertical-align:top}
.artikel-body th{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.1em;text-transform:uppercase;color:var(--faint);font-weight:500}
.artikel-body td.betrag{font-family:var(--font-mono);color:var(--mint);white-space:nowrap}
.callout{
  padding:var(--space-4) var(--space-5);
  border-left:3px solid var(--mint);
  background:rgba(31,37,35,.74);
  border-radius:var(--radius-xs);
  margin:0 0 var(--space-5);
}
.callout p{margin:0}
.meta{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.1em;color:var(--faint);margin:0 0 var(--space-5)}
.crumbs{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.06em;color:var(--faint);display:flex;gap:8px;flex-wrap:wrap;margin:0 0 var(--space-4)}
.crumbs a{text-decoration:none;padding:4px 0;margin:-4px 0}   /* Trefferflaeche 27 px (WCAG 2.5.8), Layout gleich */
.crumbs a:hover{color:var(--cream)}
/* kennzahl, nicht zahl: .zahl ist die Ziffer der Sphaeren-Engine (Kachel-Rahmen um
   jede Hero- und Kartenziffer auf der WP-Startseite, gemessen 2026-09-12) */
.zahlen{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4);margin:0 0 var(--space-5)}
.kennzahl{padding:var(--space-4);border:1px solid var(--border);border-radius:var(--radius-md)}
.kennzahl b{display:block;font-family:var(--font-mono);font-size:1.6rem;color:var(--mint);font-weight:500}
.kennzahl p{margin:4px 0 0;font-size:.85rem;color:var(--muted)}
.grund{padding:var(--space-4) 0;border-top:1px solid var(--border)}
.grund:last-of-type{border-bottom:1px solid var(--border);margin-bottom:var(--space-5)}
.grund .num{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.14em;color:var(--mint)}
.grund h2,.grund h3{margin:4px 0 6px;font-size:var(--fs-h3);line-height:1.2;letter-spacing:-.01em;font-weight:600}   /* h2 seit 25.09. (Reihenfolge h1 > h2), Optik der h3 */
.grund p{margin:0;color:var(--muted)}
.seite{position:sticky;top:calc(var(--header-h) + 24px);display:grid;gap:var(--space-5);align-self:start}
.seite nav{display:grid;gap:var(--space-3)}
.seite nav a{text-decoration:none;color:var(--muted);font-size:.92rem}
.seite nav a:hover{color:var(--cream)}

/* --- Ueber uns --- */
.zitat{
  font-family:var(--font-display);
  font-size:clamp(1.3rem,2.4vw,1.9rem);
  font-weight:600;
  line-height:1.3;
  letter-spacing:-.02em;
  max-width:32ch;
  margin:0;
}
.zitat em{font-style:normal;color:var(--mint)}
.kicker + .zitat{margin-top:var(--space-3)}
.zitat + .lead{margin-top:var(--space-5)}
.vergleich{display:grid;grid-template-columns:1fr 1fr;gap:clamp(16px,2.6vw,32px)}
.vergleich .kopf{font-family:var(--font-mono);font-size:.72rem;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);margin:0 0 var(--space-3)}
.vergleich .puox .kopf{color:var(--mint)}
.vergleich ul{list-style:none;margin:0;padding:0}
.vergleich li{padding:12px 0;border-top:1px solid var(--border)}
.vergleich .agentur li{color:var(--muted)}

/* --- Rechtstexte --- */
.sec.recht{max-width:var(--wrap)}   /* Spalte links am Seitenkopf, nicht mittig */
.recht > *{max-width:68ch}
.recht h2{font-size:1.3rem;margin:var(--space-6) 0 var(--space-3)}
.recht a{padding:2px 0}   /* inline: Trefferflaeche >= 24 px (WCAG 2.5.8, Live-Nachpruefung 25.09.), Zeile gleich */
.recht h3{font-size:1.05rem;margin:var(--space-5) 0 var(--space-3)}
.recht p,.recht li{color:var(--muted)}
.recht p+p{margin-top:var(--space-3)}
.recht ul{padding-left:20px}

/* --- Schmale Fenster --- */
@media (max-width:900px){
  /* minmax(0,1fr) statt 1fr: 1fr heisst minmax(auto,1fr), die Spalte waechst auf die Mindestbreite ihres
     Inhalts -- eine Tabelle mit nowrap-Zelle machte den Ratgeber "Was kostet" 172 px breiter als das Fenster,
     abgeschnitten statt gescrollt (Live-Nachpruefung 25.09.2026). */
  .grid2,.grid3,.grid4,.kontakt,.artikel-grid,.vergleich,.zahlen,.artikel,.form .row2{grid-template-columns:minmax(0,1fr)}
  .seite{position:static}
}
@media (max-width:520px){
  /* Tabellen im Artikel (thead + tbody) scrollen auf dem Handy in sich, statt die Seite zu sprengen;
     ab 521 px bleibt die Tabelle 100 % breit wie bisher. */
  .artikel-body table{display:block;overflow-x:auto;-webkit-overflow-scrolling:touch}
}
@media (max-width:1100px){
  /* td.betrag ohne Umbruch macht die Preistabelle 530 px breit: zwischen 521 und 566 px sprengte sie die
     Seite, zwischen 901 und 1040 px ragte sie in die Seitenleiste (Live-Nachpruefung 2, 25.09.2026).
     Mit Umbruch reicht die Mindestbreite ~360 px (mit &nbsp; vor dem Euro-Zeichen); ab 1101 px hat die Spalte Platz, dort bleibt nowrap. */
  .artikel-body td.betrag{white-space:normal}
}
@media (min-width:521px) and (max-width:1100px){
  /* Rest aus Nachpruefung 3: mit Umbruch blieb die Tabelle 458 px breit (laengste Woerter je Spalte) und
     ragte bei 901-930 px 28 px in den Spaltenabstand, bei 521-534 px 10 px in den Seitenrand. Zellen duerfen
     notfalls im Wort umbrechen (Trennstellen stehen als &shy; im Inhalt): Mindestbreite faellt unter die
     Spalte, der Tabellenalgorithmus verteilt den Platz. Eddy, 26.09.2026: "mach das". Nicht unter 521 px:
     dort scrollt die Tabelle bei Bedarf in sich (bis ~421 px, Mindestbreite 356 px), sonst zerriss es Preise ("12.00|0 EUR",
     Live-Nachpruefung 4). */
  .artikel-body td,.artikel-body th{overflow-wrap:anywhere}
}
/* Lange Einzelwoerter in Ueberschriften ("Datenschutzerklärung" bei 320/360 px 20 px breiter als das
   Fenster): Umbruch nur, wenn das Wort sonst nicht passt (anywhere greift erst ohne andere Umbruchstelle).
   Automatische Trennung nur unter 400 px und nur fuer Woerter ab 12 Zeichen -- mit hyphens:auto auf allen
   Breiten trennte Chromium "Baukas-tensystem" bei 1024 px und "Web-site" bei 480 px ohne Not
   (Live-Nachpruefung 3). Die zwei bekannten Woerter tragen zusaetzlich &shy; im Inhalt. Nur h1/h2 und
   Schwelle 12: h3 mit anywhere und Schwelle 10 brachen "Datenverlu-st" (901-959 px) und "Wissen, / das
   weiterhilft." (Live-Nachpruefung 5) -- zurueck auf den Stand von Lauf 4. */
.page-main h1,.page-main h2{overflow-wrap:anywhere}
@media (max-width:399px){
  .page-main h1,.page-main h2{hyphens:auto;hyphenate-limit-chars:12 5 5}
}
