ui/toolpanel.razor.scss
// Tool settings — the column that sits to the RIGHT of the Q menu.
//
// Rendered as a CHILD of DevMenu's root, so it inherits that root's
// `pointer-events: none` and has to opt back in itself. Declaring neither makes
// a panel silently un-hit-testable in s&box — that was the lobby bug.
//
// ⚠️ ROW LAYOUT IS TWO LINES, NOT ONE. The first version crammed label, hint
// and a − value + control onto a single 340px line; the hint squeezed the label,
// the value had nowhere to go, and every edit was a click on a 24px target.
// Label and field share the top line, the hint gets its own underneath.

.toolpanel
{
    pointer-events: all;

    // ⚠️ Positioned from the CENTRE, not from the screen edge. Both this and the
    // dev menu are centred by the shared root, so the offset is half the Q
    // menu's 820px width plus a gutter. Anchoring to the right edge instead
    // would drift apart from it at every other resolution.
    position: absolute;
    left: 50%;
    margin-left: 426px;

    // Anchored at the top; height follows the content for short lists.
    top: 8%;

    width: 380px;

    flex-direction: column;
    background-color: rgba( 14, 16, 20, 0.97 );
    border: 1px solid rgba( 255, 255, 255, 0.12 );
    border-radius: 6px;
    overflow: hidden;

    // ⚠️ `bottom` AS WELL AS `top` — a DEFINITE height, not a max-height.
    //
    // DevMenu's frame is a flex CHILD, so its `max-height: 80%` gets applied by
    // flex layout and its body shrinks and scrolls. This panel is
    // position: absolute — out of flex flow — so nothing sized it, the
    // percentage max-height never clamped, and the rows just ran off the bottom
    // of the screen with no overflow for scrolling to act on.
    //
    // Only applied once the list is long enough to need it, so a two-row tool
    // does not get a full-height frame with nothing in it.
    &.tall { bottom: 8%; }

    .titlebar
    {
        flex-direction: row;
        align-items: center;
        padding: 12px 16px;
        background-color: rgba( 255, 255, 255, 0.05 );
        border-bottom: 1px solid rgba( 255, 255, 255, 0.08 );

        .title
        {
            font-size: 15px;
            color: #fff;
            flex-grow: 1;
        }

        .close
        {
            font-size: 15px;
            color: rgba( 255, 255, 255, 0.35 );
            padding: 2px 6px;
            border-radius: 4px;
            cursor: pointer;

            &:hover { color: #fff; background-color: rgba( 255, 255, 255, 0.10 ); }
        }
    }

    .rows
    {
        flex-direction: column;
        padding: 4px 0px;

        // Take everything between the titlebar and the footer, and scroll what
        // does not fit. flex-shrink is stated rather than assumed — without a
        // shrinkable, bounded box there is nothing for overflow to act on.
        flex-grow: 1;
        flex-shrink: 1;
        overflow-y: scroll;
    }

    // The titlebar and footer must NOT be squeezed to make room for the rows —
    // otherwise a long list eats the close button.
    .titlebar, .foot { flex-shrink: 0; }

    .row
    {
        // ⛔ `flex-shrink: 0` OR A BOUNDED PANEL CRAMS INSTEAD OF SCROLLING, AND THAT IS WHAT
        // "everything is trying to fit on screen at once and nothing is understandable" WAS.
        // `.rows` is a flex column with a DEFINITE height once `.tall` is on, and a flex child
        // here defaults to shrinkable — the two lines above exist precisely because it does. So
        // the rows were being squeezed to fit the box rather than overflowing it: labels, fields
        // and the option chips all compressed, and `overflow-y: scroll` had nothing to scroll
        // because nothing ever overflowed.
        //
        // ⚠️ THIS IS WHAT MAKES "SCROLLABLE" MEAN WHAT IT SOUNDS LIKE. Every row keeps the height
        // it would have had with no bound at all — the panel looks exactly as it did before it
        // was given one — and the surplus runs off the bottom of `.rows`, which is the thing the
        // scrollbar acts on. Rows shrinking and rows scrolling are alternatives, not partners.
        flex-shrink: 0;

        flex-direction: column;
        padding: 9px 16px;
        border-bottom: 1px solid rgba( 255, 255, 255, 0.05 );

        .head
        {
            flex-direction: row;
            align-items: center;
        }

        .label
        {
            flex-grow: 1;
            font-size: 14px;
            color: rgba( 255, 255, 255, 0.90 );
        }

        // Hint on its own line, dim. It is reference, not part of the control.
        .hint
        {
            font-size: 11px;
            color: rgba( 255, 255, 255, 0.30 );
            margin-top: 3px;
        }
    }

    // ── the controls ────────────────────────────────────────────────────────

    .field
    {
        flex-direction: row;
        align-items: center;
    }

    .entry
    {
        width: 108px;
        height: 28px;
        padding: 0px 8px;
        font-size: 14px;
        color: #ffd479;
        background-color: rgba( 0, 0, 0, 0.45 );
        border: 1px solid rgba( 255, 255, 255, 0.12 );
        border-radius: 4px;

        &:hover { border-color: rgba( 255, 255, 255, 0.28 ); }
        &:focus { border-color: #ffd479; color: #fff; }
    }

    .nudge
    {
        flex-direction: row;
        margin-left: 6px;

        .step
        {
            width: 26px;
            height: 28px;
            align-items: center;
            justify-content: center;
            font-size: 15px;
            color: rgba( 255, 255, 255, 0.50 );
            background-color: rgba( 255, 255, 255, 0.06 );
            cursor: pointer;

            &:first-child { border-radius: 4px 0px 0px 4px; margin-right: 1px; }
            &:last-child  { border-radius: 0px 4px 4px 0px; }

            &:hover { background-color: rgba( 255, 255, 255, 0.18 ); color: #fff; }
        }
    }

    // A toggle is a state, so it reads as one — not as a number you nudge.
    .toggle
    {
        width: 74px;
        height: 28px;
        align-items: center;
        justify-content: center;
        font-size: 13px;
        color: rgba( 255, 255, 255, 0.45 );
        background-color: rgba( 255, 255, 255, 0.06 );
        border: 1px solid rgba( 255, 255, 255, 0.10 );
        border-radius: 4px;
        cursor: pointer;

        &:hover { border-color: rgba( 255, 255, 255, 0.30 ); }

        &.on
        {
            color: #0e1014;
            background-color: #7ad17a;
            border-color: #7ad17a;
        }
    }

    // Pick-one chips. Same visual language as .toggle — both answer "which
    // state is this in?", so they should not look like different kinds of
    // control.
    //
    // ⚠️ WRAPS, and the row is allowed to grow. A weapon list is as long as the
    // pack is; forcing it onto one line would clip the options you cannot see
    // into ones you cannot reach.
    .swatches
    {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 4px;
        max-width: 240px;

        .swatch
        {
            width: 22px;
            height: 22px;
            border-radius: 3px;

            // A hairline so a white swatch still has an edge against the panel.
            border: 1px solid rgba( 0, 0, 0, 0.45 );
            cursor: pointer;

            &:hover { transform: scale( 1.12 ); }

            // ⚠️ RINGED, NOT TINTED. On a row of colours a "selected" highlight would be
            // one more colour competing with the twelve on show; an outset ring reads as
            // selection without changing what the swatch is showing.
            &.on
            {
                border: 2px solid #ffffff;
                box-shadow: 0px 0px 0px 2px rgba( 0, 0, 0, 0.6 );
            }
        }
    }

    .options
    {
        flex-direction: row;
        flex-wrap: wrap;
        justify-content: flex-end;
        gap: 4px;
        max-width: 240px;

        .opt
        {
            padding: 3px 8px;
            font-size: 12px;
            color: rgba( 255, 255, 255, 0.55 );
            background-color: rgba( 255, 255, 255, 0.06 );
            border: 1px solid rgba( 255, 255, 255, 0.10 );
            border-radius: 4px;
            cursor: pointer;

            &:hover { border-color: rgba( 255, 255, 255, 0.30 ); color: #fff; }

            &.on
            {
                color: #0e1014;
                background-color: #4fc9a8;   // teal — the Player-assisting colour
                border-color: #4fc9a8;
            }
        }
    }

    .info
    {
        font-size: 13px;
        color: rgba( 255, 255, 255, 0.40 );
    }

    .foot
    {
        padding: 9px 16px;
        font-size: 11px;
        color: rgba( 255, 255, 255, 0.28 );
        border-top: 1px solid rgba( 255, 255, 255, 0.08 );
    }
}