/* ============================================================
   Motion & detail layer
   Everything here is additive polish. Every effect below has a
   prefers-reduced-motion escape, and the page is fully readable
   with CSS animation disabled entirely.
   ============================================================ */

/* ---------- 1. Cross-document page transitions (native, no JS) ----------
   Progressive enhancement: Chrome/Edge 126+, Safari 18.2+, Firefox partial.
   Browsers without support just navigate normally — no penalty, no polyfill. */
@view-transition { navigation: auto; }

::view-transition-old(root) { animation: vt-out .22s cubic-bezier(.4,0,1,1) both; }
::view-transition-new(root) { animation: vt-in  .32s cubic-bezier(0,0,.2,1) both; }

@keyframes vt-out { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vt-in  { from { opacity: 0; transform: translateY(10px); } }

/* The header shouldn't slide with the page — it's persistent furniture. */
header.site { view-transition-name: site-header; }
::view-transition-old(site-header),
::view-transition-new(site-header) { animation: none; mix-blend-mode: normal; }

/* A product photo morphs from its catalogue card into the detail page hero.
   The shared name is assigned per-card in JS at click time, because only one
   element on a page may carry a given view-transition-name at once. */
.vt-product-image { view-transition-name: product-image; }
::view-transition-group(product-image) { animation-duration: .4s; }

/* ---------- 2. First-paint hero sequence ----------
   CSS deliberately hides NOTHING here. Hiding is done by gsap.set() one
   statement before the timeline that reveals it, so there is no window in
   which the hero can be left blank by a script that dies, a throttled
   background tab, or a blocked file. This file only supplies the clipping
   boxes that SplitText's line wrappers need. */
.hero-line { display: block; overflow: hidden; }
.hero-line > span { display: block; will-change: transform; }

/* ---------- 3. Product cards ---------- */
.prod-card {
  position: relative;
  transition: transform .28s cubic-bezier(.2,.7,.3,1), box-shadow .28s ease, border-color .28s ease;
}
/* Family colour enters as a rule across the card top, drawn on hover. */
.prod-card::after {
  content: "";
  position: absolute; inset: 0 auto auto 0;
  height: 3px; width: 100%;
  background: var(--fam, var(--pine));
  transform: scaleX(0); transform-origin: left;
  transition: transform .38s cubic-bezier(.2,.7,.3,1);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.prod-card:hover, .prod-card:focus-visible {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lift);
  border-color: var(--fam, var(--line));
}
.prod-card:hover::after, .prod-card:focus-visible::after { transform: scaleX(1); }
.prod-card .shot img { transition: transform .5s cubic-bezier(.2,.7,.3,1); }
.prod-card:hover .shot img { transform: scale(1.04); }
.prod-card .eyebrow { color: var(--fam, var(--pine)); transition: color .2s ease; }
.prod-card .link { transition: gap .2s ease; }

/* Family → colour mapping. data-family is already on every card. */
[data-family="Retail bags"]      { --fam: var(--fam-retail); }
[data-family="Mesh & netting"]   { --fam: var(--fam-mesh); }
[data-family="Film & poly"]      { --fam: var(--fam-film); }
[data-family="Compostable"]      { --fam: var(--fam-compostable); }
[data-family="Trays & closures"] { --fam: var(--fam-trays); }
[data-family="Industrial"]       { --fam: var(--fam-industrial); }

/* ---------- 4. Filter chips ---------- */
.filter-chip { transition: background-color .2s ease, color .2s ease, border-color .2s ease, transform .12s ease; }
.filter-chip:active { transform: scale(.97); }

/* ---------- 5. Link underline that draws in ---------- */
.link-draw { position: relative; }
.link-draw::after {
  content: ""; position: absolute; left: 0; bottom: -2px;
  width: 100%; height: 1.5px; background: currentColor;
  transform: scaleX(0); transform-origin: right;
  transition: transform .3s cubic-bezier(.2,.7,.3,1);
}
.link-draw:hover::after, .link-draw:focus-visible::after { transform: scaleX(1); transform-origin: left; }

/* ---------- 6. Stat counters ---------- */
.stat-num { font-variant-numeric: tabular-nums; }

/* ---------- 7. Buttons ---------- */
.btn { transition: background-color .18s ease, color .18s ease, border-color .18s ease, transform .12s ease, box-shadow .18s ease; }
.btn-accent:hover, .btn-wa:hover { transform: translateY(-1px); box-shadow: 0 6px 18px -8px rgba(16,26,53,.5); }
.btn:active { transform: translateY(0) scale(.985); }

/* ---------- 8. Woven section divider ----------
   A tiny nod to the actual product: a mesh weave, drawn in CSS, separating
   major sections instead of a plain hairline. */
.weave-rule {
  height: 8px; border: none; margin: 0;
  background-image:
    repeating-linear-gradient(45deg,  var(--line) 0 1px, transparent 1px 7px),
    repeating-linear-gradient(-45deg, var(--line) 0 1px, transparent 1px 7px);
  opacity: .9;
}

/* ---------- 9. Guided quote form ----------
   Each step slides in from the side you're heading towards, the progress
   rail fills left to right, and each new answer chip settles into place.
   All three say "you moved forward". None of them is needed to read the form. */
.quote-progress li::before { transition: transform .45s cubic-bezier(.2,.7,.3,1); }
.quote-form fieldset.paso-adelante { animation: paso-adelante .34s cubic-bezier(.2,.7,.3,1) both; }
.quote-form fieldset.paso-atras    { animation: paso-atras .3s cubic-bezier(.2,.7,.3,1) both; }
@keyframes paso-adelante { from { opacity: 0; transform: translateX(24px); } }
@keyframes paso-atras    { from { opacity: 0; transform: translateX(-24px); } }

.quote-ficha { transition: border-color .15s ease; }
.quote-ficha.nueva { animation: ficha-entra .36s cubic-bezier(.2,.7,.3,1) both; }
@keyframes ficha-entra { from { opacity: 0; transform: translateY(6px) scale(.94); } }

/* ---------- 10. Mobile quote bar ----------
   Slides up when the last quote button scrolls away, and leaves faster than
   it came (exit .2s, enter .32s). visibility waits for the slide to finish
   before taking the bar out of the tab order. */
.barra-cotizar { transition: transform .2s cubic-bezier(.4,0,1,1), visibility 0s .2s; }
.barra-cotizar.visible { transition: transform .32s cubic-bezier(.2,.7,.3,1), visibility 0s; }
.wa-float, .assistant { transition: transform .32s cubic-bezier(.2,.7,.3,1); }

/* ---------- 11. Product-in-use clips ----------
   A crossfade, not a cut: the photo dissolves into the same product moving.
   clip.js never plays a clip under reduced motion, so nothing to strip. */
.clip-producto { transition: opacity .28s ease; }

/* ---------- 12. Order timeline (About) ----------
   The line is tied to scroll position, so the short transition only smooths
   the steps between scroll events — it never runs ahead of the reader. */
.stepper-linea { transition: transform .12s linear; }
.stepper-vivo .step::before { transition: background-color .25s ease, border-color .25s ease; }
.stepper-vivo .step .n { transition: color .25s ease; }

/* ---------- Reduced motion: strip all of it ---------- */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
  .prod-card, .prod-card .shot img, .prod-card::after,
  .btn, .filter-chip, .link-draw::after,
  .quote-progress li::before,
  .barra-cotizar, .barra-cotizar.visible, .wa-float, .assistant,
  .stepper-linea, .stepper-vivo .step::before, .stepper-vivo .step .n { transition: none !important; }
  .quote-form fieldset, .quote-ficha { animation: none !important; }
  .prod-card:hover { transform: none; }
  .prod-card:hover .shot img { transform: none; }
}
