﻿/* =============================================================
   MAIN.CSS — Gran Almazara Child Theme
   Todos los estilos del tema, organizados por sección.
   Las variables están definidas en style.css (:root).

   ÍNDICE:
   01. RESET Y BASE
   02. TIPOGRAFÍA
   03. UTILIDADES Y HELPERS
   04. BOTONES
   05. NAVBAR
   06. HERO SLIDER
   07. SECCIONES BASE (estilos compartidos)
   08. PRODUCTOS NUEVOS
   09. SOBRE NOSOTROS
   10. LA ALMAZARA
   11. PRODUCTOS DESTACADOS
   12. APADRINA UN OLIVO
   13. NEWSLETTER
   14. BLOG GRID
   15. FOOTER
   16. PÁGINAS INTERNAS (hero de página, page.php)
   17. BLOG ARCHIVE Y SINGLE
   18. PAGINACIÓN
   19. ANIMACIONES
   20. RESPONSIVE — TABLET (max 1024px)
   21. RESPONSIVE — MÓVIL (max 768px)
   ============================================================= */


/* =============================================================
   01. RESET Y BASE
   ============================================================= */

*,
*::before,
*::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-behavior: smooth;
    font-size: 16px;
    overflow-x: hidden;

    /* 🔴 EL HUECO DE LA BARRA DE DESPLAZAMIENTO, RESERVADO SIEMPRE.
       Sin esto, cualquier cosa que bloquee el scroll de fondo —hoy el carrito
       lateral— pone overflow:hidden en html, la barra desaparece y el viewport
       se ENSANCHA de golpe unos 15-17px. Todo lo anclado a la derecha (la
       cabecera fija, el propio panel) salta a la izquierda esa distancia en el
       mismo fotograma en que arranca la animación: ese era el tirón.

       Con el hueco reservado de antemano, quitar el overflow ya no cambia el
       ancho de nada y el deslizamiento sale limpio.

       ⚠ NO SUSTITUYE AL overflow-x: hidden DE ARRIBA, que es el cortafuegos
         anti-desbordamiento horizontal y sigue intacto. Son cosas distintas.

       En móvil no se nota: las barras se superponen al contenido y no reservan
       hueco, así que ahí `stable` no dibuja ningún carril vacío. Los navegadores
       que no entiendan la propiedad la ignoran, y para ellos el JS del carrito
       compensa el ancho a mano. */
    scrollbar-gutter: stable;
}

body {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    color: var(--ga-verde-oliva-oscuro);
    background-color: var(--ga-blanco);
    line-height: 1.7;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* 🔴 SOLO EN NOSOTROS: el cortafuegos anti-scroll horizontal pasa de `hidden` a
   `clip` en html y body. Por qué: `overflow-x: hidden` obliga a `overflow-y` a
   valer `auto` (regla del modelo de overflow), y eso convierte a html y body en
   CONTENEDORES DE SCROLL. Con un ancestro que es contenedor de scroll, el
   position:sticky del escenario del recorrido se ancla a ESE ancestro —que no se
   desplaza por dentro— en lugar de a la pantalla: no retiene la vista y, al seguir
   bajando, aparece hueco en blanco.
   `overflow-x: clip` recorta igual en horizontal (mantiene el cortafuegos) pero
   deja `overflow-y` en `visible`: NO crea contenedor de scroll, así que el sticky
   vuelve a funcionar. Acotado con :has() a esta página; el resto del sitio conserva
   su `hidden` intacto. Si el navegador no soporta `clip` (o `:has()`), la regla se
   ignora y queda el `hidden` de base: sin sticky pero sin desbordamiento, una
   degradación aceptable. Es la misma solución (clip en vez de hidden) ya usada en
   los carruseles de la tienda. */
html:has(.ga-main--nosotros),
body:has(.ga-main--nosotros) {
    overflow-x: clip;
}

/* ANCLAJE (scroll snap) del recorrido, SOLO en Nosotros y SOLO en el scroller raíz
   (html, que es quien desplaza la página). `proximity` (no `mandatory`) es suave:
   el scroll "cae" al tramo más cercano al pararse cerca, pero NUNCA impide seguir
   bajando ni bloquea el gesto (importa en Android). scroll-padding-top descuenta la
   cabecera fija para que el tramo no quede por debajo de ella.
   scroll-snap-type NO cambia overflow ni crea contenedores: no rompe el sticky del
   escenario. Los puntos de anclaje son los .__tramo del carril; en móvil ese carril
   se oculta, así que no hay anclaje donde el efecto está apagado. */
html:has(.ga-main--nosotros) {
    scroll-snap-type: y proximity;
    scroll-padding-top: var(--ga-nav-height);
}

img {
    max-width: 100%;
    height: auto;
    display: block;
}

a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ga-transition-fast);
}

a:hover {
    color: var(--ga-naranja-apagado);
}

ul, ol {
    list-style: none;
}

/* Clase utilitaria para ocultar texto visualmente pero mantenerlo para lectores de pantalla */
.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border-width: 0;
}


/* =============================================================
   02. TIPOGRAFÍA
   ============================================================= */

h1, h2, h3, h4, h5, h6 {
    font-family: var(--ga-font-display);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

h1 { font-size: var(--ga-text-5xl); }
h2 { font-size: var(--ga-text-4xl); }
h3 { font-size: var(--ga-text-2xl); }
h4 { font-size: var(--ga-text-xl); }

p {
    margin-bottom: var(--ga-space-sm);
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.85;
}

blockquote {
    font-family: var(--ga-font-display);
    font-style: italic;
    font-size: var(--ga-text-2xl);
    line-height: 1.5;
    color: var(--ga-verde-oliva-oscuro);
}

strong { font-weight: var(--ga-weight-bold); }


/* =============================================================
   03. UTILIDADES Y HELPERS
   ============================================================= */

/* Contenedor centrado con max-width */
.ga-section__inner {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    padding: var(--ga-space-2xl) var(--ga-space-md);
}

/* Variante estrecha para formularios y texto largo */
.ga-section__inner--narrow {
    max-width: 800px;
}

/* Layout split 50/50 — para uso en secciones que lo requieran */
.ga-section__inner--split {
    display: grid;
    grid-template-columns: 70% 30%;
    gap: var(--ga-space-xl);
    align-items: center;
}

/* Encabezado de sección centrado */
.ga-section__header--center {
    text-align: center;
    margin-bottom: var(--ga-space-xl);
}

/* Visibilidad responsive */
.ga-solo-movil { display: none; }


/* Footer de sección centrado */
.ga-section__footer--center {
    text-align: center;
    margin-top: var(--ga-space-xl);
}

/* Eyebrow — texto pequeño encima del título principal */
.ga-section__eyebrow {
    display: inline-block;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    margin-bottom: var(--ga-space-xs);
}

.ga-section__eyebrow--light {
    color: rgba(255, 255, 255, 0.7);
}

/* Títulos de sección */
.ga-section__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-5xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.1;
    margin-bottom: var(--ga-space-sm);
}

.ga-section__titulo--center { text-align: center; }
.ga-section__titulo--left   { text-align: left; }

.ga-section__titulo--light {
    color: var(--ga-blanco);
}

/* Subtítulos de sección */
.ga-section__subtitulo {
    font-size: var(--ga-text-lg);
    max-width: 600px;
    opacity: 0.8;
}

.ga-section__subtitulo--left {
    margin-left: 0;
}

/* Overlay genérico reutilizable */
.ga-overlay {
    position: absolute;
    inset: 0;
    background: rgba(74, 74, 47, var(--ga-overlay-opacity, 0.4));
    pointer-events: none;
}


/* =============================================================
   04. BOTONES
   ============================================================= */

.ga-btn {
    display: inline-flex;
    align-items: center;
    gap: var(--ga-space-xs);
    padding: 0.875rem 2rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    border: 2px solid transparent;
    border-radius: 0;    /* Estilo recto, sin border-radius — más elegante */
    cursor: pointer;
    transition: all var(--ga-transition-normal);
    text-decoration: none;
    white-space: nowrap;
}

/* Botón CTA principal — dorado */
.ga-btn--cta,
.ga-btn--primary {
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border-color: var(--ga-naranja-apagado);
}

.ga-btn--cta:hover,
.ga-btn--primary:hover {
    background-color: var(--ga-marron-oscuro);
    border-color: var(--ga-marron-oscuro);
    color: var(--ga-blanco);
}

/* Botón outline oscuro */
.ga-btn--outline,
.ga-btn--outline-dark {
    background-color: transparent;
    color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
}

.ga-btn--outline:hover,
.ga-btn--outline-dark:hover {
    background-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
}

/* Feedback táctil al presionar — simula clic físico */
.ga-btn:active {
    transform: translateY(1px) scale(0.98);
}

/* Focus ring visible para navegación por teclado */
.ga-btn:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

/* Botón outline claro (para fondos oscuros) */
.ga-btn--outline-light {
    background-color: transparent;
    color: var(--ga-blanco);
    border-color: rgba(255, 255, 255, 0.6);
}

.ga-btn--outline-light:hover {
    background-color: var(--ga-blanco);
    color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-blanco);
}


/* =============================================================
   05. NAVBAR
   ============================================================= */

.ga-header {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 1000;
    background-color: var(--ga-blanco);
    border-bottom: 1px solid rgba(74, 74, 47, 0.1);
    transition: box-shadow var(--ga-transition-normal);
}

/* Sombra cuando el usuario hace scroll hacia abajo */
.ga-header.is-scrolled {
    box-shadow: var(--ga-shadow-md);
}

/* Cabecera CREMA solo en la tienda. WooCommerce añade .woocommerce-shop al <body>
   en is_shop(); esto NO usa JS y NO altera la regla base .ga-header (blanca en el
   resto de la web). El header es hermano de <main>, por eso se acota vía <body>. */
body.woocommerce-shop .ga-header {
    background-color: var(--ga-naranja-claro);   /* #F9F6EE */
}

/* ——— TIENDA: la cabecera se oculta al hacer scroll (SOLO en la shop) ———
   Al bajar, la cabecera se desliza hacia arriba y la barra de categorías sube a top:0
   (ocupa su sitio, sin hueco encima). Reaparece solo arriba del todo. La clase
   .ga-tienda-header-oculta la pone/quita el JS según scrollY. El transform SOLO se anima
   aquí: fuera de la tienda, la regla base .ga-header sigue animando solo box-shadow. */
body.woocommerce-shop .ga-header {
    transition: transform var(--ga-transition-normal), box-shadow var(--ga-transition-normal);
    /* SIN will-change: transform. Creaba un bloque contenedor para los position:fixed
       descendientes (igual que transform), y el menú off-canvas .ga-nav__menu-wrapper vive
       dentro de .ga-header: al contenerlo aquí, el overflow-x:hidden de html/body dejaba de
       recortarlo y su ancho completo inflaba el documento (scrollWidth = ancho del menú),
       SOLO en la shop → scroll horizontal de toda la pagina en la tienda. La transición de
       la cabecera al ocultarse sigue siendo fluida sin él (transform se compone en GPU). */
}
body.woocommerce-shop.ga-tienda-header-oculta .ga-header {
    transform: translateY(-100%);   /* se desliza hacia arriba (su propio alto), fuera de vista */
}
body.woocommerce-shop.ga-tienda-header-oculta .ga-tienda-nav {
    top: 0;                          /* la barra ocupa el borde superior, sin hueco blanco encima */
}

.ga-nav {
    height: var(--ga-nav-height);
}

.ga-nav__inner {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ga-space-md);
}

/* ——— Logo ——— */
.ga-nav__logo a,
.ga-nav__logo .custom-logo-link {
    display: flex;
    align-items: center;
    text-decoration: none;
    /* Evita que el enlace fuerce un ancho distorsionado */
    width: fit-content;
    flex-shrink: 0;
    transition: opacity 0.25s ease;
}

.ga-nav__logo a:hover,
.ga-nav__logo .custom-logo-link:hover {
    opacity: 0.8;
}

/*
 * FIX: WordPress inserta width/height como atributos HTML en <img> al usar
 * the_custom_logo(). Esos atributos tienen precedencia sobre CSS sin !important,
 * lo que provoca que el logo se vea aplatanado o estirado.
 * Se sobreescribe con !important sólo en estas dos propiedades críticas.
 */
.ga-nav__logo img,
.ga-nav__logo .custom-logo {
    /* Tamaño controlado únicamente por height; width se calcula automáticamente */
    height: 56px !important;
    width: auto !important;
    /* Garantía extra: anulamos max-width de Astra/Customizer y evitamos flex-shrink */
    max-width: none !important;
    min-width: unset !important;
    flex-shrink: 0;
    object-fit: contain;
    aspect-ratio: auto;
    display: block;
    transition: opacity 0.25s ease;
}

.ga-nav__logo-text {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    letter-spacing: 0.05em;
}

/* ——— Menú principal ——— */
.ga-nav__menu {
    display: flex;
    align-items: center;
    gap: var(--ga-space-xs);
    list-style: none;
    margin: 0;
    padding: 0;
}

.ga-nav__menu > li {
    position: relative;
}

.ga-nav__menu > li > a {
    display: block;
    padding: 0.5rem var(--ga-space-sm);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ga-verde-oliva-oscuro);
    text-decoration: none;
    transition: color var(--ga-transition-fast);
    white-space: nowrap;
}

.ga-nav__menu > li > a:hover,
.ga-nav__menu > li.current-menu-item > a,
.ga-nav__menu > li.current_page_item > a {
    color: var(--ga-naranja-apagado);
}

/* Línea inferior animada en hover */
.ga-nav__menu > li > a::after {
    content: '';
    display: block;
    height: 2px;
    background-color: var(--ga-naranja-apagado);
    width: 0;
    transition: width var(--ga-transition-normal);
    margin-top: 2px;
}

.ga-nav__menu > li > a:hover::after,
.ga-nav__menu > li.current-menu-item > a::after {
    width: 100%;
}

/* ——— Dropdown submenu (Tienda) ——— */
.ga-nav__menu .sub-menu {
    position: absolute;
    top: 100%;
    left: 0;
    min-width: 200px;
    background-color: var(--ga-blanco);
    box-shadow: var(--ga-shadow-md);
    border-top: 2px solid var(--ga-naranja-apagado);
    list-style: none;
    padding: var(--ga-space-xs) 0;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-8px);
    transition: all var(--ga-transition-normal);
    z-index: 100;
}

.ga-nav__menu li:hover > .sub-menu {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.ga-nav__menu .sub-menu li a {
    display: block;
    padding: 0.6rem var(--ga-space-md);
    font-size: var(--ga-text-sm);
    color: var(--ga-verde-oliva-oscuro);
    transition: all var(--ga-transition-fast);
}

.ga-nav__menu .sub-menu li a:hover {
    background-color: var(--ga-naranja-claro);
    color: var(--ga-naranja-apagado);
    padding-left: calc(var(--ga-space-md) + 4px);
}

/* ——— Acciones de la navbar ——— */
.ga-nav__actions {
    display: flex;
    align-items: center;
    gap: var(--ga-space-sm);
}

/* Botón CTA de la navbar */
.ga-nav__cta {
    padding: 0.6rem 1.25rem;
    font-size: var(--ga-text-xs);
}

/* Carrito WooCommerce */
.ga-nav__carrito {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    color: var(--ga-verde-oliva-oscuro);
    transition: color var(--ga-transition-fast);
}

.ga-nav__carrito:hover {
    color: var(--ga-naranja-apagado);
}

.ga-nav__carrito-count {
    position: absolute;
    top: 0;
    right: 0;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-size: 10px;
    font-weight: var(--ga-weight-bold);
    min-width: 18px;
    height: 18px;
    border-radius: var(--ga-radius-full);
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
}

/* Icono de cuenta/perfil */
.ga-nav__account {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    color: var(--ga-verde-oliva-oscuro);
    transition: color var(--ga-transition-fast);
}

.ga-nav__account:hover {
    color: var(--ga-naranja-apagado);
}

.ga-nav__account-dot {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 8px;
    height: 8px;
    background-color: var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-full);
    border: 1.5px solid var(--ga-blanco);
}

/* ——— Botón hamburguesa (móvil) ——— */
.ga-nav__toggle {
    display: none;
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 8px;
}

.ga-nav__toggle-bar {
    display: block;
    width: 24px;
    height: 2px;
    background-color: var(--ga-verde-oliva-oscuro);
    transition: all var(--ga-transition-fast);
    transform-origin: center;
}

/* ——— EL ICONO DEL MENÚ, BLANCO CUANDO EL FONDO SE PONE DORADO ———
   ═══════════════════════════════════════════════════════════════════════════
   LAS TRES RAYITAS Y LA CRUZ SON EL MISMO ELEMENTO. No hay dos iconos: la X que se
   ve con el menú abierto son estas mismas .ga-nav__toggle-bar, con la primera y la
   tercera giradas 45° y la del medio a opacidad 0 (ver la animación de aquí
   abajo). Por eso una sola regla de color vale para los dos estados.

   DE DÓNDE SALE EL DORADO: NO DE AQUÍ. La regla de arriba le da al botón
   `background: none`, así que en reposo es transparente y las rayitas van en verde
   oliva, que es lo correcto sobre la cabecera clara. El dorado lo mete ASTRA, que
   estiliza los <button> del sitio con reglas del tipo `button:hover` (🪤 nº 6):
   en reposo `.ga-nav__toggle` (0-1-0) le gana a `button` (0-0-1) y el botón se
   queda transparente, pero `button:hover` puntúa 0-1-1 y sí le gana a la clase.

   🔴🔴 POR QUÉ EL PRIMER INTENTO NO FUNCIONÓ, QUE ES LO IMPORTANTE DE ESTE BLOQUE.
   Aquí había una regla igual que esta pero SIN !important y con un selector más
   corto, y no pintaba nada en la home. El motivo no estaba en el CSS: está en
   assets/js/main.js, que en las páginas CON HERO inyecta un <style> en el <head>
   con, entre otras cosas:

       .ga-header--over-hero.is-scrolled .ga-nav__toggle-bar {
           background-color: var(--ga-verde-oliva-oscuro) !important;
       }

   Es decir, en cuanto se baja del hero, el JS FUERZA el verde con !important. Un
   !important gana a cualquier declaración normal por mucha especificidad que
   tenga, así que la regla de antes no tenía nada que hacer. Y como ese <style> se
   añade al final del <head>, empatar en especificidad tampoco basta: ganaría él
   por orden de aparición. Su selector puntúa 0-3-0.

   ✅ De ahí las dos decisiones de aquí abajo: !important —para poder competir— y
   el `.ga-header` delante, que sube el selector a 0-4-0 y se lo lleva por
   especificidad. Sin ese ancestro, los dos empatarían a 0-3-0 y volvería a ganar
   el del JS.

   ⚠ ESTO EXPLICA TAMBIÉN POR QUÉ SE VEÍA DISTINTO SEGÚN LA PÁGINA: ese <style>
   solo se inyecta donde hay hero. En una ficha de producto no existe, y allí la
   regla anterior sí funcionaba. En la home, no.

   El estado de reposo no se toca: las rayitas siguen en verde oliva sobre la
   cabecera clara, y blancas sobre el hero (eso lo pone el mismo <style> del JS y
   sigue igual). En escritorio nada de esto existe: el botón va en display: none
   por encima del breakpoint móvil. */
.ga-header .ga-nav__toggle:hover .ga-nav__toggle-bar,
.ga-header .ga-nav__toggle:focus .ga-nav__toggle-bar,
.ga-header .ga-nav__toggle:active .ga-nav__toggle-bar,
.ga-header .ga-nav__toggle.is-active .ga-nav__toggle-bar {
    background-color: var(--ga-blanco) !important;
}

/* 🔴 CON EL MENÚ ABIERTO, EL DORADO SE ESCRIBE AQUÍ Y NO SE DEJA EN MANOS DE ASTRA.
   La cruz blanca solo se lee si detrás hay dorado, y ese dorado venía del :hover /
   :focus de Astra, que en un móvil depende de que el botón conserve el foco tras
   el toque. Si lo perdiera —un toque en otro sitio, un navegador que lo suelta—, el
   fondo volvería a transparente y la cruz blanca desaparecería sobre la cabecera
   clara.

   Atándolo a .is-active, que es la clase que el JS pone y quita al abrir y cerrar,
   el fondo dorado y el icono blanco entran y salen JUNTOS y no pueden
   contradecirse. Es el único estado en el que se toca el fondo del botón; el resto
   de la cabecera no se toca. */
.ga-header .ga-nav__toggle.is-active {
    background-color: var(--ga-naranja-apagado) !important;
}

/* Animación hamburguesa → X */
.ga-nav__toggle.is-active .ga-nav__toggle-bar:nth-child(1) {
    transform: rotate(45deg) translate(5px, 5px);
}
.ga-nav__toggle.is-active .ga-nav__toggle-bar:nth-child(2) {
    opacity: 0;
    transform: scaleX(0);
}
.ga-nav__toggle.is-active .ga-nav__toggle-bar:nth-child(3) {
    transform: rotate(-45deg) translate(5px, -5px);
}

/* Offset para que el contenido no quede bajo el navbar fijo */
body {
    padding-top: var(--ga-nav-height);
}

/* CAMBIO 1 (tienda): el hueco del padding-top bajo la cabecera fija muestra el
   fondo del body. En la tienda lo ponemos crema para que NO quede una franja
   blanca entre la cabecera (crema) y la banda del título. Solo en la tienda:
   .woocommerce-shop lo añade WooCommerce al <body> en is_shop(). Sin JS. */
body.woocommerce-shop {
    background-color: var(--ga-naranja-claro);   /* #F9F6EE */
}

/* NOSOTROS: el hero se pega al borde inferior de la cabecera SIN franja.
   El body reserva padding-top: var(--ga-nav-height) para que el contenido no
   quede bajo la cabecera fija, y en Nosotros —cuya primera sección es el hero
   OSCURO— ese hueco reservado se veía como una franja entre la cabecera y la
   foto (blanca primero, luego verde cuando se probó a teñirla).

   La solución NO vive aquí en el body, sino en el propio hero
   (.ga-main--nosotros .ga-nosotros-hero, más abajo): sube con un margin-top
   negativo igual a la altura de la cabecera y COMPENSA ese tiro creciendo la
   misma cantidad en alto, de modo que su borde inferior no se mueve. Así la
   foto pasa por debajo de la cabecera (blanca y opaca) tapando el hueco —sin
   franja de ningún color— y su parte visible sigue siendo la de antes.

   Se hace en el hero y no en el body por dos motivos: se resuelve con selectores
   de clase (sin :has(), que fallaba en navegadores viejos) y el padding-top del
   body queda INTACTO —el de la home, la tienda, Contacto y el resto, y también
   el de esta página— tal y como pide el encargo. */

/* La home no necesita padding-top porque el hero ocupa 100vh */
.ga-main--home {
    padding-top: 0;
}

.ga-main--home ~ body {
    padding-top: 0;
}

/* Aplicar a la home directamente */
body.home,
body.page-template-template-home {
    padding-top: 0;
}


/* =============================================================
   06. HERO SLIDER
   ============================================================= */

.ga-hero {
    position: relative;
    width: 100%;
    height: 100vh;
    min-height: 600px;
    overflow: hidden;
}

/* Quitar el padding-top de body cuando hay hero en home */
.ga-hero {
    margin-top: calc(-1 * var(--ga-nav-height));
}

.ga-hero__swiper {
    width: 100%;
    height: 100%;
}

/* Cada slide */
.ga-hero__slide {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* Imagen de fondo del slide */
.ga-hero__bg {
    position: absolute;
    inset: 0;
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    transition: transform 8s ease;
    transform: scale(1.05);
}

/* Efecto Ken Burns — zoom suave en el slide activo */
.swiper-slide-active .ga-hero__bg {
    transform: scale(1);
}

/* Overlay oscuro del slide */
.ga-hero__overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(0, 0, 0, var(--ga-hero-overlay, 0.4));
    z-index: 1;
}

/* Contenido centrado del slide */
.ga-hero__content {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0 var(--ga-space-md);
}

.ga-hero__content-inner {
    text-align: center;
    max-width: 800px;
    color: var(--ga-blanco);
}

/* Eyebrow del hero */
.ga-hero__eyebrow {
    display: inline-block;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    margin-bottom: var(--ga-space-sm);
}

/* Título principal del hero */
.ga-hero__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(3rem, 7vw, 5.5rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.05;
    color: var(--ga-blanco);
    margin-bottom: var(--ga-space-md);
    text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3);
}

/* Subtítulo del hero */
.ga-hero__subtitulo {
    font-size: var(--ga-text-lg);
    color: rgba(255, 255, 255, 0.85);
    max-width: 520px;
    margin: 0 auto var(--ga-space-lg);
    line-height: 1.6;
}

/* Botones CTA del hero */
.ga-hero__ctas {
    display: flex;
    gap: var(--ga-space-sm);
    justify-content: center;
    flex-wrap: wrap;
}

/* Paginación (puntos) de Swiper */
.ga-hero__pagination {
    bottom: var(--ga-space-lg) !important;
}

.ga-hero__pagination .swiper-pagination-bullet {
    width: 10px;
    height: 10px;
    background-color: rgba(255, 255, 255, 0.5);
    opacity: 1;
    transition: all var(--ga-transition-normal);
}

.ga-hero__pagination .swiper-pagination-bullet-active {
    background-color: var(--ga-naranja-apagado);
    width: 32px;
    border-radius: 5px;
}

/* Flechas de navegación de Swiper */
.ga-hero__nav-prev,
.ga-hero__nav-next {
    color: var(--ga-blanco) !important;
    transition: color var(--ga-transition-fast);
}

.ga-hero__nav-prev:hover,
.ga-hero__nav-next:hover {
    color: var(--ga-naranja-apagado) !important;
}

/* Flecha scroll hacia abajo */
.ga-hero__scroll-hint {
    position: absolute;
    bottom: var(--ga-space-md);
    left: 50%;
    transform: translateX(-50%);
    z-index: 3;
    color: rgba(255, 255, 255, 0.6);
    animation: ga-bounce 2s infinite;
    transition: color var(--ga-transition-fast);
}

.ga-hero__scroll-hint:hover {
    color: var(--ga-naranja-apagado);
}

@keyframes ga-bounce {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%       { transform: translateX(-50%) translateY(8px); }
}


/* =============================================================
   07. SECCIONES BASE — estilos compartidos
   ============================================================= */

/* Alternancia de fondos entre secciones */
.ga-productos-nuevos    { background-color: var(--ga-naranja-claro); }
.ga-sobre-nosotros      { background-color: var(--ga-blanco); }
.ga-almazara            { background-color: var(--ga-blanco); }
.ga-productos-destacados{ background-color: var(--ga-blanco); }
.ga-apadrina-bloque     { background-color: #F9F6EE; }


/* =============================================================
   08. PRODUCTOS NUEVOS
   ============================================================= */

/* El grid de WooCommerce se sobreescribe en woocommerce.css */
/* Aquí solo el layout del contenedor de sección */

.ga-productos-grid {
    width: 100%;
}

/* Placeholder visual para cuando WooCommerce no está activo */
.ga-productos-grid--placeholder {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--ga-space-md);
}

.ga-producto-placeholder {
    background-color: var(--ga-blanco);
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    box-shadow: var(--ga-shadow-sm);
}

.ga-producto-placeholder__imagen {
    position: relative;
    aspect-ratio: 1;
    overflow: hidden;
}

.ga-producto-placeholder__imagen img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--ga-transition-slow);
}

.ga-producto-placeholder:hover .ga-producto-placeholder__imagen img {
    transform: scale(1.05);
}

.ga-producto-placeholder__badge {
    position: absolute;
    top: var(--ga-space-sm);
    left: var(--ga-space-sm);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    padding: 4px 10px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

.ga-producto-placeholder__info {
    padding: var(--ga-space-md);
}

.ga-producto-placeholder__estrellas {
    color: var(--ga-naranja-apagado);
    font-size: var(--ga-text-sm);
    margin: var(--ga-space-xs) 0;
}

.ga-producto-placeholder__info .precio {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
}

/* Grid de 4 columnas para productos destacados */
.ga-productos-grid--4col.ga-productos-grid--placeholder {
    grid-template-columns: repeat(4, 1fr);
}


/* =============================================================
   09. SOBRE NOSOTROS
   ============================================================= */

/* Layout split 70/30 heredado de .ga-section__inner--split */

/* Cita grande */
.ga-sobre__cita {
    font-family: var(--ga-font-display);
    font-style: italic;
    font-size: var(--ga-text-3xl);
    line-height: 1.4;
    color: var(--ga-verde-oliva-oscuro);
    border-left: 3px solid var(--ga-naranja-apagado);
    padding-left: var(--ga-space-md);
    margin-bottom: var(--ga-space-xl);
}

.ga-sobre__cita-texto {
    margin: 0 0 var(--ga-space-sm);
    opacity: 1;
}

.ga-sobre__cita-autor {
    font-family: var(--ga-font-body);
    font-style: normal;
    font-size: var(--ga-text-sm);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
}

/* Contenedor de video con overlay y botón play */
.ga-sobre__video-wrapper {
    position: relative;
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    cursor: pointer;
    aspect-ratio: 16/9;
}

.ga-sobre__video-portada {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--ga-transition-slow);
}

.ga-sobre__video-wrapper:hover .ga-sobre__video-portada {
    transform: scale(1.03);
}

.ga-sobre__video-overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, 0.35);
    transition: background-color var(--ga-transition-normal);
}

.ga-sobre__video-wrapper:hover .ga-sobre__video-overlay {
    background-color: rgba(74, 74, 47, 0.5);
}

/* Botón play circular */
.ga-sobre__play-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -60%);
    width: 70px;
    height: 70px;
    border-radius: 50%;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all var(--ga-transition-normal);
    z-index: 2;
}

.ga-sobre__play-btn:hover {
    background-color: var(--ga-blanco);
    color: var(--ga-naranja-apagado);
    transform: translate(-50%, -60%) scale(1.1);
}

.ga-sobre__video-label {
    position: absolute;
    bottom: var(--ga-space-md);
    left: 50%;
    transform: translateX(-50%);
    color: var(--ga-blanco);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    z-index: 2;
    white-space: nowrap;
}

/* Columna derecha de Sobre Nosotros */
.ga-sobre__derecha {
    padding-left: var(--ga-space-lg);
}

.ga-sobre__bloques {
    display: flex;
    flex-direction: column;
    gap: var(--ga-space-lg);
    margin: var(--ga-space-lg) 0;
}

.ga-sobre__bloque {
    display: flex;
    gap: var(--ga-space-sm);
    align-items: flex-start;
}

.ga-sobre__bloque-icono {
    font-size: 1.75rem;
    line-height: 1;
    flex-shrink: 0;
    margin-top: 4px;
}

.ga-sobre__bloque-titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-bold);
    margin-bottom: var(--ga-space-xs);
}

.ga-sobre__bloque-texto {
    font-size: var(--ga-text-sm);
    line-height: 1.7;
    margin: 0;
    opacity: 0.8;
}

.ga-sobre__ver-mas {
    display: inline-flex;
    align-items: center;
    gap: var(--ga-space-xs);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    text-decoration: none;
    border-bottom: 1px solid var(--ga-naranja-apagado);
    padding-bottom: 2px;
    transition: all var(--ga-transition-fast);
}

.ga-sobre__ver-mas:hover {
    color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
    gap: var(--ga-space-sm);
}


/* =============================================================
   10. LA ALMAZARA
   ============================================================= */

.ga-almazara__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 600px;
}

.ga-almazara__imagen-wrapper {
    position: relative;
    overflow: hidden;
}

.ga-almazara__imagen {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform var(--ga-transition-slow);
}

.ga-almazara__imagen-wrapper:hover .ga-almazara__imagen {
    transform: scale(1.04);
}

/* Badge flotante en la imagen */
.ga-almazara__badge {
    position: absolute;
    bottom: var(--ga-space-lg);
    right: var(--ga-space-lg);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    padding: var(--ga-space-sm) var(--ga-space-md);
    text-align: center;
    min-width: 100px;
}

.ga-almazara__badge-numero {
    display: block;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-4xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1;
}

.ga-almazara__badge-texto {
    display: block;
    font-size: var(--ga-text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    margin-top: 4px;
    opacity: 0.9;
}

/* Contenido derecho (fondo verde oscuro) */
.ga-almazara__contenido {
    background-color: var(--ga-verde-oliva-oscuro);
    padding: var(--ga-space-3xl) var(--ga-space-2xl);
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.ga-almazara__texto {
    color: rgba(255, 255, 255, 0.8);
    font-size: var(--ga-text-base);
    line-height: 1.8;
    margin: var(--ga-space-md) 0 var(--ga-space-lg);
    opacity: 1;
}

/* Estadísticas rápidas */
.ga-almazara__stats {
    display: flex;
    gap: var(--ga-space-lg);
    margin-bottom: var(--ga-space-xl);
}

.ga-almazara__stat {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.ga-almazara__stat-numero {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-4xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-naranja-apagado);
    line-height: 1;
}

.ga-almazara__stat-label {
    font-size: var(--ga-text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, 0.6);
}


/* =============================================================
   11. PRODUCTOS DESTACADOS
   ============================================================= */

/* Similar a Productos Nuevos. El grid de WC en woocommerce.css */
.ga-productos-destacados .ga-section__inner {
    padding-top: var(--ga-space-2xl);
    padding-bottom: var(--ga-space-2xl);
}


/* =============================================================
   12. APADRINA UN OLIVO — BLOQUE CTA
   ============================================================= */

.ga-apadrina-bloque {
    position: relative;
    background-color: #F9F6EE;
    background-size: cover;
    background-position: center;
    overflow: hidden;
}

.ga-apadrina-bloque__overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, 0.6);
    z-index: 0;
}

.ga-apadrina-bloque .ga-section__inner {
    position: relative;
    z-index: 1;
}

.ga-apadrina-bloque__grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ga-space-3xl);
    align-items: center;
}

.ga-apadrina-bloque__subtitulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-style: italic;
    margin-bottom: var(--ga-space-sm);
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.9;
    opacity: 1;
}

.ga-apadrina-bloque__descripcion {
    font-size: var(--ga-text-base);
    line-height: 1.8;
    margin-bottom: var(--ga-space-md);
}

.ga-apadrina-bloque__precio {
    font-size: var(--ga-text-sm);
    margin-bottom: var(--ga-space-lg);
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.7;
}

/* Grid de beneficios 2x2 */
.ga-apadrina-bloque__beneficios {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ga-space-md);
}

.ga-apadrina-bloque__beneficio {
    display: flex;
    gap: var(--ga-space-sm);
    align-items: flex-start;
    background-color: rgba(255, 255, 255, 0.5);
    padding: var(--ga-space-md);
    border-radius: var(--ga-radius-md);
    transition: background-color var(--ga-transition-normal);
}

.ga-apadrina-bloque__beneficio:hover {
    background-color: rgba(255, 255, 255, 0.75);
}

.ga-apadrina-bloque__beneficio-icono {
    font-size: 1.75rem;
    flex-shrink: 0;
    line-height: 1;
    margin-top: 2px;
}

.ga-apadrina-bloque__beneficio-titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-lg);
    font-weight: var(--ga-weight-bold);
    margin-bottom: 4px;
}

.ga-apadrina-bloque__beneficio-texto {
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    margin: 0;
    opacity: 0.8;
}


/* =============================================================
   15. FOOTER
   ============================================================= */

.ga-footer {
    background-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
    font-style: normal;
}

.ga-footer__top {
    overflow: hidden;
}

.ga-footer__bottom {
    background-color: var(--ga-verde-oliva-oscuro);
}

/* Franja superior: logo ancho + 3 columnas iguales */
.ga-footer__inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: 2.5rem 2rem 1rem;
    display: grid;
    grid-template-columns: 2fr 1fr 1fr 1fr;
    gap: 3rem;
    align-items: start;
}

/* ——— FOOTER REDUCIDO: TIENDA Y CHECKOUT DE PAGO ———
   El pie se queda en dos filas finas: (1) frase HORECA con sus enlaces de
   teléfono/email + "Volver a la página de inicio", y (2) copyright + los 4 enlaces
   legales. Todo lo demás se OCULTA, no se borra: fuera de estas pantallas el pie sigue
   idéntico. Se hace por CSS porque footer.php no está modularizado. Estas reglas tienen
   especificidad suficiente para ganar también a las colocaciones de las media queries de
   tablet y móvil.

   🔴 SON DOS PANTALLAS Y COMPARTEN LAS MISMAS REGLAS, no un bloque gemelo. Se añade el
   selector del checkout AL LADO del de la tienda en cada regla: así el pie reducido tiene
   una sola definición y no puede acabar distinto en un sitio y en otro.

     · body.woocommerce-shop → la tienda.
     · body.woocommerce-checkout:not(.woocommerce-order-received) → el checkout DE PAGO.

   🔴 EL :not() NO ES UN ADORNO. WooCommerce marca como woocommerce-checkout tanto la
   página de pago como la de "Pedido recibido", y son dos situaciones opuestas: en la de
   pago se quita todo lo que distraiga —incluida la cabecera—, y en la de "gracias" el
   cliente ya ha pagado y hay que devolverle la navegación entera. Sin el :not(), la
   pantalla de confirmación se quedaría con el pie recortado y sin menú.

   ⚠ EL ENLACE "Volver a la página de inicio" NO SE PINTA CON CSS: lo imprime footer.php
     bajo una condición, y ahí también hubo que añadir el checkout. Si algún día deja de
     verse, mirar allí antes que aquí. */
body.woocommerce-shop .ga-footer__col--nav,
body.woocommerce-shop .ga-footer__col--social,
body.woocommerce-shop .ga-footer__col--contacto,
body.woocommerce-shop .ga-footer__logo-link,
body.woocommerce-shop .ga-footer__pagos,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__col--nav,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__col--social,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__col--contacto,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__logo-link,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__pagos {
    display: none;
}

/* En móvil, la marca llevaba una raya dorada que la separaba de las 3 columnas.
   Ya no hay columnas, así que sobra. */
body.woocommerce-shop .ga-footer__col--brand::after,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__col--brand::after {
    display: none;
}

/* FILA 1 — una sola columna a todos los breakpoints, con padding vertical mucho más
   fino que el del resto del sitio (2.5rem → 1.5rem arriba). */
body.woocommerce-shop .ga-footer__inner,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__inner {
    grid-template-columns: 1fr;
    gap: var(--ga-space-sm);
    padding: var(--ga-space-md) var(--ga-space-md) var(--ga-space-sm);
}

/* Frase a la izquierda, enlace de inicio a la derecha. flex-wrap deja que se apilen en
   móvil (frase arriba, enlace debajo) sin desbordar. */
body.woocommerce-shop .ga-footer__col--brand,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__col--brand {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ga-space-xs) var(--ga-space-md);
}

/* La frase venía centrada y limitada a 295px para la columna de marca; aquí ocupa el
   ancho que necesite y se alinea a la izquierda. min-width:0 evita desbordes a 360px. */
body.woocommerce-shop .ga-footer__tagline,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__tagline {
    max-width: none;
    margin: 0;
    text-align: left;
    min-width: 0;
}

/* Enlace de vuelta a la home. Solo se imprime en la tienda (condición en footer.php),
   así que la clase ya está acotada por sí sola y no afecta a ningún otro enlace del pie.
   En reposo va en blanco sobre el verde oscuro del footer y se enciende en dorado al
   interactuar, con la misma transición de color que usan el resto de enlaces del pie. */
.ga-footer__volver {
    font-family: var(--ga-font-body);
    font-size: 0.875rem;
    color: var(--ga-blanco);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.25s ease;
}

.ga-footer__volver:hover,
.ga-footer__volver:focus,
.ga-footer__volver:active {
    color: var(--ga-naranja-apagado);
}

/* FILA 2 — copyright + legales, aún más compacta y discreta. */
body.woocommerce-shop .ga-footer__bottom-inner,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__bottom-inner {
    flex-wrap: wrap;
    gap: var(--ga-space-xs) var(--ga-space-sm);
    padding-top: 0.4rem;
    padding-bottom: 0.4rem;
}

body.woocommerce-shop .ga-footer__copyright,
body.woocommerce-shop .ga-footer__legal-nav,
body.woocommerce-shop .ga-footer__legal-nav a,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__copyright,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__legal-nav,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer__legal-nav a {
    font-size: 0.68rem;
}

/* Títulos de columna (Páginas / Contáctanos / Redes Sociales) */
.ga-footer__col-titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.15rem;
    font-weight: 600;
    color: #F9F6EE;
    margin: 0 0 0.9rem;
    letter-spacing: 0.01em;
    line-height: 1.2;
}

/* Columna de marca */
.ga-footer__col--brand {
    margin-top: 0;
    margin-bottom: 0;
}

.ga-footer__logo-link {
    display: block;
    line-height: 0; /* elimina el espacio fantasma inline debajo de la imagen */
}

.ga-footer__logo {
    width: 115px;
    height: auto;
    display: block;
    max-width: 100%;
    margin: 0 auto;
}

.ga-footer__tagline {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.85);
    line-height: 1.65;
    margin: 1rem auto 0;
    max-width: 295px;
    text-align: center;
}

.ga-footer__tagline-enlace {
    color: #c7a862;
    text-decoration: none;
    transition: color 0.25s ease;
}

.ga-footer__tagline-enlace:hover {
    color: #dfc07a;
}

/* Contacto */
.ga-footer__contacto {
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    font-style: normal;
}

.ga-footer__contacto-item {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.78);
}

.ga-footer__contacto-item svg {
    flex-shrink: 0;
    margin-top: 2px;
    color: #c7a862;
}

.ga-footer__contacto-item span,
.ga-footer__contacto-item a {
    font-style: normal;
    color: rgba(249, 246, 238, 0.78);
    text-decoration: none;
    transition: color 0.25s ease;
}

.ga-footer__contacto-item a:hover {
    color: #c7a862;
}

/* Menú de navegación */
.ga-footer__menu {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ga-footer__menu li a,
.ga-footer__menu li span {
    font-family: 'Inter', sans-serif;
    font-size: 0.9rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.78);
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    transition: color 0.25s ease;
}

.ga-footer__menu li a::before,
.ga-footer__menu li span::before {
    content: '›';
    color: #c7a862;
    font-size: 1.15rem;
    line-height: 1;
    flex-shrink: 0;
}

.ga-footer__menu li a:hover {
    color: #c7a862;
}

/* Redes sociales */
.ga-footer__redes-desc {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.78);
    line-height: 1.65;
    margin: 0 0 1.5rem;
}

.ga-footer__redes {
    display: flex;
    flex-direction: column;
    gap: 0.65rem;
}

.ga-footer__red {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    color: rgba(249, 246, 238, 0.82);
    text-decoration: none;
    transition: color 0.25s ease;
}

.ga-footer__red span {
    font-family: 'Inter', sans-serif;
    font-size: 0.9rem;
    font-style: normal;
}

.ga-footer__red svg {
    flex-shrink: 0;
}

.ga-footer__red:hover {
    color: #c7a862;
}

/* Barra inferior */
.ga-footer__bottom-inner {
    max-width: 1280px;
    margin: 0 auto;
    padding: 0.55rem 2rem;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.ga-footer__copyright {
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.72);
    margin: 0;
    flex: 1;
    min-width: 0;
}

.ga-footer__legal-nav {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.45rem;
    flex-shrink: 0;
}

.ga-footer__legal-nav a {
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    font-style: normal;
    color: rgba(249, 246, 238, 0.55);
    text-decoration: none;
    transition: color 0.25s ease;
}

.ga-footer__legal-nav a:hover {
    color: #c7a862;
}

.ga-footer__legal-nav span {
    font-size: 0.7rem;
    color: rgba(249, 246, 238, 0.28);
    user-select: none;
}

.ga-footer__pagos {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    flex-shrink: 0;
}

/* =============================================================
   MODAL DE TELÉFONO — ga-tel-modal
   ============================================================= */

.ga-tel-modal__overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.52);
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.ga-tel-modal__overlay.ga-tel-modal--visible {
    opacity: 1;
}

.ga-tel-modal__caja {
    position: relative;
    background: #F9F6EE;
    border: 2px solid #c7a862;
    border-radius: 8px;
    padding: 2.75rem 3rem 2.25rem;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);
    text-align: center;
    max-width: 380px;
    width: 90%;
    transform: translateY(18px) scale(0.97);
    transition: transform 0.28s cubic-bezier(0.34, 1.36, 0.64, 1);
}

.ga-tel-modal__overlay.ga-tel-modal--visible .ga-tel-modal__caja {
    transform: translateY(0) scale(1);
}

.ga-tel-modal__cerrar {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    background: none;
    border: none;
    cursor: pointer;
    color: #4a4a2f;
    padding: 0.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.45;
    transition: opacity 0.2s ease;
    line-height: 0;
}

.ga-tel-modal__cerrar:hover {
    opacity: 1;
}

.ga-tel-modal__icono {
    margin-bottom: 1rem;
    line-height: 0;
}

.ga-tel-modal__titulo {
    font-family: 'Inter', sans-serif;
    font-size: 1.9rem;
    font-weight: 600;
    color: #4a4a2f;
    margin: 0 0 0.3rem;
    line-height: 1.1;
}

.ga-tel-modal__sub {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    color: #4a4a2f;
    opacity: 0.65;
    margin: 0 0 1.25rem;
}

.ga-tel-modal__numero {
    font-family: 'Inter', sans-serif;
    font-size: 1.65rem;
    font-weight: 700;
    color: #4a4a2f;
    margin: 0 0 1.6rem;
    letter-spacing: 0.02em;
    line-height: 1;
    white-space: nowrap;
}

.ga-tel-modal__copiar {
    display: inline-block;
    padding: 0.7rem 1.85rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #c7a862;
    background: transparent;
    border: 2px solid #c7a862;
    border-radius: 2px;
    cursor: pointer;
    transition: background 0.22s ease, color 0.22s ease;
}

.ga-tel-modal__copiar:hover,
.ga-tel-modal__copiar--copiado {
    background: #c7a862;
    color: #4a4a2f;
}

/* =============================================================
   MODAL DE EMAIL — ga-email-modal
   ============================================================= */

.ga-email-modal__overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.52);
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    transition: opacity 0.25s ease;
}

.ga-email-modal__overlay.ga-email-modal--visible {
    opacity: 1;
}

.ga-email-modal__caja {
    position: relative;
    background: #F9F6EE;
    border: 2px solid #c7a862;
    border-radius: 8px;
    padding: 2.75rem 3rem 2.25rem;
    box-shadow: 0 24px 64px rgba(0, 0, 0, 0.28);
    text-align: center;
    max-width: 420px;
    width: 90%;
    transform: translateY(18px) scale(0.97);
    transition: transform 0.28s cubic-bezier(0.34, 1.36, 0.64, 1);
}

.ga-email-modal__overlay.ga-email-modal--visible .ga-email-modal__caja {
    transform: translateY(0) scale(1);
}

.ga-email-modal__cerrar {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    background: none;
    border: none;
    cursor: pointer;
    color: #4a4a2f;
    padding: 0.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.45;
    transition: opacity 0.2s ease;
    line-height: 0;
}

.ga-email-modal__cerrar:hover {
    opacity: 1;
}

.ga-email-modal__icono {
    margin-bottom: 1rem;
    line-height: 0;
}

.ga-email-modal__titulo {
    font-family: 'Inter', sans-serif;
    font-size: 1.9rem;
    font-weight: 600;
    color: #4a4a2f;
    margin: 0 0 0.3rem;
    line-height: 1.1;
}

.ga-email-modal__sub {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    color: #4a4a2f;
    opacity: 0.65;
    margin: 0 0 1.25rem;
}

.ga-email-modal__direccion {
    font-family: 'Inter', sans-serif;
    font-size: 1.1rem;
    font-weight: 600;
    color: #4a4a2f;
    margin: 0 0 1.75rem;
    word-break: break-all;
    letter-spacing: -0.01em;
}

.ga-email-modal__acciones {
    display: flex;
    gap: 0.65rem;
    justify-content: center;
    flex-wrap: wrap;
}

.ga-email-modal__enviar {
    display: inline-block;
    padding: 0.7rem 1.5rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #ffffff;
    background: #c7a862;
    border: 2px solid #c7a862;
    border-radius: 2px;
    cursor: pointer;
    text-decoration: none;
    transition: background 0.22s ease, border-color 0.22s ease;
}

.ga-email-modal__enviar:hover {
    background: #b8954f;
    border-color: #b8954f;
    color: #ffffff;
}

.ga-email-modal__copiar {
    display: inline-block;
    padding: 0.7rem 1.5rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    color: #c7a862;
    background: transparent;
    border: 2px solid #c7a862;
    border-radius: 2px;
    cursor: pointer;
    transition: background 0.22s ease, color 0.22s ease;
}

.ga-email-modal__copiar:hover,
.ga-email-modal__copiar--copiado {
    background: #c7a862;
    color: #4a4a2f;
}


/* =============================================================
   16. PÁGINAS INTERNAS
   ============================================================= */

/* Hero simple de página */
.ga-page-hero {
    background-color: var(--ga-naranja-claro);
    padding: var(--ga-space-2xl) 0 var(--ga-space-xl);
}

/* Hero con imagen de fondo */
.ga-page-hero--apadrina,
.ga-page-hero--eventos,
.ga-page-hero--visitas {
    position: relative;
    background-size: cover;
    background-position: center;
    padding: var(--ga-space-3xl) 0;
    min-height: 450px;
    display: flex;
    align-items: center;
}

.ga-page-hero__overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, 0.55);
}

.ga-page-hero .ga-section__inner {
    position: relative;
    z-index: 1;
}

.ga-page-hero__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-5xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    margin-bottom: var(--ga-space-sm);
}

.ga-page-hero__titulo--light {
    color: var(--ga-blanco);
}

.ga-page-hero__subtitulo {
    font-size: var(--ga-text-xl);
    color: rgba(255, 255, 255, 0.85);
    max-width: 600px;
    margin: 0;
    opacity: 1;
}

/* Contenido de página estática (page.php) */
.ga-page-contenido .ga-page-content {
    font-size: var(--ga-text-base);
    line-height: 1.8;
}

.ga-page-content h2 {
    font-size: var(--ga-text-3xl);
    margin: var(--ga-space-xl) 0 var(--ga-space-md);
}

.ga-page-content h3 {
    font-size: var(--ga-text-2xl);
    margin: var(--ga-space-lg) 0 var(--ga-space-sm);
}

/* Sección de contacto */
.ga-contacto-grid__inner {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ga-space-2xl);
    align-items: start;
}

.ga-contacto-dato {
    margin-bottom: var(--ga-space-md);
    padding-bottom: var(--ga-space-md);
    border-bottom: 1px solid rgba(74, 74, 47, 0.1);
}

.ga-contacto-dato strong {
    display: block;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-lg);
    margin-bottom: 4px;
}

.ga-contacto-redes__links {
    display: flex;
    gap: var(--ga-space-sm);
    margin-top: var(--ga-space-xs);
}

.ga-contacto-redes__links a {
    font-size: var(--ga-text-sm);
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
}


/* =============================================================
   17. BLOG ARCHIVE Y SINGLE
   ============================================================= */

/* Hero del archivo */
.ga-archive-hero {
    background-color: var(--ga-naranja-claro);
    padding: var(--ga-space-xl) 0;
}

.ga-archive-hero__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-5xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
}

/* Post individual */
.ga-post-hero {
    background-color: var(--ga-naranja-claro);
    padding: var(--ga-space-xl) 0 var(--ga-space-lg);
}

.ga-post-categorias {
    font-size: var(--ga-text-xs);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    margin-bottom: var(--ga-space-sm);
}

.ga-post-titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-5xl);
    font-weight: var(--ga-weight-bold);
    margin-bottom: var(--ga-space-sm);
}

.ga-post-meta {
    font-size: var(--ga-text-sm);
    color: rgba(74, 74, 47, 0.6);
    display: flex;
    gap: var(--ga-space-sm);
    align-items: center;
}

.ga-post-meta__sep { opacity: 0.4; }

/* Imagen featured del post */
.ga-post-imagen-featured {
    background-color: var(--ga-verde-oliva-oscuro);
}

.ga-post-imagen-featured__img {
    width: 100%;
    max-height: 600px;
    object-fit: cover;
}

/* Contenido del post */
.ga-post-content {
    padding: var(--ga-space-2xl) 0;
}

.ga-post-content p,
.ga-post-content li {
    font-size: var(--ga-text-lg);
    line-height: 1.9;
    margin-bottom: var(--ga-space-sm);
}

/* Navegación entre posts */
.ga-post-nav {
    border-top: 1px solid rgba(74, 74, 47, 0.1);
    padding: var(--ga-space-xl) 0;
}

.ga-post-nav .nav-links {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--ga-space-md);
}

.ga-post-nav__label {
    display: block;
    font-size: var(--ga-text-xs);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    margin-bottom: 4px;
}

.ga-post-nav__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-lg);
    font-weight: var(--ga-weight-bold);
}

/* Tags del post */
.ga-post-tags {
    margin-top: var(--ga-space-xl);
    padding-top: var(--ga-space-md);
    border-top: 1px solid rgba(74, 74, 47, 0.1);
}

.ga-post-tags__lista a {
    display: inline-block;
    background-color: var(--ga-naranja-claro);
    color: var(--ga-verde-oliva-oscuro);
    font-size: var(--ga-text-xs);
    padding: 4px 12px;
    margin: 4px;
    border-radius: var(--ga-radius-full);
    text-decoration: none;
    transition: all var(--ga-transition-fast);
}

.ga-post-tags__lista a:hover {
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
}


/* =============================================================
   18. PAGINACIÓN
   ============================================================= */

.ga-paginacion {
    margin-top: var(--ga-space-2xl);
    text-align: center;
}

.ga-paginacion .nav-links {
    display: flex;
    justify-content: center;
    align-items: center;
    gap: var(--ga-space-xs);
    flex-wrap: wrap;
}

.ga-paginacion .page-numbers {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    color: var(--ga-verde-oliva-oscuro);
    border: 1px solid rgba(74, 74, 47, 0.2);
    text-decoration: none;
    transition: all var(--ga-transition-fast);
}

.ga-paginacion .page-numbers:hover,
.ga-paginacion .page-numbers.current {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
}


/* =============================================================
   19. ANIMACIONES — Entrada al hacer scroll (JS añade .is-visible)
   ============================================================= */

.ga-animate {
    opacity: 0;
    transform: translateY(30px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}

.ga-animate.is-visible {
    opacity: 1;
    transform: translateY(0);
}

.ga-animate--delay-1 { transition-delay: 0.1s; }
.ga-animate--delay-2 { transition-delay: 0.2s; }
.ga-animate--delay-3 { transition-delay: 0.3s; }
.ga-animate--delay-4 { transition-delay: 0.4s; }


/* =============================================================
   20. RESPONSIVE — TABLET (max-width: 1024px)
   ============================================================= */

@media (max-width: 1024px) {

    /* Tipografía */
    .ga-section__titulo { font-size: var(--ga-text-4xl); }
    .ga-hero__titulo    { font-size: clamp(2.5rem, 5vw, 4rem); }
    .ga-sobre__cita     { font-size: var(--ga-text-2xl); }

    /* Navbar */
    .ga-nav__cta { display: none; }

    /* Hero slider */
    .ga-hero { min-height: 500px; }

    /* Sección sobre nosotros: cambiar a 60/40 */
    .ga-section__inner--split {
        grid-template-columns: 60% 40%;
        gap: var(--ga-space-lg);
    }

    /* La almazara: apilar verticalmente */
    .ga-almazara__grid {
        grid-template-columns: 1fr;
    }

    .ga-almazara__imagen-wrapper {
        min-height: 400px;
    }

    .ga-almazara__contenido {
        padding: var(--ga-space-xl) var(--ga-space-lg);
    }

    /* Apadrina: apilar */
    .ga-apadrina-bloque__grid {
        grid-template-columns: 1fr;
        gap: var(--ga-space-xl);
    }

    /* Grid de productos: 2 columnas en tablet */
    .ga-productos-grid--placeholder {
        grid-template-columns: repeat(2, 1fr);
    }

    .ga-productos-grid--4col.ga-productos-grid--placeholder {
        grid-template-columns: repeat(2, 1fr);
    }

    /* Footer: 2 columnas en tablet */
    .ga-footer__inner {
        grid-template-columns: 1fr 1fr;
        gap: 2.5rem;
        padding: 2rem 1.5rem 2rem;
    }

    .ga-footer__col--brand {
        grid-column: auto;
        margin-top: 0;
        margin-bottom: 0;
    }

    /* Contacto: apilar */
    .ga-contacto-grid__inner {
        grid-template-columns: 1fr;
    }
}


/* =============================================================
   21. RESPONSIVE — MÓVIL (max-width: 768px)
   ============================================================= */

@media (max-width: 768px) {

    /* Variables ajustadas para móvil */
    :root {
        --ga-nav-height: var(--ga-nav-height-mobile);
    }

    /* Base */
    .ga-section__inner {
        padding: var(--ga-space-xl) var(--ga-space-sm);
    }

    /* Tipografía */
    h1                  { font-size: var(--ga-text-4xl); }
    h2                  { font-size: var(--ga-text-3xl); }
    .ga-section__titulo { font-size: var(--ga-text-3xl); }
    .ga-page-hero__titulo { font-size: var(--ga-text-4xl); }

    /* Navbar: mostrar menú hamburguesa */

    /* Logo: tamaño reducido en móvil manteniendo proporción */
    .ga-nav__logo img,
    .ga-nav__logo .custom-logo {
        height: 40px !important;
        width: auto !important;
    }

    /* Panel del menú móvil: DESPLEGABLE COMPACTO anclado bajo la cabecera, arriba
       a la derecha (justo bajo la hamburguesa). Su alto es el del CONTENIDO, no
       toda la pantalla (antes era un cajón a pantalla completa: top→bottom).
       position:fixed respecto al VIEWPORT: el top es fijo a la ventana, y en el
       home la cabecera no cambia de alto, así que los enlaces quedan visibles
       desde el primer instante. Se muestra/oculta con opacidad + un pequeño
       translateY, SIEMPRE dentro del viewport (anclado a la derecha y con ancho
       acotado), de modo que nunca puede inflar el documento (no usa left negativo
       ni desliza fuera un ancho completo). */
    .ga-nav__menu-wrapper {
        position: fixed;
        top: calc(var(--ga-nav-height-mobile) + var(--ga-space-xs));
        right: var(--ga-space-sm);
        left: auto;
        bottom: auto;
        /* Ancho AJUSTADO AL CONTENIDO: tan ancho como el enlace más largo
           ("Nosotros"/"Contacto") + el padding lateral del panel, sin espacio
           muerto a la derecha. El max-width de seguridad (72vw, y nunca más que
           el viewport menos su margen) solo entra si un enlace fuera larguísimo;
           en condiciones normales manda el max-content. */
        width: max-content;
        max-width: min(72vw, calc(100vw - var(--ga-space-md)));
        max-height: calc(100vh - var(--ga-nav-height-mobile) - var(--ga-space-md));
        background-color: var(--ga-blanco);
        border: 1px solid rgba(74, 74, 47, 0.1);
        border-radius: var(--ga-radius-md);
        box-shadow: 0 12px 32px rgba(74, 74, 47, 0.16);
        padding: var(--ga-space-xs) var(--ga-space-md);   /* +margen horizontal (16px→24px): el texto
                                                             respira más a los lados. Vertical intacto. */
        overflow-y: auto;
        transform: translateY(-8px);
        opacity: 0;
        visibility: hidden;
        transition: transform var(--ga-transition-normal),
                    opacity var(--ga-transition-normal),
                    visibility var(--ga-transition-normal);
        z-index: 999;
    }

    .ga-nav__menu-wrapper.is-open {
        transform: translateY(0);
        opacity: 1;
        visibility: visible;
    }

    /* PROBLEMA A — causa real: el panel tiene fondo blanco propio, pero cuando la
       cabecera está en modo "over-hero" (arriba del todo del home, cabecera
       transparente) una regla inyectada fuerza los enlaces a BLANCO con !important
       → blanco sobre blanco = invisibles hasta hacer scroll (que pone .is-scrolled
       y los devuelve a oscuro). Aquí los fijamos SIEMPRE en color de marca dentro
       del panel. Especificidad (0,3,2) > la inyectada (0,2,2), y acotado a móvil,
       así que el menú de escritorio conserva su texto blanco sobre el hero. */
    .ga-header .ga-nav__menu-wrapper .ga-nav__menu > li > a {
        color: var(--ga-verde-oliva-oscuro) !important;
    }

    .ga-nav__menu {
        flex-direction: column;
        align-items: flex-start;
        gap: 0;
    }

    .ga-nav__menu > li > a {
        font-size: var(--ga-text-lg);
        padding: var(--ga-space-sm) 0;
        border-bottom: 1px solid rgba(74, 74, 47, 0.08);
        width: 100%;
    }

    /* Último enlace sin línea inferior: cierre limpio del desplegable compacto. */
    .ga-nav__menu-wrapper .ga-nav__menu > li:last-child > a {
        border-bottom: none;
    }

    .ga-nav__menu .sub-menu {
        position: static;
        opacity: 1;
        visibility: visible;
        transform: none;
        box-shadow: none;
        border-top: none;
        padding-left: var(--ga-space-md);
        border-left: 2px solid var(--ga-naranja-apagado);
        margin: var(--ga-space-xs) 0;
    }

    .ga-nav__toggle {
        display: flex;
    }

    /* Hero */
    .ga-hero { min-height: 90vh; }
    .ga-hero__titulo { font-size: clamp(2rem, 8vw, 3rem); }
    .ga-hero__subtitulo { font-size: var(--ga-text-base); }
    .ga-hero__ctas { flex-direction: column; align-items: center; }
    .ga-hero__ctas .ga-btn { width: 100%; max-width: 280px; justify-content: center; }

    /* Sobre nosotros: apilar */
    .ga-section__inner--split {
        grid-template-columns: 1fr;
        gap: var(--ga-space-lg);
    }

    .ga-sobre__derecha {
        padding-left: 0;
    }

    .ga-sobre__cita {
        font-size: var(--ga-text-xl);
    }

    /* Estadísticas de la almazara */
    .ga-almazara__stats {
        flex-wrap: wrap;
        gap: var(--ga-space-md);
    }

    /* Apadrina: 1 columna en beneficios */
    .ga-apadrina-bloque__beneficios {
        grid-template-columns: 1fr;
    }

    /* Productos: 1 columna */
    .ga-productos-grid--placeholder,
    .ga-productos-grid--4col.ga-productos-grid--placeholder {
        grid-template-columns: 1fr;
    }

    /* Footer: logo + tagline arriba, 5 columnas (2 espaciadoras + 3 de contenido).
       Las 2 columnas de 2.5% crean el mismo inset que la línea dorada (94%),
       alineando visualmente el bloque de columnas con esa línea. */
    .ga-footer__inner {
        grid-template-columns: 2.5% 0.7fr 1.6fr 0.7fr 2.5%;
        gap: 1.5rem 0.1rem;
        padding: 1.75rem 0.9rem 1.5rem;
    }

    /* Columna de marca: ocupa las 5 columnas (fila superior) */
    .ga-footer__col--brand {
        grid-column: 1 / -1;
        margin-top: 0;
        margin-bottom: 0;
    }

    /* Colocación explícita de las 3 columnas de contenido en las columnas 2-4 */
    .ga-footer__col--nav      { grid-column: 2; }
    .ga-footer__col--contacto { grid-column: 3; }
    .ga-footer__col--social   { grid-column: 4; }

    .ga-footer__logo {
        width: 140px;
        margin: 0 auto;
    }

    .ga-footer__tagline {
        text-align: center;
    }

    /* Títulos de las 3 columnas de nav: más pequeños, alineados a la izquierda */
    .ga-footer__col-titulo {
        font-size: 0.82rem;
        margin-bottom: 0.55rem;
        text-align: left;
    }

    /* Ítems de menú: fuente reducida, ruptura de palabras largas */
    .ga-footer__menu {
        gap: 0.38rem;
    }

    .ga-footer__menu li a,
    .ga-footer__menu li span {
        font-size: 0.67rem;
        overflow-wrap: break-word;
        word-break: break-word;
        display: block;
    }

    /* Ocultar el bullet › para ganar espacio en las columnas estrechas */
    .ga-footer__menu li a::before,
    .ga-footer__menu li span::before {
        display: none;
    }

    /* Barra inferior: columna centrada, copyright al final */
    .ga-footer__bottom-inner {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 0.65rem;
        padding: 1rem 1.25rem 1.25rem;
    }

    /* Orden móvil: 1.pagos, 2.legal, 3.copyright */
    .ga-footer__legal-nav {
        order: 2;
    }

    .ga-footer__pagos {
        order: 1;
        justify-content: center;
    }

    .ga-footer__copyright {
        order: 3;
        flex: none;
    }

    /* Col-social: texto alineado a la izquierda dentro de su bloque */
    .ga-footer__col--social,
    .ga-footer__col--social .ga-footer__col-titulo {
        text-align: left;
    }

    /* Col-contacto: centrada (col 1.6fr flanqueada por 0.7fr iguales → célula centrada en el grid).
       Especificidad 0,2,0 en el título para superar la regla .ga-footer__col-titulo
       que fuerza text-align: left con 0,1,0 en todas las columnas. */
    .ga-footer__col--contacto,
    .ga-footer__col--contacto .ga-footer__col-titulo {
        text-align: center;
    }

    /* Email en una sola línea.
       clamp: 0.67rem en ≥320px; escala con vw por debajo para que siga cabiendo. */
    .ga-footer__col--contacto .ga-footer__menu li a[href^="mailto"] {
        white-space: nowrap;
        font-size: clamp(0.55rem, 3.35vw, 0.67rem);
    }

    /* Línea dorada entre bloque de marca y las 3 columnas.
       94% = 100% − 2×2.5% (espaciadores) − 2×gap(0.1rem): alinea con el bloque de columnas. */
    .ga-footer__col--brand::after {
        content: '';
        display: block;
        width: 94%;
        height: 1px;
        background: rgba(199, 168, 98, 0.4);
        margin: 1.25rem auto 0;
    }

    /* Posicionamiento con justify-self:
       · nav → pegado al inicio de su celda (borde izquierdo de la línea dorada)
       · contacto → stretch por defecto; text-align: center en bloque anterior
       · social → bloque fit-content pegado al final (borde derecho de la línea dorada);
         text-align: left para que todos los enlaces empiecen en la misma vertical */
    .ga-footer__col--nav {
        justify-self: start;
    }
    .ga-footer__col--social {
        justify-self: end;
        width: fit-content;
        text-align: left;
    }
    .ga-footer__col--social .ga-footer__col-titulo {
        text-align: left;
    }

    /* Página de contacto */
    .ga-contacto-grid__inner {
        grid-template-columns: 1fr;
    }

    /* Tipos de visita: 1 columna */
    .ga-visitas-tipos__grid {
        grid-template-columns: 1fr !important;
    }
}

/* =============================================================
   22. ITERACIÓN HOME (HERO SECTION & PRODUCTOS DESTACADOS)
   ============================================================= */

.ga-hero-section {
    position: relative;
    width: 100%;
    height: 100vh;
    min-height: 600px;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: #2b2b1a; /* Fondo oscuro base para cuando carga la imagen */
    background-size: cover;
    background-position: center;
    margin-top: calc(-1 * var(--ga-nav-height));
    z-index: 1;
}

.ga-hero-overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.35); /* Capa sutil de oscurecimiento */
    z-index: 2;
}

.ga-hero-content {
    position: relative;
    z-index: 3;
    text-align: center;
    max-width: 900px;
    padding: 0 var(--ga-space-md);
    color: var(--ga-blanco);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
}

.ga-hero-content h1,
.ga-hero-title {
    font-family: var(--ga-font-display);
    font-size: clamp(3rem, 8vw, 5.5rem); /* Título de gran tamaño estilo Amfissa */
    font-weight: var(--ga-weight-bold);
    color: var(--ga-blanco);
    line-height: 1.1;
    margin-bottom: var(--ga-space-lg);
    text-shadow: 0 2px 15px rgba(0,0,0,0.4);
    letter-spacing: -0.01em;
}

.ga-hero-content .ga-btn-primary {
    display: inline-block;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    padding: 1.125rem 3rem; /* Botón de padding más generoso y elegante */
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-bold);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 0;
    transition: all var(--ga-transition-normal);
    text-shadow: none;
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.15);
}


.ga-hero-content .ga-btn-primary:hover {
    background-color: transparent;
    color: var(--ga-blanco);
    border-color: var(--ga-blanco);
}

.ga-productos-destacados {
    background-color: var(--ga-blanco);
    padding: var(--ga-space-2xl) 0;
}

.ga-productos-destacados .ga-container {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
}

.ga-productos-destacados .ga-section-header {
    text-align: center;
    margin-bottom: var(--ga-space-xl);
}

.ga-productos-destacados .ga-section-eyebrow {
    display: inline-block;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--ga-naranja-apagado);
    margin-bottom: var(--ga-space-xs);
}

.ga-productos-destacados .ga-section-title {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-4xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    margin: 0;
}

.ga-productos-destacados .ga-section-divider {
    width: 60px;
    height: 2px;
    background-color: var(--ga-naranja-apagado);
    margin: var(--ga-space-sm) auto 0;
}

.ga-productos-destacados .ga-grid-3 {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 2rem;
}

.ga-product-card {
    background-color: var(--ga-blanco);
    text-align: center;
    display: flex;
    flex-direction: column;
    height: 100%;
}

.ga-product-card .ga-img-placeholder {
    width: 100%;
    aspect-ratio: 4/5;
    background-color: #e2e2e2;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
    overflow: hidden;
    margin-bottom: var(--ga-space-md);
    transition: transform var(--ga-transition-normal), box-shadow var(--ga-transition-normal);
}

.ga-product-card .ga-img-placeholder::after {
    content: '';
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, 0.05);
    opacity: 0;
    transition: opacity var(--ga-transition-normal);
}

.ga-product-card:hover .ga-img-placeholder {
    transform: translateY(-8px);
    box-shadow: var(--ga-shadow-md);
}

.ga-product-card:hover .ga-img-placeholder::after {
    opacity: 1;
}

.ga-product-card .ga-placeholder-text {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    color: rgba(74, 74, 47, 0.5);
    z-index: 1;
}

.ga-product-card .ga-placeholder-badge {
    position: absolute;
    top: var(--ga-space-sm);
    left: var(--ga-space-sm);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    padding: 4px 10px;
    letter-spacing: 0.05em;
    text-transform: uppercase;
    z-index: 1;
}

.ga-product-card .ga-product-info {
    padding: 0 var(--ga-space-xs);
}

.ga-product-card h3 {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 var(--ga-space-xs) 0;
}

.ga-product-card .ga-product-divider {
    width: 30px;
    height: 1px;
    background-color: rgba(74, 74, 47, 0.15);
    margin: 0 auto var(--ga-space-xs);
}

.ga-product-card .ga-price {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    font-weight: var(--ga-weight-medium);
    color: var(--ga-naranja-apagado);
}

/* Responsive overrides para iteración home */
@media (max-width: 1024px) {
    .ga-productos-destacados .ga-grid-3 {
        grid-template-columns: repeat(2, 1fr);
        gap: 1.5rem;
    }
    
    /* Centrar el 3er producto en tablets */
    .ga-productos-destacados .ga-grid-3 .ga-product-card:nth-child(3) {
        grid-column: span 2;
        max-width: 50%;
        margin: 0 auto;
    }
}

@media (max-width: 640px) {
    .ga-hero-section {
        margin-top: calc(-1 * var(--ga-nav-height-mobile));
    }
    
    .ga-hero-content h1 {
        font-size: 2.25rem;
    }
    
    .ga-hero-content p {
        font-size: var(--ga-text-base);
    }
    
    .ga-productos-destacados {
        padding: var(--ga-space-xl) 0;
    }
    
    .ga-productos-destacados .ga-grid-3 {
        grid-template-columns: 1fr;
        gap: 2rem;
    }
    
    .ga-productos-destacados .ga-grid-3 .ga-product-card:nth-child(3) {
        grid-column: auto;
        max-width: 100%;
    }
}


/* =============================================================
   23. HOME HERO — Pantalla completa con imagen y frase
   Usado por template-parts/home-hero.php
   ============================================================= */

.ga-home-hero {
    position: relative;
    width: 100%;
    min-height: 100dvh;
    min-height: 620px; /* fallback para navegadores que no soporten dvh */
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    /* Compensa el navbar fijo para que ocupe toda la pantalla */
    margin-top: calc(-1 * var(--ga-nav-height));
}

@supports (min-height: 100dvh) {
    .ga-home-hero {
        min-height: 100dvh;
    }
}

/* Vídeo de fondo */
.ga-home-hero__bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    /* Zoom suave de entrada */
    transform: scale(1.04);
    transition: transform 1.2s ease-out;
}

/* Cuando la página ha cargado, quitar el zoom */
.ga-home-hero.is-loaded .ga-home-hero__bg {
    transform: scale(1);
}

/* Overlay para legibilidad del texto */
.ga-home-hero__overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, var(--hero-overlay, 0.35));
    z-index: 1;
}

/* Contenido centrado */
.ga-home-hero__content {
    position: relative;
    z-index: 2;
    text-align: center;
    padding: 0 var(--ga-space-md);
    max-width: 820px;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ga-space-md);
}

/* Eyebrow pequeño — letra por letra, elegante */
.ga-home-hero__eyebrow {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    opacity: 0.95;
}

/* Título principal — serif grande, blanco, impacto máximo */
.ga-home-hero__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(3rem, 7.5vw, 5.75rem);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-blanco);
    line-height: 1.05;
    letter-spacing: -0.01em;
    text-shadow: 0 2px 24px rgba(0, 0, 0, 0.35);
    text-wrap: balance;
    margin: 0;
}

/* Subtítulo — separadores de puntos medianos */
.ga-home-hero__subtitulo {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    font-weight: var(--ga-weight-normal);
    color: var(--ga-blanco);
    letter-spacing: 0.06em;
    margin: 0;
    opacity: 1;
    line-height: 1.6;
}

/* Botón CTA del hero — dorado */
.ga-home-hero__btn {
    display: inline-flex;
    align-items: center;
    gap: 0.625rem;
    padding: 1rem 2.75rem;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.14em;
    text-transform: uppercase;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 5px;
    text-decoration: none;
    transition: all 0.3s ease;
    margin-top: var(--ga-space-xs);
}

.ga-home-hero__btn:hover {
    background-color: transparent;
    color: var(--ga-blanco);
    border-color: rgba(255, 255, 255, 0.7);
    gap: 0.875rem;
}

.ga-home-hero__btn:active {
    transform: translateY(1px) scale(0.98);
}

.ga-home-hero__btn:focus-visible {
    outline: 2px solid rgba(255, 255, 255, 0.8);
    outline-offset: 3px;
}

/* Flecha de navegación hacia la sección siguiente */
.ga-home-hero__scroll {
    position: absolute;
    bottom: var(--ga-space-lg);
    left: 50%;
    transform: translateX(-50%);
    z-index: 3;
    color: rgba(255, 255, 255, 0.55);
    transition: color 0.2s ease, transform 0.2s ease;
}

.ga-home-hero__scroll:hover {
    color: var(--ga-naranja-apagado);
    transform: translateX(-50%) translateY(3px);
}

/* Bounce solo si el usuario no ha pedido movimiento reducido */
@media (prefers-reduced-motion: no-preference) {
    .ga-home-hero__scroll {
        animation: ga-hero-bounce 2.5s ease-in-out infinite;
    }
}

@keyframes ga-hero-bounce {
    0%, 100% { transform: translateX(-50%) translateY(0); }
    50%       { transform: translateX(-50%) translateY(9px); }
}

/* Sección de productos que viene justo debajo */
.ga-home-hero {
    padding-bottom: 0;
}

.ga-home-productos {
    background-color: var(--ga-blanco);
    padding-top: 2rem;
    padding-bottom: 0.5rem;
    margin-bottom: 0;
}

.ga-home-productos .ga-section__inner {
    padding-top: 2rem;
    padding-bottom: 0.5rem;
}

.ga-home-productos .ga-section__titulo {
    margin-bottom: 0.5rem;
}

.ga-home-productos .ga-section__subtitulo {
    margin-top: 0.5rem;
}

/* ——— Tarjetas custom: imagen + título + precio + botón ——— */
.ga-home-cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--ga-space-md);
    width: 100%;
}

.ga-home-card {
    display: flex;
    flex-direction: column;
    background: var(--ga-blanco);
    border-radius: 4px;
    overflow: hidden;
    box-shadow: var(--shadow-suave);
}

.ga-home-card__img-wrap {
    display: block;
    overflow: hidden;
    min-height: 380px;
}

.ga-home-card__img {
    width: 100%;
    height: 100%;
    min-height: 380px;
    object-fit: contain;
    display: block;
    transition: transform 0.4s ease;
}

.ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: scale(1.04);
}

/* ——— AJUSTE DE TAMAÑO DE FOTO POR PRODUCTO · SOLO "Nuestros Aceites" ———
   Las clases .ga-home-card--sku-* las genera home-productos.php a partir del SKU real,
   así que estos retoques van por producto sin hardcodear IDs ni slugs. Acotado a
   .ga-home-productos: la tienda reutiliza .ga-home-card pero NO imprime la clase de SKU,
   y aun así este prefijo garantiza que nada fuera de esta sección se ve afectado.
   Solo se escala la <img> (transform): el recuadro y la tarjeta no cambian de tamaño, y
   el overflow:hidden del wrap (ya existente) mantiene cualquier escalado dentro del marco.

   Se ajustan LOS DOS estados de cada producto —reposo y hover— para conservar el zoom:
   la regla de hover base (scale 1.04) tiene más especificidad que el reposo por SKU y,
   si no se replicara aquí, al pasar el ratón la foz saltaría al 1.04 genérico (en la 2L
   la encogería; en la 5L la volvería a sacar del marco). El hover de cada una mantiene el
   mismo ~4% de zoom relativo sobre su nuevo tamaño de reposo. */

/* BOTELLA 500ml (GA-BELL-500-OCT): su foto se veía DEMASIADO PEQUEÑA junto a la 2L y la
   5L (cada foto tiene distinta proporción de aire, así que a igual escala la botella se
   ve más chica). Antes no tenía regla → escala base 1.0. Se sube a +15% para que case en
   tamaño con las otras dos. El overflow:hidden del recuadro contiene el escalado (y el del
   hover), así que solo recorta el aire, no la botella. */
.ga-home-productos .ga-home-card--sku-ga-bell-500-oct .ga-home-card__img {
    transform: translateY(10px) scale(1.35);    /* scale 1.35 (tamaño ya bueno, no se toca). translateY
                                                   POSITIVO nuevo: la 500ml quedaba más alta que la 2L/5L;
                                                   se BAJA 10px para alinear su base. translateY antes del
                                                   scale → 10px reales. */
}
.ga-home-productos .ga-home-card--sku-ga-bell-500-oct .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: translateY(10px) scale(1.40);    /* mismo desplazamiento que en reposo (no salta al hover) */
}

/* BOTELLA 2L (GA-PET-2L-NOV): su foto se veía pequeña → +9% en reposo. Centrada
   (transform-origin por defecto) y con aire de sobra, no toca el borde del recuadro. */
.ga-home-productos .ga-home-card--sku-ga-pet-2l-nov .ga-home-card__img {
    transform: scale(0.90);                 /* restablecido al tamaño bueno anterior a la última subida
                                               (era el que se veía bien). Escala sola centrada → base alineada. */
}
.ga-home-productos .ga-home-card--sku-ga-pet-2l-nov .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: scale(0.94);                 /* 0.90 × ~1.04: mismo zoom relativo que las demás */
}

/* GARRAFA 5L (GA-PET-5L-NOV): en reposo llenaba el recuadro y el zoom del hover la
   sacaba fuera → −9% en reposo. Así el hover (0.95) sigue por debajo del 1.0 del marco
   y nunca se derrama.
   Además se SUBE 10px con translateY: la garrafa se veía un pelín más baja que la 2L y
   así sus bases quedan a la misma altura. El mismo desplazamiento va en reposo y en
   hover, para que al pasar el ratón no dé un salto vertical. Va ANTES del scale para que
   sean 10px reales (si fuera después, el scale los reduciría). El margen blanco de la
   foto absorbe la subida, así que ni con el zoom del hover (0.98 < 1.0) se corta arriba. */
.ga-home-productos .ga-home-card--sku-ga-pet-5l-nov .ga-home-card__img {
    transform: translateY(-4px) scale(0.94);    /* translateY antes -10px: la garrafa quedaba más alta que la
                                                   2L (restaurada). Se BAJA 6px (−10 → −4) para alinear su base.
                                                   Scale sin tocar (0.94). */
}
.ga-home-productos .ga-home-card--sku-ga-pet-5l-nov .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: translateY(-4px) scale(0.98);    /* mismo desplazamiento que en reposo (no salta al hover);
                                                   0.98 < 1.0 del recuadro → el zoom del hover no se corta. */
}

.ga-home-card__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--ga-space-sm);
    gap: var(--ga-space-xs);
    text-align: center;
}

.ga-home-card__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1rem, 1.5vw, 1.2rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.2;
}

.ga-home-card__titulo a {
    color: inherit;
    text-decoration: none;
    transition: color 0.2s ease;
}

.ga-home-card__titulo a:hover {
    color: var(--ga-naranja-apagado);
}

.ga-home-card__precio {
    font-family: var(--ga-font-display);
    font-size: 1.1rem;
    color: var(--ga-verde-oliva-oscuro);
    font-weight: var(--ga-weight-medium);
}

.ga-home-card__btn {
    display: block;
    width: 100%;
    margin-top: auto;
    padding: 0.75rem 1rem;
    text-align: center;
    text-decoration: none;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.08em;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 5px;
    transition: var(--transition);
}

.ga-home-card__btn:hover {
    background-color: transparent;
    color: var(--ga-naranja-apagado);
}

/* ——— BRILLO ANIMADO DE "VER PRODUCTO" · SOLO EN DOS SECCIONES DE LA HOME ———
   Mismo mecanismo y mismos valores que el botón de carrito de la tienda: el
   @keyframes ga-home-card-brillo (declarado más abajo, a nivel raíz, así que está
   disponible aquí), 8s linear infinite, degradado a 100° con el punto de luz al 50%,
   background-size 250% 100%, no-repeat y arranque en 100% center. Lo único distinto es
   el color: el DORADO de marca con la luz en un dorado más claro (#e6d0a0). Se anima
   únicamente background-position → ni reflow, ni cambio de tamaño, ni desplazamiento,
   y los estados hover/active existentes se quedan como estaban.

   🔴 ACOTACIÓN. .ga-home-card__btn es la clase BASE, y la tienda la reutiliza tal cual,
   así que el brillo NO puede ir en ella. Cada selector lleva doble cerrojo:
     · .ga-main--home       → el <main> de front-page.php. La tienda es .ga-main--tienda.
     · .ga-home-productos   → la sección "Nuestros Aceites" (template-parts/home-productos.php)
     · .ga-packs            → la sección de packs del final (template-parts/home-packs.php)
   Ninguna de las tres clases aparece en page-tienda.php (comprobado: 0 coincidencias),
   de modo que el "Ver producto" de la tienda sigue sin brillo. */
.ga-main--home .ga-home-productos .ga-home-card__btn,
.ga-main--home .ga-packs .ga-home-card__btn {
    background-image: linear-gradient(
        100deg,
        var(--ga-naranja-apagado) 0%,
        var(--ga-naranja-apagado) 45%,
        #e6d0a0 50%,
        var(--ga-naranja-apagado) 55%,
        var(--ga-naranja-apagado) 100%
    );
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
}

/* En hover el botón se vacía a fondo transparente con texto dorado (regla de arriba):
   el degradado lo taparía, así que ahí se retira y se para el barrido. Ni el tamaño ni
   la posición ni los colores de esos estados cambian respecto a como estaban. */
.ga-main--home .ga-home-productos .ga-home-card__btn:hover,
.ga-main--home .ga-home-productos .ga-home-card__btn:focus,
.ga-main--home .ga-home-productos .ga-home-card__btn:active,
.ga-main--home .ga-packs .ga-home-card__btn:hover,
.ga-main--home .ga-packs .ga-home-card__btn:focus,
.ga-main--home .ga-packs .ga-home-card__btn:active {
    background-image: none;
    animation: none;
}

/* Ahorro de movimiento: dorado sólido, sin degradado ni animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-main--home .ga-home-productos .ga-home-card__btn,
    .ga-main--home .ga-packs .ga-home-card__btn {
        background-image: none;
        animation: none;
    }
}

@media (max-width: 768px) {
    .ga-home-cards {
        grid-template-columns: 1fr;
        max-width: 380px;
        margin: 0 auto;
        gap: 0.75rem;
    }
}

/* ——— Responsive home hero ——— */
@media (max-width: 768px) {
    .ga-home-hero {
        margin-top: calc(-1 * var(--ga-nav-height-mobile));
        min-height: 100svh;
    }

    /* Bloque compacto centrado verticalmente */
    .ga-home-hero__content {
        max-width: 100%;
        padding: 0 1.5rem;
        justify-content: center;
        gap: 0;
    }

    .ga-home-hero__eyebrow {
        font-size: clamp(0.72rem, 3.8vw, 0.82rem);
        letter-spacing: 0.1em;
        white-space: nowrap;
        margin-bottom: 1.5rem;
    }

    .ga-home-hero__titulo {
        font-size: clamp(2.6rem, 13vw, 5.5rem);
        line-height: 1.05;
        margin-bottom: 1.25rem;
    }

    .ga-home-hero__subtitulo {
        font-size: clamp(0.75rem, 3.5vw, 0.82rem);
        letter-spacing: 0.05em;
        white-space: nowrap;
        width: 100%;
        max-width: 280px;
        margin-bottom: 1.25rem;
    }

    .ga-home-hero__btn {
        padding: 1rem 2.5rem;
        width: 100%;
        max-width: 280px;
        justify-content: center;
        margin-top: 0;
    }
}

/* ——— Responsive home productos (cabecera) ——— */
@media (max-width: 768px) {
    /* Espacio entre hero y título: 1.75rem (sección) + 0.75rem (inner) = 2.5rem total */
    .ga-home-productos {
        padding-top: 1.75rem;
    }
    .ga-home-productos .ga-section__inner {
        padding-top: 0.75rem;
    }

    /* Espacio entre subtítulo y primera tarjeta: reducido de 4rem → 2.5rem
       para que el bloque título+subtítulo quede centrado entre hero y primera foto */
    .ga-home-productos .ga-section__header--center {
        margin-bottom: 2.5rem;
    }

    .ga-home-productos .ga-section__titulo {
        font-size: var(--ga-text-4xl);
    }

    .ga-home-productos .ga-section__subtitulo {
        font-size: clamp(0.75rem, 3.8vw, 0.9rem);
        white-space: nowrap;
    }

    .ga-solo-escritorio { display: none; }
    .ga-solo-movil      { display: inline; }

    .ga-home-productos .ga-home-card__titulo {
        font-size: 1.3rem;
        line-height: 1.3;
    }
}


/* =============================================================
   24. TEXTO + IMAGEN DIVIDIDA — ga-texto-split
   ============================================================= */

.ga-texto-split {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 560px;
    background-color: var(--ga-blanco); /* C1: rellena cualquier hueco entre columnas */
    padding-top: 0.5rem;
    padding-bottom: 1rem;
    margin-bottom: 0;
}

.ga-texto-split__contenido {
    display: flex;
    align-items: center;
    background-color: var(--ga-blanco);
    padding: var(--ga-space-2xl);
}

.ga-texto-split__contenido-inner {
    max-width: 500px;
}

.ga-texto-split__cabecera {
    display: none; /* solo visible en móvil */
}

.ga-texto-split__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(2rem, 3.5vw, 2.75rem);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    text-wrap: balance;
    margin-bottom: var(--ga-space-md);
}

.ga-texto-split__contenido p {
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.72;
    line-height: 1.85;
    margin-bottom: var(--ga-space-sm);
    max-width: 48ch;
    text-align: justify;
}

.ga-texto-split__contenido .ga-btn {
    margin-top: var(--ga-space-sm);
    border-radius: 5px;
}

.ga-texto-split__imagen {
    position: relative;
    display: flex;          /* C4: elimina espacio residual bajo el vídeo */
    align-items: stretch;
    overflow: hidden;
    min-height: 500px;
    background-color: var(--ga-blanco); /* C2: fondo explícito en el contenedor del vídeo */
    border-bottom: none;
    outline: none;
    box-shadow: none;
    margin-bottom: 0;
    padding-bottom: 0;
    font-size: 0;
    line-height: 0;
}

.ga-texto-split__imagen img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transition: transform 0.7s ease;
}

.ga-texto-split:hover .ga-texto-split__imagen img {
    transform: scale(1.04);
}

.ga-texto-split__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: var(--ga-blanco);
    display: block;
    pointer-events: none;
}

#olivo-video {
    display: block;
    margin: 0;
    padding: 0;
    border: none;
    outline: none;
}


/* Sin zoom en las imágenes del slider de comparación */
.ga-texto-split:hover .ga-compare img {
    transform: none;
    transition: none;
}


/* =============================================================
   25. PROCESO EN FILA / COLUMNA — ga-proceso / ga-pasos
   Desktop y Tablet (>768px): 6 círculos en fila horizontal.
   Móvil (≤768px): 6 círculos en columna vertical.
   ============================================================= */

.ga-proceso {
    background-color: var(--ga-naranja-claro);
    padding: 2rem 0 2.5rem;
}

.ga-proceso__inner {
    max-width: 1340px;
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
}

.ga-proceso__header {
    text-align: center;
    margin-bottom: 1.5rem;
}

.ga-proceso__header .ga-proceso__titulo {
    margin-bottom: 4px;
}

.ga-proceso__pie {
    text-align: center;
    margin-top: 2.5rem;
    display: block;
}

/* Controles del carrusel móvil — ocultos en escritorio */
.ga-proceso__flecha,
.ga-proceso__dots,
.ga-paso__numero {
    display: none;
}

.ga-proceso__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.8rem, 3.5vw, 2.8rem);
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    margin: var(--ga-space-xs) 0 var(--ga-space-sm);
}

/* ——— Contenedor de pasos ——— */
.ga-pasos {
    display: flex;
    gap: 0;
}

/* ——— Cada paso (estilos compartidos) ——— */
.ga-paso {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    position: relative;
    transition-delay: var(--delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
    .ga-paso { transition-delay: 0ms !important; }
}

/* ——— Círculo dorado protagonista ——— */
.ga-paso__circulo {
    width: 80px;
    height: 80px;
    border-radius: 50%;
    background: var(--ga-naranja-apagado);
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ga-blanco);
    position: relative;
    z-index: 1;
    margin-bottom: 1.1rem;
    flex-shrink: 0;
    box-shadow: 0 6px 20px rgba(199, 168, 98, 0.35);
    transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.ga-paso:hover .ga-paso__circulo {
    transform: scale(1.1);
    box-shadow: 0 12px 32px rgba(199, 168, 98, 0.55);
}

/* ——— Texto ——— */
.ga-paso__titulo {
    font-family: var(--ga-font-display);
    font-size: 1.175rem;
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.2;
    margin: 0 0 0.2rem;
}

.ga-paso__dato {
    font-family: var(--ga-font-body);
    font-size: 0.8rem;
    color: var(--ga-verde-montanas);
    line-height: 1.35;
    margin: 0;
}

/* ——— Foto del proceso ——— */
.ga-paso__foto {
    width: 100%;
    position: relative;
    border-radius: 8px;
    margin-top: 1rem;
    flex-shrink: 0;
}

.ga-paso__foto img {
    width: 100%;
    height: 200px;
    object-fit: cover;
    display: block;
    border-radius: 8px;
    filter: brightness(0.4);
    transition: filter 0.4s ease;
}

/* Hover activado por cualquier parte del paso (círculo o foto) */
.ga-paso:hover .ga-paso__foto img {
    filter: brightness(1);
}

/* ——— Móvil (≤768px): zigzag vertical — círculos en el centro, texto alternando lados ——— */
@media (max-width: 768px) {
    .ga-pasos {
        flex-direction: column;
    }

    /*
     * Grid 3 columnas × 2 filas:
     *   Fila 1: [texto] [círculo 80px] [vacío/texto]
     *   Fila 2: [foto]  [vacío]        [vacío/foto]
     * La col central (fila 2) queda vacía → la spine no se interrumpe nunca.
     */
    .ga-paso {
        display: grid;
        grid-template-columns: 1fr 80px 1fr;
        grid-template-rows: auto auto;
        align-items: center;
        width: 100%;
        padding: 1.5rem 0;
    }

    /* Círculo siempre en la columna central, fila 1 */
    .ga-paso .ga-paso__circulo {
        grid-column: 2;
        grid-row: 1;
        align-self: center;
        margin-bottom: 0;
    }

    /* Pasos impares (1, 3, 5): texto izquierda fila 1, foto izquierda fila 2 */
    .ga-paso:nth-child(odd) .ga-paso__texto {
        grid-column: 1;
        grid-row: 1;
        text-align: right;
        padding-right: 0.85rem;
    }

    .ga-paso:nth-child(odd) .ga-paso__foto {
        grid-column: 1;
        grid-row: 2;
        padding-right: 0.85rem;
        margin-top: 0.75rem;
        align-self: start;
    }

    /* Pasos pares (2, 4, 6): texto derecha fila 1, foto derecha fila 2 */
    .ga-paso:nth-child(even) .ga-paso__texto {
        grid-column: 3;
        grid-row: 1;
        text-align: left;
        padding-left: 0.85rem;
    }

    .ga-paso:nth-child(even) .ga-paso__foto {
        grid-column: 3;
        grid-row: 2;
        padding-left: 0.85rem;
        margin-top: 0.75rem;
        align-self: start;
    }

    /* Altura de foto más compacta en móvil */
    .ga-paso__foto img {
        height: 135px;
    }

    /* Spine vertical: recorre toda la altura de cada paso (col 2 vacía en fila 2 → spine visible) */
    .ga-paso::before {
        content: '';
        position: absolute;
        top: 0;
        bottom: 0;
        left: calc(50% - 1px);
        width: 2px;
        background: var(--ga-naranja-apagado);
        opacity: 0.4;
        z-index: 0;
        pointer-events: none;
        transition: opacity 0.35s ease;
    }

    /* Primer paso: la línea empieza en el centro del círculo */
    .ga-paso:first-child::before {
        top: calc(1.5rem + 40px);
    }

    /* Último paso: la línea termina en el centro del círculo */
    .ga-paso:last-child::before {
        bottom: auto;
        height: calc(1.5rem + 40px);
    }

    .ga-paso:hover::before {
        opacity: 0.9;
    }
}

/* ——— CARRUSEL MÓVIL — override completo del zigzag vertical ——— */
@media (max-width: 768px) {

    /* CAMBIO 1: título en una sola línea — font-size proporcional al viewport
       clamp(min, vw, max): escala con la pantalla; nowrap impide el partido */
    .ga-proceso .ga-proceso__titulo {
        font-size: clamp(1.35rem, 7.8vw, 1.8rem);
        white-space: nowrap;
    }

    /* Puntitos centrados verticalmente en el espacio crema:
       arriba = track-pb (1.25rem) + dots-mt (0.75rem) = 2rem
       abajo  = dots-mb (0.75rem) + section-pb (1.25rem) = 2rem */
    .ga-proceso {
        padding-bottom: 1.25rem;
    }

    /* Quitar padding lateral del inner para que el track use el ancho completo */
    .ga-proceso .ga-proceso__inner {
        padding-left: 0;
        padding-right: 0;
    }

    /* La cabecera recupera su propio padding */
    .ga-proceso .ga-proceso__header {
        padding-left: var(--ga-space-md);
        padding-right: var(--ga-space-md);
    }

    /* Wrapper del carrusel */
    .ga-proceso__carrusel-wrap {
        position: relative;
        padding: 0;
    }

    /* ——— TRACK: pista horizontal con scroll-snap ——— */
    .ga-proceso__carrusel-wrap .ga-pasos {
        flex-direction: row !important;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        gap: 1.75rem;
        padding: 0.75rem 3.5rem 1.25rem;
    }

    .ga-proceso__carrusel-wrap .ga-pasos::-webkit-scrollbar {
        display: none;
    }

    /* ——— SLIDE: cada paso como tarjeta de carrusel ——— */
    .ga-proceso__carrusel-wrap .ga-paso {
        display: flex !important;
        flex-direction: column !important;
        align-items: center !important;
        text-align: center !important;
        min-width: calc(100% - 7rem);
        flex-shrink: 0;
        scroll-snap-align: center;
        scroll-snap-stop: always;
        padding: 0 0 1rem !important;
        background: var(--ga-blanco);
        border-radius: 10px;
        overflow: hidden;
        box-shadow: 0 4px 20px rgba(74, 74, 47, 0.1);
    }

    /* ——— REORDENAMIENTO con CSS order ——— */
    /* 1º foto · 2º texto · 3º círculo · 4º número */
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__foto    { order: 1; }
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__texto   { order: 2; }
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__circulo { order: 3; }
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__numero  { order: 4; }

    /* ——— FOTO: ancho completo, sin border-radius (la tarjeta lo recorta) ——— */
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__foto {
        width: 100%;
        padding: 0 !important;
        margin: 0 !important;
        border-radius: 0;
        align-self: stretch;
    }

    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__foto img {
        height: 245px !important;
        width: 100%;
        object-fit: cover;
        border-radius: 0;
        filter: brightness(1) !important;
        transition: none !important;
    }

    /* ——— NÚMERO DE PASO ——— */
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__numero {
        display: block;
        font-family: var(--ga-font-body);
        font-size: 0.72rem;
        font-weight: 600;
        letter-spacing: 0.14em;
        text-transform: uppercase;
        color: var(--ga-naranja-apagado);
        margin-top: 0;
        margin-bottom: 0;
    }

    /* ——— CÍRCULO ——— */
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__circulo {
        grid-column: unset !important;
        grid-row: unset !important;
        width: 58px;
        height: 58px;
        margin: 1.1rem 0 0.75rem;
        flex-shrink: 0;
    }

    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__circulo svg {
        width: 20px;
        height: 20px;
    }

    /* ——— TEXTO ——— */
    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__texto {
        grid-column: unset !important;
        grid-row: unset !important;
        text-align: center !important;
        padding: 0 1rem !important;
        margin-top: 1.1rem;
    }

    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__titulo {
        font-size: 1.275rem;
    }

    .ga-proceso__carrusel-wrap .ga-paso .ga-paso__dato {
        font-size: 0.875rem;
    }

    /* Override nth-child odd/even del zigzag */
    .ga-proceso__carrusel-wrap .ga-paso:nth-child(odd) .ga-paso__texto,
    .ga-proceso__carrusel-wrap .ga-paso:nth-child(even) .ga-paso__texto {
        grid-column: unset;
        grid-row: unset;
        text-align: center;
        padding: 0 1rem;
    }

    .ga-proceso__carrusel-wrap .ga-paso:nth-child(odd) .ga-paso__foto,
    .ga-proceso__carrusel-wrap .ga-paso:nth-child(even) .ga-paso__foto {
        grid-column: unset;
        grid-row: unset;
        padding: 0;
        margin-top: 0;
    }

    /* Eliminar spine vertical */
    .ga-proceso__carrusel-wrap .ga-paso::before {
        display: none !important;
    }

    /* Cancelar la animación de entrada ga-animate en el carrusel:
       el IntersectionObserver la dispararía al deslizar, moviendo los slides verticalmente */
    .ga-proceso__carrusel-wrap .ga-paso.ga-animate {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
        transition-delay: 0ms !important;
    }

    .ga-proceso__carrusel-wrap .ga-paso.ga-animate.is-visible {
        transform: none !important;
        transition: none !important;
    }

    /* Cancelar hover-scale del círculo en móvil (no hay hover real en touch) */
    .ga-proceso__carrusel-wrap .ga-paso:hover .ga-paso__circulo {
        transform: none;
        box-shadow: 0 6px 20px rgba(199, 168, 98, 0.35);
    }

    /* ——— PUNTOS INDICADORES ——— */
    .ga-proceso__dots {
        display: flex;
        justify-content: center;
        gap: 0.5rem;
        margin-top: 0.75rem;
        margin-bottom: 0.75rem;
        padding: 0;
        border: none;
        background: none;
    }

    .ga-proceso__dot {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: rgba(74, 74, 47, 0.2);
        border: none;
        padding: 0;
        cursor: pointer;
        transition: background 0.25s ease, transform 0.25s ease;
    }

    .ga-proceso__dot.is-active {
        background: var(--ga-naranja-apagado);
        transform: scale(1.5);
    }

}

/* ——— Desktop y Tablet (≥769px): fila horizontal con línea dorada horizontal ——— */
@media (min-width: 769px) {
    .ga-pasos {
        flex-direction: row;
        flex-wrap: nowrap;
        padding: 0.5rem 0 1.5rem;
        gap: 20px;
    }

    .ga-paso {
        flex: 1;
        min-width: 0;
    }

    /* flex-start: los títulos arrancan todos arriba (mismo eje Y).
       min-height en titulo = 2 líneas exactas → el dato siempre
       empieza a la misma altura independientemente de si el título
       ocupa 1 o 2 líneas. margin-bottom separa del círculo. */
    .ga-paso__texto {
        min-height: 4.5rem;
        position: relative;
        display: flex;
        flex-direction: column;
        justify-content: flex-start;
        align-items: center;
        margin-bottom: 20px;
    }

    .ga-paso__titulo {
        min-height: 2.82rem; /* 2 × 1.175rem × line-height 1.2 */
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Línea discontinua vertical: del fondo del círculo hasta la foto.
       Posicionada en ::before de la foto, subiendo 2.1rem (gap total =
       margin-bottom del círculo 1.1rem + margin-top de la foto 1rem). */
    .ga-paso__foto::before {
        content: '';
        position: absolute;
        top: -2.1rem;
        left: calc(50% - 1px);
        width: 0;
        height: 2.1rem;
        border-left: 2px dashed var(--ga-naranja-apagado);
        opacity: 0.3;
        transition: opacity 0.4s ease;
        pointer-events: none;
    }

    .ga-paso:hover .ga-paso__foto::before {
        opacity: 1;
    }

    /* Línea horizontal: del centro de este círculo al centro del siguiente.
       Usa bottom porque el círculo está debajo del texto (altura variable desde arriba).
       Centro del círculo desde paso bottom = foto(200px) + gap(2.1rem) + radio(40px). */
    .ga-paso::after {
        content: '';
        position: absolute;
        bottom: calc(239px + 2.1rem);
        left: 50%;
        width: calc(100% + 20px);
        height: 2px;
        background: var(--ga-naranja-apagado);
        opacity: 0.4;
        transition: opacity 0.35s ease;
        z-index: 0;
        pointer-events: none;
    }

    .ga-paso:last-child::after {
        display: none;
    }

    .ga-paso.ga-linea-activa::after {
        opacity: 1;
    }
}


/* =============================================================
   26. SECCIÓN ACEITUNERO
   Split 50/50: overline + título + texto a la izquierda, vídeo a la derecha.
   ============================================================= */

.ga-aceitunero-split {
    background-color: var(--ga-blanco);
    padding: 4rem 2rem 2rem; /* bottom reducido para acercar a la sección de compra */
}

/* Marco dorado elegante que envuelve texto + vídeo */
.ga-aceitunero-split__marco {
    border: 1px solid var(--ga-naranja-apagado);
    border-radius: 6px;
    padding: 3rem;
    max-width: 1060px;
    margin: 0 auto;
}

/* Grid de dos columnas */
.ga-aceitunero-split__columnas {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 4rem;
    min-height: 460px;
}

/* Columna izquierda: centra verticalmente todo el bloque de texto */
.ga-aceitunero-split__contenido {
    display: flex;
    align-items: center;
}

.ga-aceitunero-split__contenido-inner {
    width: 100%;
}

/* Overline en dorado */
.ga-aceitunero-split__contenido-inner .ga-overline {
    color: var(--ga-naranja-apagado);
}

.ga-aceitunero-split__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(2rem, 3.5vw, 2.75rem);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    text-wrap: balance;
    margin: 0.5rem 0 var(--ga-space-md);
}

.ga-aceitunero-split__contenido p {
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.72;
    line-height: 1.85;
    margin-bottom: var(--ga-space-sm);
    text-align: justify;
}

/* Chevrons animados — centrados respecto a la columna izquierda */
.ga-aceitunero-scroll {
    display: flex;
    flex-direction: column;
    align-items: center;
    width: fit-content;
    margin: var(--ga-space-md) auto 0;
    color: var(--ga-naranja-apagado);
    text-decoration: none;
    animation: ga-bounce-down 1.8s ease-in-out infinite;
    line-height: 0;
}

.ga-aceitunero-scroll svg {
    display: block;
    margin-bottom: -10px;
}

.ga-aceitunero-scroll svg:last-child {
    margin-bottom: 0;
}

.ga-aceitunero-scroll:focus {
    outline: none;
}

.ga-aceitunero-scroll:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 4px;
}

@keyframes ga-bounce-down {
    0%, 100% { transform: translateY(0); }
    50%       { transform: translateY(8px); }
}

/* Flechas duplicadas — ocultas en escritorio, visibles en móvil vía @media */
.ga-aceitunero-split__flechas-movil {
    display: none;
}

/* Columna derecha: solo el vídeo */
.ga-aceitunero-split__video-wrap {
    position: relative;
    overflow: hidden;
    min-height: 420px;
    background-color: var(--ga-blanco);
}

.ga-aceitunero-split__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: var(--ga-blanco);
    display: block;
    pointer-events: none;
}

/* Overlay transparente sobre el vídeo: hace toda la columna clicable.
   z-index: 1 queda sobre el vídeo (pointer-events: none); el autoplay no se ve afectado. */
.ga-aceitunero-split__video-link {
    position: absolute;
    inset: 0;
    z-index: 1;
    cursor: pointer;
    text-decoration: none;
}

/* Título clicable: hereda tipografía exacta, dorado en hover */
.ga-aceitunero-split__titulo-link {
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.25s ease;
}

.ga-aceitunero-split__titulo-link:hover {
    color: var(--ga-naranja-apagado);
}

/* Mobile: overline+título → vídeo → flechas (párrafos y flechas originales ocultos) */
@media (max-width: 768px) {
    .ga-aceitunero-split {
        padding: 2rem 1rem;
    }

    .ga-aceitunero-split__marco {
        padding: 1.5rem;
    }

    .ga-aceitunero-split__columnas {
        grid-template-columns: 1fr;
        gap: 0;
        min-height: auto;
    }

    /* Elimina el margin-bottom: 2rem del título y el centrado vertical que deja espacio muerto */
    .ga-aceitunero-split__contenido {
        align-items: flex-start;
    }

    .ga-aceitunero-split__titulo {
        margin-bottom: 0;
    }

    .ga-aceitunero-split__video-wrap {
        min-height: 280px;
    }

    .ga-aceitunero-split__contenido-inner p {
        display: none;
    }

    .ga-aceitunero-split__contenido-inner .ga-aceitunero-scroll {
        display: none;
    }

    .ga-aceitunero-split__flechas-movil {
        display: none;
    }
}


/* =============================================================
   30. RESPONSIVE — Secciones 24-29
   ============================================================= */

/* —— Tablet (max 1024px) —— */
@media (max-width: 1024px) {

    .ga-proceso__grid {
        grid-template-columns: repeat(3, 1fr);
    }
}

/* —— Móvil (max 768px) —— */
@media (max-width: 768px) {

    /* Texto + imagen: imagen arriba, texto abajo */
    .ga-texto-split {
        grid-template-columns: 1fr;
    }

    .ga-texto-split__imagen {
        order: -1;
        min-height: 300px;
    }

    .ga-texto-split__contenido {
        padding: var(--ga-space-xl) var(--ga-space-md);
    }

    .ga-texto-split__contenido-inner {
        max-width: 100%;
    }

    /* Proceso: 2 columnas en móvil */
    .ga-proceso__grid {
        grid-template-columns: repeat(2, 1fr);
    }

    .ga-proceso__item {
        padding: var(--ga-space-sm) var(--ga-space-xs) var(--ga-space-md);
    }

}

/* ——— Responsive #seccion-olivo — reordenamiento móvil ——— */
@media (max-width: 768px) {

    /* Ocultar la sección completa en móvil para mejorar rendimiento */
    #seccion-olivo.ga-texto-split {
        display: none;
    }

    /* 1º: cabecera (eyebrow + título) */
    #seccion-olivo .ga-texto-split__cabecera {
        display: block;
        order: 1;
        padding: 1.5rem var(--ga-space-md) var(--ga-space-md);
    }

    /* 2º: vídeo — sobreescribe el order: -1 genérico */
    #seccion-olivo .ga-texto-split__imagen {
        order: 2;
        min-height: 300px;
    }

    /* 3º: contenido (solo muestra el botón, centrado) */
    #seccion-olivo .ga-texto-split__contenido {
        order: 3;
        padding: 0.5rem var(--ga-space-md) var(--ga-space-md);
        justify-content: center;
    }

    /* Ocultar eyebrow, título y párrafos del contenido en móvil */
    #seccion-olivo .ga-texto-split__contenido-inner > .ga-section__eyebrow,
    #seccion-olivo .ga-texto-split__contenido-inner > .ga-texto-split__titulo,
    #seccion-olivo .ga-texto-split__contenido-inner > p {
        display: none;
    }
}

/* —— Extra pequeño (max 480px) —— */
@media (max-width: 480px) {

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


/* =============================================================
   SLIDER COMPARACIÓN — ga-compare
   Vive dentro de .ga-texto-split__imagen (position: relative)
   ============================================================= */

/* Contenedor: ocupa exactamente el mismo espacio que la imagen anterior */
.ga-compare {
    position: absolute;
    inset: 0;
    overflow: hidden;
    cursor: ew-resize;
    user-select: none;
    -webkit-user-select: none;
}

/* ── Imágenes ──────────────────────────────────────────────── */

/* Anulamos el zoom-hover heredado de .ga-texto-split__imagen img */
.ga-compare img {
    transition: none !important;
}

/* Imagen "después" (centenario) — capa base, llena el contenedor */
/* Especificidad 0,2,0 > .ga-texto-split__imagen img (0,1,1) */
.ga-compare .ga-compare__after {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    background: var(--ga-naranja-claro);
    pointer-events: none;
    -webkit-user-drag: none;
}

/* Wrapper que recorta la imagen "antes" por la derecha */
.ga-compare__before-wrap {
    position: absolute;
    top: 0;
    left: 0;
    height: 100%;
    width: 70%; /* valor inicial; JS lo actualiza en px% */
    overflow: hidden;
    z-index: 1;
}

/* Imagen "antes" (joven) — JS fija su width al ancho total del contenedor */
/* Especificidad 0,2,0 > .ga-texto-split__imagen img (0,1,1) */
.ga-compare .ga-compare__before {
    position: absolute;
    inset: auto;
    top: 0;
    left: 0;
    height: 100%;
    /* width: se asigna por JS para igualar el ancho del contenedor padre */
    object-fit: contain;
    background: var(--ga-naranja-claro);
    pointer-events: none;
    -webkit-user-drag: none;
}

/* ── Línea divisoria ───────────────────────────────────────── */

.ga-compare__divider {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 70%; /* valor inicial; JS lo actualiza */
    width: 2px;
    background: var(--ga-naranja-apagado);
    transform: translateX(-50%);
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: ew-resize;
}

/* ── Handle dorado ─────────────────────────────────────────── */

.ga-compare__handle {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 48px;
    height: 48px;
    border-radius: 50%;
    background: var(--ga-naranja-apagado);
    border: none;
    cursor: ew-resize;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 2px;
    padding: 0;
    box-shadow: 0 2px 16px rgba(0, 0, 0, 0.28);
    touch-action: none;
    transition: transform 0.15s ease, box-shadow 0.15s ease;
    flex-shrink: 0;
}

.ga-compare__handle:hover,
.ga-compare__handle:focus-visible {
    transform: translate(-50%, -50%) scale(1.12);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.35);
    outline: none;
}

/* ── Etiquetas de esquina ──────────────────────────────────── */

.ga-compare__label {
    position: absolute;
    bottom: 1rem;
    z-index: 5;
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-blanco);
    background: rgba(26, 26, 20, 0.60);
    padding: 0.28rem 0.65rem;
    border-radius: 3px;
    pointer-events: none;
    white-space: nowrap;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}

.ga-compare__label--l { left:  1rem; }
.ga-compare__label--r { right: 1rem; }


/* =============================================================
   SECCIÓN 28 — COMPRAR ACEITUNERO
   Zona de compra (galería + info) + carrusel de aceitunas
   ============================================================= */

.ga-comprar-aceitunero {
    background-color: var(--ga-blanco);
    padding: 2rem 2rem 5rem; /* lateral 2rem = mismo que .ga-aceitunero-split */
}

.ga-comprar-aceitunero__inner {
    max-width: 1060px; /* mismo que .ga-aceitunero-split__marco → columnas encolumnadas */
    margin: 0 auto;
    padding: 0;
}


/* ── PARTE 1: Zona de compra ─────────────────────────────── */

.ga-product-zone {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); /* min=0 evita que min-content de la marquesina encoja la galería */
    gap: 4rem;
    align-items: center;
}

/* — Galería — */
.ga-product-zone__galeria {
    position: sticky;
    top: 6rem;
    align-self: start; /* la galería no se estira: fija el row height por su aspect-ratio 1/1 */
}

.ga-galeria {
    position: relative;
    overflow: hidden;
    border-radius: 6px;
    background: var(--ga-blanco);
    aspect-ratio: 1 / 1;
}

.ga-galeria__track {
    display: flex;
    transition: transform 0.4s ease;
    height: 100%;
}

.ga-galeria__slide {
    flex: 0 0 100%;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ga-blanco);
}

.ga-galeria__img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Slide 0: vídeo del aceitunero */
.ga-galeria__slide--video {
    position: relative;
}

.ga-galeria__video {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
}

/* Botones prev/next de la galería */
.ga-galeria__btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    border: 1px solid rgba(74, 74, 47, 0.14);
    color: var(--ga-verde-oliva-oscuro);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    transition: var(--transition);
    padding: 0;
}

.ga-galeria__btn:hover {
    background: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border-color: var(--ga-naranja-apagado);
}

.ga-galeria__btn--prev { left: 0.6rem; }
.ga-galeria__btn--next { right: 0.6rem; }

/* Miniaturas */
.ga-galeria__thumbs {
    display: flex;
    gap: 0.5rem;
    margin-top: 0.75rem;
    flex-wrap: wrap;
}

.ga-galeria__thumb {
    width: 62px;
    height: 62px;
    border-radius: 4px;
    border: 2px solid transparent;
    background: var(--ga-blanco);
    overflow: hidden;
    cursor: pointer;
    transition: border-color 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    flex-shrink: 0;
}

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

.ga-galeria__thumb:hover,
.ga-galeria__thumb.is-active {
    border-color: var(--ga-naranja-apagado);
}

/* Miniatura de vídeo */
.ga-galeria__thumb--video {
    background: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
}

.ga-galeria__thumb--video:hover,
.ga-galeria__thumb--video.is-active {
    background: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
}

/* — Columna de info — */
.ga-product-zone__info {
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    gap: 1.6rem;
    min-width: 0; /* corta la propagación del min-content de la marquesina al grid */
    text-align: center;
}

.ga-product-zone__nombre {
    font-family: var(--ga-font-display);
    font-size: clamp(1.2rem, 2.1vw, 1.65rem);
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    letter-spacing: -0.015em;
    margin: 0;
}

.ga-product-zone__nombre a {
    color: inherit;
    text-decoration: none;
    transition: color 0.2s ease;
}

.ga-product-zone__nombre a:hover {
    color: var(--ga-naranja-apagado);
}

/* Precio */
.ga-product-zone__precio {
    margin: -0.6rem 0 0;
}

/* Encabezado: título + franja pegados como un bloque */
.ga-pz-encabezado {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 0; /* corta la cadena de propagación del min-content de la marquesina */
}

/* Franja de oferta — marquee continuo */
.ga-pz-oferta-franja {
    overflow: hidden;
    height: 1.8rem;
    display: flex;
    align-items: center;
}

.ga-pz-oferta-franja__track {
    display: flex;
    white-space: nowrap;
    animation: ga-marquee 36s linear infinite; /* 2× duración: cada span tiene 2 unidades de texto */
    will-change: transform;
}

.ga-pz-oferta-franja__texto {
    display: inline-block;
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-naranja-apagado);
    white-space: nowrap;
}

@keyframes ga-marquee {
    0%   { transform: translateX(0); }
    100% { transform: translateX(-50%); }
}

/* Badge "OFERTA -X%" (mantenido por si se reutiliza) */
.ga-pz-badge {
    display: inline-block;
    background: var(--ga-blanco);
    color: var(--ga-naranja-apagado);
    border: 1.5px solid var(--ga-naranja-apagado);
    font-family: var(--ga-font-body);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    padding: 0.28rem 0.65rem;
    border-radius: 3px;
}

/* Precios — antiguo gris + rebajado dorado, alineados por baseline */
.ga-pz-precios-row {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 1.2rem;
    margin: 0;
}

/* L2: badge + frase ahorro en una sola línea */
.ga-pz-meta-row {
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.ga-pz-precio-original {
    display: inline-block;  /* necesario para que ::after se posicione dentro del span */
    position: relative;
    font-family: var(--ga-font-display);
    font-size: 1.5rem;
    font-weight: 500;
    color: rgba(150, 90, 90, 0.75);
    line-height: 1;
    text-decoration: none;  /* tachado nativo desactivado — lo hacemos con ::after */
}

/* Línea de tachado controlada: 58% compensa la métrica de Cormorant Garamond
   (dígitos apoyan alto en la caja, centro óptico real por debajo del 50%) */
.ga-pz-precio-original::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    top: 58%;
    transform: translateY(-50%);
    height: 2px;
    background: rgba(150, 90, 90, 0.55);
    pointer-events: none;
}

.ga-pz-precio-original del,
.ga-pz-precio-original ins,
.ga-pz-precio-original bdi {
    text-decoration: none;
    background: none;
}

/* Fuerza line-height: 1 en los spans internos de WooCommerce para que la caja
   del precio mida exactamente font-size × 1 y el ::after al 50% caiga en el centro */
.ga-pz-precio-original .woocommerce-Price-amount,
.ga-pz-precio-original bdi,
.ga-pz-precio-original .woocommerce-Price-currencySymbol {
    line-height: 1;
    vertical-align: baseline;
}

.ga-pz-precio-flecha {
    font-family: var(--ga-font-body);
    font-size: 1.1rem;
    color: rgba(0, 0, 0, 0.55);
    line-height: 1;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    position: relative;
    top: 1px;
}

.ga-pz-precio-rebajado {
    font-family: var(--ga-font-display);
    font-size: 1.75rem;
    font-weight: 700;
    color: var(--ga-naranja-apagado);
    line-height: 1;
}

/* "Ahorras X€" */
.ga-pz-ahorro {
    font-family: var(--ga-font-body);
    font-size: 0.82rem;
    font-weight: 600;
    color: var(--ga-verde-montanas);
    margin: 0;
}

/* "Por tiempo limitado" */
.ga-pz-urgencia {
    font-family: var(--ga-font-body);
    font-size: 0.78rem;
    color: var(--ga-marron-oscuro);
    font-style: italic;
    opacity: 0.85;
    margin: 0;
}

/* Descripción visual con puntos */
.ga-pz-desc-visual {
    margin: 0;
    padding: 0;
    text-align: left;
}

.ga-pz-desc-intro {
    font-family: var(--ga-font-body);
    font-size: 1.05rem;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 1;
    line-height: 1.65;
    margin: 0 0 0.75rem;
}

.ga-pz-features {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 10px;
    list-style: none;
    padding: 0;
    margin: 0;
}

.ga-pz-features li {
    font-family: var(--ga-font-body);
    font-size: 0.85rem;
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.35;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 0.4rem;
    white-space: nowrap;
    overflow: hidden;
    background: var(--ga-naranja-claro);
    border: 1px solid var(--ga-naranja-apagado);
    border-radius: 6px;
    padding: 10px 10px;
    box-sizing: border-box;
    transition: background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
    cursor: default;
}

.ga-pz-features li:hover {
    background: #97a063;
    color: var(--ga-blanco);
    border-color: var(--ga-verde-oliva-oscuro);
}

.ga-pz-features li:hover .ga-pz-features__icon svg {
    stroke: var(--ga-blanco);
}

.ga-pz-features__icon {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    margin-top: 0.1rem;
}

.ga-pz-features__icon svg {
    transition: stroke 0.25s ease;
}


/* Textos alternativos para escritorio/móvil en los features */
.ga-pz-txt-m { display: none; }

/* Control de cantidad móvil — oculto en escritorio */
.ga-qty-movil-wrap { display: none; }

/* — Selector de cantidad tipo ruleta — */
.ga-product-zone__cantidad {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.6rem;
    margin: 0;
}

.ga-qty-label {
    font-family: var(--ga-font-body);
    font-size: 0.8rem;
    font-weight: 400;
    color: var(--ga-verde-oliva-oscuro);
    letter-spacing: 0.08em;
    opacity: 1;
    white-space: nowrap;
}

/* Cuadrado ruleta: clic mitad sup. = +1, mitad inf. = −1 */
.ga-qty-ruleta {
    position: relative;
    width: 40px;
    height: 40px;
    border: 1px solid rgba(74, 74, 47, 0.15);
    border-radius: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--ga-blanco);
    cursor: pointer;
    user-select: none;
    overflow: hidden;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    flex-shrink: 0;
}

.ga-qty-ruleta:focus {
    outline: none;
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.15);
}

/* Zonas invisibles que revelan las flechas al hover */
.ga-qty-ruleta__zona {
    position: absolute;
    left: 0; right: 0;
    height: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0;
    transition: opacity 0.18s ease, background 0.18s ease;
}

.ga-qty-ruleta__zona--mas   { top: 0;    align-items: flex-start; padding-top: 1px; }
.ga-qty-ruleta__zona--menos { bottom: 0; align-items: flex-end;   padding-bottom: 1px; }

.ga-qty-ruleta:hover .ga-qty-ruleta__zona { opacity: 0.75; }

.ga-qty-ruleta:hover .ga-qty-ruleta__zona--mas {
    background: linear-gradient(to bottom, rgba(199,168,98,0.08), transparent);
}
.ga-qty-ruleta:hover .ga-qty-ruleta__zona--menos {
    background: linear-gradient(to top, rgba(199,168,98,0.08), transparent);
}

/* Número central */
.ga-qty-ruleta__numero {
    font-family: var(--ga-font-body);
    font-size: 1rem;
    font-weight: 400;
    color: #000000;
    opacity: 1;
    line-height: 1;
    position: relative;
    z-index: 1;
    pointer-events: none;
    transition: transform 0.1s ease;
}

/* — Botones de compra — */
.ga-product-zone__botones {
    display: flex;
    justify-content: center;
    gap: 0.75rem;
    margin: 0;
    flex-wrap: wrap;
}

.ga-product-zone__botones .ga-btn {
    flex: 1;
    text-align: center;
    justify-content: center; /* inline-flex en .ga-btn → sin esto el texto queda a la izq. */
    min-width: 140px;
    border-radius: 5px;
}

.ga-btn--comprar-ya {
    position: relative;
}

.ga-btn--comprar-ya:disabled,
.ga-btn--atc:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

/* Estado "añadido" para el botón ATC */
.ga-btn--atc.is-added {
    background: var(--ga-verde-montanas);
    border-color: var(--ga-verde-montanas);
    color: var(--ga-blanco);
}

/* ATC hover local — sobreescribe el marrón global: fondo blanco, texto y borde dorado */
.ga-product-zone__botones .ga-btn--atc:hover:not(:disabled) {
    background-color: var(--ga-blanco);
    border-color: var(--ga-naranja-apagado);
    color: var(--ga-naranja-apagado);
    transform: translateY(-2px);
    box-shadow: var(--shadow-suave);
}

/* Comprar ya — borde siempre oscuro, nunca dorado en hover */
.ga-product-zone__botones .ga-btn--comprar-ya:hover:not(:disabled) {
    background-color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
    transform: translateY(-2px);
}

/* Botón "Comprar ya" — outline dorado */
.ga-btn--outline-dorado {
    background: transparent;
    color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
}

.ga-btn--outline-dorado:hover {
    background: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    transform: translateY(-2px);
    box-shadow: var(--shadow-suave);
}

.ga-btn--outline-dorado:disabled {
    opacity: 0.5;
    cursor: not-allowed;
    transform: none;
}

/* — Iconos de confianza — */
.ga-product-zone__trust {
    display: flex;
    justify-content: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.ga-trust-item {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--ga-font-body);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.75;
}

.ga-trust-item svg {
    flex-shrink: 0;
    color: var(--ga-naranja-apagado);
    opacity: 1;
}


/* ── PARTE 2: Carrusel de aceitunas ─────────────────────── */

.ga-aceitunas {
    margin-top: 5rem;
    /* max-width y auto-margins eliminados: el padre __inner ya define el ancho (1060px) */
}

.ga-aceitunas__header {
    text-align: center;
    margin-bottom: 2rem;
}

.ga-aceitunas__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.4rem, 2.2vw, 1.8rem);
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 0.4rem;
}

.ga-aceitunas__subtitulo {
    font-family: var(--ga-font-body);
    font-size: 0.88rem;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.65;
    margin: 0;
}

.ga-aceitunas__wrapper {
    position: relative;
    display: flex;
    align-items: center;
    padding: 0; /* fotos al ras del margen del __inner — flechas salen fuera con posición negativa */
}

.ga-aceitunas__btn {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 10;
    background: none;
    border: none;
    color: var(--ga-naranja-apagado);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    padding: 0.25rem;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease, color 0.2s ease;
    outline: none;
}

.ga-aceitunas__btn--prev { left: -3.5rem; }  /* fuera del margen de contenido, separadas de los tarros */
.ga-aceitunas__btn--next { right: -3.5rem; }

/* Flechas visibles vía JS con clase (gestiona el hueco entre wrapper y botón) */
.ga-aceitunas--flechas-visibles .ga-aceitunas__btn {
    opacity: 1;
    pointer-events: auto;
}

.ga-aceitunas__btn:focus,
.ga-aceitunas__btn:focus-visible {
    outline: none !important;
    border: none !important;
    box-shadow: none !important;
    color: var(--ga-naranja-apagado);
}

.ga-aceitunas__btn:active {
    color: var(--ga-blanco);
}

@media (hover: none) {
    .ga-aceitunas__btn {
        opacity: 0.55;
        pointer-events: auto;
    }
}

.ga-aceitunas__viewport {
    width: 100%; /* viewport llena todo el wrapper — flechas van sobre él (absolutas) */
    overflow: hidden;
}

.ga-aceitunas__track {
    display: flex;
    gap: 1.5rem;
    transition: transform 0.4s ease;
}

/* Tarjeta de aceituna */
.ga-aceituna-card {
    flex: 0 0 calc(25% - 1.125rem); /* 4 tarjetas × gap 1.5rem: (3×1.5)/4=1.125rem */
    background: var(--ga-blanco);
    border-radius: 6px;
    overflow: hidden;
    border: 1px solid var(--ga-negro-suave);
    box-shadow: var(--shadow-suave);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.ga-aceituna-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-media);
}

/* Contenedor de la foto */
.ga-aceituna-card__img-wrap {
    position: relative;
    overflow: hidden;
    aspect-ratio: 1 / 1;
    background: var(--ga-naranja-claro);
}

.ga-aceituna-card__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transform: scale(1.35);        /* +35% (antes +18%): el tarro se ve claramente más grande dentro de
                                      su tarjeta, apurando el hueco pero sin tocar los bordes. Ni la
                                      tarjeta ni el __img-wrap (aspect-ratio 1/1) cambian de tamaño: solo
                                      crece la imagen. Centrado por defecto (object-position + transform-
                                      origin center). El overflow:hidden del __img-wrap contiene el
                                      escalado (y el del hover), así que solo recorta el aire, no el producto. */
    transition: transform 0.35s ease;
}

.ga-aceituna-card:hover .ga-aceituna-card__img {
    transform: scale(1.43);        /* 1.35 × ~1.06: mismo zoom relativo del hover que antes */
}

/* Overlay oscuro */
.ga-aceituna-card__overlay {
    position: absolute;
    inset: 0;
    background: rgba(0, 0, 0, 0.75);
    opacity: 0;
    transition: opacity 0.3s ease;
    pointer-events: none;
}

.ga-aceituna-card:hover .ga-aceituna-card__overlay {
    opacity: 1;
}

/* Info (nombre + precio + botón) — centrado en hover */
.ga-aceituna-card__info {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 1rem;
    text-align: center;
    z-index: 2;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.ga-aceituna-card:hover .ga-aceituna-card__info {
    opacity: 1;
}

.ga-aceituna-card__link {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start; /* nombre siempre pegado arriba → precio a Y fija */
    gap: 0.3rem;
    height: 4.6rem;       /* altura fija: garantiza que el botón siempre quede al mismo Y */
    width: 100%;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    overflow: visible;
}

.ga-aceituna-card__nombre {
    font-family: var(--ga-font-body);
    font-size: 0.95rem;
    font-weight: 600;
    color: var(--ga-blanco);
    margin: 0;
    line-height: 1.25;
    height: 2.5rem;       /* fija = 2 líneas (0.95×1.25×2 ≈ 2.375rem), precio arranca siempre al mismo Y */
    overflow: hidden;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
    text-align: center;
}

/* Variantes de nombre: completo (escritorio) / sin peso (móvil) */
.ga-acn-m { display: none; }

.ga-aceituna-card__precio {
    font-family: var(--ga-font-display);
    font-size: 1.2rem;
    font-weight: 700;
    color: var(--ga-blanco);
    margin: 0;
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.5);
}

.ga-aceituna-card__precio .woocommerce-Price-amount {
    font-size: inherit;
    font-family: inherit;
    color: inherit;
}

/* Botón carrito — en el flujo del info centrado */
.ga-aceituna-card__add {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    background: var(--ga-naranja-apagado);
    border: none;
    color: var(--ga-blanco);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
    flex-shrink: 0;
    transition: background 0.2s ease, transform 0.2s ease;
    margin-top: 0.25rem;
}

.ga-aceituna-card__add:hover {
    background: var(--ga-verde-oliva-oscuro);
    transform: scale(1.1);
}

/* Estado "añadido" */
.ga-aceituna-card__add.is-added {
    background: var(--ga-verde-montanas);
    cursor: default;
}

.ga-aceituna-card__add.is-added:hover {
    transform: none;
}

.ga-aceituna-card__add .ga-add-text   { display: flex; }
.ga-aceituna-card__add .ga-check-text { display: none; }

.ga-aceituna-card__add.is-added .ga-add-text   { display: none; }
.ga-aceituna-card__add.is-added .ga-check-text { display: flex; }


/* ── RESPONSIVE ──────────────────────────────────────────── */

@media (max-width: 900px) {
    .ga-product-zone {
        grid-template-columns: 1fr;
        gap: 2rem;
    }

    .ga-product-zone__galeria {
        position: static;
    }

    .ga-galeria {
        max-width: 480px;
        margin: 0 auto;
    }

    .ga-aceituna-card {
        flex: 0 0 calc(33.33% - 1rem); /* 3 tarjetas × gap 1.5rem: (2×1.5)/3=1rem */
    }

    /* En pantallas pequeñas las flechas vuelven al interior — no hay espacio lateral suficiente */
    .ga-aceitunas__wrapper {
        padding: 0 2.5rem;
    }

    .ga-aceitunas__btn--prev { left: 0; }
    .ga-aceitunas__btn--next { right: 0; }
}

@media (max-width: 768px) {
    /* Sube la sección respecto a la anterior */
    .ga-comprar-aceitunero {
        padding: 0.5rem 1rem 5rem;
    }

    /* C3: título mucho más grande, una sola línea, escala con el viewport */
    .ga-product-zone__nombre {
        font-size: clamp(1.1rem, 5.4vw, 1.65rem);
        white-space: nowrap;
        overflow: hidden;
    }

    /* Precio centrado */
    .ga-pz-precios-row {
        justify-content: center;
    }

    /* C2: texto descriptivo centrado + más separado de los checkpoints */
    .ga-pz-desc-intro {
        text-align: center;
        margin-bottom: 1.5rem;
    }

    /* Checkpoints: rejilla 2×2 centrada, texto corto, tamaño ajustado para 360px */
    .ga-pz-features {
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 8px;
    }
    .ga-pz-features li {
        justify-content: center;
        font-size: 0.75rem;
        padding: 8px;
    }
    .ga-pz-txt-d { display: none; }
    .ga-pz-txt-m { display: inline; }

    /* Selector de cantidad: ocultar ruleta de escritorio, mostrar control +/− táctil */
    .ga-product-zone__cantidad { display: none; }

    /* C4: etiqueta encima, control debajo, todo centrado — sin bordes ni caja */
    .ga-qty-movil-wrap {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        gap: 0.35rem;
    }
    .ga-qty-movil {
        display: flex;
        align-items: center;
        gap: 0.25rem;
    }
    .ga-qty-movil__btn {
        min-width: 44px;
        min-height: 44px;
        background: transparent;
        border: none;
        color: var(--ga-naranja-apagado);
        font-size: 2rem;
        font-weight: 400;
        cursor: pointer;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 0;
        line-height: 1;
        opacity: 0.9;
        transition: opacity 0.15s ease;
    }
    .ga-qty-movil__btn:active {
        opacity: 0.5;
    }
    .ga-qty-movil__num {
        min-width: 2.5rem;
        text-align: center;
        font-family: var(--ga-font-body);
        font-size: 1.25rem;
        font-weight: 600;
        color: var(--ga-verde-oliva-oscuro);
        padding: 0 0.25rem;
        display: flex;
        align-items: center;
        justify-content: center;
    }

    /* Garantías en una sola línea */
    .ga-product-zone__trust {
        flex-wrap: nowrap;
        gap: 0.5rem;
    }
    .ga-trust-item {
        font-size: clamp(0.65rem, 3.2vw, 0.85rem);
        white-space: nowrap;
        gap: 0.3rem;
    }
    .ga-trust-item svg {
        width: 14px;
        height: 14px;
        flex-shrink: 0;
    }
}

@media (max-width: 600px) {
    .ga-comprar-aceitunero {
        padding: 0.5rem 1rem 3rem;
    }

    .ga-comprar-aceitunero__inner {
        padding: 0; /* la sección ya aporta el lateral */
    }

    .ga-product-zone__botones {
        flex-direction: column;
    }

    .ga-product-zone__botones .ga-btn {
        min-width: 0;
    }

    .ga-product-zone__trust {
        gap: 0.5rem;
    }

    .ga-aceitunas {
        margin-top: 2.5rem;
    }

    .ga-aceituna-card {
        flex: 0 0 calc(50% - 0.75rem); /* 2 tarjetas × gap 1.5rem: (1×1.5)/2=0.75rem */
    }

    .ga-aceitunas__btn {
        width: 34px;
        height: 34px;
    }

    /* Overlay aceitunas en móvil ─────────────────────────────
       Las tarjetas 2-col miden ~112px → el contenido original
       (link 4.6rem + botón 42px) desbordaba y el nombre quedaba
       recortado en la parte superior. Se libera la altura fija,
       se oculta el precio y se recalibra el espaciado. */
    .ga-aceituna-card__precio {
        display: none;
    }
    .ga-aceituna-card__info {
        padding: 0.75rem 0.5rem;
        gap: 0.75rem;
    }
    .ga-aceituna-card__link {
        height: auto;
    }
    .ga-aceituna-card__nombre {
        height: auto;
        font-size: 0.82rem;
        line-height: 1.3;
    }
    .ga-aceituna-card__add {
        width: 38px;
        height: 38px;
        margin-top: 0;
    }

    /* C1: tarjetas más grandes — reducir padding lateral del wrapper */
    .ga-aceitunas__wrapper {
        padding: 0 1.5rem;
    }

    /* C2: nombre sin peso en móvil */
    .ga-acn-d { display: none; }
    .ga-acn-m { display: inline; }
}


/* =============================================================
   SECCIÓN — MERMELADA DESTACADA
   Fondo verde oscuro · recuadro crema en imagen · textos claros
   ============================================================= */

/* Sección: full-width, fondo verde oscuro con borde dorado perimetral */
.ga-mermelada-split {
    background-color: var(--ga-verde-oliva-oscuro);
    border: 1px solid var(--ga-naranja-apagado);
    box-sizing: border-box;
}

/* Grid contenedor */
.ga-mermelada-split__marco {
    display: grid;
    grid-template-columns: 1fr 1fr;
    min-height: 440px;
    background-color: var(--ga-verde-oliva-oscuro);
}

/* Columna imagen: fondo verde, la imagen se sienta sobre el recuadro crema */
.ga-mermelada-split__imagen {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 2rem 1.5rem;
    background-color: var(--ga-verde-oliva-oscuro);
}

/* Enlace envolvente de la imagen: transparente al layout */
.ga-mermelada-split__frame-link {
    display: contents;
}

/* Marco cuadrado: fondo crema suave (hover → dorado claro), borde dorado, esquinas redondeadas */
.ga-mermelada-split__frame {
    cursor: pointer;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 85%;
    max-width: 340px;
    aspect-ratio: 1 / 1;
    background-color: #F9F6EE;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 8px;
    overflow: hidden;
    transition: transform 0.7s ease, background-color 0.3s ease;
}

.ga-mermelada-split__frame:hover {
    background-color: #EDDCA8;
}

/* Tarro: cover + scale para que el producto llene el recuadro con presencia */
.ga-mermelada-split__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transform: scale(1.25);
    transform-origin: center;
}

.ga-mermelada-split:hover .ga-mermelada-split__frame {
    transform: scale(1.03);
}

/* Columna texto: fondo verde, textos en tonos claros */
.ga-mermelada-split__contenido {
    display: flex;
    align-items: flex-start;
    background-color: var(--ga-verde-oliva-oscuro);
    padding: var(--ga-space-sm) var(--ga-space-lg) var(--ga-space-lg);
}

.ga-mermelada-split__contenido-inner {
    max-width: 500px;
}

.ga-mermelada-split__contenido-inner .ga-section__eyebrow {
    font-size: 0.85rem;
    margin-top: 1rem;
    margin-bottom: 0.2rem;
}

.ga-mermelada-split__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(2rem, 3.5vw, 2.75rem);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-blanco);
    line-height: 1.2;
    text-wrap: balance;
    margin-bottom: var(--ga-space-xs);
    margin-top: 0;
}

.ga-mermelada-split__titulo a {
    text-decoration: none;
    color: inherit;
    cursor: pointer;
    transition: color 0.25s ease;
}

.ga-mermelada-split__titulo a:hover {
    color: var(--ga-naranja-apagado);
}

.ga-mermelada-split__desc {
    font-family: var(--ga-font-body);
    color: var(--ga-naranja-claro);
    opacity: 0.9;
    line-height: 1.85;
    margin-top: -1rem;
    margin-bottom: var(--ga-space-sm);
    max-width: 48ch;
    text-align: justify;
}

.ga-mermelada-split__contenido .ga-btn {
    display: block;
    width: fit-content;
    margin-top: 1.75rem;
    margin-left: auto;
    margin-right: auto;
}

/* Mobile: eyebrow → título → desc → foto → botón */
@media (max-width: 768px) {

    /* Convertir el grid 2-col en flex-column para poder aplicar order */
    .ga-mermelada-split__marco {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        padding: 1.25rem 1.5rem 2.5rem; /* top reducido de 2.5rem → menos hueco sobre la etiqueta */
        gap: 1.25rem;
        min-height: auto;
    }

    /* Aplanar los wrappers intermedios: sus hijos pasan a ser
       flex-items directos de __marco y admiten order.
       (Los nodos siguen en el DOM — los selectores de descendiente siguen funcionando.) */
    .ga-mermelada-split__contenido {
        display: contents;
    }
    .ga-mermelada-split__contenido-inner {
        display: contents;
    }

    /* Imagen: sin padding propio (el marco aporta el lateral), centrada */
    .ga-mermelada-split__imagen {
        padding: 0;
        display: flex;
        justify-content: center;
    }

    .ga-mermelada-split__frame {
        width: 65%;
        max-width: 240px;
    }

    /* Título y texto: mismo margen lateral — forman un bloque cuadrado alineado */
    .ga-mermelada-split__titulo,
    .ga-mermelada-split__desc {
        max-width: 100%;
        margin-top: 0;
        margin-bottom: 0;
        margin-left: 1.25rem;
        margin-right: 1.25rem;
    }

    /* Título: izquierda, grande, pegado a la etiqueta */
    .ga-mermelada-split__titulo {
        text-align: left;
        font-size: clamp(1.55rem, 6.5vw, 2rem);
        margin-top: -0.75rem; /* acerca el título a "Novedad" (gap 1.25rem + 0.2rem → ~0.7rem) */
    }

    /* Texto: justificado, separación silábica, subido al título */
    .ga-mermelada-split__desc {
        text-align: justify;
        hyphens: auto;
        -webkit-hyphens: auto;
        margin-top: -0.5rem; /* acerca el texto al título (gap base 1.25rem → queda 0.75rem) */
    }

    /* Botón: centrado, más separado de la foto */
    .ga-mermelada-split__contenido .ga-btn {
        margin-top: 0.75rem;
        align-self: center;
    }

    /* Orden deseado de arriba a abajo */
    /* Etiqueta: sin margin-top extra (cancela el 1rem de escritorio), alineada con título y texto */
    .ga-mermelada-split__contenido-inner .ga-section__eyebrow {
        order: 1;
        margin-top: 0;
        margin-left: 1.25rem;
        margin-right: 1.25rem;
    }
    .ga-mermelada-split__titulo                                { order: 2; }
    .ga-mermelada-split__desc                                  { order: 3; }
    .ga-mermelada-split__imagen                                { order: 4; }
    .ga-mermelada-split__contenido .ga-btn                     { order: 5; }
}

/* =============================================================
   SECCIÓN: APADRINA UN OLIVO
   ============================================================= */

.ga-apadrina {
    background-color: #F9F6EE;
    padding: var(--ga-space-xl) 0;
}

.ga-apadrina__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
}

/* ——— Cabecera ——— */
.ga-apadrina__header {
    text-align: center;
    max-width: 780px;
    margin: 0 auto var(--ga-space-lg);
}

.ga-apadrina__eyebrow {
    display: inline-block;
    font-family: var(--ga-font-body);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--ga-naranja-apagado);
    margin-bottom: var(--ga-space-xs);
}

.ga-apadrina__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(2.2rem, 4vw, 3.5rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.1;
    margin: 0.4rem 0 1rem;
}

.ga-apadrina__subtitulo {
    font-family: var(--ga-font-body);
    font-size: clamp(1rem, 1.5vw, 1.15rem);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.6;
    margin-bottom: 0;
}

.ga-apadrina__contexto {
    font-family: var(--ga-font-body);
    font-size: 0.9rem;
    color: var(--ga-naranja-claro);
    opacity: 0.85;
    line-height: 1.75;
    max-width: 680px;
    margin: 0 auto;
}

/* ——— Tarjetas de planes ——— */
.ga-apadrina__planes {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
    margin-bottom: var(--ga-space-lg);
}

.ga-apadrina-plan-card {
    position: relative;
    background-color: #F9F6EE;
    border: 2px solid transparent;
    border-radius: 8px;
    padding: 1.75rem 1.5rem 1.5rem;
    display: flex;
    flex-direction: column;
    transition: border-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.ga-apadrina-plan-card--bronce  { background-color: #F5EEDD; }
.ga-apadrina-plan-card--plata   { background-color: #F5EEDD; }
.ga-apadrina-plan-card--oro     { background-color: #F9F0D8; }
.ga-apadrina-plan-card--platino { background-color: #F5EEDD; }

.ga-apadrina-plan-card:hover {
    border-color: var(--ga-naranja-apagado);
    transform: translateY(-3px);
    box-shadow: 0 8px 32px rgba(74, 74, 47, 0.22);
}

.ga-apadrina-plan-card--destacada {
    border-color: var(--ga-naranja-apagado);
}

.ga-apadrina-plan-card__badge {
    position: absolute;
    top: -13px;
    left: 50%;
    transform: translateX(-50%);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    padding: 0.25rem 0.85rem;
    border-radius: 20px;
    white-space: nowrap;
}

.ga-apadrina-plan-card__titulo {
    font-family: var(--ga-font-display);
    font-size: 1.4rem;
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 0.5rem;
}

.ga-apadrina-plan-card__precio {
    font-family: var(--ga-font-body);
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--ga-verde-montanas);
    line-height: 1;
    margin-bottom: 1rem;
}

.ga-apadrina-plan-card__precio span {
    font-size: 0.85rem;
    font-weight: 400;
    color: var(--ga-verde-montanas);
}

.ga-apadrina-plan-card__duracion {
    font-family: var(--ga-font-body);
    font-size: 1rem;
    font-weight: 400;
    color: var(--ga-naranja-apagado);
    font-style: normal;
    margin-bottom: 0.3rem;
}

.ga-apadrina-plan-card__beneficios {
    list-style: none;
    padding: 0;
    margin: 0 0 1.5rem;
    flex-grow: 1;
}

.ga-apadrina-plan-card__beneficios li {
    font-family: var(--ga-font-body);
    font-size: 0.84rem;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.5;
    padding: 0.4rem 0 0.4rem 1.4rem;
    border-bottom: 1px solid rgba(74, 74, 47, 0.08);
    position: relative;
}

.ga-apadrina-plan-card__beneficios li::before {
    content: '✓';
    position: absolute;
    left: 0;
    color: var(--ga-naranja-apagado);
    font-weight: 700;
    font-size: 0.8rem;
}

.ga-apadrina__btn-plan {
    display: block;
    text-align: center;
    padding: 0.85rem 1.25rem;
    background-color: var(--ga-verde-oliva-oscuro);
    color: #F9F6EE;
    border: 2px solid var(--ga-verde-oliva-oscuro);
    border-radius: 2px;
    font-family: var(--ga-font-body);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    text-decoration: none;
    cursor: pointer;
    transition: var(--transition);
    margin-top: auto;
}

.ga-apadrina__btn-plan:hover {
    background-color: transparent;
    color: var(--ga-verde-oliva-oscuro);
    transform: translateY(-2px);
}

.ga-apadrina__btn-plan--destacado {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
}

.ga-apadrina__btn-plan--destacado:hover {
    background-color: transparent;
    color: var(--ga-naranja-apagado);
}

/* Puntos del carrusel de planes — ocultos en escritorio */
.ga-planes__dots {
    display: none;
}

/* ——— Mapa de olivos ——— */
.ga-apadrina__mapa-seccion {
    margin-bottom: var(--ga-space-lg);
    text-align: center;
    overflow-x: hidden;
}

.ga-apadrina__mapa-titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 2.5vw, 2rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    margin-bottom: 0.4rem;
}

.ga-apadrina__mapa-subtitulo {
    font-family: var(--ga-font-body);
    font-size: 0.9rem;
    color: var(--ga-verde-montanas);
    margin-bottom: 1.5rem;
}

.ga-apadrina__mapa-wrap {
    overflow: visible;
}

.ga-apadrina__mapa-contenedor {
    position: relative;
    display: inline-flex;
    align-items: flex-start;
    background-color: #f1e8df;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 8px;
    padding: 1.5rem 1.25rem;
    min-width: max-content;
}

.ga-apadrina__zona--izquierda {
    position: relative;
    display: grid;
    grid-template-columns: repeat(11, 38px);
    gap: 13px;
}

.ga-apadrina__caballon {
    position: relative;
    width: 12px;
    margin: 0 15px;
    align-self: stretch;
    background: linear-gradient(to bottom, #7fc4e8, #5aa8d6);
    border: 2px solid #8B6914;
    border-radius: 6px;
    overflow: hidden;
}

.ga-apadrina__caballon::after {
    content: '';
    position: absolute;
    top: 0;
    bottom: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 3px;
    background: rgba(200, 235, 255, 0.6);
    animation: gaAcequiaGlimmer 2s ease-in-out infinite;
}

@keyframes gaAcequiaGlimmer {
    0%, 100% { opacity: 0.3; }
    50%       { opacity: 0.6; }
}

.ga-apadrina__zona--derecha {
    position: relative;
    display: grid;
    grid-template-columns: repeat(9, 38px);
    column-gap: 19px;
    row-gap: 0;
    align-content: space-between;
    height: 293px; /* 6×38 + 5×13 — iguala altura de zona izquierda */
}

/* Olivo individual */
.ga-apadrina__olivo {
    position: relative;
    z-index: 1;
    width: 38px;
    height: 38px;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    color: #7f8649;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease, transform 0.15s ease;
}

.ga-apadrina__olivo:hover {
    color: #5a6030;
    transform: scale(1.25);
    z-index: 5;
}

.ga-apadrina__olivo--ocupado {
    color: #aaaaaa;
    cursor: default;
}

.ga-apadrina__olivo--ocupado:hover {
    color: #aaaaaa;
    transform: none;
}

.ga-apadrina__olivo svg {
    width: 100%;
    height: 100%;
    display: block;
}

/* Placeholder para el hueco del caballón */
.ga-apadrina__olivo-placeholder {
    width: 38px;
    height: 38px;
}

/* ——— Gota de agua interactiva ——— */
.ga-apadrina__gota {
    position: relative;
    z-index: 1;
    width: 38px;
    height: 38px;
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ga-apadrina__gota svg {
    width: 30px;
    height: 38px;
    display: block;
    animation: gaGotaPulso 1.5s ease-in-out infinite;
    filter: drop-shadow(0 2px 5px rgba(90, 168, 214, 0.55));
}

@keyframes gaGotaPulso {
    0%, 100% { transform: scale(1); }
    50%       { transform: scale(1.25); }
}

.ga-apadrina__gota:hover,
.ga-apadrina__gota:focus,
.ga-apadrina__gota:focus-visible,
.ga-apadrina__gota:active {
    background: transparent !important;
    background-color: transparent !important;
    border-color: transparent !important;
    box-shadow: none !important;
    color: inherit !important;
    outline: none;
}

.ga-apadrina__gota:hover svg {
    animation-play-state: paused;
}

.ga-apadrina__gota-tooltip {
    position: absolute;
    bottom: calc(100% + 7px);
    left: 50%;
    transform: translateX(-50%);
    background: #5aa8d6;
    color: var(--ga-blanco);
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 500;
    white-space: nowrap;
    padding: 4px 9px;
    border-radius: 3px;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.2s ease;
    z-index: 10;
}

.ga-apadrina__gota:hover .ga-apadrina__gota-tooltip {
    opacity: 1;
}

.ga-apadrina__gota-tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 4px solid transparent;
    border-top-color: #5aa8d6;
}

/* Tooltip */
.ga-apadrina__tooltip {
    display: none;
    position: absolute;
    bottom: calc(100% + 7px);
    left: 50%;
    transform: translateX(-50%);
    background-color: var(--ga-verde-oliva-oscuro);
    color: #F9F6EE;
    font-family: var(--ga-font-body);
    font-size: 0.7rem;
    white-space: nowrap;
    padding: 0.3rem 0.65rem;
    border-radius: 4px;
    pointer-events: none;
    z-index: 999;
}

.ga-apadrina__tooltip::after {
    content: '';
    position: absolute;
    top: 100%;
    left: 50%;
    transform: translateX(-50%);
    border: 4px solid transparent;
    border-top-color: var(--ga-verde-oliva-oscuro);
}

.ga-apadrina__olivo:hover .ga-apadrina__tooltip {
    display: block;
}

/* Tooltip debajo — filas 1, 2 y 3 de cualquier zona */
.ga-apadrina__tooltip.ga-tooltip-abajo {
    bottom: auto;
    top: calc(100% + 7px);
}

.ga-apadrina__tooltip.ga-tooltip-abajo::after {
    top: auto;
    bottom: 100%;
    border-top-color: transparent;
    border-bottom-color: var(--ga-verde-oliva-oscuro);
}

/* Tooltip borde derecho — 2 últimas columnas zona derecha */
.ga-apadrina__tooltip.ga-tooltip-izq {
    left: auto;
    right: 0;
    transform: none;
}

.ga-apadrina__tooltip.ga-tooltip-izq::after {
    left: auto;
    right: 10px;
    transform: none;
}

/* Tooltip borde izquierdo — 2 primeras columnas zona izquierda */
.ga-apadrina__tooltip.ga-tooltip-der {
    left: 0;
    transform: none;
}

.ga-apadrina__tooltip.ga-tooltip-der::after {
    left: 10px;
    transform: none;
}

/* Modal */
.ga-apadrina__modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}

.ga-apadrina__modal--visible {
    opacity: 1;
    pointer-events: all;
}

.ga-apadrina__modal-backdrop {
    position: absolute;
    inset: 0;
    background-color: rgba(26, 26, 20, 0.78);
    cursor: pointer;
}

.ga-apadrina__modal-box {
    position: relative;
    z-index: 1;
    background-color: #F9F6EE;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 8px;
    padding: 2.5rem 2rem 2rem;
    max-width: 360px;
    width: 90%;
    text-align: center;
}

.ga-apadrina__modal-cerrar {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--ga-verde-oliva-oscuro);
    padding: 4px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: color 0.2s ease;
}

.ga-apadrina__modal-cerrar:hover {
    color: var(--ga-naranja-apagado);
}

.ga-apadrina__modal-titulo {
    font-family: var(--ga-font-display);
    font-size: 1.5rem;
    color: var(--ga-verde-oliva-oscuro);
    margin-bottom: 1.5rem;
    line-height: 1.3;
}

/* ——— Bloque de texto bajo el mapa ——— */
.ga-apadrina__texto-bloque {
    max-width: 900px;
    margin: 0 auto var(--ga-space-lg);
    text-align: center;
}

.ga-apadrina__texto-principal {
    font-family: var(--ga-font-display);
    font-size: clamp(1.4rem, 2.5vw, 2.2rem);
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.35;
    text-align: center;
    max-width: 1120px;
    margin: 0 auto 1.5rem;
}

.ga-apadrina__texto-parrafo {
    font-family: var(--ga-font-body);
    font-size: 0.95rem;
    color: var(--ga-verde-montanas);
    line-height: 1.8;
    max-width: 856px;
    padding: 0 1.25rem;
    margin: 0 auto;
    text-align: justify;
}

.ga-apadrina__texto-transicion {
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 3vw, 2.2rem);
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    text-align: center;
    margin-top: 1.25rem;
    margin-bottom: 0;
}


.ga-apadrina__btn-cta {
    display: inline-block;
    padding: 0.9rem 2.5rem;
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 2px;
    font-family: var(--ga-font-body);
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    text-decoration: none;
    transition: var(--transition);
}

.ga-apadrina__btn-cta:hover {
    background-color: transparent;
    color: var(--ga-naranja-apagado);
    transform: translateY(-2px);
    box-shadow: var(--shadow-suave);
}

/* ——— Acordeón FAQ ——— */
.ga-apadrina-acordeon {
    width: 100%;
    margin-bottom: 1rem;
    border-radius: 4px;
    overflow: hidden;
}

.ga-apadrina-acordeon__item {
    border-bottom: 1px solid var(--ga-naranja-apagado);
}

.ga-apadrina-acordeon__item:last-child {
    border-bottom: none;
}

.ga-apadrina-acordeon__btn {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
    background: #F9F6EE;
    border: none;
    cursor: pointer;
    text-align: left;
    font-family: var(--ga-font-body);
    font-size: 0.78rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-verde-oliva-oscuro);
}

.ga-apadrina-acordeon__btn:hover,
.ga-apadrina-acordeon__btn:focus,
.ga-apadrina-acordeon__btn:focus-visible {
    background: #F9F6EE;
    color: var(--ga-verde-oliva-oscuro);
    outline: none;
}

.ga-apadrina-acordeon__chevron {
    flex-shrink: 0;
    color: var(--ga-naranja-apagado);
    transition: transform 0.3s ease;
}

.ga-apadrina-acordeon__btn[aria-expanded="true"] {
    background: #F9F6EE;
    color: var(--ga-naranja-apagado);
}

.ga-apadrina-acordeon__btn[aria-expanded="true"]:hover,
.ga-apadrina-acordeon__btn[aria-expanded="true"]:focus {
    background: #F9F6EE;
    color: var(--ga-naranja-apagado);
}

.ga-apadrina-acordeon__btn[aria-expanded="true"] .ga-apadrina-acordeon__chevron {
    transform: rotate(180deg);
}

.ga-apadrina-acordeon__panel {
    height: 0;
    overflow: hidden;
    background: #F9F6EE;
    transition: height 0.35s ease;
}

.ga-apadrina-acordeon__panel p {
    padding: 0 1.5rem 0.75rem;
    font-family: var(--ga-font-body);
    font-size: 0.95rem;
    line-height: 1.75;
    color: var(--ga-verde-oliva-oscuro);
}


/* Indicador y barra de scroll del mapa — ocultos en escritorio */
.ga-mapa-hint,
.ga-mapa-scrollbar {
    display: none;
}

/* ——— Responsive ——— */
@media (max-width: 1024px) {
    .ga-apadrina__planes {
        grid-template-columns: repeat(2, 1fr);
    }
}

/* ——— Mapa de olivos: scroll horizontal en móvil ——— */
@media (max-width: 768px) {

    /* Permitir que el mapa no quede recortado (body de Astra blinda el scroll del documento) */
    .ga-apadrina__mapa-seccion {
        overflow-x: visible;
    }

    /* Contenedor del scroll: ancho completo, fluido, sin scrollbar visible */
    .ga-apadrina__mapa-wrap {
        width: 100%;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        text-align: left; /* evita que inline-flex mapa-contenedor quede centrado; scrollLeft funciona desde 0 */
    }
    .ga-apadrina__mapa-wrap::-webkit-scrollbar {
        display: none;
    }

    /* Barra de desplazamiento personalizada */
    .ga-mapa-scrollbar {
        display: block;
        padding: 0.75rem 5% 0;
    }

    .ga-mapa-scrollbar__track {
        position: relative;
        width: 100%;
        height: 6px;
        background: rgba(74, 74, 47, 0.12);
        border-radius: 3px;
        cursor: pointer;
    }

    .ga-mapa-scrollbar__thumb {
        position: absolute;
        top: 0;
        left: 0;
        height: 100%;
        background: var(--ga-naranja-apagado);
        border-radius: 3px;
        cursor: grab;
        touch-action: none;
        user-select: none;
        -webkit-user-select: none;
        transition: background 0.15s ease;
    }

    .ga-mapa-scrollbar__thumb:active {
        cursor: grabbing;
    }
}

/* ——— Carrusel de planes en móvil ——— */
@media (max-width: 768px) {

    /* Reducir espacio crema al final de la sección en móvil */
    .ga-apadrina {
        padding-bottom: 0.75rem;
    }

    /* Wrapper: rompe el padding del inner para dar al track anchura de viewport */
    .ga-apadrina__planes-wrap {
        margin-left: calc(-1 * var(--ga-space-md));
        margin-right: calc(-1 * var(--ga-space-md));
        margin-bottom: 0; /* anula los 2.5rem de escritorio — los dots tienen su propio margin-top */
    }

    /* Track: pista horizontal con scroll-snap (igual que ga-pasos del proceso) */
    .ga-apadrina__planes {
        display: flex !important;
        flex-direction: row;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        gap: 1.5rem;
        padding: 0.75rem 16vw 1.25rem; /* 16vw: centra la tarjeta al 68vw en cualquier móvil */
        margin-bottom: 0;
    }

    .ga-apadrina__planes::-webkit-scrollbar {
        display: none;
    }

    /* Slide: 68vw fijo con flex explícito — no depende de flex-basis:auto */
    .ga-apadrina-plan-card {
        flex: 0 0 68vw;    /* flex-basis explícito a 68vw, no crece ni encoge */
        max-width: 68vw;   /* impide que el contenido expanda la tarjeta */
        min-width: 0;      /* anula cualquier min-width heredado */
        scroll-snap-align: center;
        scroll-snap-stop: always;
    }

    /* Cancelar hover de escritorio (sin hover real en touch) */
    .ga-apadrina-plan-card:hover {
        transform: none;
        box-shadow: none;
    }

    /* Puntos indicadores */
    .ga-planes__dots {
        display: flex;
        justify-content: center;
        gap: 0.5rem;
        margin-top: 0.75rem;
        margin-bottom: 0;
        padding: 0;
        border: none;
        background: none;
    }

    .ga-planes__dot {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: rgba(74, 74, 47, 0.2);
        border: none;
        padding: 0;
        cursor: pointer;
        transition: background 0.25s ease, transform 0.25s ease;
    }

    .ga-planes__dot.is-active {
        background: var(--ga-naranja-apagado);
        transform: scale(1.5);
    }
}

@media (max-width: 600px) {
    .ga-apadrina__planes {
        grid-template-columns: repeat(2, 1fr); /* irrelevante en flex; se mantiene por compatibilidad */
        gap: 1.5rem; /* mantiene el mismo gap que el bloque 768px */
    }

    .ga-apadrina-plan-card {
        padding: 1.25rem 1rem 1rem;
    }

    .ga-apadrina__zona--izquierda {
        grid-template-columns: repeat(11, 30px);
        gap: 10px;
    }

    .ga-apadrina__zona--derecha {
        grid-template-columns: repeat(9, 30px);
        column-gap: 13px;
        height: 230px; /* 6×30 + 5×10 — iguala altura de zona izquierda */
    }

    .ga-apadrina__olivo,
    .ga-apadrina__olivo-placeholder {
        width: 30px;
        height: 30px;
    }
}


/* =============================================================
   BOTELLA PREMIUM — ga-botella-premium
   Presentación del producto estrella: vídeo + texto sobre negro.
   Mobile-first: vídeo arriba, texto abajo.
   ============================================================= */

.ga-botella-premium {
    background-color: #000000;
    padding: 4rem 0 2.5rem;
    border-top: 2px solid #c7a862;
    border-bottom: 2px solid #c7a862;
    overflow: hidden;
}

.ga-botella-premium__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 2rem;
    display: flex;
    flex-direction: column;
    gap: 2.5rem;
    align-items: center;
}

.ga-botella-premium__video-link {
    display: block;
    cursor: pointer;
    text-decoration: none;
}

/* — Columna vídeo — */
.ga-botella-premium__video-col {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.ga-botella-premium__video {
    width: auto;
    max-width: 100%;
    max-height: 420px;
    height: auto;
    display: block;
    border-radius: 0;
}

/* — Columna texto — */
.ga-botella-premium__texto-col {
    width: 100%;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 1.25rem;
}

.ga-botella-premium__eyebrow {
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.2em;
    color: #c7a862;
    display: block;
}

.ga-botella-premium__titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(2rem, 5vw, 3.2rem);
    font-weight: 600;
    line-height: 1.1;
    color: #c7a862;
    margin: 0;
}

.ga-botella-premium__titulo-link {
    color: #c7a862;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.25s ease;
}

.ga-botella-premium__titulo-link:hover {
    color: #ffffff;
}

.ga-botella-premium__specs-link {
    color: #c7a862;
    text-decoration: none;
    cursor: pointer;
    transition: color 0.25s ease;
}

.ga-botella-premium__specs-link:hover {
    color: #ffffff;
}

.ga-botella-premium__parrafo {
    font-family: 'Inter', sans-serif;
    font-size: clamp(0.9rem, 1.5vw, 1rem);
    line-height: 1.8;
    color: #F9F6EE;
    margin: 0;
    margin-top: -1.75rem; /* acerca el párrafo al título */
    max-width: 520px;
}

.ga-botella-premium__specs {
    font-family: 'Inter', sans-serif;
    font-size: 0.78rem;
    font-weight: 600;
    color: #c7a862;
    opacity: 1;
    letter-spacing: 0.05em;
    margin: 0;
    border-top: 1px solid rgba(199, 168, 98, 0.3);
    padding-top: 1rem;
    width: 100%;
    max-width: 520px;
}

.ga-botella-premium__cta {
    display: inline-block;
    padding: 0.875rem 2.25rem;
    background-color: transparent;
    color: #c7a862;
    border: 2px solid #c7a862;
    font-family: 'Inter', sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    text-decoration: none;
    border-radius: 2px;
    transition: background-color 0.25s ease, color 0.25s ease, transform 0.2s ease;
    margin-top: 0.5rem;
}

.ga-botella-premium__cta:hover {
    background-color: #c7a862;
    color: #ffffff;
    transform: translateY(-2px);
}

.ga-botella-premium__cta:active {
    transform: translateY(0);
}

/* — Escritorio: dos columnas al 50% — */
@media (min-width: 900px) {
    .ga-botella-premium {
        padding: 4rem 0 2.5rem;
    }

    .ga-botella-premium__inner {
        flex-direction: row;
        gap: 5rem;
        align-items: center;
    }

    .ga-botella-premium__video-col {
        flex: 1 1 50%;
        align-self: flex-start;
    }

    .ga-botella-premium__texto-col {
        flex: 1 1 50%;
        align-self: flex-start;
    }

    .ga-botella-premium__video {
        width: auto;
        max-width: 100%;
        height: auto;
        max-height: 460px;
        transform: translateY(-0.75rem);
    }
}

/* — Botella premium: versión móvil — */
@media (max-width: 768px) {

    /* Recortar padding superior e inferior — vídeo pegado al borde dorado */
    .ga-botella-premium {
        padding-top: 1rem;
        padding-bottom: 1.5rem;
    }

    /* Cambio 3: reducir hueco entre vídeo y bloque de texto */
    .ga-botella-premium__inner {
        gap: 0.75rem;
    }

    /* Cambio 3: centrar todo el bloque de texto */
    .ga-botella-premium__texto-col {
        align-items: center;
        text-align: center;
        gap: 0.9rem;
    }

    /* Cambio 2: ocultar párrafo descriptivo */
    .ga-botella-premium__parrafo {
        display: none;
    }

    /* Cambio 2: ocultar línea de especificaciones */
    .ga-botella-premium__specs {
        display: none;
    }
}


/* =============================================================
   OPINIONES — ga-opiniones
   Mosaico animado 3x2. Altura fija. Pausa en hover.
   Diseno premium: degradado crema, comilla decorativa,
   destello en estrellas, hover elevado, etiqueta pildora.
   ============================================================= */

.ga-opiniones {
    background-color: #ffffff;
    padding: 0 0 8rem;
}

.ga-opiniones__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 2rem;
}

.ga-opiniones__header {
    text-align: center;
    margin-bottom: 3rem;
}

.ga-opiniones__titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(1.8rem, 4vw, 2.8rem);
    font-weight: 600;
    color: #4a4a2f;
    margin: 0;
    line-height: 1.15;
}

.ga-opiniones__grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-auto-rows: 250px;
    gap: 1.5rem;
}

.ga-opiniones__slot {
    position: relative;
    height: 250px;
    overflow: hidden;
    transition: transform 0.3s ease;
}

.ga-opiniones__slot:hover {
    overflow: visible;
    transform: translateY(-4px);
    z-index: 2;
}

.ga-opiniones__slot-inner {
    height: 100%;
    display: flex;
    flex-direction: column;
    opacity: 1;
    transform: translateY(0);
    filter: blur(0px);
    transition: opacity 0.6s ease-in-out, transform 0.6s ease-in-out, filter 0.6s ease-in-out;
}

.ga-opiniones__slot-inner--exiting {
    opacity: 0;
    transform: translateY(-18px);
    filter: blur(2px);
}

.ga-opiniones__card {
    position: relative;
    height: 100%;
    box-sizing: border-box;
    background-color: #F9F6EE;
    border: 1px solid rgba(199, 168, 98, 0.15);
    border-radius: 12px;
    padding: 1.75rem 2rem;
    box-shadow: 0 2px 14px rgba(74, 74, 47, 0.07);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.35rem;
    overflow: hidden;
    transition: box-shadow 0.3s ease;
}

.ga-opiniones__slot:hover .ga-opiniones__card {
    box-shadow: 0 12px 36px rgba(74, 74, 47, 0.16), inset 0 3px 0 #c7a862;
}

.ga-opiniones__card::before {
    content: '\201C';
    position: absolute;
    bottom: -2rem;
    right: 1rem;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 6rem;
    font-weight: 700;
    line-height: 1;
    color: rgba(199, 168, 98, 0.10);
    pointer-events: none;
    user-select: none;
    z-index: 0;
}

.ga-opiniones__estrellas,
.ga-opiniones__cabecera,
.ga-opiniones__nombre,
.ga-opiniones__etiqueta,
.ga-opiniones__texto {
    position: relative;
    z-index: 1;
}

.ga-opiniones__estrellas {
    display: inline-block;
    font-size: 1.55rem;
    letter-spacing: 0.10em;
    line-height: 1;
    color: #c7a862;
    flex-shrink: 0;
    background: linear-gradient(
        90deg,
        #c7a862 0%,
        #c7a862 45%,
        #f0d97a 50%,
        #fffce0 54%,
        #f0d97a 58%,
        #c7a862 64%,
        #c7a862 100%
    );
    background-size: 400% 100%;
    background-position: 32% 0;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    animation: ga-estrella-brillo 5s ease-in-out infinite;
}

.ga-opiniones__slot:nth-child(1) .ga-opiniones__estrellas { animation-delay: 0s; }
.ga-opiniones__slot:nth-child(2) .ga-opiniones__estrellas { animation-delay: 0.75s; }
.ga-opiniones__slot:nth-child(3) .ga-opiniones__estrellas { animation-delay: 1.5s; }
.ga-opiniones__slot:nth-child(4) .ga-opiniones__estrellas { animation-delay: 2.25s; }
.ga-opiniones__slot:nth-child(5) .ga-opiniones__estrellas { animation-delay: 3s; }
.ga-opiniones__slot:nth-child(6) .ga-opiniones__estrellas { animation-delay: 3.75s; }

@keyframes ga-estrella-brillo {
    0%   { background-position: 76% 0; }
    22%  { background-position: 32% 0; }
    100% { background-position: 32% 0; }
}

.ga-opiniones__cabecera {
    margin-top: 0.5rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-wrap: wrap;
    flex-shrink: 0;
}

.ga-opiniones__nombre {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.3rem;
    font-weight: 600;
    color: #4a4a2f;
    line-height: 1.2;
    flex-shrink: 0;
}

.ga-opiniones__etiqueta {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-family: 'Inter', sans-serif;
    font-size: 0.65rem;
    font-weight: 500;
    letter-spacing: 0.03em;
    padding: 0.2rem 0.6rem;
    border-radius: 999px;
    border: 1px solid;
    flex-shrink: 0;
}

.ga-opiniones__etiqueta svg {
    width: 0.7rem;
    height: 0.7rem;
    flex-shrink: 0;
}

.ga-opiniones__etiqueta--online {
    color: #c7a862;
    background: rgba(199, 168, 98, 0.10);
    border-color: rgba(199, 168, 98, 0.28);
}

.ga-opiniones__etiqueta--tienda {
    color: #7f8649;
    background: rgba(127, 134, 73, 0.10);
    border-color: rgba(127, 134, 73, 0.28);
}

.ga-opiniones__texto {
    font-family: 'Inter', sans-serif;
    font-size: 1rem;
    line-height: 1.68;
    color: #4a4a2f;
    margin-top: 0.5rem;
    opacity: 0.85;
    flex: 1;
    min-width: 0;
}


@media (min-width: 600px) and (max-width: 899px) {
    .ga-opiniones__grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (max-width: 599px) {
    .ga-opiniones {
        padding: 1.5rem 0 5rem;
    }
    .ga-opiniones__inner {
        padding: 0 0.75rem;
    }
    /* CAMBIO 5 — Título más pegado al mosaico en móvil */
    .ga-opiniones__header {
        margin-bottom: 1.25rem;
    }
    .ga-opiniones__grid {
        grid-template-columns: repeat(2, 1fr);
        grid-auto-rows: 220px;
        gap: 0.75rem;
    }
    /* Ocultar slots 5 y 6 — rejilla 2×2 con 4 slots activos */
    .ga-opiniones__slot:nth-child(n+5) {
        display: none;
    }
    /* Altura del slot ajustada al formato 2 columnas */
    .ga-opiniones__slot {
        height: 220px;
    }
    /* Interior de la tarjeta — padding compacto, contenido alineado a la izquierda */
    .ga-opiniones__card {
        padding: 1rem 0.9rem 0.75rem;
        gap: 0.25rem;
        align-items: flex-start;
        text-align: left;
    }
    .ga-opiniones__estrellas {
        font-size: 1.05rem;
        letter-spacing: 0.05em;
    }
    .ga-opiniones__cabecera {
        margin-top: 0.25rem;
        flex-direction: column;
        align-items: flex-start;
        gap: 0.25rem;
    }
    .ga-opiniones__nombre {
        font-size: 0.95rem;
    }
    .ga-opiniones__etiqueta {
        font-size: 0.58rem;
        padding: 0.15rem 0.4rem;
    }
    .ga-opiniones__texto {
        font-size: 0.81rem;
        line-height: 1.55;
        margin-top: 0.2rem;
        width: 100%;
    }
    /* CAMBIO 2 — Slot hover en móvil: sin crecimiento ni desbordamiento */
    .ga-opiniones__slot:hover {
        overflow: hidden;
        transform: none;
    }

    /* Tarjeta CTA — padding reducido para ganar ancho útil, título con presencia */
    .ga-opiniones__cta {
        padding: 0.85rem 0.6rem;
    }
    .ga-opiniones__cta-content {
        gap: 0.6rem;
    }
    .ga-opiniones__cta .ga-opiniones__cta-titulo {
        width: 100%;
        font-size: 1.1rem;
        line-height: 1.25;
    }
    .ga-opiniones__cta-sub {
        display: none;
    }
    .ga-opiniones__cta-btn {
        font-size: 0.55rem;
        padding: 0.38rem 0.7rem;
        letter-spacing: 0.08em;
        transform: none;
    }
    .ga-opiniones__cta-btn:hover {
        transform: none;
        box-shadow: none;
    }
}


/* --- Tarjeta CTA en el mosaico de opiniones --- */

.ga-opiniones__cta {
    position: relative;
    height: 100%;
    box-sizing: border-box;
    background: radial-gradient(ellipse at center, #5c5e3c 0%, #4a4a2f 100%);
    border-top: 3px solid transparent;
    border-radius: 12px;
    padding: 1.75rem 2rem;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    overflow: hidden;
    box-shadow: 0 2px 14px rgba(26, 26, 20, 0.22);
    transition: box-shadow 0.3s ease, border-top-color 0.3s ease;
}

.ga-opiniones__slot:hover .ga-opiniones__cta {
    border-top-color: #c7a862;
    box-shadow: 0 12px 36px rgba(26, 26, 20, 0.45);
}

.ga-opiniones__cta-content {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.85rem;
    width: 100%;
}

.ga-opiniones__cta-titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.35rem;
    font-weight: 600;
    color: #c7a862;
    line-height: 1.2;
    margin: 0;
}

.ga-opiniones__cta-sub {
    font-family: 'Inter', sans-serif;
    font-size: 0.85rem;
    color: #F9F6EE;
    opacity: 0.85;
    line-height: 1.55;
    margin: 0;
}

.ga-opiniones__cta-btn {
    display: inline-block;
    padding: 0.65rem 1.5rem;
    background: transparent;
    color: #c7a862;
    border: 2px solid #c7a862;
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    text-decoration: none;
    border-radius: 3px;
    transition: background 0.3s ease, color 0.3s ease, transform 0.3s ease, box-shadow 0.3s ease;
}

.ga-opiniones__cta-btn:hover {
    background: #c7a862;
    color: #3a3a22;
    transform: translateY(-2px);
    box-shadow: 0 4px 14px rgba(199, 168, 98, 0.3);
}


/* =============================================================
   FORMULARIO VALORACIÓN — ga-opinion-form-
   Pagina /deja-tu-opinion/ con fondo crema.
   ============================================================= */

.ga-main--opinion {
    background-color: #F9F6EE;
    min-height: 70vh;
}

.ga-opinion-form-seccion {
    padding: 5rem 0 8rem;
}

.ga-opinion-form-inner {
    max-width: 620px;
    margin: 0 auto;
    padding: 0 2rem;
}

.ga-opinion-form-header {
    text-align: center;
    margin-bottom: 3rem;
}

.ga-opinion-form-titulo-wrap {
    display: block;
}

.ga-opinion-form-titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(2.4rem, 12vw, 5.2rem);
    font-weight: 600;
    color: #4a4a2f;
    line-height: 1.05;
    margin: 0 0 0.6rem;
}

.ga-opinion-form-divider {
    width: 100%;
    height: 2px;
    background: rgba(199, 168, 98, 0.5);
    border: none;
    margin: 1.5rem 0 1.25rem;
}

.ga-opinion-form-subtitulo {
    font-family: 'Inter', sans-serif;
    font-size: 1rem;
    color: #c7a862;
    opacity: 1;
    line-height: 1.6;
    margin: 0 auto;
    max-width: 440px;
}

/* Avisos de resultado */

.ga-opinion-form-aviso {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    padding: 1.1rem 1.4rem;
    border-radius: 8px;
    font-family: 'Inter', sans-serif;
    font-size: 0.9rem;
    line-height: 1.55;
    margin-bottom: 2rem;
}

.ga-opinion-form-aviso--ok {
    background: rgba(127, 134, 73, 0.10);
    color: #4a4a2f;
    border: 1px solid rgba(127, 134, 73, 0.30);
}

.ga-opinion-form-aviso--ok svg {
    color: #7f8649;
    flex-shrink: 0;
    margin-top: 1px;
}

.ga-opinion-form-aviso--error {
    background: rgba(199, 168, 98, 0.10);
    color: #4a4a2f;
    border: 1px solid rgba(199, 168, 98, 0.30);
}

/* Campos */

.ga-opinion-form {
    display: flex;
    flex-direction: column;
    gap: 1.6rem;
}

.ga-opinion-form-campo {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.ga-opinion-form-label {
    font-family: 'Inter', sans-serif;
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.10em;
    color: #4a4a2f;
}

.ga-opinion-form-req {
    color: #c7a862;
    font-weight: 700;
}

.ga-opinion-form-op {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    opacity: 0.6;
    font-size: 0.7rem;
}

.ga-opinion-form-nota {
    font-family: 'Inter', sans-serif;
    font-size: 0.7rem;
    color: #4a4a2f;
    opacity: 0.5;
    line-height: 1.5;
    margin: 0;
}

/* Checkbox de consentimiento */

.ga-opinion-form-campo--consentimiento {
    gap: 0;
}

.ga-opinion-form-consentimiento-label {
    position: relative;
    display: flex;
    align-items: flex-start;
    gap: 0.65rem;
    cursor: pointer;
}

.ga-opinion-form-checkbox {
    position: absolute;
    left: 0;
    top: 2px;
    width: 18px;
    height: 18px;
    opacity: 0;
    cursor: pointer;
    margin: 0;
    z-index: 1;
}

.ga-opinion-form-checkbox-box {
    flex-shrink: 0;
    width: 18px;
    height: 18px;
    border: 1.5px solid rgba(74, 74, 47, 0.35);
    border-radius: 3px;
    background: #ffffff;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-top: 2px;
    transition: border-color 0.2s ease, background 0.2s ease;
    pointer-events: none;
}

.ga-opinion-form-checkbox-box svg {
    display: none;
}

.ga-opinion-form-checkbox:checked + .ga-opinion-form-checkbox-box {
    background: #c7a862;
    border-color: #c7a862;
}

.ga-opinion-form-checkbox:checked + .ga-opinion-form-checkbox-box svg {
    display: block;
}

.ga-opinion-form-checkbox:focus-visible + .ga-opinion-form-checkbox-box {
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.25);
    outline: none;
}

.ga-opinion-form-campo--consentimiento.ga-opinion-form-campo--error .ga-opinion-form-checkbox-box {
    border-color: rgba(199, 168, 98, 0.7);
}

.ga-opinion-form-consentimiento-texto {
    font-family: 'Inter', sans-serif;
    font-size: 0.8rem;
    color: #4a4a2f;
    line-height: 1.55;
    opacity: 0.8;
}

.ga-opinion-form-consentimiento-texto a {
    color: #c7a862;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ga-opinion-form-consentimiento-texto a:hover {
    color: #b89452;
}

.ga-opinion-form-input,
.ga-opinion-form-select,
.ga-opinion-form-textarea {
    font-family: 'Inter', sans-serif;
    font-size: 0.95rem;
    color: #1a1a14;
    background: #ffffff;
    border: 1px solid rgba(74, 74, 47, 0.22);
    border-radius: 4px;
    padding: 0.8rem 1rem;
    width: 100%;
    box-sizing: border-box;
    transition: border-color 0.2s ease, box-shadow 0.2s ease;
    appearance: none;
    -webkit-appearance: none;
}

.ga-opinion-form-input:focus,
.ga-opinion-form-select:focus,
.ga-opinion-form-textarea:focus {
    outline: none;
    border-color: #c7a862;
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.16);
}

.ga-opinion-form-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%234a4a2f' stroke-width='2.5'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    padding-right: 2.5rem;
    cursor: pointer;
    /* El select nativo abre hacia arriba o abajo según el espacio del viewport;
       overflow: visible garantiza que ningún ancestro lo recorte. */
    overflow: visible;
    position: static;
}

.ga-opinion-form-textarea {
    resize: vertical;
    min-height: 110px;
    line-height: 1.6;
}

.ga-opinion-form-campo--error .ga-opinion-form-input,
.ga-opinion-form-campo--error .ga-opinion-form-select,
.ga-opinion-form-campo--error .ga-opinion-form-textarea {
    border-color: rgba(199, 168, 98, 0.7);
}

/* Selector de estrellas clickable */

.ga-opinion-form-estrellas {
    display: flex;
    gap: 0.15rem;
    margin-top: 0.1rem;
}

.ga-opinion-form-estrella {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 2.2rem;
    line-height: 1;
    color: rgba(199, 168, 98, 0.28);
    padding: 0 0.05rem;
    transition: color 0.12s ease, transform 0.12s ease;
    outline: none;
    box-shadow: none;
    -webkit-appearance: none;
    appearance: none;
}

.ga-opinion-form-estrella.activa,
.ga-opinion-form-estrella.hover {
    color: #c7a862;
}

.ga-opinion-form-estrella:hover,
.ga-opinion-form-estrella:focus,
.ga-opinion-form-estrella:focus-visible,
.ga-opinion-form-estrella:active {
    transform: scale(1.2);
    outline: none;
    background: none;
    box-shadow: none;
    border: none;
}

/* Boton de envio */

.ga-opinion-form-campo--submit {
    margin-top: 0.5rem;
}

.ga-opinion-form-btn {
    display: inline-block;
    padding: 1rem 2.8rem;
    background: #c7a862;
    color: #ffffff;
    font-family: 'Inter', sans-serif;
    font-size: 0.78rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    border: none;
    border-radius: 2px;
    cursor: pointer;
    transition: background 0.25s ease, transform 0.25s ease;
}

.ga-opinion-form-btn:hover {
    background: #d4b872;
    transform: translateY(-2px);
}

@media (max-width: 599px) {
    .ga-opinion-form-seccion {
        padding: 3rem 0 5rem;
    }
    .ga-opinion-form-inner {
        padding: 0 1rem;
    }
}


/* =============================================================
   DESISTIMIENTO — Botón en pedidos + Formulario en Mi Cuenta
   /mi-cuenta/desistimiento/?pedido={id}
   ============================================================= */

/* Botón "Solicitar devolución" en la tabla de pedidos */
.woocommerce-button.desistimiento,
a.woocommerce-button.desistimiento {
    background-color: var(--ga-naranja-apagado) !important;
    border-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-negro-suave) !important;
    font-family: 'Inter', sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    border-radius: 2px;
    transition: background-color 0.22s ease, transform 0.22s ease;
}
.woocommerce-button.desistimiento:hover,
a.woocommerce-button.desistimiento:hover {
    background-color: #b89450 !important;
    border-color: #b89450 !important;
    color: var(--ga-blanco) !important;
    transform: translateY(-1px);
}

/* Contenedor principal */
.ga-desistimiento {
    max-width: 640px;
}

.ga-desistimiento__titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.1;
    margin: 0 0 2rem;
}

/* Avisos de estado (OK / error) */
.ga-desistimiento__notice {
    display: flex;
    align-items: flex-start;
    gap: 0.6rem;
    padding: 1rem 1.25rem;
    border-radius: 3px;
    font-family: 'Inter', sans-serif;
    font-size: 0.9rem;
    line-height: 1.55;
    margin-bottom: 1.5rem;
}
.ga-desistimiento__notice svg {
    flex-shrink: 0;
    margin-top: 0.15em;
}
.ga-desistimiento__notice--ok {
    background: rgba(127, 134, 73, 0.12);
    border-left: 3px solid var(--ga-verde-montanas);
    color: #3a4020;
}
.ga-desistimiento__notice--error {
    background: rgba(180, 60, 40, 0.08);
    border-left: 3px solid #b43c28;
    color: #7a2510;
}

.ga-desistimiento__volver {
    font-family: 'Inter', sans-serif;
    font-size: 0.9rem;
    margin-top: 1rem;
}
.ga-desistimiento__volver a {
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
    text-underline-offset: 3px;
}

/* Bloque del aviso legal */
.ga-desistimiento__legal {
    background-color: var(--ga-naranja-claro);
    border-left: 3px solid var(--ga-naranja-apagado);
    border-radius: 0 3px 3px 0;
    padding: 1.5rem 1.75rem;
    margin-bottom: 2.5rem;
}
.ga-desistimiento__legal-titulo {
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.15rem;
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 0.75rem;
}
.ga-desistimiento__legal p {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    line-height: 1.65;
    color: #4a4a2f;
    margin: 0 0 0.65rem;
}
.ga-desistimiento__legal p:last-child {
    margin-bottom: 0;
}

/* Formulario */
.ga-desistimiento__form {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
}
.ga-desistimiento__campo {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}
.ga-desistimiento__label {
    font-family: 'Inter', sans-serif;
    font-size: 0.8rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ga-verde-oliva-oscuro);
}
.ga-desistimiento__req {
    color: var(--ga-naranja-apagado);
}
.ga-desistimiento__op {
    font-weight: 400;
    text-transform: none;
    letter-spacing: 0;
    color: #888;
    font-size: 0.78rem;
}

.ga-desistimiento__input,
.ga-desistimiento__textarea {
    font-family: 'Inter', sans-serif;
    font-size: 0.95rem;
    color: var(--ga-negro-suave);
    background: #fff;
    border: 1.5px solid rgba(74, 74, 47, 0.22);
    border-radius: 3px;
    padding: 0.75rem 1rem;
    transition: border-color 0.22s ease;
    width: 100%;
    box-sizing: border-box;
}
.ga-desistimiento__input:focus,
.ga-desistimiento__textarea:focus {
    outline: none;
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.15);
}
.ga-desistimiento__input--readonly {
    background: var(--ga-naranja-claro);
    color: rgba(26, 26, 20, 0.5);
    cursor: not-allowed;
}
.ga-desistimiento__textarea {
    resize: vertical;
    min-height: 100px;
}
.ga-desistimiento__nota {
    font-family: 'Inter', sans-serif;
    font-size: 0.78rem;
    color: rgba(26, 26, 20, 0.48);
    margin: 0;
    line-height: 1.5;
}
.ga-desistimiento__nota a {
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
    text-underline-offset: 2px;
}

/* Checkbox de confirmación */
.ga-desistimiento__campo--check { gap: 0; }
.ga-desistimiento__check-label {
    display: flex;
    align-items: flex-start;
    gap: 0.75rem;
    cursor: pointer;
}
.ga-desistimiento__checkbox {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}
.ga-desistimiento__checkbox-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 20px;
    height: 20px;
    border: 1.5px solid rgba(74, 74, 47, 0.35);
    border-radius: 3px;
    background: #fff;
    margin-top: 1px;
    transition: background-color 0.2s ease, border-color 0.2s ease;
}
.ga-desistimiento__checkbox-box svg { opacity: 0; transition: opacity 0.15s ease; }
.ga-desistimiento__checkbox:checked + .ga-desistimiento__checkbox-box {
    background: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
}
.ga-desistimiento__checkbox:checked + .ga-desistimiento__checkbox-box svg { opacity: 1; }
.ga-desistimiento__check-texto {
    font-family: 'Inter', sans-serif;
    font-size: 0.875rem;
    color: var(--ga-negro-suave);
    line-height: 1.55;
}

/* Botón de envío */
.ga-desistimiento__campo--submit { margin-top: 0.5rem; }
.ga-desistimiento__btn {
    font-family: 'Inter', sans-serif;
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.12em;
    background: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 2px;
    padding: 0.9rem 2.25rem;
    cursor: pointer;
    transition: background 0.25s ease, color 0.25s ease, transform 0.25s ease;
}
.ga-desistimiento__btn:hover {
    background: transparent;
    color: var(--ga-naranja-apagado);
    transform: translateY(-2px);
}

@media (max-width: 599px) {
    .ga-desistimiento__legal { padding: 1.25rem; }
    .ga-desistimiento__btn { width: 100%; text-align: center; }
}


/* =============================================================
   PACKS DE AHORRO — ga-packs
   Fondo blanco. Cards de aceite (reutiliza ga-home-card) +
   configurador interactivo de aceitunas + upsell aceitunero.
   ============================================================= */

.ga-packs {
    background-color: var(--ga-blanco);
    padding: 5rem 0 0;
}

.ga-packs__inner {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 2rem;
}

/* — Header de sección — */
.ga-packs__header {
    text-align: center;
    margin-bottom: 0.75rem;
}

.ga-packs__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.8rem, 3vw, 2.8rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    margin: 0 0 0.4rem;
    text-wrap: balance;
}

.ga-packs__intro {
    font-family: var(--ga-font-body);
    font-size: 1rem;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0.4rem 0 0.5rem;
    line-height: 1.6;
}


.ga-packs__sin-productos {
    text-align: center;
    font-family: var(--ga-font-body);
    font-size: 0.95rem;
    color: var(--ga-verde-oliva-oscuro);
    padding: 2rem 0;
}

.ga-packs__sin-productos a {
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
}

/* — Badge de ahorro sobre la imagen del pack — */
.ga-packs__card .ga-home-card__img-wrap {
    position: relative;
}

.ga-packs__ahorro-badge {
    position: absolute;
    top: 0.75rem;
    right: 0.75rem;
    background-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-naranja-apagado);
    font-family: var(--ga-font-body);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    padding: 0.3rem 0.7rem;
    border-radius: 2px;
    z-index: 2;
    line-height: 1.3;
}

.ga-packs__ahorro-badge .woocommerce-Price-amount,
.ga-packs__ahorro-badge bdi {
    font-size: inherit;
    font-family: inherit;
    color: inherit;
}

/* — Precios protagonistas en tarjetas de pack — */
.ga-packs__precio-wrap {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 0.65rem;
    margin: 0.25rem 0 0.5rem;
}

.ga-packs__precio-tachado {
    font-family: var(--ga-font-body);
    font-size: 0.95rem;
    font-weight: 400;
    color: #aaa;
    text-decoration: line-through;
    text-decoration-color: #aaa;
}

.ga-packs__precio-tachado .woocommerce-Price-amount,
.ga-packs__precio-tachado bdi {
    font-size: inherit;
    font-family: inherit;
    color: inherit;
}

.ga-packs__precio-pack {
    font-family: var(--ga-font-display);
    font-size: clamp(1.6rem, 2.5vw, 2rem);
    font-weight: 700;
    color: var(--ga-naranja-apagado);
    line-height: 1;
}

.ga-packs__precio-pack .woocommerce-Price-amount,
.ga-packs__precio-pack bdi {
    font-size: inherit;
    font-family: inherit;
    color: inherit;
}

/* — Separador fino entre bloque aceite y bloque aceitunas — */
.ga-packs__divider {
    width: 100%;
    height: 1px;
    background-color: rgba(199, 168, 98, 0.28);
    margin: 4rem 0;
}

/* ==========================================================
   CONFIGURADOR PACK ACEITUNAS
   ========================================================== */

.ga-packs-aceitunas {
    background-color: var(--ga-blanco);
    border-radius: 6px;
    padding: 3rem 2.5rem 0.75rem;
    box-shadow: var(--shadow-suave);
    margin-top: 2rem;
}

.ga-packs-aceitunas__header {
    text-align: center;
    margin-bottom: 2.5rem;
}

.ga-packs-aceitunas__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 2.5vw, 2.2rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 0.6rem;
    line-height: 1.2;
}

.ga-packs-aceitunas__desc {
    font-family: var(--ga-font-body);
    font-size: 1rem;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.8;
    margin: 0 0 1.25rem;
    line-height: 1.6;
}

.ga-packs-aceitunas__sub {
    font-family: var(--ga-font-body);
    font-size: 0.9rem;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.65;
    max-width: 480px;
    margin: 0 auto;
    line-height: 1.65;
}

/* ==========================================================
   ECUACIÓN VISUAL — ga-packs-ec
   ========================================================== */

/* — Contenedor: ocupa todo el ancho disponible, distribuido con space-between — */
.ga-packs-ec {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-top: 3rem;
    margin-bottom: 2.5rem;
    flex-wrap: nowrap;
    width: 100%;
}

/* — Operador matemático (+, =) — */
.ga-packs-ec__op {
    font-family: var(--ga-font-display);
    font-size: clamp(2.8rem, 4vw, 4rem);
    font-weight: 300;
    color: #3a3a22;
    line-height: 1;
    flex-shrink: 0;
}

/* — Columna (apila las opciones verticalmente) — */
.ga-packs-ec__col {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.6rem;
    flex-shrink: 0;
}

/* — Etiqueta overline de la columna — */
.ga-packs-ec__col-label {
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.13em;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.5;
    display: block;
    text-align: center;
    white-space: nowrap;
}

/* — Ítem individual (botón clicable o div fijo) — */
.ga-packs-ec__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0;
    padding: 0;
    background: none;
    border: 3px solid transparent;
    border-radius: 5px;
    overflow: hidden;
    cursor: pointer;
    width: 165px;
    text-align: center;
    opacity: 0.45;
    transition: opacity 0.25s ease, border-color 0.25s ease, transform 0.25s ease, box-shadow 0.25s ease;
}

.ga-packs-ec__item img {
    width: 100%;
    height: 165px;
    object-fit: cover;
    display: block;
    pointer-events: none;
    transform: scale(1.12);      /* +12%: la aceituna se ve un poco más grande dentro de su casilla.
                                    Centrada (transform-origin por defecto); el overflow:hidden del ítem
                                    contiene el escalado, así que no toca los bordes ni cambia la casilla. */
}

.ga-packs-ec__item-nombre {
    font-family: var(--ga-font-body);
    font-size: 0.78rem;
    font-weight: 500;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.25;
    max-width: 186px;
    display: block;
}

/* — Estado activo — */
.ga-packs-ec__item--activa {
    opacity: 1;
    background-color: #F9F6EE;
    border-color: #c7a862;
    transform: translateY(-3px);
    box-shadow: 0 4px 18px rgba(199, 168, 98, 0.4);
}

/* — Hover en ítems no activos — */
.ga-packs-ec__item:hover:not(.ga-packs-ec__item--activa) {
    opacity: 0.75;
    border-color: rgba(199, 168, 98, 0.4);
}

/* — Tarro fijo (Gordal): sin cursor pointer — */
.ga-packs-ec__item--fijo {
    cursor: default;
}

/* — Nombre de variedad bajo la imagen — */
/* Fondo siempre crema en todos los estados: evita transiciones de color de fondo
   que generan parpadeo. La opacidad del ítem padre (0.45 normal / 0.75 hover / 1 activa)
   define la intensidad visual. height fija garantiza altura idéntica en todas las tarjetas. */
.ga-packs-ec__nombre {
    display: flex;
    flex-direction: column;
    justify-content: center;
    box-sizing: border-box;
    width: 100%;
    height: 3.5rem;
    overflow: hidden;
    font-family: var(--ga-font-body);
    font-size: 0.75rem;
    font-weight: 400;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--ga-naranja-apagado);
    background-color: #F9F6EE;
    text-align: center;
    line-height: 1.3;
    padding: 0 0.5rem;
    transition: color 0.3s ease;
}

/* HOVER (no seleccionada): solo sube la opacidad del ítem padre, el nombre no cambia */
.ga-packs-ec__item:hover:not(.ga-packs-ec__item--activa) .ga-packs-ec__nombre {
    color: #c7a862;
}

/* SELECCIONADA: texto dorado en negrita, sin línea divisoria interior */
.ga-packs-ec__item--activa .ga-packs-ec__nombre {
    color: #c7a862;
    font-weight: 700;
}

/* — Resultado (precio + botón ATC) — */
/*
   padding-top = gap + min-height del botón: hace que el bloque tenga el mismo
   peso por encima y por debajo del precio, de modo que cuando el row centra el
   bloque con align-items: center, el PRECIO queda alineado con el símbolo "=".
*/
.ga-packs-ec__resultado {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    flex-shrink: 0;
    gap: 0.85rem;
    padding-top: calc(44px + 0.85rem);
}

.ga-packs-ec__resultado .ga-packs__precio-pack {
    font-size: clamp(2.4rem, 3.5vw, 3.4rem);
    line-height: 1;
    color: #3a3a22;
}

/* — Botón Añadir al carrito — */
.ga-packs-ec__btn-atc {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.7rem 1.4rem;
    font-family: var(--ga-font-body);
    font-size: 0.7rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-naranja-apagado);
    background-color: transparent;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 3px;
    cursor: pointer;
    min-height: 44px;
    min-width: 180px;
    white-space: nowrap;
    transition: background-color 0.3s ease, color 0.3s ease,
                border-color 0.3s ease, transform 0.3s ease,
                box-shadow 0.3s ease;
    text-decoration: none;
}

.ga-packs-ec__btn-atc:hover:not(:disabled) {
    background-color: var(--ga-naranja-apagado);
    color: #3a3a22;
    transform: translateY(-2px);
    box-shadow: 0 4px 16px rgba(199, 168, 98, 0.35);
}

/* Estado: enviando petición AJAX */
.ga-packs-ec__btn-atc--cargando {
    opacity: 0.7;
    cursor: wait;
}

/* Spinner animado tras el texto de "Añadiendo..." */
.ga-packs-ec__btn-atc--cargando::after {
    content: '';
    display: inline-block;
    width: 10px;
    height: 10px;
    margin-left: 6px;
    border: 2px solid rgba(199, 168, 98, 0.3);
    border-top-color: var(--ga-naranja-apagado);
    border-radius: 50%;
    animation: ga-spin 0.75s linear infinite;
    vertical-align: middle;
    flex-shrink: 0;
}

@keyframes ga-spin {
    to { transform: rotate(360deg); }
}

/* Estado: añadido correctamente */
.ga-packs-ec__btn-atc--exito {
    background-color: var(--ga-verde-montanas);
    border-color: var(--ga-verde-montanas);
    color: var(--ga-blanco);
}

.ga-packs-ec__btn-atc--exito:hover {
    background-color: var(--ga-verde-montanas);
    color: var(--ga-blanco);
    transform: none;
    box-shadow: none;
}

/* Estado: error */
.ga-packs-ec__btn-atc--error {
    background-color: #b94040;
    border-color: #b94040;
    color: var(--ga-blanco);
    font-size: 0.6rem;
    white-space: normal;
    text-align: center;
}

.ga-packs-ec__btn-atc--error:hover {
    background-color: #b94040;
    color: var(--ga-blanco);
    transform: none;
    box-shadow: none;
}

/* ==========================================================
   ACEITUNERO HOURGLASS — Bloque visual photo-first
   ========================================================== */

/* ==========================================================
   POPUP ACEITUNERO — modal upsell post-pack-aceitunas
   ========================================================== */

.ga-aceitunero-modal__overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.52);
    z-index: 99999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    opacity: 0;
    transition: opacity 0.28s ease;
}

.ga-aceitunero-modal__overlay.ga-aceitunero-modal--visible {
    opacity: 1;
}

.ga-aceitunero-modal__caja {
    position: relative;
    background: #F5EEDD;
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: 10px;
    padding: 2.5rem 2.75rem 2.25rem;
    box-shadow: 0 28px 70px rgba(0, 0, 0, 0.32);
    max-width: 660px;
    width: 100%;
    transform: translateY(22px) scale(0.97);
    transition: transform 0.3s cubic-bezier(0.34, 1.36, 0.64, 1);
}

.ga-aceitunero-modal__overlay.ga-aceitunero-modal--visible .ga-aceitunero-modal__caja {
    transform: translateY(0) scale(1);
}

/* Contenido interno: quitar doble marco ya que el caja lo provee */
.ga-aceitunero-modal__caja .ga-packs-aceitunero {
    background: transparent;
    border: none;
    border-radius: 0;
    padding: 0;
}

.ga-aceitunero-modal__cerrar {
    position: absolute;
    top: 0.85rem;
    right: 0.85rem;
    background: none;
    border: none;
    cursor: pointer;
    color: var(--ga-verde-oliva-oscuro);
    padding: 0.3rem;
    display: flex;
    align-items: center;
    justify-content: center;
    opacity: 0.45;
    transition: opacity 0.2s ease;
    line-height: 0;
}

.ga-aceitunero-modal__cerrar:hover {
    opacity: 1;
}


/* ==========================================================
   ACEITUNERO HOURGLASS — Recuadro dorado horizontal
   ========================================================== */

.ga-packs-aceitunero {
    display: flex;
    align-items: center;
    gap: 1.75rem;
    background-color: #F5EEDD;
    border: 1.5px solid var(--ga-naranja-apagado);
    border-radius: 8px;
    padding: 1.75rem 2rem;
}

/* — Foto izquierda — */
.ga-packs-aceitunero__foto-btn {
    position: relative;
    flex-shrink: 0;
    width: 155px;
    height: 155px;
    border: none;
    border-radius: 7px;
    overflow: hidden;
    cursor: pointer;
    padding: 0;
    background: none;
    box-shadow: 0 6px 20px rgba(70, 52, 31, 0.28);
    transition: transform 0.25s ease, box-shadow 0.25s ease;
}

.ga-packs-aceitunero__foto-btn:hover {
    transform: scale(1.03);
    box-shadow: 0 10px 30px rgba(70, 52, 31, 0.38);
}

.ga-packs-aceitunero__img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform 0.35s ease;
}

.ga-packs-aceitunero__foto-btn:hover .ga-packs-aceitunero__img {
    transform: scale(1.06);
}

.ga-packs-aceitunero__foto-overlay {
    position: absolute;
    inset: 0;
    background-color: rgba(74, 74, 47, 0.62);
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    opacity: 0;
    transition: opacity 0.25s ease;
    color: var(--ga-blanco);
}

.ga-packs-aceitunero__foto-icono {
    display: flex;
    align-items: center;
    justify-content: center;
}

.ga-packs-aceitunero__foto-icono svg {
    stroke: var(--ga-blanco);
}

.ga-packs-aceitunero__foto-texto {
    font-family: var(--ga-font-body);
    font-size: 0.62rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-blanco);
    white-space: nowrap;
}

#ga-aceitunero-recuadro.is-exito .ga-packs-aceitunero__foto-icono svg {
    animation: ga-icon-in 0.28s ease forwards;
}

.ga-packs-aceitunero__foto-btn:hover .ga-packs-aceitunero__foto-overlay {
    opacity: 1;
}

#ga-aceitunero-recuadro.is-cargando .ga-packs-aceitunero__foto-overlay {
    opacity: 1;
    background-color: rgba(74, 74, 47, 0.55);
}

#ga-aceitunero-recuadro.is-exito .ga-packs-aceitunero__foto-overlay {
    opacity: 1;
    background-color: rgba(127, 134, 73, 0.72);
}

#ga-aceitunero-recuadro.is-error .ga-packs-aceitunero__foto-overlay {
    opacity: 1;
    background-color: rgba(185, 64, 64, 0.72);
}

/* — Info derecha — */
.ga-packs-aceitunero__info {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.ga-packs-aceitunero__etiqueta {
    font-family: var(--ga-font-body);
    font-size: 0.68rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.14em;
    color: var(--ga-naranja-apagado);
    margin: 0;
}

.ga-packs-aceitunero__titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.15rem, 2vw, 1.5rem);
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0;
    line-height: 1.15;
}

.ga-packs-aceitunero__titulo-link {
    color: inherit;
    text-decoration: none;
    transition: color 0.25s ease;
}

.ga-packs-aceitunero__titulo-link:hover {
    color: var(--ga-naranja-apagado);
    cursor: pointer;
}

.ga-packs-aceitunero__desc {
    font-family: var(--ga-font-body);
    font-size: 0.86rem;
    color: rgba(74, 74, 47, 0.78);
    margin: 0;
    line-height: 1.5;
}

/* — Botón Añadir al carrito — */
.ga-packs-aceitunero__btn-compra {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.65rem 1.3rem;
    font-family: var(--ga-font-body);
    font-size: 0.72rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-naranja-claro);
    background-color: #4a4a2f;
    border: none;
    border-radius: 3px;
    cursor: pointer;
    min-height: 40px;
    width: fit-content;
    margin-top: 0.2rem;
    transition: background-color 0.25s ease, transform 0.2s ease, box-shadow 0.2s ease;
}

.ga-packs-aceitunero__btn-compra:hover:not(:disabled) {
    background-color: #3a3a22;
    transform: translateY(-1px);
    box-shadow: 0 3px 10px rgba(58, 58, 34, 0.3);
}

#ga-aceitunero-recuadro.is-cargando .ga-packs-aceitunero__btn-compra {
    background-color: rgba(74, 74, 47, 0.55);
    cursor: wait;
}

#ga-aceitunero-recuadro.is-exito .ga-packs-aceitunero__btn-compra {
    background-color: var(--ga-verde-montanas);
}

#ga-aceitunero-recuadro.is-error .ga-packs-aceitunero__btn-compra {
    background-color: #b94040;
    font-size: 0.62rem;
    white-space: normal;
    text-align: center;
}

@keyframes ga-icon-in {
    from { opacity: 0; transform: scale(0.65); }
    to   { opacity: 1; transform: scale(1); }
}

.ga-packs-aceitunero__btn-icono {
    display: flex;
    align-items: center;
    flex-shrink: 0;
}

.ga-packs-aceitunero__btn-icono svg {
    stroke: var(--ga-naranja-claro);
}

#ga-aceitunero-recuadro.is-exito .ga-packs-aceitunero__btn-icono svg {
    animation: ga-icon-in 0.28s ease forwards;
    stroke: var(--ga-naranja-claro);
}

/* — Precio — */
.ga-packs-aceitunero__precio {
    font-family: var(--ga-font-body);
    font-size: 0.85rem;
    font-weight: 500;
    color: rgba(74, 74, 47, 0.7);
    margin: 0;
}

.ga-packs-aceitunero__precio .woocommerce-Price-amount {
    color: inherit;
}

.ga-packs-aceitunero__fallback-link {
    font-family: var(--ga-font-body);
    font-size: 0.75rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.1em;
    color: var(--ga-verde-oliva-oscuro);
    text-decoration: underline;
}

.ga-packs-aceitunero__img--placeholder {
    width: 100%;
    height: 100%;
    background-color: var(--ga-naranja-claro);
}

/* — Responsive — */
@media (max-width: 1024px) {
    .ga-packs-ec {
        gap: 0.75rem;
        overflow-x: auto;
    }

    .ga-packs-ec__op {
        font-size: clamp(2rem, 3vw, 2.8rem);
    }

    .ga-packs-ec__item {
        width: 130px;
    }

    .ga-packs-ec__item img {
        width: 100%;
        height: 130px;
    }

    .ga-packs-ec__resultado .ga-packs__precio-pack {
        font-size: clamp(2rem, 3vw, 2.6rem);
    }
}

@media (max-width: 768px) {
    .ga-packs {
        padding: 1.75rem 0 0.5rem; /* Cambio 4: menos hueco tras la sección negra */
    }

    .ga-packs__inner {
        padding: 0 1.25rem;
    }

    .ga-packs__divider {
        margin: 3rem auto;
    }

    .ga-packs-aceitunas {
        padding: 2rem 1.25rem 0.75rem;
        position: relative;
        z-index: 5;
    }

    /* Ecuación visual: apila verticalmente, cada columna hace scroll horizontal */
    .ga-packs-ec {
        flex-direction: column;
        align-items: center;
        justify-content: flex-start;
        gap: 0.75rem;
    }

    .ga-packs-ec__op {
        font-size: 2rem;
    }

    .ga-packs-ec__col {
        flex-direction: row;
        flex-wrap: nowrap;
        overflow-x: auto;
        width: 100%;
        max-width: 100%;
        gap: 0.5rem;
        padding-bottom: 4px;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        justify-content: flex-start;
        flex-shrink: 1;
    }

    .ga-packs-ec__col::-webkit-scrollbar {
        display: none;
    }

    .ga-packs-ec__col-label {
        display: none;
    }

    .ga-packs-ec__item {
        width: 100px;
        flex-shrink: 0;
    }

    .ga-packs-ec__item img {
        width: 100%;
        height: 100px;
    }

    .ga-packs-ec__resultado .ga-packs__precio-pack {
        font-size: 2.4rem;
    }

    .ga-packs-ec__resultado {
        padding-top: 0;
    }

    /* Aceitunero — recuadro vertical en móvil */
    .ga-packs-aceitunero {
        flex-direction: column;
        align-items: center;
        text-align: center;
        padding: 1.5rem 1.25rem;
        gap: 1.1rem;
    }

    .ga-packs-aceitunero__foto-btn {
        width: 145px;
        height: 145px;
    }

    .ga-packs-aceitunero__info {
        align-items: center;
    }

    .ga-packs-aceitunero__btn-compra {
        width: auto;
    }

    /* Cambio 1: títulos al mismo tamaño que en "Nuestros Aceites" */
    .ga-packs .ga-home-card__titulo {
        font-size: 1.3rem;
        line-height: 1.3;
    }

    /* Gap cero entre tarjetas */
    .ga-packs .ga-home-cards {
        gap: 0;
    }

    /* C1 — Imagen de pack más compacta en móvil */
    .ga-packs .ga-home-card__img-wrap,
    .ga-packs .ga-home-card__img {
        min-height: 210px;
    }

    /* C1 — Cuerpo de tarjeta: menos padding y menos gap interno */
    .ga-packs .ga-home-card__body {
        padding: 0.4rem 0.75rem 0.3rem;
        gap: 0.15rem;
    }

    /* C2 — Solapamiento mínimo entre tarjetas consecutivas */
    .ga-packs .ga-home-card + .ga-home-card {
        margin-top: -5px;
    }

    /* Eliminar márgenes sobrantes: frase pegada al primer pack */
    .ga-packs__header {
        margin-bottom: 0;
    }

    .ga-packs__intro {
        margin-top: 0;
        margin-bottom: 0;
    }

    /* Cambio 2: título configurador aceitunas más grande */
    .ga-packs-aceitunas__titulo {
        font-size: clamp(1.9rem, 7vw, 2.2rem);
        line-height: 1.2;
    }

}

/* ==========================================================================
   CONFIGURADOR ACEITUNAS — MODO DROPDOWN MÓVIL (≤ 768px)
   Reemplaza los scrollable-rows por desplegables visuales.
   El escritorio queda 100% intacto.
   ========================================================================== */
@media (max-width: 768px) {

    /* — Contenedor: full-bleed que cancela el padding acumulado de los padres.
       Técnica: width:100vw + left:50% + translateX(-50%) coloca el elemento
       exactamente en los bordes del viewport, sin depender del padding heredado. — */
    .ga-packs-ec--mobile-dropdown {
        position: relative;
        width: 100vw;
        left: 50%;
        transform: translateX(-50%);
        box-sizing: border-box;
        padding-left: 6px;
        padding-right: 6px;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: flex-start;
        justify-content: flex-start;
        gap: 0.25rem;
        overflow: visible;
        margin-top: 1.5rem;
        margin-bottom: 1rem;
    }

    /* — Operadores + y + a tamaño legible — */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__op {
        font-size: 1.4rem;
        align-self: center;
        padding: 0;
        line-height: 1;
        flex-shrink: 0;
    }

    /* — Ocultar el operador = (resultado ocupa línea propia) — */
    .ga-packs-ec--mobile-dropdown span.ga-packs-ec__op:last-of-type {
        display: none;
    }

    /* — Columnas seleccionables: flex:1 para repartir el ancho disponible — */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col {
        flex: 1;
        min-width: 0;
        position: relative;
        flex-direction: column;
        overflow: visible;
        align-items: center;
        gap: 0;
        padding-bottom: 0;
        scrollbar-width: auto;
        flex-shrink: 1;
    }

    /* — Trigger: ocupa el 100% del col, crece con él — */
    .ga-packs-ec__trigger {
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
        cursor: pointer;
        border: 2px solid var(--ga-naranja-apagado);
        border-radius: 5px;
        overflow: hidden;
        background: #F9F6EE;
        box-shadow: 0 2px 10px rgba(199, 168, 98, 0.25);
        transition: box-shadow 0.2s ease;
        padding-top: 4px;
    }

    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col.is-open .ga-packs-ec__trigger {
        box-shadow: 0 4px 18px rgba(199, 168, 98, 0.5);
    }

    /* Imagen cuadrada que crece con el col */
    .ga-packs-ec__trigger img {
        width: 100%;
        height: auto;
        aspect-ratio: 1 / 1;
        object-fit: cover;
        display: block;
        pointer-events: none;
    }

    /* Zona nombre: altura para 3 líneas (0.45 padding-top + 3×0.75 + 0.1 padding-bottom = 2.8rem).
       Necesario porque "CÓCTEL DE ACEITUNAS Y ENCURTIDOS" ocupa 3 líneas a ~100px de ancho.
       display:block + overflow:hidden — el texto fluye desde arriba sin corte con "...". */
    .ga-packs-ec__trigger-nombre {
        display: block;
        width: 100%;
        height: 2.8rem;
        overflow: hidden;
        padding: 0.45rem 0.2rem 0.1rem;
        box-sizing: border-box;
        font-family: var(--ga-font-body);
        font-size: 0.6rem;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.06em;
        color: var(--ga-naranja-apagado);
        text-align: center;
        line-height: 1.25;
        background: #F9F6EE;
    }

    /* Zona flecha: altura fija consistente */
    .ga-packs-ec__trigger-arrow {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        height: 1.2rem;
        box-sizing: border-box;
        font-size: 0.55rem;
        color: var(--ga-naranja-apagado);
        background: #F9F6EE;
        line-height: 1;
        transition: transform 0.2s ease;
    }

    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col.is-open .ga-packs-ec__trigger-arrow {
        transform: rotate(180deg);
    }

    /* — Panel desplegable con todas las opciones — */
    .ga-packs-ec__panel {
        position: absolute;
        top: calc(100% + 6px);
        left: 50%;
        transform: translateX(-50%);
        width: 210px;
        background: #F9F6EE;
        border: 2px solid var(--ga-naranja-apagado);
        border-radius: 6px;
        z-index: 1000;
        overflow: hidden;
        pointer-events: none;
        max-height: 0;
        opacity: 0;
        transition: max-height 0.28s ease, opacity 0.18s ease;
    }

    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col.is-open .ga-packs-ec__panel {
        max-height: 500px;
        opacity: 1;
        pointer-events: auto;
    }

    /* Panel del Tarro 1 (primer col, borde izquierdo del EC):
       El centrado por defecto (left:50% + translateX(-50%)) lo sitúa ~54px fuera
       del viewport, recortado por html/body { overflow-x: hidden }.
       Alineamos left:0 para que el panel arranque en el borde izquierdo del col. */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col:first-child .ga-packs-ec__panel {
        left: 0;
        transform: none;
    }

    /* — Ítems dentro del panel: disposición horizontal foto + nombre — */
    .ga-packs-ec__panel .ga-packs-ec__item {
        display: flex;
        flex-direction: row;
        width: 100%;
        height: auto;
        border-radius: 0;
        border: none;
        border-bottom: 1px solid rgba(199, 168, 98, 0.2);
        padding: 0.5rem 0.75rem;
        gap: 0.6rem;
        align-items: center;
        opacity: 0.75;
        transform: none;
        box-shadow: none;
        background: none;
        flex-shrink: 0;
    }

    .ga-packs-ec__panel .ga-packs-ec__item:last-child {
        border-bottom: none;
    }

    .ga-packs-ec__panel .ga-packs-ec__item img {
        width: 40px;
        height: 40px;
        object-fit: cover;
        border-radius: 3px;
        flex-shrink: 0;
    }

    .ga-packs-ec__panel .ga-packs-ec__item .ga-packs-ec__nombre {
        flex: 1;
        height: auto;
        background: none;
        text-align: left;
        font-size: 0.68rem;
        font-weight: 400;
        padding: 0;
        color: var(--ga-verde-oliva-oscuro);
        text-transform: none;
        letter-spacing: 0.02em;
    }

    .ga-packs-ec__panel .ga-packs-ec__item--activa {
        opacity: 1;
        background: rgba(199, 168, 98, 0.12);
        transform: none;
        box-shadow: none;
        border-bottom-color: rgba(199, 168, 98, 0.2);
    }

    .ga-packs-ec__panel .ga-packs-ec__item--activa .ga-packs-ec__nombre {
        font-weight: 700;
        color: var(--ga-naranja-apagado);
    }

    /* — Tarro fijo Gordal: flex:1 igual que los cols seleccionables — */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col--fijo {
        flex: 1;
        min-width: 0;
        overflow: visible;
        align-items: center;
        flex-shrink: 1;
    }

    /* El ítem del Gordal ocupa todo el col */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col--fijo .ga-packs-ec__item {
        display: flex;
        flex-direction: column;
        align-items: center;
        width: 100%;
        box-sizing: border-box;
        border: 2px solid var(--ga-naranja-apagado);
        border-radius: 5px;
        overflow: hidden;
        background: #F9F6EE;
        opacity: 1;
        transform: none;
        box-shadow: 0 2px 10px rgba(199, 168, 98, 0.25);
        padding-top: 4px;
        cursor: default;
    }

    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col--fijo .ga-packs-ec__item img {
        width: 100%;
        height: auto;
        aspect-ratio: 1 / 1;
        object-fit: cover;
        display: block;
    }

    /* Zona nombre Gordal: altura = trigger-nombre (2.8rem) + flecha (1.2rem) = 4.0rem.
       display:block + padding-top idéntico al trigger → el texto arranca a la misma altura. */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__col--fijo .ga-packs-ec__nombre {
        display: block;
        width: 100%;
        height: 4.0rem;
        box-sizing: border-box;
        overflow: hidden;
        background: #F9F6EE;
        font-size: 0.6rem;
        font-weight: 700;
        padding: 0.45rem 0.2rem 0.1rem;
        text-align: center;
        letter-spacing: 0.06em;
        line-height: 1.25;
    }

    /* — Resultado: ocupa línea propia (100% de ancho), centrado — */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__resultado {
        flex-basis: 100%;
        flex-direction: column;
        align-items: center;
        padding-top: 0.2rem;
        padding-bottom: 0.5rem;
        gap: 0.3rem;
    }

    /* Símbolo = delante del precio */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__resultado::before {
        content: '=';
        display: block;
        font-family: var(--ga-font-display);
        font-size: 1.8rem;
        font-weight: 300;
        color: #3a3a22;
        line-height: 1;
        margin-bottom: -0.15rem;
    }

    .ga-packs-ec--mobile-dropdown .ga-packs-ec__resultado .ga-packs__precio-pack {
        font-size: 2.8rem;
    }

    /* CAMBIO 2 — Espacio entre precio y botón Añadir al carrito */
    .ga-packs-ec--mobile-dropdown .ga-packs-ec__btn-atc {
        margin-top: 0.6rem;
    }

}


/* =============================================================
   PÁGINA TIENDA — .ga-tienda-   (page-templates/page-tienda.php)
   Cabecera + barra de categorías fija (anclas) + secciones apiladas.
   Reutiliza el sistema de tarjetas .ga-home-card ("Nuestros Aceites").

   FASE ACTUAL: SOLO ESCRITORIO. El diseño móvil se abordará después;
   al final solo hay un ajuste mínimo defensivo para <=768px.
   ============================================================= */

:root {
    --ga-tienda-bar-height: 60px;    /* alto de la barra de categorías fija */
}

.ga-main--tienda {
    background-color: var(--ga-blanco);   /* CAMBIO 1: tienda y secciones en blanco #FFFFFF */
}

/* ——— CABECERA ——— */
.ga-tienda-header {
    /* CAMBIO 1: banda flex para centrar "Tienda" vertical y horizontalmente, sin
       depender de paddings simétricos. min-height ≈ el alto que tenía la banda. */
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: calc(var(--ga-text-6xl) + 2 * var(--ga-space-sm));   /* 96px: 72px dejaba asomar el fondo blanco bajo el título (la caja de línea mide 67,2px y quedaba sin holgura) */
    padding: 0 var(--ga-space-md);          /* solo horizontal; el vertical lo gobierna min-height */
    text-align: center;
    background-color: var(--ga-naranja-claro);   /* #F9F6EE, a todo el ancho */
}

/* CAMBIO 1 (causa raíz): el título arrastraba un margin heredado del h1 (Astra) que
   GANABA en especificidad al margin:0 anterior (0,0,2,0) y lo empujaba hacia abajo →
   más espacio arriba. Con !important se elimina de verdad. Padding (0 vertical) y flex
   ya estaban bien; el margin era lo que descuadraba. */
.ga-main--tienda .ga-tienda-header__titulo {
    margin: 0 !important;
}

.ga-tienda-header__titulo {
    display: inline-block;                  /* CAMBIO 2: el ancho se ajusta al texto */
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-6xl);          /* 64px — impacto de título de sección */
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.05;
    letter-spacing: 0.01em;
    margin: 0;
}

/* Sube "Tienda" unos píxeles dentro de su banda en ESCRITORIO y TABLET. Va en un
   min-width:769px para no pisar el translateY del bloque móvil, que ya está ajustado
   aparte. Se usa transform y no margin/padding a propósito: es puramente visual, no
   altera el flujo ni el alto de la banda ni empuja nada de alrededor. No se toca el
   min-height, ni los paddings, ni el centrado flex. */
@media (min-width: 769px) {
    .ga-main--tienda .ga-tienda-header__titulo {
        transform: translateY(-8px);
    }
}

/* Línea dorada bajo "Tienda" ELIMINADA: content:none impide que se genere el
   pseudo-elemento, así que no queda ni línea ni espacio reservado. El padding
   simétrico de .ga-tienda-header (space-md arriba y abajo) mantiene el título
   centrado y el espaciado equilibrado, sin hueco. */
.ga-tienda-header__titulo::after {
    content: none;   /* antes: "" → línea dorada de 2px con margin-top */
    display: block;
    width: 100%;                            /* = ancho del texto (título inline-block) */
    height: 2px;
    background: var(--ga-naranja-apagado);
    margin-top: var(--ga-space-md);
}

/* ——— BARRA DE CATEGORÍAS FIJA (CAMBIO 2) ———
   sticky bajo la cabecera fija del sitio (.ga-header: fixed, 80px).
   Hija directa de <main>, sin ancestros con overflow:hidden → sticky funciona. */
.ga-tienda-nav {
    position: sticky;
    top: var(--ga-nav-height);              /* 80px: justo debajo del header fijo */
    z-index: 500;                           /* < header (1000), > contenido */
    height: var(--ga-tienda-bar-height);
    background-color: var(--ga-naranja-claro);   /* CAMBIO 2: franja crema #F9F6EE, 100% opaca sobre el blanco */
    border-top: 1px solid rgba(74, 74, 47, 0.08);
    border-bottom: 1px solid rgba(74, 74, 47, 0.12);
    box-shadow: 0 4px 16px rgba(74, 74, 47, 0.06);
}

.ga-tienda-nav__lista {
    max-width: var(--ga-max-width);
    height: 100%;
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: clamp(1rem, 3vw, 3rem);
}

.ga-tienda-nav__link {
    position: relative;
    display: inline-block;
    padding: 0.35rem 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    white-space: nowrap;
    color: var(--ga-verde-oliva-oscuro);
    transition: color var(--ga-transition-fast);
}

/* Subrayado dorado que CRECE de izquierda a derecha — MISMO mecanismo que el menú de
   la cabecera (.ga-nav__menu > li > a::after): width 0 → 100% con transition:width y la
   misma var(--ga-transition-normal). position:absolute lo mantiene siempre reservado en
   bottom:-2px → no cambia el tamaño del botón en ningún estado. Sirve para :hover Y para
   la sección activa (.is-active): una sola línea, sin doblarse ni parpadear. */
.ga-tienda-nav__link::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 0;
    height: 2px;
    background: var(--ga-naranja-apagado);
    transition: width var(--ga-transition-normal);
}

.ga-tienda-nav__link:hover {
    color: var(--ga-naranja-apagado);
}

.ga-tienda-nav__link.is-active {
    color: var(--ga-naranja-apagado);       /* dorado #c7a862 */
}

/* :hover y sección activa comparten el MISMO subrayado (una sola línea completa) */
.ga-tienda-nav__link:hover::after,
.ga-tienda-nav__link.is-active::after {
    width: 100%;
}

/* ——— SECCIONES APILADAS (CAMBIO 3) ——— */
.ga-tienda-seccion {
    /* Compensa cabecera fija + barra al saltar a un ancla,
       para que el título no quede oculto tras la barra. */
    scroll-margin-top: calc(var(--ga-nav-height) + var(--ga-tienda-bar-height));
}

.ga-tienda-seccion__inner {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    /* Aire vertical de cada sección. Como el hueco ENTRE dos secciones es la suma del
       padding inferior de una y el superior de la siguiente, 40px daban 80px de blanco.
       Con 24px quedan 48px: la tienda se compacta pero las secciones se siguen
       distinguiendo. (antes var(--ga-space-lg)=40px; originalmente space-xl=64px) */
    padding: var(--ga-space-md) var(--ga-space-md);
}

/* La PRIMERA sección respira un poco más por arriba: es la única cuyo hueco superior
   no se suma al padding inferior de una sección anterior (solo tiene la barra de
   categorías encima), así que con 24px quedaba pegada. :first-of-type — y no un id ni
   el slug "aceite" — hace que siga aplicándose a la que quede primera si mañana
   cambia el orden; <header> y <nav> son de otro tipo, así que no interfieren. Los tres
   formatos: gana en especificidad (3 clases) a los overrides de las media queries. */
.ga-tienda-seccion:first-of-type .ga-tienda-seccion__inner {
    padding-top: var(--ga-space-lg);   /* 40px (el resto sigue en 24px) */
}

.ga-tienda-seccion__header {
    text-align: center;
    /* CAMBIO 4: menos aire entre el título y las tarjetas (antes var(--ga-space-lg)=40px) */
    margin-bottom: var(--ga-space-md);
}

/* CAMBIO 2: los CINCO títulos de sección = SOLO texto dorado (sin recuadro) con
   brillo animado. Sin fondo, sin borde, sin border-radius, sin padding de píldora. */
.ga-tienda-seccion__titulo {
    display: inline-block;                  /* la caja se ajusta al texto (el brillo recorre las letras) */
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-4xl);          /* mismo tamaño que antes */
    font-weight: var(--ga-weight-bold);
    line-height: 1.1;
    margin: 0;
    color: var(--ga-naranja-apagado);       /* FALLBACK: dorado plano #c7a862 (nunca invisible sin clip) */
}

/* Brillo animado SOLO donde el navegador soporta recortar el degradado sobre el
   texto (background-clip:text). Anima únicamente background-position → sin reflow ni
   desbordamiento. El rango 100%→0% mantiene el degradado cubriendo siempre las
   letras (con no-repeat), así que el texto nunca queda invisible. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .ga-tienda-seccion__titulo {
        background-image: linear-gradient(
            100deg,
            var(--ga-naranja-apagado) 0%,
            var(--ga-naranja-apagado) 45%,
            #F5EEDD 50%,
            var(--ga-naranja-apagado) 55%,
            var(--ga-naranja-apagado) 100%
        );
        background-size: 250% 100%;
        background-repeat: no-repeat;
        background-position: 100% center;
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
        animation: ga-tienda-titulo-brillo 6s linear infinite;
    }
}

/* El punto de brillo (dorado claro #F5EEDD) recorre las letras de izquierda a
   derecha, en bucle lento (6s) y sutil. En los extremos el brillo queda fuera del
   texto → dorado plano, así que el reinicio del bucle es imperceptible. */
@keyframes ga-tienda-titulo-brillo {
    0%   { background-position: 100% center; }
    100% { background-position: 0% center; }
}

/* Ahorro de movimiento: sin animación; dorado con brillo estable (no se mueve). */
@media (prefers-reduced-motion: reduce) {
    .ga-tienda-seccion__titulo {
        animation: none;
        background-position: center;
    }
}

/* CAMBIO 1: el título de Packs Ahorro usa EXACTAMENTE el mismo mecanismo de brillo que
   los demás (background-clip:text + animación de background-position, 6s linear), pero
   sobre el verde de marca en vez del dorado. Solo hay que sustituir el degradado:
   background-size, no-repeat, position y animation los hereda de la regla base
   .ga-tienda-seccion__titulo, así que el barrido es idéntico. Solo este título; los
   otros cuatro siguen dorados. */
.ga-main--tienda .ga-tienda-seccion__titulo--verde {
    color: var(--ga-verde-oliva-oscuro);                    /* FALLBACK sin background-clip */
    -webkit-text-fill-color: var(--ga-verde-oliva-oscuro);
}

@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .ga-main--tienda .ga-tienda-seccion__titulo--verde {
        background-image: linear-gradient(
            100deg,
            var(--ga-verde-oliva-oscuro) 0%,
            var(--ga-verde-oliva-oscuro) 45%,
            var(--ga-verde-montanas) 50%,      /* punto de brillo: verde más luminoso #7f8649 */
            var(--ga-verde-oliva-oscuro) 55%,
            var(--ga-verde-oliva-oscuro) 100%
        );
        -webkit-text-fill-color: transparent;
        color: transparent;
    }
}

/* Ahorro de movimiento: verde oscuro sólido, sin degradado (la regla común ya quita
   la animación). Va el último para ganar por orden a las dos reglas de arriba. */
@media (prefers-reduced-motion: reduce) {
    .ga-main--tienda .ga-tienda-seccion__titulo--verde {
        background-image: none;
        -webkit-text-fill-color: var(--ga-verde-oliva-oscuro);
        color: var(--ga-verde-oliva-oscuro);
    }
}

/* ——— SUBFILTRO DE COSECHA — solo Aceite (CAMBIO 4) ——— */
.ga-tienda-subfiltro {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--ga-space-md);                /* más aire entre botones de texto (antes var(--ga-space-xs)) */
    margin-bottom: var(--ga-space-lg);
}

/* CAMBIO 2: la mitad de aire entre el título y su subfiltro. El hueco lo genera
   .ga-tienda-seccion__header{margin-bottom:var(--ga-space-md)} = 24px, que es COMÚN a
   las cinco secciones. Recortarlo ahí encogería también el hueco título→parrilla de
   las secciones sin subfiltro, así que lo compensamos solo cuando el subfiltro va
   justo detrás del título: afecta por igual a Packs Ahorro y a Aceite (coherente) y
   deja intactas Aceitunas, Novedades y Merchandising. El selector hermano adyacente
   funciona en todos los navegadores. */
.ga-tienda-seccion__header + .ga-tienda-subfiltro {
    margin-top: calc(var(--ga-space-xs) - var(--ga-space-md));   /* -16px → hueco efectivo 8px (un tercio de los 24px originales) */
}

/* CAMBIO 4: solo texto, sin recuadro. El subrayado se reserva siempre
   (transparente en normal) para que al seleccionar no se mueva nada. */
.ga-tienda-subfiltro__btn {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ga-verde-oliva-oscuro);
    position: relative;                     /* para el ::after del subrayado */
    background: none;
    border: none;
    border-bottom: 2px solid transparent;   /* reserva el hueco del subrayado → sin salto (tamaño fijo) */
    border-radius: 0;
    padding: 0.25rem 0;                      /* sin padding lateral → subrayado = ancho de la palabra */
    cursor: pointer;
    transition: color var(--ga-transition-fast);
}

/* Botón de aceituna del subfiltro de Packs: dos textos, se muestra uno según el
   breakpoint. Por defecto (escritorio/tablet) SOLO el largo (nombre real de la categoría);
   el corto se oculta aquí y se activa en el media query de móvil. Solo afecta a este botón
   porque estas clases únicamente existen en él. */
.ga-tienda-subfiltro__txt--corto {
    display: none;
}

/* CAMBIO 2: subrayado que CRECE de izquierda a derecha en :hover — MISMO mecanismo que la
   barra de categorías (::after con width 0→100% y transition:width var(--ga-transition-normal),
   misma duración/curva). position:absolute → no cambia el tamaño del botón. */
/* La raya crece con scaleX, NO con width. Antes iba de width:0 a width:100%: animar el
   ancho es una propiedad de layout y la interpolación de 0 a un porcentaje no es fiable,
   por eso al entrar aparecía de golpe y solo se replegaba suave al salir. Con transform
   la animación es simétrica en los dos sentidos (y va compuesta en GPU, sin reflow).
   La transition vive en el estado BASE, que es lo que la hace valer al entrar y al salir.
   El ::after es absoluto y transform no afecta al layout → no cambia ningún tamaño. */
.ga-tienda-subfiltro__btn::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 100%;                /* ancho completo desde el principio… */
    height: 2px;
    background: var(--ga-naranja-apagado);
    transform: scaleX(0);       /* …pero plegada hacia la izquierda */
    transform-origin: left;
    transition: transform var(--ga-transition-normal);
}

/* :hover y estado activo comparten el MISMO subrayado (una sola línea completa): si un
   subfiltro está seleccionado y además pasas el ratón, no se dobla ni parpadea. */
.ga-tienda-subfiltro__btn:hover::after,
.ga-tienda-subfiltro__btn.is-active::after {
    transform: scaleX(1);
}

/* CAMBIO 2: en hover el botón SOLO cambia el color del texto a dorado; nunca fondo.
   background:none (con .ga-main--tienda para ganar en especificidad) elimina el fondo
   dorado que los estilos globales de <button> aplican en la shop en hover/focus/active,
   así texto y fondo nunca coinciden en dorado y el texto sigue legible. No cambia tamaño. */
.ga-main--tienda .ga-tienda-subfiltro__btn:hover,
.ga-main--tienda .ga-tienda-subfiltro__btn:focus,
.ga-main--tienda .ga-tienda-subfiltro__btn:active {
    background: none;
}
.ga-main--tienda .ga-tienda-subfiltro__btn:hover {
    color: var(--ga-naranja-apagado);        /* solo el texto en dorado, sin fondo */
}

/* SEGUNDA LÍNEA ELIMINADA: además del fondo, los estilos globales de <button> de
   Astra/WooCommerce coloreaban el border-bottom de estos botones en :hover. Como la
   transition del botón solo lista "color" (no "border-color"), esa línea entraba de
   golpe y chocaba con el ::after animado → efecto de "dos líneas". Aquí se neutraliza
   en TODOS los estados.

   El borde NO se quita: sigue siendo de 2px transparente porque es lo que reserva el
   hueco del subrayado; con border:none el botón perdería 2px de alto y el layout daría
   un salto. Se fuerzan los dos: border:none mata cualquier borde lateral/superior que
   pudiera meter un shorthand global, y border-bottom lo devuelve a 2px transparente
   exactos, así ni el grosor ni el tamaño cambian nunca.

   Lleva !important a propósito: peleamos contra una hoja de terceros cuya
   especificidad no controlamos, y ninguna regla legítima necesita colorear este borde
   —la línea visible la pinta siempre el ::after—, así que no bloquea nada. */
.ga-main--tienda .ga-tienda-subfiltro__btn,
.ga-main--tienda .ga-tienda-subfiltro__btn:hover,
.ga-main--tienda .ga-tienda-subfiltro__btn:focus,
.ga-main--tienda .ga-tienda-subfiltro__btn:active,
.ga-main--tienda .ga-tienda-subfiltro__btn.is-active {
    border: none !important;
    border-bottom: 2px solid transparent !important;
}

.ga-tienda-subfiltro__btn.is-active {
    color: var(--ga-naranja-apagado);        /* dorado #c7a862; la línea la pinta el ::after (width:100%) */
}

/* Tarjeta oculta por el subfiltro (sin salto de scroll) */
.ga-tienda-hidden { display: none !important; }

/* ——— PARRILLA (CAMBIO 5) ———
   Reutiliza .ga-home-cards / .ga-home-card. Aquí solo reservamos
   altura para el nombre más largo → alturas de tarjeta idénticas. */
.ga-tienda-grid .ga-home-card__titulo {
    min-height: 2.6em;                      /* reserva 2 líneas de título */
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Delimitación de las tarjetas SOLO en la tienda (la home no se toca).
   Necesaria porque .ga-home-card es blanco puro y ahora el fondo es blanco.
   Borde + sombra suave siempre presentes (no cambian en hover) → sin saltos. */
.ga-tienda-grid .ga-home-card {
    border: 1px solid rgba(74, 74, 47, 0.10);
    box-shadow: var(--ga-shadow-sm);        /* 0 1px 3px rgba(74,74,47,0.12) */
}

/* ——— FILA DE ACCIONES DE LA TARJETA: carrito cuadrado + "Ver producto" ———
   Solo existe en la tienda (lo imprime ga_tienda_card), así que estas reglas no alcanzan
   a las tarjetas de la home aunque compartan la clase .ga-home-card. Vale para los tres
   formatos. Ningún estado cambia tamaños: el hover solo cambia colores. */
.ga-home-card__acciones {
    display: flex;
    align-items: stretch;                   /* el cuadrado toma el alto del botón de al lado */
    gap: var(--ga-space-xs);
    width: 100%;
    margin-top: auto;                       /* asume el empuje al fondo que tenía el botón */
}

/* Dentro de la fila, "Ver producto" ocupa el ancho restante. Sin el botón de carrito
   (productos variables/suscripción) queda solo y ocupa el 100%, como antes.
   min-width:0 evita que su texto fuerce desbordes a 360px.
   El selector va acotado a .ga-home-card__acciones —que solo imprime ga_tienda_card—,
   así que el .ga-home-card__btn de la home no se entera de nada de esto. */
.ga-home-card__acciones .ga-home-card__btn {
    flex: 1 1 auto;
    width: auto;
    min-width: 0;
    margin-top: 0;                          /* el auto lo lleva ahora la fila */
    /* SIN brillo: este botón se queda con el dorado sólido de siempre, el que hereda de
       .ga-home-card__btn. Aquí solo se ajusta cómo se reparte el espacio en la fila.
       (El degradado animado y su animation-delay de relevo que llegó a tener quedan
       retirados; el único que brilla en la tarjeta es el botón del carrito.) */
}

/* Botón de acción en VERDE OSCURO con el icono en blanco: máximo contraste sobre la
   tarjeta y contrapunto claro al dorado de "Ver producto". Mismo border-radius (5px).
   El ancho es PROPORCIONAL a la fila (28%), no cuadrado: con el 28% + el hueco de 8px,
   "Ver producto" se queda con el ~70% restante en los tres formatos. La altura la sigue
   dando align-items:stretch de la fila, así que iguala siempre al botón de al lado sin
   que haya que fijarla. */
.ga-home-card__cart {
    /* Los DOS colores del botón viven en variables locales: el degradado del brillo se
       construye a partir de ellas una sola vez, y cada estado (hover, focus, active,
       añadido) solo tiene que redefinir el par. Así el brillo sigue funcionando en todos
       los estados con el verde que toque, sin repetir el degradado cuatro veces ni
       arriesgarse a que un estado se quede sin fondo. El icono es SIEMPRE blanco: nunca
       hay un estado en el que fondo e icono coincidan. */
    --ga-cart-fondo: var(--ga-verde-oliva-oscuro);   /* #4a4a2f */
    --ga-cart-luz:   #7a7a54;                        /* el mismo oliva aclarado */

    flex: 0 0 28%;
    max-width: 28%;
    min-width: 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    border-width: 2px;
    border-style: solid;
    border-radius: 5px;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--ga-transition-fast), border-color var(--ga-transition-fast);

    /* BRILLO: mismo mecanismo que los títulos de sección (degradado de 250% de ancho,
       no-repeat, animando solo background-position) pero sobre el fondo en vez de sobre
       el texto, y en verde en lugar de dorado. El punto de luz va al 50% del degradado;
       en los extremos del recorrido queda fuera del botón, así que el reinicio del bucle
       es imperceptible. Solo se anima background-position → ni reflow ni repintado.

       A PRUEBA DE ESTILOS GLOBALES: este <a> lleva las clases de WooCommerce
       (add_to_cart_button ajax_add_to_cart), así que reglas de terceros del tipo
       `.woocommerce a.button:hover` —con más especificidad que cualquier selector de
       clase propio— pueden reescribirle fondo y color. Es el mismo problema que ya se
       documentó en .ga-tienda-novedad__btn. Por eso fondo, borde y color del icono van
       con !important en TODOS los estados: son justo las tres propiedades de las que
       depende que el icono se lea, y ningún estilo legítimo necesita cambiarlas. */
    background-color: var(--ga-cart-fondo) !important;
    border-color: var(--ga-cart-fondo) !important;
    color: var(--ga-blanco) !important;
    background-image: linear-gradient(
        100deg,
        var(--ga-cart-fondo) 0%,
        var(--ga-cart-fondo) 45%,
        var(--ga-cart-luz) 50%,
        var(--ga-cart-fondo) 55%,
        var(--ga-cart-fondo) 100%
    ) !important;
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
}

/* Ciclo del brillo del carrito, el único botón de la tarjeta que lo lleva. El barrido
   ocupa la PRIMERA MITAD (0%→50%, 4s) y la segunda se queda quieta en 0% —con el punto
   de luz ya fuera del botón por la derecha—, así que el botón brilla 4s y descansa otros
   4s: un destello espaciado en vez de un barrido continuo. Solo se anima
   background-position: ni reflow ni cambio de tamaño. */
@keyframes ga-home-card-brillo {
    0%   { background-position: 100% center; }
    50%  { background-position: 0% center; }
    100% { background-position: 0% center; }   /* pausa: le toca al otro botón */
}

/* Ahorro de movimiento: el carrito en verde sólido, sin degradado ni animación.
   ("Ver producto" ya no necesita aparecer aquí: es dorado plano en todo momento.) */
@media (prefers-reduced-motion: reduce) {
    .ga-home-card__cart {
        background-image: none !important;   /* !important porque el degradado del
                                                carrito también lo lleva (ver arriba) */
        animation: none;
    }
}

/* El icono, grande y con aire: ~28px dentro de un botón de ~68px de ancho a 360px.
   El SVG ya trae width/height en el HTML (evita el salto antes de aplicar el CSS);
   esto manda por encima para los tres formatos. flex-shrink:0 para que no lo estruje
   la caja del botón. */
.ga-home-card__cart-ico,
.ga-home-card__cart-ok {
    width: 28px;
    height: 28px;
    flex-shrink: 0;
}

/* HOVER: verde intermedio (#63663a), un escalón por encima del oliva de reposo pero
   dentro de la misma familia. Se aclara lo justo para que se note el foco del ratón sin
   perder de vista el icono blanco (contraste 5,99:1). El brillo SIGUE corriendo: al
   cambiar solo las dos variables, el degradado se recompone con el verde nuevo.
   Nunca hay fondo blanco ni transparente. Solo color: ni tamaño ni posición. */
.ga-home-card__cart:hover {
    --ga-cart-fondo: #63663a;
    --ga-cart-luz:   #8c9060;
}

/* FOCUS y ACTIVE: verde más oscuro (#3a3a22, el oliva profundo que ya usa la tienda)
   para dar sensación de pulsación. Es el estado de MÁS contraste de los cuatro
   (11,78:1), así que el icono se lee mejor que nunca. El brillo sigue activo.
   :focus-visible añade además un aro dorado para el teclado; outline no ocupa sitio en
   el layout, así que no mueve nada. */
.ga-home-card__cart:focus,
.ga-home-card__cart:active {
    --ga-cart-fondo: #3a3a22;
    --ga-cart-luz:   #5f5f3c;
}

.ga-home-card__cart:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* Mientras WooCommerce hace la petición añade la clase `loading`. */
.ga-home-card__cart.loading {
    opacity: 0.6;
}

/* Y mientras corre NUESTRA petición, el botón queda marcado con aria-disabled y
   deja de responder, para que un doble clic no añada dos unidades. El JS también
   lo comprueba por su cuenta; esto lo hace evidente a la vista y corta el clic
   antes de que llegue.

   Solo cambia la opacidad y el puntero: ni tamaño ni posición, como manda la regla
   de estados de todo el sitio. */
.ga-home-card__cart[aria-disabled="true"] {
    opacity: 0.6;
    pointer-events: none;
    cursor: default;
}

/* Estado AÑADIDO: el icono de carrito se cambia por un check y el botón pasa a verde
   claro durante 2s (la clase la pone y la quita el JS al recibir `added_to_cart`). */
.ga-home-card__cart .ga-home-card__cart-ok {
    display: none;
}
/* AÑADIDO: el verde claro de marca (--ga-verde-montanas #7f8649, el mismo que usa la
   web para "compra / éxito"). Es el más claro de los cuatro estados, así que el salto se
   nota de inmediato, y el check blanco encima mantiene 3,89:1 de contraste —por encima
   del 3:1 que pide la norma para elementos gráficos—. El brillo se para: mientras dura
   la confirmación no compite nada con ella. Se repiten los estados interactivos en el
   selector porque tras el clic el botón conserva el :focus: sin esto, focus y añadido
   empatarían en especificidad y el resultado dependería del orden. */
.ga-home-card__cart.ga-anadido,
.ga-home-card__cart.ga-anadido:hover,
.ga-home-card__cart.ga-anadido:focus,
.ga-home-card__cart.ga-anadido:active {
    --ga-cart-fondo: var(--ga-verde-montanas);
    background-image: none !important;      /* el brillo se para: la confirmación manda */
    animation: none;
}
.ga-home-card__cart.ga-anadido .ga-home-card__cart-ico {
    display: none;
}
.ga-home-card__cart.ga-anadido .ga-home-card__cart-ok {
    display: block;
}

/* WooCommerce inserta tras el botón un enlace "Ver carrito" que rompería la fila. */
.ga-home-card__acciones .added_to_cart {
    display: none;
}

/* CAMBIO 3: altura de imagen FIJA → TODAS las tarjetas de la tienda miden exactamente
   lo mismo. CAUSA de que Aceitunas de Mesa se vieran más grandes: .ga-home-card__img-wrap
   usaba solo min-height:380px y la <img> (height:100% → auto) crecía según la proporción
   de cada foto (tarros más altos = tarjetas más altas). Con height fijo, object-fit:contain
   encaja cada foto dentro del mismo recuadro. Acotado a la tienda (la home no se toca). */
.ga-tienda-grid .ga-home-card__img-wrap {
    height: 380px;                          /* recuadro fijo (antes: solo min-height:380px) */
    /* PADDING INTERIOR: sin él, una foto ALTA (la garrafa de 5L) encaja con
       object-fit:contain a exactamente 380px de alto y TOCA el borde superior e inferior
       del recuadro; como el wrap lleva overflow:hidden, el filo de la foto y el redondeo
       sub-píxel se recortan y la botella "se corta por abajo". Con este aire interior el
       área de contain mide 380 − 2×16 = 348px, así que la foto flota dentro sin llegar
       nunca al borde que recorta. box-sizing:border-box (global) hace que el padding NO
       agrande la caja: las tres columnas siguen midiendo igual. */
    padding: var(--ga-space-xs);            /* 8px (antes 16px): la mitad de aire → la foto crece hacia
                                               los lados y ocupa mejor el ancho de la tarjeta. Sigue
                                               dejando un respiro para que no toque el borde ni recorte
                                               las botellas altas por arriba/abajo. */
}
.ga-tienda-grid .ga-home-card__img {
    min-height: 0;                          /* anula el min-height:380px base → llena el ÁREA DE CONTENIDO (recuadro menos padding) vía height:100% */
    object-fit: contain;                    /* explícito: la foto entera dentro, nunca recortada */
    object-position: center;                /* si sobra aire, la foto va centrada */
}

/* ACEITUNAS DE MESA: el tarro un 6% más grande dentro del recuadro. Acotado a la SECCIÓN
   por su contenedor (#ga-tienda-aceitunas, el ancla de la sección), NO a productos
   concretos: vale para las 8 aceitunas por igual, sin IDs de producto ni slugs. Son fotos
   cuadradas, así que al ampliar el overflow:hidden del recuadro solo recorta el aire de
   los lados, nunca el tarro. Se ajusta también el hover para que no caiga al scale(1.04)
   genérico de las tarjetas de la tienda; el ~4% de zoom relativo se conserva. */
#ga-tienda-aceitunas .ga-home-card__img {
    transform: scale(1.24);                 /* +24% (antes +6%): más grande que en la home, como se pidió.
                                               Fotos cuadradas → el overflow:hidden solo recorta el aire. */
}
#ga-tienda-aceitunas .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: scale(1.29);                 /* 1.24 × ~1.04: el zoom del hover sigue contenido por el recuadro */
}

/* ——— AJUSTE DE TAMAÑO DE FOTO POR PRODUCTO · SOLO SECCIÓN ACEITE DE LA TIENDA ———
   Mismo patrón que en la home ("Nuestros Aceites"): las clases .ga-home-card--sku-* las
   genera ga_tienda_card a partir del SKU real, sin hardcodear IDs ni slugs. Acotado con
   .ga-main--tienda, así NO alcanza a las tarjetas de la home (que llevan la misma clase
   de SKU pero cuelgan de .ga-home-productos, no de .ga-main--tienda). Solo se toca la
   <img> (transform): ni el recuadro ni la tarjeta cambian de tamaño, y el overflow:hidden
   del wrap (heredado de .ga-home-card__img-wrap) mantiene el escalado dentro del marco.

   Se ajustan los DOS estados —reposo y hover— porque la regla de hover base (scale 1.04)
   gana en especificidad al reposo por SKU; si no se replicara, al pasar el ratón la foto
   saltaría al 1.04 genérico. El hover mantiene el mismo ~4% de zoom relativo. */

/* BOTELLA 500ml (GA-BELL-500-OCT): en la tienda se veía muy pequeña. Se le pone el MISMO
   escalado que ya tiene en la home ("Nuestros Aceites"): 1.35 en reposo, 1.40 en hover.
   Y, como al agrandarla queda más alta que la 2L de la tienda, se BAJA 10px con translateY
   (positivo, antes del scale → px reales; mismo valor en reposo y hover para que no salte)
   para alinear su base, igual que en la home. El overflow:hidden del recuadro contiene el
   escalado; el aire de la foto absorbe el recorte. */
.ga-main--tienda .ga-home-card--sku-ga-bell-500-oct .ga-home-card__img {
    transform: translateY(10px) scale(1.35);
}
.ga-main--tienda .ga-home-card--sku-ga-bell-500-oct .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: translateY(10px) scale(1.40);
}

/* BOTELLA 2L (GA-PET-2L-NOV): se veía más pequeña → +9% en reposo, centrada y con aire
   de sobra (el recuadro lleva 16px de padding), no toca el borde. */
.ga-main--tienda .ga-home-card--sku-ga-pet-2l-nov .ga-home-card__img {
    transform: scale(0.88);                 /* restablecido al tamaño bueno anterior a la última subida
                                               (era el que se veía bien). Escala sola centrada → base alineada. */
}
.ga-main--tienda .ga-home-card--sku-ga-pet-2l-nov .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: scale(0.92);                 /* 0.88 × ~1.04: mismo zoom relativo que las demás */
}

/* GARRAFA 5L (GA-PET-5L-NOV): el zoom del hover la desbordaba por arriba → se baja el
   reposo a 0.94, de modo que el hover (0.98) queda por debajo del 1.0 del recuadro y no
   se corta nada. translateY(-8px) para que su base quede a la misma altura que la 2L (la
   2L ampliada quedaba más alta); el mismo desplazamiento en reposo y hover para que no
   salte al pasar el ratón. translateY ANTES del scale → 8px reales. Con 0.98 de zoom hay
   de sobra margen vertical (>7px) para absorber la subida sin cortar por arriba. */
.ga-main--tienda .ga-home-card--sku-ga-pet-5l-nov .ga-home-card__img {
    transform: translateY(-2px) scale(0.94);    /* antes -8px: se baja 6px para alinear su base con la 2L. */
}
.ga-main--tienda .ga-home-card--sku-ga-pet-5l-nov .ga-home-card__img-wrap:hover .ga-home-card__img {
    transform: translateY(-2px) scale(0.98);    /* mismo desplazamiento; 0.98 < 1.0 → no se corta en hover. */
}

/* CAMBIO 3: secciones de 1 o 2 productos → MISMA tarjeta de parrilla que las
   demás secciones, centradas y sin estirar. Cada tarjeta al ancho de 1 columna
   de su breakpoint (--ga-tienda-col: 3 col escritorio · 2 col tablet/móvil).
   flex-wrap evita cualquier desbordamiento por redondeo. Sin tarjeta ancha. */
.ga-main--tienda .ga-tienda-grid--centrada {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    --ga-tienda-col: calc((100% - 2 * var(--ga-space-md)) / 3);   /* ancho de 1 de 3 columnas */
}
.ga-main--tienda .ga-tienda-grid--centrada .ga-home-card {
    flex: 0 0 var(--ga-tienda-col);
    max-width: var(--ga-tienda-col);
}

/* ——— SUBGRUPOS DENTRO DE PACKS AHORRO (CAMBIO 5) ———
   Subtítulos de MENOR jerarquía que el título de sección: Cormorant,
   más pequeños y SIN el recuadro dorado (ese es solo para los 5 títulos). */
.ga-tienda-subseccion__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);          /* menor que el título de sección (text-4xl) */
    font-weight: 600;
    color: var(--ga-verde-oliva-oscuro);
    text-align: center;
    line-height: 1.15;
    margin: 0 0 var(--ga-space-md);
}

/* Separación entre la parrilla del primer grupo y el subtítulo del segundo */
.ga-tienda-grid + .ga-tienda-subseccion__titulo {
    margin-top: var(--ga-space-lg);
}

/* Grupos de Aceitunas de Mesa: cada subcategoría se encabeza con TEXTO PLANO, alineado
   a la izquierda justo encima de sus tarjetas. Sin caja: ni fondo, ni borde, ni radius,
   ni padding. La tipografía es exactamente la de los botones de subfiltro de Aceite y
   Packs Ahorro (Inter 12px, peso 500, 0.1em de letter-spacing, mayúsculas), para que
   todos los rótulos de segundo nivel de la tienda se lean igual. Verde oscuro sólido:
   el degradado con brillo se reserva a los títulos de sección. Estático, sin animación.
   Va después de la regla base para ganarle por orden; no toca el subtítulo centrado que
   usa Packs Ahorro. No afecta al tamaño ni a la posición de las tarjetas. */
.ga-tienda-subseccion__titulo--izq {
    display: block;
    text-align: left;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);           /* 12px — igual que .ga-tienda-subfiltro__btn */
    font-weight: var(--ga-weight-medium);   /* 500 — igual que los subfiltros */
    letter-spacing: 0.1em;                  /* igual que los subfiltros */
    text-transform: uppercase;
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.3;
    margin: 0 0 var(--ga-space-md);
}

/* ——— TARJETA ANCHA DESTACADA (CAMBIO 6 y 7) ——— */
.ga-tienda-destacado {
    display: grid;
    grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
    align-items: center;
    gap: var(--ga-space-xl);
    max-width: 960px;
    margin: 0 auto;
    background: var(--ga-blanco);
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    box-shadow: var(--ga-shadow-md);
}

.ga-tienda-destacado__media {
    display: block;
    overflow: hidden;
    background: var(--ga-naranja-claro);
    height: 100%;
}

.ga-tienda-destacado__img {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 340px;
    object-fit: contain;
    transition: transform 0.4s ease;
}

.ga-tienda-destacado__media:hover .ga-tienda-destacado__img {
    transform: scale(1.04);
}

.ga-tienda-destacado__body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ga-space-sm);
    padding: var(--ga-space-lg) var(--ga-space-lg) var(--ga-space-lg) 0;
}

.ga-tienda-destacado__eyebrow {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
}

.ga-tienda-destacado__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-3xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    margin: 0;
}

.ga-tienda-destacado__titulo a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ga-transition-fast);
}

.ga-tienda-destacado__titulo a:hover {
    color: var(--ga-naranja-apagado);
}

.ga-tienda-destacado__precio {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    color: var(--ga-verde-oliva-oscuro);
}

.ga-tienda-destacado__btn {
    margin-top: var(--ga-space-xs);
}

/* Variante Apadrina — banner oscuro de marca, sin imagen (CAMBIO 7) */
.ga-tienda-destacado--apadrina {
    grid-template-columns: 1fr;
    background: var(--ga-verde-oliva-oscuro);
    padding: var(--ga-space-xl) var(--ga-space-md);
    text-align: center;
}

.ga-tienda-destacado__body--centro {
    align-items: center;
    max-width: 640px;
    margin: 0 auto;
    padding: 0;
}

.ga-tienda-destacado__eyebrow--light {
    color: var(--ga-naranja-apagado);
}

.ga-tienda-destacado__titulo--light {
    color: var(--ga-blanco);
}

.ga-tienda-destacado__texto {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    line-height: 1.7;
    color: rgba(255, 255, 255, 0.85);
    margin: 0;
}

/* ——— NOVEDADES: tarjetas grandes apiladas (SOLO esta sección) ———
   Clase propia: no toca .ga-home-card (parrilla del resto de secciones) ni
   .ga-tienda-destacado (banner de Apadrina). Foto a la izquierda e info a la derecha en
   los TRES formatos. Las columnas usan minmax(0, …) y el body min-width:0 para que el
   texto pueda encogerse: es lo que evita el desbordamiento horizontal a 360px. */
.ga-tienda-novedades {
    display: flex;
    flex-direction: column;                 /* apiladas, una debajo de otra */
    gap: var(--ga-space-lg);
}

.ga-tienda-novedad {
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
    /* stretch (antes center): con `center` cada columna se quedaba a su alto de contenido
       y se centraba, así que cuando la descripción alargaba la columna de texto, la foto
       no llegaba al final de la tarjeta. Con stretch ambas columnas miden siempre lo que
       la más alta. */
    align-items: stretch;
    gap: var(--ga-space-lg);
    width: 100%;                            /* ancho completo del contenedor de la sección */
    background: var(--ga-blanco);
    /* Marco DORADO FIJO por defecto (antes gris), del mismo dorado de marca que luce el
       de la Mermelada pero sin animación. Va en la regla base porque es la única forma de
       apuntar al Aceitunero sin recurrir a su SKU ni a su nombre: las demás tarjetas ya lo
       sobrescriben a transparent en su propia variante —--brillo y --brillo-verde, para
       que asome su degradado animado, y --merch— así que en la práctica solo lo lucen las
       tarjetas sin variante. Mismo grosor de 1px que tenía en gris. */
    border: 1px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    box-shadow: var(--ga-shadow-sm);
}

/* Registrar el color de relleno como propiedad TIPADA es lo que permite animarlo: un
   custom property sin @property es solo texto y la transición saltaría de golpe. Si el
   navegador no soporta @property, la variable sigue funcionando y el cambio de fondo
   simplemente es instantáneo en vez de suave. */
@property --ga-card-fill {
    syntax: '<color>';
    inherits: false;
    initial-value: #ffffff;
}

/* Brillo que recorre el MARCO de las tarjetas de Novedades. Reutiliza EXACTAMENTE la
   misma técnica que los títulos de sección: un degradado ancho que se desplaza con los
   @keyframes ga-tienda-titulo-brillo (6s linear). La diferencia es dónde se recorta: allí
   sobre el texto (background-clip:text), aquí sobre el borde. Se consigue con dos capas
   de fondo —la interior recortada a padding-box, que pinta el relleno de la tarjeta, y la
   del degradado recortada a border-box— más un borde transparente: el degradado solo
   asoma por el anillo de 1px. No cambia el grosor, así que la tarjeta no se mueve.

   El selector cubre ahora TODAS las tarjetas de Novedades (las que no son de
   Ediciones Limitadas), no solo la etiquetada, para que Mermelada y Aceitunero luzcan el
   mismo marco animado. Excluir --merch evita pisar su variante verde. */
.ga-tienda-novedad:not(.ga-tienda-novedad--merch) {
    --ga-card-fill: var(--ga-blanco);       /* en reposo, BLANCO */
    border-color: transparent;
    background-image:
        /* Relleno interior. Tiene que ser OPACO: si fuera semitransparente, el degradado
           del marco —que se pinta a border-box, es decir por todo el ancho— se vería
           barriendo también el interior de la tarjeta. */
        linear-gradient(var(--ga-card-fill), var(--ga-card-fill)),
        linear-gradient(
            100deg,
            var(--ga-naranja-apagado) 0%,
            var(--ga-naranja-apagado) 45%,
            #F5EEDD 50%,
            var(--ga-naranja-apagado) 55%,
            var(--ga-naranja-apagado) 100%
        );
    background-origin: padding-box, border-box;
    background-clip: padding-box, border-box;
    background-size: 100% 100%, 250% 100%;
    background-repeat: no-repeat;
    background-position: 0 0, 100% center;
    animation: ga-tienda-titulo-brillo 6s linear infinite;
    transition: --ga-card-fill var(--ga-transition-normal);
}

/* Al pasar el ratón, ESA tarjeta pasa a crema. Al ser un :hover sobre sí misma, la otra
   tarjeta no se entera y se queda en blanco. */
.ga-tienda-novedad:not(.ga-tienda-novedad--merch):hover {
    --ga-card-fill: var(--ga-naranja-claro);   /* crema #F9F6EE */
}

/* Ahorro de movimiento: marco dorado fijo, sin degradado ni animación. El fondo sigue
   siendo blanco en reposo y crema en hover, aquí ya con un background-color normal. */
@media (prefers-reduced-motion: reduce) {
    .ga-tienda-novedad:not(.ga-tienda-novedad--merch) {
        animation: none;
        background-image: none;
        background-color: var(--ga-blanco);
        border-color: var(--ga-naranja-apagado);
        transition: background-color var(--ga-transition-normal);
    }
    .ga-tienda-novedad:not(.ga-tienda-novedad--merch):hover {
        background-color: var(--ga-naranja-claro);
    }
}

/* ——— VARIANTE VERDE DEL MARCO CON BRILLO ———
   Mismo mecanismo exacto que --brillo (dos capas de fondo, la interior a padding-box y
   el degradado a border-box con el borde transparente, animando background-position con
   los mismos @keyframes ga-tienda-titulo-brillo a 6s linear). Solo cambian los colores:
   verde oscuro de marca con --ga-verde-montanas como punto de brillo, el mismo par que
   usan los títulos de sección en verde. La clase la añade el PHP según la etiqueta de
   producto "destacado-brillo-verde". */
.ga-tienda-novedad--brillo-verde {
    border-color: transparent;
    background-image:
        /* Relleno interior en kaki muy claro, opaco por el mismo motivo que en --brillo. */
        linear-gradient(#EDEEE5, #EDEEE5),
        linear-gradient(
            100deg,
            var(--ga-verde-oliva-oscuro) 0%,
            var(--ga-verde-oliva-oscuro) 45%,
            var(--ga-verde-montanas) 50%,      /* punto de brillo: verde más luminoso #7f8649 */
            var(--ga-verde-oliva-oscuro) 55%,
            var(--ga-verde-oliva-oscuro) 100%
        );
    background-origin: padding-box, border-box;
    background-clip: padding-box, border-box;
    background-size: 100% 100%, 250% 100%;
    background-repeat: no-repeat;
    background-position: 0 0, 100% center;
    animation: ga-tienda-titulo-brillo 6s linear infinite;
}

/* Ahorro de movimiento: marco verde oscuro fijo, sin degradado ni animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-tienda-novedad--brillo-verde {
        animation: none;
        background-image: none;
        background-color: #EDEEE5;
        border-color: var(--ga-verde-oliva-oscuro);
    }
}

/* Merchandising comparte la tarjeta con Novedades, así que solo se distingue por este
   modificador. Cambia ÚNICAMENTE el color de fondo (background-color, no el shorthand),
   para no tocar marco dorado, brillo, sombra ni ningún otro estilo. Va después de la
   regla base para ganarle por orden (misma especificidad). */
.ga-tienda-novedad--merch {
    /* Kaki muy claro: --ga-verde-montanas (#7f8649) al 14% sobre blanco. Distinto del
       dorado claro de la Mermelada (#F5EEDD) y del crema estándar (#F9F6EE). */
    background-color: #EDEEE5;
    /* Sin marco dorado. Transparente en vez de `border: none` para no perder el 1px
       reservado: así la tarjeta no cambia de tamaño respecto a las de Novedades. */
    border-color: transparent;
}

/* Solo aquí la foto se recorta para llenar el alto completo de la columna. Se acota a
   Merchandising: en Novedades se mantiene `contain`, que no recorta el producto. */
.ga-tienda-novedad--merch .ga-tienda-novedad__img {
    object-fit: cover;
    /* Foto a sangre SOLO aquí. El inset de 40px que comparten las demás tarjetas existe
       para que la foto empiece a la altura del rótulo "NOVEDAD" y acabe con el botón; en
       esta, con el texto corto, el alto lo marca el min-height del contenedor y ese inset
       solo dejaba 41px de kaki vacío arriba y otros 41 abajo. Con inset 0 la foto ocupa
       la tarjeta entera. Es una excepción de una línea: Mermelada y Aceitunero conservan
       intacto su inset y su alineación. */
    --ga-foto-inset: 0px;
}

/* (El eyebrow blanco de esta tarjeta se retiró: no se leía sobre el kaki claro —ratio de
   contraste ~1,2:1— y ahora directamente no se imprime desde el PHP.) */

/* Botón sólido: fondo blanco y texto verde oscuro (el mismo verde del marco y del título
   de la sección), sin rastro de dorado. Acotado a esta tarjeta, así los botones de
   Mermelada y Aceitunero conservan su dorado. El grosor del borde no cambia —lo fija la
   regla con !important de más arriba—, solo su color, así que no altera tamaños. */
/* Reposo: sólido verde oscuro con texto blanco. */
.ga-tienda-novedad--merch .ga-tienda-novedad__btn {
    background-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
    border-color: var(--ga-verde-oliva-oscuro);
}

/* ——— BRILLO ANIMADO · SOLO EL "VER PRODUCTO" DE LA CAMISETA ———
   Mismo mecanismo y mismos valores que el "Añadir al carrito" de Novedades y que el
   botón de carrito de las tarjetas: el @keyframes ga-home-card-brillo, 8s linear
   infinite, degradado a 100° con el punto de luz al 50%, background-size 250% 100%,
   no-repeat y arranque en 100% center. Lo único distinto es el color: aquí el fondo es
   el VERDE OSCURO de marca, así que la luz es #7a7a54, el mismo oliva aclarado que usa
   el botón de carrito. Se anima solo background-position → ni reflow ni cambio de
   tamaño.

   ACOTADO a esta tarjeta y a esta fila: el modificador --merch solo lo lleva la
   Camiseta, así que Mermelada y Aceitunero (que comparten el marcado
   .ga-tienda-novedad) y las tarjetas normales de la tienda se quedan como están. */
.ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__acciones .ga-tienda-novedad__btn {
    background-image: linear-gradient(
        100deg,
        var(--ga-verde-oliva-oscuro) 0%,
        var(--ga-verde-oliva-oscuro) 45%,
        #7a7a54 50%,
        var(--ga-verde-oliva-oscuro) 55%,
        var(--ga-verde-oliva-oscuro) 100%
    ) !important;
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
}

/* Hover: se vacía a blanco y el contorno verde queda a la vista. El borde conserva su
   color y grosor en los dos estados —solo cambian fondo y texto—, así que el botón no
   cambia de tamaño ni se mueve. La transición la aporta el `transition: all` de .ga-btn.

   EL BRILLO SE PAUSA AQUÍ, no se adapta. Dos motivos: el degradado verde taparía el
   fondo blanco y dejaría el texto verde oscuro ilegible sobre él; y aunque se
   recolorease la luz al blanco, un punto de luz claro barriendo un botón ya blanco no
   se vería —sería un manchón sin contraste—. El hover es un estado deliberado de botón
   vaciado, y ahí manda el contorno, no la animación. Retirar el degradado no cambia ni
   el tamaño ni la posición: solo se pinta el fondo. */
.ga-tienda-novedad--merch .ga-tienda-novedad__btn:hover,
.ga-tienda-novedad--merch .ga-tienda-novedad__btn:focus {
    background-color: var(--ga-blanco);
    color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
}

.ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__acciones .ga-tienda-novedad__btn:hover,
.ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__acciones .ga-tienda-novedad__btn:focus,
.ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__acciones .ga-tienda-novedad__btn:active {
    background-image: none !important;
    animation: none;
}

/* Ahorro de movimiento: verde sólido, sin degradado ni animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__acciones .ga-tienda-novedad__btn {
        background-image: none !important;
        animation: none;
    }
}

/* (Aquí estuvo un padding-bottom:0 en Merchandising para que el botón quedara a ras del
   borde inferior de la foto. Se retira: ahora todas las tarjetas comparten el padding
   inferior de .ga-tienda-novedad__body, de modo que el último botón siempre respira
   antes de que acabe la tarjeta. El padding va en la COLUMNA DE TEXTO, no en la tarjeta:
   así la columna de la foto sigue sin padding y llega hasta abajo. Y como ese padding
   engorda la columna de texto, la fila crece con él y `align-items: stretch` estira la
   foto en la misma medida — no hay que compensar ninguna altura de referencia. */

/* El alto va EXPLÍCITO, no con `bottom`: la <img> es un elemento reemplazado y, en
   posición absoluta, un `height:auto` toma su alto INTRÍNSECO e ignora el inset inferior
   (medido: la foto se pasaba 421px por debajo del botón). Con calc(100% − 2×inset) el
   alto sale del contenedor menos los dos insets, así el borde inferior cae exactamente
   donde acaba el botón. Lleva !important porque WooCommerce y Astra traen reglas de
   `img { height: ... }` sobre contenedores propios (0,0,1,1) que ganan a 0,0,1,0. */
.ga-main--tienda .ga-tienda-novedad__img {
    height: calc(100% - 2 * var(--ga-foto-inset)) !important;
}

/* Sin background: la foto del producto ya trae su propio fondo y una caja crema detrás
   la ensuciaba (se veía sobre todo en la Mermelada). No viene heredado de
   .ga-home-card__img-wrap — esta tarjeta no usa esa clase—, era esta misma regla. */
.ga-tienda-novedad__media {
    position: relative;                     /* referencia para la foto, que va absoluta */
    display: block;
    height: 100%;
    overflow: hidden;
    min-height: 320px;                      /* suelo: evita tarjetas diminutas con textos muy cortos */
}

/* CAUSA del hueco que sobraba abajo: estando en flujo, la <img> aportaba a la fila del
   grid su ALTO NATURAL según la proporción de la foto (una imagen 600×800 a ~493px de
   ancho pide ~657px de alto), y eso estiraba la tarjeta MUY por encima de lo que necesita
   el texto (378px medidos). No era el padding, ni el object-fit, ni que la foto fuera
   "grande": era la proporción de la propia foto mandando sobre el alto de la fila.
   Sacándola del flujo con position:absolute deja de aportar alto, así que la fila la
   marca la columna de texto. Y los insets verticales igualan el padding de esa columna,
   con lo que el borde superior de la foto cae a la altura del rótulo y el inferior a la
   del final del botón. */
.ga-tienda-novedad__img {
    --ga-foto-inset: var(--ga-space-lg);    /* = padding vertical de la columna de texto */
    position: absolute;
    top: var(--ga-foto-inset);
    left: 0;
    right: 0;
    display: block;
    width: 100%;
    min-height: 0;
    object-fit: contain;
}

.ga-tienda-novedad__body {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0;                                 /* el ritmo lo marcan los margin de cada pieza */
    padding: var(--ga-space-lg) var(--ga-space-lg) var(--ga-space-lg) 0;
    min-width: 0;                           /* deja encoger el texto → sin desbordes */
    overflow-wrap: break-word;              /* palabras largas nunca rompen el ancho */
}

/* Etiqueta de sección, discreta y pegada al título para que se lean como un bloque.
   Texto fijo ("Novedad"): no es un dato de WooCommerce. */
.ga-tienda-novedad__eyebrow {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.15em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
    margin: 0 0 var(--ga-space-xs);         /* 8px: muy cerca del título */
}

.ga-tienda-novedad__titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-3xl);
    font-weight: var(--ga-weight-bold);
    color: var(--ga-verde-oliva-oscuro);
    line-height: 1.15;
    margin: 0 0 var(--ga-space-sm);         /* 16px */
}

.ga-tienda-novedad__titulo a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ga-transition-fast);
}

.ga-tienda-novedad__titulo a:hover {
    color: var(--ga-naranja-apagado);
}

/* En Ediciones Limitadas el título NO cambia de color al pasar el ratón. Hace falta una
   regla explícita —no basta con borrar la del blanco—, porque si no la general de más
   arriba lo pondría en dorado. `inherit` lo deja en el mismo color que en reposo (el del
   contenedor .ga-tienda-novedad__titulo). Va después y con más especificidad (0,0,3,0
   frente a 0,0,2,0), así Mermelada y Aceitunero conservan su hover dorado intacto. */
.ga-tienda-novedad--merch .ga-tienda-novedad__titulo a:hover,
.ga-tienda-novedad--merch .ga-tienda-novedad__titulo a:focus {
    color: inherit;
}

.ga-tienda-novedad__desc {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    line-height: 1.7;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0;                              /* el aire alrededor del precio lo marca el propio precio */
}

.ga-tienda-novedad__desc p {
    margin: 0 0 var(--ga-space-xs);
}

.ga-tienda-novedad__desc > :last-child {
    margin-bottom: 0;
}

.ga-tienda-novedad__precio {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    color: var(--ga-verde-oliva-oscuro);
    /* MISMO aire arriba y abajo: el de arriba lo da este margin-top (la descripción va
       ya a margin:0) y el de abajo este margin-bottom, ahora que los botones no llevan
       margin-top:auto. Antes era imposible cuadrarlo: ese `auto` se comía todo el
       espacio libre y el margen inferior del precio no pintaba nada. */
    margin: var(--ga-space-sm) 0;           /* 16px arriba = 16px abajo */
}

/* get_price_html() devuelve spans, pero según el tipo de producto o los plugins puede
   venir envuelto en <p class="price">, que sí trae margen propio de WooCommerce y
   reintroduciría el hueco. Se anula desde dentro de la tarjeta, con más especificidad. */
.ga-tienda-novedad__precio p,
.ga-tienda-novedad__precio .price {
    margin: 0;
}

/* El precio de algún producto salía AZUL: su HTML incluye un <a> (lo añaden ciertos
   tipos de producto y plugins de precio) que, sin regla de color, hereda el azul por
   defecto del navegador para enlaces. Se fuerza el color de marca en el precio y en
   todo lo que cuelgue de él, incluidos los estados del enlace, así todas las tarjetas
   muestran el mismo color. El <del> del precio rebajado sigue atenuado por su opacity. */
.ga-tienda-novedad__precio,
.ga-tienda-novedad__precio * {
    color: var(--ga-verde-oliva-oscuro);
}

/* text-decoration SOLO en los enlaces. Antes iba junto al color en el selector `*`, y
   eso mataba también el line-through que WooCommerce pone en el <del> del precio
   rebajado: el precio antiguo dejaba de verse tachado. */
.ga-tienda-novedad__precio a:link,
.ga-tienda-novedad__precio a:visited,
.ga-tienda-novedad__precio a:hover,
.ga-tienda-novedad__precio a:focus {
    text-decoration: none;
}

/* Precio rebajado: el antiguo tachado y atenuado, el nuevo sin subrayado (igual que
   se ve en el resto de la tienda). */
.ga-tienda-novedad__precio del {
    opacity: 0.55;
    margin-right: var(--ga-space-xs);
    text-decoration: line-through;   /* explícito: no depender del estilo por defecto del navegador */
}

.ga-tienda-novedad__precio ins {
    text-decoration: none;
}

/* Fila de botones. flex-wrap deja que bajen solos si no caben en línea.
   margin-top:auto la ancla SIEMPRE al fondo de la columna de información (que es flex en
   columna): se coma el hueco sobrante la descripción que se coma, así el botón queda a
   la altura del borde inferior de la foto y no descolgado. */
.ga-tienda-novedad__acciones {
    display: flex;
    flex-wrap: wrap;
    gap: var(--ga-space-sm);
    width: 100%;
    /* SIN margin-top:auto. Ese `auto` absorbía todo el espacio libre de la columna y
       empujaba los botones al fondo, de modo que el hueco bajo el precio no lo marcaba
       su margen sino el sobrante de la tarjeta (medido: 235px en Mermelada, 181px en
       Aceitunero, en vez de los 8px declarados). Por eso reducir el margen del precio no
       cambiaba nada. Con margin-top:0 el hueco vuelve a depender del margen del precio y
       se puede igualar arriba y abajo. Contrapartida: los botones ya no quedan anclados
       al borde inferior de la tarjeta. */
    margin-top: 0;
}

/* CENTRADO A PRUEBA DE ESTILOS GLOBALES. El botón de carrito es un <a> que WooCommerce
   marca con .button, y en la shop el <body> lleva la clase .woocommerce, así que reglas
   como `.woocommerce a.button` (0,0,2,1) GANAN a .ga-btn (0,0,1,0) y pueden reescribir
   display y padding — por eso los intentos anteriores no cuajaron. Aquí se reafirma lo
   único que gobierna el centrado vertical: caja flex centrada y padding vertical
   simétrico. Va con !important porque peleamos contra una hoja de terceros cuya
   especificidad no controlamos, y ningún estilo legítimo necesita descentrar esto.
   El padding vertical se lee de --ga-btn-pv, así el móvil solo cambia esa variable y no
   necesita repetir los !important. No se toca line-height: con align-items:center el
   alto de la caja de línea es indiferente, y así el botón no cambia de tamaño. */
.ga-main--tienda .ga-tienda-novedad__acciones .ga-tienda-novedad__btn {
    --ga-btn-pv: 0.875rem;                  /* = el padding vertical original de .ga-btn */
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    padding-top: var(--ga-btn-pv) !important;
    padding-bottom: var(--ga-btn-pv) !important;
    /* Grosor y estilo de borde reafirmados EN REPOSO: si WooCommerce los anula
       (`.woocommerce a.button` gana a .ga-btn), colorear el borde en hover no pinta nada
       porque no hay grosor que colorear — ese era el motivo de que faltara el contorno.
       Al reservarlos ya en reposo, el hover solo cambia el COLOR: el botón no crece ni
       se mueve. 2px es el grosor de CTA del resto de la tienda (.ga-btn,
       .ga-home-card__btn). En reposo el color lo pone .ga-btn--primary (dorado, igual
       que el fondo), así que no se ve contorno hasta el hover. */
    border-width: 2px !important;
    border-style: solid !important;
    /* Esquinas redondeadas como el resto de CTA de la tienda: .ga-btn es recto
       (border-radius: 0) porque se usa en toda la web, así que se ajusta solo aquí, al
       valor de .ga-home-card__btn — el "Ver producto" de las tarjetas normales. Afecta a
       los dos botones de la tarjeta (dorado sólido y contorno), que comparten esta
       clase, y lleva !important para que WooCommerce no lo reescriba en el de carrito. */
    border-radius: 5px !important;
}

/* Color del borde EN REPOSO para el botón dorado. Hace falta porque al anular
   WooCommerce el `border`, el color cae a `currentColor` y el borde de 2px que acabamos
   de reservar se pintaría BLANCO sobre el fondo dorado (medido: rgb(255,255,255)). Con
   el dorado coincide con el fondo → no se ve contorno hasta el hover. Se acota a
   .ga-btn--primary para no pisar el contorno verde de "Ver producto" (.ga-btn--outline),
   que no lleva la clase .button y por tanto no sufre ese override. */
.ga-main--tienda .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary {
    border-color: var(--ga-naranja-apagado) !important;
}

/* HOVER igual que el resto de CTA de la tienda: fondo blanco, texto y marco dorados
   (mismos valores que .ga-product-zone__botones .ga-btn--atc:hover y que el
   .ga-home-card__btn:hover de las tarjetas). Sustituye al marrón sólido que traía
   .ga-btn--primary:hover. No cambia grosor de borde ni padding → no altera tamaños. */
.ga-main--tienda .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary:hover,
.ga-main--tienda .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary:focus {
    background-color: var(--ga-blanco) !important;
    border-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-naranja-apagado) !important;
}

/* ——— BRILLO ANIMADO DEL "AÑADIR AL CARRITO" DE NOVEDADES ———
   Mismo mecanismo, mismo @keyframes y mismos valores que el botón de carrito de las
   tarjetas normales (ga-home-card-brillo, 8s linear infinite, degradado a 100° del 250%
   de ancho, no-repeat, arrancando en 100% center): solo cambia el color, que aquí es el
   DORADO de marca con el punto de luz en un dorado más claro (#e6d0a0). Se anima
   únicamente background-position → ni reflow, ni cambio de tamaño, ni desplazamiento.

   ACOTADO A UN SOLO BOTÓN. Tres filtros encadenados:
     · .ga-btn--primary        → el "Añadir al carrito" dorado. El "Ver producto" de
                                 estas mismas tarjetas es .ga-btn--outline: queda fuera.
     · :not(--merch)           → deja fuera Ediciones Limitadas (la Camiseta), que
                                 comparte el marcado .ga-tienda-novedad.
     · .ga-tienda-novedad__…   → ningún otro botón de la web lleva estas clases.
   Va con !important en background-image por el mismo motivo que el resto de reglas de
   este botón: es un <a> con la clase .button de WooCommerce y `.woocommerce a.button`
   gana en especificidad a cualquier selector de clase propio. */
.ga-main--tienda .ga-tienda-novedad:not(.ga-tienda-novedad--merch) .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary {
    background-image: linear-gradient(
        100deg,
        var(--ga-naranja-apagado) 0%,
        var(--ga-naranja-apagado) 45%,
        #e6d0a0 50%,
        var(--ga-naranja-apagado) 55%,
        var(--ga-naranja-apagado) 100%
    ) !important;
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
}

/* En hover/focus el botón se vacía a blanco (regla de arriba): el degradado dorado lo
   taparía, así que ahí se retira y se para el barrido. Los estados existentes se quedan
   exactamente como estaban —mismos colores, mismo borde, mismo tamaño—. */
.ga-main--tienda .ga-tienda-novedad:not(.ga-tienda-novedad--merch) .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary:hover,
.ga-main--tienda .ga-tienda-novedad:not(.ga-tienda-novedad--merch) .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary:focus,
.ga-main--tienda .ga-tienda-novedad:not(.ga-tienda-novedad--merch) .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary:active {
    background-image: none !important;
    animation: none;
}

/* Ahorro de movimiento: dorado sólido, sin degradado ni animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-main--tienda .ga-tienda-novedad:not(.ga-tienda-novedad--merch) .ga-tienda-novedad__acciones .ga-tienda-novedad__btn.ga-btn--primary {
        background-image: none !important;
        animation: none;
    }
}

/* ——— CIERRE · ENLACE A APADRINA UN OLIVO ———
   Sustituye a la antigua tarjeta grande de fondo verde. Una sola línea centrada, sin
   caja, fondo, borde ni padding propio: el aire de arriba y abajo lo da el padding
   vertical de .ga-tienda-seccion__inner, común a todas las secciones. */
.ga-tienda-apadrina-linea {
    margin: 0;
    text-align: center;
}

.ga-tienda-apadrina-enlace {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);         /* tamaño de texto normal, no de título */
    color: var(--ga-verde-oliva-oscuro);
    text-decoration: none;
    transition: color var(--ga-transition-fast);
}

.ga-tienda-apadrina-enlace:hover,
.ga-tienda-apadrina-enlace:focus {
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
}

/* Aviso de categoría vacía */
.ga-tienda-vacio {
    text-align: center;
    font-family: var(--ga-font-body);
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.6;
    padding: var(--ga-space-lg) 0;
}

/* =============================================================
   PÁGINA TIENDA — RESPONSIVE (tablet · móvil · ajustes finos)
   Todo dentro de media queries → el ESCRITORIO NO cambia.
   Acotado a .ga-main--tienda para NO afectar a la home (.ga-home-card).

   Altos de cabecera (header.php + variables):
     · escritorio y tablet (>768px): --ga-nav-height = 80px
     · móvil (<=768px):              --ga-nav-height = 64px
   .ga-tienda-nav usa top:var(--ga-nav-height) y las secciones
   scroll-margin-top: calc(var(--ga-nav-height) + 60px), así que la barra
   queda a 80/64px y el scroll-margin a 140/124px según breakpoint, solos.
   ============================================================= */

/* ——— TABLET (<=1024px) ——— */
@media (max-width: 1024px) {

    /* CAMBIO 2 — parrilla a 2 columnas. Mayor especificidad que .ga-home-cards,
       así anula el 3-col base y (en <=768) el 1-col + max-width:380px de la home. */
    .ga-main--tienda .ga-tienda-grid {
        grid-template-columns: repeat(2, 1fr);
        max-width: none;
        gap: var(--ga-space-md);
    }

    /* CAMBIO 3: en tablet, cada tarjeta centrada al ancho de 1 de 2 columnas
       (gap = space-md). Con 2 productos llenan la fila; con 1, queda centrada. */
    .ga-main--tienda .ga-tienda-grid--centrada {
        --ga-tienda-col: calc((100% - var(--ga-space-md)) / 2);
    }

    /* CAMBIO 5 — menos aire vertical */
    .ga-main--tienda .ga-tienda-seccion__inner {
        padding: var(--ga-space-md) var(--ga-space-md);   /* igual que escritorio: 24px (antes 40px) */
    }
    /* CAMBIO 1: padding vertical simétrico (antes space-lg=40px arriba / space-md=24px
       abajo) → "Tienda" centrada verticalmente en su banda también en tablet. */
    .ga-main--tienda .ga-tienda-header {
        padding: 0 var(--ga-space-md);      /* CAMBIO 1: solo horizontal; el vertical lo gobierna flex+min-height */
    }
}

/* ——— MÓVIL (<=768px) ——— */
@media (max-width: 768px) {

    /* CAMBIO 1 — barra de categorías: scroll horizontal en UNA sola línea.
       Mismo patrón que la home: flex-basis explícito (flex:0 0 auto), NUNCA
       min-width; overflow contenido en la propia barra; scrollbar oculta pero
       arrastrable con el dedo. La barra sigue fija (top se hereda de la variable). */
    .ga-main--tienda .ga-tienda-nav__lista {
        justify-content: flex-start;
        gap: var(--ga-space-md);
        padding: 0 var(--ga-space-sm);
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;            /* Firefox */
        -ms-overflow-style: none;         /* Edge/IE antiguos */
    }
    .ga-main--tienda .ga-tienda-nav__lista::-webkit-scrollbar {
        display: none;                    /* Chrome/Safari */
    }
    .ga-main--tienda .ga-tienda-nav__lista li {
        flex: 0 0 auto;                   /* no encoge; ancho = texto */
    }

    /* CAMBIO 3 — títulos de sección (píldoras): caben en una línea.
       nowrap + clamp() para que "Aceitunas de Mesa"/"Merchandising" encojan
       en pantallas estrechas SIN cortar el texto. */
    /* Los CINCO títulos de sección al mismo tamaño en móvil, el que ya tenía Aceite.
       Se levanta el white-space:nowrap: con este cuerpo los más largos ("Aceitunas de
       Mesa", "Ediciones Limitadas") pueden partir en dos líneas en vez de encogerse. */
    .ga-main--tienda .ga-tienda-seccion__titulo {
        white-space: normal;
        font-size: clamp(1.75rem, 8.5vw, var(--ga-text-4xl));
    }
    /* CAMBIO 2: "Aceite de Oliva Virgen Extra" es largo; en móvil encoge más
       (5vw en vez de 6.2vw) para caber en una línea dentro del recuadro a 360px,
       sin cortar el texto. Hereda white-space:nowrap de la regla anterior. */
    .ga-main--tienda .ga-tienda-seccion__titulo--largo {
        font-size: clamp(1.05rem, 5vw, var(--ga-text-4xl));
    }
    .ga-main--tienda .ga-tienda-subseccion__titulo {
        font-size: clamp(1.2rem, 5vw, var(--ga-text-2xl));
    }

    /* CAMBIO 3 — botones de cosecha: si no caben, scroll horizontal (mismo
       patrón que la barra). El subrayado sigue reservado → nada se descoloca. */
    .ga-main--tienda .ga-tienda-subfiltro {
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -ms-overflow-style: none;
    }
    .ga-main--tienda .ga-tienda-subfiltro::-webkit-scrollbar {
        display: none;
    }
    .ga-main--tienda .ga-tienda-subfiltro__btn {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* CAMBIO 4 — tarjetas anchas: apilar en vertical sin desbordar */
    .ga-main--tienda .ga-tienda-destacado {
        grid-template-columns: 1fr;
    }
    .ga-main--tienda .ga-tienda-destacado__img {
        min-height: 240px;
    }
    .ga-main--tienda .ga-tienda-destacado__body {
        padding: var(--ga-space-md);
        align-items: center;
        text-align: center;
    }
    .ga-main--tienda .ga-tienda-destacado--apadrina {
        padding: var(--ga-space-lg) var(--ga-space-md);
    }

    /* NOVEDADES (Mermelada, Aceitunero) y EDICIONES LIMITADAS (Camiseta) en móvil: se APILAN
       como las tarjetas normales (.ga-home-card) — foto completa arriba, luego título,
       precio y botones — en vez del formato grande de foto a un lado. Se ocultan el eyebrow
       y la descripción larga (siguen visibles en escritorio, no se borran del PHP). Al ser
       una columna vertical NO hay fila más ancha que el viewport → no se infla. */
    .ga-main--tienda .ga-tienda-novedades {
        gap: var(--ga-space-md);
    }
    .ga-main--tienda .ga-tienda-novedad {
        display: flex;                 /* de grid (2 columnas) a columna vertical */
        flex-direction: column;
        gap: 0;
    }

    /* Foto ARRIBA, en flujo y completa (ya no absoluta como en el formato grande),
       igual que .ga-home-card__img-wrap: alto automático + object-fit:contain → sin recorte. */
    .ga-main--tienda .ga-tienda-novedad__media {
        position: static;
        height: auto;
        min-height: 0;
        width: 100%;
    }
    .ga-main--tienda .ga-tienda-novedad__img,
    .ga-main--tienda .ga-tienda-novedad--merch .ga-tienda-novedad__img {
        position: static;
        height: auto !important;       /* anula el calc(...) !important del formato grande */
        width: 100%;
        min-height: 0;
        object-fit: contain;           /* completa, sin recortar (también en la Camiseta) */
    }

    /* Cuerpo centrado, como las tarjetas normales. */
    .ga-main--tienda .ga-tienda-novedad__body {
        align-items: center;
        text-align: center;
        width: 100%;
        padding: var(--ga-space-sm);
        gap: 0;
    }

    /* Ocultar en móvil lo propio del formato destacado que no aplica en tarjeta pequeña:
       el eyebrow ("NOVEDAD") y la descripción larga. Siguen en el PHP, solo ocultos aquí. */
    .ga-main--tienda .ga-tienda-novedad__eyebrow,
    .ga-main--tienda .ga-tienda-novedad__desc {
        display: none;
    }

    .ga-main--tienda .ga-tienda-novedad__titulo {
        font-size: var(--ga-text-lg);
        line-height: 1.25;
        margin: 0 0 var(--ga-space-xs);
    }
    .ga-main--tienda .ga-tienda-novedad__precio {
        font-size: var(--ga-text-lg);
        margin: 0 0 var(--ga-space-sm);
    }

    /* Botones ABAJO, apilados a todo el ancho (Mermelada/Aceitunero: 2 botones; Camiseta: 1).
       Se permite que el texto parta en dos líneas para que a 360px nunca se corte. */
    .ga-main--tienda .ga-tienda-novedad__acciones {
        flex-direction: column;
        align-items: stretch;
        gap: var(--ga-space-xs);
    }
    .ga-main--tienda .ga-tienda-novedad__btn {
        width: 100%;
        justify-content: center;
        text-align: center;
        padding: 0.7rem 0.75rem;
        --ga-btn-pv: 0.7rem;                /* el vertical lo aplica la regla con !important */
        font-size: var(--ga-text-xs);
        letter-spacing: 0.05em;
        white-space: normal;
    }

    /* CAMBIO 2 — imágenes de tarjeta menos altas en 2-col estrecho (todas iguales).
       RECUADRO FIJO también en móvil, para que todas las tarjetas midan lo mismo (la
       parrilla no puede quedar escalonada). Antes esto estaba en height:auto para evitar
       el recorte de la garrafa, pero eso dejaba cada tarjeta de una altura distinta.
       Ahora se resuelve el recorte como en escritorio —object-fit:contain (NUNCA recorta)
       + padding interior— y así se recupera la altura fija sin cortar ninguna foto: la
       botella flota dentro del recuadro con aire alrededor, sin tocar el borde que
       recorta. Solo afecta a la parrilla normal (.ga-home-card dentro de .ga-tienda-grid);
       las tarjetas grandes de Novedades y Ediciones Limitadas usan .ga-tienda-novedad__img
       y no entran aquí. */
    .ga-main--tienda .ga-tienda-grid .ga-home-card__img-wrap {
        height: 300px;                         /* recuadro fijo y común a todas las tarjetas */
        min-height: 0;                         /* anula el min-height:380px base */
        padding: var(--ga-space-xs);           /* 8px (antes 12px): menos aire → foto más grande, con
                                                  respiro suficiente para no tocar el borde. */
        background-color: var(--ga-blanco);    /* el aire alrededor, en blanco */
    }
    .ga-main--tienda .ga-tienda-grid .ga-home-card__img {
        height: 100%;                          /* llena el área de contenido (recuadro menos padding) */
        min-height: 0;
        object-fit: contain;                   /* foto entera dentro → nada se recorta */
        object-position: center;
    }

    /* CAMBIO 5 — compactar el aire vertical en móvil */
    /* ——— CABECERA: QUE QUEPA SIEMPRE (solo móvil, solo la tienda) ———
       A ~356px el conjunto logo + iconos de .ga-nav__actions no cabía en el ancho útil
       (356 − 48px de padding = 308px) y, al no poder encogerse los hijos flex, empujaba
       el bloque de iconos fuera del viewport: eso es lo que arrastraba el scroll
       horizontal de TODA la página, no los carruseles.
       Acotado a body.woocommerce-shop para no alterar la cabecera de la home, tal y como
       pediste; la causa, sin embargo, es común a todo el sitio (ver nota al entregar). */
    body.woocommerce-shop .ga-nav__inner {
        padding: 0 var(--ga-space-sm);        /* 16px en vez de 24px → 16px más de ancho útil */
        gap: var(--ga-space-sm);              /* 16px en vez de 24px entre logo, menú e iconos */
        max-width: 100%;
    }

    /* Sin min-width:0 un hijo flex nunca baja de su tamaño mínimo de contenido: por eso
       desbordaba en lugar de comprimirse. */
    body.woocommerce-shop .ga-nav__inner > * {
        min-width: 0;
    }

    /* El logo es quien cede espacio; los iconos son la acción útil y no se deforman. */
    body.woocommerce-shop .ga-nav__logo {
        flex: 0 1 auto;
        min-width: 0;
    }
    body.woocommerce-shop .ga-nav__logo img {
        max-width: 100%;
        height: auto;
    }
    body.woocommerce-shop .ga-nav__actions {
        flex: 0 0 auto;
        gap: var(--ga-space-xs);              /* 8px entre iconos en vez de 16px */
    }

    /* Nombre de usuario junto al icono de cuenta: no lo imprime header.php (lo añade otro
       código), es de ancho impredecible y en móvil no aporta nada. Fuera. */
    body.woocommerce-shop .ga-header .display-name {
        display: none;
    }

    /* (Se retiró un overflow-x:hidden sobre .ga-header que se probó como red de seguridad y
       NO servía: un position:fixed solo lo recorta su bloque contenedor, no un ancestro
       cualquiera. La causa real —el will-change de la cabecera— ya está corregida arriba.) */

    /* ——— BARRA DE CATEGORÍAS: ENTERA, EN DOS LÍNEAS (solo móvil) ———
       Sustituye al scroll horizontal, que se mantiene en tablet (regla del bloque
       <=1024px), donde los botones sí caben deslizando. Aquí envuelven a dos filas para
       verse todos de golpe. Medido a 360px: fila 1 = Aceite · Aceituna de Mesa · Packs
       Ahorro; fila 2 = Novedades · Ediciones Limitadas; alto total 87px, sin
       desbordamiento horizontal.
       Al desaparecer el scroll, la función del JS que centra el botón activo se desactiva
       sola: arranca con `if (lista.scrollWidth <= lista.clientWidth + 1) return`, que aquí
       se cumple siempre. Queda inerte sin tocar el JS. */
    :root {
        /* Alto real con dos filas. Lo usa el scroll-margin-top de las secciones, así que
           mantenerlo al día evita que las anclas queden bajo la barra. */
        --ga-tienda-bar-height: 92px;
    }
    .ga-main--tienda .ga-tienda-nav {
        height: auto;                     /* no recorta aunque un nombre de categoría crezca */
    }
    .ga-main--tienda .ga-tienda-nav__lista {
        flex-wrap: wrap;
        justify-content: center;          /* las dos filas, centradas */
        align-items: center;
        height: auto;
        /* CORTAFUEGOS, no scroll: con flex-wrap el contenido ya envuelve, pero si algún
           día un rótulo no cupiera se recorta AQUÍ en vez de derramarse y arrastrar scroll
           horizontal de toda la página. Sustituye al `visible` anterior, que al quitar el
           scroll heredado dejaba la barra sin ninguna red. El subrayado del enlace activo
           (::after a bottom:-2px) queda dentro de los 8px de padding, así que no se corta. */
        overflow-x: hidden;
        gap: var(--ga-space-xs) var(--ga-space-sm);
        padding: var(--ga-space-xs) 0.75rem;   /* lateral algo menor que space-sm: gana un paso de letra */
    }
    .ga-main--tienda .ga-tienda-nav__link {
        /* Máximo tamaño que mantiene el reparto en DOS filas a 360px, medido en navegador
           con Inter realmente cargada: a 0.82rem los botones ya saltan a tres filas.
           Ojo si algún día se renombra una categoría a un nombre más largo: el reparto se
           recalcularía y podría pasar a tres filas (no desbordaría, solo crecería el alto). */
        font-size: 0.8rem;                /* 12,8px */
        letter-spacing: 0.06em;           /* menos tracking = cabe más por línea */
    }

    /* ——— SECCIÓN ACEITE EN MÓVIL ———
       Se acota con el id de la sección, que es el único identificador que distingue
       Aceite de las demás (Packs Ahorro también tiene subfiltro y debe conservarlo). */

    /* 1 · Título con más presencia. Se levanta el white-space:nowrap heredado para que
       pueda partir en dos líneas en vez de encogerse hasta caber en una. */
    #ga-tienda-aceite .ga-tienda-seccion__titulo {
        white-space: normal;
        font-size: clamp(1.75rem, 8.5vw, var(--ga-text-4xl));
    }

    /* 2 · Fuera el subfiltro de cosecha en móvil. */
    #ga-tienda-aceite .ga-tienda-subfiltro {
        display: none;
    }

    /* 3 · CARRUSEL horizontal, con el mismo mecanismo que el de la home
       (.ga-proceso__carrusel-wrap): scroll-snap nativo, sin flechas, con puntos.
       El orden 500ml → 2L → 5L lo fija la WP_Query por precio ascendente y el carrusel
       respeta el orden del DOM, así que no hay nada que reordenar.
       El track lleva su propio overflow-x, de modo que desborda hacia dentro y nunca
       provoca scroll horizontal de la página. */
    /* Se aplica a Aceite y a los TRES grupos de Aceitunas de Mesa. Los grupos no tienen id
       propio (los imprime ga_tienda_render_grupo sin grid_id), así que se seleccionan por
       el id de su sección: cada .ga-tienda-grid de dentro es un carrusel independiente. */
    /* Packs Ahorro en móvil: sin "Todos" (el filtro se reduce a los dos grupos reales) y
       los dos botones restantes centrados, anulando el flex-start con scroll horizontal
       que heredan los subfiltros en este breakpoint. */
    #ga-tienda-packs .ga-tienda-subfiltro__btn[data-filtro="todos"] {
        display: none;
    }
    #ga-tienda-packs .ga-tienda-subfiltro {
        justify-content: center;
        flex-wrap: wrap;
        /* Mismo cortafuegos que en la barra de categorías. */
        overflow-x: hidden;
        /* Este contenedor no tenía padding vertical, y el subrayado del botón activo vive
           2px por DEBAJO de su caja: sin esto, el recorte se lo comería. */
        padding-bottom: 2px;
    }

    /* En móvil el botón de aceituna muestra la variante CORTA ("Packs de Aceitunas") en
       vez del nombre largo de la categoría, para que quepa mejor en la barra a dos líneas. */
    .ga-tienda-subfiltro__txt--largo {
        display: none;
    }
    .ga-tienda-subfiltro__txt--corto {
        display: inline;
    }

    /* CAUSA RAÍZ del viewport inflado (localizada por bisección): overflow-x:auto solo
       CONTIENE si el contenedor puede encoger hasta el ancho disponible. El track y sus
       ancestros tenían min-width:auto por defecto = su min-content = la fila entera de
       tarjetas; si Astra envuelve el contenido en un flex/grid, ninguno podía bajar de ahí,
       así que en vez de scrollear se ensanchaba el documento y el móvil reducía el zoom
       (viewport 360→~800). min-width:0 en TODA la cadena rompe esa propagación (mismo
       patrón que ya usa el resto del CSS). Le pusimos min-width:0 a las tarjetas, pero
       faltaba en el track y en los ancestros. */
    .ga-main--tienda,
    .ga-main--tienda .ga-tienda-seccion,
    .ga-main--tienda .ga-tienda-seccion__inner {
        min-width: 0;
    }

    /* CARRUSEL POR TRANSFORM (opción A). El scroll nativo (overflow-x:auto) inflaba el
       viewport de maquetación del móvil porque la fila de tarjetas cuenta como ancho REAL
       aunque el track la contuviera visualmente (probado: fila → innerWidth 804; apiladas →
       360). Solución: el grid es un VIEWPORT con overflow:hidden que RECORTA la fila (no
       crea contenedor de scroll → no infla), y el desplazamiento se hace moviendo un carril
       interior con transform:translateX vía JS (un transform NO amplía el ancho del layout). */
    #ga-tienda-aceite .ga-tienda-grid,
    #ga-tienda-aceitunas .ga-tienda-grid,
    #ga-tienda-packs .ga-tienda-grid {
        display: block;
        /* `clip` en vez de `hidden` por el mismo motivo que en las secciones: recorta
           exactamente igual, pero NO convierte el grid en contenedor de scroll, así que un
           dedo apoyado sobre una tarjeta tampoco se queda atrapado aquí y el gesto vertical
           llega al documento. El eje Y se queda en `visible`, que es lo que había de facto:
           el carril nunca desborda por arriba ni por abajo. */
        overflow: clip;
        width: 100%;
        max-width: 100%;
        min-width: 0;
        padding-bottom: 0.5rem;
    }

    /* Navegadores sin `clip` (iOS Safari < 16): se quedan con el hidden de siempre. */
    @supports not (overflow: clip) {
        #ga-tienda-aceite .ga-tienda-grid,
        #ga-tienda-aceitunas .ga-tienda-grid,
        #ga-tienda-packs .ga-tienda-grid {
            overflow: hidden;
        }
    }

    /* CARRIL: la pista que se mueve. Lo crea el JS envolviendo las tarjetas. Es block-level
       display:flex → mide el 100% del viewport, así que el 85% de cada tarjeta se calcula
       sobre el viewport; las 3 tarjetas desbordan el carril y el grid (overflow:hidden) las
       recorta. Sin scroll → sin inflado. */
    .ga-main--tienda .ga-tienda-carril {
        display: flex;
        flex-direction: row;
        gap: var(--ga-space-sm);
        transform: translateX(0);
        transition: transform var(--ga-transition-normal);
        will-change: transform;
        /* El gesto VERTICAL es del navegador (scroll de la página) mientras no se decide; en
           cuanto el JS confirma que el gesto es HORIZONTAL, el carrusel BLOQUEA el eje
           (preventDefault en touchmove) para que la página no salte en vertical al deslizar de
           lado. `pinch-zoom` se mantiene para no quitarle al usuario el zoom con dos dedos. */
        touch-action: pan-y pinch-zoom;
    }
    .ga-main--tienda .ga-tienda-carril.is-dragging {
        transition: none;      /* durante el arrastre, el carril sigue al dedo sin suavizado */
    }
    #ga-tienda-aceite .ga-tienda-grid::-webkit-scrollbar,
    #ga-tienda-aceitunas .ga-tienda-grid::-webkit-scrollbar,
    #ga-tienda-packs .ga-tienda-grid::-webkit-scrollbar {
        display: none;                        /* Chrome/Safari */
    }

    /* Ancho en % DEL CONTENEDOR, nunca en vw. La unidad vw referencia el VIEWPORT: con
       3 tarjetas a 80vw = 240vw, si algo desbordaba, el navegador móvil reducía el zoom
       (shrink-to-fit) para que cupiera, inflando el viewport de maquetación (360→827); y
       como vw se recalcula sobre ese viewport ya inflado, se realimentaba. El % se calcula
       sobre el track (ancho real del dispositivo − 32px de padding del inner), así que NO
       puede realimentar el inflado. 85% (no 80%) porque el track es algo más estrecho que
       el viewport: 85% deja la tarjeta y el asomo de la siguiente casi como el 80vw previo.
       scroll-snap-align:start encaja cada tarjeta a la izquierda; el asomo cae a la derecha;
       scroll-snap-stop:always, una tarjeta por gesto. */
    #ga-tienda-aceite .ga-tienda-grid .ga-home-card,
    #ga-tienda-aceitunas .ga-tienda-grid .ga-home-card,
    #ga-tienda-packs .ga-tienda-grid .ga-home-card {
        flex: 0 0 85%;
        max-width: 85%;
        min-width: 0;      /* corta la propagación del min-content: sin esto, min-width:auto
                              (el defecto de un ítem flex) equivale al min-content del
                              contenido —imagen/título de WooCommerce— y ANULA el max-width,
                              ensanchando la tarjeta. Sigue siendo necesario con % igual que
                              con vw. Mismo patrón que la home (.ga-apadrina-plan-card). */
        scroll-snap-align: start;
        scroll-snap-stop: always;
    }

    /* CINTURÓN a nivel de página: recorta cualquier fuga horizontal del carrusel (respaldo
       del min-width:0 de arriba, por si el min-content de lo que renderice WooCommerce lo
       volviera a vencer). Se usa overflow-x: CLIP, no hidden, a propósito: clip NO crea un
       contenedor de scroll, así que NO rompe la barra de categorías sticky (.ga-tienda-nav);
       hidden en el main sí la rompería. Los carruseles siguen deslizándose por su propio
       overflow-x:auto interno. */
    .ga-main--tienda {
        overflow-x: clip;
    }
    /* Respaldo para navegadores sin `overflow: clip` (iOS Safari < 16, Chrome < 90): ahí el
       clip de arriba se ignora y el recorte lo hacen las SECCIONES. Es seguro porque
       .ga-tienda-nav (la barra sticky) es HERMANA de las secciones, no descendiente, así que
       recortar en la sección no la afecta; en el main sí.

       🔴 AQUÍ ESTABA EL BLOQUEO DE SCROLL EN ANDROID. Antes esto era `overflow-x: hidden`,
       y `hidden` en un solo eje NO se queda en un eje: por especificación, si un eje es
       `visible` y el otro no es ni `visible` ni `clip`, el `visible` pasa a valer `auto`.
       Es decir, cada sección se convertía en un CONTENEDOR DE SCROLL VERTICAL sin nada que
       scrollear. Como las secciones cubren toda la página, cualquier dedo apoyado caía
       dentro de una, Chrome de Android la elegía como destino del gesto y —con el
       `overscroll-behavior-y: contain` que lleva el body de la tienda— se negaba a encadenar
       el desplazamiento al documento: la página no se movía. iOS no aplica esa restricción
       de encadenado igual, y la home no tiene ninguna de las dos reglas; de ahí que solo
       fallara en Android y solo en la tienda. El scroll por JS de la barra de categorías
       seguía funcionando porque no depende del destino táctil.

       `clip` recorta exactamente igual pero NO crea contenedor de scroll, así que el eje
       vertical se queda en `visible` y el gesto vuelve a ser de la página. */
    .ga-main--tienda .ga-tienda-seccion {
        overflow-x: clip;
    }

    /* Solo para navegadores sin soporte de `clip`, donde no hay alternativa. Son
       precisamente los que no sufren el problema (iOS Safari < 16). */
    @supports not (overflow: clip) {
        .ga-main--tienda .ga-tienda-seccion {
            overflow-x: hidden;
        }
    }

    /* Puntos indicadores: mismo aspecto y comportamiento que .ga-proceso__dot de la home.
       Los genera el JS a partir del número de tarjetas, así el PHP no cambia. */
    .ga-tienda-dots {
        display: flex;
        justify-content: center;
        gap: 0.5rem;
        margin-top: 0.75rem;
        padding: 0;
        border: none;
        background: none;
    }
    .ga-tienda-dot {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: rgba(74, 74, 47, 0.2);
        border: none;
        padding: 0;
        cursor: pointer;
        transition: background 0.25s ease, transform 0.25s ease;
    }
    .ga-tienda-dot.is-active {
        background: var(--ga-naranja-apagado);
        transform: scale(1.5);
    }

    /* Al insertar el JS los puntos entre una parrilla y el subtítulo del grupo siguiente,
       el selector hermano `.ga-tienda-grid + .ga-tienda-subseccion__titulo` deja de casar
       y ese subtítulo perdería su separación superior. Se le devuelve aquí. */
    .ga-tienda-dots + .ga-tienda-subseccion__titulo {
        margin-top: var(--ga-space-lg);
    }

    /* Y garantía de que SIEMPRE se ven las tres, quedara como quedara el filtro: esta
       regla revierte el .ga-tienda-hidden que aplica el JS del subfiltro. Necesita
       !important porque .ga-tienda-hidden también lo lleva, y gana por especificidad
       (0,1,2,0 frente a 0,0,1,0). Al ser CSS dentro del media query, responde solo al
       cambiar de tamaño la ventana: no depende de que el JS se entere. */
    #ga-tienda-aceite .ga-home-card.ga-tienda-hidden {
        display: flex !important;
    }

    .ga-main--tienda .ga-tienda-seccion__inner {
        padding: var(--ga-space-md) var(--ga-space-sm);
    }
    .ga-main--tienda .ga-tienda-seccion__header {
        margin-bottom: var(--ga-space-md);
    }
    /* FRANJA DESLIZABLE BAJO EL FOOTER. No la causa ningún margen ni elemento del tema:
       tras </footer> solo va wp_footer(), .ga-footer no tiene margin, el último elemento
       (.ga-tienda-apadrina-linea) va a margin:0 y no hay min-height/100vh en body ni main.
       Lo que se ve ahí es el fondo del <body> (crema #F9F6EE, que junto al verde del footer
       se lee como blanco), destapado por el REBOTE DE SCROLL del móvil (overscroll). Con
       overscroll-behavior-y: contain el documento deja de rebotar más allá de su final, así
       que no queda nada que deslizar bajo el footer.
       NO se cambia el color del body: tiene que seguir siendo crema para el hueco que el
       padding-top reserva bajo la cabecera fija (si fuera verde, asomaría verde ahí arriba). */
    /* 🔴 CAUSA DEL SCROLL BLOQUEADO EN ANDROID — aquí estaba, y era esta misma regla.
       Antes ponía `overscroll-behavior-y: contain` sobre el BODY. El problema es que el
       body de este tema NO es un elemento normal: lleva `overflow-x: hidden` (main.css:49,
       el cortafuegos anti-scroll horizontal), y `hidden` en un eje obliga al otro a valer
       `auto`. Medido: el body resuelve a overflow-y:auto → ES un contenedor de scroll,
       pero su scrollHeight y su clientHeight coinciden (2644 = 2644) → no tiene NADA que
       scrollear. Con `contain` encima, se le está diciendo al navegador "no encadenes el
       desplazamiento hacia arriba": el dedo cae siempre dentro del body, Chrome de Android
       lo elige como destino del gesto, no puede moverse y se niega a pasarle el turno al
       viewport. Resultado: la página no scrollea. Encaja con los cuatro síntomas —solo en
       la tienda (la regla está acotada a .woocommerce-shop), solo en Android (Safari no
       soporta overscroll-behavior hasta la 16 y no aplica igual el bloqueo de encadenado),
       la home intacta, y el scroll por JS de la barra de categorías seguía funcionando
       porque mueve el viewport directamente, sin pasar por el destino táctil.

       La misma protección va ahora sobre la RAÍZ. En el elemento raíz, overscroll-behavior
       SÍ se propaga al viewport (el body no: la especificación lo excluye expresamente), y
       el viewport sí puede scrollear, así que corta el rebote sin poder bloquear nada.
       Si el navegador no entiende :has(), simplemente se queda sin el retoque cosmético. */
    html:has(body.woocommerce-shop) {
        overscroll-behavior-y: contain;
    }

    .ga-main--tienda .ga-tienda-header {
        padding: 0 var(--ga-space-sm);      /* CAMBIO 1: solo horizontal (el vertical lo gobierna flex+min-height) */
    }
    /* Sube "Tienda" unos píxeles dentro de su banda, SOLO en móvil. Se usa transform y no
       margin/padding a propósito: un transform es puramente visual, no altera el flujo ni
       el alto de la banda ni empuja nada de lo que hay debajo. No se toca el min-height,
       ni los paddings, ni el centrado flex de la banda. */
    .ga-main--tienda .ga-tienda-header__titulo {
        transform: translateY(-11px);
    }
    .ga-main--tienda .ga-tienda-grid {
        gap: var(--ga-space-sm);
    }
    /* CAMBIO 3: en móvil, tarjeta centrada al ancho de 1 de 2 (gap = space-sm) */
    .ga-main--tienda .ga-tienda-grid--centrada {
        --ga-tienda-col: calc((100% - var(--ga-space-sm)) / 2);
    }
}

/* ——— AJUSTES FINOS (<=600px) ——— */
@media (max-width: 600px) {

    /* CAMBIO 2 — garantizar que el nombre más largo cabe en 2 columnas a 360px:
       bajar un punto el título de tarjeta (sigue reservando 2 líneas: min-height en em). */
    .ga-main--tienda .ga-tienda-grid .ga-home-card__titulo {
        font-size: clamp(0.9rem, 3.4vw, 1.1rem);
    }
    .ga-main--tienda .ga-tienda-grid {
        gap: 0.75rem;
    }
    /* CAMBIO 3: idem con el gap fino de <=600 */
    .ga-main--tienda .ga-tienda-grid--centrada {
        --ga-tienda-col: calc((100% - 0.75rem) / 2);
    }
}



/* ==========================================================================
   PANTALLAS MUY ESTRECHAS (<=380px) — SOLO TIENDA
   --------------------------------------------------------------------------
   Este bloque nació para que la fila de enlaces legales del footer reducido
   cupiera en UNA sola línea: con CUATRO etiquetas (Aviso Legal · Privacidad ·
   Cookies · Condiciones de Venta) pedía 306,4px de los 320px libres —el ancho
   del bottom-inner menos sus 20px de padding a cada lado—, así que bastaba con
   recortar el tamaño de letra y el gap para que entrara sin saltar.

   🔴 CON CINCO ETIQUETAS ESO YA NO ES POSIBLE. Al añadir "Preferencias de
   cookies" la fila pasa a pedir unos 429px, y prohibirle el salto no la hace
   caber: la obliga a desbordar. Una fila más ancha que el viewport INFLA el
   viewport de maquetación en móvil aunque overflow-x la contenga —es la trampa
   nº 1 del claude.md, la que anuló todos los media queries de la tienda—, así
   que el nowrap pasa a ser justo lo contrario de una protección.

   Se le devuelve el salto de línea. Lo que SÍ se conserva es el recorte de
   tamaño y el gap fino, que siguen siendo útiles: con ellos las cinco etiquetas
   caben holgadas en dos líneas. El resto del footer (padding del bottom-inner,
   línea de copyright) no se toca, y por encima de 380px no cambia nada.
   ========================================================================== */
@media (max-width: 380px) {

    body.woocommerce-shop .ga-footer__legal-nav {
        flex-wrap: wrap;            /* puede saltar de línea: con 5 etiquetas es obligatorio */
        /* Dos valores: el primero separa las LÍNEAS entre sí (con una sola fila
           no se notaba, ahora sí), el segundo las etiquetas dentro de cada una. */
        gap: 0.4rem 0.28rem;
        max-width: 100%;
        min-width: 0;               /* corta la propagación del min-content del flex */
        justify-content: center;
    }

    /* Enlaces y separadores al mismo tamaño, para que el punto medio no vuelva a
       ser el elemento más grande de la fila. */
    body.woocommerce-shop .ga-footer__legal-nav,
    body.woocommerce-shop .ga-footer__legal-nav a,
    body.woocommerce-shop .ga-footer__legal-nav span {
        font-size: 0.62rem;         /* 9,92px — antes 0,68rem los enlaces y 0,7rem los "·" */
    }

    /* Ninguna etiqueta se parte por dentro: o cabe entera, o no cabe. */
    body.woocommerce-shop .ga-footer__legal-nav a {
        white-space: nowrap;
    }
}


/* =============================================================
   PÁGINA CONTACTO — .ga-contacto-   (page-templates/page-contacto.php)
   Escritorio, tablet y móvil en el mismo bloque.

   ESTRUCTURA:
     .ga-contacto-header  → solo el título, a todo el ancho
     .ga-contacto-grid    → dos columnas IGUALES (50% / 50%, misma altura)
        · .ga-contacto-panel     → IZQUIERDA, verde claro enmarcado en oliva.
                                   Dentro y en este orden: .ga-contacto-quien
                                   (firma + mensaje), .ga-contacto-filas
                                   (teléfono · WhatsApp · email),
                                   .ga-contacto-franja (disponibilidad),
                                   .ga-contacto-faq (acordeón) y, cerrando,
                                   .ga-contacto-tienda.
        · .ga-contacto-form-col  → DERECHA, formulario sobre crema.
     .ga-contacto-modal   → diálogo de acciones (lo crea main.js), fixed.

   REGLAS APLICADAS AQUÍ:
   · El hueco de la cabecera fija (80px / 64px en móvil) ya lo reserva el
     padding-top del <body> (main.css:599). NO se repite: se duplicaría.
   · Ningún estado (hover, focus, activo) cambia el TAMAÑO ni la POSICIÓN de
     un elemento: solo color, color de borde (el grosor es siempre el mismo)
     y box-shadow, que no ocupa espacio en el flujo.
   · NINGÚN min-width en toda la página. Donde hacía falta cortar el ancho
     mínimo del contenido se usa minmax(0, …) en el grid y overflow-wrap en
     el texto → sin desbordamiento horizontal a 360px.
   · Campos a 16px: por debajo de eso iOS hace zoom automático al escribir.
   · Solo variables de marca; las mezclas rgba() son tintes de esos mismos
     colores (dorado #c7a862, verde montañas #7f8649, oliva #4a4a2f).
   ============================================================= */

/* La PRUEBA DE COLOR del panel se ha REVERTIDO: el panel vuelve al verde oliva
   oscuro de marca y la variable del verde claro ya no existe.

   Se conserva el rojo del indicador de "fuera de horario", que no formaba parte
   de la prueba, pero RETONADO para fondo oscuro: el teja oscuro que se usó
   sobre el fondo claro se quedaba en 1,1:1 contra el oliva, invisible. Este
   teja claro se lee como rojo terroso —misma familia cálida de la marca, nada
   de rojo puro de alerta— y va acompañado del mismo anillo pálido que el punto
   verde.
   El valor se escribe UNA sola vez, y en componentes sueltos, para poder
   derivar de él los tintes translúcidos del halo y del pulso
   —rgba(var(--ga-rojo-teja-rgb), 0.4)— sin repetirlo en ningún sitio. */
:root {
    --ga-rojo-teja-rgb: 193, 88, 60;              /* #c1583c */
    --ga-rojo-teja: rgb(var(--ga-rojo-teja-rgb));
}

.ga-main--contacto {
    background-color: var(--ga-blanco);
}

/* ——— 1 · CABECERA DE PÁGINA ———
   Fondo BLANCO, igual que el resto de la página: así no se ve ninguna franja de
   color entre la cabecera fija del sitio y el título. El aire superior es corto
   (24px) porque encima ya están los 80px que el <body> reserva para el header
   fijo; con space-xl (64px) sobraba muchísimo. */
.ga-contacto-header {
    padding: var(--ga-space-md) var(--ga-space-md) var(--ga-space-lg);
    text-align: center;
    background-color: var(--ga-blanco);
}

/* Astra inyecta un margin al h1 que gana en especificidad a un margin:0 simple
   (mismo caso que en la Tienda): se anula con la misma especificidad de allí. */
.ga-main--contacto .ga-contacto-header__titulo {
    margin: 0 auto;
}

.ga-contacto-header__titulo {
    font-family: var(--ga-font-display);
    /* clamp: 40px en móvil estrecho → 64px en escritorio, sin salto de breakpoint */
    font-size: clamp(2.5rem, 6vw, var(--ga-text-6xl));
    font-weight: var(--ga-weight-bold);
    line-height: 1.05;
    letter-spacing: 0.06em;
    color: var(--ga-verde-oliva-oscuro);
}

/* El filete dorado bajo el título se ELIMINA (era un ::after de este mismo
   h1, no un elemento del HTML). El subtítulo también se ha eliminado, del HTML
   y de aquí: la cabecera es solo el título. */

/* ——— CONTENEDOR COMÚN ——— */
.ga-contacto-inner {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
}

.ga-contacto-cuerpo {
    padding: var(--ga-space-lg) 0 var(--ga-space-2xl);
}

/* ——— REJILLA DE DOS COLUMNAS (50% / 50%) ———
   align-items:start → cada columna toma SU PROPIA altura. Con el 'stretch' por
   defecto, al desplegar una pregunta del acordeón crecía la fila entera y la
   caja del formulario se estiraba con ella, dejando un hueco crema vacío.
   Contrapartida asumida: en reposo las dos columnas ya no terminan a la misma
   altura.
   minmax(0, …) evita que el email imponga su ancho mínimo y desborde. */
.ga-contacto-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--ga-space-xl);
    align-items: start;
}

/* ——— PANEL IZQUIERDO (verde oliva oscuro) ———
   Es el ancla visual de la página: bloque macizo de color contra el blanco.
   Columna flex: los bloques se apilan de arriba abajo y el alto sobrante, si
   el formulario es más largo, queda al final. */
.ga-contacto-panel {
    display: flex;
    flex-direction: column;
    /* SIN justify-content (queda flex-start): todos los bloques se agrupan
       arriba, uno detrás de otro, con su propia separación. Si la columna se
       estira hasta la altura del formulario, el alto sobrante queda al FINAL
       del panel, sin abrir huecos entre los bloques. */
    padding: var(--ga-space-lg);
    /* Vuelta al bloque macizo de verde oliva oscuro, sin marco: el borde de
       10px solo existía para enmarcar el interior claro de la prueba. */
    background-color: var(--ga-verde-oliva-oscuro);
    /* Borde SIEMPRE presente, transparente en reposo: en hover solo cambia de
       COLOR, nunca de grosor, así el panel no crece ni empuja nada. Si se
       añadiera solo en :hover, el elemento cambiaría de tamaño al pasar el
       ratón. */
    border: 1px solid transparent;
    border-radius: var(--ga-radius-md);
    box-shadow: var(--ga-shadow-sm);   /* reposo: sombra discreta */
    color: var(--ga-naranja-claro);    /* crema: color base de todo el panel */
    transition: box-shadow var(--ga-transition),
                transform var(--ga-transition),
                border-color var(--ga-transition);   /* 250ms ease */
}

/* ——— FILAS DE CONTACTO (sin tarjetas ni recuadros) ——— */
.ga-contacto-filas {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Línea divisoria de 1px entre filas: se pone en las filas SIGUIENTES a la
   primera, así no sobra una línea suelta arriba ni abajo. */
.ga-contacto-filas li + li .ga-contacto-fila {
    border-top: 1px solid rgba(199, 168, 98, 0.22);   /* dorado a baja opacidad */
}

/* Toda la fila es el enlace. En escritorio, el JS intercepta el clic de las
   filas con data-ga-modal y abre el diálogo; en móvil deja pasar el enlace. */
.ga-contacto-fila {
    display: block;
    padding: var(--ga-space-sm) 0;   /* compacto (antes space-md = 24px) */
    text-decoration: none;
    color: var(--ga-naranja-claro);
}

/* El dorado del hover se ha quitado de aquí: ahora el cambio de color va SOLO
   sobre el dato (.ga-contacto-fila__dato) y dentro de un @media de puntero
   fino, más abajo. Así en táctil no puede quedarse ningún estado pegado.

   El foco de teclado conserva su indicador propio: un outline, que se dibuja
   por fuera de la caja y no ocupa espacio en el flujo → no mueve nada. */
.ga-contacto-fila:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

/* Etiqueta pequeña: icono monolínea dorado + texto en mayúsculas espaciadas. */
.ga-contacto-fila__label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);
}

/* Icono en línea con la etiqueta, sin círculo ni fondo. Tamaño fijo: no se
   deforma aunque la etiqueta cambie de largo. */
.ga-contacto-fila__ico {
    flex: 0 0 auto;
    width: 16px;
    height: 16px;
    color: var(--ga-naranja-apagado);
}

/* El dato, en Inter y a buen tamaño: es lo que se lee de un vistazo. */
.ga-contacto-fila__dato {
    display: block;
    margin-top: 0.4rem;
    font-family: var(--ga-font-body);
    /* clamp para que el email quepa entero en un panel de móvil de 360px. */
    font-size: clamp(1.05rem, 3.6vw, var(--ga-text-xl));
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.01em;
    line-height: 1.35;
    /* Si no cupiera, se parte dentro del panel en lugar de ensancharlo
       (equivale al min-width:0 que aquí no se usa). */
    overflow-wrap: anywhere;
    transition: color 200ms ease;
}

/* ——— HOVER DEL DATO (solo con ratón) ———
   Afecta ÚNICAMENTE al dato: la etiqueta y el icono llevan su propio color
   dorado declarado, así que no los toca. Solo cambia el color: sin subrayado,
   sin cambio de grosor, sin desplazar nada. En táctil la regla ni existe. */
@media (hover: hover) and (pointer: fine) {

    .ga-contacto-fila:hover .ga-contacto-fila__dato {
        color: var(--ga-naranja-claro);   /* crema de marca #F9F6EE */
    }
}

/* ——— FRANJA DE DISPONIBILIDAD (dentro del panel oscuro) ———
   El HTML sale del servidor SIEMPRE en estado "fuera de horario" (punto rojo).
   gaContactoDisponibilidad() (assets/js/main.js) añade .is-abierto solo cuando la
   hora real de España cae dentro del horario. Si el JS falla, no se promete nada.
   La lógica no cambia: solo se recolorea para el fondo verde oliva. */
.ga-contacto-franja {
    padding: var(--ga-space-sm) 0 0;   /* justo debajo de las filas de contacto */
    border-top: 1px solid rgba(199, 168, 98, 0.22);
}

.ga-contacto-estado {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    font-weight: var(--ga-weight-medium);
    line-height: 1.5;
    color: var(--ga-naranja-claro);
    opacity: 1;                                  /* anula el 0.85 global de <p> */
}

/* Punto ROJO TEJA = fuera de horario (el estado por defecto del HTML).
   Mismo tratamiento que el verde —anillo pálido + halo permanente + pulso
   lento—, solo que en rojo: los dos estados se leen como un piloto encendido,
   uno de "estamos" y otro de "ahora no".

   Sobre el verde oliva, un rojo suelto se queda corto de contraste (2,0:1), así
   que lleva el MISMO anillo de 2px en el verde pálido de marca (#c3c4aa) que el
   punto verde: con él, el indicador completo queda en 5,1:1, muy por encima del
   3:1 que pide AA para gráficos.

   El punto mide 10px en los dos estados y lo único que cambia son colores y
   sombras, que no ocupan espacio en el flujo: el texto de al lado no se mueve. */
.ga-contacto-estado__punto {
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    border-radius: var(--ga-radius-full);
    background-color: var(--ga-rojo-teja);
    box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                0 0 9px 2px rgba(var(--ga-rojo-teja-rgb), 0.85),
                0 0 0 2px rgba(var(--ga-rojo-teja-rgb), 0.45);
    animation: ga-contacto-pulso-rojo 2s ease-out infinite;
    transition: background-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* Misma onda que la del verde, en rojo. Las dos primeras capas (anillo y halo)
   se repiten idénticas en los tres fotogramas para que el brillo no parpadee;
   solo varía la tercera. Únicamente box-shadow: sin width, sin height, sin
   margin, sin padding, sin transform. */
@keyframes ga-contacto-pulso-rojo {
    0% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 9px 2px rgba(var(--ga-rojo-teja-rgb), 0.85),
                    0 0 0 2px rgba(var(--ga-rojo-teja-rgb), 0.45);
    }
    70% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 9px 2px rgba(var(--ga-rojo-teja-rgb), 0.85),
                    0 0 0 15px rgba(var(--ga-rojo-teja-rgb), 0);
    }
    100% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 9px 2px rgba(var(--ga-rojo-teja-rgb), 0.85),
                    0 0 0 2px rgba(var(--ga-rojo-teja-rgb), 0);
    }
}

/* Estado ABIERTO (lo pone el JS con la clase .is-abierto sobre
   #ga-contacto-estado): piloto ENCENDIDO = brillo constante + pulso lento.
   Tres capas de box-shadow, ninguna de las cuales ocupa espacio en el flujo:
     1. anillo de 2px en el verde pálido de marca (#c3c4aa) → recorta el punto
        sobre el verde oliva oscuro, donde un verde solo perdería contraste;
     2. halo PERMANENTE difuminado en el verde de disponibilidad (#7f8649):
        es el "encendido" que se ve aunque el pulso esté en su punto bajo;
     3. onda del pulso, la única capa que varía.
   Las dos primeras se repiten idénticas en los tres fotogramas para que el
   brillo no parpadee. El punto mide 10px en todo momento: no se anima ni
   width, ni height, ni margin, ni padding, ni transform, así que ni el texto
   de al lado ni la franja se mueven un píxel. */
.ga-contacto-estado.is-abierto .ga-contacto-estado__punto {
    background-color: var(--ga-verde-montanas);
    box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                0 0 10px 3px rgba(127, 134, 73, 0.90),
                0 0 0 2px rgba(195, 196, 170, 0.45);
    animation: ga-contacto-pulso 2s ease-out infinite;
}

/* Onda que crece y se desvanece sobre el halo fijo. Solo box-shadow (spread +
   alfa): sin width, sin height, sin margin, sin transform. */
@keyframes ga-contacto-pulso {
    0% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 10px 3px rgba(127, 134, 73, 0.90),
                    0 0 0 2px rgba(195, 196, 170, 0.45);
    }
    70% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 10px 3px rgba(127, 134, 73, 0.90),
                    0 0 0 15px rgba(195, 196, 170, 0);
    }
    100% {
        box-shadow: 0 0 0 2px rgba(195, 196, 170, 0.75),
                    0 0 10px 3px rgba(127, 134, 73, 0.90),
                    0 0 0 2px rgba(195, 196, 170, 0);
    }
}

/* Accesibilidad: quien pida menos movimiento ve el punto —rojo o verde— con su
   anillo y su halo fijos, así que sigue leyéndose como encendido; solo se va la
   onda. La información no depende de la animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-contacto-estado__punto,
    .ga-contacto-estado.is-abierto .ga-contacto-estado__punto {
        animation: none;
    }
}

.ga-contacto-estado__texto {
    text-wrap: pretty;
}

/* Horario literal: siempre visible, pase lo que pase con el JS. */
.ga-contacto-estado__horario {
    margin: 0.45rem 0 0;
    padding-left: calc(10px + 0.7rem);   /* alineado con el texto del estado */
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.5;
    color: var(--ga-naranja-claro);
    opacity: 0.65;
}

/* ——— QUIÉN TE CONTESTA (abre el panel oscuro) ———
   Separación normal con las filas de contacto que vienen debajo (antes space-lg,
   40px: demasiado hueco). */
.ga-contacto-quien {
    padding: 0 0 var(--ga-space-md);
}

.ga-contacto-quien__inner {
    display: flex;
    align-items: flex-start;
    gap: var(--ga-space-md);
}

/* Foto redonda OPCIONAL (viene comentada en la plantilla). Medidas fijas: al
   activarla no descuadra el texto, solo se coloca a su izquierda. */
.ga-contacto-quien__foto {
    flex: 0 0 92px;
    width: 92px;
    height: 92px;
    overflow: hidden;
    border-radius: var(--ga-radius-full);
    border: 2px solid var(--ga-naranja-apagado);
}

.ga-contacto-quien__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: var(--ga-radius-full);
}

/* overflow-wrap:anywhere (y NO min-width:0) es lo que impide que el texto
   imponga su ancho mínimo dentro del flex cuando la foto está activada. */
.ga-contacto-quien__texto {
    overflow-wrap: anywhere;
}

/* El párrafo va DEBAJO de la firma (ese es el orden en el HTML). */
.ga-contacto-quien__parrafo {
    margin: var(--ga-space-sm) 0 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    line-height: 1.75;
    color: var(--ga-naranja-claro);
    opacity: 0.88;
    text-wrap: pretty;
}

/* Firma en la serif de marca: encabeza el bloque personal, en cursiva dorada,
   como una rúbrica que firma lo que viene debajo. */
.ga-contacto-quien__firma {
    margin: 0;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    font-weight: var(--ga-weight-bold);
    font-style: italic;
    line-height: 1.2;
    color: var(--ga-naranja-apagado);
    opacity: 1;
}

/* ——— PREGUNTAS FRECUENTES (acordeón <button> + panel en grid) ———
   La apertura se anima con grid-template-rows: 0fr → 1fr sobre el panel, con el
   contenido dentro de un hijo con overflow:hidden. Es el único método que anima
   una altura DESCONOCIDA de forma fluida: nada de max-height con un número
   grande inventado (que da el tirón al final del recorrido) ni de medir alturas
   por JavaScript. El JS solo alterna aria-expanded y una clase.
   Hereda el color del panel (color: inherit → crema) y reutiliza la misma línea
   separadora que las filas de contacto: rgba(199,168,98,0.22), el dorado de
   marca a baja opacidad. Ningún color nuevo. */
.ga-contacto-faq {
    margin-top: var(--ga-space-md);
    padding-top: var(--ga-space-md);
    border-top: 1px solid rgba(199, 168, 98, 0.22);
}

/* Mismo tratamiento que las etiquetas de las filas de contacto, para que el
   bloque no compita con la firma. */
.ga-contacto-faq__titulo {
    margin: 0 0 0.35rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ga-naranja-apagado);   /* dorado, como las etiquetas de las filas */
}

.ga-contacto-faq__item + .ga-contacto-faq__item {
    border-top: 1px solid rgba(199, 168, 98, 0.22);
}

/* El botón ocupa toda la fila: texto a la izquierda, indicador a la derecha.
   Se le quitan los estilos propios de <button> (fondo, borde, tipografía) para
   que se lea como una línea de texto del panel. */
.ga-contacto-faq__pregunta {
    display: flex;
    align-items: center;
    gap: var(--ga-space-sm);
    width: 100%;
    padding: 0.7rem 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    line-height: 1.5;
    text-align: left;
    color: inherit;
    background: none;
    border: 0;
    border-radius: 0;
    cursor: pointer;
    -webkit-appearance: none;
    appearance: none;
    transition: color 200ms ease;
}

/* 🔴 EL FONDO DORADO DEL HOVER VENÍA DE FUERA, NO DE AQUÍ.
   Astra pinta un fondo dorado en los <button> al pasar el ratón y al
   enfocarlos. El `background: none` del selector base solo cubre el estado
   normal, así que en :hover y :focus mandaba la regla del tema y la pregunta
   quedaba dorada sobre dorado, ilegible.

   Es la misma trampa ya documentada para los botones de la tienda (Astra gana
   en especificidad a cualquier selector de clase propio), y se resuelve igual:
   !important en las propiedades críticas y selector acotado a esta página, sin
   tocar ningún botón del resto del sitio. El fondo queda IGUAL en los cuatro
   estados: reposo, hover, foco y abierta. */
.ga-main--contacto .ga-contacto-faq__pregunta,
.ga-main--contacto .ga-contacto-faq__pregunta:hover,
.ga-main--contacto .ga-contacto-faq__pregunta:focus,
.ga-main--contacto .ga-contacto-faq__pregunta:focus-visible,
.ga-main--contacto .ga-contacto-faq__pregunta:active {
    background: none !important;
    border-color: transparent !important;
    box-shadow: none !important;
}

/* El texto es un <span> aparte para que el chevron no herede su interlineado.
   overflow-wrap corta el ancho mínimo del contenido dentro del flex sin
   recurrir a min-width. */
.ga-contacto-faq__texto {
    overflow-wrap: anywhere;
}

/* Indicador propio: un chevron dibujado con dos bordes. Ocupa una caja FIJA de
   8x8 con margin-left:auto (constante, abierto o cerrado), y lo único que
   cambia al abrir es un transform: rotate, que se aplica DESPUÉS del cálculo
   del layout → no mueve ni redimensiona el texto de la pregunta. Gira con la
   misma duración que el panel (300ms) para que el movimiento sea uno solo. */
.ga-contacto-faq__pregunta::after {
    content: "";
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    margin-left: auto;
    margin-right: 3px;   /* holgura para la diagonal del chevron girado */
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: rotate(45deg);            /* cerrado: apunta hacia abajo */
    transform-origin: center;
    transition: transform 300ms ease;
}

.ga-contacto-faq__item.is-abierta .ga-contacto-faq__pregunta::after {
    transform: rotate(-135deg);          /* abierto: apunta hacia arriba */
}

/* Foco de teclado: outline, que se dibuja fuera de la caja y no ocupa espacio
   en el flujo → no mueve nada. */
.ga-contacto-faq__pregunta:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

/* ——— PANEL DESPLEGABLE ———
   Cerrado, la fila del grid mide 0fr; abierto, 1fr = el alto natural de su
   contenido. La transición interpola entre ambos, así que la animación es
   suave y exacta sea cual sea el largo de la respuesta. El hijo lleva
   overflow:hidden para que el texto se recorte mientras se abre. */
.ga-contacto-faq__panel {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 300ms ease;
}

.ga-contacto-faq__item.is-abierta .ga-contacto-faq__panel {
    grid-template-rows: 1fr;
}

.ga-contacto-faq__panel-inner {
    overflow: hidden;
}

/* Respuesta en crema, un punto atenuada respecto a la pregunta (6,6:1 sobre el
   oliva, de sobra para AA). El padding va aquí dentro, así se recorta con el
   resto y el panel cerrado mide exactamente cero. */
.ga-contacto-faq__respuesta {
    margin: 0;
    padding: 0 var(--ga-space-md) 0.8rem 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: inherit;
    opacity: 0.85;           /* anula el 0.85 global de <p> con un valor propio */
    text-wrap: pretty;
}

/* Hover solo con ratón, y SOLO color de texto: la pregunta se aclara del crema
   de reposo (#F9F6EE, 8,4:1 sobre el oliva) al blanco (9,1:1). Un aclarado
   sutil, sin tocar el fondo y sin mover ni redimensionar nada.
   El dorado de antes se ha quitado: era el que, sumado al fondo dorado que
   pintaba Astra, dejaba la pregunta ilegible. */
@media (hover: hover) and (pointer: fine) {

    .ga-contacto-faq__pregunta:hover {
        color: var(--ga-blanco);
    }
}

/* Movimiento reducido: apertura y cierre instantáneos, sin transición ni en el
   panel ni en el chevron. El acordeón sigue funcionando igual. */
@media (prefers-reduced-motion: reduce) {

    .ga-contacto-faq__panel,
    .ga-contacto-faq__pregunta::after {
        transition: none;
    }
}

/* ——— ENLACE A LA TIENDA (última línea del panel) ———
   Salida para quien no venía a escribir. Enlace de TEXTO subrayado, nunca un
   botón: no debe competir con el CTA "Enviar mensaje". Al mismo tamaño que el
   resto de textos secundarios del panel (14px). Cierra el panel con la misma
   línea separadora que el resto de bloques.

   ⚠ SIN margin-top (antes 24px): ERA LA CAUSA DEL HUECO al final del acordeón.
   Esos 24px separaban su borde superior de la última pregunta, mientras que
   entre preguntas la línea va pegada —solo el 0,7rem de padding del botón—, y
   otros 24px de padding lo despegaban del texto. El panel cerrado no tenía nada
   que ver: su padding vive dentro del contenedor con overflow:hidden y se
   recorta a cero. Con margin 0, la línea queda a la misma distancia de la
   última pregunta que las de arriba. */
.ga-contacto-tienda {
    margin: 0;
    padding-top: var(--ga-space-sm);
    border-top: 1px solid rgba(199, 168, 98, 0.22);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-naranja-claro);
    opacity: 0.78;
    text-wrap: pretty;
}

/* El enlace se distingue por el subrayado y por el dorado de marca. */
.ga-contacto-tienda a {
    color: var(--ga-naranja-apagado);
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color var(--ga-transition-fast);
}

/* Hover/foco: solo color. Ni tamaño, ni posición, ni grosor de subrayado. */
.ga-contacto-tienda a:hover,
.ga-contacto-tienda a:focus-visible {
    color: var(--ga-naranja-claro);
    outline: none;
}

/* La línea de mayoristas y hostelería se ha ELIMINADO del panel (del HTML y de
   aquí): ese mensaje ya está en el pie de página del sitio. */

/* ——— COLUMNA DERECHA · FORMULARIO ———
   Crema sobre el blanco de la página: tres tonos en total (oliva oscuro del
   panel, crema del formulario, blanco de los campos y del fondo). */
.ga-contacto-form-col {
    padding: var(--ga-space-xl) var(--ga-space-lg);
    background-color: var(--ga-naranja-claro);   /* crema #F9F6EE */
    border: 1px solid rgba(199, 168, 98, 0.30);
    border-radius: var(--ga-radius-md);
    box-shadow: var(--ga-shadow-sm);   /* reposo: sombra discreta */
    transition: box-shadow var(--ga-transition);   /* 250ms ease */
    /* Ancla del formulario: al volver con ?enviado=… el navegador salta aquí y
       la cabecera fija no puede tapar el aviso. */
    scroll-margin-top: calc(var(--ga-nav-height) + var(--ga-space-md));
}

/* ——— ELEVACIÓN AL PASAR EL RATÓN ———
   Cada columna reacciona por su cuenta: son dos :hover independientes.

   La caja del formulario (crema sobre blanco) se queda SOLO con el cambio de
   sombra: ahí se distingue de sobra.

   El panel de la izquierda es verde oliva oscuro, y una sombra oscura sobre un
   fondo oscuro no se percibe, así que lleva además dos cosas: un
   translateY(-4px) y un borde perimetral que se enciende en crema muy tenue,
   como un reflejo —que es lo que sí se lee en fondos oscuros—. Nada de scale,
   ni de width/height, ni de padding/margin, ni de bordes que engorden: el
   borde ya existe transparente en reposo y solo cambia de color.

   La sombra es un tinte del verde oliva de marca (74,74,47), no un gris azulado.
   Como box-shadow no participa en el flujo ni en el cálculo del scroll, no puede
   provocar desbordamiento horizontal a ninguna anchura, tampoco a 360px (donde
   además no llega a activarse: es un efecto solo de ratón).

   @media (hover: hover) and (pointer: fine) → en móvil y tablet táctil ni
   siquiera existe la regla, así que un toque no puede dejar el estado pegado. */
@media (hover: hover) and (pointer: fine) {

    .ga-contacto-panel:hover,
    .ga-contacto-form-col:hover {
        box-shadow: 0 18px 40px rgba(74, 74, 47, 0.28);
    }

    /* Solo el panel oscuro: desplazamiento y reflejo del borde.
       rgba(249, 246, 238, …) es el crema de marca (#F9F6EE) a baja opacidad. */
    .ga-contacto-panel:hover {
        transform: translateY(-4px);
        border-color: rgba(249, 246, 238, 0.35);
    }
}

.ga-contacto-form__titulo {
    margin: 0 0 var(--ga-space-lg);
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-3xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.15;
    color: var(--ga-verde-oliva-oscuro);
}

/* Aviso de resultado (éxito / error) */
.ga-contacto-aviso {
    margin: 0 0 var(--ga-space-md);
    padding: 0.85rem 1rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.5;
    border-radius: var(--ga-radius-sm);
    border-left: 3px solid transparent;
    opacity: 1;
}

.ga-contacto-aviso--ok {
    color: var(--ga-verde-oliva-oscuro);
    background-color: rgba(127, 134, 73, 0.14);   /* verde montañas al 14% */
    border-left-color: var(--ga-verde-montanas);
}

.ga-contacto-aviso--error {
    color: var(--ga-marron-oscuro);
    background-color: rgba(70, 52, 31, 0.10);
    border-left-color: var(--ga-marron-oscuro);
}

.ga-contacto-aviso a {
    color: inherit;
    text-decoration: underline;
}

/* Más aire entre campos que en la versión anterior (antes space-md = 24px). */
.ga-contacto-campo {
    display: block;
    margin: 0 0 var(--ga-space-lg);
}

/* 🔴 IMPRESCINDIBLE: el `display: block` de arriba GANA al display:none que la
   hoja del navegador aplica a [hidden] (las reglas de autor pesan más que las
   del user agent). Sin esta línea, el campo de número de pedido se vería
   siempre, aunque lleve el atributo hidden. */
.ga-contacto-campo[hidden] {
    display: none;
}

/* Texto de ayuda bajo un campo. Sin opacidades bajas: a 0.7 sobre el crema del
   formulario se quedaba en 3,9:1, por debajo de AA para 12px. */
.ga-contacto-ayuda {
    display: block;
    margin-top: 0.4rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.5;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.85;
}

.ga-contacto-label {
    display: block;
    margin-bottom: 0.55rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ga-verde-oliva-oscuro);
}

.ga-contacto-req {
    color: var(--ga-naranja-apagado);
}

/* Campos. 16px fijos (no rem, no clamp): por debajo de 16px iOS hace zoom al
   enfocar. Sin min-width; width:100% + box-sizing:border-box (reset global). */
.ga-contacto-input {
    display: block;
    width: 100%;
    max-width: 100%;
    padding: 1.05rem 1.1rem;   /* campos más altos (antes 0.8rem 1rem) */
    font-family: var(--ga-font-body);
    font-size: 16px;
    line-height: 1.5;
    color: var(--ga-verde-oliva-oscuro);
    background-color: var(--ga-blanco);
    border: 1px solid rgba(74, 74, 47, 0.22);
    border-radius: var(--ga-radius-sm);
    /* Grosor de borde IDÉNTICO en todos los estados; el realce del foco es un
       box-shadow, que no ocupa espacio en el flujo → nada se mueve. */
    transition: border-color var(--ga-transition-fast), box-shadow var(--ga-transition-fast);
    -webkit-appearance: none;
    appearance: none;
}

.ga-contacto-input::placeholder {
    color: rgba(74, 74, 47, 0.45);
}

.ga-contacto-input:hover {
    border-color: rgba(74, 74, 47, 0.4);
}

.ga-contacto-input:focus {
    outline: none;
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.25);
}

/* Flecha propia del desplegable (appearance:none la quita). SVG en data-uri:
   sin peticiones extra y sin depender de ninguna librería de iconos. */
.ga-contacto-select {
    padding-right: 2.6rem;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none' stroke='%234a4a2f' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    cursor: pointer;
}

.ga-contacto-textarea {
    /* Solo vertical: con resize:both el usuario podría sacar el campo del
       contenedor y provocar desbordamiento horizontal. */
    resize: vertical;
    min-height: 11rem;   /* más alto que antes (9rem) */
    line-height: 1.6;
}

/* ——— CONSENTIMIENTO RGPD ———
   🔴 POR QUÉ NO SE ESTILIZA EL <input> DIRECTAMENTE.
   Astra estiliza input[type="checkbox"], y ese selector (0-2-1) gana a
   .ga-contacto-check:checked (0-2-0): pintaba la casilla entera de dorado y, al
   hacerlo con el atajo `background`, borraba el background-image donde vivía el
   tick. Subir especificidad sería una guerra que se pierde en la siguiente
   actualización del tema padre.

   Se usa el patrón que YA está probado en este tema (.ga-opinion-form-checkbox
   del formulario de opiniones y .ga-desistimiento__checkbox): el <input> real se
   colapsa y la caja visible es un <span> hermano, al que ninguna regla de Astra
   sobre input[type=checkbox] puede llegar. */
.ga-contacto-campo--check {
    margin-bottom: var(--ga-space-lg);
}

/* La etiqueta ENVUELVE input + caja + texto: se marca pulsando en cualquier
   punto, no solo en el cuadrito. */
.ga-contacto-check-label {
    display: flex;
    align-items: flex-start;
    gap: 0.7rem;
    cursor: pointer;
}

/* El input REAL: invisible, pero PRESENTE. No lleva display:none ni
   visibility:hidden, así que sigue en el árbol de accesibilidad, sigue siendo
   enfocable con el teclado y sigue enviando su valor. */
.ga-contacto-check {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
    margin: 0;
}

/* La caja visible. Medidas FIJAS: idénticas marcada y sin marcar, así que al
   hacer clic no se mueve nada. */
.ga-contacto-check-box {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 18px;
    width: 18px;
    height: 18px;
    margin-top: 0.15rem;
    background-color: var(--ga-blanco);
    border: 1px solid rgba(74, 74, 47, 0.35);
    border-radius: var(--ga-radius-sm);
    transition: border-color var(--ga-transition-fast),
                box-shadow var(--ga-transition-fast);
}

/* El tick, siempre en el DOM y siempre del mismo tamaño: solo cambia su
   opacidad, que no ocupa espacio en el flujo. Dorado por currentColor, tomado
   de la variable de marca (aquí sí se puede usar; dentro de un url() no). */
.ga-contacto-check-box svg {
    width: 12px;
    height: 12px;
    color: var(--ga-naranja-apagado);
    opacity: 0;
    transition: opacity var(--ga-transition-fast);
}

/* MARCADA: la caja sigue BLANCA. Solo aparece el tick dorado y el borde se tiñe. */
.ga-contacto-check:checked + .ga-contacto-check-box {
    border-color: var(--ga-naranja-apagado);
}

.ga-contacto-check:checked + .ga-contacto-check-box svg {
    opacity: 1;
}

/* Foco de teclado: como el input es invisible, el anillo se pinta sobre la caja.
   box-shadow no ocupa espacio en el flujo → nada se mueve. */
.ga-contacto-check:focus-visible + .ga-contacto-check-box {
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.35);
}

.ga-contacto-check-label:hover .ga-contacto-check-box {
    border-color: rgba(74, 74, 47, 0.55);
}

.ga-contacto-label-check {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.55;
    color: var(--ga-verde-oliva-oscuro);
    cursor: pointer;
    /* overflow-wrap (sin min-width) basta para que un enlace largo se parta
       dentro del flex en vez de ensanchar el formulario. */
    overflow-wrap: anywhere;
}

.ga-contacto-label-check a {
    color: var(--ga-verde-montanas);
    text-decoration: underline;
    text-underline-offset: 2px;
}

.ga-contacto-label-check a:hover {
    color: var(--ga-naranja-apagado);
}

/* Botón de envío: VERDE OLIVA sólido, a todo el ancho del formulario. Rima con
   el panel de la izquierda y cierra la columna con peso.
   En hover/focus solo cambian colores y sombra: ni tamaño ni posición. */
.ga-contacto-btn {
    display: inline-block;
    width: 100%;
    padding: 1.1rem 2rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ga-blanco);
    background-color: var(--ga-verde-oliva-oscuro);
    border: 1px solid var(--ga-verde-oliva-oscuro);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    transition: background-color var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* Lo ÚNICO que cambia en hover es el fondo (verde oliva → dorado de marca) y la
   sombra. El texto ya no se vuelve verde: esa regla estaba aquí y se ha
   quitado. */
.ga-contacto-btn:hover {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    box-shadow: var(--ga-shadow-md);
}

/* Foco de teclado y pulsación: mismo dorado que el hover, para que el botón no
   cambie de aspecto según cómo se llegue a él. El anillo del foco es un
   box-shadow, que no ocupa espacio en el flujo → nada se mueve. */
.ga-contacto-btn:focus-visible {
    outline: none;
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(74, 74, 47, 0.45);
}

.ga-contacto-btn:active {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
}

/* 🔴 BLINDAJE DEL COLOR DE TEXTO.
   Astra pinta color en los <button> al pasar el ratón, al enfocarlos y al
   pulsarlos, y esas reglas (button:hover, 0,1,1) ganan al color del selector
   base de una sola clase (0,1,0). Es la misma trampa documentada para los
   botones de la tienda, así que se resuelve igual: !important y selector
   acotado a esta página. El texto es BLANCO en los cuatro estados, y ninguna
   regla general del tema se toca —la tienda y el resto del sitio siguen
   exactamente igual—. */
.ga-main--contacto .ga-contacto-btn,
.ga-main--contacto .ga-contacto-btn:hover,
.ga-main--contacto .ga-contacto-btn:focus,
.ga-main--contacto .ga-contacto-btn:focus-visible,
.ga-main--contacto .ga-contacto-btn:active {
    color: var(--ga-blanco) !important;
}

/* Honeypot antispam: fuera de la vista y del foco, pero presente en el DOM.
   No se usa display:none porque algunos bots lo detectan y omiten el campo. */
.ga-contacto-hp {
    position: absolute;
    left: -9999px;
    top: auto;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* ——— TABLET (<=1024px): las dos columnas se APILAN ———
   Primero el panel de información, debajo el formulario (es el orden del HTML,
   así que no hace falta reordenar nada). */
@media (max-width: 1024px) {

    /* Menos aire aún sobre el título (16px): la cabecera fija ya deja su hueco. */
    .ga-contacto-header {
        padding: var(--ga-space-sm) var(--ga-space-md) var(--ga-space-md);
    }

    .ga-contacto-grid {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ga-space-lg);
    }

    .ga-contacto-cuerpo {
        padding: var(--ga-space-md) 0 var(--ga-space-xl);
    }

    .ga-contacto-form-col {
        padding: var(--ga-space-lg);
    }
}

/* ——— MÓVIL (<=768px) ——— */
@media (max-width: 768px) {

    .ga-contacto-inner {
        padding: 0 var(--ga-space-sm);
    }

    .ga-contacto-cuerpo {
        padding: var(--ga-space-sm) 0 var(--ga-space-lg);
    }

    .ga-contacto-panel {
        padding: var(--ga-space-md) var(--ga-space-md) var(--ga-space-lg);
    }

    .ga-contacto-fila {
        padding: var(--ga-space-sm) 0;
    }

    .ga-contacto-estado {
        font-size: var(--ga-text-sm);
    }

    .ga-contacto-quien__inner {
        gap: var(--ga-space-sm);
    }

    .ga-contacto-quien__firma {
        font-size: var(--ga-text-xl);
    }

    .ga-contacto-form-col {
        padding: var(--ga-space-lg) var(--ga-space-md);
    }

    .ga-contacto-form__titulo {
        font-size: var(--ga-text-2xl);
        margin-bottom: var(--ga-space-md);
    }

    .ga-contacto-campo {
        margin-bottom: var(--ga-space-md);
    }
}

/* ——— AJUSTES FINOS (<=600px) ——— */
@media (max-width: 600px) {

    .ga-contacto-header {
        padding: var(--ga-space-sm) var(--ga-space-sm) var(--ga-space-md);
    }

    .ga-contacto-panel {
        padding: var(--ga-space-sm) var(--ga-space-md) var(--ga-space-md);
    }

    .ga-contacto-form-col {
        padding: var(--ga-space-md) var(--ga-space-sm);
    }

    /* El campo sigue a 16px (obligatorio en iOS); lo que se recorta es el
       acolchado, no la letra. */
    .ga-contacto-input {
        padding: 0.9rem 0.85rem;
    }

    .ga-contacto-select {
        padding-right: 2.4rem;
        background-position: right 0.85rem center;
    }

    .ga-contacto-btn {
        padding: 1rem;
    }
}


/* =============================================================
   CONTACTO · MODAL DE ACCIONES  (.ga-contacto-modal)
   Lo construye gaContactoModal() en assets/js/main.js y lo cuelga del <body>,
   así que si el JS no corre no queda ningún nodo suelto y las filas siguen
   funcionando como enlaces normales.

   position: fixed + inset: 0 → ocupa el viewport sin añadir alto al documento
   y sin poder generar scroll horizontal (la caja va a max-width, nunca a un
   ancho fijo mayor que la pantalla).
   ============================================================= */
.ga-contacto-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;                 /* por encima de la cabecera fija (1000) */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: var(--ga-space-md);
    background-color: rgba(26, 26, 20, 0.55);   /* negro suave de marca al 55% */
    opacity: 0;
    visibility: hidden;
    transition: opacity var(--ga-transition-normal),
                visibility var(--ga-transition-normal);
}

.ga-contacto-modal.is-visible {
    opacity: 1;
    visibility: visible;
}

.ga-contacto-modal__caja {
    position: relative;
    width: 100%;
    max-width: 380px;
    padding: var(--ga-space-lg);
    background-color: var(--ga-naranja-claro);   /* crema #F9F6EE */
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-md);
    box-shadow: var(--ga-shadow-lg);
    /* Entrada: fade + ligerísima escala. Es una animación de APERTURA, no un
       estado de hover/foco, y al ir dentro de un fixed no mueve la página. */
    transform: scale(0.96);
    transition: transform var(--ga-transition-normal);
}

.ga-contacto-modal.is-visible .ga-contacto-modal__caja {
    transform: scale(1);
}

.ga-contacto-modal__cerrar {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    width: 36px;
    height: 36px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xl);
    line-height: 1;
    color: var(--ga-verde-oliva-oscuro);
    background: none;
    border: 1px solid transparent;   /* grosor reservado: el foco no mueve nada */
    border-radius: var(--ga-radius-full);
    cursor: pointer;
    transition: color var(--ga-transition-fast),
                border-color var(--ga-transition-fast);
}

.ga-contacto-modal__cerrar:hover,
.ga-contacto-modal__cerrar:focus-visible {
    color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    outline: none;
}

.ga-contacto-modal__titulo {
    margin: 0 0 0.25rem;
    padding-right: var(--ga-space-md);   /* no se mete debajo de la X */
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--ga-verde-montanas);
}

.ga-contacto-modal__dato {
    margin: 0 0 var(--ga-space-md);
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 1;
    overflow-wrap: anywhere;
}

.ga-contacto-modal__acciones {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.ga-contacto-modal__accion {
    display: block;
    width: 100%;
    padding: 0.85rem 1rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    font-weight: var(--ga-weight-medium);
    text-align: center;
    text-decoration: none;
    color: var(--ga-naranja-claro);
    background-color: var(--ga-verde-oliva-oscuro);
    border: 1px solid var(--ga-verde-oliva-oscuro);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    transition: background-color var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                color var(--ga-transition-normal);
}

.ga-contacto-modal__accion:hover,
.ga-contacto-modal__accion:focus-visible {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    color: var(--ga-verde-oliva-oscuro);
    outline: none;
}

/* Acción secundaria (copiar): mismo tamaño, solo contorno. */
.ga-contacto-modal__accion--sec {
    color: var(--ga-verde-oliva-oscuro);
    background-color: transparent;
    border-color: rgba(74, 74, 47, 0.35);
}

/* Confirmación de copiado. min-height (que no min-width) reserva su línea
   siempre: al aparecer el texto, los botones no se mueven. */
.ga-contacto-modal__feedback {
    margin: 0.6rem 0 0;
    min-height: 1.3em;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.3;
    text-align: center;
    color: var(--ga-verde-montanas);
    opacity: 1;
}


/* =============================================================
   PÁGINA NOSOTROS — .ga-nosotros-   (page-templates/page-nosotros.php)
   Escritorio, tablet y móvil en el mismo bloque.

   ESTRUCTURA (secciones a sangre; el ancho lo corta .ga-nosotros-inner):
     .ga-nosotros-hero        → foto de fondo + velo + titular
     .ga-nosotros-recorrido   → 5 pasos: textos a la izquierda + foto fija (sticky)
                                a la derecha que se cruza al scroll; apilado en móvil
     .ga-nosotros-vitrina     → carrusel coverflow de 5 tarjetas (verde claro)
     .ga-nosotros-cierre-vitrina → línea dorada + frase de cierre bajo el carrusel
     .ga-nosotros-manifiesto  → franja oscura, texto centrado a 720px
     .ga-nosotros-fiarte      → rejilla de 6 sellos 3/2/1 + línea de avales
     .ga-nosotros-cierre      → franja clara con el CTA a la tienda

   REGLAS APLICADAS AQUÍ:
   · El hueco de la cabecera fija (80px / 64px en móvil) ya lo reserva el
     padding-top del <body>. NO se repite: se duplicaría.
   · Ningún estado (hover, focus, activo) cambia el TAMAÑO ni la POSICIÓN de
     nada: solo color, color de borde (grosor siempre igual), sombra y opacidad.
     Ni un solo transform de hover en toda la página.
   · NINGUNA fila más ancha que el viewport, ningún scroll horizontal, ningún
     carrusel: todo son rejillas que se apilan. Donde hace falta cortar el ancho
     mínimo del contenido se usa minmax(0, …) y overflow-wrap, nunca min-width.
   · NINGÚN overflow-x: hidden nuevo (convertiría el elemento en contenedor de
     scroll y atraparía el gesto táctil). Las capas de fondo van con inset:0,
     así que no pueden sobresalir y no hay nada que recortar.
   · Sin background-attachment: fixed: falla en móvil.
   · Solo variables de marca; las mezclas rgba() son tintes de esos mismos
     colores (oliva 74,74,47 · dorado 199,168,98 · crema 249,246,238 ·
     negro suave 26,26,20).
   ============================================================= */

.ga-main--nosotros {
    background-color: var(--ga-blanco);
}

/* ——— CONTENEDOR COMÚN ———
   Todas las secciones son a sangre y es este contenedor el que centra y da el
   aire lateral, igual que .ga-contacto-inner en la página de contacto. */
.ga-nosotros-inner {
    max-width: var(--ga-max-width);
    margin: 0 auto;
    padding: 0 var(--ga-space-md);
}

/* 🔴 MÁRGENES DE TODOS LOS ENCABEZADOS, EN UN SOLO SITIO Y CON DOS CLASES.
   Astra inyecta márgenes a los <h1>-<h3> con un selector que GANA a uno de una
   sola clase (misma trampa ya documentada en Contacto y en la Tienda), así que
   el margen no puede declararse en las reglas de tipografía de abajo: se
   declara aquí, acotado a esta página.
   ⚠ Por eso cualquier cambio de margen de un encabezado —también dentro de un
   media query— tiene que escribirse con estas MISMAS dos clases: si no, pierde
   por especificidad aunque vaya después. */
.ga-main--nosotros .ga-nosotros-titulo {
    margin: 0 0 var(--ga-space-md);
}

.ga-main--nosotros .ga-nosotros-titulo--centrado {
    margin-bottom: var(--ga-space-lg);
}

/* Título de cada paso del recorrido. Va con DOS clases por el mismo motivo que el
   resto: gana al margen que Astra inyecta a los <h2>. Aquí van también la fuente
   y el tamaño, así queda toda su tipografía en una sola regla. */
.ga-main--nosotros .ga-nosotros-recorrido__titulo {
    margin: 0 0 var(--ga-space-md);
    font-family: var(--ga-font-display);
    font-size: clamp(1.75rem, 3.2vw, var(--ga-text-4xl));
    font-weight: var(--ga-weight-bold);
    line-height: 1.12;
    color: var(--ga-blanco);         /* blanco sobre el verde oscuro del marco */
    text-wrap: balance;
}

/* margin-top = el hueco EXACTO que dejó el filete dorado al eliminarlo: sus 2px
   de alto más los var(--ga-space-md) que lo separaban del titular. Así el bloque
   de texto del hero conserva la misma geometría de antes y el titular no sube ni
   baja, ni siquiera en las pantallas estrechas donde el contenido supera el
   min-height del hero y deja de estar anclado abajo. */
.ga-main--nosotros .ga-nosotros-hero__titulo {
    margin: calc(var(--ga-space-md) + 2px) 0 0;
}

.ga-main--nosotros .ga-nosotros-sello__titulo {
    margin: 0;   /* la separación icono/título/subtítulo la da el `gap` del sello */
}

/* ——— TÍTULOS DE SECCIÓN (h2) ———
   clamp: 30px en móvil estrecho → 36px en escritorio, sin salto de breakpoint. */
.ga-nosotros-titulo {
    font-family: var(--ga-font-display);
    font-size: clamp(1.875rem, 4.5vw, var(--ga-text-4xl));
    font-weight: var(--ga-weight-bold);
    line-height: 1.12;
    color: var(--ga-verde-oliva-oscuro);
}

.ga-nosotros-titulo--centrado {
    text-align: center;
}


/* ─────────────────────────────────────────────
   1 · HERO
   Tres capas apiladas, en este orden y por ORDEN DE DOCUMENTO (las tres están
   posicionadas y ninguna lleva z-index, así que el navegador las pinta según
   aparecen en el HTML):
       1. .ga-nosotros-hero__foto   → la <img> de portada
       2. .ga-nosotros-hero__velo   → el velo verde oscuro, SIEMPRE por encima
       3. .ga-nosotros-hero__inner  → titular y párrafo, arriba del todo
   El texto se apoya abajo a la izquierda, como un pie de fotografía editorial.
   ───────────────────────────────────────────── */
.ga-nosotros-hero {
    position: relative;             /* referencia de las capas absolutas */
    display: flex;
    align-items: flex-end;          /* el titular se apoya en la base */
    /* Altura = la visible de siempre (70vh) MÁS el alto de la cabecera. Ese
       extra no se ve: lo absorbe el margin-top negativo de abajo, que sube el
       hero por debajo del header. Como el hero crece por ARRIBA (el texto va
       anclado al borde inferior con flex-end), su base no se mueve y la ventana
       visible sigue midiendo 70vh, la de antes. */
    min-height: calc(70vh + var(--ga-nav-height));
    padding: var(--ga-space-2xl) 0 var(--ga-space-xl);
    /* Sube el hero exactamente el alto de la cabecera (80px escritorio / 64px
       móvil, la misma variable que reserva el padding-top del body). La foto
       pasa por debajo de la cabecera opaca y tapa el hueco: sin franja. El texto
       no se mueve porque el crecimiento en alto compensa este tiro. */
    margin-top: calc(-1 * var(--ga-nav-height));
    background-color: var(--ga-verde-oliva-oscuro);   /* base mientras carga la foto */
}

/* Sin foto de portada: verde oliva macizo. El velo se mantiene y el titular se
   lee igual. */
.ga-nosotros-hero--liso {
    background-color: var(--ga-verde-oliva-oscuro);
}

/* ——— LA FOTO DE PORTADA ———
   Es una <img> REAL (con alt y con prioridad de carga alta), no un fondo CSS:
   un fondo no admite texto alternativo y el navegador lo descubre más tarde.

   Se comporta como un fondo gracias a position:absolute + inset:0 + object-fit:
   cover → llena el hero a cualquier altura y en cualquier ancho SIN deformarse,
   recortando lo que sobre por el lado largo. inset:0 la ata a las cuatro
   esquinas del hero, así que no puede sobresalir ni a 360px: nada de scroll
   horizontal y nada de overflow que haga falta recortar.

   Dos clases (0-2-0) para ganar a la regla global `img { height: auto }` y a
   cualquier regla de <img> que traiga Astra. */
.ga-main--nosotros .ga-nosotros-hero__foto {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    max-width: 100%;
    object-fit: cover;             /* cubre sin estirar: no hay franjas vacías */
    /* ENCUADRE vertical. El hero ahora es más alto (70vh + alto de cabecera) y
       sus 80px/64px superiores quedan bajo el header, así que object-fit calcula
       el recorte sobre una caja más alta: con el 55% de antes la ventana visible
       (los 70vh de debajo de la cabecera) mostraba la foto más BAJA y volvía a
       comerse la cabeza. Se baja el valor al 46% para devolver ese margen
       superior y recuperar el mismo encuadre que se veía antes del cambio: la
       persona centrada y completa, con la cabeza sin cortar.
       ⚠ HISTORIA DEL VALOR:
       · Con el hero a 70vh (sin crecer), el equilibrio era 55%
         (75% cortaba la cabeza · 60/57% la rozaban).
       · Al crecer el hero bajo la cabecera, el equivalente de aquel 55% pasa a
         ~46% (el desplazamiento depende un poco del alto de pantalla).
       · 50% → 60% → 55%: se fue bajando para enseñar más suelo (las aceitunas)
         y 60% bajó DEMASIADO; 55% es el punto de ajuste actual, ciñe el encuadre
         al sujeto sin cortarle la cabeza. No subir de aquí sin volver a mirar
         la foto.
       Eje: a MÁS %, la ventana baja y se ve más suelo; a MENOS, sube y se ve más
       cielo/cabeza.
       El valor va SOLO aquí, en la regla base, y por la cascada vale igual en
       escritorio, tablet y móvil (en móvil la foto no recorta en vertical, así
       que este % ni se nota). Si algún día se quisiera un encuadre distinto en
       móvil, habría que declararlo con estas MISMAS dos clases
       (.ga-main--nosotros .ga-nosotros-hero__foto), o perdería por especificidad
       aunque fuese después. */
    object-position: center 55%;
    display: block;
}

/* Velo de marca, nunca negro puro: degradado del negro suave (26,26,20) al
   verde oliva (74,74,47), más denso abajo, que es donde va el texto. Con él el
   titular blanco queda muy por encima del 4,5:1 de AA sobre cualquier foto. */
.ga-nosotros-hero__velo {
    position: absolute;
    inset: 0;
    background-image: linear-gradient(
        to bottom,
        rgba(26, 26, 20, 0.30) 0%,
        rgba(26, 26, 20, 0.38) 45%,
        rgba(74, 74, 47, 0.86) 100%
    );
}

.ga-nosotros-hero__inner {
    position: relative;   /* por encima de foto y velo, sin z-index inventado */
    width: 100%;
}

/* El FILETE DORADO sobre el titular se ha ELIMINADO: ya no existe ni el
   <span class="ga-nosotros-hero__filete"> del HTML ni su regla aquí (tampoco la
   que lo estrechaba a 48px en móvil). La clase no se usaba en ninguna otra
   sección del sitio, así que se ha podido borrar entera sin acotar nada.
   El espacio que ocupaba lo reserva ahora el margin-top del titular. */

/* clamp: 36px en móvil estrecho → 64px en escritorio.

   REPARTO EN LÍNEAS: no hay ni un solo salto forzado en el HTML (ni <br> ni
   <span>). La medida la marca el max-width en `ch` —una unidad que va con el
   tamaño de letra, así que el número de caracteres por línea se mantiene a
   cualquier ancho— y el equilibrado lo hace text-wrap: balance, que iguala el
   largo de las líneas en vez de dejar la última coja.
   Los 22ch son para la frase actual, de 52 caracteres: la parte en tres líneas
   parejas. Antes eran 18ch, calculados para un titular de 44. */
.ga-nosotros-hero__titulo {
    max-width: 22ch;                /* corta la línea sin fijar ningún ancho */
    font-family: var(--ga-font-display);
    font-size: clamp(2.25rem, 6vw, var(--ga-text-6xl));
    font-weight: var(--ga-weight-bold);
    line-height: 1.05;
    color: var(--ga-blanco);
    text-wrap: balance;
}

.ga-nosotros-hero__texto {
    margin: var(--ga-space-md) 0 0;
    max-width: 56ch;
    font-family: var(--ga-font-body);
    font-size: clamp(1rem, 2.2vw, var(--ga-text-lg));
    line-height: 1.7;
    color: var(--ga-naranja-claro);   /* crema #F9F6EE */
    opacity: 0.92;                    /* anula el 0.85 global de <p> */
    text-wrap: pretty;
}


/* ─────────────────────────────────────────────
   2 · RECORRIDO — escenario fijo (scrollytelling)

   El BLOQUE se queda fijo y lo que cambia es el contenido: sensación de que la
   página no baja. Montaje:
     .__pista      → contenedor MÁS ALTO que la pantalla; es el carril de scroll.
                     Su altura (nº de pares × alto por par) da el recorrido.
     .__escenario  → position: sticky; se queda pegado bajo la cabecera mientras se
                     recorre la pista.
     .__par        → cada par (texto + imagen) va en position:absolute llenando el
                     escenario; los 5 se apilan y solo el activo está a opacity 1.
                     El fundido cruza texto e imagen a la vez.
   Qué par se ve lo decide gaNosotrosRecorrido() de forma PASIVA por la posición de
   scroll (sin tocar el scroll del usuario). El primero nace is-activa: se ve sin JS.

   ⚠ El alto de la pista cuenta 5 pares (var --ga-recorrido-pares). Si se añade o
   quita uno, ajustar ese número (el JS usa el recuento real; solo la pista lo fija).

   MÓVIL (<=768px): ver el @media; se suelta el sticky y los pares se apilan.
   ───────────────────────────────────────────── */
.ga-nosotros-recorrido {
    --ga-recorrido-pares: 5;                    /* nº de pares: cámbialo al añadir/quitar bloques */
    --ga-recorrido-vh: 80vh;                    /* scroll por par (antes 100vh): que pasen algo antes */
    --ga-recorrido-img: 400px;                  /* ancho de la imagen (lo más alto del par) */
    --ga-recorrido-pad: var(--ga-space-xl);     /* aire interior del marco, igual por los 4 lados (64px) */
    --ga-recorrido-texto-min: 560px;            /* alto RESERVADO para el texto del par más largo (par 5): el
                                                   panel se ciñe al MÁXIMO entre esto y la imagen, así el texto,
                                                   anclado arriba, no se sale por abajo en anchos normales. */
    --ga-verde-claro-nosotros: #DEDFCF;         /* verde claro del FONDO exterior (antes #C3C4AA, aún más claro) */
    /* Padding SUPERIOR intacto (space-2xl). El INFERIOR se recorta (space-2xl → space-md):
       junto con el superior recortado de la vitrina, quita la franja verde vacía que había
       entre el recorrido y el carrusel. No toca el sticky ni la altura de la pista. */
    padding: var(--ga-space-2xl) 0 var(--ga-space-md);
    background-color: var(--ga-verde-claro-nosotros);   /* superficie sobre la que se apoya el panel verde */
}

/* Carril de scroll: más alto que la pantalla (cada par dispone de --ga-recorrido-vh
   ≈ 80vh). NO crea ninguna fila horizontal, solo altura. */
.ga-nosotros-recorrido__pista {
    position: relative;
    height: calc(var(--ga-recorrido-pares) * var(--ga-recorrido-vh));
    padding-inline: var(--ga-space-md);   /* aire lateral: el marco no toca los bordes */
}

/* El bloque que se queda FIJO. top cuenta el alto de la cabecera fija (80px) más un
   respiro.
   ALTURA AJUSTADA al contenido (antes casi toda la pantalla, con mucho vacío
   arriba y abajo): ahora se ciñe a la IMAGEN, que es lo más alto del par
   (--ga-recorrido-img de ancho × 5/4 de alto), MÁS el aire de arriba y abajo
   (2 × pad) y el borde (2px). Con min() nunca supera el hueco de pantalla bajo la
   cabecera, para que quepa entera también en viewports bajos. Sigue siendo FIJA,
   que la necesita el sticky, pero ceñida. */
.ga-nosotros-recorrido__escenario {
    /* Alto del marco, ceñido a la imagen (lo más alto: --ga-recorrido-img × 5/4)
       más el aire de arriba y abajo (2 × pad) y el borde (2px), con tope de
       viewport. En una variable para reutilizarlo en el top centrado. */
    --ga-recorrido-alto: min(
        /* MÁXIMO entre el alto de la imagen (img × 5/4) y el reservado para el texto del par 5,
           más el aire (2 × pad) y el borde (4px). Así el panel es estable y cabe la foto Y el
           texto más largo. Sigue con tope de viewport, así que en pantallas bajas no lo supera. */
        calc(max(var(--ga-recorrido-img) * 5 / 4, var(--ga-recorrido-texto-min)) + 2 * var(--ga-recorrido-pad) + 4px),
        calc(100vh - var(--ga-nav-height) - var(--ga-space-lg))
    );
    position: sticky;
    /* CENTRADO vertical en la ventana mientras dura el recorrido:
       top = (alto de ventana − alto del marco) / 2. Con max() nunca sube por encima
       de la cabecera fija (80px + un respiro): en viewports bajos se queda justo
       debajo de ella en lugar de quedar tapado. */
    top: max(
        calc(var(--ga-nav-height) + var(--ga-space-sm)),
        calc((100vh - var(--ga-recorrido-alto)) / 2)
    );
    height: var(--ga-recorrido-alto);
    /* MARCO: VERDE OSCURO de marca con borde dorado y esquinas suaves. Va en el
       ESCENARIO (el sticky), así que el rectángulo se queda FIJO y dentro cambian los
       pares.
       ⚠ SIN padding: un position:absolute con inset se mide desde el BORDE del
       contenedor (su bloque contenedor es la caja de padding), así que IGNORA el
       padding del escenario. El aire interior lo pone el `inset` de cada par (abajo),
       no este contenedor. Por eso no hay `padding` aquí.
       🔴 SIN overflow (queda en visible): recortar aquí, en el propio sticky o en un
       ancestro, rompería la fijación. Las esquinas de la foto las redondea cada
       figura por su cuenta (overflow:hidden en la figura, que es descendiente). */
    max-width: var(--ga-max-width);
    margin-inline: auto;
    background-color: var(--ga-verde-oliva-oscuro);   /* verde oscuro de marca */
    border: 2px solid var(--ga-naranja-apagado);      /* ÚNICO marco dorado (exterior) */
    border-radius: var(--ga-radius-md);
}

/* Cada par se coloca a `pad` de los CUATRO bordes del marco (inset), que es el aire
   interior REAL: el padding del escenario lo ignora un absolute. Así el texto de la
   izquierda queda a la misma distancia del borde dorado que la imagen de la derecha.

   Activación DISCRETA: el JS solo pone/quita .is-activa (un par activo a la vez).

   ——— EFECTO CORTINA (clip-path) ———
   Todos los pares se solapan (mismo inset) y están SIEMPRE opacos. Lo que decide qué se ve
   es el RECORTE, no la opacidad:
     · Por defecto un par está REVELADO (clip-path: inset(0)).
     · Los pares POSTERIORES al activo (regla `~` de abajo) se ocultan colapsándose por
       ARRIBA (inset(100% …) → 0px de alto visible).
   Como los pares van en orden en el DOM (par1…par5), el par ACTIVO es más tardío que los de
   índice menor → los tapa por completo cuando está revelado. Al avanzar (A→B, B posterior),
   B pasa de oculto a revelado y su recorte sube de abajo hacia arriba: mientras no está del
   todo revelado, por su zona aún recortada asoma el par anterior (que sigue revelado justo
   debajo) → NUNCA hay un instante en blanco. Al retroceder, el par de arriba se colapsa
   hacia abajo y descubre el de debajo. Solo se anima clip-path (400-500ms, curva suave): no
   se mueve ni se redimensiona ninguna caja, y el recorte va en el PAR (descendiente del
   escenario), nunca en un ancestro → el sticky no se toca. */
.ga-nosotros-recorrido__par {
    position: absolute;
    inset: var(--ga-recorrido-pad);  /* aire interior por los 4 lados (lo que el padding no hacía) */
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--ga-space-xl);
    align-items: start;              /* TEXTO anclado ARRIBA: así número/título/párrafo arrancan a la
                                        misma altura en los 5 pares (antes `center` → el bloque, al medir
                                        distinto según el texto, subía su borde superior de forma desigual).
                                        La FIGURA no se ve afectada: lleva su propio align-self: center. */
    pointer-events: none;            /* el par no lleva cortina: la cortina va en la figura (abajo) */
}

/* ——— CORTINA SOLO EN LA IMAGEN ———
   La cortina (clip-path) se aplica a la FIGURA, no al par: así el TEXTO (la otra columna del
   par) NO se recorta ni se desplaza; el texto hace su propio fundido de opacidad aparte.
   Figuras POSTERIORES a la activa: cortina BAJADA (colapsadas por arriba → nada visible). La
   figura activa y las anteriores quedan reveladas; la activa tapa a las previas por orden DOM,
   así que al subir la nueva asoma la anterior justo debajo → sin instante en blanco. */
.ga-nosotros-recorrido__par.is-activa ~ .ga-nosotros-recorrido__par .ga-nosotros-recorrido__figura {
    clip-path: inset(100% 0 0 0);
}

/* Arranque sin JS: el primer par nace con is-activa desde el servidor, así que los demás
   quedan ocultos por la regla `~` y solo se ve el primero. El JS solo alterna .is-activa. */
.ga-nosotros-recorrido__par.is-activa {
    pointer-events: auto;
}

/* ——— CARRIL DE ANCLAJE (scroll snap) ———
   Capa ABSOLUTA que cubre la pista (inset:0 → toma su alto, sin añadir flujo) y no
   intercepta nada. Dentro, un .__tramo por par, cada uno de un alto = un par: su
   scroll-snap-align marca el punto donde el scroll "cae". Es invisible.
   🔴 NO lleva overflow: no toca la fijación del escenario. */
.ga-nosotros-recorrido__riel {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    pointer-events: none;
}

.ga-nosotros-recorrido__tramo {
    flex: 0 0 var(--ga-recorrido-vh);   /* un tramo por par, igual que la pista */
    scroll-snap-align: start;
}

/* Columna de texto, anclada ARRIBA (no centrada): número/título/párrafo arrancan en el
   mismo punto en los cinco pares y el párrafo crece hacia abajo según su longitud.
   margin-top: baja el conjunto un poco para repartir mejor el espacio (el punto de arranque
   común pasa más abajo; los cinco siguen arrancando IGUAL). Es moderado y limitado por el
   par 5, el más largo: más margen lo sacaría del panel en anchos de ~1024px (columnas
   estrechas, poca holgura). Solo mueve el bloque; no cambia tamaños. */
.ga-nosotros-recorrido__texto-col {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    margin-top: var(--ga-space-sm);
    /* El TEXTO no lleva cortina ni desplazamiento: la cortina (clip-path) va solo en la
       figura. Aquí solo se muestra el texto del par ACTIVO y se ocultan los demás con un
       fundido de opacidad MUY BREVE (150ms). Misma clase .is-activa que la imagen → texto e
       imagen siempre sincronizados. Solo opacidad: no mueve ni redimensiona nada. */
    opacity: 0;
    transition: opacity var(--ga-transition-fast);
}
.ga-nosotros-recorrido__par.is-activa .ga-nosotros-recorrido__texto-col {
    opacity: 1;
}

/* NÚMERO DE PARADA (01…05): ANTETÍTULO grande en dorado tenue, ENCIMA del título.
   Va EN FLUJO (primer hijo de la columna de texto), así reserva su propio espacio y el
   título cae debajo: no puede solaparse con él en ninguno de los cinco pares, mida lo
   que mida el título. margin-bottom da la separación. No es decorativo de fondo, es un
   rótulo legible, por eso opacidad alta (0.55) en vez de la marca de agua anterior. */
.ga-nosotros-recorrido__num {
    display: block;
    margin: 0 0 var(--ga-space-lg);        /* MUCHO más aire con el título (antes space-sm/16px → 64px).
                                              Va en flujo, así que solo separa; no descoloca ni rompe el
                                              centrado vertical del bloque de texto. */
    font-family: var(--ga-font-display);
    font-size: clamp(2.5rem, 5vw, 3.5rem);
    line-height: 1;
    font-weight: 600;
    letter-spacing: 0.02em;
    color: var(--ga-naranja-apagado);      /* dorado de marca */
    opacity: 0.55;                         /* tenue pero claramente legible por encima del título */
    user-select: none;
    -webkit-user-select: none;
}

.ga-nosotros-recorrido__texto {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-lg);
    line-height: 1.8;
    color: var(--ga-blanco);         /* blanco sobre el verde oscuro del marco */
    opacity: 0.92;                   /* anula el 0.85 global de <p>; casi pleno para buen contraste */
    max-width: 46ch;
    text-wrap: pretty;
    overflow-wrap: anywhere;         /* corta el ancho mínimo sin recurrir a min-width */
}

/* Dos versiones del párrafo conviven en el HTML; el CSS muestra una según el ancho. Por
   DEFECTO (escritorio/tablet, >768px): se ve la AMPLIA y se oculta la de móvil. En el
   media query de móvil (≤768px, más abajo) se invierte. Solo alterna display: ninguno
   cambia tamaños ni toca el sticky. */
.ga-nosotros-texto--movil {
    display: none;
}
.ga-nosotros-texto--amplio {
    display: block;
}

/* ——— EL MARCO DE LA IMAGEN ———
   NO llena la columna: se le da un ancho máximo contenido (~400px) y proporción
   vertical 4:5, y se centra en su celda (align/justify-self: center) tanto en
   vertical como en horizontal. El texto de la izquierda sigue estirándose a todo
   el alto del escenario (align-self por defecto: stretch) y centrando su contenido,
   así que su posición no cambia.
   · width: min(100%, 400px) → nunca más ancha que ~400px ni que su columna.
   · max-height: 100% → nunca más alta que el escenario (su celda).
   object-fit: cover recorta la foto sin deformarla. */
.ga-nosotros-recorrido__figura {
    align-self: center;
    /* CENTRADA en su columna (antes `end`, pegada al borde derecho): con `end` todo el
       hueco de la columna quedaba a la IZQUIERDA de la foto (mucho aire entre el texto y la
       imagen) y nada a la derecha. Con `center` el aire se reparte, la foto se acerca al
       texto y respira más equilibrada. Es solo alineación de rejilla (no position ni
       transform): no toca el sticky ni el efecto cortina. En columnas estrechas (tablet)
       la imagen vale el 100% de la columna y no se nota. */
    justify-self: center;
    /* Retoque sutil: con `center` la foto quedó demasiado separada del borde derecho.
       Un margen izquierdo la empuja HACIA LA DERECHA ~la mitad de esa separación (por el
       centrado de rejilla, un margen M desplaza M/2: space-lg=40 → ~20px), sin volver al
       `end` original. Solo margen (ni position ni transform). Se anula en móvil, donde la
       foto va a ancho completo. */
    margin-inline-start: var(--ga-space-lg);
    width: min(100%, var(--ga-recorrido-img));
    max-height: 100%;
    aspect-ratio: 4 / 5;
    position: relative;
    overflow: hidden;                /* recorta la foto a las esquinas; ningún eje en auto */
    border-radius: var(--ga-radius-md);   /* solo esquinas redondeadas, sin borde dorado */
    background-color: var(--ga-amarillo-pastel);
    box-shadow: var(--ga-shadow-sm);
    clip-path: inset(0);                  /* REVELADA por defecto; la cortina de la imagen la anima */
    transition: clip-path 450ms ease;     /* efecto cortina — SOLO la imagen */
}

.ga-nosotros-recorrido__media {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Respaldo si la foto aún no está subida: color de marca, nunca una <img> rota. */
.ga-nosotros-recorrido__media--respaldo {
    background-color: var(--ga-amarillo-pastel);
    background-image: linear-gradient(
        135deg,
        rgba(199, 168, 98, 0.30) 0%,
        rgba(127, 134, 73, 0.22) 100%
    );
}

/* ——— BARRA DE PROGRESO DEL RECORRIDO ———
   Fila de 5 segmentos ABAJO dentro del marco verde, en la banda de aire inferior: los
   pares están a `pad` (64px) de los bordes, así que a `bottom: space-md` la barra no pisa
   su contenido. Es ABSOLUTA → no añade flujo ni overflow al escenario y no lleva
   will-change: no toca el sticky. Cada segmento es un <button>; el estado lo pone el JS con
   el MISMO cálculo del par activo. Ningún estado cambia tamaño ni posición: solo color.

   A LA IZQUIERDA: `left: pad` la alinea con el borde izquierdo del bloque de texto (el par
   está inset `pad`, y la barra —hija del escenario— se mide desde el mismo origen que el
   par: la caja de padding del escenario). `right: auto` + flex-start la dejan pegada a la
   izquierda, sin centrar. */
.ga-nosotros-recorrido__progreso {
    position: absolute;
    left: var(--ga-recorrido-pad);
    right: auto;
    bottom: var(--ga-space-md);
    z-index: 2;                          /* sobre los pares, para poder pulsarlo */
    display: flex;
    justify-content: flex-start;
    gap: var(--ga-space-xs);
}

.ga-nosotros-recorrido__seg {
    width: 34px;
    height: 4px;
    padding: 0;
    border: 0;
    border-radius: 2px;
    cursor: pointer;
    background-color: rgba(199, 168, 98, 0.18);   /* PENDIENTE: dorado apenas visible sobre el verde */
    transition: background-color 200ms ease, opacity 200ms ease;
}

/* PASADO: dorado tenue. */
.ga-nosotros-recorrido__seg.is-pasada {
    background-color: rgba(199, 168, 98, 0.5);
}

/* ACTIVO: dorado lleno de marca. */
.ga-nosotros-recorrido__seg.is-activa {
    background-color: var(--ga-naranja-apagado);
}

/* Hover: realce de color en los no-activos; el activo ya está pleno. Solo color. */
.ga-nosotros-recorrido__seg:hover {
    background-color: rgba(199, 168, 98, 0.7);
}
.ga-nosotros-recorrido__seg.is-activa:hover {
    background-color: var(--ga-naranja-apagado);
}

/* Foco visible para teclado. outline no ocupa layout → no mueve nada. */
.ga-nosotros-recorrido__seg:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

/* Movimiento reducido: sin cortina ni fundido; imagen y texto cambian de golpe (instantáneo). */
@media (prefers-reduced-motion: reduce) {
    .ga-nosotros-recorrido__figura,
    .ga-nosotros-recorrido__texto-col {
        transition: none;
    }
}

/* ─────────────────────────────────────────────
   2b · VITRINA (carrusel coverflow de 5 tarjetas)
   ─────────────────────────────────────────────
   Coverflow PLANO (solo escala + opacidad, sin 3D). Las tarjetas van absolutas dentro del
   marco → NO hay fila real más ancha que el viewport, así que NO se infla la maquetación.
   Lo que asoma por los lados lo recorta el marco con overflow:clip (no crea contenedor de
   scroll, no toca html/body ni ancestros del recorrido de arriba). La posición la fija una
   clase por tarjeta (.pos-c central, .pos-l1/r1 adyacentes, .pos-l2/r2 extremos, .pos-out
   fuera) que pone el servidor y actualiza el JS. Todos los offsets son múltiplos del ancho
   de tarjeta → escalan solos. */

/* La variable del verde claro (--ga-verde-claro-nosotros) estaba declarada SOLO en
   .ga-nosotros-recorrido, y una sección hermana no la hereda. Se ELEVA aquí, al ancestro
   común de ambas secciones, para poder REUTILIZARLA en el carrusel sin repetir el hex en su
   bloque ni tocar el recorrido (que conserva su declaración local, ya redundante). */
.ga-main--nosotros {
    --ga-verde-claro-nosotros: #DEDFCF;
}

.ga-nosotros-vitrina {
    --vitrina-card-w: clamp(252px, 26vw, 344px);   /* ancho de tarjeta (algo mayor, para el margen blanco) */
    --vitrina-alto: 660px;                          /* alto del marco = tarjeta (foto ~cuadrada + texto + número abajo) */
    --vitrina-off1: calc(var(--vitrina-card-w) * 1.05);   /* distancia de las adyacentes (más separadas de la central) */
    --vitrina-off2: calc(var(--vitrina-card-w) * 1.95);   /* distancia de los extremos: off2 ajustado para que el
                                                             HUECO entre cada par de tarjetas contiguas sea el mismo
                                                             (antes 1.72, con el extremo montado sobre la adyacente). */
    --vitrina-dur: 500ms;
    /* Padding SUPERIOR recortado (space-2xl → space-md): con el inferior del recorrido, cierra
       la franja verde vacía entre secciones. El INFERIOR (hacia Olivos) se mantiene en space-2xl. */
    padding: var(--ga-space-md) 0 var(--ga-space-2xl);
    background-color: var(--ga-verde-claro-nosotros);   /* mismo verde claro que la sección de recorrido */
    overflow: clip;                                 /* cortafuegos: nada sobresale a lo ancho de la sección */
}

.ga-nosotros-vitrina__carrusel {
    position: relative;                             /* contexto de las flechas */
    max-width: var(--ga-max-width);
    margin: 0 auto;
}

/* MARCO: viewport que recorta. overflow:clip recorta las laterales SIN crear scroll ni
   inflar. Las tarjetas son absolutas, así que el marco necesita alto propio.
   FUNDIDO DE BORDES (opción de máscara elegida): en vez de un corte recto, las tarjetas
   extremas se DESVANECEN hacia los lados del marco. Es solo pintado (alpha) → ni layout,
   ni scroll, ni inflado del viewport. Las flechas viven FUERA del marco, así que la máscara
   no las toca. Se desactiva en móvil (≤768px), donde la central ocuparía la franja de fundido.
   Navegadores sin mask-image: se quedan con el recorte de siempre (degradación aceptable). */
.ga-nosotros-vitrina__marco {
    position: relative;
    width: 100%;
    height: var(--vitrina-alto);
    overflow: clip;
    --vitrina-fundido: var(--ga-space-xl);   /* 64px de desvanecimiento a cada lado */
    -webkit-mask-image: linear-gradient(to right, transparent 0, #000 var(--vitrina-fundido), #000 calc(100% - var(--vitrina-fundido)), transparent 100%);
            mask-image: linear-gradient(to right, transparent 0, #000 var(--vitrina-fundido), #000 calc(100% - var(--vitrina-fundido)), transparent 100%);
}
@supports not (overflow: clip) {
    .ga-nosotros-vitrina__marco { overflow: hidden; }   /* navegadores viejos: recorta igual */
}

.ga-nosotros-vitrina__pista {
    position: absolute;
    inset: 0;
}

/* TARJETA. Absoluta y centrada; la clase de posición cambia translate/scale/opacidad. Solo
   se anima transform y opacity → ni reflow ni cambio de layout. Estado base = fuera. */
.ga-nosotros-vitrina__card {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--vitrina-card-w);
    height: var(--vitrina-alto);
    display: flex;
    flex-direction: column;
    background-color: var(--ga-blanco);
    /* Marco: verde oliva oscuro de marca a baja intensidad (16%), no el dorado que
       resaltaba demasiado. Fino y discreto sobre el blanco, coherente con el verde. */
    border: 1px solid rgba(74, 74, 47, 0.16);
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    box-shadow: var(--ga-shadow-sm);
    transform: translate(-50%, -50%) scale(0.62);
    opacity: 0;
    z-index: 1;
    pointer-events: none;
    transition: transform var(--vitrina-dur) cubic-bezier(0.25, 0.1, 0.25, 1),
                opacity var(--vitrina-dur) ease;
}

/* VELO BLANCO de las laterales (ver reglas .pos-* más abajo). Va en un ::after que cubre la
   tarjeta y la desvaída HACIA EL BLANCO (nunca oscuro). Solo aspecto: no cambia tamaño ni
   posición. La central no lleva velo (opacity 0). */
.ga-nosotros-vitrina__card::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    background-color: var(--ga-blanco);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--vitrina-dur) ease;
}

/* CENTRAL: grande, nítida, encima. Solo esta recibe clics (enlaces, etc.). */
.ga-nosotros-vitrina__card.pos-c {
    transform: translate(-50%, -50%) scale(1);
    opacity: 1;
    z-index: 6;
    pointer-events: auto;
}
/* ADYACENTES: algo más pequeñas y atenuadas. */
.ga-nosotros-vitrina__card.pos-l1 {
    transform: translate(calc(-50% - var(--vitrina-off1)), -50%) scale(0.85);
    opacity: 0.5;
    z-index: 5;
}
.ga-nosotros-vitrina__card.pos-r1 {
    transform: translate(calc(-50% + var(--vitrina-off1)), -50%) scale(0.85);
    opacity: 0.5;
    z-index: 5;
}
/* EXTREMOS: aún más pequeños y tenues, asomando por los bordes (los recorta el marco). */
.ga-nosotros-vitrina__card.pos-l2 {
    transform: translate(calc(-50% - var(--vitrina-off2)), -50%) scale(0.7);
    opacity: 0.28;
    z-index: 4;
}
.ga-nosotros-vitrina__card.pos-r2 {
    transform: translate(calc(-50% + var(--vitrina-off2)), -50%) scale(0.7);
    opacity: 0.28;
    z-index: 4;
}
/* FUERA de las 5 posiciones visibles: ocultas. */
.ga-nosotros-vitrina__card.pos-out {
    transform: translate(-50%, -50%) scale(0.6);
    opacity: 0;
    z-index: 1;
}

/* LATERALES DESVAÍDAS HACIA EL BLANCO (no oscuras): un velo blanco tenue sobre cada lateral
   las aclara y suaviza, mientras la central se ve nítida y a plena intensidad. Más velo en
   los extremos que en las adyacentes. Solo aspecto (opacidad del velo): ni tamaño ni posición. */
.ga-nosotros-vitrina__card.pos-l1::after,
.ga-nosotros-vitrina__card.pos-r1::after {
    opacity: 0.34;
}
.ga-nosotros-vitrina__card.pos-l2::after,
.ga-nosotros-vitrina__card.pos-r2::after {
    opacity: 0.52;
}

/* Foto arriba, HUECO de proporción ~CUADRADA 4:4.3 (antes 4:5, más vertical). Así todas las
   tarjetas miden lo mismo. La foto va con object-fit: COVER: LLENA el hueco recortando un poco
   por arriba y por abajo (las fotos son 4:5), centrada, sin deformar. */
.ga-nosotros-vitrina__foto {
    position: relative;
    width: 100%;
    aspect-ratio: 4 / 4.3;
    flex-shrink: 0;
    overflow: hidden;
    padding: var(--ga-space-md);                 /* MARGEN BLANCO alrededor de la foto (más ancho que antes):
                                                    respira dentro de la tarjeta y no toca el borde ni el texto.
                                                    box-sizing:border-box → no cambia el tamaño de la tarjeta. */
    background-color: var(--ga-blanco);          /* mismo blanco de la tarjeta */
    margin: 0;
}
.ga-nosotros-vitrina__foto img {
    width: 100%;
    height: 100%;
    object-fit: cover;        /* LLENA el hueco recortando arriba/abajo, sin deformar */
    object-position: center;  /* encuadre centrado */
    display: block;
    user-select: none;
    -webkit-user-select: none;
    -webkit-user-drag: none;
}
/* Respaldo si la foto aún no está subida: color de marca, nunca una <img> rota. */
.ga-nosotros-vitrina__foto--respaldo {
    display: block;
    width: 100%;
    height: 100%;
    background-color: var(--ga-amarillo-pastel);
    background-image: linear-gradient(135deg, rgba(199, 168, 98, 0.30) 0%, rgba(127, 134, 73, 0.22) 100%);
}

.ga-nosotros-vitrina__cuerpo {
    display: flex;
    flex-direction: column;
    gap: var(--ga-space-xs);
    /* padding-top 0: el título va JUSTO debajo de la foto (el único aire arriba es el
       margen blanco inferior de la propia foto). Horizontal space-md (24), alineado con
       la foto; abajo space-md. */
    padding: 0 var(--ga-space-md) var(--ga-space-md);
    /* CAJA FIJA del bloque título+texto: la tarjeta es de alto fijo (--vitrina-alto) y la
       foto también, así que flex:1 hace que el cuerpo ocupe SIEMPRE el mismo hueco (el que
       sobra) en las cinco tarjetas. El título arranca a la misma altura (debajo de la foto,
       que mide igual) y el texto más corto deja aire abajo. min-height:0 permite recortar si
       alguna vez no cupiera, sin romper el flex. */
    flex: 1;
    min-height: 0;
}
.ga-nosotros-vitrina__titulo {
    margin: 0;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.12;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

/* 🔴 Astra inyecta margen a los <h3> con un selector que GANA a una sola clase (misma
   trampa que en el resto de títulos de la página): metía aire de más ENCIMA (separaba el
   título de la foto) y DEBAJO (separaba el título del texto). Se anula con DOS clases, así
   el bloque título+texto queda compacto. Solo margen: ni tamaño ni posición de vecinos. */
.ga-main--nosotros .ga-nosotros-vitrina__titulo {
    margin: 0;
}
.ga-nosotros-vitrina__texto {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.55;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.9;
    /* JUSTIFICADO: empieza y acaba a la misma altura izq/dcha. text-wrap: pretty mejora el
       reparto de las últimas líneas y hyphens: auto (con lang="es" que pone WordPress en
       <html>) permite partir palabras → menos huecos grandes entre palabras en columna
       estrecha. */
    text-align: justify;
    text-wrap: pretty;
    hyphens: auto;
    -webkit-hyphens: auto;
    overflow-wrap: anywhere;
}

/* NÚMERO de tarjeta (1–5), según el orden final. Serif de marca, discreto (tenue), abajo y
   centrado. margin-top:auto lo ancla al FONDO del cuerpo (flex column), debajo del texto;
   padding-top asegura un aire mínimo con el texto aunque este sea largo. */
.ga-nosotros-vitrina__num {
    margin-top: auto;
    padding-top: var(--ga-space-sm);
    text-align: center;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-lg);
    font-weight: var(--ga-weight-medium);
    line-height: 1;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.4;
}

/* TARJETAS LATERALES CLICABLES (sustituyen a las flechas): al hacer clic en una lateral, el
   carrusel navega hacia ella (esa tarjeta pasa a central). El JS marca cuáles son navegables
   con .is-navegable (y les pone role="button" + tabindex). Solo cursor y foco → ni tamaño ni
   posición cambian (el outline no altera el layout de los vecinos).
   🔴 pointer-events: auto es IMPRESCINDIBLE: la regla base .ga-nosotros-vitrina__card las pone en
   pointer-events:none (solo .pos-c las reactivaba), así que sin esto el clic NUNCA les llegaba.
   Especificidad 0-2-0 (dos clases) → gana al 0-1-0 de la base. */
.ga-nosotros-vitrina__card.is-navegable {
    cursor: pointer;
    pointer-events: auto;
}
.ga-nosotros-vitrina__card.is-navegable:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* El control del carrusel son las FLECHAS del cierre (.ga-nosotros-flechas): su CSS está más
   abajo, en el bloque del cierre. */

/* ——— MÓVIL (≤768px): una tarjeta a la vez, con un pequeño asomo de la siguiente ———
   Tarjeta más ancha, adyacentes casi fuera (asoman un poco) y extremos OCULTOS. Mismo
   mecanismo absoluto → no hay fila real, no se infla a 360px. */
@media (max-width: 768px) {
    .ga-nosotros-vitrina {
        --vitrina-card-w: 78vw;
        --vitrina-alto: 620px;                                /* foto ~cuadrada + texto + número abajo: cabe entero a 360px */
        --vitrina-off1: calc(var(--vitrina-card-w) * 1.02);   /* adyacente asoma un poco menos → más separación */
    }
    .ga-nosotros-vitrina__cuerpo { padding: var(--ga-space-sm); }
    /* Sin sitio para dos a cada lado: los extremos no se muestran en móvil. */
    .ga-nosotros-vitrina__card.pos-l2,
    .ga-nosotros-vitrina__card.pos-r2 {
        opacity: 0;
        transform: translate(-50%, -50%) scale(0.6);
    }
    /* Sin fundido en móvil: la tarjeta central ocupa casi todo el ancho y la franja de
       desvanecimiento le comería los bordes. Los extremos ya están ocultos, no hay corte que suavizar. */
    .ga-nosotros-vitrina__marco {
        -webkit-mask-image: none;
                mask-image: none;
    }
}

/* Movimiento reducido: sin desplazamiento; la tarjeta cambia de golpe. */
@media (prefers-reduced-motion: reduce) {
    .ga-nosotros-vitrina__card {
        transition: none;
    }
}


/* ─────────────────────────────────────────────
   CIERRE DEL CARRUSEL — flechas
   Debajo de la vitrina, sobre el mismo verde claro. El aire SUPERIOR lo da el padding
   inferior del carrusel (por eso las flechas no llevan margen arriba); el inferior separa del
   manifiesto. La sección termina en las DOS FLECHAS que controlan el carrusel.
   ───────────────────────────────────────────── */
.ga-nosotros-cierre-vitrina {
    /* Sube el bloque de flechas hacia las tarjetas: recorta el hueco que deja el padding inferior
       del carrusel (space-2xl). Mismo verde que el carrusel → sin costura visible; solo eje
       vertical → cero efecto horizontal, seguro a 360px. Aplica igual en escritorio, tablet y móvil
       (no está dentro de ningún media query). */
    margin-top: calc(-1 * var(--ga-space-xl));
    padding: 0 0 var(--ga-space-lg);
    background-color: var(--ga-verde-claro-nosotros);   /* mismo verde claro que el carrusel */
}

/* FLECHAS de navegación: SOLO el icono (trazo monolínea) en VERDE oliva de marca — sin círculo,
   aro ni fondo. El <button> es una caja transparente (zona clicable ~44px) que centra el SVG.
   Al PULSAR, el JS pone .is-pulsada (DORADO instantáneo) y la retira: la regla base retoma el
   verde con una transición LARGA (1,8s), así el dorado se DESVANECE progresivamente hasta el verde.
   Solo cambia el COLOR → nunca tamaño ni posición. Fila flex normal, sin overflow → no infla el
   viewport a 360px. */
.ga-nosotros-flechas {
    display: flex;
    justify-content: center;
    gap: var(--ga-space-xs);
    margin: 0 auto;
}
.ga-nosotros-flecha {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;                                /* nada de recuadro/sombra en reposo */
    color: var(--ga-verde-oliva-oscuro);             /* icono en VERDE oliva de marca (reposo) */
    cursor: pointer;
    transition: color 1.8s ease;                     /* al soltar el clic: dorado → verde progresivo */
}
/* 🔴 En hover/foco/activo se anula TODO lo que el TEMA (Astra) pinta en los <button>: el recuadro
   (box-shadow/fondo) y también el COLOR BLANCO que Astra pone en button:hover. El icono se queda
   SIEMPRE VERDE (salvo el destello dorado al pulsar, más abajo). !important para ganar a los
   globales del tema. Solo color: ni tamaño ni posición cambian. */
.ga-nosotros-flecha:hover,
.ga-nosotros-flecha:focus,
.ga-nosotros-flecha:active {
    background: none !important;
    box-shadow: none !important;
    outline: none !important;
    color: var(--ga-verde-oliva-oscuro) !important;   /* VERDE también en hover: nada de blanco */
}
/* Foco SOLO por teclado (:focus-visible): un CONTORNO FINO de marca (una línea, sin relleno ni
   sombra). Va DESPUÉS del grupo de arriba y con !important para ganarle el outline con teclado
   (misma especificidad → decide el orden). Con ratón solo aplica :focus → sin contorno. */
.ga-nosotros-flecha:focus-visible {
    background: none !important;
    box-shadow: none !important;
    outline: 2px solid var(--ga-naranja-apagado) !important;
    outline-offset: 1px;
    border-radius: var(--ga-radius-sm);
}
/* Al pulsar (clase puesta por el JS): DORADO instantáneo SOBRE EL ICONO. Va EL ÚLTIMO y con
   !important para ganar al verde de :hover/:active al pulsar (en escritorio pulsar = hover). Al
   quitar la clase, el icono vuelve al verde con la transición de 1,8s → el dorado se desvanece. */
.ga-nosotros-flecha.is-pulsada {
    color: var(--ga-naranja-apagado) !important;
    transition: none;
}
.ga-nosotros-flecha svg {
    display: block;
    width: 28px;
    height: 28px;
}
@media (prefers-reduced-motion: reduce) {
    .ga-nosotros-flecha { transition: none; }        /* sin desvanecido lento */
}


/* ─────────────────────────────────────────────
   4 · MANIFIESTO — LEMA
   Franja oscura a todo el ancho con un ÚNICO lema dorado, centrado horizontal y
   verticalmente. La textura va en una capa absoluta con inset:0 —no puede sobresalir— y a
   opacidad muy baja: por debajo del lema. La franja se centra con flex (columna); el gutter
   lateral lo pone .ga-nosotros-inner → a 360px el lema respira y no desborda.
   ───────────────────────────────────────────── */
.ga-nosotros-manifiesto {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;                      /* centra el lema verticalmente en la franja */
    min-height: clamp(240px, 40vh, 420px);        /* menos «verde vacío»: la franja se ajusta más al lema; min-height (no min-width) */
    padding: var(--ga-space-xl) 0;                /* padding vertical reducido (antes space-2xl) → franja más ajustada */
    background-color: var(--ga-verde-oliva-oscuro);
}

.ga-nosotros-manifiesto__textura {
    position: absolute;
    inset: 0;
    background-position: center;
    background-size: cover;
    background-repeat: no-repeat;
    opacity: 0.14;
}

.ga-nosotros-manifiesto__inner {
    position: relative;   /* sobre la textura, sin z-index inventado */
    text-align: center;
}

/* LEMA: serif de marca, protagonista pero contenido, en DORADO de marca con un BARRIDO DE LUZ
   CLARO (sheen) —el MISMO mecanismo que los títulos de sección de la tienda: reutiliza los
   @keyframes ga-tienda-titulo-brillo (ver más abajo, en el @supports)—. Base DORADA, banda
   clara/casi blanca que la recorre. Esta regla BASE es solo el color sólido = FALLBACK para
   navegadores sin background-clip:text. Ancho 48rem: la frase se reparte en 2-3 líneas holgadas
   sin ir de lado a lado (y a 360px el inner, con su gutter, la limita a una columna estrecha →
   sin desbordar). */
.ga-nosotros-manifiesto__lema {
    max-width: 48rem;
    margin: 0 auto;
    font-family: var(--ga-font-display);
    font-size: clamp(1.6rem, 4.2vw, 2.6rem);      /* protagonista pero contenido */
    font-weight: var(--ga-weight-bold);
    line-height: 1.22;
    text-align: center;
    color: var(--ga-naranja-apagado);             /* DORADO de marca (#c7a862) — fallback sin background-clip */
    opacity: 1;                                   /* anula el 0.85 global de <p> */
    text-wrap: balance;
}

/* Saltos de línea del lema SOLO para móvil: ocultos por defecto (escritorio y tablet), donde la
   frase fluye y se reparte sola. En el @media móvil se activan para forzar el reparto 2+2. */
.ga-nosotros-manifiesto__salto {
    display: none;
}

/* PRIMERA FRASE del lema, en dos variantes. Por defecto (escritorio y tablet) se ve la de "da"
   —la actual, sin cambios— y se oculta la de móvil. En el @media móvil se invierte y se muestra
   la de "produce", que equilibra mejor sus dos líneas. Las dos son inline dentro del <p>, así que
   heredan tipografía, tamaño y el brillo (background-clip:text del lema) sin tocar nada. */
.ga-nosotros-manifiesto__frase-mov {
    display: none;
}

/* BARRIDO DE LUZ (sheen) SOLO donde se puede recortar el degradado sobre el texto
   (background-clip:text). Reutiliza los @keyframes ga-tienda-titulo-brillo (los del título de
   sección de la tienda: 100%→0% de background-position). Base DORADA de marca y banda diagonal
   (110deg) CLARA/casi blanca (#F5EEDD) que la recorre, en bucle lento (7s). El rango 250% +
   no-repeat mantiene el degradado cubriendo SIEMPRE las letras → nunca quedan invisibles. Se anima
   solo background-position → ni reflow, ni cambio de tamaño, ni desbordamiento. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
    .ga-nosotros-manifiesto__lema {
        background-image: linear-gradient(
            110deg,
            var(--ga-naranja-apagado) 0%,
            var(--ga-naranja-apagado) 45%,
            #F5EEDD 50%,                        /* banda de luz CLARA/casi blanca */
            var(--ga-naranja-apagado) 55%,
            var(--ga-naranja-apagado) 100%
        );
        background-size: 250% 100%;
        background-repeat: no-repeat;
        background-position: 100% center;
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
        animation: ga-tienda-titulo-brillo 7s linear infinite;
    }
}

/* Ahorro de movimiento: sin barrido; el lema queda en DORADO SÓLIDO (se retira el degradado y se
   restaura el relleno de marca). Va DESPUÉS del @supports para ganarle por orden de aparición. */
@media (prefers-reduced-motion: reduce) {
    .ga-nosotros-manifiesto__lema {
        animation: none;
        background-image: none;
        color: var(--ga-naranja-apagado);
        -webkit-text-fill-color: var(--ga-naranja-apagado);
    }
}


/* ─────────────────────────────────────────────
   5 · POR QUÉ PUEDES FIARTE — SELLOS DE CONFIANZA
   Rejilla de 6 sellos: 3 → 2 → 1 columnas (grid, sin filas que desborden). Cada sello es
   icono + título + subtítulo, centrados. Fondo CREMA de sección; los iconos van en dorado de
   marca dentro de un aro fino (aspecto de sello).
   ───────────────────────────────────────────── */
.ga-nosotros-fiarte {
    /* Padding INFERIOR pequeño (space-md): la franja de credenciales (último elemento) queda cerca
       del borde inferior. Junto con el superior del cierre deja un hueco corto hacia el CTA, para
       que la franja quede centrada TIRANDO HACIA ABAJO respecto a los sellos. El superior se mantiene. */
    padding: var(--ga-space-2xl) 0 var(--ga-space-md);
    background-color: var(--ga-naranja-claro);   /* crema cálida (contrasta con el lema oscuro de arriba) */
}

.ga-nosotros-sellos {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ga-space-xl) var(--ga-space-md);
    list-style: none;
    margin: 0;
    padding: 0;
}

/* Contenedor-PÁGINA del carrusel de sellos: solo es una caja en móvil. En escritorio y tablet se
   hace display:contents → no genera caja y sus 2 sellos vuelven a ser celdas DIRECTAS de la rejilla
   .ga-nosotros-sellos (3×2 / 2×3), exactamente como antes de agrupar. El orden del DOM se conserva,
   así que la rejilla no cambia nada. */
.ga-nosotros-sello-pagina {
    display: contents;
}

/* Cada sello: columna centrada. La separación icono/título/subtítulo la da el gap. */
.ga-nosotros-sello {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--ga-space-sm);
}

/* Icono en un ARO fino dorado sobre disco blanco (aspecto de sello). Tamaño FIJO idéntico en las 6
   celdas → todos los iconos alinean igual. El color del trazo lo hereda el SVG (currentColor). */
.ga-nosotros-sello__icono {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 66px;
    height: 66px;
    border-radius: var(--ga-radius-full);
    border: 1px solid rgba(199, 168, 98, 0.45);
    background-color: var(--ga-blanco);
    color: var(--ga-naranja-apagado);            /* icono DORADO de marca */
    transition: border-color var(--ga-transition), box-shadow var(--ga-transition);
}
.ga-nosotros-sello__icono svg {
    display: block;
    width: 30px;
    height: 30px;
}

.ga-nosotros-sello__titulo {
    margin: 0;
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

.ga-nosotros-sello__texto {
    margin: 0;
    max-width: 32ch;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.8;
    text-wrap: pretty;
    overflow-wrap: anywhere;
}

/* INDICADOR del carrusel de sellos: SOLO se ve en móvil (el carrusel solo existe ahí). Oculto por
   defecto en escritorio y tablet, donde los sellos son una rejilla. En el @media móvil se muestra. */
.ga-nosotros-sellos-puntos {
    display: none;
}

/* Hover MUY leve, solo con ratón: el aro del sello pasa a dorado pleno + una sombra cálida suave.
   Ni tamaño ni posición cambian (solo borde y sombra). En táctil la regla ni existe. */
@media (hover: hover) and (pointer: fine) {

    .ga-nosotros-sello:hover .ga-nosotros-sello__icono {
        border-color: var(--ga-naranja-apagado);
        box-shadow: 0 4px 16px rgba(199, 168, 98, 0.22);
    }
}

/* ——— LÍNEA DE AVALES ———
   flex-wrap: wrap OBLIGATORIO: el número de elementos puede cambiar y una fila
   que no puede partir desborda y, en móvil, infla el viewport de maquetación.
   Los separadores son un ::before, no texto del HTML: si se quita un aval, no
   queda ningún "·" suelto. */
.ga-nosotros-avales {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.4rem 0.9rem;
    margin: var(--ga-space-xl) 0 0;   /* más aire ARRIBA (space-lg → space-xl): empuja la franja hacia abajo, hacia el CTA */
    padding: 0;
    list-style: none;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.6;
    text-align: center;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.75;
}

.ga-nosotros-avales li {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.ga-nosotros-avales li + li::before {
    content: "·";
    color: var(--ga-naranja-apagado);
}


/* ─────────────────────────────────────────────
   6 · CIERRE
   Franja estrecha (menos alto que el resto de secciones), fondo claro.
   ───────────────────────────────────────────── */
.ga-nosotros-cierre {
    /* Padding SUPERIOR pequeño (space-sm): con el inferior de la franja deja un hueco corto → el CTA
       queda cerca de la franja de credenciales. Padding INFERIOR también space-sm: el enlace de
       eventos queda casi al final de la sección, con solo un pequeño respiro antes del footer.
       El aire alrededor del botón lo dan los márgenes de la frase y del enlace, no este padding. */
    padding: var(--ga-space-sm) 0;
    background-color: var(--ga-naranja-claro);   /* crema #F9F6EE */
    text-align: center;
}

.ga-nosotros-cierre__frase {
    margin: 0 0 var(--ga-space-lg);   /* más aire entre la frase y el botón (space-md → space-lg) */
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 4vw, var(--ga-text-3xl));
    font-weight: var(--ga-weight-bold);
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 1;              /* anula el 0.85 global de <p> */
    text-wrap: balance;
}

/* Botón principal: verde oliva sólido, el mismo tratamiento que el CTA de la
   página de Contacto. Ancho automático (no al 100%): es una franja centrada.
   En hover y foco solo cambian fondo, borde y sombra. */
.ga-nosotros-btn {
    display: inline-block;
    max-width: 100%;
    padding: 1.1rem 2.5rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--ga-blanco);
    background-color: var(--ga-verde-oliva-oscuro);
    border: 1px solid var(--ga-verde-oliva-oscuro);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    transition: background-color var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

.ga-nosotros-btn:hover {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    box-shadow: var(--ga-shadow-md);
}

/* Foco de teclado: mismo aspecto que el hover más un anillo de box-shadow, que
   no ocupa espacio en el flujo → no mueve nada. */
.ga-nosotros-btn:focus-visible {
    outline: none;
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(74, 74, 47, 0.45);
}

.ga-nosotros-btn:active {
    background-color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
}

/* 🔴 BLINDAJE DEL COLOR DE TEXTO.
   Astra pinta color en los enlaces al pasar el ratón y al enfocarlos, y esas
   reglas ganan a un selector de una sola clase. Misma trampa ya documentada
   para los botones de la Tienda y de Contacto, y misma solución: !important
   acotado a ESTA página. Ninguna regla general del tema se toca. */
.ga-main--nosotros .ga-nosotros-btn,
.ga-main--nosotros .ga-nosotros-btn:hover,
.ga-main--nosotros .ga-nosotros-btn:focus,
.ga-main--nosotros .ga-nosotros-btn:focus-visible,
.ga-main--nosotros .ga-nosotros-btn:active {
    color: var(--ga-blanco) !important;
}

/* Enlace de texto de eventos: nunca un botón, para que no compita con el CTA de arriba. */
.ga-nosotros-cierre__enlace {
    margin: var(--ga-space-lg) 0 0;   /* más aire DEBAJO del botón (space-md → space-lg) */
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 1;
    text-wrap: pretty;
}

.ga-nosotros-cierre__enlace a {
    color: var(--ga-verde-montanas);
    text-decoration: underline;
    text-underline-offset: 3px;
    transition: color var(--ga-transition-fast);
}

/* Salto de línea del enlace de eventos SOLO para móvil: oculto por defecto (escritorio y tablet,
   donde la frase fluye sola). Va DENTRO del <a>, así que no parte el enlace: sigue siendo uno solo.
   En el @media móvil se activa. */
.ga-nosotros-cierre__enlace-salto {
    display: none;
}

/* Hover y foco: solo color. Ni tamaño, ni posición, ni grosor de subrayado. */
.ga-nosotros-cierre__enlace a:hover,
.ga-nosotros-cierre__enlace a:focus-visible {
    color: var(--ga-naranja-apagado);
    outline: none;
}


/* ——— TABLET (<=1024px) ———
   El escenario fijo del RECORRIDO SIGUE ACTIVO aquí: el efecto es para escritorio
   Y tablet, y solo se apaga en <=768px (más abajo). Aquí únicamente se ajusta el
   aire de las secciones y la rejilla de razones pasa a 2 columnas. */
@media (max-width: 1024px) {

    .ga-nosotros-hero {
        padding: var(--ga-space-xl) 0 var(--ga-space-lg);
    }

    .ga-nosotros-recorrido,
    .ga-nosotros-manifiesto,
    .ga-nosotros-fiarte {
        padding: var(--ga-space-xl) 0;
    }

    .ga-nosotros-sellos {
        grid-template-columns: repeat(2, minmax(0, 1fr));   /* tablet: 2 columnas */
    }

    /* La regla compartida de arriba deja la franja en space-xl arriba y abajo; aquí solo su padding
       INFERIOR baja a space-md para acercar también en tablet el CTA a la franja de credenciales. */
    .ga-nosotros-fiarte {
        padding-bottom: var(--ga-space-md);
    }
}


/* ——— MÓVIL (<=768px) ———
   Todo a una columna. Sin carruseles, sin filas horizontales: nada puede
   inflar el viewport de maquetación. */
@media (max-width: 768px) {

    .ga-nosotros-inner {
        padding: 0 var(--ga-space-sm);
    }

    /* ——— LEMA (manifiesto) en MÓVIL: más grande, más ancho y con reparto 2+2 ——— */

    /* AJUSTAR LA FRANJA al lema (menos verde vacío arriba y abajo): el padding vertical baja de
       space-xl (64px) —el que deja la regla compartida .ga-nosotros-recorrido/manifiesto/fiarte de
       arriba— a space-md (24px): menos de la mitad, con respiro cómodo. Además se retira el
       min-height de la base (clamp 240-420px), que forzaba una franja alta y, con el lema centrado,
       dejaba hueco verde por mucho que bajara el padding: en móvil la franja se ciñe al lema + este
       padding. Acotado al manifiesto: no toca el padding de recorrido ni fiarte de la regla
       compartida (misma especificidad, gana por ir después). */
    .ga-nosotros-manifiesto {
        min-height: auto;
        padding: var(--ga-space-md) 0;
    }

    /* ENSANCHAR: el gutter lateral del lema baja de space-sm (16px) a space-xs (8px), SOLO en la
       franja del manifiesto. Esta clase gana a .ga-nosotros-inner por ir después con la misma
       especificidad, así que solo se ensancha aquí; el resto de la página conserva sus 16px.
       Deja un margen lateral cómodo pero aprovecha más el ancho de la pantalla. */
    .ga-nosotros-manifiesto__inner {
        padding: 0 var(--ga-space-xs);
    }

    /* AGRANDAR: en móvil el lema quedaba en el mínimo del clamp base (1.6rem). Se sube y se hace
       fluido: crece con el ancho del móvil (7.2vw) con un suelo mayor que antes y un tope para no
       pasarse en móviles anchos. */
    .ga-nosotros-manifiesto__lema {
        font-size: clamp(1.7rem, 7.2vw, 2.1rem);
    }

    /* PRIMERA FRASE en móvil: se oculta la versión de "da" y se muestra la de "produce", que
       equilibra mejor las dos líneas ("produce" alarga la 2.ª y no deja palabra suelta). */
    .ga-nosotros-manifiesto__frase-esc {
        display: none;
    }
    .ga-nosotros-manifiesto__frase-mov {
        display: inline;
    }

    /* REPARTO 2+2: se activan los tres saltos del HTML (tras "barato,", tras "produce." y tras
       "queremos") → 4 líneas: «No hacemos el aceite más barato,» / «ni el que más litros produce.» /
       «Hacemos el que queremos» / «en nuestra propia mesa.». Si alguna línea no cupiera, el texto
       envuelve por su cuenta (nunca desborda: ninguna palabra es más ancha que la franja). */
    .ga-nosotros-manifiesto__salto {
        display: inline;
    }

    .ga-nosotros-hero {
        /* Misma lógica que en escritorio: 60vh visibles + el alto de la cabecera
           (aquí --ga-nav-height ya vale 64px, redefinida en :root dentro de este
           mismo @media). El margin-top negativo de la regla base también usa esa
           variable, así que crecimiento y tiro siguen cuadrando en móvil. */
        min-height: calc(60vh + var(--ga-nav-height));
        padding: var(--ga-space-lg) 0 var(--ga-space-md);
    }

    .ga-nosotros-hero__titulo {
        max-width: none;   /* a una columna, el clamp ya controla el tamaño */
    }

    /* Compensación del filete eliminado, con la medida que tenía en móvil:
       2px de alto + var(--ga-space-sm) de separación = 18px. Dos clases, como
       la regla base de márgenes. */
    .ga-main--nosotros .ga-nosotros-hero__titulo {
        margin-top: calc(var(--ga-space-sm) + 2px);
    }

    /* SOLO MÓVIL: se oculta el subtítulo del hero para dejar respirar al
       titular sobre la foto. display:none lo retira del flujo (no reserva
       espacio → sin hueco vacío), y como el inner va anclado a flex-end,
       el título se queda apoyado en la base igual que antes. En escritorio
       y tablet el subtítulo se mantiene: esta regla vive solo en este
       @media (max-width: 768px). El margin-top que había aquí se retira
       porque ya no aplica a un elemento oculto. */
    .ga-nosotros-hero__texto {
        display: none;
    }

    .ga-nosotros-recorrido,
    .ga-nosotros-manifiesto,
    .ga-nosotros-fiarte {
        padding: var(--ga-space-lg) 0;
    }
    /* Franja de credenciales cerca del borde inferior también en móvil (la regla de arriba deja
       space-lg): su padding inferior baja a space-sm → queda cerca del CTA. */
    .ga-nosotros-fiarte {
        padding-bottom: var(--ga-space-sm);
    }
    /* El cierre hereda de la base su padding (space-sm arriba y abajo): CTA cerca de la franja y
       enlace de eventos casi pegado al footer. No necesita medida propia en móvil. */

    /* Dos clases, como la regla base de márgenes: con una sola perdería por
       especificidad aunque vaya después. Más separación en móvil entre el título de sellos y el
       primer sello del carrusel (space-md → space-lg). */
    .ga-main--nosotros .ga-nosotros-titulo--centrado {
        margin-bottom: var(--ga-space-lg);
    }

    /* Salto controlado SOLO en móvil del título de los sellos: "Gran Almazara" pasa a bloque y cae
       ENTERA a la 2.ª línea, dejando "Por qué confiar en" (con "en") en la 1.ª. En escritorio y
       tablet el <span> es inline (regla base, sin tocar) y el título fluye como hasta ahora.
       Queda centrado porque hereda el text-align: center del título. */
    .ga-nosotros-fiarte-titulo__marca {
        display: block;
    }

    /* Enlace de eventos en móvil: se activa el salto para que quede en dos líneas
       "¿Tienes un evento próximamente?" / "Nosotros nos encargamos.". Sigue siendo un solo <a>. */
    .ga-nosotros-cierre__enlace-salto {
        display: inline;
    }

    /* ——— RECORRIDO: AQUÍ se apaga el escenario fijo ———
       La pista y el escenario se sueltan; los pares vuelven a flujo normal (texto
       arriba, foto debajo) y se apilan. El JS tampoco arranca por debajo de 769px,
       así que no hay ni sticky ni cálculos de scroll: exactamente como estaba.
       Se QUITA EL MARCO: apilado queda mejor sin un rectángulo enorme envolviéndolo
       todo; los pares respiran sobre el fondo de la sección, como el resto de la
       página. Y se suelta el aire lateral de la pista (ya lo pone cada par). */
    .ga-nosotros-recorrido__pista {
        height: auto;
        padding-inline: 0;
    }

    .ga-nosotros-recorrido__escenario {
        position: static;
        height: auto;
        max-width: none;
        margin-inline: 0;
        background: none;
        border: 0;
        border-radius: 0;
        padding: 0;
    }

    /* Sin marco (fondo blanco de la sección), el texto vuelve a OSCURO: en el marco
       verde de escritorio va blanco, pero aquí blanco sobre blanco no se vería.
       El título con dos clases, como su regla base, para ganar a Astra. */
    .ga-nosotros-recorrido__texto {
        flex-basis: 100%;        /* ocupa una fila entera: cae bajo la fila número+título, a ancho completo */
        color: var(--ga-verde-oliva-oscuro);
        opacity: 0.9;
        /* Justificado SOLO en móvil: cada línea empieza y acaba en el mismo punto. Para que en
           pantalla estrecha no se abran "ríos" de espacio entre palabras, se activa el guionado
           automático en español (el <html lang="es"> de WordPress lo alimenta). El text-wrap:
           pretty ya viene de la regla base. -webkit-hyphens para Safari. */
        text-align: justify;
        -webkit-hyphens: auto;
        hyphens: auto;
    }

    /* Móvil: se ve el párrafo CORTO y se oculta el amplio (al revés que en escritorio). */
    .ga-nosotros-texto--movil {
        display: block;
    }
    .ga-nosotros-texto--amplio {
        display: none;
    }

    .ga-main--nosotros .ga-nosotros-recorrido__titulo {
        /* flex-basis: 0 (no `auto`) es la CLAVE para que quede en LÍNEA con el número:
           con `auto`, el tamaño base del título era su ancho en una sola línea (max-content);
           en los títulos largos ese ancho + el número no cabían en la fila y flex-wrap
           empujaba el título ENTERO debajo del número. Con base 0, el título nunca fuerza el
           salto: se queda a la derecha del número y envuelve su propio texto en varias líneas
           dentro de su celda. */
        flex: 1 1 0;
        margin: 0;               /* sin el margin-bottom de escritorio: el aire lo pone el row-gap del contenedor */
        color: var(--ga-verde-oliva-oscuro);
    }

    /* El carril de anclaje sobra donde no hay sticky: sin puntos de snap en móvil. */
    .ga-nosotros-recorrido__riel {
        display: none;
    }

    /* La barra de progreso interactiva no tiene sentido con los pares apilados: fuera.
       (El número de parada y el marco dorado de la imagen SÍ se mantienen, quedan bien
       en vertical: no se tocan aquí.) */
    .ga-nosotros-recorrido__progreso {
        display: none;
    }

    .ga-nosotros-recorrido__par {
        position: static;
        display: block;
        padding: 0 var(--ga-space-md);   /* margen lateral del contenido: sube de space-sm (16px) a
                                            space-md (24px) para que número, título, párrafo y foto
                                            respiren respecto al borde. Uniforme: un solo contenedor. */
        opacity: 1;
        pointer-events: auto;
        transition: none;        /* el JS no corre en móvil; sin cortina */
    }

    /* Móvil: pares APILADOS y todas las imágenes visibles → NADA de cortina. Se anula el
       clip-path de la figura, incluida la regla `~` (más específica) que en escritorio oculta
       las figuras posteriores a la activa; si no, la del par 1 (que nace con is-activa)
       ocultaría las imágenes de los demás. Los textos ya van todos visibles (opacity:1 más abajo). */
    .ga-nosotros-recorrido__figura,
    .ga-nosotros-recorrido__par.is-activa ~ .ga-nosotros-recorrido__par .ga-nosotros-recorrido__figura {
        clip-path: none;
    }

    /* Separación entre pares apilados = el hueco entre el final de la foto de un par y el
       número del par siguiente (la figura no lleva margin inferior y el par no tiene padding
       vertical, así que este margin-top es TODO el aire). Se recorta de space-xl (64px) a
       space-lg (40px): pares más juntos, pero aún claramente por encima de los huecos
       internos del par (24px), para que un apartado se distinga del siguiente. */
    .ga-nosotros-recorrido__par + .ga-nosotros-recorrido__par {
        margin-top: var(--ga-space-lg);
    }

    /* MÓVIL (apilado): número y título EN LA MISMA FILA — número a la izquierda,
       título justo a su derecha. La columna de texto pasa de columna a FILA flexible
       con salto: número y título comparten la primera línea (alineados por su línea
       base, para que compartan pie) y el párrafo salta debajo a ancho completo.
       Solo aquí, en el @media móvil: en escritorio/tablet sigue mandando la regla base
       (flex-direction: column), que no se toca. */
    .ga-nosotros-recorrido__texto-col {
        display: flex;
        flex-direction: row;              /* CLAVE: la regla base es `column`; sin este override, número
                                             y título quedaban apilados aunque el contenedor fuese flex */
        flex-wrap: wrap;
        align-items: baseline;            /* número y título con la misma línea base */
        column-gap: var(--ga-space-sm);   /* aire horizontal entre número y título */
        row-gap: var(--ga-space-md);      /* separación de la fila número+título con el párrafo (antes la daba el margin del título) */
        opacity: 1;              /* móvil: pares apilados, TODOS los textos visibles (anula el opacity:0
                                    de escritorio, que solo mostraría el del par que nace con is-activa). */
        margin-top: 0;           /* el descenso del bloque es solo para el panel fijo; en móvil no aplica */
    }

    /* El número, inline con el título: se le quita el margin-bottom de space-lg (64px)
       que en escritorio lo separaba en vertical; aquí el hueco lo pone el column-gap.
       No se toca su tamaño. */
    .ga-nosotros-recorrido__num {
        flex: 0 0 auto;
        margin: 0;
    }

    /* La figura ocupa el ancho completo (se suelta el tope de ~400px de escritorio),
       debajo del texto, con aire. Conserva su aspect-ratio 4:5 como RESPALDO: si un par
       no tuviera foto, el <span> de respaldo (que sigue absoluto) necesita que la figura
       tenga alto propio. Con foto, el alto lo da directamente la <img> en flujo (regla
       de abajo), así que aquí ya no dependemos del aspect-ratio para la imagen. */
    .ga-nosotros-recorrido__figura {
        width: auto;
        max-height: none;
        aspect-ratio: 4 / 5;
        margin-top: var(--ga-space-md);
        margin-inline-start: 0;   /* sin el nudge de escritorio: aquí va a ancho completo */
    }

    /* 🔴 FIX Chrome Android — LAS FOTOS NO SE VEÍAN.
       En escritorio la foto va position:absolute dentro de la figura y esta saca su alto
       del aspect-ratio. En la vista apilada de móvil, Chrome Android NO resuelve ese alto
       cuando el único hijo de la figura es absoluto → la figura colapsa a 0 y la foto,
       recortada por overflow:hidden, queda invisible (Safari sí lo resolvía y la mostraba).
       SOLUCIÓN: devolver la <img> al FLUJO NORMAL (static + height:auto). Así es la propia
       foto (1200×1500 = 4:5) la que da el alto real a la figura, sin depender del
       aspect-ratio ni de ningún cálculo → se ve igual en Chrome Android y en Safari.
       Se resetea además todo lo que pudiera venir del modo escritorio/cortina. Solo la
       <img>: el respaldo (span sin foto) se deja absoluto, encuadrado por la figura. */
    img.ga-nosotros-recorrido__media {
        position: static;        /* reset del position:absolute de escritorio */
        width: 100%;
        height: auto;            /* alto real por la proporción intrínseca 4:5 de la foto */
        transform: none;         /* reset defensivo: sin transform heredado */
        opacity: 1;              /* siempre visible en la vista apilada (todas las fotos) */
        clip-path: none;         /* sin la cortina del modo escritorio */
    }

    /* ——— CARRUSEL DE SELLOS (SOLO móvil): 2 sellos APILADOS por página, desliza de 2 en 2 ———
       PISTA (.ga-nosotros-sellos) con overflow-x:auto + scroll-snap, SOLO aquí (jamás en html/body),
       que contiene PÁGINAS. Cada PÁGINA es flex:0 0 100% (el ancho visible exacto) con
       scroll-snap-align:start, y por dentro va en flex-direction:column → sus 2 sellos APILADOS (uno
       arriba, otro abajo). 6 sellos = 3 páginas de 2. La pista mide el 100% del inner (~328px a 360)
       y las 3 páginas (100% cada una) desbordan HACIA DENTRO → scrollea la PISTA, la página NO se
       infla ni scrollea de lado. Barra oculta; se navega con el dedo. Sin JS de arrastre. */
    .ga-nosotros-sellos {
        display: flex;
        flex-wrap: nowrap;
        gap: 0;                                /* páginas a tope: cada una 100%, SIN hueco entre ellas (clave del snap) */
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;                 /* Firefox: sin barra */
        align-items: stretch;                  /* todas las páginas IGUAL de altas → el carrusel no salta de alto al deslizar */
        /* list-style / margin / padding ya vienen a 0 desde la regla base */
    }
    .ga-nosotros-sellos::-webkit-scrollbar {
        display: none;                         /* Chrome / Safari: sin barra */
    }

    /* PÁGINA = un slide del ancho visible con los 2 sellos APILADOS y centrados en su alto. Como la
       pista iguala el alto de todas las páginas (align-items:stretch), el snap encaja sin descuadrar;
       los sellos conservan su alto natural (muy parejo entre sí) → nada se sale ni se solapa. Los 2
       sellos ocupan el ancho completo de la página (stretch por defecto) y su contenido va centrado
       por la regla base del sello. */
    .ga-nosotros-sello-pagina {
        flex: 0 0 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        gap: var(--ga-space-lg);               /* aire vertical cómodo entre el sello de arriba y el de abajo */
        scroll-snap-align: start;
    }

    /* Puntos del indicador, visibles solo en móvil: uno por página de 2 sellos. Ningún estado cambia
       tamaño ni posición: la página activa solo cambia de COLOR (dorado pleno). */
    .ga-nosotros-sellos-puntos {
        display: flex;
        justify-content: center;
        gap: var(--ga-space-xs);
        margin-top: var(--ga-space-md);
    }
    .ga-nosotros-sellos-punto {
        width: 8px;
        height: 8px;
        border-radius: var(--ga-radius-full);
        background-color: rgba(199, 168, 98, 0.30);   /* dorado tenue = página no activa */
        transition: background-color var(--ga-transition);
    }
    .ga-nosotros-sellos-punto.is-activo {
        background-color: var(--ga-naranja-apagado);  /* dorado pleno = página actual */
    }

    /* Franja de credenciales OCULTA en móvil (en escritorio y tablet sigue visible). */
    .ga-nosotros-avales {
        display: none;
    }
}


/* ——— AJUSTES FINOS (<=600px) ———
   Probado a 360px: ningún elemento impone un ancho mínimo mayor que el
   viewport, así que no hay desbordamiento horizontal. */
@media (max-width: 600px) {

    /* El botón NO es de ancho completo: se ajusta a su texto ("IR A LA TIENDA") con padding lateral
       cómodo, y se centra por el text-align:center del cierre. (Antes era block + width:100% y el
       fondo verde se extendía mucho más allá del texto.) La zona táctil la mantiene el padding. */
    .ga-nosotros-btn {
        display: inline-block;
        width: auto;
        padding: 1rem 2.5rem;
    }

    /* Menos separación entre avales: a 360px caben en tres líneas holgadas. */
    .ga-nosotros-avales {
        gap: 0.3rem 0.7rem;
    }

    .ga-nosotros-avales li {
        gap: 0.7rem;
    }
}


/* =============================================================================
   EVENTOS — HERO
   =============================================================================
   Plantilla: page-templates/page-eventos.php
   Raíz:      .ga-main--eventos      ·   Prefijo: .ga-eventos-

   Es el ÚNICO bloque de la página de Eventos. El resto de secciones de esa
   plantilla son contenido anterior con sus propios estilos en línea: aquí no se
   toca ni una regla suya, ni ninguna otra del archivo.

   MONTAJE
   Una rejilla de TRES columnas: [2 fotos apiladas] · [texto] · [2 fotos apiladas].
   Cada columna de fotos es a su vez una rejilla, y esa es la clave del responsive:
   en móvil basta con darle DOS columnas para que sus dos fotos se pongan en fila.
   El bloque de texto queda entre medias por el propio orden del HTML, así que en
   móvil sale solo lo pedido —fila de 2 fotos, texto, fila de 2 fotos— sin
   reordenar nada por CSS.

   Se usa rejilla y no flex a propósito: minmax(0, 1fr) corta el ancho mínimo del
   contenido sin necesidad de ningún min-width (regla del proyecto), y evita la
   trampa nº 10 (un flex-direction heredado que no se puede cambiar desde los hijos).

   Ninguna fila es más ancha que el viewport en ningún tamaño: no hay filas reales
   de desbordamiento, así que no puede inflar el viewport de maquetación (trampa nº 1).
   Tampoco se declara overflow en ningún elemento: no se crea ni un solo contenedor
   de scroll nuevo (trampas nº 2 y 3).

   ALTURA
   El hero NO ocupa la pantalla entera —se ve que la página sigue por debajo—: no
   tiene min-height de ningún tipo. Su alto sale de las fotos (dos cuadradas
   apiladas) más un padding vertical que se apoya en vh solo como tope.
   ============================================================================= */

/* Desplazamiento suave al pulsar "Ver formatos", SOLO en esta página y solo si el
   visitante no ha pedido reducir el movimiento. Va en la raíz (html), que es quien
   desplaza la página; es una propiedad de comportamiento, no crea contenedores de
   scroll ni toca overflow. Si el navegador no soporta :has(), el salto es
   instantáneo y el botón funciona igual. */
@media (prefers-reduced-motion: no-preference) {
    html:has(.ga-main--eventos) {
        scroll-behavior: smooth;
    }
}

/* ——— CABECERA CREMA · SOLO EN ESTA PÁGINA ———
   El gancho es .page-template-page-eventos, la clase que WordPress añade solo al
   <body> de las páginas que tienen asignada page-templates/page-eventos.php (la
   genera body_class() a partir del nombre del archivo de plantilla). No hace falta
   registrar ninguna clase nueva en functions.php ni tocar header.php.

   ESPECIFICIDAD, SIN !important: la regla base es `.ga-header` (una clase). Al
   anteponer la del body pasamos a dos, así que gana por especificidad y solo dentro
   de esta página. La home, la tienda, Contacto y Nosotros no llevan esa clase en el
   body, así que su cabecera no se entera de esta regla.

   ESTADO DE SCROLL: la cabecera solo cambia al bajar con `.is-scrolled`, y esa regla
   se limita a añadir una sombra —no toca el fondo—, así que no hay parpadeo de
   color. Aun así se nombra aquí explícitamente, para que el crema quede fijado en
   los dos estados pase lo que pase con esa clase en el futuro.
   (La cabecera que se desliza al hacer scroll es la de la TIENDA, con
   .ga-tienda-header-oculta; aquí no aplica.)

   EL FILETE INFERIOR SE DEJA INTACTO, exactamente como en la TIENDA. Esa línea fina
   bajo la cabecera no es una sombra ni un pseudoelemento: es el
   `border-bottom: 1px solid rgba(74,74,47,0.1)` de la regla base `.ga-header`, que
   NO depende de ningún estado de scroll —por eso en la tienda se ve desde que carga
   la página—. La cabecera de la tienda no lo redefine en ningún sitio, así que para
   tener la misma línea aquí lo correcto es no tocarlo: esta regla cambia SOLO el
   fondo y deja que el filete lo siga poniendo la regla base. Mismo grosor, mismo
   color y mismo mecanismo, sin escribir ni un color ni duplicar la línea.

   (Hubo aquí un `border-bottom-color: transparent` para fundir cabecera y hero en
   una sola superficie crema; se ha retirado a propósito, porque lo que se busca es
   justo lo contrario: que la línea separe las dos, igual que en la tienda.) */
.page-template-page-eventos .ga-header,
.page-template-page-eventos .ga-header.is-scrolled {
    background-color: var(--ga-naranja-claro);   /* #F9F6EE, el mismo crema del hero */
}


/* ——— EL HERO SE PEGA A LA CABECERA FIJA, SIN FRANJA ———
   MISMA solución que en Nosotros (.ga-main--nosotros .ga-nosotros-hero).

   El <body> reserva padding-top: var(--ga-nav-height) para que el contenido no
   quede bajo la cabecera fija, y ese hueco reservado se veía como una franja
   entre la cabecera y el hero: lo que asoma ahí es el FONDO DEL BODY, no el del
   hero. Teñir el body es el otro remedio que ya se usó (en la tienda), pero deja
   la franja viva —solo del color de al lado— y hay que repintarla cada vez que
   cambie el fondo de la primera sección.

   Aquí se hace como en Nosotros, que la elimina de verdad: el hero SUBE con un
   margin-top negativo igual al alto de la cabecera y COMPENSA ese tiro creciendo
   la misma cantidad por arriba (el padding-top lleva sumado var(--ga-nav-height)).
   Resultado: el fondo blanco del hero pasa por debajo de la cabecera —blanca y
   opaca, con su filete inferior— y tapa el hueco, mientras que las fotos y el
   texto NO se mueven ni un píxel, porque lo que sube lo devuelve el padding.

   Funciona igual en móvil sin repetir nada: --ga-nav-height vale 64px dentro del
   @media (max-width: 768px), donde :root la redefine, así que tiro y compensación
   se recalculan solos. */
.ga-main--eventos .ga-eventos-hero {
    /* CREMA de marca. La sección es un bloque a todo el ancho del documento, así que
       el color llega de borde a borde de la pantalla; el max-width y el aire lateral
       viven en el __inner, no aquí, y por eso no quedan franjas blancas a los lados.
       El margin-top negativo de abajo hace además que este crema pase por debajo de
       la cabecera fija y tape el hueco reservado del body: la costura sigue resuelta
       igual que cuando el hero era blanco. */
    background-color: var(--ga-naranja-claro);   /* #F9F6EE */

    /* ——— EL AIRE DE ARRIBA Y EL DE ABAJO, EN UNA SOLA MEDIDA ———
       Un único valor alimenta las dos separaciones, así que no pueden
       descuadrarse: cambiando esta línea se mueven las dos a la vez.
       El vh solo actúa de tope: en pantallas bajas el hero encoge en vez de
       comerse toda la ventana. */
    --ga-ev-hero-aire: clamp(2.5rem, 6vh, 4.5rem);

    /* Alto REAL que ocupa la cabecera fija sobre el hero: su alto (--ga-nav-height)
       MÁS el filete de 1px que la separa del contenido. Ese píxel es la diferencia
       que había entre el aire de arriba y el de abajo. */
    --ga-ev-hero-cabecera: calc(var(--ga-nav-height) + 1px);

    /* Sube el hero para que el crema pase por debajo de la cabecera y tape el hueco
       reservado del body (ver la nota de arriba). Deja el borde superior del hero
       en el mismo borde superior de la ventana. */
    margin-top: calc(-1 * var(--ga-nav-height));

    /* Como el hero arranca en lo alto de la ventana, el padding superior tiene que
       devolver TODO lo que ocupa la cabecera y, encima, el aire. Así el contenido
       queda exactamente a --ga-ev-hero-aire por debajo del filete de la cabecera,
       la misma medida que hay entre las fotos de abajo y el final del crema. */
    padding-top: calc(var(--ga-ev-hero-aire) + var(--ga-ev-hero-cabecera));
    padding-bottom: var(--ga-ev-hero-aire);
    padding-inline: 0;
}

.ga-main--eventos .ga-eventos-hero__inner {
    max-width: var(--ga-max-width);
    margin-inline: auto;
    /* Aire lateral: las fotos nunca quedan pegadas al borde de la ventana. */
    padding-inline: clamp(1.25rem, 4vw, 3rem);

    display: grid;
    /* Las columnas de fotos las mide un clamp (mínimo, ideal en vw, máximo) y el
       texto se queda con lo que sobra. minmax(0, 1fr) para que el titular pueda
       partir sin imponer un ancho mínimo. */
    grid-template-columns:
        clamp(8.5rem, 15vw, 13rem)
        minmax(0, 1fr)
        clamp(8.5rem, 15vw, 13rem);
    align-items: center;
    /* Separación entre las fotos y el texto: cerca, pero sin tocarse. */
    column-gap: clamp(1.5rem, 3.5vw, 3.5rem);
    row-gap: clamp(1.75rem, 4vw, 2.5rem);
}

/* Columna de fotos: apiladas en escritorio y tablet (una sola columna implícita). */
.ga-main--eventos .ga-eventos-hero__col {
    display: grid;
    gap: clamp(0.75rem, 1.6vw, 1.25rem);
}

/* ——— LAS CUATRO FOTOS ———
   Cuadradas SIEMPRE (aspect-ratio: 1 / 1): su ancho lo marca la columna y el alto
   sale solo de la proporción, así que el hueco está reservado desde el primer
   momento y no hay salto al cargar.
   Son SOLO imagen: no van dentro de ningún enlace y no tienen ni un solo estado
   de hover o foco, ni de tamaño ni de posición. */
.ga-main--eventos .ga-eventos-hero__foto {
    box-sizing: border-box;   /* el borde del marco vacío no cambia el tamaño */
    margin: 0;
    width: 100%;
    aspect-ratio: 1 / 1;
    border-radius: var(--ga-radius-md);
    /* Sin overflow: el redondeo lo hereda la propia <img>, así que no hace falta
       recortar con overflow y no se crea un contenedor de scroll. */
}

.ga-main--eventos .ga-eventos-hero__foto img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

/* MARCO PROVISIONAL — mientras la foto no esté subida.
   Mismo tamaño exacto que tendrá la foto, borde dorado fino sobre crema y sin
   texto dentro. Al subir el archivo con su nombre, la plantilla pinta la <img>
   en su lugar y no se mueve nada. */
/* El relleno del marco pasa a BLANCO al volverse crema el fondo del hero: en crema
   sobre crema el hueco de la foto desaparecía y solo quedaba el filete dorado. El
   tamaño, la proporción y la posición no cambian: solo el color de relleno. */
.ga-main--eventos .ga-eventos-hero__foto--vacia {
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-naranja-apagado);
}

/* ——— BLOQUE DE TEXTO ——— */
.ga-main--eventos .ga-eventos-hero__centro {
    display: grid;
    justify-items: center;
    text-align: center;
}

/* Antetítulo en dorado de marca. opacity a 1 porque la regla global de <p> las
   deja al 0.85, y aquí el dorado necesita ir a plena intensidad. */
.ga-main--eventos .ga-eventos-hero__antetitulo {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.22em;
    line-height: 1.4;
    color: var(--ga-naranja-apagado);
    opacity: 1;
}

/* Titular. Ya viene en mayúsculas desde el HTML (no se fuerza con text-transform).
   El reparto en líneas no lleva ni un salto forzado: lo marcan el max-width en ch
   —una medida que va con el tamaño de letra, así que el número de caracteres por
   línea se mantiene a cualquier ancho— y text-wrap: balance, que iguala el largo
   de las líneas en vez de dejar la última coja. */
.ga-main--eventos .ga-eventos-hero__titulo {
    margin: clamp(0.9rem, 2vw, 1.4rem) 0 0;
    max-width: 18ch;
    font-family: var(--ga-font-display);
    font-size: clamp(1.9rem, 4.6vw, 3.5rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.06;
    letter-spacing: 0.01em;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
    overflow-wrap: break-word;   /* corta el ancho mínimo sin usar min-width */
}

/* ——— BOTÓN "VER FORMATOS" ———
   DORADO macizo en reposo que pasa a VERDE al interactuar. Las dos son las
   variables de marca de siempre, intercambiadas: --ga-naranja-apagado (el dorado)
   y --ga-verde-oliva-oscuro.

   🔑 LOS DOS COLORES DEL BOTÓN VIVEN EN PROPIEDADES PERSONALIZADAS, exactamente
   igual que en el botón de carrito de las tarjetas (--ga-cart-fondo/--ga-cart-luz,
   más arriba en este mismo archivo). El degradado del brillo se construye a partir
   de ellas UNA SOLA VEZ, y cada estado solo tiene que redefinir el par de colores.
   Ese es el truco para que el barrido NO se corte al pasar el ratón: ver la nota
   del hover, más abajo.

   Ningún estado cambia tamaño ni posición: solo color de fondo, color de borde
   (siempre 1px) y sombra. El borde existe ya en reposo, así que no puede ensanchar
   el botón al pasar el ratón. */
.ga-main--eventos .ga-eventos-hero__btn {
    --ga-ev-btn-fondo: var(--ga-naranja-apagado);   /* dorado de marca #c7a862 */
    --ga-ev-btn-luz:   #e6d0a0;                     /* el mismo dorado claro de la tienda */

    margin-top: clamp(1.5rem, 3vw, 2.25rem);
    display: inline-block;
    max-width: 100%;
    padding: 1.05rem 2.5rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    /* Texto BLANCO en los dos estados, la misma variable que usan el resto de
       botones del proyecto (.ga-home-card__btn, .ga-nosotros-btn…). */
    color: var(--ga-blanco);
    background-color: var(--ga-ev-btn-fondo);
    border: 1px solid var(--ga-ev-btn-fondo);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    /* background-image entra en la transición para que el degradado cambie de
       dorado a verde con la misma suavidad que el borde, en vez de dar un corte
       seco (el degradado es lo que se ve: cubre el botón entero). Los navegadores
       interpolan degradados de igual estructura; donde no, simplemente salta.
       Transicionar background-image NO reinicia la animación, que va sobre
       background-position. */
    transition: background-color var(--ga-transition-normal),
                background-image var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* ——— BRILLO ANIMADO · COPIA LITERAL DEL DE LA TIENDA ———
   Declaración calcada del "Añadir al carrito" de Novedades
   (.ga-tienda-novedad__btn.ga-btn--primary, más arriba): degradado a 100° con las
   paradas 0% / 45% / 50% / 55% / 100%, background-size 250% 100%, no-repeat,
   arranque en 100% center y animación ga-home-card-brillo 8s linear infinite.
   Ni una parada ni un porcentaje retocados, y el @keyframes es el mismo de la
   tienda: está declarado a nivel raíz más arriba, así que se REUTILIZA tal cual,
   sin duplicarlo con otro nombre.

   Lo único distinto son los colores, que entran por las propiedades personalizadas
   del bloque de arriba en lugar de escritos a pelo. El valor resultante en reposo
   es idéntico al de la tienda: dorado de marca con la luz en #e6d0a0.

   Se anima ÚNICAMENTE background-position → ni reflow, ni cambio de tamaño, ni
   desplazamiento. Nada de opacidad pulsante ni de box-shadow. */
.ga-main--eventos .ga-eventos-hero__btn {
    background-image: linear-gradient(
        100deg,
        var(--ga-ev-btn-fondo) 0%,
        var(--ga-ev-btn-fondo) 45%,
        var(--ga-ev-btn-luz) 50%,
        var(--ga-ev-btn-fondo) 55%,
        var(--ga-ev-btn-fondo) 100%
    );
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
}

/* ——— HOVER, FOCO Y PULSACIÓN: SOLO CAMBIA EL PAR DE COLORES ———
   🔴 Estas reglas NO declaran animation, ni background-image, ni background-size,
   ni background-position. Y es lo que hace que el barrido no se corte: redefinir
   una propiedad personalizada solo recalcula el VALOR del degradado; la animación
   sigue siendo la misma, con su mismo tiempo de arranque, así que la luz continúa
   su recorrido justo donde iba —sin desaparecer, sin reiniciarse y sin saltos—.
   Volver a escribir aquí `animation` o `background-image` completo es exactamente
   lo que la reiniciaría.

   El verde y su luz son el mismo par que usa el botón de carrito de las tarjetas
   (--ga-cart-fondo / --ga-cart-luz): verde oliva oscuro de marca con la luz en
   #7a7a54, el oliva aclarado que ya existe en el proyecto. Al cambiar el par, el
   background-color y el border-color de la regla base se recalculan solos: no hace
   falta repetirlos. */
.ga-main--eventos .ga-eventos-hero__btn:hover,
.ga-main--eventos .ga-eventos-hero__btn:focus-visible,
.ga-main--eventos .ga-eventos-hero__btn:active {
    --ga-ev-btn-fondo: var(--ga-verde-oliva-oscuro);   /* #4a4a2f */
    --ga-ev-btn-luz:   #7a7a54;                        /* el mismo oliva aclarado */
}

.ga-main--eventos .ga-eventos-hero__btn:hover {
    box-shadow: var(--ga-shadow-md);
}

/* Foco de teclado: el anillo es box-shadow, que no ocupa espacio en el flujo y
   por tanto no mueve nada. */
.ga-main--eventos .ga-eventos-hero__btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(74, 74, 47, 0.45);
}

/* 🔴 BLINDAJE DEL COLOR DE TEXTO.
   Astra repinta el color de los enlaces al pasar el ratón y al enfocarlos, y esa
   regla gana a un selector de una sola clase (misma trampa nº 6 ya documentada
   en la Tienda, Contacto y Nosotros). Mismo remedio: !important acotado a ESTA
   página. Ninguna regla general del tema se toca.
   Basta UNA regla porque el texto es blanco en todos los estados: al ir sobre el
   propio botón (sin pseudoclase), cubre también hover, focus, focus-visible y
   active, que no lo reescriben en ningún sitio. */
.ga-main--eventos .ga-eventos-hero__btn,
.ga-main--eventos .ga-eventos-hero__btn:hover,
.ga-main--eventos .ga-eventos-hero__btn:focus,
.ga-main--eventos .ga-eventos-hero__btn:focus-visible,
.ga-main--eventos .ga-eventos-hero__btn:active {
    color: var(--ga-blanco) !important;
}

/* Ahorro de movimiento: dorado sólido, sin degradado ni barrido. El botón
   conserva colores, tamaño y estados de hover; solo desaparece la animación. */
@media (prefers-reduced-motion: reduce) {
    .ga-main--eventos .ga-eventos-hero__btn {
        background-image: none;
        animation: none;
    }
}

/* (Aquí vivía .ga-eventos-ancla, el elemento vacío que hacía de destino del botón
   "Ver formatos" mientras no existía la sección de formatos. Ya existe, así que el
   id pasó a ella y el ancla se retiró; su scroll-margin-top vive ahora en
   .ga-eventos-formatos, al final de este bloque.) */


/* ——— TABLET (<=1024px) ———
   Se MANTIENEN las tres columnas: las fotos encogen y el aire lateral se recorta,
   y el titular sigue teniendo sitio de sobra. Por debajo de 768px ya no caben con
   holgura y se pasa a la disposición apilada. */
@media (max-width: 1024px) {

    .ga-main--eventos .ga-eventos-hero__inner {
        grid-template-columns:
            clamp(7.5rem, 17vw, 11rem)
            minmax(0, 1fr)
            clamp(7.5rem, 17vw, 11rem);
        column-gap: clamp(1.25rem, 3vw, 2rem);
    }
}


/* ——— MÓVIL (<=768px) ———
   El inner pasa a UNA columna, así que sus tres hijos se apilan en el orden del
   HTML: columna izquierda, texto, columna derecha. Y cada columna de fotos pasa a
   DOS columnas, con lo que sus dos fotos se ponen en fila.
   Resultado: 2 fotos arriba · texto · 2 fotos abajo.
   El ancho de cada foto sale de su mitad de la rejilla (porcentaje real del inner),
   nunca de una medida fija: a 360px son ~155px de lado y no hay desbordamiento. */
@media (max-width: 768px) {

    /* Mismo montaje que en la regla base: basta con redefinir el AIRE, porque las
       dos separaciones salen de esa única variable y el descuento de la cabecera lo
       calcula sola --ga-ev-hero-cabecera (aquí --ga-nav-height ya vale 64px, y el
       margin-top negativo usa esa misma variable).

       AIRE RECORTADO EN MÓVIL (era clamp(1.75rem, 5vh, 2.75rem) → 28-44px).
       Desde que las fotos se ocultan, el hero es solo texto y ese aire dejaba el
       antetítulo demasiado lejos de la cabecera. Ahora son ~15-24px.
       🔴 LO QUE NO SE TOCA: el padding superior sigue siendo
          aire + --ga-ev-hero-cabecera, así que la cabecera fija NUNCA puede tapar
          el antetítulo por mucho que se baje esta línea; lo único que se acorta es
          la distancia visible por debajo del filete.
       Es una sola variable a propósito (ver la regla base): el aire de abajo baja
       exactamente lo mismo, y arriba y abajo siguen midiendo igual. */
    .ga-main--eventos .ga-eventos-hero {
        --ga-ev-hero-aire: clamp(0.9rem, 2.4vh, 1.5rem);
    }

    .ga-main--eventos .ga-eventos-hero__inner {
        grid-template-columns: minmax(0, 1fr);
        /* Aire ENTRE EL BOTÓN Y LAS FOTOS. En móvil solo quedan dos hijos
           visibles —el bloque de texto y la fila de fotos—, así que este row-gap
           es exactamente esa separación y nada más.
           Sube de 24 a 32px con la escala de marca, no con un número suelto:
           un paso de la escala (--ga-space-xs) sobre el que ya había
           (--ga-space-md). El mismo valor que el aire de encima del botón, para
           que quede centrado entre las dos cosas. */
        row-gap: calc(var(--ga-space-md) + var(--ga-space-xs));
        padding-inline: clamp(1.25rem, 5vw, 2rem);

        /* ═══════════════════════════════════════════════════════════════
           UNA SOLA MEDIDA PARA EL TITULAR Y PARA LA FILA DE FOTOS
           ═══════════════════════════════════════════════════════════════
           Las dos piezas comparten estas dos variables, así que no pueden
           descuadrarse: si mañana se cambia el tamaño de letra, la fila de
           fotos se recoloca sola.

           --ga-ev-hero-tipo   → el tamaño del titular.
           --ga-ev-hero-medida → el ANCHO que ocupan los dos, en `ch` de la
             tipografía del titular. Va en ch —y no en px ni en rem— porque
             así la caja se mide en anchos de carácter de la propia letra:
             es la unidad con la que ya estaba calibrado que "MOMENTOS QUE"
             cabe en una línea y el titular reparte en tres.
             El min(100%, …) impide que se pase del ancho disponible.

           🔧 SI ALGÚN DÍA HAY QUE AFINARLO, se toca AQUÍ y solo aquí:
              subir los 20ch si el titular se partiera en cuatro líneas,
              bajarlos si el texto se viera más estrecho que las fotos. */
        --ga-ev-hero-tipo: clamp(1.95rem, 10vw, 2.8rem);
        --ga-ev-hero-medida: min(100%, 20ch);
    }

    /* ═══════════════════════════════════════════════════════════════════
       HERO EN MÓVIL: TEXTO Y, DEBAJO DEL BOTÓN, DOS FOTOS FIJAS
       ═══════════════════════════════════════════════════════════════════
       Orden en móvil: antetítulo · titular · botón · las DOS fotos de la
       columna izquierda, una al lado de la otra y COMPLETAMENTE QUIETAS.
       Ni carrusel, ni auto-avance, ni transform: ese montaje se ha retirado
       entero (marcado, estilos y JavaScript).

       LA COLUMNA DERECHA SE OCULTA, NO SE BORRA: su HTML sigue intacto y en
       escritorio y tablet el hero mantiene sus cuatro fotos repartidas a los
       lados, exactamente igual que antes. Todo esto vive dentro de este @media.

       ¿UNA AL LADO DE OTRA O UNA ENCIMA DE OTRA? Al lado. Apiladas, cada foto
       mediría los ~320px de ancho útil a 360px y, siendo cuadradas, sumarían
       más de 640px de alto: el hero se comería la pantalla entera y el botón
       quedaría muy por encima del pliegue. En fila son ~152px de lado cada una,
       se ven las dos de un vistazo y el hero sigue siendo un hero. */
    .ga-main--eventos .ga-eventos-hero__col--der {
        display: none;
    }

    /* La columna izquierda pasa de apilar sus dos fotos a ponerlas en FILA.
       Dos pistas de minmax(0, 1fr): cada foto se queda con la mitad exacta del
       ancho disponible menos el hueco, en porcentaje real de la rejilla y sin un
       solo min-width, así que nunca puede desbordar. Siguen siendo cuadradas
       (aspect-ratio de la regla base) y siguen siendo solo imagen.

       DEBAJO DEL BOTÓN, SIN TOCAR EL ORDEN DEL HTML: en el marcado esta columna
       va ANTES del bloque de texto (es lo que la pone a la izquierda en
       escritorio). Se reordena con `order`, que es lo que manda la convención
       del proyecto para móvil; el HTML se queda como está y el escritorio no se
       entera.

       SIN HUECO VACÍO NI ARRIBA NI ABAJO: un elemento en display:none no genera
       pista en la rejilla, así que la columna derecha no deja su hueco ni suma
       row-gap. Quedan exactamente dos hijos visibles —texto y fila de fotos— y
       entre ellos actúa un único row-gap. Por debajo de las fotos, el aire es el
       padding inferior del hero, el mismo que el de arriba. */
    .ga-main--eventos .ga-eventos-hero__col--izq {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--ga-space-sm);
        order: 1;

        /* ——— MISMO ANCHO EXACTO QUE EL TITULAR ———
           La fila de fotos se mide con la MISMA variable que el titular. Para
           que ese `ch` valga lo mismo en los dos sitios, la fila adopta la
           tipografía y el cuerpo del titular: el ch se calcula con la letra del
           elemento donde se usa, así que sin esto un mismo 20ch daría dos
           anchos distintos (aquí se heredaría Inter y allí Cormorant).
           No hay ni una palabra dentro de esta fila —solo las dos figuras—, así
           que declarar aquí la tipografía no cambia nada de lo que se ve: es
           solo la base con la que se mide.
           Con el mismo ancho y centrada, texto y fotos comparten sus dos bordes
           izquierdo y derecho. */
        font-family: var(--ga-font-display);
        font-weight: var(--ga-weight-bold);
        font-size: var(--ga-ev-hero-tipo);
        width: var(--ga-ev-hero-medida);
        margin-inline: auto;
    }

    /* TRES LÍNEAS, no cuatro: MOMENTOS QUE / SE RECUERDAN / PARA SIEMPRE.
       Con 16ch la línea más ancha ("MOMENTOS QUE", con dos emes y dos oes) no
       cabía, así que text-wrap: balance se veía obligado a repartir en cuatro.
       Ensanchando a 20ch entra de sobra y el reparto cae solo en tres, sin un
       solo <br> en el HTML y sin tocar el tamaño de letra.
       La medida va en `ch`, que escala con la tipografía: por eso el número de
       líneas se mantiene igual en todo el rango del móvil y no solo a 360px. */
    .ga-main--eventos .ga-eventos-hero__titulo {
        max-width: var(--ga-ev-hero-medida);
        font-size: var(--ga-ev-hero-tipo);
    }

    /* El antetítulo acompaña al titular: sube de cuerpo lo justo para que el
       bloque de arriba pese como conjunto, sin acercarse al titular. */
    .ga-main--eventos .ga-eventos-hero__antetitulo {
        font-size: clamp(0.8rem, 3.6vw, 0.95rem);
    }

    /* Aire ENTRE EL TITULAR Y EL BOTÓN. El titular no lleva margen inferior, así
       que esta es toda la separación entre los dos. De 24 a 32px, EL MISMO valor
       que el row-gap de arriba: el botón queda con el mismo aire por encima que
       por debajo. Solo separación: ni el tamaño del botón, ni su relleno, ni su
       tipografía se tocan. */
    .ga-main--eventos .ga-eventos-hero__btn {
        margin-top: calc(var(--ga-space-md) + var(--ga-space-xs));
    }
}


/* ——— AJUSTES FINOS (<=600px) ———
   Comprobado a 360px: ningún elemento impone un ancho mínimo mayor que el
   viewport (no hay un solo min-width en toda la sección), así que no hay
   desbordamiento horizontal. */
@media (max-width: 600px) {

    .ga-main--eventos .ga-eventos-hero__inner {
        padding-inline: 1.25rem;
    }

    /* El botón se ajusta a su texto, no al ancho de la pantalla. La zona táctil
       la mantiene el padding. */
    .ga-main--eventos .ga-eventos-hero__btn {
        padding: 1rem 2.25rem;
    }
}


/* ——— COLUMNA CENTRAL A TODA LA ALTURA · SOLO ESCRITORIO Y TABLET (>=769px) ———
   ⚠ Este bloque es el ÚNICO de la página escrito en min-width, y es a propósito:
   769px es el complemento exacto del @media (max-width: 768px) de arriba, así que
   NADA de lo que hay aquí puede alcanzar al móvil. El móvil se queda exactamente
   como estaba: fotos arriba, texto igual de grande que hasta ahora, fotos abajo.

   QUÉ HACE
   Mientras hay tres columnas, la central deja de ser una cajita centrada con aire
   sobrante y pasa a medir lo mismo que las columnas de fotos: el antetítulo
   arranca a la altura del borde superior de las fotos de arriba y el botón acaba
   en el borde inferior de las de abajo.

   CÓMO, SIN UNA SOLA ALTURA ESCRITA A MANO
   El alto de la fila lo marcan las columnas de fotos (dos cuadrados + su hueco).
   Basta con dejar de centrar los items del inner —vuelven a `stretch`, que es el
   valor por defecto de la rejilla— para que la central se estire hasta ese alto.
   Dentro, tres franjas `auto 1fr auto`: el 1fr del medio absorbe la holgura y el
   titular se centra en ella. Ninguna medida en píxeles, ningún min-width, y las
   fotos no cambian ni de tamaño ni de proporción. */
@media (min-width: 769px) {

    .ga-main--eventos .ga-eventos-hero__inner {
        align-items: stretch;
    }

    /* Las columnas de fotos NO se estiran: si algún día el texto llegara a ser más
       alto que ellas, se quedan centradas en la fila en vez de descolgarse hacia
       arriba. Siguen aportando su alto a la fila, así que la central lo hereda. */
    .ga-main--eventos .ga-eventos-hero__col {
        align-self: center;
    }

    /* El padding vertical es el AIRE de respeto contra los bordes de las fotos: el
       antetítulo no arranca pegado al canto superior ni el botón acaba pegado al
       inferior. No cambia la altura de la columna —sigue siendo la de las fotos, y
       con box-sizing: border-box el padding va por dentro—: solo recorta el espacio
       útil que después reparten las tres franjas. */
    .ga-main--eventos .ga-eventos-hero__centro {
        grid-template-rows: auto 1fr auto;   /* antetítulo · titular · botón */
        padding-block: clamp(1.5rem, 3vw, 2.5rem);
    }

    .ga-main--eventos .ga-eventos-hero__antetitulo {
        font-size: clamp(0.72rem, 0.88vw, 0.875rem);
        letter-spacing: 0.24em;
    }

    /* El titular se centra en la franja libre. Los márgenes son el aire MÍNIMO
       entre él y sus vecinos; el resto de la holgura la reparte el 1fr por igual
       arriba y abajo, así que no quedan huecos desiguales.

       SIN saltos forzados en el HTML: el reparto en tres líneas lo hacen el ancho
       disponible y text-wrap: balance, que iguala el largo de las tres. El
       max-width en `ch` es un techo blando: como la medida va con el tamaño de
       letra, mantiene el ancho de línea en unas 9,5 veces la tipografía a cualquier
       resolución, que es la horquilla en la que esta frase siempre cae en tres. Sin
       él, al reducir el cuerpo la línea se ensanchaba en proporción y el titular se
       quedaba a un pelo de resolverse en dos. Cuando la columna es más estrecha que
       ese techo, manda la columna. */
    .ga-main--eventos .ga-eventos-hero__titulo {
        align-self: center;
        max-width: 19ch;
        margin: clamp(0.75rem, 1.5vw, 1.25rem) 0;
        font-size: clamp(1.75rem, 4.75vw, 4.2rem);
    }

    /* El botón escala en la misma proporción y se apoya en el borde inferior de la
       franja útil. El margen superior se retira: aquí quien separa es la rejilla.
       Por dentro no se toca nada —ni color, ni texto blanco, ni brillo—: la banda
       de luz es un porcentaje del propio botón, así que acompaña a su escala. */
    .ga-main--eventos .ga-eventos-hero__btn {
        align-self: end;
        margin-top: 0;
        font-size: clamp(0.85rem, 1vw, 1rem);
        padding: clamp(0.95rem, 1.3vw, 1.2rem) clamp(2.25rem, 3vw, 2.9rem);
    }
}


/* =============================================================================
   EVENTOS — CÓMO FUNCIONA (el proceso en cuatro pasos)
   =============================================================================
   Segunda sección de la página, justo debajo del hero.

   REFERENCIA VISUAL: se tomó de la sección "Así de sencillo" que había en el
   andamiaje antiguo de esta misma página —cabecera centrada, círculo dorado de 60px
   con el número dentro y línea conectora entre pasos—, y de ahí salen la escala
   tipográfica y las medidas. Aquella sección ya se ha retirado; el equivalente vivo
   que queda en el sitio es la línea de tiempo de la home (.ga-proceso), que además
   es de donde viene el encendido progresivo de la línea.

   Haberla escrito con prefijo propio desde el principio es lo que ha permitido
   borrar aquel andamiaje sin tocar una sola regla de esta sección. Las VARIABLES son
   todas las de marca.

   NADA DE FILAS MÁS ANCHAS QUE EL VIEWPORT: los pasos son una rejilla con pistas
   minmax(0, 1fr), que reparte el ancho disponible y nunca lo supera. En móvil pasa
   a una sola columna y se apilan. No hay scroll horizontal ni carrusel, así que no
   puede inflar el viewport de maquetación (🪤 nº 1).

   Ningún paso tiene estado de hover: nada cambia de tamaño ni de posición.
   ============================================================================= */

/* Fondo BLANCO. Al invertirse respecto a la referencia (que va sobre verde oscuro),
   todos los colores de texto de la sección se han invertido con él: lo que era
   blanco pasa a verde oliva oscuro, y lo que era crema translúcido pasa al mismo
   verde con opacidad. El círculo dorado del número es lo único que no cambia: no
   depende del fondo de la sección. */
/* 🔴 SIN PADDING SUPERIOR, A PROPÓSITO.
   Esta sección y la franja de introducción comparten el mismo blanco y se tocan sin
   ningún borde, así que sus separaciones se SUMABAN: el padding inferior de la
   introducción más el superior de aquí daban un hueco enorme entre el segundo
   renglón y este título.
   Ahora el aire de encima del título lo pone ENTERO la introducción (su
   padding-bottom), que es quien lo tiene que cuadrar con el de su parte de arriba.
   El padding INFERIOR se queda como estaba: ese sí es solo de esta sección. */
.ga-main--eventos .ga-eventos-proceso {
    background-color: var(--ga-blanco);
    padding-top: 0;
    /* Al crecer el bloque, más aire por debajo para que no quede apretado contra lo
       que venga después. Suelo y techo con medidas de marca (6rem → 8rem). */
    padding-bottom: clamp(var(--ga-space-2xl), 8vw, var(--ga-space-3xl));
}

/* La línea de tiempo respira más ancho que el resto de la página: se le da al
   contenedor 12rem por encima del ancho máximo del sitio (1280 → 1472px). No llega a
   borde con borde: el aire lateral es el MISMO clamp que usa el hero, así que el
   margen contra el borde de la ventana se lee coherente con las demás secciones. */
.ga-main--eventos .ga-eventos-inner {
    max-width: min(100%, calc(var(--ga-max-width) + 12rem));
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
}

/* ——— Cabecera de la sección ——— */
.ga-main--eventos .ga-eventos-seccion__head,
.ga-product-single .ga-eventos-seccion__head {
    text-align: center;
    /* Separación entre el titular "Cómo funciona" y la línea de tiempo: crece con el
       bloque para que el titular no se quede pegado a los círculos, pero un punto
       más ajustada que antes (era 2.5→4.5rem; a 1440px baja de 72 a 56px).
       Solo afecta a este hueco: ni el aire de encima del titular —que lo pone la
       franja de introducción— ni el del final de la sección se tocan. */
    margin-bottom: clamp(2rem, 4vw, 3.5rem);
}

.ga-main--eventos .ga-eventos-seccion__titulo,
.ga-product-single .ga-eventos-seccion__titulo {
    margin: 0 0 0.75rem;
    font-family: var(--ga-font-display);
    font-size: clamp(1.8rem, 3vw, 2.8rem);
    font-weight: 600;
    line-height: 1.15;
    color: var(--ga-naranja-apagado);      /* dorado de marca */
    text-wrap: balance;
}

/* (Aquí vivía .ga-eventos-seccion__frase, la línea que iba bajo el título. Se
   retiró con ella: su contenido pasó a la franja de introducción de arriba y aquí
   habría quedado repetido. La cabecera de la sección se queda solo con el <h2>.) */

/* ——— LÍNEA DE TIEMPO ———
   Cuatro columnas iguales en escritorio. minmax(0, 1fr) en vez de 1fr para que una
   palabra larga no pueda ensanchar su pista: corta el ancho mínimo del contenido
   sin necesidad de ningún min-width.

   Las tres medidas de las que depende la línea conectora viven en variables, así
   que la geometría se recalcula sola si algún día cambian el hueco o el círculo:
     · el HUECO entre pasos,
     · el ANCHO DE COLUMNA, deducido del hueco (4 pistas iguales + 3 huecos),
     · el TAMAÑO DEL CÍRCULO y su radio, que es la altura a la que va la línea. */
.ga-main--eventos .ga-eventos-pasos {
    /* Separación entre pasos: crece con el ancho de la ventana (2.5rem → 6rem), así
       que en escritorio los cuatro quedan más repartidos y en móvil no se dispara. */
    --ga-ev-pasos-gap: clamp(var(--ga-space-lg), 5vw, var(--ga-space-2xl));

    /* Diámetro del círculo, en clamp para que acompañe al tamaño de la foto. El
       mínimo son los 60px de siempre, que es lo que sigue valiendo en móvil y tablet
       porque ahí el término en vw se queda por debajo. El radio —la altura a la que
       va la línea que une los círculos— se deriva de él, así que la línea se
       recoloca sola cuando el círculo cambia de tamaño. */
    --ga-ev-num-tamano: clamp(3.75rem, 5vw, 5.5rem);
    --ga-ev-num-radio: calc(var(--ga-ev-num-tamano) / 2);

    position: relative;                   /* referencia de la línea conectora */
    list-style: none;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));

    /* ——— CUATRO FILAS COMPARTIDAS POR LOS CUATRO PASOS ———
       CÍRCULO · TÍTULO · FOTO · TEXTO. Antes no había filas declaradas: cada paso era una
       sola celda y todo lo de dentro se colocaba con la altura de SU columna, así
       que la posición de cada pieza dependía del texto de esa columna y no de una
       estructura común. Por eso un título que pasa a dos líneas descolocaba lo que
       tenía debajo —y, con él, la posición vertical dentro de la columna—: las dos
       columnas cuyos títulos envolvían eran justo las que se veían desajustadas.

       Ahora las filas las declara la LISTA y cada paso se acopla a ellas con
       subgrid (más abajo). Los cuatro círculos caen en la MISMA fila, así que
       quedan a la misma altura pase lo que pase con los textos; el título ocupa una
       fila de alto único —el del título más largo—, las cuatro fotos caen en otra
       fila común y por eso los cuatro párrafos empiezan también a la misma altura.
       Sin una sola altura escrita a mano y sin márgenes negativos: si mañana cambia
       una frase, se recoloca solo.

       El hueco entre filas es 0 porque la separación vertical ya la ponen los
       márgenes del círculo, del título y de la foto; el de columnas se mantiene. */
    grid-template-rows: auto auto auto auto;
    column-gap: var(--ga-ev-pasos-gap);
    row-gap: 0;
    align-items: start;
}

/* ——— LA LÍNEA QUE UNE LOS CÍRCULOS ———
   MISMO MECANISMO QUE LA LÍNEA DE TIEMPO DE LA HOME (.ga-paso::after, dentro de su
   @media (min-width: 769px)): cada paso menos el último dibuja el TRAMO que va del
   centro de SU círculo al centro del siguiente
       arranca en 50% (su centro) y mide una columna más el hueco,
   que es exactamente la distancia entre dos centros. Como cada tramo termina justo
   donde empieza el siguiente, se ve como una línea continua sin huecos, y al no
   ponerlo el último, no sobresale por ningún extremo.

   Se hace por tramos —y no con una sola línea— porque es lo que permite ENCENDERLOS
   POR SEPARADO: es la misma estructura sobre la que la home aplica su progreso
   acumulativo.

   PASAN POR DETRÁS de los círculos: el ::before se pinta antes que el círculo, que
   va posicionado y con z-index 1 y cuyo fondo dorado es opaco. Son decorativos y no
   capturan el ratón. */
.ga-main--eventos .ga-eventos-paso:not(:last-child)::before {
    content: '';
    position: absolute;
    z-index: 0;
    top: var(--ga-ev-num-radio);
    left: 50%;
    width: calc(100% + var(--ga-ev-pasos-gap));
    height: 1px;
    background-color: var(--ga-verde-oliva-oscuro);   /* filete oscuro: sobre blanco, el crema no se vería */
    opacity: 0.18;
    /* Misma duración y misma curva que la home (0.35s ease). */
    transition: opacity 0.35s ease, background-color 0.35s ease;
    pointer-events: none;
}

/* TRAMO RECORRIDO. La clase la pone gaEventosProgreso() en main.js sobre los pasos
   ANTERIORES al seleccionado, igual que ga-linea-activa en la home. El tramo se
   enciende en el dorado de marca a plena intensidad. */
.ga-main--eventos .ga-eventos-paso.ga-eventos-linea-activa::before {
    background-color: var(--ga-naranja-apagado);
    opacity: 1;
}

/* Cada paso se acopla a las cuatro filas de la lista en vez de repartir su interior
   por su cuenta: eso es lo que pone los cuatro círculos en la misma fila, y las
   cuatro fotos en otra.
   Si un navegador no entendiera `subgrid`, esa línea se descarta y el paso vuelve a
   repartir su interior; pero como sigue ocupando las cuatro filas y la lista alinea
   al inicio (align-items: start), los círculos siguen arrancando todos a la misma
   altura. El único matiz que se perdería es el alto único del título. */
.ga-main--eventos .ga-eventos-paso {
    display: grid;
    grid-row: span 4;
    grid-template-rows: subgrid;
    position: relative;
    z-index: 1;                           /* por delante de la línea */
    text-align: center;
}

/* Número: círculo dorado, exactamente el de la referencia.
   position: relative lo convierte en descendiente posicionado, así que se pinta
   DESPUÉS del ::before de su propio paso (el de la línea vertical del móvil) y lo
   tapa. Sin esto, en móvil la línea cruzaría por encima del círculo. */
.ga-main--eventos .ga-eventos-paso__num {
    position: relative;
    z-index: 1;
    width: var(--ga-ev-num-tamano);
    height: var(--ga-ev-num-tamano);
    margin: 0 auto var(--ga-space-md);
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--ga-radius-full);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-blanco);
    font-family: var(--ga-font-display);
    /* El número crece con su círculo, en la misma proporción. */
    font-size: clamp(1.4rem, 1.9vw, 2rem);
    font-weight: 600;

    /* ——— CENTRADO ÓPTICO DEL NÚMERO ———
       line-height: 1 deja la caja de línea justo en 1em, sin interlineado repartido
       que descuadre el centrado del flex. Aun así el dígito cae bajo: Cormorant
       Garamond reparte ascendente y descendente de forma asimétrica, así que el
       centro VISUAL de la cifra no coincide con el centro de su caja de línea.

       La corrección es un padding INFERIOR en em. Con box-sizing: border-box y el
       alto fijado por --ga-ev-num-tamano, ese padding NO agranda ni mueve el
       círculo: solo encoge la caja de contenido por abajo, y como el contenido va
       centrado con align-items, el número sube la mitad (0.075em). Al ir en em, la
       corrección escala sola con el tamaño de letra —y por tanto con el círculo—, y
       vale igual para los cuatro números con una única regla.

       ⚠ No se usa transform: translateY sobre el número porque en este marcado el
       número ES el círculo (el dígito es el texto del propio <span>, sin ningún
       elemento interior al que agarrarse): trasladarlo movería el círculo, que es
       justo lo que no puede pasar. Tampoco hay margen ni padding negativos. */
    line-height: 1;
    padding-bottom: 0.15em;
    /* Solo se animan transform y box-shadow: ninguna de las dos ocupa sitio en el
       flujo, así que el hover no puede mover ni descolocar nada. */
    transition: transform var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* HOVER: el círculo se acerca un poco (9%) y gana una sombra cálida de marca.
   NI width, NI height, NI padding, NI márgenes: solo escala y sombra, así que el
   texto del paso y la línea que une los círculos se quedan exactamente donde
   estaban. La sombra es --ga-shadow-md, en el verde oliva de marca, nunca negro. */
.ga-main--eventos .ga-eventos-paso__num:hover {
    transform: scale(1.09);
    box-shadow: var(--ga-shadow-md);
}

/* Ahorro de movimiento: sin escala ni transición. La sombra se mantiene —no es
   movimiento— para que el hover siga teniendo respuesta visual. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-paso__num {
        transition: none;
    }

    .ga-main--eventos .ga-eventos-paso__num:hover {
        transform: none;
    }

    /* (El ahorro de movimiento de la FOTO no puede ir aquí: sus reglas base se
       declaran más abajo y, a igual especificidad, ganaría la última. Va en su
       propio bloque justo después de ellas.) */

    /* La línea sigue encendiéndose, pero de golpe: sin transición. */
    .ga-main--eventos .ga-eventos-paso:not(:last-child)::before {
        transition: none;
    }
}

.ga-main--eventos .ga-eventos-paso__titulo {
    margin: 0 0 0.75rem;
    font-family: var(--ga-font-display);
    /* Sube en escritorio sin acercarse al titular de la sección: aquí el techo es
       1.75rem y el de "Cómo funciona" 2.8rem, así que la jerarquía se mantiene. */
    font-size: clamp(1.3rem, 1.7vw, 1.75rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);   /* 9,1:1 sobre blanco */
    text-wrap: balance;
}

/* ——— LA FOTO DE CADA PASO ———
   Mismo tratamiento que las del hero: cuadrada siempre (aspect-ratio: 1 / 1), con el
   mismo redondeo, y la <img> recortada con object-fit heredando ese redondeo, así
   que no hace falta overflow y no se crea ningún contenedor de scroll.

   TAMAÑO CONTENIDO: lo marca un clamp, y el min(100%, …) impide que se pase del
   ancho de su columna por estrecha que sea. Ilustra el paso, no lo protagoniza.
   Las cuatro caen en la misma fila de la rejilla, así que miden exactamente lo
   mismo y quedan a la misma altura aunque los títulos de arriba tengan distinto
   número de líneas.

   Son SOLO imagen: no van dentro de ningún enlace y no tienen ni un estado de
   hover, ni de tamaño ni de color. */
.ga-main--eventos .ga-eventos-paso__foto {
    box-sizing: border-box;   /* el borde del marco vacío no cambia el tamaño */
    /* Más presencia en escritorio (hasta 240px) sin dejar de ser proporcional entre
       las cuatro. El min(100%, …) sigue impidiendo que se pase del ancho de su
       columna, y el aspect-ratio de abajo la mantiene cuadrada. */
    width: min(100%, clamp(8rem, 16vw, 15rem));
    margin: 0 auto var(--ga-space-md);
    aspect-ratio: 1 / 1;
    border-radius: var(--ga-radius-md);
    /* Mismos dos tiempos que el círculo numerado —transform y box-shadow, con la
       misma duración y la misma curva— para que los dos efectos de la sección se
       sientan del mismo material. Ninguna de las dos propiedades ocupa sitio en el
       flujo, así que el hover no puede mover ni descolocar nada. */
    transition: transform var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* Las fotos van a plena luz y sin borde: ningún filtro, ninguna capa encima. */
.ga-main--eventos .ga-eventos-paso__foto img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

/* HOVER: la foto se acerca un 5% y gana una sombra difusa. Solo escala y sombra:
   NI width, NI height, NI padding, NI márgenes, así que el título, la frase y la
   línea de tiempo se quedan exactamente donde estaban. Afecta únicamente a la foto
   señalada; las otras tres no se enteran.
   La sombra es --ga-shadow-lg, un tinte del verde oliva de marca, nunca negro. */
.ga-main--eventos .ga-eventos-paso__foto:hover {
    transform: scale(1.05);
    box-shadow: var(--ga-shadow-lg);
}

/* MARCO PROVISIONAL — mientras la foto no esté subida.
   Mismo tamaño exacto que tendrá la foto, filete dorado fino y relleno crema (y no
   el blanco de los marcos del hero: aquí la sección es blanca y blanco sobre blanco
   dejaría el hueco invisible). El borde vive SOLO aquí: con la foto puesta, la
   imagen va sin recuadro. */
.ga-main--eventos .ga-eventos-paso__foto--vacia {
    background-color: var(--ga-naranja-claro);
    border: 1px solid var(--ga-naranja-apagado);
}

/* Ahorro de movimiento de la foto: ni escala ni transición. Va AQUÍ, después de sus
   reglas base, porque tiene su misma especificidad y a igualdad gana la última. La
   sombra del hover se mantiene: no es movimiento. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-paso__foto {
        transition: none;
    }

    .ga-main--eventos .ga-eventos-paso__foto:hover {
        transform: none;
    }
}

.ga-main--eventos .ga-eventos-paso__texto {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: clamp(0.93rem, 1.05vw, 1.05rem);
    line-height: 1.75;
    color: var(--ga-verde-oliva-oscuro);   /* al 78%, 4,9:1 sobre blanco */
    opacity: 0.78;
    overflow-wrap: break-word;            /* corta el ancho mínimo sin usar min-width */
    text-wrap: pretty;
}


/* ═══════════════════════════════════════════════════════════════════════════
   PISTA DE "DESLIZA" — SOLO MÓVIL
   ═══════════════════════════════════════════════════════════════════════════
   Nace OCULTA. En escritorio y tablet los cuatro pasos se ven de golpe y no hay
   nada que deslizar; solo se enciende dentro del @media de móvil, que es donde
   los pasos son un carrusel. */
.ga-main--eventos .ga-eventos-desliza {
    display: none;
}

/* El vaivén: un empujoncito a la derecha y vuelta, en bucle lento. Va SOLO
   sobre la flecha y SOLO con transform, así que no ocupa sitio en el flujo y no
   puede mover ni descolocar nada de alrededor —ni provocar desbordamiento: son
   6px dentro de un elemento centrado, y la sección lleva overflow-x: clip—.
   Las paradas dejan la flecha QUIETA más de la mitad del ciclo (0-15% y 75-100%)
   para que insinúe el gesto sin llamar la atención ni parpadear. */
@keyframes ga-eventos-desliza-vaiven {
    0%, 15%  { transform: translateX(0); }
    45%      { transform: translateX(6px); }
    75%, 100%{ transform: translateX(0); }
}


/* ——— TABLET (<=1024px) ———
   Cuatro columnas se quedarían en ~150px cada una y los títulos de dos palabras
   empezarían a romperse feo. Pasan a 2 × 2, que a este ancho respira. La línea
   conectora se retira: en dos filas apuntaría al vacío al final de cada una. */
@media (max-width: 1024px) {

    /* Se sueltan las filas compartidas: en 2 × 2 (y, más abajo, apilado) los pasos
       ya no comparten una fila común, y mantener el subgrid dejaría las dos filas de
       pasos pegadas —el hueco vertical entre ellas es justo el row-gap que aquí hace
       falta—. Cada paso vuelve a repartir su interior, como antes de este cambio.
       Los círculos siguen alineados dentro de cada fila porque los pasos se estiran
       y su contenido arranca arriba. */
    .ga-main--eventos .ga-eventos-pasos {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: none;
        gap: var(--ga-space-lg) var(--ga-space-md);
    }

    .ga-main--eventos .ga-eventos-paso {
        display: block;
        grid-row: auto;
    }

    /* La línea se retira en 2 × 2: en dos filas los tramos horizontales del paso 2 y
       del 4 apuntarían al vacío por el borde derecho. Vuelve en cuanto hay una sola
       fila (escritorio) o una sola columna (móvil). */
    .ga-main--eventos .ga-eventos-paso:not(:last-child)::before {
        display: none;
    }
}


/* ——— MÓVIL (<=768px) ———
   Una sola columna: los pasos se apilan en vertical, uno debajo de otro. Es una
   rejilla, no una fila, así que nada puede ser más ancho que el viewport. */
@media (max-width: 768px) {

    /* ——— HUECO ENTRE "CÓMO FUNCIONA" Y "ELIGE TU FORMATO" (1 de 2) ———
       El hueco lo SUMABAN DOS COSAS, no una:
         · este padding inferior de la sección: 4rem = 64px
         · el margen inferior de fábrica del <ol> del carrusel: 1em ≈ 16px
       ("Elige tu formato" no aporta nada: su padding-top es 0 a propósito.)
       Total, unos 80px. Se reducen LAS DOS A LA MITAD, para que el recorte sea
       equilibrado y no salga todo de un lado: 64 → 32 aquí y 16 → 8 en el <ol>,
       que dejan el hueco en 40px, justo la mitad del que había.
       Los 32px se componen con la escala de marca (24 + 8), no con un número
       suelto. El padding SUPERIOR sigue en 0 y el aire interno de las dos
       secciones no se toca. */
    .ga-main--eventos .ga-eventos-proceso {
        padding-bottom: calc(var(--ga-space-md) + var(--ga-space-xs));
    }

    .ga-main--eventos .ga-eventos-seccion__head,
    .ga-product-single .ga-eventos-seccion__head {
        margin-bottom: var(--ga-space-lg);
    }

    /* Titulares más grandes en móvil, a la altura del renglón de la franja de
       introducción. Los llevan las DOS secciones —"Cómo funciona" y "Elige tu
       formato"— con el MISMO clamp, en una sola declaración: así no pueden
       descuadrarse el día que se retoque el tamaño. El titular del bloque de
       contacto se queda como estaba, y en escritorio y tablet no cambia nada:
       esta regla vive dentro del @media. */
    .ga-main--eventos .ga-eventos-proceso .ga-eventos-seccion__titulo,
    .ga-main--eventos .ga-eventos-formatos .ga-eventos-seccion__titulo {
        font-size: clamp(2rem, 9vw, 2.6rem);
    }

    /* ═══════════════════════════════════════════════════════════════════
       CARRUSEL HORIZONTAL DE LOS CUATRO PASOS — SOLO MÓVIL
       ═══════════════════════════════════════════════════════════════════
       🔴 EL PUNTO DELICADO ES NO INFLAR EL VIEWPORT DE MAQUETACIÓN (🪤 nº 1):
       una fila más ancha que la pantalla puesta en el flujo de la página lo
       infla y anula todos los @media, que es lo que rompió la tienda.

       Aquí se sigue el patrón que SÍ funcionó en Nosotros (🪤 nº 12):
         · El contenedor del scroll es .ga-eventos-pasos y NADA más. Su ancho es
           el de su padre .ga-eventos-inner (que ya está limitado y con su
           padding), así que mide exactamente lo que hay disponible y ni un
           píxel más: lo que desborda lo hace HACIA DENTRO.
         · overflow-x va SOLO ahí. Ni en html, ni en body, ni en la sección.
         · La sección lleva además overflow-x: clip como red de seguridad. Es
           `clip` y no `hidden` a propósito: hidden convertiría la sección en
           contenedor de scroll y podría atrapar el gesto táctil (🪤 nº 3).
         · Cada paso mide el 88% del contenedor, en PORCENTAJE, así que nunca
           puede ser más ancho que él. Sin un solo min-width.

       DESLIZAMIENTO CONTINUO, SIN PAGINAR: NO hay scroll-snap. El dedo manda y
       la fila se para donde el usuario la deje, a medio paso si quiere, en vez
       de saltar de una "página" a la siguiente.

       ⚠ ESTO HAY QUE MEDIRLO EN EL MÓVIL DE VERDAD: a 360px, window.innerWidth
       tiene que seguir valiendo 360. Ninguna simulación sirve para esto. */
    .ga-main--eventos .ga-eventos-proceso {
        overflow-x: clip;
    }

    .ga-main--eventos .ga-eventos-pasos {
        /* Hueco entre pasos más corto que antes (24px → 16px): con la tarjeta al
           82vw, es lo que deja asomar el paso siguiente por la derecha en vez de
           que el hueco se coma ese asomo. La línea de tiempo se recalcula sola,
           porque su tramo mide "una tarjeta + este hueco". */
        --ga-ev-pasos-gap: var(--ga-space-sm);

        /* CÍRCULO MÁS GRANDE: 60px → ~76px a 360px. El mínimo del clamp base
           (3.75rem) era lo que valía en móvil, porque el término en vw se queda
           corto a estos anchos; aquí el vw sube a 21 y toma el mando. El radio
           —la altura a la que va la línea que une los círculos— se deriva de
           esta misma variable, así que la línea se recoloca sola. */
        --ga-ev-num-tamano: clamp(4.5rem, 21vw, 6rem);

        /* ═══════════════════════════════════════════════════════════════
           🔴 AQUÍ ESTABA EL MARGEN IZQUIERDO DESCUADRADO
           ═══════════════════════════════════════════════════════════════
           .ga-eventos-pasos es un <ol>, y un <ol> trae de fábrica (hoja de
           estilos del NAVEGADOR) padding-inline-start: 40px. Un padding SOLO
           por la izquierda, sin su equivalente por la derecha.

           El reset global de este tema (ul, ol { list-style: none }) quita la
           viñeta pero NO el padding, y la regla base de .ga-eventos-pasos
           tampoco lo tocaba: nunca ha declarado ni padding ni margin. Por eso
           el intento anterior —pasar los pasos del 88% al 100%— no lo arregló:
           corregía otra cosa y estos 40px seguían debajo.

           EN MÓVIL SE VE ASÍ: .ga-eventos-pasos es el contenedor del scroll y
           mide los 328px útiles (360 − 2 × 1rem del inner). Con 40px de padding
           a la izquierda, su caja de contenido baja a 288px, y como cada paso
           es flex-basis: 100%, el 100% se resuelve sobre esos 288px. Resultado
           en reposo: 40px de blanco a la izquierda + un paso de 288px que
           termina justo en el borde derecho. De ahí el hueco grande a un lado,
           el margen correcto al otro y el contenido cortado antes de tiempo.

           Se anula el padding lateral y también el margen lateral (Astra añade
           margin-left a las listas en algunas versiones; a cero, da igual).
           SOLO EL EJE HORIZONTAL: los márgenes de arriba y de abajo del <ol> se
           quedan como están, que la separación vertical de la sección ya está
           ajustada y no es lo que se ha pedido tocar. */
        padding-inline: 0;
        margin-inline: 0;

        /* ——— HUECO ENTRE "CÓMO FUNCIONA" Y "ELIGE TU FORMATO" (2 de 2) ———
           La otra mitad del hueco: un <ol> trae de fábrica 1em de margen arriba
           y otro abajo. El de abajo es lo último que hay dentro de la sección,
           así que se suma al padding inferior de ésta. Baja de ~16 a 8px.
           SOLO EL DE ABAJO: el de arriba separa el titular del carrusel y ese
           es aire interno de la sección, que no se toca. */
        margin-block-end: var(--ga-space-xs);

        display: flex;
        flex-wrap: nowrap;
        gap: var(--ga-ev-pasos-gap);

        /* El desbordamiento vive AQUÍ y solo aquí. */
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;

        /* Sin barra visible; se arrastra con el dedo. */
        scrollbar-width: none;
        -ms-overflow-style: none;

        /* Se sueltan las filas y columnas de la rejilla de escritorio. */
        grid-template-columns: none;
        grid-template-rows: none;
    }

    .ga-main--eventos .ga-eventos-pasos::-webkit-scrollbar {
        display: none;
    }

    /* ——— NÚMERO, TÍTULO Y TEXTO DEL PASO, A LA ESCALA DEL CÍRCULO ———
       Suben los tres a la vez que el círculo y la foto para que la tarjeta
       crezca entera y no quede una pieza descompensada. Como en el resto de la
       página, con clamp: mínimo, término en vw y tope, así que acompañan al
       ancho de la pantalla sin dispararse en las grandes. */
    .ga-main--eventos .ga-eventos-paso__num {
        font-size: clamp(1.75rem, 7.5vw, 2.25rem);
    }

    .ga-main--eventos .ga-eventos-paso__titulo {
        font-size: clamp(1.5rem, 6.4vw, 1.95rem);
    }

    /* ——— LA FRASE DEL PASO, EN LÍNEAS EQUILIBRADAS ———
       `balance` en vez del `pretty` de la regla base. No cambia el número de
       líneas que salen: reparte las palabras entre esas mismas líneas de forma
       que la más larga sea lo más corta posible.
       Es lo que parte la frase del paso 1 donde se pidió —"La que más te guste
       y" arriba y "mejor se adapte a tu evento" abajo—: de los dos repartos
       posibles en dos líneas, ese es el que deja la línea más larga más corta.
       Se consigue por ANCHO del contenedor y por el reparto del navegador, sin
       un solo <br> en el HTML. */
    .ga-main--eventos .ga-eventos-paso__texto {
        font-size: clamp(1rem, 4.2vw, 1.1rem);
        text-wrap: balance;
    }

    /* ——— 82vw: LA TARJETA CASI LLENA LA PANTALLA Y ASOMA LA SIGUIENTE ———
       La medida va en vw —es decir, en % DE PANTALLA— porque es así como se
       pidió: cada tarjeta ronda el 82% de lo que se ve. A 360px son 295px de
       tarjeta dentro de un contenedor de 328 (360 − 2 × 1rem del inner), así
       que quedan 33px: 16 de hueco y ~17 del paso siguiente asomando, que es
       lo que hace entender que la fila se desliza.

       El margen izquierdo y el derecho siguen valiendo lo mismo: el carril
       arranca en el borde de contenido del inner por los dos lados, que es lo
       que se corrigió al quitarle al <ol> los 40px de padding de fábrica.

       flex-grow y flex-shrink a 0 para que la tarjeta no se estire ni se
       encoja, y max-width con el mismo valor. Ni un solo min-width. 82vw es
       menos que el ancho de la pantalla, así que ninguna tarjeta puede
       desbordarla; y lo que desborda es el CARRIL, hacia dentro de su propio
       contenedor, nunca la página (🪤 nº 1).
       Sin scroll-snap: el avance sigue siendo libre. */
    .ga-main--eventos .ga-eventos-paso {
        flex: 0 0 82vw;
        max-width: 82vw;
    }

    /* ——— LA LÍNEA DE TIEMPO VUELVE, Y AQUÍ YA ES HORIZONTAL ———
       Con los pasos en fila, la geometría de la regla base vale tal cual: cada
       tramo arranca en el centro de SU círculo y mide una columna más el hueco,
       que es justo la distancia hasta el centro del siguiente. Solo hay que
       deshacer el display:none que hereda del bloque de tablet.
       El color, la opacidad de reposo, la transición y el encendido con
       .ga-eventos-linea-activa los hereda de la regla base, así que la
       iluminación progresiva funciona igual que en la home. */
    .ga-main--eventos .ga-eventos-paso:not(:last-child)::before {
        display: block;
    }

    /* Foto más grande, a la escala del resto de la tarjeta: de ~187px a ~238px
       a 360px (66vw). El min(100%, …) sigue impidiendo que se pase del ancho
       del paso —que ahora son 295px—, así que le queda aire a los dos lados.
       Sigue siendo cuadrada por el aspect-ratio de la regla base. */
    .ga-main--eventos .ga-eventos-paso__foto {
        width: min(100%, clamp(12rem, 66vw, 20rem));
    }

    /* ═══════════════════════════════════════════════════════════════════
       EN MÓVIL LA FOTO NO REACCIONA AL DEDO
       ═══════════════════════════════════════════════════════════════════
       El crecimiento y la sombra son un gesto DE RATÓN. En una pantalla táctil
       el :hover se dispara al tocar y, peor, SE QUEDA PEGADO al soltar: el
       navegador mantiene el estado en el último elemento tocado hasta que se
       toca otra cosa, así que la foto se quedaba agrandada. Aquí no pasa nada
       al pulsar: ni escala, ni sombra, ni transición que pueda dejarla a medio
       camino.

       Se anulan los tres estados que puede provocar un toque —:hover, :active
       y :focus— y también el estado de reposo, para que ninguna combinación
       deje un transform residual.

       ESPECIFICIDAD: estos selectores valen exactamente lo mismo que la regla
       base del hover (0,3,0) y un @media no suma nada, así que lo que decide es
       el ORDEN: este bloque va después en el archivo y por eso gana. En
       escritorio y tablet no se aplica —vive dentro del @media— y el efecto
       sigue funcionando exactamente igual que ahora. */
    .ga-main--eventos .ga-eventos-paso__foto,
    .ga-main--eventos .ga-eventos-paso__foto:hover,
    .ga-main--eventos .ga-eventos-paso__foto:focus,
    .ga-main--eventos .ga-eventos-paso__foto:focus-visible,
    .ga-main--eventos .ga-eventos-paso__foto:active {
        transform: none;
        box-shadow: none;
        transition: none;
    }

    /* ═══════════════════════════════════════════════════════════════════
       PISTA DE "DESLIZA": AQUÍ SÍ SE ENCIENDE
       ═══════════════════════════════════════════════════════════════════
       Discreta a propósito: cuerpo pequeño, el verde oliva de marca al 55% y
       las mayúsculas espaciadas de los antetítulos de la página. Se ve de un
       vistazo y no le quita protagonismo a los pasos.
       Centrada, sin margen inferior: el aire de debajo es el padding de la
       sección, el de siempre. */
    .ga-main--eventos .ga-eventos-desliza {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: var(--ga-space-xs);
        margin: var(--ga-space-sm) 0 0;
        font-family: var(--ga-font-body);
        font-size: 0.78rem;
        font-weight: var(--ga-weight-medium);
        letter-spacing: 0.18em;
        text-transform: uppercase;
        color: var(--ga-verde-oliva-oscuro);
        opacity: 0.55;
        /* Se apaga con suavidad al llegar al último paso (clase .is-fin). */
        transition: opacity var(--ga-transition-slow);
    }

    .ga-main--eventos .ga-eventos-desliza__flecha {
        display: flex;   /* que el SVG no arrastre el hueco de la línea base */
        animation: ga-eventos-desliza-vaiven 2.4s ease-in-out infinite;
    }

    /* YA NO HAY MÁS QUE VER: al llegar al último paso, el JS pone esta clase y
       la pista se apaga. pointer-events: none para que ni siquiera cuente como
       algo que se pueda tocar; no se usa display:none para que el apagado sea
       un fundido y no un salto que mueva la sección. */
    .ga-main--eventos .ga-eventos-desliza.is-fin {
        opacity: 0;
        pointer-events: none;
    }

    /* El aire lateral vuelve al de siempre: el clamp de la regla base es el del hero
       y aquí daría algo más de margen del que tenía esta sección en móvil. */
    .ga-main--eventos .ga-eventos-inner {
        padding-inline: var(--ga-space-md);
    }

}


/* Ahorro de movimiento: la pista se queda QUIETA, pero se sigue viendo. El
   usuario no pierde la información —sabe que hay más pasos—, solo el vaivén.
   Va DESPUÉS de la regla que pone la animación, porque tiene su misma
   especificidad y a igualdad gana la última. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-desliza__flecha {
        animation: none;
    }
}


/* ——— AJUSTES FINOS (<=600px) ———
   Comprobado a 360px: el contenido son 360 − 2 × 1.5rem = 312px útiles, y ningún
   elemento impone un ancho mínimo mayor (el círculo mide 60px y el texto envuelve),
   así que no hay desbordamiento horizontal. */
@media (max-width: 600px) {

    .ga-main--eventos .ga-eventos-inner {
        padding-inline: var(--ga-space-sm);   /* 1rem */
    }
}


/* =============================================================================
   EVENTOS — INTRODUCCIÓN (franja de respiro entre el hero y "Cómo funciona")
   =============================================================================
   Dos renglones centrados y una rayita dorada encima. Nada más: ni recuadro, ni
   borde, ni fondo de color, ni cursiva, ni comillas, ni iconos, ni botones. Toda
   la fuerza está en el aire que la rodea.

   MISMO BLANCO que .ga-eventos-proceso, y ninguna de las dos tiene borde ni
   sombra, así que se leen como UNA sola zona blanca continua: no hay corte ni
   cambio de tono entre ellas, solo el cambio de crema a blanco al salir del hero.

   JERARQUÍA: el renglón 1 va en la serif de marca a un máximo de 2.6rem, frente a
   los 4.2rem del titular del hero. Se queda en torno al 62% de aquel, así que
   acompaña sin competir. El renglón 2 baja a ~1.1rem —poco más de un tercio del
   renglón 1— y en un tono más suave.
   ============================================================================= */

.ga-main--eventos .ga-eventos-intro {
    background-color: var(--ga-blanco);

    /* ——— EL AIRE DE LA FRANJA, EN UNA SOLA MEDIDA ———
       Suelo y techo con las medidas de espaciado de marca (2.5rem → 4rem) y el vw
       repartiendo entre medias.
       Se usa DOS veces, y de ahí sale el equilibrio:
         · arriba  → todo el hueco entre el crema del hero y el primer renglón.
         · abajo   → el mismo hueco total hasta el título de "Cómo funciona",
                     partido en dos por la rayita (la mitad antes, la mitad después).
       Cambiando esta línea se mueven los dos a la vez y siguen cuadrando. */
    --ga-ev-intro-aire: clamp(var(--ga-space-lg), 5vw, var(--ga-space-xl));

    padding-top: var(--ga-ev-intro-aire);
    padding-bottom: calc(var(--ga-ev-intro-aire) / 2);
}

/* Columna estrecha y centrada: el texto no se estira de lado a lado. El tope va en
   rem (medida relativa) y no en ch, porque un ch aquí se calcularía con la letra
   del contenedor —Inter a 16px— y no con la de los renglones, que es mucho mayor:
   saldría una columna desproporcionadamente estrecha. */
.ga-main--eventos .ga-eventos-intro__inner {
    max-width: min(100%, 60rem);
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
    text-align: center;
}

/* La rayita: 1px de grosor, el mismo filete fino de la cabecera del sitio, aquí en
   el dorado de marca. Corta y centrada. Es decorativa (aria-hidden en el marcado) y
   no tiene ningún estado.
   VA DEBAJO del segundo renglón (antes iba encima del primero): ahora hace de
   remate de la franja y de separación con "Cómo funciona". Mismo grosor, mismo
   color y mismo ancho que antes; solo cambia dónde se coloca.
   Su margen superior es la MITAD del aire, y la otra mitad la pone el padding
   inferior de la sección: así la rayita queda centrada en el hueco de abajo. */
.ga-main--eventos .ga-eventos-intro__filete {
    display: block;
    width: clamp(2.5rem, 6vw, 4rem);
    height: 1px;
    margin: calc(var(--ga-ev-intro-aire) / 2) auto 0;
    background-color: var(--ga-naranja-apagado);
}

/* La opacidad va explícita en los dos renglones para que no se acumule con el 0.85
   global de <p>. */
.ga-main--eventos .ga-eventos-intro__linea {
    margin: 0;
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 3vw, 2.6rem);
    font-weight: 600;
    line-height: 1.2;
    /* FALLBACK, declarado ANTES del recorte: verde oliva macizo. Si el navegador no
       soporta background-clip: text, el @supports de abajo ni siquiera se aplica y
       el titular se queda con este color, perfectamente legible. Nunca invisible. */
    color: var(--ga-verde-oliva-oscuro);
    -webkit-text-fill-color: var(--ga-verde-oliva-oscuro);
    opacity: 1;
    text-wrap: balance;
}

/* ——— BRILLO ANIMADO SOBRE EL TITULAR ———
   MISMO mecanismo que los botones ("Añadir al carrito" de Novedades y "Ver formatos"
   de esta página): degradado a 100° con las paradas 0% / 45% / 50% / 55% / 100%,
   background-size 250% 100%, no-repeat, arranque en 100% center y la animación
   ga-home-card-brillo 8s linear infinite. Ni una parada ni un porcentaje cambiados, y
   el @keyframes es el mismo de los botones —declarado a nivel raíz más arriba—, así
   que se REUTILIZA tal cual, sin duplicarlo con otro nombre.

   Sobre TEXTO el degradado no se ve solo con ponerlo de fondo: hay que recortarlo a
   las letras con background-clip: text y dejar el relleno del texto transparente. Por
   eso todo esto vive dentro del @supports: donde no se soporte, no se aplica nada y
   manda el verde macizo de la regla de arriba.

   El par de color es el que ya usa el título verde de la tienda: verde oliva oscuro
   de base y --ga-verde-montanas (#7f8649) como punto de luz, un verde de marca más
   luminoso. Se anima ÚNICAMENTE background-position: ni reflow, ni cambio de tamaño,
   ni desplazamiento. Nada de opacidad pulsante, ni box-shadow, ni text-shadow, ni
   capas superpuestas.

   No se toca `display`: la caja del titular sigue siendo la de siempre, así que ni el
   tamaño, ni la posición, ni el espaciado cambian. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {

    .ga-main--eventos .ga-eventos-intro__linea {
        background-image: linear-gradient(
            100deg,
            var(--ga-verde-oliva-oscuro) 0%,
            var(--ga-verde-oliva-oscuro) 45%,
            var(--ga-verde-montanas) 50%,
            var(--ga-verde-oliva-oscuro) 55%,
            var(--ga-verde-oliva-oscuro) 100%
        );
        background-size: 250% 100%;
        background-repeat: no-repeat;
        background-position: 100% center;
        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;
        animation: ga-home-card-brillo 8s linear infinite;

        /* ——— DESFASE RESPECTO AL BOTÓN "VER FORMATOS" ———
           Los dos comparten el mismo @keyframes, la misma duración y la misma curva,
           así que sin retardo arrancan juntos y el barrido cruza los dos a la vez.
           Se separan SOLO con el retardo: la mitad del ciclo de 8s, o sea 4s, que es
           el desfase máximo posible y el único que garantiza que no vuelvan a
           coincidir por mucho rato que se deje la página quieta.

           Va NEGATIVO a propósito. El ciclo barre en su primera mitad (0%→50%) y
           descansa en la segunda, así que un +4s dejaría el titular apagado y quieto
           los primeros 4 segundos de cada carga; con -4s nace ya en ese punto de
           reposo y entra a barrer justo cuando el botón termina el suyo.
           Reparto resultante: barre el botón 0-4s, el titular 4-8s, el botón 8-12s…
           siempre alternándose.

           Va DESPUÉS del atajo `animation`, que reinicia animation-delay a 0. Ni la
           duración, ni la curva, ni el @keyframes, ni las paradas del degradado se
           tocan: el desfase es solo este retardo. */
        animation-delay: -4s;
    }
}

/* Ahorro de movimiento: verde oliva macizo y sin animación. Va DESPUÉS del @supports
   para ganarle por orden: tienen la misma especificidad. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-intro__linea {
        background-image: none;
        animation: none;
        color: var(--ga-verde-oliva-oscuro);
        -webkit-text-fill-color: var(--ga-verde-oliva-oscuro);
    }
}

/* Tono más suave sin cambiar de color: el verde de marca rebajado. Al 78% sobre
   blanco da 4,9:1, por encima del 4,5:1 de la AA. (--ga-verde-montanas, el otro
   candidato de la paleta, se queda en 3,88:1 y no llega.)
   text-wrap: balance reparte las dos líneas en las pantallas donde no cabe en una,
   en vez de dejar una palabra suelta abajo. */
.ga-main--eventos .ga-eventos-intro__apunte {
    margin: var(--ga-space-sm) 0 0;
    font-family: var(--ga-font-body);
    font-size: clamp(0.95rem, 1.2vw, 1.125rem);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.78;
    text-wrap: balance;
    overflow-wrap: break-word;   /* corta el ancho mínimo sin usar min-width */
}


/* ——— MÓVIL (<=768px) ———
   Se recorta el aire vertical para que la franja no deje huecos enormes en una
   pantalla alta y estrecha, y la rayita se acerca al texto.
   A 360px: la columna son 360 − 2 × 1.25rem = 320px útiles; el renglón 1 cae en dos
   líneas y el 2 en dos líneas equilibradas por text-wrap: balance. Ningún elemento
   impone un ancho mínimo, así que no hay desbordamiento horizontal. */
@media (max-width: 768px) {

    /* Basta con redefinir el aire: los dos paddings y el margen de la rayita salen
       de esa única variable, así que se recalculan solos y siguen equilibrados. */
    .ga-main--eventos .ga-eventos-intro {
        --ga-ev-intro-aire: clamp(var(--ga-space-md), 6vw, var(--ga-space-lg));
    }

    /* El renglón grande manda de verdad en la franja: en móvil pasa de 24 a ~32px
       a 360px, más del doble que el renglón de debajo (15px), en vez de quedarse
       casi a su altura. El techo se queda en los 2.6rem del escritorio para que
       el móvil nunca lo supere. */
    .ga-main--eventos .ga-eventos-intro__linea {
        font-size: clamp(2rem, 9vw, 2.6rem);
    }
}


/* =============================================================================
   EVENTOS — ELIGE TU FORMATO (selector de formatos + parrilla de productos)
   =============================================================================
   Va justo debajo de "Cómo funciona" y comparte su mismo blanco, sin borde ni
   sombra entre ambas: se leen como una sola zona continua.

   Lleva el id al que apunta el botón "Ver formatos" del hero, de ahí el
   scroll-margin-top: descuenta la cabecera fija para que el titular no quede
   tapado por ella al saltar.

   🔴 LA FILA DE FORMATOS ENVUELVE, NO SCROLLEA. Con seis opciones no caben en una
   línea a 360px, y las dos salidas posibles eran un carrusel con overflow-x en su
   contenedor o repartirlas en varias líneas. Se ha elegido ENVOLVER (flex-wrap):
   una fila que envuelve NUNCA es más ancha que el viewport, así que no puede
   inflar el viewport de maquetación (🪤 nº 1) y no hace falta ningún contenedor de
   scroll —ni el riesgo de atrapar el gesto táctil que eso trae (🪤 nº 3)—. Además
   las seis opciones quedan a la vista de golpe, sin tener que descubrir que hay
   más deslizando. El nowrap con contenido variable ya dio problemas en el pie
   (🪤 nº 9); aquí se evita de raíz.
   ============================================================================= */

.ga-main--eventos .ga-eventos-formatos {
    background-color: var(--ga-blanco);
    /* Sin padding superior: el aire de encima lo pone el padding inferior de "Cómo
       funciona", y sumarlos dejaría un hueco enorme entre dos secciones del mismo
       color (misma razón por la que aquella lo tiene a 0 respecto a la intro). */
    padding-top: 0;
    padding-bottom: clamp(var(--ga-space-2xl), 8vw, var(--ga-space-3xl));
    scroll-margin-top: var(--ga-nav-height);
}

/* ——— FILA DE FORMATOS ———
   Aire entre pestañas igual que en el subfiltro de la tienda: var(--ga-space-md).
   El hueco entre líneas es menor, porque aquí la fila envuelve y con 24px entre
   renglones quedaría desparramada. */
.ga-main--eventos .ga-eventos-formatos-fila {
    display: flex;
    flex-wrap: wrap;               /* jamás una fila más ancha que el viewport */
    justify-content: center;
    gap: var(--ga-space-sm) var(--ga-space-md);
    margin-bottom: clamp(var(--ga-space-lg), 4vw, var(--ga-space-xl));
}

/* ——— CADA PESTAÑA: SOLO TEXTO CON SUBRAYADO, COMO EN LA TIENDA ———
   Mismo mecanismo que el subfiltro de categorías de la tienda
   (.ga-tienda-subfiltro__btn): sin fondo, sin recuadro y sin esquinas
   redondeadas; oscuro en reposo, dorado en hover y en activo, y una raya dorada
   de 2px que se despliega por debajo.

   EL HUECO DE LA RAYA SE RESERVA DESDE EL PRINCIPIO con un border-bottom de 2px
   transparente, así que al activarse o al pasar el ratón el botón no cambia de
   alto y la fila no baila. La raya la pinta un ::after ABSOLUTO, que tampoco
   ocupa sitio en el flujo.

   La tipografía es la que ya tenían las pestañas —su tamaño y su letter-spacing
   de 0.06em—, tal y como se pidió; lo que se copia de la tienda son los colores,
   la raya, su altura, su duración y su curva. */
.ga-main--eventos .ga-eventos-formato {
    position: relative;                     /* referencia del ::after de la raya */
    padding: 0.25rem 0;                     /* sin padding lateral → la raya mide lo que la palabra */
    font-family: var(--ga-font-body);
    font-size: clamp(0.85rem, 1vw, 0.95rem);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.06em;
    line-height: 1.2;
    background: none;
    border: none;
    border-bottom: 2px solid transparent;   /* reserva el hueco de la raya */
    border-radius: 0;
    cursor: pointer;
    transition: color var(--ga-transition-fast);
}

/* La raya nace a ancho completo pero plegada a la izquierda, y se despliega con
   scaleX —no con width—: transform se compone en GPU, es simétrica al entrar y al
   salir, y no provoca reflow. La transition vive en el estado BASE, que es lo que
   la hace valer en los dos sentidos. Mismos 2px, mismo origen y misma duración y
   curva que en la tienda. */
.ga-main--eventos .ga-eventos-formato::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: -2px;
    width: 100%;
    height: 2px;
    background: var(--ga-naranja-apagado);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--ga-transition-normal);
}

/* 🔴 BLINDAJE FRENTE A ASTRA (misma trampa nº 6 y misma solución que en la
   tienda). Sus estilos globales de <button> pintan fondo y colorean el
   border-bottom en hover/focus/active, y eso daría un fondo indeseado y una
   SEGUNDA línea que chocaría con la del ::after.
   El borde NO se elimina: se devuelve a 2px transparente exactos, porque es lo
   que reserva el hueco de la raya; con border:none el botón perdería 2px de alto
   y la fila daría un salto. */
.ga-main--eventos .ga-eventos-formato,
.ga-main--eventos .ga-eventos-formato:hover,
.ga-main--eventos .ga-eventos-formato:focus,
.ga-main--eventos .ga-eventos-formato:active,
.ga-main--eventos .ga-eventos-formato.is-activo {
    background: none !important;
    border: none !important;
    border-bottom: 2px solid transparent !important;
}

/* Reposo: oscuro y sin raya. */
.ga-main--eventos .ga-eventos-formato {
    color: var(--ga-verde-oliva-oscuro) !important;
}

/* ACTIVO: dorado y raya desplegada de forma permanente. */
.ga-main--eventos .ga-eventos-formato.is-activo {
    color: var(--ga-naranja-apagado) !important;
}

.ga-main--eventos .ga-eventos-formato.is-activo::after {
    transform: scaleX(1);
}

/* HOVER, SOLO DONDE HAY RATÓN DE VERDAD.
   El @media (hover: hover) es la única diferencia respecto a la tienda, y está
   puesta a propósito: en una pantalla táctil el :hover se queda PEGADO en el
   último botón tocado, así que al cambiar de formato se verían dos pestañas
   doradas con raya. Acotándolo, en móvil solo se distingue la activa. */
@media (hover: hover) {

    .ga-main--eventos .ga-eventos-formato:hover {
        color: var(--ga-naranja-apagado) !important;
    }

    .ga-main--eventos .ga-eventos-formato:hover::after {
        transform: scaleX(1);
    }
}

/* Foco de teclado: se enciende como el hover —dorado y raya— y además un anillo
   con outline, que no ocupa sitio en el flujo y por tanto no mueve nada. Se ve
   igual en escritorio y en móvil con teclado externo. */
.ga-main--eventos .ga-eventos-formato:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 4px;
    color: var(--ga-naranja-apagado) !important;
}

.ga-main--eventos .ga-eventos-formato:focus-visible::after {
    transform: scaleX(1);
}

/* Ahorro de movimiento: la raya aparece y desaparece de golpe, sin desplegarse.
   Va después de las reglas base para ganarles por orden a igual especificidad. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-formato,
    .ga-main--eventos .ga-eventos-formato::after {
        transition: none;
    }
}

/* ——— PARRILLA DE PRODUCTOS ———
   auto-fit reparte las columnas según cuántos productos haya: con uno sale una
   sola tarjeta centrada y con siete se reparten en las filas que hagan falta, sin
   tocar nada. El min(100%, …) del minmax impide que una pista sea más ancha que el
   contenedor en pantallas estrechas —ahí manda el 100%—, así que no hay
   desbordamiento y no hace falta ningún min-width.
   Con el array de productos vacío la parrilla no imprime nada y simplemente no
   ocupa alto: un espacio limpio, sin errores ni huecos falsos. */
.ga-main--eventos .ga-eventos-productos {
    display: grid;
    /* TRES POR FILA en escritorio, sin fijar el número de columnas a mano: quien
       lo decide es el MÍNIMO de la pista, porque auto-fit calcula cuántas caben
       usando ese mínimo (no el máximo). Con 20rem por pista y el hueco de 2.5rem,
       en los ~1376px del contenedor no entran cuatro (4 × 320 + 3 × 40 = 1400) y
       sí tres (3 × 320 + 2 × 40 = 1040), que luego crecen hasta su tope de 26rem.
       Así la parrilla sigue siendo fluida: se recoloca sola con 1 a 7 productos,
       nunca deja una tarjeta estirada a lo ancho y va bajando de columnas al
       estrecharse la ventana.
       El min(100%, 20rem) impide que una pista sea más ancha que el contenedor en
       pantallas estrechas: ahí manda el 100% y queda una sola columna. */
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 26rem));
    justify-content: center;
    gap: clamp(var(--ga-space-md), 2.5vw, var(--ga-space-lg));
}

/* El display:grid de la tarjeta ganaría al [hidden] del navegador, así que el
   ocultado se declara aquí de forma explícita. Mismo patrón que el campo
   condicional del formulario de Contacto. */
.ga-main--eventos .ga-eventos-producto[hidden] {
    display: none;
}

/* La tarjeta se acopla a cuatro filas de alto propio: foto · nombre · precio ·
   botón. El 1fr del nombre absorbe la diferencia cuando un producto tiene el
   nombre más largo que otro, así que precios y botones quedan alineados entre
   tarjetas de una misma fila sin ninguna altura escrita a mano. */
.ga-main--eventos .ga-eventos-producto {
    display: grid;
    grid-template-rows: auto 1fr auto auto;
    text-align: center;
}

.ga-main--eventos .ga-eventos-producto__foto {
    display: block;
    box-sizing: border-box;
    width: 100%;
    margin: 0 0 var(--ga-space-md);
    aspect-ratio: 1 / 1;
    border-radius: var(--ga-radius-md);
    background-color: var(--ga-naranja-claro);   /* de fondo mientras carga la foto */
}

.ga-main--eventos .ga-eventos-producto__foto img,
.ga-main--eventos .ga-eventos-producto__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
}

.ga-main--eventos .ga-eventos-producto__nombre {
    margin: 0 0 var(--ga-space-xs);
    font-family: var(--ga-font-display);
    /* Sube con la tarjeta al pasar de cuatro columnas a tres. */
    font-size: clamp(1.2rem, 1.7vw, 1.7rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

/* El enlace del nombre hereda color y no se subraya, como en las tarjetas de la
   tienda. Al interactuar solo cambia de color: nada se mueve. */
.ga-main--eventos .ga-eventos-producto__nombre a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-producto__nombre a:hover,
.ga-main--eventos .ga-eventos-producto__nombre a:focus-visible {
    color: var(--ga-naranja-apagado);
}

/* El precio lo imprime WooCommerce con su propio marcado (<del>, <ins>, <bdi>…
   en rebajas y rangos), así que se le da color y tamaño al contenedor y se
   neutraliza el subrayado que Astra pone al <ins>. */
.ga-main--eventos .ga-eventos-producto__precio {
    margin: 0 0 var(--ga-space-md);
    font-family: var(--ga-font-body);
    font-size: clamp(1rem, 1.3vw, 1.25rem);
    font-weight: var(--ga-weight-medium);
    color: var(--ga-verde-montanas);
}

.ga-main--eventos .ga-eventos-producto__precio ins {
    text-decoration: none;
    background: none;
    color: var(--ga-verde-oliva-oscuro);
}

.ga-main--eventos .ga-eventos-producto__precio del {
    opacity: 0.6;
    margin-right: var(--ga-space-xs);
}

/* Botón a la ficha: mismo lenguaje que el resto de CTA de la página. El borde de
   1px existe ya en reposo, así que ningún estado cambia el tamaño. */
.ga-main--eventos .ga-eventos-producto__btn {
    align-self: end;
    justify-self: center;
    padding: 0.85rem 1.8rem;
    font-family: var(--ga-font-body);
    font-size: clamp(0.82rem, 1vw, 0.95rem);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    text-decoration: none;
    border: 1px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-sm);
    transition: background-color var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                color var(--ga-transition-normal);
}

/* 🔴 BLINDAJE FRENTE A ASTRA (misma trampa nº 6 del resto de botones de la web):
   sus reglas para enlaces y botones ganan a un selector de una sola clase. */
.ga-main--eventos .ga-eventos-producto__btn {
    background-color: transparent !important;
    border-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-naranja-apagado) !important;
}

/* Al pasar el ratón, el botón se rellena de dorado y el texto pasa a BLANCO, el
   mismo --ga-blanco que usan el resto de botones del proyecto. Solo cambian los
   tres colores: fondo, borde y texto. Ni tamaño, ni borde de otro grosor, ni
   posición. Una sola regla vale para "Ver producto" y para "Elegir opciones":
   los dos comparten clase y solo se diferencian en el texto. */
.ga-main--eventos .ga-eventos-producto__btn:hover,
.ga-main--eventos .ga-eventos-producto__btn:focus-visible {
    background-color: var(--ga-naranja-apagado) !important;
    border-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-blanco) !important;
}

.ga-main--eventos .ga-eventos-producto__btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(74, 74, 47, 0.35);
}


/* ——— MÓVIL (<=768px) ———
   Ninguna opción impone un ancho mínimo (no hay un solo min-width), así que no hay
   desbordamiento horizontal. */
@media (max-width: 768px) {

    .ga-main--eventos .ga-eventos-formatos {
        padding-bottom: var(--ga-space-xl);
    }

    /* ═══════════════════════════════════════════════════════════════════
       LAS PESTAÑAS, EN DOS RENGLONES Y CADA UNO CENTRADO POR SU CUENTA
       ═══════════════════════════════════════════════════════════════════
       Arriba 250 ml · 200 ml · 100 ml, abajo Lata · Minibotellas.

       🔴 POR QUÉ EL RENGLÓN DE ABAJO SE IBA A LA DERECHA (y no era culpa del
          flex-wrap: esto era una REJILLA, no una fila flexible).
          Estaba montado como rejilla de 6 columnas: las tres de arriba ocupaban
          2 columnas cada una y las dos de abajo, 3 cada una, con "Lata" pegada
          al final de su mitad (justify-self: end) y "Minibotellas" al principio
          de la suya (justify-self: start). Eso centra LA JUNTA entre las dos, no
          la pareja: cada una crece hacia AFUERA desde el centro, y como
          "Minibotellas" mide unos 90px y "Lata" unos 32, la pareja acababa
          desplazada hacia la derecha justo la mitad de esa diferencia (~29px).
          Una rejilla no puede centrar esa pareja, porque sus columnas son
          comunes a los dos renglones y no conocen el ancho de cada palabra.

       ✅ LA SOLUCIÓN: volver a la fila FLEXIBLE de la regla base, porque
          justify-content: center en flex centra CADA RENGLÓN POR SEPARADO —es
          alineación dentro de cada línea, no del bloque entero—. Los dos quedan
          centrados solos, sin colocar nada a mano.

       Y el reparto 3 + 2 lo decide el ANCHO de la fila: es el único número que
       manda dónde cae el salto. Tiene que ser lo bastante ancho para los tres
       primeros y lo bastante estrecho para que "Lata" no quepa detrás.

       🔴 POR QUÉ SALÍAN TRES RENGLONES: este techo estaba en 13rem (208px) y se
          quedaba corto. Los tres de arriba no cabían —solo entraban dos—, así
          que "100 ml" bajaba con "Lata" y "Minibotellas" caía sola en un tercer
          renglón. NO era el relleno lateral de las pestañas: no tienen (su
          padding es 0.25rem 0, sin nada a los lados), y el tamaño de letra es
          el que se pidió y no se toca.

       LA MEDIDA, CALIBRADA CON LO QUE YA SABEMOS: si tres pestañas más sus dos
       huecos no cabían en 208px, cada pestaña mide más de (208 − 32) / 3 ≈ 59px.
       Con ese dato, 15.5rem (248px) cumple las dos condiciones a la vez:
         · caben tres mientras cada una no pase de 72px  → (248 − 32) / 3
         · "Lata" no cabe detrás mientras cada una pase de ~56px, y ya sabemos
           que pasa de 59px, así que el cuarto baja seguro al segundo renglón.
       Queda margen por los dos lados, que es de lo que se trata.

       248px de los 328 disponibles a 360px: sobra sitio y no puede desbordar.
       Es max-width (un techo), nunca min-width, y la fila va centrada con
       margin-inline: auto.

       🔧 SI ALGÚN DÍA HAY QUE AFINARLO: se toca SOLO este número. Más ancho si
          faltara sitio arriba; más estrecho si "Lata" se subiera al primero.

       Si se añadiera un sexto formato, caería a un tercer renglón, también
       centrado. Nada se desborda: la fila envuelve. */
    .ga-main--eventos .ga-eventos-formatos-fila {
        max-width: 15.5rem;
        margin-inline: auto;
        gap: var(--ga-space-sm);   /* misma separación entre renglones y entre pestañas */
    }

    .ga-main--eventos .ga-eventos-formato {
        font-size: clamp(0.95rem, 3.9vw, 1.15rem);
        /* Que ninguna pestaña se parta por dentro: "250 ml" no puede dejar el
           "ml" en el renglón de abajo. */
        white-space: nowrap;
    }
}


/* =============================================================================
   EVENTOS — MERMELADA (cierre de la página)
   =============================================================================
   Réplica del patrón de la sección de la home (.ga-mermelada-split): rejilla
   50/50, foto del tarro en un marco claro a la izquierda y bloque de texto a la
   derecha; apilada en móvil.

   LO QUE CAMBIA RESPECTO A LA REFERENCIA es el fondo, crema en vez de verde, y
   con él los colores que dependían de ese verde:
     · fondo de la sección  → --ga-naranja-claro   (era --ga-verde-oliva-oscuro)
     · fondo del marco      → --ga-blanco          (era el crema #F9F6EE, que
                              sobre un fondo crema desaparecería)
     · titular              → --ga-verde-oliva-oscuro (era --ga-blanco)
     · párrafo              → --ga-verde-oliva-oscuro al 78%, 4,9:1 sobre crema
                              (era --ga-naranja-claro al 90%)
   El filete dorado del marco y el antetítulo en dorado se quedan como estaban:
   sobre crema siguen leyéndose igual que sobre verde.

   NO se replica el scale del marco al pasar el ratón que sí tiene la home: en
   esta página ningún hover puede cambiar tamaño ni posición. El marco conserva
   su cambio de color, que es solo pintura.
   ============================================================================= */

.ga-main--eventos .ga-eventos-mermelada {
    background-color: var(--ga-naranja-claro);
    padding-block: clamp(var(--ga-space-xl), 7vw, var(--ga-space-2xl));
}

.ga-main--eventos .ga-eventos-mermelada__marco {
    max-width: var(--ga-max-width);
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: center;
    gap: clamp(var(--ga-space-lg), 5vw, var(--ga-space-2xl));
}

.ga-main--eventos .ga-eventos-mermelada__imagen {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* El marco ES el enlace. Cuadrado, con el mismo filete dorado y el mismo
   redondeo que en la home; el ancho lo marca un clamp con tope en porcentaje,
   así que nunca se pasa de su columna. */
.ga-main--eventos .ga-eventos-mermelada__frame {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: min(100%, clamp(12rem, 26vw, 21.25rem));
    aspect-ratio: 1 / 1;
    background-color: var(--ga-blanco);
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-md);
    overflow: hidden;
    transition: background-color var(--ga-transition-normal);
}

/* HOVER: SOLO el color de fondo del marco. Ni escala, ni desplazamiento, ni
   cambio de borde: el filete dorado y el tamaño se quedan exactamente igual, así
   que ni la foto ni el texto de la derecha se mueven.

   El dorado se atenúa MEZCLÁNDOLO con el blanco del propio marco, no bajando la
   opacidad del contenedor —eso apagaría también la foto—. Un 22% del dorado de
   marca deja un tono suave que se nota sin robarle protagonismo al tarro, y al
   salir de color-mix no hay ningún color nuevo escrito a mano.

   La primera declaración es el respaldo: los navegadores que no entiendan
   color-mix se quedan con el crema de marca, que es lo que había antes. */
.ga-main--eventos .ga-eventos-mermelada__frame:hover,
.ga-main--eventos .ga-eventos-mermelada__frame:focus-visible {
    background-color: var(--ga-naranja-claro);
    background-color: color-mix(in srgb, var(--ga-naranja-apagado) 22%, var(--ga-blanco));
}

.ga-main--eventos .ga-eventos-mermelada__frame:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 4px;
}

/* Mismo tratamiento del tarro que en la home: cover y una escala fija para que
   el producto llene el recuadro con presencia. Es un valor de reposo, no un
   estado: no cambia nunca. */
.ga-main--eventos .ga-eventos-mermelada__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center;
    transform: scale(1.25);
    transform-origin: center;
}

/* ——— BLOQUE DE TEXTO ——— */
.ga-main--eventos .ga-eventos-mermelada__antetitulo {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.22em;
    line-height: 1.4;
    color: var(--ga-naranja-apagado);
    opacity: 1;
}

.ga-main--eventos .ga-eventos-mermelada__titulo {
    margin: clamp(0.75rem, 1.5vw, 1.25rem) 0 0;
    font-family: var(--ga-font-display);
    font-size: clamp(2rem, 3.5vw, 2.75rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

.ga-main--eventos .ga-eventos-mermelada__desc {
    margin: var(--ga-space-sm) 0 0;
    max-width: 48ch;
    font-family: var(--ga-font-body);
    font-size: clamp(1rem, 1.15vw, 1.125rem);
    line-height: 1.85;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.78;
    text-wrap: pretty;
}

/* ——— BOTÓN ———
   Mismo dorado y mismo brillo que "Ver formatos": los dos colores viven en
   propiedades personalizadas usadas DENTRO del degradado, así que el hover solo
   redefine el par y el barrido no se reinicia. */
.ga-main--eventos .ga-eventos-mermelada__btn {
    --ga-ev-merm-fondo: var(--ga-naranja-apagado);
    --ga-ev-merm-luz:   #e6d0a0;

    margin-top: clamp(1.5rem, 3vw, 2.25rem);
    display: inline-block;
    max-width: 100%;
    padding: 1.05rem 2.5rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-decoration: none;
    color: var(--ga-blanco);
    background-color: var(--ga-ev-merm-fondo);
    border: 1px solid var(--ga-ev-merm-fondo);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    transition: background-color var(--ga-transition-normal),
                background-image var(--ga-transition-normal),
                border-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

/* Brillo: copia literal del de los botones —mismas paradas, mismo
   background-size, mismo @keyframes reutilizado, misma duración y curva—.
   🔴 EL RETARDO ES LA ÚNICA DIFERENCIA: el ciclo dura 8s y barre en su primera
   mitad, y en esta página ya hay dos brillos ocupando las dos mitades (el botón
   "Ver formatos" barre de 0 a 4s y el titular de la introducción de 4 a 8s).
   Con -6s este entra a barrer de 2 a 6s: no arranca a la vez que ninguno de los
   dos y queda repartido entre ambos, que es lo más separado posible siendo el
   tercero de tres en un mismo ciclo. */
.ga-main--eventos .ga-eventos-mermelada__btn {
    background-image: linear-gradient(
        100deg,
        var(--ga-ev-merm-fondo) 0%,
        var(--ga-ev-merm-fondo) 45%,
        var(--ga-ev-merm-luz) 50%,
        var(--ga-ev-merm-fondo) 55%,
        var(--ga-ev-merm-fondo) 100%
    );
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
    animation-delay: -6s;
}

/* Al interactuar solo cambia el par de colores: el barrido sigue su recorrido. */
.ga-main--eventos .ga-eventos-mermelada__btn:hover,
.ga-main--eventos .ga-eventos-mermelada__btn:focus-visible,
.ga-main--eventos .ga-eventos-mermelada__btn:active {
    --ga-ev-merm-fondo: var(--ga-verde-oliva-oscuro);
    --ga-ev-merm-luz:   #7a7a54;
}

.ga-main--eventos .ga-eventos-mermelada__btn:hover {
    box-shadow: var(--ga-shadow-md);
}

.ga-main--eventos .ga-eventos-mermelada__btn:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(74, 74, 47, 0.45);
}

/* Blindaje frente a Astra. Ahora es un <button>, no un <a>, y Astra estiliza los
   botones con fondo, borde y color propios, así que hace falta blindar las tres
   cosas y no solo el color. El degradado también va con !important para que un
   `background: none` global no se lleve por delante el brillo; como se construye
   con las propiedades personalizadas, el hover sigue funcionando redefiniéndolas. */
.ga-main--eventos .ga-eventos-mermelada__btn,
.ga-main--eventos .ga-eventos-mermelada__btn:hover,
.ga-main--eventos .ga-eventos-mermelada__btn:focus,
.ga-main--eventos .ga-eventos-mermelada__btn:focus-visible,
.ga-main--eventos .ga-eventos-mermelada__btn:active {
    color: var(--ga-blanco) !important;
    background-color: var(--ga-ev-merm-fondo) !important;
    border-color: var(--ga-ev-merm-fondo) !important;
    background-image: linear-gradient(
        100deg,
        var(--ga-ev-merm-fondo) 0%,
        var(--ga-ev-merm-fondo) 45%,
        var(--ga-ev-merm-luz) 50%,
        var(--ga-ev-merm-fondo) 55%,
        var(--ga-ev-merm-fondo) 100%
    ) !important;
}

/* Ahorro de movimiento. Va DESPUÉS de las reglas base del marco y del botón para
   ganarles por orden a igual especificidad. El marco sigue cambiando de color al
   pasar el ratón, pero de golpe, sin transición. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-mermelada__frame {
        transition: none;
    }

    .ga-main--eventos .ga-eventos-mermelada__btn {
        background-image: none !important;
        animation: none;
    }
}


/* =============================================================================
   EVENTOS — DIÁLOGO DE PRESUPUESTO
   =============================================================================
   Ventana centrada sobre un velo oscuro, con el contacto directo arriba y el
   formulario debajo. La abre el botón de la sección de la mermelada.

   🔴 CÓMO SE BLOQUEA EL SCROLL DE DETRÁS, Y POR QUÉ ASÍ.
   NO se usa overscroll-behavior: en el body bloquea el scroll en Chrome de
   Android (🪤 nº 2), y tampoco se toca el overflow de html ni de body, que
   llevan el cortafuegos anti-scroll horizontal. Lo hace el JS fijando el <body>
   con position:fixed y un top negativo igual al scroll actual, y devolviéndolo
   al cerrar: el documento deja de poder desplazarse porque literalmente ya no
   desborda, sin tocar ninguna propiedad de overflow y sin que la página dé un
   salto al abrir ni al cerrar. Funciona igual en iOS y en Android.

   El diálogo es position:fixed sobre el viewport, así que NO añade alto ni ancho
   al documento y no puede provocar desbordamiento horizontal. Si el contenido no
   cabe, el que se desplaza es SU PROPIA CAJA (overflow-y en .__caja), nunca la
   página.
   ============================================================================= */

/* =============================================================================
   EVENTOS — CONTACTO (cierre de la página)
   =============================================================================
   Titular y frase centrados arriba y, debajo, dos bloques del mismo ancho con
   una raya divisoria entre ellos. Fondo BLANCO, para que corte contra el crema
   de la sección de la mermelada que queda justo encima.

   LA RAYA es el borde izquierdo del SEGUNDO bloque, no un elemento aparte: al
   ser las dos columnas iguales cae exactamente en el centro, y no ocupa una
   pista de la rejilla ni hay nada que colocar a mano. En móvil ese mismo borde
   pasa de izquierdo a superior y la raya queda horizontal entre ambos.
   ============================================================================= */

/* 🔴 SIN PADDING SUPERIOR, A PROPÓSITO.
   Esta sección va ahora detrás de Preguntas frecuentes y las dos comparten el
   mismo blanco, así que sus separaciones se SUMABAN: el padding inferior de la
   FAQ (hasta 96px) más el superior de aquí (otros 96) daban casi 200px de blanco
   muerto entre un bloque y otro. Ahora el aire de encima lo pone ENTERO la FAQ,
   que es la que tiene que cuadrarlo con el suyo de arriba.
   El padding INFERIOR sí es de esta sección —es lo que la separa del pie— y baja
   a 2.5→4rem, en línea con el resto de separaciones de la página. */
.ga-main--eventos .ga-eventos-contacto,
.ga-product-single .ga-eventos-contacto {
    background-color: var(--ga-blanco);
    padding-top: 0;
    padding-bottom: clamp(var(--ga-space-lg), 5vw, var(--ga-space-xl));
}

.ga-main--eventos .ga-eventos-contacto__inner,
.ga-product-single .ga-eventos-contacto__inner {
    max-width: var(--ga-max-width);
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
}

/* La frase bajo el titular. El tono suave se consigue rebajando el verde de
   marca: al 78% sobre blanco da 4,9:1, por encima del 4,5:1 de la AA. La
   opacidad va explícita para que no se acumule con el 0.85 global de <p>. */
.ga-main--eventos .ga-eventos-contacto__frase,
.ga-product-single .ga-eventos-contacto__frase {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-base);
    line-height: 1.7;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.78;
    text-wrap: pretty;
}

/* Menos aire entre la frase y los bloques que en las otras secciones: aquí lo
   que sigue son dos datos, no una parrilla, y con la separación común quedaba un
   hueco muerto. Va acotado a esta sección, así que "Cómo funciona" y "Elige tu
   formato" conservan la suya. */
.ga-main--eventos .ga-eventos-contacto .ga-eventos-seccion__head,
.ga-product-single .ga-eventos-contacto .ga-eventos-seccion__head {
    margin-bottom: clamp(1.25rem, 2.5vw, 2rem);
}

/* align-items en STRETCH (el valor por defecto, ya no se centra): los dos
   bloques arrancan a la misma altura, así que la etiqueta de uno queda a la
   altura de la del otro y lo mismo con el dato, aunque el de la izquierda lleve
   una línea más debajo. Y al estirarse los dos a la altura de la fila, la raya
   divisoria —que es el borde del segundo— abarca el bloque completo, etiqueta
   incluida, sin sobresalir. */
.ga-main--eventos .ga-eventos-contacto__filas,
.ga-product-single .ga-eventos-contacto__filas {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.ga-main--eventos .ga-eventos-contacto__bloque,
.ga-product-single .ga-eventos-contacto__bloque {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;   /* el contenido arranca arriba en los dos */
    gap: var(--ga-space-xs);
    padding: var(--ga-space-sm) var(--ga-space-md);
    text-align: center;
}

/* Etiqueta: mismo tratamiento que los antetítulos de la página —Inter, tamaño
   pequeño, mucho espaciado entre letras y dorado de marca—. Las mayúsculas van
   en el texto, no forzadas por CSS. */
.ga-main--eventos .ga-eventos-contacto__etiqueta,
.ga-product-single .ga-eventos-contacto__etiqueta {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.22em;
    line-height: 1.4;
    color: var(--ga-naranja-apagado);
    opacity: 1;
}

/* La coletilla del WhatsApp: pequeña y en tono suave, para que no compita con el
   número. Solo la lleva el bloque de la izquierda; al ir DEBAJO del dato, no
   descoloca ni la etiqueta ni el número del otro lado. */
.ga-main--eventos .ga-eventos-contacto__nota,
.ga-product-single .ga-eventos-contacto__nota {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.5;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.7;
}

.ga-main--eventos .ga-eventos-contacto__bloque + .ga-eventos-contacto__bloque,
.ga-product-single .ga-eventos-contacto__bloque + .ga-eventos-contacto__bloque {
    border-left: 1px solid var(--ga-naranja-apagado);
}

/* Los dos datos son enlaces. Al interactuar SOLO cambian de color y se subrayan:
   ni tamaño ni posición. overflow-wrap corta el correo si hiciera falta, sin
   necesidad de ningún min-width. */
.ga-main--eventos .ga-eventos-contacto__enlace,
.ga-product-single .ga-eventos-contacto__enlace {
    display: inline-flex;
    align-items: center;           /* centra ópticamente el icono con el número */
    gap: var(--ga-space-xs);
    font-family: var(--ga-font-body);
    /* El dato es lo que más pesa de la sección: sube de tamaño respecto a la
       etiqueta y a la nota, y va en el verde oliva de marca. */
    font-size: clamp(1.25rem, 2.2vw, 1.75rem);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;
    text-decoration: none;
    overflow-wrap: break-word;
    transition: color var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-contacto__enlace,
.ga-product-single .ga-eventos-contacto__enlace,
.ga-main--eventos .ga-eventos-contacto__enlace:focus,
.ga-product-single .ga-eventos-contacto__enlace:focus {
    color: var(--ga-verde-oliva-oscuro) !important;
}

.ga-main--eventos .ga-eventos-contacto__enlace:hover,
.ga-product-single .ga-eventos-contacto__enlace:hover,
.ga-main--eventos .ga-eventos-contacto__enlace:focus-visible,
.ga-product-single .ga-eventos-contacto__enlace:focus-visible {
    color: var(--ga-naranja-apagado) !important;
    text-decoration: underline;
}

/* El icono, en el verde propio de WhatsApp y del mismo tamaño (20px) que el del
   diálogo de presupuesto. Es el único color ajeno a la paleta de la marca, y va
   así porque es el color identificativo del servicio. */
.ga-main--eventos .ga-eventos-contacto__ico,
.ga-product-single .ga-eventos-contacto__ico {
    display: flex;
    flex: 0 0 auto;
    color: #25D366;
}


/* ——— MÓVIL (<=768px) ———
   Los bloques se apilan y la raya pasa de vertical a horizontal entre ambos.
   A 360px el correo dispone de los 312px completos —no de media columna—, así
   que entra holgado y no hay desbordamiento horizontal. */
@media (max-width: 768px) {

    .ga-main--eventos .ga-eventos-contacto__filas,
    .ga-product-single .ga-eventos-contacto__filas {
        grid-template-columns: minmax(0, 1fr);
    }

    /* ——— SIN DIVISORIA Y SIN COLETILLA EN MÓVIL ———
       Apilados y a lo ancho de la pantalla, los dos bloques ya se leen como dos
       cosas distintas: la raya solo añadía ruido. Se quita la vertical que
       heredaría de escritorio Y se deja sin poner la horizontal.
       En escritorio y tablet la divisoria sigue igual: esto vive dentro del
       @media y allí manda la regla base. */
    .ga-main--eventos .ga-eventos-contacto__bloque + .ga-eventos-contacto__bloque,
    .ga-product-single .ga-eventos-contacto__bloque + .ga-eventos-contacto__bloque {
        border-left: none;
        border-top: none;
    }

    /* "También por WhatsApp" fuera en móvil: el icono verde que acompaña al
       número ya lo dice, y en pantalla estrecha esa línea de más solo separa el
       teléfono del correo. Se OCULTA, no se borra del HTML: en escritorio y
       tablet se sigue leyendo. */
    .ga-main--eventos .ga-eventos-contacto__nota,
    .ga-product-single .ga-eventos-contacto__nota {
        display: none;
    }
}


/* =============================================================================
   EVENTOS — PREGUNTAS FRECUENTES
   =============================================================================
   <details>/<summary> nativos, sin JavaScript. Fondo crema, para alternar con el
   blanco de la sección de contacto que va justo encima.

   ⚠ NOTA PARA EL FUTURO: en la página de Contacto este patrón se descartó y se
   hizo con <button aria-expanded> + grid-template-rows, porque en su día el
   <details> nativo no se podía animar. Aquí se usa <details> a propósito —para
   que funcione sin JS y para que el buscador lea las respuestas plegadas—, y la
   animación se resuelve con lo que sí existe hoy: ::details-content junto a
   interpolate-size y transition-behavior: allow-discrete. Va todo dentro de un
   @supports, así que donde no se soporte el desplegable abre de golpe, que es el
   comportamiento nativo de siempre: nunca se rompe.
   ============================================================================= */

.ga-main--eventos .ga-eventos-faq {
    background-color: var(--ga-blanco);
    padding-block: clamp(var(--ga-space-xl), 7vw, var(--ga-space-2xl));
}

.ga-main--eventos .ga-eventos-faq__inner {
    max-width: var(--ga-max-width);
    margin-inline: auto;
    padding-inline: clamp(1.25rem, 4vw, 3rem);
}

/* DOS COLUMNAS INDEPENDIENTES.
   Cada columna es su propio contenedor con sus seis preguntas dentro, así que al
   desplegar una respuesta crece SOLO esa columna: la otra ni se mueve. Con una
   rejilla de preguntas sueltas no sería así —las de una misma fila comparten
   alto y se empujarían— ni se conservaría el orden de arriba abajo.

   ANCHO DE LECTURA: la lista se limita y se centra, de modo que en escritorio
   cada columna ronda los 460px y las respuestas no cruzan la pantalla.
   La separación entre columnas es amplia a propósito, para que se lean como dos
   bloques y no como un texto partido por la mitad. */
.ga-main--eventos .ga-eventos-faq__lista,
.ga-product-single--eventos .ga-eventos-faq__lista {
    max-width: min(100%, 64rem);
    margin-inline: auto;
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    align-items: start;            /* cada columna mide lo suyo, sin estirarse */
    column-gap: clamp(var(--ga-space-lg), 5vw, var(--ga-space-2xl));
}

.ga-main--eventos .ga-eventos-faq__item,
.ga-product-single--eventos .ga-eventos-faq__item {
    border-bottom: 1px solid var(--ga-amarillo-pastel);
}

/* La pregunta. Se retira el triángulo del navegador por las dos vías que hacen
   falta: list-style para los navegadores actuales y el pseudoelemento propio de
   WebKit para Safari. */
.ga-main--eventos .ga-eventos-faq__pregunta,
.ga-product-single--eventos .ga-eventos-faq__pregunta {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--ga-space-sm);
    padding: var(--ga-space-md) 0;
    list-style: none;
    cursor: pointer;
    font-family: var(--ga-font-display);
    font-size: clamp(1.1rem, 1.5vw, 1.35rem);
    font-weight: 600;
    line-height: 1.35;
    color: var(--ga-verde-oliva-oscuro);
    transition: color var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-faq__pregunta::-webkit-details-marker,
.ga-product-single--eventos .ga-eventos-faq__pregunta::-webkit-details-marker {
    display: none;
}

/* Hover y foco: SOLO color. Ni tamaño ni posición. */
.ga-main--eventos .ga-eventos-faq__pregunta:hover,
.ga-product-single--eventos .ga-eventos-faq__pregunta:hover,
.ga-main--eventos .ga-eventos-faq__item[open] > .ga-eventos-faq__pregunta,
.ga-product-single--eventos .ga-eventos-faq__item[open] > .ga-eventos-faq__pregunta {
    color: var(--ga-naranja-apagado);
}

.ga-main--eventos .ga-eventos-faq__pregunta:focus-visible,
.ga-product-single--eventos .ga-eventos-faq__pregunta:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

.ga-main--eventos .ga-eventos-faq__texto,
.ga-product-single--eventos .ga-eventos-faq__texto {
    overflow-wrap: break-word;   /* corta el ancho mínimo sin usar min-width */
}

/* INDICADOR de abierto/cerrado, a la derecha y en dorado: una punta de flecha
   que gira media vuelta al abrirse. El giro es del icono, que va en su propia
   caja de tamaño fijo, así que no mueve ni el texto ni la fila. */
.ga-main--eventos .ga-eventos-faq__icono,
.ga-product-single--eventos .ga-eventos-faq__icono {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--ga-naranja-apagado);
    transition: transform var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-faq__item[open] .ga-eventos-faq__icono,
.ga-product-single--eventos .ga-eventos-faq__item[open] .ga-eventos-faq__icono {
    transform: rotate(180deg);
}

.ga-main--eventos .ga-eventos-faq__respuesta,
.ga-product-single--eventos .ga-eventos-faq__respuesta {
    padding-bottom: var(--ga-space-md);
}

.ga-main--eventos .ga-eventos-faq__respuesta p,
.ga-product-single--eventos .ga-eventos-faq__respuesta p {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: clamp(0.95rem, 1.1vw, 1.05rem);
    line-height: 1.8;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.82;
    text-wrap: pretty;
}

/* ——— DESPLIEGUE SUAVE ———
   interpolate-size permite interpolar hacia `auto`, y allow-discrete hace que
   content-visibility acompañe a la transición en lugar de cortarla en seco. Se
   declara en la sección (la propiedad se hereda) y NO en :root, para no tocar
   nada fuera de Eventos.
   Todo va dentro de @supports y de prefers-reduced-motion: sin soporte, o con el
   ahorro de movimiento activo, el desplegable abre de golpe como siempre. */
@media (prefers-reduced-motion: no-preference) {

    @supports selector(::details-content) {

        .ga-main--eventos .ga-eventos-faq,
        .ga-product-single--eventos .ga-eventos-faq {
            interpolate-size: allow-keywords;
        }

        .ga-main--eventos .ga-eventos-faq__item::details-content,
        .ga-product-single--eventos .ga-eventos-faq__item::details-content {
            block-size: 0;
            overflow: hidden;
            transition: block-size var(--ga-transition-normal),
                        content-visibility var(--ga-transition-normal);
            transition-behavior: allow-discrete;
        }

        .ga-main--eventos .ga-eventos-faq__item[open]::details-content,
        .ga-product-single--eventos .ga-eventos-faq__item[open]::details-content {
            block-size: auto;
        }
    }
}

/* Con ahorro de movimiento el icono tampoco gira con animación: cambia y ya. */
@media (prefers-reduced-motion: reduce) {

    .ga-main--eventos .ga-eventos-faq__icono,
    .ga-product-single--eventos .ga-eventos-faq__icono,
    .ga-main--eventos .ga-eventos-faq__pregunta,
    .ga-product-single--eventos .ga-eventos-faq__pregunta {
        transition: none;
    }
}


/* ——— MÓVIL (<=768px) ———
   Comprobado a 360px: la pregunta envuelve, el icono mide 18px en su caja fija y
   ningún elemento impone un ancho mínimo mayor que los 312px útiles, así que no
   hay desbordamiento horizontal. */
@media (max-width: 768px) {

    .ga-main--eventos .ga-eventos-faq {
        padding-block: var(--ga-space-xl);
    }

    /* Una sola columna: los dos contenedores se apilan y las doce preguntas
       quedan seguidas en su orden original (1-6 y después 7-12), porque ese es
       el propio orden del HTML. No hace falta reordenar nada. */
    .ga-main--eventos .ga-eventos-faq__lista,
    .ga-product-single--eventos .ga-eventos-faq__lista {
        grid-template-columns: minmax(0, 1fr);
    }

    .ga-main--eventos .ga-eventos-faq__pregunta,
    .ga-product-single--eventos .ga-eventos-faq__pregunta {
        padding: var(--ga-space-sm) 0;
    }
}


/* CONGELADO DE LA PÁGINA MIENTRAS EL DIÁLOGO ESTÁ ABIERTO.
   Regla NUEVA, no toca ninguna existente, y la clase solo la pone el JS de esta
   página, así que fuera de Eventos no existe. El `top` negativo lo escribe el
   JS con el scroll del momento y lo borra al cerrar.
   Al quedar el <body> fijado al viewport, el documento deja de desbordar y no
   hay nada que desplazar: ni overflow ni overscroll-behavior de por medio, que
   es justo lo que había que evitar. */
body.ga-eventos-modal-abierto {
    position: fixed;
    left: 0;
    right: 0;
    width: 100%;
}

.ga-main--eventos .ga-eventos-modal {
    position: fixed;
    inset: 0;
    z-index: 2000;                 /* por encima de la cabecera fija (1000) */
    display: flex;
    align-items: center;
    justify-content: center;
    padding: clamp(var(--ga-space-sm), 4vw, var(--ga-space-lg));
}

/* El [hidden] del navegador perdería contra el display:flex de arriba. */
.ga-main--eventos .ga-eventos-modal[hidden] {
    display: none;
}

.ga-main--eventos .ga-eventos-modal__velo {
    position: absolute;
    inset: 0;
    background-color: var(--ga-verde-oliva-oscuro);
    opacity: 0.6;                  /* velo con color de marca, nunca negro puro */
}

/* ═══════════════════════════════════════════════════════════════════════════
   LA CAJA: NUNCA MÁS ALTA QUE LA PANTALLA, Y CON CABECERA FIJA
   ═══════════════════════════════════════════════════════════════════════════
   · ALTO. El tope es el alto del viewport menos el aire de arriba y abajo (que
     es el padding del velo, la misma medida, así que las dos separaciones son
     iguales por construcción). Va en dvh y NO en vh: en el móvil, 100vh es el
     viewport GRANDE —el de cuando la barra del navegador está recogida—, así
     que con vh la caja se pasaba de largo y sus bordes de arriba y de abajo se
     quedaban fuera de la pantalla. dvh mide lo que se ve AHORA MISMO.
     La línea de vh se deja ENCIMA como respaldo: un navegador que no entienda
     dvh descarta la segunda y se queda con la primera, que es la de siempre.

   · NO PUEDE SALIRSE. Como el tope nunca supera el viewport, la caja siempre
     cabe centrada y no hace falta anclarla arriba: sus dos bordes quedan dentro
     de la pantalla siempre. Y el diálogo va a z-index 2000, por encima de la
     cabecera fija (1000), así que tampoco se mete por debajo de ella.

   · YA NO SE DESPLAZA LA CAJA, sino su cuerpo. La caja pasa a ser una columna
     flexible: titular arriba (fijo) y cuerpo debajo (el que scrollea). Es lo
     que mantiene la equis y el titular siempre a la vista.

   · 🔴 EL RECORTE VA EN `clip`, NO EN `hidden` (🪤 nº 3 del proyecto). Esta era
     la causa de que el scroll interno se atascara: `hidden` CONVIERTE AL
     ELEMENTO EN CONTENEDOR DE SCROLL, así que había DOS contenedores de scroll
     anidados —la caja, que no tiene nada que desplazar, y dentro el cuerpo, que
     sí—. El gesto táctil se quedaba atrapado en el que no tocaba, y se notaba
     sobre todo al llegar abajo del todo e intentar volver a subir, porque el
     tirón se encadenaba a la caja, que no se mueve.
     `clip` recorta exactamente igual, respeta el redondeo del borde y NO crea
     contenedor de scroll: el otro eje se queda en `visible`. Con esto queda UN
     SOLO contenedor de scroll en el diálogo, que es el cuerpo.

   · EL AIRE LATERAL YA NO VIVE AQUÍ. La caja solo se queda el de arriba y el de
     abajo; el de los lados lo ponen el titular y el cuerpo, cada uno el suyo.
     Así el cuerpo llega de borde a borde y SU BARRA DE DESPLAZAMIENTO CAE
     PEGADA AL BORDE DERECHO de la ventana, no en medio del contenido. Las dos
     medidas salen de las mismas variables, así que no pueden descuadrarse. */
.ga-main--eventos .ga-eventos-modal__caja {
    --ga-ev-modal-aire-v: clamp(var(--ga-space-md), 4vw, var(--ga-space-lg));
    --ga-ev-modal-aire-h: clamp(var(--ga-space-md), 4vw, var(--ga-space-lg));

    position: relative;            /* por encima del velo, sin z-index inventado */
    box-sizing: border-box;
    width: min(100%, 46rem);
    max-height: calc(100vh  - 2 * clamp(var(--ga-space-sm), 4vw, var(--ga-space-lg)));
    max-height: calc(100dvh - 2 * clamp(var(--ga-space-sm), 4vw, var(--ga-space-lg)));
    display: flex;
    flex-direction: column;
    overflow: clip;
    padding: var(--ga-ev-modal-aire-v) 0;
    background-color: var(--ga-naranja-claro);
    border: 2px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-md);
    box-shadow: var(--ga-shadow-lg);
}

/* Respaldo para navegadores sin `overflow: clip` (los mismos que ya contempla
   la tienda): vuelven al hidden de siempre. Recortan igual; lo único que
   pierden es la mejora del gesto. */
@supports not (overflow: clip) {

    .ga-main--eventos .ga-eventos-modal__caja {
        overflow: hidden;
    }
}

/* EL CUERPO ES EL ÚNICO CONTENEDOR DE SCROLL DEL DIÁLOGO. Ni html, ni body, ni
   la caja.
   🔴 min-height: 0 es IMPRESCINDIBLE: un hijo de flex arranca con min-height
      auto, que le impide encogerse por debajo de su contenido; sin esto la caja
      crecería hasta desbordar y el overflow-y no llegaría a activarse nunca.
      (Es min-HEIGHT, no min-width: aquí es la pieza que hace funcionar el
      scroll interno.)
   El titular queda fuera de este envoltorio a propósito, así que se queda
   arriba con la equis mientras el resto se desliza por debajo.

   ——— LA BARRA, VISIBLE Y EN EL LATERAL ———
   El cuerpo llega de borde a borde de la caja, así que la barra se dibuja
   pegada al borde derecho de la ventana; el padding lateral de aquí abajo es lo
   que separa el contenido de la barra, para que no vayan pisándose.
   scrollbar-gutter: stable reserva ese carril desde el principio: la barra
   aparece y desaparece sin que el texto dé un salto lateral.
   Se estiliza por partida doble —el estándar (scrollbar-width/color) y el de
   WebKit— porque ningún navegador entiende las dos. Pulgar en el dorado de
   marca sobre carril transparente: se ve, y no chilla.
   ⚠ En iOS la barra es un indicador que solo asoma mientras se arrastra; eso lo
     decide el sistema y no se puede forzar desde CSS. Ahora, al menos, asoma
     donde debe: en el lateral. */
.ga-main--eventos .ga-eventos-modal__cuerpo {
    flex: 1 1 auto;
    min-height: 0;
    padding-inline: var(--ga-ev-modal-aire-h);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;   /* inercia en móvil, arriba y abajo */
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: var(--ga-naranja-apagado) transparent;
}

.ga-main--eventos .ga-eventos-modal__cuerpo::-webkit-scrollbar {
    width: 8px;
}

.ga-main--eventos .ga-eventos-modal__cuerpo::-webkit-scrollbar-track {
    background: transparent;
}

.ga-main--eventos .ga-eventos-modal__cuerpo::-webkit-scrollbar-thumb {
    background-color: var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-full);
}

/* ——— EL TEXTAREA NO SE QUEDA CON EL GESTO ———
   Un <textarea> es un contenedor de scroll de fábrica, así que al empezar el
   arrastre encima de él el gesto era suyo aunque no tuviera nada que desplazar.
     · overflow-y: auto → solo se desplaza por dentro SI su contenido lo
       desborda; con el campo vacío o con poco texto, no.
     · touch-action: pan-y → el arrastre vertical es válido y, cuando el propio
       campo no puede moverse, pasa al contenedor de scroll de arriba, que es el
       cuerpo del diálogo. Sin esto el dedo se quedaba muerto sobre el campo.
   Se declara AQUÍ y acotado al diálogo, para no tocar el bloque de estilos
   heredado de la plantilla. Los demás campos del formulario no son contenedores
   de scroll, así que no necesitan nada. */
.ga-main--eventos .ga-eventos-modal .ga-ev-form__textarea {
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    touch-action: pan-y;
}

/* La equis, arriba a la derecha. Solo cambia de color al interactuar. */
.ga-main--eventos .ga-eventos-modal__cerrar {
    position: absolute;
    top: var(--ga-space-sm);
    right: var(--ga-space-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2.5rem;
    height: 2.5rem;
    padding: 0;
    border: none;
    border-radius: var(--ga-radius-full);
    cursor: pointer;
    transition: color var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-modal__cerrar,
.ga-main--eventos .ga-eventos-modal__cerrar:hover,
.ga-main--eventos .ga-eventos-modal__cerrar:focus,
.ga-main--eventos .ga-eventos-modal__cerrar:active {
    background: none !important;
    border: none !important;
    color: var(--ga-verde-oliva-oscuro) !important;
}

.ga-main--eventos .ga-eventos-modal__cerrar:hover,
.ga-main--eventos .ga-eventos-modal__cerrar:focus-visible {
    color: var(--ga-naranja-apagado) !important;
}

.ga-main--eventos .ga-eventos-modal__cerrar:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

.ga-main--eventos .ga-eventos-modal__titulo {
    /* El aire lateral lo pone ahora el titular, no la caja (ver la nota de la
       caja): es la MISMA variable que usa el cuerpo, así que el titular y el
       contenido siguen alineados exactamente igual que antes. */
    padding-inline: var(--ga-ev-modal-aire-h);
    margin: 0 var(--ga-space-lg) var(--ga-space-md) 0;   /* hueco para la equis */
    font-family: var(--ga-font-display);
    font-size: clamp(1.6rem, 3vw, 2.2rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    color: var(--ga-verde-oliva-oscuro);
    text-wrap: balance;
}

/* ——— CONTACTO DIRECTO ———
   DOS COLUMNAS del mismo ancho con una raya divisoria entre ellas, el mismo
   tratamiento que la sección "¿Sigues teniendo alguna duda?": la raya es el
   borde izquierdo del SEGUNDO bloque, así que al ser las columnas iguales cae
   justo en el centro y no ocupa ninguna pista de la rejilla.

   Las DOS FILAS —texto arriba, dato debajo— las declara este contenedor y cada
   bloque se acopla a ellas con subgrid. Es lo que garantiza que los dos textos
   de arriba queden a la misma altura y los dos datos también, aunque uno de los
   textos envuelva a dos líneas y el otro no.

   El aire se ha recortado respecto a la versión apilada (era 24px hasta la raya
   y 40px de la raya al formulario): al ganar alto con las dos columnas, ahora se
   ve más formulario sin desplazarse. */
.ga-main--eventos .ga-eventos-modal__directo {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    grid-template-rows: auto auto;
    row-gap: 0.35rem;
    margin-bottom: var(--ga-space-md);
    padding-bottom: var(--ga-space-sm);
    border-bottom: 1px solid var(--ga-amarillo-pastel);
}

/* Solo padding HORIZONTAL: en un subgrid, un padding vertical desplazaría las
   filas respecto a las del contenedor. El de los lados no afecta al eje de las
   filas, así que la alineación entre columnas queda intacta. */
.ga-main--eventos .ga-eventos-modal__bloque {
    display: grid;
    grid-row: span 2;
    grid-template-rows: subgrid;
    justify-items: center;
    padding-inline: var(--ga-space-sm);
    text-align: center;
}

.ga-main--eventos .ga-eventos-modal__bloque + .ga-eventos-modal__bloque {
    border-left: 1px solid var(--ga-naranja-apagado);
}

.ga-main--eventos .ga-eventos-modal__linea {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.78;
}

.ga-main--eventos .ga-eventos-modal__contacto {
    display: inline-flex;
    align-items: center;
    align-self: center;
    gap: var(--ga-space-xs);
    font-family: var(--ga-font-body);
    font-size: clamp(1.05rem, 1.6vw, 1.25rem);
    font-weight: var(--ga-weight-medium);
    text-decoration: none;
    transition: color var(--ga-transition-normal);
}

.ga-main--eventos .ga-eventos-modal__contacto,
.ga-main--eventos .ga-eventos-modal__contacto:hover,
.ga-main--eventos .ga-eventos-modal__contacto:focus,
.ga-main--eventos .ga-eventos-modal__contacto:focus-visible {
    color: var(--ga-verde-oliva-oscuro) !important;
}

.ga-main--eventos .ga-eventos-modal__contacto:hover,
.ga-main--eventos .ga-eventos-modal__contacto:focus-visible {
    color: var(--ga-naranja-apagado) !important;
}

.ga-main--eventos .ga-eventos-modal__ico {
    display: flex;
    color: var(--ga-verde-montanas);
}

/* El envoltorio del formulario traía su propio panel crema con filete y esquinas
   redondeadas, pensado para cuando vivía suelto en la página. Dentro del diálogo
   —que ya es un panel crema con filete— quedaba una caja dentro de otra, así que
   aquí se le retira ese marco. Es una regla NUEVA y acotada al diálogo: la del
   <style> en línea del formulario no se toca, y el formulario conserva sus
   campos, sus textos y su funcionamiento. */
.ga-main--eventos .ga-eventos-modal .ga-ev-form-wrap {
    max-width: none;
    padding: 0;
    background: none;
    border: none;
    border-radius: 0;
}

/* ——— BOTÓN "ENVIAR CORREO" DEL FORMULARIO ———
   El botón hereda de las clases globales .ga-btn / .ga-btn--primary, que no se
   pueden tocar. Aquí se corrigen tres cosas SOLO para este botón, con un
   selector de cuatro clases que gana por especificidad sin necesitar !important.
   Ni el tamaño, ni la tipografía, ni el padding, ni la posición cambian.

   1 · ESQUINAS. .ga-btn nace con border-radius: 0 ("estilo recto" por decisión
       de diseño global). Aquí se redondea con --ga-radius-md, el radio de marca
       más cercano a los 10px pedidos: en la paleta no hay ninguno de ese valor.

   2 · CENTRADO — LA CAUSA REAL. .ga-btn es inline-flex y NO declara
       justify-content, así que su contenido se empaqueta al principio. Como el
       botón lleva un ancho mínimo de 220px escrito en su atributo style y el
       texto es más corto, sobraba sitio y la palabra se quedaba pegada a la
       izquierda. Se arregla con justify-content: center.
       El letter-spacing también influye, pero mucho menos: 0.08em se añade
       DESPUÉS de la última letra, así que los glifos quedan medio espacio a la
       izquierda del centro. Se compensa con un text-indent de la MITAD de ese
       valor, sin quitar el espaciado: el botón conserva el mismo aspecto que los
       demás de la página.
       En vertical ya estaba centrado (align-items: center y padding simétrico). */
.ga-main--eventos .ga-eventos-modal .ga-ev-form__footer .ga-btn {
    justify-content: center;
    text-indent: 0.04em;
    border-radius: var(--ga-radius-md);
}

/* 3 · HOVER. La regla global lo lleva a --ga-marron-oscuro, un marrón que no
   pega con el resto de la página. Aquí pasa al verde oliva de marca, el mismo
   al que van los demás botones de Eventos. El texto sigue blanco: 9,1:1 sobre
   ese verde, de sobra para leerse. Solo cambian los colores. */
.ga-main--eventos .ga-eventos-modal .ga-ev-form__footer .ga-btn:hover,
.ga-main--eventos .ga-eventos-modal .ga-ev-form__footer .ga-btn:focus-visible {
    background-color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
}


/* ——— CASILLA DE CONSENTIMIENTO ———
   El <input> real se colapsa (no se oculta con display:none, que lo sacaría del
   tabulador) y el cuadro visible es el <span> hermano. Así Astra no puede
   repintarlo, que es la trampa documentada en Contacto. */
.ga-main--eventos .ga-eventos-check {
    display: flex;
    align-items: flex-start;
    gap: var(--ga-space-xs);
    cursor: pointer;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
}

.ga-main--eventos .ga-eventos-check__input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.ga-main--eventos .ga-eventos-check__box {
    box-sizing: border-box;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 1.15rem;
    height: 1.15rem;
    margin-top: 0.15rem;
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-naranja-apagado);
    border-radius: var(--ga-radius-sm);
    color: transparent;            /* el tick, invisible hasta marcarla */
    transition: color var(--ga-transition-normal),
                background-color var(--ga-transition-normal);
}

/* Marcada: aparece el tick. Ni tamaño ni borde cambian. */
.ga-main--eventos .ga-eventos-check__input:checked ~ .ga-eventos-check__box {
    color: var(--ga-verde-oliva-oscuro);
}

/* Foco de teclado sobre el cuadro, ya que el input real está colapsado. */
.ga-main--eventos .ga-eventos-check__input:focus-visible ~ .ga-eventos-check__box {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* Sin marcar al intentar enviar: el filete se pone en el rojo de aviso que ya
   usa el formulario para sus campos con error. */
.ga-main--eventos .ga-eventos-check.has-error .ga-eventos-check__box {
    border-color: #c05050;
}

.ga-main--eventos .ga-eventos-check__txt a {
    color: var(--ga-verde-montanas);
    text-decoration: underline;
}


/* ——— MÓVIL Y PANTALLAS BAJAS (<=768px) ———
   La caja ocupa casi todo el viewport y se desplaza por dentro. A 360px: el
   diálogo es position:fixed, así que no añade ancho al documento y no puede
   provocar desbordamiento horizontal ni con la ventana abierta. */
@media (max-width: 768px) {

    .ga-main--eventos .ga-eventos-modal {
        padding: var(--ga-space-sm);
    }

    /* Mismo tope que en la regla base, con el aire de móvil (1rem por lado, el
       padding del velo de aquí arriba) y con el mismo respaldo en vh para los
       navegadores sin dvh.
       El relleno NO se redeclara: basta con redefinir las dos variables de aire,
       porque de ellas cuelgan el padding de la caja y el lateral del titular y
       del cuerpo. Una sola línea por medida y no pueden descuadrarse. */
    .ga-main--eventos .ga-eventos-modal__caja {
        --ga-ev-modal-aire-v: var(--ga-space-md);
        --ga-ev-modal-aire-h: var(--ga-space-sm);

        max-height: calc(100vh  - 2 * var(--ga-space-sm));
        max-height: calc(100dvh - 2 * var(--ga-space-sm));
    }

    /* Apilados, como estaban: se suelta el subgrid —con una sola columna las dos
       filas compartidas ya no tienen sentido— y la raya pasa de vertical a
       horizontal entre los dos bloques. */
    .ga-main--eventos .ga-eventos-modal__directo {
        grid-template-columns: minmax(0, 1fr);
        grid-template-rows: none;
        row-gap: var(--ga-space-sm);
    }

    .ga-main--eventos .ga-eventos-modal__bloque {
        display: flex;
        flex-direction: column;
        align-items: center;
        gap: 0.35rem;
        grid-row: auto;
        padding-inline: 0;
    }

    .ga-main--eventos .ga-eventos-modal__bloque + .ga-eventos-modal__bloque {
        border-left: none;
        border-top: 1px solid var(--ga-naranja-apagado);
        padding-top: var(--ga-space-sm);
    }
}


/* ——— MÓVIL (<=768px) ———
   Una sola columna: foto arriba y texto debajo, que es el orden del HTML —no
   hace falta reordenar nada—. El texto se centra, como el resto de la página.
   A 360px: el marco se queda en el 100% de los 312px útiles y ningún elemento
   impone un ancho mínimo mayor, así que no hay desbordamiento horizontal. */
@media (max-width: 768px) {

    .ga-main--eventos .ga-eventos-mermelada__marco {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--ga-space-lg);
    }

    .ga-main--eventos .ga-eventos-mermelada__contenido {
        text-align: center;
    }

    .ga-main--eventos .ga-eventos-mermelada__desc {
        margin-inline: auto;
    }

    .ga-main--eventos .ga-eventos-mermelada__frame {
        width: min(100%, 17rem);
    }
}


/* =============================================================================
   EVENTOS — CAMPOS DE PERSONALIZACIÓN DE ETIQUETA (ficha de producto)
   =============================================================================
   Los pinta inc/eventos-personalizacion.php justo encima del botón de añadir al
   carrito, y SOLO en los productos de la categoría Eventos.

   ⚠ ESTOS SELECTORES NO VAN ACOTADOS CON .ga-main--eventos, y es a propósito:
   estos campos no viven en la página de Eventos, sino en la FICHA de cada
   producto, que no tiene esa clase raíz. La acotación la da el prefijo propio
   .ga-eventos-perso-, que no existe en ninguna otra parte del sitio.
   ============================================================================= */

/* SIN RECUADRO: ni borde, ni fondo, ni relleno. El bloque se leía como una caja
   pegada encima del botón de comprar; suelto, la personalización se integra en
   la columna y sus campos quedan alineados con el resto de la ficha. Lo único
   que queda es la separación con lo que viene debajo.
   Los campos de dentro conservan su aspecto: cada uno trae su propio borde. */
.ga-eventos-perso {
    margin-bottom: var(--ga-space-md);
}

.ga-eventos-perso__titulo {
    margin: 0 0 var(--ga-space-sm);
    font-family: var(--ga-font-display);
    font-size: clamp(1.15rem, 1.6vw, 1.4rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 1;
}

.ga-eventos-perso__campo {
    margin-bottom: var(--ga-space-sm);
}

.ga-eventos-perso__campo:last-child {
    margin-bottom: 0;
}

.ga-eventos-perso__label {
    display: block;
    margin-bottom: 0.35rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    color: var(--ga-verde-oliva-oscuro);
}

.ga-eventos-perso__req {
    color: var(--ga-naranja-apagado);
}


/* ——— TIPO DE ETIQUETA: TARJETAS EN VEZ DE DESPLEGABLE ———
   Las cinco opciones son radios del MISMO grupo, así que la exclusividad y el
   valor que se envía los sigue resolviendo el navegador: aquí solo se dibujan.

   El contenedor es un <div role="radiogroup">, no un <fieldset>: el fieldset
   trae un min-inline-size: min-content implícito que hace de suelo de ancho y
   puede desbordar en pantallas estrechas.

   Parrilla 2×2. grid-auto-rows: 1fr iguala el alto de las cuatro tarjetas, así
   que un nombre más largo no descoloca a las de al lado. minmax(0, 1fr) corta el
   ancho mínimo del contenido sin recurrir a min-width. */
.ga-eventos-perso__opciones {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    grid-auto-rows: 1fr;
    gap: 0.6rem;
}

/* margin: 0 explícito porque Astra le pone margen inferior a los <label>, y aquí
   el espacio entre tarjetas lo pone el gap de la parrilla. */
.ga-eventos-perso__opcion {
    position: relative;
    display: block;
    margin: 0;
    cursor: pointer;
}

/* Las latas no llevan serigrafía, así que ahí las tarjetas son TRES y la última
   se quedaría sola a media fila. Cuando es la tercera Y la última, ocupa la fila
   entera y la parrilla vuelve a leerse bien. Con cuatro tarjetas esta regla no
   se cumple y no hace nada. */
.ga-eventos-perso__opcion:nth-child(3):last-child {
    grid-column: 1 / -1;
}

/* El input REAL: invisible, pero PRESENTE. Sin display:none ni
   visibility:hidden, así sigue en el árbol de accesibilidad, sigue siendo
   enfocable con el teclado y su required sigue siendo válido. Es el mismo patrón
   ya probado en la casilla RGPD de Contacto y en el formulario de opiniones:
   la caja visible es un <span> hermano, donde ninguna regla de Astra sobre
   input[type="radio"] puede llegar.

   🔴 1px Y COLOCADO DENTRO DE LA TARJETA, no 0×0 en una esquina: el radio es
   required, y cuando ninguno está marcado el navegador tiene que poder ENFOCARLO
   para enseñar su globo de aviso. Un control obligatorio al que no se puede
   enfocar bloquea el envío sin decir nada —la misma trampa documentada en el
   campo condicional de Contacto—. Con 1px sigue siendo un elemento pintado y
   enfocable, y el globo sale pegado a la tarjeta que hay que elegir. */
.ga-eventos-perso__radio {
    position: absolute;
    top: 0.7rem;
    left: 0.8rem;
    width: 1px;
    height: 1px;
    margin: 0;
    opacity: 0;
}

/* El borde de 1px existe ya en reposo y la marca de seleccionado se refuerza con
   una sombra INTERIOR, que no ocupa sitio: ningún estado cambia el tamaño ni
   mueve a las tarjetas vecinas. */
.ga-eventos-perso__opcion-caja {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    box-sizing: border-box;
    height: 100%;
    padding: 0.7rem 0.8rem;
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-amarillo-pastel);
    /* 10px, el radio del resto del sitio. Este bloque entero venía con
       --ga-radius-sm (4px), que se quedaba corto al lado de tarjetas de este tamaño.
       Va literal y no en variable porque no hay ninguna de 10px declarada: --ga-radius-sm
       son 4 y --ga-radius-md, 8. Es el mismo número que usan el botón del carrito
       lateral y el del checkout. */
    border-radius: 10px;
    transition: border-color var(--ga-transition-normal),
                background-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

.ga-eventos-perso__opcion:hover .ga-eventos-perso__opcion-caja {
    border-color: var(--ga-naranja-apagado);
}

.ga-eventos-perso__radio:checked ~ .ga-eventos-perso__opcion-caja {
    background-color: var(--ga-naranja-claro);
    border-color: var(--ga-naranja-apagado);
    box-shadow: inset 0 0 0 1px var(--ga-naranja-apagado);
}

.ga-eventos-perso__radio:focus-visible ~ .ga-eventos-perso__opcion-caja {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

.ga-eventos-perso__opcion-nombre {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;
    color: var(--ga-verde-oliva-oscuro);
    overflow-wrap: break-word;
}

.ga-eventos-perso__opcion-nota {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.4;
    color: var(--ga-verde-montanas);
    overflow-wrap: break-word;
}

/* LA QUINTA OPCIÓN — "¿Ya tienes tu diseño?".
   No es una casilla aparte que haya que sincronizar: es un radio más del mismo
   grupo, solo que a lo ancho y debajo de la parrilla. Su texto vive en el bloque
   de configuración de inc/eventos-personalizacion.php. */
.ga-eventos-perso__opcion--propio {
    margin-top: 0.6rem;
}

/* EN COLUMNA A TODOS LOS ANCHOS. Su texto de ayuda es una frase larga —"Te lo
   pediremos al preparar tu pedido · Sin coste añadido"—, y puesta en la misma
   línea que el título se descolgaba contra el borde derecho o partía de forma
   fea. Apilada se lee como lo que es: la pregunta y su explicación.
   Va con más especificidad que la regla de móvil, así que gana en los dos. */
.ga-eventos-perso__opcion--propio .ga-eventos-perso__opcion-caja {
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    gap: 0.2rem;
    /* Borde discontinuo: se distingue de las cuatro de arriba sin cambiar de
       grosor, así que al seleccionarla no se mueve nada de sitio. */
    border-style: dashed;
}

/* 🔴 AL SELECCIONARLA, EL TRAZO SIGUE SIENDO DISCONTINUO.
   La regla general de "marcada" refuerza el borde con
   `box-shadow: inset 0 0 0 1px`, que en las cuatro tarjetas de arriba se lee
   como un borde más grueso pero AQUÍ dibujaba una línea CONTINUA por dentro de
   las rayitas: parecía que al elegirla le apareciera un recuadro sólido nuevo.
   Se le quita esa sombra y se deja lo único que tiene que cambiar: el color del
   borde, que ya pasa a dorado por la regla general.

   El border-style se repite a propósito, aunque la regla de marcada no lo toque:
   así queda escrito que el trazo es el mismo en reposo y seleccionada, y no se
   pierde si alguien edita la de arriba.

   Va con 0-3-0 y solo sobre .ga-eventos-perso__opcion--propio, así que las otras
   cuatro tarjetas conservan su sombra interior tal cual. */
.ga-eventos-perso__opcion--propio .ga-eventos-perso__radio:checked ~ .ga-eventos-perso__opcion-caja {
    box-shadow: none;
    border-style: dashed;
}

/* Los tres tipos de control comparten caja. 16px fijos a propósito: por debajo,
   iOS hace zoom al escribir (mismo criterio que el formulario de Contacto).
   El borde de 1px existe ya en reposo y solo cambia de color al enfocar, así que
   ningún estado altera el tamaño ni empuja lo de al lado. */
.ga-eventos-perso__input,
.ga-eventos-perso__select,
.ga-eventos-perso__textarea {
    box-sizing: border-box;
    width: 100%;
    padding: 0.75rem 0.9rem;
    font-family: var(--ga-font-body);
    font-size: 16px;
    line-height: 1.4;
    color: var(--ga-verde-oliva-oscuro);
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-amarillo-pastel);
    /* Los tres controles del formulario —texto de la etiqueta, las dos fechas, las
       notas, la variedad y el campo de unidades— a los mismos 10px que las tarjetas de
       tipo de etiqueta. Es una sola regla porque los tres ya compartían selector: al
       cambiar aquí el radio, el formulario entero queda uniforme de una vez. */
    border-radius: 10px;
    transition: border-color var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);
}

.ga-eventos-perso__textarea {
    resize: vertical;
    line-height: 1.6;
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL RADIO DEL CAMPO DE TEXTO Y DEL ÁREA DE NOTAS — GANÁNDOLE A QUIEN LO PISA
   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ ESTOS DOS SE QUEDARON CUADRADOS Y LOS DEMÁS NO. La regla de aquí arriba
   pone 10px a los tres controles a la vez, y en las fechas, el número de unidades y
   los desplegables funcionó. Solo fallaron el "Texto de la etiqueta" y las "Notas".

   Lo que tienen en común esos dos, y ningún otro, es el TIPO de control:

       Texto de la etiqueta  → <input type="text">   ✗ se quedó recto
       Notas                 → <textarea>            ✗ se quedó recto
       Las dos fechas        → <input type="date">   ✓
       Unidades              → <input type="number"> ✓
       Cristal y variedad    → <select>              ✓

   Esa correlación no es casualidad: `input[type="text"], textarea` es exactamente el
   par de selectores con el que los temas —Astra, aquí— estilizan los formularios. Su
   CSS se imprime en el <head> DESPUÉS de las hojas del tema hijo, así que a igualdad
   de peso gana él, y por eso la regla de arriba se aplicaba a todo menos justo a esos
   dos. Se descartaron single-product.css y woocommerce.css: sus border-radius: 0 son
   de otros elementos.

   👉 SE LE GANA POR LAS DOS VÍAS A LA VEZ, porque una sola no basta contra algo que se
      carga después: se nombra el elemento y su tipo —lo que sube la especificidad por
      encima de la suya— y se marca con !important. Es el mismo recurso que hizo falta
      con el botón de pagar del carrito lateral.

   ⚠ ACOTADO A LAS FICHAS DE EVENTOS con .ga-product-single--eventos, que es la clase
     que la plantilla pone al <main> solo cuando el producto es de eventos. Las fichas
     normales y el checkout no pueden verse alcanzados.

   ⚠ SOLO EL RADIO. Ni el borde, ni el color, ni el relleno, ni el tamaño se declaran
     aquí: siguen saliendo de la regla de arriba. */
.ga-product-single--eventos input.ga-eventos-perso__input[type="text"],
.ga-product-single--eventos textarea.ga-eventos-perso__textarea {
    border-radius: 10px !important;
}

.ga-eventos-perso__input:focus,
.ga-eventos-perso__select:focus,
.ga-eventos-perso__textarea:focus {
    outline: none;
    border-color: var(--ga-naranja-apagado);
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.2);
}

.ga-eventos-perso__ayuda {
    display: block;
    margin-top: 0.3rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.5;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.7;
}

/* La ayuda que va bajo un control CENTRADO —hoy solo el aviso del pedido mínimo,
   debajo del selector de unidades— se centra con él.

   🔴 UN MODIFICADOR, NO LA CLASE BASE. .ga-eventos-perso__ayuda la comparte con
   la ayuda de "Notas", que va alineada a la izquierda como todo el formulario:
   centrar la clase base movería aquella de paso.

   Solo text-align: el span sigue siendo un bloque a todo el ancho de la columna,
   así que centra sobre el MISMO eje que el justify-content del selector de
   arriba y los dos quedan alineados entre sí. Sin anchos, sin márgenes y sin
   nada que pueda desbordar: el texto parte de línea si no cabe. */
.ga-eventos-perso__ayuda--centrada {
    text-align: center;
}


/* ——— NÚMERO DE UNIDADES ———
   Un campo ESCRIBIBLE con el mismo aspecto que el resto —comparte la clase
   .ga-eventos-perso__input, así que hereda borde, tipografía y foco; el alto sí
   se sobrescribe aquí abajo, porque este recuadro es más grande a propósito—,
   con dos botones a los lados para ajustar de uno en uno.

   No usa las clases .ga-qty-* de la ficha estándar: aquellas dibujan una caja
   estrecha y viven en single-product.css, que es de toda la tienda.

   ANCHOS FIJOS, NO 1fr: con el campo en 1fr se comía todo el ancho de la columna
   y el conjunto quedaba larguísimo para dos cifras. Ahora las tres pistas miden
   lo que tienen que medir y el justify-content: start deja el sobrante a la
   derecha en vez de estirar nada.

   El recuadro del número va en 8rem (128px): el término medio entre el 1fr de la
   primera versión, que lo estiraba a más de 350px, y los 5,5rem de la segunda,
   que se quedaban cortos. Los botones suben a 4rem para no descompensarse con él.

   El total son 16rem de pistas + 1rem de huecos = 17rem (272px), así que a 360px
   —donde la columna deja unos 328px— sobran 56px y no hay desbordamiento
   horizontal. Al ser rem y no porcentajes, mide igual en escritorio, tablet y
   móvil: no hace falta ajustarlo por breakpoint.

   🔴 CENTRADO CON justify-content, NO CON MÁRGENES NI CON ANCHOS. Las tres pistas
   suman menos que el ancho de la columna, y justify-content reparte ESE SOBRANTE:
   con 'start' se iba todo a la derecha y el conjunto quedaba pegado al margen
   izquierdo; con 'center' se parte en dos y el bloque queda a media columna. Las
   pistas siguen midiendo exactamente lo mismo —no se estira ni se encoge nada—,
   así que el campo conserva sus 8rem y los botones sus 4rem.

   Y por eso mismo no puede desbordar a 360px: centrar reparte un sobrante que ya
   existía. Si algún día las pistas llegaran a medir MÁS que la columna, el
   sobrante sería negativo y 'center' lo repartiría a los dos lados, sacando el
   bloque también por la izquierda; con 17rem contra los ~328px de la columna eso
   queda muy lejos, pero es la razón de no subir el ancho de las pistas sin
   recalcular esta cuenta.

   ——— EL AIRE DE ARRIBA VA AQUÍ, NO EN LA ETIQUETA ———
   El título "Número de unidades" pedía un poco más de separación con el selector.
   Se le da desde ESTE lado y no tocando .ga-eventos-perso__label, que es la clase
   de TODAS las etiquetas del formulario: ahí movería la separación de los ocho
   campos, y el encargo era solo este.

   ⚠ EL HUECO RESULTANTE ES 0,7rem, NO 1,05rem. Este margin-top y el
   margin-bottom: 0.35rem de la etiqueta son márgenes de dos hermanos en flujo
   normal, así que COLAPSAN: mandan el mayor de los dos, no la suma. Subir de los
   0,35rem de antes a 0,7rem es exactamente el pelín que se pedía; para cambiarlo
   basta con mover este número, mientras siga por encima de 0,35rem. */
.ga-eventos-perso__unidades {
    display: grid;
    grid-template-columns: 4rem 8rem 4rem;
    justify-content: center;
    align-items: stretch;
    gap: 0.5rem;
    margin-top: 0.7rem;
}

/* Centrado porque es un número entre dos botones, y sin las flechitas nativas:
   para eso están los botones, y así el campo queda limpio y ancho.

   El width va aquí, con el contenedor delante (0-2-0), y no solo en
   .ga-eventos-perso__input (0-1-0): el campo conserva la clase `qty` por
   convención de WooCommerce, y un selector como `input.qty { width: 80px }`
   —que gastan Astra y WooCommerce— puntúa 0-1-1 y le ganaría, dejando el campo
   estrecho justo después de haberlo ensanchado. */
.ga-eventos-perso__unidades .ga-eventos-perso__unidades-campo {
    width: 100%;
    /* MÁS ALTO que el resto de campos del formulario, a propósito: aquí solo hay
       una cifra y el recuadro tiene que pedir que la escribas.

       El relleno vertical es SIMÉTRICO, y es lo que centra la cifra en vertical:
       un input de una sola línea centra su texto dentro de la caja de contenido,
       así que con el mismo hueco arriba y abajo queda a media altura del
       recuadro. Nada de height fijo, que con line-height se comporta distinto
       según el navegador. En horizontal la centra el text-align.

       1rem arriba y abajo dejan el campo en unos 56px de alto, y los botones se
       estiran a esa misma medida con el align-items: stretch de la rejilla. */
    padding-block: 1rem;
    padding-inline: 0.6rem;
    text-align: center;
    -moz-appearance: textfield;
    appearance: textfield;
}

.ga-eventos-perso__unidades-campo::-webkit-outer-spin-button,
.ga-eventos-perso__unidades-campo::-webkit-inner-spin-button {
    -webkit-appearance: none;
    appearance: none;
    margin: 0;
}

/* 🔴 !important en fondo, color y borde: en una página de WooCommerce, Astra
   captura los <button> con reglas como `.woocommerce button:hover`, que ganan en
   especificidad a cualquier clase propia (🪤 nº 6).

   Los botones se estiran al alto del campo con el align-items: stretch de la
   rejilla, así que no hay ninguna altura escrita a mano que pueda descuadrarse
   si cambia el padding del campo. Ningún estado cambia tamaño ni posición: solo
   el color y el color del borde, con el grosor siempre igual. */
.ga-eventos-perso__paso {
    display: flex;
    align-items: center;
    justify-content: center;
    box-sizing: border-box;
    /* Llena su pista de la rejilla: el ancho se decide en un solo sitio, en el
       grid-template-columns de arriba, y no hay dos medidas que descuadrar. */
    width: 100%;
    padding: 0;
    font-family: var(--ga-font-body);
    /* El signo crece con el botón. Cambiar el tamaño de letra no mueve nada: el
       ancho lo fija la pista de la rejilla y el alto se estira al del campo. */
    font-size: var(--ga-text-xl);
    font-weight: var(--ga-weight-medium);
    line-height: 1;
    color: var(--ga-verde-oliva-oscuro) !important;
    background-color: var(--ga-blanco) !important;
    border: 1px solid var(--ga-amarillo-pastel) !important;
    /* Los botones − y + del número de unidades, al mismo radio que el campo que tienen
       al lado: si el recuadro de la cifra va a 10px y ellos se quedan en 4, la fila se
       lee como piezas de dos juegos distintos. */
    border-radius: 10px;
    cursor: pointer;
    transition: color var(--ga-transition-normal),
                border-color var(--ga-transition-normal);
}

.ga-eventos-perso__paso:hover,
.ga-eventos-perso__paso:focus,
.ga-eventos-perso__paso:active {
    color: var(--ga-naranja-apagado) !important;
    background-color: var(--ga-blanco) !important;
    border-color: var(--ga-naranja-apagado) !important;
}

/* El contorno no ocupa sitio, así que tampoco mueve nada. */
.ga-eventos-perso__paso:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* Astra contornea los botones al pulsarlos con el ratón; el foco de teclado ya
   lo pinta la regla de arriba. */
.ga-eventos-perso__paso:focus:not(:focus-visible) {
    outline: none;
}


/* ——— MÓVIL (<=600px) ———
   A 360px: el bloque ocupa el ancho de su columna sin relleno propio (los
   controles van al 100% y con box-sizing: border-box) y ningún elemento impone
   un ancho mínimo. Sin desbordamiento horizontal. */
@media (max-width: 600px) {

    /* Las tarjetas pasan a una sola columna: a dos, los nombres largos
       ("Etiqueta con foto y nombres") se partían en cuatro o cinco líneas y el
       bloque entero crecía. En columna cada nombre respira.

       🔴 grid-auto-rows: 1fr, QUE ES LO QUE LAS IGUALA. Aquí estuvo un tiempo en
       `auto`, y con `auto` cada fila mide lo que pide su contenido: la de "Etiqueta
       con foto y nombres" —que lleva la nota más larga— salía bastante más alta que
       las otras tres y la columna quedaba a saltos. Con 1fr todas las filas miden
       lo mismo: lo que mida la más alta. No hace falta escribir ninguna altura ni
       medir nada, y si mañana se añade una opción o se alarga un texto se
       reequilibran solas.

       La quinta opción ("¿Ya tienes tu diseño?") no entra en esta cuenta: se pinta
       aparte, fuera de esta parrilla, y conserva su alto propio. */
    .ga-eventos-perso__opciones {
        grid-template-columns: minmax(0, 1fr);
        grid-auto-rows: 1fr;
    }

    /* En una sola columna la tarjeta es una fila: nombre a la izquierda y el
       suplemento a la derecha, como la quinta opción. */
    /* 🔴 align-content: center ES LO QUE CENTRA EL TEXTO EN VERTICAL, y no
       align-items. Con el grid-auto-rows: 1fr de aquí arriba todas las tarjetas
       miden lo que la más alta, así que a las de texto corto les sobra alto por
       dentro. En un flex que ENVUELVE, ese sobrante lo reparte align-content, que
       coloca el bloque de líneas dentro del contenedor; align-items solo alinea los
       elementos DENTRO de su línea, y por eso el texto se quedaba arriba. Con
       `center` queda el mismo aire por encima que por debajo, tanto si el nombre
       ocupa una línea como si envuelve en dos.

       align-items: baseline se queda: es el que alinea el nombre con su nota
       cuando van uno al lado del otro en la misma línea. Los dos hacen cosas
       distintas y se necesitan los dos. */
    .ga-eventos-perso__opcion-caja {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: baseline;
        align-content: center;
        justify-content: space-between;
        gap: 0.2rem 0.6rem;
    }
}


/* =============================================================================
   EVENTOS — ARRANQUE DE LA FICHA SIN MIGAS (ficha de producto)
   =============================================================================
   Las MIGAS (la barra verde) ya no se pintan: se quitan en PHP dentro de
   page-templates/single-product-custom.php, condicionadas con $ga_es_eventos
   —que sale de ga_eventos_es_personalizable()—. Aquí solo queda cerrar el hueco
   que dejaban.

   ⚠ SOBRE LA "FRANJA BLANCA" QUE HAY ENCIMA DE LAS MIGAS: no es un elemento.
   Es el hueco que reserva `body { padding-top: var(--ga-nav-height) }` (bloque
   05. NAVBAR) para que el contenido no quede debajo de la cabecera, que es
   position: fixed. Ese hueco deja ver el fondo blanco del body y, como la
   cabecera también es blanca, se lee como una franja. Quitarlo metería la foto
   y el bloque de compra DEBAJO de la cabecera, que es opaca: el contenido se
   perdería, no subiría. Lo que sí se puede quitar —y es lo que se quita aquí—
   es todo el blanco que la ficha AÑADÍA por encima de ese hueco: las migas y el
   padding superior de la sección. Así el contenido arranca pegado al borde de
   la cabecera, sin ningún hueco vacío donde estaban las migas.

   Tampoco se sube la ficha con un margen negativo, que sería la otra forma de
   comerse ese hueco: entre la cabecera y <main> se imprimen los AVISOS de
   WooCommerce (do_action 'woocommerce_before_single_product', en
   woocommerce.php), que son justo los que muestran los errores de validación de
   la personalización. Un tiro hacia arriba los taparía precisamente en las
   fichas de Eventos.
   ============================================================================= */

.ga-product-single--eventos .ga-product__top {
    padding-top: var(--ga-space-sm);
}


/* =============================================================================
   EVENTOS — GALERÍA POR CAPAS (ficha de producto)
   =============================================================================
   En los productos de Eventos la galería no se navega a mano: no lleva
   miniaturas debajo ni flechas encima. La foto la decide SIEMPRE lo que el
   cliente elige en el formulario —el tipo de etiqueta y, en la Dórica 250, el
   color del cristal—, y de eso se encargan gaEventosFotoEtiqueta y
   gaEventosFotoCristal en assets/js/main.js.

   La plantilla solo pinta estas capas en las fichas de Eventos, así que estas
   reglas no llegan a ninguna otra ficha de la tienda.

   Las capas van al 100% del marco y no hay nada en position:absolute encima, de
   modo que la foto ocupa todo su espacio y a 360px no hay desbordamiento
   horizontal. */

/* REJILLA DE 1×1: todas las fotos comparten celda y quedan una encima de otra.
   Ni una fila horizontal ni position:absolute (🪤 nº 1 y nº 11): el alto lo
   siguen marcando el aspect-ratio del marco y las propias fotos.

   Las capas se ordenan con z-index sin estar posicionadas, que es algo que los
   elementos de una rejilla sí pueden hacer. */
.ga-eventos-galeria {
    display: grid;
}

/* ——— LAS CAPAS DE FOTO ———
   Van con el contenedor delante (0-2-0) porque `.ga-product__gallery-main img`
   de single-product.css puntúa 0-1-1 y le ganaría a una clase suelta: sin esto,
   la transición de esa hoja pisaría la de aquí.

   Solo se anima la OPACIDAD, que no toca el layout, así que el fundido no puede
   mover nada de sitio. */
.ga-eventos-galeria .ga-eventos-galeria__foto {
    grid-area: 1 / 1;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    opacity: 0;
    z-index: 1;
    transition: opacity 350ms ease;
}

.ga-eventos-galeria .ga-eventos-galeria__foto.is-activa {
    opacity: 1;
}

/* 🔴 LA ENTRANTE, POR ENCIMA. Es la pieza que evita el destello crema: la foto
   que llega se funde SOBRE la que se va, y la que se va sigue opaca debajo hasta
   que la de arriba ha terminado de entrar. Así el fondo del marco no llega a
   verse en ningún fotograma.
   Se alterna entre dos valores fijos —1 y 2— y no con un z-index que va
   subiendo: por muchas veces seguidas que se cambie de opción, el valor no crece
   sin control. */
.ga-eventos-galeria .ga-eventos-galeria__foto.is-entrando {
    z-index: 2;
}

/* ——— MOVIMIENTO REDUCIDO ———
   Sin fundido: la foto nueva —que ya está descargada, por eso están todas en el
   DOM— aparece de golpe. Al seguir siendo un cambio de capa y no de src, tampoco
   aquí se ve el fondo crema. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-galeria .ga-eventos-galeria__foto {
        transition: none;
    }
}


/* =============================================================================
   EVENTOS — "COMBÍNALAS CON ESTAS" (ficha de producto)
   =============================================================================
   Cuadrícula de miniaturas con las OTRAS botellas del mismo formato. La pinta
   page-templates/single-product-custom.php y SOLO en los productos de la
   categoría Eventos (la puerta es ga_eventos_es_personalizable), así que estos
   selectores no existen en ninguna otra ficha del sitio.

   ⚠ Igual que el bloque de personalización de arriba, NO va acotado con
   .ga-main--eventos: esto no vive en la página de Eventos, sino en la FICHA de
   cada producto, que no tiene esa clase raíz. La acotación la da el prefijo
   propio .ga-eventos-combina-.

   La misma sección se pinta DOS VECES —una por columna— y cada copia se oculta
   en el ancho que no le toca. Es la única manera de tenerla bajo la foto en
   escritorio y detrás del formulario en móvil: son columnas distintas del grid
   y 'order' solo reordena hermanos.
   ============================================================================= */

/* La copia de móvil nace oculta; solo aparece por debajo de 860px, que es
   justo donde .ga-product__grid deja de tener dos columnas. */
.ga-eventos-combina--mov {
    display: none;
}

.ga-eventos-combina__titulo {
    margin: 0 0 var(--ga-space-sm);
    font-family: var(--ga-font-display);
    font-size: clamp(1.2rem, 1.9vw, 1.5rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
}

/* TRES COLUMNAS y las filas que hagan falta. minmax(0, 1fr) es lo que deja
   encoger las celdas sin recurrir a min-width: a 360px la columna deja unos
   328px y cada miniatura se queda en unos 104px, así que no hay desbordamiento
   horizontal por estrecho que sea el móvil. */
.ga-eventos-combina__rejilla {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--ga-space-xs);
    margin: 0;
    padding: 0;
    list-style: none;
}

.ga-eventos-combina__celda {
    margin: 0;
}

/* TODA LA CELDA ES EL ENLACE: el <a> envuelve la foto y el nombre de debajo, y
   va en display:block, así que se puede pulsar en cualquier punto de la
   miniatura y no solo sobre la flecha. El velo de encima lleva
   pointer-events:none, de modo que el clic lo atraviesa y llega siempre aquí. */
.ga-eventos-combina__enlace {
    display: block;
    text-decoration: none;
    color: inherit;
    cursor: pointer;
}

.ga-eventos-combina__enlace:hover,
.ga-eventos-combina__enlace:focus-visible {
    text-decoration: none;   /* Astra subraya los enlaces al pasar por encima */
}

/* El contorno de foco no ocupa sitio, así que no desplaza nada. */
.ga-eventos-combina__enlace:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
    border-radius: var(--ga-radius-sm);
}

/* La foto manda el tamaño de la celda con su proporción, así que la cuadrícula
   tiene su alto reservado desde el primer momento y no da saltos mientras
   cargan las imágenes. El fondo crema evita el destello blanco de la carga. */
.ga-eventos-combina__foto {
    position: relative;
    display: block;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background-color: var(--ga-naranja-claro);
    border: 1px solid var(--ga-amarillo-pastel);
    border-radius: var(--ga-radius-sm);
    box-sizing: border-box;
}

.ga-eventos-combina__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 🔴 EL VELO SE SUPERPONE, NO EMPUJA. Va en position:absolute cubriendo la foto
   y solo se le anima la OPACIDAD, así que al aparecer no cambia ni el tamaño ni
   la posición de la celda y la cuadrícula no se mueve un píxel.

   CONTENIDO CENTRADO: nombre y flecha van agrupados en el centro de la
   miniatura, uno debajo del otro, y no repartidos por las esquinas. Lo hacen el
   justify-content y el align-items del flex en columna.

   🔴 OSCURECIDO TRANSLÚCIDO, NO UN FONDO SÓLIDO: la botella se sigue viendo
   debajo, atenuada, en vez de desaparecer bajo una capa opaca.

   🔴 NEGRO PURO, Y ES DELIBERADO. Antes era el verde oliva de marca al 58% y se
   cambió a petición: cualquier velo de color —verde, gris o cálido— TIÑE la foto
   y ensucia el blanco del texto, que deja de leerse como blanco. El negro solo
   quita luz, no añade color: la botella se apaga pero conserva su tono, y el
   texto blanco queda limpio encima. Es la única excepción al "overlays con color
   de marca" del claude.md, y vive acotada a esta cuadrícula de la ficha.

   El 62% sube desde el 58% que había: además de ser más opaco, el negro es MUCHO
   más oscuro que el #4a4a2f de antes, así que el salto real de contraste es
   bastante mayor que esos 4 puntos. Sobre una botella clara —el peor caso— el
   blanco pasa de ~2,1:1 a ~2,4:1, y con la sombra de la letra se lee de sobra.
   No se sube más para no perder la botella: por encima de ~65% deja de intuirse
   y la miniatura se convierte en un rectángulo negro con texto.

   Una sola declaración en rgba: aquí NO hace falta el respaldo con color-mix que
   llevaba antes, porque ese doblete existía solo para poder sacar el color de una
   variable —una var() de color no puede llevar transparencia sola—. El negro no
   sale de ninguna variable, así que rgba() basta y lo entiende cualquier
   navegador.

   Nace en opacidad 0 y sin poder recibir el ratón, para que no tape el enlace
   cuando está invisible: el clic siempre llega al <a> que hay debajo. */
.ga-eventos-combina__velo {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.3rem;
    box-sizing: border-box;
    padding: 0.6rem;
    text-align: center;
    /* NEGRO PURO al 62% — ver el porqué en el comentario de encima. */
    background-color: rgba(0, 0, 0, 0.62);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--ga-transition-normal);
}

.ga-eventos-combina__enlace:hover .ga-eventos-combina__velo,
.ga-eventos-combina__enlace:focus-visible .ga-eventos-combina__velo {
    opacity: 1;
}

/* ——— EL TEXTO DEL VELO: NEGRO, EN NEGRITA Y CON HALO ———
   Los tres elementos comparten color y sombra para que se lean como un bloque.

   🔴 LA SOMBRA ES CLARA, NO OSCURA, Y NO ES UN DESPISTE. Debajo hay una foto
   OSCURECIDA, así que una sombra negra se fundiría con el fondo y no separaría
   nada: lo que despega un texto negro de un fondo oscuro es un halo CLARO
   detrás. Van tres capas: dos pegadas a la letra, que le dibujan el borde, y una
   más abierta y suave, que abre un respiro alrededor. Así el nombre se lee igual
   sobre una botella clara que sobre una oscura.

   Y el velo se ha subido al 62%: no porque el negro contraste mejor contra un
   fondo más oscuro —contrasta peor—, sino porque APAGA EL DETALLE DE LA FOTO. Lo
   que de verdad sostiene la lectura aquí es el halo blanco, y el halo necesita un
   fondo uniforme detrás; sobre una foto con mucho contraste se veía a trozos. Con
   el velo más cerrado la botella se sigue intuyendo pero deja de competir. */
/* ——— EL TEXTO DEL VELO: BLANCO, EN NEGRITA Y CON SOMBRA ———
   Es la ÚNICA regla que da color a estos tres elementos: no hay ninguna otra
   compitiendo, ni por especificidad ni por orden, ni con !important. Aun así el
   selector cuelga del velo (0-2-0) para que ninguna regla de clase suelta pueda
   ganarle en el futuro.

   🔴 LA SOMBRA AHORA ES OSCURA, NO CLARA. Cuando el texto era negro llevaba un
   halo BLANCO, porque lo que despega un texto oscuro de un fondo oscuro es un
   halo claro. Con el texto en blanco pasa justo lo contrario: un halo blanco lo
   emborronaría en vez de definirlo. Va una sombra oscura, que le dibuja el borde
   y lo separa de las zonas claras de la botella.

   ⚠ EL RESPALDO DE var() NO ES DECORATIVO. --ga-negro-suave, que es lo que había
   aquí antes, está documentada en el claude.md pero NUNCA se declaró en el :root
   de style.css: la var() era inválida, y en una propiedad heredable como color
   eso cae a `inherit`, así que el texto heredaba el dorado de enlace de Astra.
   Ese fue el dorado que no había manera de quitar. --ga-blanco sí está declarada,
   pero se le deja el respaldo por si acaso: cuesta nada y cierra esa puerta. */
.ga-eventos-combina__velo .ga-eventos-combina__nombre,
.ga-eventos-combina__velo .ga-eventos-combina__accion,
.ga-eventos-combina__velo .ga-eventos-combina__ir {
    color: var(--ga-blanco, #ffffff);
    text-shadow:
        0 1px 2px rgba(0, 0, 0, 0.6),
        0 0 10px rgba(0, 0, 0, 0.4);
}

.ga-eventos-combina__nombre {
    font-family: var(--ga-font-display);
    font-size: clamp(0.9rem, 1.1vw, 1.05rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    overflow-wrap: break-word;
}

/* "Para combinar": entre el nombre y la flecha, más pequeño para que el nombre
   siga mandando, pero también en negrita. */
.ga-eventos-combina__accion {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-bold);
    letter-spacing: 0.06em;
    line-height: 1.3;
    overflow-wrap: break-word;
}

/* La flecha cierra el grupo, centrada bajo el texto: nombre, acción y flecha
   forman un solo bloque en mitad de la miniatura. El trazo del SVG usa
   currentColor, así que hereda el negro de la regla de arriba. */
.ga-eventos-combina__ir {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* El nombre de debajo de la foto, para cuando NO hay ratón. Nace oculto y solo
   lo encienden las dos reglas de más abajo. */
.ga-eventos-combina__nombre-fijo {
    display: none;
    margin-top: 0.35rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.3;
    text-align: center;
    color: var(--ga-verde-oliva-oscuro);
    overflow-wrap: break-word;
}

/* ——— DONDE NO HAY RATÓN ———
   En un táctil el hover no existe —o peor, se queda pegado tras el primer
   toque—, así que el velo se retira del todo y el nombre pasa a verse siempre
   debajo de la foto. Se decide por la CAPACIDAD del dispositivo y no por el
   ancho: una tableta grande o un portátil táctil también entran aquí. */
@media (hover: none) {

    .ga-eventos-combina__velo {
        display: none;
    }

    .ga-eventos-combina__nombre-fijo {
        display: block;
    }
}

/* La copia de móvil solo sale por debajo de 860px, donde siempre es táctil:
   lleva el nombre fijo pase lo que pase. */
.ga-eventos-combina--mov .ga-eventos-combina__velo {
    display: none;
}

.ga-eventos-combina--mov .ga-eventos-combina__nombre-fijo {
    display: block;
}


/* ——— ESCRITORIO (>=861px) ———
   La columna de la foto deja de ir pegada SOLO en las fichas que llevan esta
   sección: pegada, su parte de abajo —justo esta cuadrícula— se quedaría
   permanentemente fuera de la vista. */
@media (min-width: 861px) {

    .ga-product__grid--combina .ga-product__gallery {
        position: static;
    }
}


/* ——— MÓVIL Y TABLET (<=860px) ———
   Es el ancho al que .ga-product__grid pasa a una sola columna: se cambia la
   copia de escritorio por la de móvil, que sale a lo ancho tras el formulario. */
@media (max-width: 860px) {

    .ga-eventos-combina--esc {
        display: none;
    }

    .ga-eventos-combina--mov {
        display: block;
    }
}


/* ——— MOVIMIENTO REDUCIDO ———
   El velo aparece de golpe en vez de fundirse. No se pierde nada: la cuadrícula
   es estática y no hay ninguna animación más que quitar. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-combina__velo {
        transition: none;
    }
}



/* =============================================================================
   EVENTOS — CONTACTO DE LA FICHA (ficha de producto)
   =============================================================================
   Dos datos y nada más —teléfono con WhatsApp y correo—, para cerrar la columna
   izquierda bajo la cuadrícula de botellas. Sin formulario, sin horarios y sin
   dirección: para eso está la página de Contacto.

   ⚠ NO SE REUTILIZAN LAS CLASES DEL CIERRE DE LA PÁGINA DE EVENTOS. Aquellas
   reglas van acotadas con .ga-main--eventos, que es la clase raíz de esa PÁGINA,
   y una ficha de producto no la lleva: no llegarían nunca. Así que el aspecto se
   replica aquí con clases propias —misma etiqueta dorada en versalitas, mismo
   verde de WhatsApp, mismo hover— sin tocar una sola regla de esa página.

   La misma sección se pinta DOS VECES —una por columna— y cada copia se oculta
   en el ancho que no le toca, igual que la cuadrícula de botellas y por el mismo
   motivo: son columnas distintas del grid y 'order' solo reordena hermanos.
   ============================================================================= */

/* La copia de móvil nace oculta; solo aparece por debajo de 860px, que es justo
   donde .ga-product__grid deja de tener dos columnas. */
.ga-eventos-ctc--mov {
    display: none;
}

/* SIN RAYA ARRIBA. Llevaba un border-top de 1px en el verde pálido de marca que
   separaba este bloque de la cuadrícula de botellas, y se ha quitado a petición:
   el hueco de arriba ya separa de sobra y la línea metía un corte duro en una
   columna que no tiene ninguno más.

   ——— EL HUECO DE ARRIBA, A LA MITAD Y EN UNA SOLA PROPIEDAD ———
   Tenía margin-top: 2,5rem MÁS padding-top: 1,5rem = 4rem de aire propio. Eran
   dos porque el relleno era el respiro por dentro de la raya; sin raya, el
   padding ya no pinta nada y los dos hacían exactamente el mismo trabajo. Se
   funden en un solo margen de 2rem: la mitad justa de esos 4rem.

   ⚠ EL HUECO QUE SE VE ES 1rem MAYOR QUE ESTE NÚMERO, y no es un descuadre. La
   columna de la foto (.ga-product__gallery) es un flex en columna con gap: 1rem,
   así que ese hueco se suma SIEMPRE por encima de este margen. El total pasa de
   5rem a 3rem. Ese gap NO se toca: es de single-product.css, que es de toda la
   tienda, y bajarlo movería también la ficha estándar.

   Y por ser hijo de un flex, este margen NO COLAPSA con el margen inferior de la
   cuadrícula de botellas: lo que se escriba aquí es lo que se suma, sin sorpresas.

   El espacio de DEBAJO no se toca: este bloque no declara ninguno —lo cierra el
   final de la columna— y sigue igual que estaba. */
.ga-eventos-ctc {
    margin-top: calc(var(--ga-space-sm) * 2);
}

.ga-eventos-ctc__titulo {
    margin: 0 0 var(--ga-space-md);
    font-family: var(--ga-font-display);
    font-size: clamp(1.2rem, 1.9vw, 1.5rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
}

/* Los dos bloques, uno debajo de otro. Es una columna estrecha: puestos al lado
   el correo se quedaría sin sitio y partiría por cualquier lado. */
.ga-eventos-ctc__filas {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ga-space-md);
}

.ga-eventos-ctc__etiqueta {
    margin: 0 0 0.2rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    font-weight: var(--ga-weight-medium);
    letter-spacing: 0.22em;
    line-height: 1.4;
    color: var(--ga-naranja-apagado);
}

/* 🔴 !important en el color: en una página de WooCommerce, Astra captura los <a>
   con reglas que ganan en especificidad a una clase suelta y le imponen su azul
   de enlace (🪤 nº 6).

   El hover solo cambia color y subrayado: ni tamaño ni posición, así que no
   descoloca nada. overflow-wrap corta el ancho mínimo del correo sin recurrir a
   min-width, que es lo que lo deja envolver en una columna estrecha. */
.ga-eventos-ctc__enlace {
    display: inline-flex;
    align-items: center;
    gap: var(--ga-space-xs);
    font-family: var(--ga-font-body);
    font-size: clamp(1rem, 1.4vw, 1.2rem);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;
    text-decoration: none;
    overflow-wrap: break-word;
    transition: color var(--ga-transition-normal);
}

.ga-eventos-ctc__enlace,
.ga-eventos-ctc__enlace:focus {
    color: var(--ga-verde-oliva-oscuro) !important;
}

.ga-eventos-ctc__enlace:hover,
.ga-eventos-ctc__enlace:focus-visible {
    color: var(--ga-naranja-apagado) !important;
    text-decoration: underline;
}

/* El contorno de foco no ocupa sitio, así que tampoco mueve nada. */
.ga-eventos-ctc__enlace:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

/* El icono, en el verde propio de WhatsApp. Es el único color ajeno a la paleta
   de la marca, y va así porque es el color identificativo del servicio.
   flex: 0 0 auto para que no se encoja cuando el número envuelve. */
.ga-eventos-ctc__ico {
    display: flex;
    flex: 0 0 auto;
    color: #25D366;
}


/* ——— MÓVIL Y TABLET (<=860px) ———
   Es el ancho al que .ga-product__grid pasa a una sola columna: se cambia la
   copia de escritorio por la de móvil, que sale a lo ancho al final de la ficha.
   A 360px el correo dispone de los 328px completos y lleva overflow-wrap, así
   que no impone ancho mínimo y no hay desbordamiento horizontal. */
@media (max-width: 860px) {

    .ga-eventos-ctc--esc {
        display: none;
    }

    .ga-eventos-ctc--mov {
        display: block;
    }
}


/* =============================================================================
   EVENTOS — "¿POR QUÉ REGALAR ACEITE DE OLIVA?": CUATRO TARJETAS CON FOTO
   =============================================================================
   (ficha de producto)

   Ocupa el sitio de los cuatro pilares de siempre y RECUPERA SU FORMATO —cuatro
   tarjetas iguales en fila, con los mismos cortes responsive— cambiando el icono
   en círculo por una FOTO a toda la anchura en la parte de arriba. Poco texto:
   un título corto y una frase por tarjeta.

   ⚠ EL PREFIJO .ga-eventos-raices- ES HISTÓRICO: la sección se llamaba "Un regalo
   con raíces" cuando se escribieron estas clases. El titular cambió y los nombres
   se quedaron, para no mover marcado y CSS a la vez sin ganar nada. Mismo criterio
   que --ga-naranja-apagado, que en realidad es el dorado de marca.

   ⚠ AQUÍ VIVÍA EL CIERRE DE AQUELLA SECCIÓN. Había una regla que le devolvía a
   .ga-product-single--eventos .ga-product__beneficios el relleno inferior que la
   hoja de la ficha le pone a cero. Se borró porque se quedó SIN USO: la ficha de
   Eventos ya no pinta esa clase por ningún lado —la sección propia se quitó y
   ga_render_beneficios_cosecha() sigue desenganchada del hook—. La regla
   compartida de single-product.css no se ha tocado, así que las fichas que NO son
   de Eventos conservan sus cuatro pilares exactamente como estaban.

   El relleno de la banda se escribe aquí, con los dos valores de aquella
   —--ga-space-xl y --ga-space-lg por debajo de 640px— para que el ritmo vertical
   de la página no cambie respecto a lo que había.

   🔴 SIN HOVER, Y NO ES UN OLVIDO. .ga-beneficio, la tarjeta de los pilares en la
   que está inspirada esta, sube 4px al pasar el ratón (transform: translateY).
   Eso está expresamente prohibido aquí: ningún estado puede cambiar tamaño ni
   posición. Y como estas tarjetas no son enlaces ni botones —no llevan a ninguna
   parte—, un hover tampoco aportaría nada: se ha dejado fuera del todo. No hay ni
   un solo estado interactivo en toda la sección.
   ============================================================================= */

/* La banda. Crema de marca, el mismo fondo que tenían los pilares: el ritmo de
   bandas de la ficha no se altera al cambiar el contenido. */
/* 🔴 EL RELLENO DE ARRIBA Y EL DE ABAJO SON DISTINTOS, Y ES A PROPÓSITO.
   Se declaran por separado, sin el atajo padding-block, porque cada uno responde a
   una cosa distinta y han ido moviéndose de forma independiente.

   HISTORIAL, porque este valor ha ido y ha vuelto y conviene no repetir el viaje:
     · empezaron los dos en --ga-space-xl (4rem);
     · el de ARRIBA bajó a --ga-space-md (1,5rem) porque el título se veía hundido
       en la banda crema;
     · más tarde se subió otra vez a --ga-space-xl para dar aire a la sección…
     · …y se REVIRTIÓ a --ga-space-md: con 4rem encima, el título quedaba
       demasiado despegado del borde de la banda y la cabecera de la sección se
       veía vacía. Es el valor bueno y el que hay ahora.

   ⚠ EL DE ABAJO NO ENTRA EN ese vaivén: se quedó en --ga-space-2xl (6rem) y ahí
   sigue. Es el que separa las tarjetas de la sección siguiente y nunca ha dado
   problema; revertirlo no se pidió y habría vuelto a apretar el cierre de la
   sección.

   REPARTO QUE QUEDA EN ESCRITORIO Y TABLET: 1,5rem por encima del título, 4rem
   entre el título y las fotos (el margen del titular, que tampoco se toca aquí) y
   6rem desde las tarjetas hasta el final de la banda. */
.ga-eventos-raices {
    padding-top: var(--ga-space-md);
    padding-bottom: var(--ga-space-2xl);
    background-color: var(--ga-naranja-claro);
}

/* El titular de la sección, con la misma medida que tenía el de los pilares.

   ——— EL AIRE ENTRE EL TÍTULO Y LAS FOTOS ———
   El título NO lleva margen propio por arriba: ese hueco lo pone ENTERO el
   padding-top de la sección, y se trabaja allí. Aquí solo se decide lo que hay por
   DEBAJO, hasta la primera fila de tarjetas.

   ⚠ ESTE MARGEN Y EL padding-top DE LA BANDA NO SON IGUALES NI TIENEN QUE SERLO.
   Hubo un intento de igualarlos para dejar el título centrado entre el borde de la
   banda y las fotos, y se descartó: centrado quedaba peor que apoyado arriba, que
   es como está ahora —poco aire encima, más por debajo— y como se ha validado.

   El valor lo hereda del ajuste que despegó las fotos del título; no se ha vuelto
   a mover al revertir el relleno de arriba, porque el problema estaba en el aire
   de encima y no en este. */
.ga-eventos-raices__titulo {
    margin: 0 0 var(--ga-space-xl);
    font-family: var(--ga-font-display);
    font-size: clamp(1.4rem, 2.5vw, 2rem);
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    color: var(--ga-verde-oliva-oscuro);
    /* Corta el ancho mínimo del contenido sin min-width. */
    overflow-wrap: break-word;
}

/* ——— LA REJILLA: 1 → 2 → 4 ———
   Los mismos escalones que .ga-beneficios__grid, para que la sección se comporte
   igual que la que sustituye: apiladas en móvil, dos y dos en tablet y las cuatro
   en fila a partir de 900px.

   🔴 SE DECLARAN DE MENOR A MAYOR (min-width) Y NO AL REVÉS. Es la única forma de
   que el punto de partida sea UNA columna: si algo falla o una media query no
   llega a aplicarse, lo que queda es la versión apilada, que cabe en cualquier
   pantalla. Al revés, el fallo dejaría cuatro columnas en un móvil.

   minmax(0, 1fr) en vez de 1fr a secas: es lo que deja encoger las columnas por
   debajo del ancho de su contenido sin recurrir a ningún min-width. Sin él, una
   palabra larga podría ensanchar su columna y sacar la fila del viewport.

   Es un <ul>: se le quitan la viñeta y los márgenes del navegador. */
.ga-eventos-raices__grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ga-space-sm);
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 600px) {

    .ga-eventos-raices__grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: var(--ga-space-md);
    }
}

@media (min-width: 900px) {

    .ga-eventos-raices__grid {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* ——— LA TARJETA ———
   Flex en columna: la foto arriba y el cuerpo debajo, ocupando lo que necesite.
   Las cuatro miden LO MISMO de alto sin escribir ninguna altura: son celdas de
   una rejilla y el 'stretch' por defecto las estira a la más alta de su fila, así
   que los bordes de abajo quedan alineados aunque una frase ocupe dos líneas y
   otra tres. */
.ga-eventos-raices__card {
    display: flex;
    flex-direction: column;
    margin: 0;
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-amarillo-pastel);
    border-radius: var(--ga-radius-md);
    box-shadow: var(--ga-shadow-sm);
}

/* ——— LA FOTO ———
   Todas con la MISMA proporción (4:3), así que a igual ancho de columna todas
   miden igual de alto y la fila de títulos arranca a la misma altura en las
   cuatro. El aspect-ratio además reserva el hueco antes de que la imagen cargue:
   la sección no pega un salto a mitad de carga.

   🔴 LAS ESQUINAS SE REDONDEAN AQUÍ, NO CON overflow: hidden EN LA TARJETA. Ese
   overflow habría convertido cada tarjeta en un contenedor de scroll (🪤 nº 3) sin
   necesidad ninguna. Se redondean solo las dos de arriba, y con 1px menos de
   radio que la tarjeta, que es el grosor de su borde: así la curva de la foto va
   por dentro de la del borde y no asoma un pico entre las dos.

   El fondo va debajo por si la imagen tarda: se ve el color de marca y nunca un
   destello blanco. */
.ga-eventos-raices__foto {
    display: block;
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background-color: var(--ga-amarillo-pastel);
    border-radius: calc(var(--ga-radius-md) - 1px) calc(var(--ga-radius-md) - 1px) 0 0;
}

/* Marco provisional mientras no exista el archivo. Es un <span>, pero la regla de
   arriba le da display:block, así que el aspect-ratio le aplica igual y ocupa
   EXACTAMENTE lo mismo que ocupará la foto: el día que se suba la imagen no se
   mueve nada de sitio ni cambia el alto de la fila. */
.ga-eventos-raices__foto--vacia {
    background-color: var(--ga-amarillo-pastel);
}

/* ——— EL ENCUADRE DE CADA FOTO ———
   ═══════════════════════════════════════════════════════════════════════════
   Con object-fit: cover la imagen llena el recuadro y lo que sobra se recorta.
   Por defecto el recorte va CENTRADO (object-position: 50% 50%), y en tres de las
   cuatro fotos el motivo no está en el centro exacto del original: se recortaba
   por donde no tocaba. Aquí se mueve el punto de enfoque VERTICAL de cada una.

   Solo cambia QUÉ PARTE DE LA FOTO SE VE. No se toca el tamaño del recuadro, ni el
   object-fit, ni la proporción: la imagen no se estira ni se deforma en ningún
   caso, simplemente se desliza por detrás de su marco.

   🔴 SE APUNTA AL ARCHIVO, NO A LA POSICIÓN DE LA TARJETA. El selector busca el
   nombre del fichero DENTRO del src ([src*="…"]) en vez de un :nth-child. Es a
   propósito y por dos motivos:
     · un :nth-child ata el recorte a que la tarjeta siga siendo la primera, la
       tercera o la cuarta. El día que se reordenen o se añada una quinta, cada
       encuadre se aplicaría a la foto equivocada y sería un fallo silencioso, de
       los que no se ven hasta que alguien mira la página;
     · atado al archivo, el recorte viaja CON la foto. Si se reordenan las
       tarjetas, sigue bien; y si algún día se sustituye la imagen por otra con
       distinto nombre, la regla deja de aplicarse sola y esa foto vuelve al
       centrado por defecto, que es el comportamiento seguro.
   El marco provisional es un <span> sin src, así que ninguna de estas reglas puede
   alcanzarlo.

   ⚠ SE USA *= (CONTIENE) Y NO $= (TERMINA EN), y no es indiferente. LiteSpeed o el
   CDN de Hostinger pueden reescribir el src: añadirle un ?ver=…, cambiarle el
   dominio o servir la imagen desde otra ruta. Con "termina en", cualquiera de esas
   tres cosas rompería el selector en silencio y la foto volvería al centrado sin
   que nadie se enterara. Buscando el nombre DENTRO del src aguanta las tres. Los
   tres nombres son largos y únicos, así que no hay riesgo de que coincidan con
   otra imagen por accidente.

   Los porcentajes son el PUNTO DE LA FOTO que se alinea con el centro del marco:
   más de 50% enseña la parte de ABAJO, menos de 50% la de ARRIBA. Cada foto lleva
   el suyo, ajustado a ojo sobre la página y en pasos de 10 puntos; el valor de
   cada una y de dónde viene está anotado en su propia regla. Si hiciera falta
   afinar más, se sube o se baja ese número y no hay que tocar nada más.

   ⚠ ESTO SOLO SURTE EFECTO SI LA FOTO ES MÁS ALTA QUE 4:3. Es lo que hay que
   recortar en vertical. Si alguna de las tres fuera más apaisada que el marco, no
   sobraría alto por ninguna parte y su regla no cambiaría nada: entonces el
   encuadre habría que corregirlo en la propia imagen. */

/* "De nuestra tierra": se enseña un poco más abajo. */
.ga-product-single--eventos .ga-eventos-raices__foto[src*="aceitunas-verdes-olivo-aceite-oliva-eventos"] {
    object-position: center 65%;
}

/* "Lo hacemos a tu gusto": se enseña un poco más arriba, pero MENOS que antes.
   Venía del 50% de serie, se subió al 35% y con eso se pasaba: el encuadre quedaba
   demasiado alto. Vuelve 10 puntos hacia el centro. */
.ga-product-single--eventos .ga-eventos-raices__foto[src*="botella-personalizada-boda-aceite-oliva-detalle-novios"] {
    object-position: center 45%;
}

/* "Para disfrutar": se enseña más abajo. El 65% se quedaba corto —seguía faltando
   parte de abajo de la foto—, así que baja otros 10 puntos. */
.ga-product-single--eventos .ga-eventos-raices__foto[src*="aceite-oliva-virgen-extra-tostada-pan"] {
    object-position: center 75%;
}

.ga-eventos-raices__cuerpo {
    padding: var(--ga-space-md) var(--ga-space-sm);
    text-align: center;
}

.ga-eventos-raices__card-titulo {
    margin: 0 0 var(--ga-space-xs);
    font-family: var(--ga-font-display);
    font-size: 1.2rem;
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-verde-oliva-oscuro);
    overflow-wrap: break-word;
}

.ga-eventos-raices__card-texto {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.6;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.85;
    text-wrap: pretty;
    overflow-wrap: break-word;
}


/* ——— MÓVIL ESTRECHO (<=640px) ———
   El mismo escalón de relleno que usaba la sección anterior, para no cambiar el
   ritmo vertical de la ficha en móvil. A 360px la rejilla va a una sola columna
   —el corte de dos columnas empieza en 600px—, así que cada tarjeta dispone de
   los 328px del contenedor y no hay forma de que una fila desborde.

   🔴 LOS TRES VALORES VAN JUNTOS, cada uno un escalón por debajo del de
   escritorio, para que en móvil se mantenga la MISMA proporción sin estirar la
   sección: aquí cada rem de más obliga a hacer scroll.

   Suben igual que los de arriba y por el mismo motivo —la sección se veía apretada
   contra sus vecinas—: el relleno superior pasa de --ga-space-sm (1rem) a
   --ga-space-lg (2,5rem) y el inferior de --ga-space-lg a --ga-space-xl (4rem).

   REPARTO QUE QUEDA EN MÓVIL: --ga-space-sm (1rem) por encima del título, 2,5rem
   entre el título y las fotos y 4rem desde las tarjetas hasta el final de la banda.
   Un escalón por debajo de los de escritorio en cada caso, que es la proporción de
   siempre en este breakpoint.

   ⚠ EL RELLENO SUPERIOR VUELVE A --ga-space-sm, igual que el de escritorio vuelve
   a --ga-space-md: los dos se habían subido un escalón para dar aire a la sección
   y los dos se revierten, porque con ese aire de más el título se despegaba del
   borde de la banda. El relleno INFERIOR se queda en --ga-space-xl, sin revertir,
   por lo mismo que en escritorio. */
@media (max-width: 640px) {

    .ga-eventos-raices {
        padding-top: var(--ga-space-sm);
        padding-bottom: var(--ga-space-xl);
    }

    .ga-eventos-raices__titulo {
        margin-bottom: var(--ga-space-lg);
    }
}


/* =============================================================================
   EVENTOS — "ASÍ ES TODO EL PROCESO": LOS TRES PASOS (ficha de producto)
   =============================================================================
   Va justo debajo de las cuatro tarjetas. Número, título y una frase por paso.
   Sin fotos, sin botones y sin JS.

   ⚠ EL PREFIJO .ga-eventos-comopedir- ES HISTÓRICO: la sección se llamaba "Pedir
   es muy sencillo" cuando se escribieron estas clases. El titular cambió y los
   nombres se quedaron, para no mover marcado y CSS a la vez sin ganar nada.

   ⚠ NO REUTILIZA .ga-eventos-paso DE LA PÁGINA DE EVENTOS, y no por descuido.
   Aquellas reglas cuelgan de .ga-main--eventos, la clase raíz de esa PÁGINA, que
   una ficha de producto no lleva: no llegarían hasta aquí sin reescribirlas una a
   una. Y traen puesto lo que aquí sobra —rejilla de CUATRO columnas, subgrid de
   cuatro filas con una reservada a la foto de cada paso, la línea que une los
   círculos con su clase .ga-eventos-linea-activa que enciende el JS, y un
   carrusel horizontal en móvil—. Aquí son TRES pasos, sin foto y apilados.

   Lo que sí se copia es el ASPECTO: el círculo dorado con el número en blanco y
   Cormorant, el texto centrado y los mismos tamaños de párrafo, para que las dos
   secciones se lean como de la misma casa. Son bloques INDEPENDIENTES: si algún
   día se rediseñan aquellos pasos, esto hay que mirarlo a mano.

   ——— FONDO VERDE OLIVA: LA BANDA OSCURA DE LA FICHA ———
   Era blanca y pasa al verde oliva de marca, con el MISMO par que usa el panel de
   la página de Contacto: fondo --ga-verde-oliva-oscuro (#4a4a2f) y color de texto
   base --ga-naranja-claro (el crema #eae5d8), que se hereda a todo lo de dentro.
   Ese crema sobre ese verde da 7,1:1 de contraste, muy por encima del 4,5:1 que
   se le pide a un texto normal.

   Y el ritmo de bandas mejora: encima queda el crema de las cuatro tarjetas y
   debajo el blanco de las reseñas, así que esta franja oscura parte la ficha en
   dos en vez de encadenar dos secciones claras que antes se fundían.
   ============================================================================= */

/* 🔴🔴 EL COLOR DEL TEXTO SE ESCRIBE EN CADA ELEMENTO, NUNCA POR HERENCIA.
   ═══════════════════════════════════════════════════════════════════════════
   ESTO YA FALLÓ UNA VEZ Y ASÍ ES COMO FALLÓ. Al pasar la banda a verde se puso el
   crema SOLO aquí, en la sección, contando con que lo heredaran el titular, los
   títulos de paso y las frases. Resultado: el texto DESAPARECIÓ. Se quedó en
   #4a4a2f, exactamente el mismo color que el fondo.

   El motivo es la regla de tipografía general de este mismo archivo:

       h1, h2, h3, h4, h5, h6 { … color: var(--ga-verde-oliva-oscuro); }   (línea 130)
       p                      { … color: var(--ga-verde-oliva-oscuro); }   (línea 143)

   UN VALOR HEREDADO NO TIENE ESPECIFICIDAD: no compite, solo se usa cuando NINGUNA
   regla toca al elemento. Y esas dos SÍ lo tocan —son selectores de etiqueta, la
   especificidad más baja que existe (0-0-1), pero les basta para ganarle a una
   herencia—. El <h2>, los tres <h3> y los tres <p> cogían su verde oscuro y el
   `color` de la sección no llegaba a usarse nunca.

   ✅ LA REGLA: en una sección de fondo oscuro, cada elemento de texto lleva su
   `color` escrito, con un selector de clase (0-1-0), que gana a esas dos de sobra.
   El `color` de la sección se queda como red de seguridad para lo que se añada en
   el futuro, pero NO es lo que pinta nada de lo que hay hoy: si se le quita el
   color a alguna de las reglas de abajo, ese texto vuelve a desaparecer. */
.ga-eventos-comopedir {
    padding-block: var(--ga-space-xl);
    background-color: var(--ga-verde-oliva-oscuro);
    /* Red de seguridad para elementos futuros. NO es lo que colorea el titular ni
       los pasos: cada uno lleva el suyo, por el motivo de aquí arriba. */
    color: var(--ga-naranja-claro);
}

/* Mismo titular y mismo tamaño que el de las cuatro tarjetas de arriba: las dos
   secciones son hermanas y tienen que pesar igual.

   Crema PLENO, sin rebajar: es el texto que más manda de la sección. Sobre el
   verde da 7,1:1 de contraste.

   ——— MÁS AIRE ARRIBA Y ABAJO ———
   Quedaba encajonado entre el borde de la banda y los círculos. Se le da algo de
   margen por arriba, ADEMÁS del relleno que ya pone la sección, y el de abajo pasa
   de --ga-space-lg fijo (2,5rem) al mismo clamp que usa el titular de las cuatro
   tarjetas: llega a --ga-space-xl (4rem) en escritorio y se queda en los 2,5rem de
   siempre en tablet y móvil, donde por debajo de ~800px el término en vw no
   alcanza el mínimo. Con eso las dos secciones vuelven a separar igual su titular
   —antes solo lo hacía la de arriba— y en móvil ninguna se estira de más. */
.ga-eventos-comopedir__titulo {
    margin: var(--ga-space-sm) 0 clamp(var(--ga-space-lg), 5vw, var(--ga-space-xl));
    font-family: var(--ga-font-display);
    font-size: clamp(1.4rem, 2.5vw, 2rem);
    font-weight: 600;
    line-height: 1.25;
    text-align: center;
    color: var(--ga-naranja-claro);
    /* Corta el ancho mínimo del contenido sin min-width. */
    overflow-wrap: break-word;
}

/* ——— LA LISTA ———
   Arranca APILADA y solo se pone en fila a partir de 769px. Declararlo en este
   orden —de menor a mayor— es lo que garantiza que el punto de partida quepa en
   cualquier pantalla: si una media query no llegara a aplicarse, lo que queda es
   la versión de una columna, nunca tres columnas en un móvil de 360px.

   minmax(0, 1fr) en vez de 1fr a secas: es lo que deja encoger las columnas por
   debajo del ancho de su contenido sin recurrir a ningún min-width. Sin él, una
   palabra larga podría ensanchar su columna y sacar la fila del viewport.

   El diámetro del círculo, su radio y la separación entre columnas se declaran
   aquí, en la lista, y no repartidos por las reglas de dentro. Las propiedades
   personalizadas se heredan, así que los tres círculos salen del MISMO valor y no
   pueden descuadrarse entre ellos, y —lo importante— la LÍNEA que los une se
   calcula a partir de esos mismos números: cambiar el tamaño del círculo o el
   hueco entre columnas recoloca la línea sola, sin tocar su regla.

   Es un <ol>: se le quitan la numeración y los márgenes del navegador, porque el
   número lo pinta el círculo. */
.ga-eventos-comopedir__lista {
    --ga-comopedir-num: clamp(3rem, 4vw, 3.75rem);
    --ga-comopedir-radio: calc(var(--ga-comopedir-num) / 2);
    /* Se abre con el ancho de la ventana, como la separación de los pasos de la
       página de Eventos: repartidos en escritorio, contenidos en tablet. */
    --ga-comopedir-gap: clamp(var(--ga-space-lg), 5vw, var(--ga-space-2xl));

    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: var(--ga-space-lg);
    margin: 0;
    padding: 0;
    list-style: none;
}

@media (min-width: 769px) {

    .ga-eventos-comopedir__lista {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        column-gap: var(--ga-comopedir-gap);
    }
}

/* position:relative + z-index lo convierten en la referencia de su propia línea y
   lo colocan por delante de la que le llega del paso anterior.

   ——— EL RETARDO DEL DESTELLO, UNA VEZ POR PASO ———
   Aquí se declara y lo heredan las DOS piezas que brillan: el círculo y el tramo
   de línea que sale de él (que es un ::before de este mismo elemento, así que
   hereda igual). Con eso el barrido no salta en los tres a la vez, sino que
   recorre los pasos en orden —1, 2 y 3— y se lee como el proceso avanzando.

   Es un retardo, no otra animación: los keyframes, la duración y el degradado
   siguen siendo los mismos que los de los botones. */
.ga-eventos-comopedir__paso {
    --ga-comopedir-destello: 0s;

    position: relative;
    z-index: 1;
    margin: 0;
    text-align: center;
}

.ga-eventos-comopedir__paso:nth-child(2) {
    --ga-comopedir-destello: 1.3s;
}

.ga-eventos-comopedir__paso:nth-child(3) {
    --ga-comopedir-destello: 2.6s;
}

/* ——— LA LÍNEA QUE UNE LOS TRES CÍRCULOS ———
   MISMO MECANISMO QUE LA LÍNEA DE TIEMPO DE LA PÁGINA DE EVENTOS
   (.ga-main--eventos .ga-eventos-paso:not(:last-child)::before): cada paso menos
   el último dibuja el TRAMO que va del centro de SU círculo al centro del
   siguiente. Arranca en left: 50% —el centro del círculo, que va centrado con
   margin auto— a la altura de su radio, que es su centro vertical, y mide una
   columna entera más el hueco, que es exactamente la distancia entre dos centros.
   Como cada tramo acaba donde empieza el siguiente, se lee como una línea
   continua; y al no ponérselo al último, NO SOBRESALE por ningún extremo: empieza
   en el centro del círculo 1 y termina en el del 3.

   PASA POR DETRÁS de los círculos: el ::before va a z-index 0 dentro de su paso,
   y el círculo del paso siguiente —opaco y con su propio z-index— se pinta encima
   y le tapa el final.

   🔴 YA NO VA DENTRO DE UN @media: LA LÍNEA EXISTE EN TODOS LOS ANCHOS.
   Estuvo un tiempo limitada a escritorio, y con razón: en aquel momento los pasos
   se APILABAN en móvil, y esta misma línea habría caído en vertical por el centro
   de la columna cruzando el título y la frase de cada paso. Desde que en móvil los
   pasos son un carrusel HORIZONTAL, esa objeción desaparece: la fila vuelve a ser
   una fila y la línea vuelve a unir tres círculos que están uno al lado del otro.

   Y no ha hecho falta reescribirla: la fórmula es la misma —del centro de un
   círculo al del siguiente, una "columna" más el hueco— porque en el carrusel el
   ancho del paso lo da su flex-basis y el hueco sigue saliendo de
   --ga-comopedir-gap. Por eso ese hueco se declara SIEMPRE en la variable y nunca
   escribiendo el `gap` a pelo: si en móvil se pusiera el gap por un lado y la
   variable se quedara con el valor de escritorio, la línea se quedaría corta o
   larga y no habría forma de verlo sin medirlo.

   Decorativa y sin ratón: pointer-events none. */

.ga-eventos-comopedir__paso:not(:last-child)::before {
        content: '';
        position: absolute;
        z-index: 0;
        top: var(--ga-comopedir-radio);
        left: 50%;
        width: calc(100% + var(--ga-comopedir-gap));
        height: 1px;
        /* El dorado de marca rebajado: sobre el verde oscuro se ve sin gritar, y
           deja claro que es el hilo que enhebra los tres círculos dorados. Va en
           rgba porque una variable de color no puede llevar transparencia sola;
           199,168,98 es --ga-naranja-apagado (#c7a862). */
        background-color: rgba(199, 168, 98, 0.40);

        /* BRILLO — el MISMO mecanismo de los botones (.ga-home-card__cart), sin
           tocar nada de su receta: degradado a 100deg con el punto de luz en el
           50%, background-size del 250%, no-repeat, y la animación
           ga-home-card-brillo de 8s lineal en bucle, que solo mueve
           background-position. Ni reflow ni repintado, y la línea no se mueve un
           píxel: lo que viaja es la luz por dentro de ella.

           Lo ÚNICO adaptado es el color, y con el MISMO criterio que el círculo: el
           degradado no repinta el fondo de la línea —para eso ya está su
           background-color—, solo SUMA un poco de dorado en el punto de luz. Antes
           saltaba del 40% al 95% de opacidad y el destello se veía como un tramo
           encendido; ahora suma un 0.30 sobre el 40% que ya hay, así que la línea
           se aviva un punto al pasar la luz y vuelve a su tono. Los extremos van a
           alfa 0 del mismo dorado, no a `transparent`, para que la interpolación no
           ensucie el degradado con un gris intermedio. */
        background-image: linear-gradient(
            100deg,
            rgba(199, 168, 98, 0) 0%,
            rgba(199, 168, 98, 0) 45%,
            rgba(199, 168, 98, 0.30) 50%,
            rgba(199, 168, 98, 0) 55%,
            rgba(199, 168, 98, 0) 100%
        );
        background-size: 250% 100%;
        background-repeat: no-repeat;
        background-position: 100% center;
        animation: ga-home-card-brillo 8s linear infinite;
        animation-delay: var(--ga-comopedir-destello);

        pointer-events: none;
    }

/* ——— EL CÍRCULO DEL NÚMERO ———
   Disco dorado de marca, redondo del todo y algo más pequeño que el de la página
   de Eventos (48-60px frente a 60-88px), porque es una sección de la ficha y no
   el bloque principal de una página.

   position:relative + z-index lo ponen POR DELANTE de la línea, y su fondo opaco
   es lo que hace que el tramo que le llega del paso anterior se vea entrar por
   detrás en vez de cruzarle por encima.

   🔴 EL NÚMERO VA EN VERDE OSCURO, NO EN BLANCO. En la página de Eventos es blanco
   sobre el dorado, pero allí el círculo se apoya en fondo blanco y aquí lo hace
   sobre el verde. Blanco sobre dorado da 1,9:1, que no se lee; el verde oliva
   sobre el dorado da 3,9:1 y, tratándose de una cifra grande en negrita, cumple de
   sobra. Es además el criterio que ya recoge el claude.md para los textos sobre
   dorado.

   line-height: 1 deja la caja de línea en 1em exacto, sin interlineado repartido
   arriba y abajo, y el flex la centra: así el número queda a media altura del
   círculo en cualquier tamaño, sin ajustes a ojo. */
.ga-eventos-comopedir__num {
    position: relative;
    z-index: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--ga-comopedir-num);
    height: var(--ga-comopedir-num);
    margin: 0 auto var(--ga-space-sm);
    border-radius: var(--ga-radius-full);
    background-color: var(--ga-naranja-apagado);
    color: var(--ga-verde-oliva-oscuro);
    font-family: var(--ga-font-display);
    font-size: clamp(1.25rem, 1.6vw, 1.5rem);
    font-weight: 600;
    line-height: 1;
    /* Solo se animan transform y box-shadow: ninguna de las dos ocupa sitio en el
       flujo, así que el hover no puede mover ni descolocar nada. */
    transition: transform var(--ga-transition-normal),
                box-shadow var(--ga-transition-normal);

    /* ——— BRILLO — EL MISMO MECANISMO QUE LOS BOTONES ———
       Copiado tal cual de .ga-home-card__cart, sin cambiar una sola pieza de la
       receta: degradado a 100deg con el punto de luz en el 50% y las paradas en
       45% y 55%, background-size del 250%, no-repeat, arranque en 100% center y la
       animación ga-home-card-brillo —la MISMA, no una nueva— de 8s lineal en
       bucle. Esos keyframes barren en la primera mitad y descansan en la segunda,
       así que son 4s de destello y 4s de reposo: sutil, no un parpadeo continuo. Y
       solo mueven background-position, que no provoca ni reflow ni repintado.

       ——— LA BANDA DE LUZ, EN TRANSPARENCIA (Y POR ESO SUAVE) ———
       🔴 EL DEGRADADO NO REPITE EL DORADO EN LOS EXTREMOS: VA DE TRANSPARENTE A
       TRANSPARENTE. Antes iba del dorado macizo al crema macizo, y ese salto de
       color era el que hacía el brillo tan aparatoso. Ahora el degradado no pinta
       fondo: solo añade un velo de crema al 26% justo en el punto de luz, y el
       dorado que se ve por debajo es SIEMPRE el background-color. El resultado es
       un reflejo tenue que recorre el círculo, no una banda clara cruzándolo.

       Para bajarlo o subirlo, ese 0.26 es el único número que hay que tocar.

       ⚠ LOS EXTREMOS SON rgba(…, 0) Y NO `transparent`. Son el mismo color con
       alfa 0, y se escribe así a propósito: `transparent` es negro transparente, y
       algunos navegadores interpolan hacia él ensuciando el degradado con un gris
       a medio camino. Con el crema a alfa 0 se interpola crema con crema y la
       transición queda limpia. 234,229,216 es --ga-naranja-claro (#eae5d8).

       El fondo dorado sigue puesto en background-color: si el degradado no llegara
       a aplicarse, el círculo se queda dorado macizo y no se rompe nada.

       ⚠ NO SE PISA CON EL HOVER: aquel cambia transform y box-shadow, y esto solo
       background-position. Pueden convivir sin tocarse. */
    background-image: linear-gradient(
        100deg,
        rgba(234, 229, 216, 0) 0%,
        rgba(234, 229, 216, 0) 45%,
        rgba(234, 229, 216, 0.26) 50%,
        rgba(234, 229, 216, 0) 55%,
        rgba(234, 229, 216, 0) 100%
    );
    background-size: 250% 100%;
    background-repeat: no-repeat;
    background-position: 100% center;
    animation: ga-home-card-brillo 8s linear infinite;
    animation-delay: var(--ga-comopedir-destello);
}

/* ——— HOVER: EL MISMO GESTO DE LOS PASOS DE LA PÁGINA DE EVENTOS ———
   La escala es la calcada: scale(1.09), el mismo 9% y la misma transición que
   .ga-main--eventos .ga-eventos-paso__num:hover, para que el gesto se sienta
   idéntico en los dos sitios.

   🔴 LA SOMBRA SÍ CAMBIA, Y NO PODÍA NO HACERLO. Allí es --ga-shadow-md, que es un
   verde oliva translúcido pensado para caer sobre fondo blanco; sobre esta banda
   —que es exactamente ese mismo verde— sería invisible: una sombra oscura sobre un
   fondo oscuro no existe. Lo que despega un elemento de un fondo oscuro es luz, no
   sombra, así que aquí el halo es del DORADO del propio círculo, difuminado y sin
   desplazamiento vertical para que se reparta a su alrededor como un resplandor.
   199,168,98 es --ga-naranja-apagado (#c7a862); va en rgba porque una variable de
   color no puede llevar transparencia sola.

   🔴 NI width, NI height, NI padding, NI MÁRGENES. Solo escala y sombra, que son
   propiedades de PINTADO: no participan en la maquetación, así que el título y la
   frase de debajo no se mueven ni un píxel y los otros dos círculos ni se enteran
   —el selector es :hover sobre el círculo concreto, no sobre el paso ni la lista—.

   Tampoco puede desbordar en horizontal: el círculo mide como mucho 60px, va
   centrado con margin auto en una columna que en el peor caso —360px, una sola
   columna— tiene 328px, así que los 2,7px que gana por cada lado se quedan muy
   dentro. Y aunque no fuera así, un transform no amplía el ancho de maquetación.

   Sin :focus-visible: el <span> no es enfocable —no es un enlace ni un botón, no
   lleva a ninguna parte—, así que no hay recorrido de teclado que atender aquí. */
.ga-eventos-comopedir__num:hover {
    transform: scale(1.09);
    box-shadow: 0 0 20px 4px rgba(199, 168, 98, 0.35);
}

/* ——— AHORRO DE MOVIMIENTO ———
   Sin escala, sin transición y SIN BRILLO. Al círculo y a la línea se les retira
   el degradado además de parar la animación: con la animación parada el degradado
   se quedaría congelado a mitad de recorrido y les dejaría una banda clara fija
   atravesada, que es peor que no tener brillo. Quitándolo, cada uno se queda con
   su background-color de siempre —el círculo dorado macizo, la línea en su dorado
   rebajado— y se ven exactamente igual que antes de que existiera el efecto.

   La sombra del hover SÍ se mantiene: no es movimiento, y es lo que le deja al
   hover una respuesta visual. Mismo criterio que en la página de Eventos. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-comopedir__num {
        transition: none;
        background-image: none;
        animation: none;
    }

    .ga-eventos-comopedir__num:hover {
        transform: none;
    }

    .ga-eventos-comopedir__paso:not(:last-child)::before {
        background-image: none;
        animation: none;
    }
}

/* Crema PLENO, escrito aquí y no heredado: es un <h3> y le llegaría el verde
   oscuro de la regla general de encabezados (ver el aviso de más arriba). */
.ga-eventos-comopedir__paso-titulo {
    margin: 0 0 var(--ga-space-xs);
    font-family: var(--ga-font-display);
    font-size: clamp(1.1rem, 1.4vw, 1.3rem);
    font-weight: 600;
    line-height: 1.25;
    color: var(--ga-naranja-claro);
    /* Reparte las líneas de largo parecido: en un título corto y centrado queda
       mejor que llenar la primera línea hasta el borde. */
    text-wrap: balance;
    overflow-wrap: break-word;
}

/* ——— LA FRASE SE DIFERENCIA POR COLOR, NO POR OPACIDAD ———
   Iba en el mismo crema que el título, apenas rebajado, y las dos líneas se leían
   como una sola masa de texto. Ahora va en --ga-amarillo-pastel (#c3c4aa), el
   verde pálido de la paleta: sobre el verde oscuro se lee claramente como un
   subtítulo —es otro tono, no el mismo más flojo— y sigue dando 5,0:1 de
   contraste, por encima del 4,5:1 que se le pide a un texto de este tamaño. El
   título se queda en el crema (7,1:1), así que la jerarquía entre los dos es de
   COLOR además de tipografía.

   🔴 Y SE LE QUITA LA OPACIDAD, no se le baja. Apagar un texto claro sobre fondo
   oscuro lo empuja hacia el fondo muy deprisa —esta sección ya se quedó ilegible
   una vez por fiarse de eso—. Ahora la diferencia la hace el tono a plena
   intensidad, que es lo que no puede volverse ilegible.

   El color va escrito y no heredado: es un <p> y le llegaría el verde oscuro de la
   regla general de párrafos (ver el aviso del principio del bloque). */
.ga-eventos-comopedir__paso-texto {
    margin: 0;
    font-family: var(--ga-font-body);
    font-size: clamp(0.93rem, 1.05vw, 1.05rem);
    line-height: 1.75;
    color: var(--ga-amarillo-pastel);
    text-wrap: pretty;
    overflow-wrap: break-word;
}


/* ——— MÓVIL ESTRECHO (<=640px) ———
   El mismo escalón de relleno que las demás secciones de la ficha, para no romper
   su ritmo vertical. Aquí la lista ya va en una sola columna —solo se pone en fila
   desde 769px—, así que a 360px cada paso dispone de los 328px del contenedor y no
   hay forma de que una fila desborde. */
@media (max-width: 640px) {

    .ga-eventos-comopedir {
        padding-block: var(--ga-space-lg);
    }
}


/* =============================================================================
   EVENTOS — VALORACIONES REALES EN LA FICHA (ficha de producto)
   =============================================================================
   La ficha de Eventos incluye template-parts/home-opiniones.php, el MISMO
   bloque de opiniones de la home, así que hereda todo su aspecto sin una regla
   nueva: los selectores .ga-opiniones no van acotados a la home.

   Lo único que hay que corregir es el espaciado del contenedor. En la home ese
   bloque cierra la página y por eso nace con `padding: 0 0 8rem`: sin nada
   arriba —se apoya en la sección anterior— y con mucho aire abajo, que es el
   final del documento. En la ficha, en cambio, va ENTRE dos secciones: sin
   relleno superior chocaría con la de arriba, y 8rem por debajo abriría un
   hueco enorme antes de la siguiente.

   Se le pone el mismo padding vertical que gastan las demás secciones de la
   ficha. Acotado con .ga-product-single--eventos, la clase que la plantilla
   solo pone al <main> de estas fichas: la regla compartida no se toca y la home
   sigue exactamente igual.

   🔴 SIN RELLENO ABAJO, Y NO ES UN OLVIDO. Esta sección va entre el carrusel de
   "También te puede interesar" —que tiene fondo CREMA— y las preguntas
   frecuentes, que son BLANCAS igual que ella. Arriba, el cambio de color ya
   separa las dos bandas y cada una aporta su propio aire. Pero abajo, blanco
   contra blanco, los dos rellenos se sumarían: 4rem de esta más 4rem de las
   preguntas, 8rem de blanco seguido que se lee como un agujero, no como una
   separación. Dejándolo en cero, el hueco lo pone el relleno superior de las
   preguntas y las tres secciones respiran igual.
   ============================================================================= */

.ga-product-single--eventos .ga-opiniones {
    padding-top: var(--ga-space-xl);
    padding-bottom: 0;
}

@media (max-width: 640px) {

    .ga-product-single--eventos .ga-opiniones {
        padding-top: var(--ga-space-lg);
        padding-bottom: 0;
    }
}

/* ——— Y EN LAS FICHAS QUE NO SON DE EVENTOS ———
   Ahí el bloque va entre la tabla comparativa y el carrusel de "También te puede
   interesar". La comparativa es BLANCA, igual que este bloque: si los dos
   pusieran sus 4rem, quedarían 8rem de blanco seguido que se leen como un
   agujero. Y por debajo, el carrusel es CREMA y ya trae su propio relleno
   superior. Así que aquí el bloque no pone relleno ninguno: el aire se lo dan
   los vecinos, y las tres secciones respiran igual.

   El :not() lo deja fuera de las fichas de Eventos, que conservan la regla de
   arriba tal cual. Los dos selectores nunca casan a la vez. */
.ga-product-single:not(.ga-product-single--eventos) .ga-opiniones {
    padding-block: 0;
}


/* =============================================================================
   EVENTOS — "TAMBIÉN TE PUEDE INTERESAR" (ficha de producto)
   =============================================================================
   Carrusel compacto con el catálogo de la tienda normal.

   ⚠ CORRECCIÓN DE UN COMENTARIO QUE ESTABA MAL. Aquí ponía que esta sección se
   pintaba "SOLO en los productos de la categoría Eventos". NO ES CIERTO: la
   plantilla la saca en TODAS las fichas de producto —su única condición es que la
   consulta haya devuelto algo—, y no existe ninguna otra sección de relacionados
   para el resto de la tienda. Las clases se llaman .ga-eventos-rel porque el
   bloque nació en Eventos, y de ahí venía la confusión.

   Consecuencia práctica, y es importante: TODO LO DE ESTE BLOQUE ES COMPARTIDO.
   Tocar cualquiera de estas reglas cambia también las fichas normales. Lo que solo
   deba afectar a Eventos va al final del bloque, acotado con
   .ga-product-single--eventos.

   🔴 MARCO QUE RECORTA + PISTA QUE SE MUEVE CON transform. Es el mecanismo del
   carrusel de la tienda, y va así por las dos trampas documentadas:
     · Una fila real más ancha que el viewport contenida con overflow-x: auto
       INFLA el viewport de maquetación en móvil y anula los media queries
       (🪤 nº 1). Un transform no amplía el ancho de maquetación.
     · `clip` recorta igual que `hidden` pero NO convierte al marco en contenedor
       de scroll, así que no atrapa el gesto táctil (🪤 nº 3).
   ============================================================================= */

/* FONDO BLANCO, y sin relleno abajo. Las secciones que la rodean —el bloque de
   opiniones y las preguntas frecuentes— también son blancas: si esta pusiera sus
   4rem inferiores y la siguiente sus 4rem superiores, quedarían 8rem de blanco
   seguido que se leen como un agujero, no como una separación. Dejando el de
   abajo en cero, el hueco lo pone siempre el relleno superior del vecino y todas
   las bandas blancas respiran igual, sin cortes de color ni franjas. */
.ga-eventos-rel {
    padding-top: var(--ga-space-xl);
    padding-bottom: 0;
    background-color: var(--ga-blanco);
}

.ga-eventos-rel__marco {
    overflow: clip;
}

@supports not (overflow: clip) {
    .ga-eventos-rel__marco {
        overflow: hidden;
    }
}

/* La pista es la fila que se desplaza. touch-action: pan-y pinch-zoom deja
   pasar el desplazamiento vertical de la página y conserva el zoom del usuario;
   el arrastre horizontal lo gestiona el JS sin llamar nunca a preventDefault. */
.ga-eventos-rel__pista {
    display: flex;
    gap: var(--ga-space-sm);
    margin: 0;
    padding: 0;
    list-style: none;
    touch-action: pan-y pinch-zoom;
    transition: transform var(--ga-transition-slow);
}

/* CUATRO TARJETAS a la vista en escritorio. flex-basis explícito y no min-width:
   min-width solo es un suelo y aquí haría falta que encogieran (🪤 del carrusel
   móvil de la tienda). El calc descuenta los huecos que quedan entre ellas. */
/* TODAS LAS TARJETAS, DEL MISMO ANCHO Y DEL MISMO ALTO.
   El ancho lo fija el flex-basis. El alto sale de una cadena de tres pasos:
     1. La celda es un elemento flex de la pista, que por defecto va en
        align-items: stretch, así que TODAS miden lo que la más alta.
     2. La celda es a su vez flex, de modo que la tarjeta de dentro se estira a
        ese alto en vez de quedarse con el de su contenido.
     3. La tarjeta se reparte en columna y el NOMBRE se queda con el espacio
        sobrante, así que el precio y el botón caen siempre al fondo.
   Resultado: la foto arranca a la misma altura en todas y el precio y el botón
   terminan a la misma altura en todas, ocupe el nombre una línea o dos. Y sin
   una sola altura escrita a mano, que es lo que se descuadraría al cambiar un
   texto o el ancho de la pantalla. */
.ga-eventos-rel__celda {
    flex: 0 0 calc((100% - 3 * var(--ga-space-sm)) / 4);
    max-width: calc((100% - 3 * var(--ga-space-sm)) / 4);
    margin: 0;
    display: flex;
}

.ga-eventos-rel__tarjeta {
    display: flex;
    flex-direction: column;
    width: 100%;
    box-sizing: border-box;
    padding: var(--ga-space-sm);
    text-align: center;
    background-color: var(--ga-blanco);
    border: 1px solid var(--ga-amarillo-pastel);
    border-radius: var(--ga-radius-md);
    /* El borde existe ya en reposo y solo cambia de color: ningún estado altera
       el tamaño ni desplaza a las tarjetas vecinas. */
    transition: border-color var(--ga-transition-normal);
}

/* El borde se enciende al pasar por cualquiera de los enlaces de la tarjeta, no
   solo por el que se toca: así sigue leyéndose como una pieza entera. */
.ga-eventos-rel__tarjeta:hover,
.ga-eventos-rel__tarjeta:focus-within {
    border-color: var(--ga-naranja-apagado);
}

.ga-eventos-rel__foto-enlace {
    display: block;
    text-decoration: none;
}

/* La foto manda el alto con su proporción, así que la fila tiene su medida
   reservada desde el principio y no da saltos mientras cargan las imágenes. */
.ga-eventos-rel__foto {
    display: block;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    background-color: var(--ga-naranja-claro);
    border-radius: var(--ga-radius-sm);
}

.ga-eventos-rel__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* 🔴 EL NOMBRE SE QUEDA CON EL ESPACIO SOBRANTE (flex: 1). Es lo que empuja el
   precio y el botón al fondo de la tarjeta y los deja a la misma altura en
   todas, aunque un nombre ocupe una línea y otro dos. Nada de min-height.

   Y nada de text-overflow: ellipsis en un nombre de producto: envuelve, y
   overflow-wrap solo entra con palabras que no quepan enteras. */
.ga-eventos-rel__nombre {
    flex: 1 1 auto;
    margin: 0.6rem 0 0;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;
    color: var(--ga-verde-oliva-oscuro);
    overflow-wrap: break-word;
}

/* El enlace del nombre hereda color y tipografía: el <h3> ya los pone. */
.ga-eventos-rel__nombre a {
    color: inherit;
    text-decoration: none;
    transition: color var(--ga-transition-normal);
}

.ga-eventos-rel__nombre a:hover,
.ga-eventos-rel__nombre a:focus-visible {
    color: var(--ga-naranja-apagado);
    text-decoration: none;   /* Astra subraya los enlaces al pasar por encima */
}

.ga-eventos-rel__precio {
    display: block;
    margin-top: 0.25rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    color: var(--ga-verde-montanas);
}

/* EL BOTÓN, AL FONDO Y A LO ANCHO. Hereda el estilo de .ga-btn--outline-dark
   --sm, el mismo de las tarjetas de producto del resto de la web; aquí solo se
   ajusta lo que hace falta para una tarjeta estrecha:

   🔴 white-space: normal anula el nowrap de .ga-btn. Con el nowrap, a 360px
   —donde la tarjeta se queda en unos 137px útiles— "VER PRODUCTO" no cabe en una
   línea y se salía de la caja. Pudiendo partir, envuelve y no desborda.

   El margen superior es `auto`: es lo que lo pega abajo del todo cuando la
   tarjeta es más alta que su contenido. */
.ga-eventos-rel__btn {
    margin-top: var(--ga-space-sm);
    padding-inline: 0.6rem;
    white-space: normal;
}

.ga-eventos-rel__precio del {
    opacity: 0.6;
    margin-right: 0.3rem;
}

.ga-eventos-rel__precio ins {
    text-decoration: none;
    font-weight: var(--ga-weight-medium);
    color: var(--ga-naranja-apagado);
}


/* ——— TABLET (<=1024px): TRES A LA VISTA ——— */
@media (max-width: 1024px) {

    .ga-eventos-rel__celda {
        flex: 0 0 calc((100% - 2 * var(--ga-space-sm)) / 3);
        max-width: calc((100% - 2 * var(--ga-space-sm)) / 3);
    }
}


/* ——— MÓVIL (<=768px): DOS A LA VISTA ———
   A 360px: la columna deja unos 328px, el hueco es 1rem y cada tarjeta se queda
   en unos 156px. Ni el nombre ni el precio imponen ancho mínimo —llevan
   overflow-wrap—, así que la pista encoge con ellas y no hay desbordamiento
   horizontal. */
@media (max-width: 768px) {

    /* Abajo sigue en cero por el mismo motivo que en escritorio: el vecino
       blanco pone el hueco con su relleno superior. */
    .ga-eventos-rel {
        padding-top: var(--ga-space-lg);
        padding-bottom: 0;
    }

    .ga-eventos-rel__celda {
        flex: 0 0 calc((100% - var(--ga-space-sm)) / 2);
        max-width: calc((100% - var(--ga-space-sm)) / 2);
    }

    .ga-eventos-rel__tarjeta {
        padding: 0.6rem;
    }
}


/* ——— MOVIMIENTO REDUCIDO ———
   Sin transición: el JS tampoco arranca el giro automático, así que el carrusel
   se queda quieto en la primera tarjeta y solo se mueve si se arrastra. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-rel__pista {
        transition: none;
    }
}


/* -----------------------------------------------------------------------------
   SOLO EN LAS FICHAS DE EVENTOS — SIN MARCO Y CON MÁS PRODUCTOS A LA VISTA
   -----------------------------------------------------------------------------
   🔴 ESTA SECCIÓN ES COMPARTIDA CON TODA LA TIENDA. El bloque de arriba lo pinta
   la misma plantilla en TODAS las fichas —no solo en las de Eventos, pese a lo
   que decía el comentario de su cabecera—, así que aquellas reglas NO se pueden
   editar sin cambiar también el aspecto de las fichas normales. Lo de aquí abajo
   se limita a sobrescribirlas, y va acotado con .ga-product-single--eventos, la
   clase que el <main> solo lleva en esta categoría: puntúa 0-2-0 frente al 0-1-0
   de las compartidas, así que gana por especificidad y no por orden de aparición
   —ni siquiera a las que viven dentro de sus media queries—. Fuera de Eventos no
   cambia absolutamente nada.

   EL MECANISMO DEL CARRUSEL NO SE TOCA: el marco que recorta con overflow: clip y
   la pista que se mueve con transform ya estaban, y son los del carrusel de la
   tienda (🪤 nº 1 y nº 3). El giro automático, el arrastre táctil con detección de
   dirección, la pausa con el ratón encima y el respeto a prefers-reduced-motion
   los resuelve gaEventosRelacionados() en assets/js/main.js, que mide el ancho de
   paso leyéndolo del DOM: al cambiar aquí cuántas tarjetas caben, el JS se adapta
   solo y no ha hecho falta tocar una línea.
   ----------------------------------------------------------------------------- */

/* FUERA LA CAJA. Sin recuadro, sin fondo propio y sin relleno: la foto, el nombre
   y el precio se apoyan directamente sobre el blanco de la sección.

   El :hover del borde que hay más arriba se queda en nada —un borde de 0 no tiene
   color que cambiar— y no hace falta sustituirlo: el nombre ya se pone dorado al
   pasar por encima con su propia regla, que es un cambio de COLOR y no mueve
   nada. */
.ga-product-single--eventos .ga-eventos-rel__tarjeta {
    padding: 0;
    background-color: transparent;
    border: 0;
}

/* Sin marco alrededor, la que da forma a la tarjeta es la foto: se le sube el
   redondeo del pequeño al medio para que la esquina acompañe.

   ——— EL RECUADRO DE LA FOTO, EN BLANCO ———
   La regla compartida le pone el crema de marca (--ga-naranja-claro). Aquí pasa a
   blanco porque hay dos productos —la mermelada y el aceitunero— cuya foto viene
   SIN FONDO, con el PNG transparente: en ellos ese crema se colaba por detrás del
   producto y se veía un rectángulo de otro color en mitad de la fila.

   🔴 SE CAMBIA EL RECUADRO DE LA FOTO, NO EL FONDO DE LA SECCIÓN. La sección ya es
   blanca; el crema salía de este recuadro y solo de él. Tocar el fondo de la
   sección no habría arreglado nada y sí habría movido el ritmo de bandas de la
   ficha.

   ⚠ A LOS PRODUCTOS QUE SÍ TRAEN FONDO NO LES AFECTA, y no es casualidad: la <img>
   va con object-fit: cover a width y height del 100%, así que CUBRE el recuadro
   entero y no deja ver ni un píxel de lo que hay detrás. Este color solo se asoma
   por donde la imagen es transparente, que es justo el caso que se quería
   arreglar. */
.ga-product-single--eventos .ga-eventos-rel__foto {
    background-color: var(--ga-blanco);
    border-radius: var(--ga-radius-md);
}

/* ——— LA BOTELLA DE 500 ML, AL TAMAÑO DE LAS DEMÁS ———
   CAUSA, y no era del CSS: esa foto trae MÁS AIRE ALREDEDOR que las otras. Cada
   producto está fotografiado con su propio encuadre, y en esta la botella ocupa
   menos parte del cuadro, así que a igual escala se ve más chica aunque el
   recuadro mida exactamente lo mismo que el de al lado. No es resolución ni
   object-fit: con `cover` la imagen SIEMPRE llena el recuadro; lo que se queda
   corto es la botella dentro de su propia foto.

   Ya está diagnosticado y resuelto así en otro sitio del tema: la sección
   "Nuestros Aceites" de la home tiene esta misma corrección para este mismo SKU
   (.ga-home-card--sku-ga-bell-500-oct, con scale 1.35). Aquí hace falta bastante
   menos porque allí la foto va con object-fit: contain —se ve entera, con todo su
   aire— y en este carrusel va con `cover`, que ya recorta parte de ese margen.

   Se escala SOLO la <img> con transform: el recuadro, la tarjeta y la fila no
   cambian de tamaño ni se mueven, y el overflow: hidden que ya tiene el recuadro
   contiene el escalado, así que lo único que se recorta es aire. Ningún estado de
   hover toca esta imagen.

   La clase sale del SKU real del producto (la pinta la plantilla), no de un id ni
   de un slug escritos a mano: si mañana se sube una foto mejor encuadrada, se
   borra esta regla y ya está.

   ⚠ EL 1.18 ES UNA ESTIMACIÓN Y PUEDE PEDIR UN RETOQUE. No he podido medirlo en un
   navegador; está calculado a partir del 1.35 que necesita la home descontando lo
   que ya recorta el `cover`. Es UN SOLO NÚMERO: si se ve grande o pequeña, se sube
   o se baja aquí y no hay que tocar nada más. */
.ga-product-single--eventos .ga-eventos-rel--sku-ga-bell-500-oct .ga-eventos-rel__img {
    transform: scale(1.18);
}

/* ——— CUÁNTAS SE VEN: SE VUELVE A LO COMPARTIDO ———
   Aquí había dos media queries que subían la cuenta a SEIS en escritorio y CUATRO
   en tablet. Con seis, la tarjeta se quedaba en unos 186px y la foto salía
   diminuta, así que se han BORRADO las dos: sin ellas, las fichas de Eventos usan
   la misma cuenta que el resto de la tienda —cuatro en escritorio, tres en tablet
   y dos en móvil—, que es justo lo que se pedía. La tarjeta pasa de ~186px a
   ~266px: un 43% más de foto, y sigue habiendo más productos de los que caben, así
   que el carrusel se sigue leyendo como carrusel.

   No hacía falta escribir nada nuevo para conseguirlo: quitar el código que
   sobraba deja el comportamiento correcto. Si algún día se quisieran TRES en
   escritorio —foto aún más grande—, es una media query nueva aquí con /3, sin
   tocar lo compartido.

   El movimiento tampoco necesita ajustes: gaEventosRelacionados() mide el ancho de
   paso leyéndolo del DOM y cuántas caben dividiendo por él, así que se ha adaptado
   solo. */

/* ——— SIN NOMBRE, EL BOTÓN SE PEGA ABAJO ———
   En Eventos la tarjeta ya no lleva el <h3> del nombre, que era quien se quedaba
   con el espacio sobrante (flex: 1) y empujaba el botón al fondo. Sin él, el
   margen `auto` hace ese trabajo: las tarjetas siguen midiendo todas lo mismo por
   el stretch de la pista, y el botón termina a la misma altura en las cuatro
   aunque un precio ocupe dos líneas por llevar rebaja. */
.ga-product-single--eventos .ga-eventos-rel__btn {
    margin-top: auto;

    /* ——— DORADO EN REPOSO Y ESQUINAS REDONDEADAS ———
       El botón hereda .ga-btn--outline-dark, que lo deja con el borde y el texto en
       VERDE oliva. En Eventos va en el DORADO de marca, que es el color con el que
       se acentúa toda la ficha —los círculos de los pasos, la línea que los une, la
       etiqueta del contacto—, y así el carrusel deja de ser la única pieza verde
       suelta al final de la página.

       .ga-btn declara border-radius: 0 a propósito ("estilo recto, más elegante")
       para toda la web. Aquí se le da --ga-radius-md, que es EXACTAMENTE el mismo
       radio que ya tiene la foto justo encima en esta misma tarjeta: el botón y la
       imagen curvan igual y la tarjeta se lee como una pieza. (El otro candidato
       era --ga-radius-sm, el del botón grande de la página de Eventos; se descartó
       por quedar casi recto y no cumplir el encargo de que se note.)

       Solo aquí: en las fichas que no son de Eventos el botón sigue verde y recto.

       El borde ya existe en reposo y son 2px en los dos estados —lo pone .ga-btn—,
       así que al pasar el ratón NO cambia el grosor y la tarjeta no se mueve. */
    color: var(--ga-naranja-apagado);
    border-color: var(--ga-naranja-apagado);
    background-color: transparent;
    border-radius: var(--ga-radius-md);
}

/* HOVER Y FOCO: verde macizo con las letras en blanco. Cambia SOLO el color de
   fondo, el del borde y el del texto; ni el grosor del borde, ni el relleno, ni el
   tamaño de letra, así que no se mueve nada de la fila.

   El :focus-visible va con el hover para que quien navegue con el teclado vea lo
   mismo que quien usa el ratón. 0-3-0, por encima del 0-2-0 de
   .ga-btn--outline-dark:hover, así que gana por especificidad y no por orden. */
.ga-product-single--eventos .ga-eventos-rel__btn:hover,
.ga-product-single--eventos .ga-eventos-rel__btn:focus-visible {
    background-color: var(--ga-verde-oliva-oscuro);
    border-color: var(--ga-verde-oliva-oscuro);
    color: var(--ga-blanco);
}

/* ——— EL PRECIO, CENTRADO Y CON AIRE ———
   Quedaba pegado al borde de abajo de la foto, con solo 0,25rem de separación, y
   sin el nombre del producto delante no había nada que lo despegara.

   El text-align va ESCRITO aquí y no heredado de la tarjeta. El precio lo genera
   WooCommerce (wc_price → <span class="woocommerce-Price-amount"><bdi>…), y ese
   marcado suyo lo pueden alcanzar reglas de WooCommerce o de Astra con más
   especificidad que la herencia, que no tiene ninguna. Escribiéndolo en la clase
   propia, el centrado no depende de que nadie más lo respete.

   Y el mismo margen arriba que abajo, así que el precio queda a media altura entre
   la foto y el botón en vez de colgando de la foto. El botón lleva margin-top:auto,
   de modo que el sobrante de la tarjeta se reparte por debajo del precio y las
   cuatro siguen terminando a la misma altura. */
.ga-product-single--eventos .ga-eventos-rel__precio {
    /* ARRIBA POCO, ABAJO MÁS. Con 1rem por los dos lados el precio se quedaba
       flotando lejos de su foto y parecía de la tarjeta de abajo. Ahora sube
       pegado a la imagen —--ga-space-xs, medio rem— y el hueco grande se lo queda
       el lado de abajo, que es el que lo separa del botón. El botón lleva
       margin-top: auto, así que además recoge el sobrante de la tarjeta. */
    margin-top: var(--ga-space-xs);
    margin-bottom: var(--ga-space-sm);
    text-align: center;
}


/* ——— LAS FLECHAS, A LOS LADOS DEL CARRUSEL ———
   ═══════════════════════════════════════════════════════════════════════════
   La zona envuelve al marco y es su referencia de posición. Mide exactamente lo
   mismo que el carrusel, así que una flecha anclada a left: 0 o a right: 0 cae
   sobre el borde de la primera o la última foto y NO PUEDE SALIRSE del ancho de
   la sección: no hay desbordamiento horizontal posible en ningún ancho.

   Y al ir en position:absolute no ocupan sitio en el flujo, así que no le quitan
   ni un píxel de ancho a las tarjetas. Eso importa a 360px, donde no sobra nada.

   🔴 EL CENTRADO VERTICAL LO CALCULA EL JS, y no es un capricho. La flecha tiene
   que ir a media altura de la FOTO, pero la tarjeta lleva debajo el precio y el
   botón: su centro cae mucho más abajo que el de la imagen, así que un
   `top: 50%` las dejaría sobre el precio. Y la altura de la foto no se puede
   escribir aquí porque es la de una tarjeta, que cambia con el ancho de la
   ventana y con cuántas se ven en cada breakpoint.

   gaEventosRelacionados() mide la primera foto y escribe la mitad de su alto en
   --ga-ev-rel-centro; el resto lo hace el translateY(-50%). El 35% es el respaldo
   por si el JS no llegara a correr: cae dentro de la foto en cualquier caso, así
   que la flecha nunca aparece en un sitio absurdo.

   El translateY es FIJO: no lo toca ningún estado, así que el hover no mueve la
   flecha.

   ═══════════════════════════════════════════════════════════════════════════
   🔴 EL HUECO DE LAS FLECHAS SE HACE CON padding, NO CON left NEGATIVO.
   ═══════════════════════════════════════════════════════════════════════════
   Las flechas tienen que quedar FUERA del carrusel, sin pisar la primera ni la
   última foto. La forma obvia —sacarlas con left/right negativos— es justo la que
   no vale: las empujaría fuera de .ga-container, y ahí el margen disponible es el
   relleno del contenedor, que a 360px son 16px y no caben. Se saldrían de la
   sección, y con el overflow-x: hidden del body no habría barra que avisara: se
   verían cortadas.

   En vez de eso, la ZONA se reserva un carril a cada lado con padding-inline. El
   marco es un hijo en flujo, así que se encoge para dejarle ese sitio, y las
   flechas —que se posicionan contra el borde INTERIOR del padding— caen en ese
   carril: fuera de las fotos y, por construcción, dentro del ancho de la sección.
   No hay ancho de pantalla en el que puedan desbordar.

   El carril mide la flecha (2,25rem: 20px de icono + 0,5rem de relleno por lado)
   más --ga-space-xs de aire hasta la primera foto.

   ⚠ EL RELLENO VA ACOTADO A EVENTOS. La zona se pinta en TODAS las fichas, pero
   las flechas solo en las de esta categoría: si el padding fuera a la regla base,
   el carrusel de las fichas normales se estrecharía 5,5rem para dejar sitio a dos
   botones que allí no existen. */
.ga-eventos-rel__zona {
    position: relative;
}

.ga-product-single--eventos .ga-eventos-rel__zona {
    --ga-ev-rel-flecha: 2.25rem;

    padding-inline: calc(var(--ga-ev-rel-flecha) + var(--ga-space-xs));
}

/* ——— EN TÁCTIL NO HAY FLECHAS, Y POR TANTO TAMPOCO CARRIL ———
   Se decide por la CAPACIDAD del dispositivo y no por el ancho, igual que en la
   cuadrícula de botellas de la columna izquierda: una flecha es una herramienta de
   ratón, y en un móvil el carrusel ya se pasa arrastrando con el dedo.

   Y hay un motivo de espacio además del de uso: en un móvil de 360px el carril se
   comería 88px de los 328px útiles y las dos tarjetas visibles se quedarían en
   112px, donde el botón "Ver producto" no tiene sitio. Retirando las flechas, la
   tarjeta recupera sus ~156px de siempre. */
@media (hover: none) {

    .ga-product-single--eventos .ga-eventos-rel__zona {
        padding-inline: 0;
    }

    /* ⚠ ACOTADA CON .ga-product-single--eventos, Y NO POR COSTUMBRE: hace falta
       para GANAR. Una media query no suma especificidad, y la regla base de la
       flecha —que le pone display: inline-flex— viene MÁS ABAJO en el archivo. A
       igual puntuación mandaría la última, así que un `.ga-eventos-rel__flecha` a
       secas aquí no ocultaría nada. Con el ancestro delante puntúa 0-2-0 y gana
       esté donde esté. */
    .ga-product-single--eventos .ga-eventos-rel__flecha {
        display: none;
    }
}

/* 🔴 !important EN FONDO, BORDE Y SOMBRA. Esto es un <button> dentro de una página
   de WooCommerce, y Astra los captura con reglas como `.woocommerce button` que
   ganan en especificidad a cualquier clase propia y les meten su fondo, su borde y
   su relleno de botón (🪤 nº 6). Sin esto, las flechas saldrían como dos botones
   macizos en vez de como dos iconos.

   El color NO lleva !important: es lo único que tiene que poder cambiar en hover y
   en foco, y las reglas de abajo lo hacen con más especificidad. */
.ga-eventos-rel__flecha {
    position: absolute;
    z-index: 2;
    top: var(--ga-ev-rel-centro, 35%);
    transform: translateY(-50%);

    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* MISMA MEDIDA QUE EL CARRIL, leída de la MISMA variable: así el hueco que abre
       la zona y lo que ocupa la flecha no pueden descuadrarse. Con border-box, los
       2,25rem incluyen el relleno (20px de icono + 0,5rem por lado = 36px exactos). */
    box-sizing: border-box;
    width: var(--ga-ev-rel-flecha, 2.25rem);
    height: var(--ga-ev-rel-flecha, 2.25rem);
    padding: var(--ga-space-xs) !important;
    /* SIN FONDO. Ya no hace falta ninguno: la flecha ha salido de encima de las
       fotos y se apoya en el blanco de la sección, donde el icono solo se lee sin
       ayuda. Los tres !important son contra Astra, que a los <button> de una página
       de WooCommerce les mete su fondo, su borde y su sombra (🪤 nº 6); sin ellos
       volvería a aparecer un botón macizo. */
    background: none !important;
    border: 0 !important;
    box-shadow: none !important;
    cursor: pointer;
    /* DORADO EN REPOSO: el color con el que se acentúa toda la ficha. */
    color: var(--ga-naranja-apagado);
    /* Solo el color se anima: ni tamaño, ni posición, ni sombra. */
    transition: color var(--ga-transition-normal);
}

/* Una a cada lado, pegadas al borde INTERIOR del carril que abre el padding de la
   zona: quedan por fuera de la primera y la última foto, sin taparlas, y dentro
   del ancho de la sección. Sin valores negativos, así que no pueden desbordar. */
.ga-eventos-rel__flecha--prev {
    left: 0;
}

.ga-eventos-rel__flecha--next {
    right: 0;
}

/* Hover, foco y pulsación: SOLO cambia el color del icono, al dorado de marca. No
   se toca el relleno ni el tamaño, así que la fila no se mueve un píxel. Los tres
   estados se declaran juntos —y con el fondo anulado otra vez— porque Astra tiene
   su propia regla para cada uno y volvería a meter el suyo en cuanto se pasa el
   ratón o se llega con el tabulador. */
/* HOVER, FOCO Y PULSACIÓN: del dorado al verde de marca. Cambia SOLO el color del
   icono; el fondo sigue sin existir y el relleno es el mismo, así que la flecha no
   cambia de tamaño ni se mueve un píxel. Los tres estados se declaran juntos —y
   con el fondo anulado otra vez— porque Astra tiene una regla para cada uno y
   volvería a meter el suyo en cuanto se pasa el ratón o se llega con el tabulador. */
.ga-eventos-rel__flecha:hover,
.ga-eventos-rel__flecha:focus,
.ga-eventos-rel__flecha:focus-visible,
.ga-eventos-rel__flecha:active {
    background: none !important;
    border: 0 !important;
    box-shadow: none !important;
    color: var(--ga-verde-oliva-oscuro) !important;
}

/* El contorno de foco solo para quien navega con el teclado, y por fuera del
   botón: no ocupa sitio, así que tampoco desplaza nada. */
.ga-eventos-rel__flecha:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 3px;
}

.ga-eventos-rel__flecha:focus:not(:focus-visible) {
    outline: none;
}

/* Ahorro de movimiento: el color cambia de golpe, sin transición. Las flechas
   siguen funcionando igual. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-rel__flecha {
        transition: none;
    }
}


/* =============================================================================
   EVENTOS — EL ORDEN DE LA FICHA EN MÓVIL (≤860px)
   =============================================================================
   En escritorio la ficha son dos columnas: a la izquierda la foto con la
   descripción, y a la derecha el nombre, el precio y el formulario. Al apilarse en
   móvil, ese reparto deja el nombre y el precio DESPUÉS de toda la columna de la
   foto, que no es el recorrido que se quiere.

   El orden que se busca en móvil es:
     1 antetítulo + nombre + precio      5 "Combínalas con otras del mismo tamaño"
     2 foto principal                    6 descripción corta
     3 "Ahora mismo disponible"          7 desplegable de la descripción larga
     4 formulario + añadir al carrito    8 sellos de confianza
   (y el bloque de contacto cierra, como hasta ahora)

   🔴 POR QUÉ HACE FALTA display: contents Y NO BASTA CON order.
   `order` solo reordena HERMANOS. La foto vive dentro de .ga-product__gallery y el
   nombre dentro de .ga-product__purchase: son primos, no hermanos, así que ningún
   `order` puede intercalarlos. Es exactamente el muro contra el que ya se chocó
   antes en esta ficha, y por el que la cuadrícula de botellas y el bloque de
   contacto se pintan DOS veces, con una copia 'esc' y otra 'mov'.

   display: contents disuelve las dos columnas SOLO en este breakpoint: sus cajas
   dejan de existir y sus hijos pasan a ser celdas de .ga-product__grid, que aquí
   ya es de una sola columna. Con todos en el mismo contenedor, `order` sí puede
   colocarlos uno a uno. No se duplica nada, no se mueve una línea de HTML y el
   formulario sigue siendo el mismo y único: cantidad, suplemento y validación
   intactos.

   ⚠ LAS DOS COLUMNAS PIERDEN SU `gap` al dejar de ser cajas (1rem la de la foto y
   1,25rem la de compra). Por eso se le pone aquí un row-gap al grid: si no, la
   separación entre bloques pasaría a ser la del grid, 2,5rem, y la ficha quedaría
   desparramada.

   ⚠ Y PIERDEN TAMBIÉN SU position: sticky, que en este ancho ya no pintaba nada
   —la columna ocupa todo el ancho— pero conviene saberlo.

   TODO ACOTADO CON .ga-product-single--eventos: las fichas que no son de Eventos
   se apilan como siempre. Y todo dentro del @media: en escritorio y tablet no se
   aplica ni una de estas reglas, así que las dos columnas siguen exactamente igual
   —nombre, precio y formulario a la derecha; foto, descripción y combinar a la
   izquierda—.
   ============================================================================= */

@media (max-width: 860px) {

    /* Las dos columnas se disuelven: sus hijos suben a ser celdas del grid. */
    .ga-product-single--eventos .ga-product__gallery,
    .ga-product-single--eventos .ga-product__purchase {
        display: contents;
    }

    /* La separación que antes ponía cada columna. */
    .ga-product-single--eventos .ga-product__grid {
        row-gap: var(--ga-space-sm);
    }

    /* 🔴 SUELO DE SEGURIDAD, Y VA EL PRIMERO A PROPÓSITO. El `order` por defecto es
       0, que es MENOR que todos los de abajo: cualquier bloque que se añada mañana
       a una de las dos columnas y no se enumere aquí se colaría EL PRIMERO de la
       ficha, por delante del nombre del producto. Con este 20 de partida ocurre lo
       contrario: lo que no esté en la lista cae al final, que es un fallo visible y
       sin consecuencias en vez de uno que descoloca la cabecera.

       Va con `> * > *` porque los hijos del grid son ahora los NIETOS: las columnas
       siguen ahí como elementos, aunque no generen caja. Misma especificidad que
       las reglas de abajo (0-2-0), así que gana la que venga después: por eso este
       bloque tiene que ir antes que la lista. */
    .ga-product-single--eventos .ga-product__grid > * > * {
        order: 20;
    }

    .ga-product-single--eventos .ga-product__cat-tag {
        order: 1;
    }

    .ga-product-single--eventos .ga-product__name {
        order: 2;
    }

    .ga-product-single--eventos .ga-product__price-wrap {
        order: 3;
    }

    .ga-product-single--eventos .ga-product__gallery-main {
        order: 4;
    }

    .ga-product-single--eventos .ga-product__stock {
        order: 5;
    }

    /* Las dos caras del mismo sitio: el formulario cuando hay existencias y el
       aviso de agotado cuando no. Nunca se pintan las dos. */
    .ga-product-single--eventos .ga-product__cart-form,
    .ga-product-single--eventos .ga-product__agotado {
        order: 6;
    }

    /* La copia de móvil de la cuadrícula de botellas; la de escritorio está en
       display:none en este ancho, así que ni ocupa sitio ni cuenta como celda. */
    .ga-product-single--eventos .ga-eventos-combina--mov {
        order: 7;
    }

    .ga-product-single--eventos .ga-eventos-desc {
        order: 8;
    }

    .ga-product-single--eventos .ga-eventos-desc-larga {
        order: 9;
    }

    .ga-product-single--eventos .ga-product__trust-band {
        order: 10;
    }

    /* El contacto cierra la ficha, igual que antes de reordenar. */
    .ga-product-single--eventos .ga-eventos-ctc--mov {
        order: 11;
    }
}


/* =============================================================================
   FICHA DE PRODUCTO — LOS DOS BOTONES DE COMPRA, EN FILA (todas las fichas)
   =============================================================================
   "Comprar ahora" a la IZQUIERDA como acción principal y "Añadir al carrito" a la
   derecha como secundaria, del mismo alto y repartiéndose el ancho.

   ⚠ ESTE BLOQUE NACIÓ ACOTADO A EVENTOS Y AHORA ES DE TODA LA TIENDA. Se generalizó
   cambiando el ancestro de los selectores: donde ponía .ga-product-single--eventos
   ahora pone .ga-product-single, que es la clase que el <main> lleva en TODAS las
   fichas de producto. No se ha duplicado nada ni se ha movido el bloque de sitio:
   una pareja de botones idéntica en dos sitios se habría quedado descuadrada a la
   primera que alguien retocara uno de los dos.

   🔴 EL CAMBIO DE ANCESTRO NO ALTERA NINGUNA ESPECIFICIDAD, que es lo que hacía
   delicada la operación: --eventos y a secas son las dos una sola clase, así que
   cada selector puntúa exactamente igual que antes. Eso importa porque estas
   reglas están aquí para ganarle a tres competidoras muy concretas:
     · .woocommerce .single_add_to_cart_button (0-2-0 y !important, en
       woocommerce.css, que además se encola DESPUÉS de este archivo)
     · .ga-btn--outline-dark:hover (0-2-0, en single-product.css)
     · .ga-btn--primary:hover y .ga-btn:active (0-2-0, más arriba en este archivo)
   Los selectores de aquí abajo siguen en 0-3-0 y 0-4-0, así que siguen ganando por
   especificidad y no por orden de archivos.

   Y las fichas de Eventos no cambian NADA: .ga-product-single--eventos siempre
   viene acompañada de .ga-product-single en el mismo <main>, de modo que todo lo
   que aplicaba antes sigue aplicando exactamente igual.

   LOS COLORES NO SE ESCRIBEN AQUÍ: ya los traen las clases de botón del tema.
   .ga-btn--primary es fondo dorado con letras blancas, y .ga-btn--outline-dark es
   fondo transparente con borde y letras en verde oliva. Son exactamente los dos
   estilos pedidos, así que el botón nuevo solo tiene que llevar la clase que le
   toca y aquí no se repinta nada.

   🔴 EL ORDEN VISUAL SE HACE CON `order`, NO CAMBIANDO EL HTML, y hay un motivo de
   comportamiento: cuando un formulario tiene varios botones de envío, al pulsar
   Intro dentro de un campo el navegador dispara EL PRIMERO DEL MARCADO. Si
   "Comprar ahora" fuera el primero, escribir el texto de la etiqueta y pulsar
   Intro llevaría directo a la pasarela de pago. Dejando "Añadir al carrito"
   primero en el HTML, Intro hace lo prudente, y el orden que se ve lo decide el
   CSS. (Contrapartida asumida: con el tabulador se llega antes al de la derecha.)

   La fila arranca a 560px y no antes: por debajo, los dos botones no caben en una
   línea —"AÑADIR AL CARRITO" en versalitas con su icono pide unos 180px de texto,
   y a 360px cada botón se quedaría con 94px—, y .ga-btn va en white-space: nowrap,
   así que no partiría: se saldría de la caja. Por debajo de 560px se apilan, que
   es lo previsto, y el `order` los deja en el orden correcto también apilados:
   "Comprar ahora" arriba y "Añadir al carrito" debajo.
   ============================================================================= */

/* ——— ESQUINAS REDONDEADAS ———
   .ga-btn declara border-radius: 0 para toda la web ("estilo recto, más elegante").
   Aquí se le da --ga-radius-md, el mismo valor que ya llevan los botones "Ver
   producto" del carrusel de esta misma ficha, para que todos los botones de una
   ficha de Eventos curven igual. Fuera de Eventos siguen rectos.

   El de "Añadir al carrito" NO va aquí: necesita !important y más especificidad
   por lo que se explica en su propio bloque, más abajo. */
.ga-product-single .ga-product__btn-buy-now {
    border-radius: var(--ga-radius-md);
}

.ga-product-single .ga-product__btn-buy-now {
    /* -1 lo pone por delante del de carrito, que la hoja de la ficha deja en 0. */
    order: -1;
}

/* ——— "COMPRAR AHORA": EL HOVER INVIERTE SUS PROPIOS COLORES ———
   .ga-btn--primary le da el dorado con letras blancas en reposo, que es lo que se
   quiere y no se toca. Lo que se cambia es el hover: la regla general lo lleva a
   --ga-marron-oscuro, y aquí se le da la vuelta al propio botón —blanco de fondo,
   dorado en el borde y en las letras—, que es el mismo gesto que hace el de
   "Añadir al carrito" con sus dos colores. Los dos botones se comportan igual y
   cada uno se queda con su pareja.

   🔴 EL BORDE ES LO QUE SOSTIENE EL BOTÓN EN HOVER. En reposo el filete dorado no
   se distingue porque el fondo es del mismo dorado; al invertir, el fondo pasa a
   blanco y ese mismo filete es lo único que dibuja la silueta. Por eso se le
   cambia el color pero NUNCA el grosor: son 2px en los dos estados —los pone
   .ga-btn— así que el botón no crece ni empuja a su vecino. Solo cambian tres
   colores.

   :focus-visible y :active van con el hover: con el teclado y al pulsar se ve lo
   mismo que con el ratón. 0-3-0, por encima del 0-2-0 de .ga-btn--primary:hover,
   así que gana por especificidad y no por orden de aparición.

   ⚠ Este botón NO lo alcanza la regla !important de woocommerce.css que sí pisa al
   de "Añadir al carrito": aquella exige .single_add_to_cart_button o .button.alt, y
   este no lleva ninguna de las dos. Por eso aquí no hace falta !important. */
.ga-product-single .ga-product__btn-buy-now:hover,
.ga-product-single .ga-product__btn-buy-now:focus-visible,
.ga-product-single .ga-product__btn-buy-now:active {
    background-color: var(--ga-blanco);
    border-color: var(--ga-naranja-apagado);
    color: var(--ga-naranja-apagado);
}

/* ——— "AÑADIR AL CARRITO" ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴🔴 POR QUÉ ESTE BOTÓN SALÍA DORADO Y CON LAS ESQUINAS RECTAS, POR MUCHO QUE SE
   LE PUSIERA EL ESTILO. No era Astra ni WooCommerce: era ESTE MISMO TEMA. En
   assets/css/woocommerce.css, líneas 182-195, hay:

       .woocommerce .single_add_to_cart_button,
       .woocommerce button.button.alt {
           background-color: var(--ga-naranja-apagado) !important;   ← el dorado
           color:            var(--ga-blanco)          !important;
           border:  2px solid var(--ga-naranja-apagado) !important;
           border-radius: 0                            !important;   ← las esquinas
           padding: 1rem 2.5rem                        !important;
           font-size: var(--ga-text-sm)                !important;
           letter-spacing: 0.1em                       !important;
       }

   TODAS sus declaraciones llevan !important. Un !important gana a cualquier
   declaración normal por mucha especificidad que tenga, así que los intentos
   anteriores —reglas normales— no pintaban nada. El botón lleva la clase
   single_add_to_cart_button de WooCommerce y el <body> lleva .woocommerce, así que
   ese selector lo alcanza de lleno.

   Y hay un segundo cerrojo: woocommerce.css se encola DESPUÉS de main.css
   (functions.php, líneas 47 y 57), así que ni empatando en especificidad se le
   ganaría; mandaría él por orden de aparición.

   ✅ POR ESO AQUÍ SÍ SE USA !important, y es la única forma: contra una
   declaración !important solo compite otra !important. Además se sube el selector
   a 0-3-0 —añadiendo el contenedor .ga-product__cta-buttons— frente al 0-2-0 de
   aquella, para ganar por ESPECIFICIDAD y no depender del orden de los archivos.

   ⚠ ESO EXPLICA TAMBIÉN LO DEL TEXTO EN DOS LÍNEAS: el padding de 2,5rem por lado
   y el tamaño de letra de aquella regla también son !important, así que los
   ajustes de ancho de más abajo tampoco se aplicaban. Van con !important por lo
   mismo.

   ⚠ Y EL COLOR DEL TEXTO EN HOVER HAY QUE ESCRIBIRLO. Aquella regla sí tiene un
   :hover (líneas 197-201) que pone el fondo y el borde en verde, pero NO toca el
   color de la letra: se queda con el blanco del reposo. Como aquí el reposo pasa a
   verde, sin una regla propia de hover el texto seguiría verde sobre fondo verde.
   ═══════════════════════════════════════════════════════════════════════════ */
.ga-product-single .ga-product__cta-buttons .ga-product__btn-cart {
    background-color: var(--ga-blanco) !important;
    color: var(--ga-verde-oliva-oscuro) !important;
    border-color: var(--ga-verde-oliva-oscuro) !important;
    border-radius: var(--ga-radius-md) !important;
}

/* HOVER Y FOCO: se invierte a fondo verde con letras blancas. Solo colores: ni el
   grosor del borde (2px en los dos estados), ni el relleno, ni el tamaño de letra,
   así que el botón no crece ni mueve a su vecino. El icono es un SVG con
   stroke="currentColor", de modo que sigue al color del texto sin regla aparte. */
.ga-product-single .ga-product__cta-buttons .ga-product__btn-cart:hover,
.ga-product-single .ga-product__cta-buttons .ga-product__btn-cart:focus-visible {
    background-color: var(--ga-verde-oliva-oscuro) !important;
    border-color: var(--ga-verde-oliva-oscuro) !important;
    color: var(--ga-blanco) !important;
}

/* ——— NINGUNO DE LOS DOS BOTONES SE MUEVE, NI AL PASAR EL RATÓN NI AL PULSAR ———
   ═══════════════════════════════════════════════════════════════════════════
   QUÉ LO ELEVABA, que era una sola regla y no estaba en este bloque:

       assets/css/single-product.css, líneas 360-365
       .ga-btn--outline-dark:hover { … transform: translateY(-2px); … }

   Le da el tirón de 2px hacia arriba a cualquier botón con esa clase, y "Añadir al
   carrito" la lleva. Puntúa 0-2-0 y no usa !important, así que basta con
   sobrescribirla desde un selector más específico.

   ⚠ "COMPRAR AHORA" NO TENÍA ESE PROBLEMA: usa .ga-btn--primary, cuyo hover
   (main.css, línea 283) solo cambia colores. Comprobado uno por uno.

   ⚠ PERO LOS DOS SÍ SE MOVÍAN AL PULSAR. .ga-btn:active (main.css, línea 304)
   aplica en toda la web un `translateY(1px) scale(0.98)` como "feedback táctil al
   presionar", y alcanza a los dos botones. Es un salto pequeño, pero es movimiento
   y la regla del proyecto no distingue: ningún estado cambia tamaño ni posición.
   Se anula aquí también, SOLO para estos dos botones de las fichas de Eventos; en
   el resto de la web ese efecto sigue intacto.

   Los seis selectores puntúan 0-3-0, por encima del 0-2-0 de las dos reglas que
   sobrescriben, así que ganan por especificidad y no por orden de archivos —que
   importa, porque single-product.css se encola después de main.css—.

   La SOMBRA del hover se queda: no mueve nada y el claude.md la admite
   expresamente junto al color y al borde. */
.ga-product-single .ga-product__btn-cart:hover,
.ga-product-single .ga-product__btn-cart:focus-visible,
.ga-product-single .ga-product__btn-cart:active,
.ga-product-single .ga-product__btn-buy-now:hover,
.ga-product-single .ga-product__btn-buy-now:focus-visible,
.ga-product-single .ga-product__btn-buy-now:active {
    transform: none;
}

/* ——— LOS DOS EN FILA, Y "COMPRAR AHORA" MÁS ANCHO ———
   ═══════════════════════════════════════════════════════════════════════════
   La fila arranca a 700px. Por debajo se apilan, que es lo previsto y lo que pide
   el ancho: "AÑADIR AL CARRITO" en versalitas con su icono necesita unos 190px de
   texto, y a 360px cada botón se quedaría en menos de 100px.

   🔴 700px Y NO 560px COMO ANTES, y es por el cambio de tamaños. Con los dos al
   50% cabían antes; dándole al principal la mitad más de ancho, el secundario se
   queda con un 40% del hueco y necesita más columna para no ir apretado.

   EL REPARTO ES 1,4 A 1: el flex-grow decide cómo se reparte el sitio sobrante y
   flex-basis 0 hace que TODO el ancho sea sobrante, así que la proporción entre
   los dos es exactamente esa, sin que influya lo que mida cada texto. "Comprar
   ahora" se lleva ~58% y "Añadir al carrito" ~42%.

   Al ser elementos de un flex en fila se estiran solos al alto del más alto: los
   dos miden lo mismo sin escribir ninguna altura.

   ⚠ AL SECUNDARIO SE LE AFINA EL TEXTO, y no es un capricho: la columna de compra
   en escritorio no llega a 480px, así que con el 42% se queda en unos 190px. Con
   el relleno lateral de .ga-btn--xl (2rem por lado) no le cabría el texto. Se le
   baja el relleno y un punto la letra y el espaciado, lo justo para que entre en
   una línea.

   ⚠ Y white-space: normal COMO RED DE SEGURIDAD. .ga-btn va en nowrap, que en un
   botón estrecho no parte el texto: lo desborda. Dejándolo envolver, en el peor
   caso "Añadir al carrito" ocupa dos líneas —y el otro botón se estira con él,
   porque comparten fila— en lugar de salirse de la caja. Nunca hay desbordamiento
   horizontal, pase lo que pase con el ancho. */
@media (min-width: 700px) {

    .ga-product-single .ga-product__cta-buttons {
        flex-direction: row;
    }

    /* ——— EL REPARTO BAJA DE 1,4 A 1,25 PARA QUE EL TEXTO ENTRE EN UNA LÍNEA ———
       "AÑADIR AL CARRITO" en versalitas, con su icono, pide unos 155px de texto
       incluso ya afinado. El sitio más justo es a 1024px, donde la ficha va a dos
       columnas iguales y la de compra se queda en unos 440px útiles:

         a 1,4 : 1  →  el secundario recibe 183px  →  NO cabe, parte en dos líneas
         a 1,25 : 1 →  recibe 196px               →  cabe, con unos 10px de aire

       Sigue siendo claramente el pequeño de los dos (56% frente a 44%), que es lo
       pedido: solo se le da lo justo para que el texto no se parta.

       Los tres ajustes de tamaño van con !important porque los pisaba la regla de
       woocommerce.css explicada arriba —relleno de 2,5rem por lado y letra a
       --ga-text-sm, las dos con !important—, y sin ellos el texto no entra en una
       línea por mucho ancho que se le dé. Van a 0-3-0 por el mismo motivo. */
    .ga-product-single .ga-product__btn-buy-now {
        flex: 1.25 1 0;
    }

    .ga-product-single .ga-product__cta-buttons .ga-product__btn-cart {
        flex: 1 1 0;
        padding-inline: var(--ga-space-sm) !important;
        font-size: 0.7rem !important;
        letter-spacing: 0.05em !important;
        /* Red de seguridad: .ga-btn va en nowrap, que en un botón estrecho no parte
           el texto sino que lo desborda. Dejándolo envolver, en el peor caso ocupa
           dos líneas en vez de salirse de la caja. Con los números de arriba no
           debería llegar a usarse. */
        white-space: normal;
    }
}

/* ——— APILADOS (<700px): EL PRINCIPAL, MÁS ALTO ———
   Uno debajo de otro los dos ocupan el ancho completo, así que "más grande" solo
   puede ser MÁS ALTO. El principal sube su relleno vertical de los 1,1rem de
   .ga-btn--xl a --ga-space-md (1,5rem) y queda visiblemente por delante del otro,
   que se queda como está.

   El orden ya lo resuelve el `order: -1` de más arriba, que vale igual apilados:
   "Comprar ahora" arriba y "Añadir al carrito" debajo.

   Es relleno, no altura fija: si el texto envolviera en una pantalla muy estrecha,
   el botón crece y no se corta nada. */
@media (max-width: 699px) {

    .ga-product-single .ga-product__btn-buy-now {
        padding-block: var(--ga-space-md);
    }
}


/* =============================================================================
   EVENTOS — TRES ARREGLOS DE MÓVIL (≤640px)
   =============================================================================
   640px porque es el ancho en el que la hoja de la ficha apila la banda de
   confianza; los otros dos van con ella para no repartir el mismo arreglo entre
   dos breakpoints distintos. Por encima —tablet y escritorio— no se aplica nada.
   ============================================================================= */

@media (max-width: 640px) {

    /* ——— 1 · LOS CAMPOS DE FECHA YA NO SE SALEN POR LA DERECHA ———
       CAUSA, y no era el ancho: .ga-eventos-perso__input ya les da width: 100% y
       box-sizing: border-box, igual que al resto de campos. Lo que pasa es que un
       <input type="date"> NO ES UNA CAJA DE TEXTO NORMAL: el navegador le mete
       dentro sus propios controles nativos —los tres huecos de día, mes y año más
       el icono del calendario— y con la apariencia nativa activada esos controles
       le imponen un ANCHO MÍNIMO INTRÍNSECO propio. Ese mínimo gana al width:100%,
       porque un elemento no puede encogerse por debajo de su contenido mínimo, y
       en una pantalla estrecha ese mínimo es MÁS ANCHO que la columna: de ahí que
       estos dos campos asomaran por la derecha y los demás no.

       ✅ appearance: none apaga esa apariencia nativa, y con ella el ancho mínimo
       que traía puesto. El campo pasa a comportarse como los demás y el width:100%
       por fin manda. El selector de fecha SIGUE FUNCIONANDO: al tocarlo se abre el
       mismo calendario del sistema; lo único que se quita es el dibujo de los
       controles, no el control.

       El max-width es el cinturón por si algún navegador conserva parte de ese
       ancho: por encima del 100% no puede pasar, pase lo que pase.

       ⚠ SOLO EN MÓVIL, y por eso vive dentro del @media: en escritorio esos campos
       caben de sobra y conservan su icono de calendario nativo, que ahí sí ayuda.
       Nada de min-width, que además habría sido el arreglo equivocado: el problema
       era un mínimo de más, no un ancho de menos. */
    .ga-eventos-perso__input[type="date"] {
        -webkit-appearance: none;
        appearance: none;
        max-width: 100%;

        /* ——— Y EL MISMO ALTO QUE LOS DEMÁS, ESTÉ VACÍO O RELLENO ———
           Efecto secundario del appearance: none de aquí arriba. Al apagar la
           apariencia nativa, un campo de fecha SIN valor se queda literalmente sin
           contenido —no pinta ni el dd/mm/aaaa—, así que su caja de línea mide cero
           y el alto del campo pasa a ser solo relleno más borde: bastante menos que
           el de "Texto de la etiqueta", que sí tiene una línea de texto dentro. En
           cuanto se elegía una fecha aparecía el texto y el campo pegaba un salto.

           El min-height le reserva SIEMPRE el alto de una línea, lo tenga o no, y
           se calcula con los tres valores que usan todos los campos del formulario:
           una línea de texto (16px × el line-height de 1,4), el relleno de arriba y
           el de abajo (0,75rem cada uno) y los dos bordes de 1px. Son los mismos
           números de .ga-eventos-perso__input, así que el día que cambie el relleno
           o el tamaño de letra basta con reflejarlo aquí.

           min-height y no height: es un SUELO, no una altura fija. Si el navegador
           decidiera dibujar sus controles algo más altos, el campo crece y no se
           corta nada. (min-height sí está permitido; lo que no se usa en todo el
           proyecto es min-width.) */
        min-height: calc((16px * 1.4) + (0.75rem * 2) + 2px);
    }

    /* ——— 2 · LOS TRES SELLOS, EN UNA FILA DE TRES ———
       La hoja de la ficha los apila en columna a partir de aquí
       (.ga-product__trust-band { flex-direction: column }). Se le devuelve la fila
       SOLO en Eventos: 0-2-0 contra su 0-1-0, así que gana por especificidad y las
       fichas normales siguen apilándolos.

       Cada sello se lleva un tercio exacto (flex: 1 1 0) y por dentro se apila
       —icono arriba, texto debajo y centrado—, que es lo único que permite meter
       tres en 360px: en fila, "Diseño a tu gusto" al lado de su icono no cabe en
       los ~87px que le tocan a cada sello.

       Sin min-width: con flex-basis 0 el suelo lo pone el contenido mínimo, que es
       la palabra más larga de cada sello (~40px). Tres caben de sobra en los 286px
       útiles de la banda, así que no hay desbordamiento posible.

       ⚠ AQUÍ SOLO SE CAMBIA LA COLOCACIÓN, NO LOS TAMAÑOS. El relleno de la banda,
       el hueco entre sellos, el tamaño del icono y el del título ya los fija el
       bloque de los sellos que hay MÁS ABAJO en este archivo, sin media query y con
       la misma especificidad: al venir después, ganaría a cualquier valor que se
       repitiera aquí. Repetirlos sería escribir código muerto. Lo único que se
       toca es el subtexto, que allí no se ajusta y a tres columnas necesita bajar
       un punto. Si hay que retocar iconos o títulos, es en aquel bloque. */
    .ga-product-single--eventos .ga-product__trust-band {
        flex-direction: row;
    }

    .ga-product-single--eventos .ga-trust-item {
        flex: 1 1 0;
        flex-direction: column;
        align-items: center;
        text-align: center;
    }

    .ga-product-single--eventos .ga-trust-item span {
        font-size: 0.6rem;
        line-height: 1.25;
    }

    /* ——— 3 · "ASÍ ES TODO EL PROCESO", DESLIZABLE EN HORIZONTAL ———
       ═══════════════════════════════════════════════════════════════════════
       Los tres pasos dejan de apilarse y pasan a una fila que se desliza con el
       dedo, encajando de uno en uno. Sin una línea de JavaScript: scroll-snap
       nativo.

       🔴 EL SCROLL VIVE EN ESTA LISTA Y EN NINGÚN SITIO MÁS. El overflow-x va sobre
       .ga-eventos-comopedir__lista, nunca sobre html ni body, que siguen con su
       cortafuegos intacto.

       🔴 Y ASÍ ES COMO SE EVITA INFLAR EL VIEWPORT (🪤 nº 1). La clave no es el
       scroll-snap, es la MEDIDA DE LOS PASOS: van en % DEL CONTENEDOR (82%), no en
       vw. La lista mide el 100% de su columna —328px a 360px— y su fila desborda
       HACIA DENTRO, es decir, scrollea la lista y no la página. Es el mismo montaje
       que el carrusel de sellos de la página Nosotros, que funciona (🪤 nº 12).
       Si los pasos fueran en vw, la fila mediría contra la VENTANA y volvería el
       problema de la tienda: el viewport de maquetación se ensancharía y los media
       queries dejarían de aplicarse.

       ⚠ NO USAR vw AQUÍ NI AUNQUE PAREZCA EQUIVALENTE.

       La línea que une los círculos NO estorba: solo se dibuja desde 769px, así que
       en este ancho no existe. No ha habido que adaptarla ni desactivarla. El fondo
       verde tampoco se toca: lo pone la sección, que sigue siendo un bloque normal
       a todo el ancho; lo único que se desliza es la lista de dentro.

       scroll-snap-stop: always es lo que hace que un gesto largo avance UN paso y
       no se salte el segundo. La barra de scroll se oculta: el asomo de los pasos
       de al lado ya avisa de que hay más.

       ——— CENTRADO, Y POR QUÉ HACE FALTA EL RELLENO LATERAL ———
       El paso encaja CENTRADO en la pantalla (scroll-snap-align: center), no pegado
       a la izquierda. Pero un elemento no puede centrarse si no tiene sitio a los
       lados: el PRIMERO se quedaría a la izquierda y el ÚLTIMO a la derecha, porque
       para centrarlos habría que desplazar el scroll más allá de sus extremos, y
       eso no existe. El padding-inline de la lista es ese sitio: el hueco que le
       falta al primero por la izquierda y al último por la derecha.

       ⚠ EL RELLENO CAMBIA LA CUENTA DEL ANCHO, y conviene tenerlo presente: el
       flex-basis del paso es un % del CONTENIDO de la lista, que ya viene descontado
       ese relleno. Con 8% a cada lado, el 88% del contenido queda en torno al 74%
       de la pantalla, con unos 43px de asomo por cada lado a 360px. Es lo que se
       busca en un carrusel centrado: el paso activo en medio y los dos vecinos
       insinuados. Si se toca uno de los dos números hay que revisar el otro.

       ⚠ Y SIGUE SIN HABER NI UN vw: los dos valores son porcentajes del contenedor,
       así que la fila sigue desbordando HACIA DENTRO de la lista y no ensancha el
       viewport de maquetación. */
    .ga-eventos-comopedir__lista {
        /* El hueco entre pasos se declara en la VARIABLE, no en el `gap` a pelo:
           de ella sale también el ancho de cada tramo de línea, así que escribirlo
           por separado dejaría la línea corta o larga sin que se notara. */
        --ga-comopedir-gap: var(--ga-space-sm);

        grid-template-columns: none;
        display: flex;
        gap: var(--ga-comopedir-gap);
        padding-inline: 8%;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
    }

    .ga-eventos-comopedir__lista::-webkit-scrollbar {
        display: none;
    }

    /* flex-basis explícito y NO min-width: min-width solo es un suelo y aquí el
       paso tiene que medir exactamente lo que se le dice. */
    .ga-eventos-comopedir__paso {
        flex: 0 0 88%;
        max-width: 88%;
        scroll-snap-align: center;
        scroll-snap-stop: always;
    }

    /* ——— MÁS AIRE ENTRE EL TÍTULO Y EL PRIMER PASO ———
       El titular llevaba --ga-space-lg (2,5rem) por debajo, que es lo que le deja
       el clamp en este ancho, y con el carrusel justo debajo se quedaba pegado.
       Sube a --ga-space-xl. Solo en móvil: en escritorio el clamp ya lo resuelve. */
    .ga-eventos-comopedir__titulo {
        margin-bottom: var(--ga-space-xl);
    }
}


/* =============================================================================
   FICHA DE PRODUCTO — ACORDEONES SIN FONDO AL PASAR EL RATÓN
   =============================================================================
   El desplegable de la ficha es un <button>, y en una página de WooCommerce
   Astra los captura con reglas como `.woocommerce button:hover`, que ganan en
   especificidad a la clase propia y le meten SU fondo (🪤 nº 6). El resultado
   era una barra dorada con el texto también dorado encima: ilegible.

   La hoja de la ficha ya dice `background: none` y `color: var(--ga-naranja-
   apagado)` al pasar el ratón; lo único que falta es que Astra no se lo pise, y
   para eso hace falta !important, igual que en el resto de botones del tema.

   Se deja SOLO el cambio de color del texto —y el del chevron, que ya era
   dorado—: ni fondo, ni borde, ni sombra, y ningún estado altera el tamaño ni la
   posición, así que nada se desplaza.

   ⚠ Esto NO alcanza a las fichas de Eventos: allí no se pinta ni un solo
   .ga-accordion__trigger (su zona de acordeones va vacía y sus preguntas
   frecuentes son <details> nativos), así que la regla no tiene a quién aplicarse.
   ============================================================================= */

.ga-accordion__trigger,
.ga-accordion__trigger:hover,
.ga-accordion__trigger:focus,
.ga-accordion__trigger:active,
.ga-accordion__trigger:focus-visible {
    background: none !important;
    background-color: transparent !important;
    box-shadow: none !important;
    border: none !important;
}

.ga-accordion__trigger:hover,
.ga-accordion__trigger:focus-visible {
    color: var(--ga-naranja-apagado) !important;
}

/* El contorno de foco por teclado sí se conserva: no ocupa sitio y es lo único
   que le dice al teclado dónde está. */
.ga-accordion__trigger:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* Astra contornea los botones al pulsarlos con el ratón; el foco de teclado ya
   lo pinta la regla de arriba. */
.ga-accordion__trigger:focus:not(:focus-visible) {
    outline: none;
}


/* =============================================================================
   EVENTOS — SELLOS DE CONFIANZA DE LA FICHA
   =============================================================================
   Los tres sellos que van bajo el botón de comprar. Todo lo de aquí va acotado
   con .ga-product-single--eventos, la clase que la plantilla solo pone al <main>
   de estas fichas: las reglas compartidas de single-product.css no se tocan y el
   resto de la tienda conserva sus sellos tal cual.
   ============================================================================= */

/* ——— VERDE OLIVA OSCURO EN TODO EL SELLO ———
   Título, subtexto e icono comparten el verde oliva de los titulares. El icono
   va en el mismo tono —y no se queda en el verde montañas de la regla
   compartida— para que el sello se lea como una sola pieza.

   Sobre el crema de la banda este verde da un contraste de unos 8,4:1, muy por
   encima del mínimo de accesibilidad: resuelve de paso el problema de lectura
   que tenía el dorado, que se quedaba en 2,1:1.

   Sin colores escritos a mano: todo sale de la variable de marca. */
.ga-product-single--eventos .ga-trust-item strong,
.ga-product-single--eventos .ga-trust-item span,
.ga-product-single--eventos .ga-trust-item svg {
    color: var(--ga-verde-oliva-oscuro);
}

/* ——— LOS TRES SELLOS, CENTRADOS EN SU COLUMNA ———
   🔴 EL PROBLEMA NO ERA EL ANCHO DE LAS COLUMNAS. La regla compartida ya les
   pone `flex: 1`, que es `flex-basis: 0` con el mismo crecimiento para los tres:
   las tres columnas miden exactamente lo mismo y siempre lo midieron.

   Lo que faltaba era centrar el CONTENIDO dentro de cada columna. Sin
   justify-content, un contenedor flex alinea a `flex-start`, así que el icono y
   el texto de cada sello se pegaban al borde izquierdo de su columna. Como los
   tres textos miden distinto, el conjunto se veía descuadrado: el primero pegado
   al filo del recuadro y el del medio caído hacia la derecha.

   Centrando cada grupo en su columna, los tres quedan repartidos por igual y el
   conjunto centrado en el recuadro. Y al ser un cambio de alineación, no toca ni
   el tamaño ni la posición de nada más. */
/* El gap se declara aquí, junto al centrado, para no repetir el selector. */
.ga-product-single--eventos .ga-trust-item {
    justify-content: center;
    gap: 0.45rem;
}

/* ——— QUE "DISEÑO A TU GUSTO" QUEPA EN UNA LÍNEA ———
   Se le gana sitio por cuatro lados a la vez, y a los TRES sellos por igual para
   que sigan midiendo lo mismo y alineados: menos relleno lateral en la banda,
   menos hueco entre sellos, icono algo más pequeño y menos hueco entre el icono
   y el texto. Con eso el texto dispone de unos 15px más por sello.

   El título baja un punto de tamaño y casi pierde el espaciado entre letras, que
   en un texto de 17 caracteres se come él solo unos 6px. Nada de white-space:
   nowrap: si en algún ancho no llegara a caber, prefiero que parta a que se
   salga de la caja. */
.ga-product-single--eventos .ga-product__trust-band {
    padding-inline: 0.75rem;
    gap: 0.5rem;
}

.ga-product-single--eventos .ga-trust-item svg {
    width: 20px;
    height: 20px;
}

.ga-product-single--eventos .ga-trust-item strong {
    font-size: 0.66rem;
    letter-spacing: 0.01em;
}

/* En el tramo en el que la columna de compra es más estrecha —de 861 a 1024px,
   donde la ficha va a dos columnas iguales— el título afina un poco más. */
@media (min-width: 861px) and (max-width: 1024px) {

    /* Aquí afinan LOS DOS. El subtexto más largo, "Con tu visto bueno", va justo
       de sitio en este tramo, que es donde la columna de compra se queda más
       estrecha; un punto menos y entra en una línea con holgura. Se aplica a los
       tres sellos por igual para que sigan midiendo lo mismo. */
    .ga-product-single--eventos .ga-trust-item strong {
        font-size: 0.62rem;
    }

    .ga-product-single--eventos .ga-trust-item span {
        font-size: 0.63rem;
    }
}

/* 🔴 AQUÍ HABÍA UNA REGLA QUE AHORA SOBRABA, Y HABRÍA ROTO EL ARREGLO DE MÓVIL.
   Decía: "por debajo de 640px la banda se apila y cada sello ocupa el ancho
   completo: ahí sobra sitio y el título recupera su tamaño", y le devolvía al
   título los 0,875rem de --ga-text-xs dentro de un @media (max-width: 640px).

   Esa premisa YA NO SE CUMPLE: en ese mismo ancho la banda vuelve a ser una fila
   de tres (ver "TRES ARREGLOS DE MÓVIL", más arriba), y cada sello dispone de unos
   87px, no del ancho completo. Con 0,875rem el título no cabía.

   Y no era solo un tamaño feo: esta regla venía DESPUÉS de la del bloque de móvil
   y con la misma especificidad (0-2-0), así que le ganaba por orden de aparición y
   dejaba sin efecto el font-size de allí. Se elimina para que el tamaño de los
   sellos en móvil se decida en un solo sitio. */


/* =============================================================================
   EVENTOS — DESCRIPCIÓN CORTA EN LA COLUMNA DE LA FOTO (ficha de producto)
   =============================================================================
   La descripción corta se ha mudado de la columna de compra a la de la foto, y
   ahí queda entre la foto principal y la cuadrícula de botellas. Conserva su
   clase .ga-product__short-desc —o sea, su tipografía—; lo único que se ajusta
   aquí es el aire alrededor, que en su sitio anterior se lo daba el gap de la
   columna de compra y aquí se lo tiene que dar ella.

   Va acotado con .ga-eventos-desc, que solo lleva esta copia: la descripción de
   las fichas que no son de Eventos no se toca.
   ============================================================================= */

.ga-eventos-desc {
    /* La columna de la foto separa sus hijos con un gap de 1rem; con este margen
       la descripción respira un poco más respecto a la foto, sin llegar al hueco
       grande que la cuadrícula de botellas deja por debajo. */
    margin-top: var(--ga-space-xs);
}

/* ——— SIN LA RAYA DE ABAJO ———
   .ga-product__short-desc trae de serie un filete arriba Y otro abajo, los dos de
   1px en --ga-naranja-claro. El de abajo se quita: justo debajo va el desplegable
   "Descripción del producto", que ya tiene su propia línea, y las dos seguidas
   partían la columna en rebanadas.

   🔴 SE ANULA, NO SE EDITA. Esos bordes viven en single-product.css, que es de
   TODA la tienda: tocarlos allí se los quitaría también a las fichas normales.
   Se sobrescribe desde aquí y en negativo.

   El selector cuelga de .ga-product-single--eventos (0-2-0) a propósito, para
   ganarle a .ga-product__short-desc (0-1-0) por especificidad y no por orden de
   carga: así da igual en qué orden se encolen las dos hojas, esta manda siempre.
   Y como .ga-eventos-desc solo la lleva la copia de Eventos, la descripción de
   las demás fichas conserva sus dos filetes.

   El de ARRIBA se queda: separa la descripción de la foto y no estorba a nada.

   ——— Y SIN EL RELLENO QUE SOSTENÍA ESA RAYA ———
   El padding-block: 1rem de .ga-product__short-desc existía para que el texto no
   se pegara a los dos filetes. Quitado el de abajo, ese relleno inferior ya no
   separa de nada: era el primero de los tres sumandos que dejaban el desplegable
   "Descripción del producto" tan lejos (ver el desglose completo en el bloque de
   la descripción larga). Se pone a cero.

   SOLO EL DE ABAJO. El de arriba sigue haciendo su trabajo bajo el filete que se
   ha quedado, así que se sobrescribe padding-bottom y no el padding-block entero:
   el aire entre la foto y el texto no se mueve. */
.ga-product-single--eventos .ga-eventos-desc {
    border-bottom: 0;
    padding-bottom: 0;
}

/* Los párrafos que vengan del editor no arrastran su margen a los extremos: el
   espacio de fuera lo pone el bloque, no el primer o el último párrafo. */
.ga-eventos-desc > *:first-child {
    margin-top: 0;
}

.ga-eventos-desc > *:last-child {
    margin-bottom: 0;
}


/* =============================================================================
   EVENTOS — DESCRIPCIÓN LARGA EN UN DESPLEGABLE (ficha de producto)
   =============================================================================
   El texto principal del producto, plegado bajo la descripción corta y encima de
   la cuadrícula de botellas. <details>/<summary> nativos: se abre y se cierra sin
   una línea de JavaScript.

   🔴 EL ASPECTO NO SE REESCRIBE, SE REUTILIZA. El <details> lleva además la clase
   .ga-eventos-faq__item y su <summary> las de la FAQ de Eventos, así que hereda
   TAL CUAL el bloque de "EVENTOS — PREGUNTAS FRECUENTES" de más arriba: la misma
   tipografía del título, la misma flecha dorada que gira media vuelta al abrirse,
   el mismo hover que cambia SOLO el color (nunca el fondo, ni el tamaño, ni la
   posición) y el mismo contorno de foco. Si algún día se retoca el estilo de
   aquellos desplegables, este va detrás solo, que es justo lo que se pedía.

   Aquellas reglas ya vienen acotadas con .ga-product-single--eventos, la clase
   que solo lleva el <main> de las fichas de esta categoría, así que nada de esto
   asoma en el resto de la tienda.

   Lo ÚNICO que no se hereda es lo que aquí abajo se escribe, y son dos cosas:
   el interpolate-size del despliegue suave —que en la FAQ se declara en su
   <section>, y este desplegable no está dentro de ella— y la tipografía del
   cuerpo, que no puede ser la de una respuesta de la FAQ (ver más abajo).
   ============================================================================= */

/* ——— MENOS AIRE ENCIMA DEL TÍTULO ———
   ═══════════════════════════════════════════════════════════════════════════
   EL HUECO NO VENÍA DE UN SITIO NI DE DOS: VENÍAN TRES SUMÁNDOSE.
   ═══════════════════════════════════════════════════════════════════════════
   Entre el final del texto de la descripción corta y el título "Descripción del
   producto" había 3rem, repartidos así:

     1rem  relleno INFERIOR de .ga-product__short-desc (padding-block: 1rem)
   + 1rem  gap de .ga-product__gallery, que es un flex en columna
   + 1rem  relleno SUPERIOR de este <summary>
   ─────
     3rem

   Por eso bajar solo uno se notaba tan poco: cada recorte se comía como mucho un
   tercio del hueco. Ahora se recortan los DOS que se pueden tocar sin salir de
   Eventos, y el resultado son 1,5rem: exactamente la mitad.

     0rem    el relleno inferior de la descripción corta, anulado arriba en
             .ga-product-single--eventos .ga-eventos-desc (ya no sujeta ninguna
             raya, así que no separaba de nada)
   + 1rem    el gap, INTOCABLE: vive en single-product.css, que es de toda la
             tienda. Bajarlo movería las fichas normales y, dentro de esta misma
             columna, también la foto, la cuadrícula de botellas y el contacto.
             Sería el único que queda por recortar, pero no sale a cuenta.
   + 0,5rem  este relleno, de --ga-space-sm a --ga-space-xs
   ───────
     1,5rem

   Solo afecta a ESTE desplegable —el selector cuelga de .ga-eventos-desc-larga—,
   así que las doce preguntas de la FAQ conservan su relleno de siempre. Va a
   0-3-0 para ganar por especificidad y no por orden de aparición, incluida la
   media query de ≤768px de la FAQ; el recorte es el mismo en escritorio, tablet
   y móvil.

   Solo el de arriba: el de abajo, que es el que separa el título de la respuesta
   al desplegarse, se queda como estaba. Que el <summary> quede desigual —poco
   relleno arriba y más abajo— es lo normal en una cabecera de acordeón: el título
   se acerca a lo que lo precede y deja el aire del lado donde se abre. */
.ga-product-single--eventos .ga-eventos-desc-larga > .ga-eventos-faq__pregunta {
    padding-top: var(--ga-space-xs);
}

/* ——— EL CUERPO ———
   ⚠ NO REUTILIZA .ga-eventos-faq__respuesta, Y ES A PROPÓSITO. Aquella regla pone
   `margin: 0` a sus <p> porque una respuesta de la FAQ es SIEMPRE un párrafo
   suelto. Aquí el contenido lo escribe Jaime en el editor de WooCommerce y puede
   traer varios párrafos, listas o imágenes: con aquel margen a cero, dos párrafos
   seguidos se pegarían el uno al otro y se leerían como un ladrillo. Así que el
   cuerpo lleva clase propia y su propia tipografía, calcada a la de la FAQ en
   tamaño, color y altura de línea, pero con el aire entre bloques que un texto
   largo necesita. */
.ga-eventos-desc-larga__cuerpo {
    padding-bottom: var(--ga-space-md);
    font-family: var(--ga-font-body);
    font-size: clamp(0.95rem, 1.1vw, 1.05rem);
    line-height: 1.8;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.82;
    text-wrap: pretty;
    /* Corta las palabras largas —una URL pegada, un nombre sin espacios— en vez de
       dejarlas empujar la columna. Es la forma de fijar el ancho mínimo del
       contenido sin recurrir a min-width. */
    overflow-wrap: break-word;
}

.ga-eventos-desc-larga__cuerpo > *:first-child {
    margin-top: 0;
}

.ga-eventos-desc-larga__cuerpo > *:last-child {
    margin-bottom: 0;
}

/* Separación entre bloques del editor. En em y no en rem: así el hueco acompaña
   al tamaño de letra, que es un clamp y cambia con el ancho de la pantalla. */
.ga-eventos-desc-larga__cuerpo p,
.ga-eventos-desc-larga__cuerpo ul,
.ga-eventos-desc-larga__cuerpo ol {
    margin: 0 0 0.9em;
}

/* Las viñetas, dentro de la caja: con el relleno por dentro no se salen por la
   izquierda de la columna. */
.ga-eventos-desc-larga__cuerpo ul,
.ga-eventos-desc-larga__cuerpo ol {
    padding-left: 1.25rem;
}

/* 🔴 UNA IMAGEN DEL EDITOR ES LO ÚNICO DE AQUÍ DENTRO QUE PODRÍA DESBORDAR: viene
   con su ancho original, que a 360px es casi siempre mayor que la columna. Con
   esto se queda en el ancho disponible y conserva su proporción. */
.ga-eventos-desc-larga__cuerpo img {
    max-width: 100%;
    height: auto;
}

/* ——— DESPLIEGUE SUAVE ———
   Las reglas que animan ::details-content ya están escritas en el bloque de la
   FAQ y alcanzan a este desplegable, porque cuelgan de .ga-eventos-faq__item.
   Pero les falta una pieza: interpolate-size, que es lo que permite interpolar
   HACIA `auto`. Allí se declara en la <section> de la FAQ y se hereda a sus
   desplegables; este vive en la columna de la foto, fuera de esa sección, así que
   se le da aquí, sobre el propio <details> —la propiedad se hereda y llega al
   pseudoelemento—.

   Va dentro de las MISMAS dos condiciones que allí, ni una más: sin soporte de
   ::details-content, o con el ahorro de movimiento activado, no se declara nada y
   el desplegable abre de golpe, que es el comportamiento nativo de toda la vida.
   Nunca se queda cerrado ni se rompe. */
@media (prefers-reduced-motion: no-preference) {

    @supports selector(::details-content) {

        .ga-eventos-desc-larga {
            interpolate-size: allow-keywords;
        }
    }
}

/* ——— ESCRITORIO: LA COLUMNA DE LA FOTO NO PUEDE IR PEGADA ———
   .ga-product__gallery es sticky de serie. Una columna pegada que mide más que la
   pantalla deja su parte de abajo INALCANZABLE: se queda clavada arriba y el
   resto se sale por debajo del viewport mientras la página baja. Por eso la
   cuadrícula de botellas ya suelta el sticky con .ga-product__grid--combina.

   Este desplegable tiene el mismo problema, y uno peor: CRECE al abrirse. Pero no
   siempre viene acompañado de la cuadrícula —un formato que no tenga hermanos se
   queda sin ella—, así que aquel gancho no basta y hace falta este.

   :has() lo acota mejor que cualquier clase heredada: la regla solo existe cuando
   dentro de la columna hay un .ga-eventos-desc-larga, que es una clase que solo se
   pinta en las fichas de Eventos. En una ficha normal no puede llegar a aplicarse.
   Y en un navegador sin :has() el selector entero se descarta y la columna se
   comporta como hasta hoy: se degrada a lo de siempre, nunca a algo peor.

   Solo desde 861px, que es donde el grid tiene dos columnas de verdad; por debajo
   va todo apilado y el sticky ni entra en juego. */
@media (min-width: 861px) {

    .ga-product__gallery:has(.ga-eventos-desc-larga) {
        position: static;
    }
}


/* =============================================================================
   EVENTOS — PUNTO DE DISPONIBILIDAD DE LA FICHA
   =============================================================================
   El mismo indicador que la franja de la página de Contacto: un círculo verde
   con una onda que late, en lugar del tick de la ficha estándar. Mismo tamaño
   (10px) y mismo verde de marca.

   ⚠ ESTE INDICADOR NUNCA HA COMPARTIDO ESTILO CON EL DE CONTACTO, aunque se
   parezcan. Aquel es .ga-contacto-estado__punto con su @keyframes
   ga-contacto-pulso; este es .ga-eventos-stock__punto con el suyo. Son dos
   bloques independientes desde el principio, así que todo lo de aquí abajo se
   queda dentro de las fichas de eventos y NO llega a la franja de Contacto, que
   sigue exactamente igual que estaba.

   Nacieron separados por el fondo sobre el que se apoyan: en Contacto el punto
   va sobre el panel verde oscuro y su onda es de color pastel, que es lo que se
   ve ahí; aquí la línea está sobre BLANCO, donde ese pastel es invisible, así
   que la onda se pinta en el propio verde.

   ——— CÓMO ESTABA HECHA LA ONDA Y CÓMO ESTÁ AHORA ———

   ANTES: el <span> llevaba TRES capas de box-shadow —anillo fijo, halo fijo y
   onda— y la animación repetía las tres en cada fotograma para engordar el
   `spread` de la tercera de 2px a 12px. Dos problemas:

     · SE EXPANDÍA DEMASIADO: 12px de spread sobre un círculo de 10px daban una
       onda de 34px de diámetro, más de tres veces el punto.
     · NO IBA FLUIDA: box-shadow no es una propiedad que el compositor pueda
       animar. Cada fotograma obligaba al navegador a REPINTAR el punto y su
       entorno en el hilo principal, así que el latido daba tirones en cuanto
       había algo más ocupando la CPU.

   AHORA: el box-shadow del <span> se queda QUIETO —solo el anillo y el halo, las
   dos capas que ya eran fijas— y la onda se ha sacado a un ::after propio que
   crece con `transform: scale()` y se apaga con `opacity`. Son las dos únicas
   propiedades que el navegador resuelve en el compositor, sin repintar ni
   recalcular la maquetación: el latido va suave aunque el hilo principal esté
   ocupado. La onda queda ahora en 21px de diámetro (scale 2.1 sobre 10px) en vez
   de 34px: bastante más contenida y discreta.

   Y sigue sin poder mover nada de la línea: el ::after va en position:absolute,
   así que está fuera del flujo, y `transform` no reserva espacio ni participa en
   la maquetación. Ni el texto de al lado ni el ancho de la página se enteran de
   que hay algo creciendo, por eso tampoco puede provocar desbordamiento
   horizontal —y, de hecho, ahora sobresale 5,5px en lugar de los 12px de antes—.

   🔴 EL COLOR NO SE ESCRIBE AQUÍ: SE HEREDA. El punto se pintaba en
   --ga-verde-montanas (#7f8649), que es un verde oliva apagado, mientras que la
   línea de al lado va en el verde vivo del stock. Al ir uno al lado del otro, el
   círculo parecía sucio o medio apagado. Ahora el fondo es `currentColor`, así
   que el punto toma EXACTAMENTE el color del texto que tiene al lado, sea el que
   sea: no hay dos colores que mantener sincronizados ni un valor copiado a mano
   que se quede viejo el día que se retoque el verde del stock.

   Por lo mismo, la onda y el halo se sacan de ese mismo color con color-mix() en
   vez de rgba() fijos. En navegadores sin color-mix (anteriores a 2023) esas
   sombras se descartan y el punto se queda quieto y sin halo, pero SE SIGUE
   VIENDO y con el color correcto, que es lo que importa.
   ============================================================================= */

/* EL CÍRCULO CENTRAL NO CAMBIA: mismo tamaño, mismo currentColor heredado del
   texto y el mismo anillo y halo de siempre, ahora ya sin animar. Lo único nuevo
   es el position:relative, que es lo que ancla la onda del ::after; no altera la
   maquetación de un elemento que ya estaba en su sitio. */
.ga-eventos-stock__punto {
    position: relative;
    flex: 0 0 auto;
    width: 10px;
    height: 10px;
    /* Un pelo de aire a la derecha, ADEMÁS del gap de la línea: el halo del
       latido invade parte de ese hueco y el punto quedaba pegado al texto. */
    margin-right: 0.3rem;
    border-radius: var(--ga-radius-full);
    background-color: currentColor;
    box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 18%, transparent),
                0 0 8px 2px color-mix(in srgb, currentColor 35%, transparent);
}

/* LA ONDA. Nace calcada al círculo (inset:0 → los mismos 10px) y crece desde su
   centro. Va en el mismo currentColor al 40%, así que sobre el círculo —que es
   ese color ya opaco— no se nota, y solo se ve la parte que asoma por fuera: el
   efecto es una onda que sale del punto, no un disco que lo tapa.

   pointer-events:none porque es pura decoración: es una capa que se mueve por
   encima de la línea y no debe interceptar el ratón. Con la onda contenida en
   10,5px ya no llega al texto —el hueco hasta la primera letra es de unos 11px
   entre el margen y el gap—, pero antes, con los 17px del box-shadow, sí que lo
   pisaba: la regla se queda como red por si alguien vuelve a subir el scale. */
.ga-eventos-stock__punto::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: var(--ga-radius-full);
    background-color: color-mix(in srgb, currentColor 40%, transparent);
    pointer-events: none;
    animation: ga-eventos-stock-pulso 3s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
}

/* 🔴 EL CICLO ARRANCA Y TERMINA INVISIBLE, Y AHÍ ESTÁ LA CLAVE DE QUE NO DÉ EL
   TIRÓN DEL REINICIO. En el 72% la onda ya está a opacidad 0, y del 72% al 100%
   se queda quieta y apagada. Cuando vuelve al 0% y el scale salta de 2.1 a 1, el
   elemento lleva casi un segundo sin verse: el salto existe, pero es imposible
   percibirlo. Antes el ciclo terminaba a mitad de camino y el reinicio se notaba.

   Ese tramo muerto final es además lo que hace el latido CALMADO: 3s de ciclo de
   los que la onda solo ocupa unos 2,2s, y el resto es la pausa entre latidos. La
   curva (un ease-out suave) la lanza con decisión y la va frenando mientras se
   apaga, como una onda en el agua; con la 'ease-out' de manual salía más seca.

   El 14% inicial es una entrada corta pero real: la onda no aparece de golpe a
   plena opacidad, se enciende mientras empieza a separarse del círculo. */
@keyframes ga-eventos-stock-pulso {
    0% {
        transform: scale(1);
        opacity: 0;
    }
    14% {
        transform: scale(1.2);
        opacity: 0.9;
    }
    72% {
        transform: scale(2.1);
        opacity: 0;
    }
    100% {
        transform: scale(2.1);
        opacity: 0;
    }
}

/* Con ahorro de movimiento el círculo se queda quieto, pero SIGUE VIÉNDOSE: se
   retira la onda entera y el punto se queda con su anillo y su halo, que son
   fijos y no se animaban ni antes. Mismo criterio que en Contacto.

   Se quita con display:none y no con animation:none: sin animación, el ::after
   se quedaría congelado en su estado base —opacidad 0, invisible— pero seguiría
   ahí. Retirarlo del todo es más honesto y no deja nada pintándose. */
@media (prefers-reduced-motion: reduce) {

    .ga-eventos-stock__punto::after {
        display: none;
    }
}


/* =============================================================================
   EVENTOS — EL TÍTULO DE LA FICHA OCUPA TODA LA COLUMNA
   -----------------------------------------------------------------------------
   DIAGNÓSTICO, porque el motivo no era el que parecía: el <h1> NO estaba
   estrecho. Ni él ni su columna llevan ancho máximo ninguno —.ga-product__name
   no declara max-width y .ga-product__purchase es un flex en columna, así que el
   título ya ocupaba el 100% de la caja, exactamente igual que el formulario de
   personalización que va debajo—. Lo que se quedaba corto era EL TEXTO dentro de
   esa caja.

   La causa está en la regla de tipografía general de este mismo archivo:

       h1, h2, h3, h4, h5, h6 { ...; text-wrap: balance; }

   `balance` reparte las palabras en líneas de LARGO PARECIDO en lugar de llenar
   cada línea hasta el borde. Queda muy bien en un titular centrado y corto, que
   es para lo que se puso, pero en un nombre de producto largo dentro de una
   columna deja las líneas cortadas a media caja y sobra un margen derecho enorme
   que parece un ancho máximo sin serlo.

   Se le devuelve el reparto normal SOLO en las fichas de eventos: cada línea se
   llena hasta el final y el título ocupa menos renglones. El tamaño de letra no
   se toca: sigue siendo el clamp() de .ga-product__name.

   ⚠ ACOTADO A PROPÓSITO con .ga-product-single--eventos (0-2-0), que gana al
   selector de tipo (0-0-1) sin depender del orden de carga. El resto de títulos
   del sitio —y las fichas que no son de eventos— conservan su `balance`.
   ============================================================================= */

.ga-product-single--eventos .ga-product__name {
    text-wrap: wrap;
}


/* =============================================================================
   FICHA DE PRODUCTO — LAS VALORACIONES, EN UNA SOLA LÍNEA QUE RUEDA
   =============================================================================
   En la HOME las opiniones son un mosaico de 3×2 cuyas seis tarjetas se relevan
   con un fundido en cascada. En la FICHA DE PRODUCTO —en todas, sean de Eventos o
   no— se quieren en una sola fila que se desliza sola hacia la izquierda.

   🔴 LA HOME NO SE TOCA, Y ESTA ES LA MANERA DE CONSEGUIRLO. La sección la pinta
   template-parts/home-opiniones.php, que es UN SOLO ARCHIVO compartido por la home
   y por la ficha: cambiar su marcado cambiaría las dos. Así que aquí no se edita
   nada de él; se SOBRESCRIBE desde fuera, colgando cada regla de
   .ga-product-single, la clase que el <main> solo lleva en una ficha de producto.
   Puntúan 0-2-0 frente al 0-1-0 de las compartidas, así que ganan por
   especificidad y no por orden de aparición —tampoco a las que viven dentro de sus
   media queries—. En la home ninguna de estas reglas llega a aplicarse.

   El mismo criterio en el JS: gaOpinionesMosaico() se sale sin hacer nada cuando
   el mosaico está dentro de una ficha, y de la fila se encarga el carrusel.

   🔴 EL MOVIMIENTO ES UN transform SOBRE LA PISTA, Y EL RECORTE LO HACE UN MARCO.
   Es el mecanismo del carrusel de la tienda, y va así por las dos trampas
   documentadas: una fila real más ancha que el viewport contenida con
   overflow-x: auto INFLA el viewport de maquetación en móvil y anula los media
   queries (🪤 nº 1); y `clip` recorta igual que `hidden` pero NO convierte al marco
   en contenedor de scroll, así que no atrapa el gesto táctil (🪤 nº 3).

   Ni las tarjetas, ni las estrellas, ni el nombre, ni la etiqueta de compra, ni el
   texto cambian: siguen exactamente con las reglas compartidas. Lo único que se
   toca aquí es CÓMO SE COLOCAN y CÓMO SE MUEVEN.
   ============================================================================= */

/* EL MARCO QUE RECORTA. No está en el HTML: lo crea el JS envolviendo la pista,
   igual que hace el carrusel de la tienda. Si el JS no llegara a correr, no hay
   marco, la rejilla se queda como está y la sección sigue viéndose entera. */
.ga-product-single .ga-op-carrusel {
    overflow: clip;
}

@supports not (overflow: clip) {

    .ga-product-single .ga-op-carrusel {
        overflow: hidden;
    }
}

/* LA PISTA. Es la misma .ga-opiniones__grid de siempre, que aquí deja de ser una
   rejilla y pasa a ser una fila.

   Los dos números que mandan —cuántas tarjetas se ven y cuánto las separa— viven
   en propiedades personalizadas, y las heredan las tarjetas: cada breakpoint de
   más abajo solo tiene que cambiar --ga-op-car-n y todo lo demás se recalcula
   solo. El JS mide el ancho de paso leyéndolo del DOM, así que también se adapta
   sin saber nada de estos valores.

   touch-action: pan-y pinch-zoom deja pasar el desplazamiento vertical de la
   página y conserva el zoom; del arrastre horizontal se encarga el JS, que nunca
   llama a preventDefault. */
.ga-product-single .ga-opiniones__grid {
    /* PUNTO DE PARTIDA: UNA. Los escalones de más abajo van hacia ARRIBA
       (min-width), así que si alguno no llegara a aplicarse lo que queda es la
       versión de una tarjeta, que cabe en cualquier pantalla. Al revés, el fallo
       dejaría tres columnas en un móvil. */
    --ga-op-car-n: 1;
    /* El mismo hueco que el carrusel de "También te puede interesar" de arriba
       (era --ga-space-md): al estrecharlo, cada tarjeta gana unos 6px de ancho y
       las dos filas de la ficha separan igual. */
    --ga-op-car-gap: var(--ga-space-sm);

    display: flex;
    gap: var(--ga-op-car-gap);
    touch-action: pan-y pinch-zoom;
    transition: transform var(--ga-transition-slow);
}

/* CADA TARJETA. flex-basis explícito y no min-width: min-width solo es un suelo y
   aquí tienen que poder encoger (🪤 del carrusel móvil de la tienda). El calc
   descuenta los (n-1) huecos que quedan entre las n visibles.

   El alto NO se toca: lo siguen poniendo las reglas compartidas (250px, y 220px
   en móvil), así que todas miden lo mismo y la fila no se escalona. */
.ga-product-single .ga-opiniones__slot {
    flex: 0 0 calc((100% - (var(--ga-op-car-n) - 1) * var(--ga-op-car-gap)) / var(--ga-op-car-n));
    max-width: calc((100% - (var(--ga-op-car-n) - 1) * var(--ga-op-car-gap)) / var(--ga-op-car-n));
}

/* 🔴 SIN EL SALTO DEL HOVER. La regla compartida sube la tarjeta 4px con un
   translateY al pasar el ratón. En una fila que se desliza sola eso es un cambio
   de POSICIÓN —justo lo que no puede pasar aquí— y además pelea con el transform
   de la pista. Se anula solo el movimiento: el `overflow: visible` y el cambio de
   sombra de la tarjeta que lleva ese mismo hover se quedan, así que sigue habiendo
   respuesta visual al pasar por encima. En la home el salto sigue intacto. */
.ga-product-single .ga-opiniones__slot:hover {
    transform: none;
}

/* ——— CUÁNTAS SE VEN, Y POR QUÉ ESTAS Y NO CUATRO ———
   ═══════════════════════════════════════════════════════════════════════════
   EL NÚMERO NO SE ELIGE POR GUSTO: LO DECIDE LA ETIQUETA DE COMPRA.
   ═══════════════════════════════════════════════════════════════════════════
   Dentro de la tarjeta, .ga-opiniones__cabecera es un flex con `flex-wrap: wrap`
   donde el nombre y la etiqueta llevan LOS DOS flex-shrink: 0. Ninguno puede
   encoger, así que en cuanto la suma de los dos no cabe en el ancho disponible, la
   etiqueta se cae a la línea siguiente. No hay forma de arreglarlo desde la
   etiqueta: o cabe, o baja. La única palanca es el ANCHO DE LA TARJETA.

   Lo que hay que meter en una línea, en el peor caso del listado:
     · nombre más largo ("María José Hernández"), Cormorant 600 a 1,3rem  ≈ 153px
     · hueco de la cabecera (0,5rem)                                      ≈   8px
     · etiqueta "Compra en tienda" con su icono, relleno y borde          ≈ 128px
     ────────────────────────────────────────────────────────────────────────────
     hacen falta unos                                                    ≈ 290px
   de ANCHO ÚTIL, es decir, ya descontado el relleno de la tarjeta (2rem por lado
   en escritorio, 0,9rem en móvil).

   De ahí salen los escalones, calculando sobre .ga-opiniones__inner (máximo
   1200px menos 2rem de relleno por lado):

     3 tarjetas → necesita un contenedor de ~1094px → desde 1200px de ventana
     2 tarjetas → necesita ~724px                   → desde  800px de ventana
     1 tarjeta  → siempre cabe

   🔴 CUATRO NO ENTRAN, Y POR ESO NO ESTÁN. Con el contenedor a tope (1136px), cuatro
   tarjetas se quedan en 266px y su ancho útil en 202px: 88px menos de los que pide
   la cabecera, así que la etiqueta bajaría de línea SIEMPRE, en cualquier monitor.
   No es que se vea apretado en pantallas pequeñas: es que no cabe nunca. Tal y como
   se pidió, manda que la etiqueta quede junto al nombre.

   A 360px la tarjeta ocupa los 336px del inner enteros y, con el relleno reducido
   de móvil, deja ~307px útiles: la cabecera cabe también ahí.

   ⚠ LAS MEDIDAS DEL TEXTO SON ESTIMADAS (no he podido medirlas en un navegador).
   Si alguna etiqueta siguiera bajando, la palanca es esta lista: subir el ancho de
   ventana de un escalón, o bajar un número de tarjetas. */
@media (min-width: 800px) {

    .ga-product-single .ga-opiniones__grid {
        --ga-op-car-n: 2;
    }
}

@media (min-width: 1200px) {

    .ga-product-single .ga-opiniones__grid {
        --ga-op-car-n: 3;
    }
}

@media (max-width: 599px) {

    /* ——— DOS TARJETAS A LA VISTA EN MÓVIL ———
       ═══════════════════════════════════════════════════════════════════════
       Y sale UNA SOLA LÍNEA porque el ancho cuadra solo con lo que ya existe.
       La cuenta a 360px:

         inner 360 − 2 × 0,75rem de relleno .......... 336px de columna
         menos el hueco entre tarjetas (1rem) ........ 320px repartibles
         entre dos ................................... 160px por tarjeta
         menos su relleno (0,9rem por lado) .......... 131px de texto útil

       Y el mosaico de la HOME, en este mismo ancho, va a dos columnas con
       tarjetas de ~162px. Es decir: la tarjeta de este carrusel mide
       prácticamente lo mismo que la de la home, para la que YA está afinada toda
       la tipografía de este breakpoint —estrellas a 1,05rem, nombre a 0,95rem,
       etiqueta a 0,58rem con su relleno reducido, texto a 0,81rem y tarjeta de
       220px de alto—. No hace falta tocar ni un tamaño de letra: el diseño de
       móvil ya estaba pensado para una tarjeta de este ancho.

       ⚠ LA ETIQUETA DE COMPRA NO PUEDE "BAJAR DE LÍNEA" AQUÍ, porque en este
       breakpoint no está en la misma línea que el nombre: la regla compartida
       pone .ga-opiniones__cabecera en flex-direction: column, así que el nombre
       va arriba y la etiqueta debajo, a propósito y desde antes de este cambio.
       Es el mismo apilado que se ve en la home en móvil. Con sus 0,58rem y el
       relleno reducido ocupa unos 109px de los 131px disponibles, así que entra
       entera en su línea y no se parte.

       El JS no necesita saber nada: mide el ancho de paso leyéndolo del DOM y
       calcula cuántas caben dividiendo por él, así que pasa de una a dos solo.

       Solo aquí: por encima de 599px el número de tarjetas no se toca. */
    .ga-product-single .ga-opiniones__grid {
        --ga-op-car-n: 2;
    }

    /* 🔴 SE DESHACE EL OCULTADO DE LA QUINTA EN ADELANTE. La regla compartida
       (.ga-opiniones__slot:nth-child(n+5) { display: none }) existe para dejar el
       mosaico de la home en una rejilla 2×2 en móvil. En un carrusel escondería
       casi todas las tarjetas y solo quedarían cuatro por las que pasar. Va a
       0-3-0 para ganarle a aquella, que puntúa 0-2-0. */
    .ga-product-single .ga-opiniones__slot:nth-child(n+5) {
        display: block;
    }
}

/* ——— MOVIMIENTO REDUCIDO ———
   Sin transición en la pista. El JS tampoco arranca el giro automático con esta
   preferencia, así que la fila se queda quieta en la primera tarjeta y solo se
   mueve si se arrastra a mano. */
@media (prefers-reduced-motion: reduce) {

    .ga-product-single .ga-opiniones__grid {
        transition: none;
    }
}


/* =============================================================================
   MI CUENTA — AVISO DE CONFIRMACIÓN DE CORREO Y BOTONES DE LA TABLA DE PEDIDOS
   =============================================================================
   Dos arreglos de /my-account/orders/: el aviso cuyo botón se pintaba encima del
   texto, y los dos botones de la columna "Acciones", que no se parecían en nada.

   🔴 TODO VA ACOTADO A body.woocommerce-account, Y ESA CLASE HACE DOS TRABAJOS.
   El evidente: que nada de aquí toque los botones de la tienda, de la ficha de
   producto o del pago, que comparten las clases .button y .woocommerce-button.
   El menos evidente, y por el que no se puede quitar: es la que da la
   ESPECIFICIDAD necesaria para ganar.

   ⚠ assets/css/woocommerce.css SE CARGA DESPUÉS QUE ESTE ARCHIVO —depende de él
     en el wp_enqueue_style—, así que con la misma especificidad e igual
     importancia, gana siempre aquel. Y allí hay un `border-radius: 0 !important`
     sobre el botón del aviso. Sin el body. delante, estas reglas no pintarían
     nada por muchos !important que llevaran.
   ============================================================================= */

/* ——— 1. EL AVISO ———
   Por qué el botón se montaba encima del texto: en el marcado de estos avisos el
   BOTÓN VA PRIMERO y el texto detrás, y tanto WooCommerce como Astra lo sacan de
   su sitio para mandarlo a la derecha. Mientras el botón esté fuera del flujo
   normal, el texto no le reserva hueco y los dos acaban ocupando los mismos
   píxeles.

   Se arregla en el origen: se le devuelve el flujo al botón (más abajo,
   `float: none` y `position: static` a la vez, que cubren las dos formas de
   sacarlo) y se pone el aviso en columna, que es la disposición pedida.

   👉 EL ORDEN LO ARREGLA `order`, NO EL MARCADO —que aquí no se puede tocar—.
   El texto suelto del aviso es un elemento flexible anónimo y esos SIEMPRE valen
   0; dándole al botón un `order: 2` cae detrás de él sin tener que mover una sola
   línea de HTML.

   ⚠ NADA DE align-items: flex-start EN EL CONTENEDOR, y esto es importante: en
     una columna flexible eso haría que el texto se midiera por su contenido en
     vez de por el ancho disponible, y una frase larga se saldría de la caja. Se
     deja el estirado de siempre —el texto ocupa el ancho y parte donde toca— y es
     el BOTÓN el que se ciñe a su contenido con `align-self`. A 360 px esa es la
     diferencia entre un aviso que cabe y uno que desborda a lo ancho. */
body.woocommerce-account .woocommerce-info,
body.woocommerce-account .woocommerce-message {
    display: flex;
    flex-direction: column;
    gap: 1rem;
    border-radius: 10px !important;
}

/* En las versiones que envuelven el aviso en una lista, el <li> es el que lleva
   dentro el botón y el texto: se pone en columna igual, para que el arreglo valga
   con las dos formas de marcado. Si no hay lista, esta regla no encuentra a nadie
   y no hace nada. */
body.woocommerce-account .woocommerce-info > li,
body.woocommerce-account .woocommerce-message > li {
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

/* Si el icono es un ::before EN FLUJO, se queda arriba del todo. Si el tema lo
   pinta en posición absoluta —que es lo habitual—, no es un elemento flexible y
   esta regla sencillamente no le afecta. En los dos casos el icono acaba donde
   debe. */
body.woocommerce-account .woocommerce-info::before,
body.woocommerce-account .woocommerce-message::before {
    order: -1;
}

body.woocommerce-account .woocommerce-info .button,
body.woocommerce-account .woocommerce-message .button {
    /* Lo que lo devuelve al flujo. Las dos a la vez y a propósito: una neutraliza
       el flotado y la otra el posicionamiento, que son las dos maneras de
       provocar el solape. Cuál de las dos estaba puesta da igual. */
    float: none !important;
    position: static !important;

    order: 2;              /* debajo del texto */
    align-self: flex-start; /* pegado a la izquierda y del ancho de su texto */
    margin: 0 !important;

    border-radius: 10px !important;
    background-color: var(--ga-verde-oliva-oscuro) !important;
    color: var(--ga-blanco) !important;
}


/* ——— 2. LOS DOS BOTONES DE LA COLUMNA "ACCIONES" ———
   🔴 POR QUÉ "SOLICITAR DEVOLUCIÓN" SALÍA CON EL TEXTO EN VERDE OSCURO. No había
   ninguna regla verde: es la trampa nº 15 del claude.md. Su regla de más arriba
   en este mismo archivo pide `color: var(--ga-negro-suave) !important`, y esa
   variable ESTÁ EN LA PALETA PERO NO SE DECLARA en el :root de style.css
   (comprobado). Un var() que no resuelve no cae al valor por defecto: invalida la
   declaración entera, y como `color` se hereda, el botón se quedaba con el color
   del texto de la tabla, que es el verde oliva. El !important no ayudaba, porque
   el problema nunca fue de especificidad.

   Aquí se le da el blanco directamente, sin depender de ninguna variable que
   pueda no existir. */
body.woocommerce-account a.woocommerce-button.desistimiento {
    color: var(--ga-blanco) !important;
}

/* La geometría COMPARTIDA por los dos, que es lo que iguala la columna: mismo
   redondeo, mismo relleno y misma altura de línea. Con box-sizing y el borde a
   cero en los dos, el alto sale idéntico sin fijar ninguna altura a mano.

   ⚠ ES LA ÚNICA COSA QUE SE LE TOCA AL BOTÓN "VER": redondeo, relleno y caja. Sus
     colores son los que tenía y no se rozan. */
body.woocommerce-account a.woocommerce-button.view,
body.woocommerce-account a.woocommerce-button.desistimiento {
    display: inline-block;
    box-sizing: border-box;
    padding: 0.55rem 0.95rem !important;
    border-width: 0 !important;
    border-radius: 10px !important;
    font-family: 'Inter', sans-serif;
    font-size: 0.72rem;
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    text-align: center;
}

/* 🔴 FUERA EL DESPLAZAMIENTO AL PASAR EL RATÓN. La regla vieja de "Solicitar
   devolución" llevaba un `transform: translateY(-1px)`, y en esta web ningún
   estado puede cambiar tamaño ni posición: solo color, sombra u opacidad. El
   cambio de fondo que ya tenía se queda como estaba. */
body.woocommerce-account a.woocommerce-button.desistimiento:hover,
body.woocommerce-account a.woocommerce-button.desistimiento:focus,
body.woocommerce-account a.woocommerce-button.desistimiento:focus-visible {
    transform: none !important;
    color: var(--ga-blanco) !important;
}


/* =============================================================================
   CARRITO LATERAL
   =============================================================================
   Panel fijo a la derecha que se abre al pulsar el icono del carrito. Dentro se
   inyecta la página del carrito ENTERA, así que buena parte de este bloque no es
   estilo propio: es RECOLOCAR lo que viene de WooCommerce, que está pensado para
   dos columnas anchas y aquí tiene 460 píxeles.

   🔴 EL PANEL NO PUEDE INFLAR EL VIEWPORT, y por eso en reposo lleva TRES cosas a
   la vez y no una: el transform lo saca de la pantalla, visibility lo quita de la
   vista y del tabulador, y pointer-events le impide interceptar ningún clic. El
   transform por sí solo dejaría una caja de 460px asomando por el borde derecho,
   y en móvil eso es justo lo que ensancha el viewport de maquetación y anula los
   media queries (🪤 nº 1). Con visibility: hidden no hay nada que medir.
   ============================================================================= */

.ga-carrito {
    position: fixed;
    inset: 0;
    z-index: 100000;   /* la cabecera fija está en 1000; los modales de tel/email, en 99999 */

    /* Recorta el panel mientras está fuera de pantalla. En un elemento fijo esto
       no puede dar scroll a la página: no hay nada que desbordar hacia fuera. */
    overflow: hidden;

    /* ——— EL ESTADO DE REPOSO ——— */
    visibility: hidden;
    pointer-events: none;

    /* 🔴 LA visibility SE RETRASA AL CERRAR, Y ESTE TRUCO ES LA CLAVE DE QUE EL
       CIERRE NO DÉ UN TIRÓN. visibility no es una propiedad que interpole: salta
       de visible a hidden. Si saltara al empezar el cierre, el panel desaparecería
       de golpe mientras aún le queda deslizamiento por hacer.

       Con transition-delay igual a la duración del panel (400ms), el salto ocurre
       cuando la animación YA ha terminado. Al abrir no hay espera: la regla de
       .is-abierto pone el retraso a 0s, así que se ve desde el primer fotograma.

       El pointer-events sí cambia al instante en los dos sentidos, y es lo que se
       quiere: en cuanto se manda cerrar, el panel deja de recibir clics. */
    transition: visibility 0s linear 400ms;
}

.ga-carrito.is-abierto {
    visibility: visible;
    pointer-events: auto;
    transition: visibility 0s linear 0s;
}

/* ——— LA CAPA OSCURA ———
   Con el casi negro de marca diluido, nunca negro puro. El respaldo de
   --ga-negro-suave es obligatorio: está en la paleta pero no se declara en el
   :root de style.css, y un var() que no resuelve invalida la declaración entera
   (🪤 nº 15). Aquí eso dejaría el velo transparente y el panel flotando sin fondo.
   La primera declaración cubre además a los navegadores sin color-mix. */
.ga-carrito__velo {
    position: absolute;
    inset: 0;
    background-color: rgba(26, 26, 20, 0.45);
    background-color: color-mix(in srgb, var(--ga-negro-suave, #1a1a14) 45%, transparent);
    opacity: 0;
    /* Algo más corto que el panel (400ms): el fondo termina de oscurecerse justo
       antes de que el panel acabe de entrar, y así el movimiento se lee como uno
       solo en vez de como dos cosas a la vez. */
    transition: opacity 300ms ease;
}

.ga-carrito.is-abierto .ga-carrito__velo {
    opacity: 1;
}

/* ——— EL PANEL ———
   👉 EL ANCHO SE RESUELVE SIN NINGUNA MEDIA QUERY. Pide 460px y el max-width lo
   recorta a lo que haya menos un margen: en escritorio manda el ancho, y en
   cuanto la pantalla baja de unos 480px manda el tope y el panel pasa a ocupar
   todo menos ese margen. Es max-width, no min-width: aquí no se impone ningún
   ancho mínimo a nada.

   El 100% es el de .ga-carrito, que ocupa el viewport, así que no hace falta vw
   —que en escritorio incluye la barra de desplazamiento y dejaría el panel unos
   píxeles más ancho de la cuenta—. */
.ga-carrito__panel {
    position: absolute;

    /* 🔴 SEPARADO DE LOS CUATRO BORDES: ES LO QUE LO HACE FLOTAR. Antes estos tres
       valían 0 y el panel se pegaba arriba, abajo y a la derecha.

       ⚠ EL ALTO LO SIGUEN DANDO top Y bottom, no hay ningún `height` declarado. Es
         importante que siga siendo así: el cuerpo del panel es flex:1 1 auto con su
         propio overflow-y, así que se adapta solo a la altura que quede. Declarar una
         altura aquí sería romper ese ajuste automático.

       ⚠ Y SON VALORES POSITIVOS. Nada de right negativo para esconderlo: una caja
         real fuera del borde derecho ensancha el viewport de maquetación en móvil y
         anula los media queries (🪤 nº 1). De esconderlo se encarga el transform. */
    top: 1.25rem;
    right: 1.25rem;
    bottom: 1.25rem;

    /* 580px. Viene de 460 y pasó por 520: el listado respira más —el nombre del
       producto y la fila de cantidad son los que más lo agradecen— sin llegar a
       comerse la pantalla.

       ⚠ AL CAMBIAR ESTE NÚMERO NO HAY QUE TOCAR NADA MÁS, y conviene saber por qué:

         · el translateX de reposo usa un 100% que es relativo al ancho del PROPIO
           panel, así que se recalcula solo;
         · y el max-width no depende de él: descuenta los dos márgenes del viewport,
           y es quien manda en cuanto la pantalla no da para estos 580px.

       ⚠ ESTE ANCHO ES SOLO PARA ESCRITORIO Y TABLET. El @media de 768px lo devuelve
         a 460px, que es el del cajón pegado. */
    width: 580px;

    /* 🔴 DOS VECES 1,25rem, UNA POR LADO. El valor anterior —calc(100% - 1.25rem)—
       descontaba UN solo margen, el izquierdo, porque el panel iba pegado a la
       derecha. Ahora que `right` ya se come 1,25rem por su lado, hay que descontar
       los dos para que quede el MISMO aire a izquierda y a derecha; con el cálculo
       viejo el margen derecho se habría contado dos veces y el panel se habría ido
       encogiendo hacia la izquierda. */
    max-width: calc(100% - 2.5rem);

    /* Las esquinas de tarjeta, el mismo radio que el resto del proyecto. */
    border-radius: 10px;

    display: flex;
    flex-direction: column;
    box-sizing: border-box;

    background-color: var(--ga-blanco);

    /* Sombra CENTRADA, no lateral. La anterior era -12px 0 34px: proyectaba solo
       hacia la izquierda porque el panel salía del borde derecho y por ahí no había
       nada que sombrear. Flotando se ve por los cuatro lados, así que la sombra tiene
       que caer hacia abajo y alrededor.
       ⚠ Una sombra no ocupa espacio: no puede desbordar ni mover nada. */
    box-shadow: 0 18px 48px rgba(74, 74, 47, 0.22);

    /* 🔴 SE MUEVE CON transform, NUNCA CON right NEGATIVO. Un `right: -460px`
       colocaría una caja real fuera del borde derecho y en móvil eso ensancha el
       viewport de maquetación y anula los media queries (🪤 nº 1). Un transform no
       toca el ancho de maquetación de nada.

       400ms con salida suave y SIN rebote: la curva arranca rápido y frena al
       final, que es lo que hace que un panel de este tamaño se sienta pesado y
       controlado en vez de saltar dentro. Ninguno de los cuatro valores de la
       curva pasa de 1, así que no puede sobrepasar y volver.

       🔴 EL +1.25rem NO ES OPCIONAL, Y ES EL ÚNICO AJUSTE QUE PIDIÓ LA ANIMACIÓN AL
       PASAR A FLOTANTE. El 100% es el ancho del propio panel, así que por sí solo lo
       deja justo en el borde derecho de la pantalla… que ahora ya NO es donde
       descansa: descansa 1,25rem más adentro. Con solo el 100% se quedaría asomando
       exactamente esa franja en reposo. Sumando la separación, sale del todo.

       ⚠ SI ALGÚN DÍA SE CAMBIA `right`, HAY QUE CAMBIAR ESTE NÚMERO CON ÉL. Son las
         dos mitades del mismo cálculo.

       🔴 Y SOLO SE ANIMA EL transform. Ni los offsets, ni el radio, ni la sombra
       llevan transición, y eso es deliberado por dos motivos: animar top/bottom
       obliga a recalcular la maquetación en cada fotograma —tirón asegurado—, y
       además el JS espera el final de la apertura filtrando por
       `e.propertyName === 'transform'`; con dos propiedades animándose, el primer
       transitionend en llegar dispararía terminarApertura() antes de tiempo y el
       carrito se escribiría a mitad del deslizamiento.

       ⚠ Y LOS 400ms NO SE TOCAN: main.js tiene un temporizador de respaldo a 450ms
         calculado sobre ellos. */
    transform: translateX(calc(100% + 1.25rem));
    transition: transform 400ms cubic-bezier(0.22, 0.61, 0.36, 1);
}

.ga-carrito.is-abierto .ga-carrito__panel {
    transform: translateX(0);
}

/* ——— EN MÓVIL, CAJÓN PEGADO: EL EFECTO FLOTANTE ES DE ESCRITORIO Y TABLET ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ NO FLOTA TAMBIÉN AQUÍ. A 360px el panel ya mide 340: quitarle además
   1,25rem por arriba, por abajo y por la derecha lo dejaría estrecho Y bajo, y ahí
   dentro tienen que caber miniatura, nombre, precio, cantidad, aspa, total, la nota
   y el botón. El adorno se comería el sitio justo donde menos sobra —y por aquí pasa
   el 70% del tráfico—. En móvil manda el área útil.

   Se devuelven las TRES cosas que cambian con el tamaño, y las tres tienen que ir
   juntas o el panel queda a medio camino:

     · los offsets a 0, para que vuelva a pegarse;
     · el transform SIN el +1,25rem, porque ya no hay separación que compensar —si se
       quedara el de escritorio, el panel se pasaría de largo al esconderse; no se
       vería mal, pero recorrería 20px de más en cada apertura—;
     · y el max-width de siempre, que descuenta UN margen: aquí solo hay aire por la
       izquierda, así que descontar dos lo encogería sin motivo.

   ⚠ EL RADIO SE QUEDA SOLO EN LAS ESQUINAS IZQUIERDAS. Las derechas se pegan al
     borde de la pantalla: redondearlas dejaría asomar dos muescas del fondo. Es el
     orden de siempre: arriba-izquierda, arriba-derecha, abajo-derecha,
     abajo-izquierda.

   ⚠ NO SE TOCA NI LA DURACIÓN NI LA PROPIEDAD ANIMADA: sigue siendo transform a
     400ms, así que el JS se comporta igual en los dos tamaños.

   🔴 EL CORTE ES 1024px Y NO 768px, Y ESTE CAMBIO TIENE HISTORIA. Estaba en 768 y en
   pantallas intermedias —una tableta, un móvil en horizontal, la vista estrecha de un
   portátil— seguía mandando el panel FLOTANTE de escritorio, con sus 1,25rem de
   separación arriba, abajo y a la derecha. Y esos tres huecos son exactamente lo que se
   veía mal:

     · las dos franjas de arriba y de abajo NO son un fondo del panel —dentro del panel
       no hay ni un color crema: la caja es blanca y todo lo que WooCommerce pinta dentro
       está forzado a `transparent`—. Son los 20px de arriba y de abajo por los que se ve
       la PÁGINA a través del velo. Si detrás está la tienda, cuyo <body> es crema
       (línea 724), esas franjas se leen justo de ese color;
     · y el desajuste del borde derecho es el tercer hueco, el de `right`, que en un
       cajón lateral no tiene ningún sentido: ahí se espera que el panel muerda el borde.

   👉 Subiendo el corte a 1024px —el punto de tableta que ya usa todo el sitio— cualquier
      pantalla que no sea de escritorio recibe el cajón pegado a los bordes, que es como
      debe comportarse. Por encima de 1024px el panel sigue flotando exactamente igual
      que hasta hoy: ahí ese aire es el diseño, no un defecto.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 1024px) {

    .ga-carrito__panel {
        top: 0;
        right: 0;
        bottom: 0;

        /* El ensanche del panel flotante —hoy 580px— es para escritorio y tablet.
           Aquí se conserva el ancho de siempre: entre 480 y 768px el `width` es el
           que manda —por debajo manda el max-width— y ahí 580px no dejarían ni
           asomar el velo. En un cajón pegado, lo que da la sensación de panel es
           justamente ese trozo de fondo que se sigue viendo. */
        width: 460px;

        max-width: calc(100% - 1.25rem);
        border-radius: 10px 0 0 10px;
        transform: translateX(100%);
    }

    /* La cabecera acompaña al panel: aquí solo se curva la esquina de arriba a la
       izquierda, porque la derecha va pegada al borde de la pantalla. */
    .ga-carrito__cabecera {
        border-radius: 10px 0 0 0;
    }
}

/* ——— will-change SOLO MIENTRAS SE MUEVE ———
   Avisa al navegador de que va a animar el transform para que prepare la capa
   antes de empezar, en vez de improvisarla en el primer fotograma.

   🔴 LA CLASE LA PONE Y LA QUITA EL JS, y ese ir y venir es lo importante:
   will-change permanente reserva memoria de vídeo de forma indefinida y en un
   elemento a pantalla completa eso se nota, sobre todo en móviles modestos. Es una
   pista para un momento concreto, no un ajuste que se deja puesto. */
.ga-carrito.is-animando .ga-carrito__panel {
    will-change: transform;
}

/* ——— CABECERA DEL PANEL ———
   Fija arriba: no scrollea con el contenido. */
.ga-carrito__cabecera {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: 1.15rem 1.25rem;
    background-color: var(--ga-blanco);

    /* Ancla del ::after que dibuja la línea. Ver más abajo. */
    position: relative;

    /* 🔴 EL RADIO DE ARRIBA SE REPITE AQUÍ, Y ESA ES LA CAUSA DE QUE LAS ESQUINAS
       SUPERIORES SE VIERAN RECTAS.
       ═══════════════════════════════════════════════════════════════════════
       El panel redondea sus cuatro esquinas, pero esta cabecera tiene FONDO PROPIO
       —el blanco de aquí arriba— y no tenía radio: su rectángulo se pintaba ENCIMA
       del redondeo del panel y le devolvía las esquinas cuadradas por arriba.

       Abajo no pasaba, y por eso el fallo parecía caprichoso: .ga-carrito__cuerpo NO
       declara fondo, así que por ahí se ve el del panel con su curva intacta.

       👉 SE REDONDEA LA CABECERA EN VEZ DE RECORTAR EL PANEL CON overflow. Un
          `overflow: hidden` en el panel también lo habría tapado, pero convierte al
          elemento en contenedor de scroll —el eje libre pasa de `visible` a `auto`
          (🪤 nº 3)— y el panel ya tiene dentro un hijo que scrollea por su cuenta.
          Meter un segundo contenedor de scroll alrededor del que ya funciona es
          justo la clase de cambio que rompe el gesto táctil en Android. Redondeando
          la cabecera se arregla lo que se ve sin tocar cómo se desplaza nada.

       ⚠ SI SE CAMBIA EL RADIO DEL PANEL, HAY QUE CAMBIARLO AQUÍ. Son los mismos
         10px, escritos en dos sitios porque son dos cajas distintas.

       ⚠ Y EN MÓVIL SOLO LA IZQUIERDA, igual que el panel: la esquina superior
         derecha se pega al borde de la pantalla y allí no debe curvarse. Ese ajuste
         está en el @media de 768px, junto al del panel. */
    border-radius: 10px 10px 0 0;
}

/* ——— LA LÍNEA DE LA CABECERA, A LA MISMA ANCHURA QUE LA DEL TOTAL ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ NO ES YA UN border-bottom. Un borde se dibuja por FUERA del padding,
   así que cruzaba la cabecera ENTERA, de borde a borde del panel. La línea de encima
   de "Total de productos", en cambio, es el border-top de un bloque que vive dentro
   de .ga-carrito__cuerpo, y ese cuerpo tiene 1,25rem de padding lateral: su línea
   empieza y acaba 1,25rem más adentro por cada lado.

   Las dos "llegaban al borde de su caja", pero sus cajas no medían lo mismo: 20px de
   diferencia por lado. Esa era toda la divergencia.

   👉 SE IGUALAN POR LA DE ABAJO, no por la de arriba: el contenido del panel —los
      productos, el total, el botón— vive a 1,25rem de los lados, así que una raya
      alineada con él se lee mejor que una que cruza de punta a punta.

   Con un ::after posicionado a left/right 1,25rem, la línea de la cabecera arranca y
   termina exactamente donde la del total.

   ⚠ NO OCUPA ESPACIO, y por eso se hace así y no con padding: es un elemento
     absoluto, no altera el alto de la cabecera ni empuja nada.

   ⚠ UN MATIZ HONESTO SOBRE LA BARRA DE DESPLAZAMIENTO: cuando el listado es largo,
     el cuerpo saca su barra y su área de contenido se estrecha, así que la línea de
     abajo puede quedarse unos píxeles corta por la derecha respecto a esta. Es
     inevitable sin reservar el carril de la barra a costa de desplazar TODO el
     contenido, y no compensa. En móvil no ocurre: allí las barras se superponen y no
     reservan ancho.
   ═══════════════════════════════════════════════════════════════════════════ */
.ga-carrito__cabecera::after {
    content: "";
    position: absolute;
    left: 1.25rem;
    right: 1.25rem;
    bottom: 0;
    border-bottom: 1px solid var(--ga-amarillo-pastel);
}

.ga-carrito__titulo {
    margin: 0;
    font-family: 'Cormorant Garamond', Georgia, serif;
    font-size: 1.5rem;
    font-weight: 600;
    line-height: 1;
    color: var(--ga-verde-oliva-oscuro);
    /* El text-wrap: balance de la regla general de títulos no pinta nada en dos
       palabras y puede partirlas raro (🪤 nº 16). */
    text-wrap: wrap;

    /* 🔴 SEGUNDO INTENTO, Y ESTA VEZ POR GEOMETRÍA Y NO POR EMPUJONES.
       ═══════════════════════════════════════════════════════════════════════
       Aquí hubo un `position: relative; top: 1px` —un empujón óptico— que no
       resolvió. Se ha quitado: si un ajuste a ojo no acierta, apilar otro encima es
       adivinar dos veces.

       EL PROBLEMA DE FONDO ERA QUE LOS DOS ELEMENTOS NO MEDÍAN LO MISMO. El aspa es
       una caja de 2rem que centra su icono dentro. El título, en cambio, era una
       caja de línea de 1,5rem × 1,1 ≈ 1,65rem, y la cabecera se limitaba a alinear
       los centros de DOS CAJAS DE DISTINTO ALTO. Que el resultado cayera centrado
       dependía entonces de las métricas de Cormorant —de cuánto ascendente y cuánto
       descendente reserva la fuente dentro de esa caja—, y "Tu carrito" no tiene ni
       una letra con cola, así que el hueco de abajo quedaba vacío y el texto se leía
       alto.

       👉 AHORA EL TÍTULO ES UNA CAJA DE 2rem QUE CENTRA SU TEXTO, exactamente igual
          que el aspa centra su icono. Dos cajas del mismo alto, cada una centrando
          su contenido y las dos centradas entre sí: ya no depende de la fuente.

       ⚠ min-height Y NO height: si algún día el título fuera más largo y envolviera,
         la caja crece en vez de recortarlo. Y es min-HEIGHT, que sí está permitido;
         lo prohibido es min-width.

       ⚠ EL ALTO DE LA CABECERA NO CAMBIA: el aspa ya medía 2rem y era el elemento
         más alto de la fila, así que la línea divisoria de debajo se queda donde
         estaba.

       ⚠ padding: 0 explícito por si el tema padre le pusiera alguno a los h2: el
         margin ya estaba defendido, el padding no.

       ⚠ Y line-height: 1 para que la caja de línea se ciña al texto y no meta de
         nuevo un hueco asimétrico dentro de los 2rem. */
    padding: 0;
    display: flex;
    align-items: center;
    min-height: 2rem;
}

/* El aspa. Ningún estado cambia tamaño ni posición: el borde existe desde el
   principio en transparente y solo cambia de color. */
/* ——— EL ASPA: SOLO EL TRAZO ———
   Sin fondo, sin borde, sin sombra y sin círculo. El "círculo dorado" que se veía
   era este mismo botón: tenía border-radius: 50% con un borde de 1px que pasaba a
   dorado al posar el ratón, y a 2,25rem eso se lee como una pastilla.

   La caja de 2,25rem se conserva —es la zona de toque, no un adorno— pero ya no
   pinta nada: solo centra el aspa. El !important en el fondo y el borde es por las
   reglas de botón del tema padre, que son más específicas que cualquier selector
   propio razonable (🪤 nº 6). */
.ga-carrito__cerrar {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    justify-content: center;

    /* 🔴 LA CAJA, A LA ALTURA DEL TÍTULO. "Tu carrito" mide 1,5rem de cuerpo con
       line-height 1,1, o sea una caja de algo más de 1,6rem. El aspa venía en
       2,25rem: casi medio rem más alta, y al ser un cuadrado invisible junto a un
       texto eso se lee como un aspa "grande y descolgada" aunque los centros
       coincidan.

       A 2rem la caja sigue siendo cómoda de pulsar —32px, área de toque razonable en
       móvil— y ya no domina la fila.

       ⚠ align-self: center es explícito a propósito. La cabecera ya centra con
         align-items, pero declararlo aquí evita que un `stretch` heredado de las
         reglas de botón del tema padre estire el aspa a la altura de la fila y la
         descoloque. */
    width: 2rem;
    height: 2rem;
    align-self: center;
    padding: 0;
    background: none !important;
    border: 0 !important;
    border-radius: 0;
    box-shadow: none !important;
    cursor: pointer;
    /* Solo se anima el color: ni tamaño ni posición cambian en ningún estado. */
    transition: color 200ms ease;

    /* 🔴 EL !important DEL COLOR ES EL ARREGLO, Y FALTABA. Esta misma regla ya
       defendía el fondo, el borde y la sombra con !important porque las reglas de
       botón del tema padre ganan a un selector de clase (🪤 nº 6)… pero el color
       se quedó sin defender. Resultado: se aplicaba nuestro "sin fondo" y, encima,
       el blanco que el padre le pone al texto de sus botones. Aspa blanca sobre
       panel blanco, o sea invisible. Y solo se volvía dorada al pasar el ratón
       porque ahí el que mandaba era el :hover del padre, no una regla nuestra.

       No era un var() sin resolver: era pura especificidad.

       ⚠ Y EL RESPALDO DEL var() NO ES DECORATIVO AQUÍ. --ga-negro-suave está en la
         paleta del claude.md y se usa en este archivo, pero NO se declara en el
         :root de style.css (🪤 nº 15). Un var() que no resuelve NO cae al valor por
         defecto de la propiedad: la declaración se vuelve inválida y `color`, que es
         heredada, toma la del ancestro… que aquí sería justo el blanco del tema
         padre. Volveríamos al aspa blanca sobre panel blanco. Con el #1a1a14 detrás
         eso no puede pasar. */
    color: var(--ga-negro-suave, #1a1a14) !important;
}

/* 🔴 NEGRA TAMBIÉN CON EL RATÓN ENCIMA Y CON EL FOCO, Y DECLARADO EXPRESAMENTE.
   No es redundante: sin estas líneas, el :hover del tema padre vuelve a ser el
   único que habla en ese estado y decide él el color. Declarándolo aquí, el aspa
   es negra desde que se abre el panel y sigue siéndolo pase lo que pase.

   Que sea el MISMO color que en reposo es deliberado: el aspa no cambia al pasar el
   ratón, igual que antes no cambiaba. Lo único que cambia de estado es el clic. */
.ga-carrito__cerrar:hover,
.ga-carrito__cerrar:focus,
.ga-carrito__cerrar:focus-visible {
    color: var(--ga-negro-suave, #1a1a14) !important;
}

/* Al PULSAR, el aspa pasa al verde oscuro de marca. Es la única señal de estado, y
   dura lo que dura el clic: justo después el panel se cierra. Va después de las
   anteriores y con !important para ganarles: es el único estado que cambia el
   color, y en ningún caso queda blanca ni transparente. */
.ga-carrito__cerrar:active {
    color: var(--ga-verde-oliva-oscuro) !important;
}

/* ——— EL TRAZO SIGUE AL BOTÓN, Y SOLO AL BOTÓN ———
   El SVG del marcado ya viene como debe —`stroke="currentColor"` y `fill="none"`—,
   así que hereda el color de aquí y no hay dos sitios mandando sobre lo mismo.
   Esto lo blinda: son atributos de presentación, y CUALQUIER regla CSS de otro
   sitio que apuntara a `svg` los ganaría sin despeinarse. Con esto, el aspa no
   puede pintarse de otro color aunque alguien lo intente desde fuera. */
/* 🔴 EL DIBUJO, AL TAMAÑO ÓPTICO DEL TÍTULO. El SVG traía 18px por atributo; aquí se
   fija en 1rem (16px), que es prácticamente la altura de las mayúsculas de "Tu
   carrito" —1,5rem de cuerpo dan algo más de 1rem de altura de caja alta—. Con eso
   el aspa y el título pesan lo mismo en la fila.

   El CSS gana al atributo width/height del marcado, así que no hace falta tocar
   footer.php para esto.

   `display: block` por lo mismo que el candado del botón de pagar: un SVG en línea
   se sienta sobre la línea base y arrastra el hueco de los descendentes, y eso lo
   descentraba un par de píxeles dentro de su propia caja. */
.ga-carrito__cerrar svg {
    display: block;
    width: 1rem;
    height: 1rem;
    stroke: currentColor !important;
    fill: none !important;
}

/* Con el teclado hace falta ver dónde está el foco. Se marca con outline, que se
   dibuja FUERA de la caja y no ocupa sitio: no mueve ni agranda nada. */
.ga-carrito__cerrar:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* ——— EL CUERPO ———
   El ÚNICO que scrollea. El overflow va aquí, nunca en html ni en body. */
.ga-carrito__cuerpo {
    flex: 1 1 auto;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding: 1.25rem;
    box-sizing: border-box;
}

.ga-carrito__cargando {
    margin: 2rem 0;
    text-align: center;
    font-family: 'Inter', system-ui, sans-serif;
    font-size: var(--ga-text-sm);
    color: var(--ga-verde-montanas);
}


/* ═══════════════════════════════════════════════════════════════════════════
   LO QUE VIENE DE WOOCOMMERCE, RECOLOCADO PARA 460 PÍXELES
   ═══════════════════════════════════════════════════════════════════════════
   Todo lo de aquí abajo está acotado a .ga-carrito__cuerpo. Son las MISMAS clases
   que usa la página /carrito/, y sin esa acotación se le estaría cambiando el
   diseño a la página real, que tiene que seguir exactamente igual que hoy.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1. DE DOS COLUMNAS A UNA. La página del carrito pone la tabla y los totales
      uno al lado del otro, con anchos en porcentaje y flotados. En el panel van
      apilados: primero los productos, debajo los totales. */
.ga-carrito__cuerpo .woocommerce,
.ga-carrito__cuerpo .woocommerce-cart-form,
.ga-carrito__cuerpo .cart-collaterals,
.ga-carrito__cuerpo .cart_totals,
.ga-carrito__cuerpo .cross-sells {
    width: 100% !important;
    max-width: 100% !important;
    float: none !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* 🔴 AQUÍ VIVE LA LÍNEA QUE SEPARA EL LISTADO DEL TOTAL, Y NO EN LA FILA DEL TOTAL.
   ═══════════════════════════════════════════════════════════════════════════
   Primero se puso como border-top de tr.cart-subtotal, y desde ahí NO salía igual
   que la de la cabecera: ese <tr> es una caja flex dentro de una tabla, y su borde
   solo llegaba hasta donde llegaba su contenido, cortándose por la izquierda. Se ve
   enseguida al compararla con la de "Tu carrito".

   Puesta en .cart-collaterals —un div normal, de nivel bloque— ocupa el ancho entero
   sin depender de cómo se comporte la tabla.

   🔴 Y LOS MÁRGENES NEGATIVOS SON LO QUE LA HACE IDÉNTICA A LA DE ARRIBA. La de la
   cabecera cruza el panel de lado a lado, porque .ga-carrito__cabecera ocupa todo el
   ancho y su borde va por fuera de su padding. Este bloque, en cambio, vive dentro
   de .ga-carrito__cuerpo, que tiene 1,25rem de padding lateral: sin compensarlo, la
   raya quedaría más corta por los dos lados.

   Los -1,25rem de margen la estiran hasta el borde del panel y el padding del mismo
   valor devuelve el CONTENIDO a su sitio, así que el total y el botón no se mueven
   ni un píxel. Las dos líneas quedan del mismo ancho, del mismo grosor y del mismo
   color.

   🔴 AQUÍ HUBO UNOS MÁRGENES NEGATIVOS Y SE HAN QUITADO PORQUE NO SERVÍAN DE NADA.
   Se pusieron para estirar la línea hasta el borde del panel, y NUNCA se aplicaron:
   unas líneas más arriba, el reset que endereza los contenedores de WooCommerce
   incluye .cart-collaterals y le pone

       margin-left: 0 !important;
       margin-right: 0 !important;

   Mismo selector, misma especificidad y con !important: gana siempre esa. Lo que sí
   se aplicaba era el `padding` que los acompañaba —ese no lo pisa nadie—, así que el
   único efecto real de aquel intento fue meter el total, la nota y el botón 1,25rem
   hacia dentro respecto a los productos. Al quitar los dos, el bloque vuelve a
   alinearse con el listado.

   ⚠ SIN MARGEN SUPERIOR. Tenía 1,5rem, y ese aire se sumaba por ENCIMA de la línea:
     dejaba 2,5rem arriba (1rem del último producto + estos 1,5rem) contra 1rem
     abajo, con la raya descentrada. A cero, el aire de arriba lo pone solo el padding
     del último producto y las dos mitades miden 1rem.
   ═══════════════════════════════════════════════════════════════════════════ */
.ga-carrito__cuerpo .cart-collaterals {
    margin-top: 0;
    border-top: 1px solid var(--ga-amarillo-pastel);
}

/* 🔴 TODO EL PANEL EN BLANCO, TAMBIÉN LO QUE VIENE DE FUERA. El panel ya es
   blanco, pero varios de estos bloques traen su propio fondo crema de la hoja de
   WooCommerce del tema y se verían como parches dentro del panel. Aquí se les
   quita: la separación entre productos la da una línea fina, no un cambio de
   fondo.

   Acotado a .ga-carrito__cuerpo, así que la página /carrito/ conserva sus fondos
   tal y como están hoy. */
.ga-carrito__cuerpo .woocommerce,
.ga-carrito__cuerpo .woocommerce-cart-form,
.ga-carrito__cuerpo .cart-collaterals,
.ga-carrito__cuerpo .cart_totals,
.ga-carrito__cuerpo .shop_table,
.ga-carrito__cuerpo .shop_table tbody,
.ga-carrito__cuerpo .shop_table tr,
.ga-carrito__cuerpo .shop_table th,
.ga-carrito__cuerpo .shop_table td {
    background-color: transparent !important;
}

/* 2. LA TABLA DE PRODUCTOS, APILADA. Seis columnas no caben en un panel, y
      estrecharlas las dejaría ilegibles. Cada línea de producto pasa a ser un
      bloque y la fila de cabecera desaparece: solo tiene sentido en una tabla de
      verdad.

      ⚠ SOLO LA TABLA DEL FORMULARIO. La de los totales también es .shop_table,
        pero solo tiene dos columnas, cabe de sobra, y apilarla separaría cada
        concepto de su importe. De ahí el .woocommerce-cart-form por delante. */
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tbody,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tr,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table td {
    display: block;
    width: auto !important;
    box-sizing: border-box;
}

.ga-carrito__cuerpo .woocommerce-cart-form .shop_table thead {
    display: none;
}

.ga-carrito__cuerpo .woocommerce-cart-form .shop_table td {
    padding: 0 !important;
    border: 0 !important;
    text-align: left !important;
}

/* 🔴 FUERA LOS RECUADROS DE WOOCOMMERCE. La hoja de la tienda le pone a
   table.shop_table un borde con esquinas redondeadas, y a la celda de acciones lo
   suyo: dentro del panel eso se leía como dos cajas dibujadas —una alrededor del
   producto y otra alrededor del botón de actualizar— flotando sobre el blanco.

   Aquí no debe haber ninguna caja: el contenido se apoya directamente en el fondo
   del panel y lo único que separa bloques es una línea fina horizontal.

   ⚠ VA ANTES QUE LA REGLA DE LA LÍNEA DE PRODUCTO, Y ESO IMPORTA. Este reset lleva
     !important, así que la raya que separa un producto del siguiente tiene que
     llevarlo también o se la comería. Está puesto, y por eso.

   ⚠ Y ACOTADO A .woocommerce-cart-form, no a todo el cuerpo: el bloque de totales
     tiene sus propias reglas de borde —el filete de encima del subtotal— y este
     reset no puede alcanzarlas. */
.ga-carrito__cuerpo .woocommerce-cart-form,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tbody,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tr,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table th,
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table td {
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
}

/* Algunos temas y la hoja responsive de WooCommerce reimprimen el nombre de la
   columna delante de cada celda con un ::before y el atributo data-title
   ("Precio: 16,90 €"). En una rejilla propia eso sobra: cada dato ya está en su
   sitio y el rótulo solo añade ruido. */
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table td::before {
    display: none !important;
}

/* ——— LA LÍNEA DE PRODUCTO, EN REJILLA ———
   Se abandona por completo la disposición de tabla de WooCommerce: la fila pasa a
   ser una rejilla propia y cada celda se coloca por NOMBRE DE ÁREA, no por el
   orden en que WooCommerce las escribe. Así el marcado se queda como está —que no
   se puede tocar, viene del shortcode— y aquí se decide qué va dónde.

       ┌────────┬──────────────────┬──────────┐
       │        │                  │     X    │  ← eliminar, arriba a la derecha
       │ miniat.│ nombre           │ subtotal │  ← subtotal a la altura del nombre
       │        │ precio unitario  │          │
       │        │ cantidad         │          │
       └────────┴──────────────────┴──────────┘

   🔴 LA COLUMNA DEL MEDIO ES minmax(0, 1fr) Y NO 1fr, y esa diferencia es todo.
   El mínimo por defecto de una pista de rejilla es `auto`, o sea el ancho del
   contenido: un nombre de producto largo ensancharía la columna, y con ella la
   fila y el panel entero. Con el 0 de mínimo, la pista puede encoger y el texto
   parte donde toque. Es la forma de cortar el ancho mínimo SIN usar min-width.

   La X va en su propia fila de la rejilla, dentro del flujo: no es un elemento
   absoluto flotando sobre la miniatura. */
.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tr.cart_item {
    display: grid;

    /* 🔴 CUATRO COLUMNAS, Y LA CUARTA EXISTE SOLO PARA EL ASPA. Antes eran tres y el
       aspa cerraba la fila por abajo, compartiendo banda con el selector de cantidad.
       Ahora sube a la esquina superior derecha, y ahí ya estaba el importe: sin una
       columna propia, los dos se pelearían por la misma celda.

       Con la cuarta, el importe se queda donde estaba —a la altura del nombre— y el
       aspa se pone a su derecha, pegada al borde de la fila.

       ⚠ SOLO EL NOMBRE PUEDE ENCOGER: es el único minmax(0, 1fr). Las otras tres son
         `auto`, o sea justo lo que ocupan su miniatura, su importe y su aspa. Es lo
         que garantiza que la fila nunca sea más ancha que el panel por mucho que se
         alargue el nombre de un producto. */
    grid-template-columns: auto minmax(0, 1fr) auto auto;
    grid-template-areas:
        "miniatura nombre   subtotal eliminar"
        "miniatura precio   .        ."
        "miniatura cantidad .        .";
    column-gap: 0.85rem;
    row-gap: 0.3rem;
    /* 🔴 ARRIBA, NO CENTRADO. Es lo que hace que el nombre arranque a la MISMA
       ALTURA que el borde superior de la miniatura en vez de caer hacia el medio
       de la fila. Con `start`, cada celda se pega al techo de su banda. */
    align-items: start;

    padding: 1rem 0;

    /* 🔴 AQUÍ HABÍA UNA LÍNEA DIVISORIA Y SE HA QUITADO A PROPÓSITO. Era un
       border-bottom de 1px en amarillo pastel que separaba un producto del siguiente.
       Ahora los productos se separan solo por el aire del padding.

       ⚠ SI ALGÚN DÍA SE QUIERE RECUPERAR, TIENE QUE LLEVAR !important. El reset que
         quita los recuadros de WooCommerce, unas líneas más arriba, borra los bordes
         de todas las filas con !important; sin esa marca, la raya no llegaría a
         pintarse y parecería que la regla no funciona. */
}

.ga-carrito__cuerpo .woocommerce-cart-form td.product-remove    { grid-area: eliminar; justify-self: end; }
.ga-carrito__cuerpo .woocommerce-cart-form td.product-thumbnail { grid-area: miniatura; }
.ga-carrito__cuerpo .woocommerce-cart-form td.product-name      { grid-area: nombre; }
.ga-carrito__cuerpo .woocommerce-cart-form td.product-price     { grid-area: precio; }
.ga-carrito__cuerpo .woocommerce-cart-form td.product-quantity  { grid-area: cantidad; }

.ga-carrito__cuerpo .woocommerce-cart-form td.product-subtotal {
    grid-area: subtotal;
    justify-self: end;
    text-align: right !important;
    font-weight: 700;
}

/* La miniatura: en la página del carrito ocupa una columna entera. */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-thumbnail img {
    display: block;
    width: 76px;
    height: auto;
    border-radius: 8px;
}

/* El nombre, a DOS LÍNEAS como mucho, y a partir de ahí puntos suspensivos.

   ⚠ SOLO EL ENLACE DEL NOMBRE. En los productos de eventos, esta misma celda
     lleva además un <dl class="variation"> con los datos de personalización —el
     texto de la etiqueta, las fechas, las notas—, y eso NO se puede recortar: es
     lo que el cliente necesita ver para reconocer su línea. Recortando solo el
     <a> se controla el título y se respeta todo lo demás. */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-name > a {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    overflow-wrap: break-word;
    line-height: 1.35;
}

/* El precio unitario, un punto por debajo del nombre: es un dato de apoyo, no el
   importe que manda —ese es el de la derecha—. */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-price {
    font-size: var(--ga-text-xs);
    opacity: 0.75;
}

/* ——— LA FILA DE CANTIDAD ———
   La etiqueta "Cantidad" delante del selector. No existe en el marcado —WooCommerce
   solo la lleva en un atributo data-title—, así que se pinta con contenido
   generado. Es puramente decorativa: el <input> ya tiene su etiqueta accesible
   propia, así que esto no le quita información a nadie.

   El display:block revierte, SOLO aquí, el `display: none` general que apaga los
   ::before de las celdas (los rótulos que WooCommerce reimprime en móvil). */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-quantity {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-top: 0.35rem;
}

/* ═══════════════════════════════════════════════════════════════════════════
   EL SELECTOR DE CANTIDAD: −  [ n ]  +
   ═══════════════════════════════════════════════════════════════════════════
   Los dos botones los pinta ga_carrito_panel_cantidad_botones() —functions.php
   § 25— alrededor del campo NATIVO de WooCommerce, y solo durante el render del
   panel: /carrito/ y el pago conservan su campo con las flechitas del navegador.

   ⚠ EL INPUT SIGUE SIENDO EL DE WOOCOMMERCE, con su clase .qty y su name. De ese
     name sale la clave de la línea y sobre esa clase escucha el JS, así que aquí
     solo se le cambia el aspecto: ni se sustituye ni se le quita nada.

   ⚠ NINGÚN ESTADO MUEVE NADA: los botones llevan su borde desde el principio y al
     apagarse o al pasar el ratón solo cambian color, fondo y opacidad.
   ═══════════════════════════════════════════════════════════════════════════ */

.ga-carrito__cuerpo .ga-qty {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
}

.ga-carrito__cuerpo .ga-qty__btn {
    box-sizing: border-box;
    /* Cuadrados y del mismo alto que el recuadro del número, para que los tres se
       lean como una sola pieza. */
    width: 1.75rem;
    height: 1.75rem;
    padding: 0;

    display: inline-flex;
    align-items: center;
    justify-content: center;

    font-family: var(--ga-font-body);
    /* Algo más grande que antes: sin recuadro que lo sostenga, el signo tiene que
       sostenerse solo. Sigue siendo más pequeño que el nombre del producto. */
    font-size: 1.25rem;
    line-height: 1;

    color: var(--ga-negro-suave, #1a1a14);

    /* 🔴 SIN CAJA: NI BORDE, NI FONDO, NI RADIO. Los dos signos van sueltos, como
       controles limpios. La caja de 1,75rem se conserva —es la zona de toque, no un
       adorno— pero ya no pinta nada: solo centra el signo y da sitio al dedo.
       Es el mismo criterio que el aspa de cerrar el panel. */
    background-color: transparent;
    border: 0;
    cursor: pointer;

    /* Solo el color y la opacidad se animan: no hay nada más que pueda cambiar. */
    transition: color var(--ga-transition-normal),
                opacity var(--ga-transition-normal);
}

@media (hover: hover) {
    /* Al pasar el ratón, solo cambia el COLOR. Sin recuadro, sin fondo y sin
       desplazamiento: nada se mueve ni aparece de la nada. */
    .ga-carrito__cuerpo .ga-qty__btn:not(:disabled):hover {
        color: var(--ga-naranja-apagado);
    }
}

.ga-carrito__cuerpo .ga-qty__btn:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* En el tope. Solo opacidad y puntero: ni tamaño ni posición. */
.ga-carrito__cuerpo .ga-qty__btn:disabled {
    opacity: 0.35;
    cursor: not-allowed;
}

/* ——— EL RECUADRO DEL NÚMERO ———
   Pequeño y centrado. El ancho es fijo pero en `ch`, que se mide en caracteres: caben
   tres cifras —hasta 999 unidades— sin que el recuadro crezca ni encoja con la fuente.
   ⚠ Es `width`, NUNCA min-width: aquí no se impone ningún ancho mínimo al contenedor. */
.ga-carrito__cuerpo .ga-qty input.qty {
    box-sizing: border-box;
    width: 3.5ch;
    height: 1.75rem;
    padding: 0 0.25rem;

    text-align: center;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    color: var(--ga-negro-suave, #1a1a14);

    border: 1px solid var(--ga-amarillo-pastel);
    border-radius: 6px;
    background-color: var(--ga-blanco);

    /* 🔴 FUERA LAS FLECHITAS NATIVAS: para eso están los dos botones. `textfield` es
       lo que las quita en Firefox; los dos pseudoelementos, en los navegadores de
       WebKit y Blink. Hacen falta los tres. */
    -moz-appearance: textfield;
    appearance: textfield;
}

.ga-carrito__cuerpo .ga-qty input.qty::-webkit-outer-spin-button,
.ga-carrito__cuerpo .ga-qty input.qty::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.ga-carrito__cuerpo .ga-qty input.qty:focus {
    outline: none;
    /* Solo cambia el COLOR del borde; el grosor sigue siendo 1px, así que nada baila. */
    border-color: var(--ga-naranja-apagado);
}

@media (prefers-reduced-motion: reduce) {
    .ga-carrito__cuerpo .ga-qty__btn {
        transition: none;
    }
}

.ga-carrito__cuerpo .woocommerce-cart-form td.product-quantity::before {
    content: "Cantidad";
    display: block !important;
    font-size: var(--ga-text-xs);
    opacity: 0.7;
}

/* El aspa de eliminar abre la fila por ARRIBA a la derecha, a la altura del nombre y
   del importe.

   `start` y no `center`: su banda de rejilla es tan alta como la del nombre, y
   centrada se descolgaría respecto al importe que tiene al lado. Pegada al techo, las
   dos cosas arrancan a la misma altura.

   El margen izquierdo la despega del importe un poco más que el column-gap, para que
   no se lean como una sola pieza; el derecho no hace falta, porque el padding de
   1,25rem de .ga-carrito__cuerpo ya la separa del borde del panel.

   ⚠ SOLO POSICIÓN. El color dorado, la ausencia de fondo y lo que pasa al pulsarla
     siguen donde estaban: aquí no se toca ni un color. */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-remove {
    align-self: start;
    margin-left: 0.35rem;
}

/* Mientras se está eliminando esa línea, el aspa deja de responder. El JS también
   lo comprueba por su cuenta; esto es lo que además lo hace evidente a la vista y
   corta el clic antes de que llegue.

   Solo cambia la opacidad y el puntero: ni tamaño ni posición, como manda la regla
   de estados de todo el sitio. */
.ga-carrito__cuerpo .woocommerce-cart-form td.product-remove a[aria-disabled="true"] {
    opacity: 0.4;
    pointer-events: none;
    cursor: default;
}

/* ——— FUERA "ACTUALIZAR CARRITO" ———
   🔴 SE OCULTA LA FILA ENTERA, NO SOLO EL BOTÓN. La celda de acciones es el último
   <tr> de la tabla del carrito; escondiendo únicamente el botón quedaría una fila
   vacía ocupando su hueco, y lo que se pide es recuperar ese espacio para que el
   primer producto suba a su sitio.

   Ya no hace falta: el importe se actualiza solo al cambiar la cantidad —lo lleva
   el endpoint AJAX propio del panel— y al añadir productos.

   ⚠ NO SE ROMPE NADA DEL FORMULARIO. `display: none` solo deja de PINTAR: los
     campos ocultos que van dentro de esa celda —el nonce del carrito— siguen
     estando en el DOM y se seguirían enviando si el formulario se enviara. Y la
     lógica AJAX de cantidades no depende de este botón para nada: escucha el campo
     de cantidad, no la celda de acciones.

   ⚠ SOLO EN EL PANEL. Va acotado a .ga-carrito__cuerpo, así que en /carrito/ el
     botón sigue exactamente donde está y funcionando igual.

   Son DOS reglas y no una lista con comas a propósito: :has() no lo entienden los
   navegadores anteriores a 2023, y una lista con un selector inválido invalida la
   regla ENTERA. Separadas, el que no entienda :has() al menos aplica la primera y
   el botón desaparece igual. */
.ga-carrito__cuerpo .woocommerce-cart-form td.actions {
    display: none !important;
}

.ga-carrito__cuerpo .woocommerce-cart-form .shop_table tbody tr:has(td.actions) {
    display: none !important;
}

/* ——— FUERA EL CUPÓN ———
   El cupón se aplica en el pago, no aquí. La caja ya no se imprime —el endcabezado
   AJAX desactiva los cupones solo para esa petición—, así que esta regla es una
   red de seguridad: si algún plugin volviera a colar el formulario, aquí no se ve.
   La página /carrito/ y el pago conservan su cupón intacto. */
.ga-carrito__cuerpo .coupon {
    display: none !important;
}

/* 3. QUE NADA SE SALGA A LO ANCHO. Sin esto, un nombre de producto largo o el
      campo del cupón podrían empujar el contenido y darle scroll horizontal al
      panel. Se CORTA el ancho mínimo del contenido; no se impone ninguno. */
.ga-carrito__cuerpo,
.ga-carrito__cuerpo * {
    overflow-wrap: break-word;
}

.ga-carrito__cuerpo input,
.ga-carrito__cuerpo select,
.ga-carrito__cuerpo textarea,
.ga-carrito__cuerpo .button,
.ga-carrito__cuerpo table {
    max-width: 100%;
    box-sizing: border-box;
}

/* ——— LOS TOTALES: SOLO EL SUBTOTAL ———
   En el panel se enseña ÚNICAMENTE el importe de los productos. El envío y el
   total se calculan y se enseñan donde se deciden de verdad: en /carrito/ y en el
   pago, que siguen exactamente igual que hoy —todo esto va acotado a
   .ga-carrito__cuerpo—.

   👉 SE OCULTAN TODAS LAS FILAS Y SE VUELVE A ENSEÑAR LA DEL SUBTOTAL, en vez de
   ir tapando una a una las que sobran. Es a propósito: así, si mañana WooCommerce
   o un plugin añaden una fila nueva —un impuesto, un recargo, un descuento—,
   aparece OCULTA por defecto en vez de colarse en el panel sin avisar. */
.ga-carrito__cuerpo .cart_totals > h2 {
    display: none;
}

/* 🔴 EL !important ES LO QUE HACE QUE ESTO VALGA TAMBIÉN EN MÓVIL, y sin él el
   panel salía con el total por triplicado.

   WooCommerce carga en pantallas pequeñas una hoja aparte con reglas del tipo
   `.woocommerce table.shop_table_responsive tr { display: block }`. Eso puntúa
   0-2-2, y este selector sin ayuda puntúa 0-2-1: en móvil ganaba la suya y las
   filas que aquí se ocultan —envío y total— VOLVÍAN A APARECER. En escritorio esa
   hoja no se aplica, y por eso el fallo solo se veía en el móvil. */
.ga-carrito__cuerpo .cart_totals tr {
    display: none !important;
}

/* 🔴 Y ESTO QUITA LA ETIQUETA REPETIDA. Esa misma hoja de móvil reimprime delante
   de cada celda el nombre de su columna con `content: attr(data-title)` y lo
   flota a la izquierda: de ahí salía el segundo "Total de productos" pegado al
   importe, y de ahí que el importe cayera a un segundo renglón —el texto flotado
   le robaba el ancho—.

   Ya había una regla igual para la tabla de productos, pero acotada a
   .woocommerce-cart-form: no alcanzaba a la de totales. Esta cierra ese hueco.
   `content: none` es lo que de verdad impide que el pseudoelemento se genere; el
   display es el cinturón. */
.ga-carrito__cuerpo .cart_totals th::before,
.ga-carrito__cuerpo .cart_totals td::before {
    content: none !important;
    display: none !important;
}

/* Fuera el aspecto de tabla: ni bordes ni celdas, una línea limpia justo encima
   del botón. */
.ga-carrito__cuerpo .cart_totals .shop_table,
.ga-carrito__cuerpo .cart_totals .shop_table tbody {
    display: block;
    border: 0 !important;
    margin: 0 !important;
}

.ga-carrito__cuerpo .cart_totals tr.cart-subtotal {
    /* !important por lo mismo que la regla de arriba: aquí se vuelve a enseñar la
       única fila que sí queremos, y tiene que ganarle a la hoja de móvil. */
    display: flex !important;
    align-items: baseline;
    justify-content: space-between;
    gap: 1rem;

    /* 🔴 LA LÍNEA QUE SEPARA EL LISTADO DEL TOTAL NO ESTÁ AQUÍ, sino en
       .cart-collaterals. Llegó a ponerse en esta fila como border-top y se quitó:
       este <tr> es una caja flex dentro de una tabla y su borde no llegaba al borde
       izquierdo, así que no salía igual que el de la cabecera. Allí está explicado.

       ⚠ EL AIRE DE LA LÍNEA, REPARTIDO A PARTES IGUALES. Encima quedan los 1rem del
         padding inferior del último producto; debajo, el padding SUPERIOR de esta
         fila. Por eso ese es 1rem y no los 0,9rem que tenía. Si algún día se toca el
         padding de tr.cart_item, hay que mirar ese número.

       🔴 Y EL PADDING INFERIOR ES CASI CERO A PROPÓSITO: ES LO QUE AGRUPA EL TOTAL
         CON SU NOTA. Debajo va "IVA incluido…", que no es un bloque aparte sino la
         letra pequeña de este importe; separarla un rem entero las hacía parecer dos
         cosas sueltas. Pegada, se leen como una sola pieza.

         El hueco que de verdad separa —el que anuncia que ahí abajo empieza otra
         cosa, el botón— lo pone el margen inferior de la nota, no este padding.
         Arriba y abajo NO tienen por qué medir igual: cada uno hace un trabajo
         distinto. */
    padding: 1rem 0 0.15rem;
    margin-bottom: 0;
    font-size: 1.05rem;
}

.ga-carrito__cuerpo .cart_totals tr.cart-subtotal th,
.ga-carrito__cuerpo .cart_totals tr.cart-subtotal td {
    display: block !important;
    width: auto !important;
    padding: 0 !important;
    border: 0 !important;
    background: none !important;
    /* La hoja de móvil de WooCommerce flota las celdas para simular columnas. Aquí
       la fila ya es flexible y el flotado solo estorba: descolocaba el importe. */
    float: none !important;
}

.ga-carrito__cuerpo .cart_totals tr.cart-subtotal td {
    text-align: right !important;
    font-weight: 700;
    color: var(--ga-verde-oliva-oscuro);
    /* El importe, siempre en un solo renglón. Es corto —cuatro o cinco
       caracteres—, así que no hay riesgo de que se salga: lo que se evita es que
       parta entre la cifra y el símbolo del euro. */
    white-space: nowrap;
}

/* Finalizar compra, a todo el ancho: es la acción principal del panel. */
/* ——— "FINALIZAR COMPRA" ———
   👉 POR QUÉ SOBRESALÍA. El botón se veía más ancho que el listado y que la fila
   del importe, y llegaba hasta el canto del panel: algo —el relleno lateral que
   WooCommerce le da a .wc-proceed-to-checkout, o un margen del tema padre— lo
   sacaba fuera de la columna de contenido.

   ⚠ NO HE PODIDO SEÑALAR LA REGLA EXACTA: ni el CSS de WooCommerce ni el de Astra
     están en este repositorio. En vez de adivinarla, se anulan a la vez las dos
     vías por las que un bloque puede escaparse de su columna —relleno y margen
     laterales— en el envoltorio y en el propio botón. Venga de donde venga, el
     botón queda clavado al ancho del contenido.

   Así arranca y termina exactamente donde lo hacen las líneas de producto y la
   fila de "Total de productos": todos se apoyan en el mismo relleno de
   .ga-carrito__cuerpo. */
.ga-carrito__cuerpo .wc-proceed-to-checkout {
    padding-left: 0 !important;
    padding-right: 0 !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
}

.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button {
    /* 🔴 FLEX PARA PONER EL CANDADO AL LADO DEL TEXTO. Era `block` con text-align
       centrado; en cuanto el botón lleva un icono y un texto, centrar los dos y
       alinearlos por su eje pide flex. El alto NO cambia: no se declara ni altura ni
       relleno vertical, así que lo sigue dando el mismo texto de antes.

       El icono lo pinta ga_carrito_panel_boton_pagar() —functions.php § 25—, que
       sustituye el botón de WooCommerce solo durante el render del panel. */
    display: flex;
    align-items: center;
    justify-content: center;
    /* En `em`, así que el hueco crece y encoge con la letra del botón. */
    gap: 0.5em;
    box-sizing: border-box;
    width: 100% !important;
    max-width: 100% !important;
    margin-left: 0 !important;
    margin-right: 0 !important;

    text-align: center;

    /* ⚠ EL border-radius SE FUE DE AQUÍ, A SU PROPIA REGLA UNAS LÍNEAS MÁS ABAJO.
       Desde aquí NO SE APLICABA: lo pisaba woocommerce.css. Ver allí el porqué.

       ⚠ NI ALTURA NI RELLENO VERTICAL: no se declara ninguna de las dos, así que el
         botón conserva exactamente el alto que tiene hoy. El relleno se lo pone
         woocommerce.css (padding: 1rem 2rem !important) y ahí se queda. */

    /* 🔴 SIN EL RESALTADO DEL NAVEGADOR MÓVIL. Al tocar un enlace, Android y iOS
       pintan encima su propio velo —un gris o azul translúcido— que se sumaba al
       color del botón y daba ese tono oscuro raro. En transparente, el único que
       decide el color al pulsar es el CSS de aquí abajo. No cambia nada en
       escritorio: esta propiedad solo existe en los navegadores táctiles. */
    -webkit-tap-highlight-color: transparent;
}

/* ——— LA NOTA DE IMPUESTOS Y ENVÍO ———
   Va entre el total y el botón de pagar, y la pinta ga_carrito_panel_boton_pagar()
   —functions.php § 25— justo antes del <a>.

   Es una nota, no un mensaje: cuerpo pequeño y el verde de marca atenuado, el mismo
   recurso que el precio unitario de cada línea. Así informa sin competir con el
   importe que tiene encima ni con el botón que tiene debajo.

   ⚠ EL AIRE, EQUILIBRADO A LOS DOS LADOS: 1rem hasta el total y 1rem hasta el botón,
     que es la misma medida que se usa alrededor de la línea divisoria.

   ⚠ SIN nowrap NI ALTURA FIJA. A 360px la frase ocupa dos renglones y tiene que poder
     hacerlo; el overflow-wrap es el cinturón para que una palabra larga no empuje el
     ancho del panel. */
.ga-carrito__cuerpo .ga-carrito__nota {
    /* 🔴 CERO ARRIBA Y AIRE ABAJO, Y ESE DESEQUILIBRIO ES EL PUNTO.
       Arriba no hay margen porque la nota va pegada al total: es su letra pequeña,
       no un bloque aparte —el padding inferior de la fila del total también está casi
       a cero por lo mismo—.

       Abajo sí hay hueco, y es el ÚNICO separador real de esta zona: es lo que
       agrupa "total + nota" como una cosa y deja claro que el botón es otra. Este
       margen es el que hay que tocar si el botón se ve apretado o suelto. */
    margin: 0 0 1.25rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.45;
    color: var(--ga-verde-oliva-oscuro);
    opacity: 0.75;
    overflow-wrap: break-word;
}

/* ——— LAS ESQUINAS REDONDEADAS DEL BOTÓN DE PAGAR ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 ESTA REGLA EXISTE APARTE Y CON EL `body` DELANTE POR UN MOTIVO CONCRETO: DESDE
   LA REGLA DE ARRIBA EL border-radius NO LLEGABA A APLICARSE NUNCA.

   Quien lo pisaba está en assets/css/woocommerce.css:

       .woocommerce .wc-proceed-to-checkout a.checkout-button {
           border-radius: 0 !important;
       }

   Y gana por dos motivos a la vez:

     · ESPECIFICIDAD. Ese selector es 0-3-1 —tres clases y el elemento `a`— y el de
       arriba era 0-3-0. Con !important en los dos, decide la especificidad.
     · ORDEN DE CARGA. woocommerce.css declara 'gran-almazara-main' como dependencia
       en el wp_enqueue_style, así que se imprime DESPUÉS: a igualdad, gana él.

   El botón del panel llevaba desde el principio las esquinas rectas, y no se veía
   como un fallo porque parecía una elección de diseño.

   👉 LA SALIDA NO ES UN HACK, ES IGUALAR EL TERRENO. Se añade `body` al principio y
      se nombra el elemento (`a.checkout-button`), con lo que el selector pasa a
      0-3-2 y se pone por encima de aquel. Es el MISMO recurso que ya documenta el
      bloque de Mi Cuenta de este archivo —"sin el body. delante, estas reglas no
      pintarían nada por muchos !important que llevaran"—, y por la misma razón.

   ⚠ SIGUE ACOTADO AL PANEL: .ga-carrito__cuerpo está en medio del selector, así que
     /carrito/ y el pago conservan su botón tal y como está hoy.

   ⚠ EL !important SIGUE HACIENDO FALTA aunque el selector ya gane por especificidad:
     enfrente hay un `border-radius: 0 !important`, y una declaración normal pierde
     contra una marcada por mucha especificidad que tenga. Las dos cosas —el peso del
     selector y la marca— son necesarias aquí.

   ⚠ ESTE ES EL ÚNICO SITIO donde este botón decide sus esquinas. Hubo un 999px de
     píldora puesto para comprobar de un vistazo que el redondeo llegaba a aplicarse;
     ya confirmado, queda en el valor definitivo.
   ═══════════════════════════════════════════════════════════════════════════ */
body .ga-carrito__cuerpo .wc-proceed-to-checkout a.checkout-button {
    border-radius: 10px !important;
}

/* ——— EL CANDADO DEL BOTÓN DE PAGAR ———
   Medidas en `em` para que escale con el texto: si algún día cambia el cuerpo de
   letra del botón, el icono lo sigue solo y no hay dos números que sincronizar. Algo
   por debajo de la altura de la línea, para que acompañe al texto sin competir.

   ⚠ NO SE LE DA COLOR AQUÍ, Y ES A PROPÓSITO. El SVG lleva stroke="currentColor", así
     que toma el del texto del botón en cada estado —reposo, hover, foco, pulsado— sin
     que haya que repetir ni un color ni mantenerlos sincronizados.

   ⚠ flex-shrink: 0 para que no se aplaste si el texto se alargara con otra
     traducción; el que cede es el texto, que sí puede envolver.

   ⚠ NADA CAMBIA DE TAMAÑO NI DE POSICIÓN EN NINGÚN ESTADO: el icono no se declara en
     ninguna regla de :hover, :focus ni :active, así que se queda quieto. */
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button .ga-carrito__pagar-icono {
    /* ⚠ SI EL CANDADO NO SE RECONOCE, MIRA ESTE NÚMERO ANTES QUE EL DIBUJO. El icono
       es de LÍNEA, con un trazo de 2 sobre un lienzo de 24: a 1,05em —unos 15px— ese
       trazo se queda en poco más de un píxel, y ahí cualquier icono de contorno se
       desdibuja. Ya se probó a cambiar el trazado por una silueta rellena y se
       revirtió; lo que no se ha probado todavía es subir el tamaño. */
    width: 1.05em;
    height: 1.05em;
    flex-shrink: 0;

    /* 🔴 `block` Y NO EL `inline` DE SERIE, Y ESO ES LO QUE LO CENTRA DE VERDAD. Un
       SVG en línea se sienta sobre la línea base del texto y arrastra el hueco que el
       navegador reserva bajo ella para los descendentes —la cola de la "p", la "j"—,
       así que quedaba unos píxeles por encima del centro por mucho que el contenedor
       dijera align-items: center. En bloque desaparece ese hueco y el centrado del
       flex es exacto.

       (Aquí había un vertical-align: middle que no hacía nada: esa propiedad solo
       tiene efecto en contexto inline, y este SVG es un ítem flex.) */
    display: block;
}

/* ——— LOS ESTADOS DEL BOTÓN ———
   🔴 EL COLOR AL PULSAR SE FIJA AQUÍ Y NO SE HEREDA DE NADIE. El tono oscuro raro
   que salía al tocarlo en el móvil venía de fuera: el velo del navegador —ya
   desactivado arriba— más lo que el tema padre le pone a sus botones en :active,
   que suele ser un oscurecido por filtro o una variante del color de fondo. Al
   declarar aquí las cuatro cosas —fondo, degradado, texto y filtro— no queda nada
   que otro pueda cambiar por su cuenta.

   Verde oscuro de marca con el texto en blanco: 8,8:1 de contraste, de sobra.

   Ni tamaño ni posición se mueven en ningún estado: el transform se anula, y ni el
   relleno ni la altura se declaran en ninguna parte de este bloque. */
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:hover,
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:focus,
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:focus-visible,
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:active {
    transform: none !important;
}

.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:focus,
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:focus-visible,
.ga-carrito__cuerpo .wc-proceed-to-checkout .checkout-button:active {
    background-color: var(--ga-verde-oliva-oscuro) !important;
    /* Por si el tema padre le pone un degradado: uno de fondo taparía el color. */
    background-image: none !important;
    color: var(--ga-blanco) !important;
    /* Los oscurecidos por filtro son la otra forma habitual de pintar un :active,
       y no los tapa ningún background. */
    filter: none !important;
    opacity: 1 !important;
}

/* 4. Carrito vacío: el aviso de WooCommerce centrado y con aire. */
.ga-carrito__cuerpo .cart-empty,
.ga-carrito__cuerpo .return-to-shop {
    text-align: center;
}

/* ——— 5. "VOLVER A LA TIENDA", EL BOTÓN DEL CARRITO VACÍO ———
   ═══════════════════════════════════════════════════════════════════════════
   Se veía apagado, como deshabilitado. Y el motivo, tras revisar los cuatro CSS del
   tema, los de Astra y el que Astra imprime en la propia página, es que NADIE LE DABA
   COLOR: no hay ninguna regla con `opacity`, ni un fondo con alfa, ni un `filter`, ni
   un estilo de deshabilitado. Simplemente **era el único botón del panel sin vestir**.

   El marcado que devuelve WooCommerce cuando el carrito está vacío es:

       <div class="wc-empty-cart-message">
           <div class="cart-empty woocommerce-info">Tu carrito está vacío.</div>
       </div>
       <p class="return-to-shop"><a class="button wc-backward">Volver a la tienda</a></p>

   👉 Y ahí está la clave de por qué se quedó fuera: el botón NO va dentro del aviso,
      es un hermano. La regla que sí viste botones —`.woocommerce-info a.button.wc-forward`,
      la del "Ver carrito"— exige estar dentro del aviso Y la clase wc-forward; este
      enlace no cumple ninguna de las dos. Se quedaba con lo que le llegara de fuera.

   Se le da el mismo lenguaje que a su hermano: dorado de marca pleno, texto blanco y el
   radio de marca. Mismo tamaño, misma posición, mismo texto: solo color.

   ⚠ LOS !important, POR LA RAZÓN DE SIEMPRE EN ESTA TIENDA (🪤 nº 6): Astra y WooCommerce
     capturan `.button` con selectores que ganan a cualquier clase propia. Van solo sobre
     las tres propiedades que deciden que se vea sólido —fondo, color y borde—, que es el
     mismo criterio que ya usa la regla del "Ver carrito" unas líneas más abajo.

   ⚠ EL opacity: 1 ES DELIBERADO aunque hoy nadie la baje: es la propiedad que se
     sospechaba culpable, y dejarla declarada cierra esa puerta para siempre.

   ⚠ SOLO CAMBIA EL COLOR EN HOVER Y FOCO, al verde oliva de marca. Ni tamaño, ni
     posición, ni sombra. El foco de teclado conserva además su contorno.
   ═══════════════════════════════════════════════════════════════════════════ */
.ga-carrito__cuerpo .return-to-shop a.button {
    opacity: 1;
    background-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-blanco) !important;
    border: 1px solid var(--ga-naranja-apagado) !important;
    border-radius: var(--ga-radius-md);
    /* Solo el color se anima: ni tamaño ni posición cambian en ningún estado. */
    transition: background-color 200ms ease, border-color 200ms ease;
}

.ga-carrito__cuerpo .return-to-shop a.button:hover,
.ga-carrito__cuerpo .return-to-shop a.button:focus,
.ga-carrito__cuerpo .return-to-shop a.button:focus-visible {
    background-color: var(--ga-verde-oliva-oscuro) !important;
    border-color: var(--ga-verde-oliva-oscuro) !important;
    color: var(--ga-blanco) !important;
}


/* =============================================================================
   EL AVISO DE "PRODUCTO AÑADIDO" — SU BOTÓN Y SU FOCO
   =============================================================================
   El recuadro que WooCommerce pinta al añadir algo desde la ficha: "2 × … han sido
   añadidos a tu carrito" con un botón "Ver carrito". Ese botón abre ahora el panel
   lateral en vez de navegar (lo intercepta gaCarritoPanel en main.js); aquí solo se
   resuelve su aspecto y el contorno que salía al cargar.
   ============================================================================= */

/* ——— 4. EL RECUADRO VERDE AL CARGAR ———
   🔴 ERA EL ANILLO DE FOCO. WooCommerce enfoca el aviso por accesibilidad nada más
   pintarlo, para que un lector de pantalla lo anuncie; el navegador dibuja
   entonces su contorno de foco, y con el color de acento del tema eso se ve como
   un marco verde que parece una selección.

   No se quita el outline a secas —eso dejaría a quien navega con el teclado sin
   saber dónde está—: se quita SOLO cuando el foco llega por programa, que es
   exactamente la diferencia entre :focus y :focus-visible. Con el teclado, el
   contorno sigue saliendo, y además en dorado de marca.

   El outline no ocupa sitio en la maquetación: no mueve ni agranda nada. */
.woocommerce-message:focus,
.woocommerce-info:focus,
.woocommerce-error:focus {
    outline: none;
}

.woocommerce-message:focus-visible,
.woocommerce-info:focus-visible,
.woocommerce-error:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* ——— 3. EL BOTÓN "VER CARRITO" ———
   ⚠ EL !important Y LA CLASE REPETIDA NO SON UN ADORNO. En assets/css/woocommerce.css
     hay un `.woocommerce-message .button` que fija fondo, color y `border-radius: 0`
     con !important, y ese archivo se carga DESPUÉS que este —depende de él en el
     wp_enqueue_style—. Sumando la clase del enlace (0-3-1 frente a 0-2-0) y el
     !important, esta regla gana; sin las dos cosas no pintaría nada. */
.woocommerce-message a.button.wc-forward,
.woocommerce-info a.button.wc-forward {
    background-color: var(--ga-naranja-apagado) !important;
    color: var(--ga-blanco) !important;
    border-radius: 8px !important;
    /* Solo se anima el color: ni tamaño ni posición cambian en ningún estado. */
    transition: background-color 200ms ease, color 200ms ease !important;
}

.woocommerce-message a.button.wc-forward:hover,
.woocommerce-message a.button.wc-forward:focus,
.woocommerce-message a.button.wc-forward:focus-visible,
.woocommerce-info a.button.wc-forward:hover,
.woocommerce-info a.button.wc-forward:focus,
.woocommerce-info a.button.wc-forward:focus-visible {
    background-color: var(--ga-verde-oliva-oscuro) !important;
    color: var(--ga-blanco) !important;
    /* Los botones de la tienda traen un desplazamiento al pasar el ratón; aquí se
       anula, porque ningún estado puede mover ni redimensionar nada. */
    transform: none !important;
}


/* ——— MOVIMIENTO REDUCIDO ———
   El panel se sigue abriendo y cerrando igual: lo que se quita es el
   deslizamiento y el fundido, no la funcionalidad. */
@media (prefers-reduced-motion: reduce) {

    /* Incluida la del contenedor: si se dejara su transition-delay de 400ms, al
       cerrar el panel se quedaría visible ese tiempo sin animación ninguna, que es
       peor que el propio deslizamiento. Aquí todo es instantáneo. */
    .ga-carrito,
    .ga-carrito.is-abierto,
    .ga-carrito__velo,
    .ga-carrito__panel,
    .ga-carrito__cerrar {
        transition: none;
    }
}


/* =============================================================================
   CHECKOUT Y MI CUENTA — CABECERA CORTA
   =============================================================================
   Las dos son páginas normales de WordPress con un shortcode dentro
   —[woocommerce_checkout] y [woocommerce_my_account]—, así que las sirve page.php:
   la misma plantilla genérica que el aviso legal o cualquier otra página suelta.
   De ahí viene la franja grande de arriba, que es .ga-page-hero; el título que sale
   en ella —"Resumen del Pedido", "Mi Cuenta"— es el TÍTULO DE LA PÁGINA, que vive
   en la base de datos, no en el tema.

   Entre el hero (6rem arriba y 4rem abajo) y el relleno superior de
   .ga-section__inner (otros 6rem) había un montón de aire por encima de lo único
   que importa en estas dos pantallas: el formulario y los datos del cliente. Había
   que bajar para ver el primer campo.

   🔴 LAS DOS PÁGINAS COMPARTEN SELECTOR Y CIFRAS, Y ESO ES EL PUNTO DE ESTE BLOQUE.
   Antes esto era solo del checkout; al añadir Mi Cuenta se podían haber escrito dos
   bloques gemelos, y ahí el fallo estaba cantado: se retoca uno, se olvida el otro y
   las dos pantallas privadas del cliente acaban con cabeceras de distinto alto sin
   que nadie sepa por qué. Con los selectores agrupados hay UNAS SOLAS CIFRAS.

   ⚠ ESTE BLOQUE SOLO TOCA LA CABECERA Y EL AIRE, Y ES A PROPÓSITO. Hubo una versión
     que además subía el ancho del checkout a 1200 px y repartía el formulario y el
     resumen en dos columnas al 60/40. Se ha REVERTIDO: rompía el bloque "Tu pedido".
     El checkout vuelve a su columna estrecha de 800 px —la que le da
     .ga-section__inner--narrow en page.php— con el resumen dentro de su caja de
     siempre. No volver a tocar el ancho ni las columnas sin comprobar antes qué le
     pasa a ese bloque.

   🔴 TODO VA ACOTADO A LAS DOS CLASES DE BODY que pone WooCommerce, y a ninguna más.
   Las reglas BASE de .ga-page-hero, .ga-section__inner y body{padding-top} no se
   tocan: el resto de páginas que usan page.php —legales, privacidad, cookies,
   condiciones— conservan su hero grande, que es lo que les conviene.
   ============================================================================= */

/* 🔴 AQUÍ SE TIÑÓ EL FONDO DEL BODY DE CREMA, Y SE HA QUITADO. NO SE VUELVE A HACER.
   ═══════════════════════════════════════════════════════════════════════════
   El body reserva padding-top: var(--ga-nav-height) para dejar sitio a la cabecera
   fija, y ese hueco deja ver el fondo del body. Se probó a ponerlo crema en estas dos
   páginas —lo mismo que hace body.woocommerce-shop en la tienda— para que el hueco no
   se leyera como una franja blanca entre la cabecera y la banda del título.

   El efecto secundario fue el que tumbó la idea: .ga-page-contenido NO TIENE FONDO
   PROPIO, así que ese crema no se quedaba en los 80 px del hueco —teñía la página
   ENTERA, formulario de pago incluido—. Estas dos pantallas van en blanco.

   👉 Y LA FRANJA DEJA DE MOLESTAR SOLA. Lo que cantaba era el contraste
      crema-blanco-crema; con el fondo en blanco, el hueco y el contenido son del
      mismo color y no hay ninguna costura que ver. No hay nada que tapar.

   ⚠ La tienda es otro caso y su regla sigue en pie: allí el crema SÍ se quiere en
     toda la superficie, así que teñir el body es exactamente lo que toca.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ——— 1. LA BANDA DEL TÍTULO: COMPACTA Y SIN FRANJA BLANCA ENCIMA ———
   ═══════════════════════════════════════════════════════════════════════════
   Esta única regla resuelve las dos cosas a la vez, y conviene ver por qué son la
   misma cosa.

   EL PROBLEMA DE LA FRANJA. El body reserva padding-top: var(--ga-nav-height) para
   que el contenido no quede debajo de la cabecera fija. Ese hueco deja ver el fondo
   del body —blanco— justo entre la cabecera (crema) y la banda del título (crema),
   y se lee como una raya blanca metida en medio.

   LA SOLUCIÓN: QUE LA BANDA SUBA A TAPARLO. El hero se sube con un margin-top
   negativo de exactamente la altura de la cabecera, así que su fondo crema pasa a
   cubrir ese hueco y la costura desaparece. Y para que el TÍTULO no se vaya con él y
   acabe debajo de la cabecera, el padding superior compensa el tiro: la misma altura
   otra vez, más el aire que se quiera.

   🔴 ESTE ES EL PATRÓN DEL PROYECTO, NO UN INVENTO. Es lo mismo que hacen
   .ga-home-hero y el hero de Nosotros con esta misma cabecera fija: subir con
   margin-top negativo y compensar por dentro. Se reutiliza en vez de teñir nada.

   🔴 Y POR ESO NO SE TIÑE EL BODY. Se probó, y el efecto secundario lo tumbó:
   .ga-page-contenido no tiene fondo propio, así que el crema no se quedaba en el
   hueco —teñía la página entera, formulario de pago incluido—. Con este mecanismo el
   crema llega SOLO hasta donde llega la banda, y el contenido de debajo sigue blanco,
   que es lo que se quiere.

   ⚠ EL CÁLCULO SE AJUSTA SOLO EN MÓVIL. --ga-nav-height se redefine a
     --ga-nav-height-mobile dentro del @media de 768px, así que el margen negativo y
     la compensación siguen valiendo lo que mida la cabecera en cada ancho. No hay
     que duplicar nada para 360 px, y no puede descuadrarse si algún día cambia la
     altura de la cabecera.

   ⚠ EL FONDO CREMA DE LA BANDA NO SE TOCA: lo pone la regla base de .ga-page-hero,
     el mismo que en las demás páginas. Aquí solo se recolocan margen y relleno.

   ⚠ NADA DE ESTO PUEDE DESBORDAR A LO ANCHO: solo se tocan margen y relleno
     VERTICALES. El ancho del hero sigue siendo el suyo de siempre.
   ═══════════════════════════════════════════════════════════════════════════ */
/* ——— A) LAS QUE SÍ TIENEN CABECERA ———
   Mi Cuenta y la pantalla de "Pedido recibido". Aquí el margen negativo hace falta: sube
   la banda para tapar el hueco que el body reserva a la cabecera fija, y el padding lo
   compensa para que el título no se meta debajo. */
body.woocommerce-account .ga-page-hero,
body.woocommerce-checkout.woocommerce-order-received .ga-page-hero {
    margin-top: calc(-1 * var(--ga-nav-height));
    padding: calc(var(--ga-nav-height) + 0.875rem) 0 0.875rem;
}

/* ——— B) EL CHECKOUT DE PAGO: SIN BANDA DE TÍTULO ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 AQUÍ NO SE OCULTA SOLO EL TÍTULO: SE VA LA BANDA ENTERA, Y ES DELIBERADO.
   Quitando únicamente el <h1> quedaba una franja crema de más de dos rem con nada
   dentro —el hero es una caja con fondo propio, no un simple contorno del texto—, y
   una banda de color vacía sobre un formulario de pago se lee como un fallo de
   maquetación, no como diseño.

   Como además esta pantalla ya no tiene cabecera del sitio, el resultado es el que se
   busca: el formulario arranca limpio arriba, sin franja hueca y sin nada por encima
   que distraiga de pagar.

   ⚠ SE VA TAMBIÉN LO QUE EL HERO LLEVABA DENTRO: page.php pinta ahí las migas de pan
     de Rank Math cuando el plugin está activo. En un checkout no aportan nada —no hay
     dónde navegar, y de hecho tampoco hay cabecera— así que su marcha es coherente.

   ⚠ POR CSS Y NO TOCANDO page.php, por lo mismo que la cabecera del sitio en esta
     misma página: esa plantilla la comparten las legales y condicionarla allí sería
     meter un caso particular en un archivo común. Con display:none el <h1> tampoco
     recibe foco ni lo lee un lector de pantalla.

   ⚠ "PEDIDO RECIBIDO" QUEDA FUERA, como en todo este bloque: allí el cliente ya ha
     pagado, conserva cabecera y estructura normales, y su banda de título sigue
     intacta gracias al :not().

   👉 Al irse la banda, las reglas de margen y padding que tenía el hero aquí ya no
      pintan nada y se han retirado con ella. El aire de arriba lo pone ahora el
      contenido, unas líneas más abajo. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-page-hero {
    display: none;
}

/* 🔴 Y AQUÍ ESTABA EL AIRE DE VERDAD. LEER ESTO ANTES DE VOLVER A TOCAR LOS NÚMEROS
   DE ARRIBA.
   ═══════════════════════════════════════════════════════════════════════════
   El padding del hero NO era lo que mantenía la banda alta. Dentro del hero hay un
   .ga-section__inner, y ese conserva su regla base:

       .ga-section__inner { padding: var(--ga-space-2xl) var(--ga-space-md); }

   O sea SEIS REM por arriba y otros seis por abajo, dentro de la banda. La regla
   .ga-page-hero .ga-section__inner que ya existía solo le pone position y z-index:
   nunca tocó ese relleno.

   Con eso, el aire real era ~7rem arriba y ~8rem abajo. Por eso bajar el padding del
   hero de 2rem a 1.25rem apenas se notaba: movía el 10 % del problema. Quien vuelva
   a ver la banda alta que empiece por aquí y no por los números de la regla anterior.

   ⚠ SOLO EL VERTICAL. El relleno horizontal se conserva —de él sale el margen
     lateral del título—, así que se ponen a cero las dos propiedades sueltas y no el
     atajo `padding`, que se llevaría también los lados y pegaría el texto al borde
     en móvil.

   ⚠ Y EL MARGEN DEL ÚLTIMO HIJO, TAMBIÉN A CERO. .ga-page-hero__titulo lleva un
     margin-bottom de 1rem que se suma por debajo y rompía la simetría por mucho que
     los dos paddings coincidieran. Va con :last-child a propósito: si Rank Math pinta
     las migas de pan debajo del título, el título YA NO es el último y conserva su
     separación con ellas; el que se queda sin margen es el de abajo del todo, que es
     el que sobra. Así vale igual haya migas o no, sin tener que saberlo.

   Con las dos cosas, el aire visible pasa a ser exactamente el padding del hero:
   0,875rem arriba y 0,875rem abajo. Fino y simétrico de verdad.
   ═══════════════════════════════════════════════════════════════════════════ */
body.woocommerce-checkout .ga-page-hero .ga-section__inner,
body.woocommerce-account .ga-page-hero .ga-section__inner {
    padding-top: 0;
    padding-bottom: 0;
}

body.woocommerce-checkout .ga-page-hero .ga-section__inner > *:last-child,
body.woocommerce-account .ga-page-hero .ga-section__inner > *:last-child {
    margin-bottom: 0;
}

/* 🔴 Y EL MARGEN DE ARRIBA DEL TÍTULO, QUE ERA EL QUE LO DESCENTRABA.
   ═══════════════════════════════════════════════════════════════════════════
   Con los dos paddings del hero ya iguales —0,875rem arriba y 0,875rem abajo— el
   título seguía cayendo pegado al borde inferior, con bastante más crema encima que
   debajo. El motivo no estaba en ninguna regla de este archivo, y por eso costaba
   verlo:

     · la regla general `h1, h2, h3, h4, h5, h6` del tema fija familia, grosor,
       interlineado y color, pero NO declara `margin`;
     · y .ga-page-hero__titulo solo declara `margin-bottom`.

   Nadie pone el margen SUPERIOR, así que el <h1> se queda con el del navegador
   —margin-block-start: 0.67em—, que sobre un cuerpo --ga-text-5xl son más de 2rem
   metidos por encima del título. De ahí que arriba hubiera casi el triple de aire
   que abajo.

   👉 SE QUITA EL MARGEN, NO SE INFLA EL DE ABAJO. Igualar subiendo el padding-bottom
      habría dejado el título centrado, sí, pero dentro de una banda mucho más alta
      —justo lo contrario de lo que se venía persiguiendo—. Quitando el margen
      sobrante, el reparto pasa a ser exactamente el de los dos paddings y la banda se
      queda igual de fina.

   Va con :first-child y no con la clase del título, para hacer juego con la regla de
   arriba: el primero de la banda no arrastra margen por encima y el último no lo
   arrastra por debajo, sea cual sea el elemento que caiga en cada sitio.
   ═══════════════════════════════════════════════════════════════════════════ */
body.woocommerce-checkout .ga-page-hero .ga-section__inner > *:first-child,
body.woocommerce-account .ga-page-hero .ga-section__inner > *:first-child {
    margin-top: 0;
}

/* ——— 2. Y EL CONTENIDO, QUE ARRANCABA CON OTROS 6rem ———
   Era la otra mitad del problema. Se pone a cero y se devuelve una separación
   pequeña en la regla siguiente. */
body.woocommerce-checkout .ga-page-contenido .ga-section__inner,
body.woocommerce-checkout .ga-page-content,
body.woocommerce-account .ga-page-contenido .ga-section__inner,
body.woocommerce-account .ga-page-content {
    padding-top: 0;
}

body.woocommerce-checkout .ga-page-contenido .ga-section__inner,
body.woocommerce-account .ga-page-contenido .ga-section__inner {
    padding-top: 1.5rem;
    padding-bottom: var(--ga-space-lg);
}

/* 🔴 EN EL CHECKOUT DE PAGO, ALGO MÁS DE AIRE ARRIBA, Y NO ES UN CAPRICHO. Es la
   única pantalla del sitio que se queda SIN NADA por encima del contenido: sin
   cabecera y, desde ahora, sin banda de título. Con los 1,5rem de la regla anterior
   el primer campo del formulario nacía casi tocando el borde de la ventana.

   2,5rem le dan sitio para respirar sin devolverle el aire que se acaba de quitar.

   ⚠ SOLO EL DE PAGO. Mi Cuenta y "Pedido recibido" conservan su banda de título, así
     que ahí ese aire ya lo pone ella y este añadido sobraría. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-page-contenido .ga-section__inner {
    padding-top: 2.5rem;
}


/* ═══════════════════════════════════════════════════════════════════════════
   MI CUENTA — BANDA BLANCA Y MÁS AIRE ARRIBA Y ABAJO
   ═══════════════════════════════════════════════════════════════════════════
   Tres retoques que solo valen para esta pantalla. Van DESPUÉS de las reglas
   agrupadas de aquí arriba a propósito: comparten con ellas la misma especificidad
   —0-3-1— así que lo que decide es el orden, y estas tienen que ser las últimas en
   hablar. Si algún día se mueven por encima de aquellas, dejarán de aplicarse sin
   que nada avise.

   ⚠ TODO ACOTADO A body.woocommerce-account: el checkout, las páginas legales y el
     resto del sitio no se enteran de nada de esto.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · LA BANDA DEL TÍTULO, EN BLANCO.
   El crema lo pone la regla base de .ga-page-hero, que comparten las páginas legales
   —y ahí se queda—. Aquí se sustituye por el blanco de marca, así que la cabecera y
   el contenido pasan a ser una sola superficie continua.

   ⚠ Y CON ELLA SE VA EL ÚLTIMO RESTO DE CREMA DE ARRIBA: esa banda se estira bajo la
     cabecera fija con un margin-top negativo, así que el hueco que reserva el body
     también toma este color. No queda ninguna zona crema en la cabecera. */
body.woocommerce-account .ga-page-hero {
    background-color: var(--ga-blanco);
}

/* 2 y 3 · EL AIRE. Arriba, para que el menú de la cuenta no arranque pegado al
   título; abajo, para que "Salir" no termine encima del pie.

   El de abajo pasa de --ga-space-lg (2,5rem) a --ga-space-2xl (6rem): más del doble.
   Se usan variables de marca y no números sueltos, para que sigan el sistema de
   espaciado del resto del sitio. */
body.woocommerce-account .ga-page-contenido .ga-section__inner {
    padding-top: 3rem;
    padding-bottom: var(--ga-space-2xl);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — MÁS ANCHO Y EN DOS COLUMNAS DE VERDAD
   ═══════════════════════════════════════════════════════════════════════════
   🔴 QUIÉN LIMITABA EL ANCHO. page.php envuelve el contenido en
   .ga-section__inner--narrow, que vale 800px y lo comparten el aviso legal, la
   privacidad, las cookies y las condiciones. Ahí 800px es el ancho de lectura
   correcto; en un checkout de dos columnas deja la del pedido en unos 320px y por
   eso el nombre del producto se partía palabra por palabra.

   Se sube SOLO aquí, acotado al body del checkout de pago: las páginas de texto
   conservan sus 800px intactos.

   ⚠ 1240px Y NO EL ANCHO COMPLETO: en un monitor grande, un formulario de una punta
     a otra de la pantalla se lee peor, no mejor.

   ═══════════════════════════════════════════════════════════════════════════
   🔴 LAS DOS COLUMNAS SOLO EXISTEN A PARTIR DE 1025px, Y ESO ES DELIBERADO.
   Por debajo NO SE TOCA NADA: el checkout se apila exactamente como hoy, que es lo
   que se quiere en móvil y en tablet estrecha. Es también la forma de que este
   cambio no pueda romper el ancho que ya funciona: fuera de este media query, ni una
   sola declaración nueva llega al formulario.

   ⚠ HAY UN PRECEDENTE, Y ESTÁ ESCRITO UNAS LÍNEAS MÁS ARRIBA: ya hubo una versión
     con 1200px y columnas 60/40 que SE REVIRTIÓ porque rompía el bloque "Tu pedido".
     Por eso aquí se toca la maquetación de los CONTENEDORES y nada más: ni los
     campos, ni el cupón, ni los pagos exprés, ni una sola regla que entre dentro de
     #order_review.

   ⚠ Y POR ESO EL SUELO `> *` ES OBLIGATORIO. El formulario del checkout no siempre
     tiene los mismos hijos: Stripe mete ahí sus pagos exprés, un plugin puede añadir
     un aviso, y WooCommerce cambia el marcado entre versiones. Con la primera regla,
     CUALQUIER hijo que no se nombre expresamente ocupa la fila entera —que es donde
     no molesta— en vez de colarse en una de las dos columnas. Los tres que sí se
     nombran son los de siempre y no han cambiado en años.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-page-contenido .ga-section__inner--narrow {
    max-width: 1240px;
    margin-left: auto;
    margin-right: auto;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — EL CUPÓN, COMO UN ENLACE Y NO COMO UN CARTEL
   ═══════════════════════════════════════════════════════════════════════════
   "¿Tienes un cupón?" salía como una banda crema a todo el ancho, con filete dorado
   arriba y un icono cuadrado a la izquierda. Es el aspecto que este tema le da a los
   AVISOS de WooCommerce, y para un aviso está bien; el problema es que aquí no hay
   ningún aviso que dar: es una opción secundaria que la mayoría no va a usar, y con
   ese tratamiento pesaba más que el propio formulario de pago.

   🔴 DE DÓNDE VENÍA LA BANDA, PORQUE HACE FALTA SABERLO PARA GANARLE. No es de
   WooCommerce: es de assets/css/woocommerce.css, línea 355:

       .woocommerce-info {
           background-color: var(--ga-naranja-claro) !important;
           border-top-color: var(--ga-naranja-apagado) !important;
       }

   Ese archivo declara 'gran-almazara-main' como dependencia en el wp_enqueue_style, o
   sea que se imprime DESPUÉS de este. Con !important y cargándose después, para
   ganarle hacen falta las dos cosas: más especificidad Y !important. De ahí que estas
   reglas lleven ambas; no es por comodidad.

   ⚠ ACOTADO AL BLOQUE DEL CUPÓN, no a todos los .woocommerce-info del checkout. En
     esa página pueden salir otros avisos —un error de validación, un mensaje de
     envío— y esos SÍ tienen que seguir viéndose como avisos. Por eso el selector
     empieza por .woocommerce-form-coupon-toggle, que es el envoltorio que WooCommerce
     le pone solo a este.

   ⚠ SOLO ASPECTO. No se toca el enlace .showcoupon en lo que a comportamiento se
     refiere: WooCommerce escucha su clic para desplegar el campo, y ese enlace sigue
     siendo el mismo con el mismo nombre de clase. Lo único que cambia es cómo se ve.

   ⚠ Y NO ALCANZA A "PEDIDO RECIBIDO" NI A MI CUENTA: el :not() de siempre, y el
     bloque de avisos de body.woocommerce-account queda intacto unos miles de líneas
     más arriba.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Fuera la caja: sin fondo, sin filete y sin el relleno que la sostenía. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info {
    background: none !important;
    background-color: transparent !important;
    border: 0 !important;
    border-radius: 0 !important;
    box-shadow: none !important;
    padding: 0 !important;
    /* Aire arriba y abajo para que no se pegue a los pagos exprés ni al formulario,
       ahora que no hay banda que marque su sitio. */
    margin: 1.5rem 0 !important;

    color: var(--ga-negro-suave, #1a1a14) !important;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    text-align: left;
}

/* Fuera el icono cuadrado. `content: none` es lo que impide de verdad que el
   pseudoelemento se genere; el display es el cinturón. Mismo par que ya se usa para
   los rótulos de tabla del carrito lateral. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info::before {
    content: none !important;
    display: none !important;
}

/* El texto pulsable, como un enlace normal: subrayado, pero SIN el dorado.
   El dorado es el color de las llamadas a la acción de esta web, y aquí tiraba del ojo
   por encima de los campos del formulario y del propio botón de pagar. Introducir un
   cupón es una opción secundaria que la mayoría no va a usar: se queda como un enlace
   discreto, reconocible por el subrayado y no por el color.

   ⚠ currentColor Y NO LA VARIABLE A MANO. El .woocommerce-info que lo envuelve ya
     declara var(--ga-negro-suave, #1a1a14) unas líneas más arriba, así que el enlace
     toma exactamente el color del texto que tiene al lado. Es la regla nº 7 del
     documento del proyecto: si hace falta el mismo color que un texto vecino,
     currentColor antes que copiarlo. Así no hay dos valores que sincronizar, y el
     respaldo del negro vive en un solo sitio.

   Ningún estado cambia tamaño ni posición; al pasar el ratón solo cambia de color. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info a {
    color: currentColor;
    text-decoration: underline;
    transition: color var(--ga-transition-normal);
}

body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info a:hover,
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info a:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-form-coupon-toggle .woocommerce-info a:focus-visible {
    color: var(--ga-verde-oliva-oscuro);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — LA COLUMNA DERECHA, COMO UN PANEL CREMA
   ═══════════════════════════════════════════════════════════════════════════
   Todo el resumen —título, productos, subtotal, envío, total y opciones de pago—
   sobre el crema de marca, para que se lea como una pieza aparte del formulario.

   🔴 SON DOS BLOQUES HERMANOS, NO UNO. #order_review_heading y #order_review son dos
   elementos distintos: no hay ningún contenedor que los envuelva, y crearlo obligaría
   a tocar la plantilla del checkout. Se resuelve dándoles el MISMO fondo y pegándolos:
   el de arriba redondea solo sus esquinas superiores, el de abajo solo las inferiores,
   y entre ellos no queda ni margen ni hueco de rejilla. A la vista es un solo panel.

   ⚠ POR ESO EL margin VA CON !important Y A CERO. Un <h3> trae margen del navegador
     por arriba y por abajo; el de abajo abriría una franja del color del fondo justo
     por la mitad del panel y se vería la costura.

   ⚠ FUERA DEL @media DE 1025px A PROPÓSITO: el panel se quiere también en móvil, donde
     la columna ya se apila debajo del formulario. Allí solo cambia que necesita aire
     por arriba, y de eso se encarga el bloque de más abajo.

   ⚠ EL PADDING NO PUEDE DESBORDAR: este tema declara box-sizing: border-box para todo
     en su reset, así que el relleno se descuenta del ancho en vez de sumarse.

   ⚠ CONTRASTE: crema #F9F6EE con el verde oliva oscuro de los textos de marca. No se
     fuerza ningún color aquí; los que ya había se leen de sobra sobre este fondo.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
    background-color: var(--ga-naranja-claro);
    border-radius: 10px 10px 0 0;
    margin: 0 !important;
    padding: 1.5rem 1.5rem 0.75rem;
}

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review {
    background-color: var(--ga-naranja-claro);
    border-radius: 0 0 10px 10px;
    margin-top: 0 !important;
    padding: 0 1.5rem 1.5rem;
}

/* Para que el crema se vea CONTINUO. La tabla del resumen y el bloque de opciones de
   pago traen fondo propio de WooCommerce —blanco la primera, gris el segundo—, y sobre
   el panel se leerían como recuadros pegados encima en vez de como su contenido.

   ⚠ AQUÍ SE QUITA FONDO, NADA MÁS. No se toca ni un campo, ni el recuadro del número de
     tarjeta de Stripe —que conserva el suyo, como debe— ni nada del funcionamiento del
     pago. Solo se apaga el color de los CONTENEDORES. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table tbody,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table tfoot,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table tr,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table th,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table td,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review #payment,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review ul.payment_methods {
    background-color: transparent !important;
}

/* ——— FUERA LA CABECERA "PRODUCTO / SUBTOTAL" ———
   Con el título "Tu pedido" justo encima del panel, esos dos rótulos no explican nada
   que no se entienda ya: la columna de la izquierda son productos y la de la derecha,
   importes. Quitándolos, el primer producto enlaza directamente con el título.

   ⚠ SE OCULTA, NO SE BORRA. El <thead> sigue en el marcado: es la cabecera semántica
     de la tabla y quitarla del HTML dejaría los <td> sin encabezados a los que
     referirse para quien navegue con lector de pantalla. Con display:none deja de
     pintarse, que es lo único que se pedía.

   ⚠ NO ARRASTRA NINGUNA LÍNEA. El filete que se veía bajo esos rótulos es el
     border-bottom de los propios <th>, así que se va con ellos; no queda una raya
     suelta encima del primer producto.

   ⚠ Y NO SE TOCA NADA MÁS DE LA TABLA: productos, cantidades, precios, subtotal,
     envío y total siguen exactamente igual. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table thead {
    display: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — LA CASILLA DE ENVÍO Y EL TÍTULO DE SU BLOQUE
   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ LA CASILLA SE VEÍA COMO UN TITULAR. No era un descuido de estilo: en la
   plantilla de WooCommerce, esa casilla y su texto van literalmente DENTRO de un
   <h3>. Así que heredaba todo lo que este tema da a los encabezados —la serif de
   titulares, el cuerpo grande, la negrita— y competía con el título del formulario
   que tiene justo encima, cuando no es más que una opción marcable.

   Se le devuelve el aspecto de texto de formulario. La etiqueta se declara aparte del
   <h3> porque el peso y el tamaño los puede traer cualquiera de los dos.

   ⚠ EL <h3> SE QUEDA EN EL MARCADO. Cambiarlo por un <p> exigiría sobrescribir la
     plantilla del checkout, y aquí basta con vestirlo de otra manera. Solo cambia cómo
     se ve; el marcado, la casilla y su name siguen intactos.

   ⚠ text-wrap: wrap porque la regla general de títulos aplica `balance`, que en una
     frase larga como esta reparte las líneas de forma rara (🪤 nº 16).
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address,
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address label,
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address span {
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    /* 400 literal: no hay ninguna variable de peso normal declarada en style.css
       —solo --ga-weight-medium y --ga-weight-bold—, y escribir una que no existe deja
       la propiedad en `inherit` en cuanto alguien quite el respaldo (🪤 nº 15). */
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: normal;
    text-transform: none;
    color: var(--ga-negro-suave, #1a1a14);
    text-wrap: wrap;
}

/* La fila de la casilla: el cuadrito y su texto en línea, sin el aire de un titular. */
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address {
    margin: 1.25rem 0;
}

/* ——— Y MENOS AIRE ARRIBA, QUE ERAN CUARENTA PÍXELES Y NO VEINTE ———
   Entre esta casilla y la de "Crear una cuenta" se abría un hueco desproporcionado, y la
   razón es que ARRIBA HABÍA DOS SEPARACIONES SUMÁNDOSE, no una:

     · los 20px de margen de la regla de aquí arriba;
     · y otros 20px de RELLENO que pone Astra, porque esta casilla vive dentro de un <h3>
       y le entra su regla de encabezados del formulario —#customer_details h3 con
       `padding: 20px 0 14px`—. La regla de arriba nunca declaró padding, así que ese
       relleno nunca se estaba anulando.

   De ese relleno de Astra se encarga esta regla, poniéndolo a cero. Y gana sin
   !important: el selector de Astra puntúa 1-1-2 y este 1-2-1 —mismo número de ids, una
   clase más—.

   ⚠ EL MARGEN SUPERIOR YA NO SE DECIDE AQUÍ. Aquí hubo un `margin-top: 0.5rem` que pegaba
     la casilla a lo de arriba; el aire de esa zona lo pone ahora el bloque siguiente, el
     de la raya separadora, que es quien reparte de una vez la separación entre el email y
     la casilla. Se quitó de aquí para que no haya dos sitios diciendo cosas distintas
     sobre lo mismo. */
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address {
    padding-top: 0;
}

body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}


/* ——— LA RAYA SEPARADORA, DE DEBAJO DE LA CASILLA A ENCIMA DE ELLA ———
   ═══════════════════════════════════════════════════════════════════════════
   El orden de los bloques ya era el bueno —email → crear cuenta → casilla de envío →
   notas—, pero la raya gris caía DEBAJO de la casilla, así que la agrupaba con el email
   en vez de con las notas. Se cambia de sitio la separación, no el orden.

   🔴 DE DÓNDE SALÍA ESA RAYA, QUE NO ERA DE NINGÚN BLOQUE VECINO: es el `border-bottom`
   DE LA PROPIA CASILLA. WooCommerce escribe esa casilla dentro de un <h3>, y
   assets/css/woocommerce.css línea 299 le da a TODO <h3> del checkout
   `border-bottom: 1px solid rgba(74, 74, 47, 0.1) !important` junto con su relleno y su
   margen inferiores. O sea que la línea no separaba dos bloques: colgaba de la casilla y
   por eso siempre iba por debajo, pasara lo que pasara con los márgenes.

   👉 La solución es mover la raya a un elemento distinto: se le quita al <h3> y se le
      pone al DIV que lo envuelve, .woocommerce-shipping-fields, como borde SUPERIOR. Ahí
      sí separa lo de arriba de lo de abajo, que es lo que se pedía.

   ⚠ EL COLOR ES EL MISMO, copiado de esa misma regla: rgba(74, 74, 47, 0.1), el verde
     oliva de marca al 10 %. No hay ninguna variable de gris en la paleta y no se inventa
     ningún tono nuevo: es literalmente la línea que ya estaba, en otro sitio.

   ⚠ LOS !important SON OBLIGATORIOS Y VAN SOLO SOBRE LO QUE HAY QUE DESHACER —el borde,
     el relleno y el margen inferiores del <h3>—, porque enfrente están los !important de
     woocommerce.css, que además se carga DESPUÉS de esta hoja. Este selector puntúa
     1-2-1 contra su 0-1-1, así que con la marca de importancia gana sin discusión.

   ⚠ EL DESPLIEGUE DE LA DIRECCIÓN DE ENVÍO NO SE TOCA. Sigue siendo el mismo
     .shipping_address dentro del mismo contenedor, con su slideToggle de WooCommerce; lo
     único que cambia es cuánto aire hay entre la casilla y esos campos cuando se abren.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · La separación, ARRIBA del bloque de envío: aire, raya y aire. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields {
    /* 🔴 LOS DOS VALORES SON EL MISMO Y TIENEN QUE SEGUIR SIÉNDOLO: el de arriba es el
       hueco por ENCIMA de la raya y el de abajo el que hay por DEBAJO, así que cualquier
       día que se quiera más o menos aire hay que mover LOS DOS a la vez o se pierde la
       simetría que costó cuadrar (el porqué, en el bloque de aquí abajo).
       Bajaron de --ga-space-md a --ga-space-sm: 16px a cada lado en vez de 24. */
    margin-top: var(--ga-space-sm);
    padding-top: var(--ga-space-sm);
    border-top: 1px solid rgba(74, 74, 47, 0.1);
}

/* 1 bis · Y LA MISMA DISTANCIA A LOS DOS LADOS DE LA RAYA.
   ═══════════════════════════════════════════════════════════════════════════
   Los dos huecos se declaran arriba con el mismo valor —hoy 16px de margen por encima y 16px
   de relleno por debajo—, y aun así el de arriba se veía mayor. Sobraban dos cosas que no
   estaban a la vista, las dos de la fila de "Crear una cuenta":

     1. SU RELLENO Y SU MARGEN INFERIORES. Astra da a todo .form-row del checkout
        `padding: 3px; margin: 0 0 6px`. Esos 3px de relleno se suman al hueco —el margen
        de 6px no, porque se funde con el margen del bloque de envío y gana el mayor—.

     2. Y SOBRE TODO SU INTERLINEADO. Astra pone `line-height: 2` a las etiquetas de
        .form-row: con su cuerpo de letra, la fila mide unos 29px para una casilla de 16,
        así que quedan ~6px de aire muerto por DEBAJO de la casilla antes de que la fila
        termine. La casilla de envío no los tiene: su bloque le fija `line-height: 1.5`.
        Ese aire invisible es la mayor parte de la diferencia, y es el motivo de que
        cuadrar esto a base de tocar solo los márgenes no terminara de salir nunca.

   👉 Se igualan las dos filas en vez de compensar a ojo: el mismo interlineado que la de
      envío y sin relleno ni margen inferiores. A partir de ahí, los 24px declarados a
      cada lado SON los que se ven, y la simetría no depende de acertar con un número.

   ⚠ SOLO SE TOCA EL LADO DE ABAJO DE ESA FILA. El `padding-left: 3px` de Astra se
     conserva —es el que alinea esta casilla con los campos del formulario, y quitarlo
     desharía el ajuste horizontal—: por eso se declara `padding-bottom` y no el atajo.

   ⚠ NI EL COLOR DE LA RAYA, NI EL ORDEN, NI LOS TEXTOS, NI EL TAMAÑO DE LETRA: el
     interlineado cambia el alto de la fila, no el cuerpo del texto. */
/* ⚠ LOS SELECTORES NOMBRAN .form-row A PROPÓSITO, aunque .create-account bastaría para
     encontrar la fila: enfrente están `.woocommerce-js form .form-row` y
     `.woocommerce-js form .form-row label`, que puntúan 0-3-2. Con la clase de más estos
     suman 0-4-1 y 0-4-2 y ganan por especificidad, sin depender de qué hoja se imprime
     antes ni de ningún !important. */
body.woocommerce-checkout:not(.woocommerce-order-received) .form-row.create-account {
    padding-bottom: 0;
    margin-bottom: 0;
}

body.woocommerce-checkout:not(.woocommerce-order-received) .form-row.create-account label {
    line-height: 1.5;
}

/* 1 ter · Y UN POCO DE AIRE ENTRE EL CORREO Y ESTA CASILLA.
   La casilla quedaba pegada al campo de email: entre los dos solo había los 3px de
   relleno y los 6px de margen que Astra da a la fila del correo, unos 9px en total.

   ⚠ EL MARGEN VA EN EL CONTENEDOR .woocommerce-account-fields Y NO EN LA FILA, y no es
     indiferente: la fila ya tiene su margen inferior puesto a cero en la regla de arriba
     —es lo que mantiene igualada la raya gris de más abajo—, así que tocarle también el
     superior mezclaría en un mismo sitio dos ajustes que responden a cosas distintas.
     Desde el contenedor, el hueco de arriba se mueve solo y el de abajo no se entera.

   ⚠ 8px Y NO MÁS. Sumados al relleno y al margen que Astra ya da a la fila del correo,
     dejan unos 19px entre el campo y la casilla. Este valor se decidió cuando la raya de
     abajo estaba a 24px y la idea era que la casilla se leyera del grupo del email; hoy
     esa raya está a 16px, así que las dos distancias andan parejas y la agrupación la
     marca la propia raya, no el aire. Se deja como está porque el resultado se validó
     así; si algún día se quiere volver a marcar esa jerarquía, este es el número.

   ⚠ ESTE MARGEN NO ES EL DE LA RAYA GRIS y se ajustan por separado a propósito: el de la
     raya vive en .woocommerce-shipping-fields —los dos valores gemelos de más arriba— y
     este solo gobierna el hueco entre el correo y la casilla. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-account-fields {
    margin-top: var(--ga-space-xs);
}

/* 2 · Y la casilla, sin la raya ni el hueco que tenía DEBAJO: así se lee pegada al
       bloque de notas que viene después, que es donde se quiere que pertenezca.
       El margen inferior no baja a cero porque es también el que separa la casilla de los
       campos de envío cuando se despliegan; 1rem es suficiente para las dos cosas. */
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address {
    margin-top: 0;
    padding-bottom: 0 !important;
    margin-bottom: 1rem !important;
    border-bottom: 0 !important;
}


/* ——— LOS DOS CAMPOS DE LA FACTURA ———
   ═══════════════════════════════════════════════════════════════════════════
   La casilla "¿Necesitas factura?" y el DNI/NIF/CIF que aparece debajo al marcarla. Los
   pinta WooCommerce desde el § 36 de functions.php; aquí solo se resuelve su aspecto.

   🔴 LA FILA DEL DOCUMENTO SE ESCONDE CON UNA CLASE QUE PONE EL JS, no con `hidden` ni
   con un estado de partida en el CSS. El motivo está escrito también en el JS y es el
   mismo: si ese script no llegara a ejecutarse, el campo tiene que quedarse VISIBLE.
   Naciendo sin la clase, un fallo deja un campo de más —que se entiende— en vez de
   dejar sin sitio donde escribir a quien necesita factura.

   ⚠ LA CASILLA SE VISTE COMO SUS DOS HERMANAS —crear cuenta y enviar a otra dirección—:
     misma fila flex, mismo hueco entre el cuadro y el texto, mismo peso e interlineado.
     Sin esto saldría en negrita, porque Astra pone `font-weight: 700` a las etiquetas de
     .form-row, que es exactamente lo que ya hubo que deshacer en la de crear cuenta.

   ⚠ EL SELECTOR NOMBRA .form-row para ganarle a Astra por especificidad (0-4-2 contra su
     0-3-2), sin depender del orden de las hojas ni de ningún !important.

   ⚠ EL CUADRO EN SÍ NO SE TOCA AQUÍ: la casilla lleva la clase `input-checkbox` de
     WooCommerce, así que ya le entra el bloque de casillas personalizadas de más abajo
     —fondo blanco, borde de marca y tick dorado— sin escribir una regla más.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ——— UN POCO DE AIRE SOBRE LA CASILLA ———
   Se imprime justo detrás de la rejilla de campos de facturación, así que entre el correo
   electrónico y ella solo quedaban los 3px de relleno y los 6px de margen que Astra da a
   la fila del correo: unos 9px, y se leía pegada.

   ⚠ 8px, EL MISMO VALOR QUE SEPARA A "CREAR UNA CUENTA" DE LO QUE TIENE ENCIMA. No es un
     número elegido a ojo: las dos casillas cuelgan del mismo sitio y con el mismo aire
     mantienen el ritmo de la columna. Total: unos 17px hasta el campo del correo.

   ⚠ SOLO EL MARGEN DE ARRIBA. El de abajo se queda como está —es el que separa la casilla
     de su propio campo de DNI cuando aparece— y no se toca nada del bloque de envío ni de
     su raya gris, que ya estaban ajustados.

   ⚠ EL SELECTOR NOMBRA .form-row para ganarle a Astra por especificidad (0-4-1 contra su
     0-3-2), que es quien pone ese `margin: 0 0 6px` a todas las filas. */
body.woocommerce-checkout:not(.woocommerce-order-received) .form-row.ga-factura__check {
    margin-top: var(--ga-space-xs);
}

/* ⚠ LA TIPOGRAFÍA ES, LITERALMENTE, LA MISMA QUE LA DE LA CASILLA DE ENVÍO —el bloque
     #ship-to-different-address, unas líneas más arriba—: misma familia, mismo cuerpo,
     mismo peso, mismo interlineado y mismo color. Están una encima de la otra y tienen
     que leerse como dos preguntas del mismo tipo, no como dos cosas distintas. Si algún
     día se cambia allí, se cambia aquí.

   ⚠ EL RESPALDO DEL NEGRO ES OBLIGATORIO: --ga-negro-suave está en la paleta pero NO se
     declara en el :root de style.css (🪤 nº 15). */
body.woocommerce-checkout:not(.woocommerce-order-received) .form-row.ga-factura__check label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;

    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: 400;
    line-height: 1.5;
    letter-spacing: normal;
    text-transform: none;
    color: var(--ga-negro-suave, #1a1a14);
}

/* Sin el margen que Astra da al checkbox: la separación la pone el gap de arriba, igual
   que en las otras dos filas de casilla. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-factura__check .input-checkbox {
    margin: 0;
}

/* La fila del documento, escondida mientras la casilla no esté marcada. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-factura__dni--oculta {
    display: none;
}

/* ——— FUERA EL "(opcional)" DE ESTOS DOS CAMPOS ———
   🔴 LO AÑADE WooCommerce SOLO, a todo campo declarado como no obligatorio, y en estos
   dos dice justo lo contrario de lo que pasa: el documento es OBLIGATORIO en la única
   situación en la que se ve —cuando has pedido factura—, así que un "(opcional)" pegado
   a su título contradice al aviso que después impide seguir sin él.

   👉 Se esconde el rótulo, no se toca el `required` del campo. Sigue siendo false en PHP,
      que es lo que permite pagar sin factura, y la exigencia sigue viviendo donde debe:
      en el servidor.

   ⚠ ACOTADO A ESTOS DOS CAMPOS. El "(opcional)" de las Notas del pedido sí se quiere y
     se queda: ese campo es opcional de verdad, siempre. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-factura__check label .optional,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-factura__dni label .optional {
    display: none;
}


/* ——— LAS DOS CASILLAS, IGUALADAS ———
   ═══════════════════════════════════════════════════════════════════════════
   En el formulario hay DOS casillas y se veían distintas: "¿Crear una cuenta?" en
   negrita, y los cuadritos de distinto tamaño. Cada cosa tenía su causa, y ninguna era
   del tema.

   🔴 1 · LA NEGRITA VIENE DE ASTRA, no de WooCommerce ni de este tema. En
   astra/assets/css/minified/compatibility/woocommerce/woocommerce-grid.min.css:

       .woocommerce-js form .form-row label { line-height:2; font-weight:700; font-size:.9rem }

   Y la clave está en el MARCADO, que es distinto en las dos: "¿Crear una cuenta?" vive
   dentro de un <p class="form-row form-row-wide create-account">, así que le entra de
   lleno; la de envío vive dentro de un <h3> —no hay ningún .form-row por medio— y
   además ya la desactiva el bloque de arriba con su font-weight: 400. De ahí que una
   saliera en negrita y la otra no.

   Se le devuelve el 400, el mismo número literal y por el mismo motivo que allí: no hay
   ninguna variable de peso normal declarada en style.css. Basta con la especificidad
   —0-3-2 contra los 0-2-2 de Astra—, así que no hace falta ningún !important.

   🔴 2 · EL TAMAÑO: NO HABÍA NINGUNA REGLA QUE LO FIJARA, Y ESE ERA EL PROBLEMA.
   Se buscó en los cuatro CSS del tema, en los de Astra, en el CSS dinámico que Astra
   imprime en la página y en los del plugin de Correos: NADIE declara width ni height ni
   scale sobre estas casillas. Las dos salían al tamaño por defecto del navegador… pero
   solo una podía conservarlo:

     · la de crear cuenta es un elemento EN LÍNEA y nada la puede encoger;
     · la de envío es HIJA DE UN CONTENEDOR FLEX —la regla de aquí arriba— y, como todo
       ítem de flex, nace con flex-shrink: 1. Cuando el texto de al lado no cabe holgado
       —y el suyo es largo, y su columna es la estrecha del checkout—, el navegador la
       ESTRUJA a lo ancho para hacerle sitio. Sale un rectángulo en vez de un cuadrado.

   👉 Por eso la corrección son dos cosas y no una: una medida explícita e idéntica para
      las dos, y un flex-shrink: 0 en la de envío para que no pueda volver a encogerse
      por mucho que se estreche la columna.

   ⚠ 1rem Y NO EL DEFECTO DEL NAVEGADOR, a propósito: ese defecto son 13px en Chrome y
     Firefox pero no en todos los motores, así que dejarlo implícito es dejar el tamaño
     en manos de cada navegador. Con una medida escrita, las dos miden lo mismo en todos
     y además casan con los 16px de los campos de esta pantalla.

   ⚠ NO SE TOCA EL `appearance` NI SE LES PONE border-radius, y es deliberado. Redondear
     un checkbox obliga a anular su apariencia nativa y a repintar el tick a mano, que es
     justo el patrón que este proyecto ya tuvo que montar en Contacto (input colapsado +
     <span> hermano) por una razón: Astra estiliza input[type=checkbox] y gana. Aquí solo
     se declaran DOS MEDIDAS, así que el color de marcado que Astra les da sigue intacto
     y no hay nada que reconstruir.

   ⚠ SOLO PESO Y TAMAÑO. Ni el texto, ni los márgenes, ni la alineación, ni el name de
     ningún campo. Y ningún estado cambia nada: aquí no se declara ni hover ni foco.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · "¿Crear una cuenta?", sin la negrita de Astra. */
body.woocommerce-checkout:not(.woocommerce-order-received) .create-account label,
body.woocommerce-checkout:not(.woocommerce-order-received) .create-account label span {
    font-weight: 400;
}

/* 2 · Las dos casillas, exactamente del mismo tamaño. Los selectores van por ID, así que
       ganan de sobra a cualquier regla de clase de Astra o de WooCommerce. */
body.woocommerce-checkout:not(.woocommerce-order-received) #createaccount,
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address-checkbox {
    width: 1rem;
    height: 1rem;
}

/* 3 · Y ninguna de las dos puede dejarse estrujar por su contenedor flex: un ítem de flex
       nace con flex-shrink: 1 y el navegador lo estrecha cuando el texto de al lado no
       cabe holgado. Con esto miden lo que dice la regla de arriba, pase lo que pase. */
body.woocommerce-checkout:not(.woocommerce-order-received) #createaccount,
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address-checkbox {
    flex: 0 0 auto;
}


/* ——— Y LAS DOS FILAS, ARRANCANDO EN EL MISMO PUNTO ———
   ═══════════════════════════════════════════════════════════════════════════
   Con el tamaño ya igualado seguían sin cuadrar en horizontal: ni las casillas caían en
   la misma vertical, ni los dos textos empezaban a la misma distancia. Eran DOS
   diferencias distintas sumándose, y ninguna se veía en el marcado.

   🔴 1 · EL SANGRADO DE LA FILA. "Crear una cuenta" vive en un <p class="form-row">, y
   Astra da a TODO .form-row del checkout `padding: 3px` —o sea 3px por la izquierda—.
   La de envío vive en un <h3>, que no es un .form-row y no recibe nada: arrancaba 3px
   más a la izquierda que ella y que el resto de campos del formulario.

   👉 La referencia es la de crear cuenta, y no por gusto: esos 3px son los que tienen
      TODOS los campos de la columna —nombre, apellidos, dirección, correo—, así que
      alinearse con ella es alinearse con el formulario entero. Se le dan los mismos 3px
      a la de envío. El valor va literal porque es una copia del de Astra, no un número
      de esta casa: no hay variable de marca que aplique a 3px.

   🔴 2 · LA SEPARACIÓN ENTRE LA CASILLA Y SU TEXTO, que era el desajuste gordo y el que
   de verdad despista, porque las dos "parecían" tener 8px:

     · la de envío es un contenedor FLEX con `gap: 0.5rem`, y en un flex los nodos de
       texto en blanco NO cuentan: separación exacta de 8px;
     · la de crear cuenta es texto EN LÍNEA, así que suma el `margin-right: 8px` que
       Astra pone al checkbox MÁS el espacio en blanco que hay entre el <input> y el
       <span> en el marcado de WooCommerce —un espacio real, de unos 4px con esta
       tipografía—. Total: unos 12px.

   👉 Se resuelve dándole a la fila de crear cuenta EL MISMO MECANISMO que ya tiene la
      otra: label en flex con el mismo gap, y el margen del checkbox a cero para que la
      separación la decida solo el gap. Al pasar a flex, además, el espacio en blanco del
      marcado deja de contar por sí solo. Un solo mecanismo para las dos filas en vez de
      dos que hay que mantener en sintonía a base de sumar píxeles.

   ⚠ EL margin: 0 DEL CHECKBOX ANULA TAMBIÉN EL -2px SUPERIOR de Astra, y es lo que se
     busca: ese tirón hacia arriba existía para compensar la alineación en línea, y con
     `align-items: center` sobra. La casilla queda centrada con su texto, igual que la
     otra. Es el único efecto vertical de todo el bloque.

   ⚠ NO SE TOCA EL TAMAÑO —lo fija la regla 2 y sigue mandando ella—, ni el texto, ni el
     orden, ni el name de ningún campo. Ningún estado nuevo: aquí no hay hover ni foco.

   ⚠ NADA DE min-width Y NADA MÁS ANCHO QUE EL VIEWPORT: la fila es un flex que no fija
     anchos y el texto puede partir como siempre.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 4 · La fila de envío, con el mismo sangrado que los campos del formulario. */
body.woocommerce-checkout:not(.woocommerce-order-received) #ship-to-different-address {
    padding-left: 3px;
}

/* 5 · Y la de crear cuenta, con el mismo montaje que la de envío. */
body.woocommerce-checkout:not(.woocommerce-order-received) .create-account label {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    cursor: pointer;
}

/* 6 · Sin el margen que Astra le da al checkbox: la separación la pone el gap de arriba,
       igual que en la otra fila. */
body.woocommerce-checkout:not(.woocommerce-order-received) #createaccount {
    margin: 0;
}


/* ——— LAS CASILLAS, CON FONDO BLANCO Y EL TICK EN DORADO ———
   ═══════════════════════════════════════════════════════════════════════════
   Al marcarlas salían con el azul del sistema y el tick blanco, que es el dibujo NATIVO
   del navegador. Se cambian por una casilla propia: fondo blanco siempre —marcada y sin
   marcar— y la "V" en el dorado de marca.

   🔴 POR QUÉ NO BASTABA CON COLOR, Y POR QUÉ TAMPOCO CON accent-color.
   Un checkbox con su apariencia nativa lo PINTA EL SISTEMA: los `background-color` y
   `border-color` que le pongas se ignoran (por eso la regla que Astra ya tenía sobre
   input[type="checkbox"]:checked no se veía por ninguna parte). Y `accent-color`, que
   sería la vía limpia, colorea el RELLENO del cuadro y deja el tick en blanco: es
   exactamente lo contrario de lo que se pide. La única forma de mandar sobre el dibujo
   es renunciar a la apariencia nativa con appearance: none —con su -webkit- delante para
   Safari— y dibujarlo nosotros.

   🔴 Y AL RENUNCIAR A ELLA HAY QUE DECLARAR EL TAMAÑO SÍ O SÍ. Un checkbox sin apariencia
   nativa PIERDE su tamaño intrínseco: sin width y height se queda en un cuadro de cero.
   Por eso el 1rem está aquí y no es opcional. Es el mismo 1rem que ya tenían las dos
   casillas de arriba, así que esas no cambian de tamaño; las demás del formulario
   —términos, recordarme, guardar tarjeta— pasan de los 13px del navegador a ese mismo
   1rem, que es lo que hace que TODAS se lean por fin como la misma pieza.

   🔴 EL TICK ES UNA IMAGEN DE FONDO, NO UN ::before, y la elección importa: los
   pseudo-elementos sobre un <input> son terreno resbaladizo —no todos los motores los
   generan sobre elementos reemplazados— y si un navegador no lo pintara, la casilla
   marcada se vería EXACTAMENTE IGUAL que la vacía. En una pantalla de pago, donde una de
   estas casillas es la de aceptar los términos, eso no es un detalle estético: es que el
   cliente no sabe si la ha marcado. Un background-image lo dibujan todos.

   ⚠ EL DORADO VA ESCRITO EN HEXADECIMAL DENTRO DEL SVG, y es la única forma: un data:URI
     es una cadena de texto, no CSS, así que var(--ga-naranja-apagado) no se resolvería
     ahí dentro. El valor es el de esa variable —#c7a862, escrito %23c7a862 porque la
     almohadilla hay que escaparla en una URL—. Si algún día cambia el dorado de marca,
     este es uno de los sitios a tocar.

   🔴 REGLA DE ORO DE ESTE BLOQUE, DESPUÉS DE QUE SAFARI DEJARA A UN CLIENTE SIN PODER
   PAGAR: EL CUADRO SE VE SIEMPRE. Una de estas casillas es la de aceptar los términos y
   sin marcarla no se puede terminar la compra, así que aquí la visibilidad manda sobre
   cualquier idea de estilo. En consecuencia:

     · el borde va en verde oliva macizo y NO se aclara en ningún estado;
     · el tamaño y el grosor del borde son idénticos en reposo, hover, foco y marcada;
     · lo que cambia al pasar el ratón y al enfocar se dibuja FUERA de la caja —box-shadow
       y outline—, así que no empuja nada;
     · y el tick usa el método que pinta hasta el navegador más tozudo.

   ⚠ QUÉ HACER SI AUN ASÍ ALGÚN NAVEGADOR NO PINTARA EL TICK: darle también a :checked un
     fondo apenas teñido —rgba(199, 168, 98, 0.18)— para que marcada y sin marcar se
     distingan aunque no haya "V". Hoy no está puesto porque el fondo debe ser blanco y el
     background-image es fiable; queda escrito para no tener que volver a pensarlo.

   ⚠ SE ACOTA A .woocommerce, que es el envoltorio del checkout: alcanza a las casillas
     del formulario de pago Y a la de "recordarme" del acceso de clientes, que está
     encima. Deja fuera las del banner de cookies de Complianz, que vive al final del
     documento, fuera de ese envoltorio.

   ⚠ LOS CAMPOS DE TARJETA DE STRIPE VIVEN EN UN <iframe> Y NO SE TOCAN —ni se puede—.
     Lo único suyo que hay aquí es la casilla de guardar el método de pago, que es un
     <input> normal del documento.

   ⚠ prefers-reduced-motion: la única transición es la del halo del ratón, y se retira
     para quien pida menos movimiento.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"] {
    -webkit-appearance: none;
    appearance: none;

    /* 🔴 EL display VA AQUÍ, Y ES LO QUE HACÍA DESAPARECER LA CASILLA DE LOS TÉRMINOS.
       ═══════════════════════════════════════════════════════════════════════
       Astra declara, en su hoja de compatibilidad con WooCommerce
       (astra/…/compatibility/woocommerce/woocommerce-grid.min.css):

           .woocommerce-js form .form-row .input-checkbox { display: inline; … }

       Y al quitarle la apariencia nativa, el <input> deja de ser un elemento REEMPLAZADO
       —por eso hay que declararle el tamaño—. En un elemento en línea NO reemplazado,
       `width` y `height` SENCILLAMENTE NO SE APLICAN: es la especificación, no un fallo de
       ningún navegador. Los 1rem de aquí abajo se ignoraban y quedaba una caja de 0x0 con
       un borde alrededor: una mota de 2px que en un móvil de alta densidad aún se intuye y
       en un portátil no se ve en absoluto.

       👉 POR QUÉ SOLO LE PASABA A #terms, que era lo que despistaba: la regla de Astra
          exige la clase `input-checkbox`, que llevan tres de las cinco casillas
          —crear cuenta, enviar a otra dirección y términos—. Las dos primeras se salvaban
          POR CASUALIDAD: sus <label> son flex desde que se alinearon, y un ítem de flex se
          BLOCKIFICA, así que ese `display: inline` se convertía en `block` y el tamaño
          volvía a aplicarse. #terms es la única con la clase y sin label flex.

       ⚠ VA EN EL SELECTOR GENERAL Y NO EN UNO PROPIO PARA #terms: así quedan blindadas
         las cinco, incluida cualquiera que WooCommerce o un plugin añadan mañana.

       ⚠ SIN !important, Y COMPROBADO: este selector puntúa 0-4-2 —dos elementos (body,
         input) y cuatro clases contando el atributo y el :not()— frente al 0-3-2 de Astra.
         Gana por especificidad, que es como se debe ganar.

       ⚠ Y NO ESTORBA A LAS DOS QUE VAN EN FLEX: un ítem de flex ignora este valor y se
         blockifica igual. No cambia nada de lo que ya funcionaba. */
    display: inline-block;

    /* Obligatorio al quitar la apariencia nativa: sin esto, cuadro de cero. */
    width: 1rem;
    height: 1rem;
    /* Dentro de una fila flex, que no la estruje el texto de al lado. */
    flex: 0 0 auto;
    vertical-align: middle;

    background-color: var(--ga-blanco);
    /* Preparado para el tick: cuando llegue, ya sabe dónde y a qué tamaño ponerse. */
    background-repeat: no-repeat;
    background-position: center;
    background-size: 0.75rem 0.75rem;

    /* 🔴 BORDE DE MARCA MACIZO, Y AQUÍ ESTABA EL FALLO DE SAFARI. Antes era el mismo gris
       translúcido de los campos de texto —rgba(74, 74, 47, 0.2)—, que sobre blanco da un
       contraste de 1,3:1: por debajo del 3:1 que exige una pieza de interfaz, y tan al
       límite que cada motor decide si se ve. Con la apariencia nativa retirada NO QUEDA
       NADA MÁS que dibuje el cuadro: si ese hilo no se pinta, la casilla es un cuadrado
       blanco sobre fondo blanco. En Chrome se intuía; en Safari desaparecía.

       Con el verde oliva macizo son ~9:1 y no depende de cómo suavice líneas cada motor.
       🔴 Y NO SE ACLARA EN NINGÚN ESTADO —ni al marcar, ni al pasar el ratón, ni con el
          foco—: el cuadro tiene que verse SIEMPRE. Lo dorado es el tick, no el borde. */
    border: 1px solid var(--ga-verde-oliva-oscuro);
    border-radius: var(--ga-radius-sm);
    cursor: pointer;

    /* 🔴 RELLENO CERO, DECLARADO Y NO HEREDADO DEL RESET. Es la propiedad que rompió
       estas casillas la primera vez: assets/css/woocommerce.css vestía como campo de
       texto a TODO `input` que viviera en un .form-row —que son casi todos los checkbox
       del checkout— y les metía `padding: 0.75rem 1rem !important`. Con box-sizing:
       border-box, esos rellenos no caben en un cuadro de 16px: la caja crecía hasta
       ~34x26px, dejaba de ser cuadrada y el tick, centrado sobre ella, se descolocaba.
       Aquella regla ya excluye a los checkbox en su origen; este cero es el cinturón,
       para que ninguna otra pueda volver a deformar el cuadro sin que se note. */
    padding: 0;

    /* Solo el halo del ratón se funde. Ni el borde ni el tamaño cambian nunca, así que no
       hay nada más que animar. */
    transition: box-shadow var(--ga-transition-normal);
}

/* Marcada: MISMO cuadro, MISMO fondo blanco y MISMO borde oscuro. Lo único que cambia es
   que aparece la "V" dorada.

   ⚠ EL BORDE YA NO PASA A DORADO AL MARCAR, y es a conciencia: el dorado sobre blanco da
     2:1 y dejaba el cuadro más difícil de ver justo en el estado en el que más importa.
     El borde se queda oscuro siempre; el dorado lo aporta el tick.

   ⚠ EL background-color SE REPITE a propósito, para ganarle a la regla de Astra que
     pintaba el cuadro de su color global al marcarlo —que ahora sí surtiría efecto,
     porque ya no hay apariencia nativa que la ignore—.

   🔴 EL TICK ES UN background-image Y NO UN ::after, Y EN SAFARI ESO IMPORTA MÁS QUE EN
   NINGÚN SITIO. WebKit trata al <input> como elemento reemplazado y NO garantiza generar
   ::before/::after sobre él; el background, en cambio, lo pinta siempre. Es el mismo
   método que usa Bootstrap para sus casillas, que sí se sostiene en Safari. Un tick
   dibujado con bordes girados habría sido más bonito de leer en el CSS y más frágil.

   ⚠ EL SVG VA CON LOS CARACTERES ESCAPADOS —%3C, %3E y %23— porque un data:URI es una
     URL: sin escapar, Safari es de los que se plantan y no pintan nada. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"]:checked {
    background-color: var(--ga-blanco);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.6 L6.6 11.7 L12.5 4.8' fill='none' stroke='%23c7a862' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}

/* Con el ratón encima, un halo dorado POR FUERA de la caja. Se hace con box-shadow y no
   aclarando el borde —que era lo de antes— por lo mismo de siempre: el cuadro no puede
   perder definición en ningún estado. Una sombra no ocupa sitio, así que nada se mueve. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"]:hover {
    box-shadow: 0 0 0 3px rgba(199, 168, 98, 0.25);
}

/* Y con el teclado, un aro por fuera: se ve de sobra y no desplaza nada.
   ⚠ SE DECLARAN LOS DOS, :focus Y :focus-visible. El segundo es el bueno —solo se
     enciende al navegar con teclado—, pero Safari no lo entendió hasta la 15.4, y en las
     versiones anteriores un cliente que llegue tabulando se quedaría sin ver dónde está.
     Con el :focus delante, esos Safari viejos enseñan el aro igualmente; el precio es que
     también aparece un instante al hacer clic, que es lo que hacen los navegadores de
     serie y no rompe nada. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"]:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado);
    outline-offset: 2px;
}

/* 🔴 LA CASILLA DE GUARDAR EL MÉTODO DE PAGO, Y EL ÚNICO !important DE ESTE BLOQUE.
   El gateway la imprime con style="width:auto" EN LÍNEA, y un estilo en línea gana a
   cualquier regla de hoja que no lo lleve. Sin esto, al quitarle la apariencia nativa se
   quedaría sin ancho: un cuadro invisible que el cliente no podría ni ver ni entender.
   Solo se le devuelve la anchura; nada más de Stripe se toca. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #wc-stripe-new-payment-method {
    width: 1rem !important;
}

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

    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"] {
        transition: none;
    }
}


/* ——— #terms, LA CASILLA DE LOS TÉRMINOS: BLINDADA ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ ESTA TIENE REGLA PROPIA Y LAS DEMÁS NO. Sin marcarla no se puede pagar: es
   la única de las cinco cuyo fallo no es un defecto de estilo, sino una venta perdida.
   Todo lo de aquí abajo es REDUNDANCIA a propósito —repite lo que ya dice el bloque de
   arriba— para que ninguna regla de nadie pueda dejarla sin ver.

   🔴 LO QUE SÉ Y LO QUE NO, ESCRITO PARA NO DAR VUELTAS EN CÍRCULO. Se ha buscado la
   causa de que SOLO esta fallara en los cuatro CSS del tema, en los de Astra —incluido
   el CSS dinámico que imprime en la propia página—, en los del plugin de Stripe, en los
   del de suscripciones y en los del de Correos: NO HAY NI UNA REGLA que trate a #terms
   distinto de las otras cuatro. En el papel recibe exactamente el mismo tratamiento.

   Lo que sí es distinto, y es lo único comprobable, es DÓNDE VIVE:

     · las otras cuatro están sobre fondo BLANCO, en la columna de los datos;
     · #terms es la única que vive dentro de #order_review, o sea sobre el CREMA del
       panel del pedido (--ga-naranja-claro). Es la única a la que un cuadro blanco de
       borde flojo le desaparece de verdad, porque el blanco de la casilla no contrasta
       con el fondo que tiene detrás.

   Con eso, esta regla ataca las dos hipótesis que quedan vivas —que algo le gane la
   partida en la cascada, o que el modo de alto contraste del sistema le retire el
   dibujo— sin depender de acertar cuál de las dos era.

   ⚠ LOS !important SON DELIBERADOS Y VAN SOLO AQUÍ. El selector ya puntúa 1-3-1, así que
     con esto solo puede perder contra otro !important más específico, que no existe en
     ninguna de las hojas revisadas. Es el precio de que esta casilla no dependa de que
     yo haya acertado con la causa.

   ⚠ NO CAMBIA CÓMO SE VE cuando todo funciona: son exactamente los mismos valores que
     las otras cuatro. Puestas una al lado de otra tienen que ser indistinguibles, que es
     lo que se pedía.

   ⚠ accent-color ES LA RED DE SEGURIDAD SILENCIOSA. Solo tiene efecto si el navegador
     acaba dibujando la casilla NATIVA —porque algo anulara el appearance: none—. En ese
     caso saldría en dorado de marca con su tick, en vez del azul del sistema. Mientras
     la casilla propia funcione, esta línea no pinta nada: no hay contrapartida.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #terms {
    -webkit-appearance: none !important;
    appearance: none !important;
    accent-color: var(--ga-naranja-apagado);

    width: 1rem !important;
    height: 1rem !important;
    padding: 0 !important;

    background-color: var(--ga-blanco) !important;
    background-repeat: no-repeat !important;
    background-position: center !important;
    background-size: 0.75rem 0.75rem !important;

    border: 1px solid var(--ga-verde-oliva-oscuro) !important;
    border-radius: var(--ga-radius-sm) !important;
    cursor: pointer;
}

body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #terms:checked {
    background-color: var(--ga-blanco) !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.6 L6.6 11.7 L12.5 4.8' fill='none' stroke='%23c7a862' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") !important;
}

body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #terms:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #terms:focus-visible {
    outline: 2px solid var(--ga-naranja-apagado) !important;
    outline-offset: 2px;
}


/* ——— MODO DE ALTO CONTRASTE DEL SISTEMA: SE DEVUELVE LA CASILLA NATIVA ———
   ═══════════════════════════════════════════════════════════════════════════
   🔴 ES LA HIPÓTESIS QUE MEJOR EXPLICA "EN SAFARI Y EN CHROME DE ALGUNOS EQUIPOS", que
   es un patrón raro: si fuera cosa del navegador fallaría en TODOS los Chrome, no en
   unos sí y otros no. Lo que cambia de un equipo a otro no es el navegador: es el
   AJUSTE DEL SISTEMA. Con el modo de alto contraste activo —"Aumentar contraste" en
   macOS, "Contraste alto" en Windows— el navegador impone su propia paleta a los
   elementos de formulario y DESCARTA fondos e imágenes de fondo. Una casilla dibujada
   como la nuestra —cuyo cuadro ES un fondo y cuyo tick ES una imagen de fondo— se queda
   sin las dos cosas de golpe. Exactamente el síntoma descrito.

   👉 La salida correcta no es pelear contra ese modo: es RENDIRLE LA CASILLA. Aquí se le
      devuelve la apariencia nativa, y el sistema la dibuja con los colores de contraste
      que ese usuario ha elegido, que para eso los ha elegido. Se pierde el tick dorado y
      se gana que la casilla exista.

   ⚠ ESTO NO CAMBIA NADA PARA EL RESTO DE CLIENTES: fuera de ese modo, esta consulta ni
     se evalúa. No es una excepción para #terms, va para las cinco casillas: si el modo
     está activo, lo está para toda la pantalla.

   ⚠ SE MANTIENEN width y height para que el cuadro nativo conserve el tamaño del resto
     de la interfaz; el color lo pone el sistema y no se le discute. */
@media (forced-colors: active) {

    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce input[type="checkbox"],
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce #terms {
        -webkit-appearance: auto !important;
        appearance: auto !important;
        background-image: none !important;
        border: none !important;
    }
}

/* ——— EL TÍTULO DEL BLOQUE DE ENVÍO ———
   Lo escribe ga_checkout_titulo_envio() —functions.php § 35— dentro del div que
   WooCommerce despliega al marcar la casilla, así que aparece y desaparece con él.

   Se le da el mismo lenguaje que al encabezado del bloque de arriba: serif de
   titulares y verde oliva, para que los dos bloques se lean como hermanos. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-envio-titulo {
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    color: var(--ga-verde-oliva-oscuro);
    margin: 0 0 1.25rem;
}

/* Por si el tema padre trajera su propio encabezado de envío: se esconde para que no
   salgan dos. Si no existe, esta regla no hace nada. */
body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_fields_heading {
    display: none;
}


/* ——— LA ZONA FINAL: LA CASILLA Y EL BOTÓN DE PAGAR ———
   ═══════════════════════════════════════════════════════════════════════════
   Dos ajustes, ninguno de los cuales toca la mecánica del pago.

   1) AIRE ENTRE LA CASILLA DE TÉRMINOS Y EL BOTÓN. Iban casi pegados, y el botón que
      cierra una compra conviene que se lea como un paso aparte y no como una línea
      más del bloque anterior. Se le da margen al contenedor del botón —.place-order—
      y no a la casilla, para no tocar nada de la zona de términos ni de su
      validación.

   2) LAS ESQUINAS, A 10px. Enfrente hay un `border-radius: 0 !important` sobre
      #place_order en assets/css/woocommerce.css (línea 339), y ese archivo declara
      'gran-almazara-main' como dependencia: se imprime DESPUÉS de este. Un selector
      de ID puntúa 1-0-0, así que para ganarle hacen falta las dos cosas —más
      especificidad Y !important—, exactamente igual que con el botón "Finalizar
      compra" del carrito lateral. Anteponiendo el body y su clase, el selector sube a
      1-2-1 y se pone por encima.

   ⚠ NI EL COLOR, NI EL RELLENO, NI EL ANCHO SE TOCAN: los sigue poniendo
     woocommerce.css. Aquí solo cambian las esquinas.

   ⚠ Y NADA EN :hover NI EN :focus. El botón conserva su cambio de color al pasar el
     ratón, que ya está declarado allí y no mueve nada.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 🔴 LA CASILLA DE TÉRMINOS VA DENTRO DE .place-order, JUNTO AL BOTÓN. Saberlo es lo
   que explica el desajuste que había: al darle margen a .place-order se separaba el
   bloque ENTERO de las opciones de pago —la casilla incluida—, pero entre la casilla y
   el botón no se abría nada. De ahí que sobrara aire arriba y faltara abajo.

   Ahora cada hueco tiene su dueño:
     · el de arriba, este margen de .place-order —reducido a la mitad—;
     · y el de abajo, el margen inferior de la propia casilla, más abajo. */
body.woocommerce-checkout:not(.woocommerce-order-received) #payment .form-row.place-order {
    margin-top: 1rem;
}

/* El hueco entre la casilla y el botón. Se le da a la casilla y no al botón porque el
   botón es el último elemento del bloque: un margen suyo se sumaría además al final
   del panel. */
body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-terms-and-conditions-wrapper {
    margin-top: 0;
    margin-bottom: 1.5rem;
}

body.woocommerce-checkout:not(.woocommerce-order-received) #place_order {
    border-radius: 10px !important;
}


/* Apilado: el panel necesita separarse del formulario que ahora tiene encima. En
   escritorio no hace falta, porque ahí arranca a la misma altura que la columna
   izquierda y un margen lo descolgaría. */
@media (max-width: 1024px) {

    body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
        margin-top: 2rem !important;
    }
}


@media (min-width: 1025px) {

    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout {
        display: grid;
        /* 58 / 42, con minmax(0,…) en las dos: sin ese 0 de mínimo, una tabla o un
           nombre largo empujarían su columna y desbordarían la fila. Es lo mismo que
           hace la rejilla del carrito lateral, y por lo mismo. */
        grid-template-columns: minmax(0, 58fr) minmax(0, 42fr);
        column-gap: 2.5rem;
        /* Explícito: entre el título del pedido y su tabla no puede quedar hueco de
           rejilla. Es 0 por defecto, pero se declara para que nadie lo abra sin darse
           cuenta al añadir un `gap` de dos valores. */
        row-gap: 0;
        align-items: start;
    }

    /* El suelo: todo lo que no se nombre abajo cruza las dos columnas. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > * {
        grid-column: 1 / -1;
        /* Un nombre largo parte por donde toque en vez de estirar su columna. */
        overflow-wrap: break-word;
    }

    /* Izquierda: los datos del cliente, abarcando el alto del título y del resumen. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #customer_details {
        grid-column: 1;
        grid-row: span 2;
    }

    /* Derecha: el rótulo "Tu pedido" y, debajo, el resumen. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #order_review_heading,
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #order_review {
        grid-column: 2;
    }

    /* 🔴 EL TÍTULO SE ESTIRA HASTA LA TABLA. AQUÍ ESTABA EL HUECO, Y NO ERA UN MARGEN.
       ═══════════════════════════════════════════════════════════════════════
       Los márgenes ya estaban a cero y el row-gap también, y aun así quedaba una
       franja entre "Tu pedido" y su tabla. El motivo es la rejilla:

         · #customer_details abarca DOS filas (grid-row: span 2) y es mucho más alto
           que el título y la tabla juntos;
         · el navegador reparte ese exceso de altura entre las dos filas que abarca,
           así que la fila del título crece bastante por encima de lo que el título
           necesita;
         · y con align-items: start, el título se queda pegado al techo de su fila
           dejando el resto vacío.

       Ese resto vacío es lo que se veía: NO es separación entre dos cajas, es la
       parte de la fila que el título no estaba ocupando. Y como el fondo crema es del
       título —no de la fila—, ahí se veía el fondo de la página.

       👉 Con align-self: stretch el título ocupa su fila entera, su crema llega hasta
          donde empieza la tabla y las dos piezas se leen como un panel continuo. El
          texto sigue arriba, sujeto por su propio padding.

       ⚠ SOLO CAMBIA EL ALTO DE UNA CAJA DE FONDO: ni el texto se mueve, ni la tabla,
         ni nada del bloque de pago. Es la única declaración que hacía falta.

       ⚠ Y no se toca el align-items: start del padre: el resto de bloques —los de
         ancho completo— deben seguir ajustándose a su contenido. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #order_review_heading {
        align-self: stretch;
    }

    /* ——— CÓDIGO POSTAL · POBLACIÓN · PROVINCIA, EN UNA SOLA FILA ———
       ═══════════════════════════════════════════════════════════════════════
       Los tres son .form-row.form-row-wide —el 100% de ancho que WooCommerce da por
       defecto a los campos de dirección— y por eso ocupaban tres filas enteras para
       tres datos cortos.

       🔴 SE HACE CON CSS Y NO REASIGNANDO CLASES EN EL FILTRO, Y ESE ES EL PUNTO MÁS
       IMPORTANTE DE ESTE BLOQUE. Al cambiar el País, WooCommerce recalcula estos
       campos por AJAX y REESCRIBE el interior del field-wrapper: una clase puesta
       desde PHP se perdería en ese recálculo y la fila se desharía sola a la primera
       interacción. Los IDs, en cambio, el AJAX los conserva —los necesita él mismo
       para localizar los campos—, así que colgando de ellos la maquetación sobrevive.

       🔴 Y ES GRID, NO FLEX, POR UNA RAZÓN CONCRETA. Para que una columna pueda
       encogerse por debajo del ancho de su contenido —imprescindible aquí, porque
       "Provincia" es un <select> que pide bastante— en flex haría falta min-width: 0,
       que este proyecto no usa en ninguna parte. En rejilla eso se expresa con
       minmax(0, 1fr), que es la forma que sí se usa (el carrito lateral, las columnas
       del checkout) y hace exactamente lo mismo sin la propiedad prohibida.

       ⚠ EL SUELO `> *` PROTEGE AL RESTO DE CAMPOS. En este envoltorio están también el
         nombre, los apellidos, el teléfono, el correo y la dirección, y todos deben
         seguir a ancho completo. Con la primera regla, cualquier campo que no se
         nombre —incluidos los que añada mañana un plugin— cruza las tres columnas
         igual que hoy. Solo se sacan de esa norma los tres de aquí abajo.

       ⚠ SI EL PAÍS NO TIENE PROVINCIAS, WooCommerce oculta ese campo y su columna
         queda vacía: los otros dos conservan su tercio y queda aire a la derecha. No
         se rompe nada, pero se ve. Es el precio de columnas de ancho fijo, y se
         prefiere a que los campos bailen de tamaño al cambiar de país.

       ⚠ align-items: start para que un mensaje de error bajo uno de los tres no
         estire a los otros dos. */
    /* 🔴 SEIS COLUMNAS, Y NO TRES, Y ESA ES LA CLAVE DE TODO EL BLOQUE.
       ═══════════════════════════════════════════════════════════════════════
       Con tres columnas salían los tercios pero NO las mitades: Nombre y Apellidos
       —que WooCommerce reparte al 50 % con sus clases form-row-first y form-row-last—
       no tenían forma de ocupar media fila y caían al suelo de "ancho completo",
       quedándose cada uno en su propia línea. Fue el efecto colateral de agrupar
       postal, población y provincia.

       Seis columnas dividen exactamente en las dos cosas que hacen falta:

           Nombre / Apellidos              → span 3  (3 de 6 = una mitad)
           Postal / Población / Provincia  → span 2  (2 de 6 = un tercio)
           Todo lo demás                   → las seis

       Y las cuentas salen exactas con el gap incluido: un elemento que abarca varias
       columnas se queda también con los huecos que hay entre ellas, así que dos
       mitades más su hueco central suman el ancho entero, y tres tercios más sus dos
       huecos, también.

       ⚠ SE USA `span` Y NO UN NÚMERO DE COLUMNA FIJO. Así los coloca el reparto
         automático en el orden en que estén en el documento, y eso importa: el AJAX de
         WooCommerce REORDENA estos campos según el país —no en todos va la provincia
         detrás de la población—. Con posiciones fijas, un cambio de país los habría
         cruzado; con `span`, cada uno cae donde le toque y la fila se rehace sola. */
    /* 🔴 LOS DOS FORMULARIOS —FACTURACIÓN Y ENVÍO— COMPARTEN ESTA REJILLA.
       ═══════════════════════════════════════════════════════════════════════
       Todo este bloque nació para el de facturación y nombraba solo sus envoltorios y
       sus ids. El de envío —el que se despliega al marcar "enviar a una dirección
       distinta"— trae EXACTAMENTE los mismos campos, con las mismas clases de
       WooCommerce y con ids gemelos (#shipping_first_name_field frente a
       #billing_first_name_field), pero se quedaba fuera de estos selectores: por eso
       salía con cada campo en su propia línea mientras el de arriba iba en filas.

       👉 No hizo falta ninguna regla nueva. Basta con que estas nombren también al
          envío: así los dos formularios comparten literalmente la misma maquetación y no
          hay dos sitios que puedan acabar diciendo cosas distintas.

       ⚠ EL APILADO EN MÓVIL SIGUE IGUAL PARA LOS DOS: todo esto vive dentro del @media de
         1025px, así que por debajo no hay rejilla y cada campo ocupa su línea.

       ⚠ NO SE TOCA NI EL DESPLIEGUE NI EL GUARDADO: el bloque de envío sigue apareciendo
         al marcar su casilla y sus campos se envían igual. Aquí solo se decide en qué
         celda se dibuja cada uno. */
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper {
        display: grid;
        /* 🔴 QUINCE COLUMNAS. Antes eran seis, y seis solo permite repartos en sextos:
           un tercio (2/6) o la mitad (3/6), pero nunca el 40 % que pide la fila del
           nombre. Quince es el mínimo común múltiplo que da las dos cosas a la vez:

               Nombre       → span 6   (40 %)
               Apellidos    → span 9   (60 %)
               Los tres de dirección → span 5 cada uno (un tercio exacto)

           ⚠ Y POR ESO EL GAP BAJA A 0,75rem. El hueco se aplica entre CADA columna, así
             que con quince hay catorce en vez de cinco. Manteniendo 1rem se comían más
             de doscientos píxeles del ancho útil y las columnas quedaban demasiado
             finas para repartir bien. Los huecos que caen DENTRO de un span se absorben
             en él, así que entre campo y campo se sigue viendo un solo hueco: no se
             nota más apretado, solo cuadra mejor. */
        grid-template-columns: repeat(15, minmax(0, 1fr));
        column-gap: 0.75rem;
        align-items: start;
    }

    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper > *,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper > * {
        grid-column: 1 / -1;
    }

    /* 🔴 Y QUE CADA CAMPO LLENE SU CELDA. AQUÍ ESTABA EL HUECO, Y NO ERA DEL INPUT.
       ═══════════════════════════════════════════════════════════════════════
       Medido en la página: el input de Nombre daba 116px y el de Apellidos 180px.
       Esos dos números no son un ancho por defecto —serían iguales— sino
       aproximadamente el 47 % de sus respectivas celdas, y ese 47 % es exactamente lo
       que WooCommerce da de serie a .form-row-first y .form-row-last, de cuando estos
       campos se maquetaban con flotados.

       Es decir: la rejilla repartía bien las celdas y el input llenaba bien su <p>…
       pero el <p> solo ocupaba media celda. El input no podía crecer más que su
       contenedor por mucho width: 100 % que llevara.

       Se le devuelve el ancho a TODOS los .form-row del bloque, no solo a los dos de
       la fila del nombre: el reparto lo decide la rejilla, y ningún campo tiene ya
       motivo para medir por su cuenta.

       ⚠ EL !important ES NECESARIO. Enfrente hay reglas de WooCommerce sobre
         .form-row-first / .form-row-last, y este mismo caso ya obligó a lo mismo en
         las dos columnas grandes del checkout: asignar la celda no basta si el
         elemento sigue midiendo lo que diga su propio width.

       ⚠ float: none porque esos anchos venían acompañados de flotados. Un elemento de
         rejilla no flota, así que ya no hacía nada, pero se declara para que no
         reaparezca si esto deja de ser un grid. */
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper > .form-row,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper > .form-row {
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
        box-sizing: border-box;
    }

    /* El <span> que WooCommerce mete entre el <p> y el campo. En línea no tiene ancho
       propio, así que se pasa a bloque: es el último eslabón entre la celda y el
       input, y si se queda corto todo lo de arriba no sirve de nada. */
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper .woocommerce-input-wrapper,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper .woocommerce-input-wrapper {
        display: block;
        width: 100%;
        box-sizing: border-box;
    }

    /* ——— NOMBRE Y APELLIDOS: UN TERCIO Y DOS TERCIOS ———
       Los apellidos son casi siempre más largos que el nombre —dos, con frecuencia—,
       así que repartir la fila a partes iguales dejaba el de la derecha justo y el de
       la izquierda sobrado.

       ⚠ SALE 33/67 Y NO EL 35/65 EXACTO, y es a propósito: con esta rejilla de seis
         columnas, dos y cuatro es el reparto más cercano que existe. Para clavar el
         35/65 harían falta sesenta columnas —el mínimo común múltiplo con los
         tercios—, y ahí el `column-gap` se multiplicaría por 59 en vez de por 5 y se
         comería el ancho entero. Dos puntos de diferencia no se ven; un formulario
         desbordado, sí. */
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_first_name_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_first_name_field {
        grid-column: span 6;
    }

    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_last_name_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_last_name_field {
        grid-column: span 9;
    }

    /* Postal, Población y Provincia, un tercio cada uno. */
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_postcode_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_city_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_state_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_postcode_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_city_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_state_field {
        grid-column: span 5;
    }

    /* El control tiene que llenar su columna. El <select> de provincia, si no, se
       queda a su ancho natural y las tres columnas se ven desiguales aunque midan lo
       mismo. overflow-wrap para que una etiqueta larga —"Provincia / Estado / Región"
       cambia según el país— parta en vez de empujar su columna. */
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_postcode_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_city_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #billing_state_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_postcode_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_city_field,
    body.woocommerce-checkout:not(.woocommerce-order-received) #shipping_state_field {
        overflow-wrap: break-word;
    }

    /* 🔴 EL CONTROL TIENE QUE LLENAR SU COLUMNA, Y ESTE ERA EL HUECO QUE SE VEÍA ENTRE
       NOMBRE Y APELLIDOS. La celda ya medía lo que debía; lo que se quedaba corto era
       el <input>, que sin un ancho declarado se dibuja a su tamaño por defecto —unos
       veinte caracteres— y deja el resto de la columna vacío. Con dos campos en la
       misma fila eso se lee como un hueco muerto en medio.

       Va para los cinco campos que comparten fila. Los de ancho completo no lo
       necesitan: ahí el input ya llega de serie hasta el borde. */
    /* Y el control, al ancho de su campo. Antes esto nombraba uno a uno los cinco
       campos que comparten fila; ahora cubre TODO el bloque, porque el reparto ya lo
       decide la rejilla y no hay ninguno que deba medir distinto.

       ⚠ `input.input-text` Y NO `input` A SECAS: esa es la clase que WooCommerce pone
         a los campos de texto. Con el selector abierto, un día que aquí aparezca una
         casilla —un plugin, un campo nuevo— se estiraría al ancho completo del
         formulario. */
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper .form-row input.input-text,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper .form-row select,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-billing-fields__field-wrapper .form-row textarea,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper .form-row input.input-text,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper .form-row select,
    body.woocommerce-checkout:not(.woocommerce-order-received) .woocommerce-shipping-fields__field-wrapper .form-row textarea {
        width: 100%;
        box-sizing: border-box;
    }

    /* 🔴 Y AHORA QUE LLENEN SU CELDA, QUE ES LO QUE FALTABA.
       ═══════════════════════════════════════════════════════════════════════
       Asignarles su columna con grid-column NO basta: dentro de esa celda, cada
       bloque sigue midiendo lo que diga su propio `width`, y WooCommerce/Astra le
       traen a #order_review un ancho PORCENTUAL —del orden del 48%, de cuando esto
       era un layout flotado—.

       Y ese porcentaje ahora se calcula sobre una caja mucho más pequeña: ya no
       sobre el contenedor entero, sino sobre su celda del grid. De ahí el resultado
       medido en la página: 193px, MÁS ESTRECHA que antes del ensanche. Ensanchar el
       contenedor sin neutralizar este ancho empeoraba justo lo que venía a arreglar.

       Con width y max-width al 100%, el bloque ocupa su celda entera y el reparto lo
       decide únicamente la rejilla del padre: 58 / 42.

       ⚠ EL !important ES NECESARIO AQUÍ, y no es pereza: enfrente hay una regla de
         WooCommerce/Astra sobre un selector de ID —#order_review, que puntúa 1-0-0—,
         y a igualdad de importancia un ID gana a casi cualquier cosa. Se comprobó en
         la página: el ancho salía de ahí.

       ⚠ EL float: none ES HIGIENE, no necesidad: un ítem de rejilla no flota, así que
         ese float heredado ya no hacía nada. Se declara para que no reaparezca si
         algún día esto deja de ser un grid.

       ⚠ NI UNA REGLA ENTRA DENTRO DE #order_review. El campo de la tarjeta salía
         comprimido porque lo estaba su contenedor; al ocupar la celda entera se
         resuelve solo. Stripe y el bloque de pago no se tocan. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #customer_details,
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #order_review_heading,
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #order_review {
        width: 100% !important;
        max-width: 100% !important;
        float: none !important;
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   AVISO DEL CARRITO — cuando el servidor RECHAZA un añadido
   ═══════════════════════════════════════════════════════════════════════════
   El mensaje que aparece abajo cuando una tarjeta de la tienda no puede añadir su
   producto y hay un motivo que explicar: hoy, sobre todo, la regla del plugin de
   suscripciones que no deja mezclar una suscripción con un producto de compra
   única. Lo pinta gaAvisoCarrito(), al final de assets/js/main.js.

   🔴 ES EL MISMO ASPECTO QUE .ga-alinos__aviso —el del bloque de aliños, en
   single-product.css—, y esa es toda la intención: no hay un estilo nuevo en la
   web, hay un aviso que ya existía y que ahora también llega a la tienda. Hace
   falta una clase propia porque aquel vive en single-product.css, que solo se
   carga en las fichas de producto y NO en /tienda/.

   ⚠ NO ES UN MODAL. No tiene velo, no atrapa el foco y no hay nada que cerrar:
     se va solo a los 6 segundos. Un bloqueo al añadir no merece interrumpir al
     cliente, solo explicarle por qué no ha pasado nada.

   ⚠ pointer-events: none PARA QUE NUNCA ESTORBE. Está fijo sobre el contenido, y
     sin esto se comería los clics de lo que tape mientras dura.

   ⚠ NI TAMAÑO NI POSICIÓN CAMBIAN AL APARECER: solo opacidad y visibilidad. La
     caja está siempre en el mismo sitio, se ve o no se ve.
   ═══════════════════════════════════════════════════════════════════════════ */

.ga-carrito-aviso {
    position: fixed;
    left: 50%;
    bottom: 1.25rem;
    transform: translateX(-50%);
    z-index: 9999;

    /* A 360px son 331px: entra de sobra y no puede desbordar a lo ancho. El
       border-box es lo que mantiene esa cuenta con el relleno incluido. */
    width: min(92vw, 26rem);
    box-sizing: border-box;
    margin: 0;
    padding: 0.85rem 1.15rem;

    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.4;
    text-align: center;
    /* Los mensajes del plugin son largos y vienen en una sola frase: sin esto, una
       palabra suelta muy larga podría sacar la caja de su ancho. */
    overflow-wrap: break-word;

    color: var(--ga-blanco);
    background-color: var(--ga-verde-oliva-oscuro);
    border-radius: var(--ga-radius-sm);
    box-shadow: 0 4px 24px rgba(74, 74, 47, 0.28);

    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity var(--ga-transition-normal),
                visibility var(--ga-transition-normal);
}

.ga-carrito-aviso.is-visible {
    opacity: 1;
    visibility: visible;
}

@media (prefers-reduced-motion: reduce) {
    .ga-carrito-aviso {
        transition: none;
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — SIN CABECERA
   ═══════════════════════════════════════════════════════════════════════════
   En la pantalla de pago se quita la cabecera entera —logo, menú, cuenta y carrito—
   para que nada distraiga de terminar la compra. La salida es el enlace "Volver a la
   página de inicio" del pie reducido, que footer.php imprime aquí a propósito.

   🔴 "PEDIDO RECIBIDO" QUEDA FUERA DE TODO ESTE BLOQUE. WooCommerce le pone la misma
   clase woocommerce-checkout al <body>, pero es la situación contraria: el cliente ya
   ha pagado y ahí lo que se quiere es devolverle la navegación. De ahí el
   :not(.woocommerce-order-received) en las tres reglas. Si se cae de una sola, esa
   pantalla se queda coja sin que nadie lo note hasta que lo diga un cliente.

   🔴 Y SON TRES REGLAS PORQUE HACEN FALTA LAS TRES. Ocultar la barra a secas dejaría
   un hueco en blanco de 80 px arriba —el que el body reserva para la cabecera fija— y
   el salto a los campos con error seguiría descontando una altura que ya no existe.
   Cada una tapa un cabo:

     1. la barra deja de pintarse;
     2. el body deja de reservarle sitio;
     3. el desplazamiento a las anclas deja de descontar su altura.

   Y falta una cuarta pieza, que vive en el bloque del hero: allí el checkout de pago
   tiene su propia regla sin el margen negativo, porque ya no hay hueco que tapar.

   ⚠ SE OCULTA POR CSS Y NO SE QUITA DEL HTML, a propósito: get_header() vive en
     page.php, que comparten las páginas legales, y condicionarlo allí sería tocar una
     plantilla común por un caso particular. Con display:none la cabecera no se pinta
     NI RECIBE FOCO por teclado, así que no queda un menú fantasma navegable.

   ⚠ EL CARRITO LATERAL NO EXISTE AQUÍ, y es consecuencia buscada: gaCarritoPanel()
     sale por su propia puerta al no encontrar .ga-nav__carrito. No hay ningún error en
     consola —las funciones que buscan la cabecera llevan su guarda—, simplemente ese
     panel no se monta. En el pago el pedido ya se edita en la propia página.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · Fuera la barra. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-header {
    display: none;
}

/* 2 · Y fuera el hueco que le reservaba el body, o quedaría una franja en blanco de la
       altura de la cabecera antes de la banda del título. */
body.woocommerce-checkout:not(.woocommerce-order-received) {
    padding-top: 0;
}

/* 3 · El desplazamiento a las anclas, sin descontar una cabecera que ya no está.
       html lleva scroll-padding-top: var(--ga-nav-height) para que un ancla no quede
       debajo de la barra fija; sin barra, eso dejaría 80 px de más justo cuando el
       checkout salta a un campo con error.

   ⚠ VA EN SU PROPIA REGLA Y NO EN UNA LISTA. :has() no lo entienden los navegadores
     anteriores a 2023, y un selector inválido dentro de una lista invalida la regla
     ENTERA. Aislada, lo peor que puede pasar es que un navegador viejo la ignore y
     conserve el desfase de 80 px, que es un detalle y no un fallo. Es el mismo criterio
     —y el mismo :has() sobre html— que ya usa el overscroll-behavior de la tienda. */
html:has(body.woocommerce-checkout:not(.woocommerce-order-received)) {
    scroll-padding-top: 0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — SIN PIE, Y UNA LÍNEA DE LEGALES EN SU LUGAR
   ═══════════════════════════════════════════════════════════════════════════
   La pantalla de pago se queda sin cabecera y ahora también sin pie. En su sitio, al
   final de la página, los cinco enlaces legales en gris, en una sola fila alineada a la
   derecha y del ancho de la columna del pedido: lo único que esta pantalla tiene que
   seguir ofreciendo. (Nació con una raya fina encima y se le quitó; si buscas el
   border-top, ya no existe.)

   🔴 MISMO MECANISMO QUE LA CABECERA, A PROPÓSITO: display:none por CSS y acotado con
   body.woocommerce-checkout:not(.woocommerce-order-received). Ni remove_action ni una
   condición dentro de footer.php —que sirve a TODAS las páginas del sitio— por un caso
   particular. Y con display:none el pie no se pinta NI RECIBE FOCO por teclado, así que
   tampoco queda un menú fantasma navegable detrás.

   🔴 "PEDIDO RECIBIDO" QUEDA FUERA, como en todo este archivo: allí el cliente ya ha
   pagado y se le devuelve la navegación entera, pie incluido.

   ⚠ EL PIE SIGUE EN EL DOM Y EN LAS DEMÁS PÁGINAS NO CAMBIA NADA. Las reglas del "pie
     reducido" que había más arriba (líneas 1442 y siguientes) siguen ahí y siguen
     sirviendo a la TIENDA, que las comparte en la misma lista de selectores; lo único
     que ha pasado es que su mitad de checkout ya no se ve. No se tocan: separarlas
     obligaría a duplicar esa lista para no ganar nada.

   ⚠ LA SALIDA DE LA PANTALLA NO DESAPARECE: el enlace "Volver a la página de inicio"
     vivía en ese pie, pero arriba sigue la banda "GRAN ALMAZARA", que enlaza a la
     tienda. Se pierde también el copyright, que aquí no aporta.

   ⚠ NADA DE ANCHOS FIJOS NI DE min-width: la fila es un flex que ENVUELVE, así que a
     360px los enlaces caen a varias líneas en vez de estirar la fila. Es la trampa nº 9
     —el nowrap del pie con contenido variable— y por eso aquí se deja envolver desde el
     primer día, aunque mañana se añada un sexto enlace.

   ⚠ NINGÚN ESTADO CAMBIA TAMAÑO NI POSICIÓN: al pasar el ratón o al llegar con el
     tabulador solo cambia el COLOR del texto. Ni subrayado que empuje, ni negrita, ni
     desplazamiento.

   ⚠ EL GRIS NO ES UNA VARIABLE PORQUE NO EXISTE NINGUNA EN LA PALETA. Se usa el verde
     oliva de marca con transparencia —rgba(74, 74, 47, 0.6)—, que es el mismo recurso
     que este archivo ya emplea para los textos secundarios (líneas 2149 y 2827) y que
     sobre blanco se lee como un gris cálido, en vez de traer un gris frío nuevo al
     sitio. La raya sí va en variable: --ga-amarillo-pastel, la que este tema usa para
     sus líneas discretas.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · Fuera el pie entero. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-footer {
    display: none;
}

/* 2 · El aire de arriba y de abajo.
   🔴 ARRIBA VA MUY JUSTO, Y ES A PROPÓSITO: los enlaces tienen que leerse como el pie
   del recuadro de pago que tienen encima, no como un bloque aparte. Por eso el hueco
   superior baja a 0.5rem y EL padding-top DESAPARECE. Ese relleno existía para dejar
   respirar a la raya de 1px que hubo aquí; retirada la raya, lo único que hacía era
   sumar 16px al hueco.

   ⚠ ABAJO NO SE TOCA: ese margen es el que impide que los enlaces queden pegados al
     filo de la ventana, y ahí sí hace falta aire.

   ⚠ Y NO QUEDA NINGÚN border: aquí hubo un border-top de 1px y se retiró entero, sin
     dejar declaración. Si lo buscas, ya no existe. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal {
    margin: var(--ga-space-xs) 0 var(--ga-space-md);
}

/* 3 · La fila, CENTRADA dentro del ancho de su bloque —que es el de la columna del
       pedido, ver 3 bis—, no respecto a la página entera. flex con wrap: nunca puede ser
       más ancha que el viewport, y si no cabe parte en varias líneas, que quedan
       centradas también, en vez de estirar la caja. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__nav {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: var(--ga-space-xs);

    font-family: var(--ga-font-body);
    font-size: var(--ga-text-xs);
    line-height: 1.4;
    text-align: center;
    /* Una etiqueta larga —"Condiciones de Venta"— parte por donde toque antes que
       marcar un ancho mínimo. Nada de min-width en toda la web. */
    overflow-wrap: break-word;
}

/* 3 bis · Y EL BLOQUE, DEL ANCHO DE LA COLUMNA DERECHA Y DEBAJO DE ELLA.
   ═══════════════════════════════════════════════════════════════════════════
   🔴 ESTA ES LA PIEZA QUE COLOCA EL BLOQUE; LA DE ARRIBA SOLO CENTRA SU CONTENIDO. Sin
   ella, el bloque mediría el 100 % del contenedor y sus enlaces quedarían centrados
   respecto a la PÁGINA ENTERA —o sea, a caballo entre las dos columnas—, que no es lo
   que se busca: tienen que leerse como el pie del recuadro de pago.

   Se le da el ancho exacto de la columna derecha y se le empuja con margin-left: auto.
   Al medir lo mismo que esa columna, el centrado del contenido cae justo en su eje, y
   si algún día la fila se parte en dos líneas se parte DENTRO de ese ancho, sin
   extenderse por debajo de la columna izquierda:

       ancho de la columna 2 = (100% − column-gap) × 42/100

   🔴 ESOS DOS NÚMEROS NO SON INVENTADOS: son los mismos de la rejilla del formulario
   —grid-template-columns: minmax(0, 58fr) minmax(0, 42fr) y column-gap: 2.5rem, línea
   23000—. Si algún día se cambia el reparto, hay que cambiarlo AQUÍ TAMBIÉN. Es el
   precio de que este bloque viva FUERA del formulario: se imprime en el gancho
   woocommerce_after_checkout_form, después de cerrar </form>, así que no es hijo de esa
   rejilla y no puede heredar sus columnas. Meterlo dentro sería moverlo en el marcado,
   y eso no se toca.

   ⚠ FUNCIONA PORQUE COMPARTEN CAJA: comprobado en el HTML real, el <div> es hermano
     directo de <form class="checkout"> dentro del mismo .ga-section__inner--narrow, así
     que ese 100 % es exactamente el mismo ancho sobre el que la rejilla reparte 58/42.

   ⚠ SOLO A PARTIR DE 1025px, que es donde existen las dos columnas. Por debajo el
     formulario es una sola columna: el bloque se queda a ancho completo y sus enlaces
     siguen alineados a la derecha, que es lo coherente. Y al no fijar ancho en móvil,
     no hay nada que pueda desbordar a 360px.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (min-width: 1025px) {

    body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal {
        width: calc((100% - 2.5rem) * 0.42);
        margin-left: auto;
    }
}

/* 4 · Los enlaces, en el gris cálido. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__nav a {
    color: rgba(74, 74, 47, 0.6);
    text-decoration: none;
    transition: color var(--ga-transition-normal);
}

/* Al pasar el ratón y al llegar con el tabulador, SOLO el color: el mismo verde oliva
   de marca a plena opacidad. Ni tamaño, ni posición, ni subrayado. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__nav a:hover,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__nav a:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__nav a:focus-visible {
    color: var(--ga-verde-oliva-oscuro);
    text-decoration: none;
}

/* 5 · Los puntos separadores, más apagados que los propios enlaces: están para separar,
       no para leerse. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-legal__sep {
    color: rgba(74, 74, 47, 0.35);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — LA MINIATURA DEL PRODUCTO EN "TU PEDIDO"
   ═══════════════════════════════════════════════════════════════════════════
   La foto de cada producto, a la izquierda de su nombre. El marcado lo genera
   ga_checkout_miniatura_en_nombre() en functions.php, y solo existe en esta pantalla:

       <span class="ga-checkout-item">
           <span class="ga-checkout-item__img"><img class="ga-checkout-item__foto"></span>
           <span class="ga-checkout-item__nombre">NOMBRE</span>
       </span>

   🔴 POR QUÉ inline-flex Y NO flex, QUE ES LO QUE PARECE QUE TOCA.
   Ese <span> no está solo en la celda: la plantilla de WooCommerce escribe justo
   después, COMO HERMANO, el <strong class="product-quantity">× 3</strong>. Con un
   `display: flex` —que es de nivel bloque— el "× 3" caería a una línea propia debajo
   de la miniatura, y hoy se lee en la misma línea que el nombre. Con inline-flex la
   caja sigue siendo parte del renglón y el "× 3" se queda donde estaba.

   Y detrás del "× 3" viene además el <dl class="variation"> con los campos de
   personalización de eventos —hasta ocho: cristal, etiqueta, unidades, texto, las dos
   fechas, notas y variedad—. Ese es un bloque, así que baja solo. No hay que hacer
   nada con él, pero hay que saber que está: es lo que hace estrecha esta celda.

   🔴 LOS !important, Y POR QUÉ NO SON PEREZA. Se buscó en los cuatro CSS del tema hijo
   la regla que se suponía que oculta las imágenes de la tabla del pedido y NO EXISTE:
   ni un `img { display: none }` en main.css, single-product.css, woocommerce.css ni
   elementor-compat.css. O sea que si algo la esconde, viene de fuera —de Astra o del
   propio WooCommerce—, y eso no se puede leer desde local. Los !important van solo
   sobre las cuatro propiedades que deciden que la foto SE VEA y a qué tamaño; es el
   mismo criterio ya documentado unas líneas más arriba para el bloque del cupón, que
   pelea contra assets/css/woocommerce.css por la misma razón.

   ⚠ ACOTADO DOS VECES: al body del pago con el :not(.woocommerce-order-received) de
     siempre, y además a #order_review. Fuera de esa caja no hay ninguna clase
     .ga-checkout-item —el filtro de PHP no la genera en ningún otro sitio—, pero el
     selector lo deja escrito igualmente para que no pueda alcanzar a nada el día que
     alguien reutilice el nombre.

   ⚠ NINGÚN min-width, como en toda la web. El ancho mínimo se corta con el
     flex-basis explícito de la foto y con overflow-wrap en el nombre.

   ⚠ NINGÚN ESTADO CAMBIA TAMAÑO NI POSICIÓN: aquí no hay hover, ni foco, ni
     transición. La miniatura no es pulsable —el nombre en el resumen del pago no
     enlaza a ninguna parte, a diferencia del de /carrito/— y no se le añade ninguno.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item {
    display: inline-flex;
    align-items: center;
    gap: var(--ga-space-xs);
    /* Para que la caja pueda encogerse dentro de la celda en vez de empujarla: un
       inline-flex se dibuja a su ancho natural, y sin este techo un nombre largo
       ensancharía la columna del resumen. */
    max-width: 100%;
    /* Alinea la caja con el "× 3" que viene detrás. Sin esto se apoyaría en la línea
       base y el número quedaría pegado al borde inferior de la foto. */
    vertical-align: middle;
    text-align: left;
}

/* ——— EL HUECO DE LA FOTO ———
   Medida fija y flex-shrink a cero: la miniatura nunca se estruja ni se deforma,
   por estrecha que quede la columna. Lo que cede es el texto, que para eso parte.

   ⚠ LOS 72px INCLUYEN EL BORDE, no se suman a él: el reset de este tema declara
     box-sizing: border-box para todo (línea 38), así que el recuadro se descuenta
     del ancho en vez de ensanchar la caja. Por eso el flex-basis puede decir el
     mismo número que el width sin descuadrar la fila. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img {
    display: block !important;
    flex: 0 0 72px;
    width: 72px;
    height: 72px;
    /* El recorte vive en el contenedor y no en la <img>, así el redondeo se mantiene
       aunque un día la foto llegue con otra proporción. */
    overflow: hidden;
    /* El recuadro. Mismo grosor de 1px; lo que cambia es el color.

       🔴 ERA EL NEGRO DE MARCA Y PESABA DEMASIADO. Un contorno negro alrededor de una
       foto pequeña la convierte en un sello, y aquí la miniatura solo acompaña al
       nombre del producto: tiene que delimitar la foto, no enmarcarla.

       ⚠ NO HAY NINGUNA VARIABLE DE GRIS EN LA PALETA, así que en vez de inventar un
         #ccc suelto se usa --ga-amarillo-pastel, que es el color con el que este tema
         ya dibuja sus líneas y bordes discretos —las divisorias del carrito lateral,
         sin ir más lejos—. Sobre el crema del panel se lee como un gris cálido, y
         encaja con el resto en vez de traer un tono nuevo al sitio.

       ⚠ ESTA VARIABLE SÍ SE DECLARA en el :root de style.css, así que no necesita el
         respaldo que llevaba --ga-negro-suave (🪤 nº 15). Y conviene saber por qué
         importaba en un borde: `border-color` no es heredada y su valor inicial es
         currentColor, así que un var() sin resolver no habría dejado el recuadro
         negro ni transparente, sino del color del texto de la fila. */
    border: 1px solid var(--ga-amarillo-pastel);
    border-radius: var(--ga-radius-sm);
    /* Un fondo por debajo, por dos motivos. El primero es que, mientras la foto carga,
       el hueco no parpadee sobre el crema del panel.

       🔴 Y EL SEGUNDO ES POR QUÉ ES BLANCO Y NO EL CREMA. Casi todas las fotos del
       catálogo son OPACAS y traen su fondo blanco cocido en la imagen —comprobado en
       las miniaturas de 100x100: WebP con pérdida y PNG de tipo 2, ninguno con canal
       alfa—, pero dos SÍ tienen transparencia real: el aceitunero y la mermelada. Con
       el crema debajo, esas dos enseñaban el crema donde las demás enseñaban blanco y
       se leían como de otra serie. En blanco, las opacas y las transparentes quedan
       iguales. */
    background-color: var(--ga-blanco);
}

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img img {
    display: block !important;
    width: 100% !important;
    height: 100% !important;
    max-width: 100% !important;
    /* 🔴 contain, Y ANTES ERA cover. El cambio es lo que hace posible el ajuste de zoom
       por producto que hay al final de este bloque, así que no es un detalle suelto:
       con `cover` la foto ya llega recortada al borde del cuadro, de modo que cualquier
       scale() por debajo de 1 destaparía el fondo y cualquiera por encima recortaría el
       producto de inmediato. Con `contain` la foto entra ENTERA y con su aire, que es el
       margen sobre el que el scale puede trabajar en los dos sentidos.

       ⚠ LA CONTRAPARTIDA, ASUMIDA: si una foto no fuera cuadrada, ahora deja franjas de
         fondo dentro del cuadro en vez de recortarse. Sobre el blanco del contenedor y
         con fotos de catálogo que son cuadradas, no se ve; y es justo lo que permite
         corregir a mano la que se salga. */
    object-fit: contain;
    /* Higiene: WooCommerce y Astra reparten márgenes a las imágenes de las tablas. */
    margin: 0;
    padding: 0;
    border: 0;
    box-shadow: none;
    border-radius: 0;
}

/* ——— EL NOMBRE ———
   flex-basis 0 con crecimiento: ocupa lo que sobre después de la foto, ni un píxel
   más. `anywhere` es lo que de verdad permite que la palabra más larga no marque un
   ancho mínimo, que es justo lo que aquí no se puede usar (nada de min-width); el
   break-word de la línea anterior es el respaldo para navegadores que no lo entiendan. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__nombre {
    flex: 1 1 0;
    overflow-wrap: break-word;
    overflow-wrap: anywhere;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.35;
    color: var(--ga-negro-suave, #1a1a14);
}

/* ——— AJUSTE FINO EN MÓVIL ———
   A 360px la celda del nombre se queda en algo más de 200px con la columna de importes
   al lado. Con 72px de foto quedarían unos 120px para el nombre, y ahí "Descubrimiento"
   o "Personalización" empiezan a partirse por la mitad. Con 56 —que es el tamaño que
   tenía el escritorio antes de agrandarlo, o sea una medida ya vista y validada— el
   nombre respira y la miniatura se sigue leyendo de sobra.

   ⚠ DESBORDAR NO PUEDE, ni siquiera a 72px: el nombre lleva overflow-wrap: anywhere, así
     que la palabra más larga siempre puede partir. Esto es una cuestión de que se lea
     bien, no de que quepa.

   ⚠ EL RECUADRO NO SE REPITE AQUÍ. Solo cambian las tres medidas; el borde, el redondeo
     y el fondo los hereda de la regla base y no hay que volver a declararlos.

   ⚠ 600px es el punto de corte de "ajustes finos" que ya usa el resto del sitio, y no
     uno nuevo: por encima no cambia absolutamente nada. */
@media (max-width: 600px) {

    body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img {
        flex: 0 0 56px;
        width: 56px;
        height: 56px;
    }
}


/* ——— AJUSTE DE ENCUADRE POR PRODUCTO ———
   ═══════════════════════════════════════════════════════════════════════════
   Cada foto del catálogo trae su propia proporción de aire alrededor del producto, así
   que a igual tamaño de cuadro unas botellas se ven grandes y otras diminutas. Se
   corrige una a una, con transform: scale() sobre la <img>.

   🔴 ES EL MISMO MECANISMO QUE YA USAN LA HOME Y LA TIENDA, a propósito: allí son
   .ga-home-card--sku-… (main.css, líneas 3159 y 9610) y aquí .ga-checkout-item__img--sku-…
   La clase la construye ga_checkout_miniatura_en_nombre() en functions.php a partir del
   SKU real —minúsculas y sanitize_html_class—, así que no hay ningún ID ni slug escrito
   a mano y un producto nuevo solo necesita su línea aquí.

   ⚠ LOS VALORES NO SE PUEDEN COPIAR DE LA HOME, y por eso son otros. Allí la foto se
     pide en tamaño 'woocommerce_single' y el marco es de 380px; aquí es la de 100x100
     recortada en cuadrado dentro de un cuadro de 72px. Son encuadres distintos: estos
     números se calibran mirando ESTA pantalla.

   ⚠ SOLO SE TOCA LA <img>. El cuadro —su medida, su borde, su redondeo y su fondo
     blanco— no cambia, así que la fila del resumen no se mueve ni un píxel. Lo que
     sobresalga lo recorta el overflow: hidden que el contenedor ya tenía.

   ⚠ NI UN ESTADO. Aquí no hay :hover ni :focus, al contrario que en las tarjetas de la
     tienda: la miniatura del pago no es pulsable y nada debe moverse mientras el cliente
     paga. Si algún día se añade un zoom al pasar el ratón, deja de cumplirse la regla de
     que ningún estado cambia tamaño ni posición.

   ⚠ Y FUNCIONA GRACIAS AL object-fit: contain de la regla de arriba: es el que deja la
     foto entera dentro del cuadro y da margen para agrandar o encoger.
   ═══════════════════════════════════════════════════════════════════════════ */

/* GARRAFA 2L (GA-PET-2L-NOV): la foto llena el cuadro y se ve desproporcionada al lado
   de las demás. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img--sku-ga-pet-2l-nov img {
    transform: scale(0.80);
}

/* GARRAFA 5L (GA-PET-5L-NOV): mismo caso que la 2L, con algo menos de corrección. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img--sku-ga-pet-5l-nov img {
    transform: scale(0.90);
}

/* BOTELLA 500ml (GA-BELL-500-OCT): su foto trae mucho aire, así que a igual cuadro la
   botella se ve más pequeña que las garrafas. Se agranda para que casen entre ellas. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .ga-checkout-item__img--sku-ga-bell-500-oct img {
    transform: scale(1.20);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — "TU PEDIDO", "SUBTOTAL" Y "TOTAL" EN NEGRITA
   ═══════════════════════════════════════════════════════════════════════════
   Las tres piezas que estructuran la columna del resumen: el título del bloque y las
   dos filas de importe que el cliente busca antes de pagar. En negrita se leen como
   los tres puntos de anclaje de la columna, y las líneas de producto quedan por debajo
   en jerarquía sin tener que tocarlas.

   🔴 QUÉ SE QUEDA FUERA, QUE ES LA MITAD DEL ENCARGO. El <tfoot> de la tabla lleva
   TRES filas hermanas —.cart-subtotal, .woocommerce-shipping-totals y .order-total—,
   así que un selector cómodo tipo `tfoot th` se llevaría "Envío" por delante. Por eso
   cada fila se nombra por su clase y "Envío" ni se menciona. Tampoco se toca ninguna
   .cart_item: las líneas de producto se quedan exactamente como están.

   ⚠ EL TÍTULO YA DEBERÍA SER NEGRITA, y aun así la regla hace falta. La regla general
     de titulares de este archivo —`h1, h2, h3, h4, h5, h6`, línea 149— fija
     `font-weight: var(--ga-weight-bold)`, y "Tu pedido" es un <h3>. Si en pantalla no
     se ve así es porque Astra imprime su tipografía del personalizador DESPUÉS de esta
     hoja, y a igualdad de especificidad gana el último. Este selector puntúa 1-2-1
     —lleva el id—, así que le gana sin necesidad de !important.

   ⚠ EL IMPORTE DEL TOTAL YA VIENE EN <strong> DE FÁBRICA: WooCommerce lo envuelve él
     en review-order.php. Declararlo aquí no cambia nada en ese caso y cubre el del
     Subtotal, que no lo lleva. Que las dos filas se declaren igual es a propósito: así
     no dependen de un detalle del marcado de WooCommerce que puede cambiar.

   ⚠ SOLO EL GROSOR. Ni tamaño, ni familia, ni color: la columna sigue con la misma
     escala y la misma paleta de antes. Por eso aquí no aparece ninguna variable de
     color —tampoco --ga-negro-suave—: no había color que cambiar, y declararlo habría
     sido meterse en lo que el encargo dejaba fuera.

   ⚠ NINGÚN ESTADO: no hay hover, ni foco, ni transición. Un cambio de grosor tampoco
     mueve nada de sitio — "Subtotal" y "Total" son palabras cortas en su propia celda,
     y a 360px la columna va a ancho completo, así que los pocos píxeles que engorda
     el texto no pueden desbordar ni empujar la columna de importes.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · El título del bloque. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
    font-weight: var(--ga-weight-bold);
}

/* 2 y 3 · Las etiquetas "Subtotal" y "Total", con sus importes.
   Las dos filas juntas porque reciben exactamente el mismo tratamiento. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .cart-subtotal th,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .cart-subtotal td,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .order-total th,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .order-total td {
    font-weight: var(--ga-weight-bold);
}

/* La coletilla del IVA, NO. WooCommerce puede añadir dentro de la celda del total un
   <small class="includes_tax"> con el "(incluye X € de IVA)". Es una nota al pie del
   importe, no el importe: en negrita competiría con la cifra que tiene justo encima.
   Se le devuelve el grosor normal, que es el que tiene hoy. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .cart-subtotal small,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .order-total small {
    font-weight: var(--ga-weight-normal);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — EL RÓTULO "PAGO EXPRÉS" SOBRE LOS BOTONES DE STRIPE
   ═══════════════════════════════════════════════════════════════════════════
   Apple Pay, Google Pay y compañía salen arriba del formulario sin nada que los
   presente. Este rótulo los nombra.

   🔴 POR QUÉ CON CSS Y NO CON UN HOOK DE PHP, QUE ERA LA OTRA OPCIÓN.
   No es por comodidad: es que PHP NO PUEDE CUMPLIR EL REQUISITO. Que haya botones
   exprés o no lo decide el NAVEGADOR, en tiempo de ejecución: Stripe pinta siempre el
   contenedor desde el servidor y luego su JS monta dentro un <iframe> solo si el
   dispositivo tiene algún método disponible —un Android sin Google Pay configurado, o
   un Windows con Firefox, no ven ninguno—. Un rótulo impreso por PHP saldría también
   en esos casos: un encabezado suelto sin nada debajo.

   Por eso la condición se comprueba donde se puede comprobar, en el CSS:

       #wc-stripe-express-checkout-element:has(iframe)::before

   Sin iframe montado no hay rótulo. Y el ::before es CONTENIDO GENERADO, no un nodo
   del DOM: Stripe puede vaciar y rehacer el interior del contenedor las veces que
   quiera —lo hace al cambiar el importe— y no puede borrarlo, porque no está ahí.
   Tampoco se toca ni una propiedad de los botones ni del contenedor.

   ⚠ EL :not(:has(#…)) DEL SEGUNDO SELECTOR ES PARA QUE NO SALGAN DOS RÓTULOS. Según la
     versión del plugin, el contenedor puede ser el id o una caja con la clase que lo
     envuelve. Si estuvieran los dos, el :has(iframe) los cazaría a AMBOS —:has() mira
     descendientes, no solo hijos— y el rótulo se pintaría dos veces. Con ese :not(),
     la parte de la clase solo actúa cuando el id no está dentro.

   ⚠ AQUÍ SÍ SE PUEDEN LISTAR LOS DOS SELECTORES CON COMA, y conviene distinguirlo de la
     regla de siempre: lo que no se puede es MEZCLAR uno con :has() y otro sin él, porque
     el navegador que no entienda :has() se llevaría por delante también al que sí
     funcionaba. Aquí los dos lo llevan, así que caen juntos o se aplican juntos: no hay
     nada que perder y se evita tener las declaraciones duplicadas y con riesgo de que se
     descuadren al retocar una sola.

   ⚠ SI CAEN, NO PASA NADA: no sale el rótulo y los botones siguen funcionando igual.

   ⚠ LIMITACIÓN ASUMIDA, Y ES REAL: el contenido generado por CSS no es texto de
     verdad y los lectores de pantalla no lo anuncian de forma fiable. Se acepta
     porque la alternativa —PHP— no puede saber si hay botones, y un rótulo mentiroso
     es peor que uno que algún lector no lea. Los botones sí están etiquetados por
     Stripe.

   ═══════════════════════════════════════════════════════════════════════════
   🔴 POR QUÉ EL RÓTULO SALÍA A LA IZQUIERDA DE LOS BOTONES, Y NO ENCIMA.
   ═══════════════════════════════════════════════════════════════════════════
   El contenedor de Stripe es un FLEX EN FILA. Y un ::before sobre un contenedor flex no
   es "texto dentro de la caja": es un ÍTEM FLEX más, hermano de los botones. Por eso se
   colocó a su izquierda, como uno de ellos.

   Y por eso el `display: block` que llevaba no arreglaba nada: a un ítem flex se le
   "blockifica" el display y sigue siendo un ítem de la misma fila. El display no tenía
   ninguna posibilidad de sacarlo de ahí.

   👉 SE ARREGLA CON DOS PIEZAS, Y HACEN FALTA LAS DOS:

     1. flex-basis: 100% en el rótulo → pide la fila entera;
     2. flex-wrap: wrap en el CONTENEDOR → sin esto, el punto 1 no sirve de nada. Una
        fila flex es `nowrap` por defecto, así que un ítem que pide el 100% no empuja a
        nadie: simplemente se reparten el hueco a la fuerza y siguen todos en la misma
        línea. El wrap es lo que convierte esa petición en un salto de verdad.

   ⚠ EL flex-wrap ES LO ÚNICO QUE SE LE TOCA AL CONTENEDOR, y no alcanza a los botones:
     con el rótulo ocupando la primera línea, ellos caen enteros a la segunda y se
     reparten entre sí exactamente igual que antes. Ni una regla entra en los botones,
     ni en el iframe, ni en nada del funcionamiento de Stripe.

   ⚠ EL !important DEL flex-wrap ES PREVISOR: Stripe pinta ese contenedor con estilos EN
     LÍNEA (lleva un `clear:both; padding-top:1.5em` puesto a mano), y si algún día
     añadiera ahí el flex-wrap, un estilo en línea gana a esta hoja sin él.

   ⚠ Y VA TAMBIÉN UN grid-column: 1 / -1, que en un flex se ignora sin más. Es el seguro
     por si en otra versión del plugin ese contenedor fuera un grid en vez de un flex: en
     ese caso el flex-basis no haría nada y sería esta línea la que le diera la fila
     entera. Cuesta una declaración y cubre el otro escenario posible.

   ⚠ TAMAÑO: sube de --ga-text-sm a --ga-text-lg (18px), que es cuerpo de subtítulo y se
     lee de lejos, pero sigue por debajo de los 24px de "Tu pedido" y del título del
     bloque de envío, así que no compite con ellos. Sigue en la Inter del sitio y no en
     la serif de titulares: es un rótulo de sección, no un titular.
   ═══════════════════════════════════════════════════════════════════════════ */

/* 1 · El contenedor tiene que poder partir la fila. Sin esto, el 100% del rótulo no
       empuja a nadie y todo se queda en la misma línea. */
body.woocommerce-checkout:not(.woocommerce-order-received) #wc-stripe-express-checkout-element:has(iframe),
body.woocommerce-checkout:not(.woocommerce-order-received) .wc-stripe-express-checkout:has(iframe):not(:has(#wc-stripe-express-checkout-element)) {
    flex-wrap: wrap !important;
}

/* 2 · El rótulo, ocupando la primera línea entera por encima de los botones. */
body.woocommerce-checkout:not(.woocommerce-order-received) #wc-stripe-express-checkout-element:has(iframe)::before,
body.woocommerce-checkout:not(.woocommerce-order-received) .wc-stripe-express-checkout:has(iframe):not(:has(#wc-stripe-express-checkout-element))::before {
    content: "Pago exprés";

    /* La fila entera para él solo. El width acompaña al flex-basis por si el contenedor
       no fuera flex; el grid-column cubre el caso de que fuera un grid. */
    display: block;
    flex: 0 0 100%;
    width: 100%;
    grid-column: 1 / -1;
    /* Que sea SIEMPRE el primero de la caja, aunque Stripe ordenara sus ítems. */
    order: -1;

    /* Aire cómodo hasta los botones de debajo. */
    margin: 0 0 1rem;

    /* 🔴 LA MISMA TIPOGRAFÍA QUE "Datos de envío y facturación", VALOR POR VALOR.
       Ese título es un <h3> sin reglas propias en el tema: todo lo que lo viste sale
       de las dos reglas generales de tipografía de este archivo —la de h1…h6 y la de
       h3—, así que aquí se repiten sus cuatro valores tal cual:

           font-family  → var(--ga-font-display)      (la serif de marca)
           font-size    → var(--ga-text-2xl)          (el cuerpo de un h3)
           font-weight  → var(--ga-weight-bold)
           line-height  → 1.2

       El color ya coincidía: --ga-verde-oliva-oscuro es el que da la regla de h1…h6.

       ⚠ SE COPIAN LOS VALORES Y NO SE CONVIERTE EN <h3>, porque esto no es un
         elemento: es el ::before de la caja de Stripe. No hay marcado que cambiar.

       ⚠ Y SE FUE EL letter-spacing: el h3 no declara ninguno, así que mantenerlo aquí
         habría dejado los dos títulos con distinto espaciado entre letras justo
         cuando se buscaba que fueran idénticos. */
    font-family: var(--ga-font-display);
    font-size: var(--ga-text-2xl);
    font-weight: var(--ga-weight-bold);
    line-height: 1.2;
    text-align: center;
    color: var(--ga-verde-oliva-oscuro);
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — EL CUPÓN, YA EN SU SITIO NUEVO
   ═══════════════════════════════════════════════════════════════════════════
   El bloque pasó de arriba del todo a debajo de "Notas del pedido", al final de la
   columna izquierda. Lo pinta ga_checkout_cupon_abajo() en functions.php.

   🔴 EL AVISO PLEGADO NO NECESITA NI UNA REGLA NUEVA, Y ESO ERA EL OBJETIVO. El estilo
   discreto que se le dio en su día —sin banda crema, sin filete dorado, sin icono, el
   texto como un enlace— cuelga de `.woocommerce-form-coupon-toggle .woocommerce-info`,
   unos miles de líneas más arriba en este mismo archivo. Es un selector de descendencia,
   sin ninguna atadura a la posición, y el marcado nuevo conserva esa clase a propósito.
   Se movió el bloque y el estilo se fue con él.

   👉 LO QUE SÍ HACÍA FALTA es lo de aquí abajo: el DESPLEGABLE —el campo y el botón—
   nunca tuvo estilos propios en este tema. Se entiende por qué: hasta ahora vivía
   escondido arriba del todo y prácticamente no se veía. Ahora está al final de una
   columna estrecha y se despliega dentro del formulario, así que necesita medidas.

   ⚠ SE ANULAN form-row-first / form-row-last SIN USARLAS. WooCommerce reparte esos dos
     campos con `float: left; width: 47%`, que en una columna de ~320px deja el botón
     partido y el campo inservible. Por eso el marcado nuevo NO usa esas clases: monta
     una fila flex propia. Aquí no hay nada que desactivar, solo lo que se construye.

   ⚠ NADA DE min-width, como en todo el sitio: el campo se encoge con flex-basis 0 y el
     botón no se encoge por flex-shrink: 0.

   ⚠ NINGÚN ESTADO CAMBIA TAMAÑO NI POSICIÓN. El foco del campo solo cambia el color del
     borde —mismo grosor— y añade sombra; el botón solo oscurece su fondo. Nada se mueve.

   ⚠ EL CAMPO A 16px CLAVADOS. Por debajo de eso, iOS hace zoom al enfocar y descoloca el
     checkout entero. Es la misma regla que ya sigue el formulario de Contacto.
   ═══════════════════════════════════════════════════════════════════════════ */

/* El bloque desplegable. El `display: none` de partida lo trae el marcado en línea, y
   quien lo abre y lo cierra es el manejador de WooCommerce: aquí no se toca `display`,
   o le estaríamos peleando el control del desplegable. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon {
    margin: 0.75rem 0 0;
    padding: 1rem;
    background-color: var(--ga-blanco);
    border: 1px solid rgba(74, 74, 47, 0.18);
    border-radius: var(--ga-radius-md);
}

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__texto {
    margin: 0 0 0.75rem;
    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    line-height: 1.4;
    color: var(--ga-negro-suave, #1a1a14);
}

/* Campo y botón en una fila. Con wrap, para que a 360px el botón caiga debajo en vez de
   estrujar el campo hasta dejarlo inservible. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__fila {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ga-space-xs);
}

/* ——— EL CAMPO DEL CUPÓN, IGUAL QUE LOS DEMÁS CAMPOS DEL CHECKOUT ———
   🔴 DE DÓNDE SALÍA EL "RECUADRO CREMA" AL ENFOCAR: DE AQUÍ MISMO, NO DE FUERA.
   Este campo tenía box-shadow: 0 0 0 3px rgba(199,168,98,0.22) —un halo dorado de 3px al
   22 %—, y sobre fondo blanco eso se ve como un anillo crema encendido. Los demás campos
   del checkout llevan uno mucho más discreto (2px al 15 %, woocommerce.css línea 321) y
   por eso no llamaban la atención. Aquí se quita del todo: en foco solo cambia el COLOR
   del borde, que es lo pedido y no mueve nada porque el grosor sigue siendo 1px.

   ⚠ Y EL BORDE IBA MÁS OSCURO QUE EL DEL RESTO: 0,28 de opacidad frente al 0,2 que
     woocommerce.css da a los demás campos. Ahora es exactamente el mismo valor.

   🔴 LOS !important, Y POR QUÉ SON NECESARIOS AQUÍ. El borde de PUNTOS no sale de ningún
   CSS del tema hijo: se buscaron `dotted` y `dashed` en los cuatro archivos y ninguna de
   las coincidencias alcanza a este campo. O sea que lo pinta Astra —que imprime su
   tipografía y sus formularios DESPUÉS de esta hoja y no se puede leer desde local—, y
   la única forma de asegurarlo sin verlo es blindar las cuatro propiedades que deciden
   el aspecto: fondo, borde, sombra y contorno. No van en ninguna más.

   ⚠ 16px Y NO --ga-text-sm, aunque los demás campos usen 14px: por debajo de 16 iOS hace
     zoom al enfocar y descoloca el checkout. Es la regla del proyecto y aquí se respeta.
     (Que los demás campos estén a 14px es un problema anterior y de otra tarea.)

   ⚠ 10px DE RADIO, el mismo que se acaba de dar al resto de campos del formulario. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__campo {
    /* flex-basis en píxeles y no en cero: por debajo de ese ancho el botón se va a la
       línea de abajo, que es justo el comportamiento que se busca en móvil. */
    flex: 1 1 10rem;
    width: auto;
    margin: 0;
    padding: 0.6rem 0.75rem;
    box-sizing: border-box;

    font-family: var(--ga-font-body);
    /* 16px literales: es el umbral por debajo del cual iOS hace zoom al enfocar. */
    font-size: 16px;
    line-height: 1.3;
    color: var(--ga-negro-suave, #1a1a14);

    background-color: var(--ga-blanco) !important;
    /* `solid` explícito y el mismo gris translúcido que llevan los demás campos. */
    border: 1px solid rgba(74, 74, 47, 0.2) !important;
    border-radius: 10px !important;
    box-shadow: none !important;
    outline: none !important;

    transition: border-color var(--ga-transition-normal);
}

/* En foco, SOLO el color del borde. Ni fondo distinto, ni halo, ni contorno punteado.
   El grosor no cambia, así que el campo no se mueve ni empuja al botón de al lado. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__campo:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__campo:focus-visible {
    background-color: var(--ga-blanco) !important;
    border: 1px solid var(--ga-naranja-apagado) !important;
    box-shadow: none !important;
    outline: none !important;
}

/* El botón. Los !important son los de siempre en la tienda: Astra y WooCommerce capturan
   .button con selectores que ganan a cualquier clase propia y reescriben fondo, color y
   borde (🪤 nº 6). Solo van en esas tres propiedades. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__btn {
    flex: 0 0 auto;
    margin: 0;
    padding: 0.6rem 1.1rem;

    font-family: var(--ga-font-body);
    font-size: var(--ga-text-sm);
    font-weight: var(--ga-weight-medium);
    line-height: 1.3;

    color: var(--ga-blanco) !important;
    background-color: var(--ga-verde-oliva-oscuro) !important;
    border: 1px solid var(--ga-verde-oliva-oscuro) !important;
    border-radius: var(--ga-radius-sm);
    cursor: pointer;
    transition: background-color var(--ga-transition-normal),
                border-color var(--ga-transition-normal);
}

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__btn:hover,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__btn:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__btn:focus-visible {
    color: var(--ga-blanco) !important;
    /* 🔴 DORADO DE MARCA, Y ANTES ERA --ga-marron-oscuro. Ese marrón no es de la línea
       visual del sitio y ya se había descartado por lo mismo en otro sitio —el modal de
       Eventos, línea 16900, donde también se le dio la vuelta—. El nombre de la variable
       despista: --ga-naranja-apagado ES el dorado #c7a862, el de los CTAs. Es histórico y
       no se renombra.

       ⚠ SOLO COLOR. El grosor del borde no se declara aquí —sigue siendo el 1px de la
         regla de reposo—, así que el botón no cambia de tamaño ni empuja al campo de al
         lado al pasar el ratón. */
    background-color: var(--ga-naranja-apagado) !important;
    border-color: var(--ga-naranja-apagado) !important;
}

/* Mientras vuela la petición. Solo opacidad y cursor: ni tamaño ni posición. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon__btn:disabled {
    opacity: 0.6;
    cursor: default;
}

/* El aviso que devuelve el servidor tras aplicar, que el JS cuelga encima del bloque.
   Solo se le da aire; el aspecto se lo siguen dando los estilos de aviso de WooCommerce,
   que aquí sí se quieren —esto es un mensaje de verdad, no la banda del desplegable—. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon-aviso {
    margin: 0.75rem 0 0;
}

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-cupon-aviso > * {
    margin-bottom: 0;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — AIRE VERTICAL EN LAS FILAS DE "TU PEDIDO"
   ═══════════════════════════════════════════════════════════════════════════
   Las líneas de producto salían pegadas a sus filetes de separación: WooCommerce da a
   esas celdas `padding: 9px 12px`, que era razonable cuando la fila era una línea de
   texto y se quedó corto en cuanto la fila pasó a tener una miniatura de 72px.

   🔴 EL RELLENO VA EN LAS CELDAS, NO EN LA FILA. `.cart_item` es un <tr>, y a un <tr>
   el padding NO le hace nada: en el modelo de tabla, el relleno de una fila lo ponen
   sus celdas. Por eso el selector termina en `td` y no en `.cart_item` a secas. Es el
   error fácil aquí, y el síntoma sería "he puesto el padding y no pasa nada".

   🔴 Y POR ESO EL FILETE QUEDA DONDE ESTABA. La línea de separación es el `border-top`
   de esas mismas celdas, así que el padding-top empuja el contenido hacia abajo
   ALEJÁNDOLO de la línea, que es exactamente lo que se pedía. El filete no se mueve, no
   cambia de color ni de grosor: no se toca ninguna propiedad de borde.

   ⚠ MÁS ARRIBA QUE ABAJO, A PROPÓSITO: 1,25rem contra 1rem. No es un capricho de
     simetría —es que el filete de arriba pertenece a ESTA fila y el de abajo pertenece a
     la SIGUIENTE, que aporta su propio padding-top. Con los dos valores iguales, el
     hueco por debajo acabaría viéndose mayor que el de encima.

   ⚠ SOLO EL EJE VERTICAL. No se declara ni padding-left ni padding-right, así que el
     reparto horizontal se queda tal cual y a 360px no puede desbordar nada: no hay una
     sola declaración que ensanche la fila.

   ⚠ LOS TOTALES SUBEN TAMBIÉN, PERO MENOS. Subtotal, Envío y Total son filas de una sola
     línea de texto: con el mismo relleno que un producto de 72px quedarían desmesuradas,
     y sin tocar se leerían apretadas al lado de los productos aireados. 0,9rem parejos
     las deja respirando en el mismo idioma sin competir. Solo cambia su espaciado
     interior; los importes, la negrita de Subtotal y Total y la coletilla del IVA se
     quedan igual.

   ⚠ SIN !important, y se comprobó por qué se puede: en assets/css/woocommerce.css —que se
     imprime DESPUÉS de esta hoja y va cargado de !important— no hay ni una regla que
     alcance a esta tabla; sus únicos selectores de checkout son el h3, los campos del
     formulario y el botón de ir al pago. Enfrente solo está el 0-2-2 de WooCommerce, y
     estos selectores puntúan 1-4-2.

   ⚠ NINGÚN ESTADO: aquí no hay hover, ni foco, ni transición. Nada se mueve nunca.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Las filas de producto. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table .cart_item td,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table .cart_item th {
    padding-top: 1.25rem;
    padding-bottom: 1rem;
}

/* Subtotal, Envío y Total, en el mismo idioma pero a su escala. El selector va sobre el
   <tfoot> entero para que alcance también a cualquier fila que WooCommerce añada ahí
   —una tasa, un impuesto desglosado— y no quede una sola apretada entre las demás. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table tfoot th,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .shop_table tfoot td {
    padding-top: 0.9rem;
    padding-bottom: 0.9rem;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — ESQUINAS REDONDEADAS EN LOS CAMPOS DEL FORMULARIO
   ═══════════════════════════════════════════════════════════════════════════
   Los campos de facturación, envío y notas pasan a 10px de radio, el mismo que el panel
   de "Tu pedido". Es solo estético: no se toca ni una medida, ni el borde, ni el color,
   ni el relleno, ni el ancho. Solo el radio.

   🔴 HACEN FALTA ESPECIFICIDAD Y !important, Y NO ES PEREZA. Enfrente hay una regla que
   pone estas esquinas a cero A PROPÓSITO, en assets/css/woocommerce.css línea 313:

       .woocommerce-checkout .form-row input,
       .woocommerce-checkout .form-row select,
       .woocommerce-checkout .form-row textarea { border-radius: 0 !important; }

   Ese archivo declara 'gran-almazara-main' como dependencia en su wp_enqueue_style, así
   que se imprime DESPUÉS de este. Con !important y cargándose después, para ganarle hace
   falta lo mismo que ya se hizo con el bloque del cupón: más especificidad Y !important.
   La suya puntúa 0-2-1; estas 1-4-2.

   🔴 LOS DESPLEGABLES NECESITAN SU PROPIA REGLA, Y ESTE ES EL PUNTO QUE SE ESCAPA.
   País/Región y Provincia los mejora Select2 (selectWoo), que WooCommerce carga en el
   checkout. Select2 OCULTA el <select> nativo y dibuja en su lugar un <span> con la
   clase .select2-selection. Redondear el <select> no se vería: no es lo que hay en
   pantalla. Por eso va la segunda regla.

   ⚠ ESA SEGUNDA REGLA NO LLEVA !important, y es deliberado: nada del tema pone radio a
     Select2, así que solo compite con el 0-2-0 de su propia hoja, al que estas 1-3-1 ya
     le ganan. Sin !important se le deja a Select2 margen para sus propios estados.

   ⚠ ACOTADO A #customer_details, QUE ES LO QUE DEJA A STRIPE FUERA. El bloque de pago
     vive en #order_review, en la otra columna, así que ni una de estas reglas lo alcanza.
     Los campos de la tarjeta los sigue gobernando Stripe, como debe ser.

   ⚠ `input.input-text` Y NO `input` A SECAS. Esa es la clase que WooCommerce pone a los
     campos de texto. Con el selector abierto se redondearían también las casillas de
     verificación, que quedarían como pastillas. Es el mismo criterio que ya sigue la
     regla de anchos del bloque de la rejilla, unos cientos de líneas más arriba.

   ⚠ 10px LITERAL Y NO UNA VARIABLE, porque ninguna vale eso: la escala declarada en
     style.css es 4px (--ga-radius-sm), 8px (--ga-radius-md) y 9999px (--ga-radius-full).
     El 10px es el que ya usa a mano el panel de "Tu pedido", y esto se iguala con él.

   ⚠ EL BLOQUE DEL CUPÓN NO ENTRA, y es a propósito: su campo no vive en un .form-row
     sino en su propia tarjeta blanca, donde el campo y el botón comparten 4px entre
     ellos. Subir solo el campo a 10px rompería la armonía interna de esa tarjeta.

   ⚠ NINGÚN ESTADO CAMBIA TAMAÑO NI POSICIÓN: el radio es el mismo en reposo, al pasar el
     ratón y con el foco. Aquí no se declara ningún estado.

   ⚠ A 360px NO PUEDE DESBORDAR: un border-radius no altera la caja: ni ancho, ni alto,
     ni relleno. Los campos miden exactamente lo mismo que antes.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Textos, desplegables nativos y el área de notas. */
body.woocommerce-checkout:not(.woocommerce-order-received) #customer_details .form-row input.input-text,
body.woocommerce-checkout:not(.woocommerce-order-received) #customer_details .form-row select,
body.woocommerce-checkout:not(.woocommerce-order-received) #customer_details .form-row textarea {
    border-radius: 10px !important;
}

/* Y el control que de verdad se ve en País/Región y Provincia. */
body.woocommerce-checkout:not(.woocommerce-order-received) #customer_details .select2-selection {
    border-radius: 10px;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — FUERA EL BOTÓN FLOTANTE DE CONSENTIMIENTO
   ═══════════════════════════════════════════════════════════════════════════
   El botón "Gestionar consentimiento" de Complianz flota fijo en la esquina inferior
   derecha, y en la pantalla de pago se cruza con el resumen y con el botón de pagar. Es
   la misma decisión que ya se tomó con la cabecera: en el pago no debe haber nada que
   distraiga ni que se ponga por delante de terminar la compra.

   🔴 ESTO NO DEJA AL CLIENTE SIN FORMA DE GESTIONAR LAS COOKIES, Y SE COMPROBÓ ANTES DE
   ESCRIBIR LA REGLA, porque si no la hubiera habría que no hacerlo:

     · footer.php imprime el enlace "Preferencias" —<a class="cmplz-show-banner">— dentro
       de .ga-footer__legal-nav, en la barra inferior del pie, y NO dentro de la parte
       condicional del pie reducido: sale en todas las páginas;
     · y el pie del checkout esconde .ga-footer__col--nav, --social, --contacto, el logo
       y los iconos de pago (línea 1447), pero NO .ga-footer__legal-nav: a esa solo le
       baja el cuerpo a 0,68rem (línea 1523).

   O sea que en el pago sigue habiendo enlace de Preferencias, funcionando con
   gaCookiesReabrirBanner(). Lo que se quita es el atajo flotante, no el acceso.

   🔴 EL BANNER INICIAL NO SE TOCA. El de aceptar/rechazar la primera vez es otro
   elemento distinto —#cmplz-cookiebanner-container / .cmplz-cookiebanner, que son los
   que busca gaCookiesReabrirBanner() en main.js—, y ninguno de los tres selectores de
   abajo lo alcanza. Sigue saliendo en el pago igual que en el resto del sitio.

   ⚠ SE NOMBRAN LOS TRES SELECTORES DEL WIDGET porque Complianz ha cambiado su marcado
     entre versiones y desde aquí no se puede leer el DOM real. Los tres pertenecen al
     mismo botón flotante —el id del envoltorio, su clase y la del botón de dentro—, así
     que nombrarlos todos no puede alcanzar a nada más. Y ninguno choca con la clase
     .cmplz-show-banner del enlace del pie, que es otra distinta.

   ⚠ EL !important ES NECESARIO AQUÍ, no es prudencia: ese widget lo muestra y lo esconde
     el JS de Complianz, y un `display` puesto por JS va como estilo EN LÍNEA. Un estilo
     en línea gana a cualquier regla de hoja que no lleve !important, por alta que sea su
     especificidad. Sin él, la regla se perdería en cuanto el plugin decidiera mostrarlo.

   ⚠ ACOTADO AL PAGO Y SOLO AL PAGO. El selector exige body.woocommerce-checkout, así que
     en la home, la tienda, las fichas y el resto del sitio el botón flotante sigue
     apareciendo con normalidad. Y "Pedido recibido" queda fuera con el :not() de
     siempre: allí vuelven la cabecera y el pie completos.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) #cmplz-manage-consent,
body.woocommerce-checkout:not(.woocommerce-order-received) .cmplz-manage-consent,
body.woocommerce-checkout:not(.woocommerce-order-received) .cmplz-manage-consent-container {
    display: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — FUERA LOS ASTERISCOS DE CAMPO OBLIGATORIO
   ═══════════════════════════════════════════════════════════════════════════
   Los asteriscos rojos junto a "Nombre", "Apellidos" y compañía no aportan nada aquí:
   en este formulario TODO es obligatorio salvo lo que lleva "(opcional)" escrito al
   lado, así que marcar la norma en vez de la excepción solo añade ruido rojo a una
   pantalla donde lo único que se quiere es que el cliente avance.

   🔴 ESTO NO QUITA LA OBLIGATORIEDAD, Y LA DISTINCIÓN ES IMPORTANTE. Se esconde UNA
   MARCA VISUAL, nada más. Lo que hace obligatorio un campo sigue intacto en tres capas,
   y ninguna de las tres pasa por el CSS:

     1. el atributo required="required" del propio <input>, que lo pone WooCommerce y es
        lo que impide enviar el formulario desde el navegador;
     2. la validación de WooCommerce en el servidor —WC_Checkout::validate_posted_data()—,
        que es la que de verdad no se puede saltar y que es PHP puro;
     3. la clase .validate-required del .form-row, que es de la que tira el JS del
        checkout para pintar los errores.

   Ninguna se toca. Un campo vacío sigue bloqueando el pedido exactamente igual que antes.

   ⚠ Y TAMPOCO SE PIERDE PARA UN LECTOR DE PANTALLA. Ese <abbr> no era la forma en que se
     anunciaba la obligatoriedad: WooCommerce pone además required="required" Y
     aria-required="true" en el propio campo, y es de ahí de donde lo lee. El asterisco
     era información redundante, y solo para quien ve la pantalla.

   ⚠ EL "(opcional)" SE QUEDA, que es justo lo que sostiene la decisión. WooCommerce lo
     pinta en un <span class="optional">, una clase DISTINTA de la que se oculta aquí, así
     que los campos opcionales siguen distinguiéndose. Si un día se ocultaran también, el
     cliente perdería la única pista que le queda: no hacerlo.

   ⚠ ALCANZA TAMBIÉN AL ASTERISCO DE LA CASILLA DE TÉRMINOS, y es deliberado: WooCommerce
     lo pinta con la misma clase dentro de su <label>. Dejar ese solo, suelto en la
     página, cantaría más que quitarlos todos. La casilla sigue siendo obligatoria por las
     mismas tres capas de arriba.

   ⚠ EL !important NO ES IMPRESCINDIBLE PERO SÍ BARATO. Enfrente, WooCommerce declara
     `visibility: visible` sobre .required —que no compite con `display`, son propiedades
     distintas, pero deja claro que es un elemento que el plugin defiende de que lo
     escondan—. Como no hay ningún caso legítimo en que ese asterisco deba verse en esta
     pantalla, se cierra de raíz en vez de dejarlo a merced de lo que traiga Astra.

   ⚠ SE ACOTA A DENTRO DE UNA <label>. La clase `required` es un nombre demasiado común
     para soltarla sin contexto: dentro de la etiqueta solo puede ser este asterisco. El
     segundo selector añade `abbr.required` por si alguna versión lo sacara del <label>,
     y ese sí es marcado inequívoco de WooCommerce.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) label .required,
body.woocommerce-checkout:not(.woocommerce-order-received) abbr.required {
    display: none !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — EL PAGO EXPRÉS, A LA COLUMNA IZQUIERDA
   ═══════════════════════════════════════════════════════════════════════════
   Apple Pay, Google Pay y compañía dejan de cruzar las dos columnas y pasan a lo alto de
   la columna izquierda, encima de "Datos de envío y facturación". El recorrido queda:
   primero el pago rápido; debajo, el "— O —"; y debajo, rellenar los datos.

   🔴 NO SE MUEVE NI UN NODO, Y ESA ES LA CONDICIÓN DE TODA LA TAREA.
   Stripe monta los botones haciendo .mount('#wc-stripe-express-checkout-element'), y
   montar significa meter un <iframe> ahí dentro. Reparentar un <iframe> obliga al
   navegador a RECARGARLO: se destruye su contexto de navegación, pierde el enlace con la
   instancia Elements que lo creó y el botón se queda muerto. Por eso aquí no hay ni JS ni
   PHP: el marcado se queda EXACTAMENTE donde el plugin lo escribe y solo se cambia la
   CELDA de la rejilla en la que se pinta. Para Stripe no ha pasado nada.

   ⚠ Y HAY UN SEGUNDO MOTIVO, MÁS SILENCIOSO: #wc-stripe-express-checkout__order-attribution-inputs
     son campos ocultos que tienen que viajar en el POST del pedido. Al no moverlos, siguen
     dentro de <form class="checkout"> y se siguen enviando. Un movimiento de DOM que los
     sacara del formulario habría roto la atribución sin dar ningún error.

   ⚠ ESTO ES POSIBLE PORQUE YA SON HERMANOS. El bloque exprés lo pinta el gancho
     woocommerce_checkout_before_customer_details, que se dispara DENTRO del <form> y antes
     de #customer_details: o sea que ya es hijo directo de la misma rejilla que reparte las
     dos columnas. Es justo el caso en que la colocación por grid funciona —al contrario
     que el cupón, que vivía fuera del formulario y hubo que resolverlo de otra forma—.

   ⚠ POR QUÉ SALÍA A DOBLE ANCHO, que no era cosa de Stripe: lo mandaba el suelo
     `form.checkout > *` de la línea 23000, que da la fila entera a todo hijo que no se
     nombre. Aquí se le pone nombre y deja de heredarlo.

   ⚠ SELECTORES POR PREFIJO, a propósito. Se usan [id^="wc-stripe-express-checkout"] y
     [class*="express-checkout"] en vez de nombrar los ids uno a uno, porque el plugin
     reparte el bloque en varios hermanos —el contenedor, el separador y los campos de
     atribución— y su número ha cambiado entre versiones. Así, si una actualización añade
     otro, cae también en la columna izquierda en vez de irse al suelo de doble ancho.

   ⚠ LAS FILAS SE DEJAN EN AUTOMÁTICO A LA IZQUIERDA. Solo se fija la COLUMNA; el orden de
     las filas lo resuelve la colocación automática siguiendo el orden del DOM, que ya es
     el bueno (exprés → separador → datos). Así el número de piezas del exprés da igual.

   ⚠ EL PANEL DE LA DERECHA NO SE MUEVE. "Tu pedido" sigue en la columna 2 y con su 42%.
     Su tabla se coloca a la misma altura que el formulario —las dos piezas largas, una
     por columna— y el título va en la fila inmediatamente anterior, a su altura natural.
     Al ser dos filas consecutivas, entre la cabecera y la tabla no queda ni un píxel de
     fondo de página. El porqué exacto del reparto de filas está explicado abajo, junto a
     las reglas.

   ⚠ NADA DE min-width: las columnas siguen siendo las mismas minmax(0, 58fr) y
     minmax(0, 42fr) de siempre. Aquí no se toca el reparto, solo quién va en cada celda.

   🔴 EN MÓVIL NO HAY QUE HACER NADA, Y CONVIENE SABER POR QUÉ. La rejilla solo existe a
   partir de 1025px. Por debajo, form.checkout es flujo normal y el orden del DOM ya es
   exprés → "— O —" → datos → Tu pedido, que es exactamente el que se pide. Todo este
   bloque vive dentro del @media, así que el móvil no se entera del cambio: si algo
   saliera mal en escritorio, a 360px se sigue viendo como hoy.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1025px) {

    /* ═══════════════════════════════════════════════════════════════════════
       🔴 EL PAGO EXPRÉS VUELVE ARRIBA, A TODO EL ANCHO. AQUÍ NO HAY REGLA, Y ESO ES
          EL CAMBIO.
       ═══════════════════════════════════════════════════════════════════════
       Durante un tiempo este bloque colocaba el exprés en la columna izquierda
       (grid-column: 1) y mandaba el formulario a la fila 10, la cabecera a la 9 y el
       resumen a la 10. TODO ESO SE HA RETIRADO.

       👉 POR QUÉ SE DESHACE. Metido en la columna izquierda, el exprés COMPARTÍA FILAS
          con el panel "Tu pedido". Y como Stripe monta de forma ASÍNCRONA, cada vez que
          los botones aparecían el panel de la derecha se descolocaba: primero se
          agrandaba (cuando la cabecera se estiraba), luego se desplazaba. Se intentó
          resolver de tres maneras distintas y todas chocaban con la misma pared: en una
          rejilla, las filas son COMPARTIDAS por las dos columnas.

       👉 ARRIBA Y A TODO EL ANCHO, EL PROBLEMA DESAPARECE DE RAÍZ: el exprés deja de
          compartir fila con nadie. Si carga tarde se empuja a sí mismo y baja en bloque
          lo que tiene debajo, que es el comportamiento normal de una página. El panel
          "Tu pedido" ya no puede deformarse ni desincronizarse de su columna.

       ⚠ NO HACE FALTA DECLARAR NADA PARA CONSEGUIRLO, y por eso aquí no hay selector:
         el suelo `form.checkout > *` de la línea 23000 ya da la fila entera a todo hijo
         que no se nombre. Basta con NO nombrar al exprés. Colocarlo era la excepción;
         quitarla lo devuelve al comportamiento por defecto.

       ⚠ Y LAS DOS COLUMNAS TAMPOCO SE DECLARAN AQUÍ: se restauran solas al retirar las
         sobrescrituras, porque el bloque base (líneas 23007-23046) nunca se tocó. Allí
         siguen #customer_details en la columna 1 abarcando dos filas, la cabecera y el
         resumen en la 2, y el align-self: stretch que mantiene el crema continuo.

       ⚠ EL ORDEN EN MÓVIL NO CAMBIA: nunca dependió de esto. Por debajo de 1025px no hay
         rejilla y manda el orden del DOM, que ya es exprés → datos → Tu pedido.
       ═══════════════════════════════════════════════════════════════════════ */

    /* ⚠ HISTORIAL, PARA NO REPETIR EL CAMINO. Aquí hubo, y se han retirado, tres
       sobrescrituras más: el formulario en la fila 10, la cabecera en la 9 y el resumen
       en la 10. Nacieron para convivir con el exprés dentro de la columna izquierda, y
       cada una arregló un fallo que había causado la anterior:

         · el resumen con `grid-row: 2 / span 4` INFLABA las filas cortas de la izquierda
           cuando el pedido traía muchos productos (un elemento que abarca filas y no cabe
           en la suma de sus alturas las agranda y reparte el sobrante) → hueco muerto;
         · la cabecera con `grid-row: 1 / 10` + `align-self: stretch` crecía hasta la
           altura del exprés, y como Stripe carga tarde, el panel se agrandaba solo;
         · la cabecera en la fila 9 con altura propia arreglaba eso, pero el panel bajaba
           de sitio al montar los botones.

       Con el exprés arriba y a todo el ancho NINGUNO de los tres problemas puede
       reproducirse, porque su causa común era compartir filas entre las dos columnas. Si
       algún día vuelve a plantearse meterlo en una columna, esto es lo que espera. */

    /* ——— EL SEPARADOR "— O —" ———
       Solo su separación y su tipografía. Quién lo enseña y quién lo esconde se decide
       en el bloque de RESERVA DE ALTURA que viene justo debajo: no se toca aquí. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #wc-stripe-express-checkout-button-separator {
        margin-top: 1.25rem;
        margin-bottom: 1.25rem;
        text-align: center;
        font-family: var(--ga-font-body);
        font-size: var(--ga-text-sm);
        color: var(--ga-negro-suave, #1a1a14);
    }


    /* ═══════════════════════════════════════════════════════════════════════
       RESERVA DE ALTURA DEL PAGO EXPRÉS — PARA QUE "TU PEDIDO" NO DÉ EL SALTO
       ═══════════════════════════════════════════════════════════════════════
       🔴 QUÉ RESUELVE ESTO Y QUÉ NO, AHORA QUE EL EXPRÉS ESTÁ ARRIBA Y A TODO EL ANCHO.
       Con la colocación actual, "Tu pedido" ya NO puede deformarse ni desincronizarse:
       no comparte fila con el exprés y su altura la decide solo su contenido. Lo que
       sigue habiendo, si no se reserva, es un SALTO DE PÁGINA: Stripe monta de forma
       asíncrona y, al aparecer, empuja hacia abajo TODO lo que tiene debajo —las dos
       columnas enteras— a destiempo y con el cliente ya mirando la pantalla.

       👉 ESTA RESERVA SIGUE HACIENDO FALTA, y por eso no se ha retirado con el resto:
          deja el hueco hecho DE ANTEMANO para que al montar no empuje nada. Es lo mismo
          que antes, pero ahora protege del salto a la página entera en vez de a una
          columna.

       🔴 Y HAY QUE RESERVAR DOS COSAS, NO UNA. Es lo que se midió, y es la razón de que
          un min-height suelto en el contenedor no bastara. Al montar aparecen TRES
          piezas de golpe, repartidas en DOS elementos hermanos:

            en #wc-stripe-express-checkout-element   el rótulo "Pago exprés" (~39px)
                                                     + el iframe de los botones (~48px)
            en el separador                          el "— O —" con sus márgenes (~58px)

          Reservando solo el primero se quitaría el 60 % del salto y quedarían ~58px
          saltando igual. Por eso van los dos.

       ⚠ SOLO EN ESCRITORIO. Todo esto vive dentro del @media de 1025px, que es donde
         existen las dos columnas y donde el desplazamiento se nota. En móvil NO se
         reserva nada: allí el pago exprés está arriba del todo, en una sola columna, y
         un hueco muerto en un dispositivo sin Apple Pay ni Google Pay sería peor que el
         propio salto.

       ⚠ LA CONTRAPARTIDA, ASUMIDA Y CONVIENE TENERLA ESCRITA: en un escritorio SIN
         métodos exprés —Firefox en Windows, Chrome sin tarjeta guardada— el hueco
         reservado se queda vacío. Es el precio de reservar a ciegas: nadie puede saber
         antes de tiempo si Stripe va a montar algo. Si un día molesta más el hueco que
         el salto, se borra este sub-bloque entero y se vuelve al comportamiento anterior.

       ⚠ ES UN min-HEIGHT, NO UN min-WIDTH. La regla del proyecto prohíbe los min-width
         (rompen el corte del ancho mínimo); las alturas mínimas sí están permitidas, y
         esta es exactamente para lo que sirven: reservar espacio vertical.
       ═══════════════════════════════════════════════════════════════════════ */

    /* 1 · EL HUECO DE LOS BOTONES.
       7rem = 112px, medido sobre lo que ocupa el bloque ya montado: los ~24px del
       padding-top que el propio Stripe pone en línea, más el rótulo y el iframe. El
       box-sizing: border-box del reset hace que el padding vaya DENTRO de esa cuenta.

       ⚠ SI LOS BOTONES SALIERAN MÁS ALTOS —Stripe permite configurar su altura, y con
         varios métodos disponibles pueden apilarse en dos filas— la caja crecería por
         encima de la reserva y volvería a haber un salto, más pequeño. Ese es el número
         a subir: está aquí y en ningún otro sitio. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #wc-stripe-express-checkout-element {
        min-height: 7rem;
    }

    /* 2 · EL HUECO DEL "— O —".
       🔴 AQUÍ SE CAMBIA UNA DECISIÓN ANTERIOR, Y HAY QUE DECIR POR QUÉ. Antes este
       archivo decía expresamente que al separador NO se le declaraba `display`, porque
       nace con display:none en línea y es el JS de Stripe quien lo enseña; forzarlo
       sacaría un "— O —" huérfano donde no hay botones.

       Ese MOTIVO sigue siendo válido y se respeta entero. Lo que cambia es el mecanismo:
       un elemento con display:none NO TIENE CAJA, así que es imposible reservarle sitio.
       Se le da caja siempre —display: block— y se controla su aparición con VISIBILITY,
       que oculta pero conserva el hueco. El resultado a la vista es el mismo que antes:
       sin botones exprés, no se ve ningún "— O —".

       ⚠ EL !important ES NECESARIO: enfrente está el style="display:none" EN LÍNEA que
         escribe el plugin, y un estilo en línea gana a cualquier regla de hoja sin él.

       ⚠ LA CONDICIÓN ES QUE HAYA IFRAME MONTADO, no que Stripe haya cambiado el display
         —que ya no puede—. Es el mismo :has(iframe) con el que se decide el rótulo "Pago
         exprés" unos bloques más arriba, así que las dos piezas aparecen a la vez.

       ⚠ Y DEGRADA HACIA EL LADO SEGURO: un navegador sin :has() no entra en la segunda
         regla, así que el separador se queda invisible SIEMPRE. Se pierde el "— O —",
         que es un adorno; lo que nunca pasa es que salga anunciando unos botones que no
         existen. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > #wc-stripe-express-checkout-button-separator {
        display: block !important;
        visibility: hidden;
    }

    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout:has(#wc-stripe-express-checkout-element iframe) > #wc-stripe-express-checkout-button-separator {
        visibility: visible;
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — LAS DOS COLUMNAS, ARRANCANDO A LA MISMA ALTURA
   ═══════════════════════════════════════════════════════════════════════════
   "Datos de envío y facturación" y el panel "Tu pedido" tienen que empezar en la misma
   línea. Aquí están las DOS cosas que lo impedían, y solo la segunda era la que parecía.

   🔴 1 · EL CULPABLE DE VERDAD: UN ELEMENTO VACÍO E INVISIBLE QUE OCUPABA UNA FILA.
   ═══════════════════════════════════════════════════════════════════════════
   WooCommerce imprime la atribución del pedido en un elemento propio,
   <wc-order-attribution-inputs>, que por dentro solo lleva campos ocultos. Y desde que
   existe lo imprime en VARIOS sitios; uno de ellos es HERMANO DIRECTO del formulario y
   cae JUSTO ENTRE #customer_details y #order_review_heading:

       <div id="customer_details">…</div>
       <wc-order-attribution-inputs></wc-order-attribution-inputs>   ← aquí
       <h3 id="order_review_heading">Tu pedido</h3>
       <div id="order_review">…</div>

   No se ve —no tiene nada visible dentro— pero para la rejilla ES UN HIJO MÁS, y el
   suelo `form.checkout > *` de la línea 23000 le da LA FILA ENTERA, las dos columnas.

   👉 Y ahí está el daño, que no es el hueco de un elemento de altura cero: es que
      ROMPE LA COLOCACIÓN AUTOMÁTICA. Las filas de estos bloques no están escritas en
      ninguna parte —se dejaron en automático a propósito, para no depender de cuántas
      piezas traiga el pago exprés—, y el navegador las reparte con un cursor que avanza
      en el orden del marcado y NUNCA RETROCEDE. Al encontrarse este elemento a doble
      ancho después del formulario, el cursor tiene que bajar por debajo de las dos filas
      que ocupa #customer_details; y cuando llega el título "Tu pedido" ya no puede
      volver arriba: la columna derecha entera se coloca DEBAJO de la izquierda.

   👉 LA SOLUCIÓN ES QUITARLO DE LA REJILLA, no recolocar a los demás. Con display: none
      deja de ser un ítem, el cursor no lo ve, y el título y el resumen vuelven a la
      misma fila en la que empieza el formulario. Sin números de fila inventados: sigue
      mandando la colocación automática, que es lo que aguanta que el exprés traiga una
      pieza más o una menos.

   🔴 Y NO ROMPE LA ATRIBUCIÓN DEL PEDIDO, que es lo único delicado que hay aquí. Dentro
      solo hay <input type="hidden">, y un campo oculto SE ENVÍA IGUAL aunque su
      contenedor esté en display: none: lo que deja fuera de un envío es el atributo
      `disabled` o estar fuera del <form>, nunca el CSS. No se mueve ni un nodo —la
      lección del pago exprés (🪤 nº 19) vale también aquí—, solo se le quita la caja.

   ⚠ SE NOMBRA POR ETIQUETA Y COMO HIJO DIRECTO. Así alcanza a los que salen sueltos en
     el formulario aunque el plugin cambie sus ids, y NO toca los que van dentro de
     #customer_details, que ni son ítems de esta rejilla ni estorban a nadie.

   🔴 2 · EL PADDING DE ARRIBA DEL TÍTULO DE LA IZQUIERDA.
   ═══════════════════════════════════════════════════════════════════════════
   Astra le da a los encabezados del formulario `padding: 20px 0 14px`. Esos 20px de
   arriba no los tiene el panel de la derecha —su cabecera empieza en el borde de la
   caja—, así que aun con las dos columnas en la misma fila el título de la izquierda
   caía 20px por debajo del filo del panel. Se le quitan SOLO a ese título.

   ⚠ SOLO AL PRIMERO, y por eso el selector nombra a .woocommerce-billing-fields. El
     otro encabezado que vive en esta columna —"Dirección de envío", el que aparece al
     marcar la casilla— está en mitad del formulario y ahí esos 20px son el aire que le
     separa de los campos de arriba. Quitárselos también lo pegaría al bloque anterior.

   ⚠ HACE FALTA GANARLE A ASTRA POR ESPECIFICIDAD, no con !important: la suya es
     `#customer_details h3:not(…)` (1-1-2) y esta puntúa 1-3-2.

   ⚠ TODO DENTRO DE @media (min-width: 1025px): es donde existen las dos columnas. En
     móvil no hay rejilla, los bloques van uno detrás de otro y no hay nada que alinear,
     así que a 360px no cambia absolutamente nada.

   ⚠ NO SE TOCA EL REPARTO 58/42, NI EL align-items: start DEL FORMULARIO —que ya estaba
     y es el que mantiene a cada bloque a su altura natural—, ni una sola regla del
     panel de la derecha, ni Stripe.
   ═══════════════════════════════════════════════════════════════════════════ */

@media (min-width: 1025px) {

    /* 1 · Fuera de la rejilla el elemento de atribución que sale suelto en el
       formulario. Invisible ya era; lo que se le quita es la fila. */
    body.woocommerce-checkout:not(.woocommerce-order-received) form.checkout > wc-order-attribution-inputs {
        display: none;
    }

    /* 2 · El título de la columna izquierda, al filo de su columna, que es la misma
       altura a la que empieza el panel "Tu pedido". */
    body.woocommerce-checkout:not(.woocommerce-order-received) #customer_details .woocommerce-billing-fields > h3 {
        padding-top: 0;
    }
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — EL TÍTULO DEL PANEL "TU PEDIDO"
   ═══════════════════════════════════════════════════════════════════════════
   Centrado, en mayúsculas y en el negro de marca. Y la raya que lo separa de la tabla,
   en el mismo gris claro que las líneas entre productos.

   ⚠ ESTO ES PERMANENTE Y POR ESO VIVE FUERA DE LA CAJA DE PRUEBA que hay justo debajo.
     Antes estaba dentro, cuando el título era parte del experimento dorado; el día que
     se borre esa prueba, el centrado y las mayúsculas tienen que sobrevivir.

   ⚠ EL TEXTO DEL HTML NO SE TOCA: las mayúsculas las pone text-transform, así que el
     título sigue diciendo "Tu pedido" en el marcado y en el lector de pantalla.

   ⚠ EL !important SOLO EN `color`, Y NO ES PEREZA: woocommerce.css línea 299 declara
     `.woocommerce-checkout h3 { color: … !important }` y se imprime DESPUÉS de esta hoja.
     Es el mismo caso ya documentado un par de veces en esta zona. El centrado, las
     mayúsculas y el espaciado no tienen a nadie enfrente y van con reglas normales.

   ⚠ EL RESPALDO DEL NEGRO ES OBLIGATORIO: --ga-negro-suave está en la paleta pero NO se
     declara en el :root de style.css (🪤 nº 15). Sin el #1a1a14 de respaldo, `color` es
     heredada y el título se quedaría con el color del ancestro.

   ⚠ LA ALTURA DE ESTA CABECERA NO SE DECIDE AQUÍ, sino en la rejilla: ocupa una fila
     propia con align-self: start, así que mide lo que mide su contenido y NADA de la
     columna izquierda puede estirarla. Eso vive en el bloque del pago exprés, y allí está
     explicado por qué —tiene que ver con que Stripe carga tarde y antes arrastraba al
     panel—. Si algún día hay que revisar el alto de esta caja, el sitio es ese, no este.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
    /* Centrado en los dos ejes. Esta caja mide hoy lo que mide su texto —ocupa una fila
       propia de la rejilla y no se estira—, así que el centrado vertical no cambia nada
       en la práctica; se deja porque no cuesta y porque deja el título bien puesto si
       algún día la caja volviera a tener más alto que su contenido.

       ⚠ EL FLEX NO ROMPE NADA: dentro solo hay texto, así que pasa a ser una única caja
         anónima centrada. Ni el fondo, ni el borde de abajo, ni el padding cambian. */
    display: flex;
    align-items: center;
    justify-content: center;

    text-align: center;
    text-transform: uppercase;
    /* Las mayúsculas piden aire entre letras o se leen apelmazadas. */
    letter-spacing: 0.06em;
    /* La regla general de titulares aplica `balance`, que en un título de dos palabras no
       aporta nada y puede repartirlo raro (🪤 nº 16). */
    text-wrap: wrap;

    color: var(--ga-negro-suave, #1a1a14) !important;
}

/* ——— LA RAYA BAJO EL TÍTULO ———
   Esa línea no la pinta este tema: la fuerza woocommerce.css en la misma regla de los <h3>
   del checkout, con `border-bottom: 1px solid rgba(74, 74, 47, 0.1) !important`. Aquí solo
   se le cambia el COLOR para que sea idéntica a las que separan los productos, que son de
   WooCommerce y usan rgba(0, 0, 0, 0.1).

   ⚠ SE CAMBIA `border-bottom-color` Y NO EL ATAJO `border-bottom`: así el `1px solid`
     sigue siendo el suyo y no hay dos sitios declarando el grosor. Si un día WooCommerce
     lo cambiara a 2px, esta línea seguiría acompañando en vez de contradecirlo.

   ⚠ EL VALOR VA A PELO Y NO EN VARIABLE porque no existe ninguna de gris en la paleta, y
     el objetivo aquí es justamente igualar un valor ajeno, no traer un tono propio. */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
    border-bottom-color: rgba(0, 0, 0, 0.1) !important;
}


/* ═══════════════════════════════════════════════════════════════════════════
   CHECKOUT DE PAGO — LA BANDA DE MARCA DE ARRIBA
   ═══════════════════════════════════════════════════════════════════════════
   "GRAN ALMAZARA" en VERDE OSCURO de marca, centrado y enlazando a la tienda. El marcado
   lo imprime ga_checkout_banda_marca() en functions.php, colgado de
   woocommerce_before_checkout_form — o sea, FUERA del <form>, para no entrar en la
   rejilla de dos columnas ni descolocar el pago exprés.

   ⚠ AQUÍ HUBO UN ICONO DE TIENDA Y SE QUITÓ. La banda se queda solo con el nombre, y es
     el propio texto el que enlaza a la tienda: sigue siendo la vía de salida del pago,
     que es lo que había que conservar. Sin subrayado, para que se lea como el título de
     la pantalla y no como un enlace suelto.

   ⚠ EL VERDE ES --ga-verde-oliva-oscuro, el mismo de los botones "Ir a la tienda" del
     sitio. No hay ningún tono nuevo.

   🔴 EL BRILLO NO PUEDE SER EL DE LA CASA TAL CUAL, Y ESE ES EL PUNTO INTERESANTE DE ESTE
   BLOQUE. El barrido del resto del sitio lleva una banda casi blanca sobre dorado; sobre
   verde oscuro esa misma banda no se lee como brillo sino como una mancha clara cruzando
   las letras. Aquí el destello se consigue con TRANSPARENCIA en vez de con otro color: la
   franja central es el mismo verde rebajado de opacidad, así que las letras se aclaran un
   punto al pasar la luz y vuelven. El detalle completo está junto a la regla, más abajo.

   ⚠ SE REUTILIZAN LOS @keyframes ga-tienda-titulo-brillo de siempre (línea 9170). Lo único
     propio de esta banda es el degradado y la duración.

   ⚠ AQUÍ BASTA UNA CAPA DE FONDO, al contrario que en el título "TU PEDIDO". Aquel es un
     <h3> con color de fondo propio —el crema del panel— y hubo que montar dos capas para
     que el recorte contra el texto no se comiera también ese fondo. Este <span> no tiene
     fondo ninguno, así que un background-clip: text a secas es correcto y suficiente.

   ⚠ RESPALDO @supports OBLIGATORIO: la regla BASE deja el nombre en verde SÓLIDO y el
     recorte vive dentro del @supports. Un navegador que no lo entienda ve el nombre en
     verde normal, nunca invisible —que es el fallo clásico de esta técnica—.

   ⚠ Y prefers-reduced-motion VA DESPUÉS del @supports para ganarle por orden: retira la
     animación y el degradado y devuelve el relleno verde.

   ⚠ NINGÚN ESTADO MUEVE NADA. Al pasar el ratón solo baja la opacidad del grupo entero;
     ni tamaño, ni posición, ni grosor. Y se hace sobre el ENLACE y no sobre el texto,
     porque el texto va con el relleno transparente y un cambio de `color` ahí no se
     vería.

   ⚠ A 360px NO PUEDE DESBORDAR, y ahora con más margen que antes: al irse el icono, el
     nombre se queda solo en la banda. El cuerpo va con clamp() y en ese ancho cae a su
     mínimo (1,5rem), así que "GRAN ALMAZARA" ronda los 210px de los ~310 disponibles.
     Nada de min-width: el techo lo pone el max-width: 100% del enlace.
   ═══════════════════════════════════════════════════════════════════════════ */

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca {
    text-align: center;
    /* Aire cómodo hasta el pago exprés que viene debajo. */
    margin: 0 0 var(--ga-space-md);
}

/* El enlace ya no envuelve un icono y un texto, sino SOLO el nombre. Sigue siendo
   inline-flex para poder centrarlo y limitarlo al ancho disponible, pero sin gap ni
   wrap que repartir: dentro solo hay una pieza.

   ⚠ SIN SUBRAYADO, NI EN REPOSO NI EN NINGÚN ESTADO. Este enlace no se lee como un
     enlace: se lee como el título de la pantalla, y resulta que además lleva a la
     tienda. Subrayarlo lo convertiría en otra cosa. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__enlace {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    max-width: 100%;

    color: var(--ga-verde-oliva-oscuro);
    text-decoration: none;
    transition: opacity var(--ga-transition-normal);
}

/* Al pasar el ratón, SOLO opacidad: ni tamaño, ni posición, ni subrayado. Se hace sobre
   el enlace y no sobre el texto porque el texto lleva el relleno transparente del
   recorte, y ahí un cambio de `color` no se vería. */
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__enlace:hover,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__enlace:focus,
body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__enlace:focus-visible {
    color: var(--ga-verde-oliva-oscuro);
    text-decoration: none;
    opacity: 0.82;
}

body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__nombre {
    font-family: var(--ga-font-display);
    font-size: clamp(1.5rem, 5.5vw, 2.5rem);
    font-weight: var(--ga-weight-bold);
    line-height: 1.1;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    /* Las mayúsculas con espaciado dejan un hueco suelto tras la última letra; este
       margen negativo lo compensa para que el grupo quede centrado de verdad. */
    margin-right: -0.08em;

    /* FALLBACK: verde sólido para quien no soporte el recorte sobre texto. */
    color: var(--ga-verde-oliva-oscuro);
}

/* ——— EL BARRIDO, AHORA APENAS PERCEPTIBLE ———
   🔴 EL BRILLO DE LA CASA NO SIRVE TAL CUAL SOBRE VERDE, Y ESE ERA EL PROBLEMA A
   RESOLVER. El barrido del resto del sitio lleva una banda casi blanca (#F5EEDD) sobre
   dorado: sobre un verde oscuro, esa misma banda no se lee como un brillo sino como una
   mancha clara cruzando las letras, y ensucia la legibilidad justo en el nombre de la
   marca. Así que aquí el destello se consigue de otra forma.

   👉 SE ILUMINA CON TRANSPARENCIA, NO CON OTRO COLOR. La banda central es el MISMO verde
      rebajado de opacidad —rgba(74, 74, 47, 0.62)—. Como el degradado va recortado contra
      el texto, en esa franja las letras se vuelven algo translúcidas y dejan pasar el
      fondo de la página: se aclaran un punto y vuelven. Es un brillo de verdad, pero sin
      introducir ningún tono nuevo y sin ninguna mancha.

   ⚠ 74, 74, 47 ES --ga-verde-oliva-oscuro (#4a4a2f). Va en rgba porque una variable de
     color no se puede rebajar de opacidad dentro de un degradado sin reescribirla; es el
     mismo apaño que ya usa este archivo para las sombras de marca, y por eso queda
     anotado aquí de qué variable sale.

   ⚠ Y ADEMÁS SE HA SUAVIZADO EL RECORRIDO: la luz se reparte entre el 30 % y el 70 % —el
     doble de ancho que antes— y el bucle sube a 11s. Cuanto más ancha y más lenta, menos
     se percibe el paso y más se intuye. Que es lo pedido.

   ⚠ NUNCA DESAPARECE DEL TODO: 0,62 de opacidad es el punto más claro, así que en el peor
     momento las letras siguen leyéndose. Si aun así se quisiera más tenue todavía, ese
     0,62 sube hacia 1; si se quisiera un poco más de brillo, baja. Es el único número que
     hay que tocar.

   ⚠ EL RESPALDO @supports SIGUE SIENDO OBLIGATORIO: la regla base deja el nombre en verde
     SÓLIDO y todo el recorte vive aquí dentro. Quien no lo soporte ve el nombre normal,
     nunca invisible. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {

    body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__nombre {
        background-image: linear-gradient(
            110deg,
            var(--ga-verde-oliva-oscuro) 0%,
            var(--ga-verde-oliva-oscuro) 30%,
            rgba(74, 74, 47, 0.62) 50%,
            var(--ga-verde-oliva-oscuro) 70%,
            var(--ga-verde-oliva-oscuro) 100%
        );
        background-size: 250% 100%;
        background-repeat: no-repeat;
        background-position: 100% center;

        -webkit-background-clip: text;
        background-clip: text;
        -webkit-text-fill-color: transparent;
        color: transparent;

        animation: ga-tienda-titulo-brillo 11s linear infinite;
    }
}

/* Ahorro de movimiento: sin barrido. El nombre se queda en verde sólido, con su relleno
   restaurado. Va DESPUÉS del @supports para ganarle por orden de aparición. */
@media (prefers-reduced-motion: reduce) {

    body.woocommerce-checkout:not(.woocommerce-order-received) .ga-checkout-marca__nombre {
        animation: none;
        background-image: none;
        -webkit-text-fill-color: var(--ga-verde-oliva-oscuro);
        color: var(--ga-verde-oliva-oscuro);
    }
}


/* ╔═════════════════════════════════════════════════════════════════════════╗
   ║  PRUEBA COLOR DORADO COLUMNA DERECHA                                    ║
   ║                                                                         ║
   ║  🔴 BLOQUE DE PRUEBA. PARA REVERTIR: BORRAR DE ESTA CAJA HASTA EL FINAL  ║
   ║     DEL ARCHIVO. No hace falta tocar nada más.                          ║
   ╚═════════════════════════════════════════════════════════════════════════╝

   Toques del dorado de marca en el resumen "Tu pedido": marco del panel, borde de las
   miniaturas, el título y la fila del Total.

   🔴 POR QUÉ ESTÁ TODO AQUÍ ABAJO Y NO EDITADO EN SU SITIO. Es una prueba, y una prueba
   tiene que poder deshacerse de un tijeretazo. Ninguna de estas reglas modifica la regla
   original: la pisan desde el final del archivo, por orden de cascada con la MISMA
   especificidad. Al borrar el bloque, cada elemento vuelve solo a su color de antes sin
   que haya que recordar cuál era.

   ⚠ SOLO COLOR. Ni una medida, ni un grosor, ni un espaciado cambian aquí: los bordes
     que se añaden son de 1px, el mismo que ya tenían las miniaturas, y el marco del panel
     no mueve nada porque el reset del tema declara box-sizing: border-box (línea 38) y el
     borde se descuenta del ancho en vez de sumarse. A 360px no puede desbordar por esto.

   ⚠ NINGÚN ESTADO: no se declara hover, foco ni transición en todo el bloque.

   ⚠ TODO CON var(--ga-naranja-apagado), que es el dorado de marca (#c7a862). No hay
     ningún dorado nuevo inventado.
   ═══════════════════════════════════════════════════════════════════════════ */


/* ——— a · EL MARCO DEL PANEL ———
   🔴 SON DOS CAJAS HERMANAS, NO UNA, y por eso el marco se reparte. #order_review_heading
   y #order_review son dos elementos distintos pegados el uno al otro para que a la vista
   sean un solo panel (está explicado en su bloque, más arriba). Un borde completo en cada
   uno pintaría DOS líneas cruzando el panel por la mitad, justo por la costura.

   👉 El de arriba lleva borde por arriba y los costados; el de abajo, por los costados y
      abajo. Entre ellos no hay línea, así que se lee como un marco continuo. Los radios
      son los que ya tenía cada uno: no se tocan, el borde solo los sigue. */

/* 🔴 LOS !important DE ESTE SUB-BLOQUE NO SON PEREZA: SIN ELLOS EL MARCO NO SALE.
   Enfrente está assets/css/woocommerce.css línea 299, que se imprime DESPUÉS de esta hoja
   —declara 'gran-almazara-main' como dependencia— y dice:

       .woocommerce-checkout h3 {
           color: var(--ga-verde-oliva-oscuro) !important;
           border-bottom: 1px solid rgba(74, 74, 47, 0.1) !important;
       }

   #order_review_heading ES un <h3>, así que le entra de lleno. Con !important y
   cargándose después, para ganarle hacen falta las dos cosas: más especificidad Y
   !important. La suya puntúa 0-1-1; estas 1-2-1. */

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review_heading {
    border-top: 1px solid var(--ga-naranja-apagado) !important;
    border-right: 1px solid var(--ga-naranja-apagado) !important;
    border-left: 1px solid var(--ga-naranja-apagado) !important;
    /* El borde de ABAJO no se toca aquí: es la raya que separa el título de la tabla, y
       va en gris claro desde su propio bloque permanente, más arriba. */
}

body.woocommerce-checkout:not(.woocommerce-order-received) #order_review {
    border-right: 1px solid var(--ga-naranja-apagado) !important;
    border-bottom: 1px solid var(--ga-naranja-apagado) !important;
    border-left: 1px solid var(--ga-naranja-apagado) !important;
}


/* ——— b · LAS MINIATURAS SE QUEDAN COMO ESTABAN ———
   Aquí hubo un override que les ponía el borde dorado. SE HA RETIRADO, y con eso basta:
   al no haber regla que lo pise, las fotos vuelven solas al borde de su bloque original
   —1px solid var(--ga-amarillo-pastel)—, que es el gris cálido discreto que tienen que
   tener. Retirar el override ES la reversión: no se redeclara nada aquí, para no dejar
   dos sitios distintos diciendo de qué color va ese borde. */


/* ——— c · EL TÍTULO SE HA IDO DE ESTA CAJA ———
   🔴 EL TÍTULO YA NO ESTÁ AQUÍ. Se ha sacado de esta caja de prueba y vive ahora en su
   propio bloque permanente, unas líneas más arriba —"EL TÍTULO DEL PANEL"—, porque ha
   dejado de ser un experimento de color: va en NEGRO de marca, sin brillo. Aquí solo se
   deja la nota para que nadie lo busque en el sitio equivocado.

   ⚠ Y ESTAR FUERA DE LA CAJA ES LO CORRECTO: el centrado y las mayúsculas se quieren
     conservar aunque algún día se borre esta prueba. Dentro, se habrían ido con ella. */

/* La fila del Total vuelve al NEGRO de marca. Respaldo obligatorio: --ga-negro-suave no
   está declarada en el :root de style.css (🪤 nº 15). */
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .order-total th,
body.woocommerce-checkout:not(.woocommerce-order-received) #order_review .order-total td {
    color: var(--ga-negro-suave, #1a1a14);
}

/* ⚠ AQUÍ HABÍA UNA REGLA MÁS Y SE HA RETIRADO. Mientras el Total estuvo en dorado, la
   coletilla del IVA —el <small> que vive dentro de esa misma celda— lo heredaba, y hacía
   falta devolverla al negro para que no compitiera con la cifra. Ahora que el Total ya es
   negro, ese <small> hereda negro por su cuenta: la regla no pintaba nada y su comentario
   había dejado de ser cierto. (Su peso normal NO depende de esto: lo fija otra regla, en
   el bloque de la negrita de Subtotal y Total, y esa sigue en pie.) */

/* ═══════════ FIN DE LA PRUEBA COLOR DORADO COLUMNA DERECHA ═══════════ */
