/* Boundwake — tournament / guild UI motion pack
   Drop-in under assets/ui_motion/. Transform + opacity only.
   Tokens use Boundwake mood hexes with fallbacks to live :root vars. */

:root {
  --bw-parch: var(--parch, #F4E6C8);
  --bw-parch-hi: var(--parch3, #FBF4E4);
  --bw-parch-lo: var(--parch2, #EBD7B0);
  --bw-ink: var(--ink, #2A2118);
  --bw-plum: var(--plum, #2C2140);
  --bw-gold: var(--gold, #E0B14A);
  --bw-gold-deep: var(--gold2, #B07D24);
  --bw-moss: var(--moss, #3F6B4F);
  --bw-ember: var(--ember, #C45A32);
  --bw-mist: var(--mist, #6E8FAF);
  --bw-flutter: 1; /* intensity 0–1.5; scale rotate/skew amp */
}

/* =========================================================
   A. Banner flutter — soft parchment pennant / ribbon
   ========================================================= */

.bw-banner,
#bw-banner-flutter {
  --_amp: calc(var(--bw-flutter, 1) * 1deg);
  --_skew: calc(var(--bw-flutter, 1) * 0.8deg);
  position: relative;
  display: inline-flex;
  align-items: stretch;
  perspective: 420px;
  transform-style: preserve-3d;
  isolation: isolate;
  max-width: 100%;
}

.bw-banner-flag {
  position: relative;
  display: inline-block;
  min-width: 72px;
  min-height: 96px;
  padding: 10px 12px 22px;
  color: var(--bw-ink);
  font: 800 12px/1.25 ui-rounded, "Nunito", system-ui, sans-serif;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  text-align: center;
  background:
    linear-gradient(180deg, var(--bw-parch-hi) 0%, var(--bw-parch) 55%, var(--bw-parch-lo) 100%);
  border: 1.5px solid color-mix(in srgb, var(--bw-gold) 70%, #8a6a3a);
  border-bottom: 0;
  border-radius: 4px 4px 0 0;
  box-shadow:
    inset 0 1px 0 #fff8,
    0 4px 12px #00000033,
    0 0 0 1px color-mix(in srgb, var(--bw-gold) 28%, transparent);
  transform-origin: 50% 0%;
  will-change: transform;
  clip-path: polygon(0 0, 100% 0, 100% 78%, 50% 100%, 0 78%);
  overflow: hidden;
}

/* Gold trim sheen — slow single-pass drift across the face */
.bw-banner-flag::before {
  content: "";
  position: absolute;
  inset: -10% -40%;
  background: linear-gradient(
    105deg,
    transparent 35%,
    color-mix(in srgb, var(--bw-gold) 55%, transparent) 48%,
    color-mix(in srgb, #fffaf0 70%, transparent) 52%,
    transparent 65%
  );
  opacity: 0.35;
  pointer-events: none;
  transform: translateX(-60%);
  will-change: transform, opacity;
}

.bw-banner-flag::after {
  content: "";
  position: absolute;
  left: 6px;
  right: 6px;
  top: 6px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(
    90deg,
    transparent,
    var(--bw-gold),
    color-mix(in srgb, var(--bw-gold) 40%, #fff8e0),
    var(--bw-gold),
    transparent
  );
  opacity: 0.85;
  pointer-events: none;
}

/* Variants — soft tint, not Kilumen HUD chrome */
.bw-banner--tourney .bw-banner-flag {
  background:
    linear-gradient(180deg, #fff2d4 0%, var(--bw-parch) 50%, #e8c98a 100%);
  border-color: color-mix(in srgb, var(--bw-gold) 85%, #8a6a3a);
}
.bw-banner--guild .bw-banner-flag {
  background:
    linear-gradient(180deg, #e8f0e4 0%, color-mix(in srgb, var(--bw-parch) 82%, var(--bw-moss)) 55%, #d5e0c8 100%);
  border-color: color-mix(in srgb, var(--bw-moss) 55%, var(--bw-gold));
}
.bw-banner--team .bw-banner-flag {
  background:
    linear-gradient(180deg, #ebe4f4 0%, color-mix(in srgb, var(--bw-parch) 78%, var(--bw-plum)) 55%, #d8cfe4 100%);
  border-color: color-mix(in srgb, var(--bw-mist) 45%, var(--bw-gold));
}

/* Idle flutter loop (~3.2s) — slight rotateY + skew, staggered tip feel */
@keyframes bw-banner-flutter {
  0%   { transform: rotateY(calc(var(--_amp) * -1.2)) skewX(calc(var(--_skew) * -0.6)) rotateZ(calc(var(--_amp) * -0.35)); }
  28%  { transform: rotateY(calc(var(--_amp) * 1.4))  skewX(calc(var(--_skew) * 0.9))  rotateZ(calc(var(--_amp) * 0.45)); }
  55%  { transform: rotateY(calc(var(--_amp) * -0.9)) skewX(calc(var(--_skew) * -1.1)) rotateZ(calc(var(--_amp) * -0.25)); }
  78%  { transform: rotateY(calc(var(--_amp) * 0.7))  skewX(calc(var(--_skew) * 0.5))  rotateZ(calc(var(--_amp) * 0.3)); }
  100% { transform: rotateY(calc(var(--_amp) * -1.2)) skewX(calc(var(--_skew) * -0.6)) rotateZ(calc(var(--_amp) * -0.35)); }
}

@keyframes bw-banner-sheen {
  0%, 18%   { transform: translateX(-70%); opacity: 0; }
  28%       { opacity: 0.4; }
  52%       { transform: translateX(70%); opacity: 0.28; }
  62%, 100% { transform: translateX(80%); opacity: 0; }
}

html:not([data-motion="reduced"]) .bw-banner .bw-banner-flag,
html:not([data-motion="reduced"]) #bw-banner-flutter .bw-banner-flag {
  animation: bw-banner-flutter 3.2s ease-in-out infinite;
}
html:not([data-motion="reduced"]) .bw-banner .bw-banner-flag::before,
html:not([data-motion="reduced"]) #bw-banner-flutter .bw-banner-flag::before {
  animation: bw-banner-sheen 4s ease-in-out infinite;
}

/* Stagger multiple banners so the screen never pulses in sync */
.bw-banner:nth-child(2n) .bw-banner-flag { animation-delay: 0.55s; }
.bw-banner:nth-child(2n) .bw-banner-flag::before { animation-delay: 1.1s; }
.bw-banner:nth-child(3n) .bw-banner-flag { animation-delay: 1.15s; }
.bw-banner:nth-child(3n) .bw-banner-flag::before { animation-delay: 2s; }
.bw-banner--guild .bw-banner-flag { animation-duration: 3.6s; }
.bw-banner--team .bw-banner-flag { animation-duration: 2.9s; }
.bw-banner--tourney .bw-banner-flag { animation-duration: 3.1s; }

/* Optional SVG pennant face inside the flag */
.bw-banner-flag img,
.bw-banner-flag svg.bw-banner-art {
  display: block;
  width: 40px;
  height: auto;
  margin: 0 auto 4px;
  pointer-events: none;
}

/* =========================================================
   B. Renown tick — one-shot gold spark on renown gain
   ========================================================= */

.bw-renown-tick,
.bar-renown,
.flare-renown {
  position: relative;
}

.bw-renown-tick-up {
  position: absolute;
  left: 50%;
  top: 0;
  z-index: 3;
  translate: -50% -110%;
  padding: 2px 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--bw-gold) 88%, #fff);
  color: var(--bw-ink);
  font: 800 11px/1.2 ui-rounded, "Nunito", system-ui, sans-serif;
  letter-spacing: 0.02em;
  white-space: nowrap;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--bw-gold-deep) 50%, transparent), 0 2px 8px #0004;
  pointer-events: none;
  opacity: 0;
  transform: translateY(6px) scale(0.86);
  will-change: transform, opacity;
}

.bw-renown-tick.is-ticking .bw-renown-tick-up,
.bw-renown-tick-up.is-ticking {
  animation: bw-renown-tick 780ms cubic-bezier(0.22, 0.9, 0.28, 1) both;
}

.bw-renown-burst::after,
.bar-renown.bw-renown-burst::after,
.flare-renown.bw-renown-burst::after {
  content: "";
  position: absolute;
  inset: -4px;
  border-radius: inherit;
  box-shadow: 0 0 0 0 color-mix(in srgb, var(--bw-gold) 55%, transparent);
  pointer-events: none;
  opacity: 0;
  will-change: transform, opacity;
}

.bw-renown-tick.is-ticking.bw-renown-burst::after,
.bar-renown.is-ticking.bw-renown-burst::after,
.flare-renown.is-ticking.bw-renown-burst::after,
.bw-renown-burst.is-ticking::after {
  animation: bw-renown-ring 720ms ease-out both;
}

@keyframes bw-renown-tick {
  0%   { opacity: 0; transform: translateY(8px) scale(0.8); }
  18%  { opacity: 1; transform: translateY(-2px) scale(1.08); }
  55%  { opacity: 1; transform: translateY(-14px) scale(1); }
  100% { opacity: 0; transform: translateY(-28px) scale(0.94); }
}

@keyframes bw-renown-ring {
  0%   { opacity: 0.7; transform: scale(0.92); box-shadow: 0 0 0 0 color-mix(in srgb, var(--bw-gold) 60%, transparent); }
  60%  { opacity: 0.35; }
  100% { opacity: 0; transform: scale(1.18); box-shadow: 0 0 0 10px transparent; }
}

/* JS helper note (see HOOKS.md):
   el.classList.add('is-ticking');
   el.addEventListener('animationend', () => el.classList.remove('is-ticking'), { once: true });
*/

/* =========================================================
   C. Team victory sparkle — rare, short, card-local
   ========================================================= */

.bw-victory-sparkle {
  position: relative;
  overflow: hidden; /* keep flecks inside the card/panel */
}

.bw-victory-burst {
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 4;
  opacity: 0;
}

.bw-victory-sparkle.is-victorious .bw-victory-burst {
  animation: bw-victory-fade 1.45s ease-out both;
}

/* Tiny CSS particles (8 dots) — gold + parchment flecks */
.bw-victory-confetti {
  position: absolute;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--bw-gold);
  opacity: 0;
  will-change: transform, opacity;
  box-shadow: 0 0 4px color-mix(in srgb, var(--bw-gold) 50%, transparent);
}

.bw-victory-confetti:nth-child(odd) {
  width: 5px;
  height: 5px;
  border-radius: 1px;
  background: var(--bw-parch-hi);
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--bw-gold) 45%, transparent);
}
.bw-victory-confetti:nth-child(3n) {
  background: color-mix(in srgb, var(--bw-gold) 70%, #fff8e0);
  width: 4px;
  height: 7px;
  border-radius: 1px;
}
.bw-victory-confetti:nth-child(4n) {
  background: color-mix(in srgb, var(--bw-mist) 35%, var(--bw-parch));
}

.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(1)  { left: 18%; top: 42%; animation: bw-vic-1 1.35s ease-out both; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(2)  { left: 42%; top: 38%; animation: bw-vic-2 1.4s  ease-out both; animation-delay: 40ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(3)  { left: 68%; top: 44%; animation: bw-vic-3 1.3s  ease-out both; animation-delay: 70ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(4)  { left: 28%; top: 58%; animation: bw-vic-4 1.45s ease-out both; animation-delay: 30ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(5)  { left: 55%; top: 55%; animation: bw-vic-5 1.38s ease-out both; animation-delay: 90ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(6)  { left: 78%; top: 52%; animation: bw-vic-6 1.32s ease-out both; animation-delay: 50ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(7)  { left: 12%; top: 50%; animation: bw-vic-7 1.42s ease-out both; animation-delay: 110ms; }
.bw-victory-sparkle.is-victorious .bw-victory-confetti:nth-child(8)  { left: 88%; top: 40%; animation: bw-vic-8 1.28s ease-out both; animation-delay: 20ms; }

@keyframes bw-victory-fade {
  0%   { opacity: 1; }
  75%  { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes bw-vic-1 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(-6px,-10px) scale(1.1)} 100%{opacity:0;transform:translate(-18px,-46px) scale(.6) rotate(24deg)} }
@keyframes bw-vic-2 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(4px,-12px) scale(1.15)} 100%{opacity:0;transform:translate(8px,-52px) scale(.55) rotate(-18deg)} }
@keyframes bw-vic-3 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(10px,-8px) scale(1.05)} 100%{opacity:0;transform:translate(22px,-44px) scale(.5) rotate(30deg)} }
@keyframes bw-vic-4 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(-8px,-6px) scale(1.1)} 100%{opacity:0;transform:translate(-24px,-38px) scale(.55) rotate(-22deg)} }
@keyframes bw-vic-5 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(2px,-14px) scale(1.2)} 100%{opacity:0;transform:translate(4px,-50px) scale(.5) rotate(12deg)} }
@keyframes bw-vic-6 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(12px,-10px) scale(1.05)} 100%{opacity:0;transform:translate(28px,-40px) scale(.55) rotate(-28deg)} }
@keyframes bw-vic-7 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(-12px,-8px) scale(1.1)} 100%{opacity:0;transform:translate(-30px,-42px) scale(.5) rotate(20deg)} }
@keyframes bw-vic-8 { 0%{opacity:0;transform:translate(0,0) scale(.4)} 12%{opacity:1;transform:translate(8px,-12px) scale(1.15)} 100%{opacity:0;transform:translate(16px,-48px) scale(.55) rotate(-14deg)} }

/* Soft gold halo on the victorious card — opacity only, no full-screen flash */
.bw-victory-sparkle.is-victorious {
  animation: bw-victory-card-glow 1.45s ease-out both;
}
@keyframes bw-victory-card-glow {
  0%   { box-shadow: 0 0 0 0 transparent; }
  20%  { box-shadow: 0 0 0 2px color-mix(in srgb, var(--bw-gold) 55%, transparent), 0 0 18px color-mix(in srgb, var(--bw-gold) 28%, transparent); }
  100% { box-shadow: 0 0 0 0 transparent; }
}

/* =========================================================
   Reduced motion — kill loops; ticks may snap / static gold
   ========================================================= */

@media (prefers-reduced-motion: reduce) {
  .bw-banner .bw-banner-flag,
  #bw-banner-flutter .bw-banner-flag,
  .bw-banner .bw-banner-flag::before,
  #bw-banner-flutter .bw-banner-flag::before {
    animation: none !important;
  }

  .bw-renown-tick.is-ticking .bw-renown-tick-up,
  .bw-renown-tick-up.is-ticking {
    animation: none !important;
    opacity: 1;
    transform: translateY(-12px) scale(1);
  }
  .bw-renown-tick.is-ticking .bw-renown-tick-up,
  .bw-renown-tick-up.is-ticking {
    /* hold briefly via transitionless static flash — JS still removes on timeout */
  }
  .bw-renown-burst.is-ticking::after,
  .bar-renown.is-ticking.bw-renown-burst::after,
  .flare-renown.is-ticking.bw-renown-burst::after {
    animation: none !important;
    opacity: 0.55;
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--bw-gold) 50%, transparent);
  }

  .bw-victory-sparkle.is-victorious,
  .bw-victory-sparkle.is-victorious .bw-victory-burst,
  .bw-victory-sparkle.is-victorious .bw-victory-confetti {
    animation: none !important;
  }
  .bw-victory-sparkle.is-victorious .bw-victory-confetti {
    opacity: 0.85;
    transform: none;
  }
  .bw-victory-sparkle.is-victorious {
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--bw-gold) 50%, transparent);
  }
}

/* Explicit app flag (matches style.css ambient gate) */
html[data-motion="reduced"] .bw-banner .bw-banner-flag,
html[data-motion="reduced"] #bw-banner-flutter .bw-banner-flag,
html[data-motion="reduced"] .bw-banner .bw-banner-flag::before,
html[data-motion="reduced"] #bw-banner-flutter .bw-banner-flag::before {
  animation: none !important;
}

/* Pause loops when tab is hidden — pair with a tiny JS visibility listener
   that sets html[data-motion="paused"], or rely on browser throttling.
   Optional class for Coder: */
html[data-motion="paused"] .bw-banner .bw-banner-flag,
html[data-motion="paused"] #bw-banner-flutter .bw-banner-flag,
html[data-motion="paused"] .bw-banner .bw-banner-flag::before,
html[data-motion="paused"] #bw-banner-flutter .bw-banner-flag::before {
  animation-play-state: paused !important;
}
