/* ============================================================================
   EHDarkMuse — ALYX AVATAR  (sprite-sheet presence, right panel)  v alyx-9
   Presence system per the AAA animation direction:
   · asymmetric breathing (per-cycle randomized via CSS vars set from JS)
   · per-emotion transition envelopes (fade duration is a var, not a constant)
   · attention layer (whole-figure micro-orientation, 1–3px, slow ease)
   · accent layer (micro-rotation ≤0.25°, sigh / thinking only)
   · expression blending (inactive face layer at partial opacity)
   Each wrapper owns exactly ONE transform so they compose cleanly:
     .alyx-attention → translate   .alyx-breathe → scaleY/translateY
     .alyx-accent → rotate         .alyx-container → filter only
   Principle: Alyx observes, never interrupts. Stillness is content.
   ============================================================================ */

.alyx-empty-host { padding: 14px 16px !important; gap: 8px !important; }
.alyx-dock {
  position: relative; width: 100%;
  flex: 1 1 auto;                 /* fill the panel when nothing is selected */
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 10px; padding: 14px 16px;
  user-select: none;
  transition: padding var(--dur-base,200ms) var(--ease,ease);
}
/* while a cell is selected: shrink to a compact presence at the top */
.alyx-dock.alyx-compact {
  flex: 0 0 auto;
  justify-content: flex-start;
  gap: 5px;
  padding: 8px 12px 8px;
  border-bottom: 1px solid rgba(255,255,255,.06);
}
.alyx-compact .alyx-container { max-width: 140px; }
.alyx-compact .alyx-name-sub,
.alyx-compact .alyx-hint,
.alyx-compact .alyx-caption-label { display: none; }
.alyx-compact .alyx-name { font-size: 10px; letter-spacing: .28em; }
.alyx-compact .alyx-caption { font-size: calc(12px * var(--alyx-text-scale, 1)); min-height: 0; line-height: 1.3; }

/* ── transform layers ─────────────────────────────────────────────────── */

/* ATTENTION — whole-figure micro-orientation toward user / work / inward.
   JS writes the transform; this only defines the ease. Never cursor-driven. */
.alyx-attention {
  width: 100%; display: flex; justify-content: center;
  will-change: transform;
  transition: transform var(--att-dur, 650ms) cubic-bezier(.25,.1,.2,1);
}

/* BREATHING — one-shot animation per cycle, restarted by JS with fresh
   --b-dur/--b-amp/--b-lift so no two cycles are identical. Expansion from the
   base (transform-origin bottom), never floating. Asymmetric: inhale ~40%,
   exhale ~55%, ~5% rest. */
.alyx-breathe {
  width: 100%; display: flex; justify-content: center;
  transform-origin: 50% 100%;
  will-change: transform;
}
.alyx-breathe.is-breathing {
  animation: alyxBreath var(--b-dur, 4300ms) linear 1 both;
}
@keyframes alyxBreath {
  0% {
    transform: scaleY(1) translateY(0);
    animation-timing-function: cubic-bezier(.33,.02,.34,1);   /* inhale: active, eases out */
  }
  40% {
    transform: scaleY(calc(1 + var(--b-amp, .005))) translateY(var(--b-lift, -0.8px));
    animation-timing-function: cubic-bezier(.44,.02,.42,1);   /* exhale: longer, passive */
  }
  95%  { transform: scaleY(1) translateY(0); }                /* end-of-breath rest */
  100% { transform: scaleY(1) translateY(0); }
}

/* ACCENT — micro-rotation, ≤0.25°, only on a sigh peak or thinking entry.
   JS sets the rotate and the release duration. Never cyclic. */
.alyx-accent {
  width: 100%; display: flex; justify-content: center;
  will-change: transform;
  transition: transform var(--acc-dur, 600ms) cubic-bezier(.3,.05,.25,1);
}

/* ── the sprite stage ─────────────────────────────────────────────────── */

/* hidden until the intro/first-run is dismissed */
.alyx-dock.alyx-boot { opacity: 0 !important; visibility: hidden !important; }
.alyx-dock { transition: opacity .5s var(--ease,ease); }

.alyx-container {
  position: relative;
  width: 100%; max-width: 268px;
  aspect-ratio: 250 / 352;
  overflow: hidden;
  border-radius: var(--r-md, 8px);
  transition: filter var(--dur-slow,320ms) var(--ease,ease);
  will-change: filter;
}
/* two stacked sprite layers: crossfade on expression change, and sustained
   partial-opacity blends for micro-expression (soft-smile at ~22% over
   neutral). Fade duration is the per-emotion envelope, set by JS. */
.alyx-face {
  position: absolute; inset: 0; z-index: 0;
  background-image: url("../img/alyx/alyx-expressions.webp");
  background-repeat: no-repeat;
  background-size: 600% 400%;              /* 6 cols × 4 rows (24 faces) */
  background-position: 0% 0%;
  opacity: 0;
  transition: opacity var(--fade, 240ms) var(--fade-ease, ease);
  will-change: opacity;
}
.alyx-face.is-active { opacity: 1; }

/* soft emotion wash + vignette. The wash inherits its emotion's tempo:
   --wash-dur is set per state by JS (sad ≈ 900ms, surprised ≈ 120ms). */
.alyx-container::before {
  content:""; position:absolute; inset:0; z-index:2; pointer-events:none;
  background:
    /* risk telemetry: a faint ember glow at the crown, rides over the mood wash */
    radial-gradient(90% 55% at 50% 0%, var(--alyx-risk, transparent), transparent 72%),
    radial-gradient(120% 90% at 50% 18%, var(--alyx-wash, rgba(167,139,250,.10)), transparent 70%),
    radial-gradient(140% 120% at 50% 100%, rgba(0,0,0,.45), transparent 55%);
  transition: background var(--wash-dur, 320ms) var(--ease,ease);
}
.alyx-container::after { content: none; }   /* particles stay removed — forever */

/* GENERATE reaction: a brief glow flash, light only, no movement */
.alyx-container.alyx-pulse { animation: alyxPulse 1.3s var(--ease, ease); }
@keyframes alyxPulse {
  0%   { filter: brightness(1); }
  30%  { filter: brightness(1.14) saturate(1.15); }
  100% { filter: brightness(1); }
}

/* per-state emotion wash */
.alyx-container.state-neutral    { --alyx-wash: rgba(167,139,250,.09); }
.alyx-container.state-soft-smile { --alyx-wash: rgba(232,184,75,.11); }
.alyx-container.state-thinking   { --alyx-wash: rgba(120,140,200,.11); }
.alyx-container.state-happy      { --alyx-wash: rgba(232,184,75,.15); }
.alyx-container.state-concerned  { --alyx-wash: rgba(200,90,110,.13); }
.alyx-container.state-serious    { --alyx-wash: rgba(150,150,170,.10); }
.alyx-container.state-sad        { --alyx-wash: rgba(90,110,180,.13); }
.alyx-container.state-surprised  { --alyx-wash: rgba(200,160,255,.15); }
.alyx-container.state-playful    { --alyx-wash: rgba(232,120,180,.13); }
.alyx-container.state-angry      { --alyx-wash: rgba(210,70,70,.15); }
.alyx-container.state-shy        { --alyx-wash: rgba(232,150,180,.14); }
.alyx-container.state-inspired,
.alyx-container.state-happy      { filter: brightness(1.04); }
/* sheet 02 */
.alyx-container.state-smug        { --alyx-wash: rgba(200,150,255,.12); }
.alyx-container.state-curious     { --alyx-wash: rgba(150,180,230,.13); }
.alyx-container.state-wink        { --alyx-wash: rgba(232,150,200,.13); }
.alyx-container.state-teasing     { --alyx-wash: rgba(232,140,190,.13); }
.alyx-container.state-tired       { --alyx-wash: rgba(120,120,150,.11); }
.alyx-container.state-sleepy      { --alyx-wash: rgba(100,110,160,.12); }
.alyx-container.state-embarrassed { --alyx-wash: rgba(232,140,170,.16); }
.alyx-container.state-excited     { --alyx-wash: rgba(232,180,90,.16); }
.alyx-container.state-annoyed     { --alyx-wash: rgba(200,90,90,.13); }
.alyx-container.state-shocked     { --alyx-wash: rgba(190,160,255,.16); }
.alyx-container.state-disappointed{ --alyx-wash: rgba(110,120,160,.13); }
.alyx-container.state-determined  { --alyx-wash: rgba(232,184,75,.14); }
.alyx-container.state-excited     { filter: brightness(1.05); }

/* ── TWO VOICES, clearly separated ───────────────────────────────────────
   The avatar CAPTION is her in-the-moment read of THIS song: ephemeral,
   reactive, cool-toned. Alyx SAYS (separate file) is her standing memory of
   how YOU create: warmer, gold-accented. Distinct type + a hairline between
   them so a glance never confuses the two. */

.alyx-caption-block { margin-top: 4px; text-align: center; }
.alyx-caption-label {
  font-family: var(--ff-cinzel, serif);
  font-size: calc(10px * var(--alyx-text-scale, 1)); letter-spacing: .26em; text-transform: uppercase;   /* rel-1b */
  color: color-mix(in srgb, #8aa2c8 45%, transparent);   /* cool, not gold */
  margin-bottom: 2px;
  transition: opacity var(--dur-base,200ms) var(--ease,ease);
}
/* when the line is just "…" there's nothing to label — hide the tag, keep the dots */
.alyx-caption-block.alyx-caption-empty .alyx-caption-label { opacity: 0; }

/* caption — her voice on THIS song, quiet and cool. Enters AFTER the face
   settles (JS-timed). Cooler + lighter than Alyx Says so the two never blur. */
.alyx-caption {
  font-family: var(--ff-crimson, Georgia, serif); font-style: italic;
  font-size: calc(13.5px * var(--alyx-text-scale, 1)); line-height: 1.35; text-align: center;   /* rel-1b */
  color: color-mix(in srgb, #9fb0cc 60%, var(--text3, #857f90));   /* cool grey-blue */
  min-height: 37px; padding: 0 4px;   /* rel-1b: two lines at the new size */
  transition: opacity var(--dur-base,200ms) var(--ease,ease), color var(--dur-base,200ms) var(--ease,ease);
}
.alyx-caption.state-concerned { color: color-mix(in srgb, #c85a6e 55%, var(--text3)); }
.alyx-caption.state-happy     { color: color-mix(in srgb, #7fa8d8 60%, var(--text3)); }

.alyx-name { font-family: var(--ff-cinzel, serif); font-size: 12px;
  letter-spacing: .34em; color: var(--gold, #c9a961); opacity: .85; }
.alyx-name-sub { font-family: var(--ff-mono, monospace); font-size: 8px;
  letter-spacing: .3em; color: var(--text3, #857f90); margin-top: -2px; }
.alyx-hint { font-family: var(--ff-mono, monospace); font-size: 9px;
  letter-spacing: .12em; line-height: 1.5; text-align: center;
  color: color-mix(in srgb, var(--text3,#857f90) 70%, transparent);
  max-width: 180px; margin-top: 2px; }

/* reduced motion: no breathing, no attention drift, no accents; expression
   changes become near-cuts. JS also disables its schedulers. */
@media (prefers-reduced-motion: reduce) {
  .alyx-breathe.is-breathing { animation: none !important; }
  .alyx-attention, .alyx-accent { transition: none !important; transform: none !important; }
  .alyx-face { transition-duration: 80ms !important; }
  .alyx-container.alyx-pulse { animation: none !important; }
  .alyx-container { --alyx-risk: transparent !important; }   /* no telemetry glow */
}
