/* ==========================================================================
   BRAVO VALLEY - single product page layout
   ========================================================================== */

/* --------------------------------------------------------------------------
   The glass bar frames the content, so it has to be wider than what it sits
   over - never narrower. The widest container on this template is the product
   body (#brxe-bvcon3) at 1340px, so the bar runs 50px wider than that and
   falls back to its 16px viewport gutter once the screen can no longer afford
   the full width. Scoped to the product page: bv-product.css is enqueued site
   wide, and other templates keep the global 1180px bar.
   -------------------------------------------------------------------------- */
body.single-fluent-products{
  --bv-content-w:1340px;
  --bv-bar-w:min(calc(var(--bv-content-w) + 50px), calc(100vw - 32px));
}

.bv-section{ padding:56px 20px; }
@media (max-width:767px){ .bv-section{ padding-left:16px; padding-right:16px; } }

/* body already reserves the fixed header's height (--bv-offset), so the first
   section must not stack another 56px on top of it. */
#brx-content > .bv-section:first-child,
#brx-content > .brxe-section:first-child{ padding-top:4px; }

.bv-stack{ display:flex; flex-direction:column; gap:18px; }
/* Bricks .brxe-block defaults to flex-direction:column, so a row must say so. */
.bv-row{ display:flex; flex-direction:row; align-items:center; gap:10px; flex-wrap:wrap; }
.bv-row > *{ flex:0 0 auto; width:auto; }
/* ...except the hairline separator, whose whole job is a 1px width. */
.bv-row > .bv-vsep{ width:1px; }

/* --------------------------------------------------------------------------
   Hero: copy + offer on the left, gallery on the right (comp).
   Below 1000px it stacks with the gallery first (guideline s.25) - the product
   leads on mobile, it is not the desktop layout shrunk.
   -------------------------------------------------------------------------- */
.bv-hero-grid{ display:grid; grid-template-columns:1fr; gap:26px; align-items:start; }
.bv-hero-grid > *{ min-width:0; }
/* Tablet: the copy column is roughly half the width it has on desktop, so the
   parts inside it are compacted to the sizes the phone layout already uses.
   Without this the offer card's countdown - a grid 'auto' column - takes its
   intrinsic width and starves the price beside it, wrapping the MRP under the
   price and the savings chip onto three lines. */
@media (min-width:768px) and (max-width:1199px){
  .bv-offer{ padding:14px; gap:14px 16px; }
  .bv-offer__label{ font-size:.78rem; }

  /* Price and struck MRP share a line on desktop; hold that here too. */
  .bv-price__row{ flex-wrap:nowrap; gap:8px; }
  .bv-price__now{ font-size:1.55rem; }
  .bv-price__mrp{ font-size:.95rem; }
  .bv-price__save{ font-size:.7rem; padding:3px 8px; white-space:nowrap; }

  .bv-countdown-grid{ gap:5px; }
  .bv-cd-value{ min-width:42px; font-size:1.05rem; padding:6px 4px; }
  .bv-cd-colon{ line-height:36px; font-size:1rem; }

  /* Keeps "10K+ happy customers | Instant Download" on one line. */
  .bv-happy{ gap:8px; }
  .bv-happy .brxe-image{ height:28px; }
  .bv-happy .bv-proof__meta{ font-size:.84rem; }

  /* Four thumbnails visible in the narrower media column instead of three. */
  .bv-col-media .fct-gallery-thumb-control-button{ width:72px; height:72px; }
}

/* Tablet keeps the desktop two-column hero - copy left, gallery right - rather
   than stacking. The media column is fluid here instead of the desktop's fixed
   600px, so at 768-1199px the gallery scales down and leaves the copy column a
   usable measure. Desktop's fixed 600px still wins below, at 1200px up. */
@media (min-width:768px){
  .bv-hero-grid{
    grid-template-columns:minmax(0,1fr) minmax(0,clamp(300px,42vw,600px));
    gap:clamp(20px,2.6vw,40px);
  }
  /* .bv-col-media is a column flexbox with align-items:flex-start, so the
     gallery would shrink to its thumbnail row and leave a gutter beside the
     image. It has to be told to fill the column at every two-column width. */
  .bv-col-media .brxe-fct-product-gallery{ width:100%; }

  /* The copy column runs far longer than the gallery - roughly 950px against
     470px at tablet - which left a tall empty area beside it. The gallery
     follows the reader down instead of scrolling away.

     No align-self needed: .bv-hero-grid already sets align-items:start, so the
     column keeps its content height and has the row's full height to travel in.
     The offset clears the fixed glass header, which is 0px on header-less
     pages. */
  .bv-col-media{
    position:sticky;
    top:calc(var(--bv-offset, 74px) + 16px);
  }
}

@media (min-width:1200px){
  /* The media column is a fixed 600px rather than a fraction: FluentCart caps
     the main image at max-height:600px, so a wider column only stretched the
     square stage into a letterbox and cropped more off the artwork. Copy takes
     whatever is left. */
  .bv-hero-grid{ grid-template-columns:minmax(0,1fr) minmax(0,600px); gap:40px; }
}
/* Phones stack, gallery first - the product leads, it is not the desktop
   layout shrunk (guideline s.25). */
@media (max-width:767px){
  .bv-col-media{ order:-1; }
  .bv-col-copy{ order:0; }
  /* Stacked, both halves centre on a comfortable measure rather than spanning
     a 1200px-wide tablet edge to edge. */
  .bv-col-media{ align-items:center; }
  .bv-col-media .brxe-fct-product-gallery{ width:100%; max-width:600px; }
  .bv-col-media .fct-product-gallery-wrapper{ max-width:600px; margin-inline:auto; }
  .bv-col-copy{ max-width:720px; margin-inline:auto; width:100%; }
}

/* The theme-style H1 is a page-level display size (up to 96px). Inside the hero
   column that overflows, so the product title gets a card-scale display size.
   Weight, family and tracking still come from the "Bravo First" theme style. */
.bv-hero-grid .brxe-fct-product-title,
.bv-hero-grid h1{
  font-size:clamp(1.85rem, 1.25rem + 2.1vw, 2.9rem);
  line-height:1.08;
  letter-spacing:-.03em;
  margin:0;
  /* break-word split the serif title mid-word ("Conversation s"); only very
     long unbroken strings should ever break. */
  overflow-wrap:normal;
  word-break:normal;
  text-wrap:balance;
}

/* ==========================================================================
   Gallery (s.9): main image with a scrolling thumbnail row underneath it at
   every width - only the thumbnail size changes across breakpoints.

   FluentCart styles the rail through ".thumb-pos-right .fct-gallery-thumb-
   controls" (three classes), so every override below has to carry the wrapper
   class too or it silently loses the cascade.
   ========================================================================== */
.bv-col-media .fct-product-gallery-wrapper{
  display:flex; gap:14px; align-items:flex-start;
}
.bv-col-media .fct-product-gallery-thumb{
  flex:1 1 auto; min-width:0; position:relative;
  border:0 !important; border-radius:var(--bv-radius-md);
}
.bv-col-media .fct-product-gallery-thumb > img{
  width:100%; height:auto; display:block;
  border-radius:var(--bv-radius-md);
  background:var(--bv-grey);
}
.bv-col-media .fct-gallery-thumb-controls{ display:flex !important; gap:12px; }
.bv-col-media .fct-gallery-thumb-control-button{
  flex:0 0 auto !important;
  padding:0; background:transparent;
  border:2px solid transparent !important;
  border-radius:var(--bv-radius-sm) !important;
  box-shadow:none;
  overflow:hidden;
  transition:border-color var(--bv-motion-standard) var(--bv-ease);
}
.bv-col-media .fct-gallery-thumb-control-button.active{
  border-color:var(--bv-gold) !important;
  box-shadow:none;
}
.bv-col-media .fct-gallery-control-thumb{
  width:100%; height:100%; object-fit:cover; display:block;
  border-radius:calc(var(--bv-radius-sm) - 4px);
}

/* Desktop: the rail sits under the main image, not beside it, so the picture
   gets the media column's full width. It scrolls sideways when the gallery is
   longer than one row - the vertical rail this replaced scrolled the same way.
   The wrapper direction has to be set here because FluentCart's own
   ".thumb-pos-right" rule lays it out as a row. */
@media (min-width:1200px){
  /* .bv-col-media is a column flexbox with align-items:flex-start, so the
     gallery would shrink-to-fit the thumbnail row (608px) and leave a gutter
     beside the image. It has to be told to fill the column. */
  .bv-col-media .brxe-fct-product-gallery{ width:100%; }
  .bv-col-media .fct-product-gallery-wrapper{ flex-direction:column; align-items:stretch; }
  .bv-col-media .fct-product-gallery-wrapper .fct-product-gallery-thumb{
    height:auto; overflow:visible;
  }
  .bv-col-media .fct-product-gallery-wrapper .fct-gallery-thumb-controls{
    flex-flow:row nowrap; flex:0 0 auto; width:100%;
    overflow-x:auto; overflow-y:hidden;
    scroll-snap-type:x mandatory; padding-bottom:4px;
    scrollbar-width:none;
    /* "safe" so a gallery too long for the row falls back to flex-start -
     plain "center" would push the first thumbnails past the scroll origin
     where they can never be reached. */
    justify-content:safe center;
  }
  .bv-col-media .fct-gallery-thumb-controls::-webkit-scrollbar{ width:0; height:0; }
  /* Square, like the stage above them - the stage is object-fit:cover on a 1/1
     box, so a 112x94 thumb showed a different crop of the same picture. */
  .bv-col-media .fct-gallery-thumb-control-button{
    width:110px; height:110px; scroll-snap-align:start;
  }
}

/* Tablet and below: same row, smaller thumbnails and a visible scrollbar. */
@media (max-width:1199px){
  .bv-col-media .fct-product-gallery-wrapper{ flex-direction:column; align-items:stretch; }
  .bv-col-media .fct-product-gallery-wrapper .fct-product-gallery-thumb{
    height:auto; overflow:visible;
  }
  .bv-col-media .fct-product-gallery-wrapper .fct-gallery-thumb-controls{
    flex-flow:row nowrap; width:100%;
    overflow-x:auto; overflow-y:hidden;
    scroll-snap-type:x mandatory; padding-bottom:4px;
    scrollbar-width:thin;
    justify-content:safe center;
  }
  .bv-col-media .fct-gallery-thumb-control-button{
    width:92px; height:92px; scroll-snap-align:start;
  }
}
/* Mobile keeps the rail left-aligned: the row always overflows at this width,
   so it should start at the image's left edge and scroll from there. */
@media (max-width:640px){
  .bv-col-media .fct-product-gallery-wrapper .fct-gallery-thumb-controls{
    gap:8px; justify-content:flex-start;
  }
  .bv-col-media .fct-gallery-thumb-control-button{
    width:64px; height:64px; border-width:1.5px !important;
  }
}
/* Prev / next and dots are added by bv-product.js - FluentCart's gallery ships
   with thumbnails only, and the comp shows both. */
.bv-gal-nav{
  position:absolute; top:50%; transform:translateY(-50%);
  width:44px; height:44px; display:flex; align-items:center; justify-content:center;
  background:var(--bv-white); color:var(--bv-black);
  border:1px solid var(--bv-hairline); border-radius:50%;
  box-shadow:0 4px 14px rgba(26,26,26,.10);
  cursor:pointer; z-index:2;
  transition:transform var(--bv-motion-fast) var(--bv-ease);
}
.bv-gal-nav:hover{ transform:translateY(-50%) scale(1.05); }
.bv-gal-nav--prev{ left:14px; }
.bv-gal-nav--next{ right:14px; }
.bv-gal-nav svg{ width:20px; height:20px; }
.bv-gal-dots{
  position:absolute; left:0; right:0; bottom:16px;
  display:flex; justify-content:center; gap:7px; z-index:2;
}
.bv-gal-dot{
  width:8px; height:8px; border-radius:50%; border:0; padding:0;
  background:rgba(26,26,26,.22); cursor:pointer;
  transition:background var(--bv-motion-fast) var(--bv-ease), width var(--bv-motion-fast) var(--bv-ease);
}
.bv-gal-dot.is-active{ background:var(--bv-gold); width:18px; border-radius:4px; }
@media (max-width:520px){
  .bv-gal-nav{ width:38px; height:38px; }
  .bv-gal-nav--prev{ left:8px; }
  .bv-gal-nav--next{ right:8px; }
}

/* ==========================================================================
   Narrow screens: the offer card and countdown are the tightest runs here.
   ========================================================================== */
@media (max-width:520px){
  .bv-offer{ padding:14px; gap:14px 16px; }
  .bv-offer__label{ font-size:.78rem; }
  .bv-countdown-grid{ gap:5px; }
  .bv-cd-value{ min-width:44px; font-size:1.1rem; padding:6px 4px; }
  .bv-cd-colon{ line-height:38px; font-size:1rem; }
  .bv-price__mrp{ font-size:.95rem; }
  .bv-trust__item{ padding:4px 5px; gap:7px; }
  .bv-trust__item .icon svg{ width:22px; height:22px; }
  .bv-trust__item .content,
  .bv-trust__item .content p{ font-size:.58rem; letter-spacing:.04em; }
  .bv-feat{ font-size:.78rem; padding:9px 11px; gap:6px; }
  .bv-buy--wide{ min-height:56px; font-size:1rem; }
}


/* ==========================================================================
   Sticky purchase bar (guideline s.15 / s.16)
   Present on BOTH desktop and mobile. Level 3 "Floating Glass".
   Hidden until the visitor has scrolled a full viewport.
   ========================================================================== */
.bv-bar{
  position:fixed; z-index:900;
  left:50%; bottom:0;
  width:min(1180px, calc(100vw - 24px));
  margin-bottom:14px;
  border:1px solid var(--bv-glass-border);
  border-radius:var(--bv-radius-xl);
  padding:12px 14px;
  display:flex; flex-direction:column; gap:10px;
  /* NO backdrop-filter here any more - the bar is real liquid glass now and
     the blur travels with the displacement on .bv-glass__refract. Leaving one
     here would make the bar a Backdrop Root, and the refraction layer inside
     it would have had no page behind it left to sample: a flat grey slab.
     See LIQUID-GLASS.md 5.1. */
}

/* The bar wears .bv-glass (set on the Bricks element). Two things that class
   needs from its host, both of which this bar would otherwise break:

   1. Its own positioning restated. .bv-glass sets position:relative at
      single-class specificity to anchor its layers; unopposed that drops this
      fixed bar into the page flow. Two classes here so it wins regardless of
      which stylesheet loads last - bv-product.css does not depend on
      bv-glass-header.css, so the order is not guaranteed. (LIQUID-GLASS.md 5.9)
   2. Nothing on the host that creates a Backdrop Root - see the note above. */
.bv-bar.bv-glass{
  position:fixed;
  /* A price, a countdown and two buttons sit on this, so it is veiled harder
     than the header pill. Both are tunable per element in the Liquid Glass
     admin panel, where the bar now appears on its own as .bv-bar. */
  --bv-glass-fill:rgba(255,255,255,.55);
  --bv-glass-blur:14px;

  /* .bv-card--float paints an opaque .84 white - the old fake-glass look, from
     before this bar could actually bend anything. Real glass has to supply its
     own fill or there is nothing left to see through, so this takes it back.
     Its shadow is kept and restated: that one throws light UPWARD from a
     bottom-anchored bar, which the glass component's default does not. */
  background:var(--bv-glass-fill);

  /* No border of its own, and no inset top highlight - .bv-glass__rim already
     draws the edge, and it draws a better one (a chromatic hairline rather
     than a flat white line).

     Both had to go, not just look redundant. Glass layers are absolutely
     positioned, so they size to the PADDING box: with a 1px border on the host
     the rim landed 1px inside it, and a 30px radius on a box 2px smaller
     cannot nest concentrically inside a 30px radius. The result was two edges
     a pixel apart that disagreed around every corner. */
  border:0;
  box-shadow:0 -2px 40px rgba(26,26,26,.10),
             0 12px 40px rgba(26,26,26,.08);
}

/* .bv-glass lifts its own non-layer children above the glass, but on desktop
   .bv-bar__main is display:contents - so its children are not direct children
   of the bar and are never matched. Without this the price, countdown and
   buttons paint underneath the lens and specular layers. */
.bv-bar.bv-glass > *:not([class*="bv-glass__"]),
.bv-bar.bv-glass .bv-bar__main > *{ position:relative; z-index:6; }

/* Every part of the bar is a native Bricks block, and Bricks gives those
   width:100% and flex-direction:column. Inside the bar each part sizes to its
   own content and lays out in a row instead - the two parts that really are
   columns (.bv-bar__price and .field) say so themselves below - hence :where(),
   which keeps this reset at a single class so every rule after it wins. The bar
   itself is not matched: it is the parent, and sets its own width and direction. */
.bv-bar :where(.brxe-block){ width:auto; flex-direction:row; }

.bv-bar__count{
  display:flex; align-items:center; justify-content:center; gap:12px;
  flex-wrap:wrap;
}
.bv-bar__count-label{ font-size:.85rem; color:var(--bv-black); font-weight:500; }
/* The bar's countdown has no HRS/MINS/SECS captions, so a clock marks the
   digits as a running time rather than three loose numbers. */
.bv-bar__count-ico{ width:16px; height:16px; flex:none; color:var(--bv-ink-soft); }
.bv-bar__count-grid{ display:inline-flex; gap:7px; }
/* Unit sits beside its number - "04 hrs" - not stacked under it. Baseline
   alignment is what makes the small caption sit on the digits' baseline rather
   than floating mid-chip. */
.bv-bar__count-grid .field{
  display:inline-flex; flex-direction:row; align-items:baseline;
  gap:3px; padding:4px 8px;
  background:#F7E4C4; border-radius:10px;
}
.bv-bar__count-grid .value{
  font-size:1rem; font-weight:700; line-height:1.15;
  color:var(--bv-black); font-variant-numeric:tabular-nums;
}
.bv-bar__count-grid .label{
  font-size:.62rem; letter-spacing:.01em; text-transform:none;
  color:var(--bv-ink-soft); line-height:1;
}

.bv-bar__main{ display:flex; align-items:center; gap:12px; }
.bv-bar__media{ flex:none; display:none; }
/* The bar's thumbnail is a native Bricks image element, so the class may sit on
   a wrapper rather than the img itself - style both. */
.bv-bar__thumb,
.bv-bar__media img{
  width:52px; height:52px; object-fit:cover; display:block;
  border-radius:var(--bv-radius-sm); border:1px solid var(--bv-hairline);
  background:var(--bv-grey);
}
/* Sale price with the struck MRP to its right, savings chip on the line below -
   the same shape as .bv-price in the hero, and built the same way: a column
   holding a nested row.

   Deliberately NOT one wrapping row with flex-basis:100% on the chip. That put
   the chip on its own line but also stretched it to the full width of the price
   block, so its green background ran the whole width instead of hugging the
   text. align-items:flex-start on a column is what keeps the chip its own size. */
.bv-bar__price{
  display:flex; flex-direction:column; align-items:flex-start; gap:2px;
  min-width:0; margin-right:auto;
}
.bv-bar__pricerow{
  display:flex; flex-direction:row; flex-wrap:wrap;
  align-items:baseline; column-gap:8px; row-gap:0;
}
.bv-bar__mrp{ font-size:.78rem; color:var(--bv-ink-soft); }
.bv-bar__mrp s{ text-decoration:line-through; }
.bv-bar__now{
  font-size:1.4rem; font-weight:700; line-height:1.1;
  letter-spacing:-.02em; color:var(--bv-black);
}
.bv-bar__price .bv-price__save{ font-size:.72rem; padding:3px 8px; }

.bv-bar .bv-atc{ width:48px; height:48px; }
.bv-bar .bv-buy{ min-height:48px; padding:0 22px; font-size:.98rem; flex:1 1 auto; max-width:230px; }

/* Mobile: rounded upper corners, flush to the bottom edge (s.16) */
@media (max-width:767px){
  .bv-bar{
    width:100%; left:0; margin-bottom:0;
    border-radius:var(--bv-radius-lg) var(--bv-radius-lg) 0 0;
    border-bottom:0;
    gap:8px;
    padding:10px 14px calc(10px + env(safe-area-inset-bottom, 0px));
  }
  /* Label and countdown share one line; they fit inside 375px. */
  .bv-bar__count{ flex-direction:row; align-items:center; justify-content:center; gap:10px; flex-wrap:nowrap; }
  .bv-bar__count-label{ font-size:.8rem; }
  .bv-bar__count-grid{ gap:6px; }
  .bv-bar__count-grid .field{ padding:3px 6px; gap:2px; }
  .bv-bar__count-grid .value{ font-size:.95rem; }

  /* Bricks gives .brxe-block align-items:flex-start, and .bv-bar is itself one,
     so the bar's own rows shrink to their content: the countdown row was 262px
     of the 345 available and its justify-content:center therefore did nothing,
     leaving it visibly off to the left. */
  .bv-bar{ align-items:stretch; }

  /* Price, struck MRP and the savings chip stacked three deep made the bar
     137px tall - a sixth of a 812px screen, reserved permanently at the bottom
     of every product page. Price and MRP share a line here, chip underneath.

     'flex:1 1 0' matters: left to size itself the price block grows to its
     content and pushes the buy button onto a row of its own, which is taller
     still. Boxed into whatever the two buttons leave (~125px at 375), the type
     sizes below are what let price + MRP actually fit on that one line. */
  .bv-bar__price{ flex:1 1 0; min-width:0; }
  .bv-bar__pricerow{ column-gap:6px; }
  .bv-bar__now{ font-size:1.15rem; }
  .bv-bar__mrp{ font-size:.66rem; white-space:nowrap; }
  .bv-bar__price .bv-price__save{ font-size:.65rem; padding:2px 7px; white-space:nowrap; }
  .bv-bar .bv-buy{ flex:0 1 auto; min-width:0; }

  .bv-bar__main{ gap:10px; }
  .bv-bar__now{ font-size:1.3rem; }
  .bv-bar__mrp{ font-size:.72rem; }
  .bv-bar .bv-atc{ width:50px; height:50px; }
  /* Trimmed from 18px: the padding here is what decides how much of the row is
     left for the price block, and price + struck MRP need ~130px to share a
     line rather than stacking into a third row. */
  .bv-bar .bv-buy{ max-width:none; min-height:50px; padding:0 12px; font-size:.95rem; }
}

/* Very narrow phones: at 320px the price block is left ~84px beside the cart
   and buy buttons, which clipped the savings chip off the edge of the bar. The
   price info takes a full-width line of its own there and the two buttons share
   the line below, so nothing is ever cut off. */
@media (max-width:360px){
  /* "Limited Time Offer 04 hrs 40 mins 10 secs" needs ~295px and only has 290,
     so it broke onto two rows. Trimmed just enough to hold one line. */
  .bv-bar__count{ gap:6px; }
  /* nowrap on both: the row needed 291px of the 290 available, and the grid
     inherits flex-wrap:wrap, so it dropped "secs" to a second line rather than
     letting the line shrink. */
  .bv-bar__count-label{ font-size:.68rem; white-space:nowrap; }
  .bv-bar__count-grid{ gap:5px; flex-wrap:nowrap; }
  .bv-bar__count-grid .field{ padding:3px 5px; gap:2px; }
  .bv-bar__count-grid .value{ font-size:.9rem; }
  .bv-bar__count-grid .label{ font-size:.58rem; }

  .bv-bar__main{ flex-wrap:wrap; row-gap:8px; }
  .bv-bar__price{ flex:1 1 100%; margin-right:0; }
  .bv-bar .bv-buy{ flex:1 1 auto; }
}


/* Desktop: one row, thumbnail visible, countdown inline */
@media (min-width:768px){
  .bv-bar{ flex-direction:row; align-items:center; gap:18px; padding:12px 16px; }
  

.bv-bar__count{
    order:2; gap:10px;
    padding:0 18px; margin-left:auto;
    border-left:1px solid var(--bv-hairline);
    border-right:1px solid var(--bv-hairline);
  }
  /* Actions belong after the countdown, so the "main" wrapper dissolves into
     the bar's own flex line and each part is ordered directly. */
  .bv-bar__main{ display:contents; }
  .bv-bar__media{ display:block; order:1; }
  .bv-bar__price{ order:1; margin-right:0; }
  .bv-bar .bv-atc{ order:3; }
  .bv-bar .bv-buy{ order:4; flex:0 0 auto; min-width:190px; }
}

/* Tablet: the bar has to hold thumbnail, price, countdown and two buttons on a
   single row, and below 1024 there is not enough width - the countdown was
   wrapping onto a second line and making the bar 59px taller. The thumbnail is
   the least useful of them, so it goes first, and the countdown is trimmed. */
/* The thumbnail is the first thing to go: below 1024 the bar cannot hold it as
   well as price, countdown and two buttons on one row. */
@media (min-width:768px) and (max-width:1023px){
  .bv-bar__media{ display:none; }
}

/* Countdown compaction runs the whole tablet range, not just below 1024: at
   exactly 1024 the thumbnail comes back and the row is tight again, so the
   countdown wrapped there too. Full desktop sizing resumes at 1200. */
@media (min-width:768px) and (max-width:1199px){
  /* nowrap on .bv-bar__count itself: it defaults to wrap, so the digits dropped
     below the label instead of the row simply being tight. Everything below is
     what buys the ~300px that one line needs out of the ~276px on offer. */
  .bv-bar__count{ gap:8px; flex-wrap:nowrap; }
  .bv-bar__count-label{ font-size:.72rem; white-space:nowrap; }
  .bv-bar__count-grid{ gap:5px; flex-wrap:nowrap; }
  .bv-bar__count-grid .field{ padding:3px 5px; gap:2px; }
  .bv-bar__count-grid .value{ font-size:.95rem; }
  .bv-bar__count-grid .label{ font-size:.58rem; }

  .bv-bar .bv-atc{ width:44px; height:44px; }
  .bv-bar .bv-buy{ min-height:44px; padding:0 16px; min-width:0; }
}

/* Reveal after one full viewport of scrolling (JS adds .is-visible). Space below
   the page is reserved from the start regardless, so the bar arriving never
   shifts the layout. visibility:hidden keeps the box measurable, which is what
   reserveSpace() reads. */
.bv-bar{
  opacity:0; visibility:hidden; pointer-events:none;
  transform:translateX(-50%) translateY(calc(100% + 24px));
  transition:opacity var(--bv-motion-standard) var(--bv-ease),
             transform var(--bv-motion-slow) var(--bv-ease),
             visibility 0s linear var(--bv-motion-slow);
}
.bv-bar.is-visible{
  opacity:1; visibility:visible; pointer-events:auto;
  transform:translateX(-50%);
  transition:opacity var(--bv-motion-standard) var(--bv-ease),
             transform var(--bv-motion-slow) var(--bv-ease),
             visibility 0s;
}
@media (max-width:767px){
  .bv-bar{ transform:translateY(calc(100% + 24px)); }
  .bv-bar.is-visible{ transform:none; }
}
@media (prefers-reduced-motion:reduce){
  .bv-bar,.bv-bar.is-visible{ transition:opacity var(--bv-motion-fast) linear; }
}

/* Keep the bar from covering content (s.16). Height is measured at runtime. */
body.bv-has-bar{ padding-bottom:var(--bv-bar-space, 150px); }

/* FluentCart's floating cart bubble is removed: it duplicates the header cart
   and collides with the sticky purchase bar. The drawer itself still works -
   the header mini-cart carries the same data-fluent-cart-cart-expand-button. */
.fct-cart-drawer-open-btn{ display:none !important; }

/* ==========================================================================
   Phones: the proof line and the offer card are the two runs that stop
   fitting first, so they are tightened rather than allowed to wrap apart.
   ========================================================================== */
@media (max-width:430px){
  .bv-happy{ gap:8px; }
  .bv-happy .brxe-image{ height:28px; }
  .bv-happy .bv-proof__meta{ font-size:.84rem; }
  .bv-offer__col{ gap:7px; }
  .bv-price__save{ font-size:.7rem; padding:3px 8px; }
  .bv-price__row{ gap:8px; }
}

/* Smaller phones: hold the two-column offer card from the comp by tightening
   the digits and the proof line rather than letting either stack. */
@media (max-width:400px){
  .bv-offer{ padding:13px 12px; gap:12px; }
  /* The savings string runs longer than the comp's at bigger discounts, and
     the price column is only ~150px here, so hold it on one line. */
  .bv-price__save{ font-size:.65rem; padding:3px 7px; white-space:nowrap; }
  .bv-countdown-grid{ gap:4px; }
  .bv-cd-value{ min-width:38px; font-size:1.02rem; padding:6px 3px; }
  .bv-cd-colon{ line-height:34px; font-size:.9rem; }
  .bv-cd-label{ font-size:.52rem; letter-spacing:.06em; }
  .bv-happy{ gap:6px; }
  .bv-happy .brxe-image{ height:25px; }
  .bv-happy .bv-proof__meta{ font-size:.77rem; }
  .bv-happy .bv-vsep{ height:17px; }
}
/* Only the very narrowest devices give up the two columns. */
@media (max-width:339px){
  .bv-offer{ grid-template-columns:1fr; }
}
