/************************************************************
ESTANDARIZACION DISEÑO CARTZILLA - Abril 2026
Autor: Martin Carrillo
Primera versión: 2026-03-18
Última modificación: 2026-04-29
************************************************************/

.ns-item h1 {
    /* Estandarizacion de h1 en ficha de producto */
    color: #000;
    font-size: 25px;
}

.product-gallery-thumblist-item {
    /* Thumbs de galeria mas pequeñas */
    width: 3rem;
    height: 3rem;
}

/* Cucardas */

.ns-badges {
    /* Si un articulo tiene varias cucardas como oferta y nuevo suma un padding de separacion */
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* Espacio entre badges */
}

/************************************************************
CUPONES INTELIGENTES (Smart Coupons) - Junio 2026
v1.3 (2026-06-30): paleta NEUTRA configurable por tienda, cupón
troquelado (la perforación no cruza la muesca), cucarda-cartoncito
con estado activo, y bloque "cupón aplicado" idéntico en ficha y carrito.

>>> PERSONALIZACIÓN POR TIENDA <<<
Para re-colorear TODO el sistema de cupones, sobreescribí estas variables
en el CSS propio de la tienda (después de este archivo). Ejemplo:
    :root {
        --ns-cupon-accent: #c1121f;        // color de marca
        --ns-cupon-accent-dark: #9d0e18;
        --ns-cupon-applied: #15803d;       // estado aplicado/activo
        --ns-cupon-notch-bg: #ffffff;      // = color de fondo de la página
    }
************************************************************/

:root {
    /* Paleta NEUTRA por defecto (gris oscuro / casi negro) — editable por tienda */
    --ns-cupon-accent: #1f2937;
    /* acento principal */
    --ns-cupon-accent-dark: #111827;
    /* acento hover */
    --ns-cupon-ink: #1f2937;
    /* texto del cupón */
    --ns-cupon-soft: #f3f4f6;
    /* fondo suave */
    --ns-cupon-border: #d1d5db;
    /* borde / troquel */
    --ns-cupon-muted: #6b7280;
    /* texto secundario */
    --ns-cupon-applied: #15803d;
    /* estado aplicado / activo (éxito) */
    --ns-cupon-hot: #d9480f;
    /* efusivo: descuento EXTRA / pocas unidades (urgencia) */
    --ns-cupon-notch-bg: #ffffff;
    /* color de la superficie detrás del cupón (muescas) */

    /* Alias retrocompatibles — el resto del CSS los usa. No hace falta tocarlos. */
    --ns-cupon-green: var(--ns-cupon-accent);
    --ns-cupon-green-dark: var(--ns-cupon-accent-dark);
    --ns-cupon-notch: var(--ns-cupon-notch-bg);
}

/* ===================================================================
   1) CUCARDA en listados — cartoncito troquelado, copiable (ns-data-copy)
      Estado activo: cuando el cupón ya está aplicado en el carrito.
   =================================================================== */
.ns-cupon-tag {
    position: relative;
    display: inline-flex;
    align-items: stretch;
    max-width: 100%;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 6px;
    background: #fff;
    line-height: 1.1;
    vertical-align: middle;
    overflow: hidden;
}

.ns-cupon-tag-stub {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 4px 7px;
    background: var(--ns-cupon-accent);
    color: #fff;
}

.ns-cupon-tag-stub i {
    font-size: 12px;
    line-height: 1;
}

.ns-cupon-tag-main {
    display: flex;
    align-items: center;
    gap: 5px;
    min-width: 0;
    padding: 3px 8px 3px 9px;
    border-left: 1px dashed var(--ns-cupon-border);
}

.ns-cupon-tag-code {
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .3px;
    text-transform: uppercase;
    color: var(--ns-cupon-ink);
    overflow: hidden;
    text-overflow: ellipsis;
}

.ns-cupon-tag-off {
    flex: 0 0 auto;
    font-size: 10px;
    font-weight: 800;
    color: var(--ns-cupon-accent);
}

.ns-cupon-tag-state {
    flex: 0 0 auto;
    font-size: 9px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .4px;
    color: var(--ns-cupon-applied);
}

/* Estado ACTIVO (cupón aplicado) — un poco más chico, sin acción */
.ns-cupon-tag.is-active {
    border-color: var(--ns-cupon-applied);
}

.ns-cupon-tag.is-active .ns-cupon-tag-stub {
    background: var(--ns-cupon-applied);
}

.ns-cupon-tag.is-active .ns-cupon-tag-main {
    padding: 2px 7px 2px 8px;
}

.ns-cupon-tag.is-active .ns-cupon-tag-code {
    font-size: 10px;
}

/* ===================================================================
   2) TARJETA-CUPÓN reutilizable (ficha + cuponera del carrito)
      Cupón real: talón liso + perforación troquelada que NO cruza la muesca.
   =================================================================== */
.ns-cupon-card {
    position: relative;
    display: flex;
    align-items: stretch;
    width: 100%;
    margin: 12px 0;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 10px;
    background: #fff;
    color: var(--ns-cupon-ink);
    text-decoration: none;
    overflow: visible;
    transition: box-shadow .15s ease, transform .15s ease, border-color .15s ease;
}

.ns-cupon-card:hover {
    border-color: var(--ns-cupon-accent);
    box-shadow: 0 6px 16px rgba(0, 0, 0, .12);
    transform: translateY(-1px);
    color: var(--ns-cupon-ink);
}

.ns-cupon-card.ns-cupon-loading {
    opacity: .6;
    pointer-events: none;
}

/* Perforación troquelada: línea punteada INSET (no llega a los bordes/muescas) */
.ns-cupon-card::before {
    content: '';
    position: absolute;
    left: 64px;
    top: 12px;
    bottom: 12px;
    border-left: 2px dashed var(--ns-cupon-border);
    pointer-events: none;
}

/* Talón izquierdo (fondo liso) con el % OFF */
.ns-cupon-card-stub {
    position: relative;
    flex: 0 0 64px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 10px 6px;
    background: var(--ns-cupon-accent);
    color: #fff;
    border-radius: 9px 0 0 9px;
}

.ns-cupon-card-stub i {
    font-size: 18px;
    line-height: 1;
}

/* Muescas del troquel: en la costura, color de la superficie → "muerden" el borde */
.ns-cupon-card-stub::before,
.ns-cupon-card-stub::after {
    content: '';
    position: absolute;
    right: -7px;
    width: 13px;
    height: 13px;
    border-radius: 50%;
    background: var(--ns-cupon-notch-bg);
}

.ns-cupon-card-stub::before {
    top: -7px;
}

.ns-cupon-card-stub::after {
    bottom: -7px;
}

.ns-cupon-card-off {
    font-size: 14px;
    font-weight: 800;
    letter-spacing: .3px;
}

.ns-cupon-card-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 1px;
    padding: 10px 14px 10px 18px;
}

.ns-cupon-card-label {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: .4px;
    color: var(--ns-cupon-muted);
}

.ns-cupon-card-code {
    font-size: 17px;
    font-weight: 800;
    letter-spacing: .6px;
    text-transform: uppercase;
    color: var(--ns-cupon-ink);
}

/* Línea del código con los usos INLINE (no suma altura) */
.ns-cupon-card-codeline {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 2px 8px;
}

.ns-cupon-card-hint,
.ns-cupon-card-scope {
    font-size: 12px;
    color: var(--ns-cupon-muted);
}

.ns-cupon-card-scope i {
    color: var(--ns-cupon-applied);
}

/* Beneficio del cupón (crédito / descuento / EXTRA) */
.ns-cupon-card-benef {
    font-size: 13px;
    font-weight: 800;
    color: var(--ns-cupon-ink);
}

/* Descuento EXTRA — efusivo */
.ns-cupon-card-benef.ns-cupon-benef-extra {
    display: inline-block;
    align-self: flex-start;
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--ns-cupon-hot);
    color: #fff;
    text-transform: uppercase;
    letter-spacing: .3px;
    box-shadow: 0 2px 6px rgba(217, 72, 15, .28);
}

/* Meta: usos restantes + alcance */
.ns-cupon-card-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 10px;
    margin-top: 1px;
    font-size: 12px;
    color: var(--ns-cupon-muted);
}

.ns-cupon-card-meta i {
    font-size: 12px;
}

.ns-cupon-usos {
    display: inline-flex;
    align-items: center;
    gap: 3px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--ns-cupon-muted);
}

.ns-cupon-usos i {
    font-size: 11px;
}

/* Pocas unidades — efusivo */
.ns-cupon-usos.ns-cupon-usos-low {
    color: var(--ns-cupon-hot);
    font-weight: 800;
}

.ns-cupon-scope {
    display: inline-flex;
    align-items: center;
    gap: 3px;
}

.ns-cupon-scope i {
    color: var(--ns-cupon-applied);
}

.ns-cupon-card-cta {
    align-self: center;
    margin: 0 14px 0 auto;
    flex: 0 0 auto;
    padding: 8px 16px;
    border-radius: 8px;
    background: var(--ns-cupon-accent);
    color: #fff;
    font-size: 13px;
    font-weight: 700;
    white-space: nowrap;
}

.ns-cupon-card:hover .ns-cupon-card-cta {
    background: var(--ns-cupon-accent-dark);
}

/* --- Estado APLICADO (compartido ficha + carrito) --- */
.ns-cupon-card--applied {
    border-color: var(--ns-cupon-applied);
}

.ns-cupon-card--applied .ns-cupon-card-stub {
    background: var(--ns-cupon-applied);
}

.ns-cupon-card--applied .ns-cupon-card-code {
    color: var(--ns-cupon-applied);
}

/* --- Estado NO APLICA (cupón cargado que no aplica a ningún item) — naranja --- */
.ns-cupon-card--noaplica {
    border-color: var(--ns-cupon-hot);
}

.ns-cupon-card--noaplica .ns-cupon-card-stub {
    background: var(--ns-cupon-hot);
}

.ns-cupon-card--noaplica .ns-cupon-card-code {
    color: var(--ns-cupon-hot);
}

.ns-cupon-card--noaplica .ns-cupon-card-remove {
    background: var(--ns-cupon-hot);
    border-color: var(--ns-cupon-hot);
}

.ns-cupon-card--noaplica .ns-cupon-card-remove:hover {
    background: #b42318;
    border-color: #b42318;
}

.ns-cupon-card-remove {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    align-self: center;
    margin: 0 14px 0 auto;
    flex: 0 0 auto;
    padding: 7px 12px;
    border: 1px solid var(--ns-cupon-applied);
    border-radius: 8px;
    background: var(--ns-cupon-applied);
    color: #fff;
    font-size: 12px;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: background .15s ease, border-color .15s ease;
}

.ns-cupon-card-remove .ns-cupon-card-remove-x {
    opacity: .7;
    font-size: 13px;
}

.ns-cupon-card-remove:hover {
    border-color: #b42318;
    background: #b42318;
    color: #fff;
}

/* ===================================================================
   3) CUPONERA del carrito (contenedor comercial)
   =================================================================== */
.ns-cuponera {
    padding: 18px;
    border: 1px dashed var(--ns-cupon-accent);
    border-radius: 14px;
    background: var(--ns-cupon-soft);
    /* las muescas de las tarjetas internas deben matchear el fondo de la cuponera */
    --ns-cupon-notch-bg: var(--ns-cupon-soft);
}

.ns-cuponera-badge,
.ns-cuponera-hero .ns-cuponera-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 999px;
    background: var(--ns-cupon-accent);
    color: #fff;
    font-size: 11px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
}

.ns-cuponera-title {
    margin: 8px 0 2px;
    font-size: 18px;
    font-weight: 800;
    color: var(--ns-cupon-ink);
}

.ns-cuponera-sub {
    margin-bottom: 12px;
    color: var(--ns-cupon-muted);
    font-size: 13px;
}

.ns-cuponera-list {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.ns-cuponera-list .ns-cupon-card {
    margin: 0;
}

/* ===================================================================
   4) LANDING /cupones/destacados
   =================================================================== */
.ns-cuponera-hero-title {
    margin: 10px 0 4px;
    font-size: 28px;
    font-weight: 800;
    color: var(--ns-cupon-ink);
}

.ns-cuponera-hero-sub {
    color: var(--ns-cupon-muted);
    font-size: 15px;
}

.ns-cuponera-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 18px;
}

.ns-cupon-ticket {
    position: relative;
    display: flex;
    align-items: stretch;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 12px;
    background: #fff;
    overflow: visible;
    transition: box-shadow .15s ease, transform .15s ease;
}

.ns-cupon-ticket:hover {
    box-shadow: 0 8px 20px rgba(0, 0, 0, .12);
    transform: translateY(-2px);
}

/* perforación troquelada de la landing (inset, no cruza la muesca) */
.ns-cupon-ticket::before {
    content: '';
    position: absolute;
    left: 84px;
    top: 14px;
    bottom: 14px;
    border-left: 2px dashed var(--ns-cupon-border);
    pointer-events: none;
}

.ns-cupon-ticket-stub {
    position: relative;
    flex: 0 0 84px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    background: var(--ns-cupon-accent);
    color: #fff;
    border-radius: 11px 0 0 11px;
}

.ns-cupon-ticket-stub::before,
.ns-cupon-ticket-stub::after {
    content: '';
    position: absolute;
    right: -8px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--ns-cupon-notch-bg);
}

.ns-cupon-ticket-stub::before {
    top: -8px;
}

.ns-cupon-ticket-stub::after {
    bottom: -8px;
}

.ns-cupon-ticket-stub i {
    font-size: 24px;
}

.ns-cupon-ticket-off {
    font-size: 16px;
    font-weight: 800;
}

.ns-cupon-ticket-main {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 3px;
    padding: 10px 12px 10px 18px;
}

.ns-cupon-ticket-benef {
    font-size: 15px;
    font-weight: 800;
    color: var(--ns-cupon-ink);
}

.ns-cupon-ticket-benef.is-extra {
    color: var(--ns-cupon-hot);
}

.ns-cupon-ticket-code {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    align-self: flex-start;
    padding: 3px 9px;
    border: 1px dashed var(--ns-cupon-accent);
    border-radius: 6px;
    background: var(--ns-cupon-soft);
    color: var(--ns-cupon-ink);
    font-weight: 800;
    letter-spacing: .5px;
    text-transform: uppercase;
}

.ns-cupon-ticket-code i {
    font-size: 13px;
}

.ns-cupon-ticket-meta {
    display: flex;
    flex-direction: column;
    gap: 2px;
    font-size: 12px;
    color: var(--ns-cupon-muted);
}

/* Acciones a la DERECHA, centradas vertical — ticket más bajo */
.ns-cupon-ticket-actions {
    flex: 0 0 auto;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    justify-content: center;
    gap: 4px;
    padding: 10px 14px;
}

/* ===================================================================
   5) Badge de cupón aplicado sobre un item del carrito
   =================================================================== */
.ns-cupon-item-tag {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-top: 4px;
    padding: 2px 7px;
    border-radius: 4px;
    background: var(--ns-cupon-applied);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
}

/* ===================================================================
   6) Toast de "cupón aplicado / quitado" (similar a agregar al carrito)
   =================================================================== */
.ns-cupon-toast-host {
    position: fixed;
    z-index: 1090;
    left: 50%;
    bottom: 24px;
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: min(92vw, 420px);
    pointer-events: none;
}

.ns-cupon-toast {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 16px;
    border-radius: 10px;
    background: var(--ns-cupon-ink);
    color: #fff;
    font-size: 14px;
    box-shadow: 0 8px 24px rgba(0, 0, 0, .18);
    opacity: 0;
    transform: translateY(12px);
    transition: opacity .25s ease, transform .25s ease;
}

.ns-cupon-toast.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.ns-cupon-toast.is-ok {
    background: var(--ns-cupon-applied);
}

.ns-cupon-toast.is-error {
    background: #b42318;
}

.ns-cupon-toast i {
    font-size: 18px;
    flex: 0 0 auto;
}

/* ===================================================================
   7) Responsive
   =================================================================== */
@media (max-width: 575.98px) {
    .ns-cupon-card {
        flex-wrap: wrap;
    }

    .ns-cupon-card::before {
        display: none;
    }

    .ns-cupon-card-stub {
        flex-basis: 100%;
        flex-direction: row;
        gap: 6px;
        border-radius: 9px 9px 0 0;
    }

    .ns-cupon-card-stub::before,
    .ns-cupon-card-stub::after {
        display: none;
    }

    .ns-cupon-card-main {
        padding-left: 14px;
    }

    .ns-cupon-card-cta,
    .ns-cupon-card-remove {
        margin: 0 14px 12px;
        width: calc(100% - 28px);
        justify-content: center;
        text-align: center;
    }
}


/* ===================================================================
   8) ESPACIO DE BENEFICIOS en ficha de producto (arriba del agregar)
      C2A + descuento 1 pago + cuotas (collapse) + cupón + envío gratis.
      Estética común: borde gris, fondo blanco, uniforme y minimalista.
   =================================================================== */
.ns-beneficios {
    display: flex;
    flex-direction: column;
    gap: 10px;
    margin: 10px 0;
}

.ns-beneficios .ns-cupon-card {
    margin: 0;
}

/* Filas con caja (borde gris, fondo blanco) — estética unificada */
.ns-beneficio-c2a,
.ns-beneficio-destacado,
.ns-beneficio-envio,
.ns-beneficio-toggle {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 10px;
    background: #fff;
    color: var(--ns-cupon-ink);
    text-decoration: none;
}

.ns-beneficio-toggle {
    cursor: pointer;
    transition: border-color .15s ease;
}

.ns-beneficio-toggle:hover {
    border-color: var(--ns-cupon-ink);
    color: var(--ns-cupon-ink);
}

/* a) C2A — centrado, sin ícono */
.ns-beneficio-c2a {
    justify-content: center;
    text-align: center;
    font-size: 13px;
    color: var(--ns-cupon-muted);
}

/* b) Descuento en 1 pago — destacado (borde más marcado + acento + precio final) */
.ns-beneficio-destacado {
    border-color: var(--ns-cupon-ink);
}

.ns-beneficio-destacado .ns-beneficio-ico {
    background: var(--ns-cupon-ink);
    color: #fff;
}

.ns-beneficio-destacado b {
    font-size: 15px;
}

/* Precio final / monto a la derecha de una fila de beneficio */
.ns-beneficio-amount {
    margin-left: auto;
    flex: 0 0 auto;
    font-weight: 800;
    font-size: 16px;
    white-space: nowrap;
    color: var(--ns-cupon-ink);
}

/* Cuotas en una sola línea (más minimalista) */
.ns-beneficio-line {
    flex-direction: row;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 4px;
}

/* Ícono circular común */
.ns-beneficio-ico {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: var(--ns-cupon-soft);
    color: var(--ns-cupon-ink);
    font-size: 17px;
}

.ns-beneficio-body {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
    font-size: 14px;
    min-width: 0;
}

.ns-beneficio-hint {
    font-size: 11px;
    color: var(--ns-cupon-muted);
}

.ns-beneficio-caret {
    margin-left: auto;
    flex: 0 0 auto;
    color: var(--ns-cupon-muted);
    transition: transform .2s ease;
}

.ns-beneficio-toggle[aria-expanded="true"] .ns-beneficio-caret {
    transform: rotate(180deg);
}

/* c) Detalle de cuotas (collapse) — tabla prolija: concepto a la izq, monto a la der */
.ns-beneficio-detalle {
    margin-top: 8px;
    padding: 4px 14px;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 10px;
    background: var(--ns-cupon-soft);
}

.ns-cuota-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 14px;
    padding: 9px 0;
    border-bottom: 1px dashed var(--ns-cupon-border);
    font-size: 13px;
}

.ns-cuota-row:last-child {
    border-bottom: 0;
}

.ns-cuota-label {
    color: var(--ns-cupon-ink);
}

.ns-cuota-amount {
    flex: 0 0 auto;
    font-weight: 700;
    white-space: nowrap;
    color: var(--ns-cupon-ink);
}

.ns-beneficio-detalle .ns-item-cft {
    color: var(--ns-cupon-muted);
    font-size: 11px;
}

/* Financiación unificada: cuotas (línea principal) + descuento en 1 pago (sub-línea efusiva) */
.ns-fin-main {
    font-size: 14px;
    line-height: 1.2;
}

.ns-fin-oneoff {
    display: block;
    margin-top: 3px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.35;
    color: var(--ns-cupon-hot);
}

/* Cada token entero (no se parte "10% OFF" ni "( Transferencia bancaria )"): wrap sólo entre tokens */
.ns-fin-oneoff b,
.ns-fin-oneoff small {
    white-space: nowrap;
}

.ns-fin-oneoff small {
    color: inherit;
    opacity: .85;
}

.ns-fin-oneoff i {
    font-size: 12px;
}

/* Fila del descuento en 1 pago dentro del detalle (collapse) */
.ns-cuota-row-off {
    color: var(--ns-cupon-hot);
}

.ns-cuota-row-off .ns-cuota-amount {
    color: var(--ns-cupon-hot);
}

/************************************************************
PISO DEL DESCUENTO EN 1 PAGO — leyenda "en compras desde $X"
v1.0 (2026-08-13) — IMP-013

Se renderiza SOLO en los productos que por sí solos no alcanzan
el mínimo ( AppController::_setProductosParams → one_pay_min_txt ).
Es un aviso puntual, no una línea repetida en todo el listado.

Tono deliberadamente bajo: es la CONDICIÓN del beneficio, no el
beneficio. Si compite con el "-10% OFF" que tiene al lado, le
saca fuerza justo a lo que queremos que el cliente lea primero.

Personalizable por tienda vía las variables --ns-cupon-* del
bloque de Cupones Inteligentes (arriba en este mismo archivo).
************************************************************/

.ns-one-pay-discount-min {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    max-width: 100%;
    margin-top: 3px;
    padding: 1px 8px 1px 6px;
    border-radius: 999px;
    background: var(--ns-cupon-soft, #f3f4f6);
    color: var(--ns-cupon-muted, #6b7280);
    font-size: 10px;
    font-weight: 500;
    font-style: normal;
    line-height: 1.7;
    letter-spacing: .1px;
    text-decoration: none;
    white-space: nowrap;
    vertical-align: middle;
}

/* Punto de color: ata la leyenda al mismo acento "efusivo" de la cucarda de
   descuento sin gritar, y le da el respiro visual que el texto solo no tiene. */
.ns-one-pay-discount-min::before {
    content: "";
    flex: 0 0 auto;
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: var(--ns-cupon-hot, #d9480f);
    opacity: .6;
}

/* En la ficha va INLINE, pegada al "-N% OFF", no en su propio renglón. */
.ns-fin-oneoff .ns-one-pay-discount-min,
.ns-cuota-row-off .ns-one-pay-discount-min,
.ns-beneficio-hint .ns-one-pay-discount-min {
    margin-top: 0;
    margin-left: 5px;
    font-weight: 600;
}

/* Dentro del collapse el fondo ya es --ns-cupon-soft: sin contraste, la píldora
   desaparece. Ahí se apoya en el blanco de la superficie. */
.ns-cuota-row-off .ns-one-pay-discount-min {
    background: var(--ns-cupon-notch-bg, #fff);
}

/* En cards angostas el texto puede no entrar de una línea: que envuelva en vez
   de desbordar la card. */
@media (max-width: 575.98px) {
    .ns-one-pay-discount-min {
        white-space: normal;
    }
}

/* e) Envío gratis — acento verde "éxito" */
.ns-beneficio-envio .ns-beneficio-ico {
    background: var(--ns-cupon-applied);
    color: #fff;
}

.ns-beneficio-envio b {
    color: var(--ns-cupon-applied);
}

/* Video (iframe YouTube / tag video) en galeria de producto */
.ns-item-video iframe,
.ns-item-video video {
    display: block;
    width: 100%;
    aspect-ratio: 1 / 1;
}



/************************************************************
ELEMENTOS OCULTOS v1
************************************************************/

.ns-item-cft {
    display: none !important;
}

/************************************************************
AVISOS COOKIES v1 - Marzo 2026 
************************************************************/

/* AVISOS COOKIES */

#ns-aviso-cookies {
    font-size: 12px;
    color: #fff;
    display: none;
    position: fixed;
    bottom: 0;
    left: 0;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.8);
    padding: 15px;
    box-sizing: border-box;
    text-align: center;
    justify-content: center;
    align-items: center;
    z-index: 20;
}

#ns-aviso-cookies p {
    margin: 0
}

/************************************************************
SLIDE Cartzilla v2 - Abril 2026 
Última modificación: 2026-04-21
************************************************************/

/* Slide general */
.ns-slide {
    padding: 0 !important;
    margin: 0 !important;
}

.ns-slide-item {
    position: relative;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    overflow: hidden;
}

/* Imagen frontal */
.ns-slide .ns-slide-front-image {
    padding: 5px;
}

/* Contenedor de título, bajada y botones */
.ns-slide-meta {
    position: absolute;
    top: 1rem;
    left: 0;
    width: 100%;
    height: 100%;
    padding: 2rem;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    pointer-events: none;
}

.ns-slide-meta>div {
    max-width: 42rem;
    pointer-events: all;
    text-align: left;
    /* Mantiene los textos a la izquierda */
}

/* Título del slide */
.ns-slide .ns-slide-item h2 {
    font-size: 48px;
    margin-bottom: 0.5rem;
}

/* Bajada del slide */
.ns-slide .ns-slide-item p {
    font-size: 36px;
    margin-bottom: 0.5rem;
}

/* Botones */
.ns-slide .btn {
    margin-right: 1rem;
    font-size: 20px;
    padding: 0.5rem 1.5rem;
    line-height: 1.2;
}

/* Zócalo HTML del slide */

/* Mobile scaling */
@media (max-width: 768px) {
    .ns-slide .ns-slide-item h2 {
        font-size: 28px !important;
    }

    .ns-slide .ns-slide-item p {
        font-size: 20px !important;
    }

    .ns-slide .btn {
        font-size: 18px !important;
        padding: 0.5rem 1.5rem;
    }
}

/************** FIN SLIDE CSS ************************/

/**********************************************************
  MENU Cartzilla v1 - Mayo 2026
  Última modificación: 2026-04-29
************************************************************/

#ns-nav-item-cta {
    background: #FF6D2D;
    border-color: #FF6D2D;
    color: #fff;
    margin-top: 10px;
    font-weight: 600;
}

#ns-nav-item-cta:hover {
    color: #fff !important;
    background: #E6551A;
    border-color: #E6551A;
}

.is-desktop .navbar-nav>li.nav-item.dropdown {
    position: relative;
}

/* ===== Mega menu (solo DIV dropdown-menu con p-0) ===== */
.is-desktop .navbar-nav>li.nav-item.dropdown>div.dropdown-menu.p-0 {
    position: absolute !important;
    top: calc(100% + 6px) !important;

    /* ancho controlado */
    width: min(1200px, calc(100vw - 24px)) !important;
    max-width: calc(100vw - 24px) !important;

    /* Popper out */
    inset: auto !important;
    transform: none !important;

    max-height: calc(100vh - 140px);
    overflow: auto;
    box-sizing: border-box;

    /* ✅ aplicar shift SOLO al mega */
    margin-left: var(--ns-shift, 0px) !important;
}

/* Grid para 7+ columnas (solo mega) */
.is-desktop .navbar-nav>li.nav-item.dropdown>div.dropdown-menu.p-0>.d-flex {
    display: grid !important;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    column-gap: 18px;
    row-gap: 8px;
    max-width: 100%;
}

.is-desktop .navbar-nav .mega-dropdown-column {
    min-width: 0;
}

/* ===== Dropdowns normales: NO shift ===== */
/* (incluye Marcas, Oportunidades, etc) */
.is-desktop .navbar-nav>li.nav-item.dropdown>ul.dropdown-menu,
.is-desktop .navbar-nav>li.nav-item.dropdown>div.dropdown-menu:not(.p-0) {
    margin-left: 0 !important;
}

/* ===== Shift por rango: lo dejamos en el LI ===== */
.is-desktop .navbar-nav>li {
    --ns-shift: 0px;
}

.is-desktop .navbar-nav>li:nth-child(n + 2) {
    --ns-shift: -4vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 3) {
    --ns-shift: -8vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 4) {
    --ns-shift: -16vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 5) {
    --ns-shift: -24vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 6) {
    --ns-shift: -24vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 7) {
    --ns-shift: -24vw;
}

.is-desktop .navbar-nav>li:nth-child(n + 8) {
    --ns-shift: -24vw;
}

/************************************************************
CHECKOUT TRUST BAR v1 - Marzo 2026
Última modificación: 2026-03-18
************************************************************/

/* CARRITO Y CHECKOUT */

.steps-dark .step-item.active .step-count,
.steps-dark .step-item.active .step-progress {
    background-color: #198754
}

.is-payment .btn-outline-primary {
    color: #198754;
    border-color: #198754;
    background-color: #fff;
    font-weight: 500;
}

.is-payment .btn-outline-primary.active,
.is-payment .btn-outline-primary:hover,
.is-payment .btn-outline-primary:focus {
    color: #fff;
    border-color: #198754;
    background-color: #198754;
}

.ns-checkout-trust-bar {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 1000;
    background: #198754;
    border-radius: 2px;
    padding: 2px;
    text-align: center;
    border-bottom: 1px solid #034018;
}

.ns-checkout-trust-list {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 13px;
    flex-wrap: nowrap;
    letter-spacing: 0.02em;
}

.ns-checkout-trust-main {
    display: flex;
    align-items: center;
    gap: 6px;
    color: #fff;
    font-size: 0.87rem;
    font-weight: 500;
    white-space: nowrap;
}

.ns-checkout-trust-item {
    display: flex;
    align-items: center;
    gap: 5px;
    color: rgba(255, 255, 255, 0.8);
    font-size: 0.8rem;
    font-weight: 400;
    white-space: nowrap;
}

.ns-checkout-trust-sep {
    color: rgba(255, 255, 255, 0.3);
    font-size: 0.9rem;
    line-height: 1;
}

@media (max-width: 575px) {
    .ns-trust-desktop {
        display: none;
    }
}

.is-mobile .ns-checkout-trust-bar {
    padding: 4px 12px;
}

.is-mobile .ns-checkout-trust-main {
    font-size: 0.75rem;
    gap: 4px;
}

.is-checkout .ns-h1-container {
    margin-top: 10px;
}

/************************************************************
LAZY-LOAD v4.3 – 2026-03-30
Autor: Agent UX/UI
Shimmer horizontal sweep + blur-up al cargar imágenes diferidas.
Clases: .ns-lazy → .ns-lazy-loaded | .ns-lazy-error
Modificadores: .ns-lazy-xs | .ns-lazy-sm | .ns-lazy-md | .ns-lazy-lg
************************************************************/

/* Shimmer horizontal sweep (v4.3: skeleton screen moderno, fondo blanco) */
@keyframes ns-lazy-shimmer {
    0% {
        background-position: -400px center;
    }

    100% {
        background-position: 400px center;
    }
}

/* Imagen aún no cargada: oculta con blur sutil */
img.ns-lazy {
    opacity: 0;
    filter: blur(4px);
    -webkit-filter: blur(4px);
    transition: opacity 0.35s ease-out, filter 0.35s ease-out, -webkit-filter 0.35s ease-out;
}

/* Reservar altura mínima en la imagen para evitar CLS */
img.ns-lazy[data-src] {
    min-height: 250px;
    width: auto;
}

/* Shimmer en el PADRE de la imagen:
   opacity:0 en img.ns-lazy oculta backgrounds del propio img,
   pero el fondo del padre sí es visible. El selector :has() se
   deja de aplicar automáticamente cuando JS remueve data-src. */
:has(> img.ns-lazy[data-src]) {
    background: linear-gradient(90deg, #ffffff 25%, #ebebeb 50%, #ffffff 75%);
    background-size: 800px 100%;
    animation: ns-lazy-shimmer 1.4s linear infinite;
    min-height: 60px;
}

/* Fondo aún no cargado */
.ns-lazy-bg {
    opacity: 0;
    transition: opacity 0.4s ease;
}

/* Imagen/fondo ya cargados */
img.ns-lazy-loaded,
.ns-lazy-bg.ns-lazy-loaded {
    opacity: 1;
    filter: none;
    -webkit-filter: none;
    animation: none;
    background: none;
}

/* Estado error: imagen rota con ícono SVG inline */
img.ns-lazy-error {
    opacity: 1;
    filter: none;
    -webkit-filter: none;
    animation: none;
    min-height: 250px;
    background: #f8f8f8 url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='40' height='40' fill='%23ccc' viewBox='0 0 16 16'%3E%3Cpath d='M6.002 5.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0z'/%3E%3Cpath d='M2.002 1a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V3a2 2 0 0 0-2-2h-12zm12 1a1 1 0 0 1 1 1v6.5l-3.777-1.947a.5.5 0 0 0-.577.093l-3.71 3.71-2.66-1.772a.5.5 0 0 0-.63.062L1.002 12V3a1 1 0 0 1 1-1h12z'/%3E%3C/svg%3E") center / 40px no-repeat;
}

/* Reducir motion para usuarios con preferencias de accesibilidad */
@media (prefers-reduced-motion: reduce) {

    img.ns-lazy,
    .ns-lazy-bg {
        transition: none;
        filter: none;
        -webkit-filter: none;
        animation: none;
    }
}

.is-mobile img.ns-lazy-error,
.is-mobile img.ns-lazy[data-src] {
    min-height: 150px;
}

/* ---- Modificadores de tamaño de placeholder -------------------
   Uso: <img class="ns-lazy ns-lazy-xs" data-src="...">
   Sobrescriben el min-height en estado shimmer y error.
   xs  →  60px  (mini_list, thumbnails de sidebar)
   sm  → 120px  (grillas pequeñas, widgets)
   md  → 180px  (intermedio)
   default → 250px / mobile 150px (sin modificador)
   lg  → 350px  (banners, imágenes destacadas)
---------------------------------------------------------------- */
img.ns-lazy-xs[data-src],
img.ns-lazy-xs.ns-lazy-error {
    min-height: 60px;
}

img.ns-lazy-sm[data-src],
img.ns-lazy-sm.ns-lazy-error {
    min-height: 120px;
}

img.ns-lazy-md[data-src],
img.ns-lazy-md.ns-lazy-error {
    min-height: 180px;
}

img.ns-lazy-lg[data-src],
img.ns-lazy-lg.ns-lazy-error {
    min-height: 350px;
}

.is-mobile img.ns-lazy-xs[data-src],
.is-mobile img.ns-lazy-xs.ns-lazy-error {
    min-height: 40px;
}

.is-mobile img.ns-lazy-sm[data-src],
.is-mobile img.ns-lazy-sm.ns-lazy-error {
    min-height: 80px;
}

.is-mobile img.ns-lazy-md[data-src],
.is-mobile img.ns-lazy-md.ns-lazy-error {
    min-height: 120px;
}

.is-mobile img.ns-lazy-lg[data-src],
.is-mobile img.ns-lazy-lg.ns-lazy-error {
    min-height: 220px;
}

/* ================================================================
   PAGO MOBILE SUMMARY v1 - 2026-04-09
   Resumen colapsable de pedido en la etapa de pago (mobile only).
   Visible solo en <lg via d-lg-none en el template.
================================================================ */
.ns-mobile-order-bar {
    cursor: pointer;
    user-select: none;
}

.ns-mobile-order-bar[aria-expanded="true"] .ns-mobile-order-chevron {
    transform: rotate(180deg);
}

.ns-mobile-order-chevron {
    transition: transform 0.25s ease;
    display: inline-block;
}

.ns-mobile-order-detail-item {
    font-size: 0.82rem;
    padding: 4px 0;
    border-bottom: 1px solid #f0f0f0;
}

.ns-mobile-order-detail-item:last-child {
    border-bottom: none;
}

.ns-mobile-order-total {
    font-size: 1.1rem;
    font-weight: 600;
    margin-top: 8px;
    padding-top: 8px;
    border-top: 2px solid #dee2e6;
}

/* ================================================================
   PAGO VISUAL v2 - 2026-04-09
   Logos de pasarelas, trust signals desktop y footer datos.
================================================================ */

#step-3.active .step-count,
#step-3.active .step-progress {
    background-color: #198754 !important
}

/* Logos de pasarelas en headers de accordion */
.ns-pay-logo {
    height: 20px;
    width: auto;
    flex-shrink: 0;
    vertical-align: middle;
    margin-right: 8px;
}

/* Mini logos de tarjetas en header SPS */
.ns-pay-card-logo {
    height: 18px;
    width: auto;
    flex-shrink: 0;
    vertical-align: middle;
    opacity: 0.75;
    margin-right: 3px;
}

/* Label pequeño de sección (reemplaza h2 de accordion) */
.ns-section-label {
    font-size: 0.7rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: #6c757d;
    margin-bottom: 0.375rem;
    margin-top: 0.25rem;
}

/* CTA de pago — azul marino, confianza y conversión */
.btn-cta {
    background-color: #198754;
    border-color: #198754;
    color: #fff;
    font-weight: 500;
}

.btn-cta:hover,
.btn-cta:focus {
    background-color: #157347;
    border-color: #146c43;
    color: #fff;
}

.btn-cta:active {
    background-color: #0f5132;
    border-color: #0f5132;
    color: #fff;
}

/* PAGO accordion header — ocultar subtexto (<small>) en mobile */
@media (max-width: 991.98px) {
    .accordion-header .accordion-button small {
        display: none;
    }
}

/* Resumen del pedido — siempre visible en desktop, colapsable en mobile */
@media (min-width: 992px) {
    .ns-lg-always-show.collapse {
        display: block !important;
    }
}

/* === CHK-016 Payment Method Text Standardization — v1.0 — 2026-04-09 === */
#payment-method .accordion-body {
    font-size: .875rem;
}

/* === CHK-016 Payment Active State — v1.0 — 2026-04-09 === */
/* Refuerzo visual del método de pago seleccionado en el accordion */
#payment-method .accordion-item {
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    position: relative;
}

#payment-method .accordion-item:has(.accordion-button:not(.collapsed)) {
    border-color: rgba(25, 135, 84, 0.6) !important;
    box-shadow: 0 0 0 2px rgba(25, 135, 84, 0.12);
}

#payment-method .accordion-button:not(.collapsed) {
    background-color: rgba(25, 135, 84, 0.05);
}

/* Barra de acento izquierda sobre el item activo */
#payment-method .accordion-item:has(.accordion-button:not(.collapsed))::before {
    content: '';
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 3px;
    background-color: #198754;
    border-radius: 3px 0 0 3px;
}

/* Check icon: oculto por defecto, visible cuando el método está activo */
#payment-method .ns-pay-active-check {
    display: none;
    color: #198754;
    font-size: 1rem;
    line-height: 1;
    margin-left: 0.5rem;
    flex-shrink: 0;
}

#payment-method .accordion-button:not(.collapsed) .ns-pay-active-check {
    display: inline-flex;
    align-items: center;
}

/************************************************************
TOPBAR ROTATOR v1.0.2 – 2026-04-30
Autor: Agent UX/UI
Reemplazo CSS-only del tns-carousel del topbar (Tiny Slider).
Clases: .ns-topbar-rotator, .ns-topbar-rotator-item
Variantes: .ns-topbar-rotator--static (1 solo mensaje)
Doc completa: .claude/walkthrough/2026-04-29_agent-ux-ui-topbar-rotator-v1.0.1.md
************************************************************/

/* Rotador como flex item con altura fija. Items absolutos adentro.
   La altura fija evita que el topbar crezca por contenido apilado y
   garantiza el mismo box centrado para todos los mensajes. */
.ns-topbar-rotator {
    position: relative;
    flex: 1 1 auto;
    min-width: 0;
    align-self: center;
    height: 1.25rem;
    margin: 0;
    overflow: hidden;
    pointer-events: none;
}

/* Cada mensaje ocupa el mismo box del rotador, centrado h/v.
   !important defiende contra .topbar .topbar-text (inline-block).
   Se usa display:block + text-align + line-height para centrar
   sin convertir los hijos (texto, <b>, etc.) en flex items —
   eso colapsaba los espacios alrededor de los tags inline. */
.ns-topbar-rotator .ns-topbar-rotator-item {
    position: absolute !important;
    top: 0 !important;
    right: 0 !important;
    bottom: 0 !important;
    left: 0 !important;
    display: block !important;
    width: auto !important;
    height: 1.25rem !important;
    margin: 0 !important;
    padding: 0 .5rem !important;
    opacity: 0;
    font-size: .875rem;
    font-weight: 600;
    line-height: 1.25rem;
    text-align: center;
    white-space: nowrap;
    text-overflow: ellipsis;
    overflow: hidden;
    pointer-events: none;
    will-change: opacity, transform;
    color: var(--bs-white) !important;
}

/* Variante estática: un único mensaje, siempre visible. */
.ns-topbar-rotator--static .ns-topbar-rotator-item {
    opacity: 1;
}

/* Accesibilidad: si el usuario pidió menos animación, mostramos
   solo el primer mensaje sin transición. */
@media (prefers-reduced-motion: reduce) {
    .ns-topbar-rotator .ns-topbar-rotator-item {
        animation: none !important;
        opacity: 0;
        transform: none !important;
    }

    .ns-topbar-rotator .ns-topbar-rotator-item:first-child {
        opacity: 1;
    }
}

/* === fin TOPBAR ROTATOR v1.0.2 === */

.ns-mobile-logo-store {
    max-height: 40px;
    max-width: 130px;
    /* evita que el logo empuje fuera el toolbar en mobile */
    padding: 0 !important;
    margin: 0 !important;
    width: auto !important;
    height: auto;
    object-fit: contain;
}

/* Pantallas chicas (<=380px): que entren menu + logo + lupita + user + carrito */
@media (max-width: 380px) {
    .ns-mobile-logo-store {
        max-width: 96px;
        max-height: 34px;
    }

    .navbar-sticky>.navbar:first-child .navbar-tool {
        margin-left: .25rem !important;
        margin-right: .25rem !important;
    }

    .navbar-sticky>.navbar:first-child .navbar-toggler {
        padding-right: 0;
        margin-right: .35rem;
    }
}

/* === Sticky header en mobile/tablet (<992px) — 2026-06-01 ===
   El theme Cartzilla solo fija el header en desktop (min-width:992px).
   El JS de Cartzilla agrega .navbar-stuck en todos los anchos y compensa
   el salto con body.paddingTop, pero faltaba el position:fixed para
   viewports chicos. Esto lo agrega sin tocar el vendor (theme.min.css). */
@media (max-width: 991.98px) {
    .navbar-sticky.navbar-stuck {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        z-index: 1030;
        animation: navbar-show .25s;
        box-shadow: 0 .125rem .9375rem -0.0625rem rgba(0, 0, 0, .03),
            0 .275rem 1.25rem -0.0625rem rgba(0, 0, 0, .05);
    }

    /* Header mobile mas bajo: quita el padding vertical (.75rem por defecto)
       de la fila principal del navbar (logo + toolbar/carrito). */
    .navbar-sticky>.navbar:first-child {
        padding-top: 0;
        padding-bottom: 0;
    }

    /* Layout mobile del header: [Menu] [Logo] ....... [Login] [Carrito].
       El boton de menu se reubico en el HTML como primer hijo del contenedor;
       empujamos el toolbar (login+carrito) al extremo derecho. */
    .navbar-sticky>.navbar:first-child>.container {
        justify-content: flex-start;
        /* anula el space-between de Bootstrap */
    }

    .navbar-sticky>.navbar:first-child .navbar-toolbar {
        margin-left: auto;
        /* login + carrito a la derecha */
    }

    .navbar-sticky>.navbar:first-child .navbar-toggler {
        margin-right: .5rem;
        /* separa el menu del logo */
        padding-left: 0;
        /* acerca menu+logo al borde izquierdo (~mitad del hueco) */
    }
}

/* === fin Sticky header mobile === */

/* === MENU MOBILE DRAWER v2.0.0 — 2026-06-10 (UI-013) ===
   Reemplaza MENU MOBILE SCROLL LOCK v1.0.0. El menu mobile (#navbarCollapse,
   collapse de Bootstrap) vive DENTRO del header `position:fixed`; cuando se
   abria como elemento EN FLUJO aparecian dos bugs:
     1) Ultimo item inalcanzable: el `max-height: calc(100dvh - 56px)` usaba un
        `56px` magico que no coincidia con el alto real del header → el fondo
        del contenedor scrolleable quedaba por debajo del viewport.
     2) Salto al top al abrir: el lock de fondo ponia `overflow:hidden` en
        <html>, lo que resetea el scroll a 0 en varios browsers y disparaba el
        scroll handler de cartzilla (navbar-stuck).
   Solucion: el menu abierto se comporta como un DRAWER fijo que ocupa desde
   abajo del header (--ns-menu-top, calculado por NsMobileMenu via JS con el
   alto real del header) hasta el fondo del viewport, con scroll propio.
   - Sin numero magico: --ns-menu-top sale de getBoundingClientRect().
   - Sin tocar el scroll de <html>/<body> → no hay salto al top ni se dispara
     el handler de cartzilla. El drawer es un overlay opaco + overscroll-behavior
     contain (corta el scroll-chaining al fondo).
   Se activa con la clase `ns-menu-drawer` que agrega el JS (progressive
   enhancement: sin JS, el menu sigue funcionando en flujo). */
@media (max-width: 991.98px) {

    #navbarCollapse.ns-menu-drawer.show,
    #navbarCollapse.ns-menu-drawer.collapsing {
        position: fixed;
        top: var(--ns-menu-top, 56px);
        left: 0;
        right: 0;
        bottom: 0;
        height: auto !important;
        /* neutraliza el height inline del collapse de BS */
        margin: 0;
        padding: .25rem 1rem calc(1.75rem + env(safe-area-inset-bottom, 0px));
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        /* inercia iOS */
        overscroll-behavior: contain;
        /* corta el scroll-chaining al fondo */
        background: var(--bs-light, #f6f9fc);
        z-index: 1029;
        /* debajo de la fila 1 del header (1030) */
        box-shadow: inset 0 .5rem .5rem -0.5rem rgba(0, 0, 0, .08);
        transition: none !important;
        /* anula la animacion de height de BS (evita jank/stuck) */
        animation: ns-menu-drawer-in .22s ease-out;
    }
}

@keyframes ns-menu-drawer-in {
    from {
        opacity: 0;
        transform: translateY(-6px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* === fin MENU MOBILE DRAWER === */

/* === HEADER SEARCH COLLAPSE v1.0.0 — 2026-06-10 (UI-013) ===
   Acceso directo a busqueda en mobile: una lupita (.ns-search-toggle) en el
   toolbar del header abre un collapse (#navbarSearchCollapse) con SOLO el
   input de busqueda, independiente del menu de categorias. El buscador dentro
   del menu se conserva. La exclusividad menu<->buscador la maneja NsMobileMenu.
   Solo aplica <992px (la lupita es d-lg-none). */
@media (max-width: 991.98px) {
    .ns-search-collapse .input-group {
        position: relative;
    }

    /* Fix de layout: fuera del contexto .navbar (como si esta el buscador del
       menu), el <form> que genera CakePHP NO se estira y queda a media pantalla,
       con la lupita absoluta cayendo afuera como boton por defecto (recuadro
       gris). Forzamos que el form y el input ocupen el 100% del input-group. */
    .ns-search-collapse .input-group>form {
        flex: 1 1 auto;
        width: 100%;
        min-width: 0;
    }

    .ns-search-collapse .input-group .form-control {
        width: 100%;
    }

    /* La lupita es solo un icono dentro del input: sin recuadro ni fondo. */
    .ns-search-collapse .input-group button.ci-search {
        background: transparent;
        border: 0;
        box-shadow: none;
        -webkit-appearance: none;
        appearance: none;
        padding: 0;
        z-index: 5;
    }

    /* La barra de busqueda entra suave cuando se despliega */
    #navbarSearchCollapse.show .input-group,
    #navbarSearchCollapse.collapsing .input-group {
        animation: ns-search-collapse-in .2s ease-out;
    }

    /* Estado activo de la lupita mientras el buscador esta abierto */
    .ns-search-toggle[aria-expanded="true"] .navbar-tool-icon {
        color: var(--bs-primary, #198754);
    }
}

@keyframes ns-search-collapse-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* === FEATURED CATEGORIES INTERACTION v1.4.0 — 2026-06-10 (UI-014) ===
   Estados de interaccion para los items del carrusel de categorias destacadas
   (#ns-featured-categories-nav .ns-featured-categories-nav-item).
   A) hover/lift de la imagen   B) focus-visible accesible (teclado/WCAG)
   D) nombre de categoria en OVERLAY sobre la imagen.
   v1.4.0: el badge del nombre queda SIEMPRE visible en mobile y desktop (estado
      base opacity:1). El reveal por hover/focus queda como codigo latente (los
      selectores :hover/:focus-visible y el @media hover:none ya no cambian nada).
   v1.2.x: en touch (@media hover:none) el overlay quedaba SIEMPRE visible (ahora
      redundante con el estado base, se conserva inofensivo).
   v1.3.0: estilo del overlay reformado — texto NEGRO en MAYUSCULAS sobre fondo
      blanco-grisado translucido (rgba + backdrop blur) que deja ver la imagen,
      padding comodo y acento border-right 4px negro.
   Solo presentacion: no altera el carrusel tns ni el lazy-load.
   Nota a11y: el overlay es decorativo (aria-hidden); el nombre accesible viene
   del alt de la imagen y del title del enlace. */
.ns-featured-categories-nav-item {
    display: block;
    text-decoration: none;
    color: inherit;
    padding: .35rem;
    border-radius: .85rem;
    outline: none;
    transition: box-shadow .2s ease;
}

.ns-featured-categories-nav-item .ns-fcat-thumb {
    position: relative;
    /* ancla del overlay */
    display: block;
    width: 100%;
    border-radius: .75rem;
    overflow: hidden;
    /* recorta el scale de la imagen y el overlay al borde redondeado */
}

.ns-featured-categories-nav-item .ns-fcat-thumb img {
    display: block;
    max-width: 100%;
    height: auto;
    border-radius: .75rem;
    transition: transform .28s ease;
}

/* A — hover / focus lift */
.ns-featured-categories-nav-item:hover .ns-fcat-thumb img,
.ns-featured-categories-nav-item:focus-visible .ns-fcat-thumb img {
    transform: scale(1.06);
}

.ns-featured-categories-nav-item:hover {
    box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .12);
}

/* B — focus-visible ring (navegacion por teclado) */
.ns-featured-categories-nav-item:focus-visible {
    box-shadow: 0 0 0 3px rgba(25, 135, 84, .45);
}

/* D — overlay del nombre sobre la imagen (oculto por defecto) */
.ns-featured-categories-nav-item .ns-fcat-label {
    position: absolute;
    left: 0;
    /* borde izquierdo del badge pegado al de la imagen */
    right: auto;
    /* el fondo se ajusta al ancho del texto, no al card */
    bottom: 15px;
    /* despegado 15px del fondo de la imagen */
    width: auto;
    max-width: 100%;
    /* no desborda la card con nombres largos */
    padding: .35rem .6rem;
    /* fondo blanco grisado translucido: deja ver la imagen detras pero da
       legibilidad al texto negro. blur opcional (degrada a solo-rgba). */
    background: rgba(245, 245, 245, .78);
    -webkit-backdrop-filter: blur(3px);
    backdrop-filter: blur(3px);
    color: #000;
    text-transform: uppercase;
    font-size: .95rem;
    /* +2px respecto de v1.3.0 (.75rem) */
    font-weight: 700;
    letter-spacing: .02em;
    line-height: 1.2;
    text-align: left;
    border-right: 4px solid #000;
    /* acento a la derecha */
    /* v1.4.0: badge SIEMPRE visible (mobile y desktop). Para volver al reveal
       por hover, restaurar: opacity:0 + transform:translateY(100%). */
    opacity: 1;
    transform: translateY(0);
    transition: opacity .25s ease, transform .25s ease;
    pointer-events: none;
    /* el click pasa al enlace */
}

.ns-featured-categories-nav-item:hover .ns-fcat-label,
.ns-featured-categories-nav-item:focus-visible .ns-fcat-label {
    opacity: 1;
    transform: translateY(0);
}

@media (prefers-reduced-motion: reduce) {

    .ns-featured-categories-nav-item .ns-fcat-thumb img,
    .ns-featured-categories-nav-item .ns-fcat-label {
        transition: none;
    }

    .ns-featured-categories-nav-item:hover .ns-fcat-thumb img,
    .ns-featured-categories-nav-item:focus-visible .ns-fcat-thumb img {
        transform: none;
    }

    /* el overlay aparece sin deslizamiento, solo fade instantaneo */
    .ns-featured-categories-nav-item .ns-fcat-label {
        transform: none;
    }
}

/* D (mobile) — en dispositivos sin :hover real (touch) el overlay del nombre
   queda SIEMPRE visible: en mobile no hay puntero que lo dispare. */
@media (hover: none) {
    .ns-featured-categories-nav-item .ns-fcat-label {
        opacity: 1;
        transform: translateY(0);
    }

    /* anula el "sticky hover" del scale al tocar: en touch no aporta y queda pegado */
    .ns-featured-categories-nav-item:hover .ns-fcat-thumb img {
        transform: none;
    }
}

/* === fin FEATURED CATEGORIES INTERACTION === */
/* === fin HEADER SEARCH COLLAPSE === */

/* =========================================================================
   STAFF / TEAM  ·  v1.0.0  ·  2026-06-24  ·  ux-ui-specialist (claude-opus-4-8)
   Listado del equipo (Staff/cartzilla/index.ctp) + ficha (view.ctp).
   Relanzamiento del modulo Staff 13.07.0. Mobile-first. Prefijo .ns-staff-*
   Acento del theme via var(--bs-primary).
   ========================================================================= */

.ns-staff-intro {
    max-width: 720px;
    margin: 0 auto;
}

/* ---- Card del listado ---- */
.ns-staff-card {
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 1.5rem 1rem;
    background: #fff;
    border: 1px solid #e9ecef;
    border-radius: 1rem;
    transition: transform .25s ease, box-shadow .25s ease, border-color .25s ease;
}

.ns-staff-card:hover,
.ns-staff-card:focus-within {
    transform: translateY(-4px);
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .10);
    border-color: transparent;
}

/* ---- Avatar ---- */
.ns-staff-avatar {
    position: relative;
    width: 112px;
    height: 112px;
    margin-bottom: 1rem;
    border-radius: 50%;
    overflow: hidden;
    background: #f1f3f5;
    box-shadow: 0 0 0 4px #fff, 0 0 0 5px #e9ecef;
    transition: box-shadow .25s ease;
}

.ns-staff-card:hover .ns-staff-avatar,
.ns-staff-card:focus-within .ns-staff-avatar {
    box-shadow: 0 0 0 4px #fff, 0 0 0 5px var(--bs-primary, #fe696a);
}

.ns-staff-avatar img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ns-staff-avatar-fallback {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 2.25rem;
    font-weight: 600;
    color: #fff;
    background: linear-gradient(135deg, #6c7ae0, var(--bs-primary, #fe696a));
    text-transform: uppercase;
}

/* ---- Texto ---- */
.ns-staff-name {
    margin-bottom: .15rem;
    font-size: 1.05rem;
}

.ns-staff-nick {
    display: block;
    font-size: .8rem;
    color: #9da3ae;
    margin-bottom: .35rem;
}

.ns-staff-role {
    display: inline-block;
    font-size: .78rem;
    font-weight: 600;
    color: var(--bs-primary, #fe696a);
    text-transform: uppercase;
    letter-spacing: .02em;
    margin-bottom: .5rem;
}

.ns-staff-loc {
    font-size: .78rem;
    color: #9da3ae;
    margin-bottom: .65rem;
}

.ns-staff-desc {
    font-size: .82rem;
    color: #6c757d;
    margin-bottom: .9rem;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ---- Social ---- */
.ns-staff-social {
    position: relative;
    z-index: 2;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .4rem;
    margin-top: auto;
}

.ns-staff-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    color: #6c757d;
    background: #f1f3f5;
    font-size: .95rem;
    line-height: 1;
    transition: color .2s ease, background-color .2s ease, transform .2s ease;
}

.ns-staff-social a:hover,
.ns-staff-social a:focus-visible {
    color: #fff;
    background: var(--bs-primary, #fe696a);
    transform: translateY(-2px);
}

/* enlace que cubre la card (Ver perfil) sin tapar los iconos sociales */
.ns-staff-stretch::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1;
    border-radius: inherit;
}

/* ---- Ficha de integrante (view.ctp) ---- */
.ns-staff-profile-head {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: .3rem;
    margin-bottom: 2rem;
}

.ns-staff-profile-avatar {
    width: 150px;
    height: 150px;
    border-radius: 50%;
    overflow: hidden;
    background: #f1f3f5;
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .12), 0 0 0 5px #fff;
    margin-bottom: .75rem;
}

.ns-staff-profile-avatar img,
.ns-staff-profile-avatar .ns-staff-avatar-fallback {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.ns-staff-profile-role {
    font-size: .85rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .03em;
    color: var(--bs-primary, #fe696a);
}

.ns-staff-profile-social {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .5rem;
    margin-top: .5rem;
}

.ns-staff-bio {
    max-width: 760px;
    margin: 0 auto;
    line-height: 1.7;
}

/* ---- Galeria ---- */
.ns-staff-gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: .75rem;
}

@media (min-width: 576px) {
    .ns-staff-gallery {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (min-width: 992px) {
    .ns-staff-gallery {
        grid-template-columns: repeat(4, 1fr);
    }
}

.ns-staff-gallery-item {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    border-radius: .75rem;
    overflow: hidden;
    background: #f1f3f5;
}

.ns-staff-gallery-item img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .35s ease;
}

.ns-staff-gallery-item:hover img,
.ns-staff-gallery-item:focus-visible img {
    transform: scale(1.06);
}

@media (prefers-reduced-motion: reduce) {

    .ns-staff-card,
    .ns-staff-avatar,
    .ns-staff-social a,
    .ns-staff-gallery-item img {
        transition: none;
    }

    .ns-staff-card:hover,
    .ns-staff-card:focus-within {
        transform: none;
    }

    .ns-staff-gallery-item:hover img {
        transform: none;
    }
}

/* === fin STAFF / TEAM === */

/* CSS REVIEW ITEMS
    Pagina donde se visualizan todas las valoraciones de los productos.
*/

#ns-reviews-header {
    background: #333;
}

/* ===================================================================
   FICHA DE PRODUCTO — ajustes v1.0.0 (2026-07-06)
   a) Botón compartir por WhatsApp (arriba, junto a favoritos, solo ícono)
   b) Mensaje C2A (ns-cart-c2a-txt) centrado y con padding balanceado
   c) Badge de puntos (ns-badge-points) en la línea estética de beneficios
      pero con acento dorado (sin el verde de "envío gratis")
   Mobile-first.
   =================================================================== */

/* Contenedor de acciones (compartir + favoritos) a la derecha de reviews */
.ns-item-actions {
    gap: 6px;
}

/* a) Ícono compartir por WhatsApp — mismo tamaño/forma que .btn-wishlist */
.ns-item-share-wa {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    flex: 0 0 auto;
    border-radius: 50%;
    background-color: #f3f5f9;
    color: #373f50;
    font-size: 1.0625rem;
    line-height: 1;
    text-decoration: none;
    transition: color .2s ease-in-out, background-color .2s ease-in-out, box-shadow .2s ease-in-out;
}

.ns-item-share-wa:hover,
.ns-item-share-wa:focus {
    background-color: #25d366;
    color: #fff;
    text-decoration: none;
}

.ns-item-share-wa:focus-visible {
    outline: 0;
    box-shadow: 0 0 0 3px rgba(37, 211, 102, .35);
}

/* b) Mensaje C2A ("¡ Últimas X unidades disponibles !", etc.)
      Centrado, con padding vertical balanceado y estética de "aviso" sutil. */
#ns-cart-c2a-txt {
    display: block;
    margin: 0;
    padding: 11px 14px;
    text-align: center;
    line-height: 1.35;
    font-size: 13px;
    font-weight: 600;
    color: var(--ns-cupon-hot);
    background: rgba(217, 72, 15, .07);
    border: 1px solid rgba(217, 72, 15, .18);
    border-radius: 10px;
}

#ns-cart-c2a-txt b,
#ns-cart-c2a-txt strong {
    font-weight: 800;
}

/* c) Badge de puntos — misma caja que "envío gratis" pero acento dorado */
.ns-badge-points {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 11px 14px;
    border: 1px solid var(--ns-cupon-border);
    border-radius: 10px;
    background: #fff;
    color: var(--ns-cupon-ink);
    text-decoration: none;
}

.ns-badge-points .ns-beneficio-ico {
    background: #f0a500;
    color: #fff;
}

.ns-badge-points b {
    color: #b45309;
}

/* d) Calculadora de envío — input (floating label) + botón en fila, sin solaparse.
      Reemplaza el layout `d-inline w-75` + botón con margin-top negativo (rompía en mobile). */
.ns-calc-envio-field {
    min-width: 0;            /* permite que el input encoja dentro del flex en mobile */
}

.ns-calc-envio-btn {
    flex: 0 0 auto;
    white-space: nowrap;
    align-self: stretch;     /* misma altura que el input con floating label */
}

/* e) Zona CTA (Agregar / Comprar ahora) — mismo ritmo vertical (10px) que los
      beneficios de abajo y la info de producto. Reemplaza el `mb-grid-gutter` del
      form (gap grande) y los mb-2/mb-3 dispares por un espaciado uniforme. */
.ns-cta-form {
    margin-bottom: 0;
}

.ns-cta-item {
    margin-bottom: 10px;     /* separación Agregar → Comprar ahora */
}

.ns-cta-item-end {
    margin-bottom: 0;        /* la separación con los beneficios la da .ns-beneficios (margin-top 10px) */
}

/* =====================================================================
   ITEM LIST CAROUSEL — CONTROLS SOBRE LA FOTO  ·  v1.0.0 · 2026-07-21
   Sube las flechas prev/next del carrusel de artículos (related_carousel)
   para que queden sobre la imagen del producto y no sobre el título,
   precios y oferta que se muestran debajo de la foto (donde molestaban
   para la lectura). El theme las posiciona en top:50% del carrusel
   completo (foto + descripción); acá las anclamos al tercio superior,
   que coincide con la foto. Scoped a .ns-item-list para no afectar
   otros carruseles del theme.
   ===================================================================== */
.ns-item-list .tns-carousel.tns-controls-outside [data-controls] {
    top: 30%;
}

/* En mobile la card es más alta (más texto de cuotas/beneficios debajo
   de la foto), así que subimos un poco más las flechas para mantenerlas
   claramente sobre la imagen. */
@media (max-width: 767.98px) {
    .ns-item-list .tns-carousel.tns-controls-outside [data-controls] {
        top: 26%;
    }
}

/* =====================================================================
   CHECKOUT — DESGLOSE DE DESCUENTOS COLAPSABLE  ·  v1.0.0 · 2026-08-11
   Resumen de la orden (Elements/cartzilla/checkout/order_details.ctp).
   Cuando hay varios conceptos de descuento (canje de puntos, crédito y
   otros descuentos de producto), el desglose ensuciaba el resumen y
   competía visualmente con el total. Ahora el detalle vive dentro de un
   collapse de Bootstrap (`#nsDiscountDetail`), **cerrado por defecto**, y
   la fila "Descuentos" hace de disparador.
   La animación de apertura la aporta el propio `.collapsing` de Bootstrap
   (que ya respeta prefers-reduced-motion); acá sólo se define el estilo
   del disparador, la flecha y la lista anidada.
   ===================================================================== */

/* Disparador: botón sin cromo, se lee igual que las otras filas de la lista
   (Subtotal, Envío, IVA). Ocupa la fila ENTERA — etiqueta, flecha y monto
   viven adentro — así el clic sobre el importe también abre el desglose.

   El `width` es OBLIGATORIO, no redundante: los controles de formulario
   usan ancho shrink-to-fit aunque se les declare `display: flex`, así que
   sin él el botón se encoge al contenido, el `space-between` no tiene
   sobrante que repartir y el monto queda pegado a la etiqueta en vez de
   alinearse con la columna de importes.

   El desborde (--ns-disc-bleed) agranda la zona de clic y el realce del
   hover hacia ambos lados: el `padding` compensa exactamente al `margin`
   negativo, así que el texto sigue alineado con los otros <li> y el ancho
   suma los dos desbordes para no quedar corrido. Los tres valores se
   derivan de la misma variable justamente para que no se desincronicen. */
.ns-disc-toggle {
    --ns-disc-bleed: .35rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    width: calc(100% + var(--ns-disc-bleed) * 2);
    padding: .15rem var(--ns-disc-bleed);
    margin: -.15rem calc(var(--ns-disc-bleed) * -1);
    border: 0;
    border-radius: .25rem;
    background: none;
    font: inherit;
    color: inherit;
    text-align: left;
    cursor: pointer;
    transition: background-color .15s ease;
}

/* El subrayado punteado y la flecha son la única señal de que es
   interactivo: sin bordes ni fondo en reposo. */
.ns-disc-label {
    display: inline-flex;
    align-items: center;
    gap: .3rem;
    text-decoration: underline dotted rgba(0, 0, 0, .3);
    text-underline-offset: 3px;
}

/* El realce va sobre la fila completa, que es lo que ahora se puede
   clickear. El monto conserva su color (`.ns-price` lo fija aparte). */
.ns-disc-toggle:hover,
.ns-disc-toggle:focus-visible {
    background-color: rgba(125, 135, 156, .12);
}

.ns-disc-toggle:hover .ns-disc-label,
.ns-disc-toggle:focus-visible .ns-disc-label {
    color: var(--bs-primary);
    text-decoration-color: currentColor;
}

.ns-disc-toggle:focus-visible {
    outline: 2px solid var(--bs-primary);
    outline-offset: 1px;
}

/* Flecha: gira 180° cuando el collapse está abierto. Bootstrap mantiene
   `aria-expanded` en el disparador, así que no hace falta JS propio. */
.ns-disc-caret {
    font-size: .625rem;
    opacity: .65;
    transition: transform .25s ease;
}

.ns-disc-toggle[aria-expanded="true"] .ns-disc-caret {
    transform: rotate(180deg);
    opacity: 1;
}

/* Lista anidada del desglose: indentada con una guía a la izquierda en
   lugar de los &nbsp; que se usaban antes, y tipografía menor para que el
   total siga siendo la línea dominante.
   El color se mantiene en el del cuerpo (--bs-gray-700) y NO se baja al
   gris "muted" del theme (--bs-gray-600, #7d879c): a 13px ese gris da
   3,61:1 sobre blanco y no llega al 4,5:1 que pide WCAG AA para texto
   normal. La jerarquía la dan el tamaño, la sangría y la guía. */
.ns-disc-detail > ul {
    margin: .25rem 0 .35rem;
    padding-left: .75rem;
    border-left: 2px solid rgba(125, 135, 156, .35);
    font-size: .8125rem;
    color: var(--bs-gray-700, #4b566b);
}

.ns-disc-detail > ul > li + li {
    margin-top: .15rem;
}

@media (prefers-reduced-motion: reduce) {
    .ns-disc-toggle,
    .ns-disc-caret {
        transition: none;
    }
}
/* ============================================================================
   PLUGIN SWATCHES — Preview de variantes en el listado          v1.0.0
   Feature #38 · UI-023 · .claude/docs/ideas/preview-variantes-listado-plan.md

   Muestra los colores o talles CON STOCK de cada producto en la card del
   listado. Mobile-first, sin JS y sin dependencias.

   Anatomía:
     .ns-swatches            contenedor (fila)
       .ns-swatches-track    pista scrolleable en horizontal
         .ns-swatch          una variante: --img | --hexa | --txt
       .ns-swatches-more     contador "+N", FUERA del scroll (siempre visible)

   ⚠ EL FADE DE LA DERECHA SE AUTORREGULA, no hace falta JS ni una clase extra.
   El track es `flex: 1 1 auto` con `min-width: 0`: cuando los swatches entran,
   crece hasta el ancho disponible y la máscara cae sobre espacio vacío (no se
   ve); cuando desbordan, se limita al contenedor y la máscara desvanece el
   último visible, que es la pista de "seguí deslizando". Un navegador sin
   soporte de `mask-image` simplemente no muestra el fade: todo lo demás anda.

   ⚠ Los swatches NO son interactivos (ver el comentario del element): no llevan
   cursor de mano ni estados de hover que prometan un clic que no existe.
   ============================================================================ */

.ns-swatches {
    display: flex;
    align-items: center;
    gap: .375rem;
    min-width: 0;
    margin: .35rem 0 .1rem;
}

.ns-swatches-track {
    display: flex;
    align-items: center;
    gap: .3125rem;
    flex: 1 1 auto;
    min-width: 0; /* sin esto el flex item no se encoge y nunca hay overflow */
    margin: 0;
    /* El padding vertical NO es decorativo: `overflow-y:hidden` recorta, y el
       swatch bajo hover crece a scale(1.14) y proyecta sombra. Sin este colchón,
       el círculo agrandado se ve cortado arriba y abajo. */
    padding: 4px 0;
    list-style: none;
    overflow-x: auto;
    overflow-y: hidden;
    scroll-snap-type: x proximity;
    overscroll-behavior-x: contain; /* que el final del track no dispare el gesto "atrás" */
    -webkit-overflow-scrolling: touch; /* inercia en iOS < 13 */
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* Edge legacy */
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 14px), transparent 100%);
    mask-image: linear-gradient(to right, #000 calc(100% - 14px), transparent 100%);
}

.ns-swatches-track::-webkit-scrollbar {
    width: 0;
    height: 0;
    display: none;
}

/* [2026-08-18] Miniaturas un punto más grandes (22→26px mobile, 28→34px desde md):
   pedido del desarrollador. El colchón vertical del track (padding 4px) sigue alcanzando
   para el scale(1.14) del hover: 34 × 1.14 = 38,8px, o sea 2,4px de desborde por lado. */
.ns-swatch {
    flex: 0 0 auto;
    scroll-snap-align: start;
    width: 1.625rem;
    height: 1.625rem;
    border-radius: 50%;
    overflow: hidden;
    background-color: #fff;
    /* Borde por sombra interna: no altera la caja y se ve sobre cualquier color,
       incluido un blanco legítimo sobre fondo blanco. */
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .16);
}

/* Sólo los swatches que PUEDEN cambiar la portada se comportan como interactivos.
   El `[data-ns-img]` lo pone el element únicamente en el carril foto: un talle no
   tiene imagen propia, y un hexa existe justamente porque a esa variante le falta
   la foto. Sin este selector, el cursor prometería un efecto que no va a pasar. */
.ns-swatch[data-ns-img] {
    cursor: pointer;
    transition: transform .15s ease, box-shadow .15s ease;
}

.ns-swatch[data-ns-img]:hover,
.ns-swatch[data-ns-img]:focus-visible {
    transform: scale(1.14);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .28), 0 2px 6px rgba(0, 0, 0, .2);
}

.ns-swatch--img img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Bicolor: los colores de la tabla `colores` pueden traer hexa1 + hexa2. Cuando
   son iguales el resultado es un color plano, así que una sola regla cubre los
   dos casos. */
.ns-swatch--hexa {
    background-image: linear-gradient(135deg, var(--ns-sw-a) 0 50%, var(--ns-sw-b) 50% 100%);
}

/* Talles (y colores sin foto ni hexa): pastilla con la etiqueta corta. */
.ns-swatch--txt {
    display: flex;
    align-items: center;
    justify-content: center;
    width: auto;
    min-width: 1.875rem;
    height: 1.625rem;
    padding: 0 .35rem;
    border-radius: .25rem;
    font-size: .6875rem;
    line-height: 1;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .01em;
    color: var(--bs-gray-700, #4b566b);
    background-color: var(--bs-gray-100, #f6f9fc);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12);
}

.ns-swatches-more {
    flex: 0 0 auto;
    font-size: .6875rem;
    line-height: 1;
    font-weight: 600;
    color: var(--bs-gray-600, #7d879c);
    white-space: nowrap;
}

/* Desde `md` hay más ancho disponible por card: swatches un punto más grandes,
   que es donde mejor se lee una miniatura de producto.
   El corte es `md` (768) y NO `sm`: cartzilla redefine `sm` a 500px, y un
   celular apaisado mide 667-930px. */
@media (min-width: 768px) {

    .ns-swatch {
        width: 2.125rem;
        height: 2.125rem;
    }

    .ns-swatch--txt {
        width: auto;
        min-width: 2.375rem;
        height: 2.125rem;
        font-size: .75rem;
    }

    .ns-swatches-more {
        font-size: .8125rem;
    }

}

/* ── Cambio de portada al pasar el mouse por un swatch de color ───────────────
   Lo dispara `js/nubixstore/plugins/ns-swatches.js`, que reemplaza el `src` de la
   foto de la card y pone esta clase. El destello evita que el cambio se lea como
   un parpadeo o un error de carga: la nueva foto entra desde translúcida y con un
   punto de brillo de más, así el ojo la registra como una transición y no como un
   salto. La animación se auto-reinicia en cada cambio (el JS fuerza un reflow),
   para que pasar rápido de un color a otro vuelva a animar. */
.ns-swatch-flashing {
    animation: ns-swatch-flash .45s ease-out;
}

@keyframes ns-swatch-flash {
    0% {
        opacity: .3;
        filter: brightness(1.35);
        transform: scale(1.02);
    }
    50% {
        opacity: 1;
    }
    100% {
        opacity: 1;
        filter: none;
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {

    .ns-swatch[data-ns-img] {
        transition: none;
    }

    .ns-swatch[data-ns-img]:hover,
    .ns-swatch[data-ns-img]:focus-visible {
        transform: none;
    }

    /* La foto sigue cambiando ( es información, no decoración ); lo que se quita
       es el destello. */
    .ns-swatch-flashing {
        animation: none;
    }

}

/* ============================================================================
   BREADCRUMB EN UNA SOLA LÍNEA — scroll horizontal en mobile        v1.0.0
   UI-026 · 2026-08-18 · Elements/cartzilla/breadcrumb.ctp (.ns-breadcrumb-scroll)

   Antes la miga envolvía a dos o tres renglones en mobile y empujaba el H1 hacia
   abajo. Ahora es una pista de scroll: los ítems no envuelven nunca y, si no
   entran, se arrastran con el dedo.

   El corte es `lg` (992) porque el markup ya trae `flex-lg-nowrap`: de ahí para
   arriba el breadcrumb no envolvía y no hay nada que arreglar. Y NO es `sm`,
   porque cartzilla redefine `sm` a 500px (mismo criterio que `.ns-swatches`).

   Sin máscara de fade a propósito: el último ítem suele ser el nombre del
   producto y una máscara fija lo dejaría desvanecido incluso con el scroll al
   final, que se lee como un error de render. El recorte del ítem contra el borde
   del contenedor ya es la pista de que hay más para deslizar.
   ============================================================================ */

@media (max-width: 991.98px) {

    .ns-breadcrumb-scroll {
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch; /* inercia en iOS < 13 */
        overscroll-behavior-x: contain; /* que el final del track no dispare el gesto "atrás" */
        scrollbar-width: none; /* Firefox */
        -ms-overflow-style: none; /* Edge legacy */
    }

    .ns-breadcrumb-scroll::-webkit-scrollbar {
        width: 0;
        height: 0;
        display: none;
    }

    /* Los ítems no se encogen. Sin esto flex les recorta el ancho para que "entren"
       en el contenedor y el texto vuelve a partirse en dos renglones adentro de
       cada ítem, que es exactamente lo que se quiere evitar. */
    .ns-breadcrumb-scroll > .breadcrumb-item {
        flex: 0 0 auto;
        white-space: nowrap;
    }

}
