body[class*='theme-'] .mod-inventory,
body[class*='theme-'] .mod-mailbox,
body[class*='theme-'] .mod-missions,
body[class*='theme-'] .missions-container,
body[class*='theme-'] .forum-container,
body[class*='theme-'] .forum-card,
body[class*='theme-'] .forum-users-browsing,
body[class*='theme-'] .table.forum-category-list,
body[class*='theme-'] .table.forum-topics,
body[class*='theme-'] .inventory-controls,
body[class*='theme-'] .equipment-overview,
body[class*='theme-'] .detail-group,
body[class*='theme-'] .filter-dropdown,
body[class*='theme-'] .compose-form,
body[class*='theme-'] .mail-list,
body[class*='theme-'] .mail-list-header,
body[class*='theme-'] .module-container,
body[class*='theme-'] .combat-arena,
body[class*='theme-'] .mod-item-market .main-type,
body[class*='theme-'] .mod-job .jobs,
body[class*='theme-'] .mod-travel .cities,
body[class*='theme-'] .mod-preferences .set-status,
body[class*='theme-'] .mod-preferences .titles,
body[class*='theme-'] .mod-missions .desc,
body[class*='theme-'] .entry-room {
    background: var(--rot-panel-fill-soft) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .mailbox-header,
body[class*='theme-'] .mailbox-nav,
body[class*='theme-'] .mail-list-header,
body[class*='theme-'] .missions-container .missions-header,
body[class*='theme-'] .mod-missions .head,
body[class*='theme-'] h3.mission-category,
body[class*='theme-'] .forum-header,
body[class*='theme-'] .post-header,
body[class*='theme-'] .table.forum-category-list th,
body[class*='theme-'] .table.forum-topics th,
body[class*='theme-'] .module-header,
body[class*='theme-'] #menuwrap h3 {
    background: var(--rot-header-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .forum-navigation a,
body[class*='theme-'] .forum-actions a,
body[class*='theme-'] .filter-btn,
body[class*='theme-'] .apply-btn,
body[class*='theme-'] .page-btn,
body[class*='theme-'] .mail-action,
body[class*='theme-'] .filter-toggle,
body[class*='theme-'] .links-group a,
body[class*='theme-'] .operations-time a,
body[class*='theme-'] .block-turn a,
body[class*='theme-'] .block-turn-def a,
body[class*='theme-'] .mod-open .block a {
    background: var(--rot-button-fill) !important;
    border: 1px solid var(--rot-border) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .forum-navigation a:hover,
body[class*='theme-'] .forum-actions a:hover,
body[class*='theme-'] .filter-btn:hover,
body[class*='theme-'] .apply-btn:hover,
body[class*='theme-'] .page-btn:hover,
body[class*='theme-'] .mail-action:hover,
body[class*='theme-'] .filter-toggle:hover,
body[class*='theme-'] .links-group a:hover,
body[class*='theme-'] .operations-time a:hover,
body[class*='theme-'] .block-turn a:hover,
body[class*='theme-'] .block-turn-def a:hover,
body[class*='theme-'] .mod-open .block a:hover,
body[class*='theme-'] #menuwrap h3.over,
body[class*='theme-'] #menuwrap h3.active,
body[class*='theme-'] #menuwrap ul a:hover,
body[class*='theme-'] #menuwrap ul a:active,
body[class*='theme-'] .block-room a:hover {
    background: var(--rot-button-fill-hover) !important;
    border-color: var(--rot-border-strong) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .mailbox-filter select,
body[class*='theme-'] .action-select,
body[class*='theme-'] #inventory-search,
body[class*='theme-'] .compose-form input,
body[class*='theme-'] .compose-form textarea,
body[class*='theme-'] .compose-form select {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(255, 255, 255, 0.08) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .mailbox-filter select:focus,
body[class*='theme-'] .action-select:focus,
body[class*='theme-'] #inventory-search:focus,
body[class*='theme-'] .compose-form input:focus,
body[class*='theme-'] .compose-form textarea:focus,
body[class*='theme-'] .compose-form select:focus {
    border-color: var(--rot-border-strong) !important;
    box-shadow: 0 0 0 2px rgba(var(--rot-accent-rgb), 0.12) !important;
}

body[class*='theme-'] .mailbox-header h2,
body[class*='theme-'] .mail-sender,
body[class*='theme-'] .missions-container .missions-header div,
body[class*='theme-'] .mod-missions .head h2,
body[class*='theme-'] .missions-container .mission-cost,
body[class*='theme-'] .missions-container .mission-required-items h4,
body[class*='theme-'] .forum-title strong a,
body[class*='theme-'] .last-post-topic a,
body[class*='theme-'] .forum-navigation strong,
body[class*='theme-'] .forum-users-browsing strong,
body[class*='theme-'] .table.forum-category-list td strong a,
body[class*='theme-'] .table.forum-topics td strong a,
body[class*='theme-'] .mod-news dt,
body[class*='theme-'] .mod-log dt,
body[class*='theme-'] .mod-item-market .item,
body[class*='theme-'] .mod-item-market .price,
body[class*='theme-'] .mod-item-market .action,
body[class*='theme-'] .detail-group h4 i,
body[class*='theme-'] .detail-action:hover,
body[class*='theme-'] #menuwrap h3,
body[class*='theme-'] .block-turn a,
body[class*='theme-'] .block-turn-def a,
body[class*='theme-'] .mod-open .block a {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .mailbox-info,
body[class*='theme-'] .mail-time,
body[class*='theme-'] .mail-preview,
body[class*='theme-'] .pagination-info,
body[class*='theme-'] .detail-label,
body[class*='theme-'] .detail-subvalue,
body[class*='theme-'] .forum-description,
body[class*='theme-'] .forum-topics td small,
body[class*='theme-'] .forum-category-list td small,
body[class*='theme-'] .forum-topics td small a,
body[class*='theme-'] .forum-category-list td small a,
body[class*='theme-'] .last-post-meta,
body[class*='theme-'] .last-post-meta small,
body[class*='theme-'] .missions-container .mission-required-items li,
body[class*='theme-'] .missions-container .no-missions,
body[class*='theme-'] .no-messages,
body[class*='theme-'] .detail-icon i,
body[class*='theme-'] .mod-open .desc,
body[class*='theme-'] .block-room .desc-room,
body[class*='theme-'] .show-online a,
body[class*='theme-'] span.show-online {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-'] .inventory-controls,
body[class*='theme-'] .equipment-overview,
body[class*='theme-'] .compose-form,
body[class*='theme-'] .mod-mailbox-content,
body[class*='theme-'] .mail-list {
    color: var(--rot-text) !important;
}

body[class*='theme-'] .detail-group h4 {
    color: var(--rot-text-strong) !important;
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.12) !important;
}

body[class*='theme-'] .detail-item,
body[class*='theme-'] .detail-item.has-item,
body[class*='theme-'] .detail-icon,
body[class*='theme-'] .filter-dropdown,
body[class*='theme-'] .header-notification {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(255, 255, 255, 0.06) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .detail-item:hover,
body[class*='theme-'] .detail-item.has-item.detail-hover,
body[class*='theme-'] .detail-item.has-item:hover,
body[class*='theme-'] .mailbox-nav .nav-item:hover,
body[class*='theme-'] .forum-category-row:hover td,
body[class*='theme-'] .forum-topic-row:hover td,
body[class*='theme-'] .forum-row:hover,
body[class*='theme-'] .clickable-row:hover,
body[class*='theme-'] .mail-item:hover,
body[class*='theme-'] .missions-container a.mission-link:hover,
body[class*='theme-'] .table.forum-category-list tr:hover td,
body[class*='theme-'] .table.forum-topics tr:hover td {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
}

body[class*='theme-'] .header-notification.processing {
    border-left-color: var(--rot-accent) !important;
}

body[class*='theme-'] .header-notification.processing .notification-content i,
body[class*='theme-'] .header-notification.processing .notification-content .fas,
body[class*='theme-'] .detail-value,
body[class*='theme-'] .mail-subject,
body[class*='theme-'] .mail-item.unread .mail-subject,
body[class*='theme-'] .missions-container .mission-name,
body[class*='theme-'] .missions-container .mission-row .desc,
body[class*='theme-'] .forum-card,
body[class*='theme-'] .forum-empty-state strong {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .notification-progress {
    background: linear-gradient(90deg, var(--rot-accent), var(--rot-accent-strong)) !important;
}

body[class*='theme-'] .filter-options input[type='checkbox']:checked,
body[class*='theme-'] .select-all input[type='checkbox']:checked,
body[class*='theme-'] .mail-item-selection input[type='checkbox']:checked {
    background: var(--rot-accent) !important;
    border-color: var(--rot-accent) !important;
}

body[class*='theme-'] .mailbox-nav .nav-item.active,
body[class*='theme-'] .new-indicator,
body[class*='theme-'] .special-badge,
body[class*='theme-'] .missions-container .mission-row .desc,
body[class*='theme-'] .forum-users-browsing,
body[class*='theme-'] .clickable-row:hover {
    border-color: rgba(var(--rot-accent-rgb), 0.2) !important;
}

body[class*='theme-'] .mailbox-nav .nav-item.active,
body[class*='theme-'] .new-indicator,
body[class*='theme-'] .special-badge,
body[class*='theme-'] .missions-container .mission-row .desc,
body[class*='theme-'] .forum-users-browsing,
body[class*='theme-'] .mail-item.unread,
body[class*='theme-'] .missions-container a.mission-link::before,
body[class*='theme-'] h3.mission-category::before,
body[class*='theme-'] .clickable-row:hover,
body[class*='theme-'] .post-card.original-post {
    border-left-color: var(--rot-accent) !important;
}

body[class*='theme-'] .mailbox-nav .nav-item.active,
body[class*='theme-'] .new-indicator,
body[class*='theme-'] .special-badge {
    background: rgba(var(--rot-accent-rgb), 0.12) !important;
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .mail-item,
body[class*='theme-'] .forum-row,
body[class*='theme-'] .table.forum-category-list td,
body[class*='theme-'] .table.forum-topics td,
body[class*='theme-'] .post-card.reply-even,
body[class*='theme-'] .post-card.reply-odd,
body[class*='theme-'] .missions-container a.mission-link,
body[class*='theme-'] .missions-container a.mission-link:nth-child(odd),
body[class*='theme-'] .missions-container a.mission-link:nth-child(even) {
    background: var(--rot-surface) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .forum-category-row:nth-child(even) td,
body[class*='theme-'] .forum-topic-row:nth-child(even) td,
body[class*='theme-'] .forum-row:nth-child(even),
body[class*='theme-'] .post-card.reply-odd,
body[class*='theme-'] .mail-item.unread {
    background: var(--rot-surface-raised) !important;
}

body[class*='theme-'] .forum-title strong a:hover,
body[class*='theme-'] .last-post-topic a:hover,
body[class*='theme-'] .last-post-meta a:hover,
body[class*='theme-'] .forum-topics td strong a:hover,
body[class*='theme-'] .forum-category-list td strong a:hover,
body[class*='theme-'] .forum-topics td small a:hover,
body[class*='theme-'] .forum-category-list td small a:hover,
body[class*='theme-'] .mail-action.reply:hover,
body[class*='theme-'] .missions-container a.mission-link:hover .mission-name,
body[class*='theme-'] .missions-container a.mission-link:hover .mission-action,
body[class*='theme-'] h3.mission-category:hover,
body[class*='theme-'] .clickable-row:hover .forum-title a {
    color: var(--rot-link) !important;
}

body[class*='theme-'] .missions-container .mission-action {
    color: var(--rot-link) !important;
}

body[class*='theme-'] .missions-container .mission-required-items li::before,
body[class*='theme-'] .forum-navigation span {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-'] .mail-full-text {
    border-top-color: rgba(var(--rot-accent-rgb), 0.12) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] #wrap-attack .module-container {
    background: var(--rot-panel-fill) !important;
}

body[class*='theme-'] #wrap-attack .combat-arena::before {
    background: linear-gradient(to right, transparent, rgba(var(--rot-accent-rgb), 0.7), transparent) !important;
}

body[class*='theme-'] #wrap-attack .combatant {
    background: rgba(255, 255, 255, 0.04) !important;
}

body[class*='theme-'] #wrap-attack .combatant-avatar img {
    border-color: rgba(var(--rot-accent-rgb), 0.18) !important;
}

/*  ▶ THE BUTTON OVERRIDES IN THIS FILE ARE GONE — buttons.css owns buttons.

    These blocks pinned a fill, a border, a shadow and `color:
    var(--rot-accent-contrast)` — near-BLACK brass ink — onto real buttons with
    !important. That was correct while --rot-button-primary-fill was a solid
    brass gradient. It stopped being correct twice over:

      1. the token became a 16% TINT, so near-black ink landed on a near-black
         face and the label vanished;
      2. the chassis arrived in buttons.css, and !important here beats it no
         matter that buttons.css is linked last — so these rules also stripped
         the chamfer, the fold and the whole state machine off every button
         they touched.

    Measured while removing them: .btn-primary, .btn-search, .apply-btn and
    .training-content .submit-button were all rendering un-chamfered at
    rgb(23,18,5) on rgba(212,175,55,.16).

    The rule this file has to keep: A BUTTON'S INK AND ITS FILL LIVE IN ONE
    RULE. Split them across two files and one of them will move without the
    other. Nothing that is a button belongs in theme-overrides.css.  */

body[class*='theme-'] .btn-info,
body[class*='theme-'] .back-button,
body[class*='theme-'] .badge-info {
    background: var(--rot-info-fill) !important;
    border: 1px solid rgba(var(--rot-info-rgb), 0.24) !important;
    color: var(--rot-info-text) !important;
}

body[class*='theme-'] .btn-success {
    background: var(--rot-success-fill) !important;
    border: 1px solid rgba(var(--rot-success-rgb), 0.26) !important;
    color: var(--rot-success-text) !important;
}

body[class*='theme-'] .btn-danger,
body[class*='theme-'] .delete-all-btn {
    background: var(--rot-danger-fill) !important;
    border: 1px solid rgba(var(--rot-danger-rgb), 0.26) !important;
    color: var(--rot-danger-text) !important;
}

body[class*='theme-'] .btn-info:hover,
body[class*='theme-'] .back-button:hover,
body[class*='theme-'] .btn-success:hover,
body[class*='theme-'] .btn-danger:hover,
body[class*='theme-'] .delete-all-btn:hover {
    border-color: rgba(var(--rot-accent-rgb), 0.3) !important;
}

body[class*='theme-'] .badge-warning,
body[class*='theme-'] .cost-indicator,
body[class*='theme-'] .events-count,
body[class*='theme-'] .special-badge {
    background: var(--rot-reward-fill) !important;
    border: 1px solid rgba(var(--rot-reward-rgb), 0.22) !important;
    color: var(--rot-reward-text) !important;
}

body[class*='theme-'] .advanced-search-container,
body[class*='theme-'] .search-results,
body[class*='theme-'] .mod-events,
body[class*='theme-'] .tutorial-box,
body[class*='theme-'] .events-controls,
body[class*='theme-'] .no-events,
body[class*='theme-'] .event-card,
body[class*='theme-'] .player-card {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .tutorial-box {
    background: linear-gradient(180deg, rgba(var(--rot-accent-rgb), 0.12), rgba(10, 12, 18, 0.94)) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.22) !important;
}

body[class*='theme-'] .search-note,
body[class*='theme-'] .events-count,
body[class*='theme-'] .no-events {
    background: var(--rot-panel-fill-soft) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    color: var(--rot-text-muted) !important;
}

body[class*='theme-'] .advanced-search-container .form-control,
body[class*='theme-'] #event-search {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .advanced-search-container .form-control:focus,
body[class*='theme-'] #event-search:focus {
    border-color: var(--rot-border-strong) !important;
    box-shadow: 0 0 0 2px rgba(var(--rot-accent-rgb), 0.12) !important;
}

body[class*='theme-'] .tutorial-icon,
body[class*='theme-'] .events-count i,
body[class*='theme-'] .search-wrapper i,
body[class*='theme-'] .event-time i,
body[class*='theme-'] .results-header .count {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .event-message,
body[class*='theme-'] .no-events h3,
body[class*='theme-'] .search-title,
body[class*='theme-'] .results-header h3,
body[class*='theme-'] .player-info h4 a {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .search-note a,
body[class*='theme-'] .player-info h4 a,
body[class*='theme-'] .event-message a {
    color: var(--rot-link) !important;
}

body[class*='theme-'] .search-note a:hover,
body[class*='theme-'] .player-info h4 a:hover,
body[class*='theme-'] .event-message a:hover {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .player-card:hover,
body[class*='theme-'] .event-card:hover {
    border-color: var(--rot-border-strong) !important;
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
}

body[class*='theme-'] .event-unread {
    border-left-color: var(--rot-accent) !important;
}

body[class*='theme-'] .event-unread::before {
    background: var(--rot-accent) !important;
    animation: rot-theme-pulse 2s infinite !important;
}

body[class*='theme-'] .event-icon {
    background: rgba(255, 255, 255, 0.05) !important;
    color: var(--rot-text-muted) !important;
}

body[class*='theme-'] .event-achievement,
body[class*='theme-'] .event-reward,
body[class*='theme-'] .event-level {
    border-left-color: var(--rot-reward) !important;
}

body[class*='theme-'] .event-achievement .event-icon,
body[class*='theme-'] .event-reward .event-icon,
body[class*='theme-'] .event-level .event-icon {
    background: rgba(var(--rot-reward-rgb), 0.14) !important;
    color: var(--rot-reward) !important;
}

/*  .event-computer belongs in THIS list, not only in events.css. Everything
    above is `!important` on a `body[class*='theme-']` prefix, so a plain
    `.event-computer .event-icon` rule in events.css never wins and the new
    channel silently came out the same muted grey as an unclassified event. */
body[class*='theme-'] .event-success .event-icon,
body[class*='theme-'] .event-crafting .event-icon,
body[class*='theme-'] .event-computer .event-icon,
body[class*='theme-'] .event-group .event-icon {
    background: rgba(var(--rot-success-rgb), 0.14) !important;
    color: var(--rot-success) !important;
}

body[class*='theme-'] .event-danger,
body[class*='theme-'] .event-danger .event-icon,
body[class*='theme-'] .event-delete:hover {
    color: var(--rot-danger) !important;
}

body[class*='theme-'] .event-danger {
    border-left-color: var(--rot-danger) !important;
}

body[class*='theme-'] .event-danger .event-icon {
    background: rgba(var(--rot-danger-rgb), 0.16) !important;
}

@keyframes rot-theme-pulse {
    0% {
        transform: scale(0.95);
        box-shadow: var(--rot-shadow);
    }

    70% {
        transform: scale(1);
        box-shadow: 0 0 0 6px rgba(var(--rot-accent-rgb), 0);
    }

    100% {
        transform: scale(0.95);
        box-shadow: var(--rot-shadow);
    }
}

/* The Character Profile cards. .stat-card (Performance/Combat/Skills/Resources)
   was left OUT of the original conform pass, so it fell through to profile.css's
   warm-brown fills while the event/buff cards beside it went cool slate. Same
   palette for all of them now. .fr-band is deliberately NOT in this list: it is
   the one lit surface on the page and a flat fill erases the light that makes it
   read as the header. It takes the themed treatment below instead. */
body[class*='theme-'] .mod-home .event-card,
body[class*='theme-'] .mod-home .buffdebuff-card,
body[class*='theme-'] .mod-home .stat-card {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .mod-home .newmember,
body[class*='theme-'] .home-page-content .newmember {
    background-color: var(--rot-panel-fill-soft) !important;
    border-left-color: var(--rot-accent) !important;
    color: var(--rot-text) !important;
    box-shadow: var(--rot-shadow) !important;
}

body[class*='theme-'] .mod-home .newmember .help-link a {
    color: var(--rot-link) !important;
}

body[class*='theme-'] .mod-home .newmember .help-link a:hover {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .mod-home .event-card .event-header {
    background: var(--rot-header-fill) !important;
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.14) !important;
}

/*  ▶▶ 2026-08-30 — THE CARD HEADERS ARE STRUCK PLATES, AND THIS IS THE LAYER
    THAT PAINTS THEM. The theme class is always on, so the flat-fill group above
    is not a "variant" -- anything left in it gets a flat colour and whatever
    profile.css said is erased. The plate has to be RESTATED here, in full, the
    same way .fr-band's radial light did. Grain: /v2/img/ui/plate-strip.png, a
    patch cut from the top banner art. Keep in step with the .stat-card
    .card-header block at the end of profile.css. */
body[class*='theme-'] .mod-home .buffdebuff-card .card-header,
body[class*='theme-'] .mod-home .stat-card .card-header {
    background:
        linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(0, 0, 0, 0.35)),
        url(/v2/img/ui/plate-strip.png) center / auto 100% repeat-x,
        var(--rot-header-fill) !important;
    border-left: 0 !important;
    border-bottom-color: rgba(0, 0, 0, 0.70) !important;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.07),
        0 1px 0 rgba(var(--rot-accent-rgb), 0.30) !important;
}

/*  The seasonal event card keeps its brass left bar -- it is a one-off notice
    that is SUPPOSED to flag itself, not one of the six dashboard cards. */
body[class*='theme-'] .mod-home .event-card.valentine .event-header {
    border-left: 3px solid var(--rot-accent) !important;
}

body[class*='theme-'] .mod-home .event-card .event-header i,
body[class*='theme-'] .mod-home .buffdebuff-card .card-header i,
body[class*='theme-'] .mod-home .stat-card .card-header i,
body[class*='theme-'] .mod-home .event-rank .value,
body[class*='theme-'] .mod-home .event-points .value {
    color: var(--rot-accent) !important;
}

/*  ...but the card's OWN glyph is steel, so the plate has no brass on it at all
    and the warmest thing in the card is its numbers. `> i` only: the group above
    also catches the eye toggle and the drag grip, which keep the accent. Equal
    specificity to that rule (a child combinator adds none), so this MUST stay
    below it -- moving it up silently re-golds the glyph. */
body[class*='theme-'] .mod-home .buffdebuff-card .card-header > i,
body[class*='theme-'] .mod-home .stat-card .card-header > i {
    color: #aab2bb !important;
}

body[class*='theme-'] .mod-home .event-card .event-header h3,
body[class*='theme-'] .mod-home .buffdebuff-card .card-header h3,
body[class*='theme-'] .mod-home .stat-card .card-header h3,
body[class*='theme-'] .mod-home .fr-name,
body[class*='theme-'] .mod-home .fr-figure-value,
body[class*='theme-'] .mod-home .fr-tile-value,
body[class*='theme-'] .mod-home .home-stat-value,
body[class*='theme-'] .mod-home .buff-details,
body[class*='theme-'] .mod-home .event-content {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .mod-home .event-rank,
body[class*='theme-'] .mod-home .event-points {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
}

body[class*='theme-'] .mod-home .event-rank .label,
body[class*='theme-'] .mod-home .event-points .label,
body[class*='theme-'] .mod-home .buff-time {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#attacklist .filter-panel,
body[class*='theme-']#attacklist .data-table,
body[class*='theme-']#attacklist .info-panel {
    background: var(--rot-panel-fill-soft) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#attacklist .filter-item label,
body[class*='theme-']#attacklist .checkbox-label,
body[class*='theme-']#attacklist .user-link,
body[class*='theme-']#attacklist .level-badge {
    color: var(--rot-text) !important;
}

body[class*='theme-']#attacklist .input-connector,
body[class*='theme-']#attacklist .text-muted,
body[class*='theme-']#attacklist .info-text {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#attacklist .form-input {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#attacklist .form-input:focus {
    border-color: var(--rot-border-strong) !important;
    box-shadow: 0 0 0 2px rgba(var(--rot-accent-rgb), 0.12) !important;
}

body[class*='theme-']#attacklist .data-table th {
    background: var(--rot-header-fill) !important;
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#attacklist .data-table td {
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.1) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#attacklist .data-table tr:nth-child(even) {
    background: rgba(var(--rot-accent-rgb), 0.03) !important;
}

body[class*='theme-']#attacklist .data-table tr:hover {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
}

body[class*='theme-']#attacklist .online-user {
    background: rgba(var(--rot-success-rgb), 0.08) !important;
}

body[class*='theme-']#attacklist .online-user:hover {
    background: rgba(var(--rot-success-rgb), 0.12) !important;
}

body[class*='theme-']#attacklist .user-link:hover {
    color: var(--rot-text-strong) !important;
}

/* Two different elements — do not re-merge. The username LINK wants green TEXT;
   the DOT wants green FILL. Grouped together they each got BOTH, so the link
   received `background-color: var(--rot-success)` and rendered as a solid green
   block with its (also-green) username invisible inside it. Split by intent. */
body[class*='theme-']#attacklist .user-link.online {
    color: var(--rot-success) !important;
}

body[class*='theme-']#attacklist .online-indicator {
    background-color: var(--rot-success) !important;
}

body[class*='theme-']#attacklist .level-badge {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.12) !important;
}

body[class*='theme-']#attacklist .faction-federalist {
    color: var(--rot-info) !important;
}

body[class*='theme-']#attacklist .faction-revolutionary {
    color: var(--rot-danger) !important;
}

body[class*='theme-']#attacklist .group-link {
    color: var(--rot-link) !important;
}

body[class*='theme-']#attacklist .group-link:hover {
    color: var(--rot-accent) !important;
}

body[class*='theme-']#attacklist .attack-btn {
    background: var(--rot-danger-fill) !important;
    border: 1px solid rgba(var(--rot-danger-rgb), 0.26) !important;
    color: var(--rot-danger-text) !important;
}

body[class*='theme-']#attacklist .attack-btn:hover {
    border-color: rgba(var(--rot-danger-rgb), 0.36) !important;
}

body[class*='theme-']#attacklist .info-panel {
    background: linear-gradient(180deg, rgba(var(--rot-info-rgb), 0.12), rgba(0, 0, 0, 0)) !important;
    border-color: rgba(var(--rot-info-rgb), 0.22) !important;
}

body[class*='theme-']#attacklist .info-icon {
    color: var(--rot-info) !important;
}

body[class*='theme-']#citypage #wrap,
body[class*='theme-']#citypage .city-stats,
body[class*='theme-']#citypage .district-card,
body[class*='theme-']#citypage .dropdown-menu,
body[class*='theme-']#citypage .alert-info {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#citypage .city-stat-value,
body[class*='theme-']#citypage .district-header h3,
body[class*='theme-']#citypage .alert-info h4 {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#citypage .city-stat-label,
body[class*='theme-']#citypage .alert-info,
body[class*='theme-']#citypage .location-link.disabled {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#citypage .city-stat:not(:last-child):after,
body[class*='theme-']#citypage .district-header:before {
    background: var(--rot-line-glow) !important;
}

body[class*='theme-']#citypage .district-header {
    background: var(--rot-header-fill) !important;
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.14) !important;
}

body[class*='theme-']#citypage .district-content {
    background: var(--rot-panel-fill-soft) !important;
}

body[class*='theme-']#citypage .location-link,
body[class*='theme-']#citypage .dropdown-toggle {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#citypage .location-link i,
body[class*='theme-']#citypage .dropdown-toggle i.fa-caret-down,
body[class*='theme-']#citypage .alert-info i {
    color: var(--rot-accent) !important;
}

body[class*='theme-']#citypage .location-link:hover,
body[class*='theme-']#citypage .dropdown-menu .location-link:hover {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
    border-color: var(--rot-border-strong) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#citypage .location-link.highlight {
    background: rgba(var(--rot-accent-rgb), 0.12) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.26) !important;
    color: var(--rot-accent) !important;
}

body[class*='theme-']#citypage .badge {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#citypage .badge.level-req {
    background: var(--rot-danger-fill) !important;
    border-color: rgba(var(--rot-danger-rgb), 0.22) !important;
    color: var(--rot-danger-text) !important;
}

body[class*='theme-']#citypage .location-link:focus {
    outline-color: rgba(var(--rot-accent-rgb), 0.6) !important;
}

body[class*='theme-']#citypage .location-link.loading:after {
    border-color: rgba(var(--rot-accent-rgb), 0.3) !important;
    border-top-color: var(--rot-accent) !important;
}

body[class*='theme-'] .module-content.training-content,
body[class*='theme-'] .training-content .train-stat-indicator,
body[class*='theme-'] .training-content .training-options-grid,
body[class*='theme-'] .training-content .training-card,
body[class*='theme-'] .training-content .workout-form-container,
body[class*='theme-'] .training-content .train-stat-box,
body[class*='theme-'] .training-content .option-card,
body[class*='theme-'] .training-content .no-energy-message {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .training-content .training-card:hover,
body[class*='theme-'] .training-content .option-card:hover {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
    border-color: var(--rot-border-strong) !important;
}

/*  A named camp: the plain "Training Camp" rides beside the local name so the
    heading still says what the place is. */
.training-content .facility-kicker {
    display: inline-block; margin-left: 10px; vertical-align: middle;
    font: 700 9.5px 'IBM Plex Mono', monospace; letter-spacing: .18em;
    text-transform: uppercase; opacity: .7;
}
.training-content .facility-tagline {
    margin: 4px 0 0; font-size: 12.5px; font-style: italic; opacity: .8;
}

body[class*='theme-'] .training-content .section-title,
body[class*='theme-'] .training-content .facility-title,
body[class*='theme-'] .training-content .card-content h4,
body[class*='theme-'] .training-content .option-name {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .training-content .section-title i,
body[class*='theme-'] .training-content .facility-title i,
body[class*='theme-'] .training-content .option-icon {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .training-content .options-description,
body[class*='theme-'] .training-content .card-content p,
body[class*='theme-'] .training-content .train-stat-label,
body[class*='theme-'] .training-content .option-desc,
body[class*='theme-'] .training-content .option-stat,
body[class*='theme-'] .training-content .help-text,
body[class*='theme-'] .training-content .no-energy-message {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-'] .training-content .train-stat-value {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-'] .training-content .train-stat-bar,
body[class*='theme-'] .training-content .card-icon,
body[class*='theme-'] .training-content .train-stat-tag {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .training-content .train-stat-fill.endurance,
body[class*='theme-'] .training-content .training-card.workout::before {
    background: linear-gradient(90deg, var(--rot-success), rgba(var(--rot-success-rgb), 0.68)) !important;
}

body[class*='theme-'] .training-content .train-stat-fill.accuracy,
body[class*='theme-'] .training-content .training-card.range::before {
    background: linear-gradient(90deg, var(--rot-info), rgba(var(--rot-info-rgb), 0.68)) !important;
}

body[class*='theme-'] .training-content .train-stat-fill.focus,
body[class*='theme-'] .training-content .training-card.spy::before {
    background: linear-gradient(90deg, var(--rot-accent), rgba(var(--rot-accent-strong-rgb), 0.72)) !important;
}

body[class*='theme-'] .training-content .workout .card-icon,
body[class*='theme-'] .training-content .option-cost.free {
    color: var(--rot-success) !important;
    background: rgba(var(--rot-success-rgb), 0.14) !important;
    border-color: rgba(var(--rot-success-rgb), 0.24) !important;
}

body[class*='theme-'] .training-content .range .card-icon {
    color: var(--rot-info) !important;
    background: rgba(var(--rot-info-rgb), 0.14) !important;
    border-color: rgba(var(--rot-info-rgb), 0.24) !important;
}

body[class*='theme-'] .training-content .spy .card-icon {
    color: var(--rot-accent) !important;
    background: rgba(var(--rot-accent-rgb), 0.14) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.24) !important;
}

body[class*='theme-'] .training-content .option-cost {
    background: var(--rot-reward-fill) !important;
    border-color: rgba(var(--rot-reward-rgb), 0.22) !important;
    color: var(--rot-reward-text) !important;
}

body[class*='theme-'] .training-content .form-group label {
    color: var(--rot-text) !important;
}

body[class*='theme-'] .training-content select,
body[class*='theme-'] .training-content input[type='number'],
body[class*='theme-'] .training-content input[type='text'],
body[class*='theme-'] .form-group select {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .training-content select:focus,
body[class*='theme-'] .training-content input[type='number']:focus,
body[class*='theme-'] .training-content input[type='text']:focus,
body[class*='theme-'] .form-group select:focus {
    border-color: var(--rot-border-strong) !important;
    box-shadow: 0 0 0 2px rgba(var(--rot-accent-rgb), 0.12) !important;
    outline: none !important;
}

body[class*='theme-'] .training-content .option-card.selected {
    border-color: var(--rot-border-strong) !important;
    background: rgba(var(--rot-accent-rgb), 0.1) !important;
}

body[class*='theme-'] .training-content .no-energy-message i {
    color: var(--rot-danger) !important;
}

body[class*='theme-']#gamerules .rules-container,
body[class*='theme-']#gamerules .achievement-progress,
body[class*='theme-']#gamerules .rule-item,
body[class*='theme-']#gamerules .footer-note {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#gamerules .progress-icon {
    background: rgba(var(--rot-info-rgb), 0.16) !important;
}

body[class*='theme-']#gamerules .progress-icon i,
body[class*='theme-']#gamerules .progress-details h3,
body[class*='theme-']#gamerules .progress-text .current {
    color: var(--rot-info) !important;
}

body[class*='theme-']#gamerules .progress-details p,
body[class*='theme-']#gamerules .progress-text,
body[class*='theme-']#gamerules .progress-text .total {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#gamerules .progress-bar {
    background: rgba(var(--rot-info-rgb), 0.18) !important;
}

body[class*='theme-']#gamerules .progress-bar .progress {
    background: linear-gradient(90deg, var(--rot-info), var(--rot-accent)) !important;
}

body[class*='theme-']#gamerules .rules-intro p,
body[class*='theme-']#gamerules .rule-content p,
body[class*='theme-']#gamerules .footer-note p {
    color: var(--rot-text) !important;
}

body[class*='theme-']#gamerules .rule-number {
    background: var(--rot-header-fill) !important;
    color: var(--rot-accent) !important;
}

body[class*='theme-']#gamerules .rule-item:hover {
    background: rgba(var(--rot-accent-rgb), 0.06) !important;
    border-color: var(--rot-border-strong) !important;
}

body[class*='theme-']#gamerules .rule-content a {
    color: var(--rot-link) !important;
}

body[class*='theme-']#gamerules .rule-content a:hover {
    color: var(--rot-accent) !important;
}

body[class*='theme-']#gamerules .rules-footer {
    border-top-color: rgba(var(--rot-accent-rgb), 0.16) !important;
}

body[class*='theme-']#gamerules .footer-note {
    background: linear-gradient(180deg, rgba(var(--rot-danger-rgb), 0.12), rgba(0, 0, 0, 0)) !important;
    border-color: rgba(var(--rot-danger-rgb), 0.24) !important;
}

body[class*='theme-']#gamerules .footer-note i {
    color: var(--rot-danger) !important;
}

body[class*='theme-']#computer .computer-interface-overview,
body[class*='theme-']#computer .computer-interface-frame {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#computer .computer-interface-frame-top {
    background: var(--rot-header-fill) !important;
    border-bottom-color: rgba(var(--rot-accent-rgb), 0.14) !important;
}

body[class*='theme-']#computer .computer-interface-shell::before {
    background: linear-gradient(135deg, rgba(var(--rot-accent-rgb), 0.08), transparent 40%), radial-gradient(circle at bottom left, rgba(var(--rot-accent-strong-rgb), 0.12), transparent 34%) !important;
}

body[class*='theme-']#computer .computer-interface-frame-pill {
    background: rgba(var(--rot-accent-rgb), 0.12) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.24) !important;
    color: var(--rot-accent) !important;
}

body[class*='theme-']#computer .computer-interface-overview-copy h2,
body[class*='theme-']#computer .computer-status-card strong,
body[class*='theme-']#computer .computer-interface-frame-copy strong {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#computer .computer-interface-overview-copy p,
body[class*='theme-']#computer .computer-status-meta,
body[class*='theme-']#computer .computer-interface-footnote {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#computer .computer-interface-frame-copy span {
    color: #7fd18e !important;
}

body[class*='theme-']#computer .computer-status-card {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.14) !important;
}

body[class*='theme-']#computer .computer-status-label {
    color: var(--rot-accent-strong) !important;
}

body[class*='theme-']#computer .computer-interface-screen-wrap {
    background: rgba(4, 9, 6, 0.98) !important;
}

/*  The terminal draws its own bezel and drop shadow inside the iframe now, so
    this must NOT add a second frame. Left as an explicit reset rather than
    deleted: theme-overrides wins with !important, so a stale rule here would
    silently re-draw the old double border no matter what hack.css says. */
body[class*='theme-']#computer .computer-interface-viewport {
    border: 0 !important;
    box-shadow: none !important;
}

body[class*='theme-']#inventory .item-card,
body[class*='theme-']#inventory .empty-storage {
    background: var(--rot-panel-fill-soft) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#inventory .item-card:hover {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
    border-color: var(--rot-border-strong) !important;
}

body[class*='theme-']#inventory .item-header,
body[class*='theme-']#inventory .item-actions,
body[class*='theme-']#inventory .dropdown-menu {
    background: var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.14) !important;
}

body[class*='theme-']#inventory .equipped-badge {
    background: rgba(var(--rot-success-rgb), 0.16) !important;
    border: 1px solid rgba(var(--rot-success-rgb), 0.26) !important;
    color: var(--rot-success) !important;
}

body[class*='theme-']#inventory .item-level-badge,
body[class*='theme-']#inventory .item-quantity,
body[class*='theme-']#inventory .damage-indicator,
/*  `.action-btn` came OUT of this list — it is a button. Left in, its
    !important background and colour beat the chassis and the inventory's Use
    button rendered as a flat grey slab with unreadable ink. The dropdown
    toggle, the damage indicator and the filter select stay: none is a button. */
body[class*='theme-']#inventory .dropdown-toggle,
body[class*='theme-']#inventory .storage-filter select {
    background: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#inventory .damage-bar {
    background: rgba(255, 255, 255, 0.08) !important;
}

body[class*='theme-']#inventory .damage-fill,
body[class*='theme-']#inventory .repair-btn {
    background: var(--rot-danger-fill) !important;
    color: var(--rot-danger-text) !important;
    border-color: rgba(var(--rot-danger-rgb), 0.26) !important;
}

body[class*='theme-']#inventory .item-name {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#inventory .item-type,
body[class*='theme-']#inventory .item-value,
body[class*='theme-']#inventory .empty-storage-message,
body[class*='theme-']#inventory .storage-filter label {
    color: var(--rot-text-muted) !important;
}

body[class*='theme-']#inventory .action-warning {
    color: var(--rot-reward) !important;
}

body[class*='theme-']#inventory .dropdown-toggle:hover {
    background: rgba(var(--rot-accent-rgb), 0.08) !important;
    border-color: var(--rot-border-strong) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#inventory .storage-badge {
    background: rgba(var(--rot-success-rgb), 0.92) !important;
    color: var(--rot-success-text) !important;
}

body[class*='theme-']#inventory .storage-badge.personal {
    background: rgba(var(--rot-info-rgb), 0.92) !important;
    color: var(--rot-info-text) !important;
}

body[class*='theme-']#inventory .storage-badge.clan {
    background: linear-gradient(135deg, rgba(var(--rot-accent-rgb), 0.92), rgba(var(--rot-accent-strong-rgb), 0.92)) !important;
    color: var(--rot-accent-contrast) !important;
}

body[class*='theme-']#inventory .empty-storage {
    border: 2px dashed rgba(var(--rot-accent-rgb), 0.22) !important;
}

body[class*='theme-']#inventory .empty-storage-icon {
    color: var(--rot-accent) !important;
}

body[class*='theme-']#inventory .empty-storage-title {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#inventory .inventory-grid .item-card.storage-item {
    border-left-color: var(--rot-success) !important;
}

body[class*='theme-']#inventory .inventory-grid .item-card.storage-item:hover {
    border-left-color: var(--rot-success) !important;
    box-shadow: var(--rot-shadow) !important;
}

body[class*='theme-']#inventory .btn-store {
    background: var(--rot-success-fill) !important;
    color: var(--rot-success-text) !important;
}

body[class*='theme-']#inventory .btn-retrieve {
    background: var(--rot-info-fill) !important;
    color: var(--rot-info-text) !important;
}

body[class*='theme-']#inventory .filter-container .storage-filter {
    border-left-color: rgba(var(--rot-accent-rgb), 0.16) !important;
}

body[class*='theme-']#quest .mod-quest {
    background: var(--rot-panel-fill) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#quest .mod-quest .head {
    background: var(--rot-header-fill) !important;
    border-bottom: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
}

body[class*='theme-']#quest .mod-quest .head h2,
body[class*='theme-']#quest .quest-log h3,
body[class*='theme-']#quest .quest-room h3 {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#quest .mod-quest .content,
body[class*='theme-']#quest .quest-log,
body[class*='theme-']#quest .quest-room,
body[class*='theme-']#quest .mod-quest table,
body[class*='theme-']#quest .mod-quest tbody tr {
    color: var(--rot-text) !important;
}

body[class*='theme-']#quest .mod-quest a,
body[class*='theme-']#quest .mod-quest a.npc {
    color: var(--rot-link) !important;
}

body[class*='theme-']#quest .mod-quest a:hover,
body[class*='theme-']#quest .mod-quest a.npc:hover {
    color: var(--rot-accent) !important;
}

body[class*='theme-']#quest .mod-quest #quests {
    background: var(--rot-panel-fill-soft) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.16) !important;
    border-radius: var(--rot-radius-panel)!important;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03) !important;
}

body[class*='theme-']#quest .mod-quest #map a,
body[class*='theme-']#quest .mod-quest #help a,
body[class*='theme-']#quest .mod-quest #inventory a {
    background-color: var(--rot-surface-raised) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.16) !important;
    border-radius: var(--rot-radius-panel)!important;
    box-shadow: var(--rot-shadow) !important;
}

body[class*='theme-']#quest .mod-quest #money,
body[class*='theme-']#quest .mod-quest #stimpacks {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#quest .mod-quest #money {
    color: var(--rot-reward-text) !important;
}

body[class*='theme-']#quest #health .h-data li {
    background: rgba(6, 12, 20, 0.92) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.18) !important;
    border-radius: var(--rot-radius-pill)!important;
}

body[class*='theme-']#quest #health .h-data .stat,
body[class*='theme-']#quest #health .h-data .stat span {
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#quest #health .h-data .cover {
    background: rgba(4, 8, 12, 0.96) !important;
    border-radius: var(--rot-radius-pill)!important;
}

body[class*='theme-']#quest .mod-quest table {
    border-collapse: separate !important;
    border-spacing: 0 !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.14) !important;
    border-radius: var(--rot-radius-panel)!important;
    overflow: hidden !important;
}

body[class*='theme-']#quest .mod-quest thead th {
    background: var(--rot-header-fill) !important;
    border-bottom: 1px solid rgba(var(--rot-accent-rgb), 0.12) !important;
    color: var(--rot-text-strong) !important;
}

body[class*='theme-']#quest .mod-quest tbody td {
    background: var(--rot-panel-fill-soft) !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-']#quest .mod-quest tbody tr:nth-child(even) td {
    background: rgba(var(--rot-accent-rgb), 0.04) !important;
}

body[class*='theme-']#quest .mod-quest a[id$='_link'],
body[class*='theme-']#quest .mod-quest #transport {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding: 8px 12px !important;
    background: var(--rot-button-primary-fill) !important;
    border: 1px solid rgba(var(--rot-accent-rgb), 0.18) !important;
    border-radius: var(--rot-radius-panel)!important;
    color: var(--rot-accent-contrast) !important;
    text-decoration: none !important;
    box-shadow: var(--rot-shadow) !important;
}

body[class*='theme-']#quest .mod-quest a[id$='_link']:hover,
body[class*='theme-']#quest .mod-quest #transport:hover {
    background: var(--rot-button-primary-fill-hover) !important;
    border-color: var(--rot-border-strong) !important;
    color: var(--rot-accent-contrast) !important;
}

/* The unprefixed --radius-* names are a second scale that predates the ROT
   shape scale. Kept only as aliases so old rules keep resolving; they now point
   at the one scale in globalv2.css. Don't add values here — use
   --rot-radius-control / --rot-radius-panel directly in new code. */
body[class*='theme-'] {
    --radius: var(--rot-radius-control);
    --radius-sm: var(--rot-radius-control);
    --radius-md: var(--rot-radius-control);
    --radius-lg: var(--rot-radius-control);
    --radius-xl: var(--rot-radius-panel);
}

body#login[class*='theme-'] h1 .rot-top-banner.auth-top-banner,
body#register[class*='theme-'] h1 .rot-top-banner.auth-top-banner,
body[class*='theme-'] #announcement-list,
body[class*='theme-'] .auth-layout.auth-layout-login,
body[class*='theme-'] .auth-layout.auth-layout-recovery,
body[class*='theme-'] .register-shell .game-description,
body[class*='theme-'] .register-shell .register-header,
body[class*='theme-'] .register-shell .modern-register-form,
body[class*='theme-'] .modern-login-form,
body[class*='theme-'] #cta,
body[class*='theme-'] .modern-recovery-form,
body[class*='theme-'] .recovery-panel,
body[class*='theme-'] .preferences-top-actions,
body[class*='theme-'] .modal-content,
body[class*='theme-'] .changes-container,
body[class*='theme-'] .preference-card,
body[class*='theme-'] .job-content .newmember,
body[class*='theme-'] .job-content .message,
body[class*='theme-'] .job-status,
body[class*='theme-'] .panel-section,
body[class*='theme-'] .career-path,
body[class*='theme-'] .job-category,
body[class*='theme-'] .job-card,
body[class*='theme-'] .modal-container,
body[class*='theme-'] .course-filters,
body[class*='theme-'] .empty-state,
body[class*='theme-'] .course-progress,
body[class*='theme-'] .course-card,
body[class*='theme-'] .mod-donator,
body[class*='theme-'] .donator-greeting,
body[class*='theme-'] .value-chip,
body[class*='theme-'] .donator-package,
body[class*='theme-'] .donator-footer,
body[class*='theme-'] .module-content.training-content,
body[class*='theme-'] .training-content .train-stat-indicator,
body[class*='theme-'] .training-content .training-options-grid,
body[class*='theme-'] .training-content .training-card,
body[class*='theme-'] .training-content .workout-form-container,
body[class*='theme-'] .training-content .option-card,
body[class*='theme-'] .training-content .no-energy-message,
body[class*='theme-'] .advanced-search-container,
body[class*='theme-'] .search-results,
body[class*='theme-'] .mod-events,
body[class*='theme-'] .event-card,
body[class*='theme-'] .player-card,
body[class*='theme-'] #quest .mod-quest #quests,
body[class*='theme-'] #quest .mod-quest table {
    border-radius: var(--rot-radius-xl)!important;
}

/*  >> ACTION BUTTONS WERE PULLED OUT OF THIS RULE (2026-08-07).
    It forces --rot-radius-lg (= --rot-radius-panel, 10px) with !important,
    and eight of its selectors were real buttons: .course-button,
    .action-button, .certificate-button, .donate-button, .modal-cancel-btn,
    .job-content .btn-secondary, .training-content .submit-button and
    .toggle-btn.

    !important here beat buttons.css whatever the chassis said, so those
    eight stayed panel-rounded while every other button in the game sat at
    --rot-radius-control. That was THE source of the button-shape drift --
    it was invisible in the page CSS, which already said 6px.

    What is left below is panels, badges and chrome, which SHOULD be
    panel-rounded. Do not add a button back to it.  */
body[class*='theme-'] .auth-layout.auth-layout-login::before,
body[class*='theme-'] .auth-layout.auth-layout-recovery::before,
body[class*='theme-'] .mobile-topbar,
body[class*='theme-'] .mobile-brand,
body[class*='theme-'] .mobile-chip,
body[class*='theme-'] .cta-faction-card,
body[class*='theme-'] .recovery-helper-note,
body[class*='theme-'] .login-link-card,
body[class*='theme-'] .notice-item,
body[class*='theme-'] .theme-palette-option,
body[class*='theme-'] .status-bar-setup .status-bar-item,
body[class*='theme-'] .job-table,
body[class*='theme-'] .benefit-description,
body[class*='theme-'] .status-indicator,
body[class*='theme-'] .job-requirements,
body[class*='theme-'] .job-benefit,
body[class*='theme-'] .warning-block,
body[class*='theme-'] .course-status,
body[class*='theme-'] .course-warning,
body[class*='theme-'] .benefit-badge,
body[class*='theme-'] .hero-signal,
body[class*='theme-'] .package-price,
body[class*='theme-'] .package-benefits li,
body[class*='theme-'] .donator-disclaimer,
body[class*='theme-'] .train-meter-chip,
body[class*='theme-'] .option-cost,
body[class*='theme-'] .mobile-menu-toggle,
body[class*='theme-'] .mobile-nav-more,
body[class*='theme-'] .mobile-nav-link,
body[class*='theme-'] .mobile-nav-bar,
body[class*='theme-'] #sidebar .mod-user-info,
body[class*='theme-'] #sidebar #user-data,
body[class*='theme-'] #sidebar .note,
body[class*='theme-'] #sidebar #travelNote,
body[class*='theme-'] #sidebar #travelupdate,
body[class*='theme-'] #quest .mod-quest #map a,
body[class*='theme-'] #quest .mod-quest #help a,
body[class*='theme-'] #quest .mod-quest #inventory a,
body[class*='theme-'] #quest .mod-quest a[id$='_link'],
body[class*='theme-'] #quest .mod-quest #transport {
    border-radius: var(--rot-radius-lg)!important;
}

body[class*='theme-'] .auth-input-wrap input,
body[class*='theme-'] .preferences-search input,
body[class*='theme-'] .preferences-container .form-control,
body[class*='theme-'] .char-counter input,
body[class*='theme-'] .training-content select,
body[class*='theme-'] .training-content input[type='number'],
body[class*='theme-'] .training-content input[type='text'],
body[class*='theme-'] .advanced-search-container .form-control,
body[class*='theme-'] #event-search {
    border-radius: var(--rot-radius-md)!important;
}

body[class*='theme-'] .mobile-profile-link,
body[class*='theme-'] .cta-reset-note,
body[class*='theme-'] .donator-hero-kicker,
body[class*='theme-'] .secure-payment,
body[class*='theme-'] .register-kicker,
body[class*='theme-'] .package-badge,
body[class*='theme-'] .cost-indicator {
    border-radius: var(--rot-radius-pill)!important;
}

/* Late shared chrome guardrail. This file loads after page bundles. */
.page-header {
    box-sizing: border-box !important;
    margin: 0 !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-bottom: 0 !important;
    border-radius: var(--rot-chrome-radius) var(--rot-chrome-radius) 0 0!important;
    /* Crest-badge redesign (2026-07-21): the header joins the content stack as a
       panel-toned lid with a soft brass corner glow, instead of the old flat
       lighter-grey band. The brass identity now comes from the crest tile. */
    background:
        radial-gradient(135% 150% at 100% 0%, rgba(var(--rot-accent-rgb), 0.08), transparent 46%),
        var(--rot-panel-fill) !important;
    box-shadow: var(--rot-shadow) !important;
    overflow: hidden !important;
}

/* The home page header used to get a radial hotspot, a second linear wash and
   a triple box-shadow that no other page header had — three layers to say
   "this one is special". It isn't; it's the same component. */
body#loggedin #content > .page-header {
    background:
        radial-gradient(135% 150% at 100% 0%, rgba(var(--rot-accent-rgb), 0.08), transparent 46%),
        var(--rot-panel-fill) !important;
    border-color: rgba(var(--rot-shell-glow-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
}

/*  Seal the header off ONLY when nothing follows it.

    This used to test for a tab strip alone, so a header followed by a content
    wrapper fell through to "seal" -- rounding all four corners and adding an
    18px gap. That is where three of the four different joins across the site
    came from. Content wrappers are now in the exclusion list too.

    Do not try to beat this rule from a later one: `:not(:has(.tabs-navigation))`
    carries the specificity of its argument, so this selector is (0,3,0) and a
    plain `.page-header:has(+ .module)` (0,2,0) loses to it even with
    !important on both. Teach the rule; do not fight it. */
.page-header.no-navigation,
.page-header.no-banner.no-navigation,
.page-header:not(:has(+ .tabs-navigation)):not(:has(+ .training-tabs)):not(:has(+ .module)):not(:has(+ .module-container)):not(:has(+ .content-container)):not(:has(+ .stafflist-container)) {
    border-bottom: 1px solid var(--rot-chrome-border) !important;
    border-radius: var(--rot-chrome-radius)!important;
    margin-bottom: 18px !important;
}

/*  ONE JOIN, EVERYWHERE (2026-07-26).

    The rule above seals the header off -- all four corners rounded, plus an
    18px gap -- whenever a tab strip does NOT immediately follow it. That was
    never a second design; it is the FALLBACK, and it fires on any page whose
    header is followed by a content wrapper instead of tabs. Between them the
    two rules produced four different joins across the site: rounded-gap-
    rounded, rounded-then-square, a faint line in the dead space, and the
    correct docked join.

    They are all the same intent. The header LABELS the content beneath it, so
    it should read as the lid of one continuous frame -- the same way it
    already docks flat into the nav rail above. So: whenever the header is
    followed by a content wrapper OR a tab strip, keep it flat and gapless.
    The wrapper squares its own top to meet it (see the rule below).

    Doing it here rather than in ~18 templates means it no longer matters
    whether a page renders its header inside the wrapper or as a sibling --
    both produce the identical join. */
.page-header:has(+ .module),
.page-header:has(+ .module-container),
.page-header:has(+ .content-container),
.page-header:has(+ .stafflist-container),
.page-header:has(+ .module > .tabs-navigation),
.page-header:has(+ .module > .training-tabs) {
    border-bottom: 0 !important;
    border-radius: var(--rot-chrome-radius) var(--rot-chrome-radius) 0 0!important;
    margin-bottom: 0 !important;
}

#content > .module,
#content2 > .module {
    box-sizing: border-box !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-radius: var(--rot-chrome-radius)!important;
    background: var(--rot-panel-fill) !important;
    box-shadow: var(--rot-shadow) !important;
    overflow: hidden !important;
}

#content > .module::before,
#content2 > .module::before {
    display: none !important;
}

/*  The other half of the join. A wrapper squares its top and drops its top
    border when it either CONTAINS the header (the 30 pages that nest it) or
    FOLLOWS one as a sibling (the 18 that do not). Both arrangements then
    render identically, which is the point -- the markup difference stops
    being visible. */
#content > .module:has(> .page-header),
#content > .module:has(> .tabs-navigation),
#content > .module:has(> .training-tabs),
#content > .page-header + .module,
#content2 > .module:has(> .page-header),
#content2 > .module:has(> .tabs-navigation),
#content2 > .module:has(> .training-tabs),
#content2 > .page-header + .module {
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    margin-top: 0 !important;
}

/*  ...and the same for wrappers the list above does not name. Enumerating them
    is how the site drifted in the first place: `.module`, `.module-container`,
    `.content-container` and `.stafflist-container` were listed, so the pages
    that invented `.rules-container` (gamerules) or `.section-card` (hitlist)
    kept their rounded top and hairline and read as a separate card floating
    under the header. WHATEVER follows a page header is the thing the header
    docks into, so match on position rather than on a class list that will
    always be one page behind.

    Not scoped to `#content` either, because the wrappers are not consistent
    about that: gamerules puts its header inside a `.module-container` that
    hangs off `.page-container`, so an `#content >` prefix simply missed it.
    A page header has exactly one next sibling and that sibling is always the
    content -- no scope is needed to say so.

    IT LIVES AT THE END OF THIS FILE, not here. A 45-selector shared rule at
    ~line 1323 sets `border-radius: var(--rot-radius-xl) !important` on
    `body[class*='theme-'] .module-content.training-content` and friends, at
    (0,3,0). An unprefixed `.page-header + *` is (0,2,0) and loses to it, which
    is why train.php kept a rounded card floating under its header. See
    "THE DOCK" below. */

#content > .module > .page-header,
#content2 > .module > .page-header,
#content > .module > .tabs-navigation,
#content > .module > .training-tabs,
#content2 > .module > .tabs-navigation,
#content2 > .module > .training-tabs {
    box-sizing: border-box !important;
    width: calc(100% + 2px) !important;
    margin-left: -1px !important;
    margin-right: -1px !important;
}

/* DOCK the page header to the top of the content column (2026-07-19). The header
   always sits directly under the primary nav rail (desktop) / status strip (mobile),
   so square its TOP + drop the top border on EVERY page-header — it blends into the
   rail instead of reading as a rounded card lid. Descendant `#content` (spec 1,1,0)
   so it also catches pages that wrap the header (`#content > .module-container >
   .page-header`, e.g. attacklist.php), and beats the `.page-header:has(...)` /
   `.no-navigation` variants (0,3,0). BOTTOM corners keep their per-variant rounding
   (square when a module follows, rounded when standalone). The gap above is closed by
   rot-shell's `.page-container{padding-top:0}`. */
#content .page-header,
#content2 .page-header {
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}
/* Frame the legacy .module-container wrappers like a real .module: a full border
   with a ROUNDED BOTTOM, docked flat + borderless at the TOP under the nav (the
   shared page-header inside spans the full width). Without this, attacklist / train
   / hospital / holding / job / gamerules / lists / spylisting rendered as a
   borderless slab with a squared-off bottom. */
#content > .module-container,
#content2 > .module-container {
    box-sizing: border-box !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-top: 0 !important;
    border-radius: 0 0 var(--rot-chrome-radius) var(--rot-chrome-radius) !important;
    background: var(--rot-panel-fill) !important;
    box-shadow: var(--rot-shadow) !important;
    /*  ▶ CLIP, NOT HIDDEN, AND THE DIFFERENCE IS position: sticky.
        `overflow: hidden` makes an element a SCROLL CONTAINER even though it
        never scrolls, and a scroll container is the scrollport every sticky
        descendant measures its offsets against. .rot-mhead (rot-shell.css)
        asks to stick at `top: var(--rot-chrome-top)` = 117px, meaning 117px
        below the viewport top, under the fixed bar and the stat rails. Inside
        this wrapper it got 117px below THIS BOX instead -- and since the box
        already starts at viewport y=117, the header rendered 60px lower than
        the space reserved for it and sat ON TOP of the page's first 60px of
        content. On job.php that was the Payday Countdown line and half of
        Current Position, unreadable at rest, not just mid-scroll.
        It did not even buy the stickiness it cost: an overflow:hidden box
        cannot scroll, so the header never stuck to anything -- measured
        scrolling clean off the top at y=-396.
        `clip` clips identically (the rounded bottom corners this rule exists
        for still work) without becoming a scroll container, so sticky
        descendants see the viewport again. */
    overflow: clip !important;
    padding-bottom: var(--rot-chrome-pad-y);
}
/* Body gutter for the legacy .module-container pages (attacklist, halloffame,
   holding, hospital, job, lists — and gamerules, which shares the wrapper): their
   body content runs flush to the shell edges because it isn't in a padded .content
   wrapper. Inset the body while the shared page-header + tab bar keep spanning the
   full module width (the "step in" used on shops / inventory / command centre).
   Header + tabs are excluded so they stay full-bleed. */
#content > .module-container > *:not(.page-header):not(.tabs-navigation),
#content2 > .module-container > *:not(.page-header):not(.tabs-navigation) {
    margin-left: var(--rot-chrome-pad-x);
    margin-right: var(--rot-chrome-pad-x);
}
/* Same gutter for the other legacy body wrapper, .content-container (travel, report,
   centrallisting, userlist, usersonline). Here the shared page-header is a SIBLING of
   the wrapper (a direct #content child), so the wrapper itself is pure body -- inset
   it directly. Header stays full-width; body steps in, matching the module-container
   pages above so every page lines up on the same content width. */
/* Frame content-container into the same docked frame the .module-container pages
   get: full width, side + bottom border, rounded bottom, flat/borderless docked
   top. The header + tab strip above already carry side borders at the same x, so
   together the three siblings read as one continuous frame. Body content is inset
   with PADDING (not the old margin) so the frame itself spans full width.
   (usersonline, userlist, report, travel.) */
#content > .content-container,
#content2 > .content-container {
    box-sizing: border-box !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-top: 0 !important;
    border-radius: 0 0 var(--rot-chrome-radius) var(--rot-chrome-radius) !important;
    background: var(--rot-panel-fill) !important;
    box-shadow: var(--rot-shadow) !important;
    padding: var(--rot-chrome-pad-y) var(--rot-chrome-pad-x) !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}
/* On the content-container pages the header, its tab strip and the body are three
   separate #content children instead of one .module, so the tab strip capped
   itself off with a bottom border + an 18px gap, splitting the frame into two
   blocks (usersonline, userlist). Drop that cap so the header -> tabs -> body read
   as one continuous frame with the body's rounded bottom (report has no tab strip,
   so its header meets the body directly). */
#content > .tabs-navigation:has(+ .content-container),
#content2 > .tabs-navigation:has(+ .content-container) {
    border-bottom: 0 !important;
    margin-bottom: 0 !important;
}
/* stafflist uses a bespoke .stafflist-container body straight after a no-navigation
   header, so it had no frame at all. Dock the header into it and frame the body the
   same way -> one continuous panel with a rounded bottom. */
#content > .page-header:has(+ .stafflist-container),
#content2 > .page-header:has(+ .stafflist-container) {
    border-bottom: 0 !important;
    border-radius: 0 !important;
    margin-bottom: 0 !important;
}
#content > .stafflist-container,
#content2 > .stafflist-container {
    box-sizing: border-box !important;
    max-width: none !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-top: 0 !important;
    border-radius: 0 0 var(--rot-chrome-radius) var(--rot-chrome-radius) !important;
    background: var(--rot-panel-fill) !important;
    box-shadow: var(--rot-shadow) !important;
}
/* Legacy pages put the shared header nested inside a wrapper instead of as a direct
   module child — missions had `.module > .head > .page-header` (now cleaned up), and
   education has `.module > .education-container > .page-header` (a real layout scope),
   which the direct-child `:has(> .page-header)` rule above never matched. A DESCENDANT
   `:has(.page-header)` squares any module that holds the shared header at any depth —
   robust to those wrappers AND to a leading <script> that broke a `:first-child` try
   (education echoes one before its module). The module is overflow:hidden so this also
   clips the wrapper's own rounded corner flat. */
#content > .module:has(.page-header),
#content2 > .module:has(.page-header),
#content > .module:first-child,
#content2 > .module:first-child {
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
}

#content > .module:has(> .page-header + .content) > .page-header.no-navigation,
#content2 > .module:has(> .page-header + .content) > .page-header.no-navigation,
#content > .module:has(> .page-header + .content) > .page-header,
#content2 > .module:has(> .page-header + .content) > .page-header {
    border-bottom: 0 !important;
    /* Square top too — this selector (spec ~1,4,0) was the last rule still rounding
       the header lid, overriding the "dock to the rail" square-top rule above. The
       module top is already squared + overflow:hidden, so a rounded header top only
       left a dark notch in the corner (missions: header directly over content). */
    border-radius: 0 !important;
    margin-bottom: 0 !important;
}

.tabs-navigation,
.training-tabs {
    box-sizing: border-box !important;
    display: flex !important;
    align-items: center !important;
    gap: 8px !important;
    margin-top: 0 !important;
    padding: 12px !important;
    border: 1px solid var(--rot-chrome-border) !important;
    border-top: 0 !important;
    border-radius: 0!important;
    background: var(--rot-panel-fill) !important;
    box-shadow: none !important;
}

#content > .module > .tabs-navigation,
#content > .module > .training-tabs,
#content2 > .module > .tabs-navigation,
#content2 > .module > .training-tabs {
    margin-bottom: 0 !important;
    border-bottom: 0 !important;
}

.tab {
    box-sizing: border-box !important;
    min-height: 36px !important;
    padding: 8px 12px !important;
    border-radius: var(--rot-radius-panel)!important;
    letter-spacing: 0 !important;
}

/*  ▶ A STRIP WHOSE WHOLE LIST IS IN THE FIRST-CLASS NAV DOES NOT RENDER TWICE.
    ========================================================================
    Thesifer, 2026-08-09: *"We should drop them everywhere IF they are in a
    'First Class' Nav spot. On Mobile the first class nav is the bottom buttons,
    on PC it's the top nav area."*

    The Command Center's five pages are first class on BOTH surfaces -- the
    phone's Command Center sheet and the top bar's dropdown -- so that strip is
    not rendered at all any more (home.php, achievements.php, achievement_store.php,
    the two spy templates each pass null).

    Inventory, your Cell/Agency and Search are first class on a PC ONLY: they are
    dropdowns on the top bar, and the phone's five bottom tabs carry none of them.
    So their strips are marked `tabs-nav-railed` and hidden from 769px up, where
    the rail has them, and kept below it, where it does not. On a phone that strip
    is still the only route to the Garage, the group Armory or Advanced Search.

    HIDDEN, NOT REMOVED: the header/content join keys off
    `:has(+ ... .tabs-navigation)` to decide whether to square its bottom corners,
    and taking the node out flips those rules and reopens the 18px gap the docked
    join exists to close.

    BOTH SELECTOR SHAPES ARE NEEDED, and this is the trap that ate an hour the
    first time: the strip renders INSIDE the command rail, where
    `.page-header.has-rail .rot-rail > .tabs-navigation { display: flex !important }`
    (globalv2:3938-ish) sits at (0,4,0) -- a bare `.tabs-nav-railed` at (0,1,0)
    loses outright, and !important does not break a specificity tie, it only moves
    the fight to the important layer where specificity still decides. The second
    selector matches that shape exactly and is later in source order.          */
/*  The stand-in title is OFF by default -- below the breakpoint the strip itself
    is the heading. Written at the same specificity as
    `.page-header.has-rail .rot-rail > .header-heading` (globalv2:3938), which is
    what would otherwise give it `display: flex` at every width -- and did, the
    first time this pattern was built: the title AND the strip printed together.

    IT MUST COME BEFORE THE MEDIA BLOCK. Both rules are (0,4,0) and !important,
    so the later one wins the tie at every width -- putting this second would
    have silently blanked the desktop heading it exists to supply. */
.page-header.has-rail .rot-rail > .header-heading-desktop-only {
    display: none !important;
}

@media (min-width: 769px) {
    .tabs-nav-railed,
    .page-header.has-rail .rot-rail > .tabs-nav-railed {
        display: none !important;
    }
    /*  ...and the title the strip was standing in for comes back. Exactly one of
        the two is ever visible: this title at this width, the strip below it.

        `flex`, NOT `block`: the rail is a flex row and globalv2:4006 gives the
        ordinary `.header-heading` `display:flex; flex-direction:column;
        justify-content:center`. Setting `block` here made the title a short line
        pinned to the TOP of a 64px rail with the description stranded below it —
        this stand-in has to be the same object as the heading it replaces. */
    .page-header.has-rail .rot-rail > .header-heading-desktop-only {
        display: flex !important;
    }
}

#content > .module > .content,
#content2 > .module > .content {
    box-sizing: border-box !important;
    margin: 0 !important;
    padding: var(--rot-chrome-pad-y) var(--rot-chrome-pad-x) 20px !important;
    border: 0 !important;
    border-radius: 0!important;
    background: var(--rot-panel-fill) !important;
    box-shadow: none !important;
}

@media (max-width: 768px) {
    .page-header {
        border-radius: var(--rot-chrome-radius-mobile) var(--rot-chrome-radius-mobile) 0 0!important;
    }

    .page-header.no-navigation,
    .page-header.no-banner.no-navigation,
    .page-header:not(:has(+ .tabs-navigation)):not(:has(+ .training-tabs)) {
        border-radius: var(--rot-chrome-radius-mobile)!important;
        margin-bottom: 14px !important;
    }

    .page-header:has(+ .module > .tabs-navigation),
    .page-header:has(+ .module > .training-tabs) {
        border-radius: var(--rot-chrome-radius-mobile) var(--rot-chrome-radius-mobile) 0 0!important;
        margin-bottom: 0 !important;
    }

    #content > .module:has(> .page-header + .content) > .page-header.no-navigation,
    #content2 > .module:has(> .page-header + .content) > .page-header.no-navigation,
    #content > .module:has(> .page-header + .content) > .page-header,
    #content2 > .module:has(> .page-header + .content) > .page-header {
        border-radius: 0 !important;
        margin-bottom: 0 !important;
    }

    /*  THE COMMAND CENTER'S STRIP USED TO BE HIDDEN HERE (2026-08-03), with a
        `header-heading-mobile-only` title standing in for it below this width.
        Both rules are gone: the strip is not rendered at ALL any more, on either
        surface, because its five destinations are first class on both -- the
        phone's Command Center sheet and the desktop bar's dropdown. With no
        strip, render_page_header() prints its ordinary heading again and there
        is nothing to stand in for.

        The mirror of that pattern -- a strip covered on the PC only -- lives
        above this block as `.tabs-nav-railed`. */

    .tabs-navigation,
    .training-tabs {
        flex-wrap: nowrap !important;
        margin-bottom: 14px !important;
        padding: 10px !important;
        overflow-x: auto !important;
        scrollbar-width: none !important;
        white-space: nowrap !important;
        scroll-snap-type: x proximity !important;
    }

    .tabs-navigation::-webkit-scrollbar,
    .training-tabs::-webkit-scrollbar {
        display: none !important;
    }

    #content > .module > .tabs-navigation,
    #content > .module > .training-tabs,
    #content2 > .module > .tabs-navigation,
    #content2 > .module > .training-tabs {
        margin-bottom: 0 !important;
    }
}

/* ═══════════════════════════════════════════════════════════════════════════
   COMMAND RAIL — the header BOX (2026-07-24)
   ═══════════════════════════════════════════════════════════════════════════
   One header shape for every page: a self-contained rounded bar floating 18px
   above the content, with NO bottom divider.

   Before this, the legacy variant classes gave the identical component two
   different silhouettes. Pages without `no-navigation` got margin-bottom:18px,
   bottom-only rounding and a 1px bottom border (a detached card); pages with it
   got margin:0 and radius:0, welded to the panel below. So the whole page
   shifted every time you moved between them -- reported as "Achievement Store is
   at an entirely separate level" and "Disruption Briefing is too far up". The
   border goes entirely: with the rail there is nothing above the line for it to
   separate from, and a line on some pages but not others is what made the set
   read as assembled from parts.

   THIS LIVES HERE, NOT IN globalv2.css, ON PURPOSE. Six rules in this file set
   these same three properties, and the one that actually won is

       #content > .module:has(> .page-header + .content) > .page-header.no-navigation

   at roughly (1,5,0). globalv2.css loads BEFORE this file, so matching that from
   there means out-specifying it outright -- an arms race that the next override
   added here would silently win back. Last file + last rule + one ID is the
   stable answer, and it sits with the rest of the chrome overrides where anyone
   looking for header geometry will actually find it.

   The rail's INTERNALS (peg, tabs, heading, context slot) stay in globalv2.css;
   only the outer box is contested. */
#content .page-header.has-rail,
#content2 .page-header.has-rail,
#content > .module > .page-header.has-rail,
#content2 > .module > .page-header.has-rail,
#content > .module:has(> .page-header + .content) > .page-header.has-rail,
#content2 > .module:has(> .page-header + .content) > .page-header.has-rail {
    /*  ONE JOIN (2026-07-26). This used to be `margin: 0 0 18px` with a rounded
        bottom, which made the header a floating card and left a dead 18px band
        between it and the content it labels. Combined with the seal rule higher
        up, the site ended up with four different header-to-content joins:
        rounded/gap/rounded, rounded/gap/square, a faint line in the dead band,
        and the docked one.

        Picked the docked join, because it is what the header already does at
        its TOP edge -- it squares into the nav rail rather than floating under
        it -- and because the header LABELS the content beneath it. Two edges of
        the same object should not have a gap down the middle. It is also the
        one that costs no vertical space, on pages that were already pushing
        content below the fold.

        The content block below squares its own top and drops its top border
        (see the `.page-header + .module` rules above), so the two read as a
        single frame whose only rounded edge is the bottom of the content. */
    margin: 0 !important;
    padding: 0 !important;
    /*  LONGHANDS, NOT `border: 1px solid var(--rot-chrome-border)`.
        A shorthand containing a var() is a PENDING-SUBSTITUTION value: Chrome
        keeps it whole until computed-value time, and while it is pending it
        swallows the longhands that later, MORE specific !important rules set.
        That is why an attempt to drop just the side borders from a nested
        header did nothing here -- the override matched, was later in the file,
        was more specific, and still lost. Written as longhands it behaves. */
    border-width: 1px !important;
    border-style: solid !important;
    border-color: var(--rot-chrome-border) !important;
    border-bottom-width: 0 !important;
    /* TOP CORNERS SQUARE. The header sits directly beneath the full-width nav
       strip, which has a square bottom edge -- rounding the header's top corners
       cuts a notch out of that join on both sides and shows the page background
       through it. Unifying the header box is what reintroduced this: the shape
       before was top-square / bottom-rounded.

       BOTTOM CORNERS NOW SQUARE TOO: the header no longer floats, it docks into
       the content block beneath it, so neither of its horizontal edges is free.
       The rounded bottom now belongs to the content block, which is the actual
       end of the frame. */
    border-radius: 0 !important;
    /*  NO SHADOW ON A DOCKED HEADER. `--rot-shadow` is a downward drop, and
        with the header sitting flush on the content it was cast straight onto
        it -- a 4px fade from rgb(12,15,18) back up to the panel fill, right at
        the seam. That soft dark band IS the "black line" the join was supposed
        to remove; squaring the corners alone did not get rid of it because it
        was never a border. The wrapper below still carries `--rot-shadow`, so
        the frame keeps its lift; only the internal edge stops casting. */
    box-shadow: none !important;
}

/*  ...UNLESS THERE IS NOTHING TO DOCK INTO.
    A header with no following element (an empty state, a page whose whole body
    is the header) would otherwise be left with an open bottom edge -- three
    borders and a gap where the fourth should be. `:has(+ *)` is the honest test
    and it works for BOTH layouts, because the thing that follows is `.content`
    when the header is nested inside the module and `.module` when it is a
    sibling. Same selectors, one negation, and last in the file, so it beats the
    docked rule above without another round of specificity inflation. */
#content .page-header.has-rail:not(:has(+ *)),
#content2 .page-header.has-rail:not(:has(+ *)),
#content > .module > .page-header.has-rail:not(:has(+ *)),
#content2 > .module > .page-header.has-rail:not(:has(+ *)) {
    margin-bottom: 18px !important;
    border-bottom-width: 1px !important;
    border-radius: 0 0 var(--rot-chrome-radius) var(--rot-chrome-radius) !important;
    /* Nothing below it to cast onto, so the lift comes back. */
    box-shadow: var(--rot-shadow) !important;
}

/* A slot note that is a WARNING, not a classification — the Vehicle slot uses it
   for a damaged vehicle, which is still equipped but cannot be driven.
   This file forces `.detail-subvalue { color: var(--rot-text-muted) !important }`
   a few hundred lines up, which greyed the warning out along with every ordinary
   sub-label. Same !important, one class more specific, and last. */
body[class*='theme-'] .detail-subvalue.is-warn {
    color: var(--rot-danger-text) !important;
}

/* =====================================================================
   THE DOCK — the header and the content below it are ONE frame.
   =====================================================================

   The site had four different joins between a page header and the content
   it labels: rounded-bottom + 18px black band + rounded-top card; rounded
   bottom then a square top; a faint hairline floating in the dead band; and
   the docked join. They were never four designs -- they were one intent plus
   the fallbacks of a `:has()` selector, firing differently depending on
   whether a page nested its header inside the wrapper (30 pages) or rendered
   it as a sibling (18), and on which wrapper class that page invented.

   Docked wins. The header already squares flat into the nav rail at its TOP
   edge; a header that labels the content beneath it should not then float
   above it with a gap down the middle. It also costs no vertical space.

   THREE THINGS MAKE THE JOIN, and all three are here at the end of the file
   on purpose. Every one of them is contested by an earlier rule with more
   specificity and !important -- the 45-selector radius rule near line 1323
   (0,3,0) and the `.has-rail` geometry above. Last-in-file plus a
   `body[class*='theme-']` prefix is the only thing that stays won without
   starting another specificity arms race. */

/* 1. WHATEVER FOLLOWS THE HEADER squares its top and drops its top border.
      Matched on POSITION, not on a class list -- enumerating wrappers is how
      this drifted: `.module`, `.module-container`, `.content-container` and
      `.stafflist-container` were listed, so gamerules' `.rules-container`,
      hitlist's `.section-card` and train's `.module-content` kept their
      rounded lid and read as a separate card. A page header has exactly one
      next sibling and that sibling is always its content. */
body[class*='theme-'] .page-header.has-rail + *,
body[class*='theme-'] #content > .page-header + *,
body[class*='theme-'] #content2 > .page-header + *,
body[class*='theme-'] #content > .module > .page-header + *,
body[class*='theme-'] #content2 > .module > .page-header + * {
    border-top: 0 !important;
    border-top-left-radius: 0 !important;
    border-top-right-radius: 0 !important;
    margin-top: 0 !important;
}

/* 2. NO DOUBLED SIDE BORDER. A nested header sits INSIDE its wrapper's 1px
      border and draws its own, so the left edge painted two lines a pixel
      apart -- visible as a thick, slightly mismatched rail. The old fix was
      `width: calc(100% + 2px); margin-left: -1px` to overlap them, which the
      `margin: 0 !important` on `.has-rail` above silently undid. Dropping the
      header's side borders is the honest version: the wrapper owns the frame,
      the header is a band inside it. */
/*  The `:has()` variants are NOT optional padding. `:has()` carries the
    specificity of its most specific argument, so
    `#content > .module:has(> .page-header + .content) > .page-header.has-rail`
    in the base rule above scores (1,5,0) -- and that is the exact shape of
    missions / yourgroup / achievements, whose module holds `.page-header +
    .content`. Without matching it here, those three pages (and only those)
    kept the doubled border while every other page lost it, which reads as a
    random failure and is not one. */
#content > .module:has(> .page-header + .content) > .page-header.has-rail,
#content2 > .module:has(> .page-header + .content) > .page-header.has-rail,
#content > .module > .page-header.has-rail,
#content2 > .module > .page-header.has-rail,
#content > .module-container > .page-header.has-rail,
#content2 > .module-container > .page-header.has-rail,
#content > .content-container > .page-header.has-rail,
#content2 > .content-container > .page-header.has-rail,
#content .module-container > .page-header.has-rail,
#content2 .module-container > .page-header.has-rail {
    border-left-width: 0 !important;
    border-right-width: 0 !important;
    width: 100% !important;
    margin: 0 !important;
}

/* 3. THE BAND BETWEEN THEM STAYS BACKGROUND-COLOURED. The legacy wrappers
      inset their body by 18px a side (the "step in" gutter), which is fine --
      but only while the inset block has no lid of its own. With 1. applied it
      reads as the same surface continuing, which is the point. */

/* =====================================================================
   PAGINATION — one line, always.
   ---------------------------------------------------------------------
   mainv5.css sets `flex-wrap: wrap` on both the pager and its number
   list, so once the row is wider than its container the items break
   wherever they happen to fall -- which on a long log stranded "Last"
   alone on a second line, and on a phone broke an eleven-item pager into
   four lines.

   The window is capped at 7 numbers now (class.htmlSnippets.php clamps
   it), so desktop fits comfortably. Below that the NUMBERS scroll and
   the controls stay put: First/Prev/Next/Last are the things you reach
   for on a small screen, and they should never be the things that move.

   Lives here rather than in mainv5.css because mainv5 is in all 53
   bundles in min/groupsConfig.php -- editing it means bumping 53 cache
   versions, while this file is a single <link> on every page.
   ===================================================================== */
body[class*='theme-'] .pagination {
    flex-wrap: nowrap;
    min-width: 0;
}
body[class*='theme-'] .pagination ul {
    flex-wrap: nowrap;
    overflow-x: auto;
    min-width: 0;
    scrollbar-width: none;          /* the arrows are the affordance, not a bar */
}
body[class*='theme-'] .pagination ul::-webkit-scrollbar { display: none; }
body[class*='theme-'] .pagination > a { flex: none; }


/* =====================================================================
   PHONE — donator. Before: first control at y=863 on a 2,098px page.
   Lives here because the page has no stylesheet of its own; mod-donator
   is styled from mainv5/theme-overrides.
   ===================================================================== */
@media (max-width: 768px) {
  /*  The four-chip strip is marketing copy: "31-65 days per pack",
      "+5 to +12 Intelligence". You are on this page because you already
      decided; what you need is the price list. The one chip that is about
      YOU -- days held -- is in the header now. */
  body#donator .donator-value-strip { display: none; }
}

/*  FIELD REPORT — the pieces the profile's header band introduced. Brass is a
    THEMED colour, so anything painted with it here has to be named or it stays
    the default gold while the rest of the page turns. */
body[class*='theme-'] .mod-home .fr-rank-num,
body[class*='theme-'] .mod-home .fr-total-value,
body[class*='theme-'] .mod-home .fr-refer-count strong,
body[class*='theme-'] .mod-home .fr-figure > i,
body[class*='theme-'] .mod-home .fr-tile > i,
body[class*='theme-'] .mod-home .fr-seal-year {
    color: var(--rot-accent) !important;
}

body[class*='theme-'] .mod-home .fr-rank,
body[class*='theme-'] .mod-home .fr-figure,
body[class*='theme-'] .mod-home .fr-tile {
    background: var(--rot-surface-raised) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
}

/*  The band and the footing figure are the two surfaces that carry LIGHT rather
    than a fill. Restated in themed tokens instead of being flattened by the
    card rule above -- a theme changes what colour the light is, not whether
    there is any. */
body[class*='theme-'] .mod-home .fr-band {
    background:
        radial-gradient(120% 140% at 8% 0%, rgba(var(--rot-accent-rgb), 0.10), transparent 58%),
        linear-gradient(160deg, var(--rot-panel-fill-strong), var(--rot-panel-fill)) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.16) !important;
    box-shadow: var(--rot-shadow) !important;
    color: var(--rot-text) !important;
}

body[class*='theme-'] .mod-home .fr-total {
    background:
        radial-gradient(90% 120% at 50% 0%, rgba(var(--rot-accent-rgb), 0.12), transparent 70%),
        rgba(0, 0, 0, 0.3) !important;
    border-color: rgba(var(--rot-accent-rgb), 0.28) !important;
}

/*  Money stays green under every theme — the same exception the rest of the
    site makes for a balance. */
body[class*='theme-'] .mod-home .fr-tile.is-money > i,
body[class*='theme-'] .mod-home .fr-tile.is-money .fr-tile-value {
    color: var(--rot-money) !important;
}

body[class*='theme-'] .mod-home .fr-kicker,
body[class*='theme-'] .mod-home .fr-figure-sub {
    color: var(--rot-text-muted) !important;
}
