/*
 * RCX Portal — Chrome stylesheet (header, footer, disclaimers)
 *
 * Enqueued SITE-WIDE via rcx_portal_enqueue_chrome_styles() in functions.php.
 *
 * Token contract: every color MUST reference var(--wp--preset--color--*)
 * or var(--wp--custom--*). Zero hardcoded hex values.
 *
 * Design target: concept-1v3  (.ch-header__*, .ch-footer__*, .ch-disclaimer__*)
 * AA contrast verified:
 *   - Nav text on primary bg: text-secondary (#6B7280 → white fallback) ✓
 *   - Active nav on primary bg: surface (#FFF) + accent underline ✓
 *   - Avatar initials on accent bg: primary (#1E2D4F) at 8.7:1 on #B49A5E ✓
 *   - Footer text (text-secondary equiv) on primary bg ✓
 *   - Disclaimer body (text-secondary) on surface bg: 4.6:1 ✓
 *
 * DEVIATION: 15-frontend-design SD-03 strong-defaults to @wordpress/scripts.
 * This project uses plain CSS with no build pipeline, consistent with its
 * established no-build pattern (AGENTS.md; zero node footprint in the theme).
 * See base.css header for full rationale.
 */

/* ============================================================
   PAGE SHELL — sticky footer
   .wp-site-blocks is WP's FSE layout container wrapping header +
   main + disclaimers + footer for every route rendered through a
   theme block template (templates/page.html, archive-*.html,
   single-*.html, 404.html — offerings, offering detail, resources,
   resource detail when those route through a page template, etc).
   min-height + flex-column + flex on the main slot ensures the
   footer stays viewport-bottom on short pages (e.g. zero-result
   offerings filter) and flows normally — footer simply follows
   content — once content exceeds the viewport.

   SIX TEMPLATES BUILD THEIR OWN DOCUMENT SHELL AND BYPASS
   .wp-site-blocks ENTIRELY (`wp_body_open()` called directly, no
   template_include pipeline involved):
     web/app/plugins/rcx-invest-now/templates/invest-now.php               (body.rcx-invest-now-page)
     web/app/plugins/rcx-portal-auth/templates/account.php                 (body.rcx-account-page)
     web/app/plugins/rcx-portal-auth/templates/no-access.php               (body.rcx-no-access-page)
     web/app/plugins/rcx-resources/src/Detail/ResourceNotFound.php         (body.rcx-resource-not-found-page)
     web/app/plugins/rcx-salesforce-sync/src/Detail/OfferingNotFound.php   (body.rcx-offering-not-found-page)
     web/app/plugins/rcx-portal-auth/templates/login.php                   (body.rcx-login-page — EXCLUDED, see below)
   Each of the first five calls block_template_part()/do_blocks() for
   'header'/'disclaimers'/'footer' directly, so those parts land as
   direct children of <body> with no .wp-site-blocks wrapper — the
   reason the footer floated up on the short Invest Now post-submit
   confirmation page (client-reported, 2026-09-28) and, by the same
   mechanism, on Account, No-Access, and either not-found page.
   Rather than add a wrapper div to five templates just to reuse one
   selector, each template's own EXISTING body class (already set by
   its own body_class() call — no template edits) gets the identical
   shell rules below. tests/Unit/Theme/PageShellStylesheetTest.php
   discovers every document-shell template that renders the footer
   part and asserts its body class is listed here, so a sixth such
   template shipped later without this rule fails a test instead of
   shipping the same bug a third time.

   login.php is DELIBERATELY EXCLUDED — two independent reasons, either
   one sufficient on its own: (1) it renders NO header or footer chrome
   at all (spec line 155 / SP-19 — only the disclaimers band, beneath
   the card), so there is no footer to pin to the viewport bottom; (2)
   it already has its own full-viewport centering layout —
   .rcx-login__wrap sets `min-height: 100vh; display: flex;
   flex-direction: column; align-items: center; justify-content:
   center;` (base.css, "Login page" section) — which must not be
   overridden by a second, competing `display`/`min-height` pair on
   the body ancestor.

   min-height stacks three fallback declarations, each overriding
   the previous one in a browser that understands it; a browser that
   does not understand a given line's function/unit ignores that
   whole declaration and keeps the last one it understood, so this
   is layered enhancement, not competing rules:
     1. 100vh                                    — universal baseline.
     2. calc(100vh - the admin bar's height)      — see below.
     3. calc(100dvh - the admin bar's height)     — dynamic viewport
        units, for mobile browser chrome that shows/hides on scroll.

   THE ADMIN BAR OFFSET. wp_admin_bar_render() (core) adds
   `@media screen { html { margin-top: 32px !important; } }` (46px
   at <=782px) ONLY while the toolbar is showing, i.e. only for a
   logged-in user with it enabled — logged-out visitors and toolbar-
   off admins load no such rule. The same core stylesheet sets
   `html { --wp-admin--admin-bar--height: 32px }` (46px at the same
   782px breakpoint) alongside it, so the two numbers can never drift
   apart. Subtracting that custom property (falling back to 0px when
   it is not set at all) keeps `html`'s margin-top plus this
   min-height exactly at the viewport height instead of 32px over it
   — without the subtraction, a logged-in admin viewing a page whose
   content is otherwise exactly one viewport tall gets a permanent
   ~32px vertical scrollbar on every short page. This is a read of
   wp-admin/wp-includes/css/admin-bar.min.css and admin-bar.php, not
   a live-rendered check — verify with the admin bar showing on
   staging.
   ============================================================ */

.wp-site-blocks,
body.rcx-invest-now-page,
body.rcx-account-page,
body.rcx-no-access-page,
body.rcx-resource-not-found-page,
body.rcx-offering-not-found-page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: calc(100vh - var(--wp-admin--admin-bar--height, 0px));
    min-height: calc(100dvh - var(--wp-admin--admin-bar--height, 0px));
}

.wp-site-blocks > main,
.wp-site-blocks > [role="main"],
body.rcx-invest-now-page > main,
body.rcx-account-page > main,
body.rcx-no-access-page > main,
body.rcx-resource-not-found-page > main,
body.rcx-offering-not-found-page > main {
    flex: 1 0 auto;
}

/* ============================================================
   HEADER — .rcx-site-header
   ============================================================ */

.rcx-site-header {
    height: 56px;
    background: var(--wp--preset--color--primary);
    display: flex !important;
    align-items: center;
    /* Full-bleed bar; inner content aligned to 1280px spine.
       Horizontal padding: at least 48px gutter, expanding to center
       the inner content within the spine at wider viewports. */
    padding-top: 0;
    padding-bottom: 0;
    padding-inline: max(var(--wp--preset--spacing--48), calc((100% - 1280px) / 2));
    flex-shrink: 0;
    border-bottom: none;
    /* Reset any WP group block default widths */
    max-width: none !important;
    margin: 0 !important;
}

/* ----------------------------------------
   Brand / Wordmark
   ---------------------------------------- */

.rcx-site-header__brand {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.rcx-site-header__wordmark {
    font-size: var(--wp--preset--font-size--sm);
    font-weight: 600;
    color: var(--wp--preset--color--surface);
    letter-spacing: 2.5px;
    white-space: nowrap;
    text-decoration: none;
    font-family: var(--wp--preset--font-family--dm-sans);
}

.rcx-site-header__wordmark:hover {
    color: var(--wp--preset--color--surface);
    text-decoration: none;
}

/* White "plate" wrapper for the Tier-2 logo image only — approved
   2026-07-07 ("Option A" of four options demoed) per master-spec change
   order 2026-08-16-header-logo-plate. A survey of the real partner-logo
   library found zero true white-knockout logos, so every partner logo
   needs a light surface behind it rather than rendering directly on navy.
   Deliberately NOT applied to .rcx-site-header__wordmark — the text
   fallback keeps rendering directly on navy, unchanged.
   Sizing is intentionally NOT fixed-width/height: inline-flex + padding
   let the plate hug whatever size the logo itself renders at (governed
   by .rcx-site-header__logo-img's max-height/max-width below).
   DEVIATION: Frontend Design HC-01 - visual direction already decided and
   client-approved outside the pipeline (four options demoed, "Option A"
   approved 2026-07-07, documented in spec.md); this is direct
   implementation of an approved treatment, not new design exploration. */
.rcx-site-header__logo-plate {
    display: inline-flex;
    align-items: center;
    background: var(--wp--preset--color--surface);
    border-radius: var(--wp--custom--radius--md);
    padding: 6px 10px;
}

/* Logo image variant (used when branchLogo or nationalAccountLogo exists) */
.rcx-site-header__logo-img {
    max-height: 40px;
    max-width: 180px;
    object-fit: contain;
    display: block;
}

/* ----------------------------------------
   Spacer (flex: 1 gap pusher)
   ---------------------------------------- */

.rcx-site-header__spacer {
    flex: 1;
}

/* ----------------------------------------
   Primary Navigation
   ---------------------------------------- */

.rcx-site-header__nav {
    display: flex !important;
    align-items: center;
    gap: var(--wp--preset--spacing--32);
    list-style: none;
    margin: 0;
    padding: 0;
}

.rcx-site-header__nav a,
.rcx-site-header__nav-item {
    font-size: var(--wp--preset--font-size--base);
    font-weight: 500;
    font-family: var(--wp--preset--font-family--dm-sans);
    /* Muted nav color on dark bg — uses a custom nav-muted approach via
       primary token lightened: since we can't hardcode hex, we use
       text-secondary but set opacity to achieve the muted-on-dark look. */
    color: var(--wp--preset--color--surface);
    opacity: 0.6;
    text-decoration: none;
    padding-bottom: 2px;
    border-bottom: 2px solid transparent;
    transition: color 150ms ease, opacity 150ms ease, border-bottom-color 150ms ease;
    white-space: nowrap;
    line-height: 1;
}

.rcx-site-header__nav a:hover,
.rcx-site-header__nav-item:hover {
    opacity: 1;
    color: var(--wp--preset--color--surface);
    text-decoration: none;
}

/* Active state: full-opacity white text + brand-gold underline.
   Driven by aria-current="page" injected by rcx_portal_nav_aria_current()
   in functions.php — no JS required, no hardcoded class in static HTML. */
.rcx-site-header__nav a[aria-current="page"],
.rcx-site-header__nav-item[aria-current="page"],
.rcx-site-header__nav a.rcx-nav-active,
.rcx-site-header__nav-item.rcx-nav-active {
    color: var(--wp--preset--color--surface);
    opacity: 1;
    border-bottom-color: var(--wp--preset--color--accent);
}

/* ----------------------------------------
   User Region
   ---------------------------------------- */

.rcx-site-header__user {
    display: flex !important;
    align-items: center;
    gap: var(--wp--preset--spacing--12);
    flex-shrink: 0;
}

/* "Name · Branch" identifier. white-space: nowrap keeps the name + separator
   on one line; the display name itself NEVER truncates (CONTENT-LENGTH —
   Option B) — only .rcx-site-header__user-id-branch below gets a max-width +
   ellipsis, since real branch names run to 48 chars. Hover context is a
   plain native `title` attribute (set in render.php) — "{national account
   name} - {branch name}" — not a custom tooltip; a custom CSS hover tooltip
   was tried and deliberately reverted in favor of this simpler approach. */
.rcx-site-header__user-id {
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    opacity: 0.65;
    white-space: nowrap;
}

/* Branch portion only: ellipsizes when the branch name is long. The full
   value is still available via the native title attribute on the container
   above (accessible on hover / assistive tech). The name span above is
   never constrained. */
.rcx-site-header__user-id-branch {
    display: inline-block;
    max-width: 10rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* Avatar initials badge — a real link to /account (keyboard-focusable, with
   an accessible name via aria-label).
   AA contrast: primary (#1E2D4F) on accent (#B49A5E) = 8.7:1 — passes AAA. */
.rcx-site-header__avatar {
    width: 32px;
    height: 32px;
    border-radius: 50%;
    background: var(--wp--preset--color--accent);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    font-size: var(--wp--preset--font-size--xs);
    font-weight: 600;
    font-family: var(--wp--preset--font-family--dm-sans);
    /* Use primary (dark navy) for initials text on gold bg — 8.7:1 contrast */
    color: var(--wp--preset--color--primary);
    flex-shrink: 0;
    cursor: pointer;
    line-height: 1;
    text-decoration: none;
}

.rcx-site-header__avatar:hover {
    text-decoration: none;
}

/* Visible focus state (keyboard nav). Uses the surface (white) token rather
   than the accent-strong token used elsewhere in the theme (rcx-btn-primary,
   rcx-login__btn) because those sit on light surfaces — against this header's
   dark navy background, surface reaches a far higher contrast ratio than
   accent-strong does, and matches the header's own existing surface-token
   border/text treatment (e.g. .rcx-site-header__logout). */
.rcx-site-header__avatar:focus-visible {
    outline: 2px solid var(--wp--preset--color--surface);
    outline-offset: 2px;
}

/* Log Out link */
.rcx-site-header__logout {
    background: none;
    /* Border uses surface (white) token; the element's opacity: 0.65 makes it
       render as a muted dark-bordered button against the primary-navy header —
       matching concept-1v3's #3A4A66 border appearance without a hardcoded hex. */
    border: 1px solid var(--wp--preset--color--surface);
    color: var(--wp--preset--color--surface);
    opacity: 0.65;
    font-size: var(--wp--preset--font-size--xs);
    font-family: var(--wp--preset--font-family--dm-sans);
    padding: 5px var(--wp--preset--spacing--12);
    border-radius: var(--wp--custom--radius--sm);
    cursor: pointer;
    text-decoration: none;
    display: inline-block;
    transition: opacity 150ms ease, border-color 150ms ease;
    line-height: 1.4;
}

.rcx-site-header__logout:hover {
    opacity: 1;
    border-color: var(--wp--preset--color--surface);
    color: var(--wp--preset--color--surface);
    text-decoration: none;
}

/* ============================================================
   HEADER RESPONSIVE
   ============================================================ */

/* Tablet (≤1024px): reduce minimum gutter to 24px; keep the nav bar visible
   (avatar link + Log Out + the 3 nav links) but drop the redundant
   "name · branch" identity text — that text is unwrappable
   (white-space: nowrap) and its min-content width is what forced "Log Out"
   to wrap/overflow in the 641–1024 band. The ≤640 rule below already hides
   the entire .rcx-site-header__user region, so this only changes rendering
   for 641–1024. This retires the former ≤900px branch-shrink patch below —
   with the identity text gone, the header has ample room without shrinking
   the nav/user flex groups. */
@media (max-width: 1024px) {
    .rcx-site-header {
        padding-inline: max(var(--wp--preset--spacing--24), calc((100% - 1280px) / 2));
    }

    .rcx-site-header__nav {
        gap: var(--wp--preset--spacing--20);
    }

    .rcx-site-header__user-id {
        display: none;
    }
}

/* Mobile (≤640px): hamburger replaces the inline nav row.
   Wave 14: hide .rcx-site-header__nav + show the hamburger toggle.
   The header no longer wraps to a second row at this breakpoint —
   brand / spacer / user-region / hamburger all stay in one 56px bar. */
@media (max-width: 640px) {
    .rcx-site-header {
        padding-inline: max(var(--wp--preset--spacing--16), calc((100% - 1280px) / 2));
        /* Single-row: remove the flex-wrap and gap that caused the nav second row. */
        flex-wrap: nowrap;
        gap: 0;
        height: 56px;
        min-height: 56px;
    }

    /* Inline nav hidden: hamburger overlay takes over on mobile. */
    .rcx-site-header__nav {
        display: none !important;
    }

    /* Entire user region hidden: avatar, Log Out, and identity all move
       into the overlay on mobile — no duplication in the header bar. */
    .rcx-site-header__user {
        display: none !important;
    }

}

/* ============================================================
   FOOTER — .rcx-site-footer
   ============================================================ */

.rcx-site-footer {
    background: var(--wp--preset--color--primary);
    padding-top: var(--wp--preset--spacing--24);
    padding-bottom: var(--wp--preset--spacing--24);
    /* Full-bleed bar; inner content aligned to 1280px spine. */
    padding-inline: max(var(--wp--preset--spacing--48), calc((100% - 1280px) / 2));
    display: flex !important;
    align-items: center;
    flex-shrink: 0;
    max-width: none !important;
    margin: 0 !important;
}

/* Wordmark */
.rcx-site-footer__wordmark {
    font-size: var(--wp--preset--font-size--sm);
    font-weight: 600;
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    letter-spacing: 2px;
    margin: 0;
    flex-shrink: 0;
}

/* Copyright line — centered with flex: 1 */
.rcx-site-footer__copyright {
    flex: 1;
    text-align: center;
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    opacity: 0.55;
    margin: 0;
}

/* Legal links group */
.rcx-site-footer__legal {
    display: flex !important;
    gap: var(--wp--preset--spacing--24);
    flex-shrink: 0;
}

.rcx-site-footer__legal a {
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    opacity: 0.55;
    text-decoration: none;
    cursor: pointer;
    transition: opacity 150ms ease;
}

.rcx-site-footer__legal a:hover {
    opacity: 1;
    color: var(--wp--preset--color--surface);
    text-decoration: none;
}

/* ----------------------------------------
   Footer Responsive
   ---------------------------------------- */

@media (max-width: 1024px) {
    .rcx-site-footer {
        padding-top: var(--wp--preset--spacing--24);
        padding-bottom: var(--wp--preset--spacing--24);
        padding-inline: max(var(--wp--preset--spacing--24), calc((100% - 1280px) / 2));
    }
}

@media (max-width: 640px) {
    .rcx-site-footer {
        padding-top: var(--wp--preset--spacing--20);
        padding-bottom: var(--wp--preset--spacing--20);
        padding-inline: max(var(--wp--preset--spacing--16), calc((100% - 1280px) / 2));
        flex-direction: column;
        gap: var(--wp--preset--spacing--12);
        text-align: center;
    }

    .rcx-site-footer__copyright {
        flex: 0 0 auto;
    }
}

/* ============================================================
   DISCLAIMERS — .rcx-disclaimers
   ============================================================ */

.rcx-disclaimers {
    background: var(--wp--preset--color--surface);
    border-top: 1px solid var(--wp--preset--color--border);
    padding-top: var(--wp--preset--spacing--48);
    padding-bottom: var(--wp--preset--spacing--48);
    /* Full-bleed bar; inner content aligned to 1280px spine. */
    padding-inline: max(var(--wp--preset--spacing--48), calc((100% - 1280px) / 2));
    max-width: none !important;
    margin: 0 !important;
}

/* Section heading "Disclaimers" */
.rcx-disclaimers__heading {
    font-size: 18px;
    font-weight: 600;
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--primary);
    margin: 0 0 var(--wp--preset--spacing--24) 0;
    line-height: 1.3;
}

/* Horizontal rule between disclaimer blocks */
.rcx-disclaimers__divider {
    height: 1px;
    background: var(--wp--preset--color--border);
    border: none;
    margin: var(--wp--preset--spacing--24) 0;
}

/* Individual disclaimer block */
.rcx-disclaimer__block {
    display: flex;
    flex-direction: column;
    gap: var(--wp--preset--spacing--12);
}

/* Header row: badge + logo on the same line */
.rcx-disclaimer__header {
    display: flex;
    align-items: center;
    justify-content: space-between;
}

/* Label badge e.g. "General Disclaimer" */
.rcx-disclaimer__badge {
    font-size: var(--wp--preset--font-size--xs);
    font-weight: 500;
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--primary);
    border: 1px solid var(--wp--preset--color--primary);
    border-radius: var(--wp--custom--radius--sm);
    padding: 4px var(--wp--preset--spacing--12);
    display: inline-block;
    line-height: 1.4;
}

/* Right-side muted wordmark in disclaimer header */
.rcx-disclaimer__logo {
    font-size: var(--wp--preset--font-size--xs);
    font-weight: 600;
    font-family: var(--wp--preset--font-family--dm-sans);
    /* Muted — text-muted is #9CA3AF; border-input is a shade darker.
       Using text-muted token with opacity to approximate the concept-1v3
       #C8CCD4 value. */
    color: var(--wp--preset--color--text-muted);
    letter-spacing: 1.5px;
}

/* Disclaimer body copy */
.rcx-disclaimer__body {
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--text-secondary);
    line-height: 1.6;
    margin: 0;
    /* Justified per client request; hyphens avoid ragged word-spacing rivers
       at narrow widths (global + account disclaimer blocks, wave client-feedback-1). */
    text-align: justify;
    -webkit-hyphens: auto;
    hyphens: auto;
}

/* Securities closing paragraph — slight top separation */
.rcx-disclaimer__body--securities {
    margin-top: var(--wp--preset--spacing--16);
}

/* Inline link inside disclaimer body */
.rcx-disclaimer__link {
    color: var(--wp--preset--color--primary);
    text-decoration: underline;
}

.rcx-disclaimer__link:hover {
    color: var(--wp--preset--color--accent-strong);
}

/* ----------------------------------------
   Disclaimers Responsive
   ---------------------------------------- */

@media (max-width: 1024px) {
    .rcx-disclaimers {
        padding-top: var(--wp--preset--spacing--32);
        padding-bottom: var(--wp--preset--spacing--32);
        padding-inline: max(var(--wp--preset--spacing--24), calc((100% - 1280px) / 2));
    }
}

@media (max-width: 640px) {
    .rcx-disclaimers {
        padding-top: var(--wp--preset--spacing--24);
        padding-bottom: var(--wp--preset--spacing--24);
        padding-inline: max(var(--wp--preset--spacing--16), calc((100% - 1280px) / 2));
    }
}

/* ============================================================
   MOBILE NAV — .rcx-mobile-nav (Wave 14)

   Token contract: zero hardcoded hex — all colors via
   var(--wp--preset--color--*) or var(--wp--custom--*).
   ============================================================ */

/* Block wrapper: no visual style; just positioning context. */
.rcx-mobile-nav {
    display: contents;
}

/* ----------------------------------------
   Hamburger toggle button
   Base: hidden at all widths (desktop/tablet have the inline nav instead).
   The ≤640px media block below (placed AFTER this rule so it wins the
   cascade) overrides display to inline-flex on mobile.
   ---------------------------------------- */

.rcx-mobile-nav__toggle {
    display: none;
    align-items: center;
    justify-content: center;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--wp--preset--color--surface);
    /* ≥44px tap target (WCAG 2.5.5) */
    width: 44px;
    height: 44px;
    border-radius: var(--wp--custom--radius--sm);
    flex-shrink: 0;
    transition: opacity 150ms ease;
}

.rcx-mobile-nav__toggle:hover {
    opacity: 0.8;
}

/* Hamburger toggle: visible ≤640px. Placed AFTER the base display:none rule
   so equal-specificity source order makes this ≤640 declaration win. */
@media (max-width: 640px) {
    .rcx-mobile-nav__toggle {
        display: inline-flex;
    }
}

/* ----------------------------------------
   Full-screen overlay
   ---------------------------------------- */

.rcx-mobile-nav__overlay {
    position: fixed;
    inset: 0;
    z-index: 1000;
    /* [hidden] hides the overlay; JS toggles the attribute. */
}

/* When the overlay is open, the backdrop covers the page behind the panel. */
.rcx-mobile-nav__backdrop {
    position: absolute;
    inset: 0;
    background: var(--wp--preset--color--primary);
    opacity: 0.6;
}

/* ----------------------------------------
   Overlay panel (the visible drawer)
   ---------------------------------------- */

.rcx-mobile-nav__panel {
    position: absolute;
    inset: 0; /* full-screen */
    background: var(--wp--preset--color--primary);
    color: var(--wp--preset--color--surface);
    display: flex;
    flex-direction: column;
    padding: var(--wp--preset--spacing--24) var(--wp--preset--spacing--24)
             var(--wp--preset--spacing--48) var(--wp--preset--spacing--24);
    overflow-y: auto;
    /* Slide in from the right + fade; prefers-reduced-motion handled below. */
    transform: translateX(100%);
    opacity: 0;
    transition: transform 250ms ease, opacity 250ms ease;
}

/* .is-open triggers the visible state. */
.rcx-mobile-nav__overlay.is-open .rcx-mobile-nav__panel {
    transform: translateX(0);
    opacity: 1;
}

/* ----------------------------------------
   Close (X) button — prominent top-right
   ---------------------------------------- */

.rcx-mobile-nav__close {
    align-self: flex-end;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: var(--wp--preset--color--surface);
    /* ≥44px tap target */
    width: 44px;
    height: 44px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--wp--custom--radius--sm);
    flex-shrink: 0;
    transition: opacity 150ms ease;
    margin-bottom: var(--wp--preset--spacing--20);
}

.rcx-mobile-nav__close:hover {
    opacity: 0.8;
}

/* ----------------------------------------
   User identity line
   ---------------------------------------- */

/* white-space: nowrap keeps the name + separator on one line; the display
   name itself NEVER truncates (CONTENT-LENGTH — Option B) — only
   .rcx-mobile-nav__user-id-branch below ellipsizes, since real branch names
   run to 48 chars and the overlay panel is narrow. */
.rcx-mobile-nav__user-id {
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    opacity: 0.65;
    margin-bottom: var(--wp--preset--spacing--32);
    white-space: nowrap;
}

/* Branch portion only: ellipsizes when the branch name is long. The full
   value is still available via the title attribute. */
.rcx-mobile-nav__user-id-branch {
    display: inline-block;
    max-width: 10rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    vertical-align: bottom;
}

/* ----------------------------------------
   Navigation links
   ---------------------------------------- */

.rcx-mobile-nav__nav {
    display: flex;
    flex-direction: column;
    gap: 0;
    flex: 1;
}

.rcx-mobile-nav__link {
    font-size: var(--wp--preset--font-size--lg);
    font-weight: 500;
    font-family: var(--wp--preset--font-family--dm-sans);
    color: var(--wp--preset--color--surface);
    text-decoration: none;
    /* ≥44px tap target height */
    padding: var(--wp--preset--spacing--12) 0;
    border-bottom: 1px solid var(--wp--preset--color--surface);
    opacity: 0.75;
    transition: opacity 150ms ease, color 150ms ease;
    display: block;
}

.rcx-mobile-nav__link:first-child {
    border-top: 1px solid var(--wp--preset--color--surface);
}

.rcx-mobile-nav__link:hover,
.rcx-mobile-nav__link[aria-current="page"] {
    opacity: 1;
    color: var(--wp--preset--color--accent-strong);
    text-decoration: none;
}

/* ----------------------------------------
   Log Out control
   ---------------------------------------- */

.rcx-mobile-nav__logout-wrap {
    margin-top: var(--wp--preset--spacing--32);
}

.rcx-mobile-nav__logout {
    background: none;
    border: 1px solid var(--wp--preset--color--surface);
    color: var(--wp--preset--color--surface);
    opacity: 0.65;
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--dm-sans);
    padding: var(--wp--preset--spacing--8) var(--wp--preset--spacing--20);
    border-radius: var(--wp--custom--radius--sm);
    text-decoration: none;
    display: inline-block;
    /* ≥44px tap height via padding */
    line-height: 1.4;
    transition: opacity 150ms ease, border-color 150ms ease;
    cursor: pointer;
}

.rcx-mobile-nav__logout:hover {
    opacity: 1;
    border-color: var(--wp--preset--color--surface);
    color: var(--wp--preset--color--surface);
    text-decoration: none;
}

/* ----------------------------------------
   Body scroll lock while overlay is open
   ---------------------------------------- */

body.rcx-mobile-nav-open {
    overflow: hidden;
}

/* ----------------------------------------
   prefers-reduced-motion: instant open/close, no transforms
   ---------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    .rcx-mobile-nav__panel {
        transition: none;
        transform: none;
        opacity: 1;
    }
}
