/* pp-motion.css — motion/interaction layer for Preppin Peppers (Vessel 4.1.1)
   Added 2026-07-12. Additive only: no layout, colour, type or copy changes.
   Principles: feedback on pointer-down; short ease-out for state changes;
   no bounce on non-gesture UI; never clobber the theme's own transitions
   (we extend transition-property lists rather than using the shorthand);
   everything is disabled under prefers-reduced-motion (bottom of file). */

:root {
  /* strong ease-out — the built-in CSS easings are too weak to read as intentional */
  --pp-ease-out: cubic-bezier(0.23, 1, 0.32, 1);
  --pp-press: 140ms;
}

/* ---------------------------------------------------------------------------
   1. BUTTONS — press feedback lands on pointer-down (:active), not on release.
   base.css already sets `transition: color, box-shadow, background-color` on
   .button, so we re-declare the longhand list with `scale` appended instead of
   using the `transition` shorthand (which would delete the theme's transitions).
   We animate `scale`, not `transform`, so we never collide with any transform
   the theme applies (card lift, pill slide, etc).
   --------------------------------------------------------------------------- */
.button,
.button-secondary,
.button-custom,
button.shopify-payment-button__button--unbranded {
  transition-property: color, box-shadow, background-color, scale;
  transition-duration: var(--animation-speed, 0.125s), var(--animation-speed, 0.125s),
    var(--animation-speed, 0.125s), var(--pp-press);
  transition-timing-function: var(--animation-easing, ease-in-out), var(--animation-easing, ease-in-out),
    var(--animation-easing, ease-in-out), var(--pp-ease-out);
}

.button:active:not([disabled], [aria-disabled='true'], .quantity-plus, .quantity-minus),
.button-secondary:active:not([disabled], [aria-disabled='true']),
.button-custom:active:not([disabled], [aria-disabled='true']),
button.shopify-payment-button__button--unbranded:active:not([disabled]) {
  scale: 0.97;
}

/* Store's own (non-theme) buttons, defined in pp.css. Same rule: extend, never replace. */
.btn {
  transition-property: transform, background, scale;
  transition-duration: 0.15s, 0.2s, var(--pp-press);
  transition-timing-function: ease, ease, var(--pp-ease-out);
}

.pp-fbt-add,
.pp-consent-accept,
.pp-consent-decline,
.pp-agegate-enter,
.pp-agegate-leave,
.navbuy,
.pp-burger {
  transition-property: scale, opacity;
  transition-duration: var(--pp-press), var(--pp-press);
  transition-timing-function: var(--pp-ease-out), var(--pp-ease-out);
}

.btn:active,
.pp-fbt-add:active,
.pp-consent-accept:active,
.pp-consent-decline:active,
.pp-agegate-enter:active,
.pp-agegate-leave:active,
.navbuy:active,
.pp-burger:active {
  scale: 0.97;
}

/* Bundle / quantity cards on the landing page are large — a smaller press. */
.bundle {
  transition-property: border-color, box-shadow, scale;
  transition-duration: 0.15s, 0.15s, var(--pp-press);
  transition-timing-function: ease, ease, var(--pp-ease-out);
}

.bundle:active {
  scale: 0.985;
}

/* ---------------------------------------------------------------------------
   2. VARIANT SWATCHES / OPTION BUTTONS
   The theme already transitions background/border/colour (0.125s) and slides the
   selected pill. What is missing is press feedback. We append `scale` to the
   existing property list and keep the theme's own durations/easings byte-for-byte.
   --------------------------------------------------------------------------- */
.variant-option__button-label {
  transition-property: background-color, border-color, color, scale;
  transition-duration: var(--animation-speed, 0.125s), var(--animation-speed, 0.125s),
    var(--animation-speed, 0.125s), var(--pp-press);
  transition-timing-function: var(--animation-easing, ease-in-out), var(--animation-easing, ease-in-out),
    var(--animation-easing, ease-in-out), var(--pp-ease-out);
}

.variant-option__button-label:active:not(:has([aria-disabled='true'])) {
  scale: 0.96;
}

/* Swatch chips get a slightly deeper press — they are smaller targets. */
.variant-option__button-label--has-swatch:active:not(:has([aria-disabled='true'])) {
  scale: 0.94;
}

/* ---------------------------------------------------------------------------
   3. PRODUCT GALLERY — variant image swap.
   media-gallery.js replaces the whole <media-gallery> node on variant select, so
   the image hard-cuts. pp-motion.js tags each replacement gallery with .pp-media-in;
   we dissolve it in (opacity + a 2px blur that masks the seam between two frames).
   Starts at 0.4 opacity, never from 0, so there is no flash of empty background.
   Only fires on replacement, never on first paint — first paint must stay instant.
   --------------------------------------------------------------------------- */
@keyframes pp-media-in {
  from {
    opacity: 0.4;
    filter: blur(2px);
  }
  to {
    opacity: 1;
    filter: blur(0);
  }
}

media-gallery.pp-media-in {
  animation: pp-media-in 240ms var(--pp-ease-out) both;
}

/* ---------------------------------------------------------------------------
   4. .pp-acc ACCORDIONS (in product body_html — cannot be styled at source).
   interpolate-size is scoped to .pp-acc (it inherits) rather than :root, so it
   cannot change how anything else in the theme interpolates to `auto`.
   Browsers without ::details-content simply keep today's instant open/close.
   --------------------------------------------------------------------------- */
.pp-acc {
  interpolate-size: allow-keywords;
}

.pp-acc > summary {
  cursor: pointer;
  transition: opacity 120ms var(--pp-ease-out);
}

.pp-acc > summary:active {
  opacity: 0.62;
}

.pp-acc::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size 260ms var(--pp-ease-out), content-visibility 260ms var(--pp-ease-out) allow-discrete;
}

.pp-acc[open]::details-content {
  block-size: auto;
}

/* ---------------------------------------------------------------------------
   5. LINKS & NAV — subtle, fast press states. pp.css already transitions
   nav link colour (0.2s); we append opacity rather than overwrite it.
   --------------------------------------------------------------------------- */
nav ul a,
.pp-nav-right a,
.logo {
  transition-property: color, opacity;
  transition-duration: 0.2s, 120ms;
  transition-timing-function: ease, var(--pp-ease-out);
}

nav ul a:active,
.pp-nav-right a:active,
.logo:active {
  opacity: 0.6;
}

/* ---------------------------------------------------------------------------
   6. REDUCED MOTION — turns off everything above.
   Deliberately scoped to the selectors this file introduces. We do NOT ship a
   blanket `*{transition:none!important}`: several theme components (drawers,
   dialogs, allow-discrete popovers) depend on transitionend firing, and killing
   every transition globally risks leaving them stuck open on a live store.
   The theme's own motion is already gated behind prefers-reduced-motion:
   no-preference, so it is off under `reduce` regardless.
   --------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .button,
  .button-secondary,
  .button-custom,
  button.shopify-payment-button__button--unbranded,
  .btn,
  .bundle,
  .pp-fbt-add,
  .pp-consent-accept,
  .pp-consent-decline,
  .pp-agegate-enter,
  .pp-agegate-leave,
  .navbuy,
  .pp-burger,
  .variant-option__button-label,
  .pp-acc > summary,
  nav ul a,
  .pp-nav-right a,
  .logo {
    transition: none;
  }

  /* Press feedback stays, it just arrives with no travel: no scale, no motion. */
  .button:active,
  .button-secondary:active,
  .button-custom:active,
  .btn:active,
  .bundle:active,
  .pp-fbt-add:active,
  .pp-consent-accept:active,
  .pp-consent-decline:active,
  .pp-agegate-enter:active,
  .pp-agegate-leave:active,
  .navbuy:active,
  .pp-burger:active,
  .variant-option__button-label:active,
  .variant-option__button-label--has-swatch:active {
    scale: 1;
  }

  media-gallery.pp-media-in {
    animation: none;
  }

  .pp-acc::details-content,
  .pp-acc[open]::details-content {
    block-size: auto;
    overflow: visible;
    transition: none;
  }
}
