/* ══════════════════════════════════════════════════════════════════════
   LAS TARJETAS DE AGROCALIA — los tres formatos
   ══════════════════════════════════════════════════════════════════════

   `ag-card` la completa · `ag-mini` la compacta · `ag-subasta` la fila.

   Comparten foto, etiqueta, corazón, nombre, vendedor, nota y precio: lo común
   se declara una vez y cada formato solo cambia sus medidas.

   ── LOS COLORES SON LOS DEL ESCAPARATE ───────────────────────────────
   Tokens `--sd-*` con respaldo en el punto de uso, porque los sirve
   `TSellersUI` y estas tarjetas se pintan también dentro del panel de cuenta,
   que no lo carga.

   ── NO SE ESCOPAN BAJO UNA PANTALLA ──────────────────────────────────
   A propósito: son globales y se usan en el catálogo, en favoritos, en las
   colecciones y en el perfil del agricultor. El prefijo `ag-` es lo que las
   acota, y por eso todas las clases lo llevan.
   ────────────────────────────────────────────────────────────────────── */

.ag-cards { display: none; }

/* ── LO QUE LA REJILLA NECESITA SABER DE LA TARJETA ──────────────────
   Las rejillas del escaparate y de favoritos se montan con estos tokens, y los
   declaraba `TProductCard`. Al retirarlo a `old/` (10/09/2026) dejaron de
   llegar y las rejillas caían a sus respaldos: funcionaba, pero el ancho de la
   tarjeta lo decidía la pantalla en vez de la tarjeta.

   Van en `:root` a propósito: un token declarado sobre `.ag-card` no lo ve su
   contenedor, que es justo quien lo usa. */
:root{
    /* EL MÍNIMO. Por debajo de 260 la foto se queda pequeña y el nombre se
       parte en tres líneas. */
    --tf-card-min: 260px;

    /* Y EL TOPE, porque «líquida» no es «sin límite»: una fila con una sola
       tarjeta le daba el ancho entero de la página, y eso no es una tarjeta de
       producto, es un banner. */
    --tf-card-max: 350px;

    --tf-card-gap: 20px;
}

.ag-card, .ag-mini, .ag-subasta,
.ag-card *, .ag-mini *, .ag-subasta * { box-sizing: border-box; }

/* ── LO COMÚN ───────────────────────────────────────────────────────── */

.ag-card, .ag-mini, .ag-subasta {
    position: relative;
    background: #fff;
    border: 1px solid var(--sd-borde, #e4eae4);
    border-radius: 14px;
    overflow: hidden;
}
.ag-card:hover, .ag-mini:hover, .ag-subasta:hover {
    border-color: #cfe0d3;
    box-shadow: 0 4px 14px rgba(20,40,25,.09);
}

/* La tapa cubre la tarjeta para poder pulsar en cualquier sitio. Va DEBAJO del
   corazón y del botón en el apilado: si no, se traga sus clics. */
.ag-card .ag-tapa, .ag-mini .ag-tapa, .ag-subasta .ag-tapa {
    position: absolute; inset: 0; z-index: 1;
    border: 0; text-decoration: none;
}

.ag-card .ag-foto, .ag-mini .ag-foto, .ag-subasta .ag-foto {
    position: relative; display: block;
    overflow: hidden;
    background: var(--sd-gris, #f2f5f2);
}
.ag-card .ag-foto img, .ag-mini .ag-foto img, .ag-subasta .ag-foto img {
    width: 100%; height: 100%; display: block;

    /* CUBRE EL HUECO, Y ANCLADA ARRIBA. `cover` recorta lo que sobra en vez de
       deformar la foto; `object-position: top` decide POR DÓNDE recorta, y en
       una foto de producto lo que importa está arriba --el género-- mientras que
       abajo suele haber caja, suelo o mesa. Con el centrado de fábrica, una foto
       vertical entraba por la mitad y la tarjeta enseñaba el palé. */
    object-fit: cover;
    object-position: top;
}

/* SIN FOTO, EL HUECO CON SU ICONO: un rectángulo vacío se lee como una imagen
   que no ha cargado, y la gente recarga la página. */
.ag-card .ag-sinfoto, .ag-mini .ag-sinfoto, .ag-subasta .ag-sinfoto {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    color: #c3cfc6;
}
.ag-card .ag-sinfoto iconify-icon,
.ag-mini .ag-sinfoto iconify-icon,
.ag-subasta .ag-sinfoto iconify-icon { font-size: 30px; }

/* Oculto mientras la foto carga bien -- TAgroCard.js lo vuelve a enseñar
   solo si el `<img>` falla (`onerror`). Con `display:none` en vez de
   quitarlo del DOM, sigue ahí para ese caso; `.remove()` no se puede
   deshacer.

   ── Y CON LA TARJETA DELANTE, QUE SI NO NO OCULTA NADA (26/09/2026) ──
   Estaba como `.ag-sinfoto--oculto` a secas --0,0,1,0-- contra la regla que lo
   enseña, `.ag-card .ag-sinfoto` --0,0,2,0--: perdía por especificidad, así que
   el icono de «sin foto» salía SIEMPRE, también encima de las fotos que sí
   habían cargado. Se veía como un cuadradito gris en mitad de cada producto y
   no daba ningún error: el JS y el render de PHP llevaban meses poniendo una
   clase que no hacía nada. */
.ag-card .ag-sinfoto--oculto,
.ag-mini .ag-sinfoto--oculto,
.ag-subasta .ag-sinfoto--oculto { display: none; }

/* ── LA ETIQUETA DE LA ESQUINA ──────────────────────────────────────── */

.ag-card .ag-etiqueta, .ag-mini .ag-etiqueta {
    position: absolute; top: 10px; left: 10px; z-index: 2;
    display: inline-block;
    padding: 5px 12px;
    border-radius: 999px;
    font-size: 12px; font-weight: 700; line-height: 1.3;
    color: #fff;
    background: var(--sd-verde, #1d753b);
    box-shadow: 0 1px 4px rgba(20,40,25,.2);
}
.ag-mini .ag-etiqueta { top: 8px; left: 8px; padding: 3px 9px; font-size: 11px; }

/* Los cuatro tonos, que son los de la paleta semántica del proyecto. */
.ag-card .ag-et--verde, .ag-mini .ag-et--verde { background: #1d753b; }
.ag-card .ag-et--ambar, .ag-mini .ag-et--ambar { background: #e8a33d; }
.ag-card .ag-et--azul,  .ag-mini .ag-et--azul  { background: #2f6fd0; }
.ag-card .ag-et--rojo,  .ag-mini .ag-et--rojo  { background: #ef5350; }

/* ── EL CORAZÓN ─────────────────────────────────────────────────────── */

.ag-card .ag-fav, .ag-mini .ag-fav {
    height: auto; min-height: 0;
    position: absolute; top: 9px; right: 9px; z-index: 3;
    display: inline-flex; align-items: center; justify-content: center;
    width: 34px; height: 34px;
    margin: 0; padding: 0;
    background: rgba(255,255,255,.95);
    border: 0; border-radius: 999px;
    color: #9aa8a0;
    cursor: pointer;
    box-shadow: 0 1px 5px rgba(20,40,25,.18);
}
.ag-mini .ag-fav { top: 7px; right: 7px; width: 28px; height: 28px; }

/* El corazón es un SVG inline --no un `<iconify-icon>`-- justo para poder
   rellenarlo: dentro de un shadow DOM el `fill="none"` de Lucide no se alcanza
   desde aquí. */
.ag-card .ag-corazon, .ag-mini .ag-corazon { width: 18px; height: 18px; fill: none; }
.ag-mini .ag-corazon { width: 15px; height: 15px; }

.ag-card .ag-fav:hover, .ag-mini .ag-fav:hover { color: #e11d48; }

/* GUARDADO: rojo y RELLENO. Con solo el contorno no se distingue de «se puede
   guardar», que es justo lo contrario de lo que dice. */
.ag-card .ag-fav.on, .ag-mini .ag-fav.on { color: #e11d48; }
.ag-card .ag-fav.on .ag-corazon, .ag-mini .ag-fav.on .ag-corazon { fill: #e11d48; }

/* ── EL CUERPO ──────────────────────────────────────────────────────── */

/* EL CUERPO CRECE PARA QUE EL BOTÓN SE QUEDE ABAJO.
   Sin esto, el botón sube o baja según lo que haya encima --un nombre de una
   línea o de dos, un producto con lugar y otro sin él-- y en una rejilla eso se
   ve como una fila de botones a distintas alturas. Con el cuerpo en columna y
   el botón con `margin-top:auto`, su sitio no depende del contenido: siempre al
   pie de la tarjeta. */
.ag-card .ag-cuerpo, .ag-mini .ag-cuerpo {
    position: relative; z-index: 2;
    pointer-events: none;
    flex: 1;
    display: flex; flex-direction: column;
}
/* El cuerpo deja pasar el clic a la tapa, salvo lo que sí se pulsa. */
.ag-card .ag-cuerpo .ag-btn, .ag-mini .ag-cuerpo .ag-btn { pointer-events: auto; }

.ag-card .ag-cuerpo { padding: 13px 14px 14px; }
.ag-mini .ag-cuerpo { padding: 8px 10px 9px; min-height: 0; }

.ag-card .ag-nombre, .ag-mini .ag-nombre, .ag-subasta .ag-nombre {
    margin: 0; padding: 0;
    font-weight: 800; line-height: 1.3;
    color: var(--sd-tinta, #16211a);
}
.ag-card .ag-nombre { font-size: 15px; }
/* HASTA DOS LÍNEAS, y sin encogerse. Antes era una sola línea con puntos
   suspensivos porque la tarjeta medía 150px fijos; pero el cuerpo no cabía en
   esos 150 --foto de 71, relleno y cuatro líneas-- y el flex, al ser el nombre
   `overflow:hidden`, lo comprimía por debajo de su altura: el título salía
   cortado por abajo y montado sobre el vendedor. Con `flex:0 0 auto` cada línea
   conserva su altura y es la tarjeta la que crece (ver `.ag-mini`). */
.ag-mini .ag-nombre {
    flex: 0 0 auto;
    font-size: 12.5px;
    overflow: hidden;
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    line-clamp: 2;
}
.ag-subasta .ag-nombre { font-size: 13.5px; }

.ag-card .ag-vendedor, .ag-mini .ag-vendedor, .ag-subasta .ag-vendedor {
    margin: 3px 0 0; padding: 0;
    line-height: 1.35;
    color: var(--sd-suave, #6b7a70);
}
.ag-card .ag-vendedor { font-size: 13px; }
.ag-mini .ag-vendedor {
    flex: 0 0 auto;
    font-size: 11px; margin-top: 1px;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ag-subasta .ag-vendedor { font-size: 12px; }

/* ── EL LUGAR ───────────────────────────────────────────────────────── */

.ag-card .ag-lugar {
    display: flex; align-items: center; gap: 5px;
    margin: 5px 0 0; padding: 0;
    font-size: 12.5px; line-height: 1.35;
    color: var(--sd-suave, #6b7a70);
}
/* El tamaño se declara EN el icono: `iconify-icon` no hereda el `font-size`. */
.ag-card .ag-lugar iconify-icon { flex: 0 0 auto; font-size: 14px; }

/* ── LA NOTA ────────────────────────────────────────────────────────── */

.ag-card .ag-nota, .ag-mini .ag-nota {
    display: flex; align-items: center; gap: 5px;
    margin: 6px 0 0; padding: 0;
}
.ag-mini .ag-nota { margin-top: 3px; }

/* La estrella va RELLENA. Es el trazo de Lucide copiado de su propia
   definición --su `<path>` trae `fill="none"` y con `iconify-icon` vive en un
   shadow DOM que ninguna regla alcanza-- así que no se mezcla ninguna familia
   de iconos: solo se pinta el interior. */
.ag-card .ag-estrella, .ag-mini .ag-estrella {
    width: 16px; height: 16px; flex: 0 0 auto;
    fill: #feac08; color: #feac08;
}
.ag-mini .ag-estrella { width: 14px; height: 14px; }

.ag-card .ag-nota b { font-size: 13.5px; font-weight: 700; color: var(--sd-tinta, #16211a); }
.ag-mini .ag-nota b { font-size: 12px; font-weight: 700; color: var(--sd-tinta, #16211a); }
.ag-card .ag-nota small { font-size: 13px; color: var(--sd-suave, #6b7a70); }
.ag-mini .ag-nota small { font-size: 11.5px; color: var(--sd-suave, #6b7a70); }

/* ── EL PRECIO, Y EL DESCUENTO A SU DERECHA ─────────────────────────── */

.ag-card .ag-precios, .ag-mini .ag-precios {
    display: flex; align-items: baseline; flex-wrap: wrap; gap: 8px;
    margin: 9px 0 0; padding: 0;
}
.ag-mini .ag-precios { margin: 0; gap: 5px; }

.ag-card .ag-precio {
    font-size: 18px;
    font-weight: 600;
    color: var(--sd-tinta, #16211a);
    font-family: sans-serif;
}
.ag-mini .ag-precio { font-size: 14.5px; font-weight: 800; color: var(--sd-tinta, #16211a); }

/* EN OFERTA EL PRECIO VA EN ROJO: es lo que lo distingue de un precio normal de
   un vistazo. El tachado de al lado se lee después, no antes. */
.ag-card .ag-precio.ag-rebajado, .ag-mini .ag-precio.ag-rebajado { color: #e11d48; }

.ag-card .ag-antes, .ag-mini .ag-antes {
    font-size: 14px; font-weight: 600;
    color: var(--sd-suave, #93a09a);
    text-decoration: line-through;
}
.ag-mini .ag-antes { font-size: 11.5px; }

/* LA MENCIÓN DEL IVA: discreta pero legible (suelo de 10 px) y con contraste
   AA sobre el blanco de la tarjeta. El `span` no hereda el tamaño en este
   sitio --una regla global con `font:` lo fija--, así que se declara. */
.ag-card .ag-iva, .ag-mini .ag-iva, .ag-subasta .ag-iva {
    font-size: 11px; font-weight: 500; line-height: 1.2;
    color: var(--sd-suave-aa, #5f6b65);
}
.ag-mini .ag-iva { font-size: 10px; flex-basis: 100%; }
.ag-subasta .ag-iva { display: block; font-size: 10px; }

/* EL PRECIO POR KILO O LITRO: su propia línea bajo el precio, sobrio. Mismo tono
   que la mención del IVA, que es dato de lectura y no cifra de decisión. */
.ag-card .ag-ud, .ag-mini .ag-ud, .ag-subasta .ag-ud {
    flex-basis: 100%;
    font-size: 11px; font-weight: 500; line-height: 1.2;
    color: var(--sd-suave-aa, #5f6b65);
    font-variant-numeric: tabular-nums;
}
.ag-card .ag-ud { margin-top: -4px; }
.ag-mini .ag-ud { font-size: 10px; }
.ag-subasta .ag-ud { display: block; font-size: 10px; }

.ag-card .ag-dto {
    padding: 2px 8px;
    background: #ef5350; border-radius: 7px;
    font-size: 12px; font-weight: 700; color: #fff;
}

/* ── EL BOTÓN ───────────────────────────────────────────────────────── */

/* `height:auto` a la fuerza: la hoja global le pone `height:25px; display:flex`
   a todo `button` dentro de un TComponentES6, y estas tarjetas se pintan
   también dentro del panel de cuenta. */
.ag-card .ag-btn, .ag-mini .ag-btn, .ag-subasta .ag-btn {
    height: auto; min-height: 0;
    display: inline-flex; align-items: center; justify-content: center; gap: 8px;
    margin: 0;
    background: var(--sd-verde, #116f34);
    border: 0; border-radius: 10px;
    font-size: 13.5px; font-weight: 700; line-height: 1.2;
    color: #fff;
    cursor: pointer; box-shadow: none;
    pointer-events: auto;
}
.ag-card .ag-btn:hover, .ag-mini .ag-btn:hover, .ag-subasta .ag-btn:hover {
    background: var(--sd-verde-oscuro, #0b5a2a);
}
.ag-card .ag-btn iconify-icon, .ag-mini .ag-btn iconify-icon, .ag-subasta .ag-btn iconify-icon { font-size: 16px; }

/* El rótulo del botón, en su `<span>`: así se puede quitar en la vista de lista
   sin tocar el icono. */
.ag-card .ag-btn-txt { display: inline; }

/* EL PIE. `margin-top: auto` lo empuja al fondo, que es lo que hace que todas
   las tarjetas de una fila tengan el botón a la misma altura. */
.ag-card .ag-pie { margin-top: auto; display: flex; align-items: center; gap: 10px; }

/* A todo lo ancho en la completa: es la acción de la tarjeta. */
.ag-card .ag-pie .ag-btn { flex: 1; width: 100%; padding: 11px 14px; }

/* «VER PRODUCTO» NACE OCULTO: en la rejilla sobra --la tarjeta entera ya es
   pulsable-- y lo enseña la vista de lista, que es donde hay sitio. */
.ag-card .ag-ver {
    display: none;
    align-items: center; justify-content: center;
    padding: 9px 14px;
    /* EL BORDE, MÁS MARCADO QUE `--sd-borde`. Ese gris está pensado para
       separar superficies --el canto de una tarjeta sobre el fondo-- y sobre
       blanco casi no se ve; en un botón el borde ES el botón, porque no tiene
       fondo que lo dibuje. */
    border: 1px solid var(--ag-borde-btn, #a9bdaf); border-radius: 10px;
    font-size: 13px; font-weight: 600; line-height: 1.2;
    color: var(--sd-verde, #116f34); text-decoration: none;
    white-space: nowrap;
    pointer-events: auto; position: relative; z-index: 3;
}
.ag-card .ag-ver:hover { background: var(--sd-gris, #f2f5f2); }
.ag-card .ag-ver:hover { border-color: var(--sd-verde, #116f34); }

/* ── EL BORDE SE PONÍA NEGRO AL VISITARLO, Y NO SE VE MIDIENDO ──────
 *
 * La hoja global declara `a, a:active, a:focus, a:visited { … border: 0px; }`.
 * Ese shorthand deja `border-color` en `currentColor`, y el color del borde es
 * de las pocas propiedades que `:visited` SÍ puede cambiar --el navegador
 * bloquea el resto por privacidad--. Como `a:visited` (0,1,1) gana a una clase
 * suelta (0,1,0), este botón salía con el borde casi negro en cuanto se había
 * pinchado el producto una vez, mientras los no visitados seguían grises: dos
 * bordes distintos en la misma fila.
 *
 * **`getComputedStyle` no lo delata**: devuelve a propósito el valor del enlace
 * SIN visitar. Hay que declarar el `:visited` explícito.
 * Ver `Documentacion/Memoria/borde-negro-por-a-visited.md`. */
.ag-card .ag-ver:link,
.ag-card .ag-ver:visited,
.ag-card .ag-ver:hover,
.ag-card .ag-ver:active,
.ag-card .ag-ver:focus {
    border: 1px solid var(--ag-borde-btn, #a9bdaf);
    color: var(--sd-verde, #116f34);
}
/* El hueco mínimo sobre el botón lo pone el bloque de precios, no el botón: si
   lo pusiera él, `margin-top:auto` lo perdería. */
.ag-card .ag-precios { margin-bottom: 12px; }

/* En la compacta se queda en su icono: a todo lo ancho se comería la tarjeta. */
.ag-mini .ag-btn-icono { width: 30px; height: 30px; flex: 0 0 30px; padding: 0; border-radius: 8px; }

.ag-subasta .ag-btn { padding: 8px 14px; font-size: 12.5px; }

/* ── FORMATO 1: LA COMPLETA ─────────────────────────────────────────── */

/* `height:100%` para que la tarjeta ocupe toda la celda de la rejilla: es lo
   que permite que el botón se vaya al fondo. Una rejilla estira sus celdas,
   pero la tarjeta tiene que aceptar el alto. */
.ag-card { display: flex; flex-direction: column; height: 100%; }

/* EL THUMB: TODO EL ANCHO DE LA TARJETA, 138 de alto.
   ── EL `max-width: 210px` ESTABA MAL Y SE VEÍA ────────────────────
   La maqueta mide 210 x 138 porque SU tarjeta mide 210 de ancho. Copiar los dos
   números dejó la foto centrada dentro de una tarjeta de 298: un rectángulo
   despegado de los bordes, con dos franjas blancas a los lados que se leen como
   un fallo de montaje. Lo que la maqueta dice de verdad es que la foto ocupa el
   ancho ENTERO y mide 138 de alto.
   El alto sí se fija --no `aspect-ratio`-- para que las tarjetas de una fila
   tengan el texto a la misma altura, y `object-fit: cover` en el `img` recorta
   lo que sobre en vez de deformar la foto. */
.ag-card .ag-foto { display: block; width: 100%; height: 138px; margin: 0; border-radius: 0; }

/* ── FORMATO 2: LA COMPACTA ─────────────────────────────────────────── */

/* LA COMPACTA MIDE 178 de ancho y AL MENOS 150 de alto, con el thumb de 71: es
   una tarjeta de panel lateral, donde caben dos por fila. Dos tarjetas
   seguidas quedan iguales porque la fila las estira, no porque el alto sea fijo
   --fijo, el cuerpo no cabía y se solapaban título y vendedor--. */
.ag-mini {
    display: flex; flex-direction: column;
    /* Alto mínimo y no fijo: el cuerpo (nombre en dos líneas, vendedor, precio
       y «IVA incluido») no cabe en 79px, y con `height` fija se comprimía. */
    width: 178px; min-height: 150px;
    max-width: 100%;
}
.ag-mini .ag-foto { height: 71px; flex: 0 0 71px; }

.ag-mini .ag-mini-pie {
    display: flex; align-items: center; justify-content: space-between; gap: 8px;
    /* Al pie, por lo mismo que en la completa. */
    margin-top: auto; padding-top: 6px;
}
.ag-mini .ag-mini-pie .ag-precios { margin: 0; }

/* ── FORMATO 3: LA FILA DE SUBASTA ──────────────────────────────────── */

/* LA FILA DE SUBASTA: 75 de alto y el thumb CUADRADO de 57 x 57. Las dos
   medidas salen de la maqueta (el PNG va a escala 1:1) y el alto es
   exactamente el thumb más sus 9 de aire arriba y abajo. */
.ag-subasta {
    display: grid;
    grid-template-columns: 57px minmax(0, 1fr) auto;
    gap: 12px; align-items: center;
    height: 75px; padding: 9px;
}
.ag-subasta .ag-foto { width: 57px; height: 57px; flex: 0 0 57px; border-radius: 10px; }

.ag-subasta .ag-subasta-txt { position: relative; z-index: 2; min-width: 0; pointer-events: none; }

.ag-subasta .ag-queda {
    display: inline-flex; align-items: center; gap: 5px;
    margin-top: 6px; padding: 3px 9px;
    background: #fdecec; border-radius: 999px;
    font-size: 11.5px; font-weight: 700; color: #d92d20;
}
.ag-subasta .ag-queda iconify-icon { font-size: 13px; }

/* LA PÍLDORA VA EN ROJO SIEMPRE, falten dos horas o falten tres días. Aquí
   había un `.ag-holgado` que la pasaba a gris con más de un día por delante --
   idea mía, no de la maqueta, y lo que conseguía era que la misma fila se viera
   de dos maneras distintas sin que nada lo explicara. La maqueta pinta una sola
   píldora, y en una subasta el tiempo SIEMPRE es el dato que decide. */

/* ── LA FILA COMO ARTÍCULO NORMAL ───────────────────────────────────
   El mismo formato sirve para lo que no es subasta: cambian los textos, no la
   colocación. En vez de la cuenta atrás va el lugar, que es lo que la tarjeta
   completa pone en esa misma posición. */
.ag-subasta .ag-lugar {
    display: inline-flex; align-items: center; gap: 5px;
    margin: 6px 0 0; padding: 0;
    font-size: 12px; line-height: 1.35;
    color: var(--sd-suave, #6b7a70);
}
.ag-subasta .ag-lugar iconify-icon { flex: 0 0 auto; font-size: 13px; }

.ag-subasta .ag-subasta-puja { position: relative; z-index: 2; text-align: right; }
.ag-subasta .ag-subasta-puja small { display: block; font-size: 11px; color: var(--sd-suave, #6b7a70); }
.ag-subasta .ag-subasta-puja b {
    display: block; margin-top: 2px;
    font-size: 15px; font-weight: 800; color: var(--sd-tinta, #16211a);
}
.ag-subasta .ag-subasta-puja .ag-btn { margin-top: 7px; }

/* ── EL FOCO TIENE QUE VERSE ────────────────────────────────────────── */

.ag-card .ag-btn:focus-visible, .ag-mini .ag-btn:focus-visible, .ag-subasta .ag-btn:focus-visible,
.ag-card .ag-fav:focus-visible, .ag-mini .ag-fav:focus-visible,
.ag-card .ag-tapa:focus-visible, .ag-mini .ag-tapa:focus-visible, .ag-subasta .ag-tapa:focus-visible {
    outline: 2px solid var(--sd-verde, #04713a);
    outline-offset: 2px;
}

/* ══ LAS ETIQUETAS Y LOS DATOS DE VENTA ════════════════════════════════
 *
 * Dos filas que la tarjeta trae y **no enseña por defecto**: en una rejilla de
 * 262 productos suman dos líneas a cada tarjeta para repetir lo que ya dice la
 * etiqueta de la esquina. Se encienden donde hay ancho de sobra --la fila
 * apaisada de destacados-- desde la hoja de esa pantalla.
 *
 * CANDIDATAS A LA HOJA COMÚN del área de cliente junto con el resto de la
 * tarjeta; van aquí porque son de la tarjeta, no de la tienda.
 */
.ag-card .ag-tags,
.ag-card .ag-meta { display: none; }

/* ── LAS ETIQUETAS: qué es la mercancía ───────────────────────────── */
.ag-card .ag-tags { flex-wrap: wrap; gap: 6px; margin-top: 9px; }

.ag-card .ag-tag {
    display: inline-flex; align-items: center;
    padding: 3px 9px;
    border-radius: 6px;
    background: #f1f4f1;
    border: 1px solid var(--sd-borde, #e4eae4);
    color: var(--sd-texto, #46514a);
    font-size: 11px; font-weight: 600; line-height: 1.4;
}

/* El cultivo ecológico con su verde: es el que el comprador busca, y en gris
   pesa lo mismo que el formato del envase. */
.ag-card .ag-tag.es-eco {
    background: #e8f5ec;
    border-color: #bfe3cb;
    color: #1d753b;
}

/* Y los sellos de finca en azul apagado: son una afirmación del agricultor
   --«Producción integrada», «GlobalG.A.P.»--, no un certificado ecológico, y
   con el mismo verde se leerían como lo segundo. */
.ag-card .ag-tag.es-info {
    background: #eaf2fb;
    border-color: #c8ddf4;
    color: #1c5b96;
}

/* ── LOS DATOS DE VENTA: cómo y cuándo se compra ──────────────────── */
.ag-card .ag-meta {
    flex-wrap: wrap;
    align-items: center;
    gap: 6px 16px;
    padding: 9px 14px;
    border-top: 1px solid var(--sd-borde, #e4eae4);
    background: #fbfdfb;

    /* COMO EL CUERPO: la tapa que hace pulsable la tarjeta entera vive debajo,
       y sin esto esta franja se traga el clic en toda su altura. */
    position: relative; z-index: 2;
    pointer-events: none;
}

.ag-card .ag-meta-it {
    display: inline-flex; align-items: center; gap: 5px;
    font-size: 11.5px; font-weight: 600;
    color: var(--sd-suave, #6b7a70);
    white-space: nowrap;
}
.ag-card .ag-meta-it iconify-icon { font-size: 13px; color: var(--sd-tenue, #93a399); }

/* ══ EL PIE, YA FUERA DEL CUERPO ═══════════════════════════════════════
 *
 * Se sacó de `.ag-cuerpo` para que en apaisado pueda compartir fila con los
 * datos de venta. En la tarjeta vertical no cambia nada a la vista --sigue
 * siendo lo último y pegado al fondo por su `margin-top: auto`-- pero necesita
 * lo que antes le daba el cuerpo: el relleno lateral y, sobre todo, el paso del
 * ratón. El cuerpo es `pointer-events: none` para que la tapa que hace pulsable
 * la tarjeta entera reciba el clic, y sus botones lo recuperaban con una regla
 * propia; fuera de él, sin esto, el botón de comprar dejaba de responder EN
 * TODAS LAS PANTALLAS y sin un solo error.
 */
.ag-card > .ag-cuerpo { padding-bottom: 0; }

.ag-card > .ag-pie {
    padding: 10px 14px 14px;
    position: relative; z-index: 2;
    pointer-events: none;
}
.ag-card > .ag-pie > * { pointer-events: auto; }

/* ══ EL SELLO DE VERIFICADO ════════════════════════════════════════════
   Relleno y azul: de trazo se lee como «se puede verificar». Va pegado al
   nombre del vendedor, en su línea. */
.ag-card .ag-vendedor { display: flex; align-items: center; gap: 5px; }

.ag-card .ag-verificado {
    flex: 0 0 auto;
    width: 15px; height: 15px;
    color: #1d8cf0;
}

/* ── LA ETIQUETA NO SE SALE DE LA TARJETA ──────────────────────────────
 *
 * `top/left` fijos y ningún tope de ancho: con un sello de dos palabras no se
 * notaba, pero desde que la etiqueta puede traer el sello de cultivo del
 * agricultor --«Sin tratamiento postcosecha»-- se salía por la derecha de la
 * tarjeta y se metía por debajo del corazón. El hueco que se le deja a la
 * derecha es el del corazón (34px) más su margen.
 */
.ag-card .ag-etiqueta, .ag-mini .ag-etiqueta {
    max-width: calc(100% - 56px);
    white-space: normal;
    line-height: 1.25;
}



/* ═══════════════════════════════════════════════════════════════════════════
   EL DIRECTORIO DE AGRICULTORES — la hoja común de las dos pantallas
   ═══════════════════════════════════════════════════════════════════════════

   Todo cuelga de `.sd`. Aquí vive lo que las DOS pantallas comparten --la
   tarjeta del vendedor y sus cuatro tallas, los sellos, las píldoras, el bloque
   de búsqueda, las cifras, las etiquetas de lo filtrado y la columna de
   criterios--; lo propio de cada una está en su propio componente.

   Los verdes están MUESTREADOS del PNG de la maqueta (botón #01753b, «Buscar»
   #01642c, pie #005c2d), no elegidos a ojo. Y los cuatro colores de medalla,
   muestreados de las piezas de `/assets/sellers/`: es el mismo dorado del sello
   el que rodea la tarjeta.

   CANDIDATO A LA HOJA COMÚN DEL ÁREA DE CLIENTE (ver CLAUDE.md): la tarjeta,
   las píldoras, la valoración y los botones se repiten ya en TOrderDetail y
   TReturnOrder con otros valores. Cuando esa hoja se extraiga, esto sube tal
   cual.
   ═══════════════════════════════════════════════════════════════════════════ */

.sd{
    --sd-verde:        #04713a;
    --sd-verde-vivo:   #01753b;
    --sd-verde-oscuro: #005c2d;
    --sd-verde-claro:  #eef6ee;
    --sd-verde-borde:  #cfe3d2;

    --sd-tinta:  #16211a;
    --sd-texto:  #46514a;
    --sd-suave:  #6b7a70;
    --sd-tenue:  #93a399;

    --sd-crema:  #f7faf6;
    --sd-borde:  #e4eae4;
    --sd-oro:    #e2a812;

    /* ── LOS COLORES DE LAS MEDALLAS ──────────────────────────────
       Muestreados de las piezas: el tono dominante de cada escarapela. Con
       ellos se rodea la tarjeta del vendedor que tiene ese nivel, para que la
       medalla y su borde sean lo mismo y no dos verdes distintos. */
    --sd-m-oro:      #d9a51e;
    --sd-m-plata:    #a8adb4;
    --sd-m-bronce:   #c1783a;
    --sd-m-diamante: #9aa0e8;

    --sd-radio:  14px;
    --sd-sombra: 0 2px 10px rgba(20,40,25,.06);

    color: var(--sd-texto);
    font-size: 14px;
    line-height: 1.45;
}

.sd *{ box-sizing: border-box; }
.sd img{ display:block; max-width:100%; }
.sd a{ color:inherit; text-decoration:none; }
.sd h1,.sd h2,.sd h3,.sd h4{ margin:0; color:var(--sd-tinta); }

/* EL TAMAÑO SE DECLARA EN EL ICONO, NO EN SU CAJA: `iconify-icon` no hereda el
   `font-size` del padre y sin esto todos saldrían al tamaño por defecto. */
.sd iconify-icon{ display:inline-block; vertical-align:-.125em; }

/* La hoja global del sitio pinta de negro el borde de cualquier enlace ya
   visitado (`a:visited`), y estas tarjetas SON enlaces: sin esto, volver a una
   búsqueda las enseña todas con marco negro. `getComputedStyle` no lo delata. */
.sd a:visited, .sd a:visited *{ border-color: inherit; color: inherit; }

/* El contenido recogido a la medida de la página; las franjas van a sangre. */
.sd-ancho{ max-width:1200px; margin:0 auto; padding:0 20px; }

/* ═══ BOTONES ══════════════════════════════════════════════════════ */
.sd .sd-btn{
    display:inline-flex; align-items:center; justify-content:center; gap:8px;
    height:40px; padding:0 18px; border:1px solid transparent; border-radius:9px;
    font-size:13.5px; font-weight:700; cursor:pointer; white-space:nowrap;
    font-family:inherit; transition:background .15s, border-color .15s, color .15s;
}
.sd .sd-btn-primary{ background:var(--sd-verde); color:#fff; }
.sd .sd-btn-primary:hover{ background:var(--sd-verde-oscuro); color:#fff; }
.sd .sd-btn-secondary{ background:#fff; color:var(--sd-tinta); border-color:var(--sd-borde); }
.sd .sd-btn-secondary:hover{ background:var(--sd-crema); color:var(--sd-tinta); }
.sd .sd-btn-blanco{ background:#fff; color:var(--sd-tinta); }
.sd .sd-btn-sm{ height:34px; padding:0 14px; font-size:12.5px; }
.sd .sd-btn-block{ width:100%; }

/* ═══ TÍTULOS DE SECCIÓN ═══════════════════════════════════════════ */
.sd-seccion{ padding:34px 0 0; }
.sd-tit{ display:flex; align-items:flex-end; gap:16px; margin-bottom:16px; }
.sd-tit-txt{ flex:1; min-width:0; }
.sd-tit h2{ font-size:17px; font-weight:800; letter-spacing:.3px; text-transform:uppercase;
            border-bottom:3px solid var(--sd-verde); display:inline-block; padding-bottom:6px; }
.sd-tit p{ margin:8px 0 0; font-size:12.5px; color:var(--sd-suave); }
.sd .sd-tit-mas{ flex:0 0 auto; font-size:12.5px; font-weight:700; color:var(--sd-verde);
                 display:inline-flex; align-items:center; gap:6px; }

/* ═══ EL BLOQUE DE BÚSQUEDA ════════════════════════════════════════ */
.sd-busca{ background:#fff; border:1px solid var(--sd-borde); border-radius:var(--sd-radio);
           box-shadow:0 14px 34px rgba(18,40,24,.13); padding:18px; }
.sd-busca-fila{ display:flex; gap:12px; }
.sd-busca-txt{ flex:1; display:flex; align-items:center; gap:10px; height:48px;
               border:1px solid var(--sd-borde); border-radius:10px; padding:0 14px; background:#fff; }
.sd-busca-txt iconify-icon{ font-size:18px; color:var(--sd-tenue); flex:0 0 auto; }
.sd-busca-txt input{ flex:1; min-width:0; border:0; outline:none; font-size:14px;
                     font-family:inherit; color:var(--sd-tinta); background:transparent; }
.sd .sd-btn-buscar{ height:48px; padding:0 30px; font-size:14px;
                    background:var(--sd-verde-oscuro); color:#fff; border-radius:10px; }

.sd-filtros{ display:grid; grid-template-columns:repeat(3,1fr); gap:14px; margin-top:14px; }
.sd-campo{ border:1px solid var(--sd-borde); border-radius:10px; padding:8px 12px 6px; background:#fff; }
.sd-campo label{ display:block; font-size:11px; color:var(--sd-suave); }
.sd-campo select{ width:100%; border:0; outline:none; background:transparent; font-size:13.5px;
                  font-weight:600; color:var(--sd-tinta); font-family:inherit; padding:2px 0; cursor:pointer; }

/* Los dos interruptores. APAGADOS DE SALIDA: encendidos esconden a la mayoría
   del censo y la primera pantalla del directorio parece vacía. */
.sd-switches{ display:grid; grid-template-columns:repeat(2,1fr); gap:14px; margin-top:14px; }
.sd-switch{ display:flex; align-items:center; gap:10px; border:1px solid var(--sd-borde);
            border-radius:10px; padding:10px 14px; cursor:pointer; background:#fff; }
.sd-switch > iconify-icon{ font-size:19px; color:var(--sd-verde); flex:0 0 auto; }
.sd-switch-txt{ flex:1; min-width:0; }
.sd-switch-txt b{ display:block; font-size:13px; color:var(--sd-tinta); font-weight:600; }
.sd-switch-txt small{ display:block; font-size:11px; color:var(--sd-suave); }
.sd-palanca{ flex:0 0 auto; width:44px; height:24px; border-radius:99px; background:#d8ded8;
             position:relative; transition:background .18s; }
.sd-palanca::after{ content:''; position:absolute; top:3px; left:3px; width:18px; height:18px;
                    border-radius:50%; background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.25); transition:left .18s; }
.sd-switch.on .sd-palanca{ background:var(--sd-verde); }
.sd-switch.on .sd-palanca::after{ left:23px; }

/* ═══ CIFRAS ═══════════════════════════════════════════════════════ */
.sd-cifras{ display:grid; grid-template-columns:repeat(4,1fr); background:var(--sd-crema);
            border:1px solid var(--sd-borde); border-radius:var(--sd-radio); margin-top:22px; }
.sd-cifra{ display:flex; align-items:center; gap:12px; padding:16px 20px; }
.sd-cifra + .sd-cifra{ border-left:1px solid var(--sd-borde); }
.sd-cifra > iconify-icon{ font-size:22px; color:var(--sd-verde); flex:0 0 auto; }
.sd-cifra div{ flex:1; min-width:0; }
.sd-cifra b{ display:block; font-size:19px; font-weight:800; color:var(--sd-tinta); line-height:1.15; }
.sd-cifra small{ display:block; font-size:11.5px; color:var(--sd-suave); }

/* ═══ PIEZAS DE UNA TARJETA ════════════════════════════════════════ */

/* EL SELLO VERIFICADO ES UNA IMAGEN, Y LA REGLA SE ESCRIBE CON `img`.
   `.sd img{display:block}` (0,1,1) le gana a `.sd-verificado` (0,1,0) y el sello
   se iba a su propia línea debajo del nombre -- el mismo mordisco que ya estaba
   documentado en `.sd-card-foto img.sd-card-sello`. Con la clase Y el elemento,
   esta manda. Bajado tres píxeles para que se siente en la base del nombre y no
   sobre su altura de mayúsculas. */
.sd img.sd-verificado{ display:inline-block; vertical-align:-3px; width:16px; height:16px;
                       margin-left:5px; object-fit:contain; }

/* Icono a la izquierda y TODO el texto en la segunda columna: la regla de
   alineación del proyecto. Nada de `margin-left` a ojo para compensar el icono. */
.sd-linea{ display:flex; align-items:flex-start; gap:6px; margin-top:5px; }
.sd-linea > iconify-icon{ font-size:13px; color:var(--sd-tenue); flex:0 0 auto; margin-top:2px; }
.sd-linea span{ flex:1; min-width:0; font-size:12px; color:var(--sd-suave); }

.sd-rating{ display:flex; align-items:center; gap:5px; margin-top:7px; font-size:12.5px; }
.sd-rating b{ color:var(--sd-tinta); font-weight:700; }
.sd-rating iconify-icon{ color:var(--sd-oro); font-size:13px; }
.sd-rating small{ color:var(--sd-suave); font-size:11.5px; }

.sd-hechos{ display:flex; gap:14px; margin-top:10px; margin-bottom:12px; padding-top:10px;
            border-top:1px solid var(--sd-borde); }
.sd-hecho{ display:flex; align-items:flex-start; gap:6px; flex:1; min-width:0; }
.sd-hecho > iconify-icon{ font-size:14px; color:var(--sd-verde); flex:0 0 auto; margin-top:1px; }
.sd-hecho div{ flex:1; min-width:0; }
.sd-hecho b{ display:block; font-size:12px; color:var(--sd-tinta); }
.sd-hecho small{ display:block; font-size:10.5px; color:var(--sd-suave); }

.sd-pills{ display:flex; flex-wrap:wrap; gap:6px; margin-top:10px; }
.sd-pill{ font-size:10.5px; font-weight:700; border-radius:99px; padding:3px 9px;
          background:var(--sd-verde-claro); color:var(--sd-verde-oscuro); border:1px solid var(--sd-verde-borde); }

.sd-nivel{ display:inline-flex; align-items:center; gap:4px; background:var(--sd-crema);
           border:1px solid var(--sd-borde); border-radius:99px; padding:2px 9px 2px 3px;
           font-size:10px; font-weight:700; color:var(--sd-tinta); white-space:nowrap; }
.sd-nivel img{ width:18px; height:18px; object-fit:contain; }

.sd-proteccion{ display:flex; align-items:center; gap:7px; margin-top:auto;
                background:var(--sd-verde-claro); border-top:1px solid var(--sd-verde-borde);
                padding:9px 14px; }
.sd-proteccion iconify-icon{ color:var(--sd-verde); font-size:14px; flex:0 0 auto; }
.sd-proteccion span{ font-size:11.5px; font-weight:700; color:var(--sd-verde-oscuro); }

/* El avatar: con foto o con su inicial. Un círculo con letra se lee como una
   identidad; un hueco gris, no. */
.sd-avatar{ flex:0 0 auto; width:44px; height:44px; border-radius:50%; overflow:hidden;
            background:var(--sd-verde-claro); color:var(--sd-verde-oscuro); font-weight:800;
            display:flex; align-items:center; justify-content:center; font-size:15px;
            border:1px solid var(--sd-verde-borde); }
.sd-avatar img{ width:100%; height:100%; object-fit:cover; }

/* La foto de portada cuando el vendedor no ha subido ninguna: su inicial sobre
   el verde de la casa. NUNCA una foto de archivo: sería enseñar una finca que
   no es la suya. */
.sd-portada-vacia{ position:absolute; inset:0; z-index:1; display:flex; align-items:center;
                   justify-content:center; gap:10px; color:#7ba57f;
                   background:linear-gradient(135deg, #e8f2e6 0%, #d7e9d6 100%); }
.sd-portada-vacia iconify-icon{ font-size:26px; }
/* Las iniciales, para que el hueco se lea como una identidad y no como una foto
   que no ha cargado. */
.sd-portada-vacia b{ font-size:22px; font-weight:800; letter-spacing:1px; color:#6f9c74; }

/* ═══ LA TARJETA ════════════════════════════════════════════════════
   Vive en `TSellerCard` (Storefront/templates), con sus tokens puestos en la
   propia tarjeta: así no pierde el borde fuera de `.sd`, en favoritos. */

/* ═══ CARRIL ═══════════════════════════════════════════════════════ */
.sd-carril{ position:relative; }
.sd-carril-pista{ display:grid; grid-auto-flow:column; grid-auto-columns:calc((100% - 4*14px)/5);
                  gap:14px; overflow-x:auto; scroll-behavior:smooth; padding:4px 2px 8px;
                  scrollbar-width:none; }
.sd-carril-pista::-webkit-scrollbar{ display:none; }
.sd-flecha{ position:absolute; top:50%; right:-16px; transform:translateY(-50%); z-index:3;
            width:34px; height:34px; border-radius:50%; background:#fff; border:1px solid var(--sd-borde);
            box-shadow:0 3px 10px rgba(20,40,25,.16); display:flex; align-items:center; justify-content:center;
            cursor:pointer; color:var(--sd-tinta); }

/* ═══ ETIQUETAS DE LO FILTRADO ═════════════════════════════════════
   Arriba del todo y quitables una a una. Un filtro puesto hace tres pantallas
   y olvidado es la causa número uno de «no hay resultados». */
.sd-chips{ display:flex; align-items:center; flex-wrap:wrap; gap:8px; margin-bottom:12px; }
.sd-chips-tit{ font-size:11.5px; font-weight:700; color:var(--sd-suave);
               text-transform:uppercase; letter-spacing:.4px; }
.sd-chip{ display:inline-flex; align-items:center; gap:6px; background:var(--sd-verde-claro);
          border:1px solid var(--sd-verde-borde); border-radius:99px; padding:4px 6px 4px 11px;
          font-size:11.5px; font-weight:600; color:var(--sd-verde-oscuro); }
.sd-chip button{ border:0; background:rgba(0,0,0,.06); color:inherit; cursor:pointer;
                 width:16px; height:16px; border-radius:50%; display:flex; align-items:center;
                 justify-content:center; font-size:10px; padding:0; }
.sd-chip button:hover{ background:var(--sd-verde); color:#fff; }
.sd-chips-limpiar{ font-size:11.5px; font-weight:700; color:var(--sd-verde); cursor:pointer;
                   display:inline-flex; align-items:center; gap:5px; background:none; border:0;
                   font-family:inherit; }

/* ═══ COLUMNA DE CRITERIOS ═════════════════════════════════════════ */
.sd-panel{ background:#fff; border:1px solid var(--sd-borde); border-radius:var(--sd-radio);
           box-shadow:var(--sd-sombra); overflow:hidden; }
.sd-panel-cab{ display:flex; align-items:center; gap:8px; padding:11px 14px;
               border-bottom:1px solid var(--sd-borde); }
.sd-panel-cab > iconify-icon{ color:var(--sd-verde); font-size:16px; flex:0 0 auto; }
.sd-panel-cab b{ flex:1; min-width:0; font-size:13px; color:var(--sd-tinta); }
.sd-panel-cab a{ font-size:11.5px; font-weight:700; color:var(--sd-verde); cursor:pointer; }

.sd-grupo{ border-bottom:1px solid var(--sd-borde); }
.sd-grupo:last-child{ border-bottom:0; }
.sd-grupo-cab{ width:100%; display:flex; align-items:center; gap:8px; padding:11px 14px;
               background:none; border:0; cursor:pointer; font-family:inherit; text-align:left; }
.sd-grupo-cab b{ flex:1; min-width:0; font-size:12.5px; font-weight:700; color:var(--sd-tinta); }
.sd-grupo-cab > iconify-icon:first-child{ font-size:15px; color:var(--sd-verde); flex:0 0 auto; }
.sd-grupo-flecha{ font-size:15px; color:var(--sd-tenue); transition:transform .15s; }
.sd-grupo.cerrado .sd-grupo-flecha{ transform:rotate(-90deg); }
.sd-grupo-cuerpo{ padding:0 14px 12px; }
.sd-grupo.cerrado .sd-grupo-cuerpo{ display:none; }

.sd-buscasub{ display:flex; align-items:center; gap:6px; border:1px solid var(--sd-borde);
              border-radius:8px; padding:5px 9px; margin-bottom:8px; }
.sd-buscasub iconify-icon{ font-size:14px; color:var(--sd-tenue); flex:0 0 auto; }
.sd-buscasub input{ flex:1; min-width:0; border:0; outline:none; font-family:inherit; font-size:12px; }

/* Una casilla, con SU RECUENTO: sin él no se sabe si un filtro deja dos
   resultados o doscientos, y se prueba a ciegas. */
.sd-check{ display:flex; align-items:center; gap:8px; padding:4px 0; cursor:pointer; }
.sd-check input{ position:absolute; opacity:0; width:0; height:0; }
.sd-marca{ flex:0 0 auto; width:16px; height:16px; border:1px solid #c8d2c8; border-radius:4px;
           background:#fff; display:flex; align-items:center; justify-content:center;
           color:#fff; font-size:11px; }
.sd-check input:checked + .sd-marca{ background:var(--sd-verde); border-color:var(--sd-verde); }
.sd-marca iconify-icon{ visibility:hidden; }
.sd-check input:checked + .sd-marca iconify-icon{ visibility:visible; }
.sd-check-txt{ flex:1; min-width:0; font-size:12px; color:var(--sd-texto);
               display:flex; align-items:center; gap:6px; }
.sd-check-txt img{ width:17px; height:17px; object-fit:contain; }
.sd-check i{ flex:0 0 auto; font-style:normal; font-size:10.5px; color:var(--sd-tenue); }
.sd-check input:checked ~ .sd-check-txt{ color:var(--sd-verde-oscuro); font-weight:600; }
.sd-vermas{ display:inline-block; margin-top:6px; font-size:11.5px; font-weight:700;
            color:var(--sd-verde); cursor:pointer; }

/* Valoración mínima: una sola respuesta, así que píldoras y no casillas. */
.sd-notas{ display:flex; flex-wrap:wrap; gap:6px; }
.sd-nota{ cursor:pointer; }
.sd-nota input{ position:absolute; opacity:0; }
.sd-nota span{ display:inline-flex; align-items:center; gap:4px; border:1px solid var(--sd-borde);
               border-radius:99px; padding:4px 10px; font-size:11.5px; color:var(--sd-texto); }
.sd-nota span iconify-icon{ color:var(--sd-oro); font-size:12px; }
.sd-nota input:checked + span{ background:var(--sd-verde-claro); border-color:var(--sd-verde);
                               color:var(--sd-verde-oscuro); font-weight:700; }

/* ═══ BARRA DE RESULTADOS Y VISTAS ═════════════════════════════════ */
.sd-barra{ display:flex; align-items:center; gap:10px; margin-bottom:14px; }
.sd-barra h2{ font-size:15px; font-weight:800; display:flex; align-items:center; gap:8px;
              text-transform:none; border:0; padding:0; }
.sd-barra h2 iconify-icon{ color:var(--sd-verde); font-size:17px; }
.sd-barra small{ color:var(--sd-suave); font-size:12px; }
.sd-barra-sp{ flex:1; }

.sd-vista{ display:flex; border:1px solid var(--sd-borde); border-radius:8px; overflow:hidden; }
.sd-vista button{ width:34px; height:34px; border:0; background:#fff; cursor:pointer;
                  color:var(--sd-suave); font-size:16px; }
.sd-vista button.on{ background:var(--sd-verde-claro); color:var(--sd-verde-oscuro); }

/* ═══ PAGINACIÓN ═══════════════════════════════════════════════════ */
/* LA PAGINACIÓN ES UN <nav>, Y ESO LA VESTÍA SOLA.
   `www_oneway/base.php` tiene una regla global para `nav` --la que pinta la
   barra de categorías del sitio-- con fondo blanco y `border-bottom: 1px solid
   #bbb`. Como el paginador también es un `nav`, se llevaba la raya gris de
   extremo a extremo por debajo de los resultados, como si allí acabara una
   sección. El fondo blanco se deja puesto a propósito; la raya se quita. */
.sd-pag{ display:flex; justify-content:center; align-items:center; gap:6px; margin:22px 0 6px;
         background-color:#FFF; border-bottom:0; }
.sd-pag a,.sd-pag span{ min-width:32px; height:32px; border-radius:8px; border:1px solid var(--sd-borde);
                        background:#fff; display:flex; align-items:center; justify-content:center;
                        font-size:12.5px; font-weight:700; color:var(--sd-tinta); cursor:pointer; }
.sd-pag .on{ background:var(--sd-verde); border-color:var(--sd-verde); color:#fff; }
.sd-pag .vacio{ border:0; background:transparent; color:var(--sd-tenue); cursor:default; }

/* ═══ COMPROMISOS ══════════════════════════════════════════════════ */
.sd-promesas{ display:grid; grid-template-columns:repeat(4,1fr); gap:22px; background:var(--sd-crema);
              border:1px solid var(--sd-borde); border-radius:var(--sd-radio);
              padding:20px 22px; margin:34px 0 40px; }
.sd-promesa{ display:flex; align-items:flex-start; gap:12px; }
.sd-promesa > span{ flex:0 0 auto; width:38px; height:38px; border-radius:50%; background:#fff;
                    border:1px solid var(--sd-verde-borde); display:flex; align-items:center;
                    justify-content:center; color:var(--sd-verde); font-size:18px; }
.sd-promesa div{ flex:1; min-width:0; }
.sd-promesa b{ display:block; font-size:13px; color:var(--sd-verde-oscuro); }
.sd-promesa small{ display:block; font-size:11.5px; color:var(--sd-suave); margin-top:3px; }

/* ═══ SIN RESULTADOS ═══════════════════════════════════════════════
   Y con la salida puesta: decir «no hay nada» sin ofrecer cómo deshacer el
   filtro que lo ha dejado vacío es dejar al visitante en un callejón. */
.sd-vacio{ text-align:center; padding:44px 20px; background:#fff;
           border:1px dashed var(--sd-borde); border-radius:var(--sd-radio); }
.sd-vacio iconify-icon{ font-size:32px; color:var(--sd-tenue); }
.sd-vacio b{ display:block; margin-top:10px; font-size:15px; color:var(--sd-tinta); }
.sd-vacio small{ display:block; margin:6px 0 14px; font-size:12.5px; color:var(--sd-suave); }

@media (max-width:1100px){
    .sd-promesas{ grid-template-columns:repeat(2,1fr); }
    .sd-carril-pista{ grid-auto-columns:calc((100% - 2*14px)/3); }
}
@media (max-width:760px){
    .sd-filtros,.sd-switches,.sd-cifras{ grid-template-columns:1fr; }
    .sd-cifra + .sd-cifra{ border-left:0; border-top:1px solid var(--sd-borde); }
    .sd-carril-pista{ grid-auto-columns:78%; }
    .sd-promesas{ grid-template-columns:1fr; }

    /* A 400 px el botón «Buscar» se salía 48 px por la derecha (medido el
       15/09/2026, al soltar el ancho mínimo del sitio): la caja de texto no
       baja de su contenido sin `min-width:0`. Caja arriba y botón debajo. */
    .sd-busca-fila{ flex-wrap:wrap; }
    .sd-busca-txt{ min-width:0; flex:1 1 100%; }
    .sd .sd-btn-buscar{ flex:1 1 100%; }

    /* Y las flechas del carril, dentro del borde: a -16 px empujaban la página. */
    .sd-flecha{ right:0; }
}



/**
 * ═══════════════════════════════════════════════════════════════════════════
 *  LA TIENDA — lo que el sistema `sd-*` no cubre
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Los paneles de filtro, los grupos plegables, las casillas con recuento, los
 * chips, la barra de resultados y el cambio de vista vienen de `TSellersUI` sin
 * tocar una línea: es el mismo filtro del buscador de agricultores, como debe
 * ser. Aquí solo hay tres cosas que allí no existen:
 *
 *   · la PORTADA de la sección, con la foto y el texto de la categoría,
 *   · la disposición de dos columnas de esta página,
 *   · y la TARJETA DE PRODUCTO, en sus tres formas: compra directa, subasta y
 *     patrocinada grande.
 *
 * Todo cuelga de `.tf` para no alcanzar a nada de fuera, y usa los tokens
 * `--sd-*` que ya declara `TSellersUI`: colores propios aquí serían una segunda
 * paleta para la misma pantalla.
 */

/* ══ EL ANCHO DE ESTA PÁGINA ═══════════════════════════════════════
 *
 * `sd-ancho` se recoge a 1.200px, que es lo que le conviene a un directorio de
 * fichas de vendedor. Un buscador de productos NO: aquí lo que se compara son
 * cinco columnas de tarjetas, y a 1.200 con la columna de filtros restando
 * quedan 930 para la rejilla -- tarjetas de 175px con el nombre en cuatro
 * líneas. Se ensancha SOLO dentro de `.tf`, sin tocar la hoja común, que es de
 * las dos páginas. */
.tf .sd-ancho{ max-width: none; padding: 0; }

/* ── ALINEADA CON LA CABECERA DEL SITIO ─────────────────────────────
 *
 * Antes esto era `max-width: 1560px` con los 20px de relleno de `sd-ancho`: el
 * cuerpo arrancaba en x=124 y el logo de la cabecera en x=50, dos verticales
 * distintas en la misma pantalla --y con más ancho, cada vez más separadas--.
 * La cabecera y el cuerpo cuelgan de la MISMA columna (`.body-content`, que ya
 * topa en 1728px y pone los 30px de gutter), así que basta con que la caja no
 * se recoja por su cuenta: el borde izquierdo del logo, el de la portada y el
 * del filtro coinciden, y lo mismo el derecho. Y de paso la rejilla gana ancho,
 * que era la razón de ensancharla. */

/* ══ LA PORTADA DE LA SECCIÓN ══════════════════════════════════════ */

/* La caja común de la página: portada, cifras, cuerpo y garantías comparten
   columna, así que se declara una vez y todo cuelga de ella. */
.tf-caja{ padding-bottom: 8px; }

.tf-portada{
    position: relative;
    display: flex;
    align-items: flex-end;
    min-height: 260px;
    /* EL TEXTO NO PEGA CON EL BORDE DE LA FOTO: 0 a los lados dejaba el titular
       y la descripción rozando la esquina redondeada de la portada. */
    padding: 34px 40px 30px;
    overflow: hidden;
    border-radius: var(--sd-radio, 14px);
    margin-top: 14px;
}

/* LA FOTO, EN SU PROPIA CAPA Y NO COMO FONDO DEL BLOQUE. Así el JS le cambia
   la `background-image` sin tocar el degradado de encima, que es fijo: con las
   dos en la misma declaración, cada cambio de categoría tendría que reescribir
   también el velo. */
.tf-portada-foto{
    position: absolute; inset: 0;

    /* EL ENCUADRE, POR ENCIMA DEL CENTRO Y NO EN EL CENTRO.
     *
     * La caja es una franja de 1250x260 --casi 5:1-- y las portadas son fotos
     * normales, de 2:1 para abajo: `cover` las recorta a lo alto y solo se ve
     * una banda. Centrada, esa banda parte al sujeto por la mitad: en la
     * portada genérica se llevaba por delante el sombrero del agricultor por
     * arriba y la caja de aguacates por abajo, que es justo lo que la foto
     * viene a enseñar.
     *
     * El 35% sube la banda: en una foto de persona la cara vive en el tercio
     * superior, y ahí es donde tiene que caer el recorte. */
    background-position: center 35%;
    background-size: cover;
    background-repeat: no-repeat;
}

/* El velo va de opaco a transparente hacia la derecha: el texto vive a la
   izquierda y la foto tiene que seguir viéndose al otro lado.

   ── LA MESETA LLEGA HASTA DONDE LLEGA EL TEXTO (25/09/2026) ─────────
   Caía a .58 en el 42% y la descripción mide 620px: su segunda mitad quedaba
   sobre velo flojo. Con el titular --34px en negrita-- no se notaba; con la
   descripción a 13.5px sí, y solo se ha visto ahora porque hasta hoy ninguna
   categoría tenía descripción escrita (todas a 0 caracteres). La meseta se
   mantiene hasta el 56% --donde acaba la columna de texto-- y de ahí cae igual
   de rápido: la foto sigue entera en su mitad derecha, que es lo que el velo
   venía a proteger. */
.tf-portada-velo{
    position: absolute; inset: 0;
    background: linear-gradient(90deg,
        rgba(8, 30, 16, .86) 0%,
        rgba(8, 30, 16, .74) 38%,
        rgba(8, 30, 16, .52) 56%,
        rgba(8, 30, 16, .12) 82%,
        rgba(8, 30, 16, 0) 100%);
}

/* `min-width: 0`, QUE ES ÍTEM DE UN FLEX. `.tf-portada` es `display:flex`, y un
   ítem flex no baja de su ancho de contenido salvo que se le diga: la fila de
   familias en móvil --que va en una sola línea con arrastre-- estiraba este
   hueco a 1.334px dentro de una portada de 373px, y el `overflow:hidden` de la
   portada se comía las nueve últimas familias. No se veían y no había forma de
   llegar a ellas. Medido en el navegador a 420px de ancho. */
.tf-portada-txt{ position: relative; z-index: 1; min-width: 0; flex: 1; }

.tf-portada h1{
    /* PADDING A CERO, Y NO ES ADORNO: la hoja del sitio le da `padding: 10px`
       a todo `h1`, así que el titular arrancaba 10px a la derecha de su propia
       descripción. Dos verticales en el mismo bloque de texto -- se lee
       torcido aunque cada línea esté bien puesta. */
    margin: 0 0 8px;
    padding: 0;
    font-size: 34px; font-weight: 800; letter-spacing: -.8px;
    color: #fff;
}

/* LA DESCRIPCIÓN ADMITE MARCADO --la escribe un editor con el editor rico-- así
   que se le da estilo a lo que puede traer dentro: párrafos, negritas, listas.
   Sin esto, un `<ul>` heredaría los topos y el margen del navegador y saldría
   descolocado sobre la foto. */
.tf-portada-desc{
    max-width: 620px;
    font-size: 13.5px; line-height: 1.6;
    color: rgba(255,255,255,.92);
}
/* ── `color: inherit`, Y ES LO QUE HACÍA ILEGIBLE LA DESCRIPCIÓN ───────
   `boot.css` trae `p{ color: #000 }` para todo el sitio, y una regla que apunta
   al `<p>` le gana al blanco HEREDADO del contenedor, por floja que sea. Como
   la descripción la escribe el editor rico --y el editor rico envuelve en
   `<p>`--, el texto de cualquier categoría con descripción salía NEGRO sobre la
   portada oscura: se leía como una mancha, y las negritas (que sí tenían su
   regla) blancas en medio. Medido: `getComputedStyle(p).color` daba
   `rgb(0,0,0)` con el contenedor en `rgba(255,255,255,.92)`.
   La misma trampa que `a span` en las píldoras de familia, unas líneas abajo. */
.tf-portada-desc p{ margin: 0 0 8px; color: inherit; }
.tf-portada-desc p:last-child{ margin-bottom: 0; }
.tf-portada-desc b, .tf-portada-desc strong{ color: #fff; }
.tf-portada-desc ul{ margin: 6px 0; padding-left: 18px; color: inherit; }
.tf-portada-desc li{ margin: 2px 0; color: inherit; }
.tf-portada-desc a{ color: #fff; text-decoration: underline; }
.tf-portada-desc a:visited{ color: #fff; }

/* Las píldoras de la cabecera. */
.tf-pills{ display: flex; flex-wrap: wrap; gap: 8px; margin-top: 14px; }
.tf-pill{
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 12px;
    border-radius: 999px;
    background: rgba(255,255,255,.14);
    border: 1px solid rgba(255,255,255,.28);
    color: #fff;
    font-size: 11.5px; font-weight: 700;
    backdrop-filter: blur(2px);
}
.tf-pill iconify-icon{ font-size: 13px; }

/* ══ SUBCATEGORÍAS ═════════════════════════════════════════════════════
 *
 * La fila de familias que va ENCIMA DE LA REJILLA, en la columna de resultados.
 * Estuvo primero sobre la portada --de ahí las reglas oscuras de más abajo, que
 * siguen valiendo si alguna vez vuelve ahí-- y se bajó aquí porque sobre la foto
 * competía con las píldoras de tono y su contraste dependía de la imagen.
 *
 * CANDIDATO A LA HOJA COMÚN del área de cliente: una fila de enlaces con dibujo
 * y recuento es lo que necesitan también el perfil del agricultor y la
 * colección. Mientras no exista, vive aquí y queda dicho.
 */
.tf-subcats-zona{
    margin: 0 0 18px;
    padding: 14px 16px 16px;
    background: #fff;
    border: 1px solid var(--sd-borde);
    border-radius: var(--sd-radio, 14px);
}

/* El rótulo, con la misma talla que los títulos de grupo de la columna de
   filtros: es la misma jerarquía --un grupo de opciones-- y con dos tallas
   distintas la pantalla se lee como dos pantallas. */
.tf-subcats-t{
    margin: 0 0 10px;
    padding: 0;                      /* la hoja del sitio le mete 10px a los h2 */
    font-size: 12.5px; font-weight: 700;
    color: var(--sd-tinta);
    letter-spacing: 0;
}

.tf-subcats{ display: flex; flex-wrap: wrap; gap: 8px; }

/* ── LA PÍLDORA ────────────────────────────────────────────────────────
 *
 * EL `:visited` VA EN CADA REGLA, Y CON LA CLASE DEL CONTENEDOR DELANTE. Las
 * dos hojas viejas del sitio le meten mano a los enlaces ya visitados sin
 * clase que las acote --`boot.css` con `a:visited{ color:#910c88; border:0 }` y
 * `TSellersUI` con `.sd a:visited{ border-color: inherit }`-- y las dos EMPATAN
 * a especificidad con `.tf-subcat:visited` (0,0,1,1), así que ganan por orden
 * de hoja. Se vio en pantalla: las familias por las que ya se había pasado
 * salían con el borde NEGRO --`inherit` en un borde da el `currentColor` del
 * padre-- y las demás en gris claro, o sea media fila subrayada al azar según
 * por dónde hubiera navegado el visitante. Con `.tf-subcats` delante son
 * 0,0,2,1 y se acabó. Lo mismo hay que hacer con el texto de dentro, más abajo:
 * ahí el rival es `a span`, y una regla al hijo le gana a lo HEREDADO del
 * padre por floja que sea. */
.tf-subcats .tf-subcat,
.tf-subcats .tf-subcat:visited{
    display: inline-flex; align-items: center; gap: 8px;
    padding: 5px 12px 5px 5px;
    border-radius: 999px;
    background: var(--sd-crema);
    border: 1px solid var(--sd-borde);
    color: var(--sd-tinta);
    text-decoration: none;
    transition: border-color .15s, background .15s, box-shadow .15s;
}
.tf-subcats .tf-subcat:hover,
.tf-subcats .tf-subcat:focus-visible{
    background: #fff;
    border-color: var(--sd-verde);
    box-shadow: var(--sd-sombra, 0 2px 10px rgba(20,40,25,.06));
    text-decoration: none;
}
.tf-subcats .tf-subcat:focus-visible{ outline: 2px solid var(--sd-verde); outline-offset: 2px; }

/* EL DIBUJO, SIEMPRE EN SU HUECO Y SIEMPRE DEL MISMO TAMAÑO. La imagen que sube
   ADMIN puede venir de cualquier proporción --y de último recurso entra la
   PORTADA, que es casi 5:1--: sin `object-fit` se deformaría, y sin el círculo
   fijo cada píldora mediría una cosa. */
.tf-subcats .tf-subcat-ico{
    flex: 0 0 auto;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 50%;
    overflow: hidden;
    background: #fff;
    border: 1px solid var(--sd-borde);
    color: var(--sd-verde);
}
.tf-subcats .tf-subcat-ico img{ width: 100%; height: 100%; object-fit: cover; display: block; }
.tf-subcats .tf-subcat-ico iconify-icon{ font-size: 19px; }

.tf-subcats .tf-subcat:hover .tf-subcat-ico{ border-color: var(--sd-verde); }

/* El nombre, con su color dicho: `boot.css` pinta `a span{ color:#910c88;
   font-size:11px }` para todo el sitio y una regla al hijo le gana al color
   heredado del enlace, por floja que sea. */
.tf-subcats .tf-subcat .tf-subcat-n,
.tf-subcats .tf-subcat:visited .tf-subcat-n{
    color: var(--sd-tinta);
    font-size: 12.5px; font-weight: 600;
    line-height: 1.2;
}

/* El recuento, en su propia cápsula: sin ella, «Miel y conservas 12» se lee
   como parte del nombre de la familia. */
.tf-subcats .tf-subcat > b,
.tf-subcats .tf-subcat:visited > b{
    padding: 1px 7px;
    border-radius: 999px;
    background: #eef3ee;
    color: var(--sd-suave);
    font-size: 11px; font-weight: 700;
}
.tf-subcats .tf-subcat:hover > b{ background: #e6f2ea; color: var(--sd-verde); }

/* ── EL BOTÓN DE «VER TODAS» ───────────────────────────────────────────
   Nace oculto --con el atributo `hidden`, que el JS quita solo si de verdad no
   caben-- y es de TEXTO, no una píldora más: si se pareciera a las familias se
   leería como una de ellas, y lo que hace es otra cosa. */
.tf-subcats-mas{
    display: inline-flex; align-items: center; gap: 6px;
    margin-top: 10px;
    padding: 4px 2px;
    border: 0; background: none;
    color: var(--sd-verde);
    font-family: inherit; font-size: 12.5px; font-weight: 700;
    cursor: pointer;
}
.tf-subcats-mas[hidden]{ display: none; }
.tf-subcats-mas:hover{ text-decoration: underline; }
.tf-subcats-mas:focus-visible{ outline: 2px solid var(--sd-verde); outline-offset: 2px; border-radius: 6px; }
.tf-subcats-mas iconify-icon{ font-size: 15px; transition: transform .15s; }
.tf-subcats-mas[aria-expanded="true"] iconify-icon{ transform: rotate(180deg); }

/* ── LA QUE SE ESTÁ MIRANDO ────────────────────────────────────────────
 *
 * Marcada con el verde de la casa: borde, fondo blanco y el dibujo sobre verde.
 * No basta con el borde --a 1px y en una fila de doce no se ve-- ni basta con el
 * fondo: el borde es lo que se distingue de lejos y el relleno del icono lo que
 * se distingue de cerca.
 *
 * Y ADEMÁS `aria-current="page"` en el marcado, que es lo que lo dice sin
 * mirar: un color no llega a quien usa lector de pantalla, y tampoco a quien no
 * distingue el verde del gris (WCAG 2.1 AA: el color no puede ser el único
 * portador de la información).
 */
.tf-subcats .tf-subcat.es-activa,
.tf-subcats .tf-subcat.es-activa:visited{
    background: #fff;
    border-color: var(--sd-verde);
    box-shadow: 0 0 0 1px var(--sd-verde) inset;
}
/* EL ICONO DE LA SELECCIONADA VA SIN ARO. Con su círculo y su borde había DOS
   marcos concéntricos diciendo lo mismo --el de la píldora y el del icono-- y el
   dibujo quedaba encerrado en una moneda. Lo que marca la elección es el borde
   que rodea la píldora entera; dentro, el icono flota sobre el blanco. */
.tf-subcats .tf-subcat.es-activa .tf-subcat-ico{
    background: transparent;
    border-color: transparent;
}
.tf-subcats .tf-subcat.es-activa .tf-subcat-n{ color: var(--sd-verde-oscuro, #0b5a2d); }

.tf-subcats .tf-subcat.es-activa > b{
    background: var(--sd-verde);
    color: #fff;
}

/* ── Y LA VARIANTE DE LA PORTADA ───────────────────────────────────────
   La misma fila sobre la foto: fondo translúcido y todo en blanco. Se conserva
   acotada a `.tf-portada` --que le gana en especificidad a la clara-- por si la
   fila vuelve a la cabecera; si se decide que no, este bloque se borra entero y
   no se lleva nada por delante. */
.tf-portada .tf-subcats{ margin-top: 12px; }

.tf-portada .tf-subcats .tf-subcat,
.tf-portada .tf-subcats .tf-subcat:visited{
    padding: 4px 10px 4px 4px;
    background: rgba(255,255,255,.10);
    border-color: rgba(255,255,255,.26);
    color: #fff;
    backdrop-filter: blur(2px);
    box-shadow: none;
}
.tf-portada .tf-subcats .tf-subcat-ico{
    width: 22px; height: 22px;
    background: rgba(255,255,255,.16);
    border-color: rgba(255,255,255,.3);
    color: #fff;
}
.tf-portada .tf-subcats .tf-subcat-ico iconify-icon{ font-size: 12px; }
.tf-portada .tf-subcats .tf-subcat .tf-subcat-n,
.tf-portada .tf-subcats .tf-subcat:visited .tf-subcat-n{ color: #fff; font-size: 11.5px; font-weight: 700; }
.tf-portada .tf-subcats .tf-subcat:hover,
.tf-portada .tf-subcats .tf-subcat:focus-visible{
    background: rgba(255,255,255,.22);
    border-color: rgba(255,255,255,.5);
    color: #fff;
    box-shadow: none;
}
.tf-portada .tf-subcats .tf-subcat:hover .tf-subcat-ico{ border-color: rgba(255,255,255,.55); }
/* El foco se ve SIEMPRE: son enlaces de navegación sobre una foto, y el
   contorno del navegador se pierde contra cualquier portada oscura (WCAG 2.1
   AA, foco visible). */
.tf-portada .tf-subcats .tf-subcat:focus-visible{ outline: 2px solid #fff; outline-offset: 2px; }

.tf-portada .tf-subcats .tf-subcat > b,
.tf-portada .tf-subcats .tf-subcat:visited > b{
    background: rgba(0,0,0,.28);
    color: rgba(255,255,255,.95);
    font-size: 10.5px; font-weight: 800;
}
.tf-portada .tf-subcats .tf-subcat:hover > b{ background: rgba(0,0,0,.28); color: rgba(255,255,255,.95); }

/* Cada una con su tono, que es lo que las distingue de un vistazo. */
.tf-pill.es-eco{ background: rgba(61,220,115,.22); border-color: rgba(61,220,115,.5); }
.tf-pill.es-directa{ background: rgba(90,170,255,.20); border-color: rgba(90,170,255,.45); }
.tf-pill.es-subasta{ background: rgba(190,140,255,.20); border-color: rgba(190,140,255,.45); }
.tf-pill.es-local{ background: rgba(240,180,41,.22); border-color: rgba(240,180,41,.5); }

/* ══ LA BARRA DE CIFRAS ════════════════════════════════════════════ */

/* Sin fondo ni borde: la franja blanca que había alrededor dejaba una banda
   partida por detrás de la barra. La tarjeta se basta sola. */
.tf-cifras-zona{ background: transparent; }

/* LA BARRA, EN SU TARJETA Y NO A SANGRE. Con 8px de radio se separa de la
   portada de arriba y de la rejilla de abajo: pegada al borde de la página se
   leía como una franja del fondo, no como el resumen de la búsqueda. */
.tf-cifras{
    display: flex;
    align-items: center;
    gap: 22px;
    flex-wrap: wrap;

    /* DEBAJO DE LA PORTADA, NO ENCIMA. Tenía `margin-top: -18px` para
       montarla sobre la foto, y lo que hacía era comerse el borde inferior de
       la portada y quedar medio dentro medio fuera: ni una cosa ni la otra.
       Separada, la portada termina donde termina y la barra empieza donde
       empieza. */
    margin: 16px 0 0;
    padding: 12px 18px;
    border: 1px solid var(--sd-borde);
    border-radius: 8px;
    background: #fff;
    box-shadow: 0 2px 10px rgba(16,50,24,.06);
}

.tf-cifras-datos{ display: flex; align-items: center; gap: 22px; flex: 1; min-width: 0; flex-wrap: wrap; }

/* El orden y la vista, al otro extremo de la misma barra. */
.tf-cifras-orden{ display: flex; align-items: center; gap: 10px; flex: 0 0 auto; }
.tf-cifras-orden > label{ font-size: 12px; color: var(--sd-suave); white-space: nowrap; }
.tf-cifras-orden .sd-campo{ padding: 6px 10px 5px; }

/* Cada cifra separada por una línea fina, como en el diseño: sin ella, tres
   números seguidos se leen como uno solo de nueve dígitos. */
.tf-cifras-datos > * + *{ padding-left: 22px; border-left: 1px solid var(--sd-borde); }

.tf-recuento{ display: flex; align-items: center; gap: 12px; padding: 4px 0 12px; }
.tf-recuento small{ margin-left: auto; font-size: 12px; color: var(--sd-suave); }

/* El título de la rejilla comparte línea con el «Mostrando 1-24 de…»: son la
   misma pregunta --qué hay y cuánto se está viendo-- y en dos líneas la
   pantalla gana un escalón para no decir nada nuevo. */
.tf-recuento-t{
    display: flex; align-items: center; gap: 8px;
    margin: 0; padding: 0;              /* la hoja del sitio le mete 10px a los h2 */
    font-size: 16.5px; font-weight: 800; letter-spacing: -.2px;
    color: var(--sd-tinta);
}
.tf-recuento-t iconify-icon{ font-size: 18px; color: var(--sd-verde); }
.tf-recuento-t b{ font-weight: 800; color: var(--sd-suave); }

.tf-cifra{ display: flex; flex-direction: column; }
.tf-cifra b{ font-size: 19px; font-weight: 800; color: var(--sd-tinta); font-variant-numeric: tabular-nums; }
.tf-cifra small{ font-size: 11.5px; color: var(--sd-suave); }

/* El resumen de la izquierda: icono en su columna y TODO el texto en la
   segunda, que es la regla de alineación del proyecto. */
.tf-resumen{ display: flex; align-items: flex-start; gap: 11px; flex: 1; min-width: 240px; }
.tf-resumen > span{
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 34px; height: 34px;
    border-radius: 10px;
    background: var(--sd-verde-claro);
    color: var(--sd-verde);
    font-size: 17px;
}
.tf-resumen small{ display: block; font-size: 12px; line-height: 1.5; color: var(--sd-texto); }

/* Las caras de los vendedores, montadas unas sobre otras. */
.tf-caras{ display: flex; align-items: center; }
.tf-caras img, .tf-caras span{
    width: 30px; height: 30px;
    border-radius: 50%;
    border: 2px solid #fff;
    margin-left: -9px;
    object-fit: cover;
    display: grid; place-items: center;
    background: var(--sd-verde-claro);
    color: var(--sd-verde);
    font-size: 10.5px; font-weight: 800;
}
.tf-caras > *:first-child{ margin-left: 0; }
.tf-caras .tf-mas-caras{ background: #eef1ef; color: var(--sd-suave); }

/* ══ LAS DOS COLUMNAS ══════════════════════════════════════════════ */

.tf-cuerpo{
    display: grid;
    grid-template-columns: 246px minmax(0, 1fr);
    gap: 22px;
    align-items: start;
    padding: 22px 0 8px;
}

/* ── LA COLUMNA DE CRITERIOS SE QUEDA A LA VISTA ────────────────────
 *
 * Con quince filtros y cuarenta resultados, tener que subir para cambiar uno es
 * lo que hace que no se cambien.
 *
 * ── Y SIN ALTURA NI BARRA PROPIA ───────────────────────────────────
 *
 * Tuvo `max-height: calc(100vh - 112px)` con `overflow-y: auto`, para que los
 * últimos grupos --Garantías, Disponibilidad-- se pudieran alcanzar con la
 * columna pegada. El precio era una segunda barra de desplazamiento dentro de
 * la página: se rueda la rueda sobre los filtros y se mueve el panel, se rueda
 * dos píxeles más allá y se mueve la página, y ninguna de las dos llega a donde
 * se iba. Un panel de filtros con su propio recorte además ESCONDE lo que hay
 * debajo sin decir que está ahí.
 *
 * Así que la columna se desplaza CON la página --`overflow: visible`, sin
 * tope-- y por eso deja de estar pegada: `sticky` con un contenido más alto que
 * la ventana clava el panel arriba y su parte de abajo ya no se puede
 * alcanzar de ninguna manera, que es peor que las dos barras.
 */
.tf-lado{
    position: static;
    max-height: none;
    overflow: visible;
}

.tf-lado-botones{ display: flex; flex-direction: column; gap: 8px; margin-top: 12px; }

/* El buscador dentro de la sección, con el mismo aire que `sd-buscasub` pero a
   lo ancho del panel. */
.tf-busca-lado{
    display: flex; align-items: center; gap: 7px;
    margin: 0 14px 4px;
    padding: 7px 10px;
    border: 1px solid var(--sd-borde);
    border-radius: 9px;
}
.tf-busca-lado iconify-icon{ font-size: 15px; color: var(--sd-tenue); flex: 0 0 auto; }
.tf-busca-lado input{
    flex: 1; min-width: 0;
    border: 0; outline: none;
    font-family: inherit; font-size: 12.5px;
}

.tf-col{ min-width: 0; }

/* ══ LA REJILLA ════════════════════════════════════════════════════ */

/* CUANTAS QUEPAN, CON EL ANCHO DE LA TARJETA COMO TOPE.
   Con `repeat(5, 1fr)` fijo, en una pantalla de 2560px salían cinco tarjetas de
   más de 400px: la ficha se estiraba porque le sobraba sitio. Ahora la columna
   nunca pasa de `--tf-card-max` --el tope que declara la propia tarjeta
   (`TAgroCard.css`), el mismo en el escaparate, en las colecciones y en el
   perfil del agricultor-- y se ponen las que quepan.

   OJO CON `auto-fit`: el tope de arriba se declaró pero el `1fr` de aquí lo
   dejaba sin efecto -- con una sola tarjeta en la fila, `auto-fit` COLAPSA
   las columnas vacías y la única que queda, al ser `1fr` (flexible), se come
   todo el ancho libre: la ficha se convertía en un banner (22/09/2026,
   comprobado en `/tienda` filtrando hasta dejar un producto). `auto-fill`
   NO colapsa esas columnas -- las deja vacías e invisibles, así que el
   sobrante va a ellas y no a la tarjeta -- y con `var(--tf-card-max)` como
   tope, ya no hace falta que sea `fr`: una columna de ancho fijo no se
   estira aunque sobre sitio. */
.tf-rejilla{
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--tf-card-min, 260px)), var(--tf-card-max, 350px)));
    gap: var(--tf-card-gap, 20px);
}

/* En lista, una fila por producto: la foto a la izquierda y el resto en línea.
   Es la misma tarjeta con otra dirección, no otra tarjeta. */
.tf-rejilla.es-lista{ grid-template-columns: minmax(0, 1fr); }

/* ══ UNA SECCIÓN DE LA COLUMNA ═════════════════════════════════════════
 *
 * «Productos destacados» y «Todos los productos»: un título que dice qué es la
 * lista que viene debajo. Sin ellos las dos listas iban pegadas y las primeras
 * tarjetas de la rejilla se leían como parte de lo destacado.
 *
 * CANDIDATO A LA HOJA COMÚN del área de cliente: la colección y el perfil del
 * agricultor titulan igual sus bloques.
 */
.tf-seccion{ margin: 0 0 20px; }

/* ICONO EN SU COLUMNA Y TODO EL TEXTO EN LA SEGUNDA, que es la regla de
   alineación de la casa: con el icono dentro del bloque de texto, el subtítulo
   arranca en una vertical distinta de la del título. */
.tf-seccion-cab{ display: flex; align-items: flex-start; gap: 10px; margin: 0 0 12px; }

/* LA ESTRELLA, GRANDE Y MACIZA. A 19px y de trazo se perdía contra el título;
   es lo que dice de un vistazo que esta sección no es la rejilla de abajo. */
.tf-seccion-ico{
    flex: 0 0 auto;
    display: grid; place-items: center;
    width: 30px; height: 30px;
    color: var(--sd-oro, #e2a812);
    font-size: 26px;
}
.tf-seccion-ico svg{ width: 26px; height: 26px; display: block; }
.tf-seccion-txt{ flex: 1; min-width: 0; }

.tf-seccion-txt h2{
    margin: 0; padding: 0;              /* la hoja del sitio le mete 10px a los h2 */
    font-size: 16.5px; font-weight: 800; letter-spacing: -.2px;
    color: var(--sd-tinta);
}
.tf-seccion-txt small{
    display: block; margin-top: 2px;
    font-size: 12.5px; line-height: 1.45;
    color: var(--sd-suave);
}

/* ══ LOS DESTACADOS, APAISADOS ═════════════════════════════════════════
 *
 * TRES POR FILA Y A LO ANCHO. En vertical se veían igual que los 262 de abajo,
 * y lo que se paga por un destacado es justo que se distinga. A lo ancho caben
 * la foto grande, las etiquetas de la mercancía y los datos de venta.
 */
.tf-destacados{
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(330px, 1fr));
    gap: 14px;
}

/* ── LA TARJETA APAISADA: LOS DESTACADOS Y LA VISTA DE LISTA ─────────
 *
 * UN SOLO BLOQUE PARA LOS DOS. La vista de lista tenía su propia definición con
 * `flex-direction: row`, y al sacar el pie fuera del cuerpo se convirtió en una
 * TERCERA COLUMNA: en un móvil, los botones se metían encima del nombre y del
 * precio --se veía el título cortado a «Agua Hass» y «Ver producto» tapando la
 * valoración--. Son la misma tarjeta con el mismo problema, así que ahora es la
 * misma regla: foto y ficha arriba, datos y acción en su fila de abajo.
 *
 * TRES COLUMNAS Y DOS FILAS, y no una fila de `flex`:
 *
 *     ┌──────────┬───────────────────────┬──────────┐
 *     │  foto    │  cuerpo (2 columnas)             │
 *     ├──────────┴───────────────┬───────┴──────────┤
 *     │  datos de venta          │   acción         │
 *     └──────────────────────────┴──────────────────┘
 *
 * El pie de la tarjeta comparte fila con los datos de venta --reloj, pujas,
 * kilos a la izquierda; el botón a la derecha-- y la línea que los separa del
 * resto cruza la tarjeta de lado a lado, por debajo de la foto también. Con
 * `flex-direction: row` los datos quedarían como una tercera columna y el botón
 * flotando a media altura del texto.
 */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card{
    display: grid;
    grid-template-columns: 162px minmax(0, 1fr) auto;
    grid-template-rows: auto auto;
    max-width: none;
}

/* LA FOTO, METIDA HACIA DENTRO Y REDONDA POR LAS CUATRO ESQUINAS. A sangre
   contra el borde se lee como el fondo de la tarjeta; con su margen y su radio
   se lee como lo que es: la foto del lote. */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-foto{
    grid-area: 1 / 1 / 2 / 2;
    width: auto; height: auto;
    margin: 12px 0 12px 12px;
    border-radius: 12px;
    align-self: stretch;
}

:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-cuerpo{
    grid-area: 1 / 2 / 2 / 4;
    padding: 12px 14px 12px;
}

/* LA ETIQUETA Y EL CORAZÓN SIGUEN A LA FOTO. Están posicionados contra la
   TARJETA, así que al meter la foto hacia dentro hay que moverlos con ella: si
   no, la etiqueta queda flotando sobre el borde y el corazón, fuera de la
   imagen. Y con tope de ancho, que un sello largo --«Sin tratamiento
   postcosecha»-- se salía de la columna de la foto y caía encima del título. */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-etiqueta{
    top: 20px; left: 20px;
    max-width: 130px;
    white-space: normal;
    line-height: 1.25;
    font-size: 10.5px;
    padding: 4px 9px;
}
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-fav{ top: 14px; right: 14px; }

/* ── LA FILA DE ABAJO: DATOS A LA IZQUIERDA, ACCIÓN A LA DERECHA ──────
 *
 * SIN LÍNEA QUE LA SEPARE. La llevó, y sobraba: la foto ya termina donde
 * empieza la fila y el cambio de contenido --de la ficha a las condiciones de
 * la venta-- se nota solo. Con el filete, la tarjeta se leía partida en dos
 * mitades y parecían dos bloques pegados en vez de uno.
 *
 * Y APRETADA: son una línea de texto pequeño y un botón, no un pie de página.
 */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-meta{
    grid-area: 2 / 1 / 3 / 3;
    display: flex;
    padding: 2px 6px 10px 14px;
    border-top: 0;
    background: transparent;
}
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card > .ag-pie{
    grid-area: 2 / 3 / 3 / 4;
    margin-top: 0;
    padding: 0 12px 8px 0;
    border-top: 0;
    background: transparent;
    justify-content: flex-end;
    align-items: flex-end;
}

/* Y las etiquetas del producto, que aquí sí caben. */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-tags{ display: flex; }

/* En la rejilla de LISTA las etiquetas se quedan fuera: ahí la fila es más
   estrecha --caben tres por pantalla-- y entre el nombre a dos líneas, el
   precio y los datos de venta ya no hay hueco. En destacados sí, que son tres
   tarjetas grandes y es donde se decide sin abrir. */
.tf-rejilla.es-lista .ag-card .ag-tags{ display: none; }

/* El nombre, a dos líneas: en una fila, un título de cuatro empuja el precio
   fuera de la tarjeta. Y con hueco para el corazón, que va en su esquina. */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-nombre{
    padding-right: 30px;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-precios{ margin-bottom: 0; margin-top: 6px; }

/* ── LOS DOS BOTONES ──────────────────────────────────────────────────
 *
 * COMPRA DIRECTA: «Ver producto» y el carrito, que es el atajo.
 * SUBASTA: un solo botón verde, «Ver detalle», porque una subasta no se añade
 * al carrito -- se entra a pujar, y ofrecer las dos cosas es ofrecer una que no
 * existe.
 */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-pie .ag-btn{
    flex: 0 0 auto; width: 38px; height: 38px;
    padding: 0; border-radius: 10px;
    order: 2;
}
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-btn-txt{ display: none; }
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-ver{ display: inline-flex; white-space: nowrap; }

:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card.es-subasta .ag-pie .ag-btn{ display: none; }
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card.es-subasta .ag-ver{
    background: var(--sd-verde);
    border-color: var(--sd-verde);
    color: #fff;
    font-weight: 700;
    padding: 10px 16px;
}
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card.es-subasta .ag-ver:hover{
    background: var(--sd-verde-oscuro, #005c2d);
    border-color: var(--sd-verde-oscuro, #005c2d);
}
/* La flecha, en CSS: es adorno del botón --dice «vas a otro sitio»-- y no texto
   que deba leer nadie en voz alta. */
:is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card.es-subasta .ag-ver::after{
    content: '→';
    margin-left: 8px;
    font-size: 14px;
    line-height: 1;
}

.tf-mas{ display: flex; justify-content: center; padding: 22px 0 4px; }

/* ══ LAS GARANTÍAS ═════════════════════════════════════════════════
 *
 * Se fueron con su marcado (30/08/2026): las cuatro promesas son del SITIO y
 * las pinta `base.php` encima del pie para todas las páginas, con su hoja en
 * `TPlataforma/css/TGarantias.css`. Aquí eran una copia con otras palabras y
 * otro aspecto, y desde que la franja global sale en la tienda, dos franjas
 * casi iguales seguidas.
 */

/* ══ PANTALLA ESTRECHA ═════════════════════════════════════════════ */

/* LOS CORTES DE 1180 Y 980 SE HAN IDO: contaban columnas a mano --cuatro, tres--
   y con la rejilla en `auto-fill` eso ya lo hace el ancho disponible. Dejarlos
   solo servía para forzar columnas más anchas que la tarjeta y dejar un hueco
   en blanco dentro de cada celda. */
@media (max-width: 980px){
    .tf-destacados{ grid-template-columns: minmax(0, 1fr); }
}

/* ══════════════════════════════════════════════════════════════════
 *  LAS PIEZAS DE MÓVIL: EN ESCRITORIO NO EXISTEN
 * ══════════════════════════════════════════════════════════════════
 *
 * Nacen apagadas y las enciende el `@media` de abajo. Escrito así --y no al
 * revés-- porque escritorio es lo que ya estaba probado: una pieza nueva que
 * naciera visible rompería la pantalla de trabajo mientras se construye la del
 * teléfono.
 */
.tf-chips-barra,
.tf-hoja-cab,
.tf-hoja-pie,
.tf-velo,
.tf-portada-cifras{ display: none; }

/* EL BOTÓN, ACOTADO CON `.tf` Y NO SUELTO, y no es manía de escribir: la hoja
   del marco le pone `display:flex; height:25px` a TODO `button` dentro de un
   `.TComponentES6`, y esa regla pesa 0,1,1 -- le gana a `.tf-btn-filtros`, que
   pesa 0,1,0. Escrito suelto, el botón salía en ESCRITORIO, donde no pinta
   nada, y medía 25 px de alto en el teléfono. */
.tf .tf-btn-filtros{ display: none; }

/* Texto que solo lee el lector de pantalla: el número de filtros del botón va
   también en palabras, porque «2» dentro de una píldora no se dice solo. */
.tf-solo-lector{
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* ── EL BOTÓN «FILTROS (N)» ────────────────────────────────────────── */
.tf .tf-btn-filtros{
    flex: 0 0 auto;
    align-items: center; gap: 7px;
    height: auto; min-height: 44px;        /* el global `button{height:25px}` */
    margin: 0; padding: 0 14px;
    border: 1px solid var(--sd-verde);
    border-radius: 10px;
    background: var(--sd-verde);
    color: #fff;
    font-family: inherit; font-size: 13.5px; font-weight: 700;
    cursor: pointer;
}
.tf .tf-btn-filtros:hover{ background: var(--sd-verde-oscuro); }
.tf .tf-btn-filtros iconify-icon{ font-size: 17px; }

/* El contador nace vacío y solo ocupa sitio cuando hay algo que contar. */
.tf-btn-filtros-n{ display: none; }
.tf .tf-btn-filtros.es-con-filtros .tf-btn-filtros-n{
    display: inline-grid; place-items: center;
    min-width: 20px; height: 20px; padding: 0 5px;
    border-radius: 999px;
    background: #fff;
    color: var(--sd-verde);
    font-size: 11.5px; font-weight: 800;
}

/* ── LA CABECERA DE LA HOJA ────────────────────────────────────────
   Icono en su columna y TODO el texto en la segunda, para que el título y el
   subtítulo arranquen en la misma vertical. Es la regla de alineación del
   proyecto, y es lo que separa una cabecera de una fila de trozos. */
.tf-hoja-cab{
    align-items: flex-start;
    gap: 10px;
    flex: 0 0 auto;
    padding: 12px 16px;
    border-bottom: 1px solid var(--sd-borde);
}
.tf-hoja-cab > iconify-icon{ flex: 0 0 auto; font-size: 20px; color: var(--sd-verde); margin-top: 2px; }
.tf-hoja-cab-txt{ flex: 1; min-width: 0; }
.tf-hoja-cab-txt b{ display: block; font-size: 16px; font-weight: 800; color: var(--sd-tinta); }
.tf-hoja-cab-txt small{ display: block; margin-top: 2px; font-size: 12px; color: var(--sd-suave); }

.tf .tf-hoja-x{
    flex: 0 0 auto;
    width: 44px; height: 44px;
    margin: -8px -8px 0 0; padding: 0;
    border: 0; border-radius: 10px;
    background: none;
    color: var(--sd-suave);
    cursor: pointer;
}
.tf .tf-hoja-x:hover{ background: var(--sd-crema); color: var(--sd-tinta); }
.tf .tf-hoja-x iconify-icon{ font-size: 20px; }

/* ── EL PIE DE LA HOJA ─────────────────────────────────────────────
   `btn-secondary` el que descarta y `btn-primary` el que decide: sin clase,
   «Limpiar» pesaría lo mismo que el botón que enseña los resultados. */
.tf-hoja-pie{
    flex: 0 0 auto;
    gap: 10px;
    padding: 12px 16px;
    padding-bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    border-top: 1px solid var(--sd-borde);
    background: #fff;
}
.tf .tf-hoja-pie .sd-btn{ height: 48px; }
.tf .tf-hoja-limpiar{ flex: 0 0 auto; }
.tf .tf-hoja-ver{ flex: 1; min-width: 0; }

/* La línea de cifras de la portada compacta. */
.tf-portada-cifras{
    margin: 0;
    font-size: 12.5px; line-height: 1.45;
    color: rgba(255,255,255,.92);
}

/* EL FOCO, VISIBLE EN TODO LO QUE SE PULSA. Sin esto, la hoja se puede
   recorrer con el tabulador y no se ve dónde está uno -- que es exactamente lo
   que el requisito de foco visible viene a impedir (WCAG 2.4.7). */
.tf .tf-btn-filtros:focus-visible,
.tf .tf-hoja-x:focus-visible,
.tf .tf-chips-limpiar:focus-visible,
.tf .tf-hoja-pie .sd-btn:focus-visible,
.tf-chip button:focus-visible{
    outline: 3px solid #2563eb;
    outline-offset: 2px;
}

/* ══════════════════════════════════════════════════════════════════
 *  POR DEBAJO DE 860 px: LA MISMA PANTALLA, OTRA PRESENTACIÓN
 * ══════════════════════════════════════════════════════════════════
 *
 * Aquí estaba escrito «SIN CAJÓN NI BOTÓN DE ABRIR»: la columna se apilaba
 * entera encima de la rejilla. El razonamiento valía --un botón para abrir lo
 * que ya está a la vista no hace nada-- pero MEDIDO en un teléfono no se
 * sostenía: los nueve grupos abiertos ocupan 1.277 px, y la primera tarjeta
 * empezaba a 2.093, o sea a dos pantallas y media de casillas. Un catálogo en
 * el que hay que bajar dos pantallas para ver un producto no es un catálogo.
 *
 * Así que por debajo de 860 px --y SOLO por debajo-- la columna se esconde
 * detrás de un botón y se presenta como hoja (teléfono) o como panel lateral
 * (tableta). Por encima no cambia nada: la columna de siempre a la izquierda.
 *
 * ── UN SOLO PANEL, NO UNA COPIA ─────────────────────────────────────
 *
 * La hoja ES `#tfLado`, el mismo marcado con los mismos grupos y los mismos
 * recuentos. Con dos copias, los números se separan el primer día.
 *
 * Contrato y medidas: PendingWorks/TIENDA-MOVIL.md.
 */
@media (max-width: 860px){

    .tf-cuerpo{ grid-template-columns: minmax(0, 1fr); padding-top: 4px; }
    .tf-portada h1{ font-size: 24px; letter-spacing: -.5px; }

    /* EL CARRIL, SOLO EL DEL SITIO. `sd-ancho` suma sus 20 px a los 16 de
       `body-content`: 72 px de márgenes en una pantalla de 400 para que la
       rejilla se quede en 328. Los 16 del sitio ya son el gutter. */
    .tf .sd-ancho{ padding: 0; }

    /* ── LA PORTADA, SIN FOTO ────────────────────────────────────────
       La foto de la categoría es una franja de 5:1 pensada para un monitor: a
       400 px se recorta a una banda de la que no se entiende nada y cuesta
       260 px de la primera pantalla, que es justo lo que hay que devolverle a
       los productos. Queda el nombre de la sección y una línea de cifras. */
    .tf-portada{
        min-height: 0;
        padding: 18px 16px 18px;
        margin-top: 12px;
    }
    .tf-portada-foto{ display: none; }

    /* El velo deja de ser velo --no hay foto debajo-- y pasa a ser el fondo. */
    .tf-portada-velo{
        background: linear-gradient(135deg, #2f4d2a 0%, #4d7040 100%);
    }

    .tf-portada-desc,
    .tf-pills{ display: none; }

    /* LAS FAMILIAS, RECORTADAS A DOS FILAS Y CON SU BOTÓN.
     *
     * Estuvieron en una sola línea con arrastre lateral, y el arrastre ESCONDE:
     * en un móvil se veían DOS de doce y nada decía que hubiera más -- quien no
     * prueba a arrastrar, no las encuentra. Dos filas enseñan cuatro o cinco, y
     * el botón de debajo dice exactamente cuántas quedan.
     *
     * El tope son DOS FILAS de píldora (42px) más el hueco entre ellas (8px).
     * Con `max-height` y no escondiendo las que sobran, porque CUÁLES sobran
     * depende del ancho y eso no se sabe hasta que el navegador lo reparte. */
    .tf-subcats{
        max-height: 92px;
        overflow: hidden;
    }
    .tf-subcats.es-abierta{ max-height: none; }

    .tf-subcats-zona{ padding: 12px 14px 14px; margin-bottom: 14px; }

    .tf-portada-cifras{ display: block; }

    /* ── LA BARRA PEGAJOSA ───────────────────────────────────────────
       Es la MISMA barra de cifras: se esconden las cifras y quedan el botón de
       filtros, el orden y la vista. El orden va aparte de los filtros a
       propósito: es lo que más se toca y no puede costar abrir una hoja.

       `--tf-barra-top` lo pone el JS con el alto REAL de la cabecera del
       sitio, que es pegajosa y se recoge al bajar (108 px abierta, 56
       recogida). Un número escrito aquí dejaría la barra medio tapada en una
       de las dos posturas. */
    .tf-cifras-zona{
        position: sticky;
        top: var(--tf-barra-top, 56px);
        /* CON 15 NO BASTABA: las tarjetas de la rejilla --con su propio
           `position: relative` para la etiqueta y el corazón, ver
           `TAgroCard.css`-- ganaban por debajo y se veían POR ENCIMA de esta
           barra pegajosa en cuanto se hacía scroll. Por debajo de la hoja de
           filtros (1100+) y del chat de soporte (9000), que sí tienen que
           tapar todo lo demás. */
        z-index: 100;
        margin: 0 -16px;
        padding: 8px 16px;
        background: transparent;
        transition: background .15s, box-shadow .15s;
    }

    /* Pegada: fondo y sombra. Suelta: nada, para no dibujar una franja sobre
       la portada. La clase la pone el JS. */
    .tf-cifras-zona.es-pegada{
        background: #fff;
        box-shadow: 0 4px 12px rgba(16,50,24,.10);
    }

    .tf-cifras{
        margin: 0;
        padding: 0;
        border: 0;
        border-radius: 0;
        background: transparent;
        box-shadow: none;
        gap: 8px;
        flex-wrap: nowrap;
    }

    .tf-cifras-datos{ display: none; }

    .tf-cifras-orden{ flex: 1; min-width: 0; gap: 8px; }
    .tf-cifras-orden > label{ display: none; }   /* el `aria-label` ya lo nombra */
    .tf-cifras-orden .sd-campo{ flex: 1; min-width: 0; padding: 0; }

    .tf-cifras-orden .sd-campo select{
        width: 100%;
        min-height: 44px;
        padding: 0 10px;
        border: 1px solid var(--sd-borde);
        border-radius: 10px;
        background: #fff;
        font-family: inherit; font-size: 13px; font-weight: 600;
        color: var(--sd-tinta);
    }

    .tf .sd-vista{ flex: 0 0 auto; }
    .tf .sd-vista button{ width: 42px; height: 42px; }

    /* ── EL BOTÓN DE FILTROS ─────────────────────────────────────── */
    .tf .tf-btn-filtros{ display: inline-flex; }

    /* ── LOS CHIPS, FUERA DEL PANEL ──────────────────────────────────
       En una fila con desplazamiento PROPIO: con `flex-wrap`, ocho filtros
       puestos son tres filas que empujan la rejilla fuera de la pantalla otra
       vez, que es el problema que se venía a arreglar. */
    .tf-chips-barra{
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 8px 0 2px;
    }
    .tf-chips-barra.es-vacia{ display: none; }

    .tf-chips-lista{
        flex: 1; min-width: 0;
        display: flex; gap: 7px;
        overflow-x: auto;
        scrollbar-width: none;
        padding-bottom: 2px;
    }
    .tf-chips-lista::-webkit-scrollbar{ display: none; }
    .tf-chips-lista .tf-chip{ flex: 0 0 auto; }

    .tf .tf-chips-limpiar{
        flex: 0 0 auto;
        height: auto; min-height: 32px;
        margin: 0; padding: 0 6px;
        border: 0; background: none;
        color: var(--sd-verde);
        font-family: inherit; font-size: 12px; font-weight: 700;
        cursor: pointer;
    }

    .tf-recuento{ padding: 6px 0 10px; }
    .tf-recuento small{ margin-left: 0; }

    /* ══ LA HOJA DE FILTROS ══════════════════════════════════════════
       Cerrada, la columna no existe: no ocupa sitio ni recibe el tabulador. */
    .tf-lado{ display: none; }

    /* LA CABECERA DEL PANEL DE ESCRITORIO SE CALLA: su título y su «Limpiar»
       los dice ahora la cabecera de la hoja, y dos títulos seguidos --uno sin
       información-- es el error que más se repite. Lo mismo con los chips de
       dentro (están arriba, en la barra) y con el botón de limpiar del final
       (está en el pie). */
    .tf-lado .sd-panel-cab,
    .tf-lado .tf-chips,
    .tf-lado .tf-limpiar-zona{ display: none; }

    /* ── ABIERTA ────────────────────────────────────────────────────
     *
     * LO `fixed` NO SALE DE SU CONTEXTO DE APILADO, Y AQUÍ HAY DOS.
     *
     * La hoja y su velo son `position: fixed`, pero viven dentro de
     * `.body-content` (`position:relative; z-index:1`) y este dentro de
     * `<main>` (`position:relative; z-index:3`): las dos cajas crean contexto,
     * así que TODO lo de dentro se compara con la cabecera del sitio
     * --`z-index: 1000` colgando del `body`-- usando el 3 del `main`, no el
     * número que lleve la hoja. Medido el 16/09/2026: el velo tapaba la página
     * pero la cabecera se pintaba por encima y se podía seguir pulsando.
     *
     * Por eso se sube el ANTEPASADO, y solo mientras la hoja está abierta.
     * Subir el z-index de la hoja no habría servido de nada -- y es lo que
     * parece que falta cuando se mira solo el elemento.
     */
    html.tf-filtros-abiertos body > main{ z-index: 1100; }
    html.tf-filtros-abiertos .body-content{ z-index: 1100; }

    html.tf-filtros-abiertos,
    html.tf-filtros-abiertos body{ overflow: hidden; }

    /* El globo del chat de soporte vive en z-index 9000 y cae justo encima del
       pie de la hoja: tapa «Ver N productos», que es el botón que cierra. */
    html.tf-filtros-abiertos #sopChat{ visibility: hidden; }

    .tf-velo{ display: none; }

    html.tf-filtros-abiertos .tf-velo{
        display: block;
        position: fixed;
        top: 0; right: 0; bottom: 0; left: 0;
        z-index: 1190;
        background: rgba(15,23,20,.38);
    }

    html.tf-filtros-abiertos .tf-lado{
        display: flex;
        flex-direction: column;
        position: fixed;
        z-index: 1200;
        left: 0; right: 0; bottom: 0;
        height: 86vh;
        max-height: 86vh;
        background: #fff;
        border-radius: 18px 18px 0 0;
        box-shadow: 0 -10px 30px rgba(0,0,0,.18);
    }

    @media (prefers-reduced-motion: no-preference){
        html.tf-filtros-abiertos .tf-lado{ animation: tf-hoja-sube .2s ease-out; }
    }

    /* El panel se queda sin caja y pasa a ser el CUERPO con desplazamiento
       propio. `overscroll-behavior: contain` para que al llegar al final no se
       arrastre la página de debajo. */
    html.tf-filtros-abiertos .tf-lado .sd-panel{
        flex: 1;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;
        -webkit-overflow-scrolling: touch;
        border: 0;
        border-radius: 0;
        box-shadow: none;
    }

    html.tf-filtros-abiertos .tf-hoja-cab{ display: flex; }
    html.tf-filtros-abiertos .tf-hoja-pie{ display: flex; }

    /* Los controles del panel, a dedo: 44 px es lo que se acierta sin mirar. */
    .tf-lado .sd-grupo-cab{ min-height: 48px; }
    .tf-lado .sd-check{ min-height: 40px; }
    .tf .tf-busca-lado{ margin: 12px 14px 4px; padding: 10px 12px; }
    .tf .tf-busca-lado input{ font-size: 16px; }   /* 16: Safari no amplía */
}

/* ── LA TABLETA EN VERTICAL: PANEL LATERAL, NO HOJA ──────────────────
 *
 * De 601 a 860 px la rejilla sigue a la vista a la derecha del panel, así que
 * se ve cambiar mientras se filtra -- y por eso aquí los criterios se aplican
 * al momento (lo decide el JS por este mismo ancho). En un teléfono no cabe
 * esa conversación: la hoja tapa la pantalla entera. */
@media (min-width: 601px) and (max-width: 860px){

    /* EL VELO, MÁS FLOJO QUE EN EL TELÉFONO. Aquí la rejilla se ve a la
       derecha y cambia mientras se filtra: con el 38 % del teléfono se lee
       como una pantalla apagada y deja de contar lo que está contando. */
    html.tf-filtros-abiertos .tf-velo{ background: rgba(15,23,20,.20); }

    html.tf-filtros-abiertos .tf-lado{
        top: 0; bottom: 0; right: auto;
        width: 380px; max-width: 86vw;
        height: auto; max-height: none;
        border-radius: 0 18px 18px 0;
        box-shadow: 10px 0 30px rgba(0,0,0,.18);
    }

    @media (prefers-reduced-motion: no-preference){
        html.tf-filtros-abiertos .tf-lado{ animation-name: tf-hoja-entra; }
    }
}

@keyframes tf-hoja-sube{ from{ transform: translateY(24px); opacity: .6; } }
@keyframes tf-hoja-entra{ from{ transform: translateX(-24px); opacity: .6; } }

/* ── A 400 px, DOS COLUMNAS ──────────────────────────────────────────
 *
 * Una columna con la tarjeta grande deja UN producto por pantalla, y comparar
 * es la mitad de lo que se hace en un catálogo. Con dos caben cuatro sin bajar.
 * El mínimo de la rejilla se baja AQUÍ y no en `:root`: el tope de 260 px es el
 * bueno en cuanto hay sitio. */
@media (max-width: 560px){

    .tf-rejilla{
        --tf-card-min: 150px;
        --tf-card-gap: 10px;
    }

    /* LA TARJETA, COMPACTA. Es la misma `TAgroCard`, apretada: en 179 px de
       ancho el nombre a 15 px se parte en cuatro líneas y el botón a todo lo
       ancho se come la ficha. No se cambia de formato --seguiría siendo otro
       marcado que mantener-- sino la talla de lo que ya hay. */
    .tf-rejilla .ag-card .ag-foto{ height: 104px; }
    .tf-rejilla .ag-card .ag-cuerpo{ padding: 9px 10px 10px; }
    .tf-rejilla .ag-card .ag-nombre{ font-size: 13px; }
    .tf-rejilla .ag-card .ag-vendedor{ font-size: 11.5px; }

    /* EL LUGAR SE VA, no el vendedor: en una tarjeta de dos por fila lo que
       decide es qué es y de quién, y la provincia ya está en los filtros. */
    .tf-rejilla .ag-card .ag-lugar{ display: none; }

    .tf-rejilla .ag-card .ag-nota{ margin-top: 4px; }
    .tf-rejilla .ag-card .ag-precios{ margin-top: 6px; gap: 5px; }
    .tf-rejilla .ag-card .ag-precio{ font-size: 15px; font-weight: 800; }
    .tf-rejilla .ag-card .ag-antes{ font-size: 11.5px; }
    .tf-rejilla .ag-card .ag-iva,
    .tf-rejilla .ag-card .ag-ud{ font-size: 10px; }
    .tf-rejilla .ag-card .ag-dto{ padding: 1px 6px; font-size: 10.5px; }

    .tf-rejilla .ag-card .ag-pie{ margin-top: 8px; }
    .tf-rejilla .ag-card .ag-pie .ag-btn{ padding: 9px 8px; font-size: 12px; gap: 5px; }
    .tf-rejilla .ag-card .ag-pie .ag-btn iconify-icon{ font-size: 14px; }

    /* En lista, una sola columna: a 400 px no caben dos filas de 320. */
    .tf-rejilla.es-lista{ grid-template-columns: minmax(0, 1fr); }
    /* LA TARJETA APAISADA, MÁS ESTRECHA. Con la columna de foto de 162px en un
       móvil de 373px, al nombre le quedan 190: cabe «Aguacate Hass ·» y poco
       más. A 112 la foto sigue diciendo qué es y el título respira. */
    :is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card{
        grid-template-columns: 112px minmax(0, 1fr) auto;
    }
    :is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-foto{
        margin: 10px 0 10px 10px;
    }
    :is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-cuerpo{
        padding: 10px 12px 10px;
    }
    :is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-etiqueta{
        top: 16px; left: 16px;
        max-width: 92px;
    }
    :is(.tf-destacados.es-apaisada, .tf-rejilla.es-lista) .ag-card .ag-meta{
        padding-left: 12px;
    }
}


/* ══ LOS FILTROS PUESTOS, DEBAJO DEL TÍTULO ════════════════════════
 *
 * En tonos suaves y no en el verde de marca: son un ESTADO, no una acción, y
 * compitiendo en color con el botón de limpiar y con las casillas marcadas la
 * columna se convierte en un semáforo. Lo que tiene que destacar de un chip es
 * su X, que es lo único que se pulsa.
 */
/* LA ZONA RESPIRA, y no es cosmética: aquí se apilan hasta ocho chips en dos o
   tres filas, y con `2px` abajo la última quedaba pegada al botón de limpiar --
   dos bloques distintos leyéndose como uno. Va separada por arriba de la
   cabecera y por abajo del botón, que es lo que la convierte en «lo que llevas
   puesto» en vez de en un renglón más. */
.tf-chips{
    display: flex; flex-wrap: wrap; gap: 7px;
    padding: 12px 14px;
    border-top: 1px solid var(--sd-borde);
}

.tf-chip{
    display: inline-flex; align-items: center; gap: 5px;
    padding: 3px 5px 3px 10px;
    border-radius: 999px;
    background: #f1f4f1;
    border: 1px solid #e2e8e2;
    color: var(--sd-texto);
    font-size: 11px; font-weight: 600;
    max-width: 100%;
}

.tf-chip button{
    flex: 0 0 auto;
    width: 15px; height: 15px;
    display: grid; place-items: center;
    border: 0; border-radius: 50%;
    background: rgba(0,0,0,.07);
    color: var(--sd-suave);
    font-size: 11px; line-height: 1;
    font-family: inherit;
    padding: 0; cursor: pointer;
}
.tf-chip button:hover{ background: #e11d48; color: #fff; }

/* ══ LA VISTA DE LISTA: 350 × 128 ══════════════════════════════════
 *
 * Talla fija a propósito. En lista lo que se compara son filas, y con la altura
 * libre cada tarjeta mide lo que mida su nombre: dos líneas aquí, cuatro allá,
 * y la vista deja de ser una lista para ser una escalera.
 *
 * Las tarjetas se reparten en tantas columnas como quepan de 350px, en vez de
 * ocupar el ancho entero: una fila de 1.300px con una foto de 128 y el resto
 * vacío no es una lista, es un desperdicio.
 */
/* `auto-fit` EN LA COLUMNA, TOPE EN LA TARJETA.
   Con `auto-fill` y `max-width: 350px`, la rejilla reservaba columnas de un
   ancho que la tarjeta no llegaba a ocupar: en 1.300px cabían tres de 350 y
   sobraban 250 repartidos como huecos entre ellas -- las fichas se veían
   sueltas y separadas, que es lo que se notaba. Con `auto-fit` las columnas se
   reparten el ancho que hay y la tarjeta lo llena; el mínimo evita que en
   pantalla ancha salgan seis columnas de nada.

   Y ESO DEJABA UN SEGUNDO FALLO (22/09/2026): sin `max-width` en la tarjeta,
   un resultado SUELTO -- un filtro que deja uno solo -- se comía la pista
   entera, que con una sola tarjeta visible es toda la fila: la ficha salía a
   más de 1.000px, un cartel y no una fila de lista. El tope vuelve, pero en
   `.ag-card` (ver más abajo) y no en la columna: así con varias tarjetas
   siguen repartiéndose el ancho sin huecos, y con una sola no pasa de su
   tamaño razonable. */
.tf-rejilla.es-lista{
    /* 360 Y NO 320: la fila apaisada --foto de 128px, nombre, precio y los dos
       botones-- necesita ese ancho para que el título no se apriete. A 320, con
       la caja ya a todo el ancho de la cabecera, salían 4 columnas de 341px y el
       título se metía bajo el corazón. */
    grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
    gap: 12px;
}

/* La vista de lista usa LA MISMA tarjeta apaisada que los destacados: su
   bloque está más arriba, con el selector compartido. Aquí solo queda cuántas
   caben por fila. */

/* ══ EL DESLIZADOR DE PRECIO ═══════════════════════════════════════
 *
 * Dos `input[range]` sobre el mismo carril. No hay control nativo de rango con
 * dos asas, y esta es la forma de tener las dos sin traerse una librería: el
 * navegador pone el arrastre, el teclado y la accesibilidad.
 */
.tf-rango{ padding-top: 2px; }

.tf-rango-cajas{ display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tf-rango-cajas label{ display: block; }
.tf-rango-cajas small{ display: block; font-size: 11px; color: var(--sd-suave); margin-bottom: 3px; }
.tf-rango-cajas input{
    width: 100%;
    padding: 6px 9px;
    border: 1px solid var(--sd-borde);
    border-radius: 8px;
    font-family: inherit; font-size: 12.5px;
    font-variant-numeric: tabular-nums;
}

.tf-rango-barra{ position: relative; height: 22px; margin-top: 12px; }

.tf-rango-pista{
    position: absolute; left: 0; right: 0; top: 9px;
    height: 4px; border-radius: 99px;
    background: #e2e8e2;
}
.tf-rango-activo{
    position: absolute; top: 9px;
    height: 4px; border-radius: 99px;
    background: var(--sd-verde);
}

/* LAS DOS ASAS, TRANSPARENTES SALVO EL PULGAR.
   `pointer-events: none` en la pista y `auto` solo en el pulgar: si el carril
   entero recibiera el ratón, el de arriba taparía al de abajo y una de las dos
   asas no se podría coger nunca -- que es el fallo clásico de este montaje. */
.tf-rango-asa{
    position: absolute; left: 0; right: 0; top: 0;
    width: 100%; height: 22px; margin: 0;
    background: none; border: 0;
    -webkit-appearance: none; appearance: none;
    pointer-events: none;
}
.tf-rango-asa:focus{ outline: none; }

.tf-rango-asa::-webkit-slider-thumb{
    -webkit-appearance: none; appearance: none;
    pointer-events: auto;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: #fff;
    border: 3px solid var(--sd-verde);
    cursor: grab;
    box-shadow: 0 1px 4px rgba(16,50,24,.25);
}
.tf-rango-asa::-moz-range-thumb{
    pointer-events: auto;
    width: 15px; height: 15px;
    border-radius: 50%;
    background: #fff;
    border: 3px solid var(--sd-verde);
    cursor: grab;
}
.tf-rango-asa::-webkit-slider-runnable-track{ background: transparent; }
.tf-rango-asa::-moz-range-track{ background: transparent; }

/* ══ LA VALORACIÓN ═════════════════════════════════════════════════ */

/* UNA ESTRELLA, BIEN VISIBLE, y el resto escrito. Eran cinco de 13px en dos
   grises que había que contar para saber si ponía «4 y más» o «3 y más». */
.tf-estrella-filtro{
    color: var(--sd-oro);
    font-size: 15px;
    line-height: 1;
    margin-right: 6px;
}
.sd-check-txt{ display: inline-flex; align-items: center; }
.tf-valoracion em{ font-style: normal; font-size: 11.5px; color: var(--sd-suave); margin-left: 4px; }

/* ══ LOS INTERRUPTORES DE GARANTÍA ═════════════════════════════════
 *
 * Reutilizan `.sd-switch` del buscador de agricultores --misma forma, mismo
 * tamaño de palanca-- y aquí van UNO DEBAJO DE OTRO: la columna mide 246px y en
 * dos por fila, que es como están allí, no cabría ni el rótulo.
 *
 * La casilla de verdad se esconde pero SIGUE EXISTIENDO: es la que lleva el
 * estado, la que recibe el foco del teclado y la que dispara el manejador común
 * de los filtros. Con `display: none` se sale del orden de tabulación y el
 * interruptor deja de poder encenderse sin ratón.
 */
.tf-switches{ grid-template-columns: 1fr; gap: 10px; margin: 4px 0 2px; padding: 0 14px 14px; }

.tf-switch-input{
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}
/* El foco del teclado se ve en la fila entera, que es lo que se está tocando. */
.tf-switch-input:focus-visible + iconify-icon,
.tf-switch-input:focus-visible ~ .sd-palanca{ outline: 2px solid var(--sd-verde); outline-offset: 2px; }

.tf-switches .sd-switch{ padding: 9px 12px; gap: 9px; }
.tf-switches .sd-switch.on{ border-color: var(--sd-verde-borde, #cfe3d2); background: var(--sd-verde-claro, #eef6ee); }
.tf-switches .sd-switch-txt b{ font-size: 12.5px; font-weight: 700; }
.tf-switches .sd-palanca{ width: 40px; height: 22px; }
.tf-switches .sd-palanca::after{ width: 16px; height: 16px; }
.tf-switches .sd-switch.on .sd-palanca::after{ left: 21px; }

/* ══ LA PROVINCIA ══════════════════════════════════════════════════ */

.tf-select{
    width: 100%;
    padding: 7px 9px;
    border: 1px solid var(--sd-borde);
    border-radius: 8px;
    background: #fff;
    font-family: inherit; font-size: 12.5px;
    color: var(--sd-texto);
    cursor: pointer;
}

/* El botón, separado de los chips que hay encima: pegado a ellos parecía el
   último de la lista en vez de la acción que se los lleva por delante. */
.tf-limpiar-zona{ padding: 0 14px 12px; }


/* ══════════════════════════════════════════════════════════════════
 *  PASADA TIPOGRÁFICA CONTRA LA PLANTILLA
 * ══════════════════════════════════════════════════════════════════
 *
 * Medido en el navegador y comparado con el diseño. La familia ya coincidía
 * --Inter en toda la página, que es la del sitio-- pero los TAMAÑOS estaban
 * todos un punto o dos por debajo: se escribieron mirando la retícula, no la
 * maqueta, y el resultado es una pantalla que se lee «apretada» sin que se sepa
 * por qué.
 *
 * Los que más se notan son los dos que el ojo usa para recorrer la rejilla: el
 * nombre del producto y el precio. Si esos dos están pequeños, la tarjeta
 * parece una fila de tabla.
 */

/* ── LA COLUMNA DE CRITERIOS ────────────────────────────────────── */

/* El título de cada grupo, un punto por encima de sus opciones: es lo que
   permite recorrer la columna sin leerla entera. */
.tf .sd-grupo-cab b{ font-size: 13px; font-weight: 700; }
.tf .sd-check-txt{ font-size: 12.5px; }
.tf .sd-check small{ font-size: 11px; color: var(--sd-tenue); }
.tf .sd-panel-cab b{ font-size: 14px; }

/* ── LA BARRA DE CIFRAS ─────────────────────────────────────────── */

.tf-cifra b{ font-size: 21px; letter-spacing: -.5px; }
.tf-cifra small{ font-size: 11.5px; }
.tf-resumen small{ font-size: 12.5px; }
.tf-cifras-orden > label{ font-size: 12.5px; }
.tf-cifras-orden .sd-campo select{ font-size: 13px; }

/* ── LA PORTADA ─────────────────────────────────────────────────── */

/* 34px estaba bien para «Todo el catálogo»; con un nombre de categoría corto
   --«Aguacates»-- la plantilla lo lleva más grande. Se deja crecer con el
   ancho en vez de fijarlo: `clamp` da el mínimo del móvil, el ideal y el tope. */
.tf-portada h1{ font-size: clamp(26px, 3.2vw, 40px); letter-spacing: -1.2px; }
.tf-portada-desc{ font-size: 14px; }
.tf-pill{ font-size: 12px; }


/* ══ CERCA DE MÍ ═══════════════════════════════════════════════════
   Cuatro radios en dos filas: en una sola, «200 km» se queda en 50px y el
   número no se lee. */
.tf-cerca{ display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }

.tf-km{
    height: auto;                       /* el global `button{height:25px}` */
    padding: 7px 6px;
    border: 1px solid var(--sd-borde);
    border-radius: 8px;
    background: #fff;
    color: var(--sd-texto);
    font-family: inherit; font-size: 12px; font-weight: 600;
    cursor: pointer;
    font-variant-numeric: tabular-nums;
}
.tf-km:hover{ border-color: var(--sd-verde-borde); background: var(--sd-crema); }
.tf-km.es-on{ border-color: var(--sd-verde); background: var(--sd-verde-claro); color: var(--sd-verde-oscuro); }

.tf-cerca-nota{
    display: block;
    margin-top: 8px;
    font-size: 11px; line-height: 1.45; color: var(--sd-suave);
}
.tf-cerca-nota.es-mal{ color: #b3183c; }



/* ══════════════════════════════════════════════════════════════════════
   TContentReportForm — «Denunciar contenido»

   Esta hoja VIAJA CON TODA PÁGINA (pageComponents), y por eso el botón se
   define aquí: lo ponen la ficha de producto, el perfil del vendedor y cada
   valoración, y así los tres se ven igual sin que ninguno lo redefina.

   ── DISCRETO, PERO ACCESIBLE ─────────────────────────────────────────
   Es una opción que casi nadie usa y que no puede competir con «Añadir a la
   cesta»: texto pequeño, sin fondo ni borde. Pero el gris cumple AA
   (#556259 sobre blanco, 6,3:1) y el foco se ve.

   ── LA CLASE DOBLADA ─────────────────────────────────────────────────
   `.TComponentES6 button` impone display:flex y 25px de alto a todo botón
   dentro de un componente, y la hoja de la ficha arrastra reglas globales
   sobre `button`: con `button.crf-boton.crf-boton` se gana sin depender del
   orden de carga.

   Candidato a la hoja común del área pública cuando se extraiga.
   ══════════════════════════════════════════════════════════════════════ */

button.crf-boton.crf-boton{
    display: inline-flex; align-items: center; gap: 5px;
    height: auto; min-height: 0; width: auto;
    margin: 0; padding: 4px 2px;
    background: none; border: 0; border-radius: 4px; box-shadow: none;
    font-family: inherit; font-size: 12px; font-weight: 600; line-height: 1.3;
    color: #556259; cursor: pointer;
    text-decoration: none;
}
button.crf-boton.crf-boton:hover{ color: #9b1c14; text-decoration: underline; }
button.crf-boton.crf-boton:focus-visible{ outline: 2px solid #04713a; outline-offset: 2px; }
button.crf-boton.crf-boton iconify-icon{ font-size: 13px; flex: 0 0 auto; }

/* La fila que lo coloca al final de un bloque, alineado a la derecha. */
.crf-fila{ display: flex; justify-content: flex-end; margin-top: 10px; }

/* La variante de la página /denunciar-contenido: aquí SÍ es la acción principal. */
button.crf-boton.crf-boton--principal{
    padding: 10px 18px; border-radius: 8px;
    background: #04713a; color: #fff; font-size: 14px;
}
button.crf-boton.crf-boton--principal:hover{ background: #005c2d; color: #fff; text-decoration: none; }
button.crf-boton.crf-boton--principal iconify-icon{ font-size: 16px; }

/* ── LA PÁGINA ───────────────────────────────────────────────────────── */

.crf [hidden]{ display: none !important; }

.crf .crf-pagina{
    max-width: 880px; margin: 34px auto; padding: 0 16px;
    color: #16211a; font-size: 14px;
}

.crf .crf-cab{ display: flex; gap: 14px; align-items: flex-start; margin-bottom: 26px; }
.crf .crf-cab-ico{
    flex: 0 0 auto; width: 46px; height: 46px; border-radius: 12px;
    display: flex; align-items: center; justify-content: center;
    background: #eef6ee; color: #04713a;
}
.crf .crf-cab-ico iconify-icon{ font-size: 24px; }
.crf .crf-cab-txt{ flex: 1; min-width: 0; }
.crf .crf-cab-txt h1{ margin: 0 0 6px; font-size: 24px; line-height: 1.25; }
.crf .crf-cab-txt p{ margin: 0; color: #4a564e; line-height: 1.5; font-size: 14px; }

.crf .crf-pasos{ display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.crf .crf-paso{
    display: flex; gap: 10px; align-items: flex-start;
    padding: 14px; border: 1px solid #e3e9e4; border-radius: 12px; background: #fff;
}
.crf .crf-paso-ico{ flex: 0 0 auto; color: #04713a; }
.crf .crf-paso-ico iconify-icon{ font-size: 20px; }
.crf .crf-paso > div{ flex: 1; min-width: 0; }
.crf .crf-paso b{ display: block; margin-bottom: 4px; font-size: 14px; }
.crf .crf-paso small{ display: block; color: #4a564e; font-size: 13px; line-height: 1.45; }

.crf .crf-accion{ display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 26px; }
.crf .crf-accion small{ color: #4a564e; font-size: 12px; }
.crf .crf-accion a{ color: #04713a; }

/* ── EL FORMULARIO ──────────────────────────────────────────────────────
   `rows` no pinta nada: una regla global le fija 22px a todo textarea y la de
   los controles un min-height de 60px. La altura se pide por clase. */
.crf-explicacion textarea,
textarea.crf-explicacion{ min-height: 120px !important; height: 120px !important; }

p.crf-nota{
    margin: 4px 0 0; padding: 9px 11px; border-radius: 8px;
    background: #f3f6f4; color: #3f4a43; font-size: 12.5px; line-height: 1.45;
}

/* ── EL ACUSE ───────────────────────────────────────────────────────── */

.crf-acuse{ max-width: 520px; padding: 4px 2px; color: #16211a; font-size: 14px; }
.crf-acuse .crf-acuse-fila{ display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px; }
.crf-acuse .crf-acuse-ico{ flex: 0 0 auto; color: #04713a; }
.crf-acuse .crf-acuse-ico iconify-icon{ font-size: 26px; }
.crf-acuse .crf-acuse-txt{ flex: 1; min-width: 0; }
.crf-acuse .crf-acuse-txt b{ display: block; font-size: 16px; margin-bottom: 3px; }
.crf-acuse .crf-acuse-txt small{ display: block; font-size: 13px; color: #4a564e; }
.crf-acuse p{ margin: 0 0 10px; line-height: 1.5; font-size: 14px; }
.crf-acuse .crf-acuse-pie{ display: flex; justify-content: flex-end; margin-top: 14px; }



