/*
 * Serenity template — bs2-bs5-bridge.css
 *
 * BS2-to-BS5 visual aliasing for BS2 grid + utility classes that survive in:
 *   (1) custom-HTML module content stored in jos_modules.content
 *   (2) VirtueMart's older view templates that still emit .row-fluid / .span* markup
 *
 * The Skill 26 modernize-stack.py helper rewrites BS2 classes in index.php, but
 * MODULE CONTENT is data not code — those BS2 classes survive intact. Without
 * this bridge, BS5 doesn't know what .row-fluid / .spanN mean, so module rows
 * collapse to stacked-vertically block elements.
 *
 * This file is loaded LAST in the <head> CSS stack so its rules win the cascade.
 *
 * Reference: Avant's avant-fixups.css (early Phase 3b version) — same pattern
 * applied to module content that contains legacy markup.
 */

/* ---------- BS2 .row-fluid → BS5 flex row ---------- */

.row-fluid {
    display: flex;
    flex-wrap: wrap;
    margin-right: 0;
    margin-left: 0;
    box-sizing: border-box;
    width: 100%;
}

/* CS-PATCH: rowfluid-where-completion 2026-07-24 (found on Explore)
   This block was only PARTIALLY :where()'d in the 2026-07-14 FlatStore
   refactor (span1/3/6/9/12 + the [class*=span] child block were left at
   full specificity) — a canonical regression from the parallel-tab
   nights. The un-:where'd 15px PADDING gutters + BS5 12-col widths beat
   the BS2-faithful :where() grid below (margins + 14.53/23.08/...%):
   Explore 768 showed sidebar moduletable 146 vs live 161 and partner
   logos at HALF size (li.span2 got BS2 width but kept the 15px padding).
   BS2 used margin-left gutters and NO padding — the :where() standalone
   .spanN block below owns widths+gutters; this block only keeps the
   flex-child plumbing. */
.row-fluid > [class*="span"] {
    box-sizing: border-box;
    min-height: 1px;
    flex: 0 0 auto;
    /* BS2's real gutter model: margin-left, NOT padding. Must sit at real
       specificity — reset.css's element-level margin:0 beats a :where()
       margin (found on Explore browse view: span9 lost its 2.564% gutter
       and the whole main column sat 29px left of live). */
    margin-left: 2.564102564%;
}
.row-fluid > [class*="span"]:first-child {
    margin-left: 0;
}

:where(.row-fluid > .span1)   { width: 8.333333%;  }
:where(.row-fluid > .span2)   { width: 16.666667%; }
:where(.row-fluid > .span3)   { width: 25%;        }
:where(.row-fluid > .span4)   { width: 33.333333%; }
:where(.row-fluid > .span5)   { width: 41.666667%; }
:where(.row-fluid > .span6)   { width: 50%;        }
:where(.row-fluid > .span7)   { width: 58.333333%; }
:where(.row-fluid > .span8)   { width: 66.666667%; }
:where(.row-fluid > .span9)   { width: 75%;        }
:where(.row-fluid > .span10)  { width: 83.333333%; }
:where(.row-fluid > .span11)  { width: 91.666667%; }
:where(.row-fluid > .span12)  { width: 100%;       }

/* Standalone .spanN (outside .row-fluid) — float-based BS2 behaviour */

/* 2026-07-14 FlatStore: wrapped in :where() so template.css same-specificity
   overrides (e.g. .sp20 five-across cells) win like they did over load-FIRST
   BS2. The bridge loads LAST; without :where it hijacked those grids. */
:where(.span1, .span2, .span3, .span4, .span5, .span6,
.span7, .span8, .span9, .span10, .span11, .span12) {
    box-sizing: border-box;
    float: left;
    min-height: 1px;
    margin-left: 2.564102564%;
}

:where(.span1, .span2, .span3, .span4, .span5, .span6, .span7, .span8,
.span9, .span10, .span11, .span12):where(:first-child) {
    margin-left: 0;
}

:where(.span1) { width: 5.982905983%; }
:where(.span2) { width: 14.52991453%; }
:where(.span3) { width: 23.07692308%; }
:where(.span4) { width: 31.62393162%; }
:where(.span5) { width: 40.17094017%; }
:where(.span6) { width: 48.71794872%; }
:where(.span7) { width: 57.26495726%; }
:where(.span8) { width: 65.81196581%; }
:where(.span9) { width: 74.35897436%; }
:where(.span10) { width: 82.90598291%; }  /* 1170-grid %% (was 970-grid px) — fill container, not bunch-left */
:where(.span11) { width: 91.45299145%; }  /* 1170-grid %% (was 970-grid px) — fill container, not bunch-left */
:where(.span12) { width: 100%; }  /* 1170-grid %% (was 970-grid px) — fill container, not bunch-left */

/* ---------- BS2 .offset* ---------- */

.row-fluid > .offset1   { margin-left: 8.333333%;  }
.row-fluid > .offset2   { margin-left: 16.666667%; }
.row-fluid > .offset3   { margin-left: 25%;        }
.row-fluid > .offset4   { margin-left: 33.333333%; }
.row-fluid > .offset5   { margin-left: 41.666667%; }
.row-fluid > .offset6   { margin-left: 50%;        }
.row-fluid > .offset7   { margin-left: 58.333333%; }
.row-fluid > .offset8   { margin-left: 66.666667%; }
.row-fluid > .offset9   { margin-left: 75%;        }
.row-fluid > .offset10  { margin-left: 83.333333%; }
.row-fluid > .offset11  { margin-left: 91.666667%; }

/* ---------- BS2 .pull-left / .pull-right → BS5 equivalents ---------- */

.pull-left  { float: left  !important; }
.pull-right { float: right !important; }

/* ---------- BS2 .hidden-phone / .visible-phone (block context) ---------- */
/* Inline-context (.d-inline d-sm-none / .d-none d-sm-inline) handled in index.php. */
/* These are for div-context usage in module content. */

@media (max-width: 767px) {
    .hidden-phone  { display: none !important; }
    .visible-phone { display: block !important; }
}
@media (min-width: 768px) {
    .visible-phone { display: none  !important; }
    /* .hidden-phone intentionally NOT declared at >=768 — see
       CS-PATCH: hidden-phone-no-desktop-override (2026-07-24, Explore) */
}

/* ---------- BS2 button aliases ---------- */

.btn-inverse  { background-color: #212529; border-color: #212529; color: #fff; }
.btn-inverse:hover  { background-color: #000; border-color: #000; color: #fff; }
.btn-default  { background-color: #6c757d; border-color: #6c757d; color: #fff; }
.btn-default:hover  { background-color: #5c636a; border-color: #5c636a; color: #fff; }

/* ---------- Mobile responsiveness — collapse multi-col rows on small screens ---------- */

@media (max-width: 767px) {
    .row-fluid {
        flex-direction: column;
    }
    .row-fluid > [class*="span"] {
        width: 100% !important;
        margin-left: 0 !important;
    }
}

/* ---------- Sticky header — white background so it stays visible on scroll ---------- */
/* Locked 2026-06-15: The fixed-position #top-handler had no background, so when scrolling
   over the slideshow / content images the menu blended into the page and got lost. */

#top-handler.fixed,
#top-handler.scrolled {
    background: #ffffff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

#top-handler.scrolled {
    background: #ffffff;
}

/* ---------- Testimonials section — tighten the over-tall gray box ---------- */
/* Locked 2026-06-15: #testimonials .container had min-height: 460px hard-coded.
   With single-testimonial visible the gray box towers above the content. */

#testimonials .container {
    min-height: auto;
}

#testimonials .container .row-fluid {
    padding: 50px 0px;
}

#testimonials {
    margin-bottom: 0;
}

.customers-box-handler .owl-theme .owl-controls .owl-pagination {
    margin-top: 10px;
}

/* ---------- Manufacturers/Partners carousel — reduce gap before pagination dots ---------- */
/* Locked 2026-06-15: Visual gap of ~150px between brand-logo row bottom and the
   pagination dots. Caused by owl-carousel inheriting auto-height of taller items. */

.man-main-handler {
    padding-bottom: 0;
}

.man-main-handler .owl-wrapper-outer {
    padding: 0;
}

.man-main-handler .owl-pagination,
.moduletable_manufacturers .owl-pagination {
    margin-top: 10px;
}

.moduletable_manufacturers .owl-item {
    padding: 0 10px;
}

.moduletable_manufacturers .owl-item img {
    max-height: 80px;
    width: auto;
    margin: 0 auto;
}

/* ---------- Sticky header — white background so it stays visible on scroll ---------- */
/* Locked 2026-06-15: The fixed-position #top-handler had no background, so when scrolling
   over the slideshow / content images the menu blended into the page and got lost. */

#top-handler.fixed,
#top-handler.scrolled {
    background: #ffffff;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
}

#top-handler.scrolled {
    background: #ffffff;
}

/* ---------- Testimonials section — tighten the over-tall gray box ---------- */
/* Locked 2026-06-15: #testimonials .container had min-height: 460px hard-coded.
   With single-testimonial visible the gray box towers above the content. */

#testimonials .container {
    min-height: auto;
}

#testimonials .container .row-fluid {
    padding: 50px 0px;
}

#testimonials {
    margin-bottom: 0;
}

.customers-box-handler .owl-theme .owl-controls .owl-pagination {
    margin-top: 10px;
}

/* ---------- Manufacturers/Partners carousel — reduce gap before pagination dots ---------- */
/* Locked 2026-06-15: Visual gap of ~150px between brand-logo row bottom and the
   pagination dots. Caused by owl-carousel inheriting auto-height of taller items. */

.man-main-handler {
    padding-bottom: 0;
}

.man-main-handler .owl-wrapper-outer {
    padding: 0;
}

.man-main-handler .owl-pagination,
.moduletable_manufacturers .owl-pagination {
    margin-top: 10px;
}

.moduletable_manufacturers .owl-item {
    padding: 0 10px;
}

.moduletable_manufacturers .owl-item img {
    max-height: 80px;
    width: auto;
    margin: 0 auto;
}

/* ---------- Cart product images — force aspect-ratio preservation ---------- */
/* Locked 2026-06-15: BS5 doesn't auto-apply height:auto to images the way BS4 did.
   The legacy span.cart-images rule sets width:45px but no height, so under certain
   parent-height contexts the image stretches vertically into a tall narrow strip.
   Force aspect ratio + cap height defensively. */

span.cart-images img,
.cart-images img,
.cart-product-image img,
.cartpanel img.featuredProductImage,
td .cart-images img {
    width: 45px !important;
    height: auto !important;
    max-height: 60px !important;
    object-fit: contain;
}

/* And the mini-cart in header */
.cartpanel .vm_cart_products img,
.cartpanel img {
    width: 45px !important;
    height: auto !important;
    max-height: 60px !important;
    object-fit: contain;
}

/* ---------- Related-products / "You May Also Be Interested" grid images ---------- */
/* Locked 2026-06-15 (Serenity, Round 5 fix): The VirtueMart cart-bottom related-
   products block uses `<ul class="vmproduct product-details row-fluid"><li class="span6 floatleft">`
   markup with `<img class="featuredProductImage" width="585" height="585">` inside.
   Same BS5 image-stretch issue as the cart row: the legacy span6 column flexes
   to fill the row's tallest content; without `height: auto !important` the image
   stretches vertically and the products look tall + narrow. Cap defensively. */

.moduletable_products img.featuredProductImage,
.moduletable_products .pr-img-handler img,
.vmgroup_products img.featuredProductImage,
.vmgroup_products .pr-img-handler img,
.vmproduct .pr-img-handler img,
.pr-img-handler img.featuredProductImage,
.pr-img-handler img,
.show-pop-up-image img.featuredProductImage,
.featured-view img.featuredProductImage,
.latest-view img.featuredProductImage,
.topten-view img.featuredProductImage,
.recent-view img.featuredProductImage {
    max-width: 100% !important;
    width: 100% !important;
    height: auto !important;
    object-fit: contain;
    aspect-ratio: 1 / 1;
}

/* Belt-and-suspenders: any image inside any .vmproduct li directly */
.vmproduct li img,
.vmgroup_products li img,
.moduletable_products li img {
    max-width: 100% !important;
    height: auto !important;
    object-fit: contain;
}

/* Cap the spacer container's flex stretch so the row doesn't blow up vertically */
.vmproduct .spacer .pr-img-handler {
    overflow: hidden;
}

/* ---------- Category-view images (Round 9 — Tim caught the /online-store page) ---------- */
/* Locked 2026-06-16: VirtueMart's category-view markup uses
   <div class="category floatleft span3"><div class="spacer"><h2><a>
       <img width="585" height="585" src="..."/>
   The image has NO class — only the wrapper hierarchy. The earlier related-
   products fix that targeted .featuredProductImage doesn't reach these. */

.category-view .category img,
.category-view .row-fluid .category img,
.category .spacer img,
.row-fluid .spacer img,
.category-view .spacer img,
.category-view .category .spacer h2 a img {
    max-width: 100% !important;
    width: 100% !important;
    height: auto !important;
    object-fit: contain;
    aspect-ratio: 1 / 1;
}

/* Cap the spacer container so flex parent doesn't stretch the row vertically */
.category-view .category .spacer,
.category .spacer {
    overflow: hidden;
}

/* ---------- Breadcrumbs — strip list bullets, inline display (Round 11) ---------- */
/* Locked 2026-06-16: Joomla 5's mod_breadcrumbs ships a <ul class="breadcrumb"><li>...
   markup. Without `list-style: none` + `display: inline`, each crumb shows a bullet. */

.breadcrumb,
ul.breadcrumb,
#breadcrumb-line .breadcrumb,
[role="navigation"] .breadcrumb {
    list-style: none !important;
    padding-left: 0 !important;
    margin: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4em;
}

.breadcrumb > li,
ul.breadcrumb > li {
    list-style: none !important;
    display: inline-flex;
    align-items: center;
}

.breadcrumb > li::before,
.breadcrumb > li::marker {
    content: none !important;
}

/* ---------- Breadcrumbs tighten (Round 12) ---------- */
/* Locked 2026-06-16: round 11 set gap:0.4em which left visible whitespace
   between "/" and the next crumb. Tim wants tighter — natural single-space
   look like "Home / Using Joomla!" rather than "Home / [gap] Using Joomla!".
   Drop the flex gap and let the inline content's natural whitespace handle it. */

.breadcrumb,
ul.breadcrumb,
#breadcrumb-line .breadcrumb,
[role="navigation"] .breadcrumb {
    gap: 0;
}

.breadcrumb > li,
ul.breadcrumb > li {
    margin: 0;
    padding: 0;
}

/* Normalize the divider span so the "/" sits with consistent single-space
   padding either side, regardless of whether the source HTML has tabs/newlines
   inside the <span class="divider">. */
.breadcrumb .divider {
    display: inline-block;
    padding: 0 0.35em;
    white-space: normal;
}

/* ---------- UNIVERSAL image aspect-ratio defense (Round 13) ---------- */
/* Tim 2026-06-16: instead of catching the stretched-image pattern page-by-page,
   apply max-width:100% + height:auto to EVERY image with HTML width/height
   attributes (the VirtueMart marketplace pattern). Modern browsers + the HTML
   attrs give the natural aspect-ratio; CSS just keeps it from overflowing.
   This subsumes the round 5 (related products), round 9 (category view) and
   round 10 (single contact) per-page rules and catches everything else.

   Exclusions: explicit icon/emoji classes, social icons, payment icons —
   those need pixel-precise sizing from the template's own rules. */

img[width][height]:not([class*="icon"]):not([class*="socicon"]):not([class*="emoji"]):not([alt*="separator"]):not(.camera_wrap img):not(.camera_src img) {
    max-width: 100% !important;
    height: auto !important;
}

/* Safety net — any img inside known VM / Joomla content containers
   (covers cases where the img has no width/height attrs but still needs sizing) */
.main-image img,
.vm-additional-images img,
.vm-additional-images a img,
.vm-product-media-container img,
.vm-product-media-container a img,
.product-fields-list img,
.product-related-products img,
.product-field-display img,
.product-field-type-R img,
.virtuemart_view_productdetails img,
.productdetails-view img,
.product-container img,
.vmproduct img,
.vmgroup_products img,
.category-view img,
.featured-view img,
.latest-view img,
.topten-view img,
.recent-view img,
.related-products-view img,
.browse-view img,
.search-result-products img,
.com-content-article img,
.article-content img {
    max-width: 100% !important;
    height: auto !important;
}


/* ===========================================================================
 * Megamenu hover-gap fix (locked 2026-06-16, Round 19 final)
 *
 * Architecture: vendor's `top: 90px` is the CORRECT position — header is 90px
 * tall (`topheight` param), logo+menu share the row, dropdown lands right below.
 * The 40-50px visible gap from menu items to dropdown is intentional design.
 *
 * Real bug: superfish's hover-delay JS only wires to the `usedropdown` code
 * path, NOT `usemegamenu`. Megamenu is pure CSS, so mouse crossing the gap
 * instantly drops `:hover` and the dropdown vanishes mid-traversal.
 *
 * Fix: CSS transition-delay on `top` — dropdown stays at top:90 for 500ms
 * after hover-out before reverting to top:-999em (the hidden state).
 *
 * ⛔ Three traps to avoid (don't repeat the Round 17-18 mistakes):
 *   - `top: 100%` — `.main-li-container` is `position:static!important`,
 *     so 100% measures against next positioned ancestor; dropdown escapes.
 *   - `top:<smaller value>` — logo is centered in the 90px row, overlaps any
 *     value below ~90px.
 *   - Pseudo-element bridge with pointer-events:auto — `.ul-container` spans
 *     full container width, so bridge above it covers sibling menu items
 *     and blocks lateral mouse movement.
 * =========================================================================== */

/* Hide state — declare transition with 500ms delay (applies when hovering OUT) */
#megamenu-handler #mega-menu.menu-nav > li > ul.ul-container {
    transition: top 0s linear 500ms;
}

/* Hover state — no delay (applies when hovering IN).
   2026-07-14 (GliseStore): the hardcoded `top: 90px !important` here was the
   2026-06-16 donor's header height and OVERRODE other templates' own inline
   `top: topheight+116px` rule (GliseStore's panel opened 86px too high,
   covering the nav bar). The hover `top` must come from the TEMPLATE's own
   CSS — the bridge only owns the transition-delay mechanic. (Same principle
   as the bare-#top-handler fix: never hardcode one donor's geometry.) */
#megamenu-handler #mega-menu.menu-nav > li:hover > ul.ul-container,
#megamenu-handler #mega-menu.menu-nav > li.sfHover > ul.ul-container {
    transition-delay: 0s;
}

/* ---------- Mobile: standalone .spanN blocks stack full-width (footer cols, payment/social bar, .moduletable/.tf-module.spanN) ---------- */
/* Added 2026-07-14 (QStore): standalone .spanN percentage widths are desktop-grid only;
   without this they stay side-by-side and cramp on phones. */
@media (max-width: 767px) {
    .span1, .span2, .span3, .span4, .span5, .span6,
    .span7, .span8, .span9, .span10, .span11, .span12 {
        width: 100% !important; margin-left: 0 !important; float: none !important;
    }
    .owl-wrapper-outer, .owl-item, .sl-products, .vmgroup_products, .moduletable_products { max-width: 100% !important; }
}

/* ---------- Tabbed-products nav: strip BS5 .row gutter from non-col tab children + keep labels one line ---------- */
/* Added 2026-07-14 (QStore): the tab module outer .row is a BS5 flex row, so BS5 pads its
   tab children 12px (BS2 .row-fluid never did) -> reads as a stray column offsetting tabs. */
.nav-tabs-handler.row > .tabs-nav-handler,
.nav-tabs-handler.row > .tabs-handler,
.tabs-nav-handler { padding-left: 0 !important; padding-right: 0 !important; }
.tabs-nav-handler ul.nav-tabs > li,
.tabs-nav-handler ul.nav-tabs > li .tab_heading,
.tabs-nav-handler ul.nav-tabs > li a { white-space: nowrap; }

/* ============================================================
   CS-PATCH: container-1170-cap  2026-07-14  (found on Energize)
   BS5 css caps .container at 1320px @>=1400 viewport; the BS2 grid
   this bridge emulates capped it at 1170px @>=1200 (724 @768-979,
   940 @980-1199, fluid below 768). Without this, the whole boxed
   layout widens to 1320 and every %-based .spanN widens with it.
   Also: BS2 sized absolutely-positioned .spanN blocks (e.g. header
   #top-handler.span12.th-abs) with FIXED px so they matched the
   container; the bridge's percentage widths resolve against the
   VIEWPORT for abs-positioned elements unless the container is the
   containing block — so make .container position:relative.
   ============================================================ */
.container:not(.container-fluid) { position: relative; }
@media (max-width: 767px) { .container:not(.container-fluid) { max-width: 100%; } }
@media (min-width: 768px) and (max-width: 979px) { .container:not(.container-fluid) { max-width: 724px; } }
@media (min-width: 980px) and (max-width: 1199px) { .container:not(.container-fluid) { max-width: 940px; } }
@media (min-width: 1200px) { .container:not(.container-fluid) { max-width: 1170px !important; } }
/* CS-PATCH addendum 2026-07-14 (HyperShop): BS2 .container also self-centered (margin auto).
   Footer containers that relied on it hug the left edge without this. */
.container:not(.container-fluid) { margin-left: auto; margin-right: auto; }

/* ============================================================
   CS-PATCH: fa6-social-reset  2026-07-14  (found on Energize)
   Legacy sprite CSS hides social link text via text-indent:-9999px
   (+ background sprite). After Phase 10c the FA6 <i> glyph inherits
   the indent and vanishes off-screen. :has(i) scopes the reset to
   anchors that actually carry an icon element, so sprite-based
   templates that have not been converted yet are unaffected.
   ============================================================ */
#social-links li a:has(i) { text-indent: 0; background-image: none; text-align: center; text-decoration: none; }
#social-links li a i { font-size: 15px; line-height: 38px; }
#social-links .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0; }

/* ============================================================
   CS-PATCH: camera-img-maxwidth  2026-07-14  (found on Energize @768)
   The bridge's responsive-img rule (img[width][height]:not(...)) has
   higher specificity than camera.css's `.camera_wrap img{max-width:none}`,
   so camera.js cover-crop sizing (inline width/height px) gets capped to
   the box width and the slideshow letterboxes instead of cover-filling.
   Exclude slideshow imagery explicitly.
   ============================================================ */
.camera_wrap img, .camera_src img, .cameraSlide img { max-width: none !important; }

/* =====================================================================
   CS-PATCH: row-spanN-mirror  2026-07-14  (mandated by Pipeline v2 Phase 5;
   applied during HyperShop run). Phase 3a rewrites inline markup
   .row-fluid → .row, so legacy .spanN children now sit inside a BS5 flex
   .row. BS5's `.row > *` sets width:100% at equal specificity (0,1,0) to
   the bare .spanN width rules above — the bridge only wins because it
   loads last. This mirror makes the win structural (0,2,0), not
   load-order luck. Values are IDENTICAL to the bare standalone .spanN
   1170-grid percentages, so computed layout on shipped templates is
   unchanged. Gutter margins still come from the bare .spanN rules.
   Mobile stacking unchanged: the ≤767px .spanN {width:100%!important}
   block still wins via !important.
   ===================================================================== */
:where(.row > .span1)  { flex: 0 0 auto; width: 5.982905983%; }
:where(.row > .span2)  { flex: 0 0 auto; width: 14.52991453%; }
:where(.row > .span3)  { flex: 0 0 auto; width: 23.07692308%; }
:where(.row > .span4)  { flex: 0 0 auto; width: 31.62393162%; }
:where(.row > .span5)  { flex: 0 0 auto; width: 40.17094017%; }
:where(.row > .span6)  { flex: 0 0 auto; width: 48.71794872%; }
:where(.row > .span7)  { flex: 0 0 auto; width: 57.26495726%; }
:where(.row > .span8)  { flex: 0 0 auto; width: 65.81196581%; }
:where(.row > .span9)  { flex: 0 0 auto; width: 74.35897436%; }
:where(.row > .span10) { flex: 0 0 auto; width: 82.90598291%; }
:where(.row > .span11) { flex: 0 0 auto; width: 91.45299145%; }
:where(.row > .span12) { flex: 0 0 auto; width: 100%; }

/* =====================================================================
   CS-PATCH: bs2-body-reset  2026-07-14  (found on HyperShop)
   BS2 bootstrap.min.css carried `body { margin: 0 }`. When modernize-stack
   strips the BS2 CSS, the browser default 8px body margin comes back and
   the whole page shifts 8px down/right vs the live donor. Restore the reset.
   (font-size/line-height/color come from template.css on every donor seen
   so far — only the margin was lost.)
   ===================================================================== */
body { margin: 0; }

/* =====================================================================
   CS-PATCH: bs2-container-clearfix  2026-07-14  (found on HyperShop @375)
   BS2 bootstrap.min.css gave .container a table-clearfix
   (.container:before/:after { display:table; content:"" } + :after { clear:both }).
   BS5's .container has none. Containers whose children are all FLOATED
   (e.g. HyperShop's #megamenu-handler .megamenu-background bar) collapse to
   ~0 height once BS2 CSS is stripped, pulling everything below them up and
   stacking sections on top of each other (slideshow overlapped the mobile
   Shop Menu button). Faithful restoration of the BS2 behavior.
   ===================================================================== */
.container:not(.container-fluid)::before,
.container:not(.container-fluid)::after { display: table; content: ""; line-height: 0; }
.container:not(.container-fluid)::after { clear: both; }

/* =====================================================================
   CS-PATCH: bs2-responsive-span-stack  2026-07-14  (found on HyperShop @375)
   BS2 bootstrap-responsive.min.css stacked EVERY grid cell at <=767 via
   `.row-fluid [class*="span"] { display:block; float:none; width:100%;
   margin-left:0 }` — an attribute selector, so it also caught odd cells
   like HyperShop's slideshow caption `span0` that the .span1-.span12
   class list above misses. Mirror it for both .row-fluid and .row (Phase
   3a rewrites markup). display stays NON-important so .hidden-phone
   (display:none !important) still wins, exactly as in BS2.
   ===================================================================== */
@media (max-width: 767px) {
    .row-fluid [class*="span"], .row [class*="span"] {
        display: block;
        float: none !important;
        width: 100% !important;
        margin-left: 0 !important;
    }
}

/* =====================================================================
   CS-PATCH: bs2-tab-pane  2026-07-14  (found on HyperShop)
   BS2 bootstrap.min.css carried the tab-panel visibility contract:
   .tab-content > .tab-pane { display:none } + .tab-content > .active
   { display:block }. Templates with custom tab JS (jQuery .active class
   toggling) rely on it. Without it ALL tab panels render stacked (three
   product grids at once on HyperShop home). Faithful BS2 restoration.
   ===================================================================== */
.tab-content > .tab-pane, .pill-content > .pill-pane { display: none; }
.tab-content > .active, .pill-content > .active { display: block; }

/* =====================================================================
   CS-PATCH: bs2-base-typography  2026-07-14  (found on HyperShop)
   BS2 bootstrap.min.css carried the base type scale (h1 38.5/40, h2 31.5,
   h3 24.5, h4 17.5, h5 14, h6 11.9, p and list margins). Templates rely on
   it for any heading template.css does not size itself — without it module
   content headings fall to UA defaults and text banners collapse (HyperShop
   top-long promo rendered 103px tall vs 273px on live).
   Wrapped in :where() so specificity is ZERO: these beat UA defaults but
   lose to every template.css rule — faithfully reproducing BS2s
   loaded-before-template.css cascade position even though the bridge
   loads last.
   ===================================================================== */
:where(p) { margin: 0 0 10px; }
:where(h1, h2, h3, h4, h5, h6) { margin: 10px 0; font-family: inherit; font-weight: bold; line-height: 20px; color: inherit; text-rendering: optimizelegibility; }
:where(h1, h2, h3) { line-height: 40px; }
:where(h1) { font-size: 38.5px; }
:where(h2) { font-size: 31.5px; }
:where(h3) { font-size: 24.5px; }
:where(h4) { font-size: 17.5px; }
:where(h5) { font-size: 14px; }
:where(h6) { font-size: 11.9px; }
:where(ul, ol) { padding: 0; margin: 0 0 10px 25px; }

/* =====================================================================
   CS-PATCH: row-clearfix-and-offsets  2026-07-14  (found on HyperShop)
   Phase 3a rewrites .row-fluid -> .row in template markup. BS2 .row-fluid
   carried (a) a table-clearfix so FLOATED .spanN children give the row
   height (HyperShop top-long banner collapsed 193px -> 3px without it),
   and (b) .offsetN margins (banner text block .span7.offset5 hugged the
   left edge without it). Mirror both onto .row. The ::before/::after
   boxes are zero-size and harmless if a genuinely-BS5 flex .row gets them.
   ===================================================================== */
.row::before, .row::after { content: ""; display: table; line-height: 0; }
.row::after { clear: both; }
.row > .offset1  { margin-left: 8.333333%;  }
.row > .offset2  { margin-left: 16.666667%; }
.row > .offset3  { margin-left: 25%;        }
.row > .offset4  { margin-left: 33.333333%; }
.row > .offset5  { margin-left: 41.666667%; }
.row > .offset6  { margin-left: 50%;        }
.row > .offset7  { margin-left: 58.333333%; }
.row > .offset8  { margin-left: 66.666667%; }
.row > .offset9  { margin-left: 75%;        }
.row > .offset10 { margin-left: 83.333333%; }
.row > .offset11 { margin-left: 91.666667%; }

/* =====================================================================
   CS-PATCH: fluid-descendant-offsets  2026-07-14  (found on HyperShop)
   BS2 fluid offsets applied to DESCENDANTS of a fluid row (module content
   like <div class="custom"><div class="span7 offset5">), not just direct
   children, using the fluid model: offsetN = N*8.547% (+2.564% gutter when
   not :first-child). Verified against live computed style (offset5
   :first-child = 354.688px / 830px = 42.735%). These land AFTER the
   simple-12col offset mirrors above and win by file order, matching the
   BS2 render exactly.
   ===================================================================== */
.row-fluid .offset1, .row .offset1   { margin-left: 11.111111%; }
.row-fluid .offset2, .row .offset2   { margin-left: 19.658120%; }
.row-fluid .offset3, .row .offset3   { margin-left: 28.205128%; }
.row-fluid .offset4, .row .offset4   { margin-left: 36.752137%; }
.row-fluid .offset5, .row .offset5   { margin-left: 45.299145%; }
.row-fluid .offset6, .row .offset6   { margin-left: 53.846154%; }
.row-fluid .offset7, .row .offset7   { margin-left: 62.393162%; }
.row-fluid .offset8, .row .offset8   { margin-left: 70.940171%; }
.row-fluid .offset9, .row .offset9   { margin-left: 79.487179%; }
.row-fluid .offset10, .row .offset10 { margin-left: 88.034188%; }
.row-fluid .offset11, .row .offset11 { margin-left: 96.581197%; }
.row-fluid .offset1:first-child, .row .offset1:first-child   { margin-left: 8.547009%; }
.row-fluid .offset2:first-child, .row .offset2:first-child   { margin-left: 17.094017%; }
.row-fluid .offset3:first-child, .row .offset3:first-child   { margin-left: 25.641026%; }
.row-fluid .offset4:first-child, .row .offset4:first-child   { margin-left: 34.188034%; }
.row-fluid .offset5:first-child, .row .offset5:first-child   { margin-left: 42.735043%; }
.row-fluid .offset6:first-child, .row .offset6:first-child   { margin-left: 51.282051%; }
.row-fluid .offset7:first-child, .row .offset7:first-child   { margin-left: 59.829060%; }
.row-fluid .offset8:first-child, .row .offset8:first-child   { margin-left: 68.376068%; }
.row-fluid .offset9:first-child, .row .offset9:first-child   { margin-left: 76.923077%; }
.row-fluid .offset10:first-child, .row .offset10:first-child { margin-left: 85.470085%; }
.row-fluid .offset11:first-child, .row .offset11:first-child { margin-left: 94.017094%; }

/* =====================================================================
   CS-PATCH: bs2-responsive-utilities-full  2026-07-14  (found on HyperShop @768)
   The bridge carried only the phone pair (.hidden-phone/.visible-phone).
   BS2 responsive-utilities also had tablet + desktop variants — without
   them .hidden-tablet content (HyperShop blue promo strip) shows at
   768-979 where live hides it, and .visible-desktop leaks into phone/
   tablet. Exact BS2.3.2 block, appended last so it wins over the partial
   phone-only rules above.
   ===================================================================== */
.visible-phone { display: none !important; }
.visible-tablet { display: none !important; }
.hidden-desktop { display: none !important; }
.visible-desktop { display: inherit !important; }
@media (min-width: 768px) and (max-width: 979px) {
  .hidden-desktop { display: inherit !important; }
  .visible-desktop { display: none !important; }
  .visible-tablet { display: inherit !important; }
  .hidden-tablet { display: none !important; }
}
@media (max-width: 767px) {
  .hidden-desktop { display: inherit !important; }
  .visible-desktop { display: none !important; }
  .visible-phone { display: inherit !important; }
  .hidden-phone { display: none !important; }
}


/* ============================================================
   CS-PATCH: vmproduct-ul-span-grid  2026-07-14  (found on Illusion)
   Children of block product ULs must use BS2 fluid-grid widths
   (span3 = 23.0769% + 2.5641% gutter, first-child 0) — the bridge's
   flex-row .spanN splits (25% etc.) overflow the row by the gutter
   and wrap the last tile to the next line.
   ============================================================ */
:where(ul.row-fluid.vmproduct > [class*="span"], ul.row-fluid.sl-products > [class*="span"], ul.row-fluid[class*="products"] > [class*="span"]) {
    float: left; display: block; box-sizing: border-box;
    margin-left: 2.564102564%; padding-left: 0; padding-right: 0; min-height: 1px;
}
:where(ul.row-fluid.vmproduct > [class*="span"]:first-child, ul.row-fluid.sl-products > [class*="span"]:first-child, ul.row-fluid[class*="products"] > [class*="span"]:first-child) { margin-left: 0; }
:where(ul.row-fluid.vmproduct > .span1, ul.row-fluid.sl-products > .span1, ul.row-fluid[class*="products"] > .span1) { width: 5.982905983%; }
:where(ul.row-fluid.vmproduct > .span2, ul.row-fluid.sl-products > .span2, ul.row-fluid[class*="products"] > .span2) { width: 14.529914530%; }
:where(ul.row-fluid.vmproduct > .span3, ul.row-fluid.sl-products > .span3, ul.row-fluid[class*="products"] > .span3) { width: 23.076923077%; }
:where(ul.row-fluid.vmproduct > .span4, ul.row-fluid.sl-products > .span4, ul.row-fluid[class*="products"] > .span4) { width: 31.623931624%; }
:where(ul.row-fluid.vmproduct > .span5, ul.row-fluid.sl-products > .span5, ul.row-fluid[class*="products"] > .span5) { width: 40.170940171%; }
:where(ul.row-fluid.vmproduct > .span6, ul.row-fluid.sl-products > .span6, ul.row-fluid[class*="products"] > .span6) { width: 48.717948718%; }
:where(ul.row-fluid.vmproduct > .span7, ul.row-fluid.sl-products > .span7, ul.row-fluid[class*="products"] > .span7) { width: 57.264957265%; }
:where(ul.row-fluid.vmproduct > .span8, ul.row-fluid.sl-products > .span8, ul.row-fluid[class*="products"] > .span8) { width: 65.811965812%; }
:where(ul.row-fluid.vmproduct > .span9, ul.row-fluid.sl-products > .span9, ul.row-fluid[class*="products"] > .span9) { width: 74.358974359%; }
:where(ul.row-fluid.vmproduct > .span10, ul.row-fluid.sl-products > .span10, ul.row-fluid[class*="products"] > .span10) { width: 82.905982906%; }
:where(ul.row-fluid.vmproduct > .span11, ul.row-fluid.sl-products > .span11, ul.row-fluid[class*="products"] > .span11) { width: 91.452991453%; }
:where(ul.row-fluid.vmproduct > .span12, ul.row-fluid.sl-products > .span12, ul.row-fluid[class*="products"] > .span12) { width: 100%; }

/* =====================================================================
   CS-PATCH: bs5modal-on-bs2  2026-07-14  (found on GliseStore)
   VMT cohort loads Joomla's BS5 JS bundle but NO Bootstrap CSS. BS5's
   Modal JS works (adds .show + injected .modal-backdrop.fade.show) but
   nothing styles the box or backdrop. Recreate the BS2 modal look keyed
   to BS5's state classes. Scoped to .modal/.modal-backdrop only — no
   global reboot fallout. Wrapper divs (.modal-dialog/.modal-content,
   injected per Phase 6 for BS5 _getDialog) stay transparent blocks.
   ===================================================================== */
.modal { position: fixed; top: 10%; left: 50%; z-index: 1050; width: 560px; margin-left: -280px;
         background-color: #fff; border: 1px solid rgba(0,0,0,.3); border-radius: 6px;
         box-shadow: 0 3px 7px rgba(0,0,0,.3); outline: none; display: none; }
.modal.show { display: block; }
.modal .modal-dialog, .modal .modal-content { display: block; position: static; }
.modal .modal-header { padding: 9px 15px; border-bottom: 1px solid #eee; }
.modal .modal-body { position: relative; max-height: 60vh; padding: 15px; overflow-y: auto; }
.modal .modal-footer { padding: 14px 15px 15px; text-align: right; background-color: #f5f5f5;
                       border-top: 1px solid #ddd; border-radius: 0 0 6px 6px; }
.modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000; }
.modal-backdrop.fade { opacity: 0; transition: opacity .15s linear; }
.modal-backdrop.show, .modal-backdrop.fade.show { opacity: .8; }
@media (max-width: 620px) { .modal { width: auto; left: 4%; right: 4%; margin-left: 0; } }

/* =====================================================================
   CS-PATCH: bs2-container-fixed-width  2026-07-14  (found on GliseStore)
   BS2 gave .container an EXPLICIT width per breakpoint (not max-width),
   so a .container nested in a NARROWER parent overflowed it on purpose —
   GliseStore's #tabs .container is 1170px inside a 1080px section on
   live. The cap patch above (max-width) cannot reproduce that; this
   :where() block adds the BS2 fixed widths at ZERO specificity so any
   template.css width rule still wins, exactly like BS2's loaded-first
   position. The max-width cap above continues to protect top-level
   containers from BS5's 1320px default.
   ===================================================================== */
@media (min-width: 1200px) { :where(.container:not(.container-fluid)) { width: 1170px; max-width: none; } }
@media (min-width: 980px) and (max-width: 1199px) { :where(.container:not(.container-fluid)) { width: 940px; max-width: none; } }
@media (min-width: 768px) and (max-width: 979px) { :where(.container:not(.container-fluid)) { width: 724px; max-width: none; } }
@media (max-width: 767px) { :where(.container:not(.container-fluid)) { width: auto; } }

/* =====================================================================
   CS-PATCH: bs2-nav-block-anchors  2026-07-14  (found on Furniture)
   BS2 carried `.nav > li > a { display: block }`. Without it tab/nav
   anchors are UA inline; a block child span (e.g. .hidden-phone label)
   fragments the inline box and the li collapses to the label width —
   anchor padding vanishes from layout and tab labels render cramped
   together (Furniture LATEST/SALE/FEATURED). :where() = zero specificity.
   ===================================================================== */
:where(.nav) { margin-left: 0; margin-bottom: 20px; list-style: none; }
:where(.nav > li > a) { display: block; }

/* =====================================================================
   CS-PATCH: hidden-phone-no-desktop-override  2026-07-24  (found on Explore)
   Supersedes hidden-phone-inherit-fix (2026-07-14, Furniture). At >=768
   this donor cohort's BS2 build declares NO display for .hidden-phone —
   elements keep their own authored display. Both earlier bridge variants
   broke that: `block !important` fragmented inline tab-label spans
   (Furniture), and `inherit !important` flattened authored non-inherited
   displays (Explore slideshow caption h2 `display:table` shrink-to-fit
   bubbles rendered as full-width block bars). Fix: declare NOTHING at
   >=768; the <=767 `display:none !important` band above is unchanged.
   Furniture's tab anchors stay safe via bs2-nav-block-anchors.
   ===================================================================== */
@media (min-width: 768px) {
  .visible-phone { display: none !important; }
}

/* =====================================================================
   CS-PATCH: bs2-mobile-body-padding  2026-07-14  (found on Flexo @375)
   BS2 bootstrap-responsive.min.css gave <body> 20px side padding at
   <=767 — the mobile "gutter" every BS2 donor shows. Without it,
   containers that carry BS2 negative row margins bleed PAST the viewport
   edge (Flexo container at x=-10 vs live x=+10). :where() so any
   template mobile body rule still wins.
   ===================================================================== */
@media (max-width: 767px) {
  :where(body) { padding-left: 20px; padding-right: 20px; }
}

/* =====================================================================
   CS-PATCH: bs2-collapse  2026-07-14  (found on Explore)
   BS2 bootstrap.min.css carried the collapse contract:
   .collapse { height:0; overflow:hidden } + .collapse.in { height:auto }.
   Accordion menus (sidebar category menus) rely on it — without it every
   collapsed submenu occupies full layout height (Explore's menu module
   ballooned to 1223px and shoved the other sidebar modules 1400px down).
   BS5 JS toggles .show; BS2-era markup/JS toggles .in — honor both.
   ===================================================================== */
.collapse:not(.show):not(.in) { position: relative; height: 0; overflow: hidden; }
.collapse.in, .collapse.show { height: auto; }

/* =====================================================================
   CS-PATCH: rowfluid-no-stretch  2026-07-14  (found on Explore)
   BS2 .row-fluid was block+float — children NEVER stretched to the row
   height, so percentage heights on module chrome (.moduletable_menu
   { height:100% }) resolved to auto. The bridge's flex model stretches
   by default (align-items:stretch), turning that 100% into the full row
   height (Explore's sidebar menu ballooned to 1222px and shoved its
   sibling modules below the page). flex-start restores BS2 behavior.
   ===================================================================== */
.row-fluid { align-items: flex-start; }

/* =====================================================================
   CS-PATCH: explore-natural-product-images  2026-07-24  (template-scoped)
   Explore's live donor renders product thumbs at NATURAL size (150x150,
   centered) in featured/random/browse cells — the canonical Round-5/9
   width:100% !important stretch rules above blow them up to cell width
   (308px at 375, oversized at desktop too). Per the Gotchas "Browse
   thumbnails stretched" entry: later equal-specificity override back to
   natural size. Live-faithful: width auto, cap at cell, no forced ratio.
   ===================================================================== */
.moduletable_products img.featuredProductImage,
.moduletable_products .pr-img-handler img,
.vmgroup_products img.featuredProductImage,
.vmgroup_products .pr-img-handler img,
.vmproduct .pr-img-handler img,
.pr-img-handler img.featuredProductImage,
.pr-img-handler img,
.show-pop-up-image img.featuredProductImage,
.featured-view img.featuredProductImage,
.latest-view img.featuredProductImage,
.topten-view img.featuredProductImage,
.recent-view img.featuredProductImage,
.vmproduct li img,
.vmgroup_products li img,
.moduletable_products li img,
.moduletable_products li .spacer img,
.moduletable_products .row-fluid .spacer img,
.vmgroup_products li .spacer img,
.vmgroup_products .row-fluid .spacer img,
ul.vmproduct li .spacer img,
.vmproduct.row-fluid .spacer img,
.browse-view .product .spacer img,
.browse-view .row-fluid .spacer img,
.browse-view img.browseProductImage,
.category-view .product .spacer img,
img.browseProductImage {
    width: auto !important;
    max-width: 100% !important;
    height: auto !important;
    aspect-ratio: auto;
}

/* =====================================================================
   CS-PATCH: explore-mobile-ux  2026-07-24  (template-scoped)
   Tim-directed real mobile layout (Skill 33 mobile-header standard,
   locked 2026-07-15; Excite shop-hamburger lock 2026-07-16). The donor
   has NO responsive mode: #top/#menu carry the param-driven fixed
   `.w-site-width` (930px) at every viewport. Companion JS:
   js/explore-mobile.js (injects #cs-mob-menu-btn + #cs-mob-bar).
   ===================================================================== */

@media (min-width: 768px) {
  #cs-mob-menu-btn, #cs-mob-bar { display: none !important; }
}

@media (max-width: 767px) {
  /* -- the "couple of CSS lines" that forced 930px -- */
  #top.w-site-width, #menu.w-site-width, #menu-handler, #top-handler { width: auto !important; }
  html { overflow-x: hidden; }

  /* no desktop scrollbar gutter on phones (you swipe) — the classic scrollbar
     stole 15px and made the header look padded on the right (Tim, 2026-07-24) */
  html { scrollbar-width: none; -ms-overflow-style: none; }
  html::-webkit-scrollbar { display: none; width: 0; }

  /* header box: donor height:92px let the social row spill below the dark
     gradient — 105px fits logo + social (Tim-tested value) */
  #top-handler { height: 105px !important; }

  /* -- header -- */
  #top-handler { position: relative; }

  /* primary hamburger: big, top-right, on the logo row */
  #cs-mob-menu-btn {
    position: absolute; top: 12px; right: 12px;
    width: 50px; height: 44px; padding: 7px 9px;
    background: transparent; border: 0; cursor: pointer;
    display: flex; flex-direction: column; justify-content: space-between;
    z-index: 1060;
  }
  #cs-mob-menu-btn span { display: block; height: 5px; border-radius: 2px; background: #fff; }

  /* social: keep, but below the logo line + off the hamburger corner, touch-sized glyphs */
  #social { position: static !important; float: none !important; width: auto !important; text-align: center; padding: 58px 60px 6px 10px; }
  #social-links { float: none !important; display: inline-block; }
  #social-links a i { font-size: 16px; }

  /* originals replaced by the icon row */
  #log-panel { display: none !important; }
  #vm-cart { display: none !important; }

  /* -- icon row: one centered midline -- */
  #cs-mob-bar {
    display: flex; align-items: center; justify-content: center; gap: 22px;
    padding: 6px 12px; background: #f4f4f4; border-bottom: 1px solid #dfdfdf;
  }
  /* !important throughout: the template's global button/a rules paint
     param-driven colors + gradients over the bar controls */
  #cs-mob-bar button, #cs-mob-bar a {
    display: inline-flex !important; align-items: center; gap: 7px;
    background: none !important; border: 0 !important; padding: 8px 4px; cursor: pointer;
    font-size: 15px !important; color: #333 !important; text-decoration: none;
    line-height: 1 !important; height: auto !important; text-shadow: none !important;
    filter: none !important; box-shadow: none !important;
  }
  #cs-mob-bar button i, #cs-mob-bar a i { color: #333 !important; }
  #cs-mob-bar i { font-size: 18px; }
  /* a#... selector: must out-rank the generic `#cs-mob-bar a` reset above
     (same !important weight — specificity + order decide) */
  #cs-mob-bar a#cs-mob-cart {
    width: 44px !important; height: 44px !important; border-radius: 50% !important;
    background: #2b2b2b !important; justify-content: center; padding: 0 !important;
  }
  #cs-mob-bar a#cs-mob-cart i { font-size: 18px; color: #fff !important; }

  /* -- main-menu drawer (hidden until hamburger tap) -- */
  /* donor absolutely-positions the menu INTO the header bar; as a drawer it
     becomes a dark full-width panel anchored under the icon row (top set by
     explore-mobile.js on open) */
  #menu-m { display: none; }
  body.cs-menu-open #menu-m {
    display: block; position: absolute; left: 0; right: 0; z-index: 1058;
    background: #1f1f1f; box-shadow: 0 12px 24px rgba(0,0,0,0.45);
  }
  #menu-m #menu, #menu-m #menu-handler {
    position: static !important; margin: 0 !important; padding: 0 !important;
    background: transparent !important; width: auto !important;
  }
  #menu, #menu-handler { float: none !important; height: auto !important; }
  #menu-handler ul.menu-nav li a { color: #fff !important; background: transparent !important; }
  #menu-handler ul.menu-nav li ul li a { color: #cfcfcf !important; }
  #menu-handler ul.menu-nav { display: block !important; width: auto !important; height: auto !important; float: none !important; }
  #menu-handler ul.menu-nav > li { float: none !important; display: block !important; width: auto !important; border-bottom: 1px solid rgba(255,255,255,0.15); }
  #menu-handler ul.menu-nav li a { display: block !important; padding: 13px 16px !important; font-size: 16px !important; height: auto !important; line-height: 1.3 !important; }
  /* accordion-lite: submenus render inline, indented (hover is dead on touch) */
  #menu-handler ul.menu-nav li ul {
    position: static !important; display: block !important; visibility: visible !important;
    opacity: 1 !important; top: auto !important; left: auto !important;
    width: auto !important; height: auto !important; background: transparent !important;
    box-shadow: none !important; margin: 0 !important; padding: 0 !important;
  }
  #menu-handler ul.menu-nav li ul li a { padding-left: 34px !important; font-size: 15px !important; }

  /* -- shop-menu module: out of the page flow, behind the Shop toggle;
        opens as a fixed panel directly under the icon row (top set by
        explore-mobile.js on open, so the toggle stays visible to close) -- */
  #tmp-container .moduletable_menu { display: none; }
  body.cs-shop-open #tmp-container .moduletable_menu {
    display: block; position: fixed; left: 0; right: 0; z-index: 1055;
    background: #fff; margin: 0; padding: 12px 14px 16px;
    height: auto !important; /* donor height:100% = full viewport under position:fixed */
    max-height: 70vh; overflow: auto;
    box-shadow: 0 10px 22px rgba(0,0,0,0.35);
  }
  body.cs-shop-open #tmp-container .moduletable_menu ul.menu li a { display: block; padding: 10px 6px; font-size: 15px; }

  /* -- partner/brand logos: 2-per-row, not stacked (codified recurring case:
        bridge mobile stacking is flex-COLUMN; 2-up grids need explicit
        row+wrap — Excite lock in the Gotchas) -- */
  ul.vmmanufacturer { flex-direction: row !important; flex-wrap: wrap !important; }
  ul.vmmanufacturer > li[class*="span"] { width: 50% !important; margin: 0 0 14px !important; text-align: center; float: none !important; }
  ul.vmmanufacturer .man-sp-handle { display: inline-block; }

  /* -- footer: breathing room + centered payment strip -- */
  #footer { padding-left: 14px !important; padding-right: 14px !important; box-sizing: border-box; }
  #foo-left-right { padding: 0 14px 24px !important; box-sizing: border-box; }
  #foo-left-right .span6 { text-align: center; }
  #foo-left-right .span6 img { float: none !important; display: inline-block; margin: 0 auto; max-width: 100%; }

  /* -- slideshow: flow under the header (desktop model = absolute band behind
        the header with #theme-width margin-top clearance; at 375 that put the
        180px band behind the 160px header+bar and left a 300px white void) -- */
  #slideshow-handler { position: static !important; height: auto !important; }
  #theme-width, #theme-width.oklideshow, #theme-width.noslideshow { margin-top: 0 !important; }

  /* persistent arrows (hover-only nav is dead on touch) */
  #slideshow-handler .camera_prev, #slideshow-handler .camera_next {
    display: block !important; opacity: 1 !important; visibility: visible !important;
  }
}

/* =====================================================================
   CS-PATCH: explore-social-sprite-kill  2026-07-24  (template-scoped)
   Donor's legacy icon CSS keys background-image sprites on the social
   anchor IDs; #facebook and #rss survived the Phase 10c FA6 conversion
   (the donor's original 4-icon set) and painted GHOST gray icons behind/
   above the FA6 glyphs (Tim, grad round 2). Oxygen-family fix: kill the
   anchor backgrounds outright — FA6 <i> glyphs are the only icon layer.
   ===================================================================== */
#social-links li a,
#social-links li a#facebook,
#social-links li a#rss {
    background: none !important;
    background-image: none !important;
    text-indent: 0 !important;
}

/* =====================================================================
   CS-PATCH: login-fields-reach-the-ios-threshold  2026-10-19 (canonical rev .132)
   iOS Safari zooms any text field under 16px when it gets focus and does not zoom back. The 2026-09-27 block covers the
   cart's own login/coupon/quantity fields only; the Joomla login page, the login module and the registration, profile
   and reset forms kept the donor's 11-15px. MEASURED @375 on the 68 released demos: 45 rendered #username/#password
   at 11-15px. Phones only; buttons are left alone (iOS does not zoom them).
   ===================================================================== */
@media (max-width: 767px) {
    html body :is(#username, #password, #modlgn-username, #modlgn-passwd),
    html body :is(form.mod-login, form[id^="login-form"], form[class*="com-users-"], #member-registration, #member-profile, #user-registration)
        :is(input[type="text"], input[type="email"], input[type="password"], input[type="tel"], input:not([type]), select, textarea) {
        font-size: 16px !important;
    }
}
/* /CS-PATCH: login-fields-reach-the-ios-threshold */
