/* ============================================================
   Also Coffee Co — motion layer
   ------------------------------------------------------------
   Loaded last, on every page.

   Additive only. Every rule here animates opacity / transform /
   box-shadow / font axes, or adds a hover-focus state. Nothing
   sets position, size, spacing, order or line-breaking, so the
   settled layout is identical to before this file existed.

   Two jobs:

   1. Take the scroll reveals off JavaScript. pdp.css and shop.css
      set opacity:0 on reveal children and rely on app.js's
      IntersectionObserver to put it back. With scripts blocked or
      erroring, /shop/ renders with all six products invisible and
      the product page loses 57 elements including every FAQ row.
      Where the browser supports scroll-driven animations the reveal
      now runs in CSS with no JS involved; where it doesn't, nothing
      is hidden in the first place.

   2. Small detail work: entry transitions for content that is
      injected after paint, a scroll-linked header shadow, and the
      Fraunces SOFT axis on hover.
   ============================================================ */


/* ------------------------------------------------------------
   1. Un-strand the reveals
   ------------------------------------------------------------
   Unconditional: content is visible by default, full stop. The
   hidden start state is reinstated below only inside the @supports
   block, where CSS alone is able to bring it back.
   Mirrors the selector lists in pdp.css (~L920) and shop.css (~L110)
   — keep in step if those change.
   ------------------------------------------------------------ */
.also-reveal .also-eyebrow,
.also-reveal > .also-container > h2,
.also-reveal .also-cc__intro,
.also-reveal .also-pdpbrew__head,
.also-reveal .also-pdprev__head,
.also-reveal .also-ugc__head,
.also-reveal .also-pdpship__head,
.also-reveal .also-pdpfaq__head,
.also-reveal .also-pdpdetail__story,
.also-reveal .also-cc__pick,
.also-reveal .also-brewcard,
.also-reveal .also-review,
.also-reveal .also-ugc__item,
.also-reveal .also-shipcard,
.also-reveal .also-cq__item,
.also-reveal .also-pdpfaq__item,
.also-reveal .also-pdpdetail__specs,
.also-reveal .also-pcard,
.also-reveal ul.products > li { opacity: 1; }


/* ------------------------------------------------------------
   1b. CSS-driven reveal
   ------------------------------------------------------------
   Each element carries its own view() timeline, so a row of cards
   resolves together and the next row follows as it arrives. That
   is the stagger — there are no delay chains to fall out of sync,
   and scrolling back up rewinds instead of leaving a half state.

   Scoped away from body.home. The front page runs bespoke motion on
   these same elements — the journey line, the stat counters, the
   moments grid, the range filter — all keyed to .is-in, and none of
   it is reimplemented here. Letting both drive one element would give
   it two competing animations, so the front page keeps the JS path
   whole and app.js makes the matching call from the other side.
   ------------------------------------------------------------ */
@keyframes also-rv      { from { opacity: 0; transform: translateY(14px) }
                          to   { opacity: 1; transform: none } }
@keyframes also-rv-card { from { opacity: 0; transform: translateY(18px) scale(.985) }
                          to   { opacity: 1; transform: none } }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {

    /* headings and intro copy — the block resolves as one */
    body:not(.home) .also-reveal .also-eyebrow,
    body:not(.home) .also-reveal > .also-container > h2,
    body:not(.home) .also-reveal .also-cc__intro,
    body:not(.home) .also-reveal .also-pdpbrew__head,
    body:not(.home) .also-reveal .also-pdprev__head,
    body:not(.home) .also-reveal .also-ugc__head,
    body:not(.home) .also-reveal .also-pdpship__head,
    body:not(.home) .also-reveal .also-pdpfaq__head,
    body:not(.home) .also-reveal .also-pdpdetail__story {
      animation: also-rv linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 55%;
    }

    /* rows of peers — cards, reviews, FAQ rows, product tiles */
    body:not(.home) .also-reveal .also-cc__pick,
    body:not(.home) .also-reveal .also-brewcard,
    body:not(.home) .also-reveal .also-review,
    body:not(.home) .also-reveal .also-ugc__item,
    body:not(.home) .also-reveal .also-shipcard,
    body:not(.home) .also-reveal .also-cq__item,
    body:not(.home) .also-reveal .also-pdpfaq__item,
    body:not(.home) .also-reveal .also-pdpdetail__specs,
    body:not(.home) .also-reveal .also-pcard,
    body:not(.home) .also-reveal ul.products > li {
      animation: also-rv-card linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }

    /* Set by app.js on whatever is already on screen at load. A view()
       timeline is honest about entry progress, so an element straddling the
       fold would otherwise paint mid-reveal. Only the animation is dropped —
       no !important on transform, which would kill the card hover lift. */
    .also-rv-now { animation: none !important }
  }
}


/* ------------------------------------------------------------
   2. Entry transitions for content injected after paint
   ------------------------------------------------------------
   Cart messages, coupon errors, the login reminder and the postcode
   results all currently appear in a single frame, which reads as the
   page jumping rather than answering. @starting-style gives them a
   from-state on first render. Vertical movement only — no width or
   height is animated, so nothing reflows around them.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: no-preference) {
  .woocommerce-message,
  .woocommerce-info,
  .woocommerce-error,
  .also-pc__list {
    transition: opacity var(--dur-base) var(--ease-out),
                transform var(--dur-base) var(--ease-out);
  }

  @starting-style {
    .woocommerce-message,
    .woocommerce-info,
    .woocommerce-error { opacity: 0; transform: translateY(-6px) }

    .also-pc__list { opacity: 0; transform: translateY(-4px) }
  }
}


/* ------------------------------------------------------------
   3. Header depth on scroll
   ------------------------------------------------------------
   The header is translucent with a 1px rule; against a pale section it stops
   reading as a separate layer once the page moves. Scroll-linked, so no JS and
   no scroll listener. Left outside the reduced-motion query deliberately — this
   is a depth cue, not movement, and it helps just as much when animation is
   turned down.

   Two reasons it is a gradient on a pseudo-element rather than an animated
   box-shadow on the header itself:

   - box-shadow cannot be composited, so animating it directly would run main
     thread work on every scroll frame. Lighthouse flags exactly that. Only the
     opacity of this layer animates, which the compositor handles alone.
   - .also-header already carries a permanent box-shadow below 560px
     (homepage.css ~L1336). Animating the property would have overridden it and
     made the existing mobile header shadow fade in from nothing.

   Absolutely positioned and pointer-events:none, so it paints without taking
   part in layout or intercepting clicks.
   ------------------------------------------------------------ */
.also-header::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 100%;
  height: 20px;
  pointer-events: none;
  opacity: 0;
  background: linear-gradient(to bottom, rgba(64, 33, 21, .13), rgba(64, 33, 21, 0));
}

@keyframes also-hdr-depth { from { opacity: 0 } to { opacity: 1 } }

@supports (animation-timeline: scroll()) {
  .also-header::after {
    animation: also-hdr-depth linear both;
    animation-timeline: scroll();
    animation-range: 0 140px;
  }
}


/* ------------------------------------------------------------
   4. Fraunces on hover
   ------------------------------------------------------------
   The full variable build is already downloaded and carries opsz,
   SOFT and WONK, but every use is static. Easing SOFT from its
   default 60 up to 100 lets a product name swell very slightly
   warmer under the cursor — the same gesture as the wordmark.
   Both ends declare all three axes, otherwise it steps instead of
   interpolating. Fine-pointer only, and never on touch.
   ------------------------------------------------------------ */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .also-pcard__name a,
  .also-pcard2__title {
    font-variation-settings: "opsz" var(--display-opsz), "SOFT" var(--display-soft), "WONK" var(--display-wonk);
    transition: font-variation-settings var(--dur-slow) var(--ease-out),
                color var(--dur-base) var(--ease-out);
  }

  .also-pcard:hover .also-pcard__name a,
  .also-pcard__name a:focus-visible,
  .also-pcard2:hover .also-pcard2__title {
    font-variation-settings: "opsz" var(--display-opsz), "SOFT" 100, "WONK" var(--display-wonk);
  }
}


/* ------------------------------------------------------------
   5. Reduced motion
   ------------------------------------------------------------
   The --dur tokens already collapse to 0ms, but a scroll-driven
   animation has no duration to collapse — it is driven by scroll
   position — so it has to be switched off by name.
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  /* Named selectors, not `.also-reveal *`. A wildcard here reaches past the
     reveal and flattens things that were never part of it: the rotations on
     the scattered photos and open accordion chevrons, and the hover-only
     layers (.also-pcard__img--alt, .also-pcard__peek) that sit at opacity 0
     on purpose — forcing those visible stacks both product images at once.
     Nothing sets transform either; the animations are already off, and the
     static rotations are design, not motion. */
  .also-reveal .also-eyebrow,
  .also-reveal > .also-container > h2,
  .also-reveal .also-cc__intro,
  .also-reveal .also-pdpbrew__head,
  .also-reveal .also-pdprev__head,
  .also-reveal .also-ugc__head,
  .also-reveal .also-pdpship__head,
  .also-reveal .also-pdpfaq__head,
  .also-reveal .also-pdpdetail__story,
  .also-reveal .also-cc__pick,
  .also-reveal .also-brewcard,
  .also-reveal .also-review,
  .also-reveal .also-ugc__item,
  .also-reveal .also-shipcard,
  .also-reveal .also-cq__item,
  .also-reveal .also-pdpfaq__item,
  .also-reveal .also-pdpdetail__specs,
  .also-reveal .also-pcard,
  .also-reveal ul.products > li {
    animation: none !important;
    opacity: 1 !important;
  }

  .also-reveal .also-pcard__img--alt,
  .also-reveal .also-pcard__peek { opacity: 0 !important }

  .also-reveal .also-pcard:hover .also-pcard__img--alt,
  .also-reveal .also-pcard:focus-within .also-pcard__img--alt,
  .also-reveal .also-pcard:hover .also-pcard__peek { opacity: 1 !important }
}

@media (prefers-reduced-motion: reduce) {
  .also-reveal .also-pdpdetail__mark { opacity: .07 !important }
}
