Files
zeekay 045cc9a6b6 feat(motion): a loading state, and one spelling of the animated mark
There was no way to say "still working". ANIMATED_SVG folds in ONCE and stops
(`forwards`); MOTION_CSS is an intro flip plus a breathe loop. Neither is an
indeterminate state, so surfaces invented their own — the only spinner in the
fleet is ten hand-drawn raster frames in studio/branding.

getLoadingSVG() / LOADING_CSS / getLoadingMarkup() are the same origami fold the
mark already does, staggered across the five blocks and looping: each turns in
on its edge, holds while the others arrive, then turns out. Motion rather than
progress, which is what indeterminate should say. Built from MARK_BLOCKS and
MARK_SHADE, currentColor, prefers-reduced-motion honoured.

The one-shot mark hardcoded fill:#fff and .s{fill:#ddd}, so the animated mark
was invisible on a light page — the ground the house asks for. Both are
currentColor now, the slivers at reduced opacity rather than a second hex.

And svg/hanzo-mark-animated.svg was a hand-maintained SECOND spelling of that
animation — 5 paths and #fff against the constant's 7 and currentColor, one
package, two versions, already drifted. build.ts generates it from the constant
now, plus dist/logo-animated.svg with an export entry.

MARK_SHADE is exported: only the pre-baked MARK_PATHS string was reachable, so a
consumer wanting a different sliver ink had to retype the geometry.
2026-08-24 19:34:34 -07:00
..