/* Shared chrome for the Sprite Animations playground — the team-grouped character
* picker, the on-canvas hint, the aimed-attack compass, and the extras list.
* ONE source for the React app (src/views/Movement.jsx) and the Gradio Space
* (tiny-army web/playground.js). It is fully self-contained: the palette is
* scoped on `.movement-view` (copied from the auto-battler theme) so it looks
* identical whether mounted in the app or inside Gradio, with no dependency on
* the host's theme vars or sidebar classes.
*/
.movement-view {
--mv-ink: #141821;
--mv-ink-muted: #6d6a5f;
--mv-ink-faint: #8a8574;
--mv-paper: #f3ebdc;
--mv-paper-2: #ece2cc;
--mv-card: #fbf6ea;
--mv-transmit: #d8271a;
--mv-mono: 'JetBrains Mono', ui-monospace, Menlo, monospace;
--mv-sans: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
display: flex; height: 100%; width: 100%; box-sizing: border-box;
color: var(--mv-ink); font-family: var(--mv-sans);
}
.movement-view * { box-sizing: border-box; }
/* ── Team-grouped character picker ─────────────────────────────────────────── */
.movement-picker {
width: 240px; flex-shrink: 0; border-right: 2px solid var(--mv-ink);
background: var(--mv-paper-2); overflow-y: auto; padding: 12px;
}
/* It's an
, so the host (Gradio's `.prose h2`) blows it up and blackens it —
* defend size + colour with `!important`. */
.movement-picker-title {
margin: 0 0 8px !important; font-family: var(--mv-mono); font-size: 11px !important;
font-weight: 500 !important; letter-spacing: .2em; line-height: 1.4 !important;
text-transform: uppercase; color: var(--mv-transmit) !important;
}
.movement-pack { margin-top: 8px; border-top: 1px solid var(--mv-paper); }
.movement-pack > summary {
cursor: pointer; list-style: none; padding: 6px 4px; font-family: var(--mv-mono);
font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--mv-ink-muted);
}
.movement-pack > summary::-webkit-details-marker { display: none; }
.movement-pack > summary::before { content: '▸ '; color: var(--mv-ink-faint); }
.movement-pack[open] > summary::before { content: '▾ '; }
/* `!important` defends the list against a host (Gradio's `.prose ul/li`) re-adding
* bullets + vertical margins, which spread the rows out and broke the layout. */
.movement-pack ul { list-style: none !important; margin: 0 0 6px !important; padding: 0 !important; }
.movement-pack li { list-style: none !important; margin: 0 !important; padding: 0 !important; display: block !important; text-align: left !important; }
.movement-pack li::marker { content: ""; }
/* `!important` on colour/underline/padding defends against host link + list themes
* (Gradio's `.prose a`) that recolour, underline, and re-pad these rows. */
.movement-char {
display: block; padding: 4px 10px !important; margin: 0 !important; border-radius: 0;
color: var(--mv-ink) !important; text-decoration: none !important; text-align: left !important;
font-family: var(--mv-sans); font-size: 13px; font-weight: 500; line-height: 1.35; cursor: pointer;
}
.movement-char:hover { background: var(--mv-paper); }
.movement-char.active { background: var(--mv-ink); color: var(--mv-card) !important; }
/* ── Stage + canvas ────────────────────────────────────────────────────────── */
.movement-stage { flex: 1; min-width: 0; position: relative; }
.movement-canvas { position: absolute; inset: 0; display: flex; }
.movement-canvas canvas { display: block; width: 100%; height: 100%; }
/* ── On-canvas hint (instructions + toggles) ───────────────────────────────── */
.movement-hint {
position: absolute; bottom: 12px; left: 12px; z-index: 5; pointer-events: none;
font-family: var(--mv-mono); font-size: 10px; letter-spacing: .14em; text-transform: uppercase;
color: var(--mv-ink); background: var(--mv-card); border: 1.5px solid var(--mv-ink);
padding: 4px 8px; box-shadow: 2px 2px 0 var(--mv-ink); max-width: calc(100% - 24px);
}
/* `!important` on color so a host text rule can't make the light glyph match the
* dark chip background (which renders the keys as solid black boxes under Gradio). */
.movement-key {
font-family: var(--mv-mono); font-weight: 700; background: var(--mv-ink) !important;
color: var(--mv-card) !important; padding: 0 4px; border-radius: 2px;
}
.movement-effects-toggle { margin-left: 4px; cursor: pointer; opacity: .8; pointer-events: auto; }
/* ── Aimed-attack debug compass ────────────────────────────────────────────── */
.movement-compass-wrap {
position: absolute; top: 12px; left: 12px; z-index: 5; pointer-events: none;
display: flex; flex-direction: column; gap: 4px;
background: var(--mv-card); border: 1.5px solid var(--mv-ink); box-shadow: 2px 2px 0 var(--mv-ink); padding: 6px;
}
.movement-compass { display: grid; grid-template-columns: repeat(3, 18px); grid-template-rows: repeat(3, 18px); }
.movement-compass span { display: flex; align-items: center; justify-content: center; font-size: 12px; color: var(--mv-ink-faint) !important; }
.movement-compass span.on { color: var(--mv-card) !important; background: var(--mv-ink); border-radius: 3px; }
.movement-compass-label { font-family: var(--mv-mono); font-size: 9px; letter-spacing: .08em; color: var(--mv-ink-muted); text-align: center; }
/* ── Extras list ───────────────────────────────────────────────────────────── */
.movement-extras {
position: absolute; top: 12px; right: 12px; z-index: 5;
display: flex; flex-direction: column; gap: 6px; align-items: flex-end;
max-width: min(360px, 55%);
background: var(--mv-card); border: 1.5px solid var(--mv-ink); box-shadow: 2px 2px 0 var(--mv-ink); padding: 6px 8px;
}
.movement-extras-hint {
font-family: var(--mv-mono); font-size: 9px; letter-spacing: .1em; text-transform: uppercase; color: var(--mv-ink-muted);
}
.movement-extras-list { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; }
/* Host button themes (Gradio's `.gradio-container button`) enlarge these and swap
* the font — defend the type + box props with `!important` so they stay small mono. */
.movement-extra {
font-family: var(--mv-mono) !important; font-size: 9px !important; line-height: 1.2 !important;
letter-spacing: .04em !important; text-transform: uppercase !important; font-weight: 500 !important;
color: var(--mv-ink) !important; background: var(--mv-card) !important; border: 1.5px solid var(--mv-ink) !important;
cursor: pointer; padding: 2px 6px !important; display: inline-flex; align-items: center; gap: 4px;
min-height: 0 !important; border-radius: 0 !important; box-shadow: none !important;
}
.movement-extra:hover { background: var(--mv-paper) !important; }
.movement-extra.active { color: var(--mv-card) !important; background: var(--mv-ink) !important; }
.movement-extra-num { font-weight: 700; opacity: .55; }
.movement-extra-tag { font-size: 7px; letter-spacing: .06em; padding: 0 2px; margin-left: 3px; border: 1px solid currentColor; opacity: .6; vertical-align: middle; }
/* ── Mobile: stack the picker above the stage ──────────────────────────────── */
@media (max-width: 768px) {
.movement-view { flex-direction: column; }
.movement-picker {
width: 100%; max-height: 32%; border-right: 0; border-bottom: 2px solid var(--mv-ink);
}
.movement-extras { max-width: 60%; }
}