/**
 * GTPlanet Rig Builder
 *
 * Loads AFTER the site's shared global.css and site-shell.css, which draw the
 * page chrome (nav, breadcrumbs, footer). The theme's WordPress stylesheets
 * are not loaded (§17.421). This stylesheet adds Rig Builder components.
 *
 * Theming follows the site: dark mode is the `.dark` class on <html>, set by
 * an inline script before first paint. `@media (prefers-color-scheme)` is
 * never used as the styling switch, because it would ignore the visitor's
 * explicit choice in the footer theme selector.
 *
 * Values come from docs/design-tokens.md.
 */

/* --------------------------------------------------------------------------
   Base typography

   On WordPress pages this comes from the stylesheet WordPress generates at
   runtime from the theme's theme.json, which a standalone application cannot
   link to. These are the computed values measured on a live GTPlanet page, so
   Rig Builder pages match the rest of the site. Everything else — chrome,
   colours, layout — is inherited from the shared stylesheets.
   -------------------------------------------------------------------------- */

body {
    font-family: -apple-system, system-ui, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
    font-size: 16px;
    line-height: 1.5;
}

/* --------------------------------------------------------------------------
   Tokens — light mode
   -------------------------------------------------------------------------- */

:root {
    /* Brand */
    --rb-brand-charcoal: #232323;
    --rb-brand-red: #d00000;
    --rb-brand-blue: #00528c;
    --rb-brand-red-grad: linear-gradient(0deg, #901600, #c11d00);
    --rb-accent-blue: #1172b7;

    /* Surfaces & text */
    --rb-bg-card: #fff;
    --rb-bg-subtle: #f5f5f5;
    --rb-border: #d8d8d8;
    --rb-border-strong: #cbcbcb;
    --rb-text-body: #141414;
    --rb-text-link: #004d90;
    /* Headings are plain black on light and near-white on dark, matching the
       site's content colour. Blue belongs to links, not headings. */
    --rb-text-heading: #000;
    --rb-text-muted: #8c8c8c;

    /* Commerce */
    --rb-buy-bg: #1c7c1c;
    --rb-buy-bg-hover: #289528;
    --rb-buy-gradient: linear-gradient(180deg, #2a8c2a, #166f16);
    --rb-buy-gradient-hover: linear-gradient(180deg, #35a035, #208220);
    --rb-buy-border: #126810;

    /* Status: positive / savings */
    --rb-positive-bg: #e3f4e3;
    --rb-positive-border: #9fc79f;
    --rb-positive-text: #426b42;

    /* Status: selected / current */
    --rb-highlight-bg: #fff5d1;
    --rb-nav-current-bg: #e3eef8;
    --rb-nav-current-text: #004d90;
    --rb-highlight-border: #dcbd62;
    --rb-highlight-text: #61542d;

    /*
     * Light-mode error colours are not specified in docs/design-tokens.md
     * (only the dark ones are). These are derived from the dark error family
     * and should be replaced if the token file gains authoritative values.
     */
    --rb-error-bg: #fdeaea;
    --rb-error-border: #9c3030;
    --rb-error-text: #8a1f1f;

    /* Shape & spacing */
    --rb-radius: 4px;
    --rb-pad-block: 10px;
    --rb-gap: 10px;
}

/* --------------------------------------------------------------------------
   Tokens — dark mode
   -------------------------------------------------------------------------- */

.dark {
    --rb-brand-red-grad: linear-gradient(0deg, #5d0e00, #841300);

    --rb-bg-card: #141517;
    --rb-bg-subtle: #232323;
    --rb-border: #323232;
    --rb-border-strong: #505050;
    --rb-text-body: #d9d9d9;
    --rb-text-link: rgba(255, 255, 255, 0.75);
    --rb-text-heading: rgba(255, 255, 255, 0.95);
    --rb-text-muted: #ababab;

    /* The buy green is deliberately unchanged: it reads well on dark surfaces
       and the site's own CSS does not override it. */

    --rb-positive-bg: rgba(160, 251, 160, 0.08);
    --rb-positive-border: #3f6520;
    --rb-positive-text: #6ca56c;

    --rb-highlight-bg: rgba(255, 246, 201, 0.21);
    --rb-nav-current-bg: rgba(17, 114, 183, 0.22);
    --rb-nav-current-text: #fff;
    --rb-highlight-border: #6b5f2e;
    --rb-highlight-text: #d4bb3b;

    --rb-error-bg: #481111;
    --rb-error-border: #9c3030;
    --rb-error-text: #ff6f74;
}

/* Keep the Rig Builder shell aligned independently of the shared site width. */
.rigbuilder .p-nav-inner,
.rigbuilder .p-sectionLinks-inner,
.rigbuilder .p-body-inner,
.rigbuilder .p-footer-inner {
    max-width: 1280px;
}

/* --------------------------------------------------------------------------
   Header Search menu (§17.411)

   The forum's Search tab opens a XenForo "structural" menu: it hangs from the
   tab's bottom-right corner, the tab turns dark blue with square bottom
   corners, and the menu has a blue top border, a large blue heading, and a
   grey footer holding the button. These rules redraw that menu with our own
   class names, using the forum's values from xf.css, xf-dark.css and
   XenForo's compiled CSS, since the forum's menu styles are not in the shared
   files the Rig Builder loads.
   -------------------------------------------------------------------------- */

.rb-searchNav {
    position: relative;
}

.rigbuilder .p-navgroup-link--search.is-menuOpen {
    color: #e8f4fc;
    background: #2d4563;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.35);
}

.dark .rigbuilder .p-navgroup-link--search.is-menuOpen {
    background: rgba(155, 155, 155, 0.5);
}

.rb-searchMenu {
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 200;
    width: 350px;
    max-width: calc(100vw - 10px);
    border-radius: 3px 0 3px 3px;
    box-shadow: 0 5px 10px 0 rgba(0, 0, 0, 0.35);
    text-align: left;
}

.rb-searchMenu[hidden] {
    display: none;
}

.rb-searchMenu-content {
    margin: 0;
    font-size: 12px;
    line-height: 1.4;
    color: #000;
    background: #fff;
    border-top: 3px solid var(--rb-accent-blue);
    border-radius: 0 0 3px 3px;
    overflow: hidden;
}

.rb-searchMenu-header {
    margin: 0;
    padding: 6px 15px;
    font-size: 17px;
    font-weight: 400;
    line-height: 1.4;
    color: #1474b8;
    background: #fff;
    border-bottom: 1px solid #e0e0e0;
}

.rb-searchMenu-row {
    display: flex;
    padding: 12px 15px;
}

.rb-searchMenu-row .rb-input {
    flex: 1 1 auto;
    padding: 6px 8px;
}

.rb-searchMenu-footer {
    display: flex;
    justify-content: flex-end;
    padding: 6px 15px;
    background: linear-gradient(180deg, #f5f5f5, #fafafa);
    border-top: 1px solid #e0e0e0;
}

.rb-searchMenu-footer .rb-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.dark .rb-searchMenu-content,
.dark .rb-searchMenu-footer {
    color: #d9d9d9;
    background: #141517;
}

.dark .rb-searchMenu-header {
    color: #d0d0d0;
    background: #232323;
    border-color: #565656;
}

.dark .rb-searchMenu-footer {
    border-top-color: #585858;
}

/* On phones the menu still hangs from the tab, narrowed to fit the screen.
   The tab grows to the forum's phone size (xf.css gives its header links a
   23px line), so it is an easy target and meets the menu below it. The
   negative margins let it grow without moving Log In and Register. */
@media (max-width: 650px) {
    .rigbuilder .p-navgroup-link--search {
        margin: -7px 0;
        padding: 8px 12px;
        line-height: 23px;
    }

    .rigbuilder .p-navgroup-link--search .search-icon {
        height: 17px;
        vertical-align: -3px;
    }

    .rb-searchMenu {
        top: calc(100% + 7px); /* under the tab's bottom margin above */
        max-width: calc(100vw - 20px);
    }

    .rb-searchMenu-row .rb-input {
        font-size: 16px; /* stops iOS zooming in on focus */
    }
}

/* On short pages the body grows to fill the window, so the footer sits at the
   bottom instead of floating mid-screen (§17.233). The body keeps its capped,
   centered width: auto margins would otherwise stop it stretching. */
.rigbuilder #page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
}

.rigbuilder #page > .p-body-inner {
    flex: 1 0 auto;
    width: 100%;
}

/* Public navigation shares the site's content width and theme tokens. */
.rigbuilder .p-body-inner.rb-publicLayout {
    display: grid;
    grid-template-columns: 210px minmax(0, 1fr);
    align-items: start;
    gap: 10px;
}

.rb-publicLayout > .block-container {
    min-width: 0;
}

.rb-sidebar-links {
    list-style: none;
    margin: 0;
    padding: 4px 0;
}

.rb-sidebar-links a {
    display: block;
    padding: 8px 10px;
    border-left: 3px solid transparent;
    color: var(--rb-text-link);
    font-size: 14px;
    text-decoration: none;
    overflow-wrap: anywhere;
}

.rb-sidebar-hardware .rb-sidebar-links a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.rb-category-icon {
    display: block;
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
}

.rb-sidebar-links a:hover,
.rb-sidebar-links a:focus-visible {
    background: var(--rb-bg-subtle);
    border-left-color: var(--rb-accent-blue);
}

/* The current page is a soft blue tint, lighter than the header tab and blue buttons (§17.218). */
.rb-sidebar-links a[aria-current],
.rb-sidebar-links a[aria-current]:visited,
.rb-sidebar-links a[aria-current]:hover {
    color: var(--rb-nav-current-text);
    background: var(--rb-nav-current-bg);
    border-left-color: var(--rb-accent-blue);
    font-weight: 700;
}

/* Beside the content, the sidebar stays in view as the page scrolls (§17.240).
   The script sets the offset, so without it the sidebar simply scrolls. */
@media (min-width: 1001px) {
    .rb-sidebar.is-sticky {
        position: sticky;
        top: var(--rb-sidebar-top, 94px);
    }
}

.rb-sidebar-rigs > summary,
.rb-sidebar-hardware > summary,
.rb-sidebar-brands > summary {
    cursor: pointer;
}

/* --------------------------------------------------------------------------
   Narrow-screen nav (§17.277)

   Below the tablet breakpoint pages get the full width (§17.210) and the
   sidebar gives way to a compact nav above the content: tabs for the Rigs
   links and a Browse menu, then a row of category chips that scrolls sideways.
   -------------------------------------------------------------------------- */

.rb-mnav {
    display: none;
}

@media (max-width: 1000px) {
    /* Rows keep their own height, so on a short page the space that holds the
       footer down (§17.233) goes below the content, not between the rows. */
    .rigbuilder .p-body-inner.rb-publicLayout {
        grid-template-columns: minmax(0, 1fr);
        align-content: start;
        gap: 10px;
    }

    .rb-publicLayout > .rb-sidebar {
        display: none;
    }

    .rb-mnav {
        display: block;
        background: var(--rb-bg-card);
        border: 1px solid var(--rb-border);
        border-radius: var(--rb-radius);
    }
}

/* Phones: edge to edge like the blocks (§17.237). */
@media (max-width: 650px) {
    .rb-mnav {
        border-radius: 0;
        border-left-width: 0;
        border-right-width: 0;
    }
}

/* The Browse menu opens under this bar, so the bar positions it. */
.rb-mnav-bar {
    position: relative;
    display: flex;
    border-bottom: 1px solid var(--rb-border);
}

.rb-mnav-tabs {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    margin: 0;
    padding: 0;
    list-style: none;
}

/* Tabs share the spare width but size to their names, so short "My Rigs"
   leaves room for the longer names on a 320px phone. */
.rb-mnav-tabs li {
    flex: 1 1 auto;
    min-width: 0;
}

.rb-mnav-tabs a,
.rb-mnav-browse > summary {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 5px;
    height: 100%;
    min-height: 44px;
    padding: 0 4px;
    color: var(--rb-text-link);
    font-size: 14px;
    font-weight: 600;
    line-height: 1.2;
    text-align: center;
    text-decoration: none;
}

.rb-mnav-tabs a:hover,
.rb-mnav-tabs a:focus-visible,
.rb-mnav-browse > summary:hover,
.rb-mnav-browse > summary:focus-visible {
    background: var(--rb-bg-subtle);
}

/* The current tab takes the sidebar's current style, with its accent on the bottom edge (§17.218). */
.rb-mnav-tabs a[aria-current],
.rb-mnav-tabs a[aria-current]:visited,
.rb-mnav-tabs a[aria-current]:hover {
    color: var(--rb-nav-current-text);
    background: var(--rb-nav-current-bg);
    box-shadow: inset 0 -3px 0 var(--rb-accent-blue);
    font-weight: 700;
}

.rb-mnav-browse {
    flex: 0 0 auto;
    border-left: 1px solid var(--rb-border);
}

.rb-mnav-browse > summary {
    padding: 0 12px;
    list-style: none;
    cursor: pointer;
}

.rb-mnav-browse > summary::-webkit-details-marker {
    display: none;
}

.rb-mnav-browse > summary svg {
    flex: none;
    transition: transform 0.15s;
}

/* The smallest phones keep every tab name on one line (§17.383). */
@media (max-width: 360px) {
    .rb-mnav-tabs a,
    .rb-mnav-browse > summary {
        font-size: 13px;
        white-space: nowrap;
    }

    .rb-mnav-browse > summary {
        padding: 0 8px;
    }
}

/* On Best Deals, which lives in this menu, Browse is the current tab (§17.383). */
.rb-mnav-browse--current > summary {
    color: var(--rb-nav-current-text);
    background: var(--rb-nav-current-bg);
    box-shadow: inset 0 -3px 0 var(--rb-accent-blue);
    font-weight: 700;
}

.rb-mnav-browse[open] > summary {
    background: var(--rb-bg-subtle);
    box-shadow: inset 0 -3px 0 var(--rb-accent-blue);
}

.rb-mnav-browse[open] > summary svg {
    transform: rotate(180deg);
}

/* The menu drops over the page like the site's own menus, with the sticky nav's shadow. */
.rb-mnav-panel {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    z-index: 50;
    padding: 4px 10px 12px;
    background: var(--rb-bg-card);
    border-bottom: 1px solid var(--rb-border);
    box-shadow: 0 4px 4px 1px rgb(0 0 0 / 20%);
}

.rb-mnav-heading {
    margin: 10px 0 6px;
    color: var(--rb-text-heading);
    font-size: 15px;
    font-weight: 700;
}

.rb-mnav-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-mnav-grid a {
    display: flex;
    align-items: center;
    gap: 8px;
    box-sizing: border-box;
    min-height: 40px;
    height: 100%;
    padding: 6px 10px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    color: var(--rb-text-link);
    font-size: 14px;
    line-height: 1.25;
    text-decoration: none;
}

/* Chips and menu tiles lead with the category icon. */
.rb-mnav-grid .rb-category-icon,
.rb-mnav-chips .rb-category-icon {
    order: -1;
}

.rb-mnav-grid a:hover,
.rb-mnav-grid a:focus-visible,
.rb-mnav-chips a:hover,
.rb-mnav-chips a:focus-visible {
    background: var(--rb-bg-subtle);
    border-color: var(--rb-accent-blue);
}

.rb-mnav-grid a[aria-current],
.rb-mnav-grid a[aria-current]:visited,
.rb-mnav-grid a[aria-current]:hover,
.rb-mnav-chips a[aria-current],
.rb-mnav-chips a[aria-current]:visited,
.rb-mnav-chips a[aria-current]:hover {
    color: var(--rb-nav-current-text);
    background: var(--rb-nav-current-bg);
    border-color: var(--rb-accent-blue);
    font-weight: 700;
}

/* One row that scrolls sideways. An edge fades while there are more chips
   past it, so the row reads as continuing off the screen. */
.rb-mnav-chips {
    display: flex;
    gap: 6px;
    margin: 0;
    padding: 8px 10px;
    list-style: none;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
    --rb-fade-start: 0px;
    --rb-fade-end: 28px;
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--rb-fade-start), #000 calc(100% - var(--rb-fade-end)), transparent);
    mask-image: linear-gradient(to right, transparent, #000 var(--rb-fade-start), #000 calc(100% - var(--rb-fade-end)), transparent);
}

.rb-mnav-chips::-webkit-scrollbar {
    display: none;
}

/* The script sets these as the row scrolls. Without it only the end fades. */
.rb-mnav-chips.is-scrolled {
    --rb-fade-start: 28px;
}

.rb-mnav-chips.is-end {
    --rb-fade-end: 0px;
}

.rb-mnav-chips li {
    flex: none;
}

.rb-mnav-chips a {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px 5px 9px;
    border: 1px solid var(--rb-border-strong);
    border-radius: 16px;
    color: var(--rb-text-link);
    font-size: 14px;
    line-height: 1.4;
    white-space: nowrap;
    text-decoration: none;
}

.rb-mnav-chips .rb-category-icon {
    flex-basis: 18px;
    width: 18px;
    height: 18px;
}

/* --------------------------------------------------------------------------
   Section block — the site's core visual unit (design-tokens.md §8)

   Red-gradient header bar + card body. Rig Builder panels (results tiers,
   product page sections, build summary) are all built from this.
   -------------------------------------------------------------------------- */

.rb-block {
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    overflow: hidden;
    margin-bottom: var(--rb-gap);
}

.rb-block:last-child {
    margin-bottom: 0;
}

/* Phones: blocks run edge to edge, so they square off and drop the side borders
   that would sit against the screen edge (§17.237). */
@media (max-width: 650px) {
    .rb-block {
        border-radius: 0;
        border-left-width: 0;
        border-right-width: 0;
    }
}

.rb-block-header {
    background: var(--rb-brand-red-grad);
    color: #fff;
    font-size: 15px;
    font-weight: 700;
    padding: 4px 10px;
    margin: 0;
}

.rb-block-body {
    padding: var(--rb-pad-block);
    color: var(--rb-text-body);
}

.rb-block-body > p {
    margin: 0 0 10px;
}

.rb-block-body > p:last-child {
    margin-bottom: 0;
}

/* --------------------------------------------------------------------------
   Status rows — left-border accent pattern (design-tokens.md §8)
   -------------------------------------------------------------------------- */

.rb-statusList {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rb-status {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 10px;
    padding: 6px 10px;
    margin-bottom: 4px;
    border-left: 3px solid var(--rb-border-strong);
    background: var(--rb-bg-subtle);
    border-radius: 0 var(--rb-radius) var(--rb-radius) 0;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-status:last-child {
    margin-bottom: 0;
}

.rb-status-label {
    font-weight: 600;
    min-width: 190px;
}

.rb-status-detail {
    color: var(--rb-text-muted);
    font-size: 12px;
    flex: 1 1 260px;
    min-width: 0;
    /* Long unbroken values (DSNs, URLs, paths) must wrap rather than
       overflow the row. */
    overflow-wrap: anywhere;
}

.rb-status--ok {
    background: var(--rb-positive-bg);
    border-left-color: var(--rb-positive-border);
}

.rb-status--ok .rb-status-label {
    color: var(--rb-positive-text);
}

.rb-status--warn {
    background: var(--rb-highlight-bg);
    border-left-color: var(--rb-highlight-border);
}

.rb-status--warn .rb-status-label {
    color: var(--rb-highlight-text);
}

.rb-status--fail {
    background: var(--rb-error-bg);
    border-left-color: var(--rb-error-border);
}

.rb-status--fail .rb-status-label {
    color: var(--rb-error-text);
}

/* Monospace detail for versions, paths and other machine values. */
.rb-mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    word-break: break-all;
}

/* --------------------------------------------------------------------------
   Attribute chips — used later for spec values ("Direct drive · 8Nm")
   -------------------------------------------------------------------------- */

.rb-chip {
    display: inline-block;
    padding: 2px 8px;
    margin: 0 4px 4px 0;
    font-size: 12px;
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    color: var(--rb-text-body);
}

.rb-chip--current {
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
    color: var(--rb-highlight-text);
    font-weight: 700;
}

/* --------------------------------------------------------------------------
   Buy button — the site's commerce green, both modes (design-tokens.md §8)
   -------------------------------------------------------------------------- */

.rb-buy {
    display: inline-block;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    background: var(--rb-buy-bg);
    background-image: var(--rb-buy-gradient);
    border: 1px solid var(--rb-buy-border);
    border-radius: var(--rb-radius);
    cursor: pointer;
    text-decoration: none;
}

.rb-buy:hover,
.rb-buy:visited {
    color: #fff;
}

.rb-buy:hover {
    background: var(--rb-buy-bg-hover);
    background-image: var(--rb-buy-gradient-hover);
}

.rb-buy,
.rb-buyButton {
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(0, 0, 0, 0.12);
}

.rb-buy:active,
.rb-buyButton:active {
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* --------------------------------------------------------------------------
   Page furniture
   -------------------------------------------------------------------------- */

.rb-pageTitle {
    margin: 0 0 4px;
    font-size: 22px;
    color: var(--rb-text-heading);
}

.rb-lede {
    margin: 0 0 20px;
    color: var(--rb-text-muted);
    font-size: 14px;
}

/* Category introductions are real reading text, not a caption. */
.rb-lede--intro {
    color: var(--rb-text-body);
}

.rb-categoryIntro {
    display: flex;
    align-items: flex-start;
    gap: 15px;
    margin: 8px 0 20px;
}

.rb-categoryIntro > .rb-category-icon {
    flex: 0 0 42px;
    width: 42px;
    height: 42px;
    color: var(--rb-brand-charcoal);
}

.dark .rb-categoryIntro > .rb-category-icon {
    color: var(--rb-text-muted);
}

.rb-categoryIntro > .rb-lede {
    min-width: 0;
    margin: 0;
    line-height: 1.5;
}

/* Phones: the shell runs edge to edge, so page-level titles and intros get side
   space. Ones inside a padded card (the product page, guide questions) keep theirs (§17.236). */
@media (max-width: 650px) {
    #primary > .rb-pageTitle,
    #primary > .rb-lede,
    #primary > .rb-categoryIntro {
        padding: 0 10px;
    }
}

/* Below the tablet breakpoint the category chips above already show the icon (§17.278). */
@media (max-width: 1000px) {
    .rb-categoryIntro > .rb-category-icon {
        display: none;
    }
}

/* --------------------------------------------------------------------------
   Notices — page-level messages above the blocks
   -------------------------------------------------------------------------- */

.rb-notice {
    padding: 8px 10px;
    margin-bottom: var(--rb-gap);
    border: 1px solid var(--rb-border-strong);
    border-left-width: 3px;
    border-radius: 0 var(--rb-radius) var(--rb-radius) 0;
    background: var(--rb-bg-subtle);
    color: var(--rb-text-body);
    font-size: 13px;
}

.rb-notice--ok {
    background: var(--rb-positive-bg);
    border-color: var(--rb-positive-border);
    color: var(--rb-positive-text);
}

.rb-notice--warn {
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
    color: var(--rb-highlight-text);
}

.rb-notice--error {
    background: var(--rb-error-bg);
    border-color: var(--rb-error-border);
    color: var(--rb-error-text);
}

.rb-notice a {
    color: inherit;
    text-decoration: underline;
}

/*
 * A link in running text is underlined, so it reads as a link in both modes:
 * color alone is too faint in dark mode (design-tokens.md, Links). Only
 * plain links: a link with a class of its own is a button, a tab, a card or
 * other UI, which styles itself.
 */
.rigbuilder #primary p a:not([class]) {
    text-decoration: underline;
    text-underline-offset: 2px;
}

.rb-block--error .rb-block-header--error {
    /* The one place the red gradient is replaced: a validation block must not
       look like a normal section header, or it reads as ordinary furniture. */
    background: var(--rb-error-border);
}

.rb-errorList {
    margin: 6px 0 0;
    padding-left: 20px;
    font-size: 13px;
}

.rb-errorList li {
    margin-bottom: 4px;
}

.rb-inlineError {
    color: var(--rb-error-text);
    font-size: 12px;
}

.rb-inlineOk {
    color: var(--rb-positive-text);
    font-size: 12px;
    font-weight: 600;
}

/* --------------------------------------------------------------------------
   Spec table — the registry-rendered product specifications (spec §11)
   -------------------------------------------------------------------------- */

.rb-specTable {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.rb-specTable th,
.rb-specTable td {
    padding: 6px 10px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--rb-border);
    color: var(--rb-text-body);
}

.rb-specTable tr:last-child th,
.rb-specTable tr:last-child td {
    border-bottom: 0;
}

.rb-specTable th {
    width: 42%;
    font-weight: 600;
}

.rb-specTable tbody tr:nth-child(even) {
    background: var(--rb-bg-subtle);
}

/* An unverified attribute is shown, not hidden — but it must not read with the
   same confidence as a measured one. */
.rb-specTable-empty td {
    color: var(--rb-text-muted);
    font-style: italic;
}

.rb-specTable--universal {
    margin-top: 0;
    border-top: 1px solid var(--rb-border);
}

.rb-specTable-note {
    margin: 10px 0 0;
    font-size: 12px;
    color: var(--rb-text-muted);
}

/* .rb-chips is laid out with the glossary tap-outs it contains, further down. */

/* --------------------------------------------------------------------------
   Product cards and the catalog listing
   -------------------------------------------------------------------------- */

.rb-productList {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rb-productCard {
    display: flex;
    gap: 12px;
    padding: 10px 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-productCard:first-child {
    padding-top: 0;
}

.rb-productCard:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.rb-productCard-media {
    flex: 0 0 90px;
}

/* The card shows the `medium` variant at card size (spec §17.9): one stored
   size serves every "the product" context, and the browser downscales. */
.rb-productCard-media img,
.rb-productCard-media .rb-imagePlaceholder {
    display: block;
    width: 90px;
    height: 90px;
    object-fit: contain;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-productCard-body {
    flex: 1 1 auto;
    min-width: 0;
}

.rb-productCard-title {
    margin: 0 0 2px;
    font-size: 15px;
    font-weight: 600;
    color: var(--rb-text-heading);
}

.rb-productCard-meta {
    margin: 0 0 4px;
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-productCard-oneLiner {
    margin: 0 0 6px;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-productHero {
    display: flex;
    gap: 16px;
    align-items: flex-start;
}

.rb-productHero-media {
    flex: 0 0 240px;
}

/* --------------------------------------------------------------------------
   Product gallery (spec §11)

   Primary image at `medium`, every other image as a `thumb` beneath it. Both
   link to the `original`, which the lightbox below intercepts.
   -------------------------------------------------------------------------- */

.rb-gallery-main,
.rb-gallery-thumb {
    display: block;
    border-radius: var(--rb-radius);
}

.rb-gallery-main img,
.rb-gallery-thumb img,
.rb-productHero-media .rb-imagePlaceholder {
    display: block;
    width: 100%;
    height: auto;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-gallery-main:hover img,
.rb-gallery-thumb:hover img {
    border-color: var(--rb-border-strong);
}

.rb-gallery-main:focus-visible img,
.rb-gallery-thumb:focus-visible img {
    outline: 2px solid var(--rb-accent-blue);
    outline-offset: 1px;
}

.rb-gallery-thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    list-style: none;
    margin: 6px 0 0;
    padding: 0;
}

.rb-gallery-thumbs li {
    flex: 0 0 auto;
}

.rb-gallery-thumb img {
    width: 90px;
    height: 90px;
    box-sizing: border-box;
    object-fit: contain;
}

.rb-productHero-body {
    flex: 1 1 auto;
    min-width: 0;
}

.rb-productHero-oneLiner {
    margin: 0 0 8px;
    font-size: 15px;
    font-weight: 600;
    color: var(--rb-text-heading);
}

.rb-categoryList {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    font-size: 14px;
}

.rb-categoryList li {
    display: flex;
    gap: 10px;
    padding: 4px 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-categoryList-count {
    margin-left: auto;
    color: var(--rb-text-muted);
    font-size: 13px;
}

.rb-metaList {
    list-style: none;
    margin: 0 0 10px;
    padding: 0;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-metaList li {
    margin-bottom: 3px;
}

/* --------------------------------------------------------------------------
   Data tables — admin listings (design-tokens.md §5)
   -------------------------------------------------------------------------- */

.rb-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-table th,
.rb-table td {
    padding: 5px 8px;
    text-align: left;
    vertical-align: top;
    border-bottom: 1px solid var(--rb-border);
}

.rb-table thead th {
    font-size: 12px;
    font-weight: 600;
    color: var(--rb-text-muted);
    border-bottom: 2px solid var(--rb-border-strong);
    white-space: nowrap;
}

.rb-table tbody tr:nth-child(even) {
    background: var(--rb-bg-subtle);
}

.rb-table-number {
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.rb-table-muted {
    color: var(--rb-text-muted);
}

/* Long URLs and JSON blobs must not force the table wider than the page. */
.rb-table-truncate {
    max-width: 320px;
    overflow-wrap: anywhere;
}

.rb-queueProduct {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    column-gap: 16px;
}

.rb-queueProduct-source {
    white-space: nowrap;
}

.rb-table--registry .rb-vocabulary {
    font-size: 11px;
    overflow-wrap: anywhere;
}

.rb-block-header-slug {
    font-weight: 400;
    opacity: 0.75;
    font-size: 13px;
}

/* --------------------------------------------------------------------------
   Admin navigation
   -------------------------------------------------------------------------- */

.rb-adminNav {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin: 0 0 var(--rb-gap);
}

.rb-adminNav-link {
    padding: 4px 12px;
    font-size: 13px;
    font-weight: 600;
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    color: var(--rb-text-link);
    text-decoration: none;
}

.rb-adminNav-link.is-current {
    background: var(--rb-brand-blue);
    border-color: var(--rb-brand-blue);
    color: #fff;
}

.dark .rb-adminNav-link.is-current {
    background: var(--rb-accent-blue);
    border-color: var(--rb-accent-blue);
    color: #fff;
}

/* --------------------------------------------------------------------------
   Forms — registry-generated controls and admin editing
   -------------------------------------------------------------------------- */

.rb-field {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    align-items: baseline;
    padding: 6px 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-field:last-child {
    border-bottom: 0;
}

.rb-field-label {
    flex: 0 0 200px;
    font-size: 13px;
    font-weight: 600;
    color: var(--rb-text-body);
}

.rb-field-required {
    color: var(--rb-error-text);
}

.rb-field-control {
    flex: 1 1 320px;
    min-width: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
}

.rb-field-help {
    flex: 1 0 100%;
    margin: 2px 0 0;
    font-size: 11px;
    color: var(--rb-text-muted);
}

/* A bundle's derived attribute (§17.86): shown from the components, never
   edited here, so it reads as a value rather than as a disabled control. */
.rb-field--derived .rb-derivedValue {
    font-size: 14px;
    color: var(--rb-text-muted);
}

/* One row of the "add a listing" form. A row is added under the last one as
   each URL is pasted (spec §14), so the row — not the field — is what lays a
   listing's controls out, and rows stack rather than running together. */
.rb-listingRow {
    flex: 1 0 100%;
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
}

.rb-listingRow + .rb-listingRow {
    margin-top: 6px;
}

.rb-field-unit {
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-input {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
    padding: 5px 7px;
    font-family: inherit;
    font-size: 14px;
    color: var(--rb-text-body);
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
}

.dark .rb-input {
    background: rgba(0, 0, 0, 0.5);
    border-color: #575757;
    color: #fff;
}

.dark .rb-input:focus {
    background: #000;
}

.rb-input--number {
    flex: 0 1 140px;
}

.rb-input--textarea {
    flex: 1 1 100%;
    resize: vertical;
    line-height: 1.45;
}

.rb-checkbox {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-radio {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 12px;
    color: var(--rb-text-body);
}

.rb-input--small {
    padding: 3px 5px;
    font-size: 12px;
}

/* A submit button that reads as a link: destructive row actions inside a form
   must be buttons, but a full button next to every image would shout. */
/* Delete, at the foot of the editor, for the owner only (§17.334). */
.rb-editorDelete { margin: 0; text-align: right; }

/* Save This Build and Reset, at the top of the editor and again at its foot,
   where Delete sits to their left (§17.339). */
.rb-editorActions { display: flex; flex-wrap: wrap; gap: 8px; margin-left: auto; }
.rb-editorFoot { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 10px 16px; margin: 16px 0 0; }
.rb-editorFoot .rb-editorDelete { order: -1; }
.rb-editorFoot .rb-editorActions { margin-left: 0; }

/* "Are you sure?" for Reset and Delete, the page's own box rather than the
   browser's, which some browsers never show (§17.343). */
.rb-confirm {
    width: min(420px, calc(100vw - 32px));
    padding: 18px 20px 16px;
    color: var(--rb-text-body);
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
}
.rb-confirm::backdrop { background: rgba(0, 0, 0, 0.45); }
.rb-confirm form { margin: 0; }
.rb-confirm-text { margin: 0 0 16px; font-size: 15px; line-height: 1.5; color: var(--rb-text-heading); }
.rb-confirm-actions { display: flex; justify-content: flex-end; gap: 8px; }

.rb-linkButton {
    padding: 0;
    font: inherit;
    font-size: 12px;
    color: var(--rb-text-link);
    background: none;
    border: 0;
    cursor: pointer;
    text-decoration: underline;
}

/* --------------------------------------------------------------------------
   Bundle contents picker — the component list in the review queue and the
   product workbench (spec §6, §17.12)

   The list is long by nature (it is the whole catalog), so it scrolls inside
   its own box: a bundle has three or four components, and the fields below it
   must stay reachable without paging past every product we sell.
   -------------------------------------------------------------------------- */

.rb-field--bundle .rb-field-control {
    display: block;
}

.rb-bundlePicker {
    max-height: 320px;
    overflow-y: auto;
    padding: 4px 8px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
}

.rb-bundlePicker-group {
    margin: 10px 0 2px;
    font-size: 14px;
    font-weight: 700;
    color: var(--rb-text-body);
}

.rb-bundlePicker-group:first-child {
    margin-top: 2px;
}

.rb-bundlePicker-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 2px 0;
}

.rb-bundlePicker-choice {
    flex: 1 1 auto;
    min-width: 0;
    align-items: flex-start;
}

.rb-bundlePicker-meta {
    color: var(--rb-text-muted);
    font-size: 12px;
}

.rb-bundlePicker-qty {
    flex: 0 0 60px;
    text-align: right;
}

/* Quantity only means something for a component that is actually in the
   bundle; showing it at full strength on every row reads as though every
   product has a quantity. */
.rb-bundlePicker-row:not(.rb-bundlePicker-row--on) .rb-bundlePicker-qty {
    opacity: 0.45;
}

/* --------------------------------------------------------------------------
   Bundle contents on a public product page (spec §6, §11)
   -------------------------------------------------------------------------- */

.rb-bundleList {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: 14px;
}

.rb-bundleList li {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-bundleList-image {
    flex: 0 0 64px;
}

.rb-bundleList-image img,
.rb-bundleList-image .rb-imagePlaceholder {
    display: block;
    width: 64px;
    height: 64px;
    box-sizing: border-box;
    object-fit: contain;
    background: #fff;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-bundleList-details {
    flex: 1;
    min-width: 0;
    overflow-wrap: anywhere;
}

.rb-bundleList li:last-child {
    border-bottom: 0;
}

.rb-bundleList-meta {
    display: block;
    margin: 4px 0 0;
    color: var(--rb-text-muted);
    font-size: 13px;
}

.rb-bundleList-qty {
    color: var(--rb-text-muted);
}

/* --------------------------------------------------------------------------
   Admin image grid — the staged gallery in the review queue and the image
   panel in the product workbench (spec §13.5, §17.9)
   -------------------------------------------------------------------------- */

.rb-imageGrid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--rb-gap);
    list-style: none;
    margin: var(--rb-gap) 0 0;
    padding: 0;
}

.rb-imageGrid-item {
    flex: 0 0 140px;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 8px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-imageGrid-item img {
    display: block;
    width: 120px;
    height: 120px;
    object-fit: contain;
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-imageGrid-meta {
    margin: 0;
    font-size: 11px;
    color: var(--rb-text-muted);
    overflow-wrap: anywhere;
}

/* --------------------------------------------------------------------------
   Lightbox (spec §11)

   Built by assets/rigbuilder.js; with JavaScript off, the gallery links simply
   navigate to the full-size image and none of this is used.

   The scrim is near-black in both themes: a photograph is judged against the
   surface behind it, and that surface should not change with the site theme.
   -------------------------------------------------------------------------- */

.rb-lightbox {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 20px;
    background: rgba(0, 0, 0, 0.88);
}

.rb-lightbox[hidden] {
    display: none;
}

.rb-lightbox-open,
.rb-lightbox-open body {
    overflow: hidden;
}

.rb-lightbox-figure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    margin: 0;
    min-width: 0;
}

.rb-lightbox-image {
    max-width: min(1100px, 88vw);
    max-height: 80vh;
    width: auto;
    height: auto;
    background: #fff;
    border-radius: var(--rb-radius);
}

.rb-lightbox-caption {
    max-width: 88vw;
    font-size: 13px;
    text-align: center;
    color: rgba(255, 255, 255, 0.8);
}

.rb-lightbox-close,
.rb-lightbox-nav {
    flex: 0 0 auto;
    padding: 4px 12px;
    font-family: inherit;
    font-size: 28px;
    line-height: 1.2;
    color: rgba(255, 255, 255, 0.75);
    background: rgba(255, 255, 255, 0.08);
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: var(--rb-radius);
    cursor: pointer;
}

.rb-lightbox-close:hover,
.rb-lightbox-nav:hover {
    color: #fff;
    background: rgba(255, 255, 255, 0.18);
}

.rb-lightbox-close {
    position: absolute;
    top: 12px;
    right: 12px;
    font-size: 22px;
}

.rb-lightbox-nav[hidden] {
    display: none;
}

.rb-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: var(--rb-gap) 0 0;
}

.rb-button {
    display: inline-block;
    box-sizing: border-box;
    padding: 6px 14px;
    font-family: inherit;
    font-size: 13px;
    font-weight: 600;
    line-height: 1.4;
    color: var(--rb-text-body);
    background: linear-gradient(180deg, #fff, #e7e7e7);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    text-decoration: none;
}

/* Every Rig Builder button shares the product page look: a soft gradient, a
   slight lift, and an inset shadow while pressed (§17.215). */
.rb-button:hover {
    background: linear-gradient(180deg, #fff, #dcdcdc);
    /* site-shell.css (from the theme's style.css) gives every button a light
       grey border on hover (`button:hover`). A hover here changes the
       background only, so each kind of button restates its own border below. */
    border-color: var(--rb-border-strong);
    text-decoration: none;
}

.rb-button:focus-visible {
    outline: 2px solid var(--rb-accent-blue);
    outline-offset: 3px;
}

.rb-button:active {
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25);
}

/* Buttons are sometimes anchors. The site's `a, a:visited` rule is (0,1,1),
   which outranks a bare button class (0,1,0), so a visited link-button would
   take the site's link blue instead of the button's own text color. Repeating
   the class alongside `:visited` matches that specificity and wins. */
.rb-button:visited {
    color: var(--rb-text-body);
}

.dark .rb-button,
.dark .rb-button:visited {
    color: #fff;
    background: linear-gradient(180deg, #626262, #494949);
    border-color: #575757;
}

.dark .rb-button:hover {
    color: #fff;
    background: linear-gradient(180deg, #707070, #555);
    border-color: #575757;
}

/* Primary is the commerce/confirm action; it uses the site's button blue, not
   the buy green — the buy green is reserved for actual purchase links. */
.rb-button--primary,
.rb-button--primary:visited,
.dark .rb-button--primary,
.dark .rb-button--primary:visited {
    color: #fff;
    background: linear-gradient(180deg, var(--rb-accent-blue), var(--rb-brand-blue));
    border-color: var(--rb-brand-blue);
}

.rb-button--primary:hover,
.dark .rb-button--primary:hover {
    color: #fff;
    background: linear-gradient(180deg, #1681cb, #08629f);
    border-color: var(--rb-brand-blue);
}

/* The product page's action size, for a page's main call to action. */
.rb-button--large {
    min-height: 44px;
    padding: 10px 18px;
    font-size: 15px;
}

.rb-button--danger {
    color: var(--rb-error-text);
    border-color: var(--rb-error-border);
}

.rb-button--danger:hover,
.dark .rb-button--danger:hover {
    border-color: var(--rb-error-border);
}

/* --------------------------------------------------------------------------
   Review queue — proposed fields beside the scraped source (spec §13.5)
   -------------------------------------------------------------------------- */

.rb-review {
    display: flex;
    gap: var(--rb-gap);
    align-items: flex-start;
}

.rb-review-form {
    flex: 1 1 58%;
    min-width: 0;
}

.rb-review-source {
    flex: 1 1 42%;
    min-width: 0;
    position: sticky;
    /* Clears the site's sticky nav (design-tokens.md §9). */
    top: 100px;
}

.rb-source summary {
    cursor: pointer;
    font-size: 13px;
    font-weight: 600;
    padding: 4px 0;
    color: var(--rb-text-link);
}

.rb-source-text {
    max-height: 460px;
    overflow: auto;
    margin: 4px 0 0;
    padding: 8px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 11px;
    line-height: 1.45;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    color: var(--rb-text-body);
}

.rb-queueSummary {
    margin: 0 0 8px;
}

/* The summary chips are the queue's filter: each one shows that status's
   jobs. A status colour carries meaning (below), so the selected chip keeps
   its colour and is marked by weight and a ring in that colour instead of
   the cream-gold "current" treatment. Both modes: the ring is currentColor. */
.rb-queueSummary a.rb-chip {
    text-decoration: none;
}

.rb-queueSummary a.rb-chip:hover,
.rb-queueSummary a.rb-chip:focus-visible {
    text-decoration: underline;
}

.rb-queueSummary a.rb-chip[aria-current] {
    font-weight: 700;
    outline: 2px solid currentColor;
    outline-offset: 1px;
}

/* Row actions read as one line: ingesting a job, reviewing its draft and
   opening the product it became are three doors into the same row, not a
   stack. The form wrapper exists only because a POST cannot be an <a>. */
.rb-table-actions {
    white-space: nowrap;
}

.rb-table-actions form {
    display: inline;
}

.rb-table-actions > * + a {
    margin-left: 8px;
}

/* A scrape and an LLM call take tens of seconds, and the one thing that must
   not happen in that time is a second click spending them again. */
.rb-table-actions button[disabled] {
    color: var(--rb-text-muted);
    text-decoration: none;
    cursor: default;
}

/* Status chips carry meaning, so they carry colour: what needs a human is
   warm, what failed is red, what is finished is green. */
.rb-chip--pending,
.rb-chip--normalized,
.rb-chip--draft {
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
    color: var(--rb-highlight-text);
}

.rb-chip--failed,
.rb-chip--rejected {
    background: var(--rb-error-bg);
    border-color: var(--rb-error-border);
    color: var(--rb-error-text);
}

.rb-chip--approved,
.rb-chip--active {
    background: var(--rb-positive-bg);
    border-color: var(--rb-positive-border);
    color: var(--rb-positive-text);
}

/* --------------------------------------------------------------------------
   Compatibility (spec §5, §11)

   Four statuses, and the colour has to carry the difference between the two
   negatives: "checked, does not fit" is a fact about the products, while "not
   verified" is a gap in our data. Red for the first, plain grey for the second
   — an unverified pair styled as a failure would be us blaming the hardware
   for our own missing homework.
   -------------------------------------------------------------------------- */

/* A connection's answer is coloured text. Only the build's own state is a
   badge, so it stands out among them (§17.485). */
.rb-compatChip {
    display: inline-block;
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--rb-text-body);
}

.rb-compatChip--native { color: var(--rb-positive-text); }
.rb-compatChip--with-adapter,
.rb-compatChip--pc-only { color: var(--rb-highlight-text); }
.rb-compatChip--incompatible { color: var(--rb-error-text); }
.rb-compatChip--unknown { font-weight: 400; color: var(--rb-text-muted); }

.rb-compatChip + .rb-compatChip {
    margin-left: 8px;
}

.rb-stateChip {
    padding: 1px 7px;
    font-size: 11px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
}
.rb-stateChip.rb-compatChip--native { background: var(--rb-positive-bg); border-color: var(--rb-positive-border); }
.rb-stateChip.rb-compatChip--incompatible { background: var(--rb-error-bg); border-color: var(--rb-error-border); }
.rb-stateChip.rb-compatChip--unknown { font-weight: 600; }

/* Each category is a closed <details> (spec §11): the summary carries the
   counts, so a category is opened on purpose rather than scrolled past. */
.rb-compatGroup {
    margin: 0 0 4px;
    border-bottom: 1px solid var(--rb-border);
}

.rb-compatGroup:last-child {
    border-bottom: 0;
}

.rb-compatGroup-title {
    margin: 0;
    padding: 8px 0;
    cursor: pointer;
    font-size: 14px;
    font-weight: 600;
    color: var(--rb-text-heading);
}

.rb-compatGroup[open] > .rb-compatGroup-title {
    margin-bottom: 4px;
}

.rb-compatGroup > .rb-compatList,
.rb-compatGroup > .rb-compatGroup-empty,
.rb-compatGroup > .rb-compatMore {
    margin-bottom: 10px;
}

.rb-compatGroup-empty {
    margin: 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-compatGroup-count {
    margin-left: 6px;
    font-weight: 400;
    color: var(--rb-text-muted);
}

.rb-compatList {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-compatList-item {
    padding: 5px 0;
    border-bottom: 1px solid var(--rb-border);
    font-size: 14px;
}

.rb-compatList-item:last-child {
    border-bottom: 0;
}

.rb-compatList-name {
    margin-right: 6px;
}

/* The note is the sentence a reader acts on ("connects through the base pedal
   port"), so it gets its own line rather than trailing off the end of one. */
.rb-compatList-detail {
    display: block;
    margin-top: 2px;
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-compatMore {
    margin-top: 6px;
}

.rb-compatMore summary {
    cursor: pointer;
    font-size: 12px;
    color: var(--rb-text-link);
}

/* --------------------------------------------------------------------------
   Compatibility admin — the diff preview and the rule authoring surface
   -------------------------------------------------------------------------- */

/* The preview is the safety mechanism (§5.3), so it is the loudest thing on
   the page once it appears. */
.rb-block--preview {
    border: 2px solid var(--rb-highlight-border);
    border-radius: var(--rb-radius);
}

.rb-subHeader {
    margin: 18px 0 6px;
    font-size: 14px;
    color: var(--rb-text-heading);
}

.rb-input--code {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 12px;
    line-height: 1.5;
    white-space: pre;
    overflow-wrap: normal;
    overflow-x: auto;
}

.rb-table-alarm {
    color: var(--rb-error-text);
    font-weight: 700;
}

.rb-table-inactive {
    opacity: 0.55;
}

.rb-vocabularyRef {
    max-height: 320px;
    overflow: auto;
    padding: 8px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-vocabularyRef-title {
    margin: 10px 0 4px;
    font-size: 13px;
    color: var(--rb-text-heading);
}

.rb-vocabularyRef-title:first-child {
    margin-top: 0;
}

.rb-vocabularyRef-list {
    margin: 0;
    padding: 0 0 0 4px;
    list-style: none;
    font-size: 12px;
}

.rb-vocabularyRef-list li {
    padding: 1px 0;
}

/* --------------------------------------------------------------------------
   Builds — the editor, the tray and the share panel (spec §7, §9)

   Two columns on desktop: the build on the left, what it adds up to on the
   right. The right column is sticky, because the tray is the thing a reader
   keeps glancing at while they change the thing on the left — and it stops
   being sticky on mobile, where a panel that follows you up a one-column page
   is just a panel in the way.
   -------------------------------------------------------------------------- */

/* --- the parts list ------------------------------------------------------ */

.rb-buildParts,
.rb-buildParts-items {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-buildParts-slot {
    padding: var(--rb-pad-block) 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-buildParts-slot:first-child {
    padding-top: 0;
}

.rb-buildParts-slot:last-child {
    border-bottom: 0;
    padding-bottom: 0;
}

/* A category holding more of something than a build may is the one thing in
   this list that is an error, so it is the one thing that is coloured. */
.rb-buildParts-slot--over {
    background: var(--rb-error-bg);
    border-left: 3px solid var(--rb-error-border);
    padding-left: 8px;
}

.rb-buildParts-category {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 700;
    color: var(--rb-text-body);
}

/* "needed" is a to-do, not a fault: it uses the selected/current cream, not
   the error red (design-tokens.md §8). */
.rb-buildParts-needed {
    padding: 1px 5px;
    font-size: 10px;
    font-weight: 700;
    text-transform: none;
    letter-spacing: 0;
    color: var(--rb-highlight-text);
    background: var(--rb-highlight-bg);
    border: 1px solid var(--rb-highlight-border);
    border-radius: var(--rb-radius);
}

.rb-buildParts-empty {
    margin: 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-buildParts-item {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 4px 8px;
    padding: 3px 0;
}

.rb-buildParts-name {
    font-weight: 600;
    font-size: 14px;
}

.rb-buildParts-meta {
    flex: 1 1 100%;
    font-size: 11px;
    color: var(--rb-text-muted);
}

.rb-buildParts-remove {
    margin-left: auto;
    font-size: 12px;
}

/* --- what is wrong, missing, or merely worth knowing --------------------- */

.rb-buildNotes {
    margin: 0 0 var(--rb-gap);
    padding: 8px 10px;
    border-radius: var(--rb-radius);
    border: 1px solid transparent;
    border-left-width: 3px;
}

.rb-buildNotes:last-child {
    margin-bottom: 0;
}

.rb-buildNotes-title {
    margin: 0 0 4px;
    font-size: 13px;
    font-weight: 700;
}

.rb-buildNotes ul {
    margin: 0;
    padding-left: 18px;
    font-size: 13px;
}

/* The three tones are the three kinds of news, and they must not be confused:
   red is "this will not work", cream is "you have not finished", grey is
   "here is something you should know". An unverified pair is NEVER red — it is
   a gap in our data, not a fault in the reader's build (§5.1). */
.rb-buildNotes--error {
    background: var(--rb-error-bg);
    border-color: var(--rb-error-border);
    color: var(--rb-error-text);
}

.rb-buildNotes--todo {
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
    color: var(--rb-highlight-text);
}

.rb-buildNotes--warn {
    background: var(--rb-bg-subtle);
    border-color: var(--rb-border-strong);
}

/* The parts that answer a "Still to Choose" line, under it or in the editor's
   next-step banner (§17.372): a white card per part, with its Add button. */
.rb-buildFix { margin: 6px 0 2px; font-size: 13px; }
.rb-buildFix-label { margin: 0 0 4px; font-weight: 700; }
.rb-buildNotes ul.rb-buildFix-list,
.rb-buildFix-list { display: grid; gap: 6px; margin: 0 0 6px; padding: 0; list-style: none; }
.rb-buildFix-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 12px;
    padding: 6px 10px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
    color: var(--rb-text-body);
}
.rb-buildFix-item a { font-weight: 600; }
.rb-buildFix-add { margin: 0; }
.rb-buildFix-browse { font-weight: 600; }

/* --- the picker ---------------------------------------------------------- */

.rb-picker {
    margin-top: 6px;
    font-size: 13px;
}

.rb-picker > summary {
    cursor: pointer;
    color: var(--rb-text-link);
}

/* --- ownership, sharing and the list of saved builds --------------------- */

.rb-buildActions {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: var(--rb-gap);
}

.rb-buildActions--top {
    margin: 0 0 var(--rb-gap);
}

.rb-buildActions .rb-button {
    display: inline-block;
    text-decoration: none;
}

.rb-productBuildActions .rb-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    padding: 10px 18px;
    font-size: 15px;
    line-height: 1.4;
}

.rb-productBuildActions .rb-button svg {
    flex: 0 0 20px;
}

.rb-buildAttribution {
    margin: 0 0 var(--rb-gap);
    font-size: 13px;
}


/* A read-only field that exists to be copied out: it should look like a value,
   not like something to type into. */
.rb-input--copyable {
    font-size: 12px;
    cursor: pointer;
}


.rb-inlineForm {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: center;
}

.rb-inlineForm .rb-input {
    flex: 1 1 240px;
}

/* Editing a listing's URL in place (§17.525): closed, it is one small link
   under the shop's name; open, the form takes the row's full width. */
.rb-listingEdit > summary {
    display: inline;
    font-size: 12px;
    color: var(--rb-text-muted);
    cursor: pointer;
}

.rb-listingEdit[open] {
    min-width: 420px;
    margin-top: 6px;
}

.rb-listingEdit .rb-inlineForm {
    margin-top: 6px;
}

.rb-inlineForm .rb-listingEdit-sku {
    flex: 0 1 120px;
}

@media (max-width: 650px) {
    .rb-listingEdit[open] { min-width: 0; }
}

/* The admin list filter bar: three selects and a button in one row, a label
   above each select so the row reads on its own without placeholders. */
.rb-filterBar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 8px 14px;
    margin: 0 0 var(--rb-gap);
    padding: 0 0 var(--rb-gap);
    border-bottom: 1px solid var(--rb-border);
}

.rb-filterBar-field {
    display: flex;
    flex-direction: column;
    gap: 3px;
    flex: 1 1 180px;
    max-width: 280px;
}

.rb-filterBar-field .rb-input {
    width: 100%;
}

.rb-filterBar-label {
    font-size: 12px;
    font-weight: 600;
    color: var(--rb-text-muted);
}

.rb-filterBar-actions {
    display: flex;
    align-items: center;
    gap: 10px;
}

.rb-filterBar-clear {
    font-size: 13px;
}

/* With the script running, every change submits, so the button is only the
   no-script path and is hidden once the script has claimed the form. */
.rb-filterBar.is-autosubmit .rb-button {
    display: none;
}

/* My Rigs (§17.345): one row per build, with a photo of its first part, its
   name, parts and date, the build page's state chip, and its total. The build
   this browser is working on is tinted like the sidebar's current page. */
.rb-buildsHead,
.rb-pageHead {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin: 0 0 var(--rb-gap);
}

.rb-buildsHead .rb-pageTitle,
.rb-pageHead .rb-pageTitle {
    margin: 0;
}

.rb-buildsHead form {
    margin: 0;
}

.rb-buildList-none {
    margin: 0;
}

/* Rows run to the block's edges so the current row's tint fills its width. */
.rb-buildLists {
    margin: -10px;
}

.rb-buildList {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-buildList-item {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr) auto;
    align-items: center;
    gap: 6px 12px;
    padding: 10px;
    border-bottom: 1px solid var(--rb-border);
}

.rb-buildList > .rb-buildList-item:last-child {
    border-bottom: 0;
}

.rb-buildList-item.is-current {
    background: var(--rb-nav-current-bg);
    box-shadow: inset 3px 0 0 var(--rb-accent-blue);
}

.rb-buildList-thumb {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    width: 64px;
    height: 64px;
    padding: 4px;
    overflow: hidden;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: #fff;
}

.rb-buildList-thumb img {
    display: block;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.rb-buildList-thumb--icon {
    background: var(--rb-bg-subtle);
    color: var(--rb-text-muted);
}

.rb-buildList-thumb--icon .rb-category-icon {
    width: 30px;
    height: 30px;
}

.rb-buildList-main {
    display: flex;
    flex-direction: column;
    gap: 3px;
    min-width: 0;
}

.rb-buildList-main > p {
    margin: 0;
}

.rb-buildList-heading {
    line-height: 1.35;
}

.rb-buildList-name {
    font-size: 15px;
    font-weight: 600;
    overflow-wrap: anywhere;
}

.rb-buildList-tag {
    display: inline-block;
    margin-left: 4px;
    padding: 0 6px;
    border-radius: 3px;
    background: var(--rb-accent-blue);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    line-height: 1.7;
    white-space: nowrap;
    vertical-align: 2px;
}

.rb-buildList-meta {
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-buildList-facts {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 8px;
    font-size: 12px;
}

.rb-buildList-price strong {
    font-size: 14px;
}

.rb-buildList-edit {
    text-decoration: none;
    white-space: nowrap;
}

/* Empty builds fold into one closed group at the foot of the list. */
.rb-buildList-empties {
    border-top: 1px solid var(--rb-border);
}

.rb-buildLists > .rb-buildList-empties:first-child {
    border-top: 0;
}

.rb-buildList-empties > summary {
    padding: 8px 10px;
    font-size: 12px;
    font-weight: 600;
    color: var(--rb-text-muted);
    cursor: pointer;
}

.rb-buildList-empties[open] > summary {
    border-bottom: 1px solid var(--rb-border);
}

.rb-buildList-empties .rb-buildList-item {
    grid-template-columns: 40px minmax(0, 1fr) auto;
    padding-block: 6px;
}

.rb-buildList-empties .rb-buildList-thumb {
    width: 40px;
    height: 40px;
}

.rb-buildList-empties .rb-buildList-thumb--icon .rb-category-icon {
    width: 22px;
    height: 22px;
}

.rb-block-body > .rb-buildList-note {
    margin: 10px 0 0;
    padding-top: 10px;
    border-top: 1px solid var(--rb-border);
    font-size: 11px;
    color: var(--rb-text-muted);
}

@media (max-width: 650px) {
    .rb-buildsHead {
        padding: 0 10px;
    }

    .rb-buildList-item {
        grid-template-columns: 56px minmax(0, 1fr);
        align-items: start;
    }

    .rb-buildList-empties .rb-buildList-item {
        grid-template-columns: 40px minmax(0, 1fr) auto;
        align-items: center;
    }

    .rb-buildList-thumb {
        width: 56px;
        height: 56px;
    }

    .rb-buildList > .rb-buildList-item > .rb-buildList-edit {
        grid-column: 2;
        justify-self: start;
    }

    .rb-buildList-empties .rb-buildList-item > .rb-buildList-edit {
        grid-column: 3;
    }
}

/* --------------------------------------------------------------------------
   Prices, codes and buy actions (spec §10)

   The buy green (design-tokens.md §8) exists specifically for commerce
   actions and is used for nothing else — a page where every button is green
   is a page where none of them mean "this is where you spend money".

   The savings language uses the site's established "positive" family, which
   is what reactions and other good news already look like on GTPlanet.
   -------------------------------------------------------------------------- */

.rb-pricePanel {
    display: flex;
    flex-direction: column;
    gap: 8px;
}

.rb-priceRow {
    display: grid;
    grid-template-columns: 1fr auto auto;
    align-items: center;
    gap: 4px 12px;
    padding: 8px 10px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

/* The best price gets the site's selected/current treatment (design-tokens.md
   §8) rather than a green of its own: it is the row we are recommending, not
   a second buy button. */
.rb-priceRow--best {
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
}

.rb-priceRow-store {
    font-weight: 600;
    font-size: 14px;
}

.rb-priceRow-flag {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--rb-highlight-text);
}

.rb-priceRow-price {
    font-size: 15px;
    white-space: nowrap;
}

.rb-priceRow-note {
    grid-column: 1 / -1;
    margin: 0;
    font-size: 11px;
    color: var(--rb-text-muted);
}

.rb-priceRow-action {
    grid-row: 1;
    grid-column: 3;
}

/* A shop's regional price sits under its US row, visibly subordinate: the US
   row is the base every history and recommendation is measured against
   (§17.75), and the region rows are the same shop in another currency. */
.rb-priceRow--region {
    margin-left: 14px;
    padding-top: 6px;
    padding-bottom: 6px;
    border-style: dashed;
}

.rb-priceRow--region .rb-priceRow-price {
    font-size: 14px;
}

.rb-priceRow--regionOnly {
    border-bottom: 0;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    padding-bottom: 2px;
}

.rb-priceRow-regionName {
    font-weight: 600;
    font-size: 13px;
}

.rb-price {
    font-weight: 600;
}

/* The pre-code price stays visible beside the discounted one. §10.2 forbids
   presenting the discounted figure as THE price, and showing what the shop
   charges next to what you pay is the plainest way to keep that true. */
.rb-price--was {
    font-weight: 400;
    color: var(--rb-text-muted);
    text-decoration: line-through;
}

.rb-price--coded {
    color: var(--rb-positive-text);
}

/* Coloured text beside the price: "with code" in the code green, "on sale"
   muted (§17.484, §17.485). */
.rb-price-qualifier {
    font-size: 12px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--rb-positive-text);
}

.rb-price--sale .rb-price-qualifier {
    font-weight: 400;
    color: var(--rb-text-muted);
}

.rb-price--none {
    color: var(--rb-text-muted);
}

.rb-priceEmpty,
.rb-priceHonesty {
    margin: 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-priceHonesty {
    margin-top: 8px;
    padding: 6px 10px;
    background: var(--rb-bg-subtle);
    border-left: 3px solid var(--rb-accent-blue);
    border-radius: var(--rb-radius);
    color: var(--rb-text-body);
}

/*
 * "Check price at Amazon" (§17.466, §17.467). A quiet link under the priced
 * offers, never a button: it points somewhere, it does not recommend.
 */
.rb-priceAlso {
    margin: 8px 0 0;
    font-size: 14px;
    color: var(--rb-text-muted);
}

.rb-priceAlso-link,
.rb-priceAlso-link:visited {
    color: var(--rb-text-link);
    font-weight: 600;
    text-decoration: none;
}

.rb-priceAlso-link:hover,
.rb-priceAlso-link:focus-visible {
    text-decoration: underline;
}

.rb-priceAlso-link::after {
    content: '';
    display: inline-block;
    width: 12px;
    height: 12px;
    margin-left: 4px;
    vertical-align: -1px;
    background: currentColor;
    -webkit-mask: url('external-link.svg?v=1') center / contain no-repeat;
    mask: url('external-link.svg?v=1') center / contain no-repeat;
}

.dark .rb-priceAlso-link,
.dark .rb-priceAlso-link:visited {
    color: rgba(255, 255, 255, 0.75);
}

.dark .rb-priceAlso-link:hover,
.dark .rb-priceAlso-link:focus-visible {
    color: rgba(255, 255, 255, 0.9);
}

.rb-codeBadge {
    display: inline-block;
    padding: 2px 8px;
    font-size: 12px;
    font-weight: 600;
    color: var(--rb-positive-text);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}

.rb-productCode {
    margin: 0 0 var(--rb-gap);
}

.rb-buyButton {
    display: inline-block;
    padding: 6px 14px;
    font-size: 13px;
    font-weight: 600;
    color: #fff;
    background: var(--rb-buy-bg);
    background-image: var(--rb-buy-gradient);
    border: 1px solid var(--rb-buy-border);
    border-radius: var(--rb-radius);
    text-decoration: none;
    white-space: nowrap;
}

.rb-buyButton::after {
    content: '';
    display: inline-block;
    width: 14px;
    height: 14px;
    margin-left: 7px;
    vertical-align: -2px;
    background: currentColor;
    -webkit-mask: url('external-link.svg?v=1') center / contain no-repeat;
    mask: url('external-link.svg?v=1') center / contain no-repeat;
}

/* The shared site's visited-link color must not replace button text. */
.rb-buyButton:visited {
    color: #fff;
    text-decoration: none;
}

/* Override the shared dark theme's translucent link color. */
.dark .rb-buyButton,
.dark .rb-buyButton:visited {
    color: #fff;
}

.rb-buyButton:hover,
.rb-buyButton:focus {
    background: var(--rb-buy-bg-hover);
    background-image: var(--rb-buy-gradient-hover);
    color: #fff;
    text-decoration: none;
}

.rb-priceLine {
    margin: 6px 0 0;
    font-size: 14px;
}

.rb-priceLine-store {
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-priceLine-saving {
    font-size: 12px;
    font-weight: 600;
    color: var(--rb-positive-text);
}

/* Hotlinked retailer imagery: served from their CDN, never ours (§17.16), and
   without stored dimensions, so the box is reserved by aspect-ratio rather
   than by width/height attributes. */
.rb-gallery--remote .rb-gallery-main img,
.rb-gallery--remote .rb-gallery-thumb img {
    width: 100%;
    height: auto;
    aspect-ratio: 1 / 1;
    object-fit: contain;
}

.rb-gallery--remote .rb-gallery-thumb img {
    width: 90px;
    height: 90px;
}

.rb-gallery-credit {
    margin: 4px 0 0;
    font-size: 11px;
    color: var(--rb-text-muted);
}

.rb-bundleCompare {
    margin: var(--rb-gap) 0 0;
    font-size: 13px;
}

.rb-bundleCompare--saves {
    padding: 6px 10px;
    color: var(--rb-positive-text);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}

/* --------------------------------------------------------------------------
   Build summary: one group per shop (spec §10.3)
   -------------------------------------------------------------------------- */

.rb-storeGroups {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* One store (§17.295): a header with the store, what it holds, its code and
   its subtotal, then one row per item, each with its own buy button to that
   product's page at the store (§17.296). */
.rb-storeGroup {
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    overflow: hidden;
}

.rb-storeGroup-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 6px 16px;
    padding: 10px 14px;
    background: var(--rb-bg-subtle);
    border-bottom: 1px solid var(--rb-border);
}

.rb-storeGroup-title { margin: 0; font-size: 16px; font-weight: 700; }
.rb-storeGroup-sub { margin: 2px 0 0; font-size: 13px; color: var(--rb-text-muted); }
.rb-storeGroup-sub .rb-codeBadge { vertical-align: 1px; }
.rb-storeGroup-saving { font-weight: 600; color: var(--rb-positive-text); }
.rb-storeGroup-subtotal { margin: 0; font-size: 17px; font-weight: 700; white-space: nowrap; }
.rb-storeGroup-subtotalLabel { margin-right: 4px; font-size: 14px; font-weight: 400; color: var(--rb-text-muted); }

.rb-storeGroup-lines {
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-storeGroup-line {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto auto;
    align-items: center;
    gap: 12px;
    padding: 8px 14px;
    border-bottom: 1px solid var(--rb-border);
}

.rb-storeGroup-line:last-child { border-bottom: 0; }

.rb-storeGroup-image {
    display: block;
    width: 44px;
    height: 44px;
    padding: 3px;
    background: #fff;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-storeGroup-image img,
.rb-storeGroup-image .rb-imagePlaceholder { display: block; width: 100%; height: 100%; object-fit: contain; }

.rb-storeGroup-item { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rb-storeGroup-name { font-size: 15px; font-weight: 600; line-height: 1.3; }
.rb-storeGroup-type { font-size: 12px; color: var(--rb-text-muted); }

.rb-storeGroup-price { font-size: 15px; text-align: right; white-space: nowrap; }
.rb-storeGroup-price .rb-price { font-weight: 700; }
.rb-storeGroup-price .rb-price--was { font-size: 12px; font-weight: 400; }
.rb-storeGroup-each { font-size: 12px; color: var(--rb-text-muted); }

.rb-storeGroup-buy { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; }

/* "✓ Opened" under a buy button the reader has already used (§17.297). */
.rb-storeGroup-opened { font-size: 12px; font-weight: 600; white-space: nowrap; color: var(--rb-positive-text); }

/* The grand total under the stores, like a receipt's (§17.328): right
   aligned with the stores' subtotals (the same border and padding), the
   price with codes largest, the retail total and the saving under it (the
   savings callout, not the sale chip, §17.248), then what it covers. */
.rb-costTotal {
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: 4px;
    margin: 12px 0 0;
    padding: 12px 14px;
    text-align: right;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
}

.rb-costTotal p { margin: 0; }
.rb-costTotal-line { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: flex-end; gap: 4px 10px; }
.rb-costTotal-label { font-size: 14px; font-weight: 400; color: var(--rb-text-muted); }
.rb-costTotal-amount { font-size: 26px; font-weight: 700; line-height: 1.2; color: var(--rb-text-heading); }
.rb-costTotal-savings { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 4px 10px; }
.rb-costTotal-retail { font-size: 14px; color: var(--rb-text-muted); }
.rb-costTotal-saving {
    display: inline-block;
    padding: 2px 8px;
    font-size: 14px;
    font-weight: 700;
    color: var(--rb-positive-text);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}
.rb-costTotal-detail { font-size: 13px; color: var(--rb-text-muted); }
.rb-costTotal-note { font-size: 12px; color: var(--rb-text-muted); }
/* Above the stores, under the region picker (§17.468). */
.rb-costDisclaimer {
    margin: 0 0 12px;
    font-size: 13px;
    line-height: 1.5;
    color: var(--rb-text-muted);
}
.rb-costDisclaimer strong { color: var(--rb-text-body); }

@media (max-width: 650px) {
    /* The name takes the full width; the price and the buy button share
       the line under it. */
    .rb-storeGroup-line { grid-template-columns: 36px minmax(0, 1fr) auto; gap: 4px 10px; }
    .rb-storeGroup-image { grid-row: span 2; width: 36px; height: 36px; }
    .rb-storeGroup-item { grid-column: 2 / -1; }
    .rb-storeGroup-price { grid-column: 2; text-align: left; white-space: normal; }
    .rb-storeGroup-buy { grid-column: 3; }
    .rb-costTotal-amount { font-size: 22px; }
}

/* The region selector on the cost view (§17.75). Hidden markup until the
   script that makes it do anything unhides it. */
.rb-regionCost-picker {
    margin: 0 0 10px;
    font-size: 13px;
}

.rb-regionCost-picker select {
    margin-left: 4px;
}

/* Parts a selected region cannot buy locally: shown at the US price, kept
   apart so the two currencies never look like one basket. */
.rb-storeGroup--fallback {
    border-style: dashed;
}

.rb-buildTotal-note {
    margin: 4px 0 0;
    font-size: 11px;
    color: var(--rb-text-muted);
}

/* --------------------------------------------------------------------------
   The bundle-swap deal (spec §6.1)

   The one panel on the site that offers the reader something they did not ask
   for, so it uses the positive/savings family and says the arithmetic out
   loud rather than shouting.
   -------------------------------------------------------------------------- */

.rb-deal {
    margin: 0 0 var(--rb-gap);
    padding: var(--rb-pad-block);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}

.rb-deal-title {
    margin: 0 0 6px;
    font-weight: 700;
    color: var(--rb-positive-text);
}

.rb-deal-parts {
    margin: 0 0 6px;
    padding-left: 18px;
    font-size: 13px;
}

.rb-deal-price {
    color: var(--rb-text-muted);
}

.rb-deal-math {
    margin: 0 0 8px;
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-deal-form,
.rb-deal-link {
    margin: 0;
}

/* --------------------------------------------------------------------------
   The copy-code modal (spec §10.4)

   A branding moment, not a bare popup: the instant GTPlanet saves somebody
   money. It is also pure enhancement — with JavaScript off the buy link goes
   straight to the shop and the code is legible in the panel behind it.
   -------------------------------------------------------------------------- */

.rb-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, 0.75);
}

.rb-modal[hidden] {
    display: none;
}

.rb-modal-open,
.rb-modal-open body {
    overflow: hidden;
}

.rb-modal-panel {
    position: relative;
    width: 100%;
    max-width: 420px;
    padding: 24px;
    text-align: center;
    background: var(--rb-bg-card);
    color: var(--rb-text-body);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-modal-close {
    position: absolute;
    top: 4px;
    right: 8px;
    padding: 4px 8px;
    font-size: 22px;
    line-height: 1;
    color: var(--rb-text-muted);
    background: none;
    border: 0;
    cursor: pointer;
}

.rb-modal-eyebrow {
    margin: 0;
    font-size: 15px;
    font-weight: 700;
    color: var(--rb-text-body);
}

.rb-modal-code {
    margin: 6px 0 10px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 30px;
    font-weight: 700;
    letter-spacing: 0.06em;
    color: var(--rb-positive-text);
    word-break: break-all;
}

.rb-modal-code [data-rb-modal-code] {
    display: inline-block;
    max-width: 100%;
    padding: 2px 6px;
    border: 1px dashed currentColor;
    border-radius: var(--rb-radius);
}

.rb-modal-copy {
    min-width: 110px;
    white-space: nowrap;
}

.rb-modal-math {
    margin: 12px 0;
    font-size: 14px;
}

.rb-modal-go {
    margin: 0 0 12px;
}

.rb-modal-go .rb-buyButton {
    display: block;
    padding: 10px 14px;
    font-size: 15px;
}

.rb-modal-go .rb-buyButton::after {
    content: none;
}

.rb-modal-fineprint {
    margin: 0;
    font-size: 11px;
    color: var(--rb-text-muted);
}

/* --------------------------------------------------------------------------
   The guided wizard — questionnaire (spec §8.1)
   -------------------------------------------------------------------------- */

.rb-wizardProgress {
    margin: 0 0 var(--rb-gap);
}

.rb-wizardProgress-label {
    margin: 0 0 4px;
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-wizardProgress-track {
    height: 4px;
    border-radius: 2px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    overflow: hidden;
}

.rb-wizardProgress-bar {
    height: 100%;
    background: var(--rb-accent-blue);
    transition: width 0.2s ease;
}

.rb-wizardChoices {
    display: flex;
    flex-wrap: wrap;
    gap: var(--rb-gap);
    margin: var(--rb-gap) 0 0;
}

/*
 * The platforms sit in three columns or one, the four price ranges (and
 * the four wheel shapes) in four, two, or one, and a yes-or-no pair in two
 * or one: never a row with a lone card stretched across it. What
 * decides it is the room the question has, not the window, since the sidebar
 * comes and goes: hence a container query on a wrapper (an element cannot
 * query its own width). The breakpoints come from the widest card: "Almost
 * everything works on PC." needs about 230px, "$1,000 to $2,000" about 180px.
 */
.rb-wizardChoicesBox {
    container-type: inline-size;
}

.rb-wizardChoices--platform,
.rb-wizardChoices--price,
.rb-wizardChoices--pair {
    display: grid;
    grid-template-columns: 1fr;
}

@container (min-width: 380px) {
    .rb-wizardChoices--price,
    .rb-wizardChoices--pair { grid-template-columns: repeat(2, 1fr); }
}

@container (min-width: 700px) {
    .rb-wizardChoices--platform { grid-template-columns: repeat(3, 1fr); }
}

@container (min-width: 760px) {
    .rb-wizardChoices--price { grid-template-columns: repeat(4, 1fr); }
}

/*
 * The whole card is the tap target, not a 13px radio next to it. These six
 * screens are answered on a phone more often than not, and a choice you have to
 * aim at is a choice people get wrong.
 */
.rb-wizardChoice {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    flex: 1 1 240px;
    padding: 12px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
    cursor: pointer;
}

.rb-wizardChoice:hover {
    border-color: var(--rb-border-strong);
}

/*
 * :has() draws the selected state from the input itself, so the highlight
 * follows a click without JavaScript. The PHP-rendered --on class marks the
 * answer the page loaded with, so it is only a fallback for browsers without
 * :has(): applied everywhere, it would keep the old answer outlined after the
 * reader picks another.
 */
.rb-wizardChoice:has(input:checked) {
    border-color: var(--rb-accent-blue);
    box-shadow: inset 0 0 0 1px var(--rb-accent-blue);
}

@supports not selector(:has(*)) {
    .rb-wizardChoice--on {
        border-color: var(--rb-accent-blue);
        box-shadow: inset 0 0 0 1px var(--rb-accent-blue);
    }
}

.rb-wizardChoice:has(input:focus-visible) {
    outline: 2px solid var(--rb-accent-blue);
    outline-offset: 2px;
}

.rb-wizardChoice input {
    margin-top: 2px;
    flex: 0 0 auto;
}

/* The answer's icon (§17.399): the sidebar's drawings, at a size a thumb
   can read, in the heading colour, turning blue with the answer. */
.rb-wizardChoice-icon {
    flex: 0 0 auto;
    color: var(--rb-text-heading);
}

/* Beside a 36px icon, the radio and the words sit level with its middle. */
.rb-wizardChoice:has(.rb-wizardChoice-icon) {
    align-items: center;
}

.rb-wizardChoice:has(.rb-wizardChoice-icon) input {
    margin-top: 0;
}

.rb-wizardChoice-icon .rb-category-icon {
    display: block;
}

.rb-wizardChoice-icon .rb-category-icon {
    width: 36px;
    height: 36px;
}

.rb-wizardChoice:has(input:checked) .rb-wizardChoice-icon {
    color: var(--rb-accent-blue);
}

.rb-wizardChoice-body {
    display: flex;
    flex-direction: column;
    gap: 3px;
}

.rb-wizardChoice-label {
    font-weight: 600;
    color: var(--rb-text-heading);
}

.rb-wizardChoice-help {
    font-size: 12px;
    color: var(--rb-text-muted);
}

/*
 * The questions stack on one page (§17.394). The newest one fades in below
 * the answered ones. Its heading takes focus after a swap so a screen reader
 * announces it; that focus is not a thing to click, so no ring.
 */
.rb-wizardQuestion {
    scroll-margin-top: var(--rb-gap);
}

.rb-wizardQuestion .rb-block-header:focus {
    outline: none;
}

.rb-wizardQuestion--current {
    animation: rb-wizardQuestion-in 0.25s ease-out;
}

@keyframes rb-wizardQuestion-in {
    from { opacity: 0; transform: translateY(6px); }
    to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .rb-wizardQuestion--current { animation: none; }
}

/* A sentence about the whole question, under its choices. Bigger than a
   field's 11px hint, since it is read, not glanced at. */
.rb-block-body > .rb-wizardNote {
    margin: var(--rb-gap) 0 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-wizardActions {
    display: flex;
    align-items: center;
    gap: var(--rb-gap);
}

/* Next, only without JavaScript (§17.395), and always under the budget
   slider (§17.470). Beats `.rb-block-body > p`, which would put it flush
   against the choices above it. */
.rb-block-body .rb-wizardActions {
    margin: calc(var(--rb-gap) * 2) 0 0;
}

/*
 * The budget: one slider in $250 steps (§17.470), drawn like the listing
 * filters' sliders (§17.353): a blue fill up to a white thumb. The fill is
 * `--rb-budget-fill`, set by the page and kept up by rigbuilder.js; Firefox
 * draws its own with ::-moz-range-progress.
 */
.rb-wizardBudget {
    max-width: 560px;
    margin: var(--rb-gap) auto 0;
}

.rb-wizardBudget-value {
    display: block;
    margin: 0 0 8px;
    font-size: 22px;
    font-weight: 700;
    color: var(--rb-text-body);
    text-align: center;
}

.rb-block-body input.rb-wizardBudget-slider,
.dark .rb-block-body input.rb-wizardBudget-slider {
    display: block;
    width: 100%;
    height: 28px;
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    border-radius: 0;
    box-shadow: none;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

.rb-wizardBudget-slider:focus { outline: none; }

.rb-wizardBudget-slider::-webkit-slider-runnable-track {
    height: 6px;
    border-radius: 3px;
    background: linear-gradient(to right, var(--rb-accent-blue) var(--rb-budget-fill, 0%), var(--rb-border) var(--rb-budget-fill, 0%));
}

.rb-wizardBudget-slider::-moz-range-track { height: 6px; border-radius: 3px; background: var(--rb-border); }
.rb-wizardBudget-slider::-moz-range-progress { height: 6px; border-radius: 3px; background: var(--rb-accent-blue); }

.rb-wizardBudget-slider::-webkit-slider-thumb {
    width: 22px;
    height: 22px;
    margin-top: -8px;
    background: #fff;
    border: 2px solid var(--rb-accent-blue);
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    cursor: grab;
    -webkit-appearance: none;
    appearance: none;
}

.rb-wizardBudget-slider::-moz-range-thumb {
    width: 18px;
    height: 18px;
    background: #fff;
    border: 2px solid var(--rb-accent-blue);
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    cursor: grab;
}

.rb-wizardBudget-slider:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(0, 77, 144, 0.35); }
.rb-wizardBudget-slider:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(0, 77, 144, 0.35); }
.dark .rb-wizardBudget-slider::-webkit-slider-thumb { background: #e6e6e6; }
.dark .rb-wizardBudget-slider::-moz-range-thumb { background: #e6e6e6; }

.rb-wizardBudget .rb-slider-ends { margin-top: 4px; font-size: 12px; }

/* Next sits centered right under the slider it answers, wide enough to
   read as the way on. */
.rb-block-body .rb-wizardActions--center {
    justify-content: center;
    margin-top: var(--rb-gap);
}

.rb-wizardActions--center .rb-button {
    min-width: 200px;
}

/*
 * The box under the questions: "Build My Rig" once the last question is open,
 * and the way out to browsing either way. A card like the question blocks,
 * without their red header, since it asks nothing.
 */
.rb-wizardFinish {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    padding: 16px var(--rb-pad-block);
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    text-align: center;
}

.rb-wizardFinish .rb-button--large {
    min-width: 240px;
    font-size: 17px;
}

.rb-wizardEscape {
    margin: 0;
    font-size: 15px;
    color: var(--rb-text-body);
}

.rb-block--guided .rb-block-header {
    color: var(--rb-text-heading);
}

.rb-catalogFilter {
    margin: -4px 0 var(--rb-gap);
    padding: 8px 10px;
    font-size: 13px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
}

/* --------------------------------------------------------------------------
   Admin — stat tiles and health issue lists (spec §14, §17.348)
   -------------------------------------------------------------------------- */

.rb-statRow {
    display: flex;
    flex-wrap: wrap;
    gap: var(--rb-gap);
    margin-bottom: var(--rb-gap);
}

.rb-stat {
    flex: 1 1 120px;
    padding: 10px 12px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
}

.rb-stat--bad {
    border-color: var(--rb-error-border);
    background: var(--rb-error-bg);
}

.rb-stat--warn {
    border-color: var(--rb-highlight-border);
    background: var(--rb-highlight-bg);
}

.rb-stat-value {
    display: block;
    font-size: 22px;
    font-weight: 700;
    color: var(--rb-text-heading);
    font-variant-numeric: tabular-nums;
}

.rb-stat-label {
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-issueList {
    list-style: none;
    margin: 0;
    padding: 0;
}

.rb-issue {
    font-size: 12px;
    padding: 3px 7px;
    margin-bottom: 3px;
    border-left: 3px solid var(--rb-border-strong);
    border-radius: 0 var(--rb-radius) var(--rb-radius) 0;
    background: var(--rb-bg-subtle);
}

.rb-issue--error {
    border-left-color: var(--rb-error-border);
    background: var(--rb-error-bg);
    color: var(--rb-error-text);
}

.rb-issue--warning {
    border-left-color: var(--rb-highlight-border);
    background: var(--rb-highlight-bg);
    color: var(--rb-highlight-text);
}

.rb-chip--ok {
    background: var(--rb-positive-bg);
    border-color: var(--rb-positive-border);
    color: var(--rb-positive-text);
}

.rb-table-row--bad td {
    background: var(--rb-error-bg);
}

.rb-table-row--warn td {
    background: var(--rb-highlight-bg);
}

/* Recommended builds in the admin (§17.348). Rows reuse the My Rigs list. */
.rb-recommendedList .rb-buildList-item { align-items: start; }
.rb-recommendedList .rb-buildList-heading .rb-chip { margin-left: 6px; }
.rb-recommendedList .rb-issueList { margin-top: 6px; }
.rb-recommended-mounting { font-weight: 600; color: var(--rb-text-body); margin-right: 4px; }

.rb-recommendedPreview {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    gap: 12px;
    align-items: start;
}

.rb-recommendedPreview .rb-buildList-heading,
.rb-recommendedPreview .rb-buildList-meta,
.rb-recommendedPreview .rb-buildList-facts { margin: 0 0 4px; }

.rb-recommended-parts {
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
}

.rb-recommended-parts li {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 3px 0;
    border-top: 1px solid var(--rb-border);
}

.rb-recommended-partPrice {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    color: var(--rb-text-muted);
}

.rb-recommendedSource {
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--rb-border);
}

.rb-recommendedSource-form { margin: 0; }
.rb-recommendedSource-status { margin: 0 0 8px; font-size: 13px; }
.rb-recommendedSource-status a { margin-left: 6px; }
.rb-recommendedSource-other { margin-top: 10px; font-size: 13px; }
.rb-recommendedSource-other > summary { cursor: pointer; color: var(--rb-text-link); }
.rb-recommendedSource-other .rb-input { margin: 4px 0; }

/* Which reader answers have a build (§17.347, §17.348). */
.rb-coverage th,
.rb-coverage td {
    width: 25%;
    vertical-align: top;
}

.rb-coverage-cell--empty {
    background: var(--rb-highlight-bg);
}

.rb-coverage-none {
    display: block;
    font-size: 12px;
    color: var(--rb-highlight-text);
}

.rb-coverage-chip {
    display: inline-block;
    margin: 0 4px 4px 0;
    padding: 2px 8px;
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
    color: var(--rb-positive-text);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}

.rb-coverage-chip--draft {
    font-weight: 400;
    color: var(--rb-text-muted);
    background: transparent;
    border-style: dashed;
    border-color: var(--rb-border-strong);
}

/* --------------------------------------------------------------------------
   Admin how-to and health boxes (§17.347, §17.348), and small form pieces
   the recommended-build editor uses.
   -------------------------------------------------------------------------- */

.rb-howTo {
    margin: 0 0 var(--rb-gap);
    padding: 10px 14px;
    border: 1px solid var(--rb-border);
    border-left: 3px solid var(--rb-accent-blue);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
    font-size: 13px;
    line-height: 1.5;
}

.rb-howTo summary {
    font-weight: 700;
    color: var(--rb-text-heading);
    cursor: pointer;
}

.rb-howTo ol {
    margin: 8px 0;
    padding-left: 22px;
}

.rb-howTo li { margin-bottom: 3px; }
.rb-howTo p { margin: 0; }

.rb-healthBox {
    margin: 0 0 var(--rb-gap);
    padding: 10px 14px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-healthBox--ok { background: var(--rb-positive-bg); border-color: var(--rb-positive-border); }
.rb-healthBox--warn { background: var(--rb-highlight-bg); border-color: var(--rb-highlight-border); }
.rb-healthBox--bad { background: var(--rb-error-bg); border-color: var(--rb-error-border); }

.rb-healthBox-title {
    margin: 0;
    font-size: 15px;
    color: var(--rb-text-heading);
}

.rb-healthBox--ok .rb-healthBox-title { color: var(--rb-positive-text); }
.rb-healthBox--ok .rb-healthBox-title::before { content: "\2713  "; }
.rb-healthBox .rb-field-help { margin: 4px 0 8px; }
.rb-healthBox .rb-issue { background: var(--rb-bg-card); font-size: 13px; }

.rb-input--block {
    display: block;
    width: 100%;
    box-sizing: border-box;
}

.rb-field-label--stacked {
    display: block;
    margin-bottom: 4px;
}

.rb-linkButton--danger { color: var(--rb-error-text); }

/* --------------------------------------------------------------------------
   Glossary tap-outs on attribute chips (§8.3's fourth explanation source)

   A chip that explains itself is a <details>, so it works with no JavaScript
   and answers to a keyboard without anything being wired up. Closed, it has to
   be indistinguishable from a plain chip apart from the hint; open, it takes a
   line of its own rather than pushing its neighbours around, which is what the
   flex-basis below does.
   -------------------------------------------------------------------------- */

.rb-chips {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 4px;
    margin: 0 0 8px;
}

/* The chip rule above sets its own margins for the inline case; inside the
   flex row the gap does that job. */
.rb-chips > .rb-chip {
    margin: 0;
}

.rb-chip--explained {
    padding: 0;
    background: none;
    border: 0;
}

.rb-chip-summary {
    display: inline-block;
    padding: 2px 8px;
    font-size: 12px;
    list-style: none;
    cursor: pointer;
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border-strong);
    color: var(--rb-text-body);
}

/* Safari draws its own triangle unless both of these are said. */
.rb-chip-summary::-webkit-details-marker {
    display: none;
}

.rb-chip-summary::marker {
    content: '';
}

.rb-chip-summary:hover,
.rb-chip--explained[open] > .rb-chip-summary {
    border-color: var(--rb-accent-blue);
    color: var(--rb-text-heading);
}

.rb-chip-summary:focus-visible {
    outline: 2px solid var(--rb-accent-blue);
    outline-offset: 1px;
}

/* The one mark that says a chip has something behind it. Small, quiet, and
   never the chip's own text — a "?" appended to the value would be read out
   as part of the value. */
.rb-chip-hint {
    display: inline-block;
    margin-left: 5px;
    width: 13px;
    height: 13px;
    line-height: 13px;
    text-align: center;
    font-size: 10px;
    font-weight: 700;
    border-radius: 50%;
    background: var(--rb-border);
    color: var(--rb-text-body);
    vertical-align: 1px;
}

.rb-chip--explained[open] {
    /* Its own row inside the wrapping flex container: the explanation appears
       under the chip it belongs to instead of shouldering the rest of the row
       out of the way. */
    flex: 1 0 100%;
}

.rb-chip-explainer {
    margin: 6px 0 2px;
    padding: 10px 12px;
    font-size: 13px;
    line-height: 1.5;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-left: 3px solid var(--rb-accent-blue);
    border-radius: 0 var(--rb-radius) var(--rb-radius) 0;
    color: var(--rb-text-body);
}

.rb-chip-explainer p {
    margin: 0 0 6px;
}

.rb-chip-term {
    font-weight: 700;
    color: var(--rb-text-heading);
}

.rb-chip-more {
    margin-bottom: 0 !important;
    font-size: 12px;
}

/* Available to a screen reader, invisible to everyone else. */
.rb-visuallyHidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* --------------------------------------------------------------------------
   The glossary page
   -------------------------------------------------------------------------- */

/* The index and the entries each sit in a section block, so the text reads
   on the card background rather than the page's gray. */
.rb-glossaryIndex {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
}

.rb-glossaryIndex-link {
    padding: 3px 9px;
    font-size: 13px;
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    text-decoration: none;
}

.rb-glossaryEntry {
    padding: var(--rb-gap) 0;
    border-bottom: 1px solid var(--rb-border);
}

.rb-glossaryEntry:first-child {
    padding-top: 0;
}

.rb-glossaryEntry:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

/* Anchored from a chip tap-out, so the heading must not land under the site's
   sticky header. */
.rb-glossaryEntry-term {
    margin: 0 0 6px;
    font-size: 17px;
    color: var(--rb-text-heading);
    scroll-margin-top: 80px;
}

.rb-glossaryEntry p {
    margin: 0 0 8px;
}

/* --------------------------------------------------------------------------
   Sparklines and bar series (§11, §10.5)

   Both inherit their ink from `currentColor`, so neither needs a dark-mode
   rule of its own: they are already whatever colour the text around them is.
   -------------------------------------------------------------------------- */

.rb-sparkline {
    display: block;
    width: 120px;
    height: 28px;
    overflow: visible;
    color: var(--rb-accent-blue);
}

.rb-sparkline-line {
    fill: none;
    stroke: currentColor;
    stroke-width: 1.5;
    stroke-linejoin: round;
    stroke-linecap: round;
    /* The viewBox is stretched to the element's box, which would stretch the
       stroke with it. */
    vector-effect: non-scaling-stroke;
}

.rb-sparkline-now {
    fill: currentColor;
}

.rb-sparkline--sample {
    color: var(--rb-text-muted);
}

.rb-sparkline--sample .rb-sparkline-line {
    stroke-dasharray: 3 3;
}

.rb-bars {
    display: block;
    width: 120px;
    height: 28px;
    color: var(--rb-accent-blue);
}

.rb-bars-bar {
    fill: currentColor;
    opacity: 0.75;
}

.rb-chartRow {
    display: flex;
    align-items: center;
    gap: var(--rb-gap);
}

.rb-chartRow .rb-bars {
    width: 240px;
    height: 44px;
    flex: 0 0 auto;
}

.rb-chartRow-body p {
    margin: 0 0 4px;
}

.rb-table-spark {
    white-space: nowrap;
}

.rb-table-spark .rb-sparkline,
.rb-table-spark .rb-bars {
    display: inline-block;
    vertical-align: middle;
    width: 90px;
    height: 20px;
}

/* --- the price history under the best offer ------------------------------ */

.rb-priceRow-history {
    display: flex;
    align-items: center;
    gap: 8px;
    grid-column: 1 / -1;
    margin-top: 4px;
}

.rb-priceRow-history .rb-sparkline {
    flex: 0 0 auto;
    width: 90px;
    height: 22px;
}

.rb-priceRow-historyNote {
    font-size: 12px;
    color: var(--rb-text-muted);
}
.rb-priceRow-checkFrequency {
    white-space: nowrap;
}

/* --------------------------------------------------------------------------
   "Price changed since you saved this" (§7)

   Deliberately quiet. It is a note about a part, not a price — every figure a
   reader acts on is worked out from today's listings, and this must never look
   like one of them.
   -------------------------------------------------------------------------- */

.rb-buildParts-change {
    display: block;
    font-size: 12px;
}

.rb-buildParts-change--down {
    color: var(--rb-positive-text);
}

.rb-buildParts-change--up {
    color: var(--rb-text-muted);
}

.rb-buildChange {
    margin: 8px 0 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

/* --------------------------------------------------------------------------
   Admin: two tables side by side (analytics leaderboards)
   -------------------------------------------------------------------------- */

.rb-twoUp {
    display: flex;
    flex-wrap: wrap;
    gap: var(--rb-gap);
}

.rb-twoUp > * {
    flex: 1 1 300px;
    min-width: 0;
}

/* --------------------------------------------------------------------------
   Responsive — the site's breakpoints, desktop-first (design-tokens.md §2)
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
    /* Side-by-side review stops being side-by-side well before the site's own
       breakpoint: two columns of dense text in half a tablet width is worse
       than one column of each. */
    .rb-review {
        flex-direction: column;
    }

    .rb-review-source {
        position: static;
        width: 100%;
    }

    /* Same reasoning for the build: below this width the tray is narrower than
       the sentence it has to fit. It moves above the parts rather than below
       them, because "what this adds up to" is the answer the reader came for. */
}

@media (max-width: 650px) {
    .rb-pageTitle {
        font-size: 19px;
    }

    .rb-filterBar-field {
        flex-basis: 100%;
        max-width: none;
    }

    /* The month chart and its sentence stop fitting beside each other well
       before the text does. */
    .rb-chartRow {
        flex-direction: column;
        align-items: stretch;
    }

    .rb-chartRow .rb-bars {
        width: 100%;
    }

    /* One choice per row. Two 240px cards side by side at this width leaves
       each of them too narrow to hold its own help text on one line, and a
       questionnaire that reflows mid-answer is a questionnaire people abandon. */
    .rb-wizardChoice {
        flex: 1 1 100%;
    }

    .rb-wizardActions {
        flex-wrap: wrap;
    }

    .rb-status {
        gap: 2px;
        flex-direction: column;
        align-items: flex-start;
    }

    .rb-status-label {
        min-width: 0;
    }

    /*
     * The flex-basis above is a WIDTH in the default row direction but becomes
     * a HEIGHT once the row stacks, which would leave every status row 260px
     * tall. Reset it to content height.
     */
    .rb-status-detail {
        flex: 0 1 auto;
    }

    .rb-productHero {
        flex-direction: column;
    }

    .rb-productHero-media {
        flex: 0 0 auto;
        max-width: 260px;
    }

    .rb-lightbox {
        padding: 12px;
    }

    .rb-lightbox-nav {
        padding: 4px 8px;
    }

    /* Same stacking hazard as .rb-status above: these flex-basis values become
       heights once the row direction turns vertical. */
    .rb-field {
        flex-direction: column;
        align-items: stretch;
    }

    .rb-field-label,
    .rb-field-control {
        flex: 0 1 auto;
    }

    .rb-input--number {
        flex: 0 1 auto;
    }

    .rb-specTable th {
        width: 50%;
    }

    /* Admin tables are wide by nature; let them scroll inside the card rather
       than push the page sideways. */
    .rb-block-body {
        overflow-x: auto;
    }

    .rb-table-truncate {
        max-width: 180px;
    }

    /* A price row is three columns of nowrap content; at this width the buy
       button wants the full line under the price rather than a third of it. */
    .rb-priceRow {
        grid-template-columns: 1fr auto;
    }

    .rb-priceRow-action {
        grid-row: auto;
        grid-column: 1 / -1;
    }

    .rb-priceRow-action .rb-buyButton {
        display: block;
        text-align: center;
    }

    .rb-modal-code {
        font-size: 24px;
    }
}

@media (max-width: 480px) {
    .rb-block-body {
        padding: 8px;
    }

    /* Two stat cards per row rather than four in a squeeze. */
    .rb-stat {
        flex: 1 1 calc(50% - var(--rb-gap));
    }

    /* The whole button, full width, for the same reason the build actions do
       it: a thumb is bigger than a right-aligned label. */
    .rb-wizardActions .rb-button,
    .rb-wizardFinish .rb-button--large {
        width: 100%;
        text-align: center;
    }

    .rb-status {
        padding: 6px 8px;
    }

    .rb-productCard-media {
        flex: 0 0 60px;
    }

    .rb-productCard-media img,
    .rb-productCard-media .rb-imagePlaceholder {
        width: 60px;
        height: 60px;
    }

    .rb-imageGrid-item {
        flex: 1 1 100%;
    }

    .rb-adminNav-link {
        padding: 4px 8px;
        font-size: 12px;
    }

    /* A full-width button is easier to hit than a right-aligned one, and at
       this width there is nothing to sit beside it anyway. */
    .rb-buildActions .rb-button,
    .rb-buildActions form,
    .rb-buildActions form .rb-button {
        width: 100%;
        text-align: center;
    }

    .rb-buildParts-remove {
        margin-left: 0;
    }
}

/* Quantity and ownership share the existing themed input controls. */
.rb-buildQuantity { display: flex; flex-wrap: wrap; align-items: end; gap: 10px; width: 100%; margin-top: 10px; }
.rb-buildQuantity label { display: flex; flex-direction: column; gap: 4px; font-size: 12px; }
.rb-buildQuantity input { width: 85px; }
.rb-buildQuantity select { max-width: 100%; }
@media (max-width: 650px) {
    .rb-buildQuantity label:has(select) { width: 100%; }
}

/* Product detail: one editorial introduction, compact shopping, then specs.
   Scoped to product pages so shared build/admin panels retain their layout. */
.rb-productPage .rb-productOverview > .rb-block-body {
    padding: 20px;
}
.rb-productPage .rb-productHero {
    gap: 24px;
}
.rb-productPage .rb-productHero-media {
    flex: 1 0 36%;
    min-width: 0;
}
.rb-productPage .rb-productHero-body {
    max-width: 480px;
}
.rb-productPage .rb-productHero-body .rb-lede {
    margin: 0 0 8px;
    font-size: 12px;
}
.rb-platformSummary {
    margin: 12px 0 14px;
}
.rb-platformSummary-list {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.rb-platformSummary-item {
    display: grid;
    grid-template-columns: 20px minmax(0, 1fr);
    align-content: center;
    column-gap: 4px;
    min-height: 48px;
    padding: 7px 8px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
}
.rb-platformSummary-icon {
    grid-row: 1 / span 2;
    align-self: center;
    font-size: 17px;
    font-weight: 800;
    line-height: 1;
    text-align: center;
}
.rb-platformSummary-name {
    font-size: 12px;
    font-weight: 700;
    line-height: 1.2;
}
.rb-platformSummary-detail {
    font-size: 11px;
    line-height: 1.25;
}
.rb-platformSummary-item--supported {
    color: var(--rb-positive-text);
    border-color: var(--rb-positive-border);
    background: var(--rb-positive-bg);
}
.rb-platformSummary-item--conditional {
    color: var(--rb-highlight-text);
    border-color: var(--rb-highlight-border);
    background: var(--rb-highlight-bg);
}
.rb-platformSummary-item--unsupported {
    color: var(--rb-error-text);
    border-color: var(--rb-error-border);
    background: var(--rb-error-bg);
}
.dark .rb-platformSummary-item--unsupported {
    color: #d49b9b;
    border-color: #664040;
    background: rgba(185, 100, 100, 0.12);
}
.rb-platformSummary-item--unknown {
    color: var(--rb-text-muted);
}
.rb-productPage .rb-pageTitle {
    font-size: clamp(22px, 2.1vw, 28px);
    line-height: 1.18;
    letter-spacing: -0.025em;
    overflow-wrap: anywhere;
}
.rb-productPage .rb-productHero-body > p:not(.rb-lede) {
    font-size: 14px;
    line-height: 1.6;
}
.rb-productPage .rb-productHero-body .rb-buildActions {
    margin: 18px 0 0;
}
.rb-productNav {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 24px;
    padding: 2px 10px 12px;
    font-size: 16px;
    font-weight: 600;
}
.rb-productPage [id^="product-"] {
    scroll-margin-top: 100px;
}
.rb-productPage .rb-pricePanel {
    gap: 0;
}
.rb-productPage .rb-priceRow {
    border: 0;
    border-radius: 0;
    border-bottom: 1px solid var(--rb-border);
    padding: 8px 10px;
}
.rb-productPage .rb-priceRow--region {
    margin-left: 0;
}
.rb-priceRegions > summary {
    padding: 10px;
    cursor: pointer;
    color: var(--rb-text-link);
    font-size: 13px;
    font-weight: 600;
}
.rb-priceRegions > summary span {
    margin-left: 10px;
    color: var(--rb-text-body);
    font-size: 12px;
    font-weight: 400;
}
.rb-priceRegions[open] > summary {
    background: var(--rb-bg-subtle);
}
.rb-productPage .rb-specTable {
    table-layout: fixed;
    margin: 0;
}
.rb-productPage .rb-specTable td {
    overflow-wrap: anywhere;
}
.rb-compatGrid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
    align-items: start;
}
.rb-compatGrid .rb-compatGroup {
    margin: 0;
    min-width: 0;
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
}
.rb-compatGrid .rb-compatGroup-title {
    padding: 12px 14px;
    font-size: 16px;
    background: var(--rb-bg-subtle);
    border-radius: var(--rb-radius);
}
.rb-compatGrid .rb-compatGroup[open] > .rb-compatGroup-title {
    margin-bottom: 0;
    border-bottom: 1px solid var(--rb-border);
    border-radius: var(--rb-radius) var(--rb-radius) 0 0;
}
.rb-compatGrid .rb-compatGroup > .rb-compatList,
.rb-compatGrid .rb-compatGroup > .rb-compatGroup-empty {
    margin: 0 14px;
}
.rb-compatGrid .rb-compatGroup > .rb-compatShowAll {
    margin: 8px 14px 14px;
}
.rb-compatGrid .rb-compatGroup-count {
    margin-left: 8px;
}
.rb-compatGrid .rb-compatGroup[open] {
    grid-column: 1 / -1;
}

.rb-compatShowAll {
    margin: 8px 10px 12px;
}

.rb-compatShowAll > summary {
    display: block;
    list-style: none;
    width: fit-content;
    cursor: pointer;
    color: var(--rb-text-link);
    font-size: 14px;
}

.rb-compatShowAll > summary::-webkit-details-marker {
    display: none;
}

.rb-compatShowAll > summary:hover {
    text-decoration: underline;
}

.rb-compatShowAll > summary:focus-visible {
    outline: 2px solid var(--rb-accent-blue);
    outline-offset: 3px;
}

.rb-compatShowAll-less,
.rb-compatShowAll[open] .rb-compatShowAll-more {
    display: none;
}

.rb-compatShowAll[open] .rb-compatShowAll-less {
    display: inline;
}

.rb-compatGrid .rb-compatList-item {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
}

.rb-compatList-image {
    flex: 0 0 56px;
}

.rb-compatList-image img,
.rb-compatList-image .rb-imagePlaceholder {
    display: block;
    width: 56px;
    height: 56px;
    box-sizing: border-box;
    object-fit: contain;
    background: #fff;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-compatList-content {
    min-width: 0;
    overflow-wrap: anywhere;
}

.rb-compatGrid .rb-compatList-detail {
    margin-top: 5px;
    font-size: 14px;
    line-height: 1.5;
}
.dark .rb-productPage .rb-compatList-name,
.dark .rb-productPage .rb-compatList-name a {
    color: var(--rb-text-heading);
    font-weight: 600;
}
.rb-productPage .rb-bundleList {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 20px;
}
/* The sidebar leaves too little room for a gallery and details at tablet widths. */
@media (max-width: 900px) {
    .rb-productPage .rb-productHero {
        flex-direction: column;
        gap: 16px;
    }
    .rb-productPage .rb-productHero-media {
        flex: none;
        width: 100%;
        max-width: 360px;
        margin: 0 auto;
    }
    .rb-productPage .rb-productHero-body {
        width: 100%;
        max-width: none;
    }
    .rb-productPage .rb-gallery-thumb img {
        width: 60px;
        height: 60px;
    }
    .rb-productBuildActions form {
        flex: 1 1 160px;
    }
    .rb-productBuildActions .rb-button {
        width: 100%;
        justify-content: center;
    }
}
@media (max-width: 650px) {
    .rb-productPage .rb-platformSummary-name,
    .rb-productPage .rb-platformSummary-detail {
        font-size: 13px;
        line-height: 1.35;
    }
    .rb-productPage .rb-productOverview {
        background: transparent;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }
    .rb-productPage .rb-productOverview > .rb-block-body {
        padding: 15px;
    }
    .rb-productPage .rb-pageTitle {
        font-size: 24px;
    }
    .rb-productPage .rb-priceRow {
        grid-template-columns: minmax(0, 1fr) auto;
    }
    .rb-productPage .rb-priceRow-price {
        white-space: normal;
        text-align: right;
    }
    .rb-productPage .rb-priceRow-action {
        grid-column: 1 / -1;
        grid-row: auto;
    }
    .rb-priceRegions > summary span {
        display: block;
        margin: 4px 0 0 14px;
    }
}
@media (max-width: 480px) {
    .rb-platformSummary-list {
        grid-template-columns: minmax(0, 1fr);
    }
    .rb-platformSummary-item {
        grid-template-columns: 20px 80px minmax(0, 1fr);
        align-items: center;
        min-height: 44px;
    }
    .rb-platformSummary-icon {
        grid-row: auto;
    }
    .rb-compatGrid,
    .rb-productPage .rb-bundleList {
        grid-template-columns: minmax(0, 1fr);
    }
}

/* A single product card, with the offer beside the gallery. */
.rb-productPage .rb-gallery-main img {
    border: 0;
    background: transparent;
}
.rb-productPage .rb-productPurchase {
    margin-top: 18px;
}
.rb-productPurchase .rb-priceRow {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
    padding: 14px;
}
.rb-productPurchase .rb-priceRow--best {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--rb-border);
    border-radius: 0;
}
.rb-productPurchase .rb-priceRow--withCode {
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}
/* Availability caution takes precedence over the discount-code highlight. */
.rb-productPurchase .rb-priceRow--caution {
    background: var(--rb-highlight-bg);
    border: 1px solid var(--rb-highlight-border);
    border-radius: var(--rb-radius);
}
.rb-productPurchase .rb-priceRow--caution .rb-price--coded {
    color: var(--rb-highlight-text);
}
.rb-productPurchase .rb-priceRow-price {
    font-size: 26px;
    white-space: normal;
    text-align: left;
}
.rb-productPurchase .rb-price--was {
    font-size: inherit;
    margin-right: 6px;
}
.rb-productPurchase .rb-priceSavings {
    display: block;
    margin-top: 2px;
    font-size: 13px;
    font-weight: 600;
    color: var(--rb-text-muted);
}
.rb-productPurchase .rb-priceRow--withCode .rb-priceSavings {
    color: var(--rb-positive-text);
}
.rb-productPurchase .rb-priceRow--caution .rb-priceSavings {
    color: var(--rb-highlight-text);
}
.rb-productPurchase .rb-priceRow-action {
    grid-column: 1;
    grid-row: auto;
}
.rb-productPurchase .rb-buyButton {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 44px;
    box-sizing: border-box;
    padding: 10px 18px;
    font-size: 15px;
    line-height: 1.4;
    text-align: center;
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.18), 0 1px 2px rgba(0, 0, 0, 0.12);
}
.rb-productPurchase .rb-buyButton::after {
    order: -1;
    flex: 0 0 20px;
    width: 20px;
    height: 20px;
    margin-left: 0;
}
.rb-productPurchase .rb-buyButton:focus-visible {
    outline: 2px solid var(--rb-buy-border);
    outline-offset: 3px;
}
.rb-productPurchase .rb-buyButton:active {
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.25);
}
.rb-productPurchase .rb-priceSavings strong {
    display: inline-block;
    padding: 2px 6px;
    border: 1px dashed currentColor;
    border-radius: var(--rb-radius);
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    white-space: nowrap;
}
.rb-productPurchase .rb-priceRow--region .rb-priceRow-price {
    font-size: 18px;
}
.rb-productPurchase .rb-priceOfferGroup {
    margin-bottom: 8px;
    border-bottom: 1px solid var(--rb-border);
}
.rb-productPurchase .rb-priceOfferGroup--withCode {
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}
.rb-productPurchase .rb-priceOfferGroup--caution {
    background: var(--rb-highlight-bg);
    border: 1px solid var(--rb-highlight-border);
    border-radius: var(--rb-radius);
}
.rb-productPurchase .rb-priceOfferGroup .rb-priceRow {
    background: transparent;
    border: 0;
    border-radius: 0;
    padding-bottom: 8px;
}
.rb-productPurchase .rb-priceOfferGroup .rb-priceRow--region .rb-priceRow-price {
    font-size: 26px;
}
/* Plain offers have no enclosing surface, so their content aligns with the
   rest of the product details. Colored offers keep their inset padding. */
.rb-productPurchase .rb-pricePanel > .rb-priceRow:not(.rb-priceRow--withCode):not(.rb-priceRow--caution),
.rb-productPurchase .rb-priceOfferGroup:not(.rb-priceOfferGroup--withCode):not(.rb-priceOfferGroup--caution) .rb-priceRow {
    padding: 0;
}
.rb-productPurchase .rb-priceOfferGroup:not(.rb-priceOfferGroup--withCode):not(.rb-priceOfferGroup--caution) {
    border-bottom: 0;
}
.rb-productPurchase .rb-priceOfferGroup:not(.rb-priceOfferGroup--withCode):not(.rb-priceOfferGroup--caution) .rb-priceRegionNav {
    margin-top: 12px;
    padding: 0;
}
.rb-priceRegionPane[hidden],
.rb-priceRegionNav[hidden] {
    display: none;
}
.rb-priceRegionNav {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(130px, 100%), 1fr));
    gap: 8px 10px;
    padding: 2px 14px 14px;
}
.rb-priceRegionNav a,
.rb-priceRegionNav a:visited {
    color: var(--rb-text-link);
    font-size: 12px;
    line-height: 1.3;
    text-decoration: none;
    white-space: nowrap;
}
.rb-priceRegionName {
    text-decoration: underline;
    text-underline-offset: 2px;
}
.rb-priceRegionNav a:hover,
.rb-priceRegionNav a:focus-visible {
    color: var(--rb-text-body);
}
.rb-priceRegionNav a[aria-current="true"] {
    color: var(--rb-text-body);
    font-weight: 700;
}
.rb-priceRegionNav a[aria-current="true"] .rb-priceRegionName {
    text-decoration-thickness: 2px;
}
.rb-priceRegionFlag {
    text-decoration: none;
    display: inline-block;
    font-size: 20px;
    line-height: 1;
    vertical-align: -3px;
}
.rb-priceRegionStatus {
    display: block;
    margin-top: 2px;
    color: var(--rb-text-muted);
    font-size: 11px;
    line-height: 1.25;
}
.rb-priceRegionStatus--inStock {
    color: var(--rb-positive-text);
    font-weight: 700;
}
.rb-productPage .rb-productNav {
    margin-top: 24px;
    padding: 14px 0;
    border-top: 1px solid var(--rb-border);
    border-bottom: 1px solid var(--rb-border);
}
.rb-productDescription {
    margin: 20px 0 24px;
    font-size: 15px;
    line-height: 1.65;
}
.rb-productDescription p:last-child {
    margin-bottom: 0;
}
/* In-content links are underlined (design tokens), so a product named in the
   description reads as a link in both modes (§17.427). */
.rb-productDescription a {
    text-decoration: underline;
}
/* A section per rival (§17.428), its heading linking to that comparison
   (§17.432). The heading keeps its weight and size, with the in-content link
   color and underline. */
.rb-productDescription .rb-productDescription-heading {
    margin: 24px 0 8px;
    font-size: 18px;
    font-weight: 600;
    line-height: 1.3;
    color: var(--rb-text-heading);
}
.rb-productSection {
    margin-top: 24px;
    padding-top: 20px;
    border-top: 1px solid var(--rb-border);
}
.rb-productSection-title {
    margin: 0 0 12px;
    font-size: 22px;
    font-weight: 600;
    color: var(--rb-text-heading);
}
.rb-productSection > .rb-block-body {
    padding: 0;
}
.rb-compatNote {
    margin: 24px 0 0;
    padding-top: 20px;
    font-size: 15px;
    line-height: 1.6;
    color: var(--rb-text-muted);
}
@media (max-width: 650px) {
    .rb-productPage .rb-productDescription,
    .rb-productPage .rb-specTable,
    .rb-productPage .rb-specTable-note {
        font-size: 16px;
        line-height: 1.6;
    }
    .rb-productPage .rb-specTable th,
    .rb-productPage .rb-specTable td {
        padding: 8px 10px;
        overflow-wrap: anywhere;
    }
    .rb-productPage .rb-productPurchase .rb-priceRow-price {
        text-align: left;
    }
}

.rb-catalogSort {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 12px 0 16px;
}
.rb-catalogSort .rb-input {
    width: auto;
    max-width: 100%;
}

.rb-popularityTable {
    overflow-x: auto;
}

/* Universal and category product listings share a grid of labeled filters
   and a footer with filter actions. Display choices sit above results (§17.362). */
/* The panel is the last child of its form, so .rb-block:last-child would drop its gap to the results. */
.rb-block.rb-listingFilters { margin-bottom: 20px; }
.rb-listingFilters > summary { cursor: pointer; }
.rb-listingFilters > summary h2 { display: inline; margin: 0; font: inherit; color: inherit; }
.rb-listingFilters-badge { margin-left: 6px; padding: 1px 7px; border-radius: 10px; background: rgba(255, 255, 255, 0.2); font-size: 12px; font-weight: 600; }
.rb-listingFilters-count { float: right; margin-top: 1px; font-size: 13px; font-weight: 400; opacity: 0.9; }
/* At most --rb-filter-cols per row, chosen so the last row is not left
   nearly empty (§17.380), and never narrower than 230px, so a narrow
   screen still fits fewer. */
.rb-filterGrid {
    --rb-filter-cols: 4;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(max(230px, calc((100% - (var(--rb-filter-cols) - 1) * 20px) / var(--rb-filter-cols))), 1fr));
    align-items: start;
    gap: 16px 20px;
}
.rb-filterField { display: flex; flex-direction: column; gap: 6px; min-width: 0; margin: 0; padding: 0; border: 0; }
.rb-filterLabel { float: none; padding: 0; margin: 0 0 6px; font-size: 14px; font-weight: 600; color: var(--rb-text-body); }
label.rb-filterLabel { margin: 0; }
.rb-filterField > .rb-input { flex: none; width: 100%; box-sizing: border-box; }
.rb-filterRange { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--rb-text-muted); }
.rb-filterRange .rb-input { flex: 1 1 0; width: 0; box-sizing: border-box; }

/* A min/max filter as a slider with two thumbs (§17.353). The two range
   inputs lie on top of each other over one track; only their thumbs take
   the pointer, so either can be dragged. */
.rb-filterRange--slider { display: block; }
.rb-slider { position: relative; padding-top: 4px; }
.rb-slider-track { position: relative; height: 6px; margin: 9px 9px 0; background: var(--rb-border); border-radius: 3px; }
.rb-slider-fill { position: absolute; top: 0; bottom: 0; background: var(--rb-accent-blue); border-radius: 3px; }
.rb-slider-thumb {
    position: absolute;
    top: 4px;
    left: 0;
    z-index: 2;
    width: 100%;
    height: 24px;
    margin: 0;
    background: none;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}
/* The site styles every input as a boxed field; a slider's inputs are only
   their thumbs, so that box is taken off in both modes. */
.rb-slider input.rb-slider-thumb,
.dark .rb-slider input.rb-slider-thumb { padding: 0; background: transparent; border: 0; border-radius: 0; box-shadow: none; }
.rb-slider-thumb:focus { outline: none; }
.rb-slider-thumb::-webkit-slider-runnable-track { height: 24px; background: none; }
.rb-slider-thumb::-moz-range-track { height: 24px; background: none; }
.rb-slider-thumb::-webkit-slider-thumb {
    width: 18px;
    height: 18px;
    margin-top: 3px;
    background: #fff;
    border: 2px solid var(--rb-accent-blue);
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    cursor: grab;
    pointer-events: auto;
    -webkit-appearance: none;
    appearance: none;
}
.rb-slider-thumb::-moz-range-thumb {
    width: 14px;
    height: 14px;
    background: #fff;
    border: 2px solid var(--rb-accent-blue);
    border-radius: 50%;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    cursor: grab;
    pointer-events: auto;
}
.rb-slider-thumb:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px rgba(0, 77, 144, 0.35); }
.rb-slider-thumb:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px rgba(0, 77, 144, 0.35); }
.rb-slider-ends { display: flex; justify-content: space-between; margin-top: 10px; font-size: 11px; color: var(--rb-text-muted); }
.rb-slider-value { margin: 2px 0 0; font-size: 14px; font-weight: 600; color: var(--rb-text-body); text-align: center; }
.dark .rb-slider-thumb::-webkit-slider-thumb { background: #e6e6e6; }
.dark .rb-slider-thumb::-moz-range-thumb { background: #e6e6e6; }
.rb-filterChips { display: flex; flex-wrap: wrap; gap: 6px; }
.rb-filterChip { display: inline-flex; align-items: center; gap: 5px; padding: 4px 9px; border: 1px solid var(--rb-border-strong); border-radius: 14px; font-size: 13px; cursor: pointer; user-select: none; }
.rb-filterChip input { margin: 0; accent-color: var(--rb-accent-blue); }
/* "Compatible with your rig build", and which build that is (§17.379). */
.rb-filterFits-note { margin: 6px 0 0; font-size: 12px; line-height: 1.4; color: var(--rb-text-muted); }
.rb-filterFits[hidden] { display: none; }
/* Active filter chips use the shared selected state (design-tokens.md §8). */
.rb-filterChip:has(input:checked) { border-color: var(--rb-highlight-border); background: var(--rb-highlight-bg); font-weight: 700; }
.rb-filterChip:has(input:focus-visible) { outline: 2px solid var(--rb-accent-blue); outline-offset: 2px; }
.rb-filterFooter { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 20px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--rb-border); font-size: 14px; }
.rb-filterDisplay { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; min-width: 0; font-size: 14px; }
.rb-filterDisplay label { font-weight: 600; }
.rb-filterDisplay .rb-input { flex: 0 1 auto; width: auto; margin-right: 10px; }
.rb-filterActions { display: flex; align-items: center; gap: 14px; margin-left: auto; }
/* Filters apply as they change (§17.354): no Apply button, and the results
   dim while the new ones load. */
.is-live .rb-filterActions button[type="submit"],
.is-live ~ [data-rb-catalog-results] .rb-filterDisplay button[type="submit"] { display: none; }
/* With live filters, the footer has no visible action until Clear all appears. */
.is-live .rb-filterFooter:not(:has(.rb-filterActions a)) { display: none; }
[data-rb-catalog-results] { transition: opacity 0.15s; }
[data-rb-catalog-results][aria-busy="true"] { opacity: 0.5; }
/* The grid always has at least two columns above the phone breakpoint. */
@media (min-width: 651px) {
    .rb-filterField--wide { grid-column: span 2; }
}
@media (max-width: 650px) {
    .rb-filterDisplay { display: grid; grid-template-columns: auto minmax(0, 1fr); width: 100%; }
    /* border-box: the site gives selects padding and a border outside their width, which pushed them 8px past the panel (§17.355). */
    .rb-filterDisplay .rb-input { box-sizing: border-box; width: 100%; min-width: 0; margin-right: 0; }
    .rb-filterActions { width: 100%; justify-content: flex-end; }
}

/* Aligned specification columns keep comparison useful on every screen size. */
.rb-catalogTableWrap { overflow-x: auto; max-width: 100%; }
.rb-catalogTableWrap:focus-visible { outline: 2px solid var(--rb-accent-blue); outline-offset: 2px; }
.rb-catalogTable { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 14px; }
.rb-catalogTable th, .rb-catalogTable td { padding: 10px 8px; text-align: left; vertical-align: middle; border-bottom: 1px solid var(--rb-border); max-width: 230px; line-height: 1.5; overflow-wrap: normal; }
.rb-catalogTable thead th,
.rb-catalogTable thead th.rb-catalogTable-number {
    background: var(--rb-brand-red-grad);
    color: #fff;
    padding: 8px;
    text-align: left;
    vertical-align: top;
    font-size: 15px;
    line-height: 20px;
}
/* Headings may wrap so tables fit before falling back to cards (§17.207). */
.rb-catalogTable-sort { display: block; min-height: 20px; font-weight: 600; }
.rb-catalogTable-sort, .rb-catalogTable-sort:visited { color: #fff; }
.rb-catalogTable-sort:hover, .rb-catalogTable-sort:focus { text-decoration: none; }
.rb-catalogTable-sort span { margin-left: 4px; }
.rb-catalogTable th[aria-sort] { box-shadow: inset 0 -3px #fff; }
.rb-catalogTable tbody tr { --rb-table-row: var(--rb-bg-card); }
.rb-catalogTable tbody tr:nth-child(even) { --rb-table-row: var(--rb-bg-subtle); }
.rb-catalogTable tbody td, .rb-catalogTable tbody th { background: var(--rb-table-row); }
.rb-catalogTable tbody:last-child tr:last-child > :is(th, td) { border-bottom: 0; }
.rb-catalogTable thead th:first-child, .rb-catalogTable .rb-catalogTable-product { position: sticky; left: 0; z-index: 1; min-width: 310px; width: auto; max-width: none; }
/* Other columns shrink to their longest value so product names get all the remaining width (§17.219). Headings may still wrap. */
.rb-catalogTable thead th:not(:first-child), .rb-catalogTable tbody td { width: 1%; }
.rb-catalogTable tbody td { white-space: nowrap; }
.rb-catalogTable thead th { white-space: nowrap; }
/* Headings wrap only when that gives product names more room (§17.220). */
.rb-catalogTable--wrapHeads thead th, .rb-catalogTable--wrapHeads thead th:is(.rb-catalogTable-number, .rb-catalogTable-platform) { white-space: normal; }
/* Text values keep short entries on one line and wrap only the rare long one. */
.rb-catalogTable tbody td:not(.rb-catalogTable-number, .rb-catalogTable-platform, .rb-catalogTable-price) { min-width: 7em; white-space: normal; }
.rb-catalogTable-product { font-weight: 600; }
.rb-catalogTable-productSummary { display: flex; align-items: center; gap: 10px; }
.rb-catalogTable-thumbnail { flex: 0 0 52px; }
.rb-catalogTable-product a { display: block; font-size: 14px; }
.rb-catalogTable-product a:not(.rb-catalogTable-thumbnail) { font-size: 14px; text-decoration: underline; text-underline-offset: 2px; }
.rb-catalogTable-brand { display: block; margin-top: 2px; font-size: 12px; font-weight: 400; color: var(--rb-text-muted); }
.rb-catalogTable-product img { width: 52px; height: 52px; flex: 0 0 52px; object-fit: contain; background: #fff; border-radius: 3px; }
.rb-catalogTable .rb-catalogTable-number { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.rb-catalogTable .rb-catalogTable-platform { white-space: nowrap; }
.rb-catalogTable-platform abbr { text-decoration: none; }
.rb-catalogTable-number .rb-price { display: block; font-size: 16px; font-weight: 700; white-space: nowrap; }
.rb-catalogTable-number .rb-price--was { font-size: 12px; font-weight: 400; line-height: 1.3; }
.rb-catalogTable .rb-price--coded .rb-price-qualifier,
.rb-catalogTable .rb-price--sale .rb-price-qualifier {
    display: block;
    margin-top: 2px;
    font-size: 11px;
    line-height: 1.2;
}
.rb-catalogTable-unknown { color: var(--rb-text-muted); }
.rb-catalogTable abbr { cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; }
.rb-catalogTable .rb-catalogTable-groupRow th { background: var(--rb-bg-subtle); padding: 6px 8px; color: var(--rb-text-heading-form); }
.rb-catalogTable-groupRow span { font-weight: 400; }
.rb-tableGrouping { font-size: 13px; margin: 0; }

/* Sort By and Group By above the results, with the List/Grid switch (§17.362). */
.rb-listingToolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 16px; margin: 0 0 10px; }
.rb-viewSwitch { display: inline-flex; margin-left: auto; border: 1px solid var(--rb-border-strong); border-radius: var(--rb-radius); overflow: hidden; }
.rb-viewSwitch a { display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; font-size: 14px; font-weight: 600; color: var(--rb-text-link); text-decoration: none; background: var(--rb-bg-card); }
.rb-viewSwitch a + a { border-left: 1px solid var(--rb-border-strong); }
.rb-viewSwitch a:hover { background: var(--rb-bg-subtle); text-decoration: none; }
.rb-viewSwitch svg { fill: currentColor; flex: none; }
.rb-viewSwitch a[aria-current="page"], .rb-viewSwitch a[aria-current="page"]:hover { color: var(--rb-nav-current-text); background: var(--rb-nav-current-bg); }

.rb-listingToolbar .rb-tableGrouping { order: 1; flex-basis: 100%; }

/* Grid view: no results frame. Cards sit on the page like the other white blocks (§17.226, §17.227). */
.rb-catalogResults--grid { margin-bottom: var(--rb-gap); }
/* At least 200px per card and never more than four per row (§17.232). */
.rb-catalogGrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(max(200px, calc((100% - 3 * var(--rb-gap)) / 4)), 1fr)); gap: var(--rb-gap); margin: 0; padding: 0; list-style: none; }
.rb-catalogGrid-group { margin: 20px 0 8px; font-size: 15px; color: var(--rb-text-heading); }
.rb-catalogGridWrap > .rb-catalogGrid-group:first-child { margin-top: 0; }
.rb-catalogGrid-group span { font-weight: 400; color: var(--rb-text-muted); }
.rb-gridCard { display: flex; flex-direction: column; min-width: 0; margin: 0; border: 1px solid var(--rb-border); border-radius: var(--rb-radius); background: var(--rb-bg-card); overflow: hidden; }
.rb-gridCard-image { display: block; aspect-ratio: 1; padding: 12px; background: #fff; }
.rb-gridCard-image img, .rb-gridCard-image .rb-imagePlaceholder { display: block; width: 100%; height: 100%; object-fit: contain; }
.rb-gridCard-body { display: flex; flex: 1; flex-direction: column; gap: 4px; padding: 10px 12px 12px; }
.rb-gridCard-name { font-size: 14px; font-weight: 600; line-height: 1.35; text-decoration: underline; text-underline-offset: 2px; }
.rb-gridCard-brand { font-size: 12px; color: var(--rb-text-muted); }
.rb-gridCard-oneLiner { margin: 4px 0 0; font-size: 13px; line-height: 1.45; color: var(--rb-text-body); }
.rb-gridCard-specs { margin: 4px 0 0; font-size: 12px; line-height: 1.5; }
.rb-gridCard-specs div { display: flex; gap: 6px; }
.rb-gridCard-specs dt { flex: none; color: var(--rb-text-muted); }
.rb-gridCard-specs dt::after { content: ":"; }
.rb-gridCard-specs dd { margin: 0; min-width: 0; }
.rb-gridCard-specs abbr { cursor: help; text-decoration: none; }
/* The crossed-out original on its own line, then the current price with its "with code" or "on sale" label (§17.231). */
.rb-gridCard-price { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 5px; margin-top: auto; }
.rb-gridCard-price .rb-price { font-size: 16px; font-weight: 700; white-space: nowrap; }
.rb-gridCard-price .rb-price--was { flex-basis: 100%; font-size: 12px; font-weight: 400; }
/* The sale saving leads the price when a listing is sorted by discount (§17.246). */
.rb-saving { display: inline-block; padding: 1px 6px; border-radius: 3px; background: var(--rb-positive-text); color: #fff; font-size: 11px; font-weight: 700; line-height: 1.5; white-space: nowrap; }
.rb-gridCard-price .rb-saving { order: -1; margin-bottom: 2px; }
.rb-gridCard-price .rb-saving + .rb-price--was { flex-basis: auto; }
.rb-gridCard-price .rb-saving ~ .rb-price:not(.rb-price--was) { flex-basis: 100%; }
.rb-catalogTable-price .rb-saving { margin-bottom: 3px; }
/* On the product page the chip leads the "You save" line (§17.249, §17.250). */
.rb-productPurchase .rb-saving { margin-right: 6px; padding: 1px 7px; font-size: 12px; }
/* The current price and its "on sale" or "with code" label never split across lines. */
.rb-productPurchase .rb-price--sale,
.rb-productPurchase .rb-price--coded { white-space: nowrap; }
.rb-gridCard-price .rb-price-qualifier { margin-left: 2px; font-size: 11px; }
/* The product page's build buttons, stacked full width under the price (§17.234). */
.rb-gridCard-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.rb-gridCard-actions form { margin: 0; }
.rb-gridCard-actions .rb-button { display: flex; align-items: center; justify-content: center; gap: 6px; width: 100%; }
.rb-gridCard-actions svg { flex: none; }
/* Phones: the shell runs edge to edge on a white page, so the grid is inset from the
   screen edges and cards take a light gray fill inside their border (§17.235). */
@media (max-width: 650px) {
    .rb-catalogGrid { grid-template-columns: repeat(2, minmax(0, 1fr)); padding: 0 10px; }
    .rb-catalogGrid-group { margin: 16px 10px 8px; }
    .rb-catalogGridWrap > .rb-catalogGrid-group:first-child { margin-top: 0; }
    .rb-listingToolbar { padding: 0 10px; }
    .rb-gridCard { background: var(--rb-bg-subtle); }
    .rb-gridCard-image { padding: 8px; }
    .rb-gridCard-body { padding: 8px; }
    .rb-gridCard-specs div { flex-wrap: wrap; column-gap: 4px; }
}
/* Cards replace the table whenever its columns would not fit the frame (§17.202, §17.207). */
.rb-catalogTableWrap--cards { overflow: visible; }
.rb-catalogTableWrap--cards .rb-catalogTable, .rb-catalogTableWrap--cards .rb-catalogTable :is(tbody, tr, th, td) { display: block; }
.rb-catalogTableWrap--cards .rb-catalogTable thead { display: none; }
.rb-catalogTableWrap--cards .rb-catalogTable tbody tr { position: relative; padding: 12px; border-bottom: 1px solid var(--rb-border); background: var(--rb-table-row); }
.rb-catalogTableWrap--cards .rb-catalogTable tbody tr > :is(th, td) { width: auto; min-width: 0; white-space: normal; max-width: none; padding: 0; border: 0; background: none; text-align: left; }
.rb-catalogTableWrap--cards .rb-catalogTable .rb-catalogTable-product { position: static; min-width: 0; width: auto; max-width: none; margin-bottom: 8px; padding-right: 100px; }
.rb-catalogTableWrap--cards .rb-catalogTable-thumbnail { flex-basis: 44px; }
.rb-catalogTableWrap--cards .rb-catalogTable-product img, .rb-catalogTableWrap--cards .rb-catalogTable-product .rb-imagePlaceholder { width: 44px; height: 44px; flex-basis: 44px; }
.rb-catalogTableWrap--cards .rb-catalogTable tbody td { display: inline-block; margin: 0 16px 2px 0; font-size: 13px; line-height: 1.5; }
.rb-catalogTableWrap--cards .rb-catalogTable tbody td::before { content: attr(data-label) ": "; color: var(--rb-text-muted); }
.rb-catalogTableWrap--cards .rb-catalogTable tbody td.rb-catalogTable-empty { display: none; }
.rb-catalogTableWrap--cards .rb-catalogTable tbody td.rb-catalogTable-price { position: absolute; top: 12px; right: 12px; margin: 0; text-align: right; }
.rb-catalogTableWrap--cards .rb-catalogTable tbody td.rb-catalogTable-price::before { content: none; }
.rb-catalogTableWrap--cards .rb-catalogTable .rb-catalogTable-groupRow { padding: 0; }
.rb-catalogTableWrap--cards .rb-catalogTable .rb-catalogTable-groupRow th { padding: 6px 12px; }

.rb-catalogTable-product .rb-imagePlaceholder { width: 52px; height: 52px; flex: 0 0 52px; }

/* --------------------------------------------------------------------------
   The build editor's rig diagram, next step and part chooser (§17.279)

   The diagram draws a build as the rig it is: steering wheel on the base,
   pedals under it, then the mount and the seat, with hand controls on the
   left and extras on the right. Tiles are links on the editor and plain boxes
   on the build page. Selected uses the sidebar's pale blue current style
   (§17.218), not the cream, which read as a warning here (§17.281). "Needed"
   is a to-do, so it stays cream, never red.
   -------------------------------------------------------------------------- */

.rb-nextStep {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 16px;
    margin: 0 0 8px;
    padding: 12px 14px;
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-left: 4px solid var(--rb-accent-blue);
    border-radius: 0;
}

.rb-nextStep--problem { border-left-color: var(--rb-error-border); background: var(--rb-error-bg); }
.rb-nextStep--todo { border-left-color: var(--rb-highlight-border); background: var(--rb-highlight-bg); }
.rb-nextStep--done { border-left-color: var(--rb-positive-border); background: var(--rb-positive-bg); }

.rb-nextStep-text { flex: 1 1 260px; min-width: 0; }
.rb-nextStep-title { margin: 0; font-size: 19px; font-weight: 700; line-height: 1.3; color: var(--rb-text-heading); }
.rb-nextStep-help { margin: 4px 0 0; font-size: 14px; line-height: 1.45; }
.rb-nextStep--problem .rb-nextStep-help { color: var(--rb-error-text); }
.rb-nextStep-list { margin: 6px 0 0; padding-left: 18px; font-size: 14px; line-height: 1.45; color: var(--rb-error-text); }
.rb-nextStep-list li + li { margin-top: 4px; }
/* Inside the Your Rig box now (§17.339), so it keeps a gap above the chips. */
.rb-block-body > .rb-nextStep { margin-bottom: 10px; }

.rb-steps {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 var(--rb-gap);
    padding: 0;
    list-style: none;
    font-size: 13px;
}

.rb-steps-item > a,
.rb-steps-item > span {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px 3px 4px;
    border: 1px solid var(--rb-border);
    border-radius: 999px;
    background: var(--rb-bg-card);
    color: var(--rb-text-body);
    text-decoration: none;
}

.rb-steps-item > a:hover { border-color: var(--rb-border-strong); }

.rb-steps-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border-strong);
    font-size: 11px;
    font-weight: 700;
}

.rb-steps-item--done .rb-steps-mark { background: var(--rb-positive-bg); border-color: var(--rb-positive-border); color: var(--rb-positive-text); }
.rb-steps-item--problem .rb-steps-mark { background: var(--rb-error-bg); border-color: var(--rb-error-border); color: var(--rb-error-text); }
.rb-steps-item--current > a,
.rb-steps-item--current > span { background: var(--rb-nav-current-bg); border-color: var(--rb-accent-blue); color: var(--rb-nav-current-text); font-weight: 700; }
.rb-steps-item--current .rb-steps-mark { border-color: var(--rb-accent-blue); }

/* --- the diagram --------------------------------------------------------- */

/* One column, opened section by section: each section's chooser sits
   directly under its tile (§17.310). */
.rb-rig { display: flex; flex-direction: column; gap: 8px; transition: opacity 0.15s; }
.rb-rig[aria-busy="true"] { opacity: 0.6; pointer-events: none; }
/* A change being saved in the background (§17.316). */
#primary[aria-busy="true"] { cursor: progress; }
#primary[aria-busy="true"] .rb-setup,
#primary[aria-busy="true"] .rb-buildEditor { opacity: 0.6; pointer-events: none; transition: opacity 0.15s; }
.rb-rigTile { scroll-margin-top: 100px; }

.rb-rig-sideTitle { margin: 14px 0 0; padding-bottom: 4px; border-bottom: 1px solid var(--rb-border); font-size: 15px; font-weight: 700; color: var(--rb-text-body); }

/* An open section is one box: its tile as the header, its choices under it,
   all inside the selected blue (§17.311). */
.rb-rigSection--open { background: var(--rb-bg-card); border: 2px solid var(--rb-accent-blue); border-radius: var(--rb-radius); overflow: hidden; }
.rb-rigSection--open > .rb-rigTile { border: 0; border-bottom: 1px solid var(--rb-border); border-radius: 0; }
/* The section's blue frame already shows it is open, so hovering its header
   does not recolor the line under it (§17.318). */
.rb-rigSection--open > a.rb-rigTile:hover { border-color: var(--rb-border); }
.rb-chooser-body { padding: 12px; }
.rb-rig-accessories > .rb-rigSection--open { grid-column: 1 / -1; }

/* How a part fits the part it connects to, on the right of its tile. */
.rb-rigTile-fit { flex-shrink: 0; margin-left: auto; }

/* Every accessory, in one grid under its heading (§17.313). */
.rb-rig-accessories { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 6px; }
/* Tiles in a row share one height, so the grid reads as a grid (§17.344).
   An empty tile is only its name and Add (§17.486), so no tile is held
   taller than its content. Long text is cut off. The open one is a header
   over its chooser and keeps its own height. */
.rb-rig-accessories > .rb-rigSection:not(.rb-rigSection--open) > .rb-rigTile { height: 100%; }
.rb-rig-accessories .rb-rigTile-meta,
.rb-rig-accessories .rb-rigTile-name { display: -webkit-box; -webkit-box-orient: vertical; overflow: hidden; }
.rb-rig-accessories .rb-rigTile-meta { -webkit-line-clamp: 3; }
.rb-rig-accessories .rb-rigTile-name { -webkit-line-clamp: 2; }

.rb-rig-notes { margin-top: 14px; }
/* What stops the rig working, between the platform line and the map (§17.337). */
.rb-rig-errors { margin: 0 0 14px; }

.rb-rigTile {
    display: flex;
    align-items: center;
    gap: 10px;
    min-width: 0;
    padding: 8px 10px;
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    color: var(--rb-text-body);
    text-decoration: none;
    line-height: 1.3;
}

/* The border shows the hover. The site underlines links on hover, which on a
   whole tile underlines every line of text in it. */
a.rb-rigTile:hover { border-color: var(--rb-accent-blue); text-decoration: none; }
a.rb-rigTile:focus-visible { outline: 2px solid var(--rb-accent-blue); outline-offset: 2px; }

/* Filled and empty must read differently at a glance (§17.292). A filled
   tile is solid, lifted, and carries a green bar down its left edge, the
   site's positive colour. An empty one is a faint grey slot with a dashed
   edge and a faded icon and label; its "+ Add" stays link blue. */
.rb-rigTile--filled { border-left: 4px solid var(--rb-positive-border); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08); }
.rb-rigTile--empty,
.rb-rigTile--missing,
.rb-rigTile--waiting { border-style: dashed; background: var(--rb-bg-subtle); }
.rb-rigTile--empty .rb-rigTile-media { opacity: 0.6; }
/* The label stays readable on the grey slot: only the icon is faded. */
.rb-rigTile--empty .rb-rigTile-label { color: #666; }
.dark .rb-rigTile--empty .rb-rigTile-label { color: #b5b5b5; }
.rb-rigTile--missing { border-color: var(--rb-highlight-border); }
.rb-rigTile--waiting { opacity: 0.55; }
.rb-rigTile--problem { background: var(--rb-error-bg); border-color: var(--rb-error-border); }
.rb-rigTile--next { border: 2px dashed var(--rb-accent-blue); }
.rb-rigTile--selected { background: var(--rb-nav-current-bg); border: 2px solid var(--rb-accent-blue); }

.rb-rigTile-media {
    flex: 0 0 60px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 60px;
    height: 60px;
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    color: var(--rb-text-muted);
    overflow: hidden;
}

.rb-rigTile--filled .rb-rigTile-media { background: #fff; }
.rb-rigTile-media img,
.rb-rigTile-media .rb-imagePlaceholder { display: block; width: 100%; height: 100%; object-fit: contain; }
/* Category icons sized for their box (§17.344). `flex: none` undoes the
   20px flex basis every category icon has elsewhere. */
.rb-rigTile-media .rb-category-icon { flex: none; width: 40px; height: 40px; }

.rb-rigTile-text { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.rb-rigTile-label { font-size: 13px; font-weight: 400; color: var(--rb-text-muted); }
.rb-rigTile-name { font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.rb-rigTile-meta { font-size: 12px; color: var(--rb-text-muted); }
.rb-rigTile-add { font-size: 14px; font-weight: 600; color: var(--rb-text-link); }
.rb-rigTile-add::before { content: "+ "; }

.rb-rigTile-flag {
    display: inline-block;
    margin-left: 4px;
    padding: 0 5px;
    font-size: 10px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--rb-highlight-text);
    background: var(--rb-highlight-bg);
    border: 1px solid var(--rb-highlight-border);
    border-radius: var(--rb-radius);
}

/* "Optional" on an accessory: quiet, beside the yellow "Needed" (§17.313). */
.rb-rigTile-flag--included { color: var(--rb-positive-text); background: var(--rb-positive-bg); border-color: var(--rb-positive-border); }

.rb-rigTile-flag--problem { color: var(--rb-error-text); background: var(--rb-error-bg); border-color: var(--rb-error-border); }

/* Side tiles are smaller: an icon, the category and the part. */
.rb-rigTile--compact { gap: 8px; padding: 6px 8px; }
/* The same 44px box with or without a photo, so the text beside it lines up
   across a row of filled and empty accessories (§17.317, §17.344). */
.rb-rigTile--compact .rb-rigTile-media { flex-basis: 44px; width: 44px; height: 44px; background: none; }
.rb-rigTile--compact .rb-rigTile-media .rb-category-icon { width: 32px; height: 32px; }
.rb-rigTile--compact.rb-rigTile--filled .rb-rigTile-media { background: #fff; }
/* A filled tile's green edge is 3px wider than an empty tile's border, so it
   gives 3px of padding back and its contents stay in line (§17.317). */
.rb-rigTile--filled { padding-left: 7px; }
.rb-rigTile--compact.rb-rigTile--filled { padding-left: 5px; }
.rb-rigTile--compact.rb-rigTile--filled .rb-rigTile-media:has(.rb-category-icon) { background: none; }
.rb-rigTile--compact .rb-rigTile-name,
.rb-rigTile--compact .rb-rigTile-add { font-size: 13px; }

/* --- the chooser --------------------------------------------------------- */

/* The script moves focus here for screen readers; the block itself needs no ring. */
.rb-chooser:focus { outline: none; }
.rb-chooser-held { margin-bottom: 12px; padding-bottom: 8px; border-bottom: 1px solid var(--rb-border); }

/* The part a position holds, as a card (§17.291): photo on the left, the
   product page's chips, one-liner and price on the right, and the way to
   that page as a button. */
.rb-currentParts { display: flex; flex-direction: column; gap: 10px; margin: 0 0 14px; padding: 0 0 14px; list-style: none; border-bottom: 1px solid var(--rb-border); }
.rb-currentPart { display: grid; grid-template-columns: 160px minmax(0, 1fr); gap: 16px; align-items: start; }
.rb-currentPart-image { display: block; height: 160px; padding: 10px; background: #fff; border: 1px solid var(--rb-border); border-radius: var(--rb-radius); }
.rb-currentPart-image img,
.rb-currentPart-image .rb-imagePlaceholder { display: block; width: 100%; height: 100%; object-fit: contain; }
.rb-currentPart-body { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.rb-currentPart-name { font-size: 18px; font-weight: 700; line-height: 1.3; color: var(--rb-text-heading); }
a.rb-currentPart-name { color: var(--rb-text-link); }
.rb-currentPart-meta { font-size: 13px; color: var(--rb-text-muted); }
.rb-currentPart-oneLiner { margin: 0; font-size: 14px; line-height: 1.5; }
.rb-currentPart-price { margin: 0; }
.rb-currentPart-price .rb-price { font-size: 17px; font-weight: 700; }
.rb-currentPart-priceNote { font-size: 12px; color: var(--rb-text-muted); }
.rb-currentPart-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 4px; }
.rb-currentPart-role { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.rb-currentPart-role select { width: auto; }

/* Remove is a real button with a red tint, so it is easy to find but still
   reads as the one that takes something away. It keeps every button's depth
   (§17.215): the same light-top, dark-bottom gradient and lift, in red. */
/* Remove, and the editor's Delete Build (§17.344): red buttons. */
.rb-currentPart-remove.rb-button--danger,
.rb-editorDelete-button.rb-button--danger { color: var(--rb-error-text); background: linear-gradient(180deg, #fff7f7, #f3d4d4); border-color: var(--rb-error-border); }
.rb-currentPart-remove.rb-button--danger:hover,
.rb-editorDelete-button.rb-button--danger:hover { background: linear-gradient(180deg, #fff7f7, #ecc2c2); }
.dark .rb-currentPart-remove.rb-button--danger,
.dark .rb-editorDelete-button.rb-button--danger { color: #ffd9da; background: linear-gradient(180deg, #6e2a2a, #4a1414); border-color: var(--rb-error-border); }
.dark .rb-currentPart-remove.rb-button--danger:hover,
.dark .rb-editorDelete-button.rb-button--danger:hover { background: linear-gradient(180deg, #7d3232, #561a1a); }

@media (max-width: 650px) {
    .rb-currentPart { grid-template-columns: 96px minmax(0, 1fr); gap: 12px; }
    .rb-currentPart-image { height: 96px; padding: 6px; }
    .rb-currentPart-name { font-size: 16px; }
}
.rb-chooser-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 12px; margin: 0 0 8px; }
.rb-chooser-title { margin: 0; font-size: 16px; font-weight: 700; color: var(--rb-text-heading); }
.rb-chooser-order { margin: 0; font-size: 12px; color: var(--rb-text-muted); }
/* The category page's filters and sorts inside the chooser (§17.375). */
.rb-chooserFilters { margin: 0 0 12px; padding: 0 0 10px; border-bottom: 1px solid var(--rb-border); font-size: 13px; }
.rb-chooserFilters-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 12px; font-size: 13px; }
.rb-chooserFilters-bar label { font-weight: 600; }
.rb-chooserFilters-bar .rb-input { flex: 0 1 auto; width: auto; max-width: 100%; }
.rb-chooserFilters-count { margin-left: auto; color: var(--rb-text-muted); }
.rb-chooserFilters .rb-filterFooter { margin-top: 12px; padding-top: 10px; }
.is-live .rb-chooserFilters-panel .rb-filterActions button[type="submit"],
.rb-chooserFilters.is-live .rb-filterActions button[type="submit"] { display: none; }
.rb-chooserFilters.is-live .rb-filterFooter:not(:has(.rb-filterActions a)) { display: none; }
.rb-chooser-empty { margin: 0 0 8px; font-size: 14px; color: var(--rb-text-muted); }
.rb-chooser-note { margin: 6px 0; font-size: 12px; color: var(--rb-text-muted); }
.rb-chooser-browse { margin: 12px 0 0; font-size: 13px; }

.rb-chooser-more { margin-top: 10px; font-size: 14px; }
.rb-chooser-more > summary { cursor: pointer; color: var(--rb-text-link); font-weight: 600; }
.rb-chooser-more > .rb-suggest { margin-top: 10px; }

.rb-chooser-list { margin: 6px 0 0; padding: 0; list-style: none; border: 1px solid var(--rb-border); border-radius: var(--rb-radius); }
.rb-chooser-row { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 10px; padding: 6px 10px; border-bottom: 1px solid var(--rb-border); font-size: 13px; }
.rb-chooser-row:last-child { border-bottom: 0; }
.rb-chooser-rowName { flex: 1 1 auto; min-width: 0; font-weight: 600; }
.rb-chooser-rowBrand { font-weight: 400; font-size: 12px; color: var(--rb-text-muted); }
.rb-chooser-rowReason { flex: 1 1 100%; order: 3; font-size: 12px; color: var(--rb-text-muted); }
.rb-chooser-more--no .rb-chooser-row { opacity: 0.75; }

/* Three across, so the six shown first make two full rows (two on phones). */
.rb-suggest {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin: 0;
    padding: 0;
    list-style: none;
}

.rb-suggestCard {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
    overflow: hidden;
}

.rb-suggestCard-image { display: block; height: 150px; padding: 10px; background: #fff; }
.rb-suggestCard-image img,
.rb-suggestCard-image .rb-imagePlaceholder { display: block; width: 100%; height: 100%; object-fit: contain; }
.rb-suggestCard-body { display: flex; flex: 1; flex-direction: column; gap: 3px; padding: 8px 10px 10px; }
.rb-suggestCard-name { font-size: 14px; font-weight: 600; line-height: 1.3; }
.rb-suggestCard-brand { font-size: 12px; color: var(--rb-text-muted); }
.rb-suggestCard-fit { margin-top: 2px; }
.rb-suggestCard-reason { font-size: 12px; line-height: 1.4; color: var(--rb-text-muted); }
/* Key specs and what else is in the box (§17.305). */
.rb-suggestCard-body > .rb-chips { margin: 2px 0 0; }
.rb-suggestCard-includes { font-size: 12px; font-weight: 600; line-height: 1.4; color: var(--rb-positive-text); }
.rb-suggestCard-reason--conflict { color: var(--rb-highlight-text); }
.rb-chooser-note--switch { margin: 0 0 10px; font-size: 13px; color: var(--rb-text-body); }
.rb-suggest + .rb-chooser-head { margin-top: 18px; }
.rb-suggestCard-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px; margin-top: auto; padding-top: 8px; }
.rb-suggestCard-price .rb-price { font-size: 15px; font-weight: 700; white-space: nowrap; }
.rb-suggestCard-add { padding: 3px 14px; }
.rb-chooser-row .rb-suggestCard-add { margin-left: auto; padding: 2px 10px; font-size: 12px; }

/* Where the rig lives: three large choices. */
.rb-mountChoice { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; margin: 0 0 14px; }

.rb-mountChoice-option {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 14px 10px;
    font: inherit;
    text-align: center;
    color: var(--rb-text-body);
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    cursor: pointer;
}

.rb-mountChoice-option:hover { border-color: var(--rb-accent-blue); }
.rb-mountChoice-option:focus-visible { outline: 2px solid var(--rb-accent-blue); outline-offset: 3px; }
.rb-mountChoice-option .rb-category-icon { width: 32px; height: 32px; color: var(--rb-text-muted); }
.rb-mountChoice-option--current { background: var(--rb-nav-current-bg); border: 2px solid var(--rb-accent-blue); }
.rb-mountChoice-label { font-size: 15px; font-weight: 700; }
.rb-mountChoice-hint { font-size: 12px; line-height: 1.35; color: var(--rb-text-muted); }

/* Plays On: its tile above the rig, and its chooser's cards, which tick
   rather than submit, since a reader can play on more than one (§17.309). */
.rb-rigPlatforms .rb-rigTile-media { background: none; }
.rb-platformChoice-lede { margin: 0 0 12px; }
/* The checkbox sits where a mounting card has its icon. */
.rb-platformOption-input { width: 20px; height: 20px; margin: 0 0 2px; accent-color: var(--rb-accent-blue); }
.rb-platformOption:has(.rb-platformOption-input:checked) { background: var(--rb-nav-current-bg); border: 2px solid var(--rb-accent-blue); }
.rb-platformOption:has(.rb-platformOption-input:focus-visible) { outline: 2px solid var(--rb-accent-blue); outline-offset: 3px; }
.rb-platformChoice-save { min-width: 160px; }

/* --- the setup bar (§17.281, §17.287) -----------------------------------
   The build's name and the tray in one bar across the top of the editor.
   Platforms and mounting have their own tiles with the parts (§17.303,
   §17.309). It scrolls with the page (§17.286). */

.rb-setup {
    margin: 0 0 var(--rb-gap);
    padding: 10px 12px;
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-setup-fields { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 16px; }
.rb-setup-field { display: flex; flex-direction: column; gap: 4px; min-width: 0; margin: 0; padding: 0; border: 0; }
.rb-setup-field--name { flex: 1 1 220px; }
.rb-setup-field--name .rb-input { width: 100%; }
.rb-setup-label { display: block; padding: 0; font-size: 14px; font-weight: 700; color: var(--rb-text-body); }
.rb-setup-field select { width: auto; }
.rb-setup-unit { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.rb-setup-unit .rb-input { width: 90px; }
/* The name is the page's title, so it is set like one (§17.339). */
.rb-setup .rb-setup-nameInput { height: auto; padding: 6px 10px; font-size: 24px; font-weight: 700; line-height: 1.3; color: var(--rb-text-heading); }
.rb-setup .rb-setup-nameInput::placeholder { color: var(--rb-text-heading); opacity: 0.55; }

/* "Saving…" and "Saved" beside the name's label, so nothing moves (§17.335). */
.rb-setup-labelRow { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }
.rb-setup-saved { font-size: 12px; color: var(--rb-text-muted); }
.rb-setup-saved--done { color: var(--rb-positive-text); }

/* Desk thickness, under the mounting choices once a desk is chosen (§17.303). */
.rb-mountThickness { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: -4px 0 14px; }
.rb-mountThickness-help { flex-basis: 100%; margin: 0; font-size: 12px; color: var(--rb-text-muted); }

.rb-setup-status { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 20px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--rb-border); }

.rb-summaryBar-facts { display: flex; flex-wrap: wrap; gap: 4px 20px; margin: 0; }
.rb-summaryBar-facts > div { display: flex; align-items: baseline; gap: 6px; }
.rb-summaryBar-facts dt { font-size: 13px; color: var(--rb-text-muted); }
.rb-summaryBar-facts dd { margin: 0; font-size: 15px; font-weight: 600; }
/* What a build plays on, one pill per platform (§17.307). */
.rb-platformPills { display: inline-flex; flex-wrap: wrap; gap: 2px 12px; vertical-align: middle; }
.rb-platformPill { display: inline-flex; align-items: center; gap: 3px; font-size: 13px; font-weight: 600; }
.rb-platformPill--yes { color: var(--rb-positive-text); }
.rb-platformPill--no { color: var(--rb-text-muted); font-weight: 400; }
.rb-platformPill-mark { font-size: 12px; }

/* Beside "Complete": how many connections nobody has verified (§17.306). */
.rb-stateToCheck { font-size: 12px; font-weight: 600; color: var(--rb-highlight-text); white-space: nowrap; }
a.rb-stateToCheck:hover { color: var(--rb-highlight-text); }
.rb-rig-notes { scroll-margin-top: 100px; }

/* The editor's price list, behind a click (§17.308). */
.rb-costToggle > summary { cursor: pointer; font-size: 14px; font-weight: 600; color: var(--rb-text-link); }
.rb-costToggle[open] > summary { margin-bottom: 12px; }
.rb-summaryBar-saving { font-size: 12px; font-weight: 600; color: var(--rb-positive-text); }
.rb-summaryBar-note { margin: 8px 0 0; font-size: 12px; color: var(--rb-text-muted); }

@media (max-width: 650px) {
    .rb-suggest { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
    .rb-editorActions { flex: 1 1 100%; margin-left: 0; }
    .rb-editorActions .rb-button { flex: 1 1 0; justify-content: center; text-align: center; }
    .rb-editorActions .rb-editorActions-done { flex-grow: 2; }
    .rb-editorFoot .rb-editorDelete { order: 1; flex: 1 1 100%; text-align: center; }
    .rb-setup .rb-setup-nameInput { font-size: 20px; }
    .rb-suggestCard-image { height: 100px; padding: 6px; }
    .rb-mountChoice { grid-template-columns: minmax(0, 1fr); }
    .rb-mountChoice-option { flex-direction: row; flex-wrap: wrap; text-align: left; column-gap: 10px; }
    .rb-mountChoice-hint { flex-basis: 100%; }
    .rb-nextStep-title { font-size: 17px; }
}

/* --- a saved build, read-only: one column like the editor ---------------- */

/* The card over a saved build: facts about the build, not its parts
   (§17.331). The state with where it came from under it on the left, the
   reader's buttons on the right, in one row. */
.rb-buildHead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 14px 24px; padding: 14px 16px; }
.rb-buildHead p { margin: 0; }
.rb-buildHead-status { display: flex; flex-direction: column; align-items: flex-start; gap: 6px; min-width: 0; }
.rb-buildHead-meta { display: flex; flex-wrap: wrap; gap: 2px 14px; font-size: 13px; color: var(--rb-text-muted); }
.rb-buildHead-label { font-size: 13px; font-weight: 400; color: var(--rb-text-muted); }
.rb-buildHead-note { max-width: 520px; font-size: 14px; line-height: 1.5; color: var(--rb-text-body); }

/* What the build plays on, over its map (§17.330). */
.rb-rigPlays { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 14px; }

.rb-buildHead-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; }
.rb-buildHead-actions form { margin: 0; }
/* The same size as the editor's buttons (§17.342). */
.rb-buildHead-actions .rb-button { display: inline-flex; align-items: center; justify-content: center; text-decoration: none; }
/* Share copies the build's link (§17.332): narrower, with a link icon, and
   "Link copied" for a moment once it has. */
.rb-buildHead-actions .rb-buildHead-share { gap: 8px; min-width: 0; }
.rb-buildHead-shareIcon { flex: none; }
.rb-buildHead-share.is-done { color: var(--rb-positive-text); border-color: var(--rb-positive-border); }

/* The build's state, the loudest thing in the card: a solid badge with a
   mark, in the colour of its answer. */
.rb-buildHead-state .rb-compatChip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px;
    font-size: 15px;
    font-weight: 700;
    line-height: 1.2;
    color: #fff;
    border: 0;
    border-radius: var(--rb-radius);
}
.rb-buildHead-state .rb-compatChip::before { font-size: 14px; }
.rb-buildHead-state .rb-compatChip--native { background: var(--rb-buy-bg); }
.rb-buildHead-state .rb-compatChip--native::before { content: "\2713"; }
.rb-buildHead-state .rb-compatChip--incompatible { background: #b3261e; }
.rb-buildHead-state .rb-compatChip--incompatible::before { content: "\26A0"; }
/* In progress is not a warning, so it is a calm slate rather than yellow,
   and not blue, which would read as a button beside Edit Build (§17.327). */
.rb-buildHead-state .rb-compatChip--unknown { color: #fff; background: #5b6776; }
.rb-buildHead-state .rb-compatChip--unknown::before { content: "\25D0"; }


@media (max-width: 650px) {
    .rb-buildHead { padding: 12px; }
    .rb-buildHead-actions { flex: 1 1 100%; }
    /* The main button across the width, the others side by side under it. */
    .rb-buildHead-actions > * { flex: 1 1 0; }
    .rb-buildHead-actions > :first-child { flex-basis: 100%; }
    .rb-buildHead-actions > .rb-buildHead-share:not(:first-child) { flex: 0 0 auto; width: auto; padding-left: 18px; padding-right: 18px; }
    /* Alone on its row, under Copy & Customize, it takes the whole width. */
    .rb-buildHead-actions > :first-child + .rb-buildHead-share:last-child { flex: 1 1 100%; width: 100%; }
    .rb-buildHead-actions .rb-button { width: 100%; min-width: 0; }
}

/* --------------------------------------------------------------------------
   The connection map on the build page (§17.300)

   The build drawn the way it goes together, readable at a glance: parts in
   place, lines between the parts that connect, one badge per line. Solid
   lines mount, dashed lines are cables. The sentences live in the panel
   under the map and open when a part or a badge is selected.
   -------------------------------------------------------------------------- */

.rb-map { position: relative; }

.rb-map-stage {
    --rb-map-gap: 48px;
    display: grid;
    /* Room for a box's name on an outline around the top row. */
    padding-top: 12px;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr) minmax(0, 1fr);
    column-gap: var(--rb-map-gap);
    row-gap: 40px;
    align-items: center;
}

.rb-map-cell { display: flex; flex-direction: column; gap: 12px; min-width: 0; }
.rb-map-cell--left { grid-column: 1; }
.rb-map-cell--spine { grid-column: 2; }
.rb-map-cell--right { grid-column: 3; }

/* A side with nothing in it is dropped and the rest centered, each column
   keeping the width it has in the full three-column map (§17.322). */
.rb-map-stage--noLeft,
.rb-map-stage--noRight { width: calc((100% - 2 * var(--rb-map-gap)) * 2.15 / 3.15 + var(--rb-map-gap)); margin: 0 auto; }
.rb-map-stage--noLeft { grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr); }
.rb-map-stage--noLeft .rb-map-cell--spine { grid-column: 1; }
.rb-map-stage--noLeft .rb-map-cell--right { grid-column: 2; }
.rb-map-stage--noRight { grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); }
.rb-map-stage.rb-map-stage--noLeft.rb-map-stage--noRight { width: calc((100% - 2 * var(--rb-map-gap)) * 1.15 / 3.15); grid-template-columns: minmax(0, 1fr); }
.rb-map-stage--noLeft.rb-map-stage--noRight .rb-map-cell--spine { grid-column: 1; }

/* The foundation: the cockpit, stand, or desk everything above sits on,
   drawn as a platform across the whole rig. */
.rb-map-foundation {
    display: flex;
    justify-content: center;
    gap: 48px;
    margin-top: 40px;
    padding: 12px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border-strong);
    border-bottom-width: 4px;
    border-radius: var(--rb-radius);
}

.rb-map-foundation .rb-mapNode { flex: 0 1 260px; }

/* The motion platform the frame sits on: the same platform, one level down. */
.rb-map-motion { border-bottom-width: 6px; }

/* Parts with no place of their own on the map, in a plain row under it. */
.rb-map-extra { margin-top: 20px; }
.rb-map-extraTitle { margin: 0 0 6px; font-size: 15px; font-weight: 700; color: var(--rb-text-body); }
.rb-map-extraParts { display: flex; flex-wrap: wrap; gap: 10px; }
.rb-map-extraParts .rb-mapNode { flex: 0 1 240px; }

/* --- a part -------------------------------------------------------------- */

.rb-mapNode {
    position: relative;
    z-index: 1;
    min-width: 0;
    padding: 8px 10px;
    background: var(--rb-bg-card);
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.08);
    line-height: 1.3;
    cursor: pointer;
    transition: opacity 0.15s, border-color 0.15s;
}

.rb-mapNode:hover { border-color: var(--rb-accent-blue); }
.rb-mapNode:has(.rb-mapNode-head:focus-visible) { outline: 2px solid var(--rb-accent-blue); outline-offset: 2px; }

/* The part's photo, name, and price: the button that opens it in place (§17.376). */
.rb-mapNode-head { display: flex; align-items: center; gap: 10px; min-width: 0; outline: none; }
.rb-mapNode-price { margin-top: 2px; font-size: 13px; }
.rb-mapNode-price .rb-price { font-weight: 700; }
/* A build line that ships later (§17.378): the shared caution colours. */
.rb-storeGroup-delayed { display: inline-block; margin-left: 4px; padding: 0 6px; border: 1px solid var(--rb-highlight-border); border-radius: 10px; background: var(--rb-highlight-bg); color: var(--rb-highlight-text); font-size: 11px; font-weight: 700; }
.rb-costTotal-note--delayed { color: var(--rb-highlight-text); }
.rb-mapNode-priceFor { font-size: 11px; color: var(--rb-text-muted); }

/* What a selected part opens to, under its photo and name. */
.rb-mapNode-details { margin-top: 8px; cursor: auto; font-size: 13px; }
.rb-mapNode-links { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.rb-mapNode-notes { display: grid; gap: 6px; margin: 8px 0 0; padding: 0; list-style: none; line-height: 1.4; color: var(--rb-text-body); }
.rb-mapNode-view { padding: 3px 12px; font-size: 12px; }

.rb-mapNode-media {
    flex: 0 0 56px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    background: #fff;
    border-radius: var(--rb-radius);
    overflow: hidden;
    color: var(--rb-text-muted);
}

.rb-mapNode-media img { display: block; width: 100%; height: 100%; object-fit: contain; }
.rb-mapNode--icon .rb-mapNode-media { background: var(--rb-bg-subtle); }
/* The base icon rule fixes its flex basis at 20px, which beats a width here. */
.rb-mapNode-media .rb-category-icon { flex: none; width: 28px; height: 28px; }

.rb-mapNode--left .rb-mapNode-media,
.rb-mapNode--right .rb-mapNode-media { flex-basis: 40px; width: 40px; height: 40px; }
.rb-mapNode--left .rb-mapNode-media .rb-category-icon,
.rb-mapNode--right .rb-mapNode-media .rb-category-icon { width: 22px; height: 22px; }

/* A part shown by its icon (it has no photo of its own) fills its box the
   way a photo would, so it does not read as an empty slot. */
.rb-mapNode--icon .rb-mapNode-media { color: var(--rb-text-body); }
.rb-mapNode--icon .rb-mapNode-media .rb-category-icon { width: 42px; height: 42px; }
.rb-mapNode--icon.rb-mapNode--left .rb-mapNode-media .rb-category-icon,
.rb-mapNode--icon.rb-mapNode--right .rb-mapNode-media .rb-category-icon { width: 30px; height: 30px; }

.rb-mapNode-text { display: flex; flex-direction: column; min-width: 0; }
.rb-mapNode-label { font-size: 12px; font-weight: 400; color: var(--rb-text-muted); }
.rb-mapNode-name { font-size: 14px; font-weight: 600; color: var(--rb-text-body); overflow-wrap: break-word; hyphens: auto; }
.rb-mapNode--left .rb-mapNode-name,
.rb-mapNode--right .rb-mapNode-name { font-size: 13px; }

.rb-mapNode--problem { background: var(--rb-error-bg); border-color: var(--rb-error-border); }
.rb-mapNode--missing { background: var(--rb-bg-subtle); border-style: dashed; border-color: var(--rb-highlight-border); box-shadow: none; }
.rb-mapNode--missing .rb-mapNode-name { font-weight: 400; color: var(--rb-text-muted); }

/* --- the lines and their badges ------------------------------------------ */

.rb-map-lines {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
}

.rb-map-lines path { fill: none; stroke: var(--rb-border-strong); stroke-width: 2; transition: opacity 0.15s, stroke 0.15s; }
.dark .rb-map-lines path { stroke: #6a6a6a; }
.rb-map-lines path[data-kind="cable"] { stroke-dasharray: 5 4; }
.rb-map-lines path[data-status="incompatible"] { stroke: var(--rb-error-border); }

/* Hidden until the script has placed them; without it there are no lines. */
.rb-mapEdge { display: none; }

.rb-map--ready .rb-mapEdge {
    position: absolute;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin: -11px 0 0 -11px;
    padding: 0;
    font-size: 12px;
    font-weight: 700;
    line-height: 1;
    color: #fff;
    background: var(--rb-buy-bg);
    border: 2px solid var(--rb-bg-card);
    border-radius: 50%;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.12);
    cursor: pointer;
    transition: opacity 0.15s, transform 0.15s;
}

.rb-map--ready .rb-mapEdge:hover,
.rb-map--ready .rb-mapEdge:focus-visible { transform: scale(1.2); outline: none; }
.rb-map--ready .rb-mapEdge--with_adapter { color: #3d3000; background: #e3b93c; }
.rb-map--ready .rb-mapEdge--incompatible { background: var(--rb-error-border); }
.rb-map--ready .rb-mapEdge--unknown { background: #8c8c8c; }

/* Something selected: it and what it connects to stay; the rest fades. */
.rb-map--focus .rb-mapNode:not(.is-lit),
.rb-map--focus .rb-mapEdge:not(.is-lit) { opacity: 0.3; }
.rb-map--focus .rb-map-lines path:not(.is-lit) { opacity: 0.2; }
.rb-map--focus .rb-map-lines path.is-lit { stroke: var(--rb-accent-blue); }
.rb-map--focus .rb-map-lines path.is-lit[data-status="incompatible"] { stroke: var(--rb-error-border); }
.rb-mapNode.is-selected { border: 2px solid var(--rb-accent-blue); padding: 7px 9px; }

/* Parts that came in one box: a dashed outline with the box's name on it. */
.rb-map-lines .rb-mapBundle { fill: none; stroke: var(--rb-text-muted); stroke-width: 1; stroke-dasharray: 3 3; }
.rb-mapBundle-label {
    position: absolute;
    z-index: 2;
    overflow: hidden;
    padding: 0 5px;
    font-size: 12px;
    font-weight: 400;
    line-height: 14px;
    white-space: nowrap;
    text-overflow: ellipsis;
    color: var(--rb-text-muted);
    background: var(--rb-bg-card);
    transform: translateY(-50%);
    pointer-events: none;
}
.rb-mapBundle-label--foundation { border: 1px solid var(--rb-border-strong); border-radius: var(--rb-radius); }
.rb-map--focus .rb-map-lines .rb-mapBundle,
/* Faded by its text and edge only: its background stays solid, so it still
   covers the line or platform edge it sits on. */
.rb-map--focus .rb-mapBundle-label {
    color: color-mix(in srgb, var(--rb-text-muted) 30%, var(--rb-bg-card));
    border-color: color-mix(in srgb, var(--rb-border-strong) 30%, var(--rb-bg-card));
}

.rb-map-legend { display: flex; justify-content: flex-end; gap: 16px; margin: 8px 0 0; font-size: 11px; color: var(--rb-text-muted); }
.rb-map-key::before { content: ""; display: inline-block; width: 22px; margin-right: 6px; vertical-align: middle; border-top: 2px solid var(--rb-border-strong); }
.rb-map-key--cable::before { border-top-style: dashed; }
/* The legend describes lines, so it only shows once there are lines. */
.rb-map:not(.rb-map--ready) .rb-map-legend { display: none; }

/* --- the panel under the map --------------------------------------------
   Where the sentences are, so it is set for reading: body-size text, the
   notes in the body colour, and room between the lines. */

.rb-mapPanel {
    margin-top: 16px;
    padding: 14px 16px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    font-size: 15px;
    line-height: 1.5;
}

.rb-mapPanel-view[hidden] { display: none; }

.rb-mapPanel-verdict { margin: 0; font-size: 18px; font-weight: 700; line-height: 1.3; }
.rb-mapPanel-verdict--ok::before { content: "\2713\00a0"; color: var(--rb-positive-text); }
.rb-mapPanel-verdict--no { color: var(--rb-error-text); }

.rb-mapPanel-title { margin: 0 0 8px; font-size: 18px; font-weight: 700; line-height: 1.3; }
.rb-mapPanel-through { font-size: 14px; font-weight: 400; color: var(--rb-text-muted); }

/* The selected part: its photo beside its name. */
.rb-mapPanel-part { display: flex; align-items: center; gap: 14px; }
.rb-mapPanel-part .rb-mapPanel-title { margin: 0; }
.rb-mapPanel-through { display: block; margin-top: 2px; }
.rb-mapPanel-photo,
.rb-mapPanel-thumb {
    flex: none;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    color: var(--rb-text-body);
}
.rb-mapPanel-photo { width: 88px; height: 88px; padding: 6px; }
.rb-mapPanel-thumb { width: 48px; height: 48px; padding: 3px; }
.rb-mapPanel-photo img,
.rb-mapPanel-thumb img { display: block; width: 100%; height: 100%; object-fit: contain; }
.rb-mapPanel-photo .rb-category-icon { flex: none; width: 48px; height: 48px; }
.rb-mapPanel-thumb .rb-category-icon { flex: none; width: 28px; height: 28px; }
.dark .rb-mapPanel-photo:has(.rb-category-icon),
.dark .rb-mapPanel-thumb:has(.rb-category-icon) { background: var(--rb-bg-card); }

/* What the list under it is, in words. */

.rb-mapPanel-lines { margin: 0; padding: 0; list-style: none; }
.rb-mapPanel-line { display: flex; align-items: flex-start; gap: 12px; padding: 12px 0; border-top: 1px solid var(--rb-border); }
.rb-mapPanel-line:first-child { border-top: 0; }
.rb-mapPanel-line:last-child { padding-bottom: 0; }
.rb-mapPanel-body { display: flex; flex-direction: column; min-width: 0; }
.rb-mapPanel-head { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; }
.rb-mapPanel-with { font-size: 16px; font-weight: 600; }
.rb-mapPanel-note { display: block; margin-top: 4px; font-size: 15px; color: var(--rb-text-body); }

/* How the two connect, drawn with the same line as on the map. */
.rb-mapPanel-how { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--rb-text-muted); }
.rb-mapPanel-how::before { content: ""; width: 16px; border-top: 2px solid var(--rb-text-muted); }
.rb-mapPanel-how--cable::before { border-top-style: dashed; }
.rb-mapPanel-line--incompatible .rb-mapPanel-note { color: var(--rb-error-text); }

.rb-mapPanel-all { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--rb-border); }
.rb-mapPanel-all > summary { font-size: 15px; font-weight: 600; cursor: pointer; color: var(--rb-text-link); }
.rb-mapPanel-all > .rb-compatList { margin-top: 8px; }
.rb-mapPanel-all .rb-compatList-item { padding: 10px 0; font-size: 15px; }
.rb-mapPanel-all .rb-compatList-detail { margin-top: 4px; font-size: 14px; color: var(--rb-text-body); }
.rb-mapPanel-all .rb-specTable-note { font-size: 13px; }

@media (max-width: 650px) {
    /*
     * One column on a phone (§17.324). Each spine part runs full width, and
     * the parts beside it in its row sit under it, indented, so they read as
     * a different kind of part hanging off it. The spine's line runs down the
     * left edge, under the photos, and passes the indented parts; each
     * indented part's line turns up (or down) into the part it connects to.
     */
    .rb-map-stage,
    .rb-map-stage.rb-map-stage--noLeft,
    .rb-map-stage.rb-map-stage--noRight,
    .rb-map-stage.rb-map-stage--noLeft.rb-map-stage--noRight { display: flex; flex-direction: column; align-items: stretch; gap: 12px; width: auto; margin-top: -18px; }
    .rb-map-cell { order: var(--rb-order); }
    .rb-map-cell--spine { margin-top: 18px; }
    .rb-map-cell--left,
    .rb-map-cell--right { margin-left: 72px; }
    .rb-map-stage .rb-mapNode { padding: 6px; }
    .rb-map-stage .rb-mapNode.is-selected { padding: 5px; }
    .rb-map-stage .rb-mapNode-media { flex: 0 0 44px; width: 44px; height: 44px; }
    .rb-map-stage .rb-mapNode--left .rb-mapNode-media,
    .rb-map-stage .rb-mapNode--right .rb-mapNode-media { flex-basis: 34px; width: 34px; height: 34px; }
    .rb-map-stage .rb-mapNode .rb-mapNode-name { font-size: 13px; }

    .rb-map-foundation { gap: 16px; margin-top: 34px; padding: 8px; }
    .rb-map-foundation .rb-mapNode { flex: 1 1 0; }

    /* The platform keeps its parts side by side: photo on top, words under it. */
    .rb-map-foundation .rb-mapNode { padding: 6px; text-align: center; }
    .rb-map-foundation .rb-mapNode-head { flex-direction: column; gap: 4px; }
    .rb-map-foundation .rb-mapNode-details { text-align: left; }
    /* An open part takes the platform's full width, so its details are not squeezed (§17.376). */
    .rb-map-foundation { flex-wrap: wrap; }
    .rb-map-foundation .rb-mapNode.is-open { flex: 1 1 100%; }
    .rb-map-foundation .rb-mapNode.is-selected { padding: 5px; }
    .rb-map-foundation .rb-mapNode-media { flex-basis: auto; width: 44px; height: 44px; }
    .rb-mapNode--icon .rb-mapNode-media .rb-category-icon { width: 32px; height: 32px; }
    .rb-mapNode--icon.rb-mapNode--left .rb-mapNode-media .rb-category-icon,
    .rb-mapNode--icon.rb-mapNode--right .rb-mapNode-media .rb-category-icon { width: 26px; height: 26px; }
    .rb-mapNode-label { font-size: 11px; }
    .rb-mapPanel { padding: 12px; }
    .rb-mapPanel-photo { width: 64px; height: 64px; }
    .rb-mapPanel-thumb { width: 40px; height: 40px; }
    .rb-mapNode-name,
    .rb-mapNode--left .rb-mapNode-name,
    .rb-mapNode--right .rb-mapNode-name {
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
        overflow: hidden;
        font-size: 11px;
    }
}

/* --------------------------------------------------------------------------
   Recommended Builds (§17.349): the public list, its cards, and the banner
   on a recommended build's own page.
   -------------------------------------------------------------------------- */

.rb-recCards {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--rb-gap);
    margin: 0 0 var(--rb-gap);
    padding: 0;
    list-style: none;
}

.rb-recCards--compact { grid-template-columns: repeat(3, minmax(0, 1fr)); margin: 10px 0; }

.rb-recCard {
    display: flex;
    flex-direction: column;
    min-width: 0;
    overflow: hidden;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
}

/* Part photos side by side on a light panel, so product shots on white read
   the same in both modes. */
.rb-recCard-photos {
    display: grid;
    grid-template-columns: repeat(var(--rb-recCard-cols, 4), minmax(0, 1fr));
    gap: 4px;
    height: 150px;
    padding: 10px;
    background: #fff;
    border-bottom: 1px solid var(--rb-border);
}

.rb-recCard-photos--1 { --rb-recCard-cols: 1; }
.rb-recCard-photos--2 { --rb-recCard-cols: 2; }
.rb-recCard-photos--3 { --rb-recCard-cols: 3; }

.rb-recCard-photos img {
    width: 100%;
    height: 100%;
    min-height: 0;
    object-fit: contain;
}

.rb-recCard-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--rb-text-muted);
}

.rb-recCard-icon svg { width: 64px; height: 64px; }

.rb-recCard-body {
    display: flex;
    flex: 1 1 auto;
    flex-direction: column;
    gap: 6px;
    padding: 10px 12px 12px;
}

.rb-recCard-body > p { margin: 0; }

.rb-recCard-title {
    margin: 0;
    font-size: 17px;
    line-height: 1.3;
}

.rb-recCard-title a { color: var(--rb-text-heading); text-decoration: none; }
.rb-recCard-title a:hover { text-decoration: underline; }

.rb-recCard-where { font-size: 12px; }
.rb-recCard-desc { font-size: 14px; line-height: 1.5; color: var(--rb-text-body); }

.rb-recCard-price {
    margin-top: auto !important;
    padding-top: 4px;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-recCard-price strong { font-size: 18px; color: var(--rb-text-heading); }

.rb-recCard-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.rb-recCard-actions form { margin: 0; }

.rb-recCards-more { margin: 0; }

/* An editorial note, not a notice: the card surface the recommended-build
   cards use, with a blue badge. Cream read as a warning here (§17.382). */
.rb-recBanner {
    margin: 0 0 var(--rb-gap);
    padding: 14px 16px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
}

.rb-recBanner-label {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0 0 10px;
    padding: 3px 8px;
    border-radius: var(--rb-radius);
    background: var(--rb-brand-blue);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
}

.rb-recBanner-foot {
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--rb-border);
}

.rb-recBanner-text {
    margin: 0 0 6px;
    font-size: 14px;
    line-height: 1.55;
    color: var(--rb-text-body);
}

.rb-recBanner-text:last-child { margin-bottom: 0; }

@media (max-width: 1000px) {
    .rb-recCards--compact { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 650px) {
    .rb-recCards,
    .rb-recCards--compact { grid-template-columns: minmax(0, 1fr); }
    .rb-recCard-photos { height: 120px; }
}

/* --------------------------------------------------------------------------
   The wizard over recommended builds (§17.350): result tiers and the
   "do you own anything?" picker.
   -------------------------------------------------------------------------- */

/* Why the results read as they do from $3,000 up (§17.520): reading text,
   not a caption, set off from the button above it as the lede is. */
.rb-guideWhy {
    margin: 20px 0 var(--rb-gap);
    color: var(--rb-text-body);
    font-size: 14px;
}

.rb-guideTiers {
    display: grid;
    gap: var(--rb-gap);
    margin: 0 0 var(--rb-gap);
    padding: 0;
    list-style: none;
}

.rb-guideTier-role {
    margin: 0 0 6px;
    font-size: 18px;
    font-weight: 700;
    color: var(--rb-text-body);
}

.rb-guideTier--pick .rb-guideTier-role { color: var(--rb-highlight-text); }

/* "Featured Build": a recommended build in a result slot, which GTPlanet
   chose by hand (§17.396, §17.404). Green, so it never reads as the blue
   Customize This Rig button (§17.403, §17.406). */
.rb-guideTier-featured {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: var(--rb-radius);
    background: var(--rb-buy-bg);
    color: #fff;
    font-size: 10px;
    letter-spacing: 0.04em;
    vertical-align: 1px;
}

.rb-guideTier-card {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 14px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
}

.rb-guideTier--pick .rb-guideTier-card {
    border-color: var(--rb-highlight-border);
    border-width: 2px;
}

.rb-guideTier-card > p { margin: 0; }
.rb-guideTier-card .rb-recCard-title { font-size: 20px; }
.rb-guideTier-card .rb-recommended-parts { margin: 0; }

.rb-guideTier-notes {
    margin: 0;
    padding: 8px 10px 8px 26px;
    font-size: 13px;
    border-radius: var(--rb-radius);
    background: var(--rb-positive-bg);
    color: var(--rb-positive-text);
}

.rb-guideTier-tag {
    font-size: 11px;
    color: var(--rb-text-muted);
}

/* "Change your answers": a real button, so readers see they can go back. */
.rb-guideChange {
    margin: 0 0 var(--rb-gap);
}

/*
 * A result's parts (§17.406): the picture on the left, then the name, linking
 * to the part's page, with its price on the line under it. The total sits
 * under the list, on the left, above the button.
 */
.rb-guideParts {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 13px;
}

.rb-guideParts-row {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 6px 0;
    border-top: 1px solid var(--rb-border);
}

.rb-guideParts-row:last-child {
    border-bottom: 1px solid var(--rb-border);
}

.rb-guideParts-thumb {
    display: flex;
    flex: 0 0 56px;
    align-items: center;
    justify-content: center;
    height: 56px;
}

.rb-guideParts-thumb img,
.rb-guideParts-thumb .rb-category-icon {
    width: 56px;
    height: 56px;
    object-fit: contain;
    border-radius: 3px;
    background: #fff;
}

.rb-guideParts-thumb .rb-category-icon {
    padding: 10px;
    box-sizing: border-box;
    background: var(--rb-bg-subtle);
    color: var(--rb-text-muted);
}

.rb-guideParts-text {
    min-width: 0;
}

.rb-guideParts-name {
    font-size: 15px;
    color: var(--rb-text-link);
}

.rb-guideParts-name:hover {
    text-decoration: underline;
}

.rb-guideParts-price {
    display: block;
    margin-top: 1px;
    font-variant-numeric: tabular-nums;
    color: var(--rb-text-muted);
}

.rb-guideOwned-search { display: block; margin: 0 0 8px; }
.rb-guideOwned-search .rb-input { width: 100%; box-sizing: border-box; }
.rb-guideOwned-none { margin: 0 0 8px; font-size: 13px; color: var(--rb-text-muted); }

.rb-guideOwned-group {
    margin: 0 0 6px;
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
}

.rb-guideOwned-group > summary {
    padding: 8px 10px;
    font-size: 14px;
    font-weight: 600;
    cursor: pointer;
}

.rb-guideOwned-count {
    margin-left: 6px;
    font-size: 12px;
    font-weight: 400;
    color: var(--rb-positive-text);
}

.rb-guideOwned-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 2px 12px;
    max-height: 320px;
    overflow-y: auto;
    padding: 0 10px 10px;
}

.rb-guideOwned-row { padding: 3px 0; align-items: flex-start; }
.rb-guideOwned-row[hidden] { display: none; }
.rb-guideOwned-row input { margin-top: 2px; }
.rb-guideOwned-meta { color: var(--rb-text-muted); font-size: 12px; }

@media (max-width: 650px) {
    .rb-guideOwned-list { grid-template-columns: minmax(0, 1fr); }
    /* Blocks lose their side padding on phones; text outside one keeps the same gutter as My Rigs' head (§17.345). */
    .rb-guideTier-role,
    .rb-guideWhy { padding: 0 10px; }
}

/* Editorial sections on Recommended Builds: a heading with the brand's red
   accent bar and a build count, and jump links in the toolbar. */
/* Each category is a red block that collapses like the filter panel (§17.384). */
.rb-block.rb-recSection { margin: 0 0 var(--rb-gap); scroll-margin-top: 12px; }
.rb-recSection > summary { cursor: pointer; }
.rb-recSection > summary h2 { display: inline; margin: 0; font: inherit; color: inherit; }
.rb-recSection-count { float: right; margin-top: 1px; font-size: 13px; font-weight: 400; opacity: 0.9; }
.rb-recSection .rb-recCards { margin: 0; }

/* Inside a section the builds are tiles on a tinted body, set apart by the
   gap and the change in tone rather than a border round each card and a
   rule under its photos (§17.385). */
.rb-recSection > .rb-block-body { padding: var(--rb-gap); background: var(--rb-bg-subtle); }
.rb-recSection .rb-recCard { border: 0; box-shadow: 0 1px 2px rgb(0 0 0 / 8%); }
.rb-recSection .rb-recCard-photos { border-bottom: 0; }

.rb-recJump { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.rb-recJump a {
    padding: 4px 10px;
    border: 1px solid var(--rb-border-strong);
    border-radius: 14px;
    background: var(--rb-bg-card);
    color: var(--rb-text-link);
    font-size: 13px;
    font-weight: 600;
    text-decoration: none;
}
.rb-recJump a:hover { background: var(--rb-bg-subtle); text-decoration: none; }

@media (max-width: 650px) {
    /* Text outside a block keeps the phone gutter (§17.345). */
    .rb-recJump { flex-basis: 100%; }
}

/* --------------------------------------------------------------------------
   The Price Tracker (§17.387)
   -------------------------------------------------------------------------- */

.rb-block.rb-tracker-day { margin: 0 0 var(--rb-gap); }
.rb-tracker-count { float: right; margin-top: 1px; font-size: 13px; font-weight: 400; opacity: 0.9; }

.rb-tracker-list { margin: 0; padding: 0; list-style: none; }
.rb-tracker-item {
    display: grid;
    grid-template-columns: 52px minmax(0, 1fr) auto;
    align-items: center;
    gap: 12px;
    padding: 8px var(--rb-pad-block);
    border-top: 1px solid var(--rb-border);
    background: var(--rb-bg-card);
}
.rb-tracker-item:first-child { border-top: 0; }
.rb-tracker-item:nth-child(even) { background: var(--rb-bg-subtle); }

.rb-tracker-thumb img, .rb-tracker-thumb .rb-imagePlaceholder { display: block; width: 52px; height: 52px; object-fit: contain; background: #fff; border-radius: 3px; }
.rb-tracker-name { display: block; font-size: 14px; font-weight: 700; text-decoration: underline; text-underline-offset: 2px; }
.rb-tracker-store { display: block; margin-top: 2px; font-size: 12px; color: var(--rb-text-muted); }

.rb-tracker-change { margin: 0; font-size: 14px; color: var(--rb-text-body); font-variant-numeric: tabular-nums; }
.rb-tracker-change + .rb-tracker-change { margin-top: 4px; }
.rb-tracker-from { color: var(--rb-text-muted); }

.rb-tracker-badge {
    display: inline-block;
    margin-right: 6px;
    padding: 1px 7px;
    border: 1px solid;
    border-radius: 10px;
    font-size: 12px;
    font-weight: 700;
    white-space: nowrap;
}
.rb-tracker-badge--drop,
.rb-tracker-badge--instock { background: var(--rb-positive-bg); border-color: var(--rb-positive-border); color: var(--rb-positive-text); }
.rb-tracker-badge--rise { background: var(--rb-error-bg); border-color: var(--rb-error-border); color: var(--rb-error-text); }
.rb-tracker-badge--stock { background: var(--rb-highlight-bg); border-color: var(--rb-highlight-border); color: var(--rb-highlight-text); }

/* What changed sits at the right, where a store link used to be (§17.416, §17.454). */
.rb-tracker-changes { text-align: right; }
/* On the landing page each row says when, since the rows are not grouped by day there (§17.522). */
.rb-tracker-when { margin: 0 0 2px; font-size: 12px; color: var(--rb-text-muted); }

.rb-tracker-pager { display: flex; justify-content: space-between; gap: var(--rb-gap); margin: 0 0 var(--rb-gap); font-weight: 600; }
.rb-tracker-pager a[rel="next"] { margin-left: auto; }

@media (max-width: 650px) {
    /* Photo beside the name, the change below it. */
    .rb-tracker-item { grid-template-columns: 44px minmax(0, 1fr); gap: 6px 10px; }
    .rb-tracker-thumb { grid-row: span 2; align-self: start; }
    .rb-tracker-thumb img, .rb-tracker-thumb .rb-imagePlaceholder { width: 44px; height: 44px; }
    .rb-tracker-changes { text-align: left; }
    .rb-tracker-pager { padding: 0 16px; }
}

/* --------------------------------------------------------------------------
   Product comparison (§17.393)

   A Compare button on cards, list rows and product pages; a tray along the
   bottom of the screen with the pick for the page's category; and the
   comparison page, one column per product with a row per specification.
   -------------------------------------------------------------------------- */

.rb-compareToggle { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.rb-compareToggle svg { flex: none; }
.rb-compareToggle .rb-compareToggle-on,
.rb-compareToggle.is-selected .rb-compareToggle-off { display: none; }
.rb-compareToggle.is-selected .rb-compareToggle-on { display: inline; }
.rb-compareToggle.is-selected,
.rb-compareToggle.is-selected:visited,
.rb-compareToggle.is-selected:hover {
    color: var(--rb-highlight-text);
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
}
.dark .rb-compareToggle.is-selected,
.dark .rb-compareToggle.is-selected:visited,
.dark .rb-compareToggle.is-selected:hover {
    color: #fff;
    background: var(--rb-highlight-bg);
    border-color: var(--rb-highlight-border);
}
.rb-gridCard-actions .rb-compareToggle { width: 100%; }
/* In the list view the button sits under the brand as a small chip. */
.rb-compareToggle--small { margin-top: 6px; padding: 2px 8px; font-size: 12px; }
.rb-compareToggle--small svg { width: 13px; height: 13px; }
/* Outranks the list's product-name link rules (block, underlined, 14px). */
.rb-catalogTable-product a.rb-compareToggle--small { display: inline-flex; font-size: 12px; text-decoration: none; }
.rb-productBuildActions .rb-compareToggle { align-self: stretch; }

/* The tray: fixed to the bottom of the screen, above everything but dialogs. */
.rb-compareTray {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 90;
    background: var(--rb-bg-card);
    border-top: 3px solid var(--rb-brand-blue);
    box-shadow: 0 0 4px 1px rgb(0 0 0 / 30%);
    padding: 8px max(10px, env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) max(10px, env(safe-area-inset-left));
    color: var(--rb-text-body);
}
.rb-compareTray[hidden] { display: none; }
body.rb-hasCompareTray { padding-bottom: 76px; }
.rb-compareTray-inner { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; max-width: 1200px; margin: 0 auto; }
.rb-compareTray-title { margin: 0; font-size: 14px; font-weight: 700; white-space: nowrap; }
.rb-compareTray-title span { display: block; font-size: 12px; font-weight: 400; color: var(--rb-text-muted); }
.rb-compareTray-items { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; flex: 1 1 420px; min-width: 0; margin: 0; padding: 0; list-style: none; }
.rb-compareTray-items li { display: flex; align-items: center; gap: 4px; min-width: 0; height: 44px; padding: 0 4px 0 4px; border: 1px solid var(--rb-border); border-radius: var(--rb-radius); background: var(--rb-bg-subtle); font-size: 13px; }
.rb-compareTray-items a { display: flex; align-items: center; gap: 6px; min-width: 0; flex: 1; color: var(--rb-text-body); text-decoration: none; }
.rb-compareTray-items a:hover span { text-decoration: underline; }
.rb-compareTray-items img { flex: none; width: 36px; height: 36px; object-fit: contain; background: #fff; border-radius: 2px; }
.rb-compareTray-items span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rb-compareTray-items .rb-compareTray-empty { justify-content: center; border-style: dashed; background: transparent; color: var(--rb-text-muted); }
.rb-compareTray-remove { flex: none; width: 28px; height: 28px; padding: 0; border: 0; background: none; color: var(--rb-text-muted); font-size: 20px; line-height: 1; cursor: pointer; }
.rb-compareTray-remove:hover { color: var(--rb-text-body); }
.rb-compareTray-remove:focus-visible,
.rb-compareTray-clear:focus-visible { outline: 2px solid var(--rb-accent-blue); outline-offset: 1px; }
.rb-compareTray-actions { display: flex; align-items: center; gap: 10px; }
.rb-compareTray-clear { padding: 4px; border: 0; background: none; color: var(--rb-text-link); font: inherit; font-size: 13px; cursor: pointer; }
.rb-compareTray-notice { flex-basis: 100%; margin: 0; padding: 4px 8px; border: 1px solid var(--rb-highlight-border); border-radius: var(--rb-radius); background: var(--rb-highlight-bg); color: var(--rb-highlight-text); font-size: 13px; }

/* The comparison page. */
.rb-compareNotice { margin: 0 0 var(--rb-gap); padding: 6px 10px; border: 1px solid var(--rb-highlight-border); border-radius: var(--rb-radius); background: var(--rb-highlight-bg); color: var(--rb-highlight-text); font-size: 14px; }
/* The description sections that compare these products (§17.432). */
.rb-compareWriteups { margin: 0 0 var(--rb-gap); font-size: 15px; line-height: 1.65; }
.rb-compareWriteups a { text-decoration: underline; }
.rb-compareToolbar { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: 10px 20px; margin: 0 0 var(--rb-gap); }
.rb-compareToolbar:empty { display: none; }
.rb-compareAdd { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; }
.rb-compareAdd .rb-filterLabel { flex-basis: 100%; }
.rb-compareAdd select { width: auto; max-width: min(420px, 100%); font-size: 14px; }
.rb-compareAdd.is-autosubmit .rb-button { display: none; }
.rb-compareDiffToggle[hidden] { display: none; }
.rb-compareCategories { columns: 3 180px; margin: 0; padding: 0 0 0 18px; }
.rb-compareCategories li { margin: 0 0 4px; }

.rb-compareTable { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 14px; }
.rb-compareTable th,
.rb-compareTable td { padding: 8px 10px; text-align: left; vertical-align: top; border-bottom: 1px solid var(--rb-border); color: var(--rb-text-body); overflow-wrap: break-word; hyphens: auto; }
.rb-compareTable tbody tr:last-child th,
.rb-compareTable tbody tr:last-child td { border-bottom: 0; }
.rb-compareTable tbody tr:nth-child(even) { background: var(--rb-bg-subtle); }
.rb-compareTable tbody th { width: 200px; font-weight: 600; }
.rb-compareTable-corner { width: 200px; }
/* Rows where the products differ carry the selected-state yellow down their left edge. */
.rb-compareTable-differs th { box-shadow: inset 3px 0 0 var(--rb-highlight-border); }
/* Every piece of text in a row that differs is bold, labels and unstated values included. */
.rb-compareTable-differs th,
.rb-compareTable-differs td,
.rb-compareTable-differs td * { font-weight: 700; }
.rb-compareTable--diffOnly .rb-compareTable-same { display: none; }
.rb-compareTable-unstated { color: var(--rb-text-muted); font-style: italic; }
.rb-compareTable-price td { font-size: 16px; font-weight: 700; }
.rb-compareTable-price .rb-price--was { display: block; font-size: 12px; font-weight: 400; }
.rb-compareTable-differs.rb-compareTable-price .rb-price--was { font-weight: 700; }
.rb-compareTable-price .rb-saving { margin-bottom: 3px; }

.rb-compareTable .rb-compareProduct { font-weight: 400; vertical-align: bottom; }
.rb-compareProduct-image { display: block; margin: 0 0 8px; padding: 6px; background: #fff; border-radius: var(--rb-radius); text-align: center; }
.rb-compareProduct-image img { display: block; width: 100%; max-width: 220px; height: 160px; margin: 0 auto; object-fit: contain; }
.rb-compareProduct-image .rb-imagePlaceholder { display: block; height: 160px; }
.rb-compareProduct-name { display: block; font-size: 15px; font-weight: 700; line-height: 1.3; }
.rb-compareProduct-brand { display: block; margin: 2px 0 8px; font-size: 12px; color: var(--rb-text-muted); }
.rb-compareProduct-add { margin: 0 0 6px; }
.rb-compareProduct-add .rb-button { width: 100%; }
.rb-compareProduct-remove { font-size: 13px; }

/* Phones: each row's label spans the width, with the products' values in
   columns beneath it, so nothing scrolls sideways. */
@media (max-width: 650px) {
    body.rb-hasCompareTray { padding-bottom: 120px; }
    .rb-compareTray-title { flex: 1; }
    .rb-compareTray-title span { display: inline; margin-left: 6px; }
    .rb-compareTray-items { order: 3; flex-basis: 100%; }
    /* Too narrow for names: thumbnails only, with the name kept for screen readers. */
    .rb-compareTray-items li { justify-content: center; height: 40px; }
    .rb-compareTray-items a { flex: none; }
    .rb-compareTray-items a span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
    .rb-compareTray-items img { width: 30px; height: 30px; }
    .rb-compareTray-items .rb-compareTray-empty { font-size: 12px; }
    .rb-comparePage .rb-lede--intro,
    .rb-compareWriteups,
    .rb-compareToolbar,
    .rb-comparePage > .rb-specTable-note,
    .rb-compareNotice { margin-left: 10px; margin-right: 10px; }
    .rb-compareTable,
    .rb-compareTable thead,
    .rb-compareTable tbody { display: block; }
    .rb-compareTable tr { display: grid; grid-template-columns: repeat(var(--rb-compare-cols, 3), minmax(0, 1fr)); }
    .rb-compareTable-corner { display: none; }
    .rb-compareTable tbody th { grid-column: 1 / -1; width: auto; padding: 6px 10px 0; border-bottom: 0; font-size: 13px; color: var(--rb-text-muted); }
    .rb-compareTable td { padding: 4px 10px 8px; font-size: 13px; }
    .rb-compareTable td + td { border-left: 1px solid var(--rb-border); }
    .rb-compareTable-differs th { box-shadow: none; }
    .rb-compareTable-differs th::before { content: ""; display: inline-block; width: 8px; height: 8px; margin-right: 6px; border-radius: 50%; background: var(--rb-highlight-border); }
    .rb-compareTable-price td { font-size: 15px; }
    .rb-compareProduct { padding: 8px 6px; border-bottom: 1px solid var(--rb-border); }
    .rb-compareProduct + .rb-compareProduct { border-left: 1px solid var(--rb-border); }
    .rb-compareProduct-image img,
    .rb-compareProduct-image .rb-imagePlaceholder { height: 90px; }
    .rb-compareProduct-name { font-size: 13px; }
    .rb-compareProduct-add .rb-button { padding: 5px 6px; font-size: 12px; }
}

/* --------------------------------------------------------------------------
   Wizard Picks (§17.400): the admin's report of what the wizard recommends
   -------------------------------------------------------------------------- */

.rb-wizardPicks-filter {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin: 0 0 var(--rb-gap);
}

.rb-wizardPicks-filter .rb-field-label {
    margin: 0;
}

.rb-wizardPicks-filter .rb-input {
    flex: 0 0 auto;
    width: auto;
}

.rb-wizardPicks-custom {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.rb-wizardPicks-custom[hidden] {
    display: none;
}

.rb-wizardPicks-table {
    width: 100%;
}


/* --------------------------------------------------------------------------
   Wizard Searches (§17.401): what readers ask the wizard for
   -------------------------------------------------------------------------- */

.rb-wizardSearches-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 var(--rb-gap);
}

.rb-wizardSearches-table {
    width: 100%;
}

/* Nine columns do not fit a phone: the table scrolls inside its block. */
.rb-wizardSearches-scroll {
    overflow-x: auto;
}

.rb-wizardSearches-when {
    white-space: nowrap;
}

@media (max-width: 650px) {
    .rb-wizardSearches-grid {
        grid-template-columns: 1fr;
    }
}

/* --------------------------------------------------------------------------
   Landing page (§17.413): a hero with the two doors, then a sample of each
   section in the usual red-header blocks, each linking to its full page.
   -------------------------------------------------------------------------- */

/* The hero is a card like the blocks below it, framed in the nav's blue. */
.rb-homeHero {
    display: grid;
    grid-template-columns: minmax(0, 1.8fr) minmax(0, 1fr);
    grid-template-areas:
        "image points"
        "main  main";
    align-items: start;
    gap: 24px 28px;
    margin: 0 0 var(--rb-gap);
    padding: 26px 28px;
    border-radius: var(--rb-radius);
    background: var(--rb-bg-card);
    color: var(--rb-text-body);
}

.rb-homeHero-title { margin: 0 0 10px; font-size: 30px; line-height: 1.15; letter-spacing: -0.02em; color: var(--rb-text-heading); }
.rb-homeHero-lede { margin: 0 0 18px; font-size: 16px; line-height: 1.5; }
.rb-homeHero-image { grid-area: image; display: block; width: 100%; height: auto; border-radius: var(--rb-radius); }
.rb-homeHero-main { grid-area: main; }

/* The two ways in: the wizard, or a custom build. */
.rb-homeChoice { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.rb-homeChoice--single { grid-template-columns: minmax(0, 1fr); max-width: 420px; }
.rb-homeChoice-option {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
    padding: 16px;
    border: 1px solid var(--rb-border-strong);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
}
.rb-homeChoice-option--guide { border-color: var(--rb-accent-blue); border-left-width: 4px; background: var(--rb-nav-current-bg); }
.rb-homeChoice-option h2 { margin: 0; font-size: 17px; color: var(--rb-text-heading); }
.rb-homeChoice-option p { flex: 1; margin: 0 0 8px; font-size: 14px; line-height: 1.45; }
.rb-homeChoice-option form { margin: 0; }
.rb-homeChoice-option .rb-button { min-height: 40px; padding: 8px 16px; font-size: 15px; }
.rb-homeChoice-badge {
    position: absolute;
    top: 14px;
    right: 14px;
    padding: 1px 8px;
    border-radius: 10px;
    background: var(--rb-accent-blue);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}

.rb-homeHero-rigs { margin: 12px 0 0; font-size: 14px; }

/* The logo is a mask filled with the heading color, so it turns white in dark mode. */
.rb-homeHero-side {
    grid-area: points;
    padding-left: 24px;
    border-left: 1px solid var(--rb-border);
}
.rb-homeHero-logo {
    width: 100%;
    max-width: 240px;
    aspect-ratio: 1852 / 880;
    margin: 0 auto 20px;
    background: var(--rb-text-heading);
    -webkit-mask: url('rig-builder-logo.svg?v=3') center / contain no-repeat;
    mask: url('rig-builder-logo.svg?v=3') center / contain no-repeat;
}
.rb-homeHero-points {
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 14px;
    line-height: 1.45;
}
.rb-homeHero-points li { position: relative; padding-left: 28px; }
.rb-homeHero-points li + li { margin-top: 14px; }
.rb-homeHero-points li::before {
    content: "";
    position: absolute;
    top: 1px;
    left: 0;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: #2a8c2a url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E") center / 12px no-repeat;
}
.rb-homeHero-points strong { color: var(--rb-text-heading); }

/* "See all" sits at the right of each section's red header. */
.rb-homeSection > .rb-block-header { display: flex; align-items: center; gap: 8px; }
.rb-homeSection-iconHeader .rb-category-icon { flex-basis: 18px; width: 18px; height: 18px; }
.rb-homeSection-all { margin-left: auto; font-size: 13px; font-weight: 400; white-space: nowrap; text-decoration: underline; text-underline-offset: 2px; }
/* White in every state: site-shell.css colors visited links blue (`a:visited`)
   and recolors hovered ones in dark mode (`.dark a:hover`). */
.rb-homeSection > .rb-block-header .rb-homeSection-all,
.rb-homeSection > .rb-block-header .rb-homeSection-all:visited,
.rb-homeSection > .rb-block-header .rb-homeSection-all:hover,
.dark .rb-homeSection > .rb-block-header .rb-homeSection-all:hover { color: #fff; }

.rb-homeSection-footer { margin: 0; padding: var(--rb-pad-block); border-top: 1px solid var(--rb-border); }
.rb-homeSection-more { margin: var(--rb-gap) 0 0; }
.rb-block-body > p.rb-homeSection-more { margin: var(--rb-gap) 0 0; }

/* Cards sit on a grey well, as on the Featured Builds page (§17.405). */
.rb-homeSection-cards { background: var(--rb-bg-subtle); }
.rb-homeSection-cards .rb-catalogGrid { padding: 0; }
.rb-homeSection-cards .rb-gridCard { background: var(--rb-bg-card); }
/* Compact cards: a shorter photo, tighter spacing, and the price right under the
   brand rather than pinned to the card's foot, so a two-line name leaves no gap (§17.419). */
.rb-homeSection-cards .rb-gridCard-image { aspect-ratio: 4 / 3; min-height: 0; padding: 10px; overflow: hidden; }
.rb-homeSection-cards .rb-gridCard-body { gap: 2px; padding: 8px 10px 10px; }
.rb-homeSection-cards .rb-gridCard-name { line-height: 1.3; }
.rb-homeSection-cards .rb-gridCard-price { margin-top: 6px; }

/* Equal tiles; the page picks three or four columns to fill the rows best (§17.416). */
.rb-homeBrands { display: grid; grid-template-columns: repeat(var(--rb-brand-cols, 4), minmax(0, 1fr)); gap: 10px; margin: 0; padding: 0; list-style: none; }
.rb-homeBrands a {
    display: flex;
    flex-direction: column;
    gap: 2px;
    height: 100%;
    padding: 18px 20px;
    border: 1px solid var(--rb-border-strong);
    border-left: 3px solid var(--rb-accent-blue);
    border-radius: var(--rb-radius);
    background: var(--rb-bg-subtle);
    text-decoration: none;
}
.rb-homeBrands a:hover { background: var(--rb-nav-current-bg); }
.rb-homeBrands-name { font-size: 18px; font-weight: 700; color: var(--rb-text-link); }
.rb-homeBrands-count { font-size: 13px; color: var(--rb-text-muted); }

.rb-homeChips { display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; list-style: none; }
.rb-homeChips a {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 5px 12px 5px 9px;
    border: 1px solid var(--rb-border-strong);
    border-radius: 16px;
    color: var(--rb-text-link);
    font-size: 14px;
    text-decoration: none;
}
.rb-homeChips a:hover { background: var(--rb-bg-subtle); }
.rb-homeChips .rb-category-icon { flex-basis: 18px; width: 18px; height: 18px; }
.rb-homeChips-count { color: var(--rb-text-muted); font-size: 12px; }

@media (max-width: 1000px) {
    /* One column: the side wrapper dissolves so the logo can move above the image. */
    .rb-homeHero { grid-template-columns: 1fr; grid-template-areas: "logo" "image" "main" "points"; }
    .rb-homeHero-side { display: contents; }
    .rb-homeHero-logo { grid-area: logo; margin-bottom: 0; }
    .rb-homeHero-points { grid-area: points; padding-top: 18px; border-top: 1px solid var(--rb-border); }
}

@media (max-width: 650px) {
    .rb-homeHero { gap: 18px; padding: 20px 16px; border-radius: 0; }
    .rb-homeHero-title { font-size: 24px; }
    .rb-homeHero-lede { font-size: 15px; }
    .rb-homeChoice { grid-template-columns: 1fr; }
        .rb-homeBrands { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .rb-homeBrands a { padding: 14px; }
    .rb-homeBrands-name { font-size: 16px; }
}

/* A rig name with a banned word (§17.422): the reason, under the field. */
.rb-setup-nameError { margin: 6px 0 0; font-size: 13px; font-weight: 600; color: var(--rb-error-text); }
.rb-setup-nameError[hidden] { display: none; }
.rb-setup-field--name .rb-input[aria-invalid="true"] { border-color: var(--rb-error-border); }

/* A checkbox in an admin filter bar sits on the row's baseline (§17.422). */
.rb-filterBar-field--check { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 6px; padding-bottom: 8px; font-size: 14px; }

/* --------------------------------------------------------------------------
   Price alerts (§10.6): the signup under a product's prices, and the
   confirm, manage, and unsubscribe pages.
   -------------------------------------------------------------------------- */

.rb-alertSignup {
    margin-top: 16px;
    padding: 12px 14px;
    background: var(--rb-bg-subtle);
    border: 1px solid var(--rb-border);
    border-radius: var(--rb-radius);
}

.rb-alertSignup-title {
    margin: 0 0 4px;
    font-size: 15px;
    font-weight: 700;
    color: var(--rb-text-heading);
}

.rb-alertSignup-lede {
    margin: 0 0 10px;
    font-size: 13px;
    color: var(--rb-text-body);
}

.rb-alertSignup-lede a {
    color: var(--rb-text-link);
}

.rb-alertSignup-form {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    align-items: stretch;
}

.rb-alertSignup-form[hidden] {
    display: none;
}

.rb-alertSignup-region {
    flex: 0 0 auto;
    width: auto;
}

.rb-alertSignup-email {
    flex: 1 1 200px;
}

.rb-alertSignup-button {
    flex: 0 0 auto;
}

/* Off screen rather than display: none, which some scripts check for. */
.rb-alertSignup-trap {
    position: absolute;
    left: -10000px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.rb-alertSignup-result {
    margin: 0;
    padding: 8px 10px;
    font-size: 13px;
    color: var(--rb-positive-text);
    background: var(--rb-positive-bg);
    border: 1px solid var(--rb-positive-border);
    border-radius: var(--rb-radius);
}

.rb-alertSignup-result--error {
    color: var(--rb-error-text);
    background: var(--rb-error-bg);
    border-color: var(--rb-error-border);
}

.rb-alertSignup-form + .rb-alertSignup-result {
    margin-top: 8px;
}


.rb-alertPage .rb-alertPage-list {
    margin: 0 0 16px;
    padding-left: 20px;
}

.rb-alertPage-action {
    margin: 0 0 16px;
}

.rb-alertPage-table .rb-alertPage-action {
    margin: 0;
}

/* Rows are as tall as their thumbnail, so everything centres on it. */
.rb-alertPage-table td {
    vertical-align: middle;
}

.rb-alertPage-product {
    display: flex;
    align-items: center;
    gap: 10px;
}

.rb-alertPage-meta {
    display: none;
    font-size: 12px;
    color: var(--rb-text-muted);
}

.rb-alertPage-stop {
    text-align: right;
    white-space: nowrap;
}

/* "Unsubscribe from all" sits apart from the per-alert buttons, so it is
   not pressed by mistake for one of them. */
.rb-alertPage-all {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 8px 16px;
    margin-top: 16px;
    padding-top: 14px;
    border-top: 1px solid var(--rb-border);
}

.rb-alertPage-all p {
    margin: 0;
    font-size: 13px;
    color: var(--rb-text-muted);
}

.rb-alertPage-all .rb-alertPage-action {
    margin: 0;
}

.rb-alertPage-allButton {
    color: var(--rb-error-text);
}

@media (max-width: 650px) {
    .rb-alertSignup-email {
        flex: 1 1 0;
    }

    .rb-alertSignup-button {
        flex: 1 1 100%;
    }
}

@media (max-width: 480px) {
    .rb-alertSignup {
        padding: 10px;
    }
}

@media (max-width: 650px) {
    .rb-alertPage-table .rb-alertPage-col {
        display: none;
    }

    .rb-alertPage-meta {
        display: block;
        margin-top: 2px;
    }
}

/* One-button row actions in the admin's alert tables. */
.rb-inlineAction {
    display: inline-block;
    margin: 0 4px 4px 0;
}

.rb-button--small {
    padding: 2px 8px;
    font-size: 12px;
}

.rb-alertPreview {
    display: block;
    width: 100%;
    max-width: 680px;
    height: 720px;
    border: 1px solid var(--rb-border);
    background: #e4e4e4;
}

.rb-alertPreview-text {
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}

/* The admin passphrase form (§17.469): one field, so a narrow box. */
.rb-adminPassphrase { max-width: 480px; }
.rb-adminPassphrase .rb-input { width: 100%; }
