/* 2027 motion layer. Loaded after interaction.css.
   The restored seed-packet home stays the resting picture: colours, clip-path,
   type and shelf are untouched. This file only adds motion, depth and press feel.
   Every colour comes from the existing tokens. No shadows (depth is paper, ink and shift).
   Focal moment: the packet is a thing in the hand. It tilts toward the pointer,
   its printed layers separate as it scrolls away, and its button lifts into the press.
   Supporting motion only confirms a state change or an arrival.
   Travel lives in prefers-reduced-motion: no-preference. Hover lives in (hover: hover)
   and (pointer: fine). Horizontal movement uses --dir from garden.css. */

@property --zf-compact {
  syntax: "<number>";
  inherits: true;
  initial-value: 0;
}

/* The open menu must not keep the header's view-transition name, or the panel is
   trapped in that snapshot. Matches the garden page-rise check. */
.site-header:has(.site-menu[open]) { view-transition-name: none; }

/* Compact header on the home page only, so the builder stage and the cart summary
   keep the sticky offsets they already have. Sticky here is what makes the tighter
   bar visible after the first 40px. */
body.home .site-header {
  --zf-compact: 0;
  position: sticky;
  inset-block-start: 0;
  z-index: 30;
  background: var(--paper);
  padding-block-start: calc(clamp(.7rem, .35rem + 1.1vw, 1.1rem) * (1 - var(--zf-compact) * .45));
  border-block-end-color: color-mix(in oklch, var(--ink) calc(var(--zf-compact) * 100%), var(--line));
}
body.home .site-header.is-compact { --zf-compact: 1; }
body.home .site-header .brand {
  scale: calc(1 - var(--zf-compact) * .06);
  transform-origin: center;
}
html:has(body.home) { scroll-padding-block-start: clamp(4.75rem, 10vw, 8rem); }
body.home #main { scroll-margin-block-start: clamp(4.75rem, 10vw, 8rem); }

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    body.home .site-header {
      animation: zf-compact linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 40px;
    }
    @keyframes zf-compact {
      from { --zf-compact: 0; }
      to { --zf-compact: 1; }
    }
  }
}

/* Packet tilt must not widen the page. The clip stays on the hero, not the body. */
body.home .worlds { overflow-x: clip; }

@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    /* Shared scroll clock, seated at scroll 0 so the approved composition is the rest
       state. Layers only separate while the hero is scrolling away. */
    body.home .world {
      animation: zf-drift-packet linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    body.home .world .packet-hole {
      animation: zf-drift-hole linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    body.home .world > h2 {
      animation: zf-drift-label linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    body.home .world > img:not(.botanical-ornament) {
      animation: zf-drift-photo linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    html:not(.zf-arrive) body.home .world .botanical-ornament {
      animation: zf-drift-ornament linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    html:not(.zf-arrive) body.home .gift-tag {
      animation: zf-drift-tag linear both;
      animation-timeline: scroll(root);
      animation-range: 0px 32rem;
    }
    @keyframes zf-drift-packet { from { translate: 0 0; } to { translate: 0 -.35rem; } }
    @keyframes zf-drift-hole { from { translate: 0 0; } to { translate: 0 .2rem; } }
    @keyframes zf-drift-label { from { translate: 0 0; } to { translate: 0 -.7rem; } }
    @keyframes zf-drift-photo { from { translate: 0 0; } to { translate: 0 -1.35rem; } }
    @keyframes zf-drift-ornament { from { translate: 0 0; } to { translate: 0 -.45rem; } }
    @keyframes zf-drift-tag { from { translate: 0 0; } to { translate: 0 -1.85rem; } }
  }
}

/* Sections rise as they enter. Translate only — never opacity.
   animation-fill-mode:both + opacity:0 left .family-story/.business-links
   invisible below the fold (~500px empty gap on the homepage). Content must
   stay readable with JS/motion disabled or before the view() range starts. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    body.home :is(.date-picker, .collection .section-heading, .builder-promo, .family-story, .business-links) {
      animation: zf-section-in linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 24%;
    }
    @keyframes zf-section-in {
      from { translate: 0 .85rem; }
      to { translate: 0 0; }
    }

    /* Shelf cards rise, staggered. Labels stay at full opacity the whole way
       (same contrast rule as interaction.css). The delay is an entry-range offset:
       a time delay does not move a view() timeline. */
    body.home .home-shelf > .product-card:nth-child(1) { --zf-reveal-delay: 0; }
    body.home .home-shelf > .product-card:nth-child(2) { --zf-reveal-delay: 1; }
    body.home .home-shelf > .product-card:nth-child(3) { --zf-reveal-delay: 2; }
    body.home .home-shelf > .product-card:nth-child(n + 4) { --zf-reveal-delay: 3; }
    body.home .home-shelf > .product-card {
      animation: zf-shelf-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 30%;
    }
    body.home .home-shelf > .product-card {
      animation-range: entry calc(var(--zf-reveal-delay, 0) * 5%) entry calc(26% + var(--zf-reveal-delay, 0) * 5%);
    }
    @keyframes zf-shelf-rise {
      from { translate: 0 .75rem; }
      to { translate: 0 0; }
    }
  }
}

@media (prefers-reduced-motion: no-preference) {
  /* One variable eases the compact bar when scroll timelines are unavailable.
     Where scroll() runs, that animation owns --zf-compact and this does not fight it. */
  body.home .site-header { transition: --zf-compact 220ms var(--ease-out); }

  body.home .world > img:not(.botanical-ornament) { transition: scale 320ms var(--ease-out); }
  /* Keep the press scale on transform. is-magnet drops only the translate ease while the script springs the button. */
  body.home .world > .button { transition: translate 180ms var(--ease-out), transform 140ms var(--ease-out), opacity 140ms var(--ease-out); }
  body.home .world > .button.is-magnet { transition: transform 140ms var(--ease-out), opacity 140ms var(--ease-out); }

  .product-image img {
    transition: scale 240ms var(--ease-out), opacity 280ms var(--ease-out), translate 220ms var(--ease-out);
  }
  .product-card { transition: scale 140ms var(--ease-out), border-color 200ms var(--ease-out); }

  .date-choice { transition: scale 140ms var(--ease-out), background-color 160ms var(--ease-out); }
  .date-choice:active:not(:disabled, :focus-visible) { animation: zf-chip-pop 160ms var(--ease-out); }
  @keyframes zf-chip-pop {
    0% { scale: 1; }
    38% { scale: .94; }
    70% { scale: 1.05; }
    100% { scale: .96; }
  }

  .intent-options button {
    transition: background-color 180ms ease, border-color 180ms ease, scale 120ms var(--ease-out);
  }
  .intent-options button[aria-pressed="true"] {
    animation: zf-intent-pop 120ms var(--ease-out);
    @starting-style { background-color: var(--paper); border-color: var(--line); }
  }
  @keyframes zf-intent-pop {
    0% { scale: .96; }
    55% { scale: 1.05; }
    100% { scale: 1; }
  }
}

@media (prefers-reduced-motion: no-preference) and (hover: hover) and (pointer: fine) {
  body.home .world:hover > img:not(.botanical-ornament) { scale: 1.04; }
  body.home .world:hover > .button { translate: 0 -3px; }

  .product-card:hover { border-block-end-color: var(--ink); }
  .product-card:hover .product-image img { translate: 0 -4px; }

  /* Inline-end nudge. garden.css section 9 already does this; restated so the
     motion layer keeps the 4px shift with --dir. */
  :is(.button, .text-link):hover .zf-icon-arrow { translate: calc(4px * var(--dir, 1)) 0; }

  .date-choice:hover:not(:disabled) {
    background-color: color-mix(in oklch, var(--citron) 68%, var(--paper));
  }
}
