/* =============================================================
   Maia Live Commerce · capa de aplicación
   -------------------------------------------------------------
   Extiende el Design System QUANTUN. Reglas:
   · Sólo tokens --q-*. Ningún color literal nuevo.
   · Sólo se añaden patrones que el DS no trae (shell responsive,
     drawer, timeline, gráficos, landing móvil).
   · Nada aquí redefine un componente .q-* existente.
   ============================================================= */

/* =============================================================
   Tokens de marca de Mi tienda → Apariencia
   -------------------------------------------------------------
   Viven aquí y no en ds-tokens.css porque ese archivo es copia
   literal del Design System QUANTUN (..\quantun-design-system):
   no se edita dentro del proyecto. app.css carga después, así que
   estas reglas pisan las del DS con la misma especificidad.

   --q-primary va separado de --q-ink (texto) para que un rosa o un
   azul de marca no termine pintando todos los párrafos. El <style>
   de partials/theme-style reescribe estos valores por tienda.
   ============================================================= */
:root {
  --q-on-accent:     #0E0E0C;
  --q-primary:       #0E0E0C;
  --q-primary-hover: #2A2926;
  --q-on-primary:    #FAFAF7;
  --q-font-display:  var(--q-font-sans);
  --q-r-btn:         3px;
}

.q-btn { border-radius: var(--q-r-btn); }
.q-btn--sm { border-radius: var(--q-r-btn); }
.q-btn--primary { background: var(--q-primary); color: var(--q-on-primary); border-color: var(--q-primary); }
.q-btn--primary:hover { background: var(--q-primary-hover); border-color: var(--q-primary-hover); }
.q-btn--accent { color: var(--q-on-accent); }
.q-btn--accent:hover { background: var(--q-lima); filter: brightness(.94); }
.q-tab-item--active::after { background: var(--q-primary); }
.q-side-item--active,
.q-side-item--active:hover { background: var(--q-primary); color: var(--q-on-primary); }


/*
   OJO: nunca volver a poner "html, body { height: 100% }" aquí. Con
   html/body fijados a un viewport de alto, position:sticky sólo puede
   pegarse dentro de esa primera pantalla: pasado ese scroll, el
   "contenedor" del sticky se termina y el elemento se suelta y sube con
   el resto de la página — justo el bug de .pub-nav (menú público) que
   el negocio reportó como "que el menú en PC esté sticky". Ni el panel
   (.app) ni la parte pública (.pub) lo necesitan: ambos ya usan su
   propio min-height:100vh en su contenedor. Verificado scrolleando el
   menú público a través de un catálogo de 30 productos.
*/
body { margin: 0; background: var(--q-bg); }

::selection { background: var(--q-lima-soft); color: var(--q-ink); }

:where(a) { color: inherit; text-decoration: none; }
:where(a.q-link) { color: var(--q-ink); text-decoration: underline; text-underline-offset: 2px; text-decoration-color: var(--q-border-strong); }
:where(a.q-link):hover { text-decoration-color: var(--q-ink); }
/* En celular estos enlaces son de dedo, no de mouse: 14px de alto es un
   blanco incómodo. Se les da alto de toque sin cambiar cómo se ven —
   inline-block + padding vertical, que no altera el flujo del párrafo. */
@media (max-width: 760px) {
  a.q-link { display: inline-block; padding-block: 7px; }
}

/* Foco visible y consistente en todo lo interactivo. */
:where(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--q-ink);
  outline-offset: 2px;
  border-radius: var(--q-r-xs);
}

/* =============================================================
   App shell
   ============================================================= */

.app {
  display: grid;
  grid-template-columns: 232px 1fr;
  min-height: 100vh;
}

.app-side {
  background: var(--q-surface);
  border-right: 1px solid var(--q-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow-y: auto;
}

.app-main { min-width: 0; display: flex; flex-direction: column; }

.app-body { padding: var(--q-s-6) var(--q-s-7); flex: 1; }

/* Cada pantalla es una recarga completa (sin SPA): un fundido de entrada
   corto le da sensación de transición al cambio de página sin tener que
   interceptar la navegación con JS. */
/* Entrada de página: sólo opacidad, a propósito. Antes también hacía
   translateY(4px), y un transform en .app-body la convierte en el bloque
   contenedor de todo position:fixed que cuelgue de ella — mientras la
   animación corre, un modal o drawer abierto en ese instante se ancla al
   alto del contenido en vez de al de la pantalla y se sale de la vista
   (con el scroll del body bloqueado, sin forma de alcanzarlo). Los 4px
   no se notaban; el riesgo sí. */
.app-body { animation: page-in var(--q-dur-slow) var(--q-ease); }
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }

.app-top {
  display: flex; align-items: center; justify-content: space-between; gap: var(--q-s-4);
  padding: var(--q-s-3) var(--q-s-7);
  border-bottom: 1px solid var(--q-border);
  background: var(--q-bg);
  position: sticky; top: 0; z-index: 20;
}

.app-top h1 { margin: 0; font-size: var(--q-fs-xl); font-weight: 600; letter-spacing: -0.015em; }

/* Botón hamburguesa: sólo existe en móvil. */
.app-burger { display: none; }

/* =============================================================
   Grids utilitarias
   ============================================================= */

.grid { display: grid; gap: var(--q-s-3); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-auto { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
.grid-main { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; gap: var(--q-s-4); }

.stack { display: flex; flex-direction: column; gap: var(--q-s-3); }
.row { display: flex; align-items: center; gap: var(--q-s-2); flex-wrap: wrap; }
.row-tight { display: flex; align-items: center; gap: var(--q-s-1); }
.spacer { flex: 1; }

/* =============================================================
   KPI — tarjeta clicable que lleva al listado ya filtrado
   ============================================================= */

.kpi {
  display: flex; flex-direction: column; justify-content: space-between;
  gap: var(--q-s-2);
  padding: 14px 16px;
  min-height: 104px;
  background: var(--q-surface);
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-sm);
  transition: background var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease);
}
a.kpi:hover { border-color: var(--q-border-strong); }
a.kpi:active { transform: translateY(0.5px); }

.kpi-label {
  font-size: 10.5px; font-weight: 600; letter-spacing: .08em;
  text-transform: uppercase; color: var(--q-ink-4);
}
.kpi-value {
  font-family: var(--q-font-mono); font-variant-numeric: tabular-nums;
  font-size: 26px; font-weight: 500; letter-spacing: -0.02em; color: var(--q-ink);
  line-height: 1.1;
}
.kpi-value--sm { font-size: 20px; }
.kpi-icon {
  width: 24px; height: 24px; display: inline-flex; align-items: center; justify-content: center;
  color: var(--q-ink-4); background: var(--q-bg-soft);
  border: 1px solid var(--q-border-subtle); border-radius: var(--q-r-sm);
}

/* La KPI destacada. Una sola por pantalla — regla del DS. */
.kpi--ink { background: var(--q-ink); border-color: var(--q-ink); color: var(--q-bg); }
.kpi--ink .kpi-label, .kpi--ink .kpi-value, .kpi--ink .q-meta { color: inherit; }
.kpi--ink .kpi-icon { background: transparent; border-color: rgba(250,250,247,.2); color: inherit; }

/* =============================================================
   Alertas
   ============================================================= */

.alert {
  display: flex; align-items: flex-start; gap: var(--q-s-2);
  padding: 10px 12px;
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-sm);
  font-size: var(--q-fs-base);
  background: var(--q-surface);
  color: var(--q-ink-2);
}
.alert--success { background: var(--q-success-soft); border-color: transparent; color: var(--q-success-ink); }
.alert--warning { background: var(--q-warning-soft); border-color: transparent; color: var(--q-warning-ink); }
.alert--danger  { background: var(--q-danger-soft);  border-color: transparent; color: var(--q-danger-ink); }
.alert--info    { background: var(--q-info-soft);    border-color: transparent; color: var(--q-info-ink); }
.alert ul { margin: 4px 0 0; padding-left: 16px; }

/* Toast de confirmación tras una acción. */
.toast {
  position: fixed; z-index: 90;
  right: var(--q-s-6); bottom: var(--q-s-6);
  max-width: 380px;
  box-shadow: var(--q-shadow-pop);
  animation: toast-in var(--q-dur-slow) var(--q-ease);
  transition: opacity var(--q-dur-base) var(--q-ease), transform var(--q-dur-base) var(--q-ease);
}
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.toast--out { opacity: 0; transform: translateY(8px); }

/*
   Toast de "agregado al carrito": arriba y centrado, no abajo a la
   derecha como el genérico. Ese rincón queda tapado por el pulgar en
   celular y es justo donde nadie mira después de tocar "Agregar" —el
   pedido explícito fue "que se note que se agregó". Con foto del
   producto y el conteo del carrito, no sólo un texto de una línea.
*/
.toast--cart {
  position: fixed; z-index: 55;
  /* Justo debajo del menú fijo (57px), no encima: si lo tapara, taparía
     también el ícono del carrito que el toast está confirmando. */
  top: calc(57px + 10px); left: 50%;
  width: min(360px, calc(100vw - 24px));
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  /* Todo el cuerpo con el tono de éxito, no un filete a un lado: el
     borde izquierdo se perdía y quedaba como un detalle sin sentido. */
  background: var(--q-success-soft); color: var(--q-success-ink);
  border: 1px solid transparent;
  border-radius: var(--q-r-md);
  box-shadow: var(--q-shadow-pop);
  animation: toast-in-top var(--q-dur-slow) var(--q-ease);
  transition: opacity var(--q-dur-base) var(--q-ease), transform var(--q-dur-base) var(--q-ease);
}
@keyframes toast-in-top {
  from { opacity: 0; transform: translateX(-50%) translateY(-10px); }
  to   { opacity: 1; transform: translateX(-50%); }
}
.toast--cart.toast--out { opacity: 0; transform: translateX(-50%) translateY(-10px); }

.toast--cart-thumb {
  width: 42px; height: 42px; flex: none; border-radius: var(--q-r-xs);
  object-fit: cover; border: 1px solid var(--q-success); background: var(--q-surface);
}
.toast--cart-icon {
  width: 42px; height: 42px; flex: none; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--q-success); color: var(--q-bg);
}
.toast--cart-body { min-width: 0; flex: 1; }
.toast--cart-title {
  font-size: var(--q-fs-base); font-weight: 600; color: var(--q-success-ink);
  display: flex; align-items: center; gap: 5px;
}
.toast--cart-sub { font-size: var(--q-fs-sm); color: var(--q-success-ink); opacity: .8; margin-top: 1px; }
.toast--cart-sub .cell-strong { color: var(--q-success-ink); opacity: 1; }

/* =============================================================
   Modal & Drawer — actualización rápida sin salir de la tabla
   ============================================================= */

.overlay {
  position: fixed; inset: 0; z-index: 60;
  background: rgba(14,14,12,.28);
  display: flex; justify-content: flex-end;
}
/* Sin esto, poner overlay.hidden = true (como hace confirmDialog al
   cerrar) no oculta nada: el display:flex de arriba es una regla de
   autor y le gana en cascada al display:none del atributo [hidden] del
   navegador (misma especificidad, pero el navegador siempre pierde
   contra la hoja de estilos de la página) — se queda "pegado" en
   pantalla aunque JS ya haya puesto hidden. Mismo caso que .cart-drop
   más abajo. */
.overlay[hidden] { display: none; }
/* .overlay.overlay--center (dos clases), no .overlay--center a secas:
   la regla de abajo para celular ("los drawers bajan como hoja
   inferior") es .overlay a secas y, con la misma especificidad, ganaba
   por venir después en el archivo — el confirmDialog() terminaba
   pegado abajo del todo en vez de centrado. */
.overlay.overlay--center { align-items: center; justify-content: center; padding: var(--q-s-4); }

.drawer {
  width: min(460px, 100%);
  background: var(--q-surface);
  border-left: 1px solid var(--q-border);
  height: 100%;
  overflow-y: auto;
  box-shadow: var(--q-shadow-pop);
}

.modal {
  width: min(520px, 100%);
  background: var(--q-surface);
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-md);
  box-shadow: var(--q-shadow-pop);
  max-height: 90vh; overflow-y: auto;
}

/*
   Confirmación con marca propia, en vez del confirm() nativo del
   navegador (gris, sin estilo, distinto en cada sistema operativo — la
   captura que mandó el cliente era justo esa fea ventana del SO). Un
   solo diálogo compartido, inyectado una vez por confirmDialog() en
   app.js y reutilizado en todo el sitio: carrito y cada "Eliminar" del
   panel admin. Por encima de todo lo demás (toast incluido) porque
   siempre es la última palabra antes de una acción que no se deshace.
*/
.q-confirm-overlay { z-index: 95; }
.q-confirm {
  width: min(340px, 100%);
  padding: var(--q-s-6) var(--q-s-5) var(--q-s-5);
  text-align: center;
}
.q-confirm-icon {
  width: 40px; height: 40px; margin: 0 auto var(--q-s-4);
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--q-danger-soft); color: var(--q-danger-ink);
}
.q-confirm-msg { font-size: var(--q-fs-md); color: var(--q-ink-2); line-height: 1.45; margin: 0; }
.q-confirm-actions { display: flex; gap: var(--q-s-2); margin-top: var(--q-s-5); }
.q-confirm-actions .q-btn { flex: 1; }

/* Transiciones de entrada/salida (Alpine x-transition) para todo lo que
   aparece y desaparece: overlays, modal, drawer, drawer móvil. Antes el
   modal/drawer sólo animaban al ENTRAR (@keyframes, que no corre al
   quitar el nodo) y el fondo oscuro aparecía/desaparecía de golpe. Con
   x-transition, Alpine retrasa el remove() del DOM hasta que termina la
   transición de salida, así que ahora también se ve al cerrar. */
.t-fade-enter-active, .t-fade-leave-active { transition: opacity var(--q-dur-fast) var(--q-ease); }
.t-fade-enter-start, .t-fade-leave-end { opacity: 0; }

.t-pop-enter-active { transition: opacity var(--q-dur-base) var(--q-ease), transform var(--q-dur-base) var(--q-ease); }
.t-pop-enter-start { opacity: 0; transform: translateY(6px) scale(.98); }
.t-pop-leave-active { transition: opacity var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease); }
.t-pop-leave-end { opacity: 0; transform: translateY(4px) scale(.98); }

.t-slide-enter-active { transition: opacity var(--q-dur-base) var(--q-ease), transform var(--q-dur-base) var(--q-ease); }
.t-slide-enter-start { opacity: .6; transform: translateX(16px); }
.t-slide-leave-active { transition: opacity var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease); }
.t-slide-leave-end { opacity: 0; transform: translateX(16px); }

/* Mensaje al cliente e Historial son desplegables y cerrados por defecto
   (ver modal de detalle): no ocupan espacio salvo que alguien los pida, y
   el historial abierto está acotado a los últimos 3 eventos — entre eso y
   una sola columna (en vez de dos anchas) el modal no necesita scroll
   propio en ningún tamaño de pantalla. */
.chev-toggle { display: inline-flex; transition: transform .15s ease; color: var(--q-ink-4); }
.chev-toggle.is-open { transform: rotate(90deg); }
/* Variante para .q-select-toggle: la flecha ya apunta hacia abajo (igual
   que la del <select> nativo que imita), así que gira 180° y no 90°. */
.chev-toggle--down.is-open { transform: rotate(180deg); }

/* Un <button> que se ve exactamente como un <select>.
   "Registrar novedad" no puede ser un <select> de verdad —revela un
   formulario de cinco campos, no elige un valor— pero puesto junto al
   <select> de Estado tiene que verse igual, o la tarjeta parece armada
   a pedazos. Se copian las mismas declaraciones que .q-input/.q-select
   de ds-tokens.css (que no se toca) y se suma a la regla táctil de más
   abajo para que también compartan alto y letra en celular. */
.q-select-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--q-s-2);
  width: 100%;
  height: 32px;
  padding: 0 10px;
  background: var(--q-surface);
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-sm);
  font-family: inherit;
  font-size: var(--q-fs-base);
  color: var(--q-ink);
  text-align: left;
  cursor: pointer;
  outline: none;
  transition: border-color var(--q-dur-fast) var(--q-ease), box-shadow var(--q-dur-fast) var(--q-ease);
}
.q-select-toggle:hover { border-color: var(--q-border-strong); }
.q-select-toggle:focus-visible {
  border-color: var(--q-ink);
  box-shadow: 0 0 0 3px rgba(14,14,12,.06);
}

/* Lista de opciones con radio, para elegir de un toque.
   Va donde antes había un <select> anidado dentro de un desplegable:
   abrir un picker dentro de otro desplegable son dos gestos y el picker
   nativo tapa media pantalla. Aquí las opciones se ven todas de una.
   Son <label> con radio real —no divs con JS— así que el formulario
   sigue funcionando sin Alpine y el teclado navega entre opciones. */
/* Una sola caja para toda la lista, con filas separadas por una línea
   fina. Antes cada opción era su propio recuadro: siete cajas seguidas
   pesaban como siete botones y competían con el resto de la tarjeta.
   Elegir una opción es un paso menor dentro del formulario, así que se
   ve como una lista y no como una fila de acciones. */
.q-option-list {
  display: flex; flex-direction: column;
  background: var(--q-surface);
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-sm);
  overflow: hidden;
}
.q-option {
  display: flex; align-items: center; gap: 8px;
  padding: 7px 10px;
  border-top: 1px solid var(--q-border-subtle);
  font-size: var(--q-fs-base);
  color: var(--q-ink-2);
  cursor: pointer;
  transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.q-option:first-child { border-top: 0; }
.q-option:hover { background: var(--q-bg-soft); }
.q-option input { accent-color: var(--q-ink); margin: 0; flex-shrink: 0; }
/* La marca de elegido es sólo un fondo suave y el texto en tinta plena;
   sin borde propio, que era lo que hacía ruido. Si el navegador no
   soporta :has() se pierde el matiz pero el radio se sigue viendo. */
.q-option:has(input:checked) { background: var(--q-info-soft); color: var(--q-ink); }
/* El foco no usa box-shadow: el overflow:hidden del contenedor lo
   recortaría. Un fondo basta y se mantiene sutil. */
.q-option:focus-within { background: var(--q-bg-soft); }

/* Desplegable con alto animado (ficha completa del pedido): grid-rows de
   0fr a 1fr en vez de max-height con un número inventado — anima al
   contenido real, sea cual sea su alto, sin saltos ni recortes. */
.accordion { display: grid; grid-template-rows: 0fr; transition: grid-template-rows var(--q-dur-base) var(--q-ease); }
.accordion.is-open { grid-template-rows: 1fr; }
.accordion-inner { overflow: hidden; min-height: 0; }

/* Timeline compacta para caber dentro del modal sin scroll propio. */
.timeline--tight .timeline-item { grid-template-columns: 56px 14px 1fr; }
.timeline--tight .timeline-body { padding-bottom: 5px; }
.timeline--tight .timeline-title { font-size: 12px; }

.sheet-head {
  position: sticky; top: 0; z-index: 2;
  background: var(--q-surface);
  padding: 14px 16px;
  border-bottom: 1px solid var(--q-border-subtle);
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--q-s-3);
}
.sheet-body { padding: 16px; }
.sheet-foot {
  position: sticky; bottom: 0;
  background: var(--q-surface);
  padding: 12px 16px;
  border-top: 1px solid var(--q-border-subtle);
  display: flex; justify-content: flex-end; gap: var(--q-s-2);
}

/* =============================================================
   Formularios
   ============================================================= */

.field { margin-bottom: var(--q-s-3); }
.field-error { font-size: var(--q-fs-xs); color: var(--q-danger); margin-top: 5px; }
.q-input.is-invalid, .q-select.is-invalid, .q-textarea.is-invalid { border-color: var(--q-danger); }

.field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--q-s-3); }

.input-icon { position: relative; }
.input-icon > svg {
  position: absolute; left: 10px; top: 50%; transform: translateY(-50%);
  color: var(--q-ink-4); pointer-events: none;
}

/* Barra de filtros: se apila sola en móvil. */
.filters {
  display: grid;
  grid-template-columns: minmax(180px, 1.6fr) repeat(auto-fit, minmax(130px, 1fr)) auto;
  gap: var(--q-s-2);
  align-items: end;
}

.chip-row { display: flex; gap: 6px; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: 5px;
  height: 24px; padding: 0 8px;
  border: 1px solid var(--q-border); border-radius: var(--q-r-pill);
  background: var(--q-surface);
  font-size: var(--q-fs-sm); color: var(--q-ink-3);
  cursor: pointer;
  transition: background var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.chip:hover { border-color: var(--q-border-strong); }
.chip--on { background: var(--q-primary); border-color: var(--q-primary); color: var(--q-on-primary); }
/* El filtro de categorías es un <a> normal (para que la URL se pueda
   compartir), y sin esto el navegador lo pinta con SU color de enlace
   visitado — distinto por cada chip en el que ya se haya hecho clic. Es
   justo lo que se veía "sin diseño": una fila de pastillas de colores al
   azar en vez de todas iguales. El estado activo lo decide .chip--on,
   nunca el historial de navegación. */
.chip:visited { color: var(--q-ink-3); }
.chip--on:visited { color: var(--q-bg); }

/* En el catálogo público (comprador, no un panel denso) las pastillas
   respiran un poco más: más altas, letra un punto más grande, mismo
   look — sólo más cómodas de tocar y de leer. */
.pub .chip { height: 30px; padding: 0 13px; font-size: var(--q-fs-base); }
.pub .chip-row { gap: 8px; }

/* Toggle activo/inactivo */
.switch { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; user-select: none; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch-track {
  width: 32px; height: 18px; border-radius: var(--q-r-pill);
  background: var(--q-border-strong); position: relative;
  transition: background var(--q-dur-fast) var(--q-ease);
}
.switch-track::after {
  content: ''; position: absolute; top: 2px; left: 2px;
  width: 14px; height: 14px; border-radius: 50%; background: var(--q-surface);
  transition: transform var(--q-dur-fast) var(--q-ease);
}
.switch input:checked + .switch-track { background: var(--q-primary); }
.switch input:checked + .switch-track::after { transform: translateX(14px); }
.switch input:focus-visible + .switch-track { outline: 2px solid var(--q-ink); outline-offset: 2px; }

/* =============================================================
   Tablas
   ============================================================= */

/* Toda tabla ancha scrollea dentro de su card, nunca la página. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.q-table { min-width: 720px; }
.q-table--fluid { min-width: 0; }
.q-table td.num, .q-table th.num { text-align: right; font-variant-numeric: tabular-nums; }
.q-table .cell-strong { font-weight: 500; color: var(--q-ink); }

.pager { display: flex; align-items: center; justify-content: space-between; gap: var(--q-s-3); padding: 12px 16px; border-top: 1px solid var(--q-border-subtle); }
.pager nav { display: flex; gap: 4px; flex-wrap: wrap; }
.pager a, .pager span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; padding: 0 8px;
  border: 1px solid var(--q-border); border-radius: var(--q-r-xs);
  font-size: var(--q-fs-sm); color: var(--q-ink-3); background: var(--q-surface);
  transition: background var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.pager a:hover { border-color: var(--q-border-strong); color: var(--q-ink); }
.pager .is-current { background: var(--q-primary); border-color: var(--q-primary); color: var(--q-on-primary); }
.pager .is-disabled { opacity: .4; }

/* =============================================================
   Empty state
   ============================================================= */

.empty {
  padding: 32px 20px; text-align: center;
  background: var(--q-bg-soft);
  border: 1px dashed var(--q-border-strong);
  border-radius: var(--q-r-sm);
}
.empty-icon {
  display: inline-flex; width: 32px; height: 32px;
  align-items: center; justify-content: center;
  border-radius: var(--q-r-md); background: var(--q-surface);
  border: 1px solid var(--q-border); margin-bottom: 10px; color: var(--q-ink-3);
}

/* =============================================================
   Timeline de historial
   ============================================================= */

.timeline { display: flex; flex-direction: column; gap: 0; }
.timeline-item { display: grid; grid-template-columns: 68px 16px 1fr; gap: var(--q-s-2); }
.timeline-time {
  font-family: var(--q-font-mono); font-size: 10.5px; color: var(--q-ink-4);
  padding-top: 3px; line-height: 1.35;
}
.timeline-rail { position: relative; display: flex; justify-content: center; }
.timeline-rail::before {
  content: ''; position: absolute; top: 0; bottom: 0; width: 1px;
  background: var(--q-border);
}
.timeline-item:first-child .timeline-rail::before { top: 7px; }
.timeline-item:last-child .timeline-rail::before { bottom: calc(100% - 7px); }
.timeline-dot {
  position: relative; z-index: 1; margin-top: 5px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--q-ink-5); box-shadow: 0 0 0 3px var(--q-surface);
}
.timeline-dot--on { background: var(--q-primary); }
.timeline-body { padding-bottom: 14px; min-width: 0; }
.timeline-title { font-size: 12.5px; font-weight: 500; color: var(--q-ink); }

/* =============================================================
   Gráficos — SVG inline, sin librerías
   ============================================================= */

.chart { width: 100%; height: auto; display: block; overflow: visible; }
.chart-bar { fill: var(--q-ink); transition: fill var(--q-dur-fast) var(--q-ease); }
.chart-bar:hover { fill: var(--q-lima-deep); }
.chart-grid { stroke: var(--q-border-subtle); stroke-width: 1; }
.chart-axis { fill: var(--q-ink-4); font-size: 9px; font-family: var(--q-font-mono); }

/* Barra apilada de estados */
.stackbar { display: flex; height: 10px; border-radius: var(--q-r-xs); overflow: hidden; background: var(--q-bg-soft); }
.stackbar > span { display: block; height: 100%; }

/* Barra horizontal de ranking */
.rank-row { display: grid; grid-template-columns: 1fr 52px; gap: var(--q-s-3); align-items: center; padding: 7px 0; }
.rank-track { height: 6px; background: var(--q-bg-soft); border-radius: var(--q-r-pill); overflow: hidden; margin-top: 5px; }
.rank-fill { height: 100%; background: var(--q-ink); }

/* =============================================================
   Landing pública — móvil primero, una sola mano
   ============================================================= */

.pub {
  min-height: 100vh;
  background: var(--q-bg);
  display: flex; flex-direction: column; align-items: center;
  padding: var(--q-s-5) var(--q-s-4) var(--q-s-9);
}
.pub-wrap { width: 100%; max-width: 460px; }
/* Sólo el catálogo y la ficha de producto la usan: en celular el ancho ya
   lo manda el viewport (esto no hace nada por debajo de ~1180px de
   pantalla), en PC evita que 30 productos se vean apretados en una
   columna de formulario. */
.pub-wrap--wide { max-width: 1180px; }

.pub-head { text-align: center; margin-bottom: var(--q-s-5); }
.pub-head img:not(.pub-banner) { height: 22px; width: auto; }
.pub-banner { display: block; width: 100%; height: auto; border-radius: var(--q-r-md); }

/* =============================================================
   Catálogo público
   ============================================================= */

/* Dos columnas en celular —una sola haría scroll eterno con 30 productos—
   y las que quepan en pantallas grandes. */
.cat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--q-s-3);
}

/* En PC las tarjetas crecen un poco: a 150px mínimo, un catálogo ancho
   metía 7-8 columnas diminutas en vez de verse "más completo" como se
   pidió. El móvil no entra aquí —760px es el breakpoint de siempre en
   esta hoja— así que sigue exactamente igual. */
@media (min-width: 761px) {
  .cat-grid { grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: var(--q-s-4); }
}

.cat-card {
  display: flex; flex-direction: column;
  background: var(--q-surface);
  border: 1px solid var(--q-border);
  border-radius: var(--q-r-sm);
  overflow: hidden;
  transition: border-color var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease);
}
.cat-card:hover { border-color: var(--q-primary); transform: translateY(-2px); }

.cat-card-img {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--q-bg-soft);
  display: flex; align-items: center; justify-content: center;
}
.cat-card-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cat-card-ph { color: var(--q-ink-4); }

.cat-card-link { display: flex; flex-direction: column; flex: 1; min-height: 0; }
.cat-card-add { padding: 0 10px 10px; }
.cat-card-body { padding: 10px; display: flex; flex-direction: column; gap: 2px; flex: 1; }
.cat-card-name {
  font-size: var(--q-fs-base); font-weight: 500; color: var(--q-ink);
  line-height: 1.3;
  /* Dos líneas máximo: con nombres largos las tarjetas quedaban de altos
     distintos y la retícula se veía rota. */
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.cat-card-price { font-family: var(--q-font-mono); font-size: var(--q-fs-md); font-weight: 600; }

.cat-tag {
  position: absolute; left: 6px;
  padding: 2px 7px; border-radius: var(--q-r-pill);
  font-size: var(--q-fs-xs); font-weight: 500;
}
/* Sólo ícono, sin fondo: la píldora lima llena competía con la foto y
   con la etiqueta de categoría. La sombra es lo que la hace legible
   sobre cualquier foto, clara u oscura, sin necesitar un color de fondo. */
.cat-tag--top {
  top: 6px; background: transparent; padding: 2px;
  color: #fff; filter: drop-shadow(0 1px 2px rgba(14,14,12,.65));
  display: flex;
}
.cat-tag--out { bottom: 6px; background: var(--q-ink); color: var(--q-bg); }

/* Ficha del producto: la foto manda, ocupa todo el ancho de la tarjeta. */
.prod-hero {
  position: relative;
  aspect-ratio: 4 / 3;
  background: var(--q-bg-soft);
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid var(--q-border-subtle);
}
.prod-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Tira de miniaturas (portada + galería) debajo de la foto grande, con
   flechas a los lados para recorrerla — un slider, no sólo un scroll
   libre. El scroll con el dedo o la rueda del mouse sigue funcionando
   igual; las flechas son un atajo, no lo único que mueve la tira. */
.prod-gallery-wrap {
  position: relative;
  display: flex; align-items: center;
  border-bottom: 1px solid var(--q-border-subtle);
}
.prod-gallery {
  display: flex; gap: var(--q-s-2);
  padding: var(--q-s-3);
  overflow-x: auto;
  scroll-behavior: smooth;
  flex: 1; min-width: 0;
}
.prod-gallery-thumb {
  flex: none; width: 52px; height: 52px;
  border-radius: var(--q-r-xs); overflow: hidden;
  border: 2px solid transparent; display: block;
}
.prod-gallery-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.prod-gallery-thumb.is-active { border-color: var(--q-primary); }

.prod-gallery-arrow {
  flex: none;
  width: 26px; height: 26px; margin: 0 var(--q-s-2);
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; border: 1px solid var(--q-border);
  background: var(--q-surface); color: var(--q-ink-3);
  transition: background var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease);
}
.prod-gallery-arrow:hover { background: var(--q-bg-soft); border-color: var(--q-border-strong); }
/* Sin JS para deshabilitar la flecha al llegar a la punta de la tira
   (bindProductGallery no llegó a correr, o no hay JS): se deja siempre
   activa — clicable de sobra en vez de un botón muerto. */

/* En celular, foto arriba e info abajo (como siempre — .prod-layout no
   les cambia nada, sólo las agrupa). En PC pasan a estar lado a lado:
   la columna angosta de siempre dejaba media pantalla vacía a los
   lados sin razón, con .pub-wrap--wide de por medio. */
.prod-layout { display: flex; flex-direction: column; }
@media (min-width: 761px) {
  .prod-layout { flex-direction: row; align-items: flex-start; }
  .prod-media { flex: 1 1 50%; min-width: 0; }
  .prod-info { flex: 1 1 50%; min-width: 0; }
  .prod-hero { border-bottom: 0; border-right: 1px solid var(--q-border-subtle); }
  .prod-gallery-wrap { border-right: 1px solid var(--q-border-subtle); border-bottom: 0; }
}

/* =============================================================
   Menú público (catálogo, mi pedido, carrito)
   ============================================================= */

.pub-nav {
  position: sticky; top: 0; z-index: 40;
  background: var(--q-surface);
  border-bottom: 1px solid var(--q-border);
}
.pub-nav-inner {
  max-width: 1180px; margin: 0 auto;
  display: flex; align-items: center; gap: var(--q-s-4);
  padding: 10px var(--q-s-4);
}
.pub-nav-brand { display: inline-flex; flex: none; }
.pub-nav-brand img { height: 18px; width: auto; }

.pub-nav-links { display: flex; gap: var(--q-s-4); flex: 1; }
.pub-nav-links a {
  font-size: var(--q-fs-base); font-weight: 500; color: var(--q-ink-3);
  padding: 4px 0; border-bottom: 2px solid transparent;
  transition: color var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease);
}
.pub-nav-links a:hover { color: var(--q-ink); }
.pub-nav-links a.is-on { color: var(--q-ink); border-bottom-color: var(--q-ink); }

.pub-nav-cart-wrap { position: relative; flex: none; }
.pub-nav-cart {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: var(--q-r-sm);
  border: 1px solid var(--q-border); color: var(--q-ink-2);
  transition: border-color var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.pub-nav-cart:hover, .pub-nav-cart.is-on { border-color: var(--q-ink); color: var(--q-ink); }
.pub-nav-cart-label { display: none; }

/* En PC hay espacio de sobra en el menú: el botón se ensancha y dice
   "Mis compras" en vez de quedar como un ícono suelto. En celular sigue
   siendo el cuadrado de siempre — ahí el ícono ya se entiende solo. */
@media (min-width: 761px) {
  .pub-nav-cart {
    width: auto; height: 38px; padding: 0 14px 0 12px; gap: 7px;
  }
  .pub-nav-cart-label { display: inline; font-size: var(--q-fs-base); font-weight: 500; }
}
.pub-nav-badge {
  position: absolute; top: -6px; right: -6px;
  min-width: 18px; height: 18px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: var(--q-r-pill);
  background: var(--q-primary); color: var(--q-on-primary);
  font-family: var(--q-font-mono); font-size: 10px; font-weight: 600;
  /* La marca "recién agregado" (pulso breve) para que se note el cambio
     sin depender sólo del número. */
  transition: transform var(--q-dur-fast) var(--q-ease);
}
.pub-nav-badge.is-bump { animation: cart-bump .35s var(--q-ease); }
@keyframes cart-bump { 30% { transform: scale(1.35); } }

/* Mini-carrito desplegable del menú: mismo look que .dropdown del panel,
   propio porque necesita fotos y un pie con el total + botón. */
.cart-drop {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 50;
  width: 300px; max-width: calc(100vw - 2 * var(--q-s-4));
  background: var(--q-surface); border: 1px solid var(--q-border); border-radius: var(--q-r-md);
  box-shadow: var(--q-shadow-pop);
  overflow: hidden;
}
.cart-drop[hidden] { display: none; }
.cart-drop-body { max-height: 320px; overflow-y: auto; }
.cart-drop-line {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px; border-top: 1px solid var(--q-border-subtle);
  transition: background var(--q-dur-fast) var(--q-ease);
}
.cart-drop-line:first-child { border-top: 0; }
.cart-drop-line.is-new { background: var(--q-lima-soft); }
.cart-drop-thumb {
  width: 34px; height: 34px; flex: none; border-radius: var(--q-r-xs);
  object-fit: cover; border: 1px solid var(--q-border); background: var(--q-bg-soft);
}
.cart-drop-thumb--ph { display: flex; align-items: center; justify-content: center; color: var(--q-ink-4); }
.cart-drop-name { flex: 1; min-width: 0; font-size: var(--q-fs-base); color: var(--q-ink-2); }
.cart-drop-price { font-size: var(--q-fs-base); }
.cart-drop-remove-form { flex: none; }
.cart-drop-remove {
  display: flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  color: var(--q-ink-4);
  transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.cart-drop-remove:hover { background: var(--q-danger-soft); color: var(--q-danger-ink); }
.cart-drop-empty { padding: 20px 12px; text-align: center; font-size: var(--q-fs-base); color: var(--q-ink-3); }
.cart-drop-foot { padding: 10px 12px; border-top: 1px solid var(--q-border); background: var(--q-bg-soft); }
.cart-drop-foot .q-btn { margin-top: 8px; }

/* Fila del carrito */
.cart-line {
  display: flex; align-items: flex-start; gap: var(--q-s-3);
  padding: 12px 0; border-bottom: 1px solid var(--q-border-subtle);
}
.cart-line:last-of-type { border-bottom: 0; }
.cart-thumb {
  width: 60px; height: 60px; flex: none;
  border-radius: var(--q-r-xs); object-fit: cover;
  border: 1px solid var(--q-border); background: var(--q-bg-soft);
}
.cart-qty { width: 62px; text-align: center; }
.cart-line-side { flex: none; white-space: nowrap; text-align: right; }

/* En celular la columna derecha (subtotal + quitar) queda flotando muy
   lejos de "Cantidad", con una franja vacía enorme en medio — el ancho
   sobrante de la columna central se lo queda el espacio, no el texto.
   Se baja como una franja propia, alineada bajo la info del producto
   (no bajo la miniatura), con precio y botón compartiendo la misma
   línea: cierra el hueco en vez de dejarlo ahí. */
@media (max-width: 760px) {
  .cart-line { flex-wrap: wrap; }
  .cart-line-side {
    flex: 1 0 100%;
    display: flex; align-items: center; justify-content: space-between;
    text-align: left;
    margin-top: var(--q-s-2);
    padding-left: calc(60px + var(--q-s-3));
  }
  .cart-line-side form { margin-top: 0 !important; }
}
.cart-total {
  display: flex; align-items: baseline; justify-content: space-between;
  padding-top: var(--q-s-4); margin-top: var(--q-s-2);
  border-top: 1px solid var(--q-border);
}

/* Medios de pago en la pantalla pública de confirmar compra. */
.pay-card { overflow: hidden; }
.pay-head {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 14px 16px;
  background: var(--q-lima-soft); color: var(--q-ink);
  border-bottom: 1px solid var(--q-border-subtle);
}
.pay-row { padding: 12px 16px; border-bottom: 1px solid var(--q-border-subtle); }
.pay-row:last-child { border-bottom: 0; }
.pay-qr {
  width: 100%; max-width: 220px; height: auto;
  border-radius: var(--q-r-sm); border: 1px solid var(--q-border);
}
.pay-qr-toggle > summary {
  display: inline-flex; align-items: center; gap: 5px;
  margin-top: 8px; cursor: pointer; list-style: none;
  font-size: var(--q-fs-base); color: var(--q-ink-3);
}
.pay-qr-toggle > summary::-webkit-details-marker { display: none; }
.pay-qr-toggle > summary:hover { color: var(--q-ink); }

.pub-social {
  display: flex; justify-content: center; gap: 10px;
  margin-top: var(--q-s-8);
}
.pub-social a {
  display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--q-border); color: var(--q-ink-3);
  transition: border-color var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.pub-social a:hover { border-color: var(--q-ink); color: var(--q-ink); }
.pub-title { font-size: var(--q-fs-2xl); font-weight: 600; letter-spacing: -0.02em; margin: var(--q-s-4) 0 4px; }
.pub-sub { color: var(--q-ink-3); font-size: var(--q-fs-md); margin: 0; }

/* En móvil los controles crecen: 44px es el mínimo cómodo con el pulgar. */
.pub .q-input, .pub .q-select { height: 44px; font-size: var(--q-fs-lg); padding: 0 12px; }
.pub .q-textarea { font-size: var(--q-fs-lg); padding: 10px 12px; min-height: 64px; }
.pub .q-label { font-size: var(--q-fs-sm); text-transform: none; letter-spacing: 0; color: var(--q-ink-2); font-weight: 500; margin-bottom: 6px; }
.pub .q-btn { height: 48px; font-size: var(--q-fs-lg); width: 100%; }
.pub .field { margin-bottom: var(--q-s-4); }

/*
   Bug real, no sólo estético: ".pub .q-input" (dos clases) le gana en
   especificidad a ".q-input--with-icon" (una clase) y le pisaba el
   padding-left, así que el texto/placeholder del buscador arrancaba
   debajo de la lupa ("🔍usca"). El buscador del catálogo es el único
   input-con-ícono que vive dentro de .pub, así que el arreglo va aquí.
*/
.pub .q-input--with-icon { padding-left: 38px; }
.pub .input-icon > svg { left: 13px; }

/* Botón de "borrar búsqueda": a diferencia de la "x" nativa de
   type="search" (que sólo vacía el cuadro), este es un enlace real que
   navega sin "q" — sí limpia el filtro, no sólo el texto. */
.pub .q-input--with-clear { padding-right: 38px; }
.input-clear {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--q-ink-4);
}
.input-clear:hover { background: var(--q-bg-soft); color: var(--q-ink-2); }

/* Campo de referencia: es el dato clave, se ve como código. */
.pub input[name="product_reference"] {
  font-family: var(--q-font-mono); text-transform: uppercase;
  letter-spacing: .06em; font-weight: 500;
}
.pub input[name="amount_paid"] { font-family: var(--q-font-mono); font-variant-numeric: tabular-nums; }

/* Dropzone del comprobante: fila compacta (miniatura + texto), no un bloque
   apilado — un comprobante es una foto de recibo, no la protagonista de la
   pantalla. La vista previa vive dentro de la miniatura de 36px, nunca a
   tamaño completo. */
.dropzone {
  position: relative;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 12px;
  border: 1px dashed var(--q-border-strong);
  border-radius: var(--q-r-sm);
  background: var(--q-bg-soft);
  text-align: left;
  cursor: pointer;
  transition: border-color var(--q-dur-fast) var(--q-ease), background var(--q-dur-fast) var(--q-ease);
}
.dropzone:hover, .dropzone.is-over { border-color: var(--q-ink); background: var(--q-surface); }
.dropzone input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; }
.dropzone.is-filled { border-style: solid; border-color: var(--q-success); background: var(--q-success-soft); }

.dropzone-thumb {
  flex: none; width: 36px; height: 36px; border-radius: var(--q-r-xs);
  display: flex; align-items: center; justify-content: center;
  background: var(--q-surface); border: 1px solid var(--q-border); color: var(--q-ink-2);
  overflow: hidden;
}
.dropzone-thumb img { width: 100%; height: 100%; object-fit: cover; }
.dropzone-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.dropzone-text [data-dz-label] {
  font-size: 13px; font-weight: 500; color: var(--q-ink-2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Resumen de confirmación */
.summary-row {
  display: flex; align-items: flex-start; justify-content: space-between; gap: var(--q-s-4);
  padding: 11px 0;
  border-bottom: 1px solid var(--q-border-subtle);
}
.summary-row:last-child { border-bottom: 0; }
.summary-key { font-size: var(--q-fs-sm); color: var(--q-ink-4); flex-shrink: 0; }
.summary-val { font-size: var(--q-fs-md); color: var(--q-ink); text-align: right; font-weight: 500; }

.order-code {
  font-family: var(--q-font-mono); font-variant-numeric: tabular-nums;
  font-size: var(--q-fs-xl); font-weight: 600; letter-spacing: -0.01em;
}

/* Pasos del seguimiento público */
.steps { display: flex; flex-direction: column; gap: 2px; }
.step { display: flex; align-items: center; gap: 10px; padding: 9px 0; }
.step-mark {
  width: 20px; height: 20px; border-radius: 50%; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--q-border-strong); color: var(--q-ink-5); background: var(--q-surface);
}
.step--done .step-mark { background: var(--q-primary); border-color: var(--q-primary); color: var(--q-on-primary); }
.step--done .step-label { color: var(--q-ink); font-weight: 500; }
.step-label { font-size: var(--q-fs-md); color: var(--q-ink-5); }
.step-time { font-family: var(--q-font-mono); font-size: 10.5px; color: var(--q-ink-4); }

/* =============================================================
   Utilidades
   ============================================================= */

.mono { font-family: var(--q-font-mono); font-variant-numeric: tabular-nums; }
.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clamp-2 { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.nowrap { white-space: nowrap; }
.hide { display: none !important; }
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}
[x-cloak] { display: none !important; }

.thumb {
  width: 32px; height: 32px; border-radius: var(--q-r-xs);
  object-fit: cover; border: 1px solid var(--q-border); background: var(--q-bg-soft);
  flex-shrink: 0;
}
.thumb--lg { width: 56px; height: 56px; }

/* Galería de fotos del producto (admin): la portada vive aparte, arriba
   de la ficha — esto es sólo el material extra. */
.gallery-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); gap: var(--q-s-2);
}
.gallery-item {
  position: relative; aspect-ratio: 1 / 1;
  border: 1px solid var(--q-border); border-radius: var(--q-r-sm);
  overflow: hidden; background: var(--q-bg-soft);
}
.gallery-item img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-item-actions {
  position: absolute; inset: auto 0 0 0;
  display: flex; gap: 2px; padding: 4px;
  background: linear-gradient(to top, rgba(14,14,12,.65), transparent);
  opacity: 0; transition: opacity var(--q-dur-fast) var(--q-ease);
}
.gallery-item:hover .gallery-item-actions,
.gallery-item:focus-within .gallery-item-actions { opacity: 1; }
.gallery-item-actions form { flex: 1; display: flex; }
.gallery-item-actions .q-btn {
  width: 100%; background: rgba(255,255,255,.9); color: var(--q-ink);
}
.gallery-item-actions .q-btn:hover { background: var(--q-surface); }

/* =============================================================
   Responsive
   ============================================================= */

@media (max-width: 1100px) {
  .grid-main { grid-template-columns: minmax(0, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 860px) {
  .app { grid-template-columns: 1fr; }

  /* La barra lateral pasa a ser un panel deslizante. */
  .app-side {
    position: fixed; inset: 0 auto 0 0; z-index: 70;
    width: 250px;
    transform: translateX(-100%);
    transition: transform var(--q-dur-base) var(--q-ease);
    box-shadow: var(--q-shadow-pop);
  }
  .app-side.is-open { transform: none; }
  .app-burger { display: inline-flex; }
  .app-top { padding: var(--q-s-3) var(--q-s-4); }
  .app-body { padding: var(--q-s-4); }
  .app-top h1 { font-size: var(--q-fs-lg); }

  .grid-3, .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .filters { grid-template-columns: 1fr 1fr; }
  .field-row { grid-template-columns: 1fr; }

  .drawer { width: 100%; border-left: 0; }
  .overlay { align-items: flex-end; }
  .toast { right: var(--q-s-3); left: var(--q-s-3); bottom: var(--q-s-3); max-width: none; }
}

@media (max-width: 560px) {
  .grid-4, .grid-3, .grid-2 { grid-template-columns: 1fr 1fr; }
  .kpi { min-height: 88px; padding: 12px; }
  .kpi-value { font-size: 21px; }
  .filters { grid-template-columns: 1fr; }
  .summary-val { font-size: var(--q-fs-base); }
}

/* Tabla de pedidos en celular: por debajo de 760px una tabla de 720px de
   ancho mínimo obliga a scrollear en horizontal para ver cualquier dato,
   así que se reemplaza por una lista de tarjetas con lo mismo pero en
   otro orden — ver .order-cards más abajo. Por encima, la tabla de
   siempre. */
.only-mobile { display: none; }
@media (max-width: 760px) {
  .only-desktop { display: none; }
  .only-mobile { display: block; }
  .order-cards.only-mobile { display: flex; }
}

.order-cards { flex-direction: column; gap: var(--q-s-3); }
.order-card {
  background: var(--q-surface); border: 1px solid var(--q-border);
  border-radius: var(--q-r-md); padding: var(--q-s-4);
}
.order-card--alert { background: var(--q-danger-soft); border-color: transparent; }

/* =============================================================
   Ergonomía táctil — celular Y tablet
   -------------------------------------------------------------
   El panel se gestiona tanto desde el celular como desde el
   escritorio, y los tamaños pensados para mouse no sirven para
   el pulgar. Se corrigen dos cosas de raíz, en un solo lugar:

   1. Zoom automático de iOS. Safari hace zoom al enfocar
      cualquier campo con letra menor a 16px y deja la pantalla
      ampliada. Se probó subir los campos a 16px y se revirtió: el
      <select> quedaba con una letra mucho mayor que la de los
      botones de al lado y la tarjeta se veía descuadrada. Se
      prioriza la consistencia visual; si el zoom molesta en un
      iPhone real, la vuelta es subir --q-fs-base, no parchear
      sólo los campos.
   2. Blancos de toque. Se usan min-width/min-height a propósito:
      ganan sobre el width/height en línea de los botones de
      ícono (24-30px) sin tener que tocar cada uno en el Blade.

   La condición es "(max-width: 760px) OR (pointer: coarse)", no
   sólo el ancho: una tablet mide 768px o más —así que le toca la
   tabla, no las tarjetas— pero se sigue tocando con el dedo. Con
   un corte por ancho a secas quedaba con botones de 24px. El
   `pointer: coarse` mira el dispositivo señalador principal, así
   que un portátil con pantalla táctil (que se usa con mouse)
   conserva la densidad de escritorio.
   ============================================================= */
/* Densidad compacta en campos de texto, sólo cuando NO es táctil: en
   celular/tablet tiene que ganar la regla de 16px de abajo (va después
   a propósito, misma especificidad) o iOS hace zoom al enfocar. Es
   clase y no estilo en línea justamente para que pueda perder. */
@media (min-width: 761px) {
  .fs-compact { font-size: 12.5px; }
}

@media (max-width: 760px), (pointer: coarse) {
  /* Sólo el alto: la letra se deja en la del diseño (--q-fs-base, 13px)
     para que los campos no canten al lado de los botones, que usan esa
     misma escala. Antes se forzaba a 16px por el zoom de iOS y el
     resultado era un <select> con letra mucho más grande que todo lo
     que tenía alrededor. Contrapartida asumida a propósito: Safari en
     iPhone hace zoom al enfocar un campo de menos de 16px. */
  .q-input, .q-select, .q-textarea, .q-select-toggle { min-height: 42px; }

  /* Orden a propósito: todas comparten .q-btn, así que las variantes
     van después para poder bajar del alto por defecto. */
  .q-btn { min-height: 40px; }
  .q-option { min-height: 42px; }
  .q-btn--icon { min-width: 36px; min-height: 36px; }
  .q-btn--sm, .chip { min-height: 34px; }
  /* Filas de lista que son enlaces (desglose por estado en Reportes):
     el texto mide 20px de alto y el renglón entero es el blanco. */
  .tap-row { min-height: 40px; }
  /* Volver atrás desde la ficha se usa mucho en celular: el enlace de la
     miga medía 18px de alto. Padding vertical, sin mover la línea. */
  .q-crumb a { display: inline-block; padding-block: 8px; }
  /* Después de .q-btn--icon a propósito: el burger también la lleva y
     con la misma especificidad gana la última — es el control de
     navegación principal en celular, merece los 40px. */
  .app-burger { min-width: 40px; min-height: 40px; }

  /* Los íconos de copiar van pegados al dato y crecerlos rompería
     el renglón: se agranda sólo el área sensible, no el ícono. */
  .copy-icon { position: relative; }
  .copy-icon::after { content: ''; position: absolute; inset: -8px; }

  /* Sin mouse no hay :hover que revele los botones de la galería —
     se quedarían invisibles para siempre en celular/tablet. */
  .gallery-item-actions { opacity: 1; }
}
/* La cabecera de cada tarjeta es el disparador del acordeón: cerrada,
   sólo se ve esto (código, estado, cliente, valor); el resto vive en
   .accordion justo debajo, mismo mecanismo que el modal de detalle. */
.order-card-head { cursor: pointer; border-radius: var(--q-r-sm); }
.order-card-head:focus-visible { outline: 2px solid var(--q-info); outline-offset: 2px; }

@media print {
  .app-side, .app-top, .no-print { display: none !important; }
  .app { grid-template-columns: 1fr; }
  .app-body { padding: 0; }
  .q-card { break-inside: avoid; }
}

/* Botón de copiar inline, junto a un dato de la tabla (guía, referencia,
   celular, dirección...). Chico y discreto — sólo se nota al pasar el
   mouse — para no competir con el dato mismo. */
.copy-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; flex-shrink: 0;
  border: 0; background: none; padding: 0; cursor: pointer;
  color: var(--q-ink-4); border-radius: var(--q-r-sm);
  transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.copy-icon:hover { color: var(--q-ink-2); background: var(--q-info-soft); }
.copy-icon.is-copied { color: var(--q-success); }

/* =============================================================
   Hover con color de verdad
   -------------------------------------------------------------
   El hover de fábrica del Design System cambia a --q-bg-soft
   (#F5F4EF) sobre superficies casi idénticas (blanco, #FAFAF7):
   una diferencia de ~2% de luminosidad, invisible en la práctica
   en la mayoría de pantallas. Esto SÍ redefine componentes .q-*
   en app.css —contra la regla de "no tocar el DS acá"— porque es
   un pedido explícito: "todo lo que sea hover, tenga color".
   Primer intento: --q-lima-soft (verde-lima, el tono de los badges
   de acento) — se descartó por gusto ("no me gusta el color").
   Ahora --q-info-soft (azul suave, el tono de los badges "info"):
   un color igual de perceptible pero más neutral, no compite con
   los badges de estado (verde=éxito, ámbar=alerta, rojo=peligro).
   Sigue siendo sólo hover — transitorio, un elemento a la vez —
   no fondo permanente, que es lo que el DS prohíbe.
   ============================================================= */
.q-btn--secondary:hover,
.q-btn--ghost:hover { background: var(--q-info-soft); border-color: var(--q-info); }
.q-table tbody tr:hover { background: var(--q-info-soft); }
.q-side-item:hover { background: var(--q-info-soft); color: var(--q-ink); }
a.kpi:hover { background: var(--q-info-soft); }
.chip:hover { background: var(--q-info-soft); border-color: var(--q-info); }
.pager a:hover { background: var(--q-info-soft); }

/* Tarjetas de la landing pública (spec de esta fase: confirmar, rastrear,
   catálogo). Mismo patrón visual que un `.q-side-item`, pero de tamaño
   táctil para móvil, que es de donde llega casi todo este tráfico. */
.landing-card {
  display: flex; align-items: center; gap: var(--q-s-3);
  padding: 14px; margin-bottom: var(--q-s-3);
  background: var(--q-surface); border: 1px solid var(--q-border); border-radius: var(--q-r-md);
  text-decoration: none; color: inherit;
  transition: background var(--q-dur-fast) var(--q-ease), border-color var(--q-dur-fast) var(--q-ease);
}
.landing-card:hover { background: var(--q-info-soft); border-color: var(--q-info); }
.landing-card-icon {
  display: flex; align-items: center; justify-content: center; flex-shrink: 0;
  width: 40px; height: 40px; border-radius: var(--q-r-sm); background: var(--q-bg-soft); color: var(--q-ink-2);
}
.landing-card-title { font-size: 14px; font-weight: 600; }

/* Campanita de notificaciones (cabecera del panel) y su desplegable. */
.notif-dot {
  position: absolute; top: 6px; right: 6px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--q-danger); border: 1.5px solid var(--q-bg);
}
.dropdown {
  position: absolute; top: calc(100% + 6px); z-index: 30;
  background: var(--q-surface); border: 1px solid var(--q-border); border-radius: var(--q-r-md);
  box-shadow: var(--q-shadow-pop); overflow: hidden;
}
.dropdown-item {
  display: flex; align-items: center; gap: 8px;
  padding: 9px 12px; font-size: 12.5px; color: var(--q-ink-2);
  border-top: 1px solid var(--q-border-subtle);
  transition: background var(--q-dur-fast) var(--q-ease);
}
.dropdown-item:hover { background: var(--q-info-soft); }

/* Filtros de Pedidos fijos al hacer scroll, justo debajo de la cabecera
   del panel (que ya es sticky, top:0) — así se pueden cambiar sin
   volver a subir por una tabla larga. */
.filters-sticky {
  position: sticky; top: 57px; z-index: 15;
}

/* Fila con un intento de despacho fallido (dispatch_error_at): queda en
   rojo hasta que se registre transportadora y guía, no sólo mientras el
   aviso está abierto. */
.q-table tbody tr.row-alert,
.q-table tbody tr.row-alert:hover { background: var(--q-danger-soft); }

/* Confirmación de "se guardó ESTA". Tras editar en línea la página recarga
   y vuelve arriba: el toast dice que salió bien, pero no cuál de veinte
   filas fue. Se vuelve a la fila (JS) y se la tiñe un momento. Sobre la
   celda además de la fila porque la columna Acciones va fija y con fondo
   propio: sin esto quedaría del color viejo mientras el resto destella. */
@keyframes row-flash {
  from { background-color: var(--q-success-soft); }
  to   { background-color: transparent; }
}
.row-flash, .row-flash td { animation: row-flash 1.8s var(--q-ease); }

/* Columna Acciones fija a la derecha.
   Pedidos tiene nueve columnas y tres formularios en línea: suma ~1078px,
   así que en un portátil de 1280 (donde al área de contenido le quedan
   ~967) la tabla scrollea en horizontal y lo primero que se sale de vista
   es justo Acciones, que es lo que más se usa. En vez de apretar los
   formularios hasta que quepan, la columna se ancla al borde derecho y
   queda siempre a mano. A 1440 la tabla entra completa y esto no se nota.
   Las celdas necesitan fondo propio (las filas normales son transparentes)
   y hay que repetir los estados de fila —hover y row-alert— o la celda
   fija se vería de otro color que el resto de su fila. */
.q-table--pinned-actions th:last-child,
.q-table--pinned-actions td:last-child {
  position: sticky; right: 0; z-index: 2;
  background: var(--q-surface);
  box-shadow: -1px 0 0 var(--q-border-subtle);
}
.q-table--pinned-actions thead th:last-child { background: var(--q-bg-soft); z-index: 3; }
.q-table--pinned-actions tbody tr:hover td:last-child { background: var(--q-info-soft); }
.q-table--pinned-actions tbody tr.row-alert td:last-child { background: var(--q-danger-soft); }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .001ms !important; transition-duration: .001ms !important; }
}

/* =============================================================
   Mi tienda — personalización (Proyecto 1)
   ============================================================= */

/* Títulos con la letra "de títulos" del tema (Playfair en Lujo, etc.). */
.q h1, .q h2, .pub-title, .cat-card-name { font-family: var(--q-font-display); }

/* Pestañas de Mi tienda */
.tabs-mi-tienda {
  display: flex; gap: 4px; overflow-x: auto; scrollbar-width: none;
  margin-bottom: var(--q-s-4);
  padding: 4px; background: var(--q-bg-soft);
  border: 1px solid var(--q-border-subtle); border-radius: var(--q-r-md);
}
.tabs-mi-tienda-item {
  display: inline-flex; align-items: center; gap: 6px; flex: none;
  padding: 7px 12px; border-radius: var(--q-r-sm);
  font-size: var(--q-fs-base); font-weight: 500; color: var(--q-ink-3);
  transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.tabs-mi-tienda-item:hover { background: var(--q-surface); color: var(--q-ink); }
.tabs-mi-tienda-item.is-on {
  background: var(--q-surface); color: var(--q-ink);
  box-shadow: var(--q-shadow-2);
}

/* Aviso de borrador sin publicar */
.draft-banner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--q-s-3);
  flex-wrap: wrap;
  padding: 12px 14px; margin-bottom: var(--q-s-3);
  background: var(--q-lima-soft); border-radius: var(--q-r-md);
  animation: toast-in var(--q-dur-slow) var(--q-ease);
}
.draft-banner-text { display: flex; align-items: center; gap: 10px; color: var(--q-ink); }
.draft-banner-text .q-meta { display: block; }

/* Tarjetas de estilo */
.preset-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: var(--q-s-2); }
.preset-card {
  position: relative; display: flex; flex-direction: column; gap: 6px;
  padding: 8px; text-align: left; cursor: pointer;
  background: var(--q-surface); border: 1.5px solid var(--q-border); border-radius: var(--q-r-md);
  font: inherit; color: var(--q-ink-2);
  transition: border-color var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease), box-shadow var(--q-dur-fast) var(--q-ease);
}
.preset-card:hover { transform: translateY(-2px); box-shadow: var(--q-shadow-3); }
.preset-card.is-on { border-color: var(--q-ink); box-shadow: 0 0 0 3px rgba(14,14,12,.08); }
.preset-swatch {
  display: flex; gap: 6px; align-items: flex-end;
  height: 46px; padding: 8px; border-radius: calc(var(--q-r-md) - 2px);
  border: 1px solid var(--q-border-subtle);
}
.preset-swatch span { width: 22px; height: 22px; border-radius: 50%; box-shadow: 0 0 0 2px rgba(255,255,255,.7); }
.preset-name { font-size: var(--q-fs-sm); font-weight: 600; }
.preset-check {
  position: absolute; top: 6px; right: 6px;
  width: 20px; height: 20px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--q-ink); color: var(--q-bg);
  opacity: 0; transform: scale(.6);
  transition: opacity var(--q-dur-fast) var(--q-ease), transform var(--q-dur-base) var(--q-ease);
}
.preset-card.is-on .preset-check { opacity: 1; transform: none; }

/* Selector de color: muestra + código */
.color-field { display: flex; gap: 8px; align-items: center; }
.color-field input[type="color"] {
  width: 42px; height: 38px; padding: 2px; flex: none; cursor: pointer;
  border: 1px solid var(--q-border); border-radius: var(--q-r-sm); background: var(--q-surface);
}
.color-field .q-input { flex: 1; text-transform: uppercase; }

/* Control segmentado (bordes) */
.seg { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.seg-item {
  position: relative; display: flex; flex-direction: column; align-items: center; gap: 6px;
  padding: 10px 6px; cursor: pointer;
  border: 1.5px solid var(--q-border); border-radius: var(--q-r-md);
  font-size: var(--q-fs-sm); color: var(--q-ink-3);
  transition: border-color var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.seg-item input { position: absolute; opacity: 0; pointer-events: none; }
.seg-item.is-on { border-color: var(--q-ink); color: var(--q-ink); font-weight: 600; }
.seg-item:focus-within { outline: 2px solid var(--q-ink); outline-offset: 2px; }
.seg-shape { width: 60px; height: 26px; background: var(--q-ink); }
.tabs-mi-tienda::-webkit-scrollbar { display: none; }

.logo-slot {
  width: 120px; height: 64px; flex: none;
  display: flex; align-items: center; justify-content: center; padding: 8px;
  background: var(--q-bg-soft); border: 1px dashed var(--q-border-strong); border-radius: var(--q-r-md);
}
.logo-slot img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* Muestra en vivo: variables propias (--s-*) para no pisar las del panel */
.theme-sample-wrap { overflow: hidden; }
.theme-sample { background: var(--s-bg); font-family: var(--s-font); transition: background var(--q-dur-base) var(--q-ease); }
.theme-sample-nav {
  display: flex; align-items: center; justify-content: space-between;
  padding: 10px 14px; background: #fff; border-bottom: 1px solid rgba(14,14,12,.06);
}
.theme-sample-nav img { height: calc(20px * var(--s-logo-scale, 1)); width: auto; max-width: 110px; object-fit: contain; }
.theme-sample-cart { position: relative; display: inline-flex; color: var(--q-ink-2); }
.theme-sample-cart b {
  position: absolute; top: -7px; right: -9px;
  min-width: 16px; height: 16px; border-radius: 999px; padding: 0 4px;
  display: flex; align-items: center; justify-content: center;
  font-size: 9px; background: var(--s-primary); color: var(--s-on-primary);
}
.theme-sample-body { padding: 14px; }
.theme-sample-chips { display: flex; gap: 6px; margin-bottom: 12px; }
.theme-sample-chips span {
  padding: 4px 10px; border-radius: 999px; font-size: 11px;
  background: #fff; border: 1px solid rgba(14,14,12,.12); color: var(--q-ink-2);
}
.theme-sample-chips .is-on { background: var(--s-primary); border-color: var(--s-primary); color: var(--s-on-primary); }
.theme-sample-card {
  background: #fff; border-radius: var(--s-r); padding: 10px;
  border: 1px solid rgba(14,14,12,.08); display: flex; flex-direction: column; gap: 6px;
}
.theme-sample-img {
  position: relative; aspect-ratio: 16 / 10; border-radius: calc(var(--s-r) - 2px);
  background: linear-gradient(135deg, var(--s-soft), var(--s-accent));
}
.theme-sample-badge {
  position: absolute; top: 8px; left: 8px;
  padding: 2px 8px; border-radius: 999px; font-size: 10px; font-weight: 600;
  background: var(--s-accent); color: var(--s-on-accent);
}
.theme-sample-title { font-family: var(--s-font-display); font-size: 15px; font-weight: 600; color: var(--q-ink); }
.theme-sample-price { font-family: var(--q-font-mono); font-weight: 600; color: var(--q-ink); }
.theme-sample-btn {
  display: flex; align-items: center; justify-content: center; height: 36px;
  border-radius: var(--s-r-btn); font-size: 13px; font-weight: 600;
  background: var(--s-primary); color: var(--s-on-primary);
  transition: background var(--q-dur-base) var(--q-ease), border-radius var(--q-dur-base) var(--q-ease);
}
.theme-sample-btn--ghost { background: #fff; color: var(--q-ink); border: 1px solid rgba(14,14,12,.14); }

/* Barra de vista previa en la tienda (colores fijos, ver el parcial) */
.preview-bar {
  position: sticky; top: 0; z-index: 70;
  background: #0E0E0C; color: #FAFAF7;
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}
.preview-bar-inner {
  max-width: 1180px; margin: 0 auto; padding: 8px 16px;
  display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap;
}
.preview-bar-label { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; }
.preview-bar-actions { display: flex; gap: 6px; flex-wrap: wrap; }
.preview-bar-actions form { margin: 0; }
.preview-bar-btn {
  height: 30px; padding: 0 12px; border-radius: 6px; cursor: pointer;
  font: 500 13px/1 'Inter', ui-sans-serif, system-ui, sans-serif;
  background: transparent; color: #FAFAF7; border: 1px solid rgba(250,250,247,.3);
}
.preview-bar-btn:hover { background: rgba(250,250,247,.1); }
.preview-bar-btn--main { background: #C6F24E; color: #0E0E0C; border-color: #C6F24E; }
.preview-bar-btn--main:hover { background: #b6e336; }
/* El menú de la tienda es sticky en top:0: con la barra encima se corre. */
.preview-bar ~ .pub-nav { top: 46px; }

/* Cuentas de cobro por tipo (Banco / Nequi / Llave) */
.pay-type-icon {
  width: 32px; height: 32px; flex: none; border-radius: var(--q-r-md);
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--q-bg-soft); color: var(--q-ink-2);
}
.pay-type-icon--banco { background: #FFF4CC; color: #7A5A00; }
.pay-type-icon--nequi { background: #F5E1F4; color: #7A1F6E; }
.pay-type-icon--llave { background: #DDF3EC; color: #1B5A45; }
.pay-row-top { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
.pay-account {
  display: flex; align-items: center; justify-content: space-between; gap: var(--q-s-2);
  padding: 8px 8px 8px 12px; margin-bottom: 6px;
  background: var(--q-bg-soft); border-radius: var(--q-r-sm);
}
.pay-account-value { flex: 1; min-width: 0; font-size: var(--q-fs-lg); font-weight: 600; letter-spacing: .01em; overflow-wrap: anywhere; }
/* En la tienda los botones van a lo ancho (.pub .q-btn): el de copiar no. */
.pub .pay-account .q-btn { width: auto; height: 36px; flex: none; font-size: var(--q-fs-base); padding: 0 12px; }
.pay-admin-row { border-bottom: 1px solid var(--q-border-subtle); }
.pay-admin-edit { padding: var(--q-s-4); background: var(--q-bg-soft); }

/* =============================================================
   Live + tienda (Proyecto 2)
   ============================================================= */

/* Caja "¿Te dieron un código en el Live?" en el carrito */
.live-code {
  margin-bottom: var(--q-s-4); padding: 14px;
  background: var(--q-surface); border: 1px dashed var(--q-border-strong); border-radius: var(--q-r-md);
}
.live-code-head { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 10px; }
.live-code-icon {
  width: 30px; height: 30px; flex: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--q-lima); color: var(--q-on-accent);
}
.live-code-title { font-weight: 600; color: var(--q-ink); }
.live-code-row { display: flex; gap: var(--q-s-2); }
.live-code-row .q-input { flex: 1; min-width: 0; text-transform: uppercase; }
.pub .live-code-row .q-btn { width: auto; flex: none; padding: 0 18px; }

/* Marca "Del Live" en una línea del carrito */
.live-tag {
  display: inline-flex; align-items: center; gap: 3px; margin-left: 6px;
  padding: 1px 7px; border-radius: var(--q-r-pill);
  font-size: var(--q-fs-xs); font-weight: 600;
  background: var(--q-lima-soft); color: var(--q-lima-deep);
}

/* "Usamos los datos de tu última compra · No soy yo" */
.remember-note {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin: 0 0 var(--q-s-4); padding: 8px 12px;
  background: var(--q-success-soft); color: var(--q-success-ink);
  border-radius: var(--q-r-sm); font-size: var(--q-fs-sm);
  animation: toast-in var(--q-dur-slow) var(--q-ease);
}
.remember-note[hidden] { display: none; }
.remember-head { display: flex; align-items: center; gap: 6px; flex: 1 1 100%; }
.remember-summary { flex: 1 1 100%; color: var(--q-ink-2); line-height: 1.45; }
.remember-summary:empty { display: none; }
.remember-summary div:first-child { font-weight: 600; color: var(--q-ink); }
.remember-actions { display: flex; gap: var(--q-s-4); flex: 1 1 100%; }
.remember-forget {
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; font-weight: 600; color: inherit; text-decoration: underline;
}
.remember-forget[hidden] { display: none; }
.field[hidden] { display: none; }

/* Varios códigos del Live en un mismo formulario ("+ Otra prenda") */
.codes { display: flex; flex-direction: column; gap: 6px; }
.codes-row { display: flex; gap: 6px; align-items: center; animation: toast-in var(--q-dur-slow) var(--q-ease); }
.codes-row .q-input { flex: 1; }
.codes-add {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border: 1px dashed var(--q-border-strong); border-radius: var(--q-r-btn);
  background: transparent; color: var(--q-ink-2); font: inherit; font-size: var(--q-fs-sm); font-weight: 600; cursor: pointer;
}
.codes-add:hover { border-color: var(--q-primary); color: var(--q-ink); }
.codes-add[hidden] { display: none; }

/* Avisos del pedido en el panel (misma clienta, sin unidades, comprobante) */
.order-alerts { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 4px; }
.order-alert {
  display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  padding: 2px 7px; border-radius: 999px; font-size: 11px; font-weight: 600; line-height: 1.5;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-decoration: none;
}
.order-alert--info    { background: var(--q-info-soft);    color: var(--q-info-ink); }
.order-alert--warning { background: var(--q-warning-soft); color: var(--q-warning-ink); }
.order-alert--danger  { background: var(--q-danger-soft);  color: var(--q-danger-ink); }
a.order-alert:hover { filter: brightness(.96); }
.order-alerts--full { flex-direction: column; gap: var(--q-s-2); margin: 0; }
.order-alerts--full .order-alert {
  white-space: normal; border-radius: var(--q-r-sm); padding: 8px 12px; font-size: 13px; font-weight: 500; align-items: flex-start;
}

/* Badge de canal (Live / Tienda / Live + tienda) en el panel */
.channel-badge { display: inline-flex; align-items: center; gap: 4px; }

/* Filas de tabla que llevan a otra pantalla (Clientes). */
.row-link { cursor: pointer; }

/* =============================================================
   Tienda — rediseño (Proyecto 3)
   ============================================================= */

/* ── Aparición al hacer scroll (sólo con JS: ver <head> y revealIn) ── */
.js [data-reveal] {
  opacity: 0; transform: translateY(14px);
  transition: opacity .5s var(--q-ease), transform .5s var(--q-ease);
  transition-delay: var(--d, 0ms);
}
.js [data-reveal].is-visible { opacity: 1; transform: none; }

/* ── Menú superior ─────────────────────────────────────────────────── */
.pub-nav { box-shadow: 0 1px 0 rgba(14,14,12,.02); }
.pub-nav-inner { gap: var(--q-s-5); min-height: 60px; }
.pub-nav-brand img { height: calc(26px * var(--q-logo-scale, 1)); max-width: calc(150px * var(--q-logo-scale, 1)); object-fit: contain; }
.pub-nav-links { align-items: center; gap: var(--q-s-5); }
.pub-nav-links a.is-on { border-bottom-color: var(--q-primary); }

.pub-nav-burger {
  display: none; flex: none;
  width: 38px; height: 38px; margin-left: -6px;
  align-items: center; justify-content: center;
  border: 0; border-radius: var(--q-r-sm); background: transparent; color: var(--q-ink);
  cursor: pointer;
}
.pub-nav-burger:hover { background: var(--q-bg-soft); }

.pub-nav-drop { position: relative; display: inline-flex; align-items: center; gap: 2px; }
.pub-nav-drop-toggle {
  width: 22px; height: 22px; padding: 0; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--q-ink-3); cursor: pointer;
  transition: transform var(--q-dur-base) var(--q-ease), background var(--q-dur-fast) var(--q-ease);
}
.pub-nav-drop-toggle:hover { background: var(--q-bg-soft); color: var(--q-ink); }
.pub-nav-drop.is-open .pub-nav-drop-toggle { transform: rotate(180deg); }
.pub-nav-drop-panel {
  position: absolute; top: calc(100% + 14px); left: -16px; z-index: 55;
  width: 360px; padding: 10px;
  background: var(--q-surface); border: 1px solid var(--q-border);
  border-radius: var(--q-r-lg); box-shadow: var(--q-shadow-pop);
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity var(--q-dur-base) var(--q-ease), transform var(--q-dur-base) var(--q-ease), visibility 0s linear var(--q-dur-base);
}
/* Puente invisible entre el enlace y el panel: sin esto, el hover se
   pierde en el hueco de 14px y el panel se cierra al bajar el mouse. */
.pub-nav-drop-panel::before { content: ''; position: absolute; left: 0; right: 0; top: -16px; height: 16px; }
.pub-nav-drop.is-open .pub-nav-drop-panel { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
@media (hover: hover) {
  .pub-nav-drop:hover .pub-nav-drop-panel { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
}
.pub-nav-links .pub-nav-drop-panel a { border: 0; padding: 0; }
.pub-nav-drop-all {
  display: flex !important; align-items: center; gap: 8px;
  padding: 10px 12px !important; margin-bottom: 6px;
  border-radius: var(--q-r-md); background: var(--q-bg-soft);
  font-weight: 600; color: var(--q-ink) !important;
}
.pub-nav-drop-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px; }
.pub-nav-drop-grid a {
  padding: 8px 12px !important; border-radius: var(--q-r-sm);
  color: var(--q-ink-2) !important;
  transition: background var(--q-dur-fast) var(--q-ease), padding var(--q-dur-fast) var(--q-ease);
}
.pub-nav-drop-grid a:hover { background: var(--q-lima-soft); padding-left: 16px !important; }

/* Celular: menú en panel lateral */
@media (max-width: 760px) {
  .pub-nav-burger { display: inline-flex; }
  .pub-nav-links { display: none; }
  .pub-nav-inner { gap: var(--q-s-2); min-height: 56px; }
  .pub-nav-brand { flex: 1; }
}

.pub-drawer { position: fixed; inset: 0; z-index: 80; }
.pub-drawer[hidden] { display: none; }
.pub-drawer-scrim {
  position: absolute; inset: 0; background: rgba(14,14,12,.4);
  opacity: 0; transition: opacity var(--q-dur-base) var(--q-ease);
}
.pub-drawer-panel {
  position: absolute; top: 0; bottom: 0; left: 0;
  width: min(320px, 86vw); overflow-y: auto;
  display: flex; flex-direction: column; gap: 2px;
  padding: 12px 12px 24px;
  background: var(--q-surface); box-shadow: var(--q-shadow-pop);
  transform: translateX(-100%);
  transition: transform var(--q-dur-slow) var(--q-ease);
}
.pub-drawer.is-open .pub-drawer-scrim { opacity: 1; }
.pub-drawer.is-open .pub-drawer-panel { transform: none; }
.pub-drawer-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 4px 4px 12px; margin-bottom: 6px; border-bottom: 1px solid var(--q-border-subtle);
}
.pub-drawer-head img { height: calc(24px * var(--q-logo-scale, 1)); width: auto; max-width: calc(150px * var(--q-logo-scale, 1)); object-fit: contain; }
.pub-drawer-close {
  width: 36px; height: 36px; border: 0; border-radius: 50%; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--q-bg-soft); color: var(--q-ink);
}
.pub-drawer-link {
  display: flex; align-items: center; gap: 12px;
  padding: 12px; border-radius: var(--q-r-md);
  font-size: var(--q-fs-lg); font-weight: 500; color: var(--q-ink);
}
.pub-drawer-link:hover { background: var(--q-bg-soft); }
.pub-drawer-title {
  padding: 14px 12px 4px; font-size: var(--q-fs-xs); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--q-ink-4);
}
.pub-drawer-link--sub { align-items: flex-start; }
.pub-drawer-link--sub > svg { margin-top: 3px; }
.pub-drawer-link small {
  display: block; margin-top: 1px;
  font-size: var(--q-fs-sm); font-weight: 400; color: var(--q-ink-3); line-height: 1.35;
}
.pub-drawer-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; margin-left: 4px; vertical-align: 2px;
  border-radius: 999px; background: var(--q-primary); color: var(--q-on-primary);
  font-size: 11px; font-weight: 700;
}
/* El Live va aparte y con otro aspecto: es para quien ya compró en vivo,
   no una sección más de la tienda. Así no se confunde con el carrito. */
.pub-drawer-live {
  display: flex; align-items: center; gap: 12px;
  margin: 14px 0 4px; padding: 12px 14px;
  border: 1px solid var(--q-border); border-radius: var(--q-r-lg);
  background: var(--q-bg-soft); color: var(--q-ink); font-weight: 600;
}
.pub-drawer-live > span:nth-child(2) { flex: 1; min-width: 0; }
.pub-drawer-live small {
  display: block; margin-top: 2px;
  font-size: var(--q-fs-sm); font-weight: 400; color: var(--q-ink-3); line-height: 1.35;
}
.pub-drawer-live-dot {
  flex: none; width: 10px; height: 10px; border-radius: 50%;
  background: #E5484D; box-shadow: 0 0 0 4px rgba(229,72,77,.15);
}
.pub-drawer-cats { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 12px 12px 42px; }
.pub-drawer-cats a {
  padding: 6px 12px; border-radius: var(--q-r-pill);
  border: 1px solid var(--q-border); font-size: var(--q-fs-base); color: var(--q-ink-2);
}
.pub-drawer-wa {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  margin-top: auto; padding: 12px; border-radius: var(--q-r-md);
  background: #25D366; color: #0B3D1E; font-weight: 600;
}

/* ── Botón flotante de WhatsApp ─────────────────────────────────── */
.wa-float {
  position: fixed; right: 18px; bottom: 18px; z-index: 45;
  width: 54px; height: 54px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: #25D366; color: #fff;
  box-shadow: 0 8px 24px rgba(37,211,102,.35), 0 2px 6px rgba(14,14,12,.15);
  transition: transform var(--q-dur-base) var(--q-ease), box-shadow var(--q-dur-base) var(--q-ease);
  animation: wa-in .6s var(--q-ease) .8s both;
}
.wa-float:hover { transform: translateY(-3px) scale(1.04); box-shadow: 0 12px 28px rgba(37,211,102,.45), 0 2px 6px rgba(14,14,12,.15); }
@keyframes wa-in { from { opacity: 0; transform: translateY(16px) scale(.8); } to { opacity: 1; transform: none; } }

/* ── Pie de página ──────────────────────────────────────────────── */
.pub-footer {
  background: var(--q-surface); border-top: 1px solid var(--q-border);
  padding: var(--q-s-8) var(--q-s-4) var(--q-s-5);
}
.pub-footer-inner {
  max-width: 1180px; margin: 0 auto;
  display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: var(--q-s-6);
}
.pub-footer-brand img { height: calc(26px * var(--q-logo-scale, 1)); width: auto; max-width: calc(160px * var(--q-logo-scale, 1)); object-fit: contain; }
.pub-footer-brand p { margin: 10px 0 0; color: var(--q-ink-3); font-size: var(--q-fs-base); line-height: 1.5; max-width: 30ch; }
.pub-footer-brand .pub-social { justify-content: flex-start; margin-top: var(--q-s-4); padding: 0; }
.pub-footer-col { display: flex; flex-direction: column; gap: 8px; font-size: var(--q-fs-base); color: var(--q-ink-3); }
.pub-footer-col a, .pub-footer-col span { display: inline-flex; align-items: center; gap: 6px; }
.pub-footer-col a:hover { color: var(--q-ink); }
.pub-footer-title {
  font-size: var(--q-fs-xs); font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--q-ink); margin-bottom: 4px;
}
.pub-footer-pays { display: flex; flex-wrap: wrap; gap: 6px; }
.pub-footer-pay {
  padding: 4px 9px; border-radius: var(--q-r-pill);
  background: var(--q-bg-soft); border: 1px solid var(--q-border-subtle);
  font-size: var(--q-fs-sm); color: var(--q-ink-2);
}
.pub-footer-note { font-size: var(--q-fs-sm); line-height: 1.5; }
.pub-footer-policy {
  max-width: 1180px; margin: var(--q-s-5) auto 0;
  padding: 12px 0 0; border-top: 1px solid var(--q-border-subtle);
  font-size: var(--q-fs-base); color: var(--q-ink-3);
}
.pub-footer-policy summary { cursor: pointer; font-weight: 600; color: var(--q-ink-2); }
.pub-footer-policy p { margin: 8px 0 0; white-space: pre-line; max-width: 70ch; }
.pub-footer-bottom {
  max-width: 1180px; margin: var(--q-s-5) auto 0; padding-top: var(--q-s-4);
  border-top: 1px solid var(--q-border-subtle);
  font-size: var(--q-fs-sm); color: var(--q-ink-4);
}
@media (max-width: 860px) {
  .pub-footer-inner { grid-template-columns: 1fr 1fr; }
  .pub-footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 520px) {
  .pub-footer-inner { grid-template-columns: 1fr; gap: var(--q-s-5); }
  .pub-footer { padding-bottom: 90px; } /* que el WhatsApp flotante no tape el pie */
}

/* ── Tarjeta de producto: segunda foto al pasar el mouse ───────── */
.cat-card-img { overflow: hidden; }
.cat-card-img img { transition: transform .6s var(--q-ease), opacity var(--q-dur-slow) var(--q-ease); }
.cat-card-img-alt { position: absolute; inset: 0; opacity: 0; }
@media (hover: hover) {
  .cat-card:hover .cat-card-img img { transform: scale(1.04); }
  .cat-card:hover .cat-card-img.has-alt img:first-child { opacity: 0; }
  .cat-card:hover .cat-card-img-alt { opacity: 1; }
}
.cat-card { box-shadow: var(--q-shadow-1); }
.cat-card:hover { box-shadow: var(--q-shadow-3); }

/* ── Inicio ─────────────────────────────────────────────────────── */
.home-doors { display: grid; grid-template-columns: 1fr 1fr; gap: var(--q-s-4); }
.home-door {
  position: relative; overflow: hidden;
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--q-s-6); border-radius: var(--q-r-xl);
  border: 1px solid var(--q-border);
  transition: transform var(--q-dur-base) var(--q-ease), box-shadow var(--q-dur-base) var(--q-ease);
}
.home-door:hover { transform: translateY(-3px); box-shadow: var(--q-shadow-pop); }
.home-door--live { background: var(--q-primary); color: var(--q-on-primary); border-color: var(--q-primary); }
.home-door--store { background: var(--q-surface); color: var(--q-ink); }
.home-door-icon {
  width: 46px; height: 46px; margin-bottom: 8px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--q-lima); color: var(--q-on-accent);
}
.home-door--store .home-door-icon { background: var(--q-bg-soft); color: var(--q-ink); }
.home-door-kicker { font-size: var(--q-fs-xs); font-weight: 600; letter-spacing: .08em; text-transform: uppercase; opacity: .7; }
.home-door-title { font-family: var(--q-font-display); font-size: 22px; font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; }
.home-door-text { font-size: var(--q-fs-md); opacity: .8; line-height: 1.5; max-width: 38ch; }
.home-door-cta {
  display: inline-flex; align-items: center; gap: 6px; margin-top: 10px;
  font-weight: 600; font-size: var(--q-fs-md);
}
.home-door-cta svg { transition: transform var(--q-dur-base) var(--q-ease); }
.home-door:hover .home-door-cta svg { transform: translateX(4px); }

.home-track {
  display: flex; align-items: center; gap: 10px;
  margin-top: var(--q-s-3); padding: 12px 16px;
  background: var(--q-surface); border: 1px solid var(--q-border); border-radius: var(--q-r-md);
  color: var(--q-ink-2); font-size: var(--q-fs-base);
  transition: border-color var(--q-dur-fast) var(--q-ease);
}
.home-track span { flex: 1; }
.home-track:hover { border-color: var(--q-primary); }

.home-section { margin-top: var(--q-s-8); }
.home-section-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--q-s-3);
  margin-bottom: var(--q-s-4);
}
.home-section-head h2 { margin: 0; font-size: 22px; font-weight: 700; letter-spacing: -0.02em; }

.home-cats { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--q-s-3); }
.home-cat {
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px 8px 12px; border-radius: var(--q-r-lg);
  background: var(--q-surface); border: 1px solid var(--q-border);
  transition: transform var(--q-dur-base) var(--q-ease), box-shadow var(--q-dur-base) var(--q-ease);
}
.home-cat:hover { transform: translateY(-3px); box-shadow: var(--q-shadow-3); }
.home-cat-img {
  aspect-ratio: 1 / 1; margin-bottom: 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  border-radius: calc(var(--q-r-lg) - 3px); background: var(--q-bg-soft); color: var(--q-ink-4);
}
.home-cat-img img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--q-ease); }
.home-cat:hover .home-cat-img img { transform: scale(1.06); }
.home-cat-name { font-weight: 600; color: var(--q-ink); padding: 0 4px; }
.home-cat-count { font-size: var(--q-fs-sm); color: var(--q-ink-4); padding: 0 4px; }

.home-steps {
  list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--q-s-4);
}
.home-steps li {
  display: flex; flex-direction: column; gap: 6px;
  padding: var(--q-s-5); border-radius: var(--q-r-lg);
  background: var(--q-surface); border: 1px solid var(--q-border);
  color: var(--q-ink-3); font-size: var(--q-fs-base); line-height: 1.5;
}
.home-steps strong { color: var(--q-ink); font-size: var(--q-fs-lg); }
.home-step-num {
  width: 32px; height: 32px; border-radius: 50%; margin-bottom: 4px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--q-primary); color: var(--q-on-primary);
  font-family: var(--q-font-mono); font-weight: 600;
}

@media (max-width: 760px) {
  .home-doors, .home-steps { grid-template-columns: 1fr; }
  .home-door { padding: var(--q-s-5); }
  .home-door-title { font-size: 20px; }
  .home-section { margin-top: var(--q-s-7); }
  .home-cats { grid-template-columns: repeat(2, 1fr); }
}

/* En la tienda el pie de página va debajo: el contenido no necesita
   ocupar toda la pantalla (eso sólo sirve para centrar el login). */
.pub--store { min-height: 60vh; }

/* Guía de pasos de la compra (carrito → confirmar → listo) */
.flow-steps {
  list-style: none; margin: 0 0 var(--q-s-4); padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
}
.flow-steps li {
  position: relative; display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; border-radius: var(--q-r-md);
  background: var(--q-surface); border: 1px solid var(--q-border-subtle);
  font-size: var(--q-fs-sm); color: var(--q-ink-4);
}
.flow-steps-num {
  width: 22px; height: 22px; flex: none; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--q-border-strong); font-family: var(--q-font-mono); font-size: 11px; font-weight: 600;
}
.flow-steps-text { line-height: 1.2; }
.flow-steps li.is-current { border-color: var(--q-primary); color: var(--q-ink); font-weight: 600; box-shadow: var(--q-shadow-2); }
.flow-steps li.is-current .flow-steps-num { background: var(--q-primary); border-color: var(--q-primary); color: var(--q-on-primary); }
.flow-steps li.is-done { color: var(--q-ink-2); }
.flow-steps li.is-done .flow-steps-num { background: var(--q-success); border-color: var(--q-success); color: #fff; }

/* Avance del pedido en el seguimiento */
.track-progress { height: 8px; border-radius: var(--q-r-pill); background: var(--q-bg-soft); overflow: hidden; }
.track-progress-fill {
  height: 100%; width: var(--p); border-radius: inherit;
  background: linear-gradient(90deg, var(--q-primary), var(--q-lima));
  animation: track-grow 1s var(--q-ease) both;
}
@keyframes track-grow { from { width: 0; } }
.track-progress-label { margin: 8px 0 var(--q-s-3); font-size: var(--q-fs-sm); color: var(--q-ink-3); }
/* =============================================================
   Panel — rediseño (Proyecto 4)
   ============================================================= */

/* ── Botón de estado del pedido ──────────────────────────────────── */
.status-menu { position: relative; display: inline-flex; }
.status-menu-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 28px; padding: 0 10px; cursor: pointer;
  border: 1px solid transparent; border-radius: var(--q-r-pill);
  font: 600 var(--q-fs-sm)/1 var(--q-font-sans); white-space: nowrap;
  transition: box-shadow var(--q-dur-fast) var(--q-ease), transform var(--q-dur-fast) var(--q-ease), filter var(--q-dur-fast) var(--q-ease);
}
.status-menu-btn:hover:not(:disabled) { filter: brightness(.96); box-shadow: 0 0 0 3px rgba(14,14,12,.06); }
.status-menu-btn:active:not(:disabled) { transform: scale(.97); }
.status-menu-btn:disabled { cursor: default; }
.status-menu-btn svg { opacity: .7; transition: transform var(--q-dur-base) var(--q-ease); }
.status-menu-btn[aria-expanded="true"] svg { transform: rotate(180deg); }
.status-menu-btn--warning { background: var(--q-warning-soft); color: var(--q-warning-ink); }
.status-menu-btn--info    { background: var(--q-info-soft);    color: var(--q-info-ink); }
.status-menu-btn--neutral { background: var(--q-bg-soft);      color: var(--q-ink-2); border-color: var(--q-border); }
.status-menu-btn--accent  { background: var(--q-lima-soft);    color: var(--q-lima-deep); }
.status-menu-btn--success { background: var(--q-success-soft); color: var(--q-success-ink); }
.status-menu-btn--danger  { background: var(--q-danger-soft);  color: var(--q-danger-ink); }

.status-dot { width: 8px; height: 8px; flex: none; border-radius: 50%; background: currentColor; }
.status-dot--warning { background: var(--q-warning); }
.status-dot--info    { background: var(--q-info); }
.status-dot--neutral { background: var(--q-ink-4); }
.status-dot--accent  { background: var(--q-lima-deep); }
.status-dot--success { background: var(--q-success); }
.status-dot--danger  { background: var(--q-danger); }

.status-menu-panel {
  position: fixed; z-index: 90; width: 270px; padding: 6px;
  background: var(--q-surface); border: 1px solid var(--q-border);
  border-radius: var(--q-r-lg); box-shadow: var(--q-shadow-pop);
  transform-origin: top left;
}
.status-menu-title {
  padding: 6px 8px 8px; font-size: var(--q-fs-xs); font-weight: 600;
  letter-spacing: .06em; text-transform: uppercase; color: var(--q-ink-4);
}
.status-menu-panel form { margin: 0; }
.status-menu-item {
  width: 100%; display: flex; align-items: flex-start; gap: 10px;
  padding: 8px; border: 0; border-radius: var(--q-r-md); cursor: pointer;
  background: transparent; text-align: left; font: inherit; color: var(--q-ink);
  transition: background var(--q-dur-fast) var(--q-ease);
}
.status-menu-item .status-dot { margin-top: 5px; }
.status-menu-item:hover, .status-menu-item:focus-visible { background: var(--q-bg-soft); }
.status-menu-item strong { display: block; font-size: var(--q-fs-base); font-weight: 600; }
.status-menu-item small { display: block; font-size: var(--q-fs-sm); color: var(--q-ink-4); line-height: 1.35; margin-top: 1px; }
.status-menu-item.is-disabled { cursor: not-allowed; opacity: .55; }
.status-menu-item.is-disabled:hover { background: transparent; }
.status-menu-reason { display: flex; gap: 6px; padding: 4px 8px 8px 26px; }
.status-menu-reason .q-input { flex: 1; min-width: 0; height: 30px; }

/* ── Menú lateral agrupado ────────────────────────────────────────── */
.q-side-group {
  padding: 14px 10px 4px; font-size: 10px; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase; color: var(--q-ink-4);
}
.q-side-item { transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease), padding var(--q-dur-fast) var(--q-ease); }
.q-side-item:not(.q-side-item--active):hover { padding-left: 14px; }

/* ── Barra superior: botón "Nuevo" y menú de usuario ─────────────── */
.top-menu { position: relative; }
.top-menu-panel {
  position: absolute; top: calc(100% + 8px); right: 0; z-index: 60;
  min-width: 230px; padding: 6px;
  background: var(--q-surface); border: 1px solid var(--q-border);
  border-radius: var(--q-r-lg); box-shadow: var(--q-shadow-pop);
  transform-origin: top right;
}
.top-menu-item {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 9px 10px; border: 0; border-radius: var(--q-r-md);
  background: transparent; font: inherit; font-size: var(--q-fs-base); color: var(--q-ink-2);
  text-align: left; cursor: pointer;
  transition: background var(--q-dur-fast) var(--q-ease), color var(--q-dur-fast) var(--q-ease);
}
.top-menu-item:hover { background: var(--q-bg-soft); color: var(--q-ink); }
.top-menu-item small { display: block; color: var(--q-ink-4); font-size: var(--q-fs-xs); }
.top-menu-item--danger:hover { background: var(--q-danger-soft); color: var(--q-danger-ink); }
.top-menu-sep { height: 1px; margin: 6px 4px; background: var(--q-border-subtle); }
.top-menu-head { display: flex; align-items: center; gap: 10px; padding: 8px 10px 10px; }
.top-menu-head strong { display: block; font-size: var(--q-fs-base); color: var(--q-ink); }
.top-menu-head span { font-size: var(--q-fs-xs); color: var(--q-ink-4); text-transform: uppercase; letter-spacing: .05em; }
.top-user-btn {
  display: inline-flex; align-items: center; gap: 6px; padding: 3px 8px 3px 3px;
  border: 1px solid var(--q-border); border-radius: var(--q-r-pill);
  background: var(--q-surface); cursor: pointer; color: var(--q-ink-3);
  transition: border-color var(--q-dur-fast) var(--q-ease);
}
.top-user-btn:hover { border-color: var(--q-border-strong); }

/* ── Dashboard por canal ─────────────────────────────────────────── */
.channel-split { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--q-s-3); }
.channel-split-item {
  padding: 14px; border-radius: var(--q-r-md); border: 1px solid var(--q-border-subtle);
  background: var(--q-surface-2);
}
.channel-split-item .kpi-value { font-size: 22px; }
.channel-bar { display: flex; height: 10px; border-radius: var(--q-r-pill); overflow: hidden; background: var(--q-bg-soft); margin-top: var(--q-s-3); }
.channel-bar span { display: block; height: 100%; transition: width .8s var(--q-ease); }
.channel-bar .is-live { background: var(--q-lima); }
.channel-bar .is-tienda { background: var(--q-info); }
.channel-bar .is-mixto { background: var(--q-warning); }
@media (max-width: 760px) { .channel-split { grid-template-columns: 1fr; } }

.pending-row {
  display: flex; align-items: center; gap: var(--q-s-3);
  padding: 10px 16px; border-bottom: 1px solid var(--q-border-subtle);
  transition: background var(--q-dur-fast) var(--q-ease);
}
.pending-row:last-child { border-bottom: 0; }
.pending-row:hover { background: var(--q-bg-soft); }

@media (max-width: 760px) { .hide-sm { display: none; } }
