/* ================================================================
   VITRINA PÚBLICA — FixHub v10
   Paleta oscura elegante — sin morado
   ================================================================ */
 
:root {
  --vb:    rgb(20, 20, 20);
  --vs:    #1b1b1b;
  --vs2:   #232323;
  --vs3:   #2e2e2e;
  --vbor:  rgba(255,255,255,0.07);
  --vbor2: rgba(255,255,255,0.14);
  --va:    var(--color-accent);
  --va2:   #b976cf;
  --vag:   rgba(255,255,255,0.06);
  --vag2:  rgba(255,255,255,0.11);
  /* ── Texto: cuatro pasos, un rol cada uno ──────────────────────────
     La regla es que cada texto elija su PAPEL, no su tono. Antes había
     tres niveles para cuatro trabajos, así que --vtx3 (el más apagado,
     hecho para placeholders) terminó pintando también subtítulos,
     categorías y fechas: contenido que hay que leer al 30% de opacidad.
     De ahí venía la mezcla de intensidades.

       --txt-titulo   títulos, valores, énfasis
       --txt-cuerpo   texto normal, el que se lee de corrido
       --txt-sub      subtítulos y metadatos (categoría, fecha, "3 de 8")
       --txt-tenue    SOLO placeholder, deshabilitado e iconos decorativos

     Nada de contenido usa --txt-tenue. Si hay que leerlo, es --txt-sub
     como mínimo. ── */
  --txt-titulo: #efefef;
  --txt-cuerpo: rgba(239,239,239,0.70);
  --txt-sub:    rgba(239,239,239,0.45);
  --txt-tenue:  rgba(239,239,239,0.28);

  /* Nombres antiguos. --vtx3 apunta a --txt-sub, NO a --txt-tenue: es el
     que quedó regado por public/modulos y por estilos en línea del JS,
     casi siempre sobre contenido. Apuntándolo al escalón legible, lo que
     todavía no se auditó sale un poco claro de más; apuntándolo al
     tenue, salía ilegible. El que de verdad es placeholder o está
     deshabilitado pide --txt-tenue por su nombre. */
  --vtx:   var(--txt-titulo);
  --vtx2:  var(--txt-cuerpo);
  --vtx3:  var(--txt-sub);

  /* ── Tamaños ───────────────────────────────────────────────────────
     Había 28 tamaños distintos, con medios píxeles (11.5, 12.5, 13.5)
     que no son un escalón sino un ajuste suelto. Estos son los pasos;
     16px es aparte y solo para campos de formulario, porque bajo 16px
     Safari en iOS hace zoom al enfocar un input. ── */
  --fs-2xs: 10px;   /* etiquetas diminutas, contadores */
  --fs-xs:  11px;   /* etiquetas en mayúscula */
  --fs-sm:  12px;   /* metadatos */
  --fs-md:  13px;   /* cuerpo — el tamaño por defecto */
  --fs-lg:  14px;   /* cuerpo destacado, nombres */
  --fs-xl:  15px;   /* subtítulo */
  --fs-2xl: 17px;   /* título de sección */
  --fs-3xl: 20px;   /* título de página */
  --fs-input: 16px; /* solo campos de formulario, ver arriba */

  /* ── Pesos ─────────────────────────────────────────────────────────
     En navegación —la franja de accesos, el menú de usuario, las
     pestañas, la paginación— el peso NO decora: dice cuál está activo.
     En reposo van todos en 400 y el activo en 700. Cada familia elegía
     antes su propio par (600→600, 500→600, 600→nada), así que había
     ítems en reposo más pesados que otros ya activos y el peso no
     significaba nada. El 600 queda para las opciones dentro de un
     desplegable, que no tienen estado activo. ── */
  --vgrn:  #4ade80;
  --vred:  #f87171;
  --r:     10px;
  --rl:    16px;
  --rxl:   22px;
}
 
*, *::before, *::after {
  box-sizing: border-box; 
  margin: 0;
}
 
#vitrina-root {
  font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
  color: var(--vtx);
  background: var(--vb);
  -webkit-font-smoothing: antialiased;
  font-size: 14px;
  /* Columna: franja de aviso, navbar y contenido, uno debajo del otro,
     con la página ocupando como mínimo la pantalla completa. Antes el
     contenido se estiraba con min-height: calc(100vh - alto del navbar),
     y ese "alto del navbar" era un número que había que MEDIR en
     JavaScript y mantener al día en una variable CSS (--vit-nav-alto):
     si el navbar crecía a dos o tres líneas y la medición llegaba tarde,
     el contenido quedaba con más o menos alto del que en verdad tenía.
     En una columna flex la cuenta la hace el navegador: el navbar ocupa
     lo que ocupa y al contenido le toca el resto, siempre. */
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  min-height: 100dvh;
}
 
/* ════════════════════════════════════════════════════════════
   NAVBAR
   ════════════════════════════════════════════════════════════ */
.vit-nav {
  /* sticky (no fixed): sigue reservando su alto real en el flujo normal
     del documento, así que no hace falta ningún padding-top de
     compensación en #vitrina-root ni en nada de lo que viene después —
     eso es justo lo que hacía complicado el diseño "fixed" de antes. */
  position: sticky;
  /* Debajo de la franja de aviso, que también es sticky. La variable la
     escribe _actualizarTopVitpPages (vitp-paginas.js) con su alto real;
     sin aviso vale 0 y el navbar queda pegado arriba como siempre. */
  top: var(--vit-aviso-alto, 0px);
  /* Por ENCIMA de las páginas vitp (250, ver vitp-shell.css). El navbar
     crea su propio contexto de apilamiento, así que todo lo que abre
     hacia abajo —el dropdown de login, el de usuario, carrito, notas,
     pendientes— queda atrapado en ESTE número por más z-index que tenga
     por dentro (todos declaran 300 y no les servía de nada). Con 100,
     cualquier página vitp abierta se los tragaba enteros: en
     /registro-empresa el panel de "Iniciar sesión" se abría detrás de la
     página y no se podía ni ver ni usar.
     Sube hasta acá y no más: los modales y overlays que van por encima
     del navbar (#vit-sidebar-overlay 350, modales 300+, toasts 1000)
     tienen que seguir ganándole. */
  z-index: 260;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
  background: var(--vb);
}
.vit-nav.vit-nav-oculto { display: none; }
/* Fila única, arriba de todo, como la barra de menú de macOS: ☰ + logo
   primero (la "manzanita" del extremo izquierdo), después Usuario/Login,
   Agregar/Carrito/Agenda/Notas/Pendientes/WhatsApp en texto plano, y por
   último el buscador — empujado al margen derecho con margin-left:auto
   (ver más abajo). Todos viven en .vit-nav-right ahora; no hay más fila
   aparte para logo/buscador. */
.vit-nav > .vit-nav-right {
  justify-content: flex-start;
  padding: 6px 0;
  border-bottom: 1px solid var(--vbor);
}

/* Barra de filtros activos + orden. Ahora vive DENTRO del navbar (ver
   index.html), debajo de la fila de menú — así queda en la misma capa
   que el resto del navbar, sin depender de comparar z-index entre el
   navbar y un elemento aparte (eso fue lo que fallaba antes: dos
   elementos separados, con contextos de apilamiento propios, no
   terminaban de ordenarse bien entre sí).
   Siempre visible, incluso sin filtros activos — ver
   _actualizarFiltrosActivos() en vitrina.js. Trae el select de orden
   (antes vivía en el resumen del sidebar) en vez de un botón "Limpiar
   filtros" — ese sobraba, la X del buscador ya limpia todo.
   Mismo lenguaje visual que .vit-sidebar (tarjeta flotante: mismo
   fondo, borde, radio y sombra) para que combinen entre sí. */
.vit-filtros-bar-top {
  /* Columna: una pastilla por fila (controles arriba, chips abajo).
     El contenedor solo las apila y les pone el fondo detrás — lo que
     las hace verse como tarjetas flotantes (borde, radio y sombra) lo
     lleva cada pastilla, abajo. */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  /* Sticky (mismo criterio que el sidebar y el navbar): se queda
     pegado bajo el navbar al scrollear, en vez de irse con el resto de
     la grilla. "top" es el alto real del navbar, medido en vivo por
     _actualizarTopVitpPages (vitp-paginas.js); los 10px de aire que
     antes iban en el "top" ahora son relleno de acá abajo, así que la
     primera pastilla sigue arrancando a la misma altura que el
     sidebar. z-index menor al del navbar (100) pero mayor al del
     sidebar (50), para que no quede tapado al cruzarse con este último
     en pantallas angostas. */
  /* Contenedor de consulta para las reglas de más abajo, que reparten
     la pastilla de "cómo ver" según el lugar que haya.

     Va acá y no en la propia pastilla porque un elemento NO puede
     consultarse a sí mismo: @container mira siempre a un ANTEPASADO.
     Declarándolo en la pastilla, las reglas de adentro no se aplicaban
     nunca y todo se veía como si no existieran.

     Esta franja mide lo mismo que la pastilla, así que los números son
     los de la pastilla más sus 16px de relleno a cada lado. */
  container-type: inline-size;
  container-name: barracatalogo;
  position: sticky;
  top: var(--vit-nav-alto, 62px);
  z-index: 60;
  /* Sin fondo propio: las pastillas son de vidrio (.fx-vidrio) y lo que
     se tiene que ver por detrás es la página, no un panel opaco. El
     desenfoque de cada pastilla se encarga de que el texto se siga
     leyendo cuando por abajo pasa la grilla. Ojo que por los huecos
     —entre una pastilla y la otra, y a los costados— sí se ve pasar el
     contenido al scrollear: es el precio de ver el fondo.

     El aire de arriba y de abajo es relleno de acá, y la separación
     entre las dos pastillas es el gap. Antes eran márgenes de cada
     pastilla y se sumaban: 14 de una más 10 de la otra daban 24px de
     hueco entre las dos. */
  gap: 8px;
  margin: 0;
  padding: 10px 0 14px;
}
.vit-filtros-bar-top > * { margin: 0; }

/* En el catálogo la barra cuelga de .vit-main, que no tiene relleno
   lateral: las pastillas llegaban pegadas a los dos bordes mientras las
   tarjetas de abajo arrancaban a 12px (el relleno de #vit-grid-wrap).
   Se les da el MISMO relleno que a la grilla para que empiecen y
   terminen en la misma línea.

   Va con "> " y sobre .vit-main a propósito: la misma barra se usa en
   Registro, pero ahí vive dentro de #reg-main-container, que ya pone lo
   suyo. */
.vit-main > .vit-filtros-bar-top { padding-left: 36px; padding-right: 36px; }
.vit-filtros-bar-top.oculto { display: none; }

/* Cada pastilla de la barra. El fondo, el borde y la sombra NO están
   acá: los pone .fx-vidrio / .fx-vidrio-flota (utilidades.css), la
   misma receta de vidrio que usa el resto del programa. Acá queda solo
   lo que es propio de esta barra: cómo se reparte por dentro, cuánto
   relleno lleva y la curva. El Resumen de caja de Registro reutiliza
   este mismo lugar (ver _actualizarBarraTopParaPagina) y lleva las
   mismas clases de vidrio. */
.vit-barra-pastilla,
.vit-filtros-bar-top .reg-resumen-caja-bar:not(.oculto) {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 16px;
  padding: 8px 16px;
  min-height: 36px;
  border-radius: 18px;
}
/* El Resumen de caja apila sus tres filas en columna (boletas.css), y en
   una columna "align-items: center" no centra verticalmente sino que
   corre las filas al medio a lo ancho. Va pegado al borde izquierdo,
   como el resto del programa. */
.vit-filtros-bar-top .reg-resumen-caja-bar:not(.oculto) { align-items: stretch; }

/* ── La pastilla de los filtros ── */
/* El rótulo "Filtros" y, al lado, los chips de lo que está puesto. */
.vit-barra-rotulo {
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--txt-sub);
  white-space: nowrap;
  flex-shrink: 0;
}
/* Sin ningún filtro puesto no hay nada que mostrar y la pastilla se va
   entera, rótulo incluido. La clase la pone _actualizarFiltrosActivos
   (vitrina.js). */
.vit-barra-filtros.vacia { display: none; }

/* ── La pastilla de "cómo ver" ── */
/* El conteo a la izquierda y, pegados al borde derecho, el orden, el
   "por página" y el botón de tarjetas/tabla. El margen automático del
   primero de ese grupo se come todo el espacio libre de la fila.

   Cuando no entran los cuatro, el que baja NO es el que quedó último:
   hay un orden de prioridad. El conteo y el botón de vista se quedan
   siempre arriba, uno en cada punta; después cae "por página", y si
   todavía falta lugar cae el orden, debajo del anterior.

   Se decide con @container y no con un corte por ancho de VENTANA
   porque lo que importa es cuánto mide esta pastilla, que depende de si
   el sidebar está abierto y de cuánto se llevó la grilla. Un corte por
   ventana ya se probó acá y fallaba justo por eso: en una ventana de
   690px con el sidebar abierto hay poco lugar, y en una de 690px sin
   sidebar sobra.

   Los números salen de medir lo que ocupan: conteo 87 + orden 150 +
   por página 109 + botón 68, más tres separaciones de 16 = 462 para
   que entren los cuatro; sin "por página", 337. Los cortes llevan
   además los 32px de relleno de la pastilla, porque lo que se mide es
   la franja de afuera: 494 y 369. */
.vit-barra-vista > .vit-count     { flex-shrink: 0; order: 1; }
.vit-barra-vista > #vit-sort-select { flex-shrink: 0; order: 2; margin-left: auto; }
.vit-barra-vista > #vit-por-pagina  { flex-shrink: 0; order: 3; }
.vit-barra-vista > .rep-vista     { flex-shrink: 0; order: 4; }

/* Cuando algo baja, la pastilla pasa de flex a grid y cada cosa se
   coloca por nombre. Con flex, lo que baja se lleva la línea entera —un
   "20 por página" de borde a borde, que es lo que se veía— porque la
   única forma de forzar el salto de línea es darle el 100% del ancho.
   En grid el salto lo da la fila y el ancho lo sigue dando el
   contenido, así que queda del tamaño que le corresponde, pegado a la
   derecha como sus vecinos de arriba. */

/* No entran los cuatro: baja "por página". Arriba quedan el conteo, el
   orden y el botón. */
@container barracatalogo (max-width: 494px) {
  .vit-barra-vista {
    display: grid;
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "conteo orden vista"
      "porpagina porpagina porpagina";
    align-items: center;
  }
  .vit-barra-vista > .vit-count       { grid-area: conteo;    justify-self: start; }
  .vit-barra-vista > #vit-sort-select { grid-area: orden;     justify-self: end; margin-left: 0; }
  .vit-barra-vista > .rep-vista       { grid-area: vista;     justify-self: end; }
  .vit-barra-vista > #vit-por-pagina  { grid-area: porpagina; justify-self: end; }
}

/* Tampoco entra el orden: se va debajo de "por página" y arriba quedan
   solo el conteo y el botón, uno en cada punta. */
@container barracatalogo (max-width: 369px) {
  .vit-barra-vista {
    grid-template-columns: 1fr auto;
    grid-template-areas:
      "conteo vista"
      "porpagina porpagina"
      "orden orden";
  }
}
/* Sin caja ni borde: en la pastilla son parte de la barra, no campos de
   un formulario como cuando vivían en el sidebar. */
.vit-barra-vista > .vit-sort-select {
  background: transparent;
  border: none;
  padding: 6px 4px;
}
.vit-barra-vista > .vit-sort-select:focus { box-shadow: none; }
/* Los chips se llenan de izquierda a derecha y bajan de línea dentro de
   su propia pastilla, que es toda suya: ya no hay que pelearle el ancho
   al conteo ni al selector de orden, que viven en la de arriba. */
.vit-filtros-bar-top .vit-filtros-sort { flex: 1 1 auto; min-width: 0; }
/* El bloque de chips se angosta en vez de empujar al rótulo: tiene su
   propio flex-wrap, así que cuando no entran en una línea se reparten
   en dos y la pastilla crece de alto. */


.vit-logo {
  font-size: 20px;
  font-weight: 800;
  letter-spacing: -0.3px;
  color: var(--va);
  white-space: nowrap;
  cursor: default;
  user-select: none;
}
.vit-logo span { color: var(--vtx); font-weight: 300; }
 
.vit-search-wrap {
  position: relative;
  width: 100%;
  min-width: 0;
  display: flex;
  align-items: center;
  height: 44px;
  background: var(--vs2);
  border: 1px solid var(--vbor);
  border-radius: var(--rxl);
  padding: 0 6px 0 16px;
  transition: border-color 0.2s var(--ease-apple), box-shadow 0.2s var(--ease-apple);
}
 
.vit-search {
  flex: 1;
  min-width: 0;
  height: 100%;
  background: transparent;
  border: none;
  padding: 0 12px 0 0;
  /* 16px por el token, no 14: bajo 16 Safari en iOS hace zoom al tocar
     el buscador (ver --fs-input arriba). */
  font-size: var(--fs-input);
  color: var(--vtx);
  outline: none;
}
.vit-search::placeholder { color: var(--txt-tenue); }
 
.vit-search-divider {
  width: 1px;
  height: 22px;
  background: var(--vbor2);
  flex-shrink: 0;
}
 
.vit-search-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 34px;
  margin-left: 6px;
  background: transparent;
  border: none;
  border-radius: var(--r);
  color: var(--va);
  font-size: 17px;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s var(--ease-apple);
}
.vit-search-btn:hover { color: var(--va2); }
 
#vit-btn-agregar-nav.activo {
  background: var(--vag2);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
}
#vit-btn-agregar-nav.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}

/* ── Botón Scanner: mismo glow que Carrito/Agenda/Agregar ── */
#vit-btn-scan-nav.activo {
  background: var(--vag2);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
}
#vit-btn-scan-nav.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}
 
/* ── Línea de escaneo animada ── */
@keyframes scanLinea {
  0%, 100% { top: 20%; }
  50%      { top: 78%; }
}
 
@media (max-width: 700px) {
  #modal-scanner-inv.vit-carrito-dropdown {
    width: calc(100vw - 28px) !important;
  }
}
 
.vit-nav-right {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
  /* NO overflow-x:auto acá (se probó y se sacó): alcanza con ponerle
     overflow a un eje para que el navegador trate el OTRO eje también
     como "auto" (regla del spec de CSS Overflow), y eso recortaba /
     scrolleaba los dropdowns que se abren adentro de esta fila (Login,
     que a propósito no "escapa" con position:fixed — ver
     toggleLoginDropdown en vitrina.js, por el autocompletado de Safari)
     en vez de dejarlos flotar por encima como corresponde. En una
     ventana muy angosta el contenido puede no entrar en una sola línea
     — se acepta ese caso raro antes que romper el login. */
}

/* Tres grupos dentro de la fila de menú: ☰/logo fijos a la izquierda;
   Agregar producto+buscador+Carrito pegados entre sí (gap chico) y
   centrados COMO BLOQUE en el espacio restante (antes el buscador se
   centraba solo, separado del carrito, dejando un hueco enorme entre
   ambos); Servicio técnico/Notas/Pendientes/WhatsApp/Usuario/Login en
   su propio grupo, pegado al extremo derecho, sin cambios. */
/* Izquierda y derecha son la misma caja; el del medio (abajo) sí es
   distinto, porque es el que se estira. */
.vit-nav-group-left,
.vit-nav-group-right {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.vit-nav-group-center {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
}

/* ☰ y logo, ahora dentro de la fila de menú — se achican un poco para
   quedar a tono con el resto (los .vit-nav-menutext miden 30px). */
.vit-nav-group-left > .vit-btn-menu {
  width: 30px;
  height: 30px;
  font-size: 16px;
  flex-shrink: 0;
}
.vit-nav-group-left > .vit-logo {
  font-size: 16px;
  margin-right: 4px;
  flex-shrink: 0;
}
/* En fixhubpos.com el logo es la marca del producto y tiene que pesar;
   en la vitrina de un taller es apenas la firma de quién hizo el sitio,
   y ahí compite con el nombre del propio taller. Por eso el tamaño
   cambia solo en uno de los dos sitios (html.fx-pos lo pone
   comun/js/dominios.js, justamente para casos así). */
html.fx-pos .vit-nav-group-left > .vit-logo { font-size: 22px; }

/* Buscador — un ítem más (achicable) dentro de .vit-nav-group-center,
   junto a Agregar producto/Carrito/etc. */
.vit-nav-group-center > .vit-search-wrap {
  width: auto;
  min-width: 200px;
  max-width: 340px;
  height: 30px;
  flex-shrink: 1;
}

/* ── Vuelta al diseño de íconos sueltos (sin texto al lado) para
   Carrito/Servicio técnico/Notas/Pendientes/WhatsApp/Agregar producto/
   Login/Usuario — el texto queda como title/aria-label para
   accesibilidad, pero visualmente solo se ve el ícono, como era antes
   del intento de "barra de Apple" con texto plano. ── */
.vit-nav-right .vit-nav-menutext {
  width: 30px;
  height: 30px;
  gap: 0;
  padding: 0;
  justify-content: center;
  border-radius: var(--r);
  color: var(--vtx2);
  white-space: nowrap;
}
.vit-nav-right .vit-nav-menutext:hover { background: var(--vag); color: var(--vtx); }
.vit-nav-right .vit-nav-menutext i { display: inline-flex; font-size: 17px; }
.vit-nav-right .vit-nav-menutext span:not(.vit-carrito-badge-nav) { display: none; }
.vit-nav-right .vit-nav-menutext .vit-carrito-badge-nav {
  position: absolute;
  top: 1px;
  right: 1px;
  margin-left: 0;
}
/* ── Excepción: Login/Usuario se ven con texto completo ("Iniciar
   sesión" / nombre del usuario), como antes — nunca solo ícono, a
   diferencia del resto de los botones de esta fila. ── */
.vit-nav-right .vit-btn-login,
.vit-nav-right .vit-usuario-info {
  width: auto;
  gap: 8px;
  padding: 0 10px;
}
.vit-nav-right .vit-btn-login span:not(.vit-carrito-badge-nav),
.vit-nav-right .vit-usuario-info strong {
  display: inline;
}

/* ── Excepción: Servicio técnico para visitantes SIN sesión se ve con
   texto completo (llamado a la acción claro, "Servicio técnico"), no
   solo el ícono — es el único botón del navbar pensado también para
   quien no tiene cuenta. Logueado, cuando reaparece en la página
   Agenda como acceso rápido, sí vuelve a ser solo ícono (clase
   .vit-servicio-solo-icono, agregada por JS en _onLoginExitoso/
   _cerrarSesionVitrina, ver vitrina.js). ── */
.vit-nav-right .vit-btn-agenda-nav-texto {
  width: auto;
  gap: 6px;
  padding: 0 10px;
  /* El botón hereda font-size:20px de .vit-btn-carrito-nav (pensado para
     el glyph del ícono, que ya tiene su propio font-size:17px puesto
     aparte) — sin esto el texto "Servicio técnico" salía enorme. Mismo
     tamaño que el resto de los textos del sidebar (.nav-item-pill). */
  font-size: 14px;
}
.vit-nav-right .vit-btn-agenda-nav-texto span:not(.vit-carrito-badge-nav) {
  display: inline;
}

.vit-nav-right .vit-btn-agenda-nav-texto.vit-servicio-solo-icono {
  width: 30px;
  gap: 0;
  padding: 0;
}
.vit-nav-right .vit-btn-agenda-nav-texto.vit-servicio-solo-icono span:not(.vit-carrito-badge-nav) {
  display: none;
}

/* ── "Prueba gratis", al lado de "Iniciar sesión" ────────────────
   Solo existe en fixhubpos.com (el markup está en un bloque @pos), así
   que no hace falta esconderlo en el otro sitio.

   Sí lleva relleno morado, a diferencia de "Iniciar sesión", que es
   transparente. No son dos botones equivalentes: entrar es para quien
   ya es cliente y sabe que ese botón está ahí, probar es para el que
   llegó recién y todavía no decidió nada. El que hay que hacer ver es
   el segundo.

   Mismo alto que "Iniciar sesión" para que la barra no se descuadre. */
.vit-btn-prueba {
  display: flex;
  align-items: center;
  height: 36px;
  padding: 0 16px;
  border: 1px solid rgba(206, 147, 216, 0.30);
  border-radius: 999px;
  background: rgba(122, 44, 170, 0.40);
  color: #fff;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), border-color 0.15s var(--ease-apple);
}
.vit-btn-prueba:hover {
  background: rgba(138, 54, 190, 0.55);
  border-color: rgba(206, 147, 216, 0.50);
}
/* En pantalla angosta la barra ya va apretada: el botón se queda, que
   es lo que se vino a mostrar, pero pide menos ancho. */
@media (max-width: 560px) {
  .vit-btn-prueba { padding: 0 11px; font-size: 12.5px; }
}

.vit-btn-login {
  display: flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 10px;
  background: transparent;
  border: none;
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 13px;
  font-weight: 400;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple), box-shadow 0.25s var(--ease-apple);
  white-space: nowrap;
}
.vit-btn-login:hover { background: var(--vag); color: var(--vtx); }
.vit-btn-login i { font-size: 20px; transition: filter 0.25s var(--ease-apple); }
 
/* ── Estado activo: el botón "brilla" mientras el dropdown está abierto ── */
.vit-btn-login.activo {
  background: var(--vag2);
  color: var(--vtx);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
  font-weight: 700;
}
.vit-btn-login.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}
 
.vit-usuario-info {
  display: none;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 10px;
  border-radius: var(--r);
  font-size: 13px;
  color: var(--vtx2);
  cursor: pointer;
  transition: background 0.15s var(--ease-apple);
}
.vit-usuario-info:hover { background: var(--vag); }
.vit-usuario-info.activo {
  background: var(--vag2);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
}
.vit-usuario-info.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}
.vit-usuario-info.activo strong { color: var(--va); }
.vit-usuario-info strong { color: var(--vtx); font-weight: 600; transition: color 0.15s var(--ease-apple); }
.vit-usuario-info i { font-size: 20px; transition: filter 0.25s var(--ease-apple); }
/* El aviso de novedades, pegado al nombre. Del color del acento y no
   rojo: no es un error, es que hay algo esperando.

   Va con el mismo tamaño de letra y de pastilla que el número que se ve
   adentro del menú (.sb-opcion-cuenta), para que se reconozca como el
   mismo dato cuando uno abre y lo encuentra al lado de la opción que lo
   trajo. El min-width lo mantiene redondo con un solo dígito, que es el
   caso normal. */
.vit-aviso-usuario {
  flex-shrink: 0;
  min-width: 18px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--va);
  color: #fff;
  font-size: 11px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}
 
/* Herramientas */
.vit-btn-herramientas {
  display: none;
  align-items: center;
  gap: 6px;
  height: 38px;
  padding: 0 14px;
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.2s var(--ease-apple);
}
.vit-btn-herramientas:hover { border-color: var(--va); color: var(--va); }
 
/* ── Carrito wrapper ──────────────────────────────────────── */
.vit-carrito-wrapper { position: relative; }
 
.vit-agenda-wrapper { position: relative; }
 
/* ════════════════════════════════════════════════════════════
   FLECHA + GLOW — mismo diseño para TODOS los dropdowns tipo
   panel (Carrito, Agenda, Agregar Producto, Scanner, Login,
   Usuario). Antes cada uno traía su propia copia de estos
   valores, y Login/Usuario directamente no tenían el glow
   difuminado (solo la flecha); ahora es una sola definición y
   cada selector solo aporta su offset (top/right).
 
   - Carrito / Agenda / Agregar Producto / Login / Usuario: el
     pseudo-elemento vive en el WRAPPER (no en el dropdown) — todos
     estos dropdowns ahora "escapan" del wrapper con
     _escaparDropdownFlotante (vitrina.js) y flotan centrados bajo su
     botón con position:fixed, así que una flecha pegada al propio
     dropdown quedaría descolgada de su botón apenas la centrada la
     corriera. Pegada al wrapper, que no se mueve, siempre apunta bien.
   - Scanner: es position:fixed y vive fuera de cualquier wrapper,
     así que su flecha+glow es un elemento real aparte
     (#modal-scanner-glow) que JS posiciona en runtime.
   ════════════════════════════════════════════════════════════ */
.vit-carrito-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::before,
.vit-agenda-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::before,
.vit-agregarprod-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::before,
.vit-login-wrapper:has(> .vit-login-dropdown:not(.oculto))::before,
.vit-usuario-wrapper:has(> .vit-usuario-dropdown:not(.oculto))::before,
#modal-scanner-glow::before {
  content: '';
  position: absolute;
  width: 12px; height: 12px;
  background: var(--vs2);
  border-left: 1px solid var(--vbor2);
  border-top: 1px solid var(--vbor2);
  transform: rotate(45deg);
  top: calc(100% + 6px); right: 20px;
  z-index: 301;
}

.vit-carrito-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::after,
.vit-agenda-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::after,
.vit-agregarprod-wrapper:has(> .vit-carrito-dropdown:not(.oculto))::after,
.vit-login-wrapper:has(> .vit-login-dropdown:not(.oculto))::after,
.vit-usuario-wrapper:has(> .vit-usuario-dropdown:not(.oculto))::after,
#modal-scanner-glow::after {
  content: '';
  position: absolute;
  width: 60px; height: 24px;
  background: radial-gradient(ellipse at center, rgba(206,147,216,0.35) 0%, rgba(206,147,216,0) 70%);
  filter: blur(4px);
  pointer-events: none;
  top: calc(100% - 2px); right: 20px;
  z-index: -1;
}


#modal-scanner-inv {
  overflow: visible;
}
 
/* ── Flecha + glow del Scanner ──
   Igual que en Carrito/Agenda/Agregar Producto: la flecha (::before)
   va POR ENCIMA del modal (z-index 301 > 300) para que se vea
   completa, sin que el modal la recorte; el glow difuminado (::after)
   va por debajo (z-index -1). Antes ambos vivían sin z-index propio
   dentro de un contenedor (#modal-scanner-glow) que sí tenía
   z-index:299, así que quedaban atrapados por debajo del modal
   entero — de ahí el triángulo "cortado". Se quitó el z-index del
   contenedor para que sus pseudo-elementos compitan directamente
   contra el modal en el stacking context correcto. ── */
#modal-scanner-glow {
  display: none;
  position: fixed;
  pointer-events: none;
}
#modal-scanner-inv:not(.oculto) ~ #modal-scanner-glow {
  display: block;
}
.vit-btn-carrito-nav {
  display: none;
  position: relative;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: transparent;
  border: none;
  border-radius: var(--r);
  color: var(--va);
  font-size: 20px;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple);
}
.vit-btn-carrito-nav:hover { background: var(--vag); color: var(--va); }
.vit-btn-carrito-nav i { transition: filter 0.25s var(--ease-apple); }
 
/* ── Botón "Servicio técnico" (llave): mismo ícono suelto que el resto,
   sin texto al lado ── */
.vit-btn-agenda-nav-texto:hover { color: var(--vtx); }
.vit-btn-carrito-nav.activo {
  background: var(--vag2);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
}
.vit-btn-carrito-nav.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}
 
.vit-carrito-badge-nav {
  position: absolute;
  top: 1px;
  right: 1px;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  background: var(--va);
  color: #fff;
  border-radius: 10px;
  font-size: 10px;
  font-weight: 700;
}
 
/* Dropdown carrito */
.vit-carrito-dropdown {
  position: absolute;
  top: calc(100% + 12px);
  right: 0;
  width: 380px;
  max-height: 80vh;
  background: var(--vs2);
  border: 1px solid var(--vbor2);
  border-radius: var(--rl);
  z-index: 300;
  box-shadow:
  0 24px 64px rgba(0,0,0,0.8),
  0 0 0 1px rgba(206,147,216,0.35),
  0 0 22px rgba(206,147,216,0.22);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Sin esto, pasar la rueda del mouse sobre una zona del carrito sin
     scroll propio (p.ej. los campos de "Persona") deja que el gesto
     "se escape" hacia la página de atrás — este panel no scrollea nada
     él mismo (overflow:hidden), pero corta la cadena igual. */
  overscroll-behavior: contain;
  animation: asomarse 0.18s var(--ease-apple);
}
/* .vit-carrito-dropdown ya trae su propia "animation: asomarse" (arriba),
   y con la misma especificidad (una sola clase) que el ".cerrando" genérico
   de utilidades.css, el empate lo gana quien se cargue después en el HTML
   — que es este archivo. Entonces al agregar .cerrando nunca se pasaba a
   "despedirse": el dropdown (carrito, agenda/calendario, agregar producto)
   se quedaba quieto los 140ms y recién ahí lo tapaba el display:none de
   .oculto, sin transición visible. Este override, más específico
   (0,0,2,0), gana siempre sin depender del orden de los <link>. */
.vit-carrito-dropdown.cerrando {
  animation: despedirse 0.14s var(--ease-apple) forwards;
}
.vit-carrito-dropdown.oculto { display: none; }
 
/* ── Calendario de Agenda (agenda.js: _htmlVistaAnio / _htmlDiasDelMes).
   Antes el hover se simulaba con onmouseover/onmouseout inline (sin
   --ease-apple, y reconstruyendo el color base "a mano" en el onmouseout
   de cada celda). Se pasa a clases reales: el color base va en la
   variable --cal-bg (única parte que cambia por celda: hoy/seleccionado/
   feriado), y el hover + la transición quedan en CSS, iguales para
   todo el calendario. ── */
.agenda-cal-dia {
  background: var(--cal-bg, transparent);
  transition: background 0.15s var(--ease-apple);
}
.agenda-cal-dia:hover { background: var(--vag); }
 
.agenda-mini-mes {
  cursor: pointer;
  padding: 5px;
  border-radius: var(--r);
  transition: background 0.15s var(--ease-apple);
}
.agenda-mini-mes:hover { background: var(--vag); }
 
.vit-carrito-drop-header {
  padding: 16px 18px 12px;
  border-bottom: 1px solid var(--vbor);
}
 
/* ── Indicador de pasos: numerado y horizontal, estilo seguimiento de
   envío (círculo por paso conectado por una línea que se va llenando a
   medida que se avanza; ✓ en los pasos ya completados). Compartido por
   el carrito interno (carrito.js) y el público (carrito-publico.js) vía
   _renderStepsIndicadorCarrito en utilidades.js. ── */
.vit-carrito-steps {
  display: flex;
  align-items: center;
  padding-top: 10px;
}
.vit-carrito-step {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}
.vit-carrito-step-circ {
  width: 20px;
  height: 20px;
  flex-shrink: 0;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 10px;
  font-weight: 700;
  background: var(--vs3);
  border: 1px solid var(--vbor2);
  color: var(--txt-sub);
  transition: background 0.2s var(--ease-apple), border-color 0.2s var(--ease-apple), color 0.2s var(--ease-apple);
}
.vit-carrito-step-circ i { font-size: 11px; }
.vit-carrito-step.activo .vit-carrito-step-circ {
  background: var(--va);
  border-color: var(--va);
  color: #fff;
}
.vit-carrito-step.hecho .vit-carrito-step-circ {
  background: var(--vgrn);
  border-color: var(--vgrn);
  color: #fff;
}
.vit-carrito-step-linea {
  flex: 1 1 auto;
  height: 2px;
  min-width: 8px;
  margin: 0 4px;
  background: var(--vbor2);
  transition: background 0.2s var(--ease-apple);
}
.vit-carrito-step-linea.hecho { background: var(--vgrn); }
.vit-carrito-drop-titulo {
  font-size: 14px;
  font-weight: 700;
  color: var(--vtx);
  display: flex;
  align-items: center;
  gap: 8px;
}
.vit-carrito-drop-titulo i { color: var(--va); }
 
.vit-carrito-drop-items { max-height: 290px; overflow-y: auto; }
 
.vit-carrito-drop-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--vbor);
  transition: background 0.12s var(--ease-apple);
}
.vit-carrito-drop-item:hover { background: rgba(255,255,255,0.02); }
.vit-carrito-drop-item:last-child { border-bottom: none; }
 
.vit-carrito-drop-info { flex: 1; min-width: 0; }
.vit-carrito-drop-nombre { font-size: 13px; font-weight: 500; color: var(--vtx); overflow-wrap: anywhere; }
.vit-carrito-drop-precio { font-size: 13px; color: var(--va); font-weight: 700; margin-top: 3px; }
.vit-carrito-drop-cant   { font-size: 11px; color: var(--txt-sub); margin-top: 2px; }
 
.vit-carrito-drop-quitar {
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: 50%;
  width: 26px; height: 26px;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  color: var(--txt-sub);
  font-size: 12px;
  transition: all 0.15s var(--ease-apple);
  flex-shrink: 0;
}
.vit-carrito-drop-quitar:hover { border-color: var(--vred); color: var(--vred); }
 
.vit-carrito-drop-empty {
  padding: 36px 18px;
  text-align: center;
  color: var(--txt-sub);
  font-size: 13px;
}
 
.vit-carrito-drop-footer {
  padding: 14px 18px;
  border-top: 1px solid var(--vbor);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  background: var(--vs3);
}
.vit-carrito-drop-total { font-size: 14px; font-weight: 700; color: var(--vtx); }
.vit-carrito-drop-total span { color: var(--va); }
 
.vit-btn-ver-carrito {
  height: 36px; padding: 0 16px;
  background: var(--vag2);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--va);
  font-size: 13px; font-weight: 600;
  cursor: pointer; transition: all 0.2s var(--ease-apple); white-space: nowrap;
  display: flex; align-items: center; gap: 6px;
}
.vit-btn-ver-carrito:hover { background: rgba(206,147,216,0.32); border-color: var(--va); }
 
/* ── Login wrapper ─────────────────────────────────────────── */
.vit-login-wrapper { position: relative; }
 
.vit-login-dropdown {
  position: absolute;
  /* right, no left: el botón de Login vive en el extremo DERECHO de la
     barra de menú — anclado a la izquierda (left:0) el dropdown se salía
     de la pantalla por la derecha. */
  top: calc(100% + 12px); right: 0;
  width: 300px;
  /* Tenía tope vertical pero no horizontal: en una ventana de 280px este
     panel medía 288 y se salía 28px por la izquierda. Va contra
     --ancho-ventana y no contra 100vw, que incluye la barra de scroll
     (ver _publicarAnchoVentana en utilidades.js). */
  max-width: calc(var(--ancho-ventana, 100vw) - 24px);
  /* Tope + scroll propio por si no entra completo en pantallas bajas o
     con zoom — así nunca se corta contra el borde de la ventana. */
  max-height: min(600px, calc(100vh - 96px));
  max-height: min(600px, calc(100dvh - 96px));
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--vs2);
  border: 1px solid var(--vbor2);
  border-radius: var(--rl);
  padding: 24px 22px;
  display: flex; flex-direction: column; gap: 14px;
  z-index: 300;
  box-shadow:
  0 24px 64px rgba(0,0,0,0.8),
  0 0 0 1px rgba(206,147,216,0.35),
  0 0 22px rgba(206,147,216,0.22);
  animation: asomarse 0.18s var(--ease-apple);
}

.vit-login-dropdown.oculto { display: none; }

.vit-dropdown-titulo { font-size: 16px; font-weight: 700; color: var(--va); text-align: center; }
.vit-dropdown-sub    { font-size: 12px; color: var(--txt-sub); text-align: center; margin-top: -8px; }

#vit-login-campos { display: flex; flex-direction: column; gap: 14px; }
/* Los campos de contraseña nueva ocupan el mismo lugar del panel: se
   muestran en vez de los de entrar, nunca junto con ellos. */
#vit-reset-campos { display: flex; flex-direction: column; gap: 14px; }
#vit-reset-campos[hidden] { display: none; }
 
.vit-login-dropdown label {
  display: block;
  font-size: 11px; font-weight: 700;
  color: var(--txt-sub);
  text-transform: uppercase; letter-spacing: 0.08em;
  margin-bottom: 6px;
}
.vit-login-dropdown input {
  width: 100%; height: 42px;
  background: var(--vs3);
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  padding: 0 14px;
  font-size: var(--fs-input); color: var(--vtx);
  outline: none; transition: border-color 0.2s var(--ease-apple), box-shadow 0.2s var(--ease-apple);
}
.vit-login-dropdown input::placeholder { color: var(--txt-tenue); }
 
.vit-modal-error { font-size: 12px; color: var(--vred); text-align: center; min-height: 14px; }
.vit-modal-error.vit-modal-msg-ok { color: #81c784; }

.vit-btn-ingresar {
  width: 100%; height: 42px;
  background: linear-gradient(135deg, rgba(206,147,216,0.3), rgba(206,147,216,0.15));
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--va);
  font-size: 14px; font-weight: 700;
  cursor: pointer; transition: all 0.2s var(--ease-apple); letter-spacing: 0.2px;
}
.vit-btn-ingresar:hover { background: rgba(206,147,216,0.35); border-color: var(--va); }
.vit-btn-ingresar:disabled { opacity: 0.4; cursor: not-allowed; }

/* "Ver catálogo" del Home — reusa .vit-btn-ingresar (mismo look que el
   botón de login) pero más chico y centrado en vez de ancho completo,
   ahora que vive pegado abajo del carrusel de banners en vez de al
   fondo de toda la fila de Dispositivos. */
.fixhub-btn-catalogo {
  width: auto;
  height: 34px;
  padding: 0 24px;
  display: block;
  margin: 16px auto 0;
  font-size: 13px;
}

.vit-link-olvide-clave {
  display: block;
  width: 100%;
  margin-top: 4px;
  background: none;
  border: none;
  color: var(--txt-sub);
  font-size: 12px;
  text-align: center;
  cursor: pointer;
  transition: color 0.2s var(--ease-apple);
}
.vit-link-olvide-clave:hover { color: var(--va); text-decoration: underline; }
.vit-link-olvide-clave:disabled { opacity: 0.5; cursor: not-allowed; text-decoration: none; }

/* ════════════════════════════════════════════════════════════
   LAYOUT
   ════════════════════════════════════════════════════════════ */
.vit-layout {
  display: flex;
  align-items: flex-start;
  /* Se lleva el alto que sobre en la columna de #vitrina-root; ya no hay
     que restarle a mano el alto del navbar. */
  flex: 1 0 auto;
}
.vit-layout.vit-layout-oculto { display: none; }

/* ════════════════════════════════════════════════════════════
   SIDEBAR
   ════════════════════════════════════════════════════════════ */
/* Esto es el sidebar COMO COLUMNA, que es lo que es en el escritorio.
   De 700px para abajo no corre ninguna de estas medidas: ahí el sidebar
   es un cajón lateral y de eso se encarga .fx-cajon (utilidades.css), la
   misma clase que usa el cajón de accesos de la vitrina del taller.
   Van dentro del @media y no sueltas porque .vit-sidebar y .fx-cajon
   pesan lo mismo, y esta hoja se carga después: sueltas le ganaban al
   cajón y lo dejaban con el ancho y la curva de la columna. */
@media (min-width: 701px) {
  .vit-sidebar {
    width: 272px;
    min-width: 272px;
    background: var(--vb);
    border: 1px solid var(--vbor);
    border-radius: 18px;
    overflow-x: visible;
    overflow-y: auto;
    overflow-anchor: none; /* que no se autoajuste el scroll solo al cambiar de alto (filtros que se abren/cierran, etc.) */
    box-shadow: 0 8px 24px rgba(0,0,0,0.35);
    transition: width 0.35s var(--ease-apple), min-width 0.35s var(--ease-apple), margin-left 0.35s var(--ease-apple), opacity 0.35s var(--ease-apple), padding 0.35s var(--ease-apple);
  }
}

/* Solo existe como panel flotante en mobile (ver @media max-width:700px);
   en desktop el sidebar es sticky en el layout normal y no necesita cierre. */
.vit-sidebar-btn-cerrar { display: none; }
 
@media (min-width: 701px) {
  /* Sidebar sticky "de toda la vida": el navbar scrollea con la
     página como cualquier otro contenido, y el sidebar se pega al
     borde de arriba del viewport (no al navbar) apenas este último
     se sale de pantalla. height/max-height/padding/z-index
     compartidos con la variante "suelta" de Registro/Gráficos/Agenda/
     Admin viven en utilidades.css. margin-top:10px = mismo valor que
     "top" (el umbral del sticky): así arranca con ese espacio de
     separación bajo el navbar desde el primer render (no pegado del
     todo), igual que el resto de los sidebars (Registro/Gráficos/
     Agenda/Admin, variante fixed acá abajo). */
  .vit-layout > .vit-sidebar {
    /* "top" tiene que incluir el alto real del navbar (ahora sticky, se
       queda pegado arriba siempre) + el mismo margin-top:10px de acá
       abajo, para que el sidebar arranque pegado justo debajo del
       navbar con el mismo espacio de siempre, sin saltos al hacer
       scroll (ver _actualizarTopVitpPages en vitp-paginas.js, que mide
       el alto real del navbar en vivo). z-index MENOR al del navbar
       (100): si alguna vez llegan a superponerse visualmente, el
       navbar tiene que quedar por encima, nunca tapado por el sidebar.
       Acotado por .vit-layout (el footer vive afuera, como hermano de
       .vit-layout) — nunca puede "pisar" el footer, por más alto que
       sea el contenido: el sticky no puede escapar la caja de su
       contenedor. */
    position: sticky;
    top: calc(var(--vit-nav-alto, 62px) + 10px);
    z-index: 50;
    align-self: flex-start;
    margin: 10px 10px 10px 10px;
  }
}
 
/* ════════════════════════════════════════════════════════════
   Los dropdowns del navbar (Carrito, Agenda, Notas, Login, Usuario,
   Agregar producto) se resuelven en JS (vitrina.js:
   _escaparDropdownFlotante / _restaurarDropdownFlotante): mientras
   están abiertos, escapan de su wrapper y flotan por encima de TODO
   (z-index:290) sin necesidad de tocar el z-index del navbar ni
   arrastrarlo por encima del sidebar (eso tapaba el botón ☰ que vive
   dentro del propio sidebar).
   ════════════════════════════════════════════════════════════ */
 
/* ════════════════════════════════════════════════════════════
   "CÓMO VER", arriba del sidebar de filtros
   ════════════════════════════════════════════════════════════
   Cuántos productos hay y cómo mirarlos: tarjetas o tabla, orden,
   cuántos por página y qué stock. Cuatro campos rotulados, sin título
   de sección y sin plegar, arriba de los filtros — que sí son secciones
   plegables porque cada una esconde cientos de opciones.

   Estuvo un rato como columna propia a la derecha de la grilla. Se
   juntó con esta: dos columnas, una de cada lado, le comían el ancho a
   las tarjetas justo cuando la ventana no sobraba, y obligaban a cruzar
   la pantalla para pasar de "qué busco" a "cómo lo miro". */
/* Los controles, uno abajo del otro y a todo el ancho. Menos sangrado a
   la izquierda que una lista de filtros: esos son items de una lista;
   estos, campos de un formulario. */
.vit-sb-vista {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 2px 12px 4px;
}
.vit-sb-vista-label {
  display: block;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.6px;
  text-transform: uppercase;
  color: var(--txt-sub);
  margin-top: 4px;
}
/* El primero no necesita el aire de arriba: lo da el cuerpo de la
   sección, que ya viene con su relleno. */
.vit-sb-vista > .vit-sb-vista-label:first-child { margin-top: 0; }
.vit-sb-vista .vit-sort-select { width: 100%; }
/* Un campo que se puede esconder entero, etiqueta incluida (hoy, Stock
   para quien no tiene sesión). Por dentro se apila igual que si sus dos
   hijos colgaran directo del cuerpo. */
.vit-sb-vista-campo { display: flex; flex-direction: column; gap: 6px; }

.vit-sidebar.cerrado {
  width: 0;
  min-width: 0;
  margin-left: 0;
  padding: 0;
  opacity: 0;
  border: none;
  overflow: hidden;
}
 
/* ════════════════════════════════════════════════════════════
   SIDEBAR "SUELTO" para Gráficos/Registro — mismo espíritu que el
   catálogo (asomarse por encima del navbar), pero acá el <aside> se
   saca por completo de adentro de .vitp-page (ver vitp-paginas.js) y
   pasa a vivir como hermano directo de .vit-nav dentro de
   #vitrina-root (que no tiene z-index propio). Así compite de igual
   a igual contra .vit-nav (270 > 260) sin arrastrar el resto de la
   página con él y sin taparle los dropdowns al navbar.
   ════════════════════════════════════════════════════════════ */
@media (min-width: 701px) {
  .vit-sidebar.vitp-sidebar-fijo {
    /* height/max-height/padding/z-index compartidos viven en
       utilidades.css (ver comentario ahí) — acá solo lo propio de la
       variante fixed. "+10px": mismo espacio de separación bajo el
       navbar que el sidebar del catálogo (sticky, más arriba, con
       margin-top:10px) — a propósito, no pegado del todo. */
    position: fixed;
    top: calc(var(--vit-nav-alto, 62px) + 10px);
    left: 10px;
    margin: 0;
  }
}
 
/* Secciones del sidebar */
.vit-sb-section {
  padding: 2px 12px;
}
 
/* .vit-sb-section-btn hereda la cajita redondeada de .nav-item-pill
   (utilidades.css) — acá solo se agrega lo que le es propio: separar
   el ícono+texto (agrupados en un <span>) del chevron a la derecha. */
.vit-sb-section-btn {
  justify-content: space-between;
}
.vit-sb-section-btn span {
  display: flex; align-items: center; gap: 9px;
}
 
.vit-sb-section-btn.activo .vit-sb-chevron { color: var(--va); }
 
.vit-sb-chevron {
  font-size: 13px;
  color: var(--txt-sub);
  transition: transform 0.2s var(--ease-apple), color 0.15s var(--ease-apple);
  flex-shrink: 0;
}
 
/* Cuerpo de la sección: más indentado a la izquierda (28px vs 12px del
   header, que ahora ya tiene su propio margen de 12px) para que las
   opciones se vean "tabuladas" adentro de su sección. */
.vit-sb-section-body {
  padding: 4px 12px 12px 28px;
}
.vit-sb-section-body.cerrado { display: none; }
 
/* Items de filtro — más chicos que antes (son subcategorías, no
   títulos), más espacio, separador sutil */
/* Las filas de opción de los sidebars de filtros son .sb-opcion
   (utilidades.css), las mismas del admin y de la consola — acá vivía un
   segundo juego con las mismas medidas escritas a mano. Ver
   _htmlOpcionSidebar en utilidades.js. */

/* Precio */
.vit-precio-actual {
  font-size: 22px; font-weight: 800;
  color: var(--vtx); text-align: center;
  padding: 10px 0 14px; letter-spacing: -0.5px;
}
.vit-slider {
  width: 100%; accent-color: var(--vtx);
 
  cursor: pointer; margin-bottom: 8px;
}
.vit-precio-labels {
  display: flex; justify-content: space-between;
  font-size: 11px; color: var(--txt-sub); padding: 0 2px;
}
 
/* Toggle switch */
.vit-toggle-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 6px;
  border-radius: var(--r); cursor: pointer; transition: background 0.12s var(--ease-apple);
}
.vit-toggle-item:hover { background: var(--vag2); }
.vit-toggle-info  { display: flex; flex-direction: column; gap: 3px; }
/* Misma medida que .sb-opcion: las filas de Stock son una
   opción más dentro de su sección, no un título — antes eran más grandes
   y en negrita, y cantaban al lado de los demás filtros del sidebar. */
.vit-toggle-label { font-size: 13px; font-weight: 400; color: var(--vtx2); }
.vit-toggle-sub   { font-size: 11px; color: var(--txt-sub); }
 
.vit-toggle-wrap { position: relative; width: 38px; height: 22px; flex-shrink: 0; }
/* Esconder el checkbox lo hace .chk-dark (utilidades.css), que estaba
   repetido acá con las mismas cuatro propiedades. La clase se queda en el
   marcado igual, porque de ella cuelgan los selectores hermanos de abajo. */
.vit-toggle-track {
  position: absolute; inset: 0;
  background: rgba(255,255,255,0.1);
  border-radius: 22px; cursor: pointer;
  transition: background 0.2s var(--ease-apple), box-shadow 0.2s var(--ease-apple);
}
.vit-toggle-input:hover + .vit-toggle-track { box-shadow: 0 0 0 3px rgba(206,147,216,0.15); }
.vit-toggle-track::after {
  content: '';
  position: absolute; top: 3px; left: 3px;
  width: 16px; height: 16px;
  background: #fff; border-radius: 50%;
  transition: transform 0.2s var(--ease-apple);
  box-shadow: 0 1px 4px rgba(0,0,0,0.3);
}
.vit-toggle-input:checked + .vit-toggle-track { background: var(--va); }
.vit-toggle-input:checked + .vit-toggle-track::after { transform: translateX(16px); }
 
.vit-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }

.vit-count { font-size: 12px; color: var(--txt-sub); white-space: nowrap; flex-shrink: 0; }
 
/* Filtros activos dentro del resumen del sidebar */
.vit-filtros-sort {
  display: flex; flex-wrap: wrap; gap: 6px;
}
.vit-filtro-sort-tag {
  display: flex; align-items: center; gap: 5px;
  padding: 4px 10px 4px 8px;
  background: var(--vag);
  border: 1px solid var(--vbor2);
  border-radius: 20px;
  font-size: 11px; font-weight: 600;
  color: var(--va);
  cursor: pointer; transition: all 0.15s var(--ease-apple);
}
.vit-filtro-sort-tag:hover { background: var(--vag2); }
.vit-filtro-sort-tag i { font-size: 11px; }
/* Chip fijo (ej. "Solo con stock" para un cliente sin sesión) — mismo
   look pero sin X y sin cursor de click, porque no se puede quitar. */
.vit-filtro-sort-tag-bloqueado { cursor: default; padding: 4px 10px; }
.vit-filtro-sort-tag-bloqueado:hover { background: var(--vag); }
 
.vit-sort-select {
  background: var(--vs2);
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 12px; padding: 6px 10px;
  outline: none; cursor: pointer;
  transition: border-color 0.2s var(--ease-apple);
}
.vit-sort-select option { background: var(--vs2); }
 
 
/* ════════════════════════════════════════════════════════════
   GRILLA
   ════════════════════════════════════════════════════════════ */
#vit-grid-wrap {
  padding: 6px 36px 20px;
  flex: 1;
  /* La grilla de adentro se mide contra ESTE hueco y no contra la
     ventana: lo que decide cuántas tarjetas caben es el espacio que
     queda después del sidebar, no el ancho del navegador. Con la
     ventana, una de 737px dejaba un hueco de 362 —donde entran dos
     tarjetas— y la regla igual mandaba una sola, porque 737 estaba
     lejos de cualquier umbral. */
  container-type: inline-size;
  container-name: grillacatalogo;
}
 
.vit-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(175px, 100%), 1fr));
  gap: 14px;
}

/* ── El catálogo en lista ──────────────────────────────
   La otra forma de ver el mismo catálogo: una fila por producto, con
   encabezados de columna que ordenan, para barrer cien productos y ver
   de un vistazo qué hay, qué falta y a qué precio.

   Se ve como una tabla pero NO es una <table>, y esa es la decisión de
   fondo. Una tabla se ensancha con su contenido: para que no rompiera la
   página había que meterla en una caja con overflow-x, y esa caja se
   queda con la rueda del mouse — parado encima de la lista, la página no
   bajaba. Lo intenté con overscroll-behavior-y:auto, con overflow-y:
   hidden y con un escucha de "wheel" que reenviaba el gesto a mano: los
   tres son parches sobre el mismo problema.

   Con una grilla de columnas en fr no hay problema que parchear. Las
   columnas se reparten el ancho que hay, nunca desbordan, no hace falta
   segundo contenedor de scroll y la rueda es la de siempre. Lo que no
   cabe se corta con "…" en vez de empujar.

   El encabezado y las filas repiten la MISMA plantilla de columnas —por
   eso vive en una variable y no escrita dos veces— y por eso quedan
   alineados sin que nadie mida nada. */
/* La caja de afuera: corre a lo ancho cuando las columnas no caben.

   overflow-y: clip y NO hidden ni auto. Con hidden o auto esta caja
   sería contenedor de scroll vertical — aunque no haya nada que mover
   el navegador le entrega la rueda del mouse, y parado sobre la lista
   la página no baja. "clip" recorta igual y no crea contenedor, así
   que la rueda vertical sigue siendo la de la página y la horizontal
   corre la lista. Por lo mismo el encabezado pegajoso se pega contra la
   página, que es quien scrollea de verdad. */
/* La caja de arriba (.vit-tabla-caja) existe solo para que la barra de
   abajo tenga de dónde pegarse: sticky se mueve dentro de su bloque, y
   ese bloque tiene que ser exactamente el alto de la lista. */
.vit-tabla-caja { position: relative; }

/* La barra de scroll horizontal que se ve siempre, pegada al borde de
   abajo de la pantalla mientras la lista pasa por delante.

   La barra propia de la caja vive al final de la caja: con 500 productos
   queda a dos mil píxeles de la pantalla, y para enterarse de que la
   lista sigue para el lado había que bajar hasta el último. Por eso la
   de la caja se esconde y la única que se ve es esta, que es un riel
   vacío del ancho de la lista: no muestra nada, solo hace barra, y
   _acomodarLista la mantiene al tanto del ancho y del corrimiento.

   Alto 14px y no 8: acá la barra no es un adorno al costado de algo,
   es el control. */
.vit-tabla-barra {
  position: sticky;
  bottom: 0;
  z-index: 6;
  overflow-x: auto;
  overflow-y: hidden;
  height: 14px;
  margin-top: 2px;
  /* Que el final del recorrido lateral no dispare el gesto de "atrás"
     del navegador, pero que la rueda vertical siga siendo de la página. */
  overscroll-behavior-x: contain;
  overscroll-behavior-y: auto;
  /* utilidades.css le reserva a todo scroll de la casa el carril de la
     barra vertical, para que una cifra pegada a la derecha no quede
     debajo. Acá esa barra no existe — esto corre solo a lo ancho— y el
     carril serían 11px menos de recorrido a cambio de nada. */
  scrollbar-gutter: auto;
}
.vit-tabla-riel { height: 1px; }

.vit-tabla-wrap {
  /* Sin barra propia: la que se ve es .vit-tabla-barra, que está a la
     vista siempre. Dos barras para lo mismo, una de ellas escondida al
     fondo de la lista, es una de más. Esconderla no le saca el scroll:
     la rueda y el gesto lateral siguen corriendo la lista. */
  scrollbar-width: none;
  overflow-x: auto;
  overflow-y: clip;
  /* .scroll-morado (la barra fina de la casa) trae overscroll-behavior:
     contain, pensado para listas que scrollean en vertical: al llegar al
     borde, el scroll se queda adentro en vez de arrastrar la página.
     Acá el contain en vertical deja la rueda muerta encima de la lista
     — medido: la página no avanzaba ni un píxel con el puntero sobre
     una fila. Contener a lo ancho sí sirve (que el final del recorrido
     lateral no dispare el gesto de "atrás" del navegador), así que se
     separan los dos ejes, igual que .chart-wrap-scroll. */
  overscroll-behavior-x: contain;
  overscroll-behavior-y: auto;
}
.vit-tabla-wrap::-webkit-scrollbar { display: none; }

.vit-tabla {
  --vit-cols:
    28px                      /* la foto */
    minmax(146px, 1fr)        /* producto */
    minmax(286px, 1.6fr)      /* categoría: la línea larga */
    minmax(238px, 1.1fr)      /* detalle */
    minmax(148px, 1fr)        /* marca */
    minmax(148px, 1fr)        /* modelo */
    minmax(112px, 0.9fr)      /* precio */
    minmax(110px, 0.9fr)      /* stock */
    72px;                     /* los botones */
  /* Cada columna tiene un mínimo en píxeles: el ancho donde su texto
     todavía se lee entero. Si sobra espacio las fr lo reparten; si
     falta, la lista se pasa de ancho y la caja de afuera corre. Antes el
     mínimo era 0 y en pantalla angosta todo terminaba en "…".

     Las dos columnas de los extremos van en píxeles fijos y no en auto:
     "auto" mide su contenido, y el encabezado de esas dos va vacío
     mientras la fila lleva la foto y los botones. Midiendo distinto, lo
     que sobraba para repartir entre las fr también era distinto, y el
     encabezado quedaba corrido respecto de las filas — hasta 108px al
     llegar a la última columna. */
  /* La suma de los mínimos más los ocho espacios de 10px y el relleno
     lateral de 10px por lado. Escrito y no max-content a propósito:
     max-content mide el texto de las celdas, y una descripción larga
     estiraría la lista mucho más de lo necesario. */
  --vit-min: 1388px;
  min-width: var(--vit-min);
  display: flex;
  flex-direction: column;
  gap: 4px;
  /* Un respiro al final del recorrido horizontal. */
  padding-bottom: 2px;
}

/* El encabezado manda: fondo propio y letra marcada, porque además de
   decir qué columna es cuál es el control con el que se ordena. Y fijo
   arriba: una lista larga sin encabezado a la vista obliga a subir para
   saber qué columna es cuál.

   Cómo se queda arriba está explicado en la regla, más abajo. */
.vit-tabla-cab {
  display: grid;
  grid-template-columns: var(--vit-cols);
  align-items: center;
  gap: 0 10px;
  /* Se queda arriba, pero NO con position:sticky: la caja que corre a lo
     ancho es contenedor de scroll, sticky se pegaría contra ella y esa
     caja no scrollea en vertical — o sea, no se pegaba a nada. Lo corre
     _fijarEncabezadoLista en vitrina.js. */
  position: relative;
  z-index: 5;
  padding: 7px 10px;
  border-radius: 10px;
  background: var(--vs3, var(--vs2));
}
.vit-tabla-cab > * {
  /* Los rótulos son <button> para que se puedan apretar con el teclado;
     acá se les saca la pinta de botón. */
  appearance: none;
  border: 0;
  background: none;
  padding: 0;
  min-width: 0;
  font: inherit;
  text-align: center;
  color: var(--vtx);
  font-size: var(--fs-xs, 11px);
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  /* El separador de columna, que baja también por las filas. */
  border-right: 1px solid var(--vbor2);
}
.vit-tabla-cab > *:last-child { border-right: 0; }
.vit-tabla-cab button { cursor: pointer; }
.vit-tabla-cab button:hover { color: var(--va2, var(--va)); }
/* La columna por la que se está ordenando, en el color de acento: saber
   por cuál está ordenada la lista no debería obligar a mirar el select. */
.vit-tabla-cab .asc,
.vit-tabla-cab .desc { color: var(--va2, var(--va)); }
.vit-th-texto { display: inline-flex; align-items: center; gap: 5px; }
.vit-th-texto i { font-size: 13px; }

/* La fila. Misma plantilla que el encabezado, de ahí que las columnas
   calcen. Flaca a propósito: cada píxel de alto es una fila menos en
   pantalla, y la lista existe para barrer muchas de corrido. */
.vit-tabla .vit-fila {
  display: grid;
  grid-template-columns: var(--vit-cols);
  align-items: center;
  gap: 0 10px;
  padding: 4px 10px;
  min-height: 34px;
  border-radius: 999px;
  cursor: pointer;
  /* Hereda de .vit-card, que es flex en columna con animación de
     aparición y su propio borde. Acá estorban las tres. */
  border: 0;
  overflow: visible;
  animation: none;
}
/* Intercaladas, una clara y una oscura. Con las filas tan flacas, el
   fondo parejo hacía perder el renglón al correr la vista por una
   columna; alternando, el ojo se agarra de la banda. */
.vit-tabla .vit-fila:nth-child(odd)  { background: var(--vs2); }
.vit-tabla .vit-fila:nth-child(even) { background: var(--vs); }
/* El hover, morado suave y sólido. Con var(--vag) quedaba casi del
   mismo tono que las filas claras y no se veía por cuál iba el mouse,
   que es el único trabajo que tiene que hacer un hover. Sólido y no
   translúcido por lo mismo: translúcido deja ver la banda de abajo y la
   fila clara y la oscura se marcan distinto. */
.vit-tabla .vit-fila:hover {
  background: color-mix(in srgb, var(--va) 32%, var(--vs2));
  color: var(--vtx);
  transform: none;
  box-shadow: none;
}
/* Cada celda en una línea, cortada con "…" si no cabe: que todas las
   filas midan lo mismo es lo que hace que la lista se pueda barrer.

   overflow:clip y NO hidden, que es lo normal para esto. "hidden" deja
   el elemento scrolleable por programa, así que el navegador lo trata
   como contenedor de scroll y se queda con la rueda del mouse aunque no
   haya nada que mover: con el puntero sobre una celda, la página no
   bajaba. Medido acá: sobre el relleno de la página scrolleaba, sobre
   una celda no se movía un píxel. "clip" recorta igual, deja funcionar
   el "…", y no crea contenedor de scroll — que era el último que
   quedaba después de sacar la <table> y su caja. */
.vit-tabla .vit-fila > * {
  min-width: 0;
  text-align: center;
  white-space: nowrap;
  overflow: clip;
  text-overflow: ellipsis;
  border-right: 1px solid var(--vbor);
}
.vit-tabla .vit-fila > *:last-child { border-right: 0; }
.vit-tabla .vit-td-nombre { color: var(--vtx); font-weight: 500; }
.vit-tabla .vit-td-precio { color: var(--vtx); font-weight: 600; }

/* La miniatura. position:relative NO es decorativo: _htmlFotoProducto
   mete, además de la foto, una copia con position:absolute e inset:0,
   desenfocada y agrandada, que en la tarjeta de la grilla rellena el
   marco. Sin un ancestro posicionado acá, ese absolute se colgaba de la
   fila entera y tapaba la lista completa. */
.vit-tabla-foto {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  width: 26px; height: 26px;
  border-radius: 50%;
  /* clip y no hidden, por lo mismo que las celdas: hidden se queda con
     la rueda del mouse. */
  overflow: clip;
  background: var(--vs3, var(--vs));
  color: var(--txt-tenue);
  font-size: 13px;
}
.vit-tabla-foto img { width: 100%; height: 100%; object-fit: cover; }
/* El fondo desenfocado no va: en 26 píxeles no se distingue de la foto
   que tapa, y son una imagen más por fila cuando se elige "Ver todos".
   En la grilla sí se queda, que es donde el marco es grande. */
.vit-tabla-foto .vit-foto-fondo { display: none; }

.vit-tabla .vit-stock { display: inline-flex; align-items: center; gap: 5px; }
/* Los botones, en una línea y cuadrados: redondos se confundían con la
   miniatura del principio de la fila, que sí es un círculo. */
.vit-tabla .vit-card-fila-acciones {
  display: flex; gap: 6px; margin: 0; padding: 0;
  flex-wrap: nowrap; justify-content: center;
}
/* Con .vit-card-fila-acciones adelante y no solo .vit-tabla: más abajo
   hay un .vit-card-fila-acciones .vit-btn-carrito con min-width:76px,
   que pesa lo mismo y va después, así que ganaba él. Por eso el carrito
   salía ancho en la lista y empujaba los tres puntos fuera de la
   columna — cortados contra el borde. */
.vit-tabla .vit-card-fila-acciones .vit-btn-carrito,
.vit-tabla .vit-card-fila-acciones .vit-btn-menu-card {
  flex: 0 0 auto;
  width: 26px; min-width: 0; height: 26px;
  padding: 0;
  border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
}

/* En pantalla angosta no se esconde ni se achica ninguna columna: la
   lista se pasa de ancho y se corre de lado. Antes se escondían las que
   menos decían, y con eso en un teléfono no había forma de ver ni el
   detalle ni los tres puntos — que es justo lo que se pedía poder ver. */

/* ════════════════════════════════════════════════════════════
   CARDS
   ════════════════════════════════════════════════════════════ */
.vit-card {
  background: var(--vs);
  border: 1px solid var(--vbor);
  border-radius: var(--rl);
  overflow: hidden;
  cursor: pointer;
  display: flex; flex-direction: column;
  transition: border-color 0.2s var(--ease-apple), transform 0.15s var(--ease-apple), box-shadow 0.2s var(--ease-apple);
  animation: apareceProducto 0.4s var(--ease-apple) both;
  animation-delay: min(calc(var(--i, 0) * 35ms), 350ms);
}
.vit-card:hover {
  border-color: var(--vbor2);
  transform: translateY(-3px);
  box-shadow: 0 12px 32px rgba(0,0,0,0.45), 0 0 0 1px rgba(206,147,216,0.12);
}
@keyframes apareceProducto {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}
 
.vit-card-img {
  background: var(--vs2);
  height: 130px;
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid var(--vbor);
  position: relative; overflow: hidden; flex-shrink: 0;
}
.vit-card-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;   /* antes: cover */
  padding: 8px;          /* opcional: un poco de aire para que no toque los bordes */
  box-sizing: border-box;
}
.vit-card-img i   { font-size: 40px; color: var(--txt-tenue); }

/* ── Relleno difuminado detrás de la foto ──────────────────────────
   La foto se muestra entera (object-fit: contain), así que una vertical
   deja franjas vacías a los lados y una horizontal arriba y abajo.
   Detrás va la MISMA foto, pero recortada a todo el marco y desenfocada
   —el mismo truco de los videos verticales—: el hueco se llena con los
   colores de la propia foto en vez de un gris plano.

   Son dos <img> con la misma URL: el navegador la descarga UNA vez y la
   pinta dos, así que no cuesta ancho de banda. El de atrás va con
   aria-hidden y alt vacío en el HTML, porque para un lector de pantalla
   sería la misma imagen repetida.

   Se agranda (scale) porque el desenfoque come los bordes: sin eso
   queda un halo claro pegado al marco. */
.vit-foto-fondo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  filter: blur(16px) saturate(1.3);
  transform: scale(1.3);
  opacity: 0.55;
  pointer-events: none;
  user-select: none;
}
/* Estas dos van SÍ o SÍ con la especificidad de las reglas del marco
   (".vit-card-img img" y ".vit-detalle-img img"), que traen contain y
   padding. Puestas en el bloque de arriba perdían por un pelo y el
   relleno quedaba con la misma forma que la foto, sin llenar nada:
   tiene que recortar (cover) y llegar hasta el borde (sin padding). */
.vit-card-img .vit-foto-fondo,
.vit-detalle-img .vit-foto-fondo {
  object-fit: cover;
  padding: 0;
}

/* La foto de verdad, nítida y por encima del relleno. */
.vit-foto { position: relative; z-index: 1; }

/* Las flechas para pasar fotos, las de la tarjeta y las del carrusel
   grande: el mismo botón en dos tamaños. Lo que comparten —el círculo
   de vidrio oscuro, el color, cómo responde— se escribe una vez; abajo
   cada una pone su tamaño, su sombra y dónde se apoya.

   El vidrio acá es propio y no .fx-vidrio: esa receta trae borde y filo
   de luz, que es lo que hace que un panel se vea apoyado sobre la
   página. Un botón de 26px sobre una foto con eso encima se ve sucio;
   lo único que necesita es oscurecer y desenfocar la foto justo debajo
   para que la flecha blanca se lea sobre cualquier imagen. */
.vit-card-flecha,
.vit-carrusel-flecha {
  position: absolute; top: 50%; transform: translateY(-50%);
  border-radius: 50%; border: none;
  background: rgba(20,20,20,0.55);
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
  color: #fff;
  display: flex; align-items: center; justify-content: center;
  cursor: pointer; padding: 0; line-height: 1; z-index: 2;
  transition: opacity 0.15s, background 0.15s, transform 0.15s;
}
.vit-card-flecha:hover,
.vit-carrusel-flecha:hover { background: rgba(20,20,20,0.8); transform: translateY(-50%) scale(1.08); }
.vit-card-flecha:active,
.vit-carrusel-flecha:active { transform: translateY(-50%) scale(0.94); }

/* La de la tarjeta del catálogo: chica, y escondida hasta que el mouse
   pasa por la foto. */
.vit-card-flecha {
  width: 26px; height: 26px;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  opacity: 0;
}
.vit-card-flecha i { font-size: 13px; }
.vit-card-img:hover .vit-card-flecha { opacity: 1; }
.vit-card-prev { left: 6px; }
.vit-card-next { right: 6px; }
.vit-card-dots {
  position: absolute; bottom: 6px; left: 0; right: 0;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  z-index: 2;
}
.vit-card-dot {
  width: 5px; height: 5px; border-radius: 50%;
  background: rgba(255,255,255,0.5);
  box-shadow: 0 0 2px rgba(0,0,0,0.3);
  transition: background 0.15s, transform 0.15s;
}
.vit-card-dot.activo { background: #fff; transform: scale(1.2); }

/* En touch (celular) no existe :hover — las flechas quedarían
   invisibles para siempre si dependieran solo de eso. */
@media (hover: none) {
  .vit-card-flecha { opacity: 1; }
}

.vit-badge-svc {
  position: absolute; top: 8px; left: 8px;
  font-size: 10px; font-weight: 700; letter-spacing: 0.07em; text-transform: uppercase;
  padding: 3px 8px; border-radius: 12px;
  background: var(--vag2); border: 1px solid var(--vbor2); color: var(--va);
}
 
.vit-card-body { padding: 12px; display: flex; flex-direction: column; gap: 4px; flex: 1; }
.vit-card-tipo { font-size: var(--fs-2xs); font-weight: 500; font-style: italic; text-transform: uppercase; letter-spacing: 0.06em; color: var(--txt-sub); }
/* La categoría es la línea grande de la tarjeta: dice de qué se trata el
   producto ("USB-C a LIGHTNING"), que es lo que el cliente busca. La
   marca y el modelo van chicos al final, como dato. */
.vit-card-categoria { font-size: 14px; font-weight: 500; color: var(--vtx); line-height: 1.35; }
.vit-card-nombre { font-size: 11px; color: var(--txt-sub); }
.vit-card-descripcion {
  font-size: 11px;
  color: var(--txt-sub);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Se deja envolver en varias líneas en vez de cortarse con "…": la lista
   de modelos compatibles es el dato por el que se mira esta línea, y
   media lista no sirve para decidir. */
.vit-card-compat { font-size: 11px; color: var(--txt-sub); line-height: 1.35; overflow-wrap: anywhere; }
 
.vit-card-footer {
  display: flex; align-items: center; justify-content: space-between;
  /* Separación entre el precio y el stock, y permiso para que el stock
     baje de línea. Con space-between y sin gap, en una tarjeta angosta
     (dos por fila en el teléfono) los dos textos se estiran hasta
     tocarse: quedaba "$5.000• 24 en stock" pegado, como si fuera una
     sola cosa. */
  flex-wrap: wrap;
  gap: 2px 10px;
  /* margin-top:auto y no un valor fijo: empuja el precio —y con él el
     stock, el reparto por local y el botón— al fondo de la tarjeta.

     Las tarjetas de una misma fila ya medían todas lo mismo (la grilla
     las estira), pero el contenido se apilaba desde arriba, así que a
     una con una línea de más —un "Compatible: IPHONE 16" que las
     vecinas no tienen— el precio y el botón le quedaban más abajo que
     a las de al lado. Con el margen automático, lo de arriba crece
     hacia abajo y lo de abajo se queda clavado al piso: los precios y
     los botones de una fila quedan siempre a la misma altura.

     El aire de 8px que había acá lo sigue dando el padding-top, así que
     la separación con el texto no cambia. */
  margin-top: auto; padding-top: 8px;
  border-top: 1px solid var(--vbor);
}
.vit-precio        { font-size: 15px; font-weight: 700; color: var(--va); }
.vit-precio-gratis { font-size: 12px; color: var(--txt-sub); }
 
.vit-stock { display: flex; align-items: center; gap: 4px; }
.vit-dot   { width: 6px; height: 6px; border-radius: 50%; flex-shrink: 0; }
.vit-dot-in  { background: var(--vgrn); }
.vit-dot-out { background: var(--vred); }
.vit-dot-svc { background: var(--vgrn); }
.vit-stock-text-in  { font-size: 10px; color: var(--vgrn); }
.vit-stock-text-out { font-size: 10px; color: var(--vred); }
.vit-stock-text-svc { font-size: 10px; color: var(--vgrn); }
 
.vit-btn-ver {
  width: 100%; margin-top: 8px; height: 33px;
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--txt-sub); font-size: 12px;
  cursor: pointer; transition: all 0.15s var(--ease-apple);
}
.vit-btn-ver:hover { background: var(--vag); border-color: var(--vbor2); color: var(--va); }
 
.vit-btn-carrito {
  width: 100%; margin-top: 6px; height: 33px;
  background: var(--vag);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--va); font-size: 12px; font-weight: 600;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 6px;
  transition: all 0.15s var(--ease-apple);
}
.vit-btn-carrito:hover { background: var(--vag2); border-color: var(--va); }
 
/* ════════════════════════════════════════════════════════════
   MODAL DETALLE
   ════════════════════════════════════════════════════════════ */
 
.vit-detalle-modal {
  background: var(--vs2);
  border: 1px solid var(--vbor2);
  border-radius: var(--rxl);
  width: 100%; max-width: 500px; max-height: 90vh;
  overflow-y: auto; position: relative;
  overscroll-behavior: contain;
  box-shadow: 0 32px 80px rgba(0,0,0,0.8);
  animation: asomarse 0.2s var(--ease-apple);
}
.vit-detalle-img {
  background: var(--vs3); height: 230px;
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid var(--vbor); flex-shrink: 0;
  /* overflow: el relleno difuminado va agrandado y se saldría del marco
     (la grilla ya lo tenía). */
  position: relative; overflow: hidden;
}
.vit-detalle-img img {
  width: 100%;
  height: 100%;
  object-fit: contain;   /* antes: cover */
  padding: 12px;
  box-sizing: border-box;
}
.vit-detalle-img i   { font-size: 64px; color: var(--txt-tenue); }

/* La del carrusel grande: más grande, y siempre a la vista — ahí la foto
   es el contenido, no un adorno de una tarjeta. */
.vit-carrusel-flecha {
  width: 34px; height: 34px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.3);
}
.vit-carrusel-flecha i { font-size: 17px; }
.vit-carrusel-prev { left: 10px; }
.vit-carrusel-next { right: 10px; }
.vit-carrusel-dots {
  position: absolute; bottom: 10px; left: 0; right: 0;
  display: flex; align-items: center; justify-content: center; gap: 6px;
}
.vit-carrusel-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: rgba(255,255,255,0.5); cursor: pointer;
  box-shadow: 0 0 2px rgba(0,0,0,0.3);
  transition: background 0.15s, transform 0.15s;
}
.vit-carrusel-dot.activo { background: #fff; transform: scale(1.2); }
 
.vit-detalle-body { padding: 24px; display: flex; flex-direction: column; gap: 10px; }
.vit-detalle-tipo   { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; color: var(--txt-sub); }
.vit-detalle-nombre { font-size: 20px; font-weight: 700; color: var(--vtx); line-height: 1.3; }
.vit-detalle-marca  { font-size: 14px; color: var(--vtx2); }
.vit-detalle-desc   { font-size: 14px; color: var(--vtx2); line-height: 1.65; padding: 12px 0; border-top: 1px solid var(--vbor); border-bottom: 1px solid var(--vbor); }
.vit-detalle-compat { font-size: 13px; color: var(--txt-sub); }
.vit-detalle-compat strong { color: var(--vtx2); }
.vit-detalle-footer { display: flex; align-items: center; justify-content: space-between; }
.vit-detalle-precio { font-size: 28px; font-weight: 800; color: var(--va); letter-spacing: -0.5px; }
.vit-detalle-stock  { display: flex; align-items: center; gap: 7px; font-size: 14px; }

/* ── Reparto del stock local por local ──
   Va tanto en la ficha del producto como bajo el campo de stock del
   editor, así que el ancho lo pone quien la contiene. Cada local es una
   pastilla "nombre + número"; el que está en cero se apaga, para que de
   un vistazo se lea dónde HAY sin tener que leer los números. */
.vit-stock-locales {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px;
  margin-top: 10px;
}
.vit-stock-locales[hidden] { display: none; }
.vit-stock-locales-titulo {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--txt-sub, rgba(255,255,255,.45));
  margin-right: 2px;
}
.vit-stock-local {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  padding: 3px 8px;
  border-radius: 999px;
  border: 1px solid var(--vbor, rgba(255,255,255,.12));
  background: var(--vag2, rgba(255,255,255,.04));
  font-size: 11px;
  line-height: 1.4;
}
.vit-stock-local-nombre { color: var(--txt-sub, rgba(255,255,255,.6)); }
.vit-stock-local-num    { font-weight: 700; font-variant-numeric: tabular-nums; }
/* Cero no es un número más: es "acá no queda". */
.vit-stock-local-vacio  { opacity: .45; }
/* En la tarjeta de la grilla la misma línea va más chica y pegada al
   pie: hay hasta 60 en pantalla y no puede competir con el precio. */
.vit-stock-locales-mini {
  margin-top: 6px;
  gap: 4px;
}
.vit-stock-locales-mini .vit-stock-local {
  padding: 2px 6px;
  font-size: 10px;
  gap: 4px;
}
/* El total cierra la fila y se separa del reparto con el borde lila. */
.vit-stock-local-total {
  border-color: var(--color-accent, #ce93d8);
}
.vit-detalle-acciones { display: flex; flex-direction: column; gap: 8px; }

/* ── Modo página (fixhubtec.com/producto/{codigo}) ──────────────
   Mismo .vit-detalle-modal de siempre (el modal viejo ya no se usa,
   ver _renderPaginaProducto en vitrina.js), pero sin el tratamiento de
   "caja flotante angosta": ocupa el ancho disponible de .vitp-body
   (que ya viene con overflow:hidden, así que el scroll vive acá
   adentro), con más aire para la foto y el texto. */
.vit-detalle-pagina {
  max-width: 900px;
  width: 100%;
  height: 100%;
  margin: 0 auto;
  border: none;
  border-left: 1px solid var(--vbor2);
  border-right: 1px solid var(--vbor2);
  border-radius: 0;
  box-shadow: none;
  animation: none;
}
.vit-detalle-pagina .vit-detalle-img { height: 380px; }
.vit-detalle-pagina .vit-detalle-body { padding: 32px 40px; }
.vit-detalle-pagina .vit-detalle-nombre { font-size: 24px; }

/* ── Editor de producto como página ────────────────────────────────
   El encuadre lo pone .fx-form-pagina/.fx-form-cols (admin.css), el mismo
   del alta pública de empresa: no tiene sentido que dos formularios
   largos de pantalla completa se vean distinto. Acá solo van las tres
   piezas que esa página no tiene: la fila de la primera sección, con
   Guardar y Limpiar al lado del título. */

/* Título de sección a la izquierda, Guardar y Limpiar a la derecha.
   El <h3> lo pinta .admin-form h3 (admin.css); acá solo se lo reparte
   con los botones. */
.ed-prod-seccion {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
}
.ed-prod-seccion-btns {
  display: flex;
  align-items: center;
  gap: 8px;
}
/* .admin-form h3 trae un margin-bottom pensado para cuando el título va
   solo en su línea; con los botones al lado el bloque ya separa. */
.ed-prod-seccion h3 { margin-bottom: 0; }

/* Limpiar vacía el formulario entero, así que va en rojo (btn-rojo-bg,
   utilidades.css) — pero más liviano que Guardar: al lado de la acción
   de la pantalla, dos botones gritando compiten.

   Ojo: .btn-sm sola no trae fondo, solo forma y tamaño; sin el
   modificador de color queda con el fondo por defecto del navegador,
   que sobre esta pantalla oscura es un rectángulo blanco. */
.ed-prod-limpiar { font-weight: 400; }

/* ── Cabeza del formulario: campos | fotos ─────────────────────────
   La columna de las fotos se estira hasta donde llega la de los campos
   (align-items por defecto en grid es stretch), así que el hueco de la
   galería crece con ellos y la foto se ve de verdad, en vez de una
   miniatura suelta al final del formulario. */
.ed-prod-cabeza {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 12px;
}
.ed-prod-campos {
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-width: 0;
}

.ed-prod-fotos { min-width: 0; }
/* El hueco de las fotos ocupa lo que sobra bajo su etiqueta y el
   selector de archivo: por eso el flex:1 y el min-height, que es el
   piso cuando el formulario todavía está vacío. */
.ed-prod-fotos #np-imagen-galeria {
  flex: 1;
  min-height: 120px;
  margin-top: 8px;
  display: flex;
  align-items: stretch;
  gap: 8px;
  padding: 10px;
  background: var(--vs3);
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  /* En una sola línea, desplazándose de lado si hay varias: partiendo en
     varias filas, cada foto vuelve a ser una miniatura chica y se pierde
     justamente el alto que se ganó al ponerlas acá. */
  flex-wrap: nowrap;
  overflow-x: auto;
  overflow-y: hidden;
  overscroll-behavior-x: contain;
}
/* Cuadradas y tan altas como la caja, para aprovechar el espacio que
   dejan los cuatro campos de al lado.

   La foto va en posición absoluta a propósito: dejándola en el flujo,
   su tamaño natural (una imagen de producto, cientos de píxeles) pasa a
   ser el alto mínimo de la miniatura, y entonces era la foto la que
   estiraba la fila en vez de encogerse a ella. Fuera del flujo no
   aporta alto, así que la fila la miden los campos, y recién ahí el
   height:100% tiene contra qué resolverse. */
.ed-prod-fotos .np-img-item {
  height: 100%;
  width: auto;
  aspect-ratio: 1;
  flex: 0 0 auto;
}
.ed-prod-fotos .np-img-item img {
  position: absolute;
  inset: 0;
}

@media (max-width: 640px) {
  /* Una debajo de la otra: en un teléfono, media pantalla para cada una
     deja los dos lados inservibles. */
  .ed-prod-cabeza { grid-template-columns: 1fr; }
}

/* ── Repuestos ─────────────────────────────────────────────────────
   La lista y el formulario reusan el armazón de página-formulario
   (.fx-form-*) y la tarjeta de .admin-form; acá solo va lo propio: las
   fichas de la lista y las piezas de cada repuesto. */
.rep-conteo { color: var(--txt-tenue); }
.rep-conteo:not(:empty)::before { content: ' · '; }

.rep-lista { display: flex; flex-direction: column; gap: 10px; }

/* ── La grilla ──────────────────────────────────────────────────────
   Misma medida que la del catálogo: una bodega se mira igual que una
   vitrina, de un vistazo y por la foto. La tarjeta es la MISMA de la
   lista (.rep-card) — lo único que cambia es el contenedor, así que no
   hay dos tarjetas que mantener en paralelo. */
.rep-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(190px, 100%), 1fr));
  gap: 14px;
  align-items: start;
}
/* En grilla la tarjeta se da vuelta: la foto arriba y grande, el texto
   abajo. Es el cambio que hace que valga la pena ver fotos. */
.rep-grid .rep-card { flex-direction: column; gap: 10px; padding: 10px; }
.rep-grid .rep-card-foto { width: 100%; height: 140px; font-size: 34px; }
.rep-grid .rep-card-foto img { object-fit: contain; padding: 6px; box-sizing: border-box; }

/* ── La barra de arriba: cómo ver y en qué orden ── */
.rep-barra {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  margin: 2px 0 12px;
}
.rep-vista { display: inline-flex; gap: 2px; padding: 2px;
  background: var(--vs3); border: 1px solid var(--vbor2); border-radius: 999px; }
.rep-vista-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 26px;
  border: 0; border-radius: 999px;
  background: transparent; color: var(--txt-sub);
  font-size: 15px; cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple);
}
.rep-vista-btn:hover { color: var(--txt-titulo); }
.rep-vista-btn.activo { background: var(--va); color: #fff; }
/* El orden a la derecha del todo, separado de la elección de vista. */
.rep-barra .vit-sort-select { margin-left: auto; }

/* ── Los filtros marcados, como chips ── */
.rep-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.rep-chips.oculto { display: none; }
.rep-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--va) 45%, transparent);
  background: color-mix(in srgb, var(--va) 14%, transparent);
  color: var(--txt-titulo);
  font: inherit; font-size: var(--fs-xs); font-weight: 600;
  cursor: pointer;
}
.rep-chip:hover { border-color: var(--va); }
.rep-chip i { font-size: 13px; opacity: 0.7; }

/* Una sección del sidebar sin nada que ofrecer todavía. */
.rep-sb-vacio { padding: 6px 10px; font-size: var(--fs-xs); color: var(--txt-tenue); }
#vit-sidebar-repuestos .vit-sb-section.oculto { display: none; }

.rep-vacio {
  padding: 40px 20px;
  text-align: center;
  color: var(--txt-sub);
  font-size: var(--fs-md);
  line-height: 1.6;
}

.rep-card {
  display: flex;
  gap: 14px;
  background: var(--vs);
  border: 1px solid var(--vbor2);
  border-radius: var(--rl);
  padding: 12px;
  cursor: pointer;
  transition: border-color 0.2s var(--ease-apple);
}
.rep-card:hover { border-color: var(--va); }

.rep-card-foto {
  width: 84px;
  height: 84px;
  flex-shrink: 0;
  border-radius: var(--r);
  background: var(--vs3);
  border: 1px solid var(--vbor);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--txt-tenue);
  font-size: 26px;
  overflow: hidden;
}
.rep-card-foto img { width: 100%; height: 100%; object-fit: cover; }

.rep-card-cuerpo { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.rep-card-titulo { font-size: var(--fs-lg); font-weight: 700; color: var(--txt-titulo); }
.rep-card-estado { font-size: var(--fs-sm); color: var(--txt-cuerpo); }
.rep-card-pie {
  display: flex; flex-wrap: wrap; gap: 4px 14px;
  font-size: var(--fs-xs); color: var(--txt-sub);
}
.rep-card-pie span { display: inline-flex; align-items: center; gap: 4px; }

/* Las piezas, como etiquetas de colores: de un vistazo se ve qué sirve
   todavía y qué ya se sacó, que es lo que uno mira al buscar. */
.rep-piezas { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 2px; }
.rep-pieza {
  font-size: var(--fs-2xs);
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 20px;
  border: 1px solid;
}
.rep-pieza-sirve { color: var(--vgrn); border-color: color-mix(in srgb, var(--vgrn) 45%, transparent); }
.rep-pieza-usado { color: var(--va);   border-color: color-mix(in srgb, var(--va) 45%, transparent); }
.rep-pieza-malo  { color: var(--vred); border-color: color-mix(in srgb, var(--vred) 45%, transparent);
                   text-decoration: line-through; }

/* ── Piezas dentro del formulario ── */
.rep-componentes { display: flex; flex-direction: column; gap: 8px; }
.rep-sin-componentes { font-size: var(--fs-sm); color: var(--txt-tenue); padding: 6px 0; }

.rep-componente {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 130px minmax(0, 1.2fr) auto;
  align-items: center;
  gap: 8px;
}
.rep-componente-nombre { font-size: var(--fs-md); color: var(--txt-titulo); font-weight: 600; }

/* Los atajos: un toque agrega la pieza en vez de escribirla. */
.rep-sugeridos { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; }
.rep-sugerido {
  background: none;
  border: 1px dashed var(--vbor2);
  border-radius: 20px;
  color: var(--txt-sub);
  font-size: var(--fs-xs);
  padding: 4px 10px;
  cursor: pointer;
  transition: color 0.15s var(--ease-apple), border-color 0.15s var(--ease-apple);
}
.rep-sugerido:hover { color: var(--txt-titulo); border-color: var(--va); }

.rep-agregar-pieza { display: flex; gap: 8px; margin-top: 10px; }
.rep-agregar-pieza input { flex: 1; min-width: 0; font-size: var(--fs-input); }

.rep-pie-acciones { display: flex; justify-content: flex-end; margin-top: 18px; }

.ed-prod-fotos #rep-galeria {
  flex: 1;
  min-height: 120px;
  margin-top: 8px;
  display: flex;
  flex-wrap: wrap;
  align-content: flex-start;
  gap: 8px;
  padding: 10px;
  background: var(--vs3);
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  overflow-y: auto;
}
.ed-prod-fotos #rep-galeria .np-img-item { width: 104px; height: 104px; }

@media (max-width: 640px) {
  /* En un teléfono las cuatro columnas de una pieza dejan el nombre en
     dos letras: se apilan nombre+estado arriba y la nota abajo. */
  .rep-componente { grid-template-columns: minmax(0, 1fr) auto; }
  .rep-componente-nota { grid-column: 1 / -1; }
  .rep-card-foto { width: 64px; height: 64px; }
}

/* .form-row nunca envuelve (utilidades.css). En escritorio la fila de
   tres —Stock / Proveedor / Fecha de compra— entra bien en los 720px de
   la columna, pero en un teléfono deja cada campo en ~110px, y el
   selector de fecha ni siquiera cabe. Se permite el salto solo acá
   dentro: tocar .form-row en general afectaría todos los formularios de
   la aplicación. */
@media (max-width: 640px) {
  #vitp-editor-producto .form-row { flex-wrap: wrap; }
  #vitp-editor-producto .form-group { flex: 1 1 150px; min-width: 0; }
}

.vit-detalle-no-encontrado {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  padding: 80px 24px; text-align: center;
}
.vit-detalle-no-encontrado.oculto { display: none; }
.vit-detalle-no-encontrado i { font-size: 48px; color: var(--txt-tenue); }
.vit-detalle-no-encontrado p { font-size: 16px; color: var(--vtx2); margin: 0; }

.vit-btn-detalle-carrito {
  height: 46px;
  background: var(--vag2);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--va); font-size: 15px; font-weight: 700;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center; gap: 8px;
  transition: all 0.2s var(--ease-apple);
}
.vit-btn-detalle-carrito:hover { background: rgba(206,147,216,0.35); border-color: var(--va); }
 
.vit-btn-detalle-cerrar {
  position: absolute; top: 14px; right: 14px;
  width: 34px; height: 34px;
  background: rgba(0,0,0,0.5);
  border: 1px solid var(--vbor);
  border-radius: 50%; color: var(--vtx2);
  font-size: 16px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: all 0.2s var(--ease-apple);
}
.vit-btn-detalle-cerrar:hover { background: rgba(0,0,0,0.8); color: var(--vtx); }
 
/* ════════════════════════════════════════════════════════════
   SUGERENCIAS
   ════════════════════════════════════════════════════════════
   La segunda tanda: lo demás que sirve para el mismo equipo que se
   buscó. Las tarjetas son exactamente las del catálogo — lo único que
   se dibuja acá es la línea que las separa de los resultados, y tiene
   que SEPARAR de verdad: si se leyeran como una continuación de la
   grilla, alguien podría creer que una lámina es lo que buscó.
   De ahí la línea de arriba y el aire de 34px. */
.vit-sugerencias {
  margin-top: 34px;
  padding-top: 26px;
  border-top: 1px solid var(--vbor);
  animation: surgir 0.3s var(--ease-apple) both;
}

.vit-sug-cab {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-bottom: 16px;
}

.vit-sug-titulo {
  display: flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  color: var(--txt-titulo);
}

.vit-sug-titulo i { color: var(--va); font-size: 17px; }

/* El modelo va aparte y más apagado: el título dice qué es esta
   sección, y esto para qué equipo — dos datos distintos, no un título
   largo. */
.vit-sug-para {
  font-size: 13px;
  color: var(--txt-sub);
}

/* ── Las pastillas: qué tipo de sugerencia se está viendo ──
   Las mismas de "Así de fácil empiezas" en la portada (.pos-pestana en
   portada-pos.css), con los colores de la vitrina. Se repiten acá en
   vez de compartir la clase porque esa vive encerrada en #home-saas y
   sacarla de ahí le cambiaría el peso a reglas que hoy funcionan. */
.vit-sug-pastillas {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 18px;
}

.vit-sug-pastilla {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 8px 14px;
  border-radius: 999px;
  border: 1px solid var(--vbor);
  background: var(--vs2);
  color: var(--txt-sub);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  transition: color 0.15s var(--ease-apple), border-color 0.15s var(--ease-apple),
              background 0.15s var(--ease-apple);
}

.vit-sug-pastilla i { font-size: 15px; }
.vit-sug-pastilla:hover { color: var(--txt-titulo); border-color: var(--vbor2); }

.vit-sug-pastilla.activa {
  color: var(--txt-titulo);
  background: rgba(206,147,216,0.12);
  border-color: rgba(206,147,216,0.45);
}

.vit-sug-pastilla:focus-visible { outline: 2px solid var(--va); outline-offset: 2px; }

/* Cuántos hay de ese tipo. Va en su propia cápsula y no entre
   paréntesis: es un número, no parte del nombre, y así se distingue de
   un "CARCASA 360" que sí lleva número en el nombre. */
.vit-sug-cuenta {
  min-width: 18px;
  padding: 1px 5px;
  border-radius: 999px;
  background: var(--vag);
  color: var(--txt-sub);
  font-size: 11px;
  font-weight: 600;
  text-align: center;
}

.vit-sug-pastilla.activa .vit-sug-cuenta {
  background: rgba(206,147,216,0.18);
  color: var(--txt-titulo);
}

@media (max-width: 700px) {
  .vit-sugerencias { margin-top: 26px; padding-top: 20px; }
  /* En el teléfono las pastillas no se envuelven en cuatro líneas: se
     corren de lado, como una barra de pestañas. El respiro de los
     costados es el mismo del catálogo (12px), así que la primera queda
     alineada con las tarjetas y la última no se corta contra el borde. */
  .vit-sug-pastillas {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    margin-left: -12px;
    margin-right: -12px;
    padding: 0 12px 2px;
  }
  .vit-sug-pastillas::-webkit-scrollbar { display: none; }
  .vit-sug-pastilla { flex: 0 0 auto; }
}

/* ════════════════════════════════════════════════════════════
   ESTADOS
   ════════════════════════════════════════════════════════════ */
.vit-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 80px 20px; color: var(--txt-sub); text-align: center;
  animation: surgir 0.3s var(--ease-apple) both;
}
.vit-empty i { font-size: 52px; }
.vit-empty p { font-size: 15px; }
 
.vit-loading {
  display: flex; align-items: center; justify-content: center;
  gap: 12px; padding: 80px; color: var(--txt-sub); font-size: 14px;
  animation: surgir 0.2s var(--ease-apple) both;
}

/* Mientras se está pidiendo una página/filtro nuevo y YA hay productos
   dibujados, se dejan puestos (en vez de borrarlos) y solo se atenúan
   — así el alto de la grilla no cambia y no "salta" la página. Ver
   _mostrarLoading() en vitrina.js. */
.vit-grid-wrap.vit-grid-cargando .vit-grid,
.vit-grid-wrap.vit-grid-cargando .vit-paginacion {
  opacity: 0.4;
  pointer-events: none;
  transition: opacity 0.15s var(--ease-apple);
}
 
/* Dos productos por fila, pero SOLO en lo angosto de verdad. La regla
   normal de la grilla es auto-fill con un mínimo de 175px, y en un
   teléfono de 360px esa cuenta da UNA sola columna: un catálogo de una
   tarjeta por pantalla obliga a recorrer kilómetros para ver seis
   productos. minmax(0, 1fr) es lo que deja que la tarjeta se achique en
   vez de desbordar.

   El corte está en 520px y no en los 700px del resto del responsive,
   que es donde estaba antes. Con 700, una ventana de 699px —el panel
   del navegador al costado del chat, por ejemplo— mostraba DOS tarjetas
   de 327px cada una, el doble de anchas de lo necesario, cuando ahí
   entran tres de 212px holgadas. De 521px para arriba manda otra vez el
   auto-fill, que suma columnas a medida que hay lugar en vez de quedarse
   clavado en dos. */
@container grillacatalogo (max-width: 560px) {
  /* Dos, fijas. Es el piso: por angosto que sea el hueco, una sola
     tarjeta a lo ancho desperdicia la pantalla y obliga a scrollear por
     cada producto. Dos de 174px se leen bien. */
  .vit-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
}

@container grillacatalogo (min-width: 561px) and (max-width: 760px) {
  /* La franja de en medio: un hueco angosto que no es un teléfono —el
     panel del navegador al lado del chat, media pantalla, una tablet de
     pie. Acá los márgenes son chicos, así que una tarjeta aguanta ser
     un poco más angosta sin verse apretada, y con 160 de mínimo entran
     tres donde con 175 entraban dos del doble de ancho. */
  .vit-grid { grid-template-columns: repeat(auto-fill, minmax(min(160px, 100%), 1fr)); }
}

/* ════════════════════════════════════════════════════════════
   RESPONSIVE
   ════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  .vit-nav { padding: 0 14px; }

  /* La barra en el teléfono: mismo reparto que en el escritorio, solo
     más apretada. El borde se alinea con el de las tarjetas (12px,
     igual que #vit-grid-wrap) para que no quede un escaloncito contra
     la grilla. */
  .vit-filtros-bar-top { margin: 10px 0 12px; }
  .vit-barra-pastilla,
  .vit-filtros-bar-top .reg-resumen-caja-bar:not(.oculto) { padding: 8px 12px; gap: 8px 10px; }

  /* Con id, no con clase: el elemento es #vit-grid-wrap y la regla de
     arriba (padding 6px 36px) le gana a cualquier selector de clase por
     especificidad. Escrita como clase, esto no hacía nada y el teléfono
     se quedaba con los 36px de margen a cada lado — que en una pantalla
     de 360px es una quinta parte del ancho tirada a la basura. */
  #vit-grid-wrap { padding: 6px 12px 20px; }
  /* La barra sigue a la grilla: si una se angosta, la otra también, o
     dejan de estar alineadas. */
  .vit-main > .vit-filtros-bar-top { padding-left: 12px; padding-right: 12px; }
}

/* ── Navbar en 2 filas para pantallas de celular ──
   La fila única (☰+logo | Agregar producto/Servicio técnico+Buscador+
   Carrito | Notas/Pendientes/Impresos/WhatsApp/Usuario) da por hecho
   que todo entra en una línea — en un celular no entra ni cerca. Sin
   esto, .vit-nav-group-center (flex:1, centrado) se achicaba a 0 de
   ancho y sus hijos (buscador, carrito), al seguir centrados alrededor
   de ESE punto cero, terminaban superpuestos sobre el ☰/logo en vez de
   simplemente no entrar.
   Acá el ☰/logo y los íconos de Notas/Pendientes/Impresos/WhatsApp/
   Usuario (ambos angostos, con las excepciones de abajo puestas todas
   en solo-ícono) comparten la primera fila — entran de sobra, con
   margin-left:auto empujando el segundo grupo al extremo derecho vía
   "order" (en el HTML el grupo derecho viene DESPUÉS del buscador/
   carrito, pero acá se reordena para que aparezca ANTES en pantalla).
   El buscador+carrito, que sí necesitan ancho de verdad, quedan solos
   en la segunda fila completa. */
@media (max-width: 640px) {
  .vit-nav-right { flex-wrap: wrap; row-gap: 6px; }
  .vit-nav-group-left  { flex-basis: auto; order: 1; }
  .vit-nav-group-right { flex-basis: auto; order: 2; margin-left: auto; justify-content: flex-end; }
  .vit-nav-group-center { flex-basis: 100%; order: 3; }

  .vit-nav-group-center > .vit-search-wrap {
    flex: 1;
    min-width: 0;
    max-width: none;
  }

  /* Usuario/Login normalmente se ven con texto completo (ver la
     "Excepción" más arriba en este archivo) — pero con 4 íconos más al
     lado en la misma fila, un nombre largo desborda igual que pasaba
     con el buscador. Solo ícono acá; el nombre completo sigue estando
     en el dropdown de todos modos. */
  .vit-nav-right .vit-btn-login,
  .vit-nav-right .vit-usuario-info {
    width: 30px;
    gap: 0;
    padding: 0;
  }
  .vit-nav-right .vit-btn-login span:not(.vit-carrito-badge-nav),
  .vit-nav-right .vit-usuario-info strong,
  .vit-nav-right .vit-usuario-info .ti-chevron-down {
    display: none;
  }

  /* "Servicio técnico" (visitante sin sesión) — mismo criterio: el
     texto ya no entra con todo lo demás en la fila. */
  .vit-nav-right .vit-btn-agenda-nav-texto {
    width: 30px;
    gap: 0;
    padding: 0;
  }
  .vit-nav-right .vit-btn-agenda-nav-texto span:not(.vit-carrito-badge-nav) {
    display: none;
  }
}

 
/* ════════════════════════════════════════════════════════════
   PAGINACIÓN
   ════════════════════════════════════════════════════════════ */
.vit-paginacion {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 28px 20px 10px;
  flex-wrap: wrap;
}
 
.vit-pag-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  height: 36px;
  padding: 0 16px;
  background: var(--vag);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s var(--ease-apple);
}
.vit-pag-btn:hover:not(:disabled) { background: var(--vag2); color: var(--vtx); }
.vit-pag-btn:disabled { opacity: 0.35; cursor: not-allowed; }
 
.vit-pag-num {
  width: 36px;
  height: 36px;
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 13px;
  cursor: pointer;
  transition: all 0.15s var(--ease-apple);
}
.vit-pag-num:hover { background: var(--vag); border-color: var(--vbor2); color: var(--vtx); }
.vit-pag-num.activa {
  background: var(--vag2);
  border-color: var(--vbor2);
  color: var(--vtx);
  font-weight: 700;
}
 
.vit-pag-dots { font-size: 13px; color: var(--txt-sub); padding: 0 4px; }
 
/* ════════════════════════════════════════════════════════════
   FOOTER
   ════════════════════════════════════════════════════════════ */

 
 

/* Antes vivía sobre el banner del Home (sel-emp-hero-pais en
   selector-empresas.css) — se movió acá para que se vea en cualquier
   página del sitio, no solo al entrar (mismo motivo que las reseñas
   de Google, ver arriba en el footer). Franja de ancho completo al
   pie de las 3 columnas, con cada bandera en un extremo. */
/* ── Seguimiento, dentro de su desplegable ────────────────────────────
   Encabezado propio y, debajo, el buscador prestado del dropdown de
   Repara aquí (ver abrirSeguimientoDesdeAcceso en vitrina.js). Ese cuerpo
   ya trae su alto máximo y su scroll de origen, así que acá no hay que
   agregarle nada: es un desplegable dentro de otro desplegable.

   Es más ancho que los otros tres accesos porque adentro va un buscador
   con resultados y una línea de tiempo, no dos renglones de texto. */
.vit-acceso-menu-seguimiento {
  min-width: 380px;
  max-width: min(380px, calc(100vw - 24px));
  padding: 10px;
  /* El acceso que abre este menú centra su texto y el buscador prestado
     lo heredaba: las etiquetas RUT y CÓDIGO DE COMPROBANTE salían
     centradas sobre campos alineados a la izquierda. La de RUT parecía
     bien solo porque su texto llenaba el ancho. */
  text-align: left;
}
.vit-seg-cabecera {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding: 2px 2px 0;
}
.vit-seg-limpiar {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 9px;
  background: transparent;
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  color: var(--txt-sub);
  font-family: inherit;
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
  cursor: pointer;
  transition: color 0.15s var(--ease-apple), border-color 0.15s var(--ease-apple);
}
.vit-seg-limpiar:hover { color: var(--color-rojo-suave); border-color: var(--color-rojo-suave); }

/* ── Accesos rápidos del Home, arriba del banner ─────────────────
   Cuatro columnas con el ícono arriba y separadores finos entre ellas,
   el mismo formato que ya se usa en tiendas del rubro. Los mismos cuatro
   están en el pie: acá para el que recién entra, allá para el que llegó
   hasta abajo.

   Dos de ellos abren un menú en vez de navegar, porque tienen dos
   destinos cada uno. */
.vit-accesos {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  border-bottom: 1px solid var(--vbor);
  margin-bottom: 4px;
}
.vit-acceso-wrap { position: relative; display: flex; }
.vit-acceso {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Centrado vertical: el alto de la fila lo fija "Términos y privacidad",
     que cae en dos renglones en una columna de ~160px. Sin esto los otros
     tres apoyaban su contenido arriba y les quedaban 20px muertos abajo —
     se veían pegados al borde de arriba y sueltos abajo. */
  justify-content: center;
  /* Compacta a propósito: la franja es lo primero arriba del banner y no
     debe robarle protagonismo. Los 20px que se recuperaron al centrar
     pagan casi todo este aire entre el ícono y el texto. */
  gap: 8px;
  padding: 5px 10px;
  background: transparent;
  border: none;
  /* Mismo nivel de cuerpo que el contenido de sus menús, y sin negrita:
     son rótulos de navegación, no titulares. En 100% y 700 competían con
     el banner que tienen justo debajo. El lila de .abierto sigue siendo
     lo que marca cuál está desplegado. */
  color: var(--txt-cuerpo);
  font-family: inherit;
  font-size: var(--fs-lg);
  font-weight: 400;
  text-align: center;
  cursor: pointer;
  position: relative;
  transition: background 0.18s var(--ease-apple), color 0.18s var(--ease-apple);
}
/* La línea divisoria va en el borde izquierdo de cada uno menos el
   primero. Se apoya en el wrapper cuando lo hay, así los cuatro quedan
   separados igual tengan menú o no. */
.vit-accesos > *:not(:first-child) .vit-acceso::before,
.vit-accesos > .vit-acceso:not(:first-child)::before {
  content: '';
  position: absolute;
  left: 0;
  top: 22%;
  height: 56%;
  width: 1px;
  background: var(--vbor2);
}
.vit-acceso:hover { background: rgba(255,255,255,0.03); }
/* Mientras su menú está abierto, el acceso queda marcado. No es adorno:
   con cuatro menús que se abren en el mismo lugar, es lo que dice cuál de
   ellos estás mirando. Sube de nivel en la misma rampa —a blanco y
   negrita— en vez de cambiar de color: el lila ya es el de los íconos y
   el del acento, y ahí no distinguía "abierto" de "decorativo". */
.vit-acceso.abierto { color: var(--txt-titulo); font-weight: 700; background: rgba(255,255,255,0.04); }

/* Los cuatro entran escalonados al cargar el Home. Va en el contenedor y
   no en cada uno para que el orden salga del propio marcado: si mañana se
   agrega un quinto acceso, entra solo en su turno.
   "backwards" mantiene el estado inicial durante el retraso — sin eso los
   cuatro se ven un instante antes de empezar a animarse. */
@keyframes accesoEntrar {
  from { opacity: 0; transform: translateY(7px); }
  to   { opacity: 1; transform: translateY(0); }
}
.vit-accesos > * { animation: accesoEntrar 0.38s var(--ease-apple) backwards; }
.vit-accesos > *:nth-child(1) { animation-delay: 0.05s; }
.vit-accesos > *:nth-child(2) { animation-delay: 0.11s; }
.vit-accesos > *:nth-child(3) { animation-delay: 0.17s; }
.vit-accesos > *:nth-child(4) { animation-delay: 0.23s; }
.vit-accesos > *:nth-child(5) { animation-delay: 0.29s; }
.vit-acceso svg {
  width: 22px;
  height: 22px;
  stroke: var(--va);
  fill: none;
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform 0.25s var(--ease-apple);
}
.vit-acceso:hover svg { transform: translateY(-3px) scale(1.06); }

/* El menú de los que tienen dos destinos. Mismo fondo y borde que
   cualquier desplegable de la vitrina. */
.vit-acceso-menu {
  position: absolute;
  top: calc(100% - 6px);
  /* El menú es más ancho que su columna, así que se centra con
     translateX(-50%) — "margin: auto" no sirve acá: cuando la caja no
     entra en su contenedor, la spec resuelve los márgenes automáticos a
     0 y la deja desbordando hacia un solo lado.
     Y como el centrado vive en "transform", la animación de entrada NO
     puede ser la de siempre (asomarse anima transform y lo pisaría: el
     menú aparecía corrido media caja a la derecha y saltaba a su lugar
     al terminar). Por eso abajo usa asomarseCentrado, la misma animación
     pero arrastrando el -50%. */
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  max-width: 92vw;
  z-index: 120;
  min-width: 230px;
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--vs);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  box-shadow: 0 12px 32px rgba(0,0,0,0.45);
  animation: asomarseCentrado 0.15s var(--ease-apple);
}
/* Igual que "asomarse" (utilidades.css) pero conservando el
   translateX(-50%) del centrado en los dos extremos. */
@keyframes asomarseCentrado {
  from { opacity: 0; transform: translateX(-50%) translateY(-6px) scale(0.96); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
/* El primero de la fila se sale por la izquierda si se centra sobre su
   columna (el menú es más ancho que ella y la columna empieza en el borde
   de la pantalla), así que ese se alinea a la izquierda. Como deja de
   depender de transform, vuelve a la animación de siempre.
   El último se alinearía a la derecha por el mismo motivo, pero hoy no
   tiene menú — se deja la regla igual, para que no aparezca el problema
   si mañana lo tiene. */
.vit-accesos > .vit-acceso-wrap:first-child .vit-acceso-menu {
  left: 0;
  transform: none;
  animation-name: asomarse;
  /* El origen va en la esquina anclada: asomarse entra con scale(0.96), y
     encogiendo desde el centro el borde izquierdo se corría ~5px y volvía.
     Es el mismo temblor de antes, más chico. */
  transform-origin: top left;
}
.vit-accesos > .vit-acceso-wrap:last-child .vit-acceso-menu {
  left: auto;
  right: 0;
  transform: none;
  animation-name: asomarse;
  transform-origin: top right;
}
.vit-acceso-menu.oculto { display: none; }
.vit-acceso-menu > button {
  background: transparent;
  border: none;
  font-family: inherit;
  text-align: left;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple);
}
.vit-acceso-menu > button:hover { background: var(--vag); color: var(--vtx); }
/* El menú de "Dónde estamos" lleva las redes arriba y después horario y
   dirección, en el mismo orden que la columna del pie de la que sale. */
.vit-acceso-menu-donde { min-width: 250px; }
.vit-acceso-redes {
  display: flex;
  gap: 8px;
  padding: 6px 10px 10px;
  border-bottom: 1px solid var(--vbor);
  margin-bottom: 4px;
}
.vit-acceso-redes .vit-red { margin: 0; }

/* Pagos no navega a ningún lado: informa qué medios se aceptan. */
.vit-acceso-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 10px;
  text-align: left;
}
/* Los cuatro desplegables de la franja comparten DOS niveles y nada más:
   la línea primaria (una opción de Términos, el nombre de un medio de
   pago, el encabezado de Seguimiento) y la secundaria que la explica.
   "Webpay o tarjeta" estaba en --txt-titulo mientras "Términos de
   servicio", que es lo mismo un renglón más allá, estaba en
   --txt-cuerpo: dos niveles para la misma jerarquía en menús vecinos. */
.vit-acceso-menu > button,
.vit-acceso-info strong {
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--txt-cuerpo);
}
.vit-acceso-info span {
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--txt-sub);
  line-height: 1.35;
}

/* El horario y la dirección de "Dónde estamos" no son título+subtítulo
   como los medios de pago: son contenido, del mismo peso que "Términos
   de servicio" en el menú de al lado. Se igualan a ese botón (13px,
   --txt-cuerpo) en vez de heredar el escalón de metadato de arriba, que
   los dejaba al 30% de opacidad y un punto y medio más chicos. El span
   se nombra explícito porque la regla de arriba apunta a los spans
   directamente y le gana al color del contenedor. */
.vit-acceso-menu-donde .vit-acceso-info,
.vit-acceso-menu-donde .vit-acceso-info span {
  font-size: var(--fs-md);
  color: var(--txt-cuerpo);
  line-height: 1.4;
}

/* En pantallas angostas cuatro columnas dejan el texto en tres renglones:
   pasan a dos filas de dos. */
/* Quien pidió menos movimiento ve la franja puesta, sin entrada. */
@media (prefers-reduced-motion: reduce) {
  .vit-accesos > * { animation: none; }
}

@media (max-width: 640px) {
  .vit-accesos { grid-template-columns: repeat(2, 1fr); }

  /* Con dos columnas, :first-child/:last-child dejan de servir para saber
     quién está pegado a un borde: esos selectores son orden del DOM, y acá
     el 2º queda al borde DERECHO de la primera fila y el 3º al borde
     IZQUIERDO de la segunda. Centrados sobre su columna se salían de la
     pantalla — Pagos 35px por la izquierda y Términos 8px por la derecha.
     Acá manda la columna, no el orden: impares a la izquierda, pares a la
     derecha. Como dejan de depender de transform, vuelven a la animación
     de siempre, con el origen en la esquina anclada. */
  /* El menú se mide contra la FRANJA, no contra la ventana. Con
     "max-width: calc(100vw - 20px)" seguía desbordando: 100vw incluye la
     barra de scroll, así que en una ventana de 280px con 11px de barra el
     área visible es 269px y el menú se pasaba justo por esos 11px.
     Anclándolo a la franja el ancho disponible es el real, sin depender
     de si hay barra ni de cuánto mide. Para eso la franja pasa a ser el
     bloque contenedor: el wrap deja de estar posicionado. */
  .vit-accesos { position: relative; }
  .vit-acceso-wrap { position: static; }

  .vit-acceso-menu,
  .vit-acceso-menu-seguimiento {
    min-width: 0;
    max-width: calc(100% - 16px);
    /* Ahora "top: 100%" es el alto de la franja entera: el menú cae bajo
       las dos filas en vez de taparle la de abajo a los de arriba. */
    top: calc(100% + 2px);
  }
  .vit-accesos > .vit-acceso-wrap:nth-child(odd) .vit-acceso-menu {
    left: 8px;
    right: auto;
    transform: none;
    animation-name: asomarse;
    transform-origin: top left;
  }
  .vit-accesos > .vit-acceso-wrap:nth-child(even) .vit-acceso-menu {
    left: auto;
    right: 8px;
    transform: none;
    animation-name: asomarse;
    transform-origin: top right;
  }
  .vit-acceso { padding: 6px 8px; gap: 6px; font-size: 13px; }
  .vit-acceso svg { width: 20px; height: 20px; }
  /* Con dos columnas la divisoria del tercero sobra: es el primero de su
     fila. */
  .vit-accesos > *:nth-child(3) .vit-acceso::before,
  .vit-accesos > .vit-acceso:nth-child(3)::before { display: none; }
}

/* El pie completo se borró: repetía Términos, Privacidad y los datos de
   contacto que ya están en la franja de accesos, arriba de la portada.
   Estas son las redes de esa franja, lo único que sobrevivió de él. */
 
.vit-red {
  width: 36px;
  height: 36px;
  background: var(--vag);
  border: 1px solid var(--vbor2);
  border-radius: var(--r);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--vtx2);
  font-size: 16px;
  text-decoration: none;
  transition: transform 0.2s var(--ease-apple), background 0.2s var(--ease-apple), box-shadow 0.2s var(--ease-apple), color 0.2s var(--ease-apple);
  overflow: hidden;
}
 
.vit-red svg {
  width: 100%;
  height: 100%;
  padding: 7px;
  box-sizing: border-box;
  display: block;
  margin: auto;
}
 
.vit-red:hover {
  background: var(--vag2);
  color: var(--vtx);
  transform: translateY(-2px);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 6px 16px rgba(0,0,0,0.35), 0 0 16px rgba(206,147,216,0.35);
}
 
 
 
 
 
 
.vit-carrito-modal {
  background: var(--color-bg-panel);
  border: 1px solid rgba(206,147,216,0.3);
  border-radius: 16px;
  width: 100%;
  max-width: 480px;
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  box-shadow: 0 32px 80px rgba(0,0,0,0.8);
  position: relative;
}
 
.vit-carrito-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 16px 20px;
  border-bottom: 1px solid rgba(206,147,216,0.18);
  flex-shrink: 0;
}
 
.vit-carrito-modal-titulo {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-accent);
  display: flex;
  align-items: center;
  gap: 8px;
}
 
.vit-carrito-modal-body {
  padding: 16px 20px 20px;
  overflow-y: auto;
  flex: 1;
}
 
 
.vit-carrito-drop-completo {
  padding: 14px 16px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  flex: 1;
  /* Hijo flex de .vit-carrito-dropdown (column, max-height:80vh,
     overflow:hidden): sin min-height:0 se niega a achicarse por debajo
     de su propio contenido (default min-height:auto), así que en vez de
     activar SU overflow-y:auto, empujaba al padre más allá de su
     max-height — y como el padre recorta con overflow:hidden (no
     scroll), todo lo que quedaba abajo (Documento Tributario, lista de
     productos, Total) quedaba cortado sin forma de llegar ahí. Se nota
     sobre todo en mobile, con .vit-carrito-2col pasado a 1 columna
     (mucho más contenido apilado que en desktop). */
  min-height: 0;
}
 
/* ── Carrito: layout de 2 columnas (Datos+Equipo | Carrito) ── */
#vit-carrito-dropdown.vit-carrito-2col {
  /* 920px era un ancho fijo, y el carrito solo se reacomodaba bajo los
     700px: entre medio —una ventana de 900, o el navegador a media
     pantalla— el panel medía 920 contra 900 de ventana y quedaba
     cortado por el borde, con "Procesar" partido al medio.
     Con min() usa los 920 cuando hay, y lo que haya cuando no; las dos
     columnas se achican parejo en vez de salirse. Bajo 700 sigue
     mandando la regla de más abajo, que además las apila. */
  width: min(920px, calc(100vw - 28px));
}
#vit-carrito-dropdown.vit-carrito-2col .vit-carrito-drop-completo {
  display: flex;
  flex-direction: row;
  align-items: stretch;
  padding: 0;
  gap: 0;
}
/* Dentro del carrito manda la columna, no los envoltorios de adentro.
   #formulario-scroll trae .scroll-area (overflow-y:auto), pensado para el
   panel donde él era el que scrolleaba. Movido acá crece a su alto real,
   así que no desborda y no scrollea nada — pero al seguir siendo
   contenedor de scroll se tragaba la rueda, y el "contain" heredado
   impedía que el gesto llegara a la columna que sí podía moverse. Ese es
   el motivo de que el carrito solo scrolleara con el puntero justo sobre
   su barra. Lo mismo para #carrito-fijo, que viene del mismo panel. */
.vit-carrito-col #formulario-scroll,
.vit-carrito-col #carrito-fijo {
  overflow: visible;
  overscroll-behavior: auto;
  max-height: none;
}

.vit-carrito-col {
  flex: 1;
  min-width: 0;
  padding: 14px 16px 16px;
  max-height: 70vh;
  overflow-y: auto;
  /* SIN overscroll-behavior: contain. Una columna cuyo contenido cabe
     sigue siendo contenedor de scroll, y con "contain" se tragaba la
     rueda sin mover nada ni dejarla pasar al padre: el carrito solo
     scrolleaba con el puntero justo encima de su barra. El corte de la
     cadena hacia la página de atrás ya lo hacen el propio dropdown y
     #vit-carrito-drop-completo, que sí tienen "contain". */
}
/* La derecha (productos, con foto + precio) necesita más espacio que la
   izquierda (campos de texto de cliente/equipo) — si no, con la miniatura
   de producto el texto queda apretado y el nombre se corta en columna. */
.vit-carrito-col-izq {
  flex: 0.85;
}
.vit-carrito-col-der {
  flex: 1.15;
}
.vit-carrito-col-izq {
  border-right: 1px solid var(--vbor);
}

@media (max-width: 700px) {
  #vit-carrito-dropdown.vit-carrito-2col {
    width: calc(100vw - 28px);
  }
  #vit-carrito-dropdown.vit-carrito-2col .vit-carrito-drop-completo {
    flex-direction: column;
  }
  .vit-carrito-col-izq {
    border-right: none;
    border-bottom: 1px solid var(--vbor);
  }
  .vit-carrito-col {
    max-height: none;
    /* .vit-carrito-col-izq/-der traen flex:0.85/1.15 pensado para
       repartir ANCHO en modo fila (desktop) — en columna (acá, mobile),
       ese mismo flex reparte ALTURA por partes según esas proporciones
       en vez de dejar que cada columna crezca a su alto real. Quedaban
       apretadas a una fracción fija del alto disponible y el resto del
       contenido (Documento Tributario, lista de productos, Total) se
       recortaba sin scroll posible. flex:none con height:auto deja que
       cada una mida lo que su contenido necesita; .vit-carrito-drop-
       completo (flex-direction:column, overflow-y:auto, min-height:0)
       es quien scrollea si la suma de las dos no entra. */
    flex: none;
    height: auto;
    /* Y dejan de ser contenedores de scroll. Seguían con overflow-y:auto
       y overscroll-behavior:contain heredados del modo escritorio: acá
       no tienen nada propio que scrollear (max-height:none), pero al ser
       contenedores igual se tragaban la rueda y "contain" impedía que el
       gesto pasara al padre. Resultado: el carrito no scrolleaba con la
       rueda aunque .vit-carrito-drop-completo sí podía hacerlo. */
    overflow: visible;
  }
}
 
/* .form-section trae caja y separación propias (utilidades.css); dentro
   del carrito no van, lo mismo en su versión modal que en la desplegable. */
.vit-carrito-modal-body .form-section,
.vit-carrito-drop-completo .form-section {
  margin-bottom: 0;
  border: none;
  padding: 0;
  background: transparent;
}
 
@media (max-width: 700px) {
  .vit-carrito-dropdown { width: calc(100vw - 28px); right: -8px; }
}
 
.vit-usuario-wrapper { position: relative; }
 
.vit-usuario-dropdown {
  position: absolute;
  top: calc(100% + 10px);
  right: 0;
  min-width: 170px;
  background: var(--vs2);
  border: 1px solid var(--vbor2);
  border-radius: var(--rl);
  padding: 8px;
  z-index: 300;
  box-shadow:
  0 24px 64px rgba(0,0,0,0.8),
  0 0 0 1px rgba(206,147,216,0.35),
  0 0 22px rgba(206,147,216,0.22);
  animation: asomarse 0.18s var(--ease-apple);
}
.vit-usuario-dropdown.oculto { display: none; }
 
.vit-btn-salir-dropdown {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 12px;
  background: transparent;
  border: none;
  border-radius: var(--r);
  color: var(--vred);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple);
}
.vit-btn-salir-dropdown:hover { background: rgba(248,113,113,0.12); }
 
.vit-menu-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 38px;
  padding: 0 12px;
  background: transparent;
  border: none;
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 13px;
  font-weight: 400;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple);
  text-align: left;
}
.vit-menu-item:hover { background: var(--vag2); color: var(--vtx); }
.vit-menu-item i { color: var(--va); font-size: 15px; flex-shrink: 0; }
.vit-menu-item.activo {
  background: var(--vag2);
  color: var(--va);
  font-weight: 700;
}
.vit-menu-item.activo i { filter: drop-shadow(0 0 6px rgba(206,147,216,0.6)); }
 
.vit-menu-sep {
  height: 1px;
  background: var(--vbor);
  margin: 6px 4px;
}

/* Selector de sucursal del menú de usuario. No es un ítem de navegación
   —no lleva a ninguna página— así que se ve distinto a propósito: una
   etiqueta chica arriba y el select debajo, como un ajuste. Solo
   aparece cuando el negocio tiene más de un local. */
.vit-menu-sucursal {
  padding: 8px 12px 10px;
}
.vit-menu-sucursal label {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--vtx3);
  margin-bottom: 6px;
}
.vit-menu-sucursal label i { color: var(--va); font-size: 13px; }
.vit-menu-sucursal select {
  width: 100%;
  height: 34px;
  padding: 0 8px;
  border-radius: var(--r);
  border: 1px solid var(--vbor);
  background: var(--vag2);
  color: var(--vtx);
  font-size: 13px;
  cursor: pointer;
}
/* El mismo lugar y el mismo peso visual que el desplegable, pero sin
   flecha ni cursor de mano: es información, no una elección. */
/* El display de acá le gana al "display:none" que el navegador le pone
   a [hidden] (una regla de autor siempre pisa la del navegador), así que
   al administrador —que sí ve el desplegable— le quedaba además esta
   caja vacía debajo. Hay que apagarla a mano. */
.vit-menu-sucursal-fija[hidden] {
  display: none;
}
.vit-menu-sucursal-fija {
  display: flex;
  align-items: center;
  min-height: 34px;
  padding: 0 8px;
  border-radius: var(--r);
  border: 1px solid var(--vbor);
  background: var(--vag2);
  color: var(--vtx);
  font-size: 13px;
}

/* Marca permanente de que se está administrando el sistema y no el
   taller propio: una franja fina arriba de todo. Sin esto, las dos
   páginas se parecen lo bastante como para confundirlas. */
body.modo-consola::before {
  content: "";
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg, var(--va), var(--color-azul, #64b5f6));
  z-index: 9999;
  pointer-events: none;
}
 
/* ════════════════════════════════════════════════════════════
   BOTÓN FLOTANTE WHATSAPP
   ════════════════════════════════════════════════════════════ */
.vit-whatsapp-float {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
  width: 56px;
  height: 56px;
  background: #25d366;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-size: 28px;
  text-decoration: none;
  box-shadow: 0 4px 16px rgba(37, 211, 102, 0.35), 0 0 0 1px rgba(37, 211, 102, 0.2);
  transition: transform 0.2s var(--ease-apple), box-shadow 0.2s var(--ease-apple);
  cursor: pointer;
}
.vit-whatsapp-float:hover {
  transform: scale(1.08) translateY(-2px);
  box-shadow: 0 8px 24px rgba(37, 211, 102, 0.45), 0 0 0 1px rgba(37, 211, 102, 0.3);
}
.vit-whatsapp-float:active {
  transform: scale(0.96);
}
 
@media (max-width: 700px) {
  .vit-whatsapp-float {
    bottom: 16px;
    right: 16px;
    width: 50px;
    height: 50px;
    font-size: 24px;
  }
}
 
/* ════════════════════════════════════════════════════════════
   BOTÓN MENÚ + OVERLAY + DRAWER MÓVIL
   (Nota: este bloque estaba duplicado en el archivo original —
   había dos copias idénticas de .vit-btn-menu y .vit-sidebar-overlay.
   Se deja una sola versión, la más completa.)
   ════════════════════════════════════════════════════════════ */
 
.vit-btn-menu {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--vtx2);
  font-size: 20px;
  cursor: pointer;
  transition: all 0.15s var(--ease-apple);
  flex-shrink: 0;
}
.vit-btn-menu:hover {
  background: var(--vag);
  color: var(--vtx);
}
 
/* El fondo y el desenfoque los pone .fx-velo-suave (utilidades.css),
   que es la misma receta que usan los modales. Acá queda solo lo que es
   propio de este velo: a qué altura se apila y que arranca escondido. */
.vit-sidebar-overlay {
  display: none;
  z-index: 350;
}
.vit-sidebar-overlay.activo {
  display: block;
}
 
@media (max-width: 700px) {
  /* Acá el sidebar es un cajón lateral, y eso lo pone .fx-cajon
     (utilidades.css), la misma clase que usa el cajón de accesos de la
     vitrina del taller: posición, medidas, curva, entrada y salida. Lo
     que queda acá abajo es lo propio del sidebar.
     El botón de cerrar corre la misma suerte: .fx-cajon-cerrar le da la
     pinta y esta regla solo lo enciende, porque en el escritorio no va
     (arriba está en display:none). */
  .vit-sidebar-btn-cerrar { display: flex; }
 
  .vit-sidebar.cerrado {
    transform: translateX(-100%);
    width: 85%;
    min-width: auto;
    margin-left: 0;
    padding: 4px 0 4px 0;
    opacity: 1;
    border: 1px solid var(--vbor2);
  }
}
 
/* ════════════════════════════════════════════════════════════
   NAVBAR MÓVIL
   ════════════════════════════════════════════════════════════ */
@media (max-width: 700px) {
  #vitrina-root {
    /* Esto está para que nada desborde a lo ancho en el teléfono, pero
       "overflow-x: hidden" arrastra un efecto que no se ve venir: por
       spec, fijar UN eje en hidden fuerza el otro a "auto". Eso convierte
       a #vitrina-root en contenedor de scroll, y un contenedor de scroll
       se vuelve el contexto de todos los position:sticky que tenga
       adentro. Como el que scrollea de verdad es <html> y no él, la cinta
       morada y el navbar dejaban de pegarse: medido, al bajar 500px se
       iban a -500 y -306. En escritorio esta regla no aplica, por eso
       ahí siempre funcionó.

       "clip" recorta igual pero NO crea contenedor de scroll: overflow-y
       se queda en visible y el sticky vuelve a funcionar. Verificado en
       la página real: con hidden el aviso terminaba en -500, con clip se
       queda en 0.

       El "hidden" queda arriba como respaldo para navegadores que no
       entiendan clip: ahí se pierde el sticky, pero no el recorte. */
    overflow-x: hidden;
    overflow-x: clip;
  }
  .vit-nav-right {
    flex-shrink: 0;
  }
  .vit-usuario-dropdown {
    right: -8px;
  }
}
/* ════════════════════════════════════════════════════════════
   MENÚ ⋮ DE CADA PRODUCTO EN LA GRILLA (Editar / Eliminar)
   ════════════════════════════════════════════════════════════ */
.vit-card-fila-acciones {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 8px;
  /* La fila también es hija de un flex (el cuerpo de la tarjeta), así que
     ella misma tampoco baja de lo que mide su contenido si no se le dice.
     Sin esto, achicar el botón de adentro no servía de nada: la fila
     seguía siendo más ancha que la tarjeta.

     Y con permiso para envolver: si ni achicándose entran los dos (una
     pantalla muy angosta), el ⋮ baja a la línea siguiente. Es mejor que
     la alternativa, que era un botón "Agregar" de 14px con el texto
     recortado a nada. */
  min-width: 0;
  flex-wrap: wrap;
}
.vit-card-fila-acciones .vit-btn-carrito {
  flex: 1;
  /* min-width:0 o el botón NO baja de lo que mide su contenido ("🛒
     Agregar"): con el ⋮ al lado, la fila terminaba más ancha que la
     tarjeta y, como se alinea a la derecha, lo que sobraba se salía por
     la IZQUIERDA — el botón quedaba cortado contra el borde. Ahora se
     achica, y si el espacio es muy poco el texto se recorta en vez de
     desbordar. */
  /* Baja hasta 76px —lo que mide "Agregar" con su carrito— y de ahí no
     más: por debajo, el texto no se lee y el botón deja de decir qué
     hace. Si no alcanza ni eso, la fila envuelve (ver arriba). */
  min-width: 76px;
  margin-top: 0;
  padding: 0 6px;
  overflow: hidden;
}
.vit-card-fila-acciones .vit-btn-carrito span,
.vit-card-fila-acciones .vit-btn-carrito {
  white-space: nowrap;
}
.vit-card-fila-acciones .vit-btn-menu-card {
  flex-shrink: 0;
}
 
.vit-btn-menu-card {
  width: 33px;
  height: 33px;
  flex-shrink: 0;
  background: transparent;
  border: 1px solid var(--vbor);
  border-radius: var(--r);
  color: var(--txt-sub);
  font-size: 15px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.15s var(--ease-apple);
}
.vit-btn-menu-card:hover {
  background: var(--vag);
  border-color: var(--vbor2);
  color: var(--va);
}
 
/* ── Dropdown flotante (único, compartido por todas las cards) ── */
/* Selector por ID: le gana a la clase genérica .cerrando aunque esta se
   cargue después, así que sin este override el menú nunca cerraba animado. */
 
.vit-card-menu-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 34px;
  padding: 0 10px;
  background: transparent;
  border: none;
  border-radius: 6px;
  color: var(--vtx2);
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.15s var(--ease-apple), color 0.15s var(--ease-apple);
  text-align: left;
}
.vit-card-menu-item:hover { background: var(--vag2); color: var(--vtx); }
.vit-card-menu-item i { color: var(--va); font-size: 15px; flex-shrink: 0; }
.vit-card-menu-item-rojo i { color: var(--vred); }
.vit-card-menu-item-rojo:hover { background: rgba(248,113,113,0.12); color: var(--vred); }
 
.vit-agregarprod-wrapper { position: relative; display: flex; align-items: center; }
 
#modal-agregar-producto.vit-carrito-dropdown {
  width: 420px;
}
@media (max-width: 700px) {
  #modal-agregar-producto.vit-carrito-dropdown { width: calc(100vw - 28px); right: -8px; }
}

/* Agenda: más ancho para que la vista Año (3 meses por fila) se lea bien */
#vit-agenda-dropdown.vit-carrito-dropdown {
  width: 440px;
}
@media (max-width: 700px) {
  #vit-agenda-dropdown.vit-carrito-dropdown { width: calc(100vw - 28px); right: -8px; }
}

/* ── Timeline de seguimiento público (estilo Chilexpress) ── */
.vit-seg-bloque + .vit-seg-bloque {
  margin-top: 18px; padding-top: 18px; border-top: 1px solid var(--vbor);
}
.vit-seg-bloque-titulo {
  font-size: 12px; font-weight: 700; color: var(--vtx2);
  text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 10px;
}
.vit-seg-timeline { display: flex; flex-direction: column; }
.vit-seg-nodo { display: flex; gap: 12px; }
.vit-seg-nodo-col { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
.vit-seg-nodo-circulo {
  width: 26px; height: 26px; border-radius: 50%;
  background: var(--vs3); border: 1px solid var(--vbor2);
  color: var(--vtx2);
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; flex-shrink: 0;
}
.vit-seg-nodo-activo .vit-seg-nodo-circulo {
  background: var(--va); border-color: var(--va); color: #fff;
}
.vit-seg-nodo-conector { width: 2px; flex: 1; min-height: 22px; background: var(--vbor2); margin: 2px 0; }
.vit-seg-nodo-texto { padding-bottom: 18px; }
.vit-seg-nodo:last-child .vit-seg-nodo-texto { padding-bottom: 0; }
.vit-seg-nodo-fecha { font-size: 11px; color: var(--txt-sub); margin-bottom: 2px; }
.vit-seg-nodo-label { font-size: 13px; color: var(--vtx2); }
.vit-seg-nodo-activo .vit-seg-nodo-label { font-weight: 700; color: var(--vtx); }
 
#vit-btn-agenda-nav.activo {
  background: var(--vag2);
  box-shadow: 0 0 0 1px rgba(206,147,216,0.35), 0 0 16px rgba(206,147,216,0.45);
}
#vit-btn-agenda-nav.activo i {
  color: var(--va);
  filter: drop-shadow(0 0 6px rgba(206,147,216,0.8));
}

/* ── Remanentes del wizard de un solo paso (ya no existe para empleados,
   siempre es 2 columnas — ver _moverCarritoAlDropdown en vitrina.js) que
   siguen viviendo en el código y hay que mantener ocultos dentro del
   carrito flotante:
   1) #header-navegacion-carrito: header dinámico (buscar/título de
      paso/basurero/flecha "Siguiente") que carrito.js todavía puede
      llegar a crear si algo dispara mostrarDatosClienteConTransicion()
      (p.ej. la lupa de #carrito-fijo).
   2) El título propio de #carrito-fijo (lupa/"Carrito"/basurero/flecha
      "Datos"): queda redundante con el header "Carrito" externo del
      dropdown, que es el que se usa ahora.
   Los títulos "PERSONA"/"DISPOSITIVO"/"EMPRESA" (los de verdad) NO se
   tocan acá — esos sí deben mostrarse, con su mismo estilo compartido
   (.form-section-title, definida en utilidades.css). ── */
#vit-carrito-drop-completo #header-navegacion-carrito,
#vit-carrito-drop-completo #carrito-fijo > .form-section-title {
  display: none !important;
}

/* ── Página legal (Política de Privacidad) dentro del catálogo de la
   empresa — se activa con ?pagina=privacidad mientras haya un
   ?empresa= en la URL (ver _iniciarPaginaLegal en vitrina.js). Oculta
   la grilla/sidebar (.vit-layout) y muestra esto en su lugar. ── */
.vit-pagina-legal.oculto { display: none; }
.vit-pagina-legal {
  max-width: 760px;
  margin: 0 auto;
  padding: 40px 24px 60px;
  color: var(--vtx2);
  line-height: 1.6;
}
.vit-pagina-legal-logo { margin-bottom: 24px; }

.vit-pagina-legal h1 {
  font-size: 24px;
  color: var(--vtx);
  border-bottom: 1px solid var(--vbor);
  padding-bottom: 12px;
  margin-bottom: 20px;
}
.vit-pagina-legal h2 {
  font-size: 17px;
  color: var(--va);
  margin-top: 28px;
}
.vit-pagina-legal p { margin: 10px 0; }
.vit-pagina-legal ul { padding-left: 20px; margin: 10px 0; }
.vit-pagina-legal li { margin: 4px 0; }
.vit-pagina-legal strong { color: var(--vtx); }
.vit-pagina-legal a,
.vit-pagina-legal a:visited { color: var(--vtx); font-weight: 700; text-decoration: none; }

/* ── Franja de aviso superior ──────────────────────────────────────
   Va arriba de todo, sobre el navbar, de borde a borde. El color de
   fondo lo pone _pintarAvisoHome inline (viene de Admin > Portada), así
   que acá no se define: solo la forma. */
.vit-aviso-home {
  width: 100%;
  /* Tres partes: bandera, aviso al centro, bandera. El centro se lleva el
     espacio sobrante para que el texto quede centrado en la franja y no
     corrido por el ancho de una bandera. */
  display: flex;
  align-items: center;
  gap: 10px;
  /* Franja deliberadamente baja: 4px arriba y abajo más un interlineado
     de 1.3 dan ~25px de alto, un 30% menos que los ~36px que ocupaba
     antes. Es un aviso, no debe robarle altura al contenido. */
  padding: 4px 20px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: #fff;
  /* Se queda pegada arriba junto con el navbar. Antes era relative: al
     bajar se iba con el contenido y quedaba solo el navbar, que sí es
     sticky. El navbar arranca justo debajo (ver .vit-nav top), con el
     alto real de esta franja medido en vivo, porque el texto del aviso
     puede envolver a dos líneas.
     z-index por encima del navbar: si no, al pegarse los dos, el navbar
     le pasaba por arriba. */
  position: sticky;
  top: 0;
  z-index: 300;
}
.vit-aviso-home.oculto { display: none; }
.vit-aviso-texto { flex: 1; min-width: 0; }
.vit-aviso-bandera {
  flex-shrink: 0;
  font-size: 15px;
  line-height: 1;
}
.vit-aviso-home a {
  color: #fff;
  text-decoration: none;
}
/* Sin subrayado fijo, el hover es lo único que delata que es clickeable
   — por eso acá sí aparece, en vez de solo bajarle la opacidad. */
.vit-aviso-home a:hover {
  opacity: 0.85;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* ── Selector de taller en el menú de usuario ──
   Va arriba del selector de local: primero de quién es el negocio,
   después en qué sucursal de ese negocio. Solo aparece para quien
   trabaja en más de uno. */
.vit-menu-empresas {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 8px 10px;
  border-bottom: 1px solid var(--vbor);
}
.vit-menu-titulo {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--txt-sub);
  padding: 2px 8px 6px;
}
.vit-menu-empresa {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  width: 100%;
}
.vit-menu-empresa-rol {
  font-size: 11px;
  color: var(--txt-sub);
  text-transform: lowercase;
}
/* El taller donde ya estás: marcado, no clickeable. */
.vit-menu-empresa.activo {
  background: var(--vag2);
  color: var(--va);
}
.vit-menu-empresa:disabled {
  opacity: 0.5;
  cursor: default;
}

/* La fila del taller donde estás: el nombre ocupa lo suyo y los tres
   puntitos quedan al borde. */
.vit-menu-empresa-fila {
  position: relative;
  display: flex;
  align-items: stretch;
  gap: 2px;
}
.vit-menu-empresa-fila .vit-menu-empresa {
  flex: 1;
  min-width: 0;
}
.vit-menu-empresa-mas {
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 30px;
  padding: 0;
  border: none;
  border-radius: 8px;
  background: transparent;
  color: var(--txt-sub);
  cursor: pointer;
  font-size: 16px;
}
.vit-menu-empresa-mas:hover {
  background: var(--vag2);
  color: var(--vtx);
}
/* Lo compartido está en .fx-menu-anclado (utilidades.css): cuelga debajo
   de los puntitos en vez de empujar las filas de abajo, igual que el
   resto de los menús del sitio. */
.vit-menu-empresa-acciones {
  background: var(--vs2);
  min-width: 160px;
  z-index: 30;
}
.vit-menu-empresa-acciones .vit-menu-salir-taller {
  white-space: nowrap;
}
/* No hay un .oculto general en el sitio: cada componente declara el suyo.
   Sin esto, "Salir del taller" se veía siempre y los puntitos no servían
   de nada. */
.vit-menu-empresas.oculto,
.vit-menu-empresa-acciones.oculto {
  display: none;
}
/* "Salir del taller": en rojo, para que no se confunda con las filas de
   arriba, que son para cambiarse. */
.vit-menu-salir-taller {
  color: var(--vred);
  margin-top: 2px;
}


/* ── Los botones de la tarjeta en el teléfono ──────────────────────
   Con dos tarjetas por fila, "Agregar" y el ⋮ comparten unos 90px. Este
   bloque va al FINAL del archivo a propósito: las reglas de
   .vit-card-fila-acciones se definen más arriba y, con la misma
   especificidad, gana la última — puesto antes, esto no hacía nada (el
   ⋮ seguía bajándose de línea). */
@media (max-width: 700px) {
  .vit-card-fila-acciones { gap: 4px; }
  .vit-card-fila-acciones .vit-btn-carrito {
    /* 56px es el piso: por debajo, "Agregar" empieza a recortarse. */
    min-width: 56px;
    height: 30px;
    font-size: 11px;
    padding: 0 6px;
  }
  .vit-card-fila-acciones .vit-btn-menu-card {
    width: 28px;
    height: 28px;
    font-size: 13px;
  }
}

/* Y en las pantallas más angostas, el carrito del botón sobra: entre el
   dibujito y la palabra, la palabra es la que dice qué hace. Sacándolo
   entran los dos botones en la misma línea incluso ahí. */
@media (max-width: 360px) {
  .vit-card-fila-acciones .vit-btn-carrito i { display: none; }
  .vit-card-fila-acciones .vit-btn-carrito { gap: 0; }
}
