/* =========================================================
   CATEGORY-ENTRANCE.CSS
   The scroll entrance for the products area, shared by all six
   category pages — one implementation, no per-page variation.

   ANIMATION ONLY -- opacity and transform, neither of which
   affects the box an element occupies. No layout, grid, spacing,
   card size, image, typography, colour, content or behaviour is
   changed, and the hero entrance and the page transition are
   untouched.

   ---------------------------------------------------------
   THE HOVER RULE
   The cards already carry finished hover work in
   interactions.css, and a `transition` declaration replaces any
   earlier one on the same element. So:

     .product-card        has `transition: background-color,
                          box-shadow` for the hover's panel
                          deepening and its shadow. Its entrance
                          is a keyframe ANIMATION, never a
                          transition -- the two are separate
                          properties and do not overwrite each
                          other. `backwards`, never `both`, so
                          the animation releases the moment it
                          ends and leaves nothing declared.
     .product-card__image has `transition: transform` (the 1.04
                          zoom) -- NOT touched.
     .product-card__rule  has `transition: transform` and its own
                          transform-origin for the hover's 1.32
                          stretch -- NOT touched, which is also
                          what the brief asks for: the picture,
                          the name, the card's own SILANDE rule
                          and the description all arrive WITH the
                          card, as one unit, never separately.

   NO NEW SILANDE RULE IS ADDED, and the existing one's colours
   and geometry are not redefined: .cat-rule and its red/blue
   segments stay exactly as category.css declares them. The only
   thing added is the same draw the other section headings on
   this site already use -- red leading at +100ms for 170ms,
   blue following out of it at +260ms for 320ms, from a physical
   right origin. The selector is scoped to .cat-products__rule
   on purpose: .cat-rule__segment is ALSO the class inside every
   product card's own rule, and an unscoped selector would have
   animated all of those too.

   SAFETY: nothing is hidden until js/category-entrance.js adds
   .is-armed. If that script is missing or fails, no rule here
   matches and the catalogue is simply there from the first
   paint.
   ========================================================= */

:root {
  /* The same curve as every other entrance on the site,
     restated so the files stay independent of load order. */
  --ctx-ease: cubic-bezier(0.40, 0, 0.20, 1);

  --ctx-head: 600ms;
  --ctx-red: 170ms;
  --ctx-at-red: 100ms;
  --ctx-blue: 320ms;
  --ctx-at-blue: 260ms;

  --ctx-card: 600ms;
  --ctx-col: 90ms;    /* between the columns of one row */
  --ctx-lead: 120ms;  /* the cards begin just behind the heading */
}

@keyframes ctx-rise-10 { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ctx-rise-12 { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: translateY(0); } }
@keyframes ctx-draw    { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* ---------------------------------------------------------
   THE SECTION HEADING AND ITS RULE
   --------------------------------------------------------- */

.cat-products__inner.is-armed:not(.is-in) .cat-products__heading {
  opacity: 0;
  transform: translateY(10px);
}

.cat-products__inner.is-armed:not(.is-in) .cat-products__rule > .cat-rule__segment {
  transform: scaleX(0);
}

.cat-products__inner.is-armed.is-in .cat-products__heading {
  animation: ctx-rise-10 var(--ctx-head) var(--ctx-ease) backwards;
}

/* RED LEADS. The markup is red-first and in this RTL row the
   first child lands physically right, so red is the segment at
   the line's right end: it draws first and blue grows leftward
   out of it. transform-origin is PHYSICAL and is never flipped
   by direction. */
.cat-products__inner.is-armed .cat-products__rule > .cat-rule__segment {
  transform-origin: right center;
}

.cat-products__inner.is-armed.is-in .cat-products__rule > .cat-rule__segment--red {
  animation: ctx-draw var(--ctx-red) var(--ctx-ease) var(--ctx-at-red) backwards;
}

.cat-products__inner.is-armed.is-in .cat-products__rule > .cat-rule__segment--blue {
  animation: ctx-draw var(--ctx-blue) var(--ctx-ease) var(--ctx-at-blue) backwards;
}

/* ---------------------------------------------------------
   THE CARDS
   Staggered by COLUMN rather than by the order entries happen
   to arrive in: the grid fills in DOM order and this page is
   RTL, so the first card of each row sits on the physical
   RIGHT. Counting by column keeps the wave running
   right-to-left across every row at exactly the same pace,
   whatever the browser batches together, and stops a tall
   viewport from turning two rows into one long chain.
   --------------------------------------------------------- */

.cat-products__grid.is-armed .product-card:nth-child(3n + 1) { --ctx-step: 0ms; }
.cat-products__grid.is-armed .product-card:nth-child(3n + 2) { --ctx-step: var(--ctx-col); }
.cat-products__grid.is-armed .product-card:nth-child(3n + 3) { --ctx-step: calc(var(--ctx-col) * 2); }

/* The grid goes to four columns here (category.css), so the
   wave has to count in fours as well. */
@media (min-width: 1477px) {
  .cat-products__grid.is-armed .product-card:nth-child(4n + 1) { --ctx-step: 0ms; }
  .cat-products__grid.is-armed .product-card:nth-child(4n + 2) { --ctx-step: var(--ctx-col); }
  .cat-products__grid.is-armed .product-card:nth-child(4n + 3) { --ctx-step: calc(var(--ctx-col) * 2); }
  .cat-products__grid.is-armed .product-card:nth-child(4n + 4) { --ctx-step: calc(var(--ctx-col) * 3); }
}

.cat-products__grid.is-armed .product-card:not(.is-in) {
  opacity: 0;
  transform: translateY(12px);
}

/* No scale on the card, no rotation, no new shadow, and nothing
   that touches a neighbouring card's opacity. */
.cat-products__grid.is-armed .product-card.is-in {
  animation: ctx-rise-12 var(--ctx-card) var(--ctx-ease)
             calc(var(--ctx-lead) + var(--ctx-step, 0ms)) backwards;
}

/* ---------------------------------------------------------
   REDUCED MOTION — everything present, nothing moves
   --------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .cat-products__inner.is-armed:not(.is-in) .cat-products__heading,
  .cat-products__grid.is-armed .product-card:not(.is-in) {
    opacity: 1;
    transform: none;
  }

  .cat-products__inner.is-armed:not(.is-in) .cat-products__rule > .cat-rule__segment {
    transform: none;
  }

  .cat-products__inner.is-armed.is-in .cat-products__heading,
  .cat-products__inner.is-armed.is-in .cat-products__rule > .cat-rule__segment,
  .cat-products__grid.is-armed .product-card.is-in {
    animation: none;
  }
}
