/* =====================================================================
   PrepP — Handbuch (js/handbuch.js, docs/HANDBUCH.md)
   ---------------------------------------------------------------------
   Zwei Teile: die Seite (Suchzeile, Kapitelnavigation, Kapitel) und die
   MINI-DEMOS.

   Die Demos sind selbst gezeichnete Inline-SVGs; ihre Geometrie steht in
   js/handbuch.js, ihre FARBE und ihre BEWEGUNG hier. Farbe gehoert
   hierher, weil ein `var()` in einem Praesentationsattribut von keinem
   Browser aufgeloest wird — `fill="var(--pp-line)"` am Element waere
   schlicht wirkungslos.

   DIE REGEL DER BEWEGUNG, und sie ist der Grund fuer den Aufbau jedes
   @keyframes-Blocks hier unten:

     Der RUHEZUSTAND ist das, was diese Datei OHNE `animation` malt, und
     er ist je Demo der aussagekraeftige (der Draht IST gezogen, das
     Menueband IST offen). Jede Animation ist ein RUNDLAUF: Bild 0 % und
     Bild 100 % sind mit dem Ruhezustand identisch.

   Eine Endlosschleife hat kein „letztes Bild"; deshalb kann man beim
   Anhalten nicht auf das Ende zeigen, sondern nur auf einen gewaehlten
   Zustand — und der ist hier der informative. Angehalten wird auf drei
   Wegen, alle drei enden in derselben Regel:

     1. `prefers-reduced-motion: reduce`  — gewinnt IMMER, ohne Schalter
     2. `.hb-aus` am Wurzelknoten          — der Schalter „Demos anhalten"
     3. `.hb-demo.aus`                     — der Knopf an einer Demo

   Die Demos haengen BEWUSST NICHT an `.pp-anim` (dem portalweiten
   Animationsschalter): Der regiert Zierrat — Leisten, Baender, Blenden.
   Eine Demo im Handbuch ist der INHALT des Kapitels; wer sie abschaltet,
   nimmt der Erklaerung ihre Erklaerung. Deshalb ein eigener Schalter an
   Ort und Stelle statt einer Kopplung an eine Einstellung, die etwas
   anderes meint. docs/HANDBUCH.md Abschnitt 4.
   ===================================================================== */

/* ---------------------------------------------------------------------
   1. Die Seite
   --------------------------------------------------------------------- */
.hb-suchzeile {
  display: flex; align-items: center; gap: var(--pp-sp-2);
  margin: var(--pp-sp-4) 0 var(--pp-sp-2);
  flex-wrap: wrap;
}
.hb-such {
  display: flex; align-items: center; gap: var(--pp-sp-2);
  flex: 1 1 260px; min-width: 0;
  background: var(--pp-surface); border: 1px solid var(--pp-line);
  border-radius: 7px; padding: 0 var(--pp-sp-3);
}
.hb-such:focus-within { border-color: var(--pp-accent); }
.hb-such-lupe { display: flex; color: var(--pp-text-3); flex: 0 0 auto; }
.hb-such input {
  flex: 1 1 0; min-width: 0;
  background: none; border: 0; outline: none;
  color: var(--pp-text); font: inherit;
  font-size: var(--pp-fs-text); padding: 10px 0;
}
.hb-trefferzahl { min-height: 16px; margin: 0 0 var(--pp-sp-2); }
.hb-trefferzahl:empty { display: none; }

/* Zwei Spalten: Kapitelliste links, Inhalt rechts. Unter 900 px legt
   sich die Liste ueber den Inhalt (waagerecht scrollend waere sie eine
   zweite Reiterleiste, die sie nicht ist). */
.hb-split {
  display: grid; grid-template-columns: 216px minmax(0, 1fr);
  gap: var(--pp-sp-6); align-items: start;
}
.hb-nav {
  display: flex; flex-direction: column; gap: 2px;
  /* Unter der klebenden Kopfzeile (54 px), nicht unter dem Fensterrand:
     Mit top 16 px lagen die ersten 38 px der Liste — Gruppenname und
     „Erste Schritte" — hinter der Kopfzeile, sobald man scrollte
     (ns0929-p5, WebKit). --tr-kopf ist dieselbe Kante, an der die
     Trainingsfenster kleben; die max-height rechnete schon immer mit ihr
     (120 px = --tr-kopf + --tr-luft). */
  position: sticky; top: var(--tr-kopf, 76px);
  max-height: calc(100vh - 120px); overflow-y: auto;
}
.hb-nav-gruppe {
  font-size: var(--pp-fs-mini); letter-spacing: .04em; text-transform: uppercase;
  color: var(--pp-text-3); margin: var(--pp-sp-3) 0 var(--pp-sp-1); padding: 0 var(--pp-sp-2);
}
.hb-nav-gruppe:first-child { margin-top: 0; }
.hb-nav-eintrag {
  display: block; width: 100%; text-align: left;
  background: none; border: 0; border-radius: 5px; cursor: pointer;
  color: var(--pp-text-2); font: inherit; font-size: var(--pp-fs-klein);
  line-height: var(--pp-lh-knapp); padding: 7px var(--pp-sp-2);
}
.hb-nav-eintrag:hover { background: var(--pp-accent-tint); color: var(--pp-text); }
.hb-nav-eintrag.on {
  background: var(--pp-accent-tint); color: var(--pp-text);
  /* Der aktive Eintrag ist eine FORM, keine Farbe — dieselbe Regel wie
     beim EIN-Zustand des Sandbox-Menuebands: In Graustufen traegt ein
     Flaechenton von 1,1 : 1 nichts. */
  box-shadow: inset 2px 0 0 var(--pp-accent);
  font-weight: 600;
}
.hb-zurueck { margin-bottom: var(--pp-sp-3); }

.hb-gruppe { margin-bottom: var(--pp-sp-8); }
.hb-gruppe-titel { margin: 0 0 var(--pp-sp-3); }
.hb-kacheln {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: var(--pp-sp-3);
}
.hb-kachel { cursor: pointer; }
.hb-kachel-titel {
  font-size: var(--pp-fs-gross); font-weight: 600;
  line-height: var(--pp-lh-knapp); margin-bottom: var(--pp-sp-1);
}
.hb-kachel-text {
  font-size: var(--pp-fs-klein); color: var(--pp-text-2);
  line-height: var(--pp-lh-text);
}

.hb-kapitel { max-width: 70ch; }
.hb-titel { margin: var(--pp-sp-1) 0 var(--pp-sp-3); }
.hb-was {
  font-size: var(--pp-fs-gross); line-height: var(--pp-lh-text);
  margin: 0 0 var(--pp-sp-3);
}
.hb-wofuer {
  font-size: var(--pp-fs-text); line-height: var(--pp-lh-text);
  color: var(--pp-text-2);
  border-left: 2px solid var(--pp-accent-line);
  padding-left: var(--pp-sp-3); margin: 0 0 var(--pp-sp-5);
}
.hb-schritte {
  margin: 0 0 var(--pp-sp-5); padding-left: var(--pp-sp-5);
  font-size: var(--pp-fs-text); line-height: var(--pp-lh-text);
}
.hb-schritte li { margin-bottom: var(--pp-sp-2); }
.hb-ziele { display: flex; flex-wrap: wrap; gap: var(--pp-sp-2); margin-top: var(--pp-sp-4); }

/* `.title` und `.meta` sind in prepp.css IMMER an ihre Zeilenart
   gebunden (.pp-exam-row .title, .pp-own-row .title …) — es gibt keine
   allgemeine Regel, an die man sich haengen koennte. Die Trefferzeile
   bringt ihre eigene mit, im selben Mass wie ihre Nachbarn. */
.hb-treffer-zeile { cursor: pointer; align-items: flex-start; }
.hb-treffer-zeile .title { font-weight: 600; font-size: var(--pp-fs-text); }
.hb-treffer-zeile .meta {
  font-size: var(--pp-fs-klein); color: var(--pp-text-2);
  margin-top: 2px; line-height: var(--pp-lh-text);
}
.hb-treffer-zeilen {
  margin: var(--pp-sp-1) 0 0; padding-left: var(--pp-sp-4);
  font-size: var(--pp-fs-klein); color: var(--pp-text-2);
  line-height: var(--pp-lh-text);
}

/* Auf dem Finger 44 px auch dort, wo das Handbuch zweispaltig steht (iPad
   quer, 1180 px): Die Kapitel-Einträge der Navigation maßen dort 31 px, das
   Suchfeld 42 px — die 44 px unten galten nur unter 900 px (WebKit-Abnahme
   10.10.2026, wa1009). Mit Maus bleibt beides, wie es ist. */
@media (pointer: coarse) {
  .hb-nav-eintrag { min-height: 44px; }
  .hb-such input { min-height: 44px; }
}

@media (max-width: 900px) {
  .hb-split { grid-template-columns: minmax(0, 1fr); gap: var(--pp-sp-4); }
  .hb-nav { position: static; max-height: none; }
  /* C56 (Mobil-Abnahme R3): eine Trefferflaeche misst mindestens 44 px. */
  .hb-nav-eintrag { min-height: 44px; font-size: var(--pp-fs-text); }
  .hb-kapitel { max-width: none; }
}

/* ---------------------------------------------------------------------
   2. Die Demos — Rahmen, Bildflaeche, Beschriftung
   --------------------------------------------------------------------- */
.hb-demo {
  margin: 0 0 var(--pp-sp-5);
  border: 1px solid var(--pp-line); border-radius: 8px;
  background: var(--pp-surface); overflow: hidden;
}
.hb-demo-bild { display: block; background: var(--pp-bg); padding: var(--pp-sp-3); }
/* Gedeckelt und zentriert: Ein SVG mit `width: 100%` waechst in der
   Lesespalte auf 600 px Breite und damit auf ueber 340 px Hoehe — eine
   schematische Zeichnung mit sechs Rechtecken darin sagt bei 460 px
   genau dasselbe und laesst den Schritt darunter im Bild (gemessen in
   Chromium bei 1440 px: die ganze Figur 398 -> 339 px, das SVG selbst
   600 -> 460 px breit). Fuer WebKit steht die Nachmessung aus. */
.hb-svg {
  display: block; width: 100%; max-width: 460px; height: auto;
  margin: 0 auto; color: var(--pp-text-2);
}
.hb-demo-text {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--pp-sp-3); padding: var(--pp-sp-2) var(--pp-sp-3);
  border-top: 1px solid var(--pp-line);
  font-size: var(--pp-fs-klein); color: var(--pp-text-2);
  line-height: var(--pp-lh-text);
}
.hb-demo-knopf { flex: 0 0 auto; }

/* ---------------------------------------------------------------------
   3. Die Farben der Demos. Ausschliesslich --pp-Tokens und currentColor —
      kein fester Wert, damit hell und dunkel beide stimmen.
   --------------------------------------------------------------------- */
.hb-svg .hb-flaeche { fill: var(--pp-surface); stroke: var(--pp-line); stroke-width: 1; }
.hb-svg .hb-kopf    { fill: var(--pp-surface-2); }
.hb-svg .hb-spalte  { fill: var(--pp-surface-2); }
.hb-svg .hb-feld    { fill: var(--pp-bg); stroke: var(--pp-line-2); stroke-width: 1; }
.hb-svg .hb-karte   { fill: var(--pp-surface-2); stroke: var(--pp-line-2); stroke-width: 1; }
.hb-svg .hb-rahmen  { fill: none; stroke: var(--pp-line-2); stroke-width: 1.4; }
.hb-svg .hb-balken  { fill: var(--pp-line-2); }
.hb-svg .hb-chip    { fill: none; stroke: var(--pp-line-2); stroke-width: 1; }
.hb-svg .hb-marke   { fill: var(--pp-accent-tint); stroke: var(--pp-accent); stroke-width: 1.2; }
.hb-svg .hb-tinte   { fill: var(--pp-text-2); }
.hb-svg .hb-knopf   { fill: var(--pp-surface-2); stroke: var(--pp-line-2); stroke-width: 1.2; }
.hb-svg .hb-pfeil   { fill: none; stroke: var(--pp-text-2); stroke-width: 1.6;
                      stroke-linecap: round; stroke-linejoin: round; }
.hb-svg .hb-haken   { fill: none; stroke: var(--pp-ok); stroke-width: 2;
                      stroke-linecap: round; stroke-linejoin: round; opacity: 0; }
.hb-svg .hb-uhrzeiger { stroke: var(--pp-accent); stroke-width: 1.6; stroke-linecap: round;
                        transform-origin: 26px 18px; }
.hb-svg .hb-caret   { stroke: var(--pp-accent); stroke-width: 1.4; stroke-linecap: round; }
.hb-svg .hb-menue   { fill: none; stroke: var(--pp-accent); stroke-width: 1.4; stroke-linecap: round; }
.hb-svg .hb-schiene { opacity: 0; }
.hb-svg .hb-reiter  { fill: none; stroke: var(--pp-line-2); stroke-width: 1; }
.hb-svg .hb-reiter-an { fill: var(--pp-accent-tint); stroke: var(--pp-accent); }
.hb-svg .hb-taste   { fill: var(--pp-surface); stroke: var(--pp-line-2); stroke-width: 1; }
.hb-svg .hb-draht   { stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; }
.hb-svg .hb-bauteil { fill: var(--pp-surface); stroke: currentColor; stroke-width: 1.6; }
.hb-svg .hb-knoten  { fill: currentColor; }
.hb-svg .hb-gitter  { fill: none; stroke: var(--pp-line); stroke-width: .8; }
.hb-svg .hb-kante-linie {
  fill: none; stroke: var(--pp-accent); stroke-width: 1.8; stroke-linecap: round;
  /* Der Pfad ist rund 110 Einheiten lang; 130 deckt ihn sicher ab. */
  stroke-dasharray: 130; stroke-dashoffset: 0;
}
.hb-svg .hb-kante-fest { stroke-dasharray: none; }
.hb-svg .hb-kante-spitze { fill: var(--pp-accent); }
.hb-svg .hb-zeiger  { fill: var(--pp-text); stroke: var(--pp-bg); stroke-width: 1;
                      transform: translate(152px, 96px); }
.hb-svg .hb-zeiger-zoom { transform: translate(96px, 58px); }

/* ---------------------------------------------------------------------
   4. Die Bewegung. Jeder Block endet, wo er anfaengt (Rundlauf).
   --------------------------------------------------------------------- */

/* Demo „uhr": der Zeiger dreht, die Marke wandert ueber die
   Aufgabenleiste und zurueck, der Cursor blinkt. */
@keyframes hb-dreh   { from { transform: rotate(0deg); }  to { transform: rotate(360deg); } }
@keyframes hb-wandern {
  0%   { transform: translateX(0); }
  25%  { transform: translateX(40px); }
  50%  { transform: translateX(80px); }
  75%  { transform: translateX(40px); }
  100% { transform: translateX(0); }
}
@keyframes hb-blinken { 0%, 49% { opacity: 1; } 50%, 99% { opacity: 0; } 100% { opacity: 1; } }
.hb-svg .hb-uhrzeiger { animation: hb-dreh 6s linear infinite; }
.hb-svg .hb-marke     { animation: hb-wandern 7s ease-in-out infinite; }
.hb-svg .hb-caret     { animation: hb-blinken 1.2s steps(1, end) infinite; }

/* Demo „pruefen": der Knopf wird zum Haken und wieder zum Pfeil. Der
   Ruhezustand ist der Pfeil — das ist der Zustand VOR dem Klick, und
   genau ihn erklaert der Satz daneben. */
@keyframes hb-pfeil-weg { 0%, 30% { opacity: 1; } 45%, 85% { opacity: 0; } 100% { opacity: 1; } }
@keyframes hb-haken-da  { 0%, 35% { opacity: 0; } 50%, 85% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hb-knopf-ok {
  0%, 30%  { stroke: var(--pp-line-2); }
  45%, 85% { stroke: var(--pp-ok); }
  100%     { stroke: var(--pp-line-2); }
}
.hb-svg .hb-pfeil { animation: hb-pfeil-weg 4.5s ease-in-out infinite; }
.hb-svg .hb-haken { animation: hb-haken-da 4.5s ease-in-out infinite; }
.hb-svg .hb-knopf { animation: hb-knopf-ok 4.5s ease-in-out infinite; }

/* Demo „leisten": die linke Spalte wird zur Schiene, die Aufgabe rueckt
   nach — und alles wieder zurueck. */
@keyframes hb-spalte-weg { 0%, 20% { opacity: 1; } 40%, 75% { opacity: 0; } 100% { opacity: 1; } }
@keyframes hb-schiene-da { 0%, 20% { opacity: 0; } 40%, 75% { opacity: 1; } 100% { opacity: 0; } }
@keyframes hb-ruecken    { 0%, 20% { transform: translateX(0); }
                           40%, 75% { transform: translateX(-40px); }
                           100% { transform: translateX(0); } }
.hb-svg .hb-links   { animation: hb-spalte-weg 6s ease-in-out infinite; }
.hb-svg .hb-schiene { animation: hb-schiene-da 6s ease-in-out infinite; }
.hb-svg .hb-mitte   { animation: hb-ruecken 6s ease-in-out infinite; }

/* Demo „kante": der Zeiger faehrt zurueck an den Kartenrand, die
   Verbindung loest sich — dann wird sie neu gezogen. Ruhezustand:
   Verbindung steht. */
@keyframes hb-ziehen {
  0%   { transform: translate(152px, 96px); }
  12%  { transform: translate(90px, 46px); }
  50%  { transform: translate(152px, 96px); }
  100% { transform: translate(152px, 96px); }
}
@keyframes hb-zeichnen {
  0%   { stroke-dashoffset: 0; }
  12%  { stroke-dashoffset: 130; }
  50%  { stroke-dashoffset: 0; }
  100% { stroke-dashoffset: 0; }
}
@keyframes hb-spitze { 0% { opacity: 1; } 12%, 40% { opacity: 0; } 52%, 100% { opacity: 1; } }
.hb-svg .hb-zeiger:not(.hb-zeiger-zoom) { animation: hb-ziehen 5s ease-in-out infinite; }
.hb-svg .hb-kante-linie:not(.hb-kante-fest) { animation: hb-zeichnen 5s ease-in-out infinite; }
.hb-svg .hb-kante-spitze { animation: hb-spitze 5s ease-in-out infinite; }

/* Demo „band": das Panel faehrt zu und wieder auf, der aktive Reiter
   wandert dabei einen weiter. Ruhezustand: offen. */
@keyframes hb-zuklapp {
  0%, 15%  { transform: scaleY(1); opacity: 1; }
  35%, 55% { transform: scaleY(0); opacity: 0; }
  80%, 100% { transform: scaleY(1); opacity: 1; }
}
@keyframes hb-blatt-hoch {
  0%, 15%  { transform: translateY(0); }
  35%, 55% { transform: translateY(-34px); }
  80%, 100% { transform: translateY(0); }
}
@keyframes hb-reiter-wandern {
  0%, 25%   { transform: translateX(0); }
  45%, 65%  { transform: translateX(40px); }
  90%, 100% { transform: translateX(0); }
}
.hb-svg .hb-panel { transform-origin: 4px 24px; animation: hb-zuklapp 6.5s ease-in-out infinite; }
.hb-svg .hb-blatt { animation: hb-blatt-hoch 6.5s ease-in-out infinite; }
.hb-svg .hb-reiter-an { animation: hb-reiter-wandern 6.5s ease-in-out infinite; }

/* Demo „zoom": die Welt wird herangeholt und geschoben, dann wieder
   losgelassen. Ruhezustand: die ganze Flaeche im Bild. */
@keyframes hb-heran {
  0%, 10%  { transform: none; }
  40%      { transform: scale(1.5); }
  70%      { transform: scale(1.5) translate(-26px, -16px); }
  95%, 100% { transform: none; }
}
@keyframes hb-zeiger-zoom-weg {
  0%, 10%  { transform: translate(96px, 58px); }
  40%      { transform: translate(120px, 66px); }
  70%      { transform: translate(150px, 92px); }
  95%, 100% { transform: translate(96px, 58px); }
}
.hb-svg .hb-welt { transform-origin: 130px 75px; animation: hb-heran 8s ease-in-out infinite; }
.hb-svg .hb-zeiger-zoom { animation: hb-zeiger-zoom-weg 8s ease-in-out infinite; }

/* ---------------------------------------------------------------------
   5. Anhalten — drei Wege, EINE Regel. `animation: none` faellt auf die
      Deklarationen oben zurueck, also auf den Ruhezustand.
   --------------------------------------------------------------------- */
.hb-aus .hb-svg *,
.hb-demo.aus .hb-svg * { animation: none !important; }

@media (prefers-reduced-motion: reduce) {
  .hb-svg * { animation: none !important; }
}
