ui/weaponstatspanel.razor.scss
// WEAPON STATS card — bottom-right, over the HUD.
//
// ⚠️ Deliberately NOT centred and NOT modal. It is read while playing, next to
// the ammo counter it describes, so it must never take the middle of the screen
// away from the crosshair.

root {
    position: absolute;
    width: 100%;
    height: 100%;
    pointer-events: none;
    flex-direction: column;
    align-items: flex-end;
    justify-content: flex-end;
    font-family: Inter;   // ⚠️ NOT Consolas — it is not shipped and s&box
    // logged "Font 'Consolas' not found, falling back to system font",
    // which means the face was whatever the OS chose. Inter is the one
    // face this project actually ships.
}

.card {
    flex-direction: column;

    // ⚠️ 880, up from 720, FOR PACK-A-PUNCH. The value column is whatever the
    // label (210) and the bar (190 + 44 margins) leave behind, which at 720 was
    // about 212px — fine for "45" and far too tight for a packed shotgun's
    // "8 × 703.1 = 5624.8". x15.63 turns every damage figure into four digits and
    // the multi-pellet rows into three of them.
    // ⛔ CAPPED, BECAUSE THE ROW COUNT OUTGREW THE SCREEN. 18 rows at this type size
    // come to roughly 1010px before the 150px bottom margin, which overflows a 1080p
    // viewport and clips off the TOP — taking the weapon NAME with it, the one line that
    // tells you which gun you are reading. It grew a row at a time across three tiers of
    // tech and no single addition looked like the one that broke it.
    //
    // ⚠️ IT IS 24 ROWS NOW (counted off the array in Stats, not estimated) — tier 5 added
    // six, one per node that had nowhere else to appear. At the same 45px a row that is
    // roughly 1350px, so the cap and the scroll below are doing the work they were added
    // for and no style needed changing to take them.
    //
    // ⚠️ The margin also shrank 150 → 60. It existed to lift the card clear of the HUD's
    // ammo counter, and 60 still does that while buying back 90px.
    // ── NOW NINE ROWS, SO THE CARD TAKES THE HEIGHT RATHER THAN HUGGING ──
    //
    // `height`, NOT `max-height`. At 24 rows the content always overflowed and the cap was
    // what set the size; at 9 the content is far shorter than the screen, so a cap left the
    // card as a short block floating in the bottom corner with the rows crammed at the
    // authored 45px each. A fixed height makes the space real, and `.row`'s `flex-grow`
    // below is what spends it.
    //
    // The cap's original job is unchanged and still needed: `.rows` still scrolls, so
    // restoring rows to `RowOrder` cannot push the weapon NAME off the top of the screen.
    height: 92%;
    width: 880px;
    margin: 0px 48px 60px 0px;
    padding: 26px 32px 30px 32px;
    background-color: rgba(8, 8, 8, 0.88);
    border: 2px solid rgba(214, 168, 74, 0.45);
    border-radius: 2px;
}

.head {
    flex-direction: row;
    // ⚠️ WRAPS so the pack (`.pack`, below) can start a line of its own under the name, leaving this row as it was
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    padding-bottom: 16px;
    margin-bottom: 20px;
    border-bottom: 2px solid rgba(214, 168, 74, 0.25);

    .name {
        font-size: 42px;
        font-weight: bold;
        letter-spacing: 3px;
        color: #d6a84a;
    }

    // RARITY, immediately after the name.
    //
    // ⛔ NO `color` HERE ON PURPOSE. It is set inline from Rarity.HexFor so the five
    // colours live in one place in C# — the Arsenal's rarity tab needs the same
    // palette. Declaring a colour here as well would give the tier two sources, and
    // the dead one always reads like the authority.
    //
    // ⚠️ NO auto margin. `.wclass` below takes all the slack, so this stays in the
    // left group beside the name; giving this one an auto margin too would split the
    // slack between them and push the rarity into the middle of the header — the
    // exact failure the .wclass note records from when a third child was added.
    .rarity {
        margin-left: 18px;
        font-size: 24px;
        font-weight: bold;
        letter-spacing: 2px;
    }

    // The class, opposite the name.
    //
    // ⚠️ `margin-left: auto` RATHER THAN RELYING ON space-between. With two children
    // that rule put the name left and the hint right on its own; a third child lands
    // in the MIDDLE instead, which is not "the right side". The auto margin takes all
    // the slack before this element, pinning it and the hint together at the end.
    //
    // ⚠️ Deliberately quieter than the name — same gold, dimmed and smaller. It is a
    // qualifier for the title, and matching its weight would give the card two
    // competing headings.
    .wclass {
        margin-left: auto;
        margin-right: 18px;
        font-size: 22px;
        font-weight: bold;
        letter-spacing: 2px;
        color: rgba(214, 168, 74, 0.65);
    }

    .hint {
        font-size: 18px;
        letter-spacing: 1px;
        color: rgba(255, 255, 255, 0.3);
    }

    // THE PACK THE GUN CAME FROM ("PACK · BLACK OPS III", `PackLabel`), a line of its own under the name.
    //
    // ⚠️ THE WHOLE WIDTH, which is what puts it on a new line of the wrapping row. In the hint's grey, not the gold: a second
    // gold line would give the card two headings, the thing `.wclass` is dimmed to avoid.
    .pack {
        width: 100%;
        margin-top: 6px;
        font-size: 16px;
        font-weight: bold;
        letter-spacing: 2px;
        color: rgba(255, 255, 255, 0.45);
    }
}

// ⛔ THE ROWS SCROLL, THE HEAD DOES NOT — the weapon name and class stay pinned while a
// long list moves under them. Scrolling the whole card would take the name off screen,
// which is the exact failure the cap above exists to prevent.
//
// ⚠️ `.row` CARRIES `flex-shrink: 0` AND THAT IS LOAD-BEARING. This layout engine
// resolves an over-full container by COMPRESSING its children, not by overflowing them —
// so without it twenty-four 37px rows are silently squeezed into whatever height is left,
// drawn on top of each other, and no scrollbar ever appears. That failure cost two rebuilds
// of the Arsenal's tech page; see ArsenalPanel.razor.scss.
.rows {
    flex-direction: column;
    flex-grow: 1;
    gap: 8px;
    overflow-y: scroll;
}

.row {
    flex-direction: row;
    align-items: center;
    flex-shrink: 0;

    // ⛔ `flex-grow: 1` BESIDE `flex-shrink: 0`, AND BOTH MATTER. Grow spends the height the
    // nine rows do not need, so they distribute evenly down the full card instead of stacking
    // at the top. Shrink-0 is the older guard and is still load-bearing: this engine resolves
    // an over-full container by COMPRESSING children rather than overflowing them, so if rows
    // are ever restored to `RowOrder` they stop growing, refuse to compress, and scroll —
    // exactly as they did at 24. The two flags cover the two directions and neither replaces
    // the other.
    //
    // ⚠️ `align-items: center` above is what makes a taller row look intentional: the label,
    // track and figure stay on one centreline instead of riding the top edge.
    flex-grow: 1;

    .label {
        // ⚠️ Sized for the longest label at this font size. Too narrow and it wraps, which
        // knocks that one row taller than the rest.
        //
        // ⚠️ 260, UP FROM 210, BECAUSE THE TYPE GREW WITH THE ROW. Still "Rate of fire" that
        // sets it — 12 characters, and the longest of the nine ("Penetration" is 11). Checked
        // against the current `RowOrder`, not assumed from the old 24-row list.
        width: 260px;
        font-size: 32px;
        letter-spacing: 1px;
        color: rgba(255, 255, 255, 0.55);
    }

    // The bar is a comparison aid, so it sits BETWEEN label and number rather
    // than replacing either — the exact figure is what a player quotes.
    .track {
        // ⚠️ WIDER AND THICKER WITH THE TYPE. A 10px bar under 38px figures reads as a
        // hairline; the ratio to the row is what makes it legible, not the absolute size.
        // The value column is whatever the label (260) and the bar (240 + 44) leave of 880,
        // which is still comfortably wider than the 212px that forced the card to 880 for
        // Pack-a-Punch's four-digit damage strings.
        width: 240px;
        height: 14px;
        margin: 0px 22px;
        background-color: rgba(255, 255, 255, 0.09);

        .fill {
            height: 100%;
            background-color: #d6a84a;
            transition: width 0.12s ease-out;
        }
    }

    .value {
        flex-grow: 1;
        text-align: right;
        font-size: 38px;
        color: #f2ead8;

        // ⚠️ Digits are TABULAR so the column does not shimmer. Every one of these
        // rows changes as you swap weapons or pack one, and proportional figures
        // re-space the whole number when a 1 becomes a 7 — which reads as the panel
        // twitching rather than as the value changing.
        font-variant-numeric: tabular-nums;

        // Never let a long damage string wrap onto a second line — that alone
        // would make one row taller than the rest and break the grid.
        white-space: nowrap;
    }
}

// ═══ BASALT (`HudTheme`) — the map's face, Cinzel on the weapon's stats ═══
//
// *"i want the font for this map to affect … all hud messages that appear on screen"* (2026-09-27). The root wears the theme's class; the rules name it and each box
// here that sets Inter itself.
// ⛔ ON INTER'S LINE BOX, so no row grows taller: 0.898 of Cinzel's own line, which is Inter's 1.211 of the size. See
// `.round` in SurvivalHud.razor.scss for why it is not 1.211. It is wider on mixed-case text, which it sets in small capitals. Cinzel-Bold is the one face shipped,
// so every weight draws bold.
.theme-basalt
{
    font-family: Cinzel;
    line-height: 0.898;
}