/* AI Værk — icons.css: Icon-Gesten. Lade-Reihenfolge: 7/7, nach motion.css.
 *
 * ── LIZENZ ──────────────────────────────────────────────────────────────
 * Die Icon-Geometrie stammt aus dem Solar Icon Set (Linear) von 480 Design,
 * lizenziert unter CC BY 4.0 — https://creativecommons.org/licenses/by/4.0/
 * Quelle: https://github.com/480-Design/Solar-Icon-Set
 * Die Pfade liegen in ai-vaerk/lib/icon-geometry.php und stehen dort
 * wörtlich wie im Quellsatz; getrennt sind nur Teilpfade, die sich
 * einzeln bewegen. `sparkle` ist das eigene Zeichen von AI Værk, `print`
 * kommt aus Hugeicons (MIT) — beide nicht aus Solar.
 *
 * ── GRAMMATIK ───────────────────────────────────────────────────────────
 * · Ein Takt, 0.5s bis 1.2s, danach Ruhe.
 * · Jede Keyframe-Stufe trägt ihr eigenes animation-timing-function.
 *   Das ist der Unterschied zwischen gestaltet und interpoliert.
 * · Abgang schneller als Ankunft, rund zwei Drittel. Abgang ease-in
 *   (ein Ding, das wegträgt, beschleunigt), Ankunft ease-out-expo.
 * · Ankunft mit Überschwinger, dann setzen.
 * · Nichts blendet. Es fährt oder es wird gedreht.
 * · NICHTS WIRD GELÖSCHT. Im Ruhezustand ist das Icon vollständig, und
 *   keine Geste darf es unvollständig machen. stroke-dashoffset, das eine
 *   ruhende Linie wegradiert und neu zeichnet, liest als Fehler, nicht als
 *   Bewegung — daran sind pulse, lines, doc und calendar zuerst gescheitert.
 *   Ein Zeichen-Effekt ist nur auf Teilen erlaubt, die im Ruhezustand
 *   ohnehin nicht da sind.
 * · NICHTS VERLÄSST DIE BOX. Die viewBox ist 24 Einheiten, die Glyphen
 *   füllen sie fast aus, und das svg schneidet an seiner Kante. Wer
 *   hinausfährt, wird abgesägt — bei 13px sieht man dann keinen Aufbruch,
 *   sondern ein kaputtes Icon. Jeder Weg ist gegen die Kante gerechnet,
 *   inklusive der halben Strichstärke (1.125).
 * · 100% ist identisch mit 0%, damit das Abreißen beim Verlassen des
 *   Hovers unsichtbar bleibt. Wo ein Zeichen Drehsymmetrie hat, wird sie
 *   ausgenutzt: 90° oder 360° sind dasselbe Bild.
 * · Physik ehrlich halten. Losgelassenes beschleunigt und dreht mit
 *   konstanter Rate. Motorgetriebenes läuft ohne Überschwinger zum Stand.
 *
 * ── RUHEZUSTAND GEHÖRT IN BASIS-REGELN ──────────────────────────────────
 * Im Ruhezustand hängt keine Animation am Element, ein 0%-Keyframe wird
 * also NIE erreicht. Jedes Teil mit abweichendem Ruhewert braucht eine
 * Basis-Regel hier. animation-fill-mode deckt nur die Dwell-Verzögerung.
 * Deshalb ist reduzierte Bewegung kostenlos: Animation nicht anhängen,
 * und das Icon sitzt in seinem Ruhebild.
 */

/* ── Grundlage ────────────────────────────────────────────────────────── */
.ai-ico { display: inline-flex; }
/* Das svg schneidet an der eigenen Kante (SVG-Standard). Genau deshalb
   bleibt jede Geste innerhalb der Box — siehe die Regel im Kopf. Einzige
   gewollte Ausnahme ist der Drucker, dessen Blatt in einem eigenen
   clipPath aus dem Schlitz fährt. */
.ai-ico svg > *,
.ai-ico svg g > * { transform-box: view-box; }
/* Fast alles dreht und skaliert um die Bildmitte. */
.ai-ico svg > *,
.ai-ico svg g > * { transform-origin: 12px 12px; }

/* Ruhezustände mit abweichendem Wert: derzeit keine — jedes Teil ruht auf
   seinem CSS-Initialwert. Die Regel bleibt als Merkposten stehen, weil der
   erste Teil mit abweichender Ruhelage sie sofort wieder braucht. */

/* ═══════════════════════════════════════════════════════════════════════
   arrow — der Pfeil streckt sich nach vorn.

   KEINE Reise aus dem Rahmen. Der Glyph läuft von x=4 bis x=20 in einer
   24er Box — vier Einheiten Luft rechts. Was hinausfährt, wird an der
   viewBox-Kante abgeschnitten, und bei 13px sieht man dann keinen Pfeil,
   der weggeht, sondern einen abgesägten Pfeil. Die Referenz kann sich
   das Schneiden leisten, weil ihre Glyphen in einer 256er Box mit echter
   Anlaufstrecke sitzen. Hier bleibt alles drin.

   Stattdessen streckt er sich: der Kopf führt, der Schaft wächst mit.
   Die Zahlen hängen zusammen — der Schaft ist 16 Einheiten lang, also
   ist scaleX = 1 + Kopfweg/16, mit Ursprung am Schaftende (4,12). So
   bleibt die Schaftspitze IMMER am Barben-Scheitel und es klafft nie.
   ═══════════════════════════════════════════════════════════════════════ */
.lg-arrow .ic-shaft { transform-origin: 4px 12px; }
.lg-arrow .ic-barb  { transform-origin: 20px 12px; }

@keyframes ig-arrow-shaft {
  0%   { scale: 1 1;      animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  /* ausholen: einen Hauch zurück, Kopfweg -1 */
  16%  { scale: .9375 1;  animation-timing-function: cubic-bezier(.19,1,.22,1); }
  /* strecken: Kopfweg +2, der Kopf steht dann auf x=22, noch in der Box */
  58%  { scale: 1.125 1;  animation-timing-function: cubic-bezier(.33,1,.68,1); }
  /* zurück, mit einem kleinen Unterschwinger, Kopfweg -0.4 */
  80%  { scale: .975 1;   animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { scale: 1 1; }
  100% { scale: 1 1; }
}
@keyframes ig-arrow-up {
  0%   { translate: 0 0; rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  16%  { translate: -1px 0; rotate: 10deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  58%  { translate: 2px 0; rotate: -6deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  80%  { translate: -.4px 0; rotate: 2deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; rotate: 0deg; }
  100% { translate: 0 0; rotate: 0deg; }
}
@keyframes ig-arrow-dn {
  0%   { translate: 0 0; rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  16%  { translate: -1px 0; rotate: -10deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  58%  { translate: 2px 0; rotate: 6deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  80%  { translate: -.4px 0; rotate: -2deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; rotate: 0deg; }
  100% { translate: 0 0; rotate: 0deg; }
}

/* ═══════════════════════════════════════════════════════════════════════
   clock — zwei Zeiger, zwei Geschwindigkeiten.
   Getrennte Pfade, also läuft der Minutenzeiger zwei Runden, während der
   Stundenzeiger eine nimmt. Beide holen zurück, beide landen auf einem
   Vielfachen von 360° — das Endbild ist das Anfangsbild.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-clock-min {
  0%   { rotate: 0deg; animation-timing-function: cubic-bezier(.5,0,.85,.3); }
  10%  { rotate: -34deg; animation-timing-function: cubic-bezier(.14,.9,.26,1); }
  72%  { rotate: 736deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  88%  { rotate: 720deg; }
  100% { rotate: 720deg; }
}
@keyframes ig-clock-hour {
  0%   { rotate: 0deg; animation-timing-function: cubic-bezier(.5,0,.85,.3); }
  10%  { rotate: -9deg; animation-timing-function: cubic-bezier(.2,.85,.3,1); }
  80%  { rotate: 368deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { rotate: 360deg; }
  100% { rotate: 360deg; }
}
/* Das Ziffernblatt atmet einmal mit, weil das Werk darin läuft. */
@keyframes ig-clock-face {
  0%   { scale: 1; animation-timing-function: cubic-bezier(.4,0,.6,1); }
  12%  { scale: .972; animation-timing-function: cubic-bezier(.2,.9,.3,1); }
  40%  { scale: 1.012; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  70%  { scale: 1; }
  100% { scale: 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   download — der Pfeil senkt sich in die Ablage.
   KEINE Reise aus dem Rahmen, aus demselben Grund wie beim arrow.
   Der Pfeil sinkt 3 Einheiten — die Barbenspitzen stehen dann auf
   y=14.6, die Schaftspitze auf y=19, beides klar über dem Ablagenboden.
   Wieder hängen die Zahlen zusammen: der Schaft ist 13 lang, also ist
   scaleY = 1 + Weg/13 mit Ursprung oben (12,3), damit die Schaftspitze
   immer am Barben-Scheitel bleibt.
   Der Einschlag hat eine Folge: die Ablage federt breiter und kommt
   OHNE Überschwinger zur Ruhe, weil eine Ablage nicht hüpft.
   ═══════════════════════════════════════════════════════════════════════ */
.lg-download .ic-shaft { transform-origin: 12px 3px; }
.lg-download .ic-barb  { transform-origin: 12px 16px; }
.lg-download .ic-tray  { transform-origin: 12px 21px; }

@keyframes ig-dl-shaft {
  0%   { scale: 1 1;      animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  14%  { scale: 1 .908;   animation-timing-function: cubic-bezier(.19,1,.22,1); }
  56%  { scale: 1 1.231;  animation-timing-function: cubic-bezier(.33,1,.68,1); }
  80%  { scale: 1 .962;   animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { scale: 1 1; }
  100% { scale: 1 1; }
}
@keyframes ig-dl-l {
  0%   { translate: 0 0; rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  14%  { translate: 0 -1.2px; rotate: -9deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  56%  { translate: 0 3px; rotate: 6deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  80%  { translate: 0 -.5px; rotate: -2deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; rotate: 0deg; }
  100% { translate: 0 0; rotate: 0deg; }
}
@keyframes ig-dl-r {
  0%   { translate: 0 0; rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.75,.5); }
  14%  { translate: 0 -1.2px; rotate: 9deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  56%  { translate: 0 3px; rotate: -6deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  80%  { translate: 0 -.5px; rotate: 2deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; rotate: 0deg; }
  100% { translate: 0 0; rotate: 0deg; }
}
@keyframes ig-dl-tray {
  0%   { scale: 1 1; }
  56%  { scale: 1 1; animation-timing-function: cubic-bezier(.2,.9,.3,1); }
  66%  { scale: 1.06 .95; animation-timing-function: cubic-bezier(.25,.4,.3,1); }
  100% { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   sparkle — der Stern dreht sich einmal weiter.
   Absichtlich die knappste Geste im Satz: ein Teil, ein Zug, keine Maske.
   4-zählig symmetrisch, also ist 90° exakt dasselbe Bild wie 0°.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-star {
  0%   { rotate: 0deg; animation-timing-function: cubic-bezier(.5,0,.85,.3); }
  14%  { rotate: -7deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  74%  { rotate: 93deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  88%  { rotate: 90deg; }
  100% { rotate: 90deg; }
}

/* ═══════════════════════════════════════════════════════════════════════
   check — der Haken stempelt sich auf.
   Er verschwindet NICHT und wird nicht neu gezeichnet: er drückt sich
   kurz zusammen und setzt mit Überschwinger auf.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-tick {
  0%   { scale: 1; rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  20%  { scale: .82; rotate: -4deg; animation-timing-function: cubic-bezier(.16,1,.3,1); }
  62%  { scale: 1.1; rotate: 2deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  84%  { scale: 1; rotate: 0deg; }
  100% { scale: 1; rotate: 0deg; }
}

/* ═══════════════════════════════════════════════════════════════════════
   shield — es dreht sich um die Hochachse, wie eine Münze.

   Nicht in der Ebene, sondern um Y: das Schild dreht sich weg, steht
   einen Moment auf der Kante und kommt zurück. Deshalb `transform:
   rotateY()` und nicht die eigenständige rotate-Eigenschaft — die dreht
   nur in der Ebene.

   BEWUSST OHNE perspective. Eine Perspektive wird in CSS-Pixeln relativ
   zur Elementgröße gemessen, wäre also bei 13px eine ganz andere Wirkung
   als bei 44px — und genau über diese Größen hinweg wird hier beurteilt.
   Orthografisch gedreht sieht die Bewegung in jeder Größe gleich aus:
   das Schild verkürzt sich zur Kante hin und öffnet wieder.

   Schild und Haken laufen auf DERSELBEN Kurve, damit sie als ein Körper
   drehen und der Haken nicht im Schild rutscht. 360° ist dasselbe Bild
   wie 0°, also ist der Abbruch beim Verlassen unsichtbar.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-shield-spin {
  0%   { transform: rotateY(0deg); animation-timing-function: cubic-bezier(.5,0,.85,.3); }
  /* ausholen: ein Stück in die Gegenrichtung, bevor es losdreht */
  13%  { transform: rotateY(-30deg); animation-timing-function: cubic-bezier(.15,.9,.26,1); }
  74%  { transform: rotateY(372deg); animation-timing-function: cubic-bezier(.33,1,.68,1); }
  89%  { transform: rotateY(360deg); }
  100% { transform: rotateY(360deg); }
}

/* ═══════════════════════════════════════════════════════════════════════
   lines / doc — die Zeilen rücken in Leserichtung nach.
   Jede Zeile schiebt sich gut eine Einheit nach rechts und kommt zurück,
   um 70ms gestaffelt. Vorher radierten sie sich weg und zeichneten neu:
   das sah aus, als fehle das Icon kurz.
   Beim doc bleibt der Rahmen still — ein Blatt bewegt sich nicht, weil
   darauf geschrieben wird.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-line {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  26%  { translate: 1.1px 0; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  58%  { translate: 1.1px 0; animation-timing-function: cubic-bezier(.45,0,.85,.4); }
  84%  { translate: -.2px 0; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { translate: 0 0; }
  100% { translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   folder — der Deckel lüftet.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-folder-body {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  30%  { translate: 0 -.35px; }
  60%  { translate: 0 -.35px; animation-timing-function: cubic-bezier(.5,0,.85,.4); }
  84%  { translate: 0 .15px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { translate: 0 0; }
  100% { translate: 0 0; }
}
/* Der Korpus reicht bis y=2; darum bleibt der Hub klein. */
@keyframes ig-folder-lid {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  30%  { translate: 0 -.7px; }
  60%  { translate: 0 -.7px; animation-timing-function: cubic-bezier(.5,0,.85,.4); }
  84%  { translate: 0 .3px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { translate: 0 0; }
  100% { translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   lock — der Bügel hebt, hält offen, fällt zurück ins Schloss.
   Der Bügel ist am Gehäuse geführt, also hebt er GERADE. Beim Fallen
   beschleunigt er und setzt hart — ein Schloss schnappt zu.
   ═══════════════════════════════════════════════════════════════════════ */
/* -0.7 und nicht mehr: der Bügelbogen endet bei y=2, mit halber
   Strichstärke also bei y=0.875 — bei -2.2 lief er oben aus der Box. */
@keyframes ig-lock-shackle {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  26%  { translate: 0 -.7px; }
  58%  { translate: 0 -.7px; animation-timing-function: cubic-bezier(.6,0,.95,.45); }
  76%  { translate: 0 .2px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  88%  { translate: 0 0; }
  100% { translate: 0 0; }
}
/* Das Gehäuse quittiert das Zuschnappen mit einem kurzen Stauchen. */
@keyframes ig-lock-body {
  0%   { scale: 1 1; }
  74%  { scale: 1 1; animation-timing-function: cubic-bezier(.2,.9,.3,1); }
  80%  { scale: 1.035 .965; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { scale: 1 1; }
  100% { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   pulse — der Ausschlag schlägt einmal aus.
   Ein Puls ist Amplitude, nicht Zeichnung: die Spur streckt sich um die
   Nulllinie (y=15) und fällt zurück. Vorher zeichnete sie sich weg und
   neu, was als Fehler las. Der Rahmen bleibt völlig still — das Gerät
   bewegt sich nicht.
   Gerechnet: Spitze bei y≈11.5, also 15 − 3.5·1.45 ≈ 9.9, plus halbe
   Strichstärke noch klar innerhalb des Rahmens.
   ═══════════════════════════════════════════════════════════════════════ */
.lg-pulse .ic-trace { transform-origin: 12px 15px; }
@keyframes ig-pulse-trace {
  0%   { scale: 1 1; animation-timing-function: cubic-bezier(.4,0,.75,.4); }
  14%  { scale: 1 .82; animation-timing-function: cubic-bezier(.12,.9,.24,1); }
  40%  { scale: 1 1.45; animation-timing-function: cubic-bezier(.4,0,.5,1); }
  66%  { scale: 1 .93; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  86%  { scale: 1 1.02; }
  100% { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   link — die beiden Bügel ziehen zueinander und lassen los.
   Sie ziehen entlang ihrer eigenen Achse, nicht einfach zur Mitte:
   die Kette liegt diagonal.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-link-a {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  28%  { translate: -.85px -.85px; }
  56%  { translate: -.85px -.85px; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  84%  { translate: .18px .18px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { translate: 0 0; }
  100% { translate: 0 0; }
}
@keyframes ig-link-b {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  28%  { translate: .85px .85px; }
  56%  { translate: .85px .85px; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  84%  { translate: -.18px -.18px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  94%  { translate: 0 0; }
  100% { translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   people — die zweite Person tritt dazu.
   Kopf und Körper der hinteren Person laufen als EINE Bewegung, nur um
   40ms versetzt, damit sie als eine Person liest und nicht als zwei Teile.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-people-back {
  0%   { translate: 0 0; scale: 1; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  22%  { translate: -.55px 0; scale: .96; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  64%  { translate: .95px -.25px; scale: 1.03; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  86%  { translate: 0 0; scale: 1; }
  100% { translate: 0 0; scale: 1; }
}
/* Die vordere Person macht nur Platz und kommt zurück. */
@keyframes ig-people-front {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.4,0,.7,.6); }
  30%  { translate: -.5px 0; }
  62%  { translate: -.5px 0; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  88%  { translate: 0 0; }
  100% { translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   compass — die Nadel sucht über Norden hinaus und findet zurück.
   Eine Kompassnadel pendelt aus: jeder Ausschlag kleiner als der vorige.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-compass-needle {
  0%   { rotate: 0deg; animation-timing-function: cubic-bezier(.45,0,.85,.35); }
  12%  { rotate: 26deg; animation-timing-function: cubic-bezier(.16,1,.3,1); }
  46%  { rotate: -318deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  64%  { rotate: -378deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  78%  { rotate: -348deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  89%  { rotate: -366deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  100% { rotate: -360deg; }
}

/* ═══════════════════════════════════════════════════════════════════════
   mail — die Klappe fällt auf und schließt schneller, als sie aufging.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-mail-flap {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.16,1,.3,1); }
  30%  { translate: 0 2.1px; }
  62%  { translate: 0 2.1px; animation-timing-function: cubic-bezier(.5,0,.85,.35); }
  84%  { translate: 0 -.22px; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; }
  100% { translate: 0 0; }
}

/* ═══════════════════════════════════════════════════════════════════════
   phone — klingelt einmal an.
   Ausschläge werden kleiner, wie ein Hörer, der ausschwingt.
   ═══════════════════════════════════════════════════════════════════════ */
@keyframes ig-phone {
  0%   { rotate: 0deg; animation-timing-function: cubic-bezier(.4,0,.7,1); }
  10%  { rotate: 4deg; animation-timing-function: cubic-bezier(.2,.9,.3,1); }
  32%  { rotate: -10deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  52%  { rotate: 7deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  70%  { rotate: -5.5deg; animation-timing-function: cubic-bezier(.4,0,.4,1); }
  84%  { rotate: 2.5deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  93%  { rotate: -1deg; }
  100% { rotate: 0deg; }
}

/* ═══════════════════════════════════════════════════════════════════════
   calendar — das Blatt rollt sich an den Ringen auf und fällt zurück.

   Das Blatt hängt oben an den Ringen, also ist DORT das Scharnier: die
   Stauchung läuft um y=3, nicht um die Mitte. Ein Blatt, das sich hebt,
   verkürzt sich von unten — genau das macht scaleY um die Ringlinie.

   Rahmen, Trennlinie UND Punkte tragen dieselbe Transformation, denn ein
   starres Blatt nimmt seine Bedruckung mit. Deshalb dürfen die Punkte
   auch keinen eigenen Takt bekommen, so verlockend das wäre.

   Bounds: der Rahmen endet bei y=22, Scharnier bei y=3, also 19 Einheiten
   Hebel. Der Überschwinger bleibt bei 1.02 — 3 + 19·1.02 = 22.4, plus
   halbe Strichstärke 23.5. Bei 1.03 stieße er an.
   ═══════════════════════════════════════════════════════════════════════ */
.lg-calendar .ic-body,
.lg-calendar .ic-rule,
.lg-calendar .ic-dots { transform-origin: 12px 3px; }

@keyframes ig-cal-rings {
  0%   { translate: 0 0; rotate: 0deg; animation-timing-function: cubic-bezier(.19,1,.22,1); }
  22%  { translate: 0 -1px; rotate: -2deg; }
  56%  { translate: 0 -1px; rotate: -2deg; animation-timing-function: cubic-bezier(.5,0,.85,.4); }
  80%  { translate: 0 .18px; rotate: .8deg; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  92%  { translate: 0 0; rotate: 0deg; }
  100% { translate: 0 0; rotate: 0deg; }
}
@keyframes ig-cal-sheet {
  0%   { scale: 1 1; animation-timing-function: cubic-bezier(.4,0,.72,.55); }
  /* aufrollen: das Blatt verkürzt sich von unten zum Scharnier hin */
  30%  { scale: 1 .87; animation-timing-function: cubic-bezier(.18,1,.28,1); }
  48%  { scale: 1 .89; animation-timing-function: cubic-bezier(.5,0,.85,.4); }
  /* fallen lassen, einmal überschwingen, setzen */
  76%  { scale: 1 1.02; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  90%  { scale: 1 .996; }
  100% { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   print — das Blatt wird eingezogen und läuft wieder heraus.

   AM FROZEN-FRAME-STRIP ENTSCHIEDEN. Zwei Befunde von dort tragen alles:

   1  Das OBERE Blatt darf sich nicht senken. Weil sich mit Strichen
      nichts verdecken lässt, verschwindet es nicht hinter dem Korpus —
      sein Umriss fällt mit dessen Oberkante zusammen, und zwischen
      t=154ms und 359ms war auf dem Strip kein Drucker mehr zu sehen,
      sondern ein anderer Gegenstand. Es bleibt also stehen.

   2  Das UNTERE Blatt darf sich sehr wohl bewegen, und zwar nach OBEN:
      dort hat es 12.9 Einheiten Luft, und es bleibt dabei die ganze Zeit
      sichtbar unter der Maschine stehen. Bei -2 reicht es immer noch
      zwei Einheiten unter den Korpus — der Umriss bleibt ein Drucker.

   Daraus die Geste, und sie ist die eines Druckers und keines beliebigen
   Gegenstands: das Blatt wird eingezogen (schnell, der Motor greift zu),
   sitzt kurz, und läuft dann wieder heraus — ease-out auf einen TOTEN
   Stand, denn ein Papiervorschub federt nicht.

   Kein Verschwinden, kein Stauchen auf Null, kein Umriss-Bruch: das Blatt
   fährt nur, und es ist in jedem Bild ein ganzes Blatt.

   Zwei Einheiten sind bei 13px 1.08 Bildschirm-Pixel — über der Schwelle,
   unter der bei dieser Größe nichts mehr liest.
   ═══════════════════════════════════════════════════════════════════════ */
.lg-print .ic-body { transform-origin: 12px 13.5px; }

@keyframes ig-print-sheet {
  0%   { translate: 0 0; animation-timing-function: cubic-bezier(.45,0,.85,.35); }
  /* eingezogen */
  22%  { translate: 0 -2px; }
  /* kurz sitzen, während das Werk greift */
  40%  { translate: 0 -2px; animation-timing-function: cubic-bezier(.25,.45,.3,1); }
  /* herauslaufen, motorisch, ohne Überschwinger auf den Stand */
  86%  { translate: 0 0; }
  100% { translate: 0 0; }
}
/* Der Korpus quittiert im Moment des Zugriffs. Bewusst klein: er ist
   Anker, nicht Akteur — bewegte er sich merklich, bräche der Umriss. */
@keyframes ig-print-body {
  0%   { scale: 1 1; }
  12%  { scale: 1 1;        animation-timing-function: cubic-bezier(.3,.85,.35,1); }
  24%  { scale: 1.015 .975; animation-timing-function: cubic-bezier(.33,1,.68,1); }
  52%  { scale: 1 1; }
  100% { scale: 1 1; }
}

/* ═══════════════════════════════════════════════════════════════════════
   AUSLÖSER
   data-go setzt site.js auf den Host — den nächsten Link, Button oder
   [data-icon-host]. Nur bei echtem Zeiger: auf Touch gibt es keine
   Hover-Absicht, und eine Geste, die beim Antippen feuert, stört dort.
   --ig-delay staffelt mehrere Icons am selben Host.
   ═══════════════════════════════════════════════════════════════════════ */
@media (hover: hover) and (pointer: fine) {
  [data-go] .lg-arrow .ic-shaft { animation: ig-arrow-shaft .90s var(--ig-delay,0s) both; }
  [data-go] .lg-arrow .ic-up    { animation: ig-arrow-up    .90s var(--ig-delay,0s) both; }
  [data-go] .lg-arrow .ic-dn    { animation: ig-arrow-dn    .90s var(--ig-delay,0s) both; }

  [data-go] .lg-clock .ic-min   { animation: ig-clock-min  1.15s var(--ig-delay,0s) both; }
  [data-go] .lg-clock .ic-hour  { animation: ig-clock-hour 1.15s var(--ig-delay,0s) both; }
  [data-go] .lg-clock .ic-face  { animation: ig-clock-face 1.15s var(--ig-delay,0s) both; }

  [data-go] .lg-download .ic-shaft { animation: ig-dl-shaft .95s var(--ig-delay,0s) both; }
  [data-go] .lg-download .ic-l     { animation: ig-dl-l     .95s var(--ig-delay,0s) both; }
  [data-go] .lg-download .ic-r     { animation: ig-dl-r     .95s var(--ig-delay,0s) both; }
  [data-go] .lg-download .ic-tray  { animation: ig-dl-tray  .95s var(--ig-delay,0s) both; }

  [data-go] .lg-sparkle .ic-star { animation: ig-star .58s var(--ig-delay,0s) both; }

  [data-go] .lg-check .ic-tick { animation: ig-tick .80s var(--ig-delay,0s) both; }

  /* Schild und Haken auf derselben Kurve: sie drehen als ein Körper. */
  [data-go] .lg-shield .ic-body,
  [data-go] .lg-shield .ic-tick { animation: ig-shield-spin .95s var(--ig-delay,0s) both; }

  [data-go] .lg-lines .ic-line { animation: ig-line .82s both; }
  [data-go] .lg-lines .ic-l1   { animation-delay: calc(var(--ig-delay,0s) + 0s); }
  [data-go] .lg-lines .ic-l2   { animation-delay: calc(var(--ig-delay,0s) + .07s); }
  [data-go] .lg-lines .ic-l3   { animation-delay: calc(var(--ig-delay,0s) + .14s); }

  [data-go] .lg-doc .ic-line { animation: ig-line .82s both; }
  [data-go] .lg-doc .ic-l1   { animation-delay: calc(var(--ig-delay,0s) + 0s); }
  [data-go] .lg-doc .ic-l2   { animation-delay: calc(var(--ig-delay,0s) + .07s); }
  [data-go] .lg-doc .ic-l3   { animation-delay: calc(var(--ig-delay,0s) + .14s); }

  [data-go] .lg-folder .ic-body { animation: ig-folder-body .78s var(--ig-delay,0s) both; }
  [data-go] .lg-folder .ic-lid  { animation: ig-folder-lid  .78s var(--ig-delay,0s) both; }

  [data-go] .lg-lock .ic-shackle { animation: ig-lock-shackle .82s var(--ig-delay,0s) both; }
  [data-go] .lg-lock .ic-body    { animation: ig-lock-body    .82s var(--ig-delay,0s) both; }

  [data-go] .lg-pulse .ic-trace { animation: ig-pulse-trace 1.0s var(--ig-delay,0s) both; }

  [data-go] .lg-link .ic-a { animation: ig-link-a .80s var(--ig-delay,0s) both; }
  [data-go] .lg-link .ic-b { animation: ig-link-b .80s var(--ig-delay,0s) both; }

  [data-go] .lg-people .ic-back-head  { animation: ig-people-back  .84s both;
                                        animation-delay: calc(var(--ig-delay,0s) + 0s); }
  [data-go] .lg-people .ic-back-body  { animation: ig-people-back  .84s both;
                                        animation-delay: calc(var(--ig-delay,0s) + .04s); }
  [data-go] .lg-people .ic-front-head { animation: ig-people-front .84s var(--ig-delay,0s) both; }
  [data-go] .lg-people .ic-front-body { animation: ig-people-front .84s var(--ig-delay,0s) both; }

  [data-go] .lg-compass .ic-needle { animation: ig-compass-needle 1.05s var(--ig-delay,0s) both; }

  [data-go] .lg-mail .ic-flap { animation: ig-mail-flap .78s var(--ig-delay,0s) both; }

  [data-go] .lg-phone .ic-handset { animation: ig-phone .92s var(--ig-delay,0s) both; }

  [data-go] .lg-calendar .ic-rings { animation: ig-cal-rings .88s var(--ig-delay,0s) both; }
  /* Rahmen, Linie und Punkte laufen als ein Blatt. */
  [data-go] .lg-calendar .ic-body,
  [data-go] .lg-calendar .ic-rule,
  [data-go] .lg-calendar .ic-dots  { animation: ig-cal-sheet .88s var(--ig-delay,0s) both; }

  [data-go] .lg-print .ic-sheet { animation: ig-print-sheet .78s var(--ig-delay,0s) both; }
  [data-go] .lg-print .ic-body  { animation: ig-print-body  .78s var(--ig-delay,0s) both; }
}

/* Reduzierte Bewegung: site.js registriert schon nicht, hier zusätzlich
   hart aus. Kostenlos, weil jede Ruhelage in Basis-Regeln steht. */
@media (prefers-reduced-motion: reduce) {
  .ai-ico svg * { animation: none !important; }
}
