/**
 * SR - Producto Swatches
 * Estilos frontend - Diseño moderno con paleta personalizada
 * Version: 6.13.1
 */

/* ========================================
   TOKENS DE COLOR PROPIOS (v6.10.42)
   ----------------------------------------
   Gama CÁLIDA, intencionadamente DISTINTA de la paleta fría de UI
   (--neutral / --verde / --amarillo). Los badges de precio y el hover del
   item usan colores alineados con la marca (fondo neutro ~ crema de marca;
   estado activo en ámbar suave; "incluido" en verde propio). Se exponen como
   tokens --sr-ps-* para poder tematizarlos sin tocar el plugin; los valores
   por defecto preservan EXACTAMENTE el diseño actual.
   IMPORTANTE: NO son la paleta de UI. No migrar a --verde/--amarillo/--neutral
   (cambiaría el aspecto y rompería la coherencia con la marca).
   ======================================== */
:root {
    /* Badge de precio — neutro (estado por defecto) */
    --sr-ps-price-text: #444441;
    --sr-ps-price-bg: #F1EFE8;
    /* Badge de precio — activo / seleccionado (ámbar suave) */
    --sr-ps-price-active-text: #92400E;
    --sr-ps-price-active-bg: #FEF3C7;
    /* Badge de precio — tapizado (pill verde bajo el swatch) */
    --sr-ps-price-below-text: #0F6E56;
    --sr-ps-price-below-bg: #E1F5EE;
    /* Badge de precio — "incluido" (verde sutil, sin relleno) */
    --sr-ps-price-included-text: #1D9E75;
    /* Hover del item de lista (tinte cálido, pareja de --brand-primary-alt) */
    --sr-ps-item-hover-bg: #fffdf5;
}

/* ========================================
   CONTENEDOR GENERAL
   ======================================== */

.sr-ps-swatches-wrapper {
    margin-bottom: 1rem;
    /* Aísla reflow/repaint del swatch del resto de la página.
       Solo layout+style (NO size/paint: los grids con scroll
       horizontal necesitan que el contenido pueda desbordar). */
    contain: layout style;
}

.sr-ps-hidden-select {
    display: none !important;
}

/* ========================================
   UTILITY: Visualmente oculto pero accesible
   Técnica estándar a11y: visible para screen readers,
   crawlers e indexadores, oculto para usuarios visuales.
   No es "cloaking" — el contenido es legítimo y coincide
   con el visible (etiquetas, nombres de variantes).
   ======================================== */

.sr-ps-visually-hidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}

/* ========================================
   CONTENEDOR MODERNO
   ======================================== */

/*
 * HOOK DE EXTENSIÓN: .sr-ps-no-header
 * El PHP añade esta clase al wrapper cuando el admin desactiva el
 * encabezado del atributo. No tiene estilos propios por defecto
 * (el header simplemente no se renderiza), pero queda disponible
 * como punto de targeting para CSS personalizado. Ejemplo:
 *   .sr-ps-swatches-wrapper.sr-ps-no-header { margin-top: 0; }
 */

.sr-ps-swatches-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 0.375rem;
}

/* Header del inline-only: compacto, sin background pesado */
.sr-ps-swatches-inline-only .sr-ps-swatches-header {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    min-height: 0;
}

/* Título en inline-only: texto plano, no badge */
.sr-ps-swatches-inline-only .sr-ps-swatches-title {
    background: transparent;
    padding: 0;
    color: var(--neutral-500, #6B7280);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0;
}

/* Label del seleccionado en inline-only: prominente y moderno */
.sr-ps-swatches-inline-only .sr-ps-selected-label {
    color: var(--neutral-900, #111827);
    font-size: 0.8125rem;
    font-weight: 600;
    letter-spacing: -0.01em;
}

/* Contador "X colores" - decorativo, no interactivo */
.sr-ps-swatches-count {
    margin-left: auto;
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--neutral-500, #6B7280);
    line-height: 1.4;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    letter-spacing: 0;
    cursor: default;
    user-select: none;
}

.sr-ps-step-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.75rem;
    height: 1.375rem;
    padding: 0 0.375rem;
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--neutral-0, #fff);
    background-color: var(--neutral-700, #374151);
    border-radius: 4px;
    letter-spacing: 0.02em;
}

.sr-ps-swatches-title {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--neutral-1000, #000);
    text-transform: none;
    letter-spacing: 0;
    padding: 0 8px;
    background: var(--neutral-100, #F3F4F6);
    border-radius: 4px;
}

.sr-ps-selected-label {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--neutral-500, #6B7280);
}

/* ========================================
   TOOLTIP MINIMALISTA
   ======================================== */

.sr-ps-tooltip-wrapper {
    position: relative;
    display: inline-flex;
    align-items: center;
}

/* Modo "texto directo": la ayuda del atributo siempre visible, en
   gris tenue, ocupando su propia línea bajo el título. Sin icono ni
   interacción — cero fricción y mejor SEO/LLM (texto siempre en DOM).
   flex-basis:100% hace que caiga a una línea propia dentro del header
   flex (el header tiene flex-wrap en móvil; en desktop se fuerza el
   salto con el basis completo). */
.sr-ps-help-text {
    flex-basis: 100%;
    width: 100%;
    margin-top: 0.25rem;
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.45;
    color: var(--neutral-500, #6B7280);
}

.sr-ps-tooltip-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 16px;
    height: 16px;
    color: var(--neutral-400, #9CA3AF);
    cursor: help;
    transition: color 0.2s ease;
    /* En móvil: hacer clickable */
    -webkit-tap-highlight-color: transparent;
}

.sr-ps-tooltip-icon svg {
    width: 100%;
    height: 100%;
}

.sr-ps-tooltip-wrapper:hover .sr-ps-tooltip-icon,
.sr-ps-tooltip-wrapper.sr-ps-tooltip-open .sr-ps-tooltip-icon {
    color: var(--neutral-600, #4B5563);
}

.sr-ps-tooltip-content {
    position: absolute;
    left: calc(100% + 10px);
    top: 50%;
    transform: translateY(-50%);
    min-width: 180px;
    max-width: 260px;
    padding: 0.6875rem 0.875rem;
    font-size: 0.75rem;
    font-weight: 400;
    line-height: 1.55;
    color: var(--neutral-800, #1F2937);
    background-color: var(--neutral-100, #F3F4F6);
    border: 1px solid var(--neutral-200, #E5E7EB);
    border-radius: 10px;
    box-shadow: 0 4px 16px rgba(17, 24, 39, 0.08),
                0 1px 3px rgba(17, 24, 39, 0.06);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease, visibility 0.18s ease;
    z-index: 1000;
    text-align: left;
    pointer-events: none;
}

/* Flecha: cuadrado rotado para que tenga el mismo borde + fondo que
   la burbuja (un border-triangle no admite borde de 1px coherente). */
.sr-ps-tooltip-content::after {
    content: '';
    position: absolute;
    right: 100%;
    top: 50%;
    width: 9px;
    height: 9px;
    transform: translate(50%, -50%) rotate(45deg);
    background-color: var(--neutral-100, #F3F4F6);
    border-left: 1px solid var(--neutral-200, #E5E7EB);
    border-bottom: 1px solid var(--neutral-200, #E5E7EB);
    border-top: 0;
    border-right: 0;
}

.sr-ps-tooltip-wrapper:hover .sr-ps-tooltip-content,
.sr-ps-tooltip-wrapper.sr-ps-tooltip-open .sr-ps-tooltip-content {
    opacity: 1;
    visibility: visible;
}

/* Móvil: el tooltip FLOTA por encima (no desplaza ni reserva espacio
   en el flujo) y aparece HACIA ARRIBA, a lo ancho del contenedor del
   swatch. Como en la práctica los swatches con tooltip se ubican en
   posiciones con espacio libre por encima, abrir hacia arriba nunca
   tapa un control relevante y, al ser absolute, al cerrarse no deja
   hueco (no hay salto de layout). Ancla = .sr-ps-swatches-container
   (relative) para lograr el ancho completo del swatch. Mantiene el
   estilo gris premium de la base. Reutiliza .sr-ps-tooltip-open del
   JS; sin JS nuevo, sin tocar HTML/PHP. Desktop conserva la burbuja
   lateral (ahí funciona bien, hay espacio). */
@media (max-width: 767px) {
    /* El contenedor del swatch es el ancla de posicionamiento: así el
       tooltip puede ocupar TODO su ancho aunque el icono sea estrecho. */
    .sr-ps-swatches-container {
        position: relative;
    }

    /* El wrapper deja de ser ancla (si fuese relative, el content se
       anclaría al icono estrecho en vez de al contenedor ancho). */
    .sr-ps-tooltip-wrapper {
        position: static;
    }

    .sr-ps-tooltip-content {
        position: absolute;
        left: 0;
        right: 0;
        /* Hacia ARRIBA: el borde inferior del tooltip queda justo
           sobre el borde superior del contenedor del swatch, con un
           pequeño aire. No empuja nada (absolute) y no deja hueco al
           cerrarse. */
        bottom: calc(100% + 8px);
        top: auto;
        width: auto;
        min-width: 0;
        max-width: none;
        margin: 0;
        transform: none;
        /* Cerrado: oculto sin reservar espacio. Abierto: visible.
           Se mantiene la transición de opacidad de la base. */
    }

    /* Flecha apuntando hacia ABAJO (hacia el icono que lo dispara),
       en el borde inferior del tooltip. Cuadrado rotado con la misma
       piel (fondo+borde) que la burbuja, coherente con desktop. */
    .sr-ps-tooltip-content::after {
        display: block;
        right: auto;
        left: 18px;            /* alineada bajo la zona del icono */
        top: 100%;
        bottom: auto;
        transform: translate(0, -50%) rotate(45deg);
        border-left: 0;
        border-bottom: 0;
        border-right: 1px solid var(--neutral-200, #E5E7EB);
        border-top: 1px solid var(--neutral-200, #E5E7EB);
    }
}

/* ========================================
   GRID 2 COLUMNAS
   ======================================== */

.sr-ps-swatches-grid {
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
    contain: layout style;
}

.sr-ps-swatches-grid li {
    margin: 0;
    padding: 0;
    /* WPO: el navegador omite el render de los items fuera del viewport
       hasta que se acercan (gran ahorro con muchos colores). Solo en el
       grid VERTICAL de buttons — NO en los carruseles horizontales
       (inline-grid), donde colapsar items rompería scroll-snap y el
       cálculo de anchos. 'auto 56px' reserva el alto típico de un item
       de una línea para no provocar CLS; el navegador memoriza el real
       tras medirlo una vez. */
    content-visibility: auto;
    contain-intrinsic-size: auto 56px;
}

/* ========================================
   ITEMS - ESTILO CARD MODERNO
   ======================================== */

.sr-ps-swatch-list-item {
    display: flex;
    align-items: flex-start;
    width: 100%;
    height: 100%;
    padding: 0.875rem;
    background-color: var(--neutral-50, #F9FAFB);
    border: 2px solid var(--neutral-100, #F3F4F6);
    border-radius: 6px;
    cursor: pointer;
    transition: background-color 0.2s ease, border-color 0.2s ease;
    text-align: left;
    gap: 0.625rem;
}

@media (hover: hover) {
    .sr-ps-swatch-list-item:hover {
        background-color: var(--sr-ps-item-hover-bg, #fffdf5);
        border-color: var(--brand-primary-alt, #ffda6a);
    }
}

.sr-ps-swatch-list-item:focus {
    outline: none;
    border-color: var(--neutral-300, #D1D5DB);
}

.sr-ps-swatch-list-item.selected {
    background-color: var(--neutral-50, #F9FAFB) !important;
    border-color: var(--brand-primary, #ffc107);
}

@media (hover: hover) {
    .sr-ps-swatch-list-item.selected:hover {
        background-color: var(--neutral-50, #F9FAFB) !important;
    }
}

/* ========================================
   RADIO MODERNO
   ======================================== */

.sr-ps-radio-indicator {
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 18px;
    height: 18px;
    margin-top: 1px;
}

.sr-ps-radio-dot {
    width: 16px;
    height: 16px;
    border: 1.5px solid var(--neutral-300, #D1D5DB);
    border-radius: 50%;
    background-color: var(--neutral-0, #fff);
    transition: background-color 0.2s ease, border-color 0.2s ease;
}

@media (hover: hover) {
    .sr-ps-swatch-list-item:hover .sr-ps-radio-dot {
        border-color: var(--brand-primary-alt, #ffda6a);
    }
}

.sr-ps-swatch-list-item.selected .sr-ps-radio-dot {
    border-color: var(--brand-primary, #ffc107);
    border-width: 5px;
    background-color: var(--brand-primary, #ffc107);
}

/* ========================================
   CONTENIDO
   ======================================== */

.sr-ps-swatch-content {
    display: flex;
    flex-direction: column;
    flex-grow: 1;
    min-width: 0;
    gap: 0.125rem;
}

.sr-ps-swatch-label-row {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    flex-wrap: wrap;
}

.sr-ps-swatch-label {
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--neutral-800, #1F2937);
    line-height: 1.3;
    /* Estabilización anti layout shift (v6.10.31): el span es
       inline-flex column para que el ::after ghost se apile
       debajo y reserve ancho sin afectar altura. Misma técnica
       que color_picker (v6.10.28) e images-type (v6.10.30).
       El ::after ghost común está consolidado al final del CSS
       (v6.10.32, "Estabilización ancho — ghost común"). */
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
}

.sr-ps-swatch-list-item.selected .sr-ps-swatch-label {
    font-weight: 600;
    color: var(--neutral-900, #111827);
}

.sr-ps-swatch-desc {
    font-size: 0.75rem;
    font-weight: 400;
    color: var(--neutral-500, #6B7280);
    line-height: 1.4;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ========================================
   STICKER MODERNO
   ======================================== */

.sr-ps-swatch-sticker {
    display: inline-flex;
    align-items: center;
    padding: 0.125rem 0.375rem;
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.02em;
    color: var(--neutral-900, #111827);
    background: var(--brand-primary, #ffc107);
    border-radius: 4px;
    line-height: 1.3;
    white-space: nowrap;
}

/* Stickers especiales: Más vendido, Popular, Recomendado */
.sr-ps-swatch-sticker--popular {
    background: var(--verde, #198754);
    color: var(--neutral-0, #fff);
}

/* ========================================
   ACCESIBILIDAD - ARIA LIVE
   ======================================== */

.sr-ps-aria-live {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* ========================================
   TOUCH TARGETS (mínimo 44px)
   ======================================== */

@media (pointer: coarse) {
    .sr-ps-swatch-list-item {
        min-height: 44px;
    }
    
    /* Solo aplicar min-width/height cuando NO está dentro de los tipos con layout calculado */
    .sr-ps-swatches-buttons-type .sr-ps-swatch-inline-item {
        min-width: 44px;
        min-height: 44px;
    }
    
    .sr-ps-tooltip-icon {
        width: 44px;
        height: 44px;
        padding: 10px;
        margin: -10px;
    }
}

/* ========================================
   MINIATURA
   ======================================== */

.sr-ps-swatch-thumbnail {
    flex-shrink: 0;
    width: 36px;
    height: 36px;
    border-radius: 6px;
    overflow: hidden;
    background-color: var(--neutral-200, #E5E7EB);
    display: flex;
    align-items: center;
    justify-content: center;
}

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

.sr-ps-swatch-thumbnail .sr-ps-swatch-fallback {
    font-size: 0.625rem;
    font-weight: 600;
    color: var(--neutral-500, #6B7280);
    text-transform: uppercase;
}

.sr-ps-swatch-list-item.selected .sr-ps-swatch-thumbnail {
    box-shadow: 0 0 0 2px var(--brand-primary, #ffc107);
}

/* ========================================
   PRECIO
   ======================================== */

/*
 * INDICADOR DE PRECIO EN SWATCHES
 * Patas (buttons/images): badge cuadrado neutro a la derecha del nombre (P2).
 * Tapizado (inline-only): pill verde debajo del swatch (P3).
 * Variantes sin coste extra: sin badge (decisión CRO).
 */
.sr-ps-swatch-price {
    flex-shrink: 0;
    margin-left: auto;
    font-size: 0.72rem;
    font-weight: 500;
    color: var(--sr-ps-price-text, #444441);
    background: var(--sr-ps-price-bg, #F1EFE8);
    padding: 2px 9px;
    border-radius: 6px;
    line-height: 1.4;
    white-space: nowrap;
    align-self: center;
}

/* Patas seleccionada: badge pasa a ÁMBAR (refuerza la selección activa) */
.sr-ps-swatch-list-item.selected .sr-ps-swatch-price,
.sr-ps-segmented-item.sr-ps-segmented-item--active .sr-ps-segmented-price {
    color: var(--sr-ps-price-active-text, #92400E);
    background: var(--sr-ps-price-active-bg, #FEF3C7);
}

.sr-ps-swatch-price .woocommerce-Price-amount {
    font-weight: inherit;
    color: inherit;
}

.sr-ps-swatch-price .woocommerce-Price-currencySymbol {
    font-weight: inherit;
}

/* Images-type (patas alternativo): badge neutro centrado bajo el chip */
.sr-ps-swatch-price-tag {
    display: inline-block;
    margin-top: 4px;
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--sr-ps-price-text, #444441);
    background: var(--sr-ps-price-bg, #F1EFE8);
    padding: 2px 8px;
    border-radius: 6px;
    text-align: center;
    line-height: 1.4;
}

/* Tapizado (inline-only): pill VERDE debajo del swatch cuadrado (P3) */
.sr-ps-swatch-price-below {
    position: absolute;
    bottom: -20px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.7rem;
    font-weight: 500;
    color: var(--sr-ps-price-below-text, #0F6E56);
    background: var(--sr-ps-price-below-bg, #E1F5EE);
    padding: 2px 9px;
    border-radius: 20px;
    line-height: 1.4;
    white-space: nowrap;
}

/* Variante "incluido" (tapizado base, sin coste): verde más sutil,
   sin relleno fuerte — informa sin competir con los "+X€". */
.sr-ps-swatch-price-below--base {
    color: var(--sr-ps-price-included-text, #1D9E75);
    background: transparent;
    font-weight: 400;
}

/* ========================================
   OCULTAR LABELS WOOCOMMERCE
   ======================================== */

.variations .label,
.variations th.label {
    display: none !important;
}

.variations {
    width: 100%;
}

.variations tr {
    display: block;
    margin-bottom: 0;
}

.variations td {
    display: block;
    width: 100%;
    padding: 0;
}

.variations td.value {
    padding: 0;
}

/* ========================================
   TIPO: POR DEFECTO (select nativo restilizado)
   Solo CSS, cero JS. Apunta al <select> nativo de WooCommerce que
   NO está dentro de .sr-ps-hidden-select (ese es el oculto de los
   swatches custom). Mantiene accesibilidad y picker nativo móvil.
   ======================================== */

.variations td.value > select:not([multiple]),
.variations .value > select:not([multiple]) {
    -webkit-appearance: none;
    -moz-appearance: none;
    appearance: none;
    display: block;
    width: 100%;
    max-width: 100%;
    margin: 0;
    padding: 0.75rem 2.5rem 0.75rem 1rem;
    font-size: 0.9375rem;
    font-weight: 500;
    line-height: 1.4;
    color: var(--neutral-800, #1F2937);
    background-color: var(--neutral-0, #fff);
    border: 1.5px solid var(--neutral-300, #D1D5DB);
    border-radius: 6px;
    cursor: pointer;
    transition: border-color 0.15s ease, box-shadow 0.15s ease;
    /* Flecha custom SVG (chevron) — color neutral-500 */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%236B7280' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.875rem center;
    background-size: 18px 18px;
}

@media (hover: hover) {
    .variations td.value > select:not([multiple]):hover,
    .variations .value > select:not([multiple]):hover {
        border-color: var(--brand-primary-alt, #ffda6a);
    }
}

.variations td.value > select:not([multiple]):focus,
.variations .value > select:not([multiple]):focus,
.variations td.value > select:not([multiple]):focus-visible,
.variations .value > select:not([multiple]):focus-visible {
    outline: none;
    border-color: var(--brand-primary, #ffc107);
    box-shadow: 0 0 0 3px rgba(255, 193, 7, 0.18);
}

/* Estado: opción aún sin elegir ("Elige una opción") en gris suave */
.variations td.value > select:not([multiple]):invalid,
.variations .value > select:not([multiple]):invalid {
    color: var(--neutral-500, #6B7280);
    font-weight: 400;
}

/* Enlace "Limpiar" (reset_variations) coherente con el sistema */
.variations .reset_variations {
    display: inline-block;
    margin-top: 0.5rem;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--neutral-500, #6B7280);
    text-decoration: none;
    transition: color 0.15s ease;
}

@media (hover: hover) {
    .variations .reset_variations:hover {
        color: var(--brand-secondary, #0d6efd);
        text-decoration: underline;
    }
}

.variations .reset_variations:focus {
    color: var(--brand-secondary, #0d6efd);
    text-decoration: underline;
}

/* ========================================
   RESPONSIVE
   ======================================== */

@media (max-width: 480px) {
    .sr-ps-swatches-title {
        font-size: 0.75rem;
    }
    
    /* ≤480px: el icono se ve más pequeño (cabe mejor junto al
       título en pantallas estrechas) PERO conserva el área táctil
       de 44px. Antes se reseteaba a 14×14 sin padding, lo que
       anulaba el target táctil del bloque ≤767px y hacía casi
       imposible abrir el tooltip con el dedo en móvil. Ahora solo
       se reduce el SVG interior vía padding; el margin negativo
       sigue neutralizando el impacto en el layout. */
    .sr-ps-tooltip-icon {
        width: 44px;
        height: 44px;
        padding: 15px;
        margin: -15px;
    }
    
    .sr-ps-tooltip-content {
        /* En móvil el tooltip flota a lo ancho del contenedor
           (left/right:0 del bloque ≤767). Aquí solo se ajusta la
           tipografía para pantallas pequeñas; NO se toca el ancho ni
           el posicionamiento (un max-width estrecho lo rompería). */
        font-size: 0.6875rem;
    }
    
    .sr-ps-swatches-grid {
        padding: 0.375rem 0;
        gap: 0.375rem;
    }
    
    .sr-ps-swatch-list-item {
        padding: 0.75rem;
        gap: 0.5rem;
        border-radius: 4px;
    }
    
    .sr-ps-swatch-label {
        font-size: 0.8125rem;
    }
    
    .sr-ps-swatch-sticker {
        font-size: 0.5625rem;
        padding: 0.0625rem 0.25rem;
    }
    
    .sr-ps-swatch-desc {
        font-size: 0.6875rem;
    }
    
    .sr-ps-swatch-price {
        font-size: 0.6875rem;
    }
    
    .sr-ps-swatch-thumbnail {
        width: 32px;
        height: 32px;
    }
    
    .sr-ps-radio-indicator {
        width: 16px;
        height: 16px;
    }
    
    .sr-ps-radio-dot {
        width: 14px;
        height: 14px;
    }
    
    .sr-ps-swatch-list-item.selected .sr-ps-radio-dot {
        border-width: 4px;
    }
}

/* ========================================
   TIPO: MINIATURAS EN LÍNEA (tapizado)
   Base Desktop: 6.5 visibles + scroll horizontal
   ======================================== */

.sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    padding-bottom: 0.5rem;
}

/* v6.10.34 [WPO/CLS revert]: ELIMINADO el override desktop con !important
   que se introdujo en v6.10.33. Razón empírica (PageSpeed test 3 sobre
   sillon-roma): el min-height 180/200 px era mayor que el alto real del
   item (que tiene aspect-ratio:1 y ancho 158-170 px en desktop), creando
   espacio vacío visible y un CLS regresivo (0.247 vs 0.172 sin el fix).
   Tras pasar a thumbnails -768x768.avif (22 KB c/u, antes 380 KB) las
   imágenes cargan rápido y aspect-ratio:1 reserva el alto naturalmente.
   El min-height inline mobile también se reduce a 0 desde PHP (filtro
   sr_ps_inline_min_height sigue disponible para casos excepcionales). */

/* Cuando el atributo muestra precios, el grid necesita espacio inferior
   para el .sr-ps-swatch-price-below (que se posiciona en bottom:-18px).
   overflow-y pasa a visible para no recortarlo. */
.sr-ps-swatches-inline-only.sr-ps-has-prices .sr-ps-swatches-inline-grid {
    overflow-y: visible;
    padding-bottom: 24px;
}

.sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid::-webkit-scrollbar {
    height: 10px;
}

.sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid::-webkit-scrollbar-track {
    background: var(--neutral-100, #F3F4F6);
    border-radius: 5px;
}

.sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid::-webkit-scrollbar-thumb {
    background: var(--neutral-300, #D1D5DB);
    border-radius: 5px;
}

@media (hover: hover) {
    .sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid::-webkit-scrollbar-thumb:hover {
        background: var(--neutral-400, #9CA3AF);
    }
}

.sr-ps-swatches-inline-only .sr-ps-swatch-inline-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-width: calc((100% - 2.75rem) / 6.5);
    max-width: calc((100% - 2.75rem) / 6.5);
    flex: 0 0 calc((100% - 2.75rem) / 6.5);
    aspect-ratio: 1;
    padding: 0;
    background-color: var(--neutral-100, #F3F4F6);
    border: 2px solid transparent;
    border-radius: 6px;
    cursor: pointer;
    scroll-snap-align: start;
    transition: border-color 0.15s ease;
    text-decoration: none;
    line-height: 0;
}

/* La imagen lleva el recorte (antes overflow:hidden iba en el item,
   pero eso recortaba el precio que va debajo). */
.sr-ps-swatches-inline-only .sr-ps-swatch-inline-item img {
    width: 100%;
    height: 100%;
    border-radius: 4px;
    overflow: hidden;
    object-fit: cover;
    display: block;
}

@media (hover: hover) {
    .sr-ps-swatches-inline-only .sr-ps-swatch-inline-item:hover {
        border-color: var(--brand-primary-alt, #ffda6a);
    }
}

.sr-ps-swatches-inline-only .sr-ps-swatch-inline-item:focus-visible {
    outline: 2px solid var(--brand-secondary, #0d6efd);
    outline-offset: 1px;
}

.sr-ps-swatches-inline-only .sr-ps-swatch-inline-item.sr-ps-swatch-inline-item--active {
    border-color: var(--brand-primary, #ffc107) !important;
    cursor: default !important;
}

/* ========================================
   TIPO: MINIATURAS PERSONALIZADAS (chips inline)
   Imagen + texto vía ::after
   ======================================== */

/* Container de images-type: título a la izquierda, grid scrollable a la
   derecha. Con la nueva estructura (header hermano del grid) el layout
   horizontal se controla aquí, en el container, no en el header. */
.sr-ps-swatches-images-type .sr-ps-swatches-container {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.sr-ps-swatches-header--inline {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: nowrap;
    flex-shrink: 0;
}

.sr-ps-swatches-header--inline .sr-ps-swatches-title {
    flex-shrink: 0;
}

.sr-ps-swatches-images-type .sr-ps-swatches-inline-grid {
    display: flex;
    flex-wrap: nowrap;
    gap: 0.5rem;
    padding: 0;
    flex: 1;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
}

.sr-ps-swatches-images-type .sr-ps-swatches-inline-grid::-webkit-scrollbar {
    display: none;
}

.sr-ps-swatches-images-type .sr-ps-swatch-inline-item {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-direction: row;
    padding: 0.25rem 0.5rem 0.25rem 0.25rem;
    gap: 0.375rem;
    background-color: var(--neutral-0, #fff);
    border: 2px solid var(--neutral-200, #E5E7EB);
    border-radius: 6px;
    cursor: pointer;
    overflow: hidden;
    transition: border-color 0.15s ease;
    flex-shrink: 0;
    white-space: nowrap;
}

.sr-ps-swatches-images-type .sr-ps-swatch-inline-item img {
    width: 24px;
    height: 24px;
    border-radius: 4px;
    flex-shrink: 0;
    object-fit: cover;
    display: block;
}

/* === Label de images-type ===
   v6.10.30: refactorizado de ::after del button a <span> real
   para poder aplicar la misma técnica anti layout shift que
   color_picker. El span es inline-flex column con un ::after
   ghost bold invisible que reserva el ancho del bold, evitando
   que el cambio font-weight 500→600 al seleccionar empuje los
   tiles vecinos. */
.sr-ps-swatches-images-type .sr-ps-swatch-inline-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--neutral-700, #374151);
    line-height: 1;
    /* Estabilización: el span es inline-flex column para que
       el ::after ghost se apile debajo y reserve ancho sin
       afectar la altura.
       El ::after ghost común está consolidado al final del CSS
       (v6.10.32, "Estabilización ancho — ghost común"). */
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
}

@media (hover: hover) {
    .sr-ps-swatches-images-type .sr-ps-swatch-inline-item:hover {
        border: 2px solid var(--brand-primary-alt, #ffda6a);
    }
}

.sr-ps-swatches-images-type .sr-ps-swatch-inline-item:focus-visible {
    outline: 2px solid var(--brand-secondary, #0d6efd);
    outline-offset: 1px;
}

.sr-ps-swatches-images-type .sr-ps-swatch-inline-item.sr-ps-swatch-inline-item--active {
    border: 2px solid var(--brand-primary, #ffc107) !important;
}

/* === Label activo: bold + color más fuerte ===
   v6.10.30: ahora se aplica al .sr-ps-swatch-inline-label (span real),
   no al ::after del button. */
.sr-ps-swatches-images-type .sr-ps-swatch-inline-item.sr-ps-swatch-inline-item--active .sr-ps-swatch-inline-label {
    font-weight: 600;
    color: var(--neutral-900, #111827);
}

/* ========================================
   TIPO: SEGMENTED CONTROL
   Para 2-3 opciones (binarios/ternarios). Estilo iOS-like compacto.
   ======================================== */

.sr-ps-swatches-segmented-type .sr-ps-segmented-grid {
    display: flex;
    align-items: stretch;
    gap: 2px;
    padding: 3px;
    background-color: var(--neutral-100, #F3F4F6);
    border-radius: 8px;
}

.sr-ps-segmented-item {
    flex: 1;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.375rem;
    padding: 0.625rem 0.75rem;
    background-color: transparent;
    border: none;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.875rem;
    font-weight: 500;
    color: var(--neutral-700, #374151);
    transition: background-color 0.18s ease, color 0.18s ease, box-shadow 0.18s ease, transform 0.1s ease;
    min-height: 40px;
    text-align: center;
    line-height: 1.2;
    /* Anti-tema: forzar reset visual */
    text-decoration: none;
    text-shadow: none;
    font-family: inherit;
}

@media (hover: hover) {
    .sr-ps-segmented-item:hover:not(.sr-ps-segmented-item--active):not(.sr-ps-swatch-disabled) {
        background-color: rgba(255, 255, 255, 0.6) !important;
        color: var(--neutral-900, #111827) !important;
        box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
    }
}

/* Anular fondos oscuros heredados de temas (GeneratePress, etc.) que rompen el hover.
   :focus y :active se mantienen SIEMPRE (en móvil :active es el feedback de
   toque y debe conservar el color legible); solo :hover se limita a punteros. */
@media (hover: hover) {
    .sr-ps-segmented-item:hover {
        color: var(--neutral-900, #111827) !important;
    }
}

.sr-ps-segmented-item:focus,
.sr-ps-segmented-item:active {
    color: var(--neutral-900, #111827) !important;
}

/* Touch: feedback al pulsar (móvil) */
.sr-ps-segmented-item:active:not(.sr-ps-segmented-item--active):not(.sr-ps-swatch-disabled) {
    background-color: rgba(255, 255, 255, 0.85) !important;
    transform: scale(0.98);
}

.sr-ps-segmented-item:focus-visible {
    outline: 2px solid var(--brand-secondary, #0d6efd);
    outline-offset: 1px;
}

.sr-ps-segmented-item.sr-ps-segmented-item--active {
    background-color: var(--neutral-0, #fff);
    color: var(--neutral-900, #111827);
    font-weight: 600;
    /* Acento ámbar coherente con los demás swatches (tapizado/patas
       usan borde ámbar para "seleccionado"). Se mantiene la elevación
       iOS (sombra) propia del segmented: el borde da coherencia de
       marca sin renunciar a la naturaleza del control. */
    box-shadow: 0 0 0 2px var(--brand-primary, #ffc107),
                0 1px 3px rgba(0, 0, 0, 0.08),
                0 1px 2px rgba(0, 0, 0, 0.04);
    cursor: default;
}

.sr-ps-segmented-label {
    line-height: 1.2;
    /* Estabilización anti layout shift (v6.10.31): el span es
       inline-flex column con ::after ghost bold invisible que
       reserva el ancho de la versión 600 desde el inicio. En
       segmented el item tiene flex:1 (ancho repartido), pero
       esta técnica protege contra desbordes/reflows internos
       del texto al cambiar font-weight 500→600 al activar.
       Misma técnica que color_picker, images-type y buttons. */
    display: inline-flex;
    flex-direction: column;
    align-items: center;
}

/* Icono opcional del término en el segmented. Tamaño contenido para
   respetar el carácter compacto del control (no es una miniatura tipo
   swatch de tapizado). object-fit:contain evita deformar un icono o
   imagen no cuadrada. flex-shrink:0 para que no se aplaste si el label
   es largo. El gap del .sr-ps-segmented-item ya lo separa del texto. */
.sr-ps-segmented-icon {
    flex-shrink: 0;
    width: 22px;
    height: 22px;
    object-fit: contain;
    display: block;
}

/* Defensa: si por caché/otro plugin un .sr-ps-segmented-icon llegara
   sin src resoluble, el navegador mostraría su recuadro roto. Esto lo
   oculta — el PHP ya garantiza que solo se emite con imagen válida,
   pero esta regla evita cualquier artefacto visual residual. */
.sr-ps-segmented-icon:not([src]),
.sr-ps-segmented-icon[src=""],
.sr-ps-segmented-icon[src="#"] {
    display: none;
}

.sr-ps-segmented-price {
    font-size: 0.6875rem;
    font-weight: 500;
    color: var(--sr-ps-price-text, #444441);
    padding: 2px 8px;
    background-color: var(--sr-ps-price-bg, #F1EFE8);
    border-radius: 6px;
    line-height: 1.4;
    white-space: nowrap;
}

/* Disabled state para segmented */
.sr-ps-segmented-item.sr-ps-swatch-disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

.sr-ps-segmented-item.sr-ps-swatch-disabled .sr-ps-segmented-label {
    text-decoration: line-through;
}

/* Móvil: padding ajustado, font más pequeño si hay precio */
@media (max-width: 767px) {
    .sr-ps-segmented-item {
        padding: 0.5rem 0.5rem;
        font-size: 0.8125rem;
    }
    .sr-ps-segmented-price {
        font-size: 0.625rem;
    }
}

/* ========================================
   ESTADOS DISABLED (swatches no disponibles)
   ======================================== */

.sr-ps-swatch-list-item.sr-ps-swatch-disabled,
.sr-ps-swatch-inline-item.sr-ps-swatch-disabled {
    opacity: 0.45;
    cursor: not-allowed;
    position: relative;
}

.sr-ps-swatch-list-item.sr-ps-swatch-disabled::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 10%;
    right: 10%;
    height: 1px;
    background-color: var(--neutral-400, #9CA3AF);
    transform: rotate(-5deg);
    pointer-events: none;
}

.sr-ps-swatch-inline-item.sr-ps-swatch-disabled img {
    filter: grayscale(100%);
}

/* Tooltip "No disponible" al hover (desktop) */
@media (hover: hover) {
    .sr-ps-swatch-list-item.sr-ps-swatch-disabled:hover::before,
    .sr-ps-swatch-inline-item.sr-ps-swatch-disabled:hover::before {
        content: "No disponible";
        position: absolute;
        bottom: calc(100% + 6px);
        left: 50%;
        transform: translateX(-50%);
        padding: 0.25rem 0.5rem;
        background: var(--neutral-900, #111827);
        color: var(--neutral-0, #fff);
        font-size: 0.6875rem;
        font-weight: 500;
        border-radius: 4px;
        white-space: nowrap;
        z-index: 100;
        pointer-events: none;
        animation: sr-ps-fade-up 0.2s ease-out;
    }
}

/* Feedback shake al intentar seleccionar un disabled (móvil + desktop) */
.sr-ps-swatch-list-item.sr-ps-shake,
.sr-ps-swatch-inline-item.sr-ps-shake {
    animation: sr-ps-shake 0.35s ease-in-out;
}

@keyframes sr-ps-shake {
    0%, 100% { transform: translateX(0); }
    20% { transform: translateX(-4px); }
    40% { transform: translateX(4px); }
    60% { transform: translateX(-3px); }
    80% { transform: translateX(2px); }
}

@keyframes sr-ps-fade-up {
    from { opacity: 0; transform: translateX(-50%) translateY(3px); }
    to { opacity: 1; transform: translateX(-50%) translateY(0); }
}

/* Respeta usuarios con prefers-reduced-motion */
@media (prefers-reduced-motion: reduce) {
    .sr-ps-shake { animation: none; }
}

/* ========================================
   ATRAER ATENCIÓN AL PRIMER SWATCH
   Disparado por window.srPSAttract() (contrato público) cuando el
   usuario pulsa "Opciones" en la barra sticky de compra.

   Diseño clip-safe: el grid de swatches tiene overflow-x:auto +
   overflow-y:hidden y el item images-type tiene overflow:hidden. Un
   resalte que sobresalga (scale hacia fuera / box-shadow exterior) se
   recortaría. Solución: anillo INSET (dibujado DENTRO del item) +
   micro "press-in" (escala hacia DENTRO, scale<1) — nunca excede la
   caja del item, así ningún overflow lo recorta. El press-in lee como
   gesto táctil "tócame" (espíritu opción 3). Color = ámbar de marca
   (#ffc107 con alfa, mismo idioma que el estado activo/hover).
   ======================================== */

.sr-ps-swatch-inline-item.sr-ps-attn,
.sr-ps-swatch-list-item.sr-ps-attn,
.sr-ps-segmented-item.sr-ps-attn {
    position: relative;
    z-index: 2;
    will-change: transform;
    animation: sr-ps-attn 1.4s ease-in-out 2;
}

@keyframes sr-ps-attn {
    0%, 100% { transform: scale(1); box-shadow: inset 0 0 0 0 rgba(255, 193, 7, 0); }
    28% { transform: scale(0.94); border-color: var(--brand-primary, #ffc107); box-shadow: inset 0 0 0 3px rgba(255, 193, 7, 0.6); }
    56% { transform: scale(1); box-shadow: inset 0 0 0 0 rgba(255, 193, 7, 0); }
}

@media (prefers-reduced-motion: reduce) {
    .sr-ps-attn { animation: none; }
}

/* ========================================
   IMAGE LOADING STATE
   Shimmer cuando la imagen principal tarda en cargar tras cambio de variación
   ======================================== */

.sr-ps-image-loading {
    position: relative;
    overflow: hidden;
}

.sr-ps-image-loading::after {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: linear-gradient(
        90deg,
        transparent 0%,
        rgba(255, 255, 255, 0.5) 50%,
        transparent 100%
    );
    /* No 'infinite': si el cleanup JS fallara (load/error no dispara por
       caché o red), la animación pararía sola tras ~18s en vez de
       mantener una capa de composición activa indefinidamente.
       15 ciclos cubren cualquier carga real. will-change solo aquí
       (la clase es efímera) promueve la capa de forma eficiente. */
    will-change: transform;
    animation: sr-ps-shimmer 1.2s 15 ease-in-out;
    z-index: 5;
    pointer-events: none;
}

@keyframes sr-ps-shimmer {
    0%   { transform: translateX(0); }
    100% { transform: translateX(200%); }
}

@media (prefers-reduced-motion: reduce) {
    .sr-ps-image-loading::after { animation: none; opacity: 0.3; }
}

/* ========================================
   RESPONSIVE: MÓVIL (max-width: 767px)
   ======================================== */

@media (max-width: 767px) {
    /* --- MINIATURAS EN LÍNEA: 4.5 visibles, scrollbar oculto --- */
    .sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid {
        scrollbar-width: none;
        padding-bottom: 0;
    }

    .sr-ps-swatches-inline-only .sr-ps-swatches-inline-grid::-webkit-scrollbar {
        display: none;
    }

    .sr-ps-swatches-inline-only .sr-ps-swatch-inline-item {
        min-width: calc((100% - 1.75rem) / 4.5) !important;
        max-width: calc((100% - 1.75rem) / 4.5) !important;
        flex: 0 0 calc((100% - 1.75rem) / 4.5) !important;
        box-shadow: none !important;
        transition: none !important;
        transform: none !important;
    }

    /* --- MINIATURAS PERSONALIZADAS: chips compactos --- */
    .sr-ps-swatches-images-type .sr-ps-swatch-inline-item {
        padding: 0.375rem;
        gap: 0.5rem;
        transition: none !important;
    }

    .sr-ps-swatches-images-type .sr-ps-swatch-inline-item img {
        width: 20px;
        height: 20px;
    }

    .sr-ps-swatches-images-type .sr-ps-swatch-inline-label {
        font-size: 0.6875rem;
    }

    /* --- Desactivar animaciones en móvil --- */
    .sr-ps-swatch-inline-item:active,
    .sr-ps-swatch-list-item:active {
        transform: none !important;
    }

    .sr-ps-swatch-list-item.selected,
    .sr-ps-swatch-inline-item.sr-ps-swatch-inline-item--active {
        animation: none !important;
    }
}

/* ========================================
   MICRO-ANIMACIONES (solo desktop con hover)
   ======================================== */

@media (hover: hover) and (min-width: 768px) {
    .sr-ps-swatch-list-item,
    .sr-ps-swatch-inline-item {
        transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.1s ease;
    }

    .sr-ps-swatch-list-item:active:not(.sr-ps-swatch-disabled),
    .sr-ps-swatch-inline-item:active:not(.sr-ps-swatch-disabled) {
        transform: scale(0.97);
    }

    .sr-ps-swatch-list-item.selected,
    .sr-ps-swatch-inline-item.sr-ps-swatch-inline-item--active {
        animation: sr-ps-pulse 0.2s ease-out;
    }

    @keyframes sr-ps-pulse {
        0% { transform: scale(0.97); }
        50% { transform: scale(1.01); }
        100% { transform: scale(1); }
    }
}

/* ========================================
   SCROLL INDICATOR (fade gradient en móvil)
   Indica visualmente que hay más contenido para scrollear.
   Usa mask-image que se controla por clases JS según posición de scroll.
   ======================================== */

@media (max-width: 767px) {
    /* Estado: hay overflow (contenido escondido fuera del viewport) */
    .sr-ps-swatches-inline-only.sr-ps-has-overflow .sr-ps-swatches-inline-grid,
    .sr-ps-swatches-images-type.sr-ps-has-overflow .sr-ps-swatches-inline-grid {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100%);
        mask-image: linear-gradient(to right, transparent 0, black 24px, black calc(100% - 24px), transparent 100%);
        transition: -webkit-mask-image 0.2s ease, mask-image 0.2s ease;
    }

    /* En posición inicial: solo fade derecho (hay contenido a la derecha) */
    .sr-ps-swatches-inline-only.sr-ps-has-overflow.sr-ps-scroll-at-start .sr-ps-swatches-inline-grid,
    .sr-ps-swatches-images-type.sr-ps-has-overflow.sr-ps-scroll-at-start .sr-ps-swatches-inline-grid {
        -webkit-mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
        mask-image: linear-gradient(to right, black 0, black calc(100% - 24px), transparent 100%);
    }

    /* En posición final: solo fade izquierdo (hay contenido a la izquierda) */
    .sr-ps-swatches-inline-only.sr-ps-has-overflow.sr-ps-scroll-at-end .sr-ps-swatches-inline-grid,
    .sr-ps-swatches-images-type.sr-ps-has-overflow.sr-ps-scroll-at-end .sr-ps-swatches-inline-grid {
        -webkit-mask-image: linear-gradient(to right, transparent 0, black 24px, black 100%);
        mask-image: linear-gradient(to right, transparent 0, black 24px, black 100%);
    }
}

/* ===========================================================
   COLOR PICKER TYPE (v6.10.28 — P2 "Bisel sutil")
   Hereda lenguaje visual de images-type (patas): tile
   horizontal, borde 2px, hover ámbar claro, active ámbar
   pleno. Personalización P2: el círculo de color tiene un
   BISEL INTERNO permanente que sugiere textura de tela y
   un HALO EXTERIOR ámbar al seleccionar con micro-bounce.
   Cero layout shift al activar: el label reserva el ancho
   del bold con un pseudo-elemento ::after invisible.
   Cero imágenes, cero requests adicionales, cero CLS.
   =========================================================== */

/* ===========================================================
   GRID — flex-wrap (mejor para gamas amplias de colores).
   A diferencia de patas (scroll-x), aquí los colores quedan
   mejor en wrap: 6-8 colores ocupan 1-2 filas sin scroll y
   se ven todos a la vez (mejor para decisión emocional).
   =========================================================== */
.sr-ps-swatches-color-picker-type .sr-ps-color-picker-grid {
    display: flex;
    flex-wrap: wrap;
    /* Gap aumentado a 0.75rem para dar aire al halo exterior
       del estado activo (4px adicionales) sin que los tiles
       vecinos lo "rocen". También respira mejor visualmente. */
    gap: 0.75rem;
    padding: 0;
    margin: 0;
}

/* ===========================================================
   ITEM — coherente con images-type (patas) en lenguaje visual
   (borde, padding, hover ámbar, label tipográfico), con
   personalización propia P2: bisel interno permanente que
   sugiere textura de tela, halo exterior ámbar al seleccionar
   con micro-bounce de presentación.
   =========================================================== */
.sr-ps-color-picker-item {
    /* Reset button */
    appearance: none;
    -webkit-appearance: none;
    margin: 0;
    cursor: pointer;
    position: relative;

    /* === Heredado de images-type (patas) === */
    display: flex;
    align-items: center;
    justify-content: flex-start;
    flex-direction: row;
    /* Padding más generoso que patas (0.4rem envolvente) para
       que el círculo "respire" dentro del tile. Patas usa
       0.25rem 0.5rem 0.25rem 0.25rem (asimétrico para imagen
       cuadrada pegada a izda); aquí el círculo merece un
       envoltorio uniforme y más holgado. */
    padding: 0.4rem 0.625rem 0.4rem 0.4rem;
    gap: 0.5rem;
    background-color: var(--neutral-0, #fff);
    border: 2px solid var(--neutral-200, #E5E7EB);
    border-radius: 8px;
    /* IMPORTANTE: overflow VISIBLE (no hidden como patas).
       P2 tiene halo exterior ámbar al seleccionar que DEBE
       sobresalir del tile. Con overflow:hidden el halo se
       recortaría y perdería su efecto premium. */
    overflow: visible;
    transition: border-color 0.15s ease, background-color 0.15s ease;
    flex-shrink: 0;
    white-space: nowrap;
    /* Color de texto base coherente; previene heredar negro
       agresivo del tema. */
    color: var(--neutral-700, #374151);
    /* Defensa: algunos temas (GeneratePress, Astra) declaran
       letter-spacing/text-transform en botones; los resetamos. */
    letter-spacing: normal;
    text-transform: none;
    text-align: left;
    font-family: inherit;
}

/* ============================================================
   DEFENSAS ANTI HOVER/FOCUS OSCURO (refuerzo v6.10.29)
   Cubrimos TODOS los pseudo-estados que un tema o el navegador
   pueden usar para pintar el botón con fondo oscuro:
     - :hover (movimiento ratón)
     - :focus  (foco general, incluso por click en Chrome/Edge)
     - :focus-visible (foco por teclado — bueno, queremos outline)
     - :active (mientras se pulsa)
     - --active (clase nuestra: seleccionado persistente)
     - aria-checked="true" (algunos temas estilizan radios así)
   Usamos !important porque luchamos contra estilos globales
   del tema con alta especificidad; esta es la última línea de
   defensa contra el "hover/active oscuro" reportado.
   ============================================================ */
.sr-ps-color-picker-item:focus,
.sr-ps-color-picker-item:active {
    /* Sin background oscuro al hacer click (Chrome aplica :focus
       al clicar; algunos temas pintan bg oscuro en button:focus).
       Mantenemos el bg blanco salvo override expreso del hover. */
    background-color: var(--neutral-0, #fff) !important;
    color: var(--neutral-700, #374151) !important;
    /* Outline neutralizado en focus por click; lo restituye
       :focus-visible más abajo para usuarios de teclado. */
    outline: none !important;
    box-shadow: none;
}
.sr-ps-color-picker-item[aria-checked="true"]:focus,
.sr-ps-color-picker-item[aria-checked="true"]:active {
    /* Defensa adicional para el caso reportado: tile recién
       seleccionado mostraba fondo oscuro porque conserva el
       :focus después del click. Forzamos bg blanco aunque esté
       checked. */
    background-color: var(--neutral-0, #fff) !important;
}

/* === Hover === ámbar claro (igual patas), bg crema neutro */
@media (hover: hover) {
    .sr-ps-color-picker-item:hover {
        border-color: var(--brand-primary-alt, #ffda6a);
        background-color: var(--neutral-50, #F9FAFB) !important;
        color: var(--neutral-700, #374151);
    }
    .sr-ps-color-picker-item:hover .sr-ps-color-picker-label {
        color: var(--neutral-700, #374151);
    }
    /* Sobre tile activo + hover: NO oscurecer (mantener crema) */
    .sr-ps-color-picker-item.sr-ps-color-picker-item--active:hover {
        background-color: var(--neutral-50, #F9FAFB) !important;
    }
}

/* === Focus visible (teclado) === idéntico a patas */
.sr-ps-color-picker-item:focus-visible {
    outline: 2px solid var(--brand-secondary, #0d6efd) !important;
    outline-offset: 1px;
}

/* === Activo (seleccionado) ===
   Borde ámbar + label bold + halo exterior en el círculo.
   IMPORTANTE: background-color BLANCO declarado expresamente,
   con !important — sin esto, un :focus residual del click
   pintaba el tile oscuro (problema reportado en screenshot
   del usuario v6.10.28). */
.sr-ps-color-picker-item.sr-ps-color-picker-item--active {
    border-color: var(--brand-primary, #ffc107) !important;
    background-color: var(--neutral-0, #fff) !important;
}
.sr-ps-color-picker-item.sr-ps-color-picker-item--active .sr-ps-color-picker-label {
    font-weight: 600;
    color: var(--neutral-900, #111827);
}
.sr-ps-color-picker-item.sr-ps-color-picker-item--active .sr-ps-color-picker-swatch {
    /* Halo exterior P2: anillo blanco + anillo ámbar */
    box-shadow:
        inset 0 -1px 2px rgba(0,0,0,0.08),
        inset 0 1px 1px rgba(255,255,255,0.18),
        inset 0 0 0 1px rgba(0,0,0,0.10),
        0 0 0 2px var(--neutral-0, #fff),
        0 0 0 4px var(--brand-primary, #ffc107);
}

/* === Círculo del color (P2: con bisel sutil permanente) ===
   28x28: el color es decisión emocional primaria, +4px de
   presencia frente a la miniatura 24x24 de patas.
   El bisel permanente sugiere "esto es un material/tela",
   no un círculo CSS plano. Coherente con sillones tapizados. */
.sr-ps-color-picker-swatch {
    width: 28px;
    height: 28px;
    border-radius: 50%;
    flex-shrink: 0;
    display: block;
    background-color: var(--neutral-300);
    /* Bisel interno permanente (P2): luz arriba, sombra abajo,
       borde sutil. Tres capas en una sola declaración:
       1) sombra inferior interna → "peso" abajo
       2) luz superior interna → reflejo arriba
       3) borde interno → contorno para colores claros */
    box-shadow:
        inset 0 -1px 2px rgba(0,0,0,0.08),
        inset 0 1px 1px rgba(255,255,255,0.18),
        inset 0 0 0 1px rgba(0,0,0,0.10);
    /* Transición elástica para el bounce al seleccionar */
    transition: box-shadow 0.3s cubic-bezier(0.34, 1.2, 0.64, 1),
                transform 0.3s cubic-bezier(0.34, 1.2, 0.64, 1);
}

/* === Label === heredado de patas: font-size, weight, color
   + ESTABILIZACIÓN DE ANCHO (anti layout shift).
   El problema: al activarse, font-weight 500→600 ensancha el
   texto y los tiles saltan de posición. Solución: reservar
   el ancho del bold con un pseudo-elemento invisible que
   duplica el texto en font-weight:600. El span entero adopta
   siempre el ancho del más ancho de los dos (= el bold).
   Cero shift al cambiar de estado. */
.sr-ps-color-picker-label {
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--neutral-700, #374151);
    line-height: 1;
    /* La estabilización requiere que el span sea inline-flex
       en column para que el ::after fantasma se apile debajo
       (no después) y reserve ancho sin afectar la altura.
       El ::after ghost común está consolidado al final del CSS
       (v6.10.32, "Estabilización ancho — ghost común"). */
    display: inline-flex;
    flex-direction: column;
    align-items: flex-start;
}

/* Animación de presentación del activo (P2): micro-bounce
   elástico que confirma "te oí" sin ser intrusivo. Cubica
   con overshoot ligero (1.4) → vuelta a 1. Se dispara solo
   cuando se aplica la clase --active (no en cada repaint). */
@keyframes sr-ps-color-picker-pop {
    0%   { transform: scale(0.92); }
    50%  { transform: scale(1.04); }
    100% { transform: scale(1); }
}
.sr-ps-color-picker-item.sr-ps-color-picker-item--active .sr-ps-color-picker-swatch {
    animation: sr-ps-color-picker-pop 0.35s cubic-bezier(0.34, 1.4, 0.64, 1);
}
/* Respeta prefers-reduced-motion: sin animación si el usuario
   pidió reducir movimiento (accesibilidad). */
@media (prefers-reduced-motion: reduce) {
    .sr-ps-color-picker-item.sr-ps-color-picker-item--active .sr-ps-color-picker-swatch {
        animation: none;
    }
    .sr-ps-color-picker-swatch {
        transition: none;
    }
}

/* === Estado "sin color configurado" — patrón cuadriculado === */
/* El patrón se aplica solo al círculo .swatch interno; el tile
   mantiene aspecto normal con label legible. El bisel
   permanente sigue presente sobre el cuadriculado. */
.sr-ps-color-picker-item--empty .sr-ps-color-picker-swatch {
    background-color: var(--neutral-100);
    background-image:
        linear-gradient(45deg, var(--neutral-300) 25%, transparent 25%),
        linear-gradient(-45deg, var(--neutral-300) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--neutral-300) 75%),
        linear-gradient(-45deg, transparent 75%, var(--neutral-300) 75%);
    background-size: 6px 6px;
    background-position: 0 0, 0 3px, 3px -3px, -3px 0;
}

/* === Precio incremental ===
   Pill compacta a la derecha del label (coherente con
   sr-ps-segmented-price), no flotante encima como antes.
   Ahora hay sitio dentro del tile para mostrarlo en línea. */
.sr-ps-color-picker-price {
    font-size: 0.6875rem;
    font-weight: 600;
    color: var(--neutral-600, #4B5563);
    line-height: 1;
    margin-left: 0.25rem;
}

/* === Disabled === idéntico patrón a los demás tipos */
.sr-ps-color-picker-item.sr-ps-swatch-disabled {
    opacity: 0.35;
    cursor: not-allowed;
    pointer-events: none;
}
.sr-ps-color-picker-item.sr-ps-swatch-disabled:hover {
    border-color: var(--neutral-200, #E5E7EB);
}

/* === Móvil === el wrap se ajusta solo; sólo reducimos el
   círculo interno levemente para optimizar el alto de fila
   (coherente con las patas en móvil). */
@media (max-width: 767px) {
    .sr-ps-color-picker-swatch {
        width: 24px;
        height: 24px;
    }
    .sr-ps-swatches-color-picker-type .sr-ps-color-picker-grid {
        gap: 0.375rem;
    }
}


/* ===========================================================
   ESTABILIZACIÓN ANCHO — GHOST ::after COMÚN (v6.10.32)
   ===========================================================
   Las 4 reglas ::after de los labels visibles (color_picker,
   patas/images-type, buttons y segmented) eran idénticas
   palabra por palabra: mismas 9 propiedades reservando el
   ancho del bold con un fantasma invisible. Se consolidan
   aquí en una sola regla agrupada por coma, ahorrando ~30
   líneas y centralizando la lógica anti layout shift.
   
   La técnica:
     1) Cada span padre es inline-flex column (ver cada label).
     2) El ::after duplica el texto del span en font-weight:600.
     3) visibility:hidden + height:0 → invisible y sin alto.
     4) El span entero adopta el ancho del más ancho de sus
        hijos = SIEMPRE el ghost bold = ancho ESTABLE entre
        estados normal/activo. Cero layout shift al seleccionar.
   
   Si se añade un nuevo tipo de swatch con label visible y
   bold-on-active, basta con:
     a) Emitir el label con data-label="<texto>" en PHP.
     b) Aplicar inline-flex column al label en CSS.
     c) Añadir su selector::after a esta lista (línea siguiente).
   =========================================================== */
.sr-ps-swatch-label::after,
.sr-ps-swatches-images-type .sr-ps-swatch-inline-label::after,
.sr-ps-segmented-label::after,
.sr-ps-color-picker-label::after {
    content: attr(data-label);
    font-weight: 600;
    visibility: hidden;
    height: 0;
    overflow: hidden;
    pointer-events: none;
    white-space: nowrap;
    font-size: inherit;
    font-family: inherit;
}

/* ============================================================
   v6.10.38 — REDUCED MOTION (A11Y + WPO global)
   ============================================================
   Anula TODAS las transitions/animations del plugin para usuarios
   con prefers-reduced-motion: reduce activado (system setting o
   navegador). Cubre el aviso PageSpeed "Evita las animaciones no
   compuestas" para usuarios sensibles a movimiento y reduce el
   trabajo de paint en dispositivos lentos.

   ESTRATEGIA — bloque consolidado scoped al plugin:
   - Selector [class*="sr-ps-"] limita el alcance a este plugin
     (no toca tema ni otros plugins → cada uno gestiona el suyo
     según WCAG 2.1).
   - !important para vencer la especificidad alta de las reglas
     anteriores (incluye :hover, :focus, selectores compuestos
     como .variations .reset_variations).
   - animation-duration: 0.001ms (no 0): preserva el evento
     'animationend' por si algún JS lo escucha en el futuro
     (defensa). Visualmente equivalente a none.
   - animation-iteration-count: 1: fuerza fin de animaciones
     infinite (shimmer durante carga de imagen).
   - scroll-behavior: auto: anula el smooth-scroll que srPSAttract
     usa en scrollIntoView, para usuarios que pidieron menos
     movimiento (ver render_attract_assets en el PHP, también
     respeta el media query).

   COBERTURA:
   - 12 transitions costosas (color, border-color, background-color,
     box-shadow) sobre swatches, tooltip, radio dot, segmented, etc.
   - 6 @keyframes (sr-ps-shake, sr-ps-attn, sr-ps-shimmer, etc.)
   - .variations .reset_variations (selector sin prefijo sr-ps-, lo
     incluimos explícito porque [class*="sr-ps-"] no lo captura).

   Bloques anteriores en este mismo archivo con prefers-reduced-motion
   (L1249, L1283, L1326, L1661) son específicos por selector — siguen
   ahí como defensa redundante y compatibilidad con versiones que
   pudieran tener override de este bloque global. Eliminarlos podría
   causar regresión si un dev usa el filtro hipotético "quita el bloque
   global"; mantenerlos es coste cero (no se duplica especificidad
   negativamente, ambos resuelven a "none").
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
    [class*="sr-ps-"],
    [class*="sr-ps-"]::before,
    [class*="sr-ps-"]::after {
        transition: none !important;
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        scroll-behavior: auto !important;
    }
    /* Selector del plugin que NO tiene prefijo sr-ps- (es la clase
       nativa de WC pero el plugin la estiliza con transition). */
    .variations .reset_variations {
        transition: none !important;
    }
}
