/* YOHB header + bottom-nav styles. Merged into existing NavMenu + MenuComponent. */

/* Header / footer heights as CSS vars so every sticky element below can
   compose its top/bottom offsets off the same source of truth. */
:root {
    --gp-header-height: 56px;
    --gp-footer-height: 50px;
}

/* Constrain the entire page chrome to 700px max and center it on desktop.
   Body/html stay black so the area outside the centered page matches. */
html, body {
    background-color: #000000 !important;
}

/* Window/document is the scroll container — NOT an inner .main. This lets
   mobile browser chrome (URL bar, etc.) auto-hide/show correctly as the
   user scrolls, and gives sticky elements (header, footer, PageHero, profile
   stats/tabs) one consistent viewport-anchored reference. Override the
   legacy app.css `.page { height: 100vh }` flex layout. */
.page {
    max-width: 700px;
    margin: 0 auto;
    height: auto;
    min-height: 100vh;
}

/* Let content flow naturally; do NOT make .main its own scroll container.
   Override the legacy app.css `.main { flex: 0 1 100% }` so it can grow
   beyond viewport height when content is long. */
.main {
    overflow: visible !important;
    flex: 1 1 auto;
}

/* Outer .header wrapper (.page > .header in MainLayout) — YOHB chrome
   height + sticky to top of viewport so it stays pinned on scroll. */
.page > .header {
    height: var(--gp-header-height) !important;
    background-color: #000000;
    position: sticky;
    top: 0;
    z-index: 1000;
}

/* iOS: stop document rubber-band overscroll from painting content over the sticky
   header/hero. SCOPED TO iOS ONLY via the -webkit-touch-callout @supports hack
   (true only on iOS Safari/WKWebView; false on Android Chrome/Blink + desktop).
   On the document/root scroller, overscroll-behavior-y: none ALSO disables Android
   Chrome's pull-to-refresh, so applying it app-wide killed pull-to-refresh on
   Android — scoping keeps the iOS fix while Android keeps pull-to-refresh. iOS 16+. */
@supports (-webkit-touch-callout: none) {
    html {
        overscroll-behavior-y: none;
    }
}

/* Legacy pages (Garage, Discover, Post, Club, Event detail, VehicleComponent)
   each render their content inside a nested chain of historically-scrolling
   wrappers: the outer `.content` (top-level page wrapper), then
   `.content-view-wrapper`, then `.garage-view` / `.page-view` / `.post-view`,
   then `.garage-view-content` / `.page-view-content` / `.post-view-content` /
   `.vehicle-view-content`. EVERY level had overflow-y: auto, which traps
   sticky descendants (they would bind to the inner scroller instead of the
   viewport — so PageHero/profile stats/tab bar would stop sticking) AND
   clips content to the parent's intrinsic height. With body-scrolling
   architecture all of these collapse to natural flow. */
.content,
.content-view-wrapper,
.garage-view,
.page-view,
.post-view,
.garage-view-content,
.page-view-content,
.post-view-content,
.vehicle-view-content {
    overflow-y: visible !important;
}

/* HEADER */

.yohb-header {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
    background-color: #000000;
    border-bottom: 0.5px solid #1A1A1A;
    color: #FFFFFF;
}

.yohb-header-left {
    display: flex;
    align-items: center;
    gap: 14px;
    padding-left: 14px;
    flex: 1 1 0;
    min-width: 0;
}

.yohb-header-right {
    display: flex;
    align-items: center;
    gap: 14px;
    padding-right: 14px;
    flex: 1 1 0;
    min-width: 0;
    justify-content: flex-end;
}

.yohb-header-center {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
}

.yohb-header-icon {
    background: transparent;
    border: 0;
    padding: 0;
    color: #FFFFFF;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}

.yohb-header-icon:hover,
.yohb-header-icon:focus {
    color: #FFFFFF;
}

.yohb-header-icon .material-symbols-outlined {
    font-size: 24px;
    color: #FFFFFF;
}

.yohb-header-logo {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 22px;
    letter-spacing: 1.5px;
    line-height: 1;
    text-decoration: none;
    user-select: none;
    display: inline-flex;
    align-items: center;
}

.yohb-header-logo-primary { color: #FFFFFF; }
.yohb-header-logo-accent  { color: var(--gp-blue); }

.yohb-header-bell-wrap {
    position: relative;
}

/* The bell's Syncfusion button holds two children (the icon span + the absolutely
   positioned badge span). The hamburger button holds only the icon, so its default
   inline layout centers it via the outer .yohb-header-icon flex. With two children
   the bell sometimes lands a pixel or two off; force its button to flex-center the
   icon so it lines up with the hamburger / search / avatar icons next to it. */
.yohb-header-bell-wrap > .yohb-dropdown-trigger,
.yohb-header-bell-wrap .yohb-bell-dropdown {
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    line-height: 1 !important;
}

.yohb-header-bell-badge {
    position: absolute;
    top: -4px;
    right: -4px;
    width: 14px;
    height: 14px;
    border-radius: 50%;
    background-color: var(--gp-blue);
    color: #000000;
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    font-size: 9px;
    line-height: 14px;
    text-align: center;
    pointer-events: none;
}

/* Header avatar shares the PostCard avatar treatment: dark surface with a
   blue ring + blue initials, so the user identity reads consistently across
   the app chrome and the cards. */
.yohb-header-avatar {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background-color: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    box-sizing: border-box;
    color: var(--gp-blue);
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    cursor: pointer;
    text-decoration: none;
}

.yohb-header-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.yohb-header-avatar-initial {
    color: var(--gp-blue);
    line-height: 1;
}

/* Inline nav links */

.yohb-header-inline-nav {
    display: flex;
    align-items: center;
    gap: 20px;
}

.yohb-header-link {
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 14px;
    text-decoration: none;
    line-height: 1;
    padding: 4px 2px;
}

.yohb-header-link.active,
.yohb-header-link:hover {
    color: var(--gp-blue);
}

/* Syncfusion dropdown trigger button — strip default chrome so only the icon shows */
.yohb-dropdown-trigger,
.yohb-dropdown-trigger:hover,
.yohb-dropdown-trigger:focus,
.yohb-dropdown-trigger:active,
.yohb-dropdown-trigger.e-active {
    background: transparent !important;
    background-color: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    outline: none !important;
    padding: 0 !important;
    color: #FFFFFF !important;
    min-width: 0 !important;
}

.yohb-dropdown-trigger .e-btn-icon,
.yohb-dropdown-trigger .e-icons {
    margin: 0 !important;
}

/* Items inside the popup */
.yohb-dropdown-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 4px 0;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 15px;
    line-height: 1.2;
}

.yohb-dropdown-item-icon {
    font-size: 20px !important;
    color: #FFFFFF;
}

.yohb-dropdown-item-text {
    color: inherit;
}

/* Hover/active item — Syncfusion adds .e-selected / .e-focused on the <li> */
.e-dropdown-popup ul .e-item:hover .yohb-dropdown-item,
.e-dropdown-popup ul .e-item:hover .yohb-dropdown-item-icon,
.e-dropdown-popup ul .e-item.e-focused .yohb-dropdown-item,
.e-dropdown-popup ul .e-item.e-focused .yohb-dropdown-item-icon,
.e-dropdown-popup ul .e-item.e-selected .yohb-dropdown-item,
.e-dropdown-popup ul .e-item.e-selected .yohb-dropdown-item-icon {
    color: var(--gp-blue) !important;
}

/* Notification dropdown items */
.yohb-notification-item {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    min-width: 220px;
}

.yohb-notification-item-title {
    font-size: 14px;
    font-weight: 500;
    color: inherit;
}

/* Popup chrome — match dark theme */
.e-dropdown-popup {
    background-color: #000000 !important;
    border: 0.5px solid #1A1A1A !important;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5) !important;
}

.e-dropdown-popup ul {
    padding: 4px 0 !important;
    background-color: #000000 !important;
}

.e-dropdown-popup ul .e-item {
    background-color: transparent !important;
    color: #FFFFFF !important;
    padding: 10px 14px !important;
    line-height: 1.2 !important;
    height: auto !important;
}

.e-dropdown-popup ul .e-item:hover,
.e-dropdown-popup ul .e-item.e-focused,
.e-dropdown-popup ul .e-item.e-selected {
    background-color: rgba(41, 171, 226, 0.08) !important;
    color: var(--gp-blue) !important;
}

/* Search icon position swap: lives in the left cluster on mobile,
   lives next to the bell on wide screens */
.yohb-search-desktop {
    display: none;
}

/* Small-screen rules: hide inline nav (hamburger always visible at all sizes,
   but only the hamburger acts as primary nav on small screens) */
@media (max-width: calc(600px + 3rem)) {
    .yohb-header-inline-nav {
        display: none;
    }
}

@media (min-width: calc(600px + 3rem)) {
    .yohb-search-mobile {
        display: none;
    }
    .yohb-search-desktop {
        display: inline-flex;
    }
}

/* Large-screen rules: hamburger hidden, logo to the left, all nav to the right */
@media (min-width: calc(600px + 3rem)) {
    .yohb-header-hamburger {
        display: none;
    }

    /* Logo: leftmost. margin-right:auto pushes everything else to the far right. */
    .yohb-header-center {
        order: 1;
        margin: 0 auto 0 0;
        padding-left: 16px;
    }

    /* Inline links + search icon (sit just before the right-side cluster) */
    .yohb-header-left {
        order: 2;
        flex: 0 0 auto;
        padding-left: 0;
    }

    /* Auth links + bell + avatar (padding-left matches the inline-nav gap so
       Feed → Sign Up reads with the same spacing as the items within each nav) */
    .yohb-header-right {
        order: 3;
        flex: 0 0 auto;
        padding-left: 20px;
    }
}

/* PAGE HERO

   Layout: a `position: relative` flex row with the back chevron on the
   left and the RightAction on the right (margin-left: auto pushes it).
   The title is ABSOLUTELY positioned at left:50% / translate(-50%) so
   it's anchored to the visual center of the hero — NOT positioned by
   the layout flow. iOS / Material navigation-bar pattern.

   Why not grid `1fr auto 1fr`? Equal-fr columns are only equal as long
   as neither side's content forces its column past the fr share. When
   the chevron (small) and the RightAction button (larger) have different
   widths, the auto center column gets positioned between two visually
   unequal cells — the title slides off the true page center and starts
   to overlap the back chevron once it ellipses. Absolute centering kills
   the dependency: sides take whatever space they need, the title is
   always at the page midline.

   `max-width: calc(100% - 120px)` on the absolutely-positioned title
   reserves 60px on each side so the title cannot physically overlap a
   side button no matter how long the text. Bump 120 if you add wider
   hero buttons.

   PageHero.razor always renders all three cells (the back-cell and
   right-action wrappers stay present even when their content is null)
   so the flex row's edges stay where the buttons would put them. */

.page-hero {
    position: sticky;
    /* Sits below the (also sticky) global header. */
    top: var(--gp-header-height);
    z-index: 100;
    /* Inner layout — relative anchors the absolutely-positioned title. */
    display: flex;
    align-items: center;
    padding: 14px 16px 10px;
    min-height: 50px;
    background-color: #000000;
    align-self: stretch;
    width: 100%;
    max-width: 700px;
    box-sizing: border-box;
}

.page-hero-back-cell {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    z-index: 1; /* above the absolute-positioned title */
}

.page-hero-back {
    background: transparent;
    border: 0;
    padding: 0;
    color: #FFFFFF;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.page-hero-back .material-symbols-outlined {
    font-size: 36px;
    color: #FFFFFF;
}

.page-hero-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 28px;
    color: #FFFFFF;
    line-height: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Default: title is absolute-centered on the hero midline. Reserves
   60px each side for the chevron and the RightAction button so it
   cannot physically overlap them. */
.page-hero-centered {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    max-width: calc(100% - 165px);
    text-align: center;
}

/* Fallback: when ShowBackArrow=false the title is left-aligned and stays
   in flex flow (no need for absolute centering when there's no chevron). */
.page-hero-title.page-hero-left {
    position: static;
    transform: none;
    left: auto;
    top: auto;
    max-width: none;
    text-align: left;
    flex: 1 1 auto;
    min-width: 0;
}

.page-hero-right-action {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    margin-left: auto;
    z-index: 1; /* above the absolute-positioned title */
}

/* BOTTOM NAV (Footer MenuComponent variant) */

.yohb-bottom-nav {
    display: flex;
    justify-content: space-around;
    align-items: stretch;
    width: 100%;
    background-color: #000000;
    border-top: 0.5px solid #1A1A1A;
    padding-bottom: 8px;
}

.yohb-bottom-nav-item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    padding-top: 8px;
    gap: 3px;
    color: #ffffff;
    text-decoration: none;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 10px;
    line-height: 1;
}

.yohb-bottom-nav-item .material-symbols-outlined {
    font-size: 22px;
    color: #ffffff;
}

.yohb-bottom-nav-item:hover,
.yohb-bottom-nav-item-active,
.yohb-bottom-nav-item.active {
    color: var(--gp-blue);
}

.yohb-bottom-nav-item:hover .material-symbols-outlined,
.yohb-bottom-nav-item-active .material-symbols-outlined,
.yohb-bottom-nav-item.active .material-symbols-outlined {
    color: var(--gp-blue);
}

/* The existing .footer-menus wrapper is mobile-only (display:none default, flex on small screens).
   Override the legacy 50px margin-bottom on .main since the footer is a flex sibling, not fixed.
   With body-scrolling architecture the footer also sticks to the viewport bottom so it stays
   visible during scroll (same idiom as the sticky header). */
@media (max-width: calc(600px + 3rem)) {
    .main {
        margin-bottom: 0 !important;
    }

    .footer-menus {
        position: sticky;
        /* -1px + matching padding closes the 1px sub-pixel gap sticky bottom:0
           leaves below the bar on fractional DPRs, without moving the nav. */
        bottom: -1px;
        padding-bottom: 1px;
        z-index: 1000;
    }
}

/* Mobile platforms (iPhone/iPad/Android) always show the bottom nav, regardless
   of viewport width/orientation — landscape mobile is wider than the width
   breakpoint above, which would otherwise hide it. is-mobile is set on <html>
   from the device platform (gp_global.js yohbApplyMobileClass; same signal as
   Device.razor's getDevicePlatform). Desktop browsers never get is-mobile, so
   they keep the width-driven behavior above. */
html.is-mobile .footer-menus {
    display: flex;
    position: sticky;
    bottom: -1px;
    padding-bottom: 1px;
    z-index: 1000;
}

html.is-mobile .main {
    margin-bottom: 0 !important;
}

/* Drop the legacy fixed `.footer-menu { height: 60px }` from app.css. Sticky
   positioning doesn't need a fixed height, and the 60px height combined with
   the symmetric vertical padding made the icons sit visually higher than
   contents got crowded toward the top). Letting the footer size to its
   content + padding reads cleaner. */
.footer-menu {
    height: auto;
}

/* FEED PAGE */

.feed-content {
    padding: 0 16px 16px;
}

/* POST CARD (new feed-style card; `.post-card` already exists in app.css for the legacy PostComponent layout) */
/* Surface (bg/border/radius/cursor) is shared with .ent-card above — only
   PostCard-specific layout here. */
.post-card-new {
    padding: 14px;
    margin-bottom: 10px;
}

.post-header {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-bottom: 10px;
}

.post-avatar {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}

.post-avatar-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.post-avatar-initials {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: var(--gp-blue);
    text-transform: uppercase;
    line-height: 1;
}

.post-author {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.post-name {
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 13px;
    cursor: pointer;
    width: fit-content;
}

.post-name:hover {
    color: var(--gp-blue);
}

.post-meta {
    color: #555555;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.post-handle {
    cursor: pointer;
}

.post-handle:hover {
    color: var(--gp-blue);
}

/* Entity post header (PostedAsEntity): the small clickable "posted by @user"
   author credit + the entity-glyph avatar fallback (club `group` / event `event`).
   .yohb-posted-in is the matching "in {club/event}" tag on MEMBER posts shown
   outside the entity's own feed. */
.yohb-posted-by,
.yohb-posted-in {
    cursor: pointer;
}
.yohb-posted-by:hover,
.yohb-posted-in:hover {
    color: var(--gp-blue);
}
/* Trailing club/event type glyph inside the "in {entity}" tag. */
.yohb-posted-in-icon {
    font-size: 12px;
    vertical-align: -2px;
    margin-left: 3px;
    color: inherit;
}
.post-avatar-entity-glyph {
    font-size: 22px;
    color: var(--gp-blue);
}

/* CARD MENU (generic three-dot dropdown — reused across Post/Vehicle/User/Event/Club cards) */
.card-menu {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
}

.card-menu-icon {
    color: #555555;
    font-size: 20px;
    line-height: 1;
}

/* POST BODY */
.post-body {
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 13.5px;
    line-height: 1.4;
    margin-bottom: 10px;
    white-space: pre-wrap;
    word-wrap: break-word;
}

.post-body.clamped {
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.post-more {
    display: none;
    color: var(--gp-blue);
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 12px;
    cursor: pointer;
    margin-bottom: 10px;
    user-select: none;
}

/* Show the more/less link only when the full body content would exceed 3 lines.
   Same condition for both clamped (...more) and expanded (...less) states. */
.post-body.post-body-overflowing + .post-more {
    display: inline-block;
}

.post-card-images.gp-card-media {
    /* Override legacy app.css (.post-card-images { display:flex; max-height:300px })
       which kept the carousel from stretching full width and fought the
       aspect-ratio. Match wherever .post-card-images is paired with
       .gp-card-media (PostCard body, PostThreadModal reply bubbles, future
       feed-style consumers) so the override isn't scoped to .post-card-new. */
    display: block;
    width: 100%;
    max-height: none;
    border-radius: 8px;
    margin-bottom: 10px;
    overflow: hidden;
    position: relative;
}
/* Carousel chain fills the aspect-ratio box (.gp-card-media on the wrapper). */
.post-card-images.gp-card-media .card-carousel,
.post-card-images.gp-card-media .carousel-inner,
.post-card-images.gp-card-media .carousel-item,
.post-card-images.gp-card-media .card-carousel-slide {
    width: 100%;
    height: 100%;
}

.post-card-new .card-carousel-image {
    width: 100%;
    height: 100%;
    max-height: none !important;
    object-fit: cover;
    border-radius: 8px;
}

.post-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}

.post-tag {
    display: inline-flex;
    align-items: center;
    padding: 6px 10px;
    border-radius: 6px;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
    cursor: pointer;
    user-select: none;
    background: rgba(41, 171, 226, 0.1);
    border: 0.5px solid rgba(41, 171, 226, 0.3);
    color: var(--gp-blue);
}

/* POST ACTIONS */
.post-actions {
    display: flex;
    align-items: center;
    gap: 24px;
    border-top: 0.5px solid #1C1C1C;
    padding-top: 8px;
}

.post-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: #888888;
    cursor: pointer;
    user-select: none;
}

.post-action.liked {
    color: var(--gp-blue);
}

.mention-link {
    cursor: pointer;
}

.post-action .action-icon {
    font-size: 18px;
    color: inherit;
    line-height: 1;
}

.post-action.liked .action-icon.filled {
    font-variation-settings: 'FILL' 1;
}

.post-action-count {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 12px;
    color: inherit;
}

.floating-action-button {
    position: fixed;
    bottom: 88px;
    right: 24px;
    width: 56px;
    height: 56px;
    border: 0;
    border-radius: 50%;
    background: var(--gp-blue);
    color: #000000;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 900;
    padding: 0;
}

.floating-action-button:focus {
    outline: none;
}

.floating-action-button .fab-icon {
    font-size: 28px;
    color: #000000;
    line-height: 1;
}

/* Canonical Add/Edit button style (matches .yohb-edit-pencil-btn). Use this
   for every Add/Edit action button: Add -> "add" icon, Edit -> "edit" icon. */
.add-post-button {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 2px 9px;
    border: 1.5px solid var(--gp-blue);
    border-radius: var(--gp-card-border-radius);
    background: transparent;
    color: var(--gp-blue);
    cursor: pointer;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
}

.add-post-button:focus {
    outline: none;
}

.add-post-button-icon {
    /* 20px: 24px was too large, 16px too small here — the Add button layout
       differs slightly from the edit-pencil button (which stays 16px). */
    font-size: 20px !important;
    color: var(--gp-blue);
    line-height: 1;
}

.add-post-button-text {
    font-size: 12px;
    font-weight: 700;
    color: var(--gp-blue);
    line-height: 1;
}

/* ============================================================
   SHARED STATUS BADGE SYSTEM
   One fixed palette so role/status badges (Club/Event V2 cards,
   future surfaces) never drift into several different blues.
   cyan = member/registered/active, amber = founder/coordinator,
   green = attended/done, red = admin, neutral = invited/requested.
   ============================================================ */
.status-badge {
    display: inline-flex;
    align-items: center;
    font-family: 'DM Sans', sans-serif;
    font-weight: 600;
    font-size: 10px;
    padding: 4px 8px;
    border-radius: 4px;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    backdrop-filter: blur(4px);
    white-space: nowrap;
}

.status-badge-cyan { background: rgba(41, 171, 226, 0.9); color: #000000; }
.status-badge-amber { background: var(--gp-amber); color: #000000; }
.status-badge-green { background: var(--gp-success); color: #000000; }
.status-badge-red { background: var(--gp-error); color: #FFFFFF; }
.status-badge-neutral { background: rgba(255, 255, 255, 0.85); color: #000000; }

.status-overlay { position: absolute; top: 10px; right: 10px; }

/* ============================================================
   BOTTOM-SHEET MODAL (reusable; route-driven on Profile)
   ============================================================ */
@keyframes yohb-fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes yohb-sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }

.yohb-sheet-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.7);
    z-index: 1500;
    display: flex;
    align-items: flex-end;
    justify-content: center;
    animation: yohb-fade-in 0.18s ease-out;
}

.yohb-sheet {
    background: #000000;
    width: 100%;
    max-width: 700px;
    /* Positioned so .yohb-sheet-restore-cover (absolute) covers just the sheet. */
    position: relative;
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
    border: 0.5px solid #1C1C1C;
    border-bottom: none;
    /* Sized so only the global header (56px) + page hero (~64px) remain
       visible above the sheet — i.e. the user always sees what page they
       opened the sheet from, but nothing of the page body. 120px reserved.
       Body scrolls internally. The post-thread modal uses the same rule
       so every slide-up modal in the app has the same vertical extent. */
    height: calc(100vh - 120px);
    display: flex;
    flex-direction: column;
    box-shadow: 0 -8px 32px rgba(0, 0, 0, 0.8);
    animation: yohb-sheet-up 0.24s cubic-bezier(0.16, 1, 0.3, 1);
}

.yohb-sheet-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 14px 16px 12px;
    border-bottom: 0.5px solid #1C1C1C;
    flex: 0 0 auto;
}

.yohb-sheet-titles {
    display: flex;
    flex-direction: column;
    gap: 2px;
    min-width: 0;
}

.yohb-sheet-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 16px;
    letter-spacing: 0.5px;
    color: #FFFFFF;
}

/* Club-name eyebrow above the section title (Members / Your history / etc.). */
.yohb-sheet-overline {
    font-family: 'DM Sans', sans-serif;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--gp-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.yohb-sheet-close {
    color: #FFFFFF;
    font-size: 22px;
    cursor: pointer;
    background: none;
    border: 0;
    padding: 0;
    line-height: 1;
}

.yohb-sheet-body {
    overflow-y: auto;
    flex: 1 1 auto;
}

/* Anti-flash cover for slide-up modals — same idea as .yohb-restore-overlay on the
   lazy pages. Shown from open through the inner-scroll restore (opaque, sheet bg) so
   the user never sees the body content at the top before it snaps to the saved
   scrollTop. Covers the whole sheet (radius matches); removed once scroll is set. */
.yohb-sheet-restore-cover {
    position: absolute;
    inset: 0;
    background: #000000;
    z-index: 3;
    display: flex;
    align-items: flex-start;
    justify-content: center;
    border-top-left-radius: 16px;
    border-top-right-radius: 16px;
}

/* Padded content wrapper inside the body. BottomSheet wraps its ChildContent
   in this, so every padded slide-up (Profile sheets, LikesModal) shares one
   padding rule. Flush slide-ups (PostThreadModal — its root card + reply tree
   manage their own spacing) put content directly in .yohb-sheet-body and skip
   this wrapper. */
.yohb-sheet-content {
    padding: 8px 16px 24px;
}

/* About modal rows */
.yohb-about-row { padding: 12px 0; border-bottom: 0.5px solid #1C1C1C; }
.yohb-about-row:last-child { border-bottom: none; }
.yohb-about-label {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 10px;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: #888888;
    margin-bottom: 5px;
    display: flex;
    align-items: center;
}
.yohb-about-value {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 13.5px;
    color: #FFFFFF;
    line-height: 1.4;
    white-space: pre-wrap;
}
.yohb-private-note {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: #555555;
    font-size: 10px;
    margin-left: 6px;
}
.yohb-private-note .material-symbols-outlined { font-size: 11px; }
.yohb-interest-pills { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 2px; }
.yohb-interest-pill {
    background: rgba(255, 255, 255, 0.04);
    border: 0.5px solid #1C1C1C;
    border-radius: 6px;
    padding: 5px 10px;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11.5px;
    color: #FFFFFF;
}

/* Followers/Following modal */
.yohb-modal-tabs { display: flex; border-bottom: 0.5px solid #1C1C1C; }
.yohb-modal-tab {
    flex: 1;
    text-align: center;
    padding: 12px 4px;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 12px;
    color: #888888;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    background: none;
    border-top: 0;
    border-left: 0;
    border-right: 0;
}
.yohb-modal-tab.active { color: var(--gp-blue); border-bottom-color: var(--gp-blue); }
.yohb-user-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 0.5px solid #1C1C1C;
    cursor: pointer;
}
.yohb-user-row:last-child { border-bottom: none; }
.yohb-user-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
}
.yohb-user-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-user-avatar-initials {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 14px;
    color: var(--gp-blue);
    text-transform: uppercase;
}
.yohb-user-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 14px;
    color: #FFFFFF;
    flex: 1;
    min-width: 0;
}
.yohb-user-row:hover .yohb-user-name { color: var(--gp-blue); }
.yohb-empty {
    text-align: center;
    color: #555555;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    padding: 28px 0;
}

/* ============================================================
   PROFILE PAGE (v4)
   ============================================================ */
/* Full available width. .main (app.css) is a flex column with
   align-items:center, so without width:100% the profile shrinks/grows to
   its content (wide images widened the page). Lock to the column width;
   the 700px cap + outer padding still apply via .page. */
.yohb-profile {
    background: #000000;
    width: 100%;
    box-sizing: border-box;
    /* Sticky-bar heights — keep matching the rendered heights. */
    --yohb-hero-h: 60px;
    --yohb-pb-id-h: 80px;
    --yohb-stats-h: 40px;
}
.yohb-profile, .yohb-tab-content { min-width: 0; }
.yohb-tab-content > * { max-width: 100%; }

/* Profile page hero (reuses .page-hero; sticky under the global header). The
   title is the display name, full stop — the scroll-driven swap to @username
   was removed (the gp_global.js watcher was glitchy and added no real value
   over showing the display name consistently). */
.yohb-profile-hero { border-bottom: 0.5px solid #1C1C1C; }

/* Hero banner (V2) — a photo/gradient strip that scrolls away ABOVE the sticky
   .yohb-ph-top identity bar. NO scroll-collapse (the avatar/name bar below stays
   pinned exactly as before); the banner is plain non-sticky scroll content, so
   the sticky offsets are unchanged. Uses the user's avatar as a faint cover
   image when present, else the cyan gradient. */
.yohb-profile-banner {
    position: relative;
    /* Standard banner ratio (≈ Twitter/X), a bit wider — scales W+H with the column. */
    aspect-ratio: 3.5 / 1;
    flex-shrink: 0;
    overflow: hidden;
    background:
        radial-gradient(circle at 22% 28%, rgba(41, 171, 226, 0.30) 0%, transparent 55%),
        radial-gradient(circle at 82% 72%, rgba(41, 171, 226, 0.12) 0%, transparent 60%),
        linear-gradient(135deg, #0a1a2a 0%, #000000 100%);
}
.yohb-profile-banner-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
/* Logo fallback — contain + centered on the brand gradient (not cover-cropped). */
.yohb-profile-banner-img.yohb-banner-logo {
    object-fit: contain;
    padding: 28px;
}

/* Identity bar — sticky under the hero (replaces the removed .yohb-ph-top). The
   banner image scrolls away above it; this bar stays pinned. Opaque bg so the
   content scrolling behind it stays hidden when pinned. z-index above the
   sticky-chrome (tabs) so it isn't overlapped when both pin. */
.yohb-pb-id {
    position: sticky;
    top: calc(var(--gp-header-height) + var(--yohb-hero-h));
    z-index: 96;
    /* Solid bar that sits BELOW the banner image (not overlaid). Sticky: the image
       scrolls away above it while this stays pinned. Opaque so scrolled content
       behind it stays hidden. */
    background: #000000;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-bottom: 0.5px solid #1C1C1C;
}
.yohb-pb-avatar {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 2px solid var(--gp-blue);
    overflow: hidden;
    flex-shrink: 0;
    background: #1A1A1A;
    display: flex;
    align-items: center;
    justify-content: center;
}
.yohb-pb-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-pb-avatar.yohb-avatar-clickable { cursor: pointer; }
.yohb-pb-avatar-initials {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 22px;
    color: var(--gp-blue);
    text-transform: uppercase;
}
.yohb-pb-text { flex: 1; min-width: 0; }
.yohb-pb-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 18px;
    line-height: 1.1;
    color: #FFFFFF;
}
.yohb-pb-username {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: #888888;
    margin-top: 2px;
}

/* Six profile stat cards, 3 per row — each opens its slide-up sheet. Reuses the
   shared .yohb-stat-card (which centers its content for all stat cards). */
.yohb-profile-stat-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 10px;
    padding: 12px 14px;
    /* Opaque + lifted over the collapsed flat bar (above it in the DOM) so only the
       cards show until they scroll out of view, then the flat bar is revealed. z 11
       keeps them above the flat bar (z 10) yet below the pb-id (z 96). */
    position: relative;
    z-index: 11;
    background: #000000;
    margin-top: calc(-1 * var(--yohb-stats-h));
}

/* Banner-image picker (Edit Profile + ProfileSetup) — a wide rectangular preview. */
.yohb-banner-edit { display: flex; flex-direction: column; gap: 10px; }
.yohb-banner-edit-wrap { position: relative; width: 100%; }
.yohb-banner-edit-preview {
    width: 100%;
    aspect-ratio: 16 / 7;
    border-radius: var(--gp-card-border-radius);
    background: #0A0A0A;
    border: 0.5px solid #1C1C1C;
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #555555;
}
.yohb-banner-edit-preview img { width: 100%; height: 100%; object-fit: cover; }
.yohb-banner-edit-preview .material-symbols-outlined { font-size: 40px; }
.yohb-banner-edit-remove {
    position: absolute;
    top: 8px;
    right: 8px;
    width: 28px;
    height: 28px;
    border-radius: 50%;
    background: var(--gp-error);
    border: 1.5px solid #000000;
    color: #FFFFFF;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
}
.yohb-banner-edit-remove .material-symbols-outlined { font-size: 18px; }
.yohb-banner-edit-actions { display: flex; }

/* Identity meta + bio block — scrolls away normally. The avatar+name
   row (.yohb-ph-top) lives OUTSIDE this block (as a direct child of
   .yohb-profile) so it can stay sticky for the entire profile scroll. */
.yohb-profile-header {
    background: #000000;
    padding: 0 16px 16px;
}

/* Stats + tabs on the profile share ONE sticky container so the tab bar
   always sits flush below the stats bar. Previously each bar had its own
   sticky `top:` calc that referenced `--yohb-stats-h`, and when the stats
   bar's actual rendered height differed (it varies with wrap on narrow
   viewports), a gap or overlap appeared between them. The wrapper pins
   both together at one threshold and the inner bars are static. */
.yohb-profile .yohb-sticky-chrome {
    position: sticky;
    /* Sits below the identity bar + the collapsed flat stats bar. */
    top: calc(var(--gp-header-height) + var(--yohb-hero-h) + var(--yohb-pb-id-h) + var(--yohb-stats-h));
    z-index: 95;
    background: #000000;
}

/* Collapsed flat stats bar (profile) — a SEPARATE sticky element (no longer inside
   the chrome). Fixed height = --yohb-stats-h so the cards' negative margin covers it
   exactly; pins below the identity bar; sits BEHIND the cards (z 1) until they scroll
   away. One line, horizontally scrollable if it overflows on a narrow column. */
.yohb-profile .yohb-stats-bar {
    top: calc(var(--gp-header-height) + var(--yohb-hero-h) + var(--yohb-pb-id-h));
    /* Above the YohbCarousel chevrons (.yohb-carousel-nav z 2) so Posts-tab card
       buttons scroll BEHIND this pinned bar — but below the cards (z 11) that cover
       it, and below the pb-id/tabs. */
    z-index: 10;
    height: var(--yohb-stats-h);
    padding-top: 0;
    padding-bottom: 0;
}
.yohb-profile .yohb-stats-bar .yohb-stats-inline {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    overflow-y: hidden;
    gap: 0 16px;
}
.yohb-profile .yohb-stats-bar .yohb-stats-inline::-webkit-scrollbar { height: 0; }

.yohb-profile .yohb-sticky-chrome .yohb-stats-bar,
.yohb-profile .yohb-sticky-chrome .yohb-tab-bar {
    position: static;
    top: auto;
    z-index: auto;
}

/* Stats bar layout (positioning is owned by .yohb-sticky-chrome above for
   the profile; the rule below still applies to any other future host that
   uses .yohb-stats-bar without the wrapper). */
.yohb-stats-bar {
    position: sticky;
    top: calc(var(--gp-header-height) + var(--yohb-hero-h));
    z-index: 90;
    background: #000000;
    display: flex;
    align-items: center;
    padding: 8px 16px;
    border-top: 0.5px solid #1C1C1C;
    border-bottom: 0.5px solid #1C1C1C;
}
.yohb-stats-bar .yohb-stats-inline {
    border-top: 0;
    padding-top: 0;
    width: 100%;
    /* Center the stats and let them wrap onto a second row on narrow
       viewports. Gap replaces the old "·" separator (removed because a
       trailing separator on a wrapped row looked imbalanced). */
    display: flex;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    gap: 5px 8px;
}

/* (The old narrow-viewport --yohb-stats-h bump was removed: the collapsed flat
   stats bar is now a FIXED-height, single-line, horizontally-scrollable bar, so
   --yohb-stats-h stays constant at all widths and the cards' cover offset matches.) */
/* Avatar + identity row — sticky under the hero. Sits ABOVE the
   .yohb-sticky-chrome (which has z 95) so when both pin during scroll
   the chrome doesn't slide over the avatar. Padded so it spans the
   full profile width (16px each side matches what .yohb-profile-header
   used to provide for the row when it was a child of that block).
   Height should match --yohb-ph-top-h on .yohb-profile — tune the var
   if you change avatar size or padding. */
.yohb-ph-top {
    position: sticky;
    top: calc(var(--gp-header-height) + var(--yohb-hero-h));
    z-index: 96;
    background: #000000;
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 12px 16px;
    border-bottom: 0.5px solid #1C1C1C;
}
.yohb-profile-avatar {
    width: 72px;
    height: 72px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 2px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.yohb-profile-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-profile-avatar-initials {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 26px;
    color: var(--gp-blue);
    text-transform: uppercase;
}
.yohb-ph-text { flex: 1; min-width: 0; }
.yohb-ph-action { align-self: flex-start; }

/* Avatar select/preview in the Edit form */
.yohb-avatar-edit { display: flex; align-items: center; gap: 20px; margin-bottom: 6px; }
/* Unclipped wrapper so the × overlays the corner ABOVE the circle. */
.yohb-avatar-edit-wrap {
    position: relative;
    width: 84px;
    height: 84px;
    flex-shrink: 0;
}
.yohb-avatar-edit-preview {
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: #1A1A1A;
    border: 2px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
}
.yohb-avatar-edit-preview img { width: 100%; height: 100%; object-fit: cover; }
.yohb-avatar-edit-preview .material-symbols-outlined { font-size: 34px; color: var(--gp-blue); }
.yohb-avatar-edit-remove {
    position: absolute;
    top: -6px;
    right: -6px;
    z-index: 2;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    border: 1.5px solid #000000;
    background: var(--gp-error);
    color: #FFFFFF;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0;
}
.yohb-avatar-edit-remove .material-symbols-outlined { font-size: 15px; color: #FFFFFF; }
.yohb-avatar-edit-actions { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
/* This Add/Change button is a <label> inside a .form-group, so it inherits
   the form's block label styling — re-assert the canonical flex centering.
   Same fix for the banner picker's "Add/Change Banner" label. */
.yohb-avatar-edit-actions label.add-post-button,
.yohb-banner-edit-actions label.add-post-button {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin: 0;
    line-height: 1;
}
/* Bio grows with its line count (field-sizing) but no manual drag handle. */
.profile-bio-text { resize: none; field-sizing: content; }

/* File input hidden; the styled <label for> opens the native dialog. */
.yohb-file-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    overflow: hidden;
    pointer-events: none;
}

.yohb-edit-pencil-btn,
.yohb-follow-btn {
    border-radius: var(--gp-card-border-radius, 12px);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    cursor: pointer;
    text-transform: uppercase;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.yohb-edit-pencil-btn {
    border: 1.5px solid var(--gp-blue);
    background: transparent;
    color: var(--gp-blue);
    padding: 2px 9px;
}
.yohb-edit-pencil-btn .material-symbols-outlined { font-size: 16px; }
/* Reversed states: the default "Follow" label is the OUTLINED variant
   (transparent + blue text/border), and the "Following" label is the
   FILLED variant (solid blue + black text). The follow state is the
   call-to-action; the following state is the confirmation. */
.yohb-follow-btn {
  background: transparent;
  border: 1.5px solid var(--gp-blue);
  color: var(--gp-blue);
  padding: 2px 9px;
}
.yohb-follow-btn.following {
    background: var(--gp-blue);
    color: #000000;
}
/* Confirm-modal-Cancel look (blue outline, dark bg, white text) for secondary
   pill actions (e.g. the review sheet's Deny). */
.yohb-follow-btn.cancel { color: #FFFFFF; }
/* Destructive filled pill (e.g. the review sheet's Ban). */
.yohb-follow-btn.danger {
    background: var(--gp-error);
    border-color: var(--gp-error);
    color: #FFFFFF;
}

.yohb-display-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 20px;
    color: #FFFFFF;
    line-height: 1.1;
    margin-bottom: 2px;
}
.yohb-username-line {
    color: #888888;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 500;
}
.yohb-username-line .dot { color: #555555; margin: 0 4px; }

.yohb-bio-block { padding: 8px 0; }
.yohb-bio-text {
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-size: 13.5px;
    line-height: 1.45;
    white-space: pre-wrap;
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
.yohb-bio-toggle {
    display: inline-block;
    color: var(--gp-blue);
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 500;
    cursor: pointer;
    margin-top: 4px;
}

/* Member-since pill now lives in the .yohb-ph-top flex row (right side,
   balancing the avatar/name). .yohb-ph-text (flex:1) pushes it right; it
   must not shrink. */
.yohb-ph-meta { flex-shrink: 0; }
.yohb-meta-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 5px 10px;
    background: rgba(41, 171, 226, 0.08);
    border: 0.5px solid rgba(41, 171, 226, 0.25);
    border-radius: 6px;
    color: #888888;
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    font-weight: 500;
}
.yohb-meta-pill .material-symbols-outlined { font-size: 13px; color: var(--gp-blue); }

/* Stats as inline text under a divider (Option B). Each stat stays tappable
   (opens its modal route); hover turns blue. */
.yohb-stats-inline {
    border-top: 0.5px solid #1C1C1C;
    padding-top: 12px;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 500;
    color: #888888;
}
.yohb-stat-inline {
    background: none;
    border: 0;
    padding: 0;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.yohb-stat-inline strong {
    color: #FFFFFF;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    margin-right: 4px;
}
/* Whole stat is clickable, but only the word (not the number) recolors on
   hover — strong keeps its explicit #FFFFFF so it doesn't inherit the blue. */
.yohb-stat-inline:hover { color: var(--gp-blue); }

.yohb-tab-bar {
    display: flex;
    background: #000000;
    border-bottom: 0.5px solid #1C1C1C;
    position: sticky;
    /* Pins directly beneath the global header + hero + stats bar. */
    top: calc(var(--gp-header-height) + var(--yohb-hero-h) + var(--yohb-stats-h));
    z-index: 5;
}
.yohb-tab {
    flex: 1;
    text-align: center;
    padding: 14px 4px;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 12px;
    color: #888888;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
}
.yohb-tab.active { color: #FFFFFF; border-bottom-color: var(--gp-blue); }
.yohb-tab-content { padding: 14px 16px 20px; min-height: 100px; }

.yohb-section-title-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}
.yohb-section-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 1.5px;
    color: #888888;
    text-transform: uppercase;
    margin-bottom: 10px;
    padding-top: 4px;
}
.yohb-section-title:not(:first-child) { margin-top: 18px; }

/* Per-tab Add button row (uses the shared .add-post-button pill style). */
.yohb-tab-add { display: flex; justify-content: flex-end; margin-bottom: 12px; }

/* ============================================================
   V2 PHOTO-FORWARD EVENT / CLUB CARDS
   ============================================================ */
.v2-card {
    background: #0A0A0A;
    border: 0.5px solid #1C1C1C;
    border-radius: 12px;
    overflow: hidden;
    margin-bottom: 12px;
    cursor: pointer;
}
.v2-cover {
    height: 130px;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #2a2a2a;
    background-size: cover;
    background-position: center;
}
.v2-cover-event {
    background:
        radial-gradient(ellipse at 25% 30%, rgba(41, 171, 226, 0.25) 0%, transparent 60%),
        radial-gradient(ellipse at 75% 70%, rgba(255, 179, 0, 0.15) 0%, transparent 55%),
        linear-gradient(135deg, #1a1a1a 0%, #0a0a0a 100%);
}
.v2-cover-club {
    background:
        radial-gradient(circle at center, rgba(41, 171, 226, 0.2) 0%, rgba(10, 10, 10, 1) 65%),
        linear-gradient(135deg, #0a1a2a 0%, #000 100%);
}
.v2-cover .material-symbols-outlined { font-size: 48px; }
.v2-cover-img { position: absolute; inset: 0; background-size: cover; background-position: center; }
.v2-date-overlay {
    position: absolute;
    bottom: 10px;
    left: 12px;
    background: rgba(0, 0, 0, 0.7);
    backdrop-filter: blur(4px);
    border-radius: 6px;
    padding: 5px 9px;
    display: flex;
    align-items: center;
    gap: 5px;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
}
.v2-date-overlay .material-symbols-outlined { font-size: 12px; color: var(--gp-blue); }
.v2-club-emblem {
    width: 78px;
    height: 78px;
    border-radius: 50%;
    background: rgba(41, 171, 226, 0.15);
    border: 2px solid rgba(41, 171, 226, 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gp-blue);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 22px;
    letter-spacing: 1.5px;
    overflow: hidden;
}
.v2-club-emblem img { width: 100%; height: 100%; object-fit: cover; }
.v2-body { padding: 12px 14px 14px; }
.v2-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 16px;
    color: #FFFFFF;
    line-height: 1.2;
    margin-bottom: 4px;
}
.v2-meta-line {
    display: flex;
    align-items: center;
    gap: 4px;
    font-family: 'DM Sans', sans-serif;
    font-size: 11.5px;
    font-weight: 500;
    color: #888888;
}
.v2-meta-line .material-symbols-outlined { font-size: 12px; }

/* ============================================================
   ACCOLADES MODAL GRID
   ============================================================ */
.yohb-accolade-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.yohb-accolade-card {
    background: #0A0A0A;
    border: 0.5px solid #1C1C1C;
    border-radius: 12px;
    padding: 12px 8px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    min-height: 110px;
}
.yohb-accolade-icon {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: rgba(41, 171, 226, 0.12);
    border: 1px solid rgba(41, 171, 226, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gp-blue);
    margin-bottom: 6px;
    overflow: hidden;
}
.yohb-accolade-icon .material-symbols-outlined { font-size: 26px; }
.yohb-accolade-icon img { width: 100%; height: 100%; object-fit: cover; }
.yohb-accolade-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: #FFFFFF;
    letter-spacing: 0.3px;
    margin-bottom: 2px;
    line-height: 1.15;
}
.yohb-accolade-sub {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
    color: #555555;
    line-height: 1.2;
}

/* Avatar opens full-screen on click (profile header). */
.yohb-avatar-clickable { cursor: pointer; }

/* Social Media modal cards */
.yohb-social-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 0.5px solid #1C1C1C;
    text-decoration: none;
    cursor: pointer;
}
.yohb-social-card:last-child { border-bottom: none; }
.yohb-social-icon {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.04);
    border: 0.5px solid #1C1C1C;
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    overflow: hidden;
}
.yohb-social-icon img { width: 22px; height: 22px; object-fit: contain; }
.yohb-social-icon .material-symbols-outlined { font-size: 20px; color: var(--gp-blue); }
.yohb-social-text { flex: 1; min-width: 0; }
.yohb-social-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 14px;
    color: #FFFFFF;
    line-height: 1.2;
}
.yohb-social-handle {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 12px;
    color: #888888;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
a.yohb-social-card:hover .yohb-social-name { color: var(--gp-blue); }
.yohb-social-card-static { cursor: default; }
.yohb-social-chevron { color: #555555; font-size: 20px; flex: 0 0 auto; }

/* ======================================================================
   Spinner: when it is the topmost element of a page/component, separate it
   from both the top and bottom edges (do not let it sit flush against
   either — looks cramped against an empty-list panel below).
   ====================================================================== */
.yohb-spinner-top { margin-top: 10px; margin-bottom: 10px; }

/* PageHero RightAction CardMenu icon should read as white on the dark hero
   background — the default .card-menu-icon inherits a darker color from its
   ambient context (post/card surfaces). Scope to .page-hero-right-action so
   only the hero variant is affected; cards keep their existing color. */
.page-hero-right-action .card-menu-icon { color: #fff; }

/* ======================================================================
   Unified entity card (vehicle + garage share one structure) — see
   ClaudeStaging/yohb_vehicles_v2.html. Cover photo on top, owner identity
   row below, action row at bottom. Used by VehicleCard / GarageCard.
   ====================================================================== */
/* Shared base surface for EVERY card (entity cards + feed PostCard) — one
   background / border / radius so all cards stay visually consistent. Layout
   (padding, margin, overflow) stays per-card below. */
.ent-card, .post-card-new {
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    cursor: pointer;
}
.ent-card {
    overflow: hidden;
    margin-bottom: 12px;
}

/* Single knob for ALL card media shape: the .gp-card-media class + the
   --gp-card-media-aspect var (app.css). The container grows in BOTH dimensions
   on resize (no fixed height); the image stays centered & cover-cropped. */
.gp-card-media {
    aspect-ratio: var(--gp-card-media-aspect);
    height: auto;
}
.ent-cover {
    position: relative;
    background:
        radial-gradient(ellipse at 30% 35%, rgba(41, 171, 226, 0.18) 0%, transparent 60%),
        radial-gradient(ellipse at 80% 70%, rgba(255, 255, 255, 0.06) 0%, transparent 55%),
        linear-gradient(135deg, #1a1a1a 0%, #0a0a0a 100%);
    display: flex;
    align-items: center;
    justify-content: center;
    color: #2a2a2a;
}
.ent-cover .material-symbols-outlined { font-size: 64px; }
.ent-cover-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* GarageCard cover carousel — one slide per vehicle (its first image). */
.ent-cover-carousel,
.ent-cover-carousel .carousel-inner,
.ent-cover-carousel .carousel-item {
    width: 100%;
    height: 100%;
}
.ent-cover-carousel .carousel-item .ent-cover-img {
    position: static;
    height: 100%;
}
/* Per-image Year Make Model tag (bottom-left). Styled identically to the
   .cover-tag (vehicle-count) chip, just positioned bottom-left. Shown only
   when Description is set. */
.cover-ymm {
    position: absolute;
    bottom: 10px;
    left: 10px;
    background: rgba(0, 0, 0, 0.75);
    border: 0.5px solid rgba(41, 171, 226, 0.4);
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 10px;
    padding: 3px 8px;
    border-radius: 4px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

/* Positioning context for the shared image-tag (.cover-ymm) when reused on
   the PostCard carousel slide and the Vehicle-detail photo thumbs. */
.card-carousel-slide { position: relative; }

/* Cover top-right overlay: vehicle Category tag / garage "N vehicles" tag */
.cover-tag {
    position: absolute;
    top: 10px;
    right: 10px;
    background: rgba(0, 0, 0, 0.75);
    border: 0.5px solid rgba(41, 171, 226, 0.4);
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 10px;
    padding: 3px 8px;
    border-radius: 4px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
}

/* Cover bottom-left overlay: owner location */
.cover-location {
    position: absolute;
    bottom: 10px;
    left: 12px;
    background: rgba(0, 0, 0, 0.75);
    border: 0.5px solid rgba(41, 171, 226, 0.4);
    backdrop-filter: blur(4px);
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 11px;
    padding: 4px 9px;
    border-radius: 6px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.cover-location .material-symbols-outlined { font-size: 12px; color: var(--gp-blue); }

.ent-body {
    padding: 12px 14px;
    display: flex;
    align-items: center;
    gap: 12px;
}
.ent-avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 14px;
    color: var(--gp-blue);
    flex-shrink: 0;
    overflow: hidden;
}
.ent-avatar img { width: 100%; height: 100%; object-fit: cover; }
.ent-id { flex: 1; min-width: 0; }
.ent-primary {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: #FFFFFF;
    line-height: 1.15;
    margin-bottom: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
.ent-primary:hover { color: var(--gp-blue); }
.ent-secondary {
    font-family: 'DM Sans', sans-serif;
    font-size: 11.5px;
    font-weight: 500;
    color: var(--gp-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: pointer;
}
.ent-secondary:hover { color: var(--gp-blue); }
.ent-secondary .dot { color: var(--gp-muted-deep); margin: 0 4px; }
.ent-chevron { color: var(--gp-muted-deep); font-size: 22px; flex-shrink: 0; }

/* Inline action cluster pinned to the right of .ent-body — replaces the
   prior chevron + separate .ent-actions row. Mirrors the View mode's
   .veh-detail-row-actions cell. */
.ent-body-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 0 0 auto;
    margin-left: auto;
}

.ent-actions {
    position: relative;
    padding: 10px 14px;
    display: flex;
    align-items: center;
    gap: 22px;
}
/* Divider mimics PostCard — inset, does not span the full card width. */
.ent-actions::before {
    content: "";
    position: absolute;
    top: 0;
    left: 14px;
    right: 14px;
    border-top: 0.5px solid var(--gp-card-border);
}
.ent-action {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    color: var(--gp-muted);
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 12px;
    cursor: pointer;
    user-select: none;
}
.ent-action .material-symbols-outlined { font-size: 19px; }
.ent-action .count {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    color: #FFFFFF;
    font-size: 13px;
}
/* Favorited (star) — filled, brand blue */
.ent-action.favorited { color: var(--gp-blue); }
.ent-action.favorited .material-symbols-outlined { font-variation-settings: 'FILL' 1; }
/* Follow toggle (person_check) — reversed from the legacy treatment.
   "follow" (not yet following) is the call-to-action visual: filled blue
   icon + blue text/count. "following" (settled state) keeps the text and
   count muted but tints the icon blue so the active state still reads at
   a glance — the icon alone signals "you're following this profile".
   GarageCard markup emits exactly one of the two classes per row via
   CurrentUserIsFollowing. */
/* GarageCard follow toggle. White when NOT following (CTA invites the
   tap), blue when following (settled, mirrors the like/active pattern
   used elsewhere). Icon stays filled in both states for legibility. */
.ent-action.follow { color: #FFFFFF; }
.ent-action.follow .material-symbols-outlined { color: #FFFFFF; font-variation-settings: 'FILL' 1; }
.ent-action.following { color: var(--gp-blue); }
.ent-action.following .material-symbols-outlined { color: var(--gp-blue); font-variation-settings: 'FILL' 1; }
/* Owner's own card: count shown, not actionable */
.ent-action-readonly { cursor: default; }
.ent-action-spacer { flex: 1; }

/* ======================================================================
   Vehicles page (/Vehicles): filter button + expandable Make/Model panel.
   Tab bar / empty state reuse the shared .yohb-tab* / .yohb-empty rules.
   ====================================================================== */
/* Sticky chrome (mimics the Profile .yohb-sticky-chrome). The tab bar,
   active-filters bar and filter panel share ONE sticky wrapper pinned under
   the hero; the inner bars are static and stack naturally. This replaced the
   old per-element `top: calc(... + --yohb-tab-h)` approach — the 46px
   estimate was a few px short of the real tab-bar height, so the
   active-filters bar tucked up under the tabs before sticking. */
.yohb-vehicles,
.yohb-clubs {
    width: 100%;
    --yohb-hero-h: 60px;
    --yohb-stats-h: 0px;
}

/* Entity detail chrome (ClubDetails / EventDetails): the hero-data-card + tab bar
   pin below the global header + page hero while the cover image scrolls away —
   the entity identity stays visible on both tabs (profile .yohb-pb-id pattern). */
.yohb-entity-chrome {
    position: sticky;
    top: calc(var(--gp-header-height) + var(--yohb-hero-h));
    z-index: 95;
    background: #000000;
}
/* The data card loses its post-cover top offset inside the chrome, and the base
   sticky .yohb-tab-bar must NOT double-stick within it. */
.yohb-entity-chrome .yohb-hero-data-card { margin-top: 0; }
.yohb-entity-chrome .yohb-tab-bar { position: static; top: auto; }

/* Manage tab refresh: a translucent overlay + centered spinner shown while a
   tab's data reloads, so the content stays mounted (window scroll is preserved)
   instead of being torn down for a full-page spinner. Sits below the global
   header/hero and blocks interaction until the reload lands. */
.yohb-manage-overlay {
    position: fixed;
    inset: calc(var(--gp-header-height) + var(--yohb-hero-h)) 0 0 0;
    background: rgba(0, 0, 0, 0.4);
    display: flex;
    align-items: center;
    justify-content: center;
    z-index: 20;
}
/* .main is a flex column (min-height:100vh via .page). Make the Clubs wrapper
   the growing item so a short page's content fills down to the sticky bottom
   nav — otherwise the footer sits at its flow position with a gap beneath it. */
.yohb-clubs { flex: 1 0 auto; }
.yohb-vehicles .yohb-sticky-chrome,
.yohb-clubs .yohb-sticky-chrome {
    position: sticky;
    top: calc(var(--gp-header-height) + var(--yohb-hero-h) + var(--yohb-stats-h));
    z-index: 5;
    background: #000000;
}
.yohb-vehicles .yohb-sticky-chrome .yohb-tab-bar,
.yohb-vehicles .yohb-sticky-chrome .yohb-active-filters,
.yohb-vehicles .yohb-sticky-chrome .yohb-filter-panel,
.yohb-clubs .yohb-sticky-chrome .yohb-tab-bar {
    position: static;
    top: auto;
    z-index: auto;
}
.yohb-filter-btn {
    position: relative;
    background: none;
    border: none;
    padding: 0;
    color: #FFFFFF;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}
.yohb-filter-btn .material-symbols-outlined { font-size: 22px; }
.yohb-filter-btn.active { color: var(--gp-blue); }
.yohb-filter-dot {
    position: absolute;
    top: -2px;
    right: -2px;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--gp-blue);
}
.yohb-filter-panel {
    padding: 14px 16px;
    border-bottom: 0.5px solid var(--gp-card-border);
    display: flex;
    flex-direction: column;
}

/* Active-filters summary bar — sits directly under the tab bar inside the
   sticky chrome (pinning is owned by .yohb-vehicles .yohb-sticky-chrome). The
   active-filters bar and the filter panel never show at once. Shows the
   applied Make/Model with a Clear-all pill on the far right. */
.yohb-active-filters {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px 16px;
    background: var(--gp-card-bg, #0E0E0E);
    border-bottom: 0.5px solid var(--gp-card-border, #1C1C1C);
}
.yohb-active-filters-text {
    flex: 1 1 auto;
    min-width: 0;
    color: var(--gp-muted, #9A9A9A);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.yohb-active-filters-clear {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: transparent;
    border: 1.5px solid var(--gp-blue);
    color: var(--gp-blue);
    border-radius: var(--gp-card-border-radius, 12px);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 2px 9px;
    cursor: pointer;
}
.yohb-active-filters-clear .material-symbols-outlined { font-size: 16px; }
.yohb-filter-actions {
    display: flex;
    justify-content: flex-end;
    gap: 10px;
}

/* Lighten the placeholder color inside the filter panel inputs so the
   "e.g. Chevrolet" hint reads as a hint, not as actual typed content. */
.yohb-filter-panel .form-control::placeholder {
    /*color: var(--gp-muted-deep, #6E6E6E);*/
    color: #AAAAAA;
    opacity: 1; /* override the Firefox default 0.54 */
}

/* ======================================================================
   Vehicle detail (VehicleCard View mode on /Vehicle/{Id}). Reuses the
   .ent-cover / .ent-actions / .yohb-about-row visual language.
   ====================================================================== */
.yohb-vehicle-detail, .veh-detail { width: 100%; }

/* Single-row header under the cover photo: [owner | YMM+name | actions].
   Owner cell is content-width on the left, title cell takes the middle
   and gets all remaining space (the YMM+Trim line ellipsises when long),
   actions pin to the right at content-width. */
.veh-detail-row {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-bottom: 0.5px solid var(--gp-card-border, #1C1C1C);
}

.veh-detail-row-owner {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 0 0 auto;
    min-width: 0;
    cursor: pointer;
}

.veh-detail-row-title {
    flex: 1 1 auto;
    min-width: 0;
}

.veh-detail-row-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 0 0 auto;
    margin-left: auto;
}

.veh-detail-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 18px;
    color: #FFFFFF;
    line-height: 1.2;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.veh-detail-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 12.5px;
    color: var(--gp-muted);
    margin-top: 2px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.veh-detail-owner { cursor: pointer; }
.veh-detail-section { padding: 12px 14px; }
.veh-detail-text {
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: #CCCCCC;
    line-height: 1.55;
    white-space: pre-wrap;
}
/* Club/Event detail bodies read white (2026-06-12); Vehicle keeps the muted base. */
.yohb-clubs .veh-detail-text { color: #FFFFFF; }

/* ======================================================================
   V2 detail-page hero "data card" (Vehicle / Club / Event) — a full-width
   identity row directly BELOW the .ent-cover carousel. The cover keeps its
   corner tags (.cover-tag top-right / .cover-location bottom-left); the
   title + identity + actions move off the photo into this card. Reuses
   .ent-avatar and .ent-action. See ClaudeStaging/yohb_detail_pages_mockups_v2.html.
   ====================================================================== */
.yohb-hero-data-card {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    background: var(--gp-card-bg);
    border-bottom: 0.5px solid var(--gp-card-border, #1C1C1C);
}
.yohb-hdc-main { flex: 1 1 auto; min-width: 0; }
.yohb-hdc-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 17px;
    color: #FFFFFF;
    line-height: 1.15;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.yohb-hdc-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 11.5px;
    color: var(--gp-muted);
    margin-top: 2px;
    display: flex;
    align-items: center;
    gap: 5px;
    flex-wrap: wrap;
}
.yohb-hdc-sub .material-symbols-outlined { font-size: 13px; color: var(--gp-blue); }
.yohb-hdc-sub .dot { color: var(--gp-muted-deep); }
.yohb-hdc-actions {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: 0 0 auto;
    margin-left: auto;
}
/* The hero-data-card owner avatar taps through to the profile. */
.yohb-hero-data-card .ent-avatar { cursor: pointer; }

/* Vehicle spec card: a 4-column headline grid (Year/Make/Model/Drive) joined
   to the remaining spec rows inside ONE bordered card — replaces the prior
   stacked .yohb-about-row section (no separate, second-bordered kv block). */
.yohb-spec-card {
    margin: 12px 14px;
    border-radius: var(--gp-card-border-radius);
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    overflow: hidden;
}
.yohb-spec-kv {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    padding: 9px 14px;
    border-bottom: 0.5px solid var(--gp-card-border);
}
.yohb-spec-kv:last-child { border-bottom: none; }
.yohb-spec-kv-k { font-family: 'DM Sans', sans-serif; font-size: 12px; color: var(--gp-muted); }
.yohb-spec-kv-v { font-family: 'DM Sans', sans-serif; font-size: 12px; font-weight: 500; color: #FFFFFF; text-align: right; }
/* VIN / license-plate values get the Rajdhani "mono-ish" treatment (mockup .v.mono). */
.yohb-spec-kv-v.mono { font-family: 'Rajdhani', sans-serif; letter-spacing: 0.5px; }

/* Inside the spec card the 4-col metadata band is borderless — it sits as a
   band on top of the kv rows (mockup .spec-card .metadata-row). */
.yohb-spec-card .yohb-metadata-row {
    margin: 0;
    border: none;
    border-radius: 0;
    border-bottom: 0.5px solid var(--gp-card-border);
}

/* Links inside a detail-page text block (e.g. the Event location map link). */
.veh-detail-text a { color: var(--gp-blue); text-decoration: none; }

/* ======================================================================
   V2 detail-page shared building blocks (Vehicle / Club / Event / Profile).
   Ported from ClaudeStaging/yohb_detail_pages_mockups_v2.html so all four
   detail pages share one visual language: the 4-column metadata band, the big
   stat cards, the inline stat row, icon lines and the detail social row.
   ====================================================================== */

/* 4-column centered metadata band. Standalone (Club/Event) it's a bordered
   card; inside .yohb-spec-card (Vehicle) the override above strips the border. */
.yohb-metadata-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    padding: 14px;
    margin: 12px 14px;
    border-radius: var(--gp-card-border-radius);
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
}
/* 3-cell variant — EventDetails hides the Exhibitor cell when the event has no
   exhibitor fee/capacity structure. */
.yohb-metadata-row.cols-3 { grid-template-columns: repeat(3, 1fr); }
.yohb-m-cell {
    text-align: center;
    border-right: 0.5px solid var(--gp-card-border);
    padding: 0 2px;
    min-width: 0;
}
.yohb-m-cell:last-child { border-right: none; }
.yohb-m-label {
    font-family: 'DM Sans', sans-serif;
    font-size: 9px;
    font-weight: 500;
    color: var(--gp-muted-deep);
    letter-spacing: 0.6px;
    text-transform: uppercase;
    margin-bottom: 3px;
}
.yohb-m-value {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 13px;
    line-height: 1.2;
    color: #FFFFFF;
    /* No nowrap (matches the mockup) so long values like "Approval required"
       wrap instead of truncating in the narrow cell. */
}
.yohb-m-value.cyan { color: var(--gp-blue); }

/* Big number stat cards — Club Upcoming Events/Posts, Profile Followers/Following. */
.yohb-stats-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    padding: 4px 14px 6px;
}
.yohb-stat-card {
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    padding: 12px;
    /* Center the number + label on EVERY stat card (Profile, Club details, future). */
    text-align: center;
}
/* Tappable variant (Profile stats) — reset the native button box. */
button.yohb-stat-card {
    display: block;
    width: 100%;
    font: inherit;
    color: inherit;
    cursor: pointer;
}
.yohb-stat-num {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 24px;
    line-height: 1;
    color: #FFFFFF;
}
.yohb-stat-num.cyan { color: var(--gp-blue); }
.yohb-stat-label {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted);
    margin-top: 4px;
}
.yohb-stat-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 10px;
    color: var(--gp-muted-deep);
    margin-top: 2px;
}

/* Inline stat row — Event Registered/Exhibitors. Reuses the .yohb-stat-inline
   item (strong + label) from the profile stats bar, just as a non-sticky row. */
.yohb-stat-inline-row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 18px;
    padding: 8px 16px 12px;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-weight: 500;
    color: var(--gp-muted);
}
.yohb-stat-inline-row .yohb-stat-inline { cursor: default; }
/* Tappable inline stats read as links (the row default above otherwise wins). */
.yohb-stat-inline-row .yohb-stat-inline.yohb-tappable { cursor: pointer; }
.yohb-stat-inline-row .yohb-stat-inline strong { font-size: 16px; }

/* Generic clickable affordance (e.g. Club Members metadata cell + member stack). */
.yohb-tappable { cursor: pointer; }

/* Icon + text line inside a section body (Club Activities, Event Location).
   The whole line can BE the anchor (a.yohb-icon-line — Event Location when a
   map URL exists); hover stays the normal color, no underline. */
.yohb-icon-line { display: flex; align-items: center; gap: 6px; }
.yohb-icon-line .material-symbols-outlined { font-size: 16px; color: var(--gp-blue); }
.yohb-icon-line a { color: var(--gp-blue); text-decoration: none; }
a.yohb-icon-line { color: var(--gp-blue); text-decoration: none; }
a.yohb-icon-line:hover, a.yohb-icon-line:visited, .yohb-icon-line a:hover { color: var(--gp-blue); }

/* The legacy .social-icon (app.css) uses background-size: cover, which crops
   non-square brand SVGs (e.g. the wide YouTube/X logos) inside its square box.
   Override to contain so the whole logo fits centered and is never cut off
   (identical to cover for the square logos). Applies everywhere .social-icon is
   used: profile socials, the event detail row below, legacy garage links. */
.social-icon { background-size: contain; }

/* Detail-page social row (Event) — reuses the legacy .social-icon brand SVGs. */
.yohb-detail-social-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 0;
    border-bottom: 0.5px solid var(--gp-card-border);
    font-family: 'DM Sans', sans-serif;
    font-size: 12.5px;
    color: #FFFFFF;
    text-decoration: none;
}
.yohb-detail-social-row:last-child { border-bottom: none; }
.yohb-detail-social-row .social-icon { width: 18px; height: 18px; }
.yohb-detail-social-row .material-symbols-outlined { font-size: 18px; color: var(--gp-blue); }
.yohb-detail-social-handle { margin-left: auto; color: var(--gp-muted); font-size: 12px; }

/* Icons-only social row (SocialIconRow — Club + Event detail "Social" section).
   30px circles matching .yohb-member-stack-avatar. */
.yohb-social-icon-row {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 0;
}

/* Bare full-bleed brand logos — no border, no background, no padding
   (2026-06-12; the bordered 15px-glyph look was retired). */
.yohb-social-icon-circle {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;
}

.yohb-social-icon-circle .social-icon { width: 30px; height: 30px; }
.yohb-social-icon-circle .material-symbols-outlined { font-size: 16px; color: var(--gp-blue); }

/* Route-driven confirm modal (ConfirmModal — VehicleCard / GarageCard).
   Centered dialog look (like the legacy ConfirmationDialog), NOT a slide-up.
   Above the bottom-sheet backdrop (z 1500) so it can open from inside a sheet. */
.yohb-confirm-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 1600;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.yohb-confirm-card {
    width: 100%;
    max-width: 400px;
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    padding: 18px 20px 16px;
    box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
}
.yohb-confirm-heading {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 18px;
    color: #FFFFFF;
    margin-bottom: 12px;
}
.yohb-confirm-card .confirmation-dialog-body {
    align-items: flex-start;
    gap: 8px;
}
.yohb-confirm-icon { font-size: 22px; color: var(--gp-blue); flex: 0 0 auto; }
.yohb-confirm-card .confirmation-dialog-body-content {
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    color: #FFFFFF;
    line-height: 1.5;
    /* Inherits display:flex from the legacy rule (which defaults to row and laid
       the data-sharing gate's stacked paragraphs/list out horizontally). Stack
       them. */
    flex-direction: column;
    gap: 8px;
}
.yohb-confirm-card .confirmation-dialog-body-buttons { padding-top: 18px; display: flex; gap: 10px; }
/* Shared confirm-modal buttons: confirm filled (brand, or red when .danger),
   cancel de-emphasized as an outline. */
.yohb-confirm-card .confirmation-dialog-body-buttons .btn {
    flex: 1;
    height: 42px;
    border-radius: var(--gp-card-border-radius);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    border: 1.5px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--gp-blue);
    color: #001821;
}
.yohb-confirm-card.danger .confirmation-dialog-body-buttons .btn {
    background: var(--gp-error);
    color: #FFFFFF;
}
/* Club data-sharing gate — the required-fields list inside the confirm card. */
.club-share-fields {
    margin: 8px 0;
    padding-left: 20px;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
}
.club-share-fields li { margin: 2px 0; }

/* Cancel button: transparent fill, white text, brand-blue outline — on BOTH
   normal and danger dialogs. !important is required because the base `.btn` and
   the higher-specificity `.danger .btn` rules (plus legacy `.btn`/`.btn-secondary`
   rules in app.css) otherwise win and paint it filled. */
.yohb-confirm-card .confirmation-dialog-body-buttons .btn-secondary,
.yohb-confirm-card.danger .confirmation-dialog-body-buttons .btn-secondary {
    background: transparent !important;
    border-color: var(--gp-blue) !important;
    color: #FFFFFF !important;
}

/* ------------------------------------------------------------------
   ImageViewer (route-driven full-screen image overlay)
   ------------------------------------------------------------------ */

.yohb-image-viewer {
    position: fixed;
    inset: 0;
    z-index: 2000;
    background: rgba(0, 0, 0, 0.95);
    display: flex;
    align-items: center;
    justify-content: center;
}

.yohb-image-viewer-close {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2001;
    background: transparent;
    border: 0;
    color: #FFFFFF;
    cursor: pointer;
    padding: 8px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
}

.yohb-image-viewer-close .material-symbols-outlined {
    font-size: 32px;
}

/* Stage wrapper for the embedded YohbCarousel (Fullscreen mode). Sized to
   the full overlay; carousel fills it. stopPropagation lives on the wrapper
   so backdrop taps OUTSIDE the carousel still close the viewer. */
.yohb-image-viewer-stage {
    width: 100%;
    height: 100%;
}

/* ------------------------------------------------------------------
   Notifications (bell panel)
   ------------------------------------------------------------------ */

.yohb-notification-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.0);
    z-index: 1500;
}

/* Panel right-edge anchors to the .page (700px max-width) right-edge with
   12px breathing room on wide screens; on narrow screens it stays 12px from
   the viewport. Math: at viewport=700px the .page edge is at the viewport
   edge, so right=12px. Wider viewports center .page, leaving (vw - 700)/2
   of empty space on each side — add 12px so the panel sits just inside the
   .page right edge. (350px = 700/2; 338px = 350 - 12 gap.) */
.yohb-notification-panel {
    position: fixed;
    top: 64px;
    right: max(12px, calc(50vw - 338px));
    width: min(420px, calc(100vw - 24px));
    max-height: calc(100vh - 80px);
    z-index: 1600;
    background: var(--gp-card-bg);
    border: 1px solid var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    font-family: 'DM Sans', sans-serif;
    color: #FFFFFF;
}

.yohb-notification-panel-header {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 12px 14px;
    border-bottom: 1px solid var(--gp-card-border);
}

.yohb-notification-panel-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 1px;
    text-transform: uppercase;
    flex: 1;
}

.yohb-notification-mark-all {
    background: transparent;
    border: 0;
    color: var(--gp-blue);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 11px;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
    padding: 4px 6px;
}

.yohb-notification-close {
    background: transparent;
    border: 0;
    color: var(--gp-muted, #FFFFFF);
    cursor: pointer;
    padding: 0;
    display: inline-flex;
    align-items: center;
}

.yohb-notification-close .material-symbols-outlined {
    font-size: 20px;
}

.yohb-notification-list {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
}

/* 4-cell row: [target-left (dot)] [avatar-zone (tinted)] [body
   (name+handle+time on top, action below)] [dismiss]. The dot column is
   ALWAYS present in the DOM (visually empty when read) so reading a
   notification doesn't collapse columns and break the row layout. Only the
   avatar is its own click target — the rest of the row (body) routes to
   the notification target along with the dot column. */
.yohb-notif {
    display: grid;
    grid-template-columns: 28px auto 1fr auto;
    align-items: stretch;
    border-bottom: 1px solid var(--gp-card-border);
    background: transparent;
    transition: background 120ms ease;
}

.yohb-notif:last-child { border-bottom: 0; }

.yohb-notif.unread { background: rgba(41, 171, 226, 0.06); }
.yohb-notif:hover { background: rgba(255, 255, 255, 0.03); }
.yohb-notif.unread:hover { background: rgba(41, 171, 226, 0.09); }

/* Target zone (left) — clickable; renders the dot when unread. */
.yohb-notif-target-left {
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    align-self: stretch;
}

.yohb-notif-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--gp-blue);
}

/* Avatar zone — its own click target (source profile). Tinted background
   makes it read as a separate button on mobile; intentionally NO 1px
   separator line — the tinted column is the divider. */
.yohb-notif-avatar-zone {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 10px 12px;
    cursor: pointer;
    align-self: stretch;
    background: rgba(41, 171, 226, .2);
    transition: background 120ms ease;
}

  .yohb-notif-avatar-zone:hover {
    background: rgba(255, 255, 255, 0.08);
    background: rgba(41, 171, 226, .25);
  }

/* Notification avatar matches the PostCard/header avatar treatment: dark
   surface, blue ring, blue initials. */
.yohb-notif-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    box-sizing: border-box;
    overflow: hidden;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    color: var(--gp-blue);
    flex-shrink: 0;
}

.yohb-notif-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.yohb-notif-initials {
    font-size: 14px;
    letter-spacing: 1px;
}

/* Club/Event entity-avatar glyph fallback (when the club/event has no image). */
.yohb-notif-avatar .material-symbols-outlined {
    font-size: 22px;
}

/* Body — name + handle + time on top, action below. Clickable as a single
   target along with the dot column; for System/General, click marks read
   but does not navigate. */
.yohb-notif-body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 2px;
    padding: 10px 12px;
    cursor: pointer;
    min-width: 0;
}

.yohb-notif-row {
    display: flex;
    align-items: baseline;
    gap: 6px;
    flex-wrap: wrap;
}

.yohb-notif-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    font-size: 14px;
    color: #FFFFFF;
}

.yohb-notif-handle {
    font-size: 12px;
    color: var(--gp-muted, #B8C0CC);
}

.yohb-notif-time {
    font-size: 11px;
    color: var(--gp-muted-deep, #8A93A1);
    margin-left: auto;
}

.yohb-notif-action {
    font-size: 13px;
    color: var(--gp-muted, #B8C0CC);
    line-height: 1.35;
    word-wrap: break-word;
}

.yohb-notif-dismiss {
    background: transparent;
    border: 0;
    color: var(--gp-muted-deep, #8A93A1);
    cursor: pointer;
    padding: 10px 12px;
    display: inline-flex;
    align-items: center;
    align-self: stretch;
}

.yohb-notif-dismiss .material-symbols-outlined {
    font-size: 18px;
}

.yohb-notif-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    padding: 40px 20px;
    color: var(--gp-muted-deep, #8A93A1);
    font-size: 13px;
    text-align: center;
    /* Empty-state copy + icon aren't interactive content — don't let the
       user select them on tap. */
    user-select: none;
    -webkit-user-select: none;
}

.yohb-notif-empty .material-symbols-outlined {
    font-size: 36px;
}

/* Material Symbols glyphs are decorative — selecting them on tap would
   yield literal text like "directions_car". Globally non-selectable so
   default-icon placeholders on cards (.ent-cover when there's no image,
   .ent-actions row icons, etc.) can't be accidentally picked up. */
.material-symbols-outlined {
    user-select: none;
    -webkit-user-select: none;
}

/* Card avatar fallback — when there's no profile image, .ent-avatar
   renders initials text. Treat that placeholder the same as a glyph
   icon (don't select on tap). */
.ent-avatar {
    user-select: none;
    -webkit-user-select: none;
}

/* Generic empty-state copy (".yohb-empty" rendered in .veh-detail,
   Profile tabs, Vehicles list, etc.) is informational text, not
   interactive content — don't let it select on tap either. */
.yohb-empty {
    user-select: none;
    -webkit-user-select: none;
}

/* One-line image-limit hint shown above multi-image pickers (Post,
   Vehicle legacy, Club, Event). The marketing-styled forms use
   .profile-field-hint instead — this one is for legacy components
   that don't have the marketing-auth chrome around them. */
/* In-app fallback for .profile-field-hint (ClubApply, ClubManage sheets…) — the
   styled rule is scoped under .yohb-landing .marketing-auth, and FluentUI's
   reboot.css bare-p rule would otherwise re-font these to Segoe. The marketing
   rule's higher specificity still wins on marketing pages. */
.profile-field-hint {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-muted, #8A93A1);
    margin: 4px 0 0;
}

.yohb-photo-hint {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-muted, #8A93A1);
    margin: 6px 0 8px;
}

/* Centers the × icon inside .preview-image-close-button vertically AND
   horizontally — the legacy app.css rule sets `display: block` on the
   button so the inner span sits at the top-left corner. Override here
   instead of editing app.css. Used by the AddVehicle wizard photo
   previews, VehicleComponentV2, Post/Club/Event picker previews, etc. */
.preview-image-close-button {
    display: inline-flex !important;
    align-items: center;
    justify-content: center;
    border: 0;
    padding: 0;
    border-radius: 50%;
    color: #ffffff;
}

.preview-image-close-button .material-symbols-outlined {
    font-size: 20px;
    line-height: 1;
}

/* Prominent "Select photos" picker — bigger affordance than the legacy
   .profile-link-btn link-styled label. display:flex (block-level flex) so
   the picker spans the form width and centers the icon + text together;
   the inner span line-height:1 keeps them on the same baseline. Used on
   the AddVehicle wizard step 4, VehicleComponentV2 edit form, and any
   future picker — including the Step 1 "Scan VIN from a photo" button. */
.yohb-photo-picker {
    display: flex !important;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 12px 20px;
    border: 1.5px solid var(--gp-blue);
    background: rgba(41, 171, 226, 0.08);
    color: var(--gp-blue);
    border-radius: var(--gp-card-border-radius);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 14px;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    cursor: pointer;
    line-height: 1;
    transition: background 0.15s ease;
}

.yohb-photo-picker:hover,
.yohb-photo-picker:focus-within {
    background: rgba(41, 171, 226, 0.16);
}

.yohb-photo-picker .material-symbols-outlined {
    font-size: 20px;
    line-height: 1;
}

.yohb-photo-picker .yohb-photo-picker-text {
    line-height: 1;
}

/* AddVehicle step 1 VIN buttons row. Stacks the Capture + Scan buttons
   vertically with a small gap so each one keeps full width. The MAUI
   button is a <button>; the Web variants are <label for=...><InputFile>
   wrappers — both get the same .yohb-photo-picker treatment. */
.yohb-vin-buttons {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.yohb-vin-buttons .yohb-photo-picker {
    width: 100%;
}

/* Native <button> defaults (font, line-height) can drift from <label>'s.
   Restate so the two variants align identically. */
button.yohb-photo-picker {
    font-family: 'Rajdhani', sans-serif;
    font-size: 14px;
    line-height: 1;
}

/* ------------------------------------------------------------------
   Event detail: schedule day groups, fee rows, the ticket sheet, and the
   "My ticket" inline stat glyph.
   ------------------------------------------------------------------ */
.yohb-schedule-day {
    display: flex;
    gap: 16px;
    align-items: flex-start;
    margin-bottom: 6px;
}

.yohb-schedule-date {
    min-width: 84px;
    font-weight: 700;
    color: var(--gp-blue);
}

.yohb-schedule-times { flex: 1; }

/* Start / dash / end in fixed right-aligned columns with tabular numerals so
   every row lines up vertically across days. */
.yohb-schedule-time {
    display: grid;
    /* End column is 60px (vs 72px start) so the end time hugs the dash —
       60px still fits the longest time ("12:00 PM"). */
    grid-template-columns: 72px 12px 60px;
    column-gap: 4px;
    font-variant-numeric: tabular-nums;
    color: var(--gp-blue);
}

.yohb-schedule-time .yohb-schedule-start,
.yohb-schedule-time .yohb-schedule-end { text-align: right; }

.yohb-schedule-time .yohb-schedule-dash { text-align: center; }

.yohb-fee-row {
    display: flex;
    justify-content: space-between;
    margin-bottom: 4px;
}

.yohb-stat-inline .material-symbols-outlined {
    font-size: 16px;
    vertical-align: -3px;
}

.yohb-ticket-sheet {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    padding: 16px 0 24px;
    text-align: center;
}

.yohb-ticket-qr {
    width: min(70vw, 280px);
    height: auto;
    border-radius: var(--gp-card-border-radius);
}

.yohb-ticket-token {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    letter-spacing: 2px;
    font-size: 18px;
}

.yohb-ticket-meta { color: var(--gp-muted); }

/* EventManage gate check-in launch button row + the check-in person card. */
.yohb-manage-checkin { padding: 10px 14px 0; }
.yohb-checkin-person { margin-bottom: 4px; }

/* Review-registration sheet: full vehicle cards under the shared info. */
.yohb-review-vehicles { display: flex; flex-direction: column; gap: 12px; margin: 8px 0 12px; }

/* Clickable UserRow indicator icon (e.g. exhibitor car → the vehicle page).
   Bare-button reset so it renders exactly like the plain icon span. */
.yohb-userrow-icon-btn { background: none; border: none; padding: 0; margin: 0; display: flex; align-items: center; cursor: pointer; }

/* Text input with an inline clear (×) button on the right. Used on the
   AddVehicle wizard's VIN field. The input keeps right-padding so the typed
   text doesn't run under the ×. The button is only rendered when the input
   has a value (the markup gates on this), so no need for hover-only fade. */
.yohb-input-with-clear {
    position: relative;
    width: 100%;
}

.yohb-input-with-clear .form-control {
    padding-right: 36px;
}

.yohb-input-with-clear .yohb-input-clear {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    background: transparent;
    border: 0;
    padding: 4px;
    color: var(--marketing-text-muted, #888888);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    line-height: 1;
}

.yohb-input-with-clear .yohb-input-clear:hover,
.yohb-input-with-clear .yohb-input-clear:focus {
    color: var(--gp-blue);
    background: rgba(41, 171, 226, 0.10);
    outline: none;
}

.yohb-input-with-clear .yohb-input-clear .material-symbols-outlined {
    font-size: 18px;
}

/* ============================================================
   FluentCombobox — used on the AddVehicle wizard step 2 and the
   VehicleComponentV2 edit form. The host <fluent-combobox> exposes its
   internal styling via CSS custom properties (and ::part(control) /
   ::part(listbox)). Force black backgrounds across all interaction
   states so the combobox blends with the marketing-auth card.
   ============================================================ */
fluent-combobox {
    /* Custom-property overrides documented in the Fluent UI design tokens
       — these reach inside the shadow DOM. */
    --neutral-fill-input-rest: #000000;
    --neutral-fill-input-hover: #000000;
    --neutral-fill-input-active: #000000;
    --neutral-fill-input-focus: #000000;
    --neutral-fill-rest: #000000;
    --neutral-fill-hover: #000000;
    --neutral-fill-active: #000000;
    --neutral-fill-focus: #000000;
    --neutral-fill-stealth-rest: #000000;
    --neutral-fill-stealth-hover: #000000;
    --neutral-fill-stealth-active: #000000;
    --neutral-fill-stealth-focus: #000000;
    --neutral-layer-floating: #000000;
    --neutral-layer-1: #000000;
    --neutral-foreground-rest: #ffffff;
    background: transparent;
}

/* Sledgehammer: any `.control` / `.selected-value` / inner input under a
   FluentCombobox host gets a black background and white text. Reaches
   into the shadow DOM via ::part where exposed and into light-DOM
   children otherwise. Border removed — the combobox sits inside the
   marketing-auth card which already provides surface contrast; the form
   row also keeps the standard 1px .form-control border via the host. */
fluent-combobox::part(control) {
    background: #000000;
    color: #ffffff;
    border: 0;
    box-shadow: none;
}

fluent-combobox::part(listbox) {
    background: #000000;
    border-color: var(--marketing-card-border, #1C1C1C);
}

fluent-option {
    background: #000000;
    color: #ffffff;
}

fluent-option:hover,
fluent-option[aria-selected="true"] {
    background: rgba(41, 171, 226, 0.12);
    color: var(--gp-blue);
}

/* If the host renders a light-DOM wrapper `.control` (older Fluent UI
   builds) the rule above still covers it via the bare selector — the
   shadow-DOM ::part target is the canonical one for current versions. */
.yohb-landing .marketing-auth fluent-combobox .control,
.yohb-landing .marketing-auth fluent-combobox input {
    background: #000000 !important;
    background-color: #000000 !important;
    color: #ffffff;
}

/* ============================================================
   YohbCombobox — single combobox style used on the AddVehicle wizard
   and VehicleComponentV2 edit form. Visually matches .form-control
   (the same input shell as plain <select>/<input>) so typeable and
   non-typeable variants sit flush on the same form. AllowFreeText="false"
   adds .is-readonly which hides the text caret; the chevron remains
   the only affordance.
   ============================================================ */
.yohb-combobox {
    position: relative;
    width: 100%;
}

.yohb-combobox .yohb-combobox-input {
    width: 100%;
    box-sizing: border-box;
    padding-right: 36px;
    cursor: pointer;
}

.yohb-combobox.is-readonly .yohb-combobox-input {
    caret-color: transparent;
    user-select: none;
}

.yohb-combobox .yohb-combobox-caret {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--gp-blue);
    pointer-events: auto;
    cursor: pointer;
    font-size: 20px;
    transition: transform 0.15s ease;
}

.yohb-combobox.is-open .yohb-combobox-caret {
    transform: translateY(-50%) rotate(180deg);
}

.yohb-combobox .yohb-combobox-list {
    position: absolute;
    z-index: 50;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    max-height: 260px;
    overflow-y: auto;
    background: var(--marketing-card-bg, #0A0A0A);
    border: 1px solid var(--marketing-card-border, #1C1C1C);
    border-radius: 8px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
    padding: 4px 0;
}

.yohb-combobox .yohb-combobox-option {
    padding: 10px 14px;
    color: var(--marketing-text, #FFFFFF);
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    cursor: pointer;
}

.yohb-combobox .yohb-combobox-option:hover,
.yohb-combobox .yohb-combobox-option.is-highlighted {
    background: rgba(41, 171, 226, 0.12);
    color: var(--gp-blue);
}

.yohb-combobox .yohb-combobox-empty {
    padding: 10px 14px;
    color: var(--marketing-text-muted, #888888);
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    font-style: italic;
}

/* Force the document scroller to INSTANT. Bootstrap/BlazorBootstrap set
   `:root { scroll-behavior: smooth }`, which animates EVERY window-scroll change —
   including the clamp during a SPA content swap (so navigation visibly "scrolls to
   the top") and our restore. With the window-scroll architecture that animation is
   visible (the old inner-scroller pages weren't affected). We manage scroll
   explicitly per-URL and want it instant; explicit smooth scrolls (carousel,
   scrollIntoView) pass behavior:'smooth' and are unaffected by this. !important
   beats Bootstrap's non-important :root rule regardless of specificity. */
html { scroll-behavior: auto !important; }

/* Scroll-restore cover: shown over a lazy page's content while it refetches the
   previously-loaded span and snaps to the saved scroll position, so the user never
   sees content at the top before the jump. Opaque (page bg) so content behind it is
   hidden but still laid out (window.scrollTo needs the height). Sits below the global
   header/footer (z 1000) but above page content. */
.yohb-restore-overlay {
    position: fixed;
    left: 0;
    right: 0;
    top: var(--gp-header-height);
    bottom: 0;
    background: #000000;
    z-index: 50;
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

/* ============================================================
   PostThreadModal — Feed comment-tree modal. Its slide-up SHELL now
   reuses the canonical .yohb-sheet-* classes (backdrop / sheet / header /
   title / close / body) so look + slide-up animation + chrome match every
   other slide-up. The thread-specific parts below (root card, reply tree,
   composer dock) keep their own .yohb-thread-* classes. The body uses
   .yohb-sheet-body directly (no .yohb-sheet-content padding wrapper) so the
   root card + tree sit flush. See memory/slide-up-modals.md.
   ============================================================ */

/* The root PostCard lives at the top of the body — strip any
   bottom margin/border so the comment tree sits flush below. */
.yohb-thread-root > .post-card-new {
    border-radius: 0;
    border-left: 0;
    border-right: 0;
    border-top: 0;
    /* The root post inside the modal isn't clickable — it doesn't
       navigate anywhere (already at the thread it would navigate to).
       Override the shared .ent-card,.post-card-new `cursor: pointer`
       so the visual matches the behavior. PostCards rendered on pages
       (Feed, Profile Posts tab) keep `cursor: pointer` — this scope is
       limited to the modal's root post slot. */
    cursor: default;
}


.yohb-thread-replies {
    padding: 8px 14px 24px;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

/* Reply row: avatar on left, bubble + actions on right. Depth
   classes add left padding so L2 sits under L1 visually. L3+
   is flattened back to L2 indent with a "Replying to @user"
   prefix in the bubble (handled in the markup). No hierarchy
   spine / connector lines — the user dislikes them; indent +
   the explicit Replying-to prefix carry the structure. */
.yohb-thread-reply {
    display: flex;
    align-items: flex-start;
    gap: 8px;
}
.yohb-thread-reply-l1 { padding-left: 0; }
.yohb-thread-reply-l2,
.yohb-thread-reply-flat { padding-left: 40px; }

.yohb-thread-reply-avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 11px;
    color: var(--gp-blue);
    flex: 0 0 auto;
    user-select: none;
}
.yohb-thread-reply-avatar img {
    width: 100%; height: 100%; object-fit: cover;
}
.yohb-thread-reply-avatar { cursor: pointer; }
.yohb-thread-reply-initials { line-height: 1; }

.yohb-thread-reply-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

/* Facebook-style chat bubble around the content. */
.yohb-thread-reply-bubble {
    background: var(--gp-card-bg, #0E0E0E);
    border: 0.5px solid var(--gp-card-border, #1C1C1C);
    border-radius: 14px;
    padding: 8px 12px;
}
.yohb-thread-reply-author {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin-bottom: 2px;
}
.yohb-thread-reply-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: #FFFFFF;
    cursor: pointer;
}
.yohb-thread-reply-name:hover { color: var(--gp-blue); }
.yohb-thread-reply-handle {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted, #8A93A1);
    cursor: pointer;
}
.yohb-thread-reply-handle:hover { color: var(--gp-blue); }
.yohb-thread-reply-replying-to {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted, #8A93A1);
    margin-bottom: 4px;
}
.yohb-thread-reply-content {
    font-family: 'DM Sans', sans-serif;
    font-size: 13.5px;
    line-height: 1.45;
    color: #FFFFFF;
    white-space: pre-wrap;
    overflow-wrap: anywhere;
}

.yohb-thread-reply-actions {
    display: flex;
    align-items: center;
    gap: 12px;
    padding-left: 4px;
}
.yohb-thread-reply-timestamp {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted-deep, #6E6E6E);
}

/* Link buttons — used for Like / Reply / Edit / Delete / View N more
   replies / View N more comments. All share one style so "View more"
   reads as part of the same vocabulary. Default white; the active
   Like state turns blue so a liked reply stands out. */
.yohb-thread-link {
    background: transparent;
    border: 0;
    padding: 4px 6px;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-weight: 700;
    font-size: 12px;
    cursor: pointer;
    text-align: left;
    display: inline-block;
}
.yohb-thread-link:hover,
.yohb-thread-link:focus { outline: none; }
.yohb-thread-link[disabled] { opacity: 0.6; cursor: default; }
/* Active states for Like (post is liked by viewer) and Reply (composer
   is currently mounted under this row). Both pick up the brand blue
   so the active state reads at a glance — no underline noise. */
.yohb-thread-link.is-liked,
.yohb-thread-link.is-active { color: var(--gp-blue); }

/* Inline variant for Like/Reply that sit on the reply action row. */
.yohb-thread-link-inline { padding: 0; font-size: 11.5px; }

/* "View N more replies" buttons under a branch get the same
   indent as the L2 rows above them. */
.yohb-thread-link-indent2 { margin-left: 40px; }

/* Reply composer slot — mounted inline under whichever post the user
   clicked Reply on. Inherits the same 40px indent as L2/flat rows so
   the composer visually sits "under" the reply it's responding to. */
.yohb-thread-composer-slot {
    padding-left: 40px;
}
.yohb-thread-composer-slot:has(.yohb-reply-composer) {
    margin: 4px 0 8px;
}

.yohb-reply-composer {
    border-radius: 12px;
    padding: 6px 10px;
}

/* Dark-gray editor surface to match the surrounding card chrome —
   pure black blends with the modal background, white was painful. */
.yohb-reply-composer .yohb-reply-composer-editor {
    background: #1A1A1A;
    border: 0.5px solid var(--gp-card-border, #1C1C1C);
    border-radius: 8px;
    overflow: hidden;
}

/* Override SfRichTextEditor defaults (white bg, dark text, container
   border) inside our composer so the editor matches the dark theme.
   Targets the host, the content area, AND the .e-rte-container wrapper
   that ships with its own border by default. */
.yohb-reply-composer .e-richtexteditor,
.yohb-reply-composer .e-rte-container,
.yohb-reply-composer .e-richtexteditor .e-rte-content,
.yohb-reply-composer .e-richtexteditor .e-content,
.yohb-reply-composer .e-richtexteditor .e-rte-content .e-content {
    background: #1A1A1A !important;
    color: #FFFFFF !important;
    border: 0 !important;
    box-shadow: none !important;
    min-height: 38px;
}
/* Compact single-line composer that grows as text is added. Force border-box +
   a modest 8px content padding (Syncfusion's ~16px default read as 3 lines tall)
   and align the placeholder to the SAME offset — the prior 22px min-height + 4px
   padding clipped "Write a reply…" to a 1px sliver at the bottom. */
.yohb-reply-composer .e-richtexteditor .e-rte-content .e-content,
.yohb-reply-composer .e-richtexteditor .e-content {
    box-sizing: border-box !important;
    padding: 8px 10px !important;
    line-height: 1.4 !important;
}
.yohb-reply-composer .e-richtexteditor .e-rte-content .e-content[contenteditable] {
    caret-color: #FFFFFF;
}
.yohb-reply-composer .e-richtexteditor .e-placeholder {
    color: var(--gp-muted-deep, #6E6E6E);
    padding: 8px 10px !important;
    line-height: 1.4 !important;
}

.yohb-reply-composer-previews {
    margin-top: 8px;
    display: flex;
    flex-direction: row;
    justify-content: start;
    flex-wrap: wrap;
    gap: 8px;
}
.yohb-reply-composer-previews .preview-image-container {
    height: 80px !important;
    width: 80px;
}

.yohb-reply-composer-actions {
    /* Match the "Replying to @Username" → input gap (dock-context margin-bottom
       6px + bubble padding-top 6px = 12px). */
    margin-top: 12px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.yohb-reply-composer-image {
    cursor: pointer;
    color: var(--gp-blue);
    display: inline-flex;
    align-items: center;
    padding: 4px;
}
.yohb-reply-composer-image .material-symbols-outlined { font-size: 22px; }

.yohb-reply-composer-buttons {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: 6px;
}

/* Thin pill buttons — same outlined-blue style as the canonical
   AddPostButton on the Feed hero (.add-post-button), without an icon.
   Cancel is the secondary variant (muted text + border); the primary
   action stays as the standard outlined-blue pill. */
.yohb-reply-composer-btn {
    background: transparent;
    border: 1.5px solid var(--gp-blue);
    color: var(--gp-blue);
    border-radius: var(--gp-card-border-radius, 12px);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
    padding: 2px 12px;
    cursor: pointer;
    line-height: 1.6;
}
.yohb-reply-composer-btn[disabled] { opacity: 0.5; cursor: default; }
/* Cancel (secondary) variant — same outlined pill, white text and a
   neutral border. Stays as prominent as Post but reads "secondary"
   via the absence of the brand-blue accent. */
.yohb-reply-composer-btn-secondary {
    border-color: var(--gp-card-border, #1C1C1C);
    color: #FFFFFF;
}

.yohb-reply-composer-error { margin: 6px 0 0; }

/* Composer dock — the active NewReply / EditReply composer. Rendered as the
   LAST child INSIDE the scroll body (.yohb-sheet-body) and made position:sticky
   so the body's scrollbar runs full-height NEXT TO it (like a sticky header at
   the top) while it stays pinned to the bottom — it's part of the scroll flow,
   not an overlay. Capped at 45vh with internal scroll so a tall compose (many
   image previews) can't cover the whole thread. */
.yohb-thread-composer-dock {
    position: sticky;
    bottom: 0;
    z-index: 2;
    border-top: 0.5px solid #1C1C1C;
    background: var(--gp-card-bg, #0E0E0E);
    padding: 10px 14px;
    max-height: 45vh;
    overflow-y: auto;
}
.yohb-thread-composer-dock-context {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 6px;
}
.yohb-thread-composer-dock-label {
    font-size: 13px;
    color: var(--gp-muted, #9A9A9A);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.yohb-thread-composer-dock-close {
    background: transparent;
    border: 0;
    color: var(--gp-muted, #9A9A9A);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 2px;
    flex: 0 0 auto;
}
.yohb-thread-composer-dock-close:focus { outline: none; }
.yohb-thread-composer-dock-close .material-symbols-outlined { font-size: 18px; }
/* In the dock the composer is full width — drop the inline 40px indent
   and the inline vertical margin from the shared composer slot. */
.yohb-thread-composer-dock .yohb-thread-composer-slot {
    padding-left: 0;
}
.yohb-thread-composer-dock .yohb-thread-composer-slot:has(.yohb-reply-composer) {
    margin: 0;
}

/* ====== YohbCarousel — shared image gallery component ======
   Single source of truth for every multi-image carousel in the app:
   PostCard, VehicleCard, GarageCard, the reply tree, the legacy detail
   components, ImageViewer (full-screen), and Dialogs/ImageDialog.

   Built on a CSS scroll-snap track instead of BlazorBootstrap.Carousel
   so it works inside RenderFragments (the reply tree's recursive walk).
   Each slide is 100% wide; chevrons scroll one slide width via the
   yohbCarouselScroll JS helper and scroll-snap snaps to the nearest
   image. Scrollbar hidden so the visual matches a true carousel.

   The carousel itself is unsized — the host gives it dimensions
   (cards via .gp-card-media's aspect-ratio var, the reply tree via
   .yohb-thread-reply-carousel-host's aspect-ratio, ImageViewer via
   the fullscreen modifier). Keeps one set of carousel rules instead of
   per-context duplicates. */
.yohb-carousel {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    background: #1A1A1A;
}

/* Priming state — applied on the very first render of a multi-image
   carousel until OnAfterRenderAsync has positioned scrollLeft to the
   real start (or StartUrl target). Without this the user briefly sees
   the leading clone (= last image) at the default scrollLeft=0 before
   JS shifts to the real start. Layout is preserved (visibility:hidden
   keeps the track laid out so scrollLeft assignment works); only paint
   is suppressed for that single frame. Removed after init returns. */
.yohb-carousel-priming { visibility: hidden; }

.yohb-carousel-track {
    width: 100%;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
    display: flex;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}
.yohb-carousel-track::-webkit-scrollbar { display: none; }

.yohb-carousel-slide {
    flex: 0 0 100%;
    scroll-snap-align: start;
    height: 100%;
    position: relative; /* anchor for .cover-ymm bottom-left tag */
}
.yohb-carousel-image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    cursor: pointer;
    display: block;
    user-select: none;
}

/* Prev / next chevrons. Only rendered when count > 1. Bootstrap-like
   look (semi-transparent black + white chevron). Tap scrolls the track
   one slide width via the yohbCarouselScroll JS helper; scroll-snap
   snaps to the nearest image. */
.yohb-carousel-nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    background: rgba(0, 0, 0, 0.45);
    border: 0;
    width: 32px;
    height: 32px;
    border-radius: 50%;
    color: #FFFFFF;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 2;
    padding: 0;
}
.yohb-carousel-nav:hover { background: rgba(0, 0, 0, 0.65); }
.yohb-carousel-nav .material-symbols-outlined { font-size: 22px; line-height: 1; }
.yohb-carousel-prev { left: 6px; }
.yohb-carousel-next { right: 6px; }

/* Fullscreen variant (ImageViewer / Dialogs/ImageDialog). No border-
   radius, larger chevrons, the whole image is shown via object-fit:
   contain so nothing is cropped. The host (.yohb-image-viewer) provides
   the fixed full-viewport positioning + close button. */
.yohb-carousel-fullscreen { background: #000; border-radius: 0; }
.yohb-carousel-fullscreen .yohb-carousel-image { object-fit: contain; cursor: default; }
.yohb-carousel-fullscreen .yohb-carousel-nav { width: 44px; height: 44px; }
.yohb-carousel-fullscreen .yohb-carousel-nav .material-symbols-outlined { font-size: 30px; }
.yohb-carousel-fullscreen .yohb-carousel-prev { left: 12px; }
.yohb-carousel-fullscreen .yohb-carousel-next { right: 12px; }


/* Compose-only mode container (Feed ADD POST). Adds a bit of breathing
   room since there's no surrounding thread chrome. */
.yohb-thread-compose-only {
    padding: 16px 14px;
}

/* Recommend-icon Likes pill. Always blue (display-only, not a
   toggle). Sits on the right of each reply action row via
   margin-left:auto; on a PostCard it's the last child of .post-actions
   and the same margin-left:auto pins it to the right of the row. Tap
   opens the LikesModal. */
.yohb-thread-likes-pill {
    background: transparent;
    border: 0;
    padding: 4px 6px;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--gp-blue);
    cursor: pointer;
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    font-weight: 700;
    line-height: 1;
}
.yohb-thread-likes-pill .material-symbols-outlined {
    font-size: 16px;
    font-variation-settings: 'FILL' 1;
    color: var(--gp-blue);
}
.yohb-thread-likes-pill:hover .yohb-thread-likes-count,
.yohb-thread-likes-pill:focus .yohb-thread-likes-count { text-decoration: underline; }
.yohb-thread-likes-pill:focus { outline: none; }

/* In a PostCard action row the pill matches the other action buttons
   (like / share use an 18px icon + 12px label) rather than the denser
   16px/11px used on the modal's reply rows. */
.post-actions .yohb-thread-likes-pill .material-symbols-outlined { font-size: 18px; }
.post-actions .yohb-thread-likes-pill .yohb-thread-likes-count { font-size: 12px; }

/* ---- Warning pill (icon + count) — likes-pill style. Gray (the three-dot menu
   color) by default; YELLOW when the current user has unread warnings for the
   club. No red dot — color is the only signal. ----------------------------- */
.yohb-warning-pill {
    background: transparent;
    border: 0;
    padding: 4px 6px;
    display: inline-flex;
    align-items: center;
    gap: 4px;
    color: var(--gp-muted);
    cursor: pointer;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    flex-shrink: 0;
}
.yohb-warning-pill .material-symbols-outlined { font-size: 18px; color: inherit; }
.yohb-warning-pill .yohb-warning-count { color: inherit; }
.yohb-warning-pill.active { color: var(--gp-amber); }
.yohb-warning-pill.active .material-symbols-outlined { font-variation-settings: 'FILL' 1; }

/* ---- User History sheet rows (HISTORY / WARNINGS tabs) ------------------- */
.yohb-history-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 0;
    border-bottom: 0.5px solid #1C1C1C;
}
.yohb-history-icon {
    font-size: 20px;
    color: var(--gp-muted);
    flex-shrink: 0;
    margin-top: 1px;
}
.yohb-history-icon.warn { color: var(--gp-amber); }
.yohb-history-body { flex: 1; min-width: 0; }
.yohb-history-line {
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: #FFFFFF;
}
.yohb-history-actor { font-weight: 600; }
.yohb-history-note {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: #FFFFFF;
    margin-top: 2px;
}
.yohb-history-time {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted-deep);
    margin-top: 3px;
}

/* ---- Send-warning composer (Manage 3-dot "Send warning") ---------------- */
.yohb-warn-compose { display: flex; flex-direction: column; gap: 12px; }
.yohb-warn-target {
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: var(--gp-muted-deep);
}
.yohb-warn-input {
    width: 100%;
    box-sizing: border-box;
    background: #121212;
    border: 0.5px solid #2A2A2A;
    border-radius: 8px;
    padding: 10px 12px;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    resize: vertical;
}
.yohb-warn-input:focus { outline: none; border-color: var(--gp-blue); }
.yohb-warn-error {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-error);
}
.yohb-warn-send { align-self: flex-start; }
/* Warn/Ban composers disable the send button until a reason is typed — make
   that state visible (the base .yohb-follow-btn has no :disabled look). */
.yohb-warn-send:disabled { opacity: 0.45; cursor: not-allowed; }

/* Entity status banner (cancelled today; reusable for postponed etc.) — a
   full-width strip under the hero header on Details + Manage. */
.yohb-status-banner {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 12px 14px;
    padding: 12px 14px;
    border-radius: var(--gp-card-border-radius);
    background: var(--gp-card-bg);
    border: 1px solid var(--gp-error);
}
.yohb-status-banner .material-symbols-outlined { color: var(--gp-error); font-size: 20px; }
.yohb-status-banner-text {
    flex: 1;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: #FFFFFF;
}

/* Manage Permissions bulk toggles (Select all / Select none) — link-styled
   pair above the permission groups (Club + Event sheets). */
.yohb-perm-bulk { display: flex; gap: 18px; }
.yohb-perm-bulk button {
    background: none;
    border: 0;
    padding: 0;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-blue);
    cursor: pointer;
}

/* ---- Manage Invite tab search + Pending group headers ------------------- */
.yohb-invite-bar { padding: 0 0 12px; }
/* Page-level (Manage tabs): inset the invite search + group headers from the
   screen edge to match the 14px .yohb-userrow inset. Sheets keep the flush base. */
.yohb-clubs .yohb-invite-bar { padding: 0 14px 12px; }
.yohb-clubs .yohb-manage-group { padding: 0 14px; }
.yohb-invite-input {
    width: 100%;
    box-sizing: border-box;
    background: #121212;
    border: 0.5px solid #2A2A2A;
    border-radius: 8px;
    padding: 10px 12px;
    color: #FFFFFF;
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
}
.yohb-invite-input:focus { outline: none; border-color: var(--gp-blue); }
.yohb-invite-btn {
    flex-shrink: 0;
    border: 1.5px solid var(--gp-blue);
    background: transparent;
    color: var(--gp-blue);
    border-radius: 8px;
    padding: 6px 14px;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
}
.yohb-manage-group {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 11px;
    letter-spacing: 1.5px;
    color: #888888;
    text-transform: uppercase;
    margin: 14px 0 4px;
}

/* Review-application sheet: action pills sized like the Manage Permissions
   Save button, auto width, side by side. */
.yohb-review-actions { display: flex; gap: 10px; padding-top: 16px; }
/* The applicant identity card atop the review sheet — a .yohb-userrow flush with
   the sheet content padding so it lines up with the .yohb-about-row data below.
   Needs the compound selector: the base .yohb-userrow padding rule is declared
   LATER in this file and ties on specificity otherwise. */
.yohb-userrow.yohb-review-user { padding-left: 0; padding-right: 0; }

/* Apply form: a required field that's already filled renders as plain text
   (display-only), not a readonly textbox. (The form itself now uses the standard
   marketing-auth card — see ClubApply.razor.) */
.yohb-apply-static {
    font-family: 'DM Sans', sans-serif;
    font-size: 14px;
    color: #FFFFFF;
    padding: 2px 0;
}

/* Invite search (Manage): in-flight lookup spinner shown in the results area —
   the input above stays interactive while the debounced search runs. */
.yohb-invite-searching { padding: 8px 0 16px; }

/* Manage-list filter chips (Events Manage Registered/Pending tabs). */
.yohb-manage-filters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    padding: 12px 16px 4px;
}
.yohb-manage-filter-chip {
    background: transparent;
    border: 1px solid #2A2A2A;
    border-radius: 999px;
    color: #9A9A9A;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    padding: 4px 12px;
    cursor: pointer;
}
.yohb-manage-filter-chip.active {
    border-color: var(--gp-blue);
    color: #FFFFFF;
}

/* Assignment-type glyph on a UserRow (e.g. directions_car = Vehicle Exhibitor). */
.yohb-userrow-icon {
    font-size: 18px;
    color: var(--gp-blue);
    flex: 0 0 auto;
}

/* EventDetails "Hosted by" identity row (club avatar circle + name, clickable). */
.yohb-hosted-by {
    display: flex;
    align-items: center;
    gap: 10px;
    cursor: pointer;
}
.yohb-hosted-by-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: #FFFFFF;
}
.yohb-hosted-by:hover .yohb-hosted-by-name { color: var(--gp-blue); }
/* Entity glyph fallback inside a member-stack avatar circle (club linkage). */
.yohb-member-stack-avatar .material-symbols-outlined {
    font-size: 18px;
    color: var(--gp-blue);
}

/* ---- Club feed (ClubDetails Feed tab) ------------------------------------ */
/* The tab content + Add button reuse the STANDARD .yohb-tab-content padding and
   .yohb-tab-add row (same as the Profile tabs) — don't invent per-tab variants. */
/* Keyset "Load more" pill, centered under the loaded page. */
.yohb-feed-loadmore {
    display: block;
    margin: 12px auto 20px;
    background: transparent;
    border: 1.5px solid var(--gp-blue);
    color: var(--gp-blue);
    border-radius: var(--gp-card-border-radius);
    padding: 6px 18px;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 12px;
    letter-spacing: 1px;
    text-transform: uppercase;
    cursor: pointer;
}

/* Club-scoped compose (?compose=1&composeClub=): the "Posting in {club}" banner
   + permission-gated options above the composer in the thread modal. */
.yohb-compose-context {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 12px 16px 0;
}
.yohb-compose-context-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: var(--gp-blue);
}
.yohb-compose-context .profile-toggle {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 0;
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: #FFFFFF;
}
.yohb-compose-context .profile-toggle input { width: auto; }

/* Inline field-info icon (Club Add/Edit field labels) + its label row. */
.yohb-field-label-row { display: flex; align-items: center; gap: 6px; }
.yohb-info-btn {
    background: none;
    border: 0;
    padding: 0;
    color: var(--gp-blue);
    cursor: pointer;
    display: inline-flex;
    align-items: center;
}
.yohb-info-btn .material-symbols-outlined { font-size: 18px; }
/* Multi-paragraph info-dialog content (ConfirmModal ChildContent) — the body
   column gap owns the spacing. font/size/line-height MUST be re-asserted:
   FluentUI's reboot.css (loaded after ours) has a bare `p { font-family:
   var(--body-font) }` (Segoe) that beats inheritance on any plain <p>. */
.yohb-confirm-card .confirmation-dialog-body-content p {
    margin: 0;
    font-family: inherit;
    font-size: inherit;
    line-height: inherit;
}

/* Likes sheet — reuses the standard .yohb-sheet slide-up styling so
   it matches Profile's Follows / About / etc. modals exactly. The
   .yohb-sheet-elevated modifier on the backdrop raises the z-index
   one tier so the sheet stacks on top of the post thread modal
   (which sits at 1500/1501); without it both layers collide. */
.yohb-sheet-backdrop.yohb-sheet-elevated { z-index: 1600; }

.yohb-likes-row {
    display: flex;
    align-items: center;
    gap: 12px;
    width: 100%;
    background: transparent;
    border: 0;
    padding: 10px 16px;
    color: #FFFFFF;
    cursor: pointer;
    text-align: left;
}
.yohb-likes-row:hover { background: rgba(255, 255, 255, 0.04); }

.yohb-likes-avatar {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    overflow: hidden;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: var(--gp-blue);
    flex: 0 0 auto;
}
.yohb-likes-avatar img { width: 100%; height: 100%; object-fit: cover; }

.yohb-likes-id { min-width: 0; }
.yohb-likes-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 15px;
    color: #FFFFFF;
    line-height: 1.2;
}
.yohb-likes-handle {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-muted, #8A93A1);
    line-height: 1.2;
}

/* ===========================================================================
   CLUBS — list / details / manage / membership + shared TagPill & UserRow.
   Design tokens only (var(--gp-blue) etc.); kebab-case, yohb- prefixed to
   avoid collisions. Mockup: ClaudeStaging/yohb_clubs_mockup.html.
   =========================================================================== */

/* ---- TagPill: one component, neutral/info + locked status taxonomy.
   Neutral unifies the old .cover-tag / .cover-location / .cover-ymm look
   (dark translucent bg, blue border, white text). The info chips (.cover-tag/
   .cover-location/.cover-ymm) match: white text on a blue border. Only the
   status variants (Open/Pending/Invited/Muted/Warned/Closed) carry a meaning
   color. Club/Event registration type is a traffic light: Open=Open (green),
   Approval_Required=Warned (yellow), Invite_Only=Closed (red). */
.yohb-tag-pill {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    padding: 2px 7px;
    border-radius: 4px;
    border: 0.5px solid transparent;
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 10px;
    letter-spacing: 0.2px;
    white-space: nowrap;
}
.yohb-tag-pill .material-symbols-outlined { font-size: 12px; }
.yohb-tag-pill-neutral {
    background: rgba(0, 0, 0, 0.6);
    border-color: rgba(41, 171, 226, 0.4);
    color: #FFFFFF;
    text-transform: uppercase;
}
.yohb-tag-pill-open {
    background: var(--gp-success-bg);
    color: var(--gp-success);
}
.yohb-tag-pill-pending,
.yohb-tag-pill-warned {
    background: rgba(255, 179, 0, 0.12);
    color: var(--gp-amber);
}
.yohb-tag-pill-invited {
    background: rgba(41, 171, 226, 0.12);
    color: var(--gp-blue);
}
.yohb-tag-pill-muted {
    background: rgba(136, 136, 136, 0.12);
    color: var(--gp-muted);
}
.yohb-tag-pill-closed {
    background: var(--gp-error-bg);
    color: var(--gp-error);
}

/* ClubCard cover corner tag-pills (overlaid on the .ent-cover image). */
.yohb-club-cover-tag-tr { position: absolute; top: 10px; right: 10px; z-index: 1; }
.yohb-club-cover-tag-bl { position: absolute; bottom: 10px; left: 10px; z-index: 1; }
/* Over the cover photo the translucent variant backgrounds wash out, so give
   the corner pills the same solid dark chip background as the .cover-tag chips
   on the Vehicle cards. The per-variant FOREGROUND color is kept (green/blue/
   amber/muted), only the background is unified. */
.yohb-club-cover-tag-tr .yohb-tag-pill,
.yohb-club-cover-tag-bl .yohb-tag-pill {
    background: rgba(0, 0, 0, 0.75);
    border-color: rgba(41, 171, 226, 0.4);
}
/* ClubCard has no avatar; keep the body a consistent height whether or not a
   "City, State" location line is present (matches the VehicleCard body height). */
.yohb-club-card-body { min-height: 65px; }
/* Pin the name/location block to the top so the club name sits in the same
   place with or without a location line; the body-actions keep centering
   (the .ent-body align-items:center still applies to them). */
.yohb-club-card-body .ent-id { align-self: flex-start; }
/* ClubCard member-count action turns blue when the viewer is a member
   (same active treatment as a favorited/following action). */
.ent-action.is-member { color: var(--gp-blue); }
.ent-action.is-member .material-symbols-outlined { font-variation-settings: 'FILL' 1; }

/* ---- Generic sub-tab bar (Discover/My Clubs, Admins/Members). Non-sticky;
   reuses the same look as .yohb-tab buttons but with its own container so the
   profile-page sticky offsets don't apply. ------------------------------- */
.yohb-club-tab-bar {
    display: flex;
    background: #000000;
    border-bottom: 0.5px solid var(--gp-card-border);
}
.yohb-club-tab {
    flex: 1;
    text-align: center;
    padding: 11px 4px;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 1px;
    color: var(--gp-muted);
    text-transform: uppercase;
    cursor: pointer;
    border: 0;
    border-bottom: 2px solid transparent;
    background: none;
}
.yohb-club-tab.active { color: #FFFFFF; border-bottom-color: var(--gp-blue); }

/* ---- Banner gradient shared by ClubCard + ClubInfoCard (placeholder until a
   real banner image is uploaded). ----------------------------------------- */
.yohb-club-banner-bg {
    background:
        linear-gradient(180deg, rgba(0,0,0,0.05) 0%, rgba(0,0,0,0.85) 100%),
        linear-gradient(135deg, #1a1a1a 0%, #2a2a2a 50%, #1a1a1a 100%);
    position: relative;
    overflow: hidden;
}
.yohb-club-banner-bg::before {
    content: "";
    position: absolute;
    inset: 0;
    background-image:
        radial-gradient(circle at 80% 20%, rgba(41,171,226,0.10) 0%, transparent 50%),
        repeating-linear-gradient(135deg, transparent 0, transparent 18px, rgba(255,255,255,0.015) 18px, rgba(255,255,255,0.015) 19px);
    pointer-events: none;
}

/* ---- ClubCard (list view) ----------------------------------------------- */
.yohb-club-list { padding: 10px 0 12px; }
.yohb-club-card {
    margin: 0 12px 10px;
    border-radius: 12px;
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    overflow: hidden;
    cursor: pointer;
}
.yohb-club-cover {
    height: 92px;
    padding: 10px 12px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
}
.yohb-club-cover-img { width: 100%; height: 100%; object-fit: cover; }
.yohb-club-card-name {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 16px;
    color: #FFFFFF;
    line-height: 1.15;
    position: relative;
    z-index: 1;
}
.yohb-club-badge {
    position: absolute;
    top: 10px;
    left: 10px;
    padding: 3px 7px;
    border-radius: 4px;
    background: rgba(0,0,0,0.7);
    font-family: 'DM Sans', sans-serif;
    font-size: 10px;
    font-weight: 500;
    color: #FFFFFF;
    z-index: 1;
}
.yohb-club-badge-admin { background: var(--gp-blue); color: #001821; }
.yohb-club-badge-founder { background: var(--gp-amber); color: #1f1300; }
.yohb-club-info {
    padding: 10px 12px 12px;
    display: flex;
    align-items: center;
    gap: 8px;
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted);
    flex-wrap: wrap;
}
.yohb-club-info .yohb-icon-text {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}
.yohb-club-info .yohb-icon-text .material-symbols-outlined { font-size: 13px; color: var(--gp-blue); }
.yohb-club-info .yohb-dot { color: var(--gp-muted-deep); }
.yohb-club-info .yohb-tag-pill { margin-left: auto; }

/* ---- ClubInfoCard (140px banner header on detail/manage/membership) ----- */
.yohb-club-info-card {
    height: 140px;
    margin: 12px;
    border-radius: 12px;
    border: 0.5px solid var(--gp-card-border);
    padding: 12px 14px;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    position: relative;
    overflow: hidden;
}
.yohb-club-info-card-img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}
.yohb-club-info-card-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 22px;
    color: #FFFFFF;
    line-height: 1.1;
    margin-bottom: 8px;
    position: relative;
    z-index: 1;
    letter-spacing: 0.3px;
}
.yohb-club-info-card-pills {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    position: relative;
    z-index: 1;
}

/* ---- Metadata row (Listing / Joining / Members / Type) ------------------ */
.yohb-meta-row {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    padding: 14px;
    margin: 4px 12px 0;
    border-radius: var(--gp-card-border-radius);
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
}
.yohb-meta-cell {
    text-align: center;
    border-right: 0.5px solid var(--gp-card-border);
}
.yohb-meta-cell:last-child { border-right: none; }
.yohb-meta-label {
    font-family: 'DM Sans', sans-serif;
    font-size: 9px;
    font-weight: 500;
    color: var(--gp-muted-deep);
    letter-spacing: 0.8px;
    text-transform: uppercase;
    margin-bottom: 3px;
}
.yohb-meta-value {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 13px;
    color: #FFFFFF;
}
.yohb-meta-value.cyan { color: var(--gp-blue); }

/* ---- Section blocks (Description / Region / Activities) ----------------- */
.yohb-club-section { padding: 14px; }
.yohb-club-section-label {
    font-family: 'DM Sans', sans-serif;
    font-size: 10px;
    font-weight: 500;
    color: var(--gp-muted-deep);
    letter-spacing: 0.8px;
    text-transform: uppercase;
    margin-bottom: 6px;
}
.yohb-club-section-body {
    font-family: 'DM Sans', sans-serif;
    font-size: 13px;
    color: #FFFFFF;
    line-height: 1.4;
}
.yohb-club-section-body.muted { color: var(--gp-muted); }
.yohb-club-section-body .yohb-icon-line {
    display: flex;
    align-items: center;
    gap: 6px;
}
.yohb-club-section-body .yohb-icon-line .material-symbols-outlined { font-size: 16px; color: var(--gp-blue); }

/* ---- Stat cards (Upcoming Events / Posts / Pending Requests) ------------ */
.yohb-stat-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
    padding: 4px 14px 14px;
}
.yohb-stat-card {
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    padding: 12px;
    cursor: pointer;
}
.yohb-stat-num {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 24px;
    color: #FFFFFF;
    line-height: 1;
}
.yohb-stat-num.cyan { color: var(--gp-blue); }
.yohb-stat-num.amber { color: var(--gp-amber); }
.yohb-stat-label {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted);
    margin-top: 4px;
    letter-spacing: 0.3px;
}
.yohb-stat-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 10px;
    color: var(--gp-muted-deep);
    margin-top: 2px;
}

/* ---- Member preview (overlapping avatar stack) -------------------------- */
.yohb-member-preview { padding: 6px 14px 18px; }
.yohb-member-stack { display: flex; align-items: center; }
.yohb-member-stack-avatar {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 10px;
    color: var(--gp-blue);
    margin-left: -8px;
    overflow: hidden;
}
.yohb-member-stack-avatar:first-child { margin-left: 0; }
.yohb-member-stack-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-member-stack-avatar.more {
    background: var(--gp-card-bg);
    border-color: var(--gp-card-border);
    color: var(--gp-muted);
    font-family: 'DM Sans', sans-serif;
}

/* ---- Bottom action row (role-aware single primary action) --------------- */
.yohb-club-action-row {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 12px 14px 14px;
}
.yohb-action-btn {
    height: 42px;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    border-radius: var(--gp-card-border-radius);
    font-family: 'Rajdhani', sans-serif;
    font-weight: 600;
    font-size: 13px;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    cursor: pointer;
    border: 1.5px solid transparent;
}
.yohb-action-btn-primary { background: var(--gp-blue); color: #001821; }
.yohb-action-btn-outline { background: transparent; border-color: var(--gp-blue); color: var(--gp-blue); }

/* Locked CTA (invite-only club, non-member) */
.yohb-locked-cta { padding: 12px 14px 14px; text-align: center; }
.yohb-lock-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    height: 42px;
    border: 1px dashed var(--gp-card-border);
    border-radius: var(--gp-card-border-radius);
    color: var(--gp-muted);
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
}
.yohb-lock-row .material-symbols-outlined { font-size: 16px; color: var(--gp-muted); }

/* ---- UserRow (generic; Manage member/admin lists, reused by Events) ----- */
.yohb-userrow-list { padding: 4px 0 14px; }
.yohb-userrow {
    display: flex;
    align-items: center;
    padding: 10px 14px;
    gap: 10px;
    border-bottom: 0.5px solid var(--gp-card-border);
    cursor: pointer;
    position: relative;
}
.yohb-userrow-avatar {
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 1.5px solid var(--gp-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 13px;
    color: var(--gp-blue);
    flex-shrink: 0;
    overflow: hidden;
}
.yohb-userrow-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-userrow-info { flex: 1; min-width: 0; }
.yohb-userrow-name {
    font-family: 'DM Sans', sans-serif;
    font-weight: 500;
    font-size: 13px;
    color: #FFFFFF;
}
.yohb-userrow-meta {
    font-family: 'DM Sans', sans-serif;
    font-size: 11px;
    color: var(--gp-muted-deep);
    margin-top: 1px;
}
.yohb-userrow-more {
    width: 28px;
    height: 28px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--gp-muted);
    flex-shrink: 0;
    border: 0;
    background: none;
    cursor: pointer;
}
.yohb-userrow-more .material-symbols-outlined { font-size: 18px; }

/* ---- Three-dot popover (schema-driven menu items) ----------------------- */
.yohb-popover {
    position: absolute;
    top: 38px;
    right: 14px;
    background: var(--gp-card-bg);
    border: 1px solid #333;
    border-radius: 10px;
    padding: 4px;
    min-width: 170px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.8);
    /* Above the sticky footer nav (z-1000) — a row menu opened near the bottom
       of the page must not be cut off behind the bar (2026-06-12). The rows
       themselves create no stacking context, so this wins at root level. */
    z-index: 1100;
}
.yohb-popover-item {
    padding: 9px 12px;
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: #FFFFFF;
    border-radius: 6px;
    cursor: pointer;
    background: none;
    border: 0;
    width: 100%;
    text-align: left;
}
.yohb-popover-item:hover { background: rgba(255,255,255,0.04); }
.yohb-popover-item.danger { color: var(--gp-error); }
.yohb-popover-divider { height: 1px; background: #222; margin: 4px 0; }
/* Invisible full-screen catcher so any outside tap closes an open popover.
   Sits just under the popover (and over the footer nav) so a tap anywhere —
   including on the bar — closes the menu first. */
.yohb-popover-backdrop { position: fixed; inset: 0; z-index: 1099; }

/* ---- Your-Role-Row (My Membership) -------------------------------------- */
.yohb-role-row {
    margin: 12px;
    background: var(--gp-card-bg);
    border: 0.5px solid var(--gp-card-border);
    border-radius: 12px;
    padding: 14px;
    display: flex;
    align-items: center;
    gap: 12px;
    position: relative;
}
.yohb-role-avatar {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: #1A1A1A;
    border: 2px solid var(--gp-blue);
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 16px;
    color: var(--gp-blue);
    flex-shrink: 0;
    overflow: hidden;
}
.yohb-role-avatar img { width: 100%; height: 100%; object-fit: cover; }
.yohb-role-info { flex: 1; }
.yohb-role-title {
    font-family: 'Rajdhani', sans-serif;
    font-weight: 700;
    font-size: 16px;
    color: #FFFFFF;
}
.yohb-role-sub {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-muted);
    margin-top: 2px;
}

/* ---- Membership info block (key/value rows) ----------------------------- */
.yohb-membership-block { padding: 4px 14px 14px; }
.yohb-membership-row {
    display: flex;
    justify-content: space-between;
    padding: 8px 0;
    border-bottom: 0.5px solid var(--gp-card-border);
}
.yohb-membership-row:last-child { border-bottom: none; }
.yohb-membership-k {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    color: var(--gp-muted);
}
.yohb-membership-v {
    font-family: 'DM Sans', sans-serif;
    font-size: 12px;
    font-weight: 500;
    color: #FFFFFF;
}
.yohb-membership-v.green { color: var(--gp-success); }
.yohb-membership-v.cyan { color: var(--gp-blue); }

