/* Laenge der Scrollstory. Sie bestimmt, wie weit man scrollen muss, bis die
   naechste Szene beginnt.
   Am 2026-08-02 auf 780vh gezogen - das war zu viel. Bei fuenf Szenen lag
   jede Themenszene bei rund 1,7 Bildschirmhoehen: Man scrollt lange, die
   Ueberschrift steht still, nichts passiert. Am 2026-08-03 auf 420vh
   zurueckgenommen; zusammen mit den gleichmaessigeren Anteilen in
   SCENE_BREAKS faellt damit rund eine Bildschirmhoehe auf jede Themenszene.
   Kuerzer sollte es nicht werden - dann bleibt zum Lesen keine Zeit.

   Die Klammer um prefers-reduced-motion ist noetig, nicht Zierde: main.css
   setzt dort .scroll-story{height:auto}, damit der Abschnitt nur so hoch wird
   wie sein Inhalt. Media Queries erhoehen die Spezifitaet aber nicht, und
   diese Datei laedt spaeter - eine ungeklammerte Regel haette die
   Reduced-Motion-Fassung ueberstimmt und den Betroffenen 420vh Leere
   beschert. Die frueher hier stehende min-width-Regel war ausserdem
   wirkungslos: Sie wiederholte denselben Wert. */
@media(prefers-reduced-motion:no-preference){.scroll-story{height:420vh}}
@media(prefers-reduced-motion:no-preference) and (max-width:760px){.scroll-story{height:380vh}}

.energy-line{z-index:8;overflow:visible}
.energy-line:before{content:'';position:absolute;left:4.5vw;top:38%;width:min(12rem,17vw);height:1px;border-radius:999px;background:linear-gradient(90deg,transparent,rgba(212,168,67,.12),rgba(244,214,125,.5),rgba(212,168,67,.14),transparent);transform:rotate(-11deg);opacity:.72;filter:blur(.1px)}
.energy-line:after{content:'';position:absolute;left:calc(4.5vw + min(11.8rem,16.6vw));top:calc(38% - 3px);width:.42rem;height:.42rem;border-radius:50%;background:radial-gradient(circle,var(--gold-light),rgba(212,168,67,.36) 68%,transparent 74%);box-shadow:0 0 10px rgba(244,214,125,.85),0 0 28px rgba(212,168,67,.35)}
.energy-line span{position:absolute;left:4.5vw;top:38%;width:4rem;height:2px;border-radius:999px;background:linear-gradient(90deg,transparent,rgba(244,214,125,.92),transparent);filter:drop-shadow(0 0 8px rgba(212,168,67,.45));transform-origin:left center;transform:rotate(-11deg) scaleX(.7);opacity:.35;animation:energyPulse 4.8s ease-in-out infinite}
@keyframes energyPulse{0%,100%{opacity:.28;transform:rotate(-11deg) scaleX(.72)}50%{opacity:.62;transform:rotate(-11deg) scaleX(1)}}
@media(max-width:760px){.energy-line:before{left:3.8vw;top:34%;width:7rem}.energy-line:after{left:calc(3.8vw + 6.9rem);top:calc(34% - 3px)}.energy-line span{left:3.8vw;top:34%}}

.services{background:linear-gradient(180deg,#080b10 0,#11161d 7rem,#edf1f4 12rem,#edf1f4 100%);position:relative}
.services:before{content:'';position:absolute;left:0;right:0;top:0;height:8.5rem;background:linear-gradient(180deg,#080b10 0,rgba(8,11,16,.85) 45%,rgba(8,11,16,0) 100%);pointer-events:none}
/* .after-story bekommt seinen Hintergrund weiter unten im Block zum
   Videohintergrund - dort durchscheinend. Die frueher hier stehende deckende
   Fassung war seit dem 2026-08-03 wirkungslos und ist entfernt. */
.services .section-intro,.services .service-list,.services .section-intro h2,.services .section-intro p,.services .service-list article{position:relative;z-index:1}

.site-header nav{gap:.7rem;flex-wrap:wrap;justify-content:flex-end}
.site-header nav a{display:inline-flex;align-items:center;gap:.45rem;padding:.55rem .85rem;border-radius:999px;border:1px solid rgba(240,243,247,.08);background:rgba(240,243,247,.03);color:var(--muted);font-size:.72rem;letter-spacing:.03em;transition:transform .2s ease,background .2s ease,border-color .2s ease,color .2s ease}
.site-header nav a:hover,.site-header nav a:focus-visible{transform:translateY(-1px);border-color:rgba(212,168,67,.34);background:rgba(212,168,67,.08);color:var(--paper)}
.site-header .nav-cta{border:0;background:linear-gradient(135deg,var(--gold),#e1bd59);color:var(--ink);padding:.72rem 1rem;font-weight:800;box-shadow:0 12px 24px rgba(212,168,67,.22)}
.nav-call{padding:.55rem .95rem}
.nav-call__dot{width:.46rem;height:.46rem;border-radius:50%;background:radial-gradient(circle,var(--gold-light),var(--gold));box-shadow:0 0 0 .35rem rgba(212,168,67,.12),0 0 18px rgba(244,214,125,.5)}
.nav-call span:last-child{letter-spacing:.06em}
.site-header{backdrop-filter:saturate(1.05)}
.site-header.is-scrolled{box-shadow:0 12px 30px rgba(0,0,0,.18)}

.service-list{gap:1.15rem;background:transparent}
.services .service-list article{position:relative;overflow:hidden;min-height:100%;padding:1.45rem;border:1px solid rgba(82,96,111,.12);border-radius:1.1rem;background:linear-gradient(180deg,#fdfefe 0,#eef2f5 100%);box-shadow:0 18px 50px rgba(10,18,24,.08),inset 0 1px rgba(255,255,255,.6);display:flex;flex-direction:column;gap:.85rem}
.services .service-list article:hover{transform:translateY(-2px)}
.services .service-list article:before{content:'';display:block;height:7rem;margin:-.15rem -.15rem .6rem;border-radius:.9rem;position:relative;overflow:hidden}
.services .service-list article:after{content:'';position:absolute;left:0;right:0;top:0;height:.2rem;background:linear-gradient(90deg,transparent,rgba(212,168,67,.35),rgba(244,214,125,.9),rgba(212,168,67,.35),transparent);opacity:.6}
.services .service-list article b{display:inline-flex;align-items:center;justify-content:center;width:2.1rem;height:2.1rem;border-radius:999px;background:rgba(212,168,67,.12);border:1px solid rgba(212,168,67,.18)}
.services .service-list article h3{display:block;font-size:1.25rem;line-height:1.05;margin-top:.2rem}
.services .service-list article p{max-width:unset}
.services .service-list article .service-examples{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.55rem;margin-top:.15rem}
.services .service-list article .service-examples li{position:relative;padding:.7rem .8rem .7rem 1rem;border:1px solid rgba(82,96,111,.1);border-radius:.7rem;background:rgba(255,255,255,.68);color:#334252;font-size:.78rem;line-height:1.45;box-shadow:0 6px 18px rgba(7,11,18,.03)}
.services .service-list article .service-examples li:hover{background:#fff}
.services .service-list article .service-examples li:before{content:'';position:absolute;left:.45rem;top:.98rem;width:.32rem;height:.32rem;border-radius:50%;background:var(--gold);box-shadow:0 0 0 .28rem rgba(212,168,67,.12)}
.services .service-card-link{display:inline-flex;gap:.45rem;align-items:center;margin-top:1rem;color:#101722;text-decoration:none;font-size:.76rem;font-weight:800;letter-spacing:.02em}
/* **Gold traegt auf dunklem Grund, im hellen Leistungsabschnitt nicht.**
   Nachgerechnet (24.08.2026): --gold #d4a843 auf der Kartenflaeche #eef2f5
   ergibt 1,97:1. Der Link steht im Ruhezustand bei 15,98:1 - er VERSCHWAND
   also genau in dem Moment, in dem man ihn per Tastatur ansteuerte, und die
   Karten sind ganzflaechig verlinkt: Wer nicht sieht, wo er steht, trifft
   blind eine von drei Leistungsseiten.
   --gold-dunkel #7d5f12 ist derselbe Farbton, nur so weit abgedunkelt, dass
   er auf allen drei hellen Flaechen ueber 4,9:1 kommt (Karte 5,30, Abschnitt
   5,26, Kartennummer 4,91). Auf dunklem Grund bleibt --gold unangetastet. */
.services{--gold-dunkel:#7d5f12}
.services .service-card-link:hover,.services .service-card-link:focus-visible{color:var(--gold-dunkel)}
/* Dieselbe Ursache an drei weiteren Stellen: `em{color:var(--gold)}` und
   `.eyebrow{color:var(--gold-light)}` stehen als Typselektoren in main.css,
   sind fuer dunkle Flaechen geschrieben und greifen im hellen
   Leistungsabschnitt ungefiltert mit. Gemessen war die halbe
   Abschnittsueberschrift bei 1,95:1 und die Kickerzeile darueber bei 1,25:1 -
   auf einem hellen Bildschirm oder bei Sonnenlicht nicht lesbar.
   main.css ist minifiziert und wird nicht angefasst; die Korrektur gehoert
   ohnehin in diese Override-Schicht, die genau dafuer da ist. */
.services h2 em{color:var(--gold-dunkel)}
.services .eyebrow{color:var(--gold-dunkel)}
.services .service-list article b{color:var(--gold-dunkel)}
.services .service-list article:nth-child(1) h3:after{content:'Altbau · Neubau · Modernisierung';display:block;margin-top:.4rem;color:#65727f;font-size:.62rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
.services .service-list article:nth-child(2) h3:after{content:'Dach · Speicher · Anmeldung';display:block;margin-top:.4rem;color:#65727f;font-size:.62rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
.services .service-list article:nth-child(3) h3:after{content:'Wallbox · Lastmanagement · PV-Kopplung';display:block;margin-top:.4rem;color:#65727f;font-size:.62rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase}
.services .service-list article:nth-child(1):before{background-image:linear-gradient(135deg,rgba(13,17,24,.02),rgba(13,17,24,.02)),linear-gradient(90deg,transparent 0 18%,rgba(82,96,111,.22) 18% 20%,transparent 20% 36%,rgba(82,96,111,.22) 36% 38%,transparent 38% 54%,rgba(82,96,111,.22) 54% 56%,transparent 56% 72%,rgba(82,96,111,.22) 72% 74%,transparent 74% 100%),linear-gradient(180deg,transparent 0 22%,rgba(82,96,111,.16) 22% 24%,transparent 24% 100%),radial-gradient(circle at 78% 24%,rgba(212,168,67,.46) 0 .55rem,transparent .6rem),linear-gradient(135deg,#151b23 0,#293341 100%)}
.services .service-list article:nth-child(2):before{background-image:linear-gradient(90deg,rgba(255,255,255,.12) 1px,transparent 1px),linear-gradient(180deg,rgba(255,255,255,.12) 1px,transparent 1px),radial-gradient(circle at 74% 28%,rgba(244,214,125,.9) 0 .55rem,transparent .65rem),linear-gradient(135deg,#1e2c3c 0,#0b1118 100%);background-size:18px 18px,18px 18px,auto,auto}
.services .service-list article:nth-child(3):before{background-image:radial-gradient(circle at 26% 28%,rgba(244,214,125,.95) 0 .42rem,transparent .48rem),linear-gradient(155deg,transparent 0 40%,rgba(244,214,125,.9) 40% 42%,transparent 42% 100%),linear-gradient(135deg,#1d2732 0,#081018 100%);background-size:auto,auto,auto}
@media(max-width:760px){
  .services .service-list{grid-template-columns:1fr}
  .services .service-list article{padding:1.25rem}
  .services .service-list article:before{height:6.5rem}
  .services .service-list article h3{font-size:1.18rem}
  .services .service-list article:nth-child(1) h3:after,
  .services .service-list article:nth-child(2) h3:after,
  .services .service-list article:nth-child(3) h3:after{font-size:.58rem}
  .services .service-list article .service-examples{grid-template-columns:1fr}
  .services .service-list article .service-examples li{font-size:.82rem}
}

.site-header{padding:1rem 4.2vw}.site-header nav{gap:.55rem}.site-header nav a{padding:.45rem .75rem;font-size:.69rem}.site-header .nav-cta{padding:.66rem .92rem;font-size:.72rem}.brand-type{font-size:.62rem}.brand-type i{letter-spacing:.26em}.hero-intro{position:fixed;z-index:14;left:8vw;top:50%;max-width:41rem;transform:translateY(-45%);pointer-events:auto;transition:opacity .35s ease,transform .45s cubic-bezier(.16,1,.3,1)}.hero-intro::before{content:'';position:absolute;left:0;right:0;top:-1rem;height:1px;background:linear-gradient(90deg,transparent,rgba(244,214,125,.8),rgba(212,168,67,.18),transparent);opacity:.7}.hero-intro::after{content:'';position:absolute;right:-1rem;top:.6rem;width:8rem;height:8rem;border-radius:50%;background:radial-gradient(circle,rgba(212,168,67,.16),transparent 70%);filter:blur(8px);pointer-events:none}.hero-intro>p:not(.eyebrow){max-width:31rem;margin:1.3rem 0;color:var(--muted);font-size:1.03rem;line-height:1.65}.hero-actions{flex-wrap:wrap;gap:1rem}.hero-actions .button{margin-top:0;box-shadow:0 14px 34px rgba(212,168,67,.18)}.hero-proof{display:block;margin-top:1.35rem;color:#edf2f6;font-size:.66rem;letter-spacing:.12em;text-transform:uppercase}.hero-badges{display:flex;flex-wrap:wrap;gap:.55rem;margin:1.25rem 0 1rem}.hero-badges span{display:inline-flex;align-items:center;min-height:1.95rem;padding:.44rem .72rem;border-radius:999px;border:1px solid rgba(212,168,67,.18);background:rgba(240,243,247,.05);color:var(--paper);font-size:.6rem;letter-spacing:.12em;text-transform:uppercase}
@media(max-width:760px){.site-header{padding:.88rem 4vw}.site-header nav{gap:.45rem}.site-header nav a{padding:.42rem .66rem;font-size:.64rem}.site-header .nav-cta{padding:.6rem .74rem;font-size:.66rem}.hero-intro{left:6vw;right:6vw;top:auto;bottom:12vh;transform:none;max-width:none;padding:1rem .95rem .95rem;border-radius:1rem}.hero-intro>p:not(.eyebrow){font-size:.9rem;margin:1rem 0}.hero-actions{align-items:flex-start;flex-direction:column}.hero-actions .button{width:100%;justify-content:center}.hero-badges{gap:.45rem;margin:1rem 0 .95rem}.hero-badges span{padding:.4rem .64rem;font-size:.58rem}}

.hero-intro{padding:1rem 1.15rem 1.1rem;border:1px solid rgba(255,255,255,.08);border-radius:1.4rem;background:linear-gradient(180deg,rgba(5,6,8,.68),rgba(11,15,21,.5));box-shadow:0 22px 60px rgba(0,0,0,.34),inset 0 1px rgba(255,255,255,.06);backdrop-filter:blur(12px)}.hero-intro>p:not(.eyebrow){max-width:32rem}.hero-badges{display:flex;flex-wrap:wrap;gap:.55rem;margin:1.65rem 0 1.25rem}.hero-badges span{display:inline-flex;align-items:center;min-height:2rem;padding:.48rem .8rem;border-radius:999px;border:1px solid rgba(212,168,67,.18);background:rgba(240,243,247,.05);color:var(--paper);font-size:.64rem;letter-spacing:.12em;text-transform:uppercase}.hero-actions{flex-wrap:wrap;gap:1rem}.hero-actions .button{margin-top:0;box-shadow:0 14px 34px rgba(212,168,67,.18)}.hero-proof{margin-top:1.8rem;color:#edf2f6}
@media(max-width:760px){.hero-intro{padding:1rem .95rem .95rem;border-radius:1rem}.hero-badges{gap:.45rem;margin:1.1rem 0 1rem}.hero-badges span{padding:.42rem .7rem;font-size:.6rem}.hero-actions{align-items:flex-start;flex-direction:column}.hero-actions .button{width:100%;justify-content:center}}

.scene-copy{transition:opacity .45s cubic-bezier(.16,1,.3,1),translate .65s cubic-bezier(.16,1,.3,1)}
.scene-video{transition:opacity .55s ease,transform .9s cubic-bezier(.16,1,.3,1);transform:scale(1.06)}
.scene-video.is-active.is-playable{opacity:1;transform:scale(1)}

#kontakt{scroll-margin-top:7rem}
@media(max-width:760px){#kontakt{scroll-margin-top:6rem}}

.service-page{background:#050608;color:var(--paper);padding:7rem 8vw 0}
.service-page .site-header{padding:1rem 8vw;background:rgba(5,6,8,.88);backdrop-filter:blur(18px)}
.service-page .page-hero{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(18rem,.9fr);gap:2rem;align-items:end;padding:3rem 0 5rem;border-bottom:1px solid var(--line)}
.service-page .page-hero h1{margin:0;font:700 clamp(3rem,6vw,5.8rem)/.95 Fraunces,Georgia,serif;letter-spacing:-.06em;max-width:14ch}
.service-page .page-hero p{max-width:42rem;color:var(--muted);line-height:1.75}
.service-page .page-hero .hero-actions{display:flex;flex-wrap:wrap;gap:1rem;margin-top:1.4rem}
.service-page .page-note{padding:1.2rem;border:1px solid rgba(212,168,67,.16);border-radius:1rem;background:linear-gradient(180deg,rgba(212,168,67,.11),rgba(255,255,255,.03));box-shadow:0 18px 45px rgba(0,0,0,.24)}
.service-page .page-note span{display:block;color:var(--gold-light);font-size:.65rem;letter-spacing:.14em;text-transform:uppercase;margin-bottom:.45rem}
.service-page .page-note strong{display:block;font:700 clamp(1.6rem,3vw,2.8rem)/.95 Fraunces,Georgia,serif;letter-spacing:-.045em;color:var(--paper)}
.service-page .page-note p{margin:.75rem 0 0;color:var(--muted);font-size:.84rem;line-height:1.6}
.service-page .page-section{padding:5rem 0}
.service-page .page-section h2{margin:0 0 1rem;font:700 clamp(2.4rem,4.6vw,4rem)/.96 Fraunces,Georgia,serif;letter-spacing:-.055em}
.service-page .page-section p.lead{max-width:42rem;margin:0 0 1.25rem;color:var(--muted);font-size:1rem;line-height:1.75!important}
.service-page .page-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);margin-top:2rem}
.service-page .page-grid article{background:#0a0d12;padding:1.6rem}
.service-page .page-grid h3{margin:.8rem 0 .55rem;font:700 1.2rem Fraunces,Georgia,serif}
.service-page .page-grid p,.service-page .page-grid li{color:var(--muted);line-height:1.7;font-size:.88rem}
.service-page .page-grid ul{padding-left:1rem;margin:.8rem 0 0}
.service-page .faq-list{display:grid;gap:1px;background:var(--line);margin-top:2rem}
.service-page .faq-list article{background:#0a0d12;padding:1.4rem 1.6rem}
.service-page .faq-list h3{margin:0 0 .55rem;font:700 1.05rem Fraunces,Georgia,serif}
.service-page .page-cta{padding:4rem 0 6rem}
.service-page .page-cta .contact-actions{margin-top:1.2rem}
.service-page .page-cta .contact-note{max-width:44rem}
.service-page .service-card-link{display:inline-flex;gap:.55rem;align-items:center;margin-top:1rem;color:var(--gold-light);text-decoration:none;font-size:.78rem;font-weight:800}
.service-page .service-card-link b{font-size:1rem}
.service-page .service-card-link:hover,.service-page .service-card-link:focus-visible{color:var(--paper)}
/* `1fr` allein reicht hier nicht: Eine 1fr-Spur hat als Minimum implizit
   `auto`, also die min-content-Breite ihres Inhalts. Steht darin ein langes
   deutsches Kompositum, waechst die Spur ueber ihren Container hinaus, statt
   zu schrumpfen. GEMESSEN am 24.08.2026 auf pruefungen.html bei 320 px: Spur
   294,36 px in einem 281,63 px breiten Abschnitt - der Inhalt endete 13 px
   rechts neben dem Abschnitt, links blieben 19 px Rand, rechts 6 px. Kein
   Seitenscroll, aber sichtbar schief.
   `minmax(0,1fr)` nimmt der Spur dieses Minimum. Nachgemessen: scrollWidth
   gleich clientWidth, Inhalt buendig mit dem Abschnitt. */
@media(max-width:980px){.service-page{padding-left:6vw;padding-right:6vw}.service-page .site-header{padding:1rem 6vw}.service-page .page-hero{grid-template-columns:minmax(0,1fr)}.service-page .page-grid{grid-template-columns:minmax(0,1fr)}}
@media(max-width:760px){.service-page{padding-top:6.5rem}.service-page .page-hero h1{font-size:clamp(2.6rem,13vw,4.2rem)}.service-page .page-section{padding:4rem 0}.service-page .page-grid article,.service-page .faq-list article{padding:1.2rem}.service-page .page-note strong{font-size:clamp(1.4rem,8vw,2rem)}}

.trust-strip{position:relative;z-index:25;padding:0 8vw 6rem;background:#080b10}
.trust-strip__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);margin-top:1.9rem}
.trust-strip__grid article{background:#0a0d12;padding:1.7rem}
.trust-strip__grid h3{margin:.2rem 0 .55rem;font:700 1.15rem Fraunces,Georgia,serif}
.trust-strip__grid p{margin:0;color:var(--muted);font-size:.86rem;line-height:1.7}
.trust-strip__grid a{display:inline-flex;align-items:center;gap:.4rem;margin-top:.95rem;color:var(--paper);text-decoration:none;font-size:.78rem;font-weight:800}
.trust-strip__grid a:hover,.trust-strip__grid a:focus-visible{color:var(--gold-light)}
@media(max-width:900px){.trust-strip{padding-left:6vw;padding-right:6vw}.trust-strip__grid{grid-template-columns:1fr}}

/* Tippziele nach WCAG 2.5.8 auf mindestens 24px Hoehe. Padding vergroessert
   nur die Trefferflaeche; der negative Aussenabstand haelt das Layout. */
.site-footer a{display:inline-flex;align-items:center;min-height:1.6rem;padding:.3rem 0;margin:-.3rem 0}
.trust-strip__grid a{min-height:1.6rem;padding:.3rem 0;margin-top:.65rem}
/* Auf kontakt.html waren Telefonnummer und E-Mail nur 22px hoch. Die beiden
   Selektoren stehen hier mit derselben Spezifitaet wie oben in der Datei,
   damit der geerbte margin-top von 1rem wirklich ersetzt wird - ein blosses
   .service-card-link waere zu schwach. Oben 1rem minus .3rem Innenabstand,
   unten negativ ausgeglichen: die Trefferflaeche waechst, das Layout nicht. */
.services .service-card-link,
.service-page .service-card-link{min-height:1.6rem;padding:.3rem 0;margin-top:.7rem;margin-bottom:-.3rem}

/* Bilder in den drei Leistungskarten.
   Die Karten trugen oben eine leere Flaeche als Platzhalter: article:before,
   7rem hoch, mit negativen Aussenabstaenden von .15rem leicht ueber den
   Textbereich hinaus. Dort steht jetzt ein Bild. Es uebernimmt dieselbe
   Geometrie, damit sich am Aufbau der Karte nichts verschiebt - nur etwas
   hoeher, weil ein Foto mehr Flaeche braucht als ein Farbverlauf.
   .service-list kommt ausschliesslich in index.html vor, und dort tragen alle
   drei Karten ein Bild.

   Die Abschaltung braucht dieselbe Spezifitaet wie die Ausgangsregel: Weiter
   oben steht '.services .service-list article:before' mit gezeichneten
   Hintergruenden - Verteilung, Modulraster, Ladepunkt. Ein blosses
   '.service-list article:before' waere schwaecher und wirkungslos geblieben,
   der Platzhalter stuende dann ueber dem Foto. */
.services .service-list article:before{display:none}
.service-shot{display:block;width:calc(100% + .3rem);height:9.5rem;object-fit:cover;margin:-.15rem -.15rem .6rem;border-radius:.9rem;background:#0d1118}
@media(max-width:760px){.services .service-list article:before{display:none}.service-shot{height:12rem}}

/* ── KI-Kennzeichnung am Motiv (Art. 50 Abs. 4 KI-VO) ─────────────────
   Die Bildmotive sind generativ erzeugt. Der Hinweis steht bewusst als
   <figcaption> im <figure> und nicht als freier Absatz: nur so ordnet
   ein Screenreader ihn dem Bild zu, was Art. 50 Abs. 5 ausdruecklich
   verlangt ("shall conform to the applicable accessibility
   requirements"). Der Aussenabstand wandert dabei vom Bild auf die
   Figur, damit das Kartenraster unveraendert bleibt. */
.service-figure{margin:0 0 .6rem}
.service-figure .service-shot{margin-bottom:.35rem}

/* ── Die ganze Leistungskarte ist anklickbar ──────────────────────────
   Rudolfs Frage am 10.08.2026: reicht der Verweis unter dem Text, oder
   soll die ganze Karte klicken? Antwort: die ganze Karte. Das Bild sieht
   anklickbar aus, war es aber nicht - wer darauf tippt, tut nichts. Und am
   Telefon ist die Textzeile "Mehr zu ..." rund 18 px hoch, die Karte
   dagegen ueber 400.

   Umgesetzt als ausgedehnter Verweis, nicht als <a> um die halbe Karte:
   Ein umschliessender Verweis macht aus Ueberschrift, Absatz und vier
   Stichpunkten EINEN Verweisnamen - ein Screenreader liest dann am Stueck
   "Link, Elektroinstallation Altbau Neubau Modernisierung Durchdacht
   geplant ...". So bleibt die Gliederung erhalten, der Verweisname kurz
   und im Markup aendert sich nichts.

   article:after ist schon fuer den goldenen Strich oben vergeben - deshalb
   liegt die Flaeche auf dem Verweis selbst. Der steht als letztes Kind der
   Karte, seine Flaeche deckt also alles darunter ab.

   Der Preis, bewusst in Kauf genommen: Text laesst sich in der Karte nicht
   mehr mit der Maus markieren, und der kleine Aufhellungseffekt an den
   Stichpunkten entfaellt. Beides wiegt weniger als eine Trefferflaeche,
   die zwanzigmal groesser ist. */
.services .service-list article{cursor:pointer;transition:transform .25s cubic-bezier(.16,1,.3,1),box-shadow .25s ease,border-color .25s ease}
.services .service-card-link::after{content:'';position:absolute;inset:0;z-index:2}

/* Ohne sichtbare Rueckmeldung waere die Flaeche eine versteckte Funktion.
   Die Karte hebt sich deutlicher als vorher (-2px war kaum zu sehen), und
   der Verweis darunter faerbt sich mit, damit klar ist, wohin es geht. */
.services .service-list article:hover{transform:translateY(-4px);border-color:rgba(212,168,67,.34);box-shadow:0 26px 60px rgba(10,18,24,.14),inset 0 1px rgba(255,255,255,.7)}
.services .service-list article:hover .service-card-link{color:var(--gold)}

/* Tastaturbedienung: Der Verweis bleibt das fokussierbare Element, der
   Rahmen umfasst aber die ganze Karte - sonst sieht man den Fokus nur an
   einer Textzeile, waehrend die Trefferflaeche die Karte ist. */
/* Der Rahmen war golden und lag damit bei 1,95:1 auf der Abschnittsflaeche -
   unter den 3:1, die SC 1.4.11 fuer Bedienelemente verlangt, und durch den
   outline-offset zur Haelfte auf dem noch helleren Grund daneben. Jetzt in
   --ink-Naehe: #101722 auf #edf1f4 sind 15,83:1 (24.08.2026 nachgerechnet). */
.services .service-card-link:focus-visible{outline:none}
.services .service-card-link:focus-visible::after{outline:3px solid #101722;outline-offset:3px;border-radius:1.1rem}
/* Deckkraft .56 statt .55, und das ist kein Zierwert: Bei .55 ergibt die
   Schrift auf dem hellen Kartenverlauf am dunkleren Ende 4,41:1 und verfehlt
   damit WCAG AA (4,5:1 fuer normalen Text, hier 10,88 px / 400). Mit .56 liegt
   sie ueber der Schwelle. Art. 50 Abs. 5 KI-VO verlangt die Kennzeichnung
   ausdruecklich barrierefrei - deshalb wird der Wert hier nicht gesenkt. */
.media-note{margin:0;font-size:.68rem;letter-spacing:.07em;text-transform:uppercase;opacity:.56}

/* ── Durchlaufender Videohintergrund ueber die ganze Seite ────────────
   Die Buehne stand als position:sticky in der Scrollstory und war damit
   nur dort zu sehen. Jetzt liegt sie fest hinter dem gesamten Dokument.
   z-index 0, weil alle Abschnitte darunter auf 25 liegen - sie decken den
   Film also ab, solange ihr Hintergrund deckend ist.

   Auch hier die Klammer um prefers-reduced-motion: main.css setzt dort
   .story-stage{position:relative;height:26rem} - eine ruhige Buehne im Fluss
   statt einer bildschirmfuellenden festen Ebene. Ohne Klammer haette diese
   Regel das ueberstimmt.
   height entfaellt: inset:0 bemisst die Ebene bereits am Sichtfenster. Ein
   zusaetzliches 100vh haette die untere Verankerung aufgehoben und auf
   Mobilgeraeten unter die Adressleiste gereicht. */
@media(prefers-reduced-motion:no-preference){.story-stage{position:fixed;inset:0;z-index:0}}

/* Damit unten ueberhaupt etwas vom Film zu sehen ist, werden die dunklen
   Abschnitte leicht durchscheinend. 0.82 laesst den Film ahnen, ohne den
   Text anzugreifen - er steht hell auf dunkel, und die Filme sind
   Daemmerungsaufnahmen.
   .services bleibt ausdruecklich deckend: Der Abschnitt ist hell mit
   dunklem Text. Dort durchscheinend zu werden, wuerde den gemessenen
   Kontrast von 10,4:1 zerstoeren - das ist der eine Ort, an dem der Film
   nicht hingehoert. */
.after-story{background:linear-gradient(180deg,rgba(8,11,16,.82) 0,rgba(11,15,21,.82) 100%)}
.process{background:linear-gradient(135deg,rgba(16,23,34,.82),rgba(5,6,8,.82))}
.contact{background:linear-gradient(130deg,rgba(12,17,25,.82),rgba(5,6,8,.82))}
.trust-strip{background:rgba(8,11,16,.82)}
/* Die Kacheln der Vertrauensleiste stehen auf eigenem Grund - sonst
   liefe der Film durch die Textflaechen und der Kontrast bricht ein. */
.trust-strip__grid article{background:rgba(10,13,18,.92)}

/* ── Hero-Abgang: stufenlos statt in zwei Sprüngen ───────────────────
   Frueher hing er an zwei Klassen: is-hero-exiting ab 1,8 % Fortschritt
   sprang auf Deckkraft .24, is-beyond-hero ab 7 % auf 0. Bei 420vh
   Gesamtlaenge sind 1,8 % rund 7,6vh - nach einem Zehntel Bildschirm
   sprang der Hero also auf ein Viertel Deckkraft, und zwar zeitgesteuert
   ueber .35s statt scrollgebunden. Genau das fuehlte sich ungenau an:
   kleine Bewegung, grosser Sprung, und danach lief die Animation weiter,
   obwohl man laengst stand.

   Dazu kam eine Luecke: Der Hero war bei 7 % verschwunden, der Text der
   ersten Szene erschien erst bei 12 %. Dazwischen lagen rund 21vh, in
   denen ueberhaupt nichts zu sehen war ausser dem Film.

   Jetzt fuehrt --hero-out den Abgang stufenlos von 0 bis 1 ueber die
   gesamte erste Szene - er ist also genau dann fertig, wenn der naechste
   Text einsetzt. Die Daempfung uebernimmt die Zeichenschleife, deshalb
   hier ausdruecklich transition:none: Eine CSS-Transition wuerde bei
   jedem Einzelbild neu anlaufen und gegen die Daempfung arbeiten.

   translate statt transform, weil transform das Layout des Hero traegt
   und sich je Bildschirmbreite unterscheidet - translateY(-45%) am
   Rechner, none auf dem Telefon. translate ist eine eigene Eigenschaft
   und kommt dem nicht in die Quere. */
.scroll-story .hero-intro{transition:none;opacity:calc(1 - var(--hero-out,0));translate:0 calc(var(--hero-out,0) * -1.4rem);filter:blur(calc(var(--hero-out,0) * 3px))}
.scroll-story.is-hero-weg .hero-intro{pointer-events:none}

/* ── Die Scrollstory scrollt jetzt, statt an Ort und Stelle zu wechseln ──
   Rudolf am 10.08.2026: das Scrollen soll sich im ersten Drittel anfuehlen
   wie ab dem zweiten - die Textbloecke sollen durchscheinend ueber dem Film
   schweben statt ineinander zu blenden.

   Vorher: .story-copy war position:sticky ueber 100vh, .scene-copy lag
   absolut auf halber Hoehe und wurde per Klasse ein- und ausgeblendet. Der
   Film lief, der Text stand - deshalb fuehlte sich der Abschnitt an wie eine
   Diaschau, waehrend ab .after-story alles normal ueber den Film scrollt.

   Jetzt: dieselbe Bauweise wie unten. Die Bloecke stehen im Fluss, jeder
   ungefaehr einen Bildschirm hoch, und tragen denselben durchscheinenden
   Grund wie .after-story - nur etwas leichter (.72 statt .82), weil hier
   der Film die Hauptsache ist.

   Die Klammer um prefers-reduced-motion ist Pflicht: main.css baut fuer
   'reduce' bereits eine ruhige Fassung im Fluss. Ohne Klammer wuerde diese
   Regel sie ueberschreiben - genau die Falle, die in CLAUDE.md steht. */
@media(prefers-reduced-motion:no-preference){
  /* Der Abschnitt ist so hoch wie sein Inhalt. Feste 420vh waren noetig,
     solange nichts im Fluss stand; jetzt bemisst ihn der Text selbst. */
  .scroll-story{height:auto}

  /* Hero wird der erste Block im Fluss statt einer festen Ebene. Ohne das
     ueberlagerte er die nachfolgenden Bloecke. Der Abgang ueber --hero-out
     entfaellt damit: Der Hero scrollt jetzt einfach weg, so wie jeder
     andere Block auch. */
  .scroll-story .hero-intro{
    position:relative;left:auto;right:auto;top:auto;bottom:auto;
    transform:none;translate:none;filter:none;opacity:1;
    z-index:20;pointer-events:auto;
    margin:24vh 0 20vh 8vw;
  }
  .scroll-story.is-hero-weg .hero-intro{pointer-events:auto}

  /* Die Textebene traegt keinen eigenen Versatz mehr - der Scroll macht die
     Bewegung. --copy-drift bleibt unbenutzt stehen; das Skript setzt es
     weiter, es liest nur niemand mehr. */
  .story-copy{
    position:relative;top:auto;height:auto;z-index:20;
    pointer-events:auto;translate:none;padding:0 8vw 12vh;
  }

  /* Jeder Block ein Bildschirm, mittig, mit durchscheinendem Grund.
     .is-active muss mitgenannt werden: main.css setzt dort opacity:1 mit
     hoeherer Spezifitaet, und ohne diese Nennung blieben die uebrigen
     Bloecke unsichtbar. */
  .scroll-story .scene-copy,
  .scroll-story .scene-copy.copy-right,
  .scroll-story .scene-copy.is-active{
    position:relative;left:auto;right:auto;top:auto;bottom:auto;
    transform:none;
    min-height:88vh;display:flex;flex-direction:column;justify-content:center;
    max-width:44rem;padding:3rem 3rem 3.4rem;margin:0 auto 14vh;
    border-radius:1.5rem;
    background:linear-gradient(160deg,rgba(8,11,16,.72),rgba(11,15,21,.66));
    backdrop-filter:blur(14px) saturate(1.05);
    border:1px solid rgba(244,214,125,.10);
    box-shadow:0 2.4rem 5rem rgba(0,0,0,.38);
  }
  /* Der Wechsel links/rechts bleibt - er gibt dem Abschnitt seinen Rhythmus,
     jetzt nur ueber den Aussenabstand statt ueber absolute Verankerung. */
  .scroll-story .scene-copy{margin-right:auto;margin-left:0}
  .scroll-story .scene-copy.copy-right{margin-left:auto;margin-right:0}
  .scroll-story .scene-copy.final-copy{margin-left:auto;margin-right:auto}

  /* Sanft aufblenden beim Hereinscrollen - dasselbe ruhige Verhalten wie
     bei den Abschnitten weiter unten, gesteuert vom Sichtbarkeitswaechter
     im Skript.

     Beide Zustaende nennen alle drei Schreibweisen, und zwar aus einem
     gemessenen Grund: Beim ersten Versuch stand die Ruhelage nur auf
     ".scroll-story .scene-copy" (zwei Klassen), die Grundregel darueber aber
     auch auf ".copy-right" und ".is-active" (drei Klassen). Ergebnis im
     Browser nachgesehen: Die rechts stehenden Bloecke blieben dauerhaft voll
     sichtbar und blendeten nie auf. Gleiche Spezifitaet auf beiden Seiten
     loest das, ohne !important. */
  /* **Ruhezustand .65 statt .34** (24.08.2026). Nachgerechnet ueber dem
     Buehnengrund #0d1118: Bei .34 mischt sich --muted auf #444953, das sind
     2,09:1 - unter jeder Lesbarkeitsgrenze. Bei .65 sind es #767d88 und
     4,56:1, also AA fuer Fliesstext.
     Das ist kein theoretischer Randfall: Ein Block am unteren Bildrand
     bekommt `is-sichtbar` erst zwischen 15 % und 85 % der Fensterhoehe, und
     faellt `scrollstory.js` aus, bleibt der KOMPLETTE Erzaehltext dauerhaft
     im Ruhezustand. Die Auf-Blende bleibt sichtbar, sie startet nur nicht
     mehr aus dem Unlesbaren. */
  .scroll-story .scene-copy,
  .scroll-story .scene-copy.copy-right,
  .scroll-story .scene-copy.is-active{
    opacity:.65;translate:0 1.2rem;
    transition:opacity .5s ease,translate .6s cubic-bezier(.16,1,.3,1);
  }
  .scroll-story .scene-copy.is-sichtbar,
  .scroll-story .scene-copy.copy-right.is-sichtbar,
  .scroll-story .scene-copy.is-active.is-sichtbar{opacity:1;translate:0 0}

  /* Der letzte Block braucht Luft nach unten, sonst klebt .after-story
     unmittelbar daran. */
  .scroll-story .scene-copy.final-copy{margin-bottom:6vh}
}

@media(prefers-reduced-motion:no-preference) and (max-width:760px){
  .scroll-story .hero-intro{padding:0 6vw;min-height:92vh}
  .story-copy{padding:0 6vw 10vh}
  .scroll-story .scene-copy,
  .scroll-story .scene-copy.copy-right,
  .scroll-story .scene-copy.is-active{
    min-height:0;padding:2rem 1.5rem 2.2rem;margin:0 0 10vh;max-width:none;
    border-radius:1.1rem;
  }
}

/* ── Szenenwechsel geschmeidiger ─────────────────────────────────────
   Bis hierher war --scene-progress berechnet, gedaempft und gesetzt - und
   wurde von keiner einzigen Regel gelesen. Die ganze Daempfung je Szene lief
   ins Leere. Zwischen zwei Szenen lag deshalb nur ein Klassenwechsel, nichts
   Scrollgebundenes; der Text stand die gesamte Szene ueber bewegungslos.

   Jetzt traegt .story-copy einen scrollgebundenen Versatz. Bewusst der
   Container und nicht die Textspalte selbst: Deren translate ist schon fuer
   das Ein- und Ausblenden vergeben. Und bewusst ohne transition - die
   Daempfung macht die Zeichenschleife, eine CSS-Transition liefe je
   Einzelbild neu an und arbeitete dagegen. */
@media(prefers-reduced-motion:no-preference){
  .story-copy{translate:0 var(--copy-drift,0px);transition:none}
}

/* Ein- und Ausgang gestaffelt statt gleichzeitig. Vorher begannen beide im
   selben Augenblick, und einen Moment lang standen zwei halbdurchsichtige
   Texte uebereinander - das liest sich als Matsch, nicht als Wechsel. Der
   abgehende Text geht jetzt schneller und ohne Verzoegerung, der kommende
   setzt eine Zehntelsekunde spaeter ein. Daraus wird eine Uebergabe. */
.scene-copy{transition:opacity .3s ease,translate .45s cubic-bezier(.16,1,.3,1)}
.scene-copy.is-active{transition:opacity .5s ease .1s,translate .7s cubic-bezier(.16,1,.3,1) .1s}

/* Die Filme wechseln nur alle zehn Sekunden - da darf die Ueberblendung
   ruhig laenger sein als die frueheren .55s. Der Wert .9s steht zusaetzlich
   als UEBERBLENDUNG in scrollstory.js; wer ihn hier aendert, aendert ihn dort
   mit, sonst passen Aufraeumen und Bildwechsel nicht mehr zusammen. */
.scene-video{transition:opacity .9s ease,transform .9s cubic-bezier(.16,1,.3,1)}

/* ── Warum der Wechsel frueher schwarz aufblitzte ────────────────────
   Alle drei Filme lagen auf derselben z-Ebene. Beim Wechsel blendete der
   abgehende aus, waehrend der ankommende einblendete. In der Mitte stand
   also beides bei Deckkraft .5, und was zusammenkam, war nicht 1, sondern
   .5*neu + .25*alt - der fehlende Rest war der dunkle Buehnengrund. Genau
   das sah man als kurzes schwarzes Aufleuchten.

   Jetzt blendet nur noch der ankommende Film ein. Der abgehende bleibt
   waehrenddessen voll sichtbar darunter stehen und laeuft weiter, bis der
   neue ihn vollstaendig deckt. Die Summe der Deckkraft ist damit zu jedem
   Zeitpunkt 1, und weil beide Filme dabei laufen, steht auch kein Standbild
   im Bild. Das Aufraeumen uebernimmt scrollstory.js nach .9s.

   Die z-Werte muessen ausdruecklich gesetzt sein: Ohne sie entschiede die
   Reihenfolge im Dokument, und beim Sprung vom letzten zum ersten Film laege
   der abgehende oben statt unten. */
.scene-video.is-active.is-playable{z-index:4}
.scene-video.is-vorgaenger.is-playable{opacity:1;transform:scale(1);transition:none;z-index:3}

/* ── Neues Markenzeichen im Header ───────────────────────────────────
   Das W aus dem Markenpaket hat ein Seitenverhaeltnis von 729:467, also
   rund 1,56:1 - es ist deutlich breiter als hoch. Der Kasten war bisher
   quadratisch (2,2rem), gedacht fuer das alte Sechseck. Ein breites
   Zeichen darin haette sich auf 2,2 x 1,41rem eingepasst und damit
   kleiner gewirkt als das, was es ersetzt.
   Der Kasten traegt jetzt dasselbe Verhaeltnis, das Zeichen fuellt ihn
   ohne Rand: 3,12 / 2 = 1,56. */
.brand-mark{width:3.12rem;height:2rem}
@media(max-width:760px){.brand-mark{width:2.65rem;height:1.7rem}}


/* Kundenbewertungen - uebernimmt Raster und Flaechen der trust-strip, damit der
   Abschnitt sich nahtlos einfuegt: 3 Spalten, 1px Haarlinie, gleiche Kachelfarbe. */
.reviews{position:relative;z-index:25;padding:0 8vw 6rem;background:#080b10}
.reviews__grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--line);margin-top:1.9rem}
.reviews__grid article{background:#0a0d12;padding:1.7rem;display:flex;flex-direction:column}
.reviews__stars{margin:0;color:var(--gold);letter-spacing:.2em;font-size:.8rem}
.reviews__quote{margin:.9rem 0 1.4rem;padding:0;border:0;color:var(--paper);font-size:.92rem;line-height:1.72}
.reviews__author{margin:auto 0 0;color:var(--muted);font-size:.78rem;font-style:normal}
.reviews__source{margin:1.7rem 0 0;color:var(--muted);font-size:.75rem;line-height:1.6}
@media(max-width:900px){.reviews{padding-left:6vw;padding-right:6vw}.reviews__grid{grid-template-columns:1fr}}

/* Claim in der Fusszeile. Greift die Augenbrauen-Behandlung der Seite auf
   (Versalien, gesperrt, helles Gold), damit er als Aussage gelesen wird und
   nicht als Teil der Copyright-Zeile. */
.site-footer .footer-claim{display:block;margin:0 0 .45rem;color:var(--gold-light);font-weight:700;font-size:.66rem;letter-spacing:.14em;text-transform:uppercase}

/* Kontaktkarten - loesen die rohen Textzeilen ab. Das Zeichen traegt die
   Aufmerksamkeit, der Wert bleibt lesbar: eine Rufnummer, die man nicht
   abschreiben kann, kostet Anrufe. Zeichen sind selbst gezeichnet, weil die
   CSP kein Nachladen von fremden Quellen erlaubt. */
.kontakt-karten{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1rem;margin-top:1.9rem;max-width:54rem}
.kontakt-karte{display:flex;flex-direction:column;gap:.5rem;padding:1.5rem 1.4rem;text-decoration:none;color:var(--paper);background:rgba(240,243,247,.035);border:1px solid var(--line);border-radius:1rem;transition:border-color .25s ease,background .25s ease,transform .25s cubic-bezier(.16,1,.3,1)}
.kontakt-karte:hover,.kontakt-karte:focus-visible{border-color:rgba(212,168,67,.45);background:rgba(212,168,67,.07);transform:translateY(-3px)}
.kontakt-karte:focus-visible{outline:3px solid var(--gold);outline-offset:3px}
.kontakt-karte__zeichen{display:grid;place-items:center;width:2.7rem;height:2.7rem;margin-bottom:.35rem;border-radius:.8rem;background:rgba(212,168,67,.12);color:var(--gold)}
.kontakt-karte__zeichen svg{display:block;width:1.35rem;height:1.35rem}
.kontakt-karte__art{color:var(--gold-light);font-size:.64rem;font-weight:700;letter-spacing:.16em;text-transform:uppercase}
.kontakt-karte__wert{font-size:.98rem;font-weight:800;line-height:1.35;overflow-wrap:anywhere}
/* Das Telefon ist der Hauptweg eines Handwerksbetriebs und wird hervorgehoben. */
.kontakt-karte--haupt{background:rgba(212,168,67,.1);border-color:rgba(212,168,67,.34)}
.kontakt-karte--haupt .kontakt-karte__zeichen{background:var(--gold);color:var(--ink)}
.kontakt-karte--haupt .kontakt-karte__wert{color:var(--gold-light)}
@media(max-width:760px){.kontakt-karten{grid-template-columns:1fr;gap:.8rem;margin-top:1.5rem}.kontakt-karte{padding:1.2rem 1.2rem}}

/* ── Reduzierte Bewegung: zwei Luecken geschlossen (24.08.2026) ──────────
   Beide gefunden im ECC-Durchgang, beide an der Kaskade nachgewiesen.
   energy-overrides.css laedt nach main.css, deshalb genuegt hier gleiche
   Spezifitaet. */
@media(prefers-reduced-motion:reduce){
  /* 1 - Der Hero blieb `fixed`. main.css setzt `.hero-intro` unbedingt auf
     position:fixed mit z-index:14; der Reset in die Flussfassung steht in
     dieser Datei INNERHALB von @media(prefers-reduced-motion:no-preference)
     und griff bei 'reduce' deshalb nie. Folge: Die Hero-Karte klebte fest
     ueber dem ersten Szenentext und blendete beim Scrollen auf opacity:0 -
     ihre beiden Links blieben aber im Tab-Ablauf, weil opacity:0 nichts aus
     der Fokusreihenfolge nimmt und pointer-events:none nur die Maus abhaelt.
     Ein Tastaturnutzer verlor seinen Fokus zweimal an unsichtbare Ziele.
     Getroffen hat das ausgerechnet die, die die Einstellung brauchen. */
  .scroll-story .hero-intro{
    position:relative;left:auto;right:auto;top:auto;bottom:auto;
    transform:none;translate:none;filter:none;opacity:1;
    z-index:20;pointer-events:auto;
    margin:24vh 0 20vh 8vw;
  }

  /* 2 - Die Buehne blieb leer. main.css rettet in seinem reduce-Block
     `.scene-art.scene-0{display:block;opacity:1}`, schaltet dieselbe Regel
     aber SPAETER im Stylesheet bei gleicher Spezifitaet wieder ab - und zwar
     ausserhalb jeder Media-Query, weshalb sie gewinnt. Uebrig blieben rund
     416 px dunkles Nichts ueber dem Text. Steht seit dem 01.08.2026 in
     BEFUNDE-SCROLLSTORY.md Punkt 2 und war der letzte offene Punkt daraus. */
  .scroll-story .scene-art.scene-0{display:block;opacity:1}
}

/* ── Szenenleiste: KI-Kennzeichnung am Motiv + Halt-Knopf (24.08.2026) ────
   Fest am unteren Rand, solange Filme laufen. Der Grund ist deckend genug,
   dass beides ueber JEDEM Videoinhalt lesbar bleibt - genau der Fehler, den
   die Kopfzeile in den ersten 32 px noch macht: --muted auf hellem Bild ergibt
   1,95:1. Hier gerechnet: --paper #f0f3f7 auf #0b0f15 bei .92 Deckkraft
   ergibt ueber 15:1, unabhaengig vom Film dahinter. */
.szenen-leiste{
  position:fixed;left:1rem;bottom:1rem;z-index:16;
  display:flex;align-items:center;gap:.7rem;flex-wrap:wrap;
  padding:.5rem .7rem;border-radius:.7rem;
  background:rgba(11,15,21,.92);
  border:1px solid rgba(240,243,247,.22);
  box-shadow:0 10px 30px rgba(5,6,8,.45);
  max-width:calc(100vw - 2rem);
}
.szenen-leiste[hidden]{display:none}
.szenen-leiste__hinweis{
  margin:0;color:var(--paper);font-size:.72rem;letter-spacing:.04em;line-height:1.3;
}
.szenen-leiste__hinweis b{font-weight:800}
.szenen-leiste__knopf{
  /* 24 px Zielgroesse nach WCAG 2.2 SC 2.5.8, ohne das Layout zu sprengen. */
  min-height:1.75rem;padding:.25rem .7rem;
  border-radius:999px;border:1px solid rgba(240,243,247,.5);
  background:transparent;color:var(--paper);
  font:inherit;font-size:.7rem;font-weight:700;letter-spacing:.04em;
  cursor:pointer;
}
.szenen-leiste__knopf:hover{background:rgba(240,243,247,.12)}
.szenen-leiste__knopf:focus-visible{outline:2px solid var(--gold);outline-offset:2px}

/* Auf schmalen Geraeten unter den Hinweis, damit nichts abgeschnitten wird. */
@media(max-width:420px){
  .szenen-leiste{left:.6rem;right:.6rem;bottom:.6rem;justify-content:space-between}
}

/* Bei reduzierter Bewegung laeuft ohnehin kein Film - dann ist die Leiste
   gegenstandslos. scrollstory.js zeigt sie in dem Fall gar nicht erst. */

/* ── Nur fuer Screenreader (24.08.2026) ──────────────────────────────────
   Gebraucht fuer die Sternebewertungen. Dort stand `aria-label` auf einem
   <p>; dessen implizite Rolle ist `paragraph`, und fuer die verbietet die
   ARIA-Spezifikation die Benennung durch den Autor - Browser und
   Screenreader ignorieren das Attribut vollstaendig. Vorgelesen wurde
   stattdessen der rohe Inhalt, je nach Programm fuenfmal "schwarzer Stern"
   oder gar nichts. Bei einem Handwerksbetrieb ist die Bewertung das
   staerkste Vertrauenssignal der Seite.
   Kein `display:none` und kein `visibility:hidden` - beides nimmt den Text
   auch dem Screenreader. */
.nur-vorlesen{
  position:absolute;width:1px;height:1px;
  margin:-1px;padding:0;border:0;
  clip-path:inset(50%);overflow:hidden;white-space:nowrap;
}

/* ── Kopfzeile: die ersten 32 px waren ungeschuetzt (24.08.2026) ─────────
   `.site-header` ist transparent, `.is-scrolled` bringt den Grund erst ab
   scrollY > 32. Bis dahin trug nur `backdrop-filter:saturate(1.05)` - das
   aendert die Saettigung, nicht die Helligkeit. Genau das ist das erste Bild,
   das jeder Besucher sieht.

   Gerechnet ueber weissem Videoinhalt (haerteste Annahme): Navigationslinks
   (--muted #aeb7c5, 11,04 px) lagen bei 2,02:1, der Markenschriftzug
   (--paper) bei 1,11:1 - also unsichtbar.

   KORRIGIERT am selben Tag. Die erste Fassung (.88/.80/.42/0 bei 0/55/85/100)
   war zu schwach, und die Zahlen daneben waren falsch. Zwei eigene Fehler:

   1. Ich hatte --muted als #9fb0c0 gerechnet. Es ist #aeb7c5 - geraten statt
      in main.css nachgelesen.
   2. Gemessen hatte ich den KASTEN der Navigationspille, nicht die Glyphen.
      Der Innenabstand von .55rem oben und unten traegt keinen Text; die
      Deckkraft am Kastenrand ist also nicht die, unter der die Schrift steht.

   Im Browser nachgemessen (Range.getClientRects auf die Textknoten, gegen die
   Kopfzeilenhoehe von 69 px): Die Glyphen liegen zwischen 28,0 % und 67,7 %.
   Bei 67,7 % war der alte Verlauf schon auf .639 abgefallen. Ergebnis dort:
   "WEBER" (--gold) 2,85:1 und die Navigationslinks 4,19:1 - beide unter 4,5.
   Nur "ELEKTRO" (--paper, fett) lag mit 11,03:1 sicher.

   Noetig sind rechnerisch .760 fuer das Gold und .755 fuer --muted. Der
   Verlauf haelt deshalb jetzt bis 70 % - also ueber den gesamten Textbereich -
   und faellt erst darunter ab. Damit: ELEKTRO 12,40:1, WEBER 5,79:1,
   Navigationslinks 5,98:1. Der CTA-Text steht auf eigener Goldflaeche und ist
   vom Schleier unabhaengig (9,15:1).

   Bewusst weiterhin ein Verlauf und keine Flaeche: Er deckt dort, wo Text
   steht, und laeuft darunter aus, damit die Hero-Ansicht ihre Leichtigkeit
   behaelt. `.is-scrolled` (Spezifitaet 0,2,0) schlaegt diese Regel wie bisher
   und bringt die volle Flaeche.

   WER HIER ETWAS AENDERT: Die Prozentwerte haengen an der gemessenen Lage der
   Glyphen. Wird die Kopfzeile hoeher, die Schrift groesser oder der
   Innenabstand anders, muss die Lage neu gemessen werden - nicht geschaetzt. */
.site-header{
  background:linear-gradient(180deg,
    rgba(5,6,8,.90) 0%,
    rgba(5,6,8,.82) 70%,
    rgba(5,6,8,.40) 90%,
    rgba(5,6,8,0) 100%);
}

/* ── Reflow bei 320 px / 400 % Zoom (24.08.2026) ─────────────────────────
   `body{overflow-x:hidden}` heisst: Was ueberlaeuft, ist nicht wegscrollbar,
   sondern weg. Die Ueberschriften hoeren aber unterhalb einer bestimmten
   Breite auf zu schrumpfen, weil das clamp()-Minimum in rem steht - die
   Hero-h1 friert unter 341 px bei 51,2 px ein. Bei 320 px CSS-Breite (das ist
   der Pruefwert fuer SC 1.4.10, entspricht 400 % Zoom auf 1280 px) bleiben
   rund 251 px nutzbare Breite: "Energie fuer" passt nicht mehr hinein und
   laeuft unsichtbar aus dem Bild.
   main.css ist minifiziert und bleibt unangetastet; hier reicht ein
   Minimum, das kleiner ist als der eingefrorene Wert. */
@media(max-width:360px){
  .hero-intro h1{font-size:clamp(2.1rem,14vw,3.2rem)}
  .scene-copy h1{font-size:clamp(2.1rem,14vw,3.4rem)}
  .scene-copy h2,.scroll-story h2{font-size:clamp(1.8rem,11vw,2.5rem)}

  /* Deutsche Komposita sind laenger als die Box. GEMESSEN bei 320 px:
     "Unabhaengigkeit" braucht bei 35,2 px rund 250 px, verfuegbar sind 232 -
     der Rest stand ueber der Kartenkante. Die Regel galt vorher nur fuer h1;
     der Ueberlaeufer war ein h2.
     `hyphens:auto` zuerst, damit an Silbengrenzen mit Trennstrich getrennt
     wird (das Dokument traegt lang="de", sonst faende der Browser die
     Grenzen nicht). `break-word` greift nur, wenn das immer noch nicht
     reicht - und anders als `anywhere` verschiebt es die min-content-Breite
     nicht, das Layout drumherum bleibt also, wie es war. */
  h1,h2,h3{hyphens:auto;overflow-wrap:break-word}

  /* Dasselbe fuer den Fliesstext. Die Regel galt zuerst nur den
     Ueberschriften - beim Nachmessen aller Seiten lief dann ein <strong> mit
     "Isolationswiderstand, Schleifenimpedanz ..." auf pruefungen.html um
     13 px ueber seinen Kasten. Fachbegriffe sind auf dieser Website die
     laengsten Woerter ueberhaupt, und sie stehen im Text, nicht in den
     Ueberschriften. */
  p,li,strong,b,em,small,figcaption,dd,dt,td,th{hyphens:auto;overflow-wrap:break-word}
}

/* Die Hero-Karte im Fluss stand rechts buendig am Sichtfensterrand.
   Beide Motion-Bloecke oben setzen `margin:24vh 0 20vh 8vw` - links 8vw,
   rechts NULL. Solange die Karte breiter werden darf als ihr Inhalt (also
   unterhalb von rund 713 px, wo `max-width:41rem` nicht mehr greift), endet
   sie damit exakt auf der Sichtfensterkante. Darueber hinaus ragt
   `.hero-intro::after` - eine dekorative Lichtkugel mit `right:-1rem`.

   GEMESSEN am 24.08.2026 bei 320 px: document.scrollWidth 335 statt 320,
   also 15 px waagrechter Scroll auf der Startseite. Weder ein Element noch
   ein Textlauf ragte heraus - deshalb sah es keine der ueblichen Pruefungen;
   ein Pseudo-Element steht in keiner Knotenliste. Gefunden ueber
   scrollWidth/clientWidth je Knoten und getComputedStyle(el,'::after').

   Rechts denselben Abstand wie links, und die Kugel bleibt drin: bei 320 px
   endet die Karte auf 300,8 px, die Kugel auf 316,8 px. Der Wert 6vw statt
   8vw stammt aus dem Mobilblock von main.css - so bleibt die Karte trotz
   des zweiten Randes so breit wie bisher.
   Spezifitaet 0,2,0 wie die beiden Motion-Bloecke; diese Regel steht
   spaeter und gewinnt deshalb in beiden Pfaden - mit und ohne
   reduzierte Bewegung. */
@media(max-width:760px){
  .scroll-story .hero-intro{margin-left:6vw;margin-right:6vw}
}
