/* Startseite (die generischen .hero/.hero__bg/.hero__scrim/.hero__content/
   .hero__eyebrow-Basisregeln liegen in base.css - jede Seite mit dunklem
   Hero-Bild nutzt sie, nicht nur die Startseite) */

/* ---------------------------------------------------------------------------
   Hero der Startseite. Saemtliche Werte sind per getComputedStyle am Original
   gemessen (/opt/tooling/home-hero-*.mjs, Viewports 1440/1200/1199/1000/810/
   809/768/480/390/320) - nichts geschaetzt. Messtabelle: docs/qa/hero-startseite/.

   Der Hero ist eine ZENTRIERTE Flex-Spalte: Eyebrow + h1 stehen mittig ueber
   die volle Breite, nicht linksbuendig in einem 1200er-Container. Genau das
   war die Hauptabweichung (h1 im Original text-align:center/left=0/width=1440,
   bei uns text-align:start/left=144/width=1152).
   --------------------------------------------------------------------------- */

/* Im Original beginnt das Hero-Foto an der DOKUMENTOBERKANTE (y=0); sowohl
   Ankuendigungsleiste als auch Kopfzeile sind `fixed` und liegen darueber,
   ohne es nach unten zu schieben. Nachgemessen @1440: Hero-Sektion
   y=0 1440x925, Foto und Abdunkler deckungsgleich 1440x925.
   Seit Leiste und Kopfzeile auch bei uns `fixed` sind (base.css), deckt sich
   das ohne Verschiebung - die frueheren -69px entfallen. */
/* Foto laeuft 1:1 mit dem Scroll wie im Original (keine Parallaxe). */
.hero--home { overflow: hidden; min-height: 100vh; }

.hero__content {
  display: flex; flex-direction: column; align-items: center;
  gap: 74px;                      /* Original: gap zwischen Intro/Karten/Partnerleiste */
  padding: 222px 0 69px;          /* Original: Inhaltsblock beginnt bei y=222 */
  text-align: center;
  width: 100%;
}
.hero__intro {
  display: flex; flex-direction: column; align-items: stretch;
  gap: 15px;                      /* Original: Abstand Eyebrow -> h1 */
  width: 100%;
}
.hero__intro .hero__eyebrow { max-width: none; margin: 0; }
.hero__intro .hero__title { margin: 0; }

/* Kartenreihe. Das Original hat links im Flex-Container einen 5px breiten
   Phantom-Platzhalter (Framer-Artefakt) plus 23px gap, wodurch die Reihe um
   28px nach rechts versetzt liegt (links 97px, rechts 69px). Statt den
   Platzhalter nachzubauen ist der Versatz hier direkt als asymmetrisches
   Padding notiert - damit stimmen Kartenbreite (626px @1440, 506px @1200)
   und beide Aussenkanten exakt mit dem Original ueberein. */
.hero__cards {
  display: flex; gap: 23px; width: 100%;
  padding: 0 69px 0 97px;
  justify-content: center; align-items: flex-start;
}
.hero-card {
  /* FESTE Hoehe, nicht min-height: im Original sind beide Karten exakt 250px
     hoch, obwohl der dreizeilige Text der zweiten Karte rechnerisch 253px
     braucht (er ragt dort minimal ins untere Padding). Mit min-height wuchs
     unsere zweite Karte auf 253px und schob Partnerleiste, Scroll-Hinweis und
     den gesamten Rest der Seite um 3px nach unten. */
  flex: 1 1 0; min-width: 0; height: 250px;
  display: flex; flex-direction: column; align-items: flex-start; gap: 18px;
  /* Original: weiches Milchglas OHNE Rahmen. Der bisherige 1px-Rahmen und der
     deutlich dunklere Fond (rgba(17,17,17,.55)) liessen die Karten flach und
     kastig wirken. */
  background: rgba(255,255,255,.09);
  -webkit-backdrop-filter: blur(74px);
  backdrop-filter: blur(74px);
  border: 0;
  border-radius: 18px;
  padding: 47px;
  text-align: left;
}
/* Hover-Sweep 2026-07: das Original laesst die Milchglas-Karten beim Hover
   VOLLSTAENDIG ruhig (per getComputedStyle vorher/nachher belegt, nur der
   Pfeil des "Mehr erfahren"-Links bewegt sich). Die fruehere Anhebung
   (translateY(-4px) + hellerer Fond + Schatten) war erfunden und auffaellig -
   entfernt. */
.hero-card p { color: #fff; margin: 0; }
.hero-card .link-arrow { margin: 0; }
.hero-card__logo { display: block; width: auto; height: auto; margin: 0; object-fit: contain; }
.hero-card__logo--ews { width: 342px; }
.hero-card__logo--fas { width: 339px; }

/* Partnerleiste: im Original eine kompakte, zentrierte Milchglas-Pille mit den
   echten Partnerlogos (Telekom, EDAG, Freistaat Bayern, Land Hessen) - nicht
   die bisherigen grauen Text-Pillen. Alle vier Assets liegen lokal unter
   web/static/img/partner/ und werden ueber das bestehende //go:embed static
   ausgeliefert (keine externen Referenzen). */
.hero__partnerbar {
  display: flex; align-items: center; gap: 10px;
  /* Feste Hoehe 70px wie im Original. Die hoeheren Logos (Telekom 60px,
     Hessen 55px) ragen dabei bewusst ueber das 30px hohe Innenmass hinaus -
     bei symmetrischem Padding bleiben sie exakt auf der Mitte der 70px-Leiste,
     genau wie im Original. */
  height: 70px;
  background: rgba(255,255,255,.09);
  -webkit-backdrop-filter: blur(75px);
  backdrop-filter: blur(75px);
  border-radius: 5px;
  padding: 20px;
}
.hero__partnerbar-label {
  font-family: var(--font-accent); font-weight: var(--fw-bold);
  font-size: 16px; line-height: 1.2; color: #fff; margin: 0; white-space: nowrap;
}
.partner-logo { display: block; flex: 0 0 auto;
  transition: transform var(--duration-hover) var(--ease-smooth); }
/* Original (gemessen): die vier Hero-Partnerlogos skalieren beim Hover auf
   1.1 (matrix(1.1,...)), keine Anhebung, keine Transparenz. */
.partner-logo:hover { transform: scale(1.1); }
.partner-logo img { display: block; }
.partner-logo--telekom img { width: 50px; height: 60px; object-fit: cover; }
.partner-logo--edag   img { width: 86px; height: 28px; object-fit: cover; }
.partner-logo--bayern img { width: 36px; height: 41px; object-fit: contain; }
.partner-logo--hessen img { width: 49px; height: 55px; object-fit: contain; }

/* "Scrollen" sitzt im Original unten rechts auf derselben Grundlinie wie die
   Partnerleiste (beide enden 69px ueber der Hero-Unterkante) und erscheint
   erst ab 1200px. Aufbau (nachgemessen 2026-07-28): Text 15/22.5, dann 15px
   Luecke, dann der 12x20-SVG-Pfeil senkrecht nach unten (Gesamtbreite 85px,
   Endkante x=1371 @1440). Der Pfeil traegt einen Dauer-Bounce: ~1s Ruhe,
   dann 13px hoch, 14px runter, zurueck (Zyklus ~2.5s). */
.hero__scroll-hint {
  position: absolute; right: 69px; bottom: 69px; z-index: 2;
  display: flex; align-items: center; gap: 15px;
  font-size: var(--fs-body); line-height: var(--lh-body); color: #fff;
  transition: color var(--duration-hover) var(--ease-smooth);
}
.hero__scroll-arrow { display: block; width: 12px; height: 20px; }
.hero__scroll-arrow svg { display: block; width: 12px; height: 20px; }
.hero__scroll-arrow { animation: scroll-bob 2.5s ease-in-out infinite; }
@keyframes scroll-bob {
  0%, 40% { transform: none; }
  60%     { transform: translateY(-13px); }
  80%     { transform: translateY(14px); }
  100%    { transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .hero__scroll-arrow { animation: none; }
}
/* Original (gemessen): "Scrollen" dunkelt beim Hover von Weiss auf
   rgb(201,201,201) ab (Framers Standard-Hover fuer weisse Textlinks);
   der Pfeil wechselt auf seine C9C9C9-Variante (SVG-Swap im Original,
   hier schlicht currentColor). */
.hero__scroll-hint:hover { color: rgb(201,201,201); }

/* Loesungs-Blocklogo (ews/fas) - wird in den Loesungs-Textbloecken genutzt. */
.solution-logo { height: 24px; width: auto; margin-bottom: var(--space-4); }

/* ---------------------------------------------------------------------------
   Loesungs-Sektion: Original-Topologie (docs/qa/scroll-spec.md 4a).
   EINE Zeile: links Textspalte mit zwei gestapelten Textbloecken (ews/fas),
   rechts EINE gepinnte (position:sticky) Medienspalte 642x420, die beim
   Scrollen scroll-gekoppelt vom ews-Luftbild (mit Flutsimulation) zur
   fas-Nachtszene ueberblendet. Der Pin ist rein CSS (position:sticky); der
   Crossfade wird in main.js scroll-gekoppelt und rAF-gedrosselt gesetzt.
   --------------------------------------------------------------------------- */

/* Basis (alle Breiten): die Inline-Medien in den Textbloecken sind nur mobil
   sichtbar, die sticky Medienspalte nur ab 1200px (s. Media-Queries unten). */
.loesung-block__media { margin-top: var(--space-5); position: relative; }
.loesung-block__media img {
  display: block; width: 100%; height: auto; border-radius: 18px; object-fit: cover;
}
/* Skala-Legende auf dem Gefahrenkarten-Medium: im Original ein Lottie-SVG
   81x123,1 mit je 23px Abstand zum rechten/unteren Bildrand (relX 538 /
   relY 273,9 im 642x420-Medium, @390 wie @1440 identisch). Selektor mit
   img-Anteil + Resets, damit die generischen .loesung-block__media-img-Regeln
   (width 642, margin-left, object-fit) die Legende nicht erfassen. */
.loesung-block__media img.loesung-legende, img.loesung-legende {
  position: absolute; right: 23px; bottom: 23px;
  width: 81px; height: 123.1px; max-width: none; margin: 0;
  object-fit: fill; border-radius: 0; pointer-events: none;
}

@media (min-width: 1200px) {
  /* Zeile: Textspalte 324 + 96 gap + Medienspalte 642 = 1062, zentriert -
     dieselben Masse wie das Original (642x420-Medium). */
  .loesung-scroll {
    display: grid; grid-template-columns: 324px 642px; column-gap: 96px;
    align-items: start; max-width: 1062px; margin: 0 auto;
    padding: var(--space-6) 0;
  }
  /* Linke Spalte: zwei gestapelte Textbloecke. Der grosse Abstand zwischen den
     Bloecken traegt die Pin-Strecke (~530px im Original) - die Spalte wird
     dadurch hoch genug, dass die sticky Medienflaeche lange stehen bleibt.
     165 statt 210: der ews-Absatz hat jetzt den vollstaendigen Originaltext
     (2 Inter-Zeilen = 45px mehr) - der Gap gibt die 45px wieder her, damit
     fas-Block, Pin-Strecke und alle Abschnitte darunter exakt auf den
     verifizierten Desktop-Positionen bleiben. */
  .loesung-text { display: flex; flex-direction: column; gap: 165px; }
  .loesung-block { display: flex; flex-direction: column; align-items: flex-start; }
  /* Inline-Medien der Textbloecke: auf Desktop verborgen (Medium steht rechts). */
  .loesung-block__media { display: none; }

  /* Rechte Medienspalte: Zelle fuellt die volle Zeilenhoehe (align stretch via
     eigenem Grid-Item), darin die sticky 642x420-Flaeche. */
  .loesung-media { position: relative; height: 100%; }
  .loesung-media__sticky {
    position: -webkit-sticky; position: sticky;
    /* top = Ankuendigungsleiste (69) + Kopfzeile (74) + 4 Luft = 147, wie das
       Original. Zur Laufzeit gegen die echten fixen Hoehen verifiziert. */
    top: 147px;
    width: 642px; height: 420px; border-radius: 18px; overflow: hidden;
    background: rgb(232,232,232);
  }
  .loesung-media__img {
    position: absolute; inset: 0;
    width: 642px; height: 420px; object-fit: cover; display: block;
    will-change: opacity;
  }
  /* Startzustand vor JS: ews voll sichtbar, fas verdeckt (JS scrubt --loesung-x
     0..1 und blendet ueber; ohne JS bleibt ews sichtbar - sinnvoller Fallback). */
  .loesung-media__img--ews { opacity: 1; }
  .loesung-media__img--fas { opacity: 0; }
  .js-loesung .loesung-media__img--ews { opacity: calc(1 - var(--loesung-x, 0)); }
  .js-loesung .loesung-media__img--fas { opacity: var(--loesung-x, 0); }
  /* Die Skala-Legende gehoert zur ews-Ebene und blendet mit ihr aus. */
  .js-loesung .loesung-media__legende { opacity: calc(1 - var(--loesung-x, 0)); }
}

/* prefers-reduced-motion: kein Pin-Zwang, kein Crossfade-Scrubbing. Beide
   Medien statisch und sinnvoll sichtbar - hier gestapelt untereinander. */
@media (min-width: 1200px) and (prefers-reduced-motion: reduce) {
  .loesung-media__sticky {
    position: static; width: 642px; height: auto; background: transparent;
    border-radius: 0; overflow: visible;
    display: flex; flex-direction: column; gap: var(--space-6);
  }
  .loesung-media__img {
    position: static; width: 642px; height: 420px; opacity: 1 !important;
    border-radius: 18px;
  }
}

/* Original (1440): Videoreihe in einer 1062px-Spalte (x=189..1251), drei
   Kacheln je 342x192 (16:9), Spaltenabstand 18px, Zeilenabstand 0 - je
   Zeile 243px hoch (Kachel 192 + 15px + Bildunterschrift 36). Vorher lag
   das Raster in der vollen 1152px-Spalte mit 368px-Kacheln, wodurch die
   Highlights-Sektion ~140px zu hoch war und alle Abschnitte darunter
   verschob. */
/* Highlights beginnt 123px unter dem Hero (Original: H2 y=1048, Hero
   endet 925) - die sitewide 96px liessen die ganze Sektion und alles
   darunter 27px zu hoch sitzen. */
.section--highlights { padding-top: 123px; }
/* Desktop-only: der groessere Zeilenabstand der Videoreihe (row-gap 22 +
   margin-top 62 statt 0/51) macht die Highlights-Sektion 55px hoeher; das
   wird hier unter dem Raster wieder abgezogen, damit alle Abschnitte darunter
   (Loesungen ff.) ihre y-Position gegen das Original behalten. Nur >=1200px -
   die Mobilansicht (<1200px) behaelt ihre 96px. */
@media (min-width: 1200px) {
  .section--highlights { padding-bottom: 10.5px; }

  /* Sektionskopf-Rhythmus, am Original @1440 per getBoundingClientRect
     verankert (anchors-Lauf 2026-07-28): H2 -21- Intro -23- Knopf (47px hoch);
     die CTA-Sektion hat nur 15px unter der H2; die beiden Loesungs-Intros
     stehen 22.5px auseinander. Alle weissen Pill-Buttons sind 47px hoch
     (Polster 11px), nicht 49. */
  .section--highlights h2, .section--loesungen h2, .section--referenzen h2,
  .section--forschung h2, .section--partner h2 { margin-bottom: 21px; }
  .section--cta h2 { margin-bottom: 15px; }
  .section--highlights .section-intro,
  .section--referenzen .section-intro { margin-bottom: 23px; }
  .section--loesungen .section-intro { margin-bottom: 22.5px; }
  /* Pill-Buttons exakt 46.5px hoch wie im Original (Announce-Knopf,
     "Video"-Chip und Sektionsknoepfe alle 46.5 gemessen); height statt
     Polster, damit auch der Video-Chip mit Play-Glyphe nicht aufgeht. */
  main .section .btn { padding-top: 11px; padding-bottom: 11px; height: 46.5px; box-sizing: border-box; }

  /* Loesungs-Spalte: Intro2-Ende -74- ews-Logo (Logo 324px breit, Hoehe auto:
     ews 25.6, fas 31.5 - vorher auf 24px gedeckelt und damit zu klein);
     Logo -21- Absatz -23- Knopf; Block1-Ende -122.5- fas-Logo. */
  .loesung-scroll { padding-top: 51.5px; padding-bottom: 8.5px; }
  .loesung-text { gap: 122.5px; }
  .loesung-block .solution-logo { width: 324px; height: auto; margin-bottom: 21px; }
  .loesung-block p { margin: 0 0 23px; }

  /* FORSCHUNG Desktop: Zeile 396 + 69 gap + 597 = 1062, zentriert bei x=189
     (Original). Das .container-Seitenpolster wuerde die Spalte auf x=213
     schieben - deshalb hier auf 0. */
  .forschung-block {
    display: grid; grid-template-columns: 396px 597px; column-gap: 69px;
    align-items: start;
    padding-left: 0; padding-right: 0;
  }
  /* Akkordeon-Verhalten wie das Live-Original (Messlauf 2026-07-28): das
     AKTIVE Projekt ist aufgeklappt (Beschreibung 396px, 3 Zeilen), sobald der
     Auto-Zyklus laeuft (.forschung-accordion.is-running, home-forschung.js);
     vor dem ersten Scroll-Kontakt bleibt alles eingeklappt - wie das Original
     (und wie seine Ganzseiten-Captures). Titel-Hover #818181 -> #333. */
  .forschung-item__desc {
    display: block; max-height: 0; overflow: hidden; opacity: 0; margin-top: 0;
    transition: max-height .4s var(--ease-smooth), opacity .4s var(--ease-smooth),
                margin-top .4s var(--ease-smooth);
  }
  .forschung-accordion.is-running .forschung-item.is-active .forschung-item__desc {
    max-height: 90px; opacity: 1; margin-top: 26px;
  }
  /* Pfeil des aktiven Projekts zeigt im laufenden Zyklus nach OBEN. */
  .forschung-accordion.is-running .forschung-item.is-active .forschung-item__chevron {
    transform: rotate(-135deg);
  }
  .forschung-item:hover .forschung-item__title { color: var(--color-text); }
  /* VOR dem Zyklusstart sind im Original ALLE Titel grau (Pixelprobe
     2026-07-28: 5GNPR rgb(129,129,129) im Ruhezustand) - erst der laufende
     Zyklus hebt das aktive Projekt dunkel hervor. */
  .forschung-accordion:not(.is-running) .forschung-item.is-active .forschung-item__title { color: var(--color-text-muted); }
  .forschung-accordion:not(.is-running) .forschung-item.is-active:hover .forschung-item__title { color: var(--color-text); }
  /* Rechte Medienspalte: portraetiert 597x747, r18. Die Fotos blenden erst
     mit Start des Zyklus ein (vorher: Projektlogo auf Weiss - deckungsgleich
     mit den Original-Captures) und zoomen dann langsam (Ken-Burns auf ~1.25
     in 15s, linear - am Original gemessen: 597 -> ~692px Bildbreite in 11s). */
  .forschung-block__media {
    width: 597px; height: 747px; border-radius: 18px; overflow: hidden;
    background: transparent;
  }
  .forschung-media__photo {
    opacity: 0; transform: scale(1);
    transition: opacity .8s var(--ease-smooth);
    will-change: transform, opacity;
  }
  .forschung-block__media.is-running .forschung-media__card.is-active .forschung-media__photo {
    opacity: 1;
  }
  .forschung-block__media.is-running .forschung-media__photo.is-zooming {
    transform: scale(1.25);
    transition: opacity .8s var(--ease-smooth), transform 15s linear;
  }
  /* Fortschrittsbalken: die Trennlinie UEBER dem aktiven Projekt fuellt sich
     waehrend des Zyklus von links (#333 auf #c9c9c9-Basislinie, 15s linear). */
  .forschung-item { position: relative; }
  .forschung-item__progress {
    position: absolute; top: -1px; left: 0; height: 1px; width: 0;
    background: var(--color-text); pointer-events: none;
  }
  .forschung-accordion.is-running .forschung-item.is-active .forschung-item__progress {
    width: 100%; transition: width 15s linear;
  }
  /* Akkordeon-Rhythmus am Original: Intro-Ende -> erster Titel 98px
     (Titel 4541 bei Intro-Ende 4443), Zeilen-Pitch ~69.5, danach 23px zum
     "Alle Projekte"-Knopf. */
  .section--forschung .forschung-accordion { margin: 76px 0 23px; }
  .section--forschung .forschung-item { padding: 23px 0; }
  /* Die "Forschung"-Ueberschrift ist im Original ZENTRIERT ueber der
     396px-Textspalte (h2 x=306, w=162, text-align center; DOM-Probe
     2026-07-28) - nicht linksbuendig an der Spaltenkante. */
  .forschung-block__text > h2 { text-align: center; }
  /* Logo-Anzeigebreiten am Original gemessen (5GNPR 203, Smart-SWS 159, SÜS-KOM 244). */
  .forschung-media__card--5gnpr   .forschung-media__logo { width: 203px; }
  .forschung-media__card--smart-sws .forschung-media__logo { width: 159px; }
  .forschung-media__card--sues-kom  .forschung-media__logo { width: 244px; }

  /* PARTNER Desktop: Logoreihe mit FESTEN Spaltenbreiten 43/190/161/122 und
     96px Luecken (Item-Kanten am Original: 318/457/743/1000; Reihe zentriert).
     Abstand Alle-ansehen-Knopf -> Logoreihe 96px (btn-Ende 5370 -> Logo 5466).
     Die Firmennamen darunter sind im Original WEISS (= unsichtbar auf Weiss),
     stehen zentriert unter ihrem Logo und duerfen die Spalte ueberragen. */
  .section--partner .partner-logos { gap: 96px; margin-top: 96px; }
  /* Original-Rhythmus im Sektionskopf: H2 -> Intro 21px, Intro -> Knopf 23px
     (statt der 16px-Defaults). */
  .section--partner h2 { margin-bottom: 21px; }
  .section--partner .section-intro { margin-bottom: 23px; }
  .partner-logos__item img { height: 51px; }
  .partner-logos__item:nth-child(1) { width: 43px; }
  .partner-logos__item:nth-child(2) { width: 190px; }
  .partner-logos__item:nth-child(3) { width: 161px; }
  .partner-logos__item:nth-child(4) { width: 122px; }
  /* EDAG etwas flacher und 2px tiefer (Original: y5467.6 statt 5465.6). */
  .partner-logos__item:nth-child(2) img { height: 47px; margin-top: 2px; }
}

/* Original @1440: erste Kachelzeile beginnt bei y=1270, Zeilenraster (pitch)
   266px (Kachel 192 + 15 + Bildunterschrift 36 + 23 Abstand). Unsere fruehere
   Anordnung (margin-top 51, row-gap 0) setzte die erste Zeile 11px zu hoch und
   die Zeilen 22px zu eng - dadurch wichen die (inhaltsgleichen) Vorschaubilder
   Zeile fuer Zeile wachsend gegen das Original ab (Band 3). */
/* Knopf-Ende (1196.5) -73.5- erste Kachelzeile (1270); Zeilen-Pitch 266
   (Kachel 192.36 + 15 + Bildunterschrift 36 + 22.5 row-gap). Vorher sass die
   erste Zeile mit margin 62/row-gap 22 insgesamt 22px zu hoch. */
.video-grid {
  display: grid; grid-template-columns: repeat(3, 342px); justify-content: center;
  column-gap: 18px; row-gap: 22.5px;
  max-width: 1062px; margin: 74px auto 0;
}
.video-card__thumb { position: relative; border-radius: var(--radius-md); overflow: hidden; aspect-ratio: 16/9; background: var(--color-surface); }
.video-card__thumb img { width: 100%; height: 100%; object-fit: cover; }
.video-card__thumb--placeholder { display: flex; align-items: center; justify-content: center; }
.video-card__thumb .play-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); }
/* Hover-Sweep 2026-07: die Video-Kacheln des Originals reagieren beim Hover
   NICHT (Screenshot-Belege docs/qa/hover-sweep/, Play-Knopf-Fill bleibt
   #000/0.8, kein Zoom). Der fruehere Bild-Zoom + Play-Knopf-Effekt war
   erfunden und auffaellig - entfernt. */
/* Original: Bildunterschrift/Zitatzeile unter den Videos 12px/400/18. */
.video-card p { margin: 15px 0 0; font-size: var(--fs-micro); line-height: var(--lh-micro); color: var(--color-text-muted); }
/* Jede Zeile 243px hoch: Kachel 192 + 15 + Bildunterschrift 36 (2 Zeilen). */
.video-card { min-height: 243px; }

/* Referenzen-Wappenzeile: Endlos-Ticker wie im Original (live gemessen
   @1440 und @390: Laufrichtung LINKS, 39 px/s, linear, endlos, KEIN
   Pausieren bei Hover; Wappen 83x83; Pitch @>=1200: 130 = 83 + 47 Gap,
   darunter 122 = 83 + 39 Gap). Der Track enthaelt die Sequenz aller 101
   Wappen zweimal; ein Animationsdurchlauf faehrt genau eine Sequenzbreite
   (translateX -50%) - der Ruecksprung ist dadurch unsichtbar (nahtlos).
   Dauer = Sequenzbreite / Geschwindigkeit: 101 x 130 = 13130px / 39 px/s
   = 337s. Start ~0,85s nach Load wie im Original (dort Hydration-Verzug;
   1.3s Delay + ~0.15s Style-Apply; der Original-Start streut real 0.8-1.6s).
   Nur transform, kein JS. Abstaende @1440 wie Original: Button -96-
   Wappenzeile, darunter 91 (h2 -> naechste h2 = 645px). */
.crest-row {
  overflow: hidden; padding: 96px 0 87px;
  /* Edge-Fade wie im Original (Maske dort auf der Ticker-Section gemessen,
     identisch @1440 und @390): Wappen laufen an beiden Raendern aus. */
  -webkit-mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 19.5%, #000 80.5%, rgba(0, 0, 0, 0) 100%);
  mask-image: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, #000 19.5%, #000 80.5%, rgba(0, 0, 0, 0) 100%);
}
.crest-track {
  display: flex; width: max-content;
  animation: crest-marquee 337s linear infinite;
  animation-delay: 1.3s;
}
.crest-row li { flex: 0 0 auto; margin-right: 47px; }
.crest-row img { display: block; width: 83px; height: 83px; object-fit: contain; }
@keyframes crest-marquee {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  /* Ticker steht - Wappenzeile bleibt statisch sichtbar. */
  .crest-track { animation: none; }
}

/* ---------------------------------------------------------------------------
   FORSCHUNG (aus Extraktion @1440/@390). Links: Akkordeon (Titel + Pfeil,
   Trennlinien wie im Original). Rechts (Desktop): portraetierte Medienspalte
   597x830 r18, die je aktivem Projekt Foto+Logo kreuzblendet. Auf Mobil eine
   volle-Breite-Medienkarte + die Beschreibungen sichtbar.
   --------------------------------------------------------------------------- */
.forschung-block { max-width: 1062px; margin: 0 auto; }
.forschung-lead { margin: 0; }

/* Akkordeon: Basis (mobil + Desktop teilen Struktur; Beschreibung mobil sichtbar,
   Desktop eingeklappt - s. Media-Queries). */
.forschung-accordion { margin: var(--space-6) 0; }
/* Trennlinien am Original rgb(201,201,201) (Fortschrittsbalken-Basislinie,
   getComputedStyle 2026-07-28) - nicht das hellere --color-border. */
.forschung-item {
  display: block; width: 100%; text-align: left; background: none;
  border: 0; border-top: 1px solid #c9c9c9;
  padding: 22px 0; font: inherit; color: inherit; cursor: pointer;
  transition: opacity var(--duration-hover) var(--ease-smooth);
}
.forschung-item:last-of-type { border-bottom: 1px solid #c9c9c9; }
.forschung-item__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.forschung-item__title {
  font-family: var(--font-heading); font-weight: var(--fw-bold); font-size: var(--fs-body);
  color: var(--color-text-muted); transition: color var(--duration-hover) var(--ease-smooth);
}
.forschung-item.is-active .forschung-item__title { color: var(--color-text); }
.forschung-item__chevron {
  flex: 0 0 auto; width: 10px; height: 10px; margin-right: 2px;
  border-right: 2px solid var(--color-text-muted); border-bottom: 2px solid var(--color-text-muted);
  transform: rotate(45deg); transition: transform var(--duration-hover) var(--ease-smooth);
}
/* Auf Desktop bleibt der Pfeil unten (nur Titelfarbe markiert das aktive
   Projekt); nur mobil dreht er beim Aufklappen (s. Media-Query). */
/* Beschreibung: Sichtbarkeit steuern die Breakpoint-Bloecke (Desktop: nur
   das aktive Projekt im laufenden Zyklus; Mobil: Tipp-Aufklapper). Hier nur
   Farbe/Abstand - ein display:none an dieser Stelle wuerde die frueheren
   Desktop-Regeln (im 1200px-Block weiter oben) wieder ueberschreiben. */
.forschung-item__desc { margin: 0; color: var(--color-text-muted); }

/* Medienkarten: gestapelt, aktive sichtbar (Crossfade). */
.forschung-block__media { position: relative; }
.forschung-media__card {
  position: absolute; inset: 0; opacity: 0; transition: opacity .5s var(--ease-smooth);
  will-change: opacity;
}
.forschung-media__card.is-active { opacity: 1; }
.forschung-media__photo { width: 100%; height: 100%; object-fit: cover; display: block; }
.forschung-media__logo {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  height: auto; object-fit: contain;
}

/* ---------------------------------------------------------------------------
   PARTNER (aus Extraktion). Desktop (>=1200px): zentrierte Reihe echter
   Partnerlogos (Telekom/EDAG/REHAU/Swisscom). Mobil (<1200px): dieselben Logos
   als weisse Karten + magenta Telekom-IoT-Promo mit echtem Foto-Hintergrund.
   --------------------------------------------------------------------------- */
.partner-logos {
  margin: 0; padding: 0; list-style: none;
  display: flex; align-items: flex-start; justify-content: center;
}
/* Logo + Firmenname als Spalte; Name 39px unter der Logo-Unterkante,
   Logos untereinander an der Oberkante des 51px-Rasters ausgerichtet
   (home-tail.mjs @1440: Logos y5466, Namen y5556). */
.partner-logos__item { display: flex; flex-direction: column; align-items: center; justify-content: flex-start; min-height: 51px; }
.partner-logos__item img { display: block; width: auto; }
/* Name 39px unter der Logo-Unterkante - im Original rgb(255,255,255) auf
   weissem Grund (getComputedStyle 2026-07-28), sichtbar sind nur die Logos. */
.partner-logos__name {
  margin: 39px 0 0; font-size: var(--fs-body); line-height: var(--lh-body);
  color: #fff; white-space: nowrap;
}
/* magenta Promo standardmaessig verborgen (nur mobil sichtbar). */
.partner-promo { display: none; }

/* CTA-Sektion: im Original REIN WEISS (Pixelprobe 2026-07-28: (720,5900)
   = rgb(255,255,255)) - der fruehere Grauverlauf war erfunden. */
.section--cta { background: none; }
/* Desktop-Rhythmus am Original (home-tail.mjs @1440): Partnernamen 5579 ->
   "Haben Sie Fragen?" 5951 (372 = 276 + 96), Kontakt-CTA-Ende 6166 ->
   Fusszeile 6363 (197). */
@media (min-width: 1200px) {
  .section--partner { padding-bottom: 277px; }
  .section--cta { padding-bottom: 122px; }
  .section--forschung { padding-top: 113px; padding-bottom: 104px; }
  /* CTA: Intro-Ende -74- Pille (das Intro traegt hier keinen eigenen
     Abstand; margin-top der Pille uebernimmt die 74). */
  .section--cta .section-intro { margin-bottom: 0; }
}
/* Kontakt-CTA ("Contact Button" des Originals, nachgemessen 2026-07-28):
   weisse Pille 78x69 (Radius 18, Rahmen 1px #c9c9c9, Polster 23) mit NUR dem
   32x23-Briefsymbol. Beim Hover weitet sich die Pille auf ~158px, die
   Beschriftung "Kontakt" (15/700 #333) faehrt mit 15px Abstand aus und der
   47px-Schatten-Glow erscheint. Intro-Ende -74- Pillenoberkante. */
.kontakt-cta {
  display: inline-flex; align-items: center; justify-content: center;
  margin-top: 74px; padding: 22px; height: 69px; box-sizing: border-box;
  background: #fff; border: 1px solid #c9c9c9; border-radius: 18px;
  box-shadow: 0 0 47px rgba(0, 0, 0, 0);
  /* Ruhezustand: Symbol im Original-Grau #818181 ("Email Icon"); beim Hover
     wechselt das Original auf die dunkle Variante ("Hovered Mail") - hier
     ueber currentColor geloest. Die Beschriftung erscheint nur beim Hover
     und ist dann #333. */
  text-decoration: none; color: var(--color-text-muted);
  transition: box-shadow var(--duration-hover) var(--ease-smooth),
              color var(--duration-hover) var(--ease-smooth);
}
.kontakt-cta svg { flex: 0 0 auto; }
.kontakt-cta__label {
  font-size: var(--fs-body); line-height: var(--lh-body); font-weight: var(--fw-bold);
  color: var(--color-text);
  white-space: nowrap; overflow: hidden;
  max-width: 0; opacity: 0; margin-left: 0;
  transition: max-width var(--duration-hover) var(--ease-smooth),
              opacity var(--duration-hover) var(--ease-smooth),
              margin-left var(--duration-hover) var(--ease-smooth);
}
.kontakt-cta:hover { box-shadow: 0 0 47px rgba(0, 0, 0, .23); color: var(--color-text); }
.kontakt-cta:hover .kontakt-cta__label,
.kontakt-cta:focus-visible .kontakt-cta__label { max-width: 80px; opacity: 1; margin-left: 15px; }

/* Der Umbruchpunkt des Hero liegt im Original exakt bei 1200px (bei 1200
   zweispaltig, bei 1199 gestapelt) - dieselbe Desktop-Schwelle wie auf
   /starkregengefahrenkarten/, nicht 810px. Gemessen ab 1199px: Hero-Padding
   123/23/39, gap 51, Karten gestapelt mit 23px Innenabstand, Partnerleiste
   ohne Beschriftung (291px statt 494px), "Scrollen" entfaellt. */
@media (max-width: 1199px) {
  /* ---- Videoreihe ----
     Im Original ist die Videoreihe unterhalb 1200px KEIN gestapeltes Raster,
     sondern ein waagerechter Schieber (nachgemessen /opt/tooling/vids.mjs
     @390: aeusserer Kasten overflow-x:auto ueber die volle Viewportbreite,
     Inhalt 1738px breit, Kacheln 222px mit 23px Abstand ab x=23; die Sektion
     ist dadurch nur 245px hoch). Bei uns standen alle sieben Videos
     untereinander - allein das machte die Startseite rund 1170px zu lang und
     verschob saemtliche Abschnitte darunter gegen das Original.
     Kachel: Vorschaubild 222x125 (16/9), 15px Abstand, Bildunterschrift
     222x54 (12px/400/18). */
  .section--highlights > .container:last-child {
    max-width: none; padding: 0;
  }
  .video-grid {
    display: flex; grid-template-columns: none;
    /* Das vom Desktop geerbte justify-content:center zentrierte die
       ueberbreite Schieberreihe und schob die ersten beiden Kacheln aus dem
       Bild (Kachel 0 begann bei x=-651) - der Schieber startete dadurch bei
       Video 3 statt 1. Am Original beginnt er linksbuendig bei Video 1. */
    justify-content: flex-start;
    overflow-x: auto; overflow-y: hidden;
    /* margin-top 52 statt 51: Kachelzeile beginnt im Original bei y=1437,9
       (Lauf 6, unsere 51 ergaben 1436,9 - der 1px zog sich bis in die
       Loesungen-Sektion durch). */
    gap: 23px; padding: 0 23px; margin-top: 52px;
    scroll-snap-type: x proximity;
    /* Ohne scroll-padding zog der Snap die erste Kachel an die Scrollport-
       Kante (x=0) und schluckte die 23px Innenabstand - die ganze Reihe lag
       23px links vom Original (Kachel 1 im Original bei x=23). */
    scroll-padding: 0 23px;
    -webkit-overflow-scrolling: touch;
  }
  .video-card {
    flex: 0 0 222px; width: 222px;
    scroll-snap-align: start;
    display: flex; flex-direction: column; gap: 15px;
  }
  .video-card p { margin-top: 0; }

  .hero__content { gap: 51px; padding: 123px 23px 39px; }
  /* Wie in der Zeilenanordnung auf Desktop steht auch gestapelt ein
     Phantom-Platzhalter (5px) plus 23px gap VOR der ersten Karte - der
     Kartenblock beginnt dadurch 29px unter seiner eigenen Oberkante
     (Original @390: Block y=395, erste Karte y=424; @768: 292 / 321). */
  .hero__cards { flex-direction: column; padding: 29px 0 0; gap: 23px; align-items: stretch; }
  /* flex-basis 0 wuerde in der Spaltenrichtung die HOEHE auf 0 ziehen - die
     Karten fielen dadurch auf ihre Padding-Hoehe zusammen. */
  /* Gestapelt richtet sich die Hoehe im Original nach dem Inhalt (gemessen
     213-325px je nach Breite) - die feste 250px-Hoehe gilt nur zweispaltig. */
  .hero-card { flex: 0 0 auto; padding: 23px; height: auto; }
  /* Die erste Karte hat im Original rund 67px zusaetzlichen Leerraum unter
     dem Link - auf beiden gemessenen Breiten gleich (390px: 280 statt 213,
     768px: 235 statt 167). Dasselbe Framer-Artefakt wie der
     Phantom-Platzhalter oben; ohne es war der Hero 97px zu kurz und alles
     darunter entsprechend verschoben. */
  .hero__cards > .hero-card:first-child { padding-bottom: 91px; }
  /* Das Original setzt @390 auch den Fliesstext in POPPINS (nachgemessen
     15/22.5 bzw. Captions 12/18: Hero-Karten, Sektions-Intros, CTA-Text,
     Video-Bildunterschriften, Buttons) - unser sitewides Inter liess im
     Differenzbild ganze Textbloecke rot stehen und brach die Captions anders
     um. Nur <1200px; Desktop ist verifiziert und bleibt bei Inter. */
  .hero-card p, .hero-card a,
  .section--highlights .section-intro,
  .section--referenzen .section-intro,
  .section--cta .section-intro,
  .forschung-lead,
  .video-card p,
  main .btn { font-family: var(--font-heading); }
  .hero-card__logo--ews { width: 228px; }
  .hero-card__logo--fas { width: 236px; }
  .hero__partnerbar-label { display: none; }
  .partner-logo--telekom img { height: 30px; }
  .partner-logo--edag   img { height: 30px; }
  .hero__scroll-hint { display: none; }

  /* ---- Highlights-Videoreihe ----
     Im Original ist eine Kachelzeile nur ~194px hoch (Vorschaubild 125 +
     15px Abstand + Bildunterschrift ~54). Die vom Desktop geerbte feste
     Mindesthoehe (243px) machte den waagerechten Schieber ~49px zu hoch und
     schob alles darunter nach unten. */
  .video-card { min-height: 0; }

  /* ---- Referenzen ----
     Original @390: die Wappenzeile ist eine reine Wappen-Leiste OHNE
     Beschriftung (Wappen 83x83, kein Text) - genau wie auf /referenzen/. */
  /* Kopfabstaende wie im Original @390: H2 -21- Intro -23- Button(47) -68-
     Wappenzeile (vorher 16/16/49er-Button/32 - die Wappenzeile sass dadurch
     48px zu hoch und alles unter Referenzen ghostete). */
  .section--referenzen h2 { margin-bottom: 21px; }
  .section--referenzen .section-intro { margin-bottom: 23px; }
  /* Ticker unterhalb 1200: Pitch 122 (Wappen 83 + 39 Gap, gemessen @390) ->
     Sequenzbreite 101 x 122 = 12322px, bei 39 px/s = 316s je Loop. Vertikale
     Kette (68 oben / space-4 unten) unveraendert aus dem @390-Abgleich. */
  /* 69 statt 68: Wappenreihe beginnt im Original bei y=4500,5 (Lauf 6 @390,
     unsere 68 ergaben 4499,5). */
  .crest-row { padding: 69px 0 calc(var(--space-4) - 1px); }
  .crest-row li { margin-right: 39px; }
  .crest-track { animation-duration: 316s; }
  /* Lazy-Load-Fallback: das Original zeigt seine Bilder sofort beim Laden -
     unsere loading="lazy"-Bilder liessen Wappen/Kacheln/Logos bis zum
     Nachladen als leere Flaechen stehen (sichtbar in jeder Ganzseiten-
     Aufnahme). Die im 390er-Viewport sichtbaren Motive stehen darum
     zusaetzlich als CSS-Hintergrund unter dem <img> (deckungsgleich,
     das geladene Bild verdeckt sie pixelidentisch). */
  .crest-row li { background-repeat: no-repeat; background-position: center top; background-size: contain; }
  .crest-row li:nth-child(1) { background-image: url(/static/img/rbfHkq0h3XUwP5CgjQ4cBecA.png); }
  .crest-row li:nth-child(2) { background-image: url(/static/img/30HORlwBdsoAWhluzbfsWmM3t0.png); }
  .crest-row li:nth-child(3) { background-image: url(/static/img/FjmIfcO42aJkMbHawyhFlp7uNTk.png); }
  .crest-row li:nth-child(4) { background-image: url(/static/img/OOWrZm5YESJdC1faDTe2Vi3kxaA.png); }
  .crest-row li:nth-child(5) { background-image: url(/static/img/xNFZTe5R7HXyV6mX5kvaGrC0Quw.png); }
  .video-card__thumb { background-size: cover; background-position: center; }
  .video-card:nth-child(1) .video-card__thumb { background-image: url(/static/img/yt/7ZOgLJHdyls.jpg); }
  .video-card:nth-child(2) .video-card__thumb { background-image: url(/static/img/yt/xG4bSQiQQGI.jpg); }
  .video-card:nth-child(3) .video-card__thumb { background-image: url(/static/img/yt/tboBtIgHUQo.jpg); }
  .video-card:nth-child(4) .video-card__thumb { background-image: url(/static/img/yt/0pmpj88YRgo.jpg); }
  .video-card:nth-child(5) .video-card__thumb { background-image: url(/static/img/yt/NC7tkjZRrGo.jpg); }
  .video-card:nth-child(6) .video-card__thumb { background-image: url(/static/img/yt/KBN4yZlTxEE.jpg); }
  .video-card:nth-child(7) .video-card__thumb { background-image: url(/static/img/yt/sAgaxCrE0V4.jpg); }

  /* ---- Forschung ----
     Original @390: kompakter, zentrierter Block. Ueberschrift und Einleitung
     sind zentriert, die drei Projekte sind ein EINGEKLAPPTES Akkordeon
     (nur Titel + Aufklapp-Pfeil, keine Beschreibung sichtbar), und das
     Alpen-Medium ist ausgeblendet. Unser aufgeklapptes Akkordeon plus Bild
     machte die Sektion ~658px zu hoch und verschob alles darunter. */
  /* Original @390: zwischen Videoreihe und "Lösungen" liegen nur ~94px, nicht
     die sitewide 2x96px. Ohne diese Kuerzung sass Lösungen und alles darunter
     ~86px zu tief. */
  .section--highlights { padding-bottom: var(--space-7); }
  /* Der +26px-Hero-Versatz @390 war das Desktop-Padding (123px) der
     Highlights-Sektion: das Original nutzt unterhalb 1200px die sitewide 96px
     (Hero endet y=1105, H2 y=1201). Dazu die Original-Innenabstaende der
     Sektionskoepfe (nachgemessen @390): H2 -21- Intro -22- Button(47). */
  .section--highlights { padding-top: 96px; }
  .section--highlights h2 { margin-bottom: 21px; }
  .section--highlights .section-intro { margin-bottom: 22px; }
  /* Die weissen Pill-Buttons der Sektionskoepfe sind im Original 47px hoch
     (unsere 49) - gleicher 11px-Padding-Fix wie bei den Loesungs-Buttons.
     Und sie stehen LINKSBUENDIG an der Spaltenkante (alle vier gemessen bei
     x=39), nicht zentriert: display:flex + fit-content macht aus dem
     inline-flex-Knopf eine Blockbox, die der text-center-Container nicht
     mehr mittig setzt - das Flex-Innenleben (Pfeil) bleibt unveraendert. */
  .section--highlights .btn,
  .section--referenzen .btn,
  .section--forschung .btn,
  .section--partner .btn {
    padding-top: 11px; padding-bottom: 11px;
    display: flex; width: fit-content;
  }
  /* 49 statt 48: Kachelzeilen-Unterkante (1631) + 48 (Highlights-pb) + 49
     = Original-H2 "Lösungen" y=1728 (nachgemessen, inkl. Subpixel-Rundung).
     Der fruehere 32px-Wert absorbierte den inzwischen behobenen
     +16px-Versatz der Kachelzeile. */
  .section--loesungen { padding-top: 49px; }

  /* Mobil (<1200px) ist die Loesungs-Sektion gestapelt (wie das Original @390):
     kein Pin, kein Crossfade. Die sticky Medienspalte entfaellt, stattdessen
     zeigt jeder Textblock sein eigenes Inline-Medium darunter.

     Alle Abstaende am Original @390 nachgemessen (loes390-measure.mjs,
     getBoundingClientRect nach Vollscroll):
       H2(28) -20- Intro1 -23- Intro2 -50- ews-Logo(312x25) -21- Text -23-
       Button(160x47) -68- Medium(642x420, rechtsbuendig randlos) -96-
       fas-Logo(312x30) -21- Text -23- Buttonzeile -68- Medium -96- Referenzen.
     Vorher sassen wir auf 15/16/95/16/16/32/48-Gaps - dadurch lag die ganze
     Sektion versetzt und die Logos standen im Differenzbild doppelt. */
  .section--loesungen h2 { margin-bottom: 20px; }
  /* Lauf 6 @390: Intro-Absaetze stehen im Original 22,5px auseinander
     (1911,4 -> 1933,9), und Intro2-Unterkante -> ews-Logo sind 51px
     (22,5 Absatzmargin + 28,5 Scroll-Polster; vorher 23+27 = 1px zu wenig
     und 0,5px zu viel zwischen den Absaetzen). */
  .section--loesungen .section-intro { margin-bottom: 22.5px; }
  .loesung-scroll { display: block; max-width: none; padding: 28.5px 39px 0; }
  .loesung-text { display: block; }
  .loesung-block { display: block; padding-top: 0; }
  /* Abstand ews-Medium -> fas-Logo (Original: 96px). */
  .loesung-block + .loesung-block { padding-top: 96px; }
  .loesung-media { display: none; }
  /* Die Loesungs-Absaetze setzt das Original in POPPINS (15/22.5, @390 UND
     @1440 nachgemessen) - unser sitewides Inter brach frueher um (12 statt 15
     Zeilen je Block), wodurch jeder Block ~68px zu kurz war und alles darunter
     hochrutschte. Nur mobil gescoped; Desktop ist verifiziert und bleibt. */
  .section--loesungen .section-intro,
  .loesung-block p { font-family: var(--font-heading); }
  .loesung-block p { margin: 0 0 23px; }
  /* Blocklogos laufen im Original ueber die volle Textspalte (312px breit,
     ews 25px / fas 30px hoch) - nicht auf 24px Hoehe gedeckelt. */
  .loesung-block .solution-logo { width: 100%; height: auto; margin-bottom: 21px; }
  /* Original-Buttons @390 sind 46,5px hoch (unsere 49/50). */
  .section--loesungen .btn { padding-top: 11px; padding-bottom: 11px; }
  /* Der 24px-Play-Kreis trieb den Video-Chip auf 48px - Original: 46,5
     wie der Mehr-erfahren-Knopf daneben (3591,9..3638,4; Lauf 6 @390). */
  .section--loesungen .btn .play-btn--sm { height: 22.5px; }
  /* Inline-Medium randlos ueber die volle Breite (Original: 642er-Flaeche laeuft
     ueber den Rand), formatfuellend 420px hoch wie im Original. */
  /* 69 statt 68: Knopf-Unterkante -> Medium ist im Original 69px
     (2595,0 -> 2664,0 bzw. 3638,4 -> 3707,4; Lauf 6 @390). */
  .loesung-block__media { margin: 69px -39px 0; overflow: hidden; }
  .loesung-block__media img { height: 420px; object-fit: cover; object-position: 100% 50%; border-radius: 0; }
  /* Beide Inline-Medien sind im Original FESTE 642x420-Flaechen (nachgemessen
     @390 UND @768): das ews-Luftbild schliesst rechts buendig mit dem Viewport
     ab (x=-252..390 bzw. 126..768), die fas-Nachtszene haengt fix bei x=-219
     ueber die linke Kante (Rest rechts bleibt frei). Ein cover-Fit in der
     Spaltenbreite skalierte das ews-Asset minimal anders (0.568 statt 0.583) -
     saemtliche Bildkanten lagen dadurch doppelt. Der Wrapper (overflow:hidden)
     schneidet die Ueberhaenge ab. */
  .loesung-block__media img { width: 642px; max-width: none; }
  .loesung-block__media--ews img { margin-left: calc(100% - 642px); }
  /* object-position zurueck auf Mitte: die 100%-Regel oben gilt der randlosen
     Variante; die feste 642er-Flaeche des Originals ist mittig gecovert. */
  .loesung-block__media--fas img { margin-left: -219px; object-position: 50% 50%; }
  /* Medium-Unterkante -> Referenzen-H2 = 96px im Original: die traegt allein
     das padding-top der Referenzen-Sektion (sitewide 96). */
  .section--loesungen { padding-bottom: 0; }
  /* Sektionsabstaende unter Referenzen exakt ans Original @390 gezogen
     (H2-Ziel-y: Forschung 4852, Unsere Partner 5485, Haben Sie Fragen 6650):
     Wappen-Unterkante -269- Forschung-H2 => pb 159 (+ crest-pb 16 + 96 pt).
     Forschung: "Alle Projekte"-Unterkante -96- Partner-H2 => pb 0 (Partner-pt
     96 traegt den Abstand allein; die frueheren 40px sassen doppelt).
     Partner: Promo-Unterkante -96- CTA => pb 98 statt 186 (pt 98/159/98
     statt 96/157/96: gleicht die Subpixel-Rundungssumme der Zwischenschritte
     aus, nachgemessen gegen die Original-H2-y 4223/4852/5485/6650). */
  /* Lauf 6 @390: Die Aufschlaege 98/159/98 kompensierten die inzwischen an
     der Quelle behobene Kettendrift (Kachelzeile/Loesungen). Jetzt Original-
     Anker exakt: Nachtszene-Unterkante -96- Referenzen-H2 (4127,4 -> 4223,4),
     Promo-Unterkante -96- CTA-Block (6367,6 -> 6463,6). pb 158 / pt 97
     verschieben nur die unsichtbare Sektionsgrenze im einfarbigen Zwischenraum:
     die sichtbaren Anker (Forschung-H2 4852,5, Partner-H2 5484,6) sitzen damit
     auf 0. */
  .section--referenzen { padding-top: 96px; padding-bottom: 158px; }
  .section--forschung { padding-bottom: 0; }
  .section--partner { padding-top: 97px; padding-bottom: 96px; }

  /* Mobil (<1200px): zentrierter Kopf, EINGEKLAPPTES Akkordeon (nur Titel +
     Pfeil, wie im Original @390); Beschreibung klappt beim Tippen auf. Die
     portraetierte Desktop-Medienspalte entfaellt. */
  /* Original @390: NUR die Ueberschrift ist zentriert - Einleitung, Akkordeon
     und "Alle Projekte" stehen linksbuendig an der Spaltenkante (x=39). */
  .forschung-block { display: block; max-width: none; padding: 0 39px; text-align: left; }
  .forschung-block__media { display: none; }
  /* Innenabstaende wie im Original @390 (Titelzeilen y=5134/5203/5273,
     "Alle Projekte" y=5342): H2 -21- Einleitung -51- Akkordeon; Titel-Pitch
     69.5 (Item-Padding 23 statt 22), letzter Titel -46- Button. */
  .section--forschung h2 { margin-bottom: 21px; }
  .forschung-accordion { margin: 51px 0 22px; }
  .forschung-item { padding: 23px 0; }
  .forschung-block__text > h2 { text-align: center; }
  .forschung-accordion { text-align: left; }
  /* CTA-Text ist im Original zentriert (die sitewide Mobilregel setzt
     .section-intro sonst linksbuendig). */
  .section--cta .section-intro { text-align: center; }
  /* Beschreibung standardmaessig eingeklappt; oeffnet bei .is-open. */
  .forschung-item__desc {
    display: block; max-height: 0; overflow: hidden; margin-top: 0; opacity: 0;
    transition: max-height .3s var(--ease-smooth), opacity .3s var(--ease-smooth), margin-top .3s var(--ease-smooth);
  }
  .forschung-item.is-open .forschung-item__desc { max-height: 260px; opacity: 1; margin-top: var(--space-3); }
  /* Pfeil zeigt auf Mobil den Auf-/Zuklapp-Zustand an. */
  .forschung-item .forschung-item__chevron { transform: rotate(45deg); }
  .forschung-item.is-open .forschung-item__chevron { transform: rotate(-135deg); }

  /* ---- Partner ----
     Original @390: statt der Textliste eine Spalte weisser Logo-Karten
     (312x47, Radius 9, 27px Abstand) mit den ECHTEN Partnerlogos und darunter
     eine full-bleed Telekom-IoT-Promo mit echtem magenta Foto-Hintergrund. */
  /* Kopfabstaende + Kartenspalte wie im Original @390: H2 -20- Intro (Poppins,
     5 Zeilen 113px - Inter brach auf 4 Zeilen/90px um) -23- Button(47) -68-
     Karten in voller 312px-Spalte (x=39; vorher 282px bei x=54). */
  /* Lauf 6 @390: H2 -21- Intro (5512,2 -> 5533,2), Knopf-Unterkante -69-
     erste Karte (5715,2 -> 5784,2). */
  .section--partner h2 { margin-bottom: 21px; }
  .section--partner .section-intro {
    margin-bottom: 23px;
    font-family: var(--font-heading);
  }
  .partner-logos {
    display: flex; flex-direction: column; align-items: stretch;
    gap: 27px; margin: 69px 0 0; padding: 0;
  }
  /* Kartenhoehen im Original NICHT uniform 47: Logo-Hoehe + 24 Polster ergibt
     46,5 / 47 / 47,1 / 46,8 (Logos 22,5 / 23 / 23,1 / 22,8 - nachgemessen
     Lauf 6 @390: Karten 5784,2/5857,7/5931,7/6005,8, Unterkante 6052,6). */
  .partner-logos__item {
    height: 47px; background: #fff; border: 1px solid var(--color-border);
    border-radius: 9px;
    flex-direction: row; align-items: center; justify-content: center; min-height: 0;
  }
  .partner-logos__item:nth-child(1) { height: 46.5px; }
  .partner-logos__item:nth-child(3) { height: 47.1px; }
  .partner-logos__item:nth-child(4) { height: 46.8px; }
  /* Firmennamen zeigt nur der Desktop (mobil weisse Logo-Karten wie im
     Original). */
  .partner-logos__name { display: none; }
  /* Logo-Hoehen exakt wie im Original (22,5/23/23,1/22,8 - daraus folgen
     auch die Original-Breiten 93/73 usw. bei width:auto). */
  .partner-logos__item img { max-height: 24px; width: auto; height: auto; object-fit: contain; }
  .partner-logos__item:nth-child(1) img { max-height: 22.5px; }
  .partner-logos__item:nth-child(2) img { max-height: 23px; }
  .partner-logos__item:nth-child(3) img { max-height: 23.1px; }
  .partner-logos__item:nth-child(4) img { max-height: 22.8px; }
  /* Lazy-Load-Fallback wie bei Wappen/Kacheln (s.o.): Logos auch als
     CSS-Hintergrund, bis das <img> geladen ist. */
  .partner-logos__item { background-repeat: no-repeat; background-position: center; background-size: auto 22.5px; }
  .partner-logos__item:nth-child(2) { background-size: auto 23px; }
  .partner-logos__item:nth-child(3) { background-size: auto 23.1px; }
  .partner-logos__item:nth-child(4) { background-size: auto 22.8px; }
  .partner-logos__item:nth-child(1) { background-image: url(/static/img/partner/logo-telekom.png); }
  .partner-logos__item:nth-child(2) { background-image: url(/static/img/partner/logo-edag.png); }
  .partner-logos__item:nth-child(3) { background-image: url(/static/img/partner/logo-rehau.png); }
  .partner-logos__item:nth-child(4) { background-image: url(/static/img/partner/logo-swisscom.png); }
  /* Promo-Flaeche im Original @390: 264px hoch (y=6104-6368), Innenabstand
     39px oben/unten (vorher 67/47 - die Promo war 26px zu hoch). */
  .partner-promo {
    display: block; margin-top: 51px; padding: 39px;
    color: #fff; text-align: left; background: #5c0d34;
  }
  .partner-promo::before {
    content: ""; position: absolute; inset: 0; z-index: 0;
    background: url(/static/img/partner-promo-telekom.jpg) center/cover no-repeat;
  }
  .partner-promo::after {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(135deg, rgba(74,10,43,.72) 0%, rgba(143,17,82,.55) 100%);
  }
  .partner-promo { position: relative; overflow: hidden; }
  .partner-promo h3, .partner-promo p { position: relative; z-index: 2; }
  /* Original: h3-Zeilenbox 23px, Text beginnt 28px unter der h3-Oberkante
     (y=6143 -> 6171); der Promo-Text laeuft in Poppins auf 7 Zeilen (158px) -
     Inter brach auf 6 Zeilen/135px um. */
  .partner-promo h3 { color: #fff; font-size: var(--fs-sub); line-height: 23px; margin: 0 0 5px; }
  .partner-promo p {
    color: rgba(255,255,255,.95); margin: 0;
    font-family: var(--font-heading); font-size: var(--fs-body); line-height: var(--lh-body);
  }

  /* ---- Reveal: mobil nur die Hero-Eingangssequenz ----
     Das Original schliesst seine Appear-Animationen BEIM LADEN ab (so auch
     der Befund im Kopf von reveal.js: below-fold ist der Effekt beim
     Erreichen meist schon fertig). Unser Scroll-Reveal hielt Below-fold-
     Bloecke (Hero-Partnerleiste, Sektionskoepfe, Kachelzeile, Wappenreihe,
     Akkordeon, Promo) bis zum Hereinscrollen unsichtbar - jede Ganzseiten-
     Aufnahme und jeder schnelle Scroll zeigte leere Flaechen, wo das
     Original Inhalt zeigt. Mobil (<1200) animiert darum nur die
     Eingangssequenz (Eyebrow/Titel/Karten); alles andere steht sofort.
     Desktop (>=1200) bleibt unveraendert. */
  html[data-reveal-ready="on"] main [data-reveal]:not(.hero__eyebrow):not(.hero__title):not(.hero-card) {
    opacity: 1;
    translate: none;
    transition: none;
    will-change: auto;
  }

  /* ---- CTA "Haben Sie Fragen?" ----
     Original @390: ueber der H2 steht das Spekter-Auge (124x63, zentriert)
     mit 27px Abstand (Sektionsbeginn y=6464, Icon y=6560, H2 y=6650) -
     das vorhandene logo-auge.png (423x215, gleiches Seitenverhaeltnis)
     uebernimmt das per ::before. Darunter: Text -51- Button (69px hoch),
     Button-Unterkante -96- Footer; die 96 traegt der Footer-margin allein
     (pb 0 statt 96, sonst sass der Footer 81px zu tief). */
  .section--cta { padding-bottom: 0; }
  /* Mobil zeigt das Original die Pille DAUERHAFT mit Beschriftung (158x69,
     x=116 @390) und 51px unter dem Intro; die Sektion liegt auf einem weichen
     grauen Schein (Mitte weiss, Raender ~#d7d7d7 - Pixelprofil 2026-07-28),
     und das Auge darueber ist DUNKEL (#333, nicht das 818181-Grau). */
  .kontakt-cta { margin-top: 51px; }
  .section--cta .section-intro { margin-bottom: 0; }
  .kontakt-cta__label { max-width: none; opacity: 1; margin-left: 15px; }
  .section--cta {
    background: radial-gradient(ellipse 105% 130% at 50% 45%, #ffffff 52%, #d7d7d7 125%);
  }
  .section--cta .container::before {
    content: ""; display: block; width: 124px; height: 63px;
    margin: 0 auto 27px;
    background: url(/static/img/logo-auge-dark.png) center / contain no-repeat;
  }
  /* CTA "Haben Sie Fragen?": H2 -> Absatz sind im Original 15px
     (h2-Unterkante 6677,2 -> p 6692,2 @390, Lauf 6 2026-07-30), nicht die
     16px aus --space-4. Der 1px-Versatz schob CTA-Knopf und Footer nach
     unten. Die fruehere 7px-Footer-Kompensation (.site-footer__bottom
     padding-bottom:32px, "Original endet 7px knapper") war ein veralteter
     Messstand: Original-Footer ist auch auf der Startseite 547,5px hoch
     wie sitewide - Regel entfernt, docH 7478 = Original exakt. */
  .section--cta h2 { margin-bottom: 15px; }
}
@media (max-width: 809px) {
  .solution-block, .solution-block--reverse { grid-template-columns: 1fr; direction: ltr; }
  /* Original @390: der Textblock hat 39px Seitenrand (Textspalte 312px), das
     Medium laeuft randlos ueber die volle Breite. Vorher lag unser Text
     randlos (x=0/Spalte 390px) - dadurch brach der Absatz auf weniger Zeilen
     um und der Loesungsblock war je ~112px zu niedrig, was den ganzen
     Abschnitt darunter nach oben zog. row-gap 32px bildet den Abstand
     Text->Medium nach (Original ~74px inkl. Button-Padding). */
  .solution-block { padding: var(--space-6) 39px; row-gap: var(--space-6); }
  .solution-block__text { min-width: 0; }
  .solution-block__media { margin: 0 -39px; }
  /* Groesse kommt jetzt aus --fs-hero (34px ab 809px, am Original gemessen) -
     der frueher hier stehende 38px-Literalwert hat den Token ueberschrieben. */
  /* Original @390/768: die beiden Loesungsbilder (Karte/Nachtstadt) sind
     formatfuellend 420px HOCH (cover), nicht in natuerlicher 16:9-Hoehe
     (219px). Die je ~200px fehlende Bildhoehe liess den gesamten
     Loesungs-Abschnitt ~400px zu kurz werden - dadurch rutschten beide Bilder
     nach oben und standen im Differenzbild als grosse Vollrot-Bloecke gegen
     Weissraum (Baender 4/5 = 51/57%). */
  .solution-block__media img { height: 420px; object-position: 100% 50%; }
}
/* Bei 768 ist das Loesungsbild im Original nicht randlos, sondern eine feste
   642px-Flaeche (bei 390 laeuft dieselbe 642er-Flaeche ueber den Rand). Ohne
   Deckelung war unser Bild 768px breit und damit anders skaliert/ausgeschnitten
   als das Original. */
@media (min-width: 641px) and (max-width: 809px) {
  .solution-block__media { max-width: 642px; margin-left: auto; margin-right: auto; }
}
/* Loesungs-Inline-Medien: die fruehere 641-1199px-Zentrierungs-Deckelung ist
   entfernt - nachgemessen sind die 642x420-Flaechen im Original auch @768 am
   VIEWPORT verankert (ews rechtsbuendig, fas bei x=-219), nicht zentriert.
   Die Verankerung uebernehmen die margin-Regeln im 1199px-Block oben. */
@media (max-width: 480px) {
  .partner-names { gap: var(--space-4); }
}

/* ---------------------------------------------------------------------------
   Hover-Sweep 2026-07: Interaktionen 1:1 ans Original angeglichen (Playwright,
   getComputedStyle vorher/nachher; Tabelle docs/qa/hover-sweep/README.md).
   Gemessenes Original-Verhalten der weissen Pill-Buttons ("Mehr erfahren",
   "Alle ansehen", "Alle Projekte", Video-Chip):
     - box-shadow: rgba(0,0,0,0) 0 0 47px  ->  rgba(0,0,0,.23) 0 0 47px
     - KEIN Hintergrund-, Rahmen- oder transform-Wechsel
     - der Pfeil gleitet nach rechts hinaus und von links wieder herein
   Die Regeln stehen hier (nicht in base.css - fremdes Arbeitsgebiet) und sind
   auf main gescoped, damit Kopfzeile/Ankuendigungsleiste unberuehrt bleiben.
   --------------------------------------------------------------------------- */
main .btn:hover {
  background: var(--color-bg);
  border-color: var(--color-border);
  transform: none;
  box-shadow: 0 0 47px rgba(0,0,0,.23);
}
main .btn--accent:hover { background: #006a94; box-shadow: none; }
main .btn--accent-magenta:hover { background: #b8005e; box-shadow: none; }
/* Der "Video"-Chip (btn--ghost) bekommt im Original denselben Schatten-Glow. */
main .btn--ghost:hover { box-shadow: 0 0 47px rgba(0,0,0,.23); }
/* Pfeil-Swap wie im Original: hinaus nach rechts, von links wieder herein.
   Ein Element, eine Keyframe - kein Markup-Umbau. Der Play-Glyph des
   Video-Chips ist ausgenommen. */
@keyframes hov-arrow-swap {
  0%   { transform: translateX(0);     opacity: 1; }
  45%  { transform: translateX(18px);  opacity: 0; }
  55%  { transform: translateX(-18px); opacity: 0; }
  100% { transform: translateX(0);     opacity: 1; }
}
main .btn:hover > span[aria-hidden]:not(.play-btn) {
  display: inline-block;
  animation: hov-arrow-swap calc(var(--duration-hover) * 2.5) var(--ease-smooth);
}
/* Grosser Kontakt-CTA ("Haben Sie Fragen?"): Original zeigt denselben
   Schatten-Glow, keine Anhebung, kein Fond-/Rahmenwechsel. */
main .icon-btn--lg:hover {
  background: transparent;
  border-color: var(--color-border);
  transform: none;
  box-shadow: 0 0 47px rgba(0,0,0,.23);
}
/* Hero-Karten-Links: das Original unterstreicht NICHT und verschiebt den
   Pfeil nicht statisch - es laeuft nur der Pfeil-Swap. */
.hero-card .link-arrow:hover { text-decoration: none; }
.hero-card .link-arrow:hover span[aria-hidden] {
  transform: none;
  animation: hov-arrow-swap calc(var(--duration-hover) * 2.5) var(--ease-smooth);
}

/* Lauf 7b (2026-07-30) @320: das Original haelt die fas-Knopfzeile
   (Video 91 + Mehr erfahren 160 ab x169, laeuft bis x329 ueber den
   Rand) und die Telekom-Promo-H3 EINZEILIG - bei uns brachen beide um
   (+57,8 bzw. +22,4px docH). */
@media (max-width: 359px) {
  /* Knoepfe behalten ihre Naturbreite und haengen rechts ueber -
     geschrumpft brachen sie intern um (91,5 hoch statt 46,5). */
  .loesung-block .btn-row { flex-wrap: nowrap; }
  .loesung-block .btn-row > * { flex: 0 0 auto; }
  .partner-promo h3 { white-space: nowrap; }
}
