/* ============================================================
   Pip — an original character. A small glass pebble-creature
   with a ring welded to its shoulder where the tether thread passes through.
   Every state here is driven by app state (getMascotState);
   Pip never invents a mood.
   ============================================================ */

.pip {
  --px: 0px; /* pupil drift, set from JS */
  --py: 0px;
  position: relative;
  display: inline-block;
  line-height: 0;
  -webkit-tap-highlight-color: transparent;
}
.pip svg { display: block; overflow: visible; }

/* ---------- shared part styling ---------- */
.pip .pip-body {
  stroke: rgba(255, 255, 255, 0.34);
  stroke-width: 1.2;
}
.pip .pip-body-hi {
  fill: none;
  stroke: rgba(255, 255, 255, 0.5);
  stroke-width: 1.4;
  stroke-linecap: round;
  opacity: 0.7;
}
.pip .pip-feet { fill: rgba(168, 190, 232, 0.45); stroke: rgba(255,255,255,0.18); stroke-width: 1; }
.pip .pip-clip { fill: none; stroke: #a9b6d2; stroke-width: 2.4; stroke-linecap: round; }
.pip .pip-ring {
  fill: rgba(10, 14, 24, 0.25);
  stroke: #c3cfe8;
  stroke-width: 2.6;
  transition: stroke var(--t-med) var(--ease-out);
}
.pip .pip-thread {
  fill: none;
  stroke: rgba(195, 207, 232, 0.5);
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-dasharray: 0.5 4.5;
}
.pip .pip-eye-open { fill: #11141f; transition: transform 120ms var(--ease-out); transform-box: fill-box; transform-origin: center; }
.pip .pip-glint { fill: rgba(255,255,255,0.9); pointer-events: none; }
.pip .pip-eye-happy, .pip .pip-eye-closed {
  fill: none; stroke: #11141f; stroke-width: 2.4; stroke-linecap: round;
  opacity: 0;
}
.pip .pip-mouth { fill: none; stroke: #11141f; stroke-width: 2; stroke-linecap: round; }
.pip .pip-mouth--flat, .pip .pip-mouth--wobble { opacity: 0; }
.pip .pip-blush { fill: var(--st-needs); opacity: 0; transition: opacity var(--t-med); }
.pip .pip-spark { fill: #ffe9b8; opacity: 0; transform-box: fill-box; transform-origin: center; }


/* group transforms */
.pip .pip-tilt { transform-box: fill-box; transform-origin: 50% 78%; transition: transform var(--t-med) var(--ease-spring); }
.pip .pip-track { transform: translate(var(--px), var(--py)); }
.pip .pip-clip-g { transform-box: fill-box; transform-origin: 4% 85%; transition: transform var(--t-med) var(--ease-spring); }

/* blinking (JS toggles .is-blinking for ~160ms) */
.pip.is-blinking .pip-eye-open { transform: scaleY(0.1); }

/* ---------- idle: low-frequency breath ---------- */
.pip[data-state="idle"] .pip-tilt { animation: pipBreathe 3.8s ease-in-out infinite; }
@keyframes pipBreathe {
  0%, 100% { transform: scaleY(1) scaleX(1); }
  50%      { transform: scaleY(1.022) scaleX(0.996); }
}

/* ---------- notice: one-shot tilt, ring lifts, eyes wide ---------- */
.pip[data-state="notice"] .pip-tilt { animation: pipNotice 900ms var(--ease-spring) 1; }
.pip[data-state="notice"] .pip-eye-open { transform: scale(1.12); }
.pip[data-state="notice"] .pip-clip-g { transform: rotate(-7deg); }
.pip[data-state="notice"] .pip-ring { stroke: var(--st-notice); }
@keyframes pipNotice {
  0% { transform: rotate(0deg); }
  35% { transform: rotate(-6deg); }
  70% { transform: rotate(2.5deg); }
  100% { transform: rotate(0deg); }
}

/* ---------- thinking: restrained sway, ring bobs ---------- */
.pip[data-state="thinking"] .pip-tilt { animation: pipSway 2.7s ease-in-out infinite; }
.pip[data-state="thinking"] .pip-ring { stroke: var(--st-thinking); animation: pipRingBob 2.7s ease-in-out infinite; }
.pip[data-state="thinking"] .pip-clip-g { animation: pipClipLag 2.7s ease-in-out infinite; }
@keyframes pipSway {
  0%, 100% { transform: rotate(-2deg); }
  50% { transform: rotate(2deg); }
}
@keyframes pipRingBob {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-1.6px); }
}
@keyframes pipClipLag {
  0%, 100% { transform: rotate(1.6deg); }
  50% { transform: rotate(-1.6deg); }
}

/* ---------- needs_you: warm lean, pulsing ring, blush ---------- */
.pip[data-state="needs_you"] .pip-tilt { animation: pipLean 2.2s ease-in-out infinite; }
.pip[data-state="needs_you"] .pip-ring {
  stroke: var(--st-needs);
  animation: pipRingPulse 2.2s var(--ease-out) infinite;
}
.pip[data-state="needs_you"] .pip-blush { opacity: 0.35; }
.pip[data-state="needs_you"] .pip-halo {
  opacity: 1;
  animation: pipHalo 2.2s var(--ease-out) infinite;
}
@keyframes pipLean {
  0%, 100% { transform: rotate(2.4deg) translateX(1.5px); }
  50% { transform: rotate(3.6deg) translateX(2.4px); }
}
@keyframes pipRingPulse {
  0%, 100% { stroke-width: 2.6; }
  50% { stroke-width: 3.6; }
}
@keyframes pipHalo {
  0% { transform: scale(0.7); opacity: 0.65; }
  70% { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* ---------- success_soft: one hop, happy eyes, two sparks ---------- */
.pip[data-state="success_soft"] .pip-tilt { animation: pipHop 1.1s var(--ease-spring) 1; }
.pip[data-state="success_soft"] .pip-eye-open { opacity: 0; }
.pip[data-state="success_soft"] .pip-glint { opacity: 0; }
.pip[data-state="success_soft"] .pip-eye-happy { opacity: 1; }
.pip[data-state="success_soft"] .pip-blush { opacity: 0.28; }
.pip[data-state="success_soft"] .pip-spark { animation: pipSpark 1.1s var(--ease-out) 1; }
.pip[data-state="success_soft"] .pip-spark.s2 { animation-delay: 120ms; }
@keyframes pipHop {
  0% { transform: translateY(0) scaleY(1); }
  30% { transform: translateY(-9px) scaleY(1.04); }
  55% { transform: translateY(0) scaleY(0.95); }
  75% { transform: translateY(-2.5px) scaleY(1.01); }
  100% { transform: translateY(0) scaleY(1); }
}
@keyframes pipSpark {
  0% { transform: scale(0) rotate(0deg); opacity: 0; }
  35% { transform: scale(1) rotate(20deg); opacity: 1; }
  100% { transform: scale(0.2) rotate(45deg); opacity: 0; }
}

/* ---------- uncertain: tilt, one eye lowered, thread droops ---------- */
.pip[data-state="uncertain"] .pip-tilt { transform: rotate(-5deg); }
.pip[data-state="uncertain"] .pip-eye-r .pip-eye-open { transform: translateY(-1.8px) scaleY(0.86); }
.pip[data-state="uncertain"] .pip-clip-g { transform: rotate(14deg); }
.pip[data-state="uncertain"] .pip-ring { stroke: var(--st-uncertain); }
.pip[data-state="uncertain"] .pip-mouth--smile { opacity: 0; }
.pip[data-state="uncertain"] .pip-mouth--wobble { opacity: 1; }

/* ---------- sleep: settle, closed eyes, deep slow breath ---------- */
.pip[data-state="sleep"] .pip-tilt { animation: pipSleep 5.6s ease-in-out infinite; }
.pip[data-state="sleep"] .pip-eye-open, .pip[data-state="sleep"] .pip-glint { opacity: 0; }
.pip[data-state="sleep"] .pip-eye-closed { opacity: 1; }
.pip[data-state="sleep"] .pip-clip-g { transform: rotate(24deg); }
.pip[data-state="sleep"] .pip-ring { stroke: var(--st-sleep); }
.pip[data-state="sleep"] .pip-mouth--smile { opacity: 0; }
.pip[data-state="sleep"] .pip-mouth--flat { opacity: 1; }
@keyframes pipSleep {
  0%, 100% { transform: scaleY(0.95) translateY(2.5px); }
  50% { transform: scaleY(0.972) translateY(1px); }
}

/* ---------- reduced motion / user "still" preference ---------- */
.pip.pip--still .pip-tilt,
.pip.pip--still .pip-ring,
.pip.pip--still .pip-halo,
.pip.pip--still .pip-spark,
.pip.pip--still .pip-clip-g {
  animation: none !important;
}
.pip.pip--still { --px: 0px !important; --py: 0px !important; }

.pip-halo {
  fill: none;
  stroke: var(--st-needs);
  stroke-width: 1.6;
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
  pointer-events: none;
}

/* tap acknowledgement (JS adds .is-tapped briefly) */
.pip.is-tapped .pip-tilt { animation: pipTap 380ms var(--ease-spring) 1 !important; }
@keyframes pipTap {
  0% { transform: scaleY(1); }
  40% { transform: scaleY(0.9) scaleX(1.05); }
  100% { transform: scaleY(1) scaleX(1); }
}

/* ---------- one-shot transitions (JS-triggered, state-derived) ---------- */
/* arrive: Pip swings in along its thread and flashes the ring */
.pip.pip-tx-arrive .pip-tilt { animation: pipArrive 900ms var(--ease-spring) 1; }
.pip.pip-tx-arrive .pip-ring { animation: pipRingFlash 900ms var(--ease-out) 1; }
@keyframes pipArrive {
  0% { transform: translate(-26px, 18px) rotate(-14deg); opacity: 0; }
  55% { transform: translate(3px, -3px) rotate(3deg); opacity: 1; }
  100% { transform: none; opacity: 1; }
}
@keyframes pipRingFlash {
  0%, 60% { stroke-width: 2.6; }
  35% { stroke-width: 5; }
}

/* recover: after a dropped connection / reload, Pip reels the line
   back — the shoulder ring sweeps up from its droop, one careful tug */
.pip.pip-tx-recover .pip-clip-g { animation: pipReel 1.1s var(--ease-spring) 1; }
.pip.pip-tx-recover .pip-tilt { animation: pipTug 1.1s var(--ease-spring) 1; }
@keyframes pipReel {
  0% { transform: rotate(26deg); }
  45% { transform: rotate(-8deg); }
  100% { transform: none; }
}
@keyframes pipTug {
  0%, 100% { transform: none; }
  40% { transform: translateX(-3px) rotate(-3deg); }
  70% { transform: translateX(1.5px) rotate(1.5deg); }
}

/* ---------- curious: wide eyes, eager lean toward the work ---------- */
.pip[data-state="curious"] .pip-tilt { animation: pipLeanCurious 3.2s ease-in-out infinite; }
.pip[data-state="curious"] .pip-eye-open { transform: scale(1.14); }
.pip[data-state="curious"] .pip-ring { stroke: var(--st-thinking); animation: pipRingBob 2.7s ease-in-out infinite; }
.pip[data-state="curious"] .pip-clip-g { animation: pipClipLag 2.7s ease-in-out infinite; }
@keyframes pipLeanCurious {
  0%, 100% { transform: rotate(-2.2deg) translateX(-1px); }
  50%      { transform: rotate(1.8deg) translateX(1px); }
}

/* ---------- annoyed: half-lidded, flat mouth, thread droops ---------- */
.pip[data-state="annoyed"] .pip-tilt { animation: pipExhale 4.6s ease-in-out infinite; }
.pip[data-state="annoyed"] .pip-eye-open { transform: scaleY(0.55) translateY(1.5px); }
.pip[data-state="annoyed"] .pip-mouth--smile { opacity: 0; }
.pip[data-state="annoyed"] .pip-mouth--flat { opacity: 1; }
.pip[data-state="annoyed"] .pip-ring { stroke: var(--st-uncertain); }
.pip[data-state="annoyed"] .pip-clip-g { transform: rotate(18deg); }
@keyframes pipExhale {
  0%, 100% { transform: scaleY(1); }
  50%      { transform: scaleY(0.985) translateY(1px); }
}

/* ---------- angry: narrowed eyes, frown, red ring, tense tremble ---------- */
.pip[data-state="angry"] .pip-tilt { animation: pipTremble 480ms linear infinite; }
.pip[data-state="angry"] .pip-eye-open { transform: scaleY(0.45) translateY(2px); }
.pip[data-state="angry"] .pip-mouth--smile { opacity: 0; }
.pip[data-state="angry"] .pip-mouth--frown { opacity: 1; }
.pip[data-state="angry"] .pip-ring { stroke: var(--st-danger); animation: pipRingPulse 1.4s var(--ease-out) infinite; }
.pip[data-state="angry"] .pip-clip-g { transform: rotate(-10deg); }
@keyframes pipTremble {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-0.7px) rotate(-0.6deg); }
  75%      { transform: translateX(0.7px) rotate(0.6deg); }
}

/* ---------- nudge: one-shot come-forward when a run needs attention ---------- */
.pip.pip-tx-nudge .pip-tilt { animation: pipNudge 700ms var(--ease-spring) 1; }
.pip.pip-tx-nudge .pip-ring { animation: pipRingFlash 700ms var(--ease-out) 1; }
@keyframes pipNudge {
  0%   { transform: scale(1); }
  35%  { transform: scale(1.12) translateY(-5px); }
  70%  { transform: scale(0.98) translateY(1px); }
  100% { transform: none; }
}

/* ---------- state aura: the whole body carries the state color
   (idea adopted from the lantern variety candidate: at island-pill
   size a colored glow reads state faster than the small ring) ---------- */
.pip .pip-aura { opacity: 0.1; transition: fill var(--t-med) var(--ease-out), opacity var(--t-med); }
.pip[data-state="idle"] .pip-aura { fill: var(--st-idle); }
.pip[data-state="notice"] .pip-aura { fill: var(--st-notice); }
.pip[data-state="thinking"] .pip-aura,
.pip[data-state="curious"] .pip-aura { fill: var(--st-thinking); }
.pip[data-state="needs_you"] .pip-aura { fill: var(--st-needs); opacity: 0.16; }
.pip[data-state="success_soft"] .pip-aura { fill: var(--st-success); opacity: 0.14; }
.pip[data-state="uncertain"] .pip-aura,
.pip[data-state="annoyed"] .pip-aura { fill: var(--st-uncertain); opacity: 0.14; }
.pip[data-state="angry"] .pip-aura { fill: var(--st-danger); opacity: 0.16; }
.pip[data-state="sleep"] .pip-aura { fill: var(--st-sleep); opacity: 0.08; }

/* ---------- glance: one-shot notice of a nearby (simulated) event ---------- */
.pip.pip-tx-glance .pip-tilt { animation: pipGlance 620ms var(--ease-spring) 1; }
@keyframes pipGlance {
  0%   { transform: none; }
  30%  { transform: rotate(4deg) translateX(2px); }
  65%  { transform: rotate(-1.5deg); }
  100% { transform: none; }
}
