/* announce.css - the three arena-wide announcements, and the flashes behind them.
 *
 * SPLIT FROM app.css, which was 46 lines over its budget, and the seam is real rather than
 * a line-count dodge: these are one subject. Three events are big enough that the whole
 * room has to be told at once, and each has to be unmistakable for the other two at a
 * glance, mid-fight, while something is trying to kill you:
 *
 *   GOLD       punches in and overshoots. A strike.
 *   ANTI-STAR  bleeds in on letter-spacing, and the screen darkens. A hush.
 *   ELDER      comes up THROUGH the floor and settles. Ground breaking.
 *
 * The FRAME (#arenaEdge) joined them because it is the same job in a different tense: an
 * announcement says a thing HAPPENED, the frame says what the arena IS LIKE now that it
 * has. It is also the only one of these every player sees wherever they are standing,
 * which matters when the event that turns it green happens at the centre of a map most of
 * the room cannot see.
 *
 * They share ONE #megaBanner and ONE #megaFlash element, so every handler clears the
 * others classes before adding its own; keeping the three rulesets side by side here is
 * what makes that contract visible instead of something you discover.
 */

/* Gold flash when a mega-spike forms. Kept translucent (max ~0.5 at center)
   and short so it punches without curtaining over the canvas chain-lightning,
   which lives longer and must stay visible. */
#megaFlash {
  position: fixed; inset: 0; z-index: 8; pointer-events: none; opacity: 0;
  background: radial-gradient(circle at center,
    rgba(255,228,150,0.5), rgba(245,179,1,0.2) 48%, rgba(245,179,1,0) 70%);
}
#megaFlash.show { animation: megaFlash 0.55s ease-out; }
@keyframes megaFlash { 0% { opacity: 0; } 10% { opacity: 1; } 100% { opacity: 0; } }

/* The anti-star's arrival is the INVERSE. The gold whites the screen out; this
   closes it down from the edges, so the two biggest events in the game can never
   be mistaken for one another at a glance. Vignette rather than a full blackout:
   it must never hide the arena you are trying to escape across. Slower than the
   gold's, because the anti-star also warns for twice as long. */
#megaFlash.show-dark {
  background: radial-gradient(circle at center,
    rgba(58,21,102,0.18) 18%, rgba(10,4,22,0.62) 62%, rgba(4,1,9,0.86) 100%);
  animation: megaFlashDark 0.9s ease-out;
}
@keyframes megaFlashDark { 0% { opacity: 0; } 14% { opacity: 1; } 100% { opacity: 0; } }

/* Arena-wide banner when a mega-spike forms */
#megaBanner {
  position: fixed; top: 18%; left: 50%; transform: translate(-50%, 0);
  z-index: 8; pointer-events: none; opacity: 0; white-space: nowrap;
  font-weight: 800; font-size: clamp(20px, 4vw, 42px); letter-spacing: 2px;
  color: #ffcf3a; text-shadow: 0 0 20px rgba(245,179,1,0.9), 0 2px 6px rgba(0,0,0,0.7);
}
#megaBanner.show { animation: megaBanner 2.6s ease-out; }
@keyframes megaBanner {
  0%   { opacity: 0; transform: translate(-50%, 12px) scale(0.9); }
  12%  { opacity: 1; transform: translate(-50%, 0) scale(1.06); }
  25%  { transform: translate(-50%, 0) scale(1); }
  80%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -8px); }
}

/* A DARK SPIKE HAS EMERGED. The gold's banner punches in and overshoots — it is a
   lightning strike. This one BLEEDS in: no scale, no bounce, a slower curve and a
   glow that spreads instead of flaring. Same position and size so it is read the
   same way; nothing else about it is the same. Cold violet on near-black rather
   than gold, because the two must never be confused at a glance mid-fight. */
#megaBanner.dark {
  color: #c9a4ff;
  text-shadow: 0 0 26px rgba(120,50,220,0.85), 0 0 60px rgba(60,20,120,0.7), 0 2px 8px rgba(0,0,0,0.9);
}
#megaBanner.dark.show { animation: megaBannerDark 3.2s cubic-bezier(.16,.8,.3,1); }
@keyframes megaBannerDark {
  0%   { opacity: 0; letter-spacing: 12px; filter: blur(6px); }
  22%  { opacity: 1; letter-spacing: 2px; filter: blur(0); }
  78%  { opacity: 1; }
  100% { opacity: 0; letter-spacing: 6px; filter: blur(3px); }
}
@media (prefers-reduced-motion: reduce) {
  #megaBanner.dark.show { animation: megaBannerDarkCalm 3.2s ease-out; }
  @keyframes megaBannerDarkCalm { 0% { opacity: 0; } 15%, 80% { opacity: 1; } 100% { opacity: 0; } }
}

/* THE ELDER SPIKE HAS AWOKEN. A third voice, and it has to be, because the other two are
   spoken for: the gold PUNCHES in and overshoots (a strike), the anti-star BLEEDS in on
   letter-spacing (a hush). This one COMES UP THROUGH THE FLOOR.

   Built from the ground: the text is clipped away below its own baseline and rises into
   view, so it breaks upward rather than fading on, then settles back a few pixels like
   ground dropping into place. Under it a smear of tar spreads from the centre and thins
   out. That is the only ornament and it is deliberately slow and low contrast, because
   the loud part of this event is the 950px hole opening in the middle of the arena. The
   banner's job is to name it, not to compete with it.

   Sickly green on near-black, matched to the Elder's own palette, so all three
   announcements are told apart by colour alone at a glance. */
#megaBanner.elder {
  color: #b6ffcf;
  text-shadow: 0 0 24px rgba(47,143,78,0.9), 0 0 64px rgba(10,70,31,0.85), 0 3px 10px rgba(0,0,0,0.95);
}
#megaBanner.elder::after {
  content: ""; position: absolute; left: 50%; bottom: -14px;
  height: 12px; width: 0; transform: translateX(-50%);
  border-radius: 50%; filter: blur(3px);
  background: radial-gradient(ellipse at center, rgba(11,43,29,0.95), rgba(11,43,29,0) 72%);
}
#megaBanner.elder.show { animation: megaBannerElder 3.6s cubic-bezier(.2,.9,.25,1); }
#megaBanner.elder.show::after { animation: elderTar 3.6s ease-out; }
@keyframes megaBannerElder {
  0%   { opacity: 0; clip-path: inset(100% 0 0 0); transform: translate(-50%, 18px); }
  26%  { opacity: 1; clip-path: inset(0 0 0 0);    transform: translate(-50%, 0); }
  32%  { transform: translate(-50%, -3px); }
  38%  { transform: translate(-50%, 0); }
  82%  { opacity: 1; }
  100% { opacity: 0; transform: translate(-50%, -6px); }
}
@keyframes elderTar {
  0%   { width: 0; opacity: 0; }
  30%  { width: 62%; opacity: 0.85; }
  80%  { width: 74%; opacity: 0.6; }
  100% { width: 78%; opacity: 0; }
}
/* The rise IS the idea, so reduced motion keeps the arrival and drops the lurch: no
   sweep, no settle, just the fade and the tar. */
@media (prefers-reduced-motion: reduce) {
  #megaBanner.elder.show { animation: megaBannerElderCalm 3.6s ease-out; }
  #megaBanner.elder.show::after { animation-duration: 3.6s; }
  @keyframes megaBannerElderCalm { 0% { opacity: 0; } 18%, 82% { opacity: 1; } 100% { opacity: 0; } }
}

/* ---- The arena edge -------------------------------------------------------
   The same dissolve as the band, taken all the way round the window instead of
   living on the top edge alone. It does two jobs: it seats the arena inside the
   screen rather than letting it run off four hard edges, and it darkens exactly
   the ground the chrome sits on, so the leave button (bottom left) and the
   weapon meters (bottom centre) get the legibility the score and clock already
   had for free.

   Z-INDEX 3, AND THAT IS THE POINT. It sits UNDER #hudBand (4) and under the
   score, clock and standings (5), so every readable thing in the match reads on
   top of it exactly like the rest of the UI. Putting it above them would darken
   the standings, which is the one column a player reads mid-fight.

   `inset` box-shadow rather than four gradients: one paint, no seams at the
   corners, and nothing to keep in sync when the viewport changes. pointer-events
   is none on the same principle as #prestige — you are still in a live arena
   while this is on screen, so it must never eat a click or block a dodge. */
#arenaEdge {
  position: fixed; inset: 0; z-index: 3; display: none; pointer-events: none;
  box-shadow: inset 0 0 150px 34px rgba(6, 9, 20, 0.82);
}
body.playing #arenaEdge { display: block; }

/* A phone has far less arena to give away, so the frame thins rather than
   eating the playfield. */
@media (max-width: 620px) {
  #arenaEdge { box-shadow: inset 0 0 90px 18px rgba(6, 9, 20, 0.78); }
}

/* WHILE THE ELDER IS ALIVE the frame is his colour, and it breathes.
   `body.elder-alive` is set by render.js the frame an Elder appears in the lineup and
   cleared the frame he leaves, so this is a state and not an event: it does not announce
   him, it is what the arena is like NOW that he is here. Every player gets it wherever
   they are standing, which matters because the rising itself happens at the centre and
   most of the room never sees it.

   NEAR IMPERCEPTIBLE, and that is the brief (Kenny). 19 seconds a cycle, against the
   food's 7: slow enough that you cannot catch it moving, only notice afterwards that the
   room has not been still. The amplitude is a few percent of a shadow nobody looks at
   directly. If you can see this pulse, it is wrong.

   Reduced motion holds it at the midpoint: the COLOUR is the information (his enemies are
   green now) and the breath is only intensity, which is the half we are allowed to drop. */
body.elder-alive #arenaEdge {
  box-shadow: inset 0 0 165px 38px rgba(6, 26, 14, 0.86);
  animation: elderEdgeBreath 19s ease-in-out infinite;
}
@keyframes elderEdgeBreath {
  0%, 100% { box-shadow: inset 0 0 165px 38px rgba(6, 26, 14, 0.86); }
  50%      { box-shadow: inset 0 0 186px 46px rgba(9, 34, 18, 0.90); }
}
@media (max-width: 620px) {
  body.elder-alive #arenaEdge {
    box-shadow: inset 0 0 100px 20px rgba(6, 26, 14, 0.82);
    animation: elderEdgeBreathSm 19s ease-in-out infinite;
  }
  @keyframes elderEdgeBreathSm {
    0%, 100% { box-shadow: inset 0 0 100px 20px rgba(6, 26, 14, 0.82); }
    50%      { box-shadow: inset 0 0 115px 25px rgba(9, 34, 18, 0.86); }
  }
}
@media (prefers-reduced-motion: reduce) {
  body.elder-alive #arenaEdge { animation: none; }
}

/* PRESTIGE: the fourth announcement, and the only PERSONAL one. Twelve tiers, four
   bands, because twelve bespoke cards is twelve things to maintain and this fires
   several times a match: what reads as a production the first time is tiring by the
   tenth. The band escalates, the tier's own --pr identifies, and the mark is a SHAPE
   as well as a hue so it reads without colour. Held, never pulsed. */
/* SUBTRACTION TEST, per craft-detail: a radial wash behind the card was built,
   then removed. The mark and its weight already carry the escalation, the moment
   still lands without it, and it was the most expensive part on two budgets that
   are both full. What survives that cut is the thing worth keeping. */
#prestige[data-band="precious"] { --pr-mark: 44px; }
#prestige[data-band="gem"]      { --pr-mark: 46px; }
#prestige[data-band="max"]      { --pr-mark: 52px; }
#prestige[data-band] .pr-star   { font-size: var(--pr-mark, 40px); }
