/* Walk-cycle animation.
 *
 * DOM hierarchy emitted by the assembler:
 *   <g class="character">       <- bob (transform: translate)
 *     <g class="lean">          <- static forward rotation, pivot near leg tips
 *       part-shadows, arms, legs, body (+ finish), eyes, mouth
 *
 * The two legs use the same side-view gait and are offset by half a cycle.
 * They are not mirrored: these characters face right, so both knees bend
 * forward in the walk direction.
 */

.character-svg {
  width: 200px;
  height: 220px;
  display: block;
  overflow: visible;
}

/* A contour keyed to the body's OWN colour — the same hue, 18% darker. On a
 * saturated pill it vanishes into the fill; on a white or cream one it becomes
 * the edge that stops the character dissolving into a light background.
 * `paint-order: stroke fill` paints the stroke first so the fill covers its
 * inner half, keeping the silhouette exactly the size it was drawn. */
.body-shape > path {
  stroke: color-mix(in srgb, var(--body-color) 82%, #1C1A18);
  stroke-width: 2.5;
  paint-order: stroke fill;
}

.character {
  animation: bodyMotion var(--walk-duration) ease-in-out infinite;
  transform-origin: 100px 110px;
  transform-box: view-box;
}

.lean {
  transform: rotate(var(--forward-lean));
  transform-origin: 100px 200px;
  transform-box: view-box;
}

.arm, .leg, .knee {
  transform-origin: 0 0;
  transform-box: view-box;
}

/* Hip: one anatomical side-view cycle; the second leg is half a step out of phase. */
.leg-L,
.leg-R {
  animation: hipWalk var(--walk-duration) linear infinite;
}

.leg-L .knee,
.leg-R .knee {
  animation: kneeWalk var(--walk-duration) ease-in-out infinite;
}

.leg-R,
.leg-R .knee {
  animation-delay: calc(var(--walk-duration) / -2);
}

.arm-L {
  animation: swingArmFwd var(--walk-duration) ease-in-out infinite;
  animation-delay: calc(-1 * (var(--walk-duration) - var(--arm-lag)));
}
.arm-R {
  animation: swingArmBack var(--walk-duration) ease-in-out infinite;
  animation-delay: calc(-1 * (var(--walk-duration) - var(--arm-lag)));
}

/* Body: vertical bob (2x walk-cycle freq) + optional lateral sway. */
@keyframes bodyMotion {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(var(--sway-amount),            calc(-1 * var(--bob-amount))); }
  50%  { transform: translate(0, 0); }
  75%  { transform: translate(calc(-1 * var(--sway-amount)), calc(-1 * var(--bob-amount))); }
  100% { transform: translate(0, 0); }
}

@keyframes hipWalk {
  0%, 100% { transform: rotate(var(--leg-swing)); }
  50%      { transform: rotate(calc(-1 * var(--leg-swing))); }
}

/* Positive SVG rotation swings the leg tip to screen-left. For a character
 * walking to the right, the leg bends while it swings left-to-right, then
 * stays straighter while the planted leg travels right-to-left.
 */
@keyframes kneeWalk {
  0%   { transform: rotate(20deg); }
  25%  { transform: rotate(var(--knee-bend-max)); }
  50%  { transform: rotate(8deg); }
  75%  { transform: rotate(5deg); }
  100% { transform: rotate(20deg); }
}

@keyframes swingArmFwd {
  0%, 100% { transform: rotate(calc(-1 * var(--arm-swing))); }
  50%      { transform: rotate(var(--arm-swing)); }
}
@keyframes swingArmBack {
  0%, 100% { transform: rotate(var(--arm-swing)); }
  50%      { transform: rotate(calc(-1 * var(--arm-swing))); }
}

/* Pills that are standing around rather than walking somewhere. */
.is-idle .character { animation-duration: calc(var(--walk-duration) * 2.4); }
.is-idle .leg-L, .is-idle .leg-R,
.is-idle .leg-L .knee, .is-idle .leg-R .knee { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .character, .leg-L, .leg-R,
  .leg-L .knee, .leg-R .knee,
  .arm-L, .arm-R {
    animation: none !important;
  }
}
