/* ═════════════════════════════════════════════════════════════════════════
   ML1e TUNING TOKENS — the knobs live here. See docs/TUNING.md for the map.
   ═════════════════════════════════════════════════════════════════════════ */
:root {
    /* Select screen magnification. 1 = the old size; 1.5 matches "browser
       zoomed to 150%". Mobile drops it back to 1 in the media query below. */
    --ml-select-zoom: 1.5;

    /* ONE portrait size for the ladder — the hero panel and every opponent
       rung read this same var, so they can never drift apart. The width is a
       FRACTION OF THE TOWER's width, so cards and tower scale together on
       every screen. --ml-card-frac is the knob: bigger = bigger cards.
       ML4: 0.25 → 0.175 — the asked-for 30% reduction of hero + opponents. */
    --ml-card-frac: 0.175;
    --ml-portrait-w: calc(var(--ml-tower-h, 250vh) * var(--ml-tower-ar, 0.42) * var(--ml-card-frac));

    /* Raises the hero panel and every opponent card together, in px.
       Set 0 to turn it off. Per-rung positions stay in MYTH_CONFIG.ladder.rungs. */
    --ml-card-lift: 100px;

    /* ML4: the select-screen title plates render at the size of the
       /classes page header stack. 1050px is those plate PNGs' natural
       width — both plates cap here, exactly like the site. One knob. */
    --ml-plate-w: 840px;   /* ML5b: both title plates at 80% of the site's natural 1050 */

    /* ML5b: how far the MYTHOLOGIES plate climbs ON TOP of the Grand
       Saga plate - 30% of the plate height. The 1050x300 template stands
       240px tall at the 840px width, so 72px. Scaled steps live in the
       two breakpoint blocks below. Nudge this one number to taste. */
    --ml-title-overlap: 72px;

    /* ML4: ONE glide for the camera AND the hero panel — same duration,
       same curve, so the hero can never drift off its opponent mid-climb. */
    --ml-glide: 2s cubic-bezier(0.22, 0.9, 0.24, 1);

    /* Story dialogue magnification (select-style). Mobile drops it to 1. */
    --ml-story-zoom: 1.35;

    /* Horizontal nudge of the whole tower (art + rungs move together). */
    --ml-tower-x: 0px;

    /* Z-order. Rungs default ABOVE the tower art. To sit them BEHIND
       porthole frames: either set --ml-rung-z lower than --ml-tower-fg-z and
       give MYTH_CONFIG.assets.towerFront a transparent-porthole overlay PNG,
       or — if the tower art itself has transparent porthole holes — set
       --ml-rung-z: 0 so rungs slide UNDER the tower image. */
    --ml-tower-img-z: 1;
    --ml-rung-z: 3;
    --ml-tower-fg-z: 2;
}

/* =============================================================================
   MYTHOLOGIES ML1 — ladder-mode styling. Scoped to the myth-* screens only.
   gm styles.css is loaded first and left untouched.
   ============================================================================= */

:root {
    /* ML5: the accent scheme - GREEN replaces the old gold. Change
       --ml-accent to restyle the whole ladder skin; --ml-gold stays as an
       alias so every existing rule follows automatically. */
    --ml-accent: #15ff00;   /* ML5b: the ENGAGE button's green (.btn-decrypt hover) */
    /* ML7: player two's colour. The COM seat wears it now; when the 2P mode
       lands, the second cursor and the P2 nameplate read the same token. */
    --ml-blue: #2f8bff;
    --ml-gold: var(--ml-accent);
    --ml-red: #ff2b4a;
    --ml-cyan: #00f3ff;
    --ml-ink: rgba(4, 8, 16, 0.82);
    --ml-backdrop: url('https://rrxzozvjmhfscano.public.blob.vercel-storage.com/uploads/94fbf34d-ae71-4f38-b5c5-0d852d40cfa0.jpg');
}

/* ---------- shared layers ---------- */
#myth-select, #myth-ladder, #myth-vs, #myth-story, #myth-continue, #myth-item {
    /* ML1d: absolute overlay, like every gm screen. position:relative put these
       five into normal flow, where gm's #fighter-setup — display:flex ungated
       on .active, opacity 0 but still 1010px of layout — pushed them below the
       fold of an overflow:hidden body. The GM window showed only the fixed
       bg/scrim; the arena looked right because its clone re-parents under
       #arena-root with no flow above it. inset:0 replaces min-height:100vh. */
    position: absolute;
    inset: 0;
    overflow: hidden;
}
.ml-bg {
    position: absolute; inset: 0;
    background: var(--ml-backdrop) center 30% / cover no-repeat, #05070d;
    z-index: 0;
}
.ml-scrim {
    position: absolute; inset: 0; z-index: 1;
    background: radial-gradient(ellipse at 50% 25%, rgba(5,9,18,0.10), rgba(4,7,13,0.42) 78%);
}
.ml-scrim-light { background: radial-gradient(ellipse at 50% 30%, rgba(5,9,18,0.02), rgba(4,7,13,0.30) 82%); }
.ml-scrim-red { background: radial-gradient(ellipse at 50% 40%, rgba(60,4,12,0.22), rgba(10,2,5,0.62) 82%); }

.ml-quiet {
    background: none; border: none; cursor: pointer;
    font-family: 'Rajdhani', sans-serif; font-size: 13px; letter-spacing: 2px;
    text-transform: uppercase; color: rgba(220, 230, 245, 0.45);
}
.ml-quiet:hover { color: rgba(255,255,255,0.8); }

@keyframes mlBlink { 0%,100% { opacity: 1; } 50% { opacity: 0.25; } }
.ml-blink { animation: mlBlink 1.3s steps(2, start) infinite; }
@keyframes mlPulseGold {
    0%,100% { box-shadow: 0 0 0 2px var(--ml-gold), 0 0 18px rgba(21,255,0,0.55); }
    50%      { box-shadow: 0 0 0 3px var(--ml-gold), 0 0 34px rgba(21,255,0,0.9); }
}
@keyframes mlPulseRed {
    0%,100% { box-shadow: 0 0 0 2px var(--ml-red), 0 0 16px rgba(255,43,74,0.5); }
    50%      { box-shadow: 0 0 0 3px var(--ml-red), 0 0 30px rgba(255,43,74,0.85); }
}

/* ---------- THE TITLE — the wiki's Grand Saga / Futura plate treatment,
   installed verbatim (M20): the plate flashes solid white with a glow on
   hover. Swap both drop-shadow colours to #ff0000 for the Futura red. ---- */
.ml-title { position: relative; display: block; z-index: 1; }   /* ML5: paints ABOVE the Grand Saga plate it overlaps */
.ml-title-img { display: none; }
.ml-title.has-img .ml-title-text { display: none; }
.ml-title.has-img .ml-title-img {
    /* ML4: the /classes page dimensions — the plate renders at the site
       plates' natural 1050px width (--ml-plate-w). The negative margins
       reproduce the site stack's net spacing (its own -60/-80 sit inside
       default h1 gaps this markup doesn't have). Nudge these two numbers
       if the MYTHOLOGIES PNG's transparent padding differs from the
       Futura plate's. */
    display: block; width: min(var(--ml-plate-w, 1050px), 100%); height: auto;
    /* ML5: the top margin is now the OVERLAP knob - the plate climbs
       onto the Grand Saga plate by --ml-title-overlap. */
    margin: calc(-1 * var(--ml-title-overlap, 72px)) auto -58px;
    transition: filter 0.3s ease;
}
/* M70: the MYTHOLOGIES plate wears the wiki page's FUTURA treatment —
   forced solid white plus the red drop-shadow glow on hover
   (.campaign-title-img in the site's globals.css). */
.ml-title.has-img .ml-title-img:hover {
    filter: brightness(0) invert(1)
            drop-shadow(0 0 8px #ff0000)
            drop-shadow(0 0 16px #ff0000);
}

/* M70: the static GRAND SAGA plate above the title — the wiki page's
   stack. No hover glow on this one, on purpose. The PNG's wordmark sits
   in the bottom half of its canvas, so the negative top margin reclaims
   the transparent headroom (the wrap's 26px padding absorbs the pull —
   tune this one number if the stack sits too high or too low). */
.ml-grand-saga-plate {
    /* ML4: sized like the site's .grand-saga-title-img — natural width,
       centred, no pull-up (the headroom is part of the /classes look). */
    display: block; max-width: min(var(--ml-plate-w, 1050px), 100%); height: auto;
    margin: 0 auto;
}
/* The site's responsive steps, translated to this markup's net spacing. */
@media (max-width: 900px) {
    :root { --ml-title-overlap: 56px; }
    .ml-title.has-img .ml-title-img { margin-bottom: -23px; }
}
@media (max-width: 560px) {
    .ml-grand-saga-plate { max-width: 92%; }
    :root { --ml-title-overlap: 44px; }
    .ml-title.has-img .ml-title-img { width: 92%; margin-bottom: -5px; }
}

/* ---------- CHARACTER SELECT ---------- */
.ml-select-wrap {
    position: relative; z-index: 2;
    max-width: 1280px;
    margin: 0 auto;
    padding: 26px 18px 40px;
}
/* The zoom sits on the wrap's CHILDREN, not the wrap: zooming a flex item
   makes Chromium centre a phantom unzoomed box and clip the top. Zoomed
   block children size their parent honestly — the whole-page-zoom path. */
.ml-select-wrap > * { zoom: var(--ml-select-zoom); }
/* ML4: the title stack opts OUT of the select zoom so the plates render at
   true site pixels and can match /classes exactly — the old 1.5× made any
   copied site value come out half again too big. The champion line keeps
   its magnified size via its own zoom, which multiplies back up. */
.ml-select-wrap > .ml-select-head { zoom: 1; }
.ml-select-head .ml-sub, .ml-select-head .ml-title-text { zoom: var(--ml-select-zoom); }
.ml-select-head { text-align: center; margin-bottom: 6px; }
.ml-title {
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: clamp(30px, 5vw, 52px);
    letter-spacing: 10px; color: #eef4ff;
    text-shadow: 0 0 22px rgba(0,243,255,0.45), 0 3px 0 rgba(0,0,0,0.6);
}
.ml-sub {
    font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: clamp(14px, 2vw, 20px);
    letter-spacing: 7px; color: var(--ml-gold); margin-top: 2px;
}
.ml-player-chips { display: flex; justify-content: space-between; max-width: 1180px; margin: 6px auto 10px; }
.ml-chip {
    display: inline-block;
    font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 20px; letter-spacing: 5px;
    padding: 9px 22px; clip-path: polygon(14px 0, 100% 0, calc(100% - 14px) 100%, 0 100%);
}
.ml-chip-p1 { background: rgba(21,255,0,0.16); color: var(--ml-gold); border-bottom: 3px solid var(--ml-gold); }
.ml-chip-com { background: rgba(47,139,255,0.14); color: var(--ml-blue); border-bottom: 3px solid var(--ml-blue); opacity: 0.85; }

/* ML6/ML7: each seat names one of the big side images and carries that
   side's nameplate. Fixed like the art, and hidden with it on mobile. */
.ml-seat { position: fixed; bottom: 6vh; z-index: 2; pointer-events: none; max-width: 32vw; }
.ml-seat-l { left: max(12px, 4vw); text-align: left; }
.ml-seat-r { right: max(12px, 4vw); text-align: right; }
.ml-seat .ml-render-plate { position: static; margin-top: 8px; }
.ml-seat-l .ml-render-plate { text-align: left; }
.ml-seat-r .ml-render-plate { text-align: right; }

/* ═══ ML7 · GROUNDWORK FOR THE TWO-PLAYER MODE (nothing below is live yet) ═══
   When 2P lands:
   1. The right seat becomes PLAYER 2 instead of COM — swap the chip's text
      and its class from .ml-chip-com to .ml-chip-p2 (styled below, same blue).
   2. Reveal that seat's nameplate by dropping .ml-seat-p2-hidden from
      .ml-seat-r's plate; setCursor2() fills #ml-render-name-2 / -tag-2 the
      way setCursor fills the left pair. It is already right-aligned.
   3. Player two's cursor is a BLUE box: add class 'cursor2' to the tile the
      second player is on. .ml-tile.cursor2 below already styles it, and it
      only appears after player one has locked their champion — so a tile can
      briefly wear .cursor and .cursor2 at once, which is why the blue rule
      sits after the green one and wins.
   Nothing here changes the one-player screen.                              */
.ml-chip-p2 { background: rgba(47,139,255,0.14); color: var(--ml-blue); border-bottom: 3px solid var(--ml-blue); }
.ml-seat-p2-hidden { display: none; }
.ml-tile.cursor2 { animation: mlPulseBlue 1.1s ease-in-out infinite; border-color: var(--ml-blue); z-index: 2; }
@keyframes mlPulseBlue {
    0%, 100% { box-shadow: 0 0 18px rgba(47,139,255,0.45); }
    50% { box-shadow: 0 0 34px rgba(47,139,255,0.85); }
}

.ml-select-body { display: block; }
/* ML5c: the small portrait panel and the COM panel are superseded by the
   big side art - hiding them lets the grid centre on the screen itself. */
.ml-select-body > .ml-select-render { display: none; }
.ml-select-render { position: relative; min-height: 360px; }
.ml-select-render img {
    width: 100%; height: 400px; object-fit: cover; object-position: top;
    border: 1px solid rgba(0,243,255,0.25); border-radius: 6px;
    box-shadow: 0 14px 40px rgba(0,0,0,0.55);
    -webkit-mask-image: linear-gradient(#000 78%, transparent);
            mask-image: linear-gradient(#000 78%, transparent);
    background: rgba(6,10,20,0.6);
}
.ml-render-plate { position: absolute; left: 0; right: 0; bottom: 8px; text-align: center; }
.ml-render-name {
    font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 19px; letter-spacing: 2px;
    color: #fff; text-shadow: 0 0 14px rgba(0,243,255,0.6);
}
.ml-render-tag { font-family: 'Rajdhani', sans-serif; font-size: 13px; letter-spacing: 2px; color: rgba(210,225,245,0.8); }

.ml-com-panel {
    height: 400px; display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 10px; border: 1px dashed rgba(255,43,74,0.35); border-radius: 6px; background: rgba(20,4,10,0.35);
}
.ml-com-glyph { font-size: 44px; color: var(--ml-red); opacity: 0.8; }
.ml-com-line { font-family: 'Orbitron', sans-serif; font-size: 13px; letter-spacing: 3px; color: var(--ml-red); }
.ml-com-line2 { font-family: 'Rajdhani', sans-serif; font-size: 12px; letter-spacing: 2px; color: rgba(230,200,205,0.55); padding: 0 18px; text-align: center; }

.ml-continue-banner {
    margin: 0 auto 12px; max-width: 560px; padding: 10px 16px; cursor: pointer;
    background: rgba(21,255,0,0.1); border: 1px solid rgba(21,255,0,0.5); border-radius: 4px;
    font-family: 'Rajdhani', sans-serif; font-weight: 700; letter-spacing: 2px; color: var(--ml-gold);
    text-align: center;
}
.ml-continue-banner:hover { background: rgba(21,255,0,0.2); }

.ml-grid {
    --ml-cols: 5; --ml-gap: 14px;   /* ML5c: five across, every row centred */
    display: flex; flex-wrap: wrap; justify-content: center; align-content: flex-start;
    gap: var(--ml-gap); padding: 8px 0 4px; margin: 0 auto; max-width: 660px;
}
/* ML5b: the /classes .gsx-card treatment, ported - square corners, the 2px
   cyan frame, HUD corner brackets, the scrim, the hover brighten. The locked
   secret tile pulses like a locked class card. */
.ml-tile {
    position: relative; aspect-ratio: 3 / 4; cursor: pointer; border-radius: 0; overflow: hidden;
    flex: 0 0 auto;
    width: min(168px, calc((100% - (var(--ml-cols) - 1) * var(--ml-gap)) / var(--ml-cols)));
    border: 1px solid rgba(21, 255, 0, 0.35); background: #070b14;
    box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
    transition: all 0.3s ease;
}
.ml-tile img { width: 100%; height: 100%; object-fit: cover; object-position: top; display: block; }
.ml-tile::before {
    content: ""; position: absolute; inset: 0; z-index: 1; transition: all 0.4s ease;
    background: linear-gradient(0deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 50%, rgba(0,0,0,0.2) 100%);
}
/* ML5c: the HUD corners live on their own node so the SAGA COMPLETE ribbon
   (.ml-tile.done::after) can't wipe them off a finished tile. */
.ml-tile-hud {
    position: absolute; inset: 5px; pointer-events: none; z-index: 4; opacity: 0.55; transition: all 0.3s ease;
    background:
        linear-gradient(var(--ml-accent), var(--ml-accent)) top left / 14px 2px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) top left / 2px 14px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) top right / 14px 2px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) top right / 2px 14px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) bottom left / 14px 2px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) bottom left / 2px 14px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) bottom right / 14px 2px no-repeat,
        linear-gradient(var(--ml-accent), var(--ml-accent)) bottom right / 2px 14px no-repeat;
}
.ml-tile:hover .ml-tile-hud, .ml-tile.cursor .ml-tile-hud { inset: 3px; opacity: 1; }
.ml-tile:hover {
    transform: translateY(-3px); border-color: var(--ml-accent);
    box-shadow: 0 0 24px rgba(21, 255, 0, 0.35), 0 10px 25px rgba(0, 0, 0, 0.5);
}
.ml-tile.locked { animation: mlLockedPulse 2.2s ease-in-out infinite; }
@keyframes mlLockedPulse {
    0%, 100% { box-shadow: 0 0 30px rgba(255, 0, 64, 0.5), inset 0 0 20px rgba(255, 0, 64, 0.2); }
    50% { box-shadow: 0 0 50px #ff0040, inset 0 0 35px rgba(255, 0, 64, 0.4); }
}
.ml-tile.cursor { animation: mlPulseGold 1.1s ease-in-out infinite; border-color: var(--ml-gold); z-index: 2; }
.ml-tile-name {
    position: absolute; left: 0; right: 0; bottom: 0; z-index: 2; padding: 5px 4px 4px;
    background: linear-gradient(transparent, rgba(3,6,12,0.94) 42%);
    font-family: 'Orbitron', sans-serif; font-size: 11px; font-weight: 700; letter-spacing: 1px;
    color: #eaf2ff; text-align: center; text-transform: uppercase;
}
.ml-tile-house { display: block; font-family: 'Rajdhani', sans-serif; font-size: 10px; letter-spacing: 2px; color: rgba(180,200,225,0.75); }
.ml-tile.done::after {
    content: '✓ SAGA COMPLETE'; position: absolute; top: 8px; left: -34px; transform: rotate(-32deg);
    background: rgba(21,255,0,0.92); color: #211a02; font-family: 'Orbitron', sans-serif;
    font-size: 9px; font-weight: 700; letter-spacing: 1px; padding: 3px 36px;
}
.ml-tile.locked img { filter: brightness(0.14) saturate(0); }
/* ML6: the sealed champion wears the /classes locked-card treatment -
   the rotated ! plate, the striped LOCKED badge, red brackets and a
   red-tinted striped scrim. The red glow (mlLockedPulse) is unchanged. */
.ml-tile.locked { border-color: rgba(255, 0, 64, 0.45); cursor: not-allowed; }
/* ML7: hover and the cursor both used to repaint this tile with the accent
   green — the sealed champion keeps its own red under both. */
.ml-tile.locked:hover, .ml-tile.locked.cursor {
    transform: none; border-color: rgba(255, 0, 64, 0.45);
    animation: mlLockedPulse 2.2s ease-in-out infinite;
    box-shadow: 0 0 30px rgba(255, 0, 64, 0.5), inset 0 0 20px rgba(255, 0, 64, 0.2);
}
.ml-tile.locked:hover .ml-tile-hud, .ml-tile.locked.cursor .ml-tile-hud { inset: 2px; opacity: 1; }
.ml-tile.locked::before {
    background:
        repeating-linear-gradient(45deg, transparent 0, transparent 24px, rgba(255,0,64,0.06) 24px, rgba(255,0,64,0.06) 48px),
        linear-gradient(0deg, rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.82) 50%, rgba(0,0,0,0.78) 100%);
}
.ml-tile.locked .ml-tile-hud {
    inset: 2px; opacity: 1;
    background:
        linear-gradient(#ff0040, #ff0040) top left / 20px 3px no-repeat,
        linear-gradient(#ff0040, #ff0040) top left / 3px 20px no-repeat,
        linear-gradient(#ff0040, #ff0040) top right / 20px 3px no-repeat,
        linear-gradient(#ff0040, #ff0040) top right / 3px 20px no-repeat,
        linear-gradient(#ff0040, #ff0040) bottom left / 20px 3px no-repeat,
        linear-gradient(#ff0040, #ff0040) bottom left / 3px 20px no-repeat,
        linear-gradient(#ff0040, #ff0040) bottom right / 20px 3px no-repeat,
        linear-gradient(#ff0040, #ff0040) bottom right / 3px 20px no-repeat;
}
.ml-lock-icon {
    position: absolute; top: 32%; left: 50%; z-index: 3;
    transform: translate(-50%, -50%) rotate(45deg);
    width: 34px; height: 34px; border: 2px solid #ff0040;
    display: flex; align-items: center; justify-content: center; color: #ff0040;
    box-shadow: 0 0 30px rgba(255,0,64,0.5), inset 0 0 20px rgba(255,0,64,0.2);
}
.ml-lock-icon span { transform: rotate(-45deg); font-size: 1.15rem; font-weight: 900; text-shadow: 0 0 16px #ff0040; }
.ml-lock-badge {
    position: absolute; top: 56%; left: 50%; transform: translate(-50%, -50%); z-index: 3;
    padding: 4px 10px; font-family: 'Orbitron', sans-serif; font-size: 8px; font-weight: 700;
    letter-spacing: 2px; text-transform: uppercase; color: #ff0040;
    border: 1px solid #ff0040; overflow: hidden; text-shadow: 0 0 10px rgba(255,0,64,0.8);
}
.ml-lock-badge::before {
    content: ""; position: absolute; inset: 0; z-index: -1;
    background: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(255,0,64,0.18) 10px, rgba(255,0,64,0.18) 20px);
}
.ml-tile.locked .ml-tile-name { color: rgba(160,180,205,0.7); }
.ml-tile.unlocked-secret { border-color: var(--ml-gold); }
.ml-select-hint {
    margin: 6px auto 12px; text-align: center; font-family: 'Rajdhani', sans-serif;
    font-size: 13px; letter-spacing: 3px; color: rgba(0,243,255,0.7);
}
.ml-reset { display: block; margin: 14px auto 0; }
.ml-reset.armed { color: var(--ml-red); }

.ml-missing {
    position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 5; padding: 10px 14px;
    background: rgba(120, 12, 24, 0.92); border: 1px solid var(--ml-red); border-radius: 4px;
    font-family: 'Rajdhani', sans-serif; font-size: 13px; color: #ffe2e6; letter-spacing: 1px;
}

/* ---------- RESET SAGA PROGRESS — the engine's PURGE locked skin ----------
   Mirrors .locked-overlay in styles.css: Orbitron, letter-spaced, red text
   glow, the diagonal warning-stripe wash behind. Sealed (dim) at rest; the
   first tap arms it to the full warning, pulsing on the engine's own
   locked-icon-pulse keyframe. ------------------------------------------- */
#ml-reset-progress {
    position: relative; display: inline-block; margin-top: 14px; overflow: hidden;
    padding: 10px 26px; cursor: pointer; user-select: none;
    font-family: 'Orbitron', sans-serif; font-size: 11px; font-weight: 700;
    letter-spacing: 4px; text-transform: uppercase;
    color: rgba(255,0,64,0.7); background: transparent;
    border: 1px solid rgba(255,0,64,0.45);
    text-shadow: 0 0 10px rgba(255,0,64,0.5);
    filter: saturate(0.5);
    transition: filter 0.25s ease, color 0.25s ease, border-color 0.25s ease;
}
#ml-reset-progress::before {
    content: ''; position: absolute; inset: 0; z-index: -1;
    background: repeating-linear-gradient(
        45deg, transparent, transparent 10px,
        rgba(255,0,64,0.18) 10px, rgba(255,0,64,0.18) 20px);
}
#ml-reset-progress.armed {
    color: #ff0040; border-color: #ff0040; filter: none;
    text-shadow: 0 0 10px rgba(255,0,64,0.8);
    animation: locked-icon-pulse 1.2s ease-in-out infinite;
}

/* ML6: RESET SAGA PROGRESS is ARCHIVED, not deleted - the sealed/armed
   skin above is kept intact for future use. Delete this ONE rule to put
   the button back on the screen. It sits after the id rules deliberately:
   an earlier `display: none` loses to them on order. */
#ml-reset-progress { display: none; }

/* ---------- LADDER / DRIFT SPIRE ---------- */
.ml-parallax { position: absolute; inset: 0; z-index: 0; overflow: hidden; }
.ml-parallax img {
    position: absolute; left: 50%; top: 0; height: 145%; width: auto; min-width: 100%;
    object-fit: cover;
    transform: translate(-50%, var(--ml-bg-y, 0px));
    transition: transform var(--ml-glide, 2s cubic-bezier(0.22, 0.9, 0.24, 1));
    will-change: transform;
}
.ml-towerlane { position: absolute; inset: 0; z-index: 2; display: flex; justify-content: center; pointer-events: none; }
.ml-towerwrap {
    position: absolute; top: 0; height: var(--ml-tower-h, 250vh); aspect-ratio: var(--ml-tower-ar, 0.42);
    transform: translate(var(--ml-tower-x, 0px), var(--ml-cam-y, 0px));
    transition: transform var(--ml-glide, 2s cubic-bezier(0.22, 0.9, 0.24, 1));
    will-change: transform;
    filter: drop-shadow(0 0 40px rgba(0, 20, 40, 0.7));
}
.ml-towerwrap.noanim, .ml-parallax img.noanim { transition: none; }
.ml-towerwrap.entrysweep, .ml-parallax img.entrysweep { transition-duration: var(--ml-entry-ms, 3600ms); }
.ml-tower-img { width: 100%; height: 100%; display: block; position: relative; z-index: var(--ml-tower-img-z); }
/* Optional overlay ABOVE the rungs — porthole frames etc. Hidden until
   MYTH_CONFIG.assets.towerFront is given a URL. Same box as the tower art. */
.ml-tower-fg {
    position: absolute; inset: 0; width: 100%; height: 100%;
    z-index: var(--ml-tower-fg-z); pointer-events: none; display: none;
}
.ml-tower-fg[src]:not([src='']) { display: block; }
.ml-rungs { position: absolute; inset: 0; }
.ml-rung { position: absolute; width: var(--ml-portrait-w); transform: translate(-50%, -50%); translate: 0 calc(-1 * var(--ml-card-lift, 0px)); z-index: var(--ml-rung-z); }
.ml-rung .ml-rung-face {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; display: block;
    border-radius: 5px; border: 1px solid rgba(0,243,255,0.4); background: #070b14;
    transition: filter 0.6s ease, opacity 0.6s ease;
}
.ml-rung.next .ml-rung-face { filter: brightness(0.55) saturate(0.6); }
.ml-rung.now .ml-rung-face { animation: mlPulseRed 1.2s ease-in-out infinite; border-color: var(--ml-red); }
.ml-rung.down .ml-rung-face { filter: grayscale(1) brightness(0.4); }
.ml-rung.down::after {
    content: '✕'; position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: 300%; color: var(--ml-red);
    text-shadow: 0 0 16px rgba(255,43,74,0.8);
}
.ml-rung-label {
    margin-top: 3px; text-align: center; font-family: 'Orbitron', sans-serif; font-size: 10px;
    font-weight: 700; letter-spacing: 1px; color: rgba(230,240,255,0.85); text-transform: uppercase;
    text-shadow: 0 1px 3px rgba(0,0,0,0.9);
}
.ml-rung.boss .ml-rung-face { border-color: var(--ml-gold); }

/* ---------- ML5b: your-champion tiles - the accent frame ---------- */
.ml-tile.custom { border-color: rgba(21, 255, 0, 0.6); }
.ml-tile.custom .ml-tile-house { color: var(--ml-accent); }


.ml-heropanel {
    position: absolute; left: clamp(10px, 3vw, 46px); bottom: clamp(14px, 5vh, 60px); z-index: 4;
    width: var(--ml-portrait-w);   /* SAME var as .ml-rung — hero always matches opponents */
    translate: 0 calc(-1 * var(--ml-card-lift, 0px));
    /* ML4: rides the SAME glide token as the camera — same duration, same
       curve — so the hero stays locked to its opponent through the climb
       (the old `2s ease` arrived together but drifted mid-flight). */
    transition: top var(--ml-glide, 2s ease), left var(--ml-glide, 2s ease), opacity 0.45s ease;
}
.ml-heropanel.noanim { transition: none; }
.ml-heropanel.ml-hero-hidden { opacity: 0; }
.ml-heroframe img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; display: block;
    border-radius: 6px; border: 1px solid var(--ml-gold);
    box-shadow: 0 0 26px rgba(21,255,0,0.35), 0 16px 36px rgba(0,0,0,0.6);
}
/* ML4: the ladder shows the hero card ONLY — the name, house line and the
   little progress boxes are retired per the brief. Remove `display: none`
   to bring all three back (the markup and JS still populate them). */
.ml-heroplate { display: none; margin-top: 6px; text-align: center; }
.ml-hero-name { font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 14px; letter-spacing: 1px; color: #fff; }
.ml-hero-house { font-family: 'Rajdhani', sans-serif; font-size: 11px; letter-spacing: 2px; color: var(--ml-gold); }
.ml-hero-pips { margin-top: 5px; display: flex; justify-content: center; gap: 5px; }
.ml-hero-pips span { width: 12px; height: 12px; border-radius: 2px; border: 1px solid rgba(0,243,255,0.5); background: rgba(6,12,22,0.7); }
.ml-hero-pips span.won { background: var(--ml-gold); border-color: var(--ml-gold); box-shadow: 0 0 8px rgba(21,255,0,0.8); }

.ml-ladder-head { position: absolute; top: clamp(12px, 3vh, 30px); left: 0; right: 0; z-index: 4; text-align: center; pointer-events: none; }
.ml-ladder-title {
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: clamp(20px, 3.4vw, 34px);
    letter-spacing: 8px; color: #eef4ff; text-shadow: 0 0 20px rgba(0,243,255,0.5);
}
.ml-rung-counter { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 14px; letter-spacing: 4px; color: var(--ml-red); }
.ml-ladder-actions {
    position: absolute; right: clamp(10px, 3vw, 46px); bottom: clamp(14px, 5vh, 60px); z-index: 4;
    display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}

/* ---------- VS SPLASH ---------- */
.ml-vs-wrap {
    position: relative; z-index: 2; display: flex; align-items: center; justify-content: center;
    gap: clamp(10px, 4vw, 50px); padding: 0 16px;
}
.ml-vs-side { width: clamp(170px, 32vw, 460px); position: relative; }
.ml-vs-side img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; display: block;
    border-radius: 8px; box-shadow: 0 20px 60px rgba(0,0,0,0.7);
}
.ml-vs-left img { border: 1px solid var(--ml-gold); }
.ml-vs-right img { border: 1px solid var(--ml-red); }
@keyframes mlSlamL { from { transform: translateX(-70vw) skewX(6deg); } to { transform: translateX(0) skewX(0); } }
@keyframes mlSlamR { from { transform: translateX(70vw) skewX(-6deg); } to { transform: translateX(0) skewX(0); } }
.ml-vs-left  { animation: mlSlamL 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
.ml-vs-right { animation: mlSlamR 0.5s cubic-bezier(0.16, 1, 0.3, 1) both; }
.ml-vs-plate { text-align: center; margin-top: 8px; }
.ml-vs-name { font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: clamp(14px, 2vw, 20px); letter-spacing: 2px; color: #fff; }
.ml-vs-tag { font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 12px; letter-spacing: 3px; }
.ml-vs-tag-p1 { color: var(--ml-gold); }
.ml-vs-tag-com { color: var(--ml-red); }
.ml-vs-emblem {
    font-family: 'Bangers', 'Orbitron', sans-serif; font-size: clamp(48px, 9vw, 110px); color: var(--ml-red);
    text-shadow: 0 0 26px rgba(255,43,74,0.65), 0 5px 0 rgba(0,0,0,0.65);
    transform: skewX(-8deg);
}
.ml-vs-taunt {
    position: relative; z-index: 2; margin-top: 3vh; text-align: center; padding: 0 8vw;
    font-family: 'Rajdhani', sans-serif; font-size: clamp(14px, 2vw, 19px); font-style: italic;
    letter-spacing: 1px; color: rgba(225,235,250,0.9);
}
.ml-vs-hint {
    position: absolute; bottom: 4vh; left: 0; right: 0; z-index: 2; text-align: center;
    font-family: 'Orbitron', sans-serif; font-size: 12px; letter-spacing: 4px; color: rgba(0,243,255,0.7);
    animation: mlBlink 1.4s steps(2, start) infinite;
}

/* ---------- STORY PANEL ---------- */
.ml-story-wrap { position: relative; z-index: 2; max-width: 980px; margin: 0 auto; padding: 26px 18px 40px; text-align: center; }
.ml-story-wrap > * { zoom: var(--ml-story-zoom); }
.ml-story-kicker { font-family: 'Orbitron', sans-serif; font-size: 13px; font-weight: 700; letter-spacing: 6px; color: var(--ml-gold); margin-bottom: 14px; }
.ml-story-kicker.ending { color: var(--ml-cyan); }
.ml-story-panel {
    display: grid; grid-template-columns: 240px 1fr; gap: 20px; text-align: left;
    background: var(--ml-ink); border: 1px solid rgba(0,243,255,0.28); border-radius: 8px; padding: 20px;
    box-shadow: 0 24px 70px rgba(0,0,0,0.55);
}
.ml-story-art img {
    width: 100%; aspect-ratio: 3 / 4; object-fit: cover; object-position: top; display: block;
    border-radius: 6px; border: 1px solid rgba(21,255,0,0.5);
}
.ml-story-title { font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 20px; letter-spacing: 2px; color: #fff; margin-bottom: 10px; }
.ml-story-text {
    font-family: 'Rajdhani', sans-serif; font-size: 17px; line-height: 1.55; color: rgba(228,238,250,0.95);
    min-height: 140px; white-space: pre-wrap;
}
.ml-story-text .caret { display: inline-block; width: 9px; background: var(--ml-cyan); animation: mlBlink 0.8s steps(2,start) infinite; }
#ml-story-continue { margin-top: 20px; }

/* ML5c: the box no longer re-opens per line - a hidden ghost line reserves
   the height of the story's longest line, and the speaker plate keeps its
   space when a line has no speaker. */
.ml-story-text { display: grid; }
.ml-story-text > .ml-story-ghost, .ml-story-text > .ml-story-live { grid-area: 1 / 1; }
.ml-story-ghost { visibility: hidden; }

/* ML5b: the story box replayed the gm sheet's screen-entry motion every
   time showScreen('myth-story') fired (each beat re-adds .active). Killed
   for this screen alone - only the typewriter moves. */
#myth-story.screen, #myth-story.screen.active, #myth-story .ml-story-wrap, #myth-story .ml-story-panel {
    animation: none !important; transition: none !important;
}

.ml-story-who {
    margin: 14px auto 2px; font-family: 'Orbitron', sans-serif; font-size: 12px;
    font-weight: 700; letter-spacing: 5px; color: var(--ml-gold);
    text-shadow: 0 0 12px rgba(21,255,0,0.45);
}

/* ---------- CONTINUE? ---------- */
.ml-continue-wrap { position: relative; z-index: 2; text-align: center; padding-top: 14vh; }
.ml-continue-title {
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: clamp(34px, 6vw, 64px);
    letter-spacing: 10px; color: #fff; text-shadow: 0 0 30px rgba(255,43,74,0.6);
}
@keyframes mlCountPulse { 0% { transform: scale(1.35); opacity: 0.3; } 18% { transform: scale(1); opacity: 1; } 100% { transform: scale(0.96); opacity: 0.9; } }
.ml-count {
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: clamp(90px, 18vw, 190px);
    color: var(--ml-red); text-shadow: 0 0 46px rgba(255,43,74,0.75), 0 6px 0 rgba(0,0,0,0.6);
    line-height: 1; margin: 3vh 0;
}
.ml-count.tick { animation: mlCountPulse 1s ease-out; }
.ml-continue-btns { display: flex; flex-direction: column; align-items: center; gap: 12px; }
.ml-continue-foe {
    margin-top: 4vh; font-family: 'Rajdhani', sans-serif; font-size: 15px; font-style: italic;
    letter-spacing: 1px; color: rgba(235,210,215,0.85); padding: 0 8vw;
}

/* gm's celebration + toast layers are combat furniture — while any myth
   screen is up they stay in the arena, not over the story or the spoils. */
body:has(:is(#myth-select, #myth-ladder, #myth-vs, #myth-story, #myth-continue, #myth-item).screen.active)
    :is(#combat-highlight-overlay, #battle-notifications) { display: none !important; }

/* ---------- THE SPOILS (choose your item) ---------- */
.ml-item-wrap { position: relative; z-index: 2; max-width: 1100px; margin: 0 auto; padding: 26px 18px 40px; text-align: center; }
.ml-item-wrap > * { zoom: var(--ml-select-zoom); }
.ml-item-kicker { font-family: 'Orbitron', sans-serif; font-size: 13px; font-weight: 700; letter-spacing: 6px; color: var(--ml-gold); }
.ml-item-title {
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: clamp(22px, 3vw, 34px);
    letter-spacing: 7px; color: #eef4ff; text-shadow: 0 0 20px rgba(0,243,255,0.5); margin-top: 4px;
}
.ml-item-score {
    margin-top: 8px; font-family: 'Rajdhani', sans-serif; font-weight: 700; font-size: 15px;
    letter-spacing: 3px; color: rgba(0,243,255,0.85);
}
.ml-item-stage { display: flex; align-items: center; justify-content: center; gap: clamp(16px, 3vw, 40px); margin: 18px 0 6px; }
.ml-item-grid { display: grid; grid-template-columns: repeat(3, minmax(110px, 150px)); gap: 14px; }
.ml-item-tile img { aspect-ratio: 3 / 4; }
.ml-item-side {
    position: fixed; top: 0; bottom: 0; height: 100%; width: auto; max-width: 30vw;
    z-index: 1; opacity: 1; pointer-events: none;
}
/* The champion faces the centre whichever way the art was painted. */
.ml-item-side-l {
    left: 0; object-fit: cover; transform: scaleX(-1);
    -webkit-mask-image: linear-gradient(270deg, #000 55%, transparent);
    mask-image: linear-gradient(270deg, #000 55%, transparent);
}
img.ml-item-side:not([src]), img.ml-item-side[src=''] { display: none; }
/* The right side IS the beaten opponent: darkened, X-ed, named. */
#ml-item-foewrap { right: 0; min-width: 18vw; }
#ml-item-foewrap img {
    height: 100%; width: auto; max-width: 30vw; object-fit: cover; display: block;
    filter: brightness(0.42) saturate(0.7);
    -webkit-mask-image: linear-gradient(270deg, #000 55%, transparent);
    mask-image: linear-gradient(270deg, #000 55%, transparent);
}
#ml-item-foewrap img[src=''] { display: none; }
.ml-item-foex {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-family: 'Orbitron', sans-serif; font-weight: 900; font-size: min(26vh, 200px);
    color: var(--ml-red); text-shadow: 0 0 34px rgba(255,43,74,0.85);
}
.ml-item-foeplate { position: absolute; left: 0; right: 0; bottom: 5vh; text-align: center; }
.ml-item-foename { font-family: 'Orbitron', sans-serif; font-weight: 700; font-size: 17px; letter-spacing: 1px; color: #fff; text-shadow: 0 2px 10px #000; }
.ml-item-foetag { margin-top: 3px; font-family: 'Rajdhani', sans-serif; font-size: 12px; letter-spacing: 4px; color: var(--ml-red); }
#ml-item-take:disabled { opacity: 0.35; pointer-events: none; }

/* ---------- mobile ---------- */
@media (max-width: 900px) {
    :root {
        --ml-select-zoom: 1;                       /* no magnification on phones */
        --ml-story-zoom: 1;
    }
    .ml-item-stage { flex-direction: column; }
    .ml-item-side-l { display: none; }
    .ml-item-side, #ml-item-foewrap img { max-width: 38vw; }
    .ml-item-foex { font-size: min(18vh, 110px); }
    .ml-item-grid { grid-template-columns: repeat(3, minmax(88px, 1fr)); gap: 10px; }
    .ml-grid { --ml-cols: 3; --ml-gap: 10px; max-width: 420px; }
    /* ML6: the seat labels stand down with the side art they name. */
    .ml-seat, .ml-select-side, .ml-select-side-r { display: none; }
    .ml-story-panel { grid-template-columns: 1fr; }
    .ml-story-art img { max-width: 200px; margin: 0 auto; }
    .ml-hero-name { font-size: 11px; }
    .ml-ladder-actions { right: 10px; bottom: 12px; }
}

/* =============================================================================
   ML1b corrections
   ============================================================================= */

/* The gm .screen.active rule turns every screen into a centered flex box with
   20px padding — the myth screens are designed as block flow. ID specificity
   restores it without touching styles.css. */
#myth-ladder.screen.active, #myth-continue.screen.active {
    display: block;
    padding: 0;
}
/* ML2: story, vs and the spoils screen centre like the select does. */
#myth-story.screen.active, #myth-vs.screen.active, #myth-item.screen.active {
    display: flex;
    flex-direction: column;
    justify-content: safe center;
    padding: 0;
}
/* ML1e: the select screen is a flex column so .ml-select-wrap's margin:auto
   centres the body vertically AND horizontally — and, unlike
   justify-content:center, auto margins never clip the top when the content
   is taller than the viewport (it just scrolls). */
#myth-select.screen.active {
    display: flex;
    flex-direction: column;
    /* centres the body when it fits; 'safe' degrades to top-aligned +
       scrollable when it doesn't — plain 'center' (and auto margins) clip
       the top of overflowing content unreachably in Chromium. */
    justify-content: safe center;
    padding: 0;
}

/* Select + story can outgrow a short viewport — let them scroll, and pin their
   backdrop/scrim to the viewport so scrolling never reveals black below. */
#myth-select, #myth-story, #myth-item { overflow-y: auto; }
#myth-select .ml-bg, #myth-select .ml-scrim,
#myth-story .ml-bg, #myth-story .ml-scrim,
#myth-item .ml-bg, #myth-item .ml-scrim { position: fixed; }

/* gm's #fallback-background points at assets/… which is a 404 under
   /myth-engine/ — repoint it at the Drift backdrop so any transparent gap in
   any screen shows art, never raw black. Same specificity, later sheet: wins. */
#fallback-background { background-image: var(--ml-backdrop); }


/* ---------- ML5b: continue + reset share one line; the big side art ---------- */
.ml-select-footrow { display: flex; align-items: center; justify-content: center; gap: 18px; flex-wrap: wrap; margin-top: 10px; }
.ml-select-footrow .ml-continue-banner { margin: 0; }
.ml-select-footrow #ml-reset-progress { margin: 0; }
.ml-select-side { z-index: 1; max-width: 22vw; }   /* ML5c: under the wrap, and narrower so the centred grid clears it */
/* The right-hand select art: same fade-toward-centre mask as the spoils foe,
   no flip. Holds the COM placeholder until the 2P version lands. */
.ml-select-side-r {
    right: 0; object-fit: cover;
    -webkit-mask-image: linear-gradient(270deg, #000 55%, transparent);
    mask-image: linear-gradient(270deg, #000 55%, transparent);
}

