/*
 * Estilo del portal de clientes.
 *
 * Deliberadamente distinto del ERP: aquí no entra un capturista que pasa el día en el sistema,
 * sino alguien que compra de vez en cuando. Por eso hay aire, la foto manda sobre el texto y la
 * jerarquía se apoya en el tamaño antes que en los bordes.
 */

:root {
  --tinta: #16202c;
  --tinta-suave: #5b6b7c;
  --linea: #e3e8ee;
  --fondo: #f7f9fb;
  --marca: #1b5e9c;
  --marca-oscura: #14456f;
  --exito: #1c7a4a;
  --alerta: #9a6a00;
  --error: #b02a37;
  --favorito: #d6455a;
  --radio: 12px;
  --sombra: 0 1px 2px rgba(22, 32, 44, .06), 0 8px 24px rgba(22, 32, 44, .06);

  /*
   * Escala tipográfica.
   *
   * Antes había 26 tamaños distintos repartidos por la hoja —.9, .92, .93, .95 y .98rem
   * conviviendo—, diferencias que nadie distingue de un vistazo pero que sí se acumulan: dos
   * textos del mismo rango salían con medio píxel de diferencia y la página se leía descuidada
   * sin que se pudiera señalar por qué.
   *
   * Ocho pasos, cada uno como un 10% del anterior. Un tamaño nuevo se elige de aquí; si de
   * verdad no cabe en ninguno, el que falta es un paso de la escala, no una excepción suelta.
   */
  --t-2xs: .7rem;     /* letras chicas en mayúsculas: insignias, marca de la tarjeta */
  --t-xs: .78rem;     /* apoyo: fechas, monedas, encabezados de tabla */
  --t-sm: .84rem;     /* secundario: ayudas, detalles, botones chicos */
  --t-md: .92rem;     /* el texto de trabajo de la tienda */
  --t-lg: 1rem;       /* texto de controles: botones, campos, renglones de resumen */
  --t-xl: 1.15rem;    /* precio, nombre de la tienda, títulos de bloque menores */
  --t-2xl: 1.35rem;   /* títulos de sección de la portada */
  --t-3xl: 1.55rem;   /* títulos de pantalla y cifras grandes */
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  color: var(--tinta);
  background: var(--fondo);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}

a { color: var(--marca); text-decoration: none; }
a:hover { text-decoration: underline; }

/* Quien recorre la tienda con el teclado tiene que ver dónde va parado. Antes solo el buscador
   marcaba el foco, así que el recorrido con Tab era invisible en todo lo demás. Va en :where()
   para que cualquier regla del propio control la gane sin pelear especificidad. */
:where(a, button, input, select, textarea, summary):focus-visible {
  outline: 2px solid var(--marca);
  outline-offset: 2px;
}

/* Los íconos se dibujan al tamaño del texto que acompañan y con su mismo color, así que heredan
   solo con ponerlos donde van.

   De ahí que unos cuantos font-size de esta hoja se salgan de la escala tipográfica —los de
   .buscador button, .favorito, .sin-foto y .vacio .icono—: ahí el font-size no dimensiona letras
   sino un dibujo, y amarrarlos a la escala del texto los volvería a mover cada vez que se afine
   la lectura. */
.ico { display: inline-block; width: 1em; height: 1em; flex: none; vertical-align: -.125em; }

/* Los títulos van más apretados que el cuerpo: con el 1.5 del body, dos renglones de un título
   se separan tanto que dejan de leerse como una sola frase. */
h1, h2, h3 { line-height: 1.25; }

.contenedor { width: min(1200px, 100% - 2rem); margin-inline: auto; }

/* ── Encabezado ─────────────────────────────────────────────────────────── */

.cabecera {
  background: #fff;
  border-bottom: 1px solid var(--linea);
  position: sticky;
  top: 0;
  z-index: 20;
}

/* El ancho al que la cabecera deja de caber depende del largo del nombre de la tienda, así que
   el reacomodo no puede colgarse de un punto de quiebre fijo: se deja envolver y el buscador
   se baja solo cuando ya no cabe junto a la marca y las acciones. */
.cabecera-fila {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .75rem 1.5rem;
  padding: .9rem 0;
}

.marca {
  font-weight: 700;
  font-size: var(--t-xl);
  color: var(--tinta);
  white-space: nowrap;
}
.marca:hover { text-decoration: none; }

/* El logo se acota por ALTO y deja libre el ancho: los logotipos vienen en proporciones muy
   distintas —de un cuadrado a una tira muy larga— y fijar el ancho aplastaría unos y dejaría
   diminutos a otros. El alto es lo que tiene que coincidir con el resto del encabezado.

   El tope de ancho es para el caso extremo: un logotipo muy apaisado empujaría el buscador fuera
   de la fila. Al llegar al tope se contiene, no se recorta. */
.marca-logo {
  display: block;
  height: 2.2rem;
  max-width: 260px;
  object-fit: contain;
  object-position: left center;
}
@media (max-width: 640px) { .marca-logo { height: 1.9rem; max-width: 190px; } }

.buscador { flex: 1 1 260px; display: flex; max-width: 520px; }
.buscador input {
  flex: 1;
  border: 1px solid var(--linea);
  border-right: 0;
  border-radius: 999px 0 0 999px;
  padding: .55rem 1rem;
  font-size: var(--t-lg);
  min-width: 0;
}
.buscador input:focus { outline: 2px solid var(--marca); outline-offset: -1px; }
.buscador button {
  border: 1px solid var(--marca);
  background: var(--marca);
  color: #fff;
  border-radius: 0 999px 999px 0;
  padding: .55rem 1.1rem;
  font-size: 1.05rem;
  display: grid;
  place-items: center;
  cursor: pointer;
}
.buscador button:hover { background: var(--marca-oscura); }

.acciones-cabecera { display: flex; align-items: center; gap: 1rem; margin-left: auto; }

.identidad { text-align: right; line-height: 1.25; }
.identidad .nombre-cliente { font-weight: 600; font-size: var(--t-md); }
.identidad .liga-salir { font-size: var(--t-sm); color: var(--tinta-suave); }

.boton-carrito {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  background: var(--marca);
  color: #fff;
  border-radius: 999px;
  padding: .5rem 1.1rem;
  font-weight: 600;
  font-size: var(--t-md);
  white-space: nowrap;
}
.boton-carrito:hover { background: var(--marca-oscura); text-decoration: none; }
.contador-carrito {
  background: #fff;
  color: var(--marca);
  border-radius: 999px;
  min-width: 1.4rem;
  height: 1.4rem;
  display: inline-grid;
  place-items: center;
  font-size: var(--t-xs);
  font-weight: 700;
  padding-inline: .35rem;
}

/* ── Avisos ─────────────────────────────────────────────────────────────── */

.aviso {
  border-radius: var(--radio);
  padding: .8rem 1rem;
  margin: 1rem 0;
  font-size: var(--t-md);
  border: 1px solid transparent;
}
.aviso-exito { background: #e8f6ee; border-color: #bfe3ce; color: var(--exito); }
.aviso-error { background: #fdecee; border-color: #f5c2c7; color: var(--error); }
.aviso-info  { background: #eaf2fa; border-color: #c6dcf0; color: var(--marca-oscura); }

/* ── Portada ────────────────────────────────────────────────────────────── */

.portada {
  position: relative;
  overflow: hidden;
  background: linear-gradient(135deg, var(--marca-oscura), var(--marca) 55%, #2f81c9);
  color: #fff;
}

/* La foto va como capa de fondo y el texto encima. Con un banner claro el título se perdería,
   así que el velo de abajo no es decoración: es lo que mantiene legible el encabezado sea cual
   sea la imagen que suba la empresa. */
.portada-foto {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.portada-con-foto::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(100deg, rgba(12, 32, 52, .88) 0%, rgba(12, 32, 52, .55) 55%, rgba(12, 32, 52, .25) 100%);
}

.portada-texto {
  position: relative;
  z-index: 1;
  padding: 4rem 0;
  max-width: min(1200px, 100% - 2rem);
}
.portada-texto h1 {
  font-size: clamp(1.8rem, 4vw, 2.9rem);
  line-height: 1.15;
  margin: 0;
  max-width: 20ch;
  text-wrap: balance;
}
.portada-apoyo {
  font-size: var(--t-xl);
  margin: .9rem 0 0;
  max-width: 52ch;
  color: rgba(255, 255, 255, .88);
}
.portada-acciones { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.75rem; }
.boton-claro { background: #fff; color: var(--marca-oscura); }
.boton-claro:hover { background: #eaf2fa; color: var(--marca-oscura); }

@media (max-width: 640px) { .portada-texto { padding: 2.75rem 0; } }

.bloque { padding: 2.75rem 0 0; }
.bloque-encabezado {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 1rem; margin-bottom: 1.1rem;
}
.bloque-encabezado h2 { font-size: var(--t-2xl); margin: 0; }
.bloque-encabezado a { font-size: var(--t-md); font-weight: 600; white-space: nowrap; }

.reja-categorias {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: .9rem;
}
/* El mosaico con foto: la imagen manda y el nombre confirma, igual que en la tarjeta del catálogo.
   Se pierde la franja azul de la izquierda —con foto, ese acento competía con ella—. */
.mosaico {
  display: flex;
  flex-direction: column;
  background: #fff;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
  color: var(--tinta);
  transition: box-shadow .15s ease, transform .15s ease;
}
.mosaico:hover { box-shadow: var(--sombra); transform: translateY(-2px); text-decoration: none; }

/* Proporción fija para que la reja no se escalone según lo que mida cada foto. La de la categoría
   suele venir recortada y llena el cuadro; la de un artículo viene sobre fondo blanco y se
   contiene, que es como ya se ven en el catálogo. */
.mosaico-foto {
  aspect-ratio: 4 / 3;
  background: #fff;
  border-bottom: 1px solid var(--linea);
  display: grid; place-items: center;
  overflow: hidden;
}
.mosaico-foto img { width: 100%; height: 100%; object-fit: cover; }
.mosaico-foto .sin-foto { font-size: 2rem; }

/* La foto prestada de un artículo NO se recorta: es una toma de producto sobre fondo blanco y
   recortarla parte la pieza. La de la categoría sí llena el cuadro, porque para eso se eligió. */
.mosaico-foto-articulo img { object-fit: contain; padding: .9rem; }

.mosaico-texto { display: flex; flex-direction: column; gap: .2rem; padding: .8rem 1rem .9rem; }
.mosaico-nombre { font-weight: 600; font-size: var(--t-lg); line-height: 1.3; }
.mosaico-cuenta { font-size: var(--t-sm); color: var(--tinta-suave); }

/* El aviso de que la lista viene filtrada, con su salida al lado: sin él, quien llega desde la
   franja de la portada ve menos pedidos de los que tiene y no sabe por qué. */
.filtro-activo {
  display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
  margin: 0 0 1rem; font-size: var(--t-md); color: var(--tinta-suave);
}

/* La franja de pedidos en curso. Va pegada arriba de los estantes y en el tono de la marca —no en
   blanco como los paneles— porque es lo primero que un cliente busca al entrar y tiene que
   distinguirse del escaparate sin gritar.

   Los dos tonos se MEZCLAN a partir de --marca en vez de estar escritos: la empresa elige su
   color, y con un azul fijo aquí una tienda roja quedaba con una franja azul en medio de la
   portada. Al mezclarlos con blanco, cualquier color de marca da un fondo pálido legible. */
.franja-pedidos {
  display: flex; align-items: center; flex-wrap: wrap; gap: 1rem 1.5rem;
  background: color-mix(in srgb, var(--marca) 7%, #fff);
  border: 1px solid color-mix(in srgb, var(--marca) 22%, #fff);
  border-radius: var(--radio);
  padding: .9rem 1.2rem;
  margin-top: 1.75rem;
}
.franja-pedidos-titulo {
  display: flex; align-items: center; gap: .5rem;
  font-weight: 700; color: var(--marca-oscura);
}
.franja-pedidos-estados { display: flex; flex-wrap: wrap; gap: .5rem; flex: 1; }

/* Cada estado es una LIGA y no una etiqueta: el número solo sirve si lleva a los pedidos que
   cuenta. Sin eso, el cliente lee «2 por surtir» y tiene que ir a buscarlos a mano. */
.estado-pedido {
  display: inline-flex; align-items: baseline; gap: .35rem;
  background: #fff; border: 1px solid color-mix(in srgb, var(--marca) 22%, #fff); border-radius: 999px;
  padding: .3rem .8rem;
  font-size: var(--t-sm); color: var(--tinta);
}
.estado-pedido:hover { border-color: var(--marca); text-decoration: none; }
.estado-pedido .cuantos {
  font-weight: 700; font-size: var(--t-lg); color: var(--marca-oscura);
  font-variant-numeric: tabular-nums;
}

.franja-pedidos-liga { font-size: var(--t-md); font-weight: 600; white-space: nowrap; }

@media (max-width: 640px) {
  .franja-pedidos { flex-direction: column; align-items: flex-start; gap: .7rem; }
  .franja-pedidos-liga { align-self: flex-end; }
}

.franja-cliente {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 1.25rem;
  background: #fff;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 1.75rem;
  margin-top: 2.75rem;
}
.franja-cliente h2 { font-size: var(--t-xl); margin: 0 0 .35rem; }
.franja-cliente p { margin: 0; color: var(--tinta-suave); max-width: 60ch; }

/* ── Reja del catálogo ──────────────────────────────────────────────────── */

.disposicion { display: grid; grid-template-columns: 240px 1fr; gap: 2rem; padding: 2rem 0; }
@media (max-width: 860px) { .disposicion { grid-template-columns: 1fr; gap: 1rem; } }

.panel-lateral {
  background: #fff;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  padding: 1.1rem;
  align-self: start;
}
.panel-lateral h2 { font-size: var(--t-sm); text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-suave); margin: 0 0 .7rem; }
.panel-lateral ul { list-style: none; margin: 0; padding: 0; }
.panel-lateral li { margin-bottom: .15rem; }
.panel-lateral a {
  display: flex; justify-content: space-between; gap: .5rem;
  padding: .4rem .6rem; border-radius: 8px; color: var(--tinta); font-size: var(--t-md);
}
.panel-lateral a:hover { background: var(--fondo); text-decoration: none; }
.panel-lateral a.activo { background: var(--marca); color: #fff; font-weight: 600; }
.panel-lateral .cuenta {
  color: var(--tinta-suave); font-size: var(--t-sm);
  font-variant-numeric: tabular-nums;
}
.panel-lateral a.activo .cuenta { color: rgba(255,255,255,.85); }

/* Densidad: quien surte una obra compara docenas de claves, así que la reja prioriza cuántas
   caben de un vistazo sobre el lucimiento de cada tarjeta. Con el catálogo (que además lleva
   panel lateral) salen 4 por renglón; sin él, 5. */
.reja {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 1rem;
}

/* La portada es escaparate, no reja de trabajo: menos columnas y más aire, y así los 8
   destacados caen en dos renglones parejos de 4 en lugar de un 5 + 3 descuadrado. */
.reja-portada { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); gap: 1.25rem; }

/* ── Estante horizontal ─────────────────────────────────────────────────── */
/* Las listas del cliente se recorren de lado en vez de crecer hacia abajo: puestas como reja,
   doce artículos empujarían el resto de la portada fuera de la pantalla. Es CSS y nada más —sin
   temporizador ni flechas—, que es lo que puede hacer una tienda dibujada en el servidor. */

.estante {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(190px, 220px);
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  /* Sin esto, seguir empujando al llegar al final dispara el "atrás" del navegador y el cliente
     pierde la página por querer ver una tarjeta más. */
  overscroll-behavior-x: contain;
  /* La sombra del hover se sale de la caja; sin aire se recortaría contra el borde del estante. */
  padding: .25rem .25rem 1rem;
  margin-inline: -.25rem;
  scrollbar-width: thin;
}
.estante > * { scroll-snap-align: start; }
.estante:focus-visible { outline: 2px solid var(--marca); outline-offset: 2px; }

/* Sustitutos y relacionados al pie de la ficha. */
.seccion-alternativos { margin-top: 2.5rem; }
.seccion-alternativos h2 { font-size: var(--t-xl); margin: 0 0 1rem; }

.tarjeta {
  background: #fff;
  border: 1px solid var(--linea);
  border-radius: var(--radio);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: box-shadow .15s ease, transform .15s ease;
}
.tarjeta:hover { box-shadow: var(--sombra); transform: translateY(-2px); }

/* La foto ya no es cuadrada: era la que estiraba la tarjeta a lo alto y obligaba a bajar la
   página para ver cuatro claves. Con contain no se recorta nada, solo deja de sobrar aire
   arriba y abajo de artículos que son más anchos que altos. */
.tarjeta-foto {
  aspect-ratio: 4 / 3;
  background: #fff;
  display: grid;
  place-items: center;
  border-bottom: 1px solid var(--linea);
  overflow: hidden;
}
.tarjeta-foto img { width: 100%; height: 100%; object-fit: contain; padding: .5rem; }
.sin-foto { color: #c3cdd8; font-size: 2.5rem; line-height: 0; }

.tarjeta-cuerpo { padding: .7rem .8rem .8rem; display: flex; flex-direction: column; gap: .3rem; flex: 1; }
.tarjeta-marca { font-size: var(--t-2xs); text-transform: uppercase; letter-spacing: .04em; color: var(--tinta-suave); }
.tarjeta-nombre { font-weight: 600; font-size: var(--t-md); color: var(--tinta); line-height: 1.3; }
.tarjeta-nombre:hover { color: var(--marca); text-decoration: none; }
.tarjeta-codigo { font-size: var(--t-xs); color: var(--tinta-suave); font-variant-numeric: tabular-nums; }
.tarjeta-pie { margin-top: auto; padding-top: .5rem; }

/* Cifras en columnas tabulares: en una reja de tarjetas los precios quedan uno debajo de otro, y
   con los dígitos de ancho variable el punto decimal se corre de tarjeta en tarjeta. Comparar
   precios es lo que el cliente vino a hacer aquí. */
.precio { font-size: var(--t-xl); font-weight: 700; color: var(--tinta); font-variant-numeric: tabular-nums; }
.precio .moneda { font-size: var(--t-xs); font-weight: 500; color: var(--tinta-suave); margin-left: .25rem; }
.precio-oculto { font-size: var(--t-sm); color: var(--marca); font-weight: 600; }
.sin-precio { font-size: var(--t-sm); color: var(--alerta); font-weight: 600; }

/* El `align-self` no es adorno: el cuerpo de la tarjeta es un flex en columna, y ahí un
   `inline-block` se convierte en bloque y se estira de orilla a orilla. El semáforo salía como una
   banda de color del ancho de la tarjeta en vez de la píldora que mide lo que dice. */
.etiqueta {
  display: inline-block;
  align-self: start;
  font-size: var(--t-2xs);
  font-weight: 600;
  padding: .16rem .55rem;
  border-radius: 999px;
}
.etiqueta-disponible { background: #e8f6ee; color: var(--exito); }
.etiqueta-pocas { background: #fdf3e0; color: var(--alerta); }
.etiqueta-agotado { background: #f1f3f5; color: var(--tinta-suave); }

/* El corazón va encima de la foto, no en el cuerpo: ahí no compite por espacio con el nombre
   ni con el precio, que es lo que la tarjeta tiene que comunicar primero. */
.tarjeta { position: relative; }
.marca-favorito { position: absolute; top: .4rem; right: .4rem; z-index: 1; margin: 0; }
.favorito {
  border: 1px solid var(--linea);
  background: rgba(255, 255, 255, .92);
  color: var(--tinta-suave);
  border-radius: 999px;
  width: 2rem; height: 2rem;
  display: grid; place-items: center;
  font-size: 1.05rem; line-height: 1;
  cursor: pointer;
  padding: 0;
}
/* Rojo y no el azul de la marca: el corazón se lee como "me gusta" en cualquier tienda, y pintarlo
   del color de los botones lo confundiría con una acción de compra. */
.favorito:hover { color: var(--favorito); border-color: #f0b8c0; }
.favorito.activo { color: var(--favorito); border-color: #f0b8c0; background: #fff5f6; }

/* La insignia de la etiqueta: esquina contraria al corazón, para que no se estorben.

   Va en tinta oscura y no en un color alegre porque el mismo estilo tiene que servir a «Oferta» y
   a «Descontinuado»: la etiqueta no trae color propio, así que pintarla de rojo o de verde le
   pondría un tono que la empresa no eligió. Se corta con puntos suspensivos —el ancho es el de la
   tarjeta menos el corazón— para que un nombre largo no cruce la foto de lado a lado. */
.insignia {
  position: absolute; top: .4rem; left: .4rem; z-index: 1;
  background: var(--tinta); color: #fff;
  border-radius: 999px; padding: .18rem .55rem;
  font-size: var(--t-2xs); font-weight: 700; text-transform: uppercase; letter-spacing: .04em;
  max-width: calc(100% - 3.2rem);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* El botón de pedir desde la reja. Va al ancho de la tarjeta y no flotando sobre la foto: ahí
   taparía el producto, que es lo que hace que el ojo se detenga en la tarjeta. */
.tarjeta-accion { margin-top: .55rem; }

/* El control que toma el lugar del botón cuando el artículo ya va en el carrito. El borde azul es
   la señal de "ya adentro": ocupa el mismo renglón que ocupaba el botón, así que la tarjeta no
   brinca al cambiar de estado. */
.cantidad-carrito {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--marca);
  border-radius: 8px;
  overflow: hidden;
  height: 1.95rem;
}
.cantidad-carrito form { display: flex; }
.cantidad-carrito form:nth-child(2) { flex: 1; }
.cantidad-carrito .paso {
  border: 0;
  background: var(--marca);
  color: #fff;
  width: 2rem;
  font-size: var(--t-lg);
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
}
.cantidad-carrito .paso:hover { background: var(--marca-oscura); }
.cantidad-carrito .cantidad {
  width: 100%;
  border: 0;
  text-align: center;
  font-size: var(--t-md);
  font-weight: 700;
  color: var(--tinta);
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
  appearance: textfield;
}
/* Sin las flechitas del navegador: aquí las flechas son los botones − y +. */
.cantidad-carrito .cantidad::-webkit-outer-spin-button,
.cantidad-carrito .cantidad::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }

/* ── Captura rápida ─────────────────────────────────────────────────────── */

.captura { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; align-items: start; padding-bottom: 2rem; }
@media (max-width: 900px) { .captura { grid-template-columns: 1fr; gap: 1.25rem; } }

.captura-texto {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: var(--t-md);
  line-height: 1.6;
  resize: vertical;
}

.renglon-malo td { background: #fdf6f6; }
.texto-error { color: var(--error); font-size: var(--t-md); }

.atajos { display: flex; gap: 1rem; }
.atajos a { font-size: var(--t-md); font-weight: 600; white-space: nowrap; }
@media (max-width: 860px) { .atajos { display: none; } }

/* ── Estado de cuenta ───────────────────────────────────────────────────── */

.tarjetas-saldo {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 1rem;
  margin-top: 1.25rem;
}
.tarjeta-saldo {
  background: #fff;
  border: 1px solid var(--linea);
  border-top: 3px solid var(--marca);
  border-radius: var(--radio);
  padding: 1.1rem 1.25rem;
  display: flex;
  flex-direction: column;
  gap: .2rem;
}
/* El rojo se reserva para lo que exige una acción del cliente: vencido, o crédito excedido. */
.tarjeta-saldo.alerta { border-top-color: var(--error); }
.tarjeta-saldo.alerta .cifra { color: var(--error); }

.etiqueta-saldo {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .05em;
  color: var(--tinta-suave); font-weight: 600;
}
.tarjeta-saldo .cifra { font-size: var(--t-3xl); font-weight: 700; font-variant-numeric: tabular-nums; }
.tarjeta-saldo .cifra small { font-size: var(--t-sm); font-weight: 500; color: var(--tinta-suave); }
.pie-saldo { font-size: var(--t-sm); color: var(--tinta-suave); }

h2.titulo-bloque { font-size: var(--t-lg); margin: 0 0 .8rem; }

.descargas { display: flex; gap: .4rem; white-space: nowrap; }

/* ── Ficha del artículo ─────────────────────────────────────────────────── */

.ficha { display: grid; grid-template-columns: 1fr 1fr; gap: 2.5rem; padding: 2rem 0; }
@media (max-width: 860px) { .ficha { grid-template-columns: 1fr; gap: 1.5rem; } }

.galeria-principal {
  background: #fff; border: 1px solid var(--linea); border-radius: var(--radio);
  aspect-ratio: 1 / 1; display: grid; place-items: center; overflow: hidden;
}
.galeria-principal img { width: 100%; height: 100%; object-fit: contain; padding: 1.5rem; }
.galeria-tiras { display: flex; gap: .6rem; margin-top: .8rem; flex-wrap: wrap; }

/* Cada miniatura es una LIGA, no una imagen suelta: la tienda se renderiza en el servidor y no
   hay JavaScript que intercambie la foto grande, así que cambiar de vista es navegar. */
.galeria-tiras a {
  display: block; border: 1px solid var(--linea); border-radius: 8px;
  background: #fff; padding: .3rem; line-height: 0;
}
.galeria-tiras a:hover { border-color: var(--marca); }
.galeria-tiras a.activa { border-color: var(--marca); box-shadow: 0 0 0 1px var(--marca); }
.galeria-tiras img { width: 60px; height: 60px; object-fit: contain; display: block; }

.ficha h1 { font-size: var(--t-3xl); margin: 0 0 .4rem; line-height: 1.25; }
.ficha-descripcion { color: var(--tinta-suave); margin: 1rem 0; white-space: pre-line; }

.datos-compra { border-top: 1px solid var(--linea); margin-top: 1.25rem; padding-top: 1.25rem; }
.nota-empaque { font-size: var(--t-sm); color: var(--tinta-suave); margin-top: .5rem; }

/* Características del artículo. Sin marco ni fondo, a diferencia de las escalas: aquélla es una
   oferta y pide destacar; ésta es la ficha técnica y se lee de corrido. Las dos columnas van a
   ancho fijo para que los nombres queden alineados y el ojo baje por una sola línea. */
.especificaciones { width: 100%; border-collapse: collapse; font-size: var(--t-md); margin: 1.1rem 0 0; }
.especificaciones caption {
  caption-side: top; text-align: left; font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-suave);
  padding: 0 0 .35rem;
}
.especificaciones th, .especificaciones td {
  padding: .4rem .7rem .4rem 0; border-top: 1px solid var(--linea); vertical-align: top;
}
.especificaciones tr:first-child th, .especificaciones tr:first-child td { border-top: none; }
.especificaciones th { text-align: left; font-weight: 500; color: var(--tinta-suave); width: 38%; }
.especificaciones td { font-weight: 600; }

/* El valor no se pinta como liga: subrayar quince renglones convertiría la ficha técnica en un
   muro azul y ninguno se leería. Se descubre al pasar encima, que es cuando el cliente ya está
   considerando ese valor en particular. */
.especificaciones td a { color: inherit; }
.especificaciones td a:hover { color: var(--marca); }

/* ── Formularios y botones ──────────────────────────────────────────────── */

.boton {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  background: var(--marca); color: #fff; border: 0; border-radius: 8px;
  padding: .65rem 1.3rem; font-size: var(--t-lg); font-weight: 600; cursor: pointer;
}
.boton:hover { background: var(--marca-oscura); text-decoration: none; }
.boton:disabled { background: #b9c4cf; cursor: not-allowed; }
.boton-secundario { background: #fff; color: var(--tinta); border: 1px solid var(--linea); }
.boton-secundario:hover { background: var(--fondo); }
.boton-bloque { width: 100%; }
.boton-chico { padding: .35rem .7rem; font-size: var(--t-sm); }

.campo { margin-bottom: 1rem; }
.campo label { display: block; font-size: var(--t-sm); font-weight: 600; margin-bottom: .3rem; }
.campo input, .campo textarea, .campo select {
  width: 100%; border: 1px solid var(--linea); border-radius: 8px;
  padding: .55rem .8rem; font-size: var(--t-lg); font-family: inherit;
}
.campo .ayuda { font-size: var(--t-sm); color: var(--tinta-suave); margin-top: .3rem; }

.fila-cantidad { display: flex; gap: .6rem; align-items: center; }
.fila-cantidad input { width: 96px; text-align: center; }

/* ── Carrito ────────────────────────────────────────────────────────────── */

.carrito { display: grid; grid-template-columns: 1fr 320px; gap: 2rem; padding: 2rem 0; align-items: start; }
@media (max-width: 860px) { .carrito { grid-template-columns: 1fr; } }

.panel {
  background: #fff; border: 1px solid var(--linea); border-radius: var(--radio); padding: 1.25rem;
}

.renglon {
  display: grid; grid-template-columns: 84px 1fr auto; gap: 1rem;
  padding: 1rem 0; border-bottom: 1px solid var(--linea); align-items: center;
}
.renglon:last-child { border-bottom: 0; }
.renglon-foto {
  width: 84px; height: 84px; object-fit: contain; background: #fff;
  border: 1px solid var(--linea); border-radius: 8px; padding: .3rem;
}
.renglon-importe {
  text-align: right; font-weight: 600; white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.resumen dl { margin: 0; }
.resumen .linea {
  display: flex; justify-content: space-between; padding: .45rem 0; font-size: var(--t-lg);
  font-variant-numeric: tabular-nums;
}
.resumen .total { border-top: 1px solid var(--linea); margin-top: .5rem; padding-top: .8rem; font-size: var(--t-xl); font-weight: 700; }

/* ── Tablas (pedidos) ───────────────────────────────────────────────────── */

/* En un teléfono ninguna de estas tablas cabe. El que se recorre es el panel que la contiene
   —todas las .tabla del portal viven dentro de uno—; si no, lo que se arrastra de lado es el
   documento entero y la página completa queda torcida. */
.panel:has(> .tabla) { overflow-x: auto; }

.tabla { width: 100%; border-collapse: collapse; font-size: var(--t-md); }
.tabla th {
  text-align: left; font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .04em;
  color: var(--tinta-suave); padding: .6rem .5rem; border-bottom: 1px solid var(--linea);
}
.tabla td { padding: .7rem .5rem; border-bottom: 1px solid var(--linea); }
.tabla tr:last-child td { border-bottom: 0; }
.num { text-align: right; font-variant-numeric: tabular-nums; }

.estado {
  display: inline-block; font-size: var(--t-xs); font-weight: 600;
  padding: .18rem .6rem; border-radius: 999px; background: #eef1f4; color: var(--tinta-suave);
}
.estado-abierto { background: #e8f6ee; color: var(--exito); }
.estado-borrador { background: #fdf3e0; color: var(--alerta); }

/* ── Estados vacíos, paginación, pie ────────────────────────────────────── */

.vacio { text-align: center; padding: 4rem 1rem; color: var(--tinta-suave); }
.vacio .icono { font-size: 3rem; opacity: .35; display: block; line-height: 0; margin-bottom: 1rem; }

.paginacion { display: flex; justify-content: space-between; align-items: center; margin-top: 2rem; gap: 1rem; }
.paginacion .paginas { color: var(--tinta-suave); font-size: var(--t-md); }

.pie {
  border-top: 1px solid var(--linea); background: #fff; margin-top: 3rem;
  padding: 2rem 0; color: var(--tinta-suave); font-size: var(--t-md);
}
.pie-fila { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 1.5rem 3rem; }
.pie-fila p { margin: .35rem 0 0; max-width: 48ch; }
.pie-marca { color: var(--tinta); font-size: var(--t-lg); }
.pie-contacto h2 {
  font-size: var(--t-xs); text-transform: uppercase; letter-spacing: .05em;
  color: var(--tinta-suave); margin: 0 0 .3rem;
}
.pie-contacto p { margin: .12rem 0; max-width: 36ch; }

h1.titulo-seccion { font-size: var(--t-3xl); margin: 0 0 .25rem; }
p.subtitulo { color: var(--tinta-suave); margin: 0 0 1.5rem; }

/* ── Seguimiento del pedido ─────────────────────────────────────────────── */
/* Es la respuesta a la llamada de «¿dónde va lo mío?»: los mismos hechos que el vendedor consulta
   en el ERP —confirmación, salidas de material, facturas—, puestos en orden y con fecha. */

h2.titulo-panel { font-size: var(--t-lg); font-weight: 700; margin: 0 0 .2rem; color: var(--tinta); }

.linea-tiempo { list-style: none; margin: .5rem 0 0; padding: 0; }
.linea-tiempo li {
  position: relative; padding: 0 0 1.1rem 1.4rem; border-left: 2px solid var(--linea);
}
.linea-tiempo li:last-child { border-left-color: transparent; padding-bottom: 0; }
.linea-tiempo li::before {
  content: ""; position: absolute; left: -7px; top: .2rem;
  width: 12px; height: 12px; border-radius: 50%;
  background: #fff; border: 2px solid var(--linea);
}
.linea-tiempo li.hecho::before { background: var(--exito); border-color: var(--exito); }
.linea-tiempo li.cancelado::before { background: var(--error); border-color: var(--error); }
.linea-tiempo .que { font-weight: 600; font-size: var(--t-md); }
.linea-tiempo .cuando { font-size: var(--t-xs); color: var(--tinta-suave); }
.linea-tiempo .detalle { font-size: var(--t-sm); color: var(--tinta-suave); }
.linea-tiempo .descargas { margin-top: .3rem; }

/* ── Orden y filtros del catálogo ───────────────────────────────────────── */

.barra-orden {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between;
  gap: .6rem 1rem; margin: 0 0 .4rem;
}
.barra-orden .apunte { color: var(--tinta-suave); font-size: var(--t-sm); }

.ordenes { display: flex; align-items: baseline; gap: .15rem; }
.ordenes a {
  padding: .25rem .6rem; border-radius: 999px; font-size: var(--t-sm);
  color: var(--tinta-suave); text-decoration: none; white-space: nowrap;
}
.ordenes a:hover { background: var(--fondo); color: var(--tinta); }
.ordenes a.activo { background: var(--marca); color: #fff; font-weight: 600; }

/* ── Direcciones de entrega ─────────────────────────────────────────────── */

.rejilla-campos { display: grid; grid-template-columns: repeat(2, 1fr); gap: 0 1rem; }
@media (max-width: 620px) { .rejilla-campos { grid-template-columns: 1fr; } }

.lista-direcciones { list-style: none; margin: 0; padding: 0; }
.lista-direcciones li { padding: .7rem 0; border-bottom: 1px solid var(--linea); }
.lista-direcciones li:last-child { border-bottom: none; padding-bottom: 0; }
.lista-direcciones li:first-child { padding-top: 0; }
.lista-direcciones .que { font-weight: 600; font-size: var(--t-md); display: flex; align-items: center; gap: .5rem; }
.lista-direcciones .detalle { font-size: var(--t-sm); color: var(--tinta-suave); }

/* ── Escalas por volumen ────────────────────────────────────────────────── */

.escalas {
  width: 100%; max-width: 340px; margin: 1.1rem 0 0;
  border-collapse: collapse; font-size: var(--t-md);
  border: 1px solid var(--linea); border-radius: 8px; overflow: hidden;
}
.escalas caption {
  caption-side: top; text-align: left; font-size: var(--t-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-suave);
  padding: 0 0 .35rem;
}
.escalas th, .escalas td { padding: .45rem .7rem; border-top: 1px solid var(--linea); }
.escalas tr:first-child th, .escalas tr:first-child td { border-top: none; }
.escalas th { text-align: left; font-weight: 500; color: var(--tinta-suave); }
.escalas td.num { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums; }
.escalas td.ahorro { font-weight: 600; color: var(--exito); width: 4rem; }

/* El gancho de la escala en la tarjeta. Verde como el ahorro de la tabla de la ficha —es el mismo
   número— y en una línea suelta bajo el precio, sin recuadro: es un dato del precio, no otra
   insignia peleándose con la de la etiqueta. */
.gancho-volumen {
  margin-top: .15rem;
  font-size: var(--t-xs); font-weight: 700;
  color: var(--exito);
  font-variant-numeric: tabular-nums;
}

/* El empujón del carrito: la escala que sigue, con lo que falta para alcanzarla. */
.empujon {
  margin: .5rem 0 0; padding: .4rem .7rem; border-radius: 8px;
  background: #e8f6ee; color: var(--exito); font-size: var(--t-sm);
}

/* Próxima entrada de lo agotado: acompaña al semáforo, nunca lo sustituye. */
.llegada {
  display: block; margin-top: .25rem; font-size: var(--t-xs); color: var(--tinta-suave);
}
