/*
 * NavMenu plugin styles — topbar, nav-cascade, mobile drawer, nav-overlay.
 * Docs: /Docs/Features/NavMenu.md
 *
 * WHY: Extracted from pmkto/style.css into the plugin so any microsite that uses
 * the {{NavMenu:TopBar(...)}} token gets the same canonical styles without
 * copy-pasting CSS. The plugin enqueueing mechanism injects this file exactly once
 * per page regardless of how many tokens appear.
 *
 * CSS custom properties (--white, --slate-*, --accent, --accent-soft, --radius-*,
 * --ease-out) are resolved from the consuming microsite's :root declarations.
 * The plugin does not redefine them — each microsite controls its own design tokens.
 */

/* ================================================================
 * TOPBAR HEIGHT — CSS-only --topbar-h; no JS style.setProperty needed
 * WHY: The topbar height is fully determined by its own CSS values (vertical
 *      padding + logo image height). Expressing --topbar-h as a calc() from
 *      those same source-of-truth values lets the mobile drawer anchor itself
 *      flush below the topbar bar without any JS inline-style mutation, which
 *      is both CSP-compliant and architecturally cleaner.
 *      The media-query block mirrors the responsive logo-size change at 900 px.
 * ================================================================ */
:root {
    --navmenu-img-h: 52px;    /* matches .topbar__brand img { height: 52px } desktop */
    --navmenu-pad-v: 0.85rem; /* matches .topbar { padding: 0.85rem … } */
    --topbar-h: calc(var(--navmenu-pad-v) * 2 + var(--navmenu-img-h));
    /* WHY: Canonical z-index ladder keeps nav layers above hero/media overlays while
     *      still allowing microsites to tune stacking if they own exceptional layers. */
    --navmenu-z-overlay: 1150;
    --navmenu-z-topbar: 1200;
    --navmenu-z-drawer: 1210;
    --navmenu-z-cascade: 1220;
}

@media (max-width: 900px) {
    /* WHY: Mobile logo shrinks to 36 px (see .topbar__brand img inside @media 900px),
     *      so --topbar-h recalculates automatically to the smaller measured height. */
    :root {
        --navmenu-img-h: 36px;
    }
}

/* ================================================================
 * NAVIGATION — Fixed transparent header that gains a solid backdrop on scroll
 * WHY: Transparent on hero for immersive dark section; scrolled state adds
 *      frosted glass for readability over light content.
 * ================================================================ */
.topbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    /* WHY: Keep the topbar above page content layers; values come from CSS vars so
   *      microsites can override only when they have custom high-z hero/media effects. */
    z-index: var(--navmenu-z-topbar);
    isolation: isolate;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 0.85rem clamp(1rem, 4vw, 2.5rem);
    background: transparent;
    transition: background 0.35s ease, box-shadow 0.35s ease, border-color 0.35s ease;
    border-bottom: 1px solid transparent;
}

    /* WHY: Scrolled state triggers via JS class, adding solid background so links remain readable over light content. */
    .topbar.is-scrolled,
    .topbar.nav-is-open {
        background: rgba(252, 251, 249, 0.92);
        border-bottom-color: rgba(226, 232, 240, 0.6);
        box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
    }

/* WHY: backdrop-filter on .topbar on mobile creates a new containing block for
 * position:fixed descendants on iOS Safari (compositing-layer side effect).
 * This breaks touch-event routing for the fixed nav drawer and cascade panel —
 * taps pass through to page content instead of hitting the nav elements.
 * Scoping backdrop-filter to desktop-only (≥ 901 px) eliminates the bug while
 * preserving the frosted-glass aesthetic where the nav is inline, not fixed. */
@media (min-width: 901px) {
    .topbar.is-scrolled,
    .topbar.nav-is-open {
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
    }
}

.topbar__brand {
    display: flex;
    align-items: center;
    gap: 0.65rem;
    text-decoration: none;
    font-weight: 800;
    font-size: 1rem;
    letter-spacing: -0.02em;
    /* WHY: Default light color for dark hero background. */
    color: var(--white);
    transition: color 0.35s ease;
}

/* WHY: The full brand name must stay on one visual line on desktop/tablet;
 *      wrapping degrades readability and increases header height unpredictably. */
.topbar__brand span {
    white-space: nowrap;
}

.topbar.is-scrolled .topbar__brand,
.topbar.nav-is-open .topbar__brand {
    color: var(--slate-900);
}

/* WHY: width:auto lets the browser render the logo at its natural aspect ratio while the
 *      fixed height cap prevents tall logos from distorting the topbar height calculation.
 *      --navmenu-img-h tracks height (not width) so --topbar-h remains correct. */
.topbar__brand img {
    width: auto;
    height: 52px;
    object-fit: contain;
}

.topbar nav {
    display: flex;
    align-items: center;
    /* WHY: Slightly tighter spacing lets the full menu fit common tablet widths
   *      without changing information density or touchability too aggressively. */
    gap: 0.1rem;
}

    .topbar nav a {
        display: inline-flex;
        align-items: center;
        gap: 0.35rem;
        text-decoration: none;
        font-size: 0.88rem;
        font-weight: 600;
        /* WHY: Reduced horizontal padding trims total nav width so options no
   *      longer feel over-spaced and avoid early wrapping near iPad breakpoints. */
        padding: 0.45rem 0.72rem;
        border-radius: var(--radius-md);
        transition: color 0.2s ease, background 0.2s ease;
        /* WHY: Light text on dark hero default. */
        color: rgba(255, 255, 255, 0.8);
    }

        .topbar nav a:hover {
            color: var(--white);
            background: rgba(255, 255, 255, 0.1);
        }

        .topbar nav a.active {
            color: var(--white);
            background: rgba(255, 255, 255, 0.15);
        }

/* WHY: After scroll, nav links switch to dark-on-light for readability. */
.topbar.is-scrolled nav a,
.topbar.nav-is-open nav a {
    color: var(--slate-600);
}

    .topbar.is-scrolled nav a:hover,
    .topbar.nav-is-open nav a:hover {
        color: var(--slate-900);
        background: var(--slate-100);
    }

    .topbar.is-scrolled nav a.active,
    .topbar.nav-is-open nav a.active {
        color: var(--accent);
        background: var(--accent-soft);
    }


/* WHY: Keyboard users need a clear, high-contrast focus ring regardless of
 *      hero/background state so nav actions remain discoverable and operable. */
.topbar a:focus-visible,
.topbar button:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Mobile nav toggle */
.topbar__toggle {
    display: none;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
    color: var(--white);
    transition: color 0.35s ease;
}

.topbar.is-scrolled .topbar__toggle,
.topbar.nav-is-open .topbar__toggle {
    color: var(--slate-700);
}

.topbar__toggle svg {
    width: 24px;
    height: 24px;
    stroke: currentColor;
    stroke-width: 2;
    fill: none;
}

/* ================================================================
 * NAV CASCADE — Dropdown submenu for links with child pages
 * WHY: Two-column dropdown gives sub-pages discoverability and context
 *      without leaving the current page on desktop.
 * ================================================================ */
.nav-cascade {
    position: relative;
    display: inline-flex;
}

    /* WHY: Transparent bridge fills the gap between the trigger and the dropdown
   *      so the cursor stays within .nav-cascade while moving from the link
   *      to the menu, preventing the hover state from being lost. */
    .nav-cascade::after {
        content: "";
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        height: 0.75rem;
    }

.nav-cascade__trigger {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.nav-cascade__caret {
    line-height: 1;
    opacity: 0.6;
    transition: transform 0.25s var(--ease-out);
}

.nav-cascade.is-open .nav-cascade__caret {
    transform: rotate(180deg);
}

.nav-cascade__menu {
    position: absolute;
    top: calc(100% + 0.75rem);
    z-index: 50;
    display: none;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.5rem;
    border: 1px solid var(--slate-200);
    border-radius: var(--radius-lg);
    white-space: nowrap;
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.06);
    animation: navMenuReveal 0.25s var(--ease-out);
}

/* WHY: Animation handles only opacity + subtle Y-slide + scale so it matches
 *      the element's actual resting transform state (none). No X offset is used
 *      here because the left:50% center-alignment is not applied; carrying a
 *      translateX in the animation would cause a visible left-shift flash. */
@keyframes navMenuReveal {
    from {
        opacity: 0;
        transform: translateY(-8px) scale(0.97);
    }

    to {
        opacity: 1;
        transform: translateY(0) scale(1);
    }
}

.nav-cascade:hover .nav-cascade__menu,
.nav-cascade:focus-within .nav-cascade__menu,
.nav-cascade.is-open .nav-cascade__menu {
    display: flex;
}

/* WHY: .topbar prefix raises specificity above .topbar nav a so dropdown
 *      items show dark text on the white menu background instead of inheriting
 *      the transparent-hero white color.
 * WHY: The is-scrolled and nav-is-open variants boost specificity to 31 so they
 *      beat any microsite override like `.topbar.is-scrolled nav a { color: white }` (spec 22).
 *      Without this, dark-themed microsites make cascade dropdown links invisible on
 *      the dropdown's white background whenever the page is scrolled. */
.topbar .nav-cascade__menu a,
.topbar.is-scrolled .nav-cascade__menu a,
.topbar.nav-is-open .nav-cascade__menu a {
    border-radius: var(--radius-sm);
    padding: 0.55rem 0.75rem;
    font-size: 0.88rem;
    font-weight: 500;
    color: var(--slate-700);
    transition: background 0.15s ease, color 0.15s ease;
    text-decoration: none;
}

.topbar .nav-cascade__menu a:hover,
.topbar.is-scrolled .nav-cascade__menu a:hover,
.topbar.nav-is-open .nav-cascade__menu a:hover {
    background: var(--slate-100);
    color: var(--slate-900);
}

.topbar .nav-cascade__menu a.active,
.topbar.is-scrolled .nav-cascade__menu a.active,
.topbar.nav-is-open .nav-cascade__menu a.active {
    color: var(--accent);
    background: var(--accent-soft);
    font-weight: 600;
}

/* WHY: Back button exists in the DOM at all times but is only useful in the
 *      mobile slide-over panel, so it is hidden on desktop. */
.nav-cascade__back {
    display: none;
}

/* ================================================================
 * LOCALE TOGGLE — Optional language-selector rendered inside <nav>
 * WHY: Flag buttons are the canonical locale-switcher UI for any microsite
 *      that declares a "locales" array in its NavMenu:TopBar token. The
 *      actual switching logic lives in the microsite's own app.js (which
 *      hooks into [data-language-option]); this block only handles layout
 *      and visual state so any microsite can opt in without bespoke CSS.
 * ================================================================ */
.topbar__locale-toggle {
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    /* WHY: A thin left border separates the flag cluster from the nav links
     *      without requiring a wrapper element. */
    margin-left: 0.5rem;
    padding-left: 0.75rem;
    border-left: 1px solid rgba(255, 255, 255, 0.2);
    transition: border-color 0.35s ease;
}

.topbar.is-scrolled .topbar__locale-toggle {
    border-left-color: rgba(0, 0, 0, 0.12);
}

.topbar__locale-option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    background: none;
    border: 2px solid transparent;
    border-radius: 3px;
    padding: 2px;
    cursor: pointer;
    transition: border-color 0.2s ease, opacity 0.2s ease;
    opacity: 0.55;
    line-height: 0;
}

    .topbar__locale-option:hover {
        opacity: 1;
        border-color: rgba(255, 255, 255, 0.4);
    }

    .topbar__locale-option.is-active {
        opacity: 1;
        border-color: rgba(255, 255, 255, 0.9);
    }

.topbar.is-scrolled .topbar__locale-option:hover {
    border-color: rgba(0, 0, 0, 0.25);
}

.topbar.is-scrolled .topbar__locale-option.is-active {
    border-color: var(--accent);
}

.topbar__locale-flag {
    width: 20px;
    height: 20px;
    object-fit: cover;
    display: block;
}

/* WHY: Prevent background scroll while the mobile drawer is open so tap/drag
 * gestures remain focused on the navigation panel and links stay tappable. */
html.navmenu-lock-scroll,
body.navmenu-lock-scroll {
    overflow: hidden;
}

/* ================================================================
 * MOBILE NAV — Drawer and overlay at ≤ 900 px
 * WHY: Raise threshold to 900 px so iPad/tablet widths switch to the
 *      drawer before desktop nav links begin wrapping.
 * ================================================================ */
@media (max-width: 900px) {

    /* WHY: top uses --topbar-h (derived via CSS calc from the topbar's own padding
     *      and logo-height values — see :root above) so the drawer starts flush
     *      below the topbar without any JS inline-style mutations.
     * WHY: display:inline-flex (set on .is-open below) is the key to content-width sizing.
     *      position:fixed with display:flex (block-level) resolves width:auto to the
     *      viewport width in all browsers — width:max-content does NOT reliably fix this
     *      for flex columns (browser spec ambiguity). display:inline-flex is inherently
     *      shrink-to-fit, so the drawer is exactly as wide as its widest item without any
     *      explicit width property. white-space:nowrap keeps each label on one line.
     *      max-width:100vw is kept as overflow safety cap. */
    .topbar nav {
        display: none;
        position: fixed;
        top: var(--topbar-h, 68px);
        left: 0;
        max-width: 100vw;
        white-space: nowrap;
        background: var(--white);
        flex-direction: column;
        /* WHY: align-items:stretch makes every link fill the full drawer width so
         *      icons and text align to the left edge rather than centering in the
         *      column (which the inherited align-items:center from desktop would cause). */
        align-items: stretch;
        padding: 0.5rem 0.75rem 1.5rem;
        gap: 0.15rem;
        box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12);
        z-index: var(--navmenu-z-drawer);
        overflow-y: auto;
        max-height: calc(100dvh - var(--topbar-h, 68px));
    }

        /* WHY: inline-flex (not flex) is what makes the drawer shrink to content width.
         *      See comment on .topbar nav above. */
        .topbar nav.is-open {
            display: inline-flex;
        }

            /* WHY: Mobile drawer always uses dark-on-light text regardless of hero state.
             * WHY: The is-scrolled and nav-is-open variants boost specificity to 32 so these
             *      rules beat any microsite override like `.topbar.is-scrolled nav a { color: white }`
             *      (spec 22). Without this, opening the mobile drawer after scrolling on a
             *      dark-themed microsite renders white links on the white drawer background —
             *      invisible. The three-selector group covers: unscrolled, scrolled, and the
             *      nav-is-open topbar state that always accompanies an open drawer. */
            .topbar nav.is-open a,
            .topbar.is-scrolled nav.is-open a,
            .topbar.nav-is-open nav.is-open a {
                color: var(--slate-700);
                padding: 0.55rem 0.75rem;
                border-radius: var(--radius-md);
                font-size: 1rem;
            }

            .topbar nav.is-open a:hover,
            .topbar.is-scrolled nav.is-open a:hover,
            .topbar.nav-is-open nav.is-open a:hover {
                background: var(--slate-100);
                color: var(--slate-900);
            }

            .topbar nav.is-open a.active,
            .topbar.is-scrolled nav.is-open a.active,
            .topbar.nav-is-open nav.is-open a.active {
                color: var(--accent);
                background: var(--accent-soft);
            }

    /* WHY: order:-1 visually repositions the hamburger before the brand so the
     *      toggle sits at the left edge of the topbar, matching the left-side drawer. */
    .topbar__toggle {
        display: block;
        order: -1;
        /* WHY: Prevent the hamburger from being squeezed or pushed off-screen
         *      when the brand name is long on narrow viewports. */
        flex-shrink: 0;
        /* WHY: WCAG 2.5.5 recommends 44×44px minimum touch targets. The icon
         *      itself is 24px; 0.65rem padding on each side raises the tappable
         *      area to ≥44px without visually enlarging the icon. */
        min-width: 44px;
        min-height: 44px;
    }

    /* WHY: On narrow phones the logo plus full brand text can exceed the available
     *      row width alongside the hamburger, causing the toggle to be cropped.
     *      Allow the brand flex item to compress and truncate the text with an
     *      ellipsis rather than wrapping or pushing the toggle off-screen. */
    .topbar__brand {
        min-width: 0;
        flex: 1 1 auto;
    }

        .topbar__brand img {
            width: auto;
            height: 36px;
            flex-shrink: 0;
        }

        .topbar__brand span {
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
            font-size: 0.85rem;
        }

    /* WHY: In the mobile drawer the locale toggle becomes a horizontal row of flags
     *      separated from the nav links by a full-width top border.
     * WHY: width:100% fills the drawer (which is sized by the widest nav link via
     *      inline-flex shrink-to-fit). flex-wrap:wrap lets flags reflow into multiple
     *      rows if the drawer happens to be narrower than all flags in a single row. */
    .topbar__locale-toggle {
        width: 100%;
        padding: 0.75rem 1rem 0.5rem;
        margin-left: 0;
        border-left: none;
        border-top: 1px solid var(--slate-200);
        gap: 0.35rem;
        justify-content: flex-start;
        flex-wrap: wrap;
    }

    .topbar.is-scrolled .topbar__locale-toggle {
        border-left: none;
    }

    .topbar__locale-option:hover {
        border-color: rgba(0, 0, 0, 0.2);
    }

    .topbar__locale-option.is-active {
        border-color: var(--accent);
    }

    .topbar__locale-flag {
        width: 24px;
        height: 24px;
    }

    /* WHY: Overlay behind the mobile drawer intercepts taps for close. */
    .nav-overlay {
        display: none;
        position: fixed;
        inset: 0;
        background: rgba(0, 0, 0, 0.4);
        z-index: var(--navmenu-z-overlay);
    }

        .nav-overlay.is-open {
            display: block;
        }

    /* WHY: On mobile the cascade wrapper stays in the nav flow as a normal
     *      flex-column item so the trigger looks identical to other drawer links. */
    .nav-cascade {
        display: flex;
        flex-direction: column;
    }

    /* WHY: align-items:stretch on the parent inline-flex column stretches the
     *      cascade trigger to the full drawer width like all other links. */
    .nav-cascade__trigger {
        align-self: stretch;
    }

    /* WHY: On mobile the submenu becomes a fixed slide-over second-level panel.
     *      It starts off-screen to the LEFT (translateX -100%) and slides in
     *      when .is-open is set, matching the left-side main drawer.
     *      display:inline-flex (not flex) so the panel is shrink-to-fit width —
     *      same reasoning as .topbar nav above (fixed+flex = viewport-width).
     *      pointer-events:none prevents invisible interaction while hidden.
     *      top matches .topbar nav so the submenu panel starts flush below the
     *      topbar, keeping both layers consistently anchored.
     * WHY: visibility:hidden is added alongside transform:translateX(-100%) so the
     *      panel is removed from the accessibility tree while off-screen. On desktop
     *      the cascade uses display:none (already removes from a11y tree); on mobile
     *      display:inline-flex is always set so transform alone only hides the panel
     *      visually — screen readers would still announce its content while the drawer
     *      is closed. The transition delay (0s with 0.3s delay on close, 0s on open)
     *      ensures the panel re-enters the a11y tree immediately as it slides in, and
     *      leaves the a11y tree only after the slide-out animation completes. */
    .nav-cascade__menu {
        position: fixed;
        top: var(--topbar-h, 68px);
        left: 0;
        max-width: 100vw;
        display: inline-flex;
        flex-direction: column;
        pointer-events: none;
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform 0.3s var(--ease-out), visibility 0s 0.3s;
        z-index: var(--navmenu-z-cascade);
        border-radius: 0;
        border: none;
        border-right: 1px solid var(--slate-200);
        background: var(--white);
        box-shadow: 4px 0 24px rgba(0, 0, 0, 0.12);
        overflow-y: auto;
        animation: none;
        white-space: nowrap;
        gap: 0.15rem;
        max-height: calc(100dvh - var(--topbar-h, 68px));
    }

    .nav-cascade.is-open .nav-cascade__menu {
        transform: translateX(0);
        pointer-events: auto;
        visibility: visible;
        /* WHY: Override the delay so the panel becomes accessible to the a11y tree
         *      immediately when opening — it slides in visually but is already announced
         *      by screen readers from the first frame of the slide-in animation. */
        transition-delay: 0s;
    }

    /* WHY: Sub-panel links always render on white so they must be dark regardless of
     *      the topbar hero/scrolled state.
     * WHY: The is-scrolled and nav-is-open variants boost specificity to 31 so these
     *      rules beat any microsite override like `.topbar.is-scrolled nav a { color: white }`
     *      (spec 22). Without this, the cascade slide-over panel shows invisible white
     *      links on its white background when the page is scrolled on dark-themed microsites. */
    .topbar .nav-cascade__menu a,
    .topbar.is-scrolled .nav-cascade__menu a,
    .topbar.nav-is-open .nav-cascade__menu a {
        color: var(--slate-700);
        font-size: 1rem;
        padding: 0.75rem 1rem;
        border-radius: var(--radius-md);
    }

    .topbar .nav-cascade__menu a:hover,
    .topbar.is-scrolled .nav-cascade__menu a:hover,
    .topbar.nav-is-open .nav-cascade__menu a:hover {
        background: var(--slate-100);
        color: var(--slate-900);
    }

    .topbar .nav-cascade__menu a.active,
    .topbar.is-scrolled .nav-cascade__menu a.active,
    .topbar.nav-is-open .nav-cascade__menu a.active {
        color: var(--accent);
        background: var(--accent-soft);
        font-weight: 600;
    }

    /* WHY: Back button occupies the top of the slide-over panel, styled to
     *      match the drawer's link rows for visual consistency. */
    /* WHY: width:100% removed — align-items:stretch on .nav-cascade__menu stretches
     *      the back button to the container's max-content width. */
    .nav-cascade__back {
        display: inline-flex;
        align-items: center;
        gap: 0.5rem;
        background: none;
        border: none;
        border-bottom: 1px solid var(--slate-200);
        font: inherit;
        font-size: 0.92rem;
        font-weight: 600;
        color: var(--slate-500);
        cursor: pointer;
        padding: 0.75rem 0.5rem;
        /* WHY: min-height ensures the back button meets the 44px touch target
         *      recommendation. The 18px SVG + 0.75rem×2 padding reaches ~42px,
         *      so min-height picks up the remaining 2px without altering layout. */
        min-height: 44px;
        margin-bottom: 0.5rem;
        text-align: left;
    }

        .nav-cascade__back svg {
            width: 18px;
            height: 18px;
            stroke: currentColor;
            stroke-width: 2.5;
            fill: none;
            flex-shrink: 0;
        }

        .nav-cascade__back:hover {
            color: var(--slate-900);
        }
}
/* Last-Modified: 2026-03-09T08:38:28.0000000Z */