/* ══════════════════════════════════════════════════════════════════
   BBA ambient-motion layer — "The Trace".
   Every motion on the site is a laboratory instrument writing the
   product's own data: a pen-plotter line, a rule that draws, a label
   that ticks up from the vial it names. It switches OFF at the point
   of payment (cart, checkout, buy box, pay/load/account).

   SELF-CONTAINED BY LAW (same as site-header.css): this sheet lands on
   both token families (store --f-* / editorial --*), so it consumes only
   its own --bm-* properties. An unresolvable var() silently kills the
   whole declaration.

   FAIL-OPEN BY LAW: nothing here hides content unless <html> carries
   .bba-motion, which bba-motion.js adds only AFTER its observer is armed
   and removes on any error. Print and reduced-motion restore everything
   unconditionally. Hiding rules are !important on purpose — the
   homepage's reveal-failsafe forces opacity:1 !important on its old
   targets, and a gated rule with higher specificity is the only way to
   choreograph those without editing that page.
═══════════════════════════════════════════════════════════════════ */
:root{
  --bm-ink:#14181C;
  --bm-teal:#0C6E78;
  --bm-teal-bright:#2BB9C9;
  --bm-paper:#F2F1EE;
  --bm-hair:rgba(20,26,32,.12);
  --bm-mute:rgba(20,24,28,.62);
  --bm-mono:'IBM Plex Mono',Consolas,'Courier New',monospace;
  --bm-sans:'IBM Plex Sans',system-ui,-apple-system,'Segoe UI',sans-serif;
  /* One easing family. Enter is the site's own --di-ease; exit is faster (Material's 2/3 rule). */
  --bm-ease:cubic-bezier(.2,.75,.3,1);
  --bm-ease-exit:cubic-bezier(.4,0,.6,1);
  --bm-fast:140ms;      /* press, hover colour */
  --bm-base:260ms;      /* drawer, accordion, page crossfade */
  --bm-slow:560ms;      /* a block rising into view */
  --bm-draw:1100ms;     /* a rule being drawn */
  --bm-rise:10px;
}

/* ── reveal grammar ─────────────────────────────────────────────────
   .bm-rv is applied by JS in reading order; --bm-d carries the stagger. */
/* The hidden state SNAPS (transition:none): a hiding rule that transitions would fade a block
   out over the reveal duration and could be caught mid-fade. The reveal still animates
   because a transition is taken from the after-change style. */
html.bba-motion .bm-rv:not(.bm-in){
  opacity:0 !important;
  transform:translateY(var(--bm-rise)) !important;
  transition:none;
}
html.bba-motion .bm-rv{
  --bm-d:0ms;
  transition:opacity var(--bm-slow) var(--bm-ease),transform var(--bm-slow) var(--bm-ease);
  transition-delay:var(--bm-d);
}
html.bba-motion .bm-rv.bm-in{opacity:1;transform:none}
/* a card that also lifts on hover must not inherit the reveal transition's delay */
html.bba-motion .bm-rv.bm-in.bm-settled{transition-delay:0ms}

/* ── landing header entrance (homepage only) ─────────────────────────
   Copy rises line by line; the photograph settles in scale (never
   opacity — it is the LCP element); each vial's label ticks up from
   its base after the photo has landed.
   html.bm-pre is set by a one-line head snippet BEFORE first paint (so
   the copy never paints and then re-animates). It is the one hiding
   rule that does not wait for the JS gate — which is why it carries a
   CSS-only escape: 2.6 s after load the copy is shown regardless. */
html.bm-pre .bh:not(.bm-hero-in) .bh-title,
html.bm-pre .bh:not(.bm-hero-in) .bh-lede,
html.bm-pre .bh:not(.bm-hero-in) .bh-ctas,
html.bm-pre .bh:not(.bm-hero-in) .bh-fine{opacity:0;transform:translateY(14px);animation:bm-hero-failsafe 480ms var(--bm-ease) 2600ms forwards}
html.bm-pre .bh:not(.bm-hero-in) .bh-photo img{transform:scale(1.018)}
@keyframes bm-hero-failsafe{to{opacity:1;transform:none}}
html.bba-motion .bh .bh-title,html.bba-motion .bh .bh-lede,html.bba-motion .bh .bh-ctas,html.bba-motion .bh .bh-fine{
  transition:opacity 680ms var(--bm-ease),transform 680ms var(--bm-ease)}
html.bba-motion .bh .bh-lede{transition-delay:90ms}
html.bba-motion .bh .bh-ctas{transition-delay:180ms}
html.bba-motion .bh .bh-fine{transition-delay:270ms}
html.bba-motion .bh .bh-photo img{transition:transform 1400ms var(--bm-ease)}
html.bba-motion .bh .bh-tag{--bm-i:0}
html.bba-motion .bh.is-placed:not(.bm-hero-in) .bh-tick{transform:scaleY(0);transition:none}
html.bba-motion .bh.is-placed:not(.bm-hero-in) .bh-lbl{opacity:0;transform:translateY(6px);transition:none}
html.bba-motion .bh .bh-tick{transform-origin:top center;transition:transform 520ms var(--bm-ease);transition-delay:calc(560ms + var(--bm-i) * 90ms)}
html.bba-motion .bh .bh-lbl{transition:opacity 420ms var(--bm-ease),transform 420ms var(--bm-ease),border-color var(--bm-fast) ease,color var(--bm-fast) ease,box-shadow var(--bm-fast) ease;transition-delay:calc(760ms + var(--bm-i) * 90ms)}
html.bba-motion .bh.bm-hero-in.bm-settled .bh-lbl{transition-delay:0ms}

/* ── the rule that draws itself ─────────────────────────────────────
   A 1px teal line traced left-to-right along a section rule, then it
   fades and leaves the hairline behind. Inserted by JS as <i class="bm-rule">. */
html.bba-motion .bm-has-rule{position:relative}
.bm-rule{position:absolute;left:0;right:0;bottom:-1px;height:1px;background:var(--bm-teal);transform:scaleX(0);transform-origin:left center;pointer-events:none}
.bm-rule.bm-rule-top{top:-1px;bottom:auto}
html.bba-motion .bm-in .bm-rule,html.bba-motion .bm-in.bm-rule{animation:bm-draw var(--bm-draw) var(--bm-ease) 120ms forwards}
@keyframes bm-draw{0%{transform:scaleX(0);opacity:1}64%{transform:scaleX(1);opacity:1}100%{transform:scaleX(1);opacity:0}}

/* ── the one canvas: a quiet lab trace above the certificate cards ─── */
.bm-trace-wrap{position:relative;margin:22px 0 22px;background:#fff;border:1px solid var(--bm-hair);border-radius:2px;overflow:hidden}
.bm-trace-wrap::after{content:"";position:absolute;top:-1px;right:-1px;width:9px;height:9px;border-top:1px solid var(--bm-teal);border-right:1px solid var(--bm-teal);pointer-events:none}
.bm-trace{display:block;width:100%;height:150px}
@media(max-width:700px){.bm-trace{height:120px}}

/* ── control grammar (press + hover), never on layout transforms ───── */
html.bba-motion :is(.price-row-btn,.fc-add-btn,.bh-btn,.pill,.size-pill,.addbtn,.shop-search-submit,.rev-filter-btn,.cf-btn,.cf-result-add,.head-cta,.cta a,.vbox .go,.rc-unit-btn){
  transition:transform var(--bm-fast) var(--bm-ease),background-color var(--bm-fast) ease,border-color var(--bm-fast) ease,color var(--bm-fast) ease,box-shadow var(--bm-base) var(--bm-ease)}
html.bba-motion :is(.price-row-btn,.fc-add-btn,.bh-btn,.pill,.size-pill,.addbtn,.shop-search-submit,.rev-filter-btn,.head-cta,.cta a,.vbox .go):active{transform:scale(.97)}
html.bba-motion :is(.live-card,.coa-card,.post-card,.more-card,.rec,.hiw-ship){transition-property:transform,box-shadow,border-color,opacity;transition-duration:var(--bm-base),var(--bm-base),var(--bm-fast),var(--bm-slow);transition-timing-function:var(--bm-ease)}
html.bba-motion .live-card.bm-in{transition:transform var(--bm-base) var(--bm-ease),box-shadow var(--bm-base) var(--bm-ease),border-color var(--bm-fast) ease,opacity var(--bm-slow) var(--bm-ease)}

/* cart badge tick — fires when the count changes */
.bm-pop{animation:bm-pop 480ms var(--bm-ease)}
@keyframes bm-pop{0%{transform:scale(1)}38%{transform:scale(1.32)}100%{transform:scale(1)}}

/* accordions + the mobile drawer: a beat of fade, exit faster than enter */
html.bba-motion details[open]>:not(summary){animation:bm-fade var(--bm-base) var(--bm-ease)}
html.bba-motion .bba-drawer.open,html.bba-motion .mobile-nav-drawer.open{animation:bm-drop var(--bm-base) var(--bm-ease)}
html.bba-motion .bba-more[open] .bba-more-menu,html.bba-motion .header-more[open] .header-more-menu{animation:bm-drop 200ms var(--bm-ease)}
@keyframes bm-fade{from{opacity:0}to{opacity:1}}
@keyframes bm-drop{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}

/* in-page anchors glide; the sticky header already reserves the landing space */
html.bba-motion{scroll-behavior:smooth}

/* ── page-to-page: the header stays put, the page crossfades (Chromium 126+ / Safari 18.2+) ── */
@view-transition{navigation:auto}
::view-transition-old(root){animation:bm-vt-out 160ms var(--bm-ease-exit)}
::view-transition-new(root){animation:bm-vt-in 240ms var(--bm-ease)}
@keyframes bm-vt-out{to{opacity:0}}
@keyframes bm-vt-in{from{opacity:0}}
html.bba-motion .bba-header,html.bba-motion .site-header{view-transition-name:bm-header}

/* ── money surface: the instrument is switched off ───────────────────── */
html.bba-motion :is(#checkout,#cart,.checkout-section,#cart-drawer-root,.buy,#purchase-options) .bm-rv{opacity:1 !important;transform:none !important;transition:none !important}

/* ── the two unconditional escapes ─────────────────────────────────────── */
@media print{
  .bm-rv,.bh .bh-title,.bh .bh-lede,.bh .bh-ctas,.bh .bh-fine,.bh .bh-lbl,.bh .bh-tick,.bh .bh-photo img{opacity:1 !important;transform:none !important;animation:none !important;transition:none !important}
  .bm-trace-wrap{display:none !important}
}
@media (prefers-reduced-motion:reduce){
  html.bba-motion .bm-rv,html.bba-motion .bm-rv:not(.bm-in),
  html.bba-motion .bh .bh-title,html.bba-motion .bh .bh-lede,html.bba-motion .bh .bh-ctas,html.bba-motion .bh .bh-fine,
  html.bm-pre .bh .bh-title,html.bm-pre .bh .bh-lede,html.bm-pre .bh .bh-ctas,html.bm-pre .bh .bh-fine,html.bm-pre .bh .bh-photo img,
  html.bba-motion .bh .bh-lbl,html.bba-motion .bh .bh-tick,html.bba-motion .bh .bh-photo img{opacity:1 !important;transform:none !important;transition:none !important;animation:none !important}
  .bm-rule{display:none}
  html.bba-motion{scroll-behavior:auto}
  ::view-transition-old(root),::view-transition-new(root){animation:none}
  .bm-pop,html.bba-motion details[open]>:not(summary),html.bba-motion .bba-drawer.open{animation:none}
  html.bba-motion :is(.price-row-btn,.fc-add-btn,.bh-btn,.pill,.size-pill):active{transform:none}
}
