/* TROTZDEM · Horizont – das einzige Stylesheet des Horizont-Seitenbaums.
   Geladen wird es ausschliesslich von templates/horizont/fe_page_horizont.html5,
   und dieses Seitenlayout hängt nur an den Seiten unter der Wurzel „Horizont".
   Deshalb dürfen hier ungescopte Element- und Utility-Selektoren stehen
   (body, h1/h2/h3, a, img, .wrap, .btn, .pic …): sie erreichen keine Seite des
   EclipseX-Baums, der weiterhin sein eigenes PCT-Stylesheet lädt (siehe
   Trotzdem\HorizontBundle\EventListener\FilterPctStylesheetsListener).
   Wird das Stylesheet je in ein anderes Layout eingebunden, muss es vorher
   unter einen gemeinsamen Wrapper gescopt werden (".hz …" – die Klasse trägt
   der <body> bereits).

   Schriften – selbst gehostet, kein Google-Fonts-CDN und kein
   PCT-Theme-Designer-CSS. Die woff2-Dateien liegen im Bundle
   (packages/trotzdem-horizont/public/fonts/, ausgeliefert als
   public/bundles/trotzdemhorizont/fonts/). Die Pfade sind RELATIV zu dieser
   Datei – url() in CSS löst gegen das Stylesheet auf, nicht gegen den
   <base href> des Dokuments. Damit bringt das Bundle seine Schriften selbst
   mit und hängt nicht mehr an files/cto_layout (PCT-Lieferumfang), das mit dem
   Abbau der PCT-Module verschwindet.
   Gewichte: Raleway 200/300/400/600/700 (Überschriften, Buttons, Nav),
   Roboto 300/400/500/700 (Fließtext). font-display:swap, damit der Text sofort
   sichtbar ist. */
@font-face{font-family:'Raleway';font-style:normal;font-weight:200;font-display:swap;src:url('fonts/raleway-v34-latin-200.woff2') format('woff2')}
@font-face{font-family:'Raleway';font-style:normal;font-weight:300;font-display:swap;src:url('fonts/raleway-v34-latin-300.woff2') format('woff2')}
@font-face{font-family:'Raleway';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/raleway-v34-latin-regular.woff2') format('woff2')}
@font-face{font-family:'Raleway';font-style:normal;font-weight:600;font-display:swap;src:url('fonts/raleway-v34-latin-600.woff2') format('woff2')}
@font-face{font-family:'Raleway';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/raleway-v34-latin-700.woff2') format('woff2')}
@font-face{font-family:'Roboto';font-style:normal;font-weight:300;font-display:swap;src:url('fonts/roboto-v32-latin-300.woff2') format('woff2')}
@font-face{font-family:'Roboto';font-style:normal;font-weight:400;font-display:swap;src:url('fonts/roboto-v32-latin-regular.woff2') format('woff2')}
@font-face{font-family:'Roboto';font-style:normal;font-weight:500;font-display:swap;src:url('fonts/roboto-v32-latin-500.woff2') format('woff2')}
@font-face{font-family:'Roboto';font-style:normal;font-weight:700;font-display:swap;src:url('fonts/roboto-v32-latin-700.woff2') format('woff2')}
@font-face{font-family:'Roboto Mono';font-weight:300;font-display:swap;src:url('fonts/roboto-mono-300.woff2') format('woff2')}
@font-face{font-family:'Roboto Mono';font-weight:400;font-display:swap;src:url('fonts/roboto-mono-400.woff2') format('woff2')}
/* TROTZDEM · Horizont – gemeinsame Tokens, Nav, Buttons, Footer, Motion-Basis
   Quelle der Tokens: docs/research/redesign-trotzdem-works/bestand.md §10 */
@property --a { syntax:'<angle>'; inherits:false; initial-value:0deg; }
/* Szenenfortschritt. Registriert, damit er per Scroll-Timeline interpoliert werden kann. */
@property --p { syntax:'<number>'; inherits:true; initial-value:0; }
@property --pp { syntax:'<number>'; inherits:true; initial-value:0; }
:root{
  --blue:#00509d; --blue-d:#03264d; --blue-x:#020f22;
  /* Ableitungen für Text auf Tiefblau (Logo-Farben sind auf dunklem Grund nicht lesbar) */
  --sky:#6fb1ff; --green:#57c877; --yellow:#ffc300; --red:#e0524f;
  --logo-blue:#00509d; --logo-green:#2b9348; --logo-yellow:#ffc300; --logo-red:#a70b0b;
  --txt:#eef3fa; --muted:#8fa6c2; --line:rgba(255,255,255,.1);
  --font-h:'Raleway',system-ui,sans-serif; --font-b:'Roboto',system-ui,sans-serif; --font-m:'Roboto Mono',monospace;
  --ease:cubic-bezier(.2,.7,.2,1);
  --nav-h:88px;
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{margin:0;background:var(--blue-x);color:var(--txt);font-family:var(--font-b);font-weight:300;line-height:1.65;overflow-x:hidden}
a{color:inherit;text-decoration:none}
img{max-width:100%}
h1,h2,h3{font-family:var(--font-h);margin:0;line-height:1;letter-spacing:-.03em;font-weight:200}
h1 b,h2 b,h3 b{font-weight:700}
.wrap{width:min(1320px,calc(100% - 96px));margin:0 auto}
.mono{font-family:var(--font-m);font-size:12px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
main,header,footer{position:relative;z-index:1}
main{overflow-x:clip}

/* Atmosphäre */
.sky{position:fixed;inset:0;z-index:0;pointer-events:none;background:radial-gradient(1200px 800px at 70% -10%,rgba(0,80,157,.55),transparent 60%),radial-gradient(900px 600px at 10% 110%,rgba(0,80,157,.35),transparent 60%),var(--blue-x)}
.sky::after{content:"";position:absolute;inset:0;opacity:.05;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* Buttons: Sekundär = Liquid Fill, Primär (.btn-fill) = Border Beam + Hover-Glow */
.btn{display:inline-flex;align-items:center;gap:12px;padding:16px 26px;border-radius:999px;font-family:var(--font-h);font-weight:700;font-size:14px;letter-spacing:.06em;text-transform:uppercase;border:1px solid var(--sky);color:var(--sky);position:relative;isolation:isolate;overflow:hidden;cursor:pointer;background:transparent;transition:color .4s var(--ease),transform .35s var(--ease),box-shadow .35s}
.btn::before{content:"";position:absolute;left:-10%;right:-10%;bottom:-10%;height:0;background:var(--sky);border-radius:45% 45% 0 0;transition:height .55s var(--ease),border-radius .55s;z-index:-1}
.btn:hover{color:var(--blue-x)}
.btn:hover::before{height:130%;border-radius:0}
.btn-fill{background:rgba(255,255,255,.04);border-color:transparent;color:#fff;padding:18px 30px}
/* Ring exakt in der Knopfkontur (inset 0): mit -1px lag er teils außerhalb und wurde vom overflow:hidden des Knopfs an den Ecken weggeschnitten – der Beam fehlte dann unten rechts. */
.btn-fill::before{left:0;right:0;top:0;bottom:0;height:auto;border-radius:inherit;padding:1.5px;background:conic-gradient(from var(--a),transparent 0 70%,var(--sky) 85%,#fff 92%,transparent 100%);-webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude;animation:beam 2.4s linear infinite;transition:none}
.btn-fill::after{content:"";position:absolute;inset:0;border-radius:inherit;border:1px solid var(--line);z-index:-2;transition:background .4s}
@keyframes beam{to{--a:360deg}}
.btn-fill:hover{color:#fff;transform:translateY(-2px);box-shadow:0 0 0 5px rgba(111,177,255,.14),0 18px 44px -16px rgba(111,177,255,.85)}
.btn-fill:hover::before{height:auto}
.btn-fill:hover::after{background:rgba(111,177,255,.14)}
.btn[disabled],.btn.is-busy{opacity:.6;pointer-events:none}

/* Wortmarke: offizielles Logo-SVG (assets/logo-white.svg, aus dem Design System) */
.wordmark-img{height:22px;width:auto;display:block}
.wordmark-img.sm{height:18px;margin-bottom:16px}

/* Nur für Screenreader: aus dem Bild genommen, aber im Zugänglichkeitsbaum.
   "display:none"/"visibility:hidden" wäre falsch – das entfernt das Element. */
.hz-vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* Sprungmarke „Zum Inhalt": erstes Element im <body>, per Tastatur erreichbar,
   sonst außerhalb des Viewports. Kein "display:none"/"visibility:hidden" –
   das nimmt das Element aus der Tabreihenfolge. */
.hz-skip{position:fixed;left:16px;top:-120px;z-index:60;padding:14px 22px;border-radius:999px;background:var(--sky);color:var(--blue-x);font-family:var(--font-h);font-weight:700;font-size:13px;letter-spacing:.08em;text-transform:uppercase;transition:top .2s var(--ease)}
.hz-skip:focus{top:16px;outline:2px solid #fff;outline-offset:2px}

/* Nav */
.nav{position:fixed;top:0;left:0;right:0;z-index:50;transition:background .4s,border-color .4s;border-bottom:1px solid transparent}
.nav.scrolled,.nav.open{background:rgba(2,15,34,.82);backdrop-filter:blur(16px);border-color:var(--line)}
.nav .wrap{display:flex;align-items:center;justify-content:space-between;height:var(--nav-h);transition:height .4s var(--ease)}
.nav.scrolled .wrap{height:72px}
.logo{display:block}
.nav ul{display:flex;gap:36px;list-style:none;margin:0;padding:0;font-family:var(--font-h);font-weight:600;font-size:13px;letter-spacing:.1em;text-transform:uppercase}
.nav ul a{color:var(--muted);transition:color .3s;position:relative;padding:6px 0}
.nav ul a::after{content:"";position:absolute;left:0;right:0;bottom:0;height:1px;background:var(--sky);transform:scaleX(0);transform-origin:left;transition:transform .4s var(--ease)}
.nav ul a:hover,.nav ul a.active{color:#fff}
.nav ul a:hover::after,.nav ul a.active::after{transform:scaleX(1)}
/* Untermenü (Navigationsmodul mit zwei Ebenen): Dropdown unter dem Hauptpunkt,
   per Hover und per Tastatur (focus-within). Das li bekommt vertikales Padding,
   damit die Maus auf dem Weg nach unten nicht aus dem Hover fällt. */
.nav ul li{position:relative;padding:18px 0}
.nav ul .level_2{position:absolute;top:100%;left:-14px;min-width:260px;margin:-6px 0 0;padding:8px;display:grid;gap:2px;background:rgba(2,15,34,.94);backdrop-filter:blur(16px);border:1px solid var(--line);border-radius:8px;box-shadow:0 24px 60px -24px rgba(0,0,0,.8);opacity:0;transform:translateY(8px);pointer-events:none;transition:opacity .3s var(--ease),transform .3s var(--ease)}
.nav ul li:hover>.level_2,.nav ul li:focus-within>.level_2{opacity:1;transform:none;pointer-events:auto}
.nav ul .level_2 li{padding:0}
.nav ul .level_2 a{display:block;padding:10px 14px;border-radius:6px;text-transform:none;letter-spacing:0;font-size:14px;font-weight:500;color:var(--txt);transition:background .25s,color .25s}
.nav ul .level_2 a::after{display:none}
.nav ul .level_2 a:hover,.nav ul .level_2 a.active{background:rgba(111,177,255,.12);color:#fff}
.nav ul li.has-sub>a::before{content:"";display:inline-block;width:5px;height:5px;border-right:1px solid currentColor;border-bottom:1px solid currentColor;transform:rotate(45deg);margin:0 8px 3px 0;opacity:.6}
.mobile-menu .level_2{margin:2px 0 8px;display:grid;grid-template-columns:1fr 1fr;column-gap:12px}
.mobile-menu .level_2 a{font-size:17px;font-weight:400;line-height:1.3;padding:4px 0 4px 18px;border-bottom:none;color:var(--muted)}
.mobile-menu .level_2 a::before{content:"– ";color:var(--sky)}
/* Pill für externe Angebote in der Nav (Seiten-CSS-Klasse "pill", z. B. „KI lernen" → kapiert.trotzdem.works) */
.nav ul a.pill{border:1px solid var(--line);border-radius:999px;padding:9px 16px;color:#fff;transition:border-color .3s,background .3s}
.nav ul a.pill::after{display:none}
.nav ul a.pill:hover{border-color:var(--sky);background:rgba(111,177,255,.1)}
.nav ul a.pill span{color:var(--sky);margin-left:6px}
.mobile-menu a.pill span{color:var(--sky);margin-left:8px;font-size:.6em;vertical-align:middle}
.burger{display:none;width:44px;height:44px;border:1px solid var(--line);border-radius:50%;background:transparent;cursor:pointer;position:relative}
.burger i{position:absolute;left:13px;right:13px;height:1.5px;background:#fff;top:50%;transition:transform .4s var(--ease),opacity .3s}
.burger i:first-child{transform:translateY(-5px)}.burger i:last-child{transform:translateY(4px)}
.nav.open .burger i:first-child{transform:rotate(45deg)}.nav.open .burger i:last-child{transform:rotate(-45deg)}
.mobile-menu{display:none}

/* Seitenkopf für Unterseiten */
.page-head{padding:calc(var(--nav-h) + 96px) 0 72px;position:relative}
.page-head h1{font-size:clamp(56px,8.5vw,140px);letter-spacing:-.045em;line-height:.92}
.page-head .lead{font-size:20px;color:var(--muted);max-width:640px;margin:32px 0 0}
/* Der Lead kommt aus einem Rich-Text-Feld (TinyMCE) und enthält deshalb <p>.
   Ohne Reset addiert sich dessen Standardabstand (1em oben/unten) auf den
   Abstand des Containers. Gilt für beide Lead-Stellen: ".page-head .lead"
   und ".svc .lead" (hz_service_block). */
.lead>p{margin:0}
.lead>p+p{margin-top:.8em}
.page-head .mono{margin-bottom:24px;display:block}
.crumbs{display:flex;gap:10px;align-items:center}
.crumbs a:hover{color:#fff}

/* Footer */
footer{border-top:1px solid var(--line);padding:56px 0 40px;color:var(--muted);font-size:14px}
footer .cols{display:grid;grid-template-columns:2fr 1fr 1fr 1fr;gap:32px}
footer b{color:#fff;font-family:var(--font-h);display:block;margin-bottom:14px}
footer ul{list-style:none;margin:0;padding:0;display:grid;gap:8px}
footer a:hover{color:#fff}
footer .bottom{display:flex;justify-content:space-between;margin-top:48px;padding-top:24px;border-top:1px solid var(--line);font-size:12px;gap:16px;flex-wrap:wrap}

/* Motion-Basis (scrollfx.js)

   Der Startzustand hängt an ".js": die Klasse setzt das Inline-Script im
   <head> des Seitenlayouts anstelle von "no-js". Ohne JavaScript – deaktiviert,
   Ladefehler, Textbrowser – bleibt ".no-js" stehen, die Regeln greifen nicht
   und der Inhalt steht sofort sichtbar da. Sonst blieben Überschriften,
   Absätze und ganze Sektionen dauerhaft auf opacity:0, weil nur scrollfx.js
   ".is-visible" nachträgt. Die Sichtbar-Regeln selbst sind bewusst NICHT
   gescopt: sie schaden ohne den Startzustand nicht. */
.js [data-reveal]{opacity:0;transform:translateY(24px);transition:opacity .9s var(--ease) calc(var(--d,0) * 1ms),transform .9s var(--ease) calc(var(--d,0) * 1ms)}
[data-reveal].is-visible{opacity:1;transform:none}
.js .fx-word{display:inline-block;opacity:0;transform:translateY(.4em);filter:blur(6px);transition:opacity .7s var(--ease) calc(var(--i) * 80ms),transform .7s var(--ease) calc(var(--i) * 80ms),filter .7s var(--ease) calc(var(--i) * 80ms)}
.is-visible .fx-word{opacity:1;transform:none;filter:none}
@keyframes spin{to{transform:rotate(360deg)}}

/* Bildstil „Natur + Objekt" (docs/specs/bildstil-natur-objekt.md) im Horizont-Look:
   Foto behält seine Farbe, wird leicht entsättigt und kühl in Richtung Tiefblau gelegt,
   unten in den Hintergrund verlaufend, feines Korn. Hover löst die Behandlung auf. */
.pic{position:relative;overflow:hidden;border-radius:6px;background:var(--blue-d);isolation:isolate}
.pic img{display:block;width:100%;height:100%;object-fit:cover;filter:saturate(.8) contrast(1.05) brightness(.92);transition:filter .8s var(--ease),transform 1.4s var(--ease)}
.pic::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(0,80,157,.18),rgba(2,15,34,.05) 40%,rgba(2,15,34,.85) 100%);mix-blend-mode:multiply;transition:opacity .8s}
.pic::after{content:"";position:absolute;inset:0;z-index:2;opacity:.12;pointer-events:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence baseFrequency='.8' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}
.pic.tint::before{background:linear-gradient(180deg,rgba(0,80,157,.45),rgba(2,15,34,.35) 50%,rgba(2,15,34,.9) 100%)}
a:hover .pic img,.pic:hover img{filter:saturate(1) contrast(1) brightness(1);transform:scale(1.04)}
a:hover .pic::before,.pic:hover::before{opacity:.6}

/* CTA-Band (auf allen Unterseiten) */
.cta-band{padding:120px 0}
.cta-band .inner{border-top:1px solid var(--line);padding-top:56px;display:grid;grid-template-columns:1.4fr 1fr;gap:48px;align-items:end}
.cta-band h2{font-size:clamp(44px,6vw,96px);letter-spacing:-.045em;line-height:.92}
.cta-band .side{display:grid;gap:16px;justify-items:start}

@media (prefers-reduced-motion: reduce){
  /* Spezifitaet mit ".js" davor, sonst gewinnt der Startzustand oben. */
  .js [data-reveal],.js .fx-word,[data-reveal],.fx-word{opacity:1;transform:none;filter:none;transition:none}
  .btn-fill::before{animation:none}
  *{animation-duration:0s !important}
}

/* Responsive Basis */
@media (max-width:1100px){
  .wrap{width:min(1320px,calc(100% - 48px))}
  .nav ul{display:none}
  .burger{display:block}
  .nav .cta-nav{display:none}
  /* Scrollbar in sich (overflow-y), weil site.js beim Öffnen das Scrollen der Seite sperrt; kompakter, damit Haupt- und Unterpunkte auf gängigen Handys ohne Scrollen passen. */
.mobile-menu{display:block;position:fixed;inset:0;top:0;z-index:49;background:rgba(2,15,34,.96);backdrop-filter:blur(20px);padding:calc(var(--nav-h) + 8px) 24px 32px;overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;transform:translateY(-8px);opacity:0;pointer-events:none;transition:opacity .4s var(--ease),transform .4s var(--ease)}
  .mobile-menu.open{opacity:1;transform:none;pointer-events:auto}
  .mobile-menu a{display:block;font-family:var(--font-h);font-weight:200;font-size:clamp(26px,6.5vw,36px);letter-spacing:-.03em;line-height:1.2;padding:9px 0;border-bottom:1px solid var(--line);opacity:0;transform:translateY(12px);transition:opacity .5s var(--ease) calc(var(--i,0) * 60ms),transform .5s var(--ease) calc(var(--i,0) * 60ms)}
  .mobile-menu.open a{opacity:1;transform:none}
  .mobile-menu .btn{display:inline-flex;font-size:14px;font-weight:700;margin-top:20px;padding:16px 26px;letter-spacing:.06em;border-bottom:none;opacity:1;transform:none}
  .mobile-menu .btn-fill{border-bottom:none}
  .cta-band .inner{grid-template-columns:1fr}
  footer .cols{grid-template-columns:1fr 1fr}
}
@media (max-width:640px){
  :root{--nav-h:72px}
  .wrap{width:min(1320px,calc(100% - 40px))}
  .page-head{padding-top:calc(var(--nav-h) + 56px)}
  .btn{padding:14px 20px;font-size:13px}
  footer .cols{grid-template-columns:1fr}
}


/* ===== Seiten- und Szenen-Styles (aus den Horizont-Seiten) ===== */

/* --- index.html --- */
/* hero */
.hero{min-height:100vh;display:grid;align-content:end;padding:120px 0 64px;position:relative}
.hero .coords{position:absolute;top:120px;left:0;display:grid;gap:6px}
.hero h1{font-size:clamp(64px,12vw,196px);letter-spacing:-.05em;line-height:.9}
.hero h1 b{display:block}
/* Ring: Wrapper trägt Position + Parallax (scrollfx setzt transform), das Bild dreht sich; `translate` bleibt vom Parallax unberührt */
.hero .ringbg{position:absolute;right:-8%;top:50%;width:min(56vw,760px);translate:0 -50%;opacity:.14;filter:blur(1px);pointer-events:none}
.hero .ringbg img{display:block;width:100%;height:auto;animation:spin 90s linear infinite}
}
.hero .bottom{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:end;margin-top:48px;border-top:1px solid var(--line);padding-top:32px}
.hero .bottom p{font-size:20px;color:var(--muted);max-width:520px;margin:0}
.hero .bottom .cta{display:flex;gap:14px;justify-content:flex-end;flex-wrap:wrap}

/* horizontale Szene */
.scene{height:420vh;position:relative}
/* 100svh statt 100vh: die kleine Viewport-Höhe bleibt beim Ein-/Ausblenden der mobilen Browserleiste konstant – 100vh (bzw. dvh) würde die Bühne bei jedem Umschalten neu messen und zittern lassen. */
.scene .stage{position:sticky;top:0;height:100vh;height:100svh;overflow:hidden;display:flex;align-items:center}
/* --n = Anzahl Panels (inline vom Template gesetzt), --pp = geglätteter Fortschritt aus site.js */
.track{display:flex;width:calc(var(--n,4) * 100vw);transform:translate3d(calc(var(--pp,var(--p,0)) * (var(--n,4) - 1) * -100vw),0,0);will-change:transform}
.panel{width:100vw;height:100vh;height:100svh;display:grid;grid-template-columns:1fr 1fr;align-items:center;padding:0 clamp(48px,7vw,120px);gap:48px;position:relative;flex:none}
.panel .big{font-family:var(--font-h);font-weight:200;font-size:clamp(160px,28vw,420px);line-height:.8;letter-spacing:-.06em;color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.35);transform:translateX(calc((var(--pp,var(--p,0)) * (var(--n,4) - 1) - var(--i,0)) * -60px))}
.panel .big b{font-weight:200;color:var(--c);-webkit-text-stroke:0}
.panel h3{font-size:clamp(40px,5vw,80px);font-weight:300}
.panel h3 b{color:var(--c)}
.panel p{font-size:19px;color:var(--muted);max-width:480px;margin:24px 0 32px}
.panel .line{width:120px;height:2px;background:var(--c);margin-bottom:24px}
.scene .hud{position:absolute;left:0;right:0;bottom:36px;display:flex;justify-content:space-between;padding:0 clamp(48px,7vw,120px);pointer-events:none}
.scene .hud .bar{width:320px;height:1px;background:var(--line);position:relative;align-self:center}
.scene .hud .bar i{position:absolute;left:0;top:-1px;height:3px;background:#fff;width:calc(var(--p,0) * 100%)}

/* Strike-Szene (aus Klartext) */
.strike{height:300vh;position:relative}
.strike .stage{position:sticky;top:0;height:100vh;height:100svh;display:grid;place-items:center;overflow:hidden}
.strike .txt{font-family:var(--font-h);font-size:clamp(44px,8.5vw,140px);font-weight:200;letter-spacing:-.045em;line-height:1;text-align:center;padding:0 20px}
.strike .l1{display:block;transform:translateY(calc(var(--p,0) * -12px))}
.strike .l2{display:block;position:relative;color:var(--muted)}
.strike .l2::after{content:"";position:absolute;left:0;top:52%;height:.08em;background:var(--yellow);width:calc(clamp(0,(var(--p,0) - .15) * 2.5,1) * 100%);box-shadow:0 0 24px rgba(255,195,0,.5)}
.strike .l3{display:block;font-weight:700;color:#fff;clip-path:inset(0 calc((1 - clamp(0,(var(--p,0) - .55) * 3,1)) * 100%) 0 0)}
.strike .l3{font-size:.86em}
.strike .l3 .wm{height:.62em;width:auto;display:inline-block;vertical-align:-.06em;margin-right:.12em}
.strike .l3 .cur{display:inline-block;width:.06em;height:.9em;background:var(--sky);vertical-align:-.1em;margin-left:.05em;opacity:calc(1 - clamp(0,(var(--p,0) - .9) * 10,1))}
.strike .glow{position:absolute;left:50%;top:50%;width:900px;height:900px;transform:translate(-50%,-50%) scale(calc(.6 + var(--p,0) * .6));border-radius:50%;background:radial-gradient(circle,rgba(0,80,157,.45),transparent 60%);pointer-events:none;opacity:calc(var(--p,0))}
.strike .mono{position:absolute;bottom:40px;left:50%;transform:translateX(-50%);opacity:calc(1 - var(--p,0))}

/* Scroll-getriebener Fortschritt ohne JavaScript (Safari 26+, Chrome 115+).
   -----------------------------------------------------------------------
   Ursache des Zitterns auf dem iPhone: iOS positioniert die Sticky-Bühne im
   Compositor sofort, das Scroll-Event – und damit scrollfx.js/site.js, die
   --p/--pp setzen – läuft ein bis mehrere Frames hinterher. Der Track wird
   jeden Frame gegen eine schon veraltete Scrollposition verschoben.
   Mit einer View-Timeline schreibt der Browser --p/--pp selbst, synchron zum
   Frame. "contain" = genau die Strecke, in der die Bühne klebt (Szenenoberkante
   am Viewportrand bis Szenenunterkante am Viewportrand). scrollfx.js/site.js
   erkennen die Unterstützung (CSS.supports) und lassen die Variablen dann in
   Ruhe; ohne Unterstützung bleibt der bisherige JS-Weg. */
@supports (animation-timeline: view()) {
  .scene,.strike,.ringscene,.creed{animation:hz-progress linear both;animation-timeline:view();animation-range:contain 0% contain 100%}
  .scene{view-timeline:--hz-scene block}
  /* Haltephasen wie im JS-Easing: pro Panel ~50 % Halt, dann Fahrt. */
  .track[data-hz-panels="4"]{animation:hz-track-4 linear both;animation-timeline:--hz-scene;animation-range:contain 0% contain 100%}
  @keyframes hz-progress{from{--p:0}to{--p:1}}
  @keyframes hz-track-4{0%,17%{--pp:0}33%,50%{--pp:.3333}67%,83%{--pp:.6667}100%{--pp:1}}
  @media (prefers-reduced-motion: reduce){
    .scene,.strike,.ringscene,.creed,.track[data-hz-panels="4"]{animation:none}
  }
}

/* Statement */
.statement{padding:200px 0;text-align:center}
.statement h2{font-size:clamp(36px,6vw,96px);max-width:1100px;margin:0 auto}
.statement .sub p{font-size:22px;color:var(--muted);max-width:720px;margin:32px auto 0}

/* Team */
.team{padding:80px 0 180px}
.team .grid{display:grid;grid-template-columns:1fr 1fr;gap:32px;margin-top:64px}
.duo::before{content:"";position:absolute;inset:0;background:linear-gradient(160deg,var(--blue) 0%,var(--blue-d) 100%);z-index:0}
.duo img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover;object-position:center 15%;filter:grayscale(1) contrast(1.1);mix-blend-mode:luminosity;opacity:.85;transition:transform 1.2s var(--ease),filter .8s,opacity .8s}
.duo:hover img{transform:scale(1.03);filter:grayscale(0);mix-blend-mode:normal;opacity:1}
.duo .cap{position:absolute;z-index:2;left:24px;bottom:24px;font-family:var(--font-h)}
.duo .cap b{font-size:32px;font-weight:600;display:block}
.duo .cap span{color:var(--muted);font-size:13px;letter-spacing:.1em;text-transform:uppercase}
.team h2{font-size:clamp(40px,5vw,72px)}

/* Insights */
.insights{padding:0 0 160px}
.insights .head{display:flex;justify-content:space-between;align-items:end;margin-bottom:40px;gap:24px;flex-wrap:wrap}
.insights h2{font-size:clamp(40px,5vw,72px)}
.cards{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.cardx{border:1px solid var(--line);border-radius:6px;padding:0 0 28px;min-height:300px;display:flex;flex-direction:column;justify-content:space-between;gap:20px;overflow:hidden;background:linear-gradient(180deg,rgba(255,255,255,.03),transparent);transition:transform .5s var(--ease),border-color .4s,background .4s}
.cardx:hover{transform:translateY(-8px);border-color:var(--sky);background:rgba(0,80,157,.2)}
.cardx h3{font-size:24px;font-weight:600;line-height:1.2;margin:14px 28px 0}
.cardx .pic{aspect-ratio:16/9;border-radius:0}
.cardx .mono,.cardx .go{margin:0 28px}
.cardx .go{font-family:var(--font-h);font-weight:600;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--sky)}

/* Toolbox */
.tools{padding:0 0 160px}
/* auto-fit: zwei Karten füllen die Breite, drei Karten (Timer, Check-in, KI lernen) stehen nebeneinander, auf dem Handy untereinander */
.tools .row{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,340px),1fr));gap:20px;margin-top:48px}
.toolx{border:1px solid var(--line);border-radius:6px;padding:40px;position:relative;overflow:hidden;min-height:280px;display:flex;flex-direction:column;justify-content:space-between}
.toolx h3{font-size:34px;font-weight:600}
.toolx p{color:var(--muted);max-width:420px}
.toolx .num{font-family:var(--font-m);font-size:48px;color:var(--c);font-weight:300;font-variant-numeric:tabular-nums}
.toolx .cfg{display:flex;gap:18px;margin-top:8px;flex-wrap:wrap}
.toolx .cfg b{color:#fff;font-weight:400}
.toolx .bar{height:2px;background:var(--line);margin-top:18px;overflow:hidden}
.toolx .bar i{display:block;height:100%;background:var(--c);width:0;animation:fill 60s linear infinite}
@keyframes fill{to{width:100%}}
.toolx::after{content:"";position:absolute;right:-60px;top:-60px;width:260px;height:260px;border-radius:50%;border:1px solid var(--c);opacity:.35}

/* Kontakt */
.contact{padding:120px 0 160px}
.contact .inner{border-top:1px solid var(--line);padding-top:64px;display:grid;grid-template-columns:1.4fr 1fr;gap:48px;align-items:end}
.contact h2{font-size:clamp(48px,8vw,140px);letter-spacing:-.05em;line-height:.9}
.contact .side{display:grid;gap:18px;justify-items:start}
.contact .mail{font-family:var(--font-h);font-size:clamp(20px,2.4vw,32px);font-weight:600;border-bottom:1px solid var(--sky);padding-bottom:4px}
.contact .mail:hover{color:var(--sky)}

@media (max-width:1100px){
  .hero .bottom,.team .grid,.tools .row,.contact .inner{grid-template-columns:1fr}
  .hero .bottom .cta{justify-content:flex-start}
  .cards{grid-template-columns:1fr}
  .panel{grid-template-columns:1fr;align-content:center;gap:16px;padding-top:80px}
  .panel .big{font-size:clamp(120px,30vw,200px);order:-1}
  .scene .hud .bar{width:120px}
  .duo{aspect-ratio:4/5}
  .team .grid a:last-child{margin-top:0 !important}
}
@media (max-width:640px){
  .hero{padding-top:100px}
  .hero .coords{top:96px}
  .hero .ringbg{width:90vw;right:-30%}
  .scene{height:360vh}
  .panel p{font-size:16px}
  .toolx{padding:28px}
  .toolx .num{font-size:36px}
}

/* --- dienstleistungen.html --- */
/* Ring-Szene (aus Kreislauf, im Horizont-Look) */
.ringscene{height:380vh;position:relative}
.ringscene .stage{position:sticky;top:0;height:100vh;display:grid;grid-template-columns:1fr 1fr;align-items:center;gap:60px;overflow:hidden;padding-top:var(--nav-h)}
.ringwrap{display:grid;place-items:center;position:relative}
/* Kein drop-shadow auf dem gedrehten SVG: der Filter wird auf der rechteckigen
   Ebene des Elements gerendert und zeichnete ein mitdrehendes, leicht helles
   Rechteck um den Ring (sichtbar auf Stage, 05.09.2026). Das Leuchten kommt
   stattdessen als runder Verlauf hinter dem Ring, der nicht mitdreht. */
.ringwrap::before{content:"";position:absolute;width:min(90%,560px);aspect-ratio:1;border-radius:50%;background:radial-gradient(circle,rgba(0,80,157,.45) 0%,rgba(0,80,157,.18) 45%,transparent 70%);pointer-events:none}
/* viewBox mit 20 Einheiten Rand (Template) und overflow:visible: der Schatten des
   aktiven Segments (.seg.on) wurde sonst an der Kante der SVG-Zeichenfläche
   abgeschnitten – eine gerade Linie im Leuchten. Die Breite ist um den Rand
   vergrößert, damit der Ring selbst gleich groß bleibt. */
.ringwrap svg{width:min(100%,720px);overflow:visible;transform:rotate(calc(var(--p,0) * 360deg));position:relative}
.ringwrap .seg.on{filter:drop-shadow(0 0 18px currentColor)}
.seg-blue{color:var(--sky)}.seg-green{color:var(--green)}.seg-yellow{color:var(--yellow)}.seg-red{color:var(--red)}
.ringwrap .seg{opacity:.3;transition:opacity .35s}
.ringwrap .seg.on{opacity:1}
.ringwrap .label{position:absolute;text-align:center;font-family:var(--font-h)}
.ringwrap .label .num{font-size:80px;font-weight:200;font-variant-numeric:tabular-nums;line-height:1}
.steps{display:grid;gap:6px}
.step{padding:22px 26px;border-radius:6px;border:1px solid transparent;transition:all .5s var(--ease)}
.step .k{display:flex;gap:12px;align-items:center}
.step .k i{width:10px;height:10px;border-radius:50%;background:var(--c)}
.step h3{font-size:clamp(26px,3vw,40px);font-weight:600;margin:8px 0}
.step p{margin:0;color:var(--muted);max-height:0;overflow:hidden;opacity:0;transition:max-height .6s var(--ease),opacity .4s}
.step.on{border-color:var(--line);background:rgba(255,255,255,.03)}
.step.on h3{color:var(--c)}
.step.on p{max-height:140px;opacity:1}
.step:not(.on) h3{opacity:.35}
.ringscene .progress{position:absolute;left:0;bottom:0;height:2px;background:linear-gradient(90deg,var(--sky),var(--green),var(--yellow),var(--red));width:calc(var(--p,0) * 100%)}

/* Detailblöcke */
.svc{padding:140px 0;border-top:1px solid var(--line);display:grid;grid-template-columns:.9fr 1.1fr;gap:64px;align-items:start;scroll-margin-top:80px}
.svc .num{font-family:var(--font-h);font-weight:200;font-size:clamp(120px,16vw,240px);line-height:.8;letter-spacing:-.06em;color:transparent;-webkit-text-stroke:1px rgba(255,255,255,.3);position:sticky;top:120px}
.svc .num b{font-weight:200;color:var(--c);-webkit-text-stroke:0}
.svc h2{font-size:clamp(40px,5vw,72px)}
.svc h2 b{color:var(--c)}
.svc .lead{font-size:20px;color:var(--muted);max-width:560px;margin:24px 0 40px}
.svc ul{list-style:none;margin:0;padding:0;display:grid;gap:0;border-top:1px solid var(--line)}
.svc li{padding:22px 0;border-bottom:1px solid var(--line);display:grid;grid-template-columns:40px 1fr;gap:16px;align-items:start}
.svc li i{width:10px;height:10px;border-radius:50%;background:var(--c);margin-top:10px}
.svc li b{font-family:var(--font-h);font-weight:600;font-size:20px;display:block}
.svc li span{color:var(--muted);font-size:15px}
.svc .btn{margin-top:36px}

@media (max-width:1100px){
  .ringscene{height:300vh}
  .ringscene .stage{grid-template-columns:1fr;gap:16px;align-content:center}
  .ringwrap svg{width:min(77vw,412px)}
  .ringwrap .label .num{font-size:48px}
  .step{padding:12px 16px}.step h3{font-size:22px;margin:4px 0}
  .step.on p{max-height:120px}
  .svc{grid-template-columns:1fr;gap:16px;padding:96px 0}
  .svc .num{position:static;font-size:96px}
}

/* --- kontakt.html --- */
.page-head{overflow:visible;padding-bottom:40px}
.page-head .ringbg{position:absolute;right:-6%;top:40%;width:min(46vw,620px);opacity:.14;animation:spin 70s linear infinite reverse;pointer-events:none;z-index:-1}
.page-head h1{font-size:clamp(52px,8vw,132px)}
/* Der Kontaktabschnitt ist das Raster selbst (Formularspalte + Infospalte).
   Die Klasse ist bewusst eigen benannt: eine ungescopte ".grid"-Regel traf
   sonst auch das Werte-Raster der Ueber-uns-Seite. */
.hz-contact{display:grid;grid-template-columns:1.1fr .9fr;gap:64px;padding:40px 0 140px;align-items:start}

/* Formular */
.form{border:1px solid var(--line);border-radius:8px;padding:40px;background:linear-gradient(180deg,rgba(255,255,255,.03),transparent);position:relative;overflow:hidden}
.field{display:grid;gap:8px;margin-bottom:22px;position:relative}
.field label{font-family:var(--font-h);font-weight:600;font-size:13px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);display:flex;justify-content:space-between}
.field label small{font-weight:400;text-transform:none;letter-spacing:0;font-family:var(--font-b);font-size:12px}
.field input,.field textarea{width:100%;background:rgba(2,15,34,.6);border:1px solid var(--line);border-radius:4px;color:#fff;font:inherit;font-size:16px;padding:16px 18px;outline:none;transition:border-color .3s,box-shadow .3s}
.field input:focus,.field textarea:focus{border-color:var(--sky);box-shadow:0 0 0 4px rgba(111,177,255,.12)}
.field textarea{min-height:160px;resize:vertical}
.field .err{font-size:13px;color:var(--red);display:none}
.field.invalid input,.field.invalid textarea{border-color:var(--red)}
.field.invalid .err{display:block}
.check{display:flex;gap:14px;align-items:start;font-size:14px;color:var(--muted);margin:8px 0 28px;cursor:pointer}
.check input{width:20px;height:20px;margin-top:2px;accent-color:var(--sky);flex:none}
/* Link in der Einverstaendnis-Zeile (Datenschutz). Im Entwurf steht dafuer ein
   style-Attribut im Markup - als Klasse gepflegt, damit der Optionstext im
   Backend ohne Inline-Style auskommt. */
.check a{text-decoration:underline}
.check.invalid{color:var(--red)}
/* Die Checkbox liegt in einem ".field"-Wrapper, damit die Fehlerregeln
   (".field .err") greifen; die Abstaende bleiben beim ".check" des Entwurfs. */
/* Wrapper der Einverstaendnis-Zeile. Bewusst NICHT ".field": ".field label"
   setzt jedes Label darin in Mono-Versalien - der Fliesstext der Checkbox ist
   aber selbst ein <label>. Die drei Fehlerregeln entsprechen denen von
   ".field", der Abstand nach unten bleibt beim ".check" des Entwurfs. */
.check-field{display:grid;gap:8px;margin-bottom:28px}
.check-field .check{margin:8px 0 0}
.check-field .err{font-size:13px;color:var(--red);display:none}
.check-field.invalid .err{display:block}
.form .actions{display:flex;gap:16px;align-items:center;flex-wrap:wrap}
.form .hint{font-size:13px;color:var(--muted)}
.state{position:absolute;inset:0;display:grid;place-items:center;text-align:center;padding:40px;background:rgba(2,15,34,.96);opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}
.state.show{opacity:1;pointer-events:auto}
.state h3{font-size:clamp(32px,4vw,52px);margin:20px 0 12px}
.state p{color:var(--muted);max-width:420px;margin:0 auto 28px}
.state .ic{width:72px;height:72px;border-radius:50%;display:grid;place-items:center;font-size:30px;margin:0 auto;border:1px solid var(--line)}
.state.ok .ic{background:rgba(87,200,119,.15);color:var(--green);border-color:var(--green)}
.state.fail .ic{background:rgba(224,82,79,.15);color:var(--red);border-color:var(--red)}

/* Info */
.info{display:grid;gap:0}
.info .block{padding:28px 0;border-top:1px solid var(--line)}
.info .block:first-child{border-top:none;padding-top:0}
.info b{font-family:var(--font-h);font-weight:600;font-size:22px;display:block;margin-bottom:8px}
.info a.big{font-family:var(--font-h);font-size:clamp(22px,2.6vw,34px);font-weight:600;border-bottom:1px solid var(--sky);padding-bottom:2px;transition:color .3s}
.info a.big:hover{color:var(--sky)}
.info .muted{color:var(--muted)}
.info .row{display:flex;gap:24px;flex-wrap:wrap;margin-top:8px}
/* Im Entwurf stehen an diesen beiden Stellen style-Attribute im Markup
   (margin-top:14px unter der grossen Mailadresse, display:block/margin-top:10px
   vor den Koordinaten). Als Regeln gepflegt, damit die Infobloecke im Backend
   ohne Inline-Styles auskommen. */
.info a.big + .row{margin-top:14px}
.info .muted + .mono{display:block;margin-top:10px}
.info .row a:hover{color:#fff}
.hz-contact .chips{display:flex;gap:10px;flex-wrap:wrap;margin-top:14px}
.hz-contact .chip{font-family:var(--font-m);font-size:12px;letter-spacing:.1em;text-transform:uppercase;padding:8px 12px;border:1px solid var(--line);border-radius:999px;color:var(--muted)}
/* Farbige Chips: im Entwurf per style-Attribut, hier als Klasse - damit der
   Redakteur im Backend kein style schreiben muss und keine Inline-Styles
   entstehen. Praefix "chip-", NICHT die blossen Farbnamen: ".sky" ist in
   dieser Datei bereits die fixierte Hintergrundflaeche (Zeile 29) - ein
   <span class="chip sky"> wuerde daraus ein bildschirmfuellendes Overlay
   machen und die halbe Seite verdecken. */
.hz-contact .chip.chip-sky{color:var(--sky)}
.hz-contact .chip.chip-green{color:var(--green)}
.hz-contact .chip.chip-yellow{color:var(--yellow)}
.hz-contact .chip.chip-red{color:var(--red)}

@media (max-width:1100px){.hz-contact{grid-template-columns:1fr;gap:40px}.form{padding:28px}}
@media (max-width:640px){.page-head .ringbg{width:80vw;right:-30%}.form .actions{flex-direction:column;align-items:stretch}}

/* --- ueber-uns.html --- */
.page-head h1{font-size:clamp(52px,9vw,150px)}
/* Statement-Szene: Wörter werden nacheinander hell */
.creed{height:260vh;position:relative}
.creed .stage{position:sticky;top:0;height:100vh;display:grid;place-items:center;overflow:hidden}
.creed p{font-family:var(--font-h);font-weight:300;font-size:clamp(32px,5.2vw,84px);letter-spacing:-.035em;line-height:1.08;text-align:center;max-width:1100px;margin:0;padding:0 24px}
.creed .w{display:inline-block;opacity:.18;transition:opacity .25s;--k:0}
.creed .w.on{opacity:1}
/* site.js zerlegt nur Textknoten, deshalb liegen die ".w"-Spans immer
   INNERHALB der Auszeichnung – nie umgekehrt. Ein ".creed .w.on b" käme daher
   nie zum Zug und steht hier bewusst nicht. */
.creed b .w.on,.creed strong .w.on{color:var(--sky)}
.creed .src{position:absolute;bottom:40px;left:50%;transform:translateX(-50%)}

/* Gründer */
.founder{display:grid;grid-template-columns:1fr 1fr;gap:64px;align-items:center;padding:120px 0;border-top:1px solid var(--line);scroll-margin-top:80px}
/* Seitenwechsel: das Ankreuzfeld „Bild rechts" (hz_flip) am Element setzt
   ".flip". Vorher stand hier ".founder:nth-of-type(even)" – die Regel zählte
   alle <section>-Geschwister im Artikel und kippte, sobald davor ein Element
   dazukam oder wegfiel. */
.founder.flip .duo{order:2}
.duo{position:relative;aspect-ratio:4/5;overflow:hidden;border-radius:6px;background:var(--blue-d);display:block}
.duo::before{content:"";position:absolute;inset:0;background:linear-gradient(160deg,var(--blue) 0%,var(--blue-d) 100%);z-index:0}
.duo img{position:relative;z-index:1;width:100%;height:100%;object-fit:cover;object-position:center 15%;filter:grayscale(1) contrast(1.1);mix-blend-mode:luminosity;opacity:.85;transition:transform 1.2s var(--ease),filter .8s,opacity .8s}
.duo:hover img{transform:scale(1.03);filter:grayscale(0);mix-blend-mode:normal;opacity:1}
/* Die Figure-Komponente liefert <picture><source…><img>. "display:contents"
   nimmt dem <picture> die eigene Box: die Prozentmaße von ".duo img" gehen
   weiter gegen ".duo" auf und der Blendmodus wirkt gegen ".duo::before". */
.duo picture{display:contents}
.founder h2{font-size:clamp(40px,5.4vw,80px)}
.founder .role{margin:20px 0 28px}
.founder p{font-size:19px;color:var(--muted);max-width:520px}
.founder p a{color:var(--txt);border-bottom:1px solid var(--sky);transition:color .3s}
.founder p a:hover{color:var(--sky)}
.founder .tags{display:flex;gap:10px;flex-wrap:wrap;margin-top:24px}
.founder .tags span{font-family:var(--font-m);font-size:12px;letter-spacing:.1em;text-transform:uppercase;padding:8px 12px;border:1px solid var(--line);border-radius:999px;color:var(--muted)}

/* Werte */
.values{padding:140px 0;border-top:1px solid var(--line)}
.values h2{font-size:clamp(40px,5vw,72px)}
/* padding/align-items ausdrücklich: hier stand einmal die ungescopte
   ".grid"-Regel der Kontaktseite im Weg. Die ist inzwischen auf
   ".hz-contact" begrenzt; die beiden Werte bleiben trotzdem stehen, damit
   das Raster nicht von einer künftigen ".grid"-Regel abhängt. */
/* auto-fit statt fester drei Spalten: vier Prinzipien (Consulting) stehen nebeneinander, drei Werte (Über uns) ebenfalls */
.values .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,280px),1fr));gap:20px;margin-top:56px;padding:0;align-items:stretch}
.val{border:1px solid var(--line);border-radius:6px;padding:36px;min-height:300px;display:flex;flex-direction:column;justify-content:space-between;background:linear-gradient(180deg,rgba(255,255,255,.03),transparent);transition:transform .5s var(--ease),border-color .4s}
.val:hover{transform:translateY(-8px);border-color:var(--c)}
.val .n{font-family:var(--font-h);font-weight:200;font-size:64px;color:var(--c);letter-spacing:-.04em;line-height:1}
.val h3{font-size:28px;font-weight:600;margin:24px 0 10px}
.val p{margin:0;color:var(--muted)}

/* Zitat */
.quote{padding:160px 0;text-align:center}
.quote blockquote{margin:0 auto;max-width:1000px;font-family:var(--font-h);font-weight:200;font-size:clamp(28px,4.4vw,64px);letter-spacing:-.03em;line-height:1.15}
/* TinyMCE speichert Fettdruck als <strong>, das Mockup nutzt <b> – beides gilt. */
.quote blockquote b,.quote blockquote strong{font-weight:700}
.quote .src{margin-top:28px}
.quote .ring{width:120px;margin:0 auto 40px;display:block;animation:spin 40s linear infinite;opacity:.9}

@media (max-width:1100px){
  .founder{grid-template-columns:1fr;gap:28px;padding:80px 0}
  .founder.flip .duo{order:0}
  .duo{aspect-ratio:4/3}
  .values .grid{grid-template-columns:1fr}
  .creed{height:220vh}
}

/* --- insights.html --- */
.page-head h1{font-size:clamp(56px,10vw,160px)}
.toolbar{display:flex;justify-content:space-between;align-items:center;gap:24px;flex-wrap:wrap;padding:24px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);position:sticky;top:72px;z-index:5;background:rgba(2,15,34,.85);backdrop-filter:blur(14px)}
/* Auf ".hz-newslist" begrenzt (Wrapper aus templates/horizont/mod_newslist_horizont.html5),
   damit die Filter-Chips der Insights-Seite und die Schlagwort-Chips des
   Kontaktabschnitts sich nicht gegenseitig ueberschreiben. */
.hz-newslist .chips{display:flex;gap:8px;flex-wrap:wrap}
.hz-newslist .chip{font-family:var(--font-m);font-size:12px;letter-spacing:.1em;text-transform:uppercase;padding:10px 14px;border:1px solid var(--line);border-radius:999px;color:var(--muted);background:transparent;cursor:pointer;transition:all .3s var(--ease)}
.hz-newslist .chip:hover{color:#fff;border-color:rgba(255,255,255,.4)}
.hz-newslist .chip.on{background:var(--sky);border-color:var(--sky);color:var(--blue-x)}
.search{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:999px;padding:8px 8px 8px 18px;min-width:280px}
.search input{background:transparent;border:0;outline:0;color:#fff;font:inherit;font-size:15px;flex:1}
.search input::placeholder{color:var(--muted)}
.search .count{font-family:var(--font-m);font-size:12px;color:var(--muted);padding:6px 10px;border-radius:999px;background:rgba(255,255,255,.06)}
.list{padding:24px 0 120px}
.post{display:grid;grid-template-columns:140px 260px 1fr auto;gap:32px;align-items:center;padding:28px 0;border-bottom:1px solid var(--line);transition:padding .4s var(--ease),opacity .4s,transform .4s var(--ease)}
.post:hover{padding-left:16px}
.post h3{font-size:clamp(24px,2.8vw,40px);font-weight:600;line-height:1.15;transition:color .3s}
.post:hover h3{color:var(--sky)}
.post .tags{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.post .tags span{font-family:var(--font-m);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:5px 9px;border:1px solid var(--line);border-radius:999px}
.post .arr{font-size:28px;color:var(--muted);transition:transform .4s var(--ease),color .3s}
.post:hover .arr{transform:translateX(8px);color:#fff}
.post.hide{display:none}
.post .pic{aspect-ratio:16/9;width:100%}
.post.featured{padding:48px 0;border-top:1px solid var(--line);grid-template-columns:140px 1fr auto;grid-template-areas:"meta pic arr" "meta txt arr"}
.post.featured .mono{grid-area:meta}.post.featured .pic{grid-area:pic;aspect-ratio:21/9;margin-bottom:8px}.post.featured .txt{grid-area:txt}.post.featured .arr{grid-area:arr}
.post.featured h3{font-size:clamp(32px,4.4vw,64px);font-weight:300}
.post.featured .mono b{color:var(--yellow);font-weight:400}
.empty{display:none;text-align:center;padding:96px 24px;border-bottom:1px solid var(--line)}
.empty.show{display:block}
.empty h3{font-size:clamp(28px,4vw,48px);margin:16px 0 12px}
.empty p{color:var(--muted);margin:0 0 28px}
@media (max-width:1100px){
  .toolbar{top:0;position:static}
  .post,.post.featured{grid-template-columns:1fr;grid-template-areas:none;gap:12px}
  .post .pic{aspect-ratio:16/9}
  .post .arr{display:none}
  .search{min-width:0;width:100%}
}

/* --- insight.html --- */
.readbar{position:fixed;top:0;left:0;height:3px;background:linear-gradient(90deg,var(--sky),var(--yellow));width:0;z-index:60;transition:width .1s linear}
.page-head h1{font-size:clamp(40px,6.4vw,104px);max-width:1100px}
.page-head .meta{display:flex;gap:24px;flex-wrap:wrap;margin-top:32px}
.page-head .meta .tag{padding:6px 10px;border:1px solid var(--line);border-radius:999px}
.hero-pic{aspect-ratio:21/9;margin:8px 0 56px}
.layout{display:grid;grid-template-columns:1fr 340px;gap:80px;padding:24px 0 120px;align-items:start}
.article{max-width:760px;font-size:19px;line-height:1.75}
.article p{margin:0 0 1.4em;color:#d9e2ee}
.article h2{font-size:clamp(28px,3.2vw,44px);font-weight:600;margin:2.2em 0 .7em;line-height:1.1}
.article .kicker{font-family:var(--font-h);font-weight:200;font-size:clamp(26px,3vw,40px);letter-spacing:-.02em;line-height:1.2;color:#fff;border-left:2px solid var(--yellow);padding-left:24px;margin:0 0 2em}
.article .num{font-family:var(--font-h);font-weight:200;font-size:clamp(56px,7vw,110px);letter-spacing:-.05em;line-height:1;color:var(--yellow);margin:.4em 0 .1em;display:block}
.article .num small{font-size:16px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);font-family:var(--font-m);display:block;margin-top:8px}
.aside{position:sticky;top:110px;display:grid;gap:20px}
.box{border:1px solid var(--line);border-radius:6px;padding:28px;background:linear-gradient(180deg,rgba(255,255,255,.03),transparent)}
.box h3{font-size:22px;font-weight:600;margin:10px 0 8px}
.box p{margin:0 0 16px;color:var(--muted);font-size:15px}
.box .bignum{font-family:var(--font-m);font-size:36px;color:var(--yellow);font-variant-numeric:tabular-nums;display:block;margin:10px 0 4px}
.box .bar{height:2px;background:var(--line);margin:14px 0 6px;overflow:hidden}
.box .bar i{display:block;height:100%;background:var(--yellow);width:0;animation:fill 60s linear infinite}
@keyframes fill{to{width:100%}}
.toc{display:grid;gap:6px;font-size:14px}
.toc a{color:var(--muted);padding:6px 0;border-left:1px solid var(--line);padding-left:14px;transition:color .3s,border-color .3s}
.toc a:hover,.toc a.on{color:#fff;border-color:var(--sky)}
.share{display:flex;gap:10px;flex-wrap:wrap}
.related{padding:0 0 120px}
.related h2{font-size:clamp(32px,4vw,56px);margin-bottom:32px}
/* Die Artikelseite zeigt zwei "Weiterlesen"-Karten statt der drei auf der
   Startseite. Die Regeln sind deshalb auf ".related" beschraenkt - unscoped
   ueberschrieben sie die Startseiten-Karten (repeat(3,1fr)) weiter oben. */
.related .cards{grid-template-columns:1fr 1fr}
.related .cardx{padding:0 0 24px;min-height:240px;gap:16px}
.related .cardx h3{font-size:22px;margin:10px 24px 0}
.related .cardx .mono,.related .cardx .go{margin:0 24px}
@media (max-width:1100px){.layout{grid-template-columns:1fr;gap:40px}.aside{position:static}.related .cards{grid-template-columns:1fr}.article{font-size:17px}}

/* --- Rechtstexte (Impressum, Datenschutz) ---
   Die beiden Seiten benutzen das Kern-Inhaltselement "text". Contao rendert es
   als ".ce_text" direkt unter dem Artikel-Wrapper ".container" (das Horizont-
   Layout lädt kein PCT-CSS mehr).

   Der KINDselektor ("> .ce_text") ist Absicht: er trifft nur Textelemente, die
   unmittelbar im Artikel stehen. Ein ".ce_text" tiefer im Baum – etwa in einem
   Element, das eigene Masse mitbringt – bleibt unberührt. Der Newsleser
   (news_hz_full.html5) rendert den Artikeltext dagegen ohne ".ce_text"
   direkt in ".article" und ist von dieser Regel ohnehin nicht betroffen. */
.hz .container>.ce_text{max-width:760px;margin:0 auto 120px;padding:0 24px;font-size:18px;line-height:1.75;color:#d9e2ee}
.hz .container>.ce_text h2{font-family:var(--font-h);font-weight:600;font-size:clamp(26px,3vw,40px);line-height:1.15;letter-spacing:-.02em;color:#fff;margin:2em 0 .6em}
.hz .container>.ce_text h3{font-family:var(--font-h);font-weight:600;font-size:clamp(19px,2.2vw,24px);line-height:1.25;color:#fff;margin:1.6em 0 .5em}
.hz .container>.ce_text h2:first-child,.hz .container>.ce_text h3:first-child{margin-top:0}
/* Sprungziele des Inhaltsverzeichnisses liegen sonst unter der fixen Kopfzeile. */
.hz .container>.ce_text [id]{scroll-margin-top:calc(var(--nav-h) + 24px)}
.hz .container>.ce_text p{margin:0 0 1.4em}
.hz .container>.ce_text ul{margin:0 0 1.4em;padding-left:22px}
.hz .container>.ce_text li{margin:0 0 .6em}
.hz .container>.ce_text ul ul{margin:.6em 0 0}
.hz .container>.ce_text strong{color:#fff;font-weight:600}
/* Der Datenschutztext enthaelt ausgeschriebene URLs; ohne Umbruch ragen sie
   auf schmalen Viewports aus der Spalte und werden von "main{overflow-x:clip}"
   abgeschnitten. */
.hz .container>.ce_text a{color:var(--sky);text-decoration:underline;text-underline-offset:3px;overflow-wrap:anywhere}
.hz .container>.ce_text a:hover{color:#fff}
@media (max-width:700px){.hz .container>.ce_text{font-size:17px;margin-bottom:80px}}


/* --- Profilseite (hz_profile) --- */
.profile{display:grid;grid-template-columns:.8fr 1.2fr;gap:64px;align-items:start;padding:24px 0 120px;scroll-margin-top:80px}
.profile .side{position:sticky;top:120px;display:grid;gap:20px}
.profile .side>.mono{margin-top:12px}
.profile .tags{display:flex;gap:10px;flex-wrap:wrap}
.profile .tags span{font-family:var(--font-m);font-size:12px;letter-spacing:.1em;text-transform:uppercase;padding:8px 12px;border:1px solid var(--line);border-radius:999px;color:var(--muted)}
.profile .tags span.on{color:var(--c);border-color:var(--c)}
.profile .contact{list-style:none;margin:12px 0 0;padding:0;display:grid;gap:0;border-top:1px solid var(--line)}
.profile .contact li{display:grid;gap:4px;padding:14px 0;border-bottom:1px solid var(--line)}
.profile .contact a{font-family:var(--font-h);font-weight:600;font-size:18px;border-bottom:1px solid transparent;transition:color .3s,border-color .3s;justify-self:start}
.profile .contact a:hover{color:var(--c);border-color:var(--c)}
.profile h2{font-size:clamp(40px,5.4vw,80px)}
.profile .body>.mono{display:block;margin-bottom:20px}
.profile .rich{margin-top:32px;max-width:640px}
.profile .rich p{font-size:19px;color:var(--muted);margin:0 0 1em}
.profile .rich p:first-child{font-size:22px;color:var(--txt);font-weight:300}
.profile .rich h3{font-size:clamp(24px,2.6vw,32px);font-weight:600;margin:48px 0 14px}
.profile .rich h3 b{color:var(--c)}
.profile .rich strong,.profile .rich b{color:var(--txt);font-weight:500}
.profile .rich blockquote{margin:40px 0;padding-left:24px;border-left:2px solid var(--c);font-family:var(--font-h);font-weight:200;font-size:clamp(24px,2.8vw,36px);letter-spacing:-.02em;line-height:1.2;color:var(--txt)}
.profile .rich blockquote p{font:inherit;color:inherit;margin:0}
.profile .rich ul{padding-left:20px;color:var(--muted)}
.profile .btn{margin-top:32px}
@media (max-width:1100px){
  .profile{grid-template-columns:1fr;gap:40px;padding-bottom:80px}
  .profile .side{position:static;grid-template-columns:1fr 1fr;align-items:start}
  .profile .side .duo{grid-row:1/4}
  .profile .side .duo{aspect-ratio:4/5}
}
@media (max-width:640px){
  .profile .side{grid-template-columns:1fr}
  .profile .side .duo{grid-row:auto;aspect-ratio:4/3}
}

/* --- Themenliste (hz_topics) --- */
.topics{padding:120px 0;border-top:1px solid var(--line)}
.topics h2{font-size:clamp(40px,5vw,72px)}
.topics h2 b{color:var(--c)}
.topics>.mono{display:block;margin-bottom:16px}
.topics .lead{font-size:20px;color:var(--muted);max-width:640px;margin:24px 0 0}
.topics .list{margin-top:56px;border-top:1px solid var(--line)}
.topic{display:grid;grid-template-columns:96px 1fr;gap:24px;padding:36px 0;border-bottom:1px solid var(--line);align-items:start}
.topic .n{font-family:var(--font-h);font-weight:200;font-size:56px;color:var(--c);letter-spacing:-.04em;line-height:1}
.topic h3{font-size:clamp(24px,2.6vw,34px);font-weight:600;line-height:1.15}
.topic h3 b{color:var(--c)}
.topic p{color:var(--muted);max-width:760px;margin:12px 0 0;font-size:17px}
.topic .more{display:inline-block;margin-top:14px;font-family:var(--font-h);font-weight:600;font-size:13px;letter-spacing:.1em;text-transform:uppercase;color:var(--c);border-bottom:1px solid transparent;transition:border-color .3s}
.topic .more:hover{border-color:var(--c)}
@media (max-width:640px){
  .topics{padding:80px 0}
  .topic{grid-template-columns:1fr;gap:8px;padding:28px 0}
  .topic .n{font-size:36px}
}

/* --- Cookie-Consent (consent.js) ---
   Dezente Karte unten links, kein bildschirmfüllendes Overlay. Erscheint nur,
   wenn das Layout das GTM-Analytics-Template gewählt hat (Marker im <head>). */
.hz-consent{position:fixed;left:20px;bottom:20px;z-index:55;width:min(420px,calc(100% - 40px));padding:24px 26px;border:1px solid var(--line);border-radius:8px;background:rgba(2,15,34,.92);backdrop-filter:blur(16px);box-shadow:0 24px 60px -24px rgba(0,0,0,.8);opacity:0;transform:translateY(12px);transition:opacity .4s var(--ease),transform .4s var(--ease)}
.hz-consent.is-open{opacity:1;transform:none}
.hz-consent .mono{display:block;margin-bottom:10px}
.hz-consent p{margin:0;font-size:15px;color:var(--muted)}
.hz-consent p b{color:var(--txt);font-family:var(--font-h);font-weight:600;font-size:18px;display:block;margin-bottom:6px}
.hz-consent p a{color:var(--txt);border-bottom:1px solid var(--sky)}
.hz-consent .actions{display:flex;gap:10px;flex-wrap:wrap;margin-top:18px}
.hz-consent .btn{padding:12px 18px;font-size:12px}
.hz-consent .btn-fill{padding:13px 20px}
@media (prefers-reduced-motion: reduce){.hz-consent{transition:none}}


/* ===== Mobil (bis 1100px): keine Sticky-Szenen =====
   Entscheidung 05.09.2026: auf dem iPhone zitterten die klebenden Bühnen auch
   nach dem Umbau auf Scroll-Timelines (Compositor-Sticky gegen nachlaufende
   Transformationen). Auf schmalen Bildschirmen werden die Szenen deshalb als
   ruhige, gestapelte Abschnitte gezeigt: die vier Panels untereinander, das
   Strike-Statement fertig durchgestrichen, die Ring-Szene mit allen Schritten
   offen. "--hz-static:1" sagt scrollfx.js/site.js, dass sie hier nichts
   mehr animieren sollen; die Szenen-Animationen der Scroll-Timeline sind aus. */
@media (max-width:1100px){
  .scene,.strike,.ringscene{--hz-static:1;--p:1;animation:none;height:auto}
  .track[data-hz-panels]{animation:none}
  /* Leistungs-Szene: Panels gestapelt */
  .scene .stage{position:static;height:auto;overflow:visible;display:block}
  .track{display:grid;width:auto;transform:none;will-change:auto}
  .panel{width:auto;height:auto;grid-template-columns:1fr;gap:12px;padding:56px clamp(24px,7vw,48px);border-top:1px solid var(--line)}
  .panel .big{transform:none;font-size:clamp(88px,26vw,160px)}
  .panel p{margin:16px 0 24px}
  .scene .hud{display:none}
  /* Strike-Statement: Endzustand, per Reveal eingeblendet */
  .strike{padding:96px 0}
  .strike .stage{position:static;height:auto;overflow:visible;display:block}
  .strike .l1{transform:none}
  /* Der ::after-Balken ist ein einzelner Strich über der Zeile – bricht die Zeile
     auf dem Handy um, trifft er nur eine der beiden. Deshalb hier ein echter
     Durchstrich, der jede Zeile einzeln kreuzt; dazu kleinere Schrift, damit
     „in neuer Verpackung.“ möglichst gar nicht umbricht. */
  .strike .l2::after{display:none}
  .strike .l2{text-decoration:line-through;text-decoration-color:var(--yellow);text-decoration-thickness:.08em;text-underline-offset:0}
  .strike .txt{font-size:clamp(30px,8vw,140px);text-wrap:balance}
  .strike .l3{clip-path:none}
  .strike .l3 .cur{display:none}
  .strike .glow{display:none}
  .strike .mono{display:none}
  /* Ring-Szene: Ring oben, alle Schritte offen */
  .ringscene .stage{position:static;height:auto;overflow:visible;padding-top:0;padding-bottom:48px}
  .ringwrap svg{transform:none}
  .ringwrap .seg{opacity:1}
  .step{border-color:var(--line);background:rgba(255,255,255,.03)}
  .step h3,.step:not(.on) h3{opacity:1;color:var(--c)}
  .step p{max-height:none;opacity:1}
  .ringscene .progress{display:none}
}

/* ============================================================================
   Mobile Animationen (06.09.2026) – nur ≤ 1100 px, ohne Sticky/Pinning.
   Scroll-gebundene Effekte laufen über CSS-Scroll-Timelines (view()/scroll())
   und liegen in @supports-Blöcken; ohne Unterstützung bleibt der statische
   Stand bzw. der Reveal aus scrollfx.js. Nur transform/opacity/clip-path/
   filter, prefers-reduced-motion → Endzustand. Vier Teile:
   1 Leistungs-Panels (hz_scene_services), 2 Strike-Szene (hz_strike),
   3 Ring-Szene (hz_ring_scene), 4 Mikro (Zähler, Tap-Feedback).
   ========================================================================= */

/* --- Mobil 1 --- */
/* mobile-1: Leistungs-Panels (hz_scene_services) mobil als Scroll-Reveal je Panel.
   ---------------------------------------------------------------------------
   Desktop (≥1101 px) behält die Horizontal-Fahrt aus horizont.css. Auf schmalen
   Bildschirmen (Panels gestapelt, --hz-static:1) kommt jedes Panel beim Eintritt
   in den Viewport seitlich herein (abwechselnd von rechts/links, 48 px, Opacity
   0→1), die Outline-Ziffer ".big" läuft leicht gegen den Text (Parallax 0→-24 px
   über die ganze Sichtstrecke) und ein Farbstreifen ".hz-bar" in der Panelfarbe
   (--c) füllt sich von links. Alles per CSS-Scroll-Timeline (view()), kein
   Sticky, kein JS. Ohne view()-Support: klassischer Reveal über data-reveal
   (IntersectionObserver in scrollfx.js). */

/* Der Farbstreifen existiert nur mobil. Der Reveal-Startzustand aus horizont.css
   (.js [data-reveal]) wird für die Panels überall neutralisiert und nur dort
   wieder aktiviert, wo er gebraucht wird (mobiler Fallback unten) – sonst würde
   der Desktop-Track die Panels beim Hereinfahren zusätzlich einblenden. */
.panel .hz-bar{display:none}
.js .panel[data-reveal]{opacity:1;transform:none;transition:none}

@media (max-width:1100px){
  /* Seitlicher Versatz der Panels darf keine horizontale Scrollstrecke erzeugen.
     "clip" statt "hidden": hidden würde die Szene zum Scroll-Container machen und
     damit zum Bezug von view() – clip nicht. */
  .scene{overflow-x:clip}
  .panel{position:relative}
  .panel .hz-bar{display:block;position:absolute;left:0;top:-1px;width:100%;height:2px;background:var(--c);transform-origin:left center;pointer-events:none}

  @supports (animation-timeline: view()){
    .panel{animation:hz-m1-in-right linear both;animation-timeline:view();animation-range:entry 0% entry 100%}
    .panel:nth-child(even){animation-name:hz-m1-in-left}
    .panel .big{animation:hz-m1-parallax linear both;animation-timeline:view();animation-range:entry 0% exit 100%}
    .panel .hz-bar{animation:hz-m1-bar linear both;animation-timeline:view();animation-range:entry 10% cover 30%}
    @keyframes hz-m1-in-right{from{opacity:0;transform:translate3d(48px,0,0)}to{opacity:1;transform:none}}
    @keyframes hz-m1-in-left{from{opacity:0;transform:translate3d(-48px,0,0)}to{opacity:1;transform:none}}
    @keyframes hz-m1-parallax{from{transform:translate3d(0,0,0)}to{transform:translate3d(0,-24px,0)}}
    @keyframes hz-m1-bar{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  }

  /* Fallback ohne Scroll-Timeline: Reveal per IntersectionObserver (scrollfx.js),
     Streifen steht sofort voll. Spezifität über ".js .panel[data-reveal]" oben. */
  @supports not (animation-timeline: view()){
    .js .panel[data-reveal]{opacity:0;transform:translateY(24px);transition:opacity .9s var(--ease),transform .9s var(--ease)}
    .js .panel[data-reveal].is-visible{opacity:1;transform:none}
  }

  @media (prefers-reduced-motion: reduce){
    .panel,.panel .big,.panel .hz-bar,.js .panel[data-reveal]{animation:none;opacity:1;transform:none;transition:none}
  }
}

/* --- Mobil 2 --- */
/* mobile-2: Strike-Statement der Startseite als Scroll-Sequenz (ohne Pinning).

   Desktop (>1100px) bleibt unberührt – dort steuert horizont.css die Szene über
   --p an der klebenden Bühne. Mobil ist die Bühne statisch (horizont.css,
   --hz-static:1); hier wird stattdessen jedes Teil direkt per View-Timeline der
   Sektion animiert, gestaffelt über animation-range:

     cover 12–35 %  Durchstrich Zeile 2 zeichnet sich von links (clip-path)
     cover 35–60 %  Zeile 3 („TROTZDEM neu.“) tippt sich ein (clip-path), Cursor blinkt
     cover 60–68 %  Cursor blendet aus
     cover  0–60 %  Glow skaliert .6 → 1.2 und blendet ein

   Der Durchstrich: horizont.css nutzt mobil text-decoration:line-through auf
   .l2, damit jede umgebrochene Zeile einzeln gekreuzt wird – das lässt sich
   nicht zeichnen. Deshalb legt ::after denselben Text (data-text aus dem Twig)
   unsichtbar über die Zeile, trägt nur die gelbe Durchstreichung (ebenfalls je
   Zeilenfragment) und wird per clip-path von links aufgedeckt. Die Kopie ist für
   Screenreader stumm (Alt-Text-Syntax „/ ''“).

   Ohne animation-timeline: view() gilt weiterhin der statische Endzustand aus
   horizont.css; bei prefers-reduced-motion ebenfalls. */
@media (max-width:1100px){
  @supports (animation-timeline: view()){
    .strike{view-timeline:--hz-strike block;overflow:hidden}

    /* Durchstrich Zeile 2 */
    .strike .l2{position:relative;text-decoration:none}
    .strike .l2::after{
      content:attr(data-text) / "";
      display:block;position:absolute;inset:0;width:auto;height:auto;
      background:none;box-shadow:none;color:transparent;pointer-events:none;
      text-decoration:line-through;text-decoration-color:var(--yellow);
      text-decoration-thickness:.08em;text-underline-offset:0;
      filter:drop-shadow(0 0 10px rgba(255,195,0,.45));
      clip-path:inset(0 0 0 0);
      animation:hz-m-strike linear both;
      animation-timeline:--hz-strike;
      animation-range:cover 12% cover 35%;
    }
    .strike .l2:not([data-text])::after{content:none}
    /* Zeile 2 hat nur ohne data-text keine Kopie – dann bleibt der statische Strich */
    .strike .l2:not([data-text]){text-decoration:line-through}

    /* Zeile 3 tippt sich ein */
    .strike .l3{
      clip-path:inset(0 0 0 0);
      animation:hz-m-type linear both;
      animation-timeline:--hz-strike;
      animation-range:cover 35% cover 60%;
    }
    /* Cursor: sichtbar während des Tippens, danach aus; Blinken zeitbasiert über
       scaleY (eigene Eigenschaft, kollidiert nicht mit der Scroll-Opacity) */
    .strike .l3 .cur{
      display:inline-block;opacity:0;transform-origin:50% 100%;
      animation:hz-m-cur linear both, hz-m-blink .9s steps(2,jump-none) infinite;
      animation-timeline:--hz-strike, auto;
      animation-range:cover 35% cover 68%, normal;
    }

    /* Glow hinter dem Text */
    .strike .glow{
      display:block;width:100vw;height:100%;
      /* Ellipse, die in die Sektion passt (auch bei scale 1.2) – kein harter Rand durch overflow */
      background:radial-gradient(ellipse closest-side,rgba(0,80,157,.5),transparent 60%);
      animation:hz-m-glow linear both;
      animation-timeline:--hz-strike;
      animation-range:cover 0% cover 60%;
    }

    @keyframes hz-m-strike{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
    @keyframes hz-m-type{from{clip-path:inset(0 100% 0 0)}to{clip-path:inset(0 0 0 0)}}
    @keyframes hz-m-cur{0%{opacity:0}4%,76%{opacity:1}100%{opacity:0}}
    @keyframes hz-m-blink{from{transform:scaleY(1)}to{transform:scaleY(0)}}
    @keyframes hz-m-glow{from{opacity:0;transform:translate(-50%,-50%) scale(.6)}to{opacity:1;transform:translate(-50%,-50%) scale(1.2)}}

    @media (prefers-reduced-motion: reduce){
      .strike .l2::after,.strike .l3,.strike .l3 .cur,.strike .glow{animation:none}
      .strike .l2::after{clip-path:none}
      .strike .l3{clip-path:none}
      .strike .l3 .cur{display:none}
      .strike .glow{opacity:1;transform:translate(-50%,-50%) scale(1.2)}
    }
  }
}

/* --- Mobil 3 --- */
/* mobile-3: Ring-Szene (hz_ring_scene) mobil, scrollgebunden ohne Pinning.
   Alles nur bis 1100px und nur mit Unterstützung für CSS-Scroll-Timelines
   (animation-timeline: view()). Ohne Unterstützung bleibt der statische Stand
   aus horizont.css (Ring ruhig, alle Schritte offen und farbig).

   Aufbau:
   - Der Ring (.ringwrap svg) dreht sich einmal um 360°, während er durch den
     Viewport wandert: eigene View-Timeline, Range "entry 0% → exit 100%".
   - Jeder Schritt (.step) hat eine benannte View-Timeline --hz-s1…--hz-s4 und
     schaltet sich zwischen "cover 25 %" und "cover 50 %" (Schrittmitte erreicht
     die Bildmitte) aktiv: Nummer/Titel in der Schrittfarbe, linker Leuchtrand,
     Text opacity .55 → 1. Danach bleibt er aktiv (fill both).
   - Die Namen sind über timeline-scope auf .ringscene für die ganze Szene
     sichtbar; damit leuchtet das k-te Ringsegment (.seg) und die große Zahl
     (.nums span) mit dem k-ten Schritt – ohne JavaScript.
   Reduced Motion: Endzustand (alle Schritte aktiv, alle Segmente an, Zahl 04). */
@media (max-width:1100px){
  /* Vier gestapelte Zahlen für den scrollgebundenen Wechsel; die ursprüngliche
     ".num" (site.js-Ziel am Desktop) wird mobil ausgeblendet. */
  .ringwrap .label .nums{display:grid;font-size:48px;font-weight:200;font-variant-numeric:tabular-nums;line-height:1}
  .ringwrap .label .nums span{grid-area:1/1;opacity:0}
  .ringwrap .label .nums span:first-child{opacity:1}
  .ringwrap .label .num{display:none}

  @supports (animation-timeline: view()){
    .ringscene{timeline-scope:--hz-s1,--hz-s2,--hz-s3,--hz-s4}
    /* --hz-step: gemeinsamer Name, den die Kinder jedes Schritts (Titel, Text,
       Leuchtrand) über die Vorfahrensuche finden; --hz-sK: szenenweiter Name
       für Segment und Zahl. Bewusst kein overflow:hidden auf .step – das
       machte den Schritt zum Scroll-Container und view() lief ins Leere. */
    .steps .step:nth-child(1){view-timeline:--hz-step block,--hz-s1 block}
    .steps .step:nth-child(2){view-timeline:--hz-step block,--hz-s2 block}
    .steps .step:nth-child(3){view-timeline:--hz-step block,--hz-s3 block}
    .steps .step:nth-child(4){view-timeline:--hz-step block,--hz-s4 block}

    /* (a) Ring dreht mit dem Scroll */
    @keyframes hz-m3-spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
    .ringwrap svg{animation:hz-m3-spin linear both;animation-timeline:view();animation-range:entry 0% exit 100%}

    /* Segmente: ruhig bis der zugehörige Schritt aktiv wird */
    @keyframes hz-m3-seg{from{opacity:.3;filter:drop-shadow(0 0 0 transparent)}to{opacity:1;filter:drop-shadow(0 0 14px currentColor)}}
    .ringwrap .seg{opacity:.3;transition:none;animation:hz-m3-seg linear both;animation-range:cover 25% cover 50%}
    .ringwrap svg > g:nth-child(1) .seg{animation-timeline:--hz-s1}
    .ringwrap svg > g:nth-child(2) .seg{animation-timeline:--hz-s2}
    .ringwrap svg > g:nth-child(3) .seg{animation-timeline:--hz-s3}
    .ringwrap svg > g:nth-child(4) .seg{animation-timeline:--hz-s4}

    /* Große Zahl: Nummer k (span) blendet mit Schritt k ein, ihr Inhalt (b)
       blendet mit Schritt k+1 wieder aus – zwei Elemente, weil zwei Timelines
       nicht dieselbe Eigenschaft eines Elements steuern können. */
    @keyframes hz-m3-in{from{opacity:0}to{opacity:1}}
    @keyframes hz-m3-out{from{opacity:1}to{opacity:0}}
    .ringwrap .label .nums span,.ringwrap .label .nums span b{display:block;font-weight:inherit}
    .ringwrap .label .nums span{animation:hz-m3-in linear both;animation-range:cover 25% cover 50%}
    .ringwrap .label .nums span b{animation:hz-m3-out linear both;animation-range:cover 25% cover 50%}
    .ringwrap .label .nums span:nth-child(1){animation:none;opacity:1}
    .ringwrap .label .nums span:nth-child(1) b{animation-timeline:--hz-s2}
    .ringwrap .label .nums span:nth-child(2){animation-timeline:--hz-s2}
    .ringwrap .label .nums span:nth-child(2) b{animation-timeline:--hz-s3}
    .ringwrap .label .nums span:nth-child(3){animation-timeline:--hz-s3}
    .ringwrap .label .nums span:nth-child(3) b{animation-timeline:--hz-s4}
    .ringwrap .label .nums span:nth-child(4){animation-timeline:--hz-s4}
    .ringwrap .label .nums span:nth-child(4) b{animation:none}

    /* (b) Schritte: Ruhezustand gedämpft, aktiv in der Schrittfarbe */
    .step{position:relative}
    .step::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;border-radius:6px 0 0 6px;background:var(--c);box-shadow:0 0 18px 2px var(--c);pointer-events:none;opacity:0}
    @keyframes hz-m3-bar{from{opacity:0}to{opacity:1}}
    @keyframes hz-m3-col{from{color:var(--txt)}to{color:var(--c)}}
    @keyframes hz-m3-k{from{color:var(--muted)}to{color:var(--c)}}
    @keyframes hz-m3-p{from{opacity:.55}to{opacity:1}}
    .step::before{animation:hz-m3-bar linear both;animation-timeline:--hz-step;animation-range:cover 25% cover 50%}
    .step h3,.step:not(.on) h3{opacity:1;color:var(--txt);animation:hz-m3-col linear both;animation-timeline:--hz-step;animation-range:cover 25% cover 50%}
    .step .k{color:var(--muted);animation:hz-m3-k linear both;animation-timeline:--hz-step;animation-range:cover 25% cover 50%}
    .step p{opacity:.55;transition:none;animation:hz-m3-p linear both;animation-timeline:--hz-step;animation-range:cover 25% cover 50%}

    @media (prefers-reduced-motion: reduce){
      .ringwrap svg,.ringwrap .seg,.ringwrap .label .nums span,.ringwrap .label .nums span b,.step::before,.step h3,.step:not(.on) h3,.step .k,.step p{animation:none}
      .ringwrap svg{transform:none}
      .ringwrap .seg{opacity:1}
      .ringwrap .label .nums span,.ringwrap .label .nums span b{opacity:0}
      .ringwrap .label .nums span:last-child,.ringwrap .label .nums span:last-child b{opacity:1}
      .step::before{opacity:1}
      .step h3,.step:not(.on) h3,.step .k{color:var(--c)}
      .step p{opacity:1}
    }
  }
}
/* Die gestapelten Zahlen gibt es nur mobil; am Desktop zeigt ".num" wie bisher
   (site.js schreibt sie). Kein sichtbarer Unterschied ≥1101px. */
@media (min-width:1101px){
  .ringwrap .label .nums{display:none}
}

/* --- Mobil 4 --- */
/* mobile-4: Mikro-Animationen mobil (Zähler, Tap-Feedback).
   Nur unter 1100px – Desktop bleibt unverändert.
   Zähler: hz_tools.html.twig (data-counter + data-counter-media, scrollfx.js). */
@media (max-width:1100px){

  /* 2. Karten heben sich beim Antippen (kein Hover auf Touch).
     Über die Einzel-Eigenschaften translate/scale, damit die Reveal-Regel
     (.js [data-reveal] ... transform) unberührt bleibt; die Transition wird
     deshalb vollständig neu geschrieben (Reveal-Anteile 1:1 übernommen).
     ".hz" (body) hebt die Spezifität über ".js [data-reveal]". */
  .hz .toolx,.hz .cardx,.hz .post,.hz .step{touch-action:manipulation;-webkit-tap-highlight-color:transparent;
    transition:opacity .9s var(--ease) calc(var(--d,0) * 1ms),transform .9s var(--ease) calc(var(--d,0) * 1ms),
      translate .2s var(--ease),scale .2s var(--ease),border-color .2s,background-color .2s}
  .hz .toolx:active,.hz .cardx:active,.hz .post:active,.hz .step:active{translate:0 -4px;scale:.995;border-color:rgba(255,255,255,.45)}
  .hz .toolx:active{border-color:var(--c)}
  .hz .post:active{padding-left:0;border-bottom-color:rgba(255,255,255,.45)}

  /* Reduced Motion: kein Tap-Lift; Zähler zeigt den Endwert (scrollfx.js). */
  @media (prefers-reduced-motion: reduce){
    .hz .toolx,.hz .cardx,.hz .post,.hz .step{transition:none}
    .hz .toolx:active,.hz .cardx:active,.hz .post:active,.hz .step:active{translate:none;scale:none}
  }
}
