/* ==========================================================================
   KODI CHASE SCENE — Campfire Moon Bear (Kodi) chases Deer across screen
   ========================================================================== */

/* ── Outer scene container — positioned at bottom, fixed ────────────────── */
.patrol-scene {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 0;              /* zero-height strip on the bottom edge: sprites sit on its baseline */
  z-index: 980;
  pointer-events: none;
  user-select: none;
}

/* Deer peeks in from a screen edge. The wrapper is a zero-size anchor on the
   edge; .dp-body rotates about its base (--rot) and slides along its own axis. */
/* ==========================================================================
   NODI THE DEER — Corner Peeking Mascot
   Peeks only in the 3 corners where Kodi is NOT located:
   1. Bottom-Right (peeks up from bottom)
   2. Top-Right (peeks left from right edge)
   3. Top-Left (peeks right from left edge)
   (Kodi is in Bottom-Left)
   ========================================================================== */

/* ==========================================================================
   NODI THE DEER — Side-View Corner Peeking Mascot
   Peeks only from LEFT and RIGHT edges of the screen (side profile views)
   ========================================================================== */

.deer-corner-peek {
  position: fixed;
  z-index: 1001;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
  /* larger container to show proper deer side profile */
  width: 140px;
  height: 160px;
}

.deer-corner-peek.is-peeking {
  opacity: 1;
  pointer-events: auto;
}

.dp-body {
  width: 100%;
  height: 100%;
  cursor: pointer;
  filter: drop-shadow(0 10px 28px rgba(0,0,0,0.65));
  transform-origin: center center;
}

.dp-body svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}

.dp-eyes {
  transform-box: fill-box;
  transform-origin: center;
}

.dp-ear-l {
  transform-box: view-box;
  transform-origin: 18px 38px;
}

.dp-ear-r {
  transform-box: view-box;
  transform-origin: 60px 36px;
}

/* ── 2 SIDE CORNER ANCHORS ──────────────────────────────────────────────── */

/* RIGHT edge — Nodi slides in from the right */
.deer-corner-peek-top-right {
  top: 50%;
  right: -44px;
  transform: translateY(-50%);
  width: 112px;
  height: 107px;
}
.deer-corner-peek-top-right .dp-body {
  transform: translateX(115%);
}
.deer-corner-peek-top-right.is-peeking .dp-body {
  animation: nodi-peek-side-right 5s cubic-bezier(0.22, 1.2, 0.36, 1) forwards;
}

/* LEFT edge — Nodi slides in from the left */
.deer-corner-peek-top-left {
  top: 50%;
  left: -44px;
  transform: translateY(-50%);
  width: 112px;
  height: 107px;
}
.deer-corner-peek-top-left .dp-body {
  transform: translateX(-115%);
}
.deer-corner-peek-top-left.is-peeking .dp-body {
  animation: nodi-peek-side-left 5s cubic-bezier(0.22, 1.2, 0.36, 1) forwards;
}

/* ── KEYFRAME ANIMATIONS — smooth slide in with lively bounce ──────────── */

@keyframes nodi-peek-side-right {
  0%   { transform: translateX(115%); }
  /* Slide in with strong overshoot — the classic cartoon pull */
  18%  { transform: translateX(-18px) scaleX(0.92) scaleY(1.05); }
  26%  { transform: translateX(6px) scaleX(1.04) scaleY(0.97); }
  34%  { transform: translateX(-4px) scaleX(0.98) scaleY(1.01); }
  42%  { transform: translateX(0) scaleX(1) scaleY(1); }
  /* Idle wiggle — alive and curious */
  52%  { transform: translateX(0) rotate(1.5deg); }
  60%  { transform: translateX(-3px) rotate(-2deg); }
  68%  { transform: translateX(0) rotate(1deg); }
  76%  { transform: translateX(-2px) rotate(0deg); }
  84%  { transform: translateX(0); }
  /* Smooth slide back out */
  92%  { transform: translateX(30px) scaleX(0.9); }
  100% { transform: translateX(115%); }
}

@keyframes nodi-peek-side-left {
  0%   { transform: translateX(-115%); }
  18%  { transform: translateX(18px) scaleX(0.92) scaleY(1.05); }
  26%  { transform: translateX(-6px) scaleX(1.04) scaleY(0.97); }
  34%  { transform: translateX(4px) scaleX(0.98) scaleY(1.01); }
  42%  { transform: translateX(0) scaleX(1) scaleY(1); }
  52%  { transform: translateX(0) rotate(-1.5deg); }
  60%  { transform: translateX(3px) rotate(2deg); }
  68%  { transform: translateX(0) rotate(-1deg); }
  76%  { transform: translateX(2px) rotate(0deg); }
  84%  { transform: translateX(0); }
  92%  { transform: translateX(-30px) scaleX(0.9); }
  100% { transform: translateX(-115%); }
}

/* Blinks — expressive eye animations */
.is-peeking .dp-eyes {
  animation: deer-corner-blink 5s ease-in-out forwards;
}

.is-peeking .dp-ear-l {
  animation: dp-ear-flick-l 5s ease-in-out forwards;
}

.is-peeking .dp-ear-r {
  animation: dp-ear-flick-r 5s ease-in-out forwards;
}

@keyframes deer-corner-blink {
  0%, 30%, 42%, 65%, 76%, 100% { transform: scaleY(1); }
  36%                           { transform: scaleY(0.08); }
  70%                           { transform: scaleY(0.08); }
}

@keyframes dp-ear-flick-l {
  0%, 20%, 100% { transform: rotate(0deg); }
  26%           { transform: rotate(-18deg); }
  32%           { transform: rotate(6deg); }
  38%           { transform: rotate(0deg); }
  58%           { transform: rotate(-14deg); }
  64%           { transform: rotate(0deg); }
}

@keyframes dp-ear-flick-r {
  0%, 38%, 100% { transform: rotate(0deg); }
  44%           { transform: rotate(18deg); }
  50%           { transform: rotate(-6deg); }
  56%           { transform: rotate(0deg); }
  70%           { transform: rotate(12deg); }
  76%           { transform: rotate(0deg); }
}

.dp-look {
  animation: dp-look 4.5s ease-in-out infinite;
}

@keyframes dp-look {
  0%, 20%, 100% { transform: translateX(0); }
  28%, 46%      { transform: translateX(-2px); }
  54%, 72%      { transform: translateX(2px); }
  80%           { transform: translateX(0); }
}

.dp-nose {
  transform-box: fill-box;
  transform-origin: center;
}

.is-peeking .dp-nose {
  animation: dp-nose 5s ease-in-out forwards;
}

@keyframes dp-nose {
  0%, 44%, 100% { transform: scale(1); }
  48%           { transform: scale(1.18, 0.84); }
  52%           { transform: scale(1); }
  88%           { transform: scale(1.12, 0.9); }
  92%           { transform: scale(1); }
}

/* Head sways gently while Nodi is peeking */
.dp-head {
  transform-box: view-box;
}
.dp-head { transform-origin: 42px 75px; }
.is-peeking .dp-head { animation: dp-head 5s ease-in-out forwards; }

@keyframes dp-head {
  0%, 40%  { transform: rotate(0deg); }
  50%      { transform: rotate(-4deg); }
  62%      { transform: rotate(3deg); }
  74%      { transform: rotate(-3deg); }
  86%, 100% { transform: rotate(0deg); }
}

/* ── NAME TAG & SPEECH BUBBLES ─────────────────────────────────────────── */
.dp-tag,
.dp-bubble {
  position: absolute;
  pointer-events: none;
}

.dp-tag {
  opacity: 0;
  background: rgba(14, 23, 42, 0.94);
  border: 1px solid rgba(255, 206, 107, 0.5);
  color: #ffce6b;
  font: 700 8.5px "DM Mono", monospace;
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  transition: opacity 0.25s ease;
  z-index: 1003;
}

.is-peeking .dp-tag {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}

/* Tag positioning for side views */
.deer-corner-peek-top-right .dp-tag {
  bottom: 6px;
  right: calc(100% + 10px);
  white-space: nowrap;
}
.deer-corner-peek-top-left .dp-tag {
  bottom: 6px;
  left: calc(100% + 10px);
  white-space: nowrap;
}

.dp-tag:hover {
  background: #ffce6b;
  color: #1a0f0a;
  border-color: #ffce6b;
  transform: scale(1.05);
}

.dp-bubble {
  background: rgba(14, 23, 42, 0.96);
  border: 1px solid rgba(255, 206, 107, 0.7);
  color: #f4f7ff;
  font: 9.5px "DM Mono", monospace;
  padding: 8px 14px;
  border-radius: 12px;
  white-space: nowrap;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.65), 0 0 18px rgba(255, 206, 107, 0.22);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
  z-index: 1004;
}

.dp-bubble::after {
  content: '';
  position: absolute;
  border-width: 6px;
  border-style: solid;
}

/* Bubble positioning for side views */
.deer-corner-peek-top-right .dp-bubble {
  top: 20px;
  right: calc(100% + 14px);
  transform: translateX(8px) scale(0.92);
}
.deer-corner-peek-top-right .dp-bubble::after {
  top: 16px;
  left: 100%;
  border-color: transparent transparent transparent rgba(255, 206, 107, 0.7);
}

.deer-corner-peek-top-left .dp-bubble {
  top: 20px;
  left: calc(100% + 14px);
  transform: translateX(-8px) scale(0.92);
}
.deer-corner-peek-top-left .dp-bubble::after {
  top: 16px;
  right: 100%;
  border-color: transparent rgba(255, 206, 107, 0.7) transparent transparent;
}

.dp-bubble.visible {
  opacity: 1;
  transform: translate(0, 0) scale(1) !important;
}

/* ── TAP REACTION: HAPPY BOUNCE ─────────────────────────────────────────── */
.deer-corner-peek.is-popping .dp-body {
  animation: nodi-pop-bounce 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
}

@keyframes nodi-pop-bounce {
  0%   { transform: translateX(0) scale(1); }
  25%  { transform: translateX(-12px) scale(1.14, 0.88); }
  55%  { transform: translateX(4px) scale(0.96, 1.05); }
  80%  { transform: translateX(-2px) scale(1.02, 0.99); }
  100% { transform: translateX(0) scale(1); }
}

.dp-heart {
  position: absolute;
  left: 50%;
  bottom: 50px;
  font-size: 14px;
  pointer-events: none;
  animation: dp-heart-float 1.4s ease-out forwards;
}

@keyframes dp-heart-float {
  0%   { opacity: 0; transform: translate(calc(-50% + var(--hx, 0px)), 0px) scale(0.5); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--hx, 0px)), -60px) scale(1.3); }
}

/* ── Sprites: placed on the ground line and moved with translate3d ──────── */
.patrol-sprite {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 96px;
  height: 96px;
  pointer-events: none;
  will-change: transform;
  transform: translate3d(-200%, 0, 0);   /* parked off-screen until the first run */
}

/* Kodi is a little bigger than Nodi */
.patrol-kodi {
  width: 110px;
  height: 110px;
}

/* Facing lives on a plain wrapper, so it never fights the SVG animations */
.sprite-flip {
  width: 100%;
  height: 100%;
}

.patrol-scene.face-left .sprite-flip {
  transform: scaleX(-1);
}

.deer-svg,
.kodi-svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  filter: drop-shadow(0 4px 10px rgba(0,0,0,0.45));
}

/* Limbs, body bob, ears and tail are driven from JS (see initPatrolBear) so
   the stride stays in step with the actual running speed. */

/* ── Eye blink (each eye sets its own transform-origin inline) ───────────── */
.blink {
  transform-box: fill-box;
  transform-origin: center;
  animation: blink-eye 4.6s ease-in-out infinite;
}

@keyframes blink-eye {
  0%, 92%, 100% { transform: scaleY(1); }
  95%           { transform: scaleY(0.1); }
}

/* ── Kodi details ────────────────────────────────────────────────────────── */
.kodi-tongue {
  transform-box: fill-box;
  transform-origin: 50% 0;
  animation: tongue-flap 0.72s ease-in-out infinite;
}

@keyframes tongue-flap {
  0%, 100% { transform: scaleY(1); }
  45%      { transform: scaleY(1.35) translateY(1px); }
}

/* Marshmallow fire flicker (each flame sets its own transform-origin inline) */
.kodi-fire {
  animation: fire-flicker 0.4s ease-in-out infinite alternate;
}

@keyframes fire-flicker {
  0%   { transform: scale(1, 1);     opacity: 0.9; }
  50%  { transform: scale(0.8, 1.3); opacity: 1; }
  100% { transform: scale(1.2, 0.8); opacity: 0.75; }
}

.kodi-sweat {
  animation: sweat-drop 1.6s ease-in-out infinite;
}

@keyframes sweat-drop {
  0%, 70%, 100% { opacity: 0.8; transform: translateY(0); }
  80%           { opacity: 0.2; transform: translateY(6px); }
}

/* Click on Kodi: advanced acrobatic jump, fall, and 360° somersault roll stunt!
   Ground shadow stays flat on the floor, shrinking at apex and expanding on impact. */
.kodi-actor {
  transform-box: view-box;
  transform-origin: 65px 75px;
}

.patrol-kodi.hop .kodi-actor {
  animation: kodi-jump-roll 1.05s cubic-bezier(0.22, 0.7, 0.35, 1) forwards;
}

@keyframes kodi-jump-roll {
  0%   { transform: translateY(0) rotate(0deg) scale(1, 1); }
  10%  { transform: translateY(6px) rotate(10deg) scale(1.22, 0.78); }  /* Deep crouch preparation */
  22%  { transform: translateY(-48px) rotate(38deg) scale(0.86, 1.2); } /* PONG TAKEOFF into the air */
  36%  { transform: translateY(-75px) rotate(90deg) scale(0.96, 1.04); } /* Peak apex tumble float */
  48%  { transform: translateY(-30px) rotate(155deg) scale(1.08, 0.92); } /* Fast descent towards ground */
  58%  { transform: translateY(5px) rotate(215deg) scale(1.26, 0.74); } /* Ground slam impact squash! */
  68%  { transform: translateY(-4px) rotate(290deg) scale(0.92, 1.08); } /* Rolling 360 somersault across floor */
  78%  { transform: translateY(4px) rotate(360deg) scale(1.25, 0.78); } /* Landing on paws completing 360 roll */
  88%  { transform: translateY(-13px) rotate(360deg) scale(0.94, 1.06); } /* Spring rebound pop */
  95%  { transform: translateY(2px) rotate(360deg) scale(1.05, 0.95); } /* Settle into sprint */
  100% { transform: translateY(0) rotate(360deg) scale(1, 1); }
}

/* Click on Nodi: advanced graceful deer leap with flip and stick the landing */
.deer-actor {
  transform-box: view-box;
  transform-origin: 65px 75px;
}

.patrol-deer.hop .deer-actor {
  animation: deer-super-leap 0.85s cubic-bezier(0.2, 0.7, 0.35, 1) forwards;
}

@keyframes deer-super-leap {
  0%   { transform: translateY(0) rotate(0deg) scale(1, 1); }
  10%  { transform: translateY(5px) rotate(-4deg) scale(1.18, 0.82); }  /* Nimble crouch */
  30%  { transform: translateY(-65px) rotate(6deg) scale(0.86, 1.22); } /* PONG LEAP takeoff */
  48%  { transform: translateY(-88px) rotate(-2deg) scale(0.96, 1.04); } /* Graceful apex hover */
  62%  { transform: translateY(-45px) rotate(4deg) scale(1.04, 0.96); } /* Elegant descent */
  76%  { transform: translateY(4px) rotate(-2deg) scale(1.2, 0.82); }  /* Land squash with poise */
  88%  { transform: translateY(-14px) rotate(1deg) scale(0.96, 1.04); } /* Soft bounce recovery */
  95%  { transform: translateY(2px) rotate(0deg) scale(1.04, 0.96); }  /* Settle */
  100% { transform: translateY(0) rotate(0deg) scale(1, 1); }
}

.patrol-shadow {
  transform-box: fill-box;
  transform-origin: center;
}

.patrol-kodi.hop .patrol-shadow {
  animation: kodi-shadow-roll 1.05s cubic-bezier(0.22, 0.7, 0.35, 1) forwards;
}

@keyframes kodi-shadow-roll {
  0%   { transform: scale(1, 1); opacity: 0.35; }
  10%  { transform: scale(1.28, 1.25); opacity: 0.48; }  /* Deep crouch near ground */
  22%  { transform: scale(0.52, 0.52); opacity: 0.22; }  /* Rising high */
  36%  { transform: scale(0.25, 0.25); opacity: 0.12; }  /* Apex (-75px) */
  48%  { transform: scale(0.65, 0.65); opacity: 0.25; }  /* Falling down */
  58%  { transform: scale(1.38, 1.35); opacity: 0.52; }  /* Impact slam */
  68%  { transform: scale(1.1, 1.1); opacity: 0.4; }    /* Rolling */
  78%  { transform: scale(1.32, 1.3); opacity: 0.48; }   /* Paw touchdown */
  88%  { transform: scale(0.8, 0.8); opacity: 0.26; }    /* Rebound hop */
  100% { transform: scale(1, 1); opacity: 0.35; }
}

.patrol-deer.hop .patrol-shadow {
  animation: deer-shadow-leap 0.85s cubic-bezier(0.2, 0.7, 0.35, 1) forwards;
}

@keyframes deer-shadow-leap {
  0%   { transform: scale(1, 1); opacity: 0.3; }
  10%  { transform: scale(1.22, 1.2); opacity: 0.42; }  /* Crouch near ground */
  30%  { transform: scale(0.42, 0.42); opacity: 0.18; } /* Rising */
  48%  { transform: scale(0.22, 0.22); opacity: 0.1; }  /* Apex */
  62%  { transform: scale(0.55, 0.55); opacity: 0.2; }  /* Falling */
  76%  { transform: scale(1.3, 1.28); opacity: 0.46; }  /* Impact */
  88%  { transform: scale(0.75, 0.75); opacity: 0.22; } /* Bounce */
  100% { transform: scale(1, 1); opacity: 0.3; }
}

/* ── Click targets and speech bubbles ────────────────────────────────────── */
/* Bubbles sit outside the flip wrapper, so they're never mirrored */
.patrol-sprite {
  pointer-events: auto;
  cursor: pointer;
}

.pb-speech {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  margin-left: var(--shift, 0px);
  transform: translateX(-50%) translateY(8px) scale(0.88);
  background: rgba(8, 13, 30, 0.96);
  border: 1px solid rgba(161, 244, 194, 0.65);
  color: #e8f4fc;
  font: 9px "DM Mono", monospace;
  line-height: 1.45;
  text-align: center;
  padding: 6px 12px;
  border-radius: 12px;
  white-space: normal;
  width: max-content;
  max-width: min(220px, 65vw);
  box-shadow: 0 8px 24px rgba(0,0,0,0.7), 0 0 16px rgba(161,244,194,0.22);
  opacity: 0;
  transition: opacity 0.25s ease, transform 0.25s cubic-bezier(0.16,1,0.3,1);
  pointer-events: none;
  z-index: 990;
}

.pb-speech::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: rgba(161, 244, 194, 0.65);
}

#pbSpeechDeer {
  border-color: rgba(255, 206, 107, 0.7);
}

#pbSpeechDeer::after {
  border-top-color: rgba(255, 206, 107, 0.7);
}

/* Remove distracting name badges above runners to stop cluttering the screen */
.pb-tag {
  display: none !important;
}

/* While the chase is running, the other bottom-of-screen mascots step aside */
.corner-bear-container {
  transition: opacity 0.35s ease;
}

body.chase-active .corner-bear-container,
body.chase-active .deer-corner-peek {
  opacity: 0;
  pointer-events: none;
}

body.chase-active .deer-corner-peek * {
  pointer-events: none !important;
}

.pb-speech::after {
  content: '';
  position: absolute;
  top: 100%;
  left: calc(50% - var(--shift, 0px));
  transform: translateX(-50%);
  border: 5px solid transparent;
  border-top-color: rgba(161, 244, 194, 0.55);
}

.pb-speech.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
}

/* ── Footstep dust puffs (created by JS) ─────────────────────────────────── */
.dust-puff {
  position: fixed;
  bottom: 4px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: rgba(200, 190, 170, 0.35);
  pointer-events: none;
  z-index: 975;
  animation: dust-rise 0.7s ease-out forwards;
}

@keyframes dust-rise {
  0%   { transform: scale(0.5); opacity: 0.7; }
  60%  { transform: scale(2.5); opacity: 0.3; }
  100% { transform: scale(3.5); opacity: 0; }
}

/* ── Reduced motion: hide everything ────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  .patrol-scene,
  .deer-corner-peek,
  .sparkle-particle,
  .dust-puff { display: none !important; }
}

/* ── Mobile scale down ───────────────────────────────────────────────────── */
@media (max-width: 480px) {
  .patrol-sprite {
    width: 74px;
    height: 74px;
  }

  .patrol-kodi {
    width: 84px;
    height: 84px;
  }

  .dp-body {
    left: -35px;
    top: -98px;
    width: 70px;
    height: 98px;
  }

  .deer-corner-peek-bottom-left  { left: 164px; }
  .deer-corner-peek-bottom-right { right: 112px; }

  .dp-bubble {
    white-space: normal;
    max-width: 190px;
    font-size: 8.5px;
    padding: 6px 10px;
  }
}

/* ==========================================================================
   SPARKLE PARTICLES — floating upward from random positions
   ========================================================================== */
.sparkle-particle {
  position: fixed;
  pointer-events: none;
  z-index: 2;
  border-radius: 50%;
  animation: sparkle-float linear forwards;
}

@keyframes sparkle-float {
  0%   { opacity: 0;   transform: translateY(0) scale(0.4) rotate(0deg); }
  15%  { opacity: 1; }
  85%  { opacity: 0.5; }
  100% { opacity: 0;   transform: translateY(-130px) scale(1.4) rotate(200deg); }
}

/* ==========================================================================
   ENHANCED PAGE ANIMATIONS
   ========================================================================== */

/* ── Hero ambient pulse ──────────────────────────────────────────────────── */
.hero::before {
  content: '';
  position: absolute;
  top: 10%;
  left: 2%;
  width: 380px;
  height: 380px;
  background: radial-gradient(circle, rgba(161, 244, 194, 0.045) 0%, transparent 70%);
  border-radius: 50%;
  pointer-events: none;
  animation: hero-glow-pulse 7s ease-in-out infinite;
  z-index: 0;
}

@keyframes hero-glow-pulse {
  0%, 100% { opacity: 0.4; transform: scale(1); }
  50%       { opacity: 1;   transform: scale(1.22); }
}

/* ── Orbit rings subtle spin ─────────────────────────────────────────────── */
.orbit-1 { animation: orbit-slow 30s linear infinite; }
.orbit-2 { animation: orbit-slow 42s linear infinite reverse; }

@keyframes orbit-slow {
  from { transform: rotate(-27deg); }
  to   { transform: rotate(333deg); }
}

/* ── Skill / project card shimmer sweep ──────────────────────────────────── */
.skill-card, .project-card, .directory-card {
  position: relative;
  overflow: hidden;
}

.skill-card::after,
.project-card::after,
.directory-card::after {
  content: '';
  position: absolute;
  top: -60%;
  left: -80%;
  width: 45%;
  height: 200%;
  background: linear-gradient(105deg, transparent 25%, rgba(255,255,255,0.045) 50%, transparent 75%);
  transform: rotate(18deg);
  transition: left 0.55s ease;
  pointer-events: none;
}

.skill-card:hover::after,
.project-card:hover::after,
.directory-card:hover::after {
  left: 135%;
}

/* ── Stat card number pop on hover ───────────────────────────────────────── */
.stat-card:hover .counter {
  animation: stat-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
}

@keyframes stat-pop {
  0%   { transform: scale(1); }
  50%  { transform: scale(1.18); color: var(--green); }
  100% { transform: scale(1); }
}

/* ── Timeline dots pulse ─────────────────────────────────────────────────── */
.timeline-point {
  animation: tl-pulse 2.8s ease-in-out infinite;
}

@keyframes tl-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(161,244,194,0.45); }
  55%       { box-shadow: 0 0 0 7px rgba(161,244,194,0); }
}

/* ── Green pulse dot ring ────────────────────────────────────────────────── */
.pulse {
  animation: pulse-ring 2.4s ease-in-out infinite;
}

@keyframes pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(161,244,194,0.75); }
  50%       { box-shadow: 0 0 0 9px rgba(161,244,194,0); }
}

/* ── Primary button glow ─────────────────────────────────────────────────── */
.actions .button.primary {
  animation: btn-float 3.8s ease-in-out infinite;
}

@keyframes btn-float {
  0%, 100% { box-shadow: 0 4px 18px rgba(161,244,194,0.22); }
  50%       { box-shadow: 0 8px 36px rgba(161,244,194,0.48); }
}

/* ── Code window glow breathe ────────────────────────────────────────────── */
.code-window {
  animation: code-breathe 5.5s ease-in-out infinite;
}

@keyframes code-breathe {
  0%, 100% { box-shadow: 0 32px 100px rgba(0,0,0,0.4), 0 0 0 0 rgba(161,244,194,0.0); }
  50%       { box-shadow: 0 32px 100px rgba(0,0,0,0.4), 0 0 50px rgba(161,244,194,0.08); }
}

/* ── Quick badge hover ───────────────────────────────────────────────────── */
.quick-badge:hover {
  text-shadow: 0 0 14px rgba(161,244,194,0.55);
  transform: translateY(-2px);
}



/* ==========================================================================
   MASCOT SETTINGS — visibility switches
   ========================================================================== */
body.mascots-off .patrol-scene,
body.mascots-off .corner-bear-container,
body.mascots-off .deer-corner-peek,
body.mascots-off .sparkle-particle,
body.mascots-off .dust-puff,
body.no-kodi .corner-bear-container,
body.no-kodi #patrolKodi,
body.no-nodi .deer-corner-peek,
body.no-nodi #patrolDeer { display: none !important; }

/* ==========================================================================
   MASCOT SETTINGS — gear button + popup panel
   ========================================================================== */
.ms-gear {
  position: fixed;
  right: 26px;
  bottom: 86px;
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(175, 195, 233, 0.3);
  background: rgba(17, 27, 46, 0.85);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  color: var(--green);
  cursor: pointer;
  z-index: 1010;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.45);
  transition: transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1), border-color 0.2s, color 0.2s;
}
.ms-gear svg { width: 20px; height: 20px; transition: transform 0.6s cubic-bezier(0.34, 1.56, 0.64, 1); }
.ms-gear:hover, .ms-gear:focus-visible { border-color: rgba(161, 244, 194, 0.55); outline: none; }
.ms-gear:hover svg, .ms-gear[aria-expanded="true"] svg { transform: rotate(90deg); }
.ms-gear:active { transform: scale(0.92); }

.ms-panel {
  position: fixed;
  right: 26px;
  bottom: 140px;
  width: min(320px, calc(100vw - 32px));
  padding: 18px;
  border-radius: 14px;
  border: 1px solid rgba(175, 195, 233, 0.22);
  background: linear-gradient(145deg, rgba(19, 29, 50, 0.97), rgba(9, 15, 28, 0.97));
  box-shadow: 0 28px 80px rgba(0, 0, 0, 0.6);
  color: var(--text);
  z-index: 1011;
  opacity: 0;
  transform: translateY(10px) scale(0.97);
  transform-origin: bottom right;
  transition: opacity 0.2s ease, transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.ms-panel[hidden] { display: none; }
.ms-panel.open { opacity: 1; transform: none; }

.ms-head { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 14px; }
.ms-label { font: 9px var(--mono); letter-spacing: 0.11em; color: var(--green); }
.ms-head h3 { margin: 2px 0 0; font-size: 18px; letter-spacing: -0.04em; }
.ms-close {
  width: 28px; height: 28px; border-radius: 8px; border: 1px solid var(--line);
  background: transparent; color: #aab6cc; font-size: 18px; line-height: 1; cursor: pointer;
  transition: color 0.2s, border-color 0.2s;
}
.ms-close:hover { color: #fff; border-color: rgba(161, 244, 194, 0.4); }

.ms-section { padding: 12px 0; border-top: 1px solid var(--line); }
.ms-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ms-row + .ms-row { margin-top: 12px; }
.ms-text b { display: block; font-size: 12px; font-weight: 700; }
.ms-text small { display: block; font: 9px var(--mono); color: #8998b4; margin-top: 2px; }

.ms-switch {
  position: relative; flex: none; width: 38px; height: 22px; padding: 0; border-radius: 999px;
  border: 1px solid rgba(175, 195, 233, 0.28); background: rgba(255, 255, 255, 0.06); cursor: pointer;
  transition: background 0.2s, border-color 0.2s;
}
.ms-switch i {
  position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%;
  background: #9ba9c1; transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), background 0.2s;
}
.ms-switch[aria-checked="true"] { background: rgba(161, 244, 194, 0.2); border-color: rgba(161, 244, 194, 0.55); }
.ms-switch[aria-checked="true"] i { transform: translateX(16px); background: var(--green); }
.ms-switch:focus-visible, .ms-btn:focus-visible, .ms-chips button:focus-visible, .ms-close:focus-visible {
  outline: 2px solid var(--green); outline-offset: 2px;
}

.ms-readout { font: 700 11px var(--mono); color: var(--green); }
.ms-range {
  --fill: 50%;
  -webkit-appearance: none; appearance: none; width: 100%; height: 4px; margin: 14px 0 12px;
  border-radius: 999px; outline: none; cursor: pointer;
  background: linear-gradient(90deg, var(--green) var(--fill), rgba(255, 255, 255, 0.12) var(--fill));
}
.ms-range::-webkit-slider-thumb {
  -webkit-appearance: none; width: 16px; height: 16px; border-radius: 50%;
  background: #fff; border: 3px solid var(--green); box-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}
.ms-range::-moz-range-thumb {
  width: 12px; height: 12px; border-radius: 50%; background: #fff; border: 3px solid var(--green);
}
.ms-range:focus-visible { outline: 2px solid var(--green); outline-offset: 6px; }

.ms-chips { display: flex; gap: 6px; }
.ms-chips button {
  flex: 1; padding: 6px 0; border-radius: 6px; border: 1px solid var(--line); background: transparent;
  color: #b7c4dc; font: 9px var(--mono); cursor: pointer; transition: all 0.2s;
}
.ms-chips button:hover { border-color: rgba(161, 244, 194, 0.4); color: #fff; }
.ms-chips button.active { background: rgba(161, 244, 194, 0.14); border-color: rgba(161, 244, 194, 0.55); color: var(--green); }

.ms-panel.ms-anim-off .ms-speed { opacity: 0.4; pointer-events: none; }

.ms-foot { display: flex; gap: 8px; padding-top: 14px; border-top: 1px solid var(--line); }
.ms-btn {
  flex: 1; min-height: 34px; border-radius: 6px; border: 1px solid var(--line); background: transparent;
  color: #e8eefb; font: 700 10px var(--font); cursor: pointer; transition: all 0.2s;
}
.ms-btn:hover { border-color: rgba(161, 244, 194, 0.45); }
.ms-danger { color: #ff9cab; border-color: rgba(255, 136, 151, 0.3); }
.ms-danger:hover { background: rgba(255, 136, 151, 0.1); border-color: rgba(255, 136, 151, 0.6); }
.ms-danger.is-restore { color: #07140d; background: var(--green); border-color: var(--green); }

@media (max-width: 480px) {
  .ms-gear { right: 16px; bottom: 70px; width: 40px; height: 40px; }
  .ms-panel { right: 16px; bottom: 118px; }
}
@media (prefers-reduced-motion: reduce) {
  .ms-gear svg, .ms-panel, .ms-switch i { transition: none; }
}
