/* ============================================================
   Template 1: Brand Product — template-specific styles
   Layered on top of shared/css/base.css and shared/css/components.css
   ============================================================ */

/* ----- Deal banner — full-width sticky band, crimson gradient with
   abstract curved swooshes overlaid (Flash-sale-poster inspo, scaled
   down to a slim band). Hidden by default. */
.bp-deal-banner {
  display: none;
  position: fixed;     /* sticky was broken by html { overflow-x: hidden } */
  top: 0;
  left: 0;
  right: 0;
  z-index: 90;
  overflow: hidden;
  background: #00B67A;            /* Trustpilot mint — matches £77 total + savings green */
  color: #fff;
}
/* Push the rest of the page down by the banner's height when active. */
body.is-promo-active { padding-top: 34px; }
body.is-promo-active .bp-deal-banner { display: block; }
/* (Decorative swooshes removed — flat black reads cleaner.) */
.bp-deal-banner__inner {
  position: relative;
  z-index: 1;
  max-width: 1080px;
  margin: 0 auto;
  padding: 6px 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-align: center;
}
/* Strikethrough on main-page CTA buttons when a promo is active.
   Toggled by JS that wraps the strike + new price in a nowrap pair so
   they never break to a second line. */
.cta-pricepair {
  white-space: nowrap;
  display: inline-block;
}
.cta-strike {
  text-decoration: line-through;
  opacity: 0.55;
  margin-right: 0;
  font-weight: 500;
  font-size: 0.85em;
}
/* Sticky bar is compact — keep strike tight so it doesn't swamp the CTA. */
.mobile-stickybar .cta-strike { font-size: 0.75em; }
.mobile-stickybar .cta-pricepair { letter-spacing: -0.005em; }

/* Darker purpley-pink heart — pops against the electric pink banner.
   Crimson would blend; this deeper berry tone sits proud. */
.bp-deal-banner__heart {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  color: #A8005C;
  transform-origin: center;
  animation: bp-deal-heart 1.6s ease-in-out infinite;
}
@keyframes bp-deal-heart {
  0%, 100% { transform: scale(1);    }
  15%      { transform: scale(1.12); }
  30%      { transform: scale(1);    }
  45%      { transform: scale(1.08); }
  60%      { transform: scale(1);    }
}
@media (prefers-reduced-motion: reduce) {
  .bp-deal-banner__heart { animation: none; }
}
@media (prefers-reduced-motion: reduce) {
  .bp-deal-banner__flame { animation: none; }
}
.bp-deal-banner__copy {
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
  line-height: 1.2;
}
.bp-deal-banner__title {
  font-family: 'Source Serif 4', Georgia, serif;
  font-style: italic;
  font-size: 15px;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.005em;
  white-space: nowrap;
}
.bp-deal-banner__sep {
  color: rgba(255, 255, 255, 0.45);
  font-weight: 400;
  font-size: 14px;
  line-height: 1;
}
.bp-deal-banner__sub {
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 700;
  color: #fff;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  white-space: nowrap;
}
@media (max-width: 640px) {
  .bp-deal-banner__inner { padding: 5px 12px; gap: 8px; }
  .bp-deal-banner__copy { gap: 6px; }
  .bp-deal-banner__title { font-size: 13px; }
  .bp-deal-banner__sep { font-size: 12px; }
  .bp-deal-banner__sub { font-size: 11px; letter-spacing: 0.10em; }
}

/* ----- Layout shells ----- */
.bp-shell {
  max-width: 1100px;
  margin: 0 auto;
  padding: 0 20px;
}
.bp-shell--narrow {
  max-width: 680px;
}

/* ----- Hero ----- */
.bp-hero {
  padding: 20px 0 30px;
  text-align: center;
  /* Sized to its content. We previously forced 100dvh on mobile to
     stop the next section peeking in at fold, but on tall iPhones
     that left a chunk of empty white below the guarantee line.
     Letting it size naturally now — on smaller phones the hero
     content fills the viewport on its own; on taller phones the
     samples carousel flows up sooner, which is the desired effect. */
  display: flex;
  flex-direction: column;
}
.bp-hero__brand {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  margin-bottom: 8px;
}
.bp-hero__logo {
  height: 40px;
  width: auto;
}
@media (max-width: 720px) {
  .bp-hero__logo { height: 32px; }
}
/* Cover board grid (display: grid) is defined in shared/css/components.css.
   Only template-specific overrides go here. */
.bp-hero__ticker-wrap {
  position: relative;
  width: 100%;
  margin: 0 auto 17px;
}
.bp-hero__ticker-stack {
  margin: 0 auto;
}
/* Floating "Listen to samples" jump button. Solid white pill centred on
   the cover board. Black label, red pulsing play icon. Solid background
   (no backdrop-filter) avoids the Safari/Chrome bug where a re-painted
   element with backdrop-filter loses its foreground content on scroll back. */
.bp-hero__sample-jump {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 10px 16px 10px 13px;
  background: #fff;
  color: var(--ink);
  border: none;
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: 13px;
  letter-spacing: -0.005em;
  text-decoration: none;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
  transition: transform 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
  white-space: nowrap;
  will-change: transform;
}
.bp-hero__sample-jump:hover {
  animation: none;
  transform: translate(-50%, -50%) scale(1.06);
  background: rgba(255, 255, 255, 1);
  box-shadow: 0 5px 14px rgba(0, 0, 0, 0.16);
}
.bp-hero__sample-jump-icon {
  display: block;
  color: var(--crimson);
  transform-origin: center;
}
/* Whole-button gentle pulse — soft scale breathe, slow rhythm so it
   reads as a "tap me" hint rather than a noisy alert. */
.bp-hero__sample-jump {
  animation: bp-sample-jump-pulse 3.6s ease-in-out infinite;
}
@keyframes bp-sample-jump-pulse {
  0%, 100% { transform: translate(-50%, -50%) scale(1);    }
  50%      { transform: translate(-50%, -50%) scale(1.04); }
}
@media (prefers-reduced-motion: reduce) {
  .bp-hero__sample-jump { animation: none; }
}
.bp-hero__kicker {
  display: block;
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--crimson);
  margin: 0 0 10px;
}
.bp-hero__h1 {
  font-family: 'Rubik', 'Source Serif 4', sans-serif;
  font-weight: 900;
  font-size: 44px;
  line-height: 1.08;
  letter-spacing: -0.02em;
  max-width: 720px;
  margin: 0 auto 7px;
  text-wrap: balance;          /* keeps the title to 2 evenly-balanced lines */
}
/* All-caps treatment for short, punchy variants — opt in via class */
.bp-hero__h1--allcaps {
  text-transform: uppercase;
  letter-spacing: -0.07em;
  word-spacing: 0.08em;
  line-height: 1.05;
}
.bp-hero__sub {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 20px;
  line-height: 1.35;
  color: var(--ink-soft);
  max-width: 540px;
  margin: 0 auto 22px;
}
.bp-hero__cta-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 7px;
  margin-bottom: 2px;
}
.bp-hero__cta {
  font-size: 19px;
  padding: 20px 44px;
}
/* Guarantee text — plain black text under the CTA. Same treatment in
   the hero CTA wrap and the offer card so the page feels consistent. */
.bp-hero__cta-wrap .cta-sub,
.bp-offer .cta-sub {
  margin-top: 8px;
  color: var(--ink);
  font-size: 13px;
  font-weight: 600;
  font-family: 'Poppins', sans-serif;
}
.bp-hero__cta-wrap .cta-sub {
  margin-top: 0;
}

/* Mid-tier CTA sizing — Offer card runs 2px smaller than Final because
   the offer panel is narrower (matches the audio player width); the
   smaller font keeps the price + strike from feeling crushed. Final +
   sticky stay at the standardised mid-tier size. */
.bp-offer .cta--full {
  font-size: 15px;
  padding: 16px 22px;
}
.bp-final-cta .cta {
  font-size: 17px;
  padding: 18px 24px;
}
.mobile-stickybar .cta {
  font-size: 16px;
  padding: 14px 20px;
}

/* Lift the offer section 20px closer to the hero — tighter visual grouping
   between the hero CTA and the lifetime-access pricing panel. */
#offer { padding-top: 44px; }
@media (max-width: 640px) {
  #offer { padding-top: 28px; }
}

/* ----- Trust row (Dragon's Den, Emmy, etc.) ----- */
.bp-trust {
  margin: 0 auto;
  padding: 8px 16px;
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}

/* ----- Section spacing ----- */
.bp-section {
  padding: 64px 0;
}
.bp-section--tight { padding: 40px 0; }
.bp-section__head {
  text-align: center;
  margin-bottom: 36px;
  max-width: 580px;
  margin-left: auto;
  margin-right: auto;
}
/* Section kicker — crimson Poppins all-caps, mirrors the hero kicker style.
   Overrides the .kicker base styles that the HTML still inherits via class="kicker". */
.bp-section__kicker {
  display: block;
  font-family: 'Poppins', sans-serif;
  font-style: normal;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--crimson);
  margin: 0 0 12px;
}
/* Section H2 — Rubik Black all-caps in dark ink. Smaller than the hero H1.
   Crimson lives in the kicker above (the energy hit); H2 stays black for
   readability and to avoid colour overload across multiple sections. */
.bp-section__h2 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  /* Sized to mirror .bp-features-intro__h2 exactly: 34px base,
     38px from min-width:768px (see desktop override further down).
     Keeps every Rubik section heading on the page at one scale,
     only the hero h1 and final-CTA h2 sit larger. */
  font-size: 34px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 14px;
}
.bp-section__lede {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 16px;
  color: var(--ink-soft);
  line-height: 1.5;
  margin: 0;
}

/* ----- Player zoom-in on scroll — keep it simple -----
   Player starts slightly scaled-down (reads as "further away") and
   gently zooms to full scale as the user scrolls into the section.
   No dark-mode flip, no full-width background expansion — just a
   subtle "comes into place" feel. Section stays cream throughout. */
.bp-player-section { padding: 32px 0 56px; background: rgba(255, 252, 248, 0.5); }
.bp-player-wrap {
  max-width: 520px;
  margin: 0 auto;
  padding: 0 20px;
  transform: scale(0.7);
  transform-origin: center center;
  transition: transform 0.8s cubic-bezier(0.2, 0, 0.2, 1);
}
.bp-player-wrap.is-immersed {
  transform: scale(1);
}

/* Scroll-nudge — when the category tabs first come into view they do a soft,
   bouncy bob to subconsciously cue that the strip is scrollable. Fires once.
   Multiple keyframes with diminishing amplitude give the "spring settling" feel. */
@keyframes sb-scroll-nudge {
  0%   { transform: translateX(0); }
  20%  { transform: translateX(-34px); }
  42%  { transform: translateX(14px); }
  62%  { transform: translateX(-6px); }
  82%  { transform: translateX(2px); }
  100% { transform: translateX(0); }
}
.sb-player__tabs.is-nudging {
  /* Smooth ease-in-out between each keyframe — reads as a damped spring rather than a flick */
  animation: sb-scroll-nudge 1100ms cubic-bezier(0.45, 0, 0.55, 1);
}
@media (prefers-reduced-motion: reduce) {
  .sb-player__tabs.is-nudging { animation: none; }
}

/* ----- Grows with your child — single composited PNG ----- */
.bp-devices-art {
  margin: 0 auto 32px;
  max-width: 720px;
  text-align: center;
}
.bp-devices-art__img {
  display: block;
  width: 100%;
  height: auto;
  max-width: 100%;
}

/* ============================================================
   Slide-up checkout modal (UI MOCKUP — no real Stripe wiring yet)
   Two-step flow: email → payment methods.
   Branded summary persists across both steps. Add-on toggle updates total.
   ============================================================ */
.bp-checkout-modal {
  position: fixed;
  inset: 0;
  z-index: 110;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.bp-checkout-modal.is-open { pointer-events: auto; opacity: 1; }
.bp-checkout-modal[hidden] { display: none; }
.bp-checkout-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.55);
}
.bp-checkout-modal__panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  height: 75vh;
  /* Warm off-white (paper) instead of pure white — bridges the cream LP
     palette into the checkout without losing the "this is a transactional
     form" trust signal. Stripe inputs inside stay pure white via the
     Appearance API so the field boxes are still defined. */
  background: var(--paper);
  border-radius: 24px 24px 0 0;
  box-shadow: 0 -10px 32px rgba(0, 0, 0, 0.22);
  transform: translateY(100%);
  transition: transform 0.34s cubic-bezier(0.22, 0.61, 0.36, 1);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.bp-checkout-modal.is-open .bp-checkout-modal__panel { transform: translateY(0); }
.bp-checkout-modal__handle {
  position: absolute;
  top: 8px; left: 50%;
  transform: translateX(-50%);
  width: 44px;
  height: 4px;
  background: rgba(0, 0, 0, 0.18);
  border-radius: 999px;
  pointer-events: none;
}
.bp-checkout-modal__close {
  position: absolute;
  top: 14px; right: 14px;
  width: 36px; height: 36px;
  background: rgba(0, 0, 0, 0.06);
  border: 0;
  border-radius: 999px;
  color: var(--ink);
  cursor: pointer;
  display: grid;
  place-items: center;
  z-index: 2;
  -webkit-tap-highlight-color: transparent;
}
.bp-checkout-modal__close:hover { background: rgba(0, 0, 0, 0.12); }
.bp-checkout-modal__scroll {
  overflow-y: auto;
  /* Top padding sets the y-position of the in-flow securehead so it
     aligns vertically with the absolute-positioned close button on the
     right. The order summary's distance from top is set by securehead's
     own height + margin-bottom. */
  padding: 14px 24px 32px;
  -webkit-overflow-scrolling: touch;
}

/* Desktop: centred modal (vertically + horizontally) instead of the
   bottom slide-up sheet. Backdrop gets a real blur. The panel keeps
   internal scroll for long content. */
@media (min-width: 768px) {
  .bp-checkout-modal {
    align-items: center;          /* centre vertically */
  }
  .bp-checkout-modal__backdrop {
    background: rgba(20, 20, 20, 0.45);
    -webkit-backdrop-filter: blur(8px);
            backdrop-filter: blur(8px);
  }
  .bp-checkout-modal__panel {
    width: 480px;
    max-width: 92vw;
    max-height: 88vh;
    height: auto;
    border-radius: 24px;          /* all four corners rounded */
    /* Replace slide-up with a quick scale + fade-in. */
    transform: scale(0.94) translateY(12px);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
  }
  .bp-checkout-modal.is-open .bp-checkout-modal__panel {
    transform: scale(1) translateY(0);
  }
  .bp-checkout-modal__handle { display: none; }   /* no drag handle on desktop */
}

/* Discount banner — only visible when modal has .is-discounted class.
   Locked: cannot be removed by the user. Auto-applied for the promo window. */
.bp-checkout-discount {
  display: none;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  margin: 0 0 14px;
  background: rgba(255, 14, 77, 0.08);
  border: 1px solid rgba(255, 14, 77, 0.18);
  border-radius: 12px;
}
.bp-checkout-modal.is-discounted .bp-checkout-discount { display: flex; }
.bp-checkout-discount__icon {
  width: 26px; height: 26px;
  border-radius: 999px;
  background: var(--crimson);
  color: #fff;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.bp-checkout-discount__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 1px;
}
.bp-checkout-discount__title {
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 13px;
  color: var(--crimson);
}
.bp-checkout-discount__sub {
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: 12px;
  color: var(--ink-soft);
}

/* (Line-item strike/active removed: the discount is shown via its own line
   row in the order summary + the strikethrough on the Total + Pay button.) */

/* Header — clean and trust-signally, no Rubik shouting */
.bp-checkout-summary {
  text-align: center;
  margin: 6px 0 18px;
}
/* Secure-checkout label sits at the top of the modal, centred, in black. */
.bp-checkout-securehead {
  /* In-flow at the top-left of the scroll content so it scrolls away
     when the user scrolls down (close button stays fixed). Aligned
     vertically with the close button at rest. Negative top margin
     nudges the text optically up to match the close button's icon
     centre (their geometric heights differ slightly). */
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: 36px;
  margin: -2px 0 2px;
}
.bp-checkout-secure {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.bp-checkout-secure svg,
.bp-checkout-secure__lock {
  color: var(--ink);
  flex: 0 0 auto;
  /* The padlock's shackle pulls its visual centre below the geometric one,
     so nudge up to align optically with the cap-line of the text. */
  margin-top: -2px;
}
.bp-checkout-secure__sep {
  color: var(--ink-faint);
  font-weight: 500;
  font-size: 13px;
}
.bp-checkout-secure__powered {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-soft);
  letter-spacing: -0.005em;
}
.bp-checkout-secure__powered strong {
  font-weight: 700;
  color: var(--ink);
}
.bp-checkout-summary__title {
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 22px;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 8px 0 11px;
}
.bp-checkout-summary__lede {
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 auto;
  max-width: 380px;
  line-height: 1.45;
}

/* What's included — bullet list above line items. Mint-green ticks tie
   into the savings/Trustpilot palette, so visually the "value" elements
   (ticks here, savings tag below, £77 active total) all share one colour
   thread. Sits in the gap between secure-checkout and the receipt. */
.bp-checkout-includes {
  list-style: none;
  margin: 4px 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.bp-checkout-includes li {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.bp-checkout-includes li svg {
  flex: 0 0 auto;
  color: #00B67A;          /* Trustpilot mint, matches savings tag + £77 active total */
  width: 14px;
  height: 14px;
}

/* Line items */
.bp-checkout-lines {
  list-style: none;
  /* Open invoice-style summary — no box around the rows, just horizontal
     rules between them and a bolder rule above the total. Matches the
     look of a standard checkout receipt. */
  margin: 0 0 9px;
  padding: 0;
  background: transparent;
  border: 0;
  border-top: 1px solid var(--line);
  border-radius: 0;
}
.bp-checkout-line {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 4px 7px;            /* tighter bottom so Emily's code + total sit higher */
  font-family: 'Poppins', sans-serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.bp-checkout-line__price {
  font-weight: 600;
  color: var(--ink);
  flex: 0 0 auto;
}
.bp-checkout-line__body {
  display: flex;
  flex-direction: column;
  gap: 0;
}
.bp-checkout-line__label {
  line-height: 1.2;
}
.bp-checkout-line__sub {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  line-height: 1.35;
  color: var(--ink-soft);
  font-weight: 500;
  letter-spacing: 0;
  margin-top: 4px;
}
.bp-checkout-line__sub svg { color: #00B67A; flex: 0 0 auto; }
/* Inline checklist inside a line item — used by the Emily branded modal
   to expand "what lifetime access includes" without adding a separate
   block above the receipt. Visually identical to .bp-checkout-line__sub
   so the bullets feel like an extension of the existing 100-day row. */
.bp-checkout-line__includes {
  list-style: none;
  margin: 11px 0 0;       /* 6 → 11px so the bullets breathe under the title */
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.bp-checkout-line__includes li {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  line-height: 1.35;
  color: var(--ink-soft);
  font-weight: 500;
  letter-spacing: 0;
}
.bp-checkout-line__includes li svg { color: #00B67A; flex: 0 0 auto; }
/* When the line item carries the bullet list, top-align the price column
   so £97 sits next to the label rather than floating to the vertical
   middle of the now-tall body. */
.bp-checkout-line:has(.bp-checkout-line__includes) {
  align-items: flex-start;
}
/* Discount line — only visible when modal has .is-discounted class.
   Match the regular line's horizontal padding so it doesn't read as
   indented. The label gets a small green pill tag to feel like a coupon
   was applied; the price renders in savings-green. */
.bp-checkout-line--discount {
  display: none;
  font-size: 14px;
  font-weight: 500;
  /* Asymmetric top/bottom padding shifts the tag + price ~3px down within
     the row without changing the row's total height — so the bolder Total
     rule below stays put. */
  padding: 13px 4px 7px;
  color: var(--ink-soft);
}
.bp-checkout-modal.is-discounted .bp-checkout-line--discount { display: flex; }
.bp-checkout-line--discount .bp-checkout-line__label {
  display: inline-block;
  padding: 3px 10px;
  background: #00B67A;            /* solid mint to match the deal banner */
  color: #FFFFFF;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.005em;
  border-radius: 999px;
}
.bp-checkout-line__price--discount {
  color: #00B67A;
  font-weight: 700;
  font-size: 15px;
}

/* Add-on card — sits between line items and total. Soft warm pink so it
   reads as an invitational extra, not part of the basket. Reserves green
   for confirmation states elsewhere. */
.bp-checkout-extra {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px 11px;
  margin: 8px 0 14px;
  background: #F0F7F2;
  border: 1px solid rgba(31, 138, 76, 0.12);
  border-radius: 12px;
  cursor: pointer;
  width: 100%;
}
.bp-checkout-extra__title {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.2;
  color: var(--ink);
}
.bp-checkout-extra__price {
  font-weight: 600;
  font-size: 14px;
  color: var(--ink-soft);
  white-space: nowrap;
  flex: 0 0 auto;
}
.bp-checkout-addon__check {
  appearance: none;
  -webkit-appearance: none;
  width: 22px; height: 22px;
  flex: 0 0 auto;
  border: 2px solid var(--line);
  border-radius: 6px;
  background: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: border-color 0.15s ease, background 0.15s ease;
}
.bp-checkout-addon__check:checked {
  border-color: #1F8A4C;
  background: #1F8A4C;
}
.bp-checkout-addon__check:checked::after {
  content: '';
  width: 14px; height: 14px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 10 18 20 6.5'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
}
.bp-checkout-addon__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bp-checkout-addon__sub {
  font-family: 'Poppins', sans-serif;
  font-style: normal;
  font-weight: 400;
  font-size: 12px;
  line-height: 1.3;
  color: var(--ink-soft);
}
/* Addon price column removed — price now lives inline in the title text. */

/* Total — no dashed border (the lines container above already separates it) */
.bp-checkout-total {
  display: flex;
  /* Center the label vertically with the price block so the bracketed
     row reads as one balanced line, regardless of whether the strike
     £97 is showing alongside the active price. */
  align-items: center;
  justify-content: space-between;
  border-top: 2px solid var(--ink);
  border-bottom: 2px solid var(--ink);
  margin: 0 0 22px;
  padding: 12px 4px;
}
.bp-checkout-total__label {
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 17px;
  letter-spacing: -0.005em;
  color: var(--ink);
}
.bp-checkout-total__right {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 1px;
}
.bp-checkout-total__amount {
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 19px;
  color: var(--ink);
  letter-spacing: -0.01em;
  line-height: 1;
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
}
.bp-checkout-total__strike {
  display: none;
  color: var(--ink-faint);
  font-weight: 500;
  font-size: 15px;
  text-decoration: line-through;
}
.bp-checkout-modal.is-discounted .bp-checkout-total__strike { display: inline; }
.bp-checkout-modal.is-discounted .bp-checkout-total__active { color: #00B67A; }
/* Strikethrough on the Pay button — only renders when modal has
   .is-discounted. Sits inline with a non-breaking space after it so the
   active price reads "[strike £97] £77" naturally. */
/* Vertical divider between the action verb and the price on the Pay
   button — non-em-dash separator (per Sooper Books copy rules). */
.bp-checkout-pay-divider {
  display: inline-block;
  margin: 0 7px;
  opacity: 0.45;
  font-weight: 400;
}

/* Express Checkout container — sits ABOVE the contact info so wallet
   buttons (Apple Pay / Google Pay / Link) are the first thing the user
   sees. Stripe injects iframes here. */
.bp-checkout-express {
  margin: 0 0 14px;
  min-height: 0; /* collapses cleanly when no wallets supported */
  position: relative;
  transition: opacity 0.18s ease;
  /* Match the 10px corner radius of the Stripe inputs/tabs below — clip
     the wallet button to our rounding via overflow:hidden because the
     paymentRequestButton API doesn't expose a borderRadius option. */
  border-radius: 10px;
  overflow: hidden;
}
.bp-checkout-express:empty { display: none; }
/* Disabled when email field is empty/invalid — wallet sheets need an email
   before they can complete, so the user fills email first then taps. */
.bp-checkout-express.is-disabled {
  opacity: 0.45;
  pointer-events: none;
  filter: grayscale(0.4);
}

/* "or pay another way" divider between Express Checkout and the rest of
   the form. Hidden when no Express options are available (set by JS). */
.bp-checkout-express-divider {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 18px;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.bp-checkout-express-divider::before,
.bp-checkout-express-divider::after {
  content: '';
  flex: 1;
  height: 1px;
  background: var(--line);
}
.bp-checkout-express-divider[hidden] { display: none; }
.bp-checkout-total__sub {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 10px;
  color: var(--ink-faint);
  letter-spacing: 0.005em;
}

/* Step containers */
.bp-checkout-step[hidden] { display: none; }

/* Email pill (step 2) */
.bp-checkout-emailpill {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 14px;
  margin: 0 0 18px;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 12px;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
}
.bp-checkout-emailpill__label {
  color: var(--ink-faint);
  flex: 0 0 auto;
}
.bp-checkout-emailpill__email {
  flex: 1 1 auto;
  font-weight: 600;
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bp-checkout-emailpill__edit {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--crimson);
  font-weight: 600;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  flex: 0 0 auto;
}

/* Field styling shared */
.bp-checkout-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin: 0 0 12px;
}
.bp-checkout-field__label {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.bp-checkout-field input {
  font-family: 'Poppins', sans-serif;
  font-size: 15px;
  color: var(--ink);
  padding: 12px 14px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: #fff;
  width: 100%;
  box-sizing: border-box;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}
.bp-checkout-field input:focus {
  border-color: #000000;
  border-width: 2px;
  box-shadow: none;
}
.bp-checkout-field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

/* Card number field — input wrapper (icons now live on the method row, not here) */
.bp-checkout-card-input {
  position: relative;
  display: block;
}
.bp-cardicon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 18px;
  border-radius: 3px;
  font-family: Helvetica, Arial, sans-serif;
  font-weight: 800;
  font-size: 9px;
  letter-spacing: -0.02em;
  border: 1px solid var(--line);
  background: #fff;
}
.bp-cardicon--visa {
  background: #1A1F71;
  color: #fff;
  border-color: #1A1F71;
  font-style: italic;
}
.bp-cardicon--mc {
  position: relative;
  padding: 0;
  background: #fff;
  font-size: 0;
}
.bp-cardicon__mc-red,
.bp-cardicon__mc-yellow {
  position: absolute;
  top: 50%;
  width: 11px;
  height: 11px;
  border-radius: 50%;
  transform: translateY(-50%);
}
.bp-cardicon__mc-red {
  left: 4px;
  background: #EB001B;
}
.bp-cardicon__mc-yellow {
  right: 4px;
  background: #F79E1B;
  mix-blend-mode: multiply;
}
.bp-cardicon--amex {
  background: #006FCF;
  color: #fff;
  border-color: #006FCF;
}

/* Submit / continue buttons */
.bp-checkout-submit {
  display: block;
  width: 100%;
  margin: 14px 0 10px;
  padding: 16px 22px;
  background: var(--crimson);
  color: #fff;
  border: 0;
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 16px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s ease, transform 0.18s ease;
}
.bp-checkout-submit:hover {
  background: var(--crimson-dark);
  transform: translateY(-1px);
}
.bp-checkout-note {
  text-align: center;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  color: var(--ink-faint);
  margin: 4px 0 0;
}

/* Section headings — supporting type, sit BELOW the product/addon names in
   the visual hierarchy (which are the dominant items). */
.bp-checkout-secthead {
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
  margin: 18px 0 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.bp-checkout-secthead:first-of-type { margin-top: 6px; }

/* Info button + tooltip — sits inline next to a section header to surface
   helper microcopy without cluttering the layout. CSS-only: hover/focus
   reveals the tooltip; click on mobile triggers focus and shows it. */
.bp-checkout-info {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ink-faint);
  cursor: pointer;
  border-radius: 999px;
  position: relative;
  transition: color 0.15s ease;
}
.bp-checkout-info:hover, .bp-checkout-info:focus-visible {
  color: var(--accent);
  outline: none;
}
.bp-checkout-info::after {
  content: attr(data-bp-info);
  position: absolute;
  left: 50%;
  bottom: calc(100% + 8px);
  transform: translateX(-50%) translateY(4px);
  background: var(--ink);
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  line-height: 1.4;
  padding: 8px 11px;
  border-radius: 8px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 10;
}
.bp-checkout-info::before {
  content: '';
  position: absolute;
  left: 50%;
  bottom: calc(100% + 4px);
  transform: translateX(-50%) translateY(4px);
  width: 0;
  height: 0;
  border: 4px solid transparent;
  border-top-color: var(--ink);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.15s ease, transform 0.15s ease;
  z-index: 10;
}
.bp-checkout-info:hover::after,
.bp-checkout-info:focus::after,
.bp-checkout-info:hover::before,
.bp-checkout-info:focus::before {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
@media (max-width: 380px) {
  .bp-checkout-info::after { white-space: normal; max-width: 200px; text-align: center; }
}
/* Microcopy under email field — softens the moment of typing email
   into a fresh checkout, tells the buyer what happens next. */
.bp-checkout-fieldhint {
  margin: 6px 2px 0;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  color: var(--ink-faint);
  line-height: 1.3;
}

/* Email input wrap with the small Stripe Link hint icon on the right */
.bp-checkout-input-wrap {
  position: relative;
  display: block;
}
.bp-checkout-link-hint {
  position: absolute;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 16px;
  border-radius: 4px;
  background: rgba(0, 0, 0, 0.04);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 2px;
  pointer-events: none;
}
.bp-checkout-link-hint span {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: var(--ink-faint);
}

/* Payment method radio list (Stripe pattern) */
.bp-checkout-methods {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  overflow: hidden;
  margin: 0 0 16px;
}
.bp-method {
  display: grid;
  grid-template-columns: 22px auto 1fr auto;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--line);
  cursor: pointer;
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
.bp-method:last-child { border-bottom: 0; }
.bp-method[hidden] { display: none; }

/* Hide the native radio, draw our own */
.bp-method input[type="radio"] {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
.bp-method__radio {
  width: 18px;
  height: 18px;
  border: 1.5px solid #c8c4ba;
  border-radius: 50%;
  background: #fff;
  flex: 0 0 auto;
  position: relative;
  transition: border-color 0.15s ease;
}
.bp-method input:checked ~ .bp-method__radio {
  border-color: var(--crimson);
  border-width: 5px;
}

.bp-method__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 22px;
  border-radius: 4px;
  background: #f1ece1;
  color: var(--ink);
  flex: 0 0 auto;
}
.bp-method__icon--card {
  background: var(--ink);
  color: #fff;
}
.bp-method__icon--apple {
  background: #fff;
  border: 1px solid var(--line);
}
.bp-method__icon--google {
  background: transparent;
  width: auto;
}
.bp-method__icon--klarna {
  background: #FFB3C7;
  font-family: 'Poppins', sans-serif;
  font-weight: 800;
  color: #17120F;
  font-size: 14px;
}
.bp-method__klarna-mark { line-height: 1; }

.bp-method__label {
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  display: inline-flex;
  align-items: baseline;
  gap: 8px;
}
.bp-method__hint {
  font-family: 'Poppins', sans-serif;
  font-size: 11px;
  font-weight: 500;
  color: var(--ink-faint);
}

/* Card brand icons on the right of the row */
.bp-method__brands {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
  justify-self: end;
}

/* Inline expanding card form when Card row is selected */
.bp-method__expand {
  grid-column: 1 / -1;
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.28s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.bp-method input:checked ~ .bp-method__expand {
  max-height: 420px;
}
.bp-method__expand .bp-checkout-cardform {
  padding: 12px 0 4px;
}

/* Save info / Stripe Link checkbox */
.bp-checkout-saveinfo {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 12px 14px;
  margin: 0 0 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  cursor: pointer;
}
.bp-checkout-saveinfo input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 18px;
  height: 18px;
  margin: 1px 0 0;
  border: 1.5px solid var(--line);
  border-radius: 4px;
  background: #fff;
  flex: 0 0 auto;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.bp-checkout-saveinfo input[type="checkbox"]:checked {
  border-color: var(--crimson);
  background: var(--crimson);
}
.bp-checkout-saveinfo input[type="checkbox"]:checked::after {
  content: '';
  width: 12px;
  height: 12px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 10 18 20 6.5'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
}
.bp-checkout-saveinfo__body {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.bp-checkout-saveinfo__title {
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
}
.bp-checkout-saveinfo__sub {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.35;
}

/* Pay button — full-width crimson pill, brand-aligned */
.bp-checkout-submit--pay {
  background: var(--crimson);
  color: #fff;
  font-size: 15px;                 /* one point smaller to fit "Start lifetime access | Pay £77" */
  font-weight: 700;
  padding: 18px 22px;
  margin: 18px 0 6px;
  width: 100%;
  text-align: center;
  letter-spacing: -0.005em;
  white-space: nowrap;
}

/* Legacy disabled-state hint — kept for backwards compatibility but
   permanently hidden. Replaced by the inline email-field error pattern
   below: tapping the disabled wallet button now flashes the email field
   crimson and shows "Enter your email to continue." beneath it. */
.bp-checkout-disabled-hint {
  display: none !important;
}

/* Wallet button wrapper. Holds the express-checkout iframe and a
   transparent click-trap button that sits on top when the email field is
   empty. The trap captures the tap so the wallet sheet doesn't open;
   instead, JS marks the email field as in error so the user is steered
   to the right input. */
.bp-checkout-express-wrap {
  position: relative;
  margin: 0 0 14px;
}
.bp-checkout-express-blocker {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  background: transparent;
  border: 0;
  margin: 0;
  padding: 0;
  cursor: pointer;
  /* Sit above the Apple/Google Pay iframe (Stripe sometimes uses a high
     z-index inside the iframe to escape parent stacking contexts). 50 is
     well above anything Stripe layers but still below our processing
     overlay (z-index 100). */
  z-index: 50;
  /* Force a fresh stacking context so iOS Safari can't promote the
     iframe above us via -webkit-overflow-scrolling tricks. */
  transform: translateZ(0);
  -webkit-tap-highlight-color: transparent;
}
.bp-checkout-express-blocker[hidden] { display: none; }

/* Email-field error state. Triggered when the user taps the disabled
   wallet button without an email — crimson border + soft glow + inline
   message immediately below the input. Cleared as soon as the user
   types into the field. */
.bp-checkout-field[data-email-row].is-error .bp-checkout-input-wrap input {
  border-color: var(--crimson) !important;
  box-shadow: 0 0 0 3px rgba(255, 14, 77, 0.22);
}
.bp-checkout-email-error {
  display: none;
  margin: 6px 2px 0;
  font-family: 'Poppins', sans-serif;
  font-size: 12.5px;
  font-weight: 500;
  color: var(--crimson);
  letter-spacing: 0.01em;
}
.bp-checkout-email-error[hidden] { display: none; }
.bp-checkout-field[data-email-row].is-error .bp-checkout-email-error {
  display: block;
}
.bp-checkout-submit--pay:hover {
  background: var(--crimson-dark);
}

/* Guarantee footer — replaces the Stripe footer for stronger trust at click moment */
.bp-checkout-guaranteefoot {
  text-align: center;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin: 6px 0 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  justify-content: center;
}
.bp-checkout-guaranteefoot svg {
  color: #00B67A;
  flex: 0 0 auto;
}

/* Top-of-modal guarantee — outlined mint pill (border, not fill) so it
   reads as a deliberate trust badge without competing as a bright wash
   with the £77 total above it. Mint sits in the supporting role. */
.bp-checkout-guaranteetop {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  margin: 8px 0 16px;
  padding: 9px 14px;
  background: transparent;
  border: 1px solid rgba(0, 182, 122, 0.32);
  border-radius: 999px;
}
.bp-checkout-guaranteetop svg {
  color: #00B67A;
  flex: 0 0 auto;
}

/* Generic pay button base */
.bp-paybtn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: 48px;
  border-radius: 10px;
  border: 0;
  cursor: pointer;
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-weight: 600;
  font-size: 16px;
  -webkit-tap-highlight-color: transparent;
  transition: opacity 0.15s ease, transform 0.15s ease;
}
.bp-paybtn:hover { opacity: 0.92; transform: translateY(-1px); }

/* Apple Pay & Google Pay — black with logo + larger "Pay" text */
.bp-paybtn--apple,
.bp-paybtn--google {
  background: #000;
  color: #fff;
  gap: 6px;
}
.bp-paybtn__wallet-icon {
  flex: 0 0 auto;
}
.bp-paybtn__wallet-text {
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-size: 19px;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1;
}

/* Klarna — pink pill matching wallet button height, sits inline next to wallet */
.bp-paybtn--klarna {
  background: #FFB3C7;
  color: #17120F;
  font-size: 13px;
  font-weight: 600;
  gap: 5px;
}
.bp-paybtn__klarna-text { color: #17120F; }
.bp-paybtn__klarna-logo {
  font-family: 'Poppins', sans-serif;
  font-weight: 800;
  letter-spacing: -0.02em;
}
.bp-paybtn__klarna-dot { color: #17120F; }

/* Or-pay-with-card divider */
.bp-checkout-divider {
  position: relative;
  text-align: center;
  margin: 18px 0 14px;
}
.bp-checkout-divider::before {
  content: '';
  position: absolute;
  top: 50%; left: 0; right: 0;
  height: 1px;
  background: var(--line);
}
.bp-checkout-divider span {
  position: relative;
  display: inline-block;
  background: #fff;
  padding: 0 12px;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}

@media (max-width: 640px) {
  .bp-checkout-modal__panel { border-radius: 20px 20px 0 0; }
  .bp-checkout-modal__scroll { padding: 22px 18px 28px; }
  .bp-checkout-summary__title { font-size: 20px; }
  /* Sooperbooks LP modal sits ~15px shorter on mobile so it finishes just
     under the Card/PayPal/Klarna tab row instead of leaving an empty gap
     below. The branded (Emily) modal keeps its own 80vh height. */
  .bp-checkout-modal:not(.bp-checkout-modal--branded) .bp-checkout-modal__panel {
    height: calc(75vh - 15px);
  }
}
@media (prefers-reduced-motion: reduce) {
  .bp-checkout-modal,
  .bp-checkout-modal__panel { transition: none; }
}

/* ----- "Ask us anything" link below FAQ + slide-up support modal ----- */
.bp-faq-ask-line {
  text-align: center;
  margin: 36px 0 0;
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 15px;
  color: var(--ink-soft);
}
.bp-faq-ask-link {
  background: none;
  border: 0;
  padding: 0;
  margin: 0 0 0 2px;
  font: inherit;
  color: var(--crimson);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.bp-faq-ask-link:hover { text-decoration-thickness: 2px; }

/* Slide-up modal */
.bp-ask-modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.bp-ask-modal.is-open {
  pointer-events: auto;
  opacity: 1;
}
.bp-ask-modal[hidden] { display: none; }
.bp-ask-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(20, 20, 20, 0.45);
}
.bp-ask-modal__panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: calc(100vh - 24px);
  overflow-y: auto;
  background: #fff;
  border-radius: 24px 24px 0 0;
  padding: 28px 28px 32px;
  box-shadow: 0 -8px 28px rgba(0, 0, 0, 0.18);
  transform: translateY(100%);
  transition: transform 0.32s cubic-bezier(0.22, 0.61, 0.36, 1);
}
.bp-ask-modal.is-open .bp-ask-modal__panel {
  transform: translateY(0);
}
.bp-ask-modal__close {
  position: absolute;
  top: 14px;
  right: 14px;
  width: 36px;
  height: 36px;
  background: none;
  border: 0;
  border-radius: 999px;
  color: var(--ink);
  cursor: pointer;
  display: grid;
  place-items: center;
  -webkit-tap-highlight-color: transparent;
}
.bp-ask-modal__close:hover { background: rgba(0, 0, 0, 0.06); }
.bp-ask-modal__head {
  text-align: center;
  margin: 4px 0 22px;
}
.bp-ask-modal__title {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 26px;
  text-transform: uppercase;
  letter-spacing: -0.02em;
  color: var(--ink);
  margin: 8px 0 8px;
}
.bp-ask-modal__sub {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 15px;
  color: var(--ink-soft);
  line-height: 1.45;
  margin: 0 auto;
  max-width: 360px;
}
.bp-ask-form {
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.bp-ask-form__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.bp-ask-form__label {
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.bp-ask-form input[type="text"],
.bp-ask-form input[type="email"],
.bp-ask-form textarea {
  font-family: 'Poppins', sans-serif;
  font-size: 15px;
  color: var(--ink);
  padding: 11px 14px;
  border: 1.5px solid var(--line);
  border-radius: 10px;
  background: #fff;
  width: 100%;
  box-sizing: border-box;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
  resize: vertical;
}
.bp-ask-form input:focus,
.bp-ask-form textarea:focus {
  border-color: var(--ink);
  box-shadow: 0 0 0 3px rgba(26, 26, 26, 0.10);
}
.bp-ask-form__honeypot {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
}
.bp-ask-form__submit {
  margin-top: 6px;
  padding: 14px 22px;
  background: var(--crimson);
  color: #fff;
  border: 0;
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background 0.18s ease, transform 0.18s ease;
}
.bp-ask-form__submit:hover {
  background: var(--crimson-dark);
  transform: translateY(-1px);
}
.bp-ask-modal__success {
  text-align: center;
  padding: 28px 8px 12px;
}
.bp-ask-modal__success-title {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 22px;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 8px;
}
.bp-ask-modal__success-sub {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 15px;
  color: var(--ink-soft);
  margin: 0;
}
@media (max-width: 640px) {
  .bp-ask-modal__panel {
    padding: 24px 20px 28px;
    border-radius: 20px 20px 0 0;
  }
  .bp-ask-modal__title { font-size: 22px; }
}
@media (prefers-reduced-motion: reduce) {
  .bp-ask-modal,
  .bp-ask-modal__panel { transition: none; }
}

/* Desktop: centred modal (vertically + horizontally) instead of the
   bottom slide-up sheet. Mirrors the checkout modal's desktop layout —
   blurred backdrop, all-four-corners rounded panel, scale + fade-in
   entrance instead of slide-up. */
@media (min-width: 768px) {
  .bp-ask-modal {
    align-items: center;
  }
  .bp-ask-modal__backdrop {
    background: rgba(20, 20, 20, 0.45);
    -webkit-backdrop-filter: blur(8px);
            backdrop-filter: blur(8px);
  }
  .bp-ask-modal__panel {
    width: 520px;
    max-width: 92vw;
    max-height: 88vh;
    height: auto;
    border-radius: 24px;
    transform: scale(0.94) translateY(12px);
    box-shadow: 0 24px 60px rgba(0, 0, 0, 0.32);
  }
  .bp-ask-modal.is-open .bp-ask-modal__panel {
    transform: scale(1) translateY(0);
  }
}

/* ----- bp-h2-break-md / -sm — paired hard line-breaks inside an h2.
   `bp-h2-break-md` shows on tablet/desktop only.
   `bp-h2-break-sm` shows on mobile only.
   Used together to give the testimonial h2 a 2-line desktop layout
   ("Parents and experts" / "swear by it.") and a 3-line mobile layout
   ("Parents and" / "experts" / "swear by it."). */
.bp-h2-break-md { display: none; }
.bp-h2-break-sm { display: inline; }
@media (min-width: 768px) {
  .bp-h2-break-md { display: inline; }
  .bp-h2-break-sm { display: none; }
}

/* ----- FAQ — narrower than the section default for an easier read.
   Larger horizontal padding so the questions don't run to the screen
   edges. Compound selector (.bp-shell.bp-faq-shell) outranks the plain
   .bp-shell mobile rule defined later in the file. */
.bp-shell.bp-faq-shell {
  max-width: 580px;
  padding-left: 32px;
  padding-right: 32px;
}
/* Mobile: match the founder panel's white box exactly.
   Founder sits inside .bp-shell (16px side padding) and is itself
   max-width: calc(100% - 10px) — so its visible width is
   viewport - 32px - 10px = viewport - 42px.
   We replicate that footprint by giving the FAQ shell 21px side
   padding (16 + 5), so its content area = viewport - 42px and
   each .faq-item naturally fills it. */
@media (max-width: 720px) {
  .bp-shell.bp-faq-shell {
    padding-left: 21px;
    padding-right: 21px;
  }
}

/* ----- App features — 2-column tick list of short practical features ----- */
.bp-app-features {
  list-style: none;
  padding: 0;
  margin: 8px auto 0;
  max-width: 360px;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px 22px;
}
.bp-app-features li {
  position: relative;
  padding: 4px 0 4px 28px;
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: 16px;
  line-height: 1.4;
  color: var(--ink);
}
.bp-app-features li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 6px;
  width: 18px;
  height: 18px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF0E4D' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 10 18 20 6.5'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}
@media (max-width: 640px) {
  /* Stays 2-column on mobile, narrower max-width so the grid feels neat
     instead of stretching the full screen width. */
  .bp-app-features { gap: 10px 14px; max-width: 280px; }
  .bp-app-features li { font-size: 14px; padding-left: 24px; }
  .bp-app-features li::before { width: 16px; height: 16px; top: 4px; }
}
.bp-devices-label {
  text-align: center;
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  color: var(--ink-soft);
  margin: 0;
  letter-spacing: 0.02em;
}
.bp-devices-label strong { color: var(--ink); font-weight: 600; }


/* ----- Meet our characters — horizontal scroll carousel ----- */
.bp-characters-section {
  padding-bottom: 72px;
}
.bp-characters-scroll {
  display: flex;
  gap: 70px;
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  padding: 18px 36px 28px;
  scrollbar-width: none;
  /* Soft edge fade to cue scrollability without harsh edges */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 4%, #000 96%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0%, #000 4%, #000 96%, transparent 100%);
}
.bp-characters-scroll::-webkit-scrollbar { display: none; }
.bp-character {
  flex: 0 0 auto;
  width: 336px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
/* Geometry mirrors the existing brand LP: cover art floats above and over a
   coloured backing panel, so the character "stands on" the colour block. */
.bp-character__art-block {
  position: relative;
  width: 100%;
  aspect-ratio: 308 / 323;
}
.bp-character__panel {
  position: absolute;
  bottom: 0;
  left: 10.4%;
  width: 78.9%;
  height: 82.4%;
  border-radius: 20px;
  box-shadow: -3px 4px 8px rgba(0, 0, 0, 0.22);
  z-index: 1;
}
.bp-character__cover {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 81.7%;
  background-size: contain;
  background-position: bottom center;
  background-repeat: no-repeat;
  z-index: 2;
}
/* Preview/Trailer button — sits absolute at the bottom of the art block,
   over the colour panel. White pill with crimson stroke, crimson play
   disc on the left, "Trailer" label on the right. Mirrors the existing
   brand LP's character carousel button. */
.bp-character__trailer {
  position: absolute;
  bottom: 12px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px 0 0;
  background: #fff;
  border: 2px solid var(--crimson);
  border-radius: 999px;
  height: 28px;
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 500;
  color: var(--ink);
  cursor: pointer;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.10);
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.bp-character__trailer:hover {
  transform: translateX(-50%) scale(1.04);
  box-shadow: 0 3px 9px rgba(0, 0, 0, 0.14);
}
.bp-character__trailer-icon {
  width: 26px;
  height: 26px;
  margin-left: -1px;
  border-radius: 999px;
  background: var(--crimson);
  color: #fff;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
}
.bp-character__trailer-label {
  letter-spacing: -0.005em;
}
.bp-character__meta {
  text-align: center;
  padding: 0 6px;
}
.bp-character__teaser {
  font-family: 'Source Serif 4', serif;
  font-style: italic;
  font-size: 14px;
  color: var(--ink-soft);
  line-height: 1.4;
  margin: 0;
}

/* ----- Testimonials ----- */
.bp-testimonials {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 16px;
  margin-top: 32px;
}

/* Mobile: the desktop carousel JS clones the testimonials (before +
   after) for the circular wrap. If init ran at desktop width and the
   user then resized to mobile, those clones would otherwise stack
   into the single-column grid and triple the testimonial count.
   Hide anything tagged as a clone below the carousel breakpoint. */
@media (max-width: 767px) {
  .bp-testimonial[data-clone-side="before"],
  .bp-testimonial[data-clone-side="after"] {
    display: none;
  }
}

/* Desktop: testimonials become a horizontal cover-flow carousel
   (same pattern as the features carousel). Emily ("Therapist
   approved") sits in the centre by default; side cards scale to
   0.85, centred card scales to 1.06 with a crimson border.
   `overflow-x: auto` is needed for scroll-snap, but we leave overflow-y
   visible so the scaled-up centred card's drop shadow can spill above
   and below the carousel band without being clipped. */
@media (min-width: 768px) {
  .bp-testimonials {
    display: flex;
    grid-template-columns: none;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    gap: 16px;
    overflow-x: auto;
    /* `overflow-y: visible` is coerced to `auto` by the spec when one
       axis is non-visible, so we can't actually let shadows escape the
       box. Compensate with generous vertical padding so the scaled-up
       centred card's drop shadow has room to breathe inside the
       carousel band without being clipped at the bottom. */
    overflow-y: visible;
    padding: 60px max(32px, calc(50vw - 220px)) 110px;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
  }
  .bp-testimonials::-webkit-scrollbar { display: none; }
  .bp-testimonial {
    flex: 0 0 440px;
    width: 440px;
    max-width: none;
    padding: 36px 32px 32px;
    scroll-snap-align: center;
    transform: scale(0.85);
    transition: transform 0.4s ease, border-color 0.3s ease, box-shadow 0.3s ease;
    border: 2px solid transparent;
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
  }
  .bp-testimonial.is-active {
    transform: scale(1.06);
    /* Mint-green stroke around the active card to tie it to the
       Trustpilot stars, but the drop shadow stays neutral black so we
       don't get a coloured halo behind the card. */
    border-color: #00B67A;
    box-shadow: 0 28px 60px rgba(0, 0, 0, 0.14), 0 18px 40px rgba(0, 0, 0, 0.08);
    z-index: 2;
  }
}
.bp-testimonial {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 16px;
  padding: 28px 24px 24px;
  display: flex;
  flex-direction: column;
  /* Centre the column vertically so cards of different copy length
     don't leave a gap at the bottom in the desktop carousel. */
  justify-content: center;
  gap: 14px;
  text-align: center;
}
/* Trustpilot-mint star row above the headline. 5 stars implied 5/5
   for every testimonial — every quote in the variant config is a happy
   customer, so we don't render variable ratings. */
.bp-testimonial__stars {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 3px;
  color: #00B67A;
  margin: 0 0 4px;
}
.bp-testimonial__stars svg {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
}
/* Two-word scannable headline at the top of each card. Same Source
   Serif as the quote (so the card reads as one typographic family),
   but bigger + non-italic so it's the first thing the eye lands on. */
.bp-testimonial__headline {
  font-family: 'Source Serif 4', serif;
  font-weight: 700;
  font-size: 22px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.bp-testimonial__quote {
  font-family: 'Source Serif 4', serif;
  font-size: 17px;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
  font-style: italic;
}
.bp-testimonial__author {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  margin-top: 4px;
}
.bp-testimonial__avatar {
  width: 56px; height: 56px;
  border-radius: 50%;
  background: #E6D9C2;
  flex-shrink: 0;
  overflow: hidden;
}
.bp-testimonial__avatar img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.bp-testimonial__name {
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
  margin: 0;
}
.bp-testimonial__role {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  color: var(--ink-faint);
  margin: 2px 0 0;
}

/* ----- Offer card ----- */
/* Tumbling covers now live in the testimonials section. Section needs
   relative positioning + overflow clip so they stay in their own band. */
#testimonials { position: relative; padding-top: 0; }
@media (max-width: 720px) {
  #testimonials { padding-top: 0; }
}
/* Flying brand illustration above testimonials head — soft, decorative */
.bp-testimonials__hero-gif {
  display: block;
  margin: -40px auto 18px;
  width: 330px;
  max-width: 85%;
  height: auto;
  position: relative;
  z-index: 2;
}
@media (min-width: 720px) {
  .bp-testimonials__hero-gif { width: 546px; max-width: 624px; margin: -44px auto 24px; }
}
.bp-offer {
  max-width: 520px;
  margin: 0 auto;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 40px 44px;
  text-align: center;
  box-shadow: var(--shadow-md);
  position: relative;
  z-index: 1;
  transform: scale(0.7);
  transform-origin: center center;
  transition: transform 0.8s cubic-bezier(0.2, 0, 0.2, 1);
}
.bp-offer.is-immersed {
  transform: scale(1);
}
/* Offer card heading — same Rubik Black all-caps system as the section H2s,
   slightly smaller because it lives inside a card not as a section anchor. */
.bp-offer__h3 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 28px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 12px;
}
.bp-offer__price-note {
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  color: var(--ink-faint);
  margin: 0 0 24px;
}
.bp-offer__features {
  list-style: none;
  padding: 0;
  margin: 24px 20px 32px;
  text-align: left;
}
.bp-offer__features li {
  padding: 10px 0 10px 26px;
  position: relative;
  font-size: 15px;
  color: var(--ink);
  border-bottom: 1px solid var(--line);
}
.bp-offer__features li:last-child { border-bottom: 0; }
.bp-offer__features li::before {
  content: '';
  position: absolute;
  left: 0; top: 14px;
  width: 16px; height: 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23FF0E4D' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='4 12.5 10 18 20 6.5'/%3E%3C/svg%3E");
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

/* ----- Final crimson CTA section ----- */
.bp-final-cta {
  background: var(--crimson);
  color: #fff;
  padding: 80px 20px 0;
  text-align: center;
  position: relative;
  overflow: hidden;
}
/* Cover ticker — sits at the bottom of the CTA section, peeks up from
   below. Bottom 5% of each cover is clipped by the section's overflow
   so the rounded tops feel like they're poking out. Continuous left
   scroll; doubled set in HTML keeps the loop seamless. */
.bp-final-cta__ticker {
  position: relative;
  /* Break out of the section's horizontal padding so the ticker spans
     edge-to-edge of the viewport on mobile (no crimson gap left/right). */
  width: calc(100% + 40px);
  margin-left: -20px;
  /* Tall enough that the upward box-shadow on each cover has room to
     extend without being clipped at the ticker's top edge. */
  height: 280px;
  margin-top: 36px;
  /* Negative margin pushes the ticker 11px below the section's bottom
     edge so the section's overflow:hidden clips the bottom 5% of each
     cover (rounded tops poke up; bottoms hidden). */
  margin-bottom: -11px;
  overflow: hidden;
  pointer-events: none;
}
/* Final-CTA ticker has a hard left/right edge — covers run straight
   off the side of the screen. (Side fade removed at Simon's request.) */
.bp-final-cta__ticker-track {
  display: flex;
  align-items: flex-end;
  height: 100%;
  gap: 12px;
  width: max-content;
  animation: bp-final-ticker 60s linear infinite;
  will-change: transform;
}
.bp-final-cta__cover {
  flex: 0 0 auto;
  width: 175px;
  aspect-ratio: 1000 / 1333;
  border-radius: 10px 10px 0 0;
  background-color: #1a1a1a;
  background-size: cover;
  background-position: center top;
  background-repeat: no-repeat;
  box-shadow: 0 -6px 16px rgba(0, 0, 0, 0.22);
  /* video element styling — fill the box, crop to cover, no controls */
  object-fit: cover;
  object-position: center top;
  display: block;
  pointer-events: none;
}
@keyframes bp-final-ticker {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}
@media (prefers-reduced-motion: reduce) {
  .bp-final-cta__ticker-track { animation: none; }
}
/* Final crimson CTA H2 — matches the hero H1's Rubik Black system for
   visual end-cap symmetry. Sub copy removed; the H2 stands alone above
   the button + guarantee. */
.bp-final-cta__h2 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  color: #fff;
  font-size: 44px;
  line-height: 1.08;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  max-width: 720px;
  margin: 0 auto 28px;
  text-wrap: balance;
}
/* Wider button — extra horizontal padding for breathing room. */
.bp-final-cta__btn,
.bp-final-cta .cta {
  padding: 18px 56px;
}
.bp-final-cta .cta {
  background: #fff;
  color: var(--crimson);
}
.bp-final-cta .cta:hover {
  background: rgba(255, 255, 255, 0.9);
  color: var(--crimson-dark);
}
.bp-final-cta .cta-sub {
  color: rgba(255, 255, 255, 0.85);
  margin-top: 16px;
}

/* ----- Mobile breakpoints ----- */
@media (max-width: 640px) {
  .bp-shell { padding: 0 16px; }
  /* Hero gets more vertical breathing room on mobile + a punchier H1.
     Old: 30px H1, 5px gap to sub, 18px gap to CTA, 16/30 padding.
     New: 42px H1, 18px gap to sub, 28px gap to CTA, 24/40 padding. */
  .bp-hero { padding: 14px 0 40px; }
  .bp-hero__brand { margin-bottom: 12px; }
  .bp-hero__logo { height: 32px; }
  .bp-hero__kicker { margin-bottom: 14px; }
  .bp-hero__ticker-wrap { margin-bottom: 4px; }
  .bp-hero__h1 { font-size: 42px; line-height: 1.04; margin-bottom: 18px; letter-spacing: -0.02em; }
  .bp-hero__sub { font-size: 18px; margin-bottom: 28px; }
  .bp-hero__cta { width: 100%; max-width: 440px; padding: 17px 18px; font-size: 16.5px; text-align: center; }
  .bp-hero__cta .cta-strike { font-size: 0.8em; }
  .bp-offer .cta--full { font-size: 14px; padding: 14px 16px; max-width: 420px; }
  .bp-final-cta .cta { font-size: 16px; padding: 16px 18px; max-width: 440px; }

  .bp-section { padding: 48px 0; }
  .bp-player-section { padding: 32px 0 48px; }
  .bp-section__h2 { letter-spacing: -0.025em; }
  .bp-section__lede { font-size: 15px; }

  .bp-devices {
    grid-template-columns: 1fr 1.4fr 1fr;
    gap: 4px;
  }
  .bp-device { max-width: none; }
  .bp-device--centre { transform: translateY(-10px); }
  .bp-device--left { transform: rotateY(-18deg) translateY(0); }
  .bp-device--right { transform: rotateY(18deg) translateY(0); }

  .bp-included { grid-template-columns: 1fr; gap: 10px; }
  .bp-included li { font-size: 16px; }
  .bp-characters-scroll {
    padding: 12px 16px 18px;
    gap: 50px;
    /* Clean edge on mobile — no fade, cards run straight off the side */
    -webkit-mask-image: none;
            mask-image: none;
  }
  .bp-character { width: 240px; }
  .bp-offer-cover { width: 60px; }
  .bp-character__name { font-size: 13px; }
  .bp-character__tagline { font-size: 12px; }
  /* Mobile panel width alignment — white panels (offer / founders /
     testimonials) narrowed by ~10px total; audio panel widened by
     ~10px total via reduced wrap padding. */
  .bp-testimonials { grid-template-columns: 1fr; max-width: calc(100% - 10px); margin-left: auto; margin-right: auto; }

  .bp-offer { padding: 32px 24px; border-radius: 20px; margin: 0 5px; }
  .bp-offer__h3 { font-size: 24px; }
  .bp-player-wrap { padding: 0 10px; }

  .bp-final-cta { padding: 56px 20px 0; }
  .bp-final-cta__h2 { font-size: 30px; line-height: 1.05; margin-bottom: 22px; }
  .bp-final-cta__btn,
  .bp-final-cta .cta { padding: 16px 36px; }
  .bp-final-cta__ticker { margin-top: 28px; margin-bottom: -8px; height: 210px; }
  .bp-final-cta__cover { width: 125px; }
}

/* ============================================================
   FOOTER — slim black band: links row, copyright stacked below
   ============================================================ */
.bp-footer {
  background: #000;
  color: #fff;
  padding: 14px 20px 8px;
  text-align: center;
}
.bp-footer__inner {
  max-width: 980px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.bp-footer__nav {
  display: inline-flex;
  gap: 18px;
  flex-wrap: wrap;
  justify-content: center;
}
.bp-footer__nav a {
  color: rgba(255,255,255,0.78);
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 500;
  text-decoration: none;
  transition: color 0.15s ease;
}
.bp-footer__nav a:hover {
  color: #fff;
}
.bp-footer__legal {
  margin: 0;
  color: rgba(255,255,255,0.45);
  font-family: 'Poppins', sans-serif;
  font-size: 11px;
}
/* Mobile footer — symmetric slim padding. The sticky CTA bar's overlap
   is already handled by body.has-sticky-bar (in shared/css/components.css)
   which adds 82px to the body bottom when the bar is visible. */
@media (max-width: 720px) {
  .bp-footer { padding: 12px 20px; }
}

/* ============================================================
   FOUNDERS — humanise the brand. Whole section sits in a white
   card on the cream page background, matching the testimonial
   card treatment so the page reads as one consistent system.
   ============================================================ */
/* Desktop: 20px extra below the white founders box, separating it
   cleanly from the FAQ section that follows. (Inherits the section
   padding from .bp-section--tight; this adds on top.) */
.bp-founders-section { padding-top: 16px; }
@media (min-width: 768px) {
  .bp-founders-section { padding-bottom: 20px; }
}
@media (max-width: 720px) {
  .bp-founders-section { padding-top: 8px; }
}
.bp-founders {
  display: grid;
  /* Cap the photo column at 40% of the box (or 420px on full-width
     desktop, whichever is smaller). At tablet widths the photo would
     otherwise eat 60-70% of the row and squeeze the founders' copy
     into a narrow strip. min(420px, 40%) keeps the text side at
     least 60%. */
  grid-template-columns: min(420px, 40%) 1fr;
  gap: 48px;
  /* Anchor both columns to the top so the photo's top edge lines up
     with the kicker on the right. With align-items:center the photo
     would float in the middle while the copy sat at the top — looks
     odd at narrow widths. */
  align-items: start;
  text-align: left;
  max-width: 980px;
  margin: 0 auto;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 24px;
  padding: 45px 48px;
}
.bp-founders__photo-wrap {
  /* Fill the (now responsive) photo column. */
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: 20px;
  overflow: hidden;
  background: var(--cream);
}
.bp-founders__photo {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.bp-founders__body .bp-section__kicker {
  margin: 0 0 8px;
}
.bp-founders__h2 {
  font-size: 28px;
  margin: 0 0 14px;
  line-height: 1.15;
  text-wrap: balance;
}
.bp-founders__copy {
  font-family: 'Source Serif 4', Georgia, serif;
  font-size: 18px;
  line-height: 1.6;
  color: var(--ink);
  margin: 0 0 20px;
}
.bp-founders__copy p {
  margin: 0 0 14px;
}
.bp-founders__copy p:last-child {
  margin-bottom: 0;
}
.bp-founders__signoff {
  font-family: 'Source Serif 4', Georgia, serif;
  font-style: italic;
  font-size: 18px;
  color: var(--ink);
  margin: 0;
}
@media (max-width: 720px) {
  .bp-founders {
    grid-template-columns: 1fr;
    gap: 24px;
    text-align: center;
    max-width: calc(100% - 10px);
    margin-left: auto;
    margin-right: auto;
    padding: 33px 22px;
    border-radius: 20px;
  }
  .bp-founders__photo-wrap {
    width: 80%;
    aspect-ratio: 5 / 3;
    margin: 0 auto;
    border-radius: 18px;
  }
  .bp-founders__h2 { font-size: 26px; }
  .bp-founders__copy { font-size: 17px; }
}

/* Dragons' Den proof line under the hero wordmark — small caps Poppins,
   sits below the italic strapline as a separate conversion-focused
   proof signal. Subtle gold accent on the "5" pulls the eye. */
.bp-hero__dragons {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-top: 6px;
  font-family: 'Poppins', sans-serif;
  font-weight: 700;
  font-size: 10px;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink);
}
.bp-hero__dragons-flame {
  color: #E25822;
  display: inline-flex;
  align-items: center;
}

/* ============================================================
   TRUST STRIP — 4 stat badges between hero and offer panel.
   Inline tickrow with subtle borders, neutral cream chip.
   Stacks 2x2 on mobile so labels stay readable.
   ============================================================ */
.bp-trust {
  padding: 8px 0 4px;
}
.trust-row {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px 24px;
}
.trust-row__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.005em;
}
.trust-row__icon {
  width: 16px;
  height: 16px;
  color: var(--crimson);
  flex: 0 0 auto;
}
@media (max-width: 720px) {
  .bp-trust { padding: 4px 0 0; }
  .trust-row { gap: 8px 18px; padding: 0 12px; }
  .trust-row__item { font-size: 12px; gap: 6px; }
  .trust-row__icon { width: 14px; height: 14px; }
}

/* ============================================================
   BLOBBO HELP PANEL — secondary "got any questions?" CTA.
   Layered composition: Blobbo body stays stationary; the panel +
   arm sit on top and sway gently together so it reads like he's
   holding the sign up. Text inside the panel rides with the
   panel motion (no separate jiggle). Arm has a slightly different
   timing so it feels alive rather than rigid.
   ============================================================ */
.bp-blobbo {
  padding: 0 20px 24px;
  /* Pull-up was -64px; loosened to -34px so the FAQ has ~30px more
     breathing room before the "Got any questions?" panel begins. */
  margin-top: -34px;
  text-align: center;
}
.bp-blobbo__stage {
  position: relative;
  max-width: 460px;
  margin: 0 auto;
  /* Body lifts up into the panel area — less empty space below */
  padding-bottom: 80px;
  transform: scale(0.7);
  transform-origin: center center;
  transition: transform 0.8s cubic-bezier(0.2, 0, 0.2, 1);
  /* GPU-promote so the scale transform doesn't soften the rasterised
     content (PNGs + borders go grainy without this). */
  will-change: transform;
  backface-visibility: hidden;
}
.bp-blobbo__stage.is-immersed {
  transform: scale(1);
}
/* Stationary body — peeks out from the bottom centre, lifted up so
   more of the body sits behind the panel and the back hand is hidden. */
.bp-blobbo__body {
  position: absolute;
  bottom: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 220px;
  height: auto;
  z-index: 1;
  pointer-events: none;
}
/* Panel + arm sway as ONE unit — arm is locked to the panel motion
   so it reads like Blobbo is holding the board, not waving it around. */
.bp-blobbo__group {
  position: relative;
  z-index: 2;
  transform-origin: 50% 90%;
  animation: bp-blobbo-sway 5.6s ease-in-out infinite;
}
@keyframes bp-blobbo-sway {
  0%, 100% { transform: rotate(-1deg) translateY(0); }
  50%      { transform: rotate(1deg)  translateY(-3px); }
}
@media (prefers-reduced-motion: reduce) {
  .bp-blobbo__group { animation: none; }
}
.bp-blobbo__panel {
  background: #DDF1E0;
  border: 1px solid rgba(26, 60, 36, 0.10);
  border-radius: 22px;
  padding: 32px 32px 28px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.10);
}
.bp-blobbo__h2 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 24px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 12px;
  text-wrap: balance;
}
.bp-blobbo__copy {
  font-family: 'Source Serif 4', Georgia, serif;
  font-style: italic;
  font-size: 16px;
  line-height: 1.5;
  color: var(--ink-soft);
  max-width: 320px;
  margin: 0 auto 22px;
}
/* Secondary CTA — pill, dark text on white with subtle border.
   Deliberately not crimson so it reads as a quieter alternative. */
.bp-blobbo__cta {
  display: inline-block;
  padding: 14px 28px;
  background: #fff;
  color: var(--ink);
  border: 1px solid rgba(0, 0, 0, 0.12);
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 15px;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.bp-blobbo__cta:hover {
  transform: translateY(-1px);
  background: #fff;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.10);
}
/* Arm — same position as before (inside panel group), but with its
   transform-origin pinned to its own bottom-centre (the shoulder joint).
   A separate pivot animation rocks the top of the arm; the bottom stays
   anchored. Resting lean +1deg clockwise so it appears slightly tipped
   back. The panel group's gentle sway runs underneath, but because the
   arm's pivot is at the same vertical zone as the group's pivot, the
   shoulder barely drifts — only the arm's tip rocks visibly. */
.bp-blobbo__arm {
  position: absolute;
  width: 48px;
  height: auto;
  bottom: -34px;
  right: calc(28% + 47px);
  z-index: 3;
  pointer-events: none;
  transform-origin: 50% 100%;
  animation: bp-blobbo-arm-wave 5.6s ease-in-out infinite;
}
@keyframes bp-blobbo-arm-wave {
  0%, 100% { transform: rotate(-2deg); }
  50%      { transform: rotate(4deg);  }
}
@media (prefers-reduced-motion: reduce) {
  .bp-blobbo__arm { animation: none; transform: rotate(1deg); }
}
@media (max-width: 720px) {
  .bp-blobbo { padding: 0 16px 16px; margin-top: -38px; }
  .bp-blobbo__stage { padding-bottom: 64px; }
  .bp-blobbo__body { width: 170px; bottom: 4px; }
  .bp-blobbo__panel { padding: 26px 22px 22px; border-radius: 18px; }
  .bp-blobbo__h2 { font-size: 20px; }
  .bp-blobbo__copy { font-size: 14px; }
  .bp-blobbo__arm { width: 38px; bottom: -26px; right: calc(26% + 37px); }
}

/* ============================================================
   Stripe Payment Element — v1 embedded checkout
   Only rules added below. Do not refactor existing checkout
   styles above; Simon iterates on those in parallel.
   ============================================================ */
.bp-checkout-payment-element {
  margin: 8px 0 3px;
  /* Was 400px — created a big visual gap below the postcode field because
     Stripe's iframe is shorter than that. 280px is just enough to host
     the placeholder pulse before mount; iframe drives height afterwards. */
  min-height: 280px;
  position: relative;
}

/* Processing overlay shown during auto-trigger redirect (PayPal/Klarna/etc).
   Sits over the entire modal so the user gets immediate "we're connecting"
   feedback rather than a 1-2s frozen state. Fades in. */
.bp-checkout-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.92);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  border-radius: inherit;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.18s ease;
}
.bp-checkout-overlay.is-visible {
  opacity: 1;
  pointer-events: auto;
}
.bp-checkout-overlay__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 20px 28px;
}
.bp-checkout-overlay__spinner {
  width: 28px;
  height: 28px;
  border: 3px solid rgba(26, 26, 26, 0.12);
  border-top-color: var(--ink);
  border-radius: 50%;
  animation: bp-checkout-overlay-spin 0.7s linear infinite;
}
.bp-checkout-overlay__msg {
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--ink);
  letter-spacing: 0;
}
@keyframes bp-checkout-overlay-spin {
  to { transform: rotate(360deg); }
}

/* While the element is loading, show a soft pulsing placeholder.
   Stripe replaces innerHTML on mount, so this only ever shows
   pre-mount or during a re-mount. */
.bp-checkout-payment-element:empty::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 10px;
  background: linear-gradient(90deg, rgba(0,0,0,0.03), rgba(0,0,0,0.06), rgba(0,0,0,0.03));
  background-size: 200% 100%;
  animation: bp-pe-pulse 1.4s ease-in-out infinite;
}
@keyframes bp-pe-pulse {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Inline error/decline message under the Pay button. */
.bp-checkout-error {
  margin: 12px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: rgba(255, 14, 77, 0.08);
  color: var(--crimson-dark);
  font-size: 14px;
  line-height: 1.4;
}

/* Disabled Pay button while Element is initialising or processing. */
.bp-checkout-submit[disabled] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

/* Processing state — block clicks on backdrop / close so a 3DS
   challenge isn't dismissed accidentally. */
.bp-checkout-modal.is-processing .bp-checkout-modal__backdrop,
.bp-checkout-modal.is-processing .bp-checkout-modal__close {
  pointer-events: none;
  opacity: 0.5;
}

/* ============================================================
   SAMPLE PANELS (v2) — three colour-tinted category showcases
   that replace the tabbed dark player. Each panel has its own
   cover carousel + play state. Single shared audio element.
   ============================================================ */
.bp-samples-section {
  padding: 24px 16px;
  background: var(--cream);
}
.bp-sample-panel + .bp-sample-panel {
  margin-top: 16px;
}
.bp-sample-panel {
  position: relative;
  overflow: hidden;
  padding: 42px 32px 48px;
  text-align: center;
  isolation: isolate;
  max-width: 720px;
  margin: 0 auto;
  border-radius: 28px;
}
/* Animated background tint layer — sits behind content, picks up the
   active cover's category colour. Smooth fade between covers. */
.bp-sample-panel__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--panel-tint, #fff);
  transition: background-color 0.6s ease;
}
/* Per-panel default tints (at-rest, before JS picks up). JS overrides
   directly on the .bg element. BOLD + vivid per Simon's brief —
   pastels read too soft. */
.bp-sample-panel--originals       .bp-sample-panel__bg { background: #FF8C1A; }
.bp-sample-panel--fairy-tales     .bp-sample-panel__bg { background: #C41E3A; }
.bp-sample-panel--nursery-rhymes  .bp-sample-panel__bg { background: #F5B40C; }
/* On bold tints the text flips white for contrast. */
.bp-sample-panel__h3,
.bp-sample-panel__count,
.bp-sample-panel__title { color: #fff; }
/* prev/next buttons sit on the bold tint — soft white pill. */
.bp-sample-panel__ctrl {
  background: rgba(255, 255, 255, 0.20);
  color: #fff;
}
.bp-sample-panel__ctrl:hover { background: rgba(255, 255, 255, 0.30); }
.bp-sample-panel__shell {
  max-width: 520px;
  margin: 0 auto;
}
.bp-sample-panel__h3 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 32px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: #fff;
  margin: 0 0 6px;
}
.bp-sample-panel__count {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.75);
  margin: 0 0 14px;
}
/* Carousel — horizontal cover-flow, similar to the legacy player but
   per-panel. Active cover is centered, larger; siblings flank it.  */
.bp-sample-panel__carousel {
  position: relative;
  width: 100%;
  height: 226px;
  margin-bottom: 24px;
  touch-action: pan-y;
}
.bp-sample-panel__card {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 142px;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
  transform-origin: center center;
  transform: translate(-50%, -50%);
  transition: transform 0.4s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.35s ease;
  will-change: transform, opacity;
}
.bp-sample-panel__card:focus { outline: none; }
.bp-sample-panel__card-cover {
  aspect-ratio: 1000 / 1333;
  border-radius: 12px;
  overflow: hidden;
  background: transparent;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.22);
  position: relative;
}
.bp-sample-panel__card-cover img,
.bp-sample-panel__card-cover video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* Animated video overlays the static still and is only visible on the
   centred card. Cheap on mobile — non-centred cards keep no decoder. */
.bp-sample-panel__card-anim {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.3s ease;
  pointer-events: none;
}
.bp-sample-panel__card.is-active .bp-sample-panel__card-anim {
  opacity: 1;
}
/* Progress row: [0:00] [── pill bar with slug overlaid ──] [3:42]
   The slug sits inside the bar; the crimson fill grows behind it. */
.bp-sample-panel__progress {
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: 360px;
  margin: -20px auto 22px;  /* lift 20px closer to the carousel */
}
.bp-sample-panel__time-current,
.bp-sample-panel__time-total {
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: 12px;
  color: rgba(255, 255, 255, 0.65);
  min-width: 32px;
  font-variant-numeric: tabular-nums;
}
.bp-sample-panel__time-total { text-align: right; }
.bp-sample-panel__bar {
  flex: 1;
  height: 36px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}
.bp-sample-panel__bar-fill {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 0;
  background: rgba(255, 255, 255, 0.30);
  border-radius: 999px;
  transition: width 0.1s linear;
  pointer-events: none;
}
.bp-sample-panel__title {
  position: absolute;
  inset: 0;
  z-index: 1;
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 14px;
  line-height: 1;
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 14px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
}
.bp-sample-panel__controls {
  display: inline-flex;
  align-items: center;
  gap: 16px;
}
.bp-sample-panel__ctrl,
.bp-sample-panel__play {
  border: 0;
  background: rgba(0, 0, 0, 0.08);
  color: #fff;
  border-radius: 50%;
  cursor: pointer;
  transition: background 0.15s ease, transform 0.1s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.bp-sample-panel__ctrl {
  width: 46px;
  height: 46px;
  background: rgba(255, 255, 255, 0.20);
  color: #fff;
}
.bp-sample-panel__ctrl:hover { background: rgba(255, 255, 255, 0.30); }
.bp-sample-panel__ctrl svg {
  width: 22px;
  height: 22px;
  fill: #fff;
}
.bp-sample-panel__play {
  width: 76px;
  height: 76px;
  background: var(--crimson);
  color: #fff;
  position: relative;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.22);
}
.bp-sample-panel__play:hover { background: var(--crimson-dark); }
.bp-sample-panel__play::before {
  content: '';
  width: 0;
  height: 0;
  border-style: solid;
  border-width: 11px 0 11px 17px;
  border-color: transparent transparent transparent #fff;
  margin-left: 4px;
}
.bp-sample-panel__play.is-playing::before {
  border: 0;
  width: 17px;
  height: 17px;
  margin-left: 0;
  background-image: linear-gradient(to right, #fff 0 5px, transparent 5px 12px, #fff 12px 17px);
}
.bp-sample-panel__ctrl:hover,
.bp-sample-panel__play:hover {
  transform: scale(1.05);
}
/* Strip the boxed sb-player styling when it's nested inside a sample
   panel — we want the controls/title/progress to sit directly on the
   panel's tint, not in a dark card. Also tighten the spacing and pull
   the block up so it hugs the carousel above. */
.bp-sample-panel .sb-player,
.bp-sample-panel .sb-player[data-theme="dark"] {
  background: transparent;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
  gap: 12px;
  margin-top: -24px;
  max-width: 480px;
  margin-left: auto;
  margin-right: auto;
  overflow: visible;
}
.bp-sample-panel .sb-player__title {
  font-family: 'Poppins', sans-serif;
  font-size: 14px;
  font-weight: 500;
}
.bp-sample-panel .sb-player__play {
  width: 72px;
  height: 72px;
  box-shadow: none;
}
.bp-sample-panel .sb-player__play svg {
  width: 32px;
  height: 32px;
}
.bp-sample-panel .sb-player__ctrl {
  width: 44px;
  height: 44px;
}
.bp-sample-panel .sb-player__ctrl svg {
  width: 22px;
  height: 22px;
}
/* Slider thumb — small white circle that slides along the bottom of
   the progress bar as audio plays. Bar must be overflow:visible so the
   thumb can sit on the bar's bottom edge without clipping. */
.bp-sample-panel .sb-player__bar { overflow: visible; }
/* The thumb is the Sooper Books slug character (the brand mascot) used
   as a mask, so we can recolour it via background-color. Anchored at
   its bottom-LEFT corner to the progress point — at 0% it covers the
   bar's bottom-left rounded edge; as the fill grows, the slug slides
   along, pulling the fill behind it. scaleX(-1) flips so the eyes
   face the direction of travel (right). */
.bp-sample-panel .sb-player__thumb {
  --progress: 0;
  position: absolute;
  bottom: 0;
  /* JS sets --progress (0..1). Slug LEFT edge sits 6px behind the
     fill's leading edge so the slug's solid body always covers the
     bar's rounded right corner — without the offset there's a tiny
     visible gap where the bar's curve peeks out from behind the
     slug at the right end of the track. */
  left: calc(var(--progress) * 100% - 6px);
  width: 22px;
  height: 20px;
  background: var(--crimson);
  -webkit-mask: url('/shared/images/sooper-slug.svg') center / contain no-repeat;
          mask: url('/shared/images/sooper-slug.svg') center / contain no-repeat;
  transform: scaleX(-1);
  transform-origin: center center;
  pointer-events: none;
  transition: left 0.1s linear;
}
/* Light tints (e.g. Posh Rat orange) — flip text + ctrl icons to black
   for legibility. Play button stays crimson with white icon. */
.bp-sample-panel.is-light-tint .bp-sample-panel__h3,
.bp-sample-panel.is-light-tint .bp-sample-panel__count,
.bp-sample-panel.is-light-tint .sb-player__title,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__title,
.bp-sample-panel.is-light-tint .sb-player__time-current,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__time-current,
.bp-sample-panel.is-light-tint .sb-player__time-total,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__time-total {
  color: #1A1A1A;
}
.bp-sample-panel.is-light-tint .bp-sample-panel__count {
  color: rgba(26, 26, 26, 0.75);
}
.bp-sample-panel.is-light-tint .sb-player__time-current,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__time-current,
.bp-sample-panel.is-light-tint .sb-player__time-total,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__time-total {
  color: rgba(26, 26, 26, 0.55);
}
.bp-sample-panel.is-light-tint .sb-player__bar,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__bar {
  background: rgba(0, 0, 0, 0.15);
}
.bp-sample-panel.is-light-tint .sb-player__ctrl,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__ctrl {
  background: rgba(0, 0, 0, 0.06);
  color: #1A1A1A;
}
.bp-sample-panel.is-light-tint .sb-player__ctrl:hover,
.bp-sample-panel.is-light-tint .sb-player[data-theme="dark"] .sb-player__ctrl:hover {
  background: rgba(0, 0, 0, 0.12);
}
@media (max-width: 720px) {
  .bp-sample-panel { padding: 34px 24px 40px; }
  .bp-sample-panel__h3 { font-size: 30px; }
  .bp-sample-panel__count { font-size: 11px; margin-bottom: 12px; }
  .bp-sample-panel__carousel { height: 202px; }
  .bp-sample-panel__card { width: 128px; }
}

/* ============================================================
   Features intro (kicker + h2 + lede) — base styles apply on every
   screen size; desktop bumps the sizes inside the min-width media.
   ============================================================ */
.bp-features-intro {
  text-align: center;
  max-width: 760px;
  margin: 0 auto 24px;
  padding: 16px 16px 0;
  position: relative;
  z-index: 5;
}
.bp-features-intro__kicker {
  font-family: 'Poppins', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crimson);
  display: block;
  margin-bottom: 10px;
}
.bp-features-intro__h2 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 34px;          /* mobile: bigger so it clearly outranks panel h3 */
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 0 10px;
  text-wrap: balance;
}
.bp-features-intro__lede {
  font-family: 'Source Serif 4', Georgia, serif;
  font-style: italic;
  font-size: 16px;
  line-height: 1.45;
  color: var(--ink-soft);
  max-width: 540px;
  margin: 0 auto;
}

/* On mobile, hide carousel-only chrome:
   - JS-cloned feature panels (rendered for desktop's circular wrap)
   - Prev/next nav button rows (mobile uses vertical stack, no nav) */
@media (max-width: 767px) {
  .bp-feature-panel[data-clone-side="before"],
  .bp-feature-panel[data-clone-side="after"] {
    display: none;
  }
  .bp-samples-nav,
  .bp-features-nav {
    display: none;
  }
}

/* Mobile: each feature panel = bounding-box card with strong
   definition vs the cream page bg. Pure white + stronger shadow +
   subtle hairline border so the box edge is unambiguous. The
   feature h3 inside is dropped down so it clearly sits below the
   "Built for Family Life" section H2. */
.bp-feature-panel--theme-light .bp-feature-panel__bg {
  background: #FFFFFF;
  border: 1px solid rgba(26, 26, 26, 0.06);
}
.bp-feature-panel {
  box-shadow: 0 18px 48px rgba(26, 26, 26, 0.14);
}
.bp-feature-panel__h3 {
  font-size: 19px;       /* clearly smaller than the section H2 (34px) */
}
.bp-feature-panel__count {
  font-size: 11px;
  margin-bottom: 18px;
}

/* ============================================================
   Feature panels — same boxed look as the sample panels but
   each contains a CSS-animated mock of an in-app feature.
   ============================================================ */
.bp-feature-panels-section {
  padding: 24px 16px;
  background: var(--cream);
}
.bp-feature-panel {
  position: relative;
  /* No overflow:hidden here — the phone's drop shadow needs to extend
     beyond the panel's bottom edge. The bg layer below clips itself
     to the rounded corners on its own border-radius. */
  padding: 42px 32px 48px;
  text-align: center;
  isolation: isolate;
  max-width: 720px;
  margin: 0 auto;
  border-radius: 28px;
}
.bp-feature-panel + .bp-feature-panel { margin-top: 36px; }

/* ============================================================
   How it works with Yoto — video demo section.
   Sits between samples + features carousels. Lifted from the
   original Framer LP so existing Yoto buyers recognise the
   mechanic at a glance.
   ============================================================ */
.bp-how-yoto-section {
  padding: 64px 0;
  background: var(--cream);
}
.bp-how-yoto__intro {
  text-align: center;
  margin: 0 0 28px;
}
.bp-how-yoto__kicker {
  font-family: 'Poppins', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--crimson);
  display: block;
  margin-bottom: 10px;
}
.bp-how-yoto__h2 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 34px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: var(--ink);              /* matches site h2 pattern */
  margin: 0;
}
.bp-how-yoto__video-wrap {
  max-width: 600px;
  margin: 0 auto 28px;
  border-radius: 28px;            /* matches the sample panels' rounded corners */
  overflow: hidden;
  box-shadow: 0 18px 40px rgba(0, 0, 0, 0.14);
  background: #000;
  /* iOS Safari quirk: <video> ignores parent border-radius+overflow:hidden
     unless the parent forces a compositing layer. translateZ(0) does that. */
  transform: translateZ(0);
  -webkit-mask-image: -webkit-radial-gradient(white, black); /* belt-and-braces clip */
}
.bp-how-yoto__video {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 28px;            /* clip the video itself too — iOS won't always honour parent's */
}
.bp-how-yoto__body {
  max-width: 600px;
  margin: 0 auto;
  font-family: 'Source Serif 4', serif;
  font-size: 19px;                /* editorial prose, matches Emily article body weight */
  line-height: 1.6;
  color: var(--ink);              /* darker than --ink-soft for proper blog-prose contrast */
  text-align: center;
}
.bp-how-yoto__body p { margin: 0 0 18px; }
.bp-how-yoto__body p:last-child { margin-bottom: 0; }

@media (max-width: 720px) {
  .bp-how-yoto-section { padding: 44px 0; }
  .bp-how-yoto__h2 { font-size: 34px; }
  .bp-how-yoto__body { font-size: 17px; line-height: 1.55; }
}


/* Mobile pop-in: JS scroll listener writes inline `transform` on every
   `.bp-sample-panel` / `.bp-feature-panel` based on its viewport
   position (see setupBlockZooms in template.js). We don't declare a
   transform here — the inline style handles it directly, no cascade
   races, no IntersectionObserver-vs-dynamic-DOM timing problems.
   The `.is-immersed` class is still toggled by that script so the
   inner-animation pause logic below keeps working.
   `will-change: transform` hints the browser to layer-promote each
   panel for cheap repaints during scroll. */
@media (max-width: 720px) {
  .bp-feature-panel,
  .bp-sample-panel {
    will-change: transform;
  }

  /* Inner feature animations stay paused until panel is in view.
     Target ONLY descendants, never the panel itself. */
  .bp-feature-panel:not(.is-immersed) * {
    animation-play-state: paused !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bp-feature-panel,
  .bp-sample-panel {
    transform: none !important;
    will-change: auto;
  }
}

.bp-feature-panel__bg {
  position: absolute;
  inset: 0;
  z-index: -1;
  background: #1a1a1a;
  border-radius: 28px;  /* matches parent so the gradient corners are rounded too */
}
/* Sleep-timer dark gradient removed; uses shared white theme-light. */
.bp-feature-panel__h3 {
  font-family: 'Rubik', sans-serif;
  font-weight: 900;
  font-size: 32px;
  line-height: 1.05;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  color: #fff;
  margin: 0 0 6px;
}
.bp-feature-panel__count {
  font-family: 'Poppins', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.65);
  margin: 0 0 28px;
}

/* --- Phone frame ------------------------------------------- */
/* Shorter than a real phone: we only need the bottom portion where the
   timer modal pops up. Top of the device fades into the panel bg via
   a mask so the modal is the visual focus. */
.bp-phone {
  position: relative;
  width: 220px;
  margin: 0 auto;
  aspect-ratio: 220 / 300;
  background: #08090E;
  border-top-left-radius: 36px;
  border-top-right-radius: 36px;
  border-bottom-left-radius: 36px;
  border-bottom-right-radius: 36px;
  border: 1px solid rgba(255, 255, 255, 0.10);
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.22), inset 0 0 0 2px #131520;
  overflow: hidden;
}
.bp-phone__notch {
  display: none;  /* hidden — top of phone faded out anyway */
}
.bp-phone__screen {
  position: absolute;
  inset: 4px;
  border-radius: 32px;
  overflow: hidden;
  background: #15171F;
}
/* Player UI mock — sits behind the timer modal. Cover is now rectangular
   (book-cover proportions) and the layout is tighter to fit the shorter
   phone. */
.bp-phone__player {
  position: absolute;
  inset: 0;
  padding: 28px 18px 18px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}
.bp-phone__cover {
  width: 84px;
  aspect-ratio: 1000 / 1333;
  border-radius: 8px;
  background-size: cover;
  background-position: center;
  background-color: #2A2A2C;
  box-shadow: 0 8px 18px rgba(0, 0, 0, 0.5);
}
.bp-phone__title {
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 12px;
  color: #fff;
  margin-top: 4px;
}
.bp-phone__bar {
  width: 80%;
  height: 3px;
  background: rgba(255, 255, 255, 0.18);
  border-radius: 999px;
  position: relative;
}
.bp-phone__bar-fill {
  position: absolute;
  top: 0; left: 0; bottom: 0;
  width: 30%;
  background: var(--crimson);
  border-radius: 999px;
}
.bp-phone__controls {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 4px;
}
.bp-phone__ctrl, .bp-phone__play {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(255, 255, 255, 0.06);
  color: #fff;
}
.bp-phone__play {
  width: 42px;
  height: 42px;
  background: var(--crimson);
}
.bp-phone__ctrl svg, .bp-phone__play svg { width: 16px; height: 16px; }
.bp-phone__play svg { width: 18px; height: 18px; }
/* Timer button below the controls */
.bp-phone__timer-btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: 4px;
  color: rgba(255, 255, 255, 0.55);
  /* No `transition: color` — the bp-timer-btn-pulse keyframe drives
     the colour, and a transition would smooth the loop-boundary snap
     from crimson back to grey into a 300ms fade through red, which
     reads as "red first" before settling to idle. */
}
.bp-phone__timer-btn svg { width: 18px; height: 18px; }
.bp-phone__timer-label {
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 500;
}

/* --- Timer modal -------------------------------------------- */
.bp-phone__modal {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  background: #1a1a1a;
  border-top-left-radius: 18px;
  border-top-right-radius: 18px;
  padding: 10px 12px 16px;
  transform: translateY(100%);
  box-shadow: 0 -10px 30px rgba(0, 0, 0, 0.5);
}
.bp-phone__modal-handle {
  width: 28px;
  height: 3px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.35);
  margin: 0 auto 10px;
}
.bp-phone__modal-title {
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 13px;
  font-weight: 600;
  text-align: center;
  margin-bottom: 12px;
}
.bp-phone__modal-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}
.bp-phone__modal-opt {
  background: #2A2A2A;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  padding: 6px 4px;
  border-radius: 8px;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  line-height: 1;
  gap: 1px;
}
.bp-phone__modal-opt-num {
  font-size: 13px;
  font-weight: 700;
}
.bp-phone__modal-opt-unit {
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: lowercase;
  opacity: 0.7;
}
.bp-phone__modal-opt--end {
  grid-column: span 4;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.18);
  font-size: 9px;
  padding: 7px 4px;
}

/* --- Finger pointer ----------------------------------------- */
.bp-phone__finger {
  position: absolute;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.18);
  border: 2px solid rgba(255, 255, 255, 0.55);
  pointer-events: none;
  /* Initial: parked off-screen below */
  top: 100%;
  left: 50%;
  transform: translate(-50%, 0);
  opacity: 0;
}

/* --- Animation timeline (12s loop) -------------------------- */
@keyframes bp-finger-tap {
  /* 0-5%: hidden, off-screen below */
  0%, 5%   { opacity: 0; top: 100%; left: 50%; transform: translate(-50%, 0); }
  /* 10%: finger appears over the timer button (now sits just below the
     cover since prev/play/next controls were removed). */
  10%      { opacity: 1; top: 70%; left: 50%; transform: translate(-50%, 0) scale(1); }
  14%      { opacity: 1; top: 70%; left: 50%; transform: translate(-50%, 0) scale(0.7); }
  17%      { opacity: 1; top: 70%; left: 50%; transform: translate(-50%, 0) scale(1); }
  /* 22-38%: hidden while modal slides up. */
  22%, 38% { opacity: 0; }
  /* 42%: appear over the 15-min cell. Grid is 4 columns; col 3 centre =
     (3 - 0.5) / 4 = 62.5%. Modal sits in the lower ~60% of the phone
     screen; row 1 of the grid is ~62% from screen top. */
  42%      { opacity: 1; top: 62%; left: 62.5%; transform: translate(-50%, 0) scale(1); }
  45%      { opacity: 1; top: 62%; left: 62.5%; transform: translate(-50%, 0) scale(0.7); }
  47%      { opacity: 1; top: 62%; left: 62.5%; transform: translate(-50%, 0) scale(1); }
  52%, 100% { opacity: 0; }
}
@keyframes bp-modal-slide {
  /* 0-18%: hidden below. 18-24%: quicker slide up. 24-50%: stay open. */
  0%, 18%  { transform: translateY(100%); }
  24%      { transform: translateY(0); }
  50%      { transform: translateY(0); }
  60%, 100% { transform: translateY(100%); }
}
@keyframes bp-modal-15min-highlight {
  /* dark default for most of timeline */
  0%, 44%  { background: #2A2A2A; color: #fff; }
  /* 45%-50%: highlight crimson (user has selected) */
  45%      { background: var(--crimson); color: #fff; }
  50%      { background: var(--crimson); color: #fff; }
  /* fade back */
  55%, 100% { background: #2A2A2A; color: #fff; }
}
@keyframes bp-timer-btn-pulse {
  /* 0-10%: idle (muted) */
  0%, 10%  { color: rgba(255,255,255,0.55); transform: scale(1); }
  /* 12-16%: tapped */
  13%      { color: rgba(255,255,255,0.85); transform: scale(0.95); }
  17%      { color: rgba(255,255,255,0.55); transform: scale(1); }
  /* 18-50%: stays muted while modal up + selecting */
  50%      { color: rgba(255,255,255,0.55); }
  /* 60%+: timer is active — turns crimson */
  60%, 100% { color: var(--crimson); transform: scale(1); }
}
/* Two-span pill: --from holds "Timer", --to holds "14m". Stacked
   into the same grid cell so the label auto-sizes to the wider of
   the two and the swap is a pure opacity flip — no `content`-property
   animation flakiness (which was making "14m" briefly visible before
   the user tap in some browsers). */
@keyframes bp-timer-label-from { 0%, 58% { opacity: 1; } 60%, 100% { opacity: 0; } }
@keyframes bp-timer-label-to   { 0%, 58% { opacity: 0; } 60%, 100% { opacity: 1; } }
.bp-feature-panel--sleep-timer .bp-phone__finger {
  animation: bp-finger-tap 12s infinite cubic-bezier(0.4, 0, 0.2, 1);
}
.bp-feature-panel--sleep-timer .bp-phone__modal {
  animation: bp-modal-slide 12s infinite cubic-bezier(0.4, 0, 0.2, 1);
}
.bp-feature-panel--sleep-timer .bp-phone__modal-opt--target {
  animation: bp-modal-15min-highlight 12s infinite linear;
}
.bp-feature-panel--sleep-timer .bp-phone__timer-btn {
  /* step-end so colour snaps from grey to crimson at the same moment
     the modal finishes sliding down (60%) and the label flips to
     "14m". No gradual fade through pinkish-red intermediate states. */
  animation: bp-timer-btn-pulse 12s infinite step-end;
}
/* Two-span timer label — Timer / 14m grid-stacked, opacity-flipped. */
.bp-feature-panel--sleep-timer .bp-phone__timer-label {
  display: grid;
  align-items: center;
  justify-items: center;
  font-size: 9px;
}
.bp-feature-panel--sleep-timer .bp-phone__timer-label--from,
.bp-feature-panel--sleep-timer .bp-phone__timer-label--to {
  grid-area: 1 / 1;
  white-space: nowrap;
}
.bp-feature-panel--sleep-timer .bp-phone__timer-label--to { opacity: 0; }
.bp-feature-panel--sleep-timer .bp-phone__timer-label--from {
  animation: bp-timer-label-from 12s infinite step-end;
}
.bp-feature-panel--sleep-timer .bp-phone__timer-label--to {
  animation: bp-timer-label-to 12s infinite step-end;
}

@media (max-width: 720px) {
  .bp-feature-panel { padding: 34px 24px 40px; }
  .bp-feature-panel__h3 { font-size: 22px; }   /* was 30, dropped 8pt */
  .bp-feature-panel__count { font-size: 11px; margin-bottom: 22px; }
  .bp-phone { width: 220px; }
  /* Extra breathing room between the section subhead and the first
     panel below it. */
  .bp-features-intro { margin-bottom: 44px; }
}

/* ============================================================
   Desktop layout — 2-column grids for the audio + feature panels.
   Each panel sits in its column at the section's max-width; the
   section uses flex-flow: row wrap so panels stack 2-up.
   ============================================================ */
@media (min-width: 768px) {
  /* Samples section runs as a cover-flow CAROUSEL on desktop —
     centre panel full-size, side panels semi-faded, prev/next + drag
     to navigate. The carousel wrapper provides the absolute-positioning
     stage; JS sets each panel's transform on layout(). */
  .bp-samples-section {
    position: relative;
    max-width: 1100px;
    margin: -30px auto 0;       /* pulled up another 30px under the hero */
    padding: 12px 24px 80px;
  }
  .bp-samples-carousel {
    position: relative;
    width: 100%;
    height: 740px;
    perspective: 1200px;
  }
  .bp-samples-carousel .bp-sample-panel {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 520px;
    max-width: none;
    margin: 0;
    transform: translate(-50%, -50%);
    transition: transform 0.45s cubic-bezier(0.22, 0.61, 0.36, 1), opacity 0.4s ease;
    will-change: transform, opacity;
    cursor: grab;
  }
  .bp-samples-carousel .bp-sample-panel:active { cursor: grabbing; }
  .bp-sample-panel + .bp-sample-panel { margin-top: 0; }
  .bp-samples-section #bp-samples-audio { display: none; }

  /* Prev/next floating buttons — pulled up so they sit at the very
     bottom of the carousel area (the carousel has empty space below
     the scaled panels because they're centred vertically). z-index
     stays below the sticky CTA bar (z 100) so the bar always
     overlaps these buttons when both are on screen. */
  .bp-samples-nav {
    display: flex;
    justify-content: center;
    gap: 14px;
    margin-top: -56px;
    position: relative;
    z-index: 5;
  }
  .bp-samples-nav__btn {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    border: 2px solid var(--crimson);
    background: transparent;
    color: var(--crimson);
    cursor: pointer;
    display: grid;
    place-items: center;
    transition: transform 0.15s ease, background 0.15s ease, color 0.15s ease;
  }
  .bp-samples-nav__btn:hover {
    transform: scale(1.08);
    background: var(--crimson);
    color: #fff;
  }
  .bp-samples-nav__btn svg { width: 26px; height: 26px; }
  .bp-samples-nav__btn--right svg { transform: rotate(180deg); }

  /* Feature panels in a cover-flow CAROUSEL on desktop (same pattern
     as the samples carousel). Each panel gets a clear bounding-box
     look (white bg + soft shadow) regardless of theme. */
  .bp-feature-panels-section {
    position: relative;
    max-width: 1100px;
    margin: 0 auto;
    padding: 32px 24px 80px;
  }
  /* Features = full-width horizontal scroll strip. Five-ish panels
     visible at once, edges cut off intentionally so the strip reads
     as continuous. Vertical padding gives the panel shadows room to
     breathe. */
  /* Features = full-width horizontal scroll strip. Panels are bigger
     than they were so the phone + animation read clearly. The strip's
     left/right padding equals (50vw - panelWidth/2) so the first and
     last panels can snap to centre — and on first load scrollLeft=0
     places "New stories included" smack in the middle. */
  /* Features section on desktop is a 2-column grid (5 rows × 2 cols
     for 10 panels). Default state matches the founders card chrome:
     white bg, single 1px line border, soft shadow. On hover the
     panel pops out slightly, the border goes crimson, and the inner
     animation plays. */
  .bp-features-carousel {
    position: relative;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    max-width: 980px;
    margin: 0 auto;
    padding: 24px 0;
  }
  .bp-features-carousel .bp-feature-panel {
    position: relative;
    width: auto;
    max-width: none;
    margin: 0;
    padding: 36px 30px 44px;
    /* Single chrome system using box-shadow: a 1px line ring (acting
       as the border) + a soft drop shadow. No actual border, so there's
       no layout shift on hover. Same visual as the founders card. */
    box-shadow: 0 0 0 1px var(--line), 0 8px 24px rgba(0, 0, 0, 0.06);
    transform: scale(1);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
    cursor: pointer;
  }
  /* Roadmap is the last panel; with 9 panels in a 2-col grid, the last
     would orphan-left otherwise. Span both columns + centre. Width set
     explicitly because the general rule's width:auto + content-narrow
     would otherwise shrink the panel. */
  .bp-features-carousel .bp-feature-panel--roadmap {
    grid-column: 1 / -1;
    width: 100%;
    max-width: 540px;
    justify-self: center;
  }
  /* Plain white background on the bg layer — drops the desktop-only
     cream gradient override that was causing the cream stroke. */
  .bp-features-carousel .bp-feature-panel__bg {
    background: #FFFFFF !important;
    border: none;
  }
  /* Hover only — the highlight (crimson stroke + scale-up) is purely
     a hover effect. All panels animate by default. */
  .bp-features-carousel .bp-feature-panel:hover {
    transform: scale(1.02);
    box-shadow: 0 0 0 2px var(--crimson), 0 14px 36px rgba(255, 14, 77, 0.12), 0 8px 24px rgba(0, 0, 0, 0.10);
    z-index: 2;
  }
  /* All panels' inner animations play by default. */
  /* Hide leftover cloned panels + nav buttons — not needed in grid. */
  .bp-features-carousel .bp-feature-panel[data-clone-side="before"],
  .bp-features-carousel .bp-feature-panel[data-clone-side="after"] {
    display: none;
  }
  .bp-features-nav { display: none !important; }
  .bp-features-carousel .bp-feature-panel__h3 {
    font-size: 22px;
    line-height: 1.05;
    margin: 0 0 6px;
  }
  .bp-features-carousel .bp-feature-panel__count {
    font-size: 10px;
    margin-bottom: 22px;
  }
  .bp-features-carousel .bp-phone {
    width: 220px;
    aspect-ratio: 220 / 300;
  }
  /* Bounding-box bg — soft white card, regardless of the panel's
     original theme. Overrides the transparent --theme-light bg. */
  .bp-features-carousel .bp-feature-panel__bg {
    background: linear-gradient(160deg, #FFFFFF 0%, #FBF6EC 100%) !important;
  }
  .bp-feature-panel + .bp-feature-panel { margin-top: 0; }

  /* Nav buttons — same styling and spacing as samples nav. */
  .bp-features-nav {
    display: flex;
    justify-content: center;
    gap: 14px;
    margin-top: -56px;
    position: relative;
    z-index: 5;
  }
  /* Section header above the features carousel — hero-scale h2 + lede.
     Builds the "we've got it covered" emotional moment before the
     buyer reads the feature list itself. */
  /* Desktop-only intro overrides (sizes / spacing). The base styles
     are defined OUTSIDE this @media block so they apply to mobile too. */
  .bp-features-intro {
    margin: 0 auto 32px;
    padding: 24px 16px 0;
  }
  .bp-features-intro__h2     { font-size: 38px; }
  .bp-section__h2            { font-size: 38px; }
  .bp-features-intro__lede   { font-size: 19px; }
  .bp-features-intro__kicker { font-size: 13px; }

  /* Pause/fade only applies to the SAMPLES cover-flow — features are
     now a side-by-side scroll strip where every panel is visible
     and active simultaneously. */
  .bp-samples-carousel .bp-sample-panel:not(.is-active) *,
  .bp-samples-carousel .bp-sample-panel:not(.is-active) {
    animation-play-state: paused !important;
  }

  .bp-samples-carousel .bp-sample-panel { isolation: isolate; }
  .bp-samples-carousel .bp-sample-panel::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background: var(--cream);
    opacity: 0;
    transition: opacity 0.4s ease;
    pointer-events: none;
    z-index: 999;
  }
  .bp-samples-carousel .bp-sample-panel.is-shoulder::after { opacity: 0.45; }
  .bp-samples-carousel .bp-sample-panel.is-far::after      { opacity: 0.75; }
  .bp-samples-carousel .bp-sample-panel:not(.is-active) .bp-sample-panel__card-anim {
    opacity: 0 !important;
    visibility: hidden;
  }

  /* Slight static rotation per panel — looks hand-placed rather than
     grid-perfect. Different sign + magnitude per panel so no two
     adjacent panels tilt the same way. */
  .bp-sample-panel--originals       { transform: rotate(-2deg); }
  .bp-sample-panel--fairy-tales     { transform: rotate(3deg); }
  .bp-sample-panel--aesops-fables   { transform: rotate(-1.5deg); }
  .bp-sample-panel--rhymes          { transform: rotate(2deg); }
  .bp-sample-panel--nursery-rhymes  { transform: rotate(-2.5deg); }
  .bp-feature-panel--playlists      { transform: rotate(2deg); }
  .bp-feature-panel--offline        { transform: rotate(-2deg); }
  .bp-feature-panel--sleep-timer    { transform: rotate(1.5deg); }
  .bp-feature-panel--speed          { transform: rotate(-3deg); }
  .bp-feature-panel--loop           { transform: rotate(2deg); }
  .bp-feature-panel--yoto           { transform: rotate(-1.5deg); }
  .bp-feature-panel--bluetooth      { transform: rotate(2.5deg); }
}

/* Per-panel deep tints removed — every feature panel now uses the
   shared `--theme-light` white card. The dark in-app simulation lives
   inside the phone mockup; the panel chrome stays neutral. */

/* Larger cover variant for panels where the cover is the focal point */
.bp-phone__cover--lg {
  width: 110px;
  position: relative;
}

/* Status line under the cover for panels with no controls (offline) */
.bp-phone__status {
  font-family: 'Poppins', sans-serif;
  font-size: 10px;
  font-weight: 500;
  color: rgba(255, 255, 255, 0.55);
  margin-top: -3px;  /* 7px tighter to the button than the default flex gap */
  opacity: 0;
}

/* ============================================================
   Panel 2: Offline download — centred ROUND button under the cover.
   Idle: white outline + white download arrow.
   During: crimson arc fills around the button.
   On success: button fills GREEN, white tick replaces the arrow.
   Resets, loops.
   ============================================================ */
.bp-phone__dl-btn {
  position: relative;
  width: 40px;
  height: 40px;
  margin-top: 6px;
  flex-shrink: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.08);
  border: 1.5px solid rgba(255, 255, 255, 0.45);
  display: grid;
  place-items: center;
  color: #fff;
  transition: background 0.25s ease, border-color 0.25s ease;
}
.bp-phone__dl-icon, .bp-phone__dl-check {
  position: absolute;
  width: 16px;
  height: 16px;
  color: #fff;
}
.bp-phone__dl-arc {
  position: absolute;
  /* SVG sits exactly on the button's border. The button has 1.5px
     border so the arc circle (r=18.5 in viewBox 40) traces along it. */
  inset: 0;
  width: 100%;
  height: 100%;
  color: var(--crimson);
  pointer-events: none;
  overflow: visible;
}
.bp-phone__dl-check { opacity: 0; }

/* Sequence:
   0-18%   idle: white outline ring + white download arrow
   22%     finger taps
   22-70%  crimson arc fills around the button
   70-76%  arc holds at full briefly
   76-82%  arc disappears (stroke offset hidden) — gone before tick lands
   82-90%  green button + white tick replaces the arrow
   86-94%  "Available offline" caption fades in beneath
   94-100% reset back to idle outline ring */
/* Hard cut from the crimson loading ring → green tick state. No fade.
   Arc fills 22 → 76%, holds 76 → 79%, then INSTANTLY snaps hidden at
   the same moment the green bg + tick appear. */
@keyframes bp-dl-icon       { 0%, 79% { opacity: 1 } 80%, 97% { opacity: 0 } 99%, 100% { opacity: 1 } }
@keyframes bp-dl-icon-bounce {
  0%, 22%   { transform: translateY(0); }
  28%       { transform: translateY(-3px); }
  34%       { transform: translateY(0); }
  40%       { transform: translateY(-3px); }
  46%       { transform: translateY(0); }
  52%       { transform: translateY(-3px); }
  58%       { transform: translateY(0); }
  64%       { transform: translateY(-3px); }
  70%       { transform: translateY(0); }
  76%, 100% { transform: translateY(0); }
}
/* Loader behaviour: arc fills ONCE smoothly during the download phase,
   then holds full briefly before the hard cut to the green tick.
   No multi-fill spinner — Simon wants a single completion. */
@keyframes bp-dl-arc {
  0%, 22%   { stroke-dashoffset: 121 }
  76%, 79%  { stroke-dashoffset: 0 }
  80%, 100% { stroke-dashoffset: 121 }
}
@keyframes bp-dl-check      { 0%, 79% { opacity: 0 } 80%, 97% { opacity: 1 } 99%, 100% { opacity: 0 } }
@keyframes bp-dl-btn-bg     { 0%, 79% { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.45); } 80%, 97% { background: #2BD45A; border-color: #2BD45A; } 99%, 100% { background: rgba(255,255,255,0.08); border-color: rgba(255,255,255,0.45); } }
@keyframes bp-dl-status     { 0%, 80% { opacity: 0 } 84%, 97% { opacity: 1 } 99%, 100% { opacity: 0 } }
@keyframes bp-dl-finger     { 0%, 4% { opacity: 0; top: 100%; } 8%, 14% { opacity: 1; top: 78%; left: 50%; transform: translate(-50%, 0) scale(1) } 16% { opacity: 1; top: 78%; left: 50%; transform: translate(-50%, 0) scale(0.7) } 20% { opacity: 1; transform: translate(-50%, 0) scale(1); top: 78%; left: 50% } 22%, 100% { opacity: 0 } }

.bp-feature-panel--offline .bp-phone__dl-icon         { animation: bp-dl-icon 7s infinite step-end, bp-dl-icon-bounce 7s infinite ease-in-out; }
.bp-feature-panel--offline .bp-phone__dl-arc circle   { animation: bp-dl-arc 7s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--offline .bp-phone__dl-check        { animation: bp-dl-check 7s infinite step-end; }
.bp-feature-panel--offline .bp-phone__dl-btn          { animation: bp-dl-btn-bg 7s infinite step-end; }
.bp-feature-panel--offline .bp-phone__status          { animation: bp-dl-status 7s infinite ease-in-out; }
.bp-feature-panel--offline .bp-phone__finger--offline { animation: bp-dl-finger 7s infinite cubic-bezier(0.4, 0, 0.2, 1); }

/* ============================================================
   Background variants — try a crimson + a light-cream theme
   on two of the panels to see how they read.
   ============================================================ */
.bp-feature-panel--yoto.bp-feature-panel--theme-crimson .bp-feature-panel__bg {
  background: linear-gradient(160deg, #FF0E4D 0%, #C20C40 100%);
}
/* Light-themed feature panels: white card with a subtle outline.
   Headline + subtext go dark for legibility. The phone mockup inside
   stays dark, so the contrast still pops. */
.bp-feature-panel--theme-light .bp-feature-panel__bg {
  background: #FFFFFF;
  border: 1px solid rgba(26, 26, 26, 0.06);
}
.bp-feature-panel--theme-light .bp-feature-panel__h3 { color: #1A1A1A; }
.bp-feature-panel--theme-light .bp-feature-panel__count { color: rgba(26, 26, 26, 0.6); }

/* Vibrant slate-grey theme — slightly darker, has depth via gradient,
   white text reads clean. Sits between the deep tints and the light
   theme as a "neutral but alive" option. */
.bp-feature-panel--theme-graphite .bp-feature-panel__bg {
  background: linear-gradient(160deg, #3D434E 0%, #1F232C 100%);
}

/* ============================================================
   Panel 3: Send to Yoto
   ============================================================ */
/* Phone + Yoto card grouped + centred horizontally inside the panel.
   The two devices are wrapped in their own inline-flex so the gap
   between them is the only horizontal space — the group is then
   centred by the parent's flex layout. */
.bp-yoto-stage {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 22px;
  margin-top: 4px;
  padding: 0 4px;
}
/* Yoto-panel phone — same shape/size as the Listen Offline phone so the
   composition reads consistently across panels. The slightly-squarer
   aspect (vs the default phone) makes room for the card on the right. */
.bp-phone--yoto {
  width: 150px;
  aspect-ratio: 150 / 240;
}
.bp-phone--yoto .bp-phone__screen { inset: 4px; border-radius: 28px; }
.bp-phone--yoto .bp-phone__player { padding: 22px 14px 18px; gap: 8px; }
.bp-phone--yoto .bp-phone__cover--lg { width: 84px; }
.bp-phone--yoto .bp-phone__title { font-size: 11px; }

/* Desktop only — bump the Yoto phone + card up to the same size as the
   other panels' phones, tighten the gap between them, and re-centre
   under the headline. */
@media (min-width: 768px) {
  .bp-phone--yoto {
    width: 220px;
    aspect-ratio: 220 / 300;
  }
  .bp-phone--yoto .bp-phone__player { padding: 28px 18px 22px; gap: 10px; }
  .bp-phone--yoto .bp-phone__cover--lg { width: 110px; }
  .bp-phone--yoto .bp-phone__title { font-size: 13px; }
  .bp-feature-panel--yoto .bp-yoto-stage { gap: 14px; }
  .bp-feature-panel--yoto .bp-yoto-card {
    width: 130px;
    height: 196px;
    border-radius: 12px;
  }
  .bp-feature-panel--yoto .bp-yoto-card__face { width: 56px; height: 56px; }
  .bp-feature-panel--yoto .bp-yoto-card__myo-label { font-size: 14px; }
  .bp-feature-panel--yoto .bp-yoto-sticker--fly {
    width: 130px;
    height: 196px;
  }
}
.bp-phone__yoto-btn {
  margin-top: 4px;
  padding: 6px 14px;
  background: var(--crimson);
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 10px;
  font-weight: 600;
  line-height: 1;            /* keep text vertically centred in the pill */
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
/* Yoto Make-Your-Own card. Pure white, no header strip — matches the
   actual MYO card the buyer would buy. Starts blank with the orange
   smiley + "MYO" caption; the printable sticker lands on top + replaces
   the MYO state. */
.bp-yoto-card {
  position: relative;
  width: 100px;
  height: 152px;
  background: #fff;
  border-radius: 10px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35);
  overflow: hidden;
}
.bp-yoto-card__strip { display: none; }
.bp-yoto-card__myo {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  background: #fff;
  z-index: 2;
}
.bp-yoto-card__face {
  width: 44px;
  height: 44px;
}
.bp-yoto-card__myo-label {
  font-family: 'Poppins', sans-serif;
  font-weight: 800;
  font-size: 12px;
  letter-spacing: 0.18em;
  color: #1a1a1a;
}
.bp-yoto-card__sticker {
  position: absolute;
  inset: 0;
  z-index: 4;
  opacity: 0;
  transform: scale(0.7);
  background-size: cover;
  background-position: center;
}

/* Sticker = printable template. Cover artwork + crimson SOOPER BOOKS
   banner across the bottom. Used both as the flying object and as the
   card's final state. */
.bp-yoto-sticker {
  position: relative;
  display: flex;
  flex-direction: column;
  border-radius: 4px;
  overflow: hidden;
  width: 100%;
  height: 100%;
}
.bp-yoto-sticker__art {
  flex: 1;
  background-size: cover;
  background-position: center;
  background-color: #2A2A2C;
}
.bp-yoto-sticker__band {
  background: var(--crimson);
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 6px;
  font-weight: 800;
  letter-spacing: 0.12em;
  text-align: center;
  padding: 3px 2px;
  flex-shrink: 0;
}
/* Flying sticker — animates from phone position to card position */
.bp-yoto-sticker--fly {
  position: absolute;
  width: 100px;
  height: 152px;
  top: 50%;
  left: 30%;
  transform: translate(-50%, -50%) scale(0.6);
  opacity: 0;
  background-size: cover;
  background-position: center;
  border-radius: 10px;
  box-shadow: 0 8px 22px rgba(0, 0, 0, 0.5);
  z-index: 6;
}

@keyframes bp-yoto-sticker-fly {
  /* Idle / hidden until the moment the sticker leaves the phone */
  0%, 18%   { opacity: 0; left: 24%; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  22%       { opacity: 1; left: 24%; transform: translate(-50%, -50%) scale(1) rotate(0deg); }
  /* Travels right + slight tumble. Lands on the card. */
  55%       { opacity: 1; left: 76%; transform: translate(-50%, -50%) scale(0.85) rotate(6deg); }
  /* Hand-off: flying sticker hides, card sticker appears (animated below) */
  60%, 100% { opacity: 0; left: 76%; transform: translate(-50%, -50%) scale(0.85) rotate(6deg); }
}
@keyframes bp-yoto-myo-fade {
  0%, 55%   { opacity: 1; }
  60%, 100% { opacity: 0; }
}
@keyframes bp-yoto-card-sticker-in {
  0%, 55%   { opacity: 0; transform: scale(0.7); }
  60%       { opacity: 1; transform: scale(1.05); }
  64%, 100% { opacity: 1; transform: scale(1); }
}
@keyframes bp-yoto-card-glow {
  0%, 56%   { box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35); }
  62%, 78%  { box-shadow: 0 0 0 4px rgba(255, 14, 77, 0.30), 0 12px 28px rgba(0, 0, 0, 0.35); }
  100%      { box-shadow: 0 12px 28px rgba(0, 0, 0, 0.35); }
}

/* Finger taps "Send to Yoto" before the sticker leaves the phone. */
@keyframes bp-yoto-finger {
  0%, 8%   { opacity: 0; top: 100%; }
  12%      { opacity: 1; top: 78%; left: 50%; transform: translate(-50%, 0) scale(1); }
  16%      { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  18%      { opacity: 1; transform: translate(-50%, 0) scale(1); }
  22%, 100% { opacity: 0; }
}

/* Yoto panel: 6.4s loop (12s → 8s → 6.4s, another 20% faster). */
.bp-feature-panel--yoto .bp-yoto-sticker--fly      { animation: bp-yoto-sticker-fly 6.4s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--yoto .bp-yoto-card__myo         { animation: bp-yoto-myo-fade 6.4s infinite ease-in-out; }
.bp-feature-panel--yoto .bp-yoto-card__sticker     { animation: bp-yoto-card-sticker-in 6.4s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--yoto .bp-phone__finger--yoto    { animation: bp-yoto-finger 6.4s infinite cubic-bezier(0.4, 0, 0.2, 1); }
/* Card glow on landing removed — Simon prefers a quieter handoff. */

/* ============================================================
   Panel 4: Speed control
   ============================================================ */
.bp-phone__speed-pill {
  margin-top: 4px;
  padding: 5px 14px;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
}
/* Two-span pill: --from holds "1x", --to holds "1.5x". Stacked
   into the same grid cell so the pill auto-sizes to the wider
   ("1.5x") and the swap is a pure opacity flip — no layout shift,
   no `content`-property animation flakiness. */
.bp-phone__speed-pill {
  display: grid;
  align-items: center;
  justify-items: center;
}
.bp-phone__speed-val {
  grid-area: 1 / 1;
  white-space: nowrap;
}
.bp-phone__speed-val--to { opacity: 0; }

/* Speed selection modal — same pattern as the sleep-timer modal,
   slides up over the player when the speed pill is tapped. */
.bp-phone__modal--speed { padding: 10px 12px 16px; }
.bp-phone__speed-grid {
  display: flex;
  gap: 6px;
}
.bp-phone__speed-opt {
  flex: 1;
  background: #2A2A2A;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-weight: 500;
  font-size: 10px;
  text-align: center;
  padding: 9px 4px;
  border-radius: 8px;
}

/* Animation timeline (12s):
     0–22%   idle, pill shows "1x", bar fills slowly
     17%     finger appears over the speed pill
     22%     finger taps pill
     22–30%  modal slides up
     30–47%  modal sits open
     50%     finger taps "1.5x" cell, cell pulses crimson
     55–62%  modal slides down, pill swaps to "1.5x" crimson
     62–100% bar fills MUCH faster (1.5x rate). */
@keyframes bp-speed-val-from { 0%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
@keyframes bp-speed-val-to   { 0%, 55% { opacity: 0; } 56%, 100% { opacity: 1; } }
@keyframes bp-speed-pill-color {
  0%, 55%   { color: #fff; border-color: rgba(255,255,255,0.4); }
  56%, 100% { color: var(--crimson); border-color: var(--crimson); }
}
@keyframes bp-speed-modal {
  0%, 22%   { transform: translateY(100%); }
  /* Faster slide up: 22→26% instead of 22→30% */
  26%, 55%  { transform: translateY(0); }
  62%, 100% { transform: translateY(100%); }
}
@keyframes bp-speed-target-bg {
  0%, 47%   { background: #2A2A2A; }
  50%, 55%  { background: var(--crimson); }
  62%, 100% { background: #2A2A2A; }
}
@keyframes bp-speed-finger {
  0%, 12% { opacity: 0; top: 100%; left: 50%; transform: translate(-50%, 0) scale(1); }
  /* Tap 1: speed pill (sits below the cover/title) */
  17%     { opacity: 1; top: 76%; left: 50%; transform: translate(-50%, 0) scale(1); }
  20%     { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  22%     { opacity: 1; transform: translate(-50%, 0) scale(1); }
  26%, 42% { opacity: 0; }
  /* Tap 2: "1.5x" cell — 4th of 5 cells in a row in the modal which
     sits in the bottom ~50% of the phone screen. Cell vertical centre
     is ~78% from screen top. */
  47%     { opacity: 1; top: 78%; left: 70%; transform: translate(-50%, 0) scale(1); }
  50%     { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  52%     { opacity: 1; transform: translate(-50%, 0) scale(1); }
  56%, 100% { opacity: 0; }
}
@keyframes bp-speed-bar {
  0%   { width: 0%; }
  55%  { width: 22%; }      /* slow 1x rate up until "1.5x" is picked */
  100% { width: 100%; }     /* fast 1.5x rate fills the rest */
}
.bp-feature-panel--speed .bp-phone__speed-val--from    { animation: bp-speed-val-from 12s infinite step-end; }
.bp-feature-panel--speed .bp-phone__speed-val--to      { animation: bp-speed-val-to 12s infinite step-end; }
.bp-feature-panel--speed .bp-phone__speed-pill         { animation: bp-speed-pill-color 12s infinite step-end; }
.bp-feature-panel--speed .bp-phone__modal--speed       { animation: bp-speed-modal 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--speed .bp-phone__speed-opt--target  { animation: bp-speed-target-bg 12s infinite step-end; }
.bp-feature-panel--speed .bp-phone__finger--speed      { animation: bp-speed-finger 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--speed .bp-phone__bar-fill           { animation: bp-speed-bar 12s infinite linear; }

/* ============================================================
   Panel 5: Loop
   ============================================================ */
.bp-phone__loop-btn {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: 4px;
  color: rgba(255, 255, 255, 0.55);
}
.bp-phone__loop-btn svg { width: 18px; height: 18px; }
.bp-phone__loop-label   {
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 500;
}
.bp-phone__bar--loop { width: 76%; }
.bp-phone__bar-fill--loop { width: 0%; }
/* Three-span loop label — Loop / Story / All grid-stacked, opacity-flipped.
   Replaces the old `::before { content }` animation which was flaky in
   some browsers (e.g. label could read wrong state during step boundary). */
.bp-feature-panel--loop .bp-phone__loop-label {
  display: grid;
  align-items: center;
  justify-items: center;
}
.bp-phone__loop-label--loop,
.bp-phone__loop-label--story,
.bp-phone__loop-label--all {
  grid-area: 1 / 1;
  white-space: nowrap;
}
.bp-phone__loop-label--story,
.bp-phone__loop-label--all { opacity: 0; }

/* Loop button cycles through three states (matching the app's loop modes):
   Loop (grey, off) → Story (crimson, single-story repeat) → All (crimson,
   loop-everything) → Loop (grey, off). Finger taps three times to cycle
   through; progress bar just fills steadily from ~50% upward. */
@keyframes bp-loop-fill-steady {
  0%   { width: 0%; }
  100% { width: 100%; }
}
/* Taps fire at 30%, 55%, 80% — labels + colour switch at the SAME
   instant via step-end, so the visual change happens with the tap. */
@keyframes bp-loop-label-loop  { 0%, 30% { opacity: 1; } 31%, 80% { opacity: 0; } 81%, 100% { opacity: 1; } }
@keyframes bp-loop-label-story { 0%, 30% { opacity: 0; } 31%, 55% { opacity: 1; } 56%, 100% { opacity: 0; } }
@keyframes bp-loop-label-all   { 0%, 55% { opacity: 0; } 56%, 80% { opacity: 1; } 81%, 100% { opacity: 0; } }
@keyframes bp-loop-color-cycle {
  0%, 30%   { color: rgba(255,255,255,0.55); }
  31%, 80%  { color: var(--crimson); }
  81%, 100% { color: rgba(255,255,255,0.55); }
}
@keyframes bp-loop-finger {
  0%, 22%   { opacity: 0; top: 100%; left: 50%; transform: translate(-50%, 0) scale(1); }
  /* Tap 1 @ 30% — switch to Story */
  27%       { opacity: 1; top: 88%; left: 50%; transform: translate(-50%, 0) scale(1); }
  30%       { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  32%       { opacity: 1; transform: translate(-50%, 0) scale(1); }
  36%, 48%  { opacity: 0; }
  /* Tap 2 @ 55% — switch to All */
  52%       { opacity: 1; top: 88%; left: 50%; transform: translate(-50%, 0) scale(1); }
  55%       { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  57%       { opacity: 1; transform: translate(-50%, 0) scale(1); }
  61%, 73%  { opacity: 0; }
  /* Tap 3 @ 80% — back to Loop (off) */
  77%       { opacity: 1; top: 88%; left: 50%; transform: translate(-50%, 0) scale(1); }
  80%       { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  82%       { opacity: 1; transform: translate(-50%, 0) scale(1); }
  86%, 100% { opacity: 0; }
}
/* On Repeat loop runs at 10.5s. The progress bar shares the cycle so
   it goes 0% → 100% over one full pass, hitting 100% exactly when the
   button has cycled Loop → Story → All → Loop. The reset back to 0%
   then feels like a natural endpoint, not a mid-fill jump. */
.bp-feature-panel--loop .bp-phone__bar-fill--loop      { animation: bp-loop-fill-steady 10.5s infinite linear; }
.bp-feature-panel--loop .bp-phone__loop-label--loop    { animation: bp-loop-label-loop 10.5s infinite step-end; }
.bp-feature-panel--loop .bp-phone__loop-label--story   { animation: bp-loop-label-story 10.5s infinite step-end; }
.bp-feature-panel--loop .bp-phone__loop-label--all     { animation: bp-loop-label-all 10.5s infinite step-end; }
.bp-feature-panel--loop .bp-phone__loop-btn            { animation: bp-loop-color-cycle 10.5s infinite step-end; }
.bp-feature-panel--loop .bp-phone__finger--loop        { animation: bp-loop-finger 10.5s infinite cubic-bezier(0.4, 0, 0.2, 1); }

/* ============================================================
   Panel 6: Playlists
   ============================================================ */
.bp-phone__plus-btn {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 600;
}
.bp-phone__plus-btn svg { width: 12px; height: 12px; }
.bp-phone__modal--playlists {
  padding: 10px 12px 14px;
}
.bp-phone__pl-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 10px;
  margin-bottom: 4px;
  background: #2A2A2A;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 10px;
  font-weight: 500;
  border-radius: 8px;
}
.bp-phone__pl-row--new {
  background: transparent;
  border: 1px dashed rgba(255, 255, 255, 0.25);
  color: rgba(255, 255, 255, 0.65);
}
.bp-phone__pl-check {
  width: 12px; height: 12px;
  color: #2BD45A;
  opacity: 0;
}
@keyframes bp-pl-modal {
  0%, 18%  { transform: translateY(100%); }
  /* Faster slide up: 18→24% instead of 18→30% */
  24%, 70% { transform: translateY(0); }
  82%, 100% { transform: translateY(100%); }
}
@keyframes bp-pl-target-bg {
  0%, 44%  { background: #2A2A2A; }
  48%, 70% { background: var(--crimson); }
  74%, 100% { background: #2A2A2A; }
}
@keyframes bp-pl-check {
  0%, 46%  { opacity: 0; }
  52%, 70% { opacity: 1; color: #fff; }
  74%, 100% { opacity: 0; }
}
@keyframes bp-pl-finger {
  0%, 5% { opacity: 0; top: 100%; }
  /* Tap 1 — "Add to playlist" pill near the bottom of the player */
  10% { opacity: 1; top: 76%; left: 50%; transform: translate(-50%, 0); }
  13% { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  16% { opacity: 1; transform: translate(-50%, 0) scale(1); }
  20%, 38% { opacity: 0; }
  /* Tap 2 — "Bedtime favourites" (first row of the modal, the
     --target row). Modal sits in the bottom ~55% of the screen;
     row 1 centre is ~52% from screen top. */
  44% { opacity: 1; top: 52%; left: 50%; transform: translate(-50%, 0) scale(1); }
  47% { opacity: 1; transform: translate(-50%, 0) scale(0.7); }
  49% { opacity: 1; transform: translate(-50%, 0) scale(1); }
  52%, 100% { opacity: 0; }
}
.bp-feature-panel--playlists .bp-phone__modal--playlists { animation: bp-pl-modal 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--playlists .bp-phone__pl-row--target   { animation: bp-pl-target-bg 12s infinite step-end; }
.bp-feature-panel--playlists .bp-phone__pl-check         { animation: bp-pl-check 12s infinite step-end; }
.bp-feature-panel--playlists .bp-phone__finger--pl       { animation: bp-pl-finger 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }

/* ============================================================
   Panel: Quick filters — cover shown, theme pills row scrolls
   underneath, finger taps a target pill, pill highlights crimson,
   cover cross-fades to a story matching the new theme.
   ============================================================ */
.bp-phone__cover-stack {
  display: grid;
  position: relative;
}
.bp-phone__cover--theme-from,
.bp-phone__cover--theme-to {
  grid-area: 1 / 1;
}
.bp-phone__cover--theme-to { opacity: 0; }

.bp-phone__title--theme-stack {
  display: grid;
  align-items: center;
  justify-items: center;
}
.bp-phone__title--theme-from,
.bp-phone__title--theme-to {
  grid-area: 1 / 1;
  white-space: nowrap;
}
.bp-phone__title--theme-to { opacity: 0; }

.bp-phone__theme-pills-wrap {
  width: 100%;
  overflow: hidden;
  margin-top: 8px;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
          mask-image: linear-gradient(to right, transparent 0, #000 8%, #000 92%, transparent 100%);
}
.bp-phone__theme-pills {
  display: flex;
  gap: 5px;
  flex-wrap: nowrap;
  width: max-content;
  padding: 0 6px;
  will-change: transform;
}
.bp-phone__theme-pill {
  flex-shrink: 0;
  padding: 4px 9px;
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 500;
  background: rgba(255, 255, 255, 0.08);
  color: rgba(255, 255, 255, 0.65);
  white-space: nowrap;
  border: 1px solid rgba(255, 255, 255, 0.10);
}

/* Animation timeline (12s):
   0–6%    idle, cover #1, pills at neutral position
   6–34%   ONE long forward scroll — monotonic, decelerating, like
           a real touch-flick that's been released and is coasting
           to a stop. Many pills pass through the visible window so
           the user reads "lots of themes available."
   34–38%  settle with target pill ("Adventure") centred
   38–42%  pause (target sitting in the middle, ready to tap)
   42–48%  finger appears, taps, releases
   48%     INSTANT snap — cover, title, target pill all change in
           the same frame. No fade.
   48–94%  rest with new state
   94–100% snap back to start */
@keyframes bp-themes-pills-scroll {
  0%, 6%    { transform: translateX(0); }
  /* Forward-only flick with deceleration. Adventure is now the 5th
     pill (centre at row position ~250px); for it to land at the
     176px-wrap centre (88px), final translation = -162px. Steps below
     space the motion so it slows toward the end like a coasting flick. */
  12%       { transform: translateX(-45px); }
  20%       { transform: translateX(-100px); }
  26%       { transform: translateX(-138px); }
  32%       { transform: translateX(-156px); }
  38%, 100% { transform: translateX(-162px); }
}
@keyframes bp-themes-pill-active {
  0%, 47%   { background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.65); border-color: rgba(255,255,255,0.10); }
  48%, 100% { background: var(--crimson); color: #fff; border-color: var(--crimson); }
}
/* Cover + title swap step-end at 48% — instant change at the tap moment,
   no fade. The animation timing-function below is also step-end so the
   keyframes snap rather than interpolate. */
@keyframes bp-themes-cover-from {
  0%, 47%   { opacity: 1; }
  48%, 100% { opacity: 0; }
}
@keyframes bp-themes-cover-to {
  0%, 47%   { opacity: 0; }
  48%, 100% { opacity: 1; }
}
@keyframes bp-themes-title-from {
  0%, 47%   { opacity: 1; }
  48%, 100% { opacity: 0; }
}
@keyframes bp-themes-title-to {
  0%, 47%   { opacity: 0; }
  48%, 100% { opacity: 1; }
}
@keyframes bp-themes-finger {
  0%, 42%   { opacity: 0; top: 100%; left: 50%; transform: translate(-50%, 0) scale(1); }
  /* Target pill ("Adventure") settled dead-centre after the flick,
     so finger lands at left:50%. Pills row sits ~82% from screen top. */
  44%       { opacity: 1; top: 82%; left: 50%; transform: translate(-50%, 0) scale(1); }
  46%       { opacity: 1; top: 82%; left: 50%; transform: translate(-50%, 0) scale(0.7); }
  48%       { opacity: 1; top: 82%; left: 50%; transform: translate(-50%, 0) scale(1); }
  52%, 100% { opacity: 0; }
}

.bp-feature-panel--themes .bp-phone__cover--theme-from   { animation: bp-themes-cover-from 12s infinite step-end; }
.bp-feature-panel--themes .bp-phone__cover--theme-to     { animation: bp-themes-cover-to 12s infinite step-end; }
.bp-feature-panel--themes .bp-phone__title--theme-from   { animation: bp-themes-title-from 12s infinite step-end; }
.bp-feature-panel--themes .bp-phone__title--theme-to     { animation: bp-themes-title-to 12s infinite step-end; }
.bp-feature-panel--themes .bp-phone__theme-pills         { animation: bp-themes-pills-scroll 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--themes .bp-phone__theme-pill--target  { animation: bp-themes-pill-active 12s infinite step-end; }
.bp-feature-panel--themes .bp-phone__finger--themes      { animation: bp-themes-finger 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }

/* ============================================================
   Panel: Bluetooth — connect picker modal slides up, finger
   taps Headphones, row pulses crimson with check.
   ============================================================ */
.bp-phone__bt-btn {
  margin-top: 6px;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 11px;
  border: 1.5px solid rgba(255, 255, 255, 0.4);
  border-radius: 999px;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  flex-wrap: nowrap;
}
.bp-phone__bt-btn svg { width: 11px; height: 11px; }
.bp-phone__modal--bt {
  padding: 10px 12px 14px;
}
.bp-phone__bt-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  margin-bottom: 4px;
  background: #2A2A2A;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  font-size: 10px;
  font-weight: 500;
  border-radius: 8px;
}
.bp-phone__bt-row svg:first-child { width: 14px; height: 14px; flex-shrink: 0; }
.bp-phone__bt-row span { flex: 1; }
.bp-phone__bt-check { width: 12px; height: 12px; color: #fff; opacity: 0; flex-shrink: 0; }

@keyframes bp-bt-modal     { 0%, 18% { transform: translateY(100%) } 24%, 70% { transform: translateY(0) } 82%, 100% { transform: translateY(100%) } }
@keyframes bp-bt-target-bg { 0%, 44% { background: #2A2A2A } 48%, 70% { background: var(--crimson) } 74%, 100% { background: #2A2A2A } }
@keyframes bp-bt-check     { 0%, 46% { opacity: 0 } 52%, 70% { opacity: 1 } 74%, 100% { opacity: 0 } }
@keyframes bp-bt-finger    { 0%, 5% { opacity: 0; top: 100% } 10% { opacity: 1; top: 76%; left: 50%; transform: translate(-50%, 0) } 13% { opacity: 1; transform: translate(-50%, 0) scale(0.7) } 16% { opacity: 1; transform: translate(-50%, 0) scale(1) } 20%, 38% { opacity: 0 } 44% { opacity: 1; top: 60%; left: 50%; transform: translate(-50%, 0) scale(1) } 47% { opacity: 1; transform: translate(-50%, 0) scale(0.7) } 49% { opacity: 1; transform: translate(-50%, 0) scale(1) } 52%, 100% { opacity: 0 } }

.bp-feature-panel--bluetooth .bp-phone__modal--bt   { animation: bp-bt-modal 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }
.bp-feature-panel--bluetooth .bp-phone__bt-row--target { animation: bp-bt-target-bg 12s infinite step-end; }
.bp-feature-panel--bluetooth .bp-phone__bt-check    { animation: bp-bt-check 12s infinite step-end; }
.bp-feature-panel--bluetooth .bp-phone__finger--bt  { animation: bp-bt-finger 12s infinite cubic-bezier(0.4, 0, 0.2, 1); }

/* ============================================================
   Panel: Roadmap / Coming soon — different visual language to the
   phone-mockup panels. Dashed border (blueprint feel), live "in
   development" pill at top, list of three upcoming integrations
   each with a faint pulsing dot to imply active progress.
   ============================================================ */
.bp-feature-panel--roadmap .bp-feature-panel__bg {
  background: linear-gradient(160deg, #FFFFFF 0%, #FBF6EC 100%);
}
.bp-roadmap__pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 12px;
  background: rgba(255, 14, 77, 0.08);
  border: 1px solid rgba(255, 14, 77, 0.30);
  color: var(--crimson);
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  margin-bottom: 14px;
}
.bp-roadmap__pill-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--crimson);
  position: relative;
}
.bp-roadmap__pill-dot::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: var(--crimson);
  animation: bp-new-badge-pulse 1.6s infinite ease-in-out;
}

.bp-roadmap__list {
  list-style: none;
  margin: 18px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bp-roadmap__item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 16px;
  background: #FFFFFF;
  border: 1px solid rgba(26, 26, 26, 0.08);
  border-radius: 14px;
  text-align: left;
}
/* App-tile icons — all the same size + corner radius so they read as
   a uniform set, regardless of whether the source asset is an SVG
   logo, a webp app icon, or a square PNG. */
.bp-roadmap__tile {
  width: 48px;
  height: 48px;
  border-radius: 11px;
  flex-shrink: 0;
  object-fit: cover;
  background: #fff;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,0.06), 0 2px 4px rgba(0,0,0,0.08);
}
/* CarPlay SVG already has its own green gradient + white logo —
   render the file directly via the shared <img> tile rule. */

.bp-roadmap__body { flex: 1; min-width: 0; }
.bp-roadmap__name {
  font-family: 'Poppins', sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: var(--ink);
  line-height: 1.2;
}
.bp-roadmap__sub {
  font-family: 'Source Serif 4', Georgia, serif;
  font-style: italic;
  font-size: 12px;
  color: var(--ink-soft);
  margin-top: 2px;
}
.bp-roadmap__chip {
  flex-shrink: 0;
  padding: 4px 10px;
  background: rgba(255, 14, 77, 0.08);
  color: var(--crimson);
  border: 1px solid rgba(255, 14, 77, 0.25);
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.10em;
  text-transform: uppercase;
}

/* Stagger a slight fade-in on each row when the panel becomes active
   in the carousel — implies things being built one after another. */
@keyframes bp-roadmap-row-in {
  0%   { transform: translateY(8px); opacity: 0.4; }
  100% { transform: translateY(0); opacity: 1; }
}
.bp-feature-panel--roadmap.is-active .bp-roadmap__item {
  animation: bp-roadmap-row-in 0.5s ease-out both;
}
.bp-feature-panel--roadmap.is-active .bp-roadmap__item:nth-child(2) { animation-delay: 0.1s; }
.bp-feature-panel--roadmap.is-active .bp-roadmap__item:nth-child(3) { animation-delay: 0.2s; }

/* ============================================================
   Panel: New stories — iOS-style push notification slides in
   from the top of the phone, sits, then slides back up. Plus a
   small "New release" pill on the cover for context.
   ============================================================ */
.bp-phone__new-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  background: rgba(255, 14, 77, 0.12);
  color: var(--crimson);
  border: 1px solid rgba(255, 14, 77, 0.35);
  border-radius: 999px;
  font-family: 'Poppins', sans-serif;
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.04em;
  margin-top: 2px;
}
.bp-phone__new-badge-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--crimson);
  position: relative;
}
.bp-phone__new-badge-dot::after {
  content: '';
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: var(--crimson);
}
/* One-way radiate: ring starts small + visible at 0%, grows outward
   while fading, ends invisible. Loop restarts from small — the jump
   happens at opacity 0 so you don't see a contraction. */
@keyframes bp-new-badge-pulse {
  0%   { transform: scale(0.8); opacity: 0.7; }
  100% { transform: scale(2.6); opacity: 0; }
}

.bp-phone__notif {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  background: rgba(40, 40, 42, 0.92);
  -webkit-backdrop-filter: blur(20px);
          backdrop-filter: blur(20px);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  padding: 8px 9px;
  display: flex;
  align-items: center;
  gap: 8px;
  color: #fff;
  font-family: 'Poppins', sans-serif;
  z-index: 10;
  transform: translateY(-180%);
  opacity: 0;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.4);
}
.bp-phone__notif-icon {
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--crimson);
  display: grid;
  place-items: center;
  flex-shrink: 0;
}
.bp-phone__notif-icon svg {
  width: 14px;
  height: 14px;
  color: #fff;
}
.bp-phone__notif-body { flex: 1; min-width: 0; line-height: 1.2; }
.bp-phone__notif-title {
  font-size: 9px;
  font-weight: 600;
  letter-spacing: 0.02em;
}
.bp-phone__notif-text {
  font-size: 9px;
  font-weight: 400;
  opacity: 0.85;
  margin-top: 1px;
}
.bp-phone__notif-time {
  font-size: 8px;
  opacity: 0.5;
  flex-shrink: 0;
  align-self: flex-start;
  margin-top: 2px;
}

@keyframes bp-notif-in {
  0%   { transform: translateY(-180%); opacity: 0; }
  8%   { transform: translateY(4px);   opacity: 1; }
  12%  { transform: translateY(-2px);  opacity: 1; }   /* tiny settle bounce */
  16%  { transform: translateY(0);     opacity: 1; }
  72%  { transform: translateY(0);     opacity: 1; }
  82%  { transform: translateY(-180%); opacity: 0; }
  100% { transform: translateY(-180%); opacity: 0; }
}
@keyframes bp-new-badge-in {
  0%, 8%   { opacity: 0; transform: scale(0.8); }
  16%      { opacity: 1; transform: scale(1.05); }
  20%, 80% { opacity: 1; transform: scale(1); }
  88%, 100% { opacity: 0; transform: scale(0.8); }
}
.bp-feature-panel--new-stories .bp-phone__notif         { animation: bp-notif-in 10s infinite cubic-bezier(0.4, 0, 0.2, 1); }
/* Badge stays on screen — only the dot's outer ring pulses gently. */
.bp-feature-panel--new-stories .bp-phone__new-badge-dot::after { animation: bp-new-badge-pulse 2s infinite ease-in-out; }
