/* Typography (visual polish pass, roadmap items 49-51): Barlow replaces the old bare
   system-font stack for body/UI text everywhere -- Anton stays reserved for the wordmark and
   major (theme-driven, via --rb-heading-font) page headings only, never body text, matching the
   convention already established on the mobile app. IBM Plex Mono is used for small meta text
   (timestamps, category/type labels, post metadata) -- see the rule near the bottom of this file.
   All three load from a single Google Fonts <link> in base.html. This is a sitewide change, so it
   also reaches the anonymous pre-login view -- deliberate: fonts are explicitly outside the theme
   system's protected "pixel-identical colors" concern (see CLAUDE.md's "App shell & typography"
   section for the full reasoning), unlike --rb-bg/--rb-text/etc., which stay untouched for an
   anonymous request. */
:root {
    --rb-body-font: 'Barlow', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --rb-mono-font: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    /* App shell chrome (roadmap items 49/50): a subtle tint of --rb-bg toward --rb-text, not a
       hardcoded color -- the same color-mix()-toward-text-color trick already used below by
       .composer textarea's background etc. Mixing toward --rb-text (rather than a fixed
       black/white) is direction-agnostic: --rb-text is always chosen to contrast against --rb-bg,
       so this always shifts the shell a little *toward* that contrast regardless of whether the
       active theme is light or dark -- the CSS equivalent of the mobile app's
       deriveSurfaceVariant() (RideBuddy/.../ui/theme/Theme.kt), which does the same lerp-toward-
       black-or-white-by-luminance trick in Kotlin, just computed a different way. See CLAUDE.md's
       "App shell & typography" section for the full reasoning. */
    --rb-shell-bg: color-mix(in srgb, var(--rb-bg, #15141a) 90%, var(--rb-text, #edeae3) 10%);
    --rb-shell-border: color-mix(in srgb, var(--rb-text, #edeae3) 14%, transparent);
}

body {
    margin: 0;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    background: var(--rb-bg, #15141a);
    color: var(--rb-text, #edeae3);
    font-family: var(--rb-body-font);
}

main {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
}

h1 {
    font-size: 2.5rem;
    margin-bottom: 0.5rem;
    font-family: var(--rb-heading-font, inherit);
    text-wrap: balance;
}

h2 {
    font-size: 1.2rem;
    font-weight: 700;
    margin: 0 0 0.25rem;
    text-wrap: balance;
}

@media (max-width: 480px) {
    h1 {
        font-size: 2rem;
    }
}

p {
    color: var(--rb-label, #a39fae);
}

.site-nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 1rem 1.5rem;
}

.site-nav a, .site-nav button {
    color: var(--rb-accent, #edeae3);
    background: none;
    border: none;
    font: inherit;
    text-decoration: none;
    cursor: pointer;
}

/* Wordmark stays Anton regardless of the rider's theme font choice -- brand identity, not a
   theme-driven heading (see the typography note above :root). Higher specificity than the plain
   `.site-nav a` rule above (a.site-nav__brand beats a bare class), so this only overrides
   font-family/letter-spacing without touching that rule's color/cursor/etc. */
.site-nav a.site-nav__brand {
    font-family: 'Anton', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    letter-spacing: 0.02em;
}

.error {
    color: var(--rb-accent, #ff6b6b);
}

/* Public page shell (generalized 2026-09-03, originally the "/" -only landing hero) -- now shared
   by every anonymous page (login/register/forgot-password/about/contact/status/beta-download/
   index), not just "/": see base.html's anonymous branch. Deliberately NOT themed via --rb-*
   tokens the way logged-in pages are: this is the brand identity every anonymous visitor sees the
   same way, independent of any rider's stored theme (which an anonymous request never resolves
   anyway -- see base.html's "pixel-identical" note this replaced). Overrides the bare `main`
   rule's center-everything default with its own full-page flex column: header raised at the top,
   content flexing to fill whatever's left (so a short page like "/" still fills the viewport and
   pins the footer to the bottom, while a tall page like Status/beta-download just grows normally).
*/
.public-shell {
    width: 100%;
    min-height: 100vh;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    text-align: center;
    /* Two background layers: a dark gradient painted OVER the photo -- this is what keeps the
       chrome logo/nav/page content legible regardless of how bright/busy the photo is at any given
       crop, and is also what makes the logo's mix-blend-mode below work reliably (a bright patch of
       sky behind the logo would fight the blend; the overlay guarantees there isn't one).
       background-attachment:fixed sizes/positions the photo relative to the *viewport*, not this
       element's own box -- deliberate, since this element's height now varies hugely page to page
       (roughly one viewport on "/", much taller on Status/beta-download); without `fixed`,
       background-size:cover would rescale the photo to cover whatever the tallest page's full
       height is, zooming it in far more than intended on short pages. Content scrolls over a
       pinned backdrop instead, the standard fix for a shared hero-style background across
       differently-sized pages. */
    background:
        linear-gradient(rgba(10, 9, 12, 0.68), rgba(10, 9, 12, 0.78)),
        url("../images/landing-background.70fd68cac40e.jpg") center 35% / cover no-repeat;
    background-attachment: fixed;
}

/* Raised near the top (direct product request -- the original cut vertically centered this in the
   viewport) rather than centered or flexed to fill space. */
.public-shell__header {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    padding: 2rem 1.5rem 1.25rem;
}

.public-shell__logo-link {
    display: inline-flex;
}

/* The source PNG (ShiftNTwist.png) is a flat RGB render on solid black, not a transparent asset --
   mix-blend-mode:screen is what removes that black plate: screen blending treats pure black as
   fully transparent (the darkened photo behind it shows through unchanged) while the logo's bright
   chrome highlights punch through at full brightness. This only reads cleanly because the shell's
   own dark overlay above guarantees a dark backdrop everywhere the logo can land -- don't reuse
   this logo asset with mix-blend-mode over a light background, it needs a dark one under it. Sized
   smaller than the original single-page hero cut (720px) since this now repeats as a persistent
   header on every page, not a one-time splash moment. */
.public-shell__logo {
    width: min(420px, 62vw);
    height: auto;
    mix-blend-mode: screen;
}

.public-shell__nav {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.5rem 2rem;
    width: 100%;
    max-width: 640px;
}

.public-shell__nav a {
    color: #f2efe9;
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    padding: 0.4rem 0.1rem;
    border-bottom: 2px solid transparent;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.public-shell__nav a:hover,
.public-shell__nav a:focus-visible {
    color: #ff5a4d;
    border-bottom-color: #ff5a4d;
}

/* Fills whatever vertical space the header/footer don't use -- what keeps a short page (index)
   filling the viewport while a tall one (Status, beta-download) just grows past it normally. Each
   page's own <main class="..."> (login-page/static-page/etc.) renders inside this and keeps its
   own max-width/padding from the shared page-container rule above. */
.public-shell__content {
    flex: 1;
    width: 100%;
}

.public-shell__footer {
    padding: 1.25rem 1.5rem;
    color: color-mix(in srgb, #f2efe9 65%, transparent);
    font-size: 0.8rem;
}

.public-shell__footer p {
    margin: 0;
    color: inherit;
}

/* Disclaimer sits directly above the copyright line, its own paragraph with a small bottom
   margin to visually separate the two -- slightly more opaque than the copyright text since it's
   the more load-bearing of the two lines, centered and capped in width so it wraps to a readable
   line length instead of stretching edge-to-edge on wide viewports. Qualified as
   `.public-shell__footer p.public-shell__footer-disclaimer` (not just the bare class) so its own
   margin actually beats `.public-shell__footer p` above on specificity, rather than reaching for
   !important. */
.public-shell__footer p.public-shell__footer-disclaimer {
    max-width: 42rem;
    margin: 0 auto 0.6rem;
    color: color-mix(in srgb, #f2efe9 82%, transparent);
}

.public-shell__footer-disclaimer strong {
    color: #f2efe9;
}

.public-shell__footer a {
    color: inherit;
    text-decoration: underline;
    text-decoration-color: color-mix(in srgb, #f2efe9 40%, transparent);
}

.public-shell__footer a:hover,
.public-shell__footer a:focus-visible {
    color: #ff5a4d;
    text-decoration-color: currentColor;
}

/* Index-page-only tagline (added 2026-09-03) -- fills whatever space .public-shell__content has
   available (index has no other content), centered both ways within it. Anton for the headline
   matches the wordmark's own display-face treatment; kept short/punchy on purpose. */
.landing-tagline {
    height: 100%;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    padding: 1.5rem;
    text-align: center;
}

.landing-tagline__headline {
    font-family: 'Anton', -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: clamp(1.5rem, 4vw, 2.75rem);
    letter-spacing: 0.01em;
    color: #f2efe9;
    text-wrap: balance;
    max-width: 42rem;
    margin: 0;
}

.landing-tagline__subtext {
    font-size: 1rem;
    color: color-mix(in srgb, #f2efe9 78%, transparent);
    max-width: 34rem;
    margin: 0;
}

/* Below ~500px, nav items at the normal gap wrap unevenly (e.g. 3 on one line, a lone item on the
   next) -- a plain vertical stack keeps every item evenly centered regardless of the item count,
   rather than a fixed 2-column grid tuned for one specific count (a 2-column grid was tried when
   this nav had exactly 4 items, but its leftover-row cell isn't centered across the row for an odd
   count -- see git history -- so a count-agnostic stack replaced it once a 5th item, "Blog", was
   added 2026-09-04). */
@media (max-width: 500px) {
    .public-shell__nav {
        flex-direction: column;
        gap: 1.1rem;
    }
}

/* Visible, accent-colored focus states sitewide (visual polish pass) -- browsers' default focus
   ring doesn't track a rider's theme and can be hard to see against some custom backgrounds. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
textarea:focus-visible,
select:focus-visible,
[tabindex]:focus-visible {
    outline: 2px solid var(--rb-accent, #edeae3);
    outline-offset: 2px;
}

/* Shared hover state for the "outline button" pattern used across the composer, chat, forum, and
   settings forms (border + accent text on transparent background) -- a light accent-tinted fill on
   hover, matching the reaction/filter-chip/thread-list hover treatments already in this file. */
.composer button[type="submit"]:hover:not(:disabled),
.chat-composer button:hover:not(:disabled),
.report-form__row button[type="submit"]:hover:not(:disabled),
.forum-toolbar button:hover:not(:disabled),
.new-thread-form__row button[type="submit"]:hover:not(:disabled),
.settings-save-row button:hover:not(:disabled),
.load-earlier-btn:hover:not(:disabled),
.delete-btn:hover,
.accept-answer-btn:hover:not(:disabled) {
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
}

/* Timeline: shared layout for the feed page and the preferences page. Both are <main> elements,
   so they must explicitly override the bare `main` rule above (which centers/shrinks its
   content) -- `.timeline-page`/`.timeline-preferences-page` win on specificity since they're
   class selectors on the same element. Messaging's `.messages-page`/`.chat-page` (below) need the
   exact same override for the exact same reason, so they share this rule. */
.timeline-page,
.timeline-preferences-page,
.messages-page,
.chat-page,
.profile-page,
.rider-profile-page,
.forum-page,
.forum-thread-page,
.forum-tags-page,
.friends-page,
.groups-page,
.groups-search-page,
.group-detail-page,
.search-page,
.moderation-page,
.moderation-riders-page,
.moderation-rider-detail-page,
.current-activity-page,
.beta-download-page,
.us-statistics-page,
.static-page,
.login-page {
    width: 100%;
    max-width: 640px;
    margin: 0 auto;
    padding: 0 1.5rem 3rem;
    /* box-sizing:border-box (added alongside the app shell, roadmap items 49-51): without it,
       width:100% + this rule's own horizontal padding add up to more than 100% of the available
       width under the default content-box model, causing real horizontal page overflow at narrow
       viewports -- caught live while verifying the new mobile drawer layout (a pre-existing gap in
       this rule, not something the shell introduced, but now visibly relevant since the shell's
       mobile breakpoint is the first place this file specifically calls out testing at). */
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    text-align: left;
}

.timeline-page {
    gap: 1.5rem;
}

/* Rider activity map (ad-hoc request, 2026-09-01) -- the shared page-container rule above caps
   width at 640px, far too narrow for a 3840x2160 snapshot; overridden wider here, same pattern
   the Forum Q&A redesign already established for its own two-column layout. The image itself
   just needs to scale down to fit -- it's never upscaled past its native 3840px width. */
.current-activity-page {
    max-width: 1600px;
    gap: 1rem;
}

#current-activity-image {
    width: 100%;
    max-width: 3840px;
    height: auto;
    border: 1px solid color-mix(in srgb, var(--rb-text, #1c1b1f) 15%, transparent);
    border-radius: 8px;
}

/* Beta download page (ad-hoc request, 2026-09-02) -- reuses .settings-section/.btn-accent/
   .muted-note wholesale; only the button's own spacing and the numbered install-steps list need
   anything new. */
.beta-download-page__button {
    display: inline-block;
    margin-top: 0.75rem;
}

.beta-download-page__steps {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    padding-left: 1.5rem;
}

.beta-download-page__steps li {
    line-height: 1.5;
}

/* Timeline: composer */
.composer {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

.composer form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.composer textarea {
    width: 100%;
    box-sizing: border-box;
    resize: vertical;
    min-height: 4.5rem;
    padding: 0.6rem;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    color: var(--rb-text, #edeae3);
    font: inherit;
}

.composer__meta {
    display: flex;
    justify-content: flex-end;
}

.composer__char-count {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.composer__row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.75rem;
    align-items: flex-end;
}

.composer__field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.composer__field select,
.composer__field input[type="file"] {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.35rem 0.5rem;
}

.composer button[type="submit"] {
    align-self: flex-end;
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 8px;
    padding: 0.5rem 1.25rem;
    font-weight: 600;
    cursor: pointer;
}

.composer button[type="submit"]:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Timeline: feed */
.feed-section {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.feed-section__link {
    align-self: flex-end;
    font-size: 0.85rem;
}

.feed {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.feed-sentinel {
    height: 1px;
}

.feed-skeleton {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.feed-skeleton__card {
    height: 5.5rem;
    border-radius: 12px;
    background: linear-gradient(
        90deg,
        color-mix(in srgb, var(--rb-text, #edeae3) 6%, transparent) 25%,
        color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent) 37%,
        color-mix(in srgb, var(--rb-text, #edeae3) 6%, transparent) 63%
    );
    background-size: 400% 100%;
    animation: feed-skeleton-shimmer 1.4s ease infinite;
}

@keyframes feed-skeleton-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

.post-card {
    position: relative;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

.post-card__header {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    padding-right: 1.75rem;
    font-size: 0.85rem;
    margin-bottom: 0.5rem;
}

.post-card__author {
    font-weight: 600;
    color: var(--rb-text, #edeae3);
}

.post-card__meta {
    color: var(--rb-label, #a39fae);
}

.post-card__content {
    margin: 0 0 0.75rem;
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
}

.post-card__image {
    display: block;
    max-width: 100%;
    max-height: 420px;
    width: auto;
    height: auto;
    border-radius: 8px;
    margin-bottom: 0.75rem;
    object-fit: contain;
    cursor: pointer;
}

/* Roadmap item 59: tapping/clicking a post's inline image opens it full-size. timeline.js's
   openLightbox() builds this overlay fresh on open and removes it from the DOM entirely on close
   (click on the backdrop/close button, or Escape) -- deliberately not toggled via [hidden] or a
   persistent hidden element, sidestepping the [hidden]-vs-class-`display` specificity gotcha
   documented elsewhere in this file (see the .feed/.feed-skeleton/.post-card__actions-menu
   comments below) by never needing to fight the cascade over it. Same --rb-* / color-mix() token
   approach as the rest of this file -- no hardcoded colors, so this still reflects a logged-in
   rider's own theme (Timeline is @login_required, so this only ever renders for one anyway). */
.lightbox-overlay {
    position: fixed;
    inset: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem;
    box-sizing: border-box;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 82%, black 18%);
}

.lightbox-overlay__image {
    display: block;
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
    border-radius: 8px;
    box-shadow: 0 8px 32px color-mix(in srgb, black 45%, transparent);
    cursor: default;
}

.lightbox-overlay__close {
    position: fixed;
    top: 1.25rem;
    right: 1.5rem;
    width: 2.5rem;
    height: 2.5rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 30%, transparent);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 80%, var(--rb-text, #edeae3) 20%);
    color: var(--rb-text, #edeae3);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

.lightbox-overlay__close:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
}

.post-card__reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.reaction-btn {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 999px;
    background: transparent;
    color: var(--rb-text, #edeae3);
    padding: 0.2rem 0.6rem;
    font-size: 0.95rem;
    cursor: pointer;
}

.reaction-btn--active {
    border-color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 18%, transparent);
}

/* Timeline: per-post Delete/Report action control -- absolutely positioned within .post-card
   (position: relative above) so it sits inset top-right without disturbing the header's existing
   author/meta space-between layout; .post-card__header's padding-right above keeps a long meta
   string (e.g. "3h ago · Group Name") from running underneath it. */
.post-card__actions {
    position: absolute;
    top: 1rem;
    right: 1rem;
}

.post-card__actions-toggle {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 999px;
    background: transparent;
    color: var(--rb-label, #a39fae);
    width: 1.75rem;
    height: 1.75rem;
    line-height: 1;
    font-size: 1rem;
    cursor: pointer;
}

.post-card__actions-menu {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.25rem;
    display: flex;
    flex-direction: column;
    min-width: 7rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 8px;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 96%, var(--rb-text, #edeae3) 4%);
    box-shadow: 0 4px 12px color-mix(in srgb, black 25%, transparent);
    overflow: hidden;
    z-index: 5;
}

.post-card__actions-item {
    border: none;
    background: transparent;
    color: var(--rb-text, #edeae3);
    text-align: left;
    padding: 0.5rem 0.75rem;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.post-card__actions-item:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 10%, transparent);
}

.post-card__actions-reported {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.post-card__actions-menu[hidden] {
    display: none;
}

/* Timeline: report form, opened in place of the "..." control by the Report menu item. */
.report-form {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.25rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    width: 14rem;
    max-width: calc(100vw - 3rem);
    padding: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 8px;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 96%, var(--rb-text, #edeae3) 4%);
    box-shadow: 0 4px 12px color-mix(in srgb, black 25%, transparent);
    z-index: 5;
}

.report-form__field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.report-form__field select,
.report-form__field textarea {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.35rem 0.5rem;
    resize: vertical;
}

.report-form__row {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

.report-form__row button {
    font: inherit;
    font-size: 0.8rem;
    border-radius: 6px;
    padding: 0.35rem 0.6rem;
    cursor: pointer;
}

.report-form__row button[type="submit"] {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    font-weight: 600;
}

.report-form__row button[type="submit"]:disabled {
    opacity: 0.6;
    cursor: default;
}

.report-form__cancel {
    background: transparent;
    color: var(--rb-label, #a39fae);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
}

.report-form__error {
    margin: 0;
    font-size: 0.8rem;
}

/* Timeline comments fast-follow (2026-09-01) -- a comment-count affordance on every post card
   ("N comments" / "Add a comment") that expands a comment thread inline within the same card (see
   CLAUDE.md's Timeline section for why inline, not a separate page). Reuses existing classes
   wherever the shape already matches rather than duplicating: comment reactions are
   .reaction-btn/.reaction-btn--active (identical pill styling to post reactions, via
   timeline.js's shared renderReactionButtons() helper), the own-comment Delete affordance reuses
   .delete-btn.delete-btn--small, "Load more comments" reuses .load-earlier-btn, and the composer's
   submit row reuses .report-form__row (including its button[type="submit"] accent-outline
   style/hover/disabled states) -- only the pieces with no existing equivalent get new rules below. */
.post-card__comments-toggle {
    align-self: flex-start;
    background: transparent;
    border: none;
    padding: 0;
    margin-top: 0.5rem;
    color: var(--rb-label, #a39fae);
    font-size: 0.85rem;
    cursor: pointer;
}

.post-card__comments-toggle:hover {
    color: var(--rb-accent, #edeae3);
}

.post-card__comments {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
}

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

.comment-card {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 10%, transparent);
    border-radius: 8px;
    padding: 0.6rem 0.75rem;
}

.comment-card__header {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.8rem;
    margin-bottom: 0.3rem;
}

.comment-card__author {
    font-weight: 600;
    color: var(--rb-text, #edeae3);
}

.comment-card__meta {
    color: var(--rb-label, #a39fae);
}

.comment-card__content {
    margin: 0 0 0.5rem;
    color: var(--rb-text, #edeae3);
    font-size: 0.9rem;
    white-space: pre-wrap;
    word-break: break-word;
}

.comment-card__footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.comment-card__reactions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.3rem;
}

.comment-composer {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.comment-composer__field {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    resize: vertical;
}

.comment-composer__error {
    margin: 0;
    font-size: 0.8rem;
}

/* timeline.js toggles these elements with the plain `hidden` attribute (feed-skeleton,
   feed, composer-group-field before its first "audience=GROUP" selection). The UA stylesheet's
   own `[hidden] { display: none }` rule has the same specificity as a single class selector, so
   without this, whichever rule happens to come later in the cascade wins -- `.feed-skeleton`/
   `.feed`/`.composer__field`'s own `display: flex` above was silently beating it and leaving
   these visible. `[hidden]` here has higher specificity (class + attribute) than any of those, so
   it always wins regardless of source order. Caught live: the Group field rendered even with
   Audience set to Public, and the skeleton shimmer never disappeared once the feed loaded.
   `.post-card__comments[hidden]` (comments fast-follow, 2026-09-01) needs the identical override
   for the identical reason -- its own `display: flex` above would otherwise beat `[hidden]`. */
.feed-skeleton[hidden],
.feed[hidden],
.composer__field[hidden],
.post-card__comments[hidden] {
    display: none;
}

/* Timeline: mute/filter preferences */
.back-link {
    display: inline-block;
    margin-bottom: 1.5rem;
}

.mute-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.mute-list__item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
}

.mute-list__item button {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    background: transparent;
    color: var(--rb-text, #edeae3);
    border-radius: 6px;
    padding: 0.25rem 0.6rem;
    cursor: pointer;
}

.muted-note {
    font-size: 0.85rem;
    color: var(--rb-label, #a39fae);
}

.filter-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0.75rem 0;
}

.filter-chip {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    background: transparent;
    color: var(--rb-text, #edeae3);
    border-radius: 999px;
    padding: 0.3rem 0.8rem;
    cursor: pointer;
}

.filter-chip--active {
    border-color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 18%, transparent);
}

/* Messaging: thread list + start-new-conversation list (pages/templates/pages/messages.html) --
   same list-item/border/`color-mix()` token approach as .mute-list above. */
.messages-page {
    gap: 1.5rem;
}

.thread-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.thread-list__item a {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
    color: var(--rb-text, #edeae3);
    text-decoration: none;
}

.thread-list__item a:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 6%, transparent);
}

.thread-list__name {
    font-weight: 600;
}

.thread-list__meta {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

/* Messaging: one conversation (pages/templates/pages/chat_thread.html). */
.chat-page {
    gap: 1rem;
}

.chat-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.load-earlier-btn {
    align-self: center;
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 999px;
    padding: 0.35rem 0.9rem;
    font-size: 0.85rem;
    cursor: pointer;
    display: inline-block;
}

.load-earlier-btn:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Sets its own `display` at the same class-selector specificity as [hidden] -- same reasoning
   documented above for .feed/.feed-skeleton/.composer__field/.chat-messages. */
.load-earlier-btn[hidden] {
    display: none;
}

.chat-messages {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* #chat-skeleton reuses .feed-skeleton (see below), whose own [hidden] override already applies;
   .chat-messages needs its own since it sets display: flex at the same class-selector
   specificity as [hidden], same reasoning as .feed/.feed-skeleton documented above. */
.chat-messages[hidden] {
    display: none;
}

.chat-bubble {
    align-self: flex-start;
    max-width: 75%;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 0.5rem 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
}

.chat-bubble--own {
    align-self: flex-end;
    border-color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
}

.chat-bubble__text {
    margin: 0;
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
}

.chat-bubble__text--error {
    font-style: italic;
    color: var(--rb-label, #a39fae);
}

/* Roadmap item 66 -- message reactions. The reaction row itself carries BOTH .chat-bubble__reactions
   AND .post-card__reactions (see messaging.js's renderMessages), and each button carries
   .reaction-btn/.reaction-btn--active directly -- deliberately reusing Timeline's own reaction pill
   treatment verbatim (flex-wrap row, pill borders, the active-state highlight) rather than
   inventing a second visual language for what's visually the same control, just without a count
   badge (a DM reaction is a single slot, not a many-riders-aggregated count). No rules of its own
   here -- .chat-bubble__reactions is a namespaced no-op hook only, matching .chat-bubble__text/
   .chat-bubble__time's own per-feature-class convention, so a future messaging-only tweak has
   somewhere to land without touching Timeline's shared .post-card__reactions styling. */

.chat-bubble__time {
    align-self: flex-end;
    font-size: 0.7rem;
    color: var(--rb-label, #a39fae);
}

.chat-composer {
    display: flex;
    gap: 0.6rem;
    align-items: flex-end;
}

.chat-composer textarea {
    flex: 1;
    box-sizing: border-box;
    resize: vertical;
    min-height: 3rem;
    padding: 0.6rem;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    color: var(--rb-text, #edeae3);
    font: inherit;
}

.chat-composer button {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 8px;
    padding: 0.5rem 1.25rem;
    font-weight: 600;
    cursor: pointer;
}

.chat-composer button:disabled {
    opacity: 0.6;
    cursor: default;
}

/* forum_thread.html reuses .chat-composer for its reply form and toggles it with the plain
   `hidden` attribute while the thread is still loading (chat_thread.html's own #chat-composer is
   never hidden, so this override wasn't needed until now) -- same class-selector-vs-[hidden]
   specificity fix as .feed/.feed-skeleton/.composer__field/.load-earlier-btn/.chat-messages above. */
.chat-composer[hidden] {
    display: none;
}

/* Profile stats (roadmap items 16/19): lifetime mileage + states-visited badges. Read-only, so no
   form/composer rules needed here -- just the skeleton (reuses .feed-skeleton), an error message
   (reuses .error), and a small stat-card grid. */
.profile-page {
    gap: 1.5rem;
}

.stat-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
    gap: 1rem;
}

.stat-grid[hidden] {
    display: none;
}

.stat-card {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

.stat-card__label {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.stat-card__value {
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--rb-text, #edeae3);
}

.stat-card__badge {
    margin: 0;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--rb-accent, #edeae3);
}

/* Accident stat on the (public, non-theme-reflecting) activity page -- a literal, fixed red, not
   var(--rb-accent): unlike .error's theme-tied red-ish fallback, this value must always read as
   red regardless of any future reuse on a themed page, since red here has a specific "something
   alarming happened" meaning (see CLAUDE.md's "Rider activity map" section) that a rider's own
   accent color could otherwise wash out or contradict. */
.stat-card__value--danger {
    color: #c62828;
}

.state-badges,
.mileage-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    margin-top: 0.25rem;
}

/* .mileage-badge (roadmap item 17) mirrors .state-badge exactly -- same pill treatment, grouped
   together rather than duplicated so the two badge kinds can never visually drift apart. */
.state-badge,
.mileage-badge {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.15rem 0.45rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--rb-text, #edeae3);
}

/* Forum (roadmap item 48, redesigned 2026-09-01 into a StackExchange-style Q&A -- see CLAUDE.md's
   Forum "Website frontend" subsection): sort tabs, category+tag filter row, new-thread composer,
   two-column thread list + sidebar, vote widgets, tags, accepted-answer highlighting, and the
   thread detail + flat replies. Same --rb-* / color-mix() token approach as Timeline/Messaging
   above -- no hardcoded colors (deliberately not the reference layout's blue scheme), so a
   rider's reflected theme (see "Rider website login & theme reflection" in CLAUDE.md) still
   applies here. */
/* Wider than the shared 640px page rule above -- a two-column thread-list + sidebar layout needs
   real room; this selector's own max-width here wins over the shared rule's on source order (same
   0,1,0 specificity), without needing to repeat every other property that rule already set. */
.forum-page {
    gap: 1.25rem;
    max-width: 1100px;
}

.forum-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    border-bottom: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    padding-bottom: 0.5rem;
}

.forum-tab {
    background: transparent;
    border: none;
    border-radius: 999px;
    padding: 0.4rem 0.9rem;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--rb-label, #a39fae);
    cursor: pointer;
}

.forum-tab:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 8%, transparent);
}

.forum-tab--active {
    color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 16%, transparent);
}

.forum-toolbar {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 0.75rem;
}

/* Active tag facet chip -- shown alongside the pre-existing category <select> in the same filter
   row (folding the new tag facet into the existing toolbar, per the redesign spec, rather than a
   second separate filter bar). */
.forum-active-tag {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--rb-text, #edeae3);
    border: 1px solid color-mix(in srgb, var(--rb-accent, #edeae3) 40%, transparent);
    border-radius: 999px;
    padding: 0.25rem 0.5rem 0.25rem 0.75rem;
}

.forum-active-tag[hidden] {
    display: none;
}

.forum-active-tag button {
    background: transparent;
    border: none;
    color: var(--rb-label, #a39fae);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
    padding: 0 0.15rem;
}

.forum-active-tag button:hover {
    color: var(--rb-accent, #edeae3);
}

.forum-toolbar__field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.forum-toolbar__field select {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.35rem 0.5rem;
}

.forum-toolbar button,
.new-thread-form__row button[type="submit"] {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 8px;
    padding: 0.5rem 1.1rem;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.new-thread-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

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

.new-thread-form__field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.new-thread-form__field input,
.new-thread-form__field select,
.new-thread-form__field textarea {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    resize: vertical;
}

.new-thread-form__row {
    display: flex;
    justify-content: flex-end;
    gap: 0.5rem;
}

.new-thread-form__row button[type="button"] {
    background: transparent;
    color: var(--rb-label, #a39fae);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 8px;
    padding: 0.5rem 1.1rem;
    font: inherit;
    cursor: pointer;
}

/* Two-column layout: main thread-list column + right sidebar (Top Users of the Week, Hot
   Questions). Stacks to one column under 960px -- see the media query near .forum-sidebar below.
   No ad-slot column here -- the reference layout's "Google Adsense 300x250" box is deliberately
   omitted (per the redesign spec), not stubbed out as dead space either. */
.forum-layout {
    display: grid;
    grid-template-columns: 1fr 280px;
    gap: 1.5rem;
    align-items: start;
}

.forum-main {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    min-width: 0;
}

.forum-sidebar {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
}

.forum-sidebar__widget {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

.forum-sidebar__widget h2 {
    font-size: 0.95rem;
    margin: 0 0 0.6rem;
}

@media (max-width: 960px) {
    .forum-layout {
        grid-template-columns: 1fr;
    }
}

/* Top Users of the Week -- GET /api/forum/leaderboard/?window=week, capped at 10 by the backend.
   Medal styling on the top 3 ranks, a plain numeric rank badge below that. */
.leaderboard-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.leaderboard-list__item {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.leaderboard-list__rank {
    flex: none;
    width: 1.5rem;
    text-align: center;
    font-family: var(--rb-mono-font);
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.leaderboard-list__item--medal-1 .leaderboard-list__rank,
.leaderboard-list__item--medal-2 .leaderboard-list__rank,
.leaderboard-list__item--medal-3 .leaderboard-list__rank {
    font-size: 1rem;
}

.leaderboard-list__name {
    flex: 1;
    color: var(--rb-text, #edeae3);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.leaderboard-list__points {
    flex: none;
    font-family: var(--rb-mono-font);
    font-size: 0.75rem;
    color: var(--rb-accent, #edeae3);
}

/* Hot Questions -- the top 5 threads from the backend's own ?sort=popular_week ranking (see
   forum.js's loadHotQuestions), a page-level widget fetched once, independent of whichever sort
   tab/filter is active in the main column. */
.hot-questions-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.hot-questions-list__item {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.5rem;
    font-size: 0.85rem;
}

.hot-questions-list__item a {
    color: var(--rb-text, #edeae3);
    text-decoration: none;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hot-questions-list__item a:hover {
    color: var(--rb-accent, #edeae3);
    text-decoration: underline;
}

.hot-questions-list__count {
    flex: none;
    font-family: var(--rb-mono-font);
    font-size: 0.75rem;
    color: var(--rb-label, #a39fae);
}

.forum-thread-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.forum-thread-list[hidden] {
    display: none;
}

/* Each card is a vote column (thread-level voting only here -- reply voting only appears on the
   detail page) beside a body column, rather than the whole card being one <a> -- the title is the
   only real navigation target now, so tag pills/author link/vote buttons inside the same card
   never have to fight a wrapping anchor for clicks (no nested-interactive-element workaround
   needed, unlike this card's pre-redesign author-link, which did need one). */
.forum-thread-card {
    display: flex;
    gap: 0.9rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
}

.forum-thread-card--solved {
    border-color: color-mix(in srgb, var(--rb-accent, #edeae3) 45%, transparent);
}

.forum-thread-card__body {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    min-width: 0;
}

.forum-thread-card__byline {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.8rem;
}

.forum-thread-card__link {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.5rem;
    color: var(--rb-text, #edeae3);
    text-decoration: none;
}

.forum-thread-card__link:hover .forum-thread-card__title {
    color: var(--rb-accent, #edeae3);
}

.forum-thread-card__title {
    font-weight: 600;
}

.forum-thread-card__solved-badge {
    font-size: 0.7rem;
    font-weight: 700;
    color: var(--rb-accent, #edeae3);
}

.forum-thread-card__stats {
    display: flex;
    flex-wrap: wrap;
    gap: 0.9rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.forum-thread-card__timestamp,
.forum-thread-card__byline {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.forum-category-badge {
    align-self: flex-start;
    border: 1px solid color-mix(in srgb, var(--rb-accent, #edeae3) 40%, transparent);
    color: var(--rb-accent, #edeae3);
    border-radius: 999px;
    padding: 0.1rem 0.55rem;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.03em;
    text-transform: uppercase;
}

/* Author-initial placeholder -- this codebase has no avatar-image field anywhere (mobile or
   website), so a plain accent-tinted initial stands in for the reference layout's avatar, same
   "no icon assets" convention as Timeline's emoji reaction glyphs. */
.avatar-placeholder {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 22%, transparent);
    color: var(--rb-accent, #edeae3);
    font-weight: 700;
    font-size: 0.75rem;
}

/* Tags -- shared between the thread-list card, the thread-detail page, and forum_tags.html's
   browse list (which additionally shows a thread_count via .tag-browse-list__count below). */
.tag-pill-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.tag-pill-list[hidden] {
    display: none;
}

.tag-pill {
    display: inline-block;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.1rem 0.5rem;
    font-family: var(--rb-mono-font);
    font-size: 0.7rem;
    color: var(--rb-text, #edeae3);
    text-decoration: none;
}

.tag-pill:hover {
    border-color: var(--rb-accent, #edeae3);
    color: var(--rb-accent, #edeae3);
}

/* Shared vote widget -- thread-list cards (thread-level only), the thread-detail question, and
   every reply all render through the same forum.js renderVoteWidget()/handleVoteClick() pair (see
   that file), so the up/down-arrow markup only needs styling once here too. --sm is the compact
   variant used inside list cards and reply cards; the bare .vote-widget size is used for the
   thread-detail question, which gets a little more visual weight. */
.vote-widget {
    flex: none;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.15rem;
}

.vote-btn {
    background: transparent;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    width: 1.75rem;
    height: 1.75rem;
    line-height: 1;
    font-size: 0.85rem;
    color: var(--rb-label, #a39fae);
    cursor: pointer;
}

.vote-btn:hover {
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
    color: var(--rb-accent, #edeae3);
}

.vote-btn--active {
    border-color: var(--rb-accent, #edeae3);
    color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 18%, transparent);
}

.vote-count {
    font-family: var(--rb-mono-font);
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--rb-text, #edeae3);
}

.vote-widget--sm .vote-btn {
    width: 1.4rem;
    height: 1.4rem;
    font-size: 0.7rem;
}

.vote-widget--sm .vote-count {
    font-size: 0.75rem;
}

/* Forum thread detail page */
.forum-thread-page {
    gap: 1.25rem;
}

.thread-detail {
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1.25rem;
}

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

.thread-detail__layout {
    display: flex;
    gap: 1rem;
}

.thread-detail__body-col {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 0;
}

.thread-detail__meta {
    margin: 0;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.thread-detail__body {
    margin: 0;
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
}

.reply-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.reply-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
}

/* Accepted-answer highlight -- a visibly distinct border/background tint (accent-derived, no
   hardcoded color) plus the badge below, so the accepted reply reads as such even scrolled past
   its own badge. */
.reply-card--accepted {
    border-color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 8%, transparent);
}

.accepted-answer-badge {
    align-self: flex-start;
    font-size: 0.7rem;
    font-weight: 700;
    letter-spacing: 0.02em;
    color: var(--rb-accent, #edeae3);
}

.reply-card__layout {
    display: flex;
    gap: 0.75rem;
}

.reply-card__body-col {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 0;
}

.reply-card__meta {
    margin: 0;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.reply-card__body {
    margin: 0;
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
}

.reply-card__actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.2rem;
}

/* "Accept this answer" -- author-only, shown per not-yet-accepted reply (forum.js's
   isThreadAuthor()/isAccepted checks). Deliberately a plain outline button matching .delete-btn's
   weight, not a filled/primary treatment -- it sits right next to Delete on the rider's own reply
   and shouldn't visually outrank it. */
.accept-answer-btn {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 6px;
    padding: 0.35rem 0.75rem;
    font: inherit;
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

/* forum_tags.html -- the "Tags" nav destination's own page (see base.html's
   .app-header__forum-nav-link). */
.forum-tags-page {
    gap: 1rem;
}

.tag-browse-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.tag-browse-list[hidden] {
    display: none;
}

.tag-browse-list__item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 8px;
    padding: 0.6rem 0.9rem;
}

.tag-pill--browse {
    font-size: 0.85rem;
    padding: 0.2rem 0.7rem;
}

.tag-browse-list__count {
    font-family: var(--rb-mono-font);
    font-size: 0.75rem;
    color: var(--rb-label, #a39fae);
}

.delete-btn {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.35rem 0.75rem;
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
}

.delete-btn--small {
    margin-top: 0.4rem;
    padding: 0.2rem 0.55rem;
    font-size: 0.75rem;
}

.delete-btn[hidden] {
    display: none;
}

/* Profile page editable sections (Personal Information / Message Templates / Theme / Emergency
   Contacts, added 2026-08-31) -- same --rb-* / color-mix() token approach as every other page in
   this file, and the same .new-thread-form__field-style label+input pattern Forum already
   established, generalized into a reusable .settings-field so this page doesn't invent a fourth
   near-identical input style. */
.settings-form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}

/* Same class-selector-vs-[hidden]-specificity fix already documented several times in this file
   (.feed/.feed-skeleton/.composer__field/.load-earlier-btn/.chat-messages/.new-thread-form/
   .chat-composer/.delete-btn) -- .settings-form's own `display: flex` above would otherwise beat
   the UA stylesheet's `[hidden] { display: none }` at equal specificity, since this rule is
   declared later in the cascade. */
.settings-form[hidden] {
    display: none;
}

.settings-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

.settings-section h2 {
    margin: 0;
    font-size: 1.1rem;
}

.settings-field {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.settings-field input[type="text"],
.settings-field input[type="number"],
.settings-field select,
.settings-field textarea {
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    resize: vertical;
}

.settings-field--checkbox {
    flex-direction: row;
    align-items: center;
    gap: 0.5rem;
    color: var(--rb-text, #edeae3);
    font-size: 0.9rem;
}

.settings-field--checkbox input[type="checkbox"] {
    width: 1rem;
    height: 1rem;
}

.settings-field--color input[type="color"] {
    width: 3.5rem;
    height: 2rem;
    padding: 0.1rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    background: transparent;
    cursor: pointer;
}

.settings-field-row {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
}

.settings-field-row > .settings-field {
    flex: 1 1 10rem;
}

/* Same [hidden]-specificity fix as .settings-form above -- #custom-theme-fields/#custom-theme-colors
   are toggled with the plain hidden attribute in profile.js's updateCustomThemeVisibility(). */
.settings-field-row[hidden] {
    display: none;
}

.settings-save-row {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}

.settings-save-row button {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 8px;
    padding: 0.5rem 1.1rem;
    font: inherit;
    font-weight: 600;
    cursor: pointer;
}

.settings-save-row button:disabled {
    opacity: 0.6;
    cursor: default;
}

.settings-save-status {
    font-size: 0.85rem;
    color: var(--rb-text, #edeae3);
}

.settings-save-status--error {
    color: var(--rb-accent, #edeae3);
    font-weight: 600;
}

.contact-list {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.contact-list[hidden] {
    display: none;
}

.contact-row {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 10px;
    padding: 0.75rem;
}

.contact-row .settings-field {
    flex: 1 1 9rem;
}

.contact-row .settings-field--checkbox {
    flex: 0 0 auto;
}

/* Small meta text -- timestamps, category/type labels, post metadata -- gets IBM Plex Mono
   (visual polish pass, roadmap items 49-51): a technical, telemetry-adjacent feel fitting a
   motorcycle app, and a clear typographic distinction from body copy. --rb-mono-font is defined
   near the top of this file alongside --rb-body-font. */
.post-card__meta,
.thread-list__meta,
.forum-thread-card__byline,
.forum-thread-card__timestamp,
.forum-thread-card__stats,
.thread-detail__meta,
.reply-card__meta,
.state-badge,
.mileage-badge,
.forum-category-badge,
.composer__char-count,
.chat-bubble__time,
.stat-card__label {
    font-family: var(--rb-mono-font);
}

/* ==========================================================================
   App shell: persistent header + sidebar (roadmap items 49/50)
   ==========================================================================
   Fixed ~64px header (wordmark + account/logout) and fixed ~240px left sidebar (Timeline/
   Messages/Forum/Profile/Marketplace/Help), both position:fixed so they stay in place while the
   page scrolls under/beside them -- the normal document scroll is the only scroll container
   (no nested overflow div), matching this repo's preference for the simplest mechanism that
   works. .app-content offsets around both via margin. Collapses to a hamburger-triggered drawer
   under the mobile breakpoint (see the media query below) -- a bottom tab bar was considered and
   rejected: 6 items (including two disabled ones) reads cramped as icon-only tabs, and a drawer
   reuses the exact same nav markup/active-state CSS as desktop with no duplication. */
.app-shell {
    min-height: 100vh;
}

.app-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    height: 64px;
    z-index: 40;
    display: flex;
    align-items: center;
    gap: 1rem;
    padding: 0 1.25rem;
    background: var(--rb-shell-bg);
    border-bottom: 1px solid var(--rb-shell-border);
    box-sizing: border-box;
}

.app-header__menu-toggle {
    display: none;
    align-items: center;
    justify-content: center;
    width: 2.25rem;
    height: 2.25rem;
    padding: 0;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--rb-text, #edeae3);
    cursor: pointer;
}

.app-header__menu-toggle:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 10%, transparent);
}

.app-header__menu-toggle svg {
    width: 1.5rem;
    height: 1.5rem;
}

.app-header__brand {
    display: inline-flex;
    align-items: center;
}

/* Sized to fit comfortably inside the 64px .app-header bar (see above) with room above/below. */
.app-header__brand-logo {
    display: block;
    height: 38px;
    width: auto;
}

/* Forum Q&A redesign (2026-09-01) -- "Tags"/"Users" nav links + a quick-filter search box,
   integrated into the existing persistent app-header (rendered only on the three Forum pages, via
   base.html's request.resolver_match.url_name check) rather than a second, separate header. Sits
   between the brand and the account area, so it reads as an extension of the same header row. */
.app-header__forum-nav {
    display: flex;
    align-items: center;
    gap: 1rem;
    margin-left: 1.5rem;
    font-size: 0.9rem;
}

.app-header__forum-nav-link {
    color: var(--rb-label, #a39fae);
    text-decoration: none;
    white-space: nowrap;
}

.app-header__forum-nav-link:hover {
    color: var(--rb-text, #edeae3);
}

.app-header__forum-nav-link--active {
    color: var(--rb-accent, #edeae3);
    font-weight: 600;
}

.app-header__forum-search {
    font: inherit;
    font-size: 0.85rem;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 999px;
    padding: 0.3rem 0.75rem;
    width: 14rem;
    max-width: 40vw;
}

@media (max-width: 768px) {
    /* The header's Tags/Users/search row doesn't fit alongside the hamburger toggle + brand on a
       narrow viewport -- dropped rather than squeezed illegibly; Tags/Users are still reachable
       from the sidebar drawer's own Forum link, and the search box's job (filtering the loaded
       thread list) has no other affordance on mobile, a deliberate small scope cut for this pass. */
    .app-header__forum-nav {
        display: none;
    }
}

.app-header__account {
    display: flex;
    align-items: center;
    gap: 0.85rem;
    margin-left: auto;
    font-size: 0.9rem;
}

/* The account name is a real link to /profile/ now (Profile was removed from the sidebar's
   account section and reached from here instead -- see CLAUDE.md's "App shell & typography"
   section). Plain text color + no underline so it doesn't look like a generic hyperlink sitting in
   the header chrome, with the same accent-tinted hover fill used for the "outline button" pattern
   elsewhere in this file (composer/chat/forum/settings-save buttons, see the shared hover rule near
   the top of this file) so it still reads as clickable. */
.site-nav__user {
    color: var(--rb-text, #edeae3);
    text-decoration: none;
    border-radius: 6px;
    padding: 0.3rem 0.5rem;
    margin: -0.3rem -0.5rem;
}

.site-nav__user:hover {
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
}

.app-shell-scrim {
    position: fixed;
    inset: 0;
    top: 64px;
    background: color-mix(in srgb, black 55%, transparent);
    z-index: 35;
}

.app-shell-scrim[hidden] {
    display: none;
}

.app-sidebar {
    position: fixed;
    top: 64px;
    bottom: 0;
    left: 0;
    width: 240px;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 1rem 0.75rem;
    background: var(--rb-shell-bg);
    border-right: 1px solid var(--rb-shell-border);
    overflow-y: auto;
    z-index: 38;
    box-sizing: border-box;
}

.app-sidebar__link {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.6rem 0.75rem;
    border-radius: 8px;
    color: var(--rb-text, #edeae3);
    text-decoration: none;
    font-size: 0.95rem;
}

.app-sidebar__link:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 8%, transparent);
}

.app-sidebar__icon {
    flex: none;
    width: 1.25rem;
    height: 1.25rem;
}

/* Active nav item (matched per-page in base.html via request.resolver_match.url_name) uses the
   rider's accent color -- both the text/icon color and a left-edge indicator bar. */
.app-sidebar__link--active {
    color: var(--rb-accent, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
    font-weight: 600;
}

.app-sidebar__link--active::before {
    content: "";
    position: absolute;
    left: -0.75rem;
    top: 0.35rem;
    bottom: 0.35rem;
    width: 3px;
    border-radius: 999px;
    background: var(--rb-accent, #edeae3);
}

/* Marketplace/Help -- no real page yet, shown disabled/"Coming Soon" rather than a dead link. */
.app-sidebar__link--disabled {
    color: var(--rb-label, #a39fae);
    cursor: default;
    opacity: 0.65;
}

/* Section break between the sidebar's three groups (primary / Forum+placeholders / account,
   added 2026-08-31) -- same visual weight as the divider that already sat above Log Out before
   this pass (see .app-sidebar__account-section below), now reused as a plain in-flow divider
   between Section 1 and Section 2 too. */
.app-sidebar__section-divider {
    border-top: 1px solid var(--rb-shell-border);
    margin: 0.5rem 0.75rem;
}

/* Section 3 (account: Profile + Log Out) -- pinned to the bottom of the sidebar via flex
   margin-top: auto on this wrapping div (not markup order), so it stays last even as more nav
   items are added to Section 1/2 above it. Carries the divider that used to sit directly on
   .app-sidebar__logout (Log Out was the only account-section item before this pass; Profile moved
   in here alongside it, out of the primary list, per the nav restructure). */
.app-sidebar__account-section {
    margin-top: auto;
    padding-top: 0.5rem;
    border-top: 1px solid var(--rb-shell-border);
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
}

.app-sidebar__logout {
    display: contents;
}

.app-sidebar__link--button {
    width: 100%;
    background: none;
    border: none;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.app-sidebar__badge {
    margin-left: auto;
    font-family: var(--rb-mono-font);
    font-size: 0.65rem;
    font-weight: 600;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    padding: 0.15rem 0.4rem;
    border-radius: 999px;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 25%, transparent);
    color: var(--rb-label, #a39fae);
}

.app-content {
    margin-left: 240px;
    padding-top: 64px;
    min-height: 100vh;
    box-sizing: border-box;
}

@media (max-width: 768px) {
    .app-header__menu-toggle {
        display: inline-flex;
    }

    .app-sidebar {
        width: min(80vw, 280px);
        transform: translateX(-100%);
        transition: transform 0.2s ease;
        box-shadow: 4px 0 16px color-mix(in srgb, black 35%, transparent);
    }

    .app-sidebar.is-open {
        transform: translateX(0);
    }

    .app-content {
        margin-left: 0;
    }
}

/* ==========================================================================
   Timeline compose FAB (roadmap item 51)
   ==========================================================================
   The composer used to sit at the top of the Timeline page and scroll with the feed. It now
   opens from a fixed circular button, bottom-right, using the rider's accent color -- genuinely
   fixed-position (no ancestor sets transform/filter, which would otherwise re-scope `position:
   fixed`), so it never moves during a feed scroll. The composer itself lives inside a native
   <dialog> (open/close mechanics in static/js/shell.js) rather than a hand-rolled modal --
   zero-dependency, and <dialog> gives real focus-trapping/Escape-to-close/top-layer stacking for
   free. */
.compose-fab {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    border: none;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--rb-accent, #d32f2f);
    color: #fff;
    box-shadow: 0 6px 18px color-mix(in srgb, black 35%, transparent);
    cursor: pointer;
    z-index: 25;
}

.compose-fab svg {
    width: 1.5rem;
    height: 1.5rem;
}

.compose-fab:hover {
    filter: brightness(1.08);
}

.compose-dialog {
    border: none;
    padding: 0;
    background: transparent;
    max-width: min(92vw, 34rem);
    width: 100%;
    margin: auto;
}

.compose-dialog::backdrop {
    background: color-mix(in srgb, black 55%, transparent);
}

.compose-dialog[open] {
    display: block;
}

.compose-dialog .composer {
    max-height: 85vh;
    overflow-y: auto;
    box-sizing: border-box;
    background: var(--rb-bg, #15141a);
    box-shadow: 0 12px 32px color-mix(in srgb, black 40%, transparent);
}

.compose-dialog__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 0.5rem;
}

.compose-dialog__header h2 {
    margin: 0;
}

.compose-dialog__close {
    flex: none;
    border: none;
    background: transparent;
    color: var(--rb-label, #a39fae);
    width: 1.75rem;
    height: 1.75rem;
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 6px;
    cursor: pointer;
}

.compose-dialog__close:hover {
    background: color-mix(in srgb, var(--rb-text, #edeae3) 10%, transparent);
}

.compose-dialog__close svg {
    width: 1.1rem;
    height: 1.1rem;
}

/* Timeline needs extra bottom clearance so the FAB never sits on top of the last feed card. */
.timeline-page {
    padding-bottom: 6rem;
}

/* ==========================================================================
   Friends / Groups / Search (added 2026-08-31) -- three new pages built against the
   already-shipped Friends & Groups backend, plus roadmap item 54's new ranked-search endpoint.
   Same --rb-* / color-mix() token approach as every other page in this file -- no hardcoded colors,
   so a logged-in rider's reflected theme still applies here. New page container classes
   (.friends-page/.groups-page/.groups-search-page/.group-detail-page/.search-page) are already
   listed in the shared bare-`main`-override selector above.
   ========================================================================== */
.friends-page,
.groups-page,
.groups-search-page,
.group-detail-page,
.search-page,
.rider-profile-page,
.moderation-page,
.moderation-riders-page,
.moderation-rider-detail-page {
    gap: 1.5rem;
}

/* Rider profile page (roadmap item 52) -- action area below the read-only stats (.stat-grid,
   reused verbatim from .profile-page above): one of "Send Friend Request" / "Request Pending" /
   a "Send Message" link / informational text, never more than one at a time. */
.rider-profile-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.rider-profile-actions[hidden] {
    display: none;
}

/* Author-name links added to Timeline/Forum/Friends (roadmap item 52) -- a tap/click target that
   still reads as plain text inline in its existing card, not as a conspicuous "this is a link"
   blue underline; :hover is the only affordance, matching this file's existing restrained link
   styling elsewhere (e.g. .forum-thread-card__link). All four/five sites below share this rule so
   a future author-render site added to this file gets the identical treatment for free. */
.post-card__author-link,
.forum-thread-card__author-link,
.thread-detail__author-link,
.reply-card__author-link,
.rider-list__name-link {
    color: inherit;
    text-decoration: none;
}

.post-card__author-link:hover,
.forum-thread-card__author-link:hover,
.thread-detail__author-link:hover,
.reply-card__author-link:hover,
.rider-list__name-link:hover {
    text-decoration: underline;
}

/* Generic row list -- friends, friend requests, group members, join requests, group invites,
   search results. Deliberately not reusing .thread-list, since every row here needs an actions
   area (buttons), not just a single full-row <a> link like Messaging's conversation list. */
.rider-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.rider-list__item {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 8px;
    padding: 0.6rem 0.85rem;
}

.rider-list__info {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    min-width: 0;
}

.rider-list__name {
    font-weight: 600;
    color: var(--rb-text, #edeae3);
    display: flex;
    align-items: center;
    gap: 0.4rem;
    flex-wrap: wrap;
}

.rider-list__meta {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
}

.rider-list__actions {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    align-items: center;
}

/* Primary/positive action (Accept, Approve, Request to Join, Send Friend Request, Create Group,
   Send Invite) -- identical accent-solid-border style to .forum-toolbar button/
   .new-thread-form__row button[type="submit"], reused here rather than re-declared a fourth time. */
.btn-accent {
    background: transparent;
    color: var(--rb-accent, #edeae3);
    border: 1px solid var(--rb-accent, #edeae3);
    border-radius: 8px;
    padding: 0.4rem 0.9rem;
    font: inherit;
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
}

.btn-accent:disabled {
    opacity: 0.6;
    cursor: default;
}

/* Secondary/destructive action (Unfriend, Decline, Cancel, Reject, Leave Group, Remove Member) --
   reuses .delete-btn's exact muted-border style rather than a near-duplicate. */
.rider-list__actions .delete-btn {
    margin-top: 0;
}

/* Per-friend home-location-sharing toggle (roadmap item 67 follow-up, added 2026-09-01) --
   .settings-field--checkbox already supplies the checkbox+label look (see the Profile/Timeline
   Preferences pages); this just forces the toggle onto its own line within the flex-wrap
   .rider-list__item row rather than competing for space with the name/actions on the first line. */
.rider-list__share-toggle {
    flex-basis: 100%;
    margin-top: 0.25rem;
}

/* Terminal, non-interactive state text (e.g. Search's "Requested" after a successful send, or a
   400's returned detail message) -- same treatment as Timeline's post-report "Reported" swap. */
.rider-list__state {
    font-size: 0.85rem;
    color: var(--rb-label, #a39fae);
}

.rider-list__state--error {
    color: var(--rb-accent, #ff6b6b);
}

/* Reused across Friends/Groups/Search for the section-title + optional link/count row above a
   .rider-list. */
.section-heading {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.section-heading h2 {
    margin: 0;
}

/* Explicit-submit search form (Search page + Groups search page) -- matches this codebase's
   established explicit-submit precedent (Group search already worked this way; no debounce
   anywhere in this repo) rather than introducing a first debounced-input pattern for this feature
   alone. */
.search-form {
    display: flex;
    gap: 0.5rem;
}

.search-form input[type="search"] {
    flex: 1;
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
}

/* Groups: "my groups" card grid + Create Group inline form (reuses .new-thread-form's exact
   field/row styling via the shared selectors below rather than a duplicate rule set). */
.group-card-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.group-card {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    border-radius: 10px;
    padding: 0.75rem 0.9rem;
}

.group-card__info {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    min-width: 0;
}

.group-card__name {
    font-weight: 600;
    color: var(--rb-text, #edeae3);
    text-decoration: none;
}

.group-card__name:hover {
    text-decoration: underline;
}

.group-card__meta {
    font-size: 0.8rem;
    color: var(--rb-label, #a39fae);
    display: flex;
    gap: 0.4rem;
    align-items: center;
    flex-wrap: wrap;
}

/* Group detail: description block + member/join-request/invite sections. */
.group-detail__description {
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
}

.group-detail__section {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

/* Invite-a-rider form (admin-only) -- single email input + submit, same input styling as
   .new-thread-form__field's inputs and .search-form's search input above. */
.invite-form {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
}

.invite-form input[type="email"] {
    flex: 1;
    min-width: 12rem;
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
}

/* [hidden]-vs-class-selector specificity fix, same recurring reason documented several times
   above for .feed/.feed-skeleton/.composer__field/.load-earlier-btn/.chat-messages/
   .new-thread-form/.chat-composer/.delete-btn/.settings-form. */
.rider-list[hidden],
.group-card-list[hidden],
.new-group-form[hidden] {
    display: none;
}

.new-group-form {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 12px;
    padding: 1rem;
}

/* ==========================================================================
   Content moderation dashboard (added 2026-08-31)
   ==========================================================================
   Every token/technique below reuses the same --rb-* / color-mix() approach as the rest of this
   file -- no hardcoded palette, same as every other page, even though this dashboard is only ever
   seen by staff. Layout reuses .settings-section (bordered card), .new-thread-form__field (label +
   input), .rider-list, .section-heading, .btn-accent, .search-form, and .muted-note/.error rather
   than inventing near-duplicates -- only the pieces genuinely new to this feature (report queue
   cards, status badges, the messages-framework list) get their own rules here. */
.moderation-section {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.moderation-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

.moderation-card {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 15%, transparent);
    border-radius: 10px;
    padding: 0.85rem 1rem;
}

.moderation-card__body {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
}

.moderation-card__meta {
    font-size: 0.8rem;
    font-family: var(--rb-mono-font);
    color: var(--rb-label, #a39fae);
    margin: 0;
}

.moderation-card__title {
    font-weight: 600;
    color: var(--rb-text, #edeae3);
    margin: 0;
}

.moderation-card__content {
    color: var(--rb-text, #edeae3);
    white-space: pre-wrap;
    word-break: break-word;
    margin: 0;
}

/* Each reported item's inline Hide form -- a required textarea + submit, deliberately compact
   (this is a repeated-per-row control, not a standalone page section like Suspend/Ban below). */
.moderation-hide-form {
    display: flex;
    gap: 0.5rem;
    align-items: flex-start;
    flex-wrap: wrap;
}

.moderation-hide-form textarea {
    flex: 1;
    min-width: 12rem;
    font: inherit;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    border-radius: 6px;
    padding: 0.4rem 0.6rem;
    resize: vertical;
}

/* Suspend + Ban forms side by side on the rider-detail page -- both reuse .new-thread-form's
   existing field styling wholesale (see the shared selectors above), this just lays the two forms
   out next to each other rather than stacked. */
.moderation-action-forms {
    display: flex;
    gap: 1.5rem;
    flex-wrap: wrap;
    align-items: flex-start;
}

.moderation-action-forms .new-thread-form {
    flex: 1;
    min-width: 16rem;
}

/* Account status pill -- ACTIVE reads as unremarkable text, SUSPENDED/BANNED use the same
   accent-red already established for .error/.rider-list__state--error elsewhere in this file, so a
   restricted rider's status is visually consistent with every other "something needs attention"
   signal in this app, not a new color introduced just for this one badge. */
.status-badge {
    display: inline-block;
    padding: 0.1rem 0.5rem;
    border-radius: 999px;
    font-size: 0.75rem;
    font-weight: 600;
    font-family: var(--rb-mono-font);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    color: var(--rb-label, #a39fae);
}

.status-badge--suspended,
.status-badge--banned {
    color: var(--rb-accent, #ff6b6b);
    border-color: color-mix(in srgb, var(--rb-accent, #ff6b6b) 45%, transparent);
}

/* django.contrib.messages' framework-supplied success/error tags, rendered on the queue and
   rider-detail pages -- this feature's first real use of django.contrib.messages in this repo
   (installed/wired since day one, but never actually rendered in a template until now). */
.moderation-messages {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.moderation-messages li {
    border-radius: 8px;
    padding: 0.5rem 0.75rem;
    font-size: 0.9rem;
}

.moderation-messages li.success {
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 12%, transparent);
    border: 1px solid color-mix(in srgb, var(--rb-accent, #edeae3) 35%, transparent);
}

.moderation-messages li.error {
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, #ff6b6b 12%, transparent);
    border: 1px solid color-mix(in srgb, #ff6b6b 40%, transparent);
}

/* Login/Register/Forgot-Password/Reset-Password (redesigned 2026-09-04, direct request: "look
   more professional, center it horizontally, and lower it a little bit") -- all four pages share
   this one `.login-page` class and a bare `{{ form.as_p }}` render, which previously had zero
   form-specific CSS anywhere in this file (only the shared page-container rule's generic
   max-width/left-align applied), so every field rendered in raw browser-default styling. This
   rule block comes after that shared rule in the cascade, so it wins on source order at equal
   specificity -- same convention `.current-activity-page`/`.us-statistics-page` already use to
   widen past the shared 640px cap, just narrowing instead here. */
.login-page {
    max-width: 26rem;
    align-items: center;
    text-align: center;
    /* Centered horizontally via margin:auto (overriding the shared rule's plain `margin: 0 auto`
       is a no-op here since it's the same value -- the real fix was `align-items:center`/
       `text-align:center` above, since the shared rule's own `margin:0 auto` already centered the
       BOX, but its left-aligned text inside a fairly wide 640px box read as lopsided/off-center;
       narrowing the card AND centering its content together is what actually reads as centered).
       margin-top lowers it from the header, per the direct request, rather than sitting right
       under the nav. */
    margin-top: clamp(1.5rem, 6vh, 4rem);
    padding: 2rem 2rem 2.25rem;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 78%, var(--rb-text, #edeae3) 6%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 14%, transparent);
    border-radius: 16px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.28);
}

.login-page h1 {
    font-size: 1.9rem;
}

.login-page .muted-note {
    margin-top: -0.25rem;
}

.login-page form {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0.9rem;
    margin-top: 0.25rem;
}

.login-page form p {
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    text-align: left;
}

.login-page form label {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--rb-label, #a39fae);
}

.login-page form input {
    font: inherit;
    font-size: 1rem;
    color: var(--rb-text, #edeae3);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 22%, transparent);
    border-radius: 8px;
    padding: 0.55rem 0.75rem;
    box-sizing: border-box;
    width: 100%;
}

.login-page form input:focus-visible {
    border-color: var(--rb-accent, #edeae3);
}

/* Solid/filled primary button -- a deliberate departure from this file's usual outline-button
   convention (.btn-accent/.settings-save-row button/etc): those are secondary actions inside an
   already-authenticated page; this is the single primary action on an anonymous entry point, and
   reads as more "professional"/decisive filled rather than outlined, per the direct request. Uses
   --rb-bg as the button's own text color (an inverse swap of the page's own bg/accent tokens,
   same "derive from existing tokens, no new hardcoded palette" discipline as every other themed
   rule in this file) since this app has no separate "text-on-accent" token. */
.login-page form button[type="submit"] {
    font: inherit;
    font-size: 0.95rem;
    font-weight: 700;
    color: var(--rb-bg, #15141a);
    background: var(--rb-accent, #edeae3);
    border: none;
    border-radius: 8px;
    padding: 0.65rem 1rem;
    cursor: pointer;
    margin-top: 0.35rem;
}

.login-page form button[type="submit"]:hover {
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 88%, white 12%);
}

.login-page a {
    color: var(--rb-accent, #edeae3);
}

.login-page a:hover,
.login-page a:focus-visible {
    text-decoration-thickness: 2px;
}

.login-page .moderation-messages {
    width: 100%;
}

/* Contact page (redesigned 2026-09-04, direct request: "center this and make it look more
   professional") -- same centered/lowered/shadowed-card treatment as .login-page just above, but
   sized for a couple of prose paragraphs rather than a form (wider, no form-field rules needed).
   `.contact-page` is layered on top of the shared `.static-page` class already on this page's
   <main> (see the page-container rule near the top of this file) so it keeps that rule's base
   flex/box-sizing plumbing and only overrides the specifics here -- same two-class pattern
   `.login-page` itself already uses. */
.contact-page {
    max-width: 32rem;
    align-items: center;
    text-align: center;
    margin-top: clamp(1.5rem, 6vh, 4rem);
    padding: 2.25rem 2.5rem 2.5rem;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 78%, var(--rb-text, #edeae3) 6%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 14%, transparent);
    border-radius: 16px;
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4), 0 4px 16px rgba(0, 0, 0, 0.28);
}

.contact-page h1 {
    font-size: 1.9rem;
}

.contact-page a {
    color: var(--rb-accent, #edeae3);
}

.contact-page a:hover,
.contact-page a:focus-visible {
    text-decoration-thickness: 2px;
}

/* US Statistics page (ad-hoc test page, 2026-09-04) -- an interactive SVG map, sharing the
   .stat-grid/.stat-card/.muted-note conventions used across every other content page in this
   file. Wider than the shared 640px page-container cap, same pattern .current-activity-page
   already established for its own wide map image. Color values for both the marker dots and the
   three helmet-law fill categories live as custom properties on .us-statistics-page (not
   hardcoded per-rule) so the SVG's own fill and each legend swatch's background always agree --
   one source of truth, not two rules that could drift apart. */
.us-statistics-page {
    max-width: 1600px;
    gap: 1.5rem;
    --us-map-active: #2e7d32;
    --us-map-inactive: #1976d2;
    --us-map-accident: #c62828;
    --us-map-universal: #2e8b7f;
    --us-map-partial: #c98a2b;
    --us-map-none: #8d6e63;
}

/* The "floating" card treatment (direct request: the map "feels like it floats above the page")
   -- an elevated panel via box-shadow + a background a shade lighter than the page itself, rather
   than any scroll-triggered animation (this project's general restraint around motion, see
   CLAUDE.md's App shell & typography notes). position:relative scopes the absolutely-positioned
   zoom controls and hover popup layer to this frame, not the whole page. */
.us-map-frame {
    position: relative;
    /* overflow:hidden keeps a hover popup near the frame's own edge (e.g. Maine, Florida) clipped
       to the card itself rather than escaping visually onto the page content around it -- caught
       live during verification (a California popup rendered tall enough to overlap the intro
       paragraph above the frame before this was added). */
    overflow: hidden;
    border-radius: 16px;
    padding: 1.5rem;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 82%, var(--rb-text, #edeae3) 6%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 12%, transparent);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.45), 0 4px 16px rgba(0, 0, 0, 0.3);
}

.us-map-frame__zoom-controls {
    position: absolute;
    top: 1.5rem;
    right: 1.5rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.us-map-frame__zoom-btn {
    width: 2.25rem;
    height: 2.25rem;
    border-radius: 8px;
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    background: color-mix(in srgb, var(--rb-bg, #15141a) 92%, var(--rb-text, #edeae3) 8%);
    color: var(--rb-text, #edeae3);
    font-size: 1.1rem;
    line-height: 1;
    cursor: pointer;
}

.us-map-frame__zoom-btn:hover {
    background: color-mix(in srgb, var(--rb-accent, #edeae3) 14%, transparent);
}

.us-map-frame__zoom-btn--reset {
    width: auto;
    padding: 0 0.6rem;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
}

.us-map__svg {
    display: block;
    width: 100%;
    height: auto;
    cursor: grab;
    touch-action: none;
    /* Panning is dragged via JS-computed transform values, not this property -- but a smooth
       snap-back on the Reset button (and on the initial mount) reads better than an instant jump;
       JS toggles a "no-transition" class off during an active drag so live dragging itself stays
       1:1 with the pointer, not lagging behind a transition. */
}

.us-map__svg.us-map__svg--dragging {
    cursor: grabbing;
}

.us-map__zoom-layer {
    transition: transform 0.15s ease-out;
}

.us-map__svg--dragging .us-map__zoom-layer {
    transition: none;
}

.us-map__state {
    fill: color-mix(in srgb, var(--us-map-universal) 22%, var(--rb-bg, #15141a) 78%);
    stroke: color-mix(in srgb, var(--rb-text, #edeae3) 35%, transparent);
    stroke-width: 1.5;
    cursor: pointer;
    transition: fill 0.12s ease;
}

.us-statistics-page .us-map__state--universal {
    fill: color-mix(in srgb, var(--us-map-universal) 55%, var(--rb-bg, #15141a) 45%);
}

.us-statistics-page .us-map__state--partial {
    fill: color-mix(in srgb, var(--us-map-partial) 45%, var(--rb-bg, #15141a) 55%);
}

.us-statistics-page .us-map__state--none {
    fill: color-mix(in srgb, var(--us-map-none) 45%, var(--rb-bg, #15141a) 55%);
}

.us-map__state:hover,
.us-map__state--hover {
    fill: var(--rb-accent, #edeae3) !important;
}

.us-map__inset-frame {
    fill: none;
    stroke: color-mix(in srgb, var(--rb-text, #edeae3) 30%, transparent);
    stroke-width: 2;
}

.us-map__inset-label {
    fill: color-mix(in srgb, var(--rb-text, #edeae3) 60%, transparent);
    font-size: 30px;
    font-family: var(--rb-mono-font);
}

.us-map__marker {
    stroke: #fff;
    stroke-width: 1.5;
    pointer-events: none;
}

.us-map__marker--active {
    fill: var(--us-map-active);
}

.us-map__marker--inactive {
    fill: var(--us-map-inactive);
}

.us-map__marker--accident {
    fill: var(--us-map-accident);
}

.us-map-legends {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 1.5rem 3rem;
    /* .us-statistics-page is a left-aligned flex column (the shared page-container rule) -- this
       overrides that alignment just for the legends row so both groups (and the wrapped swatch
       rows within each, via .us-map-legend's own centering below) sit centered under the map,
       matching a direct request. */
    align-self: center;
    width: 100%;
}

.us-map-legend {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: 0.4rem 1.25rem;
}

.us-map-legend h2 {
    width: 100%;
    text-align: center;
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    color: var(--rb-label, #a39fae);
}

.us-map-legend__item {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: 0.85rem;
    color: var(--rb-text, #edeae3);
}

.us-map-legend__swatch {
    width: 0.85rem;
    height: 0.85rem;
    border-radius: 50%;
    border: 1px solid #fff;
    flex-shrink: 0;
}

.us-map-legend__swatch--active { background: var(--us-map-active); }
.us-map-legend__swatch--inactive { background: var(--us-map-inactive); }
.us-map-legend__swatch--accident { background: var(--us-map-accident); }
.us-map-legend__swatch--universal { background: var(--us-map-universal); border-radius: 3px; }
.us-map-legend__swatch--partial { background: var(--us-map-partial); border-radius: 3px; }
.us-map-legend__swatch--none { background: var(--us-map-none); border-radius: 3px; }

/* Hover popup -- built entirely by static/js/us_statistics.js, appended into #us-map-popup-layer
   (an absolutely-positioned, full-frame, pointer-events:none overlay so it never blocks map drag/
   hover) at the state's on-screen position: a small, ALWAYS-RECTANGULAR card carrying the actual
   text. An earlier cut also drew a second, decorative element clipped to the hovered state's own
   irregular outline (a literal "popup in the shape of the state") -- that element rendered mostly
   hidden behind this card and added little, so it was removed (2026-09-04, direct feedback:
   "doesn't look visually appealing"), not just left disabled. */
.us-map-popup-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
    z-index: 3;
}

.us-map__popup {
    position: absolute;
    width: 12.5rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    gap: 0.15rem;
    padding: 0.75rem;
    box-sizing: border-box;
    border-radius: 10px;
    background: color-mix(in srgb, var(--rb-bg, #15141a) 94%, var(--rb-text, #edeae3) 6%);
    border: 1px solid color-mix(in srgb, var(--rb-text, #edeae3) 20%, transparent);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
    color: var(--rb-text, #edeae3);
    opacity: 0;
    transition: opacity 0.12s ease;
}

.us-map__popup--visible {
    opacity: 0.97;
}

.us-map__popup__name {
    font-family: var(--rb-heading-font, inherit);
    font-size: 1rem;
    font-weight: 700;
    margin: 0 0 0.15rem;
}

.us-map__popup__stats {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.05rem 0.6rem;
    font-size: 0.7rem;
    color: var(--rb-label, #a39fae);
}

.us-map__popup__stats strong {
    color: var(--rb-text, #edeae3);
}

.us-map__popup__helmet {
    margin-top: 0.35rem;
    font-size: 0.68rem;
    color: var(--rb-label, #a39fae);
    max-width: 12rem;
}

.us-map__popup__moto {
    font-size: 0.68rem;
    color: var(--rb-label, #a39fae);
}
