/* =========================================================
   Rojo Digital — hoja de estilos unica
   Reemplaza a main.css, index.css, tienda.css, contacto.css,
   styles.css y panelAdministrador.css.
   ========================================================= */

/* ---------- 1. Fichas de diseno (design tokens) ---------- */

/*
 * Los colores estan divididos en dos grupos, y la division es la que hace
 * posible el tema oscuro sin reescribir cada regla:
 *
 *   FIJOS      no cambian nunca. El rojo de la marca es el rojo de la marca
 *              de dia y de noche, y --blanco es el blanco que va ENCIMA del
 *              rojo (texto de botones), no el fondo de una tarjeta.
 *
 *   SEMANTICOS dicen QUE son, no de que color: "superficie", "texto",
 *              "borde". Son los unicos que se redefinen mas abajo para el
 *              tema oscuro. Cada regla del archivo usa estos, asi que
 *              cambiar el tema es cambiar siete lineas y no doscientas.
 *
 * El error clasico aca es tener una variable llamada --blanco y volverla
 * gris oscuro de noche: el nombre pasa a mentir, y el texto blanco sobre
 * los botones rojos se vuelve ilegible. Por eso estan separados.
 */
:root {
  /* ---- FIJOS: identidad de marca y contraste sobre color ---- */
  --rojo:        #dc2121;
  --rojo-oscuro: #b01a1a;
  --blanco:      #ffffff;   /* texto sobre rojo. NUNCA cambia. */

  /* ---- SEMANTICOS: se redefinen en el tema oscuro ---- */
  --fondo:        #f1f2f2;  /* fondo de la pagina */
  --superficie:   #ffffff;  /* tarjetas, paneles, la navbar */
  --superficie-2: #fcfcfd;  /* bloques dentro de una tarjeta */
  --texto:        #2f2d2d;
  --tinta:        var(--texto);        /* nombre viejo, se conserva */

  /* El velo oscuro de la portada y de su vista previa.

     NO es var(--tinta) y eso es el arreglo: --tinta sigue al tema, asi
     que en oscuro vale casi blanco. La portada la mezclaba con la foto
     (background-blend-mode: overlay) y en vez de oscurecerla la lavaba,
     dejandola palida y con un contraste raro contra el texto blanco.

     La portada es siempre un tratamiento oscuro con letras blancas en
     los dos temas, asi que su velo tiene que ser un color fijo. Por eso
     este token se define una sola vez y los bloques de tema oscuro no
     lo tocan. */
  /* ---- SUPERFICIE OSCURA FIJA ----
     Un fondo oscuro que NO sigue al tema: el pie, la pantalla de
     login y el velo de la portada son oscuros con letras claras en
     los dos temas. Escritos con --tinta se daban vuelta en oscuro,
     porque --tinta es la TINTA DEL TEXTO y ahi vale casi blanco. */
  --panel-oscuro: #2f2d2d;
  --sobre-oscuro: #ffffff;
  --portada-velo: var(--panel-oscuro);

  /* ---- SOLIDO DE CONTRASTE ----
     Lo contrario del anterior: esto SI se da vuelta con el tema,
     porque su trabajo es resaltar contra la superficie de al lado.
     En claro es un boton casi negro con letra blanca; en oscuro,
     uno casi blanco con letra oscura. */
  --solido:       #2f2d2d;
  --sobre-solido: #ffffff;
  --solido-hover: #454141;
  --tinta-media:  #575353;   /* mas oscuro que antes: a tamanos chicos el minimo tecnico no alcanza */
  --tinta-hover:  #454141;
  --gris:         #dcdcdc;             /* bordes */

  /* Campos de formulario: en reposo van tintados y al enfocarlos se
     ponen del color de la superficie. Asi el campo activo es el unico
     claro de la pantalla y salta solo. */
  --campo-fondo:  #f7f7f8;
  --campo-borde:  #a9a6b2;

  /* Avisos. Cada uno con su fondo, su borde y su color de texto, porque
     un texto oscuro sobre fondo claro no sirve al invertir el tema. */
  --exito:        #1f7a44;
  --exito-suave:  #e8f5ed;
  --exito-texto:  #14532d;
  --alerta:       #8a5a0c;
  --alerta-suave: #fbf3e3;
  --alerta-texto: #6b4508;
  --rojo-suave:   #fdeaea;
  --rojo-texto:   #7f1020;

  /* Zona de peligro: borrados y acciones sin vuelta atras. */
  --peligro-suave: #fdf6f6;
  --peligro-borde: #e9b4b4;

  /* Tipografias: ya se cargan en el <head> del fragmento */
  --fuente-titulo: "Playfair Display", Georgia, serif;
  --fuente-texto:  "Montserrat", system-ui, -apple-system, "Segoe UI", sans-serif;

  /* Escala de espaciado: multiplos de 4px, para que todo se alinee */
  --e1: 0.25rem;
  --e2: 0.5rem;
  --e3: 0.75rem;
  --e4: 1rem;
  --e5: 1.5rem;
  --e6: 2rem;
  --e7: 3rem;
  --e8: 4rem;

  --radio:       6px;
  --radio-chico: 4px;

  --sombra:       0 1px 2px rgba(47, 45, 45, .06), 0 6px 20px -8px rgba(47, 45, 45, .18);
  --sombra-fuerte:0 2px 6px rgba(47, 45, 45, .10), 0 18px 40px -18px rgba(47, 45, 45, .35);

  --ancho-maximo: 1200px;
  --alto-navbar:  68px;

  /* Le avisa al navegador de que tono es la pagina, para que pinte las
     barras de scroll y los controles nativos a juego. */
  color-scheme: light;
}

/* =========================================================
   TEMA OSCURO
   =========================================================

   Se activa de dos maneras, y el orden importa:

   1. data-tema="oscuro" en <html>: lo eligio la persona con el boton.
      Manda sobre todo lo demas.
   2. prefers-color-scheme: la configuracion del sistema operativo del
      visitante. Solo se aplica si NO eligio nada todavia, por eso el
      :not([data-tema]). Sin esa guarda, alguien con Windows en oscuro
      que elige el tema claro volveria a ver oscuro.

   Los colores no son el claro invertido. El fondo es gris muy oscuro y
   no negro puro, y el texto es gris muy claro y no blanco puro: negro
   sobre blanco puro produce un contraste que cansa la vista y hace que
   las letras finas "vibren". Y el rojo se aclara un poco, porque el
   #dc2121 sobre fondo oscuro queda apagado y sin contraste suficiente.
   ========================================================= */

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) {
    color-scheme: dark;

    --rojo:        #ff5a5a;
    --rojo-oscuro: #ff7b7b;

    --fondo:        #17161a;
    --superficie:   #201f24;
    --superficie-2: #26252b;
    --texto:        #ece9e6;
    --tinta-media:  #b9b4bd;
    --tinta-hover:  #34323a;
    --gris:         #3a3840;

    /* El solido se da vuelta: boton claro con letra oscura. El panel
       oscuro y su texto NO se redefinen, a proposito. */
    --solido:       #ece9e6;
    --sobre-solido: #17161a;
    --solido-hover: #ffffff;

    --campo-fondo:  #2b2a31;
    --campo-borde:  #5f5d6b;

    --exito:        #4ade80;
    --exito-suave:  #14301f;
    --exito-texto:  #a7f3c4;
    --alerta:       #fbbf5a;
    --alerta-suave: #33270f;
    --alerta-texto: #f5d9a0;
    --rojo-suave:   #3a1518;
    --rojo-texto:   #ffb4b4;

    --peligro-suave: #331419;
    --peligro-borde: #6b2a30;

    /* Las sombras suaves no se ven sobre fondo oscuro: se refuerzan. */
    --sombra:        0 1px 2px rgba(0, 0, 0, .40), 0 6px 20px -8px rgba(0, 0, 0, .60);
    --sombra-fuerte: 0 2px 6px rgba(0, 0, 0, .50), 0 18px 40px -18px rgba(0, 0, 0, .75);
  }
}

/* La eleccion explicita con el boton. Repite los valores porque tiene que
   ganarle a la media query de arriba en los dos sentidos: prender el
   oscuro con el sistema en claro, y prender el claro con el sistema en
   oscuro. Una sola de las dos reglas no alcanza. */
:root[data-tema="oscuro"] {
  color-scheme: dark;

  --rojo:        #ff5a5a;
  --rojo-oscuro: #ff7b7b;

  --fondo:        #17161a;
  --superficie:   #201f24;
  --superficie-2: #26252b;
  --texto:        #ece9e6;
  --tinta-media:  #b9b4bd;
  --tinta-hover:  #34323a;
  --gris:         #3a3840;

  --solido:       #ece9e6;
  --sobre-solido: #17161a;
  --solido-hover: #ffffff;

  --campo-fondo:  #2b2a31;
  --campo-borde:  #5f5d6b;

  --exito:        #4ade80;
  --exito-suave:  #14301f;
  --exito-texto:  #a7f3c4;
  --alerta:       #fbbf5a;
  --alerta-suave: #33270f;
  --alerta-texto: #f5d9a0;
  --rojo-suave:   #3a1518;
  --rojo-texto:   #ffb4b4;

  --peligro-suave: #331419;
  --peligro-borde: #6b2a30;

  --sombra:        0 1px 2px rgba(0, 0, 0, .40), 0 6px 20px -8px rgba(0, 0, 0, .60);
  --sombra-fuerte: 0 2px 6px rgba(0, 0, 0, .50), 0 18px 40px -18px rgba(0, 0, 0, .75);
}

/* ---------- 2. Reset ---------- */

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

body, h1, h2, h3, h4, p, ul, ol, li, figure, blockquote, dl, dd {
  margin: 0;
  padding: 0;
}

ul, ol { list-style: none; }

body {
  min-height: 100vh;
  background: var(--fondo);
  color: var(--tinta);
  font-family: var(--fuente-texto);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

a { color: inherit; text-decoration: none; }

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

button { cursor: pointer; background: none; border: none; }

:focus-visible {
  outline: 2px solid var(--rojo);
  outline-offset: 3px;
  border-radius: var(--radio-chico);
}

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

/* ---------- 3. Tipografia ---------- */

h1, h2, h3, h4 {
  font-family: var(--fuente-titulo);
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

h1 { font-size: clamp(1.9rem, 1.4rem + 2.2vw, 3rem); }
h2 { font-size: clamp(1.5rem, 1.25rem + 1.1vw, 2.1rem); }
h3 { font-size: clamp(1.15rem, 1.05rem + .45vw, 1.4rem); }

.seccion-titulo {
  display: flex;
  align-items: center;
  gap: var(--e4);
  margin-bottom: var(--e5);
}
.seccion-titulo::after {
  content: "";
  flex: 1;
  height: 2px;
  background: var(--gris);
}

.texto-apagado { color: var(--tinta-media); }

/* ---------- 4. Estructura ---------- */

.contenedor {
  width: 100%;
  max-width: var(--ancho-maximo);
  margin-inline: auto;
  padding-inline: var(--e4);
}

.seccion { padding-block: var(--e7); }

@media (min-width: 768px) {
  .contenedor { padding-inline: var(--e5); }
  .seccion    { padding-block: var(--e8); }
}

/* ---------- 5. Botones ---------- */

.boton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  padding: var(--e3) var(--e5);
  border-radius: var(--radio);
  font-size: .92rem;
  font-weight: 600;
  text-align: center;
  border: 2px solid transparent;
  transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}

.boton--primario { background: var(--rojo); color: var(--blanco); }
.boton--primario:hover { background: var(--rojo-oscuro); }

.boton--borde { border-color: var(--rojo); color: var(--rojo); background: transparent; }
.boton--borde:hover { background: var(--rojo); color: var(--blanco); }

/* El boton solido que no es rojo: "Importar", por ejemplo.

   Antes era background:var(--tinta) con color:var(--blanco), y en el
   tema oscuro --tinta vale casi BLANCO: quedaba un boton blanco con
   letra blanca, ilegible. Y al pasarle el mouse saltaba a
   --tinta-hover, que en oscuro SI es oscuro, asi que el boton se daba
   vuelta entero de golpe. Eso es el "color que cambia diferente". */
.boton--neutro { background: var(--solido); color: var(--sobre-solido); }
.boton--neutro:hover { background: var(--solido-hover); }

.boton--wsp { background: #25D366; color: #06331a; }
.boton--wsp:hover { background: #1eb356; color: var(--blanco); }

.boton--chico { padding: var(--e2) var(--e3); font-size: .82rem; }
.boton--ancho { width: 100%; }

.boton[disabled] { opacity: .5; cursor: not-allowed; }

/* ---------- 6. Barra de navegacion ---------- */

.navbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--superficie);
  border-bottom: 1px solid var(--gris);
}

.navbar__interior {
  max-width: var(--ancho-maximo);
  margin-inline: auto;
  min-height: var(--alto-navbar);
  padding-inline: var(--e4);
  display: flex;
  align-items: center;
  gap: var(--e4);
}

.navbar__marca {
  font-family: var(--fuente-titulo);
  font-size: 1.35rem;
  font-weight: 900;
  letter-spacing: -.01em;
  color: var(--rojo);
  white-space: nowrap;
}
/* Solo el segundo tramo va en tinta: el primero ("Rojo") queda en rojo,
   que es la marca. Antes esta regla alcanzaba a los dos spans y se comia
   el color del padre, asi que el nombre salia todo oscuro. */
.navbar__marca span + span { color: var(--tinta); }

.navbar__enlaces {
  display: none;
  gap: var(--e5);
  margin-left: var(--e6);
}

.navbar__enlaces a {
  font-size: .92rem;
  font-weight: 500;
  padding-block: var(--e2);
  border-bottom: 2px solid transparent;
}
.navbar__enlaces a:hover,
.navbar__enlaces a.activo { border-bottom-color: var(--rojo); color: var(--rojo); }

.navbar__acciones {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--e3);
}

.navbar__redes { display: none; gap: var(--e3); }
.navbar__redes a {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--fondo);
  transition: background-color .18s ease;
}
.navbar__redes a:hover { background: var(--gris); }

.navbar__hamburguesa {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: var(--radio-chico);
  border: 1px solid var(--gris);
}

@media (min-width: 900px) {
  .navbar__enlaces    { display: flex; }
  .navbar__redes      { display: flex; }
  .navbar__hamburguesa{ display: none; }
}

/* Menu desplegable en pantallas chicas */
.menu-movil {
  display: none;
  background: var(--superficie);
  border-bottom: 1px solid var(--gris);
  padding: var(--e4);
}
.menu-movil.abierto { display: block; }
.menu-movil a {
  display: block;
  padding: var(--e3) var(--e2);
  border-bottom: 1px solid var(--fondo);
  font-weight: 500;
}
.menu-movil a:last-child { border-bottom: none; }

@media (min-width: 900px) {
  .menu-movil, .menu-movil.abierto { display: none; }
}

/* ---------- 7. Buscador ---------- */

.buscador { display: flex; align-items: center; }

.buscador input {
  width: 100%;
  max-width: 260px;
  padding: var(--e2) var(--e3);
  border: 1px solid var(--gris);
  border-radius: var(--radio) 0 0 var(--radio);
  background: var(--fondo);
  font-size: .88rem;
}
.buscador input:focus { outline: none; border-color: var(--rojo); }

.buscador button {
  padding: var(--e2) var(--e3);
  background: var(--rojo);
  color: var(--blanco);
  border-radius: 0 var(--radio) var(--radio) 0;
  border: 1px solid var(--rojo);
  font-size: .88rem;
}

/* ---------- 8. Portada ---------- */

.portada {
  position: relative;
  min-height: 52vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--e8) var(--e4);
  /* La imagen la pone la plantilla con style="", porque es configurable
     por comercio. Este degradado es el velo que va encima. */
  background-color: var(--portada-velo);
  background-blend-mode: overlay;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  color: var(--blanco);
}
.portada::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(47,45,45,.62), rgba(47,45,45,.72));
}
.portada__contenido { position: relative; z-index: 1; }

.portada__contenido { max-width: 46rem; display: grid; gap: var(--e4); justify-items: center; }
.portada h1 { color: var(--blanco); }
.portada p { font-size: 1.05rem; opacity: .92; max-width: 38rem; }
.portada__botones { display: flex; flex-wrap: wrap; gap: var(--e3); justify-content: center; margin-top: var(--e2); }

/* ---------- 9. Grilla de productos ---------- */

.grilla-productos {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: var(--e4);
}

@media (min-width: 640px) {
  .grilla-productos { grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--e5); }
}

/* container-type convierte a la tarjeta en una "caja de
   referencia": a partir de acá se puede preguntar cuánto mide ELLA,
   en vez de cuánto mide la ventana. Ver .tarjeta__acciones. */
.tarjeta {
  container-type: inline-size;
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .18s ease, box-shadow .18s ease;
}
.tarjeta:hover { transform: translateY(-3px); box-shadow: var(--sombra-fuerte); }

.tarjeta__figura {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--fondo);
  overflow: hidden;
}
.tarjeta__figura img {
  width: 100%; height: 100%;
  object-fit: cover;
}

.tarjeta__insignia {
  position: absolute;
  top: var(--e2); left: var(--e2);
  background: var(--rojo);
  color: var(--blanco);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  padding: var(--e1) var(--e2);
  border-radius: var(--radio-chico);
}

.tarjeta__cuerpo {
  padding: var(--e4);
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  flex: 1;
}

.tarjeta__marca {
  font-size: .7rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tinta-media);
}

.tarjeta__nombre {
  font-family: var(--fuente-texto);
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.35;
}
.tarjeta__nombre a:hover { color: var(--rojo); }

.tarjeta__precio {
  font-family: var(--fuente-titulo);
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--rojo);
  margin-top: auto;
}

/* Los dos botones, apilados por defecto.

   ANTES ESTO ERA UNA @media (min-width: 400px) Y ESE ERA EL BUG:
   preguntaba por el ancho de la VENTANA para decidir algo que
   depende del ancho de la TARJETA. Con la ventana en 430px la
   grilla arma dos columnas de 191px, la regla se activaba igual, y
   los dos botones —72px + 101px + separación, más los 32px de
   relleno de la tarjeta— no entraban en 191px. "+ Consulta" se
   salía 8px por el borde derecho.

   @container pregunta por la tarjeta, que es lo que importa. Y el
   umbral va en rem a propósito: con la letra en "grande" o
   "enorme" los botones crecen, el rem crece con ellos, y el umbral
   se corre solo. Con un valor en px, subir el tamaño de letra
   volvería a romperlo. */
.tarjeta__acciones {
  display: grid;
  gap: var(--e2);
  margin-top: var(--e2);
}

@container (min-width: 14rem) {
  .tarjeta__acciones { grid-template-columns: 1fr auto; }
}

/* Y por si acaso: que el texto de un botón pueda achicarse en vez de
   empujar. Un botón que se sale es peor que uno con el texto justo. */
.tarjeta__acciones .boton { min-width: 0; }

/* ---------- 10. Filtros ---------- */

.barra-filtros {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  margin-bottom: var(--e5);
}

.filtro {
  padding: var(--e2) var(--e4);
  border: 1px solid var(--gris);
  border-radius: 999px;
  background: var(--superficie);
  font-size: .85rem;
  font-weight: 500;
  transition: all .16s ease;
}
.filtro:hover { border-color: var(--rojo); color: var(--rojo); }
.filtro.activo { background: var(--rojo); border-color: var(--rojo); color: var(--blanco); }

/* ---------- 11. Ficha de producto ---------- */

.ficha { display: grid; gap: var(--e5); }

@media (min-width: 860px) {
  .ficha { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--e7); align-items: start; }
}

.ficha__figura {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  overflow: hidden;
  aspect-ratio: 1 / 1;
}
.ficha__figura img { width: 100%; height: 100%; object-fit: cover; }

.ficha__datos { display: flex; flex-direction: column; gap: var(--e4); }

.ficha__precio {
  font-family: var(--fuente-titulo);
  font-size: clamp(2rem, 1.6rem + 1.6vw, 2.8rem);
  font-weight: 700;
  color: var(--rojo);
}

.ficha__lista { display: grid; gap: var(--e2); }
.ficha__lista div {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: var(--e3);
  padding-block: var(--e2);
  border-bottom: 1px solid var(--gris);
  font-size: .92rem;
}
.ficha__lista dt { color: var(--tinta-media); }

.ficha__acciones { display: grid; gap: var(--e3); margin-top: var(--e2); }
@media (min-width: 520px) { .ficha__acciones { grid-template-columns: 1fr 1fr; } }

.migas {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  font-size: .82rem;
  color: var(--tinta-media);
  margin-bottom: var(--e5);
}
.migas a:hover { color: var(--rojo); }

/* ---------- 12. Lista de consulta (WhatsApp) ---------- */

.consulta-boton {
  position: fixed;
  right: var(--e4);
  bottom: var(--e4);
  z-index: 60;
  display: none;
  align-items: center;
  gap: var(--e2);
  padding: var(--e3) var(--e5);
  border-radius: 999px;
  background: #25D366;
  color: #06331a;
  font-weight: 700;
  box-shadow: var(--sombra-fuerte);
}
.consulta-boton.visible { display: inline-flex; }

.consulta-boton__contador {
  display: grid;
  place-items: center;
  min-width: 22px; height: 22px;
  padding-inline: 6px;
  border-radius: 999px;
  background: var(--solido);
  color: var(--sobre-solido);
  font-size: .74rem;
}

.panel-consulta {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: none;
  background: rgba(47, 45, 45, .5);
}
.panel-consulta.abierto { display: block; }

.panel-consulta__caja {
  position: absolute;
  right: 0; top: 0; bottom: 0;
  width: min(420px, 100%);
  background: var(--superficie);
  display: flex;
  flex-direction: column;
  box-shadow: var(--sombra-fuerte);
}

.panel-consulta__cabecera {
  padding: var(--e4);
  border-bottom: 1px solid var(--gris);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
}

.panel-consulta__items {
  flex: 1;
  overflow-y: auto;
  padding: var(--e4);
  display: flex;
  flex-direction: column;
  gap: var(--e3);
}

.panel-consulta__item {
  display: grid;
  grid-template-columns: 56px 1fr auto;
  gap: var(--e3);
  align-items: center;
  padding-bottom: var(--e3);
  border-bottom: 1px solid var(--fondo);
}
.panel-consulta__item img {
  width: 56px; height: 56px;
  object-fit: cover;
  border-radius: var(--radio-chico);
}
.panel-consulta__item strong { font-size: .88rem; font-weight: 600; display: block; }
.panel-consulta__item span { font-size: .82rem; color: var(--rojo); font-weight: 600; }

.panel-consulta__quitar {
  color: var(--tinta-media);
  font-size: 1.2rem;
  line-height: 1;
  padding: var(--e2);
}
.panel-consulta__quitar:hover { color: var(--rojo); }

.panel-consulta__pie {
  padding: var(--e4);
  border-top: 1px solid var(--gris);
  display: grid;
  gap: var(--e3);
}

.panel-consulta__vacio {
  text-align: center;
  color: var(--tinta-media);
  padding: var(--e7) var(--e4);
  font-size: .92rem;
}

/* ---------- 13. Formularios ---------- */

.campo { display: grid; gap: var(--e2); margin-bottom: var(--e4); }

.campo label { font-size: .85rem; font-weight: 600; }

.campo input[type="text"],
.campo input[type="number"],
.campo input[type="email"],
.campo input[type="password"],
.campo input[type="file"],
.campo textarea,
.campo select {
  width: 100%;
  padding: var(--e3);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  background: var(--superficie);
}
.campo input:focus, .campo textarea:focus, .campo select:focus {
  outline: none;
  border-color: var(--rojo);
  box-shadow: 0 0 0 3px var(--rojo-suave);
}
.campo textarea { min-height: 110px; resize: vertical; }

.campo--casilla {
  display: flex;
  align-items: flex-start;
  gap: var(--e3);
}
.campo--casilla input { width: 18px; height: 18px; margin-top: 3px; flex: none; accent-color: var(--rojo); }
.campo--casilla label { font-weight: 500; }

.campo__error { color: var(--rojo); font-size: .8rem; }
.campo input.con-error, .campo textarea.con-error { border-color: var(--rojo); }

/* align-items: start y no el "stretch" que trae grid por defecto.

   Sin esto, los dos campos de una fila se estiran a la altura del mas
   alto. Y como .campo es a su vez un grid, ese estiron le llega al
   input: el campo de la izquierda, que no tiene texto de ayuda, le
   quedaba el recuadro al doble de alto que el de al lado, que si lo
   tiene. Parecia un input distinto y era la fila empujandolo.

   Es la misma trampa que ya estaba resuelta en .filtros-panel__campos. */
.formulario-fila { display: grid; gap: var(--e4); align-items: start; }
@media (min-width: 640px) { .formulario-fila--2 { grid-template-columns: 1fr 1fr; } }

/* ---------- 14. Avisos ---------- */

.aviso {
  padding: var(--e3) var(--e4);
  border-radius: var(--radio-chico);
  border-left: 4px solid;
  margin-bottom: var(--e4);
  font-size: .92rem;
}
.aviso--exito  { background: var(--exito-suave);  border-color: var(--exito);  color: var(--exito-texto); }
.aviso--error  { background: var(--rojo-suave);   border-color: var(--rojo);   color: var(--rojo-texto); }
.aviso--alerta { background: var(--alerta-suave); border-color: var(--alerta); color: var(--alerta-texto); }
.aviso ul { margin-top: var(--e2); display: grid; gap: var(--e1); }
.aviso li { font-size: .86rem; }

/* ---------- 15. Panel de administracion ---------- */

.admin { display: grid; gap: var(--e5); }

@media (min-width: 1000px) {
  .admin { grid-template-columns: minmax(0, 380px) minmax(0, 1fr); align-items: start; }
}

.panel {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  padding: var(--e5);
}
.panel__titulo {
  font-family: var(--fuente-titulo);
  font-size: 1.25rem;
  margin-bottom: var(--e4);
  padding-bottom: var(--e3);
  border-bottom: 2px solid var(--rojo);
}

.tabla-envoltorio { overflow-x: auto; }

.tabla { width: 100%; border-collapse: collapse; font-size: .88rem; }
.tabla th, .tabla td {
  padding: var(--e3);
  text-align: left;
  border-bottom: 1px solid var(--gris);
  vertical-align: middle;
}
.tabla th {
  font-size: .72rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--tinta-media);
  white-space: nowrap;
}
.tabla tbody tr:hover { background: var(--fondo); }
.tabla td.numero { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tabla__miniatura { width: 44px; height: 44px; object-fit: cover; border-radius: var(--radio-chico); }
.tabla__acciones { display: flex; gap: var(--e2); }

.etiqueta {
  display: inline-block;
  padding: 2px var(--e2);
  border-radius: var(--radio-chico);
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.etiqueta--si   { background: var(--exito-suave); color: var(--exito); }
.etiqueta--no   { background: var(--gris);        color: var(--tinta-media); }
.etiqueta--dest { background: var(--rojo-suave);  color: var(--rojo); }

.metricas { display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: var(--e3); margin-bottom: var(--e5); }
.metrica { background: var(--superficie); border: 1px solid var(--gris); border-radius: var(--radio); padding: var(--e4); }
.metrica__n { font-family: var(--fuente-titulo); font-size: 1.8rem; font-weight: 700; line-height: 1; }
.metrica__t { font-size: .78rem; color: var(--tinta-media); margin-top: var(--e1); }

/* ---------- 16. Login ---------- */

.login-pantalla {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--e5);
  background-color: var(--panel-oscuro);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  position: relative;
}
.login-pantalla::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(47,45,45,.75), rgba(47,45,45,.85));
}
.login-caja { position: relative; z-index: 1; }
.login-caja {
  width: min(400px, 100%);
  background: var(--superficie);
  border-radius: var(--radio);
  padding: var(--e6);
  box-shadow: var(--sombra-fuerte);
}
.login-caja h1 { font-size: 1.6rem; margin-bottom: var(--e2); }
.login-caja > p { color: var(--tinta-media); font-size: .9rem; margin-bottom: var(--e5); }

/* ---------- 17. Contacto ---------- */

.contacto-grilla { display: grid; gap: var(--e5); }
@media (min-width: 860px) { .contacto-grilla { grid-template-columns: 1fr 1fr; gap: var(--e7); } }

.mapa {
  width: 100%;
  min-height: 320px;
  border: 1px solid var(--gris);
  border-radius: var(--radio);
}

.dato-contacto {
  display: flex;
  gap: var(--e3);
  padding-block: var(--e3);
  border-bottom: 1px solid var(--gris);
}
.dato-contacto:last-child { border-bottom: none; }
.dato-contacto strong { display: block; font-size: .82rem; text-transform: uppercase; letter-spacing: .05em; color: var(--tinta-media); }

/* ---------- 18. Pie ---------- */

/* El pie es oscuro con letras claras en LOS DOS TEMAS. Escrito con
   --tinta se daba vuelta: en oscuro quedaba un pie casi blanco, con
   el texto en gris oscuro, los titulos en blanco sobre blanco y la
   linea divisoria (rgba blanca) invisible. */
.pie {
  background: var(--panel-oscuro);
  color: #b9b4bd;
  margin-top: var(--e8);
  padding-block: var(--e7) var(--e5);
}
.pie__grilla {
  display: grid;
  gap: var(--e5);
  padding-bottom: var(--e5);
  border-bottom: 1px solid rgba(255,255,255,.12);
}
@media (min-width: 720px) { .pie__grilla { grid-template-columns: 1.4fr 1fr 1fr; gap: var(--e6); } }

.pie h4 {
  font-family: var(--fuente-texto);
  font-size: .8rem;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--blanco);
  margin-bottom: var(--e3);
}
.pie p, .pie a { font-size: .88rem; line-height: 1.7; }
.pie a:hover { color: var(--blanco); }
.pie ul { display: grid; gap: var(--e2); }
.pie__marca { font-family: var(--fuente-titulo); font-size: 1.3rem; font-weight: 900; color: var(--blanco); margin-bottom: var(--e2); }
.pie__legal { padding-top: var(--e4); font-size: .8rem; text-align: center; color: var(--tinta-media); }

/* ---------- 19. Vacios y errores ---------- */

.estado-vacio {
  text-align: center;
  padding: var(--e8) var(--e4);
  background: var(--superficie);
  border: 1px dashed var(--gris);
  border-radius: var(--radio);
}
.estado-vacio h3 { margin-bottom: var(--e2); }
.estado-vacio p { color: var(--tinta-media); margin-bottom: var(--e4); }

.pantalla-error {
  min-height: 70vh;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--e6);
}
.pantalla-error__codigo {
  font-family: var(--fuente-titulo);
  font-size: clamp(4rem, 3rem + 6vw, 8rem);
  font-weight: 900;
  color: var(--rojo);
  line-height: 1;
}

/* ---------- 20. Vista de lista (catálogos sin fotos) ---------- */

.lista-productos {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--gris);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  overflow: hidden;
}

.fila-producto {
  background: var(--superficie);
  padding: var(--e3) var(--e4);
  display: grid;
  gap: var(--e2) var(--e4);
  grid-template-columns: 1fr;
  align-items: center;
  transition: background-color .14s ease;
}
.fila-producto:hover { background: var(--fondo); }

@media (min-width: 700px) {
  .fila-producto { grid-template-columns: 1fr auto auto; }
}

.fila-producto__datos { min-width: 0; }

.fila-producto__nombre {
  font-size: .95rem;
  font-weight: 600;
  line-height: 1.35;
  overflow-wrap: anywhere;
}
.fila-producto__nombre a:hover { color: var(--rojo); }

.fila-producto__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e1) var(--e3);
  margin-top: 2px;
  font-size: .76rem;
  color: var(--tinta-media);
}
.fila-producto__meta code {
  font-family: ui-monospace, "Courier New", monospace;
  background: var(--fondo);
  padding: 0 4px;
  border-radius: 3px;
}

.fila-producto__precio {
  font-family: var(--fuente-titulo);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--rojo);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.fila-producto__precio small {
  display: block;
  font-family: var(--fuente-texto);
  font-size: .68rem;
  font-weight: 500;
  color: var(--tinta-media);
  text-align: right;
}

.fila-producto__acciones { display: flex; gap: var(--e2); }

/* ---------- 21. Paginado ---------- */

.paginado {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--e2);
  margin-top: var(--e6);
}

.paginado a, .paginado span {
  min-width: 38px;
  padding: var(--e2) var(--e3);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  background: var(--superficie);
  font-size: .85rem;
  text-align: center;
  font-variant-numeric: tabular-nums;
}
.paginado a:hover { border-color: var(--rojo); color: var(--rojo); }
.paginado .actual { background: var(--rojo); border-color: var(--rojo); color: var(--blanco); font-weight: 600; }
.paginado .inerte { opacity: .4; }

.paginado__info {
  border: none;
  background: none;
  color: var(--tinta-media);
  font-size: .82rem;
}

/* ---------- 22. Barra de filtros del panel ---------- */

.filtros-panel {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  padding: var(--e4);
  margin-bottom: var(--e4);
  display: grid;
  gap: var(--e3);
}

.filtros-panel__campos {
  display: grid;
  gap: var(--e3);
  grid-template-columns: 1fr;
}
@media (min-width: 720px) {
  /* Arriba y no abajo. Con align-items:end, un campo que lleva una
     linea de ayuda debajo se acomodaba subiendo su input, y quedaban
     los cinco recuadros a distintas alturas. Alineando arriba, las
     etiquetas y los inputs quedan en linea y la ayuda cuelga abajo,
     que es donde no molesta. */
  .filtros-panel__campos { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}
@media (min-width: 1024px) {
  /* Tres y tres. Con seis campos, meterlos todos a lo ancho antes de
     esta medida deja cada uno tan angosto que no se lee el placeholder. */
  .filtros-panel__campos { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (min-width: 1400px) {
  /* Los seis filtros en una sola fila: se ven todos juntos, que es como
     se filtra en el sistema de facturacion. Las columnas no son iguales
     porque los campos no piden lo mismo: un codigo entra en poco, un
     nombre necesita aire, y los desplegables tienen opciones cortas. */
  .filtros-panel__campos {
    grid-template-columns: .8fr 1.1fr 1.1fr 1fr .75fr .85fr;
  }
}
.filtros-panel .campo { margin-bottom: 0; }

.acciones-masivas {
  border-top: 1px dashed var(--gris);
  padding-top: var(--e3);
  display: grid;
  gap: var(--e3);
}
.acciones-masivas__titulo {
  font-size: .74rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--tinta-media);
  font-weight: 600;
}
.acciones-masivas__fila {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
}
.acciones-masivas input[type="text"] {
  flex: 1 1 180px;
  min-width: 0;
  padding: var(--e2) var(--e3);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
}

/* ---------- 23. Utilidades ---------- */

.oculto { display: none !important; }
.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;
}

/* ---------- 24. Importación en curso ---------- */

.importando {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin-top: var(--e3);
  padding: var(--e3) var(--e4);
  background: var(--alerta-suave);
  border-left: 3px solid var(--alerta);
  border-radius: 0 var(--radio-chico) var(--radio-chico) 0;
  font-size: .86rem;
}

.importando__giro {
  flex: none;
  width: 20px;
  height: 20px;
  border: 3px solid var(--gris);
  border-top-color: var(--alerta);
  border-radius: 50%;
  animation: girar .8s linear infinite;
}

@keyframes girar { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
  .importando__giro { animation: none; border-top-color: var(--gris); }
}

/* ---------- 25. Zona peligrosa ---------- */

.zona-peligro {
  margin-top: var(--e3);
  padding-top: var(--e3);
  border-top: 1px dashed var(--rojo);
}

.zona-peligro__titulo {
  font-size: .74rem;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--rojo);
  font-weight: 600;
  margin-bottom: var(--e2);
}

/* ---------- 26. Vista previa de la portada en el panel ---------- */

.portada-previa {
  position: relative;
  border-radius: var(--radio);
  overflow: hidden;
  margin-bottom: var(--e4);
  border: 1px solid var(--gris);
  background: var(--portada-velo);
  aspect-ratio: 21 / 9;
}

.portada-previa img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: .55;
}

.portada-previa__texto {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--e1);
  padding: var(--e4);
  text-align: center;
  color: var(--blanco);
}

.portada-previa__texto strong {
  font-family: var(--fuente-titulo);
  font-size: clamp(1rem, .8rem + 1.4vw, 1.5rem);
  line-height: 1.15;
}

.portada-previa__texto span {
  font-size: .78rem;
  opacity: .9;
  max-width: 40ch;
}

/* =========================================================
   12. Panel de administración: herramientas plegables
   =========================================================

   El panel dejó de ser dos columnas. Antes la tabla compartía
   la pantalla con cuatro formularios que casi nunca se usan al
   mismo tiempo que se mira la lista, y en un catálogo de 27.000
   productos la lista es lo que importa: ahora ocupa todo el ancho
   y las herramientas viven plegadas arriba.
   ========================================================= */

/* El panel necesita más ancho que la tienda: son seis columnas de
   tabla, no tarjetas de producto. */
.contenedor--ancho { max-width: 1600px; }

.herramientas {
  display: grid;
  gap: var(--e3);
  margin-bottom: var(--e5);
}

@media (min-width: 1100px) {
  /* En pantallas anchas las cuatro herramientas entran en fila:
     cerradas ocupan una tira fina y no empujan la tabla hacia abajo. */
  .herramientas { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; }
}

.plegable {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  overflow: hidden;
}

.plegable[open] {
  box-shadow: var(--sombra);
  /* Abierto ocupa las dos columnas: los formularios necesitan el ancho. */
  grid-column: 1 / -1;
}

.plegable__cabecera {
  display: flex;
  align-items: center;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  cursor: pointer;
  font-weight: 600;
  list-style: none;
  user-select: none;
}

/* El triángulo por defecto de <summary> se saca en los dos motores. */
.plegable__cabecera::-webkit-details-marker { display: none; }
.plegable__cabecera::marker { content: ""; }

.plegable__cabecera::before {
  content: "▸";
  color: var(--rojo);
  font-size: .9rem;
  transition: transform .15s ease;
  flex: none;
}
.plegable[open] > .plegable__cabecera::before { transform: rotate(90deg); }

.plegable__cabecera:hover { background: var(--superficie-2); }

.plegable__titulo { flex: none; }

.plegable__pista {
  color: var(--tinta-media);
  font-weight: 400;
  font-size: .8rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.plegable__cuerpo {
  padding: 0 var(--e4) var(--e4);
  border-top: 1px solid var(--gris);
  padding-top: var(--e4);
}

/* ---------- Filtros: cuatro campos combinables ---------- */

.filtros-panel__acciones {
  display: flex;
  align-items: center;
  gap: var(--e3);
  flex-wrap: wrap;
  margin-top: var(--e3);
}

/* ---------- Pantalla de bloqueo ----------
   Cubre todo mientras el servidor trabaja. Sin esto, un archivo
   grande parece no hacer nada, se vuelve a apretar, y dos
   importaciones simultáneas duplican el catálogo. */

.bloqueo {
  position: fixed;
  inset: 0;
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(47, 45, 45, .55);
  backdrop-filter: blur(2px);
}

.bloqueo__caja {
  background: var(--superficie);
  border-radius: var(--radio);
  box-shadow: var(--sombra-fuerte);
  padding: var(--e6);
  max-width: 380px;
  text-align: center;
  display: grid;
  justify-items: center;
  gap: var(--e3);
}

.bloqueo__caja .importando__giro { width: 32px; height: 32px; border-width: 4px; }

/* =========================================================
   24. Legibilidad de los formularios del panel

   El problema: campos blancos, sobre paneles blancos, sobre
   fondo casi blanco. Todo el mismo valor y el ojo no encuentra
   dónde empieza y termina cada cosa.

   La solución es invertir la convención: el campo en reposo va
   con fondo tintado, y se pone BLANCO cuando lo estás usando.
   Así el campo activo es el único claro de la pantalla y salta
   solo, sin necesidad de bordes gruesos ni colores fuertes.

   Está acotado al panel a propósito: la tienda ya está aprobada
   y no hay motivo para cambiarle el aspecto.
   ========================================================= */

.plegable .campo input[type="text"],
.plegable .campo input[type="number"],
.plegable .campo input[type="search"],
.plegable .campo input[type="file"],
.plegable .campo textarea,
.plegable .campo select,
.filtros-panel .campo input[type="text"],
.filtros-panel .campo input[type="search"],
.filtros-panel .campo select,
.acciones-masivas input[type="text"] {
  background: var(--campo-fondo);
  border: 1px solid var(--campo-borde);
  box-shadow: inset 0 1px 2px rgba(47, 45, 45, .05);
}

.plegable .campo input:focus,
.plegable .campo textarea:focus,
.plegable .campo select:focus,
.filtros-panel .campo input:focus,
.filtros-panel .campo select:focus,
.acciones-masivas input[type="text"]:focus {
  background: var(--superficie);
  box-shadow: 0 0 0 3px var(--rojo-suave);
}

/* La etiqueta también necesita jerarquía: hoy compite con el texto
   de ayuda que va abajo y los dos se leen igual. */
.plegable .campo > label,
.filtros-panel .campo > label {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-media);
}

/* Los obligatorios se marcan con el asterisco en rojo y no solo
   con un asterisco negro que se pierde. */
.plegable .campo > label::after { color: var(--rojo); }

/* ---------- Grupos dentro de un formulario largo ----------
   El formulario de producto son diez campos seguidos. Partido en
   bloques con título se recorre mucho más rápido. */

.grupo-campos {
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  padding: var(--e4);
  margin-bottom: var(--e4);
  background: var(--superficie-2);
}

.grupo-campos__titulo {
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--rojo);
  margin-bottom: var(--e3);
  padding-bottom: var(--e2);
  border-bottom: 1px solid var(--gris);
}

.grupo-campos .campo:last-child { margin-bottom: 0; }

/* La casilla sobre fondo propio: separa "es una opción" de
   "es un dato que escribís". */
.plegable .campo--casilla {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  padding: var(--e3);
}

/* La zona de peligro tenía el mismo aspecto que el resto. */
.zona-peligro {
  border: 1px solid var(--peligro-borde);
  background: var(--peligro-suave);
  border-radius: var(--radio-chico);
  padding: var(--e3);
}
.zona-peligro__titulo { color: var(--rojo-oscuro); font-weight: 700; font-size: .8rem; }

/* ---------- Salto directo en el paginador ---------- */

.paginado__ir {
  display: inline-flex;
  align-items: center;
  gap: var(--e2);
  font-size: .82rem;
  color: var(--tinta-media);
}

.paginado__ir label { font-weight: 600; }

.paginado__ir input {
  width: 5.5rem;
  padding: var(--e1) var(--e2);
  border: 1px solid var(--campo-borde);
  border-radius: var(--radio-chico);
  background: var(--campo-fondo);
  text-align: center;
  font: inherit;
}
.paginado__ir input:focus {
  outline: none;
  background: var(--superficie);
  border-color: var(--rojo);
  box-shadow: 0 0 0 3px var(--rojo-suave);
}

/* ---------- Campos de confirmación escrita ---------- */

.acciones-masivas__aviso {
  background: var(--alerta-suave);
  border-left: 3px solid var(--alerta);
  border-radius: var(--radio-chico);
  padding: var(--e2) var(--e3);
  font-size: .82rem;
  color: var(--alerta-texto);
}

/* Monoespaciada y espaciada: se ve que hay que copiar algo literal, no
   escribir una frase.

   SIN text-transform: uppercase, Y ESA AUSENCIA ES EL ARREGLO DE UN BUG.

   Lo tenía. Y text-transform cambia lo que se DIBUJA, no lo que el campo
   VALE: escribiendo "confirmar", la pantalla mostraba "CONFIRMAR" y el
   valor seguía siendo minúscula. El campo mostraba una cosa y mandaba
   otra, y no había forma de darse cuenta mirándolo.

   Eso rompía las dos salidas posibles:

   - Comparando exacto, quedaba RECHAZADO con un cartel que decía "No
     coincide" sobre dos textos que se leían idénticos.

   - Comparando sin distinguir mayúsculas —que fue el primer intento de
     arreglo— quedaba ACEPTADO, y entonces la palabra de seguridad pasaba a
     ser un trámite: escribías en minúscula, la pantalla te lo disfrazaba
     de mayúscula, y seguía de largo. Se saca la frustración y se deja la
     mentira, que era lo importante.

   Sin el transform, el campo muestra lo que hay. Ahí sí tiene sentido
   pedir la palabra en mayúsculas y compararla exacta: se ve la diferencia,
   el error se entiende, y escribirla en mayúsculas vuelve a ser el acto
   deliberado que justifica todo el mecanismo.

   La monoespaciada y el letter-spacing hacen ese trabajo sin engañar:
   comunican "esto se copia literal" cambiando la FORMA de las letras, no
   su contenido. */
.campo-confirmacion {
  flex: 0 1 12rem;
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  letter-spacing: .05em;
}

.campo-confirmacion--peligro {
  border-color: var(--peligro-borde) !important;
  background: var(--superficie) !important;
}

/* =========================================================
   25. Barra de progreso de la importación

   La importación dejó de correr dentro de la petición: ahora
   trabaja en el servidor y el panel pregunta cómo viene. Esto
   es lo que se ve mientras tanto.
   ========================================================= */

.progreso {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-left: 4px solid var(--alerta);
  border-radius: var(--radio);
  padding: var(--e4);
  margin-bottom: var(--e4);
  box-shadow: var(--sombra);
}

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

.progreso__cabecera > div { flex: 1; min-width: 0; }

.progreso__porcentaje {
  font-family: var(--fuente-titulo);
  font-size: 1.6rem;
  font-weight: 900;
  color: var(--rojo);
  flex: none;
  font-variant-numeric: tabular-nums;
}

.progreso__barra {
  height: 10px;
  background: var(--fondo);
  border-radius: 999px;
  overflow: hidden;
}

.progreso__relleno {
  height: 100%;
  width: 0;
  background: var(--rojo);
  border-radius: 999px;
  /* La transición hace que el salto entre sondeos se vea como avance
     continuo en vez de a tirones cada dos segundos. */
  transition: width .4s ease;
}

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

/* =========================================================
   26. Boton de tema claro / oscuro
   ========================================================= */

.boton-tema {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  padding: 0;
  border: 1px solid var(--gris);
  border-radius: 50%;
  background: var(--superficie);
  color: var(--texto);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, color .15s ease;
}

.boton-tema:hover {
  border-color: var(--rojo);
  color: var(--rojo);
}

.boton-tema:focus-visible {
  outline: none;
  border-color: var(--rojo);
  box-shadow: 0 0 0 3px var(--rojo-suave);
}

/* Se muestra el icono del tema al que vas a CAMBIAR:
   de dia se ve la luna (tocá para oscurecer), de noche el sol. */
.boton-tema__sol  { display: none; }
.boton-tema__luna { display: block; }

@media (prefers-color-scheme: dark) {
  :root:not([data-tema="claro"]) .boton-tema__sol  { display: block; }
  :root:not([data-tema="claro"]) .boton-tema__luna { display: none; }
}

:root[data-tema="oscuro"] .boton-tema__sol  { display: block; }
:root[data-tema="oscuro"] .boton-tema__luna { display: none; }

/* La eleccion explicita de tema claro le gana a la media query de arriba. */
:root[data-tema="claro"] .boton-tema__sol  { display: none; }
:root[data-tema="claro"] .boton-tema__luna { display: block; }

/* =========================================================
   27. Ventana de confirmación

   Es un <dialog> nativo. El ::backdrop es el fondo oscurecido
   que el navegador dibuja solo detrás de la ventana: no hace
   falta un div extra ni manejarlo a mano.
   ========================================================= */

.modal {
  border: none;
  padding: 0;
  background: transparent;
  max-width: min(440px, calc(100vw - 2rem));
  color: var(--texto);
}

.modal::backdrop {
  background: rgba(10, 9, 12, .62);
  backdrop-filter: blur(2px);
}

.modal__caja {
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-top: 4px solid var(--tinta-media);
  border-radius: var(--radio);
  box-shadow: var(--sombra-fuerte);
  padding: var(--e5);
  display: grid;
  gap: var(--e3);
}

/* Las acciones sin vuelta atrás se ven distinto a propósito: si borrar
   se ve igual que guardar, se confirman igual de rápido. */
.modal--peligro .modal__caja { border-top-color: var(--rojo); }
.modal--peligro .modal__marca { color: var(--rojo); }

.modal__marca {
  font-size: .7rem;
  font-weight: 700;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--tinta-media);
}

.modal__titulo {
  font-family: var(--fuente-titulo);
  font-size: 1.35rem;
  line-height: 1.25;
}

.modal__texto {
  font-size: .92rem;
  color: var(--tinta-media);
}

.modal__campo { margin-bottom: 0; }

.modal__campo input {
  width: 100%;
  padding: var(--e3);
  border: 1px solid var(--campo-borde);
  border-radius: var(--radio-chico);
  background: var(--campo-fondo);
  color: var(--texto);
}
.modal__campo input:focus {
  outline: none;
  background: var(--superficie);
  border-color: var(--rojo);
  box-shadow: 0 0 0 3px var(--rojo-suave);
}

.modal__campo code {
  font-family: ui-monospace, "SFMono-Regular", Consolas, monospace;
  background: var(--superficie-2);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  padding: 0 .35em;
  color: var(--rojo);
  font-weight: 700;
}

.modal__acciones {
  display: flex;
  gap: var(--e3);
  justify-content: flex-end;
  flex-wrap: wrap;
  margin-top: var(--e2);
}

/* Un botón apagado tiene que verse apagado, o se hace clic y "no anda". */
.modal__acciones .boton:disabled {
  opacity: .45;
  cursor: not-allowed;
}

/* =========================================================
   28. Más contraste en los formularios del panel

   Lo de la sección 24 (campo tintado, blanco al enfocar) resolvía
   "dónde termina un campo", pero seguía siendo todo muy pálido:
   etiquetas grises sobre fondo gris claro sobre panel blanco.

   Acá se sube el contraste de las tres capas que competían:
   la etiqueta, el borde del campo y el bloque que los agrupa.
   ========================================================= */

/* La etiqueta pasa a tinta plena. Antes iba en gris medio y competía
   en peso con el texto de ayuda que va DEBAJO del campo, así que el
   ojo no sabía cuál de los dos leer primero. */
.plegable .campo > label,
.filtros-panel .campo > label {
  color: var(--texto);
  font-size: .74rem;
}

/* El texto de ayuda sí baja de peso: es lo secundario. */
.plegable .campo .texto-apagado { font-size: .76rem; }

/* Los grupos dejan de ser una caja gris más y se marcan con el rojo
   de la marca en el borde izquierdo: se distinguen de un vistazo
   cuántos bloques tiene el formulario y dónde empieza cada uno. */
.grupo-campos {
  border-left: 3px solid var(--rojo);
  background: var(--superficie-2);
}

.grupo-campos__titulo {
  font-size: .74rem;
  letter-spacing: .08em;
}

/* El asterisco de obligatorio, en rojo y separado del texto. */
.plegable .campo > label {
  display: flex;
  align-items: baseline;
  gap: .3em;
}

/* Foco: además del anillo rojo, el borde entero se pinta. Con solo la
   sombra alrededor, en pantallas con poco brillo casi no se nota. */
.plegable .campo input:focus,
.plegable .campo textarea:focus,
.plegable .campo select:focus,
.filtros-panel .campo input:focus,
.filtros-panel .campo select:focus {
  border-color: var(--rojo);
  border-width: 1px;
}

/* La barra de filtros, que es lo que más se usa, se despega del fondo
   con un borde superior de color en vez de quedar como otra caja
   blanca más entre las herramientas y la tabla. */
.filtros-panel {
  border-top: 3px solid var(--rojo);
}

/* La tabla: encabezado con fondo propio y filas alternadas. Con
   27.000 productos, seguir una fila a lo ancho sin nada que guíe el
   ojo es donde se cometen los errores de editar el producto de al lado. */
.tabla thead th {
  background: var(--superficie-2);
  border-bottom: 2px solid var(--gris);
  color: var(--texto);
}

.tabla tbody tr:nth-child(even) { background: var(--superficie-2); }
.tabla tbody tr:hover { background: var(--rojo-suave); }

/* =========================================================
   29. Tamaño de letra elegible

   Casi todo el archivo está en rem, y un rem vale lo que diga
   el font-size de la raíz. Así que cambiar ESE número escala
   todo junto —letras y espacios, en proporción— sin tocar una
   sola regla más. Es la razón por la que conviene escribir en
   rem y no en px desde el principio.

   Tres tamaños y no un deslizador: elegir entre tres cosas es
   una decisión de un segundo; elegir un número exacto es una
   tarea. Y quien necesita esto no quiere una tarea.
   ========================================================= */

/* En porcentaje y no en px: 100% es el tamaño que el usuario tenga
   configurado en su navegador (16px salvo que lo haya cambiado).
   Poner 16px fijo le pisaría esa elección justamente a quien ya se
   tomó el trabajo de agrandar la letra en todo el sistema. */
:root                       { font-size: 100%; }
:root[data-letra="grande"]  { font-size: 112.5%; }  /* 18px sobre el default */
:root[data-letra="enorme"]  { font-size: 125%; }    /* 20px sobre el default */

.selector-letra {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--gris);
  border-radius: 999px;
  overflow: hidden;
  flex: none;
}

.selector-letra button {
  padding: .35rem .6rem;
  line-height: 1;
  color: var(--tinta-media);
  font-weight: 700;
  background: var(--superficie);
  transition: background .15s ease, color .15s ease;
}

.selector-letra button + button { border-left: 1px solid var(--gris); }
.selector-letra button:hover { background: var(--superficie-2); color: var(--texto); }

/* El tamaño activo se marca: sin esto no hay forma de saber
   en cuál estás, y se termina apretando al azar. */
.selector-letra button[aria-pressed="true"] {
  background: var(--rojo);
  color: var(--blanco);
}

.selector-letra .letra-a { font-size: .78rem; }
.selector-letra .letra-b { font-size: .95rem; }
.selector-letra .letra-c { font-size: 1.15rem; }

/* =========================================================
   30. Legibilidad del panel

   El panel es una herramienta de trabajo que se usa horas, y
   la usan dos personas con vistas distintas. Los números de
   antes: texto de 11 px, etiquetas de 12 px en mayúsculas con
   espaciado, y gris medio sobre gris claro.

   Las mayúsculas chiquitas son de lo peor que hay para leer
   rápido: le sacan a la palabra su forma, que es de lo que se
   agarra el ojo para reconocerla sin deletrearla. Sirven para
   un título de tres palabras, no para veinte etiquetas.
   ========================================================= */

/* Las etiquetas dejan de ser mayúsculas diminutas y pasan a ser
   texto normal, grande y en tinta plena. */
.plegable .campo > label,
.filtros-panel .campo > label {
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0;
  text-transform: none;
  color: var(--texto);
  margin-bottom: var(--e1);
}

/* El texto de ayuda: más grande que antes y con más contraste,
   pero claramente por debajo de la etiqueta. */
.plegable .campo .texto-apagado,
.campo__ayuda {
  font-size: .88rem;
  color: var(--tinta-media);
  line-height: 1.5;
  margin-top: var(--e1);
}

/* Campos más altos y con más aire: además de leerse mejor, son
   más fáciles de acertar con el mouse o con el dedo. */
.plegable .campo input[type="text"],
.plegable .campo input[type="number"],
.plegable .campo input[type="search"],
.plegable .campo select,
.plegable .campo textarea,
.filtros-panel .campo input,
.filtros-panel .campo select {
  padding: .7rem .8rem;
  font-size: 1rem;
  border-radius: var(--radio);
}

/* Mas aire entre campos en los plegables. El panel de filtros queda
   afuera a proposito: ahi es una grilla y el espacio lo pone el gap,
   asi que un margen extra solo desalineaba las filas. */
.plegable .campo { margin-bottom: var(--e4); }

/* Los títulos de los grupos: legibles de lejos, sin mayúsculas
   apretadas. */
.grupo-campos__titulo {
  font-size: .95rem;
  letter-spacing: 0;
  text-transform: none;
  font-weight: 700;
}

.grupo-campos { padding: var(--e5); }

/* Los plegables: cabecera más alta y más contrastada, para que
   se distingan de un vistazo cuántas secciones hay. */
.plegable__cabecera {
  padding: var(--e4);
  font-size: 1.05rem;
}
/* La pista deja de cortarse con puntos suspensivos: con la letra
   grande no entraba y se perdia justo la parte que explica que hace
   el boton. Prefiere ocupar dos lineas antes que decir la mitad. */
.plegable__pista {
  font-size: .9rem;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}

/* La tabla, que es lo que más se mira. */
.tabla { font-size: .95rem; }
.tabla th, .tabla td { padding: var(--e3) var(--e4); }
.tabla thead th { font-size: .9rem; font-weight: 700; }

/* Las métricas de arriba: el número grande y la etiqueta legible. */
.metrica__n { font-size: 2rem; }
.metrica__t { font-size: .92rem; color: var(--texto); }

/* Los avisos y los botones del panel. */
.aviso { font-size: 1rem; padding: var(--e4); }
.plegable .boton, .filtros-panel .boton { font-size: .95rem; }
.boton--chico { font-size: .9rem; padding: var(--e2) var(--e4); }

/* La zona de peligro plegada: cerrada ocupa una línea y no se
   puede tildar de paso, que era como se activaba sin querer. */
.zona-peligro--plegada { padding: 0; }
.zona-peligro__resumen {
  cursor: pointer;
  padding: var(--e3) var(--e4);
  font-weight: 700;
  color: var(--rojo-oscuro);
  font-size: .95rem;
  list-style: none;
}
.zona-peligro__resumen::-webkit-details-marker { display: none; }
.zona-peligro__resumen::marker { content: ""; }
.zona-peligro__resumen::before { content: "▸ "; }
.zona-peligro--plegada[open] > .zona-peligro__resumen::before { content: "▾ "; }
.zona-peligro--plegada[open] { padding: 0 var(--e4) var(--e4); }

/* "Aplicar a los N productos de este filtro" era el ejemplo mas
   claro del problema: la frase que dice a cuantos productos le vas
   a pegar estaba en 0.74rem, en mayusculas y en gris medio. Es la
   linea mas importante del panel y era la mas chica.

   Ahora es texto normal, del tamano del cuerpo, en tinta plena, y
   con la cantidad separada del resto. */
.acciones-masivas__titulo {
  font-size: 1.05rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--texto);
  font-weight: 700;
}

/* =========================================================
   31. Segundo factor

   Tres piezas: el campo del código, el QR y la lista de
   códigos de recuperación. Las tres tienen algo en común:
   se leen dígito por dígito, no de un vistazo. Por eso van
   en tipografía monoespaciada y con las letras separadas.
   ========================================================= */

/* El campo de los seis dígitos. Grande y espaciado: se escribe
   mirando el teléfono con una mano y tecleando con la otra. */
.campo-codigo {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 1.5rem;
  letter-spacing: .35em;
  text-align: center;
}

/* El QR con fondo blanco propio aunque el sitio esté en oscuro.
   La cámara necesita el contraste entre los cuadrados y el fondo;
   invertido, muchos lectores directamente no lo toman. */
.qr-caja {
  background: #fff;
  padding: var(--e4);
  border-radius: var(--radio);
  width: min(15rem, 100%);
  margin: var(--e4) 0;
}
.qr-caja svg { display: block; width: 100%; height: auto; }

/* La clave para cargar a mano, partida visualmente para poder
   dictarla sin perder el hilo. */
.secreto-totp {
  display: inline-block;
  font-size: 1.05rem;
  letter-spacing: .15em;
  word-break: break-all;
  padding: var(--e2) var(--e3);
  background: var(--superficie-2);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
}

/* Los diez códigos de papel. En columnas porque así se copian
   mejor a mano, y monoespaciados para que ningún carácter se
   confunda con otro al leerlos del papel. */
.lista-codigos {
  list-style: none;
  padding: 0;
  margin: var(--e4) 0 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
  gap: var(--e2);
}
.lista-codigos li {
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, Consolas, monospace;
  font-size: 1.05rem;
  letter-spacing: .08em;
  padding: var(--e2) var(--e3);
  background: var(--superficie-2);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  text-align: center;
}

/* =========================================================
   32. El panel en el celular

   La barra del panel escondía sus enlaces por debajo de 900px
   —igual que la de la tienda— pero, a diferencia de aquella,
   NO tiene botón de hamburguesa. O sea que desde un teléfono
   no había forma de llegar a «Usuarios» ni a «Ver la tienda»:
   los enlaces existían en el marcado y estaban en display:none
   sin nada que los abriera.

   La solución no es una hamburguesa. Son tres enlaces cortos:
   esconderlos detrás de un botón agrega un toque, un menú y
   JavaScript para ahorrar una línea de pantalla. Se pasan a
   una segunda fila y quedan siempre a la vista.
   ========================================================= */

.navbar--panel .navbar__interior {
  flex-wrap: wrap;
  padding-block: var(--e2);
}

.navbar--panel .navbar__enlaces {
  display: flex;
  /* order 3 los manda abajo de la marca y de las acciones, que
     en el marcado vienen antes. */
  order: 3;
  width: 100%;
  margin-left: 0;
  gap: var(--e5);
  padding-block: var(--e3) var(--e2);
  border-top: 1px solid var(--gris);

  /* NADA de overflow-x aca.

     Le habia puesto overflow-x:auto "por las dudas", pensando en el
     dia que hubiera mas enlaces. El efecto real fue que el navegador
     dibujara la barra de desplazamiento igual: aparecian flechitas
     al costado de una fila de tres palabras que entraban de sobra.
     Una barra de scroll donde no hay nada que desplazar no es una
     precaucion, es un adorno roto.

     Si algun dia son mas enlaces, que bajen a otra linea. */
  flex-wrap: wrap;
  row-gap: var(--e2);
}

/* La marca ocupa lo suyo y las acciones el resto. Sin esto, en
   375px el botón de «Cerrar sesión» empuja al selector de letra
   fuera del borde. */
.navbar--panel .navbar__marca { font-size: 1.15rem; }
.navbar--panel .navbar__acciones { gap: var(--e2); }

@media (min-width: 900px) {
  /* De acá para arriba entra todo en una línea, como siempre. */
  .navbar--panel .navbar__interior { flex-wrap: nowrap; padding-block: 0; }
  .navbar--panel .navbar__enlaces {
    order: 0;
    width: auto;
    margin-left: var(--e6);
    padding-top: 0;
    border-top: none;
  }
  .navbar--panel .navbar__marca { font-size: 1.35rem; }
  .navbar--panel .navbar__acciones { gap: var(--e3); }
}

/* ---------- Tablas que no entran ----------

   Con seis columnas y 375px de ancho, ninguna tabla del panel
   entra. Se desplazan de costado, que es preferible a achicar
   la letra hasta que no se lea o a esconder columnas: en un
   panel de trabajo, la columna que uno esconde es siempre la
   que el otro necesitaba.

   El detalle que lo hace usable es el borde: sin una señal de
   que hay más a la derecha, mucha gente no prueba deslizar y
   concluye que el sistema no muestra esos datos. */
.tabla-envoltorio {
  overflow-x: auto;
  /* Un poco de aire abajo para la barra de desplazamiento, que
     en escritorio se dibuja encima del contenido. */
  padding-bottom: var(--e2);
}

@media (max-width: 640px) {
  /* Menos relleno horizontal: entra una columna más antes de
     tener que deslizar. */
  .tabla th, .tabla td { padding: var(--e3) var(--e2); }

  /* La primera columna queda fija al deslizar, para no perder
     de vista de qué producto es la fila que se está mirando.
     Sin esto, deslizás hasta el precio y ya no sabés de cuál. */
  .tabla-envoltorio .tabla td:first-child,
  .tabla-envoltorio .tabla th:first-child {
    position: sticky;
    left: 0;
    background: var(--superficie);
  }
  .tabla-envoltorio .tabla thead th:first-child { background: var(--superficie-2); }
}

/* ---------- Texto que cambia con el ancho ----------

   «Cerrar sesión» son 132px, y con el selector de letra y el
   botón del tema al lado no entraban junto a la marca: las
   acciones se caían a una fila propia y la barra terminaba
   ocupando 156px de alto. Fija arriba, en un teléfono de 812px,
   eso es una quinta parte de la pantalla ocupada para siempre.

   En el celular dice «Salir», que es lo mismo en 62px. */
.en-chico  { display: inline; }
.en-ancho  { display: none; }

@media (min-width: 900px) {
  .en-chico { display: none; }
  .en-ancho { display: inline; }
}

/* Y el selector de letra un poco más compacto ahí también. */
@media (max-width: 899px) {
  .selector-letra button { padding: .3rem .5rem; }
}

/* ---------- Los plegables en el celular ----------

   La cabecera es un flex: título y pista uno al lado del otro.
   En 375px la pista no entra, se parte en cuatro renglones
   angostos al costado del título y el bloque queda deforme.

   Se pasa a dos filas: título arriba, pista abajo en toda la
   línea. El triángulo se queda arriba a la izquierda con las
   dos filas a su derecha, que es donde el ojo lo busca. */
@media (max-width: 640px) {
  .plegable__cabecera {
    display: grid;
    grid-template-columns: auto 1fr;
    align-items: start;
    row-gap: var(--e1);
  }

  /* El triángulo ocupa las dos filas de la primera columna. */
  .plegable__cabecera::before {
    grid-row: 1 / -1;
    align-self: center;
  }

  /* La pista salta a la segunda fila, debajo del título, y
     ocupa el ancho de la columna de contenido. */
  .plegable__pista {
    grid-column: 2;
    font-size: .85rem;
    line-height: 1.4;
  }
}

/* ---------- El buscador de la tienda en el celular ----------

   Estaba adentro de las acciones, peleando el ancho con el
   botón del tema y la hamburguesa, y quedaba en 120px: el
   placeholder se leía «Busca». En una tienda, buscar es la
   acción principal, así que baja a una fila propia y ocupa
   todo el ancho.

   El truco del margin-left:auto se le pasa al buscador cuando
   existe: sin eso, las acciones se irían al borde derecho y el
   buscador quedaría pegado a los enlaces, en el medio de la
   nada. Con el margen en el buscador, los dos forman un solo
   bloque a la derecha, como estaba antes. */
@media (max-width: 639px) {
  /* El buscador baja a su propia fila, a todo el ancho. Y las
     acciones CONSERVAN su margin-left:auto, que es lo que las
     empuja al borde derecho.

     Esto lo rompi en el commit anterior: le pase el margen
     automatico al buscador y se lo saque a las acciones sin
     distinguir el ancho. En el celular el buscador esta en otra
     fila, asi que en la primera no quedaba NADIE con margen
     automatico: la marca y los iconos se apelotonaban a la
     izquierda con medio renglon vacio a la derecha. Se veia
     como una barra a medio armar, y lo era. */
  .navbar__interior { flex-wrap: wrap; padding-block: var(--e2); }
  .navbar__interior > .buscador {
    order: 3;
    width: 100%;
    margin-left: 0;
  }
  /* El max-width de 260px es lo que hacia que el campo se cortara a
     dos tercios de la fila: se ponia width:100% y el tope lo frenaba
     igual. En su fila propia no hay nada con que competir. */
  .buscador input { width: 100%; max-width: none; }
}

@media (min-width: 640px) {
  /* De aca para arriba el buscador y las acciones comparten fila,
     asi que el margen automatico va en el primero de los dos para
     que formen un solo bloque a la derecha. */
  .navbar__interior > .buscador { margin-left: auto; }
  .navbar__interior > .buscador ~ .navbar__acciones { margin-left: 0; }
}

/* =========================================================
   33. Encabezado de los filtros y opciones avanzadas
   ========================================================= */

/* El bloque de filtros arrancaba directo con los campos: la única
   señal de para qué servían era el botón «Filtrar» al final. Ahora
   se anuncia antes de que empieces a escribir. */
.filtros-panel__encabezado {
  padding-bottom: var(--e3);
  margin-bottom: var(--e4);
  border-bottom: 1px solid var(--gris);
}

.filtros-panel__titulo {
  font-family: var(--fuente-titulo);
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--texto);
  margin: 0;
}

.filtros-panel__ayuda {
  font-size: .88rem;
  color: var(--tinta-media);
  margin: var(--e1) 0 0;
}

/* Las acciones masivas plegadas: separadas del resto por una línea,
   con un poco de aire, para que se lean como "otra cosa" y no como
   un paso más del filtro. */
.plegable--avanzado {
  margin-top: var(--e4);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  background: var(--superficie-2);
}
.plegable--avanzado > .plegable__cuerpo { padding-top: 0; }

/* =========================================================
   34. Ajustes finos del panel de filtros y de la barra
   ========================================================= */

/* ---------- Más separación alrededor de los filtros ----------

   El bloque quedaba pegado a las herramientas de arriba y a la
   tabla de abajo, con el mismo aire que había entre dos plegables
   cualesquiera. Con más espacio propio y una sombra suave se lee
   como una sección aparte y no como un plegable más de la lista. */
.filtros-panel {
  margin-top: var(--e6);
  margin-bottom: var(--e6);
  padding: var(--e5);
  box-shadow: var(--sombra);
}

/* El borde rojo de arriba, un poco más presente: es la única marca
   de color que separa esta sección del resto. */
.filtros-panel { border-top-width: 4px; }

/* ---------- Campos un poco menos altos ----------

   0.7rem arriba y abajo daba campos de casi 50px. Eran cómodos de
   apuntar con el dedo, pero con seis en fila el bloque entero se
   volvía un muro. 0.5rem los baja unos 6px cada uno sin que dejen
   de ser cómodos: el mínimo recomendado para tocar con el dedo son
   44px de alto total, y con el relleno más la letra siguen encima. */
.filtros-panel .campo input,
.filtros-panel .campo select {
  padding: .5rem .7rem;
}

/* Y menos aire entre la etiqueta y su campo, que era lo otro que
   estiraba la fila. */
.filtros-panel .campo > label { margin-bottom: 2px; }

/* ---------- La barra del panel, un poco más baja ----------

   Con la fila de enlaces abajo quedaba en 123px. Sacándole relleno
   a esa segunda fila baja a poco más de 100 sin que los enlaces
   queden apretados contra la línea divisoria. */
@media (max-width: 899px) {
  .navbar--panel .navbar__interior { padding-block: var(--e1); }
  .navbar--panel .navbar__enlaces  { padding-block: var(--e2); }
}

/* =========================================================
   35. La barra del panel: marca y enlaces en la MISMA línea

   Medido, la marca y las acciones estaban centradas al píxel
   (las dos en y=26) y los glifos a 1px. O sea que la barra
   estaba geométricamente bien.

   Pero se veía torcida igual, y eso alcanza: las dos filas
   con contenido de peso distinto —una marca en serif arriba,
   tres enlaces en sans abajo— no leen como un encabezado,
   leen como dos cosas apiladas.

   Se reordena: identidad y navegación juntas arriba, que es
   como se lee un encabezado en cualquier lado; las
   herramientas (letra, tema, salir) abajo. Al estar marca y
   enlaces en la misma línea, el desnivel entre ellos no puede
   existir por construcción.
   ========================================================= */
@media (max-width: 899px) {
  .navbar--panel .navbar__enlaces {
    order: 0;
    width: auto;
    flex: 1;
    margin-left: var(--e4);
    padding-block: 0;
    border-top: none;
    gap: var(--e4);
  }

  .navbar--panel .navbar__acciones {
    order: 3;
    width: 100%;
    margin-left: 0;
    /* Las herramientas siguen contra el borde derecho, que es
       donde el pulgar las busca. */
    justify-content: flex-end;
    padding-top: var(--e2);
    border-top: 1px solid var(--gris);
  }
}


/* =========================================================
   36. La pantalla de revisar fotos

   El problema de diseño de esta pantalla no es que se vea
   linda: es que alguien tiene que mirar cien fotos y decidir
   cien veces, y despues repetirlo cuarenta veces mas. Todo lo
   de abajo esta puesto para bajar el costo de UN gesto, porque
   cualquier roce se multiplica por cuatro mil.

   Las tres decisiones que mandan:

   1. LA TARJETA ENTERA ES EL BOTON. La casilla real esta
      escondida y toda la tarjeta es un label. Apuntarle a un
      cuadradito de 14px cuatro mil veces es media hora de
      punteria; apuntarle a una tarjeta de 160px es un gesto.
      En un celular, la diferencia es entre poder y no poder.

   2. EL ESTADO SE LEE DE LEJOS. Vienen todas tildadas, o sea
      que lo raro es lo destildado. Esa es la que tiene que
      gritar: se apaga, se desatura y se cruza. Quien barre la
      pantalla con la vista tiene que ver los huecos sin leer.

   3. LA FOTO MANDA. Es lo unico que se esta juzgando, asi que
      se lleva casi toda la tarjeta. El nombre va abajo, chico
      y en dos lineas: sirve para confirmar, no para leer.
   ========================================================= */

.revision-barra {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--e3);
  padding: var(--e3) var(--e4);
  margin-bottom: var(--e4);
  background: var(--superficie);
  border: 1px solid var(--gris);
  border-radius: var(--radio);

  /* Pegada arriba mientras se baja: el contador y el boton de
     aplicar tienen que estar a mano en todo momento. Sin esto,
     confirmar obliga a volver al principio de una pagina de
     cien tarjetas. */
  position: sticky;
  top: 0;
  z-index: 5;
}

/* La del pie no se pega: ya esta al final, y pegarla le comeria
   pantalla al ultimo renglon de tarjetas. */
.revision-barra--pie {
  position: static;
  margin: var(--e4) 0 0;
}

.revision-barra__cuenta { font-size: .92rem; color: var(--tinta-media); }
.revision-barra__cuenta strong { color: var(--tinta); font-size: 1.05rem; }

.revision-barra__botones {
  display: flex;
  flex-wrap: wrap;
  gap: var(--e2);
  align-items: center;
}

/* --- La grilla ---------------------------------------------
   auto-fill con minimo en rem y no en px: el minimo crece con
   el selector de tamano de letra, asi que quien lo sube ve
   tarjetas mas grandes y no las mismas con el texto apretado. */
.revision-grilla {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--e3);
}

.revision-tarjeta {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--e2);
  padding: var(--e2);
  background: var(--superficie);
  border: 2px solid var(--gris);
  border-radius: var(--radio);
  cursor: pointer;
  /* Sin esto, arrastrar para elegir varias selecciona el texto
     de los nombres y la pantalla queda toda azul. */
  user-select: none;
  transition: border-color .12s ease, opacity .12s ease;
}

/* La casilla real sigue existiendo —la manda el formulario y la
   leen los lectores de pantalla— pero no se dibuja. No se usa
   display:none porque eso la saca del orden de tabulacion y del
   arbol de accesibilidad. */
.revision-tarjeta__casilla {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.revision-tarjeta__figura {
  position: relative;
  display: block;
  aspect-ratio: 1 / 1;
  background: var(--superficie-2);
  border-radius: calc(var(--radio) - 2px);
  overflow: hidden;
}

/* contain y no cover: cover recorta, y recortar una foto de
   producto puede esconder justo la parte por la que se
   distingue de otra. Aca se juzga, no se decora. */
.revision-tarjeta__figura img {
  width: 100%; height: 100%;
  object-fit: contain;
  display: block;
}

/* El tilde va sobre la foto y no al lado para no ocupar lugar
   en la tarjeta. */
.revision-tarjeta__marca {
  position: absolute;
  top: var(--e1); right: var(--e1);
  width: 1.5rem; height: 1.5rem;
  border-radius: 50%;
  background: var(--exito);
  border: 2px solid var(--blanco);
  display: grid;
  place-items: center;
}
.revision-tarjeta__marca::after {
  content: "";
  width: .42rem; height: .72rem;
  border: solid var(--blanco);
  border-width: 0 2px 2px 0;
  transform: translateY(-1px) rotate(45deg);
}

.revision-tarjeta__datos {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

/* EL NOMBRE COMPLETO, hasta cuatro lineas. Antes se cortaba a dos,
   y estaba mal por dos motivos distintos.

   El primero es de datos, y lo destapo una tanda de Mooving: los
   nombres de una misma familia comparten el arranque —"CARPETA
   MOOVING ESCOLAR 3X40..."— y lo que los diferencia esta AL FINAL:
   HELLO KITTY, SPIDERMAN, RIVER, MICKEY. Cortar por el final se
   comia exactamente lo unico que hacia falta para decidir si la
   foto corresponde. Catorce carpetas con el mismo texto y catorce
   disenos distintos.

   El segundo es que la razon que estaba escrita aca era FALSA:
   decia que dejarlos enteros haria tarjetas de alturas distintas y
   una grilla dentada. No pasa. Es CSS grid, y en una grilla los
   items de una misma fila comparten la altura de la mas alta
   automaticamente. Nunca hubo dentado que evitar.

   Las cuatro lineas quedan como valvula para el nombre patologico
   de ciento veinte caracteres, con el title encima. */
.revision-tarjeta__nombre {
  font-size: .78rem;
  line-height: 1.3;
  color: var(--tinta);
  display: -webkit-box;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: anywhere;
}

.revision-tarjeta__codigo {
  font-size: .7rem;
  color: var(--tinta-media);
  background: none;
  border: none;
  padding: 0;
}

.revision-tarjeta__motivo {
  font-size: .68rem;
  color: var(--tinta-media);
  opacity: .85;
}

/* El aviso de que aprobar PISA una foto existente. Va en color
   de alerta porque es la unica decision de esta pantalla que
   puede destruir algo. */
.revision-tarjeta__pisa {
  font-size: .66rem;
  font-weight: 600;
  color: var(--alerta-texto);
  background: var(--alerta-suave);
  border-radius: 3px;
  padding: 1px 5px;
  align-self: flex-start;
  margin-top: 2px;
}

/* --- Los dos estados --------------------------------------- */

.revision-tarjeta:has(.revision-tarjeta__casilla:checked) {
  border-color: var(--exito);
}

/* Destildada: apagada, desaturada y cruzada. Los tres a la vez y
   no uno solo, porque uno solo le falla a alguien: el color no
   le sirve a quien no lo distingue, y la opacidad sola se pierde
   en una pantalla al sol. */
.revision-tarjeta:has(.revision-tarjeta__casilla:not(:checked)) {
  border-color: var(--gris);
  opacity: .5;
}
.revision-tarjeta:has(.revision-tarjeta__casilla:not(:checked)) img {
  filter: grayscale(1);
}
.revision-tarjeta:has(.revision-tarjeta__casilla:not(:checked)) .revision-tarjeta__marca {
  background: var(--tinta-media);
}
.revision-tarjeta:has(.revision-tarjeta__casilla:not(:checked)) .revision-tarjeta__marca::after {
  /* De tilde a cruz, girando y estirando el mismo trazo. */
  width: .62rem; height: .62rem;
  border-width: 0 2px 0 0;
  transform: rotate(45deg) translate(-1px, 1px);
  box-shadow: -2px 0 0 0 var(--blanco) inset;
}

/* El foco tiene que verse: con la casilla escondida, sin esto
   quien navega con el teclado no sabe donde esta parado. */
.revision-tarjeta:has(.revision-tarjeta__casilla:focus-visible) {
  outline: 3px solid var(--rojo);
  outline-offset: 2px;
}

@media (hover: hover) {
  .revision-tarjeta:hover { border-color: var(--rojo); }
}

/* --- Los chips de origen ----------------------------------- */
.chips { display: flex; flex-wrap: wrap; gap: var(--e2); margin-top: var(--e3); }

.chip {
  font-size: .82rem;
  padding: .25rem .7rem;
  border-radius: 999px;
  border: 1px solid var(--gris);
  color: var(--tinta-media);
  background: var(--superficie);
  text-decoration: none;
}
.chip:hover { border-color: var(--rojo); color: var(--rojo); }
.chip--activo {
  background: var(--solido);
  color: var(--sobre-solido);
  border-color: var(--solido);
}

/* En el celular entran dos por fila y la barra deja de pegarse:
   con la barra fija arriba, una pantalla de 640px se queda con
   la mitad del alto para las fotos. */
@media (max-width: 640px) {
  .revision-grilla { grid-template-columns: repeat(auto-fill, minmax(8rem, 1fr)); }
  .revision-barra { position: static; }
  .revision-barra__botones { width: 100%; }
  .revision-barra__botones .boton--primario { flex: 1; }
}

/* El numerito del enlace "Revisar fotos". Redondo, chico y en el
   color de la marca: tiene que llamar sin gritar, porque convive
   con la barra del panel que se usa todo el dia. */
.pendientes {
  display: inline-block;
  min-width: 1.25rem;
  padding: 0 .3rem;
  margin-left: .3rem;
  border-radius: 999px;
  background: var(--rojo);
  color: var(--blanco);
  font-size: .7rem;
  font-weight: 700;
  line-height: 1.25rem;
  text-align: center;
  vertical-align: middle;
}


/* =========================================================
   37. Campos de archivo con presencia, y aire en lo avanzado

   Dos cosas que se ven mal por el mismo motivo de fondo: los
   campos de archivo y los bloques plegados heredaban el
   espaciado de un campo de texto cualquiera, y no son eso.
   ========================================================= */

/* ---------- El campo de archivo ----------

   Tenia la misma altura que un input de texto, y no cumple la
   misma funcion. Un campo de texto espera que escribas: si esta
   bajito no importa, porque el foco y el cursor ya te dicen que
   estas ahi. Un campo de archivo es un BOTON disfrazado de
   campo: hay que verlo, entender que se puede apretar, y
   acertarle. Con la altura de un input de texto se lee como una
   linea decorativa.

   Y son la puerta de las dos operaciones mas pesadas del panel
   —subir 4.000 fotos, importar 28.000 productos—, asi que
   tienen que pesar en la pantalla lo que pesan de verdad.

   El borde punteado no es adorno: es la convencion de "solta un
   archivo acá" y le dice sin palabras que ese rectangulo grande
   es una zona y no un renglon. */
.campo input[type="file"] {
  min-height: 3.4rem;
  padding: var(--e3) var(--e4);
  border: 2px dashed var(--campo-borde);
  border-radius: var(--radio);
  background: var(--campo-fondo);
  cursor: pointer;
  /* Centra el texto y el boton nativo en toda esa altura, que si
     no quedan pegados arriba y se ve peor que antes. */
  display: flex;
  align-items: center;
  font-size: .95rem;
}

.campo input[type="file"]:hover {
  border-color: var(--rojo);
  background: var(--superficie);
}

.campo input[type="file"]:focus-visible {
  outline: 3px solid var(--rojo);
  outline-offset: 2px;
  border-style: solid;
}

/* El boton nativo de "Elegir archivo" tambien crece: es lo que
   la persona aprieta y con el tamano de fabrica queda chiquito
   adentro de un campo alto. */
.campo input[type="file"]::file-selector-button {
  padding: .5rem .9rem;
  margin-right: var(--e3);
  border: 1px solid var(--gris);
  border-radius: var(--radio-chico);
  background: var(--superficie);
  color: var(--tinta);
  font-family: inherit;
  font-size: .9rem;
  font-weight: 600;
  cursor: pointer;
}
.campo input[type="file"]::file-selector-button:hover {
  border-color: var(--rojo);
  color: var(--rojo);
}

/* La regla de la seccion 32 le pone borde y sombra de campo de
   texto a los input[type=file] que estan dentro de un plegable.
   Eso pelea con el borde punteado de arriba y gana por venir
   despues, asi que se lo devuelve acá. */
.plegable .campo input[type="file"],
.filtros-panel .campo input[type="file"] {
  border: 2px dashed var(--campo-borde);
  box-shadow: none;
}
.plegable .campo input[type="file"]:hover,
.filtros-panel .campo input[type="file"]:hover {
  border-color: var(--rojo);
}

/* ---------- Aire adentro de "Opciones avanzadas" ----------

   El cuerpo tenia padding-top: 0 para que el contenido no
   quedara demasiado lejos del titulo cuando se abre. Pero
   adentro de estos bloques hay formularios enteros —avisos,
   casillas, campos de confirmacion, botones peligrosos— y todo
   eso pegado al borde y entre si se lee como un amontonamiento.

   Y ese amontonamiento tiene un costo real, no solo estetico:
   son las acciones que no se pueden deshacer. Un boton de
   borrar apretado contra un aviso de peligro y contra el
   siguiente formulario invita a errar el clic. El aire acá es
   una forma de seguridad. */
.plegable--avanzado > .plegable__cuerpo {
  padding: var(--e4);
  padding-top: var(--e3);
  display: flex;
  flex-direction: column;
  gap: var(--e5);
}

/* Cada formulario de adentro, separado del de al lado por una
   linea. Con tres o cuatro acciones distintas en un mismo
   bloque, sin separacion no se ve donde termina una y empieza
   la otra — y eso, con acciones masivas, es apretar la que no
   era. */
.plegable--avanzado > .plegable__cuerpo > form + form,
.plegable--avanzado > .plegable__cuerpo > .grupo-campos + form,
.plegable--avanzado > .plegable__cuerpo > form + .grupo-campos {
  padding-top: var(--e5);
  border-top: 1px solid var(--gris);
}

/* Y adentro de cada formulario, que el aviso, los campos y el
   boton no se toquen. */
.plegable--avanzado form > * + * { margin-top: var(--e3); }

.plegable--avanzado .acciones-masivas {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--e3);
}

/* El campo de confirmacion, un poco mas alto y con mas aire: es
   donde hay que copiar una palabra con cuidado justo antes de
   una accion que no se deshace. */
.campo-confirmacion {
  min-height: 2.6rem;
  padding: .5rem .7rem;
}


/* =========================================================
   38. Un campo que no se estira

   Los campos del panel ocupan el 100% del ancho, que es lo
   correcto cuando cada uno va en su renglon. Pero adentro de
   una fila de accion masiva —campo mas boton, en linea— un
   select al 100% empuja el boton fuera de la vista.

   flex-basis y no width: la fila es un flex container, asi que
   el ancho lo negocia con el boton en vez de imponerlo.
   ========================================================= */
.campo--angosto {
  flex: 0 1 15rem;
  min-width: 0;
}

/* Los select y los input de texto sueltos dentro de una fila de
   accion masiva no tenian el estilo de campo del panel: se veian
   como piezas traidas de otro lado, sin borde propio ni fondo.
   La regla de la seccion 32 cubria input[type=text] pero no
   select, que era justo el de "Categoria a asignar". */
.acciones-masivas select,
.acciones-masivas__fila select,
.plegable--avanzado select {
  padding: var(--e3);
  border: 1px solid var(--campo-borde);
  border-radius: var(--radio-chico);
  background: var(--campo-fondo);
  box-shadow: inset 0 1px 2px rgba(47, 45, 45, .05);
  color: var(--tinta);
  font-family: inherit;
  font-size: .95rem;
  width: 100%;
}
.acciones-masivas select:hover,
.acciones-masivas__fila select:hover,
.plegable--avanzado select:hover {
  border-color: var(--rojo);
}



/* =========================================================
   39. Jerarquia adentro de una seccion, y la barra de filtros

   ESTA SECCION SE ESCRIBIO DOS VECES. La primera version tocaba
   .plegable__cuerpo y sus formularios enteros —los volvia flex,
   les ponia gap y les borraba los margenes con !important— y
   rompio dos cosas: desnivelo las columnas del panel y encimo
   campos adentro de los formularios.

   El desnivel salio de .plegable + .plegable { margin-top }.
   .herramientas es una GRILLA de dos columnas, asi que ese
   selector le pone margen a todos menos al primero, incluido el
   primero de la columna derecha. La grilla ya separa con gap: no
   habia nada que agregar.

   La leccion, anotada porque me la voy a olvidar: para arreglar
   UN bloque anidado no hace falta redefinir el layout de todos
   los contenedores que lo contienen. Esta version toca solo el
   bloque anidado.
   ========================================================= */

/* --- Un plegable adentro de otro: sangrado, no tarjeta ---

   Era la causa real de "parece que dentro de una seccion empieza
   otra". .plegable es una tarjeta —fondo, borde, esquinas— y la
   zona de peligro de "reemplazar el catalogo entero" era OTRA
   tarjeta con las mismas tres cosas, adentro. Mismo lenguaje
   visual en dos niveles distintos.

   Y en el panel eso no es estetico: esa seccion tiene adentro un
   boton que borra 28.000 productos. Perder el hilo de en que
   seccion estas es perder el hilo de a que le estas apuntando.

   La regla: nivel superior es TARJETA (borde completo); bloque
   subordinado es SANGRADO (barra a la izquierda, sin borde). La
   jerarquia se lee por la forma y no por el color. */
.plegable__cuerpo details.zona-peligro {
  border: none;
  border-radius: 0;
  border-left: 3px solid var(--rojo);
  background: none;
  padding: 0 0 0 var(--e4);
  margin-top: var(--e4);
}
.plegable__cuerpo details.zona-peligro > .zona-peligro__resumen {
  padding: 0 0 var(--e2);
}
.plegable__cuerpo details.zona-peligro[open] {
  padding: 0 0 0 var(--e4);
}

/* --- La casilla de "volver a la de fabrica" ---
   Lleva un texto de ayuda de varias lineas adentro de la
   etiqueta, asi que el cuadradito tiene que quedar a la altura
   del primer renglon y no centrado en todo el bloque. */
.campo--reset { align-items: flex-start; }
.campo--reset input[type="checkbox"] {
  margin-top: .25rem;
  flex: 0 0 auto;
}
.campo--reset label { display: block; cursor: pointer; }
.campo--reset .campo__ayuda {
  display: block;
  margin-top: .3rem;
  font-weight: 400;
}

/* =========================================================
   40. La barra de filtros, como una barra de herramientas

   El titulo no se distinguia de los de las secciones plegadas, y
   los campos estaban tan altos que seis de ellos ocupaban media
   pantalla. Un filtro no es un formulario de carga: se usa de
   pasada, muchas veces por dia, y tiene que leerse de un
   vistazo.

   Asi que el titulo sube un poco y los campos bajan bastante:
   etiquetas mas chicas y pegadas a su campo, y campos de altura
   de herramienta. Ni apretado ni inflado.
   ========================================================= */

.filtros-panel__encabezado h3,
.filtros-panel__encabezado > strong {
  font-size: 1.28rem;
}

/* Etiquetas: chicas, en mayuscula suave y bien cerca de su campo.
   En una barra de seis filtros la etiqueta es una referencia, no
   un enunciado: cuanto menos alto ocupa, mas se ve la fila
   entera de un golpe. */
.filtros-panel .campo > label {
  font-size: .74rem;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--tinta-media);
  margin-bottom: .2rem;
}

/* Altura de herramienta y no de formulario. */
.filtros-panel .campo input[type="text"],
.filtros-panel .campo input[type="search"],
.filtros-panel .campo select {
  padding: .42rem .6rem;
  font-size: .92rem;
  min-height: 0;
}

.filtros-panel .campo__ayuda {
  font-size: .72rem;
  margin-top: .2rem;
}

/* Y los campos, mas cerca entre si: la fila se lee como una sola
   herramienta en vez de seis cosas separadas. */
.filtros-panel__campos { gap: var(--e3); }


/* =========================================================
   41. Encabezados de subseccion: a lo largo, no a lo alto

   Adentro de "Opciones avanzadas" conviven cuatro cosas que no
   se parecen en nada —reclasificar, poner una foto a toda una
   familia, publicar u ocultar, y borrar— y no habia NADA que
   dijera donde termina una y empieza la siguiente. Se pasaba del
   select de categoria al campo de foto sin transicion.

   En un bloque que contiene un boton que borra 28.000 productos,
   no saber en que subseccion estas es no saber a que le estas
   apuntando.

   POR QUE ASI Y NO CON UN TITULO NORMAL

   Un h3 con su margen ocupa tres renglones de alto entre bloques
   y estira una seccion que ya es larga. Este ocupa UNO: etiqueta
   chica a la izquierda y una linea que cruza hasta el borde
   derecho. Divide a lo ancho en vez de empujar hacia abajo, que
   es lo que hace una regla de una barra de herramientas.

   El truco de la linea es un pseudo-elemento que crece con
   flex:1. No es un border-bottom del parrafo porque eso pasaria
   POR DEBAJO del texto; asi la linea arranca donde el texto
   termina.
   ========================================================= */

.subseccion {
  display: flex;
  align-items: center;
  gap: var(--e3);
  margin: var(--e5) 0 var(--e2);
  font-size: .76rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--tinta-media);
}

.subseccion::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--gris);
}

/* El primero no necesita separarse de lo que tiene arriba: viene
   justo despues del aviso de cuantos productos alcanza. */
.subseccion:first-of-type { margin-top: var(--e3); }

/* La de borrar se distingue por color, no por tamano: es la
   misma forma que las otras tres —un renglon— pero se ve de
   lejos que no es una mas. */
.subseccion--peligro {
  color: var(--rojo);
}
.subseccion--peligro::after {
  background: var(--peligro-borde);
}


/* =========================================================
   42. El buscador, la tabla de usuarios y un subtitulo

   --- La lupa quedaba abajo ---

   El icono es un <svg> puesto en linea, y un elemento en linea se
   apoya en la LINEA DE BASE del texto: debajo queda reservado el
   espacio del descendente —el rabito de la p y la g— aunque no
   haya ninguna letra. El icono queda alto y el boton, mas bajo de
   lo que deberia. Se ve como si el buscador estuviera cortado.

   Se arregla de las dos puntas: el boton centra su contenido en
   grilla, y el svg pasa a display:block para que deje de
   comportarse como una letra.

   Y las dos mitades se igualan con un min-height compartido, que
   es lo que hace que se lean como UN control y no como un campo
   con un boton al lado.
   ========================================================= */

.buscador input,
.buscador button {
  min-height: 2.4rem;
  box-sizing: border-box;
}

.buscador button {
  display: grid;
  place-items: center;
  /* Sin esto el ancho lo decide el padding contra un contenido que
     mide cero de alto: queda un boton flaco y torcido. */
  min-width: 2.6rem;
  cursor: pointer;
}

.buscador button svg {
  display: block;
}

/* =========================================================
   43. Aire entre las secciones de una pantalla

   En Usuarios se pasaba del plegable "Crear una cuenta" a la
   tabla sin nada en el medio, asi que la tabla parecia la
   continuacion del plegable y no otra cosa. Un subtitulo y aire
   arreglan las dos mitades del problema: dice que es, y dice
   donde empieza.
   ========================================================= */

.seccion-sub {
  margin: var(--e6) 0 var(--e3);
  font-family: var(--fuente-titulo);
  font-size: 1.28rem;
  font-weight: 700;
  color: var(--texto);
}
/* --- La fila de edicion de un usuario ---

   Cuelga de la fila de datos que tiene arriba, asi que se ve como
   una continuacion y no como otra fila de la tabla: sin borde
   propio y con la celda sin el padding de una celda normal, para
   que el plegable ocupe todo el ancho.

   El padding de abajo se agranda solo cuando hay algo abierto: con
   todo cerrado, ese aire de mas separaba las cuentas mas que la
   linea que las divide. */
.tabla--usuarios .fila-editar > td {
  padding: 0 var(--e3) var(--e2);
  border-bottom: 2px solid var(--gris);
}

.tabla--usuarios .fila-editar:has(.plegable[open]) > td {
  padding-bottom: var(--e4);
}

/* El hover de la tabla pinta la fila entera, y sobre la fila de
   edicion abierta eso tinta el formulario completo de rojo suave.
   Con el formulario abierto lo que importa es leerlo, no saber
   sobre que fila esta el mouse. */
.tabla--usuarios .fila-editar:hover { background: none; }

/* Y la fila de datos deja de tener borde inferior: el que separa
   una cuenta de la siguiente es el de la fila de edicion. */
.tabla--usuarios .fila-usuario > td { border-bottom: none; }

/* Las dos filas de una misma cuenta se pintan igual al pasar el
   mouse, asi se lee que son una sola cosa. */
.tabla--usuarios .fila-usuario:hover { background: var(--rojo-suave); }

/* --- El plegable adentro de una fila pesa como un enlace ---

   .plegable es la clase de las secciones grandes del panel: tarjeta
   con borde, fondo propio y padding generoso. Eso esta bien para
   "Importar lista de precios", que es un bloque de primer nivel.

   Repetida una vez por fila de tabla, cada cuenta quedaba con una
   tarjeta debajo del MISMO peso visual que esas secciones, y tres
   cuentas se leian como seis bloques. El problema no era el
   desplegable: era que el disparador cerrado tenia peso de tarjeta
   cuando tenia que tener peso de enlace.

   Cerrado, entonces, no dibuja nada. El panel con borde aparece al
   abrirlo, que es cuando hay algo que separar del resto. */
.plegable--fila {
  background: none;
  border: none;
  border-radius: 0;
  overflow: visible;
}

.plegable--fila > .plegable__cabecera {
  /* Ancho al contenido: el area que responde al clic termina donde
     termina el texto. Con el ancho completo de la tabla, pasar el
     mouse por cualquier lugar de la fila daba a entender que todo
     era clickeable. */
  width: fit-content;
  padding: var(--e2) 0;
  font-size: .88rem;
  font-weight: 600;
  color: var(--tinta-media);
  gap: var(--e2);
}

.plegable--fila > .plegable__cabecera:hover {
  background: none;
  color: var(--rojo);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.plegable--fila[open] { box-shadow: none; }
.plegable--fila[open] > .plegable__cabecera { color: var(--rojo); }

/* Abierto SI es un panel, y ahi el borde ayuda: separa el
   formulario de la cuenta de abajo. */
.plegable--fila > .plegable__cuerpo {
  margin-top: var(--e1);
  padding: var(--e4);
  border: 1px solid var(--gris);
  border-radius: var(--radio);
  background: var(--superficie-2);
}


/* =========================================================
   44. Dos correcciones de alcance

   --- El label en mayuscula chica era para SEIS campos, no para
       todos los que caen adentro del bloque ---

   La regla decia ".filtros-panel .campo > label", y las opciones
   avanzadas viven adentro de .filtros-panel. Asi que "Categoria a
   asignar a los 27.877 del filtro" —un label largo, en un campo
   de 15rem— salia en mayusculas, a 11,8 px y con letter-spacing,
   partido en dos renglones desparejos con el numero en otro
   color. Parecia texto justificado a la fuerza.

   La mayuscula chica tiene sentido en la BARRA de seis filtros,
   donde cada label es una palabra y lo que importa es que la fila
   entera se lea de un golpe. No tiene ningun sentido en un
   formulario de una sola accion.

   Se acota a .filtros-panel__campos, que es la grilla de los seis,
   y adentro de las opciones avanzadas los labels vuelven a ser
   labels normales.
   ========================================================= */

.plegable--avanzado .campo > label,
.plegable__cuerpo .campo > label {
  font-size: .85rem;
  font-weight: 600;
  letter-spacing: normal;
  text-transform: none;
  color: var(--texto);
  margin-bottom: 0;
}

/* Y el campo de categoria deja de ser angosto: con 15 rem el label
   no entraba en un renglon. Crece hasta donde necesite y el boton
   se acomoda al lado. */
.campo--angosto {
  flex: 1 1 20rem;
  max-width: 26rem;
}

/* =========================================================
   45. Aire adentro de las secciones plegadas

   "Esta todo muy apretado" en Importar, y es cierto: el cuerpo de
   una seccion tiene un campo de archivo, dos avisos de colores, un
   plegable de peligro y un boton, y todos heredaban el margen que
   trajera cada uno — o ninguno.

   ESTA REGLA SOLO AGREGA MARGEN. No cambia display, ni
   flex-direction, ni align-items. Esa distincion no es teorica:
   la version anterior de este arreglo volvia el cuerpo un flex
   column, y eso hizo dos destrozos —desnivelo las columnas del
   panel y centro los controles— porque otras clases ya traian un
   align-items pensado para una FILA. Un margen no puede hacer
   eso.
   ========================================================= */

.plegable__cuerpo > * + * {
  margin-top: var(--e4);
}

/* Los margenes escritos a mano en el HTML se suman al de arriba y
   dan huecos del doble en unos lugares y no en otros. */
.plegable__cuerpo > .aviso,
.plegable__cuerpo > p[style*="margin"] {
  margin-bottom: 0;
}

/* Adentro de un formulario, el mismo ritmo pero mas corto: los
   campos de una misma accion van juntos, y la separacion grande
   queda para separar acciones distintas. */
.plegable__cuerpo form > * + * {
  margin-top: var(--e3);
}

/* El boton de la accion, despegado de lo que tiene arriba: es el
   ultimo paso y conviene que se lea como tal, no como otro campo
   mas de la lista. */
.plegable__cuerpo form > button[type="submit"] {
  margin-top: var(--e5);
}

/* Y el bloque de peligro respira arriba y abajo. */
.plegable__cuerpo details.zona-peligro {
  margin-bottom: var(--e2);
}
