/**
 * Quiosco — product grid styles (defensive design system).
 *
 * Scope: `.qsc-grid` y descendientes BEM. Cero `!important`. Mobile first.
 *
 * Filosofía v0.6:
 *   - Quiosco GARANTIZA estructura visual (alturas iguales, CTA al
 *     fondo, padding consistente, color reseteado, sizing por `rem`)
 *     INDEPENDIENTE del theme. El plugin se vende como producto: no
 *     puede romperse cuando el theme aplica `a { color: orange }` o
 *     `li.product { border: 1px solid; padding: 16px }`.
 *   - Customización pública vía CSS variables (token API). El sitio
 *     redefine `--qsc-card-bg`, `--qsc-button-bg`, etc. y NO pelea
 *     specificity. Documentado en README.
 *   - En contexto archive (`<li class="product">`), neutralizamos el
 *     styling hostil del theme SOLO en los `<li>` que contienen un
 *     card Quiosco — vía `:has()`. No afectamos otros loops WC ni
 *     otros plugins.
 *
 * Browser support para `:has()`:
 *   Chrome 105+ (sept 2022), Safari 15.4+ (mar 2022), Firefox 121+
 *   (dic 2023). Browsers viejos pierden la archive defense (doble-card
 *   visual) pero el archive sigue funcional. Trade-off aceptable.
 */

/* -------------------------------------------------------------------------
 * Public token API (CSS variables).
 * Specificity 0 vía `:where()` → el sitio puede override desde un
 * selector normal (`:root`, `body`, `.qsc-grid`, etc.) sin pelear.
 * Defaults neutrales (negro/blanco/gris) para que cualquier theme se
 * vea aceptable out-of-the-box.
 * ------------------------------------------------------------------------- */

:where(.qsc-grid) {
  --qsc-grid-gap: 1.5rem;

  --qsc-card-bg: #ffffff;
  --qsc-card-text: #1a1a1a;
  --qsc-card-text-muted: #555555;
  --qsc-card-border: 1px solid #e5e5e5;
  --qsc-card-radius: 0.5rem;
  --qsc-card-shadow: none;
  --qsc-card-padding: 1.25rem;

  --qsc-media-aspect-ratio: 4 / 3;

  --qsc-title-size: 1.125rem;
  --qsc-title-weight: 700;
  --qsc-title-line-height: 1.3;

  --qsc-price-size: 1rem;
  --qsc-price-color: inherit;

  --qsc-button-bg: #1a1a1a;
  --qsc-button-text: #ffffff;
  --qsc-button-bg-hover: #000000;
  --qsc-button-radius: 0.375rem;
  --qsc-button-padding: 0.75rem 1.25rem;

  /* Category pill (v0.7) — overlay sobre la imagen del card.
     Defaults neutros (negro/blanco, sin radius) para que cualquier
     theme se vea aceptable out-of-the-box. El sitio override desde
     `:root` para gradients, radius asimétricos, etc. */
  --qsc-category-bg: #1a1a1a;
  --qsc-category-text: #ffffff;
  --qsc-category-padding: 0.5rem 0.875rem;
  --qsc-category-font-size: 0.875rem;
  --qsc-category-font-weight: 600;
  --qsc-category-radius-tl: 0;
  --qsc-category-radius-tr: 0;
  --qsc-category-radius-bl: 0;
  --qsc-category-radius-br: 0;
}

/* -------------------------------------------------------------------------
 * Isolated-card token redeclaration (v0.8 contract).
 *
 * El template `templates/woocommerce/content-product.php` se invoca en MUY
 * variados contextos: archive loop (`<ul class="products">`), `[products]`
 * shortcode, related products en single-product, cross-sells / upsells en
 * cart / checkout, sidebar widgets. La mayoría no envuelve los cards en
 * `.qsc-grid` — usan `<ul class="products">` (cascadeo natural de WC) o
 * directamente bloques sueltos.
 *
 * Las vars declaradas SOLO en `:where(.qsc-grid)` no aplican en esos
 * contextos → el card cae a fallback (font-size del UA, color heredado,
 * sin border-radius, etc.) y se ve roto.
 *
 * Solución: redeclaramos las vars de **card-level** acá, scoped al card.
 * Las card vivirá igual de bien aislada o dentro de un `.qsc-grid`. Mantenemos
 * la declaración original en `:where(.qsc-grid)` para no romper backwards
 * compat: un site que override desde `.qsc-grid` (specificity 0,1,0) o
 * desde `:root` siempre gana sobre `:where()` (specificity 0).
 *
 * NO redeclaramos `--qsc-grid-gap` porque sólo aplica al wrapper grid,
 * no al card aislado.
 * ------------------------------------------------------------------------- */

:where(.qsc-grid__card) {
  --qsc-card-bg: #ffffff;
  --qsc-card-text: #1a1a1a;
  --qsc-card-text-muted: #555555;
  --qsc-card-border: 1px solid #e5e5e5;
  --qsc-card-radius: 0.5rem;
  --qsc-card-shadow: none;
  --qsc-card-padding: 1.25rem;

  --qsc-media-aspect-ratio: 4 / 3;

  --qsc-title-size: 1.125rem;
  --qsc-title-weight: 700;
  --qsc-title-line-height: 1.3;

  --qsc-price-size: 1rem;
  --qsc-price-color: inherit;

  --qsc-button-bg: #1a1a1a;
  --qsc-button-text: #ffffff;
  --qsc-button-bg-hover: #000000;
  --qsc-button-radius: 0.375rem;
  --qsc-button-padding: 0.75rem 1.25rem;

  --qsc-category-bg: #1a1a1a;
  --qsc-category-text: #ffffff;
  --qsc-category-padding: 0.5rem 0.875rem;
  --qsc-category-font-size: 0.875rem;
  --qsc-category-font-weight: 600;
  --qsc-category-radius-tl: 0;
  --qsc-category-radius-tr: 0;
  --qsc-category-radius-bl: 0;
  --qsc-category-radius-br: 0;
}

/* -------------------------------------------------------------------------
 * Grid wrapper — mobile-first 1col, 2col tablet, N col desktop.
 * Mantenemos los breakpoints heredados de v0.4 (768/1024) para no
 * romper QA / specs E2E existentes.
 * ------------------------------------------------------------------------- */

.qsc-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--qsc-grid-gap);
  list-style: none;
  margin: 0;
  padding: 0;
}

@media (min-width: 768px) {
  .qsc-grid--cols-2,
  .qsc-grid--cols-3,
  .qsc-grid--cols-4,
  .qsc-grid--cols-5,
  .qsc-grid--cols-6 {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .qsc-grid--cols-1 { grid-template-columns: 1fr; }
  .qsc-grid--cols-2 { grid-template-columns: repeat(2, 1fr); }
  .qsc-grid--cols-3 { grid-template-columns: repeat(3, 1fr); }
  .qsc-grid--cols-4 { grid-template-columns: repeat(4, 1fr); }
  .qsc-grid--cols-5 { grid-template-columns: repeat(5, 1fr); }
  .qsc-grid--cols-6 { grid-template-columns: repeat(6, 1fr); }
}

/* -------------------------------------------------------------------------
 * Card — flex column + height 100% + positioning context for overlays.
 *
 * Why height 100%: en CSS Grid, cada item se estira al alto del row
 * por default (`align-items: stretch`). Pero el contenido interno no
 * se estira a menos que el card sea flex column con height 100%. Así
 * empujamos el CTA al fondo de TODAS las cards aunque tengan títulos
 * de distinta longitud.
 *
 * Why box-sizing explícito: algunos themes (rare) resetean `*` sin
 * border-box. Padding + border en el card afuera del width romperían
 * el grid. Defensa.
 *
 * Why `position: relative` (v0.7.1 contract): `.qsc-grid__card` es el
 * contenedor visual COMPLETO del componente — incluye media + body +
 * cta. Sites que quieran agregar decoraciones (hover gradient overlay,
 * brand chrome) usan `.qsc-grid__card::before` o `::after` con
 * `position: absolute; inset: 0` para cubrir TODO el card sin gaps
 * (importante: el CTA es hermano del card-link, no descendiente, así
 * que un overlay en `__body::after` deja al CTA fuera y aparece un
 * gap visual). Sin `position: relative` acá, el `::after` sube al
 * primer ancestor positioned (típicamente `<body>`) y se rompe.
 *
 * Why `overflow: hidden`: combinado con `border-radius`, clipea overlays
 * que excedan el contenedor. También evita que el `<img>` con
 * `transform: scale(1.05)` (hover effect típico) sangre por fuera.
 * ------------------------------------------------------------------------- */

.qsc-grid__card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  box-sizing: border-box;
  background: var(--qsc-card-bg);
  color: var(--qsc-card-text);
  border: var(--qsc-card-border);
  border-radius: var(--qsc-card-radius);
  box-shadow: var(--qsc-card-shadow);
  overflow: hidden;
  /* Reset text-align en caso de que el theme lo haya aplicado al
     <li class="product"> con `text-align: center` (Storefront, varios). */
  text-align: left;
}

.qsc-grid__card-link {
  display: flex;
  flex-direction: column;
  flex: 1;
  color: inherit;
  text-decoration: none;
}

/* Media: aspect-ratio fijo evita CLS, no-shrink garantiza que el body
   se estira (no la imagen) cuando un card tiene más texto.
   `position: relative` también es load-bearing para el overlay de
   `.qsc-grid__category` (v0.7). */
.qsc-grid__media {
  position: relative;
  width: 100%;
  aspect-ratio: var(--qsc-media-aspect-ratio);
  overflow: hidden;
  flex-shrink: 0;
}

.qsc-grid__image,
.qsc-grid__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Category pill (v0.7) — overlay decorativo sobre la imagen.
   `pointer-events: none` para que no capture clicks del card-link `<a>`
   que cubre todo el media + body. `z-index: 2` lo apila encima de la
   imagen sin pelear con otros decorators que el theme pueda agregar. */
.qsc-grid__category {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  margin: 0;
  padding: var(--qsc-category-padding);
  background: var(--qsc-category-bg);
  color: var(--qsc-category-text);
  font-size: var(--qsc-category-font-size);
  font-weight: var(--qsc-category-font-weight);
  line-height: 1.2;
  border-top-left-radius: var(--qsc-category-radius-tl);
  border-top-right-radius: var(--qsc-category-radius-tr);
  border-bottom-left-radius: var(--qsc-category-radius-bl);
  border-bottom-right-radius: var(--qsc-category-radius-br);
  pointer-events: none;
}

/* Body: flex 1 → consume el espacio sobrante, empujando al CTA al
   fondo (margin-top: auto del CTA). gap interno entre title/price/excerpt. */
.qsc-grid__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: 0.5rem;
  padding: var(--qsc-card-padding);
}

.qsc-grid__title {
  margin: 0;
  font-size: var(--qsc-title-size);
  font-weight: var(--qsc-title-weight);
  line-height: var(--qsc-title-line-height);
  color: inherit;
}

.qsc-grid__price {
  font-size: var(--qsc-price-size);
  color: var(--qsc-price-color);
  font-weight: 600;
}

.qsc-grid__excerpt {
  margin: 0;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--qsc-card-text-muted);
}

/* CTA wrapper: margin-top: auto empuja al fondo del card. Padding
   horizontal alineado con el body, padding bottom propio para no
   sumar al body padding.

   Contrato v0.7.1: el CTA NO declara `background` en core. Razón: si
   el card tiene un overlay decorativo via `.qsc-grid__card::after`
   (hover gradient, brand chrome), un background opaco acá lo taparía
   y aparecería un gap visual entre body y cta. El sitio decide si
   pintar el CTA — vía mu-plugin / theme. */
.qsc-grid__cta {
  display: flex;
  margin-top: auto;
  padding: 0 var(--qsc-card-padding) var(--qsc-card-padding);
}

/* -------------------------------------------------------------------------
 * Button — reset agresivo + variables.
 *
 * Why reset: themes hostiles aplican `a { color: orange }`,
 * `button { font-family: serif }`, `a { text-decoration: underline }`.
 * Sin reset explícito, el CTA se ve roto sobre el bg coloreado del site.
 * Setear color, font, border, text-decoration explícito gana por
 * specificity de `.qsc-grid__button` + cascade order normal.
 * Cero `!important`.
 *
 * Why hover setea color: defensa contra `a:hover { color: orange }`.
 * Si solo seteamos bg en hover, color del texto cambia al del theme
 * (a veces el mismo color del bg → invisible).
 * ------------------------------------------------------------------------- */

.qsc-grid__button,
.qsc-grid__button:link,
.qsc-grid__button:visited {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  padding: var(--qsc-button-padding);
  background: var(--qsc-button-bg);
  color: var(--qsc-button-text);
  border: 0;
  border-radius: var(--qsc-button-radius);
  font: inherit;            /* reset font-family / font-size del UA button */
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 200ms ease, color 200ms ease;
}

/* Reset color en estados :link y :visited específicos: muchos themes
   declaran `a:link, a:visited { color: ... }` (specificity 0,1,1 vía
   pseudo-class) que ganaría a `.qsc-grid__button` (0,1,0). Repetimos el
   chain para empatar specificity y dejar que cascade order decida —
   nuestro CSS se encola con priority 99, así que va después del theme. */

/* -------------------------------------------------------------------------
 * Hover — gated to devices with real hover. Touch screens skip esto
 * (evita "stuck hover" después de un tap).
 * ------------------------------------------------------------------------- */

@media (hover: hover) {
  .qsc-grid__card-link:hover .qsc-grid__image {
    opacity: 0.95;
  }

  .qsc-grid__button:hover,
  .qsc-grid__button:focus,
  .qsc-grid__button:active {
    background: var(--qsc-button-bg-hover);
    color: var(--qsc-button-text);  /* explicit — defensa contra `a:hover { color: orange }` */
    text-decoration: none;
  }
}

/* -------------------------------------------------------------------------
 * Focus visible — keyboard a11y. Outline 2px en card-link y button.
 * Usamos `:focus-visible` para que mouse-click no muestre outline (UX),
 * solo keyboard nav.
 * ------------------------------------------------------------------------- */

.qsc-grid__card-link:focus-visible,
.qsc-grid__button:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* -------------------------------------------------------------------------
 * Reduced motion — corta transiciones para users con
 * `prefers-reduced-motion: reduce`.
 * ------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .qsc-grid__card-link .qsc-grid__image,
  .qsc-grid__button {
    transition: none;
  }
}

/* -------------------------------------------------------------------------
 * Archive context defense.
 *
 * Cuando Quiosco overridea el archive de WooCommerce, las cards se
 * envuelven en `<li class="product">` (preservando la grid de WC).
 * El theme/builder (Kubio Pro, Astra, Storefront, …) suele aplicar
 * styling al `li.product` (border, padding, background, text-align
 * center, margin) que se SUMA al card Quiosco adentro → "doble card"
 * visual.
 *
 * Solución: con `:has(> .qsc-grid__card)` neutralizamos el styling del
 * `<li>` SOLO cuando contiene un card Quiosco. Otros loops (e.g. un
 * theme con un widget de productos no-Quiosco) quedan intactos.
 *
 * Browser support: `:has()` es Chrome 105+, Safari 15.4+, Firefox 121+.
 * Sin polyfill — fallback es doble-card visual pero archive funcional.
 * ------------------------------------------------------------------------- */

/* Specificity matched against Kubio Pro's `body.woocommerce ul.products > li.product`
   (specificity 0,3,3). Without the leading `body.woocommerce` / `body.woocommerce-page`
   our defense was 0,3,2 — Kubio's border/bg leaked through. We declare both
   `body.woocommerce` and `body.woocommerce-page` because WC pages carry one or
   the other (or both) depending on context (archive vs single).

   Surgical: ONLY neutralize the `border` + `background` that builders apply
   to draw a "container card" around the `<li>` — Quiosco card draws its own.
   We deliberately do NOT touch `margin`, `padding`, `list-style`, `text-align`
   here: those belong to the grid container which we set on `ul.products`
   below. Pre-v0.8.2 we cleared them too, which collapsed the gap between
   cards in archives where the grid itself was supplying the spacing. */
/* Match Quiosco-rendered list items DIRECTLY by their `.qsc-grid__item` class.
   Specificity: body(1e) + .woocommerce(1c) + ul(1e) + .products(1c) +
   [class*="columns-"](1c) + li(1e) + .qsc-grid__item(1c) + .product(1c) =
   (0, 5, 3). Beats Kubio's `body.woocommerce ul.products.columns-4 > li.product`
   (0, 4, 3) cleanly. Direct class match instead of `:has()` because some
   browsers compute `:has()` specificity inconsistently in cascade resolution. */
body.woocommerce ul.products[class*="columns-"] > li.qsc-grid__item.product,
body.woocommerce ul.products[class*="columns-"] > li.qsc-grid__item.product-category,
body.woocommerce-page ul.products[class*="columns-"] > li.qsc-grid__item.product,
body.woocommerce-page ul.products[class*="columns-"] > li.qsc-grid__item.product-category,
body.woocommerce ul.products > li.qsc-grid__item.product,
body.woocommerce ul.products > li.qsc-grid__item.product-category,
body.woocommerce-page ul.products > li.qsc-grid__item.product,
body.woocommerce-page ul.products > li.qsc-grid__item.product-category {
  background: transparent;
  border: 0;
  /* WooCommerce/Kubio ship `li.product` with `float: left; width: calc(25% - 2rem);
     max-width: calc(25% - 2rem); margin: 0 N% Nem 0`. Once we promote the
     parent to `display: grid` (rule below), the grid `gap` handles spacing
     between cards — individual `margin` on each `<li>` would stack on top
     and break the alignment. Reset width/max-width/float/clear/margin so
     grid sizing + gap take over. */
  width: auto;
  max-width: none;
  margin: 0;
  float: none;
  clear: none;
}

/* `<ul.products>` is what WooCommerce renders on archive pages. Stock WC
   styles it as a `display: flex; flex-wrap: wrap` with `float`-based fallback
   columns (`.columns-4` etc.) — that produces shrunken cards (~186px wide on
   /shop/ with 3 products in a 4-col container) and ignores `gap`. Quiosco's
   own `[quiosco_product_grid]` shortcode renders into a `<ul class="qsc-grid">`
   with proper grid layout, but `<ul.products>` from the archive override
   doesn't carry that class.

   Here we apply the same grid contract to any `<ul.products>` that contains
   Quiosco items (`:has(> li.qsc-grid__item)`). `auto-fit` + `minmax(320px, 1fr)`
   keeps cards at a readable width regardless of the legacy `columns-N` class
   the theme/builder added. Specificity bumped with `body.woocommerce` to win
   over Kubio's flex declarations on the same selector. */
body.woocommerce ul.products[class*="columns-"]:has(> li.qsc-grid__item),
body.woocommerce-page ul.products[class*="columns-"]:has(> li.qsc-grid__item),
body.woocommerce ul.products:has(> li.qsc-grid__item),
body.woocommerce-page ul.products:has(> li.qsc-grid__item) {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--qsc-grid-gap, 32px);
  list-style: none;
  margin: 0;
  padding: 0;
}

/* WooCommerce ships `ul.products` with `::before` + `::after` pseudo-elements
   that act as float clearfix (legacy from when the layout used floats). Once
   we promote the `<ul>` to `display: grid`, those pseudo-elements become
   grid items and consume the first/last column slots — pushing real cards
   off the row. Hide them in the grid context. */
body.woocommerce ul.products[class*="columns-"]:has(> li.qsc-grid__item)::before,
body.woocommerce ul.products[class*="columns-"]:has(> li.qsc-grid__item)::after,
body.woocommerce-page ul.products[class*="columns-"]:has(> li.qsc-grid__item)::before,
body.woocommerce-page ul.products[class*="columns-"]:has(> li.qsc-grid__item)::after,
body.woocommerce ul.products:has(> li.qsc-grid__item)::before,
body.woocommerce ul.products:has(> li.qsc-grid__item)::after,
body.woocommerce-page ul.products:has(> li.qsc-grid__item)::before,
body.woocommerce-page ul.products:has(> li.qsc-grid__item)::after {
  content: none;
  display: none;
}

/* Si el theme aplica algún `width` raro al `<li>`, dejamos que la grid
   de WC lo maneje — no la pisamos acá. Solo neutralizamos el chrome
   visual. */
