/* 04 — Header
   Owns: .fl-page-header, nav-right desktop layout, fixed positioning, logo
   Depends on: 01-tokens, 02-base

   Markup contract (confirmed against the live page and includes/nav-right.php):
     <header class="fl-page-header fl-page-header-primary fl-page-nav-right
                     fl-page-nav-toggle-icon fl-page-nav-toggle-visible-medium-mobile">
       <div class="fl-page-header-wrap">
         <div class="fl-page-header-container container">
           <div class="fl-page-header-row row">
             <div class="col-md-12 col-lg-4 fl-page-header-logo-col">
               <div class="fl-page-header-logo">
                 <a href="..."><img class="fl-logo-img" ...></a>
               </div>
             </div>
             <div class="col-md-12 col-lg-8 fl-page-nav-col">
               <div class="rw-header-text">
                 <div class="rw-header-phone">Call: <a href="tel:...">...</a></div>
               </div>
               <div class="fl-page-nav-wrap">
                 <nav class="fl-page-nav fl-nav navbar navbar-default navbar-expand-lg">
                   <a class="shiftnav-toggle shiftnav-toggle-button">...</a>
                   <div class="fl-page-nav-collapse collapse navbar-collapse">
                     <ul class="nav navbar-nav navbar-right menu fl-theme-menu">
                       <li class="menu-item ... nav-item"><a class="nav-link">...</a></li>
                       ...
                     </ul>
                   </div>
                 </nav>
               </div>
             </div>
           </div>
         </div>
       </div>
     </header>

   Findings that diverge from the task-7 brief's drafts (verified against the
   live DOM and bb-theme/js/theme.js + rw/shared-js/rw-jquery.js, not just
   the archived LESS):

   - `.fl-page-header-fixed` does not exist anywhere in this theme. The
     *scrolled* fixed-header trigger is `.rw-fixed-header`, toggled on
     `.fl-page-header` itself by rw/shared-js/rw-jquery.js — a waypoints
     handler that adds the class once the page has scrolled past 160px and
     the direction is 'down', and removes it on 'up'. bb-theme's own
     Customizer "Fixed Header" toggle does add a `.fl-fixed-header` BODY
     class (confirmed present via curl) — UPDATE (final review, Finding 1):
     this class is no longer inert. It was originally treated as inert
     because the parent LESS that used to key off it
     (bb-theme/less/fixed-header.less) lived in the generated skin, which
     Task 4 dequeued — but that also left bb-theme/js/theme.js's
     `_fixedHeader()` writing compensating inline styles (a `padding-top` on
     `.fl-page`, a `top` on `.fl-page-header`) for a fixed header that no CSS
     ever created, producing a ~208px empty band above the top bar at
     >=992px on every page. The "at-rest" rules below key off
     `.fl-fixed-header` (restoring the old LESS's gate) specifically to make
     that inline compensation correct again. `.rw-fixed-header` remains the
     *scrolled*-state trigger and is unaffected by this — see below.

   - UPDATED 2026-09-12: two menu items now have children — "Services"
     (Shooting / Crewing / Creative Directing) and "About" (Contact) — so
     `ul.sub-menu` finally matches real content. The note that used to sit
     here, recording that it matched nothing, is obsolete. Each parent <li>
     carries `menu-item-has-children` and contains, in order: the trigger
     <a class="nav-link">, an empty <div class="fl-submenu-icon-wrap">, and
     the <ul class="sub-menu"> whose own items are <a class="nav-link"> too.

   - Submenu open/close is owned by THIS FILE, driven from :hover and
     :focus-within, and the parent theme's JS dropdown is switched off by
     rw/shared-js/rw-nav-dropdown.js. This reverses what used to be true and
     is the fix for the dropdowns-never-close bug — the full explanation is
     in the "Submenu" block below, and rw-nav-dropdown.js documents the other
     half. Two consequences worth knowing here:

       * Nothing in this file may set `display` on `ul.sub-menu`. That was
         the bug. The closed state is opacity/visibility/pointer-events.

       * bb-theme's `.fl-sub-menu-open` / `.fl-sub-menu-right` classes are
         now dead — nothing adds them, and no rule here reads them. The
         right-edge collision they existed to solve does not arise with this
         menu (the rightmost dropdown, "About", is followed by "Get A Quote",
         so its 230px panel opens well inside the viewport). If a dropdown
         is ever added to the last item, a right-aligned variant will need
         writing; do not reach for the parent's classes to get it.

   - ShiftNav's own toggle button has no breakpoint logic of its own and
     was visible at every width once the archived header-nav-right.css
     (which used to hide it at >=992px) was dequeued in Task 4 — confirmed
     in the browser at 1000px, toggle and desktop menu both showing at
     once. Fixed here (see the rule above `.navbar-nav`), scoped to
     `.fl-page-nav .shiftnav-toggle-button` so only this header's own
     toggle is affected.

   - Header is WHITE (`--surface`) with dark nav text (`--nav-text`, which
     resolves to `--black` / #1e1e1e). Chosen by the repo owner on
     2026-08-29, resolving the open question left by the rebuild: the
     earlier brand-blue header forced --nav-text out of use, and the
     Customizer's `fl-header-bg-color: #ffffff` already pointed this way.
     --accent is reserved here for the nav underline, never for text. */

/* ── Header shell ─────────────────────────────────────────── */
.fl-page-header {
    background-color: var(--surface);
    box-shadow: var(--header-shadow);
}

.fl-page-header-primary {
    padding-top: var(--header-padding);
    padding-bottom: var(--header-padding);
    transition: padding var(--header-transition);
}

.fl-page-header-row { align-items: center; }

@media (min-width: 992px) {
    .fl-page-nav-right .fl-page-nav-col {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        justify-content: center;
    }
}

/* ── Fixed header (at-rest state, >=992px) ───────────────────
   FIX (final review, Finding 1): restores what bb-theme/less/fixed-header.less
   used to supply before Task 4 dequeued the generated skin. body.fl-fixed-header
   is still emitted (bb-theme's own Customizer "Fixed Header" toggle, confirmed
   always-on for this site — see curl output in the fix report) and
   bb-theme/js/theme.js::_fixedHeader() still runs unconditionally on that gate.
   At >=992px it writes an inline `top` on .fl-page-header (the topbar height,
   i.e. --page-bar-height) and an inline `padding-top` on .fl-page (topbar
   height + header height) to compensate for a header it assumes is fixed —
   but with no CSS ever putting .fl-page-bar / .fl-page-header into
   `position: fixed`, that compensating padding-top became a bare empty band.

   These two rules restore `position: fixed` at the same gate and breakpoint
   the old LESS used (`.fl-fixed-header` + min-width:992px), so the JS-written
   top/padding-top become correct compensation again. Matches the old LESS's
   *intent* (fixed topbar above a fixed header, JS reconciles the offset), not
   its literal selectors — `.fl-page-header` still gets no explicit left/right
   here, same as the original, because it is always full-width in normal flow. */
@media (min-width: 992px) {
    .fl-fixed-header .fl-page-bar {
        position: fixed;
        min-width: 100%;
        top: 0;
        left: 0;
        right: 0;
        z-index: 101;
    }

    .fl-fixed-header .fl-page-header {
        position: fixed;
        min-width: 100%;
        top: 0; /* overwritten inline by theme.js::_fixedHeader() with the topbar height */
        z-index: 100;
    }

    /* Keeps the topbar clear of the WP admin bar (32px at >=783px, so always
       32px inside this >=992px block) when logged in. .fl-page-header's own
       admin-bar offset is not duplicated here — theme.js already folds the
       +32px into the inline `top` it writes (see barHeight += 32 above),
       which wins over any stylesheet rule regardless of specificity. */
    .fl-fixed-header.admin-bar .fl-page-bar { top: var(--admin-bar-desktop); }
}

/* ── Fixed header (scrolled state) ─────────────────────────── */
.fl-page-header.rw-fixed-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 102;
}

/* KNOWN LIMITATION — re-verified at final review (Finding 1), STILL PRESENT,
   NOT closed by the >=992px fix above (verified in-browser, not fixable from
   this file — see task-7-report.md and the final-fix-report):
   bb-theme's own theme.js runs FLTheme._fixedHeader() unconditionally
   whenever body carries `.fl-fixed-header` (the Customizer "Fixed Header"
   toggle — always on for this site), because that gate checks nothing about
   `.rw-fixed-header` or this stylesheet. At widths below its
   `medium_breakpoint` (992px) it calls `header.css('top', 0)` on every
   load/resize — and ONLY on load/resize, never on scroll — so once
   `.rw-fixed-header` is added later by a scroll past 160px, that stale
   inline `top: 0` is still what's in effect. Either way it sets an INLINE
   `top` style, which wins over the two rules below regardless of their
   specificity — inline style beats any ordinary stylesheet rule, and the
   CSS priority flag that could out-rank an inline style is forbidden in
   this file. Confirmed by simulating the admin bar's DOM/geometry (no login
   required — `FLTheme._fixedHeader()` re-invoked directly with an injected
   `#wpadminbar` + `.admin-bar` class) at a 375px width with `.rw-fixed-header`
   added: the header ends up `position: fixed; top: 0` (from the inline
   style, not these rules), so the always-fixed WP admin bar (46px, z-index
   99999) visually covers the header's top 46px. This is entirely a <992px
   code path — untouched by the >=992px `position: fixed` rules added above
   for Finding 1 — so that fix does NOT close this. These two rules are kept
   because they are correct and become effective the moment that inline
   write stops happening — the real fix is JS/enqueue-level (stop
   theme.js's _fixedHeader from running, or override its inline write),
   which is out of this task's permitted file scope.

   Separately, ALSO OBSERVED at final review (simulated, same method, not
   previously documented): at >=992px logged in, `_fixedHeader()` computes
   `.fl-page`'s compensating `padding-top` (`totalHeaderHeight = barHeight +
   headerHeight`) BEFORE folding the admin-bar's +32px into `barHeight` — so
   `padding-top` stays the same (~208px) whether or not `.admin-bar` is
   present, while the header's own inline `top` correctly grows by 32px
   (`header.css('top', barHeight)`, computed after the +32). The fixed
   header therefore sits 32px lower than the reserved padding accounts for,
   overlapping the top 32px of scrolled page content for logged-in admins at
   desktop widths. Same root cause and same out-of-scope JS fix as above —
   noted here for the repo owner, not fixed. */
.admin-bar .fl-page-header.rw-fixed-header { top: var(--admin-bar-mobile); }

@media (min-width: 783px) {
    .admin-bar .fl-page-header.rw-fixed-header { top: var(--admin-bar-desktop); }
}

/* ── Logo ─────────────────────────────────────────────────── */
.fl-page-header-logo img {
    width: auto;
    height: auto;
    max-width: 100%;
    max-height: var(--logo-height);
    /* bb-theme's JS writes an inline `width` on this img (measured
       style="width: 325.961px"), which beats the `width: auto` above — inline
       styles lose only to !important, and this theme confines that to
       99-utilities.css. So on shrink the BOX stays at the full natural width
       while max-height pulls its height to 80px, and the SVG's own
       preserveAspectRatio then letterboxes the artwork and centres it in that
       too-wide box. That is the "logo drifts to the middle as it shrinks"
       symptom.

       object-fit keeps the artwork undistorted and object-position pins it to
       the left edge of the box, so it shrinks in place instead of sliding
       toward the centre. Fixing the inline width itself would mean overriding
       bb-theme's JS, not CSS. */
    object-fit: contain;
    object-position: left center;
    transition: max-height var(--header-transition);
}

.fl-page-header-logo a { display: inline-block; }


/* ── Header text / phone ──────────────────────────────────────
   Light-on-dark: the header sits on --brand. --accent is reserved
   for non-text use (the hover/focus underline), never the text
   itself. */
.rw-header-text {
    text-align: right;
    margin-bottom: var(--header-phone-gap);
    transition: margin-bottom var(--header-transition);
}

.rw-header-phone {
    color: var(--nav-text);
    font-weight: 600;
    font-size: clamp(0.875rem, 0.6rem + 1vw, 1.25rem);
    transition: font-size var(--header-transition);
}

.rw-header-phone a {
    color: var(--accent);
    transition: var(--transition-base);
}

.rw-header-phone a:hover,
.rw-header-phone a:focus-visible {
    /* FIX (final review, Finding 4): without this, 02-base.css's global
       `a:hover, a:focus { text-decoration: underline }` still applies on top
       of the border-bottom accent below — a doubled underline. The accent
       border-bottom is this link's only intended hover/focus affordance. */
    text-decoration: none;
    border-bottom-color: var(--accent-dark);
}

/* ── Desktop nav ──────────────────────────────────────────── */

/* Collision fix: ShiftNav's own toggle button (rendered in our markup by
   includes/nav-right.php via shiftnav_toggle()) has no breakpoint logic of
   its own — it is visible at every width unless something hides it. The
   archived header-nav-right.css used to do this (`.shiftnav-toggle-button {
   display: none }` at >=992px) but that file was dequeued in Task 4, so
   without this rule the toggle sits directly next to the desktop menu at
   any width >=992px (confirmed in the browser — see task-7-report.md).
   Scoped to .fl-page-nav so it only affects this header's own toggle, not
   ShiftNav elsewhere on the site — this is resolving OUR side of the
   collision, not styling ShiftNav's panel. */
@media (min-width: 992px) {
    .fl-page-nav .shiftnav-toggle-button { display: none; }
}

/* Drop Bootstrap's standalone-navbar padding.

   base-4 ships `.navbar { padding: 0.5rem 1rem }`. That is chrome for a navbar
   that is its own bar; this one sits inside .fl-page-nav-col, a grid column
   already supplying 15px gutters, so the 16px each side is a second inset that
   buys nothing and costs 32px of the row the menu has to fit into.

   Not cosmetic. .navbar-nav inherits flex-wrap: wrap from Bootstrap, so once
   the labels went uppercase the items totalled 805px against 793px available
   and "Get A Quote" dropped to a second line. Removing this padding takes the
   available width to 825px, which is what keeps the menu on one row without
   having to shrink --nav-font-size or --nav-padding-x. */
.fl-page-nav.navbar { padding: 0; }
/* Both axes, not just inline. The 0.5rem block half inflated .fl-page-nav-wrap
   to 59px, which kept the shrunk header at 111px instead of 100px — the nav
   column, not the 80px logo, was governing the height. */

.fl-page-nav .navbar-nav { align-items: center; }

.fl-page-nav .navbar-nav > li { position: relative; }

.fl-page-nav .navbar-nav > li > a.nav-link {
    position: relative;
    padding: 0 var(--nav-padding-x);
    color: var(--nav-text);
    font-size: var(--nav-font-size);
    font-weight: 600;
    text-transform: uppercase;
    transition: var(--transition-base);
}

/* Accent underline, wiped in from the left on hover/focus. A pseudo-element
   rather than border-bottom because a border cannot be transformed — and
   animating `width` would force layout on every frame, where `transform`
   is composited. Inset by --nav-padding-x so the rule spans the label, not
   the link's full padded box. */
.fl-page-nav .navbar-nav > li > a.nav-link::after {
    content: "";
    position: absolute;
    left: var(--nav-padding-x);
    right: var(--nav-padding-x);
    bottom: -2px;
    height: 2px;
    background-color: var(--accent);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.25s ease;
}

.fl-page-nav .navbar-nav > li > a.nav-link:hover::after,
.fl-page-nav .navbar-nav > li > a.nav-link:focus-visible::after {
    transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
    .fl-page-nav .navbar-nav > li > a.nav-link::after { transition: none; }
}

.fl-page-nav .navbar-nav > li > a.nav-link:hover,
.fl-page-nav .navbar-nav > li > a.nav-link:focus-visible {
    color: var(--nav-text);
    /* FIX (final review, Finding 4): these links currently escape
       02-base.css's global `a:hover, a:focus { text-decoration: underline }`
       only because base-4 happens to ship
       `.nav-link:hover,.nav-link:focus{text-decoration:none}` — a
       third-party accident, not something this file ever asserted. Assert
       it explicitly so the no-underline styling doesn't silently depend on
       base-4 continuing to ship that rule. */
    text-decoration: none;
}

/* Current page keeps the underline at rest.
   ADDED 2026-09-12: the ancestor/parent variants. WordPress only puts
   `current-menu-item` on the item whose own URL matched, so on /shooting/ the
   underline was landing on nothing visible at top level and "Services" read
   as unvisited. WP marks that parent `current-menu-ancestor current-menu-parent`
   instead, and both are matched here because the two diverge once a submenu is
   more than one level deep — the grandparent gets ancestor only.

   The :hover clause keeps the trigger lit for as long as its panel is open.
   Hovering the LI covers the whole time the cursor is down inside the panel,
   which hovering the <a> alone does not, so the underline no longer snaps off
   the moment the cursor leaves the label to pick an item. */
.fl-page-nav .navbar-nav > li.current-menu-item > a.nav-link::after,
.fl-page-nav .navbar-nav > li.current-menu-ancestor > a.nav-link::after,
.fl-page-nav .navbar-nav > li.current-menu-parent > a.nav-link::after,
.fl-page-nav .navbar-nav > li.menu-item-has-children:hover > a.nav-link::after,
.fl-page-nav .navbar-nav > li.menu-item-has-children:focus-within > a.nav-link::after,
.fl-page-nav .navbar-nav > li.menu-item-has-children.rw-submenu-open > a.nav-link::after {
    transform: scaleX(1);
}

/* ── Highlighted menu item ───────────────────────────────────
   `menu-highlight` is typed by hand into a menu item's CSS Classes field in
   Appearance > Menus, turning that item into a filled accent button. Currently
   the last item, "Get A Quote".

   Vertical padding is set here specifically because the base .nav-link rule
   above uses `padding: 0 var(--nav-padding-x)` — with no vertical padding the
   accent background would be only as tall as the text itself.

   The accent underline is suppressed rather than left to run: it is --accent
   drawn on an --accent background, so it would be invisible anyway, and the
   item already reads as emphasised without it. Both the hover and the
   current-menu-item variants are covered, or landing on Get A Quote would
   paint a permanent invisible bar under it.

   Radius reuses --card-border-radius so this matches the .btn family in
   02-base.css rather than inventing a second button shape. */
.fl-page-nav .navbar-nav > li.menu-highlight > a.nav-link {
    /* Asymmetric on purpose — do not "tidy" this back to a symmetric pair.
       The label is uppercase, so it has no descenders and its visual mass sits
       high in the line box; matching the top and bottom padding numerically
       leaves it looking as though it has settled toward the top. The extra
       0.08rem underneath balances it optically. */
    padding: 0.6rem var(--nav-padding-x) 0.68rem;
    border-radius: var(--card-border-radius, 4px);
    background-color: var(--accent);
    color: var(--white);
}

.fl-page-nav .navbar-nav > li.menu-highlight > a.nav-link:hover,
.fl-page-nav .navbar-nav > li.menu-highlight > a.nav-link:focus-visible {
    background-color: var(--accent-dark);
    color: var(--white);
}

.fl-page-nav .navbar-nav > li.menu-highlight > a.nav-link::after {
    /* Unqualified on purpose: `display: none` on the base selector already
       suppresses every state variant (current-menu-item, current-menu-ancestor,
       :hover, :focus-within), because none of those rules re-declare `display`.
       The old paired selector listing current-menu-item explicitly was
       redundant then and would have needed extending three more times now. */
    display: none;
}

/* ── Submenu ────────────────────────────────────────────────
   REWRITTEN 2026-09-12. Open/close is now driven from CSS state
   (:hover / :focus-within) by this file, and the parent theme's JS
   dropdown is neutralised by rw/shared-js/rw-nav-dropdown.js. Read that
   file's header before changing anything below — the two halves are one
   mechanism and the CSS alone is not safe to reason about.

   WHY THE REWRITE, i.e. the bug this fixes:

   The previous version of this block closed the panel with `display: none`
   and left opening to the parent theme. That is what made the dropdowns open
   and then never close.

   bb-theme never hides a submenu with `display`. Its own CSS parks the panel
   off-screen at `left: -99999px` (bb-theme/less/theme.less:413) and reveals
   it by moving it back (`.fl-sub-menu-open > ul.sub-menu { left: auto }`,
   :452). Its close handler ends with `$(this).show()`
   (bb-theme/js/theme.js:740) — which upstream is harmless, because the panel
   it re-shows is still parked off-screen where nobody can see it.

   Against THIS file's `display: none`, that same line is fatal. jQuery's
   .show() clears the inline display, finds the element still hidden by the
   stylesheet, and therefore writes `display: block` inline as the element's
   "default" display. An inline style beats a stylesheet rule, so the panel
   was pinned open permanently, and every subsequent mouseleave just rewrote
   the same inline style. Opens on hover, never closes.

   So: no `display` toggling in this file, ever. The closed state below is
   opacity + visibility + pointer-events, which has the side benefit of
   defusing that .show() line entirely — it writes nothing when the element's
   computed display is not `none` — and, unlike `display`, is animatable.
   That is what makes the fade-and-rise possible at all; jQuery's fadeIn/
   fadeOut were writing inline opacity every frame and would have fought any
   transition declared here.

   Desktop only, and deliberately so. ShiftNav's inline #shiftnav-dynamic-css
   hides .fl-page-nav-collapse outright at 991px and below, so this
   menu does not exist at mobile widths and needs no accordion behaviour —
   the off-canvas panel is a separate component. */

.fl-page-nav .navbar-nav > li.menu-item-has-children > a.nav-link {
    /* The panel is reachable by pointer, so the trigger must not claim to be
       a button. aria-expanded is maintained on it by rw-nav-dropdown.js. */
    cursor: pointer;
}

/* BB emits an empty <div class="fl-submenu-icon-wrap"><span
   class="fl-submenu-toggle-icon"></span></div> between the trigger and the
   <ul> on every parent item. The approved design has no caret, and left
   unstyled the wrapper is a block-level element inside a flex row. Hidden
   rather than deleted — it is walker output, not ours to remove. */
.fl-page-nav .fl-submenu-icon-wrap { display: none; }

/* Hover bridge.
   The panel is offset --nav-submenu-gap below the nav bar, and that gap is
   dead space: crossing it would fire mouseleave on the <li> and shut the
   panel before the cursor arrived. This pseudo-element extends the li's own
   hover area down across the gap. It must live on the LI and not on the
   panel — the panel is pointer-events: none while closed, so a bridge drawn
   on it would be unreachable exactly when it is needed. */
.fl-page-nav .navbar-nav > li.menu-item-has-children::before {
    content: "";
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    height: calc(var(--nav-submenu-gap) + var(--nav-submenu-rise));
}

.fl-page-nav ul.sub-menu {
    position: absolute;
    top: calc(100% + var(--nav-submenu-gap));
    left: 0;
    z-index: 1000;

    margin: 0;
    padding: 0.5rem 0;
    min-width: var(--nav-submenu-width);
    list-style: none;

    background-color: var(--nav-submenu-bg);
    border-radius: var(--nav-submenu-radius);
    box-shadow: var(--nav-submenu-shadow);

    /* Closed. See the block comment above for why this is not `display`. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(calc(var(--nav-submenu-rise) * -1));

    /* visibility is stepped, not eased, and its 0s transition is DELAYED by
       the full duration on close so the panel stays hittable for the whole
       fade-out instead of vanishing on frame one. The open rule below resets
       that delay to 0s so it becomes visible immediately. This is the
       standard pairing for animating a hidden element without `display`. */
    transition: opacity var(--nav-submenu-duration) ease,
                transform var(--nav-submenu-duration) ease,
                visibility 0s linear var(--nav-submenu-duration);
}

/* Open.
   :focus-within earns keyboard support for free — tabbing into the trigger
   opens the panel, tabbing past its last child closes it, with no JS
   involved.

   .rw-submenu-open is the touch path (rw-nav-dropdown.js): on a coarse
   pointer the first tap opens rather than navigates, and that needs a real
   state to hold the panel open. It cannot lean on :hover — iOS's synthesised
   hover is incidental behaviour, not a contract, and it survives only until
   the next tap lands somewhere else. */
.fl-page-nav .navbar-nav > li.menu-item-has-children:hover > ul.sub-menu,
.fl-page-nav .navbar-nav > li.menu-item-has-children:focus-within > ul.sub-menu,
.fl-page-nav .navbar-nav > li.menu-item-has-children.rw-submenu-open > ul.sub-menu {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
    transform: translateY(0);
    transition: opacity var(--nav-submenu-duration) ease,
                transform var(--nav-submenu-duration) ease,
                visibility 0s linear 0s;
}

/* Right-edge collision.
   Set by rw-nav-dropdown.js when a panel's natural left-aligned position
   would run past the viewport, which the rightmost dropdown ("About") does
   at every width it exists at, 992-1280px: the nav is right-aligned, so the
   distance from
   that item's left edge to the screen edge is fixed by the widths of the
   items beside it rather than by the viewport, and --nav-padding-x steps
   down to 15px at 1280 and 10px at 1100 while --nav-font-size steps down
   too. Every one of those pulls the item rightwards while the panel stays
   --nav-submenu-width wide. Measured clearance at 1504px is only 22px, and
   the steps consume well over that.

   Anchored to the item's right edge rather than nudged by a calculated
   offset: the panel then sits under the item it belongs to no matter how
   narrow the viewport, and needs no second measurement to stay correct.

   This is measured rather than expressed as a media query or an :nth-child
   guess because the trigger is the menu's own text — rename "Gear Rentals"
   or add an item and the crossover width moves. bb-theme's equivalent
   (.fl-sub-menu-right) is NOT reused: nothing sets it any more, since the
   code that did was the JS this theme switches off. */
.fl-page-nav .navbar-nav > li.menu-item-has-children.rw-submenu-flip > ul.sub-menu {
    left: auto;
    right: 0;
}

/* Escape sets this on the li (rw-nav-dropdown.js) to force the panel shut
   while the cursor is still inside it — :hover cannot be cancelled from
   script, so the close has to be expressed as something that outranks it.
   Dropped again on the next mouseenter so hovering back in still works.

   .menu-item-has-children is carried here purely to match the specificity of
   the open rule above (0,5,2); without it this is (0,4,2) and loses to
   :hover, which is the one case it exists to beat. Source order then decides,
   which is why this block must stay BELOW the open rule. */
.fl-page-nav .navbar-nav > li.menu-item-has-children.rw-submenu-dismissed > ul.sub-menu {
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(calc(var(--nav-submenu-rise) * -1));
}

/* ── Submenu items ──────────────────────────────────────────
   Typographically a quieter echo of the top-level links: same family and
   uppercase treatment, one step down in size and weight so the panel reads
   as subordinate to the bar it hangs from. */
.fl-page-nav ul.sub-menu li { position: relative; }

.fl-page-nav ul.sub-menu li a.nav-link {
    position: relative;
    display: block;
    /* Asymmetric: the underline sits 4px below the label's box, so the row
       needs that much more beneath the text than above it to stay optically
       centred and to keep the rule clear of the next item. */
    padding: 0.5rem 1.35rem 0.65rem;
    color: var(--nav-submenu-text);
    font-size: calc(var(--nav-font-size) - 1px);
    font-weight: 600;
    line-height: 1.35;
    text-transform: uppercase;
    letter-spacing: 0.01em;
    white-space: nowrap;
    transition: background-color var(--nav-submenu-duration) ease,
                color var(--nav-submenu-duration) ease;
}

/* The one piece of brand colour in the panel, and the same gesture the
   top-level links make: a rule wiped in from the left on transform rather
   than on width, so it composites instead of forcing layout.

   Drawn on .rw-nav-label, an inline <span> the theme wraps the link text in
   (rw_wrap_submenu_item_label() in functions.php), NOT on the <a>. The <a> is
   block-level so the whole row is clickable, which also makes it panel-wide —
   a rule on it would run the full width of the panel regardless of how short
   the label is. The span is inline, so it is exactly as wide as the text and
   the underline stops where the word does, as the design requires and as the
   top-level links already do.

   If that filter is ever removed the span disappears and these links simply
   lose their underline. Nothing else about the panel depends on it. */
.fl-page-nav ul.sub-menu li a.nav-link .rw-nav-label {
    position: relative;
    display: inline-block;
}

.fl-page-nav ul.sub-menu li a.nav-link .rw-nav-label::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: -4px;
    height: 2px;
    background-color: var(--accent);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.24s ease;
}

.fl-page-nav ul.sub-menu li a.nav-link:hover,
.fl-page-nav ul.sub-menu li a.nav-link:focus-visible {
    background-color: var(--nav-submenu-hover);
    color: var(--nav-submenu-text);
    /* Same reason as the top-level links: assert it rather than inherit it by
       accident from base-4's .nav-link reset. The underline below is the
       hover affordance; a text-decoration one would double it. */
    text-decoration: none;
}

.fl-page-nav ul.sub-menu li a.nav-link:hover .rw-nav-label::after,
.fl-page-nav ul.sub-menu li a.nav-link:focus-visible .rw-nav-label::after {
    transform: scaleX(1);
}

/* Current page keeps its underline at rest, matching the top-level bar. */
.fl-page-nav ul.sub-menu li.current-menu-item > a.nav-link .rw-nav-label::after {
    transform: scaleX(1);
}

@media (prefers-reduced-motion: reduce) {
    .fl-page-nav ul.sub-menu,
    .fl-page-nav ul.sub-menu li a.nav-link,
    .fl-page-nav ul.sub-menu li a.nav-link .rw-nav-label::after {
        transition: none;
    }
    /* Without the rise the panel would still jump 6px on open. Land it flat. */
    .fl-page-nav ul.sub-menu { transform: none; }
    .fl-page-nav .navbar-nav > li.menu-item-has-children:hover > ul.sub-menu,
    .fl-page-nav .navbar-nav > li.menu-item-has-children:focus-within > ul.sub-menu,
    .fl-page-nav .navbar-nav > li.menu-item-has-children.rw-submenu-open > ul.sub-menu {
        transform: none;
    }
}

/* ═══════════════════════════════════════════════════════════
   RESPONSIVE HEADER — 2026-09-05 diagrams
   The nav font-size and padding steps are NOT here: they are token
   redefinitions in 01-tokens.css, because every rule above already reads
   --nav-font-size / --nav-padding-x. Only geometry lives in this block.
   ═══════════════════════════════════════════════════════════ */

/* Full-width header content.
   The diagrams put the logo ~48px from the left edge and the CTA ~48px from
   the right at 1920px, and ~45px at 1024px — i.e. the header spans the
   viewport rather than sitting in the 1140px .container the rest of the site
   uses. Overriding the container here rather than changing the markup keeps
   page.php and the Customizer untouched.

   This is also what makes the diagram's 20px nav padding viable at 1920px:
   capped at 1140px the menu needed 870px against 825px available and wrapped,
   which is why --nav-padding-x had been tightened to 14px. Full width restores
   the room, so the spec's stepped 20/15/10 values fit as drawn. */
.fl-page-header-container.container {
    max-width: none;
    padding-inline: var(--page-pad-inline);
}

/* ── Shrink on scroll, desktop only ──────────────────────────
   .rw-fixed-header is added to .fl-page-header by rw/shared-js/rw-jquery.js
   once the page scrolls past 160px (a Waypoints handler). It already existed
   and already drove --logo-width-fixed; these rules give it the 100px height
   from the diagram.

   Height comes from the logo plus padding rather than an explicit height on
   the header: 10px + 80px + 10px. The logo is capped by --logo-height in both
   states (see the Logo block above), so the shrink is a single max-height
   swap, which is also what makes it animatable.

   Below 992px the header is a flat 100px at all times (see the block after
   this one), so the shrink is gated to desktop to avoid the two fighting. */
@media (min-width: 992px) {
    /* NOTE: .fl-page-header and .fl-page-header-primary are the SAME element —
       both classes sit on the <header> (see includes/nav-right.php). Writing
       `.fl-page-header.rw-fixed-header .fl-page-header-primary` makes a
       descendant selector that matches nothing, which is exactly the mistake
       this comment exists to stop being repeated. */
    .fl-page-header.rw-fixed-header {
        padding-top: var(--header-pad-block);
        padding-bottom: var(--header-pad-block);
    }

    .fl-page-header.rw-fixed-header .fl-page-header-logo img {
        max-height: var(--logo-height-scrolled);
    }

    /* "Vertical padding / margin between elements in Nav Col reduces as needed
       to fit 100px height" — the diagram's own note. The logo is 80px once
       shrunk, but the nav column stacks the phone above the menu and measured
       91px, which drove the header to 111px. Closing the gap and pinning the
       phone size brings the column under 80px so the logo governs the height. */
    .fl-page-header.rw-fixed-header .fl-page-nav-col { gap: 0; }
    .fl-page-header.rw-fixed-header .rw-header-text {
        margin-bottom: var(--header-phone-gap-scrolled);
    }
    .fl-page-header.rw-fixed-header .rw-header-phone { font-size: 0.875rem; }
}

/* ── Below the nav breakpoint ────────────────────────────────
   The diagrams jump from 992px (desktop menu) straight to 768px (hamburger),
   leaving 769-991px undrawn. Applied from 991px down, so the layout changes at
   exactly the point the desktop menu gives way to the toggle — rather than at
   768px, which would leave a 223px band with neither layout. Flagged as an
   assumption; move the breakpoint if the diagrams meant it literally.

   Header is a flat 100px here and does NOT shrink on scroll, per the note on
   the 768px frame. */
@media (max-width: 991px) {
    /* Flat 100px. min-height rather than height so the header can still grow
       if the phone number wraps on a very narrow screen; measured without it
       the content only came to 84-89px and the bar looked short of the spec. */
    .fl-page-header-primary {
        display: flex;
        align-items: center;
        min-height: var(--header-height-scrolled);
        padding-top: var(--header-pad-block);
        padding-bottom: var(--header-pad-block);
    }

    .fl-page-header-primary > .fl-page-header-wrap { width: 100%; }

    /* 33.33% / 66.67% split. Both columns are col-md-12 in the markup, so
       without this they are full width and stack. */
    .fl-page-header-row .fl-page-header-logo-col {
        flex: 0 0 33.33333%;
        max-width: 33.33333%;
    }

    .fl-page-header-row .fl-page-nav-col {
        flex: 0 0 66.66667%;
        max-width: 66.66667%;
    }

    /* Logo fills its column instead of using --logo-width. That token bottoms
       out at 380px, which is wider than the whole 33% column below ~1140px —
       it would overflow. Filling the column also reproduces the diagrams,
       where the logo shrinks steadily from 768px down to 320px. */

    /* Phone above, toggle and CTA below, both right-aligned. */
    .fl-page-nav-col {
        display: flex;
        flex-direction: column;
        align-items: flex-end;
        justify-content: center;
    }

    /* The toggle and the collapse are siblings inside nav.fl-page-nav, so one
       flex row puts the hamburger and the CTA side by side as drawn. */
    .fl-page-nav {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-end;
        flex-wrap: nowrap;
        gap: var(--gutter);
    }

    /* THE MOBILE CTA IS NOW THE MENU ITEM, not a second element.
       includes/nav-right.php used to render a standalone <a class="rw-header-cta">
       because ShiftNav hid the whole collapse below 990px with !important, so
       nothing inside it could be revealed. That element duplicated the menu
       item's URL and label as hardcoded strings in the template, which is the
       part that could silently drift when the page was renamed.

       With ShiftNav gone the collapse is only hidden by 02-base.css's
       `.collapse:not(.show)` at 0-2-0. `.fl-page-nav-collapse.collapse` ties
       that and wins on source order (this file loads after 02-base.css), so no
       !important is needed to bring it back. */
    .fl-page-nav-collapse.collapse {
        display: flex;
        /* base-4 gives .navbar-collapse flex-basis:100%, which would drop it
           onto its own row under the toggle. */
        flex-basis: auto;
        flex-grow: 0;
    }

    /* Everything except the CTA stays hidden — those items are in the
       off-canvas panel. */
    .fl-page-nav-collapse .navbar-nav > li:not(.menu-highlight) {
        display: none;
    }

    .fl-page-nav-collapse .navbar-nav {
        flex-direction: row;
    }

    /* Sized to the header, not to the desktop button. The full .btn is 54px
       tall and pushed the header to 117px against the 100px the diagrams
       specify; at this size the phone (~28px) and the toggle row (~38px) fit
       the 80px content box left by the 10px padding.

       The optical correction is the same idea as the desktop button but scaled
       to this type size rather than copied: uppercase has no descenders, so
       equal top and bottom padding reads as top-heavy. The desktop button adds
       1.28px under a 15px label (~0.085em), so at 12px that is ~1.02px. */
    .fl-page-nav .navbar-nav > li.menu-highlight > a.nav-link {
        padding: 0.55rem 1.1rem 0.61rem;
        font-size: 0.75rem;
    }

    /* Remove the inherited gap between the phone and the toggle row; the
       column's own gap controls the spacing here. */
    /* The 30px desktop gap does not fit the 100px mobile header; the column's
       own 4px gap spaces the phone from the toggle row instead. */
    .fl-page-nav-col > .rw-header-text { margin-bottom: 0; }
    .fl-page-nav-col { gap: 4px; }

    /* Flat, not clamped. The desktop clamp reaches 19.5px by 991px, which took
       the header to 110px against the specified 100px; pinned here it lands on
       100px at every width from 320 to 991. */
    .rw-header-phone { font-size: 0.875rem; }
}


/* ── Off-canvas menu (rw-offcanvas-nav) ──────────────────────
   THESE TWO RULES ARE THE THEME'S HALF OF THE OFF-CANVAS MENU, and they live
   here rather than in the plugin on purpose: the plugin has to work on 150+
   sites running different themes, so it cannot know that this theme's desktop
   navigation is called `.fl-page-nav-collapse`. Guessing is precisely how
   ShiftNav ended up injecting `display: none !important` against that class —
   which is also why the mobile CTA below had to be a separate element rather
   than the .menu-highlight menu item.

   No !important is needed now, because nothing is competing: ShiftNav's
   injected stylesheet is gone and these are the only rules with an opinion.

   991px matches the breakpoint ShiftNav used, so the handover point does not
   move during the migration. */
/* 992px, NOT 991. The old pair hid the toggle at min-width:991 while base-4
   only reveals the desktop nav at min-width:992 — so at exactly 991px there was
   neither a menu nor a toggle. ShiftNav shipped the same 990/991 split, so that
   dead pixel was inherited faithfully along with everything else. Matching
   Bootstrap's own lg breakpoint closes it.

   There is no `display: none` on the collapse here, and there does not need to
   be: 02-base.css supplies `.collapse:not(.show) { display: none }` (base-4
   ships .navbar-collapse but none of the collapse primitives), which already
   hides it at every width. base-4 then reveals it from 992px up with
   `.navbar-expand-lg .navbar-collapse { display: flex !important }`. The rule
   that used to sit here was redundant with both. */
@media (min-width: 992px) {
    .rw-offcanvas-toggle {
        display: none;
    }
}

/* Panel palette, assigned from this theme's tokens rather than left on the
   plugin's defaults. The plugin ships defaults that already match this design,
   so this rule changes nothing today — it exists so a palette swap reaches the
   menu like it reaches everything else, instead of leaving hardcoded hexes
   stranded inside a plugin.

   --rw-nav-bg is NOT assigned here: #001624 is not in this theme's palette
   (it is darker than --brand-dark), so it stays site-specific and lives in
   90-agape.css with the other one-site values. */
.rw-offcanvas-panel {
    --rw-nav-item-bg:         var(--brand-dark);
    --rw-nav-item-bg-hover:   var(--brand-light);
    --rw-nav-item-bg-current: var(--accent);
    --rw-nav-item-color:      var(--white);
}

/* The header toggle. Colour only — the plugin draws the bars. */
.rw-header-toggle {
    color: var(--neutral-400);
    margin-right: var(--spacing-md);
}

.rw-header-toggle:hover,
.rw-header-toggle:focus-visible {
    color: var(--brand);
}
