/* UI tools 2 (Oct 22, 2026): pixelarticons sizing, floating-ui tooltip, Kenney UI placeholders (CC0), anime.js helpers.
   Loaded after ui.css. Does NOT touch the [data-engine="sd"] battle block. Kenney art here is PLACEHOLDER until final art. */
svg[data-icon^="pixelarticons:"] { image-rendering: pixelated; flex: none; }
.pxi { width: 1.25em; height: 1.25em; vertical-align: -0.22em; }
.ui-title .ico svg { width: 72%; height: 72%; }
.ui-empty .pxi-empty { display: block; width: 48px; height: 48px; margin: 0 auto 6px; color: var(--ink-soft); }
.ui-tab .pxi { width: 16px; height: 16px; margin: 0; } /* .ui-tab is a grid, so the icon sits above the label (narrower tabs on phones) */
.ui-row .opt-ico { width: 22px; height: 22px; color: var(--ink-soft); }
.ui-row.sel .opt-ico { color: var(--ink); }

/* Floating tooltip: Pixel Adventure cream tile as a 9-slice frame. Text is dark ink on cream (>= 12:1). */
.ui-tip { position: fixed; left: 0; top: 0; z-index: 90; pointer-events: none; box-sizing: border-box; width: max-content; max-width: 320px; overflow: hidden;
  padding: 6px 10px; color: var(--ink); background: #fff1d2; font: 700 14px/1.3 var(--ui-family, ui-rounded, "Nunito", "Trebuchet MS", system-ui, sans-serif); -webkit-font-smoothing: antialiased;
  border: 12px solid transparent; border-image: url('../../art/ui/kenney_ui_placeholder/pa_panel_cream.png') 6 fill / 12px / 0 round;
  image-rendering: pixelated; filter: drop-shadow(0 4px 0 rgba(26, 18, 38, .55)); opacity: 0; transition: opacity var(--t-fast) var(--ease-out); }
.ui-tip.show { opacity: 1; }
.ui-tip[hidden] { display: none; }
.ui-tip .tt { display: block; font-size: 15px; font-weight: 800; margin-bottom: 2px; image-rendering: auto; }
.ui-tip .tt[hidden] { display: none; }
.ui-tip .tb { display: block; white-space: pre-line; image-rendering: auto; }
@media (max-height: 430px) { .ui-tip { font-size: 13px; max-width: 280px; } }

/* Kenney UI Pack 2.0 slider + checkbox (smooth vector look, so placeholders only). Rows keep their 44px min height. */
.kui-slider { position: relative; display: inline-block; width: 96px; height: 18px; margin-right: 8px; vertical-align: middle; flex: none;
  background: url('../../art/ui/kenney_ui_placeholder/slide_horizontal_grey.png') center / 100% 8px no-repeat; }
.kui-slider .fill { position: absolute; left: 0; top: 5px; height: 8px; width: var(--v); background: url('../../art/ui/kenney_ui_placeholder/slide_horizontal_color.png') left center / 96px 8px no-repeat; border-radius: 4px; }
.kui-slider .hdl { position: absolute; top: -1px; left: calc(var(--v) - 8px); width: 16px; height: 20px; }
.kui-check { width: 22px; height: 22px; vertical-align: middle; margin-right: 6px; }
.ui-row .price { display: inline-flex; align-items: center; }

/* anime.js: HP drain ghost chunk, level-up popup (timeline replaces the CSS ui-pop keyframes when .ax is set). */
.bar > s.ax-ghost { position: absolute; left: 0; top: 0; bottom: 0; background: #fff1d2; opacity: .85; text-decoration: none; }
.b-lvup.ax { animation: none; }

body.ui-reduce .ui-tip { transition: none; }
@media (prefers-reduced-motion: reduce) { .ui-tip { transition: none; } .bar > s.ax-ghost { display: none; } }
body.ui-reduce .bar > s.ax-ghost { display: none; }

/* Menu motion (Oct 22, 2026): anime.js drives open / back / modal pop once loaded (.ax-m turns the CSS keyframes off; CSS animations
   would otherwise beat its inline styles). Until then the CSS fallback runs in the same snappy 120-220 ms window. Closing clones are inert. */
.ui-stage.in { animation-duration: 200ms; }
.ui-stage.back { animation-duration: 150ms; }
.ui-modal .ui-panel { animation-duration: 180ms; }
.ui-stage.ax-m.in, .ui-stage.ax-m.back, .ui-modal.ax-m .ui-panel { animation: none; }
.ax-out, .ax-out * { pointer-events: none !important; }

/* Capture sequence (Oct 22, 2026; SOUL_PLAYBOOK 5.3, capture_fx.js): PLACEHOLDER parts until the fx_extra sheets land.
   Trainer back view (Cal 'up' frame) holds the crystal up; violet rune beam; light motes (crisp dots, no haze); rune ring
   (6 glyphs, locks into a solid ring); facet petals + Warmth ring on the bloom. Crystal: vertical facets, no middle band.
   Banner: dark ink on sun yellow (>= 12:1). .end = reduced-motion end state (no motion at all). */
.ax-catch { position: absolute; inset: 0; z-index: 6; pointer-events: none; overflow: hidden; }
.ax-catch i { position: absolute; display: block; }
.ax-hold { inset: 0; }
.ax-trainer { background-repeat: no-repeat; image-rendering: pixelated; filter: drop-shadow(0 3px 0 rgba(26, 18, 38, .35)); }
.ax-catch.end .ax-trainer { display: none; }
.ax-gem { width: 30px; height: 48px; margin: -24px 0 0 -15px; background: var(--outline, #1a1226); clip-path: polygon(50% 0, 100% 28%, 100% 72%, 50% 100%, 0 72%, 0 28%); }
.ax-gem > i { inset: 4px; clip-path: polygon(50% 0, 100% 28%, 100% 72%, 50% 100%, 0 72%, 0 28%);
  background: linear-gradient(90deg, #f3e6ff 0 22%, #c79bff 23% 50%, #8f5bf0 51% 78%, #6a3bd1 79%); }
.ax-gem.glow > i { background: linear-gradient(90deg, #fff 0 30%, #e6d2ff 31% 60%, #b98cff 61%); }
.ax-beam { height: 8px; margin-top: -4px; transform-origin: 0 50%; border-radius: 4px;
  background: repeating-linear-gradient(90deg, #f3e6ff 0 6px, #a46bff 6px 12px, #6a3bd1 12px 14px); box-shadow: 0 0 0 2px rgba(106, 59, 209, .45); }
.ax-mote { width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: #fff6d8; box-shadow: 0 0 0 2px #c79bff; }
.ax-runes { border-radius: 50%; }
.ax-runes::before { content: ''; position: absolute; inset: 0; border-radius: 50%; border: 3px dashed rgba(164, 107, 255, .75); }
.ax-runes.lock::before { border: 4px solid #a46bff; box-shadow: 0 0 0 3px #f3e6ff inset; }
.ax-rune { left: 50%; top: 50%; width: 12px; height: 16px; margin: -8px 0 0 -6px; background: #a46bff; border: 2px solid #f3e6ff;
  clip-path: polygon(50% 0, 100% 30%, 70% 100%, 30% 100%, 0 30%); }
.ax-ring { width: 64px; height: 64px; margin: -32px 0 0 -32px; border: 4px solid #ffb347; border-radius: 50%; opacity: 0; box-sizing: border-box; }
.ax-petal { width: 14px; height: 26px; margin: -13px 0 0 -7px; background: linear-gradient(#fff 0 35%, #c79bff 36%); clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%); }
.ax-catch.end .ax-gem, .ax-catch.end .ax-runes { opacity: 1 !important; }
.ax-lit { filter: brightness(2.2) saturate(.2); transition: filter 120ms; }
.ax-caught { position: absolute; left: 0; right: 0; top: 11%; z-index: 7; margin: 0 auto; width: max-content; max-width: 86%; pointer-events: none; text-align: center; box-sizing: border-box;
  padding: 6px 24px 9px; color: var(--ink, #1f1633); background: var(--sun, #ffd23f); border: 4px solid var(--outline, #1a1226); border-radius: 16px;
  box-shadow: 0 5px 0 rgba(26, 18, 38, .55), inset 0 0 0 3px #fff6c9; font: 800 clamp(16px, 3.2vh, 28px)/1.15 var(--ui-family, ui-rounded, "Nunito", "Trebuchet MS", system-ui, sans-serif); }
.ax-caught b { display: block; font-size: 1.35em; letter-spacing: .02em; }
.ax-caught span { display: block; font-size: .78em; }

/* Animator FX art (fx_art.js, Oct 22, 2026): sheet players. Nearest-neighbour, transform-placed, never take input.
   Capture art sits above the trainer and foe and below the HP plates / message box (z-index 6, same as the placeholder). */
.fxa { position: absolute; left: 0; top: 0; display: block; transform-origin: 0 0; background-repeat: no-repeat; image-rendering: pixelated; pointer-events: none; }
.ax-catch.art .ax-gem, .ax-catch.art .ax-beam, .ax-catch.art .ax-runes, .ax-catch.art .ax-ring, .ax-catch.art .ax-petal, .ax-catch.art .ax-mote { display: none; }
.ax-heal { position: fixed; inset: 0; z-index: 40; pointer-events: none; overflow: hidden; }
.ax-evo { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; align-content: center; gap: 2vh; background: rgba(26, 18, 38, .88); }
.ax-evo canvas { width: min(56vh, 70vw); height: min(56vh, 70vw); image-rendering: pixelated; }
.ax-evo-msg { margin: 0; padding: .5em 1em; font: 600 clamp(16px, 3.2vh, 28px)/1.3 var(--font, system-ui); color: #fff7e8; background: #1a1226; border: 3px solid #fff7e8; border-radius: 6px; }
/* capture z-order: the crystal FX always draws over the trainer (hands-hidden pose frames), never clipped to the sprite bounds */
.ax-catch .ax-trainer { z-index: 1; }
.ax-catch .fxa { z-index: 2; }
/* reduced motion: the battle intro bars (.b-bars) and exit flash (.b-flash) are pure transitions. ui.css sets animation:none on .ui-root *, which froze them ON
   screen (bars covered half the battle; flash stuck white). Skip them instead. They are timer-driven, with no animationend wait. */
@media (prefers-reduced-motion: reduce) { .ui-root .b-bars, .ui-root .b-flash { display: none; } }
body.ui-reduce .ui-root .b-bars, body.ui-reduce .ui-root .b-flash { display: none; }
