/* Random Encounter — mobile-first portrait JRPG.
   Pillarboxed on desktop; full-screen on mobile. */

:root {
    --bg-deep: #0e0820;
    --bg-frame: #1a1224;
    --bg-panel: #221a36;
    --bg-panel-2: #2c2342;
    --border: #4a3a6a;
    --border-bright: #6a539a;
    --border-dim: #2c2253;
    --text: #f0e8ff;
    --text-dim: #b3a5d4;
    --text-muted: #847497;
    --accent: #ffd24a;
    --accent-2: #ff8fc4;   /* magenta secondary — encounter stinger, departure lines, brackets */
    --hp: #4ade80;
    --hp-low: #f87171;
    --mp: #60a5fa;
    --ap: #ff9447;
    --xp: #fbbf24;
    --gold: #facc15;
    --common: #a8a8a8;
    --uncommon: #4ade80;
    --rare: #60a5fa;
    --legendary: #f59e0b;
    --danger: #ef4444;
    --crit-orange: #ff8a4a;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    /* Firefox: thin scrollbar with themed colors. WebKit gets the pseudo-element
       rules below for the same look in Chrome/Safari. */
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

/* WebKit (Chrome, Safari, Edge): thin themed scrollbar. */
*::-webkit-scrollbar {
    width: 6px;
    height: 6px;
}

*::-webkit-scrollbar-track {
    background: transparent;
}

*::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 3px;
}

*::-webkit-scrollbar-thumb:hover {
    background: var(--border-bright);
}

*::-webkit-scrollbar-corner {
    background: transparent;
}

html, body {
    height: 100%;
    overflow: hidden;
    background: var(--bg-deep);
    color: var(--text);
    font-family: 'VT323', 'Courier New', monospace;
    font-size: 20px;
    line-height: 1.2;
    -webkit-font-smoothing: antialiased;
    user-select: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: transparent;
    touch-action: manipulation;
}

input, textarea {
    user-select: text;
    -webkit-user-select: text;
}

#app {
    display: flex;
    align-items: stretch;
    justify-content: center;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    background: var(--bg-deep);
    /* Top padding clears the dynamic island / status bar in both modes.
       Bottom padding clears the iOS Safari URL bar in browser mode; in
       standalone mode there's no chrome there, so we drop it (see below). */
    padding-top: env(safe-area-inset-top);
    padding-bottom: env(safe-area-inset-bottom);
    box-sizing: border-box;
}

/* PWA standalone (Add to Home Screen): no URL bar, no browser chrome at all.
   The home indicator is a translucent visual overlay that doesn't block
   taps, so let the content fill all the way to the bottom. */
@media (display-mode: standalone) {
    #app {
        padding-bottom: 0;
    }
}

.screen-frame {
    /* no-op; #app uses #app's own rules */
}

.screen {
    width: 100%;
    max-width: 480px;
    height: 100%;
    background: var(--bg-frame);
    border-left: 2px solid var(--border);
    border-right: 2px solid var(--border);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    position: relative;
    flex: 0 1 480px;
}

@media (max-width: 480px) {
    .screen {
        border-left: none;
        border-right: none;
    }
}

/* ───── Frame primitive ─────
   Ornate double-line frame with a corner diamond at each corner. Use anywhere
   we'd otherwise have a plain bordered panel. Accent color via --frame-accent
   (default = border). Optional title chip via a child `.frame-title` element. */

:root {
    /* 8×8 SVG diamond, fill = currentColor of the bg-image trick (we set fill
       via a per-class data URI override below). Default diamond is --border. */
    --diamond-border: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8'><polygon points='4,0 8,4 4,8 0,4' fill='%234a3a6a' stroke='rgba(0,0,0,0.6)' stroke-width='0.5'/></svg>");
    --diamond-accent: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8'><polygon points='4,0 8,4 4,8 0,4' fill='%23ffd24a' stroke='rgba(0,0,0,0.6)' stroke-width='0.5'/></svg>");
    --diamond-magenta: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8'><polygon points='4,0 8,4 4,8 0,4' fill='%23ff8fc4' stroke='rgba(0,0,0,0.6)' stroke-width='0.5'/></svg>");
    --diamond-danger: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='8' height='8'><polygon points='4,0 8,4 4,8 0,4' fill='%23ef4444' stroke='rgba(0,0,0,0.6)' stroke-width='0.5'/></svg>");
}

.frame {
    position: relative;
    border: 2px solid var(--border);
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.025), rgba(0, 0, 0, 0.18)),
        var(--bg-panel);
    box-shadow: inset 0 0 14px rgba(0, 0, 0, 0.35);
    padding: 10px 12px;
}

/* Corner diamonds — 4 of them, one per corner, via a single pseudo-element with
   4 stacked background-image SVGs. The pseudo is `inset: -5px` so the diamonds
   straddle the border, giving the classic ornate-frame look. */
.frame::before {
    content: "";
    position: absolute;
    inset: -5px;
    pointer-events: none;
    background-image: var(--diamond-border), var(--diamond-border), var(--diamond-border), var(--diamond-border);
    background-repeat: no-repeat;
    background-position: top left, top right, bottom left, bottom right;
    background-size: 8px 8px;
}

.frame.accent  { border-color: var(--accent); }
.frame.accent::before  { background-image: var(--diamond-accent), var(--diamond-accent), var(--diamond-accent), var(--diamond-accent); }

.frame.magenta { border-color: var(--accent-2); }
.frame.magenta::before { background-image: var(--diamond-magenta), var(--diamond-magenta), var(--diamond-magenta), var(--diamond-magenta); }

.frame.danger  { border-color: var(--danger); }
.frame.danger::before  { background-image: var(--diamond-danger), var(--diamond-danger), var(--diamond-danger), var(--diamond-danger); }

.frame.flat {
    /* compact variant — no inset depth shadow, no gradient fill */
    background: var(--bg-panel);
    box-shadow: none;
}

/* Tiny title chip that sits straddling the top border. Looks like a label
   stitched into the chrome. Place as first child of a .frame. */
.frame-title {
    position: absolute;
    top: -7px;
    left: 14px;
    background: var(--bg-frame);
    padding: 0 8px;
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    color: var(--accent);
    letter-spacing: 1px;
    line-height: 1;
    z-index: 1;
}

.frame-title.magenta { color: var(--accent-2); }
.frame-title.danger  { color: var(--danger); }

/* Ornament rule — short line + diamonds + short line. Used between blocks
   on the title screen and as a divider in dossier panels. */
.ornament-rule {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin: 6px 0;
}

.ornament-rule .ornament-line {
    height: 1px;
    width: 40px;
    background: linear-gradient(to right, transparent, var(--border) 30%, var(--border) 70%, transparent);
}

.ornament-rule .ornament-diamond {
    width: 6px;
    height: 6px;
    transform: rotate(45deg);
    background: var(--accent);
}

.ornament-rule .ornament-diamond.magenta { background: var(--accent-2); }

/* ───── Reusable web components ─────
   Light DOM custom elements (see components.js). The CSS rules here style
   the inner shape they build. */

/* <re-class-icon> — emoji sprite for a class. Size cascades from parent
   context via font-size; no per-instance sizing inside the component. */
re-class-icon {
    display: inline-block;
    font-style: normal;
    line-height: 1;
    text-align: center;
}

/* <re-bar> — label | track[fill] | numbers, in a single row */
re-bar {
    display: grid;
    grid-template-columns: 26px 1fr auto;
    align-items: center;
    gap: 8px;
    line-height: 1;
}

re-bar .re-bar-label {
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    line-height: 1;
}

re-bar .re-bar-track {
    height: 8px;
    background: var(--bg-deep);
    border: 1px solid var(--border);
}

re-bar .re-bar-fill {
    height: 100%;
    transition: width 220ms ease-out;
}

re-bar .re-bar-num {
    font-family: 'VT323', monospace;
    font-size: 16px;
    line-height: 1;
    min-width: 56px;
    text-align: right;
}

re-bar[kind="hp"] .re-bar-label,
re-bar[kind="hp"] .re-bar-fill,
re-bar[kind="hp"] .re-bar-num { color: var(--hp); }
re-bar[kind="hp"] .re-bar-fill { background: var(--hp); }

re-bar[kind="mp"] .re-bar-label,
re-bar[kind="mp"] .re-bar-fill,
re-bar[kind="mp"] .re-bar-num { color: var(--mp); }
re-bar[kind="mp"] .re-bar-fill { background: var(--mp); }

re-bar[kind="xp"] .re-bar-label,
re-bar[kind="xp"] .re-bar-fill,
re-bar[kind="xp"] .re-bar-num { color: var(--xp); }
re-bar[kind="xp"] .re-bar-fill { background: var(--xp); }

re-bar[kind="ap"] .re-bar-label,
re-bar[kind="ap"] .re-bar-fill,
re-bar[kind="ap"] .re-bar-num { color: var(--ap); }
re-bar[kind="ap"] .re-bar-fill { background: var(--ap); }

/* <re-bar compact> — thin fill bar with no label or numeric readout, sized
   for compact contexts (enemy HP indicator under the sprite). */
re-bar[compact] {
    grid-template-columns: 1fr;
    width: 80px;
}

re-bar[compact] .re-bar-label,
re-bar[compact] .re-bar-num { display: none; }

re-bar[compact] .re-bar-track { height: 4px; }

/* <re-level-chip> — small "Lv N" pill, status-driven coloring */
re-level-chip {
    display: inline-block;
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    line-height: 1;
    padding: 3px 6px;
    border: 1px solid var(--border);
    background: rgba(0, 0, 0, 0.25);
    color: var(--text-dim);
    border-radius: 2px;
    letter-spacing: 0.5px;
    white-space: nowrap;
}

re-level-chip[data-status="up"] {
    color: var(--accent);
    border-color: var(--accent);
    background: rgba(255, 210, 74, 0.12);
}

/* Press Start 2P's "→" glyph sits low on its em-box; nudge it up so the
   level-up pill reads as vertically centered with the surrounding text. */
re-level-chip .arr {
    display: inline-block;
    transform: translateY(-2px);
}

re-level-chip[data-status="ko"] {
    color: #fff;
    background: var(--danger);
    border-color: var(--danger);
}

/* Difficulty variants for enemy level chips. */
re-level-chip[data-status="easy"] {
    color: var(--text-muted);
}

re-level-chip[data-status="hard"] {
    color: #ffc4c4;
    border-color: var(--hp-low);
}

re-level-chip[data-status="danger"] {
    color: #fff;
    background: var(--danger);
    border-color: var(--danger);
}

/* <re-character-card> — sprite | info(name+chip+bars), variant-driven layout */
.re-character-card {
    display: grid;
    grid-template-columns: 36px 1fr;
    gap: 10px;
    align-items: center;
    padding: 6px 10px;
    background: var(--bg-panel);
    border: 2px solid var(--border);
    transition: border-color 100ms, background 100ms, transform 60ms;
    min-width: 0;
}

.re-character-card.dead {
    opacity: 0.45;
}

.re-character-card.active {
    border-color: var(--accent);
    background: var(--bg-panel-2);
}

.re-character-card.hit {
    animation: shake 250ms;
}

.re-character-card .rcc-sprite {
    font-size: 32px;
    line-height: 1;
    text-align: center;
}

.re-character-card .rcc-info {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.re-character-card .rcc-name-row {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    gap: 8px;
}

.re-character-card .rcc-name {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--text-dim);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.re-character-card .rcc-bars {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

/* Variant tweaks */

/* Battle: more compact label cells since bars are stacked tight */
.re-character-card[data-variant="battle"] .re-bar-label {
    min-width: 0;
    font-size: 8px;
}

.re-character-card[data-variant="battle"] .re-bar-num {
    font-size: 16px;
    min-width: 56px;
}

/* Merchant: smaller everything for the row-of-4 status strip + role-color
   left stripe (component sets --role from the character's class). */
.re-character-card[data-variant="merchant"] {
    padding: 6px 10px 6px 12px;
    grid-template-columns: 22px 1fr;
    gap: 8px;
    background: var(--bg-panel);
    border: none;
    box-shadow: inset 3px 0 0 var(--role, var(--border));
}

.re-character-card[data-variant="merchant"].dead {
    box-shadow: inset 3px 0 0 var(--danger);
}

.re-character-card[data-variant="merchant"] .rcc-sprite {
    font-size: 20px;
}

.re-character-card[data-variant="merchant"] .rcc-name {
    font-size: 10px;
}

.re-character-card[data-variant="merchant"] re-bar {
    grid-template-columns: 20px 1fr auto;
    gap: 6px;
}

.re-character-card[data-variant="merchant"] re-bar .re-bar-track { height: 6px; }
.re-character-card[data-variant="merchant"] re-bar .re-bar-num { font-size: 14px; min-width: 50px; }

/* Target picker: lives inside an .action-btn wrapper (for keyboard/focus),
   so the card itself doesn't need its own border/background — would
   double-frame the chrome. */
.re-character-card[data-variant="target"] {
    border: none;
    background: transparent;
    padding: 0;
    cursor: pointer;
}

/* ───── Title font for headers ───── */
.pixel-title {
    font-family: 'Press Start 2P', monospace;
    font-size: 14px;
    line-height: 1.6;
    letter-spacing: 0.5px;
}

.pixel-small {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    line-height: 1.6;
    letter-spacing: 0.5px;
}

/* ───── Generic buttons (menu items) ───── */
.btn {
    appearance: none;
    background: var(--bg-panel);
    border: 2px solid var(--border);
    color: var(--text);
    font-family: 'VT323', monospace;
    font-size: 22px;
    padding: 12px 14px;
    cursor: pointer;
    transition: background 80ms, border-color 80ms, transform 60ms;
    text-align: center;
    min-height: 48px;
}

.btn:hover, .btn:focus {
    background: var(--bg-panel-2);
    border-color: var(--border-bright);
    outline: none;
}

.btn:active {
    transform: translateY(1px);
}

.btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}

/* Primary button — yellow fill, dark plum text, soft glow. Use for the
   one "go" action per screen (Continue, Get Grinding, Tap to claim, etc).
   Must come AFTER .btn so its property values win on same-specificity. */
.btn-primary {
    background: var(--accent);
    color: #1a1224;
    border: 2px solid var(--accent);
    font-family: 'Press Start 2P', monospace;
    font-size: 12px;
    letter-spacing: 1px;
    text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.15);
    box-shadow:
        inset 0 -3px 0 rgba(0, 0, 0, 0.18),
        0 0 14px rgba(255, 210, 74, 0.30);
    transition: background 80ms, box-shadow 120ms, transform 60ms;
}

.btn-primary:hover, .btn-primary:focus {
    background: #ffe07a;
    border-color: var(--accent);
    box-shadow:
        inset 0 -3px 0 rgba(0, 0, 0, 0.18),
        0 0 20px rgba(255, 210, 74, 0.45);
    outline: none;
}

.btn-primary:active {
    box-shadow: inset 0 1px 0 rgba(0, 0, 0, 0.25);
    transform: translateY(1px);
}

/* ───── Title screen ───── */
.title-screen {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 24px;
    gap: 18px;
    text-align: center;
    background: radial-gradient(ellipse at center, transparent 40%, rgba(0, 0, 0, 0.55) 100%);
}

/* CRT-treated wordmark. The one place we break our otherwise crisp style.
   Five layered children: halo, base text, scanlines, sweep highlight, corners. */
.title-wordmark {
    position: relative;
    padding: 10px 18px;
    margin: 0 auto 4px;
    display: inline-block;
}

.title-wm-halo {
    position: absolute;
    inset: -20px;
    /* Two layered halos: a pink-magenta wash + a tighter yellow inner glow so
       the wordmark looks like it's actually emitting light. */
    background:
        radial-gradient(ellipse at center, rgba(255, 210, 74, 0.28), transparent 55%),
        radial-gradient(ellipse at center, rgba(255, 143, 196, 0.32), transparent 70%);
    filter: blur(8px);
    pointer-events: none;
}

.title-wm-text {
    position: relative;
    font-family: 'Press Start 2P', monospace;
    font-size: 26px;
    line-height: 1.18;
    letter-spacing: 1px;
    color: var(--accent);
    /* Layered glow: inner-tight + outer-soft, both yellow. The displacement
       drop-shadow stays for legibility against the plum background. */
    text-shadow:
        3px 3px 0 #6b3a14,
        4px 4px 0 rgba(0, 0, 0, 0.55),
        0 0 8px rgba(255, 224, 122, 0.7),
        0 0 22px rgba(255, 210, 74, 0.55),
        0 0 38px rgba(255, 210, 74, 0.35);
}

.title-wm-scanlines {
    position: absolute;
    inset: 0;
    /* Scanline cycle tuned by eye to the font's pixel grid (Press Start 2P
       at 26px, ~2.6 device-px per design-pixel). The 3.3px cycle with a
       soft fade into black puts a scan line in each row's bottom gap. */
    background: repeating-linear-gradient(to bottom,
        transparent 0 2px,
        rgba(0, 0, 0, 0.28) 3.3px 2px);
    mix-blend-mode: multiply;
    pointer-events: none;
}

.title-wm-sweep {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom,
        transparent 0 38%,
        rgba(255, 255, 255, 0.10) 40% 42%,
        transparent 44% 100%);
    mix-blend-mode: screen;
    pointer-events: none;
}

.title-wm-corner {
    position: absolute;
    width: 7px;
    height: 7px;
    border: 2px solid var(--accent-2);
    opacity: 0.7;
}

.title-wm-corner.tl { top: 0; left: 0; border-right: none; border-bottom: none; }
.title-wm-corner.tr { top: 0; right: 0; border-left: none; border-bottom: none; }
.title-wm-corner.bl { bottom: 0; left: 0; border-right: none; border-top: none; }
.title-wm-corner.br { bottom: 0; right: 0; border-left: none; border-top: none; }

.title-screen .subtitle {
    color: var(--text-dim);
    font-family: 'VT323', monospace;
    font-size: 22px;
    font-style: italic;
    max-width: 340px;
    line-height: 1.25;
}

.title-screen .menu {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    max-width: 280px;
    margin-top: 4px;
}

.title-screen .menu .btn {
    width: 100%;
}

.title-save-row {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 8px;
    margin-top: 4px;
    font-family: 'VT323', monospace;
    font-size: 18px;
    color: var(--text-muted);
}

.title-save-label {
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    color: var(--text-dim);
    letter-spacing: 1px;
}

.title-save-sep {
    width: 4px;
    height: 4px;
    transform: rotate(45deg);
    background: var(--border-bright);
}

.title-screen .flavor {
    position: absolute;
    bottom: 18px;
    left: 0;
    right: 0;
    text-align: center;
    color: var(--text-muted);
    font-family: 'VT323', monospace;
    font-size: 16px;
}

/* ───── Cheat menu (Konami easter egg on title) ───── */

.cheat-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.75);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 999;
    padding: 20px;
}

.cheat-modal {
    background: var(--bg-deep);
    border: 2px solid var(--accent);
    border-radius: 4px;
    padding: 20px;
    max-width: 360px;
    width: 100%;
    box-shadow: 0 0 24px rgba(255, 210, 74, 0.3);
}

.cheat-title {
    font-family: 'Press Start 2P', monospace;
    font-size: 12px;
    color: var(--accent);
    text-align: center;
    margin-bottom: 4px;
}

.cheat-subtitle {
    font-family: 'VT323', monospace;
    font-size: 16px;
    color: var(--text-muted);
    text-align: center;
    margin-bottom: 16px;
    font-style: italic;
}

.cheat-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
    gap: 12px;
}

.cheat-row.checkbox {
    justify-content: flex-start;
    cursor: pointer;
}

.cheat-label {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    color: var(--text);
}

.cheat-input {
    flex: 0 0 100px;
    background: rgba(0, 0, 0, 0.4);
    border: 1px solid var(--border);
    color: var(--text);
    font-family: 'VT323', monospace;
    font-size: 18px;
    padding: 6px 8px;
    text-align: right;
    border-radius: 2px;
}

.cheat-input:focus {
    outline: none;
    border-color: var(--accent);
}

.cheat-check {
    width: 18px;
    height: 18px;
    accent-color: var(--accent);
    cursor: pointer;
}

.cheat-buttons {
    display: flex;
    gap: 10px;
    margin-top: 18px;
}

.cheat-buttons .btn {
    flex: 1;
}

/* ───── Party creation ───── */
.create-screen {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 12px 14px;
    gap: 10px;
    overflow-y: auto;
}

.create-screen h2 {
    font-family: 'Press Start 2P', monospace;
    font-size: 13px;
    color: var(--accent);
    text-align: center;
    margin-bottom: 2px;
}

/* Slot tabs at top */
.create-screen .slot-tabs {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
}

.create-screen .slot-tab {
    background: var(--bg-panel);
    border: 2px solid var(--border);
    padding: 6px 4px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    color: var(--text);
    transition: all 80ms;
    min-width: 0;
}

.create-screen .slot-tab:hover {
    border-color: var(--border-bright);
}

.create-screen .slot-tab.active {
    border-color: var(--accent);
    background: rgba(255, 210, 74, 0.12);
}

.create-screen .slot-tab .slot-num {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    color: var(--text-muted);
}

.create-screen .slot-tab .slot-sprite {
    font-size: 26px;
    line-height: 1;
}

.create-screen .slot-tab .slot-name {
    font-family: 'VT323', monospace;
    font-size: 14px;
    color: var(--text);
    line-height: 1.1;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;
    text-align: center;
}

.create-screen .slot-tab .slot-class {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    color: var(--text-dim);
    letter-spacing: 0.5px;
}

.create-screen .slot-tab.active .slot-class {
    color: var(--accent);
}

/* Class picker row */
.create-screen .class-picker-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
}

.create-screen .class-card {
    background: var(--bg-panel-2);
    border: 2px solid var(--border);
    padding: 6px 2px;
    cursor: pointer;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    color: var(--text);
    transition: all 80ms;
}

.create-screen .class-card .emoji {
    font-size: 24px;
    line-height: 1;
}

.create-screen .class-card .name {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    color: var(--text-dim);
}

.create-screen .class-card.selected {
    border-color: var(--accent);
    background: rgba(255, 210, 74, 0.15);
}

.create-screen .class-card.selected .name {
    color: var(--accent);
}

/* Class details panel — uses `.frame` for the chrome, just adds layout.
   Extra top margin gives the DOSSIER title chip space to sit above the class
   palette without crowding it; extra top padding lets the header breathe under
   the chip. */
.create-screen .class-info {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin-top: 10px;
    padding: 18px 12px 12px;
}

.class-info-header {
    display: flex;
    align-items: center;
    gap: 10px;
}

.class-info-header .sprite {
    font-size: 32px;
    line-height: 1;
}

.class-info-title .name {
    font-family: 'Press Start 2P', monospace;
    font-size: 12px;
    color: var(--accent);
}

/* Optional Lv N pill, only shown when starting above L1 (cheat menu). */
.class-info-title re-level-chip {
    margin-bottom: 4px;
}

.class-info-title .blurb {
    font-family: 'VT323', monospace;
    font-size: 17px;
    color: var(--text-dim);
    font-style: italic;
    margin-top: 3px;
    line-height: 1.15;
}

.class-stats {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 4px;
}

.class-stat {
    background: var(--bg-deep);
    border: 1px solid var(--border);
    padding: 4px 6px;
    text-align: center;
}

.class-stat .stat-label {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    color: var(--text-muted);
    letter-spacing: 0.5px;
}

.class-stat .stat-val {
    font-family: 'VT323', monospace;
    font-size: 16px;
    color: var(--text);
    line-height: 1.1;
}

.class-stat.hp  .stat-val, .class-stat.hp  .stat-label { color: var(--hp); }
.class-stat.mp  .stat-val, .class-stat.mp  .stat-label { color: var(--mp); }
.class-stat.ap  .stat-val, .class-stat.ap  .stat-label { color: var(--ap); }
.class-stat.atk .stat-val { color: #f5b46a; }
.class-stat.def .stat-val { color: #a8c4ff; }
.class-stat.mag .stat-val { color: #d29bff; }
.class-stat.res .stat-val { color: #9bd0ff; }
.class-stat.spd .stat-val { color: #82e6c1; }
.class-stat.lck .stat-val { color: var(--accent); }

.class-block-label {
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    color: var(--text-dim);
    margin-bottom: 2px;
}

.class-gear .gear-line {
    display: flex;
    justify-content: space-between;
    gap: 8px;
    font-size: 15px;
    color: var(--text);
    padding: 1px 0;
}

.class-gear .gear-stats {
    color: var(--text-muted);
    font-size: 16px;
}

.class-skills .skill-line {
    display: grid;
    grid-template-columns: 38px max-content 1fr;
    gap: 8px;
    font-size: 15px;
    color: var(--text-dim);
    padding: 1px 0;
    align-items: baseline;
}

.class-skills .skill-line.no-lvl {
    grid-template-columns: max-content 1fr;
}

.class-block-label .scale-hint {
    color: var(--text-muted);
    font-family: 'VT323', monospace;
    font-size: 16px;
    text-transform: none;
    font-weight: normal;
}

.class-skills .skill-lvl {
    color: var(--accent);
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
}

.class-skills .skill-name {
    color: var(--text);
    font-size: 15px;
}

.class-skills .skill-desc {
    color: var(--text-muted);
    font-size: 16px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

/* Name input + start */
.create-screen .name-row {
    display: flex;
    gap: 6px;
}

.create-screen input[type="text"] {
    flex: 1;
    background: var(--bg-deep);
    border: 2px solid var(--border);
    color: var(--text);
    padding: 8px 10px;
    font-family: 'VT323', monospace;
    font-size: 20px;
}

.create-screen input[type="text"]:focus {
    outline: none;
    border-color: var(--accent);
}

.create-screen .roll-name {
    padding: 6px 10px;
    font-size: 18px;
}

.create-screen .start-row {
    margin-top: auto;
    padding-top: 8px;
}

.create-screen .begin-grinding {
    width: 100%;
    padding: 14px 18px;
    font-size: 13px;
    letter-spacing: 1.5px;
}

/* ───── Battle screen ─────
   Four rows, top to bottom: LOG / ENEMIES / PARTY / ACTIONS. Each of the
   first three carries a title chip on its top border, giving the screen
   the same chrome rhythm as the rest of the game. */
.battle-screen {
    display: grid;
    /* LOG: takes whatever's left, scrolls on overflow.
       ENEMIES: just big enough for the sprite + chip + bar stack.
       PARTY: 310px to fit 4 character cards (~70px each) + gaps + padding.
       ACTIONS: trimmed to fit 5 buttons in a 3+2 grid without slack.
       Totals tuned so LOG stays usable on iPhone 17 Pro in Safari (where
       the URL bar and dynamic island both bite into available height). */
    grid-template-rows: minmax(0, 1fr) 160px 310px 160px;
    height: 100%;
    background: linear-gradient(180deg, #2a1a3a 0%, #1a1224 50%, #221a36 100%);
}

/* LOG pane wrapper — provides the chip's positioning context with no
   overflow constraints, so the chip can extend above the border line. */
.log-zone {
    position: relative;
    margin-top: 14px;
    padding-top: 0;
    border-top: 1px solid var(--border);
    border-bottom: 2px solid var(--border);
    min-height: 0;
    display: flex;
    flex-direction: column;
}

.enemy-zone {
    position: relative;  /* anchor for ENEMIES chip */
    display: flex;
    flex-direction: column;
    justify-content: center;
    border-bottom: 2px solid var(--border);
    /* No border-top: .log-zone's border-bottom serves as the divider, and
       the ENEMIES chip at top:-7px straddles it. */
    background: radial-gradient(ellipse at center bottom, rgba(255,210,74,0.06), transparent 60%);
    min-height: 0;
    /* No overflow:hidden — the ENEMIES chip is positioned at top:-7px and
       would otherwise be clipped. Enemy bob/shake animations stay within
       their own cells. */
}

.enemy-row {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    justify-content: space-around;
    padding: 8px 12px 10px;
    min-height: 0;
}

/* <re-enemy-card> — sprite + name + level chip + element tags + thin HP bar.
   Class hooks: .hit / .attacking / .dead / .elite / .targetable / .focus
   are added externally by battle.js for animations and targeting state. */
.re-enemy-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    cursor: pointer;
    padding: 4px 6px;
    border: 2px solid transparent;
    transition: all 100ms;
    max-width: 120px;
}

.re-enemy-card.targetable:hover, .re-enemy-card.targetable.focus {
    border-color: var(--accent);
    background: rgba(255,210,74,0.08);
}

.re-enemy-card.dead {
    opacity: 0.25;
    pointer-events: none;
}

.re-enemy-card.hit {
    animation: shake 250ms;
}

.re-enemy-card.attacking {
    animation: lunge 350ms;
}

@keyframes shake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-6px); }
    40% { transform: translateX(6px); }
    60% { transform: translateX(-4px); }
    80% { transform: translateX(4px); }
}

@keyframes lunge {
    0%, 100% { transform: translateY(0); }
    40% { transform: translateY(10px) scale(1.1); }
}

.re-enemy-card .rec-sprite {
    font-size: 54px;
    line-height: 1;
    filter: drop-shadow(0 4px 0 rgba(0,0,0,0.6));
    animation: bob 2.6s ease-in-out infinite;
    transform-origin: center bottom;
}

/* Stagger durations + offsets so a row of enemies doesn't bob in lockstep. */
.enemy-row re-enemy-card:nth-child(2) .rec-sprite { animation-duration: 3.0s; animation-delay: -0.7s; }
.enemy-row re-enemy-card:nth-child(3) .rec-sprite { animation-duration: 2.3s; animation-delay: -1.4s; }
.enemy-row re-enemy-card:nth-child(4) .rec-sprite { animation-duration: 2.8s; animation-delay: -0.4s; }

.re-enemy-card.dead .rec-sprite {
    animation: none;
    filter: grayscale(1) drop-shadow(0 4px 0 rgba(0,0,0,0.4));
}

@keyframes bob {
    0%, 100% { transform: translateY(0); }
    50%      { transform: translateY(-7px); }
}

.re-enemy-card .rec-name {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--text-dim);
    text-align: center;
}

.re-enemy-card.elite .rec-name {
    color: var(--legendary);
}

.re-enemy-card .rec-tags {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    justify-content: center;
    min-height: 14px;
}

.re-enemy-card .rec-tags .tag {
    font-family: 'Press Start 2P', monospace;
    font-size: 8px;
    padding: 2px 5px;
    border-radius: 2px;
    line-height: 1;
}

.re-enemy-card .rec-tags .tag.weak {
    background: rgba(248, 113, 113, 0.25);
    color: #ffc4c4;
    border: 1px solid var(--hp-low);
}

.re-enemy-card .rec-tags .tag.resist {
    background: rgba(96, 165, 250, 0.2);
    color: #c5dcfa;
    border: 1px solid var(--mp);
}

.party-zone {
    display: grid;
    grid-template-rows: repeat(4, 1fr);
    gap: 4px;
    padding: 8px;
    border-bottom: 2px solid var(--border);
    position: relative;  /* anchor for PARTY chip */
}

/* PARTY chip — straddles the divider between enemy-zone and party-zone. */
.party-zone .party-chip {
    /* Inherits .frame-title styling. */
}

/* LOG pane content — chrome (border + chip) lives on .log-zone wrapper.
   Combat-log itself just stacks log lines with sticky-bottom scrolling.
   The `margin-top: auto` on the first child gives us sticky-bottom + scroll:
   when content < container, the auto margin pushes everything to the bottom;
   when content overflows, the auto margin collapses and the scrollbar takes
   over. Using justify-content: flex-end would hide overflow above the box
   (Chrome quirk), so we use this pattern instead. */
.combat-log {
    flex: 1 1 auto;
    min-height: 0;
    background: transparent;
    padding: 10px 14px 8px;
    overflow-y: auto;
    overflow-x: hidden;
    font-family: 'VT323', monospace;
    font-size: 18px;
    color: var(--text-dim);
    line-height: 1.35;
    display: flex;
    flex-direction: column;
}

.combat-log > :first-child {
    margin-top: auto;
}

/* LOG / ENEMIES / PARTY chips all inherit .frame-title defaults (top:-7px,
   PS2P 9px yellow on bg-frame). They straddle the top border of their pane,
   keeping the visual rhythm consistent across the battle screen. */

/* combat-log scrollbar inherits the global thin styling above */

.log-btn {
    position: absolute;
    top: 4px;
    right: 4px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    border-radius: 2px;
    color: var(--text);
    font-size: 14px;
    line-height: 1;
    padding: 4px 6px;
    cursor: pointer;
    transition: all 80ms;
}

.log-btn:hover, .log-btn:focus {
    border-color: var(--accent);
    background: var(--bg-panel-2);
    outline: none;
}

.log-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.78);
    z-index: 30;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    animation: fadeIn 150ms forwards;
}

.log-panel {
    background: var(--bg-frame);
    border: 2px solid var(--border-bright);
    width: 100%;
    max-height: 85%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.log-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-bottom: 2px solid var(--border);
    background: var(--bg-panel);
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--accent);
}

.log-close {
    background: transparent;
    border: none;
    color: var(--text);
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    padding: 0 6px;
}

.log-body {
    overflow-y: auto;
    padding: 8px 12px;
    flex: 1;
}

.log-section {
    margin-bottom: 14px;
}

.log-round {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    color: var(--accent);
    border-bottom: 1px solid var(--border);
    padding-bottom: 4px;
    margin-bottom: 6px;
}

.log-line {
    font-size: 18px;
    color: var(--text-dim);
    line-height: 1.3;
    padding: 1px 0;
}

.log-line.important {
    color: var(--text);
}

.log-empty {
    color: var(--text-muted);
    text-align: center;
    padding: 30px 0;
}

.combat-log .line {
    opacity: 0;
    animation: fadeIn 200ms forwards;
}

.combat-log .line.fade {
    color: var(--text-muted);
}

/* Round divider — "── ◆ ROUND N ◆ ──" feel, but rendered via the same plain
   text (combat.js emits "── Round N ──"). Style it as a centered chrome chip
   with the round word in yellow. */
.combat-log .line.round-marker {
    color: var(--accent);
    text-align: center;
    margin: 12px 0 6px;
    padding: 4px 0;
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    letter-spacing: 2px;
    border-top: 1px solid var(--border);
    border-bottom: 1px solid var(--border);
    background: rgba(255, 210, 74, 0.04);
}

.combat-log .line.round-marker:first-child {
    margin-top: 0;
}

/* Departure flavor — magenta italic, the "has departed this plane" beat. */
.combat-log .line.depart {
    color: var(--accent-2);
    font-style: italic;
}

/* Inline colored bits inside log lines. */
.combat-log .log-num {
    color: var(--accent);
    font-weight: 700;
}

.combat-log .log-num.crit {
    color: var(--crit-orange);
    font-weight: 700;
}

.combat-log .log-num.heal {
    color: var(--hp);
}

.combat-log .log-num.mp {
    color: var(--mp);
}

.combat-log .log-num.gold {
    color: var(--gold);
}

.combat-log .log-tag {
    font-family: 'Press Start 2P', monospace;
    font-size: 12px;
    letter-spacing: 1px;
}

.combat-log .log-tag.crit   { color: var(--crit-orange); }
.combat-log .log-tag.weak   { color: var(--hp-low); }
.combat-log .log-tag.resist { color: var(--mp); font-style: italic; }

.combat-log .log-spell { color: var(--accent); }
.combat-log .log-item  { color: var(--uncommon); }

@keyframes fadeIn {
    to { opacity: 1; }
}

.action-zone {
    background: var(--bg-panel);
    padding: 8px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    overflow-y: auto;
}

.action-zone .prompt {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    color: var(--accent);
    text-align: center;
    margin-bottom: 2px;
}

/* Tap-to-continue is a real <button>: full-width, dashed border that brightens
   to yellow on hover, pulses gently so the eye finds it after combat. The
   pulse animation pauses on hover so the hover state reads clearly. */
button.prompt.continue-prompt {
    appearance: none;
    display: block;
    width: 100%;
    background: rgba(255, 210, 74, 0.04);
    color: var(--accent);
    font-family: 'Press Start 2P', monospace;
    font-size: 12px;
    padding: 30px 12px;
    letter-spacing: 2px;
    border: 1px dashed var(--border);
    cursor: pointer;
    transition: background 120ms, border-color 120ms, color 120ms, transform 60ms;
    animation: pulse 1.4s ease-in-out infinite;
}

button.prompt.continue-prompt:hover,
button.prompt.continue-prompt:focus {
    background: rgba(255, 210, 74, 0.12);
    border-color: var(--accent);
    color: var(--accent);
    outline: none;
    animation: none;
    opacity: 1;
    box-shadow: 0 0 16px rgba(245, 200, 74, 0.25);
}

button.prompt.continue-prompt:active {
    transform: translateY(1px);
    background: rgba(255, 210, 74, 0.18);
}

.action-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
}

.action-list {
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-height: 100%;
    overflow-y: auto;
}

.action-btn {
    background: var(--bg-panel-2);
    border: 2px solid var(--border);
    color: var(--text);
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    padding: 10px 6px;
    cursor: pointer;
    text-align: center;
    min-height: 38px;
    transition: all 80ms;
}

.action-btn:hover, .action-btn:focus {
    border-color: var(--accent);
    background: var(--bg-panel);
    outline: none;
}

.action-btn[disabled] {
    opacity: 0.4;
    cursor: not-allowed;
}

.action-btn .cost {
    color: var(--mp);
    font-size: 8px;
}

.action-btn.list-row {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    padding: 8px 10px;
    gap: 2px;
}

/* Top row: name on left, cost badge on right. */
.action-btn.list-row .ab-row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
}

.action-btn.list-row .ab-name {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
}

/* Description line: small VT323 in muted color, sits below the name row. */
.action-btn.list-row .ab-desc {
    font-family: 'VT323', monospace;
    font-size: 14px;
    color: var(--text-muted);
    line-height: 1.15;
}

.action-btn.back {
    background: transparent;
    border-color: var(--border);
    color: var(--text-dim);
}

/* ───── Encounter splash ─────
   Acts as a full-screen "stage curtain" before each battle. The outer layer
   is the dark backdrop; an inner border frames the action. */
.splash-screen {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse at center, transparent 30%, rgba(0, 0, 0, 0.6) 100%),
        rgba(14, 8, 32, 0.95);
    z-index: 10;
    animation: splashIn 220ms;
    padding: 16px;
    display: flex;
}

.splash-curtain {
    flex: 1;
    border: 1px solid var(--border-dim);
    box-shadow: inset 0 0 0 1px var(--border-dim);
    margin: 4px;  /* gap so the inset shadow forms a visible second line */
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 18px;
    padding: 24px 16px;
}

@keyframes splashIn {
    from { opacity: 0; transform: scale(1.04); }
    to { opacity: 1; transform: scale(1); }
}

.splash-screen .splash-stinger {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    color: var(--accent-2);
    letter-spacing: 3px;
    text-shadow: 2px 2px 0 rgba(0, 0, 0, 0.5);
}

.splash-screen .splash-title {
    font-family: 'Press Start 2P', monospace;
    font-size: 17px;
    line-height: 1.5;
    color: var(--accent);
    text-align: center;
    text-shadow: 3px 3px 0 #2a1a3a, 4px 4px 0 rgba(0, 0, 0, 0.55);
    padding: 0 16px;
}

.splash-screen .splash-sprites {
    display: flex;
    gap: 24px;
    font-size: 56px;
    filter: drop-shadow(0 6px 0 rgba(0, 0, 0, 0.55));
}

.splash-screen .splash-detail {
    min-width: 240px;
    padding: 10px 14px;
    text-align: center;
}

.splash-screen .splash-sub {
    color: var(--text-dim);
    font-family: 'VT323', monospace;
    font-size: 20px;
    text-align: center;
    line-height: 1.2;
}

.splash-screen .tap-hint {
    margin-top: 8px;
    padding: 8px 16px;
    color: var(--text-dim);
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    letter-spacing: 2px;
    border: 1px dashed var(--border);
    animation: pulse 1.4s infinite;
}

@keyframes pulse {
    0%, 100% { opacity: 0.4; }
    50% { opacity: 1; }
}

/* ───── Reward screen ───── */
.reward-screen {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 20px 16px;
    gap: 14px;
    overflow-y: auto;
}

.reward-screen h2 {
    font-family: 'Press Start 2P', monospace;
    font-size: 16px;
    color: var(--accent);
    text-align: center;
    margin-bottom: 4px;
}

/* Victory banner — bigger, with glow halo backdrop. */
.reward-screen h2.victory-banner {
    font-size: 20px;
    letter-spacing: 3px;
    text-shadow: 3px 3px 0 #2a1a3a, 0 0 14px rgba(245, 200, 74, 0.4);
    padding: 12px 0 4px;
    margin-bottom: 6px;
    background: radial-gradient(ellipse at center, rgba(245, 200, 74, 0.15), transparent 70%);
}

/* Legacy reward-line — still used in equip-manage panel (no-spare-gear case). */
.reward-line {
    display: flex;
    justify-content: space-between;
    background: var(--bg-panel);
    border: 2px solid var(--border);
    padding: 8px 12px;
    font-size: 20px;
}

.reward-line .label { color: var(--text-dim); }
.reward-line .value { color: var(--accent); font-family: 'Press Start 2P', monospace; font-size: 12px; }

/* Spoils frame — yellow-bordered .frame.accent with title chip. Each line
   is a label+value row; equipment lines carry a tier-* class for the
   left-stripe color. */
.spoils-frame {
    padding: 14px 12px 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.spoils-line {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 10px;
    padding: 2px 4px;
    font-family: 'VT323', monospace;
    font-size: 18px;
    color: var(--text);
    border-left: 3px solid transparent;
    padding-left: 6px;
}

.spoils-line.tier-uncommon  { border-left-color: var(--uncommon); }
.spoils-line.tier-rare      { border-left-color: var(--rare); }
.spoils-line.tier-legendary { border-left-color: var(--legendary); }

.spoils-label {
    color: var(--text);
}

.spoils-value {
    color: var(--accent);
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
}

.spoils-meta {
    color: var(--text-muted);
    font-size: 15px;
    text-align: right;
}

.level-up {
    background: var(--bg-panel);
    border: 2px solid var(--accent);
    padding: 10px;
    font-size: 18px;
}

.level-up .name {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--accent);
    margin-bottom: 6px;
}

.level-up .stat-changes {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    color: var(--hp);
    font-size: 16px;
}

/* ───── Reward screen per-character boxes ───── */

.reward-party {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.char-reward {
    /* Layout — chrome comes from .frame primitive. Add a left role-color
       stripe via box-shadow inset (cheaper than a real border). */
    padding: 9px 12px 9px 14px;
    box-shadow:
        inset 4px 0 0 var(--role, var(--border)),
        inset 0 0 14px rgba(0, 0, 0, 0.35);
}

.char-reward.dead {
    opacity: 0.45;
    box-shadow:
        inset 4px 0 0 var(--danger),
        inset 0 0 14px rgba(0, 0, 0, 0.35);
}

.char-reward-header {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 4px;
}

.char-reward-header .sprite {
    font-size: 24px;
    line-height: 1;
}

.char-reward-header .name {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--text);
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.char-line {
    font-size: 18px;
    color: var(--text-dim);
    line-height: 1.3;
    padding-left: 34px;  /* align under name */
}

.char-line.gains {
    color: var(--text);
}

.char-line.levelup {
    color: var(--hp);
    font-size: 16px;
}

.char-line.levelup-flavor {
    color: var(--text-muted);
    font-size: 15px;
    font-style: italic;
}

.char-line.dead-note {
    color: var(--danger);
    font-style: italic;
    font-size: 16px;
}

.char-bars {
    display: flex;
    flex-direction: column;
    gap: 3px;
    margin-top: 6px;
    padding-left: 34px;  /* align under name */
}

.continue-row.two-buttons {
    display: flex;
    gap: 8px;
}

.continue-row.two-buttons .btn {
    flex: 1;
}

/* ───── Item browser (shared by Inventory / Buy / Sell) ─────
   Layout: header strip → tabs → tile grid (scrolls) → description pane → footer */
.item-browser {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 12px 14px;
    gap: 8px;
}

.ib-header {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    padding: 14px 12px 10px;
    margin-top: 6px;
}

.ib-gold {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--gold);
}

/* Tabs row — secondary buttons that look "pressed" when active. */
.ib-tabs {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    gap: 4px;
}

.ib-tab {
    appearance: none;
    background: var(--bg-panel);
    border: 2px solid var(--border);
    color: var(--text-dim);
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    letter-spacing: 0.5px;
    padding: 10px 4px;
    cursor: pointer;
    transition: background 80ms, border-color 80ms, color 80ms;
}

.ib-tab:hover, .ib-tab:focus {
    border-color: var(--border-bright);
    color: var(--text);
    outline: none;
}

.ib-tab.active {
    background: var(--bg-panel-2);
    border-color: var(--accent);
    color: var(--accent);
}

/* 3-wide tile grid. Scrolls when there are more tiles than fit. */
.ib-grid {
    flex: 1 1 0;
    min-height: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 6px;
    overflow-y: auto;
    padding: 4px 2px;
    align-content: start;
}

.ib-empty {
    grid-column: 1 / -1;
    color: var(--text-muted);
    font-style: italic;
    text-align: center;
    padding: 24px 0;
    font-size: 17px;
}

.ib-tile {
    appearance: none;
    background: var(--bg-panel);
    border: 2px solid var(--border);
    cursor: pointer;
    padding: 8px 4px 6px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    color: var(--text);
    position: relative;
    transition: border-color 80ms, background 80ms, transform 60ms;
    min-height: 86px;
}

.ib-tile:hover, .ib-tile:focus { outline: none; border-color: var(--border-bright); }
.ib-tile.tier-uncommon  { border-color: var(--uncommon); }
.ib-tile.tier-rare      { border-color: var(--rare); }
.ib-tile.tier-legendary { border-color: var(--legendary); }

.ib-tile.selected {
    background: var(--bg-panel-2);
    box-shadow: inset 0 0 0 2px var(--accent), 0 0 14px rgba(255, 210, 74, 0.25);
}

.ib-tile-icon {
    font-size: 30px;
    line-height: 1;
}

.ib-tile-name {
    font-family: 'VT323', monospace;
    font-size: 16px;
    color: var(--text);
    text-align: center;
    line-height: 1.1;
    /* Clamp to 2 lines; ellipsis if longer. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.ib-tile-count {
    position: absolute;
    top: 2px;
    right: 4px;
    font-family: 'Press Start 2P', monospace;
    font-size: 9px;
    color: var(--accent);
    background: rgba(0, 0, 0, 0.55);
    padding: 2px 4px;
    border-radius: 2px;
    line-height: 1;
}

/* Description pane below the grid */
.ib-desc {
    padding: 14px 12px 12px;
    margin-top: 6px;
    display: flex;
    flex-direction: column;
    gap: 6px;
    flex: 0 0 auto;
}

.ib-desc.tier-uncommon  { border-color: var(--uncommon); }
.ib-desc.tier-rare      { border-color: var(--rare); }
.ib-desc.tier-legendary { border-color: var(--legendary); }

.ib-desc-empty {
    flex: 0 0 auto;
    text-align: center;
    color: var(--text-muted);
    font-style: italic;
    font-size: 16px;
    padding: 16px 0;
    border-top: 1px dashed var(--border);
    margin-top: 6px;
}

.ib-desc-head {
    display: flex;
    align-items: center;
    gap: 10px;
}

.ib-desc-icon {
    font-size: 26px;
    line-height: 1;
}

.ib-desc-name {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--text);
    flex: 1;
}

.ib-desc-stats {
    font-family: 'VT323', monospace;
    font-size: 17px;
    color: var(--text-dim);
}

.ib-desc-text {
    font-family: 'VT323', monospace;
    font-size: 17px;
    color: var(--text-dim);
    line-height: 1.25;
}

.ib-desc-meta {
    font-family: 'VT323', monospace;
    font-size: 15px;
    color: var(--text-muted);
    font-style: italic;
}

.ib-action {
    margin-top: 6px;
    width: 100%;
}

.ib-footer {
    display: flex;
    gap: 8px;
    padding-top: 4px;
}

.ib-footer .btn { flex: 1; }
.ib-footer .ib-done { flex: 1; }

/* Party picker rows (compact list under the description pane in Inventory).
   One row per party member: sprite | name+chip+info | action button. */
.ib-party-picker {
    display: flex;
    flex-direction: column;
    gap: 4px;
    margin-top: 6px;
}

.ib-party-row {
    display: grid;
    grid-template-columns: 32px 1fr auto;
    align-items: center;
    gap: 10px;
    padding: 6px 10px;
    background: var(--bg-panel);
    border: 1px solid var(--border);
    min-height: 50px;
}

.ib-party-row.dead {
    opacity: 0.5;
}

.ib-party-row .iprow-icon {
    font-size: 24px;
    line-height: 1;
    text-align: center;
}

.iprow-main {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.iprow-head {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.iprow-name {
    font-family: 'Press Start 2P', monospace;
    font-size: 10px;
    color: var(--text);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.iprow-info {
    font-family: 'VT323', monospace;
    font-size: 15px;
    color: var(--text-dim);
    line-height: 1.2;
}

.iprow-info .tc-label { color: var(--text-muted); }
.iprow-info .tc-name { color: var(--text); }
.iprow-info .tc-stats { color: var(--accent); }

.iprow-action {
    padding: 8px 10px;
    font-size: 10px;
    min-width: 70px;
}

/* ───── Read-only Party view (merchant submenu) ─────
   Stacked list of party members, each with their status card on top and
   a 4-line equipment block below. Scrolls when needed. */
.party-view {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 12px 14px;
    gap: 8px;
}

.party-view-header {
    display: flex;
    align-items: center;
    padding: 14px 12px 10px;
    margin-top: 6px;
    min-height: 22px;
}

.party-view-list {
    flex: 1;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 4px 0;
}

.pview-member {
    background: var(--bg-panel);
    border: 1px solid var(--border);
    padding: 8px 10px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.pview-slots {
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding-left: 6px;
}

.pview-slot {
    display: grid;
    grid-template-columns: 24px auto 1fr auto;
    align-items: baseline;
    gap: 4px;
    font-family: 'VT323', monospace;
    font-size: 16px;
    line-height: 1.2;
}

.pview-slot-icon {
    font-size: 18px;
    line-height: 1;
    text-align: center;
}

.pview-slot.empty {
    color: var(--text-muted);
    font-style: italic;
}

.pview-slot.empty .pview-slot-icon {
    color: var(--text-muted);
}

.pview-slot-label { color: var(--text-muted); }
.pview-slot-name  { color: var(--text); }
.pview-slot-stats {
    color: var(--accent);
    text-align: right;
    font-size: 15px;
}

.party-view-footer {
    padding-top: 4px;
}

.party-view-footer .btn { width: 100%; }

/* Empty-slot state for tc-* rows (rendered inside .iprow-info). */
.iprow-info .tc-row.tc-empty,
.iprow-info .tc-row.tc-empty .tc-name {
    color: var(--text-muted);
    font-style: italic;
}

/* ───── Inventory overlay ─────
   Picker overlay (currently just ring-slot disambiguation). Sits on top of
   the item browser as a darkened modal. */
.inv-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0,0,0,0.78);
    z-index: 30;
    display: flex;
    flex-direction: column;
    padding: 18px;
    gap: 6px;
    overflow-y: auto;
}

.inv-overlay .prompt {
    font-family: 'Press Start 2P', monospace;
    font-size: 11px;
    color: var(--accent);
    text-align: center;
    margin-bottom: 6px;
}

.loot-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.loot-item {
    background: var(--bg-panel);
    border: 2px solid var(--border);
    padding: 8px 10px;
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.loot-item.common { border-color: var(--common); }
.loot-item.uncommon { border-color: var(--uncommon); }
.loot-item.rare { border-color: var(--rare); }
.loot-item.legendary { border-color: var(--legendary); }

.loot-item .name { font-size: 18px; }
.loot-item .stats { font-size: 14px; color: var(--text-muted); }

.reward-screen .continue-row {
    margin-top: auto;
    padding-top: 8px;
}

/* ───── Merchant screen ───── */
.merchant-screen {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: 16px;
    gap: 12px;
    overflow-y: auto;
}

.merchant-header {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px;
}

.merchant-header .sprite { font-size: 44px; }
.merchant-header .title { font-family: 'Press Start 2P', monospace; font-size: 11px; color: var(--accent); }
.merchant-header .patter { font-size: 18px; color: var(--text-dim); font-style: italic; margin-top: 4px; }
.merchant-header .gold-row { font-size: 18px; color: var(--gold); margin-top: 4px; font-family: 'Press Start 2P', monospace; font-size: 10px; }

.merchant-party {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 4px 0;
}

.merchant-menu {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 8px;
}

.shop-list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.shop-row {
    background: var(--bg-panel);
    border: 2px solid var(--border);
    padding: 8px 10px;
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}

.shop-row:hover { border-color: var(--accent); }
.shop-row.too-expensive { opacity: 0.5; cursor: not-allowed; }

.shop-row .info { flex: 1; min-width: 0; }
.shop-row .name { font-size: 18px; }
.shop-row .desc { font-size: 14px; color: var(--text-muted); }
.shop-row .price { color: var(--gold); font-family: 'Press Start 2P', monospace; font-size: 11px; }

.merchant-screen .footer {
    margin-top: auto;
    padding-top: 8px;
    display: flex;
    gap: 8px;
}

.merchant-screen .footer .btn { flex: 1; }

/* ───── Game Over ───── */
.gameover-screen {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    padding: 24px;
    gap: 20px;
    text-align: center;
}

.gameover-screen h1 {
    font-family: 'Press Start 2P', monospace;
    font-size: 22px;
    color: var(--danger);
    text-shadow: 3px 3px 0 #2a1a3a;
}

.gameover-screen .body {
    color: var(--text-dim);
    font-size: 20px;
    max-width: 360px;
}

.gameover-screen .penalty {
    /* chrome is from .frame.danger primitive; just layout overrides here */
    padding: 14px 14px 12px;
    font-family: 'VT323', monospace;
    font-size: 18px;
    color: var(--text-dim);
    text-align: left;
    min-width: 240px;
}

/* ───── Toast / floating numbers ───── */
.float-num {
    position: absolute;
    font-family: 'Press Start 2P', monospace;
    font-size: 14px;
    color: var(--danger);
    text-shadow: 2px 2px 0 #000;
    pointer-events: none;
    animation: floatUp 900ms forwards;
    z-index: 5;
}

.float-num.heal { color: var(--hp); }
.float-num.crit { color: var(--accent); font-size: 18px; }
.float-num.miss { color: var(--text-muted); }

@keyframes floatUp {
    0% { transform: translateY(0); opacity: 1; }
    100% { transform: translateY(-40px); opacity: 0; }
}
