/* =========================================================================
   The Vitruvian — Speaking Glyph
   ONE shared mark for every "make the character speak" trigger in the Lab.
   Three render modes (button / icon / badge), four states (idle / pressed /
   thinking / speaking) from ONE motion source. SPEAKING reads real TTS
   amplitude via --amp (set on :root by SpeakingGlyph.js from a passive
   AnalyserNode on the TTS output).

   Identity is faithful to attached_assets/vitruvian-glyph_*.html (gold Vitruvian
   man, rings, sheen). Motion is tuned BOLDER + LARGER than that calm showcase
   page so the mark reads as clearly alive over the busy live 3D scene.

   CONTRAST: the demo sits every mode on a DARK surface so the gold man pops.
   The Lab's real trigger buttons are gold-filled, so icon mode adopts the demo's
   dark/cream ".vicon" shell, button mode adds a legibility halo, badge has a dark
   chip. Colours come from glyph-local --vg-* tokens (the demo's gold), NEVER the
   per-legend accent — so the mark is always the warm Vitruvian gold.
   ========================================================================= */

:root { --amp: 0.04; }

/* ---- glyph-local palette: the demo's gold (evening default / morning light) ---- */
[data-vglyph] {
  --vg-gold: #c9a45c;
  --vg-gold-mid: #ffe9b0;
  --vg-gold-bright: #ecc77e;
}
body.light-mode [data-vglyph],
body[data-mode="light"] [data-vglyph] {
  --vg-gold: #8f6a26;
  --vg-gold-mid: #e0ba60;
  --vg-gold-bright: #a87a1d;
}

/* ---- wrapper carrying the rings + the masked man (button/icon) ---- */
.vwrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  pointer-events: none;
}

/* ring blooms — summon (idle) + emit (speaking) */
.vring {
  position: absolute;
  inset: 2%;
  border-radius: 50%;
  border: 2px solid var(--vg-gold-bright);
  opacity: 0;
  pointer-events: none;
}

/* the masked Vitruvian man — clean white-on-transparent PNG as the alpha mask,
   a moving gold gradient painted through it (?v=2 busts the old cached PNG). */
.vman {
  width: 88%;
  height: 88%;
  -webkit-mask-image: url("/static/images/Vmanwhite.png?v=2");
  mask-image: url("/static/images/Vmanwhite.png?v=2");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  background-image: linear-gradient(115deg,
    var(--vg-gold) 28%, var(--vg-gold-mid) 50%, var(--vg-gold) 72%);
  background-size: 280% 100%;
  background-position: 130% 0;
  pointer-events: none;
  will-change: transform, filter;
}

/* ====================== sizing + contrast per mode ====================== */
/* Button mode — glyph before the existing label; a dark halo keeps the gold man
   legible on the gold/rust pills. Larger than the demo for presence in the Lab. */
[data-vglyph="button"] .vwrap { width: 30px; height: 30px; margin-inline-end: 3px; }
[data-vglyph="button"] .vman { filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5)); }

/* Icon mode — the glyph IS the button: demo dark (evening) / cream (morning)
   shell so the man reads; background/border win over the host's gold fill. */
[data-vglyph="icon"] {
  background: linear-gradient(180deg, #26190e 0%, #190f07 100%) !important;
  border: 1px solid rgba(201, 164, 92, .45) !important;
  border-radius: 50% !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .05), 0 5px 16px rgba(0, 0, 0, .45);
}
body.light-mode [data-vglyph="icon"],
body[data-mode="light"] [data-vglyph="icon"] {
  background: linear-gradient(180deg, #fbf4e2 0%, #efe2c5 100%) !important;
  border-color: rgba(201, 164, 92, .55) !important;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, .75), 0 3px 10px rgba(98, 70, 28, .18);
}
[data-vglyph="icon"]:hover { border-color: rgba(236, 199, 126, .8) !important; }
[data-vglyph="icon"] .vwrap { width: 82%; height: 82%; }
[data-vglyph="icon"][data-vstate="pressed"] { transform: scale(.93); }

/* ====================== IDLE ======================
   alive + inviting: deeper breath + slow sway + frequent double ring blooms */
[data-vglyph][data-vstate="idle"] .vman {
  animation:
    vg-sheen 3.6s ease-in-out infinite,
    vg-breathe 2.8s ease-in-out infinite,
    vg-sway 6s ease-in-out infinite,
    vg-idle-glow 3.6s ease-in-out infinite;
  animation-delay: var(--stagger, 0s), 0s, 0s, var(--stagger, 0s);
}
/* two rings offset by half the cycle → a bloom is visible almost continuously */
[data-vglyph][data-vstate="idle"] .v1 {
  animation: vg-summon 3.6s ease-out infinite;
  animation-delay: var(--stagger, 0s);
}
[data-vglyph][data-vstate="idle"] .v2 {
  animation: vg-summon 3.6s ease-out infinite;
  animation-delay: calc(var(--stagger, 0s) + 1.8s);
}
@keyframes vg-sheen {
  0% { background-position: 130% 0; }
  28% { background-position: -30% 0; }
  100% { background-position: -30% 0; }
}
@keyframes vg-breathe {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.09); }
}
@keyframes vg-sway {
  0%, 100% { rotate: -2.5deg; }
  50% { rotate: 2.5deg; }
}
/* continuous breathing glow so the mark is ALWAYS visibly alive at rest;
   keeps a constant dark shadow so button-mode stays legible on gold pills */
@keyframes vg-idle-glow {
  0%, 100% {
    filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5))
            drop-shadow(0 0 2px rgba(236, 199, 126, 0)) brightness(1);
  }
  50% {
    filter: drop-shadow(0 1px 1.5px rgba(0, 0, 0, .5))
            drop-shadow(0 0 8px var(--vg-gold-bright)) brightness(1.16);
  }
}
@keyframes vg-summon {
  0% { transform: scale(.5); opacity: 0; }
  14% { opacity: .9; }
  62% { transform: scale(1.5); opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

/* ====================== PRESSED — stamp ====================== */
[data-vglyph][data-vstate="pressed"] .vman {
  animation: none;
  rotate: 0deg;
  transform: scale(.78);
  transition: transform .12s ease;
}

/* ====================== THINKING — deeper breath + tilt ====================== */
[data-vglyph][data-vstate="thinking"] .vman { animation: vg-think 1.4s ease-in-out infinite; }
@keyframes vg-think {
  0%, 100% { transform: scale(1) rotate(-5deg); background-position: 120% 0; }
  50% { transform: scale(1.1) rotate(5deg); background-position: -20% 0; }
}

/* ====================== SPEAKING — moves with the voice; rings radiate ======================
   transform = amplitude-driven scale (snappy); filter = a continuous glow pulse so
   there is ALWAYS visible energy even when amplitude is momentarily low; rings emit. */
[data-vglyph][data-vstate="speaking"] .vman {
  background-position: 50% 0;
  rotate: 0deg;
  transform: scale(calc(1 + var(--amp) * .42));
  animation: vg-glow .5s ease-in-out infinite;
  transition: transform .05s linear;
}
@keyframes vg-glow {
  0%, 100% { filter: drop-shadow(0 0 calc(2px + var(--amp) * 6px) var(--vg-gold-bright)) brightness(1); }
  50% { filter: drop-shadow(0 0 calc(7px + var(--amp) * 15px) var(--vg-gold-bright)) brightness(1.28); }
}
[data-vglyph][data-vstate="speaking"] .v1 { animation: vg-emit 1s ease-out infinite; }
[data-vglyph][data-vstate="speaking"] .v2 { animation: vg-emit 1s ease-out infinite; animation-delay: .5s; }
@keyframes vg-emit {
  0% { transform: scale(.8); opacity: calc(.4 + var(--amp) * .5); }
  100% { transform: scale(2.15); opacity: 0; }
}

/* ====================== BADGE MODE ======================
   dark circular glyph badge on the art corner; the image/item is the tap target.
   State rules above are mode-agnostic ([data-vglyph][data-vstate]) so the badge
   inherits the same four-state motion automatically. */
.vbadge {
  position: absolute;
  right: 6px;
  bottom: 6px;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(16, 11, 6, .82);
  border: 1px solid rgba(201, 164, 92, .5);
  display: flex;
  align-items: center;
  justify-content: center;
  pointer-events: none;
  z-index: 3;
  box-shadow: 0 3px 10px rgba(0, 0, 0, .4);
  overflow: visible;
}
body.light-mode .vbadge,
body[data-mode="light"] .vbadge {
  background: rgba(255, 250, 236, .92);
  border-color: rgba(122, 92, 46, .5);
}
.vbadge .vman { width: 66%; height: 66%; }
.vbadge .vring { inset: 1px; }
[data-vglyph="badge"] { cursor: pointer; }

/* ====================== REDUCED MOTION ====================== */
@media (prefers-reduced-motion: reduce) {
  [data-vglyph] .vman,
  [data-vglyph] .vring { animation: none !important; transition: none !important; }
  [data-vglyph][data-vstate="speaking"] .vman { transform: none; rotate: 0deg; }
}
