/* ==========================================================================
   BGI Compact Mobile Header Bar
   --------------------------------------------------------------------------
   The single source of truth for the <992px public-site header bar:

       [burger] [search]        <centred logo>        [account] [cart]

   Loaded by BOTH header stacks, which must stay byte-identical:
     - Slim/Twig pages  templates/web/site_base.twig (markup:
                        templates/web/header/site_mobile_bar.twig)
     - Legacy osC pages www4.gifts.ie/media/{GIE,GTS}/stylesheets.php (markup:
                        www4.gifts.ie/media/shared/mobile_header_bar.php)

   EDITING THIS FILE? BUMP THE CACHE TOKEN. Currently v2.

   Every edit here requires bumping the ?<CDN_CACHE>vNN token in ALL THREE
   referencing files, in the SAME commit:
       templates/web/site_base.twig
       www4.gifts.ie/media/GIE/stylesheets.php
       www4.gifts.ie/media/GTS/stylesheets.php

   Skip it and the change is invisible in browsers for up to 4 hours
   (Cache-Control: max-age=14400), in the most misleading way possible: the
   deploy succeeds, the file on the server genuinely contains the edit, and
   grepping it on the box proves it — while the page keeps rendering the OLD
   CSS behind a `cf-cache-status: HIT`. Everything checks out except what you
   actually see, so the obvious conclusion ("it didn't deploy") sends you
   looking in entirely the wrong place. This exact thing happened at v1.

   Bumping requests a NEW URL, so it sidesteps the CDN rather than needing a
   Cloudflare purge. A brand-new file is correct at v1 — but the first edit
   after it has been deployed makes v1 stale, and it must go to v2.

   The tokens must also match ACROSS the three files, or the Slim and legacy
   stacks load different cached copies of this stylesheet and the two headers
   drift apart. Same convention as nav-megamenu.css / nav-mobile-drawer.css.

   Two house rules this file obeys:
     - px ONLY. Bootstrap 3 sets html{font-size:10px} on the public site, so
       1rem = 10px and every rem value is silently wrong. Never introduce rem.
     - box-sizing:border-box is in force on both stacks (Tailwind preflight on
       Slim pages, Bootstrap 3 on legacy pages), so `height` INCLUDES padding.
       The 56px logo box therefore holds 46px of visible logo — that is the
       intended arithmetic, not an off-by-padding bug.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Brand colour
   --------------------------------------------------------------------------
   --color-primaryColor is emitted by the compiled Tailwind bundle, which ONLY
   the Slim pages load. Legacy osC pages instead define --theme-primaryColor
   (see media/GIE/stylesheets.php and media/GTS/stylesheets.php), fed from the
   per-site DB theme. The chain below lets one file serve both stacks.

   The last resort is `currentColor`, deliberately NOT a brand literal. GTS
   resolves to its own blue through the DB theme, so hardcoding gifts.ie red
   here would paint greetings.ie the wrong colour on any page where the
   variables go missing. Degrading to the inherited text colour instead is
   visually neutral and fails quietly in the right direction. Matches the same
   chain used by the legacy partial's inline styles in
   media/shared/mobile_header_bar.php — keep the two in step.

   If you ever see icons rendering as body text colour, the bug is a missing
   variable upstream, not this line.
   -------------------------------------------------------------------------- */

/* Outer bar: left cluster | flexible centred logo | right cluster */
.bgi-mhdr-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 4px;
}

/* Both side clusters share the SAME min-width so the logo stays optically
   centred whether or not the cart icon is present. */
.bgi-mhdr-side {
    display: flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 4px;
    min-width: 96px;
}
.bgi-mhdr-side--left  { justify-content: flex-start; }
.bgi-mhdr-side--right { justify-content: flex-end; }

.bgi-mhdr-centre {
    display: flex;
    flex: 1 1 auto;
    min-width: 0;
    align-items: center;
    justify-content: center;
}

/* Identical 44x44 tap target for every icon — burger, search, account, cart. */
.bgi-mhdr-cell {
    display: inline-flex;
    flex: 0 0 44px;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    font-size: 22px;
    line-height: 1;
    /* Tailwind var (Slim) → DB-theme var (legacy) → inherited colour.
       No brand literal on purpose. See "Brand colour" above before touching. */
    color: var(--color-primaryColor, var(--theme-primaryColor, currentColor));
}

/* Glyphs inherit their size from the cell so all four match exactly. */
.bgi-mhdr-cell i,
.bgi-mhdr-cell svg {
    font-size: inherit;
    line-height: 1;
}

/* The account + cart partials nest their real interactive target 2-3 levels
   deep, so without this the tap target is only the ~22px glyph while the
   burger/search buttons ARE their own 44px cell. Stretch every level of the
   chain so the whole 44x44 cell is tappable and all four behave alike.

   The emitted nesting (iconStyle: 'plain'), verified against the partials:
     cart              .bgi-header-cart > a
     account, guest    div.relative > div[title="Login"] > a
     account, signed-in  div.js-account-menu > div[title="My Account"] > span.js-account-toggle

   Every selector is a DIRECT-CHILD chain, and the level-2 step is qualified
   with [title], on purpose:
     - .js-account-dropdown is also a div child of .js-account-menu. A generic
       `> div > div` would outrank its `.hidden` utility (0,2,0 vs 0,1,0) and
       force the dropdown permanently open. It carries no title attribute, so
       [title] excludes it.
     - the dropdown's own menu links must keep `block px-4 py-1 text-gray-700`;
       a bare `.bgi-mhdr-cell a` would centre and recolour them.
   No `position` is set here — .js-account-menu keeps its own `relative`, which
   anchors the absolutely-positioned dropdown. No `overflow` is set either:
   stretching the anchor to fill the cell moved the cart pill's positioning
   context off the 22px glyph, so the partial now offsets it top:5px; right:3px
   — wholly INSIDE the 44x44 cell — and clipping is no longer a concern. Do not
   introduce `overflow:hidden` on any level of this chain regardless. */
.bgi-mhdr-cell > div,
.bgi-mhdr-cell > div > div[title],
.bgi-mhdr-cell > div > a,
.bgi-mhdr-cell > div > div[title] > a,
.bgi-mhdr-cell > div > div[title] > .js-account-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    color: inherit;
    line-height: 1;
}

/* Bare button reset (no Bootstrap-3 navbar-toggle chrome). */
.bgi-mhdr-btn {
    margin: 0;
    padding: 0;
    background: transparent;
    border: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
}

/* --------------------------------------------------------------------------
   Legacy header background
   --------------------------------------------------------------------------
   Owner request 2026-08-20: the header should read the same on both stacks.
   Measured on beta beforehand — Slim/Twig pages are gray-50 at BOTH
   breakpoints, inherited from `body.bg-gray-50` (site_base.twig), while legacy
   pages are pure white because their <body> carries no class and no background
   rule. This gives the legacy header region the same colour explicitly.

   #f9fafb IS Tailwind's gray-50 — the same colour Tailwind 4 emits as
   oklch(0.985 0.002 247.839). Hex on purpose: universal browser support, and
   legacy pages never load the Tailwind bundle that defines the oklch value.

   COUPLED TO THE SLIM BODY CLASS. If `body.bg-gray-50` in
   templates/web/site_base.twig ever changes, change this with it or the two
   stacks drift apart again — which is the whole thing this file exists to stop.

   Slim is untouched by this: these two helpers appear ONLY on legacy pages
   (the audit grep below returns no hits under templates/), and the Slim body
   already supplies the identical colour. One stack inherits it, the other
   states it, both land on the same value.

   Scoped to the header region ONLY, as asked. Legacy page bodies stay white
   BELOW the header. Making whole legacy pages match would mean setting
   `body`, a broader change to the checkout flow that has NOT been approved.

   Note this deliberately gives the visibility helpers a second job (they hide
   AND they paint). That is sound here because on legacy those wrappers ARE the
   header region — but it does mean a future non-header use of either helper
   would arrive with an unwanted background. If that ever happens, split the
   background onto its own class rather than adding overrides at the call site.

   Two known bare patches this does NOT cover — both outside this file's reach,
   both reported rather than silently papered over:
     - GTS: the Trustpilot strip in media/GTS/header/header.php sits inside
       <header> but outside both wrappers, so it stays white at every width.
     - GTS desktop: .header-top and .header-nav paint themselves #009fd6
       (pw_style.css:182, :134), so the grey behind them is largely unseen.
   -------------------------------------------------------------------------- */
.bgi-mhdr-desktop-only,
.bgi-mhdr-mobile-only {
    background-color: #f9fafb;
}

/* --------------------------------------------------------------------------
   Mobile logo sizing
   --------------------------------------------------------------------------
   #header-div-mobile is emitted by templates/web/header/header_col1_logo.twig
   (align='center' branch) and by the legacy mobile bar partial. The sibling
   #header-div rule (50px box, shared with the checkout header) deliberately
   stays in header_col1_logo.twig — it is NOT part of the mobile bar and must
   not be resized here.

   56px box / 5px padding = 46px of visible logo (border-box; see the note at
   the top of this file). Boundary mirrors the header's mobile↔desktop swap.

   Why the rule needs every one of its declarations — do not strip any:

     height:56px      LOAD-BEARING, this is the actual fix. logo.svg has an
                      intrinsic RATIO (300x102, from its viewBox) but no
                      intrinsic SIZE. For such a replaced element `width:auto`
                      resolves against the containing block — fine in the old
                      fixed-width w-[50%] column, but the centre cell of the
                      mobile bar is a shrink-to-fit flex item with an
                      indefinite width, so width:auto resolved to 0 and the
                      logo rendered 0px wide, i.e. invisible (measured on beta:
                      0w x 10h, the 10h being this padding). max-height alone
                      CANNOT fix that: with no definite width there is no ratio
                      to apply. A definite height gives the ratio something to
                      resolve from.
     width:auto       lets that ratio produce the width (135px at this height).
     max-width:100%   narrow-phone protection: the centre cell shrinks as the
     object-fit:      two 96px icon clusters take their share — only 89px wide
       contain        at a 320px viewport, narrower than the logo's natural
                      135px. Without these the logo overflows horizontally.
                      max-width alone would SQUASH it, because the ratio is not
                      preserved once `height` is specified rather than auto;
                      object-fit:contain letterboxes instead.
     max-height:56px  belt-and-braces cap.

   Verified on beta with Playwright: 390px viewport → logo 135x56 inside a
   159px centre cell, optically centred, no horizontal overflow; 320px viewport
   → logo scales to 89x56 with the ratio preserved, still centred, no overflow.
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {
    #header-div-mobile img {
        height: 56px;
        max-height: 56px;
        width: auto;
        max-width: 100%;
        object-fit: contain;
        padding-top: 5px;
        padding-bottom: 5px;
    }
}

/* --------------------------------------------------------------------------
   Legacy fallback search row
   --------------------------------------------------------------------------
   #bgi-mobile-search-row is the collapsed row below the bar, revealed ONLY
   when the full-screen Algolia overlay is absent (SEARCH_PROVIDER is not
   algolia, or its app id / search key are unset). On legacy pages it wraps
   each site's PRE-EXISTING mobile-search partial, and those partials still
   carry the visibility rules they had back when they were permanent,
   always-visible rows of the old header:

     GIE  media/GIE/header/extras/mobile-search.php
          <div class="container-fluid visible-xs-block d-block d-sm-none">
     GTS  media/GTS/header/extras/doofinder-mobile-search.php
          <div id="mobile_search">

   Inside this wrapper the row's own display toggle (set inline by the script
   in the bar partial) must be the ONLY thing deciding visibility. Hence:

   Why !important is genuinely required — do not "simplify" this to plain
   specificity. On GIE the hiding declaration is Bootstrap 3's
   `.visible-xs-block { display: none !important; }` (bootstrap.css:6633),
   which BS3 relaxes to `block !important` only inside @media (max-width:767).
   So from 768px up the partial is display:none with !important behind it, and
   NO amount of specificity beats an !important declaration — only another
   !important can.

   NOTE the mechanism is BS3, not the `.d-block d-sm-none` classes also sitting
   on that element: both legacy sites load Bootstrap 3.4.1 ONLY (see
   media/{GIE,GTS}/stylesheets.php), and BS3 defines no `.d-*` display
   utilities at all, so those two classes are inert here. If a BS4/5 bundle is
   ever added to these pages, `.d-sm-none` becomes live and also !important —
   this rule already covers that case.

   One rule covers BOTH sites. The GTS partial's root IS a direct div child of
   the wrapper, so it matches too, and the !important here outranks
   pw_style.css:245 `#header.gts-header #mobile_search { display: none; }`
   which carries no !important — an !important declaration wins over a
   non-important one regardless of the specificity on either side. A separate
   three-id `#header #bgi-mobile-search-row #mobile_search` chain was
   considered and deliberately NOT added: against the current non-important
   pw_style rule it is redundant, and if that rule ever gained !important a
   plain id chain would lose to it anyway, so it hedges nothing.

   This cannot leak a search row onto a normal page. When the Algolia overlay
   IS present the wrapper keeps its inline display:none, and a display:none
   ancestor hides its whole subtree no matter what the children declare.

   Belt-and-braces, not the sole mechanism: nav-mobile-drawer.css (v14) already
   forces both partials visible below 992px via
   `header .container-fluid.visible-xs-block` and
   `#header.gts-header #mobile_search`, and both fallback rows do sit inside
   the required ancestors (<header> on GIE, #header.gts-header on GTS). Those
   drawer rules were written for the OLD permanent row, which has since been
   removed from both headers — so they now read like dead code and are a
   plausible future deletion. This rule makes the fallback row's behaviour
   self-contained so that deletion stays harmless.
   -------------------------------------------------------------------------- */
#bgi-mobile-search-row > div {
    display: block !important;
}

/* --------------------------------------------------------------------------
   Visibility helpers
   --------------------------------------------------------------------------
   992px is the site-wide mobile↔desktop boundary — the same line the megamenu
   (nav-megamenu.css) and the off-canvas drawer (nav-mobile-drawer.css) switch
   on, and the same one the Slim header expresses as Tailwind's `min-[992px]:`
   utilities.

   These two classes exist for the LEGACY stack, which has only Bootstrap 3
   (breakpoints 576/768/992 under different names, none of which express "hide
   at exactly this boundary" cleanly) and no Tailwind at all. Slim pages can
   keep using the `min-[992px]:` utilities; using these there instead is fine
   and equivalent.

   HOW TO APPLY THEM — always wrap in a fresh div whose ONLY class is the
   helper. Never add the helper to an existing styled element:

       <div class="bgi-mhdr-desktop-only">    <!-- correct -->
           <div class="header-nav"> ... </div>
       </div>

       <div class="header-nav bgi-mhdr-desktop-only">   <!-- do NOT do this -->

   Both declarations below are plain single-class selectors (0,1,0) with no
   !important, so ANY id-scoped `display` rule in the legacy stylesheets beats
   them. pw_style.css is full of `#header.gts-header .thing` chains at 2,1,0 —
   put the helper on one of those elements and it silently loses, leaving a
   desktop-only strip visible on mobile with nothing obviously wrong in either
   file. A bare wrapper cannot lose that race: nothing in any stylesheet selects
   a bare `.bgi-mhdr-desktop-only`, and an id-chain targeting the child cannot
   reach its parent. This holds no matter what the surrounding CSS declares, so
   it is the rule to follow rather than grepping each time.

   Do NOT "fix" a losing helper by adding !important here — that would apply to
   every use site to paper over one bad one. Move the class to a wrapper.

   There are four use sites, all bare wrappers: two in media/GTS/header/
   header.php, one in media/GIE/header/header.php, one in
   media/shared/mobile_header_bar.php. Line numbers are deliberately NOT cited
   — three of the four moved twice on the day this was written, and a wrong
   line number is worse than none.
   Re-locate them, AND audit compliance with the rule above, using:

     grep -rn 'class="[^"]*bgi-mhdr-\(desktop\|mobile\)-only[^"]*"' www4.gifts.ie/media/ templates/

   Read the output directly: any hit whose class attribute contains ANYTHING
   besides the helper is the bug, and the offending class is visible in the
   matched line. A clean run shows only bare `class="bgi-mhdr-*-only"`.

   Two simpler-looking greps that do NOT work — both were tried and rejected:
     - Matching the bare class name (no `class="..."` wrapper) also hits the
       PHP comments and the `<!--/bgi-mhdr-desktop-only-->` close markers in
       those headers: 11 hits, only 4 of them elements. Noisy enough that a
       reader stops trusting it.
     - Anchoring the attribute exactly, class="bgi-mhdr-\(desktop\|mobile\)-only",
       gives a clean 4 — but it silently MISSES the very failure it exists to
       catch, because class="header-nav bgi-mhdr-desktop-only" no longer
       matches. Zero results then means "no bad use sites" AND "bad use site
       present", indistinguishably. Worse than noise.
   The `[^"]*` either side is what makes the check both quiet and honest.

   templates/ is in the search root deliberately even though the Slim side uses
   Tailwind `min-[992px]:` utilities and carries no helper today — so the audit
   does not silently stop covering Slim if that ever changes.
   -------------------------------------------------------------------------- */
@media (max-width: 991px) {
    .bgi-mhdr-desktop-only { display: none; }
}
@media (min-width: 992px) {
    .bgi-mhdr-mobile-only { display: none; }
}
