/* ---- Tipografia de la tienda (Fraunces + Inter) ----
   Autoalojadas en /public/fonts (solo el subset "latin", que ya cubre los
   acentos y "ñ" del español - vienen de los paquetes @fontsource/fraunces
   y @fontsource/inter) en vez de cargarse desde Google Fonts: el sitio
   manda un Content-Security-Policy bastante estricto
   (style-src/font-src 'self', ver src/server/index.ts) que bloquea
   cualquier hoja de estilo o fuente que no venga del propio dominio -
   autoalojar evita tener que aflojar esa politica nada mas para esto, y de
   paso evita una llamada a un dominio externo (Google) en cada visita.
   Solo se usan dentro de "body.tienda" (ver mas abajo) - el panel
   administrativo se queda con la fuente del sistema de siempre. */
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/fraunces-400.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/fraunces-500.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/fraunces-600.woff2") format("woff2");
}
@font-face {
  font-family: "Fraunces";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/fraunces-700.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/inter-400.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/static/fonts/inter-500.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/inter-600.woff2") format("woff2");
}
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/inter-700.woff2") format("woff2");
}
/* Letra manuscrita para el eslogan del hero (ver .hero-slogan mas abajo) -
   mismo criterio de autoalojado que Fraunces/Inter arriba: subset "latin"
   nada mas, extraido de @fontsource/dancing-script. */
@font-face {
  font-family: "Dancing Script";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/static/fonts/dancing-script-400.woff2") format("woff2");
}
@font-face {
  font-family: "Dancing Script";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/static/fonts/dancing-script-600.woff2") format("woff2");
}
@font-face {
  font-family: "Dancing Script";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/static/fonts/dancing-script-700.woff2") format("woff2");
}

:root {
  /* Paleta negro y dorado, tomada de la tarjeta de presentacion real de la
     marca (fondo negro con el monograma en dorado tipo laton/bronce, no
     un dorado amarillo brillante). --color-acento se eligio ademas
     verificando que tuviera buen contraste tanto sobre fondo blanco (para
     precios y textos) como sobre fondo negro/con texto negro encima
     (botones, insignias) - ver /tmp/contraste.mjs si hace falta revisar
     otros tonos a futuro.

     Tema oscuro completo: --color-fondo (antes un blanco hueso) y
     --color-texto (antes casi negro) se invirtieron para que TODO el sitio
     (tienda y panel administrativo) quede en negro/carbon con texto claro,
     no solo el encabezado. --color-superficie es el "negro un poco mas
     claro" para tarjetas/tablas/inputs - lo que antes era blanco puro -
     para que se note un escalon sutil sobre el fondo en vez de que todo
     quede del mismo tono. --color-borde y --color-texto-muted son los
     equivalentes oscuros de los grises (#ddd, #eee, #888, #999...) que
     estaban pensados para texto oscuro sobre fondo claro. */
  --color-primario: #16181d;
  --color-acento: #a6813e;
  --color-fondo: #1c1e23;
  --color-superficie: #26282f;
  --color-borde: #3b3e46;
  --color-texto: #efece3;
  --color-texto-muted: #a9a59b;
  --marmol: url("/static/img/marmol-negro-dorado.jpg");
  /* Prueba: encabezado negro liso con letras en dorado amarillo brillante,
     como alternativa al fondo de marmol (que depende de la calidad de la
     foto). Mas claro/amarillo que --color-acento a proposito, para que se
     note bien como texto sobre negro solido. */
  --dorado-texto: #d4af37;
  /* Negro puro (no el gris carbon --color-primario que usa el resto del
     sitio) solo para la franja del encabezado - se pidio "mas brillante"
     que el negro grisaceo original. */
  --negro-encabezado: #000000;
  /* Colores oficiales de marca de Mercado Libre (amarillo + azul marino),
     solo para el badge ".icono-ml" de abajo - identifica en el panel los
     encabezados/columnas que muestran datos que vienen de Mercado Libre.
     No se pudo usar el logotipo real (descarga de archivos bloqueada en
     este entorno), asi que es un badge propio con "ML" en vez de una
     copia del isotipo oficial. */
  --ml-amarillo: #ffe600;
  --ml-azul: #2d3277;
  font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
}

* { box-sizing: border-box; }
body { margin: 0; background: var(--color-fondo); color: var(--color-texto); }
/* Los links "sueltos" (dentro de un hint, una nota, un texto de ayuda) que
   no traen su propia clase nunca se estilizaron aparte - con fondo claro se
   veian bien con el azul por defecto del navegador, pero sobre el nuevo
   fondo oscuro del sitio se ven fuera de lugar (no combinan con negro y
   dorado). Las clases mas especificas (.subnav a, .volver-tienda, etc.)
   siguen ganando por especificidad, asi que esto solo cambia los que no
   tenian ningun estilo propio. */
a { color: var(--color-acento); }

/* ---- Barra de carga (indicador de navegacion) ----
   El sitio usa navegacion tradicional de pagina completa (no es una app de
   una sola pantalla): sin este aviso, dar clic en un link o en "Guardar"
   no daba ninguna señal mientras el navegador cargaba lo siguiente - se
   sentia como que no habia pasado nada (sobre todo en el panel
   administrativo, con tablas grandes), lo que invitaba a dar clic varias
   veces por accidente. Ver navegacion.js: se activa solo con JS en
   cualquier clic en un link interno o el submit de un formulario, y se
   queda visible hasta que la pagina siguiente termine de cargar y
   reemplace a esta (el navegador la corta sola, no hace falta ocultarla
   "a mano"). */
.barra-carga {
  position: fixed; top: 0; left: 0; height: 3px; width: 0; z-index: 2000;
  background: var(--color-acento); opacity: 0;
  transition: opacity .2s ease;
}
.barra-carga.activa { opacity: 1; width: 78%; transition: width 8s cubic-bezier(.1, .6, .2, 1), opacity .2s ease; }

/* ---- Frontend / Tienda ---- */
/* Marmol negro con vetas doradas de fondo (ver public/img/marmol-negro-dorado.jpg)
   con un degradado oscuro semitransparente encima: sin el degradado, el
   marmol de fondo se ve muy claro en algunas zonas y el texto/logo blanco
   del menu pierde contraste - con el degradado se ve la textura del marmol
   pero el encabezado se sigue leyendo bien en cualquier parte. La opacidad
   se dejo bastante mas baja que la primera version (que tapaba casi todo
   el marmol y se veia opaca/deslavada) - un text-shadow en el logo/menu
   (ver .logo, .lema, .link-carrito, etc. mas abajo) es lo que ahora
   sostiene la legibilidad, no el degradado. */
.banner {
  background: var(--negro-encabezado);
  color: var(--dorado-texto);
  padding: 1.5rem 2rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .7);
}
.nav { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem; }
.nav-derecha { display: flex; align-items: center; gap: .75rem; flex-wrap: wrap; }
.marca { display: flex; align-items: center; gap: 1.25rem; flex-wrap: wrap; }
.logo {
  font-weight: 700; font-size: 1.25rem; color: inherit; text-decoration: none;
  display: inline-flex; align-items: center; gap: 1rem;
}
.logo-figura { display: block; height: 6.5rem; width: auto; }
.logo-texto { display: block; height: 4.75rem; width: auto; }
.lema h1 { font-size: .95rem; font-weight: 600; margin: 0 0 .25rem; }
.lema p { font-size: .8rem; margin: 0; opacity: .85; }
.link-info {
  background: transparent; color: var(--dorado-texto); border: 1px solid rgba(212,175,55,.5);
  padding: .4rem .9rem; border-radius: 999px; cursor: pointer;
}
.link-carrito {
  background: transparent; color: var(--dorado-texto); border: 1px solid rgba(212,175,55,.5);
  padding: .4rem .9rem; border-radius: 999px; text-decoration: none; font-size: .9rem;
}
.link-carrito:hover { background: rgba(212,175,55,.15); }
.link-admin {
  background: transparent; color: var(--dorado-texto); border: 1px solid rgba(212,175,55,.5);
  border-radius: 999px; text-decoration: none; opacity: .75;
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.2rem; height: 2.2rem; font-size: 1.1rem; line-height: 1;
}
.link-admin:hover { background: rgba(212,175,55,.15); opacity: 1; }
.banner-secundario { padding: 1.5rem 2rem; }

/* El logo (dos imagenes de altura fija) y los 5 enlaces de la esquina
   derecha del menu cabian en una sola fila en pantallas grandes, pero en
   celular no entraban (el "nav" no envolvia) - la pagina completa se
   quedaba mas ancha que la pantalla y habia que hacer scroll horizontal
   para ver el resto. Ya se agrego flex-wrap arriba para que como minimo no
   se corte nada; aqui ademas se achica el logo y se reduce el padding para
   que en celular quede acomodado en 2-3 lineas en vez de una sola fila
   apretada. */
@media (max-width: 640px) {
  .banner { padding: 1.25rem 1rem; }
  .logo-figura { height: 4rem; }
  .logo-texto { height: 3rem; }
  .nav-derecha { gap: .5rem; }
  .link-info, .link-carrito { padding: .35rem .7rem; font-size: .85rem; }
  /* En celular se quita el acceso a la parte administrativa (el engrane
     que enlaza a /backend/inventario) del menu de la tienda - se queda
     disponible solo en pantallas mas grandes. */
  .link-admin { display: none; }
}

.tienda { padding: 2rem; }
@media (max-width: 640px) {
  .tienda { padding: 1.25rem 1rem; }
  .carrito-pagina { padding: 1.25rem 1rem; }
}
.filtros-catalogo { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.25rem; }
.filtros-catalogo select,
.filtros-catalogo .filtro-buscar {
  padding: .5rem .7rem; border: 1px solid var(--color-borde); border-radius: .4rem; font: inherit;
  background: var(--color-superficie); color: var(--color-texto);
}
.filtros-catalogo .filtro-buscar { flex: 1 1 14rem; }

/* ---- Selector de vista del catalogo (miniaturas / descripcion) ----
   Calca lo que ya trae Mercado Libre: alternar entre la cuadricula
   compacta de fotos (la que ya existia, sin cambios - "miniaturas") y una
   lista donde cada producto se lee como una fila completa con su
   descripcion ("descripcion"). La eleccion se recuerda en este navegador
   (ver tienda.js). */
.selector-vista { display: flex; gap: .4rem; margin-left: auto; }
.boton-vista {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.4rem; height: 2.4rem; border-radius: .4rem; padding: 0;
  border: 1px solid var(--color-borde); background: var(--color-superficie);
  color: var(--color-texto-muted); cursor: pointer;
}
.boton-vista svg { width: 1.15rem; height: 1.15rem; }
.boton-vista:hover { color: var(--color-texto); border-color: var(--color-acento); }
.boton-vista.boton-vista-activo { color: var(--color-acento); border-color: var(--color-acento); background: rgba(166, 129, 62, .14); }

.productos-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 1rem; margin-top: 1rem; }
.producto-card.oculto { display: none; }
.producto-card {
  background: var(--color-superficie); border-radius: .75rem; padding: 1rem; box-shadow: 0 1px 3px rgba(0,0,0,.08);
  display: flex; flex-direction: column; gap: .5rem; transition: transform .1s ease;
}
.producto-card:hover { transform: translateY(-2px); box-shadow: 0 4px 10px rgba(0,0,0,.1); }
.producto-card-link { display: block; text-decoration: none; color: inherit; }
.producto-card .precio { color: var(--color-acento); font-weight: 700; }
.producto-card .sku { color: var(--color-texto-muted); font-size: .8rem; }
.producto-img { width: 100%; height: 10rem; object-fit: contain; background: var(--color-borde); border-radius: .5rem; margin-bottom: .5rem; }
.producto-img-vacia { display: flex; align-items: center; justify-content: center; background: var(--color-borde); color: var(--color-texto-muted); font-size: .8rem; }

/* Vista "descripcion": una fila por producto en vez de la cuadricula, con
   la foto a la izquierda (mas chica) y toda la descripcion a la derecha,
   sin recortar nada - pensada para leer el detalle de varios productos
   sin tener que entrar a cada ficha uno por uno. */
.productos-grid.vista-lista { display: flex; flex-direction: column; gap: .75rem; }
.productos-grid.vista-lista .producto-card { flex-direction: row; align-items: center; flex-wrap: wrap; }
.productos-grid.vista-lista .producto-card-link { display: flex; gap: 1.25rem; align-items: flex-start; flex: 1 1 16rem; min-width: 0; }
.productos-grid.vista-lista .producto-img,
.productos-grid.vista-lista .producto-img-vacia {
  width: 6rem; height: 6rem; flex-shrink: 0; margin-bottom: 0;
}
.productos-grid.vista-lista .producto-card-info { display: flex; flex-direction: column; gap: .3rem; min-width: 0; }
.productos-grid.vista-lista .btn-agregar-carrito { flex-shrink: 0; }
@media (max-width: 640px) {
  .productos-grid.vista-lista .producto-card { flex-direction: column; align-items: stretch; }
}

/* ---- "Tambien te puede interesar" (ficha de producto) ---- */
.productos-relacionados-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 1rem; margin-top: .75rem;
}
.productos-relacionados .producto-card { background: var(--color-superficie); }

/* Boton "secundario" (Ver carrito, Cancelar, etc.): a proposito se deja
   blanco solido (no var(--color-superficie)) para que contraste fuerte
   contra el fondo oscuro del sitio, con un borde dorado en vez del borde
   oscuro que tenia cuando el fondo de la pagina era claro (ahi un borde
   oscuro se notaba; sobre fondo oscuro un borde oscuro desaparecia). */
.btn.btn-secundario {
  background: white; color: var(--color-primario); border: 1px solid var(--color-acento);
}
.btn.btn-secundario:hover { background: #f1efe7; opacity: 1; }
.producto-acciones { margin: 1rem 0; display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
.producto-acciones .etiqueta-cantidad { font-size: .85rem; color: var(--color-texto-muted); margin: 0; }
.producto-cantidad-input { width: 4rem; padding: .5rem; border: 1px solid var(--color-borde); border-radius: .4rem; font: inherit; background: var(--color-superficie); color: var(--color-texto); }

/* ---- Compartir producto por WhatsApp (ficha de producto) ---- */
.link-compartir {
  display: inline-flex; align-items: center; gap: .4rem; margin-top: .25rem;
  color: var(--color-texto-muted); font-size: .85rem; text-decoration: none;
}
.link-compartir:hover { color: var(--color-acento); text-decoration: underline; }
.link-compartir svg { width: 16px; height: 16px; flex-shrink: 0; }

/* ---- Detalle de producto / compra ---- */
.producto-detalle { padding: 2rem; max-width: 50rem; margin: 0 auto; }
.producto-detalle-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem; background: var(--color-superficie); border-radius: .75rem; padding: 1.5rem; }
.producto-detalle-img { width: 100%; height: 20rem; object-fit: cover; border-radius: .5rem; cursor: zoom-in; }
.producto-imagen-principal-envoltura { position: relative; overflow: hidden; border-radius: .5rem; }
/* Zoom al pasar el cursor (solo equipos con mouse - en celular/tablet el
   cursor no existe, ahi se sigue usando el zoom por toque que abre el
   visor grande). El origen del acercamiento (transform-origin) lo va
   moviendo tienda.js segun donde este el cursor sobre la foto. */
@media (hover: hover) and (pointer: fine) {
  .producto-imagen-principal-envoltura.zoom-activo .producto-detalle-img {
    transform: scale(2.2);
  }
  .producto-detalle-img { transition: transform .15s ease-out; }
}
@media (prefers-reduced-motion: reduce) {
  .producto-detalle-img { transition: none; }
}
.producto-imagen-zoom-disparador {
  position: absolute; bottom: .6rem; right: .6rem; width: 2.4rem; height: 2.4rem;
  border-radius: 50%; border: none; background: rgba(0,0,0,.55); color: white;
  display: flex; align-items: center; justify-content: center; cursor: zoom-in;
}
.producto-imagen-zoom-disparador svg { width: 1.2rem; height: 1.2rem; }
.producto-imagen-zoom-disparador:hover { background: rgba(0,0,0,.75); }
.producto-galeria-miniaturas { display: flex; gap: .5rem; margin-top: .6rem; flex-wrap: wrap; }
.producto-miniatura {
  padding: 0; border: 2px solid transparent; border-radius: .4rem; background: none; cursor: pointer;
  width: 3.5rem; height: 3.5rem; overflow: hidden; flex: none; opacity: .7;
}
.producto-miniatura img { width: 100%; height: 100%; object-fit: cover; display: block; }
.producto-miniatura:hover { opacity: 1; }
.producto-miniatura-activa { border-color: var(--color-acento); opacity: 1; }
.producto-detalle-precio { font-size: 1.5rem; color: var(--color-acento); font-weight: 700; margin: .5rem 0; }
/* Caja de descuentos aplicados: color de texto oscuro explicito porque el
   fondo se deja claro (crema) a proposito, como acento calido dentro de la
   ficha de producto (que ya es oscura) - sin esto el texto (heredado de
   --color-texto, ahora claro) quedaria casi ilegible sobre el crema. */
.descuentos-producto { background: #faf3e2; color: #3a2f1f; border-radius: .5rem; padding: .75rem 1rem; margin-bottom: 1rem; }
.descuentos-producto .etiqueta-seccion { margin-top: 0; }
.lista-descuentos { margin: .25rem 0 0; padding-left: 1.1rem; font-size: .9rem; }
.lista-descuentos li { margin-bottom: .3rem; }
.precio-descuento { color: var(--color-acento); font-weight: 700; }
.precio-tachado { color: var(--color-texto-muted); text-decoration: line-through; font-size: .85rem; }
.aviso-stock-bajo { color: #e0a83e; font-weight: 600; font-size: .85rem; margin: .2rem 0 .6rem; }
.aviso-stock-bajo.aviso-agotado { color: #e0685a; }
.volver-tienda { display: inline-block; margin-bottom: 1rem; color: var(--color-acento); text-decoration: none; }
.volver-tienda:hover { text-decoration: underline; }
.pagina-confirmacion { max-width: 30rem; margin: 4rem auto; background: var(--color-superficie); padding: 2rem; border-radius: .75rem; text-align: center; }
.pagina-confirmacion-ancha { max-width: 40rem; text-align: left; }
.pagina-confirmacion-ancha .tabla { margin: 1.5rem 0; }
.pagina-confirmacion-ancha .carrito-total { margin-bottom: .5rem; }
.pagina-confirmacion-ancha .panel-forma-pago { text-align: left; margin: 1rem 0; }
.acciones-pago-retorno { display: flex; flex-direction: column; gap: 1rem; margin: 1.5rem 0; text-align: left; }
.acciones-pago-retorno .btn { align-self: center; }
@media (max-width: 640px) {
  .producto-detalle-grid { grid-template-columns: 1fr; }
}

.oculto { display: none; }
/* Oculta visualmente pero deja disponible para lectores de pantalla - para
   labels de campos cuyo placeholder ya explica el campo visualmente (ej.
   el input de Daniela) pero que igual necesitan un <label> real. */
.oculto-visualmente {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.5); display: flex; align-items: center; justify-content: center; }
.modal.oculto { display: none; }
.modal-contenido { background: var(--color-superficie); padding: 1.5rem; border-radius: .75rem; max-width: 24rem; }
.modal-contenido-formulario {
  max-width: 30rem;
  width: 90vw;
  max-height: 85vh;
  overflow-y: auto;
}

/* ---- Modal flotante del panel administrativo ----
   "Editar" en Inventario y en Descuentos, y "Aplicar a productos" de un
   descuento, abrian esa pagina en una pestaña nueva: soluciona lo de no
   perder de vista la lista de donde se partio, pero cambia por completo de
   ventana. Ahora abren la misma pagina, sin ningun cambio, dentro de un
   iframe dentro de una ventana flotante sobre la lista - se ve, se edita y
   se cierra sin salir de donde se estaba. Ver crearModalFlotante() en
   backend.js. Al cerrarse, la lista de atras se recarga sola para reflejar
   cualquier cambio guardado adentro. */
.modal-contenido-flotante {
  background: var(--color-fondo);
  padding: 0;
  display: flex;
  flex-direction: column;
  width: 94vw;
  max-width: 68rem;
  height: 90vh;
  max-height: 90vh;
  border-radius: .75rem;
  overflow: hidden;
}
.modal-flotante-barra {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: .6rem 1rem;
  background: var(--color-primario);
  color: white;
  flex-shrink: 0;
}
.modal-flotante-barra span {
  font-size: .85rem;
  opacity: .8;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.modal-flotante-cerrar {
  background: none;
  border: 1px solid rgba(255, 255, 255, .4);
  color: white;
  border-radius: .4rem;
  padding: .3rem .75rem;
  cursor: pointer;
  font-size: .85rem;
  flex-shrink: 0;
}
.modal-flotante-cerrar:hover { background: rgba(255, 255, 255, .15); }
.modal-flotante-cuerpo { position: relative; flex: 1; min-height: 0; }
.modal-flotante-cuerpo iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: none;
  background: var(--color-superficie);
}
.modal-flotante-cargando {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-fondo);
  color: var(--color-texto);
  font-size: .9rem;
}
.modal-flotante-cargando.oculto { display: none; }
@media (max-width: 640px) {
  .modal-contenido-flotante {
    width: 100vw;
    max-width: 100vw;
    height: 100vh;
    max-height: 100vh;
    border-radius: 0;
  }
}

/* ---- Visor de zoom de la ficha de producto ---- */
.modal-zoom { background: rgba(0,0,0,.85); }
.modal-contenido-zoom {
  background: transparent; padding: 0; max-width: 90vw; width: auto;
  display: flex; align-items: center; justify-content: center; position: relative;
}
.modal-contenido-zoom img { max-width: 90vw; max-height: 82vh; object-fit: contain; border-radius: .4rem; }
.zoom-cerrar {
  position: absolute; top: -2.75rem; right: 0; background: none; border: none;
  color: white; font-size: 1rem; cursor: pointer; padding: .4rem .6rem;
}
.zoom-cerrar:hover { text-decoration: underline; }
.zoom-nav {
  position: absolute; top: 50%; transform: translateY(-50%); width: 2.75rem; height: 2.75rem;
  border-radius: 50%; border: none; background: rgba(255,255,255,.15); color: white;
  font-size: 1.4rem; cursor: pointer; display: flex; align-items: center; justify-content: center;
}
.zoom-nav:hover { background: rgba(255,255,255,.3); }
.zoom-anterior { left: -1.25rem; }
.zoom-siguiente { right: -1.25rem; }
.zoom-contador {
  position: absolute; bottom: -2rem; left: 50%; transform: translateX(-50%);
  color: white; font-size: .85rem; margin: 0; font-variant-numeric: tabular-nums;
}
@media (max-width: 640px) {
  .zoom-anterior { left: .25rem; }
  .zoom-siguiente { right: .25rem; }
}

/* ---- Carrito de compras ---- */
.carrito-pagina { padding: 2rem; max-width: 40rem; margin: 0 auto; }
.carrito-lista { display: flex; flex-direction: column; gap: .75rem; margin: 1.5rem 0; }
.carrito-item {
  background: var(--color-superficie); border-radius: .5rem; padding: .75rem 1rem;
  display: grid; grid-template-columns: 3rem 1fr 4rem 5rem auto; gap: .75rem; align-items: center;
}
.carrito-item-info { display: flex; flex-direction: column; }
.carrito-cantidad { width: 100%; padding: .3rem; border: 1px solid var(--color-borde); border-radius: .3rem; background: var(--color-superficie); color: var(--color-texto); }
.carrito-subtotal { font-weight: 600; text-align: right; }
.carrito-resumen { background: var(--color-superficie); border-radius: .75rem; padding: 1.5rem; margin-top: 1.5rem; }
.carrito-total { font-size: 1.25rem; font-weight: 700; color: var(--color-acento); margin-bottom: 1rem; }
@media (max-width: 640px) {
  .carrito-item { grid-template-columns: 2.5rem 1fr; grid-template-areas: "img info" "cantidad subtotal" "quitar quitar"; }
}

/* ---- Backend / Admin ---- */
.panel-header {
  display: flex; justify-content: space-between; align-items: center; padding: 1rem 2rem;
  background: var(--negro-encabezado);
  color: var(--dorado-texto); flex-wrap: wrap; gap: 1rem;
  text-shadow: 0 1px 4px rgba(0, 0, 0, .7);
}
.panel-header-derecha { display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap; }
.panel-nav { display: flex; gap: 1rem; }
.panel-nav a { color: var(--dorado-texto); text-decoration: none; opacity: .85; padding-bottom: .2rem; border-bottom: 2px solid transparent; white-space: nowrap; }
.panel-nav a:hover { opacity: 1; text-decoration: underline; }
.panel-nav a.panel-nav-activo { opacity: 1; font-weight: 600; border-bottom-color: var(--color-acento); }
/* En celular, el titulo (h1) de cada pantalla del panel usaba el tamano
   por defecto del navegador (~2rem, mas grueso por ser h1) y el menu de
   arriba (Inventario/Ventas/Administrativo) se partia en 2-3 lineas
   irregulares debajo de el, empujando el boton "Salir" mas abajo - entre
   eso y el sub-menu de cada seccion (tambien partido en varias lineas)
   se podia ir mas de media pantalla en puro encabezado antes de llegar al
   contenido real. Aqui se achica el titulo, y tanto el menu superior como
   los sub-menus (.subnav) pasan a ser una sola fila que se desliza de
   lado (como las pestañas de una app) en vez de partirse en varias
   lineas - mucho menos scroll para llegar a lo que importa. */
@media (max-width: 640px) {
  .panel-header { padding: 1rem 1.1rem; gap: .6rem; }
  .panel-header h1 { font-size: 1.2rem; margin: 0; }
  .panel-header-derecha { flex-direction: column; align-items: stretch; width: 100%; gap: .6rem; }
  .panel-nav {
    overflow-x: auto; flex-wrap: nowrap; -webkit-overflow-scrolling: touch;
    padding-bottom: .2rem; gap: 1.1rem;
  }
  .panel-nav a { flex: none; font-size: .95rem; }
  .btn-salir, .btn-tienda { align-self: flex-end; }
  .panel-contenido { padding: 1.25rem 1rem; }
  .subnav, .subnav-secundario {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    padding-bottom: .3rem;
  }
  .subnav a, .subnav-secundario a { flex: none; }
}
.btn-salir {
  color: white; text-decoration: none; padding: .4rem .9rem; border-radius: .4rem;
  border: 1px solid rgba(255, 255, 255, .4); background: rgba(255, 255, 255, .08);
  font-size: .85rem; white-space: nowrap;
}
.btn-salir:hover { background: rgba(255, 255, 255, .2); }
/* Desde el panel administrativo no habia ninguna forma de volver a ver la
   tienda en linea tal como la ve un cliente (para revisar como se ve un
   cambio recien guardado, por ejemplo) sin borrar la URL a mano. Se abre en
   pestaña nueva (target="_blank") para no perder el lugar donde se estaba
   trabajando en el panel. Mismo tamaño/forma que "Salir" pero con el
   borde/texto en dorado (--color-acento) para no confundirse con el boton
   de cerrar sesion. */
.btn-tienda {
  color: var(--color-acento); text-decoration: none; padding: .4rem .9rem; border-radius: .4rem;
  border: 1px solid var(--color-acento); background: transparent;
  font-size: .85rem; white-space: nowrap;
}
.btn-tienda:hover { background: rgba(166, 129, 62, .15); }
.panel-contenido { padding: 2rem; }
/* v1.9: en pantallas anchas el contenido del panel (Administrativo,
   Inventario, Ventas) queda centrado en vez de pegado a la izquierda.
   v1.19: todas las pantallas del panel usan este mismo ancho (antes habia
   variantes de 34rem y 70rem que dejaban unas pantallas muy angostas). Los
   formularios largos se acomodan en dos columnas con .formulario-columnas. */
.panel-contenido { max-width: 90rem; margin-left: auto; margin-right: auto; }
/* .nota y las que siguen (badges, mensajes, filas resaltadas) se dejan a
   proposito como cajas claras (crema/verde/rojo/amarillo) sobre el fondo
   oscuro del panel - funcionan como una "etiqueta"/aviso que resalta, igual
   que en un tablero oscuro tipico. Como el texto normal del sitio
   (--color-texto) ahora es claro, cada una necesita su propio color de
   texto oscuro explicito - si no, quedaria texto claro sobre fondo claro. */
.nota { background: #faf3e2; color: #3a2f1f; border-left: 4px solid var(--color-acento); padding: .75rem 1rem; margin-bottom: 1.5rem; }
/* Para mensajes de texto libre capturados por el administrador (ej. el
   mensaje de pago en efectivo en /admin/pagos) que se muestran tal cual en
   la tienda - respeta los saltos de linea que haya escrito sin necesidad
   de convertirlos a <br/> a mano. */
.texto-libre { white-space: pre-line; }
.nota-error { background: #fdecea; color: #6b1f15; border-left-color: #c0392b; }
.nota-error ul { margin: .5rem 0 0; padding-left: 1.25rem; }
.nota-advertencia { background: #fff4e0; color: #5c4108; border-left-color: #d9922a; }
.nota-advertencia ul { margin: .5rem 0 0; padding-left: 1.25rem; }

/* Aviso de nivel 2 de bloqueo por pago (ver Fase 2 en NOTAS-PROYECTO.md):
   barra angosta arriba del todo, antes del header del panel - se ve en
   cualquier pagina de Backend/Administrativo mientras el Administrador del
   cliente tenga sesion iniciada y el nivel siga en 2. Mismos colores que
   .nota-advertencia (ambar) pero como franja de ancho completo, no una
   tarjeta con margenes. */
.aviso-bloqueo-nivel2 {
  background: #fff4e0;
  color: #5c4108;
  border-bottom: 1px solid #d9922a;
  padding: .6rem 1.5rem;
  text-align: center;
  font-size: .85rem;
  font-weight: 600;
}
.subnav { display: flex; gap: 1.5rem; margin-bottom: 1.5rem; border-bottom: 1px solid var(--color-borde); flex-wrap: wrap; }
.subnav a { padding: .5rem 0; color: var(--color-texto-muted); text-decoration: none; border-bottom: 2px solid transparent; }
.subnav a:hover { color: var(--color-acento); }
.subnav a.subnav-activo { color: var(--color-acento); border-bottom-color: var(--color-acento); font-weight: 600; }
.subnav-secundario { gap: 1.25rem; margin-top: -.75rem; margin-bottom: 1.5rem; border-bottom-color: var(--color-borde); }
.subnav-secundario a { padding: .35rem 0; font-size: .88rem; }
.subnav-secundario a.subnav-activo { border-bottom-color: var(--color-texto-muted); }
.tabla { width: 100%; border-collapse: collapse; background: var(--color-superficie); }
.tabla th, .tabla td { text-align: left; padding: .6rem .8rem; border-bottom: 1px solid var(--color-borde); }
.tabla th.num, .tabla td.num { text-align: right; font-variant-numeric: tabular-nums; }
.badge { padding: .15rem .5rem; border-radius: 999px; font-size: .75rem; background: var(--color-borde); color: var(--color-texto); }
.badge-activo, .badge-pagado { background: #d4f7dc; color: #1c4a2a; }
.badge-inactivo { background: #f7d4d4; color: #5c1f1f; }
.badge-enviado, .badge-entregado { background: #d4e6f7; color: #1c3a5c; }
.select-estado {
  padding: .3rem .5rem; border-radius: .4rem; border: 1px solid var(--color-borde);
  font: inherit; font-size: .8rem; background: #d4f7dc; color: #1c4a2a;
}
.select-estado.select-estado-inactivo { background: #f7d4d4; color: #5c1f1f; }
.select-estado:disabled { background: var(--color-borde); color: var(--color-texto-muted); cursor: not-allowed; }
.nota-sin-existencias { display: block; font-size: .72rem; color: var(--color-texto-muted); margin-top: .2rem; }
.input-tabla {
  padding: .3rem .4rem; border: 1px solid var(--color-borde); border-radius: .4rem;
  font: inherit; font-size: .85rem; background: var(--color-superficie); color: var(--color-texto);
}
.input-tipo { width: 7rem; }
.input-precio { width: 4.5rem; }
.input-existencias { width: 4rem; }
.fila-alerta td { background: #fff4e0; color: #5c4108; }
/* Pocas existencias (Backend > Inventario): amarillo mas saturado que
   .fila-alerta (que es para datos incompletos) para que se distinga de esa
   otra alerta - ver UMBRAL_STOCK_BAJO en lib/inventario.ts. */
.celda-existencias-bajas { background: #fff3b0; border-radius: .4rem; }
.nota-existencias-bajas { display: block; font-size: .72rem; color: #8a6d00; margin-top: .2rem; font-weight: 600; }
.tarjetas { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.tarjeta { background: var(--color-superficie); padding: 1.25rem 1.5rem; border-radius: .75rem; text-align: center; min-width: 9rem; flex: 1; }
.tarjeta .numero { display: block; font-size: 1.75rem; font-weight: 700; color: var(--color-acento); white-space: nowrap; }

/* ---- Formularios de inventario ---- */
.panel-acciones { margin-bottom: 1rem; display: flex; gap: .75rem; flex-wrap: wrap; align-items: center; }
.panel-acciones select { padding: .5rem .7rem; border: 1px solid var(--color-borde); border-radius: .4rem; font: inherit; background: var(--color-superficie); color: var(--color-texto); }
.btn {
  display: inline-block; background: var(--color-primario); color: white;
  padding: .55rem 1.1rem; border-radius: .4rem; border: none; cursor: pointer;
  text-decoration: none; font-size: .95rem;
}
.btn:hover { opacity: .9; }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:disabled:hover { opacity: .5; }
.formulario { display: flex; flex-direction: column; gap: .5rem; max-width: 30rem; }
.formulario input, .formulario select, .formulario textarea {
  padding: .5rem; border: 1px solid var(--color-borde); border-radius: .4rem; width: 100%; font: inherit;
  background: var(--color-superficie); color: var(--color-texto);
}
.formulario label { font-size: .85rem; color: var(--color-texto-muted); margin-top: .3rem; }
/* Atributo hidden siempre gana (campo de correo del checkout, v1.7) */
[hidden] { display: none !important; }
/* Logo propio subido en /admin/negocio (v1.6) */
.logo-propio { max-height: 2.6rem; width: auto; }
.logo-propio-vista { max-height: 4rem; width: auto; background: #222; padding: .3rem; border-radius: .3rem; }
/* Selector Meta / OpenWA de /admin/mensajes (v1.5) */
.selector-proveedor-whatsapp {
  border: 1px solid var(--color-borde); border-radius: .4rem; padding: .6rem .8rem;
  display: flex; flex-direction: column; gap: .35rem; margin: 0;
}
.selector-proveedor-whatsapp legend { font-weight: 600; padding: 0 .3rem; }
.selector-proveedor-whatsapp label { display: flex; align-items: center; gap: .5rem; margin-top: 0; }
.selector-proveedor-whatsapp input[type="radio"] { width: auto; padding: 0; margin: 0; }
.formulario-en-linea {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap: .75rem 1rem; max-width: none; align-items: end;
}
.formulario-en-linea .ancho-completo { grid-column: 1 / -1; }
/* v1.19: formulario de dos columnas para pantallas de configuracion (Pagos,
   Mi negocio, Mensajes, Nuevo producto). Cada campo va en un <div class="campo">
   con su etiqueta, su caja y su ayuda; .ancho-completo ocupa las dos columnas.
   En celular queda en una sola columna. */
.formulario-columnas {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: .9rem 1.5rem; max-width: none; align-items: start;
}
.formulario-columnas .campo { display: flex; flex-direction: column; gap: .35rem; }
.formulario-columnas .campo label { margin-top: 0; }
.formulario-columnas .campo .nota-pequena { margin: 0; }
.formulario-columnas .ancho-completo { grid-column: 1 / -1; }
.formulario-columnas > .btn { justify-self: start; }
.formulario-columnas + .formulario-columnas { margin-top: 1.25rem; }
@media (max-width: 900px) {
  .formulario-columnas { grid-template-columns: 1fr; }
}
.etiqueta-seccion { font-weight: 600; margin: 1rem 0 0; font-size: .9rem; }
.opciones-pago { display: flex; flex-direction: column; gap: .5rem; margin: .35rem 0; }
.opcion-pago {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .65rem .9rem;
  border: 1.5px solid var(--color-borde);
  border-radius: .55rem;
  background: var(--color-superficie);
  cursor: pointer;
  font-size: .9rem;
  color: var(--color-texto);
  transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}
.opcion-pago:hover { border-color: var(--color-acento); }
.opcion-pago input { width: auto; margin: 0; accent-color: var(--color-acento); flex-shrink: 0; }
.opcion-pago-texto { flex: 1; font-weight: 500; }
.opcion-pago-tarjetas { display: flex; align-items: center; gap: .3rem; flex-shrink: 0; }
.opcion-pago-tarjetas img { height: 1.15rem; width: auto; display: block; border-radius: .15rem; }
/* Resaltado dorado (en vez del gris casi blanco de antes, que desaparecia
   sobre el nuevo fondo oscuro) para la forma de pago elegida. */
.opcion-pago-seleccionada {
  border-color: var(--color-acento);
  background: rgba(166, 129, 62, .16);
  box-shadow: 0 0 0 1px var(--color-acento);
}
.panel-forma-pago { margin: .25rem 0; }
.panel-forma-pago .nota { margin-bottom: 0; }
/* Lista de checkboxes para "Aplicar descuento(s) del catalogo" (ficha de
   Editar producto, Inventario) - reemplaza el <select multiple> nativo, que
   se veia con fondo blanco fijo del navegador sin importar el tema oscuro
   del panel y no dejaba distinguir bien que opciones estaban marcadas. */
.lista-checkbox {
  display: flex;
  flex-direction: column;
  gap: .25rem;
  max-height: 11rem;
  overflow-y: auto;
  border: 1px solid var(--color-borde);
  border-radius: .5rem;
  padding: .4rem;
  background: var(--color-fondo);
}
.opcion-checkbox {
  display: flex;
  align-items: center;
  gap: .55rem;
  padding: .45rem .6rem;
  border-radius: .4rem;
  cursor: pointer;
  font-size: .85rem;
  color: var(--color-texto);
}
.opcion-checkbox:hover { background: rgba(166, 129, 62, .12); }
.opcion-checkbox input { width: auto; margin: 0; accent-color: var(--color-acento); flex-shrink: 0; }
.tarjeta-seccion { background: var(--color-superficie); border-radius: .75rem; padding: 1.25rem 1.5rem; margin-bottom: 1.5rem; }
.tarjeta-seccion h2 { margin-top: 0; font-size: 1.1rem; }
.reporte-barra-pista { background: var(--color-borde); border-radius: 999px; height: .5rem; width: 100%; min-width: 6rem; overflow: hidden; }
/* El ancho ya no se manda como "style=width:X%" inline (el CSP del sitio,
   style-src 'self', lo bloqueaba - ver data-porcentaje mas abajo y
   reportes-charts.js, que lo lee y pone el ancho por JS en vez de HTML). */
.reporte-barra-relleno { background: var(--color-acento); height: 100%; border-radius: 999px; width: 0; }
.mensaje:empty, .nota-pequena:empty { display: none; }
.mensaje { background: #d4f7dc; color: #1c4a2a; padding: .6rem 1rem; border-radius: .4rem; margin-bottom: 1rem; }
.mensaje.mensaje-error { background: #fbe0dd; color: #8a2c1f; }
.mensaje.mensaje-error a { color: #8a2c1f; font-weight: 600; }
.nota-pequena { background: transparent; border: none; color: var(--color-texto-muted); font-size: .8rem; padding: 0; }
.miniatura { width: 2.5rem; height: 2.5rem; object-fit: cover; border-radius: .3rem; display: block; }
.miniatura-vacia { width: 2.5rem; height: 2.5rem; background: var(--color-borde); border-radius: .3rem; display: block; }
.galeria { display: flex; flex-wrap: wrap; gap: 1rem; margin-bottom: 1rem; }
.imagen-card { background: var(--color-superficie); border-radius: .5rem; padding: .5rem; width: 9rem; text-align: center; }
.imagen-card img { width: 100%; height: 6rem; object-fit: cover; border-radius: .4rem; }
.imagen-acciones { display: flex; flex-direction: column; gap: .25rem; margin-top: .4rem; }
.imagen-acciones form button { font-size: .75rem; padding: .3rem; width: 100%; }
.formulario-imagen { display: flex; gap: .5rem; align-items: center; }
/* Video de producto (Inventario > editar): misma tarjeta que .imagen-card
   pero mas ancha, para que el reproductor se vea a un tamano razonable en
   vez de un recuadro diminuto. */
.video-card { background: var(--color-superficie); border-radius: .5rem; padding: .5rem; width: 18rem; text-align: center; }
.video-card video { width: 100%; max-height: 14rem; border-radius: .4rem; display: block; background: #000; }
.video-card form { margin-top: .4rem; }
.btn-link-peligro {
  background: none; border: none; color: #e0685a; text-decoration: underline;
  cursor: pointer; padding: 0; font: inherit;
}
/* Boton solido "Descartar cambios" del aviso de cierre sin guardar (ver
   backend.js) - mismo tono rojo que .btn-link-peligro, pero como boton
   lleno porque aqui compite visualmente con "Guardar y cerrar". */
.btn-descartar-cambios { background: #b3372a; }
.btn-descartar-cambios:hover { background: #96271c; opacity: 1; }

/* ---- Tabla dinamica de Pedidos ---- */
.tabla-scroll { overflow-x: auto; }
.tabla-dinamica th.col-oculta, .tabla-dinamica td.col-oculta { display: none; }
.panel-columnas {
  background: var(--color-superficie); border-radius: .75rem; padding: 1rem 1.25rem; margin-bottom: 1rem;
  max-width: 26rem;
}
.lista-columnas { list-style: none; margin: 0 0 .75rem; padding: 0; display: flex; flex-direction: column; gap: .3rem; }
.item-columna {
  display: flex; align-items: center; gap: .5rem; background: var(--color-superficie); border-radius: .4rem;
  padding: .4rem .6rem; cursor: grab; border: 1px solid var(--color-borde);
}
.item-columna.arrastrando { opacity: .5; }
.item-columna label { display: flex; align-items: center; gap: .4rem; font-size: .9rem; cursor: pointer; }
.manija-arrastre { color: var(--color-texto-muted); font-size: .9rem; cursor: grab; }
.acciones-columnas { display: flex; gap: .5rem; flex-wrap: wrap; }

/* ---- Plataforma (superusuario): plan y funcionalidades ---- */
.acciones-plan { display: flex; gap: .6rem; flex-wrap: wrap; margin-bottom: 1.2rem; }

/* Nivel de bloqueo por pago (Fase 2, /admin/plataforma) - 5 tarjetas de
   radio en vez del patron de "un boton por opcion" de .acciones-plan (ver
   el comentario junto a construirOpcionesNivelBloqueo en admin.routes.ts). */
.formulario-bloqueo-nivel { max-width: 36rem; }
.grupo-opciones-nivel-bloqueo { display: flex; flex-direction: column; gap: .5rem; margin-bottom: .5rem; }
.opcion-nivel-bloqueo {
  display: flex; align-items: flex-start; gap: .6rem; padding: .6rem .8rem;
  border: 1px solid var(--color-borde); border-radius: .5rem; cursor: pointer;
}
.opcion-nivel-bloqueo input { width: auto; margin-top: .2rem; }
.opcion-nivel-bloqueo-actual { border-color: var(--color-acento); background: rgba(217, 146, 42, .08); }

/* ---- Perfiles y accesos ---- */
.acciones-perfil { display: flex; flex-direction: column; gap: .4rem; min-width: 11rem; }
.formulario-en-linea-corto { display: flex; gap: .4rem; }
.formulario-en-linea-corto input, .formulario-en-linea-corto select { padding: .35rem .5rem; border: 1px solid var(--color-borde); border-radius: .4rem; font: inherit; font-size: .8rem; width: 100%; background: var(--color-superficie); color: var(--color-texto); }
.btn-pequeno { padding: .35rem .6rem; font-size: .8rem; white-space: nowrap; }

/* ---- Widget de chat: Daniela ---- */
/* Solo el icono, en cualquier tamaño de pantalla - el boton con todo el
   texto ("¿Dudas? Chatea con Daniela") se veia como una franja ancha fija
   encima del contenido. El texto sigue existiendo para lectores de
   pantalla via aria-label en el boton (ver inicializarWidgetDaniela en
   tienda.js) y ".daniela-boton-texto" se oculta visualmente aqui abajo. */
.daniela-boton {
  position: fixed; bottom: 1.75rem; right: 1.25rem; z-index: 1000;
  background: var(--color-acento); color: var(--color-primario); border: none;
  padding: 0; width: 4.2rem; height: 4.2rem; border-radius: 50%; cursor: pointer;
  box-shadow: 0 4px 12px rgba(0,0,0,.2); font-size: .9rem; font-weight: 600;
  display: inline-flex; align-items: center; justify-content: center;
}
.daniela-boton:hover { opacity: .92; }
.daniela-boton-icono { display: inline-flex; line-height: 1; }
.daniela-boton-icono svg { width: 2.5rem; height: 2.5rem; }
.daniela-boton-texto { display: none; }
@media (max-width: 480px) {
  .daniela-boton {
    width: 3.8rem; height: 3.8rem;
    bottom: 1.4rem; right: 1rem;
  }
  .daniela-boton-icono svg { width: 2rem; height: 2rem; }
}
.daniela-panel {
  position: fixed; bottom: 6.3rem; right: 1.25rem; z-index: 1000;
  width: 20rem; max-width: calc(100vw - 2.5rem); max-height: 28rem;
  background: var(--color-superficie); border-radius: .75rem; box-shadow: 0 8px 24px rgba(0,0,0,.25);
  display: flex; flex-direction: column; overflow: hidden;
}
.daniela-panel.oculto { display: none; }
.daniela-panel-header {
  background: var(--color-primario); color: white; padding: .75rem 1rem;
  display: flex; justify-content: space-between; align-items: center; font-size: .9rem;
}
.daniela-panel-header button {
  background: transparent; border: 1px solid rgba(255,255,255,.5); color: white;
  border-radius: 999px; padding: .2rem .6rem; font-size: .75rem; cursor: pointer;
}
.daniela-mensajes {
  flex: 1; overflow-y: auto; padding: .75rem 1rem;
  display: flex; flex-direction: column; gap: .5rem;
}
.daniela-mensaje { margin: 0; padding: .5rem .7rem; border-radius: .6rem; font-size: .85rem; max-width: 85%; }
.daniela-mensaje-agente { background: var(--color-borde); color: var(--color-texto); align-self: flex-start; }
.daniela-mensaje-escribiendo { font-style: italic; color: var(--color-texto-muted); }
.daniela-mensaje-usuario { background: var(--color-acento); color: var(--color-primario); align-self: flex-end; }
.daniela-form { display: flex; gap: .5rem; padding: .75rem; border-top: 1px solid var(--color-borde); }
.daniela-form input { flex: 1; padding: .5rem; border: 1px solid var(--color-borde); border-radius: .4rem; font: inherit; background: var(--color-fondo); color: var(--color-texto); }
.daniela-form .btn { padding: .5rem .9rem; font-size: .85rem; }
@media (max-width: 480px) {
  .daniela-panel { right: .75rem; left: .75rem; width: auto; bottom: 5.6rem; }
  .daniela-boton { right: .75rem; }
}

/* ---- Auth ---- */
.auth-box { max-width: 22rem; margin: 4rem auto; background: var(--color-superficie); padding: 2rem; border-radius: .75rem; }
.auth-box form { display: flex; flex-direction: column; gap: .5rem; }
.auth-box input { padding: .5rem; border: 1px solid var(--color-borde); border-radius: .4rem; background: var(--color-fondo); color: var(--color-texto); }
.auth-box button { margin-top: .5rem; padding: .6rem; background: var(--color-primario); color: white; border: none; border-radius: .4rem; cursor: pointer; }
.error:empty { display: none; }
.error { color: #e0685a; }

/* ---- Reportes: graficas ---- */
.grafica-envoltura { position: relative; margin-bottom: .75rem; }
.grafica-svg { width: 100%; height: auto; display: block; overflow: visible; }
.grafica-svg:focus { outline: 2px solid var(--color-primario); outline-offset: 4px; border-radius: .3rem; }
.grafica-svg-barras, .grafica-svg-columnas { overflow: visible; }
.grafica-gridline { stroke: #e1e0d9; stroke-width: 1; }
.grafica-eje-texto { fill: #767566; font-size: 10px; font-variant-numeric: tabular-nums; }
.grafica-eje-texto-categoria { font-size: 11px; }
.grafica-etiqueta-directa, .grafica-valor-directo { fill: #16181d; font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
.grafica-crosshair { stroke: #c3c2b7; stroke-width: 1; }
.grafica-pista { fill: #f2f1ec; }
.grafica-barra { transition: opacity .1s ease; }
.grafica-barra-activa { opacity: .82; }
.grafica-vacia { color: var(--color-texto-muted); padding: 1.5rem 0; text-align: center; }

.grafica-tooltip {
  position: absolute;
  pointer-events: none;
  background: #16181d;
  color: white;
  padding: .45rem .65rem;
  border-radius: .4rem;
  font-size: .78rem;
  line-height: 1.4;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .18);
  z-index: 5;
  max-width: 14rem;
}
.grafica-tooltip.oculto { display: none; }
.grafica-tooltip-fila { display: flex; align-items: baseline; gap: .35rem; white-space: nowrap; }
.grafica-tooltip-llave { width: .55rem; height: .55rem; border-radius: 50%; flex: none; }
.grafica-tooltip-fila strong { font-variant-numeric: tabular-nums; }
.hint { color: var(--color-texto-muted); font-size: .8rem; }

/* ---- Resumen de Mercado Libre (Inventario > Editar producto) ----
   Solo de consulta: comision, envio y ganancia neta que ya se guardaron en
   "precios" (autocompletados al publicar, o corregidos a mano). Es una
   lista de definicion en dos columnas, con el ultimo renglon (la ganancia
   neta) resaltado para que sea lo primero que se note. */
.resumen-ml { display: flex; flex-direction: column; gap: 0; margin: 0; }
.resumen-ml > div {
  display: flex; justify-content: space-between; gap: 1rem;
  padding: .55rem 0; border-bottom: 1px solid var(--color-borde);
}
.resumen-ml > div:first-child { padding-top: 0; }
.resumen-ml dt { margin: 0; color: var(--color-texto-muted); }
.resumen-ml dd { margin: 0; font-variant-numeric: tabular-nums; text-align: right; }
.resumen-ml-total { border-bottom: none !important; margin-top: .1rem; }
.resumen-ml-total dt, .resumen-ml-total dd { color: var(--color-acento); font-weight: 700; font-size: 1.05rem; }

/* ---- Guia de temporadas (Inventario > Descuentos) ----
   Cuadricula de tarjetas, una por temporada (Buen Fin, Hot Sale, Dia de las
   Madres...), cada una con su boton "Usar esta temporada" (ver backend.js).
   Fondo --color-fondo (mas oscuro que --color-superficie de la tarjeta que
   las contiene) para que se note un escalon sutil, igual que .imagen-card
   con el resto del panel. */
.temporadas-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr)); gap: .9rem; margin-top: .75rem; }
.temporada-card {
  background: var(--color-fondo); border: 1px solid var(--color-borde); border-radius: .6rem;
  padding: .9rem 1rem; display: flex; flex-direction: column; gap: .4rem;
}
.temporada-card h3 { margin: 0; font-size: 1rem; }
.temporada-fechas { margin: 0; font-size: .85rem; color: var(--color-acento); font-weight: 600; }
.temporada-card .nota-pequena { flex: 1; }
.temporada-card .btn { align-self: flex-start; margin-top: .2rem; }

/* ---- Badge "ML" (identifica datos de Mercado Libre) ----
   Se usa como prefijo en encabezados de seccion/pagina, encabezados de
   columna de tabla y el link de "Mercado Libre" del subnav, en las
   pantallas donde se muestran datos que vienen de Mercado Libre (no en
   menciones sueltas dentro de un parrafo, ni en los badges de
   activo/inactivo que ya existen para otra cosa). Tamano fijo en rem para
   que se vea igual de bien junto a un <h1> que junto a un link de subnav
   o un <th>. No es una copia del logotipo oficial de Mercado Libre (no se
   pudo descargar el archivo real en este entorno) - es un badge propio con
   los colores oficiales de la marca. */
.icono-ml {
  display: inline-flex; align-items: center; justify-content: center;
  height: 1.15rem; padding: 0 .32rem; margin-right: .4rem;
  border-radius: .25rem; background: var(--ml-amarillo); color: var(--ml-azul);
  font-size: .62rem; font-weight: 800; letter-spacing: .02em; line-height: 1;
  vertical-align: middle;
}
h1 .icono-ml, h2 .icono-ml { height: 1.3rem; font-size: .68rem; }
.subnav a .icono-ml { margin-right: .35rem; }

/* ---- Reportes: layout tipo BI (tablero en cuadricula) ----
   Clases nuevas y aditivas, scoped a Reportes - no se toca .tarjeta/.tarjetas
   base porque esas se reusan en Perfiles, Inventario, Quejas, Pedidos ML,
   etc. y un cambio ahi se veria en todo el sitio. */
.dashboard-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.25rem; align-items: start; }
.dashboard-grid > .tarjeta-seccion { margin-bottom: 0; }
.dashboard-grid > .col-full { grid-column: 1 / -1; }
@media (max-width: 900px) {
  .dashboard-grid { grid-template-columns: 1fr; }
}

.tarjetas-reportes { display: flex; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
.tarjeta-reportes {
  display: flex; align-items: center; gap: .9rem; background: var(--color-superficie); padding: 1.1rem 1.4rem;
  border-radius: .75rem; min-width: 11rem; flex: 1;
}
.tarjeta-reportes-icono {
  display: flex; align-items: center; justify-content: center; flex: none;
  width: 2.75rem; height: 2.75rem; border-radius: .6rem; background: var(--color-borde); color: var(--color-texto);
  font-size: 1.3rem; font-weight: 700;
}
.tarjeta-reportes-icono svg { width: 1.4rem; height: 1.4rem; }
.tarjeta-reportes-icono-acento { background: rgba(166, 129, 62, .18); color: var(--color-acento); }
.tarjeta-reportes-cuerpo { display: flex; flex-direction: column; }
.tarjeta-reportes-cuerpo .numero { font-size: 1.5rem; font-weight: 700; white-space: nowrap; }
.tarjeta-reportes-etiqueta { font-size: .8rem; color: var(--color-texto-muted); }

.tarjeta-grafica-header { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; margin-bottom: .25rem; }
.tarjeta-grafica-header h2, .tarjeta-grafica-header h3 { margin: 0; }
.tarjeta-grafica-total { font-size: 1.05rem; font-weight: 700; color: var(--color-acento); white-space: nowrap; }

.detalle-tabla { margin-top: .75rem; }
.detalle-tabla summary {
  cursor: pointer; font-size: .85rem; color: var(--color-texto-muted); padding: .3rem 0; list-style: none;
}
.detalle-tabla summary::-webkit-details-marker { display: none; }
.detalle-tabla summary::before { content: "\25b8  "; }
.detalle-tabla[open] summary::before { content: "\25be  "; }
.detalle-tabla .tabla-scroll { margin-top: .5rem; }

/* ---- Reportes: tema oscuro tipo BI ----
   Scoped a .panel-contenido-oscuro (solo la pagina de Reportes) para no
   afectar el resto del panel administrativo, que sigue con el tema claro
   de siempre. */
.panel-contenido-oscuro {
  --rep-bg: #0e0f12;
  --rep-superficie: #1c1d22;
  --rep-borde: #34353c;
  --rep-texto: #f1efe7;
  --rep-texto-muted: #a8a49a;
  --rep-acento: #c6a15e;
  background: var(--rep-bg);
  color: var(--rep-texto);
}
.panel-contenido-oscuro .nota {
  background: var(--rep-superficie); border-left-color: var(--rep-acento); color: var(--rep-texto-muted);
}
.panel-contenido-oscuro .subnav { border-bottom-color: var(--rep-borde); }
.panel-contenido-oscuro .subnav a { color: var(--rep-texto-muted); }
.panel-contenido-oscuro .subnav a:hover { color: var(--rep-texto); }
.panel-contenido-oscuro .subnav a.subnav-activo { color: var(--rep-texto); border-bottom-color: var(--rep-acento); }
.panel-contenido-oscuro .subnav-secundario { border-bottom-color: var(--rep-borde); }
.panel-contenido-oscuro .subnav-secundario a.subnav-activo { border-bottom-color: var(--rep-texto-muted); }
.panel-contenido-oscuro a { color: var(--rep-acento); }
.panel-contenido-oscuro h1, .panel-contenido-oscuro h2, .panel-contenido-oscuro h3 { color: var(--rep-texto); }
.panel-contenido-oscuro .tarjeta-seccion { background: var(--rep-superficie); border: 1px solid var(--rep-borde); }
.panel-contenido-oscuro .tarjeta-reportes { background: var(--rep-superficie); border: 1px solid var(--rep-borde); }
.panel-contenido-oscuro .tarjeta-reportes-cuerpo .numero { color: var(--rep-texto); }
.panel-contenido-oscuro .tarjeta-reportes-etiqueta { color: var(--rep-texto-muted); }
.panel-contenido-oscuro .tarjeta-reportes-icono { background: rgba(255, 255, 255, .08); color: var(--rep-texto); }
.panel-contenido-oscuro .tarjeta-reportes-icono-acento { background: rgba(198, 161, 94, .18); color: var(--rep-acento); }
.panel-contenido-oscuro .tarjeta-grafica-total { color: var(--rep-acento); }
.panel-contenido-oscuro .detalle-tabla summary { color: var(--rep-texto-muted); }
.panel-contenido-oscuro .tabla { background: var(--rep-superficie); color: var(--rep-texto); }
.panel-contenido-oscuro .tabla th, .panel-contenido-oscuro .tabla td { border-bottom-color: var(--rep-borde); }
.panel-contenido-oscuro .hint, .panel-contenido-oscuro .nota-pequena { color: var(--rep-texto-muted); }
.panel-contenido-oscuro .reporte-barra-pista { background: rgba(255, 255, 255, .1); }

.panel-contenido-oscuro .grafica-gridline { stroke: var(--rep-borde); }
.panel-contenido-oscuro .grafica-crosshair { stroke: var(--rep-borde); }
.panel-contenido-oscuro .grafica-eje-texto { fill: var(--rep-texto-muted); }
.panel-contenido-oscuro .grafica-etiqueta-directa, .panel-contenido-oscuro .grafica-valor-directo { fill: var(--rep-texto); }
.panel-contenido-oscuro .grafica-pista { fill: rgba(255, 255, 255, .06); }
.panel-contenido-oscuro .grafica-vacia { color: var(--rep-texto-muted); }
.panel-contenido-oscuro .grafica-tooltip { background: #050505; box-shadow: 0 4px 16px rgba(0, 0, 0, .5); }

/* Combos de Reportes (v1.42): barra de filtros arriba y "que mostrar" en
   cada grafica. */
.filtros-reportes {
  display: flex; flex-wrap: wrap; align-items: flex-end; gap: .75rem 1rem;
  background: var(--rep-superficie); border: 1px solid var(--rep-borde); border-radius: .75rem;
  padding: .9rem 1rem; margin: 1rem 0;
}
.filtro-reportes-campo { display: flex; flex-direction: column; gap: .3rem; font-size: .78rem; color: var(--rep-texto-muted); flex: 1 1 10rem; min-width: 0; }
.filtros-reportes select,
.combo-metrica {
  padding: .45rem .6rem; border: 1px solid var(--rep-borde); border-radius: .45rem;
  background: var(--rep-bg); color: var(--rep-texto); font: inherit; font-size: .85rem; max-width: 100%;
}
.filtro-reportes-acciones { display: flex; align-items: center; gap: .75rem; }
.filtro-reportes-quitar { font-size: .85rem; }
.filtro-reportes-resumen { flex: 1 1 100%; margin: 0; font-size: .8rem; color: var(--rep-texto-muted); }
.filtro-reportes-resumen strong { color: var(--rep-texto); }
.tarjeta-grafica-header { flex-wrap: wrap; }
.tarjeta-grafica-acciones { display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; }
.combo-metrica { font-size: .78rem; padding: .3rem .5rem; }

/* ---- Backend/Admin: presentacion mas profesional ----
   Mismo criterio que "Tienda: rediseño" (ver "body.tienda" mas abajo): en
   vez de tocar las reglas base (.btn, .tabla, .formulario, .nota...) que
   comparten tienda y panel, todo esto va detras de selectores que empiezan
   en "body.panel" (la clase que render.ts le pone al <body> de cualquier
   vista que no sea de "frontend/" - o sea Backend, Administrativo Y Login,
   ver PATRON_TIENDA/bodyClass en render.ts) para no arriesgar nada de la
   tienda publica.

   El panel ya tenia el mismo negro/dorado de marca (--negro-encabezado en
   el encabezado, --color-acento en botones/enlaces), pero con la fuente
   generica del sistema, tablas sueltas sin borde, formularios sin foco
   visible y avisos/badges en pastel claro (verde/rojo/amarillo "de
   formulario de los 2000") que desentonaban fuerte contra el fondo negro -
   se sentia mucho menos cuidado que la tienda. Aqui se le da el mismo
   tratamiento: tipografia con caracter (Fraunces en titulos, igual que el
   hero), botones y campos con transiciones, tablas envueltas en una
   tarjeta con esquinas redondeadas, y los avisos/badges pasados a version
   oscura translucida en vez de pastel solido. */
body.panel {
  font-family: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
}
body.panel h1,
body.panel h2,
body.panel h3 {
  font-family: "Fraunces", Georgia, "Times New Roman", serif;
  font-weight: 600;
  letter-spacing: -.01em;
}
body.panel :focus-visible {
  outline: 2px solid var(--color-acento);
  outline-offset: 2px;
}

/* Encabezado superior: mismo negro/dorado de siempre, solo con mas aire,
   una sombra sutil que lo separa del contenido al hacer scroll, y el
   titulo en Fraunces en vez de la fuente del sistema. */
body.panel .panel-header {
  padding: 1.15rem 2rem;
  box-shadow: 0 4px 18px rgba(0, 0, 0, .35);
  position: relative;
  z-index: 10;
}
body.panel .panel-header h1 {
  font-size: 1.35rem;
  margin: 0;
}
body.panel .panel-nav a {
  font-family: "Inter", system-ui, sans-serif;
  font-size: .86rem;
  transition: opacity .15s ease, border-color .15s ease;
}
body.panel .panel-nav a:hover { text-decoration: none; border-bottom-color: rgba(212, 175, 55, .5); }
body.panel .btn-salir,
body.panel .btn-tienda {
  border-radius: 999px;
  font-weight: 600;
  transition: background .15s ease, opacity .15s ease, border-color .15s ease;
}

body.panel .panel-contenido { padding: 2.25rem 2rem; }
@media (max-width: 640px) {
  body.panel .panel-contenido { padding: 1.25rem 1rem; }
}

/* Sub-menus de cada seccion */
body.panel .subnav a,
body.panel .subnav-secundario a {
  transition: color .15s ease, border-color .15s ease;
  font-weight: 500;
}

/* Botones: mismo gradiente dorado que "Agregar al carrito" en la tienda,
   en vez del negro casi invisible sobre el fondo tambien negro que tenia
   el .btn base (--color-primario #16181d contra --color-fondo #1c1e23). */
body.panel .btn {
  font-family: "Inter", system-ui, sans-serif;
  font-weight: 600;
  font-size: .9rem;
  padding: .6rem 1.2rem;
  border-radius: .5rem;
  background: linear-gradient(180deg, #b8925a, var(--color-acento));
  color: #1a1408;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .35);
  transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease;
}
body.panel .btn:hover { opacity: 1; transform: translateY(-1px); box-shadow: 0 6px 16px rgba(166, 129, 62, .3); }
body.panel .btn:active { transform: translateY(0); }
body.panel .btn.btn-secundario {
  background: transparent;
  color: var(--color-texto);
  border: 1.5px solid var(--color-borde);
  box-shadow: none;
}
body.panel .btn.btn-secundario:hover { border-color: var(--color-acento); background: rgba(166, 129, 62, .1); color: var(--color-texto); }
body.panel .btn:disabled,
body.panel .btn:disabled:hover { background: var(--color-borde); color: var(--color-texto-muted); box-shadow: none; transform: none; opacity: 1; }
body.panel .btn-pequeno { padding: .4rem .8rem; font-size: .8rem; border-radius: .4rem; }
body.panel .btn-descartar-cambios { background: #b3372a; color: white; }
body.panel .btn-descartar-cambios:hover { background: #96271c; opacity: 1; }
body.panel .btn-link-peligro { transition: opacity .15s ease; }

/* Campos de formulario: mismo anillo de foco dorado que la tienda, en vez
   del borde gris por defecto sin ningun aviso visual al enfocar. */
body.panel input:not([type="checkbox"]):not([type="radio"]),
body.panel select,
body.panel textarea {
  border-radius: .5rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
body.panel input:not([type="checkbox"]):not([type="radio"]):focus,
body.panel select:focus,
body.panel textarea:focus {
  outline: none;
  border-color: var(--color-acento);
  box-shadow: 0 0 0 3px rgba(166, 129, 62, .18);
}
body.panel .formulario label { font-weight: 500; }

/* Tablas: antes flotaban sueltas sobre el fondo (solo una linea debajo de
   cada fila); ahora van envueltas en una tarjeta con borde y esquinas
   redondeadas, encabezado en mayusculas pequeñas y una fila que se resalta
   un poco al pasar el cursor - mas facil de leer en tablas largas. */
body.panel .tabla-scroll {
  border: 1px solid var(--color-borde);
  border-radius: .75rem;
  overflow: hidden;
}
body.panel .tabla-scroll .tabla { border: none; }
body.panel .tabla th {
  background: rgba(255, 255, 255, .03);
  font-size: .72rem;
  text-transform: uppercase;
  letter-spacing: .06em;
  color: var(--color-texto-muted);
  font-weight: 600;
}
body.panel .tabla tbody tr { transition: background .1s ease; }
body.panel .tabla tbody tr:hover { background: rgba(255, 255, 255, .025); }
body.panel .tabla-scroll .tabla th:first-child,
body.panel .tabla-scroll .tabla td:first-child { padding-left: 1rem; }
body.panel .tabla-scroll .tabla th:last-child,
body.panel .tabla-scroll .tabla td:last-child { padding-right: 1rem; }

/* Tarjetas de resumen (numeros grandes arriba de las tablas) */
body.panel .tarjeta,
body.panel .tarjeta-seccion,
body.panel .tarjeta-reportes {
  border: 1px solid var(--color-borde);
  box-shadow: 0 1px 3px rgba(0, 0, 0, .25);
}

/* Avisos y badges: antes eran pastel solido (pensados para un fondo claro)
   sobre un fondo ahora negro - se veian "pegados". Version oscura
   translucida del mismo color, mas a tono con el resto del panel. */
body.panel .nota { background: rgba(166, 129, 62, .12); color: var(--color-texto); border-radius: .5rem; }
body.panel .nota-error { background: rgba(192, 57, 43, .16); color: var(--color-texto); border-left-color: #e0645a; }
body.panel .nota-advertencia { background: rgba(217, 146, 42, .16); color: var(--color-texto); border-left-color: #d9922a; }
body.panel .mensaje { background: rgba(46, 160, 90, .18); color: #bfeccd; border-radius: .5rem; }
body.panel .mensaje.mensaje-error { background: rgba(224, 101, 90, .18); color: #f6c6c0; }
body.panel .mensaje.mensaje-error a { color: #f6c6c0; }
body.panel .badge-activo, body.panel .badge-pagado { background: rgba(46, 160, 90, .2); color: #a4e6bb; }
body.panel .badge-inactivo { background: rgba(224, 101, 90, .2); color: #f6c6c0; }
body.panel .badge-enviado, body.panel .badge-entregado { background: rgba(90, 150, 224, .2); color: #b7d3f6; }
body.panel .select-estado { background: rgba(46, 160, 90, .2); color: #a4e6bb; border-color: var(--color-borde); }
body.panel .select-estado.select-estado-inactivo { background: rgba(224, 101, 90, .2); color: #f6c6c0; }
body.panel .fila-alerta td { background: rgba(217, 146, 42, .14); color: var(--color-texto); }
body.panel .celda-existencias-bajas { background: rgba(224, 189, 10, .16); }
body.panel .nota-existencias-bajas { color: #e3ca55; }

/* Login (/acceso-portal-9x2): antes era una tarjeta plana sin sombra ni
   borde, botones/inputs sin foco visible - se ve mas cuidado con el mismo
   tratamiento (sombra, radio, boton dorado con degradado) que el resto del
   panel ya rediseñado arriba. */
body.panel .auth-box {
  border: 1px solid var(--color-borde);
  border-radius: 1rem;
  padding: 2.5rem 2.25rem;
  box-shadow: 0 20px 48px rgba(0, 0, 0, .4);
}
body.panel .auth-box h1 {
  font-size: 1.4rem;
  text-align: center;
  margin: 0 0 1.5rem;
}
body.panel .auth-box label { font-size: .82rem; color: var(--color-texto-muted); font-weight: 500; }
body.panel .auth-box input {
  padding: .65rem .75rem;
  border-radius: .5rem;
  transition: border-color .15s ease, box-shadow .15s ease;
}
body.panel .auth-box input:focus {
  outline: none;
  border-color: var(--color-acento);
  box-shadow: 0 0 0 3px rgba(166, 129, 62, .18);
}
body.panel .auth-box button {
  margin-top: .75rem;
  padding: .7rem;
  border-radius: .5rem;
  background: linear-gradient(180deg, #b8925a, var(--color-acento));
  color: #1a1408;
  font-weight: 600;
  transition: transform .12s ease, box-shadow .12s ease;
}
body.panel .auth-box button:hover { transform: translateY(-1px); box-shadow: 0 6px 16px rgba(166, 129, 62, .3); }

/* ---- Cupon de descuento (checkout) ---- */
.bloque-cupon { display: flex; gap: .5rem; align-items: center; }
.bloque-cupon input { flex: 1; text-transform: uppercase; }
.bloque-cupon input::placeholder { text-transform: none; }

/* ---- Checkout en dos pasos (carrito y compra directa): paso 1 es
   nombre/contacto/direccion, paso 2 es forma de pago + cupon. Ver
   inicializarPasosCheckout() en tienda.js. ---- */
.checkout-pasos { display: flex; align-items: center; gap: .4rem; margin: 0 0 1.1rem; font-size: .8rem; color: var(--color-texto-muted); }
.checkout-paso-separador { color: var(--color-texto-muted); }
.checkout-paso-indicador { color: var(--color-texto-muted); }
.checkout-paso-indicador.checkout-paso-activo { color: var(--color-acento); font-weight: 600; }
.checkout-paso.oculto { display: none; }
.checkout-paso-nav { display: flex; justify-content: space-between; align-items: center; margin-top: 1.1rem; }
.checkout-paso-nav.checkout-paso-nav-derecha { justify-content: flex-end; }
.btn-link-simple {
  background: none; border: none; padding: 0; color: var(--color-acento);
  text-decoration: underline; cursor: pointer; font: inherit; font-size: .85rem;
}

/* ---- Sellos de confianza junto al boton de pago (checkout) ---- */
.checkout-confianza {
  display: flex; flex-wrap: wrap; gap: .6rem 1.2rem; margin-top: 1rem;
  padding-top: .9rem; border-top: 1px solid var(--color-borde);
}
.checkout-confianza-item {
  display: flex; align-items: center; gap: .4rem;
  font-size: .78rem; color: var(--color-texto-muted);
}
.checkout-confianza-item svg {
  width: 18px; height: 18px; flex-shrink: 0; color: var(--color-acento);
}

/* ---- Avisar cuando vuelva a haber existencias (ficha de producto) ---- */
.bloque-aviso-stock { margin: .75rem 0; }
.bloque-aviso-stock label { display: block; margin-bottom: .35rem; font-size: .9rem; }
.bloque-aviso-stock-campos { display: flex; gap: .5rem; flex-wrap: wrap; }
/* Sin min-width: 0, un input dentro de un flex nunca se encoge mas alla
   del ancho que le pida su contenido/placeholder (comportamiento por
   defecto del navegador) - en celular eso empujaba el ancho total de la
   pagina un poco mas alla de la pantalla (scroll horizontal de unos
   pixeles, dificil de notar pero ahi estaba). */
.bloque-aviso-stock-campos input { flex: 1; min-width: 0; }

/* ---- Barra de envio gratis (/carrito) ---- */
.barra-envio-gratis { margin: 1rem 0; }
.barra-envio-gratis p { margin: 0 0 .35rem; font-size: .9rem; font-weight: 600; }
.barra-envio-gratis-track { height: 8px; border-radius: 999px; background: var(--color-borde); overflow: hidden; }
.barra-envio-gratis-relleno { height: 100%; width: 0; background: var(--color-acento); border-radius: 999px; transition: width .3s ease; }

/* ---- Reseñas de producto ---- */
.estrellas { color: var(--color-acento); letter-spacing: .05em; }
.resenas-promedio { font-size: 1.05rem; }
.resenas-producto { margin-top: 2rem; }
.lista-resenas { display: flex; flex-direction: column; gap: .9rem; margin: 1rem 0; }
.resena { border-bottom: 1px solid var(--color-borde); padding-bottom: .9rem; }
.resena:last-child { border-bottom: none; padding-bottom: 0; }
.resena-encabezado { margin-bottom: .25rem; }

/* ---- Guia de tallas en la ficha de producto ---- */
.guia-tallas-producto { margin: .75rem 0; }

/* ---- Rastrear pedido ---- */
.resultado-seguimiento { margin-top: 1.5rem; }
.resultado-seguimiento ul { padding-left: 1.1rem; margin: .4rem 0; }
.solicitud-devolucion { margin-top: 1rem; }
.solicitud-devolucion summary { cursor: pointer; font-weight: 600; }
.solicitud-devolucion form { margin-top: .75rem; }

/* ---- Aviso de privacidad ---- */
.pagina-privacidad h2 { margin-top: 1.75rem; }
.pagina-privacidad ul { padding-left: 1.2rem; }
.pagina-privacidad li { margin-bottom: .3rem; }

/* =======================================================================
   ---- Tienda: rediseño ----
   Todo lo de aqui en adelante es exclusivo de la tienda en linea publica
   (Inicio, ficha de producto, carrito, confirmacion, seguimiento, aviso de
   privacidad) - el panel administrativo/backend no se toca. Dos formas de
   lograrlo:

   1) Clases que ya eran exclusivas de la tienda desde antes (.banner,
      .producto-card, .carrito-item, etc.) se ajustan directo - no las usa
      ninguna vista de Backend/Administrativo (confirmado por busqueda de
      texto en src/views/backend, src/views/admin y src/views/auth antes de
      escribir esto), asi que no hay riesgo de que el cambio se cuele ahi.

   2) Elementos GENERICOS que si comparte con el panel (.btn, .formulario,
      .modal, .nota, .mensaje, inputs/selects sueltos, la tabla de
      "Gracias por tu compra") se sobreescriben con el selector
      "body.tienda ..." en vez de tocar la regla base. <body> trae la
      clase "tienda" solo en las paginas de la tienda (ver bodyClass en
      lib/render.ts) - en el panel administrativo <body class="panel">
      nunca hace match con estos selectores, asi que la regla original
      sigue aplicando sin cambios ahi.

   Tipografia: Fraunces (serif con caracter, se siente a boutique/moda) para
   titulos, Inter para todo lo demas - antes todo el sitio (tienda y panel)
   usaba nada mas la fuente del sistema, que es la razon principal por la
   que se sentia "generico". Se cargan los .woff2 desde Google Fonts en
   layout.html, solo se referencian aqui dentro de "body.tienda". */

body.tienda {
  --tienda-display: "Fraunces", Georgia, "Times New Roman", serif;
  --tienda-cuerpo: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  /* Superficie "elevada" (para hover de tarjetas) y dos sombras reutilizables
     - antes cada tarjeta traia su propia sombra suelta (0 1px 3px...) sin
     ningun criterio comun. */
  --tienda-superficie-alta: #2d3038;
  --tienda-sombra: 0 1px 2px rgba(0, 0, 0, .35);
  --tienda-sombra-md: 0 8px 24px rgba(0, 0, 0, .38);
  --tienda-sombra-lg: 0 20px 48px rgba(0, 0, 0, .45);
  font-family: var(--tienda-cuerpo);
  /* Prueba: el resto de la tienda usaba --color-fondo (#1c1e23, gris carbon)
     mientras que el hero de arriba se va a negro puro - se notaba una
     costura de color justo donde termina el hero. Aqui (nunca en el "body"
     base, para no tocar el panel) se sobreescribe a negro puro para que
     quede todo del mismo tono sin corte visible. Las tarjetas siguen
     usando --color-superficie (gris) para no perder el contorno contra
     el fondo. */
  background: var(--negro-encabezado);
}
body.tienda h1,
body.tienda h2,
body.tienda h3,
body.tienda .fuente-display {
  font-family: var(--tienda-display);
  font-weight: 600;
  letter-spacing: -.01em;
}
body.tienda :focus-visible {
  outline: 2px solid var(--color-acento);
  outline-offset: 2px;
}

/* ---- Botones (sobreescribe .btn solo dentro de la tienda) ----
   La base (.btn de mas arriba) queda casi negra sobre un fondo que tambien
   es casi negro (--color-primario #16181d contra --color-fondo #1c1e23) -
   apenas se distingue, asi que en la tienda el boton principal ("Agregar al
   carrito", "Comprar", "Proceder al pago"...) pasa a dorado solido, que es
   justo el color que mas contraste tiene contra el fondo oscuro. El
   secundario (.btn-secundario, ya blanco con borde dorado) se deja igual -
   ya tenia buen contraste. */
body.tienda .btn {
  font-family: var(--tienda-cuerpo);
  font-weight: 600;
  font-size: .92rem;
  padding: .7rem 1.4rem;
  border-radius: .5rem;
  background: linear-gradient(180deg, #b8925a, var(--color-acento));
  color: #1a1408;
  box-shadow: var(--tienda-sombra);
  transition: transform .12s ease, box-shadow .12s ease, opacity .12s ease;
}
body.tienda .btn:hover { opacity: 1; transform: translateY(-1px); box-shadow: 0 6px 16px rgba(166, 129, 62, .3); }
body.tienda .btn:active { transform: translateY(0); }
body.tienda .btn.btn-secundario {
  background: transparent;
  color: var(--color-texto);
  border: 1.5px solid var(--color-borde);
  box-shadow: none;
}
body.tienda .btn.btn-secundario:hover { border-color: var(--color-acento); background: rgba(166, 129, 62, .1); color: var(--color-texto); }
body.tienda .btn-pequeno { padding: .4rem .8rem; font-size: .8rem; border-radius: .4rem; }
body.tienda .btn:disabled,
body.tienda .btn:disabled:hover { background: var(--color-borde); color: var(--color-texto-muted); box-shadow: none; transform: none; opacity: 1; }

/* ---- Campos de formulario (inputs/selects sueltos, fuera de .filtros-
   catalogo que ya tenia su propio estilo) ---- */
body.tienda input:not([type="checkbox"]):not([type="radio"]),
body.tienda select,
body.tienda textarea {
  font-family: var(--tienda-cuerpo);
  border-radius: .5rem;
  border-color: var(--color-borde);
  transition: border-color .15s ease, box-shadow .15s ease;
}
body.tienda input:not([type="checkbox"]):not([type="radio"]):focus,
body.tienda select:focus,
body.tienda textarea:focus {
  outline: none;
  border-color: var(--color-acento);
  box-shadow: 0 0 0 3px rgba(166, 129, 62, .18);
}
body.tienda .formulario label { font-family: var(--tienda-cuerpo); font-weight: 500; }

/* ---- .nota / .mensaje dentro de la tienda (avisos de stock, cupon, etc.)
   - mismo tratamiento calido, solo con radio y borde un poco mas cuidados. ---- */
body.tienda .nota,
body.tienda .mensaje { border-radius: .5rem; }

/* ---- Modales (checkout, zoom, politicas) ---- */
body.tienda .modal { background: rgba(10, 9, 6, .72); backdrop-filter: blur(3px); }
body.tienda .modal-contenido:not(.modal-contenido-zoom) {
  border-radius: 1rem;
  border: 1px solid var(--color-borde);
  box-shadow: var(--tienda-sombra-lg);
}

/* -----------------------------------------------------------------------
   ---- Encabezado / navegacion ----
   Header pegado arriba (sticky) con una linea dorada tenue abajo en vez de
   flotar suelto - ayuda a que "Carrito"/"Mis pedidos" siempre esten a la
   mano al hacer scroll por un catalogo largo. */
body.tienda .banner {
  position: sticky;
  top: 0;
  z-index: 50;
  border-bottom: 1px solid rgba(212, 175, 55, .25);
}
/* Solo en Inicio: esta misma linea dorada del header era en realidad "el
   contorno del cuadro" que se notaba contra el hero de abajo - una raya
   recta y pareja de lado a lado justo donde empieza el hero, sin importar
   que tan oscuro se pusiera el degradado (confirmado con una muestra de
   pixel: la raya es solida, no parte del fondo del hero). Aqui se degrada
   de transparente (izquierda, se funde con el negro del header y con el
   lado ya oscurecido del hero) a dorada tenue (derecha, igual que en el
   resto de paginas). */
body.tienda:has(.hero) .banner-tienda {
  border-bottom: 1px solid transparent;
  border-image: linear-gradient(to right, transparent 0%, transparent 18%, rgba(212, 175, 55, .25) 60%) 1;
}
/* El menu de la derecha (enlaces + boton de carrito + engrane) se veia mas
   grande/pesado que el logotipo (delgado, tipo firma) de la izquierda - el
   logo terminaba "perdido" al lado. Todo el bloque se redujo de escala
   (letras, relleno, el ancho del boton de carrito bajo casi un tercio) para
   que se sienta proporcional al logo en vez de competirle. */
body.tienda .nav-derecha { gap: .2rem; }
body.tienda .link-info {
  border: none;
  background: none;
  padding: .25rem .45rem;
  font-size: .66rem;
  font-family: var(--tienda-cuerpo);
  opacity: .8;
  border-radius: .3rem;
  text-decoration: none;
  transition: opacity .15s ease, background .15s ease;
}
body.tienda .link-info:hover { opacity: 1; background: rgba(212, 175, 55, .1); }
body.tienda .link-carrito {
  background: rgba(212, 175, 55, .12);
  font-family: var(--tienda-cuerpo);
  font-weight: 600;
  border-color: rgba(212, 175, 55, .6);
  font-size: .66rem;
  padding: .25rem .5rem;
}
body.tienda .link-carrito:hover { background: rgba(212, 175, 55, .22); }
body.tienda .link-admin {
  width: 1.5rem;
  height: 1.5rem;
  font-size: .72rem;
}

/* Header compacto (solo logo + nav) de Inicio - el eslogan que antes vivia
   ahi adentro (.marca .lema) se movio al hero de abajo, que tiene mucho
   mas espacio para respirar y una foto de fondo. */
body.tienda .banner-tienda { padding: 1rem 2rem; }
/* El dibujo (isotipo bailarina) del logo del encabezado se quita de aqui -
   ahora solo se muestra completo, grande, dentro del cuadro del degradado
   del hero (ver .hero::before). En el encabezado queda unicamente el
   nombre en letras. */
body.tienda .banner-tienda .logo-figura { display: none; }
body.tienda .banner-tienda .logo-texto { height: 3.1rem; }
/* Solo en Inicio (la unica pagina con <section class="hero">): las letras
   del logo tambien se mudaron al hero (ver .hero-marca-izquierda), asi que
   aqui en el encabezado ya no queda nada del logo - se usa "visibility"
   (no "display") para que el link siga ocupando su lugar y el menu de la
   derecha no se recorra. En el resto de las paginas (que no tienen hero)
   el logo del encabezado se queda como estaba. Con min-width: 900px para
   que coincida exactamente con el punto donde .hero-marca-izquierda se
   oculta en celular (ver mas abajo) - si no, en celular la pagina se
   quedaba sin logo en ningun lado. */
@media (min-width: 900px) {
  body.tienda:has(.hero) .banner-tienda .logo { visibility: hidden; }
}
@media (max-width: 640px) {
  body.tienda .banner-tienda { padding: .85rem 1rem; }
}

/* ---- Hero (solo Inicio) ----
   Se probo primero con la foto de marmol negro con vetas doradas
   (--marmol, ver arriba - ya no se usa en ningun lado): a pantalla completa
   se notaba borrosa y el encuadre dejaba una mancha de vetas doradas
   amontonada en una esquina. Se reemplazo por un degradado negro/dorado 100%
   vectorial (nunca se pixelea) con el isotipo de la marca de fondo, pero la
   primera version lo traia enorme (60% del ancho del hero) y opacado - se
   veia como una mancha/linea sin forma reconocible y le quitaba presencia al
   logotipo real de la esquina. Se dejo chico (18%), completo (sin recortar
   por los bordes) y a la derecha del contenido en vez de encimado con el
   texto, para que se lea como lo que es (el mismo isotipo del logo) en vez
   de una textura abstracta. Centrado horizontal/vertical con flexbox, mismo
   tamaño/alto que tenia antes - el padding no se toco. */
.hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  /* El logotipo (dibujo + letras, ver .hero-marca-izquierda mas abajo) vive
     ahora del lado izquierdo - se oscurecio todavia mas esa zona (para que
     el logo resalte con buen contraste) y el brillo del degradado radial
     se hizo mas chico/concentrado en la esquina superior derecha. Ademas,
     el contorno del cuadro (la linea recta donde el hero empieza/termina,
     bien visible contra el negro puro de arriba/abajo) se funde a negro
     con dos manchas radiales en las esquinas de la izquierda - asi del
     lado del logo no se nota donde acaba el rectangulo del hero, en vez de
     una orilla dura. */
  background:
    radial-gradient(ellipse 60% 100% at 0% 0%, #000000 0%, transparent 82%),
    radial-gradient(ellipse 60% 100% at 0% 100%, #000000 0%, transparent 82%),
    linear-gradient(to right, rgba(0, 0, 0, .85) 0%, transparent 42%),
    linear-gradient(to bottom, transparent 45%, #000000 100%),
    radial-gradient(ellipse 45% 60% at 96% 4%, rgba(196, 155, 78, .3), transparent 58%),
    linear-gradient(160deg, #050403 0%, #15110a 50%, #030201 100%);
  padding: 1.85rem 2rem;
  overflow: hidden;
}
/* Isotipo de la marca (el mismo que usa el logo y el footer), dos copias a
   distinta escala/rotacion, grandes y recortadas por el overflow:hidden del
   .hero (solo se asoma una parte) - version "veta de marmol" que al cliente
   le gusto, del lado derecho. Ya viene en dorado (fill #c9a24b, ver
   figura-dorado.svg); saturate() + drop-shadow para que las lineas se vean
   luminosas. Puramente vectorial: no depende de la calidad de ninguna foto. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  background: url("/static/img/moda-fitness-figura-dorado.svg") no-repeat center / contain;
  filter: saturate(1.6) drop-shadow(0 0 22px rgba(201, 162, 75, .45));
  pointer-events: none;
}
.hero::before {
  top: -24%;
  right: -14%;
  width: 70%;
  aspect-ratio: 1 / 1;
  transform: rotate(9deg);
  opacity: .5;
}
.hero::after {
  bottom: -34%;
  right: 6%;
  width: 40%;
  aspect-ratio: 1 / 1;
  transform: rotate(-14deg);
  opacity: .18;
}
@media (max-width: 900px) {
  .hero::before,
  .hero::after { display: none; }
}
/* El logotipo completo (dibujo + letras) vivia repartido en dos lugares -
   el dibujo aqui en el hero y las letras arriba en el encabezado (ver
   .logo-texto). Ahora las letras se mudaron tambien al hero, junto al
   dibujo, como un logo unico del lado izquierdo (el encabezado de arriba
   se queda sin logo en esta pagina - ver "body.tienda:has(.hero) .logo"
   mas abajo, que solo aplica aqui porque solo Inicio tiene .hero). */
.hero-marca-izquierda {
  position: absolute;
  top: 50%;
  left: 4%;
  transform: translateY(-50%);
  display: flex;
  align-items: center;
  gap: .9rem;
  pointer-events: none;
}
.hero-figura-izquierda,
.hero-texto-izquierda {
  display: block;
  width: auto;
  filter: saturate(1.6) drop-shadow(0 0 22px rgba(201, 162, 75, .45));
  opacity: .9;
}
.hero-figura-izquierda { height: clamp(5.3rem, 8.8vw, 7.8rem); }
.hero-texto-izquierda { height: clamp(3.7rem, 6.3vw, 5.5rem); }
/* v1.44: sin logo propio (instalacion que no es Moda Fitness) se muestra el
   nombre del negocio en letra, en la cabecera y en la portada. */
.logo-nombre {
  font-family: "Fraunces", Georgia, serif; font-weight: 700;
  font-size: clamp(1.3rem, 3vw, 1.9rem); color: #c9a24b;
  letter-spacing: .02em; line-height: 1.1;
}
.hero-nombre-izquierda {
  display: block; max-width: 22rem;
  font-family: "Fraunces", Georgia, serif; font-weight: 700;
  font-size: clamp(2rem, 4vw, 3.2rem); line-height: 1.05;
  color: #c9a24b;
  text-shadow: 0 0 22px rgba(201, 162, 75, .45);
}
@media (max-width: 899px) {
  .hero-marca-izquierda { display: none; }
}
.hero-contenido {
  position: relative;
  max-width: 40rem;
  margin: 0 auto;
  text-align: center;
}
.hero-eyebrow {
  font-family: var(--tienda-cuerpo);
  text-transform: uppercase;
  letter-spacing: .14em;
  font-size: .74rem;
  font-weight: 600;
  color: var(--dorado-texto);
  margin: 0 0 .6rem;
}
.hero-titulo {
  font-size: clamp(1.3rem, 2.6vw, 2rem);
  line-height: 1.16;
  color: #fdfaf2;
  margin: 0 0 .6rem;
  text-wrap: balance;
  text-shadow: 0 2px 12px rgba(0, 0, 0, .5);
}
/* "Tu Maximo Nivel" dentro del titulo, en cursiva normal (misma fuente
   Fraunces del resto del titulo, solo inclinada) para que resalte sin
   cambiar de tipografia ni de color - se queda en blanco igual que el
   resto de la frase. */
.hero-titulo-cursiva {
  font-style: italic;
}
.hero-slogan {
  font-family: "Dancing Script", cursive;
  font-weight: 600;
  font-size: clamp(1.3rem, 2.4vw, 1.7rem);
  line-height: 1.25;
  color: var(--dorado-texto);
  margin: 0;
  text-wrap: balance;
}
@media (max-width: 640px) {
  .hero { padding: 1.5rem 1.25rem; }
}
@media (prefers-reduced-motion: reduce) {
  body.tienda .btn { transition: none; }
}

/* ---- Encabezado de seccion del catalogo ("Tienda en linea" + toolbar) ---- */
.tienda > h2 {
  font-size: 1.6rem;
  margin: 0 0 .35rem;
}
.filtros-catalogo {
  background: var(--color-superficie);
  border: 1px solid var(--color-borde);
  border-radius: .75rem;
  padding: .85rem;
  margin-top: 1.5rem;
}
.filtros-catalogo select,
.filtros-catalogo .filtro-buscar { border-radius: .5rem; background: var(--color-fondo); }
.boton-vista { border-radius: .5rem; }

/* ---- Tarjetas de producto ----
   Imagen en proporcion cuadrada fija (antes tenia una altura fija con
   object-fit: contain, que dejaba franjas vacias irregulares segun la
   forma de cada foto) + elevacion mas marcada al pasar el mouse. */
.producto-card {
  border-radius: 1rem;
  border: 1px solid var(--color-borde);
  box-shadow: var(--tienda-sombra);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.producto-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--tienda-sombra-md);
  border-color: rgba(166, 129, 62, .45);
}
/* object-fit: cover con un cuadro 1:1 recortaba las fotos de las modelos
   de cuerpo completo (siempre verticales, mas altas que anchas) - se veian
   cortadas de la cabeza y/o los pies. Con "contain" la foto siempre se ve
   completa (nunca recorta), y el cuadro 3:4 (vertical) es una proporcion
   mucho mas cercana a una foto de cuerpo completo que el 1:1 anterior, asi
   que sobra menos espacio vacio a los lados. */
.producto-img,
.producto-img-vacia {
  aspect-ratio: 3 / 4;
  height: auto;
  object-fit: contain;
}
.producto-img-vacia {
  flex-direction: column;
  gap: .35rem;
  color: var(--color-texto-muted);
  font-size: .75rem;
  background: linear-gradient(160deg, var(--color-borde), var(--color-fondo));
}
.producto-img-vacia::before {
  content: "";
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  background: rgba(166, 129, 62, .16);
  border: 1.5px dashed rgba(166, 129, 62, .5);
}
.producto-card-info h3 { font-size: 1.02rem; margin: 0; }
.producto-card-info > p:not([class]) {
  font-size: .85rem;
  color: var(--color-texto-muted);
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.producto-card .precio { font-family: var(--tienda-display); font-size: 1.2rem; }
.producto-card .sku {
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .7rem;
}
.productos-grid.vista-lista .producto-img,
.productos-grid.vista-lista .producto-img-vacia { border-radius: .6rem; }

/* ---- Precio con descuento / avisos de stock, como chips ---- */
.precio-descuento { font-family: var(--tienda-display); font-size: 1.2rem; }
.aviso-stock-bajo {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: rgba(224, 168, 62, .14);
  border-radius: 999px;
  padding: .2rem .65rem;
  font-size: .78rem;
}
.aviso-stock-bajo::before { content: "●"; font-size: .55rem; }
.aviso-stock-bajo.aviso-agotado { background: rgba(224, 104, 90, .14); }
/* "Pedido especial" (ver checkbox en Backend > Inventario > Editar): mismo
   chip que .aviso-stock-bajo, pero con el dorado de --color-acento en vez
   del ambar/rojo de existencias, para que se lea como informativo ("asi es
   este producto") y no como una alerta. */
.aviso-pedido-especial {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  background: rgba(166, 129, 62, .14);
  color: var(--color-acento);
  border-radius: 999px;
  padding: .2rem .65rem;
  font-size: .78rem;
  font-weight: 600;
}
.aviso-pedido-especial::before { content: "◆"; font-size: .6rem; }

/* ---- Ficha de producto ---- */
.producto-detalle { max-width: 64rem; }
.producto-detalle-grid {
  border: 1px solid var(--color-borde);
  box-shadow: var(--tienda-sombra-md);
  gap: 2.5rem;
}
.producto-detalle h1 { font-size: 2rem; margin: 0 0 .4rem; }
.producto-detalle-precio { font-size: 2rem; }
.producto-detalle > .sku,
.producto-detalle-grid .sku {
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .72rem;
  color: var(--color-texto-muted);
}
/* Mismo ajuste que .producto-img de la cuadricula del catalogo (ver arriba):
   "cover" en un cuadro 1:1 recortaba la foto de cuerpo completo en la
   ficha del producto - aqui es todavia mas importante que se vea completa,
   es la pantalla donde la clienta decide comprar. */
.producto-detalle-img { border-radius: .75rem; aspect-ratio: 3 / 4; object-fit: contain; }
.producto-cantidad-input { border-radius: .5rem; text-align: center; }
/* Video del producto (opcional, ver bloqueVideo en frontend.routes.ts):
   va debajo de la ficha, no adentro de la cuadricula de fotos, asi que se
   le da su propio ancho maximo centrado en vez de heredar el grid. */
.producto-video {
  display: block; width: 100%; max-width: 40rem; margin: 0 auto 2rem;
  border-radius: .75rem; box-shadow: var(--tienda-sombra-md); background: #000;
}
@media (max-width: 640px) {
  .producto-detalle { padding: 1.25rem 1rem; }
}

/* ---- Reseñas ---- */
.resenas-producto h2 { font-size: 1.3rem; }
.resena { padding: 1rem 0; }
.resena strong { font-family: var(--tienda-display); font-weight: 600; }

/* ---- Carrito ---- */
.carrito-item {
  border-radius: .85rem;
  border: 1px solid var(--color-borde);
  padding: .85rem 1.1rem;
}
.miniatura,
.miniatura-vacia { border-radius: .55rem; }
.carrito-item-info strong { font-family: var(--tienda-display); font-weight: 600; }
.carrito-cantidad { border-radius: .45rem; text-align: center; }
.carrito-subtotal { font-family: var(--tienda-display); }
.carrito-resumen {
  border: 1px solid var(--color-borde);
  box-shadow: var(--tienda-sombra-md);
}
.carrito-total { font-family: var(--tienda-display); font-size: 1.5rem; }

/* ---- Forma de pago (checkout) ---- */
.opcion-pago { border-radius: .65rem; }
.checkout-pasos {
  display: flex;
  align-items: center;
  gap: .5rem;
  font-family: var(--tienda-cuerpo);
}
.checkout-paso-indicador {
  display: inline-flex;
  align-items: center;
  gap: .45rem;
}
.checkout-paso-indicador::before {
  content: attr(data-paso-indicador);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.35rem;
  height: 1.35rem;
  border-radius: 50%;
  border: 1.5px solid var(--color-texto-muted);
  color: var(--color-texto-muted);
  font-size: .72rem;
  font-weight: 700;
}
.checkout-paso-indicador.checkout-paso-activo::before {
  border-color: var(--color-acento);
  color: var(--color-primario);
  background: var(--color-acento);
}
.checkout-paso-separador { flex: 1; height: 1px; background: var(--color-borde); max-width: 2.5rem; }

/* ---- Confirmacion de compra ---- */
.pagina-confirmacion {
  border-radius: 1rem;
  border: 1px solid var(--color-borde);
  box-shadow: var(--tienda-sombra-md);
}
.confirmacion-icono {
  width: 3.5rem;
  height: 3.5rem;
  border-radius: 50%;
  background: rgba(166, 129, 62, .16);
  color: var(--color-acento);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 auto 1.25rem;
}
.confirmacion-icono svg { width: 1.9rem; height: 1.9rem; }
.pagina-confirmacion h1 { font-size: 1.7rem; }
body.tienda .pagina-confirmacion .tabla {
  border-radius: .6rem;
  overflow: hidden;
  border: 1px solid var(--color-borde);
}
body.tienda .pagina-confirmacion .tabla th {
  background: var(--color-fondo);
  font-family: var(--tienda-cuerpo);
  text-transform: uppercase;
  letter-spacing: .04em;
  font-size: .72rem;
  color: var(--color-texto-muted);
}

/* ---- Barra de envio gratis ---- */
.barra-envio-gratis-track { height: 6px; }

/* ---- Footer ----
   Antes era una sola linea centrada de copyright en Inicio, y ni siquiera
   existia en el resto de las paginas de la tienda (carrito, ficha de
   producto, confirmacion...) - se ve mas cuidado tener el mismo pie en
   todas, con un poco mas de contexto de la marca y los links que ya
   existian sueltos en el header. */
.footer-tienda {
  border-top: 1px solid var(--color-borde);
  margin-top: 3rem;
  padding: 2.5rem 2rem 2rem;
}
.footer-tienda-contenido {
  max-width: 64rem;
  margin: 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 2rem;
  justify-content: space-between;
}
.footer-tienda-marca {
  display: flex;
  align-items: center;
  gap: .65rem;
  max-width: 22rem;
}
.footer-tienda-marca img { height: 2.5rem; width: auto; }
.footer-tienda-marca p { margin: 0; font-size: .82rem; color: var(--color-texto-muted); }
/* Iconos de redes sociales (v1.8, Mi negocio). */
.footer-tienda-redes { display: flex; align-items: center; gap: .6rem; }
.footer-tienda-redes a {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border-radius: 50%;
  border: 1px solid var(--color-acento); color: var(--color-acento);
}
.footer-tienda-redes a:hover, .footer-tienda-redes a:focus-visible { background: var(--color-acento); color: #000; }
.footer-tienda-redes svg { width: 1.15rem; height: 1.15rem; }
.footer-tienda-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.75rem 2.5rem;
}
.footer-tienda-columna { display: flex; flex-direction: column; gap: .55rem; }
.footer-tienda-columna h4 {
  font-family: var(--tienda-cuerpo);
  text-transform: uppercase;
  letter-spacing: .06em;
  font-size: .72rem;
  color: var(--color-texto-muted);
  margin: 0 0 .2rem;
}
.footer-tienda-columna a,
.footer-tienda-columna button {
  background: none;
  border: none;
  padding: 0;
  color: var(--color-texto);
  text-decoration: none;
  font-size: .85rem;
  font-family: var(--tienda-cuerpo);
  cursor: pointer;
  text-align: left;
  opacity: .85;
}
.footer-tienda-columna a:hover,
.footer-tienda-columna button:hover { opacity: 1; color: var(--color-acento); }
.footer-tienda-base {
  max-width: 64rem;
  margin: 2rem auto 0;
  padding-top: 1.25rem;
  border-top: 1px solid var(--color-borde);
  font-size: .78rem;
  color: var(--color-texto-muted);
  text-align: center;
}
@media (max-width: 640px) {
  .footer-tienda { padding: 2rem 1.25rem 1.5rem; }
}

/* ---- Fondo de la tienda: collage de fotos del inventario ----
   Un mosaico de fotos reales de producto (ver colash-inventario.ts), fijo
   detras de todo el contenido, casi todo negro y a opacidad muy baja - la
   idea es que se sienta como una textura/marca de agua, nunca que compita
   con el contenido real (tarjetas, texto, botones) que va encima. Con
   position:fixed + z-index negativo se pinta debajo del resto de los hijos
   normales de <body> (header/main/footer), sin tener que tocarles el
   z-index a ellos - se asoma nada mas en los huecos (margenes, fondo detras
   de las tarjetas). No aparece si el inventario no tiene fotos suficientes
   (ver MINIMO_IMAGENES) para no verse disperso/incompleto. */
.fondo-colash-tienda {
  position: fixed;
  inset: 0;
  z-index: -1;
  overflow: hidden;
  pointer-events: none;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  grid-auto-rows: 140px;
  gap: 2px;
}
.fondo-colash-tienda img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Grises + muy oscuras: son las mismas fotos de producto, pero la idea es
     que se lean como una textura tenue, no como una galeria de fondo. */
  filter: grayscale(1) brightness(.22) contrast(1.05);
}
.fondo-colash-tienda::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, .84);
}
@media (prefers-reduced-motion: no-preference) {
  .fondo-colash-tienda { opacity: 0; animation: fondo-colash-entrada .8s ease forwards .1s; }
}
@keyframes fondo-colash-entrada {
  to { opacity: 1; }
}

/* ===== /admin/plataforma (Fase 5): resumen con medidores, interruptores
   deslizables, pestanas y checklist de lanzamiento. Todo nuevo, no toca ni
   redefine ninguna regla existente de arriba. ===== */

.resumen-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; margin-bottom: 1.5rem; }
@media (max-width: 900px) { .resumen-grid { grid-template-columns: repeat(2, 1fr); } }
.tarjeta-resumen { background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: .85rem; padding: 1.1rem 1.2rem; display: flex; flex-direction: column; gap: .7rem; }
.tarjeta-resumen .etiqueta { font-size: .72rem; text-transform: uppercase; letter-spacing: .06em; color: var(--color-texto-muted); font-weight: 600; }
.tarjeta-resumen .fila-medidor { display: flex; align-items: center; gap: .9rem; }
.tarjeta-resumen .valor-principal { font-size: 1.3rem; font-weight: 700; line-height: 1.15; }
.tarjeta-resumen .subtexto { font-size: .78rem; color: var(--color-texto-muted); }
.tarjeta-ancha { margin-top: 1rem; }
.grafica-consumo { display: block; width: 100%; height: auto; margin-top: .3rem; }
.grafica-consumo-base { stroke: var(--color-borde); stroke-width: 1; }
.barra-consumo-rect { fill: var(--color-acento); }
.barra-consumo-rect-vacia { fill: var(--color-borde); }
.barra-consumo-eje { fill: var(--color-texto-muted); font-size: 9px; }
.barra-consumo:hover .barra-consumo-rect,
.barra-consumo:hover .barra-consumo-rect-vacia { opacity: .68; }

.estado-pill { display: inline-flex; align-items: center; gap: .35rem; font-size: .72rem; font-weight: 600; padding: .2rem .55rem; border-radius: 999px; width: fit-content; }
.estado-pill.ok { background: rgba(46,160,90,.18); color: #a4e6bb; }
.estado-pill.warn { background: rgba(217,146,42,.18); color: #f0c584; }
.estado-pill.crit { background: rgba(192,57,43,.22); color: #f6c6c0; }
.estado-pill::before { content: ""; width: .45rem; height: .45rem; border-radius: 50%; background: currentColor; }

.donut { --pct: 0; --color-donut: #4fc47f; width: 60px; height: 60px; border-radius: 50%; background: conic-gradient(var(--color-donut) calc(var(--pct) * 1%), var(--color-borde) 0); display: flex; align-items: center; justify-content: center; flex-shrink: 0; position: relative; }
.donut::after { content: ""; position: absolute; inset: 7px; border-radius: 50%; background: var(--color-superficie); }
.donut span { position: relative; z-index: 1; font-size: .78rem; font-weight: 700; }

.escalera-plan { display: flex; gap: .3rem; }
.escalera-plan span { flex: 1; height: .5rem; border-radius: 999px; background: var(--color-borde); }
.escalera-plan span.activo { background: var(--dorado-texto); }

.medidor-nivel { display: flex; gap: .3rem; }
.medidor-nivel span { flex: 1; height: .5rem; border-radius: 999px; background: var(--color-borde); }
.medidor-nivel span.n1.activo { background: #2ea05a; }
.medidor-nivel span.n2.activo { background: #8fb93e; }
.medidor-nivel span.n3.activo { background: #d9922a; }
.medidor-nivel span.n4.activo { background: #d9702a; }
.medidor-nivel span.n5.activo { background: #c0392b; }

.banner-sugerencia { display: flex; justify-content: space-between; align-items: center; gap: 1rem; border-radius: .7rem; padding: .9rem 1.2rem; flex-wrap: wrap; border: 1px solid var(--color-borde); margin-bottom: 1.5rem; }
.banner-sugerencia.ok { background: rgba(46,160,90,.14); border-color: rgba(46,160,90,.4); }
.banner-sugerencia.crit { background: rgba(192,57,43,.18); border-color: rgba(224,101,90,.45); }
.banner-sugerencia p { margin: 0; font-size: .88rem; }
.banner-sugerencia .acciones-banner { display: flex; gap: .5rem; flex-wrap: wrap; }
.btn-dorado { background: var(--dorado-texto); color: #201a08; }
.btn-dorado:hover { opacity: .92; }

.fila-interruptor { display: flex; align-items: center; gap: .65rem; }
.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex-shrink: 0; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.slider-toggle { position: absolute; inset: 0; background: var(--color-borde); border-radius: 999px; transition: background .18s ease; pointer-events: none; }
.slider-toggle::before { content: ""; position: absolute; height: 18px; width: 18px; left: 3px; top: 3px; background: var(--color-texto); border-radius: 50%; transition: transform .18s ease, background .18s ease; }
.switch input:checked + .slider-toggle { background: #2ea05a; }
.switch input:checked + .slider-toggle::before { transform: translateX(18px); background: #0d2313; }
.switch input:focus-visible + .slider-toggle { outline: 2px solid var(--dorado-texto); outline-offset: 2px; }
.switch-label { font-size: .82rem; font-weight: 600; }
.switch-label.on { color: #a4e6bb; }
.switch-label.off { color: var(--color-texto-muted); }
td.col-ultima { color: var(--color-texto-muted); font-size: .8rem; }

.tab-nav { display: flex; gap: .3rem; border-bottom: 1px solid var(--color-borde); margin-bottom: 1.75rem; }
.tab-nav a { padding: .7rem 1.1rem; font-size: .9rem; font-weight: 600; color: var(--color-texto-muted); text-decoration: none; border-bottom: 2px solid transparent; margin-bottom: -1px; display: inline-block; }
.tab-nav a:hover { color: var(--color-texto); }
.tab-nav a.activo { color: var(--dorado-texto); border-color: var(--dorado-texto); }

.filtros-bitacora { display: flex; gap: .5rem; margin-bottom: .8rem; flex-wrap: wrap; }
.chip-filtro { background: var(--color-superficie); border: 1px solid var(--color-borde); color: var(--color-texto-muted); font-size: .78rem; padding: .3rem .75rem; border-radius: 999px; cursor: pointer; font-family: inherit; }
.chip-filtro.activo { background: var(--dorado-texto); color: #201a08; border-color: var(--dorado-texto); font-weight: 600; }

.progreso-checklist { display: flex; align-items: center; gap: 1.1rem; background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: .85rem; padding: 1.1rem 1.3rem; margin-bottom: 1.25rem; }
.aviso-seguridad { background: rgba(192,57,43,.14); border: 1px solid rgba(224,101,90,.35); border-radius: .6rem; padding: .75rem 1rem; font-size: .8rem; color: #f6c6c0; line-height: 1.5; margin-bottom: 1.25rem; }
.lista-checklist { display: flex; flex-direction: column; gap: .7rem; }
.item-checklist { background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: .7rem; padding: .9rem 1.1rem; display: grid; grid-template-columns: 1.5fr 1.2fr 1.6fr auto; gap: 1rem; align-items: center; }
@media (max-width: 900px) { .item-checklist { grid-template-columns: 1fr; } }
.item-checklist .nombre-item { font-weight: 600; }
.item-checklist .nombre-item .subtexto { display: block; font-weight: 400; margin-top: .1rem; }
.selector-estado { display: inline-flex; border: 1px solid var(--color-borde); border-radius: 999px; overflow: hidden; width: fit-content; }
.selector-estado button { font-size: .72rem; font-weight: 600; padding: .3rem .65rem; color: var(--color-texto-muted); background: transparent; border: none; border-right: 1px solid var(--color-borde); cursor: pointer; font-family: inherit; }
.selector-estado button:last-child { border-right: none; }
.selector-estado button.activo.pendiente { background: var(--color-borde); color: var(--color-texto); }
.selector-estado button.activo.en_progreso { background: #d9922a; color: #2b1a03; }
.selector-estado button.activo.listo { background: #2ea05a; color: #0d2313; }
.form-detalle-checklist { display: flex; gap: .4rem; align-items: center; }
.form-detalle-checklist input[type="text"] { background: var(--color-fondo); border: 1px solid var(--color-borde); color: var(--color-texto); border-radius: .4rem; padding: .4rem .55rem; font-size: .82rem; font-family: inherit; width: 100%; }
.enlace-item { font-size: .8rem; color: var(--dorado-texto); text-decoration: none; white-space: nowrap; }
.enlace-item:hover { text-decoration: underline; }
.form-agregar-checklist { display: flex; gap: .5rem; flex-wrap: wrap; margin-top: 1rem; }
.form-agregar-checklist input[type="text"] { background: var(--color-superficie); border: 1px solid var(--color-borde); color: var(--color-texto); border-radius: .4rem; padding: .5rem .7rem; font-size: .85rem; font-family: inherit; flex: 1; min-width: 12rem; }

/* Servicios y pagos (Fase 5.2): mismo espiritu visual que .item-checklist,
   pero con una ficha por servicio en vez de una fila de 3 columnas - hay
   demasiados campos (nombre, costo, cuenta, fechas, notas) para una fila. */
.lista-servicios-pago { display: flex; flex-direction: column; gap: 1rem; }
.item-servicio-pago { background: var(--color-superficie); border: 1px solid var(--color-borde); border-radius: .7rem; padding: 1rem 1.1rem; display: flex; flex-direction: column; gap: .6rem; }
.cabecera-servicio-pago { display: flex; align-items: center; justify-content: space-between; gap: .75rem; flex-wrap: wrap; }
.cabecera-servicio-pago strong { font-size: 1rem; }
.costo-servicio-pago { font-size: .85rem; color: var(--color-texto-muted); margin: 0; }
.acciones-servicio-pago { display: flex; justify-content: flex-end; }
.formulario-en-linea label[hidden] { display: none; }
.calculo-servicio-pago { margin: 0; padding: .5rem .75rem; border-radius: .4rem; background: var(--color-fondo, transparent); border: 1px dashed var(--color-borde); font-size: .9rem; font-weight: 600; }


/* Pestanas via radio+label, sin JS: el radio con checked lo decide el server
   segun ?tab= (ver tabActiva() en admin.routes.ts), asi que tras una accion en
   el checklist la pagina vuelve a esa pestana en vez de reiniciar en Resumen. */
.tab-radio-oculto { display: none; }
.panel-tab { display: none; }
#tab-resumen:checked ~ .panel-tab-resumen { display: block; }
#tab-checklist:checked ~ .panel-tab-checklist { display: block; }
#tab-servicios:checked ~ .panel-tab-servicios { display: block; }
#tab-salud:checked ~ .panel-tab-salud { display: block; }
#tab-comunicacion:checked ~ .panel-tab-comunicacion { display: block; }
.tab-nav label { padding: .7rem 1.1rem; font-size: .9rem; font-weight: 600; color: var(--color-texto-muted); cursor: pointer; border-bottom: 2px solid transparent; margin-bottom: -1px; display: inline-block; }
.tab-nav label:hover { color: var(--color-texto); }
#tab-resumen:checked ~ .tab-nav label[for="tab-resumen"],
#tab-checklist:checked ~ .tab-nav label[for="tab-checklist"],
#tab-servicios:checked ~ .tab-nav label[for="tab-servicios"],
#tab-salud:checked ~ .tab-nav label[for="tab-salud"],
#tab-comunicacion:checked ~ .tab-nav label[for="tab-comunicacion"] { color: var(--dorado-texto); border-color: var(--dorado-texto); }

/* Tarjeta de ganancia neta en Reportes (v1.12): es liga a Control de costos. */
a.tarjeta-reportes { color: inherit; text-decoration: none; }

/* Indicador de OpenAI (v1.15), en Plataforma > Servicios y pagos. */
.indicador-openai {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem;
  margin: 1rem 0 1.5rem; padding: 1.4rem 1.6rem; border-radius: 1rem;
  background: linear-gradient(135deg, rgba(198,161,94,.10), rgba(198,161,94,0) 60%), var(--rep-superficie, #1c1d22);
  border: 1px solid var(--rep-borde, #34353c); color: var(--rep-texto, #f1efe7);
}
.io-principal { display: flex; flex-direction: column; gap: .3rem; min-width: 14rem; }
.io-titulo { font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; opacity: .7; }
.io-monto { font-size: 2.6rem; font-weight: 700; line-height: 1.05; letter-spacing: -.02em; color: var(--rep-acento, #c6a15e); font-variant-numeric: tabular-nums; }
.io-centavos { font-size: 1.4rem; font-weight: 600; }
.io-moneda { font-size: .9rem; font-weight: 600; opacity: .7; letter-spacing: .04em; }
.io-sub { font-size: .85rem; opacity: .75; }
.io-stats { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: .6rem; }
.io-stats span { font-size: .8rem; padding: .3rem .7rem; border-radius: 999px; background: rgba(255,255,255,.06); }
.io-stats strong { font-variant-numeric: tabular-nums; margin-right: .2rem; }
.io-lado { display: flex; flex-direction: column; align-items: center; gap: .3rem; }
.io-medidor { width: 10rem; height: auto; }
.io-pista { fill: none; stroke: rgba(255,255,255,.08); stroke-width: 10; stroke-linecap: round; }
.io-avance { fill: none; stroke: url(#io-degradado); stroke-width: 10; stroke-linecap: round; }
.io-degradado-inicio { stop-color: #8a6d3b; }
.io-degradado-fin { stop-color: #e2c17f; }
.io-alerta .io-degradado-inicio { stop-color: #b5701f; }
.io-alerta .io-degradado-fin { stop-color: #f0a73c; }
.io-critico .io-degradado-inicio { stop-color: #8f2a20; }
.io-critico .io-degradado-fin { stop-color: #e0574a; }
.io-medidor-valor { fill: currentColor; font-size: 18px; font-weight: 700; }
.io-medidor-etiqueta { font-size: .75rem; opacity: .7; text-align: center; max-width: 12rem; }
.io-nota { flex-basis: 100%; font-size: .8rem; opacity: .7; margin: 0; }
@media (max-width: 600px) { .io-monto { font-size: 2.1rem; } .indicador-openai { padding: 1.1rem; } }

/* Costo estimado por cliente (v1.16), arriba de Servicios y pagos. */
.costo-por-cliente { align-items: flex-start; }
.costo-por-cliente .io-principal { flex: 1 1 22rem; }
.cpc-desglose { list-style: none; padding: 0; margin: .8rem 0 .4rem; display: flex; flex-direction: column; gap: .35rem; max-width: 34rem; }
.cpc-desglose li { display: flex; justify-content: space-between; gap: 1rem; font-size: .85rem; padding-bottom: .35rem; border-bottom: 1px solid rgba(255,255,255,.06); }
.cpc-desglose li span { opacity: .8; }
.cpc-desglose strong { font-variant-numeric: tabular-nums; white-space: nowrap; }
.cpc-desglose .cpc-total { border-bottom: 0; font-size: .95rem; }
.cpc-desglose .cpc-total span { opacity: 1; font-weight: 600; }
.cpc-parametros { display: flex; flex-direction: column; gap: .6rem; flex: 0 1 15rem; }
.cpc-parametros label { display: flex; flex-direction: column; gap: .25rem; font-size: .8rem; }
.cpc-parametros .io-medidor-etiqueta { text-align: left; max-width: none; }
.cpc-parametros input {
  padding: .5rem .7rem; border-radius: .5rem; font: inherit; color: var(--rep-texto, #f1efe7);
  background: rgba(0,0,0,.25); border: 1px solid var(--rep-borde, #34353c);
}

/* Salud de la tienda (v1.17), en Plataforma > Salud de la tienda. */
.salud-semaforo {
  display: flex; flex-wrap: wrap; align-items: center; gap: 1.2rem 2rem;
  margin: 1rem 0 1.5rem; padding: 1.4rem 1.6rem; border-radius: 1rem;
  border: 1px solid var(--color-borde); background: var(--color-superficie);
}
.salud-fondo-verde { border-color: rgba(46,160,90,.6); }
.salud-fondo-naranja { border-color: rgba(217,146,42,.7); }
.salud-fondo-rojo { border-color: rgba(192,57,43,.8); background: linear-gradient(135deg, rgba(192,57,43,.14), rgba(192,57,43,0) 60%), var(--color-superficie); }
.salud-luces { display: flex; flex-direction: column; gap: .45rem; padding: .6rem; border-radius: .9rem; background: #111216; border: 1px solid var(--color-borde); }
.salud-foco { display: inline-block; width: 2.4rem; height: 2.4rem; border-radius: 50%; }
.salud-foco-chico { width: 1.1rem; height: 1.1rem; }
.salud-apagado { background: #2a2c33; }
.salud-verde { background: #2ea05a; box-shadow: 0 0 14px rgba(46,160,90,.8); }
.salud-naranja { background: #e08e1f; box-shadow: 0 0 14px rgba(224,142,31,.8); }
.salud-rojo { background: #d0402f; box-shadow: 0 0 14px rgba(208,64,47,.85); }
.salud-titulo { font-size: 2rem; font-weight: 700; line-height: 1.1; }
.salud-frase { margin: .3rem 0 .4rem; font-size: 1rem; }
.salud-mini { display: flex; align-items: center; gap: .6rem; }
.salud-medidas { display: grid; grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); gap: 1rem; margin-bottom: 1rem; }
.salud-medida { display: flex; flex-direction: column; gap: .4rem; padding: 1rem 1.1rem; border-radius: .8rem; background: var(--color-superficie); border: 1px solid var(--color-borde); border-left-width: 4px; }
.salud-borde-verde { border-left-color: #2ea05a; }
.salud-borde-naranja { border-left-color: #e08e1f; }
.salud-borde-rojo { border-left-color: #d0402f; }
.salud-valor { font-size: 1.7rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.salud-canales { list-style: none; padding: 0; display: flex; flex-direction: column; gap: .4rem; }
.salud-check { display: flex; align-items: flex-start; gap: .5rem; }
.salud-check input { width: auto; margin-top: .2rem; }
.salud-umbrales fieldset { border: 1px solid var(--color-borde); border-radius: .6rem; padding: .6rem .9rem; display: flex; flex-wrap: wrap; gap: .6rem 1rem; }
.salud-umbrales fieldset label { display: flex; flex-direction: column; gap: .2rem; flex: 1 1 9rem; }
.salud-detalle-evento { white-space: pre-line; }
/* Con 4 pestanas en Plataforma no caben en celular: se acomodan en dos renglones. */
@media (max-width: 600px) {
  .tab-nav { flex-wrap: wrap; }
  .tab-nav label, .tab-nav a { padding: .55rem .7rem; }
}

/* Administrativo > Mi plan (v1.18): botones de pagar mensualidad / anualidad. */
.formulario-pago-plan { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem; margin: .6rem 0; }
.aviso-bloqueo-nivel2 a { color: inherit; font-weight: 600; text-decoration: underline; }

/* v1.20 - Navegacion del panel en celular. Antes el encabezado ocupaba 4
   renglones (titulo, menu, "Ir a la tienda" y "Salir" cada uno en el suyo)
   y los sub-menus se partian en 3-4 renglones porque la regla general de
   .subnav (flex-wrap: wrap) venia despues de la de celular y le ganaba.
   Ahora: titulo con "Salir" a la derecha en un renglon, y el menu con
   "Ir a la tienda" en el segundo; cada sub-menu es una sola fila que se
   desliza de lado (navegacion.js deja visible la pestaña activa). */
@media (max-width: 640px) {
  body.panel .panel-header { padding: .9rem 1rem .6rem; }
  body.panel .panel-header h1 { padding-right: 5rem; font-size: 1.15rem; line-height: 1.3; }
  body.panel .panel-header-derecha {
    flex-direction: row; flex-wrap: nowrap; align-items: center; gap: .75rem;
  }
  body.panel .panel-nav { flex: 1 1 auto; min-width: 0; scrollbar-width: none; }
  body.panel .panel-nav::-webkit-scrollbar { display: none; }
  body.panel .btn-tienda { flex: none; align-self: center; padding: .3rem .7rem; font-size: .8rem; }
  body.panel .btn-salir {
    position: absolute; top: .85rem; right: 1rem; padding: .3rem .8rem; font-size: .8rem;
  }
  body.panel .subnav,
  body.panel .subnav-secundario {
    flex-wrap: nowrap; overflow-x: auto; -webkit-overflow-scrolling: touch;
    scrollbar-width: none; gap: 1.25rem;
  }
  body.panel .subnav::-webkit-scrollbar { display: none; }
  body.panel .subnav a { flex: none; white-space: nowrap; }
}
/* Registro diario de OpenAI debajo del indicador (v1.23) */
.io-por-dia { margin: -.5rem 0 1.5rem; }
.io-por-dia summary { cursor: pointer; font-weight: 600; padding: .4rem 0; }
.io-por-dia table { width: 100%; }
.io-por-dia td:not(:first-child), .io-por-dia th:not(:first-child) { text-align: right; }
.io-por-dia tr.io-dia-vacio td { opacity: .5; }
/* v1.30: version desplegada al pie del panel y aviso de cada Guardar dentro
   de su tarjeta en Plataforma > Comunicacion. */
.pie-version { text-align: center; font-size: .75rem; color: var(--color-texto-muted); padding: 1.5rem 1rem; }
.aviso-tarjeta { margin: .75rem 0 0; }
.acciones-tarjeta { display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }

/* v1.37: ventana para confirmar un precio al cliente distinto del sugerido. */
.dialogo-confirmar {
  max-width: min(40rem, calc(100vw - 2rem)); padding: 1.2rem 1.4rem; border-radius: .8rem;
  border: 1px solid var(--rep-borde, #34353c); background: var(--rep-superficie, #1c1d22); color: var(--rep-texto, #f1efe7);
}
.dialogo-confirmar::backdrop { background: rgba(0,0,0,.6); }
.dialogo-confirmar h4 { margin-top: 0; }
.dialogo-confirmar .fila-perdida td { color: #f6c6c0; }
.dialogo-confirmar label { display: block; margin: .8rem 0 .3rem; font-size: .85rem; }
.dialogo-confirmar textarea {
  width: 100%; box-sizing: border-box; padding: .5rem .7rem; border-radius: .5rem; font: inherit; resize: vertical;
  color: var(--rep-texto, #f1efe7); background: rgba(0,0,0,.25); border: 1px solid var(--rep-borde, #34353c);
}

/* v1.39: precio que paga el cliente (Plataforma > Cobro en linea), destacado. */
.precio-cliente {
  display: flex; flex-direction: column; gap: .45rem; margin: .4rem 0 1rem; padding: 1.2rem 1.4rem; border-radius: 1rem;
  background: linear-gradient(135deg, rgba(198,161,94,.18), rgba(198,161,94,.03) 70%), var(--rep-superficie, #1c1d22);
  border: 1px solid var(--rep-acento, #c6a15e); color: var(--rep-texto, #f1efe7);
}
.pc-titulo { font-size: .75rem; letter-spacing: .08em; text-transform: uppercase; opacity: .85; display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.pc-modo { font-size: .7rem; letter-spacing: .04em; padding: .15rem .55rem; border-radius: 999px; border: 1px solid var(--rep-acento, #c6a15e); color: var(--rep-acento, #c6a15e); }
.pc-monto { font-size: 2.6rem; font-weight: 700; line-height: 1.05; letter-spacing: -.02em; color: var(--rep-acento, #c6a15e); font-variant-numeric: tabular-nums; }
.pc-monto.pc-vacio { font-size: 1.4rem; opacity: .7; }
.pc-unidad { font-size: .9rem; font-weight: 600; opacity: .75; letter-spacing: .04em; }
.pc-linea { font-size: .9rem; display: flex; flex-wrap: wrap; align-items: center; gap: .4rem; }
.pc-motivo { opacity: .8; font-style: italic; }
@media (max-width: 600px) { .pc-monto { font-size: 2.1rem; } .precio-cliente { padding: 1rem; } }

/* v1.42: Cobro en linea, precio sugerido de los 3 planes. */
.tabla-precios-plan .campo-margen-plan { width: 5.5rem; }
.tabla-precios-plan small { color: var(--color-texto-muted); }
.tabla-precios-plan .fila-plan-actual td { background: rgba(198, 161, 94, .1); }

/* ---- v1.43: arreglos de experiencia en la tienda ----
   1. Las ventanas (.modal: pago, politicas, sobre nosotros) no tenian
      z-index, asi que el encabezado fijo de la tienda (z-index 50) y el boton
      de Daniela (1000) quedaban encima y tapaban el titulo, los pasos y el
      boton de cerrar de "Completa tu pedido". Queda arriba de los dos y abajo
      de la barra de carga (2000). */
.modal { z-index: 1100; }
/* El boton "Cerrar" de las ventanas de la tienda salia con el estilo gris
   por defecto del navegador. */
body.tienda .modal button[data-cerrar-modal] {
  background: transparent;
  color: var(--color-texto-muted);
  border: 1px solid var(--color-borde);
  border-radius: .4rem;
  padding: .35rem .8rem;
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}
body.tienda .modal button[data-cerrar-modal]:hover { color: var(--color-texto); border-color: var(--color-acento); }

/* 2. Avisos de la tienda (carrito vacio, Mis pedidos, descuentos del
      producto) con el mismo tono oscuro/dorado del panel en vez de la caja
      crema que rompia la paleta negro/dorado. */
body.tienda .nota,
body.tienda .descuentos-producto { background: rgba(166, 129, 62, .12); color: var(--color-texto); border-radius: .5rem; }
body.tienda .nota-error { background: rgba(192, 57, 43, .16); color: var(--color-texto); border-left-color: #e0645a; }
body.tienda .nota-advertencia { background: rgba(217, 146, 42, .16); color: var(--color-texto); border-left-color: #d9922a; }

/* 3. Tarjetas del catalogo: el boton "Agregar al carrito" siempre al fondo
      de la tarjeta, alineado con los de las demas aunque la descripcion o los
      avisos cambien de alto. */
.producto-card-link { flex: 1 1 auto; }

/* 4. En el carrito el precio no se parte en dos renglones ("$549 / MXN"). */
.carrito-subtotal { white-space: nowrap; }
@media (min-width: 641px) {
  .carrito-item { grid-template-columns: 3rem 1fr 4rem auto auto; }
}

@media (max-width: 640px) {
  /* Menu de la tienda en celular: letras de 10.5px y botones de 21px de alto
     eran muy dificiles de tocar. Ahora ~14px y ~40px de alto. */
  body.tienda .nav-derecha { gap: .25rem; }
  body.tienda .link-info,
  body.tienda .link-carrito {
    font-size: .85rem;
    min-height: 2.5rem;
    padding: .45rem .7rem;
    display: inline-flex;
    align-items: center;
  }

  /* Catalogo a 2 columnas en celular (antes 1 producto por pantalla). Solo
     la vista de cuadricula; la vista de lista se queda igual. */
  .productos-grid:not(.vista-lista) {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: .65rem;
  }
  .productos-grid:not(.vista-lista) .producto-card { padding: .6rem; gap: .4rem; }
  .productos-grid:not(.vista-lista) .producto-card-info h3 { font-size: .9rem; }
  .productos-grid:not(.vista-lista) .producto-card-info > p:not([class]) { font-size: .78rem; }
  .productos-grid:not(.vista-lista) .producto-card .precio { font-size: 1.02rem; }
  .productos-grid:not(.vista-lista) .aviso-stock-bajo { font-size: .7rem; padding: .15rem .5rem; }
  .productos-grid:not(.vista-lista) .btn-agregar-carrito { font-size: .82rem; padding: .55rem .4rem; white-space: normal; }

  /* Filtros del catalogo en 2 columnas parejas en vez de 4 renglones de
     anchos distintos. */
  .filtros-catalogo { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filtros-catalogo .filtro-buscar,
  .filtros-catalogo .selector-vista { grid-column: 1 / -1; }
  .filtros-catalogo select { width: 100%; min-width: 0; }

  /* Espacio al final de la pagina para que el boton flotante de Daniela no
     tape el pie de pagina ni los ultimos botones. */
  body.tienda { padding-bottom: 5.5rem; }
}
