/*
 * Motion: the storefront's named animations, M1–M14 (M9 was removed).
 *
 * Each animation is switched on per brand under "motion" in
 * config/brand/{slug}/brand.json, and the theme adds a body class for each one
 * that is on (motion-{key}, for example motion-strength-slide). Every rule
 * below sits under its own class, so an animation that is off has no effect,
 * and the admin-only Motion panel can switch one live by toggling its class.
 *
 * Each block is self-contained and labelled with its id and config key, so
 * any one can be deleted cleanly, together with the matching block in
 * assets/js/motion.js where one exists. The one-shot effects that follow a
 * change of value (M3's slide, M4, M5, M8, M11, M12) run in motion.js on the
 * Web Animations API and need no rules here beyond what they rest on.
 *
 * Plan rule: 150–200 ms, opacity and transform only. The owner accepted two
 * exceptions: the line draws (M6, M14) run 600 ms so they can be seen, and the
 * strength slide (M3) fades the label text colour with the fill. Nothing here
 * animates layout, and will-change is set only while a line draws. Hover and
 * press effects (M1, M13) apply to a mouse only, never to touch, where hover
 * and press states stick. Everything sits inside prefers-reduced-motion:
 * no-preference, so a visitor who asks for reduced motion sees none of it,
 * whatever the flags say.
 */

/* stylelint-disable no-descending-specificity */

/* Timing tokens only; they draw nothing. motion.js reads them too. */
:root {
  --motion-duration: var(--duration);
  --motion-ease: var(--ease);
  --motion-rise: 4px;

  /* Only M6 and M14, the line draws: long and even enough to be seen. */
  --motion-draw: 600ms;
  --motion-draw-ease: cubic-bezier(0.4, 0, 0.2, 1);
}

@media (prefers-reduced-motion: no-preference) {
  /* Shared keyframes. They run only where a block below names them. */
  @keyframes motion-fade {
    from {
      opacity: 0;
    }
  }

  @keyframes motion-rise {
    from {
      opacity: 0;
      transform: translateY(var(--motion-rise));
    }
  }

  /* ---------- M1 nav_hover: nav hover line draws from the left ---------- */

  /* The hover rule already fades in; with a mouse it now also draws out from
     the left edge, where the copper tick sits on the active link. */
  @media (hover: hover) and (pointer: fine) {
    .motion-nav-hover .site-nav a::after {
      transform: scaleX(0);
      transform-origin: left center;
      transition:
        opacity var(--motion-duration) var(--motion-ease),
        transform var(--motion-duration) var(--motion-ease);
    }

    .motion-nav-hover .site-nav a:hover::after,
    .motion-nav-hover .site-nav a[aria-current]::after {
      transform: none;
    }
  }

  /* ---------- M2 mobile_menu: mobile menu panel fades in, links settle ---------- */

  @media (width <= 899px) {
    .motion-mobile-menu .site-header[data-open] .site-nav {
      animation: motion-fade var(--motion-duration) var(--motion-ease);
    }

    .motion-mobile-menu .site-header[data-open] .site-nav > * {
      animation: motion-rise 200ms var(--motion-ease) both;
    }
  }

  /* ---------- M3 strength_slide: strength selector, selection slides ---------- */

  /* motion.js adds .has-thumb and one .seg-thumb span to the product page's
     strength control while this is on, and slides the span under the checked
     strength. The span takes over the checked label's fill; without it the
     label keeps its own fill, as before. The label text colour follows the
     fill over the same time. The fill is the feedback for a tap, so the
     system's grey tap flash is left off these labels. */
  .motion-strength-slide .strength .segmented.has-thumb {
    position: relative;
  }

  .motion-strength-slide .seg-thumb {
    position: absolute;
    top: 0;
    left: 0;
    border-radius: var(--radius-data);
    background: var(--color-structure);
    transform-origin: left top;
    pointer-events: none;
  }

  .motion-strength-slide .strength .segmented.has-thumb label {
    position: relative;
    -webkit-tap-highlight-color: transparent;
    transition:
      background-color var(--motion-duration) var(--motion-ease),
      color var(--motion-duration) var(--motion-ease);
  }

  .motion-strength-slide .strength .segmented.has-thumb input:checked + label {
    background: transparent;
  }

  /* ---------- M4 price_change: price and stock come up from faint when the strength changes ---------- */

  /* Opacity only, in motion.js: the value never moves, so it cannot read as
     going up and down. */

  /* ---------- M5 gallery_fade: gallery image comes up from faint ---------- */

  /* In motion.js. */

  /* ---------- M6 name_line_draw: product-name datum line draws once on screen (600 ms) ---------- */

  /* Past the 150–200 ms rule; accepted by the owner behind this flag. The tick
     is there from the start; the line draws out of it once it is comfortably
     on screen, the age gate is closed, and the fonts are in. A short script at
     the top of <body> holds the line at its start from the first paint
     (.motion-lines-held on <html>); motion.js then holds, draws, or leaves it
     per element (data-motion-line). With JavaScript off, or if motion.js never
     runs, the line shows drawn. */
  .motion-name-line-draw.has-motif .name-datum {
    background: none;
  }

  .motion-name-line-draw.has-motif .name-datum::after {
    content: "";
    position: absolute;
    right: 0;
    top: calc((var(--tick-height) - var(--datum-weight)) / 2);
    width: calc(100% - var(--tick-width) - 8px);
    height: var(--datum-weight);
    background: var(--color-structure);
    transform-origin: left center;
  }

  .motion-lines-held .motion-name-line-draw.has-motif .name-datum:not([data-motion-line])::after,
  .motion-name-line-draw.has-motif .name-datum[data-motion-line="held"]::after {
    transform: scaleX(0);
  }

  .motion-name-line-draw.has-motif .name-datum[data-motion-line="drawing"]::after {
    transition: transform var(--motion-draw) var(--motion-draw-ease);
    will-change: transform;
  }

  /* ---------- M7 notices: added to cart, the notice slides in and the cart count rolls ---------- */

  .motion-notices .woocommerce-message,
  .motion-notices .woocommerce-info,
  .motion-notices .woocommerce-error,
  .motion-notices .wc-block-components-notice-banner {
    animation: motion-rise 200ms var(--motion-ease);
  }

  .motion-notices .cart-count {
    overflow: hidden;
  }

  .motion-notices .cart-count > [aria-hidden] {
    display: inline-block;
  }

  .motion-notices:has(.woocommerce-message) .cart-count > [aria-hidden] {
    animation: motion-count 200ms var(--motion-ease) 120ms both;
  }

  @keyframes motion-count {
    from {
      opacity: 0;
      transform: translateY(100%);
    }
  }

  /* ---------- M8 cart_totals: cart and checkout amounts refresh softly ---------- */

  /* In motion.js, which only reads the blocks' elements and animates them
     with the Web Animations API: no class or attribute is ever written to an
     element the cart or checkout block renders. */

  /* ---------- M10 faq_open: a question's answer slides in when opened ---------- */

  .motion-faq-open .wp-block-details[open] > :not(summary) {
    animation: motion-rise 200ms var(--motion-ease);
  }

  /* ---------- M11 coa_viewer: the COA document rises into the viewer ---------- */

  /* The PDF frame is a fixed-size sheet, so it rises as the viewer opens. The
     page image rises in motion.js, once it can be drawn. */
  .motion-coa-viewer .coa-viewer[open] .coa-frame {
    animation: motion-document 200ms var(--motion-ease) 60ms both;
  }

  @keyframes motion-document {
    from {
      opacity: 0;
      transform: translateY(8px);
    }
  }

  /* ---------- M12 shop_cards: shop filter, cards that come back fade in ---------- */

  /* In motion.js. */

  /* ---------- M13 button_press: buttons press down 1 px ---------- */

  /* 150 ms, the quick end of the plan's range, so the press still feels
     immediate. A mouse only: on touch a press state flashes while scrolling
     and can stick. */
  @media (hover: hover) and (pointer: fine) {
    .motion-button-press .button,
    .motion-button-press .wc-block-components-button:not(.is-link) {
      transition:
        background-color var(--motion-duration) var(--motion-ease),
        transform 150ms var(--motion-ease);
    }

    .motion-button-press .button:active:not(:disabled),
    .motion-button-press .wc-block-components-button:not(.is-link, .is-disabled):active {
      transform: translateY(1px);
    }
  }

  /* ---------- M14 section_lines: section datum draws once on screen (600 ms) ---------- */

  /* Past the 150–200 ms rule, and a scroll effect on content sections;
     accepted by the owner behind this flag. motion.js holds only sections
     still below the fold (data-motion-line="held"), so nothing on screen ever
     disappears, and draws each once it is comfortably on screen with the age
     gate closed. */
  .motion-section-lines.has-motif .page-section[data-motion-line]::before {
    transform-origin: left center;
  }

  .motion-section-lines.has-motif .page-section[data-motion-line="held"]::before {
    transform: scaleX(0);
  }

  .motion-section-lines.has-motif .page-section[data-motion-line="held"]::after {
    opacity: 0;
  }

  .motion-section-lines.has-motif .page-section[data-motion-line="drawing"]::before {
    transition: transform var(--motion-draw) var(--motion-draw-ease);
    will-change: transform;
  }

  .motion-section-lines.has-motif .page-section[data-motion-line="drawing"]::after {
    transition: opacity var(--motion-duration) var(--motion-ease);
  }
}
