/* static/style.css */
.fade-in {
    opacity: 0;
    transition: opacity 0.5s ease-in-out;
}

.fade-in.show {
    opacity: 1;
}

html, body {
    height: 100%;
    margin: 0;
    background-color: var(--rmb-surface);
}

html {
    scroll-behavior: smooth;
}

body {
    display: flex;
    flex-direction: column;
}

.content {
    flex: 1;
}

.footer {
    flex-shrink: 0;
}

input[type="number"] {
    -moz-appearance: textfield;
    -webkit-appearance: number-input;
    appearance: number-input;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
    -webkit-appearance: number-input;
}

input[type="number"]::-moz-spin-button,
input[type="number"]::-moz-inner-spin-button {
    display: inline-block;
}

input[type="number"] {
    width: auto;
    padding: 5px;
}

@media (max-width: 640px) {
    input[type="number"] {
        width: 50px;
        padding: 2px;
    }
}

.logo {
    height: 100px;
    max-height: 100%;
    width: auto;
}


/* ReturnMeBack brand — "Signal" design tokens (rev 5)
   Two groups, clearly separated below: THEME-AWARE tokens carry an inline
   "dark: ..." note showing what they become in dark mode — read that note,
   don't go hunting in the @media block to find out whether or how a token
   changes. FIXED tokens have no such note because they don't have a dark
   override anywhere in this file; their value here is their value in both
   themes, period. If you're ever unsure which group a token is in, this
   file is the only place that answers it — the two dark blocks below exist
   purely to supply the values these notes already promise, never to
   introduce a token that isn't listed here first. */
:root {
    color-scheme: light;

    /* ---- THEME-AWARE — redefined for dark mode; see the comment on each. */
    --rmb-text: #1c1a18; /* dark: #f2ede7 */
    --rmb-text-rgb: 28, 26, 24; /* dark: 242, 237, 231 — --rmb-text, for rgba() tints */
    --rmb-text-muted: #6b6058; /* dark: #bcb2a7 */
    --rmb-border: #e7e2dc; /* dark: #34302b — intentionally near-invisible hairline in both themes */
    --rmb-border-strong: #96897a; /* dark: #7c7165 */

    /* accent/danger/success AS TEXT/BORDER/ICON on --rmb-surface (links,
       pills, alerts, status dots) — not as a fill behind --rmb-text-on-accent.
       Equal to the fixed base token below in light mode (no visual change),
       brightened only in dark mode. See "Dark mode" further down for why
       this is a separate token from the fill color instead of overriding
       --rmb-accent/--rmb-danger/--rmb-success directly. */
    --rmb-accent-text: var(--rmb-accent); /* dark: #ee7250 */
    --rmb-danger-text: var(--rmb-danger); /* dark: #ee7a70 */
    --rmb-success-text: var(--rmb-success); /* dark: #52ba80 */

    /* Surfaces: the page/card/panel background scale. Distinct from --rmb-text
       (text) so the two can flip independently — a themed background swap
       must never accidentally invert text color and vice versa. */
    --rmb-surface: #ffffff; /* dark: #1c1a18 */
    --rmb-surface-sunken: #faf8f5; /* dark: #221f1c — recessed panel, e.g. showcase frame */
    --rmb-surface-hover: #f5f2ee; /* dark: #2a2622 — hover fill for menu items/buttons */

    /* Nav chrome: its own subtle tint in both themes, offset further from
       --rmb-surface than --rmb-surface-sunken is — the nav is a distinct
       chrome plane, not a recessed content panel, so it earns a firmer step
       even though both started from "a little off white/near-black." Kept
       as its own token rather than aliased to --rmb-surface-sunken so the
       two can be retuned independently when they diverge for unrelated
       reasons. --rmb-nav-border stays the ordinary hairline in both themes
       — it used to be strengthened in dark mode (back when --rmb-nav-surface
       had no tint of its own and the border was the only separation signal),
       but now that the fill itself carries the distinction, the plain
       hairline is enough to close the edge without the bar reading as
       outlined in bright warm grey. */
    --rmb-nav-surface: #f6f3ef; /* dark: #26221e */
    --rmb-nav-border: var(--rmb-border);

    /* ---- FIXED — same value in both themes. No entry in either dark block
       below; if one gets added later, move that token up into the group
       above and give it a "dark: ..." note. */
    --rmb-accent: #d8492f;
    --rmb-accent-hover: #c03f28;
    --rmb-text-on-accent: #ffffff;
    --rmb-accent-rgb: 216, 73, 47; /* --rmb-accent, for rgba() tints */
    --rmb-danger: #b3261e;
    --rmb-danger-hover: #8f1e18;
    --rmb-danger-rgb: 179, 38, 30; /* --rmb-danger, for rgba() tints */
    --rmb-success: #2f7a4f;

    /* Fixed-dark: brand-dark elements that stay dark regardless of theme
       (footer band, photo letterbox mat, modal scrim, drop shadows) — kept
       separate from --rmb-text so that token is free to flip to a light color
       for text in dark mode without also flipping these to white. */
    --rmb-fixed-dark: #1c1a18;
    --rmb-fixed-dark-rgb: 28, 26, 24;
    --rmb-text-on-fixed-dark-rgb: 255, 255, 255; /* content drawn on a fixed-dark surface */

    --rmb-radius-button: 15px;
    --rmb-radius-input: 10px;
    --rmb-radius-panel: 10px;
}

/* Dark values for every token the THEME-AWARE group above promised one for
   — nothing here should exist without a matching "dark: ..." note in
   :root, and nothing in that group should lack an entry here. Why
   --rmb-accent/--rmb-danger/--rmb-success (the FILL tokens, not their -text
   siblings) are absent: they stay the color behind white --rmb-text-on-accent
   text (buttons, badges, avatars, ribbons), and that pairing's contrast has
   nothing to do with the page's surface color, so there's no reason for it
   to shift with theme. --rmb-fixed-dark and its -rgb/text-on- siblings are
   absent for the same kind of reason, in the other direction — they exist
   specifically to *stay* dark in both themes. Radii aren't a color concern.

   Applied two ways so this file is the only thing the nav's dark-mode
   toggle (see layout.html) needs to flip a `data-theme` attribute against —
   no token values to add there:
   - `@media (prefers-color-scheme: dark)` follows the OS/browser setting by
     default, unless the toggle has set `data-theme="light"`.
   - `:root[data-theme="dark"]` is the toggle's explicit-dark override,
     independent of OS preference. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        color-scheme: dark;

        --rmb-text: #f2ede7;
        --rmb-text-rgb: 242, 237, 231;
        --rmb-text-muted: #bcb2a7;
        --rmb-border: #34302b;
        --rmb-border-strong: #7c7165;

        --rmb-accent-text: #ee7250;
        --rmb-danger-text: #ee7a70;
        --rmb-success-text: #52ba80;

        --rmb-surface: #1c1a18;
        --rmb-surface-sunken: #221f1c;
        --rmb-surface-hover: #2a2622;

        --rmb-nav-surface: #26221e;
        --rmb-nav-border: var(--rmb-border);
    }
}

:root[data-theme="dark"] {
    color-scheme: dark;

    --rmb-text: #f2ede7;
    --rmb-text-rgb: 242, 237, 231;
    --rmb-text-muted: #bcb2a7;
    --rmb-border: #34302b;
    --rmb-border-strong: #7c7165;

    --rmb-accent-text: #ee7250;
    --rmb-danger-text: #ee7a70;
    --rmb-success-text: #52ba80;

    --rmb-surface: #1c1a18;
    --rmb-surface-sunken: #221f1c;
    --rmb-surface-hover: #2a2622;

    --rmb-nav-surface: #26221e;
    --rmb-nav-border: var(--rmb-border);
}

.font-body {
    font-family: 'Manrope', system-ui, sans-serif;
}

.font-mono {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
}

.rmb-pill {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    color: var(--rmb-accent-text);
    border: 1px solid var(--rmb-accent-text);
    padding: 0.2rem 0.6rem;
    display: inline-block;
}

.btn-rmb-primary {
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    font-weight: 700;
    padding: 0.8rem 1.4rem;
    border-radius: var(--rmb-radius-button);
    display: inline-block;
    transition: background 0.15s ease;
}

.btn-rmb-primary:hover:not(:disabled) {
    background: var(--rmb-accent-hover);
    color: var(--rmb-text-on-accent);
}

.link-rmb-arrow {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.8rem;
    font-weight: 700;
    color: var(--rmb-text);
}

.link-rmb-arrow:hover {
    color: var(--rmb-accent-text);
}

.rmb-link {
    font-size: 0.875rem;
    color: var(--rmb-text-muted);
}

.rmb-link:hover {
    color: var(--rmb-accent-text);
}

.rmb-link--danger:hover {
    color: var(--rmb-danger-text);
}

.rmb-link-strong {
    font-weight: 700;
}

.rmb-hint {
    color: var(--rmb-text-muted);
    font-size: 0.875rem;
}

.rmb-flow {
    border-top: 1px solid var(--rmb-border);
}

.rmb-step {
    display: grid;
    grid-template-columns: 48px 1fr;
    gap: 1.5rem;
    padding: 1.75rem 0;
}

.rmb-step + .rmb-step {
    border-top: 1px solid var(--rmb-border);
}

.rmb-flow-node-row {
    display: flex;
    align-items: center;
}

.rmb-flow-node {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-weight: 700;
    font-size: 0.8rem;
    color: var(--rmb-accent-text);
    width: 28px;
    height: 28px;
    flex: none;
    border: 1px solid var(--rmb-accent-text);
    border-radius: 999px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-flow-rail {
    flex: 1;
    height: 1px;
    background: var(--rmb-border);
    margin-left: 0.75rem;
    margin-right: -2rem;
}

.rmb-step h3 {
    font-size: 1.25rem;
    font-weight: 800;
    color: var(--rmb-text);
    margin-bottom: 0.5rem;
    letter-spacing: -0.01em;
}

.rmb-step p {
    color: var(--rmb-text-muted);
    line-height: 1.6;
}

.rmb-inline-trust {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.8rem;
    color: var(--rmb-text-muted);
    text-align: left;
    border-left: 2px solid var(--rmb-accent-text);
    padding-left: 0.75rem;
    margin-top: 0.9rem;
}

.rmb-showcase-frame {
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    padding: 1.25rem;
    width: 100%;
}

.rmb-qr-sticker {
    position: relative;
    background: var(--rmb-surface);
    border-radius: var(--rmb-radius-panel);
    padding: 1rem;
    width: 160px;
    margin: 0 auto;
    box-shadow: 0 12px 30px -12px rgba(var(--rmb-fixed-dark-rgb), 0.35);
}

.rmb-qr-sticker::after {
    content: "";
    position: absolute;
    bottom: 0;
    right: 0;
    width: 22px;
    height: 22px;
    background: linear-gradient(135deg, transparent 50%, var(--rmb-surface-sunken) 50%);
    border-radius: 0 0 var(--rmb-radius-panel) 0;
    box-shadow: -2px -2px 4px rgba(var(--rmb-fixed-dark-rgb), 0.12);
}

.rmb-qr-sticker--lg {
    width: 220px;
}

.rmb-qr-sticker img {
    display: block;
    width: 100%;
    height: auto;
}

.rmb-qr-sticker-brand {
    font-weight: 800;
    color: var(--rmb-accent-text);
    text-transform: uppercase;
    text-align: center;
    line-height: 1.15;
    font-size: 0.85rem;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
}

.rmb-unread-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--rmb-accent-text);
    margin-right: 0.4rem;
    vertical-align: middle;
}

.rmb-mini-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 0;
    text-align: left;
}

.rmb-mini-row + .rmb-mini-row {
    border-top: 1px solid var(--rmb-border);
}

.rmb-mini-icon {
    flex: none;
    width: 36px;
    height: 36px;
    border-radius: var(--rmb-radius-input);
    background: rgba(var(--rmb-accent-rgb), 0.08);
    color: var(--rmb-accent-text);
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-mini-icon svg {
    width: 18px;
    height: 18px;
}

.rmb-mini-title {
    font-weight: 800;
    color: var(--rmb-text);
    font-size: 0.9rem;
    margin-bottom: 0.1rem;
}

.rmb-mini-sub {
    color: var(--rmb-text-muted);
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* messages inbox (messages.html): a sortable DataTables rmb-table, one row
   per conversation. The item name links to the thread. */

.rmb-message-name {
    font-weight: 700;
    color: var(--rmb-text);
    white-space: nowrap;
}

.rmb-message-name:hover {
    text-decoration: underline;
}

.rmb-conversation-row--unread .rmb-message-name {
    font-weight: 800;
}

/* Keep each header on one line with its sort arrow, and the unread dot on
   the same line as the item name - the preview column absorbs the squeeze. */
.rmb-conversation-table th,
.rmb-conversation-table td.rmb-td--heading {
    white-space: nowrap;
}

/* Small muted, non-wrapping metadata - the inbox's type/time cells and a
   thread message's sender/time line. */
.rmb-message-meta {
    flex: none;
    color: var(--rmb-text-muted);
    font-size: 0.75rem;
    white-space: nowrap;
}

/* Chat thread (thread.html). The container is a recessed, scrolling well so
   the conversation reads as separate from the info box above it; "mine" is a
   neutral tint rather than --rmb-accent, which already means primary action /
   Lost. */
.rmb-thread {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding: 1rem;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

.rmb-thread-message {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    max-width: 80%;
}

.rmb-thread-message--mine {
    align-self: flex-end;
    text-align: right;
}

.rmb-thread-message--theirs {
    align-self: flex-start;
}

.rmb-thread-bubble {
    padding: 0.5rem 0.75rem;
    border-radius: var(--rmb-radius-panel);
    white-space: pre-wrap;
    overflow-wrap: anywhere;
    text-align: left;
}

.rmb-thread-message--mine .rmb-thread-bubble {
    background: rgba(var(--rmb-text-rgb), 0.08);
}

.rmb-thread-message--theirs .rmb-thread-bubble {
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
}

/* "New message" button: laid over the bottom edge of the chat well (outside
   it, so new rows can't end up below it), shown when a message from the
   other party arrives out of view. Neutral, not accent - it's information,
   not a primary action. */
.rmb-thread-wrap {
    position: relative;
}

.rmb-thread-new {
    position: absolute;
    bottom: 0.75rem;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--rmb-text);
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-button);
    padding: 0.3rem 0.9rem;
    box-shadow: 0 10px 30px rgba(var(--rmb-fixed-dark-rgb), 0.14);
}

.rmb-thread-new:hover {
    background: var(--rmb-surface-hover);
}

.rmb-thread-new[hidden] {
    display: none;
}

/* A finder's shared location (rmb.js renderMessageText / locationMap): the
   maps link inside the bubble, and a "Show map" button under it that loads an
   OpenStreetMap embed on tap. */
.rmb-location-link {
    text-decoration: underline;
}

.rmb-location-link:hover {
    color: var(--rmb-accent-text);
}

.rmb-location-map {
    text-align: left;
}

.rmb-location-map iframe {
    display: block;
    width: 20rem;
    max-width: 100%;
    height: 14rem;
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

.rmb-location-map button {
    display: block;
    margin-top: 0.25rem;
}

/* The enlarged map (rmb.js showLargeMap): nearly the whole screen. */
.rmb-location-map-large {
    width: min(56rem, calc(100vw - 2rem));
    text-align: right;
}

.rmb-location-map-large iframe {
    display: block;
    width: 100%;
    height: min(70vh, 40rem);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

.rmb-share-location[hidden] {
    display: none;
}

/* A reply shown before the server has confirmed it ("Sending..."), and one
   that failed to send (meta line carries a Retry button). */
.rmb-thread-message--pending .rmb-thread-bubble {
    opacity: 0.6;
}

.rmb-thread-message--failed .rmb-thread-bubble {
    border: 1px solid var(--rmb-danger-text);
}

.rmb-thread-message--failed .rmb-message-meta {
    color: var(--rmb-danger-text);
}

/* One-line truncated preview of the latest message; wraps on mobile, where
   the row is a card with room for it. */
.rmb-message-preview {
    display: block;
    max-width: 16rem;
    color: var(--rmb-text-muted);
    font-size: 0.85rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.rmb-conversation-row--unread .rmb-message-preview {
    color: var(--rmb-text);
}

@media (max-width: 767px) {
    .rmb-message-preview {
        max-width: none;
        white-space: normal;
    }
}

/* item rows */

.rmb-item-list {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.rmb-item-row {
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

.rmb-item-row--lost {
    border: 2px solid var(--rmb-accent-text);
}

.rmb-item-row--archived {
    opacity: 0.7;
}

.rmb-item-summary {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.65rem 1rem;
    cursor: pointer;
    list-style: none;
}

.rmb-item-summary::-webkit-details-marker {
    display: none;
}

.rmb-item-summary::after {
    content: '';
    flex: none;
    width: 7px;
    height: 7px;
    border-right: 2px solid var(--rmb-text-muted);
    border-bottom: 2px solid var(--rmb-text-muted);
    transform: rotate(45deg);
    transition: transform 0.15s ease;
}

.rmb-item-row[open] > .rmb-item-summary::after {
    transform: rotate(-135deg);
}

.rmb-item-thumb {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: var(--rmb-radius-input);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(var(--rmb-accent-rgb), 0.08);
    color: var(--rmb-accent-text);
}

.rmb-item-thumb img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: pointer;
}

.rmb-item-thumb svg {
    width: 22px;
    height: 22px;
}

.rmb-item-summary-main {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    /* Grows to fill the row, but can also shrink below its content size -
       needed so .rmb-item-name has room to truncate on a narrow screen
       instead of pushing the QR/Order controls off the row. */
    flex: 1 1 auto;
    min-width: 0;
    /* When name + category can't both fit on one line, category (and any
       badges) wrap below the name rather than shrinking the name further
       or pushing QR/Order off the row - see .rmb-item-summary below. */
    flex-wrap: wrap;
}

.rmb-item-name {
    font-weight: 700;
    color: var(--rmb-text);
    font-size: 0.9rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    /* Without this, flexbox's default min-width:auto floors the name at
       its full unwrapped width, defeating the ellipsis above - a long
       item name would still push the row wider than the screen. */
    min-width: 0;
}

.rmb-item-category-tag {
    flex: none;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    color: var(--rmb-text-muted);
    background: rgba(var(--rmb-text-rgb), 0.05);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-button);
    padding: 0.1rem 0.45rem;
    white-space: nowrap;
}

.rmb-item-badges {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
}

.rmb-item-summary .btn-rmb-primary {
    flex: none;
    padding: 0.45rem 1.1rem;
    font-size: 0.8rem;
}

.rmb-item-body {
    padding: 0 1rem 1rem;
    border-top: 1px solid var(--rmb-border);
}

.rmb-item-body p {
    color: var(--rmb-text-muted);
    font-size: 0.9rem;
    margin: 0.65rem 0 0;
}

/* Moved here from the collapsed summary - a QR-code lookup is an occasional
   action, not something that should compete with Order for row space. */
.rmb-item-qr-inline {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.65rem 0 0;
    padding: 0;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--rmb-text-muted);
    font-size: 0.85rem;
}

.rmb-item-code {
    color: var(--rmb-text);
    letter-spacing: 0.04em;
}

/* The enlarged QR's code, set big enough to read off and type. */
.rmb-qr-modal-code {
    text-align: center;
    margin-top: 0.75rem;
}

.rmb-qr-modal-code .font-mono {
    font-size: 1.35rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    color: var(--rmb-text);
}

.rmb-item-qr-inline img {
    display: block;
    flex: none;
    width: 30px;
    height: 30px;
    padding: 3px;
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: 6px;
    object-fit: contain;
}

.rmb-item-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
    margin-top: 0.9rem;
}

/* Size to content, don't grow to fill the row - "Edit" was being
   stretched as wide as "Mark as Lost" for no reason, which is most of why
   these read as oversized. white-space: nowrap below (on the actual
   button text) still gives each action a real minimum, so on a narrow
   phone an action that can't fit wraps to its own line whole rather than
   the label wrapping mid-word inside a squeezed button. */
.rmb-item-actions > * {
    flex: 0 0 auto;
}

/* These six reuse the app's standard button classes, sized for a hero CTA
   (e.g. "Register New Item") — too heavy for a dense row of utility
   actions in a disclosure panel, so trim padding/font-size here only. */
.rmb-item-actions button {
    padding: 0.4rem 0.7rem;
    font-size: 0.8rem;
    white-space: nowrap;
}

/* Print Sticker / Archive / Delete tuck into a "..." overflow menu instead
   of sitting as full-weight buttons next to Edit/Mark Lost - see the
   account dropdown above, which this reuses the same visual language for. */
.rmb-item-actions > .rmb-item-menu {
    flex: none;
    min-width: 0;
    position: relative;
}

/* Three drawn dots, not a "..." text glyph - a button's default centering
   is text-align, and letter-spacing adds trailing space after the last
   character that counts toward that centering but has no ink, so the
   dots rendered visibly left-of-center. Flex + currentColor sidesteps
   both that and any font-specific glyph/baseline quirks. */
.rmb-item-actions button.rmb-item-menu-trigger {
    width: 34px;
    height: 34px;
    padding: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
}

.rmb-item-menu-trigger span {
    display: block;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: currentColor;
    flex: none;
}

.rmb-item-menu-panel {
    display: none;
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    min-width: 170px;
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    box-shadow: 0 10px 30px rgba(var(--rmb-fixed-dark-rgb), 0.14);
    padding: 6px;
    z-index: 20;
}

.rmb-item-menu.is-open .rmb-item-menu-panel {
    display: block;
}

.rmb-item-actions .rmb-item-menu-link {
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 10px;
    border-radius: 7px;
    font-size: 0.85rem;
    font-weight: 400;
    font-family: 'Manrope', system-ui, sans-serif;
    color: var(--rmb-text);
    background: none;
    border: none;
    cursor: pointer;
}

.rmb-item-actions .rmb-item-menu-link:hover {
    background: var(--rmb-surface-hover);
}

.rmb-item-actions .rmb-item-menu-link--danger {
    color: var(--rmb-danger-text);
}

.rmb-item-actions .rmb-item-menu-link--danger:hover {
    background: rgba(var(--rmb-danger-rgb), 0.08);
}

.rmb-list-divider {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--rmb-text-muted);
    margin: 1.25rem 0 0.4rem;
}

.rmb-item-list > .rmb-list-divider:first-child {
    margin-top: 0;
}

/* My Items, grouped by where each item lives: Private, your family,
   families you've joined. Each section: a header (icon, name, who can see
   it, plan usage, who's in it) over its own .rmb-item-list. */
.rmb-item-sections {
    display: flex;
    flex-direction: column;
    gap: 1.75rem;
}

.rmb-item-section-head {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 0.75rem;
}

.rmb-item-section-icon {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border-radius: 10px;
    color: var(--rmb-accent-text);
    background: rgba(var(--rmb-accent-rgb), 0.1);
}

.rmb-item-section-icon svg {
    width: 18px;
    height: 18px;
}

.rmb-item-section-title {
    flex: 1;
    min-width: 0;
}

.rmb-item-section-title h3 {
    font-size: 1rem;
    font-weight: 700;
    line-height: 1.3;
    color: var(--rmb-text);
}

.rmb-item-section-title .rmb-hint {
    font-size: 0.8rem;
}

/* A person's initial in a circle. Neutral, so it never competes with
   accent (primary action / Lost); the viewer's own is accent-tinted. */
.rmb-avatar {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border-strong);
    color: var(--rmb-text);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.65rem;
    font-weight: 600;
    line-height: 1;
}

.rmb-avatar--you {
    background: rgba(var(--rmb-accent-rgb), 0.12);
    border-color: var(--rmb-accent-text);
    color: var(--rmb-accent-text);
}

/* Who's in a family: overlapping avatars. */
.rmb-avatar-stack {
    flex: none;
    display: inline-flex;
}

.rmb-avatar-stack .rmb-avatar {
    width: 26px;
    height: 26px;
    font-size: 0.7rem;
    box-shadow: 0 0 0 2px var(--rmb-surface);
}

.rmb-avatar-stack .rmb-avatar + .rmb-avatar {
    margin-left: -7px;
}

/* Who added an item, on its row in a shared family. */
.rmb-item-creator {
    flex: none;
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-size: 0.75rem;
    color: var(--rmb-text-muted);
}

.rmb-item-creator .rmb-avatar {
    width: 18px;
    height: 18px;
    font-size: 0.6rem;
}

/* The summary row itself never wraps - QR/Order should never drop off
   to their own line. .rmb-item-summary-main (name + category + badges)
   wraps internally instead, so the category tag is what gives up its
   spot on a narrow screen, not the primary controls. */

.rmb-page-title {
    color: var(--rmb-text);
}

.text-rmb-danger {
    color: var(--rmb-danger-text);
}

/* rmb nav & footer */

.rmb-nav {
    background: var(--rmb-nav-surface);
    border-bottom: 1px solid var(--rmb-nav-border);
}

/* Hidden unconditionally by default; .is-open only re-enables it inside
   the same max-width range the hamburger button itself is visible in
   (Tailwind's lg breakpoint, 1024px) - so resizing past that point hides
   the panel via the media query alone, with no JS involved. Previously
   this was toggled with mobileMenu.style.display in a <script> in
   layout.html: an inline style always wins over a class-based rule (media
   query or not), so resizing past lg while the menu was open left it
   stuck open - the hamburger button (hidden via a plain Tailwind class)
   would disappear, but the panel had no reason to. */
#mobile-menu {
    display: none;
    /* Same plane the nav bar itself sits on, with the same hairline it
       already uses to separate itself from the page - reads as a
       continuation of the nav (a drawer), not more page content. */
    background: var(--rmb-nav-surface);
    border-top: 1px solid var(--rmb-nav-border);
}

@media (max-width: 1023.98px) {
    #mobile-menu.is-open {
        display: block;
    }
}

.rmb-nav-link {
    color: var(--rmb-text-muted);
}

.rmb-nav-link:hover {
    color: var(--rmb-accent-text);
}

.rmb-nav-ping {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: var(--rmb-danger-text);
}

/* Cart's item-count badge - unlike .rmb-nav-ping (a bare "something
   changed" dot), this carries an actual number, so it sits inline after
   the word rather than pinned to a corner, and reuses the same accent
   fill + mono digits as .rmb-account-avatar for the same reason: small
   numeric/id-like content reads as system UI in mono, not body text. */
.rmb-nav-count {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    margin-left: 4px;
    border-radius: 999px;
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    font-weight: 600;
    vertical-align: middle;
}

/* account dropdown */

.rmb-account {
    position: relative;
    list-style: none;
}

.rmb-account-btn {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    background: var(--rmb-surface-hover);
    border: 1px solid var(--rmb-border);
    border-radius: 999px;
    padding: 5px 12px 5px 6px;
    color: var(--rmb-text);
    font-weight: 600;
    font-size: 0.9rem;
    cursor: pointer;
}

.rmb-account-btn:hover {
    border-color: var(--rmb-accent-text);
}

.rmb-account-avatar {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 11px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-account-caret {
    font-size: 10px;
    color: var(--rmb-text-muted);
    transition: transform 0.15s ease;
}

.rmb-account.is-open .rmb-account-caret {
    transform: rotate(180deg);
}

.rmb-account.is-open .rmb-account-btn {
    border-color: var(--rmb-accent-text);
}

.rmb-account-menu {
    display: none;
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    min-width: 220px;
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    box-shadow: 0 10px 30px rgba(var(--rmb-fixed-dark-rgb), 0.14);
    padding: 6px;
    z-index: 30;
}

.rmb-account.is-open .rmb-account-menu {
    display: block;
}

.rmb-account-menu-link {
    display: block;
    padding: 8px 10px;
    border-radius: 7px;
    font-size: 0.9rem;
    color: var(--rmb-text);
}

.rmb-account-menu-link:hover {
    background: var(--rmb-surface-hover);
    color: var(--rmb-text);
}

.rmb-account-menu-link--danger {
    color: var(--rmb-danger-text);
}

.rmb-account-menu-link--danger:hover {
    background: rgba(var(--rmb-danger-rgb), 0.08);
}

/* A family in the Account menu's switcher: a form button dressed as a menu
   link, with the selected family marked (templates/_family_switcher.html). */
.rmb-family-switch {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    text-align: left;
    background: none;
    border: 0;
    cursor: pointer;
}

.rmb-family-switch--current {
    font-weight: 700;
}

.rmb-family-switch--current > span:first-child::before {
    content: "✓";
    margin-right: 6px;
    color: var(--rmb-accent-text);
}

.rmb-account-menu-divider {
    height: 1px;
    background: var(--rmb-border);
    margin: 4px 2px;
}

.rmb-profile-avatar {
    width: 64px;
    height: 64px;
    border-radius: 50%;
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 26px;
    font-weight: 600;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-profile-links {
    display: flex;
    flex-direction: column;
}

.rmb-profile-link {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 14px 6px;
    border-top: 1px solid var(--rmb-border);
    color: var(--rmb-text);
    font-weight: 600;
}

.rmb-profile-links .rmb-profile-link:first-child {
    border-top: none;
}

.rmb-profile-link:hover {
    color: var(--rmb-text);
    background: var(--rmb-surface-hover);
    border-radius: 8px;
}

.rmb-edit-link {
    color: var(--rmb-text-muted);
    font-size: 0.875rem;
    line-height: 1;
    padding: 4px;
    border-radius: 6px;
}

/* Segmented control: a row of equal options, one selected - buttons with
   aria-pressed (Profile's theme) or links with aria-current (My Items'
   All / Private / Family). */
.rmb-segments {
    display: flex;
    gap: 0.5rem;
}

.rmb-segment {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    padding: 0.6rem 0.5rem;
    background: none;
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-button);
    color: var(--rmb-text-muted);
    font-weight: 600;
    font-size: 0.875rem;
    text-decoration: none;
    cursor: pointer;
}

.rmb-segment:hover {
    color: var(--rmb-text);
    border-color: var(--rmb-text-muted);
}

.rmb-segment[aria-pressed="true"],
.rmb-segment[aria-current="page"] {
    color: var(--rmb-accent-text);
    border-color: var(--rmb-accent-text);
    background: rgba(var(--rmb-accent-rgb), 0.08);
}

.rmb-segment-count {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    font-weight: 400;
}

.rmb-edit-link:hover {
    color: var(--rmb-accent-text);
    background: var(--rmb-surface-hover);
}

.rmb-display-name-form {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    margin-bottom: 0.25rem;
}

.rmb-display-name-form .rmb-input {
    width: auto;
    margin-top: 0;
}

.rmb-account-menu-label {
    display: block;
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--rmb-border-strong);
    padding: 8px 10px 2px;
}

/* Admin-only release tag under Logout: selectable so it can be copied. */
.rmb-account-menu-release {
    padding-bottom: 6px;
    text-transform: none;
    user-select: text;
}

.rmb-footer {
    background: var(--rmb-fixed-dark);
}

.rmb-footer-text {
    color: rgba(var(--rmb-text-on-fixed-dark-rgb), 0.55); /* muted text on --rmb-fixed-dark */
}

.rmb-footer-link {
    color: rgba(var(--rmb-text-on-fixed-dark-rgb), 0.75); /* brighter than .rmb-footer-text, on --rmb-fixed-dark */
}

.rmb-footer-link:hover {
    color: var(--rmb-text-on-accent);
}

/* rmb items/cards */

.rmb-card {
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    padding: 1rem;
    position: relative;
}

.rmb-card--featured {
    border: 2px solid var(--rmb-accent-text);
}

.rmb-card-ribbon {
    position: absolute;
    top: -0.9rem;
    left: 50%;
    transform: translateX(-50%);
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.7rem;
    line-height: 1.4;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    white-space: nowrap;
    padding: 0.3rem 0.7rem;
    border-radius: var(--rmb-radius-button);
}

.rmb-plan-feature {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.rmb-check {
    width: 16px;
    height: 16px;
    flex-shrink: 0;
}

.rmb-empty-icon {
    width: 64px;
    height: 64px;
    margin: 0 auto 1rem;
    display: block;
}

.rmb-card h3 {
    font-size: 1.1rem;
    font-weight: 800;
    color: var(--rmb-text);
    margin-bottom: 0.5rem;
}

.rmb-card p {
    color: var(--rmb-text-muted);
    font-size: 0.9rem;
    margin-bottom: 0.35rem;
}

.rmb-card p strong {
    color: var(--rmb-text);
}

.rmb-card .price-text {
    color: var(--rmb-text);
    font-size: 1.5rem;
    font-weight: 800;
    margin-bottom: 0.75rem;
}

.rmb-badge {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    font-weight: 700;
    padding: 0.2rem 0.55rem;
    border-radius: var(--rmb-radius-button);
    display: inline-block;
    border: 1px solid var(--rmb-border);
    color: var(--rmb-text);
}

.rmb-item-image-wrap {
    position: relative;
    /* Bleeds to the card's edges, undoing .rmb-card's 1rem padding, so the
       banner reaches the card's own rounded corners flush. */
    margin: -1rem -1rem 0.75rem;
    aspect-ratio: 4 / 3;
    background: var(--rmb-fixed-dark);
    border-radius: var(--rmb-radius-panel) var(--rmb-radius-panel) 0 0;
    overflow: hidden;
}

.rmb-item-image {
    display: block;
    width: 100%;
    height: 100%;
    /* contain (not cover) so the whole item stays visible; the dark wrap
       background shows through as a letterbox for any photo whose aspect
       ratio doesn't match the 4:3 box, keeping every card the same shape. */
    object-fit: contain;
    cursor: pointer;
}

.rmb-item-image-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: rgba(var(--rmb-text-on-fixed-dark-rgb), 0.45);
}

.rmb-item-image-placeholder svg {
    width: 40px;
    height: 40px;
}

.rmb-clamp-2 {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.rmb-badge--lost {
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
    border-color: var(--rmb-accent);
}

.rmb-badge--active {
    background: var(--rmb-success);
    color: var(--rmb-text-on-accent);
    border-color: var(--rmb-success);
}

.rmb-badge--danger {
    background: var(--rmb-danger);
    color: var(--rmb-text-on-accent);
    border-color: var(--rmb-danger);
}

.btn-rmb-secondary {
    background: var(--rmb-surface);
    color: var(--rmb-text);
    border: 1px solid var(--rmb-border-strong);
    font-weight: 700;
    padding: 0.5rem 0.9rem;
    border-radius: var(--rmb-radius-button);
    transition: border-color 0.15s ease, color 0.15s ease;
}

.btn-rmb-secondary:hover:not(:disabled) {
    border-color: var(--rmb-text);
}

.btn-rmb-danger {
    background: var(--rmb-danger);
    color: var(--rmb-text-on-accent);
    font-weight: 700;
    padding: 0.5rem 0.9rem;
    border-radius: var(--rmb-radius-button);
    transition: background 0.15s ease;
}

.btn-rmb-danger:hover:not(:disabled) {
    background: var(--rmb-danger-hover);
}

.btn-rmb-primary:disabled,
.btn-rmb-secondary:disabled,
.btn-rmb-danger:disabled,
.btn-rmb-lost:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Outlined in the "lost" accent (same hue as .rmb-badge--lost) rather than
   solid-filled like .btn-rmb-primary — flagging an item as lost is a state
   toggle, not the page's main positive CTA, so it shouldn't carry the same
   visual weight as a filled button. */
.btn-rmb-lost {
    background: var(--rmb-surface);
    color: var(--rmb-accent-text);
    border: 1px solid var(--rmb-accent-text);
    font-weight: 700;
    padding: 0.5rem 0.9rem;
    border-radius: var(--rmb-radius-button);
    transition: background 0.15s ease, color 0.15s ease;
}

.btn-rmb-lost:hover:not(:disabled) {
    background: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
}

/* These set their own display, which ties with Tailwind's .hidden
   at equal specificity — since this stylesheet loads after the
   Tailwind CDN link, our display wins the tie and .hidden silently
   does nothing on these unless overridden here. */
.btn-rmb-primary.hidden,
.btn-rmb-secondary.hidden,
.btn-rmb-danger.hidden,
.btn-rmb-lost.hidden,
.rmb-badge.hidden,
.rmb-display-name-form.hidden {
    display: none;
}

.rmb-modal {
    background: rgba(var(--rmb-fixed-dark-rgb), 0.6); /* --rmb-fixed-dark at 60% opacity */
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    opacity: 1;
    /* Above .rmb-item-menu-panel (20) and .rmb-account-menu (30) - without
       this, either dropdown left open (e.g. by its own Delete/Profile link
       opening this modal) paints above the modal overlay and stays
       clickable through it. Below .rmb-toast-container's z-index: 50, so an
       AJAX error toast from a modal's own submit still surfaces on top. */
    z-index: 40;
    transition: opacity 0.2s ease, display 0.2s allow-discrete;
}

.rmb-modal.hidden {
    display: none;
    opacity: 0;
}

/* Applied to <body> while any .rmb-modal is open (see rmb.js lockScroll).
   position:fixed, not plain overflow:hidden, because iOS Safari doesn't
   reliably block background touch-scroll otherwise; rmb.js sets the
   matching negative `top` offset inline before adding this class. */
body.rmb-scroll-locked {
    position: fixed;
    left: 0;
    right: 0;
    overflow: hidden;
}

@starting-style {
    .rmb-modal:not(.hidden) {
        opacity: 0;
    }
}

.rmb-modal-content,
.rmb-panel {
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    box-shadow: 0 20px 60px -15px rgba(var(--rmb-fixed-dark-rgb), 0.35);
}

.rmb-modal-content h2,
.rmb-panel h2 {
    color: var(--rmb-text);
}

.rmb-modal-content label,
.rmb-panel label {
    color: var(--rmb-text);
}

.rmb-modal-content p,
.rmb-panel p {
    color: var(--rmb-text-muted);
}

.rmb-modal-close {
    color: var(--rmb-text);
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: 50%;
    padding: 4px;
    box-shadow: 0 2px 6px -1px rgba(var(--rmb-fixed-dark-rgb), 0.25);
}

.rmb-modal-close:hover {
    color: var(--rmb-accent-text);
    background: var(--rmb-surface-hover);
}

.rmb-toast-container {
    position: fixed;
    top: 132px; /* clears the 116px-tall nav (driven by the 100px logo) plus a gap */
    right: 1rem;
    z-index: 50;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    max-width: min(90vw, 380px);
    animation: rmbToastIn 0.25s ease;
}

.rmb-toast-container.rmb-toast-hide,
.rmb-toast.rmb-toast-hide {
    animation: rmbToastOut 0.2s ease forwards;
}

.rmb-toast {
    background: var(--rmb-surface);
    border-left: 4px solid var(--rmb-text-muted);
    border-radius: var(--rmb-radius-panel);
    box-shadow: 0 20px 60px -15px rgba(var(--rmb-fixed-dark-rgb), 0.35);
    padding: 0.9rem 1.1rem;
    font-size: 0.9rem;
    color: var(--rmb-text);
}

.rmb-toast--success {
    border-left-color: var(--rmb-success-text);
}

.rmb-toast--danger {
    border-left-color: var(--rmb-danger-text);
}

.rmb-toast--warning {
    border-left-color: var(--rmb-accent-text);
}

.rmb-alert {
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    padding: 0.75rem 1rem;
}

.rmb-alert--danger {
    border-color: var(--rmb-danger-text);
    color: var(--rmb-danger-text);
    background: rgba(var(--rmb-danger-rgb), 0.08); /* --rmb-danger at low opacity */
}

.rmb-alert--warning {
    border-color: var(--rmb-accent-text);
    color: var(--rmb-accent-text);
    background: rgba(var(--rmb-accent-rgb), 0.08); /* --rmb-accent at low opacity */
}

@keyframes rmbToastIn {
    from {
        opacity: 0;
        transform: translateY(-8px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes rmbToastOut {
    to {
        opacity: 0;
        transform: translateY(-8px);
    }
}

.rmb-input {
    display: block;
    width: 100%;
    margin-top: 0.25rem;
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-input);
    padding: 0.5rem 0.6rem;
    color: var(--rmb-text);
}

/* Compact quantity field for table cells. The attribute selector matches the
   specificity of the global input[type="number"] rule so its width doesn't win. */
input[type="number"].rmb-input--qty {
    width: 4.5rem;
    max-width: 100%;
}

/* Compact inline select, e.g. the role dropdown on each Family page row. */
.rmb-input--compact {
    display: inline-block;
    width: auto;
    margin-top: 0;
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
}

.rmb-input:focus {
    outline: none;
    border-color: var(--rmb-accent-text);
}

.rmb-table {
    width: 100%;
    border-collapse: collapse;
    background: var(--rmb-surface);
}

.rmb-table th {
    color: var(--rmb-text-muted);
    font-weight: 700;
    text-align: left;
    border-bottom: 1px solid var(--rmb-border);
}

.rmb-table td {
    color: var(--rmb-text);
    border-bottom: 1px solid var(--rmb-border);
}

/* Collapsible responsive table: a normal <table> at >=768px; at <768px each
   row becomes its own bordered card, with a data-label attribute on each td
   supplying the label a real <th> would have shown. Replaces the older
   pattern (used nowhere in this app after this change) of duplicating every
   row into a separate table row *and* a separate card block. */
@media (max-width: 767px) {
    .rmb-table--responsive,
    .rmb-table--responsive tbody,
    .rmb-table--responsive tr,
    .rmb-table--responsive td {
        display: block;
        width: 100%;
    }

    .rmb-table--responsive thead {
        display: none;
    }

    .rmb-table--responsive tr {
        background: var(--rmb-surface);
        border: 1px solid var(--rmb-border);
        border-radius: var(--rmb-radius-panel);
        padding: 1rem;
        margin-bottom: 1rem;
    }

    .rmb-table--responsive td {
        border-bottom: none;
        padding: 0.25rem 0;
    }

    /* Default: label + value on one line, like a real column header would show. */
    .rmb-table--responsive td[data-label]:not(.rmb-td--block) {
        display: flex;
        justify-content: space-between;
        align-items: baseline;
        gap: 1rem;
    }

    .rmb-table--responsive td[data-label]:not(.rmb-td--block)::before {
        content: attr(data-label);
        font-weight: 700;
        color: var(--rmb-text-muted);
        flex-shrink: 0;
    }

    /* The row's "title" cell (Order #123 / a user's name) - no label, bigger text. */
    .rmb-table--responsive td.rmb-td--heading {
        font-weight: 700;
        font-size: 1.05rem;
    }

    /* Cells that don't fit the label:value shape (item lists, action buttons,
       the bare checkbox) - full-width block, no label prefix. */
    .rmb-table--responsive td.rmb-td--block {
        padding-top: 0.5rem;
    }
}

/* DataTables reskin: we don't load DataTables' own CSS, so every visible
   piece it renders (search box, length select, paging, info line, sort
   arrows) is styled here from the `dt-*` classes its JS applies, using the
   same tokens as the rest of the table. */
.dt-layout-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.75rem;
}

.dt-layout-row:has(.dt-search),
.dt-layout-row:has(.dt-length) {
    margin-bottom: 0.75rem;
}

/* The row wrapping the <table> itself is also a .dt-layout-row - the flex
   layout above is for the search/length/info/paging rows only. A flex row
   with justify-content: space-between doesn't stretch a single child to
   fill it, so the table would size to its content and sit at the start
   instead of spanning the page. */
.dt-layout-row:has(table) {
    display: block;
}

.dt-layout-row:has(.dt-info),
.dt-layout-row:has(.dt-paging) {
    margin-top: 1rem;
}

.dt-search,
.dt-length {
    display: flex;
    align-items: center;
}

.dt-search label,
.dt-length label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    color: var(--rmb-text-muted);
    font-size: 0.875rem;
    white-space: nowrap;
}

.dt-length select {
    margin-right: 0.4rem;
}

.dt-input {
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-input);
    padding: 0.4rem 0.6rem;
    color: var(--rmb-text);
}

.dt-input:focus {
    outline: none;
    border-color: var(--rmb-accent-text);
}

.dt-info {
    color: var(--rmb-text-muted);
    font-size: 0.875rem;
}

.dt-paging {
    display: flex;
    gap: 0.35rem;
}

.dt-paging-button {
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-button);
    padding: 0.3rem 0.7rem;
    color: var(--rmb-text);
    font-size: 0.875rem;
}

.dt-paging-button:hover {
    border-color: var(--rmb-text);
}

.dt-paging-button.current {
    background: var(--rmb-accent);
    border-color: var(--rmb-accent);
    color: var(--rmb-text-on-accent);
}

.dt-paging-button.disabled {
    color: var(--rmb-border-strong);
    border-color: var(--rmb-border);
}

th.dt-orderable-asc,
th.dt-orderable-desc {
    cursor: pointer;
}

.dt-column-order {
    display: inline-block;
    margin-left: 0.35rem;
    font-size: 0.75rem;
}

.dt-orderable-asc .dt-column-order::after,
.dt-orderable-desc .dt-column-order::after {
    content: '\21C5'; /* up/down arrows: sortable, not yet sorted */
    color: var(--rmb-border-strong);
}

th.dt-ordering-asc .dt-column-order::after {
    content: '\2191'; /* up arrow: sorted ascending */
    color: var(--rmb-accent-text);
}

th.dt-ordering-desc .dt-column-order::after {
    content: '\2193'; /* down arrow: sorted descending */
    color: var(--rmb-accent-text);
}

.rmb-cart-summary {
    border-top: 1px solid var(--rmb-border);
    padding-top: 1rem;
}

/* subscription style */
/* Add to your static/style.css or equivalent */

.toggle-path {
    width: 48px;
    height: 24px;
    border-radius: 12px;
    background-color: var(--rmb-border);
    position: relative;
    transition: background-color 0.3s ease-in-out;
}

.toggle-circle {
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background-color: var(--rmb-surface);
    position: absolute;
    top: 0;
    left: 0;
    transform: translateX(0);
    transition: transform 0.3s ease-in-out;
}

input:checked ~ .toggle-circle {
    transform: translateX(24px);
}

input:checked ~ .toggle-path {
    background-color: var(--rmb-accent);
}

/* ---- Printed QR sticker (_qr_sticker.html, issue #137) ----
   A physical label, so its colours are fixed print colours from
   app/stickers.py (set as --sticker-* on the element), not page tokens: it
   looks the same in light and dark mode. Every measurement is a fraction of
   --sticker-size, which is real millimetres when printed. */
.rmb-sticker {
    --s: var(--sticker-size);
    box-sizing: border-box;
    flex: none;
    width: var(--s);
    height: var(--s);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: calc(var(--s) * 0.025);
    padding: calc(var(--s) * 0.04);
    border: calc(var(--s) * 0.02) solid var(--sticker-ink);
    border-radius: var(--sticker-radius);
    background: var(--sticker-tint);
    color: var(--sticker-ink);
    font-family: 'Manrope', sans-serif;
    line-height: 1;
    text-align: center;
    overflow: hidden;
    /* Browsers drop background colours when printing unless told not to. */
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
}

.rmb-sticker-wordmark {
    font-size: calc(var(--s) * var(--sticker-wordmark));
    font-weight: 800;
    letter-spacing: -0.02em;
    white-space: nowrap;
}

/* The code always sits on white, whatever the theme - contrast is what
   makes it scan. */
.rmb-sticker-qr {
    display: block;
    flex: none;
    width: calc(var(--s) * var(--sticker-qr));
    height: calc(var(--s) * var(--sticker-qr));
    background: #ffffff;
    border-radius: calc(var(--s) * 0.03);
    overflow: hidden;
}

.rmb-sticker-qr svg {
    display: block;
    width: 100%;
    height: 100%;
}

.rmb-sticker-scan {
    font-size: calc(var(--s) * var(--sticker-scan));
    font-weight: 800;
    letter-spacing: 0.14em;
    /* Balances the trailing letter-spacing so the word stays centred. */
    padding-left: 0.14em;
    text-transform: uppercase;
    white-space: nowrap;
}

.rmb-sticker-code {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: calc(var(--s) * var(--sticker-code));
    font-weight: 600;
    letter-spacing: 0.04em;
    white-space: nowrap;
}

.rmb-sticker [hidden] {
    display: none;
}

/* Print dialog (items.html): preview above the options on a phone, beside
   them on a wider screen. */
.rmb-sticker-dialog {
    width: min(32rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    overflow-y: auto;
}

.rmb-sticker-dialog-body {
    display: grid;
    gap: 1rem;
}

/* Print stays in reach while the options scroll on a small screen. The
   negative bottom covers the dialog's own padding, so nothing scrolls
   visibly under the buttons. */
.rmb-sticker-dialog-actions {
    position: sticky;
    bottom: -1rem;
    margin: 1rem -1rem -1rem;
    padding: 0.75rem 1rem 1rem;
    background: var(--rmb-surface);
    border-top: 1px solid var(--rmb-border);
}

.rmb-sticker-dialog-options {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

@media (min-width: 768px) {
    .rmb-sticker-dialog {
        width: min(52rem, calc(100vw - 2rem));
    }

    .rmb-sticker-dialog-body {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 1.5rem;
        align-items: start;
    }

    .rmb-sticker-stage {
        min-height: 20rem;
    }
}

.rmb-sticker-stage {
    display: flex;
    align-items: center;
    justify-content: center;
    /* Fits the largest preset at the preview scale (60 mm at 4 px/mm), so
       the dialog doesn't jump in height when the size changes. */
    min-height: 17rem;
    padding: 1rem;
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

/* The preview's scene: the sticker alone, or placed on a to-scale picture
   of a thing (app.stickers.STICKER_MOCKUPS). placeSticker() in items.html
   sizes it and positions the sticker in px from the picture's mm. */
.rmb-sticker-scene {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-sticker-scene--item {
    display: block;
    flex: none;
}

.rmb-sticker-scene--item > img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 6px 10px rgba(var(--rmb-fixed-dark-rgb), 0.18));
}

.rmb-sticker-scene--item > .rmb-sticker {
    position: absolute;
    box-shadow: 0 1px 2px rgba(var(--rmb-fixed-dark-rgb), 0.35);
}

.rmb-modal-content .rmb-sticker-fit-note {
    color: var(--rmb-accent-text);
}

/* Radio choices drawn as selectable chips (the native radio stays in the
   DOM, focusable, for keyboard and screen readers). */
.rmb-choice-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
}

.rmb-choice-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.5rem;
}

.rmb-choice,
.rmb-swatch {
    position: relative;
    cursor: pointer;
}

.rmb-choice input,
.rmb-swatch input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px;
}

.rmb-choice > span {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    height: 100%;
    padding: 0.45rem 0.8rem;
    color: var(--rmb-text);
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border-strong);
    border-radius: var(--rmb-radius-input);
    font-size: 0.9rem;
    line-height: 1.25;
}

.rmb-choice small {
    color: var(--rmb-text-muted);
    font-size: 0.75rem;
}

.rmb-choice input:checked + span {
    border-color: var(--rmb-accent-text);
    box-shadow: inset 0 0 0 1px var(--rmb-accent-text);
    background: rgba(var(--rmb-accent-rgb), 0.08);
}

.rmb-choice input:disabled + span {
    opacity: 0.45;
    cursor: not-allowed;
}

.rmb-swatch-dot {
    display: block;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--swatch);
    border: 3px solid var(--rmb-surface);
    box-shadow: 0 0 0 1px var(--rmb-border-strong);
}

.rmb-swatch input:checked + .rmb-swatch-dot {
    box-shadow: 0 0 0 2px var(--rmb-text);
}

.rmb-choice input:focus-visible + span,
.rmb-swatch input:focus-visible + .rmb-swatch-dot {
    outline: 2px solid var(--rmb-accent-text);
    outline-offset: 2px;
}

/* print-only content, e.g. printSticker() in items.html: kept out of the
   layout on screen. While body has .rmb-printing it's the only thing
   printed; any other print of the page is left alone. */
#printArea {
    position: absolute;
    width: 0;
    height: 0;
    overflow: hidden;
}

/* A faint dashed line around the sticker to cut along, a little outside
   its edge so a slightly-off cut doesn't eat into the colour border. */
.rmb-sticker-cutline {
    padding: 1.5mm;
    border: 0.2mm dashed #b8b0a8;
    border-radius: 3mm;
}

.rmb-sticker-cutline--round {
    border-radius: 50%;
}

/* Shipping stickers (sticker_ship.html, sticker_shipment.html, issue #140) */
.rmb-ship-facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
    gap: 1rem;
}

.rmb-ship-form {
    display: grid;
    gap: 1rem;
}

@media (min-width: 768px) {
    .rmb-ship-form {
        grid-template-columns: 12rem minmax(0, 1fr);
    }
}

.rmb-address-block {
    font-style: normal;
    line-height: 1.5;
    color: var(--rmb-text);
}

/* The address label: a plain black-on-white block sized to cut out and
   stick on a C5/C6 envelope, whatever the theme. */
.rmb-ship-label {
    width: 100mm;
    max-width: 100%;
    padding: 6mm 8mm;
    border: 0.3mm dashed #96897a;
    background: #ffffff;
    color: #1c1a18;
    font-family: 'Manrope', sans-serif;
}

.rmb-ship-label-from {
    font-size: 8pt;
    font-weight: 800;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #6b6058;
    margin-bottom: 4mm;
}

.rmb-ship-label-to {
    font-style: normal;
    font-size: 13pt;
    line-height: 1.4;
}

.rmb-ship-codes {
    columns: 3 10rem;
    column-gap: 1.5rem;
    color: var(--rmb-text);
}

.rmb-ship-codes li {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    break-inside: avoid;
    padding: 0.15rem 0;
}

.rmb-ship-tick {
    width: 0.85rem;
    height: 0.85rem;
    border: 1px solid var(--rmb-border-strong);
    border-radius: 3px;
    flex: none;
}

/* Stickers on items (issue #141) */
.rmb-item-sticker-code {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0.65rem 0 0;
    color: var(--rmb-text);
}

.rmb-family-stickers li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.25rem 0.75rem;
    padding: 0.4rem 0;
    border-top: 1px solid var(--rmb-border);
    color: var(--rmb-text);
}

.rmb-family-sticker-code,
.rmb-family-sticker-status {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    overflow-wrap: anywhere;
}

.rmb-family-sticker-status {
    margin-left: auto;
    justify-content: flex-end;
}

/* A finder types the code printed under a QR (_code_entry_form.html). */
.rmb-code-entry {
    display: flex;
    gap: 0.5rem;
    width: 100%;
}

.rmb-code-entry-input {
    flex: 1;
    min-width: 0;
    text-transform: uppercase;
    letter-spacing: 0.08em;
}

.rmb-code-entry-input::placeholder {
    letter-spacing: 0.08em;
}

.rmb-code-entry .btn-rmb-primary {
    flex: none;
}

.rmb-code-entry-error {
    margin-top: 0.5rem;
    font-size: 0.85rem;
    color: var(--rmb-danger-text);
    text-align: left;
}

/* Home page: "Found something?" under the hero. */
.rmb-finder-band {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 1rem 1.5rem;
    padding: 1.25rem 1.5rem;
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
}

.rmb-finder-band-text {
    flex: 1 1 16rem;
}

.rmb-finder-band .rmb-code-entry {
    flex: 1 1 18rem;
    width: auto;
}

/* The item a sticker's link jumped to (rmb.js opens it). */
.rmb-item-row:target {
    outline: 2px solid var(--rmb-accent-text);
    outline-offset: 2px;
}

.rmb-choice--block {
    display: block;
}

.rmb-connect-list {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rmb-connect-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.6rem 0.8rem;
    text-align: left;
    background: var(--rmb-surface);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    color: var(--rmb-text);
    cursor: pointer;
}

.rmb-connect-option:hover,
.rmb-connect-option:focus-visible {
    border-color: var(--rmb-accent-text);
    background: var(--rmb-surface-hover);
}

.rmb-connect-name {
    display: flex;
    flex-direction: column;
    flex: 1;
    font-weight: 700;
}

/* Postal address on the profile (issue #140): two columns for postal code
   and city, everything else full width. */
.rmb-address-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 0.9rem;
}

@media (min-width: 640px) {
    .rmb-address-form {
        grid-template-columns: 10rem minmax(0, 1fr);
    }

    .rmb-address-field--wide {
        grid-column: 1 / -1;
    }
}

.rmb-field-error {
    margin-top: 0.25rem;
    font-size: 0.85rem;
    color: var(--rmb-danger-text);
}

/* ---- Admin sticker batches (sticker_batches.html, sticker_sheets.html,
   issue #139) ---- */
.rmb-batch-form {
    display: grid;
    gap: 1rem;
}

@media (min-width: 768px) {
    .rmb-batch-form {
        grid-template-columns: 12rem minmax(0, 1fr) auto;
        align-items: start;
    }

    .rmb-batch-form-submit {
        padding-top: 2rem;
    }
}

@media (min-width: 768px) {
    .rmb-ship-customer {
        grid-column: 1 / 3;
    }
}

.rmb-sheet-options {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.rmb-print-tips {
    list-style: disc;
    padding-left: 1.25rem;
}

.rmb-print-tips li + li {
    margin-top: 0.25rem;
}

/* A4 batch sheets. On screen each is drawn as a sheet of paper; printed,
   each fills one page inside the @page margin. The grid's numbers come
   from app.stickers.sheet_layout(): columns, and the cell (sticker plus
   its cut line), set as --sheet-columns / --sheet-cell. */
.rmb-sticker-sheets {
    overflow-x: auto;
    padding-bottom: 1rem;
}

.rmb-sticker-sheet {
    box-sizing: border-box;
    width: 210mm;
    min-height: 297mm;
    margin: 0 auto 1.5rem;
    /* Matches the printed page margin (SHEET_MARGIN_MM). */
    padding: 10mm;
    background: #ffffff;
    border: 1px solid var(--rmb-border);
    box-shadow: 0 10px 30px -12px rgba(var(--rmb-fixed-dark-rgb), 0.35);
    display: grid;
    grid-template-columns: repeat(var(--sheet-columns), var(--sheet-cell));
    grid-auto-rows: var(--sheet-cell);
    gap: 3mm;
    justify-content: center;
    align-content: start;
}

.rmb-sticker-sheet > .rmb-sticker-cutline {
    display: flex;
    align-items: center;
    justify-content: center;
}

.rmb-print-blocked-note {
    display: none;
}

.rmb-batch-shipments li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0;
    border-top: 1px solid var(--rmb-border);
    color: var(--rmb-text);
}

/* A code's sticker in the batch page's QR dialog: big enough to scan from
   the screen, whatever size the sticker prints at. */
.rmb-code-preview .rmb-sticker {
    --sticker-size: 15rem !important;
}

/* Archived shop products (manage_products.html, issue #49): one row each. */
.rmb-archived-products li {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.6rem 0;
    border-top: 1px solid var(--rmb-border);
    color: var(--rmb-text);
}

/* An order's sum: one line per part, the total under a hairline. */
.rmb-order-summary {
    color: var(--rmb-text);
}

.rmb-order-summary > div {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.2rem 0;
}

.rmb-order-summary dd {
    font-variant-numeric: tabular-nums;
}

.rmb-order-summary > .rmb-order-summary-total {
    border-top: 1px solid var(--rmb-border);
    margin-top: 0.25rem;
    padding-top: 0.5rem;
    font-weight: 800;
}

/* The buy stickers page's pack choices (issue #61): stacked. */
.rmb-sticker-packs {
    display: grid;
    gap: 0.5rem;
}

/* ---- Scanning a sticker with the camera (_qr_scanner.html, issue #154) ---- */

.rmb-qr-viewfinder {
    width: min(100%, 20rem);
    margin-top: 0.5rem;
}

/* The video and its guide, clipped together to the rounded corners. */
.rmb-qr-view {
    position: relative;
    overflow: hidden;
    border-radius: var(--rmb-radius-panel);
}

.rmb-qr-viewfinder[hidden] {
    display: none;
}

.rmb-qr-viewfinder video {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    object-fit: cover;
    background: var(--rmb-fixed-dark);
}

/* Where to hold the QR: a square in the middle of the view. */
.rmb-qr-viewfinder-guide {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 60%;
    aspect-ratio: 1;
    transform: translate(-50%, -50%);
    border: 3px solid rgb(var(--rmb-text-on-fixed-dark-rgb));
    border-radius: var(--rmb-radius-input);
    box-shadow: 0 0 0 999px rgba(var(--rmb-fixed-dark-rgb), 0.35);
    pointer-events: none;
}

.rmb-qr-stop {
    margin-top: 0.5rem;
}

/* ---- "Print your own sticker" guide (print_guide.html, issue #138) ---- */

.rmb-guide {
    max-width: 60rem;
    margin: 0 auto;
    color: var(--rmb-text);
}

.rmb-guide-header {
    border-bottom: 1px solid var(--rmb-border);
    padding-bottom: 1.25rem;
    margin-bottom: 1.5rem;
}

.rmb-guide-lead {
    max-width: 40rem;
    font-size: 1.05rem;
    line-height: 1.6;
    color: var(--rmb-text-muted);
}

.rmb-guide-needs {
    background: var(--rmb-surface-sunken);
    border: 1px solid var(--rmb-border);
    border-radius: var(--rmb-radius-panel);
    padding: 1rem 1.25rem;
}

.rmb-guide-needs h3,
.rmb-guide-trouble h3 {
    font-weight: 800;
    margin-bottom: 0.5rem;
}

.rmb-guide-needs ul {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem 1.5rem;
}

.rmb-guide-needs li::before {
    content: "✓";
    color: var(--rmb-success-text);
    font-weight: 800;
    margin-right: 0.4rem;
}

.rmb-guide-step {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 1.25rem;
    padding: 2rem 0;
    break-inside: avoid;
}

.rmb-guide-step + .rmb-guide-step {
    border-top: 1px solid var(--rmb-border);
}

.rmb-guide-step-text .rmb-flow-node {
    margin-bottom: 0.75rem;
}

.rmb-guide-step-text h3 {
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
}

.rmb-guide-step-text p,
.rmb-guide-points {
    line-height: 1.6;
    margin-bottom: 0.6rem;
}

.rmb-guide-points {
    list-style: disc;
    padding-left: 1.25rem;
}

.rmb-guide-points--numbered {
    list-style: decimal;
}

.rmb-guide-points li + li {
    margin-top: 0.25rem;
}

.rmb-guide-step-art {
    display: flex;
    justify-content: center;
    align-items: center;
}

/* Step 1's real stickers, at 60 % of their printed size so all three fit
   side by side on a phone. Only --s changes, so their proportions stay the
   sticker's own. */
.rmb-guide-examples {
    flex-wrap: wrap;
    gap: 1rem;
}

.rmb-guide-examples .rmb-sticker {
    --s: calc(var(--sticker-size) * 0.6);
}

.rmb-guide-trouble {
    padding: 1.25rem;
    margin: 1rem 0 2rem;
}

.rmb-guide-trouble table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 0.75rem;
}

.rmb-guide-trouble th,
.rmb-guide-trouble td {
    text-align: left;
    vertical-align: top;
    padding: 0.5rem 0.75rem 0.5rem 0;
    border-bottom: 1px solid var(--rmb-border);
}

.rmb-guide-trouble th {
    font-family: 'JetBrains Mono', ui-monospace, monospace;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--rmb-text-muted);
}

@media (min-width: 768px) {
    .rmb-guide-step {
        grid-template-columns: minmax(0, 1fr) 300px;
        gap: 3rem;
        align-items: center;
    }
}

/* The guide's illustrations (_guide_art.html). One drawing language: the
   same 240 x 160 canvas, a 2.5 outline and a 1.5 detail line, accent plus
   warm neutrals - all page tokens, so each picture follows dark mode. The
   QR parts stay white and dark in both themes, like a real sticker. */
.rmb-illo {
    width: 100%;
    max-width: 300px;
    height: auto;
    overflow: visible;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.rmb-illo .i-line { fill: none; stroke: var(--rmb-text-muted); stroke-width: 2.5; }
.rmb-illo .i-line--thin { stroke: var(--rmb-border-strong); stroke-width: 1.5; }
.rmb-illo .i-paper { fill: var(--rmb-surface); stroke: var(--rmb-text-muted); stroke-width: 2.5; }
.rmb-illo .i-warm { fill: var(--rmb-border); stroke: var(--rmb-text-muted); stroke-width: 2.5; }
.rmb-illo .i-scene { fill: var(--rmb-surface-sunken); stroke: var(--rmb-border); stroke-width: 1.5; }
.rmb-illo .i-cell { fill: var(--rmb-surface-hover); stroke: var(--rmb-border-strong); stroke-width: 1.5; }
.rmb-illo .i-field { fill: var(--rmb-surface-sunken); stroke: var(--rmb-border-strong); stroke-width: 1.5; }
.rmb-illo .i-glass { fill: rgba(var(--rmb-text-rgb), 0.05); stroke: var(--rmb-text-muted); stroke-width: 2.5; }
.rmb-illo .i-slot { fill: var(--rmb-text-muted); }
.rmb-illo .i-accent { fill: var(--rmb-accent); }
.rmb-illo .i-soft { fill: rgba(var(--rmb-accent-rgb), 0.18); stroke: var(--rmb-accent-text); stroke-width: 1.5; }
.rmb-illo .i-tint { fill: rgba(var(--rmb-accent-rgb), 0.1); stroke: var(--rmb-accent-text); stroke-width: 2.5; }
.rmb-illo .i-picked { fill: rgba(var(--rmb-accent-rgb), 0.12); stroke: var(--rmb-accent-text); stroke-width: 2.5; }
.rmb-illo .i-picked-line { fill: none; stroke: var(--rmb-accent-text); stroke-width: 2.5; }
.rmb-illo .i-qr { fill: rgb(var(--rmb-text-on-fixed-dark-rgb)); }
.rmb-illo .i-qr--edged { stroke: var(--rmb-border-strong); stroke-width: 1.5; }
.rmb-illo .i-qr-ink { fill: var(--rmb-fixed-dark); }
.rmb-illo .i-ok { fill: var(--rmb-success); }
.rmb-illo .i-ok-mark { fill: none; stroke: var(--rmb-text-on-accent); stroke-width: 2.5; }
.rmb-illo .i-cut,
.rmb-illo .i-cutline { fill: none; stroke: var(--rmb-border-strong); stroke-width: 1.5; stroke-dasharray: 4 4; }
.rmb-illo .i-trail { fill: none; stroke: var(--rmb-text-muted); stroke-width: 2.5; stroke-dasharray: 0.1 7; }
.rmb-illo .i-blade { fill: var(--rmb-surface-hover); stroke: var(--rmb-text-muted); stroke-width: 1.5; }
.rmb-illo .i-hole { fill: var(--rmb-surface); }
.rmb-illo .i-hole--edged { stroke: var(--rmb-text-muted); stroke-width: 1.5; }
.rmb-illo .i-ring { fill: none; stroke: var(--rmb-border-strong); stroke-width: 4; }
.rmb-illo .i-ring--small { stroke-width: 2.5; }

.rmb-illo .i-label {
    font-family: 'Manrope', sans-serif;
    font-size: 10px;
    font-weight: 700;
    fill: var(--rmb-text);
}

.rmb-illo .i-label--muted { fill: var(--rmb-text-muted); font-weight: 600; }
.rmb-illo .i-label--on-accent { fill: var(--rmb-text-on-accent); }

/* "Download as PDF": the same page on A4, picture beside each step. The
   page script switches to the light theme while printing. */
@media print {
    .rmb-guide {
        font-size: 10.5pt;
        -webkit-print-color-adjust: exact;
        print-color-adjust: exact;
    }

    .rmb-guide-step {
        grid-template-columns: minmax(0, 1fr) 55mm;
        gap: 8mm;
        align-items: center;
        padding: 4mm 0;
    }

    .rmb-guide-step--last {
        grid-template-columns: minmax(0, 1fr);
    }

    .rmb-illo {
        max-width: 55mm;
    }

    .rmb-guide-trouble {
        box-shadow: none;
        break-inside: avoid;
    }
}

/* Printed page margin. Keep in step with SHEET_MARGIN_MM in
   app/stickers.py, which lays out the A4 sheets for this printable area. */
@page {
    margin: 10mm;
}

/* Batch sheets are made for A4 (browsers without named pages print them on
   the default paper). */
@page rmb-sheet {
    size: A4;
    margin: 10mm;
}

@media print {
    body.rmb-printing > *:not(#printArea) {
        display: none !important;
    }

    body.rmb-printing #printArea {
        position: static;
        width: auto;
        height: auto;
        overflow: visible;
        display: flex;
        justify-content: center;
    }

    /* A page with a .rmb-print-page section prints only that section: the
       batch sheets (one per page) and the shipment packing view. */
    body:has(.rmb-print-page) > :not(.rmb-page-content),
    .rmb-screen-only,
    .rmb-sticker-sheets--blocked {
        display: none !important;
    }

    body:has(.rmb-print-page) .rmb-page-content,
    body:has(.rmb-print-page) .rmb-page-content > * {
        max-width: none;
        margin: 0;
        padding: 0;
    }

    .rmb-ship-codes-panel {
        border: none;
        box-shadow: none;
        padding: 0;
    }

    .rmb-sticker-sheets {
        overflow: visible;
        padding: 0;
    }

    .rmb-sticker-sheet {
        page: rmb-sheet;
        width: auto;
        min-height: 0;
        margin: 0;
        padding: 0;
        border: none;
        box-shadow: none;
        break-after: page;
    }

    .rmb-sticker-sheet:last-child {
        break-after: auto;
    }

    .rmb-print-blocked-note {
        display: block;
    }
}

@media (prefers-reduced-motion: reduce) {
    .rmb-toast-container {
        animation: none;
    }

    html {
        scroll-behavior: auto;
    }
}
