/* ============================================================================
 * Image-based Avatar Frames (cosmetics)
 * ----------------------------------------------------------------------------
 * Replaces the legacy CSS-border frames with high-quality generated art.
 * Loaded LAST so it wins over the per-screen .avatar-frame rules (battle.css
 * inset:-3px, store.css inset:-4px) by source order — no !important needed.
 *
 * GEOMETRY: each frame's art (img/frames/<id>.webp) has a transparent, centered
 * avatar opening. scripts/generate-frames.js prints the opening ratio
 * (opening Ø / canvas). PROTRUDING placement (store / profile / spectate):
 *     frame width = avatar / ratio, centered  ->  inset = -((100/ratio) - 100)/2
 * so the opening lines up with the round avatar at ANY size.
 *
 *   frame_gold    ratio 0.544  ->  inset -41.9%
 *   frame_neon    ratio 0.516  ->  inset -46.9%
 *   frame_diamond ratio 0.589  ->  inset -34.9%
 *   frame_fire    ratio 0.454  ->  inset -60.1%   (flames protrude the most)
 *
 * The compact BATTLE avatar fits frames into its slot instead — see the
 * .pp-avatar.has-imgframe rules in battle.css (uses --hole set by battle.js).
 * ========================================================================== */

/* Base positioning — self-contained so image frames work anywhere the class is
   used (battle .pp-avatar, store mock, profile picker) without depending on
   another screen's stylesheet being loaded. */
.avatar-frame { position: absolute; inset: -3px; border-radius: 50%; pointer-events: none; }

.avatar-frame.frame_gold,
.avatar-frame.frame_neon,
.avatar-frame.frame_diamond,
.avatar-frame.frame_fire,
.avatar-frame.frame_season1_champion,
.avatar-frame.frame_season1_top10,
.avatar-frame.frame_genesis_pass,
.avatar-frame.frame_koth_legend,
.avatar-frame.frame_whale,
.avatar-frame.frame_fortune {
    border: none;
    box-shadow: none;
    animation: none;
    /* reset the legacy season-frame mask (battle.css uses -webkit-mask +
       mask-composite:exclude for champion/top10) — it would clip the image. */
    -webkit-mask: none;
    mask: none;
    background-position: center;
    background-size: contain;
    background-repeat: no-repeat;
    filter: drop-shadow(0 3px 8px rgba(0, 0, 0, .45));
}

/* Paid */
.avatar-frame.frame_gold    { inset: -41.9%; background-image: url('/img/frames/frame_gold.webp'); }
.avatar-frame.frame_neon    { inset: -46.9%; background-image: url('/img/frames/frame_neon.webp'); }
.avatar-frame.frame_diamond { inset: -34.9%; background-image: url('/img/frames/frame_diamond.webp'); }
.avatar-frame.frame_fire    { inset: -60.1%; background-image: url('/img/frames/frame_fire.webp'); }
/* Earned (free) */
.avatar-frame.frame_season1_champion { inset: -43.5%; background-image: url('/img/frames/frame_season1_champion.webp'); }
.avatar-frame.frame_season1_top10 { inset: -49.8%; background-image: url('/img/frames/frame_season1_top10.webp'); }
.avatar-frame.frame_genesis_pass  { inset: -47.7%; background-image: url('/img/frames/frame_genesis_pass.webp'); }
.avatar-frame.frame_koth_legend   { inset: -51.9%; background-image: url('/img/frames/frame_koth_legend.webp'); }
.avatar-frame.frame_whale         { inset: -37.9%; background-image: url('/img/frames/frame_whale.webp'); }
/* Wheel-exclusive — hole ratio 0.550 (scripts/generate-frames.js 1524) */
.avatar-frame.frame_fortune       { inset: -40.9%; background-image: url('/img/frames/frame_fortune.webp'); }

/* ── Animated frames (glow only — no layout shift, GPU-cheap) ──────────────
   Champion (apex): pulsing gold->cyan brand aura. Fire: warm flicker.
   Placed after the per-frame rules so `animation` wins by source order.
   Honors reduced-motion. */
@media (prefers-reduced-motion: no-preference) {
    .avatar-frame.frame_season1_champion { animation: champAura 2.6s ease-in-out infinite; }
    .avatar-frame.frame_fire             { animation: fireFlicker 1.4s ease-in-out infinite alternate; }
}
@keyframes champAura {
    0%, 100% { filter: drop-shadow(0 3px 8px rgba(0,0,0,.45)) drop-shadow(0 0 5px rgba(255,202,92,.55)); }
    50%      { filter: drop-shadow(0 3px 8px rgba(0,0,0,.45)) drop-shadow(0 0 15px rgba(70,224,255,.80)); }
}
@keyframes fireFlicker {
    0%   { filter: drop-shadow(0 3px 8px rgba(0,0,0,.45)) drop-shadow(0 0 5px rgba(255,120,20,.55)) brightness(1); }
    100% { filter: drop-shadow(0 3px 8px rgba(0,0,0,.45)) drop-shadow(0 0 16px rgba(255,70,10,.85)) brightness(1.08); }
}

/* ── Profile "Avatar Frame" picker swatches — show the real frame art ──────
   Uses new classes (.frame-swatch/.fp-mock) so it doesn't collide with the
   legacy .frame-preview rules. .fp-mock is the placeholder avatar; the
   .avatar-frame inside protrudes per-frame via the inset rules above. */
.frame-swatch {
    display: flex; align-items: center; justify-content: center;
    min-height: 80px; margin-bottom: 2px;
}
.fp-mock {
    position: relative; width: 36px; height: 36px; border-radius: 50%;
    background: radial-gradient(circle at 50% 35%, rgba(70, 224, 255, .14), rgba(8, 12, 22, .92));
}
.frame-swatch.no-frame { min-height: 80px; }
.frame-swatch.no-frame .avatar-silhouette-mini { width: 40px; height: 40px; }
