/* ==========================================================================
   Doina Vin · kit/motion.css
   House rules: C:\dev\doinavin\.claude\skills\native-css-motion\SKILL.md
   - Everything is visible at rest, without this file, without JS and under reduced motion.
   - Feedback: 150-250 ms colour/border transitions for everyone; press scale and hover lift only
     with prefers-reduced-motion: no-preference.
   - Entrances (drawer, menu sheet, dialogs, facet panels, toast, admin menu): @starting-style,
     no-preference only.
   - Owner policy 2026-10-17: the automatic motion (view transitions, scroll-driven effects, hero photos,
     the Premii bars) runs for everyone, reduced motion included, unless the visitor chose
     html[data-motion="off"] (localStorage dv_motion, see inc/chrome.php dvh_motion_head).
   - Scroll-driven effects: @supports (animation-timeline: view()) + html.dv-js:not([data-motion="off"]),
     and transform-only (never opacity), so nothing is hidden even when a reader stops mid-scroll.
   - Fixed bars (section 6) hand the one filled action over with scroll timelines, which need no JS:
     they run with JS off too, in one step when the visitor chose motion "off", and fall back to a state with a
     single filled action where scroll timelines are missing.
   - Never inside the checkout skin (.dvh-checkout, .dvh-checkout-head): button feedback only.
   - Do not put .dvh-rise on first-screen elements (it would shift data-measure tops).
   ========================================================================== */

/* ---- 1. Feedback transitions (colour only: safe for everyone) --------------------------------- */
:where(.dvh-btn, .button, .wc-block-components-button, .dvh-add, .add_to_cart_button, .dvh-chip, .dvh-iconbtn,
       .dvh-cartbtn, .dvh-facet__btn, .dvh-stepper__btn, .dvh-seg > *, .dvh-day, .dvh-slot, .dvh-option, .dvh-zoom,
       .dvh-input, .dvh-select, .dvh-textarea, .dvh-check input, .dvh-radio input, .dvh-option input,
       .dvh-nav__link, .dvh-lang a, .dvh-tabs a, .nav-tab, .dvh-adminmenu a, .dvh-table tbody tr,
       .dvh-adminmenu__collapse, .dvh-adminbar__toggle, .dvh-adminmenu__close, .dvh-tags, .dvh-tags__remove) {
  transition:
    background-color var(--dur-hover) var(--ease-out),
    border-color var(--dur-hover) var(--ease-out),
    color var(--dur-hover) var(--ease-out),
    box-shadow var(--dur-hover) var(--ease-out),
    text-decoration-color var(--dur-hover) var(--ease-out);
}
:where(a) { transition: text-decoration-thickness var(--dur-press) var(--ease-out), text-decoration-color var(--dur-press) var(--ease-out); }
:where(.dvh-switch__track) { transition: background-color var(--dur-press) var(--ease-out), border-color var(--dur-press) var(--ease-out); }

@media (prefers-reduced-motion: no-preference) {

  /* ---- 2. Press and hover movement ------------------------------------------------------------- */
  :where(.dvh-btn, .button, .wc-block-components-button, .dvh-add, .add_to_cart_button, .dvh-chip, .dvh-iconbtn,
         .dvh-cartbtn, .dvh-stepper__btn, .dvh-day, .dvh-slot, .dvh-seg > *) {
    transition:
      background-color var(--dur-hover) var(--ease-out),
      border-color var(--dur-hover) var(--ease-out),
      color var(--dur-hover) var(--ease-out),
      box-shadow var(--dur-hover) var(--ease-out),
      scale var(--dur-press) var(--ease-out);
  }
  :where(.dvh-btn, .button, .wc-block-components-button, .dvh-add, .add_to_cart_button, .dvh-chip, .dvh-iconbtn,
         .dvh-cartbtn, .dvh-stepper__btn, .dvh-day, .dvh-slot, .dvh-seg > *):active:not(:disabled) { scale: .97; }

  :where(.dvh-acc > summary .dvh-icon, .dvh-facet__btn .dvh-icon, .dvh-menu__nav summary .dvh-icon, .dvh-filters__more > summary .dvh-icon) {
    transition: rotate var(--dur-ui) var(--ease-out);
  }
  .dvh-add__done .dvh-icon { animation: dvh-pop var(--dur-ui) var(--ease-out) both; }
  .dvh-cartbtn__count.is-bumped { animation: dvh-bump var(--dur-press) var(--ease-out); }   /* kit.js, after an add */
  .dvh-switch__track::after { transition: translate var(--dur-press) var(--ease-out), background-color var(--dur-press) var(--ease-out); }

  @media (hover: hover) {
    .dvh-card__img, .dvh-mini__well img { transition: translate var(--dur-ui) var(--ease-out); }
    .dvh-card__well::before { transition: scale var(--dur-ui) var(--ease-out), opacity var(--dur-ui) var(--ease-out); }
    .dvh-card:hover .dvh-card__img, .dvh-mini:hover .dvh-mini__well img { translate: -50% -6px; }
    .dvh-card:hover .dvh-card__well::before { scale: .86; opacity: .7; }
    .dvh-expcard__media :is(img, video) { transition: scale var(--dur-settle) var(--ease-out); }
    .dvh-expcard:hover .dvh-expcard__media :is(img, video) { scale: 1.03; }
    /* arrow links nudge 3 px toward where they go */
    :is(.dvh-labeltease, .dvh-visitrow, .dvh-btn--tertiary) > .dvh-icon:last-child { transition: translate var(--dur-hover) var(--ease-out); }
    :is(.dvh-labeltease, .dvh-visitrow, .dvh-btn--tertiary):hover > .dvh-icon:last-child { translate: 3px 0; }
  }

  /* ---- 3. Entrances with @starting-style (UI that appears) ---------------------------------------- */
  dialog.dvh-drawer {
    transition: translate var(--dur-drawer) var(--ease-out), display var(--dur-drawer) allow-discrete, overlay var(--dur-drawer) allow-discrete;
  }
  dialog.dvh-drawer:not([open]) { translate: 100% 0; transition-timing-function: var(--ease-move); }
  @starting-style { dialog.dvh-drawer[open] { translate: 100% 0; } }

  dialog.dvh-menu, dialog.dvh-agegate {
    transition: opacity var(--dur-ui) var(--ease-out), translate var(--dur-ui) var(--ease-out), display var(--dur-ui) allow-discrete, overlay var(--dur-ui) allow-discrete;
  }
  dialog.dvh-menu:not([open]) { opacity: 0; translate: 0 -8px; }
  @starting-style { dialog.dvh-menu[open] { opacity: 0; translate: 0 -8px; } }
  dialog.dvh-agegate:not([open]) { opacity: 0; }
  @starting-style { dialog.dvh-agegate[open] { opacity: 0; } }
  .dvh-agegate[open] .dvh-agegate__card { animation: dvh-rise-in var(--dur-drawer) var(--ease-emph) both; }

  dialog.dvh-zoomview {
    transition: opacity var(--dur-ui) var(--ease-out), scale var(--dur-ui) var(--ease-out), display var(--dur-ui) allow-discrete, overlay var(--dur-ui) allow-discrete;
  }
  dialog.dvh-zoomview:not([open]) { opacity: 0; scale: .98; }
  @starting-style { dialog.dvh-zoomview[open] { opacity: 0; scale: .98; } }

  :where(dialog.dvh-drawer, dialog.dvh-menu)::backdrop {
    transition: opacity var(--dur-ui) linear, display var(--dur-ui) allow-discrete, overlay var(--dur-ui) allow-discrete;
  }
  :where(dialog.dvh-drawer, dialog.dvh-menu):not([open])::backdrop { opacity: 0; }
  @starting-style { :where(dialog.dvh-drawer, dialog.dvh-menu)[open]::backdrop { opacity: 0; } }

  .dvh-facet__panel:not(.is-static) { transition: opacity 200ms var(--ease-out), translate 200ms var(--ease-out); }
  @starting-style { .dvh-facet__panel:not(.is-static) { opacity: 0; translate: 0 -4px; } }
  .dvh-toast:not(.is-static), .dvh-cookie:not(.is-static) { transition: opacity var(--dur-ui) var(--ease-out), translate var(--dur-ui) var(--ease-out); }
  @starting-style { .dvh-toast:not(.is-static) { opacity: 0; translate: -50% 12px; } }
  @starting-style { .dvh-cookie:not(.is-static) { opacity: 0; translate: 0 12px; } }

  /* wp-admin menu: a sheet from the left on phones (native popover) */
  @media (max-width: 782.98px) {
    .dvh-admin--page .dvh-adminmenu[popover] { transition: translate var(--dur-ui) var(--ease-out), display var(--dur-ui) allow-discrete, overlay var(--dur-ui) allow-discrete; }
    .dvh-admin--page .dvh-adminmenu[popover]:not(:popover-open) { translate: -100% 0; }
    @starting-style { .dvh-admin--page .dvh-adminmenu[popover]:popover-open { translate: -100% 0; } }
    .dvh-admin--page .dvh-adminmenu[popover]::backdrop { transition: opacity var(--dur-ui) linear, display var(--dur-ui) allow-discrete, overlay var(--dur-ui) allow-discrete; }
    .dvh-admin--page .dvh-adminmenu[popover]:not(:popover-open)::backdrop { opacity: 0; }
    @starting-style { .dvh-admin--page .dvh-adminmenu[popover]:popover-open::backdrop { opacity: 0; } }
  }

  /* accordions open and close with their content height */
  @supports (interpolate-size: allow-keywords) and selector(::details-content) {
    :root { interpolate-size: allow-keywords; }
    :where(.dvh-acc, .dvh-menu__nav details)::details-content {
      block-size: 0; overflow-y: clip;
      transition: block-size var(--dur-ui) var(--ease-out), content-visibility var(--dur-ui) allow-discrete;
    }
    :where(.dvh-acc, .dvh-menu__nav details)[open]::details-content { block-size: auto; }
  }
}

/* ==== Owner 2026-10-17: the automatic motion below (page transitions, scroll effects, hero photos, the
   Premii bars) runs for everyone, also with the system's reduced-motion setting on. The visitor's own choice
   is html[data-motion="off"] (localStorage dv_motion, set before first paint by dvh_motion_head in
   inc/chrome.php; a film's pause button switches it): then none of it runs. Sections 2-3 above (hover, press,
   UI entrances) keep following prefers-reduced-motion. ==== */

/* ---- 4. Cross-document view transitions (shop to shop only; brand and shop are two origins) --------
   With motion "off" the head script skips them on both pages (pageswap / pagereveal). */
@view-transition { navigation: auto; }
.dvh-header { view-transition-name: dv-header; }
::view-transition-old(root) { animation: dvh-vt-out .16s cubic-bezier(.23, 1, .32, 1) both; }
::view-transition-new(root) { animation: dvh-vt-in .32s cubic-bezier(.16, 1, .3, 1) both; }
::view-transition-group(*) { animation-duration: .45s; animation-timing-function: var(--ease-emph); }
/* bottles: style="view-transition-name: dv-bottle-<product id>" inline on the card image and the
   wine-page gallery image (unique per page), so the bottle morphs from card to page */

/* ---- 5. Scroll-driven effects (transform only; content never hidden) ------------------------------ */
@supports (animation-timeline: view()) {
  /* header lifts onto white once the page scrolls */
  html.dv-js:not([data-motion="off"]) .dvh-header {
    animation: dvh-header-lift linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 64px;
  }

  /* section heads, cards, steps rise 32 px as they enter; cards in one row rise together (owner 2026-10-20: a per-column
     stagger made neighbouring cards look misaligned mid-scroll, so the stagger was removed) */
  html.dv-js:not([data-motion="off"]) .dvh-rise {
    animation: dvh-rise linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 70%;
  }
  /* no rise inside a horizontal phone strip (the view timeline would follow the page, not the strip) */
  @media (max-width: 599.98px) { html.dv-js:not([data-motion="off"]) .dvh-cards--strip > .dvh-rise { animation: none; } }

  /* photos settle inside a clipping frame (overflow: clip keeps view() on the page scroller) */
  html.dv-js .dvh-settle { overflow: clip; }
  html.dv-js:not([data-motion="off"]) :is(.dvh-settle > img, .dvh-expcard__media.dvh-settle > video) {
    animation: dvh-settle linear both;
    animation-timeline: view();
    animation-range: entry 0% cover 50%;
  }

  /* hero media drifts 32 px as the hero leaves; house-band rings turn slowly */
  html.dv-js .dvh-hero { view-timeline: --dvh-hero block; }
  html.dv-js:not([data-motion="off"]) .dvh-hero .dvh-hero__media > img {
    animation: dvh-drift linear both;
    animation-timeline: --dvh-hero;
    animation-range: exit 0% exit 100%;
  }
  html.dv-js .dvh-houseband { view-timeline: --dvh-band block; }
  html.dv-js:not([data-motion="off"]) .dvh-houseband::before {
    animation: dvh-rings linear both;
    animation-timeline: --dvh-band;
    animation-range: cover 0% cover 100%;
  }

  /* hero stills: the photo a page opens on grows from 1 to 1.08 and drifts down 3% of its height (slower than
     the page: a small parallax) while the page scrolls through its first 80vh. Its frame clips it (overflow:
     clip) and the 4% overscale always covers the 3% drift, so no edge ever shows. theme.js gives browsers
     without scroll timelines the same through --dvh-hero-p. Add class dvh-herostill to any other photo frame
     that opens a page. */
  html.dv-js:not([data-motion="off"]) :is(.pg-contact-head .pg-contact-frame, .pg-investitori-intro .pg-investitori-frame, .pg-prof-head .pg-prof-frame,
      .pg-presa-hero .dvh-hero__media, .pg-experience-hero .dvh-hero__media, .pg-kavi-concept__frame, .dvh-herostill) > img {
    animation: dvh-herostill linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 80vh;
  }

  /* the itinerary rail draws itself as the programme scrolls through (the hairline rail stays) */
  html.dv-js .dvh-itin { view-timeline: --dvh-itin block; }
  html.dv-js:not([data-motion="off"]) .dvh-itin::after {
    animation: dvh-itin-rail linear both;
    animation-timeline: --dvh-itin;
    animation-range: entry 30% cover 70%;
  }

  /* base.css shortens every animation to .01ms under prefers-reduced-motion; a scroll-linked one keeps the
     length of its scroll range instead (auto) */
  @media (prefers-reduced-motion: reduce) {
    html.dv-js:not([data-motion="off"]) :is(.dvh-header, .dvh-rise, .dvh-settle > img, .dvh-expcard__media.dvh-settle > video, .dvh-hero .dvh-hero__media > img,
        :is(.pg-contact-head .pg-contact-frame, .pg-investitori-intro .pg-investitori-frame, .pg-prof-head .pg-prof-frame,
            .pg-presa-hero .dvh-hero__media, .pg-experience-hero .dvh-hero__media, .pg-kavi-concept__frame, .dvh-herostill) > img),
    html.dv-js:not([data-motion="off"]) .dvh-houseband::before,
    html.dv-js:not([data-motion="off"]) .dvh-itin::after {
      animation-duration: auto !important;
    }
  }
}
/* hero stills where scroll timelines are missing: theme.js writes --dvh-hero-p (0..1) on scroll */
@supports not (animation-timeline: scroll()) {
  html.dv-js:not([data-motion="off"]) :is(.pg-contact-head .pg-contact-frame, .pg-investitori-intro .pg-investitori-frame, .pg-prof-head .pg-prof-frame,
      .pg-presa-hero .dvh-hero__media, .pg-experience-hero .dvh-hero__media, .pg-kavi-concept__frame, .dvh-herostill) > img {
    scale: calc(1 + .08 * var(--dvh-hero-p, 0));
    translate: 0 calc(3% * var(--dvh-hero-p, 0));
  }
}

/* Premii bars under reduced motion: premii.css grows them only under no-preference, and base.css would cut any
   animation to .01ms; here they grow the same way (rows from the left, columns from the baseline) unless the
   visitor chose "off". theme.js holds the years below the first screen until they arrive. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="off"]) .pg-premii-bar__units {
    transform-origin: 0 50%;
    animation: dvh-premii-grow-x var(--dur-settle) var(--ease-emph) both !important;
    animation-delay: calc(var(--i, 0) * 40ms + 120ms) !important;
  }
}
@media (prefers-reduced-motion: reduce) and (min-width: 600px) {
  html:not([data-motion="off"]) .pg-premii-bar__units {
    transform-origin: 50% 100%;
    animation-name: dvh-premii-grow-y !important;
    animation-delay: calc(var(--j, 0) * 40ms + 120ms) !important;
  }
}

/* ---- 6. Fixed bars hand the one filled action over (scroll timelines: no JS needed) --------------
   Desktop buy bar (wine page): docks once the in-panel add button has scrolled away; it slides with
   motion on (reduced motion included) and appears in one step with motion "off". Booking bar (experience page, phones):
   steps aside while the booking card is on screen and comes back once the card's button has left.
   Without scroll timelines the desktop buy bar stays hidden (the in-panel button is the action) and the
   booking bar's button turns secondary, so two filled actions never share a view. */
@supports (animation-timeline: view()) and (timeline-scope: --dvh-buy) {
  @media (min-width: 900px) {
    body:has(.dvh-buy__form) { timeline-scope: --dvh-buy; }
    .dvh-buy__form { view-timeline: --dvh-buy block; }
    .dvh-buybar:not(.is-static):not(.dvh-buybar--book) {
      animation: dvh-dock linear both;
      animation-timeline: --dvh-buy;
      animation-range: exit 0% exit 100%;
    }
  }
  @media (max-width: 899.98px) {
    body:has(.dvh-buybar--book) { timeline-scope: --dvh-book; }
    body:has(.dvh-buybar--book) .dvh-booking { view-timeline: --dvh-book block; }
    .dvh-buybar--book:not(.is-static) {
      animation: dvh-bar-out linear both, dvh-bar-in linear forwards;
      animation-timeline: --dvh-book, --dvh-book;
      animation-range: entry 15% entry 35%, exit 80% exit 95%;
    }
  }
  /* motion "off" (html[data-motion], the visitor's choice): the bars appear in one step */
  html[data-motion="off"] .dvh-buybar:not(.is-static):not(.dvh-buybar--book) { animation-timing-function: steps(1, jump-start); }
  html[data-motion="off"] .dvh-buybar--book:not(.is-static) { animation-timing-function: steps(1, jump-start), steps(1, jump-start); }
  @media (prefers-reduced-motion: reduce) {
    html:not([data-motion="off"]) :is(.dvh-buybar:not(.is-static)) { animation-duration: auto !important; }
  }
}
@supports not ((animation-timeline: view()) and (timeline-scope: --dvh-buy)) {
  @media (min-width: 900px) { .dvh-buybar:not(.is-static):not(.dvh-buybar--book) { display: none; } }
  .dvh-buybar--book .dvh-buybar__btn { background: transparent; color: var(--ink); border-color: var(--ink); }
}

/* ---- Keyframes ----------------------------------------------------------------------------------- */
@keyframes dvh-pop { from { scale: .6; } to { scale: 1; } }
@keyframes dvh-bump { 50% { scale: 1.25; } }
@keyframes dvh-rise-in { from { opacity: 0; translate: 0 8px; } to { opacity: 1; translate: 0 0; } }
@keyframes dvh-vt-out { to { opacity: 0; } }
@keyframes dvh-vt-in { from { opacity: 0; translate: 0 10px; } }
@keyframes dvh-header-lift {
  to { background-color: var(--surface); box-shadow: 0 12px 24px -22px rgb(26 23 27 / .5); }
}
@keyframes dvh-rise { from { translate: 0 var(--rise); } to { translate: 0 0; } }
@keyframes dvh-settle { from { scale: 1.08; } to { scale: 1; } }
@keyframes dvh-drift { to { translate: 0 var(--drift); } }
@keyframes dvh-rings {
  from { translate: 0 calc(-50% + 24px); rotate: -8deg; }
  to { translate: 0 calc(-50% - 24px); rotate: 8deg; }
}
@keyframes dvh-itin-rail { from { scale: 1 0; } to { scale: 1 1; } }
@keyframes dvh-herostill { from { scale: 1; translate: 0 0; } to { scale: 1.08; translate: 0 3%; } }
@keyframes dvh-premii-grow-x { from { scale: 0.001 1; } }
@keyframes dvh-premii-grow-y { from { scale: 1 0.001; } }
@keyframes dvh-dock {
  from { translate: 0 105%; visibility: hidden; }
  to { translate: 0 0; visibility: visible; }
}
@keyframes dvh-bar-out { to { translate: 0 110%; visibility: hidden; } }
@keyframes dvh-bar-in {
  from { translate: 0 110%; visibility: hidden; }
  to { translate: 0 0; visibility: visible; }
}
