/* ─────────────────────────────────────────────────────────────────────────
   navigator.css — Kurus, the free-roaming navigator. All classes .knav-*.
   Opaline pearl body (tint #cdd9f5, glow #aebfe8, deep #2a3a66), PINK eyes,
   two slow counter-rotating "rings". Extends the companion.css glass pearl at
   navigator scale. Three nested wrappers (.knav-orb-spring > .knav-orb-idle >
   .knav-orb) so the JS spring transform, the CSS idle-drift transform, and the
   CSS breathe transform never fight.

   z-index 199: above the splash (120), and ONE BELOW the legacy z-index:200
   layer so any 200 element reliably paints over Kurus regardless of DOM-append
   order. The real same-/higher-z elements are:
     • #history-overlay  (openHistory, 01-main.js) — full-screen modal, z 200
     • #share-overlay    (openShare,   01-main.js) — full-screen modal, z 200
     • .ui-tooltip       — z 200, pointer-events:none + transient
     • .ui-modal 300, .ui-toast-region 400
   Kurus sits at 199 so the two legacy 200 modals cover it; .knav-hidden still
   display:none's the root. (Earlier audits wrongly claimed .ui-tooltip was the
   only 200 overlap — the two legacy modals are real, interactive 200 layers.)
   ───────────────────────────────────────────────────────────────────────── */

#kurus-nav {
  position: fixed;
  inset: 0;
  pointer-events: none;       /* overlay never eats clicks… */
  z-index: 199;               /* one below legacy 200 modals (see header) */
}
#kurus-nav.knav-hidden { display: none; }

/* ── the spring wrapper: JS writes translate() here every frame ───────────── */
.knav-orb-spring {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--knav-size, 64px);
  height: var(--knav-size, 64px);
  /* No permanent will-change: the spring SLEEPS at rest, so pinning a layer here
     wastes a compositor layer while idle. Hint only while actually moving. */
}
.knav-orb-spring.knav-is-moving { will-change: transform; }

/* ── the idle-drift wrapper: two incommensurate sine keyframes ────────────── */
.knav-orb-idle {
  position: absolute;
  inset: 0;
  animation:
    knav-drift-x var(--knav-drift-x, 7.3s) ease-in-out infinite,
    knav-drift-y var(--knav-drift-y, 5.1s) ease-in-out infinite;
}
/* while the spring is moving, kill the drift amplitude so transforms don't fight */
.knav-orb-idle.knav-is-moving { animation: none; transform: none; }

/* 0%/100% are the NEUTRAL (translate 0) phase so re-enabling drift after a move
   (when .knav-is-moving is removed and the keyframes restart at 0%) introduces no
   positional jump — the orb resumes from where the spring left it. The +/- drift
   extremes live at 25%/75%. */
@keyframes knav-drift-x {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(calc(var(--knav-drift, 6px) * -1)); }
  75%      { transform: translateX(var(--knav-drift, 6px)); }
}
@keyframes knav-drift-y {
  0%, 100% { transform: translateY(0); }
  25%      { transform: translateY(var(--knav-drift, 6px)); }
  75%      { transform: translateY(calc(var(--knav-drift, 6px) * -1)); }
}

/* ── the pearl orb itself (breathe + body + eyes + rings) ──────────────────── */
.knav-orb {
  position: absolute;
  inset: 0;
  width: var(--knav-size, 64px);
  height: var(--knav-size, 64px);
  pointer-events: auto;       /* …but the orb itself is interactive (hover, ×) */
  cursor: default;
  animation: knav-breathe 3.2s ease-in-out infinite;
}

/* opaline glow halo */
.knav-orb .knav-glow {
  position: absolute; inset: -34%; border-radius: 50%; z-index: 0;
  background: radial-gradient(circle at 50% 46%,
    rgba(174, 191, 232, .42), rgba(174, 191, 232, .12) 48%, transparent 72%);
  filter: blur(8px);
}
/* pearl body — tint→glow→deep radial, glassy inset highlights */
.knav-orb .knav-body {
  position: absolute; inset: 0; border-radius: 50%; z-index: 1;
  background: radial-gradient(circle at 38% 30%,
    #f3f7ff 0%, #cdd9f5 22%, #aebfe8 58%, #2a3a66 100%);
  box-shadow:
    inset 0 -4px 10px rgba(42, 58, 102, .55),
    inset 0 3px 7px rgba(255, 255, 255, .6),
    0 3px 12px rgba(42, 58, 102, .38);
}
/* specular rim */
.knav-orb .knav-rim {
  position: absolute; left: 16%; top: 7%; width: 46%; height: 20%;
  border-radius: 50%; z-index: 3;
  background: linear-gradient(180deg, rgba(255,255,255,.88), rgba(255,255,255,0));
  filter: blur(1px); transform: rotate(-12deg);
}

/* ── rings: two thin concentric border rings, slow counter-rotate ─────────── */
.knav-orb .knav-rings {
  position: absolute; inset: 0; z-index: 2; pointer-events: none;
  opacity: .35;
}
.knav-orb .knav-ring {
  position: absolute; border-radius: 50%;
  border: 1px solid rgba(205, 217, 245, .7);
}
.knav-orb .knav-ring-a {
  inset: -10%;
  border-color: rgba(174, 191, 232, .8);
  animation: knav-spin 18s linear infinite;
}
.knav-orb .knav-ring-b {
  inset: -20%;
  border-color: rgba(205, 217, 245, .55);
  animation: knav-spin 26s linear infinite reverse;
}

/* ── PINK eyes (deadpan resting), moods mirror companion.css naming ───────── */
.knav-orb .knav-eyes {
  position: absolute; left: 0; right: 0; top: 40%; z-index: 4;
  display: flex; justify-content: center; gap: 10px;
}
.knav-orb .knav-eye {
  width: 5px; height: 11px; border-radius: 999px;
  background: rgba(255, 100, 160, .9); filter: blur(.4px);
  transform: scaleY(.42);     /* deadpan resting */
  animation: knav-blink 3.6s ease-in-out infinite;
}
/* moods (default = deadpan) */
.knav-orb[data-mood="sly"] .knav-eye { animation: none; transform: scaleY(.42) rotate(-9deg); }
.knav-orb[data-mood="sly"] .knav-eye:last-child { transform: scaleY(.72) rotate(-9deg); }
.knav-orb[data-mood="side"] .knav-eye { animation: none; transform: translateX(2px) scaleY(.42); }
.knav-orb[data-mood="surprised"] .knav-eye { animation: none; transform: scaleY(1); }

@keyframes knav-breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.045); } }
@keyframes knav-blink   { 0%, 90%, 100% { transform: scaleY(.42); } 94% { transform: scaleY(.1); } }
@keyframes knav-spin    { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }

/* ── dismiss × on the orb (interactive) ───────────────────────────────────── */
.knav-dismiss {
  position: absolute; top: -6px; right: -6px; z-index: 6;
  width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid rgba(42, 58, 102, .4);
  background: rgba(20, 24, 36, .85); color: #cdd9f5;
  font-size: 13px; line-height: 1; cursor: pointer; pointer-events: auto;
  display: flex; align-items: center; justify-content: center;
  opacity: 0; transition: opacity .16s ease;
}
.knav-orb:hover .knav-dismiss, .knav-dismiss:focus-visible { opacity: 1; }
/* Touch devices have no hover, so the × would be invisible/untappable. Reveal it
   and enlarge the hit area toward the ~44px touch-target recommendation. */
@media (hover: none) {
  .knav-dismiss { opacity: 1; padding: 12px; top: -14px; right: -14px; }
}

/* ── speech bubble (fixed-position, flips side/vertical to avoid clipping) ─── */
.knav-bubble {
  position: fixed;
  /* anchored relative to the orb's rest corner by default (bottom-right). The
     JS adds .knav-bubble-left/-right/-below; we position via those classes. */
  right: calc((1 - .85) * 100vw + var(--knav-size, 64px) / 2 + 12px);
  bottom: calc((1 - .82) * 100vh + var(--knav-size, 64px) / 2);
  max-width: min(260px, 70vw);
  background: var(--panel2, #1b1f29); color: var(--ink, #e7ecf3);
  border: 1px solid rgba(174, 191, 232, .25);
  border-radius: 14px; padding: 11px 30px 11px 14px;
  font-size: 14px; line-height: 1.5;
  pointer-events: auto;
  opacity: 0; transform: translateY(4px);
  transition: opacity var(--knav-fade, 220ms) ease, transform var(--knav-fade, 220ms) ease;
  visibility: hidden;
}
.knav-bubble.knav-bubble-show { opacity: 1; transform: translateY(0); visibility: visible; }

/* horizontal flips */
.knav-bubble.knav-bubble-left  { right: calc((1 - .85) * 100vw + var(--knav-size, 64px) / 2 + 12px); left: auto; }
.knav-bubble.knav-bubble-right { left: calc(.85 * 100vw + var(--knav-size, 64px) / 2 + 12px); right: auto; }
/* vertical flip */
.knav-bubble.knav-bubble-below { bottom: auto; top: calc(.82 * 100vh + var(--knav-size, 64px) / 2 + 12px); }

.knav-bubble .knav-dismiss-x {
  position: absolute; top: 6px; right: 8px;
  width: 18px; height: 18px; padding: 0;
  border: none; background: transparent; color: var(--ink2, #aab3c0);
  font-size: 16px; line-height: 1; cursor: pointer; pointer-events: auto;
}
.knav-bubble .knav-dismiss-x:hover { color: var(--ink, #e7ecf3); }

/* ── STEP-3 STUBS: spotlight + pointer (defined, mounted, unused in Step 2) ── */
.knav-spotlight {
  position: fixed; pointer-events: none; z-index: 1;
  border-radius: 50%; display: none;
  box-shadow: 0 0 0 9999px rgba(8, 11, 18, .55);
}
.knav-spotlight-ring {
  position: fixed; pointer-events: none; z-index: 2;
  border-radius: 50%; display: none;
  border: 2px solid rgba(174, 191, 232, .8);
}
.knav-pointer {
  position: fixed; pointer-events: none; z-index: 5;
  display: none; width: 0; height: 0;
  transition: transform var(--knav-pointer-anim, 400ms) ease;
}

/* ── REDUCED-MOTION / FALLBACK overrides (kept at the bottom) ──────────────── */
/* Kurus stays present + functional: no spring (JS snaps), no breathe/drift/ring
   animation, bubbles use opacity-only fade. */
@media (prefers-reduced-motion: reduce) {
  .knav-orb,
  .knav-orb-idle,
  .knav-orb .knav-eye,
  .knav-orb .knav-ring-a,
  .knav-orb .knav-ring-b { animation: none !important; }
  .knav-orb-idle { transform: none !important; }
  .knav-orb .knav-eye { transform: scaleY(.42); }
  .knav-bubble { transition: opacity var(--knav-fade, 220ms) ease; transform: none; }
  .knav-bubble.knav-bubble-show { transform: none; }
}
/* explicit class form (set by initNavigator) — same overrides, no media query */
.knav-reduced .knav-orb,
.knav-reduced .knav-orb-idle,
.knav-reduced .knav-orb .knav-eye,
.knav-reduced .knav-orb .knav-ring-a,
.knav-reduced .knav-orb .knav-ring-b { animation: none !important; }
.knav-reduced .knav-orb-idle { transform: none !important; }
.knav-reduced .knav-orb .knav-eye { transform: scaleY(.42); }
.knav-reduced .knav-bubble { transition: opacity var(--knav-fade, 220ms) ease; transform: none; }
.knav-reduced .knav-bubble.knav-bubble-show { transform: none; }
