/* LEVEL UP SCREEN (see levelup.js). Same theme tokens as the finish screen.
   0.3s medallion draws | 0.7s old mark charges | 0.85s burst + new mark |
   1.0s name spells in | 1.5s from > to | 1.65s ladder | 1.8s road | 2.25s button */

.levelup {
  position: fixed; inset: 0; z-index: calc(var(--z-dialog, 150) + 1);
  display: grid; place-items: center; cursor: pointer; overflow: hidden;
  padding: max(24px, env(safe-area-inset-top, 0px)) 24px max(24px, env(safe-area-inset-bottom, 0px));
  font-family: var(--font-body, system-ui, sans-serif); color: var(--text, #fff);
  background:
    radial-gradient(60% 45% at 50% 36%, color-mix(in srgb, var(--accent) calc(var(--glow-alpha, 0.15) * 100%), transparent), transparent 72%),
    var(--bg, #0a0a0e);
  animation: lu-in 0.35s ease-out both;
}
.levelup.is-leaving { animation: lu-out 0.24s ease-in both; }
@keyframes lu-in  { from { opacity: 0; } to { opacity: 1; } }
@keyframes lu-out { to { opacity: 0; } }

.lu-body { position: relative; z-index: 2; width: min(100%, 340px); display: grid; justify-items: center; gap: 14px; text-align: center; animation: lu-shake 0.45s linear 0.85s both; }
/* Light shake on impact, a few pixels only. */
@keyframes lu-shake {
  0%, 100% { transform: none; } 12% { transform: translate(-3px, 2px); } 28% { transform: translate(3px, -2px); }
  44% { transform: translate(-2px, -1px); } 60% { transform: translate(2px, 1px); } 78% { transform: translate(-1px, 0); }
}
.lu-kicker { margin: 0; font-size: 0.78rem; letter-spacing: 0.34em; text-transform: uppercase; color: var(--accent); opacity: 0; animation: lu-up 0.5s ease-out 0.2s both; }

/* Medallion: the ring draws itself, the old mark charges inside it. */
.lu-medal { position: relative; width: 156px; height: 156px; display: grid; place-items: center; font-size: 4.8rem; line-height: 1; margin: 4px 0; }
.lu-medal svg { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }
.lu-medal circle { fill: none; stroke-width: 3; }
.lu-track { stroke: var(--rim, #2b2b38); }
.lu-draw {
  stroke: var(--accent); stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 100;
  filter: drop-shadow(0 0 calc(var(--glow-alpha, 0.15) * 50px) var(--accent));
  animation: lu-draw 0.9s cubic-bezier(0.4, 0, 0.2, 1) 0.3s both;
}
@keyframes lu-draw { to { stroke-dashoffset: 0; } }
.lu-medal > span { position: absolute; }
.lu-old { opacity: 0; animation: lu-old 0.7s ease-in 0.2s both; }
@keyframes lu-old {
  0% { opacity: 0; transform: scale(0.85); }
  25% { opacity: 1; transform: none; }
  55% { opacity: 1; transform: none; }
  100% { opacity: 0; transform: translateY(130px) scale(0.7); }
}
/* The new rank is thrown up from below, overshoots, and settles in a few jolts. */
.lu-new {
  opacity: 0; filter: drop-shadow(0 0 calc(var(--glow-alpha, 0.15) * 100px) var(--accent));
  animation: lu-new 0.75s linear 0.5s both;
}
@keyframes lu-new {
  0%   { opacity: 0; transform: translateY(180px) scale(0.8); animation-timing-function: cubic-bezier(0.1, 0.8, 0.2, 1); }
  45%  { opacity: 1; transform: translateY(-30px) scale(1.08); animation-timing-function: ease-in-out; }
  62%  { transform: translateY(12px) scale(0.97); animation-timing-function: ease-in-out; }
  78%  { transform: translateY(-6px) scale(1.02); animation-timing-function: ease-in-out; }
  90%  { transform: translateY(2px) scale(1); }
  100% { opacity: 1; transform: none; }
}

/* Light: a slow-turning fan of rays behind the medallion, plus the hit. */
.lu-rays {
  position: absolute; left: 50%; top: 36%; width: 820px; height: 820px; margin: -410px 0 0 -410px; border-radius: 50%; pointer-events: none;
  background: repeating-conic-gradient(from 0deg, color-mix(in srgb, var(--accent) 34%, transparent) 0 7deg, transparent 7deg 24deg);
  -webkit-mask-image: radial-gradient(circle, #000 8%, transparent 66%); mask-image: radial-gradient(circle, #000 8%, transparent 66%);
  opacity: 0; scale: 0.5;
  animation: lu-rays-in 1.2s ease-out 0.85s both, lu-spin 14s linear 0.85s infinite;
}
/* A second fan turns the other way, so the light seems to wheel around the rank. */
.lu-rays--b {
  background: repeating-conic-gradient(from 10deg, color-mix(in srgb, var(--accent-2, var(--accent)) 26%, transparent) 0 3deg, transparent 3deg 15deg);
  animation: lu-rays-in-b 1.2s ease-out 0.85s both, lu-spin-rev 22s linear 0.85s infinite;
}
@keyframes lu-rays-in   { to { opacity: calc(0.45 + var(--glow-alpha, 0.15)); scale: 1; } }
@keyframes lu-rays-in-b { to { opacity: calc(0.3 + var(--glow-alpha, 0.15)); scale: 1; } }
@keyframes lu-spin     { to { rotate: 360deg; } }
@keyframes lu-spin-rev { to { rotate: -360deg; } }
.lu-glow {
  position: absolute; left: 50%; top: 36%; width: 380px; height: 380px; margin: -190px 0 0 -190px; border-radius: 50%; pointer-events: none;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 60%, transparent), transparent 65%); opacity: 0;
  animation: lu-flash 0.9s ease-out 0.85s both;
}
@keyframes lu-flash { 0% { opacity: 1; transform: scale(0.3); } 100% { opacity: 0; transform: scale(1.9); } }

.lu-rings, .lu-sparks { position: absolute; left: 50%; top: 36%; width: 0; height: 0; pointer-events: none; }
.lu-rings span {
  position: absolute; left: 0; top: 0; width: 156px; height: 156px; margin: -78px 0 0 -78px;
  border-radius: 50%; border: 2px solid var(--accent); opacity: 0;
  animation: lu-ring 1.5s cubic-bezier(0.12, 0.7, 0.2, 1) 0.85s both;
}
.lu-rings span:nth-child(2) { animation-delay: 1.03s; border-width: 1px; border-color: var(--accent-2, var(--accent)); }
.lu-rings span:nth-child(3) { animation-delay: 1.21s; border-width: 1px; }
@keyframes lu-ring { 0% { opacity: 0.9; transform: scale(0.4); } 100% { opacity: 0; transform: scale(6); } }
.lu-sparks i {
  position: absolute; left: 0; top: 0; width: var(--s); height: var(--s); border-radius: 50%; opacity: 0;
  background: var(--accent-2, var(--accent)); box-shadow: 0 0 8px var(--accent);
  animation: lu-spark 1.3s cubic-bezier(0.1, 0.8, 0.3, 1) calc(0.85s + var(--d)) both;
}
@keyframes lu-spark { 0% { opacity: 1; transform: translate(0, 0); } 100% { opacity: 0; transform: translate(var(--dx), calc(var(--dy) + 40px)) scale(0.2); } }
.lu-embers { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.lu-embers i {
  position: absolute; bottom: -8px; width: var(--s); height: var(--s); border-radius: 50%; opacity: 0;
  background: var(--accent-2, var(--accent)); box-shadow: 0 0 6px var(--accent);
  animation: lu-ember var(--t) ease-in var(--d) infinite;
}
@keyframes lu-ember { 0% { opacity: 0; transform: translate(0, 0); } 15% { opacity: 0.8; } 100% { opacity: 0; transform: translate(var(--x), -85vh); } }

/* The name spells in, letter by letter */
.lu-name {
  margin: 0; text-wrap: balance; color: var(--text, #fff);
  font-family: var(--font-display, inherit); font-weight: var(--display-weight, 700);
  font-size: clamp(1.7rem, calc(2.6rem * var(--display-scale, 1)), 2.8rem);
  line-height: var(--display-line, 1.1); letter-spacing: var(--display-tracking, 0.02em); text-transform: var(--display-transform, none);
  text-shadow: 0 0 calc(var(--glow-alpha, 0.15) * 160px) var(--accent);
}
.lu-name .w { display: inline-block; white-space: nowrap; }
.lu-name .w > span { display: inline-block; opacity: 0; animation: lu-letter 0.45s cubic-bezier(0.2, 1, 0.3, 1) calc(1.0s + var(--i) * 0.045s) both; }
@keyframes lu-letter { from { opacity: 0; transform: translateY(0.5em) scale(1.3); filter: blur(6px); } to { opacity: 1; transform: none; filter: blur(0); } }

.lu-from { margin: 0; font-size: 0.9rem; color: var(--text-dimmer, #8d8d9a); opacity: 0; animation: lu-up 0.45s ease-out 1.5s both; }

.lu-dots { display: flex; flex-wrap: wrap; justify-content: center; gap: 5px; opacity: 0; animation: lu-up 0.45s ease-out 1.65s both; }
.lu-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--rim, #2b2b38); }
.lu-dots i.on { background: var(--accent); }
.lu-dots i.now { animation: lu-dot 0.5s cubic-bezier(0.2, 1.8, 0.3, 1) 1.9s both; box-shadow: 0 0 10px var(--accent); }
@keyframes lu-dot { 0% { transform: scale(0.2); } 60% { transform: scale(2.1); } 100% { transform: scale(1.3); } }

/* Road to the next rank */
.lu-road { width: 100%; display: grid; gap: 8px; opacity: 0; animation: lu-up 0.45s ease-out 1.8s both; }
.lu-bar { height: 6px; border-radius: 999px; background: var(--rim, #2b2b38); overflow: hidden; }
.lu-bar i { display: block; height: 100%; width: 0; border-radius: inherit; background: var(--accent); box-shadow: 0 0 10px var(--accent); animation: lu-fill 0.9s cubic-bezier(0.3, 0.7, 0.2, 1) 2.0s both; }
@keyframes lu-fill { to { width: var(--p); } }
.lu-next { margin: 0; font-size: 0.85rem; color: var(--text-dim, #b9b9c4); }

.lu-btn {
  width: 100%; margin-top: 6px; padding: 14px; border: 0; border-radius: var(--r-md, 12px); cursor: pointer;
  font: inherit; font-family: var(--font-display, inherit); font-weight: var(--display-weight, 700);
  letter-spacing: var(--display-tracking, 0.02em); text-transform: var(--display-transform, none);
  color: var(--on-accent, #fff); background: var(--accent); opacity: 0; animation: lu-up 0.4s ease-out 2.25s both;
}
.lu-btn:active { transform: scale(0.98); }
.lu-btn:focus-visible { outline: 2px solid var(--text, #fff); outline-offset: 3px; }
@keyframes lu-up { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Skip / reduced motion: the end state, nothing moving */
.levelup.is-static *, .levelup.is-static *::before { animation: none !important; }
.levelup.is-static :is(.lu-kicker, .lu-new, .lu-from, .lu-dots, .lu-road, .lu-btn, .lu-name .w > span) { opacity: 1; }
.levelup.is-static .lu-draw { stroke-dashoffset: 0; }
.levelup.is-static .lu-bar i { width: var(--p); }
.levelup.is-static .lu-rays { opacity: 0.45; scale: 1; }
.levelup.is-static .lu-rays--b { opacity: 0.3; }
.levelup.is-static :is(.lu-old, .lu-rings, .lu-sparks, .lu-glow, .lu-embers) { display: none; }
.levelup.is-static .lu-dots i.now { transform: scale(1.3); }
@media (prefers-reduced-motion: reduce) { .levelup, .levelup.is-leaving { animation: none; } }
