ui/mapbrowser.razor.scss
// Map select — a fullscreen page over the lobby (2026-10-05): the maps down the left under the title and the two tabs,
// the one you're pointing at far right. Black Ops' "Mission select" for the layout; the lobby's look for the rest
// (Inter, strips with a left rule, the gold accent the config and map modals already used).
//
// ⛔ CLASS NAMES THE LOBBY DOESN'T USE. This page renders INSIDE the lobby's root, so every `.lobby .x` rule in
// LobbyMenu.razor.scss reaches any element of ours called `.x`. The first cut called its columns `.left` and `.right`
// and its backdrop `.bg` and `.scrim`: the lobby's 0.42 scrim won over ours (0.82), so the art showed through bright,
// and its `.right { margin-left: auto; width: 330px }` pulled the picture about. Keep to names that aren't in that file.
//
// ⚠️ Rendered inside the lobby's root, which is `pointer-events: none`, so this has to opt back
// in. A panel that declares neither is silently un-hit-testable in s&box — that was the lobby's
// own bug, and ConfigBrowser carries the same note.
//
// ⚠️ SIZES IN THE 1080-HIGH UI SPACE, like the lobby's.

$gold: #ffd479;

.mapselect
{
    font-family: Inter;

    position: absolute;
    top: 0px; left: 0px; right: 0px; bottom: 0px;
    width: 100%;
    height: 100%;

    pointer-events: all;

    // ⚠️ PLAIN BLACK FOR NOW (the user: *"i dont want to see the map background / for now make it black, i will get an
    // image later"*). The image goes here as `background-image` with `background-size: cover`; nothing else changes.
    background-color: #000;

    .page
    {
        position: absolute;
        top: 0px; left: 0px; right: 0px; bottom: 0px;
        width: 100%;
        height: 100%;
        flex-direction: row;

        // The lobby's `.content` padding, so the title lands where the brand was.
        padding: 56px 64px;
    }

    // ── the left column: title, tabs, names ─────────────────────────────────

    .select
    {
        flex-direction: column;
        width: 380px;
        flex-shrink: 0;
    }

    // The brand's size and weight: this page's name stands where the lobby's did.
    .title
    {
        font-size: 44px;
        font-weight: 600;
        color: #fff;
        text-transform: uppercase;
        letter-spacing: 2px;
    }

    .tabs
    {
        flex-direction: row;
        flex-shrink: 0;
        margin-top: 8px;

        // The underline carries the selection, not a filled pill: two pills read as two buttons rather than as one
        // thing with two states.
        .tab
        {
            padding: 8px 0px;
            margin-right: 28px;
            font-size: 14px;
            text-transform: uppercase;
            letter-spacing: 1.5px;
            color: #6f747c;
            border-bottom: 2px solid rgba( 0, 0, 0, 0 );
            cursor: pointer;

            &:hover { color: #c9cdd4; }

            &.on
            {
                color: #fff;
                border-bottom: 2px solid $gold;
            }
        }
    }

    // ⚠️ THE CHOSEN MAP, WHERE THE TABS STAND ON THE MAPS (the gamemode step, 2026-10-05): drawn as the one tab that is on.
    .modeof
    {
        flex-shrink: 0;
        align-self: flex-start;
        margin-top: 8px;
        padding: 8px 0px;
        font-size: 14px;
        text-transform: uppercase;
        letter-spacing: 1.5px;
        color: #fff;
        border-bottom: 2px solid $gold;
    }

    .tabhint
    {
        flex-shrink: 0;
        margin-top: 10px;
        margin-bottom: 20px;
        font-size: 13px;
        color: #7d828a;
    }

    .list
    {
        flex-direction: column;
        flex-grow: 1;
        flex-shrink: 1;

        // ⛔ THE LIST SCROLLS; ITS ROWS DO NOT SHRINK. Survival has 19 maps, more than the column's height holds at
        // this row size. With the flex default every row would absorb the difference and their names would print on
        // top of one another, which is what the lobby's own column did before it got the same rule.
        overflow-y: scroll;

        .empty
        {
            padding: 20px 4px;
            font-size: 14px;
            color: #6b7078;
        }

        // ⚠️ SOLID, NOT TRANSLUCENT (the user: *"the map selection should not be transparent"*). Shaped like the
        // lobby's `.opt` rows, a strip with a left rule, in opaque greys.
        .row
        {
            flex-direction: row;
            align-items: center;
            flex-shrink: 0;
            padding: 10px 16px;
            margin-bottom: 4px;
            background-color: #111317;
            border-left: 2px solid #2a2e36;
            cursor: pointer;

            .name
            {
                flex-grow: 1;
                font-size: 17px;
                color: #b9bec6;
            }

            .badge
            {
                font-size: 11px;
                text-transform: uppercase;
                letter-spacing: 1.2px;
                color: $gold;
            }

            &:hover
            {
                background-color: #191c22;
                .name { color: #fff; }
            }

            // ⚠️ "ON" IS THE PREVIEWED MAP, which stays lit when the cursor leaves the list, so the picture on the right
            // always says whose it is.
            &.on
            {
                background-color: #1f232a;
                border-left: 2px solid $gold;
                .name { color: #fff; }
            }
        }
    }

    .back
    {
        flex-shrink: 0;
        align-self: flex-start;
        margin-top: 18px;
        padding: 10px 18px;
        font-size: 15px;
        color: #a3a8b0;
        background-color: #111317;
        border-left: 2px solid #2a2e36;
        cursor: pointer;

        &:hover
        {
            color: #fff;
            background-color: #191c22;
            border-left: 2px solid #5a5f68;
        }
    }

    // ── the map you're pointing at, far right ───────────────────────────────

    // ⚠️ PUSHED TO THE RIGHT EDGE (`margin-left: auto`), at the card's own size (the user: *"the map image should go a
    // lot more to the right, be smaller, and the name should be a lot bigger and the description bigger too"*).
    .detail
    {
        flex-direction: column;
        flex-shrink: 0;
        width: 640px;
        margin-left: auto;
        justify-content: center;
        align-items: flex-start;
    }

    .dname
    {
        font-size: 60px;
        font-weight: 700;
        color: #fff;
        text-transform: uppercase;
        letter-spacing: 1px;
        margin-bottom: 16px;
    }

    // ⚠️ 640 × 360, the cards' own resolution, so the picture is drawn 1:1 at 1080p rather than stretched.
    .dart
    {
        width: 640px;
        height: 360px;
        flex-shrink: 0;
        background-size: cover;
        background-position: center;
        background-color: #111317;
        border: 1px solid #2a2e36;
        align-items: center;
        justify-content: center;

        .noimg
        {
            font-size: 120px;
            font-weight: 600;
            color: #2a2e36;
        }
    }

    // ⚠️ THE GAMEMODE POINTED AT, UNDER THE MAP'S PICTURE (the gamemode step, 2026-10-05). The map's name stays the big one.
    .dmode
    {
        margin-top: 18px;
        font-size: 30px;
        font-weight: 600;
        color: $gold;
        text-transform: uppercase;
        letter-spacing: 1px;
    }

    .ddesc
    {
        width: 640px;
        margin-top: 18px;
        font-size: 22px;
        color: #c9cdd4;
    }

    .dmeta
    {
        margin-top: 14px;
        font-size: 14px;
        text-transform: uppercase;
        letter-spacing: 1.5px;
        color: #6f747c;

        &.loaded { color: $gold; }

        // ⚠️ The lobby's own "can't ready" red (`.opt.disabled .opt-desc`): the same warning, said before the click.
        &.unset { color: #d97a7a; }
    }

    // ── loading ─────────────────────────────────────────────────────────────
    //
    // ⛔ NOT AN OVERLAY. The page's ordinary content while a map loads, so it is plain flexbox with nothing to
    // mis-measure — and it blocks interaction by construction, because the tabs and rows are simply not rendered.

    .loadpage
    {
        position: absolute;
        top: 0px; left: 0px; right: 0px; bottom: 0px;
        width: 100%;
        height: 100%;
        align-items: center;
        justify-content: center;
    }

    .loadpane
    {
        flex-direction: column;
        align-items: center;
        width: 520px;

        .loadtitle
        {
            font-size: 26px;
            font-weight: 600;
            color: #fff;
            text-align: center;
        }

        .loadstatus
        {
            margin-top: 8px;
            font-size: 14px;
            color: #7d828a;
        }

        .loaddetail
        {
            margin-top: 4px;
            font-size: 12px;
            color: #5c6169;
            font-family: Consolas;
        }

        .loadbar
        {
            width: 100%;
            height: 4px;
            margin-top: 22px;
            border-radius: 2px;
            background-color: #1f232a;
            overflow: hidden;

            // ⛔ A TRAVELLING STRIPE, NOT A GROWING FILL. There is no download-progress API for a
            // package mount, so a fill would be an animation pretending to be a measurement — and
            // the moment it sat at 80% for a minute it would read as a hang.
            .loadfill
            {
                width: 34%;
                height: 100%;
                border-radius: 2px;
                background-color: $gold;
                animation-name: mapload;
                animation-duration: 1.1s;
                animation-timing-function: ease-in-out;
                animation-iteration-count: infinite;
            }
        }
    }
}

// ⚠️ AT FILE SCOPE, NOT NESTED. s&box's SCSS does not hoist a @keyframes out of a selector block —
// nested, the rule compiles and the animation simply never runs, which looks like a frozen bar.
@keyframes mapload
{
    0%   { margin-left: -34%; }
    100% { margin-left: 100%; }
}