﻿/* ═════════════════════════════════════════════════════════════════════════
   Informationsfluss — die Punkte sind die Hauptdarsteller

   Ein Punkt ist eine Information: eine Suche, ein Anruf, eine Anfrage, ein
   Termin. Der Besucher sieht an seiner Bewegung, ob sie ankommt, hängen
   bleibt, sich verdoppelt oder verschwindet.

   Bewusst NICHT: Textblöcke, die nacheinander einblenden. Verbindungslinien
   als Hauptdarstellung. Kästen mit Beschreibungssätzen. Häkchenlisten.
   ═════════════════════════════════════════════════════════════════════════ */

.fl { position: relative; }
.fl__svg { display: block; width: 100%; height: auto; overflow: visible; }

/* ── Systemknoten: Symbol, darunter ein kurzes Wort. Kein Satz. ───────── */

.fl__k { transition: opacity 900ms var(--ease-sys), transform 1200ms var(--ease-sys); }
.fl__k rect {
  fill: var(--flaeche); stroke: var(--line-2); stroke-width: 1.2;
  transition: stroke 600ms var(--ease-sys), fill 600ms var(--ease-sys);
}
.fl__k path, .fl__k circle, .fl__k line {
  fill: none; stroke: var(--ink-2); stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
  transition: stroke 600ms var(--ease-sys);
}
.fl__k text {
  fill: var(--muted); font-family: var(--sans); font-size: 15px;
  font-weight: 500; text-anchor: middle; letter-spacing: 0.01em;
  transition: fill 600ms var(--ease-sys);
}

/* Aufmerksamkeit nötig — nicht „schlecht". */
.fl__k.is-achtung rect { stroke: var(--sicht-fl); }
.fl__k.is-achtung path, .fl__k.is-achtung circle, .fl__k.is-achtung line { stroke: var(--sicht); }
/* Belegt in Ordnung. */
.fl__k.is-gut rect { stroke: var(--ergebnis); }
.fl__k.is-gut text { fill: var(--ergebnis); }
/* Tritt zurück, während anderswo etwas passiert. */
.fl__k.is-still { opacity: 0.32; }

/* ── Die Punkte ──────────────────────────────────────────────────────── */

.fl__p {
  offset-distance: 0%;
  offset-rotate: 0deg;
  opacity: 0;
}
.fl__p circle { r: 7; }

/* Eine Anfrage, ein Anruf, eine Suche — Farbe nach Bedeutung. */
.fl__p--anfrage circle { fill: var(--anfrage); }
.fl__p--sicht circle   { fill: var(--sicht-fl); }
.fl__p--ablauf circle  { fill: var(--ablauf); }
.fl__p--gut circle     { fill: var(--ergebnis); }

/* Eine vollständige Anfrage trägt ihre Bestandteile sichtbar mit sich. */
.fl__p--voll circle:nth-child(1) { r: 11; fill: var(--anfrage); }
.fl__p--voll circle:nth-child(n+2) { r: 3; fill: var(--flaeche); }

/* Ankommen: läuft durch und bleibt. */
@keyframes fl-an {
  0%   { offset-distance: 0%; opacity: 0; }
  8%   { opacity: 1; }
  92%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 1; }
}
/* Abbrechen: kommt nicht an und verlischt unterwegs. */
@keyframes fl-ab {
  0%   { offset-distance: 0%; opacity: 0; }
  10%  { opacity: 1; }
  55%  { offset-distance: 52%; opacity: 1; }
  75%  { offset-distance: 56%; opacity: 0.25; }
  100% { offset-distance: 56%; opacity: 0; }
}
/* Hängen bleiben: pendelt zwischen zwei Stellen. */
@keyframes fl-haengt {
  0%   { offset-distance: 0%; opacity: 0; }
  10%  { opacity: 1; }
  40%  { offset-distance: 46%; }
  70%  { offset-distance: 22%; }
  100% { offset-distance: 40%; opacity: 1; }
}
/* Unbeantwortet: kommt an und pulst. */
@keyframes fl-wartet {
  0%   { offset-distance: 0%; opacity: 0; }
  10%  { opacity: 1; }
  60%  { offset-distance: 100%; opacity: 1; }
  75%  { opacity: 0.35; }
  90%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0.5; }
}

.fl__p.is-laeuft  { animation: fl-an var(--d, 2600ms) var(--ease-sys) var(--v, 0ms) both; }
.fl__p.is-bricht  { animation: fl-ab var(--d, 2600ms) var(--ease-sys) var(--v, 0ms) both; }
.fl__p.is-haengt  { animation: fl-haengt var(--d, 3200ms) linear var(--v, 0ms) both; }
.fl__p.is-wartet  { animation: fl-wartet var(--d, 3000ms) var(--ease-sys) var(--v, 0ms) both; }

/* Nach einem Sprachwechsel bleibt die bereits sichtbare Bühne im Ergebnis:
   keine wiederholte Bewegung, alle Bedeutungsfarben gleichzeitig sichtbar. */
.fl.is-uebernommen .fl__p,
.fl.is-abgeschlossen .fl__p {
  animation: none !important;
  opacity: 1;
  offset-distance: var(--ruhe, 100%);
}

/* Verlorene Wege werden im Prüfmoment golden markiert. */
.fl__verlust {
  fill: none; stroke: var(--sicht-fl); stroke-width: 2;
  stroke-dasharray: 1 1; stroke-dashoffset: 1; opacity: 0;
  transition: stroke-dashoffset 900ms var(--ease-sys), opacity 500ms var(--ease-sys);
}
.fl.is-pruefung .fl__verlust { opacity: 0.85; stroke-dashoffset: 0; }
.fl.is-behoben .fl__verlust { opacity: 0; }

/* Der Prüfimpuls ist kein Loader: er wandert einmal durch den Ablauf. */
.fl__impuls {
  fill: none; stroke: var(--sicht-fl); stroke-width: 1.4; opacity: 0;
}
.fl.is-pruefung .fl__impuls { animation: fl-impuls 1500ms var(--ease-sys) both; }
@keyframes fl-impuls {
  0%   { opacity: 0; transform: translateX(-60%); }
  25%  { opacity: 0.6; }
  75%  { opacity: 0.6; }
  100% { opacity: 0; transform: translateX(60%); }
}

/* Der Systemraum bestätigt einmal — kein Dauerleuchten. */
.fl__raum {
  fill: none; stroke: var(--line); stroke-width: 1;
  transition: stroke 800ms var(--ease-sys), opacity 800ms var(--ease-sys);
  opacity: 0;
}
.fl.is-geordnet .fl__raum { opacity: 1; }
.fl.is-bestaetigt .fl__raum { stroke: var(--ergebnis); }

/* ── Statusmeldungen: kurz, groß, eine zur Zeit ──────────────────────── */

/* Unter dem Ablauf, nicht darüber: mittig platziert verdeckte die Meldung den
   Anfrage-Knoten — also genau die Stelle, über die sie spricht. */
.fl__status {
  margin-top: 6px;
  text-align: left; pointer-events: none;
  opacity: 0; transition: opacity 600ms var(--ease-sys);
  min-height: 74px;
}
.fl__status.is-an { opacity: 1; }
.fl__status b {
  display: block; font-size: clamp(19px, 2vw, 27px); font-weight: 600;
  letter-spacing: -0.02em; line-height: 1.15;
}
.fl__status span { display: block; margin-top: 7px; font-size: 14.5px; color: var(--muted); }
.fl__status--achtung b { color: var(--sicht); }
.fl__status--gut b { color: var(--ergebnis); }

/* Kleine Meldung am Rand, wenn der Blick beim Ablauf bleiben soll. */
.fl__notiz {
  position: absolute; left: 50%; transform: translateX(-50%);
  bottom: 4%; font-size: 13.5px; letter-spacing: 0.02em;
  opacity: 0; transition: opacity 500ms var(--ease-sys);
  color: var(--sicht);
}
.fl__notiz.is-an { opacity: 1; }

/* Wiederholen, dezent. */
.fl__nochmal {
  margin-top: 14px; border: 0; background: transparent; padding: 6px 2px;
  color: var(--muted); font: inherit; font-size: 13px; cursor: pointer;
  transition: color 200ms var(--ease-sys);
}
.fl__nochmal:hover { color: var(--ink); }

@media (max-width: 899px) {
  /* Weniger Systeme gleichzeitig, größere Punkte, Abläufe nacheinander. */
  .fl__p circle { r: 9; }
  .fl__k text { font-size: 17px; }
  .fl__status { max-width: 84%; }
  .fl__status b { font-size: 20px; }
}

@media (prefers-reduced-motion: reduce) {
  .fl__p { animation: none !important; opacity: 1; offset-distance: var(--ruhe, 100%); }
  .fl__p.is-bricht { offset-distance: 54%; opacity: 0.3; }
  .fl__impuls { animation: none !important; }
  .fl__k, .fl__raum, .fl__verlust, .fl__status, .fl__notiz { transition: none !important; }
}

/* Die Notiz begleitet den Ablauf am unteren Rand der Bühne. */
.fl__buehne { position: relative; }
.fl__notiz { bottom: 2%; }

/* ═══ Vereinte Hero-Bühne ═════════════════════════════════════════════════
   Überschrift, CTA und Systemgrafik liegen auf EINER Fläche. Keine Kachel,
   kein Rahmen, kein Schatten um die Grafik — sonst wirkt sie wie ein
   eingebettetes Video neben dem Text statt als dessen Beweis. */

.hero--buehne {
  max-width: var(--max);
  margin: 0 auto;
  padding: clamp(104px, 13vh, 150px) var(--gutter) clamp(48px, 6vw, 80px);
  display: grid;
  gap: clamp(28px, 3.5vw, 56px);
  align-items: center;
  min-height: 100svh;
}
.hero__wort { max-width: 46ch; }
.hero__buehne { position: relative; min-width: 0; }

/* Der Statusbereich hat eine reservierte Höhe: beim Wechsel springt nichts,
   und es kann nie eine zweite Meldung daneben stehen. */
.fl__status {
  margin-top: clamp(10px, 1.6vw, 18px);
  min-height: 82px;
  text-align: left;
}
.fl__quelle-hinweis { margin-top: 2px; font-size: 12px; color: var(--muted); }

/* Maßnahmen sitzen direkt am betroffenen Weg — keine neue Textkarte. */
.fl__mass text {
  fill: var(--sicht); font-family: var(--sans); font-size: 15px;
  font-weight: 500; letter-spacing: 0.01em;
}
.fl__mass { opacity: 0; transition: opacity 700ms var(--ease-sys); }
.fl[data-szene="2"] .fl__mass, .fl[data-szene="3"] .fl__mass,
.fl[data-szene="4"] .fl__mass, .fl[data-szene="5"] .fl__mass,
.fl[data-szene="6"] .fl__mass { opacity: 1; }

/* Der gelöste Weg bleibt ruhig grün — nur er, nichts sonst. */
.fl__geloest {
  fill: none; stroke: var(--ergebnis); stroke-width: 2;
  stroke-dasharray: 1 1; stroke-dashoffset: 1; opacity: 0;
  transition: stroke-dashoffset 1000ms var(--ease-sys), opacity 500ms var(--ease-sys);
}
.fl[data-szene="3"] .fl__geloest, .fl[data-szene="4"] .fl__geloest,
.fl[data-szene="5"] .fl__geloest, .fl[data-szene="6"] .fl__geloest {
  opacity: 1; stroke-dashoffset: 0;
}

/* Messimpuls: ein einzelner ruhiger Puls, kein Dauerblinken. */
.fl__mess circle { fill: none; stroke: var(--ablauf); stroke-width: 1.4; }
.fl__mess { opacity: 0; }
.fl[data-szene="4"] .fl__mess { animation: fl-mess 2000ms var(--ease-sys) 2; }
@keyframes fl-mess {
  0%   { opacity: 0; transform: scale(0.7); transform-origin: 515px 214px; }
  40%  { opacity: 0.8; }
  100% { opacity: 0; transform: scale(1.25); transform-origin: 515px 214px; }
}

@media (min-width: 980px) {
  .hero--buehne { grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); }
  /* Kleiner als zuvor (48 px). Der Hero trägt nur noch die Überschrift und den
     Knopf — der erklärende Absatz steht weiter unten bei den Werkzeugen und
     stand hier doppelt. Bei weniger Text darf die Zeile ruhiger sein. */
  .hero--buehne .hero__title { font-size: clamp(28px, 2.8vw, 40px); max-width: 20ch; line-height: 1.08; }
}
@media (max-width: 979px) {
  /* Eigene senkrechte Komposition: Überschrift, CTA und Vertrauenszeile
     füllen den ersten Bildschirm, die Grafik beginnt darunter.

     Der Satz ist damit auf dem Phone eine geschlossene Aussage: man liest
     ihn zu Ende, bevor irgendetwas anderes ins Bild kommt. Vorher lugte die
     Grafik von unten herein und zog den Blick weg, während der Satz noch
     nicht gelesen war.

     100svh statt 100vh: svh rechnet mit ausgefahrener Browserleiste, also
     der kleinsten je sichtbaren Fläche. 100vh wäre auf iOS und Android um
     die Höhe der Leiste zu hoch — die Vertrauenszeile stünde beim Laden
     unter der Kante. Die Zeile darüber bleibt als Rückfall für Browser
     ohne svh stehen. */
  .hero--buehne {
    grid-template-columns: minmax(0, 1fr);
    min-height: auto;
    /* Der Abstand nach oben sitzt jetzt im Wortblock, weil er dort in die
       Rechnung für den ersten Bildschirm eingeht. */
    padding-top: 0;
    gap: 0;
    align-items: start;
  }
  /* Nur für die Bühnen-Fassung (hero--buehne). Ungescopt griff die Regel
     auch auf den neuen hero--start der Startseite zu: dessen Wortblock
     wurde ein ganzer Bildschirm hoch und mittig gesetzt — die Überschrift
     begann am Telefon erst bei einem Drittel der Höhe. */
  .hero--buehne .hero__wort {
    max-width: 100%;
    box-sizing: border-box;
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* Die Kopfzeile liegt über dem Hero, nicht davor. Ohne diesen Ausgleich
       säße die Mitte des Satzes optisch zu hoch. */
    padding-top: var(--kopf-hoehe, 74px);
    padding-bottom: clamp(20px, 4vh, 40px);
  }
  .hero--buehne .hero__buehne { margin-top: clamp(28px, 7vh, 64px); }

  .fl__status { min-height: 96px; }
  .fl__mass text { font-size: 16px; }
  .fl__k text { font-size: 19px; }
}

/* ═══ Überschrift am Phone: ein Satz, kein Wortstapel ═════════════════════
   `text-wrap: balance` gleicht Zeilenlängen aus. Auf breiten Schirmen liest
   sich das ruhig. Auf 390 px kam dabei — gemessen von 320 bis 430 px —
   durchgehend heraus:

       Wir bauen Websites, / die passende / Anfragen bringen.

   Die zweite Zeile war halb leer, „passende" und „Anfragen" standen
   auseinandergerissen. Der Grund ist nicht der Umbruchalgorithmus allein,
   sondern der Schriftgrad: 9,2vw sind auf 390 px 35,9 px, davon passen
   knapp zwei Wörter in eine Zeile.

   Zwei Änderungen, beide nur unterhalb 900 px:
   · eine Stufe kleiner — die Überschrift bleibt der größte Text der Seite,
     aber es passen wieder ganze Satzteile in eine Zeile,
   · `pretty` statt `balance` — füllt die Zeile normal und verhindert nur
     noch die alleinstehende Schlusszeile.
   Über 900 px bleibt alles, wie es war. */
@media (max-width: 899px) {
  .hero--buehne .hero__title {
    /* Die Untergrenze greift ab 338 px abwärts. Bei 25 px verfehlte
       „Wir bauen Websites, die" die 280 px nutzbare Breite um zwei Pixel und
       die alte Fünfzeilen-Treppe kam zurück. */
    font-size: clamp(23px, 6.8vw, 38px);
    line-height: 1.06;
    text-wrap: pretty;
    /* Kein Wort soll allein in einer Zeile stehen können. */
    hyphens: none;
  }
}

/* ═══ Sechs Quellen ═══════════════════════════════════════════════════════
   Die Systeme wandern von ihrer ungeordneten Lage in einen Ring. Sie
   verschwinden nicht und werden nicht ersetzt — der Kern koordiniert nur. */

.qu__buehne { position: relative; margin-top: clamp(28px, 3.4vw, 48px); }
/* Bezugsfläche für die Statusmeldung: genau die Grafik, ohne die Zeile
   darüber. */
.qu__flaeche { position: relative; }
.qu__n {
  transform: translate(var(--tx0), var(--ty0));
  transition: transform 1600ms var(--ease-sys);
}
.qu.is-geordnet .qu__n { transform: translate(var(--tx1), var(--ty1)); }

.qu__kern { opacity: 0; transition: opacity 900ms var(--ease-sys); }
.qu.is-geordnet .qu__kern { opacity: 1; }
.qu__kern circle { fill: var(--flaeche); stroke: var(--line-2); stroke-width: 1.2; }
.qu__kern text {
  fill: var(--ink); font-family: var(--sans); font-size: 15px;
  font-weight: 600; text-anchor: middle; letter-spacing: -0.01em;
}
.qu.is-bestaetigt .qu__kern circle { stroke: var(--ergebnis); }

.qu .fl__raum { stroke-width: 1.2; }

/* Die Meldung steht IM Ring, nicht darunter. Zwischen dem oberen Knoten und
   dem Kern liegen rund 100 Einheiten frei — dort gehört sie hin, sonst hängt
   sie losgelöst unter der Fläche und man liest sie getrennt vom Vorgang.
   Der Platz reicht für zwei Zeilen; die Höhe ist reserviert, damit beim
   Wechsel nichts springt. */
.qu__buehne { position: relative; }

/* Nur ab 900 px: Dort ist der Ring groß genug, dass die Meldung zwischen dem
   oberen Knoten und dem Kern Platz hat. Darunter ist die Bühne rund 210 px
   hoch — eine Meldung im Ring würde dort jeden Knoten verdecken. */
@media (min-width: 1200px) {
  /* Gilt nur noch fuer Buehnen ohne Gehirn. Im Gehirn ist die Mitte belegt. */
  .qu:not(:has(.gh)) .fl__status {
    position: absolute;
    left: 50%;
    /* Im freien Band zwischen oberem Knoten und Kern ZENTRIERT.

       Der Bezug ist .qu__flaeche, nicht die ganze Bühne. Vorher hing die
       Meldung an .qu__buehne — als die Zeile „Alles ist da." darüberkam,
       wuchs die Bühne, und 34 % lagen plötzlich im oberen Knoten statt im
       freien Band.

       Im Koordinatenraum 1000 × 700: der obere Knoten endet geordnet bei
       y 160, der Kern beginnt bei y 304. Bandmitte 232, das sind 33 %. */
    top: 34%;
    transform: translate(-50%, -50%);
    width: min(35%, 380px);
    text-align: center;
    min-height: 0;
    margin: 0;
    /* Grund hinter der Schrift, damit die Ringlinie nicht hindurchläuft. */
    background: radial-gradient(ellipse at center,
      var(--canvas) 0%, var(--canvas) 62%, transparent 100%);
    padding: 4px 10px;
  }
  .qu .fl__status b { font-size: clamp(16px, 1.5vw, 21px); }
  .qu .fl__status span { font-size: 14px; }
  .qu .fl__nochmal { position: relative; z-index: 1; }
}

@media (max-width: 1199px) {
  /* Unter der Fläche, im normalen Fluss. Darüber ist der Ring zu klein:
     die Meldung würde den Kern verdecken — gemessen bei 1024 und 900 px. */
  .qu .fl__status { position: static; text-align: left; min-height: 104px; }
}

@media (max-width: 899px) {
  /* Der Ring wird nicht geschrumpft — er bekommt mehr Raum, die Punkte
     werden größer, und die Beschriftung bleibt lesbar. Die Maße gelten im
     stehenden Koordinatenraum 440 × 810, den `quellen-hochkant.js` setzt:
     bei 390 px Fensterbreite ist der Maßstab 0,80, aus 21 Einheiten Schrift
     werden also knapp 17 CSS-Pixel. */
  .qu .fl__k text { font-size: 21px; }
  .qu__kern text { font-size: 23px; }
  .qu .fl__p circle { r: 13; }
  .qu .fl__status { min-height: 104px; }

  /* Die Bühne bekommt den ganzen Schirm. Wer bis hierher gescrollt hat, sieht
     die Animation und sonst nichts — Überschrift und Handlungsaufruf sind
     dann nach oben aus dem Bild gelaufen. Das war der Grund, warum die
     Bewegung vorher unruhig wirkte: sie lief in einem 245 px hohen Streifen
     zwischen zwei anderen Textblöcken. */
  .hero--buehne .hero__buehne {
    min-height: 100svh;
    display: grid;
    align-content: center;
    padding-block: clamp(12px, 3vw, 28px);
  }
  .qu__buehne { margin-top: 0; }

  /* Ohne Deckel würde die stehende Bühne mit der Fensterbreite mitwachsen:
     bei 899 px sind 809 px Inhaltsbreite nutzbar, das Format 440 × 810
     ergäbe daraus 1490 px Höhe — zwei Bildschirme hoch. Gedeckelt wird die
     BREITE, nicht die Höhe: sonst bliebe die Zeichnung in einem zu breiten
     Kasten stehen und liefe oben und unten mit Leerraum aus. 380 px sind
     genau die Breite, aus der 700 px Höhe werden.
     Auf einem Phone greift der Deckel nicht — dort sind 350 px nutzbar. */
  .qu__svg--hochkant {
    max-width: 380px;
    margin-inline: auto;
  }
}

/* ═══ Ein Ziel. Viele Signale. ════════════════════════════════════════════
   Zahlen statt Erklärkästen. Das System nimmt zurück, was gerade nicht zählt. */

.sg__buehne { margin-top: clamp(30px, 3.6vw, 50px); }
.sg__ziel { display: grid; gap: 8px; }
.sg__ziel span { font-size: 10.5px; letter-spacing: 0.17em; text-transform: uppercase; color: var(--sicht); }
.sg__ziel b { font-family: var(--serif); font-style: normal; font-weight: 400;
  font-size: clamp(28px, 3.4vw, 46px); line-height: 1.04; letter-spacing: -0.025em; }

.sg__signale {
  list-style: none; margin-top: clamp(28px, 3.2vw, 44px);
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 1px; background: var(--line); border-block: 1px solid var(--line);
}
.sg__s {
  background: var(--canvas); padding: 20px 18px;
  opacity: 0; transform: translateY(10px);
  transition: opacity 700ms var(--ease-sys), transform 700ms var(--ease-sys);
}
.sg.is-signale .sg__s { opacity: 1; transform: none; }
.sg__s b { display: block; font-size: clamp(26px, 2.6vw, 36px); font-weight: 500;
  letter-spacing: -0.04em; font-variant-numeric: tabular-nums; }
.sg__s span { display: block; margin-top: 5px; font-size: 13.5px; color: var(--muted); line-height: 1.4; }
.sg__s--sicht b { color: var(--sicht); }
.sg__s--anfrage b { color: var(--anfrage); }
.sg__s--ablauf b { color: var(--ablauf); }
.sg__s--ergebnis b { color: var(--ergebnis); }

/* Der Befund: was nicht zählt, tritt zurück. Kein Text erklärt das — man sieht es. */
.sg.is-befund .sg__s[data-rolle="vorhanden"] { opacity: 0.26; }

.sg__befund, .sg__hebel { opacity: 0; transform: translateY(10px);
  transition: opacity 800ms var(--ease-sys), transform 800ms var(--ease-sys); }
.sg.is-befund .sg__befund { opacity: 1; transform: none; }
.sg.is-hebel .sg__hebel { opacity: 1; transform: none; }

.sg__befund { margin-top: clamp(26px, 3vw, 38px); display: grid; gap: 7px; max-width: 46ch; }
.sg__befund b { font-size: clamp(19px, 2vw, 26px); font-weight: 600; letter-spacing: -0.02em; }
.sg__befund span { font-size: clamp(19px, 2vw, 26px); font-weight: 600; letter-spacing: -0.02em; color: var(--anfrage); }

.sg__hebel { margin-top: clamp(22px, 2.6vw, 32px); padding-top: 20px;
  border-top: 1px solid var(--line); display: grid; gap: 8px; max-width: 46ch; }
.sg__hebel span { font-size: 10.5px; letter-spacing: 0.17em; text-transform: uppercase; color: var(--sicht); }
.sg__hebel b { font-size: clamp(19px, 1.9vw, 25px); font-weight: 600; letter-spacing: -0.018em; }
.sg__quelle { margin-top: 18px; font-size: 12px; color: var(--muted); }

@media (max-width: 899px) {
  .sg__signale { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sg__s { padding: 16px 14px; }
}
@media (prefers-reduced-motion: reduce) {
  .sg__s, .sg__befund, .sg__hebel { transition: none !important; }
}

/* Im Ring steht nur die eine große Aussage. Gemessen: das freie Band zwischen
   oberem Knoten und Kern ist rund 78 px hoch, Titel plus Beisatz brauchen 128.
   Der Beisatz entfällt dort — „keine langen Texte innerhalb der Grafik". */
@media (min-width: 1200px) {
  .qu .fl__status span { display: none; }
  .qu .fl__status b { font-size: clamp(15px, 1.35vw, 19px); line-height: 1.25; }
}

/* Arabisch baut höher als lateinische Schrift: dieselbe Meldung lief in der
   Naskh auf zwei Zeilen und ragte gemessen 3 px in den Kern. Eine Stufe
   kleiner hält sie im freien Band. */
@media (min-width: 1200px) {
  [dir="rtl"] .qu .fl__status b { font-size: clamp(15px, 1.4vw, 19px); line-height: 1.35; }
}

/* ═══ Das Gehirn ═══════════════════════════════════════════════════════════
   Die Form entsteht aus dem, was verbunden wird. Deshalb wächst zuerst jede
   Verbindung vom System zum Kern, und erst wenn sie stehen, schließt sich der
   Umriss. Umgekehrt wäre es Dekoration: eine Gehirnform, in die etwas
   hineingezeichnet wird.

   Gezeichnet wird über stroke-dashoffset — eine Linie, die sich selbst zieht,
   statt einer, die eingeblendet wird. Der Unterschied ist der zwischen
   „wächst" und „erscheint".
   ═════════════════════════════════════════════════════════════════════════ */

.gh__umriss, .gh__furche {
  fill: none;
  stroke: var(--ink-2);
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Die Länge jeder Linie ist über das Attribut `pathLength="1"` am Element
     auf 1 normiert; deshalb genügt hier die 1 als Strichlänge. Als CSS-
     Eigenschaft gibt es pathLength nicht — sie stand hier und wurde still
     verworfen, wodurch aus der 1 ein Pixel wurde: der Umriss war ein
     Strichmuster von 1 px auf 2001 px Weg und hat sich nie gezeichnet. */
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}
.gh__umriss { stroke-width: 2.2; }
.gh__furche { stroke-width: 1.3; }

/* Der Umriss kommt zuletzt: erst mit der Bestätigung ist es ein Gehirn. */
.fl.is-bestaetigt .gh__umriss {
  opacity: 0.9;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 2400ms var(--ease-sys), opacity 500ms var(--ease-sys);
}
.fl.is-bestaetigt .gh__furche {
  opacity: 0.4;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1600ms var(--ease-sys) 900ms,
              opacity 500ms var(--ease-sys) 900ms;
}

/* Die Verbindungen. Sie wachsen gestaffelt, sobald geordnet wird. */
.gh__bahn {
  fill: none;
  stroke: var(--line-2);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}
.fl.is-geordnet .gh__bahn {
  opacity: 1;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 1100ms var(--ease-sys) var(--v, 0ms),
              opacity 400ms var(--ease-sys) var(--v, 0ms);
}
.fl.is-bestaetigt .gh__bahn { stroke: var(--ergebnis); opacity: 0.55; }

/* Die Systeme: Punkt und Wort, kein Kasten. Ein Kasten von 132 × 76 Einheiten
   deckt bei neun Stück den Umriss zu. */
.gh__k text {
  fill: var(--muted);
  font-family: var(--sans);
  font-size: 19px;
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: fill 600ms var(--ease-sys);
}
.gh__punkt {
  fill: var(--flaeche);
  stroke: var(--line-2);
  stroke-width: 1.6;
  transition: stroke 600ms var(--ease-sys), fill 600ms var(--ease-sys);
}
.fl.is-geordnet .gh__punkt { stroke: var(--ink-2); }
.fl.is-bestaetigt .gh__punkt { stroke: var(--ergebnis); fill: var(--ergebnis); }
.fl.is-bestaetigt .gh__k text { fill: var(--ink-2); }
.gh__k.is-achtung .gh__punkt { stroke: var(--sicht); fill: var(--sicht-fl); }
.gh__k.is-achtung text { fill: var(--sicht); }

/* Der Kern trägt keinen Rahmen mehr — im Gehirn ist er die Stelle, an der
   alles zusammenläuft, nicht ein weiterer Kasten. */
.gh__kern circle {
  fill: var(--flaeche);
  stroke: var(--line-2);
  stroke-width: 1.6;
  transition: stroke 700ms var(--ease-sys), stroke-width 700ms var(--ease-sys);
}
.fl.is-geordnet .gh__kern circle { stroke: var(--ink); stroke-width: 2; }
.fl.is-bestaetigt .gh__kern circle { stroke: var(--ergebnis); }

/* Die alte Ellipse gibt es nicht mehr. */
.gh .fl__raum { display: none; }

/* ── Zwei Fassungen ──────────────────────────────────────────────────────
   Dieselbe Form, zweimal gezeichnet: liegend für den Schreibtisch, stehend
   fürs Telefon. Grund ist die Schriftgröße. Die Schrift steht in Einheiten
   des Koordinatenraums, gerendert wird sie mit dem Maßstab Fläche geteilt
   durch Raumbreite. Bei 390 px Fensterbreite und dem liegenden Raum von
   920 Einheiten sind das 0,42 — aus 21 Einheiten würden 8,9 CSS-Pixel.
   Die stehende Fassung zeichnet die Form kleiner und gewinnt damit den
   Platz, den die Wörter daneben brauchen: Maßstab 0,65, also 13,7 px.

   Umgeschaltet wird bei 979 px, wo die Bühne ohnehin einspaltig wird. Bei
   1024 px ist die Fläche 523 px breit; die liegende Fassung ergäbe dort nur
   10,8 px Schrift, die stehende 17,7 px.

   Die frühere Regel setzte hier 25 px und einen größeren Punktradius. Beides
   war wirkungslos: `.qu .fl__k text` ist spezifischer und hat gewonnen. */
.gh--hoch { display: none; }
@media (max-width: 979px) {
  .gh--breit { display: none; }
  .gh--hoch { display: block; }
}

/* Strichstärken sind Pixel im Koordinatenraum. Im schmaleren Raum der
   stehenden Fassung kämen dieselben Zahlen dünner an, deshalb hier größer:
   2,7 × 0,65 ergibt dieselben 1,76 px wie 2,2 × 0,80. */
.gh--hoch .gh__umriss { stroke-width: 2.7; }
.gh--hoch .gh__furche { stroke-width: 1.6; }
.gh--hoch .gh__bahn { stroke-width: 1.7; }
.gh--hoch .gh__punkt { stroke-width: 2; }
.gh--hoch .gh__synapse { stroke-width: 1.3; }

/* Die Schrift steht in Einheiten des Koordinatenraums, gerendert wird sie mit
   dem Maßstab Fläche/Raumbreite. Die Fläche schrumpft von 735 px bei 1440 auf
   500 px bei 980 — bei fester Einheitengröße fiele die Schrift von 15,2 auf
   10,3 px. Deshalb wächst sie stufenweise mit, sodass beim Leser ungefähr
   dieselben 15 px ankommen. Bei 25 Einheiten braucht das längste Wort
   („Justificatifs") 169 Einheiten; bis zum Rand sind 188 frei. */
.gh--breit .gh__k text, .gh--breit .gh__kern text { font-size: 19px; }
@media (max-width: 1399px) {
  .gh--breit .gh__k text, .gh--breit .gh__kern text { font-size: 21px; }
}
@media (max-width: 1279px) {
  .gh--breit .gh__k text, .gh--breit .gh__kern text { font-size: 23px; }
}
@media (max-width: 1149px) {
  .gh--breit .gh__k text, .gh--breit .gh__kern text { font-size: 25px; }
}
.gh--hoch .gh__k text { font-size: 21px; }
/* 20 statt 23: bei 23 Einheiten war „acessio" 84 Einheiten breit und
   der Kern 84 Einheiten im Durchmesser — das Wort saß auf dem Rand. */
.gh--hoch .gh__kern text { font-size: 20px; }

/* ── Synapsen ────────────────────────────────────────────────────────────
   Mit der letzten Verbindung ist die Grafik nicht fertig, sondern fängt an
   zu arbeiten: zwischen benachbarten Bahnen entstehen Querverbindungen, und
   auf ihnen schießen Impulse hin und her. Sie kommen nacheinander — erst
   eine, dann immer mehr —, damit man das Wachsen sieht und nicht ein fertiges
   Netz vorgesetzt bekommt.

   Die Sprossen sind dünner und blasser als die Bahnen. Sie sind die zweite
   Ebene, nicht eine zweite Hauptsache. */
.gh__synapse {
  fill: none;
  stroke: var(--ergebnis);
  stroke-width: 1.1;
  stroke-linecap: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
  opacity: 0;
}
.fl.is-bestaetigt .gh__synapse {
  opacity: 0.38;
  stroke-dashoffset: 0;
  transition: stroke-dashoffset 620ms var(--ease-sys) var(--s, 0ms),
              opacity 400ms var(--ease-sys) var(--s, 0ms);
}

/* Der Impuls. Grundzustand unsichtbar: während der Verzögerung gilt noch
   diese Regel, sonst stünden alle Punkte von Anfang an auf ihrem Startpunkt
   herum. Jeder zweite läuft rückwärts — daher das Hin und Her. */
.gh__feuer { opacity: 0; }
.gh__feuer circle { fill: var(--ergebnis); }
.fl.is-bestaetigt .gh__feuer {
  animation: gh-feuer var(--d, 2400ms) var(--ease-sys) var(--s, 0ms) infinite;
}
@keyframes gh-feuer {
  0% { offset-distance: 0%; opacity: 0; }
  9% { opacity: 0.95; }
  44% { offset-distance: 100%; opacity: 0.95; }
  54% { offset-distance: 100%; opacity: 0; }
  100% { offset-distance: 100%; opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .gh__synapse { opacity: 0.38; stroke-dashoffset: 0; transition: none !important; }
  .fl.is-bestaetigt .gh__feuer { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
  /* Ohne Bewegung steht die fertige Form sofort. */
  .gh__umriss { opacity: 0.9; stroke-dashoffset: 0; }
  .gh__furche { opacity: 0.4; stroke-dashoffset: 0; }
  .gh__bahn { opacity: 0.55; stroke-dashoffset: 0; }
  .gh__umriss, .gh__furche, .gh__bahn { transition: none !important; }
}


/* Im Gehirn steht die Meldung unter der Grafik. Innen ist kein freies Band
   mehr: der Kern nimmt die Mitte, die Verbindungen den Rest. Gemessen deckte
   die Meldung dort die Beschriftungen „Nachweise" und „Sichtbarkeit" zu. */
.qu:has(.gh) .fl__status {
  position: static;
  text-align: center;
  margin: clamp(10px, 1.4vw, 18px) auto 0;
  max-width: 46ch;
  min-height: 84px;
}
.qu:has(.gh) .fl__status b { font-size: clamp(17px, 1.7vw, 23px); line-height: 1.25; }

/* ── Hero: ein Band, zwei Spalten, ein Bildschirm ─────────────────────────
   Links Aussage, Aufforderung, Vertrauenszeile und der Gründer als ein
   Element untereinander. Rechts die Systemgrafik. Beides mittig in der
   Bildschirmhöhe, nichts wird angeschnitten.

   Die Höhenkette ist der Kern: fester Hero, `min-height: 0` auf jeder Stufe,
   und die Grafik richtet sich nach der Zeile statt nach ihrer Breite. Sonst
   wird das SVG so hoch wie breit — unabhängig vom Schriftgrad.

   Reihenfolge beachten: die Grundregeln stehen VOR der Medienabfrage. Standen
   sie dahinter, haben sie bei gleicher Spezifität gewonnen und das Porträt
   blieb bei 200 px Breite stehen, statt auf Bildschirmhöhe zu schrumpfen. */

/* Grundfassung — gilt am Phone und als Rückfall. */
.hero__gruender { margin: 0; display: grid; justify-items: center; }
.hero__gruender img { width: 100%; max-width: 200px; height: auto; display: block; }
.hero__gruender figcaption { margin-top: 10px; text-align: center; }
.hero__gruender figcaption b {
  display: block; font-family: var(--serif); font-weight: 400;
  font-size: clamp(17px, 1.4vw, 21px); letter-spacing: -0.02em;
  color: var(--ink); line-height: 1.15;
}
.hero__gruender figcaption span {
  display: block; margin-top: 2px; font-size: clamp(12.5px, 1vw, 14px); color: var(--muted);
}

@media (min-width: 980px) {
  .hero.hero--buehne {
    grid-template-columns: minmax(0, 0.86fr) minmax(0, 1.14fr);
    grid-template-rows: minmax(0, 1fr);
    align-items: center;
    gap: clamp(28px, 3.5vw, 64px);
    padding-top: calc(var(--kopf-hoehe) + clamp(8px, 1.6vh, 24px));
    padding-bottom: clamp(20px, 3.5vh, 48px);
    height: 100svh;
    min-height: 620px;
    overflow: hidden;
  }

  .hero__links {
    min-height: 0;
    display: grid;
    align-content: center;
    gap: clamp(14px, 2.4vh, 30px);
  }

  .hero.hero--buehne .hero__wort { max-width: none; text-align: left; }
  .hero.hero--buehne .hero__title {
    max-width: 17ch;
    margin-inline: 0;
    font-size: clamp(28px, 2.6vw, 40px);
    line-height: 1.06;
  }
  .hero.hero--buehne .hero__actions { justify-content: flex-start; margin-top: clamp(14px, 2vh, 24px); }
  .hero.hero--buehne .hero__trust  { justify-content: flex-start; margin-top: clamp(8px, 1.4vh, 16px); }

  /* Bild links, Name rechts daneben: als Zeile frisst der Gründer kaum Höhe. */
  .hero.hero--buehne .hero__gruender {
    min-height: 0;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 16px;
  }
  .hero.hero--buehne .hero__gruender img {
    width: auto;
    max-width: none;
    height: clamp(96px, 13vh, 150px);
  }
  .hero.hero--buehne .hero__gruender figcaption { margin-top: 0; text-align: left; }

  .hero__buehne { min-height: 0; height: 100%; margin-top: 0; display: grid; align-items: center; }
  .hero__buehne .qu__flaeche { min-height: 0; height: 100%; display: grid; align-items: center; }
  .hero__buehne .fl__svg { height: 100%; width: 100%; max-height: 100%; min-height: 0; }
}
