/*
Theme Name: Astra Child
Theme URI: https://wpastra.com/
Template: astra
Author: Brainstorm Force
Author URI: https://wpastra.com/about/?utm_source=theme_preview&utm_medium=author_link&utm_campaign=astra_theme
Description: The Astra WordPress theme is lightning-fast and highly customizable. It has over 1 million downloads and the only theme in the world with 6,000+ five-star reviews! It’s ideal for professional web designers, solopreneurs, small businesses, eCommerce, membership sites and any type of website. It offers special features and templates so it works perfectly with all page builders like Spectra, Elementor, Beaver Builder, etc. Fast performance, clean code, mobile-first design and schema markup are all built-in, making the theme exceptionally SEO-friendly. It’s fully compatible with WooCommerce, SureCart and other eCommerce plugins and comes with lots of store-friendly features and templates. Astra also provides expert support for free users. A dedicated team of fully trained WordPress experts are on hand to help with every aspect of the theme. Try the live demo of Astra: https://zipwp.org/themes/astra/
Tags: custom-menu,custom-logo,entertainment,one-column,two-columns,left-sidebar,e-commerce,right-sidebar,custom-colors,editor-style,featured-images,full-width-template,microformats,post-formats,rtl-language-support,theme-options,threaded-comments,translation-ready,blog
Version: 4.13.6.1785085950
Updated: 2026-07-26 14:12:30

*/

.surecookie-branding-mobile.surecookie-branding {
  display: none !important;
}

.hero-container-elementor {
  padding: 0px !important;
}

/* ==========================================================================
   Colores de marca — una sola fuente para el amarillo y el oscuro.
   ========================================================================== */
:root {
  --ct-accent: #f6c256;
  --ct-dark: #000;
  --ct-light: #fff;

  /* Radio de las fotos. Lo usan las tarjetas de categoría del home y las de
     producto de la tienda: cambiarlo acá las mueve a las dos juntas, que es
     lo único que mantiene la coherencia con el tiempo. */
  --ct-radio: 6px;
}

/* ==========================================================================
   MARQUEE DEL HEADER

   Requiere DOS copias idénticas del contenido dentro del track. La animación
   corre el track exactamente el ancho de una copia, así que cuando termina,
   la segunda copia está justo donde arrancó la primera: el loop no salta.

   Markup (widget HTML de Elementor):

   <div class="marquee-header">
     <div class="marquee-header__track">
       <div class="marquee-header__group">
         <span>ENVÍOS GRATIS A TODO EL PAÍS A PARTIR DE $74000</span>
         <span>ENVÍOS GRATIS A TODO EL PAÍS A PARTIR DE $74000</span>
       </div>
       <div class="marquee-header__group" aria-hidden="true">
         <span>ENVÍOS GRATIS A TODO EL PAÍS A PARTIR DE $74000</span>
         <span>ENVÍOS GRATIS A TODO EL PAÍS A PARTIR DE $74000</span>
       </div>
     </div>
   </div>

   El segundo grupo va con aria-hidden: es decoración, un lector de pantalla
   no tiene que leer el aviso dos veces.
   ========================================================================== */
/* El widget HTML de Astra envuelve el contenido en dos divs. Sin esto el
   marquee queda con el padding del widget y no llega a los bordes. */
.ast-header-html:has(.marquee-header),
.ast-header-html:has(.marquee-header) .ast-builder-html-element {
  padding: 0;
  margin: 0;
  width: 100%;
}

.marquee-header {
  /* las tres perillas */
  --marquee-speed: 30s; /* más chico = más rápido */
  --marquee-gap: 3rem; /* aire entre repeticiones */
  --marquee-copies: 2; /* cuántas copias hay en el track */

  overflow: hidden;
  /* --marquee-bg y --marquee-fg los inyecta inc/marquee.php desde el
	   Customizer; los var() de marca son el fallback.
	   Ojo con el color del texto: sobre este amarillo el blanco da 1.67:1 de
	   contraste (el mínimo WCAG AA es 4.5:1). El oscuro da 9.64:1. */
  background: var(--marquee-bg, var(--ct-accent));
  color: var(--marquee-fg, var(--ct-dark));
  padding-block: 8px;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  /* el usuario no puede seleccionar texto que se está moviendo, y el cursor
	   de texto sobre algo en movimiento se siente raro */
  -webkit-user-select: none; /* Safari e iOS todavía lo necesitan */
  user-select: none;
}

.marquee-header__track {
  display: flex;
  /* sin esto el track se limita al ancho del contenedor y no hay nada
	   que desplazar */
  width: max-content;
  animation: marquee-header-scroll var(--marquee-speed) linear infinite;
}

.marquee-header__group {
  display: flex;
  flex: 0 0 auto; /* que no se encoja para entrar en el contenedor */
  gap: var(--marquee-gap);
  padding-inline-end: var(--marquee-gap);
  white-space: nowrap;
}

/* El separador entre avisos se dibuja por CSS y no se tipea en el contenido:
   así no aparece un guión colgado al final de la vuelta. */
.marquee-header__group > span::after {
  content: "—";
  margin-inline-start: var(--marquee-gap);
  opacity: 0.5;
}

@keyframes marquee-header-scroll {
  from {
    transform: translateX(0);
  }
  to {
    /* -100% es el ancho del track completo; dividido por la cantidad de
		   copias da exactamente el ancho de una. Por eso alcanza con cambiar
		   --marquee-copies si algún día ponés 3 en vez de 2. */
    transform: translateX(calc(-100% / var(--marquee-copies)));
  }
}

/* Poder detenerlo es un requisito de accesibilidad (WCAG 2.2.2): cualquier
   cosa que se mueve sola más de 5 segundos tiene que poder pausarse. */
.marquee-header:hover .marquee-header__track,
.marquee-header:focus-within .marquee-header__track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-header__track {
    animation: none;
    /* sin animación el track se centra en vez de quedar cortado */
    justify-content: center;
  }

  .marquee-header__group:not(:first-child) {
    display: none;
  }
}

/* ==========================================================================
   MARQUEE DEL PIE

   Markup de inc/marquee-pie.php, shortcode [ct_marquee_pie]:

     div.marquee-pie
       div.marquee-pie__track
         div.marquee-pie__grupo > span.marquee-pie__palabra ...
         div.marquee-pie__grupo > span.marquee-pie__palabra ...   (la copia)

   Misma mecánica de dos copias que el del header. Lo que cambia es el tamaño
   (es tipografía decorativa, no un aviso) y las puntas: en vez de cortarse
   contra el borde, el contenido se desvanece con una máscara.

   La máscara y no dos gradientes encima: el degradado a negro exigiría saber
   de qué color es el fondo de la sección y repetirlo acá. Con mask-image lo
   que se desvanece es el texto, así que las puntas se funden con el fondo que
   haya detrás — negro en el footer actual — y siguen funcionando si mañana esa
   sección cambia de color.
   ========================================================================== */
.marquee-pie {
  /* las perillas; el shortcode pisa estas mismas variables en el style
     del contenedor */
  --marquee-pie-speed: 800s;
  --marquee-pie-size: clamp(2.5rem, 9vw, 7rem);
  --marquee-pie-gap: 0.4em;
  --marquee-pie-fade: 18%;
  --marquee-pie-sep: "•";
  --marquee-pie-copies: 2;

  overflow: hidden;
  width: 100%;
  background: var(--marquee-pie-bg, transparent);
  color: var(--marquee-pie-fg, var(--ct-light));
  padding-block: 0.15em;
  font-size: var(--marquee-pie-size);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-transform: uppercase;
  /* Es decoración: seleccionarla con el mouse al arrastrar sólo molesta. */
  -webkit-user-select: none;
  user-select: none;

  /* Las dos puntas transparentes. El doble transparent/black del medio es lo
     que deja la zona central opaca: la máscara es "invisible, visible,
     visible, invisible". */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--marquee-pie-fade),
    #000 calc(100% - var(--marquee-pie-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--marquee-pie-fade),
    #000 calc(100% - var(--marquee-pie-fade)),
    transparent 100%
  );
}

.marquee-pie__track {
  display: flex;
  /* sin esto el track se limita al ancho del contenedor y no hay nada
     que desplazar */
  width: max-content;
  animation: marquee-pie-scroll var(--marquee-pie-speed) linear infinite;
}

/* Por default la cinta va hacia la izquierda. Al revés es la misma animación
   con el sentido invertido, no un segundo @keyframes. */
.marquee-pie--derecha .marquee-pie__track {
  animation-direction: reverse;
}

.marquee-pie__grupo {
  display: flex;
  align-items: center;
  flex: 0 0 auto; /* que no se encoja para entrar en el contenedor */
  gap: var(--marquee-pie-gap);
  padding-inline-end: var(--marquee-pie-gap);
  white-space: nowrap;
}

/* El separador se dibuja por CSS y no se tipea en el contenido: así no queda
   uno colgado al final de la vuelta ni lo lee nadie. */
.marquee-pie__palabra::after {
  content: var(--marquee-pie-sep);
  margin-inline-start: var(--marquee-pie-gap);
  /* más chico y apagado que la palabra: separa sin competir */
  font-size: 0.5em;
  vertical-align: middle;
  opacity: 0.45;
}

@keyframes marquee-pie-scroll {
  from {
    transform: translateX(0);
  }
  to {
    /* -100% es el ancho del track completo; dividido por la cantidad de copias
       da exactamente el ancho de una, que es lo que hace que el salto al
       reiniciar sea invisible. */
    transform: translateX(calc(-100% / var(--marquee-pie-copies)));
  }
}

/* Igual que arriba: WCAG 2.2.2 pide poder detener cualquier cosa que se mueva
   sola más de 5 segundos. */
.marquee-pie:hover .marquee-pie__track,
.marquee-pie:focus-within .marquee-pie__track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .marquee-pie__track {
    animation: none;
    /* sin animación el track se centra en vez de quedar cortado */
    justify-content: center;
  }

  .marquee-pie__grupo:not(:first-child) {
    display: none;
  }
}

/* ==========================================================================
   FIRMA DE LA AGENCIA (LOGO FLEX)

   Markup de inc/logo-flex.php, shortcode [ct_logo_flex]:

     a.logo-flex
       img.logo-flex__logo
       span.logo-flex__marquee                         (aria-hidden)
         span.logo-flex__track
           span.logo-flex__grupo > span.logo-flex__item ...
           span.logo-flex__grupo > span.logo-flex__item ...   (la copia)

   Port del componente <LogoFlex /> de los sitios en Next, donde el loop lo
   arma GSAP. Misma mecánica de dos copias que los otros dos marquees del
   tema: el track se corre el ancho de una copia y al reiniciar la segunda
   quedó justo donde arrancó la primera, así que el salto no se ve.

   La diferencia con la cinta del pie es la escala: acá no es una tira de
   ancho completo sino una ventana angosta al lado del isotipo, y por eso el
   ancho se fija con una variable en vez de ocupar el 100%.
   ========================================================================== */
.logo-flex {
  /* las perillas; el shortcode pisa estas mismas variables en el style
     del enlace */
  --logo-flex-speed: 16s;
  --logo-flex-ancho: 12.5rem;
  --logo-flex-size: 0.8rem;
  --logo-flex-gap: 0.25rem;
  --logo-flex-fade: 10%;
  --logo-flex-copies: 2;

  display: inline-flex;
  align-items: center;
  gap: 1rem;
  padding: 0.75rem 1rem;
  border: 1px solid var(--logo-flex-borde, rgba(255, 255, 255, 0.1));
  background: var(--logo-flex-bg, transparent);
  color: var(--logo-flex-fg, var(--ct-light));
  font-size: var(--logo-flex-size);
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  /* La ventana angosta contra un logo chico se lee más como sello que como
     texto: en versalitas el ritmo de las palabras es parejo aunque cambien. */
  text-transform: uppercase;
  -webkit-user-select: none;
  user-select: none;
}

.logo-flex:hover,
.logo-flex:focus-visible {
  color: var(--logo-flex-fg, var(--ct-light));
}

/* La vuelta completa del isotipo al pasar el mouse. La perspectiva no está en
   el original, pero sin ella rotateY es una proyección plana: el logo se
   achata y se estira en vez de girar. */
.logo-flex__logo {
  width: 36px;
  height: 36px;
  flex: 0 0 auto;
  transition: transform 0.5s ease-out;
}

@media (hover: hover) {
  .logo-flex:hover .logo-flex__logo {
    transform: perspective(400px) rotateY(360deg);
  }
}

.logo-flex__marquee {
  position: relative;
  /* La ventana: es lo único que fija el ancho, el track de adentro es más
     largo y se recorta contra esto. */
  width: var(--logo-flex-ancho);
  /* Sin esto el flex la encoge para entrar en un footer angosto y el ancho
     de arriba deja de significar nada. */
  flex: 0 0 auto;
  max-width: 100%;
  overflow: hidden;

  /* Las dos puntas transparentes. Igual que en la cinta del pie: con máscara
     y no con dos degradados encima, para no tener que repetir acá de qué
     color es el fondo del footer. */
  -webkit-mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--logo-flex-fade),
    #000 calc(100% - var(--logo-flex-fade)),
    transparent 100%
  );
  mask-image: linear-gradient(
    to right,
    transparent 0,
    #000 var(--logo-flex-fade),
    #000 calc(100% - var(--logo-flex-fade)),
    transparent 100%
  );
}

.logo-flex__track {
  display: flex;
  /* sin esto el track se limita al ancho de la ventana y no hay nada
     que desplazar */
  width: max-content;
  animation: logo-flex-scroll var(--logo-flex-speed) linear infinite;
}

.logo-flex__grupo {
  display: flex;
  align-items: center;
  flex: 0 0 auto; /* que no se encoja para entrar en la ventana */
  gap: var(--logo-flex-gap);
  padding-inline-end: var(--logo-flex-gap);
  white-space: nowrap;
}

.logo-flex__item {
  display: inline-flex;
  align-items: center;
}

.logo-flex__asterisco {
  width: 0.75em;
  height: 0.75em;
}

@keyframes logo-flex-scroll {
  from {
    transform: translateX(0);
  }
  to {
    /* -100% es el ancho del track completo; dividido por la cantidad de copias
       da exactamente el ancho de una. */
    transform: translateX(calc(-100% / var(--logo-flex-copies)));
  }
}

/* WCAG 2.2.2: cualquier cosa que se mueva sola más de 5 segundos tiene que
   poder detenerse. Al ser el hover del enlace entero, también frena con el
   foco del teclado. */
.logo-flex:hover .logo-flex__track,
.logo-flex:focus-within .logo-flex__track {
  animation-play-state: paused;
}

@media (prefers-reduced-motion: reduce) {
  .logo-flex__logo {
    transition: none;
  }

  .logo-flex__track {
    animation: none;
  }

  /* Sin animación no hay nada que recorra la ventana, así que la copia sobra
     y el ancho pasa a ser el del contenido: se ve el nombre entero y no un
     recorte al azar de la tira. */
  .logo-flex__grupo:not(:first-child) {
    display: none;
  }

  .logo-flex__marquee {
    width: auto;
    -webkit-mask-image: none;
    mask-image: none;
  }
}

/* ==========================================================================
   SEARCH DEL HEADER

   Markup propio, de inc/search.php (reemplaza astra_get_search del padre):

     div.ct-search
       form.ct-search__form
         label.screen-reader-text
         input.ct-search__field
         button.ct-search__submit > svg.ct-search__icon

   Al no reusar ninguna clase de Astra, no hereda nada del comportamiento
   `slide-search`: está siempre abierto y no hay estilos que pisar.
   ========================================================================== */
.ct-search {
  --ct-search-w: 350px;

  display: flex;
  align-items: center;
}

.ct-search__form {
  display: flex;
  align-items: center;
  gap: 10px;
  width: var(--ct-search-w);
  max-width: 100%;
  padding: 4px 2px;
  border-bottom: 1px solid var(--ct-light);
  transition:
    border-color 0.25s ease,
    box-shadow 0.25s ease;
}

/* Indicador de foco: la línea pasa a blanca y se engrosa. El engrosado va
   por box-shadow y no por border-width para que no mueva un píxel el
   layout al enfocar. */
.ct-search__form:focus-within {
  border-bottom-color: var(--ct-accent);
  box-shadow: 0 1px 0 var(--ct-accent);
}

.ct-search__field {
  flex: 1 1 auto;
  /* en un flex item min-width vale auto: sin esto el input se niega a
	   achicarse y desborda la celda del header en pantallas angostas */
  min-width: 0;
  -webkit-appearance: none !important;
  appearance: none !important;
  background: transparent !important;
  border: 0 !important;
  border-radius: 0;
  box-shadow: none !important;
  padding: 2px 0 !important;
  color: #fff !important;
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.4;
}

/* El outline propio se saca porque el foco ya se indica en el form entero */
.ct-search__field:focus {
  outline: none !important;
  box-shadow: none !important;
  background: transparent !important;
  color: #fff;
}

.ct-search__field::placeholder {
  color: rgba(255, 255, 255, 0.45);
  opacity: 1; /* Firefox le baja la opacidad por su cuenta */
}

/* La X nativa de Chrome/Safari dentro del input[type=search] */
.ct-search__field::-webkit-search-cancel-button,
.ct-search__field::-webkit-search-decoration {
  -webkit-appearance: none;
}

.ct-search__submit {
  /* El ícono va a la izquierda sin tocar el orden del DOM: así el tab
	   sigue yendo campo -> botón, que es el orden que se espera. */
  order: -1;
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  color: var(--ct-light);
  cursor: pointer;
  transition: color 0.25s ease;
}

.ct-search__submit:hover,
.ct-search__form:focus-within .ct-search__submit {
  color: var(--ct-accent);
  background-color: transparent;
  border: 0 !important;
}

.ct-search__submit:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

.ct-search__icon {
  display: block;
  width: 18px;
  height: 18px;
  fill: currentColor;
  border: 0 !important;
}

@media (max-width: 921px) {
  .ct-search {
    --ct-search-w: 100%;
  }
}

@media (width >=1280px) {
  .ct-search {
    --ct-search-w: 500px;
  }
}

@media (width <=767px) {
  img.custom-logo,
  .ast-header-woo-cart {
    width: 48px !important;
    height: 48px !important;
  }
}

@media (width>=767px) and (width<=1279px) {
  img.custom-logo,
  .ast-header-woo-cart {
    width: 64px !important;
    height: 64px !important;
  }

  .ast-grid-right-center-section {
    display: none;
    width: 0px;
  }

  div.ast-builder-layout-element.site-header-focus-item.ast-header-woo-cart {
    width: 120px !important;
  }
}

/* ==========================================================================
   BARRA "ENCONTRÁ TU CAFÉ"

   Markup propio, de inc/encontra-tu-cafe.php, vía [ct_encontra_tu_cafe]:

     section.ct-etc
       h2.ct-etc__titulo
       p.ct-etc__bajada
       form.ct-etc__form
         div.ct-etc__campo            (uno por filtro)
           span.ct-etc__icono > svg.ct-etc__svg
           label.ct-etc__label
           select.ct-etc__select
         div.ct-etc__campo--submit
           button.ct-etc__submit

   Se dibuja sobre fondo oscuro porque va abajo del hero. Si algún día se usa
   en un fondo claro, alcanza con redefinir las tres variables locales.
   ========================================================================== */
.ct-etc {
  --ct-etc-fg: #fff;
  --ct-etc-borde: var(--ct-accent);
  --ct-etc-gap: 18px;

  width: 100%;
  max-width: 1100px;
  margin-inline: auto;
  padding: 10px 20px;
  color: var(--ct-etc-fg);
  text-align: center;
}

.ct-etc__titulo {
  margin: 0 0 8px;
  color: var(--ct-etc-fg);
  font-size: clamp(1.5rem, 3.5vw, 2.25rem);
  line-height: 1.15;
}

.ct-etc__bajada {
  margin: 0 auto clamp(20px, 3vw, 32px);
  max-width: 52ch;
  color: rgba(255, 255, 255, 0.7);
  font-size: 0.95rem;
  line-height: 1.5;
}

/* auto-fit + minmax reparte los campos según cuántos pida el shortcode: con
   tres entran en una fila, con cinco se acomodan en dos sin tocar el CSS. */
.ct-etc__form {
  /* display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--ct-etc-gap);
  align-items: start;
  text-align: left;
}

/* Dos columnas —icono | control— con el icono ocupando las dos filas del
   label y el select. Es grid y no un flex anidado para no meter un wrapper
   extra en el markup: el icono se coloca a mano y el resto cae solo. */
.ct-etc__campo {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 12px;
  row-gap: 6px;
  /* En un grid item min-width vale auto: sin esto un nombre largo de
	   término estira la columna y rompe el reparto parejo. */
  flex: 1;
  width: 100%;
}

.ct-etc__icono {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: center;
  display: flex;
  width: 30px;
  /* Los SVG son de trazo y usan currentColor: alcanza con esta línea para
	   cambiarles el color a todos. */
  color: var(--ct-accent);
}

.ct-etc__icono > svg,
.ct-etc__icono > img {
  display: block;
  width: 100%;
  height: auto;
}

/* El botón no tiene ni icono ni label: sin esto quedaría en la columna
   angosta del icono. */
.ct-etc__campo--submit {
  display: block;
}

.ct-etc__label {
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* Los !important son para ganarle a woocommerce-general, que estila todos los
   select del sitio. Es el mismo motivo por el que los tiene .ct-search__field. */
.ct-etc__select {
  -webkit-appearance: none !important;
  appearance: none !important;
  width: 100% !important;
  min-width: 0;
  margin: 0 !important;
  padding: 11px 34px 11px 12px !important;
  background-color: transparent !important;
  border: 0 !important;
  border-bottom: 1px solid var(--ct-etc-borde) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  color: var(--ct-etc-fg) !important;
  font: inherit;
  font-size: 0.95rem;
  line-height: 1.3;
  cursor: pointer;
  transition:
    border-color 0.25s ease,
    background-color 0.25s ease;

  /* La flecha va como background-image (data URI) y no como pseudo-elemento:
	   un <select> no admite ::after. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%23f5c056' d='M1 1l5 5 5-5'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 12px center !important;
  background-size: 11px 7px !important;
}

.ct-etc__select:hover {
  border-color: rgba(255, 255, 255, 0.45) !important;
}

.ct-etc__select:focus,
.ct-etc__select:focus-visible {
  outline: none !important;
  outline-offset: 0px;
  border-color: var(--ct-accent) !important;
}

/* El desplegable lo dibuja el sistema operativo y hereda el fondo translúcido
   del select, con lo que en Windows y Android quedaba texto blanco sobre
   blanco. Fijar el color acá es la única forma de arreglarlo. */
.ct-etc__select option {
  background-color: var(--ct-dark);
  color: var(--ct-etc-fg);
}

.ct-etc__submit {
  width: 100%;
  margin-top: 40px;
  padding: 12px 24px !important;
  background-color: transparent !important;
  border: 1px solid var(--ct-accent) !important;
  border-radius: 0px !important;
  color: var(--ct-light) !important;
  font: inherit;
  font-size: 0.95rem;
  font-weight: 700;
  line-height: 1.3;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition:
    background-color 0.25s ease,
    color 0.25s ease;
}

.ct-etc__submit:hover,
.ct-etc__submit:focus {
  background-color: transparent !important;

  border-color: rgba(255, 255, 255, 0.45) !important;
}

.ct-etc__submit:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 2px;
}

/* ==========================================================================
   GRILLA DE CATEGORÍAS DEL HOME

   Markup propio, de inc/categorias-home.php, vía [ct_categorias]:

     section.ct-cats
       h2.ct-cats__titulo
       ul.ct-cats__grilla
         li.ct-cats__item--grande   (las 2 primeras)
         li.ct-cats__item--chica    (el resto)
           a.ct-cats__link
             span.ct-cats__foto > img.ct-cats__img
             span.ct-cats__texto
               span.ct-cats__nombre
               span.ct-cats__bajada

   Va sobre fondo CLARO a propósito, rompiendo con el hero y la barra de
   filtros. Dos motivos: la página necesita respirar después de dos secciones
   oscuras seguidas, y —lo importante— la fotografía del catálogo está tomada
   sobre negro. Sobre fondo oscuro las fotos se funden con la sección y se
   pierde la estructura de tarjetas; sobre claro cada tile tiene borde propio.

   El negro queda reservado para la sección del tostadero, que es donde el
   contraste rinde de verdad.
   ========================================================================== */
.ct-cats {
  --ct-cats-fondo: transparent; /*#f7f5f2 off-white cálido: el blanco puro contra el
	                             negro del hero hace una costura dura */
  --ct-cats-foto-fondo: transparent;
  --ct-cats-fg: #1a1a1a;
  --ct-cats-gap: clamp(12px, 1.6vw, 22px);

  background: var(--ct-cats-fondo);
  color: var(--ct-cats-fg);
  padding: clamp(36px, 6vw, 76px) 20px;
}

.ct-cats__titulo {
  margin: 0 0 6px;
  max-width: 1200px;
  margin-inline: auto;
  color: var(--ct-cats-fg);
  font-size: clamp(1.5rem, 3.2vw, 2.15rem);
  line-height: 1.15;
  text-align: center;
}

.ct-cats__intro {
  margin: 0 auto clamp(20px, 3vw, 34px);
  max-width: 1200px;
  color: rgba(26, 26, 26, 0.65);
  font-size: 0.95rem;
}

.ct-cats__titulo + .ct-cats__grilla,
.ct-cats__intro + .ct-cats__grilla {
  margin-top: clamp(20px, 3vw, 34px);
}

/* 6 columnas para poder repartir 3+3 arriba y 2+2+2 abajo con una sola
   grilla. Los spans los decide el modificador que pone el PHP. */
.ct-cats__grilla {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: var(--ct-cats-gap);
  max-width: 1200px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.ct-cats__item {
  /* En un grid item min-width vale auto: sin esto un nombre largo estira la
	   columna y rompe el reparto. */
  min-width: 0;
  margin: 0;
}

.ct-cats__item--grande {
  grid-column: span 3;
}

.ct-cats__item--chica {
  grid-column: span 2;
}

.ct-cats__link {
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  color: inherit;
  text-decoration: none;
}

/* El contenedor de la foto lleva fondo oscuro para que la imagen —recortada
   sobre negro— llegue a los bordes sin que se note el corte, y para que las
   categorías que todavía no tengan miniatura no dejen un hueco blanco. */
.ct-cats__foto {
  position: relative;
  display: block;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--ct-cats-foto-fondo);
  border-radius: var(--ct-radio);
}

img.ct-cats__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: bottom !important;

  transition: transform 0.45s ease;
}

.ct-cats__link:hover .ct-cats__img,
.ct-cats__link:focus-visible .ct-cats__img {
  transform: scale(1.04);
}

.ct-cats__link:focus-visible .ct-cats__foto {
  outline: 2px solid var(--ct-accent);
  outline-offset: 3px;
}

.ct-cats__texto {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.ct-cats__nombre {
  font-size: clamp(1rem, 1.5vw, 1.2rem);
  font-weight: 700;
  line-height: 1.25;
  /* El subrayado se dibuja con background y no con text-decoration para
	   poder animarlo de 0 a 100% sin que salte la línea de base. */
  background-image: linear-gradient(var(--ct-accent), var(--ct-accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0 2px;
  transition: background-size 0.3s ease;
}

.ct-cats__link:hover .ct-cats__nombre,
.ct-cats__link:focus-visible .ct-cats__nombre {
  background-size: 100% 2px;
}

.ct-cats__bajada {
  color: rgba(26, 26, 26, 0.6);
  font-size: 0.85rem;
  line-height: 1.35;
}

@media (prefers-reduced-motion: reduce) {
  .ct-cats__img,
  .ct-cats__nombre {
    transition: none;
  }

  .ct-cats__link:hover .ct-cats__img {
    transform: none;
  }
}

/* Tablet: dos columnas parejas, se pierde la jerarquía de tamaño porque a
   ese ancho no aporta nada. */
@container (max-width: 860px) {
  .ct-cats__grilla {
    grid-template-columns: repeat(2, 1fr);
  }

  .ct-cats__item--grande,
  .ct-cats__item--chica {
    grid-column: span 1;
  }

  /* Con 5 categorías la última queda sola en su fila: que ocupe el ancho
	   completo en vez de dejar un hueco al lado. */
  .ct-cats__item:last-child:nth-child(odd) {
    grid-column: span 2;
  }

  .ct-cats__item:last-child:nth-child(odd) .ct-cats__foto {
    aspect-ratio: 16 / 7;
  }
}

@container (max-width: 520px) {
  .ct-cats__grilla {
    grid-template-columns: 1fr;
  }

  .ct-cats__item--grande,
  .ct-cats__item--chica,
  .ct-cats__item:last-child:nth-child(odd) {
    grid-column: span 1;
  }

  .ct-cats__item:last-child:nth-child(odd) .ct-cats__foto {
    aspect-ratio: 4 / 3;
  }
}

/* ==========================================================================
   FOTO DE LAS TARJETAS DE PRODUCTO

   Mismo radio que las tarjetas de categoría del home, vía --ct-radio.

   Markup de WooCommerce + Astra (no hay wrapper de miniatura: la imagen es
   hija directa del enlace, así que hay que redondear el <img>):

     ul.products
       li.product
         a.woocommerce-loop-product__link
           img.attachment-woocommerce_thumbnail
           h2.woocommerce-loop-product__title
           span.price
         a.button.add_to_cart_button

   Se apunta al <img> dentro del enlace del loop y no a `li.product img` a
   secas, para no alcanzar al ícono de la insignia de oferta ni a nada que
   agregue un plugin abajo de la tarjeta.
   ========================================================================== */
/* Sin ancestro: WooCommerce sólo pone la clase .woocommerce en el body de las
   páginas de tienda. En el home, donde la sección de Destacados convive con
   la grilla de categorías —que es justo donde se nota la coherencia—, esa
   clase no está. `ul.products li.product` ya es específico de Woo. */
ul.products li.product a.woocommerce-loop-product__link img {
  /* border-radius: var(--ct-radio);*/
}

/* Las mismas reglas con más especificidad, para ganarle a Astra en las
   páginas de tienda si algún día define un radio propio. */
.woocommerce ul.products li.product a.woocommerce-loop-product__link img,
.woocommerce-page ul.products li.product a.woocommerce-loop-product__link img,
.related ul.products li.product a.woocommerce-loop-product__link img,
.up-sells ul.products li.product a.woocommerce-loop-product__link img,
.cross-sells ul.products li.product a.woocommerce-loop-product__link img {
  /* border-radius: var(--ct-radio); */
}

/* La galería de la ficha de producto, para que la coherencia no se corte al
   entrar al detalle. Si preferís que ahí la foto vaya a sangre, borrá este
   bloque y el resto sigue igual. */
.woocommerce div.product .woocommerce-product-gallery__image img {
  /* border-radius: var(--ct-radio);*/
}

/* container query y no media query: la barra puede vivir en una columna
   angosta de Elementor con la pantalla ancha, y ahí lo que importa es el
   ancho del contenedor, no el del viewport.

   No es crítico que se soporte (iOS < 16 lo ignora): el auto-fit de arriba
   ya colapsa a una columna cuando no entran dos de 160px. Esto sólo adelanta
   el salto y cierra un poco el gap. */
@container (max-width: 520px) {
  .ct-etc__form {
    grid-template-columns: 1fr;
    gap: 14px;
  }
}

.woocommerce-Tabs-panel p {
  text-align: start !important;
}

.woocommerce span.onsale {
  padding: 0 0.8rem !important;
  text-transform: uppercase !important;
  font-size: 0.8rem !important;
  color: #fff !important;
  font-weight: 800 !important;
  top: -15px !important;
  right: -10px !important;
  border-radius: 0px !important;
  box-shadow: 0 1px 10px #000 !important;
}

h2.woocommerce-loop-product__title {
  font-weight: 600 !important;
}

/*Grid Decorativo template*/

.con-grid::before {
  content: "";
  position: absolute;
  opacity: 0.45;
  top: 10%;
  left: -5%;
  transform: translatey(-50%);
  z-index: -1;
  width: calc(2rem * 4 + 1px);
  height: calc(2rem * 4 + 1px);
  background-image:
    linear-gradient(to right, var(--ct-accent) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ct-accent) 1px, transparent 1px);
  background-size: 2rem 2rem;
  -webkit-mask-image: linear-gradient(
    145deg,
    #000 30%,
    rgba(0, 0, 0, 0.45) 100%
  );
  mask-image: linear-gradient(145deg, #000 30%, transparent 100%);

  pointer-events: none;
}

.con-grid-white::before {
  content: "";
  position: absolute;
  opacity: 0.45;
  top: 10%;
  left: -5%;
  transform: translatey(-50%);
  z-index: -1;
  width: calc(2rem * 4 + 1px);
  height: calc(2rem * 4 + 1px);
  background-image:
    linear-gradient(to right, var(--ct-light) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ct-light) 1px, transparent 1px);
  background-size: 2rem 2rem;
  -webkit-mask-image: linear-gradient(
    145deg,
    #000 30%,
    rgba(0, 0, 0, 0.45) 100%
  );
  mask-image: linear-gradient(145deg, #000 30%, transparent 100%);

  pointer-events: none;
}
.con-grid-black::before {
  content: "";
  position: absolute;
  opacity: 0.45;
  top: 10%;
  left: -5%;
  transform: translatey(-50%);
  z-index: -1;
  width: calc(2rem * 4 + 1px);
  height: calc(2rem * 4 + 1px);
  background-image:
    linear-gradient(to right, var(--ct-dark) 1px, transparent 1px),
    linear-gradient(to bottom, var(--ct-dark) 1px, transparent 1px);
  background-size: 2rem 2rem;
  -webkit-mask-image: linear-gradient(
    145deg,
    #000 30%,
    rgba(0, 0, 0, 0.45) 100%
  );
  mask-image: linear-gradient(145deg, #000 30%, transparent 100%);

  pointer-events: none;
}

.tiger-img {
}

@media (width >=1440px) {
  .tiger-img {
    left: 280px !important;
  }
}

@media (height <=800px) {
  .tiger-img {
    top: -150px !important;
  }
}

/* ==========================================================================
   TARJETA DE CATEGORÍA (Elementor)

   Las clases las pone a mano el contenedor de Elementor, así que el markup
   esperado es:

     .category-card          contenedor (el que recibe el hover)
       .image                imagen (o su wrapper)
       .title                título
       .icon                 flecha / ícono

   Todo se dispara desde el contenedor y no desde cada widget: Elementor sólo
   deja animar elemento por elemento, y lo que se quiere acá es que las cuatro
   cosas pasen juntas.

   :focus-within va al lado de :hover para que quien navega con teclado vea lo
   mismo que quien usa mouse; si el enlace está dentro de la tarjeta, alcanza.
   ========================================================================== */
.category-card {
  --cc-dur: 0.4s;
  --cc-ease: cubic-bezier(0.22, 0.61, 0.36, 1);

  /* Necesario para que el scale de la imagen no se coma el layout de al lado
	   cuando la foto sangra hasta los bordes. */
  position: relative;
  cursor: pointer;
}

/* ---- Imagen: scale leve, recortada por el wrapper ---------------------- */
/* El overflow va acá: sin esto la imagen agrandada se desborda de la tarjeta
   en vez de "acercarse" dentro del marco. */
.category-card .image {
  overflow: hidden;
}

/* Se cubren los dos casos posibles del markup de Elementor: que .image sea el
   wrapper (widget de imagen) o que sea la <img> misma. */
.category-card .image img,
.category-card img.image {
  display: block;
  transform: scale(1);
  transition: transform var(--cc-dur) var(--cc-ease);
  /* El navegador la promueve a su propia capa y el scale no se ve granulado
	   en pantallas comunes. */
  will-change: transform;
}

.category-card:hover .image img,
.category-card:hover img.image,
.category-card:focus-within .image img,
.category-card:focus-within img.image {
  transform: scale(1.05);
}

/* ---- Título: color accent + subrayado que crece desde la izquierda ----- */
/* El subrayado se dibuja con background y no con text-decoration para poder
   animarlo de 0 a 100% sin que salte la línea de base ni cambie la altura.
   `display: inline` hace que la línea mida lo que mide el texto y no todo el
   ancho de la columna. */
.category-card .title {
  display: inline;
  background-image: linear-gradient(var(--ct-accent), var(--ct-accent));
  background-repeat: no-repeat;
  background-position: 0 100%; /* anclado a la izquierda: crece hacia la derecha */
  background-size: 0 2px;
  padding-bottom: 2px; /* aire entre el texto y la línea */
  transition:
    background-size var(--cc-dur) var(--cc-ease),
    color var(--cc-dur) var(--cc-ease);
}

.category-card:hover .title,
.category-card:focus-within .title {
  color: var(--ct-accent);
  background-size: 100% 2px;
}

/* ---- Ícono: rota -45° y se pinta de accent ----------------------------- */
/* Elementor mete el color del ícono en el fill del SVG con una especificidad
   alta (.elementor-widget-icon .elementor-icon svg), así que se apunta al svg
   y al <i> por separado en vez de confiar en currentColor. */
.category-card .icon,
.category-card .icon svg,
.category-card .icon i {
  transition:
    transform var(--cc-dur) var(--cc-ease),
    color var(--cc-dur) var(--cc-ease),
    stroke var(--cc-dur) var(--cc-ease);
}

/* La rotación va en el contenedor y no en el svg: si girara el svg, el
   recuadro del widget quedaría quieto y el ícono se descentraría. */
.category-card .icon {
  display: inline-flex;
  transform: rotate(0deg);
  transform-origin: center;
}

.category-card:hover .icon,
.category-card:focus-within .icon {
  transform: rotate(-45deg);
}

.category-card:hover .icon,
.category-card:hover .icon i,
.category-card:focus-within .icon,
.category-card:focus-within .icon i {
  color: var(--ct-accent);
}

.category-card:hover .icon svg,
.category-card:focus-within .icon svg {
  stroke: var(--ct-accent);
}

/* Mismo criterio que el marquee y las tarjetas del home: si el sistema pide
   menos movimiento, el cambio de color se mantiene (es la señal de que algo
   es interactivo) y se apagan el scale y la rotación. */
@media (prefers-reduced-motion: reduce) {
  .category-card .image img,
  .category-card img.image,
  .category-card .title,
  .category-card .icon,
  .category-card .icon svg,
  .category-card .icon i {
    transition: none;
  }

  .category-card:hover .image img,
  .category-card:hover img.image,
  .category-card:focus-within .image img,
  .category-card:focus-within img.image {
    transform: none;
  }

  .category-card:hover .icon,
  .category-card:focus-within .icon {
    transform: none;
  }
}

/*cta links animation hover*/

div.custom-link a .elementor-button-icon svg {
  width: 1.5rem !important;
  height: 1.5rem !important;
  transition: rotate 0.4s cubic-bezier(0.22, 0.61, 0.36, 1) !important;
}

div.custom-link a .elementor-button-content-wrapper {
  align-items: center !important;
}

div.custom-link a:hover svg {
  rotate: -45deg !important;
}

div.custom-link .elementor-button-link {
  border-radius: 0px !important;
}

div.club-card-link .elementor-button-link {
  padding: 10px 20px !important;
}

/* ==========================================================================
   TRANSICIÓN ENTRE PÁGINAS (View Transitions, cross-document)

   Fade in / fade out entre navegaciones, sin una línea de JS.

   Cómo funciona: al hacer click en un link, el navegador saca una foto de la
   página actual, pide la nueva al servidor y recién cuando la tiene lista
   hace el cruce entre las dos fotos. No hay router ni intercepción de clicks:
   lo maneja el navegador solo.

   Condiciones para que se dispare:
     - la navegación tiene que ser same-origin (un link a otro sitio no anima)
     - LAS DOS páginas —la que sale y la que entra— tienen que tener este
       @view-transition. Como vive en el CSS del tema, se cumple en todo el
       sitio automáticamente.

   El at-rule tiene que estar en el nivel superior de la hoja: si lo metés
   dentro de un @media o un @supports, el navegador lo ignora en silencio.

   Soporte: Chrome/Edge y Safari recientes. Donde no está implementado, la
   regla se ignora y la navegación es la de siempre — no rompe nada, así que
   no hace falta fallback.

   Ojo con el TTFB: el fade arranca cuando el servidor ya devolvió la página
   nueva. Si una vista tarda en responder (carrito y checkout de Woo no se
   cachean), se ve la página vieja congelada ese rato y después el cruce.
   Si eso pasa, el problema es el tiempo de respuesta, no esta animación.
   ========================================================================== */
@view-transition {
  navigation: auto;
}

/* El cruce por defecto del navegador ya es un fade, pero dura ~0.25s parejo
   para los dos lados. Se define a mano para que la salida sea más corta que
   la entrada: así la página nueva "aparece" en vez de sentirse como un
   parpadeo simétrico. */
@keyframes ct-page-fade-out {
  to {
    opacity: 0.5;
  }
}

@keyframes ct-page-fade-in {
  from {
    opacity: 0.5;
  }
}

/* (root) es el snapshot de la página entera. Si algún día se le pone un
   view-transition-name a un elemento puntual —el logo, la foto de una
   categoría— ese elemento sale de este grupo y se anima por separado. */
::view-transition-old(root) {
  animation: 0.5s ease both ct-page-fade-out;
}

::view-transition-new(root) {
  animation: 0.5s ease both ct-page-fade-in;
}

/* Sin animación el cambio es instantáneo, que es exactamente el
   comportamiento de siempre: no se pierde nada. */
@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root),
  ::view-transition-new(root) {
    animation: none;
  }
}

/* ==========================================================================
   TÍTULO DE LAS TARJETAS DE PRODUCTO

   Mismo hover que el título de las tarjetas de categoría: color accent y un
   subrayado que crece desde la izquierda. Se repite acá y no se unifica en
   una clase compartida porque el markup de Woo no se puede tocar sin
   sobrescribir el template content-product.php.

   Markup (WooCommerce + Astra):

     ul.products
       li.product
         a.woocommerce-loop-product__link   <- dispara el hover
           img
           h2.woocommerce-loop-product__title
           span.price
         a.button.add_to_cart_button        <- queda AFUERA del enlace

   El hover cuelga del enlace y no de li.product a propósito: el botón de
   "añadir al carrito" es hermano del enlace, y pasar por encima del botón no
   tiene por qué subrayar el título.

   Sin ancestro .woocommerce por el mismo motivo que el bloque del border-radius
   de más arriba: en el home esa clase no está en el body y la sección de
   Destacados es justo donde importa que se vea igual que las categorías.
   ========================================================================== */

h2.woocommerce-loop-product__title {
  /* El h2 es bloque y ocuparía todo el ancho de la columna: el subrayado
	   quedaría mucho más largo que el texto. inline-block hace que la caja se
	   ajuste al texto y —a diferencia de width: fit-content— sigue respetando
	   el text-align del contenedor, así que funciona igual con el título
	   centrado o alineado a la izquierda. */
  display: inline;

  /* Mismo truco que .ct-cats__nombre: el subrayado va por background y no por
	   text-decoration para poder animarlo de 0 a 100% sin que salte la línea de
	   base ni cambie la altura de la tarjeta. */
  background-image: linear-gradient(var(--ct-accent), var(--ct-accent));
  background-repeat: no-repeat;
  background-position: 0 100%; /* anclado a la izquierda: crece hacia la derecha */
  background-size: 0 2px;
  padding-bottom: 2px;

  /* Mismos tiempos que .category-card para que las dos grillas se sientan
	   parte de lo mismo. */
  transition:
    background-size 0.4s cubic-bezier(0.22, 0.61, 0.36, 1),
    color 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}

a.ast-loop-product__link:hover h2.woocommerce-loop-product__title,
a.ast-loop-product__link:focus-visible h2.woocommerce-loop-product__title {
  background-size: 100% 2px;
}

@media (prefers-reduced-motion: reduce) {
  a.ast-loop-product__link h2.woocommerce-loop-product__title {
    transition: none;
  }
}

/*woocommerce-LoopProduct-link woocommerce-loop-product__link*/

/* ==========================================================================
   SLIDER DE IMÁGENES

   Markup propio, de inc/slider.php, vía [ct_slider]:

     div.ct-slider
       div.ct-slider__viewport
         div.ct-slider__slide  (uno por imagen) > img.ct-slider__img
         button.ct-slider__flecha--prev / --next     (opcionales)
       div.ct-slider__dots > button.ct-slider__dot   (opcionales)

   Mismo gesto que el hero del plugin coffee-tigger-slider, pero sin GSAP: la
   foto que entra abre un recorte de izquierda a derecha mientras se desescala
   y se enfoca, y la que sale se cierra contra su borde izquierdo empujada
   hacia afuera. Todo son clip-path, transform y filter, que el CSS interpola
   solo. El JS (assets/js/ct-slider.js) sólo prende y apaga las clases.

   Los estilos viven acá y no en un archivo aparte a propósito: style.css se
   carga en el <head> en todas las páginas. Encolar una hoja propia recién en
   el render del shortcode la mandaría al footer, y hasta que llegara se verían
   las N imágenes apiladas una abajo de la otra.
   ========================================================================== */
.ct-slider {
  /* las perillas: el shortcode pisa estas tres por style inline */
  --ct-slider-dur: 1.54s;
  --ct-slider-ratio: 16/9;
  --ct-slider-fit: cover;
  --ct-slider-alto: auto;

  /* Cuánto se corre hacia afuera la que sale. Va en % y no en px: así el
	   desplazamiento es el mismo gesto en un panel de 300px que en uno de 900,
	   igual que el imageOutX del plugin. */
  --ct-slider-salida-x: 30%;
  /* La que sale arranca apenas después que la que entra. Tiene que coincidir
	   con SALIDA_DELAY en ct-slider.js, que lo usa para saber cuándo limpiar. */
  --ct-slider-salida-delay: 0.1s;

  /* --- La curva ---
	   Es "cts-hop", el CustomEase del plugin, muestreado. El original es
	   M0,0 C0.071,0.505 0.192,0.726 0.318,0.852 0.45,0.984 0.504,1 1,1: dos
	   segmentos de bézier, o sea que NO se puede escribir como un solo
	   cubic-bezier(). linear() con suficientes puntos sí lo reproduce —fijate
	   que en 31.8% vale 0.852, que es el punto donde se unen los dos segmentos.

	   La declaración de arriba es el fallback: un navegador sin linear() la
	   deja y descarta la de abajo, que no sabe parsear. */
  --ct-slider-hop: cubic-bezier(0.16, 0.84, 0.28, 1);
  --ct-slider-hop: linear(
    0 0%,
    0.12 1.9%,
    0.23 3.9%,
    0.328 6.2%,
    0.417 8.6%,
    0.497 11.2%,
    0.568 13.8%,
    0.631 16.6%,
    0.687 19.5%,
    0.737 22.5%,
    0.78 25.6%,
    0.818 28.7%,
    0.852 31.8%,
    0.883 35%,
    0.909 38%,
    0.931 41%,
    0.949 44.3%,
    0.964 48%,
    0.976 52.2%,
    0.984 57.3%,
    0.991 63.2%,
    0.995 70.3%,
    0.998 78.6%,
    1 88.5%,
    1 100%
  );

  /* power2.in de GSAP. Es una ease que ACELERA: la que sale tiene que irse,
	   no frenar. Con una que desacelere parece que se arrepiente. */
  --ct-slider-salida-ease: cubic-bezier(0.55, 0.055, 0.675, 0.19);

  position: relative;
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 100%;
  /* auto por defecto: el alto lo pone la proporción del viewport. Con el
	   atributo `alto` del shortcode pasa a ser un valor fijo. */
  height: var(--ct-slider-alto);
}

/* El que recorta. Es grid de una sola celda: las N imágenes se apilan sin
   position:absolute, así el contenedor sigue teniendo alto propio. */
.ct-slider__viewport {
  position: relative;
  display: grid;
  overflow: hidden;
  width: 100%;
  /* Con `alto` fijo el shortcode manda --ct-slider-ratio a auto y el alto sale
	   de este flex; sin él, la proporción es la que da el alto. */
  flex: 1 1 auto;
  min-height: 0;
  aspect-ratio: var(--ct-slider-ratio);
  background: var(--ct-dark);
  border-radius: 0;
}

/* --- Estado base: la foto escondida ---
   Es de donde parten las que entran y a donde vuelven las que salieron. El
   recorte es un polígono de cuatro puntos cerrado contra el borde izquierdo;
   el de abierto tiene los MISMOS cuatro puntos, que es lo que deja interpolar
   clip-path sin saltos.

   La opacidad queda en 1 a propósito: la que esconde es la máscara. Si además
   hubiera un fade, el borde del wipe se vería difuso y el gesto se leería como
   una disolvencia, que es justo lo que no queremos.

   Sin `transition` acá: el reposo tiene que ser instantáneo. La transición la
   trae .is-entering / .is-leaving y se va con ellas. */
.ct-slider__slide {
  grid-area: 1 / 1;
  position: relative;
  z-index: 0;
  /* En grid, min-width/min-height valen `auto`: el item se niega a bajar de su
	   tamaño intrínseco y una imagen grande desbordaría igual. */
  min-width: 0;
  min-height: 0;
  clip-path: polygon(0% 0%, 0% 0%, 0% 100%, 0% 100%);
  /* Las tres capas listan las MISMAS funciones en el mismo orden: es lo que
	   permite que transform interpole en vez de saltar. */
  transform: translateX(0) scale(1.12);
  filter: blur(10px);
}

.ct-slider__img {
  display: block;
  width: 100% !important;
  height: 100% !important;
  object-fit: cover;
  object-position: center;
}

/* --- La que se ve --- */
.ct-slider__slide.is-active {
  z-index: 1;
  clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
  transform: translateX(0) scale(1);
  filter: blur(0px);
}

.slider-custom-container {
  border: 0 !important;
}

/* --- La que entra ---
   Va en la capa 2: barre por encima de la que sale, y cuando termina de
   abrirse ya tapa el panel entero. Es la que trae la transition. */
.ct-slider__slide.is-entering {
  z-index: 2;
  /* Sólo mientras animan: dejarlo puesto en las N mantendría una capa de
	   composición por imagen aunque estén quietas. */
  will-change: clip-path, transform, filter;
  transition:
    clip-path var(--ct-slider-dur) var(--ct-slider-hop),
    transform var(--ct-slider-dur) var(--ct-slider-hop),
    filter var(--ct-slider-dur) var(--ct-slider-hop);
}

/* --- La que sale ---
   Se cierra contra su borde izquierdo mientras se corre hacia afuera. Eso es
   lo que se ve en la franja que el wipe todavía no cubrió, y da la sensación
   de que una empuja a la otra. */
.ct-slider__slide.is-leaving {
  z-index: 1;
  clip-path: polygon(0% 0%, 0% 0%, 0% 100%, 0% 100%);
  transform: translateX(var(--ct-slider-salida-x)) scale(0.95);
  filter: blur(8px);
  will-change: clip-path, transform, filter;
  transition:
    clip-path var(--ct-slider-dur) var(--ct-slider-salida-ease)
      var(--ct-slider-salida-delay),
    transform var(--ct-slider-dur) var(--ct-slider-salida-ease)
      var(--ct-slider-salida-delay),
    filter var(--ct-slider-dur) var(--ct-slider-salida-ease)
      var(--ct-slider-salida-delay);
}

/* --- Flechas ---
   Son hijas del viewport y ocupan la misma celda del grid que las fotos: así
   quedan centradas sin position:absolute ni cálculos de alto. */
.ct-slider__flecha {
  grid-area: 1 / 1;
  z-index: 3;
  align-self: center;
  display: grid;
  place-items: center;
  width: 44px; /* 44px es el mínimo de área táctil recomendado */
  height: 44px;
  margin-inline: 12px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgb(0 0 0 / 0.35);
  color: var(--ct-light);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition:
    background-color 0.25s ease,
    color 0.25s ease;
}

.ct-slider__flecha--prev {
  justify-self: start;
}

.ct-slider__flecha--next {
  justify-self: end;
}

.ct-slider__flecha:hover,
.ct-slider__flecha:focus-visible {
  background: rgb(0 0 0 / 0.6);
  color: var(--ct-accent);
}

.ct-slider__flecha:focus-visible {
  outline: 2px solid var(--ct-accent);
  outline-offset: 2px;
}

.ct-slider__flecha-icono {
  display: block;
  width: 22px;
  height: 22px;
}

/* --- Dots ---
   Debajo del viewport, no encima de la foto. Si los querés superpuestos,
   moveles `position: absolute; bottom: 1em;` y listo: el resto no cambia. */
.ct-slider__dots {
  display: flex;
  flex: none;
  justify-content: center;
  gap: 4px;
}

/* El botón es más grande que el punto para tener área de toque; el punto se
   dibuja con un pseudo-elemento, así el activo se enciende sin cambiar de
   tamaño ni empujar a los vecinos. */
.ct-slider__dot {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.ct-slider__dot::before {
  content: "";
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.35;
  transition:
    opacity 0.3s ease,
    background-color 0.3s ease;
}

.ct-slider__dot:hover::before,
.ct-slider__dot:focus-visible::before {
  opacity: 0.7;
}

.ct-slider__dot[aria-current="true"]::before {
  background: var(--ct-accent);
  opacity: 1;
}

.ct-slider__dot:focus-visible {
  outline: 2px solid var(--ct-accent);
  outline-offset: -2px;
}

/* Mismo criterio que el resto del tema: el cambio de imagen se mantiene —es
   la información—, se va el movimiento. La duración baja a 0.01s en vez de 0
   para que el JS igual tenga un tick donde limpiar las clases, y el blur se
   apaga: es justo el tipo de efecto que molesta a quien pide menos
   movimiento. El autoplay lo desactiva el JS por su cuenta. */
@media (prefers-reduced-motion: reduce) {
  .ct-slider {
    --ct-slider-dur: 0.01s;
    --ct-slider-salida-delay: 0s;
    --ct-slider-salida-x: 0%;
  }

  .ct-slider__slide,
  .ct-slider__slide.is-active,
  .ct-slider__slide.is-leaving {
    filter: none;
  }
}

/* ==========================================================================
   CARRITO FLOTANTE (plugin Modern Cart)

   Arranca invisible y aparece cuando el scroll pasa los 50px. Arriba de todo
   el botón cae sobre el hero y le compite a la foto; más abajo deja de
   molestar y ahí es cuando de verdad hace falta, porque el carrito del header
   ya salió de pantalla.

   La clase `ct-scrolleado` la pone en <html> el JS de inc/cart-flotante.php.

   Los selectores arrancan con `html` a propósito: el CSS del plugin usa
   exactamente `#moderncart-floating-cart button`, así que con la misma
   especificidad ganaría el que se cargue último —y ese orden no lo controla
   el tema—. Un tipo de más alcanza para ganar siempre, sin llegar a
   !important, que apagaría la transición.

   visibility además de opacity: un botón en opacity 0 sigue siendo
   clickeable y sigue anunciándose en un lector de pantalla. El delay de
   visibility al ocultar es igual a lo que dura el fade, para que la salida se
   vea entera; al mostrar es 0s, así se puede clickear desde el primer frame.

   La transición repite background-color 0.2s porque reemplaza a la del
   plugin, que es la que hace el cambio de color al pasar el mouse.
   ========================================================================== */
html #moderncart-floating-cart button {
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease,
    background-color 0.2s linear,
    visibility 0s linear 0.3s;
}

html.ct-scrolleado #moderncart-floating-cart button {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity 0.3s ease,
    transform 0.3s ease,
    background-color 0.2s linear,
    visibility 0s;
}

/* El fade se mantiene —es lo que evita que el botón aparezca de golpe— y se
   apaga el desplazamiento, que es la parte que molesta a quien pide menos
   movimiento. Mismo criterio que el marquee y las tarjetas del home. */
@media (prefers-reduced-motion: reduce) {
  html #moderncart-floating-cart button {
    transform: none;
    transition:
      opacity 0.3s ease,
      background-color 0.2s linear,
      visibility 0s linear 0.3s;
  }

  html.ct-scrolleado #moderncart-floating-cart button {
    transition:
      opacity 0.3s ease,
      background-color 0.2s linear,
      visibility 0s;
  }
}

/* El contador va en el oscuro de marca y no en el violeta que trae el plugin. */
#moderncart-floating-cart .moderncart-floating-cart-count {
  background-color: var(--ct-dark) !important;
}

#video-tostadero video {
  aspect-ratio: 3/5 !important;
}

@media (width >= 768px) and (width <= 1024px) {
  .site-footer-above-section-3 {
    margin-right: 20px !important;
  }
}
@media (width >= 1025px) {
  .site-footer-above-section-3 {
    margin-right: 40px !important;
  }
}

div.site-branding.ast-site-identity span.site-logo-img {
  width: 64px !important;
  height: 64px !important;
  display: block;
}

div.site-branding.ast-site-identity span.site-logo-img a.custom-logo-link {
  width: 100% !important;
  height: 100% !important;
  display: block;
}

div.site-branding.ast-site-identity
  span.site-logo-img
  a.custom-logo-link
  img.custom-logo {
  width: 100% !important;
  height: 100% !important;
  object-fit: contain;

  max-width: 100% !important;
}



 @media (width >= 1024px) and (width <= 1479px) {
  div.site-branding.ast-site-identity span.site-logo-img {
    width: 84px !important;
    height: 84px !important;
  }
} 

@media (width >= 1480px) {
  
  div.site-branding.ast-site-identity span.site-logo-img {
   transform: translateY(10px);
    width: 100px !important;
    height: 100px !important;
  }
}

.video-empresas-cont .elementor-wrapper {

  aspect-ratio: 4/5 !important;

}
/* ==========================================================================
   FORMULARIO DE COTIZACIÓN MAYORISTA
   Shortcode [ct_form_mayorista] — inc/form-mayorista.php

   Sigue la misma gramática que las tarjetas de "Servicios" de la página de
   empresas: fondo blanco, filete gris fino, títulos negros pesados con punto
   final y el amarillo reservado para el acento y el botón. Los campos toman
   el borde gris en reposo y el amarillo al foco, igual que el buscador del
   header, para que el foco se lea siempre de la misma manera en todo el sitio.

   La tipografía no se declara: hereda la global de Astra/Elementor. Fijarla
   acá sería tener dos fuentes de verdad y que el formulario se quedara atrás
   el día que se cambie la del sitio.
   ========================================================================== */
.ct-fm {
  --ct-fm-borde: #e6e6e6;
  --ct-fm-fg: #1a1a1a;
  --ct-fm-tenue: #6b6b6b;
  --ct-fm-gap: clamp(16px, 2vw, 24px);

  background: transparent;
  color: var(--ct-fm-fg);
  padding: clamp(40px, 6vw, 80px) 0;

  /* El ancla del botón "Cotizar servicio" cae acá: sin este margen el título
     queda pegado al borde de arriba (o tapado por el header sticky). */
  scroll-margin-top: 100px;
}

.ct-fm__inner {
  max-width: 1180px;
  margin-inline: auto;
  padding-inline: clamp(16px, 4vw, 24px);
}

.ct-fm__titulo {
  margin: 0 0 12px;
  font-size: clamp(2rem, 4vw, 3.2rem);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ct-dark);
}

.ct-fm__bajada {
  max-width: 62ch;
  margin: 0 0 clamp(24px, 3vw, 40px);
  font-size: clamp(0.95rem, 1.1vw, 1.05rem);
  line-height: 1.6;
  color: var(--ct-fm-tenue);
}

/* --------------------------------------------------------------------------
   Aviso de resultado
   El borde izquierdo grueso es el mismo gesto que el filete de las tarjetas
   de servicios: marca el bloque sin necesidad de un fondo de color fuerte.
   -------------------------------------------------------------------------- */
.ct-fm__aviso {
  margin: 0 0 24px;
  padding: 16px 20px;
  border: 1px solid var(--ct-fm-borde);
  border-left: 4px solid var(--ct-accent);
  background: #fcfaf6;
  font-size: 0.95rem;
  line-height: 1.5;
}

.ct-fm__aviso--error {
  border-left-color: #c0392b;
  background: #fdf6f5;
}

.ct-fm__aviso a {
  color: inherit;
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   Confirmación
   Ocupa el lugar del formulario, no va arriba de él: el envío ya ocurrió y no
   hay nada que completar. Con más aire que el aviso de error porque es el
   único contenido de la sección en ese estado.
   -------------------------------------------------------------------------- */
.ct-fm__gracias {
  padding: 32px 28px;
  border: 1px solid var(--ct-fm-borde);
  border-left: 4px solid var(--ct-accent);
  background: #fcfaf6;
}

.ct-fm__gracias-titulo {
  margin: 0 0 10px;
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--ct-dark);
  line-height: 1.3;
}

.ct-fm__gracias-texto {
  margin: 0;
  max-width: 52ch;
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--ct-fm-tenue);
}

.ct-fm__gracias-texto a {
  color: var(--ct-dark);
  text-decoration: underline;
}

/* --------------------------------------------------------------------------
   Acceso al Botón de Arrepentimiento (shortcode [ct_boton_arrepentimiento])

   Va en el home, en la primera pantalla, como pide la Resolución 424/2020.
   Discreto a propósito: es una obligación legal, no una llamada a la acción
   comercial, y compitiéndole al botón de compra sólo ensucia la página. Lo
   que la norma exige es que esté visible y accesible sin registrarse, no que
   sea protagonista.
   -------------------------------------------------------------------------- */
.ct-arr__acceso {
  display: inline-block;
  padding: 8px 16px;
  border: 1px solid currentColor;
  border-radius: var(--ct-radio);
  font-size: 0.82rem;
  line-height: 1.2;
  text-decoration: none;
  color: inherit;
  transition:
    background-color 0.2s ease,
    color 0.2s ease;
}

.ct-arr__acceso:hover,
.ct-arr__acceso:focus-visible {
  background: var(--ct-accent);
  border-color: var(--ct-accent);
  color: var(--ct-dark);
}

@media (prefers-reduced-motion: reduce) {
  .ct-arr__acceso {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Grilla
   Dos columnas desde 720px. El textarea pisa las dos con --full.
   -------------------------------------------------------------------------- */
.ct-fm__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--ct-fm-gap);
}

@media (min-width: 720px) {
  .ct-fm__grid {
    grid-template-columns: 1fr 1fr;
  }

  .ct-fm__campo--full {
    grid-column: 1 / -1;
  }
}

.ct-fm__campo {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: 0; /* sin esto un input largo desborda la celda del grid */
}

.ct-fm__label {
  font-size: 0.72rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ct-dark);
}

.ct-fm__opcional {
  margin-left: 6px;
  font-weight: 500;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ct-fm-tenue);
}

/* Los !important son para ganarle a las reglas de formulario de Astra y de
   WooCommerce, que apuntan a `input[type=text]` con más peso que una clase.
   Es el mismo motivo por el que los tienen los campos de "Encontrá tu café". */
.ct-fm__input {
  width: 100%;
  padding: 14px 16px !important;
  border: 1px solid var(--ct-fm-borde) !important;
  border-radius: 0 !important;
  background: var(--ct-light) !important;
  color: var(--ct-fm-fg) !important;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.4;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
}

.ct-fm__input::placeholder {
  color: #a9a9a9;
}

.ct-fm__input:focus {
  outline: none;
  border-color: var(--ct-accent) !important;
  box-shadow: 0 0 0 3px rgba(246, 194, 86, 0.28);
}

/* El campo inválido sólo se marca después de intentar enviar: :invalid a secas
   pinta de rojo un formulario recién abierto y vacío. */
.ct-fm__form:invalid .ct-fm__input:invalid:not(:focus):not(:placeholder-shown) {
  border-color: #c0392b !important;
}

.ct-fm__input--area {
  min-height: 140px;
  resize: vertical;
}

.ct-fm__input--select {
  appearance: none;

  /* Flecha dibujada en el fondo: evita depender del select nativo, que cada
     navegador pinta distinto, sin sumar un JS de dropdown propio. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231a1a1a' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E") !important;
  background-repeat: no-repeat !important;
  background-position: right 14px center !important;
  background-size: 18px 18px !important;
  padding-right: 44px !important;
}

.ct-fm__ayuda {
  font-size: 0.8rem;
  line-height: 1.4;
  color: var(--ct-fm-tenue);
}

/* Honeypot: fuera de pantalla en vez de display:none, porque buena parte de
   los bots saltea los campos ocultos por display y así no morderían el anzuelo. */
.ct-fm__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Pie: nota legal a la izquierda, botón a la derecha
   Mismo botón amarillo del "Cotizar servicio" de la sección de servicios.
   -------------------------------------------------------------------------- */
.ct-fm__pie {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  margin-top: clamp(24px, 3vw, 36px);
}

.ct-fm__nota {
  max-width: 46ch;
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--ct-fm-tenue);
}

.ct-fm__boton {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 22px 32px;
  border: 0;
  border-radius: 0;
  background: var(--ct-accent);
  color: var(--ct-light);
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  cursor: pointer;
  transition: background-color 0.18s ease, transform 0.18s ease;
}

.ct-fm__boton:hover,
.ct-fm__boton:focus-visible {
  background: var(--ct-dark);
  color: var(--ct-light);
}

.ct-fm__boton:active {
  transform: translateY(1px);
}

/* Misma flecha y mismo gesto que los CTA .custom-link de Elementor: rota a
   -45deg en el hover. Se anima `rotate` y no `transform` a propósito, para no
   pisar un transform que llegue de otro lado y para poder combinarlo. */
.ct-fm__flecha {
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  transition: rotate 0.4s cubic-bezier(0.22, 0.61, 0.36, 1);
}

.ct-fm__boton:hover .ct-fm__flecha,
.ct-fm__boton:focus-visible .ct-fm__flecha {
  rotate: -45deg;
}

@media (max-width: 719px) {
  .ct-fm__pie {
    flex-direction: column-reverse;
    align-items: stretch;
  }

  .ct-fm__boton {
    justify-content: center;
  }
}

/* Mismo criterio que las tarjetas del home: si el sistema pide menos
   movimiento, el cambio de color del botón se mantiene (es la señal de que
   algo es interactivo) y se apaga la rotación de la flecha. */
@media (prefers-reduced-motion: reduce) {
  .ct-fm__input,
  .ct-fm__boton,
  .ct-fm__flecha {
    transition: none;
  }

  .ct-fm__boton:hover .ct-fm__flecha,
  .ct-fm__boton:focus-visible .ct-fm__flecha {
    rotate: none;
  }
}


/* ==========================================================================
   CARRITO — ENVÍO GRATIS Y COTIZADOR (inc/mini-cart-envios.php)

   Astra no le pone padding al contenedor del carrito deslizante: se lo pone a
   cada hijo por separado (ul.product_list_widget, __total, __buttons tienen
   cada uno el suyo). Los bloques que agrega el tema hijo son hijos nuevos de
   ese mismo contenedor, así que nacen sin nada y quedan pegados al borde.

   Por eso el padding horizontal se repite acá vía --ct-mc-pad en vez de
   heredarse. Si algún día el drawer se ve desalineado, ese es el único número
   que hay que tocar: el resto de las medidas cuelgan de él.
   ========================================================================== */
.woocommerce-mini-cart__total ~ .ct-envio-gratis-barra,
.ct-envio-gratis-barra,
.ct-cotizador-envio {
  --ct-mc-pad: 1.5em;
}

/* --- Barra de envío gratis --- */
.ct-envio-gratis-barra {
  padding: 0.9em var(--ct-mc-pad);
  border-bottom: 1px solid var(--ast-border-color, #eee);
}

.ct-envio-gratis-texto {
  margin: 0 0 0.5em !important;
  font-size: 0.85em;
  line-height: 1.4;
}

.ct-envio-gratis-lograda {
  color: #2e7d32;
  font-weight: 600;
}

.ct-envio-gratis-progreso {
  height: 6px;
  background: rgba(0, 0, 0, 0.08);
  border-radius: var(--ct-radio);
  overflow: hidden;
}

.ct-envio-gratis-progreso-relleno {
  height: 100%;
  background: var(--ct-accent);
  transition: width 0.3s ease;
}

/* --- Cotizador --- */
.ct-cotizador-envio {
  padding: 0.9em var(--ct-mc-pad);
  border-bottom: 1px solid var(--ast-border-color, #eee);
}

/* Mismo peso y tamaño que el "Subtotal:" de Astra, para que las dos etiquetas
   del drawer se lean como parte de la misma jerarquía y no como dos criterios
   distintos. */
.ct-cotizador-envio-titulo {
  margin: 0 0 0.5em !important;
  font-size: 0.9em;
  font-weight: 500;
}

/* Provincia y localidad: la API de Envia rechaza la cotización sin provincia,
   así que el cotizador de un solo campo no alcanzaba. Van apilados y con el
   mismo borde que el grupo del CP para que los tres se lean como un bloque. */
.ct-cotizador-envio-campo {
  display: block;
  width: 100%;
  margin-bottom: 6px;
  padding: 0.6em 0.75em !important;
  border: 1px solid var(--ast-border-color, #ccc) !important;
  border-radius: var(--ct-radio);
  background: transparent;
  font-size: 0.85em;
  color: inherit;
}

.ct-cotizador-envio-campo:focus {
  outline: none;
  border-color: var(--ct-accent) !important;
  box-shadow: none !important;
}

/* El input y el botón comparten un solo borde exterior, como una caja partida:
   así se lee que el botón actúa sobre ese campo y no sobre el carrito entero. */
.ct-cotizador-envio-grupo {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--ast-border-color, #ccc);
  border-radius: var(--ct-radio);
  overflow: hidden;
}

.ct-cotizador-envio-input {
  flex: 1;
  min-width: 0;
  border: none !important;
  background: transparent;
  padding: 0.6em 0.75em !important;
  font-size: 0.85em;
  color: inherit;
}

.ct-cotizador-envio-input:focus {
  outline: none;
  box-shadow: none !important;
}

.ct-cotizador-envio-grupo:focus-within {
  border-color: var(--ct-accent);
}

.ct-cotizador-envio-boton {
  flex: none;
  background: none;
  border: none;
  border-left: 1px solid var(--ast-border-color, #ccc);
  padding: 0 1em;
  font-size: 0.85em;
  cursor: pointer;
  color: inherit;
  transition: background-color 0.2s ease;
}

.ct-cotizador-envio-boton:hover,
.ct-cotizador-envio-boton:focus-visible {
  background: var(--ct-accent);
}

.ct-cotizador-envio-ayuda {
  display: inline-block;
  margin-top: 0.6em;
  font-size: 0.78em;
  text-decoration: underline;
}

/* --- Resultado --- */
.ct-cotizador-envio-resultado:empty {
  display: none;
}

.ct-cotizador-envio-cargando,
.ct-cotizador-envio-error {
  font-size: 0.8em;
  opacity: 0.7;
  margin: 0.7em 0 0 !important;
}

.ct-cotizador-envio-tarifas {
  list-style: none;
  margin: 0.7em 0 0;
  padding: 0;
}

.ct-cotizador-envio-tarifas li {
  border-bottom: 1px solid var(--ast-border-color, #eee);
}

/* El <li> entero es la etiqueta del radio: el área clickeable es la fila
   completa y no sólo el puntito, que en mobile es un blanco difícil de
   acertar. */
.ct-cotizador-envio-tarifa {
  display: flex;
  align-items: center;
  gap: 0.6em;
  padding: 0.6em 0;
  font-size: 0.82em;
  line-height: 1.35;
  cursor: pointer;
  margin: 0;
}

.ct-cotizador-envio-tarifa input[type="radio"] {
  flex: none;
  margin: 0;
  accent-color: var(--ct-accent);
}

.ct-cotizador-envio-tarifa-nombre {
  flex: 1;
  min-width: 0;
}

.ct-cotizador-envio-tarifa-precio {
  flex: none;
  font-weight: 600;
}

/* Mismo tratamiento tipográfico que el "Subtotal:" de Astra: es la otra fila
   de cierre del carrito y tienen que leerse como un par. */
.ct-cotizador-envio-total {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  margin: 0.8em 0 0 !important;
  padding-top: 0.7em;
  border-top: 1px solid var(--ast-border-color, #eee);
  font-size: 0.95em;
  font-weight: 600;
}

/* Mientras vuelve el AJAX el bloque queda a media opacidad y sin recibir
   clicks: evita que se dispare una segunda cotización sobre la primera. */
.ct-cotizador-envio--cargando .ct-cotizador-envio-resultado {
  opacity: 0.45;
  pointer-events: none;
  transition: opacity 0.15s ease;
}

.ct-cotizador-envio-nota {
  margin: 0 !important;
  font-size: 0.8em;
  opacity: 0.75;
  line-height: 1.45;
}

@media (prefers-reduced-motion: reduce) {
  .ct-envio-gratis-progreso-relleno,
  .ct-cotizador-envio-boton,
  .ct-cotizador-envio--cargando .ct-cotizador-envio-resultado {
    transition: none;
  }
}

/* ==========================================================================
   CARRITO — SPINNER DE CARGA (blockUI)

   WooCommerce bloquea el carrito con blockUI mientras procesa (borrar un
   ítem, cambiar cantidad). Por defecto tapa todo con un velo blanco al 60% y
   dibuja encima un loader.svg gris que no tiene nada que ver con la paleta.

   Acá el velo se vuelve transparente y el spinner se dibuja con un borde
   rotando, así no depende de ningún archivo de imagen.

   Los !important son necesarios y no un atajo: blockUI escribe `background` y
   `opacity` como estilos inline sobre el overlay, así que ninguna regla de
   hoja de estilos les gana sin eso.
   ========================================================================== */
.blockUI.blockOverlay,
.woocommerce .blockUI.blockOverlay {
  background: transparent !important;
  opacity: 1 !important;
}

.blockUI.blockOverlay::before,
.woocommerce .blockUI.blockOverlay::before {
  width: 26px;
  height: 26px;
  margin: -13px 0 0 -13px;
  background: none !important;
  border: 2px solid rgba(0, 0, 0, 0.15);
  border-top-color: var(--ct-dark);
  border-radius: 50%;
  animation: ct-spin 0.7s linear infinite;
}

@keyframes ct-spin {
  to {
    transform: rotate(360deg);
  }
}

/* ==========================================================================
   TOASTS DE WOOCOMMERCE (inc/toasts.php)

   El aviso de "se agregó al carrito" se mueve por JS a un contenedor fijo
   abajo a la derecha. Sigue siendo el mismo nodo .woocommerce-message que
   imprime WooCommerce —con su botón "Ver carrito" y su ícono—, así que acá
   hay que ganarle a los estilos que Astra ya le puso: de ahí los !important
   sobre fondo, borde y padding.

   El contenedor no recibe clicks (pointer-events: none) y sí cada toast: con
   varios apilados, el aire entre ellos no debe bloquear lo que hay debajo.
   ========================================================================== */
.ct-toasts {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 100000;
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(380px, calc(100vw - 32px));
  pointer-events: none;
}

.ct-toasts .woocommerce-message {
  position: relative;
  margin: 0 !important;
  padding: 1em 1.2em 1em 3.2em !important;
  background: var(--ct-dark) !important;
  color: var(--ct-light);
  border: none !important;
  border-radius: var(--ct-radio);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
  font-size: 0.86em;
  line-height: 1.45;
  cursor: pointer;
  pointer-events: auto;
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.3s ease,
    transform 0.3s ease;
}

.ct-toasts .woocommerce-message.ct-toast--visible {
  opacity: 1;
  transform: none;
}

/* El check que trae Astra: mismo glifo, en el amarillo de marca y alineado a
   la primera línea del texto. */
.ct-toasts .woocommerce-message::before {
  top: 1.05em !important;
  left: 1.2em !important;
  color: var(--ct-accent) !important;
}

/* De fábrica el botón va flotado a la derecha, que en 380px de ancho deja el
   texto en una columna de dos palabras. Acá baja debajo del mensaje. */
.ct-toasts .woocommerce-message .button {
  float: none !important;
  display: inline-block;
  margin: 0.8em 0 0 !important;
  padding: 0.5em 1.1em !important;
  font-size: 0.85em !important;
  line-height: 1.3 !important;
  background: var(--ct-accent) !important;
  color: var(--ct-dark) !important;
  border-radius: var(--ct-radio);
}

@media (max-width: 600px) {
  .ct-toasts {
    right: 16px;
    left: 16px;
    bottom: 16px;
    width: auto;
  }
}

/* Se mantiene el fade —es lo que evita que aparezca de golpe— y se apaga el
   desplazamiento. Mismo criterio que el resto del tema. */
@media (prefers-reduced-motion: reduce) {
  .ct-toasts .woocommerce-message {
    transform: none;
    transition: opacity 0.3s ease;
  }
}

#block-28 p {
  margin-bottom: 0 !important;
}


.cart_totals.calculated_shipping {
   width: 100% !important;
}


.cart-collaterals{
  display: flex !important;
}