@charset "UTF-8";
/* Viga: Google Fonts en _Layout.cshtml */

/* === CURVY THEME =========================================================
   Diseno con esquinas redondeadas, curvas via clip-path y paleta verde/rojo/
   morado. Variables responsivas (:root) y breakpoints estan en visor-base.css.
   Reglas estructurales tokenizadas (banda COMPRAR, categorias) en
   visor-structure.css. Reglas comunes tokenizadas en visor-base.css.

   Este archivo contiene (en este orden):
     1) Tokens semanticos del tema Curvy + variables locales derivadas.
     2) Reglas residuales del tema (cards .element-item, footer .bill,
        botones +/-, etc.) que pintan el look Curvy.
     3) Overrides y casos particulares Curvy-only (clip-path en cards y banda
        inferior, posicionado de +/- y badge de cantidad).

   Estrategia responsive:
     - Las cards consumen --card-w / --card-h responsivos (visor-base.css).
     - Las dimensiones internas (alto de la imagen, alto de la banda inferior,
       posicion de los textos, tamano del badge de cantidad) se derivan con
       calc() de --card-w/--card-h para preservar las proporciones del
       diseno (ratio mockup 372x548) en cada breakpoint.
     - clip-path usa polygon() con %, asi la curva se reescala sin deformar.

   Cuidado con clicks en zonas con clip-path: los pseudo-elementos ::before
   con clip-path tienen pointer-events:none para que el clip recorte solo
   visualmente y los clicks lleguen al elemento real (button +/- o card).
   ======================================================================= */

/* === TOKENS SEMANTICOS DEL TEMA CURVY ===================================== */
:root {
    /* Banda COMPRAR (.a_demo_four) - oculta en Curvy, pero mantenemos tokens
       sanos para que no quede vacio si algun caso edge la muestra. */
    --theme-banda-text: #fff;
    --theme-banda-border-side: none;
    --theme-banda-bg: linear-gradient(115deg, #2fd88f 0%, #23c98b 45%, #08b8a0 100%);
    --theme-banda-bg-active: linear-gradient(115deg, #08b8a0 0%, #23c98b 55%, #2fd88f 100%);
    --theme-banda-shadow: none;
    --theme-banda-shadow-active: none;

    /* Categorias (.a_demo_three): mismos tokens que el tema Light — gradiente
       vertical morado oscuro, sombra inset rosa arriba + escalon oscuro
       abajo (efecto boton 3D clasico). */
    --theme-categoria-text: #d4ffeb;
    --theme-categoria-border-side: none;
    --theme-categoria-bg: linear-gradient(to top, rgb(85, 25, 100) 0%, rgb(105, 33, 124) 100%);
    --theme-categoria-bg-active: linear-gradient(to top, rgb(105, 33, 124) 0%, rgb(85, 25, 100) 100%);
    --theme-categoria-shadow: inset 0px 1px 0px #ec29ec, 0px 5px 0px 0px #771585;
    --theme-categoria-shadow-active: inset 0px 1px 0px #ec29ec, 0px 2px 0px 0px #771585;
    /* Curvy: indicador de categoria seleccionada — box-shadow INSET
       verde oscuro (#08b8a0). El inset hace que la franja se pinte
       DENTRO del bottom del boton sin agregar tamaño exterior, asi
       el boton no aparenta engordar al seleccionarse (a diferencia
       del shadow exterior 0 4px 0 que extendia visualmente 4px). */
    --theme-categoria-selected-shadow: inset 0 -4px 0 0 #08b8a0;
    --theme-categoria-selected-text-shadow: none;

    --theme-modal-text: #2c2c2c;
    --theme-input-focus-border: #79279e;
    --theme-input-focus-shadow: inset 0 1px 1px rgba(89, 18, 122, 0.4), 0 0 8px rgba(89, 18, 122, 0.45);
    --theme-btn-action-bg: #79279e;
    --theme-btn-action-bg-hover: #681e8e;
    --theme-btn-action-bg-active: #59127a;
    --theme-btn-action-border: #59127a;
    --theme-btn-action-border-active: #79279e;
    --theme-btn-action-focus-ring: 0 0 0 3px rgba(121, 39, 158, 0.45);
    --theme-cart-empty-color: #59127a;
    --theme-card-text-primary: #3f4650;
    --theme-card-text-secondary: #424a55;
    --theme-text-shadow-emboss: none;
    --theme-modal-close-color: #999;
    --theme-modal-close-opacity: 0.5;
    --theme-input-placeholder: #999;
    --theme-pay-bg: #398439;
    --theme-pay-bg-hover: #449d44;
    --theme-pay-bg-active: #5cb85c;
    --theme-pay-border: #255625;
    --theme-pay-border-hover: #2f7a2f;
    --theme-pay-border-active: #3d8b3d;

    /* Body: gris azulado claro (cuando no se aplica imagen de fondo). */
    --theme-body-bg: #cfd6df;
    --theme-body-color: #2c2c2c;

    /* Botones +/- del modal carrito (.btnm/.btnp) */
    --theme-btn-pm-bg: #E1E8EE;
    --theme-btn-pm-color: #2c2c2c;

    /* Card de producto (.element-item) - Curvy: blanco puro con sombra. */
    --theme-card-bg: #ffffff;
    --theme-card-color: #3f4650;
    --theme-card-border: 5px solid #ffffff;

    --theme-pagar-btn-shadow: 0 4px 10px rgba(89, 18, 122, 0.35);

    /* Footer: barra blanca. */
    --theme-bill-bg: #ffffff;
    --theme-bill-color: #2c2c2c;
    --theme-footer-border-top: none;

    /* Tokens extraidos de overrides */
    --theme-swal-info-color: #79279e;
    --theme-swal-info-border: #79279e;
    --theme-swal-spinner-border: rgba(121, 39, 158, 0.3);
    --theme-swal-spinner-border-left: #79279e;
    --theme-modal-header-bg: linear-gradient(130deg, #79279e 0%, #59127a 100%);
    --theme-modal-header-color: white;
    --theme-modal-header-radius: 18px 18px 0 0;
    --theme-modal-title-color: white;
    --theme-modal-header-close-color: #d4a0d4;
    --theme-modal-header-close-text-shadow: 0 0 6px rgba(180, 120, 185, 0.28);
    --theme-modal-header-close-color-hover: #ffffff;
    --theme-payment-item-bg: #fff;
    --theme-payment-item-shadow: 0 4px 16px rgba(89, 18, 122, 0.07);
    --theme-payment-item-color: #2c2c2c;
    --theme-payment-item-bg-hover: rgba(121, 39, 158, 0.05);
    --theme-payment-item-shadow-hover: 0 6px 20px rgba(121, 39, 158, 0.15);
    --theme-payment-item-logo-bg: #f5f0f9;
    --theme-payment-item-logo-border-color: rgba(121, 39, 158, 0.14);
    --theme-payment-item-name-color: #2d2d2d;
    --theme-cart-table-border-color: rgba(121, 39, 158, 0.2);
    --theme-cart-desc-color: rgba(68, 68, 68, 0.9);
    --theme-cart-qty-input-bg: rgba(121, 39, 158, 0.10);
    --theme-cart-qty-input-color: #59127a;
    --theme-cart-qty-input-font-weight: 700;

    /* === VARIABLES LOCALES CURVY (derivadas del card responsivo) ==========
       Las proporciones del mockup original (372x548) se preservan calculando
       cada dimension interna en funcion de --card-w / --card-h. Asi, en cada
       breakpoint donde visor-base.css redefine --card-w/--card-h, la card
       Curvy se reescala manteniendo la misma silueta.
         - Imagen: cuadrada, ancho util de la card (card-w - 10 por borders).
         - Banda inferior: ~13.5% de card-h (mockup: 73/548 = 13.32%).
         - Cuerpo blanco con curva: ~53.3% de card-h (mockup: 292/548).
         - Textos y precio: posicion proporcional al alto de la card.
         - Badge de cantidad: ~64% de la altura de la banda. */
    --curvy-card-inner-w: calc(var(--card-w) - 10px);
    --curvy-image-h: var(--curvy-card-inner-w);
    /* Card height efectivo de Curvy: 50px menos que --card-h base de
       visor-base.css. Todas las dimensiones internas se derivan de este
       valor para mantener proporciones del mockup en el card compacto. */
    --curvy-card-h: calc(var(--card-h) - 50px);
    --curvy-bar-h: calc(var(--curvy-card-h) * 0.135);
    --curvy-body-h: calc(var(--curvy-card-h) * 0.534);
    /* === BORDER RADIUS GLOBAL DEL TEMA CURVY =============================
       Variable unica que controla el border-radius de TODOS los elementos
       principales: card, marco gris (::after), imagen (top corners),
       banda .sig (TL+BL via border-radius), pildoras de categoria, .bill.
       Tambien controla el rounding TL/BL del PAGAR (via border-radius en
       .sig; el clip-path solo se encarga del bezier concavo de la
       derecha, que NO se debe tocar). Cambiar SOLO este valor para
       variar la apariencia de los corners de toda la card y footer. */
    --curvy-radius: 15px;
    /* Badge mas grande para que se note en el top-right del card.
       0.95 del bar-h da ~54px en default (era 37px con 0.64). */
    --curvy-qty-size: calc(var(--curvy-bar-h) * 0.95);
    --curvy-qty-fs: calc(var(--curvy-bar-h) * 0.55);
    /* Badge del carrito EN EL FOOTER: mas chico que el badge del top-right
       de cada card. El footer ya tiene icono + precio dominantes, asi que
       un badge al 70% del tamano del de las cards queda mejor proporcionado
       en notebooks landscape (1366-1599). */
    --curvy-footer-qty-size: calc(var(--curvy-qty-size) * 0.9);
    --curvy-footer-qty-fs: calc(var(--curvy-qty-fs) * 0.9 - 2px);
    --curvy-signos-mas-fs: calc(var(--curvy-bar-h) * 0.85);
    --curvy-signos-menos-fs: calc(var(--curvy-bar-h) * 0.64);
    /* Top de cada texto, proporcional al card-h (modelo Curvy: los textos
       caen dentro de la zona blanca tipo "bill"). name=0.64, price=0.80, y
       desc en el midpoint exacto (0.72) para que name->desc y desc->price
       queden iguales. El -Npx afina cada baseline dentro de su franja.
       Equivalente Curvy de --card-text-*-top del base (visor-base.css):
       un tema "tipo Curvy" reescribe estas 3 variables, no las reglas. */
    --curvy-text-name-top: calc(var(--curvy-card-h) * 0.64 - 5px);
    --curvy-text-desc-top: calc(var(--curvy-card-h) * 0.72 - 7.5px);
    --curvy-text-price-top: calc(var(--curvy-card-h) * 0.80 - 10px);
}

/* === BODY / BACKGROUND ==================================================== */

/* El _Layout.cshtml maneja el background-image de fondo (con image overlay)
   para Curvy igual que para Neon/Dark. Aqui solo definimos color de fallback
   y opciones de tipografia. */
body.totem-curvy {
    background-color: #cfd6df;
    color: #2c2c2c;
    font-family: 'Viga', sans-serif;
}

/* === CATEGORIAS (.top-nav .a_demo_three) ==================================
   Curvy: pildoras moradas redondeadas, mantienen el contrato del JS de
   isotope/filtros (clases .selected/.is-selected, etc.). */
/* === CATEGORIAS CURVY (estilo "compra"): pildora con badge rojo curvo
   a la izquierda + gradiente verde a la derecha, replicando el patron
   del .sig (boton comprar) del card. Position:relative + overflow:hidden
   para que el ::before con clip-path quede contenido. */
.top-nav .a_demo_three,
.top-nav a.a_demo_three {
    position: relative !important;
    /* overflow:visible para que el ::after (linea debajo de la categoria
       seleccionada) no quede clipped. El bg gradient se clipea solo por
       border-radius asi que no hay leak visual. */
    overflow: visible !important;
    border: none !important;
    border-radius: var(--curvy-radius) !important;
    /* Estado normal: solo verde (sin el rojo). El degradado rojo se
       agrega solo en :active (ver regla mas abajo). Solo se usa
       background-image (sin shorthand background) y SIN !important
       para que la animacion del .is-checked pueda retener su estado
       final con animation-fill-mode:forwards. El shorthand background
       con !important hubiera locked el bg-image internamente. */
    background-image: linear-gradient(130deg,
        #2fd88f 0%,
        #2fd88f 30%,
        #08b8a0 80%,
        #08b8a0 100%);
    /* Padding-left removido: el rojo es parte del gradient del bg
       (no un elemento separado que ocupe espacio), asi que no hace
       falta reservar area. Padding simetrico (default clamp via
       visor-structure.css) deja el texto naturalmente centrado en
       el boton. text-align:center alinea el caracter horizontalmente. */
    text-align: center !important;
    color: var(--theme-categoria-text) !important;
    /* Pill mas bajo en Curvy: override del --pad-y de
       visor-structure.css (clamp(8px,1.1vw,14px) -> clamp(5px,0.85vw,11px)).
       En 1536px el pad-y resuelto pasa de 14 -> 11 = 6px menos de alto total.
       El padding se sigue declarando en .a_demo_three con var(--pad-y),
       que resuelve esta version en cascada por mayor especificidad. */
    --pad-y: clamp(5px, 0.85vw, 11px);
    /* Marco gris real via ::after (ver regla mas abajo) — mismo
       rendering que el card .element-item. Solo .is-checked usa
       box-shadow como fallback (overflow:hidden lo necesita y
       recorta el ::after). */
    box-shadow: none !important;
    text-shadow: none !important;
    /* Margin-right extra para compensar el marco gris (5px) y dar
       separacion visible entre pildoras adyacentes. */
    margin-right: 25px !important;
    margin-bottom: -13px;
    /* Transition para el efecto "press" al clickear. */
    transition: box-shadow 0.15s ease-out !important;
}

/* Efecto press de la pildora de categoria (cualquier boton al
   presionarse): box-shadow inset oscuro como feedback visual. */
.top-nav .a_demo_three:active,
.top-nav a.a_demo_three:active {
    /* Solo press feedback (inset oscuro). El marco gris lo aporta el
       ::after (en non-selected) o el box-shadow (en .is-checked). */
    box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.10) !important;
}

/* Marco gris real via ::after para categorias no seleccionadas — mismo
   rendering que .element-item::after del card (border:5px solid + inset
   :-4px + border-radius concentrico). En .is-checked el overflow:hidden
   recorta este ::after, asi que para ese estado se usa box-shadow como
   fallback (ver .is-checked rule mas abajo). */
.top-nav .a_demo_three:not(.is-checked)::after,
.top-nav a.a_demo_three:not(.is-checked)::after {
    content: "" !important;
    position: absolute !important;
    inset: -2px !important;
    border: 3px solid #eeeeee !important;
    border-radius: calc(var(--curvy-radius) + 2px) !important;
    box-sizing: border-box !important;
    pointer-events: none !important;
    z-index: 10 !important;
    /* Misma drop-shadow que el .element-item::after del card. */
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.35) !important;
}

/* Categoria seleccionada (.is-checked): el bg ARRANCA solido verde
   (mismo gradient que el normal pero con stops "extra" para que la
   interpolacion al estado final funcione). Durante el sweep del rojo
   el bg se ve solido — no hay degradado verde izquierdo visible.
   A los 0.6s (cuando el rojo termina), el bg hace una transicion
   hacia "verde-con-transparente-izquierda" via @keyframes. Asi en
   el estado final el rojo del ::before se ve PURO sobre el bg del
   parent (donde el bg verde quedo transparente), igual que el
   layered original. */
.top-nav .a_demo_three.is-checked,
.top-nav a.a_demo_three.is-checked {
    /* Mantiene el marco gris + drop-shadow del card en estado seleccionado
       (via box-shadow porque overflow:hidden recortaria el ::after). */
    box-shadow: 0 0 0 3px #eeeeee, 0 5px 12px rgba(0, 0, 0, 0.35) !important;
    overflow: hidden !important;
    color: #ffffff !important;
    /* z-index:0 + position:relative crea stacking context, asi el
       ::before con z:-1 queda DEBAJO del texto in-flow (que paint
       despues de los negative-z descendants). */
    z-index: 0 !important;
    /* Bg verde solido (mismo que el normal). El rojo ahora es un badge
       solido en el ::before — no hace falta animar el bg. */
}

/* ::before — badge ROJO curvo en el lado izquierdo del boton, mismo
   estilo que el .sig::before del card (clip-path curvyBadge + color
   solido sin degradado). Aspect-ratio 2:1 matchea la proporcion del
   badge original. height:50% lo achica a la mitad (centrado vertical
   con top:25%/bottom:25%). z-index:-1 deja el texto del boton arriba.
   La animacion mueve el badge de left:100% (off a la derecha) a left:0
   (posicion final), independientemente del ancho. */
.top-nav .a_demo_three.is-checked::before,
.top-nav a.a_demo_three.is-checked::before {
    content: "" !important;
    position: absolute !important;
    top: 0 !important;
    bottom: 0 !important;
    /* Sin !important en left: la animacion sweep-red-rtl interpola left
       de 100% a 0 y necesita poder override el valor estatico (CSS
       animations son blocked por author !important). */
    left: 0;
    right: auto !important;
    width: auto !important;
    aspect-ratio: 1 / 1 !important;
    z-index: -1 !important;
    border-radius: 0 !important;
    /* Mismo gradiente que el .sig::before: rosa muy claro (#ffb5b3,
       casi blanco) arriba-izquierda -> rojo oscuro (#cc0010) abajo-
       derecha. El 0% en (130deg) cae en la esquina superior izquierda
       creando un "halo blanco" sutil en esa zona, igual que el badge
       del boton comprar. */
    background: linear-gradient(130deg, #ffb5b3 0%, #ff6b68 25%, #ff303b 75%, #cc0010 100%) !important;
    clip-path: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><clipPath id='curvyBadgeCat' clipPathUnits='objectBoundingBox'><path d='M 0 0 H .9178 C .7671 .4932 .5411 .8356 .1370 1 H 0 Z'/></clipPath></svg>#curvyBadgeCat") !important;
    pointer-events: none !important;
    /* Direccion del sweep determinada por la clase agregada en visor-principal.js:
       .sweep-from-right -> rojo entra desde la derecha (RTL)
       .sweep-from-left  -> rojo entra desde la izquierda (LTR)
       Default si no hay clase: RTL (compatibilidad). */
    animation: sweep-red-rtl 0.35s ease-out forwards !important;
}

.top-nav .a_demo_three.is-checked.sweep-from-right::before,
.top-nav a.a_demo_three.is-checked.sweep-from-right::before {
    animation: sweep-red-rtl 0.35s ease-out forwards !important;
}

.top-nav .a_demo_three.is-checked.sweep-from-left::before,
.top-nav a.a_demo_three.is-checked.sweep-from-left::before {
    animation: sweep-red-ltr 0.35s ease-out forwards !important;
}

@keyframes sweep-red-rtl {
    from { left: 100%; }
    to { left: 0; }
}

@keyframes sweep-red-ltr {
    from { left: -100%; }
    to { left: 0; }
}

/* Estado NO seleccionado: ::before deshabilitado. */
.top-nav .a_demo_three:not(.is-checked)::before,
.top-nav a.a_demo_three:not(.is-checked)::before {
    content: none !important;
}



/* === GRID / LAYOUT DE PRODUCTOS ==========================================
   El layout de cards lo maneja Isotope masonry (visor-principal.js initIsotopeGrid),
   que posiciona cada .element-item con position:absolute + transform.
   No usar display:flex/grid aqui: Isotope ignora flex/gap y la presencia
   de esas propiedades confunde al lector. La separacion entre cards se
   da via margin en .element-item (Isotope si respeta margin como gutter). */
.center-nav .grid {
    padding: 12px 0;
}

/* En landscape, visor-base.css topa .center-nav a 5*(card-w + 10px) que
   asume 5px de margin a cada lado (gutter 10). Como Curvy usa margin:12
   (gutter 24), el ancho default ya no alcanza para 5 cards. Override:
   5*(card-w + 24) que es el ancho efectivo de cada card con su margin. */
@media (orientation: landscape) {
    body.totem-curvy .center-nav {
        max-width: calc(5 * (var(--card-w) + 24px)) !important;
    }
}

/* === CARD DE PRODUCTO (.element-item) =====================================
   Forma curvy: usa --card-w / --card-h responsivos. Border 5px blanco que
   crea el "marco" del diseno; box-sizing: border-box mantiene el ancho/alto
   externo igual al definido por el breakpoint.

   IMPORTANTE: NO forzar position: relative aqui. Isotope masonry necesita
   position: absolute en .element-item para colocarlas; si forzamos relative
   con !important, Isotope sigue aplicando el transform: translate(x,y)
   calculado para absolute y las cards quedan diagonalmente desfasadas. */
.element-item {
    width: var(--card-w) !important;
    /* Curvy-only: --curvy-card-h = --card-h - 50px (definido en :root).
       Todas las variables internas (bar-h, body-h, text-*-top) se
       derivan del mismo valor, asi proporciones internas se mantienen. */
    height: var(--curvy-card-h) !important;
    border: none !important;
    border-radius: var(--curvy-radius) !important;
    /* overflow:visible permite que .totem-cart-qty (badge top-right) se
       pueda salir del card y se vea por encima de cards adyacentes. La
       imagen, la curva (::before) y la banda .sig tienen su propio
       border-radius asi que no se desbordan visualmente. */
    /* Background con gradiente: blanco arriba (detras de la imagen) y
       gris claro #eeeeee en la zona inferior detras de la banda .sig
       (mismo gris que el border y el badge de cantidad). */
    background: linear-gradient(
        to bottom,
        #ffffff 0%,
        #ffffff calc(100% - var(--curvy-bar-h) - 1px),
        #eeeeee calc(100% - var(--curvy-bar-h) - 1px),
        #eeeeee 100%
    ) !important;
    overflow: visible !important;
    cursor: pointer !important;
    /* La drop-shadow vive en el ::after (marco exterior). El marco
       solapa 1px hacia adentro del card asi que no hace falta un
       inset aqui. */
    box-shadow: none !important;
    padding: 0 !important;
    /* Margin: 20px en ambos ejes. Isotope masonry usa esto como gutter.
       Resultado: 40px entre cards (20 + 20) tanto horizontal como
       verticalmente. */
    margin: 20px !important;
    box-sizing: border-box !important;
}

/* Marco gris de 5px dibujado POR FUERA del card, solapando 1px hacia
   adentro para evitar AA gaps sub-pixel en las curvas redondeadas.
   - inset:-4px: el ::after extiende 4px hacia afuera del card.
   - border:5px (box-sizing:border-box): la franja gris ocupa los 5px
     mas externos del ::after, asi el border-inner-edge queda a +1px
     DENTRO del card (overlap de 1px que cubre cualquier gap AA).
   - border-radius:curvy-radius+4: concentrico con la curva del card
     (centro comun) → outer del frame y outer del card son arcos del
     mismo punto, sin posibilidad de mismatch.
   pointer-events:none para no bloquear clicks. */
.element-item::after {
    content: "" !important;
    position: absolute !important;
    inset: -4px !important;
    border: 5px solid #eeeeee !important;
    border-radius: calc(var(--curvy-radius) + 4px) !important;
    box-sizing: border-box !important;
    pointer-events: none !important;
    z-index: 10 !important;
    /* Sombra del card movida aqui: se proyecta desde el marco exterior
       en vez del card interno para que no aparezca un halo entre ambos. */
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.35) !important;
}

/* === IMAGEN DEL PRODUCTO ==================================================
   Imagen ocupa la zona superior con object-fit:cover (no contain como en
   los otros temas) para que llene la zona y la curva blanca le tape la mitad
   inferior con efecto onda. Alto = ancho util (cuadrada) para conservar la
   estetica del mockup en todos los breakpoints. */
.element-item img {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: auto !important;
    width: 100% !important;
    height: var(--curvy-image-h) !important;
    object-fit: cover !important;
    object-position: center !important;
    /* Esquinas top redondeadas con --curvy-radius directo (igual que
       el card, .sig, categorias y bill). Cambiando la variable
       global se ajusta tambien la imagen. */
    border-radius: var(--curvy-radius) var(--curvy-radius) 0 0 !important;
    z-index: 1 !important;
    margin: 0 !important;
    display: block !important;
}

/* === CURVA BLANCA SOBRE LA IMAGEN ==========================================
   Pseudo-elemento ::before del .element-item con clip-path en polygon()
   (con %) que dibuja una onda blanca sobre la mitad inferior de la imagen y
   se extiende hasta donde empieza la banda de controles. polygon() escala
   limpio en cualquier ancho/alto (path() con coords absolutas no escalaba).
   pointer-events:none para que NO bloquee los clicks (que deben pasar a la
   card o a los buttons +/-). */
.element-item::before {
    content: "" !important;
    position: absolute !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: var(--curvy-bar-h) !important;
    height: var(--curvy-body-h) !important;
    /* Blanco semi-transparente con gradiente vertical: el body-bg de la
       pantalla se ve a traves dando un efecto "frosted glass" sutil. Mas
       opaco arriba (.75) para definir la curva y mas translucido abajo
       (.55) para que se funda con la banda verde. */
    background: linear-gradient(to top, rgba(238, 238, 238, 0.95) 0%, rgba(238, 238, 238, 0.95) 40%, rgba(238, 238, 238, 0.50) 100%) !important;
    /* CURVA REAL (no polygon) del mockup. clip-path: url(svg-data-uri)
       referencia un <clipPath clipPathUnits="objectBoundingBox"> con dos
       cubic-bezier identicos al mockup:
         M 0 152 C 95 150 238 127 315 55 C 342 30 357 10 362 0 ...  (372x292)
       Coordenadas normalizadas a 0..1 dividiendo por el ancho/alto del
       bounding box (objectBoundingBox), por lo que la curva escala en
       cualquier breakpoint sin perder la forma. */
    clip-path: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><clipPath id='curvyBody' clipPathUnits='objectBoundingBox'><path d='M 0 .5205 C .2554 .5137 .6398 .4349 .8468 .1884 C .9194 .1027 .9597 .0342 1 0 L 1 1 L 0 1 Z'/></clipPath></svg>#curvyBody") !important;
    z-index: 2 !important;
    pointer-events: none !important;
    border-radius: 0 !important;
    transform: none !important;
    box-shadow: none !important;
    margin: 0 !important;
    padding: 0 !important;
}

/* Sin imagen: mantenemos la curva blanca para coherencia visual. */
/* Sin imagen: ocultamos tambien el ::before con la curva (no tiene
   sentido mostrar la onda blanca si no hay imagen detras). El card
   queda gris liso con titulo/desc/precio y la banda .sig al pie. */
.element-item.no-image::before {
    display: none !important;
}

/* Sin imagen: el placeholder (icono centrado) se ve pixelado con
   object-fit:cover (zoomea + crop). object-fit:contain lo muestra
   completo a tamano natural dentro del area, evitando los bordes
   pixelados. Las fotos reales de producto siguen con cover. */
.element-item.no-image img {
    object-fit: contain !important;
}

/* Cuando el producto no tiene imagen real, mismo gradiente blanco
   semi-transparente que el ::before — el body-bg se ve a traves dando
   look "frosted glass" uniforme en todo el card. */
.element-item.no-image {
    background: linear-gradient(to top, rgba(238, 238, 238, 0.95) 0%, rgba(238, 238, 238, 0.95) 40%, rgba(238, 238, 238, 0.50) 100%) !important;
}

/* === TEXTOS SOBRE LA CURVA ================================================
   Nombre, descripcion y precio se posicionan en la zona blanca de la card
   (encima de la curva clip-path). z-index:3 los pone por encima del ::before.
   font-size se conecta con las variables responsivas --text-*-fs ya
   definidas en visor-base.css por breakpoint. */
.element-item .product-name {
    position: absolute !important;
    top: var(--curvy-text-name-top) !important;
    /* Centrado horizontal por translateX (mismo enfoque que .precioso):
       elimina cualquier desfase que pudiera venir de margenes/line-height
       heredados. width:max-content + max-width para no desbordar. */
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    width: max-content !important;
    max-width: calc(100% - 24px) !important;
    bottom: auto !important;
    margin: 0 !important;
    text-align: center !important;
    color: #3f4650 !important;
    font-size: var(--text-name-fs) !important;
    font-weight: 400 !important;
    letter-spacing: 0.8px !important;
    text-transform: uppercase !important;
    line-height: 1.2 !important;
    z-index: 3 !important;
    /* Sombra blanca sutil que ayuda a legibilidad sobre la curva
       semi-transparente, sin saturar la card. */
    text-shadow: 0.8px 0.8px 0 #a8b0bc !important;
}

.element-item .product-description {
    position: absolute !important;
    top: var(--curvy-text-desc-top) !important;
    /* Centrado por translateX igual que name/precio. El rombo (vineta)
       que aparece via ::before cuando la desc esta vacia hereda el
       text-align:center del padre, asi tambien queda centrado. */
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    width: max-content !important;
    max-width: calc(100% - 24px) !important;
    bottom: auto !important;
    margin: 0 !important;
    text-align: center !important;
    color: #424a55 !important;
    font-size: var(--text-desc-fs) !important;
    font-weight: 400 !important;
    line-height: 1.45 !important;
    z-index: 3 !important;
    text-shadow: 0.8px 0.8px 0 #a8b0bc !important;
    /* Limita a 1 linea en Curvy: las cards mas chicas (180x330, 200x360)
       no tienen espacio vertical suficiente para 2 lineas + precio sin que
       la desc pise al precio. Para texto largo, ellipsis con nowrap.
       Otros temas (Light/Neon/Dark) si usan 2 lineas. */
    display: block !important;
    overflow: hidden !important;
    max-height: 1.5em !important;
    white-space: nowrap !important;
    text-overflow: ellipsis !important;
    -webkit-line-clamp: 1 !important;
}

/* Override empty state: visor-base.css aplica min-height: 2.4em al separador
   ::before del rombo cuando la desc esta vacia. En Curvy con desc de 1 linea
   y posicionamiento absoluto, esa altura extra agrega lineas del separador
   que pisan al precio. Forzamos 1.45em para que el separador del rombo
   ocupe el alto de una sola linea. */
.element-item .product-description:empty {
    min-height: 1.45em !important;
    max-height: 1.45em !important;
}

.element-item .precioso {
    position: absolute !important;
    /* La compensacion de altura vive directamente en --curvy-text-price-top
       (0.80*card-h - 10px). Usar la variable tal cual mantiene la simetria
       con name/desc y permite que el midpoint de desc siga siendo exacto. */
    top: var(--curvy-text-price-top) !important;
    /* Centrado horizontal explicito via translateX: el elemento se posa
       con su centro en x=50% del card, sin importar el ancho del texto.
       Mas confiable que left:12+right:12+text-align:center si algun
       flow externo (margenes heredados del <p>, line-height, etc.) corre
       el bounding box. max-width acota el ancho a card-w menos 24px de
       respeto a los bordes. */
    left: 50% !important;
    right: auto !important;
    transform: translateX(-50%) !important;
    width: max-content !important;
    max-width: calc(100% - 24px) !important;
    bottom: auto !important;
    margin: 0 !important;
    text-align: center !important;
    /* Mismo gris azulado que .product-name (#3f4650): coherencia con los
       otros textos de la card (titulo y descripcion ya usan tonos del
       mismo family). Weight 500 (no 600/800 que se veian "strong") y
       sin letter-spacing negativo que descentraba visualmente el texto.
       text-align:center + left/right simetricos garantizan el centrado
       horizontal real. */
    color: #3f4650 !important;
    font-family: 'Viga', sans-serif !important;
    font-size: var(--text-price-fs) !important;
    font-weight: 500 !important;
    line-height: 1 !important;
    z-index: 3 !important;
    text-shadow: 0.8px 0.8px 0 #a8b0bc !important;
}

/* === BANDA INFERIOR (.a_demo_four oculta + .sig siempre visible) ===========
   Curvy NO usa el modelo "click en banda -> COMPRAR -> aparecen +/-". En su
   lugar, la fila .sig esta siempre visible (con la banda verde y el badge
   rojo). El primer click en .signos.mas (+) agrega 1 al carrito, igual que
   un click en la imagen o en cualquier zona del .element-item. */
.element-item .a_demo_four,
.element-item .a_demo_static {
    display: none !important;
}

.element-item .sig {
    position: absolute !important;
    left: 0 !important;
    right: 0 !important;
    top: auto !important;
    bottom: 0 !important;
    width: calc(100% - 2px) !important;
    margin: 0 auto !important;
    height: var(--curvy-bar-h) !important;
    z-index: 3 !important;
    overflow: hidden !important;
    /* Mismo border-radius que el card en los 4 corners via --curvy-radius.
       Importante: BR y BL deben matchear el rounding del card (sino el
       verde se sale por la curva inferior del card). El .sig NO tiene
       clip-path propio, asi que border-radius sí controla la forma. */
    border-radius: var(--curvy-radius) !important;
    /* Transition para el efecto "press" cuando el usuario hace click en
       el "+". Ahora el efecto es box-shadow inset (no filter), asi que
       transition incluye box-shadow. transform/filter se mantienen para
       compatibilidad con otras reglas que los usan. */
    transition: box-shadow 0.15s ease-out, transform 0.15s ease-out, filter 0.15s ease-out !important;
    /* Gradiente verde extendido: agregamos stops mas claros al inicio
       (#58ffb0) y mas oscuro al final (#006b5a) para que la variacion
       cromatica se note en el bar chico. El mockup usa solo 3 stops
       intermedios; el bar a tamano original (372x73) muestra el
       gradiente, pero al reducirse a 300x57 el rango es muy estrecho.
       Estos extra stops amplifican el efecto sin cambiar la paleta. */
    background: linear-gradient(144deg, #8effc6 20%, #2fd88f 42%, #23c98b 52%, #08b8a0 70%) !important;
    /* !important fuerza visible aunque el HTML inline diga display:none. El
       JS hace .show()/.hide() del .sig segun qty, pero en Curvy la banda
       siempre esta visible (visualmente es parte de la card). */
    display: flex !important;
    flex-direction: row !important;
    align-items: center !important;
    justify-content: flex-start !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 auto !important;
    border: none !important;
}

/* Badge rojo curvo en el lado izquierdo de la banda. clip-path en polygon()
   con % para que escale con el ancho del badge. Width = 2 * bar-h preserva
   el ratio 2:1 del mockup (146x73). pointer-events:none para que los clicks
   pasen al boton minus que va por encima. */
.element-item .sig::before {
    content: "" !important;
    position: absolute !important;
    left: 0 !important;
    /* top:-1 + height +1 hace que el ::before (rojo) se extienda 1px
       sobre el borde superior del .sig. Sin esto, el border-radius:14px
       del .sig clipea el ::before en el corner curvo y dejaba un
       sub-pixel de "alto extra" del verde respecto al rojo por
       anti-aliasing. El clip-path del ::before sigue mappeado al
       objectBoundingBox del nuevo box ligeramente mas alto. */
    top: -1px !important;
    width: calc(var(--curvy-bar-h) * 2) !important;
    height: calc(100% + 1px) !important;
    /* Transition para el efecto "press" (transform + brightness) cuando
       el usuario hace click en el "-" — el :has(...) selector aplica el
       estado active al ::before. */
    transition: transform 0.15s ease-out, filter 0.15s ease-out !important;
    /* Gradiente rojo extendido: agregamos un rosa mas claro al inicio
       (#ffb5b3) y un rojo mas oscuro al final (#cc0010) para que la
       variacion se note en el badge chico. Mismo razonamiento que el
       verde — paleta del mockup extendida en los extremos. */
    background: linear-gradient(130deg, #ffb5b3 0%, #ff6b68 25%, #ff303b 75%, #cc0010 100%) !important;
    /* CURVA REAL del badge rojo del mockup:
         M 0 0 H 134 C 112 36 79 61 20 73 H 0 Z   (146x73)
       Normalizado a objectBoundingBox (0..1) para que escale con el
       ancho/alto del ::before en cada breakpoint. */
    clip-path: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><clipPath id='curvyBadge' clipPathUnits='objectBoundingBox'><path d='M 0 0 H .9178 C .7671 .4932 .5411 .8356 .1370 1 H 0 Z'/></clipPath></svg>#curvyBadge") !important;
    z-index: 1 !important;
    pointer-events: none !important;
    margin: 0 !important;
    padding: 0 !important;
    border-radius: 0 !important;
}

/* Boton minus en zona roja. SIEMPRE visible (el mockup lo muestra aun con
   qty=0). Centrado visualmente en la mitad horizontal del rojo a y=50%
   del bar: a y=mid el rojo va de x=0 a x ~= bar-h (donde la curva cruza
   la mitad), asi que el centro del rojo a esa Y es x=0.5*bar-h.
   translate(-50%,-50%) hace que (left,top) sea el CENTRO del elemento
   (no la esquina), simplificando el centrado. La compose de transforms
   se aplica derecha-a-izquierda: skew y scale primero, translate al
   final, asi que el centrado funciona aun con la deformacion. */
/* "-" cubre TODA la zona del badge rojo (2*bar-h x bar-h) para que el
   click funcione en cualquier parte del rojo, no solo en el glifo
   chico. Background transparente -> solo se ve el "-" gracias al
   gradient text. text-align center + line-height = altura centra el
   simbolo horizontal y verticalmente dentro del rectangulo grande. */
.element-item .signos.menos {
    position: absolute !important;
    left: 0 !important;
    top: -4px !important;
    right: auto !important;
    bottom: auto !important;
    width: calc(var(--curvy-bar-h) * 2) !important;
    height: 100% !important;
    min-width: 0 !important;
    border: 0 !important;
    /* Forzar click area: pointer-events:auto y appearance:none para que
       el <input type=button> sea totalmente clickeable en su rectangulo
       sin que el browser aplique estilos default que limiten el area. */
    pointer-events: auto !important;
    -webkit-appearance: none !important;
    appearance: none !important;
    background: linear-gradient(130deg, #ffffff 0%, #ffeeec 50%, #ffd0cc 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    color: transparent !important;
    font-family: 'Viga', sans-serif !important;
    font-weight: 800 !important;
    font-size: calc(var(--curvy-signos-menos-fs) + 4px) !important;
    line-height: var(--curvy-bar-h) !important;
    text-align: center !important;
    cursor: pointer !important;
    z-index: 4 !important;
    /* Padding asimetrico: padding-right desplaza el centro del texto
       hacia la izquierda dentro del rectangulo grande, replicando la
       posicion visual que tenia el "-" cuando estaba en x = bar-h/2 + 5.
       Formula: padding-right = bar-h - 10 hace que el text-align:center
       resulte en center_x = bar-h/2 + 5 dentro de un box de 2*bar-h. */
    padding: 0 calc(var(--curvy-bar-h) - 10px) 0 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
    text-shadow: none !important;
    visibility: visible !important;
}

/* Boton mas en zona verde. Centrado visualmente en la mitad horizontal
   del verde a y=50% del bar: a y=mid el verde va de x ~= bar-h (donde
   la curva del rojo cruza la mitad) a x=100% (ancho del card), asi
   que el centro del verde a esa Y es x = 50% + 0.5*bar-h.
   translate(-50%,-50%) ubica el centro del elemento en (left,top). */
/* "+" cubre TODA la zona verde (desde el ancho del badge hasta el
   borde derecho del bar) para que el click funcione en cualquier
   parte del verde, no solo en el glifo. text-align center centra el
   "+" horizontalmente; line-height = altura del bar lo centra
   verticalmente. */
.element-item .signos.mas {
    position: absolute !important;
    left: calc(var(--curvy-bar-h) * 2) !important;
    top: -2px !important;
    right: 0 !important;
    bottom: auto !important;
    width: auto !important;
    height: 100% !important;
    min-width: 0 !important;
    border: 0 !important;
    /* Forzar click area total (ver .signos.menos para razon). */
    pointer-events: auto !important;
    -webkit-appearance: none !important;
    appearance: none !important;
    /* Degradado mint claro -> blanco aplicado al "+" via background-clip:
       text (tecnica de gradient text). Mismo angulo 135deg que el degradado
       morado del PAGAR para coherencia. El degradado va de blanco puro
       arriba-izquierda a mint suave abajo-derecha, asi el "+" tiene una
       sutil sensacion de brillo/profundidad sin chocar con el verde del
       fondo (misma familia cromatica) y manteniendo alto contraste por
       diferencia de luminosidad (~12:1 vs el verde mas oscuro #08b8a0).
       -webkit-text-fill-color anula el color base para que el clip text
       se vea (sin esto el color del input renderiza encima del clip). */
    background: linear-gradient(130deg, #ffffff 0%, #d4ffeb 50%, #a8f0cd 100%) !important;
    -webkit-background-clip: text !important;
    background-clip: text !important;
    -webkit-text-fill-color: transparent !important;
    color: transparent !important;
    font-family: 'Viga', sans-serif !important;
    font-weight: 800 !important;
    font-size: var(--curvy-signos-mas-fs) !important;
    line-height: var(--curvy-bar-h) !important;
    text-align: center !important;
    cursor: pointer !important;
    z-index: 4 !important;
    /* Mismo desplazamiento de padding-right que el "-", para que el "+"
       quede 0.5*bar-h - 5px a la izquierda del centro del rectangulo
       verde, replicando la posicion visual original. */
    padding: 0 calc(var(--curvy-bar-h) - 10px) 0 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
    text-shadow: none !important;
}

/* === EFECTO PRESS (oscurecimiento) DE LOS BOTONES +/- ===================
   Click en "+" o "-" → la zona correspondiente se oscurece y vuelve.
     - "-" :active  =>  filter:brightness en .sig::before (solo el rojo).
     - "+" :active  =>  box-shadow:inset negro semi-transparente sobre el
       .sig (oscurece SOLO el verde porque el ::before z-index:1 se pinta
       encima, sin verse afectado). Antes intentamos filter en el .sig
       con un counter-filter en el ::before, pero los canales del rojo
       que estan en 255 saturan con el counter (clamp) y al componerse
       quedan oscurecidos — el box-shadow inset evita ese problema. */
.element-item .sig:has(.signos.menos:active)::before {
    filter: brightness(0.85) !important;
}

.element-item .sig:has(.signos.mas:active) {
    box-shadow: inset 0 0 0 9999px rgba(0, 0, 0, 0.08) !important;
}

/* Badge de cantidad: pildora verde semi-transparente arriba a la derecha
   del .sig. Aparece solo cuando hay numero (CSS :empty). Tamano y fuente
   escalan con la altura de la banda. */
/* En Curvy el badge .totem-cart-qty se renderiza como hijo directo de
   .element-item (no dentro de .sig — ver _Products.cshtml). Por eso
   position:absolute aqui referencia al .element-item, no al bar.
   top/right en pixeles desde el borde superior derecho del card. */
.element-item .totem-cart-qty {
    position: absolute !important;
    right: -15px !important;
    top: -15px !important;
    left: auto !important;
    bottom: auto !important;
    width: var(--curvy-qty-size) !important;
    height: calc(var(--curvy-qty-size) - 2px) !important;
    border-radius: calc(var(--curvy-qty-size) * 0.36) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    z-index: 4 !important;
    /* Mismo gris #eeeeee que usa el card (border, fondo bajo curva, body
       background). Texto en #3f4650 (mismo que el titulo del card) para
       coherencia y buen contraste sobre el gris claro. Borde blanco
       para separarlo visualmente del card al estar pegado al corner. */
    background: #eeeeee !important;
    color: #3f4650 !important;
    border: 4px solid #ffffff !important;
    font-size: var(--curvy-qty-fs) !important;
    font-weight: 400 !important;
    margin: 0 !important;
    padding: 0 !important;
    text-shadow: none !important;
    /* Misma drop-shadow que el marco gris del card (.element-item::after)
       y de las pildoras de categoria, para que el badge "flote" con el
       mismo lenguaje visual del tema Curvy. */
    box-shadow: 0 5px 12px rgba(0, 0, 0, 0.35) !important;
    /* Limita a 1 caracter ancho cuando hay multiples digitos */
    min-width: var(--curvy-qty-size) !important;
    flex: 0 0 auto !important;
    cursor: pointer !important;
}

/* z-index alto + posicion isolate para que el badge cree su propio
   stacking context y se pinte por encima de cards adyacentes cuando
   sobresale (top:-20 right:-20) del .element-item. */
.element-item .totem-cart-qty {
    z-index: 9999 !important;
}
.element-item:has(.totem-cart-qty:not(:empty)) {
    z-index: 10 !important;
}


.element-item .totem-cart-qty:empty {
    display: none !important;
}

/* === FOOTER (.footer .bill) ===============================================
   Barra blanca en la parte inferior con boton PAGAR a la izquierda (forma
   curva morada) y monto a la derecha en negro grande. Alto se conecta con
   --footer-h y --pay-slot-h responsivos para escalar por breakpoint. */
.footer {
    padding: 0 24px 18px !important;
}

/* Area de doble-tap del modal de info: la sacamos de ENCIMA de "Pagar" (banda base de 100px) y
   la movemos al gap transparente a la IZQUIERDA de la barra .bill (el padding-left de 24px del
   footer), PEGADA a la barra: de left:0 hasta tocar su borde (24px), por el alto de la barra.
   MISMA posicion nueva que en Prisma (body.totem-prisma .totem-footer-info-hit). El footer Curvy
   tiene 18px de padding-bottom, asi que bottom:18px alinea el hit con el borde inferior de la barra. */
body.totem-curvy .totem-footer-info-hit {
    left: 0 !important;
    width: 24px !important;
    top: 0 !important;
    bottom: 18px !important;
}

.bill {
    width: 100% !important;
    /* Bill height escalando con --pay-slot-h (responsivo por breakpoint).
       Multiplicador 1.9 para que el footer se reduzca proporcional a las
       pantallas chicas — el 2.3 anterior dejaba el bill muy alto cuando
       --pay-slot-h cae a valores chicos. */
    height: calc(var(--pay-slot-h) * 1.9) !important;
    /* Sin border: el margen blanco lo controla solo el padding del
       .pay-merged--solo para que el PAGAR pueda quedar FLUSH a la
       izquierda del bill (0px) con 5px arriba/derecha/abajo. */
    border: none !important;
    /* Mismo border-radius que el card, .sig y categorias via --curvy-radius. */
    border-radius: var(--curvy-radius) !important;
    background: #ffffff !important;
    overflow: hidden !important;
    box-shadow: 0 5px 14px rgba(0, 0, 0, 0.35) !important;
    /* collapse (no separate) elimina el margen que el browser pone entre
       la table.bill y su unica celda — asi el .pay-merged--solo llena
       la table completa y el PAGAR puede llegar a sus bordes. */
    border-collapse: collapse !important;
}

/* PAGAR con 5px de margen blanco en los 4 lados dentro del bill. */
.bill .total .pay-merged--solo {
    background: #ffffff !important;
    padding: 5px !important;
    border: none !important;
    height: 100% !important;
}

.bill .pay-footer-slot {
    display: flex !important;
    flex-direction: row !important;
    align-items: stretch !important;
    justify-content: stretch !important;
    width: 100% !important;
    height: 100% !important;
    position: relative !important;
    overflow: hidden !important;
    padding: 0 !important;
    gap: 0 !important;
}

/* Solo escondemos el spacer del placeholder (izquierda — sirve para
   centrado en otros temas pero no aplica al layout del Curvy). El
   spacer derecho con el carrito real queda visible. */
.bill .pay-footer-slot .pay-footer-spacer:has(.cart-footer-icon--placeholder) {
    display: none !important;
}

/* Spacer derecho (carrito real): sin flex-grow para no comer el ancho
   del monto. width:auto + el icono adentro hace que ocupe solo lo que
   necesita. El icono mismo se posiciona absolute al right:15% del slot
   via visor-base.css. */
.bill .pay-footer-slot .pay-footer-spacer:has(.cart-footer-icon:not(.cart-footer-icon--placeholder)) {
    flex: 0 0 auto !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
}

/* Carrito en negro + agrandado + pegado a la derecha en Curvy con 20px
   de margen del borde derecho. visor-base.css aplica transform:
   translate(50%, -50%) que centra el icono en el punto right; lo
   anulamos a translate(0, -50%) para que el RIGHT sea literal del
   borde derecho del icono al borde derecho del slot. */
.bill .pay-footer-slot .cart-footer-icon:not(.cart-footer-icon--placeholder) {
    /* Filter chain: pasa el PNG a violeta theme (target ~ rgb(105, 33, 124)
       = #69217C) sin reemplazar el asset.
         brightness(0)               → silueta a negro puro (descarta el color original).
         invert/sepia/saturate/hue   → desplaza el negro hacia el violeta target.
       Despues encadenamos 2 drop-shadow horizontales (0.6px, sin blur) en
       el mismo violeta para dilatar el contorno y dar grosor visual. */
    filter: brightness(0) saturate(100%) invert(18%) sepia(80%) saturate(2670%) hue-rotate(283deg) brightness(82%) contrast(95%)
            drop-shadow(0.6px 0 0 #69217C)
            drop-shadow(-0.6px 0 0 #69217C) !important;
    /* Multiplicador 1.2 (era 1.5) para que el carrito no domine el slot
       en pantallas chicas donde --cart-icon-h ya es chico de por si. */
    height: calc(var(--cart-icon-h) * 1.2) !important;
    right: 20px !important;
    transform: translate(0, -50%) !important;
}

/* Badge (CAJA) — solo controla position, size, bg, border, y centra
   el wrapper interno .cart-badge-count via flex. Sin estilos de texto
   (font-size/color) aqui — esos viven en .cart-badge-count para poder
   ajustarse por separado. */
.bill .pay-footer-slot .pay-footer-spacer .my-cart-badge {
    position: absolute !important;
    top: 8px !important;
    right: 33px !important;
    left: auto !important;
    bottom: auto !important;
    transform: none !important;
    width: var(--curvy-footer-qty-size) !important;
    height: calc(var(--curvy-footer-qty-size) - 2px) !important;
    border-radius: calc(var(--curvy-footer-qty-size) * 0.36) !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    background: rgb(105, 33, 124) !important;
    border: 3px solid rgb(195, 145, 215) !important;
    margin: 0 !important;
    padding: 0 !important;
    text-shadow: none !important;
    box-shadow: none !important;
    min-width: var(--curvy-footer-qty-size) !important;
    flex: 0 0 auto !important;
    z-index: 10 !important;
    overflow: visible !important;
}

/* Cantidad (NUMERO) dentro del badge — estilos de texto y ajustes
   finos de posicion separados de la caja. Aqui se puede tunear color,
   font-size, line-height, padding-top/bottom, transform translateY,
   etc. sin tocar la geometria del badge. */
.bill .pay-footer-slot .pay-footer-spacer .my-cart-badge .cart-badge-count {
    color: #ffffff !important;
    font-family: 'Viga', sans-serif !important;
    font-size: var(--curvy-footer-qty-fs) !important;
    font-weight: 400 !important;
    line-height: 1 !important;
    display: inline-block !important;
    text-align: center !important;
    transform: translate(0, 1px) !important;
}

/* Boton PAGAR: llena el slot completo del bill (100%) para no dejar
   "huecos" blancos a la derecha. visor-base.css define max-width:
   calc(100% - 100px) + margin:0 auto (centra y cap 100px); aqui hay
   que pisarlo para que el PAGAR pueda llegar al borde derecho. */
.bill .pay-footer-slot .payTextBig {
    position: relative !important;
    width: 50% !important;
    max-width: 50% !important;
    margin: 0 !important;
    height: 100% !important;
    margin: 0 !important;
    /* Aire lateral MINIMO del CTA grande ("Agregar"/"Ir al carrito"/...): el texto no debe
       tocar los bordes del boton. El fit de fuente (fitPayLabelBig en visor-principal.js)
       mide contra este padding y achica la letra si el texto igual no cabe. */
    padding: 0 30px !important;
    box-sizing: border-box !important;
    border: 0 !important;
    /* Mismo gradiente vertical morado de las pildoras de categoria.
       NOTA: box-shadow no se puede aplicar aqui porque .payTextBig tiene
       clip-path que recortaria el efecto 3D — el escalon de las
       categorias no se ve en este boton. */
    background: linear-gradient(to top, rgb(85, 25, 100) 0%, rgb(105, 33, 124) 100%) !important;
    color: #ffffff !important;
    /* Multiplicador para que la tipografia luzca grande dentro de la curva
       morada (mockup: 88px sobre slot ~110). Escala con btn-pay-fs. */
    font-size: calc(var(--btn-pay-fs) * 1.6) !important;
    font-weight: 700 !important;
    font-style: italic !important;
    letter-spacing: 1px !important;
    line-height: 1 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    cursor: pointer !important;
    overflow: hidden !important;
    text-shadow: none !important;
    box-shadow: none !important;
    /* Border-radius solo en TL y BL via --curvy-radius (matchea el de la
       .sig de los cards y el del bill). TR=0 (sharp por el clip-path,
       y para no chocar contra la curva TR del bill). BR=0 (el clip-path
       dibuja un bezier concavo que es el rounding visual de esa esquina). */
    border-radius: var(--curvy-radius) 0 0 var(--curvy-radius) !important;
    /* CURVA REAL del PAGAR del mockup (SVG 920x164):
         M 0 0 H 920 V 82 C 895 118 845 148 765 164 H 0 Z
       Path con esquinas izquierdas y top-right SHARP. El rounding de
       TL/TR/BL lo aplica border-radius con --curvy-radius asi que el
       clip solo se encarga del bezier concavo de la derecha (NO tocar). */
    clip-path: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg'><clipPath id='curvyPay' clipPathUnits='objectBoundingBox'><path d='M 0 0 H 1 V .5 C .9728 .7195 .9185 .9024 .8315 1 H 0 Z'/></clipPath></svg>#curvyPay") !important;
}

.bill .pay-footer-slot .payTextBig.pay-btn-empty {
    /* "Agrega al carrito" en carrito vacio: usamos --btn-pay-empty-fs
       completo (sin el .75 anterior que lo achicaba). El texto cabe en la
       zona uncurved: en y=mid la curva esta en x=100% del boton, y en
       y=75% la curva esta en x~=95%, asi que 17 caracteres centrados
       (Agrega al carrito) entran con margen. font-style normal y
       weight 700 igual que en los otros temas (no italic). */
    font-size: var(--btn-pay-empty-fs) !important;
    font-style: normal !important;
    font-weight: 700 !important;
}

.bill .pay-footer-slot .payTextBig .payLabelBig {
    position: relative !important;
    z-index: 2 !important;
    color: inherit !important;
    font-size: inherit !important;
    /* Una sola linea SIEMPRE: sin esto el texto largo se partiria en 2 lineas y el fit de
       fuente (que mide el ancho intrinseco con scrollWidth) no detectaria el desborde. */
    white-space: nowrap !important;
    max-width: 100% !important;
}

/* "Pagar" 10px mas a la izquierda (pedido de diseno). La clase la pone visor-principal.js
   SOLO cuando el CTA dual muestra "Pagar"; transform no afecta el layout ni el fit. */
.bill .pay-footer-slot .payTextBig .payLabelBig.pay-label-pagar {
    transform: translateX(-10px) !important;
}

.bill .pay-footer-slot .payTextBig .payAmountWrap {
    position: relative !important;
    z-index: 2 !important;
    margin-left: 0.5em !important;
    color: inherit !important;
    font-size: inherit !important;
}

/* Monto centrado entre el PAGAR y el carrito. Position absolute (en vez
   de flex item) para que el ancho del monto NO afecte donde queda el
   carrito (que es absolute al right:20px). left:50% lo arranca justo
   despues del PAGAR, right calculado deja espacio para el carrito
   (20px de su margen + 1.5*cart-icon-h de su ancho + 20px buffer). */
.bill .pay-footer-slot .payAmountWrap {
    position: absolute !important;
    left: calc(50% + 40px) !important;
    /* right basado en el ancho real del carrito (cart-icon-h * 1.2) +
       20px buffer. Ahora matchea el nuevo multiplicador del icono. */
    right: calc(20px + var(--cart-icon-h) * 1.2) !important;
    top: 0 !important;
    bottom: 0 !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    color: #000000 !important;
    font-family: 'Viga', sans-serif !important;
    /* Font reducido de 1.8x a 1.5x para que el monto encaje mejor en
       pantallas chicas donde --btn-pay-fs ya es proporcionalmente chico. */
    font-size: calc(var(--btn-pay-fs) * 1.5) !important;
    font-weight: 400 !important;
    letter-spacing: 1px !important;
}

/* Pseudo: linea separadora vertical entre PAGAR y monto, opcional. */
.bill .pay-footer-slot::after {
    content: none;
}

/* === MODAL CARRITO (.cart-modal) =========================================
   Heredamos los estilos base de visor-base.css; solo ajustamos colores que
   dependen de los tokens. Border-radius y header morado vienen via tokens. */
#my-cart-modal .modal-content {
    border-radius: 18px;
    overflow: hidden;
}

/* === MODAL CIERRE (X) ===================================================== */
.modal-header .close,
.modal-header .cierre {
    color: var(--theme-modal-header-close-color);
}

/* === SWAL / OTROS ========================================================
   Reglas residuales para que SweetAlerts y otros modales sigan los tokens.
   La mayoria viene tokenizada via visor-base.css. */

/* ============================================================================
   RESPONSIVE MOVIL / TABLET (Curvy-only)  —  agregado 2026-06-18
   ============================================================================
   Objetivo: que el tema Curvy se vea bien en telefono y tablet de cualquier
   tamano y orientacion, SIN tocar visor-base.css (cero regresion para los
   otros 3 temas ni para el totem grande en produccion).

   Por que vive todo aca y scopeado a body.totem-curvy:
     - visor-base.css define los breakpoints en :root (compartidos). Esta
       seccion NO los modifica: solo agrega nuevos breakpoints que PISAN
       las variables SOLO cuando el body es .totem-curvy (mayor especificidad
       que :root) y solo en anchos/orientaciones que el totem no usa
       (telefono <600px, tablet/telefono portrait <900px). Los totems corren
       en pantallas grandes (landscape >=768 o portrait >=900), asi que estos
       bloques NUNCA les aplican.

   SUTILEZA CLAVE (custom properties):
     Las variables derivadas --curvy-* estan declaradas en :root y resuelven
     var(--card-w/--card-h) CONTRA :root. Si solo redefinieramos --card-w/
     --card-h en body.totem-curvy, las --curvy-* (declaradas en :root) NO
     verian ese override y la card no se reescalaria (solo cambiaria su width
     literal, no su alto ni sus posiciones internas). Por eso re-declaramos
     el bloque de derivaciones --curvy-* a nivel body.totem-curvy: ahi
     resuelven var(--card-*) contra el valor EFECTIVO del body (incluidos los
     overrides moviles de abajo). Las formulas son identicas a las del :root,
     asi que en pantalla grande el resultado es byte-identico (sin regresion);
     en movil siguen el --card-w/--card-h reducido.

   Conteo de columnas: Isotope usa columnWidth=outerWidth(.element-item) que
   INCLUYE el margin. Por eso en movil bajamos --card-w Y el margin de la card
   para que entren 2 columnas en telefono (320-600px) y 3 en tablet portrait;
   Isotope reacomoda solo en resize/orientationchange (listener ya existente).
   ======================================================================= */

/* --- (0) Re-declarar derivaciones --curvy-* a nivel body (enabler) ---------
   Identico a las formulas del :root (lineas ~137-174). En pantalla grande
   body hereda --card-w/--card-h de :root => valores identicos. En movil
   toma los overrides de abajo. No incluye --curvy-radius (constante). */
body.totem-curvy {
    --curvy-card-inner-w: calc(var(--card-w) - 10px);
    --curvy-image-h: var(--curvy-card-inner-w);
    --curvy-card-h: calc(var(--card-h) - 50px);
    --curvy-bar-h: calc(var(--curvy-card-h) * 0.135);
    --curvy-body-h: calc(var(--curvy-card-h) * 0.534);
    --curvy-qty-size: calc(var(--curvy-bar-h) * 0.95);
    --curvy-qty-fs: calc(var(--curvy-bar-h) * 0.55);
    --curvy-footer-qty-size: calc(var(--curvy-qty-size) * 0.9);
    --curvy-footer-qty-fs: calc(var(--curvy-qty-fs) * 0.9 - 2px);
    --curvy-signos-mas-fs: calc(var(--curvy-bar-h) * 0.85);
    --curvy-signos-menos-fs: calc(var(--curvy-bar-h) * 0.64);
    --curvy-text-name-top: calc(var(--curvy-card-h) * 0.64 - 5px);
    --curvy-text-desc-top: calc(var(--curvy-card-h) * 0.72 - 7.5px);
    --curvy-text-price-top: calc(var(--curvy-card-h) * 0.80 - 10px);
}

/* --- (1) COMPACTACION GLOBAL (<=1024px, todos los modos no-totem) ----------
   Densidad de "chrome": categorias mas chicas y juntas, menos aire entre
   categorias y productos, y menos padding del grid. La altura REAL de la card
   en Curvy = --curvy-card-h (= --card-h - 50), por eso card-h se elige ~ alto
   real deseado + 50. Imagen (--curvy-image-h = card-w - 10) y textos/banda/
   badges (derivados por calc) se miniaturizan solos al bajar --card-w/--card-h. */
@media (max-width: 1024px) {
    body.totem-curvy .top-nav {
        margin-top: 6px !important;
        margin-bottom: 8px !important;
    }
    /* Pildoras de categoria mas compactas => entran mas por fila. */
    body.totem-curvy .top-nav .a_demo_three,
    body.totem-curvy .top-nav a.a_demo_three {
        font-size: 13px !important;
        --pad-y: clamp(3px, 0.5vw, 6px) !important;
        padding: clamp(3px, 0.5vw, 6px) 12px !important;
        margin-right: 9px !important;
        margin-bottom: 3px !important;
    }
    /* Menos padding vertical del grid y menos colchon inferior del scroll. */
    body.totem-curvy .center-nav .grid {
        padding: 4px 0 !important;
    }
    body.totem-curvy .center-nav {
        padding-bottom: 130px !important;
    }
}

/* --- (2) TABLET / ANCHO MEDIO (601-899px): 4-5 columnas --------------------
   Cubre tablet portrait y telefono apaisado en este rango. NO se usa
   orientation: ningun totem cae en 601-899px (portrait totem >=900, landscape
   totem >=1900), asi que un simple rango de ancho es suficiente y robusto.
   Card real ~200px alto. */
@media (min-width: 601px) and (max-width: 899.98px) {
    body.totem-curvy {
        --card-w: 150px;
        --card-h: 250px;
        --cart-icon-h: 80px;
        --text-name-fs: 1.05em;
        --text-desc-fs: 0.85em;
        --text-price-fs: 1.3em;
    }
    body.totem-curvy .element-item {
        /* outer = 150 + 2*8 = 166 => 768/166=4 cols; 899/166=5. */
        margin: 8px !important;
    }
}

/* --- (3) LANDSCAPE MEDIO 901-1366px (tablet/laptop apaisado): 5-7 columnas -
   Los totems apaisados de produccion son >=1900px, asi que 901-1366 landscape
   son tablets/laptops, no totems. Portrait >=900 (totem vertical) NO entra. */
@media (orientation: landscape) and (min-width: 901px) and (max-width: 1366px) {
    body.totem-curvy {
        --card-w: 160px;
        --card-h: 260px;
        --cart-icon-h: 95px;
        --text-name-fs: 1.05em;
        --text-desc-fs: 0.85em;
        --text-price-fs: 1.3em;
    }
    body.totem-curvy .element-item {
        /* outer = 160 + 2*10 = 180 => 1024/180=5 cols; 1366/180=7. */
        margin: 10px !important;
    }
    /* El tope de columnas landscape de visor-base/curvy (5*(card-w+gutter))
       cae natural con el card chico; no hace falta override extra. */
}

/* --- (3b) FOOTER GRANDE EN TABLET -----------------------------------------
   En tablet el footer por defecto se veia chico y desaprovechaba el area.
   Lo agrandamos como en movil: "Agrega al carrito" en 2 lineas y letra
   grande, monto y carrito mas grandes, y footer mas alto. La media combinada
   cubre tablet portrait (601-899) y landscape 901-1366, pero SOLO en
   pantallas con alto >=600px: asi excluye telefonos apaisados (poca altura,
   el footer debe quedar chato) y no toca totems (portrait >=900 / landscape
   >=1900). */
@media (min-width: 601px) and (max-width: 899.98px) and (min-height: 600px),
       (orientation: landscape) and (min-width: 901px) and (max-width: 1366px) and (min-height: 600px) {
    body.totem-curvy {
        --pay-slot-h: 76px;        /* .bill = pay-slot-h*1.9 = ~144px (footer mas alto) */
        --btn-pay-fs: 42px;        /* PAGAR ~67px, monto ~63px */
        --btn-pay-empty-fs: 42px;  /* "Agrega al carrito" grande (2 lineas) */
        --cart-icon-h: 105px;      /* carrito ~126px */
    }
    /* PAGAR algo mas angosto (42%) para dar lugar al monto grande; el monto
       arranca en 45% (hueco claro respecto al boton) y termina antes del
       carrito. Mismo patron que en movil pero con tipografias mayores. */
    body.totem-curvy .bill .pay-footer-slot .payTextBig {
        width: 42% !important;
        max-width: 42% !important;
        font-size: calc(var(--btn-pay-fs) * 1.6) !important;
    }
    /* "Agrega al carrito" en 2 lineas, igual que en movil. */
    body.totem-curvy .bill .pay-footer-slot .payTextBig.pay-btn-empty {
        font-size: var(--btn-pay-empty-fs) !important;
        line-height: 1.08 !important;
    }
    body.totem-curvy .bill .pay-footer-slot .payTextBig.pay-btn-empty .payLabelBig {
        white-space: normal !important;
        line-height: 1.08 !important;
    }
    /* Monto grande, con hueco respecto al PAGAR y al carrito. */
    body.totem-curvy .bill .pay-footer-slot .payAmountWrap {
        left: 45% !important;
        right: calc(18px + var(--cart-icon-h) * 1.2) !important;
        font-size: calc(var(--btn-pay-fs) * 1.5) !important;
    }
    body.totem-curvy .bill .pay-footer-slot .cart-footer-icon:not(.cart-footer-icon--placeholder) {
        right: 16px !important;
    }
    /* Footer mas alto => mas colchon para que la ultima fila no quede tapada. */
    body.totem-curvy .center-nav {
        padding-bottom: 190px !important;
    }
}

/* --- (4) TELEFONO (<=600px): 3 columnas, card/imagen/textos miniaturizados -
   Card real ~150px alto. outer = 108 + 2*5 = 118 => 360/118=3 cols (354),
   320/118=2 (el bloque (6) baja aun mas para 3 cols en 320). El footer Curvy
   (PAGAR 50% + monto/carrito absolutos) se reordena para que el monto no
   quede aplastado en anchos chicos. */
@media (max-width: 600px) {
    body.totem-curvy {
        /* outer = 78 + 2*5 = 88 => 360/88=4.09 -> 4 cols (352, holgura 8px);
           390/88=4; 430/88=4. Telefono moderno (>=360) muestra 4 columnas. */
        --card-w: 78px;
        --card-h: 176px;
        --cart-icon-h: 38px;
        --btn-pay-fs: 18px;
        --btn-pay-empty-fs: 12px;
        --text-name-fs: 0.9em;
        --text-price-fs: 1.05em;
        /* Con la descripcion oculta (regla abajo) re-espaciamos nombre y precio
           para que NO se encimen en la card chica: nombre justo bajo la imagen,
           precio cerca de la banda. (Las proporciones 0.64/0.80 del :root son
           para cards altas y dejan ~9px de gap, insuficiente aca.) */
        --curvy-text-name-top: calc(var(--curvy-card-h) * 0.60);
        --curvy-text-price-top: calc(var(--curvy-card-h) * 0.78);
    }
    /* A 4 columnas (card ~78px) la descripcion se trunca a ~6 letras y no
       aporta; ademas encimaria a nombre/precio. La ocultamos en telefono para
       priorizar densidad + legibilidad de NOMBRE y PRECIO. */
    body.totem-curvy .product-description {
        display: none !important;
    }
    body.totem-curvy .element-item {
        /* margin 5 (gutter 10px) para que SE NOTE el espacio entre productos
           aun con las cards chicas. Combinado con el marco fino de abajo deja
           ~6px visibles entre marcos. */
        margin: 5px !important;
    }
    /* Marco gris mas FINO en telefono: el ::after por defecto sobresale 4px
       (inset:-4 + borde 5) y se comeria el gutter, pegando las cards. Aca lo
       reducimos a ~2px para que quede un hueco claro entre productos. */
    body.totem-curvy .element-item::after {
        inset: -2px !important;
        border-width: 2px !important;
        border-radius: calc(var(--curvy-radius) + 2px) !important;
        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.30) !important;
    }

    /* Footer Curvy reflujado: PAGAR mas angosto, monto corrido, icono chico.
       PAGAR a 42% (antes 44) y monto arrancando en 48% (antes 46) para dejar
       un hueco CLARO (~6% del ancho) entre el boton y el monto: en pantallas
       chicas se pegaban. */
    body.totem-curvy .bill .pay-footer-slot .payTextBig {
        width: 42% !important;
        max-width: 42% !important;
        font-size: calc(var(--btn-pay-fs) * 1.5) !important;
    }
    body.totem-curvy .bill .pay-footer-slot .payTextBig.pay-btn-empty {
        font-size: var(--btn-pay-empty-fs) !important;
        line-height: 1.05 !important;
    }
    body.totem-curvy .bill .pay-footer-slot .payTextBig.pay-btn-empty .payLabelBig {
        white-space: normal !important;
        line-height: 1.05 !important;
    }
    body.totem-curvy .bill .pay-footer-slot .payAmountWrap {
        /* left 48% deja un hueco claro respecto al PAGAR (42%); right con +2px
           de respiro extra para no rozar el carrito. */
        left: 48% !important;
        right: calc(14px + var(--cart-icon-h) * 1.2) !important;
        font-size: calc(var(--btn-pay-fs) * 1.25) !important;
    }
    body.totem-curvy .bill .pay-footer-slot .cart-footer-icon:not(.cart-footer-icon--placeholder) {
        right: 10px !important;
    }
    body.totem-curvy .bill .pay-footer-slot .pay-footer-spacer .my-cart-badge {
        right: 18px !important;
        top: 6px !important;
    }
    body.totem-curvy .footer {
        padding: 0 10px 10px !important;
    }
}

/* --- (5) TELEFONO APAISADO (landscape, alto corto): footer/grid mas chatos -
   Telefono rotado (~360px de alto): achicamos el footer y el colchon del
   scroll para que se vea mas catalogo. No toca el ancho de la card. */
@media (orientation: landscape) and (max-height: 500px) {
    body.totem-curvy {
        --pay-slot-h: 34px;
        --btn-pay-fs: 22px;
        --cart-icon-h: 58px;
    }
    body.totem-curvy .center-nav {
        padding-bottom: 90px !important;
    }
}

/* --- (6) TELEFONO CHICO (<=380px): 4 columnas en 344-380, 3 en 320 ---------
   Card aun mas chica (outer = 74+2*5=84): 360/84=4.28 -> 4 cols; 344/84=4 ->
   4 cols; 320/84=3.8 -> 3 cols (telefonos de 320 son raros hoy). Se mantiene
   el gutter 10px (margin 5) + marco fino (heredado de (4)) para que el espacio
   entre productos siga notandose. */
@media (max-width: 380px) {
    body.totem-curvy {
        --card-w: 74px;
        --card-h: 160px;
        --text-name-fs: 0.85em;
        --text-desc-fs: 0.7em;
        --text-price-fs: 1em;
    }
    body.totem-curvy .element-item {
        margin: 5px !important;
    }
}

/* --- (7) MODAL CARRITO en viewport corto (telefono apaisado) ---------------
   El centrado vertical por .modal:before + inline-block puede cortar el modal
   por arriba si es mas alto que el viewport. Limitamos el alto y damos scroll
   interno, scopeado a Curvy para no tocar los otros temas. */
@media (max-height: 640px) {
    body.totem-curvy #my-cart-modal .modal-content {
        max-height: 92vh;
        overflow-y: auto;
    }
}
