﻿/* ─────────────────────────────────────────────────────────────
   Creature — "橘子"，一隻住在這個網站裡的橘貓。
   This file describes how the SVG cat looks in each state.
   creature.js drives state via classes on .creature; everything
   else (tail sway, blink, Z float, walk gait) is pure CSS so the
   compositor handles it without JS frame work.
   ───────────────────────────────────────────────────────────── */

.creature-wrap {
  position: fixed;
  left: 0; top: 0;
  z-index: var(--z-pet);
  pointer-events: none;
  /* the cat moves the wrap with translate3d, NOT with left/top */
  transform: translate3d(var(--cat-x, calc(100vw - 200px)), var(--cat-y, calc(100dvh - 220px)), 0);
  transition: transform var(--cat-walk-dur, 0ms) var(--ease-smooth);
  will-change: transform;
}
.creature-wrap > * { pointer-events: auto; }

.creature {
  --eye-open: 1;
  --look-x: 0px;
  --look-y: 0px;
  --tilt: 0deg;
  --flip: 1;          /* -1 to face left when walking left */

  width: 160px;
  height: 160px;
  position: relative;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  filter: drop-shadow(0 16px 32px #ff7a0044);
  transform: scaleX(var(--flip));
  transition: transform var(--d-base) var(--ease-spring);
}
.creature:active { cursor: grabbing; }
.creature.dragging { transition: none !important; }

.creature svg { width: 100%; height: 100%; overflow: visible; }

/* ── Pose visibility — only the active body group shows ───── */
.creature .cat__body { display: none; }
.creature.is-sit   .cat__body--sit   { display: inline; }
.creature.is-loaf  .cat__body--loaf  { display: inline; }
.creature.is-sleep .cat__body--sleep { display: inline; }
.creature.is-walk  .cat__body--sit   { display: inline; }   /* walk reuses sit body */
.creature.is-stretch .cat__body--sit { display: inline; }
.creature.is-groom .cat__body--sit   { display: inline; }
.creature.is-yawn  .cat__body--sit   { display: inline; }

/* ── Head — gaze + idle bob ───────────────────────────────── */
.cat__head {
  transform: translate(var(--look-x), var(--look-y)) rotate(var(--tilt));
  transition: transform var(--d-base) var(--ease-spring);
}
.creature.is-sit  .cat__head { animation: catHeadBob 4.6s var(--ease-smooth) infinite; }
.creature.is-loaf .cat__head { animation: catHeadBob 6.2s var(--ease-smooth) infinite; }
@keyframes catHeadBob {
  0%, 100% { transform: translate(var(--look-x), var(--look-y)) rotate(var(--tilt)); }
  50%      { transform: translate(var(--look-x), calc(var(--look-y) - 2px)) rotate(var(--tilt)); }
}
.creature.is-walk .cat__head {
  animation: catHeadStep 0.42s steps(2) infinite;
}
@keyframes catHeadStep {
  0%, 100% { transform: translate(0, 0) rotate(-2deg); }
  50%      { transform: translate(0, -1px) rotate(2deg); }
}

/* ── Eyes — open / blink / shut ───────────────────────────── */
.cat__eye {
  transform: scaleY(var(--eye-open));
  transform-origin: center;
  transform-box: fill-box;
  transition: transform 110ms var(--ease-smooth);
}
.cat__pupil {
  transform: translate(var(--look-x), var(--look-y));
  transition: transform var(--d-base) var(--ease-spring);
  transform-box: fill-box;
}
.cat__eye-shut { opacity: 0; transition: opacity var(--d-base); }
.creature.is-sleep .cat__eye, .creature.is-loaf .cat__eye { opacity: 0.05; }
.creature.is-sleep .cat__eye-shut, .creature.is-loaf .cat__eye-shut { opacity: 1; }

/* ── Tail — independent sway, faster while walking ───────── */
.cat__tail {
  transform-origin: 70px 175px;
  animation: tailSway 3.8s ease-in-out infinite;
  will-change: transform;
}
@keyframes tailSway {
  0%, 100% { transform: rotate(-4deg); }
  50%      { transform: rotate(8deg); }
}
.creature.is-walk  .cat__tail { animation-duration: 0.7s; }
.creature.is-sleep .cat__tail { animation: none; transform: rotate(40deg) translate(20px, -10px); transition: transform var(--d-slow); }
.creature.is-loaf  .cat__tail { animation: none; transform: rotate(20deg); }

/* ── Z's — only float in sleep ────────────────────────────── */
.cat__zzz { opacity: 0; transition: opacity var(--d-base); }
.creature.is-sleep .cat__zzz { opacity: 1; animation: zzzFloat 3.2s ease-in-out infinite; }
@keyframes zzzFloat {
  0%   { transform: translate(0, 0); opacity: 0; }
  20%  { opacity: 0.9; }
  100% { transform: translate(8px, -16px); opacity: 0; }
}

/* ── Stretch — body elongates briefly ─────────────────────── */
.creature.is-stretch .cat__body--sit {
  transform: scaleX(1.15) scaleY(0.92);
  transform-origin: 50% 100%;
  transition: transform 600ms var(--ease-back);
}
.creature.is-stretch .cat__paws--front {
  transform: translate(0, 8px) scaleX(1.1);
  transform-origin: 50% 100%;
  transition: transform 600ms var(--ease-back);
}
.creature.is-stretch .cat__head {
  transform: translate(0, -6px) rotate(-4deg);
  transition: transform 600ms var(--ease-back);
}

/* ── Groom — tongue flicks; head leans down ───────────────── */
.creature.is-groom .cat__tongue { animation: tongueFlick 1.2s ease-in-out infinite; }
@keyframes tongueFlick {
  0%, 100% { opacity: 0; transform: translateY(0); }
  20%, 80% { opacity: 0.95; }
  50%      { opacity: 1; transform: translateY(2px); }
}
.creature.is-groom .cat__head {
  animation: groomLean 1.4s ease-in-out infinite;
}
@keyframes groomLean {
  0%, 100% { transform: rotate(-4deg) translateY(2px); }
  50%      { transform: rotate(6deg) translateY(8px); }
}

/* ── Yawn — mouth opens, eyes squint ──────────────────────── */
.creature.is-yawn .cat__yawn  { opacity: 1; transform: scaleY(1.2); transition: opacity 200ms, transform 400ms; }
.creature.is-yawn .cat__mouth { opacity: 0; transition: opacity 200ms; }
.creature.is-yawn .cat__eye   { opacity: 0.3; }

/* ── Walk — paw bobs (cheap pseudo-gait) ──────────────────── */
.creature.is-walk .cat__paws--front {
  animation: pawStep 0.42s steps(2) infinite;
}
@keyframes pawStep {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
.creature.is-walk .cat__shadow {
  animation: shadowStep 0.42s ease-in-out infinite;
}
@keyframes shadowStep {
  0%, 100% { transform: scaleX(1); opacity: 0.3; }
  50%      { transform: scaleX(0.85); opacity: 0.18; }
}

/* ── Speech bubble — same as before ───────────────────────── */
.speech {
  position: absolute;
  bottom: calc(100% + 2px);
  right: 0;
  max-width: 240px;
  padding: 10px 14px;
  background: var(--glass-bg-hi);
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-lg);
  font-size: var(--text-sm); color: var(--fg-strong);
  line-height: 1.5;
  box-shadow: var(--sh-2);
  transform: translateY(8px) scale(0.94) scaleX(var(--flip));
  opacity: 0;
  transition: transform var(--d-base) var(--ease-back), opacity var(--d-base);
  pointer-events: none;
  white-space: pre-wrap;
}
.speech.show { transform: translateY(0) scale(1) scaleX(var(--flip)); opacity: 1; }
.speech::after {
  content: "";
  position: absolute;
  right: 28px; bottom: -7px;
  width: 14px; height: 14px;
  background: var(--glass-bg-hi);
  border-right: 1px solid var(--glass-border);
  border-bottom: 1px solid var(--glass-border);
  transform: rotate(45deg);
}

/* ── Mobile size ──────────────────────────────────────────── */
@media (max-width: 720px) {
  .creature { width: 110px; height: 110px; }
  .speech   { max-width: 180px; font-size: var(--text-xs); }
}

/* ── Performance downshift hooks (consume body classes from perf.js) */
body.bare .cat__tail        { animation: none !important; }
body.bare .cat__zzz         { animation: none !important; }
body.bare .creature .cat__head { animation: none !important; }
body.bare .creature         { filter: none !important; }
body.hidden-tab .cat__tail,
body.hidden-tab .cat__zzz,
body.hidden-tab .cat__head  { animation-play-state: paused !important; }
