/* ============================================================
   productcard.css — the ONE calm product-card interaction
   ------------------------------------------------------------
   Shared by: Shop (DS + NEUN), homepage, collections, search,
   related + recommended products. Pure CSS: no listeners per card,
   no animation library, no layout properties animated.

   Design intent — premium fashion editorial, not a demo reel.
   The default state is already finished. Hover is a refinement.

   Exactly two things respond:
     1. THE IMAGE  — soft crossfade to a second angle (only when a
                     real secondary image exists) + a 1.5% settle.
     2. THE CARD   — a quiet border/shadow response.
   Title, price, category and badges never move. Ever.

   Only opacity + transform are animated (compositor-friendly).
   Gated on real hover hardware, so touch never gets a stuck state.
   ============================================================ */

:root {
  /* One rhythm for the whole card system. */
  --pc-dur: 380ms;
  --pc-ease: cubic-bezier(.22, .61, .36, 1); /* refined ease-out, no bounce */
  --pc-scale: 1.015;                          /* well inside the 1.01–1.025 brief */
}

/* ---------- image stack ---------- */
/* Both layers share one box, so a crossfade can never shift layout. */
[data-card] [data-pimg],
[data-card] [data-pimg2] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;          /* identical crop for both angles */
  transform: scale(1);
  transition: opacity var(--pc-dur) var(--pc-ease),
              transform var(--pc-dur) var(--pc-ease);
}

/* The secondary angle sits on top at zero opacity and only exists
   when the JS found a genuine second image (it sets [data-has]). */
[data-card] [data-pimg2] {
  opacity: 0;
  pointer-events: none;
  z-index: 2;
}

/* ---------- the card itself ---------- */
[data-card] {
  /* Never animate layout. Border response is box-shadow only. */
  transition: box-shadow var(--pc-dur) var(--pc-ease),
              transform var(--pc-dur) var(--pc-ease);
}
[data-card] [data-pimg-wrap] {
  transition: box-shadow var(--pc-dur) var(--pc-ease);
}

/* ============================================================
   HOVER — real pointers only. Touch devices never enter this
   block, so there is no stuck overlay and no double-tap.
   ============================================================ */
@media (hover: hover) and (pointer: fine) {

  /* 1. image: settle + crossfade. :focus-within gives keyboard parity. */
  [data-card]:hover [data-pimg],
  [data-card]:hover [data-pimg2],
  [data-card]:focus-within [data-pimg],
  [data-card]:focus-within [data-pimg2] {
    transform: scale(var(--pc-scale));
  }

  /* Crossfade ONLY when a real secondary image was attached. */
  [data-card]:hover [data-pimg2][data-has],
  [data-card]:focus-within [data-pimg2][data-has] {
    opacity: 1;
  }

  /* 2. card: quiet border response, per house. */

  /* Dangerous Street — smoked charcoal. Heavy, composed, no glow. */
  [data-brand="dangerous"][data-card]:hover [data-pimg-wrap],
  [data-brand="dangerous"][data-card]:focus-within [data-pimg-wrap] {
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16),
                0 12px 34px -16px rgba(0, 0, 0, .75);
  }

  /* NEUN — warm neutral, very soft. A settle, not a floating SaaS card. */
  [data-brand="neun"][data-card]:hover [data-pimg-wrap],
  [data-brand="neun"][data-card]:focus-within [data-pimg-wrap] {
    box-shadow: inset 0 0 0 1px rgba(22, 21, 18, .16),
                0 10px 28px -16px rgba(22, 21, 18, .22);
  }
  [data-brand="neun"][data-card]:hover,
  [data-brand="neun"][data-card]:focus-within {
    transform: translateY(-2px);   /* slight lift, editorial not floaty */
  }
}

/* ---------- keyboard focus: always visible, never hover-only ---------- */
[data-card] a:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 3px;
}
[data-brand="dangerous"][data-card] a:focus-visible { outline-color: #C9A87C; }
[data-brand="neun"][data-card] a:focus-visible      { outline-color: #1A1714; }

/* The one quiet control (wishlist). Consistently placed, always
   reachable by keyboard — never revealed only on hover. */
[data-card] [data-quiet] {
  opacity: .6;
  transition: opacity var(--pc-dur) var(--pc-ease);
}
@media (hover: hover) and (pointer: fine) {
  [data-card]:hover [data-quiet],
  [data-card] [data-quiet]:focus-visible { opacity: 1; }
}

/* ============================================================
   REDUCED MOTION — no swap, no scale, no lift.
   Only the border response survives, and it snaps.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  [data-card],
  [data-card] [data-pimg],
  [data-card] [data-pimg2],
  [data-card] [data-pimg-wrap],
  [data-card] [data-quiet] {
    transition: none !important;
  }
  [data-card]:hover [data-pimg],
  [data-card]:hover [data-pimg2],
  [data-card]:focus-within [data-pimg],
  [data-card]:focus-within [data-pimg2],
  [data-brand="neun"][data-card]:hover,
  [data-brand="neun"][data-card]:focus-within {
    transform: none !important;
  }
  /* no image swap at all under reduced motion */
  [data-card]:hover [data-pimg2][data-has],
  [data-card]:focus-within [data-pimg2][data-has] {
    opacity: 0 !important;
  }
}
