/* ==========================================================================
   WV Buy Bar — persistent purchase reminder
   --------------------------------------------------------------------------
   Slim olive bar with three elements clustered around the horizontal
   center: product name (left of center), review count + star rating
   (center), Buy Now CTA (right of reviews). Outer olive fills the
   left/right thirds naturally because children are justify-content: center,
   not edge-to-edge.

   Product-aware — consumer passes a WC_Product via args. Two behaviors:
   'scroll' (anchor link, default) or 'add-to-cart' (button + data attrs;
   JS wiring deferred until a consumer needs it — see COMPONENTS.md).

   Height matches Buzzword Bar (60px). Any change to either component's
   height must be coordinated across both so they read as kin when placed
   on the same page.
   ========================================================================== */

.wv-buy-bar {
  /* Full-bleed breakout — escapes any centered container (e.g. PDP's
     1440px wrapper) so the bar hits the actual viewport edges. Same
     pattern as the Buzzword Bar. */
  width: 100vw;
  position: relative;
  left: 50%;
  right: 50%;
  margin-left: -50vw;
  margin-right: -50vw;

  /* Designer-approved (2026-04-23): 100px, locked to the Buzzword Bar
     which is also 100px. Any change here must be mirrored there. */
  height: 100px;

  /* Accent-driven: --wv-pdp-accent custom property set on .wv-pdp by
     the dispatcher partial. Defaults to --wv-color-accent (olive) when
     the product's pdp_accent_color is unset; switches to product
     color (omega/probiotic/etc.) when set.
     NEEDS DESIGNER REVIEW: hover state at L~130 stays --wv-color-olive-dark
     for now. When product accent is e.g. coral, the hover is still
     dark olive — could be jarring. Future refinement: derive a darker
     variant per accent (color-mix or per-color hover tokens). */
  background: var(--wv-pdp-accent);

  /* NEEDS DESIGNER REVIEW: top/bottom rules. 1px solid --wv-color-text-primary
     reads as a hairline against the olive. Weight, color, or presence
     may change per spec. */
  border-top: 1px solid var(--wv-color-text-primary);
  border-bottom: 1px solid var(--wv-color-text-primary);
}

.wv-buy-bar__inner {
  display: flex;
  align-items: center;
  /* Cluster, don't edge-justify. Outer olive fills left/right thirds. */
  justify-content: center;
  /* NEEDS DESIGNER REVIEW: gap between product name and reviews cluster.
     48px as generous starting point; the reviews→CTA gap is tighter
     (set via .wv-buy-bar__cta margin-left) to match mockup asymmetry. */
  gap: 48px;
  max-width: var(--wv-container-max);
  margin: 0 auto;
  height: 100%;
  padding: 0 var(--wv-page-gutter);
}

.wv-buy-bar__name {
  color: var(--wv-color-text-inverse);
  /* USER-APPROVED OVERRIDE (NEEDS DESIGNER REVIEW): wv-h2 ships as
     General Grotesque 400 / 40px; overriding weight to 600 per user
     direction. Flag for formal typography review — may justify adding
     a new global class (e.g. wv-h2-demi) rather than per-site overrides. */
  font-weight: 600;
}

.wv-buy-bar__reviews {
  display: flex;
  align-items: center;
  /* NEEDS DESIGNER REVIEW: gap between review count and star row */
  gap: 8px;
}

.wv-buy-bar__review-count {
  color: var(--wv-color-text-inverse);
  /* text-transform isn't covered by CLAUDE.md #3's forbidden redeclaration
     list (only family/size/weight/line-height), so adding it here is fine.
     wv-label-small handles the rest. */
  text-transform: uppercase;
}

.wv-buy-bar__stars {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

.wv-buy-bar__stars img {
  /* NEEDS DESIGNER REVIEW: star size (14px matches review-count height). */
  width: 14px;
  height: 14px;
  display: block;
  flex-shrink: 0;
  /* Stars ship as olive PNGs which disappear on the olive bar. Filter
     maps the pixels to pure white for visibility. NEEDS DESIGNER REVIEW:
     if exact --wv-color-text-inverse (cream) match is required, switch
     to a <span> + mask-image + background-color setup, or commission
     a cream star asset. */
  filter: brightness(0) invert(1);
}

.wv-buy-bar__cta {
  display: inline-flex;
  align-items: center;
  /* Asymmetric spacing per mockup — reviews→CTA is tighter than
     name→reviews. Flex gap on parent is 48px; this pulls CTA closer. */
  margin-left: 8px;
  /* NEEDS DESIGNER REVIEW: pill dimensions */
  height: 36px;
  padding: 0 28px;
  /* NEEDS DESIGNER REVIEW: button fill. --wv-color-text-primary is the
     dark olive-black; mockup shows a near-black pill on olive. */
  background: var(--wv-color-text-primary);
  color: var(--wv-color-text-inverse);
  border-radius: var(--wv-radius-pill);
  text-decoration: none;
  transition: background var(--wv-transition-base);
  /* Reset when rendered as <button> (behavior='add-to-cart' variant) */
  border: 0;
  cursor: pointer;
  white-space: nowrap;
}

.wv-buy-bar__cta:hover {
  /* NEEDS DESIGNER REVIEW: hover not specified — subtle shift to
     --wv-color-olive-dark as a starting point. */
  background: var(--wv-color-olive-dark);
}

/* ==========================================================================
   RESPONSIVE — Mobile-first base + tablet+ restoration
   --------------------------------------------------------------------------
   Per MOBILE-LAYOUT-DISCIPLINE.md archetype #8 (Full-bleed bar): mobile
   reduces height (40–60px range) and may drop an element. Here we drop
   the reviews cluster (count + stars) — user-authorized 2026-06-05 — and
   tighten the inner gap so name + CTA cluster comfortably at narrow
   widths. Tablet+ restores the desktop 100px height + reviews row.

   wv-h2 product name resolves to 26px at mobile via --wv-fs-h2, which
   fits comfortably in the 56px bar.

   Sticky variant's `top: var(--wv-header-height)` auto-adjusts (header
   is 48px at mobile, 81px at desktop) — no per-breakpoint override
   needed for sticky offset.

   Height mirrored on .wv-buzzword-bar — the two bars are designed to
   read as kin when placed on the same page.
   ========================================================================== */

.wv-buy-bar { height: 56px; }
.wv-buy-bar__inner { gap: 16px; }
.wv-buy-bar__reviews { display: none; }

@media (min-width: 768px) {
  .wv-buy-bar { height: 100px; }
  .wv-buy-bar__inner { gap: 48px; }
  .wv-buy-bar__reviews { display: flex; }
}

/* ==========================================================================
   Sticky variant — position: fixed + sentinel-driven visibility
   --------------------------------------------------------------------------
   position: sticky has been unreliable for this bar (full-bleed breakout
   conflicts + parent containing block quirks). Using position: fixed
   with a sentinel element instead — bar pinned at viewport top, shown
   only when the sentinel has scrolled above viewport.

   Sentinel: a zero-height div emitted by the partial RIGHT BEFORE the
   bar's render position. IntersectionObserver on the sentinel — when
   it leaves viewport upward, show bar; when it re-enters, hide bar.

   Checkpoint logic: when any [data-wv-buy-bar-checkpoint] is in view,
   hide sticky regardless of sentinel state.

   z-index 50: site mega menu is at 1000 — sticky slides under the menu.
   ========================================================================== */

.wv-buy-bar__sentinel {
  /* Zero-height placeholder — IntersectionObserver target. */
  width: 1px;
  height: 1px;
  margin: 0;
  padding: 0;
  pointer-events: none;
  visibility: hidden;
}

/* !important on positioning + margin properties to defeat the base
   .wv-buy-bar's full-bleed breakout (left: 50%; margin-left: -50vw)
   which has equal specificity and source-order wins on its own
   declarations.

   `top: var(--wv-header-height)` so the bar sits BELOW the site
   header (which is itself position: fixed at top: 0, z-index 1000).
   The header is 81px tall at desktop / 48px mobile. Without this
   offset, the bar's top 81px would be hidden behind the header,
   leaving only ~19px visible at the viewport top — the
   "bottom-1/5-visible" bug surfaced 2026-06-01.

   body.admin-bar shifts the header down by 32px (WP admin bar),
   so the buy bar shifts the same amount further. */
.wv-buy-bar--sticky {
  position: fixed !important;
  top: var(--wv-header-height) !important;
  left: 0 !important;
  right: auto !important;
  margin-top: 0 !important;
  margin-right: 0 !important;
  margin-bottom: 0 !important;
  margin-left: 0 !important;
  width: 100vw !important;
  z-index: 50;

  /* Hidden initially — JS sets data-visible="true" once sentinel leaves
     viewport upward. */
  opacity: 0;
  pointer-events: none;
  transform: translateY(-100%);
  transition: opacity 200ms ease, transform 200ms ease;
}

body.admin-bar .wv-buy-bar--sticky {
  top: calc(var(--wv-header-height) + 32px) !important;
}

.wv-buy-bar--sticky[data-visible="true"] {
  opacity: 1;
  pointer-events: auto;
  transform: translateY(0);
}

/* ==========================================================================
   STICKY — Mobile: pin to viewport top, not under the header
   --------------------------------------------------------------------------
   The site header is smart-sticky at mobile only — hides on scroll down,
   reveals on scroll up. If the buy bar stays at `top: var(--wv-header-height)`
   when the header hides, a 48px empty band appears above the bar.
   User direction 2026-06-05: at mobile, the sticky buy bar renders at
   the top of the viewport (replacing the hidden header's slot).

   When the header re-appears on scroll-up, header.z-index: 1000 covers
   the buy bar (z-index: 50) until the next scroll-down hides it again.

   Admin-bar at mobile: WP admin bar is 46px tall at viewport ≤782px;
   the buy bar sits just below it so the admin bar isn't covered.

   Tablet+ (≥768) restores the desktop behavior — header is always
   visible, so the buy bar sits below it at `var(--wv-header-height)`.
   ========================================================================== */

.wv-buy-bar--sticky {
  top: 0 !important;
}

body.admin-bar .wv-buy-bar--sticky {
  top: 46px !important;
}

@media (min-width: 768px) {
  .wv-buy-bar--sticky {
    top: var(--wv-header-height) !important;
  }
  body.admin-bar .wv-buy-bar--sticky {
    top: calc(var(--wv-header-height) + 32px) !important;
  }
}
