/* ═══════════════════════════════════════════════════════════════════
   Bewegung

   Bewegung gibt es nur dort, wo sie etwas erklärt: der Code, der sich
   schreibt; die Szene, die zeigt, was er im Spiel bewirkt; die Schaubilder
   zu dv_core. Seit dem 3. Oktober 2026 blendet nichts mehr beim Scrollen
   ein, und der Schein hinter dem Auftakt ist weg.

   Drei Regeln, an die sich hier alles hält:

   1. Ohne JavaScript ist alles sichtbar. Der verborgene Ausgangszustand
      hängt an `.js` am <html> — die Klasse setzt das Inline-Skript im
      Kopf. Bleibt JavaScript aus, greift keine einzige Verbergung.
   2. Bewegt werden nur `transform` und `opacity` (und die Zeichenlinie
      der Schaubilder). Das läuft im Compositor; alles andere ruckelt.
   3. `prefers-reduced-motion` schaltet jede Bewegung ab — nicht die
      Inhalte. Wer keine Animation will, sieht dieselbe Seite, sofort.
   ═══════════════════════════════════════════════════════════════════ */

/* ── Der Lua-Code schreibt sich ──────────────────────────────────
   main.js blendet Zeile für Zeile ein und wechselt danach zum nächsten
   Schnipsel. Der Balken läuft mit, solange geschrieben wird. */
.js .schnipsel .zeile{opacity:0}
.js .schnipsel .zeile.da{
  opacity:1;
  animation:zeile-rein .26s cubic-bezier(.22,.61,.36,1) both;
}
/* Der abtretende Schnipsel bleibt in seiner Rasterzelle liegen und
   verschwindet nur — sonst springt die Höhe. */
.js .schnipsel.aus{opacity:0;visibility:hidden;pointer-events:none}
.js .schnipsel.aus .zeile{opacity:0}
@keyframes zeile-rein{
  from{opacity:0;transform:translateX(-6px)}
  to  {opacity:1;transform:none}
}
.lauf{animation:blinken 1s steps(2,start) infinite}
@keyframes blinken{0%,100%{opacity:1}50%{opacity:0}}
.hero-code-fuss{animation:zeile-rein .4s cubic-bezier(.22,.61,.36,1) both}

/* Zeilen im Codeblock sind Spannen. Ohne inline-block greift kein
   transform — Umformungen wirken auf inline laufenden Text nicht. */
.hero-code [data-tippen] .zeile{display:inline-block}

/* Der Wechsel der erkannten Framework-Angabe. */
[data-framework]{transition:opacity .18s ease}

/* ── Die Schaubilder ─────────────────────────────────────────────
   Sie erklären, was der Absatz daneben behauptet. Das Aussehen steht in
   startseite.css, hier nur, was sich bewegt. */

/* Frameworkerkennung: der Kern steht fest, die Erkennung wandert. Alle
   vier stehen da — das ist die Aussage. Hervorgehoben ist immer nur
   einer, und die Linie dorthin leuchtet mit. Läuft in Schleife: wer
   später hinsieht, sieht es auch. */
.js .dia-fw.sichtbar .fw-box rect{animation:fw-box 8s linear infinite both}
.js .dia-fw.sichtbar .fw-box text{animation:fw-text 8s linear infinite both}
.js .dia-fw.sichtbar .dia-linien path{animation:fw-linie 8s linear infinite both}
.js .dia-fw.sichtbar .fw-box:nth-child(1) rect,
.js .dia-fw.sichtbar .fw-box:nth-child(1) text,
.js .dia-fw.sichtbar .dia-linien path:nth-child(1){animation-delay:0s}
.js .dia-fw.sichtbar .fw-box:nth-child(2) rect,
.js .dia-fw.sichtbar .fw-box:nth-child(2) text,
.js .dia-fw.sichtbar .dia-linien path:nth-child(2){animation-delay:2s}
.js .dia-fw.sichtbar .fw-box:nth-child(3) rect,
.js .dia-fw.sichtbar .fw-box:nth-child(3) text,
.js .dia-fw.sichtbar .dia-linien path:nth-child(3){animation-delay:4s}
.js .dia-fw.sichtbar .fw-box:nth-child(4) rect,
.js .dia-fw.sichtbar .fw-box:nth-child(4) text,
.js .dia-fw.sichtbar .dia-linien path:nth-child(4){animation-delay:6s}
@keyframes fw-box{
  0%,3%   {stroke:var(--line-2);fill:var(--sunken)}
  6%,22%  {stroke:var(--accent);fill:var(--accent-wash)}
  25%,100%{stroke:var(--line-2);fill:var(--sunken)}
}
@keyframes fw-text{
  0%,3%   {fill:var(--ink-3)}
  6%,22%  {fill:var(--accent-ink)}
  25%,100%{fill:var(--ink-3)}
}
@keyframes fw-linie{
  0%,3%   {stroke:var(--line-2);stroke-width:1.2}
  6%,22%  {stroke:var(--accent);stroke-width:1.8}
  25%,100%{stroke:var(--line-2);stroke-width:1.2}
}

/* Abhängigkeiten: zwei Linien, die sich zeichnen. Mehr wird es nicht, und
   genau das ist die Aussage. */
.js .dia-zeichnen path{stroke-dasharray:96;stroke-dashoffset:96}
.js .dia-dep.sichtbar .dia-zeichnen path{
  stroke:var(--accent);
  animation:linie 1s cubic-bezier(.22,.61,.36,1) forwards;
}
.js .dia-dep.sichtbar .dia-zeichnen path:nth-child(2){animation-delay:.15s}
@keyframes linie{to{stroke-dashoffset:0}}

/* dv_core als Fundament (Hinweis unter dem Auftakt): die Scripts stehen
   oben, die Stützen zeichnen sich, dann füllt sich das Fundament. Einmal
   und nicht in Schleife — der Satz daneben ist eine Feststellung, kein
   Ablauf, und was dauernd blinkt, wird überlesen. Ausgangszustand nur mit
   .js (ohne JavaScript steht das fertige Bild da), Ablauf erst mit
   .sichtbar (main.js setzt es, sobald das Bild im Fenster steht). */
.dia-basis .bs-unter{font:500 9px/1 var(--mono);fill:var(--ink-3);text-anchor:middle;letter-spacing:.04em}
.dia-basis .bs-mehr rect{stroke-dasharray:3 3}
.dia-basis .bs-linien path{stroke:var(--accent);stroke-width:1.5}

.js .dia-basis .bs-chip{opacity:0;transform:translateY(-7px)}
.js .dia-basis .bs-linien path{stroke-dasharray:52;stroke-dashoffset:52}
.js .dia-basis .bs-kern rect{fill:var(--sunken);stroke:var(--line-2)}
.js .dia-basis .bs-kern text{fill:var(--ink-3)}
.js .dia-basis .bs-unter{opacity:0}

.js .dia-basis.sichtbar .bs-chip{animation:bs-chip .55s cubic-bezier(.22,.61,.36,1) forwards}
.js .dia-basis.sichtbar .bs-c2{animation-delay:.08s}
.js .dia-basis.sichtbar .bs-c3{animation-delay:.16s}
.js .dia-basis.sichtbar .bs-c4{animation-delay:.24s}
.js .dia-basis.sichtbar .bs-c5{animation-delay:.32s}
.js .dia-basis.sichtbar .bs-linien path{animation:linie .6s .55s cubic-bezier(.22,.61,.36,1) forwards}
.js .dia-basis.sichtbar .bs-linien path:nth-child(2){animation-delay:.62s}
.js .dia-basis.sichtbar .bs-linien path:nth-child(3){animation-delay:.69s}
.js .dia-basis.sichtbar .bs-linien path:nth-child(4){animation-delay:.76s}
.js .dia-basis.sichtbar .bs-linien path:nth-child(5){animation-delay:.83s}
.js .dia-basis.sichtbar .bs-kern rect{animation:bs-kern-r .5s 1.25s ease-out forwards}
.js .dia-basis.sichtbar .bs-kern text{animation:bs-kern-t .5s 1.25s ease-out forwards}
.js .dia-basis.sichtbar .bs-unter{animation:bs-ein-t .6s 1.7s ease-out forwards}
@keyframes bs-chip{to{opacity:1;transform:none}}
@keyframes bs-kern-r{to{fill:var(--accent);stroke:var(--accent)}}
@keyframes bs-kern-t{to{fill:var(--on-accent)}}
@keyframes bs-ein-t{to{opacity:1}}

/* ── Die Kulisse läuft ───────────────────────────────────────────
   Jede Spalte enthält ihren Block zweimal. Die Verschiebung um genau die
   halbe Höhe schließt die Schleife ohne sichtbaren Sprung. Drei
   verschiedene Dauern, damit die Spalten nicht im Gleichschritt laufen —
   das fiele sofort als Muster auf. */
@keyframes regen{
  from{transform:translate3d(0,0,0)}
  to  {transform:translate3d(0,-50%,0)}
}
.js .code-regen pre{animation:regen 92s linear infinite}
/* Andere Dauer und ein negativer Verzug: die Spalten starten damit an
   verschiedenen Stellen ihrer Schleife und laufen nie im Gleichschritt. */
.js .regen-spalte:nth-child(2) pre{animation-duration:137s;animation-delay:-46s}
.js .regen-spalte:nth-child(3) pre{animation-duration:111s;animation-delay:-73s}

/* ── Ausschalter ─────────────────────────────────────────────────
   Kein Halbmaß: bei reduzierter Bewegung ist alles sofort da, in seinem
   Endzustand, ohne Übergang. Die Regel aus tokens.css kürzt nur die
   Dauer, nicht die Verzögerung — ohne diesen Block stünde das Fundament
   von dv_core noch knapp zwei Sekunden dunkel da. */
@media (prefers-reduced-motion:reduce){
  .lauf,.tafel,.hero-code-fuss,
  .js .code-regen pre,
  .js .dia-fw.sichtbar .fw-box rect,
  .js .dia-fw.sichtbar .fw-box text,
  .js .dia-fw.sichtbar .dia-linien path,
  .js .dia-dep.sichtbar .dia-zeichnen path{
    animation:none!important;
  }
  /* Ohne Bewegung stehen die Linien vollständig da und die Frameworkkästen
     alle gleich — die Aussage bleibt dieselbe. */
  .js .dia-zeichnen path{stroke-dashoffset:0;stroke:var(--accent)}
  .js .schnipsel .zeile{opacity:1;animation:none}
  .js .dia-basis .bs-chip{opacity:1;transform:none}
  .js .dia-basis .bs-linien path{stroke-dashoffset:0}
  .js .dia-basis .bs-kern rect{fill:var(--accent);stroke:var(--accent)}
  .js .dia-basis .bs-kern text{fill:var(--on-accent)}
  .js .dia-basis .bs-unter{opacity:1}
  .js .dia-basis.sichtbar .bs-chip,
  .js .dia-basis.sichtbar .bs-linien path,
  .js .dia-basis.sichtbar .bs-kern rect,
  .js .dia-basis.sichtbar .bs-kern text,
  .js .dia-basis.sichtbar .bs-unter{animation:none}
}
