/* Vote modal — animations + particles. Used by Bills, Ballots (any votable).
   Keeps animations out of Tailwind utility classes; everything else stays Tailwind. */

/* ── Reveal: fade + rise (240ms) ───────────────────────── */
@keyframes vm-rise {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vm-rise { animation: vm-rise 240ms cubic-bezier(0.16, 1, 0.3, 1) both; }

/* ── Modal entrance: backdrop fade + panel scale ───────── */
@keyframes vm-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
@keyframes vm-panel-in {
  from { opacity: 0; transform: translateY(6px) scale(0.97); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes vm-sheet-in {
  from { opacity: 0; transform: translateY(100%); }
  to   { opacity: 1; transform: translateY(0); }
}
.vm-backdrop-in { animation: vm-backdrop-in 220ms cubic-bezier(0.16, 1, 0.3, 1) both; }
.vm-panel-in    { animation: vm-panel-in 260ms cubic-bezier(0.16, 1, 0.3, 1) both; }
.vm-sheet-in    { animation: vm-sheet-in 280ms cubic-bezier(0.16, 1, 0.3, 1) both; }

/* ── Modal close: backdrop fade + panel/sheet slide out ────────── */
@keyframes vm-backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}
@keyframes vm-panel-out {
  from { opacity: 1; transform: translateY(0) scale(1); }
  to   { opacity: 0; transform: translateY(6px) scale(0.97); }
}
@keyframes vm-sheet-out {
  from { opacity: 1; transform: translateY(0); }
  to   { opacity: 0; transform: translateY(100%); }
}
.vm-backdrop-out { animation: vm-backdrop-out 200ms cubic-bezier(0.55, 0, 0.6, 0.4) both; }
.vm-panel-out    { animation: vm-panel-out 200ms cubic-bezier(0.55, 0, 0.6, 0.4) both; }
.vm-sheet-out    { animation: vm-sheet-out 240ms cubic-bezier(0.55, 0, 0.6, 0.4) both; }

/* While the user is dragging the sheet, the panel uses inline transform — kill the
   transition so the gesture tracks the finger 1:1. JS adds .vm-dragging on touchstart. */
.vm-dragging { transition: none !important; }

/* ── Sigil scale-rotate (success state) ─────────────────── */
@keyframes vm-sigil-in {
  0%   { opacity: 0; transform: scale(0.6) rotate(-6deg); }
  60%  { opacity: 1; transform: scale(1.05) rotate(0); }
  100% { opacity: 1; transform: scale(1) rotate(0); }
}
.vm-sigil-in { animation: vm-sigil-in 480ms cubic-bezier(0.16, 1, 0.3, 1) both; }

/* ── Monochrome emerald particles ───────────────────────── */
@keyframes vm-particle {
  0%   { opacity: 0; transform: translate(0, 0) scale(0.5); }
  20%  { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--tx), var(--ty)) scale(1); }
}
.vm-particle {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 9999px;
  background: #10b981;
  pointer-events: none;
  animation: vm-particle 900ms cubic-bezier(0.16, 1, 0.3, 1) both;
}
.vm-particle.vm-particle-square {
  border-radius: 1px;
  transform-origin: center;
}

/* ── Stance icons (Yes / No / Unsure) ─────────────────────
   Animated SVG glyphs in app/views/we_vote/votes/modal/_glyph.html.erb.
   Hover trigger = .vm-stance (the parent button) so animations fire while the
   user is choosing a stance. Colors are fixed per icon (independent of the
   button's selected/unselected state which is controlled by Tailwind classes). */
.vm-icon-yes    { color: #16a34a; }
.vm-icon-no     { color: #ea580c; }
.vm-icon-unsure { color: rgb(134 144 156); }
/* Explicit fill/stroke for unsure — bypass currentColor in case a parent's
   text-* class is bleeding into SVG inheritance. */
.vm-icon-unsure .vm-icon-ring { stroke: rgb(134 144 156); }
.vm-icon-unsure .vm-icon-q    { fill:   rgb(134 144 156); }
.dark .vm-icon-yes    { color: #22c55e; }
.dark .vm-icon-no     { color: #f97316; }
.dark .vm-icon-unsure { color: #f1f5f9; }
.dark .vm-icon-unsure .vm-icon-ring { stroke: #f1f5f9; }
.dark .vm-icon-unsure .vm-icon-q    { fill:   #f1f5f9; }

.vm-icon-root    { transform-origin: 100px 100px; }
.vm-icon-disc    { fill: currentColor; }
.vm-icon-disc-bg { fill: #fff; }
.dark .vm-icon-disc-bg { fill: transparent; }

/* Soft outer rim (rest state) and outward-pulsing glow (hover) */
.vm-icon-rim {
  fill: none; stroke-width: 2;
}
.vm-icon-yes    .vm-icon-rim { stroke: #bbf7d0; }
.vm-icon-no     .vm-icon-rim { stroke: #fed7aa; }
.vm-icon-unsure .vm-icon-rim { stroke: #e2e8f0; }
.vm-icon-glow {
  fill: none; stroke: currentColor; stroke-width: 2;
  transform-origin: 100px 100px;
  opacity: 0;
}
.vm-stance:hover .vm-icon-glow,
.vm-icon-play   .vm-icon-glow {
  animation: vm-icon-glow-pulse 1.6s ease-out infinite;
}
@keyframes vm-icon-glow-pulse {
  0%   { transform: scale(0.94); opacity: 0.45; stroke-width: 2; }
  100% { transform: scale(1.22); opacity: 0;    stroke-width: 0.5; }
}

/* Yes — check draws, disc presses, rays burst */
.vm-icon-check {
  fill: none; stroke: #fff; stroke-width: 16;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 110; stroke-dashoffset: 0;
}
.vm-stance:hover  .vm-icon-yes .vm-icon-check,
.vm-icon-yes.vm-icon-play  .vm-icon-check {
  animation: vm-icon-check-draw 650ms cubic-bezier(.65, 0, .35, 1);
}
.vm-stance:hover  .vm-icon-yes .vm-icon-root,
.vm-icon-yes.vm-icon-play  .vm-icon-root {
  animation: vm-icon-press 700ms cubic-bezier(.34, 1.56, .64, 1);
}
@keyframes vm-icon-check-draw {
  0%   { stroke-dashoffset: 110; }
  100% { stroke-dashoffset: 0; }
}
@keyframes vm-icon-press {
  0%   { transform: scale(1)    translateY(0); }
  20%  { transform: scale(0.94) translateY(2px); }
  55%  { transform: scale(1.05) translateY(-2px); }
  100% { transform: scale(1)    translateY(0); }
}

.vm-icon-ray {
  stroke: currentColor; stroke-width: 3; stroke-linecap: round;
  opacity: 0; transform-origin: 100px 100px;
}
.vm-stance:hover .vm-icon-yes .vm-icon-ray,
.vm-icon-yes.vm-icon-play .vm-icon-ray {
  animation: vm-icon-ray 600ms cubic-bezier(.4, 0, .2, 1) forwards;
}
.vm-stance:hover .vm-icon-yes .vm-icon-ray-1, .vm-icon-yes.vm-icon-play .vm-icon-ray-1 { animation-delay: 350ms; }
.vm-stance:hover .vm-icon-yes .vm-icon-ray-2, .vm-icon-yes.vm-icon-play .vm-icon-ray-2 { animation-delay: 380ms; }
.vm-stance:hover .vm-icon-yes .vm-icon-ray-3, .vm-icon-yes.vm-icon-play .vm-icon-ray-3 { animation-delay: 410ms; }
.vm-stance:hover .vm-icon-yes .vm-icon-ray-4, .vm-icon-yes.vm-icon-play .vm-icon-ray-4 { animation-delay: 360ms; }
.vm-stance:hover .vm-icon-yes .vm-icon-ray-5, .vm-icon-yes.vm-icon-play .vm-icon-ray-5 { animation-delay: 390ms; }
.vm-stance:hover .vm-icon-yes .vm-icon-ray-6, .vm-icon-yes.vm-icon-play .vm-icon-ray-6 { animation-delay: 420ms; }
@keyframes vm-icon-ray {
  0%   { opacity: 0; stroke-dasharray: 0 12; stroke-dashoffset: 0; }
  50%  { opacity: 1; stroke-dasharray: 8 4; }
  100% { opacity: 0; stroke-dasharray: 0 12; stroke-dashoffset: -16; }
}

/* No — both strokes draw in, then a sharp shake */
.vm-icon-x {
  fill: none; stroke: #fff; stroke-width: 16;
  stroke-linecap: round; stroke-linejoin: round;
  stroke-dasharray: 92; stroke-dashoffset: 0;
}
.vm-stance:hover .vm-icon-no .vm-icon-x-a, .vm-icon-no.vm-icon-play .vm-icon-x-a { animation: vm-icon-x-draw 280ms cubic-bezier(.5, 0, .2, 1); }
.vm-stance:hover .vm-icon-no .vm-icon-x-b, .vm-icon-no.vm-icon-play .vm-icon-x-b { animation: vm-icon-x-draw 280ms cubic-bezier(.5, 0, .2, 1) 180ms both; }
@keyframes vm-icon-x-draw {
  0%   { stroke-dashoffset: 92; }
  100% { stroke-dashoffset: 0; }
}
.vm-stance:hover .vm-icon-no .vm-icon-root,
.vm-icon-no.vm-icon-play .vm-icon-root {
  animation: vm-icon-shake 480ms cubic-bezier(.36, .07, .19, .97) 460ms;
}
@keyframes vm-icon-shake {
  0%, 100% { transform: translateX(0)    rotate(0); }
  15%      { transform: translateX(-5px) rotate(-2deg); }
  30%      { transform: translateX(5px)  rotate(2deg); }
  50%      { transform: translateX(-3px) rotate(-1.2deg); }
  70%      { transform: translateX(3px)  rotate(1.2deg); }
  85%      { transform: translateX(-1px) rotate(0); }
}

/* Unsure — typographic ?, scales 1.08 on hover, ring tightens */
.vm-icon-ring {
  fill: none; stroke: currentColor; stroke-width: 14;
  transition: stroke-width 350ms cubic-bezier(.25, .1, .25, 1);
}
.vm-icon-q {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-weight: 700; font-size: 130px;
  fill: currentColor;
  text-anchor: middle; dominant-baseline: central;
  letter-spacing: -0.02em;
}
.vm-icon-glyph {
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 250ms cubic-bezier(.25, .1, .25, 1);
}
.vm-stance:hover .vm-icon-unsure .vm-icon-glyph { transform: scale(1.08); }
.vm-stance:hover .vm-icon-unsure .vm-icon-ring  { stroke-width: 11; }

/* Play-once equivalents for the success state (no hover available) */
.vm-icon-unsure.vm-icon-play .vm-icon-glyph {
  animation: vm-icon-q-pop 700ms cubic-bezier(.16, 1, .3, 1) both;
}
.vm-icon-unsure.vm-icon-play .vm-icon-ring {
  animation: vm-icon-ring-tighten 700ms cubic-bezier(.25, .1, .25, 1) both;
}
@keyframes vm-icon-q-pop {
  0%   { transform: scale(0.6); opacity: 0; }
  60%  { transform: scale(1.08); opacity: 1; }
  100% { transform: scale(1); opacity: 1; }
}
@keyframes vm-icon-ring-tighten {
  0%   { stroke-width: 14; }
  100% { stroke-width: 11; }
}

/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .vm-rise,
  .vm-backdrop-in,
  .vm-panel-in,
  .vm-sheet-in,
  .vm-sigil-in,
  .vm-particle,
  .vm-icon-check,
  .vm-icon-x,
  .vm-icon-ray,
  .vm-icon-root,
  .vm-icon-glyph,
  .vm-icon-glow,
  .vm-icon-ring {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Line clamp helper (used by bill title in header) */
.vm-line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
