/* =========================================================================
   Portal de compras — sistema visual
   =========================================================================

   La idea: esto no es un escaparate, es la hoja de pedido semanal. La unidad
   que organiza todo es LA SEMANA, no el producto. De ahí la tira de días
   siempre visible con la cuenta atrás del corte, que es la restricción real
   del negocio.

   Colores sacados de los materiales, no del imaginario «bio»: tierra mojada,
   papel de sala de manipulado, verde de caixa, apio para la señal de que algo
   está disponible, tomate solo para la urgencia.

   Todas las medidas de toque son de 44 px como mínimo: se pide con el pulgar,
   de pie, con prisa.
   ========================================================================= */

:root {
  /* Color -------------------------------------------------------------- */
  --tinta: #12211a;         /* casi negro con fondo verde: tierra mojada */
  --tinta-suave: #3d4d44;
  --gris: #5e6b62;          /* texto secundario; 4.6:1 sobre papel */
  --paper: #f2f5f0;         /* blanco mineral frío */
  --paper-alt: #e7ede6;
  --blanco: #ffffff;
  --linea: #ccd8c9;        /* separadores decorativos */
  --linea-camp: #8a9c86;   /* borde de campo: 3,06:1, lo pide 1.4.11 */
  --bosc: #1b5e3f;          /* verde botella: estructura y marca */
  --bosc-fosc: #12442d;
  --api: #b9d64a;           /* apio ácido: SOLO disponible y acción */
  --api-suau: #eaf3c9;
  --tomaquet: #d9502b;      /* urgencia: solo relleno */
  --tomaquet-text: #b03616; /* urgencia: texto, 4.6:1 sobre papel */
  --tomaquet-suau: #fbe8e1;

  /* Tipografía ---------------------------------------------------------- */
  --tipo-display: 'Bricolage Grotesque', 'Trebuchet MS', system-ui, sans-serif;
  --tipo-cuerpo: 'Public Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* Espacio ------------------------------------------------------------- */
  --e1: 0.25rem;
  --e2: 0.5rem;
  --e3: 0.75rem;
  --e4: 1rem;
  --e5: 1.5rem;
  --e6: 2rem;
  --e7: 3rem;

  /* Formas -------------------------------------------------------------- */
  --radio: 4px;             /* honesto, de caja de campo */
  --radio-pill: 999px;
  --sombra: 0 1px 2px rgba(18, 33, 26, .08), 0 4px 12px rgba(18, 33, 26, .06);
  --sombra-alta: 0 2px 6px rgba(18, 33, 26, .12), 0 12px 28px rgba(18, 33, 26, .12);

  /* Medidas ------------------------------------------------------------- */
  --toque: 44px;
  --ancho: 1180px;
  --alto-cabecera: 56px;
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* La cabecera es sticky: sin esto, saltar al contenido o tabular hacia
     arriba deja el destino debajo de ella. */
  scroll-padding-top: calc(var(--alto-cabecera) + var(--e2));
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--tinta);
  font-family: var(--tipo-cuerpo);
  font-size: 1rem;              /* 16px: por debajo, iOS hace zoom al enfocar */
  line-height: 1.5;
  font-variant-numeric: tabular-nums;  /* kg, € y fechas siempre alineados */
  -webkit-font-smoothing: antialiased;
}

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

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

a { color: var(--bosc); text-underline-offset: .18em; }
a:hover { color: var(--bosc-fosc); }

/* Foco visible SIEMPRE. Un portal que se usa con prisa se acaba usando con
   el teclado, y un foco invisible deja a la gente perdida. */
:focus-visible {
  outline: 3px solid var(--api);
  outline-offset: 2px;
  border-radius: 2px;
  /* Dos tonos: el apio se ve sobre los fondos oscuros (6,8:1 sobre el verde
     de la tira) y el halo de tinta lo separa del papel, donde el apio solo
     daría 1,5:1. Con un anillo de un color, uno de los dos fondos pierde. */
  box-shadow: 0 0 0 6px var(--tinta);
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}

/* Solo para lectores de pantalla */
.solo-lectores {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Salto al contenido: lo primero que encuentra quien va con teclado */
.saltar {
  position: absolute;
  left: var(--e4);
  top: -100px;
  z-index: 100;
  background: var(--bosc);
  color: var(--blanco);
  padding: var(--e3) var(--e4);
  border-radius: var(--radio);
  transition: top .15s ease;
}
.saltar:focus { top: var(--e2); }

/* ----------------------------------------------------------- tipografía */
h1, h2, h3 {
  font-family: var(--tipo-display);
  font-weight: 700;
  letter-spacing: -.02em;
  line-height: 1.1;
  margin: 0 0 var(--e3);
}

h1 { font-size: clamp(1.6rem, 5vw, 2.4rem); }
h2 { font-size: clamp(1.2rem, 3.2vw, 1.5rem); }
h3 { font-size: 1.0625rem; letter-spacing: -.01em; }

.eyebrow {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gris);
  margin: 0 0 var(--e2);
}

.texto-secundario { color: var(--gris); }
.texto-pequeno { font-size: .8125rem; }

/* ------------------------------------------------------------- esquelet */
.envoltorio {
  width: 100%;
  max-width: var(--ancho);
  margin-inline: auto;
  padding-inline: var(--e4);
}

@media (min-width: 48rem) {
  .envoltorio { padding-inline: var(--e5); }
}

/* ------------------------------------------------------------- cabecera */
.cabecera {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--tinta);
  color: var(--paper);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}

.cabecera__fila {
  display: flex;
  align-items: center;
  gap: var(--e3);
  min-height: var(--alto-cabecera);
}

.marca {
  font-family: var(--tipo-display);
  font-weight: 800;
  font-size: 1.0625rem;
  letter-spacing: -.02em;
  color: var(--paper);
  text-decoration: none;
  display: flex;
  align-items: center;
  gap: var(--e2);
}
.marca:hover { color: var(--api); }

.marca__punto {
  width: .5rem; height: .5rem;
  border-radius: var(--radio-pill);
  background: var(--api);
  flex: 0 0 auto;
}

/* El logo se sirve al alto de la cabecera y con el ancho libre: los logos de
   los clientes son de proporciones muy distintas y recortarlos a una caja fija
   deforma unos y deja los otros diminutos. */
.marca__logo {
  height: 32px;
  width: auto;
  max-width: 180px;
  object-fit: contain;
}

/* El pedido en curso: discreto cuando está vacío, encendido cuando lleva algo.
   No es solo color — el texto cambia de «Tu pedido» al número de productos. */
.cabecera__pedido {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  min-height: var(--toque);
  padding-inline: var(--e3);
  border: 1px solid rgba(255, 255, 255, .25);
  border-radius: var(--radio-pill);
  color: var(--paper);
  text-decoration: none;
  font-size: .875rem;
  white-space: nowrap;
}
.cabecera__pedido:hover { background: rgba(255, 255, 255, .1); color: var(--paper); }

.cabecera__pedido--lleno {
  background: var(--api);
  border-color: var(--api);
  color: var(--tinta);
  font-weight: 700;
}
.cabecera__pedido--lleno:hover { background: #cbe466; color: var(--tinta); }

@media (max-width: 30rem) {
  /* En pantallas estrechas el texto del botón estorba: queda el carrito y el
     número, que es lo que se mira. */
  .cabecera__pedido-texto { font-size: .8125rem; }
  .marca__logo { max-width: 100px; }
}

/* El botón de las tres líneas. Solo en móvil: en escritorio el menú está a la
   vista y un botón que esconde lo que ya se ve sería trabajo de más. */
.cabecera__menu {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: var(--radio);
  background: transparent;
  color: var(--paper);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.cabecera__menu:hover { background: rgba(255, 255, 255, .1); }

.cabecera__acciones-cabeza {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: var(--e3);
  margin-bottom: var(--e2);
  border-bottom: 1px solid rgba(255, 255, 255, .12);
}

.cabecera__acciones-titulo {
  font-family: var(--tipo-display);
  font-weight: 700;
  font-size: 1.125rem;
}

.cabecera__cerrar {
  min-width: 44px;
  min-height: 44px;
  border: 0;
  background: transparent;
  color: var(--paper);
  font-size: 1.75rem;
  line-height: 1;
  cursor: pointer;
}

.cabecera__velo {
  position: fixed;
  inset: 0;
  z-index: 30;
  background: rgba(0, 0, 0, .5);
}

.cabecera__acciones {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--e1);
  /* Cuando no caben, la fila se desplaza en lugar de partirse o de empujar
     la página. `min-width: 0` es imprescindible: sin él, un hijo flexible se
     niega a encoger por debajo de su contenido y desborda igual. */
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}

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

.cabecera__acciones .enlace-icono { flex: 0 0 auto; }

/* -------------------------------------------------------------------------
   MÓVIL: el mismo menú, en un panel lateral.
   La fila horizontal no cabía y había que adivinar que se desplazaba: en
   pantalla salía «Catàleg · La meva llist…» cortado y tres entradas a las que
   no se llegaba nunca.
   ------------------------------------------------------------------------- */
@media (max-width: 47.99rem) {
  .cabecera__acciones {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    z-index: 31;
    width: min(20rem, 84vw);
    margin-left: 0;
    padding: var(--e4);
    /* En columna y con scroll VERTICAL: son seis entradas y en un móvil
       apaisado no caben de largo. */
    flex-direction: column;
    align-items: stretch;
    gap: var(--e1);
    overflow-x: hidden;
    overflow-y: auto;
    background: var(--tinta);
    border-left: 1px solid rgba(255, 255, 255, .12);
    /* Fuera de pantalla hasta que se abre. `translate` y no `display:none`
       para que la transición tenga de dónde salir. */
    transform: translateX(100%);
    transition: transform .2s ease;
  }

  .cabecera__acciones[data-abierto] { transform: translateX(0); }

  .cabecera__acciones .enlace-icono {
    /* Toque de 44 px de alto: se usa con el móvil en la mano, a veces con
       guantes. Y a la izquierda, que es como se leen las listas. */
    display: flex;
    align-items: center;
    /* A la IZQUIERDA: una lista de enlaces se recorre por su borde, y
       centrados obligan a barrer con la vista para encontrar cada uno.
       `.enlace-icono` viene centrado de la fila de escritorio. */
    justify-content: flex-start;
    text-align: left;
    min-height: 44px;
    padding: 0 var(--e2);
    font-size: 1.0625rem;
  }
}

/* ESCRITORIO: la fila de siempre, y ni botón ni cabecera del panel. */
@media (min-width: 48rem) {
  .cabecera__menu,
  .cabecera__acciones-cabeza,
  .cabecera__velo { display: none !important; }
}

.enlace-icono {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-width: var(--toque);
  min-height: var(--toque);
  padding-inline: var(--e2);
  border-radius: var(--radio);
  color: var(--paper);
  text-decoration: none;
  font-size: .875rem;
}
.enlace-icono:hover { background: rgba(255, 255, 255, .1); color: var(--api); }

/* ------------------------------------------------ tira de la semana (firma)
   El elemento por el que se recuerda el portal. Enseña de un vistazo qué días
   te traemos, para cuál estás pidiendo y cuánto te queda para cerrarlo. */
.semana {
  background: var(--bosc-fosc);
  color: var(--paper);
  padding-block: var(--e3);
}

.semana__interior {
  display: flex;
  align-items: center;
  gap: var(--e4);
  flex-wrap: wrap;
}

.semana__dias {
  display: flex;
  gap: var(--e1);
  flex: 1 1 auto;
  /* Con dos semanas de fechas la fila no cabe en un móvil. Se desplaza DENTRO
     de la tira: si no, la que se desplaza es la página entera, y un portal que
     baila en horizontal se siente roto. `min-width: 0` es imprescindible, o el
     hijo flexible se niega a encoger por debajo de su contenido. */
  min-width: 0;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  scroll-snap-type: x proximity;
  padding-bottom: 2px;
}

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

.dia {
  /* No encoge: prefiere desplazarse a apretujarse hasta ser ilegible. */
  flex: 1 0 2.75rem;
  scroll-snap-align: start;
  min-height: var(--toque);
  border: 1px solid rgba(255, 255, 255, .16);
  background: transparent;
  color: rgba(242, 245, 240, .5);
  border-radius: var(--radio);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  cursor: not-allowed;
  padding: var(--e1);
  transition: background .12s ease, border-color .12s ease;
}

.dia__letra {
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
}
.dia__num { font-size: .9375rem; font-weight: 600; line-height: 1; }

/* Un día al que sí repartimos y todavía se puede pedir */
.dia--disponible {
  color: var(--paper);
  border-color: rgba(185, 214, 74, .75);
  cursor: pointer;
}
.dia--disponible:hover { background: rgba(185, 214, 74, .16); }

/* El día para el que se está pidiendo ahora */
.dia--elegido {
  background: var(--api);
  border-color: var(--api);
  color: var(--tinta);
  cursor: pointer;
}

/* Día de reparto que ya ha pasado su corte */
.dia--cerrado { text-decoration: line-through; }

.semana__corte {
  flex: 0 0 auto;
  text-align: right;
  line-height: 1.25;
}

.semana__corte-etiqueta {
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: rgba(242, 245, 240, .6);
  display: block;
}

.semana__corte-valor { font-size: .9375rem; font-weight: 700; }

/* Solo por debajo de 12 h se convierte en reloj: el resto del tiempo dice el
   día y la hora, que informa sin meter prisa. */
.semana__corte--urgente .semana__corte-valor { color: var(--api); }

/* ------------------------------------------------------------ avisos */
.aviso {
  display: flex;
  gap: var(--e3);
  align-items: flex-start;
  padding: var(--e3) var(--e4);
  border-radius: var(--radio);
  border-left: 4px solid var(--bosc);
  background: var(--paper-alt);
  margin-bottom: var(--e4);
}

.aviso--oferta { border-left-color: var(--api); background: var(--api-suau); }
.aviso--urgente { border-left-color: var(--tomaquet); background: var(--tomaquet-suau); }
.aviso__titulo { font-weight: 700; margin: 0 0 var(--e1); }
.aviso__texto { margin: 0; }

/* ------------------------------------------------------------- botones */
.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  min-height: var(--toque);
  padding: var(--e2) var(--e5);
  border: 1px solid transparent;
  border-radius: var(--radio);
  background: var(--bosc);
  color: var(--blanco);
  font-weight: 600;
  font-size: .9375rem;
  text-decoration: none;
  cursor: pointer;
  transition: background .12s ease, transform .06s ease;
}
.boton:hover { background: var(--bosc-fosc); color: var(--blanco); }
.boton:active { transform: translateY(1px); }
.boton[disabled], .boton[aria-disabled="true"] {
  background: var(--linea);
  color: var(--gris);
  cursor: not-allowed;
}

.boton--lleno {
  width: 100%;
}

.boton--secundario {
  background: transparent;
  border-color: var(--linea);
  color: var(--tinta);
}
.boton--secundario:hover { background: var(--paper-alt); color: var(--tinta); }

.boton--accion {
  background: var(--api);
  color: var(--tinta);
}
.boton--accion:hover { background: #a9c93a; color: var(--tinta); }

/* -------------------------------------------------------------- tarjeta */
.tarjeta {
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  box-shadow: var(--sombra);
}

/* --------------------------------------------------------------- camps */
.campo { margin-bottom: var(--e4); }

.campo > label {
  display: block;
  font-size: .8125rem;
  font-weight: 700;
  letter-spacing: .02em;
  margin-bottom: var(--e1);
}

.campo input[type="text"],
.campo input[type="email"],
.campo input[type="password"],
.campo input[type="search"],
.campo input[type="number"],
.campo select,
.campo textarea {
  width: 100%;
  min-height: var(--toque);
  padding: var(--e2) var(--e3);
  background: var(--blanco);
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio);
  color: var(--tinta);
}

.campo input:focus, .campo select:focus, .campo textarea:focus {
  border-color: var(--bosc);
}

.campo__ayuda {
  display: block;
  margin-top: var(--e1);
  font-size: .8125rem;
  color: var(--gris);
}

.campo__error {
  display: block;
  margin-top: var(--e1);
  font-size: .8125rem;
  font-weight: 600;
  color: var(--tomaquet-text);
}

.campo--error input { border-color: var(--tomaquet-text); }

/* --------------------------------------------------------------- entrar */
.entrada {
  min-height: 100vh;
  min-height: 100dvh;
  display: grid;
  grid-template-rows: 1fr auto;
}

.entrada__centro {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e5) var(--e4);
}

.entrada__caja {
  width: 100%;
  max-width: 24rem;
}

.entrada__marca {
  font-family: var(--tipo-display);
  font-weight: 800;
  font-size: 1.75rem;
  letter-spacing: -.03em;
  margin-bottom: var(--e1);
}

.entrada__lema {
  color: var(--gris);
  margin: 0 0 var(--e6);
}

.entrada__pie {
  padding: var(--e4);
  text-align: center;
  color: var(--gris);
  font-size: .8125rem;
}

/* ------------------------------------------------------------ mensajes */
.mensajes { margin-block: var(--e4); }

.mensaje {
  padding: var(--e3) var(--e4);
  border-radius: var(--radio);
  border-left: 4px solid var(--bosc);
  background: var(--paper-alt);
  margin-bottom: var(--e2);
}
.mensaje--success { border-left-color: var(--api); background: var(--api-suau); }
.mensaje--error { border-left-color: var(--tomaquet); background: var(--tomaquet-suau); }
.mensaje--warning { border-left-color: #c8901f; background: #fbf1dc; }

/* ------------------------------------------------------------------ pie */
.pie {
  margin-top: var(--e7);
  padding-block: var(--e5);
  border-top: 1px solid var(--linea);
  color: var(--gris);
  font-size: .8125rem;
}

.contenido { padding-block: var(--e5) var(--e6); }

/* =========================================================================
   Catálogo
   ========================================================================= */

.barra-busqueda {
  display: flex;
  gap: var(--e2);
  align-items: center;
  margin-bottom: var(--e4);
}

.barra-busqueda > .boton { flex: 0 0 auto; white-space: nowrap; }

.barra-busqueda input[type="search"] {
  /* min-width: 0 es lo que le permite ENCOGER: por defecto un elemento flex
     no baja de su ancho de contenido, así que a 320 px el botón se salía de
     la pantalla y arrastraba la página entera. */
  flex: 1 1 auto;
  min-width: 0;
  min-height: var(--toque);
  padding: var(--e2) var(--e3);
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio);
  background: var(--blanco);
  font-size: 1rem;              /* 16px o iOS hace zoom al enfocar */
}

/* Cinta de categorías: se desplaza en horizontal en el móvil */
/* Por dónde se va: «Todo › Verdura › De hoja».
   Discreta a propósito —es orientación, no acción— pero con área de toque de
   44 px en los pasos que se pueden pulsar, que se usa con el móvil en la mano
   y a veces con guantes. */
.miga {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .25rem;
  margin-bottom: var(--e2);
  font-size: .9rem;
}

.miga__paso {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 .25rem;
  color: var(--gris);
  text-decoration: none;
}

.miga__paso:hover,
.miga__paso:focus-visible { text-decoration: underline; }

/* Dónde estás: en negrita y sin enlace, porque pulsarlo no llevaría a ningún
   sitio nuevo. El color NO es la única señal — también cambia el peso. */
.miga__paso--aqui {
  color: var(--tinta);
  font-weight: 600;
}

.miga__flecha { color: var(--linea); }

.cinta {
  display: flex;
  gap: var(--e2);
  overflow-x: auto;
  padding-bottom: var(--e2);
  margin-bottom: var(--e4);
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.cinta::-webkit-scrollbar { height: 4px; }
.cinta::-webkit-scrollbar-thumb { background: var(--linea); border-radius: 2px; }

.pastilla {
  flex: 0 0 auto;
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  padding: var(--e1) var(--e4);
  border: 1px solid var(--linea);
  border-radius: var(--radio-pill);
  background: var(--blanco);
  color: var(--tinta);
  text-decoration: none;
  font-size: .875rem;
  font-weight: 600;
  white-space: nowrap;
}
.pastilla:hover { border-color: var(--bosc); color: var(--bosc); }
.pastilla[aria-current="true"] {
  background: var(--bosc);
  border-color: var(--bosc);
  color: var(--blanco);
}

/* --------------------------------------------------------------- productos */
.rejilla {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--e3);
}

@media (min-width: 34rem) { .rejilla { grid-template-columns: repeat(3, 1fr); } }
/* Cuatro por fila como máximo (petición del usuario): con cinco, las
   tarjetas quedaban estrechas y altas, todo foto y aire. */
@media (min-width: 48rem) { .rejilla { grid-template-columns: repeat(4, 1fr); } }

.producto {
  display: flex;
  flex-direction: column;
  /* Contenedor posicionado de la tarjeta: la estrella de favorito se sitúa
     respecto a ELLA, no respecto a la foto, para poder salir del recuadro de
     la imagen cuando la tarjeta se convierte en fila de lista. */
  position: relative;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
  transition: border-color .12s ease, box-shadow .12s ease;
}
.producto:focus-within, .producto:hover {
  border-color: var(--bosc);
  box-shadow: var(--sombra);
}

.producto--al-carro { border-color: var(--bosc); }

.producto__imagen {
  /* 4:3 y no cuadrada: la foto era el bloque más alto de la tarjeta y con
     muchos productos sin imagen quedaba un cuadrado gris de aire. */
  aspect-ratio: 4 / 3;
  background: var(--paper-alt);
  position: relative;
  overflow: hidden;
}
.producto__imagen img { width: 100%; height: 100%; object-fit: cover; }

.producto__marca {
  position: absolute;
  top: var(--e2);
  left: var(--e2);
  padding: 2px var(--e2);
  border-radius: var(--radio-pill);
  font-size: .625rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  background: var(--api);
  color: var(--tinta);
}

.producto__marca--agotado { background: var(--tomaquet-text); color: var(--blanco); }
/* Lo que acaba de entrar en temporada: el verde de la marca, que es el color
   de «esto está bien», y no el apio, reservado a disponibilidad. */
.producto__marca--nuevo { background: var(--bosc); color: var(--blanco); }
.producto__marca--queda { background: var(--tinta); color: var(--paper); }

.producto__cuerpo {
  padding: var(--e2) var(--e3);
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1 1 auto;
}

/* Dos líneas SIEMPRE (recortado con puntos suspensivos y hueco reservado):
   es lo que hace que todas las tarjetas midan lo mismo y la rejilla no
   baile entre nombres cortos y largos. */
/* Márgenes a cero en todo el texto de la tarjeta: los <p> y el <h3> traían
   los suyos por defecto (el precio, 18px arriba Y abajo) y ese aire sumado
   era el blanco vertical que hacía las tarjetas un tercio más altas. */
.producto__nombre,
.producto__ref,
.producto__precio,
.producto__nota { margin: 0; }

.producto__nombre {
  font-weight: 600;
  line-height: 1.25;
  font-size: .9375rem;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.35em;
}

.producto__ref {
  font-size: .6875rem;
  color: var(--gris);
  letter-spacing: .02em;
}

.producto__precio {
  font-family: var(--tipo-display);
  font-size: 1.125rem;
  font-weight: 700;
  letter-spacing: -.02em;
}

.producto__unidad { font-size: .8125rem; color: var(--gris); font-weight: 400; }

/* El «1,30 €/kg» del embalaje: pequeño y gris, al lado del precio de la
   caja. Es informativo, no compite con el precio que se paga. */
.producto__precio-unidad {
  font-family: var(--tipo-cuerpo);
  font-size: .75rem;
  font-weight: 600;
  color: var(--gris);
  letter-spacing: 0;
  white-space: nowrap;
}

/* Presente aunque esté vacía: reserva su línea y las tarjetas no bailan. */
.producto__nota { font-size: .75rem; color: var(--gris); min-height: 1.1em; }

.producto__pie { padding: 0 var(--e3) var(--e2); }

/* Control de cantidad: pensado para el pulgar */
.cantidad {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio-pill);
  overflow: hidden;
  background: var(--blanco);
}

.cantidad__boton {
  flex: 0 0 auto;
  width: var(--toque);
  min-height: var(--toque);
  border: 0;
  background: transparent;
  color: var(--bosc);
  font-size: 1.25rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.cantidad__boton:hover { background: var(--paper-alt); }
.cantidad__boton[disabled] { color: var(--linea); cursor: not-allowed; }

.cantidad__valor {
  flex: 1 1 auto;
  min-width: 2.5rem;
  border: 0;
  text-align: center;
  font-weight: 700;
  font-size: 1rem;
  background: transparent;
  -moz-appearance: textfield;
}
.cantidad__valor::-webkit-outer-spin-button,
.cantidad__valor::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* El anillo de foco global no cabe DENTRO de la pastilla (overflow:hidden la
   recorta y quedaban dos franjas verdes a los lados del número): el foco del
   número lo enseña la pastilla ENTERA, y los botones ± llevan el suyo por
   dentro. Sigue habiendo indicador visible en todos los casos — quitarlo sin
   sustituto dejaría al teclado a ciegas. */
.cantidad__valor:focus-visible {
  outline: none;
  box-shadow: none;
}

/* El halo lleva DOS anillos, como el foco global: el apio solo da 1,64:1
   sobre blanco y con eso el foco prácticamente no se ve — justo en el control
   que más se usa del portal. El anillo exterior de tinta es el que cumple el
   3:1 que pide WCAG para un indicador de foco; el apio se queda por dentro
   como color de la casa. Es el mismo apaño que ya explica el bloque del foco
   global unas líneas más arriba. */
.cantidad:focus-within {
  border-color: var(--bosc);
  box-shadow: 0 0 0 3px var(--api), 0 0 0 5px var(--tinta);
}

.cantidad__boton:focus-visible {
  outline: none;
  box-shadow: inset 0 0 0 3px var(--api), inset 0 0 0 5px var(--tinta);
}

.anadir {
  width: 100%;
  min-height: var(--toque);
  border: 1px solid var(--bosc);
  border-radius: var(--radio-pill);
  background: var(--blanco);
  color: var(--bosc);
  font-weight: 700;
  cursor: pointer;
}
.anadir:hover { background: var(--bosc); color: var(--blanco); }

/* ------------------------------------------------------------- barra carro */
.barra-carro {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 30;
  background: var(--tinta);
  color: var(--paper);
  padding: var(--e3) 0 calc(var(--e3) + env(safe-area-inset-bottom));
  box-shadow: 0 -2px 16px rgba(18, 33, 26, .18);
  transform: translateY(110%);
  visibility: hidden;
  transition: transform .18s ease, visibility .18s;
}
.barra-carro--visible { transform: translateY(0); visibility: visible; }

/* En escritorio el pedido YA es la columna derecha: la barra sobra, y su
   «Ver el pedido» era un botón roto — abría el velo por encima de todo
   (el cajón solo existe por debajo de tableta) y no pasaba nada más. */
@media (min-width: 62rem) {
  .barra-carro { display: none; }
}

.barra-carro__interior {
  display: flex;
  align-items: center;
  gap: var(--e4);
}

.barra-carro__resumen { flex: 1 1 auto; line-height: 1.2; }
.barra-carro__lineas { font-size: .8125rem; color: rgba(242,245,240,.7); }
.barra-carro__total {
  font-family: var(--tipo-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -.02em;
}

/* Con la barra fija, el final de la página queda tapado sin este hueco.
   La clase la escribe `inicio.html` como `con-panel`: cuando esto decía
   `con-carro` la regla no se aplicaba NUNCA, y en móvil los últimos 68 px
   quedaban debajo de la barra — el pie, que es donde está el teléfono que el
   portal ofrece una y otra vez («llámanos»). */
body.con-panel .contenido { padding-bottom: 6rem; }

/* ------------------------------------------------------------------ cesta */
.linea-cesta {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--e2) var(--e3);
  padding: var(--e3) 0;
  border-bottom: 1px solid var(--linea);
  align-items: center;
}

.linea-cesta__nombre { font-weight: 600; }
.linea-cesta__detalle { font-size: .8125rem; color: var(--gris); }
.linea-cesta__importe { font-weight: 700; text-align: right; white-space: nowrap; }
.linea-cesta__control { grid-column: 1 / -1; max-width: 11rem; }

@media (min-width: 40rem) {
  .linea-cesta { grid-template-columns: 1fr 11rem auto; }
  .linea-cesta__control { grid-column: auto; }
}

.totales {
  display: flex;
  justify-content: space-between;
  padding: var(--e2) 0;
}
.totales--gran {
  font-family: var(--tipo-display);
  font-size: 1.375rem;
  font-weight: 700;
  letter-spacing: -.02em;
  border-top: 2px solid var(--tinta);
  margin-top: var(--e2);
  padding-top: var(--e3);
}

/* ---------------------------------------------------------------- pedidos */

/* Cada pedido es una tarjeta y no una fila de tabla: en el móvil una fila con
   seis datos se parte por donde quiere, y aquí hay que poder leer de un
   vistazo en qué punto está y repetirlo. */
.lista-pedidos { list-style: none; margin: 0; padding: 0; }

.pedido-tarjeta {
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: var(--e4);
  margin-bottom: var(--e3);
}

.pedido-tarjeta__principal {
  display: flex;
  align-items: center;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e3);
}

.pedido-tarjeta__ref {
  font-family: var(--tipo-display);
  font-weight: 700;
  font-size: 1.0625rem;
  color: var(--tinta);
  text-decoration: none;
}
.pedido-tarjeta__ref:hover { color: var(--bosc); text-decoration: underline; }

.pedido-tarjeta__datos {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2) var(--e5);
  font-size: .875rem;
}

.pedido-tarjeta__dato { display: flex; flex-direction: column; }

.pedido-tarjeta__etiqueta {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gris);
}

.pedido-tarjeta__espera {
  margin: var(--e3) 0 0;
  font-size: .8125rem;
  color: var(--tomaquet-text);
  font-weight: 600;
}

.pedido-tarjeta__pie {
  display: flex;
  align-items: baseline;
  gap: var(--e2);
  margin-top: var(--e3);
  padding-top: var(--e3);
  border-top: 1px solid var(--linea);
}

.pedido-tarjeta__importe {
  font-family: var(--tipo-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -.02em;
}

/* El botón de repetir se va a la derecha: es la acción, y la acción va al
   final de la línea que se lee. */
.pedido-tarjeta__repetir { margin-left: auto; }

.boton--pequeno {
  min-height: 36px;
  padding: var(--e1) var(--e3);
  font-size: .8125rem;
}

.estado {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--e3);
  border-radius: var(--radio-pill);
  font-size: .75rem;
  font-weight: 700;
  letter-spacing: .02em;
  background: var(--paper-alt);
  color: var(--tinta-suave);
  white-space: nowrap;
}
/* Las claves salen de `portal/services/estados.py` y se pegan tal cual detrás
   de `estado--`. Si cambian allí, cambian aquí: la plantilla escribía
   `estat--rebuda` mientras el CSS definía `.estado--recibida`, así que el
   estado del pedido llevaba toda la vida saliendo sin color. */
.estado--recibido { background: var(--api-suau); color: var(--bosc-fosc); }
.estado--en-preparacion { background: #fbf1dc; color: #7a5a10; }
.estado--preparado { background: var(--api); color: var(--tinta); }
.estado--facturado { background: var(--paper-alt); color: var(--tinta-suave); }
.estado--cancelado { background: var(--tomaquet-suau); color: var(--tomaquet-text); }
.estado--pagado { background: var(--api-suau); color: var(--bosc-fosc); }
.estado--pendiente { background: var(--tomaquet-suau); color: var(--tomaquet-text); }

.estimado { font-style: italic; color: var(--gris); }

.espera {
  display: inline-flex;
  align-items: center;
  gap: var(--e1);
  font-size: .75rem;
  font-weight: 700;
  color: var(--tomaquet-text);
}

/* ------------------------------------------------------------------ vacio */
.vacio {
  text-align: center;
  padding: var(--e7) var(--e4);
  color: var(--gris);
}
.vacio__titulo {
  font-family: var(--tipo-display);
  font-size: 1.25rem;
  color: var(--tinta);
  margin-bottom: var(--e2);
}

/* El nombre de la empresa sale de la base de datos y puede ser largo. Se deja
   partir en dos líneas dentro de la cabecera, pero nunca empujar al menú
   fuera de la pantalla. */
.marca {
  min-width: 0;
  line-height: 1.15;
  /* Sin partirse en cuatro líneas: el `max-width: 45%` de antes existía para
     dejarle sitio al menú, y el menú ya no está en la fila —en móvil vive en
     el panel lateral—. En pantallas muy estrechas se recorta con puntos
     suspensivos, que se lee mucho mejor que «Horta / Pla / de / Munt». */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}


/* Tablas anchas: que desborde el componente, nunca la página (1.4.10) */
.tabla-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}
.tabla-scroll > table { min-width: 22rem; }

/* --- La tabla del portal -------------------------------------------------

   Las tablas del portal llevaban su estilo repetido celda a celda con
   `style=`: el mismo borde escrito quince veces en cada plantilla, imposible
   de cambiar en un sitio y distinto en cada pantalla. Esto es esa tabla. */
.tabla {
  width: 100%;
  border-collapse: collapse;
  margin-top: var(--e4);
}

.tabla th {
  padding: var(--e2) var(--e2) var(--e2) 0;
  text-align: left;
  border-bottom: 2px solid var(--tinta);
  font-size: .8125rem;
  letter-spacing: .02em;
}

.tabla td {
  padding: var(--e3) var(--e2) var(--e3) 0;
  border-bottom: 1px solid var(--linea);
  vertical-align: top;
}

.tabla tbody tr:hover { background: var(--paper); }

.tabla__derecha { text-align: right; }
/* Los números no se parten de línea y comparten ancho de dígito (el
   `tabular-nums` del body), así que las columnas de € quedan alineadas. */
.tabla__numero { white-space: nowrap; }

/* --- Ficha (pedido, factura) --------------------------------------------- */
.ficha-cabecera {
  display: flex;
  align-items: center;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-bottom: var(--e4);
}

.ficha-datos {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));
  gap: var(--e3) var(--e5);
  padding: var(--e4);
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  margin-bottom: var(--e5);
}

.ficha-dato { display: flex; flex-direction: column; gap: 2px; }

.ficha-dato__etiqueta {
  font-size: .6875rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--gris);
}

.ficha-dato__valor { font-weight: 600; }

.ficha-acciones {
  display: flex;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-top: var(--e6);
}

/* --- Totales de una ficha ------------------------------------------------ */
.resumen-totales {
  margin-left: auto;
  margin-top: var(--e5);
  max-width: 20rem;
}

.resumen-totales__fila {
  display: flex;
  justify-content: space-between;
  gap: var(--e5);
  padding: var(--e2) 0;
  border-bottom: 1px solid var(--linea);
}

.resumen-totales__fila--gran {
  border-bottom: 0;
  border-top: 2px solid var(--tinta);
  margin-top: var(--e1);
  padding-top: var(--e3);
  font-family: var(--tipo-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -.02em;
}

.tarjeta--nota {
  padding: var(--e4);
  margin-top: var(--e5);
  border-left: 3px solid var(--api);
}

.sin-margen { margin: 0; }

/* Miniatura del producto en las tablas: reconocer por la foto es más rápido
   que leer veinte nombres parecidos. */
.tabla__miniatura { width: 44px; padding-right: 0; }
.tabla__miniatura img {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: var(--radio);
}

.tabla__cantidad { width: 8rem; }

/* La casilla de elegir factura: 44 px de toque como todo lo demás. */
.tabla__marcar { width: 2.5rem; }
.tabla__marcar input {
  width: 20px;
  height: 20px;
  cursor: pointer;
}

.campo-cantidad {
  width: 100%;
  min-height: var(--toque);
  padding: var(--e2);
  text-align: center;
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio);
  background: var(--blanco);
}

.barra-acciones {
  display: flex;
  gap: var(--e2);
  flex-wrap: wrap;
  margin: var(--e4) 0 var(--e2);
}

/* El logo en la pantalla de acceso: aquí hay sitio, así que va el grande.
   Sin altura fija —cada empresa tiene el suyo con su proporción—, solo un
   tope para que un logo apaisado no empuje el formulario fuera de la vista. */
.entrada__marca--logo { margin-bottom: var(--e3); }
.entrada__marca--logo img {
  max-width: 100%;
  max-height: 80px;
  width: auto;
  margin-inline: auto;
  object-fit: contain;
}

/* ------------------------------------------------------------------ perfil */
.perfil__cabeza {
  display: flex;
  align-items: center;
  gap: var(--e4);
  margin-bottom: var(--e4);
}

.perfil__datos { flex: 1 1 auto; min-width: 0; }
.perfil__datos .campo { margin-bottom: 0; }

/* La foto, redonda y con la inicial de respaldo: un icono genérico repetido
   no distingue a nadie en la lista de compañeros. */
.perfil__foto,
.perfil__inicial {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 50%;
  background: var(--bosc);
  color: var(--blanco);
  font-family: var(--tipo-display);
  font-weight: 700;
}

.perfil__foto { width: 72px; height: 72px; font-size: 1.75rem; }
.perfil__inicial { width: 28px; height: 28px; font-size: .8125rem; }

.perfil__foto img,
.perfil__inicial img { width: 100%; height: 100%; object-fit: cover; }

.perfil__gente { list-style: none; margin: 0; padding: 0; }
.perfil__gente li {
  display: flex;
  align-items: center;
  gap: var(--e2);
  padding: var(--e1) 0;
}

/* El campo de fichero no acepta el mismo tratamiento que un input de texto:
   el navegador pinta su propio botón dentro. */
.campo input[type="file"] {
  width: 100%;
  min-height: var(--toque);
  padding: var(--e2);
  background: var(--blanco);
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio);
}

/* =========================================================================
   Panel del pedido, vistas del catálogo y favoritos
   =========================================================================

   El panel sustituye a la barra flotante que solo contaba líneas. Ahora el
   pedido está SIEMPRE a la vista, con lo que llevas y el día de entrega: era
   el sitio natural del calendario, que antes ocupaba la franja superior de
   todas las pantallas sin ser lo que se mira al comprar.
   ========================================================================= */

/* La página se parte en catálogo + panel a partir de tableta. Por debajo, el
   panel baja al final y se abre desde la barra inferior. */
.con-panel .envoltorio--tienda {
  display: grid;
  gap: var(--e5);
  grid-template-columns: 1fr;
}

@media (min-width: 62rem) {
  .con-panel .envoltorio--tienda {
    grid-template-columns: minmax(0, 1fr) 20rem;
    align-items: start;
  }
  /* Pegajoso SOLO donde el panel es la columna lateral del catálogo
     (`con-panel`). La regla era global y se colaba en la cesta: «Tu pedido»
     se quedaba clavado y «Cuándo y dónde» se deslizaba por debajo. */
  .con-panel .panel {
    position: sticky;
    /* Por debajo de la cabecera del sitio, que también es pegajosa: con
       top:0 el panel se metía debajo y se comía su propio título. */
    top: calc(var(--alto-cabecera) + var(--e3));
    max-height: calc(100vh - var(--alto-cabecera) - var(--e5));
    overflow-y: auto;
  }
}

.panel {
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
}

/* La barra de cerrar solo existe cuando el panel es un cajón: en escritorio,
   donde es una columna fija de la página, no hay nada que cerrar. */
.panel__barra { display: none; }

.panel__cerrar {
  width: var(--toque);
  height: var(--toque);
  border: 0;
  background: none;
  font-size: 1.5rem;
  line-height: 1;
  color: var(--gris);
  cursor: pointer;
}

/* --- El pedido como cajón (por debajo de tableta) ------------------------

   SOLO en el catálogo (`body.con-panel`), que es la única pantalla donde el
   panel es un cajón con su botón para abrirlo. En la CESTA el mismo bloque es
   contenido de la página —las líneas, las cantidades y los totales— y esta
   regla lo dejaba con `visibility: hidden` sin nada que lo abriera: en móvil y
   en tableta, la pantalla donde se confirma el pedido no enseñaba NI UN
   producto ni el total. Solo se veía a partir de 1200 px. */
@media (max-width: 61.99rem) {
  body.con-panel .panel {
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    max-height: 85vh;
    overflow-y: auto;
    border-radius: var(--radio) var(--radio) 0 0;
    border-bottom: 0;
    box-shadow: var(--sombra-alta);
    padding-bottom: env(safe-area-inset-bottom);
    /* `visibility` además del `transform`: sin ella el panel cerrado sigue
       siendo tabulable y el teclado se pierde dentro de algo que no se ve. */
    transform: translateY(101%);
    visibility: hidden;
    transition: transform .2s ease, visibility .2s;
  }

  body.con-panel .panel--abierto {
    transform: translateY(0);
    visibility: visible;
  }

  body.con-panel .panel__barra {
    display: flex;
    justify-content: flex-end;
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--blanco);
    border-bottom: 1px solid var(--linea);
  }
}

.velo {
  position: fixed;
  inset: 0;
  z-index: 35;
  background: rgba(18, 33, 26, .5);
}
.velo[hidden] { display: none; }

/* Con el cajón abierto, la página de debajo no se mueve. */
body.sin-scroll { overflow: hidden; }

/* --- Diálogo (anular el pedido) ----------------------------------------- */

.dialogo {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--e4);
  background: rgba(18, 33, 26, .5);
}
.dialogo[hidden] { display: none; }

.dialogo__caja {
  width: 100%;
  max-width: 28rem;
  max-height: 90vh;
  overflow-y: auto;
  padding: var(--e5);
  background: var(--blanco);
  border-radius: var(--radio);
  box-shadow: var(--sombra-alta);
}

/* Anular no se deshace: el botón lo dice con su color, y además con el texto
   del diálogo. El rojo es el de urgencia de la paleta, que sobre blanco pasa
   de 4,5:1 con texto blanco encima. */
.boton--peligro {
  background: var(--tomaquet-text);
  border-color: var(--tomaquet-text);
  color: var(--blanco);
}
.boton--peligro:hover {
  background: #8f2b11;
  border-color: #8f2b11;
  color: var(--blanco);
}

.panel__seccion { padding: var(--e3) var(--e4); border-bottom: 1px solid var(--linea); }

/* El título se queda arriba mientras se recorren las líneas: con un pedido
   largo, el panel scrollea por dentro y sin esto se pierde de vista qué es
   lo que se está mirando. Solo en el catálogo (`con-panel`), que es donde el
   panel scrollea por dentro: en la cesta scrollea la página entera y este
   sticky dejaba el título clavado tapando lo que subía. */
.con-panel .panel__cuerpo > .panel__seccion:first-child {
  position: sticky;
  top: 0;
  z-index: 2;
  background: var(--blanco);
}

.panel__titulo { font-family: var(--tipo-display); font-size: 1.125rem; margin: 0; }
.panel__etiqueta { display: block; font-size: .8125rem; color: var(--gris); margin-bottom: .25rem; }

.panel__select {
  width: 100%;
  min-height: 44px;
  padding: 0 var(--e3);
  border: 1px solid var(--linea-camp);
  border-radius: var(--radio);
  background: var(--blanco);
  font: inherit;
  color: var(--tinta);
}

.panel__corte { margin: .5rem 0 0; font-size: .8125rem; color: var(--gris); }
.panel__corte--urgente { color: var(--tomaquet-text); font-weight: 700; }

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

.panel__linea {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: .25rem var(--e3);
  align-items: center;
  padding: var(--e3) var(--e4);
  border-bottom: 1px solid var(--linea);
}

.panel__linea-nombre { grid-column: 1 / -1; font-weight: 600; font-size: .9375rem; }
.panel__linea-importe { font-weight: 700; text-align: right; }

/* El control de cantidad del panel es más estrecho que el de la tarjeta, pero
   NO más pequeño de tocar: los botones siguen siendo de 44 px. */
.cantidad--pequena { max-width: 8.5rem; }

.panel__totales { padding: var(--e3) var(--e4); }
.panel__total-fila { display: flex; justify-content: space-between; padding: .125rem 0; }
.panel__total-fila--gran {
  margin-top: .25rem;
  padding-top: .5rem;
  border-top: 2px solid var(--tinta);
  font-weight: 800;
  font-size: 1.0625rem;
}

.panel__aviso {
  margin: 0;
  padding: var(--e3) var(--e4);
  background: var(--tomaquet-suau);
  color: var(--tomaquet-text);
  font-size: .875rem;
  font-weight: 600;
}

.panel__pie { padding: var(--e4); }
.boton--ancho { width: 100%; justify-content: center; }

/* La cesta no reserva: recordatorio pequeño bajo el botón de tramitar. */
.panel__reserva {
  margin: var(--e2) 0 0;
  font-size: .8125rem;
  color: var(--gris);
  text-align: center;
}

/* Aviso de escasez en una línea del carrito: ocupa su fila entera. */
.panel__linea-aviso {
  grid-column: 1 / -1;
  margin: 0;
  font-size: .8125rem;
  font-weight: 600;
  color: var(--tomaquet-text);
}

/* --- La cesta: líneas + «cuándo y dónde», scrolleando al unísono -------- */

.cesta-grid {
  display: grid;
  gap: var(--e6);
  grid-template-columns: 1fr;
  /* Sin esto, un nombre de producto largo estira la columna del panel y
     empuja el formulario fuera. */
  align-items: start;
}

@media (min-width: 62rem) {
  .cesta-grid { grid-template-columns: minmax(0, 1fr) 24rem; }
}

/* --- Resumen de lo que iría a lista de espera (diálogo de la cesta) ----- */

.plan-espera {
  list-style: none;
  margin: var(--e4) 0;
  padding: 0;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
}

.plan-espera__fila {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--e2);
  padding: var(--e3) var(--e4);
  background: var(--tomaquet-suau);
}

.plan-espera__fila + .plan-espera__fila { border-top: 1px solid var(--linea); }

.plan-espera__nombre { font-weight: 700; }

.plan-espera__detalle { color: var(--tomaquet-text); font-size: .875rem; }

.panel__vacio { padding: var(--e5) var(--e4); text-align: center; color: var(--gris); }
.panel__vacio-pista { font-size: .875rem; }

/* --- Conmutador de vista y favoritos ----------------------------------- */

.vista-barra {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--e2);
  margin-bottom: var(--e3);
}

.vista-barra__grupo { display: inline-flex; border: 1px solid var(--linea-camp); border-radius: var(--radio); overflow: hidden; }

.vista-barra__boton {
  min-height: 40px;
  padding: 0 var(--e3);
  border: 0;
  background: var(--blanco);
  color: var(--tinta);
  font: inherit;
  cursor: pointer;
}

.vista-barra__boton[aria-pressed="true"] { background: var(--bosc); color: var(--blanco); }

/* La estrella vive sobre la imagen en cuadrícula y al final de la fila en
   lista. En las dos es un botón de 44 px: se toca con el pulgar. */
.favorito {
  position: absolute;
  /* .5rem y no .25rem: con la estrella pegada al borde, el área ampliada de
     44 px de abajo se SALÍA de la tarjeta por arriba y por la derecha, y ahí
     el toque no llegaba al botón — de los cuatro cuadrantes prometidos solo
     respondía uno. Con 8 px de separación los 44 caben dentro. Comprobado con
     `elementFromPoint` en las cuatro esquinas, que es la única forma de verlo:
     el rect del botón sigue midiendo 28 y no dice nada del área real. */
  top: .5rem;
  right: .5rem;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .9);
  color: var(--gris);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

/* El círculo se ve pequeño pero se toca grande: el área sensible se estira
   con un pseudo-elemento hasta los 44 px que pide la norma, sin que la
   estrella tape la foto del producto. */
.favorito::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 44px;
  height: 44px;
  transform: translate(-50%, -50%);
}

/* Más oscuro que el #c9971a de antes, que sobre el círculo casi blanco daba
   2,60:1 — por debajo del 3:1 que pide un objeto gráfico. */
.favorito[aria-pressed="true"] { color: #9a6f00; }

/* --- Vista de lista ----------------------------------------------------- */

/* La lista NO es la cuadrícula estrechada: es otra forma de mirar lo mismo.
   La cuadrícula se recorre con la vista, saltando de foto en foto; la lista se
   recorre con el dedo de arriba abajo buscando un nombre. Eso cambia el
   diseño entero:

     · una sola caja con las filas separadas por una línea fina, en vez de un
       montón de tarjetas sueltas — un apilado de recuadros no se lee como una
       lista, se lee como tarjetas mal puestas;
     · el precio en columna propia y alineado a la derecha, para poder
       compararlo bajando la vista, que es lo que se hace en una lista;
     · el nombre solo en su línea, y debajo lo pequeño (referencia, marca,
       nota) — la jerarquía de la tarjeta, en horizontal.

   La tipografía y el color son los mismos que en cuadrícula a propósito: es
   la misma tienda vista de otra manera, no otra pantalla. */
.rejilla--lista {
  display: block;
  background: var(--blanco);
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
}

/* Cinco columnas: franja de estado · foto · qué es · favorito · cuánto llevo.
   El orden de las celdas es el del HTML, así que la estrella va entre el
   cuerpo y el pie.

   NO se usa `display: contents` en el cuerpo: al soltar sus hijos como celdas
   sueltas, un producto con nota («de 5 en 5», «mínimo 2») metía una celda de
   más y descolocaba toda la fila. El cuerpo es una celda y se ordena dentro. */
.rejilla--lista .producto {
  display: grid;
  /* Las dos últimas columnas van a MEDIDA FIJA, no `auto`: con `auto`, la
     fila de un producto que está en el pedido (control de ±) y la de uno que
     no (botón «Añadir») tienen anchos distintos, y entonces la columna del
     precio termina en un sitio distinto en cada fila. Alineados en columna es
     justo lo que hace comparable una lista; desalineados, es un montón de
     filas parecidas. */
  grid-template-columns: 3rem minmax(0, 1fr) 44px 9.5rem;
  gap: 0 var(--e3);
  align-items: center;
  /* Fuera la caja individual: la caja es la lista entera, y aquí solo hace
     falta la línea que separa una fila de la siguiente. */
  margin: 0;
  border: 0;
  border-bottom: 1px solid var(--linea);
  border-radius: 0;
  /* La franja de estado, que en la cuadrícula es el borde verde de la
     tarjeta. Aquí un borde alrededor volvería a dibujar recuadros, así que se
     queda en una franja a la izquierda: es la misma señal, en el sitio donde
     se recorre la lista. */
  border-left: 3px solid transparent;
  padding: var(--e2) var(--e3);
  min-height: 3.75rem;
}
.rejilla--lista .producto:last-child { border-bottom: 0; }

/* En una lista el hover marca la FILA, no dibuja una caja: un borde verde
   alrededor de una fila la saca de la columna y hace saltar a las de abajo. */
.rejilla--lista .producto:hover,
.rejilla--lista .producto:focus-within {
  background: var(--paper-alt);
  box-shadow: none;
  border-color: var(--linea);
}
.rejilla--lista .producto--al-carro {
  border-left-color: var(--bosc);
  background: rgba(185, 214, 74, .10);   /* el apio, apenas insinuado */
}
.rejilla--lista .producto--al-carro:hover,
.rejilla--lista .producto--al-carro:focus-within {
  background: rgba(185, 214, 74, .18);
  border-left-color: var(--bosc);
}

.rejilla--lista .producto__imagen {
  width: 3rem;
  height: 3rem;
  aspect-ratio: auto;
  border-radius: var(--radio);
  flex: none;
}

/* El cuerpo en dos líneas, con el precio en su propia columna a la derecha.
   Se colocan las celdas una a una porque el HTML es el mismo que el de la
   cuadrícula —donde el orden es nombre, marca, referencia, precio, nota— y
   agrupar lo pequeño en un `<div>` obligaría a reordenar la tarjeta, que está
   bien como está. */
.rejilla--lista .producto__cuerpo {
  padding: 0;
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr) auto;
  align-items: center;
  column-gap: var(--e2);
  row-gap: 1px;
  min-width: 0;
}

.rejilla--lista .producto__nombre {
  grid-column: 1 / -2;
  grid-row: 1;
  font-size: .9375rem;
  /* Una sola línea con puntos suspensivos: en lista manda la densidad, y un
     nombre de dos líneas descuadra la columna del precio. */
  display: block;
  min-height: 0;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

.rejilla--lista .producto__ref { grid-column: 1; grid-row: 2; }

/* La marca («Quedan 7,97», «Agotado», «Acaba de entrar») deja de flotar sobre
   la foto —que en lista mide 3 rem y quedaba tapada por un texto recortado e
   ilegible— y baja a la segunda línea, junto a la referencia. */
.rejilla--lista .producto__marca {
  position: static;
  grid-column: 2;
  grid-row: 2;
  justify-self: start;
}

.rejilla--lista .producto__nota {
  grid-column: 3;
  grid-row: 2;
  min-height: 0;
  min-width: 0;
  white-space: nowrap;
  text-overflow: ellipsis;
  overflow: hidden;
}

/* El precio ocupa las dos líneas, a la derecha y con un ancho mínimo: es lo
   que hace que los precios queden en columna al bajar la vista. Mantiene el
   tamaño y la tipografía de la cuadrícula — es el dato por el que se elige, y
   encogerlo en la lista lo convertía en un detalle más. */
.rejilla--lista .producto__precio {
  grid-column: 4;
  grid-row: 1 / span 2;
  justify-self: end;
  text-align: right;
  min-width: 6.5rem;
  white-space: nowrap;
  line-height: 1.15;
}
/* El €/kg del embalaje baja a su propia línea, debajo del precio de la caja:
   en horizontal los dos números seguidos se leían como uno solo. */
.rejilla--lista .producto__precio-unidad { display: block; }

/* Los dos estados del pie ocupan lo MISMO: así la fila no cambia de forma al
   añadir un producto, y la columna del precio no se mueve de sitio a mitad de
   la lista. */
.rejilla--lista .producto__pie { padding: 0; min-width: 0; }
.rejilla--lista .cantidad { width: 100%; }
.rejilla--lista .cantidad__valor { min-width: 2.5rem; }
.rejilla--lista .anadir { width: 100%; }

/* En lista la estrella deja de flotar sobre la foto y ocupa su propia celda,
   que es lo que el diseño decía desde el principio. */
.rejilla--lista .favorito {
  position: static;
  background: none;
  width: 44px;
  height: 44px;
  font-size: 1.25rem;
}
.rejilla--lista .favorito::after { content: none; }

@media (max-width: 40rem) {
  .rejilla--lista .producto { grid-template-columns: 2.5rem minmax(0, 1fr) auto auto; }
  .rejilla--lista .producto__imagen { width: 2.5rem; height: 2.5rem; }
  .rejilla--lista .favorito { width: 40px; height: 40px; }
}

/* En el teléfono no caben las cuatro columnas: con 343 px útiles, la foto, la
   estrella y el control se llevan 232 y al nombre le quedan 111 — menos de lo
   que ocupa el precio, así que el nombre colapsaba a cero y no se leía.

   Así que la fila pasa a dos líneas: arriba lo que identifica el producto,
   abajo el precio y la acción. La foto ocupa las dos para que el bloque se lea
   como una unidad. Sigue siendo bastante más denso que la cuadrícula, que es
   para lo que se cambia a lista. */
@media (max-width: 32rem) {
  /* La estrella baja a la fila de las acciones, con el ±, y deja de ocupar
     una columna arriba. No es un capricho de composición: MEDIDO a 390 px, la
     línea de la referencia necesita 229 px (37 de la referencia, 110 de la
     marca, 66 del precio y los huecos) y con la estrella arriba solo quedaban
     210 — el precio se montaba encima de la marca. Sin ella caben 261.

     Además queda mejor agrupado: a la izquierda el producto (su foto y si es
     favorito) y a la derecha lo que se hace con él. */
  .rejilla--lista .producto {
    grid-template-columns: 44px minmax(0, 1fr);
    grid-template-areas:
      "foto     cuerpo"
      "favorito pie";
    row-gap: var(--e2);
    align-items: start;
  }
  .rejilla--lista .producto__imagen { grid-area: foto; align-self: start; }
  .rejilla--lista .producto__cuerpo { grid-area: cuerpo; align-self: center; }
  .rejilla--lista .favorito { grid-area: favorito; align-self: center; justify-self: start; }

  /* Aquí no hay sitio para una columna de precios propia: el nombre se
     quedaba en un palmo. El precio sube a la línea de la referencia, pegado a
     la derecha — sigue siendo el número que más pesa de la línea, y así la
     fila baja de cuatro renglones a dos.

     No es un detalle de estética: con el precio en su propio renglón la fila
     medía 133 px, tanto como una tarjeta de la cuadrícula, o sea que cambiar
     a lista no servía para lo único que sirve, ver más productos de una vez. */
  .rejilla--lista .producto__cuerpo {
    grid-template-columns: auto auto minmax(0, 1fr);
    row-gap: 2px;
  }
  .rejilla--lista .producto__nombre { grid-column: 1 / -1; grid-row: 1; }
  .rejilla--lista .producto__ref { grid-column: 1; grid-row: 2; }
  .rejilla--lista .producto__marca { grid-column: 2; grid-row: 2; }
  .rejilla--lista .producto__precio {
    grid-column: 3;
    grid-row: 2;
    justify-self: end;
    text-align: right;
    min-width: 0;
    font-size: 1rem;
    white-space: nowrap;
  }
  .rejilla--lista .producto__precio-unidad { display: inline; }
  /* La nota solo aparece cuando hay algo que decir («de 5 en 5», «mínimo 2»);
     el resto del tiempo no ocupa renglón. */
  .rejilla--lista .producto__nota {
    grid-column: 1 / -1;
    grid-row: 3;
    white-space: normal;
  }
  .rejilla--lista .producto__nota:empty { display: none; }

  /* El control se pega a la derecha en vez de estirarse de lado a lado: con
     44 px de botón, una pastilla de punta a punta invita a tocar el «+» sin
     mirar cuál es. */
  .rejilla--lista .producto__pie {
    grid-area: pie;
    display: flex;
    justify-content: flex-end;
  }
  /* Los dos estados miden lo mismo también aquí: un «Añadir» de punta a punta
     al lado de un ± de 9,5 rem hace que la fila cambie de forma al añadir el
     producto, y la lista da un salto bajo el dedo. */
  .rejilla--lista .cantidad,
  .rejilla--lista .anadir { width: 9.5rem; }
}

/* Quitar del pedido: discreto, porque no es la acción que se busca, pero con
   sus 44 px de toque como todo lo demás. */
.panel__quitar {
  width: 44px;
  height: 44px;
  border: 0;
  background: none;
  color: var(--gris);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 50%;
}

.panel__quitar:hover { background: var(--tomaquet-suau); color: var(--tomaquet-text); }

.panel__linea { grid-template-columns: 1fr auto auto; }
