/* ==========================================================================
   responsive.css — centralized responsive-layer fixes
   ==========================================================================

   WHAT THIS FILE IS

   Fixes from RESPONSIVE-AUDIT.md's runtime audit, added as a NEW layer
   rather than by editing the vendor sheets or the port's own _clone-shim.css/
   _tokens.css. Those two files already established the pattern this follows:
   load last, override by matching-or-exceeding selector specificity plus
   source order, and leave the six vendor sheets (fonts.css, master.css,
   customV1.css, nuxt.css, owl.carousel.css, owl.theme.default.css) untouched.

   LOAD POSITION

   Last (tagPriority 10 in nuxt.config.ts, after _tokens.css's 9) — see that
   file's own comment on why tagPriority controls cascade position instead of
   Nuxt's `css: []` array (dev/prod injection order isn't reliably the same
   for the latter).

   CANONICAL BREAKPOINTS

   Every value below is one the vendor CSS already uses somewhere — nothing
   here is a new number invented for this file. See RESPONSIVE-AUDIT.md
   Section 3 for the full inventory this was drawn from.

     576px / 577px    master.css's own mobile-vs-tablet split
                       (@media (max-width:576px) / (min-width:577px))
     768px / 769px    master.css's own --prdcount ladder split
                       (master.css:10047, 10053)
     1100px / 1101px  the site's real desktop threshold — used throughout
                       master.css and customV1.css, and (as of the nav fix
                       in this same audit pass) by useMobileNav.ts and
                       _clone-shim.css too

   CSS media-query conditions cannot reference custom properties, so this is
   a documentation comment, not a `var()` block — the vendor CSS lives with
   the same constraint.

   !important POLICY

   Avoided wherever normal cascade (specificity + this file's late load
   order) is enough to win. Every place it IS used below has a comment
   explaining why a plain declaration wouldn't win.
   ========================================================================== */

/* --------------------------------------------------------------------------
   FIX: /packages-pricing overflows 104px at 768px (RESPONSIVE-AUDIT.md P0/P1)

   .bs-banner-theme-v29's pricing-comparison grid uses
   `grid-template-columns: repeat(5, 1fr)` for 577-1100px viewports
   (master.css:8239-8241, class .bs-banner-tablet-quantity-5). `1fr` resolves
   to `minmax(auto, 1fr)`, so each column refuses to shrink below its
   min-content width (~168px measured) — 5 columns need ~872px minimum, and
   anything narrower overflows. Confirmed 768px overflow: 104px. Confirmed
   worst case ~577px: ~295px overflow. The whole 577-871px band is affected,
   not just 768px.

   Fix: collapse to fewer columns using the SAME 769/768 boundary
   master.css's own --prdcount ladder already treats as a real breakpoint
   (master.css:10047,10053) — not a new number. 3 columns at 769-1100px and
   2 at 577-768px both land comfortably inside the container (245-368px per
   column vs. the ~168px minimum). With the label column already hidden
   below 1101px (customV1.css:2501, `.bs-banner-theme-v29
   .bs-banner-item:first-child{display:none}`), 6 items remain — 3 columns
   gives a clean 2x3 grid, 2 columns a clean 3x2, no orphan row (the current
   5-wide layout leaves a lone 6th item on its own row).

   Scoped to .bs-banner-theme-v29 specifically, matching how customV1.css
   itself scopes v29's other overrides (e.g. customV1.css:864-869,
   :2501-2509) — this does not touch any other banner that happens to also
   use a 5-column tablet layout for different content.

   No !important: this selector's specificity, (0,4,0), already beats
   master.css's `.bs-banner-model-v2.bs-banner-tablet-quantity-5
   .bs-banner-features` at (0,3,0), and this file loads after master.css
   regardless. Horizontal scroll was considered and rejected as a "fix" —
   the site already treats silent clipping (`body{overflow-x:hidden}`,
   master.css:74) as its overflow policy, and a sideways-scrolling
   comparison table is not a readable substitute for an actual column
   collapse.
   -------------------------------------------------------------------------- */
@media (min-width: 769px) and (max-width: 1100px) {
  .bs-banner-theme-v29 .bs-banner-model-v2.bs-banner-tablet-quantity-5 .bs-banner-features {
    grid-template-columns: repeat(3, 1fr);
  }
}

@media (min-width: 577px) and (max-width: 768px) {
  .bs-banner-theme-v29 .bs-banner-model-v2.bs-banner-tablet-quantity-5 .bs-banner-features {
    grid-template-columns: repeat(2, 1fr);
  }
}

/* --------------------------------------------------------------------------
   FIX: touch targets under 44x44px (RESPONSIVE-AUDIT.md P2)

   Both fixes below enlarge only the CLICKABLE hit area, not the visible
   button/icon, via an invisible pseudo-element -- the standard technique for
   WCAG 2.5.8 (Target Size, Minimum) when the visual design must stay
   unchanged. A click anywhere inside a pseudo-element's painted area (even
   where it extends past its generating element's own border box) registers
   as a click on that element, so this needs no JS changes.

   Caveat for whoever re-runs the audit script: geometry-based detectors
   (getBoundingClientRect() on the button itself) cannot see this -- they
   measure the element's own border box, not an overflowing pseudo-element.
   Both fixes were verified with an actual Playwright click at the edge of
   the expanded zone instead, confirming the real handler fires.
   -------------------------------------------------------------------------- */

/* Hamburger button: 26x36px visible, needs >=44x44 hit area.
   Both of .bs-mobile-menu-btn's own pseudo-elements are already used by the
   vendor CSS for real content (::before = top icon line, ::after = the
   "menu" text label, master.css:8446-8479) -- so the hit-area expansion
   goes on its child <span class="bs-mobile-menu-line"> (SiteHeader.vue)
   instead, whose own ::after is unused.

   That span is already `position:absolute; left:0;
   right:calc(.5 * var(--gap))` within the button (master.css:8452-8464), so
   at this button's only active range (<=1100px, --gap is always 16px --
   customV1.css:2107-2109) its border-box sits at button-relative
   (left:0, top:13px, width:18px, height:~2px, from its border-top).

   The offsets below place a 44x44 box centered on the BUTTON's center
   (13,18 in button-relative coordinates), expressed relative to the span's
   own top-left corner (0,13): x-range [-9,35], y-range [-17,27] -> width
   44 = 35-(-9), height 44 = 27-(-17). If --gap's 16px value for this
   breakpoint ever changes, these offsets need re-deriving. */
@media (max-width: 1100px) {
  .bs-mobile-menu-line::after {
    content: '';
    position: absolute;
    left: -9px;
    top: -17px;
    width: 44px;
    height: 44px;
  }
}

/* Banner CTA buttons: width is always >=44px in practice (measured
   74-157px across the audit), only height is short -- 42px at <=1100px
   (customV1.css:2250-2266, wins over master.css:9752-9762's 40px). The
   desktop rule (customV1.css:1415-1439, >=1101px) is already 44px, so this
   is scoped to the same <=1100px range as the vendor's own short rule.
   `position` isn't set by any existing rule on this button in any theme
   (verified against every override in customV1.css) -- `relative` here
   only establishes an anchor for the ::before below, it does not move the
   button (no top/left/right/bottom given). */
@media (max-width: 1100px) {
  .bs-banner-text-outer button {
    position: relative;
  }
  .bs-banner-text-outer button::before {
    content: '';
    position: absolute;
    inset: -1px 0; /* +1px top/bottom closes 42px -> 44px; left/right at 0
                      since width is already compliant everywhere this
                      appears */
  }
}
