/*
 * La tienda pública.
 *
 * Los colores salen del logo, no de una paleta inventada: se sacaron contando
 * los píxeles de img/anguzsan-logo-web.png. El logo es alegre —naranjas, rojo,
 * rosa, ámbar sobre pizarra— y una tienda en blanco y gris al lado de ese logo
 * parece de otra empresa.
 *
 * La pizarra es el fondo del propio logo, así que la site-header y el site-footer lo
 * llevan: el logo se asienta encima sin recorte que se note.
 */

:root {
    /* Del logo, tal cual */
    --slate: #363B4E;
    --fire: #ED5A26;

    /*
     * El mismo naranja, bajado de luz para when lleva texto.
     *
     * `--fire` es el del logo y con él **no se puede escribir**: blanco encima
     * da 3,4 de contraste y él sobre la crema da 3,2, cuando la norma pide 4,5.
     * No es una manía de auditoría: a pleno sol en un móvil, un botón naranja
     * con letras blancas no se lee, y este catálogo se mira desde un obrador.
     *
     * Éste da 5,1 con blanco encima y 4,8 sobre la crema. Es el mismo tono
     * —mismo matiz y misma saturación, solo menos luz—, así que el logo y la
     * brand siguen siendo los de siempre.
     */
    --fire-deep: #C64010;
    --raspberry: #FC1D3F;
    --amber: #FC9D1D;
    --sand: #F8CE86;
    --pink: #F1ACBE;
    --salmon: #F4AE94;

    /* Derivados para el papel y los bordes */
    --cream: #FDF7EF;
    --cream-deep: #F6EADA;
    --slate-light: #4A5165;
    --soft-text: #6B7280;

    --radius: 14px;
    --shadow: 0 1px 2px rgba(54, 59, 78, .06), 0 8px 24px rgba(54, 59, 78, .08);
    --shadow-high: 0 4px 8px rgba(54, 59, 78, .10), 0 16px 40px rgba(54, 59, 78, .14);
}

body {
    background-color: var(--cream);
    color: var(--slate);
    font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

a {
    color: var(--fire-deep);
    text-decoration: none;
}

a:hover {
    color: var(--raspberry);
}

/* -- Cabecera ----------------------------------------------------------- */

.site-header {
    background: var(--slate);
    color: #fff;
}

.site-header .logo {
    /*
     * Menos alto que el PNG que había, y no es que el logo encoja.
     *
     * Aquel llevaba dentro su propio rectángulo de pizarra, así que de sus 46px
     * de alto la mitad era fondo y las letras medían unos 21. El SVG es solo el
     * lettering: a 46 se vería el doble de grande y se saldría de su columna.
     * Con 30 las letras quedan algo mayores que antes, que es lo que se busca,
     * sin desbordar.
     */
    height: 30px;
    width: auto;
    display: block;
}

/*
 * La ribbon de colores del logo, de lado a lado bajo la site-header. Es lo que
 * ata la página al logo sin tener que llenarla de color.
 */
.ribbon {
    height: 5px;
    background: linear-gradient(
        to right,
        var(--fire) 0 20%,
        var(--amber) 20% 40%,
        var(--raspberry) 40% 60%,
        var(--pink) 60% 80%,
        var(--sand) 80% 100%
    );
}

/*
 * El search-box, en su propia fila y a todo lo ancho.
 *
 * Estaba metido entre el logotipo y los botones de cuenta y carrito, y en un
 * catálogo de más de seis mil referencias es **la herramienta principal**: who
 * compra para un obrador no navega por categorías, teclea «capsula pergamino n2»
 * o la referencia del proveedor. Compartiendo fila con el resto se leía como un
 * accesorio.
 */
.search-row {
    margin-top: .25rem;
}

.search-box .form-control {
    border: 0;
    border-radius: 999px;
    padding: .8rem 1.35rem;
    background: #fff;
    font-size: 1.02rem;
}

.search-box .form-control::placeholder {
    color: var(--soft-text);
}

.search-box .form-control:focus {
    box-shadow: 0 0 0 .25rem rgba(252, 157, 29, .35);
}

/*
 * En el teléfono, el logo y los botones en la MISMA fila.
 *
 * La site-header son tres piezas: el logo, los botones de cuenta y carrito, y el
 * search-box, que va en su fila entera. A tamaño normal el logo mide 142 px y los
 * dos botones otros 190: en una pantalla de 360 no caben juntos, así que los
 * botones se iban a un renglón propio y la site-header pasaba a medir tres filas.
 * Eso son 60 px de nada justo donde más falta hacen, encima del producto.
 *
 * Con el logo algo menor y los botones más apretados entran los tres en dos
 * filas. El logo sigue leyéndose: son 24 px de letra, y es un SVG.
 */
@media (max-width: 575.98px) {
    .site-header .container {
        padding-top: .65rem;
        padding-bottom: .65rem;
    }

    .site-header .logo {
        height: 24px;
    }

    .site-header .btn {
        padding: .4rem .7rem;
        font-size: .85rem;
    }

    /* El search-box no se aprieta: es la herramienta principal de la tienda, y
       por debajo de 16 px de letra el iPhone hace zoom al tocarlo. */
    .search-box .form-control {
        padding: .65rem 1.1rem;
    }
}

/* -- Botones ------------------------------------------------------------ */

.btn-shop {
    --bs-btn-color: #fff;
    --bs-btn-bg: var(--fire-deep);
    --bs-btn-border-color: var(--fire-deep);
    --bs-btn-hover-color: #fff;
    --bs-btn-hover-bg: #A0340D;
    --bs-btn-hover-border-color: #A0340D;
    --bs-btn-active-bg: #C24314;
    --bs-btn-active-border-color: #C24314;
    --bs-btn-focus-shadow-rgb: 237, 90, 38;
    --bs-btn-disabled-bg: var(--salmon);
    --bs-btn-disabled-border-color: var(--salmon);
    border-radius: 999px;
    font-weight: 600;
    padding: .55rem 1.4rem;
}

.btn-shop-soft {
    --bs-btn-color: var(--slate);
    --bs-btn-bg: #fff;
    --bs-btn-border-color: var(--cream-deep);
    --bs-btn-hover-color: var(--fire);
    --bs-btn-hover-bg: #fff;
    --bs-btn-hover-border-color: var(--fire);
    --bs-btn-focus-shadow-rgb: 237, 90, 38;
    border-radius: 999px;
    font-weight: 600;
}

/* La burbuja con cuántos artículos hay en el carrito. */
.cart-count {
    display: inline-block;
    min-width: 1.5em;
    background: #fff;
    color: var(--fire);
    border-radius: 999px;
    font-size: .78rem;
    font-weight: 800;
    padding: 0 .35em;
    margin-left: .25rem;
}

/* -- Portada ------------------------------------------------------------ */

.intro {
    background: linear-gradient(135deg, var(--sand), var(--pink));
    border-radius: var(--radius);
    padding: 2.5rem 2rem;
    color: var(--slate);
}

.intro h1 {
    font-weight: 800;
    letter-spacing: -.02em;
}

.intro-tagline {
    margin-bottom: 1.1rem;
    max-width: 44rem;
}

.intro-buttons {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
}

/*
 * Los tres datos de debajo.
 *
 * Van en una lista de verdad y no en un párrafo con puntos: son tres hechos
 * sueltos, y who navega con un lector de pantalla los oye como tres y no
 * como una frase. Los separadores los pone el CSS, que es donde tienen que
 * estar: no son texto, son maquetación, y un lector de pantalla no los lee.
 */
.intro-facts {
    margin: 1.1rem 0 0;
    padding: 0;
    list-style: none;
    font-size: .88rem;
    line-height: 1.75;
}

/*
 * Los tres datos van en flujo de texto, no en cajas.
 *
 * Con flex y `gap`, en una pantalla estrecha cada dato se va a su renglón y el
 * separador se queda colgando al PRINCIPIO de la línea, como una viñeta suelta
 * que no separa nada. Como texto corrido se parten donde toca y el punto cae
 * siempre entre dos datos, que es lo suyo.
 */
.intro-facts li {
    display: inline;
}

.intro-facts li + li::before {
    content: " · ";
    color: rgba(54, 59, 78, .45);
}

/* El de WhatsApp con su verde, que es lo que hace que se reconozca de un
   vistazo sin tener que leerlo. */
.btn-whatsapp {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    background: #25d366;
    border: 0;
    color: #fff;
    font-weight: 600;
}

.btn-whatsapp:hover,
.btn-whatsapp:focus {
    background: #1fb457;
    color: #fff;
}

.btn-whatsapp svg {
    width: 1.15rem;
    height: 1.15rem;
    fill: currentColor;
    flex: none;
}

/* El segundo botón, sobre el degradado: blanco y con borde, que sobre arena y
   rosa el naranja de la casa no se despega del fondo. */
.btn-intro {
    background: rgba(255, 255, 255, .9);
    border: 1px solid rgba(54, 59, 78, .15);
    color: var(--slate);
    font-weight: 600;
}

.btn-intro:hover,
.btn-intro:focus {
    background: #fff;
    color: var(--slate);
}

/*
 * En el teléfono, la presentación se aprieta y los botones se estiran.
 *
 * Con el relleno de 2.5rem y el título a tamaño de escritorio, la caja medía
 * 300 px de alto: la primera pantalla entera para un lema, sin un producto ni
 * un botón a la vista. Apretada cabe ella y asoma lo que hay debajo, que es de
 * lo que va la tienda.
 *
 * Y los botones a todo lo ancho y uno por renglón: dos botones cortos y
 * seguidos en una pantalla de 360 px se tocan mal y se leen peor.
 */
@media (max-width: 575.98px) {
    .intro {
        padding: 1.35rem 1.15rem;
    }

    .intro h1 {
        font-size: 1.3rem;
    }

    .intro-tagline {
        font-size: .95rem;
        margin-bottom: .9rem;
    }

    .intro-buttons .btn {
        flex: 1 1 100%;
        justify-content: center;
    }

    .intro-facts {
        font-size: .82rem;
    }
}

/* La presentación de una categoría, when la hay escrita. */
.category-intro {
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-left: 5px solid var(--amber);
    border-radius: 10px;
    padding: 1rem 1.2rem;
    font-size: .95rem;
}

/* -- Categorías --------------------------------------------------------- */

.category {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-left: 5px solid var(--fire);
    border-radius: 10px;
    padding: .7rem .9rem;
    color: var(--slate);
    font-weight: 600;
    font-size: .92rem;
    height: 100%;
    transition: transform .12s ease, box-shadow .12s ease;
}

.category:hover {
    color: var(--slate);
    transform: translateY(-2px);
    box-shadow: var(--shadow);
}

/*
 * El borde de cada categoría va rotando por los cinco colores del logo. Con
 * 133 categorías, uno solo sería una pared de rayas iguales.
 */
.category:nth-child(5n+2) { border-left-color: var(--amber); }
.category:nth-child(5n+3) { border-left-color: var(--raspberry); }
.category:nth-child(5n+4) { border-left-color: var(--pink); }
.category:nth-child(5n+5) { border-left-color: var(--sand); }

.category .how-many {
    background: var(--cream);
    color: var(--soft-text);
    border-radius: 999px;
    padding: .1rem .6rem;
    font-size: .78rem;
    font-weight: 700;
    flex: none;
}

/*
 * En pantalla estrecha, la cuenta baja de renglón.
 *
 * La tarjeta reparte el card-name a un lado y la cuenta al otro, y la cuenta va
 * con `flex: none` para que no se parta el «10 categorías · 585 artículos» por
 * la mitad. El efecto secundario es que tampoco cede: con un card-name largo en
 * una pantalla de 360 px, la cuenta se salía de la tarjeta y se cortaba contra
 * el borde. Dejando envolver, cae entera debajo del card-name.
 */
@media (max-width: 575.98px) {
    .category {
        flex-wrap: wrap;
    }
}

/* -- Tarjeta de producto ------------------------------------------------ */

.product-card {
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    height: 100%;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: transform .12s ease, box-shadow .12s ease;
}

.product-card:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-high);
}

.product-card .portrait {
    background: #fff;
    padding: 1rem;
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;

    /* El `min-height: 0` es lo que hace que el `aspect-ratio` de arriba sirva
       para algo.

       Sin él no servía. Un hijo de flex arranca con `min-height: auto`, que
       significa «no te encojas por debajo de tu contenido», y el contenido aquí
       es una foto de 400 de lado: el hueco crecía hasta 432 —los 400 más el
       padding— en vez de quedarse en el cuadrado que pide el `aspect-ratio`. Y
       el `max-height: 100%` de la foto tampoco frenaba nada, porque un
       porcentaje contra una altura que aún no está decidida no se resuelve.

       Se veía en la portada: seis por fila, tarjetas de 219 de ancho y el hueco
       de la foto midiendo el doble de alto, con la foto flotando en medio de
       todo aquel blanco. */
    min-height: 0;
}

.product-card .portrait img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.product-card .card-body {
    padding: .9rem 1rem 1.1rem;
    display: flex;
    flex-direction: column;
    flex: 1;
    border-top: 1px solid var(--cream-deep);
}

.product-card .card-name {
    color: var(--slate);
    font-size: .95rem;
    font-weight: 600;
    line-height: 1.3;
    margin-bottom: .25rem;
}

.product-card .brand {
    color: var(--soft-text);
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Cuando la brand es enlace lleva a su catálogo entero, así que tiene que
   poder pulsarse: en .78rem la línea mide 18px y hace falta 24. */
a.brand {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
}

.price {
    color: var(--raspberry);
    font-weight: 800;
    font-size: 1.25rem;
    line-height: 1.1;
}

.price-big {
    font-size: 2rem;
}

.fineprint {
    color: var(--soft-text);
    font-size: .78rem;
}

/* -- Ficha grande ------------------------------------------------------- */

.portrait-big {
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    padding: 1.5rem;
    /*
     * El hueco reservado antes de que llegue la foto.
     *
     * Sin esto la product-card se pinta con la caja a cero y da un salto when carga
     * la imagen: el price y el botón de comprar se mueven bajo el dedo. Google
     * lo mide —es la parte de «estabilidad visual» de Core Web Vitals— y las
     * fotos de producto son cuadradas o casi, así que el cuadrado no deforma
     * nada.
     */
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
}

.portrait-big img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/*
 * El <picture> no puede quedarse en medio.
 *
 * El freno de la foto es `max-height: 100%`, y ese 100% se mide contra el
 * padre. Con un <picture> por medio el padre de la imagen es el <picture>, que
 * no tiene alto propio, así que el porcentaje no se puede resolver y el freno
 * no llega a aplicarse: la foto salía a su tamaño natural y estiraba la caja.
 *
 * Con `display: contents` la etiqueta deja de pintar caja —sigue ahí y sigue
 * eligiendo el WebP, que es para lo que está— y la imagen pasa a ser hija
 * directa de la caja de la foto, que sí tiene alto. Entonces el freno agarra.
 *
 * **A la tarjeta del listado le faltaba**, y ahí estaba pasando lo mismo desde
 * el principio: la foto salía de 400 de alto dentro de una caja de 233, o sea
 * 68 píxeles por debajo de su sitio, en las 6.500 fichas del catálogo. No se
 * veía porque casi todas las fotos son cuadradas y `object-fit: contain` las
 * pinta centradas, dejando el hueco sobrante transparente. En las verticales
 * —las 31 que tienen el PNG de 960x1280 del inventario— sí se ve: la foto se
 * mete por debajo de la raya y tapa el nombre de la marca.
 */
.product-card .portrait picture,
.portrait-big picture,
.slide picture {
    display: contents;
}

/*
 * El slides de fotos de la product-card.
 *
 * Sin un solo guion: la tira se desplaza con `scroll-snap`, que lo trae el
 * navegador, y las miniaturas de debajo son enlaces a un ancla. Pulsar una
 * lleva a su foto porque el navegador salta al ancla, y `scroll-behavior`
 * hace que el salto se vea como un slides.
 *
 * Se eligió así porque las fotos son lo que decide una compra: no pueden
 * depender de que cargue un guion.
 */
.photo-slides {
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    padding: 1.5rem;
}

.slides {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-behavior: smooth;
    gap: 1rem;
    /* La barra de desplazamiento estorba: la tira ya se entiende por las
       miniaturas y por la foto cortada del borde. */
    scrollbar-width: none;
}

.slides::-webkit-scrollbar {
    display: none;
}

.slide {
    flex: 0 0 100%;
    scroll-snap-align: center;
    display: flex;
    align-items: center;
    justify-content: center;
    /*
     * El ancla se para donde empieza la tira y no arriba del todo de la
     * página: sin esto, pulsar una miniatura mandaba el slides al principio del
     * documento y la product-card se iba de la pantalla.
     */
    scroll-margin-top: 0;
}

.slide {
    /* El mismo hueco reservado que en la foto suelta, por lo mismo. */
    aspect-ratio: 1;
}

.slide img {
    max-height: 100%;
    object-fit: contain;
}

/*
 * En el teléfono, la foto no se puede comer la pantalla.
 *
 * La caja de la foto es cuadrada para que no dé el salto al cargar, y en
 * pantalla ancha está bien: cae al lado del price. En el móvil el price va
 * DEBAJO, y un cuadrado a todo lo ancho mide lo que mide la pantalla: con la
 * site-header, el menú y el card-name del producto por encima, el price y el botón
 * de comprar quedaban fuera de la primera pantalla en TODAS las fichas. Había
 * que bajar a ciegas para saber cuánto cuesta.
 *
 * Se queda en tres cuartos: la foto sigue siendo lo primero y lo más grande,
 * pero el price entra. Y sigue siendo una proporción fija, así que no vuelve
 * el salto al cargar.
 */
@media (max-width: 575.98px) {
    /*
     * Alto fijo y no proporción.
     *
     * Con `aspect-ratio` la caja pide 3/2, pero la foto de dentro es más alta
     * que eso y la estira: `max-height: 100%` no le sirve de freno porque el
     * 100% se mide contra una altura que depende del propio contenido, y eso
     * no se puede resolver. Dando el alto en firme, el freno ya tiene contra
     * qué medir y la foto se queda dentro. Sigue sin dar el salto al cargar,
     * que es para lo que estaba la proporción.
     */
    .portrait-big,
    .slide {
        aspect-ratio: auto;
        height: 15rem;
    }

    .portrait-big,
    .photo-slides {
        padding: .75rem;
    }
}

.slide-thumbs {
    display: flex;
    gap: .5rem;
    flex-wrap: wrap;
    justify-content: center;
    margin-top: 1rem;
}

.slide-thumb {
    display: block;
    border: 1px solid var(--cream-deep);
    border-radius: 8px;
    padding: 2px;
    background: #fff;
    line-height: 0;
}

.slide-thumb:hover,
.slide-thumb:focus-visible {
    border-color: var(--fire);
}

.slide-thumb img {
    width: 64px;
    height: 64px;
    object-fit: contain;
}

.panel {
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    padding: 1.5rem;
}

.crumbs {
    font-size: .85rem;
    color: var(--soft-text);
}

.crumbs a {
    color: var(--soft-text);
}

.crumbs a:hover {
    color: var(--fire-deep);
}

/* Sin existencias. Avisa, no prohíbe: se puede comprar igual. */
.sold-out {
    color: var(--fire-deep);
    font-size: .76rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
}

/* -- Paginador ---------------------------------------------------------- */

.pager .page-link {
    color: var(--slate);
    border-color: var(--cream-deep);
}

.pager .page-link:hover {
    color: var(--fire-deep);
    background: #fff;
}

.pager .active .page-link {
    background: var(--fire-deep);
    border-color: var(--fire-deep);
    color: #fff;
}

/* -- Pie ---------------------------------------------------------------- */

.site-footer {
    background: var(--slate);
    color: rgba(255, 255, 255, .75);
    font-size: .88rem;
}

/*
 * Los enlaces del site-footer, con sitio para el dedo.
 *
 * Iban uno detrás de otro separados por `<br>`, y cada uno medía los 18px de la
 * línea de texto. La norma pide 24 de alto, y no por capricho: con menos, en un
 * móvil se acierta al de al lado. Se sube con `padding` y no con `line-height`
 * para que el bloque siga midiendo lo mismo y el site-footer no crezca de golpe.
 */
.site-footer a {
    color: var(--sand);
    display: inline-block;
    padding: .2rem 0;
    min-height: 24px;
}

.site-footer a:hover {
    color: #fff;
}

/*
 * El correo del site-footer va subrayado, y los enlaces sueltos dentro de un párrafo.
 *
 * Van en medio de una línea de texto —«Telf. 926 87 08 56 · info@…»— y lo único
 * que los distinguía era el color. Quien no separa bien esos dos colores no ve
 * que ahí hay un enlace; el subrayado se ve siempre, y es lo que pide la norma
 * when un enlace vive dentro de un bloque de texto.
 *
 * No se subrayan todos los enlaces del sitio: en un menú o en una tarjeta el
 * sitio entero es pulsable y ya se sabe, y subrayarlos sería ruido.
 */
.site-footer p a,
.site-footer .col-12 > a {
    text-decoration: underline;
    text-underline-offset: .15em;
}

.site-footer h2 {
    color: #fff;
    font-size: .8rem;
    text-transform: uppercase;
    letter-spacing: .08em;
    margin-bottom: .6rem;
}

/* -- WhatsApp ----------------------------------------------------------- */

/*
 * El botón de atención al cliente, fijo abajo a la derecha.
 *
 * Se queda por encima de todo salvo de los avisos, y se aparta del borde lo
 * suficiente para no taparle a nadie el botón de comprar en el móvil.
 */
.whatsapp {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    z-index: 1030;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    background: #25d366;
    color: #fff;
    box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .3);
    transition: transform .15s ease-in-out;
}

.whatsapp:hover,
.whatsapp:focus {
    color: #fff;
    transform: scale(1.08);
}

.whatsapp svg {
    width: 2rem;
    height: 2rem;
    fill: currentColor;
}

/* A who tenga puesto que no quiere animaciones, no se le mueve. */
@media (prefers-reduced-motion: reduce) {
    .whatsapp {
        transition: none;
    }

    .whatsapp:hover,
    .whatsapp:focus {
        transform: none;
    }
}

/* ---------------------------------------------------------------------------
   El chat del catálogo

   Va encima del botón de WhatsApp, no en su lugar. El de WhatsApp lleva a una
   persona y es el que mejor funciona; este es para lo otro, para las tres de la
   mañana y para «¿tenéis cápsulas del número 2?».

   En el teléfono el panel ocupa casi la pantalla, que es como se usa un chat en
   un móvil. En el ordenador es una columna estrecha en la esquina.
   --------------------------------------------------------------------------- */
.chat {
    position: fixed;
    right: 1rem;
    bottom: 5.5rem;
    z-index: 1031;
    display: flex;
    flex-direction: column;
    align-items: flex-end;
    gap: .6rem;
}

/* Con el aviso de cookies puesto, todo el rincón se sube. */
.cookie-notice:not([hidden]) ~ .chat {
    bottom: 11rem;
}

.chat-open {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    padding: .55rem .95rem;
    border: 0;
    border-radius: 999px;
    background: var(--slate, #363b4e);
    color: #fff;
    font-size: .88rem;
    font-weight: 600;
    box-shadow: 0 .35rem 1rem rgba(0, 0, 0, .3);
    cursor: pointer;
}

.chat-open:hover,
.chat-open:focus-visible {
    background: #2b2f3e;
}

.chat-open svg {
    width: 1.15rem;
    height: 1.15rem;
    fill: currentColor;
    flex: none;
}

.chat-panel {
    display: flex;
    flex-direction: column;
    width: min(22rem, calc(100vw - 2rem));
    max-height: min(32rem, calc(100vh - 9rem));
    background: #fff;
    border: 1px solid var(--cream-deep, #eadfd2);
    border-radius: 14px;
    box-shadow: 0 1rem 2.5rem rgba(54, 59, 78, .25);
    overflow: hidden;
}

.chat-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .7rem .9rem;
    background: var(--slate, #363b4e);
    color: #fff;
}

.chat-title {
    margin: 0;
    font-size: .95rem;
    font-weight: 700;
}

.chat-close {
    border: 0;
    background: none;
    color: inherit;
    font-size: 1.4rem;
    line-height: 1;
    padding: 0 .25rem;
    cursor: pointer;
}

.chat-messages {
    flex: 1;
    overflow-y: auto;
    padding: .9rem;
    display: flex;
    flex-direction: column;
    gap: .55rem;
    background: var(--cream, #fdf7ef);
}

.chat-message {
    max-width: 85%;
    padding: .5rem .75rem;
    border-radius: 12px;
    font-size: .9rem;
    line-height: 1.45;
    /* El texto del modelo puede traer una referencia larguísima sin espacios;
       sin esto, empuja la burbuja fuera del panel. */
    overflow-wrap: anywhere;
    white-space: pre-wrap;
}

.chat-from-assistant {
    align-self: flex-start;
    background: #fff;
    border: 1px solid var(--cream-deep, #eadfd2);
}

.chat-from-person {
    align-self: flex-end;
    background: var(--slate, #363b4e);
    color: #fff;
}

.chat-items {
    display: flex;
    flex-direction: column;
    gap: .45rem;
}

.chat-item {
    display: flex;
    gap: .6rem;
    padding: .5rem;
    background: #fff;
    border: 1px solid var(--cream-deep, #eadfd2);
    border-radius: 10px;
}

.chat-item img {
    width: 48px;
    height: 48px;
    object-fit: contain;
    flex: none;
    background: var(--cream, #fdf7ef);
    border-radius: 6px;
}

.chat-item-body {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    min-width: 0;
}

.chat-item-name {
    font-size: .85rem;
    font-weight: 600;
    color: var(--slate, #363b4e);
    text-decoration: none;
    line-height: 1.3;
}

/* El price y el botón en la misma línea: con el botón en un renglón propio,
   seis artículos seguidos no caben en la pantalla de un teléfono. */
.chat-item-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    flex-wrap: wrap;
}

.chat-item-detail {
    font-size: .78rem;
    color: var(--soft-text, #6b7280);
}

.chat-item-foot .btn {
    padding: .2rem .55rem;
    font-size: .76rem;
    white-space: nowrap;
}

.chat-compose {
    display: flex;
    gap: .4rem;
    padding: .6rem;
    border-top: 1px solid var(--cream-deep, #eadfd2);
}

/* 16 px justos: por debajo, Safari en el iPhone hace zoom al tocar el campo. */
.chat-compose .form-control {
    font-size: 1rem;
}

.chat-fineprint {
    margin: 0;
    padding: 0 .7rem .7rem;
    font-size: .72rem;
    line-height: 1.4;
    color: var(--soft-text, #6b7280);
}

/*
 * En el teléfono, el panel casi entero.
 *
 * Una columna de 22rem en una pantalla de 360 px deja el chat en un sello. Y
 * el botón, sin el rótulo: al lado del de WhatsApp, dos píldoras con texto en
 * la esquina tapan media pantalla.
 */
@media (max-width: 575.98px) {
    .chat {
        right: .75rem;
        bottom: 5rem;
        left: .75rem;
        align-items: flex-end;
    }

    .chat-panel {
        width: 100%;
        max-height: calc(100vh - 8rem);
    }

    .chat-open span {
        display: none;
    }

    .chat-open {
        width: 3rem;
        height: 3rem;
        padding: 0;
        justify-content: center;
    }

    .chat-open svg {
        width: 1.4rem;
        height: 1.4rem;
    }
}

/* -- Después de pagar --------------------------------------------------- */

/*
 * El sello de que ha salido bien. Es lo primero que se mira al volver de la
 * pasarela, y hasta ahora lo primero era una lista de importes.
 */
.paid-stamp {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 4rem;
    height: 4rem;
    margin-bottom: .75rem;
    border-radius: 50%;
    background: #1f8a4c;
    color: #fff;
    font-size: 2rem;
    line-height: 1;
}

/* Mientras el aviso de la pasarela no ha entrado: ni bien ni mal, esperando. */
.pending-stamp {
    background: var(--sand, #e8c39e);
    color: var(--slate, #363b4e);
}

/* -- Aviso de cookies --------------------------------------------------- */

.cookie-notice {
    position: fixed;
    left: 1rem;
    right: 1rem;
    bottom: 1rem;
    z-index: 1040;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    max-width: 62rem;
    margin: 0 auto;
    padding: 1rem 1.25rem;
    border-radius: 10px;
    background: var(--slate, #363b4e);
    color: rgba(255, 255, 255, .9);
    box-shadow: 0 .5rem 1.5rem rgba(0, 0, 0, .3);
    font-size: .9rem;
}

.cookie-notice a {
    color: var(--sand, #e8c39e);
}

/* Con el aviso puesto, el botón de WhatsApp se sube para no taparse. */
.cookie-notice:not([hidden]) ~ .whatsapp {
    bottom: 6.5rem;
}

/*
 * En el móvil el aviso se come dos filas de resultados.
 *
 * El texto en pantalla estrecha ocupa cuatro renglones y con los botones deja
 * el aviso en 200 px de alto, fijo abajo: who busca algo ve la primera fila
 * de productos y el resto tapado hasta que lo cierra. Se acorta el texto —el
 * detalle sigue a un toque, en la página de privacidad—, se aprieta el
 * espaciado y los botones se ponen en línea con él.
 */
@media (max-width: 575.98px) {
    .cookie-notice {
        left: .5rem;
        right: .5rem;
        bottom: .5rem;
        padding: .7rem .85rem;
        font-size: .85rem;
        gap: .4rem;
    }

    .cookie-notice .btn {
        padding: .3rem .7rem;
        font-size: .8rem;
    }

    /* Lo que solo está para explicar se queda fuera en pantalla estrecha. */
    .cookie-notice .hide-on-phone {
        display: none;
    }
}

/* ---------------------------------------------------------------------------
   Guías

   Contenido, no catálogo. Van a dos columnas: el texto a la izquierda y el
   índice a la derecha.

   Una columna de prosa no puede ser ancha —pasados unos ochenta caracteres se
   pierde el renglón—, así que en una pantalla de 1320 px sobra sitio por
   fuerza. En vez de dejarlo vacío, que se lee como un fallo de maquetación, lo
   ocupa el índice: dice dónde estás, deja saltar de apartado y lleva a las
   categorías, que es el enlace que interesa que se pulse.

   Del ancho del texto se encarga la columna. Aquí NO se le pone max-width al
   artículo: fue el error de la primera versión, porque se lleva por delante
   también la parrilla de fichas.
   --------------------------------------------------------------------------- */
.guide p {
    line-height: 1.7;
}

/*
   En pantalla ancha, la prosa se para en su medida de lectura.

   La columna de la guía mide ahí unos 856 px, que son ciento y pico
   caracteres por línea: demasiados, se pierde el renglón al volver. Los
   120 px que sobran quedan DENTRO de la columna, al lado del índice, y no se
   notan; lo que no se puede es capar también la parrilla de fichas, que fue
   el error de la primera versión.

   Por debajo de 992 px no hace falta: la columna ya es estrecha y el índice
   no sale.
*/
@media (min-width: 992px) {
    .guide > header,
    .guide > p,
    .guide > .alert,
    .guide .guide-section > h2,
    .guide .guide-section > p {
        max-width: 46rem;
    }
}

/*
   Dentro de la columna de la guía caben tres fichas, no cuatro.

   Las clases de la tarjeta (col-lg-3) miran el ancho de la VENTANA y no el del
   sitio donde caen; en una columna de dos tercios eso deja fichas de 175 px con
   la foto ilegible. Se sobreescribe solo aquí.
*/
@media (min-width: 992px) {
    .guide .guide-section .row > [class*='col-'] {
        width: 33.3333%;
    }
}

/* La portada: apaisada y recortada, para que las diez den la misma altura
   aunque el generador devuelva proporciones distintas. */
.guide-cover {
    display: block;
    width: 100%;
    height: auto;
    max-height: 20rem;
    object-fit: cover;
    border-radius: 10px;
}

/*
 * Las de dentro del texto de una guía. Más bajas que la portada: parten la
 * lectura sin robarle el sitio, que lo que se ha venido a leer es el texto.
 */
.guide-inside {
    display: block;
    width: 100%;
    height: auto;
    max-height: 14rem;
    object-fit: cover;
    border-radius: 10px;
}

.card-cover {
    display: block;
    width: calc(100% + 2.2rem);
    height: 9rem;
    margin: -1rem -1.1rem .35rem;
    object-fit: cover;
    border-radius: 10px 10px 0 0;
}

.guide-index {
    position: sticky;
    top: 1.5rem;
    padding: 1.25rem 1.4rem;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 10px;
    background: var(--bone, #f7f3ee);
}

.index-list {
    margin: .5rem 0 0;
    padding-left: 1.1rem;
    font-size: .92rem;
    line-height: 1.5;
}

.index-list li + li {
    margin-top: .4rem;
}

.category-list {
    list-style: none;
    padding-left: 0;
}

.guide .guide-lead {
    font-size: 1.05rem;
    line-height: 1.6;
}

.guide-section {
    scroll-margin-top: 1.5rem;
}

/* El summary de una guía. Sin el filete de la izquierda: se ve en media
   internet y apunta a un sitio donde no hay nada que mirar. El color va por
   arriba, que es por donde empieza a leerse. */
.summary {
    padding: 1rem 1.25rem;
    border: 1px solid rgba(54, 59, 78, .1);
    border-top: 2px solid var(--orange, #e8622a);
    border-radius: 2px 2px 10px 10px;
    background: var(--bone, #f7f3ee);
}

.summary ol {
    padding-left: 1.1rem;
}

.guide-card {
    display: flex;
    flex-direction: column;
    gap: .35rem;
    height: 100%;
    padding: 1rem 1.1rem;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 10px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, transform .15s ease;
}

.guide-card:hover {
    border-color: var(--orange, #e8622a);
    transform: translateY(-2px);
}

.guide-card .guide-emoji {
    font-size: 1.5rem;
    line-height: 1;
}

.guide-card .guide-title {
    font-weight: 600;
    line-height: 1.35;
}

.guide-card-big .guide-lead {
    font-size: .9rem;
    color: #6b7280;
    line-height: 1.5;
}

/* ---------------------------------------------------------------------------
   Secciones de la portada y tarjetas de categoría

   La foto es la de un artículo de dentro, no una imagen inventada: junto a
   «Cápsulas» se ve una cápsula que se vende. Ver App\Service\CategoryImages.
   --------------------------------------------------------------------------- */
.category-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 10px;
    overflow: hidden;
    background: #fff;
    text-decoration: none;
    color: inherit;
    transition: border-color .15s ease, transform .15s ease;
}

.category-card:hover {
    border-color: var(--orange, #e8622a);
    transform: translateY(-2px);
}

.category-photo {
    display: block;
    width: 100%;
    height: 8.5rem;
    object-fit: contain;
    background: var(--bone, #f7f3ee);
    padding: .5rem;
}

.category-no-photo {
    height: 8.5rem;
}

.category-body {
    display: flex;
    flex-direction: column;
    gap: .25rem;
    padding: .7rem .8rem .8rem;
}

.category-name {
    font-weight: 600;
    line-height: 1.3;
}

.category-text {
    font-size: .82rem;
    color: #6b7280;
    line-height: 1.45;
}

.category-card .how-many {
    margin-top: auto;
    padding-top: .35rem;
    font-size: .78rem;
    /* Estaba en #9ca3af, que sobre blanco da 2,5: por debajo de lo que se lee
       en una pantalla al sol. El de la casa da 4,8 y se sigue viendo apagado,
       que es lo que se buscaba. */
    color: var(--soft-text);
}

.shop-section h2 {
    border-bottom: 2px solid var(--orange, #e8622a);
    padding-bottom: .35rem;
}

/* La casilla trampa para robots: fuera de la vista pero no display:none, que
   algunos la detectan y la saltan. */
.covered {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.bell-notice {
    padding: 1rem 1.1rem;
    border: 1px dashed rgba(54, 59, 78, .25);
    border-radius: 10px;
    background: var(--bone, #f7f3ee);
}

/* ---------------------------------------------------------------------------
   Opiniones

   Las stars de elegir van en orden inverso en el HTML para poder pintar de
   la 1 a la que se brand usando solo CSS (~), sin una línea de JavaScript.
   --------------------------------------------------------------------------- */
.review-item {
    padding: 1rem 0;
    border-top: 1px solid rgba(54, 59, 78, .12);
}

.stars-pick {
    display: inline-flex;
    flex-direction: row-reverse;
    gap: .15rem;
    font-size: 1.8rem;
    line-height: 1;
}

.stars-pick input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.stars-pick label {
    color: #d5d8e0;
    cursor: pointer;
    transition: color .1s ease;
}

.stars-pick input:checked ~ label,
.stars-pick label:hover,
.stars-pick label:hover ~ label {
    color: #f0a500;
}

.stars-pick input:focus-visible + label {
    outline: 2px solid var(--orange, #e8622a);
    outline-offset: 2px;
}

.stars {
    color: #f0a500;
    letter-spacing: .05em;
}

.review {
    padding: .9rem 0;
    border-top: 1px solid rgba(54, 59, 78, .1);
}

.review .who {
    font-size: .85rem;
    color: #6b7280;
}

/* ---------------------------------------------------------------------------
   Sugerencias del search-box
   ---------------------------------------------------------------------------
   La lista va en posición absoluta sobre el contenido y no empujándolo: si al
   escribir la página diera un salto, el usuario perdería de vista lo que
   estaba leyendo. El contenedor es relativo para que cuelgue justo del campo.
*/

.search-field {
    position: relative;
    flex: 1 1 auto;
    /* Sin esto el campo no limita a la lista y el desplegable se sale por la
       derecha, como se veía en la captura. */
    min-width: 0;
}

.suggestions {
    position: absolute;
    z-index: 1080;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    margin: 0;
    padding: 4px 0;
    list-style: none;
    max-height: 60vh;
    overflow-y: auto;
    background: var(--bs-body-bg, #fff);
    border: 1px solid rgba(0, 0, 0, .15);
    border-radius: 10px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, .18);

    /*
     * El color se fija aquí y NO se hereda, que es lo que rompía el
     * desplegable: la lista cuelga de la site-header de la tienda, que tiene su
     * propio color de texto, así que el card-name y el price salían en claro
     * sobre el fondo blanco de la lista. Las suggestions estaban ahí, y no se
     * veía ninguna.
     */
    color: #212529;
}

@media (prefers-color-scheme: dark) {
    .suggestions {
        color: #f8f9fa;
    }
}

.suggestion {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px 12px;
    /* Sin `inherit`: ver el comentario de arriba. */
    color: inherit;
    text-decoration: none;
    /* Que la fila no crezca con la foto: el alto lo manda el texto. */
    min-height: 0;
}

.suggestions li.highlighted .suggestion,
.suggestion:hover,
.suggestion:focus {
    background: rgba(0, 0, 0, .06);
    text-decoration: none;
}

.suggestion img {
    width: 44px;
    height: 44px;
    /* Las tres a la vez: sin max-height, una foto alta estira la fila y la
       lista de ocho ocupa media pantalla, que es como se veía. */
    max-width: 44px;
    max-height: 44px;
    object-fit: contain;
    flex: 0 0 auto;
}

/* El card-name se corta con puntos suspensivos en vez de partirse en tres
   líneas: así todas las suggestions miden lo mismo y la lista se lee de un
   vistazo. */
.suggestion-name {
    flex: 1 1 auto;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.suggestion-price {
    flex: 0 0 auto;
    font-weight: 600;
    white-space: nowrap;
}

/* La raya que separa los artículos de las guías. Va en el `li` y no en el
   enlace para que el resalte del teclado, que pinta el enlace entero, no se
   coma la línea. */
.suggestions li.suggestion-divider {
    border-top: 1px solid rgba(0, 0, 0, .12);
}

/* El emoji ocupa el hueco de la foto, con la misma caja de 44px: si midiera
   menos, el card-name de las guías empezaría más a la izquierda que el de los
   artículos y la columna se vería torcida. */
.suggestion-emoji {
    width: 44px;
    height: 44px;
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 22px;
    line-height: 1;
}

/* «Guía» donde el artículo lleva el price: en gris y más pequeño, que es una
   etiqueta y no un dato que haya que comparar. */
.suggestion-guide {
    flex: 0 0 auto;
    font-size: .82em;
    opacity: .65;
    white-space: nowrap;
    text-transform: uppercase;
    letter-spacing: .04em;
}

/* Qué se lleva el cliente: caja o unidad. Va encima del price porque es lo
   que hay que leer antes de mirar la cifra. */
.what-it-has {
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: .04em;
    font-size: .82rem;
    opacity: .75;
}

.loose-sale {
    border: 1px solid rgba(0, 0, 0, .12);
    border-radius: 10px;
    padding: 12px 14px;
    background: rgba(0, 0, 0, .03);
}

/* Reordenar el carrito dragging. El cursor y la opacidad son la única
   señal de que la línea se puede mover: no se añade ningún asa para no meter
   un elemento más en una fila que ya lleva cantidad, price y quitar. */
.cart-line {
    cursor: grab;
}

.cart-line.dragging {
    opacity: .45;
    cursor: grabbing;
}

/*
 * La casilla de cantidad del carrito.
 *
 * Llevaba `form-control-sm`, que son 14 px de letra, y eso en un iPhone tiene
 * un efecto que no se ve en el escritorio: Safari da por hecho que no se puede
 * leer y hace ZOOM a la página entera al tocar el campo. El cliente se queda
 * con el carrito ampliado y descuadrado, y tiene que volver a alejarlo a mano
 * para seguir. Con 16 px no hace zoom, que es el único número que le vale.
 *
 * Y se le pone medida: es una cantidad de tres cifras, no necesita más, y en
 * pantalla estrecha lo que sobra se lo quita a la palabra y al botón.
 */
.quantity-box {
    width: 5rem;
    flex: 0 0 auto;
    text-align: center;
}

/*
 * En el teléfono, la fila de cantidad pasa de renglón antes que desbordarse.
 *
 * En su columna caben 210 px y dentro van la casilla, la palabra («cajas»,
 * «unidades sueltas») y el botón de cambiar. No caben: la palabra va sin
 * partir, así que lo que se salía era el botón, por el borde derecho de la
 * pantalla. Dejándola envolver, el botón baja a un segundo renglón y se ve
 * entero.
 */
@media (max-width: 575.98px) {
    .cart-line form {
        flex-wrap: wrap;
    }

    .quantity-box {
        width: 4.5rem;
    }
}

.cart-line:focus-visible {
    outline: 2px solid currentColor;
    outline-offset: 4px;
}

/*
 * El semáforo del almacén de una product-card.
 *
 * Cuatro tramos en vez de un número: who compra por cajas no sabe si «3» es
 * mucho o poco, pero sí ve de un vistazo cuántos tramos están encendidos.
 *
 * El color va acompañado SIEMPRE de un texto —«Quedan pocas», «Sin
 * existencias»— y no al revés. Un semáforo a secas no lo lee who no
 * distingue el rojo del verde, que es un 8 % de los hombres.
 */
.stock-level {
    display: flex;
    gap: .6rem;
    align-items: flex-start;
}

.stock-bar {
    display: flex;
    gap: 3px;
    flex: 0 0 auto;
    margin-top: .25rem;
}

.stock-bar span {
    width: 14px;
    height: 6px;
    border-radius: 3px;
    background: #e3e1dc;
}

.stock-green    .stock-bar .filled { background: #2e7d32; }
.stock-amber .stock-bar .filled { background: #d99400; }
.stock-red     .stock-bar .filled { background: #c62828; }
.stock-grey     .stock-bar .filled { background: #9a958c; }

.stock-green    strong { color: #2e7d32; }
.stock-amber strong { color: #a06e00; }
.stock-red     strong { color: #c62828; }
.stock-grey     strong { color: #6f6a62; }

/* Lo que dice la product-card técnica del fabricante: datos sueltos, en lista. */
.features {
    list-style: none;
    padding: 0;
    margin: 0;
    color: #5c574f;
}

.features li {
    padding: .15rem 0 .15rem 1.1rem;
    position: relative;
}

.features li::before {
    content: "·";
    position: absolute;
    left: .35rem;
    font-weight: 700;
}

/* ---------------------------------------------------------------------------
   Ofertas

   El price de antes va tachado al lado del de ahora, no debajo: en una tarjeta
   de listado, dos líneas de price descuadran la altura de la fila entera y las
   tarjetas dejan de alinearse.

   Y el porcentaje solo sale en la product-card. En el listado sobra: ahí lo que se
   compara es una tarjeta con otra, no un price con su pasado.
   --------------------------------------------------------------------------- */
.price-before {
    margin-left: .4rem;
    font-size: .85em;
    font-weight: 400;
    color: #6b7280;
    text-decoration: line-through;
}

.offer-label {
    display: inline-block;
    margin-left: .5rem;
    padding: .1rem .5rem;
    border-radius: 999px;
    background: var(--raspberry, #fc1d3f);
    color: #fff;
    font-size: .75rem;
    font-weight: 700;
    vertical-align: middle;
}

/* La foto de reserva de una guía es cuadrada —es una miniatura de producto— y
   la portada compuesta es apaisada. Se recorta para que las tarjetas de una
   fila midan lo mismo, que si no la del artículo estira su fila entera. */
.article-cover {
    aspect-ratio: 2 / 1;
    object-fit: contain;
    background: #fff;
}

/* ---------------------------------------------------------------------------
   La tira de marcas

   Se arrastra en horizontal y **no lleva JavaScript**: es desbordamiento con
   scroll-snap, que trae el navegador. Es la misma técnica del slides de fotos de
   la product-card y por el mismo reason — un carrusel que depende de un guion se queda
   quieto el día que el guion falla.

   La barra se deja a la vista en móvil, que es donde hace de aviso de que hay
   más a la derecha; en escritorio se afina.
   --------------------------------------------------------------------------- */
.brand-strip {
    display: flex;
    gap: .75rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scroll-padding-left: .25rem;
    padding-bottom: .75rem;
    -webkit-overflow-scrolling: touch;
}

.brand-strip::-webkit-scrollbar { height: 6px; }
.brand-strip::-webkit-scrollbar-thumb { background: rgba(54, 59, 78, .25); border-radius: 3px; }

.brand-strip:focus-visible {
    outline: 2px solid var(--orange, #e8622a);
    outline-offset: 3px;
}

.brand-tile {
    flex: 0 0 auto;
    width: 8.5rem;
    scroll-snap-align: start;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .35rem;
    padding: .75rem .5rem;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 10px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    text-align: center;
    transition: border-color .15s ease, transform .15s ease;
}

.brand-tile:hover {
    border-color: var(--orange, #e8622a);
    transform: translateY(-2px);
}

.brand-tile img {
    width: 100%;
    aspect-ratio: 1;
    object-fit: contain;
    border-radius: 6px;
}

/* Sin foto, la inicial. Mejor que un hueco: la tarjeta mantiene su altura y la
   fila no se descuadra. */
.brand-no-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1;
    border-radius: 6px;
    background: var(--cream, #fdf7ef);
    color: #6b7280;
    font-size: 2rem;
    font-weight: 700;
}

.brand-name {
    font-size: .85rem;
    font-weight: 600;
    line-height: 1.25;
}

.brand-count {
    font-size: .72rem;
    color: #6b7280;
}

@media (prefers-reduced-motion: reduce) {
    .brand-tile { transition: none; }
    .brand-strip { scroll-behavior: auto; }
}

/* La llamada del final de cada sección de guías. Va en línea, no como bloque
   grande: entre dos secciones tiene que separar, no cortar la lectura. */
.section-cta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: .75rem 1.25rem;
    padding: .9rem 1.1rem;
    border: 1px dashed rgba(54, 59, 78, .22);
    border-radius: 10px;
    background: var(--cream, #fdf7ef);
}


/* ---------------------------------------------------------------------------
   La grid que no deja huecos

   Elegir bien el número de columnas no basta y por eso se añadió esto: con once
   tarjetas en filas de cuatro sale 4+4+3, y ese hueco de la última fila se ve.
   Con diecinueve, igual. No hay número de columnas que reparta bien cualquier
   cantidad.

   Lo que sí funciona es dejar que **la última fila estire**: las filas llenas
   salen con las columnas que se pidan y la que queda coja reparte el sitio
   sobrante entre las suyas. Tres tarjetas un poco más anchas no se notan; tres
   huecos al lado de una, sí.

   `--columns` la pone la plantilla con `columnas_para()`, que sigue eligiendo
   el reparto que deja la última fila lo más llena posible: estirar cuatro
   tarjetas para llenar el hueco de una queda raro, y estirar tres para llenar
   el de una no.
   --------------------------------------------------------------------------- */
.grid {
    --columns: 4;
    --gutter: 1rem;

    /*
     * Las columnas que se usan de verdad, y por qué hay dos variables.
     *
     * `--columns` la pone la plantilla EN LÍNEA, con `columnas_para()`, para
     * que la última fila quede lo más llena posible. Y un `style` en línea gana
     * a cualquier regla de la hoja, también a las de dentro de un `@media`: la
     * regla de abajo que dice «en el teléfono, dos columnas» estaba escrita
     * desde el principio y NO SE APLICABA NUNCA. En `/categorias`, en un móvil
     * de 360 px, salían las cuatro columnas que pedía la plantilla y cada
     * tarjeta medía 72 px de ancho, con el card-name y la cuenta saliéndose por
     * los lados.
     *
     * Con la variable de por medio se arregla sin `!important`: lo que la
     * plantilla pone en línea solo llega hasta aquí, como valor de partida, y
     * lo que mandan los `@media` es esta otra, que no está en línea y por tanto
     * sí se puede sobreescribir.
     */
    --columns-that-fit: var(--columns);

    display: flex;
    flex-wrap: wrap;
    gap: var(--gutter);
}

.grid > * {
    flex: 1 1 calc((100% - (var(--columns-that-fit) - 1) * var(--gutter)) / var(--columns-that-fit));
    /* Sin esto, una fila coja de una sola tarjeta la deja del ancho de la
       pantalla, que es peor que el hueco. */
    max-width: calc(1.6 * (100% - (var(--columns-that-fit) - 1) * var(--gutter)) / var(--columns-that-fit));
    min-width: 0;
}

/* En pantalla pequeña mandan las columnas de siempre, pasen las que pasen: dos
   en el teléfono y tres en la tableta. Cinco tarjetas de ancho no se leen. */
@media (max-width: 575.98px) {
    .grid { --columns-that-fit: 2; }
    .grid > * { max-width: none; }
}

@media (min-width: 576px) and (max-width: 991.98px) {
    .grid { --columns-that-fit: 3; }
    .grid > * { max-width: none; }
}

/* El logotipo va con aire alrededor y sin recortar: un logotipo recortado deja
   de ser el logotipo. La foto de producto, en cambio, sí llena la tarjeta. */
.brand-tile .brand-tile-logo {
    object-fit: contain;
    padding: .5rem;
    background: #fff;
}

/* En el listado conviven grupos y categorías sueltas. El grupo lleva su brand
   para que se sepa qué se está mirando antes de pinchar. */
.group-tag {
    display: inline-block;
    padding: .05rem .4rem;
    border-radius: 4px;
    background: rgba(31, 92, 110, .1);
    color: #1f5c6e;
    font-weight: 600;
}

/* ---------------------------------------------------------------------------
   Aparecer al bajar

   La clase `to-appear` la pone el guion, no la plantilla, y eso importa:
   **sin JavaScript no hay nada oculto**. Si se marcara desde el HTML y el guion
   fallara, media portada se quedaría invisible.
   --------------------------------------------------------------------------- */
.to-appear {
    opacity: 0;
    transform: translateY(12px);
}

.to-appear.is-here {
    opacity: 1;
    transform: none;
    transition: opacity .45s ease, transform .45s cubic-bezier(.22, .61, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
    .to-appear,
    .to-appear.is-here {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ---------------------------------------------------------------------------
   Las flechas de la tira de marcas

   Van ocultas en el HTML y las enseña el guion: sin él no harían nada, y un
   botón que no hace nada es peor que no tener botón.
   --------------------------------------------------------------------------- */
.strip-controls {
    display: flex;
    gap: .35rem;
}

.strip-controls button {
    width: 2rem;
    height: 2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(54, 59, 78, .18);
    border-radius: 50%;
    background: #fff;
    color: inherit;
    line-height: 1;
    cursor: pointer;
    transition: border-color .15s ease, opacity .15s ease;
}

.strip-controls button:hover:not(:disabled) { border-color: var(--orange, #e8622a); }
.strip-controls button:disabled { opacity: .35; cursor: default; }
.strip-controls button:focus-visible { outline: 2px solid var(--orange, #e8622a); outline-offset: 2px; }

/* ---------------------------------------------------------------------------
   La fila de «lo que más se vende»

   Aquí no se destaca por tamaño y se llegó por descarte. Se probó con las tres
   primeras a doble ancho y a ancho y medio, y las dos veces pasó lo mismo: la
   foto de la tarjeta es cuadrada, así que **más ancho es más alto**, y la
   sección se comía media pantalla para enseñar doce cosas.

   Lo que se hace ahora es al revés: todas iguales, la foto más baja que en un
   listado —lo que se compara aquí es qué es y cuánto vale, no el detalle— y lo
   que destaca se dice con el tag, que no ocupa nada.

   Y las filas se llenan enteras. `flex-grow` reparte lo que sobre entre las de
   la última fila, así que **no queda hueco a la derecha**: si no cabe otro
   producto, el sitio se lo quedan los que hay.
   --------------------------------------------------------------------------- */
.mosaic {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem;
    align-items: stretch;
}

.mosaic > * {
    flex: 1 1 calc((100% - 5rem) / 6);
    min-width: 0;
}

/* La foto, más baja. En un listado se mira el producto; aquí se recorre. */
.mosaic .portrait { aspect-ratio: 3 / 2; }

@media (max-width: 991.98px) {
    .mosaic > * { flex-basis: calc((100% - 2rem) / 3); }
}

@media (max-width: 575.98px) {
    .mosaic > * { flex-basis: calc((100% - 1rem) / 2); }
}

/* ---------------------------------------------------------------------------
   Los tags

   Salen de datos —el puesto en ventas, la fecha de la oferta, si está
   descatalogado— y por eso ninguno se queda puesto de más. Van arriba a la
   izquierda, encima de la foto y sin taparla.
   --------------------------------------------------------------------------- */
.product-card { position: relative; }

.tags {
    position: absolute;
    top: .5rem;
    left: .5rem;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .25rem;
    pointer-events: none;
}

.tag {
    padding: .1rem .45rem;
    border-radius: 999px;
    background: rgba(54, 59, 78, .88);
    color: #fff;
    font-size: .68rem;
    font-weight: 700;
    line-height: 1.5;
    letter-spacing: .01em;
}

.tag-top { background: var(--slate, #363b4e); }
.tag-offer { background: var(--raspberry, #fc1d3f); }
.tag-last-few { background: var(--amber, #b8730a); }

/* ---------------------------------------------------------------------------
   El menú del catálogo

   Un solo menú para el móvil y para el ordenador. En pantalla ancha los grupos
   van en fila y el panel se abre a todo lo largo; en el teléfono la fila se
   desplaza en horizontal y el panel se abre debajo del grupo.

   Es un <details>, así que **abre y cierra sin JavaScript**. El atributo `name`
   hace que solo pueda haber uno abierto, y eso también lo resuelve el navegador
   en los que lo entienden.
   --------------------------------------------------------------------------- */
.menu-bar {
    position: relative;
    background: #fff;
    border-bottom: 1px solid rgba(54, 59, 78, .1);
    box-shadow: 0 1px 2px rgba(54, 59, 78, .04);
}

.menu-strip {
    display: flex;
    align-items: stretch;
    gap: .25rem;
    overflow-x: auto;
    scrollbar-width: none;
}

.menu-strip::-webkit-scrollbar { display: none; }

/*
 * En pantalla grande el menú baja de línea en vez de cortarse.
 *
 * La tira mide 1.658 px y el contenedor no pasa de 1.296, así que **no cabía
 * en ninguna pantalla**: ni en un monitor de 1.920. Lo que quedaba fuera eran
 * las cuatro últimas entradas —Marcas, Guías, Tarifa profesional y
 * Pregúntanos—, y como la barra de desplazamiento va escondida, en un
 * ordenador con ratón no había manera de llegar a ellas ni de saber que
 * estaban ahí.
 *
 * Con el dedo sí se descubre que la tira se arrastra, y en el teléfono dos
 * filas de menú se comen la pantalla, así que allí se queda como está: se
 * desplaza, y el degradado de abajo avisa de que sigue.
 */
@media (min-width: 992px) {
    .menu-strip {
        flex-wrap: wrap;
        overflow-x: visible;
    }
}

/*
 * El aviso de que la tira del menú sigue.
 *
 * Son diez y pico grupos en una tira que se desplaza de lado, y la barra está
 * escondida a propósito (afea y en el móvil no se pinta hasta que tocas). El
 * problema es que entonces nada dice que haya más: en un teléfono se ven tres
 * grupos y el resto del catálogo parece no existir.
 *
 * Se difumina el borde derecho. No es un adorno: un corte limpio se lee como
 * el final de la lista y un degradado se lee como «sigue».
 */
@media (max-width: 991.98px) {
    .menu-bar::after {
        content: "";
        position: absolute;
        top: 0;
        right: 0;
        width: 2.25rem;
        /* Hasta donde llega la tira, no hasta abajo del panel abierto. */
        height: 2.75rem;
        pointer-events: none;
        background: linear-gradient(to right, rgba(255, 255, 255, 0), #fff 70%);
    }
}

.menu-group { position: static; }

.menu-group > summary,
.menu-single {
    display: flex;
    align-items: center;
    gap: .4rem;
    padding: .7rem .8rem;
    white-space: nowrap;
    font-size: .92rem;
    font-weight: 600;
    color: inherit;
    text-decoration: none;
    cursor: pointer;
    border-bottom: 2px solid transparent;
    list-style: none;
}

.menu-group > summary::-webkit-details-marker { display: none; }

.menu-group > summary:hover,
.menu-single:hover,
.menu-group[open] > summary {
    border-bottom-color: var(--orange, #e8622a);
}

.menu-group > summary:focus-visible,
.menu-single:focus-visible {
    outline: 2px solid var(--orange, #e8622a);
    outline-offset: -2px;
}

/*
 * El panel, siempre suelto y de lado a lado.
 *
 * Va anclado a `.menu-bar`, no al grupo: el grupo es `position: static` a
 * propósito para que el panel se cuelgue de la barra entera. Y eso es lo que
 * lo saca de la tira, que se desplaza de lado y tiene `overflow-x`: como su
 * bloque contenedor está por FUERA de la tira, la tira no lo recorta.
 *
 * Antes esto solo se hacía a partir de 992 px, y en el teléfono el panel se
 * quedaba dentro de la tira, en el flujo. El resultado era este: el panel
 * medía lo que medía su botón —232 px de los 390 de la pantalla—, con las once
 * categorías del grupo apiladas en esa columna, y al mover la tira de lado se
 * iba con ella el panel entero, 626 px de alto incluidos. Se pensó para no
 * tapar lo que hay detrás; tapar es justo lo que tiene que hacer un menú.
 */
.menu-panel {
    position: absolute;
    left: 0;
    right: 0;
    top: 100%;
    z-index: 30;
    padding: 1rem 0 1.25rem;
    background: var(--cream, #fdf7ef);
    border-top: 1px solid rgba(54, 59, 78, .08);
    box-shadow: 0 12px 24px rgba(54, 59, 78, .12);
}

/* Un grupo con muchas categorías no se puede salir de la pantalla por abajo:
   en el teléfono se desplaza dentro del panel. */
@media (max-width: 991.98px) {
    .menu-panel {
        max-height: 70vh;
        overflow-y: auto;
    }
}

.menu-columns {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
    gap: .15rem 1.5rem;
}

.menu-columns a {
    display: flex;
    justify-content: space-between;
    gap: 1rem;
    padding: .4rem .5rem;
    border-radius: 6px;
    color: inherit;
    text-decoration: none;
    font-size: .9rem;
}

.menu-columns a:hover { background: #fff; }

/*
 * El logotipo de la marca en su fila del menú.
 *
 * El hueco se reserva lo tenga o no: si sólo lo dejaran las que tienen
 * logotipo, los nombres de la columna quedarían a distintas sangrías y la
 * lista se leería peor que sin logotipos.
 *
 * `margin-right: auto` porque la fila es flex con `space-between`, y sin él el
 * nombre se iría al centro en vez de quedarse pegado a su logotipo.
 */
.menu-brand-logo {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* Pequeño, pero no tanto como para no reconocerlo: a 1,1 rem de alto el
       logotipo de Artipas era una mancha roja. */
    flex: 0 0 2.2rem;
    width: 2.2rem;
    height: 1.5rem;
}

.menu-brand-logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.menu-columns a > .menu-brand-logo + * {
    margin-right: auto;
}

/* Con el dedo, .4rem de alto son 30 px de destino y se falla. En el teléfono
   se le da aire hasta los 44 que recomiendan Apple y Google. */
@media (max-width: 991.98px) {
    .menu-columns a {
        padding: .65rem .5rem;
    }
}

.menu-count { color: #6b7280; font-size: .8rem; font-variant-numeric: tabular-nums; }

.menu-all {
    display: inline-block;
    margin-top: .9rem;
    font-size: .88rem;
    font-weight: 600;
}

@media (prefers-reduced-motion: no-preference) {
    .menu-group[open] > .menu-panel { animation: menu-baja .18s ease-out; }

    @keyframes menu-baja {
        from { opacity: 0; transform: translateY(-6px); }
        to { opacity: 1; transform: none; }
    }
}

/* ---------------------------------------------------------------------------
   El semáforo del almacén en la tarjeta

   Cuatro rayitas al lado de la brand. Es el mismo semáforo de la product-card en
   pequeño: un número suelto —«quedan 3»— no le dice nada a who compra por
   cajas, y el color se entiende sin leer.

   Va con `title` y `aria-label` porque el color solo no es información: who
   no distingue el verde del rojo, y who usa lector de pantalla, tienen que
   poder saber lo mismo.
   --------------------------------------------------------------------------- */
.brand-line {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 1.2rem;
}

.stock-level-mini {
    display: inline-flex;
    gap: 2px;
    flex: 0 0 auto;
}

.stock-level-mini > span {
    width: 6px;
    height: 10px;
    border-radius: 1px;
    background: rgba(54, 59, 78, .14);
}

.stock-green    .filled { background: #2e7d32; }
.stock-amber .filled { background: #d99400; }
.stock-red     .filled { background: #c62828; }
.stock-grey     .filled { background: #9a958c; }

/* ---------------------------------------------------------------------------
   Compartir

   Va al final de la product-card y de la guía, que es donde se decide share algo:
   arriba nadie ha leído todavía nada que merezca la pena mandar.

   Los botones son del mismo tamaño y del mismo color, sin los colores de cada
   red: una fila de siete botones de colores tira más de la vista que el propio
   producto, y aquí lo que se vende es el producto.
   --------------------------------------------------------------------------- */
.share {
    display: flex;
    flex-direction: column;
    gap: .6rem;
    margin-top: 1.25rem;
    padding-top: 1rem;
    border-top: 1px solid rgba(54, 59, 78, .12);
}

/* Una fila para share y otra para preguntar. En una sola, once botones
   seguidos se leen como una tira y no se distingue mandarle esto a alguien de
   preguntarle a una máquina, que son dos cosas distintas. */
.share-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .5rem .75rem;
}

.share-label {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: #6b7280;
}

.share-buttons { display: flex; flex-wrap: wrap; gap: .4rem; }

.share-button {
    position: relative;
    width: 2.2rem;
    height: 2.2rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(54, 59, 78, .16);
    border-radius: 50%;
    background: #fff;
    color: var(--slate, #363b4e);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.share-button svg { width: 1rem; height: 1rem; display: block; }

.share-button:hover { border-color: var(--orange, #e8622a); color: var(--orange, #e8622a); }
.share-button:focus-visible { outline: 2px solid var(--orange, #e8622a); outline-offset: 2px; }
.share-button.has-copied { border-color: #2e7d32; color: #2e7d32; }

/* El «Copiado» sale encima del botón y no al lado: al lado empujaría los demás
   y la fila entera se movería justo al pulsar. */
.share-copied {
    position: absolute;
    bottom: calc(100% + .3rem);
    left: 50%;
    transform: translateX(-50%);
    padding: .1rem .45rem;
    border-radius: 4px;
    background: #2e7d32;
    color: #fff;
    font-size: .7rem;
    white-space: nowrap;
}

.share-ai {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: .25rem .75rem .25rem .45rem;
    border: 1px solid rgba(54, 59, 78, .16);
    border-radius: 999px;
    background: #fff;
    color: inherit;
    text-decoration: none;
    font-size: .8rem;
    font-weight: 600;
}

/* El logotipo de cada uno. Con `contain` y una caja cuadrada porque no todos
   tienen la misma proporción —el de Perplexity es más alto que ancho— y
   estirarlos para que cuadren es deformarle a alguien su brand. */
.share-ai-brand {
    flex: 0 0 auto;
    width: 1.3rem;
    height: 1.3rem;
    object-fit: contain;
}

.share-ai:hover { border-color: var(--orange, #e8622a); color: var(--orange, #e8622a); }

/* El listado entero de marcas, con su logotipo. Rejilla propia y no columnas de
   Bootstrap: las tarjetas son estrechas y con `auto-fill` caben las que quepan
   en cada pantalla en vez de cuatro siempre. */
.brand-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: .75rem;
}

.brand-card {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .35rem;
    padding: .75rem .5rem;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 10px;
    background: #fff;
    text-decoration: none;
    color: inherit;
    text-align: center;
    transition: border-color .15s ease, transform .15s ease;
}

.brand-card:hover {
    border-color: var(--orange, #e8622a);
    transform: translateY(-2px);
}

/* Caja de altura fija: con logotipo o con inicial, todas las tarjetas de una
   fila miden lo mismo y el card-name queda a la misma altura. */
.brand-card-image {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 4.5rem;
}

/* Sin recortar y con aire: un logotipo recortado deja de ser el logotipo. */
.brand-card-image img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

.brand-card-initial {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 3.25rem;
    height: 3.25rem;
    border-radius: 8px;
    background: var(--cream, #fdf7ef);
    color: #6b7280;
    font-size: 1.6rem;
    font-weight: 700;
}

.brand-card-name {
    font-size: .85rem;
    font-weight: 600;
    line-height: 1.25;
}

.brand-card-count {
    font-size: .72rem;
    color: #6b7280;
}

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


/* Las formas de pago, en tarjetas. Quien entra en esa página busca «la suya»,
   no lee las cuatro: con el rótulo grande y el cuándo debajo se encuentra de un
   vistazo. */
.payment-ways {
    display: grid;
    gap: 1.1rem;
    margin: 1.5rem 0;
}

@media (min-width: 768px) {
    .payment-ways { grid-template-columns: 1fr 1fr; }
}

.payment-way {
    position: relative;
    overflow: hidden;
    padding: 1.4rem 1.5rem 1.5rem;
    border: 1px solid rgba(54, 59, 78, .1);
    border-radius: 14px;
    background: #fff;
}

/* El aire de color va en la esquina y se apaga hacia dentro. Es lo que le da
   carácter a la tarjeta sin la barrita de la izquierda, que se ve en media
   internet y que además apunta a un sitio donde no hay nada que mirar. */
.payment-way::before {
    content: "";
    position: absolute;
    top: -55%;
    right: -30%;
    width: 16rem;
    height: 16rem;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(232, 98, 42, .11), rgba(232, 98, 42, 0) 68%);
    pointer-events: none;
}

.payment-way > * { position: relative; }

/* El titular y el «cuándo vale esto» en el mismo renglón: es la pareja que se
   compara de una a otra, y separada en dos líneas obliga a leerlas todas. */
.payment-way h2 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .4rem .65rem;
    margin: 0 0 .9rem;
    padding-bottom: .7rem;
    /* La raya se apaga por la derecha en vez de cortarse a plomo. */
    border-bottom: 1px solid transparent;
    border-image: linear-gradient(to right, rgba(54, 59, 78, .18), rgba(54, 59, 78, 0)) 1;
}

/* El titular empuja al «cuándo» hasta el borde, y when no cabe se lo lleva a
   la línea de abajo entero en vez de partirlo. */
.payment-way .payment-way-title { flex: 1 1 auto; }

.payment-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 9px;
    background: rgba(232, 98, 42, .1);
    color: var(--orange, #e8622a);
}

.payment-icon svg { width: 1.2rem; height: 1.2rem; }

.payment-way .when {
    flex: 0 0 auto;
    padding: .18rem .6rem;
    border-radius: 999px;
    background: rgba(31, 92, 110, .09);
    color: #1f5c6e;
    font-size: .7rem;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    white-space: nowrap;
}

.payment-way p { margin: 0 0 .55rem; }

/* Las marcas admitidas. Cada logotipo tiene su proporción y ninguno se estira:
   se le fija la altura y el ancho sale solo. */
.payment-marks {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .45rem;
    margin: 0 0 .8rem;
    padding: 0;
    list-style: none;
}

.payment-marks li {
    display: flex;
    align-items: center;
    padding: .25rem .45rem;
    border: 1px solid rgba(54, 59, 78, .1);
    border-radius: 6px;
    background: #fff;
}

.payment-marks img {
    height: 1.15rem;
    width: auto;
}

.payment-way p:last-child { margin-bottom: 0; }

/* -- Pregúntanos ------------------------------------------------------ */

/* El reason, como fichas y no como desplegable: se ven las cinco de golpe y se
   brand de un toque, que en el móvil es la diferencia entre rellenarlo y no. */
.reasons {
    display: flex;
    flex-wrap: wrap;
    gap: .4rem;
    margin-top: .35rem;
}

.reason input {
    position: absolute;
    opacity: 0;
    width: 0;
    height: 0;
}

.reason span {
    display: inline-block;
    padding: .35rem .8rem;
    border: 1px solid rgba(54, 59, 78, .18);
    border-radius: 999px;
    background: #fff;
    font-size: .85rem;
    cursor: pointer;
    transition: border-color .15s ease, background .15s ease;
}

.reason input:checked + span {
    border-color: var(--orange, #e8622a);
    background: var(--cream, #fdf7ef);
    font-weight: 600;
}

/* Sin esto, who va con el teclado no sabe dónde está: el radio de verdad es
   invisible, así que el foco tiene que verse en la product-card. */
.reason input:focus-visible + span {
    outline: 2px solid var(--orange, #e8622a);
    outline-offset: 2px;
}

.contact-form legend {
    float: none;
    width: auto;
    font-size: inherit;
}

/* Lo que se estaba mirando when se pulsó «pregúntanos por esto». Va como
   pastilla y no como caja con filete: es un dato suelto, no un apartado. */
.about-what {
    display: inline-flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem;
    padding: .35rem .85rem;
    border: 1px solid rgba(232, 98, 42, .3);
    border-radius: 999px;
    background: var(--cream, #fdf7ef);
    font-size: .88rem;
}

.about-what span {
    color: #6b7280;
    font-size: .78rem;
    text-transform: uppercase;
    letter-spacing: .03em;
}

.contact-panel hr {
    margin: 1.1rem 0;
    border-color: rgba(54, 59, 78, .12);
}

/* Teléfono, WhatsApp y correo. Quien tiene prisa no rellena un formulario:
   llama. Esconderle el teléfono no hace que escriba, hace que se vaya. */
.contact-way {
    display: flex;
    align-items: center;
    gap: .7rem;
    padding: .6rem .5rem;
    border-radius: 8px;
    color: inherit;
    text-decoration: none;
    transition: background .15s ease;
}

.contact-way:hover { background: var(--cream, #fdf7ef); }

.contact-way strong { display: block; font-size: .95rem; }

.contact-way small { display: block; color: #6b7280; font-size: .78rem; }

.contact-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 2.2rem;
    height: 2.2rem;
    border-radius: 50%;
    background: var(--cream, #fdf7ef);
    color: var(--orange, #e8622a);
}

.contact-icon svg { width: 1.15rem; height: 1.15rem; }

.before-typing {
    margin: 0;
    padding-left: 1.1rem;
}

.before-typing li { margin-bottom: .3rem; }

@media (prefers-reduced-motion: reduce) {
    .reason span,
    .contact-way { transition: none; }
}

/* El opening-hours, en tabla: son dos filas de «esto, a estas horas» y una lista de
   guiones se lee peor que dos columnas alineadas. */
.opening-hours {
    width: 100%;
    margin-bottom: .5rem;
    border-collapse: collapse;
}

.opening-hours th {
    padding: .3rem 0;
    font-weight: 600;
    text-align: left;
}

.opening-hours td {
    padding: .3rem 0;
    color: #4b5563;
    text-align: right;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.opening-hours tr + tr th,
.opening-hours tr + tr td { border-top: 1px solid rgba(54, 59, 78, .08); }

/* Los documents del proveedor: fichas técnicas y certificados. Para un obrador
   que compara envases es lo que decide la compra, así que se ven como lo que
   son —cosas que se abren— y no como una lista de enlaces más. */
.documents ul {
    margin: 0 0 .6rem;
    padding: 0;
    list-style: none;
}

.documents li + li { margin-top: .3rem; }

.documents a {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .4rem .7rem;
    border: 1px solid rgba(54, 59, 78, .14);
    border-radius: 8px;
    background: #fff;
    color: inherit;
    text-decoration: none;
    font-size: .88rem;
    transition: border-color .15s ease;
}

.documents a:hover { border-color: var(--orange, #e8622a); }

.documents svg {
    width: 1.05rem;
    height: 1.05rem;
    flex: 0 0 auto;
    color: #c0392b;
}

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

/* Las características, en tabla. Para who compara envases esto es la
   comparación, así que se lee de un vistazo: la etiqueta a la izquierda, el
   dato a la derecha y una guía de puntos entre los dos, que es lo que impide
   perder el renglón when hay seis filas. */
.specs {
    width: 100%;
    border-collapse: collapse;
    font-size: .9rem;
}

.specs th,
.specs td {
    padding: .35rem 0;
    vertical-align: baseline;
    border-bottom: 1px dotted rgba(54, 59, 78, .18);
}

.specs th {
    width: 40%;
    color: #6b7280;
    font-weight: 400;
    text-align: left;
}

.specs td {
    font-weight: 600;
    text-align: right;
    font-variant-numeric: tabular-nums;
}

.specs tr:last-child th,
.specs tr:last-child td { border-bottom: 0; }

/* Preguntas frecuentes
   -----------------------------------------------------------------------
   Veintitantas preguntas plegadas. La gracia está en que la lista de
   preguntas se lea de un tirón, así que el peso visual va en el `summary` y
   la answer se pinta más suave: al abrir una, la vista no salta.

   Nada de barrita a la izquierda: el mismo criterio que las formas de pago.
   Aquí lo que separa una question de la siguiente es una raya que se apaga,
   y el tema entero va en su tarjeta. */

.faq-index {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    margin-bottom: 1.6rem;
}

.faq-index a {
    padding: .35rem .8rem;
    border: 1px solid rgba(54, 59, 78, .12);
    border-radius: 999px;
    background: #fff;
    color: var(--slate);
    font-size: .875rem;
    line-height: 1.4;
    transition: border-color .15s, color .15s;
}

.faq-index a:hover,
.faq-index a:focus-visible {
    border-color: var(--fire);
    color: var(--fire);
}

.faq-topic {
    position: relative;
    overflow: hidden;
    margin-bottom: 1.1rem;
    padding: 1.3rem 1.5rem .6rem;
    border: 1px solid rgba(54, 59, 78, .1);
    border-radius: var(--radius);
    background: #fff;
    /* Que el ancla no deje el titular pegado a la site-header fija. */
    scroll-margin-top: 5rem;
}

/* El mismo aire de color en la esquina que llevan las formas de pago: es lo
   que hace que las dos páginas se reconozcan como de la misma casa. */
.faq-topic::before {
    content: "";
    position: absolute;
    top: -60%;
    right: -25%;
    width: 15rem;
    height: 15rem;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(232, 98, 42, .09), rgba(232, 98, 42, 0) 68%);
    pointer-events: none;
}

.faq-topic > * { position: relative; }

.faq-topic > h2 {
    margin: 0 0 .4rem;
    color: var(--slate-light);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.question {
    border-top: 1px solid transparent;
    border-image: linear-gradient(to right, rgba(54, 59, 78, .16), rgba(54, 59, 78, 0)) 1;
}

.faq-topic .lista-preguntas > .question:first-child { border-top: 0; }

.question > summary {
    display: flex;
    align-items: flex-start;
    gap: 1rem;
    padding: .85rem 0;
    color: var(--slate);
    font-weight: 600;
    line-height: 1.45;
    cursor: pointer;
    /* El triángulo de fábrica fuera: se pinta el signo de la derecha. */
    list-style: none;
}

.question > summary::-webkit-details-marker { display: none; }

.question > summary:hover { color: var(--fire-deep); }

.question > summary:focus-visible {
    outline: 2px solid var(--fire);
    outline-offset: 3px;
    border-radius: 6px;
}

/* El signo: un más que se convierte en menos al abrir. Dos rayas y una gira,
   que se entiende sin leer nada y no hace falta ninguna tipografía de iconos. */
.question-mark {
    position: relative;
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
    margin-top: .28rem;
}

.question-mark::before,
.question-mark::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 0;
    width: 100%;
    height: 2px;
    border-radius: 2px;
    background: var(--fire);
    transform: translateY(-50%);
}

.question-mark::after {
    transform: translateY(-50%) rotate(90deg);
    transition: transform .18s ease;
}

.question[open] .question-mark::after { transform: translateY(-50%) rotate(0deg); }

@media (prefers-reduced-motion: reduce) {
    .question-mark::after { transition: none; }
}

.question > .answer {
    padding: 0 2rem .95rem 0;
    color: var(--soft-text);
    line-height: 1.6;
}

.question > .answer > p { margin-bottom: .7rem; }
.question > .answer > p:last-child { margin-bottom: 0; }
.question > .answer strong { color: var(--slate); }

/* Las guías que salen en el search-box
   -----------------------------------------------------------------------
   Van arriba de los resultados y tienen que leerse como otra cosa, no como
   un producto sin foto. De ahí el fondo distinto y el emoji delante: se
   distingue de un vistazo que eso es un texto y no una referencia. */

.search-guides {
    padding: 1rem 1.2rem .4rem;
    border: 1px solid rgba(54, 59, 78, .1);
    border-radius: var(--radius);
    background: #fff;
}

.search-guides > h2 {
    margin: 0 0 .6rem;
    color: var(--slate-light);
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .09em;
    text-transform: uppercase;
}

.search-guides ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

.search-guides li + li { border-top: 1px solid rgba(54, 59, 78, .08); }

.search-guides a {
    display: flex;
    align-items: flex-start;
    gap: .8rem;
    padding: .7rem 0;
    color: inherit;
}

.search-guides a:hover .card-title { color: var(--fire-deep); }

.search-guides .emoji { font-size: 1.3rem; line-height: 1.2; }
.search-guides .text { display: block; }

.search-guides .card-title {
    display: block;
    font-weight: 600;
    line-height: 1.35;
}

.search-guides .guide-lead {
    display: block;
    margin-top: .15rem;
    color: var(--soft-text);
    font-size: .875rem;
    line-height: 1.45;
}

/* -- Portada y product-card ---------------------------------------------------- */

/*
 * Las seis categorías que abren la portada.
 *
 * Cuadradas y con la foto centrada, que es como se leen en fila: seis tarjetas
 * de alturas distintas parecen seis cosas distintas. En móvil van de dos en
 * dos, que a seis por fila la foto se queda en un sello.
 */
.featured {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .35rem;
    height: 100%;
    padding: .75rem .5rem;
    border: 1px solid var(--cream-deep);
    border-radius: 14px;
    background: #fff;
    color: inherit;
    text-align: center;
    text-decoration: none;
    transition: border-color .15s, transform .15s;
}

.featured:hover,
.featured:focus {
    border-color: var(--fire-deep);
    transform: translateY(-2px);
    text-decoration: none;
}

/*
 * El hueco de la foto manda sobre la foto.
 *
 * `CategoryCards` devuelve la foto de un artículo de la categoría, y esas vienen
 * de todos los tamaños: sin caja fija, una apaisada de 1.000 px estiraba su
 * tarjeta y descuadraba la fila entera.
 */
.featured-photo {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    aspect-ratio: 1;
    background: var(--cream);
    border-radius: 10px;
    overflow: hidden;
}

.featured-photo img {
    width: 100%;
    height: 100%;
    object-fit: contain;
}

.featured-name {
    font-size: .88rem;
    font-weight: 600;
    line-height: 1.25;
}

.featured-count {
    font-size: .76rem;
    color: var(--soft-text);
}

/*
 * Envío, portes y devolución, al lado del botón.
 *
 * Sin viñeta y en letra chica: son tres datos que se leen de un vistazo antes
 * de comprar, no una lista que haya que estudiar.
 */
.what-to-know {
    list-style: none;
    margin: 0;
    padding: .7rem .9rem;
    border-radius: 12px;
    background: var(--cream);
    font-size: .84rem;
    line-height: 1.5;
}

.what-to-know li + li {
    margin-top: .2rem;
}

/*
 * La cabecera de la página de una marca: el texto y su logotipo.
 *
 * En dos columnas. El texto se lee a 62 caracteres —más largo y se pierde el
 * renglón— y eso dejaba media página vacía a la derecha; ahí va el logotipo,
 * que además así deja de estar pegado al título repitiendo el nombre dos veces
 * seguidas.
 *
 * El logotipo va el último en el HTML y se coloca a la derecha con el orden de
 * la rejilla: en un teléfono, donde las columnas se apilan, lo primero tiene
 * que ser el título y no una imagen de media pantalla.
 */
.brand-header {
    display: grid;
    gap: 1.5rem;
    margin-bottom: 1.25rem;
}

@media (min-width: 768px) {
    /*
     * Las columnas, según lo que haya que poner.
     *
     * El texto se lee a 62 caracteres y el logotipo mide catorce rem, así que
     * la fila hay que repartirla a mano o queda en blanco lo de en medio: eran
     * 316 px vacíos en la página de Braun. **Cada caso lleva las columnas que
     * necesita, ni una más**: una columna reservada para un logotipo que no
     * existe deja el mismo hueco que se venía a quitar, sólo que al final.
     */
    .brand-header {
        align-items: start;
    }

    /* Sólo el logotipo: el texto se estira hasta él. */
    .brand-header-with-logo {
        grid-template-columns: minmax(0, 1fr) 14rem;
    }

    /* Sólo las categorías: se reparte lo que hay. */
    .brand-header-wide {
        grid-template-columns: minmax(0, 62ch) minmax(0, 1fr);
    }

    /* Las dos cosas, que es el caso normal. */
    .brand-header-wide.brand-header-with-logo {
        grid-template-columns: minmax(0, 62ch) minmax(0, 1fr) 14rem;
    }
}

/*
 * Dónde está el producto de la marca, al lado del texto.
 *
 * La columna del medio de la cabecera. En un teléfono va debajo, entre el
 * texto y el logotipo, que es el orden en que se necesita: qué es esta marca,
 * por dónde empezar a mirar, y quién es.
 */
.brand-where-title {
    margin-bottom: .6rem;
    color: var(--slate);
}

.brand-header-logo {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1.25rem;
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
}

.brand-header-logo img {
    max-width: 100%;
    /* Un logotipo cuadrado y uno apaisado tienen que ocupar lo mismo de alto,
       o la caja da saltos de una marca a otra. */
    max-height: 7rem;
    object-fit: contain;
}

/*
 * La caja de la lista de correo, debajo de las guías de la portada.
 *
 * Con fondo propio y borde, para que se lea como una invitación y no como una
 * tarjeta más de la rejilla. El correo y el botón van en la misma línea en
 * pantalla grande y apilados en el teléfono, que es donde se rellena.
 */
.newsletter-box {
    margin-top: 1.25rem;
    padding: 1.4rem 1.5rem;
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
}

.newsletter-title {
    margin: 0 0 .35rem;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--slate);
}

.newsletter-text {
    max-width: 62ch;
    margin-bottom: 1rem;
}

.newsletter-fields {
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    margin-bottom: .6rem;
}

.newsletter-fields input {
    flex: 1 1 18rem;
    min-width: 0;
}

/* La casilla y su texto en la misma línea, con el cuadro arriba: el texto lleva
   un enlace y salta de renglón, y centrado quedaría el cuadro a media altura. */
.newsletter-consent {
    display: flex;
    align-items: flex-start;
    gap: .5rem;
    margin: 0;
}

/*
 * La banda que parte la rejilla cada ocho fichas.
 *
 * Tiene que leerse como un aparte y no como una ficha más: fondo distinto, sin
 * sombra y con el texto en una línea. Si se pareciera a una tarjeta, el ojo la
 * contaría como producto y sería peor que no ponerla.
 */
.between-rows {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: .35rem;
    padding: 1.6rem 1.2rem;
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
}

.between-rows-emoji {
    font-size: 2rem;
    line-height: 1;
    margin-bottom: .2rem;
}

.between-rows-title {
    margin: 0;
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--slate);
}

.between-rows-text {
    max-width: 52ch;
    margin: 0 0 .9rem;
    color: #6b7280;
    font-size: .9rem;
}

/*
 * El cierre de la página de una marca.
 *
 * Va detrás de la rejilla y se separa con una línea: es contenido de apoyo, no
 * lo que se viene a ver. Quien busca producto ya lo tiene arriba, y dónde está
 * cada gama lo tiene en la cabecera.
 */
.brand-closing {
    margin-top: 2.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--cream-deep);
}

/*
 * El cierre, en dos columnas cuando hay marcas que enseñar.
 *
 * El párrafo se lee a 62 caracteres y dejaba media fila en blanco a la
 * derecha. Ahí van las otras marcas, que además ponen imagen en una parte de
 * la página que era sólo texto.
 */
@media (min-width: 768px) {
    .brand-closing-wide {
        display: grid;
        grid-template-columns: minmax(0, 62ch) minmax(0, 1fr);
        gap: 2rem;
        align-items: start;
    }
}

.brand-alongside-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(7rem, 1fr));
    gap: .75rem;
}

/* Más pequeñas que en el índice de marcas: aquí son un apunte, no la lista. */
.brand-alongside-grid .brand-card-image {
    height: 3.25rem;
}

.brand-alongside-grid .brand-card-initial {
    width: 2.25rem;
    height: 2.25rem;
    font-size: 1.1rem;
}

.brand-where {
    display: flex;
    flex-wrap: wrap;
    gap: .45rem;
    margin: 0;
    padding: 0;
    list-style: none;
}

.brand-where li {
    display: inline-flex;
    align-items: baseline;
    gap: .35rem;
    padding: .35rem .7rem;
    background: #fff;
    border: 1px solid var(--cream-deep);
    border-radius: 999px;
    font-size: .9rem;
}

/*
 * Lo que es la brand, encima de su grid de fichas.
 *
 * Se lee como una entradilla y no como un dato más, que es lo que es. El ancho
 * limitado no es un adorno: una línea de ciento veinte caracteres se pierde al
 * saltar de renglón.
 */
.brand-intro {
    max-width: 62ch;
    color: var(--slate);
    font-size: 1.02rem;
    line-height: 1.55;
}

/*
 * El párrafo de datos, con el mismo ancho que la entradilla de arriba.
 *
 * Iba a lo ancho de la página, y en un monitor eso son líneas de ciento
 * cincuenta caracteres: se pierde el renglón al saltar. Pero lo que se veía
 * antes que eso era el escalón, un párrafo estrecho encima de uno ancho, que
 * parece un fallo de sangrado aunque no lo sea.
 */
.category-facts {
    max-width: 62ch;
}

/* ---------------------------------------------------------------------------
   La brand de la product-card, con su logotipo

   Los ficheros llevaban tiempo en `assets/media/marcas` y solo se veían en la
   página de la brand y en el carrusel de la portada. En la product-card, que es donde
   se decide la compra, la brand era una palabra en gris de .78rem.

   Alto fijo y ancho automático: los logotipos vienen de todas las formas
   —cuadrados, apaisados, alguno casi una tira— y lo único que se puede fijar
   sin deformar ninguno es cuánto ocupan de alto.
   --------------------------------------------------------------------------- */
.brand-with-logo {
    display: flex;
    align-items: center;
    gap: .5rem;
}

.brand-logo-inline {
    height: 26px;
    width: auto;
    max-width: 110px;
    object-fit: contain;
}

/*
 * El precio por cantidad, en la ficha.
 *
 * Una fila por tramo, con la cantidad a la izquierda y el precio en negrita:
 * es una tabla de precios y se lee como tal, de arriba abajo comparando la
 * columna del medio. En una tabla de verdad no cabe en un teléfono sin
 * desbordarse, así que son filas de rejilla que se apilan solas.
 */
.volume-price {
    padding: .7rem .9rem;
    border: 1px dashed var(--fire-deep);
    border-radius: 12px;
    background: #FFF8F4;
}

.volume-price-title {
    font-weight: 700;
    font-size: .9rem;
    margin-bottom: .35rem;
}

.volume-price-steps {
    list-style: none;
    margin: 0;
    padding: 0;
    font-size: .86rem;
}

.volume-price-steps li {
    display: grid;
    grid-template-columns: auto auto 1fr;
    gap: .5rem;
    align-items: baseline;
    padding: .15rem 0;
}

.volume-price-steps li + li {
    border-top: 1px solid rgb(198 64 16 / 18%);
}

.volume-price-off {
    color: #6B7280;
    text-align: right;
}

/*
 * El bloque de «facturar a una empresa» del paso de pago.
 *
 * Va plegado en un `<details>`, que es lo que hace que no haga falta guion
 * para desplegarlo: seis casillas más a la vista en el paso de pago son seis
 * motivos para dejar la compra a medias, y la mayoría son de particular.
 */
.billing-details > summary {
    cursor: pointer;
    font-weight: 600;
    padding: .5rem .75rem;
    border: 1px dashed var(--cream-deep);
    border-radius: 10px;
    background: var(--cream);
}

.billing-details[open] > summary {
    border-style: solid;
    border-color: var(--fire-deep);
    margin-bottom: .25rem;
}

/*
 * La trampa del formulario de la lista de correo.
 *
 * Fuera de la pantalla y no `display:none`: hay programas que se saltan lo que
 * está oculto con `display`, y los lectores de pantalla ya lo ignoran por el
 * `aria-hidden` y el `tabindex="-1"` del marcado. Ver `NewsletterGuard`.
 */
.newsletter-trap {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/*
 * La tabla de los catorce alérgenos, en la ficha.
 *
 * En rejilla y no en tabla: en un teléfono una tabla de catorce filas con tres
 * columnas se desborda o se come la pantalla, y lo que se busca aquí es el
 * propio alérgeno, no comparar columnas. Ver `Allergens`.
 */
.allergens {
    list-style: none;
    margin: 1rem 0 0;
    padding: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
    gap: .4rem;
}

/*
 * El icono a la izquierda y las dos líneas de texto a la derecha.
 *
 * En una sola línea —icono, nombre y estado— no cabía: «Cereales con gluten»
 * y «PUEDE CONTENER» en 150 px se cortaban a media palabra. El estado va
 * debajo del nombre, que además es como se lee: primero qué es y luego qué
 * dice la ficha de él.
 */
.allergen {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: center;
    column-gap: .5rem;
    padding: .45rem .6rem;
    border: 1px solid var(--cream-deep);
    border-radius: 10px;
    background: #fff;
    font-size: .82rem;
}

/*
 * El icono va con `stroke` y no `fill`: son trazos, y así el mismo dibujo
 * sirve para los tres estados cambiando solo el color.
 */
.allergen-icon {
    width: 22px;
    height: 22px;
    grid-row: span 2;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.allergen-name {
    line-height: 1.2;
}

/*
 * Sin `nowrap` y sin mayúsculas forzadas: con las dos cosas, «PUEDE CONTENER»
 * no cabe en una celda de móvil y se sale de la caja.
 */
.allergen-state {
    font-size: .72rem;
    line-height: 1.2;
    opacity: .85;
}

/* Lo que lleva: en rojo y con peso, que es lo que hay que ver primero. */
.allergen.is-contiene {
    border-color: #E5534B;
    background: #FDF2F1;
    color: #A32C25;
    font-weight: 600;
}

/* Lo que puede llevar: avisa, pero no es lo mismo. */
.allergen.is-trazas {
    border-color: var(--amber);
    background: #FFF8EC;
    color: #8A5A00;
}

/*
 * Y lo que la ficha no nombra, en gris y apagado. **No dice «no contiene»**:
 * dice que su ficha no lo nombra, que no es lo mismo.
 */
.allergen.is-no-consta {
    color: #9099A8;
}

.allergen.is-no-consta .allergen-icon {
    opacity: .45;
}

/*
 * La página de los siropes.
 *
 * Lo que tiene que verse es el precio por kilo, así que es lo único en grande:
 * las tres cifras de la entrada, el número de cada tarjeta y la columna de la
 * tabla. El resto es Bootstrap sin tocar.
 */
.syrup-hero {
    display: grid;
    gap: 1.5rem;
    align-items: center;
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .syrup-hero {
        grid-template-columns: 1fr 1fr;
    }
}

.syrup-hero-title {
    margin: 0 0 .5rem;
    color: var(--slate);
    font-size: clamp(1.6rem, 4vw, 2.3rem);
    font-weight: 700;
    line-height: 1.15;
}

.syrup-hero-lead {
    margin: 0 0 1.1rem;
    color: var(--slate-light);
    font-size: 1.05rem;
}

/* Las tres cifras: sabores, el kilo más barato y lo que hay en el almacén. */
.syrup-figures {
    display: flex;
    flex-wrap: wrap;
    gap: 1.75rem;
    margin: 0 0 1.25rem;
    padding: 0;
    list-style: none;
}

.syrup-figures strong {
    display: block;
    color: var(--fire-deep);
    font-size: 1.6rem;
    line-height: 1.1;
}

.syrup-figures span {
    color: var(--soft-text);
    font-size: .85rem;
}

.syrup-hero-buttons {
    margin: 0;
}

.syrup-hero-photo img {
    width: 100%;
    height: auto;
    border-radius: var(--radius);
    box-shadow: var(--shadow);
}

/* La tarjeta de un sabor: foto, nombre y el precio por kilo mandando. */
.syrup-card {
    display: flex;
    height: 100%;
    flex-direction: column;
    padding: .6rem;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    background: #fff;
    box-shadow: var(--shadow);
    color: inherit;
    text-decoration: none;
    transition: box-shadow .15s ease, transform .15s ease;
}

.syrup-card:hover,
.syrup-card:focus-visible {
    box-shadow: var(--shadow-high);
    transform: translateY(-2px);
}

.syrup-card-photo {
    display: block;
    overflow: hidden;
    margin-bottom: .5rem;
    border-radius: calc(var(--radius) - 6px);
    aspect-ratio: 1;
    background: var(--cream);
}

.syrup-card-photo img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.syrup-card-flavour {
    color: var(--slate);
    font-weight: 600;
    line-height: 1.2;
}

.syrup-card-kilo {
    color: var(--fire-deep);
    font-size: 1.05rem;
    font-weight: 700;
}

.syrup-card-format {
    color: var(--soft-text);
    font-size: .82rem;
}

/* Un apunte corto: los tres de antes de la tabla y las preguntas. */
.syrup-note {
    padding: 1rem 1.15rem;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    background: #fff;
}

.syrup-note p {
    margin: 0;
    color: var(--slate-light);
}

.syrup-note-title {
    margin-bottom: .35rem !important;
    color: var(--slate);
    font-weight: 600;
}

/*
 * El grupo de un sabor se separa del siguiente con una línea, que es lo que
 * hace legible una tabla de treinta filas: sin ella el ojo no sabe dónde acaba
 * un sabor.
 */
.syrup-table tbody + tbody {
    border-top: 2px solid var(--cream-deep);
}

.syrup-table th[scope="rowgroup"] {
    font-weight: 600;
    vertical-align: middle;
}

.syrup-per-kilo {
    font-weight: 700;
    white-space: nowrap;
}

.syrup-close {
    padding: 1.25rem 1.4rem;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    background: var(--cream);
}

.syrup-close-title {
    margin-bottom: .35rem;
    color: var(--slate);
    font-size: 1.1rem;
    font-weight: 700;
}

/*
 * Las opiniones de la portada: una tira que pasa sola.
 *
 * Tarjetas estrechas y de la misma altura, con la cara y el nombre arriba, el
 * texto en medio y de dónde sale abajo. La tira se arrastra con el dedo y con
 * la rueda sin JavaScript; las flechas y el paseo los pone [[opinions.js]].
 */
.opinion-score {
    color: var(--soft-text);
    font-size: .9rem;
}

.opinion-score span[aria-hidden] {
    color: var(--amber);
    letter-spacing: .05em;
}

.opinion-score strong {
    color: var(--slate);
}

.opinion-arrows {
    display: flex;
    flex: 0 0 auto;
    gap: .35rem;
}

.opinion-strip {
    display: flex;
    overflow-x: auto;
    gap: .85rem;
    padding: .25rem .25rem 1rem;
    margin: 0 -.25rem;
    scroll-snap-type: x mandatory;
    scrollbar-width: thin;
    -webkit-overflow-scrolling: touch;
}

/* La barra de desplazamiento, discreta: la tira ya se mueve sola. */
.opinion-strip::-webkit-scrollbar {
    height: 6px;
}

.opinion-strip::-webkit-scrollbar-thumb {
    border-radius: 999px;
    background: var(--cream-deep);
}

.opinion {
    display: flex;
    flex: 0 0 clamp(250px, 80vw, 300px);
    flex-direction: column;
    margin: 0;
    padding: 1rem 1.1rem;
    border: 1px solid var(--cream-deep);
    border-radius: var(--radius);
    background: #fff;
    box-shadow: var(--shadow);
    scroll-snap-align: start;
}

.opinion-top {
    display: flex;
    align-items: center;
    gap: .6rem;
    margin-bottom: .5rem;
}

/*
 * La cara: la inicial sobre un color sacado del propio nombre.
 *
 * Así cada persona tiene el suyo y siempre el mismo, sin guardar nada de ella
 * y sin servir desde aquí su foto de perfil de Google. Ver
 * [[Testimonials::initialsOf]].
 */
.opinion-face {
    display: grid;
    width: 38px;
    height: 38px;
    flex: 0 0 38px;
    border-radius: 50%;
    background: hsl(var(--face, 20) 55% 92%);
    color: hsl(var(--face, 20) 55% 30%);
    font-size: .9rem;
    font-weight: 700;
    place-items: center;
}

.opinion-who {
    display: flex;
    min-width: 0;
    flex-direction: column;
    line-height: 1.25;
}

.opinion-author {
    overflow: hidden;
    color: var(--slate);
    font-weight: 600;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.opinion-trade {
    color: var(--soft-text);
    font-size: .8rem;
}

.opinion-stars {
    margin: 0 0 .4rem;
    color: var(--amber);
    font-size: .95rem;
    letter-spacing: .06em;
    line-height: 1;
}

.opinion-stars-off {
    color: var(--cream-deep);
}

/*
 * El texto, recortado a seis líneas.
 *
 * **El recorte es de pantalla, nunca del dato**: en el fichero está entero,
 * que es lo que esa persona escribió, y quien quiera leerlo va a la fuente por
 * el logotipo de abajo.
 */
.opinion-text {
    display: -webkit-box;
    overflow: hidden;
    flex: 1 1 auto;
    margin: 0 0 .7rem;
    color: var(--slate);
    font-size: .92rem;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 6;
    line-clamp: 6;
}

/* De dónde sale, con su logotipo: lo que hace que se la crea alguien. */
.opinion-source {
    display: flex;
    align-items: center;
    padding-top: .55rem;
    border-top: 1px solid var(--cream);
}

.opinion-source a {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    color: var(--soft-text);
    font-size: .82rem;
    text-decoration: none;
}

.opinion-source a:hover {
    color: var(--slate);
}

.opinion-source img {
    width: 16px;
    height: 16px;
    object-fit: contain;
}

.opinion-source svg {
    flex: 0 0 auto;
}

/*
 * «En almacén»: lo que se sirve mañana.
 *
 * Sin esto, el precio más bajo de la página es el de una marca que está a cero
 * y no se nota hasta el carrito.
 */
.syrup-here {
    display: inline-block;
    padding: .05rem .4rem;
    border-radius: 999px;
    background: #E8F5EC;
    color: #1E7A43;
    font-size: .72rem;
    font-weight: 600;
    white-space: nowrap;
}

/* La foto del bote en la tabla: pequeña, cuadrada y sin estorbar. */
.syrup-thumb {
    width: 48px;
    padding-right: 0;
}

.syrup-thumb img {
    width: 40px;
    height: 40px;
    border-radius: 8px;
    background: var(--cream);
    object-fit: contain;
}
