/* ============================================================
   AI Pet — artwork, expressions and the 12 action animations.

   Everything is driven by two attributes on the pet element:
     .pet[data-action="idle|blink|look|walk|sit|lie|sleep|wake|pat|wave|listen|talk"]
       -> posture (static transform) + motion (keyframes)
     .pet[data-expression="neutral|happy|curious|calm|sleepy|surprised|sad"]
       -> eyelids, brows, mouth

   Transient actions read their real length from --action-duration, which
   ActionPlayer sets from the authoritative durationMs.
   ============================================================ */

.pet {
  --pet-x: 0.5;
  position: relative;
  display: grid;
  place-items: center;
  width: clamp(184px, 30vw, 272px);
  aspect-ratio: 1;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  cursor: pointer;
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
  transform: translateX(calc((var(--pet-x) - 0.5) * 42px));
  transition: transform 900ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

.pet:focus {
  outline: none;
}

.pet:focus-visible {
  outline: 3px solid rgba(143, 122, 224, 0.7);
  outline-offset: 8px;
}

.pet-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform-origin: center;
  transition: transform 220ms cubic-bezier(0.2, 0.9, 0.3, 1);
}

.pet:hover .pet-svg {
  transform: scale(1.02);
}

.pet:active .pet-svg {
  transform: scale(0.985);
}

/* Pat acknowledgement ring. */
.pet-ripple {
  position: absolute;
  left: 50%;
  top: 64%;
  width: 116%;
  aspect-ratio: 1;
  translate: -50% -50%;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.92);
  box-shadow:
    inset 0 0 22px rgba(255, 255, 255, 0.5),
    0 0 0 1px rgba(219, 167, 141, 0.28);
  opacity: 0;
  pointer-events: none;
}

.pet.is-patted .pet-ripple {
  animation: pet-pat-ripple 760ms cubic-bezier(0.2, 0.7, 0.3, 1);
}

@keyframes pet-pat-ripple {
  0% {
    opacity: 0.9;
    transform: scale(0.42);
  }
  100% {
    opacity: 0;
    transform: scale(1.12);
  }
}

/* ------------------------------------------------------------ rig layers */

.pet-facing,
.pet-posture,
.pet-motion {
  transform-box: view-box;
  transform-origin: 120px 214px;
}

.pet-facing {
  transition: transform 320ms ease;
}

.pet[data-facing="left"] .pet-facing {
  transform: scaleX(-1);
}

.pet-posture {
  transition: transform 460ms cubic-bezier(0.22, 0.9, 0.28, 1.04);
}

.pet-shadow {
  transform-box: view-box;
  transform-origin: 120px 218px;
  transition: transform 460ms ease;
}

.pet-tail {
  transform-box: view-box;
  transform-origin: 162px 176px;
}

.pet-ear {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  transition: transform 420ms ease;
}

.pet-eye {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 200ms ease;
}

.pet-eye-open,
.pet-eye-shut {
  transition: opacity 140ms ease;
}

.pet-eye-shut {
  opacity: 0;
}

.pet-lid {
  transform-box: fill-box;
  transform-origin: 50% 0%;
  transform: scaleY(0);
  transition: transform 150ms ease;
}

.pet-brow {
  transform-box: fill-box;
  transform-origin: center;
  opacity: 0.45;
  transition:
    transform 240ms ease,
    opacity 240ms ease;
}

.pet-cheek {
  opacity: 0;
  transition: opacity 240ms ease;
}

.pet-arm {
  transform-box: view-box;
}

.pet-arm--left {
  transform-origin: 96px 198px;
}

.pet-arm--right {
  transform-origin: 144px 198px;
}

.pet-paw {
  transform-box: fill-box;
  transform-origin: center;
}

.pet-mouth {
  stroke: #8f5257;
  stroke-width: 3;
  stroke-linecap: round;
  fill: none;
  visibility: hidden;
}

.pet-mouth--happy,
.pet-mouth--curious,
.pet-mouth--surprised {
  stroke: none;
}

.pet-mouth-talk {
  transform-box: fill-box;
  transform-origin: 50% 25%;
  visibility: hidden;
  stroke: none;
}

/* --------------------------------------------------------- expressions */

.pet[data-expression="neutral"] .pet-mouth--neutral,
.pet[data-expression="happy"] .pet-mouth--happy,
.pet[data-expression="curious"] .pet-mouth--curious,
.pet[data-expression="calm"] .pet-mouth--calm,
.pet[data-expression="sleepy"] .pet-mouth--sleepy,
.pet[data-expression="surprised"] .pet-mouth--surprised,
.pet[data-expression="sad"] .pet-mouth--sad {
  visibility: visible;
}

.pet[data-expression="happy"] .pet-eye-open {
  opacity: 0;
}

.pet[data-expression="happy"] .pet-eye-shut {
  opacity: 1;
}

.pet[data-expression="happy"] .pet-cheek {
  opacity: 0.5;
}

.pet[data-expression="curious"] .pet-eye {
  transform: scale(1.07);
}

.pet[data-expression="curious"] .pet-brow {
  opacity: 0.85;
  transform: translateY(-2px);
}

.pet[data-expression="calm"] .pet-lid {
  transform: scaleY(0.46);
}

.pet[data-expression="calm"] .pet-brow {
  opacity: 0.3;
}

.pet[data-expression="calm"] .pet-cheek {
  opacity: 0.16;
}

.pet[data-expression="sleepy"] .pet-lid {
  transform: scaleY(0.86);
}

.pet[data-expression="sleepy"] .pet-brow {
  opacity: 0.35;
  transform: translateY(2px);
}

.pet[data-expression="surprised"] .pet-eye {
  transform: scale(1.12);
}

.pet[data-expression="surprised"] .pet-brow {
  opacity: 0.9;
  transform: translateY(-4px);
}

.pet[data-expression="sad"] .pet-lid {
  transform: scaleY(0.3);
}

.pet[data-expression="sad"] .pet-brow--left {
  transform: rotate(-13deg) translateY(1px);
}

.pet[data-expression="sad"] .pet-brow--right {
  transform: rotate(13deg) translateY(1px);
}

.pet[data-expression="sad"] .pet-cheek {
  opacity: 0.18;
}

/* --------------------------------------------------------- posture (static) */

.pet[data-action="sit"] .pet-posture {
  transform: scale(1.07, 0.88);
}

.pet[data-action="lie"] .pet-posture {
  transform: scale(1.2, 0.68);
}

.pet[data-action="sleep"] .pet-posture {
  transform: scale(1.24, 0.64);
}

.pet[data-action="lie"] .pet-shadow,
.pet[data-action="sleep"] .pet-shadow {
  transform: scaleX(1.14);
}

.pet[data-action="lie"] .pet-arm,
.pet[data-action="sleep"] .pet-arm {
  transition: transform 460ms ease;
  transform: translateY(-6px);
}

/* ============================================================ IDLE */
/* Slow breath + bob, tail sway, occasional ear twitch. */

.pet[data-action="idle"] .pet-motion {
  animation: pet-idle 4.4s ease-in-out infinite;
}

.pet[data-action="idle"] .pet-tail {
  animation: pet-tail-sway 6.4s ease-in-out infinite;
}

.pet[data-action="idle"] .pet-ear {
  animation: pet-ear-twitch 8.2s ease-in-out infinite;
}

.pet[data-action="idle"] .pet-ear--right {
  animation-delay: -2.6s;
}

@keyframes pet-idle {
  0%,
  100% {
    transform: translateY(0) scale(1, 1);
  }
  30% {
    transform: translateY(-3px) scale(0.994, 1.012);
  }
  62% {
    transform: translateY(0.5px) scale(1.009, 0.992);
  }
}

@keyframes pet-tail-sway {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(5deg);
  }
}

@keyframes pet-ear-twitch {
  0%,
  84%,
  100% {
    transform: rotate(0deg);
  }
  88% {
    transform: rotate(-7deg);
  }
  92% {
    transform: rotate(3deg);
  }
  96% {
    transform: rotate(0deg);
  }
}

/* =========================================================== BLINK */
/* A quick double-lid close, with a tiny head dip. */

.pet[data-action="blink"] .pet-lid {
  animation: pet-blink var(--action-duration, 180ms) ease-in-out;
}

.pet[data-action="blink"] .pet-motion {
  animation: pet-blink-dip var(--action-duration, 180ms) ease-in-out;
}

@keyframes pet-blink {
  0%,
  12%,
  100% {
    transform: scaleY(0);
  }
  46%,
  58% {
    transform: scaleY(1);
  }
}

@keyframes pet-blink-dip {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(1.6px) scale(1.004, 0.996);
  }
}

/* ============================================================ LOOK */
/* Head leads, eyes scan, then settle back to centre. */

.pet[data-action="look"] .pet-motion {
  animation: pet-look var(--action-duration, 900ms) cubic-bezier(0.3, 0.7, 0.3, 1) both;
}

.pet[data-action="look"] .pet-eye {
  animation: pet-eye-scan var(--action-duration, 900ms) ease-in-out both;
}

.pet[data-action="look"] .pet-tail {
  animation: pet-tail-sway 1.8s ease-in-out 1;
}

@keyframes pet-look {
  0%,
  8% {
    transform: rotate(0deg) translateX(0);
  }
  24%,
  46% {
    transform: rotate(-2.6deg) translateX(-5px);
  }
  62%,
  82% {
    transform: rotate(2.4deg) translateX(5px);
  }
  100% {
    transform: rotate(0deg) translateX(0);
  }
}

@keyframes pet-eye-scan {
  0%,
  6% {
    transform: translateX(0);
  }
  24%,
  46% {
    transform: translateX(-3.2px);
  }
  62%,
  82% {
    transform: translateX(3.2px);
  }
  100% {
    transform: translateX(0);
  }
}

/* ============================================================ WALK */
/* A happy trot in place: hop+bob, alternating paws, wagging tail. */

.pet[data-action="walk"] .pet-motion {
  animation: pet-walk 720ms ease-in-out infinite;
}

.pet[data-action="walk"] .pet-paw--left {
  animation: pet-paw-step 360ms ease-in-out infinite;
}

.pet[data-action="walk"] .pet-paw--right {
  animation: pet-paw-step 360ms ease-in-out infinite;
  animation-delay: -180ms;
}

.pet[data-action="walk"] .pet-tail {
  animation: pet-tail-wag 360ms ease-in-out infinite;
}

@keyframes pet-walk {
  0%,
  100% {
    transform: translateY(0) translateX(-6px) rotate(-1deg);
  }
  25% {
    transform: translateY(-7px) translateX(3px) rotate(0deg);
  }
  50% {
    transform: translateY(0) translateX(7px) rotate(1deg);
  }
  75% {
    transform: translateY(-7px) translateX(-3px) rotate(0deg);
  }
}

@keyframes pet-paw-step {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  50% {
    transform: translateY(-6px) rotate(-7deg);
  }
}

@keyframes pet-tail-wag {
  0%,
  100% {
    transform: rotate(-8deg);
  }
  50% {
    transform: rotate(9deg);
  }
}

/* ============================================================= SIT */
/* Settles onto its haunches and sways gently. */

.pet[data-action="sit"] .pet-motion {
  animation: pet-sit-breathe 3.8s ease-in-out infinite;
}

.pet[data-action="sit"] .pet-tail {
  animation: pet-tail-sway 5.2s ease-in-out infinite;
}

@keyframes pet-sit-breathe {
  0%,
  100% {
    transform: scale(1, 1) rotate(0deg);
  }
  50% {
    transform: scale(1.014, 0.984) rotate(0.7deg);
  }
}

/* ============================================================= LIE */
/* Flattens into a loaf, breathes slowly, tail curling. */

.pet[data-action="lie"] .pet-motion {
  animation: pet-lie-breathe 4.6s ease-in-out infinite;
}

.pet[data-action="lie"] .pet-tail {
  animation: pet-tail-sway 8s ease-in-out infinite;
}

@keyframes pet-lie-breathe {
  0%,
  100% {
    transform: scale(1, 1);
  }
  50% {
    transform: scale(1.016, 0.978);
  }
}

/* =========================================================== SLEEP */
/* Deep breathing, lids shut, Zzz drifting up. */

.pet[data-action="sleep"] .pet-motion {
  animation: pet-sleep-breathe 5.2s ease-in-out infinite;
}

.pet[data-action="sleep"] .pet-lid {
  transform: scaleY(1);
}

.pet[data-action="sleep"] .pet-tail {
  animation: pet-tail-sway 9s ease-in-out infinite;
}

@keyframes pet-sleep-breathe {
  0%,
  100% {
    transform: scale(1, 1);
  }
  50% {
    transform: scale(1.02, 0.974);
  }
}

/* ============================================================ WAKE */
/* A startle: squashed, then a stretch upward, then the eyes pop open. */

.pet[data-action="wake"] .pet-motion {
  animation: pet-wake var(--action-duration, 1200ms) cubic-bezier(0.22, 1.3, 0.36, 1) both;
}

.pet[data-action="wake"] .pet-lid {
  animation: pet-lid-pop var(--action-duration, 1200ms) ease-out both;
}

.pet[data-action="wake"] .pet-ear {
  animation: pet-ear-perk var(--action-duration, 1200ms) ease-out both;
}

@keyframes pet-wake {
  0% {
    transform: scale(1, 0.78) translateY(4px);
  }
  22% {
    transform: scale(0.94, 1.12) translateY(-12px);
  }
  42% {
    transform: scale(1.04, 0.96) translateY(0);
  }
  60% {
    transform: scale(0.99, 1.02) translateY(-3px) rotate(-1.5deg);
  }
  78% {
    transform: scale(1, 1) translateY(0) rotate(1.5deg);
  }
  100% {
    transform: scale(1, 1) translateY(0);
  }
}

@keyframes pet-lid-pop {
  0%,
  8% {
    transform: scaleY(1);
  }
  34%,
  100% {
    transform: scaleY(0);
  }
}

@keyframes pet-ear-perk {
  0% {
    transform: rotate(0deg);
  }
  30% {
    transform: rotate(-9deg);
  }
  60% {
    transform: rotate(4deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

/* ============================================================= PAT */
/* Squash-and-stretch happy wiggle. */

.pet[data-action="pat"] .pet-motion {
  animation: pet-pat var(--action-duration, 1100ms) ease-in-out both;
}

.pet[data-action="pat"] .pet-ear {
  animation: pet-ear-bounce var(--action-duration, 1100ms) ease-out both;
}

@keyframes pet-pat {
  0% {
    transform: scale(1, 1);
  }
  18% {
    transform: scale(1.07, 0.9);
  }
  34% {
    transform: scale(0.94, 1.07) translateY(-5px);
  }
  50% {
    transform: scale(1.04, 0.96);
  }
  66% {
    transform: scale(0.98, 1.02) rotate(-1.2deg);
  }
  84% {
    transform: scale(1, 1) rotate(1deg);
  }
  100% {
    transform: scale(1, 1);
  }
}

@keyframes pet-ear-bounce {
  0%,
  100% {
    transform: rotate(0deg);
  }
  18% {
    transform: rotate(-8deg);
  }
  40% {
    transform: rotate(6deg);
  }
  62% {
    transform: rotate(-4deg);
  }
}

/* ============================================================ WAVE */
/* Lean, raise the left paw, wag it, lower it. */

.pet[data-action="wave"] .pet-motion {
  animation: pet-wave-body var(--action-duration, 1400ms) ease-in-out both;
}

.pet[data-action="wave"] .pet-arm--left {
  animation: pet-arm-raise var(--action-duration, 1400ms) cubic-bezier(0.3, 0.9, 0.3, 1) both;
}

.pet[data-action="wave"] .pet-paw--left {
  animation: pet-paw-wave 380ms ease-in-out 0.25s 3;
}

.pet[data-action="wave"] .pet-tail {
  animation: pet-tail-wag 420ms ease-in-out infinite;
}

@keyframes pet-wave-body {
  0%,
  100% {
    transform: rotate(0deg) translateX(0);
  }
  20%,
  80% {
    transform: rotate(-2.5deg) translateX(-2px);
  }
}

@keyframes pet-arm-raise {
  0% {
    transform: translate(0, 0) rotate(0deg);
  }
  18%,
  82% {
    transform: translate(-3px, -44px) rotate(-8deg);
  }
  100% {
    transform: translate(0, 0) rotate(0deg);
  }
}

@keyframes pet-paw-wave {
  0%,
  100% {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(-26deg);
  }
}

/* ========================================================== LISTEN */
/* Alert posture: ears up, head tilts side to side, eyes wide. */

.pet[data-action="listen"] .pet-motion {
  animation: pet-listen 3.4s ease-in-out infinite;
}

.pet[data-action="listen"] .pet-ear {
  animation: pet-ear-listen 1.7s ease-in-out infinite;
}

.pet[data-action="listen"] .pet-eye {
  transform: scale(1.06);
}

.pet[data-action="listen"] .pet-tail {
  animation: pet-tail-sway 3.2s ease-in-out infinite;
}

@keyframes pet-listen {
  0%,
  100% {
    transform: rotate(0deg) translateY(0);
  }
  18%,
  42% {
    transform: rotate(-3deg) translateY(-2px);
  }
  58% {
    transform: rotate(0deg) translateY(0);
  }
  76% {
    transform: rotate(2.2deg) translateY(-1px);
  }
}

@keyframes pet-ear-listen {
  0%,
  100% {
    transform: rotate(0deg);
  }
  30% {
    transform: rotate(-7deg);
  }
  64% {
    transform: rotate(4deg);
  }
}

/* ============================================================ TALK */
/* Mouth flaps, body bobs, thought dots drift. */

.pet[data-action="talk"] .pet-motion {
  animation: pet-talk-bob 1.15s ease-in-out infinite;
}

.pet[data-action="talk"] .pet-mouths .pet-mouth:not(.pet-mouth-talk) {
  visibility: hidden;
}

.pet[data-action="talk"] .pet-mouth-talk {
  visibility: visible;
  animation: pet-talk-mouth 300ms ease-in-out infinite;
}

.pet[data-action="talk"] .pet-tail {
  animation: pet-tail-sway 2.4s ease-in-out infinite;
}

@keyframes pet-talk-bob {
  0%,
  100% {
    transform: translateY(0) rotate(0deg);
  }
  30% {
    transform: translateY(-2.5px) rotate(-0.8deg);
  }
  60% {
    transform: translateY(0) rotate(0.8deg);
  }
}

@keyframes pet-talk-mouth {
  0%,
  100% {
    transform: scaleY(0.25);
  }
  45% {
    transform: scaleY(1);
  }
  70% {
    transform: scaleY(0.55);
  }
}

/* ====================================================== effect layers */

.pet-fx {
  pointer-events: none;
}

.fx-hearts,
.fx-zzz,
.fx-sparks,
.fx-dots {
  display: none;
}

.fx-heart,
.fx-z,
.fx-spark,
.fx-dot {
  transform-box: fill-box;
  transform-origin: center;
}

/* --- pat: floating hearts --- */

.fx-heart--1 {
  --hx: 74px;
  --hy: 98px;
}

.fx-heart--2 {
  --hx: 168px;
  --hy: 106px;
  animation-delay: 110ms;
}

.fx-heart--3 {
  --hx: 122px;
  --hy: 64px;
  animation-delay: 60ms;
}

.pet[data-action="pat"] .fx-hearts,
.pet.is-patted .fx-hearts {
  display: block;
}

.pet[data-action="pat"] .fx-heart,
.pet.is-patted .fx-heart {
  opacity: 0;
  animation: pet-heart-rise 900ms cubic-bezier(0.2, 0.8, 0.3, 1) both;
}

@keyframes pet-heart-rise {
  0% {
    transform: translate(var(--hx), calc(var(--hy) + 10px)) scale(0.35);
    opacity: 0;
  }
  25% {
    opacity: 0.95;
  }
  100% {
    transform: translate(var(--hx), calc(var(--hy) - 24px)) scale(1.05);
    opacity: 0;
  }
}

/* --- sleep: drifting Zzz --- */

.fx-z--1 {
  --zx: 174px;
  --zy: 108px;
  --zs: 0.7;
}

.fx-z--2 {
  --zx: 192px;
  --zy: 84px;
  --zs: 0.92;
  animation-delay: 0.9s;
}

.fx-z--3 {
  --zx: 208px;
  --zy: 58px;
  --zs: 1.14;
  animation-delay: 1.8s;
}

.pet[data-action="sleep"] .fx-zzz {
  display: block;
}

.pet[data-action="sleep"] .fx-z {
  animation-name: pet-z-float;
  animation-duration: 2.8s;
  animation-timing-function: ease-in-out;
  animation-iteration-count: infinite;
  animation-fill-mode: backwards;
}

@keyframes pet-z-float {
  0% {
    transform: translate(var(--zx), var(--zy)) scale(var(--zs));
    opacity: 0;
  }
  25% {
    opacity: 0.9;
  }
  75% {
    opacity: 0.6;
  }
  100% {
    transform: translate(calc(var(--zx) + 8px), calc(var(--zy) - 18px)) scale(calc(var(--zs) * 1.12));
    opacity: 0;
  }
}

/* --- wake: spark burst --- */

.pet[data-action="wake"] .fx-sparks {
  display: block;
}

.pet[data-action="wake"] .fx-spark {
  stroke: #f7c65c;
  stroke-width: 4;
  stroke-linecap: round;
  opacity: 0;
  fill: none;
  animation: pet-spark 640ms ease-out 2 both;
}

.pet[data-action="wake"] .fx-spark--2,
.pet[data-action="wake"] .fx-spark--5 {
  animation-delay: 90ms;
}

.pet[data-action="wake"] .fx-spark--3,
.pet[data-action="wake"] .fx-spark--4 {
  animation-delay: 45ms;
}

@keyframes pet-spark {
  0% {
    opacity: 0;
    transform: scale(0.45);
  }
  40% {
    opacity: 1;
    transform: scale(1.05);
  }
  100% {
    opacity: 0;
    transform: scale(1.18);
  }
}

/* --- talk: thought dots --- */

.pet[data-action="talk"] .fx-dots {
  display: block;
}

.fx-dot {
  fill: #a697ef;
  opacity: 0;
}

.fx-dot--2 {
  animation-delay: 0.14s;
}

.fx-dot--3 {
  animation-delay: 0.28s;
}

.pet[data-action="talk"] .fx-dot {
  animation: pet-talk-dot 1.05s ease-in-out infinite;
}

@keyframes pet-talk-dot {
  0%,
  100% {
    opacity: 0.16;
    transform: translateY(0) scale(0.82);
  }
  40% {
    opacity: 1;
    transform: translateY(-3px) scale(1);
  }
}

/* ================================================= reduced motion */

@media (prefers-reduced-motion: reduce) {
  .pet-motion,
  .pet-tail,
  .pet-ear,
  .pet-paw,
  .pet-arm,
  .pet-lid,
  .pet-eye,
  .pet-mouth-talk,
  .fx-heart,
  .fx-z,
  .fx-spark,
  .fx-dot,
  .pet-ripple {
    animation: none !important;
  }

  .pet-svg,
  .pet,
  .pet-facing,
  .pet-posture,
  .pet-shadow {
    transition-duration: 0.001ms;
  }

  .fx-hearts,
  .fx-zzz,
  .fx-sparks,
  .fx-dots {
    display: none !important;
  }
}

/* ============================================================
   Character sprite layer (Ayane placeholder GIFs).

   The built-in SVG stays in the DOM as the guaranteed fallback. When an asset exists for
   the current action the SVG is hidden and the sprite layer is shown. Nothing here knows
   which character it is — the manifest decides.
   ============================================================ */

.pet-sprite-layer {
  position: absolute;
  inset: 0;
  display: none;
  z-index: 2;
  pointer-events: none;
  /* GIF canvases differ in size (445x444 vs 512x512); containing them in one box keeps the
     character at a consistent scale, and bottom alignment keeps her feet planted. */
  align-items: flex-end;
  justify-content: center;
}

.pet.pet--sprite .pet-sprite-layer {
  display: flex;
}

/* The SVG rabbit is the fallback: hidden only while a sprite is actually showing. */
.pet.pet--sprite .pet-svg {
  visibility: hidden;
}

/*
 * Placement is anchored to the CHARACTER, not to the canvas.
 *
 * These placeholder GIFs frame the character very differently: inside its canvas the
 * character occupies 59%-94% of the height and the lowest pixel sits anywhere from 2.9%
 * to 14.6% above the bottom. Aligning the canvas made her visibly hop and change size
 * when the action changed. The manifest now records each asset's content box, and these
 * rules pin that box to the stage floor and centre it on her body.
 *
 *   --sprite-scale    display scale for this asset
 *   --sprite-cbottom  (y + h) of the content box: where her feet are inside the canvas
 *   --sprite-ccx      (x + w / 2): where her body centre is inside the canvas
 */
.pet-sprite-layer img,
.pet-sprite-layer canvas {
  position: absolute;
  display: block;
  width: auto;
  height: calc(var(--sprite-scale, 1) * 100%);
  max-width: none;
  max-height: none;
  image-rendering: auto;
  transform-origin: bottom center;
  /* Feet on the floor: the element extends just far enough below the box that the
     content bottom lands exactly on the box bottom. */
  left: 50%;
  bottom: calc(-1 * (1 - var(--sprite-cbottom, 1)) * var(--sprite-scale, 1) * 100%);
  transform: translateX(calc(-50% - (var(--sprite-ccx, 0.5) - 0.5) * 100%));
}

/* Poses that are deliberately off the floor (being carried) are centred instead. */
.pet-sprite-layer [data-anchor='center'] {
  bottom: auto;
  top: 50%;
  transform: translate(-50%, -50%);
}

/* Client-only dragging feedback. Not a server action. */
.pet.is-picked-up {
  transform: translateY(-4px) scale(1.02);
  transition: transform 120ms ease;
}

.pet.is-picked-up .pet-sprite-layer img,
.pet.is-picked-up .pet-sprite-layer canvas {
  filter: drop-shadow(0 12px 14px rgba(58, 40, 48, 0.28));
}

/* ============================================================
   Business state cues for actions drawn with borrowed art.

   `listen` and `talk` have no art of their own, so they are DRAWN with idle art (see
   render.visualFallback). The business state is still distinct — data-action says
   listen/talk — so a light visual cue keeps it perceptible without inventing new art.
   ============================================================ */

/* Listening: a soft attention ring, as if she is waiting for you to speak. */
.pet[data-action='listen'] .pet-sprite-layer::after {
  content: '';
  position: absolute;
  inset: 8%;
  border-radius: 50%;
  border: 2px solid rgba(143, 122, 224, 0.35);
  animation: pet-listen-ring 2200ms ease-out infinite;
  pointer-events: none;
}

@keyframes pet-listen-ring {
  0% {
    transform: scale(0.86);
    opacity: 0.55;
  }
  70% {
    transform: scale(1.04);
    opacity: 0;
  }
  100% {
    transform: scale(1.04);
    opacity: 0;
  }
}

/* Talking: a barely-there bob, so she reads as speaking while idle art is on screen. */
.pet[data-action='talk'] .pet-sprite-layer {
  animation: pet-talk-bob 1400ms ease-in-out infinite;
}

@keyframes pet-talk-bob {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-2px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .pet[data-action='listen'] .pet-sprite-layer::after,
  .pet[data-action='talk'] .pet-sprite-layer {
    animation: none;
  }
}
