/* Custom animations in posts (<figure class="viz anim">, from
   apps/blog/app/animations.py). Loaded by the public article page and the
   editor, so a drawing looks the same in both. The palette and motion classes
   here are the whole vocabulary an animation can use; they're documented for
   any AI in apps/blog/skills/animations/SKILL.md. */

.anim {
  --a-ink: var(--ink, #1b1c19);
  --a-soft: var(--ink-soft, #3a3c37);
  --a-muted: var(--muted, #67665e);
  --a-line: var(--line-strong, rgba(27, 28, 25, 0.3));
  --a-surface: var(--surface, #fffdf8);
  --a-bg: var(--bg-deep, #f1eee6);
  --a-accent: var(--accent, #b93a06);
  --a-wash: var(--accent-wash, rgba(185, 58, 6, 0.14));
  --a-sage: var(--sage, #6f8f7a);
  --a-step: 0.3s;
}

/* Plain SVG rules inside a drawing (the built-in figures center every
   transform; custom ones rotate and scale around 0,0 like any SVG). */
.viz.anim svg * { transform-box: view-box; transform-origin: 0 0; }

.anim .a-fill-ink { fill: var(--a-ink); }
.anim .a-fill-soft { fill: var(--a-soft); }
.anim .a-fill-muted { fill: var(--a-muted); }
.anim .a-fill-line { fill: var(--a-line); }
.anim .a-fill-surface { fill: var(--a-surface); }
.anim .a-fill-bg { fill: var(--a-bg); }
.anim .a-fill-accent { fill: var(--a-accent); }
.anim .a-fill-wash { fill: var(--a-wash); }
.anim .a-fill-sage { fill: var(--a-sage); }
.anim .a-stroke-ink { stroke: var(--a-ink); }
.anim .a-stroke-soft { stroke: var(--a-soft); }
.anim .a-stroke-muted { stroke: var(--a-muted); }
.anim .a-stroke-line { stroke: var(--a-line); }
.anim .a-stroke-surface { stroke: var(--a-surface); }
.anim .a-stroke-bg { stroke: var(--a-bg); }
.anim .a-stroke-accent { stroke: var(--a-accent); }
.anim .a-stroke-wash { stroke: var(--a-wash); }
.anim .a-stroke-sage { stroke: var(--a-sage); }
.anim .a-text { fill: var(--a-soft); font-family: var(--font-mono, "JetBrains Mono", ui-monospace, monospace); font-size: 11px; }

/* Motion that works around the shape's own center. */
.viz.anim svg :is(.a-spin, .a-spin-rev, .a-pulse, .a-float, .a-sway, .a-ripple) { transform-box: fill-box; transform-origin: center; }
.viz.anim svg .a-grow-x { transform-box: fill-box; transform-origin: left center; }
.viz.anim svg .a-grow-y { transform-box: fill-box; transform-origin: center bottom; }

.anim .a-spin { animation: a-spin 8s linear infinite; }
.anim .a-spin-rev { animation: a-spin 8s linear infinite reverse; }
.anim .a-pulse { animation: a-pulse 2.4s ease-in-out infinite; }
.anim .a-blink { animation: a-blink 2.6s ease-in-out infinite; }
.anim .a-float { animation: a-float 4s ease-in-out infinite; }
.anim .a-sway { animation: a-sway 5s ease-in-out infinite; }
.anim .a-ripple { animation: a-ripple 2.8s ease-out infinite; }
.anim .a-draw { stroke-dasharray: 1; stroke-dashoffset: 1; animation: a-draw 4s ease-in-out infinite; }
.anim .a-march { stroke-dasharray: 3 5; animation: a-march 1.6s linear infinite; }
.anim .a-grow-x { animation: a-grow-x 5s ease-in-out infinite; }
.anim .a-grow-y { animation: a-grow-y 5s ease-in-out infinite; }
.anim .a-fade { animation: a-fade 5s ease-in-out infinite; }
.anim .a-appear { opacity: 0; animation: a-appear 0.9s ease-out forwards; }
/* Stagger: style="--k: N" delays by N steps. */
.anim :is(.a-spin, .a-spin-rev, .a-pulse, .a-blink, .a-float, .a-sway, .a-ripple, .a-draw, .a-march, .a-grow-x, .a-grow-y, .a-fade, .a-appear) {
  animation-delay: calc(var(--k, 0) * var(--a-step));
}

@keyframes a-spin { to { transform: rotate(360deg); } }
@keyframes a-pulse { 0%, 100% { transform: scale(0.88); opacity: 0.55; } 50% { transform: scale(1.12); opacity: 1; } }
@keyframes a-blink { 0%, 100% { opacity: 0.3; } 50% { opacity: 1; } }
@keyframes a-float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
@keyframes a-sway { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes a-ripple { 0% { transform: scale(0.8); opacity: 0.9; } 100% { transform: scale(1.8); opacity: 0; } }
@keyframes a-draw { 0% { stroke-dashoffset: 1; } 40%, 75% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -1; } }
@keyframes a-march { to { stroke-dashoffset: -32; } }
@keyframes a-grow-x { 0% { transform: scaleX(0); } 35%, 80% { transform: scaleX(1); } 100% { transform: scaleX(0); } }
@keyframes a-grow-y { 0% { transform: scaleY(0); } 35%, 80% { transform: scaleY(1); } 100% { transform: scaleY(0); } }
@keyframes a-fade { 0%, 100% { opacity: 0; } 25%, 75% { opacity: 1; } }
@keyframes a-appear { to { opacity: 1; } }

@media (prefers-reduced-motion: reduce) {
  .anim svg * { animation: none !important; }
  .anim .a-appear, .anim .a-fade { opacity: 1; }
  .anim .a-draw { stroke-dashoffset: 0; }
}

/* Paused until the figure scrolls into view (site.js adds .is-live). */
.viz.anim:not(.is-live) svg * { animation-play-state: paused; }
