/* ==========================================================================
   Baustein: Kennzahlen-Block (Sektion 8)
   Datei: css/bausteine/kennzahlen-block.css
   Gebraucht auf: index.html, work-zone.html (Beweis: Logo-Laufband ohne Zahl, Zahl mit Icon, Zitat-Kachel)
   Bauvorschrift: DESIGN.md, Baustein "Kennzahlen-Block"
   Regeln: docs/entwicklung.md. Klassen-Präfix dieser Datei siehe unten,
   Tokens und Rollen kommen aus css/style.css und werden hier nicht neu definiert.

   Abweichung von der Bauvorschrift, Vorgabe aus der Build-Session 2026-09-08:
   Statt drei gleich großen Zellen in einem Rahmen ein Bento-Raster aus Kacheln
   unterschiedlicher Größe. Beibehalten sind alle Maße und Rollen des Bausteins:
   28px Innenabstand, Zahl in display-3, Bezug in label --muted. Der Rahmen --line
   um das Ganze weicht getrennten Kachelflächen, Abstand ist --gap (10px) nach D7.

   Stand 2026-09-16 (Weisung Christian Hansmann, Vorlage awesomic.com, Sektion
   "Why teams choose Awesomic"): das Bento bleibt, wird aber beruhigt. Dort tragen
   alle Kacheln dieselbe helle Fläche (zinc-100 auf Weiß), keinen Rahmen, einen
   großen Radius und 28 px Innenabstand. Die Hierarchie macht allein die Kachelgröße,
   nicht die Farbe. Übersetzt auf unsere Palette (D17): jede Kachel liegt in --paper
   auf der weißen Sektionsfläche, Radius --r-xl (20 px, unser größter regulärer
   Radius; --r-section 40 ist nach D20 den Sektionskanten vorbehalten), kein Rahmen.
   Damit entfallen die dunkle Ankerkachel (--ink), die blaue Akzentkachel (--blue)
   und die Kunstfläche mit der Wortmarke samt Verlauf. Die Ankerkachel trägt ihren
   Vorrang jetzt über Fläche (2x2) und die Zahl in display-2.
   Abweichung von der Bauvorschrift, Nachtrag Phase 4 offen.
   ========================================================================== */

/* Präfix: .kpi-* */

/* --------------------------------------------------------------------------
   Sektionskopf, linksbündig (Vorgabe 2026-09-08)
   Stand 2026-09-14 (D20): .kpi-head ist im Markup durch .section-head ersetzt,
   der Kopf ist site-weit linksbündig ohne Eyebrow. Der Text darunter ist Historie.

   Abweichung vom Baustein "Sektionskopf": der setzt die display-2 rechts auf
   76 Prozent Breite, mit dem Eyebrow links daneben. Hier stehen Eyebrow und
   Zeile linksbündig untereinander, also genau das Bild, das .section-head ab
   980 px ohnehin zeigt. Für die anderen Sektionen gilt der Baustein weiter.

   Deshalb .kpi-head statt .section-head am Element, und keine Regel auf
   .section-head, .display-2 oder .eyebrow: sonst kippen alle Sektionen mit
   (docs/entwicklung.md, Regel 4). Gleiches Vorgehen wie .slider-head in
   Sektion 7 (Referenzen).

   Die Klasse trägt bewusst keine eigene Regel. Sie ist nur der Verzicht auf
   .section-head, alles andere kommt aus style.css: .display-2 läuft dann über
   die Breite des Containers, der Abstand unter dem Eyebrow sind die 24 px aus
   .eyebrow. Der Abstand nach unten bleiben die 72 px aus .kpi-bento.
   -------------------------------------------------------------------------- */

/* Eigene Klasse an der H2 statt einer Regel auf .section-head oder .display-2: sonst kippen
   alle Sektionen mit (docs/entwicklung.md, Regel 4). Sie trägt nur den Umbruch: "Warum
   Unternehmen ruff_consult wählen" (Wortlaut Christian Hansmann, 2026-09-16, ohne Punkt)
   ließ bei 1440 px sonst "wählen" allein in der zweiten Zeile stehen. */
.kpi-title { text-wrap: balance; }

/* Drei Spalten, jede eine eigene Liste (Weisung Christian Hansmann, 2026-09-17).

   Vorgeschichte: Am 2026-09-16 lief das Bento im Mehrspaltensatz (columns), damit jede
   Kachel nur so hoch ist wie ihr Inhalt. Der Mehrspaltensatz verteilt aber selbst und kann
   Kacheln nicht dehnen, die Spalten endeten deshalb auf verschiedenen Höhen. Jetzt gilt:
   die Spalten sind gleich hoch, und den Ausgleich macht je Spalte eine Kachel, die ihren
   Leerbereich wachsen und schrumpfen lässt (.kpi-tile--dehnt). Alle anderen Kacheln bleiben
   so hoch wie ihr Inhalt. Dafür braucht es echte Spalten, also Flex statt columns, und die
   Zuordnung Kachel zu Spalte steht im Markup. Der erzwungene Umbruch
   (.kpi-tile--spaltenende, break-after) ist damit gegenstandslos und entfernt. */
.kpi-bento {
  margin: 72px 0 0;
  display: flex;
  align-items: stretch;
  gap: var(--gap);
}
.kpi-col {
  list-style: none;
  margin: 0;
  padding: 0;
  flex: 1 1 0;
  min-width: 0;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--gap);
}
/* Die Spalte darf nie breiter werden als ihr Platz. Ohne die Deckelung zieht die Logospur
   in der Kunden-Kachel (zwei Spuren, zusammen rund 2.400 px, flex: none) ihre Spalte auf
   ihre eigene Breite, sobald der Bento untereinander läuft und die Breite nicht mehr aus
   flex-basis kommt. Die Spur selbst bleibt beschnitten, sie steckt in overflow: hidden. */
.kpi-tile { max-width: 100%; }

/* Grundform jeder Kachel: Kategorie oben, darunter Zahl mit Bezug. Seit 2026-09-16 alles
   am oberen Rand statt Kategorie oben und Zahl unten (space-between): so stehen die Zahlen
   benachbarter Kacheln auf einer Höhe, statt je nach Textlänge zu versetzen. Das ist der
   Aufbau der Vorlage (awesomic.com, "Why teams choose Awesomic"). */
.kpi-tile {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 28px;
  padding: 28px;
  min-width: 0; /* damit die Logospur die Kachel nicht aufzieht */
  background: var(--paper); /* eine Fläche für alle Kacheln, 2026-09-16 */
  border: 0;
  border-radius: var(--r-xl);
}

/* Die dehnbare Kachel je Spalte: sie nimmt die Höhe auf, die der Spalte zum Ausgleich fehlt.
   Wo der Leerbereich in ihr entsteht, steht beim jeweiligen Baustein weiter unten
   (Marke-Kachel, Bildkachel, Skills-Kachel). */
.kpi-tile--dehnt { flex: 1 1 auto; }

/* Bento auf Hell (2026-09-29, work-zone.html, dort Fortsetzung der Fläche des Ablaufs): Die
   Kacheln tragen Weiß statt --paper, nach der Regel "Karten stehen auf der jeweils anderen
   hellen Fläche" (DESIGN.md). Ohne den Modifier stünden sie unsichtbar auf gleichem Grund.
   Auf der Startseite ohne Verwendung, dort steht das Bento auf Weiß. */
.kpi-bento--auf-hell .kpi-tile { background: var(--white); }

/* Rollen kommen aus style.css, hier nur Abstand, Farbe und Umbruch. */
.kpi-eyebrow { color: var(--muted); }
.kpi-prefix  { color: var(--muted); margin-bottom: 4px; }
.kpi-value   { display: block; }
.kpi-note    { margin-top: 14px; max-width: 34em; }

/* Partner-Signet in der Kachel "Jahre SAP-Partnerschaft" (2026-10-12).
   Weisung vom selben Tag: ueber dem Text, auf einer Hoehe mit "10+", rechtsbuendig.
   Dafuer eine eigene Kopfzeile mit zwei Spalten. Die linke bleibt die gewohnte
   .kpi-headline aus Zahl und Bezug, damit die Kachel sich von den anderen nicht
   unterscheidet, die rechte nimmt das Signet auf.
   align-items: flex-start stellt die Oberkante des Signets auf die Oberkante der Zahl.
   margin-left: auto braucht es nicht, space-between schiebt es an den rechten Rand.
   Das Signet bringt eigene Farben mit (SAP-Blau, Gold, dunkles Rot), die nicht aus der
   Palette stammen. Das ist bei einer fremden Marke richtig so und keine Abweichung von
   D17: Markenzeichen Dritter werden nicht eingefaerbt. */
.kpi-kopfzeile {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 20px;
}
.kpi-partnerlogo {
  display: block;
  flex: none;
  width: 120px;
  height: auto;
}

/* Zahl zuerst, Bezug darunter (Weisung Christian Hansmann, 2026-09-16, Aufbau der Vorlage
   awesomic.com: "4 000+" groß, "Customers" klein darunter). Vorher stand der Bezug als
   Kategorie über der Zahl. Beide gehören eng zusammen, deshalb ein eigener Block mit 6 px
   statt der 28 px, die .kpi-tile zwischen seinen Blöcken lässt. */
.kpi-headline { display: flex; flex-direction: column; gap: 6px; }
/* Der Fließtext ist jetzt direktes Kind der Kachel, den Abstand trägt der gap der Kachel. */
.kpi-tile > .kpi-note { margin-top: 0; }

/* Die Ankerkachel (.kpi-tile--anchor, "über 77.000 Mitarbeiter", MAHLE) ist am
   2026-09-16 auf Weisung Christian Hansmann entfernt. Mit ihr sind auch die
   Regeln dieser Klasse weg, es gibt keine Kachel mit Sonderformat mehr.
   Ebenfalls unbenutzt, aber stehen geblieben, weil harmlos und generisch:
   .kpi-prefix (das "über" stand nur auf dieser Kachel). */


/* --------------------------------------------------------------------------
   Bildkachel (2026-09-17, Weisung Christian Hansmann)
   Die Kachel ist das Bild: kein Innenabstand, kein gap, die Datei laeuft bis an die
   Kante und der Radius der Kachel schneidet sie (overflow). Die Hoehe macht das Bild
   selbst ueber sein Seitenverhaeltnis, deshalb height auto und keine feste Hoehe: im
   Mehrspaltensatz ist jede Kachel ohnehin nur so hoch wie ihr Inhalt. Zwei Dateien mit
   verschiedenem Format (trees-wide 8:3, trees-portrait 8:9), damit die zwei Kacheln im
   Bento nicht gleich aussehen. Der Bezug zur Flaeche --paper entfaellt hier, das Bild
   deckt sie vollstaendig ab.
   -------------------------------------------------------------------------- */
.kpi-tile--bild {
  padding: 0;
  gap: 0;
  overflow: hidden;
}
.kpi-tile--bild img {
  display: block;
  width: 100%;
  height: auto;
}
/* Dehnt die Bildkachel, füllt das Bild die zusätzliche Höhe und wird dabei beschnitten,
   statt einen leeren Streifen zu lassen. */
.kpi-tile--bild.kpi-tile--dehnt img { flex: 1 1 auto; min-height: 0; height: 100%; object-fit: cover; }

/* Text auf dem Bild (2026-09-17, Weisung Christian Hansmann). Er steht mittig in beiden
   Achsen, in heading-m (25 px), fett und fest über zwei Zeilen. Die zwei Zeilen macht ein
   <br> im Markup, nicht der Umbruch des Browsers: der trennte "1.000" von "EUR".
   Deshalb ist text-wrap: balance hier wieder weg, es hat mit dem festen Umbruch keine
   Aufgabe mehr. Eine Abdunklung unter dem Text gibt es nicht mehr: der
   Verlauf an der unteren Kante ist am 2026-09-17 auf Weisung entfernt. Weiß steht damit
   direkt auf dem Bild, der Kontrast ist an den hellen Stellen entsprechend niedrig, siehe
   README.md. Position relativ zur Kachel, das Bild bleibt im Fluss. */
.kpi-tile--bildtext { position: relative; }

/* Zweites Bild beim Hover (2026-10-08, Weisung: "Hintergrundbild veraendert sich",
   "Text ist immer sichtbar und veraendert sich nicht").
   Die Ebene liegt ueber dem Bild und unter dem Text: Das Bild steht im Fluss und hat
   damit keinen Stapelplatz, .kpi-bild-text hat z-index 1, diese Ebene liegt mit 0
   dazwischen. Der Text bleibt dadurch waehrend des ganzen Wechsels oben und unberuehrt.

   Das Bild darunter blendet nicht selbst ab, diese Ebene ist deckend und legt sich
   darueber. Das spart eine zweite Animation und sieht gleich aus.

   object-fit: cover, weil die zwei Bilder verschiedene Seitenverhaeltnisse haben:
   dom-wide.webp ist 2000 x 668 (2,99:1), trees-wide.webp 1400 x 525 (2,67:1). Den Rahmen
   gibt das erste Bild vor, das zweite wird darin beschnitten, rund 11 Prozent der Breite.
   Der Selektor nennt Klasse und Element, damit er .kpi-tile--bild img schlaegt, das
   width: 100% und height: auto setzt.

   Weisses auf diesem Bild ist stellenweise sehr knapp, siehe README.md. Auf Weisung vom
   2026-10-08 bleibt das Bild wie es ist, es wird hier also nicht abgedunkelt. */
.kpi-tile--wechselbild img.kpi-bild-wechsel {
  position: absolute;
  z-index: 0;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  opacity: 0;
  transition: opacity .3s ease;
}
.kpi-tile--wechselbild:hover img.kpi-bild-wechsel { opacity: 1; }

.kpi-bild-text {
  position: absolute;
  z-index: 1;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0 28px;
  margin: 0;
  text-align: center;
  color: #fff;
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Kunden-Kachel mit Logo-Laufband (2026-09-16, Weisung Christian Hansmann,
   Vorlage awesomic.com, Kachel "4 000+ Customers")
   Dort steht oben die Zahl mit ihrem Bezug, darunter läuft ein Logo-Band über die
   volle Kachelbreite, ohne den Innenabstand der Kachel, mit weichen Kanten links und
   rechts. Übersetzt: die Spur hebt den 28-px-Rand der Kachel per negativem Rand auf,
   die Kanten macht eine mask statt zwei Overlay-Felder, die Logos sind 24 px hoch wie
   im Hero. Gleiche zehn Dateien wie dort (assets/logo/kunden/), nur andere Klassen,
   damit hero.css und diese Datei sich nicht ins Gehege kommen.
   Tempo: Spur rund 1.480 px in 88 s, also rund 17 px je Sekunde wie im Hero.
   Die Spur läuft durch, auch unter dem Zeiger: der Halt bei Hover und Fokus ist am
   2026-09-16 auf Weisung Christian Hansmann entfernt, hier und bei den Stichwörtern.
   Damit bleibt als Anhalter nur prefers-reduced-motion (D10). Der offene WCAG-Punkt
   2.2.2 wiegt dadurch schwerer als beim Hero-Laufband, das den Halt noch hat
   (README, Offene Punkte).
   -------------------------------------------------------------------------- */
.kpi-tile--logos { padding-bottom: 28px; }
/* Nur das Laufband, ohne Zahl (work-zone.html, Beweis, 2026-10-01): die Spur steht mittig
   in der gedehnten Kachel statt am unteren Rand. */
.kpi-tile--nur-logos { justify-content: center; }
.kpi-tile--nur-logos .kpi-logos { margin-top: 0; }
/* Zeile mit der Zahl links und dem Icon rechts (Vorlage awesomic.com). Der Bezug steht
   darüber über die volle Kachelbreite, nicht neben dem Icon: sonst bricht ein längerer
   Bezug wie "Abgeschlossene Projekte" um und die Zahl steht tiefer als in der Nachbarkachel.
   Das Icon ist Schmuck, es steht deshalb aria-hidden im Markup. 64 px, wie in der Vorlage
   im Verhältnis zur Kachelbreite. Die Datei ist PNG mit 160 px Kantenlänge, also zweifach
   für dichte Bildschirme; WebP nach D12 steht aus, siehe README. */
.kpi-tile-head { display: flex; justify-content: space-between; align-items: center; gap: 16px; }
.kpi-icon { flex: none; width: 64px; height: 64px; }
.kpi-logos {
  --kpi-logos-gap: 40px;
  margin: auto -28px 0; /* auto: die Spur sitzt am unteren Rand der Kachel */
  min-width: 0;
  display: flex;
  gap: var(--kpi-logos-gap);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.kpi-logos-track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: var(--kpi-logos-gap); flex: none;
  animation: kpi-logos 88s linear infinite;
}
.kpi-logos-track li { flex: none; display: flex; }
.kpi-logos-track img { display: block; height: 24px; width: auto; }
/* Optisches Gewicht angleichen, dieselbe Staffelung wie im Hero: die dünne, breite
   Wortmarke niedriger, die kompakten Bildmarken höher. */
.kpi-logos-track img.kpi-logo--wide { height: 16px; }
.kpi-logos-track img.kpi-logo--compact { height: 32px; }
@keyframes kpi-logos { to { transform: translateX(calc(-100% - var(--kpi-logos-gap))); } }

/* Drei Bänder statt einer Spur (2026-10-30, Weisung, Einteilung aus DEV-1665).
   Konzern, Mittelstand, darunter Kleinunternehmen und öffentlicher Dienst zusammen in
   einem Band. Aufbau wie bei der Stichwort-Kachel: .kpi-logos--baender stapelt die Zeilen,
   jede Zeile schneidet selbst ab, die weichen Kanten bleiben als Maske an .kpi-logos.
   Die Einzelspur-Fassung ohne .kpi-logos-line bleibt unverändert, work-zone.html nutzt sie.
   Mittleres Band läuft rückwärts, dadurch laufen die Nachbarn gegeneinander.
   Je Band eine eigene Dauer, damit alle drei rund 18 px je Sekunde laufen, das Tempo der
   Stichwort-Kachel: die Spuren sind 2.970, 4.801 und 668 px breit, dazu die Lücke dahinter. */
.kpi-logos--baender {
  --kpi-logos-zeile: 20px;
  flex-direction: column;
  gap: var(--kpi-logos-zeile);
}
.kpi-logos-line {
  display: flex;
  gap: var(--kpi-logos-gap);
  overflow: hidden;
}
.kpi-logos-line--back .kpi-logos-track { animation-direction: reverse; }
.kpi-logos-line:nth-child(1) .kpi-logos-track { animation-duration: 167s; }
.kpi-logos-line:nth-child(2) .kpi-logos-track { animation-duration: 269s; }
/* Drittes Band: nur fünf Logos. Mit den 40 px der anderen Bänder wäre die Spur 508 px breit
   und damit schmaler als die breiteste Zeile (gemessen 557 px bei Viewport 640, wo die Kachel
   allein in einer Spalte steht; darüber und darunter ist sie schmaler, ab 641 px nur noch 275). Dieselbe Marke stünde
   dann zweimal gleichzeitig im Bild. 80 px Abstand bringen die Spur auf 668 px, also mit
   Abstand über die breiteste Zeile, und zwei Spuren reichen wie bei den Nachbarbändern.
   Bis zum 2026-11-03 standen hier drei Logos, 180 px und vier Spuren. Dass alle 42 s dieselben
   Marken wiederkommen, liegt an der Einteilung, nicht an der Technik: nur fünf der 62 Kunden
   fallen unter Kleinunternehmen oder öffentlicher Dienst (README, Offene Punkte). */
.kpi-logos-line:nth-child(3) { --kpi-logos-gap: 80px; }
.kpi-logos-line:nth-child(3) .kpi-logos-track { animation-duration: 42s; }

/* --------------------------------------------------------------------------
   Zitat-Kachel mit Durchlauf (2026-10-12, Weisung Christian Hansmann, work-zone.html)
   Vorlage: Karte mit rundem Porträt links oben, Kundenlogo rechts oben, darunter das
   Zitat, Name und Rolle am unteren Rand. Der umrandete Knopf "Success Story" der Vorlage
   ist am 2026-10-12 auf Weisung entfallen.
   Jedes Zitat steht 10 s (bis 2026-10-12 6 s), dann blendet das nächste über. Ein Klick
   auf die Kachel holt sofort das nächste (Weisung Christian Hansmann, 2026-10-12). Den Takt gibt wie beim
   Ablauf-Blatt die Füllung der Fortschrittspille vor (.kpi-zitate-takt-fuellung), das Skript hört auf ihr Ende
   (js/bausteine/kennzahlen-block.js). Zeiger oder Fokus in der Kachel halten den Lauf
   an (WCAG 2.2.2), das macht animation-play-state.
   Ohne Skript und bei prefers-reduced-motion fehlt .is-auto: dann stehen alle Zitate
   untereinander, durch eine Linie getrennt (D10). Mit .is-auto liegen alle in derselben
   Rasterzelle, die Kachel ist so hoch wie das längste Zitat und springt beim Wechsel nicht.
   Ausgeblendete Zitate sind visibility: hidden und damit für Screenreader nicht da.
   -------------------------------------------------------------------------- */
.kpi-tile--zitate { position: relative; }
.kpi-zitate {
  list-style: none; margin: 0; padding: 0;
  flex: 1 1 auto;
  display: grid;
  /* Spalte höchstens so breit wie die Kachel (2026-11-05). Mit der Standardspalte wuchs sie
     auf den breitesten Inhalt aller Zitate, auch der ausgeblendeten: Ein Inhalt, der nicht
     umbricht, trieb die Spalte auf, und bei 320 px Fensterbreite lief deshalb auch das
     sichtbare Zitat rund 30 px über den rechten Rand der Kachel. */
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
}
.kpi-zitat { display: flex; min-width: 0; overflow-wrap: anywhere; }
.kpi-zitat + .kpi-zitat { border-top: 1px solid var(--line); padding-top: 28px; }
.kpi-zitat-figur {
  margin: 0;
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 24px;
}
.kpi-zitat-kopf {
  align-self: stretch;
  display: flex; justify-content: space-between; align-items: center; gap: 16px;
}
/* Porträt rund, 96 px, als <img class="kpi-zitat-foto"> mit width/height 96. Nur für Zitate
   mit Nennung von Firma und Person, seit 2026-11-10 sind alle Zitate anonym und ohne Kopf.
   Als <span> ergibt die Regel einen Kreis in --paper, etwa für einen Platzhalter. */
.kpi-zitat-foto {
  flex: none;
  width: 96px; height: 96px;
  border-radius: 50%;
  background: var(--paper);
  color: var(--muted);
  display: grid; place-items: center;
  text-align: center;
  font-size: 10px;
  object-fit: cover;
  overflow: hidden;
}
.kpi-zitat-logo { color: var(--muted); }
img.kpi-zitat-logo { display: block; height: 28px; width: auto; }
.kpi-zitat-text { margin: 0; color: var(--ink); }
.kpi-zitat-text p { margin: 0; }
/* Name und Rolle am unteren Rand: der Leerbereich der gedehnten Kachel entsteht über ihnen. */
.kpi-zitat-person { margin-top: auto; padding-top: 24px; padding-right: 56px; /* Platz für die Pille */ display: flex; flex-direction: column; gap: 4px; }
.kpi-zitat-name { font-weight: 700; color: var(--ink); }
.kpi-zitat-rolle { color: var(--muted); }

/* Durchlauf: alle Zitate in einer Zelle, nur das aktive sichtbar, Überblendung 600 ms. */
.kpi-zitate.is-auto { gap: 0; }
.kpi-zitate.is-auto .kpi-zitat {
  grid-area: 1 / 1;
  border-top: 0; padding-top: 0;
  opacity: 0; visibility: hidden;
  transition: opacity .6s ease, visibility 0s .6s;
}
.kpi-zitate.is-auto .kpi-zitat.is-aktiv {
  opacity: 1; visibility: visible;
  transition: opacity .6s ease, visibility 0s 0s;
}
/* Fortschrittspille (2026-10-12, Weisung Christian Hansmann: "ein Ladebalken so wie bei allen
   anderen Durchläufen auf der Seite"). Maß und Farben wie im Ablauf (prozess-raster.css,
   .process-board--auf-weiss .process-step-progress): 40 x 8, Spur --paper, Füllung --muted
   (4.56 auf der Spur), unten rechts, 5 px weiter vom Rand als der Innenabstand der Kachel.
   Ihre Animation ist zugleich der Takt des Durchlaufs. Sichtbar nur mit .is-auto an der Liste:
   ohne Skript und bei reduzierter Bewegung läuft nichts, dann gibt es auch keine Pille. */
.kpi-zitate-takt {
  display: none;
  position: absolute; right: 33px; bottom: 33px;
  width: 40px; height: 8px;
  border-radius: var(--r-pill);
  background: var(--paper);
  overflow: hidden;
  pointer-events: none;
}
.kpi-zitate.is-auto ~ .kpi-zitate-takt { display: block; }
.kpi-zitate-takt-fuellung {
  display: block;
  width: 100%; height: 100%;
  border-radius: inherit;
  background: var(--muted);
  transform: scaleX(0);
  transform-origin: left center;
}
.kpi-zitate-takt.laeuft .kpi-zitate-takt-fuellung { animation: kpi-zitate-takt var(--kpi-zitate-takt, 10s) linear forwards; }
/* Halt bei Zeiger und bei Tastaturfokus. :focus-visible statt :focus-within: Chrome fokussiert
   den Knopf auch beim Mausklick, mit :focus-within stünde der Lauf nach jedem Klick still. */
.kpi-tile--zitate:hover .kpi-zitate-takt.laeuft .kpi-zitate-takt-fuellung,
.kpi-zitate-weiter:focus-visible ~ .kpi-zitate-takt.laeuft .kpi-zitate-takt-fuellung { animation-play-state: paused; }
/* Weiter per Klick: ein unsichtbarer Knopf über der ganzen Kachel, nur mit Durchlauf, das
   Skript setzt ihn ein. Als echter Knopf ist er per Tastatur erreichbar (Enter, Leertaste)
   und trägt einen Namen ("Nächstes Zitat"). Der Fokusring folgt dem Radius der Kachel. */
.kpi-zitate-weiter {
  position: absolute; inset: 0; z-index: 1;
  margin: 0; padding: 0;
  border: 0; border-radius: inherit;
  background: transparent;
  cursor: pointer;
}
@keyframes kpi-zitate-takt { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* --------------------------------------------------------------------------
   Skills-Kachel mit laufenden Stichwort-Pillen (2026-09-16, Weisung Christian
   Hansmann, Vorlage awesomic.com, Kachel mit den Skill-Sets)
   Dort laufen vier Zeilen Stichwörter abwechselnd nach links und nach rechts, alle
   mit gleicher Dauer, über die volle Kachelbreite mit weichen Kanten. Übersetzt mit
   denselben Mitteln wie das Logo-Laufband eine Kachel weiter: Zeile mit overflow und
   mask, darin zwei gleiche Spuren, die zweite aria-hidden. Die Zeilen laufen durch,
   auch unter dem Zeiger (Weisung 2026-09-16), Anhalter ist nur prefers-reduced-motion.
   Die Pille ist aus .stapel-tag abgeleitet (DESIGN.md, Anker-Tagleiste): --r-pill,
   body-s in Gewicht 700, feste Höhe, Text nie umbrechend. Abweichung: statt des
   Rahmens in --line-strong eine weiße Fläche, weil seit dem beruhigten Bento
   (2026-09-16) keine Kachel dieser Sektion mehr eine Kontur trägt und die Pillen
   sonst als einziges Element Linien hätten. Weiß auf --paper trennt ausreichend,
   der Text bleibt --ink. Nachtrag Phase 4 offen.
   -------------------------------------------------------------------------- */
/* Reihenfolge seit dem 2026-09-17 (Weisung Christian Hansmann): erst die Stichwortzeilen,
   darunter Zahl, Bezug und Icon. Dehnt die Kachel, wächst der Abstand dazwischen, Zahl und
   Icon bleiben am unteren Rand. Vorher hing die umgekehrte Fassung an .kpi-tags. */
.kpi-tile--tags .kpi-tile-head { margin-top: auto; }
/* 50 px von der oberen Kachelkante bis zur ersten Stichwortzeile (Weisung Christian
   Hansmann, 2026-09-17), statt der 28 px Innenabstand, die alle Kacheln tragen. Als
   padding an der Kachel, nicht als margin an den Zeilen: die laufen seitlich über den
   Innenabstand hinaus und sollen von dieser Rechnung frei bleiben. Der 640er-Block setzt
   .kpi-tile auf 22 px und braucht deshalb dieselbe Ausnahme noch einmal. */
.kpi-tile--tags { padding-top: 50px; }
.kpi-tags {
  --kpi-tags-gap: 8px;
  margin: 0 -28px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--kpi-tags-gap);
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 10%, #000 90%, transparent);
}
.kpi-tags-line {
  display: flex;
  gap: var(--kpi-tags-gap);
  overflow: hidden;
}
.kpi-tags-track {
  list-style: none; margin: 0; padding: 0;
  display: flex; align-items: center; gap: var(--kpi-tags-gap); flex: none;
  animation: kpi-tags 64s linear infinite;
}
/* Jede zweite Zeile läuft in die andere Richtung, wie in der Vorlage. */
.kpi-tags-line--back .kpi-tags-track { animation-direction: reverse; }
/* Gleiche Dauer für alle Zeilen hieße vier verschiedene Geschwindigkeiten, weil die Zeilen
   unterschiedlich lang sind (gemessen 1.202, 927, 1.207 und 1.151 px). Je Zeile eine eigene
   Dauer ergibt rund 18 px je Sekunde, also das Tempo des Logo-Laufbands eine Kachel weiter.
   Die Breiten hängen an den Stichwörtern, nicht an der Kachelbreite, sie bleiben stabil. */
.kpi-tags-line:nth-child(1) .kpi-tags-track { animation-duration: 67s; }
.kpi-tags-line:nth-child(2) .kpi-tags-track { animation-duration: 52s; }
.kpi-tags-line:nth-child(3) .kpi-tags-track { animation-duration: 67s; }
.kpi-tags-line:nth-child(4) .kpi-tags-track { animation-duration: 64s; }
.kpi-tag {
  display: inline-flex; align-items: center;
  height: 34px; padding: 0 14px;
  background: var(--white);
  border-radius: var(--r-pill);
  font-size: var(--fs-body-s); font-weight: 700; letter-spacing: .02em; line-height: 1;
  white-space: nowrap;
}
/* Acht Stichwörter, die für das Angebot stehen, laufen in Ink mit weißem Text
   (Weisung 2026-09-16: "einige sehr relevante Tags schwarz"). Zwei je Zeile, damit in
   jeder Zeile immer eine dunkle Pille im Bild ist. Weiß auf --ink erreicht 18.89 (D3).
   Die Auswahl ist eine inhaltliche Entscheidung, sie steht in README.md. */
.kpi-tag--stark { background: var(--ink); color: #fff; }
@keyframes kpi-tags { to { transform: translateX(calc(-100% - var(--kpi-tags-gap))); } }

/* --------------------------------------------------------------------------
   Drehende Bildmarke in der Kachel "Gegründet" (2026-09-16, Weisung Christian
   Hansmann, Vorbild die Chrom-Fassung aus higgsfield.ai)
   Der Film hat denselben flachen Hintergrund wie die Kachel (--paper), deshalb steht
   das Objekt frei und es ist kein Rahmen zu sehen. Er läuft stumm in Schleife, ohne
   Bedienelemente, und ist als Zierde aria-hidden. Bei prefers-reduced-motion nimmt das
   Standbild seinen Platz ein (D10), beides steckt im Markup, deshalb braucht es dafür
   kein Skript. Der Film misst 960 px im Quadrat und liegt lokal unter assets/marke/.
   -------------------------------------------------------------------------- */
.kpi-marke {
  margin: 20px auto 0;
  width: min(260px, 100%);
  /* Der Hintergrund des Films ist im ersten Frame genau --paper, wandert im Lauf der
     Drehung aber leicht ins Hellere. Ohne Maske stünde deshalb ein heller Kasten in der
     Kachel. Die runde Maske blendet den Rand des Films weich aus, das Objekt bleibt
     vollständig sichtbar und der Übergang zur Kachel ist unsichtbar, unabhängig davon,
     wie sich der Hintergrund des Films ändert. */
  -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 72%);
  mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 72%);
}
/* Dehnt die Kachel, wächst der Abstand über und unter dem Objekt gleichmäßig. */
.kpi-tile--dehnt .kpi-marke { margin-top: auto; margin-bottom: auto; }
.kpi-marke-video,
.kpi-marke-still { display: block; width: 100%; height: auto; }
.kpi-marke-still { display: none; }

/* Die ProjektGPT-Kachel (13 Minuten und 317 Bewerbungen) ist am 2026-09-17 auf Weisung
   Christian Hansmann entfernt. Mit ihr sind die Regeln der Klasse .kpi-pair weg, sie war
   die einzige Kachel mit zwei Zahlen. Wenn die zwei Werte zurückkommen, gilt weiter die
   Vorher-nachher-Regel aus .agents/product-marketing.md: beide Werte nennen, nie den
   Faktor allein. Der Block steht in der Git-Historie dieses Branches. */

/* --------------------------------------------------------------------------
   Breakpoint 980 px: zwei Spalten, die Ankerkachel gibt ihre zweite Zeile ab
   -------------------------------------------------------------------------- */
@media (max-width: 980px) {
  /* Zwei Spalten: die ersten beiden stehen nebeneinander und sind gleich hoch, die dritte
     legt sich als eigene Reihe darunter und stellt ihre Kacheln nebeneinander. */
  .kpi-bento { flex-wrap: wrap; }
  .kpi-col { flex: 1 1 calc(50% - var(--gap)); }
  .kpi-col:last-child { flex-basis: 100%; flex-direction: row; align-items: stretch; }
  .kpi-col:last-child > .kpi-tile { flex: 1 1 0; }
}

/* --------------------------------------------------------------------------
   Breakpoint 640 px: eine Spalte, keine Kachel spannt mehr
   -------------------------------------------------------------------------- */
@media (max-width: 640px) {
  /* Eine Spalte: alles untereinander, nichts dehnt sich mehr, es gibt nichts auszugleichen. */
  .kpi-bento {
    margin-top: 48px;
    flex-direction: column;
  }
  .kpi-col,
  .kpi-col:last-child { flex: 0 0 auto; width: 100%; flex-direction: column; }
  .kpi-tile--dehnt { flex: 0 1 auto; }
  .kpi-tile--dehnt .kpi-marke { margin-top: 20px; margin-bottom: 0; }
  .kpi-tile--bild.kpi-tile--dehnt img { height: auto; }
  .kpi-tile {
    gap: 20px;
    padding: 22px;
  }
  .kpi-tile--logos { padding-bottom: 22px; }
  .kpi-tile--bild { padding: 0; }
  /* 580 px statt 420 px (2026-09-21): Das Blatt liegt absolut über der Kachel und kann sie
     nicht wachsen lassen. Bei 420 px war es auf 375 px Breite mit jedem Schritt höher als die
     Kachel (bis 510 px Inhalt bei 400 px Höhe) und scrollte intern, auch vor der Umstellung auf
     den Kundenaufwand. Mit 580 px Kachel bleiben 560 px für das Blatt; der längste Schritt
     braucht bei 375 px 510 px und bei 320 px 557 px. */
  .kpi-tile--tags { padding-top: 50px; }
  .kpi-bild-text { padding: 0 22px; }
  .kpi-tags { margin-left: -22px; margin-right: -22px; }
  .kpi-icon { width: 56px; height: 56px; }
  .kpi-logos { margin-left: -22px; margin-right: -22px; }
  .kpi-zitat-foto { width: 72px; height: 72px; }
  .kpi-zitate-takt { right: 27px; bottom: 27px; }
}

/* --------------------------------------------------------------------------
   Reduzierte Bewegung: die Logospur steht (D10)
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  /* Der Bildwechsel bleibt, er traegt die Weisung. Nur die Ueberblendung faellt weg,
     das Bild schaltet dann hart um (D10). */
  .kpi-tile--wechselbild img.kpi-bild-wechsel { transition: none; }
  .kpi-logos-track,
  .kpi-tags-track { animation: none; }
  .kpi-marke-video { display: none; }
  .kpi-marke-still { display: block; }
  .kpi-zitate-takt { display: none !important; }
  .kpi-zitate-takt-fuellung { animation: none; }
}

/* Landschaftsabschluss nur auf work-zone.html (Weisung 2026-10-01).
   Der nächste Abschnitt nutzt den bestehenden Übergriff mit --r-section.
   Der helle Himmel wird weich in die helle Kundenfläche eingeblendet. */
.kpi-section--landscape { padding-bottom: 0; }
/* 80 px höher als zuvor (Weisung Christian Hansmann, 2026-10-12): statt 72 px Abstand zum
   Bento greift das Bild 8 px darunter. Der obere Rand ist durch die Maske durchsichtig, die
   Kacheln bleiben sichtbar; pointer-events: none hält sie bedienbar. */
.kpi-landscape {
  margin: -8px calc(-1 * var(--pad-x)) 0;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(to bottom, transparent, #000 32%);
  mask-image: linear-gradient(to bottom, transparent, #000 32%);
}
.kpi-landscape img {
  display: block;
  width: 100%;
  height: auto;
  min-height: 280px;
  object-fit: cover;
  object-position: center bottom;
}
@media (max-width: 980px) {
  .kpi-landscape img { object-position: right bottom; }
}
