/* =====================================================================
   publico/assets/layout.css
   ---------------------------------------------------------------------
   LAS PIEZAS COMPARTIDAS QUE YA ESTÁN EN EL MANUAL.

   Cabecera, menú móvil, pie y la tarjeta de producto. La tarjeta vive
   acá y no en publico.css ni en portada.css porque la usan las dos: el
   catálogo y la portada. Un solo archivo, una sola tarjeta.

   Todo acá consume tokens semánticos de tema.css — --ink, --bg-elev,
   --accent, --dur-ui — y no declara ni un hex propio. Si ves un
   #RRGGBB en este archivo, está mal.

   POR QUÉ ESTÁ SEPARADO DE publico.css
   ------------------------------------
   publico.css es de la tienda y la ficha, y todavía está en el sistema
   viejo (Space Grotesk, --tinta, --papel). La cabecera y el pie ya
   están en el manual. Dos etapas distintas de la migración en un mismo
   archivo obligan a leer 600 líneas para saber cuál de los dos
   sistemas manda en cada regla.

   Cuando la tienda y la ficha se migren, publico.css se reescribe
   contra estos mismos tokens y este archivo se queda igual.

   ORDEN DE CARGA:  tema.css → layout.css → publico.css
   ===================================================================== */

/* EL FONDO NUNCA ES LISO.
   Papel milimetrado de dos niveles, relación 1:4 — línea menor cada
   24px, mayor cada 96 — y siempre por debajo del 10% de opacidad. Es
   textura: se percibe, no se mira. Si compite con el texto, está
   demasiado fuerte.

   Va en <body> y no en cada sección para que sea continuo: una
   cuadrícula que arranca y se corta con cada banda deja de leerse como
   papel y pasa a leerse como un error de maquetación.

   Va en background-color + background-image y NUNCA en el atajo
   `background`. El atajo borra la imagen, y esa es exactamente la
   forma en que esto se rompió la primera vez. */
body{
  margin:0;
  background-color:var(--bg);
  background-image:
    repeating-linear-gradient(0deg,  var(--grid-major) 0 1px, transparent 1px 96px),
    repeating-linear-gradient(90deg, var(--grid-major) 0 1px, transparent 1px 96px),
    repeating-linear-gradient(0deg,  var(--grid-minor) 0 1px, transparent 1px 24px),
    repeating-linear-gradient(90deg, var(--grid-minor) 0 1px, transparent 1px 24px);
  color:var(--ink);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
  display:flex; flex-direction:column; min-height:100vh;
}
*{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body > footer{ margin-top:auto; }

/* Oswald sí, mayúsculas NO por defecto.
   El manual pide mayúsculas para Oswald display — títulos, navegación,
   botones, etiquetas — pero un <h3> también envuelve DATOS: el nombre
   de un producto, el título de una ficha. "ESUN PLA+ MARRÓN 1KG" se
   lee peor que "Esun PLA+ Marrón 1Kg", y encima contradice la lámina
   20, que prohíbe texto entero en mayúsculas fuera de un titular.

   Las mayúsculas se piden a mano con .display, donde corresponden. */
h1,h2,h3{
  font-family:var(--font-display); font-weight:600;
  letter-spacing:0.01em; line-height:1.06; margin:0;
}
.display{ text-transform:uppercase; letter-spacing:0.06em; }
img,svg{ display:block; max-width:100%; }
a{ color:inherit; text-decoration:none; }
ul{ list-style:none; margin:0; padding:0; }
input,select,button,textarea{ font-family:inherit; }

/* El primer tabulador de la página salta la cabecera entera y va al
   contenido. Sin esto, quien navega con teclado pasa por los veinte
   enlaces de las tres franjas en cada página que abre. */
.saltar{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--ink); color:var(--bg);
  padding:12px 20px; border-radius:0 0 var(--radius-sm) 0;
  font-family:var(--font-display); font-size:14px; font-weight:600;
}
.saltar:focus{ left:0; }


/* =====================================================================
   CABECERA · FRANJA 1 · CONTACTO
   Microcopy, no titular. Es información de referencia: si compite en
   tamaño con el buscador, le roba atención a lo que la gente vino a
   hacer.
   ===================================================================== */
.cab-contacto{
  background:var(--bg-elev-2);
  border-bottom:1px solid var(--panel-border);
  font-size:13.5px;
}
.cab-contacto-fila{
  display:flex; align-items:center; justify-content:space-between;
  gap:var(--s3); min-height:42px; flex-wrap:wrap;
}
.cab-canales{ display:flex; align-items:center; gap:var(--s4); flex-wrap:wrap; }

.cab-canal{
  display:inline-flex; align-items:center; gap:8px;
  color:var(--ink-dim); font-weight:600;
  transition:opacity var(--dur-ui) ease, color var(--dur-ui) ease;
}
/* Los íconos traen su propio color y NO heredan del tema: son marcas
   ajenas y no se recolorean para combinar. Lo único que se controla es
   el tamaño. */
.cab-canal svg{ width:18px; height:18px; flex:none; }
.cab-canal-num{ font-variant-numeric:tabular-nums; }
.cab-direccion{ text-align:right; }

@media (hover:hover) and (pointer:fine){
  /* El hover baja opacidad en vez de cambiar color: cambiar el color
     tocaría también los íconos, que son de otra marca. */
  .cab-canal:hover{ opacity:.75; }
}


/* ---------- Selector de almacén ----------
   Va en la franja 1 y a la izquierda, que es el primer sitio donde cae
   la vista. Condiciona el stock, lo que se puede reservar y el envío:
   no es un dato de contacto más. */
.cab-sede{ position:relative; flex:none; }

.cab-sede-boton{
  display:inline-flex; align-items:center; gap:8px;
  min-height:34px; padding:0 10px 0 8px; margin-left:-8px;
  border:1.5px solid transparent; border-radius:var(--radius-sm);
  background:none; color:var(--ink); font-size:13.5px; font-weight:600;
  cursor:pointer;
  transition:border-color var(--dur-ui) ease, background-color var(--dur-ui) ease;
}
/* Con un solo almacén el botón existe pero no hace nada: se apaga el
   cursor y el borde para que no prometa una acción que no hay. */
.cab-sede-boton[disabled]{ cursor:default; }

.cab-sede-boton > svg{ width:17px; height:17px; flex:none; color:var(--ink-dim); }
.cab-sede-img{
  width:22px; height:16px; flex:none; object-fit:cover;
  border-radius:2px; border:1px solid var(--panel-border);
}
.cab-sede-ciudad{
  color:var(--ink-faint); font-weight:400;
  padding-left:8px; border-left:1px solid var(--panel-border);
}
.cab-sede-flecha{ width:14px !important; height:14px !important; opacity:.6; }

.cab-sede-menu{
  position:absolute; left:0; top:calc(100% + 6px); z-index:75; width:270px;
  background:var(--bg-elev); border:1px solid var(--panel-border);
  border-radius:var(--radius-md); box-shadow:0 16px 34px -18px var(--shadow);
  padding:6px;
  opacity:0; visibility:hidden;
  transform:scale(0.97) translateY(-4px);
  transform-origin:top left;
  transition:opacity var(--dur-ui) var(--ease-out),
             transform var(--dur-ui) var(--ease-out),
             visibility var(--dur-ui);
}
.cab-sede-menu.abierto{ opacity:1; visibility:visible; transform:scale(1) translateY(0); }

.cab-sede-titulo{
  margin:6px 10px 8px;
  font-family:var(--font-display); font-size:11px; font-weight:600;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--ink-faint);
}
.cab-sede-item{
  display:flex; align-items:center; gap:10px;
  padding:9px 10px; border-radius:var(--radius-sm);
  transition:background-color var(--dur-ui) ease;
}
.cab-sede-item img,
.cab-sede-hueco{
  width:26px; height:19px; flex:none; object-fit:cover;
  border-radius:2px; border:1px solid var(--panel-border); background:var(--bg-elev-2);
}
.cab-sede-item b{ display:block; font-size:14px; font-weight:600; color:var(--ink); }
.cab-sede-item small{ display:block; font-size:12px; color:var(--ink-faint); }
/* El almacén activo se marca con el borde de acento, no con relleno:
   es el único acento que se permite la cabecera y solo aparece con el
   desplegable abierto. */
.cab-sede-item.on{ box-shadow:inset 0 0 0 1.5px var(--accent); }

.cab-sede-nota{
  margin:8px 10px 4px; padding-top:8px;
  border-top:1px solid var(--panel-border);
  font-size:12px; color:var(--ink-faint);
}

@media (hover:hover) and (pointer:fine){
  .cab-sede-boton:not([disabled]):hover{ border-color:var(--panel-border); background:var(--bg-elev); }
  .cab-sede-item:hover{ background:var(--bg-elev-2); }
}


/* =====================================================================
   CABECERA · FRANJA 2 · IDENTIDAD
   ===================================================================== */
.cab-identidad{ background:var(--bg-elev); border-bottom:1px solid var(--panel-border); }
.cab-identidad-fila{
  display:flex; align-items:center; gap:var(--s3);
  min-height:84px; padding-top:var(--s2); padding-bottom:var(--s2);
}

.cab-hamburguesa{ display:none; }

/* El logotipo es arte fijo. El SVG entra en línea y hereda el color
   del tema con currentColor: una sola tinta, siempre. */
.cab-marca{ flex:none; display:flex; align-items:center; color:var(--ink); }
.cab-marca svg{ height:38px; width:auto; }

/* Provisional, mientras no esté el SVG maestro. Se distingue a
   propósito del logo real para que no se olvide que falta. */
.marca-provisional{ display:flex; flex-direction:column; line-height:1.15; }
.marca-provisional b{
  font-family:var(--font-display); font-weight:700; font-size:22px;
  text-transform:uppercase; letter-spacing:0.06em;
}
.marca-provisional small{
  font-family:var(--font-display); font-size:10px; font-weight:500;
  text-transform:uppercase; letter-spacing:0.14em; color:var(--ink-faint);
}

/* ---------- Buscador ---------- */
.cab-buscador{ flex:1; min-width:0; position:relative; display:flex; }
.cab-buscador input{
  flex:1; min-width:0;
  height:48px; padding:0 52px 0 var(--s2);
  border:1.5px solid var(--panel-border); border-radius:var(--radius-sm);
  background:var(--bg); color:var(--ink); font-size:15px;
  transition:border-color var(--dur-ui) ease;
}
.cab-buscador input::placeholder{ color:var(--ink-faint); }
/* El foco se marca con borde de acento, nunca con sombra difusa: una
   sombra de color es lo primero que delata que un sistema técnico se
   maquetó con la plantilla de otro. */
.cab-buscador input:focus{ outline:none; border-color:var(--accent); }
.cab-buscador button{
  position:absolute; right:0; top:0; height:48px; width:48px;
  display:flex; align-items:center; justify-content:center;
  border:0; background:none; color:var(--ink-dim); cursor:pointer;
  transition:color var(--dur-ui) ease;
}
.cab-buscador button svg{ width:19px; height:19px; }
.cab-buscador button:active{ transform:scale(0.97); }
.cab-buscador-movil{ display:none; }

@media (hover:hover) and (pointer:fine){
  .cab-buscador button:hover{ color:var(--ink); }
}

/* ---------- Acceder ---------- */
.cab-acceso{ position:relative; flex:none; }
.cab-acceso-boton svg{ width:18px; height:18px; }

.cab-acceso-menu{
  position:absolute; right:0; top:calc(100% + 8px); width:270px; z-index:70;
  background:var(--bg-elev); border:1px solid var(--panel-border);
  border-radius:var(--radius-md); box-shadow:0 16px 34px -18px var(--shadow);
  padding:6px;
  opacity:0; visibility:hidden;
  transform:scale(0.97) translateY(-4px);
  /* Nace en 0.97 y no en 0: nada en el mundo real aparece de la nada.
     El origen es la esquina del botón que lo abrió, no el centro. */
  transform-origin:top right;
  transition:opacity var(--dur-ui) var(--ease-out),
             transform var(--dur-ui) var(--ease-out),
             visibility var(--dur-ui);
}
.cab-acceso-menu.abierto{ opacity:1; visibility:visible; transform:scale(1) translateY(0); }

.cab-acceso-item{
  display:block; padding:10px 12px; border-radius:var(--radius-sm);
  transition:background-color var(--dur-ui) ease;
}
.cab-acceso-item b{ display:block; font-size:14px; font-weight:600; color:var(--ink); }
.cab-acceso-item small{ display:block; font-size:12px; color:var(--ink-faint); margin-top:1px; }
.cab-acceso-linea{ height:1px; background:var(--panel-border); margin:6px 10px; }

@media (hover:hover) and (pointer:fine){
  .cab-acceso-item:hover{ background:var(--bg-elev-2); }
}


/* =====================================================================
   CABECERA · FRANJA 3 · NAVEGACIÓN
   La única pegajosa. Las otras dos se van al bajar: la 1 es de
   referencia y la 2 ocupa alto que hace falta para ver productos.
   ===================================================================== */
.cab-nav{
  position:sticky; top:0; z-index:60;
  background:var(--bg-elev); border-bottom:1.5px solid var(--panel-border);
}
.cab-nav-fila{ display:flex; align-items:center; gap:var(--s2); min-height:var(--row-h); }

.cab-nav-catalogo{
  flex:none; display:inline-flex; align-items:center; min-height:var(--row-h);
  padding:0 var(--s2); margin-right:var(--s1);
  font-family:var(--font-display); font-size:13px; font-weight:600;
  letter-spacing:0.08em; text-transform:uppercase;
  color:var(--ink); border-right:1px solid var(--panel-border);
}

.cab-nav-lista{ display:flex; align-items:center; flex:1; min-width:0; flex-wrap:wrap; }
.cab-nav-item{ position:relative; }
.cab-nav-item > a{
  display:inline-flex; align-items:center; gap:5px;
  min-height:var(--row-h); padding:0 12px;
  font-family:var(--font-display); font-size:13px; font-weight:500;
  letter-spacing:0.06em; text-transform:uppercase;
  color:var(--ink-dim);
  border-bottom:2px solid transparent;
  transition:color var(--dur-ui) ease, border-color var(--dur-ui) ease;
}
.cab-nav-item > a.on{ color:var(--ink); border-bottom-color:var(--ink); }
.cab-nav-flecha{ width:13px; height:13px; opacity:.6; }

/* ---------- Desplegable ----------
   :hover para mouse, :focus-within para teclado, .abierto para táctil
   (lo pone el JS). Los tres caminos llevan al mismo estado. */
.cab-desplegable{
  position:absolute; top:100%; left:0; z-index:65; min-width:220px;
  background:var(--bg-elev); border:1px solid var(--panel-border);
  border-radius:0 0 var(--radius-md) var(--radius-md);
  box-shadow:0 16px 34px -18px var(--shadow);
  padding:6px;
  opacity:0; visibility:hidden;
  transform:scale(0.98) translateY(-4px);
  transform-origin:top left;            /* nace donde está el disparador */
  transition:opacity var(--dur-ui) var(--ease-out),
             transform var(--dur-ui) var(--ease-out),
             visibility var(--dur-ui);
}
.cab-nav-item.con-subs:hover > .cab-desplegable,
.cab-nav-item.con-subs:focus-within > .cab-desplegable,
.cab-nav-item.abierto > .cab-desplegable{
  opacity:1; visibility:visible; transform:scale(1) translateY(0);
}

.cab-desplegable a{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s2);
  padding:9px 12px; border-radius:var(--radius-sm);
  font-size:14px; color:var(--ink-dim);
  transition:background-color var(--dur-ui) ease, color var(--dur-ui) ease;
}
.cab-desplegable-cuenta{
  font-size:11px; color:var(--ink-faint); font-variant-numeric:tabular-nums;
}

@media (hover:hover) and (pointer:fine){
  .cab-nav-item > a:hover{ color:var(--ink); }
  .cab-desplegable a:hover{ background:var(--bg-elev-2); color:var(--ink); }
}

.cab-tema{ margin-left:auto; }


/* =====================================================================
   MENÚ MÓVIL
   ===================================================================== */
.menu-fondo{
  position:fixed; inset:0; z-index:90;
  background:rgba(38,43,51,.5); backdrop-filter:blur(2px);
  opacity:0; visibility:hidden;
  transition:opacity var(--dur-panel) var(--ease-out), visibility var(--dur-panel);
}
.menu-fondo.visible{ opacity:1; visibility:visible; }

.menu-movil{
  position:fixed; top:0; left:0; bottom:0; z-index:100;
  width:min(320px,86vw);
  background:var(--bg-elev); border-right:1px solid var(--panel-border);
  display:flex; flex-direction:column;
  /* En porcentaje y no en píxeles: se mueve por su propio ancho, sea
     cual sea el que le toque en cada pantalla. */
  transform:translateX(-100%);
  transition:transform var(--dur-panel) var(--ease-in-out);
}
.menu-movil.abierto{ transform:translateX(0); }

.menu-movil-cabecera{
  display:flex; align-items:center; justify-content:space-between; gap:var(--s2);
  padding:var(--s2) var(--s2) var(--s2) var(--s3);
  border-bottom:1px solid var(--panel-border);
}
.menu-movil-titulo{
  font-family:var(--font-display); font-weight:600; font-size:15px;
  letter-spacing:0.08em; text-transform:uppercase;
}
.menu-movil-acciones{ display:flex; align-items:center; gap:var(--s1); }
.menu-cerrar{
  width:44px; height:44px; flex:none; padding:0;
  display:flex; align-items:center; justify-content:center;
  border:0; background:none; color:var(--ink-dim); font-size:22px; cursor:pointer;
  transition:color var(--dur-ui) ease;
}
.menu-cerrar:active{ transform:scale(0.97); }

.menu-movil-cuerpo{ padding:var(--s2); overflow-y:auto; flex:1; }

.menu-rotulo{
  font-family:var(--font-display); font-size:11px; font-weight:600;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--accent-text);
  margin:var(--s3) 12px var(--s1);
}
.menu-item{
  display:block; min-height:var(--row-h); padding:11px 12px;
  border-radius:var(--radius-sm); font-size:15px; color:var(--ink-dim);
  transition:background-color var(--dur-ui) ease, color var(--dur-ui) ease;
}
.menu-item.on{ color:var(--ink); font-weight:600; }
.menu-item-fuerte{
  font-family:var(--font-display); font-weight:600; font-size:14px;
  letter-spacing:0.08em; text-transform:uppercase; color:var(--ink);
}
/* El acceso de colaboradores se ve apagado: existe, pero no es para el
   visitante que llegó a comprar. */
.menu-item.apagado{ color:var(--ink-faint); font-size:14px; }

.menu-subs{ margin:0 0 var(--s1) 12px; padding-left:12px; border-left:1px solid var(--panel-border); }
.menu-subs a{
  display:block; padding:8px 12px; font-size:14px; color:var(--ink-faint);
  border-radius:var(--radius-sm);
  transition:color var(--dur-ui) ease;
}
.menu-separador{ height:1px; background:var(--panel-border); margin:var(--s2) 12px; }
.menu-wa{ width:100%; margin-top:var(--s2); }

@media (hover:hover) and (pointer:fine){
  .menu-item:hover{ background:var(--bg-elev-2); color:var(--ink); }
  .menu-subs a:hover{ color:var(--ink); }
  .menu-cerrar:hover{ color:var(--ink); }
}


/* =====================================================================
   PIE · FRANJA 1 · CONTENIDO
   ===================================================================== */
.pie{ border-top:1.5px solid var(--panel-border); }

.pie-contenido{ background:var(--bg-elev); padding:var(--s8) 0 var(--s6); }
.pie-grid{
  display:grid; grid-template-columns:1.6fr 1fr 1fr 1fr 1.4fr;
  gap:var(--s6) var(--s4); align-items:start;
}
/* Los elementos de una fila arrancan en la misma línea, no en su
   centro. En cuanto una columna crece un renglón, el centrado deja la
   fila entera torcida sin que se sepa por qué. */

.pie-col-marca{ max-width:320px; }
.pie-logo{ color:var(--ink); margin-bottom:var(--s2); }
.pie-logo svg{ height:34px; width:auto; }
.pie-lema{ margin:0 0 var(--s2); font-size:14px; color:var(--ink-dim); }
.pie-stock{ margin:0; font-size:13px; color:var(--ink-faint); line-height:1.5; }

.pie-titulo{
  font-family:var(--font-display); font-size:12px; font-weight:600;
  letter-spacing:0.12em; text-transform:uppercase; color:var(--ink);
  margin-bottom:var(--s2);
}
.pie-col li{ margin-bottom:9px; font-size:14px; }
.pie-col a{ color:var(--ink-dim); transition:color var(--dur-ui) ease; }
/* Las páginas que todavía no existen se muestran apagadas en vez de
   ocultarse: así se ve qué falta y el visitante entiende que la página
   existirá, no que se la escondimos. */
.pie-pendiente{ color:var(--ink-faint); cursor:default; }

.pie-col-contacto p{ margin:0 0 var(--s1); font-size:14px; color:var(--ink-dim); }
.pie-enlace{ color:var(--ink); font-weight:600; }
.pie-wa-linea{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; }
.pie-wa-quien{ font-size:12px; color:var(--ink-faint); }

@media (hover:hover) and (pointer:fine){
  .pie-col a:hover{ color:var(--ink); }
  .pie-enlace:hover{ color:var(--accent-text); }
}


/* =====================================================================
   PIE · FRANJA 2 · LEGAL
   Otra superficie, no otro color inventado: es la misma escala de
   elevación del tema, un escalón más abajo.
   ===================================================================== */
.pie-legal{
  background:var(--bg-elev-2);
  border-top:1px solid var(--panel-border);
  padding:var(--s6) 0 var(--s3);
}
.pie-legal-grid{
  display:grid; grid-template-columns:1fr 1.4fr auto;
  gap:var(--s4); align-items:start;
}
.pie-legal-bloque .pie-titulo{ margin-bottom:12px; }

.pie-pagos{ display:flex; flex-wrap:wrap; gap:8px; }
.pie-pagos li{
  font-size:12px; font-weight:600; color:var(--ink-dim);
  padding:5px 10px; border:1px solid var(--panel-border);
  border-radius:var(--radius-sm); background:var(--bg-elev);
}

.pie-empresas li{ font-size:13px; color:var(--ink-dim); margin-bottom:7px; }
.pie-ruc{
  display:block; font-size:12px; color:var(--ink-faint);
  font-variant-numeric:tabular-nums;
}

.pie-legal-reclamos{ justify-self:end; }
.pie-reclamos{
  display:inline-flex; align-items:center; gap:10px;
  padding:12px 16px; min-height:var(--row-h);
  border:1.5px solid var(--line); border-radius:var(--radius-sm);
  font-family:var(--font-display); font-size:11px; font-weight:600;
  letter-spacing:0.08em; text-transform:uppercase; line-height:1.3;
  color:var(--ink);
  transition:border-color var(--dur-ui) ease, color var(--dur-ui) ease;
}
.pie-reclamos svg{ width:24px; height:24px; flex:none; }
.pie-reclamos:active{ transform:scale(0.97); }

.pie-firma{
  display:flex; justify-content:space-between; align-items:center;
  gap:var(--s2); flex-wrap:wrap;
  margin-top:var(--s4); padding-top:var(--s3);
  border-top:1px solid var(--panel-border);
  font-size:12.5px; color:var(--ink-faint);
}
.pie-colaborador{ color:var(--ink-faint); transition:color var(--dur-ui) ease; }

@media (hover:hover) and (pointer:fine){
  .pie-reclamos:hover{ border-color:var(--accent); color:var(--accent-text); }
  .pie-colaborador:hover{ color:var(--ink-dim); }
}


/* =====================================================================
   REJILLA Y TARJETA DE PRODUCTO
   La pieza más repetida del sitio. La usan el catálogo y la portada.
   ===================================================================== */
/* CUATRO POR FILA, FIJO.
   No auto-fill: con auto-fill el número de columnas lo decide el ancho
   sobrante, y bastaba que la suma diera 896px contra 894 disponibles
   para que cayera a tres sin que nada lo explicara.

   Cuatro es la cuenta en escritorio. Abajo baja a tres y después a
   dos, porque cuatro columnas en un teléfono de 380px son tarjetas de
   85px: ahí no se ve el color del filamento, que es lo único que
   importa en esta rejilla. */
.rejilla{
  display:grid;
  grid-template-columns:repeat(4,minmax(0,1fr));
  gap:var(--s2);
}

.producto{
  background:var(--bg-elev);
  border:1px solid var(--panel-border);
  border-radius:var(--radius-sm);
  overflow:hidden;
  /* Solo border-color y transform: los dos corren en la GPU. Animar
     box-shadow en 24 tarjetas a la vez repinta media pantalla. */
  transition:border-color var(--dur-ui) ease, transform var(--dur-ui) var(--ease-out);
}
.producto-enlace{ display:flex; flex-direction:column; height:100%; }

.producto-foto{
  position:relative; aspect-ratio:1;
  background:var(--bg); overflow:hidden;
  border-bottom:1px solid var(--panel-border);
}
.producto-foto img{ width:100%; height:100%; object-fit:cover; }

/* El hueco sin foto lleva las líneas de la cuadrícula del sistema: se
   lee como "falta la foto", no como un error de carga. */
.sin-foto{
  display:block; width:100%; height:100%;
  background:
    repeating-linear-gradient(0deg,  var(--grid-major) 0 1px, transparent 1px 24px),
    repeating-linear-gradient(90deg, var(--grid-major) 0 1px, transparent 1px 24px),
    var(--bg-elev-2);
}

/* Radio bajo, no píldora: la única píldora del sistema es el
   interruptor de tema. */
.sello{
  position:absolute; top:8px; padding:4px 9px;
  border-radius:var(--radius-sm);
  font-family:var(--font-display); font-size:11px; font-weight:600;
  letter-spacing:0.08em; text-transform:uppercase;
}
.sello-agotado{ right:8px; background:var(--ink); color:var(--bg); }
/* .sello-oferta existe si algún día vuelve el sello de porcentaje.
   Hoy la oferta se comunica con el precio tachado, sin color — ver el
   comentario en tienda/_tarjeta.php. */
.sello-oferta{ left:8px; background:var(--accent); color:var(--accent-ink); }

.producto-datos{
  padding:14px; display:flex; flex-direction:column; flex:1; gap:6px;
}

/* El nombre es DATO, no titular: Work Sans, caja normal. "ESUN PLA+
   MARRÓN 1KG" se lee peor que "Esun PLA+ Marrón 1Kg", y la lámina 20
   prohíbe texto entero en mayúsculas fuera de un titular. */
.producto-nombre{
  font-family:var(--font-body); font-weight:600; font-size:14px;
  letter-spacing:0; line-height:1.35; margin:0; color:var(--ink);
  display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
}
.producto-ruta{
  margin:0; font-family:var(--font-display); font-size:11px; font-weight:500;
  color:var(--ink-faint);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap;
}

/* Los elementos de la fila arrancan en la misma línea de base, no
   centrados: el precio tachado y el vigente tienen alturas distintas y
   centrarlos deja los dos números a distinta altura. */
.producto-precio{
  margin-top:auto; padding-top:var(--s1);
  display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
}
.producto-precio .antes{
  font-size:12px; color:var(--ink-faint); text-decoration:line-through;
  font-variant-numeric:tabular-nums;
}
.producto-precio .ahora{
  font-family:var(--font-display); font-weight:600; font-size:18px;
  letter-spacing:0.01em; color:var(--ink); font-variant-numeric:tabular-nums;
}

/* Los cuatro colores de estado del manual. Cada uno con su palabra
   escrita al lado: el color nunca es el único portador del estado. */
.disponibilidad{
  align-self:flex-start;
  font-size:11.5px; font-weight:600;
  padding:3px 9px; border-radius:var(--radius-sm);
  border:1px solid currentColor; white-space:nowrap;
}
.disponibilidad.hay{    color:var(--ok); }
.disponibilidad.pocas{  color:var(--accent-text); }
.disponibilidad.pedido{ color:var(--info); }
.disponibilidad.no{     color:var(--ink-faint); }
.disponibilidad.grande{ font-size:13px; padding:6px 14px; display:inline-block; margin:0 0 var(--s3); }

@media (hover:hover) and (pointer:fine){
  .producto:hover{ border-color:var(--line); transform:translateY(-2px); }
}


/* =====================================================================
   PESTAÑAS FLOTANTES
   Pegadas al borde derecho y redondeadas solo del lado visible: la
   pieza se corta contra el borde en vez de flotar con sombra
   alrededor. Es la misma lógica de la lámina que se sale del margen.
   ===================================================================== */
.flotantes{
  position:fixed; right:0; bottom:24px; z-index:80;
  display:flex; flex-direction:column; align-items:flex-end; gap:10px;
}

.flotante{
  display:flex; align-items:center; justify-content:center;
  width:52px; height:52px; padding:0; flex:none;   /* área táctil holgada */
  border:0; border-radius:var(--radius-md) 0 0 var(--radius-md);
  cursor:pointer;
  box-shadow:-6px 6px 18px -8px var(--shadow);
  transition:transform var(--dur-press) var(--ease-out),
             opacity var(--dur-ui) var(--ease-out),
             visibility var(--dur-ui);
}
.flotante svg{ width:26px; height:26px; }
.flotante:active{ transform:scale(0.94); }

/* El verde es de WhatsApp, no nuestro: no gasta el acento del sistema
   y la gente lo lee como "WhatsApp" antes que como un color. */
.flotante-wa{ background:#25D366; color:#FFFFFF; }

/* Tinta plana: no señala nada porque no tiene nada que señalar. */
.flotante-subir{
  background:var(--ink); color:var(--bg);
  opacity:0; visibility:hidden;
  transform:translateX(8px);
}
.flotante-subir.visible{ opacity:1; visibility:visible; transform:translateX(0); }

@media (hover:hover) and (pointer:fine){
  .flotante:hover{ transform:translateX(-3px); }
  .flotante-subir.visible:hover{ transform:translateX(-3px); }
}


/* =====================================================================
   RESPONSIVE
   El orden de sacrificio, del primero al último: los nombres de las
   empresas junto a cada WhatsApp, la franja 2 entera, la lista de
   categorías. El buscador nunca se pierde — se muda.
   ===================================================================== */

@media (max-width:1080px){
  .pie-grid{ grid-template-columns:1.4fr 1fr 1fr; }
  .pie-col-contacto{ grid-column:1 / -1; }
}

@media (max-width:1080px){
  .rejilla{ grid-template-columns:repeat(3,minmax(0,1fr)); }
}

@media (max-width:900px){
  /* La franja 3 pierde su lista y se queda con buscador y tema: con
     siete categorías, dos filas de navegación empujan el primer
     producto fuera de la pantalla. */
  .cab-nav-lista,
  .cab-nav-catalogo{ display:none; }
  .cab-buscador-movil{ display:flex; flex:1; }
  .cab-nav-fila{ padding-top:10px; padding-bottom:10px; gap:12px; }
  .cab-buscador-movil input{ height:44px; font-size:14px; }
  .cab-buscador-movil button{ height:44px; width:44px; }

  /* La franja 2 se reduce a la barra de identidad: hamburguesa, logo y
     acceso. El buscador ya está abajo. */
  .cab-identidad-fila > .cab-buscador{ display:none; }
  .cab-identidad-fila{ min-height:64px; }
  .cab-marca svg{ height:30px; }
  .cab-hamburguesa{
    display:flex; align-items:center; justify-content:center; flex:none;
    width:44px; height:44px; padding:0;
    border:1.5px solid var(--panel-border); border-radius:var(--radius-sm);
    background:var(--bg-elev); color:var(--ink); cursor:pointer;
  }
  .cab-hamburguesa svg{ width:20px; height:20px; }
  .cab-hamburguesa:active{ transform:scale(0.97); }
  .cab-acceso-boton span{ display:none; }
  .cab-acceso-boton{ padding:0 14px; }
  .cab-marca{ margin-right:auto; }

  .pie-legal-grid{ grid-template-columns:1fr 1fr; }
  .pie-legal-reclamos{ grid-column:1 / -1; justify-self:start; }
}

@media (max-width:640px){
  .rejilla{ grid-template-columns:repeat(2,minmax(0,1fr)); gap:12px; }
  .flotantes{ bottom:16px; gap:8px; }
  .flotante{ width:46px; height:46px; }
  .flotante svg{ width:23px; height:23px; }
  .producto-datos{ padding:11px 12px 13px; }

  /* La franja 1 se va del todo. El WhatsApp y la dirección siguen en
     el pie, que es donde alguien los busca cuando ya decidió. */
  .pie-grid{ grid-template-columns:1fr 1fr; }
  .pie-col-marca{ grid-column:1 / -1; max-width:none; }
  .pie-legal-grid{ grid-template-columns:1fr; }
  .pie-contenido{ padding:var(--s6) 0 var(--s4); }
}


/* =====================================================================
   MOVIMIENTO REDUCIDO
   No es movimiento cero: se conservan opacidad y color, que ayudan a
   entender QUÉ cambió. Se elimina desplazamiento y escalado.
   ===================================================================== */
@media (prefers-reduced-motion: reduce){
  .cab-sede-menu{ transform:none; transition:opacity var(--dur-ui) ease, visibility var(--dur-ui); }
  .cab-sede-menu.abierto{ transform:none; }
  .cab-acceso-menu,
  .cab-desplegable{ transform:none; transition:opacity var(--dur-ui) ease, visibility var(--dur-ui); }
  .cab-acceso-menu.abierto,
  .cab-nav-item.con-subs:hover > .cab-desplegable,
  .cab-nav-item.con-subs:focus-within > .cab-desplegable,
  .cab-nav-item.abierto > .cab-desplegable{ transform:none; }
  .menu-movil{ transition:none; }
  .producto:hover{ transform:none; }
  .flotante:hover,
  .flotante:active{ transform:none; }
  .flotante-subir{ transform:none; }
  .flotante-subir.visible{ transform:none; }
  .cab-hamburguesa:active,
  .menu-cerrar:active,
  .pie-reclamos:active,
  .cab-buscador button:active{ transform:none; }
}