/* ============================================================================
   redesign-motion.css  —  MOTION & EXPERIENCE LAYER
   Claire Organics "Botanical Apothecary" redesign. Loads LAST among the
   redesign stylesheets so it owns the site's motion vocabulary. Pairs with
   redesign-motion.js, which adds `rd-motion` to <html>, commits the hidden
   pre-state, then adds `.rd-armed` (the transition) and `.is-in` (the reveal),
   and sets `rd-scrolled` on <html> while the page is scrolled.

   Principles
     · Motion is OPT-IN via JS: every "hidden until revealed" state is gated
       behind `html.rd-motion` AND `prefers-reduced-motion: no-preference`. If
       JS is absent/fails, or the visitor prefers reduced motion, nothing is
       hidden — the page renders fully static. Progressive enhancement only.
     · Calm, unhurried, botanical: one-shot eased reveals (fade + gentle rise).
       No scroll-scrubbing, no replay-on-scroll-up.
     · The pre-hidden state carries NO transition — it is committed instantly by
       JS, then `.rd-armed` supplies the transition one frame later. This means
       the reveal only ever animates 0→1 (no visible fade-OUT of content that
       already painted before the script ran).
     · GPU-friendly: only opacity + transform animate. No standing `will-change`.
   ========================================================================== */

:root {
  /* slow "settle" ease used by the reveal + hero systems */
  --rd-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
}


/* ==========================================================================
   1. SCROLL-REVEAL SYSTEM  (.rd-io → .rd-io.rd-armed → .rd-io.is-in)
   JS tags eligible elements with `.rd-io` (opacity:0, NO transition → snaps
   hidden with no flash), flushes, then on the next frame adds `.rd-armed`
   (the transition) before observing. `.is-in` is added when the element scrolls
   into view (IntersectionObserver, observed once) or already sits in the first
   viewport. A `--rd-io-delay` staggers grouped items.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  html.rd-motion .rd-io {
    opacity: 0;
    transform: translateY(22px);
  }

  /* Media-led tiles/cards travel less and ease a hair longer — heavier objects
     should feel like they "settle" rather than dart in. */
  html.rd-motion .rd-io.rd-io--media {
    transform: translateY(16px) scale(0.992);
    transform-origin: center 60%;
  }

  /* Transition is armed one frame after the hidden state is committed. */
  html.rd-motion .rd-io.rd-armed {
    transition:
      opacity 0.85s var(--rd-ease-out),
      transform 0.85s var(--rd-ease-out);
    transition-delay: var(--rd-io-delay, 0ms);
  }
  html.rd-motion .rd-io.rd-io--media.rd-armed {
    transition-duration: 0.95s;
  }

  /* Keyboard/AT escape hatch: a not-yet-revealed region that receives focus
     (or contains the focused element) un-hides instantly — content is never
     left invisible under a focus ring. */
  html.rd-motion .rd-io:focus-within {
    opacity: 1 !important;
    transform: none !important;
    transition: none;
  }

  html.rd-motion .rd-io.is-in {
    opacity: 1;
    transform: none;
  }
}


/* ==========================================================================
   2. HERO LOAD-IN  (first impression)
   The home hero is a baked promo slider (flexslider) with no text overlay, so
   the load-in is a single calm media fade + rise on the OUTER wrapper only —
   never on the flexslider track/slides/img, whose opacity & transform are owned
   by flexslider. Driven by `.rd-hero--in`, added by JS on the frame after
   `rd-motion` so the pre-hidden state paints for one frame first.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  html.rd-motion .home-top-slider {
    opacity: 0;
    transform: translateY(14px);
  }
  html.rd-motion .home-top-slider.rd-hero--in {
    animation: rd-hero-in 1.1s var(--rd-ease-out) forwards;
  }
}
@keyframes rd-hero-in {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}


/* ==========================================================================
   3. SECTION-HEAD FLOURISHES  (micro)
   The clay hairline under editorial section heads draws in from the centre as
   a deliberate AFTER-stroke — its delay (0.4s) lets the head finish its rise
   (which ends ~0.85s) before the line completes (~1.1s). Pre-collapsed only
   while motion is armed; static (full width) otherwise.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  html.rd-motion .rd-section-head .rd-flourish {
    transform: scaleX(0);
    transform-origin: center;
    transition: transform 0.7s var(--rd-ease-out) 0.4s;
  }
  html.rd-motion .rd-section-head.is-in .rd-flourish {
    transform: scaleX(1);
  }

  /* The featured-products heading carries its clay rule as ::after */
  html.rd-motion .featured-product-wrapper > .section-header__title::after {
    transform: scaleX(0);
    transform-origin: center;
    transition: transform 0.7s var(--rd-ease-out) 0.4s;
  }
  html.rd-motion .featured-product-wrapper > .section-header__title.is-in::after {
    transform: scaleX(1);
  }
}


/* ==========================================================================
   4. BUTTON TACTILITY  (micro)
   A gentle lift on hover and a real "press" on active for PROMOTIONAL / primary
   buttons — the physicality premium CTAs have. Utility controls (cart-drawer
   checkout, cart quantity steppers, search submit, newsletter submit) keep the
   colour/shadow feedback but must NOT jump — a 2px hop on a +/- stepper or a
   submit flush against an input reads as fidgety. Reduced-motion users keep the
   existing colour/shadow transition only.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .btn,
  input[type="submit"].btn,
  button.btn {
    transition:
      background-color var(--rd-dur) var(--rd-ease),
      color var(--rd-dur) var(--rd-ease),
      border-color var(--rd-dur) var(--rd-ease),
      transform 0.28s var(--rd-ease),
      box-shadow 0.3s var(--rd-ease);
  }
  .btn:hover,
  input[type="submit"].btn:hover,
  button.btn:hover {
    transform: translateY(-2px);
  }
  /* The press-down is good everywhere. */
  .btn:active,
  input[type="submit"].btn:active,
  button.btn:active {
    transform: translateY(0);
    transition-duration: 0.09s;
  }

  /* Neutralise the hover lift on utility surfaces. */
  #subscribe,
  #subscribe:hover,
  #subscribe:active,
  .input-group .btn:hover,
  .input-group .btn:active,
  .input-group-btn.btn:hover,
  .btn-qty-adjust:hover,
  .cart-drawer .btn:hover,
  .rd-search-overlay__submit:hover {
    transform: none;
  }

  /* The product-card quick-add button is centred with `left:50%` +
     `translate(-50%,0)`, so the plain `translateY(-2px)` lift above would drop
     the -50% correction and shunt it half its own width to the right on hover.
     Re-apply the centring in every state that sets a transform. */
  .product_grid-item .float-btn.btn:hover,
  .product_grid-item .float-btn.btn:focus {
    transform: translate(-50%, -2px);
  }
  .product_grid-item .float-btn.btn:active {
    transform: translate(-50%, 0);
  }

  /* A disabled / sold-out button must not lift — the motion reads as "clickable"
     and undoes the grey-out. Centred quick-add keeps its -50% while staying put. */
  .btn[disabled]:hover,
  .btn.disabled:hover,
  #AddToCart.disabled:hover,
  #MobileAddToCart.disabled:hover {
    transform: none;
  }
  .product_grid-item .float-btn.btn.disabled:hover,
  .product_grid-item .float-btn.btn[disabled]:hover {
    transform: translate(-50%, 0);
  }
}


/* ==========================================================================
   5. PRODUCT-CARD LIFT  (micro — home featured + collection grids)
   The whole card rises on hover; the rounded image tile owns the single,
   correctly-shaped shadow (redesign-collection.css). We deliberately do NOT add
   a second shadow to the wrapper — its box is un-rounded and spans the text, so
   a wrapper shadow would cast a square halo behind the title/price. The inner
   .grid-link lifts, leaving the OUTER .product_grid-item free for the
   scroll-reveal transform (no conflict). Image zoom / secondary-image crossfade
   ride on top.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .product_grid-item .grid-link {
    transition: transform var(--rd-dur) var(--rd-ease);
  }
  .product_grid-item:hover .grid-link {
    transform: translateY(-5px);
  }
}


/* ==========================================================================
   6. SMALL DELIGHTS  (micro)
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  /* Brand-values icons rise a touch on hover. */
  .rd-value__icon svg,
  .rd-value__icon img { transition: transform 0.35s var(--rd-ease), color 0.35s var(--rd-ease); }
  .rd-value:hover .rd-value__icon svg,
  .rd-value:hover .rd-value__icon img { transform: translateY(-2px) scale(1.08); }

  /* Footer social chips & quick links get a quiet nudge. */
  .rd-footer-follow .social-links a,
  .site-footer .social-links a { transition: transform 0.3s var(--rd-ease), color 0.3s var(--rd-ease); }
  .rd-footer-follow .social-links a:hover { transform: translateY(-3px); }

  /* Scroll-to-top arrow lifts on hover. */
  #scrollTopButton { transition: transform 0.3s var(--rd-ease), opacity 0.3s var(--rd-ease); }
  #scrollTopButton:hover { transform: translateY(-3px); }
}


/* ==========================================================================
   7. STICKY HEADER — GROUNDED STATE  (micro)
   redesign-motion.js sets `html.rd-scrolled` once the page is scrolled past the
   announcement bar. The stuck header then earns a soft shadow and tightens its
   vertical padding a touch, so it reads as a focused, floating bar. The theme's
   own `.on-stick-top` toggle does not fire in this build, so we drive our own
   collision-free class.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
  .header-bar.sticky-topbar {
    transition: box-shadow 0.4s var(--rd-ease), background-color 0.4s var(--rd-ease);
  }
  .header-bar.sticky-topbar .header-wrapper {
    transition: padding-top 0.4s var(--rd-ease), padding-bottom 0.4s var(--rd-ease);
  }
  html.rd-scrolled .header-bar.sticky-topbar {
    box-shadow: 0 8px 28px -20px rgba(44, 52, 42, 0.55);
  }
  html.rd-scrolled .template-index .header-bar.sticky-topbar .header-wrapper {
    padding-top: 10px;
    padding-bottom: 10px;
  }
  /* The wordmark eases down with the bar. */
  .site-header__logo,
  .site-header__logo img { transition: transform 0.4s var(--rd-ease), opacity var(--rd-dur) var(--rd-ease); }
  html.rd-scrolled .site-header__logo img { transform: scale(0.94); }
}


/* ==========================================================================
   8. REDUCED-MOTION SAFETY NET
   The gates above already exclude reduced-motion, but assert hard-off here in
   case any future rule forgets the gate: never hide content, never move it.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html.rd-motion .rd-io,
  html.rd-motion .home-top-slider,
  html.rd-motion .rd-section-head .rd-flourish,
  html.rd-motion .featured-product-wrapper > .section-header__title::after {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }
}
