/*
Theme Name:   Verdetop
Theme URI:    https://www.verdetop.com
Description:  Tema hijo de Storefront para la tienda y servicios de Verdetop. Identidad segun el manual de marca: dos verdes corporativos (#0f5637 y #a7d4b9) y Poppins en dos pesos (600 y 300).
Author:       Verdetop
Template:     storefront
Version: 6.2.10
Text Domain:  verdetop
*/

:root {
	/* ===== Paleta Verdetop =====
	   El manual de marca define DOS colores corporativos y ninguno mas:
	   verde oscuro #0f5637 y verde claro #a7d4b9. Todo lo que antes era un
	   tercer color (el marron tierra de la barra superior, la terracota de
	   ofertas, el dorado de las valoraciones) se reconduce a esos dos, y los
	   neutros llevan una base verde para que canvas, bordes y grises lean
	   como la misma familia y no como un gris frio pegado encima.
	   Regla al tocar esto: no introducir un hex nuevo fuera de este bloque;
	   si hace falta un tono, derivarlo aqui como token. */

	/* Los dos colores del manual, sin alterar. */
	--jv-color-forest: #0f5637;
	--jv-color-mint: #a7d4b9;

	/* Solo queda un derivado: -mint-soft, el verde claro diluido, para fondos
	   sutiles donde #a7d4b9 a plena saturacion pesaria demasiado.
	   Habia ademas tres tokens de "verde mas oscuro" (-forest-dark,
	   -selected-dark, -earth-dark), los tres con el mismo #0a3b25, que se
	   usaban para hovers y fondos solidos. Ya no existen: hay UN verde oscuro y
	   es el de marca. Al igualarlos, los hover que solo oscurecian dejaron de
	   verse, asi que ahora se invierten a verde claro (buscar "El hover se
	   INVIERTE"). */
	--jv-color-mint-soft: #d7ebe0;

	--jv-color-canvas: #f6faf7;
	--jv-color-surface: #ffffff;
	--jv-color-ink: #0f5637;

	/* Seleccion activa (variantes/formatos elegidos): el corporativo pleno con
	   texto blanco. Antes se usaba a proposito un verde mas claro y vivo que el
	   de marca porque el verde bosque de entonces (#2d5a3d) quedaba apagado
	   como fondo de un chip pequeno; #0f5637 tiene bastante mas saturacion y ya
	   no necesita esa excepcion, asi que la seleccion vuelve al color de marca. */
	--jv-color-selected: #0f5637;

	/* El borde sube de peso (#dbe7e0 -> #c6dbcd) porque al retirar las sombras
	   se queda como unico recurso para separar una superficie de otra. Sobre
	   blanco pasa de 1.27:1 a 1.46:1: sigue siendo discreto, pero se ve. */
	--jv-color-border: #c6dbcd;

	/* Borde para usar DENTRO de superficies verde claro: el borde normal sobre
	   #a7d4b9 da 1.13:1, o sea, invisible. */
	--jv-color-border-on-mint: #7fb99a;

	/* Sin grises: los tres grises verdosos de apoyo pasan a la familia verde.
	   El muted (texto secundario, precios tachados, placeholders) es el verde
	   de marca aclarado un 20% (#3f785f): sobre blanco da 5.2:1, sigue en AA.
	   Los deshabilitados usan mint-soft de fondo con ese mismo verde encima
	   (4.1:1, aceptable para un estado deshabilitado). */
	--jv-color-disabled-bg: #d7ebe0;
	--jv-color-disabled-text: #3f785f;
	--jv-color-price-muted: #3f785f;

	/* Ofertas: era terracota (#a83220) para senalar rebaja con un color ajeno a
	   la marca. Con la paleta de dos colores pasa al corporativo. Se conserva
	   como token propio, y no como alias de --jv-color-forest, porque sigue
	   siendo un rol semantico distinto: si algun dia se quiere devolver una
	   senal de rebaja diferenciada, se cambia solo aqui. Contraste con texto
	   blanco 9.4:1, muy por encima de WCAG AA. */
	--jv-color-sale: #0f5637;

	/* Tipografia — "Poppins" (Google Font), la corporativa del manual. Se
	   mantiene el par sans/serif como dos tokens distintos aunque hoy
	   apunten a la misma familia: hay reglas repartidas por el archivo que
	   usan --jv-font-serif, y colapsarlos en uno obligaria a tocarlas todas. */
	--jv-font-sans: 'Poppins', -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;
	--jv-font-serif: 'Poppins', -apple-system, BlinkMacSystemFont, "Helvetica Neue", Helvetica, Arial, sans-serif;

	--jv-text-category-h1: 40px;
	--jv-text-product-h1: 32px;
	--jv-text-filter-heading: 16.8px;
	--jv-text-body: 15px;
	--jv-text-tile-name: 14px;

	/* Radios — todos a 0. El lenguaje es nordico/suizo: caja recta, rejilla y
	   contraste, sin nada blando. Se conservan los cuatro tokens en vez de
	   borrarlos porque siguen distinguiendo QUE es cada cosa (tarjeta, control,
	   desplegable, pildora) y permiten reintroducir curvatura en un solo sitio
	   si algun dia se quiere. Los `border-radius: 50%` sueltos del archivo
	   (contador de cesta, puntos del carrusel) NO son cajas sino circulos, y se
	   quedan como estan. */
	--jv-radius-none: 0px;
	--jv-radius-card: 0px;
	--jv-radius-control: 0px;
	--jv-radius-dropdown: 0px;
	--jv-radius-pill: 0px;

	--jv-border-control: 1px solid var(--jv-color-border);

	/* Sistema único de ancho de página — usado en header, footer, home, PLP, PDP.
	   Una sola fuente de verdad: nunca anidar otro max-width/padding dentro.
	   Un px fijo (1280px, luego 1600px) SIEMPRE topaba en algún punto: por
	   encima de ese ancho de monitor, todo el sobrante quedaba como margen
	   muerto sin crecer más. El sitio pedía que el contenido NUNCA deje de
	   crecer, con un % de aire proporcional al tamaño de pantalla en vez de
	   un techo duro. Empezó en 96% (2% de aire a cada lado), pero en
	   monitores grandes ese margen se notaba demasiado justo/apretado — 92%
	   (4% a cada lado) sigue creciendo sin tope con el viewport, solo que
	   con más aire relativo a los lados en pantallas anchas. */
	--jv-container-max: 92%;
	--jv-container-pad: 24px;

	/* Lado del cuadrado de la hoja dentro del lockup. El SVG es un viewBox de
	   400x104 y ese cuadrado ocupa los primeros 104, asi que su lado y el alto
	   del logo son literalmente el mismo numero.
	   Existe aparte de --jv-logo-height porque ese token baja a 40px con la
	   franja compacta (:root.jv-compacto), y lo que se alinea con la linea
	   interior del lockup —el bloque de texto del hero— tiene que quedarse
	   quieto al hacer scroll en vez de deslizarse 16px a la izquierda. */
	--jv-logo-square: 56px;

	/* Alto del logo en la franja del header. De aqui cuelga tambien la
	   alineacion del menu de abajo, asi que cambiarlo mueve las dos cosas a la
	   vez y siguen cuadrando. */
	--jv-logo-height: var(--jv-logo-square);

	/* Ancho renderizado del logo, de la misma geometria (viewBox 400x104).
	   Es el ancho de las DOS columnas laterales de .jv-header-row: haciendolas
	   iguales, la columna del buscador queda centrada respecto a la pagina sin
	   depender de lo que midan logo y acciones. */
	--jv-logo-width: calc(var(--jv-logo-height) * 400 / 104);

	/* Alto del header ya pegado (position:sticky en .site-header). Se lo restan
	   los otros sticky de la web y el salto de los anclas, para que nada se
	   meta debajo. Son medidas reales en Chrome, no calculos: el header no mide
	   igual en las tres anchuras porque la fila de categorias colapsa a 1279px
	   y el header pasa a dos filas a 600px. Si se cambia el alto de alguna
	   fila, hay que volver a medirlas. */
	--jv-header-height: 114px;
}

/* Ver --jv-header-height: 95px medidos entre 601 y 1279 (fila de categorias
   colapsada), 128px por debajo de 600 (buscador en su propia fila). */
@media (max-width: 1279px) {
	:root {
		--jv-header-height: 95px;
	}
}

@media (max-width: 600px) {
	:root {
		--jv-header-height: 128px;
	}
}

/* Movil: con 92% + 24px de padding se perdian ~39px por lado (~20% del ancho
   en un telefono de 390px). Todo el sitio cuelga de estos dos tokens
   (.jv-container, .col-full, header, footer, PDP, PLP), asi que bajarlos aqui
   recupera el espacio en todas las paginas a la vez. */
@media (max-width: 767px) {
	:root {
		--jv-container-max: 100%;
		--jv-container-pad: 18px;
	}

	/* Storefront deja 24px de padding-bottom en .site-header; en movil la fila
	   de categorias esta oculta, asi que quedaba una franja clara vacia bajo el
	   buscador que ocupaba sitio al hacer scroll. */
	.site-header {
		padding-bottom: 0 !important;
	}

	/* Altura del header pegado sin esos 24px (95 -> 71, 128 -> 104). */
	:root {
		--jv-header-height: 71px;
	}
}

@media (max-width: 600px) {
	:root {
		--jv-header-height: 104px;
	}
}

/* Los anclas (#seccion) aterrizaban debajo del header pegado. */
html {
	scroll-padding-top: var(--jv-header-height);
}

/* ===== Sistema de ancho de página (unificado) ===== */

.jv-container {
	max-width: var(--jv-container-max);
	margin: 0 auto;
	padding: 0 var(--jv-container-pad);
	box-sizing: border-box;
}

/* Storefront envuelve TODO #content y #colophon en ".col-full" con su propio
   max-width en "em" + padding en content-box (~1148px reales, no 1280px) —
   fuente original de los anchos inconsistentes entre header/contenido/footer.
   Se redefine aquí para que sea un alias exacto de .jv-container: mismo
   valor, misma unidad, mismo box-sizing, en todo el sitio. */
.col-full {
	max-width: var(--jv-container-max);
	/* Sin esto NO es el alias exacto de .jv-container que dice el comentario:
	   .jv-container lleva `margin: 0 auto` y aqui faltaba, asi que por debajo
	   de ~1075px mandaba el margen fijo en em de Storefront. Con un max-width
	   ademas del margen izquierdo fijo la caja queda sobre-restringida y el
	   sobrante se va entero al margen derecho: el contenido caia hasta 3,4px a
	   la izquierda del header (medido a 1060px), y con el hero full-bleed
	   colgando de esta caja, ese desfase se lo comia el bloque del hero. */
	margin-left: auto;
	margin-right: auto;
	padding: 0 var(--jv-container-pad);
	box-sizing: border-box;
}

/* .jv-container--flush: variante explícita sin max-width/padding propio,
   para cuando el elemento YA vive dentro de #content > .col-full (que ya
   aporta el mismo ancho/padding vía la regla .col-full de arriba) — evita
   duplicar el padding. Úsala en vez de .jv-container cuando el contenedor
   padre inmediato en el flujo de la página ya sea .col-full (p. ej.
   .jv-plp-layout, .jv-category-hero__inner). NO uses esto dentro de una
   .jv-home-band: esa sí necesita el padding propio de .jv-container, porque
   la banda es full-bleed (width:100vw) y no aporta padding por sí misma. */
.jv-container--flush {
	max-width: none;
	margin: 0;
	padding: 0;
}

/* overflow:visible explícito — sin esto, Chrome calculaba body con
   overflow-y:auto (probablemente por los varios position:fixed de la
   página: drawer "Todo", toast del carrito, barra sticky de WooCommerce),
   lo que convierte a <body> en el "nearest scrolling ancestor" de CUALQUIER
   position:sticky de la página aunque su scrollTop nunca se mueva (el
   scroll real ocurre en <html>) — el efecto es que TODO sticky de la web
   (imagen/buybox de la PDP, barra sticky de WooCommerce...) se comportaba
   como position:static, moviéndose 1:1 con el scroll en vez de quedarse
   pegado. Confirmado con getComputedStyle(document.body).overflowY antes
   del fix: "auto". */
body {
	background: var(--jv-color-canvas);
	color: var(--jv-color-ink);
	font-family: var(--jv-font-sans);
	font-weight: 300;
	font-size: var(--jv-text-body);
	line-height: 1.5;
	letter-spacing: normal;
	overflow: visible;
}

/* Mismo problema que body (ver comentario de arriba) un nivel más abajo:
   #page (.hfeed.site, el wrapper que Storefront pone justo dentro de
   <body>) también calculaba overflow-y:auto por su cuenta — confirmado con
   getComputedStyle antes de este fix. Con DOS ancestros seguidos actuando
   como "nearest scrolling ancestor", forzar solo body no bastaba: #page
   volvía a romper el sticky un nivel más abajo. */
#page.hfeed.site {
	overflow: visible;
}

h1, h2, h3, h4, h5, h6 {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	color: var(--jv-color-ink);
	letter-spacing: normal;
}

/* Titulares editoriales grandes (categoria, blog) — sans bold grande, nunca serif, siempre >= 32px */
.jv-editorial-heading,
.woocommerce-products-header__title,
.page-title,
.entry-title {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: var(--jv-text-category-h1);
	line-height: 1.1;
	letter-spacing: -0.01em;
}

/* Cuando el Category Hero Editorial Block gestiona su propio H1, se oculta el page-title por defecto de WooCommerce */
body.jv-has-category-hero .woocommerce-products-header__title.page-title {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

a {
	color: var(--jv-color-ink);
}

a:hover {
	color: var(--jv-color-forest);
}

/* Top promo bar — barra oscura tipo carrusel, igual que espejoled */
.jv-top-bar {
	background: var(--jv-color-forest);
	color: #ffffff;
	text-align: center;
	font-size: 13px;
	font-weight: 300;
	letter-spacing: 0.02em;
	padding: 10px 16px;
}

/* ===== Header ===== */

/* Storefront aplica un padding-top propio a .site-header (~36px, calculado
   sobre su tipografía base) — pensado para separar el logo del borde
   superior en su layout original. Con nuestra fila superior ahora en fondo
   oscuro pegado al full-bleed (.jv-header-row-bg), ese padding dejaba una
   franja de fondo blanco (el de .site-header) entre la barra de envíos y la
   barra verde, un hueco que no debería existir. Storefront también aplica
   un margin-bottom propio (~59px, misma lógica en em) pensado para separar
   el header del <main> en su layout original — con la home ya trayendo su
   propio padding-top mínimo en .jv-home-band:first-child (10px, simétrico
   con el padding-bottom de esa misma banda), este margin-bottom se sumaba
   por encima dejando un hueco de cabecera mucho mayor que el de pie del
   hero. */
/* position:sticky en el <header> entero y no en cada fila: las dos filas (la
   verde del logo y la de categorias) viven aqui dentro, asi que se quedan
   pegadas JUNTAS y no una sobre otra. La barra de envios (.jv-top-bar) es
   hermana y queda fuera a proposito: se va con el scroll.
   Sin z-index propio: Storefront ya declara .site-header{position:relative;
   z-index:999} y solo cambiamos el position, asi que el header sigue pintando
   por encima de la pagina (el z-index mas alto fuera de el es 200, el toast del
   carrito). El drawer "Todo" NO se ve afectado: el JS lo saca del header, vive
   suelto en <body> con z-index:10000.
   Funciona porque html/body/#page llevan overflow:visible explicito (ver el
   comentario de body); con el overflow:auto que Chrome les calculaba solo,
   este sticky no se pegaria. */
.site-header {
	position: sticky;
	top: 0;
	background: var(--jv-color-canvas);
	box-shadow: none;
	border-bottom: 1px solid var(--jv-color-border);
	padding-top: 0 !important;
	margin-bottom: 0 !important;
}

/* La barra de admin de WordPress es position:fixed y taparia el header pegado
   al estar logueado. Sus dos alturas son las de WP (32px, y 46px en su propio
   breakpoint de 782px); por debajo de 600px WP la pasa a position:absolute y se
   va con el scroll, asi que ahi el header vuelve a top:0. */
body.admin-bar .site-header {
	top: 32px;
}

@media screen and (max-width: 782px) {
	body.admin-bar .site-header {
		top: 46px;
	}
}

@media screen and (max-width: 600px) {
	body.admin-bar .site-header {
		top: 0;
	}
}

.site-header .site-header-cart,
.site-header ul.menu,
.site-header .secondary-navigation {
	box-shadow: none;
}

/* Wrapper full-bleed SOLO para el fondo de la fila superior (nuestro verde
   bosque, en vez del azul marino de amazon.es) — el contenido real
   (.jv-container.jv-header-row, dentro) sigue centrándose a
   --jv-container-max exactamente igual que la fila de nav de abajo, en vez
   de competir por el ancho con el propio full-bleed en la misma clase (ver
   comentario en jv_header_container_open(), inc/mega-menu.php). */
.jv-header-row-bg {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	background: var(--jv-color-mint);
}

/* Fila superior del header: logo + buscador + cuenta/cesta, imitando la
   estructura de dos filas de Amazon (fila oscura compacta arriba, fila de
   categorías en fondo claro debajo). Ancho gestionado por .jv-container.
   Grid de 3 columnas en vez de flex simple: con flex, el buscador
   (flex:1) ocupaba el hueco entre logo y acciones, pero como logo y
   acciones tienen anchos DISTINTOS entre sí, ese hueco no está centrado
   respecto al viewport — quedaba visualmente descentrado. Grid con
   columnas laterales "auto" (cada una tan ancha como su contenido) y la
   central "1fr" parecia centrar el buscador, pero NO lo centraba respecto a la
   pagina: con columnas laterales "auto", cada una mide lo que su contenido, y
   el logo (215px) y las acciones (80px) no miden lo mismo — el centro de la
   columna del medio caia 75.4px a la derecha del centro real (medido).
   Con las DOS laterales fijadas al mismo ancho (--jv-logo-width) la columna
   central esta centrada por construccion, a cualquier anchura; el buscador se
   centra dentro de ella con su propio margin:auto. Medido despues: 0.02px de
   desviacion a 1440, 0.00 a 1280, 0.01 a 1024 y a 768.
   Un "1fr X 1fr" no serviria: en la rejilla la columna central llega a su
   maximo ANTES de que las laterales repartan el sobrante, asi que entre 601 y
   1171px de viewport el logo empujaba y volvia a descentrar el campo. */
.jv-header-row {
	display: grid;
	grid-template-columns: var(--jv-logo-width) minmax(0, 1fr) var(--jv-logo-width);
	align-items: center;
	gap: 24px;
	position: relative;
}

/* Header MUY compacto — Amazon usa una fila de ~48-56px de alto en la barra
   oscura, no ~80px+ como teníamos. El padding vertical es el UNICO verde que
   se ve por encima y por debajo del lockup, asi que tiene que ser identico
   arriba y abajo; el alto total de la franja sale de sumarlo al alto del logo
   (4 + 56 + 4 = 64px, ver .site-header .site-branding .jv-site-logo). Si se
   cambia uno de los dos valores hay que recalcular el otro.
   Ya no hay suelo: el boton "Todo" tenia ancho fijo atado a este alto mientras
   existio el divisor de la fila de abajo, y al quitarlo el logo quedo libre
   para encoger (ver el bloque de la franja compacta al final). */
.storefront-primary-navigation .site-branding,
.site-header .site-branding {
	padding: 4px 0;
	margin: 0;
	float: none;
}

.site-branding {
	display: flex !important;
	align-items: center;
	float: none !important;
	width: fit-content !important;
	flex: 0 0 auto !important;
}

.site-title {
	width: fit-content;
	flex-shrink: 0;
}

/* display:flex y NO inline-flex: siendo de nivel inline, este enlace genera
   una caja de linea dentro de .site-title y hereda el hueco del descendente de
   la fuente, unos pocos px que se anaden solo POR DEBAJO de la imagen. El
   efecto es que el logo queda descentrado en la franja (menos verde arriba que
   abajo) aunque el padding del branding sea simetrico. */
.site-branding a {
	display: flex;
	align-items: center;
	gap: 10px;
	color: var(--jv-color-ink);
	text-decoration: none;
}

.site-branding .jv-icon {
	width: auto;
	height: 26px;
	color: var(--jv-color-forest);
}

/* El logo se dimensiona por ALTO y no por ancho, para poder cuadrarlo contra
   la franja verde: 60px de logo + los 6px de padding del branding arriba y
   abajo dan los 72px de la franja.
   El selector lleva .site-header a proposito, para llegar a 0-3-0 de
   especificidad: Storefront define `.site-header .site-branding img` (0-2-1)
   con height:auto y max-width:230px, y le gana a cualquier regla nuestra de
   dos clases. Sin ese .site-header delante, el alto de aqui se ignora y el
   logo se dimensiona solo, a los 230px del max-width de Storefront (que es
   justo lo que hay que anular abajo).
   OJO: esto exige que el propio SVG declare width/height ademas del viewBox.
   Sin dimensiones intrinsecas el width:auto del img se resuelve a 0 dentro de
   .site-branding (que es width:fit-content) y el logo desaparece sin dejar ni
   hueco ni error en consola. Si algun dia se resube el logo desde el original
   del disenador, hay que volver a anadirle width/height.
   El ancho sale solo de la proporcion 400x104 del SVG (~215px); no ponerle
   max-width aqui, porque recortaria el ancho sin recortar el alto y
   deformaria el lockup. El caso estrecho se resuelve en el media query de
   600px, que vuelve a medir por ancho. */
.site-header .site-branding .jv-site-logo {
	display: block;
	height: var(--jv-logo-height);
	width: auto;
	max-width: none;
	/* Anima el paso a la franja compacta (ver el bloque del final). */
	transition: height .22s ease;
}

.site-title,
.site-branding a {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 24px;
	letter-spacing: normal;
	color: var(--jv-color-ink);
	margin: 0;
}

.site-description {
	display: none;
}

/* Nav bar principal — mega-menú + acciones, todo en una sola fila y una sola línea */
.main-navigation {
	border-top: 1px solid var(--jv-color-border);
	box-shadow: none;
	background: var(--jv-color-canvas);
}

.jv-header-nav-row {
	display: flex;
	align-items: stretch;
}

/* Botón "Todo" — visible en cualquier ancho, siempre el primer elemento de
   la fila de navegación (mismo sitio que el "☰ Todo" de amazon.es, junto a
   las categorías rápidas). Abre inc/mega-menu.php::jv_render_all_menu_drawer(). */
.jv-all-menu-toggle {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex-shrink: 0;
	background: none;
	border: none;
	/* padding simetrico + margin-left negativo que lo compensa: el fondo del
	   hover respira por los cuatro lados y el TEXTO no se mueve — se queda en
	   x=81.6, el borde izquierdo del logo de la fila de arriba. */
	padding: 5px 5px 5px 5px;
	margin-left: -5px;
	margin-right: 4px;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 13px;
	color: var(--jv-color-ink);
	cursor: pointer;
}

.jv-all-menu-toggle:hover {
	color: var(--jv-color-forest);
}

/* Botón hamburguesa duplicado para la fila superior en móvil (ver
   jv_render_mobile_menu_toggle(), inc/mega-menu.php) — oculto por defecto;
   .jv-header-row en el media query de 600px lo activa (display:inline-flex).
   Vive sobre el verde claro de la fila (.jv-header-row-bg), así que va en el
   verde corporativo + sin el texto/borde del botón "Todo" de desktop (ese es
   solo icono, como el ☰ de amazon.es en su header móvil). */
.jv-header-mobile-toggle {
	display: none;
	padding: 8px;
	margin: 0;
	border: none;
	color: var(--jv-color-forest);
}

.jv-header-mobile-toggle .jv-icon {
	width: auto;
	height: 22px;
}

.jv-header-mobile-toggle:hover {
	color: var(--jv-color-forest);
	opacity: .85;
}

/* :not(.jv-header-mobile-toggle) — sin acotar, esta regla tambien alcanzaba al
   hamburguesa de movil (comparte la clase .jv-all-menu-toggle) y, al venir
   DESPUES de .jv-header-mobile-toggle .jv-icon con la misma especificidad
   (0-2-0), le ganaba por orden: ese icono se estaba pintando a 18px en vez de
   los 22px que declara su propia regla. Con el ancho ya distinto del alto,
   heredarlo lo habria dejado ademas aplastado. */
.jv-all-menu-toggle:not(.jv-header-mobile-toggle) .jv-icon {
	width: auto;
	height: 18px;
}

/* =============================================================
   Drawer "Todo" — panel lateral con el árbol completo de categorías y
   navegación drill-down (ver jv_render_all_menu_drawer() en mega-menu.php).
   Patrón de amazon.es: overlay oscuro + panel deslizante desde la
   izquierda; dentro, un único "carril" de niveles donde solo uno es visible
   (is-active) a la vez — entrar en una categoría desliza el carril entero
   una posición a la izquierda en vez de expandir contenido inline, y el
   botón "Menú principal" desliza de vuelta.
   ============================================================= */
.jv-all-menu {
	position: fixed;
	inset: 0;
	z-index: 10000;
	visibility: hidden;
	pointer-events: none;
}

/* Storefront pone las flechas prev/next de navegación entre productos
   (nav.storefront-product-pagination, en la PDP) como enlaces
   position:fixed con z-index:1499 propio. Confirmado con elementsFromPoint()
   que el hit-test SÍ da prioridad al overlay/drawer una vez reparentado a
   <body> (ver jv_all_menu_drawer_script(), inc/mega-menu.php) — pero el
   navegador seguía COMPONIENDO visualmente la miniatura de producto por
   encima del overlay semitransparente del drawer (probablemente una capa
   de composición GPU aparte para ese position:fixed concreto). z-index más
   bajo no bastaba porque el problema no era de z-index en absoluto — se
   oculta directamente mientras el drawer está abierto (body.jv-no-scroll,
   la clase que ya usa jv_all_menu_drawer_script() para bloquear el scroll
   de fondo), que es exactamente cuándo tapaba el panel. */
body.jv-no-scroll .storefront-product-pagination a {
	display: none;
}

.jv-all-menu.is-open {
	visibility: visible;
	pointer-events: auto;
}

.jv-all-menu__overlay {
	position: absolute;
	inset: 0;
	background: rgba(31, 42, 32, .5);
	opacity: 0;
	transition: opacity .25s ease;
}

.jv-all-menu.is-open .jv-all-menu__overlay {
	opacity: 1;
}

.jv-all-menu__panel {
	position: absolute;
	top: 0;
	left: 0;
	bottom: 0;
	/* Ancho fijo de 320px en cualquier pantalla (antes 80vw, que en moviles
	   estrechos lo dejaba en 288). width:100% es la red de seguridad: si la
	   pantalla midiera menos de 320px, el panel se adapta en vez de desbordar. */
	width: 100%;
	max-width: 320px;
	background: var(--jv-color-surface);
	transform: translateX(-100%);
	transition: transform .28s ease;
	display: flex;
	flex-direction: column;
	overflow: hidden;
}

.jv-all-menu.is-open .jv-all-menu__panel {
	transform: translateX(0);
}

/* Al abrirse, el JS enfoca el panel (role=dialog, tabindex=-1) y Chrome
   pinta el anillo :focus-visible de 2px alrededor de TODO el drawer; como el
   resto de bordes coinciden con el borde de la pantalla o con el header
   verde, solo se percibia como una linea verde en el borde derecho. Es un
   dialogo modal completo, no un control: el anillo no aporta y se quita. */
.jv-all-menu .jv-all-menu__panel:focus,
.jv-all-menu .jv-all-menu__panel:focus-visible {
	/* Especificidad 0-3-0 a proposito: el anillo global [tabindex]:focus-visible
	   (0-2-0) va DESPUES en este archivo y a igualdad ganaria el. */
	outline: none;
}

.jv-all-menu__header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	padding: 13px 16px;
	background: var(--jv-color-forest);
	color: #ffffff;
	flex-shrink: 0;
}

.jv-all-menu__title {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 14px;
}

.jv-all-menu__close {
	background: none;
	border: none;
	color: #ffffff;
	padding: 4px;
	cursor: pointer;
	line-height: 0;
}

.jv-all-menu__close .jv-icon {
	width: auto;
	height: 20px;
}

/* "Carril" de 2 posiciones (raíz | categoría activa) que se desplaza
   horizontalmente entero con transform — al entrar en una categoría se
   desliza -100% (el nivel raíz sale por la izquierda mientras la
   categoría entra desde la derecha) y al volver se desliza de vuelta a 0%.
   Transición corta (150ms) para que se perciba el movimiento sin sentirse
   lento. is-active solo decide qué nivel de categoría concreto se muestra
   en la posición "derecha" del carril — todos los niveles de categoría
   ocupan el mismo hueco superpuestos con position:absolute, y solo el
   is-active es visible ahí. */
.jv-all-menu__levels {
	position: relative;
	flex: 1;
	overflow: hidden;
	display: flex;
	width: 200%;
	transform: translateX(0);
	transition: transform .15s ease;
}

.jv-all-menu__levels.is-drilled {
	transform: translateX(-50%);
}

.jv-all-menu__level {
	flex: 0 0 50%;
	width: 50%;
	display: flex;
	flex-direction: column;
	overflow-y: auto;
}

.jv-all-menu__level:not(.jv-all-menu__level--root) {
	position: absolute;
	top: 0;
	left: 50%;
	right: 0;
	bottom: 0;
	display: none;
}

.jv-all-menu__level:not(.jv-all-menu__level--root).is-active {
	display: flex;
}

.jv-all-menu__back {
	display: flex;
	align-items: center;
	gap: 6px;
	width: 100%;
	background: var(--jv-color-canvas);
	border: none;
	border-bottom: 1px solid var(--jv-color-border);
	padding: 11px 16px;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 12px;
	color: var(--jv-color-price-muted);
	cursor: pointer;
	flex-shrink: 0;
}

.jv-all-menu__back-icon {
	width: auto;
	height: 16px;
	transform: rotate(180deg);
}

.jv-all-menu__level-title {
	padding: 12px 16px 6px;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 13px;
	color: var(--jv-color-ink);
	flex-shrink: 0;
}

.jv-all-menu__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.jv-all-menu__item--divider {
	border-top: 8px solid var(--jv-color-canvas);
}

.jv-all-menu__link {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	width: 100%;
	background: none;
	border: none;
	border-bottom: 1px solid var(--jv-color-border);
	padding: 10px 16px;
	font-family: var(--jv-font-sans);
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-ink);
	text-decoration: none;
	cursor: pointer;
	text-align: left;
}

.jv-all-menu__link:hover {
	background: var(--jv-color-canvas);
}

.jv-all-menu__link--account {
	font-weight: 600;
	gap: 8px;
	justify-content: flex-start;
}

.jv-all-menu__link--account .jv-icon {
	width: auto;
	height: 17px;
	color: var(--jv-color-forest);
}

/* color y no fill: .jv-icon lleva `fill: currentColor`, asi que el color de
   texto es lo que acaba pintando el SVG. Verde de marca en vez del gris de
   apoyo — sobre el blanco del panel son 8,7:1 en vez de 5,9:1. */
.jv-all-menu__link--parent .jv-icon {
	width: auto;
	height: 14px;
	color: var(--jv-color-ink);
	flex-shrink: 0;
}

.jv-all-menu__link--viewall {
	color: var(--jv-color-forest);
	font-weight: 600;
}

/* "Servicios" destacado en el drawer móvil — mismo verde claro que el botón
   equivalente del menú de escritorio (.jv-mega-nav__link--button), para que
   se note que es la otra mitad del negocio (jardinería/instalación), no
   una categoría de tienda más. */
.jv-all-menu__link--services {
	color: var(--jv-color-forest);
	font-weight: 600;
	background: color-mix(in srgb, var(--jv-color-selected) 12%, transparent);
}

.jv-all-menu__link--services:hover {
	background: color-mix(in srgb, var(--jv-color-selected) 20%, transparent);
}

.jv-all-menu__link--services .jv-icon {
	color: var(--jv-color-forest);
}

.jv-all-menu__count {
	color: var(--jv-color-price-muted);
	font-weight: 300;
	font-size: 11.5px;
}

body.jv-no-scroll {
	overflow: hidden;
}

/* width:100% además de flex:1 — en pruebas, flex-grow:1 con flex-basis:0%
   dejaba de facto el <nav> más estrecho que el espacio real disponible en
   .jv-header-nav-row (medido: ~74px de hueco muerto a la derecha, entre
   "Servicios" y el borde del header, que debería alinear con el
   carrito/cuenta de la fila superior). width:100% fuerza el mismo
   resultado final sin depender del cálculo de flex-grow, que en esta
   cascada concreta no llegaba a ocupar el 100% del contenedor aunque era
   el único flex-item en flujo (el otro hijo de .jv-header-nav-row,
   .jv-all-menu, es position:fixed y no debería contar). */
.main-navigation.jv-main-nav {
	display: flex;
	align-items: stretch;
	flex: 1 1 auto;
	width: 100%;
	min-width: 0;
	border-top: none;
	background: none;
}

/* flex:1 + min-width:0 — sin esto, .jv-primary-navigation (flex-item de
   .main-navigation.jv-main-nav) se encogía a SU PROPIO contenido en vez de
   ocupar el resto del ancho disponible junto al botón "Todo" (comportamiento
   flex por defecto: 0 1 auto, nunca crece). Esto rompía además el cálculo
   JS de qué categorías caben (jv_priority_nav_script(), inc/mega-menu.php):
   el <ul> de dentro medía su ancho contra un padre ya encogido a contenido,
   no contra el ancho real disponible de la fila. */
.jv-primary-navigation {
	height: 100%;
	flex: 1;
	min-width: 0;
	/* Ancla de los paneles por debajo de 1024 (ver el bloque del final). */
	position: relative;
}

/* Ver comentario del bloque de alineacion: Storefront reserva aqui un
   margen derecho porcentual de su rejilla de columnas (4.347826087%, ~55px a
   1440px de ancho) que no aplica a este header, y que dejaba "Servicios"
   ese tanto por delante del carrito de la fila superior. El selector lleva
   .site-header para empatar en especificidad (0-3-0) y ganar por orden. */
.site-header .main-navigation.jv-main-nav {
	margin-right: 0;
}

/* Especificidad ".main-navigation ul.jv-mega-nav" (no solo ".jv-mega-nav")
   necesaria para ganar a la regla nativa de Storefront
   ".main-navigation ul,.secondary-navigation ul{display:block}", que tiene
   mayor especificidad que una sola clase y causaba que el flex nunca se
   aplicase (el menú caía a bloque y se apilaba en 2 líneas). */
/* width:100% — sin esto el <ul> se encogía a su propio contenido dentro de
   .jv-primary-navigation (que sí ocupa el resto del ancho vía flex:1), así
   que el margin-left:auto de .jv-mega-nav__group-start empujaba el grupo
   final (Fabricantes/Blog/Servicios) contra el borde derecho DEL PROPIO
   <ul> encogido, no contra el borde real de la fila — dejaba un hueco vacío
   entre "Servicios" y el borde derecho real del header, en vez de quedar
   justo debajo del carrito/cuenta de la fila superior. */
.main-navigation ul.jv-mega-nav {
	/* Con nombre porque no lo usa solo esta regla: el desplegable se apoya en el
	   para arrancar a ras del final de la banda blanca (ver .jv-mega-panel). La
	   propiedad se hereda hasta el panel, asi que tocar el padding del menu
	   mueve el panel solo. */
	--jv-nav-pad-y: 5px;
	/* Lo que queda por debajo del <li> hasta el final de la banda: los 5px de
	   padding MAS 1px de reparto, porque el <li> es 2px mas bajo que la caja de
	   contenido del <ul> y `align-items: center` deja la mitad a cada lado.
	   Medido a 1440: banda 151,75 / <li> 145,75. */
	--jv-nav-bajo-item: 6px;
	display: flex;
	align-items: center;
	flex-wrap: nowrap;
	width: 100%;
	gap: 14px;
	margin: 0;
	padding: var(--jv-nav-pad-y) 0;
	list-style: none;
	height: 100%;
}

.jv-mega-nav .menu-item {
	margin: 0;
	position: relative;
}

/* Storefront trae ".main-navigation ul li a{padding:.875em 0}" — con la
   tipografía base de Storefront eso se traducía en ~21px de padding
   vertical real (computado), MUCHO más que los 5px de aquí, e inflaba la
   altura de toda la fila (75px en vez de ~35px). Aunque nuestro selector
   tiene más clases (más específico en teoría), en la práctica seguía
   perdiendo — !important para no depender de pelear por especificidad,
   mismo patrón ya usado en este archivo contra otras reglas de Storefront. */
.jv-mega-nav > .menu-item > a {
	display: inline-flex;
	align-items: center;
	gap: 3px;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 13.5px;
	white-space: nowrap;
	letter-spacing: normal;
	color: var(--jv-color-ink);
	text-transform: none;
	text-decoration: none;
	padding: 8px 0px 8px 8px !important;
}

.jv-mega-nav > .menu-item > a:hover {
	color: var(--jv-color-forest);
}

/* Fabricantes/Blog/Servicios no son categorías de catálogo (no tienen
   mega-panel de subcategorías) — van agrupados al final de la fila, con un
   hueco extra antes del primero (jv-mega-nav__group-start) y un separador
   vertical fino a modo de "aquí empieza otra cosa", para que se perciba de
   un vistazo que ya no son departamentos de producto, igual que Amazon deja
   más aire antes de sus enlaces de cuenta/idioma al final del menú. */
/* margin-left:auto (no solo 20px) empuja TODO el grupo final
   (Fabricantes/Blog/Servicios) hasta el borde derecho de la fila — antes el
   <ul> flex se quedaba encogido a su propio contenido y pegado a la
   izquierda (el hueco extra lo absorbía .jv-primary-navigation por su
   flex:1, no este <ul>), dejando ese grupo bastante a la izquierda del
   carrito/cuenta de la fila superior en vez de justo debajo, como pide el
   patrón de Amazon (enlaces de cuenta siempre en la columna más a la
   derecha, en ambas filas). */
.jv-mega-nav > .jv-mega-nav__group-start {
	margin-left: auto;
	padding-left: 20px;
	border-left: 1px solid var(--jv-color-border);
}

.jv-mega-nav > .menu-item > a.jv-mega-nav__link--strong {
	font-weight: 600;
}

/* "Servicios"/"Blog" no son categorías de tienda — se marcan en el verde
   claro de los botones de compra (--jv-color-selected, el mismo de "Añadir
   a la cesta"), no el verde oscuro de marca (--jv-color-forest, ya muy
   presente en logo/barra superior/enlaces en hover) — así destacan de
   verdad a simple vista del resto de enlaces de categoría (negro/tinta),
   igual que Amazon distingue con otro tono los enlaces que no son
   departamentos de producto. */
.jv-mega-nav > .menu-item > a.jv-mega-nav__link--accent {
	color: var(--jv-color-selected);
	font-weight: 600;
}

.jv-mega-nav > .menu-item > a.jv-mega-nav__link--accent:hover {
	text-decoration: underline;
}

/* "Servicios" no es una categoría de tienda ni un simple enlace más — es la
   otra mitad del negocio (jardinería/instalación, no e-commerce), así que
   necesita destacar como un botón real, no solo como texto en otro color
   (eso ya lo hacía --link--accent, que se queda para "Blog"). Mismos bordes
   que "Añadir a la cesta" (--jv-radius-control, esquinas suaves, NO pill)
   para que se lea como el mismo lenguaje de botón de acción en todo el sitio. */
.jv-mega-nav > .menu-item > a.jv-mega-nav__link--button {
	background: var(--jv-color-selected);
	color: #ffffff;
	font-weight: 600;
	/* !important necesario: gana a la regla base .jv-mega-nav > .menu-item > a
	   (padding: 8px 0 !important, ver más arriba en este archivo) que si no
	   pisaba el padding horizontal, dejando el texto pegado a los bordes
	   verdes del botón en vez del hueco lateral de un botón real. */
	padding: 8px 18px !important;
	border: 1px solid var(--jv-color-selected);
	border-radius: var(--jv-radius-control);
}

.jv-mega-nav > .menu-item > a.jv-mega-nav__link--button:hover {
	background: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

/* Selector doble (.jv-icon.jv-mega-caret, 0-2-0) a proposito: la flecha lleva
   las dos clases, y con solo `.jv-mega-caret` (0-1-0) empataba en
   especificidad con `.jv-icon` y perdia por orden, porque .jv-icon se declara
   mas abajo en este mismo archivo. Resultado: los 14px de aqui nunca se
   aplicaron y las flechas salian a los 20px de .jv-icon.
   Alto fijo y ancho automatico, como el resto de iconos de Font Awesome. */
.jv-icon.jv-mega-caret {
	width: auto;
	height: 15px;
	margin-top: 1px;
	transition: transform .2s ease;
}

.jv-has-mega.is-open .jv-mega-caret {
	transform: rotate(180deg);
	color: var(--jv-color-forest);
}

/* Icono de categoría (.jv-cat-icon) — ver jv_megamenu_category_icon() en
   inc/mega-menu.php. La base .jv-icon ya aporta fill:currentColor, width:auto
   y flex-shrink; aquí solo se ajusta el tamaño óptico al texto de cada
   contexto (13.5px en la fila de nav, 13px en el drawer) y la separación. */
.jv-mega-nav > .menu-item > a .jv-cat-icon {
	height: 15px;
	margin-right: 4px;
	margin-top: -2px;
}

.main-navigation .jv-mega-panel .jv-mega-panel__list a .jv-cat-icon {
	height: 14px;
	margin-right: 6px;
	vertical-align: -2px;
}

.jv-all-menu__link .jv-cat-icon {
	height: 15px;
	/* El padding cuenta como caja propia en un SVG en linea (es un elemento
	   reemplazado), asi que se suma al margin: 10px de hueco en total. */
	padding-right: 2px;
	margin-right: 8px;
	vertical-align: -2px;
}

/* Panel del mega-menú — fondo claro de marca, imagen de contexto a la derecha */
.jv-mega-panel {
	/* Medidas con nombre en vez de numeros sueltos repetidos: la cabecera, el
	   cuerpo y el pie cuelgan del mismo margen lateral, asi que alinean solos y
	   cambiarlo es tocar una linea. */
	--jv-panel-pad: 24px;
	--jv-panel-fila: 7px;
	/* Las tres bandas se apilan. Sin esto quedarian en fila, porque el panel se
	   abre con display:flex. */
	flex-direction: column;
	display: none;
	position: absolute;
	/* El <li> acaba 5px antes que la banda: esos 5px son el padding de abajo del
	   <ul>, que va despues de el. Sin sumarlos, el panel se metia dentro de la
	   banda y se comia su ultima franja. El margin-top de 1px que habia aqui era
	   para el borde de 1px del panel, que ya no existe. */
	top: calc(100% + var(--jv-nav-bajo-item, 0px));
	left: 50%;
	transform: translateX(-50%);
	z-index: 60;
	/* Dos columnas del nombre mas largo (297px) + hueco + margenes = 667px
	   medidos; 680 deja holgura para nombres nuevos. */
	width: 680px;
	max-width: 90vw;
	background: var(--jv-color-surface);
	border: 0;
	border-radius: var(--jv-radius-dropdown);
	box-shadow: none;
	overflow: hidden;
}

.jv-mega-nav > .menu-item:first-child .jv-mega-panel,
.jv-mega-nav > .menu-item:nth-child(2) .jv-mega-panel {
	left: 0;
	transform: none;
}

.jv-has-mega.is-open .jv-mega-panel {
	display: flex;
}

/* ----- Cabecera -----
   El mismo verde de la barra de navegacion, para que el panel se lea como una
   prolongacion de la barra y no como una tarjeta suelta flotando encima. */
.jv-mega-panel__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	padding: 12px var(--jv-panel-pad);
	background: var(--jv-color-forest);
	color: #ffffff;
}

.jv-mega-panel__ident {
	display: inline-flex;
	align-items: center;
	min-width: 0;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.3;
}

/* El icono en verde claro y el nombre en blanco: el icono acompana, no compite.
   Los iconos son de relleno con fill:currentColor, asi que se tinen con
   `color` y no con `fill`. */
/* El margen NO se hereda de ningun sitio: el hueco del icono lo pone
   `.jv-mega-nav > .menu-item > a .jv-cat-icon`, que solo alcanza al enlace de la
   barra. Aqui hay que darselo, o el icono sale montado sobre la primera letra. */
.jv-mega-panel__head .jv-cat-icon {
	height: 16px;
	flex-shrink: 0;
	margin-right: 9px;
	padding-right: 0;
	color: var(--jv-color-mint);
}

.jv-mega-panel__titulo {
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* El cuerpo ya solo lleva la lista —el pie salio fuera para poder tener fondo
   propio—, asi que no necesita ni el hueco ni el padding de abajo que
   separaban las dos partes. */
.jv-mega-panel__inner {
	flex: 1;
	min-width: 0;
	padding: 16px var(--jv-panel-pad) 18px;
	display: flex;
	flex-direction: column;
	gap: 0;
}

/* Storefront trae ".main-navigation ul ul{position:absolute;left:-9999px;
   float:left}" para su propio mecanismo de submenús anidados — nuestro
   <ul class="jv-mega-panel__list"> vive dentro de ".main-navigation ul" y
   coincide con ese selector genérico, así que el panel se renderizaba fuera
   de pantalla. Se neutraliza aquí explícitamente con mayor especificidad. */
.main-navigation .jv-mega-panel__list {
	position: static;
	float: none;
	left: auto;
	top: auto;
	z-index: auto;
	list-style: none;
	margin: 0;
	padding: 0;
	/* `columns` y no grid: el multicolumna reparte en VERTICAL, asi que cada
	   columna se lee en alfabetico hacia abajo (que es como se busca una
	   categoria). Con grid el orden seria horizontal y habria que reordenar la
	   lista en PHP para leerla igual. */
	columns: 2;
	column-gap: 26px;
}

.jv-mega-panel__list li {
	break-inside: avoid;
}

/* Tres clases a proposito. Storefront trae
     .main-navigation ul.menu ul li a { padding:.875em 1.41575em; font-size:.875em }
   con especificidad (0,2,4), y le ganaba a `.jv-mega-panel__list a` (0,1,0): ni
   el padding ni el tamano de letra del tema se estaban aplicando, de ahi que un
   panel tuviera filas de 45px y otro de 66px. Con (0,3,1) se gana. */
.main-navigation .jv-mega-panel .jv-mega-panel__list a {
	display: block;
	/* Storefront le pone ancho fijo (200px) a los enlaces de submenu del menu
	   principal. Con eso puesto, ensanchar el panel no ensancha la caja del
	   texto: el nombre se sale del <a> y lo recorta el overflow del panel, aun
	   teniendo su columna 303px de sobra. Esta regla es (0,3,1) y la de
	   Storefront (0,2,4), asi que gana por clases sin necesidad de !important. */
	width: auto;
	/* El fondo del hover asoma por los dos lados y no solo por la izquierda:
	   la fila se lee como una fila entera. */
	padding: var(--jv-panel-fila) 8px;
	margin: 0 -8px;
	/* Una linea por subcategoria: los anchos de los paneles estan calculados
	   sobre el nombre mas largo, y esto convierte "cabe" en una garantia en vez
	   de en una casualidad del texto que haya hoy. */
	white-space: nowrap;
	font-size: 14px;
	font-weight: 300;
	line-height: 1.35;
	text-decoration: none;
	color: var(--jv-color-ink);
}

.main-navigation .jv-mega-panel .jv-mega-panel__list a strong {
	font-size: inherit;
	font-weight: inherit;
}

/* Solo fondo y color, sin cambiar el peso: en multicolumna un cambio de grosor
   al pasar el raton reequilibra las columnas y el texto salta. */
.main-navigation .jv-mega-panel .jv-mega-panel__list a:hover {
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

/* Banda propia de lado a lado, y por eso el pie es hermano del cuerpo y no hijo
   suyo: dentro del padding del cuerpo el fondo no llegaba a los bordes. La raya
   de 1px es la que separa, no un hueco: aqui el borde es portante, como en todo
   el tema. */
/* Rejilla de dos filas y no un flex con wrap: en flex, con seis marcas no cabia
   todo en una linea y la accion —empujada a la derecha— se quedaba sola en una
   tercera, varada. Colocando a mano, el reparto es siempre el mismo:
       fila 1:  MARCAS ................... Ver las N marcas >
       fila 2:  las marcas, a todo lo ancho
   Si hay seis marcas o menos no se pinta el enlace y la etiqueta se queda sola
   en su fila, que es lo que toca. */
.jv-mega-panel__foot {
	display: grid;
	grid-template-columns: 1fr auto;
	align-items: center;
	gap: 8px 16px;
	padding: 12px var(--jv-panel-pad) 13px;
	background: var(--jv-color-canvas);
	border-top: 1px solid var(--jv-color-border);
}

.jv-mega-panel__label {
	grid-area: 1 / 1;
}

.jv-mega-panel__brands-all {
	grid-area: 1 / 2;
}

.jv-mega-panel__brands {
	grid-area: 2 / 1 / 3 / 3;
}

.jv-mega-panel__label {
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--jv-color-price-muted);
}

.jv-mega-panel__brands {
	display: flex;
	flex-wrap: wrap;
	gap: 4px 14px;
}

.main-navigation .jv-mega-panel__brands a {
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-ink);
	text-decoration: none;
}

.main-navigation .jv-mega-panel__brands a:hover {
	color: var(--jv-color-forest);
	text-decoration: underline;
}

/* Fuera del <span> de las marcas y empujado a la derecha: dentro parecia una
   marca mas de la lista. */
.main-navigation a.jv-mega-panel__brands-all {
	display: inline-flex;
	align-items: center;
	gap: 5px;
	justify-self: end;
	flex-shrink: 0;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
	text-decoration: none;
	white-space: nowrap;
}

.main-navigation a.jv-mega-panel__brands-all:hover {
	text-decoration: underline;
}

.jv-mega-panel__brands-all .jv-icon {
	width: auto;
	height: 12px;
}

/* "Ver todas (N)" en el mega-menú enlaza a una página de índice propia
   (/product-category/{cat}/marca/, ver jv_render_category_brand_index_page()
   en category-brand.php) en vez de un flyout/vista alternativa dentro del
   mega-menú: un panel secundario posicionado con left:100% quedaba
   recortado por el overflow:hidden de .jv-mega-panel, y una "vista"
   alternativa dentro del mismo panel no conseguía una altura de scroll
   fiable para 70+ marcas. Una página aparte también es mejor para SEO
   (URL propia indexable) que contenido oculto tras JS. */
.jv-brand-flyout__title {
	display: block;
	font-size: 11px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--jv-color-price-muted);
	margin-bottom: 10px;
}

/* Especificidad ".main-navigation .jv-brand-flyout__list" necesaria por el
   mismo motivo documentado arriba en .jv-mega-panel__list: Storefront trae
   ".main-navigation ul{display:block}"
   con más peso que una sola clase, y este <ul> vive anidado dentro de
   ".main-navigation" — sin el prefijo, "display:grid" nunca ganaba la
   cascada y las 78 marcas se apilaban colapsadas en una sola fila. */
.main-navigation .jv-brand-flyout__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.main-navigation .jv-brand-flyout__list--grid {
	display: grid;
	grid-template-columns: repeat(2, 1fr);
	gap: 0 16px;
}

.jv-brand-flyout__list a {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 8px;
	padding: 7px 4px;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-ink);
	text-decoration: none;
	border-radius: var(--jv-radius-control);
}

.jv-brand-flyout__list a:hover {
	background: var(--jv-color-canvas);
	color: var(--jv-color-forest);
}

.jv-brand-flyout__list a span {
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

@media (max-width: 600px) {
	.jv-brand-flyout__list--grid {
		grid-template-columns: 1fr;
	}
}

/* Vive en la cabecera, sobre verde oscuro: verde claro (5,30:1) para que se
   distinga del titulo, que va en blanco. Sin margin-left:auto, que ya lo separa
   el space-between de la cabecera. */
.main-navigation .jv-mega-panel__all {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	flex-shrink: 0;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-mint);
	text-decoration: none;
	white-space: nowrap;
}

.main-navigation .jv-mega-panel__all:hover {
	color: #ffffff;
	text-decoration: underline;
}

.jv-mega-panel__all .jv-icon {
	width: auto;
	height: 14px;
}

/* Panel ancho — categorías con muchas subcategorías (ej. Fertilizantes, 14).
   860px salen de medir el nombre mas largo de todo el menu:
   "Deshumidificadores Domesticos y Semi Industriales", 386px, x2 columnas +
   hueco + margenes = 845. */
.jv-mega-panel--wide {
	width: 860px;
	max-width: 90vw;
}

/* DOS columnas y no tres. Con tres, ese nombre de 386px pedia un panel de
   1.257px: se sale de una pantalla de 1280 y roza el 90vw de una de 1440. Con
   dos, el panel crece hacia abajo (7 filas en vez de 5), que sale mucho mas
   barato que crecer a lo ancho. */
.main-navigation .jv-mega-panel--wide .jv-mega-panel__list {
	columns: 2;
}

/* Panel "Más categorías". 660px = dos columnas de "Invernaderos y Armarios de
   Cultivo" (287px, la categoria raiz mas larga) + hueco + margenes. Se mide
   sobre TODAS las raiz y no solo sobre las que hay hoy en el panel, porque el
   priority-nav va moviendo aqui las que no caben en la barra. */
.jv-mega-panel--simple {
	width: 660px;
}

.jv-mega-panel__inner--full {
	width: 100%;
}

.main-navigation .jv-mega-panel--simple .jv-mega-panel__list {
	columns: 2;
	column-gap: 26px;
}

/* El <li> deja de ser la percha: con `right: 0` sobre el, el panel crecia hacia
   la izquierda desde el boton, y al ensancharlo a 660px se salia de la pantalla
   en cuanto el boton se corria a la izquierda (medido a 1280: x = -28px). Ahora
   cuelga de la fila del menu, que es un sitio fijo y siempre mas ancha que el
   panel, asi que no puede salirse.
   El `top: 100%` sin sumarle nada es parte del cambio de percha: la fila acaba
   justo donde acaba la banda blanca, asi que los 6px que necesitan los paneles
   colgados de un <li> aqui sobrarian. */
/* Dos clases y no una: `.jv-mega-nav .menu-item` declara position:relative con
   especificidad (0,2,0) y le ganaba a un `.jv-mega-item--more` suelto (0,1,0),
   asi que el <li> seguia siendo la percha y el panel seguia saliendose. */
.jv-mega-nav .jv-mega-item--more {
	position: static;
}

.jv-mega-item--more .jv-mega-panel--simple {
	top: 100%;
	left: auto;
	right: 0;
	transform: none;
}

/* Acciones del header: buscador expandible + cuenta + carrito, alineados y del mismo tamaño */
/* justify-self:end — la columna de la derecha ya no mide lo que las acciones,
   sino lo mismo que la del logo (ver .jv-header-row), asi que sin esto se
   quedarian flotando a la izquierda de su columna en vez de a ras del borde
   derecho del header. */
.jv-header-actions {
	display: flex;
	align-items: center;
	gap: 4px;
	flex-shrink: 0;
	padding: 0;
	justify-self: end;
}

.jv-header-search {
	position: relative;
	display: flex;
	align-items: center;
}

/* Centrado DENTRO de la columna central del grid (ver .jv-header-row) — no
   flex:1 (eso lo hacía llenar el hueco entero, pegado al lado del logo, no
   centrado respecto al ancho total de la fila). width:100% + max-width +
   margin:auto es el patrón estándar para centrar un bloque más estrecho
   que su columna. */
.jv-header-search--persistent {
	width: 100%;
	max-width: 600px;
	margin: 0 auto;
}

.jv-header-search--persistent .widget,
.jv-header-search--persistent .woocommerce-product-search {
	width: 100%;
	margin: 0;
}

.jv-header-search--persistent .search-field {
	width: 100%;
	padding: 7px 16px;
	font-size: 13.5px;
	border-radius: var(--jv-radius-card);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
}

/* Resultados del buscador permanente: desplegable superpuesto, nunca forma
   parte de la altura de la cabecera. El ancho permite que imagen, nombre,
   categoría y precio respiren sin romper cada fila. */
.jv-live-search-results {
	display: none;
	position: absolute;
	top: calc(100% + 12px);
	left: 50%;
	width: min(680px, calc(100vw - 48px));
	max-height: min(560px, calc(100vh - 180px));
	padding: 14px;
	overflow-y: auto;
	transform: translateX(-50%);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	box-shadow: none;
	color: var(--jv-color-ink);
	z-index: 100;
}

.jv-live-search-results.is-visible {
	display: block;
}

.jv-live-search-group + .jv-live-search-group {
	margin-top: 14px;
	padding-top: 14px;
	border-top: 1px solid var(--jv-color-border);
}

.jv-live-search-group__label {
	display: block;
	margin: 0 0 8px;
	color: var(--jv-color-price-muted);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: .08em;
	text-transform: uppercase;
}

.jv-live-search-chips {
	display: flex;
	flex-wrap: wrap;
	gap: 7px;
}

.jv-live-search-chip {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	padding: 7px 10px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-pill);
	color: var(--jv-color-ink);
	font-size: 12px;
	font-weight: 600;
	text-decoration: none;
}

.jv-live-search-chip:hover {
	background: var(--jv-color-mint-soft);
	border-color: var(--jv-color-forest);
}

.jv-live-search-chip__count {
	color: var(--jv-color-price-muted);
	font-size: 11px;
}

.jv-live-search-item {
	display: grid;
	grid-template-columns: 64px minmax(0, 1fr) auto;
	align-items: center;
	gap: 12px;
	min-height: 76px;
	padding: 6px;
	border-radius: var(--jv-radius-control);
	color: var(--jv-color-ink);
	text-decoration: none;
}

.jv-live-search-item + .jv-live-search-item {
	margin-top: 4px;
}

.jv-live-search-item:hover {
	background: var(--jv-color-canvas);
}

.jv-live-search-item__media {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 64px;
	height: 64px;
	overflow: hidden;
	background: #fff;
	border: 1px solid var(--jv-color-border);
	border-radius: 0;
}

.jv-live-search-item__media img {
	display: block;
	width: 100%;
	height: 100%;
	margin: 0;
	object-fit: contain;
}

.jv-live-search-item__body {
	display: block;
	min-width: 0;
}

.jv-live-search-item__title,
.jv-live-search-item__meta {
	display: block;
}

.jv-live-search-item__title {
	overflow: hidden;
	font-size: 13px;
	font-weight: 600;
	line-height: 1.3;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.jv-live-search-item__meta {
	margin-top: 3px;
	overflow: hidden;
	color: var(--jv-color-price-muted);
	font-size: 11px;
	line-height: 1.3;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.jv-live-search-item__price {
	color: var(--jv-color-forest);
	font-size: 13px;
	font-weight: 600;
	white-space: nowrap;
}

.jv-live-search-item__price del {
	display: block;
	color: var(--jv-color-price-muted);
	font-size: 10px;
	font-weight: 300;
}

.jv-live-search-item__price ins {
	background: none;
	text-decoration: none;
}

.jv-live-search-results__empty {
	margin: 0;
	padding: 16px;
	color: var(--jv-color-price-muted);
	font-size: 13px;
	text-align: center;
}

/* Header móvil estilo amazon.es: fila 1 = hamburguesa + logo + cuenta/cesta
   (mismo patrón que su ☰ + logo + cuenta + carrito), fila 2 = buscador a
   todo el ancho debajo. Storefront traía una "handheld footer bar" fija al
   pie de pantalla con estos mismos iconos duplicados (ver
   remove_action('storefront_footer','storefront_handheld_footer_bar',999)
   en inc/setup.php) — con esa barra quitada, el buscador YA NO debe
   ocultarse (display:none, como hacía antes): ahora es el único buscador
   visible en móvil, así que tiene que mostrarse en su propia fila. */
@media (max-width: 600px) {
	.jv-header-row {
		position: static;
		grid-template-columns: auto 1fr auto;
		grid-template-areas: "hamburger logo actions" "search search search";
		row-gap: 10px;
		column-gap: 10px;
	}

	.jv-header-mobile-toggle {
		display: inline-flex;
		grid-area: hamburger;
	}

	.site-branding {
		grid-area: logo;
	}

	.jv-header-actions {
		grid-area: actions;
	}

	.jv-header-search--persistent {
		display: block;
		grid-area: search;
		max-width: none;
		margin: 0;
	}

	/* Mismo selector que la regla de escritorio (con .site-header) porque el
	   @media no suma especificidad: con dos clases perderia contra ella y el
	   logo seguiria fijado a 60px de alto tambien aqui. */
	.site-header .site-branding .jv-site-logo {
		height: auto;
		width: 150px;
		max-width: 40vw;
	}

	/* La franja "☰ Todo" de la fila de categorías (debajo del buscador) queda
	   redundante en móvil: la hamburguesa ya vive arriba junto al logo (ver
	   .jv-header-mobile-toggle) y ambos botones abren el mismo drawer — dos
	   entradas visibles al mismo sitio, una encima de otra. Se oculta aquí
	   SOLO el de la fila de nav (sin la clase --mobile-toggle) dejando el de
	   la fila superior como único punto de entrada en esta anchura. */
	.jv-all-menu-toggle:not(.jv-header-mobile-toggle) {
		display: none;
	}
}

/* Cuenta/carrito viven en la fila superior (ver .jv-header-row), que desde
   el rebrand a Verdetop es verde claro (--jv-color-mint) y no verde oscuro:
   van en el verde corporativo, no en blanco, y el hover es un velo del propio
   verde. Si esta fila vuelve alguna vez a un fondo oscuro, hay que invertir
   estos tres colores a la vez (icono, hover y .jv-header-mobile-toggle). */
.jv-header-search__toggle,
.jv-header-account,
.jv-header-actions .cart-contents {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 38px;
	height: 38px;
	border-radius: 50%;
	background: none;
	border: none;
	color: var(--jv-color-forest);
	cursor: pointer;
	text-decoration: none;
	position: relative;
	flex-shrink: 0;
}

.jv-header-search__toggle:hover,
.jv-header-account:hover,
.jv-header-actions .cart-contents:hover {
	background: rgba(15, 86, 55, .12);
	color: var(--jv-color-forest);
}

.jv-header-search__toggle .jv-icon,
.jv-header-account .jv-icon,
.jv-header-actions .cart-contents .jv-icon {
	width: auto;
	height: 21px;
}

.jv-header-search__panel {
	display: none;
	position: absolute;
	top: 100%;
	right: 0;
	margin-top: 10px;
	width: 320px;
	max-width: 80vw;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-dropdown);
	box-shadow: none;
	padding: 16px;
	z-index: 70;
}

.jv-header-search.is-open .jv-header-search__panel {
	display: flex;
	align-items: center;
	gap: 8px;
}

.jv-header-search__panel .widget_product_search {
	flex: 1;
}

.jv-header-search__panel form.woocommerce-product-search {
	display: flex;
	gap: 8px;
}

.jv-header-search__close {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border-radius: 50%;
	background: none;
	border: none;
	color: var(--jv-color-price-muted);
	cursor: pointer;
	flex-shrink: 0;
}

.jv-header-search__close .jv-icon {
	width: auto;
	height: 16px;
}

.jv-header-search__close:hover {
	color: var(--jv-color-ink);
	background: var(--jv-color-canvas);
}

/* .jv-cart-count depende de position:relative en su padre directo
   (.cart-contents, dentro de .jv-header-actions) para anclarse al icono en
   vez de flotar respecto al ancestro posicionado más cercano de la página. */
.jv-header-actions .cart-contents {
	gap: 0;
}

.jv-cart-count {
	position: absolute;
	top: 3px;
	right: 3px;
}

/* Mini-carrito desplegable (ver jv_render_mini_cart_dropdown en
   inc/setup.php) — abre con hover sobre el wrapper completo (icono +
   panel), igual que el buscador (.jv-header-search__panel), y se queda
   abierto mientras el ratón está encima del panel para poder hacer clic en
   sus botones sin que se cierre a medio camino. */
.jv-mini-cart {
	position: relative;
}

.jv-mini-cart__panel {
	display: none;
	position: absolute;
	top: 100%;
	right: 0;
	margin-top: 10px;
	width: 420px;
	max-width: 90vw;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	box-shadow: none;
	padding: 0;
	z-index: 70;
	overflow: hidden;
}

.jv-mini-cart:hover .jv-mini-cart__panel,
.jv-mini-cart:focus-within .jv-mini-cart__panel {
	display: block;
}

/* Cabecera "Tu cesta (N)" — generada por jv_mini_cart_heading_script() en
   JS (ver inc/setup.php) a partir del contador de artículos ya presente en
   el icono de cesta (.jv-cart-count), en vez de un texto fijo de WooCommerce
   que no incluye el número de líneas de un vistazo. */
.jv-mini-cart__heading {
	padding: 16px 20px;
	border-bottom: 1px solid var(--jv-color-border);
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 15px;
	color: var(--jv-color-ink);
}

/* Contenido del widget nativo WC_Widget_Cart — solo se retocan tipografía y
   espaciado para que encaje con el resto del header, el marcado (lista de
   líneas de producto, subtotal, botones) es el que WooCommerce ya genera y
   sincroniza por AJAX (woocommerce_add_to_cart_fragments). */
.jv-mini-cart__panel .widget_shopping_cart_content {
	font-size: 13.5px;
	padding: 20px;
}

.jv-mini-cart__panel .woocommerce-mini-cart__empty-message {
	margin: 0;
	padding: 20px;
	color: var(--jv-color-price-muted);
}

.jv-mini-cart__panel ul.woocommerce-mini-cart {
	list-style: none;
	margin: 0 0 16px;
	padding: 0;
	max-height: 360px;
	overflow-y: auto;
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li {
	display: flex;
	align-items: center;
	gap: 14px;
	padding: 14px;
	margin-bottom: 8px;
	background: var(--jv-color-canvas);
	border-radius: var(--jv-radius-control);
	position: relative;
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li:last-child {
	margin-bottom: 0;
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li img {
	width: 60px;
	height: 60px;
	object-fit: contain;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	flex-shrink: 0;
}

/* WooCommerce envuelve IMAGEN + NOMBRE en un único <a> (no son hermanos
   sueltos) — display:flex aquí es lo que realmente separa la miniatura del
   texto en fila; sin esto, el <a> en su display:inline por defecto dejaba
   la imagen (absolute-ish por su tamaño) superpuesta visualmente sobre las
   primeras letras del nombre del producto. */
.jv-mini-cart__panel ul.woocommerce-mini-cart li a:not(.remove) {
	display: flex;
	align-items: center;
	gap: 12px;
	flex: 1;
	min-width: 0;
	color: var(--jv-color-ink);
	text-decoration: none;
	font-weight: 600;
	font-size: 14px;
	line-height: 1.4;
	padding-right: 16px;
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li .quantity {
	display: block;
	margin-top: 4px;
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li a.remove {
	position: absolute;
	top: 10px;
	right: 10px;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 22px;
	height: 22px;
	border-radius: 50%;
	background: var(--jv-color-surface);
	color: var(--jv-color-price-muted) !important;
	text-decoration: none;
	font-size: 15px;
	line-height: 1;
}

.jv-mini-cart__panel ul.woocommerce-mini-cart li a.remove:hover {
	background: var(--jv-color-sale);
	color: #ffffff !important;
}

.jv-mini-cart__panel .woocommerce-mini-cart__total {
	display: flex;
	justify-content: space-between;
	align-items: center;
	margin: 0 0 16px;
	padding-top: 14px;
	border-top: 1px solid var(--jv-color-border);
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 16px;
	color: var(--jv-color-ink);
}

.jv-mini-cart__panel .woocommerce-mini-cart__buttons {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0;
}

.jv-mini-cart__panel .woocommerce-mini-cart__buttons a {
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	font-size: 14px;
	padding: 12px 14px;
}

.widget_product_search .search-field,
.woocommerce-product-search .search-field {
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-card);
	background: var(--jv-color-surface);
	font-family: var(--jv-font-sans);
	font-weight: 300;
	font-size: var(--jv-text-body);
	padding: 10px 16px;
	width: 100%;
}

.woocommerce-product-search button[type="submit"] {
	background: none;
	border: none;
	color: var(--jv-color-ink);
	flex-shrink: 0;
}

/* La fila colapsaba al drawer por debajo de 1280px, porque entre 960 y 1279 el
   menú se partía en dos líneas. Eso ya no puede pasar: el priority-nav
   (jv_priority_nav_script) esconde en "Más categorías" las categorías que no
   caben, así que la fila se queda en una línea a cualquier anchura, con las que
   quepan. El colapso baja aquí hasta 767px.
   767 y no menos porque el suelo no lo pone este tema: **Storefront oculta
   .main-navigation por su cuenta por debajo de 768px**. Comprobado a 700, 640 y
   601: la fila no aparece aunque se quite este media query. */
@media (max-width: 767px) {
	.jv-header-nav-row {
		flex-wrap: wrap;
	}

	.main-navigation.jv-main-nav {
		flex: 1 1 100%;
		order: 2;
	}

	/* El botón "Menú" nativo de Storefront (acordeón inline con solo las
	   top-4 categorías) queda sustituido por .jv-all-menu-toggle, que abre
	   el drawer con el árbol COMPLETO de categorías y navegación drill-down
	   — mismo propósito, mejor cobertura y mejor UX (un solo punto de
	   entrada, en vez de dos botones distintos para "menú" y "todo"). */
	.menu-toggle {
		display: none;
	}

	.jv-primary-navigation {
		display: none;
		width: 100%;
	}

	.main-navigation.toggled .jv-primary-navigation {
		display: block;
	}

	.jv-mega-nav {
		flex-direction: column;
		align-items: stretch;
		flex-wrap: nowrap;
		gap: 0;
		padding: 8px 0 16px;
	}

	.jv-mega-nav > .menu-item > a {
		width: 100%;
		justify-content: space-between;
		padding: 12px 4px;
		border-bottom: 1px solid var(--jv-color-border);
	}

	.jv-mega-panel {
		display: none;
		position: static;
		width: 100%;
		max-width: none;
		transform: none;
		box-shadow: none;
		border: none;
		border-bottom: 1px solid var(--jv-color-border);
		border-radius: 0;
		flex-direction: column;
	}

	.jv-mega-item.is-open .jv-mega-panel,
	.jv-mega-item.jv-mobile-open .jv-mega-panel {
		display: flex;
	}

	.jv-mega-item--more .jv-mega-panel--simple {
		right: auto;
	}

	.main-navigation .jv-mega-panel .jv-mega-panel__list {
		columns: 1;
	}

	.jv-mega-panel--wide {
		width: 100%;
	}

	.jv-header-actions {
		order: 1;
		margin-left: auto;
	}
}

/* CTA solida — botón redondeado, verde llamativo (mismo tono que "Añadir al
   carrito" en la PDP, unificado en todo el sitio: categorías, grid, CTAs). */
/* a.button.alt Y button.button.alt (los dos a 0-2-1): el CSS en linea del
   Customizer de Storefront trae `button.alt` con 0-1-1, que le gana a `.button`
   a secas y pintaba de #333333 cualquier <button class="button alt"> — el
   "Suscribirme" del boletin del pie salia negro en toda la web. */
.button,
.wp-block-button__link,
.single_add_to_cart_button,
.checkout-button,
a.button.alt,
button.button.alt {
	background: var(--jv-color-selected);
	border: 1px solid var(--jv-color-selected);
	color: #ffffff;
	border-radius: var(--jv-radius-control);
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: var(--jv-text-body);
	padding: 16px 20px;
	box-shadow: none;
	text-transform: none;
}

/* El hover se INVIERTE (verde claro con texto verde oscuro) en vez de oscurecer
   el fondo: al quedar un unico verde oscuro, "oscurecer" ya no existe. Da
   5.30:1, que pasa AA. Mismo criterio en los otros cuatro botones del sitio. */
.button:hover,
.wp-block-button__link:hover,
.single_add_to_cart_button:hover,
a.button.alt:hover,
button.button.alt:hover {
	background: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

/* Storefront aplica su propio fondo oscuro (--storefront-button-background,
   resuelto a un gris/negro) al botón de añadir al carrito de la PDP con
   mayor especificidad que la regla genérica de arriba — se refuerza aquí
   con el mismo selector que usa Storefront para ganar la cascada. */
.single-product div.product form.cart .single_add_to_cart_button,
button.single_add_to_cart_button.alt,
.single_add_to_cart_button.button.alt {
	background: var(--jv-color-selected) !important;
	border-color: var(--jv-color-selected) !important;
	color: #ffffff !important;
}

.single-product div.product form.cart .single_add_to_cart_button:hover,
button.single_add_to_cart_button.alt:hover,
.single_add_to_cart_button.button.alt:hover {
	background: var(--jv-color-mint) !important;
	border-color: var(--jv-color-mint) !important;
	color: var(--jv-color-forest) !important;
}

/* ===== Layout PLP — sidebar de filtros + grid ===== */
/* .jv-plp-layout hereda el ancho de .jv-container (misma clase aplicada por
   inc/category-filters.php) — no declara max-width/padding propios. */

.jv-plp-layout {
	display: flex;
	align-items: flex-start;
	gap: 40px;
}

/* Amazon usa prácticamente todo el ancho del viewport en categoría (sin el
   tope de 1280px que usa el resto del sitio) — el listado de producto es la
   página que más se beneficia de esa anchura extra porque permite 4
   columnas con aire real entre tarjetas en vez de comprimirlas.
   .jv-plp-layout vive dentro de #content > .col-full, que YA tiene su
   propio max-width:1280px (ver regla .col-full arriba) — quitarle el
   max-width solo a .jv-plp-layout no basta, porque el padre ya recortó el
   ancho disponible antes de que la regla llegue. Se usa el mismo patrón
   full-bleed que .jv-home-band (100vw + margen negativo) para saltarse
   ese límite del padre y llegar a ancho de viewport completo. */
.jv-plp-layout--wide {
	width: 100vw;
	max-width: none;
	margin-left: calc(50% - 50vw);
	padding: 0 32px;
	box-sizing: border-box;
}

.jv-plp-main {
	flex: 1;
	min-width: 0;
	order: 2;
}

.jv-plp-sidebar {
	width: 240px;
	flex-shrink: 0;
	position: sticky;
	/* + el header, que ahora esta pegado y taparia el filtro de arriba. */
	top: calc(var(--jv-header-height) + 24px);
	order: 1;
}

.jv-filter-section {
	margin-bottom: 32px;
}

.jv-filter-section__title {
	font-family: var(--jv-font-sans);
	font-size: var(--jv-text-filter-heading);
	font-weight: 600;
	margin: 0 0 12px;
}

.jv-filter-list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.jv-filter-list li {
	margin-bottom: 4px;
}

.jv-filter-list a {
	display: flex;
	justify-content: space-between;
	gap: 8px;
	padding: 8px 10px;
	border-radius: var(--jv-radius-control);
	font-size: var(--jv-text-body);
	font-weight: 300;
	color: var(--jv-color-ink);
	text-decoration: none;
}

.jv-filter-list a:hover {
	background: var(--jv-color-surface);
	color: var(--jv-color-forest);
}

.jv-filter-list--brands {
	max-height: 420px;
	overflow-y: auto;
}

.jv-filter-count {
	color: var(--jv-color-price-muted);
	font-weight: 300;
	flex-shrink: 0;
}

@media (max-width: 900px) {
	.jv-plp-layout {
		flex-direction: column;
		/* align-items pasa a gobernar el ANCHO al girar a columna, y el
		   flex-start de la regla de escritorio (que esta ahi para que el
		   sidebar sticky no se estire a lo alto) encogia cada hijo a su
		   contenido: .jv-plp-main media 387.9px donde solo habia 326 y sacaba
		   scroll horizontal a toda la pagina. */
		align-items: stretch;
	}

	.jv-plp-sidebar {
		width: 100%;
		position: static;
		order: 2;
	}

	.jv-plp-main {
		order: 1;
	}
}

/* Grid de producto — grid CSS explicito, reemplaza el mecanismo de floats de Storefront */
.woocommerce ul.products,
.woocommerce-page ul.products {
	display: grid !important;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
	list-style: none;
	margin: 0 0 24px;
	padding: 0;
}

.woocommerce ul.products::before,
.woocommerce ul.products::after,
.woocommerce-page ul.products::before,
.woocommerce-page ul.products::after {
	content: none !important;
	display: none !important;
}

.woocommerce ul.products.columns-3,
.woocommerce-page ul.products.columns-3 {
	grid-template-columns: repeat(3, 1fr);
}

.woocommerce ul.products.columns-2,
.woocommerce-page ul.products.columns-2 {
	grid-template-columns: repeat(2, 1fr);
}

/* 4 columnas a ancho completo (ver .jv-plp-layout--wide), como en Amazon —
   antes se forzaban 3 aquí porque el sidebar+contenedor de 1280px dejaba
   muy poco ancho de columna para 4; con el layout ahora a ancho completo, 4
   columnas caben con aire de sobra.
   OJO: ".woocommerce"/".woocommerce-page" son clases de <body>, no
   ancestros de ".jv-plp-main" dentro del DOM — ".jv-plp-main .woocommerce
   ul.products" como combinador descendiente nunca podía coincidir (pedía
   un .woocommerce DENTRO de .jv-plp-main). Body-class + selector de
   descendiente normal (sin ese tramo intermedio imposible) sí funciona, y
   con 2 clases + tag iguala/supera la especificidad de ".woocommerce
   ul.products.columns-3" al venir después en la cascada. */
.jv-plp-main ul.products.columns-3,
.jv-plp-main ul.products.columns-2,
.jv-plp-main ul.products.columns-4 {
	grid-template-columns: repeat(4, 1fr);
}

@media (max-width: 1300px) {
	.jv-plp-main ul.products.columns-3,
	.jv-plp-main ul.products.columns-2,
	.jv-plp-main ul.products.columns-4 {
		grid-template-columns: repeat(3, 1fr);
	}
}

.woocommerce ul.products li.product,
.woocommerce-page ul.products li.product {
	display: block !important;
	width: auto !important;
	margin: 0 !important;
	float: none !important;
	clear: none !important;
}

@media (max-width: 900px) {
	.woocommerce ul.products,
	.woocommerce-page ul.products {
		grid-template-columns: repeat(2, 1fr) !important;
	}
}

/* Producto — imagen con esquinas suaves y foto en contexto, tarjeta cálida tipo espejoled */
ul.products li.product {
	position: relative;
	box-shadow: none;
	border: none;
}

ul.products li.product a.woocommerce-LoopProduct-link {
	position: relative;
	display: block;
}

/* object-fit: contain — el producto se ve entero dentro del cuadrado (con
   fondo blanco de relleno si la foto original no es cuadrada) en vez de
   recortarlo para llenar el marco. */
/* padding propio en la imagen (no solo en el <li>) — Amazon deja aire
   alrededor de cada foto de producto dentro de su tarjeta blanca, en vez de
   que la imagen toque el borde del marco; box-sizing:border-box para que
   el padding no empuje el ancho total más allá del 100% de la columna. */
/* padding:14px dejaba demasiado margen alrededor de la foto — Amazon dejar
   la imagen ocupar casi toda la tarjeta, con solo un respiro mínimo, no un
   marco grueso. 4px es ese "casi pantalla completa pero no del todo". */
ul.products li.product img,
.woocommerce ul.products li.product img {
	display: block;
	width: 100%;
	aspect-ratio: 1 / 1;
	object-fit: contain;
	background: var(--jv-color-surface);
	border-radius: var(--jv-radius-card);
	box-shadow: none;
	overflow: hidden;
	padding: 4px;
	box-sizing: border-box;
	transition: transform .5s ease;
}

ul.products li.product a.woocommerce-LoopProduct-link:hover img {
	transform: scale(1.04);
}

/* Icono de lupa / quick-view flotante, visible al hover, puramente decorativo */
ul.products li.product a.woocommerce-LoopProduct-link::after {
	content: "";
	position: absolute;
	top: 12px;
	right: 12px;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: #ffffff;
	background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231f2a20' stroke-width='1.8'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cline x1='20' y1='20' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: center;
	background-size: 16px 16px;
	box-shadow: none;
	opacity: 0;
	transform: translateY(-4px);
	transition: opacity .25s ease, transform .25s ease;
	pointer-events: none;
}

ul.products li.product:hover a.woocommerce-LoopProduct-link::after {
	opacity: 1;
	transform: translateY(0);
}

ul.products li.product .price {
	font-weight: 300;
	color: var(--jv-color-ink);
}

ul.products li.product .price del,
ul.products li.product .jv-loop-price-row del {
	color: var(--jv-color-price-muted);
	opacity: 1;
	font-size: 14px;
}

ul.products li.product .price ins,
ul.products li.product .jv-loop-price-row ins {
	color: var(--jv-color-ink);
	text-decoration: none;
	font-size: 19px;
	font-weight: 600;
}

ul.products li.product .woocommerce-loop-product__title {
	font-weight: 600;
	font-size: var(--jv-text-body);
	margin-top: 12px;
}

/* Precio de oferta / badge de descuento — terracota cálido con buen contraste AA.
   Por defecto (PDP) sigue siendo el badge nativo de WooCommerce posicionado
   sobre la imagen (position:absolute heredado del core). */
.onsale {
	background: var(--jv-color-sale);
	color: #ffffff;
	border-radius: var(--jv-radius-dropdown);
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 12px;
	line-height: 1.4;
	letter-spacing: 0.02em;
	text-transform: uppercase;
	top: 12px;
	left: 12px;
	padding: 5px 12px;
	box-shadow: none;
	z-index: 2;
}

/* En el grid/listado el badge vive junto al precio, no sobre la imagen —
   ver jv_render_loop_price_with_badge() en sale-badge.php. Se neutraliza el
   position:absolute heredado para que fluya en línea junto al precio. */
ul.products li.product .jv-loop-price-row {
	display: flex;
	align-items: baseline;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px;
	margin-top: 12px;
	text-align: center;
}

ul.products li.product .jv-loop-badge {
	position: static;
	display: inline-block;
	background: none;
	border: none;
	box-shadow: none;
	padding: 0;
	margin: 0;
	color: var(--jv-color-sale);
	font-size: 15px;
	font-weight: 600;
	line-height: inherit;
}

/* ===== Hover de tarjeta de producto (grid) — inspirado en growindustry.es =====
   Toda la tarjeta se resalta al pasar el ratón (borde + elevación sutil,
   además del zoom de imagen ya existente). El botón "Añadir al carrito" solo
   aparece en hover (menos ruido visual en el listado), y si el producto es
   variable, unos botones de formato aparecen también en hover — clicar uno
   actualiza el precio mostrado sin recargar la página (ver
   inc/loop-hover-variants.php). Al salir de la tarjeta todo vuelve a su
   estado por defecto (precio de rango, sin variante seleccionada). */

/* La tarjeta entera (imagen+título+precio+variantes+botón) es una única
   superficie con su propio fondo/borde/sombra — al hacer hover crece hacia
   abajo mostrando variantes+botón, tapando visualmente lo que haya debajo
   (fila siguiente de productos), pero SIN salir del flujo normal del grid:
   la celda del <li> se queda anclada en su fila/columna reales (position:
   relative, nunca absolute) y solo su CONTENIDO interno se permite
   desbordar hacia abajo vía overflow visible + un contenedor interno con
   position:absolute (ver .jv-loop-card-inner más abajo).
   La primera versión de este hover ponía position:absolute en el propio
   <li> — eso lo saca del flujo del grid, y el grid recalcula el resto de
   columnas para llenar el hueco que deja: el vecino de al lado "saltaba" a
   ocupar su sitio y el hover parecía desplazar/ocultar productos en vez de
   simplemente superponerse a la fila de abajo. Anclar el <li> y solo volar
   su contenido interno evita ese reflow por completo. */
ul.products li.product {
	position: relative;
	border: 1px solid transparent;
	border-radius: var(--jv-radius-card);
	padding: 8px;
	margin: -8px -8px 1.5em;
	transition: border-color .2s ease, box-shadow .2s ease, background-color .2s ease;
}

.woocommerce ul.products li.product.is-hover-expanded,
.woocommerce-page ul.products li.product.is-hover-expanded {
	z-index: 5;
}

/* Contenedor interno que replica visualmente la tarjeta (fondo/borde/sombra)
   y es el que realmente se vuelve position:absolute al expandir — anclado
   al <li> (que se queda estático, position:relative, ocupando su celda de
   grid normal) con top/left/width en 0/0/100%, así que en reposo es
   indistinguible de un bloque normal en flujo, y en hover se convierte en
   overlay que crece hacia abajo sin afectar la altura de la fila del grid
   ni el ancho de las columnas vecinas. */
.jv-loop-card-inner {
	position: relative;
}

.is-hover-expanded .jv-loop-card-inner {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	box-shadow: none;
	padding: 8px;
	box-sizing: border-box;
}

/* El botón "Añadir al carrito" y el panel de variantes viven ahora dentro
   del flujo normal de la tarjeta (ya no son overlays position:absolute
   propios) — es la tarjeta entera la que se convierte en overlay al hacer
   hover (ver arriba), así que su contenido interno vuelve a comportarse
   como una columna normal: título, precio, variantes y botón se apilan uno
   debajo de otro sin necesidad de calcular posiciones por JS. */
ul.products li.product .button {
	opacity: 0;
	max-height: 0;
	overflow: hidden;
	margin-top: 0;
	padding-top: 0;
	padding-bottom: 0;
	border-width: 0;
	transition: opacity .15s ease, max-height .2s ease, margin-top .2s ease, padding .2s ease;
	background: var(--jv-color-selected);
	border-color: var(--jv-color-selected);
}

ul.products li.product .button:hover {
	background: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

ul.products li.product.is-hover-expanded .button {
	opacity: 1;
	max-height: 60px;
	margin-top: 10px;
	padding-top: 12px;
	padding-bottom: 12px;
	border-width: 1px;
}

.jv-loop-short-desc {
	font-size: 12.5px;
	line-height: 1.4;
	color: var(--jv-color-price-muted);
	margin: 4px 0 0;
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
}

/* Panel de botones de variante — ahora fluye dentro de la tarjeta (que ya
   se expande entera al hacer hover, ver arriba) en vez de calcular su
   posición absoluta por JS. */
.jv-loop-variants {
	display: none;
	flex-wrap: wrap;
	gap: 6px;
	padding: 10px;
	margin-top: 10px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
}

ul.products li.product.is-hover-expanded .jv-loop-variants {
	display: flex;
}

/* Nombre de variante arriba, precio debajo, CENTRADO — mismo criterio visual
   que el selector "Formato" de la PDP (.jv-variation-btn: centrado, label en
   600, precio en 400/muted), pero sin el precio tachado dentro del botón
   (eso solo se muestra ya en el precio principal de la tarjeta) y en tamaño
   más compacto, porque aquí caben muchas más variantes por tarjeta que
   "Formato" en la PDP. */
.jv-loop-variant-btn {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 1px;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	padding: 4px 8px;
	font-family: var(--jv-font-sans);
	font-size: 11px;
	font-weight: 600;
	line-height: 1.3;
	color: var(--jv-color-ink);
	cursor: pointer;
	white-space: nowrap;
	text-align: center;
	transition: border-color .15s ease, background-color .15s ease, color .15s ease;
}

.jv-loop-variant-btn__label {
	white-space: nowrap;
}

.jv-loop-variant-btn__price {
	font-size: 10.5px;
	font-weight: 300;
	color: var(--jv-color-price-muted);
	white-space: nowrap;
}

.jv-loop-variant-btn__price ins {
	text-decoration: none;
	color: inherit;
}

.jv-loop-variant-btn__price del {
	display: none;
}

.jv-loop-variant-btn:hover {
	border-color: var(--jv-color-selected);
}

/* Estilo Amazon (mismo patrón que .jv-variation-btn.is-selected en la PDP,
   ver style.css): fondo claro con borde verde marcado, NO relleno sólido —
   antes se rellenaba entero de verde, inconsistente con el selector de la
   ficha de producto. */
.jv-loop-variant-btn.is-selected {
	border: 2px solid var(--jv-color-selected);
	background: var(--jv-color-surface);
	color: var(--jv-color-ink);
	padding: 4px 9px;
}

.jv-loop-variant-btn.is-selected .jv-loop-variant-btn__price {
	color: var(--jv-color-price-muted);
}

/* Inputs, selects, size/format selector — 1px borde + 2-4px radio */
input[type="text"],
input[type="email"],
input[type="password"],
input[type="tel"],
input[type="number"],
select,
textarea {
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-control);
	font-family: var(--jv-font-sans);
	font-weight: 300;
	font-size: var(--jv-text-body);
	box-shadow: none;
}

/* Filtros / widgets de sidebar */
.widget-area .widget-title {
	font-size: var(--jv-text-filter-heading);
	font-weight: 600;
	text-transform: none;
}

/* Breadcrumb — tamaño reducido estilo Amazon (más discreto que el resto del
   texto de la página) y sin subrayado en los enlaces. */
.woocommerce-breadcrumb {
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

.woocommerce-breadcrumb a {
	color: var(--jv-color-price-muted);
	text-decoration: none;
}

.woocommerce-breadcrumb a:hover {
	text-decoration: underline;
}

/* Footer — mismo tono que --jv-color-canvas (ya no crema cálido, ver :root)
   para quedar coherente con el resto de la página. */
.site-footer,
#colophon {
	/* Sin el padding vertical de Storefront (1,618em arriba, 3,7em abajo). El
	   aire de arriba ya lo pone el padding de .jv-footer-main, y el de abajo lo
	   ponia por duplicado la barra inferior. Ojo: quitarlo junta el borde de
	   arriba de aqui con el de .jv-footer-main, que por eso pierde el suyo. */
	padding: 0;
	background: var(--jv-color-canvas);
	color: var(--jv-color-ink);
}

.site-footer a,
#colophon a {
	color: var(--jv-color-ink);
}

.site-footer a:hover,
#colophon a:hover {
	color: var(--jv-color-forest);
}

/* Iconos SVG de la cabecera/carrito — sin emojis, siempre SVG inline.
   flex-shrink:0 es necesario: dentro de un padre flex (botones de header,
   nav) un <svg> sin width/height HTML explícitos (solo viewBox) puede
   colapsar su ancho a ~0 al calcular su tamaño flex-basis intrínseco. */
.jv-icon {
	display: inline-flex;
	flex-shrink: 0;
	width: auto;
	height: 20px;
	fill: currentColor;
	stroke: none;
	vertical-align: middle;
}

/* Verde claro de marca (--jv-color-selected) en vez de --jv-color-forest —
   ahora que el icono vive sobre el fondo verde oscuro de marca de la
   fila superior (ver .jv-header-row), un badge en el mismo verde apenas
   destacaba; este tono es lo bastante más claro para saltar a la vista,
   equivalente al badge amarillo de amazon.es sobre su barra oscura. */
.jv-cart-count {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	min-width: 18px;
	height: 18px;
	padding: 0 4px;
	border-radius: 50%;
	/* Circulo blanco con el numero en verde oscuro (8.73:1). Vive sobre la
	   franja verde claro del header, asi que el blanco lo separa del fondo sin
	   necesitar borde. Es el unico elemento circular que queda tras pasar los
	   radios a 0: aqui el circulo es la forma, no una esquina redondeada. */
	background: #ffffff;
	color: var(--jv-color-forest);
	font-size: 11px;
	font-weight: 600;
	line-height: 1;
}

/* ===== Home ===== */
/* .jv-home no declara max-width/padding propio: ya vive dentro de
   #content > .col-full (unificado arriba con .jv-container). */

.jv-hero {
	position: relative;
	color: #ffffff;
	min-height: 640px;
	text-align: left;
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	margin: 0;
	background: var(--jv-color-forest);
}

.jv-hero__slides {
	position: absolute;
	inset: 0;
}

.jv-hero__slide {
	position: absolute;
	inset: 0;
	opacity: 0;
	pointer-events: none;
	transition: opacity 500ms ease;
}

.jv-hero__slide.is-active {
	opacity: 1;
	pointer-events: auto;
	z-index: 1;
}

.jv-hero__media {
	position: absolute;
	inset: 0;
	background-position: center center;
	background-repeat: no-repeat;
	background-size: cover;
}

/* right ademas de left: el panel solo tenia `left`, asi que su ancho lo fijaba
   el contenido hasta el max-width y podia desbordar por la derecha. Con
   left:48px no se notaba, pero a partir de left:147px el tramo 701-767px de
   viewport (justo encima del breakpoint movil de 700px) dejaba de tener
   147+620 px de sitio y el overflow:hidden del hero recortaba el texto.
   Con left + right + max-width el ancho es min(620, hueco disponible) y no
   hay recorte en ninguna anchura. */
.jv-hero__inner {
	position: absolute;
	/* Alineado con la linea interior del lockup del logo, no con un px fijo.
	   El hero es full-bleed (ancho del viewport), asi que el % se resuelve
	   sobre el viewport igual que el del contenedor: (100% - 92%) / 2 es el
	   mismo 4% de aire lateral que deja .col-full, + su padding = borde
	   izquierdo del logo, + el lado del cuadrado = la linea interior.
	   Iba a `left: 147px`, que es el valor que da esta cuenta a 1680px de
	   ancho exactos y a ningun otro: a 1920 se quedaba 9,8px corto y a 1100 se
	   pasaba 23px. NO usar --jv-logo-height aqui (ver --jv-logo-square). */
	left: calc(
		(100% - var(--jv-container-max)) / 2
		+ var(--jv-container-pad)
		+ var(--jv-logo-square)
	);
	right: 48px;
	/* Centrado vertical dentro del hero: mismo aire por encima y por debajo del
	   panel. Antes iba anclado abajo (bottom:64px), asi que el hueco superior
	   era el sobrante del hero — mucho mayor.
	   Se hace con top/bottom a 0 + height:fit-content + margenes automaticos,
	   NO con translateY(-50%): la traslacion cae en medio pixel cuando la
	   altura del panel es impar y emborrona el texto. Solo margin-top y
	   margin-bottom (nunca el atajo `margin: auto`), porque los margenes
	   horizontales automaticos lo centrarian tambien en horizontal y perderia
	   el left:147px. */
	top: 0;
	bottom: 0;
	height: fit-content;
	margin-top: auto;
	margin-bottom: auto;
	z-index: 2;
	width: fit-content;
	max-width: 620px;
	padding: 28px 32px 32px;
	background: rgba(20, 33, 22, 0.78);
}

.jv-hero .jv-editorial-heading {
	color: #ffffff;
	font-size: clamp(38px, 4.2vw, 60px);
	font-weight: 600;
	letter-spacing: -0.02em;
	line-height: 1.04;
	margin: 0 0 18px;
}

.jv-hero__eyebrow {
	margin: 0 0 14px;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .11em;
	text-transform: uppercase;
}

.jv-hero__subhead {
	font-size: 18px;
	font-weight: 300;
	line-height: 1.6;
	max-width: 560px;
	margin: 0 0 32px;
}

.jv-hero__cta {
	display: inline-block;
	background: var(--jv-color-forest);
	color: #ffffff;
	border-color: var(--jv-color-forest);
	border-radius: var(--jv-radius-control);
	padding: 16px 32px;
}

.jv-hero__cta:hover {
	background: var(--jv-color-mint-soft);
	border-color: var(--jv-color-mint-soft);
	color: var(--jv-color-forest);
}

.jv-hero__controls {
	position: absolute;
	right: 24px;
	bottom: 24px;
	z-index: 4;
	display: flex;
	align-items: center;
	gap: 12px;
	padding: 8px;
	background: rgba(20, 33, 22, 0.78);
}

.jv-hero__arrow,
.jv-hero__dot {
	appearance: none;
	border: 1px solid rgba(255, 255, 255, .65);
	background: transparent;
	color: #ffffff;
	cursor: pointer;
}

.jv-hero__arrow {
	display: grid;
	place-items: center;
	width: 38px;
	height: 38px;
	padding: 0;
	font-size: 18px;
}

.jv-hero__dots {
	display: flex;
	gap: 8px;
}

.jv-hero__dot {
	width: 10px;
	height: 10px;
	padding: 0;
	border-radius: 50%;
}

.jv-hero__dot.is-active {
	background: #ffffff;
}

.jv-hero__arrow:focus-visible,
.jv-hero__dot:focus-visible {
	outline: 3px solid #ffffff;
	outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
	.jv-hero__slide {
		transition: none;
	}
}

@media (max-width: 700px) {
	.jv-hero {
		min-height: 560px;
	}

	.jv-hero .jv-editorial-heading {
		font-size: 28px;
		line-height: 1.02;
		margin-bottom: 12px;
	}

	.jv-hero__media {
		background-position: 62% center;
	}

	.jv-hero__inner {
		left: 16px;
		right: 16px;
		/* Se deshace el centrado vertical del desktop: aqui el panel va anclado
		   abajo, dejando hueco para los controles del carrusel. */
		top: auto;
		margin-top: 0;
		margin-bottom: 0;
		bottom: 248px;
		padding: 18px;
	}

	.jv-hero__eyebrow {
		margin-bottom: 10px;
		font-size: 11px;
	}

	.jv-hero__subhead {
		font-size: 15px;
		line-height: 1.4;
		margin-bottom: 14px;
	}

	.jv-hero__cta {
		padding: 12px 18px;
		font-size: 14px;
	}

	.jv-hero__controls {
		right: 16px;
		bottom: 82px;
	}
}

/* Bandas de sección full-bleed con fondo alterno — dan ritmo visual y marcan
   con claridad el cambio de apartado en la home (antes todo el mismo crema). */
.jv-home-band {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	padding: 80px 0;
}

/* La banda que envuelve el hero es la primera cosa bajo el header — el
   padding-top general de 80px de .jv-home-band dejaba un hueco enorme entre
   el menú y la imagen del carrusel, antes de llegar a nada de contenido.
   10px es aire mínimo, no separación editorial entre secciones. Mismo
   padding-bottom (no 0): el hueco entre la imagen del hero y el siguiente
   bloque (logística/almacén Valencia, .jv-home-logistics, pegado justo
   debajo en el HTML) tiene que ser igual de aire que el de arriba —
   dejarlo en 0 pegaba la foto directamente al bloque verde siguiente,
   asimétrico frente al margen sí visible encima del hero. */
/* El hero va a sangre: ni aire ni linea por encima ni por debajo.
   La banda YA es full-bleed (width:100vw), asi que no hace falta sacar el
   hero con otro 100vw propio — que ademas seria un octavo elemento
   desbordando en movil. Lo unico que lo metia hacia dentro era el
   .jv-container de dentro, que aqui se anula. */
.jv-home-band:first-child {
	padding-top: 0;
	padding-bottom: 0;
}

.jv-home-band:first-child > .jv-container {
	max-width: none;
	padding-left: 0;
	padding-right: 0;
}

/* La regla general `.jv-home-band + .jv-home-band { border-top }` dibujaba una
   linea justo debajo de la foto. Entre el hero y lo que venga despues no debe
   haber separador: la propia foto ya corta la pagina. */
.jv-home-band:first-child + .jv-home-band {
	border-top: none;
}

.jv-home-band--canvas {
	background: var(--jv-color-canvas);
}

.jv-home-band--surface {
	background: var(--jv-color-surface);
}


/* Ojo: --canvas acaba en este MISMO verde claro (se redefine mas abajo, en el
   bloque de ritmo de bandas), asi que las dos clases pintan igual por caminos
   distintos. Si se cambia el color de una hay que mirar la otra. */
.jv-home-band--mint {
	background: var(--jv-color-mint);
}

/* Franja de confianza/logística justo debajo del hero — almacén propio en
   Valencia + envío peninsular, mensaje que el usuario quiere visible desde
   el primer scroll de la home, no solo dentro de la ficha de producto
   (donde ya vive un bloque parecido, .jv-trust-badges). */
.jv-home-logistics {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	background: var(--jv-color-forest);
	padding: 22px 0;
}

/* Mismo ancho que el resto de la web (.jv-container): 92% centrado con
   el mismo padding, manteniendo el fondo a sangre del bloque padre. */
/* Rejilla y no flex con space-between: ese reparto sale de lo que mide cada
   texto, asi que los cuatro bloques caian donde caian y no sobre las columnas
   de la franja mint de abajo (medido a 1570: hasta 172px de desvio). Estas
   cuatro columnas son las MISMAS que las de .jv-footer-contacto__inner y las de
   .jv-footer-main. */
.jv-home-logistics__inner {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	align-items: center;
	gap: 24px;
	max-width: var(--jv-container-max);
	margin: 0 auto;
	padding: 0 var(--jv-container-pad);
	box-sizing: border-box;
}

.jv-home-logistics__item {
	display: flex;
	align-items: center;
	gap: 10px;
	color: #ffffff;
}

.jv-home-logistics__item strong {
	display: block;
	font-size: 14px;
	font-weight: 600;
}

.jv-home-logistics__item span {
	display: block;
	font-size: 12.5px;
	color: rgba(255, 255, 255, .8);
}

/* Caja fija de 20x20, la misma que la franja mint de abajo. Con `width:auto` el
   ancho lo ponia el viewBox y los cuatro iconos no lo tienen igual (medal y
   shield 512x512 -> 26px, location 384x512 -> 19,5, truck 640x512 -> 32,5), asi
   que cada texto arrancaba a una distancia distinta de su propio icono. No
   deforma: preserveAspectRatio vale `xMidYMid meet` por defecto. */
.jv-home-logistics__icon {
	width: 20px;
	height: 20px;
	flex-shrink: 0;
	fill: #ffffff;
}

/* Los mismos cortes que .jv-footer-contacto__inner: antes esta franja se ponia
   en una columna a 700px mientras la de abajo seguia en dos hasta 560, y las dos
   estan a la vista a la vez al final de la home. */
@media (max-width: 900px) {
	.jv-home-logistics__inner {
		grid-template-columns: repeat(2, 1fr);
		gap: 16px;
	}
}

@media (max-width: 560px) {
	.jv-home-logistics__inner {
		grid-template-columns: 1fr;
	}
}

/* Banda oscura verde bosque — para la sección de Servicios, el único bloque
   con fondo de marca fuerte, coherente con el acento usado en botones/CTAs. */
.jv-home-band--forest {
	background: var(--jv-color-forest);
}

.jv-home-band--forest .jv-section__title,
.jv-home-band--forest .jv-service-card h3 {
	color: #ffffff;
}

.jv-home-band--forest .jv-service-card p {
	color: rgba(255, 255, 255, .75);
}

.jv-home-band--forest .jv-service-card {
	background: rgba(255, 255, 255, .06);
	border-color: rgba(255, 255, 255, .16);
}

.jv-home-band--forest .jv-service-card__icon {
	color: #ffffff;
}

.jv-home-band--forest .jv-link-cta {
	color: #ffffff;
}

.jv-home-band + .jv-home-band {
	border-top: 1px solid var(--jv-color-border);
}

.jv-home-band--forest + .jv-home-band,
.jv-home-band + .jv-home-band--forest {
	border-top: none;
}

.jv-section {
	margin-bottom: 0;
}

.jv-section__title {
	font-family: var(--jv-font-sans);
	font-size: 34px;
	font-weight: 600;
	letter-spacing: -0.01em;
	text-align: center;
	margin-bottom: 48px;
}

.jv-category-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
}

.jv-category-tile {
	position: relative;
	display: block;
	aspect-ratio: 4 / 3;
	text-decoration: none;
	color: #ffffff;
	overflow: hidden;
	border-radius: var(--jv-radius-card);
	isolation: isolate;
}

.jv-category-tile__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-color: var(--jv-color-forest);
	border-radius: var(--jv-radius-card);
	transition: transform .5s ease;
}

.jv-category-tile__media--empty {
	display: flex;
	align-items: center;
	justify-content: center;
}

.jv-category-tile__media--empty .jv-icon {
	width: auto;
	height: 40px;
	color: rgba(255, 255, 255, .6);
}

.jv-category-tile__overlay {
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(31, 42, 32, 0) 40%, rgba(24, 32, 24, .82) 100%);
	transition: background .3s ease;
}

.jv-category-tile__name {
	position: absolute;
	left: 20px;
	right: 20px;
	bottom: 18px;
	font-weight: 600;
	font-size: 18px;
	line-height: 1.3;
	letter-spacing: normal;
}

.jv-category-tile:hover .jv-category-tile__media {
	transform: scale(1.06);
}

.jv-category-tile:hover .jv-category-tile__overlay {
	background: linear-gradient(180deg, rgba(31, 42, 32, .1) 30%, rgba(20, 28, 20, .88) 100%);
}

/* =========================================================================
   Home — carrusel horizontal de subcategorías (patrón growindustry.es):
   fila deslizable de tiles con foto de fondo + nombre superpuesto, para
   navegar directo a la subcategoría concreta en vez de solo a la categoría
   raíz. Se añade junto al grid de "Compra por categoría" existente, no lo
   sustituye.
   ========================================================================= */

.jv-subcategory-rail {
	margin-top: 56px;
}

.jv-subcategory-rail__scroller {
	display: flex;
	gap: 20px;
	overflow-x: auto;
	padding-bottom: 8px;
	scroll-snap-type: x proximity;
	-webkit-overflow-scrolling: touch;
	scrollbar-width: thin;
}

.jv-subcategory-rail__scroller::-webkit-scrollbar {
	height: 6px;
}

.jv-subcategory-rail__scroller::-webkit-scrollbar-thumb {
	background: var(--jv-color-border);
	border-radius: var(--jv-radius-pill);
}

.jv-subcategory-rail__item {
	position: relative;
	flex: 0 0 auto;
	width: 220px;
	aspect-ratio: 4 / 3;
	scroll-snap-align: start;
	display: block;
	text-decoration: none;
	color: #ffffff;
	overflow: hidden;
	border-radius: var(--jv-radius-card);
	isolation: isolate;
}

.jv-subcategory-rail__media {
	position: absolute;
	inset: 0;
	background-size: cover;
	background-position: center;
	background-color: var(--jv-color-forest);
	border-radius: var(--jv-radius-card);
	transition: transform .5s ease;
}

.jv-subcategory-rail__item::after {
	content: '';
	position: absolute;
	inset: 0;
	background: linear-gradient(180deg, rgba(31, 42, 32, 0) 45%, rgba(24, 32, 24, .82) 100%);
	transition: background .3s ease;
}

.jv-subcategory-rail__name {
	position: absolute;
	left: 16px;
	right: 16px;
	bottom: 14px;
	z-index: 1;
	font-weight: 600;
	font-size: 15px;
	line-height: 1.3;
}

.jv-subcategory-rail__item:hover .jv-subcategory-rail__media {
	transform: scale(1.06);
}

@media (max-width: 600px) {
	.jv-subcategory-rail__item {
		width: 160px;
	}
}

.jv-service-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
}

.jv-service-card {
	text-align: center;
	padding: 48px 32px;
	background: var(--jv-color-surface);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-card);
}

.jv-service-card__icon {
	width: auto;
	height: 36px;
	color: var(--jv-color-forest);
	margin-bottom: 16px;
}

.jv-service-card h3 {
	font-size: 18px;
	font-weight: 600;
	margin-bottom: 12px;
}

.jv-service-card p {
	line-height: 1.6;
}

.jv-service-grid--six {
	grid-template-columns: repeat(3, 1fr);
}

.jv-service-card--photo {
	display: block;
	text-align: left;
	padding: 0;
	overflow: hidden;
	text-decoration: none;
	color: inherit;
}

.jv-service-card--photo .jv-service-card__media {
	display: block;
	height: 160px;
	background-size: cover;
	background-position: center;
}

.jv-service-card--photo .jv-service-card__body {
	display: block;
	padding: 20px 24px 24px;
}

.jv-service-card--photo h3 {
	font-size: 17px;
	margin-bottom: 8px;
}

.jv-service-card__excerpt {
	display: block;
	margin-bottom: 14px;
	color: var(--jv-color-price-muted);
	font-size: 14px;
	line-height: 1.55;
}

.jv-home-band--forest .jv-service-card__excerpt {
	color: rgba(255, 255, 255, .76);
}

.jv-services__intro {
	max-width: 640px;
	margin: 0 auto 32px;
	text-align: center;
	color: var(--jv-color-price-muted);
}

.jv-home-band--forest .jv-services__intro {
	color: rgba(255, 255, 255, .8);
}

.jv-services__cta {
	display: inline-block;
	margin-top: 32px;
}

@media (max-width: 900px) {
	.jv-service-grid--six {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 600px) {
	.jv-service-grid--six {
		grid-template-columns: 1fr;
	}
}

.jv-link-cta {
	display: inline-block;
	margin-top: 12px;
	text-decoration: underline;
	color: var(--jv-color-ink);
}

.jv-trust-band {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
	text-align: center;
	padding: 48px 0;
	border-top: var(--jv-border-control);
	border-bottom: var(--jv-border-control);
}

.jv-trust-item {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 8px;
	font-size: var(--jv-text-body);
}

.jv-trust-item .jv-icon {
	color: var(--jv-color-forest);
}

/* "Por qué elegirnos" — tarjetas más desarrolladas que el antiguo trust-band
   (4 iconos en fila sin texto): ahora cada motivo tiene título + explicación. */
.jv-why-grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
}

.jv-why-card {
	padding: 32px 24px;
	background: var(--jv-color-canvas);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-card);
}

.jv-why-card__icon {
	width: auto;
	height: 32px;
	color: var(--jv-color-forest);
	margin-bottom: 16px;
}

.jv-why-card h3 {
	font-size: 16px;
	font-weight: 600;
	margin: 0 0 8px;
	line-height: 1.3;
}

.jv-why-card p {
	font-size: 13.5px;
	line-height: 1.6;
	color: var(--jv-color-price-muted);
	margin: 0;
}

/* Marcas destacadas — nombres reales de la taxonomía product_brand */
.jv-brands__intro {
	text-align: center;
	max-width: 620px;
	margin: -24px auto 40px;
	color: var(--jv-color-price-muted);
	line-height: 1.6;
}

.jv-brand-grid {
	display: grid;
	grid-template-columns: repeat(5, 1fr);
	gap: 16px;
}

.jv-brand-tile {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 4px;
	text-align: center;
	padding: 24px 12px;
	background: var(--jv-color-surface);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-card);
	text-decoration: none;
	transition: border-color .2s ease, transform .2s ease;
}

.jv-brand-tile:hover {
	border-color: var(--jv-color-forest);
	transform: translateY(-2px);
}

.jv-brand-tile__name {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 15px;
	color: var(--jv-color-ink);
}

.jv-brand-tile__count {
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

/* Tarjetas con logo real: fondo oscuro fijo en vez del crema por defecto,
   porque varios logos de fabricante descargados son en blanco (pensados
   para fondos oscuros) y sobre --jv-color-surface serían invisibles. Un
   fondo consistente entre todas también da orden visual a la fila, ya que
   los logos llegan en proporciones y estilos muy distintos entre sí. */
.jv-brand-tile--logo {
	background: var(--jv-color-ink);
	padding: 20px 16px;
}

.jv-brand-tile--logo:hover {
	border-color: var(--jv-color-forest);
}

.jv-brand-tile__logo {
	max-width: 100%;
	max-height: 40px;
	width: auto;
	height: auto;
	object-fit: contain;
}

.jv-brand-tile--logo .jv-brand-tile__count {
	color: rgba(255, 255, 255, 0.65);
}

/* ===== Índice de marcas por categoría (/product-category/{cat}/marca/) ===== */

.jv-brand-index {
	padding: 32px 0 64px;
}

.jv-brand-index__title {
	font-family: var(--jv-font-sans);
	font-size: 32px;
	font-weight: 600;
	color: var(--jv-color-ink);
	margin: 16px 0 8px;
}

.jv-brand-index__intro {
	color: var(--jv-color-price-muted);
	margin: 0 0 32px;
}

.jv-brand-index__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 16px;
}

/* min-height + 2 líneas fijas en el nombre (clamp) — sin esto, una marca
   con nombre largo ("MASTER PRODUCTS") ocupaba 2 líneas y estiraba TODA su
   fila de grid a esa altura (align-items:stretch por defecto), mientras las
   marcas de nombre corto de la misma fila se quedaban con hueco vacío de
   sobra — la fila siguiente, con nombres todos cortos, volvía a ser más
   baja: un patrón irregular de alturas fila a fila. Con una altura mínima
   igual en todas las tarjetas y el nombre siempre limitado a 2 líneas
   (trunca con … si no cabe), todas las tarjetas del índice miden lo mismo
   sin importar cuántas marcas tengan nombre largo. */
.jv-brand-index__card {
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: 4px;
	min-height: 96px;
	padding: 20px;
	background: var(--jv-color-surface);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-card);
	text-decoration: none;
	transition: border-color .2s ease, transform .2s ease;
	box-sizing: border-box;
}

.jv-brand-index__card:hover {
	border-color: var(--jv-color-forest);
	transform: translateY(-2px);
}

.jv-brand-index__card-name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 16px;
	line-height: 1.3;
	color: var(--jv-color-ink);
}

.jv-brand-index__card-count {
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

@media (max-width: 900px) {
	.jv-brand-index__grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 500px) {
	.jv-brand-index__grid {
		grid-template-columns: 1fr;
	}
}

@media (max-width: 900px) {
	.jv-why-grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.jv-brand-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* Dos columnas dejan de caber antes de lo que parece: `1fr` es minmax(AUTO,1fr)
   y ese `auto` es el min-content del hijo, asi que la columna NO baja de ahi.
   Las tarjetas de "Por que elegirnos" tienen 48px de padding propio y no
   bajaban de 162.8px cada una: a 360px de pantalla pedian 350 donde habia 283 y
   se salian de la pagina. Una sola columna por debajo de 480. */
@media (max-width: 480px) {
	.jv-why-grid,
	.jv-brand-grid {
		grid-template-columns: 1fr;
	}
}

.jv-blog-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
	margin-bottom: 16px;
}

.jv-blog-card {
	text-decoration: none;
	color: var(--jv-color-ink);
	display: flex;
	flex-direction: column;
}

.jv-blog-card img {
	width: 100%;
	aspect-ratio: 4 / 3;
	object-fit: cover;
	border-radius: var(--jv-radius-card);
	margin-bottom: 12px;
}

.jv-blog-card__title {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 24px;
	line-height: 1.25;
	margin-bottom: 10px;
}

.jv-blog-card__excerpt {
	font-size: var(--jv-text-body);
	line-height: 1.6;
	color: var(--jv-color-price-muted);
}

@media (max-width: 900px) {
	.jv-category-grid,
	.jv-service-grid,
	.jv-trust-band,
	.jv-blog-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* ===== Footer ===== */

.jv-footer-main {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
	padding: 24px 0;
}

/* Franja de contacto — verde claro a sangre, igual que la franja verde oscuro
   de logistica justo encima (mismo recurso: 100vw con margen negativo). Por
   dentro repite la caja de .col-full, el contenedor del pie: 92% con 24px de
   padding. MEDIDO identico a 1920/1570/1280/1024, asi que sus cuatro columnas
   caen a plomo sobre las tres de enlaces de abajo. */
.jv-footer-contacto {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	background: var(--jv-color-mint);
	padding: 21px 0;
}

/* align-items centra cada dato contra el alto de la franja: en movil una
   columna puede ocupar dos lineas y otra una, y sin esto se irian arriba. */
.jv-footer-contacto__inner {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	align-items: center;
	gap: 24px;
	max-width: var(--jv-container-max);
	margin: 0 auto;
	padding: 0 var(--jv-container-pad);
	box-sizing: border-box;
}

/* Y aqui el otro eje: el icono, centrado contra SUS dos lineas. Antes iba
   pegado arriba porque la rejilla de la columna lo clavaba en la fila 1. */
.jv-footer-contacto__item {
	display: flex;
	align-items: center;
	gap: 10px;
}

/* Caja fija de 20x20 y no `width:auto`: el viewBox de 'location' es 384x512 y
   el de los otros tres 512x512, asi que con ancho automatico el pin salia de
   15px y corria su texto 5px a la izquierda, descuadrandolo del titulo de
   abajo (los 30px de sangria de .jv-footer-column son fijos). No deforma:
   preserveAspectRatio vale `xMidYMid meet` por defecto, o sea que el icono se
   escala entero y se centra dentro de la caja. */
.jv-footer-contacto__icon {
	width: 20px;
	height: 20px;
	flex-shrink: 0;
	color: var(--jv-color-forest);
}

.jv-footer-contacto__item strong {
	display: block;
	font-size: 13px;
	font-weight: 600;
	margin-bottom: 1px;
}

/* MEDIDO sobre el verde claro #a7d4b9: el gris verdoso de antes (#3f785f) da
   3,14:1 y esto es texto de 12px, o sea normal y no grande — AA pide 4,5. El
   verde de marca da 5,30:1. La jerarquia entre las dos lineas la marcan el
   cuerpo y el peso, no el tono. */
.jv-footer-contacto__item span,
.jv-footer-contacto__item a {
	display: block;
	font-size: 12px;
	font-weight: 300;
	color: var(--jv-color-forest);
	text-decoration: none;
}

.jv-footer-contacto__item a:hover {
	text-decoration: underline;
}

/* Ya no es rejilla: el icono y el dato se fueron arriba. Los 30px que ocupaban
   (20 del icono + 10 del hueco) se quedan como sangria para que cada titulo
   siga cayendo a plomo con el texto de su contacto. */
.jv-footer-column {
	padding-left: 30px;
}

/* Sin margen de arriba: el titulo ya es lo primero de su columna y el aire lo
   pone el padding de .jv-footer-main. */
.jv-footer-col__heading {
	color: var(--jv-color-forest) !important;
	font-size: 13px;
	font-weight: 600;
	margin: 0 0 10px;
}

.jv-footer-col__list {
	list-style: none;
	margin: 0;
	padding: 0;
}

.jv-footer-col__list li {
	margin-bottom: 5px;
}

.jv-footer-col__list a {
	color: var(--jv-color-ink);
	opacity: 0.75;
	text-decoration: none;
	font-size: 12.5px;
}

.jv-footer-col__list a:hover {
	opacity: 1;
	color: var(--jv-color-forest);
	text-decoration: underline;
}

/* Los simbolos en fila. La sangria la pone .jv-footer-column (30px), asi que
   arrancan a plomo con los enlaces de las columnas de al lado. */
.jv-footer-social {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: 14px;
	list-style: none;
	margin: 0;
	padding: 0;
}

.jv-footer-social li {
	margin: 0;
	line-height: 0;
}

.jv-footer-social__icon {
	width: 18px;
	height: 18px;
	color: var(--jv-color-forest);
}

/* Realce solo cuando de verdad hay a donde ir: mientras no haya cuentas el
   icono es un <span> y no reacciona al raton, que es lo que toca. */
.jv-footer-social a:hover .jv-footer-social__icon {
	opacity: 0.7;
}

@media (max-width: 900px) {
	.jv-footer-contacto__inner,
	.jv-footer-main {
		grid-template-columns: repeat(2, 1fr);
		gap: 16px;
	}

	.jv-footer-main {
		padding: 20px 0;
	}
}

@media (max-width: 560px) {
	.jv-footer-contacto__inner,
	.jv-footer-main {
		grid-template-columns: 1fr;
	}
}

/* Barra inferior: copyright, legal y ROPO unificados */
.jv-footer-bottom {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 10px;
	padding: 14px 0;
	font-size: 11.5px;
	color: var(--jv-color-price-muted);
}

.jv-footer-bottom__legal {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 8px;
}

.jv-footer-bottom__legal .jv-icon {
	width: auto;
	height: 14px;
	color: var(--jv-color-forest);
	flex-shrink: 0;
}

.jv-footer-bottom__legal a {
	color: var(--jv-color-ink);
	opacity: 0.75;
	text-decoration: none;
}

.jv-footer-bottom__legal a:hover {
	opacity: 1;
	text-decoration: underline;
}

.jv-footer-bottom__sep {
	opacity: 0.5;
}

@media (max-width: 700px) {
	.jv-footer-bottom {
		flex-direction: column;
		align-items: flex-start;
		gap: 8px;
	}
}

/* Legacy: bloque de registro oficial separado, ya no se usa */
.jv-footer-official {
	display: none;
}

/* ===== 404 ===== */

.jv-404 {
	max-width: 480px;
	margin: 96px auto;
	text-align: center;
	padding: 0 24px;
}

.jv-404__icon {
	width: auto;
	height: 48px;
	color: var(--jv-color-forest);
	margin-bottom: 16px;
}

.jv-404 h1 {
	font-size: 32px;
	margin-bottom: 8px;
}

.jv-404 p {
	color: var(--jv-color-price-muted);
	margin-bottom: 24px;
}

.jv-404__search {
	display: flex;
	gap: 8px;
	margin-bottom: 24px;
}

.jv-404__search input[type="search"] {
	flex: 1;
}

/* ===== Category Hero Editorial Block (PLP) ===== */

.jv-category-hero {
	position: relative;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	min-height: 340px;
	display: flex;
	align-items: flex-end;
	background-color: var(--jv-color-forest);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
	margin-bottom: 48px;
}

.jv-category-hero--image .jv-category-hero__overlay {
	background: linear-gradient(180deg, rgba(15, 86, 55, .1) 0%, rgba(35, 28, 24, .8) 100%);
}

.jv-category-hero__overlay {
	width: 100%;
	padding: 64px 0 40px;
}

/* Sin intro (solo título, ver jv_render_category_hero() en
   inc/category-hero.php) — min-height y padding más generosos, pensados
   para acomodar título + párrafo, dejaban un bloque mucho más alto de lo
   necesario con solo una línea de texto dentro, con aire de sobra tanto
   por encima como por debajo del H1. */
.jv-category-hero--no-intro {
	min-height: 200px;
}

.jv-category-hero--no-intro .jv-category-hero__overlay {
	padding: 32px 0;
}

.jv-category-hero--no-intro .jv-category-hero__title {
	margin-bottom: 0;
}

/* .jv-category-hero__inner usa .jv-container (mismo ancho que el resto de la
   página) en vez de declarar su propio max-width/padding duplicado.
   text-align:center — el hero es full-bleed (ancho de viewport completo) y
   sin esto el título/intro se quedaban alineados al borde izquierdo del
   contenedor de 1280px, que en pantallas anchas queda visualmente "pegado
   a la izquierda" en vez de centrado en el banner. */
.jv-category-hero__inner {
	width: 100%;
	text-align: center;
}

.jv-category-hero__title {
	color: #ffffff;
	font-weight: 600;
	letter-spacing: -0.01em;
	margin: 0 0 12px;
}

.jv-category-hero__intro {
	max-width: 680px;
	margin: 0 auto;
	font-size: 16.8px;
	font-weight: 300;
	line-height: 1.6;
	color: #ffffff;
}

.jv-category-hero__intro p {
	margin: 0 0 8px;
}

/* Breadcrumb propio de la vista categoría×marca (sin equivalente de término
   real, ver jv_render_category_brand_breadcrumb() en inc/category-hero.php). */
.jv-category-hero__breadcrumb {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 12px;
	font-size: var(--jv-text-body-sm, 13.6px);
	color: rgba(255, 255, 255, .85);
}

.jv-category-hero__breadcrumb a {
	color: rgba(255, 255, 255, .85);
	text-decoration: none;
}

.jv-category-hero__breadcrumb a:hover {
	color: #ffffff;
	text-decoration: underline;
}

.jv-category-hero__breadcrumb .jv-icon {
	width: auto;
	height: 14px;
	opacity: .7;
}

/* ===== Fila de tarjetas de subcategoría (estilo espejoled — antes del grid de productos) ===== */

.jv-subcat-row {
	padding: 32px var(--jv-container-pad) 8px;
}

.jv-subcat-row__title {
	margin: 0 0 16px;
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

.jv-subcat-row__wrap {
	position: relative;
}

/* justify-content:safe center — centra las tarjetas cuando caben todas en
   una fila sin necesitar scroll (el caso más habitual, categorías con 4-6
   subcategorías), pero el prefijo "safe" evita que el centrado recorte el
   principio del contenido si en algún caso hay más tarjetas de las que
   caben y sí hace falta scroll horizontal real. */
.jv-subcat-row__track {
	display: flex;
	justify-content: safe center;
	gap: 16px;
	overflow-x: auto;
	padding-bottom: 8px;
	scroll-snap-type: x proximity;
	-webkit-overflow-scrolling: touch;
}

.jv-subcat-row__track::-webkit-scrollbar {
	height: 6px;
}

.jv-subcat-row__track::-webkit-scrollbar-thumb {
	background: var(--jv-color-border);
	border-radius: var(--jv-radius-pill);
}

/* Flecha "hay más" — solo visible cuando el JS detecta desborde real (ver
   jv_subcat_row_arrow_script(), inc/category-hero.php); [hidden] la quita
   del todo tanto visual como de la interacción, no solo con opacity. */
.jv-subcat-row__arrow {
	position: absolute;
	top: 50%;
	right: 8px;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 40px;
	height: 40px;
	border-radius: 50%;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	box-shadow: none;
	color: var(--jv-color-ink);
	cursor: pointer;
}

.jv-subcat-row__arrow:hover {
	background: var(--jv-color-canvas);
}

.jv-subcat-row__arrow[hidden] {
	display: none;
}

.jv-subcat-row__arrow .jv-icon {
	width: auto;
	height: 20px;
}

.jv-subcat-card {
	position: relative;
	flex: 0 0 200px;
	height: 260px;
	border-radius: var(--jv-radius-card);
	background-color: var(--jv-color-forest);
	background-size: cover;
	background-repeat: no-repeat;
	background-position: center;
	overflow: hidden;
	scroll-snap-align: start;
	text-decoration: none;
	transition: transform 0.2s ease;
}

.jv-subcat-card:hover {
	transform: translateY(-4px);
}

/* Fila "Categorías destacadas" de Fabricantes: cada tarjeta es un logo de
   marca (texto ancho), no una foto — background-size:cover (por defecto,
   arriba) recorta el texto contra el marco fijo de 200x260px. contain +
   fondo oscuro fijo muestra el logo completo, mismo patrón que
   .jv-brand-tile--logo en la home. */
.jv-subcat-card--brand {
	background-color: var(--jv-color-ink);
	background-size: contain;
	padding: 24px;
	background-origin: content-box;
}

.jv-subcat-card--brand .jv-subcat-card__overlay {
	background: linear-gradient(180deg, rgba(0, 0, 0, 0) 60%, rgba(0, 0, 0, 0.7) 100%);
}

.jv-subcat-card__overlay {
	position: absolute;
	inset: 0;
	display: flex;
	align-items: flex-end;
	padding: 18px;
	background: linear-gradient(180deg, rgba(0, 0, 0, 0) 40%, rgba(0, 0, 0, 0.55) 100%);
}

.jv-subcat-card__name {
	color: #ffffff;
	font-family: var(--jv-font-sans);
	font-size: 17px;
	font-weight: 600;
	line-height: 1.25;
}

@media (max-width: 700px) {
	.jv-subcat-card {
		flex-basis: 160px;
		height: 210px;
	}
}

@media (max-width: 700px) {
	.jv-category-hero {
		min-height: 240px;
	}

	.jv-category-hero__title {
		font-size: 32px;
	}
}

/* ===== Ficha técnica (PDP) — chips clave→valor ===== */
/* .jv-technical-table ya no se usa (sustituida por .jv-chip-grid, ver
   inc/product-tabs.php), se conserva la regla por si queda contenido legacy
   en caché de plantillas, pero no debería pintarse ya en ningún sitio. */

.jv-technical-table {
	width: 100%;
	border-collapse: collapse;
	margin-bottom: 32px;
}

.jv-technical-table tr {
	border-bottom: var(--jv-border-control);
}

.jv-technical-table th,
.jv-technical-table td {
	text-align: left;
	padding: 12px 16px 12px 0;
	font-size: var(--jv-text-body);
	font-weight: 300;
	vertical-align: top;
}

.jv-technical-table th {
	width: 240px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

.jv-technical-table td {
	color: var(--jv-color-price-muted);
}

.jv-chip-grid {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
	gap: 12px;
	margin: 0 0 32px;
}

.jv-chip {
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	padding: 14px 16px;
	display: flex;
	flex-direction: column;
	gap: 4px;
}

.jv-chip__label {
	font-size: 12px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .04em;
	color: var(--jv-color-forest);
}

.jv-chip__value {
	font-size: var(--jv-text-body);
	font-weight: 600;
	color: var(--jv-color-ink);
	line-height: 1.4;
}

.jv-document-block {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 24px;
}

.jv-technical-subheading {
	font-family: var(--jv-font-sans);
	font-size: 16px;
	font-weight: 600;
	margin: 0 0 12px;
	display: flex;
	align-items: center;
	gap: 8px;
	color: var(--jv-color-ink);
}

.jv-document-block .jv-technical-subheading:not(:first-child) {
	margin-top: 24px;
}

.jv-technical-subheading__icon {
	width: auto;
	height: 18px;
	color: var(--jv-color-forest);
}

.jv-document-list {
	list-style: none;
	margin: 0 0 8px;
	padding: 0;
}

.jv-document-list li {
	border-bottom: 1px solid var(--jv-color-border);
}

.jv-document-list li:last-child {
	border-bottom: none;
}

.jv-document-list a {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 12px 4px;
	color: var(--jv-color-ink);
	font-size: var(--jv-text-body);
	font-weight: 600;
	border-radius: var(--jv-radius-control);
	transition: background-color .15s ease, color .15s ease;
}

.jv-document-list a:hover {
	background: var(--jv-color-canvas);
	color: var(--jv-color-forest);
	text-decoration: underline;
}

.jv-document-list .jv-icon {
	width: auto;
	height: 18px;
	color: var(--jv-color-forest);
	flex-shrink: 0;
}

@media (max-width: 600px) {
	.jv-chip-grid {
		grid-template-columns: 1fr 1fr;
	}
}

@media (max-width: 420px) {
	.jv-chip-grid {
		grid-template-columns: 1fr;
	}
}

/* ===== Vídeo de producto (PDP) ===== */

.jv-video-grid {
	display: grid;
	gap: 20px;
}

.jv-video-embed {
	position: relative;
	width: 100%;
	padding-top: 56.25%;
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	background: var(--jv-color-ink);
}

.jv-video-embed iframe {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	border: 0;
}

/* ===== Sidebar de filtros — acordeón + checkboxes ===== */

.jv-plp-sidebar__title {
	font-family: var(--jv-font-sans);
	font-size: 20px;
	font-weight: 600;
	margin: 0 0 16px;
}

.jv-filter-section__toggle {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	background: none;
	border: none;
	border-bottom: var(--jv-border-control);
	padding: 0 0 10px;
	margin-bottom: 12px;
	font-family: var(--jv-font-sans);
	font-size: var(--jv-text-filter-heading);
	font-weight: 600;
	color: var(--jv-color-ink);
	cursor: pointer;
}

.jv-filter-section__toggle .jv-icon {
	width: auto;
	height: 16px;
	transition: transform 0.15s ease;
}

.jv-filter-section__toggle[aria-expanded="false"] .jv-icon {
	transform: rotate(-90deg);
}

.jv-filter-checkbox {
	display: flex;
	align-items: center;
	gap: 10px;
	padding: 7px 4px;
	cursor: pointer;
	font-size: var(--jv-text-body);
	color: var(--jv-color-ink);
}

.jv-filter-checkbox input[type="checkbox"] {
	width: 16px;
	height: 16px;
	accent-color: var(--jv-color-forest);
	border-radius: 0;
	flex-shrink: 0;
}

.jv-filter-checkbox span:first-of-type {
	flex: 1;
}

/* ===== Toolbar PLP — contador + toggle vista ===== */

/* Una sola fila para conteo + orden + toggle de vista — antes convivían TRES
   piezas del mismo conteo/controles en líneas separadas: esta toolbar
   ("55 productos" + vista), el "Mostrando 1-48 de 55 resultados" nativo de
   WooCommerce (mismo dato que "55 productos", repetido) y el selector
   "Orden predeterminado" suelto en su propia fila. jv_render_plp_toolbar()
   (inc/category-filters.php) ya quita el hook nativo del conteo y llama a
   mano a woocommerce_catalog_ordering() dentro de .jv-plp-toolbar__right,
   junto al toggle de vista, así que aquí solo hace falta el layout de una
   fila con el conteo a la izquierda y el resto agrupado a la derecha. */
.jv-plp-toolbar {
	display: flex;
	align-items: center;
	justify-content: space-between;
	flex-wrap: wrap;
	gap: 12px;
	margin-bottom: 20px;
	padding-bottom: 16px;
	border-bottom: 1px solid var(--jv-color-border);
}

.jv-plp-toolbar__count {
	font-size: var(--jv-text-body);
	color: var(--jv-color-price-muted);
}

.jv-plp-toolbar__right {
	display: flex;
	align-items: center;
	gap: 12px;
}

.jv-plp-toolbar__sorting .woocommerce-ordering {
	margin: 0;
}

.jv-plp-toolbar__sorting .orderby {
	font-family: var(--jv-font-sans);
	font-size: 13.5px;
	color: var(--jv-color-ink);
	background: var(--jv-color-surface);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-control);
	padding: 8px 32px 8px 12px;
	cursor: pointer;
}

@media (max-width: 700px) {
	.jv-plp-toolbar {
		flex-direction: column;
		/* Mismo caso que .jv-plp-layout, ver ahi el porque. */
		align-items: stretch;
	}

	.jv-plp-toolbar__right {
		width: 100%;
		justify-content: space-between;
		/* El <select> de ordenacion y el conmutador de vista no caben juntos en
		   una pantalla de movil: sin esto se salian 62px. */
		flex-wrap: wrap;
	}

	.jv-plp-toolbar__sorting,
	.jv-plp-toolbar__sorting .woocommerce-ordering {
		min-width: 0;
	}

	.jv-plp-toolbar__sorting .orderby {
		max-width: 100%;
	}
}

.jv-view-toggle {
	display: flex;
	gap: 4px;
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-pill);
	padding: 4px;
	background: var(--jv-color-surface);
}

.jv-view-toggle__btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 32px;
	border: none;
	border-radius: var(--jv-radius-pill);
	background: none;
	color: var(--jv-color-price-muted);
	cursor: pointer;
}

.jv-view-toggle__btn .jv-icon {
	width: auto;
	height: 16px;
}

.jv-view-toggle__btn.is-active {
	background: var(--jv-color-forest);
	color: #ffffff;
}

/* Vista lista: cada producto a ancho completo, imagen a la izquierda */
.jv-plp-main ul.products.jv-view-list {
	grid-template-columns: 1fr !important;
}

.jv-plp-main ul.products.jv-view-list li.product {
	display: flex !important;
	align-items: center;
	gap: 24px;
	border-bottom: var(--jv-border-control);
	padding-bottom: 20px;
}

.jv-plp-main ul.products.jv-view-list li.product img {
	width: 160px;
	height: 160px;
	object-fit: cover;
	flex-shrink: 0;
}

/* ===== Selector de variantes — botones tipo Amazon (no dropdown) ===== */

.jv-visually-hidden {
	position: absolute;
	width: 1px;
	height: 1px;
	overflow: hidden;
	clip: rect(0 0 0 0);
	white-space: nowrap;
}

.jv-variation-buttons {
	display: flex;
	flex-wrap: wrap;
	gap: 10px;
	margin: 8px 0 4px;
}

/* El <form class="cart"> nativo trae 2em de margin-bottom por defecto de
   WooCommerce (pensado para cuando el botón de compra vive justo dentro),
   pero aquí el botón se traslada al buybox (ver inc/pdp-layout.php) y solo
   queda la tabla de variantes — ese margen de sobra, sumado al de la ficha
   técnica y la meta justo debajo, dejaba demasiado aire antes de llegar a
   "Descripción". */
.single-product div.product .summary form.cart {
	margin-bottom: 4px;
}

/* Cada botón muestra formato + precio de esa variante concreta apilados
   (nombre arriba, precio abajo), como en el selector "Nombre de estilo" de
   Amazon — antes solo mostraba el nombre del formato, sin dar ninguna pista
   de precio hasta seleccionarlo. */
.jv-variation-btn {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 4px;
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-control);
	background: var(--jv-color-surface);
	color: var(--jv-color-ink);
	font-family: var(--jv-font-sans);
	font-size: var(--jv-text-body);
	font-weight: 600;
	padding: 10px 16px;
	cursor: pointer;
}

.jv-variation-btn__label {
	font-weight: 600;
	max-width: 220px;
	white-space: normal;
	overflow-wrap: anywhere;
}

.jv-variation-btn__price {
	font-size: 12.5px;
	font-weight: 300;
	color: var(--jv-color-price-muted);
}

.jv-variation-btn__price ins {
	text-decoration: none;
	color: inherit;
}

.jv-variation-btn__price del {
	opacity: .8;
	margin-right: 3px;
}

/* Comparativas editoriales: la tabla conserva columnas legibles y se
   desplaza dentro del bloque, sin ensanchar toda la PDP en móvil. */
.jv-table-scroll {
	display: block;
	max-width: 100%;
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
}

.jv-table-scroll table {
	min-width: 620px;
	margin-bottom: 0;
}

.jv-variation-btn:hover {
	border-color: var(--jv-color-selected);
}

/* Estilo Amazon: la variante seleccionada NO se rellena de color, se queda
   en blanco con un borde de color redondeado (Amazon usa azul, aquí nuestro
   verde) — antes se rellenaba entera de verde, lo que quedaba más pesado
   visualmente que el patrón de referencia. */
.jv-variation-btn.is-selected {
	border: 2px solid var(--jv-color-selected);
	border-radius: var(--jv-radius-control);
	background: var(--jv-color-surface);
	color: var(--jv-color-ink);
	padding: 9px 15px;
}

.jv-variation-btn.is-selected .jv-variation-btn__price {
	color: var(--jv-color-price-muted);
}

.jv-variation-btn:disabled {
	background: var(--jv-color-disabled-bg);
	color: var(--jv-color-disabled-text);
	border-color: var(--jv-color-disabled-bg);
	cursor: not-allowed;
}

/* ===== Bloque SEO + FAQs de categoría ===== */

.jv-category-seo {
	max-width: 760px;
	margin: 48px 0 0;
	padding-top: 40px;
	border-top: var(--jv-border-control);
}

.jv-category-seo__text {
	font-size: 16px;
	line-height: 1.7;
	color: var(--jv-color-ink);
	margin: 0 0 28px;
}

.jv-category-seo__text--extended {
	color: var(--jv-color-price-muted);
}

.jv-category-benefits {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 14px;
	margin: 0 0 40px;
}

.jv-benefit-card {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 8px;
	padding: 18px 16px;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
}

.jv-benefit-card .jv-icon {
	width: auto;
	height: 26px;
	color: var(--jv-color-forest);
}

.jv-benefit-card__title {
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

.jv-benefit-card__text {
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--jv-color-price-muted);
	margin: 0;
}

@media (max-width: 900px) {
	.jv-category-benefits {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 560px) {
	.jv-category-benefits {
		grid-template-columns: 1fr;
	}
}

.jv-category-seo__list {
	list-style: none;
	margin: 0 0 40px;
	padding: 0;
}

.jv-category-seo__list li {
	display: flex;
	align-items: baseline;
	gap: 10px;
	padding: 10px 0;
	border-bottom: 1px solid var(--jv-color-border);
	font-size: var(--jv-text-body);
}

.jv-category-seo__list .jv-icon {
	width: auto;
	height: 14px;
	color: var(--jv-color-forest);
	flex-shrink: 0;
}

.jv-category-seo__list a {
	color: var(--jv-color-ink);
	text-decoration: none;
}

.jv-category-seo__list a:hover {
	color: var(--jv-color-forest);
}

.jv-category-seo__list span {
	color: var(--jv-color-price-muted);
}

.jv-category-faqs__title {
	font-family: var(--jv-font-sans);
	font-size: 24px;
	font-weight: 600;
	margin: 0 0 16px;
}

.jv-faq-item {
	border-bottom: var(--jv-border-control);
}

.jv-faq-item__question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	width: 100%;
	background: none;
	border: none;
	padding: 16px 0;
	font-family: var(--jv-font-sans);
	font-size: var(--jv-text-body);
	font-weight: 600;
	color: var(--jv-color-ink);
	text-align: left;
	cursor: pointer;
}

.jv-faq-item__question .jv-icon {
	width: auto;
	height: 18px;
	flex-shrink: 0;
	transition: transform 0.15s ease;
}

.jv-faq-item.is-open .jv-faq-item__question .jv-icon {
	transform: rotate(180deg);
}

.jv-faq-item__answer {
	display: none;
	padding: 0 0 16px;
}

.jv-faq-item.is-open .jv-faq-item__answer {
	display: block;
}

.jv-faq-item__answer p {
	font-size: var(--jv-text-body);
	line-height: 1.6;
	color: var(--jv-color-price-muted);
	margin: 0;
}

/* ===== Landing de servicio (page-servicio.php) ===== */

.jv-service-hero {
	position: relative;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	min-height: 460px;
	display: flex;
	align-items: flex-end;
	background-color: var(--jv-color-forest);
	background-size: cover;
	background-position: center;
	background-repeat: no-repeat;
}

.jv-service-hero__overlay {
	width: 100%;
	padding: 72px 0 48px;
	background: linear-gradient(180deg, rgba(31, 42, 32, .15) 0%, rgba(24, 32, 24, .85) 100%);
}

.jv-service-hero__inner {
	width: 100%;
	max-width: 760px;
}

.jv-service-hero__title {
	color: #ffffff;
	font-size: 44px;
	font-weight: 600;
	line-height: 1.15;
	letter-spacing: -0.01em;
	margin: 0 0 16px;
}

.jv-service-hero__subhead {
	color: rgba(255, 255, 255, .92);
	font-size: 17px;
	line-height: 1.6;
	max-width: 640px;
	margin: 0 0 32px;
}

/* "Dolores" — preguntas retóricas destacadas dentro del hero, no párrafo plano */
.jv-service-pains {
	display: flex;
	flex-direction: column;
	gap: 10px;
	margin: 0 0 36px;
	padding: 0;
	list-style: none;
}

.jv-service-pains li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	color: #ffffff;
	font-size: 16px;
	font-weight: 600;
	line-height: 1.5;
	padding: 12px 16px;
	background: rgba(255, 255, 255, .1);
	border: 1px solid rgba(255, 255, 255, .2);
	border-radius: var(--jv-radius-card);
}

.jv-service-pains .jv-icon {
	width: auto;
	height: 18px;
	flex-shrink: 0;
	margin-top: 2px;
	color: #ffffff;
}

.jv-service-hero__cta {
	display: inline-flex;
	align-items: center;
	gap: 8px;
}

@media (max-width: 700px) {
	.jv-service-hero {
		min-height: 360px;
	}

	.jv-service-hero__overlay {
		padding: 40px 0 32px;
	}

	.jv-service-hero__title {
		font-size: 30px;
	}

	.jv-service-pains li {
		font-size: 14.5px;
	}
}

/* CTA temprano bajo el hero */
.jv-service-cta-band {
	text-align: center;
	padding: 32px 0;
	border-bottom: var(--jv-border-control);
}

.jv-service-cta-band p {
	margin: 0 0 16px;
	color: var(--jv-color-price-muted);
	font-size: 15px;
}

/* Reutiliza .jv-category-benefits / .jv-benefit-card ya definidos arriba para
   el grid de 4 beneficios de la landing de servicio (mismo lenguaje visual). */
.jv-service-benefits {
	padding: 64px 0;
}

.jv-service-benefits .jv-category-benefits {
	margin: 0;
}

/* "Cómo trabajamos" — línea de tiempo horizontal con número + título + texto */
.jv-service-process {
	padding: 64px 0;
	background: var(--jv-color-surface);
}

.jv-service-process__steps {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 24px;
	counter-reset: jv-step;
}

.jv-service-step {
	position: relative;
	padding: 24px 20px 20px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
}

.jv-service-step__number {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	width: 36px;
	height: 36px;
	border-radius: 50%;
	background: var(--jv-color-forest);
	color: #ffffff;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 15px;
	margin-bottom: 14px;
}

.jv-service-step__title {
	font-family: var(--jv-font-sans);
	font-size: 15.5px;
	font-weight: 600;
	color: var(--jv-color-ink);
	margin: 0 0 8px;
}

.jv-service-step__text {
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--jv-color-price-muted);
	margin: 0;
}

@media (max-width: 900px) {
	.jv-service-process__steps {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 560px) {
	.jv-service-process__steps {
		grid-template-columns: 1fr;
	}
}

/* Bloque de precio orientativo — pastilla destacada */
.jv-service-price {
	padding: 56px 0;
	text-align: center;
}

.jv-service-price-badge {
	display: inline-flex;
	align-items: center;
	gap: 10px;
	background: var(--jv-color-forest);
	color: #ffffff;
	border-radius: var(--jv-radius-pill);
	padding: 16px 32px;
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 19px;
	margin: 0 0 14px;
}

.jv-service-price-badge .jv-icon {
	width: auto;
	height: 20px;
}

.jv-service-price__note {
	max-width: 520px;
	margin: 0 auto;
	color: var(--jv-color-price-muted);
	font-size: 13.5px;
	line-height: 1.6;
}

/* FAQs de servicio — mismo patrón visual que jv-category-faqs, ancho de lectura limitado */
.jv-service-faqs {
	padding: 64px 0;
	background: var(--jv-color-surface);
}

.jv-service-faqs__inner {
	max-width: 760px;
	margin: 0 auto;
}

/* CTA final reforzado — banda de marca a todo el ancho */
.jv-service-cta-final {
	width: 100vw;
	margin-left: calc(50% - 50vw);
	background: var(--jv-color-forest);
	color: #ffffff;
	text-align: center;
	padding: 64px 0;
}

.jv-service-cta-final h2 {
	color: #ffffff;
	font-size: 28px;
	margin: 0 0 12px;
}

.jv-service-cta-final p {
	color: rgba(255, 255, 255, .8);
	max-width: 520px;
	margin: 0 auto 28px;
	font-size: 15px;
	line-height: 1.6;
}

/* ===== Hub /servicios/ ===== */

.jv-services-hub-intro {
	max-width: 680px;
	margin: 0 auto 48px;
	text-align: center;
	color: var(--jv-color-price-muted);
	font-size: 16px;
	line-height: 1.7;
}

.jv-services-hub-grid {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
}

.jv-service-hub-card {
	display: flex;
	flex-direction: column;
	text-decoration: none;
	color: var(--jv-color-ink);
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	transition: transform .2s ease;
}

.jv-service-hub-card:hover {
	transform: translateY(-3px);
	color: var(--jv-color-ink);
}

.jv-service-hub-card__media {
	position: relative;
	aspect-ratio: 4 / 3;
	background-size: cover;
	background-position: center;
	background-color: var(--jv-color-forest);
}

.jv-service-hub-card__media--empty {
	display: flex;
	align-items: center;
	justify-content: center;
}

.jv-service-hub-card__media--empty .jv-icon {
	width: auto;
	height: 36px;
	color: rgba(255, 255, 255, .6);
}

.jv-service-hub-card__body {
	padding: 20px;
	display: flex;
	flex-direction: column;
	flex: 1;
}

.jv-service-hub-card__title {
	font-family: var(--jv-font-sans);
	font-size: 17px;
	font-weight: 600;
	margin: 0 0 8px;
}

.jv-service-hub-card__text {
	font-size: 13.5px;
	line-height: 1.55;
	color: var(--jv-color-price-muted);
	margin: 0 0 16px;
	flex: 1;
}

.jv-service-hub-card__link {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-service-hub-card__link .jv-icon {
	width: auto;
	height: 14px;
}

@media (max-width: 900px) {
	.jv-services-hub-grid {
		grid-template-columns: repeat(2, 1fr);
	}
}

@media (max-width: 560px) {
	.jv-services-hub-grid {
		grid-template-columns: 1fr;
	}
}

/* =============================================================
   PDP — galería con más protagonismo
   La galería nativa de WooCommerce (.woocommerce-product-gallery /
   .summary) vive en columnas flotadas al 41%/53% por defecto (Storefront).
   Se reequilibra a favor de la imagen, se agranda el marco visual y se
   cuidan las miniaturas, sin tocar el JS de zoom/lightbox/slider (siguen
   siendo los de WooCommerce, activados en inc/setup.php).
   ============================================================= */

/* overflow:hidden NO va en .woocommerce-product-gallery/.images en sí — ese
   es el elemento con position:sticky (ver más abajo, dentro de
   .jv-pdp-top-grid), y un elemento sticky con overflow:hidden en su propio
   nodo rompe el sticky (deja de "engancharse" y se mueve 1:1 con el scroll
   como si fuera position:static). El redondeo de esquinas ya lo aplica
   .woocommerce-product-gallery__wrapper (el hijo directo, ver regla
   siguiente) — border-radius sin overflow:hidden en el nodo exterior no
   tiene efecto visual porque no hay nada que recortar ahí directamente. */
.single-product div.product .woocommerce-product-gallery,
.single-product div.product .images {
	border-radius: var(--jv-radius-card);
}

.single-product div.product .woocommerce-product-gallery__wrapper {
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	background: var(--jv-color-surface);
}

/* object-fit: contain (no cover) — el producto tiene que verse entero
   dentro del cuadrado, con aire de fondo alrededor si la foto original no es
   cuadrada, en vez de recortar partes de la imagen para rellenar el marco. */
.single-product div.product .woocommerce-product-gallery img {
	border-radius: var(--jv-radius-card);
	aspect-ratio: 1 / 1;
	object-fit: contain;
	width: 100%;
	background: var(--jv-color-surface);
}

/* =============================================================
   PDP — layout de 3 columnas estilo Amazon: imagen | información
   (nombre, estrellas, precio, variantes, ficha técnica, meta) | buybox
   sticky (cantidad + añadir al carrito + pastillas de confianza).
   inc/pdp-layout.php reordena los hooks nativos de woocommerce_single_product_summary
   y traslada por JS el botón de compra + trust-badges dentro de
   .jv-pdp-buybox (ver jv_pdp_buybox_script) — así el <form class="cart">
   nativo de WooCommerce (necesario para el JS de variaciones/AJAX) no se
   parte en dos columnas, solo se reordena visualmente su contenido.
   ============================================================= */
/* div.product ya NO es grid — solo apila en flujo vertical normal
   .jv-pdp-top-grid (imagen+info+buybox, ver más abajo) seguido de
   .jv-pdp-sections/related/paginación. El grid de 3 columnas vive ahora en
   .jv-pdp-top-grid, un wrapper creado por JS (ver jv_pdp_buybox_script en
   inc/pdp-layout.php) que envuelve SOLO esos 3 elementos — así su altura
   define el contenedor de scroll real de position:sticky, y el sticky de
   imagen/buybox se libera de forma nativa en cuanto se termina esa altura,
   sin llegar a .jv-pdp-sections/related (comportamiento de Amazon: la
   imagen deja de acompañar el scroll al llegar a la descripción). Antes
   div.product era el grid completo con .jv-pdp-sections/related como filas
   adicionales (grid-column:1/-1) del MISMO grid — eso hacía que el
   contenedor de scroll de sticky fuera toda esa altura combinada, dejando
   la imagen pegada durante reseñas/relacionados también. */
.jv-pdp-top-grid {
	display: grid;
	grid-template-columns: 1fr;
	grid-template-areas:
		"mobilehead"
		"gallery"
		"info"
		"buybox";
	gap: 20px;
}

/* Sin grid-area propia, un hijo de un contenedor grid con
   grid-template-areas ya definido no participa en el auto-placement de la
   forma esperada — jv_pdp_mobile_reorder_script() (inc/pdp-layout.php)
   inserta este contenedor como primer hijo de .jv-pdp-top-grid en móvil,
   pero sin esta línea no aparecía visualmente aunque estuviera bien
   colocado en el DOM (confirmado por JS: el nodo existía con el contenido
   correcto, solo no se veía). */
.jv-pdp-mobile-header {
	grid-area: mobilehead;
}

/* div.product vive dentro de #content > .col-full, que tiene su propio
   max-width:1280px (ver regla .col-full) — igual que le pasaba a
   .jv-plp-layout antes de aplicarle el mismo arreglo, quitarle el
   max-width solo a div.product no basta porque el padre ya recorta el
   ancho disponible antes de que la regla llegue. Full-bleed (100vw +
   margen negativo) salta ese límite... pero Amazon NO deja que la ficha
   ocupe el 100% del viewport en pantallas anchas: por mucho que la pantalla
   crezca, el contenido se detiene en un ancho máximo y el resto queda de
   aire a los lados, centrado (comprobado entrando en amazon.es con la
   ventana ancha). Antes esto se hacía 100vw + padding fijo de 32px, que en
   monitores grandes dejaba la ficha prácticamente pegada a los bordes de la
   ventana. auto en vez de calc(50%-50vw) centra un bloque con max-width
   propio dentro del ancho completo disponible. */
/* div.product ya vive dentro de #content > .col-full, que desde el cambio a
   --jv-container-max:96% (ver :root) YA aporta el ancho proporcional
   correcto por sí mismo — antes, con .col-full topando en un px fijo
   (1280px), esta regla necesitaba escapar ese límite a la fuerza
   (width:100vw + margin-left:calc(), luego un max-width propio para volver
   a frenar el crecimiento) para poder ser más ancha que el resto del sitio.
   Con el padre ya proporcional, no hace falta ningún layout de ancho
   propio: basta con ocupar el 100% del padre. */
/* Storefront trae ".single-product div.product{overflow:hidden}" (pensado
   para contener los floats de su layout original de 2 columnas) — un
   ancestro con overflow distinto de "visible" rompe position:sticky en
   TODOS sus descendientes (se convierte en el contenedor de scroll del
   sticky, y como div.product en sí no tiene scroll propio, el sticky no
   tiene nada a lo que "engancharse" y cae a comportarse como estático,
   moviéndose 1:1 con el scroll de la página en vez de quedarse pegado).
   Esto hacía que la imagen/buybox (.jv-pdp-top-grid, sticky) se soltaran
   del todo nada más empezar a hacer scroll, en vez de acompañar hasta el
   final de la columna central como se esperaba. */
.single-product div.product {
	overflow: visible;
}

@media (min-width: 1000px) {
	.single-product div.product {
		width: 100%;
	}
}

/* Storefront trae ".single-product div.product .images{width:41.17%;
   float:left;...}" con la MISMA especificidad (3 clases) dentro de su
   propio @media(min-width:768px) — en un empate de especificidad gana la
   regla que se carga después en el <link>, que resultó ser la de
   Storefront, dejando la columna de imagen encogida a un ancho de sobra
   pequeño (calculado sobre el 41% de su propio contenido en vez del ancho
   real de columna de grid). Se refuerza con !important, mismo patrón que
   ya se usa para el botón de compra más abajo en este archivo. */
.single-product div.product .woocommerce-product-gallery,
.single-product div.product .images {
	grid-area: gallery;
	width: 100% !important;
	float: none !important;
	margin-right: 0 !important;
}

/* Storefront trae ".summary{width:52.94%;float:right}" con la MISMA
   especificidad (1 clase) — mismo problema que ya se resolvió para
   ".images" más abajo en este archivo: en un empate de especificidad gana
   la regla que se carga después en el <link>, que es la de Storefront, y
   dejaba la columna central encogida a la mitad de su ancho de columna de
   grid real (585px de track quedaban en ~330px visibles). Se refuerza con
   !important, mismo patrón que .images y el botón de compra. */
.single-product div.product .summary {
	grid-area: info;
	width: 100% !important;
	float: none !important;
	margin-right: 0 !important;
}

.jv-pdp-buybox {
	grid-area: buybox;
}

@media (min-width: 1000px) {
	/* Amazon mantiene la columna de imagen a un ancho más o menos fijo (no
	   proporcional al viewport) y deja que sea la columna central de
	   info/specs la que absorba el espacio extra en pantallas anchas — con
	   la PDP ahora a ancho completo (ver más abajo, .single-product
	   div.product full-bleed), un 40% fijo sobre 1600px+ daba una imagen
	   enorme (640px+) y dejaba la columna central desproporcionadamente
	   estrecha en comparación. minmax() fija un techo razonable a la
	   imagen y dispara el resto a la columna central. */
	.jv-pdp-top-grid {
		grid-template-columns: minmax(320px, 560px) 1fr 320px;
		grid-template-areas: "gallery info buybox";
		gap: 40px;
		align-items: start;
	}

	.single-product div.product .woocommerce-product-gallery,
	.single-product div.product .images {
		/* La columna central (specs/variantes/ficha técnica) suele ser más
		   alta que la imagen — sticky evita que la foto quede "huérfana"
		   arriba con un hueco en blanco debajo mientras se sigue leyendo la
		   columna 2, y acompaña el scroll como en Amazon. Ahora limitado a
		   la altura de .jv-pdp-top-grid (ver más arriba) en vez de a todo
		   div.product: el sticky se libera de forma nativa en cuanto esa
		   altura termina, sin seguir pegado durante la descripción/relacionados.
		   top:0 (no 24px) — con scroll en el tope de la página, un sticky
		   con top>0 se desplaza ESE valor hacia abajo desde su posición
		   estática natural en el grid (es cómo funciona position:sticky),
		   así que la imagen/buybox quedaban 24px por debajo de .summary
		   (que no es sticky) nada más cargar, desalineando el título del
		   top de la foto. Con top:0 arrancan alineados y el "pegado" al
		   hacer scroll sigue funcionando igual, solo que sin ese offset. */
		/* position:sticky crea su propio stacking context aunque no tenga
		   z-index explícito — sin ESTE z-index bajo, la imagen (sticky)
		   podía pintarse por encima del mega-menú desplegado (.jv-mega-panel,
		   z-index:60, position:absolute) al pasar el ratón por una categoría
		   estando en la ficha de producto: el panel se veía "tapado" por la
		   foto de la izquierda en vez de flotar por encima como debería. */
		position: sticky;
		/* top = alto del header pegado, no 0: con 0 la foto/buybox se metian
		   debajo del header al engancharse. No desplaza nada con el scroll
		   arriba del todo — un sticky solo se despega cuando su posicion
		   natural cruza ese umbral, y aqui arranca 268px por debajo
		   (comprobado: top=268.8 igual que .summary a scrollTop 0). */
		top: var(--jv-header-height);
		align-self: start;
		z-index: 1;
	}

	.jv-pdp-buybox {
		position: sticky;
		/* top = alto del header pegado, no 0: con 0 la foto/buybox se metian
		   debajo del header al engancharse. No desplaza nada con el scroll
		   arriba del todo — un sticky solo se despega cuando su posicion
		   natural cruza ese umbral, y aqui arranca 268px por debajo
		   (comprobado: top=268.8 igual que .summary a scrollTop 0). */
		top: var(--jv-header-height);
		align-self: start;
		z-index: 1;
	}
}

.jv-pdp-buybox {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 16px;
	box-sizing: border-box;
	display: flex;
	flex-direction: column;
	gap: 8px;
}

/* El título de producto heredaba el mismo tamaño que los H1 editoriales de
   categoría/blog (40px, pensado para encabezar una página entera) — en la
   ficha de producto, con columna central más estrecha y compacta al estilo
   Amazon, un título tan grande ocupaba demasiado espacio en relación al
   resto del contenido. */
.single-product div.product .summary .product_title.entry-title {
	font-size: 24px;
	line-height: 1.25;
	margin-bottom: 4px;
}

/* Filete fino estilo Amazon: separa nombre/marca de precio, y precio de
   selector de variantes — en vez de depender solo del espaciado vertical
   entre bloques (que en Amazon siempre lleva además esta línea de 1px).
   --jv-color-border (gris muy claro, pensado para bordes de tarjeta) casi
   no se distinguía del fondo blanco de la columna — se usa un gris algo
   más oscuro solo para este filete, que necesita ser visible por sí mismo
   sin el contexto de una tarjeta alrededor. */
.jv-pdp-divider {
	border: none;
	border-top: 1px solid #d5d9d3;
	margin: 12px 0;
}

/* Fecha de entrega estimada — ver jv_render_pdp_delivery_estimate() en
   inc/delivery-estimate.php. Se traslada por JS al buybox de columna 3,
   justo encima de "Cantidad" (ver jv_pdp_buybox_script en inc/pdp-layout.php),
   por eso vive aquí sin depender de en qué columna termine renderizándose. */
.jv-pdp-delivery-estimate {
	display: flex;
	align-items: center;
	flex-wrap: wrap;
	gap: 4px 8px;
	margin: 0 0 4px;
	font-size: 13.5px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-pdp-delivery-estimate .jv-icon {
	width: auto;
	height: 18px;
	flex-shrink: 0;
	color: var(--jv-color-forest);
}

.jv-pdp-delivery-estimate__link {
	font-weight: 300;
	color: var(--jv-color-price-muted);
	text-decoration: underline;
}

.jv-pdp-delivery-estimate__link:hover {
	color: var(--jv-color-forest);
}

/* El buybox encabeza con "Comprar nuevo" + el precio final limpio (solo la
   cifra grande, sin -XX%/precio recomendado — eso ya se lee completo en la
   columna central, repetirlo aquí era ruido) — mismo patrón que Amazon,
   donde el bloque de compra muestra una única cifra de precio. */
.jv-pdp-buybox__heading {
	margin: 0;
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

/* Buybox reducido para productos sin stock — ver jv_pdp_wrap_out_of_stock()
   en inc/pdp-layout.php: sin form.cart no hay cantidad/botón que mostrar,
   solo el aviso de disponibilidad, pero el wrapper sigue existiendo para
   mantener el grid de 3 columnas (imagen no se estira a todo el ancho). */
.jv-pdp-buybox__out-of-stock {
	margin: 0;
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-price-muted);
}

.jv-pdp-buybox__price.jv-amazon-price {
	font-size: 26px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

/* El selector de variantes ya NO se clona en el buybox de columna 3 (ver
   jv_pdp_buybox_script en inc/pdp-layout.php) — vive en la columna central y,
   al hacer scroll, en la barra sticky inferior nativa de Storefront (ver
   .jv-sticky-bar__variations más abajo). */

/* Etiqueta visible "Cantidad" (ver jv_pdp_buybox_script en inc/pdp-layout.php
   — el <label> nativo de WooCommerce es screen-reader-text) justo encima
   del selector numérico, como en Amazon. */
.jv-pdp-buybox__qty-label {
	display: block;
	margin-bottom: 4px;
	font-size: 12.5px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

/* Agrupa cantidad + botón + disponibilidad (ver jv_pdp_buybox_script en
   inc/pdp-layout.php) en una única columna con espaciado consistente — antes
   estos tres elementos vivían sueltos dentro del buybox con el margin/padding
   por defecto de WooCommerce, que no dejaba aire hacia los bordes de la
   tarjeta y hacía que la cantidad tocara visualmente el borde izquierdo. */
.jv-pdp-buybox__action {
	display: flex;
	flex-direction: column;
	gap: 10px;
	width: 100%;
}

/* Para producto variable, .woocommerce-variation-add-to-cart (cantidad +
   botón + los 3 hidden inputs que WooCommerce resincroniza en cada cambio
   de variante) se queda en su sitio ORIGINAL dentro del <form>, oculto —
   ver jv_pdp_buybox_script en inc/pdp-layout.php: moverlo rompía tanto el
   input[name="variation_id"] como los límites min/max de cantidad, porque
   WooCommerce los localiza con $form.find()/$singleVariationWrap.find() en
   cada evento, que solo encuentra descendientes ACTUALES del form. El
   buybox muestra en su lugar cantidad+botón PROPIOS (.jv-pdp-buybox__action
   > .quantity / .single_add_to_cart_button) que reflejan/reenvían al nodo
   real oculto. */
.jv-pdp-buybox__action--source {
	position: absolute;
	width: 1px;
	height: 1px;
	padding: 0;
	margin: -1px;
	overflow: hidden;
	clip: rect(0, 0, 0, 0);
	white-space: nowrap;
	border: 0;
}

.jv-pdp-buybox__action .quantity,
.jv-pdp-buybox__action form.cart div.quantity {
	width: 100%;
	box-sizing: border-box;
}

.jv-pdp-buybox__action .quantity .qty {
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	padding: 7px;
	font-size: 13.5px;
}

/* Amazon usa un botón de compra bastante más discreto que el CTA genérico
   del resto del sitio (padding 16px/20px, pensado para banners/CTAs de
   home) — dentro del buybox, con el ancho fijo de la columna 3, ese mismo
   tamaño se veía desproporcionadamente grande y grueso. */
.jv-pdp-buybox__action .single_add_to_cart_button {
	width: 100%;
	box-sizing: border-box;
	text-align: center;
	font-size: 13px;
	font-weight: 600;
	padding: 7px 16px;
}

/* Disponibilidad (ej. "105 disponibles") justo debajo del botón, estilo
   Amazon ("En stock" cerca del botón de compra) — en vez de quedar suelta
   dentro de la columna central sin relación visual con la acción de compra. */
.jv-pdp-buybox__action .stock,
.jv-pdp-buybox__stock {
	margin: 0;
	padding: 0;
	font-size: 13px;
	text-align: center;
}

.jv-pdp-buybox__stock:empty {
	display: none;
}

.jv-pdp-buybox__action .stock.in-stock,
.jv-pdp-buybox__stock .in-stock {
	color: var(--jv-color-forest);
}

.jv-pdp-buybox__action .stock.out-of-stock,
.jv-pdp-buybox__stock .out-of-stock {
	color: var(--jv-color-sale);
}

/* .woocommerce-variation (precio nativo oculto + disponibilidad) no debe
   dejar su propio padding/margen por defecto de WooCommerce una vez movido
   dentro de la fila de acción del buybox. */
.jv-pdp-buybox__action .woocommerce-variation {
	padding: 0;
	margin: 0;
}

.jv-pdp-buybox .jv-trust-badges {
	/* En la columna central (300px+) 3 tarjetas en fila caben bien, pero
	   dentro del buybox (300px de ancho total, con su propio padding) 3
	   columnas comprimían tanto cada tarjeta que el texto se cortaba a media
	   palabra — 2 columnas con la tarjeta impar ocupando el ancho completo
	   deja textos legibles sin agrandar el buybox. */
	grid-template-columns: repeat(2, 1fr);
	margin: 0;
	gap: 8px;
}

.jv-pdp-buybox .jv-trust-badge {
	padding: 12px 10px;
}

.jv-pdp-buybox .jv-trust-badge:last-child:nth-child(odd) {
	grid-column: 1 / -1;
}

.jv-pdp-buybox .jv-trust-payment-methods__list {
	margin: 0;
}

/* Pastillas de medios de pago a 2 por línea (en vez de intentar caber las 4
   en una sola fila, lo que las comprimía) — si el número de pastillas es
   impar, la última queda centrada en su propia fila en vez de pegada a la
   izquierda con hueco asimétrico al lado. */
.jv-trust-payment-methods__list {
	justify-content: center;
}

.jv-trust-payment-methods__list li {
	flex: 0 0 calc(50% - 4px);
	text-align: center;
	box-sizing: border-box;
}

/* Ficha técnica dinámica bajo el selector de variantes — ver
   jv_render_dynamic_specs_block() en inc/product-tabs.php. Tabla de 2
   columnas (etiqueta/valor) al estilo Amazon; con más de 6 specs, las
   filas extra quedan ocultas hasta pulsar "Mostrar más". */
.jv-dynamic-specs {
	margin: 4px 0 14px;
}

.jv-dynamic-specs__table {
	width: 100%;
	border-collapse: collapse;
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	/* border-radius sobre una tabla no recorta sus celdas por defecto —
	   necesita su propio contexto de recorte para que las esquinas de la
	   primera/última fila se vean realmente redondeadas. */
	isolation: isolate;
}

.jv-dynamic-specs__table tr:not(:last-child) {
	border-bottom: 1px solid var(--jv-color-border);
}

/* Filas alternadas (zebra striping) — ayuda a seguir la fila de una
   columna a otra en tablas de varias líneas, patrón habitual en fichas de
   especificaciones (Amazon, fichas de producto en general). */
.jv-dynamic-specs__table tr:nth-child(even) {
	background: var(--jv-color-canvas);
}

/* Filas más compactas — Amazon aprieta mucho más las specs que lo que
   dejaba este padding (11px arriba/abajo aporta bastante altura acumulada
   en una tabla de 6-7 filas, ver "mucho hueco en altura" reportado). */
.jv-dynamic-specs__table th,
.jv-dynamic-specs__table td {
	text-align: left;
	padding: 7px 14px;
	font-size: 13px;
	line-height: 1.35;
	vertical-align: top;
}

.jv-dynamic-specs__table th {
	width: 42%;
	color: var(--jv-color-price-muted);
	font-weight: 600;
	border-right: 1px solid var(--jv-color-border);
}

.jv-dynamic-specs__table td {
	color: var(--jv-color-ink);
	font-weight: 600;
}

.jv-dynamic-specs__row--extra {
	display: none;
}

#jv-dynamic-specs.is-expanded .jv-dynamic-specs__row--extra {
	display: table-row;
}

.jv-dynamic-specs__toggle {
	display: inline-flex;
	align-items: center;
	gap: 4px;
	margin-top: 10px;
	background: none;
	border: none;
	padding: 0;
	font-family: var(--jv-font-sans);
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
	cursor: pointer;
}

.jv-dynamic-specs__toggle .jv-icon {
	width: auto;
	height: 14px;
	transition: transform .2s ease;
}

#jv-dynamic-specs.is-expanded .jv-dynamic-specs__toggle .jv-icon {
	transform: rotate(180deg);
}

/* Contenedor de marca+nombre reubicado antes de la imagen en móvil (ver
   jv_pdp_mobile_reorder_script(), inc/pdp-layout.php) — solo existe en el
   DOM por debajo de 600px, así que no necesita ningún ajuste específico de
   desktop (nunca se crea ahí). */
.jv-pdp-mobile-header {
	margin-bottom: 12px;
}

/* Acordeón de "Ficha técnica" — SOLO en móvil (jv_pdp_mobile_specs_accordion_script
   envuelve #jv-dynamic-specs en este wrapper para cualquier ancho, pero el
   estilo de acordeón-colapsado-por-defecto solo se activa por debajo de
   600px; en desktop el toggle existe en el DOM pero permanece oculto y la
   ficha se ve siempre completa, igual que antes de este cambio). El
   display:none explícito es necesario: sin él, el <button> sin ninguna otra
   regla fuera de la media query se renderizaba con el estilo nativo del
   navegador (display:inline-block), un botón "Ficha técnica" suelto y sin
   estilizar quedaba visible en escritorio encima de la tabla ya expandida. */
.jv-pdp-specs-accordion__toggle {
	display: none;
}

@media (max-width: 600px) {
	.jv-pdp-specs-accordion__toggle {
		display: flex;
		align-items: center;
		justify-content: space-between;
		width: 100%;
		padding: 12px 0;
		background: none;
		border: none;
		border-top: 1px solid var(--jv-color-border);
		border-bottom: 1px solid var(--jv-color-border);
		font-family: var(--jv-font-sans);
		font-size: 14px;
		font-weight: 600;
		color: var(--jv-color-ink);
		cursor: pointer;
	}

	.jv-pdp-specs-accordion__toggle .jv-icon {
		width: auto;
		height: 18px;
		transition: transform .2s ease;
	}

	.jv-pdp-specs-accordion.is-open .jv-pdp-specs-accordion__toggle .jv-icon {
		transform: rotate(180deg);
	}

	/* Selector por ID (#jv-dynamic-specs), no por la clase
	   .jv-pdp-specs-accordion__body: ese nodo se SUSTITUYE por completo
	   (outerHTML) en cada cambio de variante (ver jv_pdp_dynamic_specs_script(),
	   inc/product-tabs.php) y el reemplazo no conserva ninguna clase añadida
	   por JS — el ID sí es estable porque el HTML de reemplazo lo reincluye
	   explícitamente. Controlar la visibilidad desde el WRAPPER
	   (.jv-pdp-specs-accordion), que nunca se destruye, hace innecesario que
	   el hijo conserve ninguna clase propia. */
	.jv-pdp-specs-accordion #jv-dynamic-specs {
		display: none;
		margin-top: 10px;
	}

	.jv-pdp-specs-accordion.is-open #jv-dynamic-specs {
		display: block;
	}
}

/* Marca encima del título (ver jv_render_pdp_meta() en inc/pdp-layout.php)
   — logo si existe uno subido (brand-logo-{slug}.*), y siempre un link de
   texto "Ver los productos de {marca}" debajo, estilo Amazon ("Visita la
   tienda de Nikon"). Ya no es una pastilla/pill con icono bajo el título. */
.jv-pdp-brand {
	display: flex;
	flex-direction: column;
	align-items: flex-start;
	gap: 4px;
	margin: 0 0 10px;
}

.jv-pdp-brand__logo-link {
	display: inline-block;
	line-height: 0;
}

.jv-pdp-brand__logo {
	max-height: 28px;
	max-width: 140px;
	width: auto;
	height: auto;
	object-fit: contain;
}

.jv-pdp-brand__link {
	font-size: 12.5px;
	color: var(--jv-color-forest);
	text-decoration: none;
}

.jv-pdp-brand__link:hover {
	text-decoration: underline;
}

/* Bloque comparativo "¿Cuál elegir?" — entre la descripción corta y el
   selector de variantes (woocommerce_single_product_summary, prioridad 25,
   ver jv_render_variant_compare_block() en product-tabs.php). Inspirado en
   growindustry.es: destaca solo los atributos que cambian entre variantes,
   para decidir sin tener que clicar cada botón de formato uno a uno. */
.jv-variant-compare {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 18px 20px;
	margin: 4px 0 20px;
}

.jv-variant-compare__title {
	display: flex;
	align-items: center;
	gap: 8px;
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-ink);
	margin: 0 0 12px;
}

.jv-variant-compare__title .jv-icon {
	width: auto;
	height: 18px;
	color: var(--jv-color-selected);
}

.jv-variant-compare__list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 10px;
	max-height: 260px;
	overflow-y: auto;
}

.jv-variant-compare__list li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 13.5px;
	line-height: 1.5;
	color: var(--jv-color-ink);
}

.jv-variant-compare__check {
	width: 16px;
	height: 16px;
	flex-shrink: 0;
	margin-top: 2px;
	color: var(--jv-color-selected);
}

.jv-variant-compare__name {
	color: var(--jv-color-ink);
}

/* Miniaturas: más grandes y con mejor separación que el 14%/columnas-4 por
   defecto, que las deja diminutas cuando hay 4-5 imágenes. */
.single-product div.product .woocommerce-product-gallery .flex-control-thumbs {
	display: flex;
	flex-wrap: wrap;
	gap: 9px;
	margin-top: 12px !important;
}

.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li {
	width: 72px !important;
	height: 72px;
	float: none !important;
	margin: 0 !important;
	border-radius: var(--jv-radius-control);
	overflow: hidden;
	border: 1px solid var(--jv-color-border);
}

.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li img {
	width: 100%;
	height: 100%;
	object-fit: contain;
	background: #fff;
	border-radius: 0;
	opacity: .7;
}

.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li img.flex-active,
.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li:hover img {
	opacity: 1;
}

@media (max-width: 767px) {
	.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li {
		width: 60px !important;
		height: 60px;
	}
}

@media (max-width: 480px) {
	.single-product div.product .woocommerce-product-gallery .flex-control-thumbs li {
		width: 52px !important;
		height: 52px;
	}
}

/* En móvil, puntitos de carrusel (como amazon.es en su app/web móvil) en
   vez de la fila de miniaturas — WooCommerce/FlexSlider ya genera AMBOS
   elementos en el DOM cuando hay más de 1 imagen (.flex-control-thumbs Y
   .flex-control-nav, este último con un <li><a>nº</a></li> por imagen,
   pensado precisamente para renderizarse como puntos), así que no hace
   falta ningún carrusel/JS nuevo: basta con ocultar uno y dar estilo al
   otro. Los enlaces .flex-control-nav ya cambian de imagen igual que las
   miniaturas (mismo JS de FlexSlider), solo cambia su apariencia visual. */
@media (max-width: 600px) {
	.single-product div.product .woocommerce-product-gallery .flex-control-thumbs {
		display: none;
	}

	.single-product div.product .woocommerce-product-gallery .flex-control-nav {
		display: flex;
		justify-content: center;
		align-items: center;
		gap: 6px;
		margin: 10px 0 0;
		padding: 0;
		list-style: none;
	}

	.single-product div.product .woocommerce-product-gallery .flex-control-nav li {
		margin: 0;
	}

	.single-product div.product .woocommerce-product-gallery .flex-control-nav a {
		display: block;
		width: 7px;
		height: 7px;
		border-radius: 50%;
		background: var(--jv-color-border);
		text-indent: -9999px;
		overflow: hidden;
		cursor: pointer;
	}

	.single-product div.product .woocommerce-product-gallery .flex-control-nav a.flex-active {
		background: var(--jv-color-forest);
	}
}

/* =============================================================
   PDP — secciones en scroll continuo (sin pestañas clicables)
   Sustituye el sistema de tabs de WooCommerce (jQuery UI, contenido oculto
   hasta hacer click). Ver woocommerce/single-product/tabs/tabs.php e
   inc/product-tabs.php. Cada bloque va alternando fondo crema/blanco y
   lleva su propio encabezado con icono para que se lean como capítulos
   diferenciados, no como una sola columna monótona de texto.
   ============================================================= */

.jv-pdp-sections {
	clear: both;
	margin-top: 8px;
}

/* Con el grid de 3 columnas de la cabecera (imagen | info | buybox), la fila
   entera adopta la altura de la columna más alta (normalmente la central,
   con specs+variantes) — el sticky de imagen/buybox ya acompaña el scroll
   mientras se lee esa columna, y se libera de forma nativa (vuelve a su
   posición estática en el flujo del grid) en cuanto termina esa altura,
   dejando debajo el aire propio de cada columna más corta.
   ANTES había aquí un margin-top negativo pensado para "compensar" ese aire
   y acercar el salto a "Descripción" — pero un margin-top negativo no quita
   aire visual, MUEVE la sección siguiente hacia arriba en el documento,
   invadiendo la franja donde la imagen/buybox sticky (z-index:1, ver
   .jv-pdp-top-grid) todavía existe en el layout mientras se suelta del
   sticky. Añadir z-index a .jv-pdp-sections "arregla" el solape de texto
   pero cambia el síntoma: la sección tapa al buybox en vez de solaparse con
   su texto, así que el buybox se corta en seco contra el borde de la
   sección en lugar de terminar con el mismo aire limpio que la imagen. La
   única forma de que buybox e imagen liberen su sticky IGUAL (mismo aire,
   sin cortes ni solapes) es no mover la sección siguiente por encima de esa
   franja: nada de margin-top negativo aquí. Si el hueco bajo la columna más
   corta molesta estéticamente, se reduce ajustando el gap/alto real del
   grid (.jv-pdp-top-grid), no empujando la sección siguiente hacia arriba. */

.jv-pdp-section {
	padding: 48px 0;
	border-top: 1px solid var(--jv-color-border);
}

.jv-pdp-section:first-child {
	border-top: none;
}

.jv-pdp-section--description,
.jv-pdp-section--jv_technical,
.jv-pdp-section--jv_documents,
.jv-pdp-section--reviews {
	border-radius: var(--jv-radius-card);
	border-top: none;
	padding: 56px 40px;
	margin: 0 0 24px;
	box-shadow: none;
}

.jv-pdp-section--description {
	background: var(--jv-color-surface);
}

.jv-pdp-section--jv_technical {
	background: rgba(15, 86, 55, .04);
	border: 1px solid rgba(15, 86, 55, .12);
}

.jv-pdp-section--jv_documents {
	background: rgba(180, 140, 40, .05);
	border: 1px solid rgba(180, 140, 40, .14);
}

.jv-pdp-section--reviews {
	background: rgba(168, 50, 32, .035);
	border: 1px solid rgba(168, 50, 32, .1);
}

.jv-pdp-section__inner {
	max-width: 740px;
	margin: 0 auto;
}

.jv-pdp-section__heading {
	display: flex;
	align-items: center;
	gap: 12px;
	font-family: var(--jv-font-sans);
	font-size: 26px;
	font-weight: 600;
	color: var(--jv-color-ink);
	margin: 0 0 28px;
}

.jv-pdp-section--description .jv-pdp-section__heading {
	font-size: 30px;
}

.jv-pdp-section__icon {
	width: auto;
	height: 26px;
	color: var(--jv-color-forest);
	flex-shrink: 0;
}

/* ----- Descripción del producto: la sección clave para vender ----- */
/* Columna limitada a ~740px para lineas de lectura cómodas, tipografia algo
   mayor que el resto del sitio (--jv-text-body es 14px; aquí 17px) y
   line-height generoso. El HTML viene del proveedor Hortitec (the_content)
   con párrafos/listas/negritas/encabezados ya en el post_content. */
.jv-pdp-section--description .jv-pdp-section__body {
	max-width: 740px;
	margin: 0 auto;
	font-size: 17px;
	line-height: 1.75;
	color: var(--jv-color-ink);
}

/* Amazon mantiene la descripción en una única columna de lectura, no a
   ancho completo ni repartida en 2 columnas tipo periódico (que se probó
   antes aquí y se revirtió: con contenido de longitud variable del
   proveedor, el corte entre columnas quedaba en un punto arbitrario del
   texto, distinto en cada producto, y no aportaba nada sobre una columna
   más ancha). 800px es algo más ancho que el body general (740px) para
   aprovechar el espacio extra de la tarjeta sin llegar a ancho completo. */
.jv-pdp-section--description .jv-pdp-section__body {
	max-width: 800px;
}

/* Contenido ESTRUCTURADO del pipeline (inc/jv-content-renderer.php): sus
   bloques controlan su propio layout (rejillas, split, imagen a media columna),
   así que se le da más ancho de lectura (~1000px) para que quepan las dos
   columnas sin líneas de texto incómodamente largas. El contenido antiguo de
   texto corrido del proveedor sigue en su columna estrecha (800px de arriba). */
.jv-pdp-section--description .jv-pdp-section__body:has(.jv-structured-content) {
	max-width: 1180px;
}
/* Cuando la descripción es estructurada, su contenedor .jv-pdp-section__inner
   también se ensancha (por defecto está a 740px y estrangularía el contenido). */
.jv-pdp-section--description:has(.jv-structured-content) .jv-pdp-section__inner {
	max-width: 1180px;
}

.jv-pdp-section--description .jv-pdp-section__body > *:first-child {
	margin-top: 0;
}

.jv-pdp-section--description .jv-pdp-section__body p {
	margin: 0 0 22px;
}

.jv-pdp-section--description .jv-pdp-section__body h2,
.jv-pdp-section--description .jv-pdp-section__body h3,
.jv-pdp-section--description .jv-pdp-section__body h4 {
	font-family: var(--jv-font-sans);
	color: var(--jv-color-forest);
	line-height: 1.3;
	margin: 40px 0 16px;
}

.jv-pdp-section--description .jv-pdp-section__body h2 {
	font-size: 24px;
	font-weight: 600;
}

.jv-pdp-section--description .jv-pdp-section__body h3 {
	font-size: 20px;
	font-weight: 600;
}

.jv-pdp-section--description .jv-pdp-section__body h4 {
	font-size: 18px;
	font-weight: 600;
}

.jv-pdp-section--description .jv-pdp-section__body strong,
.jv-pdp-section--description .jv-pdp-section__body b {
	color: var(--jv-color-forest);
	font-weight: 600;
}

.jv-pdp-section--description .jv-pdp-section__body ul,
.jv-pdp-section--description .jv-pdp-section__body ol {
	margin: 0 0 24px;
	padding: 0;
	list-style: none;
}

.jv-pdp-section--description .jv-pdp-section__body ol {
	counter-reset: jv-desc-ol;
}

.jv-pdp-section--description .jv-pdp-section__body ul li,
.jv-pdp-section--description .jv-pdp-section__body ol li {
	position: relative;
	padding-left: 30px;
	margin-bottom: 12px;
	line-height: 1.6;
}

/* Viñetas planas sustituidas por icono de check — mejora la lectura y
   encaja con el resto de "pastillas"/iconografía del sitio. */
/* El check/viñeta y el número automáticos SOLO aplican al texto corrido del
   proveedor. El contenido estructurado del pipeline (.jv-structured-content)
   trae sus propias listas con icono/número propios (.jv-benefit, .jv-step,
   .jv-fit-list), así que se excluyen con :not() para no duplicar marcadores. */
.jv-pdp-section--description .jv-pdp-section__body ul li:not(.jv-benefit):not(.jv-step):not(.jv-fit-list li)::before {
	content: "";
	position: absolute;
	left: 0;
	top: 5px;
	width: 18px;
	height: 18px;
	border-radius: 50%;
	background: var(--jv-color-forest);
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 11px no-repeat;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 11px no-repeat;
}

/* Las listas del contenido estructurado no llevan el padding-left ni el
   marcador del texto corrido: ya se maquetan con flexbox propio. */
.jv-structured-content ul li,
.jv-structured-content ol li {
	padding-left: 0;
	margin-bottom: 0;
}
.jv-structured-content ul li::before,
.jv-structured-content ol li::before {
	display: none !important;
	content: none !important;
}
/* La lista de "Incluye/Necesitas" usa viñetas normales, separadas del borde del
   recuadro y con aire alrededor. Se fuerza para vencer al padding/marcador
   heredado del texto corrido del proveedor. */
.jv-fit-list {
	margin: 8px 0 0 !important;
	padding-left: 22px !important;
	list-style: disc !important;
	line-height: 1.6;
}
.jv-fit-list li {
	padding-left: 6px !important;
	margin-bottom: 8px;
	list-style: disc !important;
	position: static !important;
}
.jv-fit-list li:last-child { margin-bottom: 0; }
.jv-fit-list li::before {
	display: none !important;
	content: none !important;
}
.jv-fit-list li::marker {
	color: var(--jv-color-forest);
}

.jv-pdp-section--description .jv-pdp-section__body ol {
	counter-reset: jv-desc-ol;
}

.jv-pdp-section--description .jv-pdp-section__body ol li {
	counter-increment: jv-desc-ol;
}

.jv-pdp-section--description .jv-pdp-section__body ol li::before {
	content: counter(jv-desc-ol);
	position: absolute;
	left: 0;
	top: 0;
	width: 20px;
	height: 20px;
	border-radius: 50%;
	background: var(--jv-color-forest);
	color: #fff;
	font-size: 11px;
	font-weight: 600;
	line-height: 20px;
	text-align: center;
}

.jv-pdp-section--description .jv-pdp-section__body img {
	max-width: 100%;
	height: auto;
	border-radius: var(--jv-radius-card);
}

.jv-pdp-section--description .jv-pdp-section__body a {
	color: var(--jv-color-forest);
	text-decoration: underline;
}

.jv-pdp-section--description .jv-pdp-section__body table {
	width: 100%;
	border-collapse: collapse;
	margin: 0 0 24px;
	font-size: 15px;
}

.jv-pdp-section--description .jv-pdp-section__body table th,
.jv-pdp-section--description .jv-pdp-section__body table td {
	border: 1px solid var(--jv-color-border);
	padding: 10px 12px;
	text-align: left;
}

/* ----- Imágenes ilustrativas intercaladas en la descripción ----- */
/* Ver jv_inject_gallery_images_into_description() en inc/product-tabs.php:
   cuando el producto tiene 2+ imágenes en su galería, se inserta la 2ª (y
   3ª si hay) imagen adicional partiendo el bloque de texto — nunca repite
   la imagen destacada que ya se ve arriba en la galería principal. */
.jv-desc-inline-image {
	margin: 32px 0;
	border-radius: var(--jv-radius-card);
	overflow: hidden;
}

.jv-desc-inline-image img {
	display: block;
	width: 100%;
	height: auto;
	margin: 0;
	border-radius: var(--jv-radius-card);
}

@media (min-width: 900px) {
	/* min(320px, 40%) en vez de un 320px fijo: con dos imágenes flotantes
	   opuestas (float-left + float-right) en el mismo párrafo de texto corto,
	   un ancho fijo podía sumar más que el propio contenedor en anchos de
	   viewport intermedios (justo por encima de este breakpoint, antes de
	   que .jv-pdp-section__body alcance su max-width completo de 740-800px)
	   y desbordar o solaparse. Limitado al 40% del contenedor, dos floats
	   opuestos nunca superan el 80% de su ancho combinado, dejando siempre
	   sitio para el texto/aire entre ambos y sin poder desbordar el
	   contenedor en ningún ancho de pantalla. */
	.jv-desc-inline-image--float-right {
		float: right;
		width: min(320px, 40%);
		margin: 6px 0 24px 32px;
	}

	.jv-desc-inline-image--float-left {
		float: left;
		width: min(320px, 40%);
		margin: 6px 32px 24px 0;
	}
}

/* ----- Información adicional / Ficha técnica y Reviews: variantes de sección ----- */

.jv-pdp-section--jv_technical .jv-pdp-section__body,
.jv-pdp-section--reviews .jv-pdp-section__body {
	background: transparent;
}

.jv-pdp-section--reviews #reviews {
	background: transparent;
}

.jv-pdp-section--reviews .woocommerce-Reviews-title {
	display: none;
}

.jv-pdp-section--reviews #review_form_wrapper {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 24px;
	margin-top: 24px;
}

.jv-pdp-section--reviews .commentlist {
	list-style: none;
	margin: 0;
	padding: 0;
}

.jv-pdp-section--reviews .commentlist .comment {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 20px;
	margin-bottom: 16px;
}

.jv-pdp-section--reviews .woocommerce-noreviews {
	background: var(--jv-color-surface);
	border: 1px dashed var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 20px;
	color: var(--jv-color-price-muted);
}

@media (max-width: 900px) {
	.jv-pdp-section {
		padding: 36px 0;
	}

	.jv-pdp-section--description,
	.jv-pdp-section--jv_technical,
	.jv-pdp-section--jv_documents,
	.jv-pdp-section--reviews {
		padding: 36px 24px;
	}

	.jv-pdp-section__heading {
		font-size: 22px;
	}

	.jv-pdp-section--description .jv-pdp-section__heading {
		font-size: 24px;
	}

	.single-product div.product .woocommerce-product-gallery,
	.single-product div.product .images,
	.single-product div.product .summary {
		width: 100% !important;
		float: none !important;
	}
}

@media (max-width: 600px) {
	.jv-pdp-section--description .jv-pdp-section__body {
		font-size: 15.5px;
		line-height: 1.7;
	}

	.jv-desc-inline-image--float-right,
	.jv-desc-inline-image--float-left {
		float: none;
		width: 100%;
		margin: 24px 0;
	}
}

/* =========================================================================
   Club Pro — landing de membresía por niveles
   ========================================================================= */

.jv-club-hero {
	background: var(--jv-color-forest);
	padding: 72px 0 96px;
	text-align: center;
	color: #fff;
}

.jv-club-hero__eyebrow {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	background: rgba(255, 255, 255, .12);
	border: 1px solid rgba(255, 255, 255, .28);
	border-radius: var(--jv-radius-pill);
	padding: 8px 18px;
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	margin-bottom: 24px;
}

.jv-club-hero__eyebrow svg {
	width: auto;
	height: 14px;
	fill: var(--jv-color-mint);
	fill: var(--jv-color-mint);
}

.jv-club-hero__title {
	font-size: 44px;
	font-weight: 600;
	margin: 0 0 16px;
	line-height: 1.15;
	color: #fff;
}

.jv-club-hero__subhead {
	max-width: 620px;
	margin: 0 auto;
	font-size: 17px;
	line-height: 1.6;
	color: rgba(255, 255, 255, .85);
}

.jv-club-tiers {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 24px;
	margin-top: -64px;
	margin-bottom: 64px;
}

.jv-club-tier {
	position: relative;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 40px 32px;
	box-shadow: none;
	display: flex;
	flex-direction: column;
}

.jv-club-tier--featured {
	border-color: var(--jv-color-forest);
	box-shadow: none;
	transform: translateY(-12px);
}

.jv-club-tier__ribbon {
	position: absolute;
	top: -14px;
	left: 50%;
	transform: translateX(-50%);
	background: var(--jv-color-forest);
	color: #fff;
	font-size: 12.5px;
	font-weight: 600;
	letter-spacing: .02em;
	text-transform: uppercase;
	padding: 6px 18px;
	border-radius: var(--jv-radius-pill);
	white-space: nowrap;
}

.jv-club-tier__header {
	text-align: center;
	margin-bottom: 24px;
}

.jv-club-tier__name {
	font-size: 24px;
	font-weight: 600;
	margin: 0 0 6px;
	color: var(--jv-color-ink);
}

.jv-club-tier__tagline {
	font-size: 14px;
	color: var(--jv-color-price-muted);
	margin: 0;
}

.jv-club-tier__discount {
	text-align: center;
	padding: 20px 0;
	margin-bottom: 20px;
	border-top: 1px solid var(--jv-color-border);
	border-bottom: 1px solid var(--jv-color-border);
}

.jv-club-tier__discount-value {
	display: block;
	font-size: 40px;
	font-weight: 600;
	color: var(--jv-color-forest);
	line-height: 1.1;
}

.jv-club-tier__discount-label {
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

.jv-club-tier__price {
	text-align: center;
	margin-bottom: 28px;
}

.jv-club-tier__price strong {
	display: block;
	font-size: 20px;
	color: var(--jv-color-ink);
}

.jv-club-tier__price span {
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

.jv-club-tier__features {
	list-style: none;
	margin: 0 0 28px;
	padding: 0;
	flex: 1;
}

.jv-club-tier__features li {
	display: flex;
	align-items: flex-start;
	gap: 10px;
	font-size: 14.5px;
	line-height: 1.5;
	color: var(--jv-color-ink);
	padding: 8px 0;
}

.jv-club-tier__features li svg {
	width: auto;
	height: 16px;
	flex-shrink: 0;
	margin-top: 2px;
	fill: var(--jv-color-forest);
}

.jv-club-tier__cta {
	text-align: center;
	width: 100%;
}

.jv-club-compare {
	margin-bottom: 64px;
}

.jv-club-compare__table-wrap {
	overflow-x: auto;
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	background: var(--jv-color-surface);
}

.jv-club-compare__table {
	width: 100%;
	border-collapse: collapse;
	min-width: 560px;
}

.jv-club-compare__table th,
.jv-club-compare__table td {
	padding: 16px 20px;
	text-align: center;
	border-bottom: 1px solid var(--jv-color-border);
	font-size: 14.5px;
}

.jv-club-compare__table th:first-child,
.jv-club-compare__table td:first-child {
	text-align: left;
	font-weight: 600;
	color: var(--jv-color-ink);
}

.jv-club-compare__table thead th {
	background: var(--jv-color-canvas);
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-club-compare__table tbody tr:last-child td {
	border-bottom: none;
}

.jv-club-compare__table td svg {
	width: auto;
	height: 16px;
}

.jv-club-compare__table td svg[aria-hidden] {
}

.jv-club-compare__table td:not(:first-child) {
	color: var(--jv-color-price-muted);
}

.jv-club-faqs {
	max-width: 780px;
	margin: 0 auto 72px;
}

.jv-club-faqs__inner {
	margin-top: 24px;
}

.jv-club-cta-final {
	background: var(--jv-color-canvas);
	padding: 64px 0;
	text-align: center;
	border-top: 1px solid var(--jv-color-border);
}

.jv-club-cta-final h2 {
	font-size: 28px;
	margin: 0 0 12px;
	color: var(--jv-color-ink);
}

.jv-club-cta-final p {
	margin: 0 0 24px;
	color: var(--jv-color-price-muted);
}

@media (max-width: 900px) {
	.jv-club-tiers {
		grid-template-columns: 1fr;
		margin-top: -32px;
	}

	.jv-club-tier--featured {
		transform: none;
	}

	.jv-club-hero {
		padding: 56px 0 72px;
	}

	.jv-club-hero__title {
		font-size: 32px;
	}
}

/* =========================================================================
   PDP — precio estilo Amazon: "-XX% 119,99€" en una sola línea (descuento
   en rojo fino a la izquierda, precio grande a la derecha), "Precio
   recomendado: 129,99€ (i)" tachado y pequeño debajo con tooltip.
   ========================================================================= */

.jv-pdp-price {
	display: flex;
	flex-direction: column;
	gap: 4px;
}

/* Storefront ancla esta barra arriba por defecto (top:0, desliza desde
   arriba al hacer scroll) — se reancla abajo, como el patrón "Estás
   viendo: X" de Amazon, que vive pegado al borde inferior del viewport.
   Las animaciones nativas --slideInDown/--slideOutUp de Storefront usan
   translate3d(0,-100%,0) como estado "oculto" porque la barra nace
   anclada arriba (ocultarla es moverla hacia arriba, fuera de la
   pantalla). Al reanclarla abajo, ese mismo -100% la sube DENTRO del
   viewport en vez de sacarla, dejándola siempre visible. Se sobreescriben
   los propios keyframes con nombres propios que ocultan hacia ABAJO
   (translateY(100%)), coherente con bottom:0. */
.storefront-sticky-add-to-cart {
	top: auto !important;
	bottom: 0 !important;
	box-shadow: none;
	transform: translate3d(0, 100%, 0);
}

@keyframes jvSlideInUpBar {
	from { transform: translate3d(0, 100%, 0); visibility: visible; }
	to { transform: translate3d(0, 0, 0); }
}

@keyframes jvSlideOutDownBar {
	from { transform: translate3d(0, 0, 0); }
	to { visibility: hidden; transform: translate3d(0, 100%, 0); }
}

.storefront-sticky-add-to-cart.storefront-sticky-add-to-cart--slideInDown {
	animation-name: jvSlideInUpBar;
}

.storefront-sticky-add-to-cart.storefront-sticky-add-to-cart--slideOutUp {
	animation-name: jvSlideOutDownBar;
}

.jv-sticky-bar__variations {
	display: flex;
	align-items: center;
	gap: 8px;
	flex-wrap: wrap;
}

.jv-sticky-bar__add-to-cart {
	white-space: nowrap;
}

@media (max-width: 700px) {
	.jv-sticky-bar__variations {
		width: 100%;
		justify-content: flex-end;
	}
}

/* El precio nativo de WooCommerce junto al selector de variante
   (.woocommerce-variation-price) queda oculto: ya se muestra el mismo dato
   arriba, en el bloque .jv-pdp-price estilo Amazon — mostrarlo dos veces es
   redundante. El resto de .woocommerce-variation (stock) sigue visible con
   normalidad. */
.woocommerce-variation-price {
	display: none;
}

/* .woocommerce-variation-description (WooCommerce rellena esto vía AJAX al
   seleccionar variante, found_variation — de ahí que apareciera con un
   pequeño retraso tras cargar la página, no en el HTML inicial) hace
   fallback a la descripción larga completa del producto cuando la
   variación en sí no tiene su propia descripción — que es el caso de
   prácticamente todo el catálogo. El resultado era el mismo texto de
   "Acerca de este producto" (jv_render_pdp_short_description(), más abajo
   en la misma columna) duplicado justo debajo del selector de variantes,
   sin ningún encabezado que lo explicara. */
.woocommerce-variation-description {
	display: none;
}

.jv-pdp-price__sale-row {
	display: flex;
	align-items: baseline;
	gap: 10px;
}

/* Amazon usa un peso de fuente FINO para el "-XX %" (mucho más ligero que
   el precio grande de al lado) — antes llevaba font-weight: 600 igual de
   pesado que el precio, perdiendo la jerarquía visual de la referencia. */
.jv-pdp-price__percentage {
	font-family: var(--jv-font-sans);
	font-weight: 300;
	font-size: 22px;
	color: var(--jv-color-sale);
	align-self: center;
}

.jv-pdp-price__sale {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 32px;
	color: var(--jv-color-ink);
}

/* Estilo Amazon (ver captura de referencia): la parte entera del precio a
   tamaño completo con un peso medio (no tan grueso como un titular), los
   decimales + símbolo € en tamaño mucho más reducido y peso normal — ni la
   parte entera ni los decimales llevan el mismo grosor "extra bold" que se
   usaba antes, que hacía el número más pesado visualmente que en Amazon.
   Ver jv_format_price_amazon_style() en inc/sale-badge.php. */
.jv-amazon-price {
	display: inline-flex;
	align-items: flex-start;
}

.jv-amazon-price__decimals {
	font-size: .45em;
	font-weight: 300;
	margin-top: .1em;
}

.jv-pdp-price__regular-row {
	display: flex;
	align-items: center;
	gap: 6px;
	font-size: 14px;
	color: var(--jv-color-price-muted);
}

.jv-pdp-price__regular-label {
	color: var(--jv-color-price-muted);
}

.jv-pdp-price__regular {
	color: var(--jv-color-price-muted);
	text-decoration: line-through;
}

.jv-pdp-price__info {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	position: relative;
	width: 18px;
	height: 18px;
	padding: 0;
	background: none;
	border: none;
	color: var(--jv-color-price-muted);
	cursor: pointer;
}

.jv-pdp-price__info .jv-icon {
	width: auto;
	height: 16px;
	fill: currentColor;
}

.jv-pdp-price__info:hover,
.jv-pdp-price__info:focus {
	color: var(--jv-color-forest);
}

.jv-pdp-price__tooltip {
	display: none;
	position: absolute;
	bottom: calc(100% + 8px);
	left: 50%;
	transform: translateX(-50%);
	width: 260px;
	background: var(--jv-color-ink);
	color: #fff;
	font-size: 12.5px;
	line-height: 1.5;
	font-weight: 300;
	text-align: left;
	padding: 12px 14px;
	border-radius: var(--jv-radius-control);
	box-shadow: none;
	z-index: 10;
}

.jv-pdp-price__info:hover .jv-pdp-price__tooltip,
.jv-pdp-price__info:focus .jv-pdp-price__tooltip {
	display: block;
}

/* =========================================================================
   PDP — pastillas de confianza como tarjetas individuales bien encuadradas
   ========================================================================= */

.jv-trust-badges {
	display: grid;
	grid-template-columns: repeat(3, 1fr);
	gap: 12px;
	margin: 20px 0;
}

.jv-trust-badge {
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	padding: 18px 16px;
	display: flex;
	flex-direction: column;
	align-items: center;
	text-align: center;
	gap: 8px;
}

.jv-trust-badge__icon {
	width: auto;
	height: 24px;
	fill: var(--jv-color-forest);
	flex-shrink: 0;
}

.jv-trust-badge__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
}

.jv-trust-badge__body strong {
	font-size: 13.5px;
	color: var(--jv-color-ink);
}

/* Verde de marca y no el gris secundario: estas pastillas van sobre panel verde
   claro (ver .jv-trust-badge mas abajo) y ahi el gris #5c6b62 da 3.42:1, por
   debajo del 4.5 que pide AA. En verde oscuro son 5.30:1. La jerarquia con el
   titulo la siguen marcando el tamano y el peso, no el color. */
.jv-trust-badge__body span {
	font-size: 12px;
	color: var(--jv-color-forest);
}

.jv-trust-payment-methods__list {
	list-style: none;
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 8px;
	margin: 0 0 20px;
	padding: 0;
}

.jv-trust-payment-methods__list li {
	font-size: 12px;
	font-weight: 600;
	color: var(--jv-color-price-muted);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-pill);
	padding: 5px 14px;
}

@media (max-width: 600px) {
	.jv-trust-badges {
		grid-template-columns: 1fr;
	}
}

/* =========================================================================
   Valoraciones — estrellas doradas en vez del morado por defecto de
   WooCommerce (#stars/star-rating usa una fuente icónica con color propio).
   ========================================================================= */

#respond #rating,
.comment-form-rating .stars a,
p.stars a {
	color: var(--jv-color-forest) !important;
}

.woocommerce div.product .woocommerce-tabs ul.tabs li,
.star-rating,
.comment-form-rating .stars a,
p.stars a::before {
	color: var(--jv-color-forest);
}

.woocommerce #reviews #comments ol.commentlist li .comment-text .star-rating,
.woocommerce .star-rating span,
.star-rating span::before {
	color: var(--jv-color-forest) !important;
}

.comment-form-rating .stars a:before,
.comment-form-rating .stars a.active:before {
	color: var(--jv-color-forest) !important;
}

/* =========================================================================
   "Acerca de este producto" — descripción corta en la columna central de la
   PDP, entre la ficha técnica y el buybox. Ver jv_render_pdp_short_description
   en inc/pdp-layout.php.
   ========================================================================= */

.jv-pdp-short-desc {
	margin: 20px 0;
	padding-top: 20px;
	border-top: 1px solid var(--jv-color-border);
}

.jv-pdp-short-desc__heading {
	font-family: var(--jv-font-sans);
	font-size: 16px;
	font-weight: 600;
	color: var(--jv-color-ink);
	margin: 0 0 10px;
}

.jv-pdp-short-desc__body {
	font-size: 14px;
	line-height: 1.6;
	color: var(--jv-color-ink);
	display: -webkit-box;
	-webkit-box-orient: vertical;
	-webkit-line-clamp: 3;
	overflow: hidden;
}

.jv-pdp-short-desc__body.is-expanded {
	display: block;
	-webkit-line-clamp: unset;
	overflow: visible;
}

.jv-pdp-short-desc__body p {
	margin: 0 0 8px;
}

.jv-pdp-short-desc__toggle {
	margin-top: 8px;
	background: none;
	border: none;
	padding: 0;
	font-family: var(--jv-font-sans);
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
	cursor: pointer;
	text-decoration: underline;
}

/* Al reves que los demas: este ya venia subrayado de serie, asi que la senal
   de hover es QUITAR el subrayado. */
.jv-pdp-short-desc__toggle:hover {
	text-decoration: none;
}

/* =========================================================================
   Descripción enriquecida con datos del manual PDF: bloque de pastillas de
   specs técnicas + diagrama recortado + enlace de descarga del manual.
   ========================================================================= */

.jv-spec-pills-block {
	margin: 32px 0;
}

.jv-spec-pills-block__title {
	font-family: var(--jv-font-sans);
	font-size: 20px;
	font-weight: 600;
	margin: 0 0 16px;
	color: var(--jv-color-ink);
}

.jv-spec-pills {
	display: grid;
	grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
	gap: 10px;
	margin-bottom: 24px;
}

.jv-spec-pill {
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	padding: 12px 16px;
}

.jv-spec-pill--forest {
	background: rgba(15, 86, 55, .05);
	border-color: rgba(15, 86, 55, .14);
}

.jv-spec-pill__label {
	display: block;
	font-size: 11.5px;
	font-weight: 600;
	text-transform: uppercase;
	letter-spacing: .03em;
	color: var(--jv-color-price-muted);
	margin-bottom: 3px;
}

.jv-spec-pill__value {
	display: block;
	font-size: 14.5px;
	font-weight: 600;
	color: var(--jv-color-ink);
}

.jv-spec-diagram {
	margin: 24px 0;
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	border: 1px solid var(--jv-color-border);
}

.jv-spec-diagram img {
	display: block;
	width: 100%;
	height: auto;
}

.jv-spec-diagram__caption {
	display: block;
	padding: 10px 16px;
	background: var(--jv-color-canvas);
	font-size: 12.5px;
	color: var(--jv-color-price-muted);
	text-align: center;
}

.jv-spec-doc-link {
	display: inline-flex;
	align-items: center;
	gap: 8px;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	padding: 10px 18px;
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-ink);
	text-decoration: none;
}

.jv-spec-doc-link:hover {
	border-color: var(--jv-color-forest);
	color: var(--jv-color-forest);
}

.jv-spec-doc-link .jv-icon {
	width: auto;
	height: 18px;
	fill: var(--jv-color-forest);
}

@media (max-width: 600px) {
	.jv-spec-pills {
		grid-template-columns: repeat(2, 1fr);
	}
}

/* PDP móvil — tipografías y espacios a escala de amazon.es, no de
   escritorio. Los tamaños/paddings de título, precio y selector de
   variantes se pensaron para una columna central de ~500-600px de ancho
   real (ver .single-product div.product en @media min-width:1000px); sin
   ningún ajuste propio para móvil, esos mismos valores (32px de precio,
   24px de título, botones de variante con padding 10px 16px...) se veían
   desproporcionados en una pantalla de ~360-400px de ancho.
   Este bloque vive DELIBERADAMENTE al final del archivo: reglas de igual
   especificidad (ej. .jv-pdp-price__sale definida más arriba, fuera de
   cualquier media query, con font-size:32px) ganan por orden de aparición
   cuando ambas aplican a la vez — un intento anterior de este mismo ajuste,
   colocado más arriba en el archivo, perdía silenciosamente contra esa
   regla posterior de desktop pese a estar dentro de un @media que sí
   coincidía. Ponerlo al final garantiza que gane sin depender de subir la
   especificidad de cada selector uno a uno. */
@media (max-width: 600px) {
	/* No solo ".summary .product_title" — jv_pdp_mobile_reorder_script()
	   (inc/pdp-layout.php) mueve el <h1> fuera de .summary hacia
	   .jv-pdp-mobile-header en este mismo ancho de pantalla, así que el
	   selector original dejaba de aplicar justo cuando más falta hacía. */
	.single-product div.product .product_title.entry-title {
		font-size: 19px;
		line-height: 1.3;
		margin-bottom: 2px;
	}

	.jv-pdp-brand__link {
		font-size: 12.5px;
	}

	.jv-pdp-price__sale {
		font-size: 24px;
	}

	.jv-pdp-price__percentage {
		font-size: 17px;
	}

	.jv-pdp-price__regular-row {
		font-size: 12.5px;
	}

	.jv-pdp-divider {
		margin: 10px 0;
	}

	.jv-variation-btn {
		padding: 7px 12px;
		gap: 2px;
	}

	.jv-variation-btn__label {
		font-size: 13px;
	}

	.jv-variation-btn__price {
		font-size: 11px;
	}

	/* wc_price() de WooCommerce trae su propio tamaño de fuente en los
	   <span class="woocommerce-Price-amount">, que no hereda el font-size
	   más pequeño puesto arriba en .jv-variation-btn__price — hay que
	   fijarlo explícitamente en el span real donde vive el número. */
	.jv-variation-btn__price .woocommerce-Price-amount {
		font-size: 11px;
	}

	.jv-variation-buttons {
		gap: 6px;
	}

	.jv-pdp-buybox {
		padding: 14px;
	}

	.jv-pdp-buybox__heading {
		font-size: 13px;
	}

	.jv-pdp-buybox__price.jv-amazon-price {
		font-size: 22px;
	}
}

/* =========================================================================
   Toast "Añadido a la cesta" — ver inc/cart-toast.php. El enlace nativo de
   WooCommerce (a.added_to_cart.wc-forward) queda oculto: se sigue
   inyectando en el DOM (WooCommerce lo necesita para su propio JS interno),
   pero la notificación real que ve el usuario es este toast fijo arriba de
   la página, no ese enlace suelto dentro de la tarjeta de producto que
   antes empujaba el layout de la cuadrícula.
   ========================================================================= */

a.added_to_cart.wc-forward {
	display: none !important;
}

.jv-cart-toast {
	position: fixed;
	top: 16px;
	left: 50%;
	transform: translateX(-50%) translateY(-140%);
	z-index: 200;
	width: 100%;
	max-width: 480px;
	padding: 0 16px;
	pointer-events: none;
	opacity: 0;
	transition: transform .25s ease, opacity .25s ease;
}

.jv-cart-toast.is-visible {
	transform: translateX(-50%) translateY(0);
	opacity: 1;
	pointer-events: auto;
}

.jv-cart-toast__inner {
	position: relative;
	display: flex;
	align-items: center;
	gap: 12px;
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	box-shadow: none;
	padding: 14px 40px 14px 16px;
}

.jv-cart-toast__check {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	height: 28px;
	flex-shrink: 0;
	border-radius: 50%;
	background: var(--jv-color-selected);
	color: #ffffff;
}

.jv-cart-toast__check .jv-icon {
	width: auto;
	height: 16px;
}

.jv-cart-toast__media {
	flex-shrink: 0;
	width: 44px;
	height: 44px;
	border-radius: var(--jv-radius-control);
	overflow: hidden;
	background: var(--jv-color-canvas);
}

.jv-cart-toast__media img {
	width: 100%;
	height: 100%;
	object-fit: contain;
}

.jv-cart-toast__body {
	display: flex;
	flex-direction: column;
	gap: 2px;
	min-width: 0;
	flex: 1;
}

.jv-cart-toast__title {
	font-family: var(--jv-font-sans);
	font-weight: 600;
	font-size: 13px;
	color: var(--jv-color-ink);
}

.jv-cart-toast__product {
	font-size: 12.5px;
	color: var(--jv-color-price-muted);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.jv-cart-toast__actions {
	display: flex;
	flex-direction: column;
	gap: 6px;
	flex-shrink: 0;
}

.jv-cart-toast__view,
.jv-cart-toast__checkout {
	font-family: var(--jv-font-sans);
	font-size: 12px;
	font-weight: 600;
	text-align: center;
	white-space: nowrap;
	text-decoration: none;
	border-radius: var(--jv-radius-control);
	padding: 6px 12px;
}

.jv-cart-toast__view {
	color: var(--jv-color-forest);
	background: none;
	border: 1px solid var(--jv-color-border);
}

.jv-cart-toast__checkout.button.alt {
	background: var(--jv-color-selected);
	border-color: var(--jv-color-selected);
	color: #ffffff;
	padding: 6px 12px;
}

.jv-cart-toast__close {
	position: absolute;
	top: 8px;
	right: 8px;
	background: none;
	border: none;
	padding: 4px;
	line-height: 0;
	color: var(--jv-color-price-muted);
	cursor: pointer;
}

.jv-cart-toast__close .jv-icon {
	width: auto;
	height: 14px;
}

@media (max-width: 600px) {
	.jv-cart-toast {
		top: 8px;
		max-width: none;
		padding: 0 8px;
	}

	.jv-cart-toast__inner {
		padding: 12px 36px 12px 12px;
		gap: 8px;
	}

	.jv-cart-toast__actions {
		flex-direction: column;
	}

	.jv-cart-toast__title {
		font-size: 12px;
	}

	.jv-cart-toast__product {
		font-size: 11.5px;
	}
}

/* Selector de formato dentro de la barra sticky inferior nativa de
   Storefront (storefront_sticky_single_add_to_cart) — ver
   jv_sticky_add_to_cart_variations_script en inc/pdp-layout.php, que
   sustituye ahí el enlace "Seleccionar opciones" por estos botones. Más
   compacto que en la columna central (mismo criterio que el resto de
   copias de .jv-variation-buttons en esta ficha): con muchas variantes,
   flex-wrap deja que caigan a una segunda línea en vez de desbordar la
   barra o encogerse ilegibles. */
.jv-sticky-bar__variations {
	display: flex;
	flex-wrap: wrap;
	justify-content: flex-end;
	gap: 6px;
	margin-left: auto;
	max-width: 60%;
}

.jv-sticky-bar__variations .jv-variation-btn {
	padding: 6px 10px;
	font-size: 12px;
}

@media (max-width: 800px) {
	.jv-sticky-bar__variations {
		max-width: 100%;
		justify-content: flex-start;
	}
}

/* ============================================================
   Contenido estructurado del pipeline de IA
   (inc/jv-content-renderer.php). Acento verde, secciones con
   cabecera, imagen a media columna emparejada con texto.
   ============================================================ */

.jv-structured-content {
	display: flex;
	flex-direction: column;
	gap: 28px;
}

/* Sección sin borde ni tarjeta: aspecto editorial y limpio. La separación
   entre secciones la dan el espacio (gap) y la línea inferior de la cabecera. */
.jv-cs {
	border: 0;
	border-radius: 0;
	overflow: hidden;
	background: none;
	clear: both; /* una sección nunca invade el float de la anterior */
}

/* Cabecera de sección: solo texto, SIN banda de color de fondo (queda más
   editorial y menos "plantilla"). Una fina línea inferior separa del contenido. */
.jv-cs__head {
	margin: 0 0 16px;
	padding: 0 0 12px;
	background: none;
	border-bottom: 1px solid var(--jv-color-border);
	font-family: var(--jv-font-sans);
	font-size: 18px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-cs__body {
	padding: 0;
}

.jv-content-prose {
	color: var(--jv-color-ink);
	line-height: 1.7;
}
.jv-content-prose p { margin: 0 0 12px; }
.jv-content-prose p:last-child { margin-bottom: 0; }
/* Limpia el flotado al final de la prosa para que la sección no colapse. */
.jv-content-prose::after { content: ""; display: block; clear: both; }

/* Imagen FLOTADA dentro de la prosa: el texto la rodea y continúa debajo
   cuando es más largo (sin huecos ni estirar la imagen). En móvil no flota:
   ocupa el ancho y el texto va debajo. */
.jv-cs-float {
	margin: 4px 0 12px;
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	overflow: hidden;
	max-width: 100%;
}
.jv-cs-float img { display: block; width: 100%; height: auto; }

.jv-cs-image--full {
	margin: 0;
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-card);
	overflow: hidden;
}
.jv-cs-image--full img { display: block; width: 100%; height: auto; }

/* Beneficios: check verde + título y texto en líneas separadas. */
.jv-benefit-grid {
	list-style: none;
	margin: 0;
	padding: 0;
	display: grid;
	grid-template-columns: 1fr;
	gap: 14px;
}

.jv-benefit {
	display: flex;
	gap: 10px;
	align-items: flex-start;
	list-style: none;
}
.jv-benefit::marker { content: ""; }

.jv-benefit__icon {
	flex: 0 0 auto;
	width: auto;
	height: 20px;
	margin-top: 2px;
	color: var(--jv-color-selected);
	background: rgba(76,175,110,.12);
	border-radius: 50%;
	padding: 3px;
}

.jv-benefit__body {
	display: flex;
	flex-direction: column;
	gap: 3px;
	min-width: 0;
}

.jv-benefit__title {
	display: block;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-benefit__text {
	display: block;
	color: var(--jv-color-ink);
	line-height: 1.5;
}

/* Pastillas de datos decisivos. */
.jv-chip--accent {
	background: linear-gradient(180deg, rgba(15, 86, 55, .06), var(--jv-color-canvas));
	border-color: rgba(15, 86, 55, .25);
}
.jv-chip--accent .jv-chip__value { font-weight: 600; }

/* Split / encaje a dos columnas. */
.jv-split-grid,
.jv-fit-grid {
	display: grid;
	grid-template-columns: 1fr;
	gap: 14px;
}

.jv-split-col,
.jv-fit-col {
	padding: 18px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
	line-height: 1.55;
}
/* El título va pegado al padding superior: sin margen ni espacio extra propio
   del <h3> del tema, para que respire igual que los otros tres lados. */
.jv-fit-col__title {
	margin: 0 0 10px !important;
	padding-top: 0 !important;
	line-height: 1.2;
}
.jv-fit-col__title::before { content: none !important; }

.jv-split-col__title,
.jv-fit-col__title {
	margin: 0 0 6px;
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-forest);
}


/* Pasos numerados. */
.jv-step-list {
	list-style: none;
	margin: 0;
	padding: 0;
	display: flex;
	flex-direction: column;
	gap: 14px;
}

.jv-step {
	display: flex;
	gap: 12px;
	align-items: flex-start;
}

.jv-step__num {
	flex: 0 0 auto;
	width: 26px;
	height: 26px;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	background: var(--jv-color-forest);
	color: #fff;
	border-radius: 50%;
	font-size: 13px;
	font-weight: 600;
}

.jv-step__body { display: flex; flex-direction: column; gap: 2px; padding-top: 2px; min-width: 0; }
.jv-step__title { display: block; font-weight: 600; color: var(--jv-color-forest); }
.jv-step__text { display: block; color: var(--jv-color-ink); line-height: 1.55; }

/* Aviso destacado. */
.jv-content-notice {
	display: flex;
	gap: 12px;
	align-items: flex-start;
	padding: 14px 16px;
	background: rgba(15, 86, 55, .06);
	border: 1px solid rgba(15, 86, 55, .25);
	border-left: 4px solid var(--jv-color-forest);
	border-radius: var(--jv-radius-control);
	line-height: 1.55;
}
.jv-content-notice__icon { flex: 0 0 auto; width: 20px; height: 20px; margin-top: 1px; color: var(--jv-color-forest); }
.jv-content-notice__title { color: var(--jv-color-forest); }

/* Comparativa de variantes: scroll horizontal, 1ª columna fija. */
.jv-compare-wrap {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border: 1px solid var(--jv-color-border);
	border-radius: var(--jv-radius-control);
}
.jv-compare-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.jv-compare-table th, .jv-compare-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--jv-color-border); white-space: nowrap; }
.jv-compare-table thead th { background: rgba(15, 86, 55, .08); color: var(--jv-color-forest); font-weight: 600; }
.jv-compare-table tbody tr:nth-child(even) td,
.jv-compare-table tbody tr:nth-child(even) .jv-compare-table__rowhead { background: var(--jv-color-canvas); }
.jv-compare-table__rowhead { position: sticky; left: 0; background: var(--jv-color-surface); font-weight: 600; color: var(--jv-color-ink); z-index: 1; }
.jv-compare-table thead .jv-compare-table__rowhead { background: rgba(15, 86, 55, .08); }

/* Bloques de conocimiento por familia (VPD, etc.). */
.jv-knowledge-block__intro { margin: 0 0 12px; max-width: 760px; line-height: 1.6; color: var(--jv-color-ink); }
.jv-knowledge-block__source { margin-top: 12px; max-width: 760px; font-size: 13px; color: var(--jv-color-price-muted); line-height: 1.6; }
.jv-knowledge-block__table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid var(--jv-color-border); border-radius: var(--jv-radius-control); }
.jv-knowledge-table { width: 100%; border-collapse: collapse; font-size: 13px; font-variant-numeric: tabular-nums; }
.jv-knowledge-table__caption { text-align: left; padding: 10px 14px 0; font-size: 12px; color: var(--jv-color-price-muted); }
.jv-knowledge-table th, .jv-knowledge-table td { text-align: left; padding: 10px 14px; border-bottom: 1px solid var(--jv-color-border); vertical-align: top; }
.jv-knowledge-table thead th { background: rgba(15, 86, 55, .08); color: var(--jv-color-forest); font-weight: 600; white-space: nowrap; }
.jv-knowledge-table tbody th[scope="row"] { font-weight: 600; color: var(--jv-color-forest); }
.jv-knowledge-table__note { display: block; margin-top: 3px; font-size: 12px; font-weight: 300; color: var(--jv-color-price-muted); white-space: normal; max-width: 260px; }

/* FAQ acordeón accesible. */
.jv-faq-item { border: 1px solid var(--jv-color-border); border-radius: var(--jv-radius-control); margin-bottom: 8px; background: var(--jv-color-surface); }
.jv-faq-item:last-child { margin-bottom: 0; }
.jv-faq-item__q { cursor: pointer; padding: 13px 44px 13px 16px; font-weight: 600; color: var(--jv-color-ink); list-style: none; position: relative; }
.jv-faq-item__q::-webkit-details-marker { display: none; }
.jv-faq-item__q::after { content: ""; position: absolute; right: 16px; top: 50%; width: 8px; height: 8px; border-right: 2px solid var(--jv-color-forest); border-bottom: 2px solid var(--jv-color-forest); transform: translateY(-70%) rotate(45deg); transition: transform .2s ease; }
.jv-faq-item[open] .jv-faq-item__q::after { transform: translateY(-30%) rotate(-135deg); }
.jv-faq-item__a { padding: 0 16px 14px; line-height: 1.6; color: var(--jv-color-ink); }

@media (min-width: 768px) {
	.jv-benefit-grid { grid-template-columns: 1fr 1fr; }
	.jv-split-grid, .jv-fit-grid { grid-template-columns: 1fr 1fr; }
	/* Imagen flotada a media columna; el texto la rodea y sigue debajo. */
	.jv-cs-float { width: 42%; }
	.jv-cs-float--imgleft { float: left; margin-right: 22px; }
	.jv-cs-float--imgright { float: right; margin-left: 22px; }
	/* La imagen flotada no debe ser más alta que un tope razonable: si lo es,
	   se recorta con object-fit para no dejar una columna de hueco enorme. */
	.jv-cs-float img { max-height: 340px; object-fit: contain; }
}

@media (prefers-reduced-motion: reduce) {
	.jv-faq-item__q::after { transition: none; }
}

/* Cuerpo principal de la descripción estructurada (description_html): prosa
   continua con H2 internos como subtítulos verdes. */
.jv-cs--body .jv-cs__body { padding: 0; }
.jv-content-prose--body h2 {
	font-family: var(--jv-font-sans);
	font-size: 18px;
	font-weight: 600;
	color: var(--jv-color-forest);
	margin: 24px 0 10px;
	scroll-margin-top: 90px;
}
.jv-content-prose--body h2:first-child { margin-top: 0; }
.jv-content-prose--body h3 {
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-forest);
	margin: 18px 0 8px;
}
.jv-content-prose--body p { margin: 0 0 14px; line-height: 1.7; }
.jv-content-prose--body ul,
.jv-content-prose--body ol { margin: 0 0 14px; }

/* ===== Imagenes sin redondeo =====
   El redondeo de imagenes no estaba en un sitio, sino repartido en una decena
   de reglas con selectores de clase (.jv-blog-card img, la galeria de la PDP,
   las miniaturas del mini-carrito, los __media de las tarjetas de categoria...),
   todas con especificidad 0-2-0 o mayor. Un `img { border-radius: 0 }` suelto
   es 0-0-1 y no le gana a ninguna: se quedaria sin efecto. De ahi el
   !important, que ademas concentra la decision en un solo bloque en vez de
   editar diez reglas y perder el rastro de por que cada una vale 0.

   El alcance es la imagen en si: los <img> y los contenedores cuyo contenido
   ES la imagen (los __media, que la pintan como background-image). Tarjetas,
   botones, paneles y desplegables conservan su radio: si aqui se colara
   .jv-category-tile o .jv-blog-card, se estaria cuadrando la tarjeta entera,
   que no es lo pedido. */
img,
.jv-category-tile__media,
.jv-subcategory-rail__media,
.jv-live-search-item__media,
.jv-cart-toast__media {
	border-radius: 0 !important;
}

/* =============================================================
   Pasada nordica — superficies, foco y jerarquia
   Ver el bloque :root para las dos decisiones que gobiernan esto:
   radios a 0 y sombras fuera.
   ============================================================= */

/* ----- Foco visible -----
   El tema tenia 2 reglas :focus-visible y un solo `outline` en todo el
   archivo: navegando con teclado no se sabia donde estabas. Se declara un
   anillo unico para todo lo interactivo. :focus-visible (y no :focus) para
   que no aparezca al hacer clic con raton, solo al tabular. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
select:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
	outline: 2px solid var(--jv-color-forest);
	outline-offset: 2px;
}

/* Sobre fondo verde oscuro el anillo verde no se veria. */
.jv-home-band--forest a:focus-visible,
.jv-home-band--forest button:focus-visible,
.jv-top-bar a:focus-visible {
	outline-color: var(--jv-color-mint);
}

/* ----- Ritmo de bandas -----
   La home ya alternaba bandas (--surface blanca, --canvas casi blanca,
   --forest verde oscuro), pero --canvas y --surface se distinguian apenas.
   --canvas pasa al verde claro de marca: el ritmo queda blanco / verde /
   blanco / verde / verde oscuro, que es el banding tipico nordico y ademas
   mete el color de marca en el fondo, no solo en los detalles. */
.jv-home-band--canvas {
	background: var(--jv-color-mint);
}

/* Dentro del verde claro, el gris secundario da 3.42:1 y no llega a AA:
   el texto de apoyo pasa a tinta (9.45:1) y los bordes al verde medio, que
   sobre #a7d4b9 si se ve. */
/* :not(.jv-hero__subhead) — el hero vive DENTRO de esta banda pero su texto no
   se apoya en el verde claro, sino en su propio panel oscuro
   (rgba(20,33,22,.78)) sobre la foto. Sin excluirlo, esta regla lo pintaba de
   tinta y lo dejaba casi ilegible contra ese panel. */
.jv-home-band--canvas .jv-price-muted,
.jv-home-band--canvas .jv-section__sub,
.jv-home-band--canvas p:not(.jv-hero__subhead) {
	color: var(--jv-color-ink);
}

.jv-home-band--canvas .jv-category-tile,
.jv-home-band--canvas .jv-brand-tile,
.jv-home-band--canvas .jv-subcategory-rail__media {
	border-color: var(--jv-color-border-on-mint);
}

/* ----- Jerarquia tipografica -----
   Poppins 600 a tamano grande necesita el tracking cerrado: con el espaciado
   por defecto los titulares se ven blandos y pierden la contundencia que pide
   el estilo. Solo a partir de 28px; por debajo el tracking negativo empieza a
   comerse la legibilidad. */
h1, h2,
.jv-section__title,
.jv-category-hero__title {
	letter-spacing: -0.02em;
}

/* ----- Superficies didacticas -----
   Los badges de confianza (envio, pago, devolucion) y la ficha tecnica son
   los bloques que EXPLICAN, no los que decoran. Pasan a panel verde claro con
   icono en verde oscuro: se leen como una unidad informativa y no como un
   borde mas en una pagina llena de bordes. */
.jv-trust-badge {
	background: var(--jv-color-mint);
	border: 1px solid var(--jv-color-border-on-mint);
	color: var(--jv-color-ink);
}

.jv-trust-badge .jv-icon {
	color: var(--jv-color-forest);
}

/* La columna de etiquetas de la ficha tecnica en verde claro convierte la
   tabla en una lectura de dos tiempos (que se mide / cuanto mide) en vez de
   una reja uniforme de celdas. */
.woocommerce-product-attributes-item__label,
.jv-pdp-specs th,
.shop_attributes th {
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
	font-weight: 600;
}

/* ----- Restos de terceros -----
   El resto del sitio ya es caja recta y sin sombra, pero Storefront, el
   slider de precio de jQuery UI y la galeria de WooCommerce traen su propio
   radio y su propia sombra interior. Se aplanan aqui, al final del archivo,
   porque son reglas ajenas: agrupadas en un solo bloque se ve de un vistazo
   que no son decisiones nuestras sino correcciones sobre codigo de fuera.
   La sombra interior de los campos es la mas visible: aparece en todos los
   formularios del sitio, incluido el buscador del header. */
input[type="text"],
input[type="email"],
input[type="tel"],
input[type="url"],
input[type="password"],
input[type="search"],
input[type="number"],
.search-field,
select,
textarea {
	box-shadow: none;
	border-radius: 0;
}

button.menu-toggle,
a.woocommerce-product-gallery__trigger {
	border-radius: 0;
	color: var(--jv-color-forest);
}

/* Textos que Storefront/WooCommerce seguian pintando en gris (#333, #636363,
   #6d6d6d, #43454b...): la paleta es verde oscuro / blanco / verde claro y
   no admite grises. Los selectores llevan especificidad extra a proposito:
   los CSS de WooCommerce y de los bloques cargan despues que el del tema y,
   a igualdad de especificidad, ganarian ellos. */
.screen-reader-text,
.woocommerce-pagination ul.page-numbers li a.page-numbers,
.woocommerce-pagination ul.page-numbers li span.page-numbers.current,
.storefront-product-pagination__title,
.storefront-sticky-add-to-cart .storefront-sticky-add-to-cart__content-title,
.storefront-sticky-add-to-cart .storefront-sticky-add-to-cart__content-price,
.wc-block-grid__products .wc-block-grid__product .wc-block-grid__product-title,
.wc-block-grid__products .wc-block-grid__product .wc-block-grid__product-price,
.wc-block-grid__products .wc-block-grid__product .wc-block-grid__product-onsale,
.wc-block-grid__products .wc-block-grid__product .wp-block-button .wp-block-button__link {
	color: var(--jv-color-forest);
}

/* Filtro de precio (jQuery UI): la barra y los tiradores venian con radio
   redondo propio del widget. */
.price_slider,
.price_slider .ui-slider-range,
.price_slider .ui-slider-handle,
.ui-slider .ui-slider-range,
.ui-slider .ui-slider-handle {
	border-radius: 0;
}

/* ----- Hero de la home: jerarquia a dos colores -----
   Solo el titular va en blanco. El resto del texto del slide (antetitulo y
   entradilla) pasa al verde claro de marca, de modo que la jerarquia se lee
   por COLOR y no solo por tamano: blanco = lo que hay que leer si solo lees
   una cosa; verde claro = contexto.
   Contraste comprobado contra el peor caso posible, que es el panel
   rgba(20,33,22,.78) sobre una zona clara de la foto: 4.96:1, por encima de
   AA. Sobre foto media sube a 7.64:1. Si algun dia se baja la opacidad del
   panel por debajo de .78, hay que rehacer esta cuenta. */
/* Tres clases (0-3-0) a proposito. La regla de contraste de la banda verde es
   `.jv-home-band--canvas p:not(.jv-hero__subhead)`, y ese :not() NO es
   gratis: aporta la especificidad de su argumento, asi que la regla vale
   0-2-1 y no 0-2-0. Con solo `.jv-hero .jv-hero__eyebrow` (0-2-0) el
   antetitulo seguia saliendo en tinta sobre el panel oscuro. */
.jv-home-band .jv-hero .jv-hero__eyebrow,
.jv-home-band .jv-hero .jv-hero__subhead {
	color: var(--jv-color-mint);
}

/* ----- Ultimos restos de terceros -----
   Estos necesitan mas especificidad que el bloque anterior porque WooCommerce
   los declara con selectores largos (hasta 0-4-0). */
.woocommerce .widget_price_filter .price_slider,
.woocommerce .widget_price_filter .ui-slider .ui-slider-range,
.woocommerce .widget_price_filter .ui-slider .ui-slider-handle,
.widget_price_filter .price_slider,
.widget_price_filter .ui-slider-range,
.widget_price_filter .ui-slider-handle {
	border-radius: 0;
}

.woocommerce div.product .woocommerce-product-gallery .woocommerce-product-gallery__trigger {
	border-radius: 0;
	box-shadow: none;
}

/* Flechas "producto anterior / siguiente" de Storefront. */
.storefront-product-pagination a {
	box-shadow: none;
}

/* Placeholders de carga de WooCommerce Blocks (carrito y checkout): se ven
   un instante mientras carga el bloque, pero con esquina redonda desentonan
   con el resto. */
.wc-block-components-skeleton__element {
	border-radius: 0;
}

/* En la home el header se apoya directamente sobre la foto del hero, y su
   borde inferior quedaba como una linea de 1px cruzando la imagen. En el
   resto de plantillas ese borde si hace falta, porque debajo hay fondo claro
   y sin el el header se disolveria en la pagina. */
.home .site-header,
.page-template-front-page .site-header {
	border-bottom: none;
}

/* =============================================================
   Franja compacta al hacer scroll
   La clase la pone jv_header_compact_script() en <html> (inc/mega-menu.php).

   Encoge las DOS cosas que definen el alto de la franja —el logo y el campo de
   busqueda—, porque la franja mide el mayor de los dos: bajando solo el logo se
   quedaba clavada en los 46px del buscador.

   El boton "Todo" no se toca. Mientras existio el divisor de la fila de abajo
   su ancho estaba atado al alto del logo, y encogerlo lo dejaba sin sitio para
   el icono y el texto a la vez; al quitar el divisor el boton volvio a medir lo
   que mide su contenido, asi que aqui se queda entero.
   ============================================================= */

:root.jv-compacto {
	--jv-logo-height: 40px;
	/* --jv-logo-width cuelga de este valor y se recalcula solo: por eso la clase
	   va en :root y no en <body> (el var() de una custom property se sustituye
	   donde se DECLARA, asi que cambiar el alto mas abajo lo dejaria congelado
	   con el valor de reposo y la rejilla del header no seguiria al logo). */

	/* El header pegado mide menos en compacto, y es el estado en el que de
	   verdad importa: el scroll ya esta hecho. Medido, igual que el de reposo. */
	--jv-header-height: 96px;
}

@media (max-width: 1279px) {
	:root.jv-compacto {
		--jv-header-height: 78px;
	}
}

/* Por debajo de 600px el logo se dimensiona por ANCHO (ver el media query del
   header), asi que el alto del token no le afecta y la franja solo baja por el
   buscador. */
@media (max-width: 600px) {
	:root.jv-compacto {
		--jv-header-height: 112px;
	}
}

:root.jv-compacto .site-header .site-branding {
	padding: 3px 0;
}

/* Campo de busqueda: 46 -> 32px. Las cuatro direcciones van explicitas porque
   el padding NO es simetrico: 34px a la izquierda dejan libre la lupa (un
   ::before en left:15px y 11.7px de ancho) y 40px a la derecha, la X de borrar.
   La primera version puso `padding: 5px 14px` y el atajo se llevo por delante
   esos dos huecos: el placeholder se metia debajo de la lupa. */
:root.jv-compacto .jv-header-search--persistent .search-field {
	padding: 5px 40px 5px 34px;
	font-size: 12.5px;
}

.site-header .site-branding,
.jv-header-search--persistent .search-field {
	transition: padding .22s ease, font-size .22s ease;
}

/* Quien pide menos movimiento recibe el mismo cambio de tamano, de golpe. */
@media (prefers-reduced-motion: reduce) {
	.site-header .site-branding .jv-site-logo,
	.site-header .site-branding,
	.jv-header-search--persistent .search-field {
		transition: none;
	}
}


/* =============================================================
   Buscador del header: lupa centrada y boton de borrar
   ============================================================= */

/* La lupa es un ::before con la webfont "Font Awesome 5 Free" que NO pone este
   tema, y venia con `top: 15px` fijo. Con el campo de 46.3px quedaba centrada
   de casualidad (centro real 23.15 contra 22.5 de la lupa); en cuanto el campo
   encoge en el estado compacto se queda colgando abajo. Centrado de verdad, que
   ya no depende del alto. */
.jv-header-search--persistent form.woocommerce-product-search::before {
	top: 50%;
	transform: translateY(-50%);
}

/* Hueco a la derecha para la X. El selector tiene que ir DESPUES de
   `.woocommerce-product-search .search-field { padding: 10px 16px }` (misma
   especificidad, 0-2-0, gana el ultimo), por eso este bloque va al final. */
.jv-header-search--persistent .search-field {
	padding-right: 40px;
}

.jv-search-clear {
	position: absolute;
	top: 50%;
	right: 6px;
	transform: translateY(-50%);
	display: flex;
	align-items: center;
	justify-content: center;
	width: 32px;
	height: 28px;
	padding: 0;
	background: none;
	border: none;
	color: var(--jv-color-ink);
	cursor: pointer;
	opacity: .5;
	transition: opacity .15s ease;
}

/* Obligatorio: el atributo hidden funciona poniendo display:none desde la hoja
   del navegador, y el display:flex de arriba le gana. Sin esta linea la X se
   veria siempre, tambien con el campo vacio. */
.jv-search-clear[hidden] {
	display: none;
}

.jv-search-clear:hover,
.jv-search-clear:focus-visible {
	opacity: 1;
}

.jv-search-clear .jv-icon {
	width: auto;
	height: 13px;
}


/* =============================================================
   Botones sobre fondo verde oscuro
   Con un unico verde oscuro, un boton de marca sobre una superficie de marca
   es el mismo color contra si mismo: 1:1, invisible. Estas son las cuatro
   superficies verdes que existen de verdad (auditado sobre el DOM de la home,
   la ficha de servicio, el hub y el Club, no deducido del CSS): el hero de la
   home, la banda de servicios, el hero de ficha de servicio y su CTA final.
   Verde claro de fondo y texto verde oscuro = 5.30:1, pasa AA.
   ============================================================= */

.jv-hero a.button.alt,
.jv-hero .jv-hero__cta,
.jv-home-band--forest .button,
.jv-home-band--forest a.button.alt,
.jv-category-hero .button,
.jv-category-hero a.button.alt,
.jv-club-hero .button,
.jv-club-hero a.button.alt,
.jv-service-hero .button,
.jv-service-hero a.button.alt,
.jv-service-cta-final .button,
.jv-service-cta-final a.button.alt {
	background: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

/* Aqui el hover NO puede invertir a verde claro (ya lo es), asi que aclara al
   verde diluido. Sobre el, el texto verde oscuro sube de 5.30:1 a 7.99:1. */
.jv-hero a.button.alt:hover,
.jv-hero .jv-hero__cta:hover,
.jv-home-band--forest .button:hover,
.jv-home-band--forest a.button.alt:hover,
.jv-category-hero .button:hover,
.jv-category-hero a.button.alt:hover,
.jv-club-hero .button:hover,
.jv-club-hero a.button.alt:hover,
.jv-service-hero .button:hover,
.jv-service-hero a.button.alt:hover,
.jv-service-cta-final .button:hover,
.jv-service-cta-final a.button.alt:hover {
	background: var(--jv-color-mint-soft);
	border-color: var(--jv-color-mint-soft);
	color: var(--jv-color-forest);
}


/* =============================================================
   Hover de los <button> pelados
   Alcanza a los <button> que NO son .button (esos ya tienen su hover invertido
   con 0-2-0 y ganan a este 0-1-1): "Todo", flechas de carrusel, conmutador de
   vista, cierres de drawer y de aviso, preguntas del FAQ, filtros.

   El `color` no es decorativo. Sin el, cinco de estos botones quedaban
   ilegibles al pasar el raton, porque su texto no es verde oscuro: blanco sobre
   verde claro da 1.65:1 y el gris secundario 3.42:1, ambos por debajo del 4.5
   que pide AA. Sobre verde claro el unico texto valido es el verde de marca,
   que da 5.30:1.
   ============================================================= */

button:hover {
	background-color: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
}


/* =============================================================
   Paneles del mega-menú en pantallas medias (768-1023)
   Cada panel cuelga del <li> de SU categoría: centrado con left:50% +
   translateX(-50%), y el de "Más categorías" pegado con right:0. A partir de
   1024px eso cabe de sobra, pero por debajo un panel de 440-760px colgando de
   un <li> que está a la derecha se sale de la pantalla — medido a 768px: 187px
   fuera por la izquierda.
   Aquí el panel deja de colgar del <li> y se ancla a la fila entera
   (.jv-primary-navigation, position:relative), de borde a borde: ocupa el ancho
   de la fila, así que no puede salirse de la pantalla. El position:static del
   <li> es lo que traslada el anclaje.
   ============================================================= */

@media (max-width: 1023px) {
	.jv-mega-nav > .menu-item {
		position: static;
	}

	.jv-mega-panel,
	.jv-mega-item--more .jv-mega-panel--simple {
		/* Aqui el panel cuelga de la fila entera, y la fila ya acaba donde acaba
		   la banda: el desplazamiento del padding sobra. */
		top: 100%;
		left: 0;
		right: 0;
		width: auto;
		max-width: none;
		transform: none;
	}

	/* Aqui el panel ya no manda en su ancho —lo pone la fila—, asi que dos
	   columnas dejarian cada una en ~320px y el nombre mas largo (386px), que
	   va con nowrap, se saldria y lo recortaria el overflow del panel. Con una
	   sola columna, la columna ES la fila entera: ~658px a 768px de pantalla,
	   de sobra para una linea. */
	.main-navigation .jv-mega-panel .jv-mega-panel__list,
	.main-navigation .jv-mega-panel--wide .jv-mega-panel__list,
	.main-navigation .jv-mega-panel--simple .jv-mega-panel__list {
		columns: 1;
	}
}

/* =============================================================
   Rejilla de producto destacado de la home
   (ver front-page.php e inc/home-bestsellers.php)

   Esquema: 4 columnas x 3 filas, con el producto principal ocupando un bloque
   de 2x2 arriba a la derecha. Nueve productos por pestaña.

   Los bloques son CUADRADOS (aspect-ratio: 1) en vez del rectangulo vertical
   de la referencia, para que el lenguaje sea el mismo que el del resto del
   sitio. Eso hace que el grande cuadre solo: al ocupar 2 columnas mide
   2*columna + hueco de ancho, y al ocupar 2 filas mide exactamente lo mismo de
   alto, porque las filas las dimensionan los cuadrados pequenos. Si alguna vez
   se quiere el formato vertical de la referencia, es cambiar ese aspect-ratio.

   Separacion por BORDE y no por sombra ni por fondo gris: es el lenguaje plano
   del tema (radio 0, sin sombras, borde portante).
   ============================================================= */

.jv-top__head {
	max-width: 640px;
	margin: 0 auto 32px;
	text-align: center;
}

.jv-top__eyebrow {
	margin: 0 0 12px;
	font-family: var(--jv-font-sans);
	font-size: 13px;
	font-weight: 600;
	letter-spacing: .11em;
	text-transform: uppercase;
}

.jv-top__head .jv-section__title {
	margin-bottom: 14px;
}

.jv-top__intro {
	margin: 0;
	font-size: 16px;
	font-weight: 300;
	line-height: 1.6;
}

/* ----- Pestanas -----
   Rectangulos rectos, no pastillas: el tema tiene los cuatro tokens de radio a
   0 y una pastilla seria el unico elemento redondeado de la pagina. */
.jv-top__tabs {
	display: flex;
	justify-content: center;
	flex-wrap: wrap;
	gap: 8px;
	margin: 0 0 40px;
}

.jv-top__tab {
	appearance: none;
	min-height: 44px;
	padding: 10px 20px;
	border: 1px solid var(--jv-color-border);
	border-radius: 0;
	background: var(--jv-color-surface);
	color: var(--jv-color-ink);
	font-family: var(--jv-font-sans);
	font-size: 13.5px;
	font-weight: 600;
	line-height: 1.2;
	white-space: nowrap;
	cursor: pointer;
	transition: background-color 200ms ease, border-color 200ms ease, color 200ms ease;
}

.jv-top__tab:hover {
	border-color: var(--jv-color-forest);
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
}

.jv-top__tab.is-active,
.jv-top__tab[aria-selected="true"] {
	background: var(--jv-color-forest);
	border-color: var(--jv-color-forest);
	color: #ffffff;
}

/* ----- Rejilla ----- */
.jv-top__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0;
}

/* El atributo `hidden` no puede con un `display: grid` declarado por clase:
   sin esta regla las cuatro pestanas se pintarian una debajo de otra. */
.jv-top__grid[hidden] {
	display: none;
}

.jv-top__card--1   { grid-column: 1;          grid-row: 1; }
.jv-top__card--2   { grid-column: 2;          grid-row: 1; }
.jv-top__card--big { grid-column: 3 / span 2; grid-row: 1 / span 2; }
.jv-top__card--3   { grid-column: 1;          grid-row: 2; }
.jv-top__card--4   { grid-column: 2;          grid-row: 2; }
.jv-top__card--5   { grid-column: 1;          grid-row: 3; }
.jv-top__card--6   { grid-column: 2;          grid-row: 3; }
.jv-top__card--7   { grid-column: 3;          grid-row: 3; }
.jv-top__card--8   { grid-column: 4;          grid-row: 3; }

.jv-top__card {
	position: relative;
	display: flex;
	flex-direction: column;
	gap: 14px;
	aspect-ratio: 1;
	overflow: hidden;
	padding: 18px;
	border: 4px solid var(--jv-color-ink);
	margin: -2px;
	background: var(--jv-color-surface);
	color: var(--jv-color-ink);
	text-decoration: none;
	cursor: pointer;
	transition: border-color 220ms ease;
}

/* Sin border-color: el borde base ya es --jv-color-ink y --jv-color-forest es
   el MISMO #0f5637, asi que cambiarlo aqui no pintaba nada. La senal de hover
   son el zoom de la foto y el panel que sube. */
.jv-top__card:hover,
.jv-top__card:focus-visible {
	text-decoration: none;
}

/* El anillo global (2px verde, separado 2px) se dibuja FUERA del bloque, y
   como los bloques se solapan 4px para colapsar sus bordes, caia justo encima
   del borde verde del vecino: verde sobre verde, invisible en todos los
   bloques menos los del contorno de la rejilla. Metido hacia dentro cae sobre
   el blanco del propio bloque (8,7:1), dentro de su padding — funciona con los
   18px de escritorio y con los 12px de movil. */
.jv-top__card:focus-visible {
	outline-offset: -10px;
}

/* Hueco de la foto. Se lleva todo el alto que sobre despues del texto, que es
   lo que tiene medida fija (nombre recortado a dos lineas + precio). */
.jv-top__frame {
	position: relative;
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden;
}

/* contain y no cover: son fotos de producto sobre fondo blanco y hay que ver
   el producto entero, no un recorte. */
.jv-top__media {
	position: absolute;
	inset: 0;
	background-position: center center;
	background-repeat: no-repeat;
	background-size: contain;
	transform: scale(1);
	transition: transform 480ms cubic-bezier(.22, .61, .36, 1);
}

.jv-top__card:hover .jv-top__media,
.jv-top__card:focus-visible .jv-top__media {
	transform: scale(1.06);
}

/* La informacion que aparece al pasar el raton sube por encima de la foto, no
   por debajo del texto: el bloque es cuadrado y de medida fija, asi que
   anadir contenido al pie lo desbordaria. Es hermano de .jv-top__media y no
   hijo, o el scale del hover se lo llevaria tambien.
   max-height: 100% es el tope duro — descripciones largas recortan por abajo
   (el enlace) en vez de tapar toda la foto. */
.jv-top__reveal {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	max-height: 100%;
	padding: 12px 14px 14px;
	background: var(--jv-color-forest);
	color: #ffffff;
	transform: translateY(101%);
	transition: transform 320ms cubic-bezier(.22, .61, .36, 1);
}

.jv-top__card:hover .jv-top__reveal,
.jv-top__card:focus-visible .jv-top__reveal {
	transform: translateY(0);
}

.jv-top__desc {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin-bottom: 8px;
	font-size: 12.5px;
	font-weight: 300;
	line-height: 1.45;
	color: rgba(255, 255, 255, .9);
}

.jv-top__card--big .jv-top__desc {
	-webkit-line-clamp: 4;
	margin-bottom: 12px;
	font-size: 15px;
	line-height: 1.55;
}

.jv-top__cta {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	font-family: var(--jv-font-sans);
	font-size: 12.5px;
	font-weight: 600;
	color: var(--jv-color-mint);
}

.jv-top__card--big .jv-top__cta {
	font-size: 14px;
}

/* Los iconos son de relleno y su viewBox NO es cuadrado: se dimensionan por
   alto con width:auto, o cada uno sale de un tamano distinto. */
.jv-top__cta svg,
.jv-top__all svg {
	height: 11px;
	width: auto;
	fill: currentColor;
	transition: transform 240ms ease;
}

.jv-top__card:hover .jv-top__cta svg,
.jv-top__all:hover svg {
	transform: translateX(4px);
}

/* ----- Texto del bloque ----- */
.jv-top__body {
	display: flex;
	flex-direction: column;
	flex: 0 0 auto;
}

/* Rectangulo, no pastilla, igual que las pestanas. Verde oscuro sobre verde
   claro son 5,30:1; el naranja de la referencia no existe en esta paleta, asi
   que la etiqueta se distingue por caja y caja alta, no por color. */
.jv-top__badge {
	align-self: flex-start;
	margin-bottom: 8px;
	padding: 3px 7px;
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
	font-family: var(--jv-font-sans);
	font-size: 10.5px;
	font-weight: 600;
	letter-spacing: .09em;
	line-height: 1.2;
	text-transform: uppercase;
}

/* Dos lineas fijas: el alto del texto tiene que ser constante o los bloques de
   una misma fila reparten distinto el hueco de la foto y las fotos salen de
   tamanos distintos. */
.jv-top__name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin-bottom: 8px;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
}

.jv-top__card--big .jv-top__name {
	font-size: 26px;
	line-height: 1.2;
	letter-spacing: -0.01em;
	margin-bottom: 12px;
}

.jv-top__price {
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 300;
}

.jv-top__card--big .jv-top__price {
	font-size: 18px;
}

/* get_price_html() trae su propio marcado (<del>/<ins> en rebajas): se
   normaliza aqui o se cuelan los estilos globales de precio. */
.jv-top__price .woocommerce-Price-amount,
.jv-top__price ins {
	color: inherit;
	background: none;
	text-decoration: none;
	font-weight: inherit;
}

.jv-top__price del {
	margin-right: 8px;
	color: inherit;
	opacity: .55;
}

/* ----- Enlace al catalogo ----- */
/* display:flex + width:fit-content + margin auto: siendo de nivel bloque, el
   margin auto SI lo centra (con inline-flex no haria nada). */
.jv-top__all {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: fit-content;
	margin: 40px auto 0;
	min-height: 44px;
	padding: 12px 26px;
	border: 1px solid var(--jv-color-forest);
	background: var(--jv-color-forest);
	color: #ffffff;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	transition: background-color 220ms ease, color 220ms ease;
}

.jv-top__all:hover,
.jv-top__all:focus-visible {
	background: var(--jv-color-mint);
	border-color: var(--jv-color-mint);
	color: var(--jv-color-forest);
	text-decoration: none;
}

/* ----- Entrada -----
   Cada bloque se descubre con un velo del color de la banda que se recoge
   hacia abajo. scaleY (transform) y no clip-path ni un cambio de alto: lo
   compone la GPU y no toca la rejilla. El velo TAPA por defecto y lo retira el
   script de wp_footer al entrar la seccion en pantalla (jv_top_script,
   inc/home-bestsellers.php); el <noscript> de la plantilla lo quita para quien
   navegue sin JS. El color es el del BLOQUE (--surface), no el de la banda: el velo
   se dibuja dentro del borde, asi que lo que tapa es el interior blanco de la
   tarjeta. La banda de detras es verde claro y no pinta aqui. */
.jv-top__veil {
	position: absolute;
	inset: 0;
	z-index: 6;
	background: var(--jv-color-surface);
	transform-origin: 50% 100%;
	transform: scaleY(1);
	transition: transform 620ms cubic-bezier(.22, .61, .36, 1);
	transition-delay: var(--jv-top-espera, 0ms);
	pointer-events: none;
}

.jv-top.is-visible .jv-top__veil {
	transform: scaleY(0);
}

/* Sin raton el panel desaparece del todo, no se queda abierto: lo que hay
   detras del hover aqui es EXTRA (la descripcion), porque nombre y precio ya
   se ven en reposo. Dejarlo abierto solo pondria un "Ver producto" fijo tapando
   la foto, redundante con que el bloque entero ya es el enlace. */
@media (hover: none) {
	.jv-top__reveal {
		display: none;
	}
}

@media (prefers-reduced-motion: reduce) {
	.jv-top__veil,
	.jv-top__media,
	.jv-top__reveal,
	.jv-top__card,
	.jv-top__tab,
	.jv-top__all,
	.jv-top__cta svg,
	.jv-top__all svg {
		transition: none;
	}

	.jv-top__veil {
		transform: scaleY(0);
	}
}

/* ----- Anchuras ----- */

/* Con 4 columnas por debajo de 1200 el bloque baja de 245px y la foto se queda
   sin sitio. Tres columnas: el grande pasa a la izquierda y los otros ocho se
   reparten en columna y en dos filas al pie. */
@media (max-width: 1199px) {
	.jv-top__grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.jv-top__card--big { grid-column: 1 / span 2; grid-row: 1 / span 2; }
	.jv-top__card--1   { grid-column: 3;          grid-row: 1; }
	.jv-top__card--2   { grid-column: 3;          grid-row: 2; }
	.jv-top__card--3   { grid-column: 1;          grid-row: 3; }
	.jv-top__card--4   { grid-column: 2;          grid-row: 3; }
	.jv-top__card--5   { grid-column: 3;          grid-row: 3; }
	.jv-top__card--6   { grid-column: 1;          grid-row: 4; }
	.jv-top__card--7   { grid-column: 2;          grid-row: 4; }
	.jv-top__card--8   { grid-column: 3;          grid-row: 4; }

	.jv-top__card--big .jv-top__name { font-size: 22px; }
}

@media (max-width: 899px) {
	.jv-top__grid {
		grid-template-columns: repeat(2, 1fr);
		gap: 0;
	}

	.jv-top__card--big { grid-column: 1 / span 2; grid-row: 1 / span 2; }
	.jv-top__card--1   { grid-column: 1;          grid-row: 3; }
	.jv-top__card--2   { grid-column: 2;          grid-row: 3; }
	.jv-top__card--3   { grid-column: 1;          grid-row: 4; }
	.jv-top__card--4   { grid-column: 2;          grid-row: 4; }
	.jv-top__card--5   { grid-column: 1;          grid-row: 5; }
	.jv-top__card--6   { grid-column: 2;          grid-row: 5; }
	.jv-top__card--7   { grid-column: 1;          grid-row: 6; }
	.jv-top__card--8   { grid-column: 2;          grid-row: 6; }
}

/* La tira de pestanas deja de caber centrada: pasa a barrido horizontal
   PROPIO (overflow-x en la tira, nunca en la pagina). */
@media (max-width: 767px) {
	.jv-top__tabs {
		justify-content: flex-start;
		flex-wrap: nowrap;
		overflow-x: auto;
		margin-bottom: 28px;
		padding-bottom: 4px;
		-webkit-overflow-scrolling: touch;
	}

	.jv-top__tab {
		flex: 0 0 auto;
	}

	.jv-top__card--big .jv-top__name {
		font-size: 19px;
	}
}

/* Por debajo de 480 un bloque cuadrado a dos columnas se queda en 190px y la
   foto no llega a 100: los pequenos pasan a formato vertical, que es el de la
   referencia. El grande sigue cuadrado porque ocupa las dos columnas. */
@media (max-width: 480px) {
	.jv-top__card {
		aspect-ratio: 3 / 4;
		padding: 12px;
		gap: 10px;
	}

	.jv-top__card--big {
		aspect-ratio: 1;
	}

	.jv-top__name {
		font-size: 13px;
	}

	.jv-top__price {
		font-size: 13px;
	}

	.jv-top__badge {
		font-size: 9.5px;
		padding: 2px 6px;
	}
}

/* =============================================================
   Selector de categorias principales (debajo del hero)
   Ver front-page.php y jv_familias_por_volumen() en
   inc/home-bestsellers.php.

   La pastilla es el LOCKUP DEL LOGO repetido: cuadrado de verde claro con el
   icono a la izquierda y el nombre en blanco sobre verde oscuro, con el propio
   verde oscuro haciendo de marco alrededor del cuadrado. No hay borde
   declarado: el marco ES el fondo, y lo dibuja el hueco que dejan el margen
   del cuadro y el padding del nombre. Ojo, no puede ser padding de la
   pastilla: la rejilla es flex y los % de padding de un item de flex se
   resuelven contra la fila entera, no contra la pastilla.
   ============================================================= */

/* Flex y no grid por una sola razon: `justify-content: center` centra la
   ultima fila cuando no viene completa —las 2 que sobran de 17 a cinco por
   fila—. Grid las dejaria pegadas a la izquierda. Las filas completas suman
   justo el 100%, asi que se ven igual que con grid. */
.jv-catsel__grid {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: 16px;
}

.jv-catsel__item {
	/* La proporcion exacta de la referencia. De aqui sale el alto a partir del
	   ancho de la columna, y de ese alto salen las demas medidas. */
	aspect-ratio: 3696 / 1002;
	/* inline-size y NO size: `size` contiene tambien el eje vertical y dejaba
	   la pastilla clavada en 471x128 a cualquier anchura, con scroll
	   horizontal. Aqui solo hace falta poder medir el ancho. */
	container-type: inline-size;
	display: flex;
	align-items: stretch;
	overflow: hidden;
	/* Cinco por fila. El -0.01px es el margen para el redondeo: sin el, cinco
	   anchos redondeados hacia arriba suman algo mas del 100% y el quinto se
	   cae a la fila siguiente. */
	flex: 0 0 calc((100% - 4 * 16px) / 5 - 0.01px);
	background: var(--jv-color-forest);
	color: #ffffff;
	text-decoration: none;
	cursor: pointer;
	transition: background-color 220ms ease, color 220ms ease;
}

/* Ancho Y alto declarados, los dos iguales. Antes iba con `aspect-ratio: 1` y
   estirado en vertical, y eso solo sale cuadrado si el motor deduce el ancho
   de la razon; WebKit resuelve flex-basis:auto por contenido y ahi el cuadro
   se quedaba con el ancho del SVG de cada categoria, que no es el mismo en
   todas (los viewBox van de 320x512 a 640x512). Con las dos medidas puestas
   no hay nada que deducir.
   Centrado en vertical en vez de estirado: si un nombre se va a tres lineas y
   empuja la fila, el cuadro sigue siendo cuadrado. */
.jv-catsel__icono {
	flex: 0 0 auto;
	align-self: center;
	/* 24,3994cqw = el alto de la pastilla menos los dos marcos. Las lineas en
	   px de encima son el respaldo para navegadores sin consultas de
	   contenedor. */
	width: 61px;
	height: 61px;
	margin-left: 3px;
	width: 24.3994cqw;
	height: 24.3994cqw;
	margin-left: 1.3555cqw;
	display: grid;
	place-items: center;
	background: var(--jv-color-mint);
	transition: background-color 220ms ease;
}

/* Los iconos son de relleno y su viewBox NO es cuadrado (320x512 a 640x512):
   se dimensionan por alto con width:auto, o cada uno sale de un tamano. */
.jv-catsel__icono svg {
	height: 71%;
	width: auto;
	fill: var(--jv-color-forest);
	transition: fill 220ms ease;
}

.jv-catsel__nombre {
	display: flex;
	align-items: center;
	/* Sin padding en la pastilla, 1cqw es el 1% de su ancho pelado, asi que
	   los porcentajes de la referencia —27,7% y 14% del ALTO— salen directos.
	   Las lineas en px de encima son el respaldo para navegadores sin consultas
	   de contenedor: si no entienden la unidad, descartan la linea y se quedan
	   con la anterior. */
	padding: 0 10px 0 19px;
	padding: 0 3.7955cqw 0 7.5096cqw;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-size: 5.5576cqw;
	font-weight: 600;
	line-height: 1.25;
}

/* El hover INVIERTE la pastilla entera: las dos mitades se intercambian el
   color. No puede oscurecer porque no hay nada mas oscuro que el verde de
   marca (ver la regla de la paleta), y aclarar solo una mitad rompia el
   lockup. Verde oscuro sobre verde claro son 5,30:1 en los dos sentidos. */
.jv-catsel__item:hover,
.jv-catsel__item:focus-visible {
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
	text-decoration: none;
}

.jv-catsel__item:hover .jv-catsel__icono,
.jv-catsel__item:focus-visible .jv-catsel__icono {
	background: var(--jv-color-forest);
}

.jv-catsel__item:hover .jv-catsel__icono svg,
.jv-catsel__item:focus-visible .jv-catsel__icono svg {
	fill: var(--jv-color-mint);
}

@media (prefers-reduced-motion: reduce) {
	.jv-catsel__item,
	.jv-catsel__icono,
	.jv-catsel__icono svg {
		transition: none;
	}
}

/* Por debajo de 1400 la pastilla baja de 235px y el nombre se queda en menos
   de 13px. Cuatro por fila, y las que sobren siguen centradas solas. */
@media (max-width: 1399px) {
	.jv-catsel__item {
		flex-basis: calc((100% - 3 * 16px) / 4 - 0.01px);
	}
}

/* A cuatro columnas por debajo de 1200 la pastilla baja de 250px y el nombre
   mas largo —"Invernaderos y Armarios de Cultivo"— se parte en cuatro lineas. */
@media (max-width: 1199px) {
	.jv-catsel__item {
		flex-basis: calc((100% - 2 * 16px) / 3 - 0.01px);
	}
}

@media (max-width: 899px) {
	.jv-catsel__item {
		flex-basis: calc((100% - 16px) / 2 - 0.01px);
	}
}

/* A dos columnas por debajo de 600 quedan ~110px para el nombre y hasta la
   primera palabra se sale. Una columna, y la pastilla mas baja para que 17
   categorias no se hagan eternas. */
@media (max-width: 599px) {
	.jv-catsel__grid {
		gap: 10px;
	}

	.jv-catsel__item {
		flex-basis: 100%;
	}
}

/* =============================================================
   Servicios de jardineria (home)
   Ver front-page.php.

   Es la reticula de .jv-top con otro contenido: 9 bloques cuadrados en 4
   columnas con uno grande de 2x2, bordes colapsados y velo de entrada. Las
   diferencias, todas obligadas por el contenido o por la banda:

   - La foto va con `cover`. Las de producto son recortes sobre blanco y hay
     que verlas enteras; estas son escenas y con `contain` cada una dejaria
     franjas de un alto distinto.
   - Se queda fijo el titulo y suben la explicacion y el boton.
   - La banda es verde oscuro, asi que la reticula se invierte: borde claro
     sobre fondo oscuro. El fondo del bloque es el MISMO verde de la banda
     porque la marca solo tiene dos verdes y no hay uno intermedio que
     inventar; lo que dibuja la reticula es el borde.
   ============================================================= */

.jv-serv__head {
	max-width: 640px;
	margin: 0 auto 32px;
	text-align: center;
}

.jv-serv__head .jv-section__title {
	margin-bottom: 14px;
}

.jv-serv__intro {
	margin: 0;
	font-size: 16px;
	font-weight: 300;
	line-height: 1.6;
	color: rgba(255, 255, 255, .8);
}

/* ----- Reticula ----- */
.jv-serv__grid {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: 0;
}

/* El grande abajo a la izquierda: fila de cuatro arriba, y debajo el grande
   con dos a su derecha en cada una de las dos filas que ocupa. */
.jv-serv__card--1   { grid-column: 1;          grid-row: 1; }
.jv-serv__card--2   { grid-column: 2;          grid-row: 1; }
.jv-serv__card--3   { grid-column: 3;          grid-row: 1; }
.jv-serv__card--4   { grid-column: 4;          grid-row: 1; }
.jv-serv__card--big { grid-column: 1 / span 2; grid-row: 2 / span 2; }
.jv-serv__card--5   { grid-column: 3;          grid-row: 2; }
.jv-serv__card--6   { grid-column: 4;          grid-row: 2; }
.jv-serv__card--7   { grid-column: 3;          grid-row: 3; }
.jv-serv__card--8   { grid-column: 4;          grid-row: 3; }

/* Borde de 4px y margen de -2px: los bloques se solapan y sus bordes se funden
   en una sola linea en vez de sumar 8px. El margen negativo saca la reticula
   2px fuera del contenedor, que caen dentro de sus 24px de padding. */
.jv-serv__card {
	position: relative;
	display: flex;
	flex-direction: column;
	/* Sin padding ni hueco: la foto llega al borde por arriba y por los lados,
	   y el margen que necesita el titulo se lo pone el propio pie. */
	gap: 0;
	aspect-ratio: 1;
	overflow: hidden;
	padding: 0;
	border: 4px solid var(--jv-color-mint);
	margin: -2px;
	background: var(--jv-color-forest);
	color: #ffffff;
	text-decoration: none;
	cursor: pointer;
}

.jv-serv__card:hover,
.jv-serv__card:focus-visible {
	text-decoration: none;
}

/* Misma trampa que en .jv-top: el anillo se dibuja FUERA, y como los bloques se
   solapan 4px caia justo sobre el borde del vecino —verde claro sobre verde
   claro, invisible—. Hay que meterlo hacia dentro.
   Pero al quitarle el padding al bloque, ahi dentro ya no hay verde oscuro:
   hay FOTO, y una foto puede ser de cualquier color. La banda de box-shadow le
   pone debajo el verde de marca, asi que el anillo cae siempre sobre verde
   oscuro (5,30:1) sea cual sea la imagen. El color del anillo lo pone ya la
   regla de banda oscura. */
.jv-serv__card:focus-visible {
	outline-offset: -7px;
	outline-width: 3px;
	box-shadow: inset 0 0 0 12px var(--jv-color-forest);
}

.jv-serv__frame {
	position: relative;
	flex: 1 1 auto;
	min-height: 0;
	overflow: hidden;
}

/* cover y no contain: son escenas de jardin, no fotos de producto recortadas
   sobre blanco. Con contain cada foto dejaria franjas de un alto distinto. */
.jv-serv__media {
	position: absolute;
	inset: 0;
	background-position: center center;
	background-repeat: no-repeat;
	background-size: cover;
	transform: scale(1);
	transition: transform 480ms cubic-bezier(.22, .61, .36, 1);
}

.jv-serv__card:hover .jv-serv__media,
.jv-serv__card:focus-visible .jv-serv__media {
	transform: scale(1.06);
}

/* Invertido respecto a .jv-top: alli el panel es verde oscuro sobre bloque
   blanco, aqui verde claro sobre bloque verde oscuro. Verde oscuro sobre verde
   claro son 5,30:1, que es el unico par valido de la paleta. */
.jv-serv__reveal {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	max-height: 100%;
	padding: 12px 14px 14px;
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
	transform: translateY(101%);
	transition: transform 320ms cubic-bezier(.22, .61, .36, 1);
}

.jv-serv__card:hover .jv-serv__reveal,
.jv-serv__card:focus-visible .jv-serv__reveal {
	transform: translateY(0);
}

.jv-serv__desc {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	margin-bottom: 8px;
	font-size: 12.5px;
	font-weight: 300;
	line-height: 1.45;
}

.jv-serv__card--big .jv-serv__desc {
	-webkit-line-clamp: 4;
	margin-bottom: 12px;
	font-size: 15px;
	line-height: 1.55;
}

.jv-serv__cta {
	display: inline-flex;
	align-items: center;
	gap: 7px;
	font-family: var(--jv-font-sans);
	font-size: 12.5px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-serv__card--big .jv-serv__cta {
	font-size: 14px;
}

.jv-serv__cta svg,
.jv-serv__all svg {
	height: 11px;
	width: auto;
	fill: currentColor;
	transition: transform 240ms ease;
}

.jv-serv__card:hover .jv-serv__cta svg,
.jv-serv__all:hover svg {
	transform: translateX(4px);
}

/* ----- Titulo del bloque ----- */
.jv-serv__body {
	display: flex;
	flex-direction: column;
	flex: 0 0 auto;
	padding: 14px 16px 16px;
}

/* Dos lineas fijas: el alto del texto tiene que ser constante o los bloques de
   una misma fila reparten distinto el hueco de la foto y las fotos salen de
   tamanos distintos. Los titulos acaban casi todos en "en Valencia" y se
   recortan ahi, que es justo lo prescindible. */
/* Dos lineas de tope Y de suelo. El recorte solo pone el tope, y con un titulo
   de una linea el pie medía menos: como el hueco de la foto es lo que sobra
   despues del pie, esa foto salia mas alta que la de al lado. El min-height son
   dos interlineados, asi que hay que repetirlo donde cambia el interlineado. */
.jv-serv__name {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 2.7em;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
}

.jv-serv__card--big .jv-serv__name {
	min-height: 2.4em;
	font-size: 26px;
	line-height: 1.2;
	letter-spacing: -0.01em;
}

/* ----- Enlace a todos los servicios -----
   Sobre verde oscuro un boton verde oscuro seria invisible (1:1), asi que va
   en verde claro con texto verde oscuro y aclara al pasar el raton. */
.jv-serv__all {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	width: fit-content;
	margin: 40px auto 0;
	min-height: 44px;
	padding: 12px 26px;
	border: 1px solid var(--jv-color-mint);
	background: var(--jv-color-mint);
	color: var(--jv-color-forest);
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	text-decoration: none;
	transition: background-color 220ms ease, border-color 220ms ease;
}

.jv-serv__all:hover,
.jv-serv__all:focus-visible {
	background: var(--jv-color-mint-soft);
	border-color: var(--jv-color-mint-soft);
	color: var(--jv-color-forest);
	text-decoration: none;
}

/* ----- Entrada -----
   El velo es del color del BLOQUE y se dibuja dentro del borde, asi que lo que
   tapa es el interior verde oscuro. Lo retira el script de wp_footer al entrar
   la seccion en pantalla (jv_top_script, inc/home-bestsellers.php), que observa
   este bloque y el de destacados. */
.jv-serv__veil {
	position: absolute;
	inset: 0;
	z-index: 6;
	background: var(--jv-color-forest);
	transform-origin: 50% 100%;
	transform: scaleY(1);
	transition: transform 620ms cubic-bezier(.22, .61, .36, 1);
	transition-delay: var(--jv-serv-espera, 0ms);
	pointer-events: none;
}

.jv-serv.is-visible .jv-serv__veil {
	transform: scaleY(0);
}

/* Aqui NO se esconde el panel sin raton, al reves que en .jv-top: alli lo que
   tapa es informacion extra (nombre y precio ya se ven), pero aqui lleva la
   explicacion del servicio, que es contenido. Se queda abierto. */
@media (hover: none) {
	.jv-serv__reveal {
		transform: translateY(0);
	}
}

@media (prefers-reduced-motion: reduce) {
	.jv-serv__veil,
	.jv-serv__media,
	.jv-serv__reveal,
	.jv-serv__all,
	.jv-serv__cta svg,
	.jv-serv__all svg {
		transition: none;
	}

	.jv-serv__veil {
		transform: scaleY(0);
	}
}

/* ----- Anchuras ----- */

/* Igual que en .jv-top: con 4 columnas por debajo de 1200 el bloque baja de
   245px y la foto se queda sin sitio. */
@media (max-width: 1199px) {
	.jv-serv__grid {
		grid-template-columns: repeat(3, 1fr);
	}

	.jv-serv__card--1   { grid-column: 1;          grid-row: 1; }
	.jv-serv__card--2   { grid-column: 2;          grid-row: 1; }
	.jv-serv__card--3   { grid-column: 3;          grid-row: 1; }
	.jv-serv__card--4   { grid-column: 1;          grid-row: 2; }
	.jv-serv__card--5   { grid-column: 2;          grid-row: 2; }
	.jv-serv__card--6   { grid-column: 3;          grid-row: 2; }
	.jv-serv__card--big { grid-column: 1 / span 2; grid-row: 3 / span 2; }
	.jv-serv__card--7   { grid-column: 3;          grid-row: 3; }
	.jv-serv__card--8   { grid-column: 3;          grid-row: 4; }

	.jv-serv__card--big .jv-serv__name { font-size: 22px; }
}

@media (max-width: 899px) {
	.jv-serv__grid {
		grid-template-columns: repeat(2, 1fr);
	}

	.jv-serv__card--1   { grid-column: 1;          grid-row: 1; }
	.jv-serv__card--2   { grid-column: 2;          grid-row: 1; }
	.jv-serv__card--3   { grid-column: 1;          grid-row: 2; }
	.jv-serv__card--4   { grid-column: 2;          grid-row: 2; }
	.jv-serv__card--5   { grid-column: 1;          grid-row: 3; }
	.jv-serv__card--6   { grid-column: 2;          grid-row: 3; }
	.jv-serv__card--7   { grid-column: 1;          grid-row: 4; }
	.jv-serv__card--8   { grid-column: 2;          grid-row: 4; }
	.jv-serv__card--big { grid-column: 1 / span 2; grid-row: 5 / span 2; }
}

@media (max-width: 767px) {
	.jv-serv__card--big .jv-serv__name {
		font-size: 19px;
	}
}

/* Una columna por debajo de 600, que es lo que ya hacia el bloque anterior.
   A dos columnas y 360px de pantalla el bloque se queda en 145x194: la foto son
   125px de alto y el panel se comia 80, porque en tactil esta SIEMPRE abierto
   —lleva la explicacion del servicio, que es contenido, no un extra como en
   Destacados—. Y se recortaban los nueve titulos: a 145px caben unos 40
   caracteres en dos lineas y los titulos tienen entre 45 y 57.
   Apaisado y no cuadrado para que nueve servicios no sean 3.000px de scroll. */
@media (max-width: 599px) {
	.jv-serv__grid {
		grid-template-columns: 1fr;
	}

	/* Hay que deshacer las colocaciones a mano de los tramos de arriba, o el
	   grande seguiria pidiendo dos columnas y los demas su fila fija. */
	.jv-serv__card,
	.jv-serv__card--big,
	.jv-serv__card--1,
	.jv-serv__card--2,
	.jv-serv__card--3,
	.jv-serv__card--4,
	.jv-serv__card--5,
	.jv-serv__card--6,
	.jv-serv__card--7,
	.jv-serv__card--8 {
		grid-column: 1;
		grid-row: auto;
		/* La proporcion se la queda la FOTO, no el bloque: el panel de la
		   explicacion tiene un alto propio de unos 93px que no encoge, asi que
		   con la proporcion en el bloque el hueco de la foto salia de restar
		   dos cosas que escalan distinto y a 360px quedaban 39px de foto. */
		aspect-ratio: auto;
	}

	.jv-serv__frame {
		flex: 0 0 auto;
		aspect-ratio: 4 / 3;
	}

	.jv-serv__body {
		padding: 12px 14px 14px;
	}

	.jv-serv__card--big .jv-serv__name {
		font-size: 17px;
	}
}

/* ===== Carrusel de marcas (home) =====
   Los logos van como MASCARA, no como imagen. De los 11 archivos, seis vienen
   en blanco —pensados para fondo oscuro— y sobre el verde claro de la banda no
   se verian; el canal alfa, en cambio, tiene la forma exacta de la marca, asi
   que enmascarando un fondo del verde de marca salen todos en verde oscuro con
   5,30:1 pase lo que pase con el archivo. Se pierden los colores de marca
   (Trabe, Hesi y Canna eran de color), y a cambio la fila queda ordenada, que
   era la otra razon por la que existia la pastilla oscura. */

.jv-brands__carrusel {
	/* relative Y hidden: el recorte solo alcanza a los hijos absolutos si este
	   elemento es su bloque contenedor. Cada marca lleva un
	   .screen-reader-text con su nombre, que WordPress posiciona en absoluto;
	   sin este `relative` se escapaban del recorte y estiraban el documento a
	   4.402px, o sea scroll horizontal en toda la pagina. */
	position: relative;
	overflow: hidden;
	width: 100vw;
	margin-left: calc(50% - 50vw);
	padding: 10px 0;
	/* El desfile no se corta en seco en los bordes: se desvanece. */
	-webkit-mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
	mask-image: linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
}

.jv-brands__pista {
	display: flex;
	align-items: center;
	width: max-content;
	animation: jv-brands-desfile 48s linear infinite;
}

/* Parado mientras se mira o mientras se tabula por el: un enlace que se mueve
   no hay quien lo pulse. */
.jv-brands__carrusel:hover .jv-brands__pista,
.jv-brands__carrusel:focus-within .jv-brands__pista {
	animation-play-state: paused;
}

/* De derecha a izquierda, un juego entero por vuelta. */
@keyframes jv-brands-desfile {
	from { transform: translateX(0); }
	to   { transform: translateX(-50%); }
}

.jv-brands__marca {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	width: 190px;
	height: 64px;
	/* La separacion va AQUI y no en un `gap` de la pista. Con gap, el ancho
	   total es 2N elementos + (2N-1) huecos, y el -50% de la animacion se queda
	   a medio hueco del sitio: el bucle daria un salto en cada vuelta. Metida
	   en el elemento, el total es 2N x (ancho + hueco) y la mitad es exacta. */
	margin-right: 72px;
	text-decoration: none;
}

.jv-brands__logo {
	display: block;
	width: 100%;
	height: 100%;
	background-color: var(--jv-color-forest);
	-webkit-mask-image: var(--jv-brand-logo);
	mask-image: var(--jv-brand-logo);
	-webkit-mask-repeat: no-repeat;
	mask-repeat: no-repeat;
	-webkit-mask-position: center;
	mask-position: center;
	-webkit-mask-size: contain;
	mask-size: contain;
	opacity: .85;
	transition: opacity 200ms ease;
}

.jv-brands__marca:hover .jv-brands__logo,
.jv-brands__marca:focus-visible .jv-brands__logo {
	opacity: 1;
}

/* Sin mascaras, el fondo verde seria un rectangulo macizo: se cae a la imagen
   tal cual. Los seis logos blancos no se veran, pero es mejor eso que once
   ladrillos verdes. */
@supports not ((-webkit-mask-image: linear-gradient(#000, #000)) or (mask-image: linear-gradient(#000, #000))) {
	.jv-brands__logo {
		background-color: transparent;
		background-image: var(--jv-brand-logo);
		background-repeat: no-repeat;
		background-position: center;
		background-size: contain;
	}
}

/* Sin movimiento no hay carrusel: las marcas se reparten en varias lineas y la
   copia decorativa desaparece, o saldria cada marca dos veces. */
@media (prefers-reduced-motion: reduce) {
	.jv-brands__carrusel {
		width: auto;
		margin-left: 0;
		-webkit-mask-image: none;
		mask-image: none;
	}

	.jv-brands__pista {
		animation: none;
		width: auto;
		flex-wrap: wrap;
		justify-content: center;
	}

	.jv-brands__marca[aria-hidden] {
		display: none;
	}
}

@media (max-width: 767px) {
	.jv-brands__marca {
		width: 150px;
		height: 48px;
		margin-right: 48px;
	}

	.jv-brands__pista {
		animation-duration: 34s;
	}
}



/* ==========================================================================
   Drawer lateral de carrito (inc/cart-drawer.php)
   --------------------------------------------------------------------------
   Panel que se desliza desde la derecha al pulsar el icono de cesta o al
   añadir un producto, en sustitución del salto a /carrito/ y del antiguo
   toast superior.

   Reutiliza el markup del widget nativo WC_Widget_Cart (.widget_shopping_cart)
   porque WooCommerce ya lo mantiene sincronizado por AJAX; lo de aquí es
   solo la caja que lo contiene y el reestilado de ese widget dentro de ella.
   ========================================================================== */

.jv-drawer {
	position: fixed;
	inset: 0;
	z-index: 100000; /* por encima de la cabecera sticky */
	visibility: hidden;
	pointer-events: none;
}

.jv-drawer.is-open {
	visibility: visible;
	pointer-events: auto;
}

.jv-drawer__overlay {
	position: absolute;
	inset: 0;
	background: rgba(15, 86, 55, 0.45); /* --jv-color-forest con alfa */
	opacity: 0;
	transition: opacity 0.25s ease;
}

.jv-drawer.is-open .jv-drawer__overlay {
	opacity: 1;
}

.jv-drawer__panel {
	position: absolute;
	top: 0;
	right: 0;
	height: 100%;
	width: min(420px, 100vw);
	background: var(--jv-color-surface);
	display: flex;
	flex-direction: column;
	/* Fuera de pantalla en reposo: translate (no 'right') para que la
	   animación corra en la capa de composición y no provoque reflow. */
	transform: translateX(100%);
	transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
	box-shadow: -4px 0 24px rgba(15, 86, 55, 0.18);
	outline: none;
}

.jv-drawer.is-open .jv-drawer__panel {
	transform: translateX(0);
}

/* Respeta a quien pide menos movimiento: el panel aparece sin deslizarse. */
@media (prefers-reduced-motion: reduce) {
	.jv-drawer__panel,
	.jv-drawer__overlay {
		transition: none;
	}
}

/* Congela el fondo mientras el panel está abierto. */
body.jv-drawer-open {
	overflow: hidden;
}

/* ── Cabecera ─────────────────────────────────────────────────────────── */

.jv-drawer__head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	padding: 18px 20px;
	border-bottom: 1px solid var(--jv-color-border);
	flex: 0 0 auto;
}

.jv-drawer__title {
	margin: 0;
	font-family: var(--jv-font-sans);
	font-size: 18px;
	font-weight: 600;
	color: var(--jv-color-forest);
	display: flex;
	align-items: baseline;
	gap: 6px;
}

.jv-drawer__count {
	font-weight: 300;
	color: var(--jv-color-price-muted);
}

.jv-drawer__close {
	background: none;
	border: none;
	padding: 6px;
	cursor: pointer;
	color: var(--jv-color-forest);
	display: flex;
	align-items: center;
	line-height: 0;
}

.jv-drawer__close .jv-icon {
	width: 20px;
	height: 20px;
}

/* ── Barra de envío gratuito ──────────────────────────────────────────── */

.jv-drawer__shipbar {
	padding: 14px 20px;
	background: var(--jv-color-canvas);
	border-bottom: 1px solid var(--jv-color-border);
	flex: 0 0 auto;
}

.jv-drawer__shipbar-text {
	margin: 0 0 8px;
	font-size: 13px;
	color: var(--jv-color-forest);
	display: flex;
	align-items: center;
	gap: 6px;
}

.jv-drawer__shipbar-text .jv-icon {
	width: 14px;
	height: 14px;
	flex: 0 0 auto;
}

/* El importe que falta lo devuelve wc_price() envuelto en .amount. */
.jv-drawer__shipbar-text .amount {
	font-weight: 600;
}

.jv-drawer__shipbar-track {
	height: 6px;
	background: var(--jv-color-mint-soft);
	overflow: hidden;
}

.jv-drawer__shipbar-fill {
	display: block;
	height: 100%;
	background: var(--jv-color-forest);
	transition: width 0.3s ease;
}

/* ── Cuerpo: widget de carrito ────────────────────────────────────────── */

.jv-drawer__body {
	flex: 1 1 auto;
	overflow-y: auto;
	padding: 0 20px;
}

/* El widget trae márgenes pensados para una barra lateral; dentro del
   drawer ocupa todo el ancho disponible. */
.jv-drawer__body .widget_shopping_cart,
.jv-drawer__body .widget_shopping_cart_content {
	margin: 0;
	padding: 0;
	width: 100%;
}

.jv-drawer__body .woocommerce-mini-cart {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Rejilla de la línea de carrito.
   Ojo al orden real del DOM que imprime el widget: primero el enlace
   .remove, después el <a> con la miniatura Y el nombre dentro (el nombre es
   texto suelto de ese mismo enlace, no un nodo aparte), y por último
   .quantity. Por eso las columnas se asignan explícitamente con
   grid-column en vez de confiar en el flujo automático. */
.jv-drawer__body .woocommerce-mini-cart-item {
	position: relative;
	display: grid;
	/* miniatura · datos · botón de borrar */
	grid-template-columns: 64px 1fr 24px;
	grid-template-rows: auto auto;
	gap: 4px 12px;
	align-items: start;
	padding: 16px 0;
	margin: 0;
	border-bottom: 1px solid var(--jv-color-border);
}

/* El enlace del producto envuelve imagen + nombre. Se convierte en subgrid
   de dos columnas para que la miniatura quede a la izquierda y el texto a
   su derecha, sin tener que separar el markup del widget. */
.jv-drawer__body .woocommerce-mini-cart-item > a:not(.remove) {
	grid-column: 1 / 3;
	grid-row: 1;
	display: grid;
	grid-template-columns: 64px 1fr;
	gap: 12px;
	align-items: start;
	font-size: 14px;
	line-height: 1.35;
	color: var(--jv-color-ink);
	text-decoration: none;
	font-weight: 600;
}

.jv-drawer__body .woocommerce-mini-cart-item a img {
	width: 64px;
	height: 64px;
	object-fit: contain;
	margin: 0;
	float: none;
	border: 1px solid var(--jv-color-border);
	background: var(--jv-color-surface);
}

/* .quantity ("1 × 89,44 €") va bajo el nombre, alineado con el texto y no
   con la miniatura. */
.jv-drawer__body .woocommerce-mini-cart-item .quantity {
	grid-column: 1 / 3;
	grid-row: 2;
	display: block;
	padding-left: 76px; /* 64px de miniatura + 12px de gap */
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

.jv-drawer__body .woocommerce-mini-cart-item .variation {
	grid-column: 1 / 3;
	grid-row: 2;
	padding-left: 76px;
	font-size: 12px;
	color: var(--jv-color-price-muted);
	margin: 2px 0 0;
}

/* Botón "×" de quitar línea: en el DOM viene el primero, pero visualmente
   corresponde a la tercera columna de la primera fila. */
.jv-drawer__body .woocommerce-mini-cart-item a.remove,
.jv-drawer__body .woocommerce-mini-cart-item a.remove_from_cart_button {
	grid-column: 3;
	grid-row: 1;
	position: static;
	float: none;
	width: 24px;
	height: 24px;
	line-height: 22px;
	text-align: center;
	font-size: 18px;
	color: var(--jv-color-price-muted);
	background: none;
	border: 1px solid var(--jv-color-border);
	text-decoration: none;
}

.jv-drawer__body .woocommerce-mini-cart-item a.remove:hover,
.jv-drawer__body .woocommerce-mini-cart-item a.remove_from_cart_button:hover {
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
	border-color: var(--jv-color-forest);
}

/* Carrito vacío */
.jv-drawer__body .woocommerce-mini-cart__empty-message {
	padding: 48px 0;
	text-align: center;
	color: var(--jv-color-price-muted);
	font-size: 15px;
}

/* ── Total y botones ──────────────────────────────────────────────────── */

/* El widget pinta el subtotal y los botones al final de su contenido; se
   fijan al pie del panel para que "Finalizar compra" esté siempre visible
   sin tener que desplazar la lista, que es el punto de toda la reforma. */
.jv-drawer__body .woocommerce-mini-cart__total {
	position: sticky;
	bottom: 0;
	display: flex;
	align-items: center;
	justify-content: space-between;
	margin: 0;
	padding: 16px 0 12px;
	border-top: 1px solid var(--jv-color-border);
	background: var(--jv-color-surface);
	font-size: 15px;
	color: var(--jv-color-forest);
}

.jv-drawer__body .woocommerce-mini-cart__total strong {
	font-weight: 300;
}

.jv-drawer__body .woocommerce-mini-cart__total .amount {
	font-size: 20px;
	font-weight: 600;
}

.jv-drawer__body .woocommerce-mini-cart__buttons {
	position: sticky;
	bottom: 0;
	display: grid;
	gap: 8px;
	margin: 0;
	padding: 0 0 16px;
	background: var(--jv-color-surface);
}

.jv-drawer__body .woocommerce-mini-cart__buttons a {
	display: block;
	width: 100%;
	margin: 0;
	padding: 14px 16px;
	text-align: center;
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	border: 1px solid var(--jv-color-forest);
}

/* "Ver cesta" — secundario */
.jv-drawer__body .woocommerce-mini-cart__buttons a:not(.checkout) {
	order: 2;
	background: var(--jv-color-surface);
	color: var(--jv-color-forest);
}

/* "Finalizar compra" — acción principal, primero en el orden visual */
.jv-drawer__body .woocommerce-mini-cart__buttons a.checkout {
	order: 1;
	background: var(--jv-color-forest);
	color: var(--jv-color-surface);
}

.jv-drawer__body .woocommerce-mini-cart__buttons a.checkout:hover {
	filter: brightness(1.12);
}

/* ── Pie de confianza ─────────────────────────────────────────────────── */

.jv-drawer__foot {
	flex: 0 0 auto;
	padding: 12px 20px;
	border-top: 1px solid var(--jv-color-border);
	background: var(--jv-color-canvas);
}

.jv-drawer__trust {
	display: flex;
	flex-wrap: wrap;
	gap: 6px 16px;
	justify-content: center;
}

.jv-drawer__trust-item {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

.jv-drawer__trust-item .jv-icon {
	width: 14px;
	height: 14px;
	color: var(--jv-color-forest);
}

/* ── Móvil ────────────────────────────────────────────────────────────── */

@media (max-width: 480px) {
	.jv-drawer__panel {
		width: 100vw;
	}
}

/* El toast antiguo queda sustituido por el drawer; se oculta por si algún
   render lo dejara en el DOM (ver inc/cart-toast.php, ya desactivado). */
.jv-cart-toast {
	display: none !important;
}

/* ── "Completa tu pedido" dentro del drawer ───────────────────────────── */

.jv-drawer__cross {
	padding: 20px 0 16px;
	border-top: 1px solid var(--jv-color-border);
}

.jv-drawer__cross-title {
	margin: 0 0 12px;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

/* Carrusel horizontal: mantiene el bloque de sugerencias en una sola franja
   para que no empuje el total del carrito fuera de la vista. */
.jv-drawer__cross-list {
	display: flex;
	gap: 10px;
	margin: 0;
	padding: 0 0 6px;
	list-style: none;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
}

.jv-drawer__cross-item {
	flex: 0 0 140px;
	scroll-snap-align: start;
	display: flex;
	flex-direction: column;
	justify-content: space-between;
	gap: 8px;
	margin: 0;
	padding: 10px;
	border: 1px solid var(--jv-color-border);
	background: var(--jv-color-surface);
}

.jv-drawer__cross-link {
	display: block;
	text-decoration: none;
	color: var(--jv-color-ink);
}

.jv-drawer__cross-link img {
	display: block;
	width: 100%;
	height: 84px;
	object-fit: contain;
	margin: 0 0 8px;
	background: var(--jv-color-canvas);
}

.jv-drawer__cross-name {
	display: block;
	font-size: 12px;
	line-height: 1.35;
	font-weight: 600;
}

.jv-drawer__cross-foot {
	display: flex;
	flex-direction: column;
	gap: 6px;
}

.jv-drawer__cross-price {
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

/* El precio llega de get_price_html(), que en oferta trae <del> y <ins>. */
.jv-drawer__cross-price del {
	font-weight: 300;
	font-size: 11px;
	color: var(--jv-color-price-muted);
	margin-right: 4px;
}

.jv-drawer__cross-price ins {
	text-decoration: none;
}

.jv-drawer__cross-add {
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 5px;
	width: 100%;
	padding: 7px 8px;
	font-family: var(--jv-font-sans);
	font-size: 12px;
	font-weight: 600;
	text-decoration: none;
	color: var(--jv-color-forest);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-forest);
}

.jv-drawer__cross-add:hover {
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
}

.jv-drawer__cross-add .jv-icon {
	width: 11px;
	height: 11px;
}

/* Estados del botón AJAX de WooCommerce: 'loading' mientras va la petición y
   'added' al terminar. Sin esto el clic no da ninguna señal de que algo está
   pasando. */
.jv-drawer__cross-add.loading {
	opacity: 0.6;
	pointer-events: none;
}

.jv-drawer__cross-add.added {
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
}

/* WooCommerce inyecta su propio enlace "Ver cesta" detrás de cada botón AJAX;
   dentro del drawer sobra, porque la cesta ya está a la vista. */
.jv-drawer__cross .added_to_cart {
	display: none !important;
}

/* Orden dentro del cuerpo del drawer.
   El widget de WooCommerce imprime, en este orden: lista de líneas, total y
   botones. El bloque de sugerencias se añade después en el DOM, así que sin
   esto quedaría por debajo del botón de finalizar compra — que es justo
   donde nadie lo mira. Con flex + order se coloca entre las líneas y el
   total, sin tocar el markup del widget. */
.jv-drawer__body {
	display: flex;
	flex-direction: column;
}

.jv-drawer__body .widget_shopping_cart,
.jv-drawer__body .widget_shopping_cart_content {
	display: contents;
}

.jv-drawer__body .woocommerce-mini-cart {
	order: 1;
}

.jv-drawer__cross-slot {
	order: 2;
}

.jv-drawer__body .woocommerce-mini-cart__total {
	order: 3;
}

.jv-drawer__body .woocommerce-mini-cart__buttons {
	order: 4;
}

.jv-drawer__body .woocommerce-mini-cart__empty-message {
	order: 1;
}

/* Con display:contents en el contenedor, el sticky del total/botones pierde
   su ancestro de scroll; se recupera anclándolos al propio cuerpo. */
.jv-drawer__body .woocommerce-mini-cart__total,
.jv-drawer__body .woocommerce-mini-cart__buttons {
	position: sticky;
	background: var(--jv-color-surface);
}

.jv-drawer__body .woocommerce-mini-cart__total {
	bottom: 96px; /* deja sitio a los dos botones apilados */
}

.jv-drawer__body .woocommerce-mini-cart__buttons {
	bottom: 0;
}

/* ==========================================================================
   Checkout de bloques (WooCommerce Blocks)
   --------------------------------------------------------------------------
   Cart y Checkout usan los bloques nuevos (wp:woocommerce/checkout), no el
   shortcode clasico, asi que el checkout YA es de una sola pagina y reactivo.
   Lo que falta es que se vea de Verdetop: los bloques traen su propia hoja de
   estilos y sus botones salen en el gris por defecto de WooCommerce.

   Se estilan por clases .wc-block-*, que son la superficie publica de los
   bloques; no se toca su markup interno.
   ========================================================================== */

/* Boton "Realizar el pedido" — el mas importante de la tienda, y venia en el
   gris #333 de WooCommerce en vez del verde corporativo. */
.wc-block-checkout__actions_row .wc-block-components-checkout-place-order-button,
.wc-block-components-checkout-place-order-button {
	background-color: var(--jv-color-forest) !important;
	color: var(--jv-color-surface) !important;
	border: 1px solid var(--jv-color-forest) !important;
	border-radius: var(--jv-radius-control) !important;
	font-family: var(--jv-font-sans) !important;
	font-weight: 600 !important;
	font-size: 16px !important;
	padding: 16px 24px !important;
	transition: filter 0.15s ease;
}

.wc-block-components-checkout-place-order-button:hover:not(:disabled) {
	filter: brightness(1.12);
}

.wc-block-components-checkout-place-order-button:disabled {
	background-color: var(--jv-color-disabled-bg) !important;
	border-color: var(--jv-color-border) !important;
	color: var(--jv-color-disabled-text) !important;
}

/* Campos de formulario: el checkout es donde mas se teclea, y los bloques
   traen bordes/radios propios que no casan con el resto del sitio. */
.wc-block-components-text-input input[type="text"],
.wc-block-components-text-input input[type="email"],
.wc-block-components-text-input input[type="tel"],
.wc-block-components-text-input input[type="number"],
.wc-block-components-select__container select,
.wc-blocks-components-select__select {
	border: var(--jv-border-control) !important;
	border-radius: var(--jv-radius-control) !important;
	font-family: var(--jv-font-sans) !important;
	font-size: var(--jv-text-body) !important;
	color: var(--jv-color-ink) !important;
	background: var(--jv-color-surface) !important;
}

.wc-block-components-text-input input:focus,
.wc-blocks-components-select__select:focus {
	border-color: var(--jv-color-forest) !important;
	outline: 2px solid var(--jv-color-mint) !important;
	outline-offset: 0 !important;
	box-shadow: none !important;
}

/* La etiqueta flotante hereda un gris frio que no es de la paleta. */
.wc-block-components-text-input label,
.wc-block-components-form .wc-block-components-text-input label {
	color: var(--jv-color-price-muted) !important;
	font-family: var(--jv-font-sans) !important;
}

.wc-block-components-text-input.is-active label {
	color: var(--jv-color-forest) !important;
}

/* Titulos de bloque ("Informacion de contacto", "Direccion de envio"...). */
.wc-block-components-title,
.wp-block-woocommerce-checkout-order-summary-block .wc-block-components-title {
	font-family: var(--jv-font-sans) !important;
	color: var(--jv-color-forest) !important;
	font-weight: 600 !important;
}

/* Resumen del pedido: caja con el mismo lenguaje que el resto de tarjetas. */
.wp-block-woocommerce-checkout-totals-block,
.wc-block-components-sidebar .wc-block-components-panel {
	border-radius: var(--jv-radius-card) !important;
}

.wc-block-components-totals-item__value,
.wc-block-components-totals-footer-item .wc-block-components-totals-item__value {
	color: var(--jv-color-forest) !important;
	font-weight: 600 !important;
}

/* Enlaces del checkout (politica de privacidad, editar carrito...). */
.wc-block-components-checkout-step__description a,
.wc-block-components-checkout-policies__item a,
.wc-block-components-sidebar a {
	color: var(--jv-color-forest) !important;
}

/* Radios de metodo de envio/pago seleccionados: el azul por defecto de los
   bloques se sustituye por el verde corporativo. */
.wc-block-components-radio-control__option--checked-option-highlighted,
.wc-block-components-radio-control-accordion-option--checked-option-highlighted {
	border-color: var(--jv-color-forest) !important;
	box-shadow: 0 0 0 1px var(--jv-color-forest) !important;
}

.wc-block-components-radio-control__input:checked {
	accent-color: var(--jv-color-forest);
}

/* Avisos de error: se mantienen rojos a proposito (un error debe leerse como
   error), pero se les da la tipografia y el radio del sitio. */
.wc-block-components-validation-error {
	font-family: var(--jv-font-sans) !important;
}

/* ==========================================================================
   Lineas del carrito propias del drawer
   --------------------------------------------------------------------------
   Sustituyen al markup de WC_Widget_Cart (ver jv_drawer_cart_contents): el
   widget no permitia cambiar cantidades ni mostraba el ahorro, y su "x" de
   eliminar era un caracter de texto.
   ========================================================================== */

.jv-drawer__contents-slot {
	display: flex;
	flex-direction: column;
	min-height: 100%;
}

.jv-drawer__items {
	margin: 0;
	padding: 0;
	list-style: none;
}

.jv-drawer__item {
	display: grid;
	grid-template-columns: 64px 1fr auto;
	gap: 12px;
	align-items: start;
	padding: 16px 0;
	border-bottom: 1px solid var(--jv-color-border);
}

.jv-drawer__item-media img {
	display: block;
	width: 64px;
	height: 64px;
	object-fit: contain;
	border: 1px solid var(--jv-color-border);
	background: var(--jv-color-surface);
}

.jv-drawer__item-info {
	min-width: 0; /* deja que el nombre largo se ajuste en vez de desbordar */
}

.jv-drawer__item-name {
	display: block;
	font-size: 14px;
	line-height: 1.35;
	font-weight: 600;
	color: var(--jv-color-ink);
	text-decoration: none;
}

.jv-drawer__item-meta {
	margin-top: 2px;
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

.jv-drawer__item-meta p {
	margin: 0;
}

.jv-drawer__item-row {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 10px;
	margin-top: 10px;
}

/* ── Selector de cantidad ─────────────────────────────────────────────── */

.jv-drawer__qty {
	display: inline-flex;
	align-items: stretch;
	border: 1px solid var(--jv-color-border);
}

.jv-drawer__qty-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 28px;
	padding: 0;
	background: var(--jv-color-surface);
	border: none;
	cursor: pointer;
	color: var(--jv-color-forest);
}

.jv-drawer__qty-btn:hover {
	background: var(--jv-color-mint-soft);
}

.jv-drawer__qty-btn .jv-icon {
	width: 10px;
	height: 10px;
}

.jv-drawer__qty-input {
	width: 38px;
	padding: 5px 2px;
	text-align: center;
	font-family: var(--jv-font-sans);
	font-size: 13px;
	color: var(--jv-color-ink);
	background: var(--jv-color-surface);
	border: none;
	border-left: 1px solid var(--jv-color-border);
	border-right: 1px solid var(--jv-color-border);
	-moz-appearance: textfield;
	appearance: textfield;
}

/* Las flechas nativas del input number compiten con los botones +/-. */
.jv-drawer__qty-input::-webkit-outer-spin-button,
.jv-drawer__qty-input::-webkit-inner-spin-button {
	-webkit-appearance: none;
	margin: 0;
}

.jv-drawer__item-price {
	text-align: right;
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-forest);
	white-space: nowrap;
}

.jv-drawer__item-save {
	display: block;
	margin-top: 2px;
	font-size: 11px;
	font-weight: 300;
	color: var(--jv-color-price-muted);
}

/* ── Papelera ─────────────────────────────────────────────────────────── */

.jv-drawer__item-remove {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 30px;
	height: 30px;
	padding: 0;
	background: none;
	border: none;
	cursor: pointer;
	color: var(--jv-color-price-muted);
	transition: color 0.15s ease;
}

.jv-drawer__item-remove:hover {
	color: var(--jv-color-forest);
}

.jv-drawer__item-remove .jv-icon {
	width: 15px;
	height: 15px;
}

/* ── Totales y accion final ───────────────────────────────────────────── */

.jv-drawer__totals {
	position: sticky;
	bottom: 0;
	margin-top: auto; /* empuja el bloque al fondo si el carrito es corto */
	padding: 14px 0 16px;
	background: var(--jv-color-surface);
	border-top: 1px solid var(--jv-color-border);
}

.jv-drawer__saving {
	display: flex;
	align-items: center;
	gap: 6px;
	margin: 0 0 8px;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-drawer__saving .jv-icon {
	width: 13px;
	height: 13px;
}

.jv-drawer__subtotal {
	display: flex;
	align-items: baseline;
	justify-content: space-between;
	margin: 0 0 12px;
	font-size: 15px;
	color: var(--jv-color-forest);
}

.jv-drawer__subtotal-value {
	font-size: 20px;
	font-weight: 600;
}

.jv-drawer__checkout {
	display: block;
	width: 100%;
	padding: 14px 16px;
	text-align: center;
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	text-decoration: none;
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
	border: 1px solid var(--jv-color-forest);
}

.jv-drawer__checkout:hover {
	filter: brightness(1.12);
	color: var(--jv-color-surface);
}

.jv-drawer__empty {
	padding: 48px 0;
	text-align: center;
	color: var(--jv-color-price-muted);
	font-size: 15px;
}

/* Mientras va la peticion de cantidad, el panel no acepta mas clics: evita
   que dos pulsaciones seguidas a "+" se pisen y dejen una cantidad erronea. */
.jv-drawer.is-busy .jv-drawer__body {
	opacity: 0.55;
	pointer-events: none;
}

/* ==========================================================================
   Checkout sin distracciones (inc/checkout-focus.php)
   --------------------------------------------------------------------------
   Cabecera reducida al logo y pie a lo legal: en la pagina que cobra, cada
   enlace de navegacion es una salida. El markup del menu ya no se genera en
   PHP; esto solo maqueta lo que queda.
   ========================================================================== */

.jv-checkout-header {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	max-width: var(--jv-container-max);
	margin: 0 auto;
	padding: 18px var(--jv-container-pad);
}

.jv-checkout-logo img {
	display: block;
	height: 44px;
	width: auto;
}

.jv-checkout-secure {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-checkout-secure .jv-icon {
	width: 14px;
	height: 14px;
}

/* La cabecera del checkout no se pega al hacer scroll: en un formulario
   largo, robar alto de pantalla estorba mas de lo que ayuda. */
.jv-checkout-focus .site-header {
	position: static !important;
	border-bottom: 1px solid var(--jv-color-border);
	background: var(--jv-color-surface);
}

/* Restos del tema que cuelgan fuera de los hooks desmontados. */
.jv-checkout-focus .jv-header-row-bg,
.jv-checkout-focus .storefront-breadcrumb,
.jv-checkout-focus .woocommerce-breadcrumb,
.jv-checkout-focus .jv-topbar,
.jv-checkout-focus .site-header-cart,
.jv-checkout-focus .storefront-handheld-footer-bar {
	display: none !important;
}

/* El titulo "Finalizar Compra" ocupaba una pantalla entera antes del
   formulario; se reduce para que el primer campo entre sin hacer scroll. */
.jv-checkout-focus .entry-title,
.jv-checkout-focus .page-title {
	font-size: 24px;
	margin: 0 0 20px;
	text-align: left;
}

.jv-checkout-focus .site-main {
	padding-top: 24px;
}

/* ── Pie minimo ───────────────────────────────────────────────────────── */

.jv-checkout-footer {
	max-width: var(--jv-container-max);
	margin: 0 auto;
	padding: 20px var(--jv-container-pad) 28px;
	border-top: 1px solid var(--jv-color-border);
	text-align: center;
}

.jv-checkout-footer__trust {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin: 0 0 10px;
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

.jv-checkout-footer__trust .jv-icon {
	width: 13px;
	height: 13px;
	color: var(--jv-color-forest);
}

.jv-checkout-footer__sep {
	color: var(--jv-color-border);
}

.jv-checkout-footer__links {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 6px 14px;
	margin: 0;
	font-size: 12px;
}

.jv-checkout-footer__links a {
	color: var(--jv-color-price-muted);
	text-decoration: none;
}

.jv-checkout-footer__links a:hover {
	color: var(--jv-color-forest);
	text-decoration: underline;
}

.jv-checkout-footer__copy {
	color: var(--jv-color-disabled-text);
}

@media (max-width: 600px) {
	.jv-checkout-header {
		padding: 14px 16px;
	}
	.jv-checkout-logo img {
		height: 34px;
	}
}

/* Orden dentro del carrito propio del drawer.
   Las reglas de order/display:contents que ordenaban el widget nativo de
   WooCommerce ya no aplican (ese widget se sustituyo por markup propio, ver
   jv_drawer_cart_contents), y sin ellas las sugerencias caian debajo del
   boton de comprar. Aqui se coloca cada bloque de forma explicita:
   lineas -> sugerencias -> totales. */
.jv-drawer__contents-slot {
	display: flex;
	flex-direction: column;
	min-height: 100%;
}

.jv-drawer__items { order: 1; }
.jv-drawer__cross-slot { order: 2; }
.jv-drawer__totals { order: 3; }
.jv-drawer__empty { order: 1; }

/* Las reglas heredadas del widget antiguo ya no tienen a quien aplicar; se
   neutralizan para que no interfieran con esta rejilla. */
.jv-drawer__body .widget_shopping_cart,
.jv-drawer__body .widget_shopping_cart_content {
	display: block;
}

/* La franja promocional superior tambien es distraccion en el checkout: habla
   de envios y recogida cuando el cliente ya esta pagando. Se oculta por CSS y
   no desmontando su hook porque la imprime el tema fuera de storefront_header,
   directamente en el body. */
.jv-checkout-focus .jv-top-bar {
	display: none !important;
}

/* Selector Particular / Empresa del checkout (inc/checkout-focus.php). */

.jv-client-type {
	display: flex;
	gap: 8px;
	margin: 0 0 18px;
}

.jv-client-type__tab {
	flex: 1 1 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 11px 12px;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-price-muted);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.jv-client-type__tab:hover {
	border-color: var(--jv-color-forest);
	color: var(--jv-color-forest);
}

.jv-client-type__tab.is-active {
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
	border-color: var(--jv-color-forest);
}

.jv-client-type__tab .jv-icon {
	width: 14px;
	height: 14px;
}

@media (max-width: 480px) {
	.jv-client-type__tab {
		font-size: 13px;
		padding: 10px 8px;
	}
}

/* ── Acceso dentro del checkout (inc/checkout-focus.php) ──────────────── */

.jv-login {
	margin: 0 0 20px;
}

.jv-login__tabs {
	display: flex;
	gap: 8px;
	margin-bottom: 12px;
}

.jv-login__tab {
	flex: 1 1 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: 7px;
	padding: 11px 12px;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-price-muted);
	background: var(--jv-color-surface);
	border: 1px solid var(--jv-color-border);
	cursor: pointer;
	transition: border-color 0.15s ease, color 0.15s ease;
}

.jv-login__tab:hover {
	border-color: var(--jv-color-forest);
	color: var(--jv-color-forest);
}

.jv-login__tab.is-active {
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
	border-color: var(--jv-color-forest);
}

.jv-login__tab .jv-icon {
	width: 13px;
	height: 13px;
}

.jv-login__panel {
	padding: 16px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
}

.jv-login__note {
	margin: 0 0 12px;
	font-size: 13px;
	color: var(--jv-color-price-muted);
}

.jv-login__field {
	margin-bottom: 12px;
}

.jv-login__field label {
	display: block;
	margin-bottom: 4px;
	font-size: 13px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-login__field input {
	width: 100%;
	padding: 11px 12px;
	font-family: var(--jv-font-sans);
	font-size: var(--jv-text-body);
	color: var(--jv-color-ink);
	background: var(--jv-color-surface);
	border: var(--jv-border-control);
	border-radius: var(--jv-radius-control);
}

.jv-login__field input:focus {
	border-color: var(--jv-color-forest);
	outline: 2px solid var(--jv-color-mint);
	outline-offset: 0;
}

.jv-login__actions {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 12px;
	flex-wrap: wrap;
}

.jv-login__submit {
	padding: 12px 22px;
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-surface);
	background: var(--jv-color-forest);
	border: 1px solid var(--jv-color-forest);
	cursor: pointer;
}

.jv-login__submit:hover:not(:disabled) {
	filter: brightness(1.12);
}

.jv-login__submit:disabled {
	background: var(--jv-color-disabled-bg);
	border-color: var(--jv-color-border);
	color: var(--jv-color-disabled-text);
	cursor: default;
}

.jv-login__lost {
	font-size: 13px;
	color: var(--jv-color-price-muted);
	text-decoration: underline;
}

.jv-login__lost:hover {
	color: var(--jv-color-forest);
}

.jv-login__msg {
	margin: 12px 0 0;
	padding: 10px 12px;
	font-size: 13px;
	background: var(--jv-color-mint-soft);
	color: var(--jv-color-forest);
}

/* El error de credenciales se marca con borde, no con un rojo nuevo: la
   paleta de marca solo admite los dos verdes. */
.jv-login__msg.is-error {
	background: var(--jv-color-surface);
	border-left: 3px solid var(--jv-color-forest);
	font-weight: 600;
}


/* ==========================================================================
   Fotos como <img> en lugar de background-image
   (jv-media-img-equivalencia)

   Las fotos del hero, de productos destacados y de servicios se pintaban
   con background-image en CSS incrustado. El navegador no descubre una
   imagen de fondo hasta procesar el CSS, asi que el LCP se retrasaba
   siempre; ademas un fondo no admite srcset (el movil se descargaba la
   foto de escritorio) y Google no lo indexa.

   Ahora son <img> reales. Estas reglas reproducen el comportamiento
   anterior pixel a pixel: el contenedor sigue siendo el mismo elemento
   absoluto de siempre, y la imagen de dentro replica background-size y
   background-position con object-fit y object-position.

   El hover (transform: scale) sigue aplicandose al contenedor, que es
   quien lo tenia, asi que la animacion no cambia.
   ========================================================================== */

.jv-hero__media > img,
.jv-top__media > img,
.jv-serv__media > img {
	width: 100%;
	height: 100%;
	display: block;
	object-position: center center;
}

/* cover: la foto llena el marco aunque se recorte por los lados. */
.jv-hero__media > img,
.jv-serv__media > img {
	object-fit: cover;
}

/* contain: el producto se ve entero, sin recortar. Es lo que ya hacia
   .jv-top__media y el motivo por el que el codigo pide 'medium_large' y
   no 'woocommerce_thumbnail' (ese viene recortado en cuadrado). */
.jv-top__media > img {
	object-fit: contain;
}


/* --------------------------------------------------------------------------
   Hero de categoria: la foto como <img>, no como fondo CSS

   El contenedor .jv-category-hero es un flex que alinea el texto abajo. La
   imagen se saca de ese flujo con position:absolute para que no empuje al
   texto, y se manda al fondo con z-index 0; el overlay del texto sube a 1.

   Se mantiene el background-color de respaldo de .jv-category-hero: se ve
   mientras la foto carga y en las categorias que no tienen imagen.
   -------------------------------------------------------------------------- */

.jv-category-hero__img {
	position: absolute;
	inset: 0;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	z-index: 0;
}

.jv-category-hero__overlay {
	position: relative;
	z-index: 1;
}


/* ==========================================================================
   Confianza y fecha de entrega junto al boton "Realizar el pedido"
   (jv_checkout_trust_near_button, inc/checkout-focus.php)

   El pie del checkout ya lleva SSL/envio/devolucion, pero en un formulario
   largo el pie no esta a la vista en el momento en que aparece la duda:
   justo antes de pulsar pagar. Este bloque repite lo esencial ahi mismo.
   ========================================================================== */

.jv-checkout-trust {
	background: var(--jv-color-mint);
	border-radius: var(--jv-radius-card);
	padding: 14px 16px;
	margin: 0 0 12px;
	text-align: center;
}

.jv-checkout-trust__delivery {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: 8px;
	margin: 0 0 8px;
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-checkout-trust__badges {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	justify-content: center;
	gap: 6px 16px;
	margin: 0;
	font-size: 12px;
	color: var(--jv-color-price-muted);
}

.jv-checkout-trust__badges span {
	display: inline-flex;
	align-items: center;
	gap: 5px;
}

.jv-checkout-trust .jv-icon {
	width: 14px;
	height: 14px;
	color: var(--jv-color-forest);
}

.jv-checkout-trust__badges .jv-icon {
	width: 13px;
	height: 13px;
}


/* ==========================================================================
   PLP rediseñada (categoria / tienda) — v5.0.0
   Referencia estructural: apple.com/shop/accessories/all, traducida al
   lenguaje de la home: caja recta, sin sombras, dos verdes, Poppins 300/600
   y bordes portantes colapsados.
   Todo lo de aqui usa clases NUEVAS (.jv-opener, .jv-catrow, .jv-pcard,
   .jv-gridhead, .jv-mas, .jv-seo) salvo las de filtro, que ya existian y
   van acotadas a .jv-plp2__aside a proposito: asi este bloque es INERTE
   hasta que llega el marcado que lo usa, y se puede subir por separado sin
   dejar la pagina a medias.
   ========================================================================== */

/* ============================================================
   PLP rediseñada — referencia apple.com/shop/accessories/all
   traducida al lenguaje de la home: caja recta, sin sombras,
   dos verdes, bordes portantes colapsados.
   ============================================================ */

.jv-plp2 { background: var(--jv-color-surface); }

.jv-plp2__crumbs {
  padding: 18px 0;
  font-size: 13px;
  font-weight: 300;
  color: var(--jv-color-price-muted);
}

.jv-plp2__crumbs a { color: var(--jv-color-price-muted); text-decoration: none; }
.jv-plp2__crumbs a:hover { text-decoration: underline; text-underline-offset: 3px; }
.jv-plp2__crumbs span { margin: 0 4px; }

/* ----- 1. Apertura: la pastilla oscura del hero de la home -----
   Mismo mecanismo que .jv-hero__inner: foto a sangre y el texto en un
   panel oscuro translúcido encima, centrado en vertical con top/bottom 0
   + height:fit-content + márgenes automáticos (no translateY(-50%), que
   cae en medio píxel con alturas impares y emborrona el texto).
   El borde izquierdo se alinea con la línea interior del lockup del
   logo, igual que en la home: NO es un px fijo, cuelga del contenedor. */

.jv-opener {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  overflow: hidden;
}

.jv-opener__media {
  height: clamp(320px, 36vw, 520px);
}

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

.jv-opener__panel {
  position: absolute;
  left: calc(
    (100% - var(--jv-container-max, 92%)) / 2
    + var(--jv-container-pad, 24px)
    + var(--jv-logo-square, 56px)
  );
  right: 48px;
  top: 0;
  bottom: 0;
  height: fit-content;
  margin-top: auto;
  margin-bottom: auto;
  z-index: 2;
  box-sizing: border-box;
  width: fit-content;
  max-width: 620px;
  padding: 28px 32px 32px;
  background: rgba(20, 33, 22, 0.78);
  color: #ffffff;
}

.jv-opener__title {
  margin: 0 0 18px;
  font-family: var(--jv-font-sans);
  font-size: clamp(38px, 4.2vw, 60px);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.02em;
  color: #ffffff;
}

.jv-opener__rule { display: none; }

.jv-opener__intro {
  margin: 0;
  max-width: 560px;
  font-family: var(--jv-font-sans);
  font-size: 18px;
  font-weight: 300;
  line-height: 1.6;
  color: #ffffff;
}

.jv-opener__meta {
  margin: 22px 0 0;
  font-size: 12px;
  font-weight: 300;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--jv-color-mint);
}

/* ----- 2. Fila de subcategorías -----
   Apple pone la foto en su marco y la etiqueta DEBAJO, nunca encima.
   Esto sustituye a las tarjetas con velo negro y nombre sobrepuesto:
   el velo era un tercer color fuera de la paleta y el texto blanco
   caía sobre fotos de cualquier luminosidad. */

.jv-catrow { padding: clamp(48px, 6vw, 88px) 0 0; }

.jv-catrow__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 24px;
  margin: 0 0 28px;
}

.jv-catrow__titulo {
  margin: 0;
  font-family: var(--jv-font-sans);
  font-size: clamp(22px, 2.4vw, 30px);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--jv-color-forest);
}

.jv-catrow__todas {
  font-size: 14px;
  font-weight: 300;
  color: var(--jv-color-forest);
  text-decoration: underline;
  text-underline-offset: 4px;
  white-space: nowrap;
}

.jv-catrow__todas:hover { text-decoration: none; }

.jv-catrow__track {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(160px, 1fr);
  gap: 24px;
  overflow-x: auto;
  padding-bottom: 8px;
}

.jv-catrow__item {
  display: block;
  text-decoration: none;
  color: var(--jv-color-ink);
}

.jv-catrow__media {
  display: block;
  border: 1px solid var(--jv-color-border);
  overflow: hidden;
  transition: border-color 200ms ease;
}

.jv-catrow__media img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  transition: transform 400ms ease;
}

/* min-height de dos líneas, no solo recorte: el recorte pone el techo
   pero no el suelo, y con un nombre de una línea ("Luminarias LED") la
   cuenta de debajo subía y dejaba de alinearse con la de al lado.
   Mismo problema y misma solución que en .jv-serv de la home. */
.jv-catrow__nombre {
  display: block;
  min-height: 2.6em;
  margin: 14px 0 2px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--jv-color-forest);
}

.jv-catrow__cuenta {
  display: block;
  font-size: 12px;
  font-weight: 300;
  color: var(--jv-color-price-muted);
}

.jv-catrow__item:hover .jv-catrow__media { border-color: var(--jv-color-forest); }
.jv-catrow__item:hover .jv-catrow__media img { transform: scale(1.05); }
.jv-catrow__item:hover .jv-catrow__nombre { text-decoration: underline; text-underline-offset: 3px; }

/* ----- 3. Cuerpo: filtros + rejilla ----- */

.jv-plp2__body {
  display: flex;
  align-items: flex-start;
  gap: clamp(32px, 4vw, 64px);
  /* Sin relleno inferior: el aire que separa la rejilla del bloque de
     texto lo pone ya el margen superior de .jv-seo, y sumarlos dejaba
     un hueco del doble. */
  padding: clamp(48px, 6vw, 88px) 0 0;
}

.jv-plp2__aside {
  flex: 0 0 232px;
  width: 232px;
  position: sticky;
  top: 120px;
}

.jv-plp2__main { flex: 1; min-width: 0; }

/* Encabezado de la rejilla: el titular grande de Apple + la barra de
   controles debajo, separados por una línea. */
.jv-gridhead { margin: 0 0 28px; }

/* Estas tres medidas las comparten la columna de filtros y la de la
   rejilla: son lo que hace que las dos líneas caigan a la misma altura.
   Si se toca una, se mueven las dos a la vez — que es justo lo que se
   quiere, en vez de un número mágico repetido en dos sitios. */
.jv-plp2 {
  --jv-plp-head-size: clamp(22px, 2.4vw, 30px);
  --jv-plp-head-lh: 1.2;
  --jv-plp-head-gap: 20px;
  --jv-plp-head-row: 38px;
  --jv-plp-head-pad: 16px;
}

.jv-gridhead__titulo {
  margin: 0 0 var(--jv-plp-head-gap);
  font-family: var(--jv-font-sans);
  font-size: var(--jv-plp-head-size);
  line-height: var(--jv-plp-head-lh);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--jv-color-forest);
}

/* box-sizing:content-box en las DOS barras, y no es un detalle: con
   border-box el min-height fija la caja entera, así que la barra del
   contador medía 55px (select 38 + padding 16 + borde 1) mientras el
   rótulo se quedaba clavado en los 38 del min-height. Esos eran los
   17px de desfase. En content-box el min-height gobierna solo la fila,
   y padding y borde se suman igual en ambas. */
.jv-gridhead__bar {
  box-sizing: content-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: var(--jv-plp-head-row);
  padding: 0 0 var(--jv-plp-head-pad);
  border-bottom: 1px solid var(--jv-color-border);
}

.jv-gridhead__count {
  font-size: 13px;
  font-weight: 300;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--jv-color-price-muted);
}

.jv-gridhead__tools { display: flex; align-items: center; gap: 12px; }

.jv-gridhead select {
  height: 38px;
  padding: 0 34px 0 12px;
  border: 1px solid var(--jv-color-border);
  border-radius: 0;
  background: var(--jv-color-surface);
  font-family: var(--jv-font-sans);
  font-size: 14px;
  font-weight: 300;
  color: var(--jv-color-ink);
}

.jv-viewtoggle { display: flex; }

.jv-viewtoggle button {
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 1px solid var(--jv-color-border);
  border-radius: 0;
  background: var(--jv-color-surface);
  color: var(--jv-color-forest);
  cursor: pointer;
}

.jv-viewtoggle button + button { margin-left: -1px; }

.jv-viewtoggle button.is-active {
  background: var(--jv-color-forest);
  color: #fff;
  border-color: var(--jv-color-forest);
}

.jv-viewtoggle svg { width: 16px; height: 16px; fill: currentColor; }

/* Rejilla de bordes colapsados con el MISMO grosor y color que el
   mosaico de la home (.jv-top): gap 0, borde de 4px en verde de marca
   y margen de -2px, así dos tarjetas contiguas solapan su borde y
   pintan UNA línea de 4px en vez de sumar 8px. */
/* minmax(0, 1fr) y NO 1fr a secas: `1fr` equivale a `minmax(auto, 1fr)`
   y ese `auto` es el min-content del hijo, así que una columna nunca
   baja de lo que pida el contenido más ancho que haya dentro. Los
   botones de formato del desplegable piden ~180px, y con `1fr` las dos
   columnas de móvil se ensanchaban hasta sacar 9px de scroll
   horizontal a toda la página. Con minmax(0,…) la columna puede ser
   más estrecha que su contenido y el recorte lo hace el overflow del
   desplegable. */
.jv-pgrid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.jv-pcard {
  position: relative;
  margin: -2px;
  border: 4px solid var(--jv-color-ink);
  background: var(--jv-color-surface);
}

/* El <li> NUNCA se saca del flujo: se queda anclado en su celda y solo
   vuela su CONTENIDO. Sacar el <li> con position:absolute hace que la
   rejilla recalcule las columnas para llenar el hueco y el vecino
   "salta" a ocupar su sitio. Mismo criterio que el hover original. */
.jv-pcard:hover { z-index: 5; }

/* position:static a propósito: el desplegable se ancla al <li> con
   top:100%, y si el interior fuera relative se anclaría a él. */
.jv-pcard__inner {
  position: static;
  display: flex;
  flex-direction: column;
  height: 100%;
  padding: 20px;
}

/* NADA sale del flujo al pasar el ratón, y esa es la clave del asunto.
   Antes el interior entero pasaba a position:absolute, y entonces la
   tarjeta dejaba de aportar altura a su fila: si resultaba ser la más
   alta de las cuatro, la fila se recalculaba a la siguiente más alta y
   TODA la rejilla pegaba un salto al pasar el cursor de una tarjeta a
   otra. Ahora el interior se queda quieto y solo cuelga el desplegable,
   que va absoluto y por tanto no cuenta para la altura de la fila. */

.jv-pcard__link {
  display: flex;
  flex-direction: column;
  flex: 1;
  text-decoration: none;
  color: var(--jv-color-ink);
}

/* Lo que se despliega: formatos y botón de compra. Oculto en reposo
   para bajar el ruido del listado, igual que en el original.

   Se anima con grid-template-rows de 0fr a 1fr, no con max-height: un
   max-height obliga a inventar un techo, y si te pasas el movimiento
   termina antes que la transición (el contenido deja de crecer pero el
   reloj sigue) y si te quedas corto recorta. Con 0fr→1fr la animación
   va exactamente hasta la altura natural, sea cual sea el número de
   formatos. display:none no vale aquí porque no es animable. */
/* Cuelga del <li> (de ahí que el interior NO pueda ser position:
   relative, o anclaría aquí). top:100% lo sitúa en el borde inferior de
   la tarjeta; el -4px y el +8px de ancho lo alinean con sus cantos. */
.jv-pcard__extra {
  position: absolute;
  top: 100%;
  left: -4px;
  width: calc(100% + 8px);
  box-sizing: border-box;
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  /* Cerrado no debe interceptar el ratón, o taparía la tarjeta de
     abajo con una caja invisible. */
  pointer-events: none;
  transition: grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1),
              opacity 200ms ease;
}

/* min-height:0 es obligatorio: por defecto un item de rejilla no baja
   de su min-content y la fila nunca llegaría a 0. */
.jv-pcard__extra-in {
  overflow: hidden;
  min-height: 0;
}

/* El fondo y el borde van AQUÍ dentro, no en .jv-pcard__extra: si los
   llevara el contenedor, con la fila a 0fr seguirían pintándose (el
   padding y el borde quedan fuera de la pista) y cada tarjeta cerrada
   arrastraría una franja de 4px colgando. Aquí los recorta el
   overflow:hidden y en reposo no se ve absolutamente nada.
   Sin borde superior y con fondo opaco tapa el borde inferior de la
   tarjeta, así el desplegable se lee como continuación de ella. */
.jv-pcard__extra-box {
  background: var(--jv-color-surface);
  border: 4px solid var(--jv-color-ink);
  border-top: 0;
  padding: 14px 16px 16px;
}

/* El aire de arriba lo pone el padding de la caja, no el margen del
   primer hijo: sin borde ni padding superior ese margen se escaparía
   de la caja (colapso de márgenes) y abriría un hueco por el que se
   vería el borde de la tarjeta. */
.jv-pcard__extra-box > :first-child { margin-top: 0; }

.jv-pcard:hover .jv-pcard__extra {
  grid-template-rows: 1fr;
  opacity: 1;
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  .jv-pcard__extra { transition: none; }
  .jv-pcard__media img { transition: none; }
}

.jv-pcard__variantes {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-top: 14px;
  padding: 10px;
  background: var(--jv-color-canvas);
  border: 1px solid var(--jv-color-border);
}

.jv-pcard__variante {
  max-width: 100%;
  overflow-wrap: anywhere;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  padding: 6px 10px;
  background: var(--jv-color-surface);
  border: 1px solid var(--jv-color-border);
  font-family: var(--jv-font-sans);
  font-size: 11px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--jv-color-forest);
  cursor: pointer;
}

.jv-pcard__variante span {
  font-weight: 300;
  color: var(--jv-color-price-muted);
}

.jv-pcard__variante:hover,
.jv-pcard__variante.is-sel {
  background: var(--jv-color-forest);
  border-color: var(--jv-color-forest);
  color: #ffffff;
}

.jv-pcard__variante:hover span,
.jv-pcard__variante.is-sel span { color: var(--jv-color-mint); }

/* El hover no puede oscurecer —no hay nada más oscuro que el verde de
   marca—, así que se invierte: fondo verde claro y texto verde oscuro. */
.jv-pcard__cta {
  display: block;
  width: 100%;
  margin-top: 12px;
  padding: 12px 16px;
  background: var(--jv-color-forest);
  border: 1px solid var(--jv-color-forest);
  border-radius: 0;
  font-family: var(--jv-font-sans);
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
  cursor: pointer;
}

.jv-pcard__cta:hover {
  background: var(--jv-color-mint);
  border-color: var(--jv-color-mint);
  color: var(--jv-color-forest);
}

.jv-pcard__media { display: block; }

/* Un respiro dentro del marco: sin él, las fotos que llegan al borde
   (barras LED apaisadas) tocan la línea de la tarjeta mientras las
   verticales dejan aire, y la rejilla se lee irregular. */
.jv-pcard__media img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  background: transparent;
  padding: 8px;
  transition: transform 400ms ease;
}

.jv-pcard:hover .jv-pcard__media img { transform: scale(1.04); }

.jv-pcard__body {
  display: flex;
  flex-direction: column;
  flex: 1;
  margin-top: 18px;
}

/* La marca hace de eyebrow: es el dato que Apple pone en pequeño y en
   color sobre el nombre ("Only at Apple"), y aquí sí informa. */
.jv-pcard__marca {
  display: block;
  margin: 0 0 8px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--jv-color-price-muted);
}

.jv-pcard__nombre {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0 0 8px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  color: var(--jv-color-forest);
}

.jv-pcard__desc {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin: 0 0 16px;
  font-size: 13px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--jv-color-price-muted);
}

.jv-pcard__precio {
  display: block;
  margin-top: auto;
  font-size: 18px;
  font-weight: 600;
  color: var(--jv-color-forest);
}

/* ----- Carga progresiva ----- */

.jv-mas {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  padding: 36px 0 0;
  text-align: center;
}

/* Es solo la marca que vigila el observador, y va FUERA del flujo. Con
   position:static y margin-top:-400px —como estaba— el margen negativo
   de un item de flex arrastra hacia arriba a todos sus hermanos: el
   botón y el contador se subían 400px y quedaban solapados sobre la
   última fila de productos. Absoluta, se adelanta sin empujar nada. */
.jv-mas__centinela {
  position: absolute;
  top: -400px;
  left: 0;
  width: 100%;
  height: 1px;
  pointer-events: none;
}

.jv-mas__cargando,
.jv-mas__fin,
.jv-mas__progreso {
  margin: 0;
  font-size: 13px;
  font-weight: 300;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--jv-color-price-muted);
}

.jv-mas__boton {
  display: inline-block;
  padding: 14px 32px;
  background: var(--jv-color-forest);
  border: 1px solid var(--jv-color-forest);
  font-size: 14px;
  font-weight: 600;
  color: #ffffff;
  text-decoration: none;
}

.jv-mas__boton:hover {
  background: var(--jv-color-mint);
  border-color: var(--jv-color-mint);
  color: var(--jv-color-forest);
}

.jv-mas__boton[hidden],
.jv-mas__cargando[hidden],
.jv-mas__fin[hidden] { display: none; }

/* ----- Bloque posterior a la rejilla ----- */

/* Vive FUERA de .jv-plp2__body, o sea fuera de la columna de la
   rejilla: este bloque describe la categoría entera, no el listado
   filtrado, así que ocupa el ancho completo del contenedor y arranca a
   ras del sidebar en vez de quedar indentado detrás de él. */
.jv-seo {
  margin-top: clamp(56px, 6vw, 88px);
  padding-top: clamp(32px, 4vw, 48px);
  padding-bottom: 64px;
  border-top: 1px solid var(--jv-color-border);
}

.jv-seo__text {
  margin: 0 0 16px;
  font-size: 15px;
  font-weight: 300;
  line-height: 1.75;
  color: var(--jv-color-ink);
}

.jv-seo__benefs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 0;
  margin: 32px 0;
}

.jv-seo__benef {
  margin: -1px;
  padding: 20px;
  border: 2px solid var(--jv-color-border);
}

.jv-seo__benef strong {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--jv-color-forest);
}

.jv-seo__benef span {
  font-size: 13px;
  font-weight: 300;
  line-height: 1.55;
  color: var(--jv-color-price-muted);
}

.jv-seo__list {
  list-style: none;
  margin: 0 0 40px;
  padding: 0;
}

.jv-seo__list li {
  padding: 9px 0;
  border-bottom: 1px solid var(--jv-color-border);
  font-size: 14px;
  font-weight: 300;
}

.jv-seo__list a {
  color: var(--jv-color-forest);
  text-decoration: none;
}

.jv-seo__list a:hover { text-decoration: underline; text-underline-offset: 3px; }
.jv-seo__list span { color: var(--jv-color-price-muted); }

.jv-seo__faqtitle {
  margin: 0 0 16px;
  font-size: clamp(20px, 2.2vw, 26px);
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--jv-color-forest);
}

.jv-faq { border-bottom: 1px solid var(--jv-color-border); }

.jv-faq:first-of-type { border-top: 1px solid var(--jv-color-border); }

.jv-faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  width: 100%;
  padding: 18px 0;
  border: 0;
  background: none;
  font-family: var(--jv-font-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--jv-color-forest);
  text-align: left;
  cursor: pointer;
}

.jv-faq__q[aria-expanded="true"] .jv-chev { transform: rotate(180deg); }

/* Misma técnica que el desplegable de la tarjeta: 0fr a 1fr abre hasta
   la altura real de la respuesta, sin techo inventado. */
.jv-faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 260ms cubic-bezier(0.4, 0, 0.2, 1);
}

.jv-faq__q[aria-expanded="true"] + .jv-faq__a { grid-template-rows: 1fr; }

.jv-faq__a p {
  overflow: hidden;
  min-height: 0;
  margin: 0;
  font-size: 14px;
  font-weight: 300;
  line-height: 1.7;
  color: var(--jv-color-ink);
}

.jv-faq__q[aria-expanded="true"] + .jv-faq__a p { padding-bottom: 18px; }

@media (prefers-reduced-motion: reduce) {
  .jv-faq__a { transition: none; }
}

/* ----- 4. Filtros: misma estructura, menos peso visual ----- */

/* El hueco que ocupa el titular de la rejilla en la otra columna. Se
   calcula de los mismos tokens (tamaño x interlineado + separación), no
   se estima: así la línea de "Filtrar" y la del contador caen a la
   misma altura a cualquier anchura, aunque el clamp del titular cambie
   de valor por el camino. */
.jv-plp2__aside-head::before {
  content: '';
  display: block;
  height: calc(var(--jv-plp-head-size) * var(--jv-plp-head-lh));
  margin-bottom: var(--jv-plp-head-gap);
}

.jv-plp2__aside .jv-plp-sidebar__title {
  box-sizing: content-box;
  display: flex;
  align-items: center;
  min-height: var(--jv-plp-head-row);
  margin: 0;
  padding: 0 0 var(--jv-plp-head-pad);
  border-bottom: 1px solid var(--jv-color-border);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--jv-color-price-muted);
}

/* Sin border-top propio: la línea de arriba ya la pone el rótulo
   "Filtrar", y duplicarla pintaba dos rayas pegadas. */
.jv-plp2__aside .jv-filter-section { margin: 0; border-bottom: 1px solid var(--jv-color-border); }

.jv-plp2__aside .jv-filter-section__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  width: 100%;
  padding: 16px 0;
  border: 0;
  background: none;
  font-family: var(--jv-font-sans);
  font-size: 15px;
  font-weight: 600;
  color: var(--jv-color-forest);
  text-align: left;
  cursor: pointer;
}

.jv-chev {
  width: 14px;
  height: 14px;
  flex: 0 0 auto;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  transition: transform 200ms ease;
}

.jv-plp2__aside .jv-filter-section.is-open .jv-chev { transform: rotate(180deg); }

.jv-plp2__aside .jv-filter-list { list-style: none; margin: 0; padding: 0 0 16px; }

.jv-plp2__aside .jv-filter-list a {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 7px 0;
  font-size: 14px;
  font-weight: 300;
  color: var(--jv-color-ink);
  text-decoration: none;
}

.jv-plp2__aside .jv-filter-list a:hover {
  color: var(--jv-color-forest);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.jv-plp2__aside .jv-filter-count { font-size: 12px; color: var(--jv-color-price-muted); flex: 0 0 auto; }

/* ----- Anchuras ----- */

@media (max-width: 1400px) { .jv-pgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }

@media (max-width: 1000px) {
  /* align-items pasa a gobernar el ANCHO al girar a columna: con el
     flex-start de escritorio (que está para que el sticky no se estire)
     cada hijo encoge a su contenido y saca scroll horizontal. */
  .jv-plp2__body { flex-direction: column; align-items: stretch; }

  /* Los productos van PRIMERO. Con nueve secciones de filtro por delante
     había que pasar una pantalla y media de acordeones antes de ver un
     solo producto. */
  .jv-plp2__main { order: 1; }
  .jv-plp2__aside { order: 2; position: static; width: 100%; flex: none; }

  /* En una columna no hay nada con lo que alinear: el hueco reservado
     para el titular de la rejilla sería aire muerto sobre "Filtrar". */
  .jv-plp2__aside-head::before { display: none; }

  /* La pastilla deja de flotar sobre la foto y pasa a ocupar el ancho
     del contenedor: a 390px, superpuesta y con el sangrado del lockup,
     se comía la foto entera y el texto quedaba sobre la parte más
     clara de la imagen. */
  .jv-opener { width: auto; margin-left: 0; }
  .jv-opener__panel {
    position: static;
    width: auto;
    max-width: none;
    padding: 24px;
    /* Opaco y en verde de marca: el rgba(20,33,22,.78) de la home está
       pensado para ir SOBRE una foto. Aquí el panel cae sobre blanco y
       ese 0,78 lo lavaba a un gris verdoso. */
    background: var(--jv-color-forest);
  }
  .jv-opener__title { font-size: clamp(30px, 7vw, 40px); }
  .jv-opener__intro { font-size: 16px; }

  /* El titular y el enlace dejan de compartir línea: en space-between el
     enlace no encoge y estrujaba el título a dos líneas. */
  .jv-catrow__head { flex-direction: column; align-items: flex-start; gap: 10px; }
}

/* La barra de controles se parte antes que desbordar: el select más el
   par de botones no caben en una línea de 390px y el segundo botón se
   salía de la pantalla. */
@media (max-width: 620px) {
  .jv-gridhead__bar { flex-wrap: wrap; gap: 12px; }
  .jv-gridhead__tools { width: 100%; justify-content: space-between; }
  .jv-gridhead select { flex: 1; min-width: 0; }
}

@media (max-width: 700px) {
  .jv-pgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .jv-pcard__link { padding: 14px; }
  .jv-pcard__desc { display: none; }
}

/* --- Añadido del paso 2 --------------------------------------------- */

/* Categoría sin foto (Kits de Cultivo Interior, Uncategorized): la
   pastilla no puede flotar sobre una imagen que no existe, así que pasa a
   bloque en flujo con el verde de marca opaco. */
.jv-opener--sin-foto .jv-opener__panel {
  position: static;
  width: auto;
  max-width: none;
  background: var(--jv-color-forest);
}

/* 70 subcategorías no tienen foto propia. Cuando tampoco hay foto del
   padre de la que tirar, el marco queda como superficie lisa en vez de
   como un hueco roto. */
.jv-catrow__media--vacio {
  display: block;
  aspect-ratio: 4 / 3;
  background: var(--jv-color-mint-soft);
}

/* La fila de marcas enseña logos con texto ancho: contain para verlos
   enteros, no cover, que los recorta. */
.jv-catrow__item--marca .jv-catrow__media img {
  object-fit: contain;
  padding: 12px;
  background: var(--jv-color-surface);
}

/* --- Paso 3: tarjeta y rejilla ---------------------------------------
   Se adapta al marcado REAL del bucle (.jv-loop-card-inner lo crea el JS
   de inc/loop-hover-variants.php), no al de la maqueta. */

/* Bordes colapsados, igual que el mosaico de la home: gap 0, borde de 4px
   y margen de -2px, asi dos tarjetas contiguas funden su borde en UNA
   linea en vez de sumar 8px. */
.jv-plp-main ul.products,
.woocommerce.tax-product_cat ul.products,
.woocommerce.post-type-archive-product ul.products {
	gap: 0 !important;
}

.woocommerce ul.products li.product.jv-pcard,
.woocommerce-page ul.products li.product.jv-pcard {
	border: 4px solid var(--jv-color-ink);
	border-radius: 0;
	margin: -2px !important;
	padding: 0;
	background: var(--jv-color-surface);
	transition: none;
}

.jv-pcard .jv-loop-card-inner {
	padding: 20px;
	background: var(--jv-color-surface);
}

/* Al expandirse cubre exactamente el <li> incluido su borde: -4px arriba
   e izquierda, +8px de ancho. */
.jv-pcard.is-hover-expanded .jv-loop-card-inner {
	top: -4px;
	left: -4px;
	width: calc(100% + 8px);
	border: 4px solid var(--jv-color-ink);
	border-radius: 0;
	padding: 20px;
	box-shadow: none;
}

/* El fondo NO cambia al pasar el raton (peticion expresa). La senal es la
   foto, que se acerca un punto. */
.woocommerce ul.products li.product.jv-pcard:hover,
.woocommerce-page ul.products li.product.jv-pcard:hover {
	background: var(--jv-color-surface);
	border-color: var(--jv-color-ink);
}

/* Fuera la lupa flotante: es una falsa afordancia (no abre nada) y traia
   un hex fuera de los tokens de marca. */
.jv-pcard a.woocommerce-LoopProduct-link::after {
	content: none !important;
	display: none !important;
}

/* Jerarquia de Apple: marca / nombre / descripcion / precio, a la
   izquierda. El bucle venia centrado. */
.jv-pcard .woocommerce-loop-product__title,
.jv-pcard .jv-loop-short-desc,
.jv-pcard .jv-loop-price-row,
.jv-pcard .price {
	text-align: left;
}

.jv-pcard .jv-loop-price-row {
	justify-content: flex-start;
}

.jv-loop-marca {
	display: block;
	margin: 14px 0 6px;
	font-family: var(--jv-font-sans);
	font-size: 11px;
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--jv-color-price-muted);
}

.jv-pcard .woocommerce-loop-product__title {
	margin-top: 0;
	font-size: 15px;
	line-height: 1.35;
	color: var(--jv-color-forest);
}

/* El anillo de foco se dibuja por fuera, o sea encima del borde del
   vecino: metido hacia dentro cae sobre el blanco interior. */
.jv-pcard a:focus-visible {
	outline-offset: -10px;
}

/* --- Paso 3b: alineacion a la izquierda ------------------------------
   Storefront centra con `.woocommerce ul.products li.product` (0,2,2) y
   con reglas propias sobre el titulo, asi que un `.jv-pcard .titulo`
   (0,2,0) perdia y todo seguia centrado. Hay que igualar/superar esa
   especificidad, no repetir la propiedad. */
.woocommerce ul.products li.product.jv-pcard,
.woocommerce-page ul.products li.product.jv-pcard,
.woocommerce ul.products li.product.jv-pcard .jv-loop-card-inner,
.woocommerce-page ul.products li.product.jv-pcard .jv-loop-card-inner {
	text-align: left;
}

.woocommerce ul.products li.product.jv-pcard .woocommerce-loop-product__title,
.woocommerce-page ul.products li.product.jv-pcard .woocommerce-loop-product__title,
.woocommerce ul.products li.product.jv-pcard .jv-loop-short-desc,
.woocommerce ul.products li.product.jv-pcard .price,
.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row {
	text-align: left;
}

.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row,
.woocommerce-page ul.products li.product.jv-pcard .jv-loop-price-row {
	justify-content: flex-start;
}

/* --- Paso 4b: ajustes al activar el sidebar nuevo --------------------- */

/* .jv-plp2 se usa solo como portador de los tokens compartidos de
   cabecera; el fondo lo pone la pagina, no el layout. */
.jv-plp-layout.jv-plp2 { background: transparent; }

/* El sticky tiene que descontar el header pegado, como ya hacia
   .jv-plp-sidebar. Mi regla venia despues en la cascada con un 120px
   fijo y le ganaba, dejando el primer filtro debajo del header. */
.jv-plp-sidebar.jv-plp2__aside {
	top: calc(var(--jv-header-height) + 24px);
	width: 240px;
	flex: 0 0 240px;
}

@media (max-width: 900px) {
	.jv-plp-sidebar.jv-plp2__aside { position: static; width: 100%; flex: none; }
	.jv-plp2__aside-head::before { display: none; }
}

/* --- Paso 4c/6b: ancho del bloque posterior y alineacion de lineas ---- */

/* El bloque ya sale del layout, pero conservaba su tope de ancho antiguo
   (760px medidos). A ancho completo del contenedor, como se pidio. */
.jv-category-seo {
	max-width: none;
	width: auto;
	margin-top: clamp(56px, 6vw, 88px);
	padding-top: clamp(32px, 4vw, 48px);
	padding-bottom: 64px;
	border-top: 1px solid var(--jv-color-border);
}

.jv-category-seo__text {
	max-width: none;
}

/* Storefront le da margen inferior a sus formularios, y el de orden vive
   dentro de la barra: sumaba ~10px de alto y descuadraba la linea del
   contador respecto a la de "Filtrar" (medido 9,78px). */
.jv-gridhead .woocommerce-ordering,
.jv-gridhead form.woocommerce-ordering {
	margin: 0;
	padding: 0;
}

.jv-gridhead select,
.jv-gridhead .woocommerce-ordering select {
	height: 38px;
	margin: 0;
	padding: 0 34px 0 12px;
	border: 1px solid var(--jv-color-border);
	border-radius: 0;
	background-color: var(--jv-color-surface);
	font-family: var(--jv-font-sans);
	font-size: 14px;
	font-weight: 300;
	color: var(--jv-color-ink);
}

/* Los botones de vista median 42px y eran ellos, no el select, los que
   fijaban el alto de la barra: 4px mas que la fila del rotulo "Filtrar".
   Igualados a 38, las dos lineas caen a la misma altura. */
.jv-gridhead .jv-view-toggle__btn {
	width: 38px;
	height: 38px;
	padding: 0;
	border-radius: 0;
}

/* Medido: el contenedor .jv-view-toggle media 48px (padding propio de
   4px + su caja), no los botones, y era el que estiraba la barra a 65px
   frente a los 55 del rotulo "Filtrar". Igualado a la fila de 38. */
.jv-gridhead .jv-view-toggle {
	height: 38px;
	padding: 0;
	align-items: center;
}

/* ======================================================================
   Paso 7 — portar al marcado REAL lo que se quedo escrito contra las
   clases de la maqueta.

   Medido: 16 clases de la maqueta (.jv-pcard__*, .jv-seo, .jv-faq*) no
   existen en produccion, asi que sus reglas eran letra muerta. Aqui se
   reescriben contra las clases que el tema si emite.
   ====================================================================== */

/* ---- Interior de la tarjeta ---------------------------------------- */

/* Un respiro dentro del marco: sin el, las fotos apaisadas que llegan al
   borde tocan la linea de la tarjeta mientras las verticales dejan aire,
   y la rejilla se lee irregular. */
.woocommerce ul.products li.product.jv-pcard img,
.woocommerce-page ul.products li.product.jv-pcard img {
	padding: 8px;
	background: transparent;
}

/* Recorte a DOS lineas, no solo tope: reservar el alto evita que el
   precio baile de tarjeta a tarjeta dentro de la misma fila. */
.woocommerce ul.products li.product.jv-pcard .woocommerce-loop-product__title,
.woocommerce-page ul.products li.product.jv-pcard .woocommerce-loop-product__title {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 2.7em;
	margin: 0 0 8px;
	font-size: 15px;
	font-weight: 600;
	line-height: 1.35;
}

.woocommerce ul.products li.product.jv-pcard .jv-loop-short-desc,
.woocommerce-page ul.products li.product.jv-pcard .jv-loop-short-desc {
	display: -webkit-box;
	-webkit-line-clamp: 2;
	-webkit-box-orient: vertical;
	overflow: hidden;
	min-height: 3.1em;
	margin: 0 0 12px;
	font-size: 13px;
	font-weight: 300;
	line-height: 1.55;
	color: var(--jv-color-price-muted);
}

.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row,
.woocommerce-page ul.products li.product.jv-pcard .jv-loop-price-row {
	margin-top: 0;
	gap: 8px;
}

.woocommerce ul.products li.product.jv-pcard .price,
.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row ins {
	font-size: 18px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

/* ---- Apertura suave del desplegable --------------------------------
   El panel de formatos abria con display:none -> flex, que no es
   animable: aparecia de golpe. Con grid-template-rows de 0fr a 1fr la
   apertura llega exactamente a la altura natural, sea cual sea el numero
   de formatos, sin inventar un techo con max-height. */
.jv-pcard .jv-loop-variants {
	display: grid !important;
	grid-template-rows: 0fr;
	gap: 0;
	padding: 0;
	margin-top: 0;
	border: 0;
	opacity: 0;
	overflow: hidden;
	transition: grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1),
	            opacity 200ms ease,
	            margin-top 280ms cubic-bezier(0.4, 0, 0.2, 1);
}

.jv-pcard.is-hover-expanded .jv-loop-variants {
	grid-template-rows: 1fr;
	margin-top: 10px;
	opacity: 1;
}

/* La caja visible va DENTRO de la pista: si el fondo y el borde los
   llevara el contenedor, con la fila a 0fr seguirian pintandose (quedan
   fuera de la pista) y cada tarjeta cerrada arrastraria una franja. */
.jv-pcard .jv-loop-variants > * {
	min-width: 0;
}

.jv-pcard .jv-loop-variants::before {
	content: none;
}

/* ---- Bloque posterior a la rejilla ---------------------------------- */

.jv-category-benefits {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
	gap: 0;
	margin: 32px 0;
}

/* Bordes colapsados, mismo recurso que la rejilla de producto. */
.jv-benefit-card {
	margin: -1px;
	padding: 20px;
	border: 2px solid var(--jv-color-border);
	border-radius: 0;
	background: var(--jv-color-surface);
	box-shadow: none;
}

.jv-benefit-card__title {
	display: block;
	margin: 0 0 6px;
	font-size: 14px;
	font-weight: 600;
	color: var(--jv-color-forest);
}

.jv-benefit-card__text {
	font-size: 13px;
	font-weight: 300;
	line-height: 1.55;
	color: var(--jv-color-price-muted);
}

.jv-category-seo__list {
	list-style: none;
	margin: 0 0 40px;
	padding: 0;
}

.jv-category-seo__list li {
	display: flex;
	align-items: baseline;
	gap: 8px;
	padding: 9px 0;
	border-bottom: 1px solid var(--jv-color-border);
	font-size: 14px;
	font-weight: 300;
}

.jv-category-seo__list a {
	color: var(--jv-color-forest);
	text-decoration: none;
}

.jv-category-seo__list a:hover {
	text-decoration: underline;
	text-underline-offset: 3px;
}

.jv-category-seo__list span { color: var(--jv-color-price-muted); }

.jv-category-faqs__title {
	margin: 0 0 16px;
	font-size: clamp(20px, 2.2vw, 26px);
	font-weight: 600;
	letter-spacing: -0.015em;
	color: var(--jv-color-forest);
}

.jv-faq-item { border-bottom: 1px solid var(--jv-color-border); }
.jv-faq-item:first-of-type { border-top: 1px solid var(--jv-color-border); }

.jv-faq-item__question {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: 16px;
	width: 100%;
	padding: 18px 0;
	border: 0;
	background: none;
	font-family: var(--jv-font-sans);
	font-size: 15px;
	font-weight: 600;
	color: var(--jv-color-forest);
	text-align: left;
	cursor: pointer;
}

.jv-faq-item__question .jv-icon { transition: transform 200ms ease; }
.jv-faq-item__question[aria-expanded="true"] .jv-icon { transform: rotate(180deg); }

/* Misma tecnica que el desplegable de la tarjeta, para que no haya dos
   formas distintas de abrir cosas en la misma pagina. */
.jv-faq-item__answer {
	display: grid;
	grid-template-rows: 0fr;
	transition: grid-template-rows 260ms cubic-bezier(0.4, 0, 0.2, 1);
}

.jv-faq-item__question[aria-expanded="true"] + .jv-faq-item__answer {
	grid-template-rows: 1fr;
}

.jv-faq-item__answer p {
	overflow: hidden;
	min-height: 0;
	margin: 0;
	font-size: 14px;
	font-weight: 300;
	line-height: 1.7;
	color: var(--jv-color-ink);
}

.jv-faq-item__question[aria-expanded="true"] + .jv-faq-item__answer p {
	padding-bottom: 18px;
}

@media (prefers-reduced-motion: reduce) {
	.jv-pcard .jv-loop-variants,
	.jv-faq-item__answer { transition: none; }
}

/* El envoltorio interno es el UNICO hijo de la rejilla, que es lo que
   exige la apertura 0fr->1fr; los botones colgaban directos y cada uno
   creaba una fila implicita que el 0fr no gobernaba. El fondo y el borde
   van aqui dentro para que el overflow los recorte: en el contenedor
   quedarian fuera de la pista y se verian con el panel cerrado. */
.jv-pcard .jv-loop-variants__in {
	overflow: hidden;
	min-height: 0;
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	padding: 10px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
}

/* Ajustes finales para igualar la maqueta al pixel (medido con
   getComputedStyle en ambas): el sidebar iba a 240px y la maqueta lo
   tiene en 232, y el margen bajo la marca era de 6px en vez de 8. El
   ancho de columna de la rejilla se corrige solo al cambiar el sidebar. */
.jv-plp-sidebar.jv-plp2__aside {
	width: 232px;
	flex: 0 0 232px;
}

.jv-loop-marca {
	margin-bottom: 8px;
}

/* Tres niveles, cada uno con un trabajo: .jv-loop-variants anima la
   pista, __in la recorta, __box pinta. Con el padding y el borde en __in
   —fuera de la pista— el panel cerrado seguia midiendo 22px. */
.jv-pcard .jv-loop-variants__in {
	overflow: hidden;
	min-height: 0;
	display: block;
	padding: 0;
	border: 0;
	background: none;
}

.jv-pcard .jv-loop-variants__box {
	display: flex;
	flex-wrap: wrap;
	gap: 6px;
	padding: 10px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
}

/* La rejilla usa el mismo contenedor que el resto de la pagina, como en
   la maqueta. Iba a ancho de viewport (100vw + 32px), asi que el bloque
   de texto de abajo —que si usa el contenedor— salia mas estrecho que la
   rejilla y las dos cajas no alineaban. */
.jv-plp-layout.jv-plp-layout--wide.jv-plp2 {
	width: auto;
	max-width: none;
	margin-left: 0;
	padding: 0;
}

/* Ultimo desajuste medido: la separacion entre el sidebar y la rejilla
   era de 40px (heredada del layout anterior) y la maqueta la tiene en
   clamp(32,4vw,64) = 57,6px a 1440. Eran justo los 17,6px que sobraban
   repartidos entre las cuatro columnas. */
.jv-plp-layout.jv-plp2 {
	gap: clamp(32px, 4vw, 64px);
}

/* La fila de subcategorias heredaba el centrado del carrusel anterior:
   la maqueta alinea la etiqueta y la cuenta a la IZQUIERDA, bajo el
   borde de su foto. */
.jv-catrow__item,
.jv-catrow__nombre,
.jv-catrow__cuenta {
	text-align: left;
}

/* Fondo blanco en toda la pagina de categoria, como la maqueta: el
   canvas verdoso partia la pagina en bandas que la maqueta no tiene. */
.tax-product_cat,
.post-type-archive-product,
.tax-product_cat #page,
.post-type-archive-product #page,
.tax-product_cat #content,
.post-type-archive-product #content {
	background: var(--jv-color-surface);
}

/* --- Igualar a la maqueta: hero y preguntas frecuentes ---------------- */

/* El panel del hero heredaba el centrado del hero anterior. En la maqueta
   el texto va a la IZQUIERDA, alineado con la linea interior del lockup
   del logo, que es lo que ata este bloque con la home. */
.jv-opener__panel,
.jv-opener__title,
.jv-opener__intro,
.jv-opener__meta {
	text-align: left;
}

/* Las preguntas eran cajas con borde en los cuatro lados, fondo blanco y
   8px de separacion entre ellas (medido). La maqueta las deja como una
   lista de filetes: solo linea inferior, sin caja y sin margen, para que
   se lean como una tabla y no como cinco tarjetas sueltas. */
.jv-category-faqs .jv-faq-item {
	border: 0;
	border-bottom: 1px solid var(--jv-color-border);
	border-radius: 0;
	background: none;
	margin: 0;
	padding: 0;
	box-shadow: none;
}

.jv-category-faqs .jv-faq-item:first-of-type {
	border-top: 1px solid var(--jv-color-border);
}

.jv-category-faqs .jv-faq-item__question {
	padding: 18px 0;
	background: none;
	border: 0;
}

/* El chevron iba a 18px y pesaba de mas frente al filete. */
.jv-category-faqs .jv-faq-item__question .jv-icon {
	width: 14px;
	height: 14px;
}

/* --- Espacio migas -> hero y paginacion numerica ---------------------- */

/* El envoltorio de migas de Storefront metia 55,6px de margen inferior
   mas 21,2 de relleno: 76,8px de aire entre las migas y la foto. La
   maqueta deja 18. */
.tax-product_cat .storefront-breadcrumb,
.post-type-archive-product .storefront-breadcrumb {
	margin-bottom: 0;
	padding-top: 18px;
	padding-bottom: 18px;
}

/* Fuera la paginacion numerica: con carga progresiva sobran, y ademas
   eran la via por la que se acababa en la ultima pagina —la 10 de
   Iluminacion, con 4 productos sueltos y sin zona de carga porque ya no
   hay pagina siguiente—, que parece un listado roto.
   Se ocultan, NO se eliminan del HTML: los enlaces siguen en el
   documento para que Google recorra el catalogo, y el boton "Ver mas
   productos" es tambien un enlace real a la pagina siguiente. */
.tax-product_cat .woocommerce-pagination,
.post-type-archive-product .woocommerce-pagination {
	position: absolute;
	width: 1px;
	height: 1px;
	margin: -1px;
	padding: 0;
	overflow: hidden;
	clip: rect(0 0 0 0);
	clip-path: inset(50%);
	white-space: nowrap;
	border: 0;
}

/* --- El contenido de la tarjeta deja de salir del flujo --------------- */

/* Se anula la expansion por superposicion del tema: el interior se queda
   siempre en su sitio, asi la celda nunca deja de aportar su altura a la
   fila y no hay nada que compensar. */
.jv-pcard.is-hover-expanded .jv-loop-card-inner,
.woocommerce ul.products li.product.jv-pcard.is-hover-expanded .jv-loop-card-inner {
	position: relative;
	top: auto;
	left: auto;
	width: auto;
	border: 0;
	padding: 20px;
	background: none;
}

/* El desplegable cuelga del <li> y es lo unico absoluto. top:100% lo
   coloca en el borde inferior de la tarjeta; -4px y +8px de ancho lo
   alinean con sus cantos. */
.jv-pcard .jv-pcard__extra {
	position: absolute;
	top: 100%;
	left: -4px;
	width: calc(100% + 8px);
	box-sizing: border-box;
	display: grid;
	grid-template-rows: 0fr;
	opacity: 0;
	pointer-events: none;
	z-index: 5;
	transition: grid-template-rows 280ms cubic-bezier(0.4, 0, 0.2, 1),
	            opacity 200ms ease;
}

.jv-pcard .jv-pcard__extra-in {
	overflow: hidden;
	min-height: 0;
	background: var(--jv-color-surface);
	border: 4px solid var(--jv-color-ink);
	border-top: 0;
	padding: 0 16px 16px;
}

.jv-pcard:hover { z-index: 6; }

.jv-pcard:hover .jv-pcard__extra {
	grid-template-rows: 1fr;
	opacity: 1;
	pointer-events: auto;
}

/* Dentro del desplegable los dos elementos vuelven a comportarse como
   bloques normales: ya no necesitan ocultarse por su cuenta. */
.jv-pcard .jv-pcard__extra .jv-loop-variants {
	display: block !important;
	grid-template-rows: none;
	opacity: 1;
	margin: 14px 0 0;
	border: 0;
	padding: 0;
}

.jv-pcard .jv-pcard__extra .jv-loop-variants__in {
	overflow: visible;
}

.jv-pcard .jv-pcard__extra .button {
	opacity: 1;
	max-height: none;
	overflow: visible;
	margin-top: 12px;
	padding: 12px 16px;
	border-width: 1px;
	width: 100%;
	text-align: center;
}

@media (prefers-reduced-motion: reduce) {
	.jv-pcard .jv-pcard__extra { transition: none; }
}

/* Safari dibuja el <select> con su apariencia nativa —esquinas
   redondeadas incluidas— e IGNORA border-radius mientras appearance sea
   auto. Con appearance:none desaparece tambien la flecha del sistema, asi
   que se dibuja una propia en verde de marca. */
.jv-gridhead select,
.jv-gridhead .woocommerce-ordering select,
.woocommerce .jv-gridhead select {
	-webkit-appearance: none;
	-moz-appearance: none;
	appearance: none;
	border-radius: 0;
	background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230f5637' stroke-width='2'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
	background-repeat: no-repeat;
	background-position: right 12px center;
	background-size: 14px 14px;
}

/* Ningun redondeo en los controles de la pagina de categoria. */
.tax-product_cat select,
.tax-product_cat input,
.tax-product_cat button,
.tax-product_cat .button,
.post-type-archive-product select,
.post-type-archive-product input,
.post-type-archive-product button,
.post-type-archive-product .button {
	border-radius: 0;
}

/* Tres niveles: __extra anima la pista, __extra-in la recorta y
   __extra-box pinta. El relleno y el borde tienen que vivir en el tercero
   o quedan fuera de la pista y se ven con el desplegable cerrado. */
.jv-pcard .jv-pcard__extra-in {
	overflow: hidden;
	min-height: 0;
	background: none;
	border: 0;
	padding: 0;
}

.jv-pcard .jv-pcard__extra-box {
	background: var(--jv-color-surface);
	border: 4px solid var(--jv-color-ink);
	border-top: 0;
	padding: 14px 16px 16px;
}

.jv-pcard .jv-pcard__extra-box > :first-child { margin-top: 0; }

/* --- Titulo y precio iguales al grid de la home ----------------------
   Medido en .jv-top__name y .jv-top__price de la portada:
     nombre  14px / 600 / 1.35 / verde de marca / 8px inferior
     precio  14px / 300 / 1.5  / verde de marca
   La PLP los tenia en 15px y en 18px-600, que pesaba mas que el nombre e
   invertia la jerarquia. La descripcion se queda como esta. */

.woocommerce ul.products li.product.jv-pcard .woocommerce-loop-product__title,
.woocommerce-page ul.products li.product.jv-pcard .woocommerce-loop-product__title {
	font-size: 14px;
	font-weight: 600;
	line-height: 1.35;
	color: var(--jv-color-forest);
	margin: 0 0 8px;
	min-height: 2.7em;
}

.woocommerce ul.products li.product.jv-pcard .price,
.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row,
.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row ins,
.woocommerce-page ul.products li.product.jv-pcard .price,
.woocommerce-page ul.products li.product.jv-pcard .jv-loop-price-row ins {
	font-size: 14px;
	font-weight: 300;
	line-height: 1.5;
	color: var(--jv-color-forest);
}

/* El tachado del precio anterior se queda un punto por debajo, como en la
   home, sin competir con el vigente. */
.woocommerce ul.products li.product.jv-pcard .jv-loop-price-row del {
	font-size: 13px;
	font-weight: 300;
	color: var(--jv-color-price-muted);
}

/* El descuento acompana al precio, no lo domina. */
.woocommerce ul.products li.product.jv-pcard .jv-loop-badge {
	font-size: 13px;
	font-weight: 600;
}

/* ===== Filtro precio: verde Verdetop (no morado #7f54b3 de Storefront Customizer) =====
   El customizer de Storefront inyecta background #7f54b3 en .ui-slider-range/handle.
   Aqui forzamos tokens de marca. */
.woocommerce .widget_price_filter .ui-slider,
.widget_price_filter .ui-slider,
.widget_price_filter .price_slider {
	background: var(--jv-color-mint-soft, #d7ebe0) !important;
	border: 0 !important;
	height: 6px !important;
}
.woocommerce .widget_price_filter .ui-slider .ui-slider-range,
.widget_price_filter .ui-slider .ui-slider-range,
.widget_price_filter .price_slider .ui-slider-range,
.price_slider .ui-slider-range,
.ui-slider .ui-slider-range {
	background: var(--jv-color-forest, #0f5637) !important;
	border: 0 !important;
	height: 6px !important;
}
.woocommerce .widget_price_filter .ui-slider .ui-slider-handle,
.widget_price_filter .ui-slider .ui-slider-handle,
.widget_price_filter .price_slider .ui-slider-handle,
.price_slider .ui-slider-handle,
.ui-slider .ui-slider-handle {
	background: var(--jv-color-forest, #0f5637) !important;
	border: 2px solid #ffffff !important;
	border-radius: 50% !important;
	box-shadow: 0 1px 3px rgba(15, 86, 55, 0.28);
	height: 18px !important;
	width: 18px !important;
	top: -7px !important;
	margin-left: -9px;
}
.woocommerce .widget_price_filter .ui-slider .ui-slider-handle:hover,
.woocommerce .widget_price_filter .ui-slider .ui-slider-handle:focus,
.woocommerce .widget_price_filter .ui-slider .ui-slider-handle.ui-state-active,
.widget_price_filter .ui-slider .ui-slider-handle:hover,
.widget_price_filter .ui-slider .ui-slider-handle:focus,
.widget_price_filter .ui-slider .ui-slider-handle.ui-state-active {
	background: var(--jv-color-forest, #0f5637) !important;
	border-color: var(--jv-color-mint, #a7d4b9) !important;
	outline: none;
}


/* Buscador en movil: iOS hace zoom al enfocar cualquier campo con menos de
   16px, asi que el campo va a 16px tambien en estado compacto. El buscador es
   la ultima fila del grid y no tenia padding inferior: el verde quedaba solo
   por arriba. Se sube el campo (menos hueco con el logo) y se deja el mismo
   verde abajo. */
@media (max-width: 600px) {
	.jv-header-row {
		row-gap: 6px;
		padding-bottom: 8px;
	}

	.jv-header-search--persistent .search-field,
	:root.jv-compacto .jv-header-search--persistent .search-field {
		font-size: 16px;
	}
}

/* Enlace "Ver más información" del hero de categoría -> salta el listado de
   productos y va directo al bloque de texto/FAQ (#jv-category-info). */
body.jv-has-category-hero {
	scroll-behavior: smooth;
}
.jv-opener__more {
	display: inline-flex;
	align-items: center;
	gap: 6px;
	margin-top: 10px;
	font-size: 14px;
	font-weight: 600;
	color: inherit;
	text-decoration: underline;
	text-underline-offset: 3px;
	opacity: .9;
}
.jv-opener__more:hover {
	opacity: 1;
}
.jv-opener__more .jv-icon {
	width: 14px;
	height: 14px;
}
.jv-category-table {
	margin: 24px 0;
}
.jv-category-table__title {
	font-size: 18px;
	margin: 0 0 12px;
}

/* ── Barra envío gratis 24-72h (carrito y checkout de bloques) ─────────
   Ver inc/free-shipping-bar.php. Mismo lenguaje que .jv-drawer__shipbar. */

.jv-freeship {
	margin: 0 0 16px;
	padding: 12px 14px;
	background: var(--jv-color-canvas);
	border: 1px solid var(--jv-color-border);
	border-radius: 8px;
}

.jv-freeship[hidden] {
	display: none;
}

.jv-freeship__text {
	margin: 0 0 8px;
	font-size: 14px;
	color: var(--jv-color-forest);
	display: flex;
	align-items: center;
	gap: 8px;
}

.jv-freeship__text strong {
	font-weight: 600;
}

.jv-freeship__icon .jv-icon {
	width: 16px;
	height: 16px;
	display: block;
}

.jv-freeship__icon--ok,
.jv-freeship.is-free .jv-freeship__icon--truck {
	display: none;
}

.jv-freeship.is-free .jv-freeship__icon--ok {
	display: inline-flex;
}

.jv-freeship.is-free {
	background: var(--jv-color-mint-soft);
	border-color: var(--jv-color-forest);
}

.jv-freeship.is-free .jv-freeship__text {
	font-weight: 600;
}

.jv-freeship__track {
	height: 6px;
	background: var(--jv-color-mint-soft);
	border-radius: 999px;
	overflow: hidden;
}

.jv-freeship.is-free .jv-freeship__track {
	background: var(--jv-color-canvas);
}

.jv-freeship__fill {
	display: block;
	height: 100%;
	width: 0;
	background: var(--jv-color-forest);
	border-radius: 999px;
	transition: width 0.4s ease;
}

/* Opción "Envío gratuito 24-72h a partir de 99 €" desactivada en el
   checkout mientras no se llega al mínimo (inc/free-shipping-bar.php). */
.jv-eco-locked {
	cursor: not-allowed;
	pointer-events: none;
	/* El borde inferior del grupo lo pinta WooCommerce en su última opción
	   real; esta fila va detrás, así que cierra el recuadro ella misma. */
	box-shadow: inset 0 -1px 0 rgba(15, 86, 55, 0.2);
}

.jv-eco-locked > * {
	opacity: 0.55;
}

.jv-eco-locked .wc-block-components-radio-control__input {
	cursor: not-allowed;
}
