/* castomo-icons — stroke icons, draw-in, and motions. Dependency-free; pair with icons.js.
 *
 * Markup (any of the three renders the same):
 *   <svg class="ci" viewBox="0 0 24 24" aria-hidden="true">…shapes…</svg>          inline (copy from gallery)
 *   <svg class="ci"><use href="/assets/icons/sprite.svg#bell"/></svg>               sprite
 *   <i data-ci="bell"></i>                                                         placeholder, icons.js inlines it
 *
 * Behaviour is opt-in with attributes on the <svg> (or the <i> placeholder):
 *   data-motion="ring"   one of the motions below; plays on hover/focus of the icon or of the
 *                        nearest a, button, label, summary, [role=button] or .ci-host around it
 *   data-trigger="loop"  play forever instead of on hover
 *   data-trigger="in"    play once when scrolled into view (needs icons.js)
 *   class="ci-draw"      stroke draws itself in when scrolled into view (needs icons.js)
 *
 * Every shape carries pathLength="1", so draw-in is plain CSS on inherited dash properties — it
 * works through <use> as well, with no per-path measuring. Sizing: --ci-size, --ci-stroke.
 * Colour: currentColor. prefers-reduced-motion (or [data-motion="reduce"] on <html>) stops all
 * motion and shows every stroke finished.
 */
.ci {
  --ci-ease: cubic-bezier(.2, .7, .2, 1);
  --ci-spring: cubic-bezier(.34, 1.56, .64, 1);
  width: var(--ci-size, 24px); height: var(--ci-size, 24px);
  flex: none; overflow: visible; vertical-align: -0.2em;
  fill: none; stroke: currentColor; stroke-width: var(--ci-stroke, 1.6);
  stroke-linecap: round; stroke-linejoin: round;
  transform-origin: 50% 50%;
}
i[data-ci] { display: inline-block; width: var(--ci-size, 24px); height: var(--ci-size, 24px); }

/* ── draw-in: hidden only once icons.js has marked the page, so no-JS pages show finished icons */
.ci-js .ci-draw:not(.ci-in) { stroke-dasharray: 1; stroke-dashoffset: 1; }
.ci-draw.ci-in { stroke-dasharray: 1; animation: ci-draw var(--ci-draw-dur, 1.4s) var(--ci-ease) var(--ci-delay, 0s) both; }
@keyframes ci-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }

/* ── motion triggers: hover/focus of the icon or its interactive host, loop, or in-view once */
:is(a, button, label, summary, [role="button"], .ci-host):is(:hover, :focus-visible) .ci[data-motion]:not([data-trigger]),
.ci[data-motion]:not([data-trigger]):hover,
.ci[data-motion][data-trigger="loop"],
.ci[data-motion][data-trigger="in"].ci-in {
  animation: var(--ci-anim) var(--ci-dur, .7s) var(--ci-timing, var(--ci-ease)) var(--ci-delay, 0s) var(--ci-iter, 1) both;
}
.ci[data-trigger="loop"] { --ci-iter: infinite; }

/* ── motions: each sets its keyframes, and duration/origin/easing when the default is wrong */
.ci[data-motion="draw"]    { --ci-anim: ci-draw-re; --ci-dur: 1.2s; stroke-dasharray: 1; }
.ci[data-motion="nudge"]   { --ci-anim: ci-nudge; --ci-dur: .6s; }
.ci[data-motion="back"]    { --ci-anim: ci-back; --ci-dur: .6s; }
@keyframes ci-back    { 0%, 100% { transform: none; } 45% { transform: translateX(-3px); } }
.ci[data-motion="lift"]    { --ci-anim: ci-lift; --ci-dur: .6s; }
.ci[data-motion="fly"]     { --ci-anim: ci-fly; --ci-dur: .9s; }
.ci[data-motion="bounce"]  { --ci-anim: ci-bounce; --ci-dur: .9s; }
.ci[data-motion="spin"]    { --ci-anim: ci-spin; --ci-dur: 1.2s; }
.ci[data-motion="turn"]    { --ci-anim: ci-turn; --ci-dur: .6s; --ci-timing: var(--ci-spring); }
.ci[data-motion="ring"]    { --ci-anim: ci-ring; --ci-dur: .9s; transform-origin: 50% 8%; }
.ci[data-motion="beat"]    { --ci-anim: ci-beat; --ci-dur: 1s; }
.ci[data-motion="pop"]     { --ci-anim: ci-pop; --ci-dur: .5s; --ci-timing: var(--ci-spring); }
.ci[data-motion="wiggle"]  { --ci-anim: ci-wiggle; --ci-dur: .6s; }
.ci[data-motion="shake"]   { --ci-anim: ci-shake; --ci-dur: .5s; }
.ci[data-motion="sway"]    { --ci-anim: ci-sway; --ci-dur: 1s; transform-origin: 20% 95%; }
.ci[data-motion="float"]   { --ci-anim: ci-float; --ci-dur: 1.8s; --ci-timing: ease-in-out; }
.ci[data-motion="twinkle"] { --ci-anim: ci-twinkle; --ci-dur: 1.1s; }
.ci[data-motion="blink"]   { --ci-anim: ci-blink; --ci-dur: .5s; }
.ci[data-motion="flip"]    { --ci-anim: ci-flip; --ci-dur: .8s; }
.ci[data-motion="tilt"]    { --ci-anim: ci-tilt; --ci-dur: .6s; }
/* a looping spin must not ease in and out every turn */
.ci[data-motion="spin"][data-trigger="loop"] { --ci-timing: linear; }

@keyframes ci-draw-re { 0% { stroke-dashoffset: 1; } 100% { stroke-dashoffset: 0; } }
@keyframes ci-nudge   { 0%, 100% { transform: none; } 45% { transform: translateX(3px); } }
@keyframes ci-lift    { 0%, 100% { transform: none; } 45% { transform: translateY(-3px); } }
@keyframes ci-fly     { 0% { transform: none; } 40% { transform: translate(6px, -6px) scale(.85); opacity: 0; }
                        41% { transform: translate(-6px, 6px) scale(.85); opacity: 0; } 100% { transform: none; opacity: 1; } }
@keyframes ci-bounce  { 0%, 100% { transform: none; } 30% { transform: translateY(-5px); } 55% { transform: translateY(0); }
                        70% { transform: translateY(-2px); } 85% { transform: translateY(0); } }
@keyframes ci-spin    { to { transform: rotate(360deg); } }
@keyframes ci-turn    { 0% { transform: none; } 100% { transform: rotate(-90deg); } }
@keyframes ci-ring    { 0%, 100% { transform: none; } 15% { transform: rotate(14deg); } 30% { transform: rotate(-12deg); }
                        45% { transform: rotate(8deg); } 60% { transform: rotate(-5deg); } 75% { transform: rotate(2deg); } }
@keyframes ci-beat    { 0%, 60%, 100% { transform: none; } 15% { transform: scale(1.18); } 30% { transform: scale(.98); } 45% { transform: scale(1.1); } }
@keyframes ci-pop     { 0% { transform: none; } 50% { transform: scale(1.22); } 100% { transform: none; } }
@keyframes ci-wiggle  { 0%, 100% { transform: none; } 20% { transform: rotate(-9deg); } 40% { transform: rotate(8deg); }
                        60% { transform: rotate(-5deg); } 80% { transform: rotate(3deg); } }
@keyframes ci-shake   { 0%, 100% { transform: none; } 20%, 60% { transform: translateX(-2px); } 40%, 80% { transform: translateX(2px); } }
@keyframes ci-sway    { 0%, 100% { transform: none; } 30% { transform: rotate(-8deg); } 65% { transform: rotate(5deg); } }
@keyframes ci-float   { 0%, 100% { transform: none; } 50% { transform: translateY(-3px); } }
@keyframes ci-twinkle { 0%, 100% { transform: none; opacity: 1; } 35% { transform: scale(1.2) rotate(8deg); opacity: .55; }
                        70% { transform: scale(.94); opacity: 1; } }
@keyframes ci-blink   { 0%, 100% { transform: none; } 45% { transform: scaleY(.15); } }
@keyframes ci-flip    { 0% { transform: perspective(60px) rotateY(0); } 100% { transform: perspective(60px) rotateY(360deg); } }
@keyframes ci-tilt    { 0%, 100% { transform: none; } 45% { transform: rotate(-12deg); } }

.ci[data-motion="parts"]   { --ci-anim: none; }

/* ── big doodles: illustration canvases (120×120 or 240×80), drawn heavier and sized by width */
.ci.ci-big { width: var(--ci-big, 160px); height: auto; stroke-width: var(--ci-stroke, 2.2); --pu: 5; }

/* ── comic stories (strip()): the strip fills its container; one caption sits under each panel */
.ci-story { margin: 0; display: grid; gap: 10px; }
.ci-story .ci.ci-big { width: 100%; }
.ci-story figcaption b { display: block; margin-bottom: 6px; }
.ci-story ol { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px; }

/* ── part animations: elements tagged data-a move on their own while the icon's trigger holds.
   Lengths scale by --pu (1 on the 24 grid, 5 on big canvases) so one keyframe fits both.
   data-i staggers siblings: delay = index × --ps. */
.ci [data-a] { transform-box: fill-box; transform-origin: 50% 50%; }
:is(a, button, label, summary, [role="button"], .ci-host):is(:hover, :focus-visible) .ci[data-motion="parts"]:not([data-trigger]) [data-a],
.ci[data-motion="parts"]:not([data-trigger]):hover [data-a],
.ci[data-motion="parts"][data-trigger="loop"] [data-a],
.ci[data-motion="parts"][data-trigger="in"].ci-in [data-a] {
  animation: var(--pa) var(--pd, 1.6s) var(--pt, ease-in-out) calc(var(--pi, 0) * var(--ps, .2s)) infinite both;
}
.ci [data-i="1"] { --pi: 1; } .ci [data-i="2"] { --pi: 2; } .ci [data-i="3"] { --pi: 3; }
.ci [data-i="4"] { --pi: 4; } .ci [data-i="5"] { --pi: 5; }
.ci [data-a="dash-flow"] { stroke-dasharray: .07 .05; }

.ci [data-a="fade"]       { --pa: pa-fade; }
.ci [data-a="bob"]        { --pa: pa-bob; --pd: 1.2s; }
.ci [data-a="rise"]       { --pa: pa-rise; --pd: 2s; --ps: .6s; --pt: ease-out; }
.ci [data-a="fall"]       { --pa: pa-fall; --pd: 1.1s; --ps: .35s; --pt: ease-in; }
.ci [data-a="drop"]       { --pa: pa-drop; --pd: 1.8s; --pt: cubic-bezier(.5, 0, .7, 1); }
.ci [data-a="spin"]       { --pa: pa-spin; --pd: 2.4s; --pt: linear; }
.ci [data-a="spin-rev"]   { --pa: pa-spin-rev; --pd: 1.8s; --pt: linear; }
.ci [data-a="spin-slow"]  { --pa: pa-spin; --pd: 9s; --pt: linear; }
.ci [data-a="hand"]       { --pa: pa-spin; --pd: 2.4s; --pt: linear; transform-origin: 50% 100%; }
.ci [data-a="hand-slow"]  { --pa: pa-spin; --pd: 28.8s; --pt: linear; transform-origin: 50% 100%; }
.ci [data-a="swing"]      { --pa: pa-swing; transform-origin: 50% 0; }
.ci [data-a="jiggle"]     { --pa: pa-jiggle; }
.ci [data-a="switch"]     { --pa: pa-switch; --pd: 2.4s; }
.ci [data-a="wave"]       { --pa: pa-wave; --pd: 1.8s; transform-origin: 40% 100%; }
.ci [data-a="sway"]       { --pa: pa-sway; --pd: 3s; transform-origin: 50% 100%; }
.ci [data-a="flutter"]    { --pa: pa-flutter; --pd: 1.4s; transform-origin: 0 50%; }
.ci [data-a="pulse"]      { --pa: pa-pulse; --pd: 1.2s; }
.ci [data-a="ping"]       { --pa: pa-ping; --pd: 1.8s; --pt: ease-out; }
.ci [data-a="beat"]       { --pa: ci-beat; --pd: 1.3s; }
.ci [data-a="draw-loop"]  { --pa: pa-draw-loop; --pd: 2.6s; stroke-dasharray: 1; }
.ci [data-a="dash-flow"]  { --pa: pa-dash-flow; --pd: 1.2s; --pt: linear; }
.ci [data-a="grow"]       { --pa: pa-grow; --pd: 1.6s; transform-origin: 50% 100%; }
.ci [data-a="slide-up"]   { --pa: pa-slide-up; --pd: 1.6s; }
.ci [data-a="slide-down"] { --pa: pa-slide-down; --pd: 1.6s; }
.ci [data-a="blink"]      { --pa: pa-blink; --pd: 3.2s; }
.ci [data-a="flicker"]    { --pa: pa-flicker; --pd: .9s; transform-origin: 50% 100%; }
.ci [data-a="twinkle"]    { --pa: pa-twinkle; --pd: 1.8s; --ps: .35s; }
.ci [data-a="lift"]       { --pa: pa-lift; --pd: 2.2s; }
.ci [data-a="orbit"]      { --pa: pa-orbit; --pd: 2.2s; --pt: linear; }
.ci [data-a="squash"]     { --pa: pa-squash; --pd: 2.6s; }
.ci [data-a="fly"]        { --pa: pa-fly; --pd: 2.2s; }
.ci [data-a="pop"]        { --pa: pa-pop; --pd: 2.2s; }
.ci [data-a="sweep"]      { --pa: pa-spin; --pd: 3s; --pt: linear; transform-origin: 0 100%; }

/* character parts: the pivot (shoulder, hip, neck) is set inline on the part as view-box px */
.ci [data-a="grow-x"]     { --pa: pa-grow-x; --pd: 2s; transform-origin: 0 50%; }
.ci [data-a="flip-half"]  { --pa: pa-flip-half; --pd: 2.4s; }
.ci [data-a="wobble"]     { --pa: pa-wobble; --pd: 2s; }
@keyframes pa-grow-x     { 0% { transform: scaleX(.05); } 70%, 100% { transform: none; } }
@keyframes pa-flip-half  { 0%, 40% { transform: none; } 60%, 100% { transform: rotate(180deg); } }
@keyframes pa-wobble     { 0%, 100% { transform: rotate(-18deg); } 50% { transform: rotate(18deg); } }
.ci [data-a="arm-wave"]   { --pa: pa-arm-wave; --pd: 1s; }
.ci [data-a="arm-sway"]   { --pa: pa-arm-sway; --pd: 1.6s; }
@keyframes pa-arm-sway   { 0%, 100% { transform: rotate(-5deg); } 50% { transform: rotate(6deg); } }
.ci [data-a="rock"]       { --pa: pa-rock; --pd: .8s; }
.ci [data-a="rock-rev"]   { --pa: pa-rock-rev; --pd: .8s; }
.ci [data-a="nod"]        { --pa: pa-nod; --pd: 2.4s; }
.ci [data-a="jump"]       { --pa: pa-jump; --pd: 1.3s; }
.ci [data-a="tap"]        { --pa: pa-tap; --pd: .4s; }
@keyframes pa-arm-wave   { 0%, 100% { transform: rotate(-10deg); } 50% { transform: rotate(14deg); } }
@keyframes pa-rock       { 0%, 100% { transform: rotate(-16deg); } 50% { transform: rotate(16deg); } }
@keyframes pa-rock-rev   { 0%, 100% { transform: rotate(16deg); } 50% { transform: rotate(-16deg); } }
@keyframes pa-nod        { 0%, 100% { transform: none; } 30% { transform: rotate(-7deg); } 60% { transform: rotate(5deg); } }
@keyframes pa-jump       { 0%, 100% { transform: none; } 40%, 55% { transform: translateY(calc(-3px * var(--pu, 1))); } }
@keyframes pa-tap        { 0%, 100% { transform: none; } 50% { transform: translateY(calc(-.6px * var(--pu, 1))); } }

@keyframes pa-fade       { 0%, 100% { opacity: .15; } 40%, 70% { opacity: 1; } }
@keyframes pa-bob        { 0%, 100% { transform: none; } 50% { transform: translateY(calc(-2px * var(--pu, 1))); } }
@keyframes pa-rise       { 0% { transform: translateY(calc(1px * var(--pu, 1))); opacity: 0; } 30% { opacity: 1; }
                           100% { transform: translateY(calc(-4px * var(--pu, 1))); opacity: 0; } }
@keyframes pa-fall       { 0% { transform: translateY(calc(-2px * var(--pu, 1))); opacity: 0; } 30% { opacity: 1; }
                           100% { transform: translateY(calc(3px * var(--pu, 1))); opacity: 0; } }
@keyframes pa-drop       { 0% { transform: translateY(calc(-5px * var(--pu, 1))); opacity: 0; } 20% { opacity: 1; }
                           70% { transform: translateY(calc(3px * var(--pu, 1))); opacity: 1; } 100% { transform: translateY(calc(4px * var(--pu, 1))); opacity: 0; } }
@keyframes pa-spin       { to { transform: rotate(360deg); } }
@keyframes pa-spin-rev   { to { transform: rotate(-360deg); } }
@keyframes pa-swing      { 0%, 75%, 100% { transform: none; } 15% { transform: rotate(12deg); } 30% { transform: rotate(-10deg); }
                           45% { transform: rotate(6deg); } 60% { transform: rotate(-3deg); } }
@keyframes pa-jiggle     { 0%, 75%, 100% { transform: none; } 15%, 45% { transform: translateX(calc(1.5px * var(--pu, 1))); }
                           30%, 60% { transform: translateX(calc(-1.5px * var(--pu, 1))); } }
@keyframes pa-switch     { 0%, 35%, 100% { transform: none; } 50%, 85% { transform: translateX(calc(10px * var(--pu, 1))); } }
@keyframes pa-wave       { 0%, 60%, 100% { transform: none; } 12%, 36% { transform: rotate(14deg); } 24% { transform: rotate(-6deg); } 48% { transform: rotate(-3deg); } }
@keyframes pa-sway       { 0%, 100% { transform: rotate(-4deg); } 50% { transform: rotate(4deg); } }
@keyframes pa-flutter    { 0%, 100% { transform: none; } 50% { transform: skewY(-6deg) scaleX(.94); } }
@keyframes pa-pulse      { 0%, 100% { transform: scale(.7); opacity: .4; } 40% { transform: scale(1.15); opacity: 1; } }
@keyframes pa-ping       { 0% { transform: scale(.6); opacity: 1; } 100% { transform: scale(1.6); opacity: 0; } }
@keyframes pa-draw-loop  { 0% { stroke-dashoffset: 1; } 45%, 65% { stroke-dashoffset: 0; } 100% { stroke-dashoffset: -1; } }
@keyframes pa-dash-flow  { to { stroke-dashoffset: -.24; } }
@keyframes pa-grow       { 0%, 100% { transform: scaleY(.35); } 50% { transform: none; } }
@keyframes pa-slide-up   { 0% { transform: translateY(calc(3px * var(--pu, 1))); opacity: 0; } 25%, 75% { opacity: 1; }
                           100% { transform: translateY(calc(-3px * var(--pu, 1))); opacity: 0; } }
@keyframes pa-slide-down { 0% { transform: translateY(calc(-3px * var(--pu, 1))); opacity: 0; } 25%, 75% { opacity: 1; }
                           100% { transform: translateY(calc(3px * var(--pu, 1))); opacity: 0; } }
@keyframes pa-blink      { 0%, 44%, 56%, 100% { transform: none; } 50% { transform: scaleY(.1); } }
@keyframes pa-flicker    { 0%, 100% { transform: none; } 25% { transform: scale(.92, 1.08); } 50% { transform: scale(1.05, .94); } 75% { transform: scale(.96, 1.05); } }
@keyframes pa-twinkle    { 0%, 100% { transform: scale(.6); opacity: .35; } 50% { transform: scale(1.1); opacity: 1; } }
@keyframes pa-lift       { 0%, 25%, 100% { transform: none; } 45%, 80% { transform: translateY(calc(-2.5px * var(--pu, 1))); } }
@keyframes pa-orbit      { 0%, 100% { transform: translate(calc(1.5px * var(--pu, 1)), 0); } 25% { transform: translate(0, calc(1.5px * var(--pu, 1))); }
                           50% { transform: translate(calc(-1.5px * var(--pu, 1)), 0); } 75% { transform: translate(0, calc(-1.5px * var(--pu, 1))); } }
@keyframes pa-squash     { 0%, 100% { transform: none; } 50% { transform: scaleX(.08); } }
@keyframes pa-fly        { 0%, 100% { transform: none; opacity: 1; } 40% { transform: translate(calc(4px * var(--pu, 1)), calc(-4px * var(--pu, 1))); opacity: 0; }
                           41% { transform: translate(calc(-4px * var(--pu, 1)), calc(4px * var(--pu, 1))); opacity: 0; } 75% { transform: none; opacity: 1; } }
@keyframes pa-pop        { 0%, 100% { transform: scale(0); } 18% { transform: scale(1.25); } 28%, 82% { transform: none; } }

@media (prefers-reduced-motion: reduce) {
  .ci, .ci * { animation: none !important; stroke-dashoffset: 0 !important; }
}
[data-motion="reduce"] .ci, [data-motion="reduce"] .ci * { animation: none !important; stroke-dashoffset: 0 !important; }
