@charset "UTF-8";
/*!
Theme Name: Sam Gold Framework
Theme URI: https://samgold.studio
Author: Sam Gold
Author URI: https://samgold.studio
Description: Professional WordPress framework for artist, brand and ecommerce websites. Built for speed, design precision and extensibility.
Version: 3.2.0
Requires at least: 6.3
Tested up to: 6.7
Requires PHP: 8.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: sgf
Tags: ecommerce, custom-logo, custom-menu, featured-images, full-width-template, theme-options, translation-ready

Sam Gold Framework, Copyright 2025 Sam Gold
Sam Gold Framework is distributed under the terms of the GNU GPL.
*/
/*--------------------------------------------------------------
>>> TABLE OF CONTENTS:
----------------------------------------------------------------
# Generic
	- Normalize
	- Box sizing
# Base
	- Typography
	- Elements
	- Links
	- Forms
## Layouts
# Components
	- Navigation
	- Posts and pages
	- Comments
	- Widgets
	- Media
	- Captions
	- Galleries
# plugins
	- Jetpack infinite scroll
# Utilities
	- Accessibility
	- Alignments

--------------------------------------------------------------*/
/* AQUÍ DENTRO NO SE EMITE CSS — 1 oct
   ===================================
   Este índice trae variables, breakpoints y mixins: cosas de Sass, que
   no escriben ni un byte en la hoja compilada. `tokens` NO está, y es a
   propósito: ese fichero sí escribe, un `:root{}` con los 142 tokens.

   Estaba aquí, y como `woocommerce.scss` también importa este índice
   —necesita las variables—, el bloque entero salía DOS veces, una en
   `style.css` y otra en `woocommerce.css`. El hijo, que compila igual,
   lo sacaba una tercera.

   Y el orden de carga es: style.css, el bloque del panel, la hoja del
   hijo, woocommerce.css. O sea que lo que el panel escribía lo
   machacaba woocommerce.css acto seguido, con los valores de fábrica,
   a igual especificidad y por llegar después.

   Eso explica por qué el panel no servía para nada: elegías 80px de
   alto de cabecera, se guardaba, se emitía correctamente, y 20 líneas
   más abajo otra hoja volvía a poner 72. No era un mando desconectado,
   era un mando al que le pisaban el cable.

   Los tokens los importa `style.scss`, una vez. Si algún día hace falta
   otro punto de entrada, que importe este índice y NO los tokens. */
/* EL TEXTO DE LEER NO ENCOGE. EL DE MIRAR, SI.
   ============================================
   Medido en un sitio de lujo que funciona (29 sep), comparando su
   version de escritorio con la de movil:

     display   62px -> 38px   (x0.61)
     titular   47px -> 34px   (x0.72)
     seccion   36px -> 28px   (x0.78)
     texto     17px -> 17px   (x1.00)
     pequeno   15px -> 15px   (x1.00)

   La regla no es "todo encoge un poco". Es que el texto de LECTURA
   es una constante —16px se leen igual en un movil que en un
   monitor— y lo unico que se adapta es el texto que esta ahi para
   mirarse. Y cuanto mas grande es, mas encoge: un titular de 64px
   en una pantalla de 375 no es grande, es una palabra por linea.

   De ahi que xs/sm/base/md/lg sigan fijos y solo los cuatro
   escalones de arriba lleven `clamp()`. El comentario de antes decia
   "sin clamp para que el catalogo no cambie de tamano": eso sigue
   siendo verdad, y por eso el catalogo usa base y sm, que no se
   tocan.

   El `vw` del medio esta calculado para que cada escalon llegue a su
   maximo justo a 1280px de ancho, que es donde empieza nuestro
   escritorio grande.

   Lo que NO cambia es el tracking ni el interlineado: van en `em` y
   sin unidad, asi que la proporcion se mantiene sola a cualquier
   tamano. Por eso el tracking se escribe en `em` y nunca en `px`. */
/* ESCALA EMPAREJADA: TAMANO + INTERLINEADO + TRACKING
   ===================================================
   Un cuerpo de letra no se elige solo. A cada tamano le corresponde
   un interlineado y un tracking, y las dos cosas van en sentido
   CONTRARIO al tamano:

     cuanto mas grande el texto  ->  menos interlineado y mas tracking
                                     negativo (letras mas juntas)

   El porque es optico, no estetico. A 62px el ojo ya no necesita
   tanto aire entre lineas para no perderse de renglon, y el espacio
   entre letras que a 14px hace falta para leer, a 62px se convierte
   en agujeros. Dejar el mismo tracking en toda la escala es lo que
   hace que un titular grande se vea "de plantilla": no esta mal
   dibujado, esta mal espaciado.

   Los valores salen de medir un sitio de lujo que funciona
   (29 sep): -0.045em a 62px, -0.03em a 36px, -0.013em a 15px, con el
   interlineado bajando de 1.57 a 1.15 en el mismo recorrido. Aqui
   esta la misma curva ajustada a nuestra escala.

   Se usan EMPAREJADOS. Si pones `--sgf-text-4xl`, pon tambien
   `--sgf-lead-4xl` y `--sgf-track-4xl`. Usar un tamano con el
   tracking de otro es exactamente el defecto que esto corrige. */
/* UN SOLO CANAL, 16px, EN TODAS LAS PANTALLAS — 29 sep
   ----------------------------------------------------
   Estaba en 48px en escritorio y 16 en movil. Dos valores para lo
   mismo, y el de escritorio dejaba las fotos encerradas en el centro
   de la pantalla.

   24px en escritorio, 16 de tablet para abajo. Lo que da sensacion
   de amplitud no es el aire de los lados, es que la imagen sea
   grande; el aire lateral solo la encoge. Pero pegado del todo al
   borde el contenido parece un descuido, asi que 24 en pantalla
   grande y 16 donde el ancho escasea.

   El escalon se da en 1023px, que es el corte de tablet que ya usa
   el tema en otros veintitantos sitios. Inventar un corte nuevo aqui
   seria una linea mas donde el diseno se parte sin que nadie sepa
   por que. */
/* EL HOVER TENÍA QUE NOTARSE, Y NO SE NOTABA — 1 oct
   ==================================================
   Esto solo movía el `border-color` de `--sgf-color-control` a
   `--sgf-color-text`. Un botón de 56px cuyo único cambio al pasar el
   ratón es el tono de una línea de 1px no está respondiendo: parece
   que no has llegado a él.

   Ahora además entra un lavado de fondo muy tenue, derivado del propio
   color de texto. Es el mismo gesto en toda la casa —aclarar o teñir
   un paso desde el color que ya tiene la pieza— y funciona sobre
   cualquier marca, porque sale de sus tokens y no de un gris elegido
   para el fondo blanco de fábrica.

   `6%` es poco a propósito: sobre un botón de contorno el protagonista
   sigue siendo el borde; el fondo solo confirma que lo estás apuntando. */
/* LA FLECHA DE UN CARRIL, UNA SOLA VEZ — 1 oct
   ============================================
   Había TRES flechas de carrusel en el tema —la de recomendados de la
   ficha, la de la historia de producto y la del cajón del carrito— con
   tres geometrías y tres aspectos:

       recomendados   48px   fondo surface   sin borde   círculo
       historia       40px   fondo bg        1px borde   círculo
       cajón          28px   sin fondo       sin borde   CUADRADA

   Hacen exactamente lo mismo: mover un carril un paso. La diferencia
   no la decidió nadie, la decidió el fichero donde cayó cada una. Y la
   de recomendados tenía el hover en `$sgf-gray-200`, un gris fijo de
   Sass, sobre una web de fondo crema.

   El tamaño sí es legítimo que cambie —una flecha de 40 dentro del
   cajón del carrito se come el ancho—, pero entonces se declara como
   tamaño, no se reinventa la pieza entera.

   El estado desactivado se apaga y NO se oculta: si desapareciera, la
   otra flecha saltaría de sitio justo cuando la estás pulsando. Esa
   razón estaba escrita dos veces, en dos ficheros; ahora está aquí.

   @param {Length} $lado  Lado del botón.
   @param {Length} $icono Lado del SVG de dentro. */
/* ESTADOS DE UN CAMPO, EN UN SOLO SITIO — 30 sep
   ==============================================
   `.sgf-input`, `.sgf-textarea` y `.sgf-select` repetian las mismas
   diez declaraciones y tenian los mismos dos estados: reposo y foco.
   Tres copias que hay que recordar cambiar a la vez.

   Aqui estan los seis estados que necesita un campo, una vez:

     hover          se puede escribir aqui
     focus-visible  estoy aqui con el teclado
     focus          estoy aqui (raton)
     error          esto hay que arreglarlo
     disabled       esto no se puede tocar
     readonly       esto se lee pero no se cambia

   Sobre el foco, que es donde estaba el fallo gordo: habia
   `outline: none` y solo cambiaba el borde. Quitar el contorno sin
   poner otro deja a quien navega con teclado sin saber donde esta, y
   el borde por si solo no basta porque ya cambia por otras razones.

   Ahora el contorno vuelve, pero SOLO en `:focus-visible`, o sea
   solo con teclado. Con raton se queda el cambio de borde, que es
   suficiente porque ya sabes donde has pulsado. */
/* ═══════════════════════════════════════════════════════════
   EL TITULAR DE UNA SECCIÓN
   ═══════════════════════════════════════════════════════════

   Una sección de página tiene un titular, y ese titular mide siempre
   lo mismo esté en la portada, en Nosotros o en Los viñedos. Suena
   obvio y no lo estaba: medido en el navegador, «Nuestros vinos» en
   la portada salía a 40,96px y «Nuestra historia» en Nosotros a 25,6.
   La misma pieza, dos tamaños, y el sitio parecía de dos personas.

   El motivo era que `.sgf-coleccion__heading` y
   `.sgf-pilares__heading` llevaban la escala escrita a mano —las dos,
   palabra por palabra, copiada la una de la otra— y
   `.sgf-home-section__title` no llevaba ninguna: heredaba el tamaño
   de `h1`/`h2` del texto corrido, que es otra cosa.

   Escrito aquí, el tamaño del titular de sección se decide una vez.
   Y como es un mixin y no una clase suelta, cada componente sigue
   poniendo lo suyo —el margen inferior, la alineación— sin tener que
   heredar decisiones que no son de su incumbencia.

   El `clamp` empieza en 28px y llega a 48: en un móvil un titular de
   48px parte en cuatro líneas y deja de ser un titular.
   ─────────────────────────────────────────────────────────── */
/* ─── Título de bloque de la ficha ───────────────────────────

   «Del elaborador», «Notas de cata», «Detalles del producto», «Perfil
   sensorial», «En nariz y boca». En la columna de compra todos esos son
   la misma cosa: el nombre de un bloque. Tienen que leerse como una sola
   escala o la columna parece montada por tres personas distintas.

   Existe porque pasó: el perfil sensorial nació con la clase del
   `eyebrow` —14px y en color de acento— y su rótulo interno en mono a
   10,5 y caja alta, mientras los acordeones de al lado iban a 16. Tres
   tamaños y tres familias para cinco rótulos que están uno debajo de
   otro.

   Escrito aquí se decide una vez. Cada componente sigue poniendo lo
   suyo —el margen, el gesto de abrir— que eso sí es de su incumbencia.
   ─────────────────────────────────────────────────────────── */
/* Los tokens se emiten AQUÍ y solo aquí. `abstracts/abstracts` ya no los
   trae: lo importan también otros puntos de entrada, y el bloque salía
   repetido en cada hoja, pisando lo que escribe el panel. */
:root {
  /* COLORES: DE ORIGEN Y DERIVADOS — 1 oct
     ======================================
     Los de ORIGEN son los que elige una marca y los que el panel
     guarda. Los DERIVADOS se calculan de ellos aquí, en el CSS.

     Antes se derivaban en Sass, al compilar, y de `$sgf-white` /
     `$sgf-black` fijos. O sea que no dependían del color del tema:
     dependían del color que tenía el framework el día que se
     escribieron. Cuando el tema hijo ponía su texto en `#1a1814`,
     `subtle`, `border-alt`, `tinte` y `accent-muted` se quedaban en
     blanco al 20% y había que reescribirlos a mano. De ahí los 17
     tokens clavados a pelo en el hijo: no era capricho, es que no
     había otra forma.

     Ya se tropezó con esto el 25 sep: `rgba(#ffffff, 0.2)`
     interpolaba el color y dejaba la función sin evaluar, así que
     llegaba `rgba(#ffffff, 0.2)` al CSS, que el navegador descarta.
     Se arregló la sintaxis —interpolar el resultado y no el
     argumento— pero no la dependencia, que era el problema de fondo.

     Ahora derivan en el navegador con `color-mix()`, de la variable y
     no de un literal. Cambiar `--sgf-color-text` arrastra a los
     suyos, venga del panel, del hijo o de un cliente futuro.

     Los valores no se mueven: con `bg: #ffffff`, `color-mix(in srgb,
     var(--sgf-color-bg) 20%, transparent)` da `rgba(255,255,255,.2)`,
     exactamente lo que había. Igual el tinte con `text: #111111`.

     `color-mix()` es la primera vez que se usa en el framework. Está
     en todos los navegadores desde mediados de 2023. */
  --sgf-color-bg: #ffffff;
  --sgf-color-bg-alt: #262626;
  --sgf-color-surface: #f7f7f7;
  --sgf-color-text: #111111;
  --sgf-color-muted: #707070;
  --sgf-color-border: #e5e5e5;
  --sgf-color-accent: #d24d1e;
  /* EL SUELO DEL COMERCIO — 1 oct
     =============================
     Las páginas de contar —portada, nosotros, viñedos, diario— y las
     de comprar —tienda y ficha— no hacen el mismo trabajo, así que no
     tienen por qué pisar el mismo suelo.

     Leyendo, el fondo cálido es la voz de la marca. Comprando, se
     compara: se mira una botella al lado de otra, se lee un precio,
     se decide. Ahí el fondo tiene que apartarse.

     Y hay un motivo medido, no de gusto: las fotos del catálogo están
     tiradas sobre un gris neutro —muestreé las esquinas: entre
     #dedad8 y #e4e4e3—, y un fondo CÁLIDO alrededor de una fotografía
     NEUTRA se pelea con ella. Por eso la tienda se veía apagada.

     Por defecto vale lo mismo que el fondo de página: un theme recién
     instalado no cambia en nada. Quien quiera separar los dos modos,
     lo pone en el panel. */
  --sgf-color-bg-tienda: var(--sgf-color-bg);
  /* LA SUPERFICIE OSCURA DE LA MARCA — 1 oct
     ========================================
     El pie, y la tira utilitaria cuando la cabecera se posa al
     desplazar. Son las dos puntas de la página, así que es un color y
     no dos: escribirlo en los dos sitios es cómo se separan después.

     `ink-fg` es lo que se escribe encima. Blanco sobre el granate de
     Junciera da 17,5:1, muy por encima del 4,5:1 que pide WCAG.

     Por defecto valen el fondo y el texto de siempre: un theme recién
     instalado conserva su pie claro y no se entera de que esto
     existe. */
  --sgf-color-ink: var(--sgf-color-bg);
  --sgf-color-ink-fg: var(--sgf-color-text);
  /* LA BARRA DE DESPLAZAMIENTO — 1 oct
     ==================================
     No estaba estilada en ningún sitio, así que salía la del sistema:
     gris, ancha y ajena a todo lo demás. En una web donde el fondo es
     crema y la tipografía es SangBleu, una barra gris de Windows se
     ve como una pieza de otra casa pegada en el borde.

     Sale del texto, no de un gris inventado: así hereda la
     temperatura de la marca —sobre crema tira a cálido, sobre el
     blanco roto de la tienda también— sin elegir un color nuevo.

     El carril va transparente. Pintarlo deja una franja permanente en
     el borde de la página; en reposo no hay nada que comunicar.

     Son dos y no cuatro: empecé poniendo también un ancho y un color
     de pulgar al pasar el ratón, y los dos se quedaron sin usar en
     cuanto medí que la única barra visible de la web es la del
     documento. Un token que nadie lee es el mismo peso muerto que
     borré de este fichero esta misma mañana. */
  --sgf-scroll-pulgar: color-mix(in srgb, var(--sgf-color-text) 26%, transparent);
  --sgf-scroll-carril: transparent;
  --sgf-color-subtle: color-mix(in srgb, var(--sgf-color-bg) 20%, transparent);
  --sgf-color-accent-fg: var(--sgf-color-bg);
  --sgf-color-tinte: color-mix(in srgb, var(--sgf-color-text) 5%, transparent);
  /* BORRADOS AQUÍ — 1 oct
     `--sgf-color-border-alt`, `--sgf-color-accent-muted` y
     `--sgf-color-surface-alt`: cero usos en el padre, en el hijo y en
     el plugin. Contados con grep sobre .scss/.css/.php/.js, validando
     antes el instrumento contra `--sgf-color-muted`, que da 287.
     Los tres salían de `$sgf-white`, así que sobre el fondo blanco del
     padre eran blanco sobre blanco. No se notaba porque nadie los
     leía. Si vuelve a hacer falta alguno, se deriva como los de
     arriba; restaurarlos tal cual es traer de vuelta un invisible. */
  /* ESTADOS, DE LA PALETA Y NO INVENTADOS AQUI — 30 sep
     ---------------------------------------------------
     Estos tres valian #4ade80, #facc15 y #f87171: claros, pensados
     para fondo oscuro. Este sitio tiene el fondo crema, y ahi:

       error   #f87171 sobre #f3eee4 -> 2,4:1
       exito   #4ade80 sobre #f3eee4 -> 1,5:1

     WCAG pide 4,5:1 para texto y 3:1 para un borde que comunica
     algo. O sea que el borde rojo de un campo mal rellenado en el
     pago casi no se distinguia del normal, justo donde mas falta
     hace que se vea.

     Lo revelador es que `_colors.scss` YA tenia los tres valores
     legibles y nadie los habia conectado: el token escribia encima.
     Quien se topo con ello en el checkout escribio un apaño local
     —«aqui hace falta el que se lee»— en vez de arreglar el token,
     asi que el problema seguia vivo en todos los demas sitios.

     Ahora el token ES la paleta. El apaño del checkout se queda:
     apunta al mismo color, asi que ya no hace nada, pero borrarlo es
     otra limpieza y no quiero tocar el pago de paso. */
  --sgf-color-success: #2e7d4f;
  --sgf-color-warning: #b26a00;
  --sgf-color-error: #c5361f;
  --sgf-color-info: #60a5fa;
  --sgf-font-display: Helvetica Neue, Helvetica, Arial, sans-serif;
  --sgf-font-body: Helvetica Neue, Helvetica, Arial, sans-serif;
  --sgf-font-mono: ui-monospace, SF Mono, Menlo, monospace;
  --sgf-text-xs: 12px;
  --sgf-text-sm: 14px;
  --sgf-text-base: 16px;
  --sgf-text-md: 16px;
  --sgf-text-lg: 20px;
  --sgf-text-xl: 24px;
  --sgf-text-2xl: 24px;
  --sgf-text-3xl: clamp(23px, 2.5vw, 32px);
  --sgf-text-4xl: clamp(28px, 3.125vw, 40px);
  --sgf-text-hero: clamp(34px, 3.75vw, 48px);
  --sgf-text-display: clamp(38px, 5vw, 64px);
  --sgf-lead-xs: 1.4;
  --sgf-lead-sm: 1.55;
  --sgf-lead-base: 1.5;
  --sgf-lead-md: 1.5;
  --sgf-lead-lg: 1.3;
  --sgf-lead-xl: 1.25;
  --sgf-lead-2xl: 1.25;
  --sgf-lead-3xl: 1.15;
  --sgf-lead-4xl: 1.1;
  --sgf-lead-hero: 1.08;
  --sgf-lead-display: 1.05;
  --sgf-track-xs: -0.02em;
  --sgf-track-sm: -0.02em;
  --sgf-track-base: -0.015em;
  --sgf-track-md: -0.015em;
  --sgf-track-lg: -0.025em;
  --sgf-track-xl: -0.025em;
  --sgf-track-2xl: -0.025em;
  --sgf-track-3xl: -0.03em;
  --sgf-track-4xl: -0.035em;
  --sgf-track-hero: -0.04em;
  --sgf-track-display: -0.045em;
  --sgf-leading-tight: 1.2;
  --sgf-leading-snug: 1.35;
  --sgf-leading-base: 1.5;
  --sgf-leading-loose: 1.6;
  --sgf-tracking-tight: -0.01em;
  --sgf-tracking-normal: 0;
  --sgf-tracking-wide: 0.02em;
  --sgf-tracking-wider: 0.06em;
  --sgf-tracking-widest: 0.12em;
  --sgf-space-1: 4px;
  --sgf-space-2: 8px;
  --sgf-space-3: 16px;
  --sgf-space-4: 24px;
  --sgf-space-5: 32px;
  --sgf-space-6: 40px;
  --sgf-space-7: 48px;
  --sgf-space-8: 56px;
  --sgf-space-9: 64px;
  --sgf-space-10: 72px;
  --sgf-space-11: 80px;
  --sgf-space-12: 96px;
  --sgf-space-16: 128px;
  --sgf-space-20: 160px;
  --sgf-space-24: 192px;
  --sgf-space-32: 256px;
  --sgf-gutter: 24px;
  /* El canal baja en tablet. Va en el token y no en cada
     componente: asi la cabecera, el pie, la tienda y las secciones
     se estrechan todas a la vez y en la misma vertical. Repartir
     este `@media` por los componentes es garantizar que uno se
     quede atras. */
}
@media (max-width: 1023px) {
  :root {
    --sgf-gutter: 16px;
  }
}
:root {
  --sgf-sidebar-width: 280px;
  --sgf-sidebar-gap: 48px;
  --sgf-grid-gap: 16px;
  --sgf-row-gap: 48px;
  --sgf-header-utility: 40px;
  --sgf-header-primary: 56px;
  /* Lo que ocupa la cabecera entera. Se calcula una vez: hasta
     ahora, quien necesitaba restarla escribia un 96 a mano y el dia
     que la cabecera cambie de alto se queda mintiendo.

     CON `var()`, QUE SI NO MENTÍA IGUAL — 1 oct
     -------------------------------------------
     Estaba interpolado desde las variables de Sass:
     `calc(40px + 56px)`, o sea
     `calc(40px + 56px)` escrito en la hoja. Un número fijo.

     Y el panel permite cambiar el alto de la tira de arriba: en
     Junciera está en 24px, así que la cabecera mide 80 y este token
     seguía diciendo 96. Dieciséis píxeles de error en el token que
     existe precisamente para que nadie escriba 96 a mano.

     Con `var()` se calcula en el navegador y sigue a lo que haya:
     al valor de fábrica, al del panel o al que ponga un hijo. */
  --sgf-header-total: calc(var(--sgf-header-utility) + var(--sgf-header-primary));
  /* EL AIRE ENTRE SECCIONES, UNA SOLA VEZ
     -------------------------------------
     Cada bloque de portada traia su propio `clamp`, y no todos el
     mismo: unos daban 96px fijos y otros 143 a 1585 de ancho.
     Medido en Los Vinedos: cuatro separaciones distintas entre
     secciones —211, 259, 296 y 307— en la misma pagina.

     Un ritmo no es «bastante aire»: es el MISMO aire. Cuando cada
     sección respira distinto, la página se lee como una pila de
     piezas en vez de como un documento. */
  --sgf-section-y: clamp(96px, 9vw, 192px);
  /* LA MEDIDA DE LECTURA
     --------------------
     Cuantos caracteres caben en una linea antes de que el ojo pierda
     el renglon al volver. Entre 45 y 75 es lo comodo; 62 es el medio.

     Hasta ahora vivia implicita: `.sgf-dos p` topaba en 54ch porque
     iba en una columna, y fuera de esa columna no topaba en nada. Un
     parrafo suelto en una pagina a 1.600 de ancho salia a 1.537px,
     unos 190 caracteres por linea. */
  --sgf-measure: 62ch;
  /* LA LETRA DEL MOBILIARIO
     -----------------------
     Cabecera, pie y banner no son contenido: son el marco. Tenian
     cada uno su tamano a pelo y ninguno pasaba por la escala.

     Medido antes de tocar nada: barra superior 12/500/interlinea 12,
     «Tienda» 16/500/24, «Buscar» 16/500/16, newsletter 16/400/22,4,
     pie 14/400/21. Cinco interlineas, dos pesos para el mismo papel
     y `letter-spacing: normal` en todo, saltandose los `--sgf-track-*`
     que el resto de la casa si respeta.

     La causa del 16 del nav es que los enlaces no estaban
     tipografiados: heredaban el cuerpo de la pagina. Los de al lado
     —«Buscar», «Cesta»— si tenian regla, y de ahi dos interlineas en
     la misma fila.

     Dos tamanos y un peso para todo el marco. Cambiarlos es cambiar
     estas tres lineas. */
  --sgf-chrome-size: var(--sgf-text-sm);
  --sgf-chrome-micro: var(--sgf-text-xs);
  --sgf-chrome-weight: 500;
  --sgf-header-promo: 56px;
  /* EL CONTORNO DE LOS CONTROLES — 1 oct
     ====================================
     WCAG 1.4.11 pide 3:1 al borde de un control: es lo único que dice
     dónde empieza y acaba un campo. Estaba muy por debajo.

     Medido sobre los dos fondos del proyecto:

         alfa    sobre crema (#f3eee4)   sobre blanco (padre)
         0.22        1,59                     1,63
         0.48        3,08  ok                 3,33  ok

     Se deriva del texto en vez de ser un gris fijo. Antes era
     `$sgf-gray-300`, un `#d6d6d6` pensado para fondo blanco: sobre el
     crema de un cliente, o sobre cualquier fondo que no fuera el de
     fábrica, el número volvía a caer sin que nadie se enterara.
     Derivado del texto, el contraste se sostiene lo cambie quien lo
     cambie, porque texto y fondo siempre se mueven juntos.

     El 48% es el mínimo con margen: 0,47 da 3,00 clavado, y un umbral
     que pasa por centésimas se cae con el primer cambio de beis.

     El panel lo sigue pudiendo pisar: si una marca necesita otro
     contorno, lo elige, y la responsabilidad del contraste pasa a ser
     suya. Lo que no puede es venir mal DE FÁBRICA. */
  --sgf-color-control: color-mix(in srgb, var(--sgf-color-text) 48%, transparent);
  --sgf-radius-pill: 999px;
  --sgf-container-xs: 480px;
  --sgf-container-sm: 640px;
  --sgf-container-md: 768px;
  --sgf-container-lg: 1024px;
  --sgf-container-xl: 1440px;
  --sgf-container-2xl: 1920px;
  --sgf-grid-columns: 12;
  --sgf-grid-gutter: 24px;
  /* PROPORCIONES: LA FOTO DE CATALOGO ES VERTICAL — 29 sep
     ------------------------------------------------------
     Medidas en un sitio de lujo que funciona: 0.82 (4:5), 0.71
     (5:7) y 0.58 (4:7). Ni una sola apaisada en sus rejillas.

     No es capricho. Una rejilla de fotos verticales se lee como una
     editorial de revista; la misma rejilla en apaisado se lee como
     un catalogo de piezas. El objeto no cambia: cambia el encuadre.

     `retrato` es la de diario: producto, tarjeta, tile.
     `alta` es la editorial, para cuando la foto tiene que mandar.
     `cuadrada` se queda para miniaturas y muestras de color, donde
     lo que importa es reconocer, no mirar. */
  --sgf-ratio-retrato: 4 / 5;
  --sgf-ratio-alta: 5 / 7;
  --sgf-ratio-cuadrada: 1 / 1;
  --sgf-radius-sm: 2px;
  /* La casilla tiene su propio radio y no reusa `radius-sm` (2px).
     Un control de 16px con 2px de radio se lee como un cuadrado con
     la esquina matada; para que se lea REDONDEADO hace falta cerca
     de un tercio del lado. Como es proporcion y no capricho, el dia
     que la casilla cambie de tamano hay que revisar esto. */
  --sgf-check-radius: 5px;
  /* EL RADIO DE LAS FOTOS DE CATÁLOGO — 1 oct
     ----------------------------------------
     Las tarjetas de producto llevaban un `border-radius: 8px` escrito
     a pelo en `_cards.scss`, y la tira de categorías llevaba un 0 con
     un comentario explicando que se ponía a 0 «porque las tarjetas
     están a 0». Las dos cosas a la vez no pueden ser ciertas: la
     tarjeta estaba a 8 y la tira a 0, y por eso no pegaban.

     El problema de fondo no era el número, era que no había ninguno:
     dos sitios decidiendo por su cuenta y un comentario describiendo
     un estado que ya no existía. Ahora hay un token, y quien quiera
     cambiar el redondeo de las fotos del catálogo lo cambia aquí y
     cambia en los dos sitios.

     No reusa `radius-md` (2px) porque esto no es un control: es una
     fotografía grande, y 2px en una foto de 300px no se ve. */
  --sgf-radius-foto: 8px;
  --sgf-radius-md: 2px;
  --sgf-radius-lg: 2px;
  --sgf-radius-xl: 2px;
  --sgf-radius-full: 999px;
  --sgf-z-raised: 10;
  --sgf-z-dropdown: 100;
  --sgf-z-sticky: 500;
  --sgf-z-overlay: 800;
  --sgf-z-modal: 900;
  --sgf-z-nav: 1000;
  --sgf-z-toast: 1100;
  --sgf-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --sgf-ease-out: cubic-bezier(0.16, 1, 0.3, 1);
  --sgf-ease-in: cubic-bezier(0.4, 0, 1, 1);
  --sgf-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --sgf-ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);
  --sgf-duration-fast: 120ms;
  --sgf-duration-ui: 180ms;
  --sgf-duration-base: 240ms;
  --sgf-duration-drawer: 280ms;
  --sgf-duration-slow: 480ms;
  --sgf-duration-slower: 800ms;
  --sgf-nav-height: 72px;
  /* La cabecera comparte canal con la pagina: si la nav respira 48
     y el contenido 16, el logo no cae sobre nada. */
  --sgf-nav-pad-x: 24px;
  --sgf-nav-pad-y: 24px;
  /* CABECERA: DOS TOKENS QUE EXISTÍAN Y NADIE LEÍA — 1 oct
     ======================================================
     `--sgf-nav-bg` y `--sgf-nav-color` tenían control en el panel,
     se guardaban en la base de datos, y cero usos en todo el CSS.
     Elegías el color de la cabecera, le dabas a guardar, se escribía
     en la página y no pasaba nada. El mismo defecto que la posición
     del pop-up: un mando que parece funcionar y está desconectado.

     `--sgf-nav-bg` valía `transparent`, que NO es lo que hace la
     cabecera: `layouts/_header.scss` pinta `var(--sgf-color-bg)`. Si
     se cablea dejando el token en `transparent`, la cabecera se queda
     sin fondo — el valor por defecto de una variable definida gana al
     fallback de `var()`, que solo entra si la variable NO existe.
     Así que el defecto por defecto es el fondo de la página, que es
     lo que se ve hoy.

     `--sgf-nav-color` no se usaba en ningún sitio porque cada pieza
     de la cabecera pedía `--sgf-color-text` por su cuenta. Ahora el
     color se pone una vez en `.sgf-site-header` y dentro se hereda.
     Por defecto es el texto del tema: mismo píxel que antes. */
  --sgf-nav-bg: var(--sgf-color-bg);
  --sgf-nav-color: var(--sgf-color-text);
}
@media (prefers-reduced-motion: reduce) {
  :root {
    --sgf-duration-fast: 0.01ms;
    --sgf-duration-ui: 0.01ms;
    --sgf-duration-base: 0.01ms;
    --sgf-duration-drawer: 0.01ms;
    --sgf-duration-slow: 0.01ms;
    --sgf-duration-slower: 0.01ms;
  }
}

/* LAS PÁGINAS DE COMPRAR PISAN OTRO SUELO
   =======================================
   Tienda, categorías de producto y ficha. No la cesta ni el pago: eso
   es otra conversación y no se amplía sin decirlo.

   OJO, ESTO NO ES OPCIONAL: UN DERIVADO SE CONGELA DONDE SE DECLARA.
   ------------------------------------------------------------------
   `--sgf-color-accent-fg: var(--sgf-color-bg)` declarado en `:root` se
   calcula ALLÍ y hereda ya resuelto. Cambiar `--sgf-color-bg` aquí
   abajo no lo recalcula: se quedaría con el beis de la raíz.

   Lo comprobé en el navegador con una sonda antes de escribir esto:
   con `--probe-derivado: var(--probe-base)` en `:root` y la base
   cambiada en `body`, el derivado seguía valiendo el de `:root` tanto
   en `body` como en sus nietos.

   Por eso los tres derivados se vuelven a declarar aquí. Si se olvida
   uno, el síntoma es sutil y feo: la cabecera o el texto de un botón
   se quedan beis sobre blanco roto, que es casi lo mismo pero no lo
   es, y se nota como suciedad sin saber de dónde viene. */
/* LAS PÁGINAS DE COMPRAR, TODAS — 1 oct
   =====================================
   La lista empezó con el catálogo y la ficha, que es donde se compara una
   botella con otra. Faltaban las cuatro que vienen después y hacen el mismo
   trabajo: el carrito, el pago, la entrada a la cuenta y el cambio de
   contraseña.

   Era visible: se recorría tienda → ficha → carrito y el suelo cambiaba de
   color a mitad de la compra, sin que nada en la página explicara por qué.
   Un cambio de fondo dentro de un mismo flujo se lee como «he salido de
   donde estaba».

   `woocommerce-account` cubre las tres de cuenta —entrar, recuperar
   contraseña y editarla—: WooCommerce se la pone a todas. */
body.woocommerce-shop,
body.tax-product_cat,
body.tax-product_tag,
body.single-product,
body.woocommerce-cart,
body.woocommerce-checkout,
body.woocommerce-account {
  --sgf-color-bg: var(--sgf-color-bg-tienda);
  --sgf-color-accent-fg: var(--sgf-color-bg-tienda);
  --sgf-color-subtle: color-mix(in srgb, var(--sgf-color-bg-tienda) 20%, transparent);
  --sgf-nav-bg: var(--sgf-color-bg-tienda);
}

/*--------------------------------------------------------------
# Generic
--------------------------------------------------------------*/
/* Normalize
--------------------------------------------- */
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
/* Document
	 ========================================================================== */
/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */
html {
  line-height: 1.15;
  -webkit-text-size-adjust: 100%;
}

/* Sections
	 ========================================================================== */
/**
 * Remove the margin in all browsers.
 */
body {
  margin: 0;
}

/**
 * Render the `main` element consistently in IE.
 */
main {
  display: block;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */
h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
	 ========================================================================== */
/**
 * 1. Add the correct box sizing in Firefox.
 * 2. Show the overflow in Edge and IE.
 */
hr {
  box-sizing: content-box;
  height: 0;
  overflow: visible;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */
pre {
  font-family: monospace, monospace;
  font-size: 1em;
}

/* Text-level semantics
	 ========================================================================== */
/**
 * Remove the gray background on active links in IE 10.
 */
a {
  background-color: transparent;
}

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */
abbr[title] {
  border-bottom: none;
  text-decoration: underline;
  text-decoration: underline dotted;
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */
b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */
code,
kbd,
samp {
  font-family: monospace, monospace;
  font-size: 1em;
}

/**
 * Add the correct font size in all browsers.
 */
small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */
sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Embedded content
	 ========================================================================== */
/**
 * Remove the border on images inside links in IE 10.
 */
img {
  border-style: none;
}

/* Forms
	 ========================================================================== */
/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */
button,
input,
optgroup,
select,
textarea {
  font-family: inherit;
  font-size: 100%;
  line-height: 1.15;
  margin: 0;
}

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */
button,
input {
  overflow: visible;
}

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */
button,
select {
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */
button,
[type=button],
[type=reset],
[type=submit] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */
button::-moz-focus-inner,
[type=button]::-moz-focus-inner,
[type=reset]::-moz-focus-inner,
[type=submit]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */
button:-moz-focusring,
[type=button]:-moz-focusring,
[type=reset]:-moz-focusring,
[type=submit]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */
fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * 1. Correct the text wrapping in Edge and IE.
 * 2. Correct the color inheritance from `fieldset` elements in IE.
 * 3. Remove the padding so developers are not caught out when they zero out
 *		`fieldset` elements in all browsers.
 */
legend {
  box-sizing: border-box;
  color: inherit;
  display: table;
  max-width: 100%;
  padding: 0;
  white-space: normal;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */
progress {
  vertical-align: baseline;
}

/**
 * Remove the default vertical scrollbar in IE 10+.
 */
textarea {
  overflow: auto;
}

/**
 * 1. Add the correct box sizing in IE 10.
 * 2. Remove the padding in IE 10.
 */
[type=checkbox],
[type=radio] {
  box-sizing: border-box;
  padding: 0;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */
[type=number]::-webkit-inner-spin-button,
[type=number]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */
[type=search] {
  -webkit-appearance: textfield;
  outline-offset: -2px;
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */
[type=search]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */
::-webkit-file-upload-button {
  -webkit-appearance: button;
  font: inherit;
}

/* Interactive
	 ========================================================================== */
/*
 * Add the correct display in Edge, IE 10+, and Firefox.
 */
details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */
summary {
  display: list-item;
}

/* Misc
	 ========================================================================== */
/**
 * Add the correct display in IE 10+.
 */
template {
  display: none;
}

/**
 * Add the correct display in IE 10.
 */
[hidden] {
  display: none;
}

/* Box sizing
--------------------------------------------- */
/* Inherit box-sizing to more easily change it's value on a component level.
@link http://css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice/ */
*,
*::before,
*::after {
  box-sizing: inherit;
}

html {
  box-sizing: border-box;
}

/*--------------------------------------------------------------
# Base
--------------------------------------------------------------*/
/* Typography
--------------------------------------------- */
body {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-base);
  line-height: 1.5;
  color: var(--sgf-color-text);
  background-color: var(--sgf-color-bg);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* ─── Titulares ──────────────────────────────────────────────
   Caja mixta. Peso medio-alto. Tracking ligeramente negativo solo
   en los tamaños grandes, que es donde se nota. */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--sgf-font-display);
  font-weight: 500;
  color: var(--sgf-color-text);
  text-wrap: balance;
  margin: 0 0 0.5em;
}

/* Cada nivel lleva SU interlineado y SU tracking, no uno comun.
   Antes todos compartian 1.2 y -0.01em, con dos parches sueltos en
   h1 y h2. El resultado: un h1 de 32px con el mismo espaciado de
   letra que un h6 de 16px, que es lo que hace que un titular grande
   se vea inflado en vez de compuesto. Ver variables/_typography.scss. */
h1 {
  font-size: var(--sgf-text-3xl);
  line-height: var(--sgf-lead-3xl);
  letter-spacing: var(--sgf-track-3xl);
}

h2 {
  font-size: var(--sgf-text-2xl);
  line-height: var(--sgf-lead-2xl);
  letter-spacing: var(--sgf-track-2xl);
}

h3 {
  font-size: var(--sgf-text-xl);
  line-height: var(--sgf-lead-xl);
  letter-spacing: var(--sgf-track-xl);
}

h4 {
  font-size: var(--sgf-text-lg);
  line-height: var(--sgf-lead-lg);
  letter-spacing: var(--sgf-track-lg);
}

h5 {
  font-size: var(--sgf-text-md);
  line-height: var(--sgf-lead-md);
  letter-spacing: var(--sgf-track-md);
}

h6 {
  font-size: var(--sgf-text-base);
  line-height: var(--sgf-lead-base);
  letter-spacing: var(--sgf-track-base);
}

p {
  margin: 0 0 1em;
  max-width: 68ch;
}

/* ─── Enlaces ────────────────────────────────────────────────
   Sin subrayado por defecto; el subrayado marca el enlace de acción
   secundaria («Buscar una tienda») y los enlaces dentro de texto. */
a {
  color: inherit;
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}

/* El subrayado se pide a mano con .sgf-link-underline, y se queda en
   el texto corrido: ahi un enlace sin subrayar es indistinguible de
   una palabra normal. En la cuenta y en las interfaces no hace falta. */
.sgf-link-underline,
.sgf-prose {
  max-width: var(--sgf-measure);
}

/* La entradilla de una SECCION no es un parrafo de libro.
   -------------------------------------------------------
   62ch es la medida de lectura para prosa corrida, donde el ojo tiene
   que volver al renglon siguiente decenas de veces. Una entradilla son
   dos parrafos que presentan lo que viene debajo, y con 62ch se queda
   en 552px de 1.537: una columna estrecha con media pantalla vacia al
   lado, que es justo lo que no queremos.

   Sigue habiendo tope —sin el, una linea seria de 190 caracteres y eso
   no lo lee nadie— pero mas holgado. */
.sgf-home-section > .sgf-prose {
  max-width: 88ch;
}

.sgf-prose p a {
  text-decoration: underline;
  text-underline-offset: 0.25em;
  text-decoration-thickness: 1px;
}

/* ─── Etiqueta de campaña ────────────────────────────────────
   El único sitio donde entra el acento en el catálogo:
   «Materiales reciclados», «Nuevo», «Última unidad». Caja mixta,
   mismo cuerpo que el título, en color. */
.sgf-eyebrow,
.sgf-label {
  display: block;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  font-weight: 500;
  letter-spacing: 0;
  text-transform: none;
  color: var(--sgf-color-accent);
  margin-bottom: var(--sgf-space-1);
}

/* Texto secundario: la línea gris bajo el nombre del producto. */
.sgf-subtle {
  color: var(--sgf-color-muted);
  font-size: var(--sgf-text-sm);
  font-weight: 400;
}

/* Dato numérico. Cifras tabulares para que los precios cuadren en
   columna, pero en la misma familia que el resto: la monoespaciada
   aquí rompería el registro. */
.sgf-data {
  font-variant-numeric: tabular-nums;
}

/* ─── Cita ───────────────────────────────────────────────────── */
/* Sin barra a la izquierda — 29 sep.
   El `padding-left` se va con ella: sin el borde eran 40px de
   sangrado sin causa, y la cita quedaba desplazada sin que nada
   explicara por que. Lo que marca que es una cita es el cuerpo y el
   color, no un adorno. */
blockquote {
  margin: var(--sgf-space-8) 0;
  font-size: var(--sgf-text-md);
  line-height: 1.5;
  color: var(--sgf-color-muted);
}

/* ─── Código ─────────────────────────────────────────────────── */
code, kbd, pre, samp {
  font-family: var(--sgf-font-mono);
  font-size: 0.9em;
}

pre {
  background: var(--sgf-color-surface);
  border: 1px solid var(--sgf-color-border);
  padding: var(--sgf-space-6);
  border-radius: var(--sgf-radius-md);
  overflow-x: auto;
}

code {
  background: var(--sgf-color-surface);
  padding: 0.15em 0.4em;
  border-radius: var(--sgf-radius-sm);
}

/* Elements
--------------------------------------------- */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
}

/* LA BARRA DE DESPLAZAMIENTO — 1 oct
   ==================================
   No estaba estilada en ningún sitio: salía la del sistema operativo.
   Gris, ancha y de otra casa.

   SE USAN LAS PROPIEDADES ESTÁNDAR, NO LOS PSEUDOELEMENTOS DE WEBKIT
   ------------------------------------------------------------------
   `scrollbar-width` y `scrollbar-color` son las del estándar y están
   en Firefox, en Chrome y en Safari. Hacen una cosa que
   `::-webkit-scrollbar` no hace: respetan la barra flotante del
   sistema, la que en macOS aparece al desplazar y se va sola.

   En cuanto se declara un `::-webkit-scrollbar` con ancho, Chrome
   abandona la barra flotante y pinta una clásica, permanente, que
   OCUPA SITIO: la página se estrecha unos diez píxeles y el contenido
   se recoloca. Se gana control sobre la forma del pulgar y se pierde
   que la barra desaparezca cuando no hace falta. No compensa en una
   web cuyo contenido es fotografía a sangre.

   El pulgar sale del color de texto del tema, así que en las páginas
   de contar es cálido como el crema y en la tienda acompaña al blanco
   roto, sin elegir un gris nuevo. El carril va transparente: en reposo
   no hay nada que comunicar y una franja permanente en el borde es
   ruido.

   Va en `html` y no en `*`: ponerlo en todo obliga a cada carrusel a
   volver a apagarla, y hay una docena que la esconden a propósito. */
html {
  scrollbar-width: thin;
  scrollbar-color: var(--sgf-scroll-pulgar) var(--sgf-scroll-carril);
}

/* SOLO LA DEL DOCUMENTO, Y NO ES PEREZA — 1 oct
   ---------------------------------------------
   Aquí había además un bloque con `::-webkit-scrollbar` para los
   paneles internos. Se borró después de mirar cuáles scrollean de
   verdad, y resultó que:

     .sgf-filter-sidebar--sticky   oculta su barra A PROPÓSITO, y lo
                                   explica: pegada al borde derecho de
                                   la columna lee como un separador
                                   entre los filtros y la rejilla
     .sgf-catalog-thumbs           carrusel, oculta
     .sgf-drawer-reco__list        carrusel, oculta

   Y las otras dos clases que había escrito —`.sgf-shop-layout__filters`
   y `.sgf-cart-drawer__body`— no existen en el marcado.

   O sea que la única barra que se ve en toda la web es la del
   documento. Un bloque para dar forma a barras que nadie enseña es
   código que no hace nada y que el día que alguien las enseñe hará
   algo que nadie decidió. */
body {
  margin: 0;
  min-height: 100vh;
  overflow-x: hidden;
}

img,
picture,
video,
canvas,
svg {
  display: block;
  max-width: 100%;
}

input,
button,
textarea,
select {
  font: inherit;
}

.sgf-site-content {
  min-height: 60vh;
  /* AL TOKEN, NO A UN BLANCO CLAVADO — 30 sep
     -----------------------------------------
     Estaba en `#fff`. El `body` si usa el token, asi que en una casa
     con fondo crema —como esta— el sitio entero era crema MENOS la
     franja del contenido, que se quedaba blanca. Se ve enseguida en
     una pagina larga: la cabecera es beis, el pie es beis y lo de en
     medio no.

     Solo pasaba en las paginas que pintan `.sgf-site-content` con
     contenido corriente. La portada no lo sufria porque va llena de
     bloques a sangre que tapan el fondo, y por eso llevaba semanas
     ahi sin que nadie lo viera. */
  background: var(--sgf-color-bg);
}

.sgf-site-main {
  padding-top: var(--sgf-nav-height);
}

.sgf-landing .sgf-site-main,
.home .sgf-site-main {
  padding-top: 0;
}

/* EL CONTENEDOR VIVE EN _grid.scss — 29 sep
   -----------------------------------------
   Aqui habia una SEGUNDA definicion de `.sgf-container`, con otro
   ancho (1920px) y otro canal. Las dos se compilaban, y mandaba la
   que quedara mas abajo en el CSS final: o sea, el orden de los
   `@use`. Un dia alguien reordena un import y el sitio entero cambia
   de ancho sin que nadie haya tocado un ancho.

   Un componente, un fichero. El contenedor y sus variantes estan en
   layouts/_grid.scss. */
/* EL PIE NO SE SUBE — 30 sep
   ==========================
   Medido en la pagina de cuenta a 1585x950: el `main` media 468px
   —solo lo que mide su contenido— asi que el pie empezaba en el
   pixel 666 y el formulario se quedaba pegado a la cabecera con
   media pantalla en blanco debajo.

   No se habia roto: nunca hubo `min-height` en el `main`. En una
   pagina larga no se nota; en el acceso, la cesta vacia, el 404 y el
   pedido recibido —que son cortas por naturaleza— se nota siempre.

   `svh` y no `vh`: en movil, `100vh` cuenta la barra de direcciones
   del navegador como si no existiera, asi que la pagina queda mas
   alta que la pantalla y aparece un scroll de unos pixeles que no
   lleva a ninguna parte. `svh` mide la ventana pequena, que es la
   que de verdad se ve. El `vh` de antes queda de respaldo para
   navegadores viejos.

   QUIEN SE LIBRA DE ESTO — 2 oct
   ------------------------------
   La cesta con productos lo anula en
   `plugins/woocommerce/_checkout.scss`: allí el carril de
   recomendados va fuera del `main`, así que el estirón de este
   `min-height` se cuela entre la cesta y el carril y lo echa de la
   primera vista. Si vuelves a tocar este alto, mira también allí. */
.sgf-site-main {
  min-height: calc(100vh - var(--sgf-header-total));
  min-height: calc(100svh - var(--sgf-header-total));
}

/* UN MODIFICADOR TIENE QUE PODER MODIFICAR — 30 sep
   -------------------------------------------------
   Esto valia `.sgf-container--narrow`, una sola clase, igual que
   `.sgf-container`. Empataban en especificidad y decidia el orden de
   los ficheros: gana `.sgf-container { max-width: 100% }`, que va en
   layouts y se carga despues.

   O sea que el modificador no modificaba nada. El Diario —lo unico
   del sitio que NO debe ir a todo lo ancho, porque es texto para
   leer— salia a 1.585px con la columna de lectura a 907 y el titular
   estirado sobre 1.537. Y el token que lo arreglaba, `--sgf-container-md`,
   llevaba ahi todo el tiempo sin que nadie lo leyera.

   Con las dos clases pesa (0,2,0) y gana siempre, sin depender de en
   que orden se importen las hojas. */
.sgf-container.sgf-container--narrow {
  max-width: var(--sgf-container-md);
}

hr {
  border: none;
  border-top: 1px solid var(--sgf-color-border);
  margin: var(--sgf-space-12) 0;
}

ul, ol {
  padding-left: var(--sgf-space-6);
  margin: 0 0 1.2em;
}

/* Los <li> no llevan margen de serie.
   Era un margen de texto corrido aplicado a TODO elemento de lista del
   sitio, y una lista es hoy casi siempre una interfaz —la navegacion,
   los filtros, las miniaturas de color, los pasos de un pedido— donde
   ese hueco descuadra separaciones puestas a proposito con `gap`.
   Donde haga falta espacio entre puntos de una lista de verdad, lo
   pone quien la escribe. */
.sgf-entry__content ul,
.sgf-entry__content ol {
  max-width: 68ch;
}

.sgf-entry__content li::marker {
  color: var(--sgf-color-muted);
}

dl {
  margin: 0 0 1.2em;
}

dt {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-sm);
  color: var(--sgf-color-muted);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
}

dd {
  margin: 0 0 var(--sgf-space-4) var(--sgf-space-4);
}

figure {
  margin: var(--sgf-space-8) 0;
}

figcaption {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  margin-top: var(--sgf-space-2);
  letter-spacing: var(--sgf-tracking-wide);
}

.sgf-ratio {
  position: relative;
  overflow: hidden;
}
.sgf-ratio img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sgf-ratio--square {
  aspect-ratio: 1/1;
}

.sgf-ratio--portrait {
  aspect-ratio: 3/4;
}

.sgf-ratio--landscape {
  aspect-ratio: 4/3;
}

.sgf-ratio--wide {
  aspect-ratio: 16/9;
}

.sgf-ratio--ultra {
  aspect-ratio: 21/9;
}

.sgf-entry__content table,
table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--sgf-text-sm);
  font-variant-numeric: tabular-nums;
}

th, td {
  padding: var(--sgf-space-3) var(--sgf-space-4);
  text-align: left;
  border-bottom: 1px solid var(--sgf-color-border);
}

th {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}

.sgf-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

/* Links
--------------------------------------------- */
/* SIN SUBRAYADO, TAMPOCO AL PASAR EL RATÓN — 1 oct
   ================================================
   Aquí había `&:hover { text-decoration: underline }` para todos los
   enlaces del sitio. La idea era confirmar que algo responde cuando lo
   apuntas; el resultado era que cada tarjeta, cada categoría del
   catálogo y cada botón que fuera un `<a>` se rayaba al pasar por
   encima. En una web de fotografía a sangre, una línea apareciendo y
   desapareciendo bajo cada cosa es ruido.

   La respuesta al ratón la dan ahora las piezas, cada una como le
   toca: los botones cambian de fondo, las tarjetas mueven la foto un
   2%, las filas del cajón adelantan su flecha. Eso dice «esto
   responde» sin rayar nada.

   LO QUE SÍ SE QUEDA, Y POR QUÉ
   -----------------------------
   Un enlace dentro de un párrafo. Ahí el color no vale: `a` hereda
   `color: inherit`, o sea que un enlace en medio de un texto se pinta
   exactamente igual que el texto. Sin subrayado no habría NADA que lo
   distinguiera, ni para quien lo ve ni para quien no distingue
   colores. Por eso la prosa conserva el suyo más abajo, y solo la
   prosa. */
a {
  color: inherit;
  text-decoration: none;
  text-underline-offset: 0.2em;
  transition: color var(--sgf-duration-fast) var(--sgf-ease);
}
a:focus-visible {
  outline: 2px solid var(--sgf-color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.sgf-skip-link {
  position: absolute;
  top: -100%;
  left: var(--sgf-space-4);
  z-index: var(--sgf-z-top);
  background: var(--sgf-color-accent);
  color: var(--sgf-color-accent-fg);
  padding: var(--sgf-space-3) var(--sgf-space-6);
  border-radius: var(--sgf-radius-md);
  font-size: var(--sgf-text-sm);
  font-weight: 600;
  text-decoration: none;
}
.sgf-skip-link:focus {
  top: var(--sgf-space-4);
}

/* Forms
--------------------------------------------- */
input[type=text],
input[type=email],
input[type=url],
input[type=password],
input[type=search],
input[type=tel],
input[type=number],
textarea,
select {
  display: block;
  width: 100%;
  padding: var(--sgf-space-3) var(--sgf-space-4);
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-sm);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-sm);
  line-height: 1.5;
  transition: border-color var(--sgf-duration-fast) var(--sgf-ease);
  -webkit-appearance: none;
}
input[type=text]::placeholder,
input[type=email]::placeholder,
input[type=url]::placeholder,
input[type=password]::placeholder,
input[type=search]::placeholder,
input[type=tel]::placeholder,
input[type=number]::placeholder,
textarea::placeholder,
select::placeholder {
  color: var(--sgf-color-muted);
}
input[type=text],
input[type=email],
input[type=url],
input[type=password],
input[type=search],
input[type=tel],
input[type=number],
textarea,
select {
  /* LOS ESTADOS VAN AQUI, EN EL SELECTOR DE ELEMENTO — 30 sep
     ---------------------------------------------------------
     Medido en la pagina de cuenta: un `<input type=email>` sin
     ninguna clase. El sistema tiene `.sgf-input` con sus estados,
     pero media web no la usa: los campos de WooCommerce, los de
     acceso y los de la caja son elementos pelados o llevan las
     clases de Woo.

     Poner los estados solo en el componente es pulir la parte del
     sistema que menos se usa. Aqui alcanzan a TODO campo del sitio,
     tenga la clase que tenga. */
}
input[type=text]:hover:not(:disabled):not([readonly]),
input[type=email]:hover:not(:disabled):not([readonly]),
input[type=url]:hover:not(:disabled):not([readonly]),
input[type=password]:hover:not(:disabled):not([readonly]),
input[type=search]:hover:not(:disabled):not([readonly]),
input[type=tel]:hover:not(:disabled):not([readonly]),
input[type=number]:hover:not(:disabled):not([readonly]),
textarea:hover:not(:disabled):not([readonly]),
select:hover:not(:disabled):not([readonly]) {
  border-color: var(--sgf-color-text);
}
input[type=text]:focus,
input[type=email]:focus,
input[type=url]:focus,
input[type=password]:focus,
input[type=search]:focus,
input[type=tel]:focus,
input[type=number]:focus,
textarea:focus,
select:focus {
  outline: none;
  border-color: var(--sgf-color-text);
}
input[type=text]:focus-visible,
input[type=email]:focus-visible,
input[type=url]:focus-visible,
input[type=password]:focus-visible,
input[type=search]:focus-visible,
input[type=tel]:focus-visible,
input[type=number]:focus-visible,
textarea:focus-visible,
select:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
input[type=text],
input[type=email],
input[type=url],
input[type=password],
input[type=search],
input[type=tel],
input[type=number],
textarea,
select {
  /* Por `aria-invalid`, que es el atributo que ya leen los lectores
     de pantalla. El aviso visual y el hablado salen del MISMO sitio:
     no hay forma de pintar el borde rojo y olvidarse de anunciarlo,
     ni al reves. */
}
input[type=text][aria-invalid=true],
input[type=email][aria-invalid=true],
input[type=url][aria-invalid=true],
input[type=password][aria-invalid=true],
input[type=search][aria-invalid=true],
input[type=tel][aria-invalid=true],
input[type=number][aria-invalid=true],
textarea[aria-invalid=true],
select[aria-invalid=true] {
  border-color: var(--sgf-color-error);
}
input[type=text][aria-invalid=true]:focus-visible,
input[type=email][aria-invalid=true]:focus-visible,
input[type=url][aria-invalid=true]:focus-visible,
input[type=password][aria-invalid=true]:focus-visible,
input[type=search][aria-invalid=true]:focus-visible,
input[type=tel][aria-invalid=true]:focus-visible,
input[type=number][aria-invalid=true]:focus-visible,
textarea[aria-invalid=true]:focus-visible,
select[aria-invalid=true]:focus-visible {
  outline-color: var(--sgf-color-error);
}
input[type=text]:disabled,
input[type=email]:disabled,
input[type=url]:disabled,
input[type=password]:disabled,
input[type=search]:disabled,
input[type=tel]:disabled,
input[type=number]:disabled,
textarea:disabled,
select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
input[type=text],
input[type=email],
input[type=url],
input[type=password],
input[type=search],
input[type=tel],
input[type=number],
textarea,
select {
  /* Solo lectura no es lo mismo que desactivado: el texto SE LEE
     —y se copia— asi que no se apaga. Lo que se quita es la
     invitacion a escribir. */
}
input[type=text][readonly],
input[type=email][readonly],
input[type=url][readonly],
input[type=password][readonly],
input[type=search][readonly],
input[type=tel][readonly],
input[type=number][readonly],
textarea[readonly],
select[readonly] {
  border-color: transparent;
  background: var(--sgf-color-bg-alt, var(--sgf-color-surface));
  cursor: default;
}

label {
  display: block;
  font-family: var(--sgf-font-body);
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--sgf-color-text);
  margin-bottom: var(--sgf-space-2);
}

/*--------------------------------------------------------------
# Layouts
--------------------------------------------------------------*/
.sgf-site-main {
  width: 100%;
}

.sgf-blog,
.sgf-archive,
.sgf-search {
  padding-block: var(--sgf-space-16);
}

.sgf-search--shop .sgf-page-title {
  font-weight: 400;
  letter-spacing: -0.03em;
}

.sgf-search__none {
  margin: var(--sgf-space-8) 0 0;
  color: var(--sgf-color-muted);
}

.sgf-single {
  padding-block: var(--sgf-space-16) var(--sgf-space-24);
}

.sgf-page {
  padding-block: var(--sgf-space-16) var(--sgf-space-24);
}

/* ...salvo cuando la pagina abre con un bloque que ya trae su propio
   aire. Este `padding-top` esta pensado para una pagina de prosa, que
   empieza con un parrafo y necesita separarse de la cabecera. Una
   pagina de bloques no: el primer bloque abre con `--sgf-section-y` y
   los dos se suman.

   `:has()` porque la condicion es del padre pero depende del hijo. Un
   navegador que no lo entienda se queda con el espaciado de antes, que
   es de mas, no de menos: degrada a feo, no a roto.

   LA CESTA Y EL PAGO QUEDAN FUERA — 1 oct
   ---------------------------------------
   El bloque de carrito de WooCommerce sale con `alignwide`, así que
   entraba por esa puerta y se quedaba sin el aire de arriba: el paso
   «1 Cesta» arrancaba pegado al logo, medido a 0px de padding cuando
   `_blocks.scss` pedía 48. Y pasaba sin avisar, porque el `:has()`
   le gana en especificidad a `.woocommerce-cart .sgf-site-main`.

   `alignwide` aquí no es un bloque de portada con su propio aire: es
   una tabla de productos. La regla es para páginas que ABREN con un
   bloque editorial, y la cesta no es una de ellas. */
body:not(.woocommerce-cart):not(.woocommerce-checkout) .sgf-page:has(> .sgf-container > .sgf-entry > .sgf-entry__content > :is(.sgf-home-section, .sgf-dos, .sgf-mosaico, .sgf-indice, .sgf-cifras, .alignfull, .alignwide):first-child) {
  padding-top: 0;
}

/* ─── Fila 1: utilitaria ─────────────────────────────────────── */
/* LA TIRA OSCURA, EN TODO EL SITIO — 1 oct
   ========================================
   Antes era `--sgf-color-surface` aquí y granate solo dentro de
   `body.has-transparent-header .sgf-site-header.is-scrolled`. O sea
   que el mismo elemento —la misma fila, con los mismos dos enlaces—
   era beis en la tienda, beis en el diario, beis en la portada sin
   desplazar y granate en la portada desplazada.

   Esa tira es lo primero que se ve de la casa y aparece igual en todas
   las páginas: no puede cambiar de color según dónde estés. Lo que
   cambia de color sin que lo hayas tocado parece roto.

   Sale del mismo token que el pie. Son las dos puntas de la página y
   siguen siendo el mismo color: un solo sitio donde cambiarlo.

   Y aquí se invierte el SUELO, no cada enlace. Los enlaces de esta
   tira piden `--sgf-nav-color` y el atenuado de los hermanos al pasar
   el ratón pide `--sgf-color-muted`: cambiando solo el fondo, el hover
   apagaría los enlaces a un gris que sobre granate no se ve.

   Por defecto `--sgf-color-ink` vale lo mismo que el fondo de página,
   así que un theme recién instalado sigue viendo su tira clara. */
.sgf-utility-bar {
  height: var(--sgf-header-utility);
  --sgf-nav-color: var(--sgf-color-ink-fg);
  --sgf-color-muted: color-mix(in srgb, var(--sgf-color-ink-fg) 62%, transparent);
  background: var(--sgf-color-ink);
  color: var(--sgf-color-ink-fg);
  /* Mismo canal que la nav de debajo y que el contenido: las dos
     filas de la cabecera y el cuerpo de la pagina empiezan en la
     misma vertical a cualquier ancho. */
}
.sgf-utility-bar__inner {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sgf-space-4);
  height: 100%;
  padding-inline: var(--sgf-gutter);
}
.sgf-utility-bar a {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-nav-color);
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sgf-utility-bar:has(a:hover) a {
    color: var(--sgf-color-muted);
  }
  .sgf-utility-bar:has(a:hover) a:hover {
    color: var(--sgf-nav-color);
  }
}
.sgf-utility-bar__sep {
  width: 1px;
  height: 12px;
  background: var(--sgf-color-border);
}
.sgf-utility-bar {
  /* En movil tambien se ve.
     Estaba oculta por debajo de 900px. Los cuatro enlaces no caben
     en 375px, asi que en vez de esconderlos la fila se desplaza a lo
     ancho: se ve que hay mas y se llega a ellos, que es mejor que
     no saber que existen. Cuerpo mas corto y alto mas bajo para que
     no le coma sitio a la navegacion. */
}
@media (max-width: 899px) {
  .sgf-utility-bar {
    height: 32px;
  }
  .sgf-utility-bar__inner {
    justify-content: flex-start;
    gap: var(--sgf-space-3);
    padding-inline: var(--sgf-space-3);
    overflow-x: auto;
    scrollbar-width: none;
  }
  .sgf-utility-bar__inner::-webkit-scrollbar {
    display: none;
  }
  .sgf-utility-bar a {
    white-space: nowrap;
  }
}

/* ─── Fila 2: navegacion principal ───────────────────────────── */
.sgf-site-header {
  position: sticky;
  top: 0;
  z-index: var(--sgf-z-nav);
  /* El fondo de la cabecera sale de su propio token, no del de la
     página. `--sgf-nav-bg` vale `var(--sgf-color-bg)` por defecto, así
     que esto pinta lo mismo que antes; la diferencia es que ahora el
     panel puede cambiarlo. Antes el mando existía y no llegaba aquí. */
  background: var(--sgf-nav-bg);
  color: var(--sgf-nav-color);
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}
@media (max-width: 1023px) {
  .sgf-site-header .sgf-nav__search {
    display: none;
  }
}

.sgf-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  height: var(--sgf-header-primary);
  max-width: none;
  margin: 0;
  /* EL CANAL DE LA CABECERA ES EL DE LA PAGINA — 29 sep
     ---------------------------------------------------
     Estuvo con su propio valor (24px) y su propio corte (899px)
     mientras el contenido usaba el token, que baja en 1023. Entre
     900 y 1023 el contenido entraba a 16 y la cabecera a 24: ocho
     pixeles de desfase en una franja entera de tablets, del tipo
     que se ve pero no se sabe señalar.

     Atado al token, el logo y el primer producto empiezan en la
     misma vertical a cualquier ancho, y el dia que se cambie el
     canal se cambia en un sitio. */
  padding-inline: var(--sgf-gutter);
}

/* La colocación del botón ya no se decide aquí: «Menú» y la lista van
   dentro de `.sgf-nav__left`, que es quien ocupa la celda y los
   separa. Esta regla lo ponía en la columna 1 Y lo escondía, y las dos
   cosas sobran. */
/* «Menú» y la lista comparten el lado izquierdo. El contenedor es lo
   que los separa, no un `padding` calculado contra el ancho del botón:
   ese número se queda viejo en cuanto cambie el texto o el idioma. */
.sgf-nav__left {
  grid-column: 1;
  grid-row: 1;
  justify-self: start;
  display: flex;
  align-items: center;
  gap: var(--sgf-space-6);
  min-width: 0;
}

.sgf-nav__primary {
  justify-self: start;
}

.sgf-nav__logo {
  grid-column: 2;
  grid-row: 1;
  justify-self: center;
  font-size: 18px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--sgf-nav-color);
}
.sgf-nav__logo img {
  display: block;
  max-height: 24px;
  width: auto;
}

.sgf-nav__actions {
  grid-column: 3;
  grid-row: 1;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: var(--sgf-space-8);
}

/* Los enlaces del menu entran AQUI, con las acciones.
   No tenian ninguna regla de letra: heredaban el cuerpo de la pagina
   —16px con interlinea 1,5— mientras sus vecinos de la misma fila
   declaraban 16 con interlinea 1. Dos interlineas en una sola fila,
   y ninguna de las dos elegida. */
/* Aqui NO se declara letra. La del menu y la de las acciones las pone
   el componente de navegacion, que es su sitio. Estaban declaradas en
   los dos ficheros con el mismo peso, asi que decidia el orden de
   carga: cuatro sitios distintos diciendo de que tamano es un enlace
   de la cabecera, y ninguno sabiendo de los otros tres.
   Esta regla se queda solo con lo que SI es de la cabecera: color,
   fondo y caja. */
.sgf-nav__site-name,
.sgf-nav__search,
.sgf-nav__cart,
.sgf-nav__wish,
.sgf-nav__ghost {
  color: var(--sgf-nav-color);
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}

.sgf-nav__ghost {
  cursor: default;
}

@media (hover: hover) and (pointer: fine) {
  .sgf-nav:has(a:hover) .sgf-nav__menu a,
  .sgf-nav:has(a:hover) .sgf-nav__ghost,
  .sgf-nav:has(a:hover) .sgf-nav__search,
  .sgf-nav:has(a:hover) .sgf-nav__cart,
  .sgf-nav:has(a:hover) .sgf-nav__wish,
  .sgf-nav:has(a:hover) .sgf-nav__site-name,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__menu a,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__ghost,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__search,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__cart,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__wish,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__site-name {
    color: var(--sgf-color-muted);
  }
  .sgf-nav:has(a:hover) a:hover,
  .sgf-nav:has(.sgf-nav__ghost:hover) .sgf-nav__ghost:hover {
    color: var(--sgf-nav-color);
  }
}
.sgf-nav__cart,
.sgf-nav__wish {
  display: inline-flex;
  align-items: baseline;
  gap: 0.35em;
  width: auto;
  height: auto;
  border-radius: 0;
}
.sgf-nav__cart svg,
.sgf-nav__wish svg {
  display: none;
}

.sgf-nav__cart-count {
  position: static;
  min-width: 0;
  height: auto;
  padding: 0;
  background: none;
  border-radius: 0;
  font-size: inherit;
  font-weight: inherit;
  font-variant-numeric: tabular-nums;
  color: inherit;
  opacity: 1;
  transform: none;
}
.sgf-nav__cart-count:empty, .sgf-nav__cart-count:not(.has-items) {
  display: none;
}

.sgf-nav-search {
  position: fixed;
  left: 0;
  right: 0;
  top: var(--sgf-search-top, var(--sgf-overlay-header, calc(var(--sgf-header-utility) + var(--sgf-header-primary))));
  z-index: calc(var(--sgf-z-nav) + 2);
  min-height: var(--sgf-header-promo);
  padding: 0 var(--sgf-gutter) var(--sgf-space-5);
  overflow-x: hidden;
  background: var(--sgf-color-bg);
  border-bottom: 1px solid var(--sgf-color-border);
  animation: sgf-search-in var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-nav-search__form {
  position: relative;
  min-width: 0;
  margin: 0;
}
.sgf-nav-search input[type=search].sgf-nav-search__input {
  display: block;
  width: 100%;
  height: var(--sgf-header-promo);
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  font-family: inherit;
  font-size: var(--sgf-text-lg);
  font-weight: 400;
  letter-spacing: -0.03em;
  line-height: var(--sgf-header-promo);
  color: var(--sgf-nav-color);
  caret-color: var(--sgf-nav-color);
}
.sgf-nav-search input[type=search].sgf-nav-search__input:focus {
  outline: none;
  border-color: transparent;
}
.sgf-nav-search input[type=search].sgf-nav-search__input::placeholder {
  color: var(--sgf-color-muted);
  letter-spacing: -0.02em;
  opacity: 0.55;
}
.sgf-nav-search input[type=search].sgf-nav-search__input::-webkit-search-decoration, .sgf-nav-search input[type=search].sgf-nav-search__input::-webkit-search-cancel-button {
  appearance: none;
}
.sgf-nav-search__hits {
  display: grid;
  grid-template-columns: repeat(8, minmax(0, 1fr));
  column-gap: var(--sgf-space-2);
  row-gap: var(--sgf-space-3);
  width: 100%;
  min-width: 0;
  max-height: min(70vh, 40rem);
  margin: var(--sgf-space-3) 0 0;
  padding: 0;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: var(--sgf-color-border) transparent;
}
.sgf-nav-search__hits::-webkit-scrollbar {
  width: 2px;
}
.sgf-nav-search__hits::-webkit-scrollbar-track {
  background: transparent;
}
.sgf-nav-search__hits::-webkit-scrollbar-thumb {
  background: var(--sgf-color-border);
  border-radius: 0;
}
@media (max-width: 1199px) {
  .sgf-nav-search__hits {
    grid-template-columns: repeat(6, minmax(0, 1fr));
  }
}
@media (max-width: 899px) {
  .sgf-nav-search__hits {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}
@media (max-width: 599px) {
  .sgf-nav-search__hits {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.sgf-nav-search__hit {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 0;
  color: inherit;
  text-decoration: none;
}
.sgf-nav-search__hit.is-active, .sgf-nav-search__hit:hover {
  color: inherit;
}
.sgf-nav-search__hit.is-active .sgf-nav-search__name, .sgf-nav-search__hit:hover .sgf-nav-search__name {
  color: var(--sgf-color-muted);
}
.sgf-nav-search__media {
  display: block;
  overflow: hidden;
  aspect-ratio: 4/5;
  margin: 0 0 var(--sgf-space-2);
  background: var(--sgf-color-surface);
  border-radius: 8px;
}
.sgf-nav-search__media img, .sgf-nav-search__ph {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sgf-nav-search__hit:hover img {
    transform: scale(1.02);
  }
}
.sgf-nav-search__copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.sgf-nav-search__name {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-nav-search__price {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  font-variant-numeric: tabular-nums;
}
.sgf-nav-search__empty {
  margin: var(--sgf-space-4) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
}
.sgf-nav-search__all {
  display: block;
  margin-top: var(--sgf-space-4);
  padding-top: var(--sgf-space-3);
  border-top: 1px solid var(--sgf-color-border);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
  text-decoration: none;
}
.sgf-nav-search__all:hover {
  color: var(--sgf-nav-color);
}
.sgf-nav-search__hits[hidden], .sgf-nav-search__empty[hidden], .sgf-nav-search__all[hidden] {
  display: none;
}
@media (max-width: 899px) {
  .sgf-nav-search {
    padding-inline: var(--sgf-space-3);
  }
}

@keyframes sgf-search-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
html.search-open .sgf-promo-bar {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

/* ─── Fila 3: barra promocional ──────────────────────────────── */
.sgf-promo-bar {
  min-height: var(--sgf-header-promo);
  padding-inline: var(--sgf-gutter);
  background: var(--sgf-color-bg);
  border-bottom: 1px solid var(--sgf-color-border);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  color: var(--sgf-nav-color);
  text-align: center;
}
.sgf-promo-bar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sgf-space-3);
  min-height: var(--sgf-header-promo);
  max-width: var(--sgf-container, 1280px);
  margin-inline: auto;
}
.sgf-promo-bar__track {
  flex: 1;
  min-width: 0;
  display: flex;
  justify-content: center;
}
.sgf-promo-bar__slide {
  margin: 0;
}
.sgf-promo-bar__slide a {
  text-decoration: underline;
  text-underline-offset: 0.25em;
  font-weight: 500;
}
.sgf-promo-bar__slide a:hover {
  color: var(--sgf-color-muted);
}
.sgf-promo-bar__nav {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--sgf-color-muted);
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out), background-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-promo-bar__nav svg {
  width: 16px;
  height: 16px;
}
.sgf-promo-bar__nav:hover {
  color: var(--sgf-nav-color);
  background: var(--sgf-color-surface);
}
@media (max-width: 599px) {
  .sgf-promo-bar__nav {
    display: none;
  }
}
@media (max-width: 599px) {
  .sgf-promo-bar {
    font-size: var(--sgf-chrome-micro);
    padding-inline: var(--sgf-space-3);
  }
}

/* ─── Hamburguesa ────────────────────────────────────────────── */
/* LA HAMBURGUESA TAMBIÉN EN ESCRITORIO — 1 oct
   ============================================
   Estaba `display: none` por encima de 1023px: el menú completo solo
   existía en el móvil. Pero lo que hay dentro del cajón —las
   categorías con su contador, las experiencias con su foto, las
   últimas del diario— no es menos útil en una pantalla grande; era
   simplemente que no había por dónde abrirlo.

   La lista de «Tienda · Mundo · Diario» se queda: es el acceso de un
   clic a lo de siempre. La hamburguesa es la puerta a todo lo demás.
   Dos caminos al mismo sitio no sobran cuando uno es corto y el otro
   es completo. */
.sgf-nav__toggle {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  display: inline-flex;
  align-items: center;
  /* Alto completo de la fila para que el objetivo táctil llegue a los
     44px aunque el texto mida 17. */
  min-height: 44px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--sgf-nav-color);
  cursor: pointer;
  transition: opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .sgf-nav__toggle:hover {
    opacity: 0.6;
  }
}

/* La X al abrir se iba sobre los tres `<span>` de la hamburguesa. Ya no
   hay spans: el botón es la palabra «Menú». Quien cierra es la barra de
   abajo del cajón, el overlay o el propio botón. */
/* AQUÍ HABÍA UN MENÚ MÓVIL ENTERO, Y ESTABA MUERTO — 1 oct
   ========================================================
   `.sgf-nav__overlay` estaba declarado DOS veces y como dos cosas
   distintas: en `components/navigation/_navigation.scss` es el velo
   oscuro que atenúa la página, y aquí era un panel deslizante opaco,
   con su propio fondo, su padding y sus enlaces a 20px. Una
   implementación anterior del menú del móvil que nadie llegó a
   retirar.

   Nunca se vio, y por un detalle: se activaba con `body.nav-open`, y
   el JS pone esa clase en `<html>`, no en `<body>`. El selector no ha
   casado jamás. Menos mal: si hubiera casado, al abrir el menú se
   habría desplegado un panel opaco tapando la página entera por
   debajo del cajón de verdad.

   Lo que sí hacía era dejar su `visibility: hidden` de base pegado al
   elemento, y eso tapaba el velo del otro fichero: el panel lateral
   de escritorio salía flotando sobre la página sin atenuarla.

   Se va entero. El velo se queda donde siempre estuvo. */
.sgf-site-header.is-hidden {
  transform: translateY(-100%);
}

@media (prefers-reduced-motion: reduce) {
  .sgf-site-header, .sgf-nav__overlay, .sgf-nav__toggle span,
  .sgf-nav__primary a, .sgf-nav__cart {
    transition: none;
  }
  .sgf-nav-search {
    animation: none;
  }
  .sgf-nav-search__hit img {
    transition: none;
  }
  .sgf-nav-search__hit:hover img {
    transform: none;
  }
}
.sgf-split-screen {
  padding-top: 0 !important;
}

.sgf-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 100vh;
}
@media (max-width: 767px) {
  .sgf-split {
    grid-template-columns: 1fr;
  }
}

.sgf-split__image {
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  background: var(--sgf-color-surface);
}
@media (max-width: 767px) {
  .sgf-split__image {
    position: relative;
    height: 60vw;
    min-height: 260px;
  }
}

.sgf-split__img,
.sgf-split__image-placeholder {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sgf-split__image-placeholder {
  background: var(--sgf-color-surface);
}

.sgf-split__content {
  display: flex;
  align-items: center;
  padding: var(--sgf-space-24) var(--sgf-space-12);
  min-height: 100vh;
}
@media (max-width: 1023px) {
  .sgf-split__content {
    padding: var(--sgf-space-16) var(--sgf-space-8);
    min-height: auto;
  }
}

.sgf-split__inner {
  max-width: 480px;
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-6);
}

.sgf-split__title {
  font-family: var(--sgf-font-display);
  font-size: clamp(var(--sgf-text-3xl), 4vw, var(--sgf-text-4xl));
  font-weight: 400;
  line-height: var(--sgf-leading-tight);
  letter-spacing: var(--sgf-tracking-tight);
  margin: 0;
}

.sgf-split__text {
  color: var(--sgf-color-muted);
  line-height: var(--sgf-leading-loose);
}

.sgf-site-main--landing {
  padding-top: 0;
}

.sgf-landing {
  position: relative;
  overflow: hidden;
}

#sgf-scene-root {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}

#sgf-scroll-container {
  position: relative;
  z-index: 1;
}

.sgf-hero {
  position: relative;
  width: 100%;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}

.sgf-hero__slit {
  position: absolute;
  left: 0;
  right: 0;
  height: 50%;
  background: var(--sgf-color-bg);
  z-index: 2;
  transform-origin: center;
}
.sgf-hero__slit--top {
  top: 0;
  transform-origin: top;
}
.sgf-hero__slit--bot {
  bottom: 0;
  transform-origin: bottom;
}

.sgf-hero__logo {
  position: absolute;
  z-index: 3;
  opacity: 0;
  will-change: transform, opacity;
}
.sgf-hero__logo img, .sgf-hero__logo svg {
  height: clamp(48px, 8vw, 96px);
  width: auto;
}

.sgf-hero__symbol {
  position: absolute;
  z-index: 1;
  opacity: 0;
  will-change: transform, opacity;
}

.sgf-hero__scroll-hint {
  position: absolute;
  bottom: var(--sgf-space-8);
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  opacity: 0;
}
.sgf-hero__scroll-hint span {
  display: block;
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}

.sgf-hero--editorial {
  align-items: stretch;
  justify-content: flex-start;
  color: var(--sgf-color-bg);
}

.sgf-hero--editorial .sgf-hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--sgf-color-text);
}

.sgf-hero--editorial .sgf-hero__image,
.sgf-hero--editorial .sgf-hero__video {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* EL FONDO DE YOUTUBE — 1 oct
   ---------------------------
   Un iframe no tiene `object-fit`: YouTube pinta su reproductor en
   16:9 y, si el hueco es más alto que ancho, mete bandas negras
   arriba y abajo. En un fondo a pantalla completa eso se ve como un
   fallo.

   Así que se recorta a mano: el iframe se hace tan grande como haga
   falta para tapar el marco por los dos lados —`177.77vh` es 16/9 de
   la altura, `56.25vw` es 9/16 de la anchura— y se centra. Lo que
   sobra se va fuera del `overflow: hidden`, que es exactamente lo que
   hace `cover`.

   El iframe va ENCIMA de la foto, que se queda debajo como respaldo:
   mientras YouTube carga, y para siempre si un bloqueador o una red
   corporativa lo tumban, lo que se ve es la fotografía y no un
   rectángulo negro.

   `pointer-events: none` porque esto es decorado: nadie debe poder
   pulsar el vídeo ni llegar a él con el tabulador. */
.sgf-hero--editorial .sgf-hero__yt {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}
.sgf-hero--editorial .sgf-hero__yt iframe {
  position: absolute;
  top: 50%;
  left: 50%;
  width: max(100%, 177.7778vh);
  height: max(100%, 56.25vw);
  border: 0;
  transform: translate(-50%, -50%);
}

/* TODO ABAJO, NO REPARTIDO — 29 sep
   ---------------------------------
   Estaba en `space-between`: el antetitulo se iba arriba del todo, el
   titular quedaba a media altura y el boton abajo. Sobre una foto eso
   es una loteria — en la portada el titular caia justo encima de las
   botellas y la "s" de "Vinos naturales" desaparecia contra la pared
   clara. El texto se colocaba donde sobraba sitio, no donde la foto
   estaba tranquila.

   Con `flex-end` los tres se agrupan abajo, que en una foto de bodegon
   es la zona limpia (el mantel), y ademas se leen como un bloque. El
   `gap` sustituye al reparto automatico: ahora el aire entre ellos lo
   decidimos nosotros y es el mismo siempre, mida lo que mida el hero. */
.sgf-hero--editorial .sgf-hero__copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: var(--sgf-space-5);
  width: 100%;
  height: 100%;
  padding-block: var(--sgf-space-12);
  padding-inline: var(--sgf-gutter);
}

/* UN VELO PARA QUE EL TEXTO SE LEA — 1 oct
   ========================================
   El texto del hero cae sobre una fotografía clara —mantel blanco,
   pared clara— y según la foto se perdía. El velo sube desde abajo, que
   es justo donde está el texto (`justify-content: flex-end`), y se
   desvanece antes de la mitad: la botella, que es el motivo, no se
   toca.

   SOLO EL HERO DE TONO CLARO, Y NO ES LO MISMO QUE «EL DE LA PORTADA»
   -------------------------------------------------------------------
   Esto pasó por dos sitios equivocados antes de caer aquí:

   1. `.sgf-hero--editorial` a secas: todos los heroes del sitio.
   2. `body.home .sgf-hero--editorial`: los de la portada. Pero la
      portada tiene DOS heroes editoriales —el bodegón de arriba y «El
      vino se hace solo» más abajo—, así que el velo caía igual en los
      dos.

   Las dos veces acoté por DÓNDE ESTÁ en vez de por QUÉ ES.

   La condición de verdad es el tono. `hero.php` pone
   `sgf-hero--light` cuando la foto es pálida, y entonces el texto va
   OSCURO: ahí el velo claro hace falta, porque el texto se pierde en
   los claros del mantel. El hero de tono oscuro lleva
   `color: var(--sgf-color-bg)`, texto claro sobre foto oscura; ahí un
   velo pálido no es que sobre, es que estorba —mete claro justo detrás
   de texto claro—.

   Así se mantiene solo: cualquier hero claro que se monte mañana lo
   hereda, y ninguno oscuro lo recibe por accidente.

   El color sale del fondo alterno del tema y no de un hex suelto, así
   que acompaña a la marca: si alguien cambia el beis, el velo va
   detrás. */
.sgf-hero--editorial.sgf-hero--light .sgf-hero__copy {
  background: linear-gradient(to top, var(--sgf-color-bg-alt) 0%, color-mix(in srgb, var(--sgf-color-bg-alt) 0%, transparent) 43%);
}
@media (max-width: 767px) {
  .sgf-hero--editorial.sgf-hero--light .sgf-hero__copy {
    padding-block: var(--sgf-space-9);
  }
}

.sgf-hero--editorial .sgf-hero__title {
  max-width: 12ch;
  margin: 0;
  font-size: var(--sgf-text-hero);
  font-weight: 500;
  letter-spacing: var(--sgf-track-hero);
  line-height: var(--sgf-lead-hero);
  color: var(--sgf-color-bg);
}

.sgf-hero--editorial .sgf-hero__foot {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--sgf-space-4);
}

.sgf-hero--editorial .sgf-hero__lede {
  margin: 0;
  max-width: 36ch;
  font-size: var(--sgf-text-sm);
  font-weight: 400;
  line-height: 1.4;
  color: var(--sgf-color-bg);
}

.sgf-hero--editorial.sgf-hero--light {
  color: var(--sgf-color-text);
}
.sgf-hero--editorial.sgf-hero--light .sgf-hero__title,
.sgf-hero--editorial.sgf-hero--light .sgf-hero__lede {
  color: inherit;
}

.sgf-home-section {
  padding-block: var(--sgf-section-y);
  padding-inline: var(--sgf-gutter);
}
@media (max-width: 767px) {
  .sgf-home-section {
    padding-block: var(--sgf-space-9);
    padding-inline: var(--sgf-space-3);
  }
}

.sgf-home-section__title {
  /* EL MISMO TAMAÑO QUE EN LA PORTADA — 1 oct
     ----------------------------------------
     Esto solo ponía el margen, así que el titular se quedaba con el
     tamaño que `h1`/`h2` tienen para el texto corrido: 25,6px frente
     a los 40,96 de «Nuestros vinos» en la portada. Medido en las dos
     páginas. Es el mismo elemento —el titular de una sección— y no
     hay ninguna razón para que mida distinto según en qué página
     caiga. */
  font-family: var(--sgf-font-display);
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-weight: 400;
  line-height: var(--sgf-lead-4xl);
  letter-spacing: var(--sgf-track-4xl);
  color: var(--sgf-color-text);
  margin: 0 0 var(--sgf-space-5);
}

/* FILA DE BALDOSAS EN CARRIL
   ==========================
   Una fila de fotos crece: hoy son tres, manana seis. En reticula, la
   sexta obliga a elegir entre apretar las seis en el mismo ancho o
   partirlas en dos filas de tres, y las dos opciones cambian el
   significado —en la primera las fotos se hacen pequenas, en la
   segunda parece que hay dos grupos—. En carril no: entran las que
   entren y las demas esperan a la derecha.

   Cuantas se ven lo sigue mandando `columnas`, el mismo ajuste de
   antes. Lo que cambia es que ahora es «cuantas se ven a la vez» en
   vez de «cuantas caben en total».

   El decimal de mas (2,3 y no 2) es lo que deja asomar un trozo de la
   siguiente. Sin el, el borde derecho coincide con el final y la tira
   parece una reticula: nadie adivina que hay mas.

   `$hueco` es `--sgf-space-4` y no el `--sgf-grid-gap` por defecto del
   mixin, porque en reticula esta fila usa `sgf-grid--gap-sm`, que son
   24px. Con el valor por defecto el carril tendria 16 y el mismo
   bloque cambiaria de hueco al cambiar de forma.

   EL ASOMO SOLO CUANDO HAY ALGO QUE ASOMAR
   ----------------------------------------
   El decimal encoge las piezas para dejar ver un trozo de la
   siguiente. Si no hay siguiente, encoge igual y deja un hueco muerto:
   medido en el catalogo, tres fotos con `columnas: 3` salian a 471px
   en 1.585 y sobraban 124px a la derecha, sin scroll. O sea el precio
   de una pista y ninguna pista.

   Asi que el decimal se pone solo cuando existe la pieza que sobra.
   `:has(> :nth-child(4))` es literalmente «hay una cuarta»; sin ella,
   las tres llenan el ancho y la tira se comporta como la fila de antes.

   EL CANAL, EN UNA VARIABLE
   -------------------------
   El relleno lateral y el calculo del ancho TIENEN que usar el mismo
   numero: si el relleno es 24 y el calculo resta 0, las piezas se
   salen; al reves, se quedan cortas. Estaban en dos sitios y ya se
   habian desincronizado —a sangre, el carril se comia los 24 del
   canal y la primera foto nacia pegada al borde de la pantalla, justo
   el borde que comparte toda la pagina—. Con una variable no pueden
   discrepar: a sangre vale el canal, dentro del contenedor vale cero
   porque el contenedor ya lo puso. */
.sgf-tile-row--carril {
  --carril-canal: 0px;
}
.sgf-tile-row--carril.alignfull {
  --carril-canal: var(--sgf-gutter);
}
.sgf-tile-row--carril {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--sgf-space-4);
  margin: 0;
  padding-inline: var(--carril-canal);
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--carril-canal);
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sgf-tile-row--carril::-webkit-scrollbar {
  display: none;
}
.sgf-tile-row--carril > * {
  flex: 0 0 calc((100% - var(--sgf-space-4) * (1 - 1)) / 1);
  scroll-snap-align: start;
  min-width: 0;
  margin: 0;
  list-style: none;
}
.sgf-tile-row--carril {
  /* Cerrados por arriba, por lo mismo que los pilares: `:has()` suma
     especificidad y la regla de movil le ganaria a la de escritorio a
     cualquier ancho. En escritorio no llegaba a verse porque las
     reglas de 1024 llevan `.sgf-tile-row--N` y pesan igual, pero en
     el tramo de tablet si mandaba la de movil. */
}
@media (max-width: 639px) {
  .sgf-tile-row--carril:has(> :nth-child(2)) > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (1.15 - 1)) / 1.15);
  }
}
@media (min-width: 640px) and (max-width: 1023px) {
  .sgf-tile-row--carril > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (2 - 1)) / 2);
  }
  .sgf-tile-row--carril:has(> :nth-child(3)) > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (2.3 - 1)) / 2.3);
  }
}
@media (min-width: 1024px) {
  .sgf-tile-row--carril.sgf-tile-row--2 > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (2 - 1)) / 2);
  }
  .sgf-tile-row--carril.sgf-tile-row--3 > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (3 - 1)) / 3);
  }
  .sgf-tile-row--carril.sgf-tile-row--4 > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (4 - 1)) / 4);
  }
  .sgf-tile-row--carril.sgf-tile-row--2:has(> :nth-child(3)) > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (2.25 - 1)) / 2.25);
  }
  .sgf-tile-row--carril.sgf-tile-row--3:has(> :nth-child(4)) > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (3.25 - 1)) / 3.25);
  }
  .sgf-tile-row--carril.sgf-tile-row--4:has(> :nth-child(5)) > * {
    flex-basis: calc((100% - var(--sgf-space-4) * (4.3 - 1)) / 4.3);
  }
}

/* CARRIL DE PRODUCTO
   ==================
   El bloque se llama «Carril de producto» desde que nacio y nunca fue
   un carril: pintaba `.products` a secas, o sea la rejilla de la
   tienda —tres columnas—, asi que con cuatro fichas la cuarta caia
   sola en una segunda fila y la seccion medida daba 1.356px, mas alta
   que la pantalla. Es el tercero de los tres bloques de fila; los
   otros dos se arreglaron hoy y este se habia quedado.

   Se apunta con DOS clases para ganarle a `.products` por
   especificidad y no por orden de carga.

   `$canal: 0` porque el carril cae en la lista y el canal ya lo puso
   la seccion que la envuelve. */
.sgf-product-rail--carril .products {
  display: flex;
  flex-wrap: nowrap;
  gap: var(--sgf-grid-gap);
  margin: 0;
  padding-inline: 0px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 0px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sgf-product-rail--carril .products::-webkit-scrollbar {
  display: none;
}
.sgf-product-rail--carril .products > * {
  flex: 0 0 calc((100% - var(--sgf-grid-gap) * (1.15 - 1)) / 1.15);
  scroll-snap-align: start;
  min-width: 0;
  margin: 0;
  list-style: none;
}
@media (min-width: 640px) and (max-width: 1023px) {
  .sgf-product-rail--carril .products > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (2.3 - 1)) / 2.3);
  }
}
@media (min-width: 1024px) {
  .sgf-product-rail--carril .products {
    /* Tres enteras cuando caben tres; el cuarto de ficha de mas
       solo aparece si hay una cuarta que asomar. Sin esto, tres
       productos se encogen para dejar sitio a un asomo que no
       existe. */
  }
  .sgf-product-rail--carril .products > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (3 - 1)) / 3);
  }
  .sgf-product-rail--carril .products:has(> :nth-child(4)) > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (3.25 - 1)) / 3.25);
  }
}

.sgf-tile {
  position: relative;
  display: block;
  min-width: 0;
  color: var(--sgf-color-text);
}

.sgf-tile:has(.sgf-tile__image) {
  color: var(--sgf-color-bg);
}

.sgf-tile__media {
  overflow: hidden;
  background: var(--sgf-color-surface);
  border-radius: 8px;
}

/* EL 4:5 ES DE LA BALDOSA, NO DE LA CLASE — 30 sep
   ================================================
   Estuvo apaisada (4/3). En una rejilla editorial la apaisada aplana:
   todas las piezas parecen la misma foto recortada. Asi que vertical
   —pero vertical EN UNA BALDOSA, que mide unos 300px de ancho.

   El ratio estaba en `.sgf-tile__media` a secas, y esa clase la usan
   tambien la escena, la foto de una rejilla 60-40 y la foto suelta a
   sangre, donde la caja mide 900 o 1.500. Un 4:5 a 898px son 1.123 de
   alto: mas que la pantalla, y ademas recorta casi la mitad del ancho
   de una foto apaisada.

   Ya se habia parcheado dos veces —primero para `.alignfull`, luego
   para `> figure`— y las dos veces por donde estaba la foto, no por
   que la estiraba. El propio comentario de aquel arreglo lo dice:
   «una proporcion no es buena o mala: depende del ancho al que se
   aplique». Pero el selector seguia mirando la alineacion, asi que
   cada contexto nuevo volvia a romperse. Medido hoy en «Nosotros»:
   la foto del camino, apaisada de origen, salia vertical a 1.123px.

   Aqui se dice de quien es el ratio: de la baldosa. Fuera de una
   baldosa, la foto vale lo que valga su original. */
.sgf-tile .sgf-tile__media {
  aspect-ratio: var(--sgf-ratio-retrato);
}

.sgf-tile__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.sgf-tile__copy {
  position: absolute;
  left: var(--sgf-space-4);
  bottom: var(--sgf-space-4);
  right: var(--sgf-space-4);
}

.sgf-tile__title {
  margin: 0;
  font-size: var(--sgf-text-xl);
  font-weight: 500;
  color: inherit;
}

.sgf-tile__tags {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sgf-space-2);
  margin: var(--sgf-space-1) 0 0;
  font-size: var(--sgf-text-sm);
  color: inherit;
}

.sgf-landing__content > .sgf-hero--editorial {
  width: 100%;
}

/* -----------------------------------------------
   LOS TRES CUERPOS DE TEXTO DE UNA SECCION — 29 sep

   Habia discrepancias medidas en la portada: el pie del manifiesto a
   14px y la entrada de la coleccion a 16px, cuando los dos hacen lo
   MISMO —acompañar a un titular de seccion—. Pasaba por elegir el
   token a ojo en cada bloque.

   A partir de aqui, tres papeles y tres tokens. Sin excepciones:

     ANTETITULO / ETIQUETA ...... --sgf-text-xs   (12px)
     APOYO DE UNA SECCION ....... --sgf-text-base (16px), lh 1.75
     CUERPO DE UNA TARJETA ...... --sgf-text-sm   (14px), lh 1.7

   La tarjeta va mas pequeña a proposito y no es una incoherencia: es
   un contexto menor dentro de una reticula, y compite con su foto. Lo
   que no puede pasar es que dos parrafos con el mismo papel midan
   distinto.
   ----------------------------------------------- */
/* -----------------------------------------------
   MANIFIESTO — 29 sep

   Una frase sola. Lo que la hace cara no es el tamaño de la letra:
   es el vacío que tiene alrededor. Por eso el aire va en la seccion
   y no en el texto, y por eso la medida de linea se acorta cuanto
   mas grande es la frase — una linea de 90 caracteres a 64px no se
   lee, se recorre.
   ----------------------------------------------- */
.sgf-manifiesto {
  /* EL AIRE NO ES UN AGUJERO — 29 sep.
     Estaba en 14vw arriba Y abajo, y la seccion siguiente anade lo
     suyo: sumados dejaban medio scroll de nada debajo de la frase.
     El aire de arriba enmarca; el de abajo lo pone la seccion que
     viene. */
  /* Arriba enmarca, abajo separa de lo que viene. Estuvo tan corto
     por abajo que el pie quedaba pegado a la primera foto del
     mosaico: la frase y las imagenes parecian el mismo bloque. */
  padding-block: clamp(var(--sgf-space-16), 11vw, var(--sgf-space-24)) clamp(var(--sgf-space-12), 8vw, var(--sgf-space-20));
  padding-inline: var(--sgf-gutter);
}
.sgf-manifiesto__inner {
  max-width: 62rem;
  margin-inline: auto;
  text-align: center;
}
.sgf-manifiesto {
  /* CENTRAR EL TEXTO NO BASTA SI EL PARRAFO ES MAS ESTRECHO — 29 sep
     -----------------------------------------------------------------
     El antetitulo y el pie son `<p>`, y el tema les pone un
     `max-width` de medida de lectura. `text-align: center` centra las
     LINEAS dentro de la caja, pero la caja seguia pegada a la
     izquierda porque sus margenes laterales eran 0.

     Medido: el centro de la seccion estaba en 505px, la frase en 505
     y el antetitulo en 363. Se veia torcido y no habia forma de
     saberlo mirando el `text-align`.

     `margin-inline: auto` centra la CAJA. Va sobre los dos hijos que
     heredan esa medida, no sobre el contenedor, que ya estaba bien. */
  /* OJO: el `auto` va DENTRO de la forma corta de cada uno.
     Una regla `margin-inline: auto` puesta aqui arriba no sirve de
     nada: `margin: 0 0 X` de mas abajo es una forma corta y resetea
     los laterales a 0. Comprobado midiendo — la primera version de
     este arreglo no movio ni un pixel. */
}
.sgf-manifiesto__eyebrow {
  /* Mas aire bajo el antetitulo: a este cuerpo de frase, seis
     unidades lo dejaban pegado al titular. */
  margin: 0 auto clamp(var(--sgf-space-8), 3vw, var(--sgf-space-12));
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  font-weight: 500;
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}
.sgf-manifiesto__frase {
  margin: 0;
  font-family: var(--sgf-font-display);
  font-weight: 400;
  /* Escalon `display`: es el texto mas grande de la casa.
     Estuvo en -0.015em, que a 61px es casi nada: las letras
     quedaban sueltas y la frase parecia mas un parrafo grande
     que un titular compuesto. */
  line-height: var(--sgf-lead-display);
  letter-spacing: var(--sgf-track-display);
  text-wrap: balance;
  color: var(--sgf-color-text);
}
.sgf-manifiesto__pie {
  margin: clamp(var(--sgf-space-10), 4vw, var(--sgf-space-12)) auto 0;
  font-family: var(--sgf-font-body);
  /* Apoyo de seccion: el mismo token y la misma interlinea que
     la entrada de la coleccion. Estaba en `sm` y se veia. */
  font-size: var(--sgf-text-base);
  line-height: 1.75;
  color: var(--sgf-color-muted);
}
.sgf-manifiesto {
  /* La medida manda sobre el cuerpo Y sobre el ancho: a mas cuerpo,
     menos caracteres por linea. */
}
.sgf-manifiesto--corta .sgf-manifiesto__frase {
  font-size: clamp(2.25rem, 6vw, 4.5rem);
}
.sgf-manifiesto--corta .sgf-manifiesto__inner {
  max-width: 46rem;
}
.sgf-manifiesto--media .sgf-manifiesto__frase {
  font-size: clamp(1.75rem, 4vw, 3rem);
}
.sgf-manifiesto--media .sgf-manifiesto__inner {
  max-width: 56rem;
}
.sgf-manifiesto--larga .sgf-manifiesto__frase {
  font-size: clamp(1.375rem, 2.4vw, 1.875rem);
  line-height: 1.35;
}
.sgf-manifiesto--larga .sgf-manifiesto__inner {
  max-width: 64rem;
}
.sgf-manifiesto--papel {
  background: var(--sgf-color-bg);
}
.sgf-manifiesto--tinta {
  background: var(--sgf-color-text);
}
.sgf-manifiesto--tinta .sgf-manifiesto__frase {
  color: var(--sgf-color-bg);
}
.sgf-manifiesto--tinta .sgf-manifiesto__eyebrow,
.sgf-manifiesto--tinta .sgf-manifiesto__pie {
  color: var(--sgf-color-subtle);
}
.sgf-manifiesto--campo {
  background: var(--sgf-color-surface);
}
.sgf-manifiesto {
  /* Tinte: velo de color, no superficie. Se usa para agrupar esta
     sección con la de debajo (normalmente un mosaico) en una sola
     banda. Ver `--sgf-color-tinte` en _tokens.scss. */
}
.sgf-manifiesto--tinte {
  background: var(--sgf-color-tinte);
}
.sgf-manifiesto {
  /* El sello va sobre el antetítulo y comparte su aire: sello,
     antetítulo y frase tienen que leerse como un bloque, no como
     tres cosas sueltas.

     `width: auto` con el alto en línea: la altura la decide el
     editor y el ancho lo pone la proporción de la imagen. Sin el
     `auto`, la regla de ancho que el hijo pone a las imágenes del
     contenido lo estiraría. */
}
.sgf-manifiesto__sello {
  display: block;
  width: auto;
  max-width: 100%;
  /* 16px, no 32: el sello y el antetitulo dicen lo mismo (la
     D.O.), asi que tienen que leerse como una unidad. Con 32
     parecian dos cosas sueltas. */
  margin: 0 auto var(--sgf-space-3);
}

/* -----------------------------------------------
   PILARES — 29 sep

   Lo de heirest: foto y texto alternando lado. La alternancia la
   hace `:nth-child` y no un ajuste, para que no dependa de que
   alguien se acuerde de alternarla al añadir uno.
   ----------------------------------------------- */
.sgf-pilares {
  padding-block: var(--sgf-section-y);
  padding-inline: var(--sgf-gutter);
}
.sgf-pilares__heading {
  font-family: var(--sgf-font-display);
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-weight: 400;
  line-height: var(--sgf-lead-4xl);
  letter-spacing: var(--sgf-track-4xl);
  color: var(--sgf-color-text);
  margin: 0 0 clamp(var(--sgf-space-10), 6vw, var(--sgf-space-16));
  /* A la izquierda, como el de la coleccion: debajo hay una
     reticula que empieza por la izquierda y centrar el titulo
     rompe ese borde compartido. */
  text-align: left;
}
.sgf-pilares {
  /* RETICULA, NO FILAS ALTERNAS — 29 sep
     Estaban como foto-y-texto alternando lado: cuatro filas de 600px
     que sumaban 2.576px de scroll para decir cuatro frases. Ahora es
     la misma reticula que las fichas de arriba —foto arriba, texto
     debajo—, asi la pagina tiene UN ritmo y no dos. */
}
.sgf-pilares__lista {
  display: grid;
  /* El MISMO hueco que la reticula de fichas. Ya existia
     `--sgf-grid-gap` y estas rejillas se lo saltaban con un
     clamp propio: tres rejillas en la misma pagina con tres
     huecos distintos es lo que rompe la coherencia (29 sep). */
  column-gap: var(--sgf-grid-gap);
  row-gap: var(--sgf-row-gap);
  grid-template-columns: 1fr;
}
.sgf-pilares {
  /* RETICULA: dos o tres columnas que bajan.
     Es la de la portada y la que sale por defecto. En movil se
     desliza igual: cinco fichas de foto vertical apiladas son unos
     2.400px de scroll para leer cinco nombres. Medido en Los
     Vinedos, la pagina pasaba de 8.000 a 10.874px por esa seccion
     sola. */
}
@media (min-width: 640px) {
  .sgf-pilares--reticula .sgf-pilares__lista {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .sgf-pilares--reticula .sgf-pilares__lista {
    grid-template-columns: repeat(3, 1fr);
  }
}
@media (max-width: 639px) {
  .sgf-pilares--reticula .sgf-pilares__lista {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--sgf-grid-gap);
    margin: 0;
    padding-inline: 0px;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 0px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sgf-pilares--reticula .sgf-pilares__lista::-webkit-scrollbar {
    display: none;
  }
  .sgf-pilares--reticula .sgf-pilares__lista > * {
    flex: 0 0 calc((100% - var(--sgf-grid-gap) * (1.15 - 1)) / 1.15);
    scroll-snap-align: start;
    min-width: 0;
    margin: 0;
    list-style: none;
  }
}
.sgf-pilares {
  /* CARRIL: una tira que se recorre de lado, tambien en escritorio.
     -------------------------------------------------------------
     Para enumeraciones —cinco tipos de uva, seis pasos— donde lo que
     importa es que se vean como UNA serie. Una reticula de 3+2 las
     parte en dos grupos que no significan nada: quien la mira busca
     que tienen en comun las dos de abajo, y no tienen nada.

     El numero de fichas visibles no es redondo a proposito. Con 3
     justas, el borde derecho coincide con el final y la tira parece
     una reticula: nadie adivina que hay mas. Con 3,3 se ve un trozo
     de la cuarta, que es la unica forma de que el gesto se pida
     solo.

     `$canal: 0` porque el carril cae en la lista, no en la seccion,
     y la seccion ya puso el suyo. */
}
.sgf-pilares--carril .sgf-pilares__lista {
  /* EL ASOMO, SOLO SI HAY ALGO QUE ASOMAR
     -------------------------------------
     El decimal encoge las fichas para dejar ver un trozo de la
     siguiente. Si no hay siguiente, encoge igual y deja un hueco
     muerto. Medido en «Nosotros», tres fichas con `visibles: 3.3`:
     455px cada una, 1.397 ocupados de 1.537 y 140px vacios a la
     derecha, sin nada a lo que desplazarse. El precio de una
     pista y ninguna pista.

     Esto ya se arreglo en la fila de baldosas y en el carril de
     producto, y este se quedo fuera: los tres bloques de fila
     tenian el mismo fallo y solo parchee dos. Aqui esta el
     tercero. */
  display: flex;
  flex-wrap: nowrap;
  gap: var(--sgf-grid-gap);
  margin: 0;
  padding-inline: 0px;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: 0px;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.sgf-pilares--carril .sgf-pilares__lista::-webkit-scrollbar {
  display: none;
}
.sgf-pilares--carril .sgf-pilares__lista > * {
  flex: 0 0 calc((100% - var(--sgf-grid-gap) * (1 - 1)) / 1);
  scroll-snap-align: start;
  min-width: 0;
  margin: 0;
  list-style: none;
}
.sgf-pilares--carril .sgf-pilares__lista {
  /* CADA TRAMO, CERRADO POR ARRIBA
     ------------------------------
     `:has()` SUMA especificidad: toma la de su argumento mas
     especifico. Una regla de movil con `:has(> :nth-child(2))`
     pesa mas que la de escritorio sin el, y entonces el orden de
     los `@media` no decide nada: la de movil gana a 1.600px.

     Me paso al escribir esto: en «Nosotros» las tres fichas
     salieron a 659px —el valor de tablet— y desbordaron la caja.

     Por eso cada tramo se cierra por arriba: solo hay una regla
     activa a cada ancho y no compiten. */
}
@media (max-width: 639px) {
  .sgf-pilares--carril .sgf-pilares__lista:has(> :nth-child(2)) > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (1.15 - 1)) / 1.15);
  }
}
@media (min-width: 640px) and (max-width: 1023px) {
  .sgf-pilares--carril .sgf-pilares__lista > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (2 - 1)) / 2);
  }
  .sgf-pilares--carril .sgf-pilares__lista:has(> :nth-child(3)) > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (2.3 - 1)) / 2.3);
  }
}
@media (min-width: 1024px) {
  .sgf-pilares--carril .sgf-pilares__lista > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (3 - 1)) / 3);
  }
  .sgf-pilares--carril .sgf-pilares__lista:has(> :nth-child(4)) > * {
    flex-basis: calc((100% - var(--sgf-grid-gap) * (3.3 - 1)) / 3.3);
  }
}

.sgf-pilar {
  display: flex;
  flex-direction: column;
}
.sgf-pilar__media {
  margin: 0 0 var(--sgf-space-5);
  overflow: hidden;
  background: var(--sgf-color-surface);
  /* Sin foto, esta caja se queda a cero de alto y la ficha se
     convierte en un agujero entre fichas altas: la rejilla
     parece rota en vez de parecer pendiente. Guardando la
     proporcion, el hueco se lee como lo que es —una foto que
     falta— y quien edita ve exactamente donde va. */
}
.sgf-pilar__media:empty {
  aspect-ratio: var(--sgf-ratio-retrato);
}
.sgf-pilar__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--sgf-ratio-retrato);
  object-fit: cover;
}
.sgf-pilar__titulo {
  margin: 0 0 var(--sgf-space-3);
  font-family: var(--sgf-font-display);
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  font-weight: 400;
  line-height: 1.25;
  color: var(--sgf-color-text);
}
.sgf-pilar__texto {
  margin: 0;
  font-family: var(--sgf-font-body);
  /* Cuerpo de TARJETA, no apoyo de seccion: 14px a proposito.
     Ver la regla de los tres cuerpos, arriba. */
  font-size: var(--sgf-text-sm);
  line-height: 1.7;
  color: var(--sgf-color-muted);
}
.sgf-pilar__cta {
  display: inline-block;
  align-self: flex-start;
  margin-top: var(--sgf-space-5);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  color: var(--sgf-color-text);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
  transition: opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-pilar__cta:hover {
  opacity: 0.6;
}

/* -----------------------------------------------
   COLECCIÓN — 29 sep
   Titular, texto y fichas, todo junto. La cabecera se alinea a la
   izquierda y NO al centro: debajo hay una reticula que empieza por
   la izquierda, y centrar el titulo rompe ese borde compartido.
   ----------------------------------------------- */
.sgf-coleccion {
  padding-block: var(--sgf-section-y);
  padding-inline: var(--sgf-gutter);
}
.sgf-coleccion__head {
  max-width: 48rem;
  /* El texto NO puede tocar las fichas. Estaba en 5vw, que a
     1024px son 51px y con la ultima linea del parrafo encima de
     la primera foto. Minimo fijo alto y que crezca desde ahi. */
  margin-bottom: clamp(var(--sgf-space-12), 7vw, var(--sgf-space-20));
}
.sgf-coleccion__eyebrow {
  margin: 0 0 var(--sgf-space-4);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  font-weight: 500;
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}
.sgf-coleccion__heading {
  font-family: var(--sgf-font-display);
  font-size: clamp(1.75rem, 4vw, 3rem);
  font-weight: 400;
  line-height: var(--sgf-lead-4xl);
  letter-spacing: var(--sgf-track-4xl);
  color: var(--sgf-color-text);
  margin: 0;
  text-wrap: balance;
}
.sgf-coleccion__intro {
  margin: var(--sgf-space-5) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-base);
  line-height: 1.75;
  /* Medida corta a proposito: un parrafo de entrada que cruza
     toda la pantalla no se lee, se salta. */
  max-width: 38rem;
  color: var(--sgf-color-muted);
}
.sgf-coleccion__rejilla {
  display: grid;
  /* El MISMO hueco que la reticula de fichas. Ya existia
     `--sgf-grid-gap` y estas rejillas se lo saltaban con un
     clamp propio: tres rejillas en la misma pagina con tres
     huecos distintos es lo que rompe la coherencia (29 sep). */
  column-gap: var(--sgf-grid-gap);
  row-gap: var(--sgf-row-gap);
  grid-template-columns: 1fr;
}
@media (min-width: 640px) {
  .sgf-coleccion__rejilla {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1024px) {
  .sgf-coleccion__rejilla--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .sgf-coleccion__rejilla--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}
.sgf-coleccion {
  /* LA REJILLA DE WOO PISABA ESTO — 29 sep
     --------------------------------------
     Esta rejilla lleva ademas la clase `.products` de WooCommerce,
     y Woo tiene un `@media (max-width: 1023px)` que la pone a dos
     columnas. Misma especificidad que la de arriba (0,1,0) y en una
     hoja que se carga despues, asi que ganaba: el bloque pedia una
     columna en movil y salian dos.

     Con el padre delante subimos a (0,2,0) y la especificidad gana
     al orden. Se acota a la portada a proposito: en el catalogo de
     la tienda dos columnas en movil SI sirven, porque ahi se viene
     a comparar y a elegir, no a mirar. */
}
@media (max-width: 639px) {
  .sgf-coleccion .sgf-coleccion__rejilla,
  .sgf-coleccion .sgf-coleccion__lista {
    /* Mismo carril que el mosaico. 1.4 y no 1.15: son fichas
       con nombre y precio debajo, y a pantalla casi completa
       solo se ve un vino por pantallazo. Con 1.4 se comparan
       dos, que es a lo que se viene.

       `$canal: 0` a proposito. Este carril va sobre la rejilla,
       que es HIJA de `.sgf-coleccion`, y la seccion ya pone
       sus 24px: con el canal del mixin encima sumaban 48 y las
       fichas entraban el doble de adentro que el resto de la
       pagina.

       El mosaico no lo sufre porque alli el mixin cae sobre el
       mismo elemento que ya tenia el canal, y sobrescribe la
       propiedad en vez de sumarla. Misma inclusion, resultado
       distinto segun donde caiga. */
    display: flex;
    flex-wrap: nowrap;
    gap: var(--sgf-grid-gap);
    margin: 0;
    padding-inline: 0px;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-left: 0px;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sgf-coleccion .sgf-coleccion__rejilla::-webkit-scrollbar,
  .sgf-coleccion .sgf-coleccion__lista::-webkit-scrollbar {
    display: none;
  }
  .sgf-coleccion .sgf-coleccion__rejilla > *,
  .sgf-coleccion .sgf-coleccion__lista > * {
    flex: 0 0 calc((100% - var(--sgf-grid-gap) * (1.4 - 1)) / 1.4);
    scroll-snap-align: start;
    min-width: 0;
    margin: 0;
    list-style: none;
  }
}

/* -----------------------------------------------
   LÁMINA — 29 sep
   El descanso. Una portada donde todo pide algo cansa.
   ----------------------------------------------- */
.sgf-lamina {
  position: relative;
  display: grid;
  place-items: center;
  overflow: hidden;
  background: var(--sgf-color-surface);
}
.sgf-lamina--baja {
  min-height: 46vh;
}
.sgf-lamina--media {
  min-height: 68vh;
}
.sgf-lamina--alta {
  min-height: 92vh;
}
.sgf-lamina__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sgf-lamina {
  /* El velo solo existe si hay texto encima. Oscurecer una foto sin
     nada escrito es estropearla por nada. */
}
.sgf-lamina__velo {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.42));
}
.sgf-lamina__cita {
  position: relative;
  max-width: 90%;
  margin: 0;
  padding: clamp(var(--sgf-space-8), 6vw, var(--sgf-space-20));
  text-align: center;
}
.sgf-lamina__cita p {
  /* Mismo caso que el manifiesto: la caja se centra con
     `auto`, no con `text-align`. */
  margin: 0 auto;
  font-family: var(--sgf-font-display);
  font-size: clamp(1.5rem, 3.4vw, 2.75rem);
  font-weight: 400;
  line-height: 1.22;
  text-wrap: balance;
  color: #fff;
}
.sgf-lamina__autor {
  display: block;
  margin-top: var(--sgf-space-6);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  font-style: normal;
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}
.sgf-lamina--izquierda {
  place-items: center start;
}
.sgf-lamina--izquierda .sgf-lamina__cita {
  text-align: left;
}
.sgf-lamina--abajo {
  place-items: end center;
}

/* -----------------------------------------------
   AÑADA — 29 sep
   La escasez, con numero o callada. Ver el render.
   ----------------------------------------------- */
.sgf-anada {
  display: grid;
  gap: clamp(var(--sgf-space-6), 4vw, var(--sgf-space-12));
  align-items: center;
  padding-block: var(--sgf-section-y);
  padding-inline: var(--sgf-gutter);
  background: var(--sgf-color-surface);
}
@media (min-width: 900px) {
  .sgf-anada {
    grid-template-columns: 1fr 1fr;
  }
}
.sgf-anada__img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: var(--sgf-ratio-alta);
  object-fit: cover;
}
.sgf-anada__cuerpo {
  max-width: 34rem;
}
.sgf-anada__year {
  margin: 0 0 var(--sgf-space-4);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  font-weight: 500;
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}
.sgf-anada__titulo {
  margin: 0;
  font-family: var(--sgf-font-display);
  font-size: clamp(1.75rem, 3.4vw, 2.75rem);
  font-weight: 400;
  line-height: 1.15;
  color: var(--sgf-color-text);
}
.sgf-anada__texto {
  margin: var(--sgf-space-5) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-base);
  line-height: 1.7;
  color: var(--sgf-color-muted);
}
.sgf-anada {
  /* La cifra es el argumento: se pinta grande y sola. */
}
.sgf-anada__cifra {
  display: flex;
  align-items: baseline;
  gap: var(--sgf-space-3);
  margin: clamp(var(--sgf-space-8), 4vw, var(--sgf-space-12)) 0 0;
  padding-top: var(--sgf-space-6);
  border-top: 1px solid var(--sgf-color-border);
}
.sgf-anada__numero {
  font-family: var(--sgf-font-display);
  font-size: clamp(2.5rem, 6vw, 4rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  color: var(--sgf-color-text);
}
.sgf-anada__unidad {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  line-height: 1.4;
  color: var(--sgf-color-muted);
}
.sgf-anada__fuente {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
}
.sgf-anada__cta {
  display: inline-block;
  margin-top: var(--sgf-space-8);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  color: var(--sgf-color-text);
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
  transition: opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-anada__cta:hover {
  opacity: 0.6;
}

/* -----------------------------------------------
   MOSAICO — 29 sep
   Cuatro fotos casi pegadas. Los 8px son el punto en que se leen
   como UNA pieza; mas separacion y parecen cosas distintas puestas
   al lado. Todas con la misma proporcion y recortadas: una fila
   donde cada foto tiene su alto es lo que hace que una galeria
   parezca de aficionado.
   ----------------------------------------------- */
.sgf-mosaico {
  display: grid;
  /* Mismo hueco que las fichas y que los pilares. Estuvo en 8px
     fijos y se leia como una pieza distinta del resto. */
  column-gap: var(--sgf-grid-gap);
  row-gap: var(--sgf-row-gap);
  padding-inline: var(--sgf-gutter);
  padding-block: var(--sgf-section-y);
  grid-template-columns: repeat(2, 1fr);
  /* EN EL MOVIL, CARRIL QUE SE DESLIZA — 29 sep
     -------------------------------------------
     Cuatro fotos en 2x2 dentro de 375px son cuatro miniaturas de
     164px: se ve que hay fotos, no se ve lo que hay EN ellas.

     Carril y no columna apilada: la foto sale casi a pantalla
     completa y el resto se recorre con el dedo, sin que la seccion
     se coma cuatro pantallas de scroll vertical.

     El patron sale del mixin, que a su vez sale del carril de
     relacionados y de la galeria de producto. No hay una tercera
     implementacion de lo mismo. */
}
@media (max-width: 639px) {
  .sgf-mosaico {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--sgf-grid-gap);
    margin: 0;
    padding-inline: var(--sgf-gutter);
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-left: var(--sgf-gutter);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .sgf-mosaico::-webkit-scrollbar {
    display: none;
  }
  .sgf-mosaico > * {
    flex: 0 0 calc((100% - var(--sgf-grid-gap) * (1.15 - 1)) / 1.15);
    scroll-snap-align: start;
    min-width: 0;
    margin: 0;
    list-style: none;
  }
}
@media (min-width: 900px) {
  .sgf-mosaico--3 {
    grid-template-columns: repeat(3, 1fr);
  }
  .sgf-mosaico--4 {
    grid-template-columns: repeat(4, 1fr);
  }
}
.sgf-mosaico__pieza {
  margin: 0;
  overflow: hidden;
  background: var(--sgf-color-surface);
}
.sgf-mosaico__img {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  transition: transform var(--sgf-duration-slow) var(--sgf-ease-out);
}
.sgf-mosaico--vertical .sgf-mosaico__img {
  aspect-ratio: var(--sgf-ratio-alta);
}
.sgf-mosaico--cuadrada .sgf-mosaico__img {
  aspect-ratio: 1/1;
}
.sgf-mosaico--apaisada .sgf-mosaico__img {
  aspect-ratio: 4/3;
}
.sgf-mosaico {
  /* Tinte: el mismo velo que el manifiesto, para que los dos se lean
     como UNA banda.

     El aire de arriba se quita SOLO cuando va pegado a un
     manifiesto; la regla esta al final del bloque. Antes no lo
     llevaba nunca, dando por hecho que siempre iria bajo una
     frase, y en Los Vinedos —donde va tras un bloque de texto—
     quedaba pegado a 19px. */
}
.sgf-mosaico--tinte {
  background: var(--sgf-color-tinte);
}
@media (hover: hover) {
  .sgf-mosaico__pieza:hover .sgf-mosaico__img {
    transform: scale(1.03);
  }
}

/* El unico caso que renuncia al aire de arriba: pegado a la frase que
   presenta las fotos, los dos se leen como UNA banda y el hueco de
   abajo del manifiesto ya los separa lo justo. La regla declara su
   propia condicion en vez de dar por hecho quien tiene encima. */
.sgf-manifiesto + .sgf-mosaico {
  padding-top: 0;
}

/* =============================================
   INDICE + PROSA + OBJETO
   =============================================
   Indice corto a la izquierda, texto en medio, foto a la derecha.
   Se pulsa una entrada del indice y cambian texto y foto; la foto no
   cambia de sitio, solo de contenido.

   Sin bordes, sin cajas y sin esquinas redondeadas a proposito. En la
   referencia que medimos (29 sep) no hay una sola linea divisoria ni
   una tarjeta con borde en toda la portada: lo que separa las cosas
   es el espacio, no el dibujo de una caja. Una caja es una forma
   barata de organizar; el espacio cuesta mas y se nota. */
.sgf-indice {
  padding-block: clamp(var(--sgf-space-12), 9vw, var(--sgf-space-20));
  padding-inline: var(--sgf-gutter);
}

.sgf-indice__cabecera {
  margin: 0 0 clamp(var(--sgf-space-7), 5vw, var(--sgf-space-12));
}

.sgf-indice__eyebrow {
  margin: 0 0 var(--sgf-space-3);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}

.sgf-indice__heading {
  margin: 0;
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-4xl);
  line-height: var(--sgf-lead-4xl);
  letter-spacing: var(--sgf-track-4xl);
  font-weight: 400;
}

/* Tres franjas: indice estrecho, texto ancho, foto. El indice no
   necesita crecer —son palabras sueltas— y el texto si, por eso va en
   `fr` y el indice en un ancho de contenido con tope. */
.sgf-indice__cuerpo {
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 3fr);
  column-gap: clamp(var(--sgf-space-7), 6vw, var(--sgf-space-16));
  align-items: start;
}

.sgf-indice__nav {
  list-style: none;
  margin: 0;
  padding: 0;
  /* Se queda a la vista mientras se lee la entrada larga. */
  position: sticky;
  top: calc(var(--sgf-nav-height, 72px) + var(--sgf-space-5));
}

.sgf-indice__nav li + li {
  margin-top: var(--sgf-space-3);
}

.sgf-indice__nav-item {
  position: relative;
  display: block;
  width: 100%;
  padding: 0 0 0 var(--sgf-space-4);
  border: 0;
  background: none;
  text-align: left;
  cursor: pointer;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-base);
  line-height: var(--sgf-lead-base);
  letter-spacing: var(--sgf-track-base);
  color: var(--sgf-color-muted);
  transition: color var(--sgf-duration-base) var(--sgf-ease-out);
}

/* El punto marca la entrada abierta. Va en un `::before` con hueco
   reservado por el padding: si apareciera y desapareciera del flujo,
   la lista entera bailaria a cada clic. */
.sgf-indice__nav-item::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0;
  transition: opacity var(--sgf-duration-base) var(--sgf-ease-out);
}

.sgf-indice__nav-item[aria-selected=true] {
  color: var(--sgf-color-text);
}

.sgf-indice__nav-item[aria-selected=true]::before {
  opacity: 1;
}

.sgf-indice__nav-item:hover {
  color: var(--sgf-color-text);
}

.sgf-indice__panel {
  display: grid;
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  column-gap: clamp(var(--sgf-space-7), 5vw, var(--sgf-space-12));
  align-items: start;
}

.sgf-indice__panel[hidden] {
  display: none;
}

.sgf-indice__titulo {
  margin: 0 0 var(--sgf-space-4);
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-xl);
  line-height: var(--sgf-lead-xl);
  letter-spacing: var(--sgf-track-xl);
  font-weight: 400;
}

.sgf-indice__parrafo {
  margin: 0;
  max-width: 46ch;
  font-size: var(--sgf-text-base);
  line-height: var(--sgf-lead-base);
  letter-spacing: var(--sgf-track-base);
  color: var(--sgf-color-muted);
}

.sgf-indice__cta {
  display: inline-block;
  margin-top: var(--sgf-space-5);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  color: inherit;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 6px;
}

.sgf-indice__media {
  margin: 0;
  overflow: hidden;
  background: var(--sgf-color-surface);
  aspect-ratio: var(--sgf-ratio-retrato);
}

.sgf-indice__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* En movil no caben tres franjas ni dos. El indice pasa a ser una
   fila que se desliza, que es como se navegan las pestanas en un
   telefono, y el panel se apila. */
@media (max-width: 899px) {
  .sgf-indice__cuerpo {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--sgf-space-7);
  }
  .sgf-indice__nav {
    position: static;
    display: flex;
    gap: var(--sgf-space-5);
    overflow-x: auto;
    /* Los 16px del canal, para que la primera entrada no nazca
       pegada al borde y la ultima tenga donde terminar. */
    margin-inline: calc(var(--sgf-gutter) * -1);
    padding-inline: var(--sgf-gutter);
    scrollbar-width: none;
  }
  .sgf-indice__nav::-webkit-scrollbar {
    display: none;
  }
  .sgf-indice__nav li + li {
    margin-top: 0;
  }
  .sgf-indice__nav-item {
    white-space: nowrap;
  }
  .sgf-indice__panel {
    grid-template-columns: minmax(0, 1fr);
    row-gap: var(--sgf-space-6);
  }
  /* La foto primero: en un telefono la imagen es la que hace parar
     el scroll, y el texto se lee despues. */
  .sgf-indice__media {
    order: -1;
  }
}
/* NINGUNA FOTO MAS ALTA QUE LA PANTALLA — 29 sep
   ==============================================
   Medido en Los Vinedos a 1585x950: una foto a sangre salia a 2113px
   de alto. Mas del doble de la pantalla, o sea que no se podia ver
   entera ni haciendo scroll: siempre estabas dentro de la foto.

   El motivo: al barrer las proporciones a vertical puse
   `.sgf-tile__media` en 4:5. Para una ficha dentro de una reticula
   esta bien —mide 300px de ancho— pero la MISMA clase la usa la foto
   suelta a sangre, y a 1585 de ancho un 4:5 son casi 2000 de alto.
   Una proporcion no es buena o mala: depende del ancho al que se
   aplique.

   Techo en `78vh`: la foto siempre deja ver que hay algo debajo, que
   es lo que invita a seguir bajando. Y `cover`, no `contain`: se
   recorta antes que dejar barras.

   No lleva `aspect-ratio: auto` por si acaso: se lo quitamos
   explicitamente, porque si no el ratio y la altura pelean y gana el
   ratio. */
/* EL TECHO DEPENDE DEL ANCHO, NO DE LA CLASE — 29 sep (2)
   -------------------------------------------------------
   La primera version de esta regla solo miraba `.alignfull`, y eso
   era mirar el sintoma. Medido en el catalogo: la MISMA foto sin
   `alignfull` salia a 948px, porque lo que la estira no es el align
   sino el ratio 4:5 aplicado a una caja ancha. A 977px de ancho, un
   4:5 son 1221 de alto lleve la clase que lleve.

   Asi que se acota por el CONTEXTO: una figura suelta dentro del
   contenido es una foto que manda, y ahi el ratio de ficha no pinta
   nada. Dentro de una reticula si, porque alli la caja mide 300px y
   el 4:5 es justo lo que hace la columna. */
/* CUARTA PASADA: Y TAMPOCO ES EL ALIGN — 30 sep
   ---------------------------------------------
   El tope de `78vh` es para una foto que ES la banda: ocupa la pagina
   de lado a lado y manda ella. Pero el selector seguia mirando
   `.alignfull`, y resulta que una rejilla de dos columnas tambien
   puede ir a sangre. Entonces la foto de UNA COLUMNA se comia un tope
   de altura pensado para otra cosa.

   Medido, el mismo modulo en dos paginas —«Los terrenos» en Los
   Vinedos y «Nuestra historia» en Nosotros, mismas columnas de 898 y
   599—:

     Los terrenos       foto 898 x 741   (el tope, 78vh)
     Nuestra historia   foto 898 x 674   (su proporcion)

   Mismo ancho las dos. Lo que cambiaba era el alto, y una foto mas
   alta con el mismo ancho se lee como mas estrecha. Parecia otro
   modulo siendo el mismo al reves.

   `:not(.sgf-grid)` lo dice por estructura: si el bloque es una
   rejilla, su foto es una columna y su altura la decide la fila, no un
   tope de pantalla. Van cuatro veces acotando esta regla, y las tres
   primeras fueron por donde estaba la foto —el align, la figura— en
   vez de por lo que la caja ES. */
.sgf-entry__content > figure .sgf-tile__media,
.sgf-entry__content > .alignfull:not(.sgf-grid) .sgf-tile__media {
  aspect-ratio: auto;
  height: min(78vh, 760px);
  overflow: hidden;
}

.sgf-entry__content > figure .sgf-tile__image,
.sgf-entry__content > .alignfull .sgf-tile__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* El mosaico NO lleva tope de altura.
   Lo llegue a poner y sobra: la proporcion de cada pieza la elige el
   cliente en el bloque (vertical, cuadrada o apaisada) y un tope por
   encima la contradice en silencio. Si una fila sale demasiado alta,
   se cambia la forma o el numero de columnas, que es la palanca que
   el bloque ya ofrece.

   Tampoco hace falta repetir `object-fit: cover`: ya esta en el
   `__img` del propio mosaico. */
/* TRES BORDES IZQUIERDOS ERAN TRES DE MAS — 29 sep
   ================================================
   Medido en Los Vinedos a 1585px: el texto de las cabeceras entraba
   a 48, los parrafos sueltos a 24 y las cifras a 64. Tres verticales
   distintas en la misma pagina. Se ve descosido aunque nadie sepa
   decir cual esta mal, porque no hay una "bien": lo que falla es que
   sean tres.

   La causa del 48: `.sgf-home-section` lleva su propio canal, que en
   la portada es correcto —ahi el bloque va suelto a sangre— pero
   dentro de una pagina el contenedor YA ha puesto los 24. Los dos
   sumaban.

   Asi que el canal propio solo lo llevan las secciones que se salen
   del contenedor. Las que van dentro heredan el del contenedor y
   entran donde entra todo lo demas.

   SEGUNDA PASADA — 30 sep
   -----------------------
   La primera version de esta regla apuntaba a `.sgf-entry__content >`,
   o sea SOLO a las secciones de primer nivel. Pero `.sgf-home-section`
   la ponen siete bloques distintos, y uno de ellos es la CABECERA que
   va anidada dentro de `.sgf-dos`. Esa no era hija directa de nada, no
   entraba en el selector, y volvia a sumar sus 24: el texto de las
   cabeceras seguia entrando a 48 mientras el resto entraba a 24.
   Dos bordes izquierdos otra vez, y la regla que decia arreglarlo
   estaba justo encima.

   La regla de abajo dice la version general y cierta: el canal es lo
   que el bloque DEVUELVE cuando se sale a sangre. Si esta dentro de un
   contenedor, el contenedor ya lo puso —da igual a que profundidad— y
   repetirlo mete el texto 24px mas adentro. Fuera de un contenedor
   (una seccion suelta en una plantilla) se queda, que es donde de
   verdad hace falta.

   TERCERA PASADA — 30 sep
   -----------------------
   Y va para los SIETE bloques que se ponen canal propio, no solo para
   el que dio la cara. La portada no tiene `.sgf-container`, asi que
   alli ninguno falla y el fallo no existe hasta que alguien mete uno
   de estos bloques en una pagina normal. Arreglar solo el que salto
   es dejar los otros seis armados esperando. */
.sgf-container :is(.sgf-home-section,
.sgf-manifiesto,
.sgf-pilares,
.sgf-coleccion,
.sgf-anada,
.sgf-mosaico,
.sgf-indice):not(.alignfull) {
  padding-inline: 0;
}

/* Lo mismo en vertical, y por la misma razon. Una `.sgf-home-section`
   anidada dentro de otro bloque no es una banda de la pagina: es la
   cabecera DE ese bloque. El bloque ya abrio su aire con
   `--sgf-section-y`; si la cabecera vuelve a abrirlo, se suman.

   Medido a 375px: 96 del bloque + 64 de la cabecera + 128 de la
   plantilla = 288px en blanco antes de la primera palabra, en una
   pantalla de 812. Un tercio de la pantalla vacio, y las tres capas
   creyendo cada una que el aire era suyo. */
.sgf-dos .sgf-home-section,
.sgf-grid .sgf-home-section,
.sgf-home-section .sgf-home-section {
  padding-block: 0;
}

/* CABECERA + SU REJILLA = UNA SECCION
   ----------------------------------
   Un titular y los datos que presenta son una sola cosa. Como bloques
   son dos hermanos, y cada uno trae su `--sgf-section-y`: 144 abajo
   del titular mas 144 arriba de la rejilla son 288px entre una frase
   y su propia tabla. A esa distancia ya no se leen juntos.

   El aire entre los dos baja a un hueco de dentro de seccion. El de
   despues no se toca: el bloque siguiente sigue entrando con los 144
   que le tocan, asi que la seccion completa respira como las demas. */
.sgf-entry__content > .sgf-home-section:has(+ .sgf-cifras, + .sgf-pilares, + .sgf-tile-row) {
  /* `flow-root` y no solo `padding-bottom: 0`. Al quitarle el
     relleno de abajo, el margen del ultimo parrafo deja de estar
     contenido y SE ESCAPA de la caja: colapsa hacia fuera y separa
     la cabecera de su rejilla 17px que no habia pedido nadie y que
     no aparecen en ninguna regla. `flow-root` abre un contexto de
     formato nuevo, y dentro de el los margenes de los hijos se
     quedan dentro. */
  display: flow-root;
  padding-bottom: 0;
}

.sgf-entry__content > .sgf-home-section + .sgf-cifras,
.sgf-entry__content > .sgf-home-section + .sgf-pilares,
.sgf-entry__content > .sgf-home-section + .sgf-tile-row {
  padding-top: var(--sgf-space-8);
}

/* =============================================
   CIFRAS
   =============================================
   Tres o cuatro datos duros, en grande. Va debajo de una entradilla
   y cierra la presentacion con algo comprobable.

   DOS FORMAS, SEGUN DONDE VAN — 30 sep
   ------------------------------------
   `linea` es como nacieron: un filete arriba y los datos debajo, en
   pistas de 128px. Funciona cuando van en la columna estrecha de al
   lado de un titular, que es donde se disenaron.

   Puestas SOLAS y a todo lo ancho no funcionan: tres datos de 128px
   en un hueco de 1.537 dejan 1.150px de pagina en blanco a su
   derecha. El filete llega hasta el final y los datos no, asi que
   ademas parece un error.

   `tarjetas` es la misma informacion ocupando el sitio que tiene.
   Cada dato en su caja, las cajas repartiendose el ancho. */
.sgf-cifras {
  display: grid;
  margin: var(--sgf-space-9) 0 0;
  /* `padding: 0`: es un `<ul>` y traia los 40px de sangrado que el
     navegador le pone a toda lista. Con `list-style: none` el punto
     desaparece pero el sangrado no, asi que las cifras empezaban
     40px a la derecha del resto del texto y nadie sabia por que. */
  padding: 0;
  list-style: none;
}

.sgf-cifras--linea {
  grid-template-columns: repeat(auto-fit, minmax(0, 8rem));
  gap: var(--sgf-space-4) var(--sgf-space-6);
  padding-top: var(--sgf-space-5);
  border-top: 1px solid var(--sgf-color-border);
  /* `minmax(0, 8rem)` topa cada columna en 128px: en una columna
     estrecha eso es lo que se quiere —una cifra no necesita 485px—
     pero en movil solo caben dos pistas de 128 y sobran 47px
     muertos a la derecha de CADA fila. El borde derecho quedaba
     descuadrado respecto al resto de la pagina, que si llega al
     canal.

     Medido a 375px: pistas de 128 y 128 en un hueco de 343.

     Abajo las columnas se reparten el ancho en vez de toparse. */
}
@media (max-width: 767px) {
  .sgf-cifras--linea {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--sgf-space-4) var(--sgf-space-5);
  }
}

.sgf-cifras--tarjetas {
  /* `min(18rem, 100%)` y no `18rem` a secas: en un movil de 320px
     una pista de 288px con el canal ya no cabe, y la rejilla
     desborda en horizontal. Con `min()` la pista nunca pide mas
     ancho del que hay. */
  grid-template-columns: repeat(auto-fit, minmax(min(18rem, 100%), 1fr));
  gap: var(--sgf-grid-gap);
}
.sgf-cifras--tarjetas .sgf-cifras__item {
  /* El mismo velo que el manifiesto y el mosaico: la casa ya
     tiene un tono para separar una pieza del fondo sin dibujar
     una caja. Un borde aqui seria un cuarto lenguaje. */
  background: var(--sgf-color-tinte);
  border-radius: var(--sgf-radius-md);
  padding: clamp(var(--sgf-space-6), 3vw, var(--sgf-space-9));
}
.sgf-cifras--tarjetas .sgf-cifras__valor {
  font-size: var(--sgf-text-4xl);
  line-height: var(--sgf-lead-4xl);
  letter-spacing: var(--sgf-track-4xl);
}

.sgf-cifras__valor {
  display: block;
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-2xl);
  line-height: var(--sgf-lead-2xl);
  letter-spacing: var(--sgf-track-2xl);
  font-weight: 500;
  color: var(--sgf-color-text);
}

.sgf-cifras__etiqueta {
  display: block;
  margin-top: var(--sgf-space-1);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  color: var(--sgf-color-muted);
}

/* =============================================
   FICHA
   =============================================
   Pares de dato y valor. Para un proceso o para los datos tecnicos
   de un vino.

   Una linea por fila y la ultima tambien cerrada: sin la de abajo la
   lista se deshilacha y parece que falta algo. */
.sgf-ficha {
  max-width: 36rem;
  margin: var(--sgf-space-7) 0 0;
  padding: 0;
}

.sgf-ficha__linea {
  display: grid;
  /* La columna del dato es fija para que los valores arranquen
     todos en la misma vertical. Con `auto` cada fila empezaria
     donde acabara su termino y la ficha se leeria en zigzag. */
  grid-template-columns: 7rem minmax(0, 1fr);
  gap: var(--sgf-space-3);
  align-items: baseline;
  padding-block: var(--sgf-space-3);
  border-top: 1px solid var(--sgf-color-border);
}

.sgf-ficha__linea:last-child {
  border-bottom: 1px solid var(--sgf-color-border);
}

.sgf-ficha__dato {
  margin: 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-tracking-widest);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}

.sgf-ficha__valor {
  margin: 0;
  font-size: var(--sgf-text-base);
  line-height: var(--sgf-lead-base);
  letter-spacing: var(--sgf-track-base);
  color: var(--sgf-color-text);
}

@media (max-width: 599px) {
  /* En movil no caben 7rem de termino y un valor legible al lado:
     el valor se quedaria en dos palabras por linea. Se apilan. */
  .sgf-ficha__linea {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--sgf-space-1);
  }
}
/* =============================================
   DOS COLUMNAS
   =============================================
   La pieza que le faltaba a las paginas: emparejar dos cosas que van
   juntas. Sin ella un texto se queda en una columna estrecha pegada
   al borde y, en una pantalla ancha, al lado no hay nada.

   Un hueco de 1400px no se lee como aire. Se lee como que falta
   algo. */
.sgf-dos {
  display: grid;
  /* RITMO DE SECCION — 30 sep
     -------------------------
     Nacio sin aire vertical y se notaba: entre una foto a sangre de
     933px y el titular de debajo quedaban 19px. El texto parecia el
     pie de la foto, no el principio de otra cosa.

     Mismo `clamp` que coleccion y pilares, para que todas las
     secciones de la casa respiren igual. */
  padding-block: var(--sgf-section-y);
  column-gap: clamp(var(--sgf-space-7), 5vw, var(--sgf-space-16));
  row-gap: var(--sgf-space-7);
  align-items: start;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

/* `minmax(0, …)` y no `1fr` a secas: `1fr` es `minmax(auto, 1fr)` y
   un contenido ancho —una tabla, una foto grande— empuja su columna y
   se come la otra. Con 0 de minimo el reparto se respeta. */
.sgf-dos--estrecha-ancha {
  grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
}

.sgf-dos--ancha-estrecha {
  grid-template-columns: minmax(0, 6fr) minmax(0, 4fr);
}

.sgf-dos--centro {
  align-items: center;
}

/* Los hijos ya no necesitan su propio canal: lo pone el contenedor de
   la pagina y las columnas van dentro. */
.sgf-dos > * {
  margin: 0;
  max-width: none;
}

/* Un parrafo dentro de una columna se lee entero; no hace falta la
   medida de lectura del contenido, que aqui lo estrecharia dos
   veces. */
.sgf-dos p {
  max-width: 54ch;
}

@media (max-width: 899px) {
  /* Se apilan. En un movil dos columnas de 170px no son dos
     columnas: son dos cosas ilegibles. */
  .sgf-dos,
  .sgf-dos--estrecha-ancha,
  .sgf-dos--ancha-estrecha {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* =============================================
   CONTAINER SYSTEM
   ============================================= */
/* Base container — horizontal centering + gutters */
/* A SANGRE, CON 16px DE AIRE — 29 sep
   ===================================
   El contenedor estaba en 1280px centrado con 40px de canal. Eso
   deja, en un monitor de 1440, 160px de nada a cada lado y unas
   fotos que nunca llegan a mandar.

   El cambio: sin tope de ancho y 16px de canal, el MISMO valor en
   todos los tamanos. Medido en un sitio de lujo que funciona (29
   sep): a 1440 de pantalla su contenido ocupa 1429, y el canal es de
   16px tanto en movil como en escritorio.

   Que esto NO significa: que el texto se lea a 1400px de ancho. La
   medida de lectura la sigue poniendo el parrafo (`max-width: 68ch`
   en la base) y las variantes estrechas de abajo. Lo que va a sangre
   es la MAQUETA; el texto sigue en su columna. Es justo lo que hace
   que la foto se lea grande y el texto se lea como una nota al pie
   de la foto, en vez de los dos peleando por el mismo ancho.

   Las variantes estrechas se quedan: una pagina legal o una entrada
   de diario necesitan su medida y no tienen fotos que mandar. */
.sgf-container {
  width: 100%;
  max-width: 100%;
  margin-inline: auto;
  /* EL MISMO TOKEN QUE EL TIRON DEL `alignfull` — 29 sep
     ----------------------------------------------------
     Estaba en `--sgf-space-3` (16px) escrito a mano, de cuando el
     canal valia 16. Al subir el canal a 24, el contenedor se quedo
     en 16 y el tiron de los bloques a sangre paso a 24: cada seccion
     a sangre se salia 8px por cada lado. Medido en Los Vinedos:
     izq -8, ancho 1025 en un viewport de 1009.

     Los dos al token. Si el canal cambia, el tiron cambia con el y
     el borde sigue siendo el borde. */
  padding-inline: var(--sgf-gutter);
}

/* Variantes para leer. No para maquetar. */
.sgf-container--lg {
  max-width: 1024px;
} /* lectura comoda */
.sgf-container--md {
  max-width: 768px;
} /* contenido estrecho */
.sgf-container--prose {
  max-width: 72ch;
} /* texto largo */
/* Se quedan por compatibilidad: habia plantillas pidiendolas. Ahora
   no acotan nada, porque el contenedor ya va a sangre. */
.sgf-container--full,
.sgf-container--wide,
.sgf-container--xl {
  max-width: 100%;
}

/* =============================================
   GRID SYSTEM
   ============================================= */
/* Base grid — gap defaults, responsive */
.sgf-grid {
  display: grid;
  gap: var(--sgf-space-6);
}

/* Column presets */
.sgf-grid-2 {
  grid-template-columns: repeat(2, 1fr);
}

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

.sgf-grid-4 {
  grid-template-columns: repeat(4, 1fr);
}

.sgf-grid-6 {
  grid-template-columns: repeat(6, 1fr);
}

/* Auto-fill grids (responsive without breakpoints) */
.sgf-grid--auto-sm {
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
}

.sgf-grid--auto-md {
  grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
}

.sgf-grid--auto-lg {
  grid-template-columns: repeat(auto-fill, minmax(420px, 1fr));
}

/* Asymmetric layouts (for split / feature sections) */
.sgf-grid--60-40 {
  grid-template-columns: 60fr 40fr;
}

.sgf-grid--40-60 {
  grid-template-columns: 40fr 60fr;
}

.sgf-grid--70-30 {
  grid-template-columns: 70fr 30fr;
}

.sgf-grid--30-70 {
  grid-template-columns: 30fr 70fr;
}

/* Gap variants */
.sgf-grid--gap-sm {
  gap: var(--sgf-space-4);
}

.sgf-grid--gap-lg {
  gap: var(--sgf-space-10);
}

.sgf-grid--gap-xl {
  gap: var(--sgf-space-12);
}

.sgf-grid--gap-none {
  gap: 0;
}

/* Column span helpers (for use inside grids) */
.sgf-col-span-2 {
  grid-column: span 2;
}

.sgf-col-span-3 {
  grid-column: span 3;
}

.sgf-col-full {
  grid-column: 1/-1;
}

/* Collapse to 1 col on mobile */
@media (max-width: 767px) {
  .sgf-grid-2,
  .sgf-grid-3,
  .sgf-grid-4,
  .sgf-grid--60-40,
  .sgf-grid--40-60,
  .sgf-grid--70-30,
  .sgf-grid--30-70 {
    grid-template-columns: 1fr;
  }
  .sgf-grid-6 {
    grid-template-columns: repeat(2, 1fr);
  }
  .sgf-col-span-2,
  .sgf-col-span-3 {
    grid-column: span 1;
  }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .sgf-grid-3,
  .sgf-grid-4 {
    grid-template-columns: repeat(2, 1fr);
  }
  .sgf-grid-6 {
    grid-template-columns: repeat(3, 1fr);
  }
}
/* =============================================
   BENTO GRID
   ============================================= */
.sgf-bento {
  display: grid;
  gap: var(--sgf-space-4);
}
.sgf-bento__item {
  background: var(--sgf-color-surface);
  border: 1px solid var(--sgf-color-border);
  padding: var(--sgf-space-6);
  /* items should set grid-column and grid-row spans via inline style or modifier classes */
}
.sgf-bento {
  /* Preset bento layout (2 rows, 3 cols asymmetric) */
}
.sgf-bento--featured {
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: auto auto;
}
.sgf-bento--featured .sgf-bento__item:first-child {
  grid-column: span 2;
  grid-row: span 2;
}
@media (max-width: 767px) {
  .sgf-bento {
    grid-template-columns: 1fr !important;
  }
  .sgf-bento__item {
    grid-column: span 1 !important;
    grid-row: span 1 !important;
  }
}

/* =============================================
   MASONRY (CSS columns)
   ============================================= */
.sgf-masonry {
  columns: 3;
  column-gap: var(--sgf-space-6);
}
.sgf-masonry__item {
  break-inside: avoid;
  margin-bottom: var(--sgf-space-6);
}
.sgf-masonry--2col {
  columns: 2;
}
.sgf-masonry--4col {
  columns: 4;
}
@media (max-width: 1023px) {
  .sgf-masonry {
    columns: 2;
  }
  .sgf-masonry--4col {
    columns: 2;
  }
}
@media (max-width: 639px) {
  .sgf-masonry {
    columns: 1;
  }
  .sgf-masonry--2col, .sgf-masonry--4col {
    columns: 1;
  }
}

/* =============================================
   FLEX UTILITIES
   ============================================= */
.sgf-flex {
  display: flex;
}

.sgf-flex--center {
  align-items: center;
}

.sgf-flex--between {
  justify-content: space-between;
}

.sgf-flex--wrap {
  flex-wrap: wrap;
}

.sgf-flex--col {
  flex-direction: column;
}

.sgf-flex--gap-sm {
  gap: var(--sgf-space-3);
}

.sgf-flex--gap-md {
  gap: var(--sgf-space-5);
}

.sgf-flex--gap-lg {
  gap: var(--sgf-space-8);
}

/* =============================================
   ANNOUNCEMENT BAR
   ============================================= */
/* `hidden` TIENE QUE GANAR — 29 sep
   ---------------------------------
   El atributo `hidden` pone `display: none`, pero lo pone la hoja del
   NAVEGADOR, y cualquier `display` escrito por nosotros le gana. Con
   `--tarjeta { display: flex }`, el aviso que el visitante habia
   cerrado seguia ocupando sus 400x139 en la esquina, visible y
   clicable, en todas las paginas siguientes. Medido: `hidden` a true,
   `display` flex, opacidad 1.

   Va fuera del bloque y con `!important` a proposito: es una regla
   sobre un atributo de estado, y tiene que ganarle a cualquier
   `display` que se le ponga al componente hoy o dentro de un ano. */
.sgf-announcement-bar[hidden] {
  display: none !important;
}

.sgf-announcement-bar {
  position: relative;
  z-index: calc(var(--sgf-z-nav) + 1); /* always above nav */
  background: var(--sgf-color-accent);
  color: var(--sgf-color-bg);
  /* Aire lateral simetrico y suficiente para que el aspa tenga su
     hueco a la derecha sin descentrar el texto. */
  padding: var(--sgf-space-2) var(--sgf-space-9);
  text-align: center;
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wide);
  line-height: 1.4;
  overflow: hidden;
  /* Slide-up animation when dismissed */
  max-height: 60px;
  transition: max-height var(--sgf-duration-base) var(--sgf-ease-out), padding var(--sgf-duration-base) var(--sgf-ease-out), opacity var(--sgf-duration-fast);
}
.sgf-announcement-bar.is-dismissed {
  max-height: 0;
  padding-block: 0;
  opacity: 0;
  pointer-events: none;
}
.sgf-announcement-bar__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sgf-space-4);
  max-width: 1280px;
  margin-inline: auto;
}
.sgf-announcement-bar {
  /* `flex: 0 1 auto` y no `flex: 1`.
     Con `flex: 1` el parrafo se quedaba con todo el ancho libre y
     empujaba el enlace contra el borde derecho: la pareja texto +
     enlace quedaba 49px a la izquierda del centro de la barra, que es
     justo lo que no se ve mirando pero canta al medirlo. Sin crecer,
     los dos se centran juntos como el grupo que son. */
}
.sgf-announcement-bar__text {
  flex: 0 1 auto;
  text-align: center;
}
.sgf-announcement-bar__text a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.sgf-announcement-bar__text a:hover {
  opacity: 0.8;
}
.sgf-announcement-bar {
  /* El aspa va SIEMPRE superpuesta, no en el flujo.
     Puesta en el flujo caia debajo del texto centrado, a 24px de lado
     y clipada por el `overflow: hidden` de la barra. Superpuesta al
     margen derecho se lee donde todo el mundo la busca, y los 44px de
     zona pulsable son el minimo para un dedo aunque el aspa dibuje 16.
     El aire lateral de la barra (space-9) le reserva el hueco, asi que
     el texto nunca se le mete debajo. */
}
.sgf-announcement-bar__close {
  position: absolute;
  top: 50%;
  right: var(--sgf-space-2);
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  padding: 0;
  opacity: 0.7;
  line-height: 1;
  transition: opacity var(--sgf-duration-fast);
}
.sgf-announcement-bar__close:hover {
  opacity: 1;
}
.sgf-announcement-bar {
  /* Variant: dark/surface background */
}
.sgf-announcement-bar--muted {
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border-bottom: 1px solid var(--sgf-color-border);
}
.sgf-announcement-bar {
  /* --------------------------------------------------------------
     TARJETA FLOTANTE
     Las tres posiciones que no son «bajo la navegacion» comparten
     forma: una tarjeta con la foto a la izquierda, el texto arriba y
     el enlace abajo. Bajo la navegacion sigue siendo la banda fina de
     siempre, que es otra cosa y no lleva nada de esto.
     -------------------------------------------------------------- */
}
.sgf-announcement-bar--tarjeta {
  position: fixed;
  z-index: var(--sgf-z-toast);
  display: flex;
  align-items: stretch;
  width: min(400px, 100vw - var(--sgf-space-6));
  padding: 0; /* el aire lo pone el lado del texto */
  text-align: left;
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border: 1px solid var(--sgf-color-border);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.14);
  /* La banda se recoge con `max-height`, que aqui no sirve: la
     tarjeta es mucho mas alta y el valor fijo la recortaria. Se
     esconde desplazandola y apagandola. */
  max-height: none;
  transition: opacity var(--sgf-duration-base) var(--sgf-ease-out), transform var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-announcement-bar--tarjeta.is-dismissed {
  opacity: 0;
  transform: translateY(var(--sgf-space-4));
  padding: 0;
}
.sgf-announcement-bar {
  /* La foto, a sangre contra el borde de la tarjeta y con un ancho
     fijo: si se le deja crecer, una foto apaisada se come el texto. */
}
.sgf-announcement-bar__media {
  flex: none;
  width: 108px;
  overflow: hidden;
  background: var(--sgf-color-bg-alt);
}
.sgf-announcement-bar__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sgf-announcement-bar--tarjeta .sgf-announcement-bar__inner {
  flex-direction: column;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sgf-space-4);
  /* Hueco a la derecha para el aspa, que va superpuesta. Sin el, el
     texto largo se mete debajo del boton. */
  padding: var(--sgf-space-4) var(--sgf-space-6) var(--sgf-space-4) var(--sgf-space-4);
  max-width: none;
  margin-inline: 0;
  min-width: 0; /* deja que el texto se parta */
}
.sgf-announcement-bar--tarjeta .sgf-announcement-bar__text {
  flex: 0 1 auto;
  text-align: left;
  text-transform: uppercase;
  letter-spacing: var(--sgf-tracking-wide);
  line-height: 1.5;
}
.sgf-announcement-bar {
  /* Subrayado de puntos: separa el enlace del texto de encima sin
     tener que subirle el peso ni cambiarle el color. */
  /* Viene como `<a>` cuando lleva a una página y como `<button>`
     cuando abre la ventana del correo (`#newsletter` en el panel). Los
     dos tienen que verse igual, así que aquí se le quita al botón la
     piel que le pone el navegador. */
}
.sgf-announcement-bar__cta {
  appearance: none;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  align-self: flex-start;
  color: inherit;
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 6px;
  transition: opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-announcement-bar__cta:hover {
  opacity: 0.6;
}
.sgf-announcement-bar {
  /* EL ASPA SE IBA 22PX HACIA ARRIBA — 3 oct
     =========================================
     La regla base centra el aspa en la banda con el par `top: 50%` +
     `transform: translateY(-50%)`. Esta variante cambiaba el `top` a
     8px y se dejaba el `transform`, así que el botón bajaba al 8 y
     volvía a subir 22. Medido: el aspa empezaba 13px POR ENCIMA del
     borde de la tarjeta, y el `overflow: hidden` de la tarjeta se
     comía lo que sobresalía.

     Un par que posiciona junto se cambia junto. Si se toca el `top`
     hay que decir qué pasa con el `transform`, aunque sea para
     anularlo.

     Lo demás que había aquí —`position`, `display`, `width`,
     `height`, los centrados— era copia exacta de la regla base. Una
     variante dice en qué se diferencia, no lo repite todo: mientras
     lo repetía, el día que cambie el tamaño del botón habría que
     acordarse de los dos sitios. */
}
.sgf-announcement-bar--tarjeta .sgf-announcement-bar__close {
  top: 0;
  right: 0;
  transform: none;
  /* El aspa a 8px de las dos esquinas, que es donde se busca en una
     tarjeta pequeña. Lo que se mueve es el dibujo dentro del botón,
     con el relleno: la zona pulsable sigue midiendo 44 y creciendo
     hacia dentro, que es espacio muerto de la tarjeta. */
  align-items: flex-start;
  justify-content: flex-end;
  padding: var(--sgf-space-2);
  opacity: 0.55;
}
.sgf-announcement-bar {
  /* Abajo: la tarjeta centrada contra el borde inferior. */
}
.sgf-announcement-bar[data-place=bottom] {
  bottom: var(--sgf-space-4);
  left: 50%;
  transform: translateX(-50%);
}
.sgf-announcement-bar[data-place=bottom].is-dismissed {
  transform: translateX(-50%) translateY(var(--sgf-space-4));
}
.sgf-announcement-bar[data-place=left] {
  bottom: var(--sgf-space-4);
  left: var(--sgf-space-4);
}
.sgf-announcement-bar[data-place=right] {
  bottom: var(--sgf-space-4);
  right: var(--sgf-space-4);
}
.sgf-announcement-bar {
  /* En un movil de 375 no caben 108px de foto y un texto legible al
     lado. La foto se va y queda la tarjeta de texto, que es lo que
     tiene que leerse. */
}
@media (max-width: 480px) {
  .sgf-announcement-bar {
    /* En movil la barra de arriba no puede gastar 64px por lado: el
       texto se quedaria en una columna de nada. El aspa sigue cabiendo
       en los 48.

       Acotado a `top` a proposito. Sin el selector esto tambien caia
       sobre la tarjeta, que lleva `padding: 0` porque su aire lo pone
       el lado del texto: le metia 48px por banda y en un movil de 375
       se comia 96 de los 351, dejando el texto empezando en el pixel
       73. Misma especificidad y escrito despues, ganaba en silencio. */
  }
  .sgf-announcement-bar[data-place=top] {
    padding-inline: var(--sgf-space-7);
  }
  .sgf-announcement-bar--tarjeta {
    width: calc(100vw - var(--sgf-space-4));
  }
  .sgf-announcement-bar--tarjeta .sgf-announcement-bar__media {
    display: none;
  }
}

/* EL AVISO SE APILA SOBRE LAS COOKIES — 29 sep, revisado el 2 oct
   ---------------------------------------------------------------
   `.sgf-cookies` y la tarjeta viven las dos en `bottom: 24px` con el
   mismo `z-index`, y el cliente puede ponerlas en el mismo lado. El
   choque no era posible: era seguro. Medido en un movil de 375, se
   solapaban por completo y no se leia ninguna de las dos.

   LA PRIMERA SOLUCION APAGABA LA TARJETA, Y ERA PEOR DE LO QUE PARECIA

   El razonamiento era que la promocion puede esperar veinte segundos a
   que alguien responda al aviso. Pero el aviso NO SE CIERRA SOLO: no
   hay aspa, ni temporizador, ni cierre al hacer scroll — solo
   «Aceptar» y «Solo necesarias». Asi que para quien lo ignora, que es
   mucha gente, la tarjeta no esperaba veinte segundos: no aparecia
   nunca, en ninguna visita. Y en desarrollo, con almacenamiento
   limpio, era permanentemente invisible.

   Ademas se apagaba SIEMPRE, incluso con la tarjeta en el lado
   contrario al aviso, donde no se tocan.

   AHORA SE APILA, Y SOLO CUANDO DE VERDAD CHOCAN

   La tarjeta sube por encima del aviso lo que mida el aviso. El alto
   lo publica el modulo de cookies en `--sgf-cookies-alto`, medido, no
   fijado a ojo: depende del texto, del idioma y del ancho.

   Se mueve con `transform`, que es una de las dos propiedades que la
   tarjeta ya tiene en transicion, asi que sube y baja con su animacion
   en vez de dar un salto. El valor de reserva cubre el instante entre
   que el aviso se pinta y el JS lo mide.

   `:has()` y no una clase puesta por JS: el componente se apaña
   mirando lo que hay en la pagina. El tema ya usa `:has()` en los
   filtros. */
/* Mismo lado, izquierda: el aviso va a la izquierda salvo que se le
   diga lo contrario. */
html:has(.sgf-cookies.is-open:not([data-side=right])) .sgf-announcement-bar--tarjeta[data-place=left] {
  transform: translateY(calc(-1 * (var(--sgf-cookies-alto, 180px) + var(--sgf-space-3))));
}

/* Mismo lado, derecha. */
html:has(.sgf-cookies.is-open[data-side=right]) .sgf-announcement-bar--tarjeta[data-place=right] {
  transform: translateY(calc(-1 * (var(--sgf-cookies-alto, 180px) + var(--sgf-space-3))));
}

/* Centrada abajo. Solo se aparta donde no caben las dos en una fila:
   el aviso son 320px y la tarjeta 400px, asi que por debajo de ~900px
   se tocan. Por encima conviven sin estorbarse y moverla seria un
   salto gratuito. */
@media (max-width: 900px) {
  html:has(.sgf-cookies.is-open) .sgf-announcement-bar--tarjeta[data-place=bottom] {
    transform: translateX(-50%) translateY(calc(-1 * (var(--sgf-cookies-alto, 180px) + var(--sgf-space-3))));
  }
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
  .sgf-announcement-bar {
    transition: none;
  }
}
/* =============================================
   HEADER: TRANSPARENT VIA BODY CLASS
   Applied by sgf_landing_body_class() in
   inc/template-functions.php on the Landing
   Page template. JS adds .is-scrolled on scroll.
   ============================================= */
body.has-transparent-header .sgf-site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  width: 100%;
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
}
body.has-transparent-header .sgf-site-header.is-search-open {
  background: var(--sgf-color-bg);
  border-bottom-color: var(--sgf-color-border);
}
body.has-transparent-header .sgf-site-header {
  /* La tira utilitaria ya NO se repinta aquí. Pasó por tres sitios
     —beis en la regla base, granate dentro de `.is-scrolled`, granate
     para toda la cabecera transparente— y cada paso dejaba el color
     escrito en un lugar más. Ahora está una sola vez, en la regla base
     de `layouts/_header.scss`, que es la que vale para todo el sitio.
     Una excepción aquí volvería a partir el color en dos. */
}
body.has-transparent-header .sgf-site-header.is-scrolled {
  background: var(--sgf-color-bg);
  border-bottom-color: var(--sgf-color-border);
  box-shadow: none;
}

body.has-transparent-header .sgf-hero--editorial {
  margin-top: var(--sgf-overlay-utility, var(--sgf-header-utility));
  height: calc(100vh - var(--sgf-overlay-utility, var(--sgf-header-utility)));
}

body.has-transparent-header .sgf-promo-bar {
  position: fixed;
  left: 0;
  right: 0;
  top: var(--sgf-overlay-header, calc(var(--sgf-header-utility) + var(--sgf-header-primary)));
  z-index: var(--sgf-z-nav);
  background: transparent;
  border-bottom-color: transparent;
  transition: background var(--sgf-duration-base) var(--sgf-ease-out), border-color var(--sgf-duration-base) var(--sgf-ease-out);
}
body.has-transparent-header .sgf-promo-bar.is-scrolled {
  background: var(--sgf-color-bg);
  border-bottom-color: var(--sgf-color-border);
}

html.search-open .sgf-promo-bar,
html.search-open body.has-transparent-header .sgf-promo-bar {
  visibility: hidden;
  opacity: 0;
  pointer-events: none;
}

body.has-transparent-header .sgf-hero--editorial .sgf-hero__copy {
  padding-top: calc(var(--sgf-overlay-chrome, 112px) + var(--sgf-space-6));
}

/* =============================================
   HEADER: TRANSPARENT / OVERLAY
   Used on hero landing pages where the header
   sits over an image or dark background.
   PHP adds class="sgf-site-header--transparent"
   via body_class or template logic.
   ============================================= */
.sgf-site-header--transparent {
  background: transparent;
  border-bottom-color: transparent;
  box-shadow: none;
  /* When scrolled, fade in a solid background */
}
.sgf-site-header--transparent.is-scrolled {
  background: var(--sgf-color-bg);
  border-bottom-color: var(--sgf-color-border);
  box-shadow: 0 1px 0 var(--sgf-color-border);
}

/* Transparent + light text (for dark hero backgrounds) */
.sgf-site-header--transparent-light {
  --sgf-nav-text: hsl(0 0% 96%); /* override in template — light text */
  background: transparent;
  border-bottom-color: transparent;
}
.sgf-site-header--transparent-light .sgf-nav__link,
.sgf-site-header--transparent-light .sgf-nav__toggle,
.sgf-site-header--transparent-light .sgf-nav__cart,
.sgf-site-header--transparent-light .sgf-nav__logo {
  color: var(--sgf-nav-text);
}
.sgf-site-header--transparent-light.is-scrolled {
  background: var(--sgf-color-bg);
  --sgf-nav-text: var(--sgf-color-text);
  border-bottom-color: var(--sgf-color-border);
}

/* Smooth background transition on scroll */
.sgf-site-header {
  transition: background var(--sgf-duration-base) var(--sgf-ease-out), border-color var(--sgf-duration-base) var(--sgf-ease-out), box-shadow var(--sgf-duration-base) var(--sgf-ease-out), transform var(--sgf-duration-base) var(--sgf-ease-out);
}

/* =============================================
   HEADER: STICKY — HIDE ON SCROLL DOWN,
   SHOW ON SCROLL UP
   JS adds/removes .is-hidden class.
   ============================================= */
.sgf-site-header--sticky-smart {
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out), background var(--sgf-duration-base) var(--sgf-ease-out), border-color var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-site-header--sticky-smart.is-hidden {
  transform: translateY(-100%);
}

/* =============================================
   HEADER: MINIMAL (checkout, landing, focus)
   No nav links. Just logo + optional single CTA.
   ============================================= */
.sgf-site-header--minimal {
  border-bottom: 1px solid var(--sgf-color-border);
}
.sgf-site-header--minimal .sgf-nav__menu,
.sgf-site-header--minimal .sgf-nav__toggle,
.sgf-site-header--minimal .sgf-nav__cart {
  display: none;
}
.sgf-site-header--minimal .sgf-nav__logo {
  grid-column: 2;
  margin-inline: auto;
}
.sgf-site-header--minimal {
  /* Optional: one CTA button visible on right */
}
.sgf-site-header--minimal .sgf-nav__cta {
  display: flex;
  margin-left: auto;
}

/* Show CTA in normal nav too (hidden by default) */
.sgf-nav__cta {
  display: none;
  align-items: center;
}

/* La cabecera se pega arriba. El aviso va dentro, así que
   no hay que empujar el contenido ni dejar un hueco. */
.sgf-site-header {
  transition: top var(--sgf-duration-base) var(--sgf-ease-out), background var(--sgf-duration-base) var(--sgf-ease-out), border-color var(--sgf-duration-base) var(--sgf-ease-out), transform var(--sgf-duration-base) var(--sgf-ease-out);
}

/* =============================================
   HEADER: CENTERED LOGO (editorial/brand)
   Logo is centered, nav splits left/right.
   ============================================= */
.sgf-site-header--centered .sgf-nav {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
}
.sgf-site-header--centered .sgf-nav__logo {
  grid-column: 2;
  order: 0;
}
.sgf-site-header--centered .sgf-nav__menu {
  grid-column: 1;
  justify-content: flex-start;
  order: -1;
}
.sgf-site-header--centered .sgf-nav__actions {
  grid-column: 3;
  justify-content: flex-end;
}
@media (max-width: 1023px) {
  .sgf-site-header--centered {
    /* collapse to standard mobile on small screens */
  }
  .sgf-site-header--centered .sgf-nav {
    display: flex;
    justify-content: space-between;
  }
}

/* =============================================
   REDUCED MOTION
   ============================================= */
@media (prefers-reduced-motion: reduce) {
  .sgf-site-header,
  .sgf-site-header--transparent,
  .sgf-site-header--sticky-smart {
    transition: none;
  }
}
/* =============================================
   SGF SITE FOOTER
   ============================================= */
/* EL PIE ES UNA SUPERFICIE INVERTIDA — 1 oct
   ==========================================
   Sobre un fondo oscuro no vale con poner el texto blanco: dentro del
   pie hay titulares, enlaces, texto apagado, separadores y los campos
   del boletín, y todos piden `--sgf-color-text`, `--sgf-color-muted` o
   `--sgf-color-border`. Esos tres valen lo que valen para fondo claro:
   sobre el granate, el texto se vuelve ilegible y las líneas
   desaparecen.

   Se podría ir pieza por pieza pintando cada una de blanco. Serían
   unas quince reglas nuevas, y la decimosexta que alguien añada el año
   que viene nacería rota sin que nadie se entere.

   Así que lo que se invierte es el SUELO: aquí dentro, «texto»
   significa el claro del pie, «apagado» significa ese claro a media
   asta y «borde» ese claro muy tenue. Todo lo que ya usaba los tokens
   —y lo usa todo— se arregla solo, incluido lo que se escriba después.

   Ojo, esto tiene que declararse AQUÍ y no en `:root`: un token
   derivado se congela en el elemento donde se declara, así que ponerlo
   arriba no lo recalcularía al cambiar el fondo. */
.sgf-site-footer {
  /* EL FONDO TAMBIÉN SE INVIERTE, Y NO ES OPCIONAL
     ----------------------------------------------
     La primera versión invirtió `text`, `muted`, `border` y
     `control` y se dejó `bg` y `surface`. El botón «Suscríbete» es
     `.sgf-btn--ghost`, que se pinta `--btn-bg: var(--sgf-color-bg)` y
     `--btn-fg: var(--sgf-color-text)`: se quedó con su fondo CREMA y
     el texto ya invertido a BLANCO. Medido en pantalla: 1,05:1.
     Ilegible.

     Aquí dentro «el fondo» tiene que significar el fondo DE AQUÍ. Si
     se invierte medio conjunto, lo que se rompe es justo lo que se
     pinta su propio fondo, que es lo que uno no mira. */
  --sgf-color-bg: var(--sgf-color-ink);
  --sgf-color-surface: var(--sgf-color-ink);
  --sgf-color-text: var(--sgf-color-ink-fg);
  --sgf-color-muted: color-mix(in srgb, var(--sgf-color-ink-fg) 62%, transparent);
  --sgf-color-border: color-mix(in srgb, var(--sgf-color-ink-fg) 20%, transparent);
  --sgf-color-control: color-mix(in srgb, var(--sgf-color-ink-fg) 34%, transparent);
  background: var(--sgf-color-ink);
  color: var(--sgf-color-ink-fg);
  border-top: 1px solid var(--sgf-color-border);
  padding-top: var(--sgf-space-16);
  padding-bottom: var(--sgf-space-8);
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
}

.sgf-footer__inner {
  width: 100%;
  max-width: none;
  margin-inline: 0;
  padding-inline: var(--sgf-gutter);
}
@media (max-width: 899px) {
  .sgf-footer__inner {
    padding-inline: var(--sgf-space-3);
  }
}

/* -----------------------------------------------
   NEWSLETTER BAND
   ----------------------------------------------- */
.sgf-footer__newsletter-band {
  padding-bottom: var(--sgf-space-16);
  margin-bottom: var(--sgf-space-12);
  border-bottom: 1px solid var(--sgf-color-border);
}

.sgf-footer__nl {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-8);
}
@media (max-width: 767px) {
  .sgf-footer__nl {
    flex-direction: column;
    align-items: stretch;
  }
}

.sgf-footer__nl-copy {
  min-width: 0;
}

.sgf-footer__nl-title {
  margin: 0;
  /* El unico texto del pie que es una FRASE y no un rotulo, asi que
     lleva peso de prosa (400) y no el del mobiliario. Es lo que lo
     separa del boton que tiene al lado: los dos decian 16px y uno
     400 y el otro 500, sin que nada explicara por que. */
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xl);
  font-weight: 400;
  line-height: var(--sgf-lead-xl);
  letter-spacing: var(--sgf-track-xl);
  color: var(--sgf-color-text);
  /* SIN `max-width` — 30 sep
     -----------------------
     Tenia 36ch, o sea unos 36 caracteres. La frase tiene 47, asi que
     partia SIEMPRE en dos lineas por mucho sitio que hubiera a la
     derecha: al lado del boton quedaban cientos de pixeles vacios y
     la unica oferta del pie se leia en dos trozos.

     La medida de lectura es para PARRAFOS, donde el ojo tiene que
     volver al renglon siguiente. Aqui no hay renglon siguiente: es
     una linea sola. Toparla no protegia nada, solo la rompia.

     Quien limita el ancho ahora es el flex del banner, que es quien
     sabe cuanto sitio deja el boton. */
}
@media (max-width: 767px) {
  .sgf-footer__nl-title {
    /* Ahi el banner ya apila y no hay ancho para 47 caracteres a
       24px: baja un escalon y parte donde toque. */
    font-size: var(--sgf-text-lg);
    line-height: var(--sgf-lead-lg);
    letter-spacing: var(--sgf-track-lg);
  }
}

.sgf-footer__nl-open {
  flex-shrink: 0;
}

/* -----------------------------------------------
   COLUMNS
   ----------------------------------------------- */
/* TANTAS COLUMNAS COMO MENÚS — 3 oct
   ==================================
   Esto era `repeat(3, …)` fijo, y las columnas no son fijas: cada una
   sale solo si su menú está asignado (lo decide `footer-nav.php`). Con
   dos menús quedaba un carril vacío de 274px a la derecha, dentro del
   granate, que se lee como que algo no ha cargado.

   Mismo arreglo que la barra de añadas del 2 de octubre y por el mismo
   motivo: una rejilla que fija el número de carriles obliga a que el
   contenido se adapte a ella, cuando es al revés. Se cuentan con
   `:has()` —gana la última que encaja, y cada una pide «al menos N»—
   para que lo decida el CSS y no haya que pasarle la cuenta desde la
   plantilla. */
.sgf-footer__top {
  display: grid;
  grid-template-columns: repeat(1, minmax(0, 1fr));
  gap: var(--sgf-space-10);
  /* Era space-16. El aire de debajo de las columnas lo daba el blanco
     de la página; sobre el granate ese hueco se ve como un bloque de
     color vacío, y pesa. */
  padding-bottom: var(--sgf-space-8);
}
@media (max-width: 767px) {
  .sgf-footer__top {
    grid-template-columns: 1fr;
    gap: var(--sgf-space-8);
  }
}

.sgf-footer__top:has(> .sgf-footer__col:nth-child(2)) {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.sgf-footer__top:has(> .sgf-footer__col:nth-child(3)) {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* En móvil siempre una columna, pase lo que pase arriba: las reglas de
   `:has()` pesan más que la media query de dentro del bloque, así que
   hay que repetirla aquí o el pie saldría a dos columnas en el móvil. */
@media (max-width: 767px) {
  .sgf-footer__top:has(> .sgf-footer__col:nth-child(2)),
  .sgf-footer__top:has(> .sgf-footer__col:nth-child(3)) {
    grid-template-columns: 1fr;
  }
}
.sgf-footer__col--nav {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-5);
}

.sgf-footer__col-title {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-lg);
  line-height: var(--sgf-lead-lg);
  letter-spacing: var(--sgf-track-lg);
  text-transform: none;
  color: var(--sgf-color-text);
}

.sgf-menu-item--sin-enlace {
  color: var(--sgf-color-muted);
  cursor: default;
}

.sgf-footer__menu {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.sgf-footer__menu li a {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  color: var(--sgf-color-text);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}

/* -----------------------------------------------
   BOTTOM
   ----------------------------------------------- */
.sgf-footer__bottom {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sgf-space-4);
  padding-top: var(--sgf-space-8);
  border-top: 1px solid var(--sgf-color-border);
}
@media (max-width: 767px) {
  .sgf-footer__bottom {
    grid-template-columns: 1fr;
    justify-items: start;
    gap: var(--sgf-space-3);
  }
}

.sgf-footer__legal {
  margin: 0;
  justify-self: end;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
}
@media (max-width: 767px) {
  .sgf-footer__legal {
    justify-self: start;
  }
}

.sgf-footer__legal-menu {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  gap: var(--sgf-space-4);
  flex-wrap: wrap;
}
.sgf-footer__legal-menu li a {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}

.sgf-footer__social--texto {
  display: flex;
  gap: var(--sgf-space-4);
  flex-wrap: wrap;
  justify-content: center;
}
.sgf-footer__social--texto .sgf-footer__social-link {
  width: auto;
  height: auto;
  padding: 0;
  border: 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
@media (max-width: 767px) {
  .sgf-footer__social--texto {
    justify-content: flex-start;
  }
}

/* Iconos: solo la variante mínima los sigue usando. */
.sgf-footer__social:not(.sgf-footer__social--texto) {
  display: flex;
  gap: var(--sgf-space-3);
  flex-wrap: wrap;
}

.sgf-footer__social:not(.sgf-footer__social--texto) .sgf-footer__social-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  color: var(--sgf-color-muted);
  border: 1px solid var(--sgf-color-control);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-footer__social:not(.sgf-footer__social--texto) .sgf-footer__social-link:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-footer__social:not(.sgf-footer__social--texto) .sgf-footer__social-link:hover {
    border-color: var(--sgf-color-text);
    background: color-mix(in srgb, var(--sgf-color-text) 6%, transparent);
  }
}
@media (hover: hover) and (pointer: fine) {
  .sgf-footer__social:not(.sgf-footer__social--texto) .sgf-footer__social-link:hover {
    color: var(--sgf-color-text);
  }
}

.sgf-footer__logo {
  display: inline-block;
  text-decoration: none;
  color: var(--sgf-color-text);
}

.sgf-footer__logo-img {
  height: 28px;
  width: auto;
  max-width: 160px;
  object-fit: contain;
}

.sgf-footer__logo-text {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
}

.sgf-footer__tagline {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  color: var(--sgf-color-muted);
  max-width: 28ch;
}

@media (hover: hover) and (pointer: fine) {
  .sgf-footer__top:has(a:hover) a {
    color: var(--sgf-color-muted);
  }
  .sgf-footer__top:has(a:hover) a:hover {
    color: var(--sgf-color-text);
  }
  .sgf-footer__bottom:has(a:hover) a {
    color: var(--sgf-color-muted);
  }
  .sgf-footer__bottom:has(a:hover) a:hover {
    color: var(--sgf-color-text);
  }
}
.sgf-nl {
  position: fixed;
  inset: 0;
  z-index: calc(var(--sgf-z-nav) + 1);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sgf-space-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-nl.is-open {
  opacity: 1;
  pointer-events: auto;
}
.sgf-nl .sgf-nl__dialog {
  transform: scale(0.96);
  transform-origin: center;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-nl.is-open .sgf-nl__dialog {
  transform: none;
}
.sgf-nl[hidden] {
  display: none;
}

.sgf-nl__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
}

.sgf-nl__dialog {
  position: relative;
  z-index: 1;
  width: min(440px, 100%);
  padding: var(--sgf-space-8) var(--sgf-space-6) var(--sgf-space-6);
  background: var(--sgf-color-bg);
}
.sgf-nl__dialog:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}

.sgf-nl__close {
  position: absolute;
  top: var(--sgf-space-4);
  right: var(--sgf-space-4);
  display: flex;
  padding: 0;
  background: none;
  border: 0;
  color: var(--sgf-color-text);
  cursor: pointer;
}

.sgf-nl__title {
  margin: 0 32px 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-lg);
  font-weight: 500;
  line-height: var(--sgf-lead-lg);
  letter-spacing: var(--sgf-track-lg);
  color: var(--sgf-color-text);
}

.sgf-nl__text {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: 400;
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  color: var(--sgf-color-muted);
}

.sgf-nl__form {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-3);
  margin: var(--sgf-space-5) 0 0;
}
.sgf-nl__form .sgf-input,
.sgf-nl__form input[type=email] {
  width: 100%;
  height: 48px;
  padding-inline: var(--sgf-space-3);
  font-family: var(--sgf-font-body);
  /* 16px CLAVADOS y no el tamano del mobiliario: por debajo de
     16, Safari en iPhone hace zoom al enfocar el campo y deja la
     pagina descuadrada. */
  font-size: 16px;
  background: var(--sgf-color-bg);
  border: 1px solid var(--sgf-color-control);
  border-radius: 2px;
  box-shadow: none;
}
.sgf-nl__form .sgf-input:focus,
.sgf-nl__form input[type=email]:focus {
  border-color: var(--sgf-color-text);
  outline: none;
}
.sgf-nl__form .sgf-nl__submit {
  width: 100%;
  height: 48px;
  font-size: var(--sgf-chrome-size);
}

.sgf-nl__legal {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  font-weight: 400;
  color: var(--sgf-color-muted);
}
.sgf-nl__legal a {
  color: var(--sgf-color-text);
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

body.sgf-nl-abierto {
  overflow: hidden;
}

.sgf-site-footer--minimal {
  padding-block: var(--sgf-space-6);
}
.sgf-site-footer--minimal .sgf-footer__inner--minimal {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-6);
  flex-wrap: wrap;
}
@media (max-width: 639px) {
  .sgf-site-footer--minimal .sgf-footer__inner--minimal {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
}

.sgf-place {
  position: fixed;
  inset: 0;
  z-index: calc(var(--sgf-z-nav) + 2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sgf-space-4);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-place.is-open {
  opacity: 1;
  pointer-events: auto;
}
.sgf-place .sgf-place__dialog {
  transform: scale(0.96);
  transform-origin: center;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-place.is-open .sgf-place__dialog {
  transform: none;
}
.sgf-place[hidden] {
  display: none;
}

.sgf-place__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
}

.sgf-place__dialog {
  position: relative;
  z-index: 1;
  width: min(440px, 100%);
  padding: var(--sgf-space-8) var(--sgf-space-6) var(--sgf-space-6);
  background: var(--sgf-color-bg);
}
.sgf-place__dialog:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}

.sgf-place__flag {
  margin: 0 0 var(--sgf-space-4);
  font-size: 22px;
  line-height: 1;
}

.sgf-place__close {
  position: absolute;
  top: var(--sgf-space-4);
  right: var(--sgf-space-4);
  display: flex;
  padding: 0;
  background: none;
  border: 0;
  color: var(--sgf-color-text);
  cursor: pointer;
}

.sgf-place__title {
  margin: 0 32px 0 0;
  font-family: var(--sgf-font-body);
  font-size: 18px;
  font-weight: 500;
  line-height: 24px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--sgf-color-text);
}

.sgf-place__text {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  font-weight: 400;
  line-height: 20px;
  color: var(--sgf-color-muted);
}

.sgf-place__form {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-4);
  margin: var(--sgf-space-5) 0 0;
}

.sgf-place__row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sgf-space-3);
}
@media (max-width: 479px) {
  .sgf-place__row {
    grid-template-columns: minmax(0, 1fr);
  }
}

.sgf-place__field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-family: var(--sgf-font-body);
  font-size: 13px;
  font-weight: 400;
  line-height: 18px;
  color: var(--sgf-color-muted);
}
.sgf-place__field select {
  width: 100%;
  height: 48px;
  padding: 0 36px 0 var(--sgf-space-3);
  font-family: var(--sgf-font-body);
  font-size: 16px;
  font-weight: 400;
  color: var(--sgf-color-text);
  background-color: var(--sgf-color-bg);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path fill='none' stroke='%23111111' stroke-width='1.2' d='M1 1.5L6 6.5L11 1.5'/></svg>");
  background-repeat: no-repeat;
  background-position: right 12px center;
  border: 1px solid var(--sgf-color-control);
  border-radius: 2px;
  box-shadow: none;
  appearance: none;
}
.sgf-place__field select:focus {
  border-color: var(--sgf-color-text);
  outline: none;
}

.sgf-place__go {
  width: 100%;
  height: 48px;
  font-size: var(--sgf-text-sm);
}

.sgf-place__money {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: 13px;
  line-height: 18px;
  color: var(--sgf-color-muted);
}

body.sgf-place-abierto {
  overflow: hidden;
}
body.sgf-place-abierto .sgf-cookies {
  display: none;
}

@view-transition {
  navigation: auto;
}
@keyframes sgf-page-out {
  to {
    opacity: 0;
    transform: translateY(-10px);
  }
}
@keyframes sgf-page-in {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}
::view-transition-old(root) {
  animation: sgf-page-out var(--sgf-duration-slow) var(--sgf-ease-out) both;
}

::view-transition-new(root) {
  animation: sgf-page-in var(--sgf-duration-slower) var(--sgf-ease-out) both;
}

html.sgf-is-leaving .sgf-site-content {
  opacity: 0;
  transform: translateY(-10px);
  pointer-events: none;
  transition: opacity var(--sgf-duration-slow) var(--sgf-ease-out), transform var(--sgf-duration-slow) var(--sgf-ease-out);
}

/* LA ENTRADA ES UNA ANIMACIÓN, NO DOS CLASES — 1 oct
   =================================================
   Esto dejaba la web EN BLANCO. Lo reproduje: cualquier página que
   cargara con la marca `sgf_go` puesta se quedaba con
   `opacity: 0` para siempre. Cabecera visible, contenido invisible.
   Es lo que pasaba al cerrar sesión, y no era del logout: pasaba en
   cualquier navegación que usara el camino de JavaScript.

   EL MECANISMO QUE FALLABA
   ------------------------
   Eran dos clases y un baile entre ellas: PHP ponía `sgf-is-entering`
   (contenido a cero) y `page.js` añadía `sgf-is-ready` dentro de dos
   `requestAnimationFrame` para dispararlo. Medido en el navegador:
   los dos `rAF` NO LLEGABAN A EJECUTARSE —el navegador suspende el
   pintado durante una transición de vista, y si esa transición se
   aborta, nunca vuelve a llamarlos—. Sin segundo fotograma no hay
   segunda clase, y sin segunda clase el contenido no vuelve.

   POR QUÉ ESTO NO SE PUEDE ARREGLAR CON UN TEMPORIZADOR
   ----------------------------------------------------
   Se podría añadir un `setTimeout` de red de seguridad y taparlo.
   Pero el problema de fondo es que el estado VISIBLE —el normal, el
   que tiene que ganar siempre— dependía de que un script llegara a
   ejecutarse. Eso es al revés: lo que puede fallar es el adorno, no
   el contenido.

   Una animación con `both` empieza en cero y TERMINA EN EL VALOR
   NATURAL ella sola. No hay segunda clase que añadir, no hay script
   del que depender y no hay forma de quedarse a medias: si el
   navegador no anima, pinta el estado final, que es el contenido
   visible. El fallo deja de existir en vez de quedar vigilado.

   `sgf-is-ready` ya no existe. Si aparece en algún sitio, es resto. */
html.sgf-is-entering .sgf-site-content {
  animation: sgf-page-in var(--sgf-duration-slower) var(--sgf-ease-out) both;
}

@media (prefers-reduced-motion: reduce) {
  @view-transition {
    navigation: none;
  }
  html.sgf-is-leaving .sgf-site-content,
  html.sgf-is-entering .sgf-site-content {
    opacity: 1;
    transform: none;
    transition: none;
    animation: none;
  }
}
/*--------------------------------------------------------------
# Components
--------------------------------------------------------------*/
/* Navigation
--------------------------------------------- */
/* La cabecera se posiciona en layouts/_header.scss, con `sticky`.
   Aqui habia una SEGUNDA definicion con `fixed`, del theme anterior, y
   ganaba por venir despues en el orden de importacion. Con `fixed` la
   cabecera sale del flujo: la barra promocional de debajo se pintaba
   detras de ella, a la misma altura, y no se veia.

   `sticky` se queda arriba igual al desplazar, pero sigue ocupando su
   sitio, que es lo que necesita cualquier cosa que venga detras. */
.sgf-nav__logo {
  flex-shrink: 0;
  z-index: 1;
}
.sgf-nav__logo a {
  display: block;
  text-decoration: none;
}
.sgf-nav__logo img,
.sgf-nav__logo svg {
  height: clamp(24px, 3.5vw, 40px);
  width: auto;
  display: block;
}

.sgf-nav__site-name {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-xl);
  color: var(--sgf-nav-color);
  text-decoration: none;
  letter-spacing: var(--sgf-tracking-tight);
}

/* EL CAJÓN, TAMBIÉN EN ESCRITORIO — 1 oct
   =======================================
   Vivía solo bajo 1024px. Lo de dentro —las categorías con su
   contador, las experiencias, las últimas del diario— no es menos útil
   en una pantalla grande: era que no había por dónde abrirlo.

   En móvil ocupa la pantalla entera porque ahí no hay nada más que
   mirar. En escritorio sale del lateral y deja ver la página debajo:
   a 1440px un panel a sangre sería un portazo, y el cliente estaba
   leyendo algo cuando lo abrió. 480px da sitio a las dos columnas de
   tarjetas sin tapar la página.

   El mismo marcado, el mismo contenido, las mismas pestañas. Lo único
   que cambia es cuánto ocupa.

   El panel es el propio `.sgf-drawer`, que al ser `position: fixed` se
   sale del `flex` de la barra sin arrastrar nada consigo: la lista de
   al lado ni se entera. */
/* ════════════════════════════════════════════════════════════════
   DE DÓNDE SALE EL MENÚ — 1 oct
   ════════════════════════════════════════════════════════════════

   Cuatro sitios, elegidos en Datos SGF → Navegación. La clase la pone
   `sgf_menu_posicion_body_class()` en el `<body>`, igual que
   `sgf-pdp--{clave}`.

   Lo que cambia entre los cuatro son SEIS cosas a la vez: el lado al
   que se pega, hacia dónde se va cuando está cerrado, cuánto se
   separa del borde, el radio, la sombra y qué bordes lleva. Por eso
   son variables y no cuatro copias de la misma regla: la regla se
   escribe UNA vez, abajo, y aquí solo se dice cuánto vale cada cosa.

   OJO CON `--sgf-menu-fuera`
   -------------------------
   Lleva el hueco sumado a mano y no `calc(100% + var(--sgf-menu-hueco))`.
   No es descuido: una variable que se calcula a partir de otra se
   resuelve EN EL ELEMENTO DONDE SE DECLARA. Declarada aquí, en el
   `body`, se quedaría con el hueco del `body` para siempre, y la
   media query de móvil —que pone el hueco a cero— no la cambiaría.
   Está comprobado en este tema y ha costado tiempo dos veces.

   El valor sale de `$sgf-menu-hueco`, que es una variable de Sass:
   una sola fuente al escribir, sin herencia que resolver al pintar.
   ════════════════════════════════════════════════════════════════ */
body {
  --sgf-menu-izq: auto;
  --sgf-menu-der: 0;
  --sgf-menu-fuera: 100%;
  --sgf-menu-hueco: 0px;
  --sgf-menu-arriba: 0px;
  --sgf-menu-alto: 100dvh;
  --sgf-menu-radio: 0px;
  --sgf-menu-sombra: -24px 0 60px rgb(0 0 0 / 0.08);
  --sgf-menu-borde-y: 0;
  --sgf-menu-borde-izq: 1px solid var(--sgf-color-border);
  --sgf-menu-borde-der: 0;
}

body.sgf-menu--izquierda {
  --sgf-menu-izq: 0;
  --sgf-menu-der: auto;
  --sgf-menu-fuera: -100%;
  /* La sombra cae hacia la página, o sea hacia el lado contrario al
     borde del que sale. Dejarla igual que a la derecha la metería
     fuera de la pantalla y el panel quedaría recortado sin relieve. */
  --sgf-menu-sombra: 24px 0 60px rgb(0 0 0 / 0.08);
  --sgf-menu-borde-izq: 0;
  --sgf-menu-borde-der: 1px solid var(--sgf-color-border);
}

/* FLOTANTE: LA ISLA
   -----------------
   El panel deja de ser parte del borde de la pantalla y pasa a estar
   ENCIMA: separado por los cuatro lados, con esquinas redondeadas,
   borde completo y una sombra más larga que lo despega de verdad.

   El radio es 20 y no el `--sgf-radius-foto` de 8: una pieza de 480
   por 800 necesita mucho más redondeo que una foto para leerse como
   un objeto suelto. Con 8 parece un rectángulo con las esquinas
   matadas, que es lo contrario de lo que se busca. */
body.sgf-menu--flotante-derecha,
body.sgf-menu--flotante-izquierda {
  --sgf-menu-hueco: 16px;
  /* LA ISLA EMPIEZA DEBAJO DE LA TIRA GRANATE
     -----------------------------------------
     Pegada al borde, la tira utilitaria se pinta ENCIMA del panel y
     por eso las pestañas llevan un `padding-top` de su alto: para
     no quedarse debajo del granate.

     Una isla no puede resolverlo así. Medido: con `top: 16px` la
     tira le cruzaba la esquina redondeada de arriba, y además el
     padding de las pestañas dejaba un hueco muerto dentro del
     panel. Lo que necesita una isla es empezar DESPUÉS de la tira,
     no taparse de ella. Entonces el padding sobra, y se quita abajo.

     `--sgf-header-utility` se resuelve aquí, en el `body`, y eso
     está bien porque solo se declara en `:root`: no hay ningún
     ámbito intermedio que la cambie. */
  --sgf-menu-arriba: calc(var(--sgf-header-utility) + 16px);
  --sgf-menu-alto: calc(100dvh - var(--sgf-header-utility) - 32px);
  --sgf-menu-radio: 20px;
  --sgf-menu-sombra: 0 24px 64px rgb(0 0 0 / 0.18);
  --sgf-menu-borde-y: 1px solid var(--sgf-color-border);
  --sgf-menu-borde-izq: 1px solid var(--sgf-color-border);
  --sgf-menu-borde-der: 1px solid var(--sgf-color-border);
}

body.sgf-menu--flotante-derecha {
  --sgf-menu-izq: auto;
  --sgf-menu-der: 16px;
  --sgf-menu-fuera: calc(100% + 16px);
}

body.sgf-menu--flotante-izquierda {
  --sgf-menu-izq: 16px;
  --sgf-menu-der: auto;
  --sgf-menu-fuera: calc(-100% - 16px);
}

/* EN MÓVIL NO HAY ISLA
   --------------------
   El cajón ocupa la pantalla entera a propósito: con pestañas y
   tarjetas hace falta el ancho. Una isla de 16px de margen en un
   móvil de 375 deja dos franjas inútiles y le quita sitio justo a lo
   que hay que enseñar.

   Así que en móvil «flotante» solo conserva el LADO por el que entra,
   que es la parte del ajuste que sí tiene sentido ahí. */
@media (max-width: 1023px) {
  body.sgf-menu--flotante-derecha,
  body.sgf-menu--flotante-izquierda {
    --sgf-menu-hueco: 0px;
    --sgf-menu-arriba: 0px;
    --sgf-menu-alto: 100dvh;
    --sgf-menu-radio: 0px;
  }
  body.sgf-menu--flotante-derecha {
    --sgf-menu-der: 0;
    --sgf-menu-fuera: 100%;
  }
  body.sgf-menu--flotante-izquierda {
    --sgf-menu-izq: 0;
    --sgf-menu-fuera: -100%;
  }
}
.sgf-nav__primary {
  display: flex;
  align-items: center;
}
@media (max-width: 1023px) {
  .sgf-nav__primary {
    position: fixed;
    top: 0;
    left: var(--sgf-menu-izq);
    right: var(--sgf-menu-der);
    bottom: 0;
    /* EL CAJÓN OCUPA LA PANTALLA — 1 oct
       ----------------------------------
       Eran `min(320px, 85vw)`: una tira estrecha con la página
       asomando por el lado izquierdo. Esa franja no aporta
       contexto —la página de debajo está quieta y tapada a
       medias—, y en cambio deja el menú sin sitio para enseñar
       nada. Con pestañas y tarjetas hace falta el ancho entero.

       `100dvh` y no `100vh`: en iOS la barra del navegador aparece
       y desaparece al desplazar, y con `vh` el botón de cerrar de
       abajo se quedaba debajo del borde justo cuando hace falta. */
    width: 100%;
    height: 100dvh;
    background: var(--sgf-color-bg);
    border-left: 0;
    padding: 0;
    transform: translateX(var(--sgf-menu-fuera));
    transition: transform var(--sgf-duration-drawer) var(--sgf-ease-drawer);
    z-index: var(--sgf-z-modal);
    overflow: hidden;
    flex-direction: column;
    align-items: stretch;
  }
  .sgf-nav__primary.is-open, .nav-open .sgf-nav__primary {
    transform: translateX(0);
  }
}

/* ════════════════════════════════════════════════════════════════
   EL CAJÓN DEL MÓVIL

   Tres pestañas arriba, el contenido en medio con su propio scroll, y
   la barra de cerrar abajo del todo, fija. Esa es toda la estructura, y
   el orden importa: lo que decides está arriba donde empieza la vista,
   lo que miras ocupa el centro, y la salida está donde cae el pulgar.
   ════════════════════════════════════════════════════════════════ */
.sgf-drawer {
  display: none;
  /* El escritorio va AQUÍ y no en un bloque suelto más arriba. Lo
     tuve un rato antes de esta regla y no abría: `display: none` está
     en esta misma declaración, misma especificidad, y gana la que se
     lee después. Una excepción escrita antes de la norma no es una
     excepción, es un adorno. */
}
@media (min-width: 1024px) {
  .sgf-drawer {
    display: grid;
    grid-template-rows: auto 1fr auto;
    /* El lado, el hueco, el radio, la sombra y los bordes salen del
       ajuste del panel. La regla es una; lo que cambia son los
       valores. Ver el bloque «De dónde sale el Menú», arriba. */
    position: fixed;
    top: var(--sgf-menu-arriba);
    left: var(--sgf-menu-izq);
    right: var(--sgf-menu-der);
    width: min(480px, 90vw);
    height: var(--sgf-menu-alto);
    background: var(--sgf-color-bg);
    border-top: var(--sgf-menu-borde-y);
    border-bottom: var(--sgf-menu-borde-y);
    border-left: var(--sgf-menu-borde-izq);
    border-right: var(--sgf-menu-borde-der);
    border-radius: var(--sgf-menu-radio);
    box-shadow: var(--sgf-menu-sombra);
    /* Con esquinas redondeadas hay que recortar lo de dentro: las
       pestañas llevan su propio fondo y, sin esto, sus esquinas
       cuadradas asoman por encima del radio del panel. */
    overflow: hidden;
    transform: translateX(var(--sgf-menu-fuera));
    transition: transform var(--sgf-duration-drawer) var(--sgf-ease-drawer);
    z-index: var(--sgf-z-modal);
  }
  .nav-open .sgf-drawer {
    transform: translateX(0);
  }
}
@media (max-width: 1023px) {
  .sgf-drawer {
    display: grid;
    /* Tres filas: pestañas, contenido elástico, cerrar. El `1fr`
       del medio es lo que mantiene el botón pegado abajo sin
       `position: fixed` —y sin `fixed` no hay que pelearse con el
       teclado del móvil cuando se abra el buscador—. */
    grid-template-rows: auto 1fr auto;
    height: 100%;
    min-height: 0;
  }
}

/* ── La casa, bajo las pestañas ─────────────────────────────── */
/* Tres páginas sueltas —Nosotros, Los viñedos, Contacto— entre los
   paneles y el botón de cerrar. Discretas a propósito: el protagonista
   del cajón es lo que enseña la pestaña, y estas son la puerta de
   servicio. Por eso van en el color apagado y en cuerpo pequeño, y
   solo la actual se pone oscura. */
.sgf-drawer__casa {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sgf-space-2) var(--sgf-space-5);
  padding: var(--sgf-space-4) var(--sgf-gutter);
  border-top: 1px solid var(--sgf-color-border);
  font-size: 13px;
  line-height: 20px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.sgf-drawer__casa a {
  color: var(--sgf-color-muted);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-drawer__casa a:hover, .sgf-drawer__casa a[aria-current=page] {
  color: var(--sgf-color-text);
}

/* ── Pestañas ───────────────────────────────────────────────── */
.sgf-drawer__tabs {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  border-bottom: 1px solid var(--sgf-color-border);
  /* El cajón pegado al borde arranca en 0 y la tira utilitaria se
     pinta encima: sin este hueco las pestañas quedarían debajo del
     granate y no se verían.

     La isla no lo necesita —empieza DEBAJO de la tira, no debajo de
     su pintura— y ahí este relleno sería un hueco muerto dentro del
     panel. Por eso sale del mismo ajuste y no de un número fijo. */
  padding-top: var(--sgf-menu-pestanas-aire, var(--sgf-header-utility));
  background: var(--sgf-color-bg);
}

@media (min-width: 1024px) {
  body.sgf-menu--flotante-derecha,
  body.sgf-menu--flotante-izquierda {
    --sgf-menu-pestanas-aire: 0px;
  }
}
.sgf-drawer__tab {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  min-height: 56px;
  padding: var(--sgf-space-4) var(--sgf-space-2);
  color: var(--sgf-color-muted);
  background: none;
  border: 0;
  /* La pestaña activa se marca con una línea abajo, no con un
     recuadro: el recuadro la convierte en un botón más y entonces
     compite con las tarjetas de dentro. La línea solo señala. */
  border-bottom: 1px solid transparent;
  margin-bottom: -1px;
  cursor: pointer;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-drawer__tab.is-on {
  color: var(--sgf-color-text);
  border-bottom-color: var(--sgf-color-text);
}
.sgf-drawer__tab {
  /* Separadores entre pestañas, como en la referencia. El primero no
     lleva: una línea pegada al borde de la pantalla no separa nada. */
}
.sgf-drawer__tab + .sgf-drawer__tab {
  box-shadow: inset 1px 0 0 var(--sgf-color-border);
}

/* ── Paneles ────────────────────────────────────────────────── */
.sgf-drawer__panels {
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

.sgf-drawer__panel {
  padding: var(--sgf-space-6) var(--sgf-gutter) var(--sgf-space-8);
}
.sgf-drawer__panel[hidden] {
  display: none;
}

/* ── Lista de enlaces (pestaña Tienda) ──────────────────────── */
.sgf-drawer__lista {
  list-style: none;
  margin: 0;
  padding: 0;
}

.sgf-drawer__fila {
  border-bottom: 1px solid var(--sgf-color-border);
}
.sgf-drawer__fila:last-child {
  border-bottom: 0;
}

.sgf-drawer__enlace {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sgf-space-3);
  /* 56px de alto: el mínimo cómodo para el pulgar. Una lista de
     categorías que se pulsa a ciegas mientras andas no puede ir a
     40. */
  min-height: 56px;
  padding-block: var(--sgf-space-3);
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-2xl);
  line-height: 1.15;
  color: var(--sgf-color-text);
  text-decoration: none;
  /* «Todos los vinos» iba en cursiva para destacarlo. La cursiva de la
     SangBleu es de otra voz —la de una cita, la de un pie de foto— y
     en una lista de navegación lee como énfasis, no como jerarquía.
     Lo que lo distingue es que no lleva contador: es el único que no
     filtra nada. */
}
.sgf-drawer__enlace--destacado {
  font-style: normal;
}

/* LA FLECHA, NO EL NÚMERO — 1 oct
   ===============================
   Aquí salía el recuento de productos de la categoría: un «1» suelto
   al final de cada fila. En una bodega con un vino por categoría, esa
   columna de unos no informa de nada y parece un error de maquetación.

   Y aunque hubiera cuarenta, el número no es lo que el dedo necesita
   saber ahí: necesita saber que la fila lleva a algún sitio. Eso lo
   dice una flecha.

   Se dibuja en CSS y no con un SVG en el marcado: es un adorno del
   componente, no contenido. Así tampoco hay que pasarlo por el PHP ni
   traducirlo. */
.sgf-drawer__cuenta {
  display: block;
  width: 7px;
  height: 7px;
  border-top: 1px solid var(--sgf-color-muted);
  border-right: 1px solid var(--sgf-color-muted);
  transform: rotate(45deg);
  flex: none;
  /* El texto del contador se va, pero el elemento se queda: el número
     sigue en el DOM para quien navega con lector de pantalla, que sí
     agradece saber cuántos hay antes de entrar. */
  overflow: hidden;
  text-indent: -999em;
  transition: transform var(--sgf-duration-fast) var(--sgf-ease-out);
}

@media (hover: hover) and (pointer: fine) {
  .sgf-drawer__enlace:hover .sgf-drawer__cuenta {
    transform: rotate(45deg) translate(2px, -2px);
  }
}
/* ── Tarjetas (Experiencias y Blog) ─────────────────────────── */
.sgf-drawer__tarjetas {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--sgf-space-4);
  list-style: none;
  margin: 0;
  padding: 0;
}

.sgf-drawer__card {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-2);
  color: inherit;
  text-decoration: none;
  /* Lo que todavía no tiene página no se puede pulsar NI se disfraza
     de que sí. Es la lección del «Mundo»: un elemento con pinta de
     enlace que no llevaba a ningún sitio y que el tabulador ni
     alcanzaba. */
}
.sgf-drawer__card--pronto {
  cursor: default;
}
.sgf-drawer__card--pronto .sgf-drawer__titulo {
  color: var(--sgf-color-muted);
}
.sgf-drawer__card--pronto .sgf-drawer__foto {
  opacity: 0.55;
}

.sgf-drawer__foto {
  display: block;
  width: 100%;
  /* `height: auto` NO SOBRA — 1 oct
     -------------------------------
     WordPress escribe `width` y `height` como atributos del `<img>`,
     y el navegador los convierte en un alto real. Con un alto
     explícito, `aspect-ratio` deja de aplicarse: no es que pierda,
     es que la proporción solo se usa cuando falta una de las dos
     medidas.

     Visto en pantalla: tres de las cuatro tarjetas salían de 160x708
     en vez de 160x213, y empujaban el título y las etiquetas fuera
     de la vista. No había ninguna regla CSS poniendo ese alto —lo
     comprobé recorriendo las hojas—, venía del atributo.

     Con `auto` el alto vuelve a estar sin determinar y la proporción
     manda. */
  height: auto;
  aspect-ratio: 3/4;
  object-fit: cover;
  background: var(--sgf-color-surface);
  /* Radio 0, como el resto del sistema. */
  border-radius: 0;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-drawer__foto--vacia {
  aspect-ratio: 3/4;
}

@media (hover: hover) and (pointer: fine) {
  a.sgf-drawer__card:hover .sgf-drawer__foto {
    transform: scale(1.02);
  }
}
.sgf-drawer__titulo {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  color: var(--sgf-color-text);
}

.sgf-drawer__pills {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sgf-space-1);
}

.sgf-drawer__pill {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-micro);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-xs);
  letter-spacing: var(--sgf-track-xs);
  text-transform: none;
  padding: 2px var(--sgf-space-2);
  color: var(--sgf-color-muted);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-pill);
  white-space: nowrap;
}
.sgf-drawer__pill--pronto {
  border-style: dashed;
}

/* ── Cerrar ─────────────────────────────────────────────────── */
.sgf-drawer__close {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  min-height: 56px;
  padding: var(--sgf-space-4);
  color: var(--sgf-color-ink-fg);
  background: var(--sgf-color-ink);
  border: 0;
  cursor: pointer;
  /* Sale del mismo token que el pie y la tira de arriba: las tres
     superficies oscuras de la casa son el mismo color, y se cambia en
     un sitio. */
  padding-bottom: calc(var(--sgf-space-4) + env(safe-area-inset-bottom));
}

/* ── El movimiento ──────────────────────────────────────────────
   Las filas y las tarjetas entran escalonadas, y SOLO cuando el cajón
   está abierto: si la animación se declarara sin esa condición, se
   gastaría con el cajón cerrado y al abrirlo ya estaría hecha.

   El escalonado se corta a los 8 elementos. Más allá el retraso se
   nota como lentitud, no como elegancia: lo último entraría medio
   segundo tarde y parecería que la lista se ha quedado colgada. */
/* Sin `@media`: el cajón existe en los dos anchos desde que también se
   abre en escritorio, y la entrada escalonada es parte de cómo se
   presenta. Estaba encerrada bajo 1023px de cuando el cajón era solo
   del móvil, así que en escritorio las filas aparecían de golpe. */
.sgf-drawer__fila,
.sgf-drawer__tarjeta {
  opacity: 0;
  transform: translateY(8px);
}

.nav-open .sgf-drawer__panel.is-on .sgf-drawer__fila,
.nav-open .sgf-drawer__panel.is-on .sgf-drawer__tarjeta {
  animation: sgf-drawer-entra var(--sgf-duration-base) var(--sgf-ease-out) forwards;
  animation-delay: calc(min(var(--sgf-orden), 8) * 40ms);
}

@keyframes sgf-drawer-entra {
  to {
    opacity: 1;
    transform: translateY(0);
  }
}
/* Quien pide menos movimiento ve el contenido, no la ausencia de
   contenido: sin animación las filas tienen que estar visibles, no
   quedarse en `opacity: 0` para siempre. */
@media (prefers-reduced-motion: reduce) {
  .sgf-drawer__fila,
  .sgf-drawer__tarjeta {
    opacity: 1;
    transform: none;
    animation: none !important;
  }
  .sgf-drawer__foto {
    transition: none;
  }
}
.sgf-nav__menu {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-8);
  list-style: none;
  margin: 0;
  padding: 0;
  /* En móvil manda el cajón con pestañas, no esta lista. Se esconde
     en vez de borrarse del marcado porque sigue siendo la navegación
     de verdad: si el cajón no se pudiera pintar —un hijo que filtra
     las pestañas a cero— esta lista vuelve a salir con la regla de
     abajo y la web se sigue navegando. */
}
@media (max-width: 1023px) {
  .sgf-nav__menu {
    display: none;
  }
  .sgf-nav__primary:not(:has(.sgf-drawer)) .sgf-nav__menu {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--sgf-space-6);
    width: 100%;
    padding: var(--sgf-space-24) var(--sgf-space-8) var(--sgf-space-8);
  }
}
.sgf-nav__menu a,
.sgf-nav__menu .sgf-nav__ghost {
  /* La letra del marco, la misma que el pie. Antes esto decia
     16/500 con `letter-spacing: 0`, y la capa de cabecera decia
     otra cosa para los elementos de al lado: dos ficheros
     declarando el mismo papel, y ganaba el que se cargara
     despues. Ahora los dos dicen lo mismo porque los dos dicen
     ESTO. */
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  color: var(--sgf-nav-color);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
@media (max-width: 1023px) {
  .sgf-nav__menu a,
  .sgf-nav__menu .sgf-nav__ghost {
    font-size: var(--sgf-text-md);
  }
}
.sgf-nav__menu .sgf-nav__mobile-search {
  display: none;
}
@media (max-width: 1023px) {
  .sgf-nav__menu .sgf-nav__mobile-search {
    display: list-item;
  }
}

.sgf-nav__actions {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-8);
}

.sgf-nav__search,
.sgf-nav__cart {
  position: relative;
  display: inline-flex;
  align-items: baseline;
  /* La misma letra que los enlaces de al lado. Iban a 16 con
     interlinea 1 mientras «Tienda» y «Diario» iban a 16 con 1,5:
     dos interlineas en una sola fila, y ninguna elegida a proposito.
     La fila se centra con `align-items`, asi que la interlinea no
     la alinea; solo la descuadraba. */
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-chrome-size);
  font-weight: var(--sgf-chrome-weight);
  line-height: var(--sgf-lead-sm);
  letter-spacing: var(--sgf-track-sm);
  text-transform: none;
  color: var(--sgf-nav-color);
  text-decoration: none;
  opacity: 1;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}

.sgf-nav__cart-count {
  position: static;
  min-width: 0;
  height: auto;
  padding: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-variant-numeric: tabular-nums;
  border-radius: 0;
  opacity: 1;
  transform: none;
}
.sgf-nav__cart-count:empty, .sgf-nav__cart-count:not(.has-items) {
  display: none;
}

/* AQUÍ HABÍA UNA SEGUNDA HAMBURGUESA — 1 oct
   ==========================================
   `.sgf-nav__toggle` estaba declarado en DOS ficheros: en
   `layouts/_header.scss` con 40px y 20px de raya, y aquí con 32px y
   1,5px. Dos tamaños para el mismo botón, y ganaba el que se cargara
   después. Es exactamente el patrón que lleva toda la sesión
   apareciendo: el mismo objeto descrito en dos sitios.

   Ahora el botón es la palabra «Menú» y vive solo en
   `layouts/_header.scss`, con el resto del cromo de la cabecera.

   Las reglas de las tres rayas y de la X al abrir se van con él: ese
   marcado ya no existe. Mantenerlas sería dejar CSS esperando a unos
   elementos que nadie pinta. */
.sgf-nav__overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.6);
  backdrop-filter: blur(2px);
  z-index: var(--sgf-z-overlay);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--sgf-duration-ui) var(--sgf-ease-out);
}

.nav-open .sgf-nav__overlay {
  opacity: 1;
  /* `visibility` explícito: una implementación anterior del menú
     móvil —ya retirada de `layouts/_header.scss`— dejaba este
     elemento en `visibility: hidden`, y con eso el velo no se veía
     por mucho que la opacidad fuera 1. Declararlo aquí deja de
     depender de qué más haya tocado el elemento. */
  visibility: visible;
  pointer-events: auto;
}

/* Botones y tarjetas
--------------------------------------------- */
/* Los directorios existian pero nadie los importaba: los botones
   reales salian de base/elements/_buttons.scss. Van despues de la
   capa base para poder sobrescribirla sin subir especificidad. */
.sgf-btn, .woocommerce .button:not(.sgf-btn),
input[type=submit]:not(.sgf-btn),
button[type=submit]:not(.sgf-btn) {
  --btn-bg: transparent;
  --btn-fg: var(--sgf-color-text);
  --btn-border: var(--sgf-color-control);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sgf-space-1);
  height: 48px;
  /* EL `1px` VERTICAL NO ERA NUESTRO — 1 oct
     ----------------------------------------
     Media docena de botones del sitio medían `padding: 1px 24px` o
     `1px 32px`, y ese 1px no estaba escrito en ninguna hoja: es el
     `padding: 1px 6px` que el navegador le da a `<button>` por
     defecto. Como aquí solo se declaraba `padding-inline`, el
     vertical seguía siendo el del navegador.

     Por eso aparecía en unos sí y en otros no: el que lo perdía era
     el componente que escribía el `padding` completo por su cuenta.
     O sea que la diferencia entre botones no la decidía el sistema,
     la decidía quién se acordó de poner la propiedad entera.

     Declarándolo aquí deja de depender de eso. No mueve un píxel: la
     altura es fija y `box-sizing` es `border-box`, así que ese 1px no
     pintaba nada; solo ensuciaba la medida. */
  padding-block: 0;
  padding-inline: var(--sgf-space-4);
  font-family: inherit;
  /* EL TAMANO REAL DEL BOTON ES 16 — 30 sep
     ---------------------------------------
     Esto decia `--sgf-text-sm` (14) y las variantes que se usan de
     verdad —primary, secondary y ghost— lo subian a 16 cada una por
     su cuenta. O sea que el 14 solo lo veia un `.sgf-btn` sin
     variante, que apenas existe, y por eso `.sgf-btn--sm` tenia que
     volver a declarar 14: no estaba haciendo un boton pequeno,
     estaba deshaciendo el 16 de las variantes.

     El sistema real es: los botones miden 16 y los pequenos 14. Se
     dice aqui una vez, se quitan los 16 repetidos y `--sm` vuelve a
     significar lo que su nombre dice.

     Casi ningun pixel cambia: primary, secondary y ghost declaraban 16
     y ahora lo heredan, o sea el mismo valor. El unico que se mueve es
     un `.sgf-btn` sin variante, que pasa de 14 a 16. Medido: hay uno
     visible en todo el sitio, «Ver resultados» en el cajon de filtros
     del movil, y ahi 16 es lo que le toca —es la accion que cierra el
     cajon, no una nota al pie. */
  font-size: var(--sgf-text-base);
  font-weight: 500;
  line-height: 1;
  /* `0` computaba a `normal`, y era el unico texto de la cabecera o
     el pie que no llevaba el tracking emparejado con su tamano. El
     valor es el de `base` y no el de `sm` porque TODAS las variantes
     reales del boton —primary, secondary, ghost— suben a
     `--sgf-text-base`; el 14 de aqui arriba solo lo ve un `.sgf-btn`
     sin variante, que es justo por lo que `--sgf-btn--sm` tiene que
     volver a declarar 14. Ese enredo es otra limpieza. */
  letter-spacing: var(--sgf-track-base);
  text-transform: none;
  /* UN BOTÓN NO SE SUBRAYA — 1 oct
     ------------------------------
     `base/elements/_links.scss` pone `a:hover { text-decoration:
     underline }` para TODOS los enlaces, y no excluía a los botones.
     Así que cualquier `<a class="sgf-btn">` —«La tienda» del hero,
     «Ver la colección», los CTA del pie— se subrayaba al pasar el
     ratón, como si fuera un enlace de texto dentro de un párrafo.

     Se declara aquí y no allí porque el que manda sobre cómo se ve un
     botón es el componente del botón. Y hace falta el `&:hover`
     explícito: `a:hover` lleva una pseudoclase, así que gana a una
     `.sgf-btn` a secas.

     `--text` es la excepción y se lo vuelve a poner: esa variante ES
     un enlace con forma de botón, y el subrayado es lo que lo dice. */
  text-decoration: none;
}
.sgf-btn:hover, .woocommerce .button:hover:not(.sgf-btn),
input[type=submit]:hover:not(.sgf-btn),
button[type=submit]:hover:not(.sgf-btn) {
  text-decoration: none;
}
.sgf-btn, .woocommerce .button:not(.sgf-btn),
input[type=submit]:not(.sgf-btn),
button[type=submit]:not(.sgf-btn) {
  background: var(--btn-bg);
  color: var(--btn-fg);
  border: 1px solid var(--btn-border);
  border-radius: var(--sgf-radius-pill);
  cursor: pointer;
  appearance: none;
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-btn:focus-visible, .woocommerce .button:focus-visible:not(.sgf-btn),
input[type=submit]:focus-visible:not(.sgf-btn),
button[type=submit]:focus-visible:not(.sgf-btn) {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-btn:hover, .woocommerce .button:hover:not(.sgf-btn),
  input[type=submit]:hover:not(.sgf-btn),
  button[type=submit]:hover:not(.sgf-btn) {
    border-color: var(--sgf-color-text);
    background: color-mix(in srgb, var(--sgf-color-text) 6%, transparent);
  }
}
.sgf-btn[disabled], .woocommerce [disabled].button:not(.sgf-btn),
input[disabled][type=submit]:not(.sgf-btn),
button[disabled][type=submit]:not(.sgf-btn), .sgf-btn.disabled, .woocommerce .disabled.button:not(.sgf-btn),
input.disabled[type=submit]:not(.sgf-btn),
button.disabled[type=submit]:not(.sgf-btn) {
  opacity: 0.4;
  pointer-events: none;
}

/* CTA principal: pildora negra de 56px. */
.sgf-btn--primary, .woocommerce .button:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
input[type=submit]:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
button[type=submit]:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
.single-product .single_add_to_cart_button,
.woocommerce .button.alt {
  --btn-bg: var(--sgf-color-text);
  --btn-fg: var(--sgf-color-bg);
  --btn-border: var(--sgf-color-text);
  height: 56px;
  padding-inline: var(--sgf-space-5);
  border-radius: var(--sgf-radius-pill);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-btn--primary:focus-visible, .woocommerce .button:focus-visible:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
input[type=submit]:focus-visible:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
button[type=submit]:focus-visible:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
.single-product .single_add_to_cart_button:focus-visible,
.woocommerce .button.alt:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
.sgf-btn--primary, .woocommerce .button:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
input[type=submit]:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
button[type=submit]:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
.single-product .single_add_to_cart_button,
.woocommerce .button.alt {
  /* EL RELLENO SUBÍA A UN GRIS QUE NO ERA DE LA CASA — 1 oct
     --------------------------------------------------------
     Era `$sgf-gray-700`, o sea `#3d3d3d` escrito a pelo en Sass. En
     Junciera el botón primario es `#1a1814`, un negro CÁLIDO: al
     pasar el ratón saltaba a un gris FRÍO. No es que se viera poco,
     es que cambiaba de familia de color, y encima era un literal que
     ninguna marca podía cambiar desde el panel.

     Ahora se aclara un paso desde su propio color, mezclando con el
     fondo de la página. Conserva el tono de la marca sea cual sea, y
     el salto se nota igual en claro que en oscuro. */
  /* AL GRANATE, QUE YA ES UN COLOR DE LA CASA — 1 oct
     -------------------------------------------------
     Antes aclaraba el propio negro un paso. Funcionaba y no decía
     nada: un botón oscuro que al tocarlo se vuelve un poco menos
     oscuro es un cambio que se mide, no que se siente.

     El granate ya viste el pie y la tira de arriba. Usarlo también
     aquí hace que el color aparezca en los tres sitios donde la web
     responde o cierra, en vez de ser el color de dos adornos. Y el
     salto se nota de verdad, que era lo que faltaba.

     Sale de `--sgf-color-ink`, igual que el pie: un solo sitio donde
     cambiarlo. En un theme recién instalado ese token vale lo mismo
     que el fondo, así que allí el hover sigue siendo el aclarado de
     antes y no un granate que nadie ha elegido. */
}
@media (hover: hover) and (pointer: fine) {
  .sgf-btn--primary:hover, .woocommerce .button:hover:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
  input[type=submit]:hover:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
  button[type=submit]:hover:not(.sgf-btn):not(input[type=submit]:not(.sgf-btn)):not(button[type=submit]:not(.sgf-btn)),
  .single-product .single_add_to_cart_button:hover,
  .woocommerce .button.alt:hover {
    --btn-fg: var(--sgf-color-ink-fg);
    background: var(--sgf-color-ink);
    border-color: var(--sgf-color-ink);
    color: var(--sgf-color-ink-fg);
  }
}

/* CTA secundario: misma pildora en blanco con borde. */
.sgf-btn--secondary,
.sgf-btn--ghost {
  --btn-bg: var(--sgf-color-bg);
  --btn-fg: var(--sgf-color-text);
  --btn-border: var(--sgf-color-control);
  height: 56px;
  padding-inline: var(--sgf-space-5);
  border-radius: var(--sgf-radius-pill);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-btn--secondary:focus-visible,
.sgf-btn--ghost:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-btn--secondary:hover,
  .sgf-btn--ghost:hover {
    border-color: var(--sgf-color-text);
    background: color-mix(in srgb, var(--sgf-color-text) 6%, transparent);
  }
}

/* BOTÓN CLARO, PARA FONDOS OSCUROS — 1 oct
   ========================================
   Faltaba en el sistema, y se notaba: el CTA del hero oscuro («Los
   viñedos», sobre la foto de noche) usaba `--secondary`, que está
   pensado para fondo claro, y el «Suscríbete» del pie usaba `--ghost`,
   que sobre el granate quedaba granate sobre granate. Dos piezas del
   mismo papel resueltas con dos variantes prestadas.

   Al reposo es un bloque claro macizo: sobre una fotografía oscura o
   sobre el granate del pie, eso es lo que se ve a un metro de
   distancia. Al pasar el ratón se vacía y deja solo el contorno: el
   color se va, la forma se queda, y el gesto es el mismo en los dos
   sitios.

   Los colores salen de la pareja `ink` / `ink-fg`, los mismos que
   visten el pie y la tira de arriba. Así el botón pertenece a la
   superficie en la que está, no a un blanco elegido aparte. */
.sgf-btn--claro {
  --btn-bg: var(--sgf-color-ink-fg);
  --btn-fg: var(--sgf-color-ink);
  --btn-border: var(--sgf-color-ink-fg);
  height: 56px;
  padding-inline: var(--sgf-space-5);
  border-radius: var(--sgf-radius-pill);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-btn--claro:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-btn--claro:hover {
    --btn-fg: var(--sgf-color-ink-fg);
    background: transparent;
    color: var(--sgf-color-ink-fg);
    border-color: var(--sgf-color-ink-fg);
  }
}

.sgf-btn--text {
  --btn-border: transparent;
  --btn-bg: transparent;
  height: auto;
  padding: 0;
  border-radius: 0;
  text-decoration: underline;
  text-underline-offset: 0.25em;
}
.sgf-btn--text:hover {
  /* La base apaga el subrayado para todos los botones; esta
     variante es la excepción y se lo devuelve, porque aquí el
     subrayado ES lo que dice que se puede pulsar. */
  text-decoration: underline;
  --btn-fg: var(--sgf-color-muted);
  border-color: transparent;
}

.sgf-btn--sm {
  height: 40px;
  padding-inline: var(--sgf-space-3);
  font-size: var(--sgf-text-sm);
}

.sgf-btn--block {
  display: flex;
  width: 100%;
}

/* EL SELECTOR DE TALLA VIVÍA AQUÍ Y EN EL PDP — 2 oct
   ===================================================
   Estaba entero en los dos sitios: `.sgf-size-head`, `.sgf-size-grid`,
   `.sgf-size` y su campana, declarados aquí y otra vez en
   `plugins/woocommerce/_single-product.scss`, casi palabra por
   palabra. El comentario de aquí decía «el PDP lo afina», pero no
   afinaba: repetía.

   Y repetido con el mismo peso, así que mandaba el orden de las hojas.
   El día que el PDP pasó a contar las columnas en vez de fijar cinco,
   la cuenta no se vio: esta copia seguía diciendo cinco, y en una
   ficha de vino con tres añadas quedaban dos carriles vacíos dentro
   de la caja.

   El selector solo sale en la ficha de producto, y `woocommerce.css`
   se carga en toda página de tienda. Un componente, un fichero: el
   bueno es el del PDP, que además tiene `__txt`, `__label` y la guía
   de tallas que aquí nunca llegaron. */
/* ─── Carga ──────────────────────────────────────────────────── */
.sgf-btn.loading, .woocommerce .loading.button:not(.sgf-btn),
input.loading[type=submit]:not(.sgf-btn),
button.loading[type=submit]:not(.sgf-btn) {
  color: transparent;
  pointer-events: none;
  position: relative;
}
.sgf-btn.loading::after, .woocommerce .loading.button:not(.sgf-btn)::after,
input.loading[type=submit]:not(.sgf-btn)::after,
button.loading[type=submit]:not(.sgf-btn)::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: 50%;
  color: var(--btn-fg);
  animation: sgf-btn-spin 600ms linear infinite;
}

@keyframes sgf-btn-spin {
  to {
    transform: rotate(360deg);
  }
}
@media (prefers-reduced-motion: reduce) {
  .sgf-btn, .woocommerce .button:not(.sgf-btn),
  input[type=submit]:not(.sgf-btn),
  button[type=submit]:not(.sgf-btn) {
    transition: none;
  }
  .sgf-btn.loading::after, .woocommerce .loading.button:not(.sgf-btn)::after,
  input.loading[type=submit]:not(.sgf-btn)::after,
  button.loading[type=submit]:not(.sgf-btn)::after {
    animation-duration: 1.6s;
  }
}
.sgf-product-card {
  display: flex;
  flex-direction: column;
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  padding: 0;
}

.sgf-product-card__image-wrap {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: var(--sgf-ratio-retrato);
  overflow: hidden;
  background: var(--sgf-color-surface);
  border-radius: var(--sgf-radius-foto);
  margin: 0 0 var(--sgf-space-3);
}

/* El wrap es quien recorta la foto. El enlace solo cubre la imagen:
   el ojo de vista rápida es un botón hermano, no un hijo. Un botón
   dentro de un enlace es HTML inválido y el clic abre las dos cosas. */
.sgf-product-card__image-link {
  display: block;
  width: 100%;
  height: 100%;
}

.sgf-product-card__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  border-radius: 0;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out);
}

/* Zoom minimo. Solo en puntero fino: en táctil no hay hover que soltar. */
@media (hover: hover) and (pointer: fine) {
  .sgf-product-card:hover .sgf-product-card__image {
    transform: scale(1.02);
  }
}
/* Edición limitada: pastilla, esquina izquierda.
   El ojo de vista rápida vive a la derecha: no se pisan. */
.sgf-product-card__image-wrap .sgf-badge--limited {
  position: absolute;
  top: var(--sgf-space-3);
  left: var(--sgf-space-3);
  z-index: 1;
  margin: 0;
  padding: 6px 10px;
  color: var(--sgf-color-text);
  background: var(--sgf-color-bg);
  border-radius: 999px;
  pointer-events: none;
}
@media (max-width: 767px) {
  .sgf-product-card__image-wrap .sgf-badge--limited {
    top: var(--sgf-space-2);
    left: var(--sgf-space-2);
    padding: 5px 8px;
  }
}

.sgf-product-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-1);
}

.sgf-product-card__flag,
.sgf-product-card .sgf-eyebrow {
  margin: 0;
  font-size: var(--sgf-text-xs);
  font-weight: 500;
  line-height: 20px;
  color: var(--sgf-color-accent);
  text-transform: none;
  letter-spacing: 0;
}

.sgf-product-card__title {
  margin: 0;
  font-size: var(--sgf-text-base);
  font-weight: 500;
  line-height: 24px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--sgf-color-text);
}
.sgf-product-card__title a {
  color: inherit;
}

.sgf-product-card__meta {
  font-size: var(--sgf-text-sm);
  font-weight: 400;
  line-height: 20px;
  color: var(--sgf-color-muted);
  /* Una linea.
     La linea gris de la tarjeta sale de la descripcion corta, y una
     descripcion corta de verdad son varios parrafos: con catalogo
     real, cada tarjeta se comia media pantalla y la rejilla dejaba de
     poder compararse de un vistazo, que es para lo que existe.

     Se recorta por CSS y no en PHP para no tocar el texto: sigue
     completo en el marcado, y en la ficha se lee entero. */
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.sgf-product-card__price {
  margin-top: var(--sgf-space-1);
  font-size: var(--sgf-text-base);
  font-weight: 500;
  line-height: 24px;
  font-variant-numeric: tabular-nums;
  color: var(--sgf-color-text);
}
.sgf-product-card__price del {
  color: var(--sgf-color-muted);
  font-weight: 400;
  margin-right: var(--sgf-space-2);
}
.sgf-product-card__price ins {
  text-decoration: none;
  color: var(--sgf-color-text);
}

/* El catalogo no lleva boton de compra: se compra desde la ficha. */
.sgf-product-card__add,
.sgf-product-card .add_to_cart_button,
.sgf-product-card .added_to_cart,
.sgf-product-card .sgf-stock,
.sgf-product-card .onsale {
  display: none;
}

.sgf-product-card.outofstock .sgf-product-card__image {
  opacity: 0.4;
}

@media (prefers-reduced-motion: reduce) {
  .sgf-product-card__image {
    transition: none;
  }
  .sgf-product-card:hover .sgf-product-card__image {
    transform: none;
  }
}
/* Aviso de cookies
--------------------------------------------- */
/* Va en style.css: el markup se imprime en wp_footer en cualquier
   pagina, no solo en las de tienda. */
.sgf-cookies {
  position: fixed;
  bottom: var(--sgf-space-4);
  left: var(--sgf-space-4);
  z-index: var(--sgf-z-toast);
  width: min(320px, 100vw - var(--sgf-space-8));
  padding: 18px 20px 16px;
  background: var(--sgf-color-bg);
  border: 1px solid var(--sgf-color-border);
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity var(--sgf-duration-drawer) var(--sgf-ease-out), transform var(--sgf-duration-drawer) var(--sgf-ease-drawer);
}
.sgf-cookies[data-side=right] {
  left: auto;
  right: var(--sgf-space-4);
}
.sgf-cookies.is-open {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.sgf-cookies[hidden] {
  display: none;
}

.sgf-cookies__texto {
  margin: 0 0 14px;
  font-family: var(--sgf-font-body);
  font-size: 13px;
  font-weight: 400;
  line-height: 1.45;
  color: var(--sgf-color-muted);
}

.sgf-cookies__acciones {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 14px 18px;
}

.sgf-cookies__aceptar,
.sgf-cookies__rechazar {
  padding: 0;
  background: none;
  border: 0;
  font-family: inherit;
  font-size: 13px;
  font-weight: 400;
  line-height: 1.2;
  cursor: pointer;
}

.sgf-cookies__aceptar {
  color: var(--sgf-color-text);
}

.sgf-cookies__rechazar,
.sgf-cookies__privacidad {
  color: var(--sgf-color-muted);
  text-decoration: none;
}

.sgf-cookies__privacidad {
  font-size: 13px;
}

.sgf-cookies__aceptar:hover,
.sgf-cookies__rechazar:hover,
.sgf-cookies__privacidad:hover {
  color: var(--sgf-color-text);
}

@media (prefers-reduced-motion: reduce) {
  .sgf-cookies {
    transition: none;
  }
}
/* Cajon del carrito
--------------------------------------------- */
/* Va en style.css y no en woocommerce.css: el markup se imprime en
   wp_footer en TODAS las paginas. */
/* ─── Velo ───────────────────────────────────────────────────── */
.sgf-cart-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--sgf-z-overlay);
  background: rgba(0, 0, 0, 0.35);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--sgf-duration-ui) var(--sgf-ease-out), visibility 0s linear var(--sgf-duration-ui);
}

html.is-open .sgf-cart-overlay,
html.sgf-guide-abierta .sgf-cart-overlay,
html.search-open .sgf-cart-overlay {
  opacity: 1;
  visibility: visible;
  transition-delay: 0s;
}

/* ─── Panel ──────────────────────────────────────────────────── */
#sgf-cart-drawer {
  position: fixed;
  /* ARRANCA BAJO LA CABECERA DEL SITIO, NO EN LO ALTO DE TODO.
     ---------------------------------------------------------
     Con `top: 0` el cajon se metia debajo de la cabecera, que va en
     `--sgf-z-nav` (1000) por encima de `--sgf-z-modal` (900). Esa
     escala es deliberada —el carrito se abre a un lado y la
     cabecera sigue siendo util—, pero solo funciona si el cajon no
     se mete debajo: tal cual estaba, sus primeros 88 px quedaban
     tapados, y ahi viven el titulo «Cesta» y la ✕. El boton de
     cerrar no se podia pulsar: el clic se lo quedaba
     `.sgf-nav__actions`, que estaba encima.

     Se baja el cajon en vez de subirlo de capa, que es lo que pide
     esa decision de diseño.

     `--sgf-drawer-top` la escribe `cart-drawer.js` al abrir, con la
     cabecera medida. La suma de tokens es el respaldo para antes de
     que corra el JS, y se queda 8 px larga porque el token de la
     barra de servicio dice 40 y la barra pinta 32. */
  top: var(--sgf-drawer-top, calc(var(--sgf-header-utility) + var(--sgf-header-primary)));
  right: 0;
  bottom: 0;
  z-index: var(--sgf-z-modal);
  display: flex;
  flex-direction: column;
  width: min(440px, 100vw);
  background: var(--sgf-color-bg);
  border-left: 1px solid var(--sgf-color-border);
  transform: translateX(100%);
  visibility: hidden;
  transition: transform var(--sgf-duration-drawer) var(--sgf-ease-drawer), visibility 0s linear var(--sgf-duration-drawer);
}

html.is-open #sgf-cart-drawer {
  transform: translateX(0);
  visibility: visible;
  transition-delay: 0s;
}

/* ─── Cabecera ───────────────────────────────────────────────── */
.sgf-cart-drawer__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-4);
  padding: var(--sgf-space-5) var(--sgf-space-6) var(--sgf-space-3);
  border-bottom: 0;
  flex-shrink: 0;
}

.sgf-cart-drawer__title {
  font-size: 16px;
  font-weight: 500;
}

.sgf-cart-drawer__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  color: var(--sgf-color-text);
  background: none;
  border: 0;
  cursor: pointer;
}
.sgf-cart-drawer__close svg {
  display: block;
}
.sgf-cart-drawer__close:hover {
  color: var(--sgf-color-muted);
}

/* ─── Artículos ──────────────────────────────────────────────
   Es la única zona que scrollea: cabecera y pie quedan fijos para
   que el total y el botón de pagar no se pierdan al bajar. */
/* El aviso de envio del cajon, alineado con lo demas.
   ---------------------------------------------------
   `.sgf-ship-progress` es un componente compartido —tambien sale en
   la pagina del carrito— y por eso no trae margenes propios. Dentro
   del cajon eso lo dejaba pegado al borde izquierdo mientras la
   cabecera, los articulos y el pie llevaban sus 24 px: una sola
   linea desalineada con todo lo que tiene debajo. El margen se pone
   aqui, que es donde se sabe en que contenedor esta. */
#sgf-cart-drawer > .sgf-ship-progress {
  padding: var(--sgf-space-3) var(--sgf-space-6);
}

.sgf-cart-drawer__scroll {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--sgf-space-4) var(--sgf-space-6) var(--sgf-space-3);
}

.sgf-cart-drawer__items {
  padding: 0;
}
.sgf-cart-drawer__items:empty::after {
  content: attr(data-empty-text);
  display: block;
  padding: var(--sgf-space-10) 0;
  text-align: center;
  color: var(--sgf-color-muted);
  font-size: 14px;
}

.sgf-cart-item {
  display: grid;
  grid-template-columns: 64px 1fr;
  gap: var(--sgf-space-4);
  padding: var(--sgf-space-4) 0;
  border-bottom: 1px solid var(--sgf-color-border);
}
.sgf-cart-item:last-child {
  border-bottom: 0;
}

.sgf-cart-item__image {
  width: 64px;
  height: 64px;
  object-fit: cover;
  background: var(--sgf-color-surface);
}

.sgf-cart-item__info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.sgf-cart-item__name {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.35;
}

.sgf-cart-item__price {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  color: var(--sgf-color-muted);
}

.sgf-cart-item__remove {
  align-self: flex-start;
  margin-top: var(--sgf-space-1);
  font-size: 12px;
  color: var(--sgf-color-muted);
  text-decoration: underline;
  text-underline-offset: 0.2em;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
}
.sgf-cart-item__remove:hover {
  color: var(--sgf-color-text);
}

/* ─── Pie ────────────────────────────────────────────────────── */
.sgf-cart-drawer__footer {
  flex-shrink: 0;
  padding: 0;
  border-top: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.sgf-cart-drawer__total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  padding: 14px var(--sgf-space-6);
  border-top: 1px solid var(--sgf-color-border);
  font-size: 14px;
  font-weight: 500;
}

.sgf-cart-drawer__total-amount {
  font-variant-numeric: tabular-nums;
}

/* EL BOTON QUE COBRA NO PUEDE SER EL MAS PEQUENO — 30 sep
   -------------------------------------------------------
   Esto reimplementaba el boton primario entero dentro del componente:
   alto, tamano, peso, interlinea, fondo, color, borde, radio y hover.
   Nueve declaraciones para volver a describir algo que el elemento YA
   es —lleva `.sgf-btn--primary` en el HTML— y que ademas describia
   distinto: 48px de alto y 14 de letra, cuando un primario mide 56 y
   16.

   Resultado medido: «Tramitar el pedido» salia mas pequeno que el
   enlace a un video de YouTube de una pagina de contenido. El boton
   que cobra era el menos importante de la pantalla.

   Aqui se queda solo lo que de verdad es del CAJON —cuanto ocupa y
   donde se coloca—. Lo de ser un boton lo pone la clase. */
.sgf-cart-drawer__checkout {
  width: calc(100% - var(--sgf-space-6) * 2);
  margin: 14px var(--sgf-space-6) var(--sgf-space-5);
}

/* ─── Sin JavaScript ─────────────────────────────────────────
   Si el script no llega a cargar, el cajón nunca recibe la clase
   que lo abre — pero tampoco debe quedarse visible ocupando la
   página. Con position:fixed y translateX ya queda fuera, y esto
   lo saca además del árbol de accesibilidad. */
#sgf-cart-drawer[aria-hidden=true] {
  pointer-events: none;
}

html.is-open #sgf-cart-drawer {
  pointer-events: auto;
}

@media (prefers-reduced-motion: reduce) {
  #sgf-cart-drawer,
  .sgf-cart-overlay {
    transition: none;
  }
}
/* ─── Articulo del cajon ─────────────────────────────────────
   El mismo registro que la pagina de cesta: foto, nombre, precio,
   paso de cantidad y papelera. Antes el cajon solo ofrecia "Quitar"
   mientras la cesta dejaba sumar y restar; dos sitios para lo mismo
   con capacidades distintas obligan a aprender dos veces. */
.sgf-cart-item {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr) auto;
  gap: var(--sgf-space-3);
  align-items: start;
  padding-block: var(--sgf-space-4);
  border-bottom: 1px solid var(--sgf-color-border);
}
.sgf-cart-item.is-busy {
  opacity: 0.5;
  pointer-events: none;
}
.sgf-cart-item {
  transition: opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}

.sgf-cart-item__media {
  background: var(--sgf-color-surface);
}
.sgf-cart-item__media img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 1/1;
  object-fit: cover;
}

.sgf-cart-item__body {
  min-width: 0;
}

.sgf-cart-item__name {
  font-family: var(--sgf-font-body);
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  margin: 0;
}

.sgf-cart-item__price,
.sgf-cart-item__meta {
  font-size: 14px;
  line-height: 20px;
  color: var(--sgf-color-muted);
  margin: var(--sgf-space-1) 0 0;
}

.sgf-cart-item__line {
  font-size: 15px;
  font-weight: 500;
  line-height: 22px;
  margin: 0;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.sgf-cart-item__controls {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-2);
  margin-top: var(--sgf-space-3);
}

/* El paso de cantidad NO se estila aqui.
   Es el componente compartido .sgf-qty de components/forms/_forms.scss,
   el mismo que usa cualquier otro sitio donde se elija una cantidad.
   Aqui habia una segunda definicion que ademas perdia: _forms.scss se
   importa despues y ganaba por orden, asi que el cajon acababa con el
   estilo viejo pasara lo que pasara. */
/* Papelera. Icono y no la palabra "Quitar": al lado del paso de
   cantidad, dos textos seguidos compiten; un icono se distingue de un
   vistazo y es lo que ya hace la cesta. */
.sgf-cart-item__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--sgf-color-muted);
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out), background-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-cart-item__remove svg {
  width: 20px;
  height: 20px;
}
.sgf-cart-item__remove:hover {
  color: var(--sgf-color-text);
  background: var(--sgf-color-surface);
}

.sgf-cart-drawer__empty {
  font-size: 15px;
  line-height: 22px;
  color: var(--sgf-color-muted);
  padding-block: var(--sgf-space-6);
  margin: 0;
}

@media (prefers-reduced-motion: reduce) {
  .sgf-cart-item,
  .sgf-qty__btn,
  .sgf-cart-item__remove {
    transition: none;
  }
}
/* Con la cesta vacia el pie se esconde: un total de 0,00 y un boton de
   pasar por caja que no lleva a ninguna parte solo estorban.
   El JS lo apaga con el atributo `hidden`, y sin esta regla el
   `display` del pie gana a la hoja del navegador y el atributo no
   surte efecto. */
.sgf-cart-drawer__footer[hidden] {
  display: none;
}

.sgf-cart-drawer__total[hidden] {
  display: none;
}

.sgf-drawer-pay {
  margin-top: var(--sgf-space-4);
  padding-top: var(--sgf-space-4);
  border-top: 1px solid var(--sgf-color-border);
}

/* Rotulos del cajon: en redonda y en su caja normal.
   -------------------------------------------------
   Iban en monoespaciada de 10 px, versales y muy espaciada. A ese
   tamaño las versales dejan de leerse de un vistazo y se descifran
   letra a letra, y en una cesta —donde solo se comprueban cuatro
   cosas antes de pagar— eso es justo lo contrario de lo que hace
   falta. Siguen siendo secundarios por tamaño y color, que es
   suficiente para que no compitan con los importes. */
.sgf-drawer-pay__label,
.sgf-drawer-reco__title {
  margin: 0 0 var(--sgf-space-2);
  font-family: inherit;
  font-size: var(--sgf-text-sm);
  letter-spacing: normal;
  text-transform: none;
  color: var(--sgf-color-muted);
}

.sgf-drawer-pay__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sgf-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sgf-drawer-pay__item img {
  display: block;
  max-height: 22px;
  width: auto;
}

.sgf-drawer-pay__name {
  display: inline-block;
  padding: 3px 8px;
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-sm);
  font-size: 12px;
  color: var(--sgf-color-muted);
}

.sgf-drawer-reco {
  margin-top: var(--sgf-space-4);
  padding-top: var(--sgf-space-4);
  border-top: 1px solid var(--sgf-color-border);
}

/* AQUÍ HABÍA UN SEGUNDO `.sgf-drawer-reco` ENTERO — 1 oct
   ------------------------------------------------------
   Este fichero declaraba el componente dos veces: una lista en fila
   de 48px (aquí) y el carril de tarjetas de 104px (más abajo). Ganaba
   el de abajo por orden de aparición, así que todo esto era código
   muerto… menos dos cosas, que no lo eran:

   - `.sgf-drawer-reco__media img { width: 48px; height: 48px }`, que
     el de abajo tenía que deshacer a mano con `aspect-ratio: unset`.
   - `:hover .sgf-drawer-reco__name { text-decoration: underline }`,
     el subrayado al pasar por encima que llevamos tres encargos
     quitando del sitio.

   Un componente, un sitio. El carril vive abajo. */
.sgf-drawer-panels {
  margin-top: var(--sgf-space-4);
  border-top: 1px solid var(--sgf-color-border);
}

.sgf-drawer-panel {
  border-bottom: 1px solid var(--sgf-color-border);
}

.sgf-drawer-panel__title {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--sgf-space-3) 0;
  font-size: 13px;
  cursor: pointer;
  list-style: none;
}
.sgf-drawer-panel__title::-webkit-details-marker {
  display: none;
}
.sgf-drawer-panel__title::after {
  content: "+";
  font-family: var(--sgf-font-mono);
  color: var(--sgf-color-muted);
}

.sgf-drawer-panel[open] > .sgf-drawer-panel__title::after {
  content: "−";
}

.sgf-drawer-panel__body {
  padding-bottom: var(--sgf-space-3);
  font-size: 13px;
  line-height: 1.55;
  color: var(--sgf-color-muted);
}
.sgf-drawer-panel__body p {
  margin: 0 0 var(--sgf-space-2);
}
.sgf-drawer-panel__body p:last-child {
  margin-bottom: 0;
}

.sgf-cart-item {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  gap: var(--sgf-space-3);
  align-items: start;
  padding: var(--sgf-space-3);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-md, 8px);
  background: var(--sgf-color-bg);
}
.sgf-cart-item + .sgf-cart-item {
  margin-top: var(--sgf-space-3);
}

.sgf-cart-item__media {
  width: 72px;
}
.sgf-cart-item__media img {
  display: block;
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--sgf-radius-sm);
}

.sgf-cart-item__body {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-1, 4px);
  min-width: 0;
}

.sgf-cart-item__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--sgf-space-2);
}

.sgf-cart-item__name {
  margin: 0;
  font-size: 14px;
  line-height: 1.35;
  min-width: 0;
  overflow-wrap: anywhere;
}

.sgf-cart-item__remove {
  flex: 0 0 auto;
  padding: 0;
  border: 0;
  background: none;
  color: var(--sgf-color-muted);
  font-family: inherit;
  font-size: 13px;
  text-decoration: underline;
  cursor: pointer;
}
.sgf-cart-item__remove:hover, .sgf-cart-item__remove:focus-visible {
  color: var(--sgf-color-text);
}
.sgf-cart-item__remove svg {
  display: none;
}

.sgf-cart-item__meta {
  margin: 0;
  font-size: 13px;
  color: var(--sgf-color-muted);
}

.sgf-cart-item__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-2);
  margin-top: var(--sgf-space-2);
}

.sgf-cart-item__price {
  margin: 0;
  font-size: 14px;
}

.sgf-qty {
  display: inline-flex;
  align-items: center;
  gap: var(--sgf-space-1, 4px);
  padding: 2px;
  border: 1px solid var(--sgf-color-border);
  border-radius: 999px;
}

.sgf-qty__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  font-family: inherit;
  font-size: 15px;
  line-height: 1;
  cursor: pointer;
}
.sgf-qty__btn:hover:not([disabled]) {
  background: var(--sgf-color-surface);
}
.sgf-qty__btn[disabled] {
  opacity: 0.35;
  cursor: default;
}

.sgf-qty__value {
  min-width: 20px;
  text-align: center;
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}

.sgf-cart-drawer .sgf-ship-progress {
  margin: 0;
  padding: var(--sgf-space-3) var(--sgf-space-6);
  background: var(--sgf-color-bg);
  border-bottom: 1px solid var(--sgf-color-border);
  font-size: 13px;
}
.sgf-cart-drawer .sgf-ship-progress.is-empty {
  display: none;
}
.sgf-cart-drawer .sgf-ship-progress .sgf-ship-progress__fill {
  background: var(--sgf-color-text);
}
.sgf-cart-drawer .sgf-ship-progress.is-reached .sgf-ship-progress__fill {
  background: #2e7d4f;
}
.sgf-cart-drawer .sgf-ship-progress.is-reached .sgf-ship-progress__label svg {
  color: #2e7d4f;
}

.sgf-drawer-pay {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-3);
  margin-top: var(--sgf-space-3);
  padding-top: var(--sgf-space-3);
  border-top: 1px solid var(--sgf-color-border);
}

.sgf-drawer-pay__label {
  margin: 0;
  font-size: 12px;
  color: var(--sgf-color-muted);
  text-transform: none;
  letter-spacing: 0;
}

.sgf-drawer-pay__list {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-2);
  margin: 0;
  padding: 0;
  list-style: none;
}

.sgf-drawer-pay__name {
  padding: 0;
  border: 0;
  font-size: 13px;
  color: var(--sgf-color-text);
}

.sgf-drawer-pay__item img {
  max-height: 20px;
}

/* ── Cajón al modo Pas: carril, marcas, cesta vacía ─────────── */
.sgf-cart-drawer__empty {
  padding: var(--sgf-space-3) 0 var(--sgf-space-5);
  text-align: left;
}
.sgf-cart-drawer__empty p {
  margin: 0;
  font-size: 14px;
  line-height: 22px;
  color: var(--sgf-color-text);
}
.sgf-cart-drawer__empty a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.18em;
}

.sgf-drawer-reco {
  margin-top: var(--sgf-space-5);
  padding-top: 0;
  border-top: 0;
}

.sgf-drawer-reco__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-3);
  margin-bottom: var(--sgf-space-4);
}

.sgf-drawer-reco__title {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--sgf-color-text);
}

.sgf-drawer-reco__nav {
  display: flex;
  gap: var(--sgf-space-1);
}

.sgf-drawer-reco__arrow {
  /* La tercera. Era CUADRADA y sin borde mientras las otras dos eran
     círculos: la diferencia no la decidió nadie, la decidió el
     fichero. El tamaño sí es suyo —en un cajón de 28px de alto una
     flecha de 40 se come el ancho— y por eso se pasa como tamaño en
     vez de reinventar la pieza. */
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  background: var(--sgf-color-bg);
  border: 1px solid var(--sgf-color-control);
  border-radius: 50%;
  color: var(--sgf-color-text);
  cursor: pointer;
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-drawer-reco__arrow:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-drawer-reco__arrow:hover {
    border-color: var(--sgf-color-text);
    background: color-mix(in srgb, var(--sgf-color-text) 6%, transparent);
  }
}
.sgf-drawer-reco__arrow svg {
  width: 14px;
  height: 14px;
}
.sgf-drawer-reco__arrow:disabled, .sgf-drawer-reco__arrow[disabled] {
  opacity: 0.35;
  cursor: default;
  pointer-events: none;
}

.sgf-drawer-reco__list {
  display: flex;
  gap: var(--sgf-space-3);
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.sgf-drawer-reco__list::-webkit-scrollbar {
  display: none;
}

.sgf-drawer-reco__item {
  flex: 0 0 104px;
  width: 104px;
  scroll-snap-align: start;
}
.sgf-drawer-reco__item[hidden] {
  display: none;
}

.sgf-drawer-reco__link {
  /* El `gap: 6px` uniforme trataba igual tres relaciones distintas:
     foto→nombre (dos cosas separadas), nombre→precio (una sola cosa,
     el producto) y el hueco que dejaba el `min-height` del nombre.
     El aire lo reparten ahora los propios elementos, cada relación
     con su medida. */
  display: grid;
  justify-items: start;
  row-gap: 0;
  text-decoration: none;
  color: inherit;
}

.sgf-drawer-reco__media {
  position: relative;
  display: block;
  width: 104px;
  height: 104px;
  background: var(--sgf-color-surface);
  overflow: hidden;
}
.sgf-drawer-reco__media img,
.sgf-drawer-reco__media .sgf-drawer-reco__img {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  border-radius: 0;
  aspect-ratio: unset;
}

/* UNA LÍNEA, Y SIN `-webkit-box` — 1 oct
   --------------------------------------
   El recorte se hacía con `display: -webkit-box` + `line-clamp`. Con
   el enlace en `grid`, el navegador BLOQUIFICA a sus hijos y ese
   `display` se convierte en `flow-root`: el recorte dejaba de
   aplicarse sin avisar —medido en vivo— y un nombre largo habría
   partido en dos líneas, bajando el precio de esa tarjeta y
   desalineándolo del de al lado.

   Una línea con puntos suspensivos no depende del `display`, así que
   no se puede romper igual. Y es lo que hace falta: con todas las
   tarjetas de la misma altura, los precios quedan a la misma raya. */
.sgf-drawer-reco__name,
.sgf-drawer-reco__price {
  overflow: hidden;
  width: 100%;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 12px;
  line-height: 16px;
  color: var(--sgf-color-text);
}

/* NOMBRE Y PRECIO SON UNA SOLA COSA — 1 oct
   ----------------------------------------
   El nombre se recortaba a DOS líneas con `min-height: 32px`, así que
   un vino que se llama «Rosado» dejaba una línea en blanco entre su
   nombre y su precio: 22px de hueco donde debería haber 2. Se leía
   como si el precio fuera de otra tarjeta.

   El `min-height` estaba ahí para que los precios quedaran a la misma
   altura en todas las tarjetas. Se consigue igual recortando el
   nombre a UNA línea —son nombres de vino, caben— y entonces todas
   las tarjetas miden lo mismo sin reservar aire vacío.

   El aire que sí hace falta es el de después de la foto: ahí sí hay
   un salto entre dos cosas distintas. */
.sgf-drawer-reco__name {
  margin-top: 10px;
}

.sgf-drawer-reco__price {
  margin-top: 2px;
  color: var(--sgf-color-muted);
}

/* «Añadir» era texto subrayado, que es lo que hace un enlace, y esto
   no lo es: mete el vino en la cesta sin salir del cajón. Ahora tiene
   forma de control —perfil fino, todo el ancho de la tarjeta— y el
   subrayado se va, como en el resto del sitio. */
.sgf-drawer-reco__add {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  margin-top: 8px;
  padding: 0;
  height: 26px;
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-pill);
  background: none;
  font-family: inherit;
  font-size: 12px;
  line-height: 16px;
  color: var(--sgf-color-text);
  text-decoration: none;
  cursor: pointer;
  transition: border-color var(--sgf-duration-fast) var(--sgf-ease), background-color var(--sgf-duration-fast) var(--sgf-ease);
}
.sgf-drawer-reco__add:hover, .sgf-drawer-reco__add:focus-visible {
  border-color: var(--sgf-color-text);
  background: color-mix(in srgb, var(--sgf-color-text) 6%, transparent);
  text-decoration: none;
}

.sgf-cart-drawer__footer .sgf-drawer-pay,
.sgf-cart-drawer__footer .sgf-drawer-panels {
  margin: 0;
}

.sgf-drawer-pay {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sgf-space-3);
  margin: 0;
  padding: 14px var(--sgf-space-6);
  border-top: 1px solid var(--sgf-color-border);
  border-bottom: 0;
}

.sgf-drawer-pay__label {
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--sgf-color-text);
}

.sgf-drawer-pay__list {
  display: flex;
  align-items: center;
  gap: 10px;
}

.sgf-drawer-pay__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: 18px;
  line-height: 0;
}
.sgf-drawer-pay__item svg {
  display: block;
  height: 14px;
  width: auto;
}
.sgf-drawer-pay__item.sgf-drawer-pay__item--visa svg {
  height: 13px;
}
.sgf-drawer-pay__item.sgf-drawer-pay__item--mastercard svg {
  height: 16px;
}
.sgf-drawer-pay__item.sgf-drawer-pay__item--apple svg {
  height: 15px;
}

.sgf-drawer-pay__word {
  margin-left: 2px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: -0.02em;
  color: #111;
}

.sgf-drawer-panels {
  margin-top: 0;
  border-top: 0;
}

.sgf-drawer-panel {
  border-top: 1px solid var(--sgf-color-border);
  border-bottom: 0;
}

.sgf-drawer-panel__title {
  padding: 14px var(--sgf-space-6);
  font-size: 14px;
  line-height: 20px;
  color: var(--sgf-color-text);
}

.sgf-drawer-panel__body {
  padding: 0 var(--sgf-space-6) 14px;
}

.sgf-cart-item {
  padding: var(--sgf-space-4) 0;
  border: 0;
  border-bottom: 1px solid var(--sgf-color-border);
  border-radius: 0;
  background: none;
}
.sgf-cart-item + .sgf-cart-item {
  margin-top: 0;
}

.sgf-cart-item__media img {
  width: 72px;
  height: 90px;
  object-fit: cover;
  border-radius: 0;
  aspect-ratio: 4/5;
}

/* Forms
--------------------------------------------- */
.sgf-form {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-5);
}

.sgf-field {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-2);
}
.sgf-field__label {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
}
.sgf-field__hint {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  font-style: italic;
}
.sgf-field {
  /* Al token, no a un `hsl()` escrito a mano. Estaba tres veces en
     este fichero y una cuarta en feedback: cuatro sitios donde
     cambiar el rojo de error y tres donde olvidarse. */
}
.sgf-field__error {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-error);
}
.sgf-field--error .sgf-field__input {
  border-color: var(--sgf-color-error);
}
.sgf-field--success .sgf-field__input {
  border-color: var(--sgf-color-success);
}

.sgf-input {
  display: block;
  width: 100%;
  padding: var(--sgf-space-3) var(--sgf-space-4);
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-sm);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-sm);
  line-height: 1.5;
  transition: border-color var(--sgf-duration-fast) var(--sgf-ease-out);
  -webkit-appearance: none;
}
.sgf-input::placeholder {
  color: var(--sgf-color-muted);
}
.sgf-input:hover:not(:disabled):not([readonly]) {
  border-color: var(--sgf-color-text);
}
.sgf-input:focus {
  outline: none;
  border-color: var(--sgf-color-text);
}
.sgf-input:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
.sgf-input {
  /* Por `aria-invalid`, que es el atributo que ya leen los lectores
     de pantalla. El aviso visual y el hablado salen del MISMO sitio:
     no hay forma de pintar el borde rojo y olvidarse de anunciarlo,
     ni al reves. */
}
.sgf-input[aria-invalid=true] {
  border-color: var(--sgf-color-error);
}
.sgf-input[aria-invalid=true]:focus-visible {
  outline-color: var(--sgf-color-error);
}
.sgf-input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.sgf-input {
  /* Solo lectura no es lo mismo que desactivado: el texto SE LEE
     —y se copia— asi que no se apaga. Lo que se quita es la
     invitacion a escribir. */
}
.sgf-input[readonly] {
  border-color: transparent;
  background: var(--sgf-color-bg-alt, var(--sgf-color-surface));
  cursor: default;
}
.sgf-input--sm {
  padding: var(--sgf-space-2) var(--sgf-space-3);
  font-size: var(--sgf-text-xs);
}
.sgf-input--lg {
  padding: var(--sgf-space-4) var(--sgf-space-5);
  font-size: var(--sgf-text-base);
}

.sgf-search-field {
  position: relative;
}
.sgf-search-field::after {
  content: "";
  position: absolute;
  right: var(--sgf-space-4);
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cline x1='21' y1='21' x2='16.65' y2='16.65'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-size: contain;
  pointer-events: none;
}
.sgf-search-field__input {
  padding-right: var(--sgf-space-10);
}

.sgf-textarea {
  display: block;
  width: 100%;
  padding: var(--sgf-space-3) var(--sgf-space-4);
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-sm);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-sm);
  line-height: 1.5;
  min-height: 120px;
  resize: vertical;
  transition: border-color var(--sgf-duration-fast) var(--sgf-ease-out);
  -webkit-appearance: none;
}
.sgf-textarea::placeholder {
  color: var(--sgf-color-muted);
}
.sgf-textarea:hover:not(:disabled):not([readonly]) {
  border-color: var(--sgf-color-text);
}
.sgf-textarea:focus {
  outline: none;
  border-color: var(--sgf-color-text);
}
.sgf-textarea:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
.sgf-textarea {
  /* Por `aria-invalid`, que es el atributo que ya leen los lectores
     de pantalla. El aviso visual y el hablado salen del MISMO sitio:
     no hay forma de pintar el borde rojo y olvidarse de anunciarlo,
     ni al reves. */
}
.sgf-textarea[aria-invalid=true] {
  border-color: var(--sgf-color-error);
}
.sgf-textarea[aria-invalid=true]:focus-visible {
  outline-color: var(--sgf-color-error);
}
.sgf-textarea:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.sgf-textarea {
  /* Solo lectura no es lo mismo que desactivado: el texto SE LEE
     —y se copia— asi que no se apaga. Lo que se quita es la
     invitacion a escribir. */
}
.sgf-textarea[readonly] {
  border-color: transparent;
  background: var(--sgf-color-bg-alt, var(--sgf-color-surface));
  cursor: default;
}

.sgf-select {
  display: block;
  width: 100%;
  padding: var(--sgf-space-3) var(--sgf-space-10) var(--sgf-space-3) var(--sgf-space-4);
  background: var(--sgf-color-surface);
  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='%23888' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--sgf-space-4) center;
  background-size: 12px;
  color: var(--sgf-color-text);
  border: 1px solid var(--sgf-color-border);
  border-radius: var(--sgf-radius-sm);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-sm);
  line-height: 1.5;
  cursor: pointer;
  transition: border-color var(--sgf-duration-fast) var(--sgf-ease-out);
  -webkit-appearance: none;
}
.sgf-select:hover:not(:disabled):not([readonly]) {
  border-color: var(--sgf-color-text);
}
.sgf-select:focus {
  outline: none;
  border-color: var(--sgf-color-text);
}
.sgf-select:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
.sgf-select {
  /* Por `aria-invalid`, que es el atributo que ya leen los lectores
     de pantalla. El aviso visual y el hablado salen del MISMO sitio:
     no hay forma de pintar el borde rojo y olvidarse de anunciarlo,
     ni al reves. */
}
.sgf-select[aria-invalid=true] {
  border-color: var(--sgf-color-error);
}
.sgf-select[aria-invalid=true]:focus-visible {
  outline-color: var(--sgf-color-error);
}
.sgf-select:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.sgf-select {
  /* Solo lectura no es lo mismo que desactivado: el texto SE LEE
     —y se copia— asi que no se apaga. Lo que se quita es la
     invitacion a escribir. */
}
.sgf-select[readonly] {
  border-color: transparent;
  background: var(--sgf-color-bg-alt, var(--sgf-color-surface));
  cursor: default;
}

.sgf-check {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-3);
  cursor: pointer;
}
.sgf-check input[type=checkbox],
.sgf-check input[type=radio] {
  width: 16px;
  height: 16px;
  appearance: none;
  -webkit-appearance: none;
  border: 1.5px solid var(--sgf-color-border);
  background: var(--sgf-color-surface);
  border-radius: var(--sgf-check-radius);
  flex-shrink: 0;
  cursor: pointer;
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), transform var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-check input[type=checkbox]:checked {
  background-color: var(--sgf-color-text);
  border-color: var(--sgf-color-text);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='2 6 5 9 10 3'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 10px;
}
.sgf-check {
  /* LA FORMA VUELVE A DECIR CUANTOS PUEDES ELEGIR — 30 sep
     ------------------------------------------------------
     Estuvo todo cuadrado un dia. El motivo era real —convivian seis
     circulos con veinte cuadrados y la columna se veia descosida—
     pero el precio era peor que la enfermedad: redondo y cuadrado no
     son decoracion, son un codigo que la gente ya sabe leer sin que
     nadie se lo explique.

       cuadrado redondeado  ->  puedes marcar varios
       circulo              ->  solo cabe uno

     Unificar la silueta borraba esa pista y dejaba al cliente
     probando a ver que pasa. Vuelven las dos formas.

     El descosido que lo motivo se arregla por otro lado: ahora las
     casillas son todas iguales porque solo hay UNA implementacion,
     no porque todas sean cuadradas. */
}
.sgf-check input[type=radio] {
  border-radius: 50%;
}
.sgf-check input[type=radio]:checked {
  border-color: var(--sgf-color-text);
  box-shadow: inset 0 0 0 3px var(--sgf-color-text);
  background-color: var(--sgf-color-surface);
}
.sgf-check {
  /* ─── LOS ESTADOS QUE FALTABAN ─────────────────────────────
     Habia tres: reposo, marcado y desactivado. Un control pulido
     tiene ocho, y la diferencia no es decorativa: cada uno responde
     a una pregunta distinta del que lo usa.

       reposo          ¿esto se puede tocar?
       hover           ¿estoy encima del que quiero?
       active          ¿ha registrado mi clic?
       focus-visible   ¿dónde estoy con el teclado?
       marcado         ¿cuál elegí?
       indeterminado   ¿está a medias?
       error           ¿qué tengo que arreglar?
       desactivado     ¿por qué no puedo?

     Faltaban cuatro, y `focus-visible` es el que mas duele: sin el,
     quien navega con teclado no sabe donde esta. */
}
.sgf-check input[type=checkbox]:hover:not(:disabled),
.sgf-check input[type=radio]:hover:not(:disabled) {
  border-color: var(--sgf-color-text);
}
.sgf-check input[type=checkbox]:active:not(:disabled),
.sgf-check input[type=radio]:active:not(:disabled) {
  transform: scale(0.92);
}
.sgf-check {
  /* ── Foco de teclado ──
     `:focus-visible` y NO `:focus`. `:focus` tambien salta al hacer
     clic con el raton, asi que dejaba un cerco alrededor de cada
     casilla que acababas de pulsar: ruido para quien usa raton y
     ninguna ayuda para quien usa teclado.

     Va en `outline` con `offset` y no en `border`: el borde ya dice
     otra cosa (reposo / hover / error) y el contorno no mueve la
     maquetacion ni un pixel al aparecer. */
}
.sgf-check input[type=checkbox]:focus-visible,
.sgf-check input[type=radio]:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
.sgf-check {
  /* ── A medias ──
     Una raya, no un visto. Un visto dice "todo"; el indeterminado
     dice "algunos", y son respuestas distintas a la misma pregunta.
     Lo usa una casilla que gobierna a otras: «Marida con» cuando
     solo hay dos de cuatro marcadas. */
}
.sgf-check input[type=checkbox]:indeterminate {
  background-color: var(--sgf-color-text);
  border-color: var(--sgf-color-text);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 12 12' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round'%3E%3Cline x1='3' y1='6' x2='9' y2='6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 10px;
}
.sgf-check {
  /* ── Error ──
     Por `aria-invalid`, que es el atributo que ya leen los lectores
     de pantalla. Asi el aviso visual y el hablado salen del MISMO
     sitio y no pueden contradecirse: no hay forma de pintar el
     borde rojo y olvidarse de anunciarlo. */
}
.sgf-check input[type=checkbox][aria-invalid=true],
.sgf-check input[type=radio][aria-invalid=true] {
  border-color: var(--sgf-color-error);
}
.sgf-check input[type=checkbox]:disabled,
.sgf-check input[type=radio]:disabled {
  opacity: 0.4;
  cursor: not-allowed;
}
.sgf-check input:disabled ~ .sgf-check__label {
  opacity: 0.4;
  cursor: not-allowed;
}
.sgf-check {
  /* ── El dedo necesita mas sitio que el raton ──
     La casilla dibuja 16px porque a mas se ve tosca, pero 16px no
     se aciertan con el pulgar. En pantalla tactil la ETIQUETA
     entera pasa a 44px de alto, que es el minimo reconocido, sin
     agrandar el dibujo ni estirar el panel en escritorio. */
}
@media (pointer: coarse) {
  .sgf-check {
    min-height: 44px;
  }
}
.sgf-check__label {
  font-family: var(--sgf-font-body);
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  letter-spacing: 0;
  text-transform: none;
  cursor: pointer;
  color: var(--sgf-color-text);
}

.sgf-toggle {
  display: flex;
  align-items: center;
  gap: var(--sgf-space-3);
  cursor: pointer;
}
.sgf-toggle input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border-width: 0;
}
.sgf-toggle__track {
  position: relative;
  width: 44px;
  height: 24px;
  border-radius: 12px;
  background: var(--sgf-color-surface);
  border: 1.5px solid var(--sgf-color-border);
  flex-shrink: 0;
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-toggle__thumb {
  position: absolute;
  left: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--sgf-color-muted);
  transition: transform var(--sgf-duration-fast) var(--sgf-ease-spring), background-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
input:checked ~ .sgf-toggle__track {
  background: var(--sgf-color-accent);
  border-color: var(--sgf-color-accent);
}
input:checked ~ .sgf-toggle__track .sgf-toggle__thumb {
  transform: translateY(-50%) translateX(20px);
  background: var(--sgf-color-bg);
}
.sgf-toggle__label {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  color: var(--sgf-color-text);
}

.sgf-qty {
  display: inline-flex;
  align-items: center;
  height: 40px;
  padding-inline: 4px;
  background: var(--sgf-color-bg);
  border: 1px solid var(--sgf-color-control);
  border-radius: 999px;
}
.sgf-qty__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 32px;
  height: 32px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 50%;
  cursor: pointer;
  font-family: var(--sgf-font-body);
  font-size: 18px;
  line-height: 1;
  color: var(--sgf-color-text);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-qty__btn:hover:not(:disabled) {
  background: var(--sgf-color-surface);
}
.sgf-qty__btn:disabled {
  color: var(--sgf-color-control);
  cursor: default;
}
.sgf-qty__value, .sgf-qty__input {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: 40px;
  height: 100%;
  background: transparent;
  border: 0;
  text-align: center;
  font-family: var(--sgf-font-body);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  color: var(--sgf-color-text);
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}
.sgf-qty__value::-webkit-outer-spin-button, .sgf-qty__value::-webkit-inner-spin-button, .sgf-qty__input::-webkit-outer-spin-button, .sgf-qty__input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.sgf-qty__value:focus, .sgf-qty__input:focus {
  outline: none;
}

.sgf-form-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sgf-space-5);
}
@media (max-width: 639px) {
  .sgf-form-row {
    grid-template-columns: 1fr;
  }
}

.sgf-newsletter {
  display: flex;
  gap: var(--sgf-space-3);
}
.sgf-newsletter__input {
  flex: 1;
}
.sgf-newsletter__btn {
  flex-shrink: 0;
}
@media (max-width: 479px) {
  .sgf-newsletter {
    flex-direction: column;
  }
}

/* Feedback
--------------------------------------------- */
.sgf-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--sgf-space-2);
  font-family: var(--sgf-font-mono);
  font-size: 10px;
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  border: 1px solid currentColor;
  border-radius: var(--sgf-radius-sm);
}
.sgf-badge--accent {
  color: var(--sgf-color-accent);
}
.sgf-badge--muted {
  color: var(--sgf-color-muted);
}
.sgf-badge--success {
  color: hsl(145, 50%, 55%);
}
.sgf-badge--error {
  color: hsl(0, 65%, 55%);
}
.sgf-badge--sale {
  background: var(--sgf-color-accent);
  color: var(--sgf-color-bg);
  border-color: transparent;
}
.sgf-badge--new {
  background: var(--sgf-color-surface);
  color: var(--sgf-color-text);
  border-color: var(--sgf-color-border);
}

.sgf-alert {
  display: flex;
  gap: var(--sgf-space-4);
  padding: var(--sgf-space-4) var(--sgf-space-5);
  border-left: 3px solid currentColor;
  background: var(--sgf-color-surface);
}
.sgf-alert__icon {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
}
.sgf-alert__body {
  flex: 1;
}
.sgf-alert__title {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-sm);
  font-weight: 500;
  margin-bottom: var(--sgf-space-1);
  color: var(--sgf-color-text);
}
.sgf-alert__text {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
}
.sgf-alert--info {
  color: var(--sgf-color-accent);
}
.sgf-alert--success {
  color: hsl(145, 50%, 55%);
}
.sgf-alert--warning {
  color: hsl(38, 85%, 55%);
}
.sgf-alert--error {
  color: hsl(0, 65%, 55%);
}

.sgf-toast-stack {
  position: fixed;
  bottom: var(--sgf-space-6);
  right: var(--sgf-space-6);
  z-index: var(--sgf-z-toast, 1100);
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-3);
  pointer-events: none;
}

.sgf-toast {
  pointer-events: auto;
  display: flex;
  align-items: center;
  gap: var(--sgf-space-3);
  padding: var(--sgf-space-3) var(--sgf-space-5);
  background: var(--sgf-color-surface);
  border: 1px solid var(--sgf-color-border);
  border-left: 3px solid currentColor;
  max-width: 320px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  transform: translateX(120%);
  opacity: 0;
  transition: transform var(--sgf-duration-base) var(--sgf-ease-out), opacity var(--sgf-duration-base) var(--sgf-ease-out);
}
.sgf-toast.is-visible {
  transform: translateX(0);
  opacity: 1;
}
.sgf-toast.is-hiding {
  transform: translateX(120%);
  opacity: 0;
}
.sgf-toast__text {
  font-family: var(--sgf-font-body);
  font-size: var(--sgf-text-xs);
  flex: 1;
  color: var(--sgf-color-text);
}
.sgf-toast__close {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  margin-left: auto;
  cursor: pointer;
  background: none;
  border: none;
  padding: 0;
  line-height: 1;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-toast__close:hover {
  color: var(--sgf-color-accent);
}
.sgf-toast--success {
  color: hsl(145, 50%, 55%);
}
.sgf-toast--error {
  color: hsl(0, 65%, 55%);
}
.sgf-toast--info {
  color: var(--sgf-color-accent);
}

@keyframes sgf-shimmer {
  from {
    background-position: -200% 0;
  }
  to {
    background-position: 200% 0;
  }
}
.sgf-skeleton {
  background: linear-gradient(90deg, var(--sgf-color-surface) 25%, var(--sgf-color-border) 50%, var(--sgf-color-surface) 75%);
  background-size: 200% 100%;
  animation: sgf-shimmer 1.4s ease infinite;
  border-radius: var(--sgf-radius-sm);
}
.sgf-skeleton--text {
  height: 1em;
  width: 100%;
  margin-bottom: var(--sgf-space-2);
}
.sgf-skeleton--text-sm {
  height: 0.75em;
  width: 60%;
}
.sgf-skeleton--circle {
  border-radius: 50%;
}
.sgf-skeleton--card {
  aspect-ratio: 3/4;
  width: 100%;
}
.sgf-skeleton--image {
  aspect-ratio: 16/9;
  width: 100%;
}

@media (prefers-reduced-motion: reduce) {
  .sgf-skeleton {
    animation: none;
  }
}
.sgf-progress {
  width: 100%;
  height: 3px;
  background: var(--sgf-color-surface);
  border-radius: 2px;
  overflow: hidden;
}
.sgf-progress__fill {
  height: 100%;
  background: var(--sgf-color-accent);
  border-radius: 2px;
  transition: width var(--sgf-duration-slow) var(--sgf-ease-out);
}
.sgf-progress--shipping {
  height: 2px;
  margin-block: var(--sgf-space-2);
}

@keyframes sgf-spin {
  to {
    transform: rotate(360deg);
  }
}
.sgf-spinner {
  width: 20px;
  height: 20px;
  border: 2px solid var(--sgf-color-border);
  border-top-color: var(--sgf-color-accent);
  border-radius: 50%;
  animation: sgf-spin 0.6s linear infinite;
  flex-shrink: 0;
}
.sgf-spinner--sm {
  width: 14px;
  height: 14px;
}
.sgf-spinner--lg {
  width: 32px;
  height: 32px;
  border-width: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .sgf-spinner {
    animation-duration: 2s;
  }
}
/* Breadcrumb
--------------------------------------------- */
.sgf-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sgf-space-2);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
}
.sgf-breadcrumb a {
  color: inherit;
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-breadcrumb a:hover {
  color: var(--sgf-color-text);
}
.sgf-breadcrumb__separator {
  color: var(--sgf-color-border);
}
.sgf-breadcrumb .breadcrumb-item + .breadcrumb-item::before,
.sgf-breadcrumb span + span::before {
  content: "/";
  margin-right: var(--sgf-space-2);
  color: var(--sgf-color-border);
}

/* Tabs
--------------------------------------------- */
.sgf-tabs__list {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--sgf-color-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.sgf-tabs__list::-webkit-scrollbar {
  display: none;
}
.sgf-tabs__tab {
  padding: var(--sgf-space-3) var(--sgf-space-5);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
  cursor: pointer;
  border: none;
  background: none;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-tabs__tab:hover {
  color: var(--sgf-color-text);
}
.sgf-tabs__tab[aria-selected=true], .sgf-tabs__tab.is-active {
  color: var(--sgf-color-text);
  border-bottom-color: var(--sgf-color-accent);
}
.sgf-tabs__panel {
  padding-top: var(--sgf-space-6);
}
.sgf-tabs__panel[hidden] {
  display: none;
}

.woocommerce-tabs .tabs {
  display: flex;
  gap: 0;
  border-bottom: 1px solid var(--sgf-color-border);
  overflow-x: auto;
  scrollbar-width: none;
  list-style: none;
  margin: 0;
  padding: 0;
}
.woocommerce-tabs .tabs::-webkit-scrollbar {
  display: none;
}
.woocommerce-tabs .tabs li {
  list-style: none;
}
.woocommerce-tabs .tabs li a {
  display: block;
  padding: var(--sgf-space-3) var(--sgf-space-5);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
  color: var(--sgf-color-muted);
  text-decoration: none;
  white-space: nowrap;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.woocommerce-tabs .tabs li a:hover {
  color: var(--sgf-color-text);
}
.woocommerce-tabs .tabs .active a {
  color: var(--sgf-color-text);
  border-bottom: 2px solid var(--sgf-color-accent);
  margin-bottom: -1px;
}
.woocommerce-tabs .panel {
  padding-top: var(--sgf-space-6);
}

/* Pagination
--------------------------------------------- */
.sgf-pagination,
.navigation.pagination,
.woocommerce-pagination {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sgf-space-2);
  padding-block: var(--sgf-space-12);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
}
.sgf-pagination .page-numbers,
.sgf-pagination a,
.sgf-pagination span,
.navigation.pagination .page-numbers,
.navigation.pagination a,
.navigation.pagination span,
.woocommerce-pagination .page-numbers,
.woocommerce-pagination a,
.woocommerce-pagination span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 36px;
  height: 36px;
  padding-inline: var(--sgf-space-3);
  color: var(--sgf-color-muted);
  text-decoration: none;
  border: 1px solid transparent;
  border-radius: var(--sgf-radius-pill);
  transition: background-color var(--sgf-duration-fast) var(--sgf-ease-out), border-color var(--sgf-duration-fast) var(--sgf-ease-out), color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.sgf-pagination .page-numbers:focus-visible,
.sgf-pagination a:focus-visible,
.sgf-pagination span:focus-visible,
.navigation.pagination .page-numbers:focus-visible,
.navigation.pagination a:focus-visible,
.navigation.pagination span:focus-visible,
.woocommerce-pagination .page-numbers:focus-visible,
.woocommerce-pagination a:focus-visible,
.woocommerce-pagination span:focus-visible {
  outline: 2px solid var(--sgf-color-text);
  outline-offset: 2px;
}
@media (hover: hover) and (pointer: fine) {
  .sgf-pagination .page-numbers:hover,
  .sgf-pagination a:hover,
  .sgf-pagination span:hover,
  .navigation.pagination .page-numbers:hover,
  .navigation.pagination a:hover,
  .navigation.pagination span:hover,
  .woocommerce-pagination .page-numbers:hover,
  .woocommerce-pagination a:hover,
  .woocommerce-pagination span:hover {
    color: var(--sgf-color-text);
    border-color: var(--sgf-color-control);
  }
}
.sgf-pagination .page-numbers.current, .sgf-pagination .page-numbers[aria-current=page],
.sgf-pagination a.current,
.sgf-pagination a[aria-current=page],
.sgf-pagination span.current,
.sgf-pagination span[aria-current=page],
.navigation.pagination .page-numbers.current,
.navigation.pagination .page-numbers[aria-current=page],
.navigation.pagination a.current,
.navigation.pagination a[aria-current=page],
.navigation.pagination span.current,
.navigation.pagination span[aria-current=page],
.woocommerce-pagination .page-numbers.current,
.woocommerce-pagination .page-numbers[aria-current=page],
.woocommerce-pagination a.current,
.woocommerce-pagination a[aria-current=page],
.woocommerce-pagination span.current,
.woocommerce-pagination span[aria-current=page] {
  color: var(--sgf-color-text);
  border-color: var(--sgf-color-text);
}
.sgf-pagination .page-numbers.prev, .sgf-pagination .page-numbers.next,
.sgf-pagination a.prev,
.sgf-pagination a.next,
.sgf-pagination span.prev,
.sgf-pagination span.next,
.navigation.pagination .page-numbers.prev,
.navigation.pagination .page-numbers.next,
.navigation.pagination a.prev,
.navigation.pagination a.next,
.navigation.pagination span.prev,
.navigation.pagination span.next,
.woocommerce-pagination .page-numbers.prev,
.woocommerce-pagination .page-numbers.next,
.woocommerce-pagination a.prev,
.woocommerce-pagination a.next,
.woocommerce-pagination span.prev,
.woocommerce-pagination span.next {
  padding-inline: var(--sgf-space-4);
}
.sgf-pagination .page-numbers.dots,
.sgf-pagination a.dots,
.sgf-pagination span.dots,
.navigation.pagination .page-numbers.dots,
.navigation.pagination a.dots,
.navigation.pagination span.dots,
.woocommerce-pagination .page-numbers.dots,
.woocommerce-pagination a.dots,
.woocommerce-pagination span.dots {
  border-color: transparent;
  pointer-events: none;
}

.post-navigation {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sgf-space-6);
  padding-block: var(--sgf-space-12);
  border-top: 1px solid var(--sgf-color-border);
}
.post-navigation .nav-previous,
.post-navigation .nav-next {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-2);
}
.post-navigation .nav-next {
  text-align: right;
  align-items: flex-end;
}
.post-navigation .nav-subtitle {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  text-transform: uppercase;
  letter-spacing: var(--sgf-tracking-wide);
}
.post-navigation a {
  font-size: var(--sgf-text-sm);
  color: var(--sgf-color-text);
  text-decoration: none;
  transition: color var(--sgf-duration-fast) var(--sgf-ease-out);
}
.post-navigation a:hover {
  color: var(--sgf-color-accent);
}

/* Posts and pages
--------------------------------------------- */
.sgf-post-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(320px, 100%), 1fr));
  gap: var(--sgf-space-8);
  margin: var(--sgf-space-12) 0;
}

.sgf-post-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--sgf-color-border);
  background: var(--sgf-color-surface);
  transition: border-color var(--sgf-duration-base) var(--sgf-ease);
}
.sgf-post-card:hover {
  border-color: var(--sgf-color-accent);
}

.sgf-post-card__thumb {
  display: block;
  aspect-ratio: var(--sgf-ratio-retrato);
  overflow: hidden;
}

.sgf-post-card__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform var(--sgf-duration-slow) var(--sgf-ease);
}
.sgf-post-card:hover .sgf-post-card__img {
  transform: scale(1.03);
}

.sgf-post-card__body {
  padding: var(--sgf-space-6);
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--sgf-space-3);
}

.sgf-post-card__meta {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  letter-spacing: var(--sgf-tracking-wide);
}

.sgf-post-card__title {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-xl);
  font-weight: 400;
  line-height: var(--sgf-leading-snug);
  letter-spacing: var(--sgf-tracking-tight);
  margin: 0;
}
.sgf-post-card__title a {
  color: var(--sgf-color-text);
  text-decoration: none;
}

.sgf-post-card__excerpt {
  color: var(--sgf-color-muted);
  font-size: var(--sgf-text-sm);
  line-height: var(--sgf-leading-base);
  margin: 0;
  flex: 1;
}

.sgf-post-card__link {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  letter-spacing: var(--sgf-tracking-wider);
  text-transform: uppercase;
  color: var(--sgf-color-accent);
  text-decoration: none;
  margin-top: auto;
}
.sgf-post-card__link:hover {
  text-decoration: underline;
}

/* .sgf-entry ya NO limita el ancho.
   Llevaba max-width: 72ch, la medida de lectura, puesta en el
   contenedor exterior. Eso encajonaba en 640px cualquier cosa que
   viviera dentro de una pagina —la cuenta, la cesta, la caja— aunque
   no fueran texto corrido, y las dejaba pegadas a la izquierda con
   media pantalla vacia al lado.

   La medida no se pierde: el texto la sigue teniendo por dentro, en
   `p` y en `.sgf-entry__content > *`, que es donde corresponde. Se
   limita lo que se lee, no lo que se usa. */
.sgf-entry__hero,
.sgf-entry__featured {
  margin-bottom: var(--sgf-space-12);
}
.sgf-entry__hero img,
.sgf-entry__featured img {
  width: 100%;
  max-height: 60vh;
  object-fit: cover;
}

.sgf-entry__header {
  margin-bottom: var(--sgf-space-10);
}

.sgf-entry__meta {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  letter-spacing: var(--sgf-tracking-wide);
  margin-bottom: var(--sgf-space-4);
  display: flex;
  gap: var(--sgf-space-4);
  flex-wrap: wrap;
}

.sgf-entry__title {
  font-family: var(--sgf-font-display);
  font-size: clamp(var(--sgf-text-3xl), 5vw, var(--sgf-text-4xl));
  line-height: var(--sgf-leading-tight);
  letter-spacing: var(--sgf-tracking-tight);
  font-weight: 400;
}

.sgf-entry__content {
  line-height: var(--sgf-leading-loose);
  color: var(--sgf-color-text);
  /* El margen entre hermanos es para PROSA: parrafo tras parrafo.
     Una seccion de portada ya trae su propio aire (`--sgf-section-y`)
     y sumarle 19px mas descuadra el ritmo sin que se vea de donde
     sale. Medido: cuatro separaciones distintas en una pagina que
     deberia tener una. */
}
.sgf-entry__content > * + * {
  margin-top: 1.2em;
}
.sgf-entry__content {
  /* Un bloque que trae su propio `padding-block` no lleva margen:
     los dos, no solo el de arriba. Medido: la primera version de
     esta regla anulaba `margin-top` y dejaba pasar el
     `margin-bottom: 56px` que `figure` hereda de la prosa, asi que
     una de las ocho separaciones seguia siendo distinta. */
}
.sgf-entry__content > .sgf-home-section,
.sgf-entry__content > .sgf-dos,
.sgf-entry__content > .sgf-mosaico,
.sgf-entry__content > .sgf-indice,
.sgf-entry__content > .sgf-cifras,
.sgf-entry__content > .sgf-ficha,
.sgf-entry__content > .sgf-pilares,
.sgf-entry__content > .sgf-coleccion,
.sgf-entry__content > .sgf-manifiesto,
.sgf-entry__content > .sgf-anada,
.sgf-entry__content > .sgf-tile-row,
.sgf-entry__content > .alignfull {
  margin-block: 0;
}
.sgf-entry__content > * {
  max-width: 68ch;
}
.sgf-entry__content {
  /* ...pero 68ch es una MEDIDA DE LECTURA, y una rejilla no se lee:
     se recorre. Hasta ahora solo escapaban de ella los bloques con
     `alignfull` o `alignwide`, o sea los que alguien se acordo de
     marcar en el editor. Un bloque de maquetacion sin marcar salia
     a 605px con la pagina a 961: las tarjetas de cifras y la
     reticula de uvas ocupaban dos tercios y dejaban el resto en
     blanco, que es justo lo que venian a resolver.

     La medida la llevan los elementos de texto, no las cajas que
     los contienen. */
}
.sgf-entry__content > .sgf-home-section,
.sgf-entry__content > .sgf-dos,
.sgf-entry__content > .sgf-mosaico,
.sgf-entry__content > .sgf-indice,
.sgf-entry__content > .sgf-cifras,
.sgf-entry__content > .sgf-ficha,
.sgf-entry__content > .sgf-pilares,
.sgf-entry__content > .sgf-coleccion,
.sgf-entry__content > .sgf-manifiesto,
.sgf-entry__content > .sgf-anada,
.sgf-entry__content > .sgf-tile-row,
.sgf-entry__content > .sgf-hero,
.sgf-entry__content > .sgf-lamina {
  max-width: none;
}
.sgf-entry__content > h2, .sgf-entry__content > h3, .sgf-entry__content > h4 {
  margin-top: var(--sgf-space-10);
}
.sgf-entry__content {
  /* ANCHO COMPLETO: LA SALIDA DE LA MEDIDA DE LECTURA — 29 sep
     ----------------------------------------------------------
     La regla de arriba pone 68ch a TODO hijo directo. Es correcta
     para prosa y es un desastre para una seccion: un hero puesto a
     «ancho completo» desde el editor salia a 605px en una pantalla
     de 1009, y no habia manera de verlo desde el editor porque la
     opcion estaba marcada. El atributo si estaba; lo que faltaba
     era que alguien lo escribiera en el HTML y que el CSS lo
     respetara. Las dos mitades del arreglo.

     Especificidad: la que acota es `> *` (0,1,0). Estas llevan
     clase, o sea (0,2,0), y le ganan sin `!important`.

     El tiron lateral es EXACTAMENTE el canal del contenedor, no
     `calc(50% - 50vw)`. `100vw` incluye la barra de scroll, asi que
     la formula clasica se sale unos pixeles por la derecha y saca
     scroll horizontal en escritorio. Restando el canal se llega
     justo al borde y ni uno mas. */
}
.sgf-entry__content > .alignfull {
  max-width: none;
  width: auto;
  margin-inline: calc(var(--sgf-gutter) * -1);
}
.sgf-entry__content {
  /* «Ancho» ya no es un tercer ancho: el contenedor va a sangre y
     lo unico que sobra es la medida de lectura. Asi que `alignwide`
     es simplemente «todo el contenido», sin salirse del canal. */
}
.sgf-entry__content > .alignwide {
  max-width: none;
  width: auto;
}

.sgf-entry__footer {
  margin-top: var(--sgf-space-12);
  padding-top: var(--sgf-space-6);
  border-top: 1px solid var(--sgf-color-border);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  letter-spacing: var(--sgf-tracking-wide);
}

.sgf-post-nav {
  margin-top: var(--sgf-space-20);
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sgf-space-4);
  border-top: 1px solid var(--sgf-color-border);
  padding-top: var(--sgf-space-8);
}
.sgf-post-nav .nav-previous, .sgf-post-nav .nav-next {
  display: flex;
  flex-direction: column;
  gap: var(--sgf-space-2);
}
.sgf-post-nav .nav-previous a, .sgf-post-nav .nav-next a {
  text-decoration: none;
}
.sgf-post-nav .nav-next {
  text-align: right;
}

.sgf-post-nav__label {
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  letter-spacing: var(--sgf-tracking-wide);
  text-transform: uppercase;
}

.sgf-post-nav__title {
  color: var(--sgf-color-text);
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-lg);
}

.sgf-page-header {
  margin-bottom: var(--sgf-space-12);
  padding-bottom: var(--sgf-space-8);
  border-bottom: 1px solid var(--sgf-color-border);
}

.sgf-page-title {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-3xl);
  font-weight: 400;
  letter-spacing: var(--sgf-tracking-tight);
}

.sgf-no-results {
  padding: var(--sgf-space-24) 0;
  text-align: center;
}

.sgf-no-results__title {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-3xl);
  font-weight: 400;
  margin-bottom: var(--sgf-space-4);
}

body.error404 .sgf-site-content {
  display: flex;
  flex-direction: column;
  min-height: calc(100svh - var(--sgf-nav-height));
}

.sgf-404 {
  flex: 1 1 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sgf-space-12) var(--sgf-space-4);
}

.sgf-404__inner {
  width: min(440px, 100%);
  text-align: center;
}

.sgf-404__title {
  margin: 0;
  font-family: var(--sgf-font-body);
  font-size: 28px;
  font-weight: 500;
  line-height: 36px;
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--sgf-color-text);
}
@media (max-width: 767px) {
  .sgf-404__title {
    font-size: 24px;
    line-height: 32px;
  }
}

.sgf-404__text {
  margin: var(--sgf-space-3) 0 0;
  font-family: var(--sgf-font-body);
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: var(--sgf-color-muted);
}

.sgf-404__go {
  margin-top: var(--sgf-space-7);
  min-width: 180px;
}

.sgf-search-result {
  padding: var(--sgf-space-6) 0;
  border-bottom: 1px solid var(--sgf-color-border);
}

.sgf-search-result__meta {
  display: flex;
  gap: var(--sgf-space-4);
  font-family: var(--sgf-font-mono);
  font-size: var(--sgf-text-xs);
  color: var(--sgf-color-muted);
  margin-bottom: var(--sgf-space-2);
  letter-spacing: var(--sgf-tracking-wide);
}

.sgf-search-result__type {
  text-transform: uppercase;
}

.sgf-search-result__title {
  font-family: var(--sgf-font-display);
  font-size: var(--sgf-text-xl);
  font-weight: 400;
  margin: 0 0 var(--sgf-space-2);
}
.sgf-search-result__title a {
  color: var(--sgf-color-text);
  text-decoration: none;
}
.sgf-search-result__title a:hover {
  color: var(--sgf-color-accent);
}

.sgf-search-result__excerpt {
  color: var(--sgf-color-muted);
  font-size: var(--sgf-text-sm);
  margin: 0;
}

/* Comments
--------------------------------------------- */
/* Widgets
--------------------------------------------- */
/* Media
--------------------------------------------- */
/* Captions
--------------------------------------------- */
/* Galleries
--------------------------------------------- */
/*--------------------------------------------------------------
# Plugins
--------------------------------------------------------------*/
/* Jetpack infinite scroll
--------------------------------------------- */
/* Hide the Posts Navigation and the Footer when Infinite Scroll is in use. */
.infinite-scroll .posts-navigation,
.infinite-scroll.neverending .site-footer {
  display: none;
}

/* Re-display the Theme Footer when Infinite Scroll has reached its end. */
.infinity-end.neverending .site-footer {
  display: block;
}

/*--------------------------------------------------------------
# Utilities
--------------------------------------------------------------*/
/* Accessibility
--------------------------------------------- */
.screen-reader-text,
.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;
}

.screen-reader-text:focus,
.sr-only:focus {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  white-space: normal;
}

:focus-visible {
  outline: 2px solid var(--sgf-color-accent);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
/* Alignments
--------------------------------------------- */
.alignleft {
  /*rtl:ignore*/
  float: left;
  /*rtl:ignore*/
  margin-right: 1.5em;
  margin-bottom: 1.5em;
}

.alignright {
  /*rtl:ignore*/
  float: right;
  /*rtl:ignore*/
  margin-left: 1.5em;
  margin-bottom: 1.5em;
}

.aligncenter {
  clear: both;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: 1.5em;
}

/* Animations
--------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity var(--sgf-duration-slow) var(--sgf-ease-out), transform var(--sgf-duration-slow) var(--sgf-ease-out);
  will-change: transform, opacity;
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

[data-reveal=clip] {
  clip-path: inset(0 0 100% 0);
  transform: none;
  transition: clip-path var(--sgf-duration-slow) var(--sgf-ease-out), opacity var(--sgf-duration-slow) var(--sgf-ease-out);
}

[data-reveal=clip].is-visible {
  clip-path: inset(0 0 0% 0);
  opacity: 1;
  transform: none;
}

[data-reveal=fade] {
  transform: none;
}

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    transition: none;
    opacity: 1;
    transform: none;
    clip-path: none;
  }
}
:root {
  --stagger-dur: var(--sgf-duration-slow);
  --stagger-distance: 12px;
  --stagger-stagger: 50ms;
  --stagger-blur: 3px;
  --stagger-ease: var(--sgf-ease-out);
}

.t-stagger-line {
  display: block;
  opacity: 0;
  transform: translateY(var(--stagger-distance));
  filter: blur(var(--stagger-blur));
  transition: opacity var(--stagger-dur) var(--stagger-ease), transform var(--stagger-dur) var(--stagger-ease), filter var(--stagger-dur) var(--stagger-ease);
  will-change: transform, opacity, filter;
}

.t-stagger-line--2 {
  transition-delay: var(--stagger-stagger);
}

.t-stagger-line--3 {
  transition-delay: calc(var(--stagger-stagger) * 2);
}

.t-stagger-line--4 {
  transition-delay: calc(var(--stagger-stagger) * 3);
}

.t-stagger.is-shown .t-stagger-line {
  opacity: 1;
  transform: translateY(0);
  filter: blur(0);
}

.t-stagger.is-hiding .t-stagger-line {
  opacity: 0;
  transform: none;
  filter: blur(0);
  transition: opacity var(--sgf-duration-ui) var(--sgf-ease);
  transition-delay: 0s;
}

@media (prefers-reduced-motion: reduce) {
  .t-stagger-line {
    transition: none !important;
  }
}
:root {
  --tilt-perspective: 1000px;
  --tilt-return: var(--sgf-duration-slower);
  --tilt-return-ease: var(--sgf-ease-out);
  --tilt-follow: var(--sgf-duration-drawer);
  --tilt-follow-ease: var(--sgf-ease-out);
  --tilt-glare-opacity: 0.22;
  --tilt-glare-fade: var(--sgf-duration-drawer);
}

.t-tilt {
  touch-action: none;
}

.t-tilt-card {
  position: relative;
  overflow: hidden;
  transform: perspective(var(--tilt-perspective)) rotateX(var(--tilt-rx, 0deg)) rotateY(var(--tilt-ry, 0deg));
  transform-style: preserve-3d;
  transition: transform var(--tilt-return) var(--tilt-return-ease);
  will-change: transform;
}

.t-tilt-card.is-tilting {
  transition: transform var(--tilt-follow) var(--tilt-follow-ease);
}

.t-tilt-glare {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  mix-blend-mode: screen;
  background: radial-gradient(circle 95px at var(--tilt-gx, 50%) var(--tilt-gy, 50%), rgba(255, 255, 255, 0.4), rgba(255, 255, 255, 0.04) 52%, transparent 84%), radial-gradient(circle 250px at var(--tilt-gx, 50%) var(--tilt-gy, 50%), rgba(255, 255, 255, 0.14), transparent 78%);
  transition: opacity var(--tilt-glare-fade) var(--tilt-return-ease);
}

.t-tilt.is-hover .t-tilt-glare {
  opacity: var(--tilt-glare-opacity);
}

@media (prefers-reduced-motion: reduce) {
  .t-tilt-card {
    transform: none !important;
    transition: none !important;
  }
}
[data-chars] span {
  display: inline-block;
  transition: transform var(--sgf-duration-fast) var(--sgf-ease-out), opacity var(--sgf-duration-fast) var(--sgf-ease-out);
}

@media (hover: hover) and (pointer: fine) {
  [data-chars]:hover span {
    transform: translateY(-2px);
    opacity: 0.7;
  }
}
/* Spacing
--------------------------------------------- */
/* =============================================
   SPACING UTILITIES
   mt-* / mb-* / my-* / mx-* / pt-* / pb-* / py-*
   px-* / p-* / m-*
   Numbers map to --sgf-space-N tokens.
   ============================================= */
/* Margin top */
.mt-0 {
  margin-top: 0;
}

.mt-1 {
  margin-top: var(--sgf-space-1);
}

.mt-2 {
  margin-top: var(--sgf-space-2);
}

.mt-3 {
  margin-top: var(--sgf-space-3);
}

.mt-4 {
  margin-top: var(--sgf-space-4);
}

.mt-5 {
  margin-top: var(--sgf-space-5);
}

.mt-6 {
  margin-top: var(--sgf-space-6);
}

.mt-8 {
  margin-top: var(--sgf-space-8);
}

.mt-10 {
  margin-top: var(--sgf-space-10);
}

.mt-12 {
  margin-top: var(--sgf-space-12);
}

.mt-16 {
  margin-top: var(--sgf-space-16);
}

/* Margin bottom */
.mb-0 {
  margin-bottom: 0;
}

.mb-1 {
  margin-bottom: var(--sgf-space-1);
}

.mb-2 {
  margin-bottom: var(--sgf-space-2);
}

.mb-3 {
  margin-bottom: var(--sgf-space-3);
}

.mb-4 {
  margin-bottom: var(--sgf-space-4);
}

.mb-5 {
  margin-bottom: var(--sgf-space-5);
}

.mb-6 {
  margin-bottom: var(--sgf-space-6);
}

.mb-8 {
  margin-bottom: var(--sgf-space-8);
}

.mb-10 {
  margin-bottom: var(--sgf-space-10);
}

.mb-12 {
  margin-bottom: var(--sgf-space-12);
}

.mb-16 {
  margin-bottom: var(--sgf-space-16);
}

/* Margin Y (block) */
.my-0 {
  margin-block: 0;
}

.my-4 {
  margin-block: var(--sgf-space-4);
}

.my-6 {
  margin-block: var(--sgf-space-6);
}

.my-8 {
  margin-block: var(--sgf-space-8);
}

.my-10 {
  margin-block: var(--sgf-space-10);
}

.my-12 {
  margin-block: var(--sgf-space-12);
}

.my-16 {
  margin-block: var(--sgf-space-16);
}

/* Margin X (inline) */
.mx-auto {
  margin-inline: auto;
}

.mx-0 {
  margin-inline: 0;
}

.mx-4 {
  margin-inline: var(--sgf-space-4);
}

.mx-6 {
  margin-inline: var(--sgf-space-6);
}

/* Padding top */
.pt-0 {
  padding-top: 0;
}

.pt-4 {
  padding-top: var(--sgf-space-4);
}

.pt-6 {
  padding-top: var(--sgf-space-6);
}

.pt-8 {
  padding-top: var(--sgf-space-8);
}

.pt-10 {
  padding-top: var(--sgf-space-10);
}

.pt-12 {
  padding-top: var(--sgf-space-12);
}

.pt-16 {
  padding-top: var(--sgf-space-16);
}

/* Padding bottom */
.pb-0 {
  padding-bottom: 0;
}

.pb-4 {
  padding-bottom: var(--sgf-space-4);
}

.pb-6 {
  padding-bottom: var(--sgf-space-6);
}

.pb-8 {
  padding-bottom: var(--sgf-space-8);
}

.pb-10 {
  padding-bottom: var(--sgf-space-10);
}

.pb-12 {
  padding-bottom: var(--sgf-space-12);
}

.pb-16 {
  padding-bottom: var(--sgf-space-16);
}

/* Padding Y */
.py-0 {
  padding-block: 0;
}

.py-4 {
  padding-block: var(--sgf-space-4);
}

.py-6 {
  padding-block: var(--sgf-space-6);
}

.py-8 {
  padding-block: var(--sgf-space-8);
}

.py-10 {
  padding-block: var(--sgf-space-10);
}

.py-12 {
  padding-block: var(--sgf-space-12);
}

.py-16 {
  padding-block: var(--sgf-space-16);
}

/* Padding X */
.px-0 {
  padding-inline: 0;
}

.px-4 {
  padding-inline: var(--sgf-space-4);
}

.px-5 {
  padding-inline: var(--sgf-space-5);
}

.px-6 {
  padding-inline: var(--sgf-space-6);
}

.px-8 {
  padding-inline: var(--sgf-space-8);
}

/* Section spacing — large vertical blocks */
.sgf-section {
  padding-block: var(--sgf-space-16);
}

.sgf-section--sm {
  padding-block: var(--sgf-space-10);
}

.sgf-section--lg {
  padding-block: clamp(80px, 10vw, 160px);
}

.sgf-section--flush {
  padding-block: 0;
}

/* Display
--------------------------------------------- */
/* =============================================
   DISPLAY UTILITIES
   ============================================= */
.d-none {
  display: none !important;
}

.d-block {
  display: block !important;
}

.d-flex {
  display: flex !important;
}

.d-grid {
  display: grid !important;
}

.d-inline {
  display: inline !important;
}

.d-inline-block {
  display: inline-block !important;
}

.d-inline-flex {
  display: inline-flex !important;
}

/* Responsive display */
@media (max-width: 767px) {
  .d-none--mobile {
    display: none !important;
  }
  .d-block--mobile {
    display: block !important;
  }
}
@media (min-width: 768px) {
  .d-none--desktop {
    display: none !important;
  }
  .d-block--desktop {
    display: block !important;
  }
}
/* =============================================
   TEXT UTILITIES
   ============================================= */
.text-left {
  text-align: left;
}

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

.text-right {
  text-align: right;
}

.text-muted {
  color: var(--sgf-color-muted);
}

.text-accent {
  color: var(--sgf-color-accent);
}

.text-mono {
  font-family: var(--sgf-font-mono);
}

.text-display {
  font-family: var(--sgf-font-display);
}

.text-xs {
  font-size: var(--sgf-text-xs);
}

.text-sm {
  font-size: var(--sgf-text-sm);
}

.text-base {
  font-size: var(--sgf-text-base);
}

.text-lg {
  font-size: var(--sgf-text-lg);
}

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

.text-uppercase {
  text-transform: uppercase;
  letter-spacing: var(--sgf-tracking-wide);
}

.text-nowrap {
  white-space: nowrap;
}

.text-balance {
  text-wrap: balance;
}

.text-truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* =============================================
   OVERFLOW
   ============================================= */
.overflow-hidden {
  overflow: hidden;
}

.overflow-x-auto {
  overflow-x: auto;
}

/* =============================================
   POSITION & VISUAL
   ============================================= */
.relative {
  position: relative;
}

.sticky {
  position: sticky;
  top: 0;
}

.w-full {
  width: 100%;
}

.h-full {
  height: 100%;
}

.rounded-sm {
  border-radius: var(--sgf-radius-sm);
}

.rounded-md {
  border-radius: var(--sgf-radius-md);
}

.rounded-lg {
  border-radius: var(--sgf-radius-lg);
}

.border {
  border: 1px solid var(--sgf-color-border);
}

.border-top {
  border-top: 1px solid var(--sgf-color-border);
}

.border-bottom {
  border-bottom: 1px solid var(--sgf-color-border);
}

.bg-surface {
  background: var(--sgf-color-surface);
}

.bg-accent {
  background: var(--sgf-color-accent);
  color: var(--sgf-color-bg);
}

/*# sourceMappingURL=style.css.map */
