/* ===========================================================================
   THE BUTTON CHASSIS — soft-cornered plate.
   ===========================================================================

   ONE shape for every action in the game. The notes below are the reasons,
   because every one of them was arrived at by getting it wrong first.

   ▶ WHY THIS IS ITS OWN FILE, LINKED LAST.
   The chassis started in globalv2.css and did not survive. globalv2 is in the
   cssGlobal bundle, which global.head.php links FIRST — every page bundle and
   theme-overrides.css load after it, and ELEVEN of those declared their own
   button. `.rot-btn` alone was defined three times (globalv2, the confirm
   dialog, and rot-shell.css, which is deliberately last in cssGlobal and so
   beat both of the others). The symptom was perfect and misleading: the
   clip-path applied and measured correctly, and the button still rendered as a
   grey rounded rectangle, because nine flat declarations were painting over a
   fully-resolved chassis. A chassis that everything overrides is not a
   chassis. This file is linked after theme-overrides.css in global.head.php
   and it is the last word on what a button looks like.

   ▶ THE LEGACY CLASSES ARE THE CHASSIS, NOT ALIASES OF IT.
   `.btn`, `.buy-button`, `.course-button`, `.action-button`,
   `.certificate-button`, `.btn-forum`, `.donate-button`, `.iw-save`,
   `.btn-lottery`, `.btn-search`, `.apply-btn`, `.spy-empty-action`,
   `.btn-delete-account`, `.cards-customize-btn`, `.fr-refer-btn`, `.rot-actbtn`,
   `.action-btn`
   and `.primary-action` were
   fourteen parallel button sets. They are all selected here rather than being
   rewritten across a few hundred templates: same result, no markup churn, and
   any page still emitting an old class gets the new button for free. New
   markup should use `.rot-btn` plus a tier.

   ▶ `button:not([class])` IS THE SAFETY NET, and it is why every list below
   carries it. 108 `<button>`/`<input type=submit>` elements in the game have no
   class at all, and NOTHING styled a bare `<button>` — not globalv2, not
   rot-shell — so they rendered as the browser's grey box next to a chassis
   button. `:not([class])` means it can only ever catch a button nobody styled;
   the moment one gets a class, its own CSS takes over again.

   ▶ INPUTS ARE DELIBERATELY NOT ON THE CHASSIS. `input::before` does not exist,
   so an `<input type=submit>` would get the element background — the 1px STROKE
   colour — as a solid fill, with no face drawn over it. It would be a filled
   grey slab at rest instead of a hollow button. Bare submit inputs are styled
   in globalv2.css:1299 instead, and that rule is already on the same radius
   token. Do not "finish the job" by adding them here.

   THE SHAPE — a plain rectangle with 6px corners. That is all it is.

   ▶ THE CHAMFER IS GONE (2026-08-07). It was a large cut off the bottom-right
   with a "fold" drawn inside it, and it did not survive contact with the whole
   site. Thesifer: *"once I see it all across the site, it just doesn't look
   right."* Do not reintroduce it as a variant on a subset of buttons — the
   point of one chassis is that there is one shape.

   ▶ THE RADIUS IS THE TOKEN, NOT A NUMBER. `--rot-radius-control` (6px,
   globalv2.css:134) is what the whole rest of the game already rounds its
   controls to — and that is exactly why the chamfer read as drift: every
   non-chassis button on the site was a 6px rectangle sitting next to a cut
   one. Thesifer named `.train-go` ("Begin Training") as the shape that looks
   right; it is 6px. So the chassis takes the token, and a button that hardcodes
   its own radius is a straggler, not a variant — see the list at the bottom.

   ▶ THE OUTLINE IS ITS OWN LAYER, and stays that way. The element's own
   background IS the 1px stroke and ::before is the face inset 1px inside it.
   That is inherited from the chamfer (a clip-path clips the border too, so a
   real border could not be used) and it is kept because every tier, state and
   seat below is already tuned against it — the ::before face is what hover
   fills, what press darkens and what focus draws brackets on. Swapping it for
   `border: 1px solid` is a rewrite of all five states, not a simplification.
   The inner radius is 1px tighter than the outer so the ring stays even.

   ▶ A stroked ring needs an OPAQUE face — you cannot draw a 1px ring through a
   transparent fill. The face is mixed against --rot-btn-seat, the surface the
   button sits on, declared on CONTAINERS at the bottom of this file rather
   than on every button. If a button ever looks like it has a coloured wash
   over the whole face instead of a thin edge, that variable is wrong for where
   it is standing.

   THE STATES — the same five everywhere, and the meaning is in the light:
     rest      hollow. seat behind a 1px tier stroke, tier ink, faint halo
     hover     solid tier gradient, ink flips to the on-colour, glow ON
     pressed   deeper solid, GLOW OFF, 1px down
     focus     hollow again + corner brackets + a shaped halo
     disabled  the tier drops out entirely; flat, colourless, no depth

   The glow going OUT on press is what sells the press, more than the 1px of
   travel does. Do not "fix" a weak press by making it move further.

   ▶ BRACKETS ARE THE FOCUS STATE AND NOTHING ELSE. Tried and rejected twice as
   a resting chassis for reading as clutter; as a lock-on frame they are right.

   ▶ SOLID BRASS STILL MEANS "YOU ARE HERE". A primary button is hollow at rest
   because the main nav fills its active tab with solid brass. Hover is where
   the fill happens. See --rot-accent in globalv2.css.
   =========================================================================== */

.rot-btn,
.btn,
.buy-button,
.course-button,
.action-button,
.certificate-button,
.btn-forum,
.donate-button,
.iw-save,
.iw-cancel,
.btn-lottery,
.btn-search,
.apply-btn,
.spy-empty-action, .btn-delete-account, .cards-customize-btn, .fr-refer-btn, .rot-actbtn, .action-btn, .primary-action,
button:not([class]) {
    /* the tier — overridden by the modifiers below. neutral by default. */
    --rot-btn-rgb: var(--rot-fac-rgb);
    --rot-btn-tier: #97a3b0;
    --rot-btn-ink: var(--rot-text-strong);
    --rot-btn-on: #0d1116;
    --rot-btn-bracket: #dfe6ed;

    --rot-btn-seat: var(--rot-panel-fill);
    --rot-btn-face: color-mix(in srgb, var(--rot-btn-tier) 7%, var(--rot-btn-seat));
    --rot-btn-press: color-mix(in srgb, var(--rot-btn-tier) 74%, #000);
    --rot-btn-r: var(--rot-radius-control);

    appearance: none;
    -webkit-appearance: none;
    cursor: pointer;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    min-height: 38px;
    padding: 0 18px;
    box-sizing: border-box;
    position: relative;
    z-index: 0;
    isolation: isolate;
    border: 0;
    border-radius: var(--rot-btn-r);
    /*  ▶ THE ELEMENT'S OWN BACKGROUND IS THE SURFACE THE INK IS CHOSEN FOR.
        It used to be the TIER -- solid brass on a primary button -- with the readable dark
        face supplied only by ::before at z-index -2. That made legibility depend on a
        negative-z pseudo-element painting over its own parent's background, and when that
        does not happen the button is brass ink on brass fill. Reported from the daily-reward
        modal, whose Claim Reward button is focused the moment it opens: a solid pale-brass
        slab with ghost text and no corner brackets, i.e. no ::before at all. Reproduced
        exactly by suppressing the pseudo-element.
        The stroke is an inset shadow now, so every state stays legible on the element alone
        and ::before is decoration. Each state below sets the element background to match
        what its face shows -- change one, change the other. */
    background: var(--rot-btn-face);
    box-shadow: inset 0 0 0 1px var(--rot-btn-tier);
    color: var(--rot-btn-ink);
    font-family: var(--rot-font-ui);
    font-size: 12.5px;
    font-weight: 700;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    line-height: 1;
    text-align: center;
    /*  NO RESTING GLOW. It was drop-shadow(0 0 4px) on every button, and
        inventory.php renders 572 of them in one list — a composited shadow per
        button for an effect measurable only with a colour picker. The glow now
        exists solely to mark hover and focus, which is also where the
        reference put the emphasis. */
    transition: background 0.13s, box-shadow 0.13s, color 0.13s, filter 0.13s, transform 0.07s;
}

/*  THE FACE, inset 1px inside the stroke.
    The resets at the bottom are not defensive noise: several of these classes
    already used ::before for a shine sweep or a glyph (forums.css:827,
    jobs.css:385), and an inherited `width:0` or a running animation on the
    face layer is invisible until someone hovers the one page that had it. */
.rot-btn::before,
.btn::before,
.buy-button::before,
.course-button::before,
.action-button::before,
.certificate-button::before,
.btn-forum::before,
.donate-button::before,
.iw-save::before,
.iw-cancel::before,
.btn-lottery::before,
.btn-search::before,
.apply-btn::before,
.spy-empty-action::before, .btn-delete-account::before, .cards-customize-btn::before, .fr-refer-btn::before, .rot-actbtn::before, .action-btn::before, .primary-action::before,
button:not([class])::before {
    content: '';
    position: absolute;
    inset: 1px;
    z-index: -2;
    background: var(--rot-btn-face);
    border-radius: calc(var(--rot-btn-r) - 1px);
    transition: inherit;
    animation: none;
    opacity: 1;
    width: auto;
    height: auto;
    border: 0;
    transform: none;
    box-shadow: none;
}

/*  The chassis used to own ::after as well — the "fold" that made the chamfer
    read as a cut rather than a missing corner. Both are gone with the chamfer,
    so ::after belongs to the call site again. Do not claim it here without
    checking: several of these classes already use it (the blocked-nav padlock
    at rot-shell.css:2377 is the one that nearly got eaten). */

.rot-btn > i, .btn > i, .buy-button > i, .course-button > i, .action-button > i,
.certificate-button > i, .btn-forum > i, .donate-button > i, .btn-lottery > i,
.btn-search > i, .apply-btn > i, .spy-empty-action > i,
.btn-delete-account > i, .cards-customize-btn > i, .fr-refer-btn > i, .rot-actbtn > i,
.action-btn > i, .primary-action > i,
button:not([class]) > i {
    font-size: 12px;
    line-height: 1;
    margin: 0;
}

/* ---- sizes ---- */
/*  Size changes height and type only. The radius is DELIBERATELY not scaled:
    the chamfer had to grow with the button to stay legible as a cut, a 6px
    corner does not, and three different radii is how "slightly curved" turns
    back into drift. */
/*  `.btn-forum.small` is the forums' own name for this size — Edit, Delete and
    Quote on a post. It is listed here rather than renamed in ~55 places of
    markup, which is the same bargain every other legacy class in this file
    already gets (.buy-button, .course-button, .apply-btn...). */
.rot-btn--sm, .btn-sm, .btn.btn-sm, .btn-forum.small {
    min-height: 32px;
    padding: 0 14px;
    font-size: 11.5px;
}
.rot-btn--lg, .btn-lg { min-height: 46px; padding: 0 24px; font-size: 13.5px; }
.rot-btn--block, .btn-block { width: 100%; }

/* ---- hover: the fill arrives and the light comes on ---- */
.rot-btn:hover, .btn:hover, .buy-button:hover, .course-button:hover,
.action-button:hover, .certificate-button:hover, .btn-forum:hover,
.donate-button:hover, .iw-save:hover, .iw-cancel:hover, .btn-lottery:hover,
.btn-search:hover, .apply-btn:hover, .spy-empty-action:hover, .btn-delete-account:hover, .cards-customize-btn:hover, .fr-refer-btn:hover, .rot-actbtn:hover, .action-btn:hover, .primary-action:hover,
button:not([class]):hover {
    color: var(--rot-btn-on);
    /*  The same gradient the face takes below. --rot-btn-on is a dark ink, so the element
        underneath has to be the lit fill or a missing face leaves dark on dark. */
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--rot-btn-tier) 82%, #fff) 0%,
        var(--rot-btn-tier) 58%,
        color-mix(in srgb, var(--rot-btn-tier) 88%, #000) 100%);
    text-decoration: none;
    transform: none;
    filter: drop-shadow(0 3px 10px rgba(var(--rot-btn-rgb), 0.45));
}
.rot-btn:hover::before, .btn:hover::before, .buy-button:hover::before,
.course-button:hover::before, .action-button:hover::before,
.certificate-button:hover::before, .btn-forum:hover::before,
.donate-button:hover::before, .iw-save:hover::before, .iw-cancel:hover::before,
.btn-lottery:hover::before, .btn-search:hover::before, .apply-btn:hover::before,
.spy-empty-action:hover::before, .btn-delete-account:hover::before, .cards-customize-btn:hover::before, .fr-refer-btn:hover::before, .rot-actbtn:hover::before, .action-btn:hover::before, .primary-action:hover::before,
button:not([class]):hover::before {
    background: linear-gradient(180deg,
        color-mix(in srgb, var(--rot-btn-tier) 82%, #fff) 0%,
        var(--rot-btn-tier) 58%,
        color-mix(in srgb, var(--rot-btn-tier) 88%, #000) 100%);
    left: auto;
    right: auto;
    width: auto;
    opacity: 1;
}

/* ---- pressed: deeper, and the light goes out ---- */
.rot-btn:active, .btn:active, .buy-button:active, .course-button:active,
.action-button:active, .certificate-button:active, .btn-forum:active,
.donate-button:active, .iw-save:active, .iw-cancel:active, .btn-lottery:active,
.btn-search:active, .apply-btn:active, .spy-empty-action:active, .btn-delete-account:active, .cards-customize-btn:active, .fr-refer-btn:active, .rot-actbtn:active, .action-btn:active, .primary-action:active,
button:not([class]):active {
    color: var(--rot-btn-on);
    background: var(--rot-btn-press);
    transform: translateY(1px);
    filter: none;
}
.rot-btn:active::before, .btn:active::before, .buy-button:active::before,
.course-button:active::before, .action-button:active::before,
.certificate-button:active::before, .btn-forum:active::before,
.donate-button:active::before, .iw-save:active::before, .iw-cancel:active::before,
.btn-lottery:active::before, .btn-search:active::before, .apply-btn:active::before,
.spy-empty-action:active::before, .btn-delete-account:active::before, .cards-customize-btn:active::before, .fr-refer-btn:active::before, .rot-actbtn:active::before, .action-btn:active::before, .primary-action:active::before,
button:not([class]):active::before { background: var(--rot-btn-press); }

/* ---- focus: hollow again, brackets, and a shaped halo ---- */
.rot-btn:focus, .btn:focus, .buy-button:focus, .course-button:focus,
.action-button:focus, .certificate-button:focus, .btn-forum:focus,
.donate-button:focus, .iw-save:focus, .iw-cancel:focus, .btn-lottery:focus,
.btn-search:focus, .apply-btn:focus, .spy-empty-action:focus, .btn-delete-account:focus, .cards-customize-btn:focus, .fr-refer-btn:focus, .rot-actbtn:focus, .action-btn:focus, .primary-action:focus,
button:not([class]):focus {
    outline: none;
    /*  Not `box-shadow: none` -- the stroke lives in the inset shadow now, and clearing it
        left a focused button with no edge at all. */
    box-shadow: inset 0 0 0 1px var(--rot-btn-tier);
}
.rot-btn:focus-visible, .btn:focus-visible, .buy-button:focus-visible,
.course-button:focus-visible, .action-button:focus-visible,
.certificate-button:focus-visible, .btn-forum:focus-visible,
.donate-button:focus-visible, .iw-save:focus-visible, .iw-cancel:focus-visible,
.btn-lottery:focus-visible, .btn-search:focus-visible, .apply-btn:focus-visible,
.spy-empty-action:focus-visible, .btn-delete-account:focus-visible, .cards-customize-btn:focus-visible, .fr-refer-btn:focus-visible, .rot-actbtn:focus-visible, .action-btn:focus-visible, .primary-action:focus-visible,
button:not([class]):focus-visible {
    color: var(--rot-btn-ink);
    /*  ▶ THIS IS THE ONE THAT WAS REPORTED. It painted the ELEMENT
        `color-mix(tier 70%, #fff)` -- near-white brass -- while the ink stayed
        --rot-btn-ink, the LIGHT ink meant for the dark hollow face. Legible only while
        ::before covered the fill; the instant it did not, brass on brass at about 1.1:1.
        "Hollow again" is the intent, so the element keeps the dark face and the brightened
        tier goes on the stroke, where it reads as focus without ever being the text's
        background. */
    background: var(--rot-btn-face);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--rot-btn-tier) 70%, #fff);
    filter: drop-shadow(0 0 7px rgba(var(--rot-btn-rgb), 0.7));
}
.rot-btn:focus-visible::before, .btn:focus-visible::before,
.buy-button:focus-visible::before, .course-button:focus-visible::before,
.action-button:focus-visible::before, .certificate-button:focus-visible::before,
.btn-forum:focus-visible::before, .donate-button:focus-visible::before,
.iw-save:focus-visible::before, .iw-cancel:focus-visible::before,
.btn-lottery:focus-visible::before, .btn-search:focus-visible::before,
.apply-btn:focus-visible::before, .spy-empty-action:focus-visible::before, .btn-delete-account:focus-visible::before, .cards-customize-btn:focus-visible::before, .fr-refer-btn:focus-visible::before, .rot-actbtn:focus-visible::before, .action-btn:focus-visible::before, .primary-action:focus-visible::before,
button:not([class]):focus-visible::before {
    background: var(--rot-btn-face);
    background-image:
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket)),
        linear-gradient(var(--rot-btn-bracket), var(--rot-btn-bracket));
    background-repeat: no-repeat;
    background-size: 12px 2px, 2px 12px, 12px 2px, 2px 12px,
                     12px 2px, 2px 12px, 12px 2px, 2px 12px;
    background-position:
        2px 2px, 2px 2px,
        calc(100% - 2px) 2px, calc(100% - 2px) 2px,
        2px calc(100% - 2px), 2px calc(100% - 2px),
        calc(100% - 2px) calc(100% - 2px), calc(100% - 2px) calc(100% - 2px);
}

/* ---- disabled: the tier drops out, so it can never read as a dim live one ---- */
.rot-btn[disabled], .btn[disabled], .buy-button[disabled], .course-button[disabled],
.action-button[disabled], .certificate-button[disabled], .btn-forum[disabled],
.donate-button[disabled], .iw-save[disabled], .btn-lottery[disabled],
.btn-search[disabled], .apply-btn[disabled],
/*  ▶ THESE WERE MISSING and it showed: the ammo grid renders belt buttons
    disabled to explain why a round will not chamber, and they came out at full
    brass with cursor:pointer — a dead control that looked live. Every class the
    chassis claims needs its [disabled] form here too, or `disabled` is
    decorative on that class.  */
.action-btn[disabled], .primary-action[disabled], .rot-actbtn[disabled],
.btn-delete-account[disabled], .cards-customize-btn[disabled], .fr-refer-btn[disabled],
.spy-empty-action[disabled], .iw-cancel[disabled],
.rot-btn.is-disabled, .btn.disabled, .action-button.disabled, .action-btn.disabled,
.rot-btn[aria-disabled="true"], .btn[aria-disabled="true"],
.action-btn[aria-disabled="true"] {
    cursor: not-allowed;
    --rot-btn-rgb: 70, 76, 84;
    --rot-btn-tier: #2b3036;
    --rot-btn-ink: #585c60;
    --rot-btn-face: #171b20;
    filter: none !important;
    transform: none !important;
}
.rot-btn[disabled]:hover::before, .btn[disabled]:hover::before,
.action-button.disabled:hover::before, .btn.disabled:hover::before,
.rot-btn.is-disabled:hover::before,
.rot-btn[aria-disabled="true"]:hover::before {
    background: var(--rot-btn-face);
}

/* ---- latched: the control is currently ON -------------------------------
    A MODE, not an action. Customize/Done on the profile is the case that named
    it: while you are dragging cards the button is not something you can press
    to reorder, it is the state the page is IN, and the brass rule says a FILLED
    brass block means "you are here".

    ▶▶ IT SETS THE TOKENS, NOT `background`. This is the whole reason the state
    lives here instead of at the call site. The chassis paints in two layers --
    the element carries the background the ink was chosen for, and ::before
    repaints it as the face, inset inside the stroke. A call-site rule that says
    `background: <brass>; color: <dark ink>` only reaches the ELEMENT; ::before
    keeps painting `var(--rot-btn-face)` over the top, so the button is dark ink
    on the default dark face and cannot be read until you hover it, at which
    point the chassis's own :hover::before finally lights the face and it
    reappears. That is precisely how it was reported: *"a few of these buttons
    aren't really visible unless you hover over them while they're active."*

    Overriding --rot-btn-face and --rot-btn-ink instead means BOTH layers follow
    from one declaration and cannot disagree -- the same trick [disabled] above
    uses. Hover still wins on top, because those rules set `background`
    directly, so a latched button keeps its feedback.

    ▶ AND IT IS TIER-AGNOSTIC. The face is mixed from --rot-btn-tier, so a
    latched danger button goes red and a latched neutral goes steel without
    anyone writing a second rule.

    Any new "this control is on" state belongs on this list. Do not hand-roll
    one -- run tools/boxsweep_buttons.py, which fails on exactly that mistake. */
.rot-btn.is-on,
.btn.is-on,
.rot-actbtn.is-on,
.action-btn.is-on,
.primary-action.is-on,
.cards-customize-btn.is-editing,
.rot-btn[aria-pressed="true"],
.rot-actbtn[aria-pressed="true"],
.action-btn[aria-pressed="true"] {
    --rot-btn-face: linear-gradient(180deg,
        color-mix(in srgb, var(--rot-btn-tier) 82%, #fff) 0%,
        var(--rot-btn-tier) 58%,
        color-mix(in srgb, var(--rot-btn-tier) 88%, #000) 100%);
    --rot-btn-ink: var(--rot-btn-on);
}

/* =============================== THE TIERS ===============================
   Brass = the primary action. Red = destructive or hostile. Neutral = the
   rest. These are the ONLY three; a fourth colour on a button means a meaning
   is being invented at the call site.

   The legacy modifier classes are listed against the tier they belong to
   rather than being renamed, so old markup lands on the right tier untouched.
   ========================================================================= */
.rot-btn--primary,
.btn-primary,
.buy-button,
.course-button,
.certificate-button,
.donate-button,
.btn-lottery,
.btn-search,
.apply-btn,
.spy-empty-action, .btn-delete-account, .cards-customize-btn, .fr-refer-btn, .rot-actbtn, .action-btn, .primary-action,
.iw-save,
.btn-forum.primary,
.rot-btn.is-primary,
.primary-action,
.action-button:not(.danger):not(.disabled) {
    --rot-btn-rgb: var(--rot-accent-rgb);
    --rot-btn-tier: var(--rot-accent);
    --rot-btn-ink: var(--rot-accent-strong);
    --rot-btn-on: var(--rot-accent-contrast);
    --rot-btn-bracket: var(--rot-accent-strong);
}

.rot-btn--danger,
.btn-danger,
.btn-delete-account,
.action-button.danger,
.btn-forum.danger,
.rot-modal--danger .rot-btn--primary {
    --rot-btn-rgb: var(--rot-danger-rgb);
    --rot-btn-tier: var(--rot-danger);
    /*  NOT --rot-danger-text (#ffe9e9). Near-white resting ink loses the tier
        entirely on a hollow button — you cannot tell a danger button from a
        neutral one until you hover it. This is the readable red. */
    --rot-btn-ink: #e8635d;
    --rot-btn-on: var(--rot-on-danger);
    --rot-btn-bracket: #ff8a84;
}

.rot-btn--neutral,
.rot-btn--ghost,
.btn-secondary,
.btn-forum.secondary,
.iw-cancel {
    --rot-btn-rgb: var(--rot-fac-rgb);
    --rot-btn-tier: #97a3b0;
    --rot-btn-ink: var(--rot-text-strong);
    --rot-btn-on: #0d1116;
    --rot-btn-bracket: #dfe6ed;
}

/*  Success and info are NOT a fourth and fifth tier — they are two legacy
    classes that meant "confirm" and "read more". They keep their own hue
    because the semantic palette already owns those two colours, but they use
    the same chassis and the same five states as everything else. */
.btn-success,
.btn-forum.success {
    --rot-btn-rgb: var(--rot-success-rgb);
    --rot-btn-tier: var(--rot-success);
    --rot-btn-ink: var(--rot-success-text);
    --rot-btn-on: #10241a;
    --rot-btn-bracket: #a9f0c4;
}
.btn-info {
    --rot-btn-rgb: var(--rot-info-rgb);
    --rot-btn-tier: var(--rot-info);
    --rot-btn-ink: var(--rot-info-text);
    --rot-btn-on: #0b1725;
    --rot-btn-bracket: #cfe4ff;
}

/* ===============================  SEATS  ===============================
   The face is mixed against the surface UNDER the button, so a container that
   is not a plain panel says so once, here. Wrong seat = a coloured wash over
   the whole face instead of a thin edge.
   ========================================================================= */
.rot-panel, .module, .al-card, .card, .panel, .content-box { --rot-btn-seat: var(--rot-panel-fill); }
.al-board, .rot-shell-head, .page-header, .card-header { --rot-btn-seat: var(--rot-header-fill); }
.al-filters, .al-sweep, .filter-panel { --rot-btn-seat: var(--rot-panel-fill-alt); }
.rot-modal { --rot-btn-seat: var(--rot-panel-fill-strong, #161b22); }

/*  ▶ THE OPT-OUT LIST, AND WHY EACH ONE IS NOT A BUTTON.

    `.btn` is deliberately broad — hundreds of call sites — so the boundary has
    to be written down. Everything below was found by sweeping every page for
    button-shaped elements without the chassis, and each one is here because it
    is NOT an action:

      .rot-gnav-btn    global nav chrome (the shell's own control)
      .copy-btn        icon-only micro-affordance, no label to hang a shape on
      .lo-set-btn      saved-loadout chips — a set SELECTOR, not an action
      .al-chip-btn     the attack list's sort toggles — state, not action
      .dropdown-menu .action-btn   rows in an open menu. A menu item is a
                       LIST ROW; chamfering fourteen of them inside one small
                       popup turns a menu into a pile of buttons.
      .lo-menu-item    the same thing one view over — the slot-first
                       inventory's row menu. It was MISSED when the line above
                       was written, and the result was the bug in miniature:
                       Equip/Sell/Add to Market wore the full uppercase brass
                       face while Send, which navigates and so stays an <a>,
                       sat under them as plain 12.5px text. Both are menu rows.
      .pagination .btn / .tabs .btn / a.btn-plain — navigation wearing a class

    A state control must not look like a button, for the same reason solid
    brass means "you are here": if everything is a button, nothing is.
    Add here rather than inventing a new class, and say why. */
a.btn-plain,
.rot-gnav-btn,
.copy-btn,
.lo-set-btn,
.al-chip-btn,
.dropdown-menu .action-btn,
.lo-menu-item,
.pagination .btn,
.tabs .btn {
    background: none;
    filter: none;
}
/*  ::before only — that is the chassis face. ::after is no longer the chassis's
    to cancel (the fold is gone), and cancelling it here would silently eat any
    glyph the call site draws. */
a.btn-plain::before,
.rot-gnav-btn::before,
.copy-btn::before,
.lo-set-btn::before,
.al-chip-btn::before,
.dropdown-menu .action-btn::before,
.lo-menu-item::before,
.pagination .btn::before,
.tabs .btn::before { content: none; }
