/* =============================================================
   ROCKET REDESIGN v2 — Ajustes de integración
   Lo que el prototipo no traía porque no aplicaba a una demo estática:
   variantes de aviso que sí usa el panel, paginador de Laravel con el
   look del .pager del diseño, y utilidades de maquetación.

   El design system vive en rocket-v2.css (generado del prototipo) y no
   se toca a mano: todo lo nuestro va aquí para poder regenerar aquel.
   ============================================================= */

/* ---------- Avisos: el prototipo solo definía .err y .ok ---------- */
.albar.warn { background: rgba(222,120,30,.09); border: 1px solid rgba(222,120,30,.26); color: #A2560F; }
.albar.info { background: rgba(62,155,255,.09); border: 1px solid rgba(62,155,255,.26); color: #1F6FCC; }
.albar > svg { width: 20px; height: 20px; flex-shrink: 0; }
:root[data-theme="dark"] .albar.warn { background: rgba(222,120,30,.14); border-color: rgba(222,120,30,.34); color: #F0B173; }
:root[data-theme="dark"] .albar.info { background: rgba(62,155,255,.13); border-color: rgba(62,155,255,.32); color: #8FC2FF; }
.albar.ok > svg, .albar.err > svg, .albar.warn > svg, .albar.info > svg { color: inherit; }

/* ---------- Dropdown de notificaciones vacío ---------- */
.notif-empty { padding: 26px 12px; text-align: center; color: var(--ink-3); font-size: .86rem; }
.ni-ic.info { background: rgba(62,155,255,.14); color: var(--info); }
.ni-ic.ok, .ni-ic.success { background: rgba(15,160,95,.14); color: var(--pos); }
.ni-ic.warn, .ni-ic.warning { background: rgba(222,120,30,.15); color: var(--warn); }
.ni-ic.err, .ni-ic.danger { background: rgba(224,87,83,.14); color: var(--neg); }
.ni-ic.primary { background: var(--accent-soft); color: var(--accent); }

/* ---------- Paginador de Laravel con el look del .pager del diseño ----------
   El paginador del framework pinta <a>/<span>; el prototipo usaba <span
   onclick>. Se comparte todo el estilo de .pg y solo se resuelve el estado
   deshabilitado, que aquí no es un atributo sino una clase. */
.pager .pg.disabled { opacity: .38; cursor: not-allowed; pointer-events: none; }
.pager .pg { text-decoration: none; }

/* ---------- Utilidades de maquetación ---------- */
.v2-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.v2-row.end { justify-content: flex-end; }
.v2-spacer { flex: 1 1 auto; }
.v2-mt { margin-top: 16px; }
.v2-mb { margin-bottom: 16px; }
.v2-nowrap { white-space: nowrap; }
.v2-right { text-align: right; }
.v2-center { text-align: center; }
.v2-g2 { grid-template-columns: repeat(2, 1fr); }
.v2-g3 { grid-template-columns: repeat(3, 1fr); }
.v2-g4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 1100px) { .v2-g4 { grid-template-columns: repeat(2, 1fr); } .v2-g3 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 700px)  { .v2-g4, .v2-g3, .v2-g2 { grid-template-columns: 1fr; } }

/* Etiquetas de formulario reutilizables (el prototipo las tenía inline) */
.v2-field { display: block; margin-bottom: 14px; }
.v2-field > span { display: block; font-weight: 600; font-size: .84rem; color: var(--ink-2); margin-bottom: 7px; }
.v2-field .inp-err { border-color: var(--neg); box-shadow: 0 0 0 3px rgba(224,87,83,.13); }
.v2-help { font-size: .8rem; color: var(--ink-3); margin-top: 6px; line-height: 1.5; }
.v2-err { font-size: .8rem; color: var(--neg); margin-top: 6px; }

/* Bloque de cabecera de tarjeta reutilizable (equivale al .et-hd del diseño
   pero admite envolver en móvil sin desbordar). */
.v2-cardhd { display: flex; align-items: center; justify-content: space-between; gap: 14px; padding: 18px 20px 14px; flex-wrap: wrap; }
.v2-cardhd b { font-size: 1.08rem; letter-spacing: -.015em; }
.v2-cardhd .v2-cardhd-r { display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }

/* Tabla: celda que no debe partirse y celda numérica monoespaciada */
.tbl td.num, .tbl th.num { font-family: var(--mono); text-align: right; white-space: nowrap; }

/* Selector nativo con el aspecto de .inp (formularios portados) */
select.inp { appearance: none; -webkit-appearance: none; padding-right: 36px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239B9CA8' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center; background-size: 15px; }

/* Imagen de producto en tablas y tarjetas */
.v2-thumb { width: 46px; height: 46px; border-radius: 12px; object-fit: cover; background: var(--chip); flex-shrink: 0; }
.v2-thumb.lg { width: 72px; height: 72px; border-radius: 14px; }

/* ---------- Checkbox (confirmación masiva de pedidos) ----------
   El prototipo no dibujó selección múltiple en la tabla de pedidos, pero el
   panel real la tiene y es la forma rápida de confirmar. Se construye con los
   tokens del design system para que no desentone. */
.v2-chk { display: inline-flex; align-items: center; cursor: pointer; }
.v2-chk input { position: absolute; opacity: 0; width: 0; height: 0; }
.v2-chk i { width: 19px; height: 19px; border-radius: 6px; border: 1.5px solid var(--line); background: var(--bg); display: block; position: relative; transition: .15s; }
.v2-chk i::after { content: ''; position: absolute; left: 5.5px; top: 2px; width: 5px; height: 9px; border: solid #fff; border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0); transition: transform .15s; }
.v2-chk input:checked + i { background: var(--accent); border-color: var(--accent); }
.v2-chk input:checked + i::after { transform: rotate(45deg) scale(1); }
.v2-chk:hover i { border-color: var(--accent); }
:root[data-theme="dark"] .v2-chk input:checked + i::after { border-color: #0A0A0E; }

/* Barra flotante de acción masiva */
.v2-bulk { position: sticky; bottom: 18px; z-index: 60; display: none; align-items: center; gap: 14px;
  margin: 14px auto 0; padding: 12px 18px; width: fit-content; border-radius: var(--r-pill);
  background: var(--negro); color: #fff; box-shadow: var(--sh-pop); }
.v2-bulk.on { display: flex; }
.v2-bulk b { font-family: var(--mono); font-size: .84rem; }
:root[data-theme="dark"] .v2-bulk { background: var(--panel); border: 1px solid var(--line); color: var(--ink); }

/* ---------- Catálogo: imágenes reales ----------
   El prototipo pintaba los productos con emoji (.pi-e / .plr-img como texto).
   En el panel real son fotos, así que aquí se define cómo se encajan dentro de
   los mismos contenedores del design system. */
.prod-img img { width: 100%; height: 100%; object-fit: contain; padding: 14px; transition: transform .35s cubic-bezier(.19,1,.22,1); }
.prod:hover .prod-img img { transform: scale(1.06) translateY(-3px); }
.prod-body h4 a { color: inherit; }
.prod-flag { position: absolute; top: 12px; left: 12px; font-family: var(--mono); font-size: .64rem; font-weight: 700;
  background: rgba(15,160,95,.16); color: var(--pos); padding: 4px 9px; border-radius: 20px; letter-spacing: .04em; }
img.plr-img { width: 56px; height: 56px; border-radius: 12px; object-fit: contain; background: var(--chip); flex-shrink: 0; padding: 4px; }

/* Barra superior del catálogo (contador + orden + vista) cuando el filtrado es
   de servidor: los enlaces sustituyen a los botones con onclick del prototipo. */
.cat-bar { align-items: center; }

/* ---------- Barra de porcentaje (calidad de cliente, tasas) ----------
   El prototipo mostraba las tasas dentro de un anillo; aquí hacen falta
   además barras horizontales con el número al lado. */
.v2-rate { display: flex; align-items: center; gap: 12px; }
.v2-rate > i { display: block; height: 22px; border-radius: 8px; flex: 0 0 auto; min-width: 4px; transition: width .9s cubic-bezier(.19,1,.22,1); }
.v2-rate > b { font-family: var(--mono); font-size: .92rem; font-weight: 700; }
.v2-rate::before { content: ''; position: absolute; }
.card > .v2-rate { position: relative; }

/* La fila de búsqueda de calidad de cliente respira igual que el resto de
   formularios del panel cuando el viewport se estrecha. */
@media (max-width: 700px) { .cal-searchrow { flex-direction: column; align-items: stretch !important; } }

/* ---------- Motivos de rechazo (modal) ----------
   Lista de opciones excluyentes con el mismo lenguaje que los chips del
   diseño: el radio nativo se oculta y la propia fila hace de control. */
.rj-opts { display: flex; flex-direction: column; gap: 6px; }
.rj-opt { display: flex; align-items: center; gap: 11px; padding: 11px 14px; border: 1px solid var(--line);
  border-radius: var(--r-ctrl); cursor: pointer; font-size: .89rem; transition: .14s; background: var(--bg); }
.rj-opt:hover { border-color: var(--accent); }
.rj-opt input { position: absolute; opacity: 0; width: 0; height: 0; }
.rj-opt::before { content: ''; width: 17px; height: 17px; border-radius: 50%; border: 2px solid var(--line);
  flex-shrink: 0; transition: .14s; }
.rj-opt:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); font-weight: 600; }
.rj-opt:has(input:checked)::before { border-color: var(--accent); border-width: 5px; }
/* Fallback para navegadores sin :has() — la clase la pone el propio input */
.rj-opt input:checked ~ span { font-weight: 600; }

/* ---------- Inicio bento sin evento ----------
   El bento del diseño reserva un área para el ticket del evento. Si no hay
   evento configurado no se pinta, y sin esto quedaría un hueco: se recoloca
   el ranking arriba a lo ancho. */
.bento.no-tkt { grid-template-areas: "lb lb lb" "tkr tkr tkr" "nvl pvd cmt" "tape tape tape" "acd acd rf2"; }

/* La tarjeta de Academy y la de integraciones son enlaces: sin esto heredan el
   subrayado y el color del enlace. */
/* Sin subrayado, pero SIN heredar la tinta: `a.acdb` pesa mas que `.acdb`, asi
   que un `color: inherit` aqui se comia el blanco del banner y en tema claro lo
   dejaba en casi negro sobre fondo negro. Las dos piezas son oscuras en los dos
   temas, asi que el color va fijo. */
a.acdb, a.intg2 { text-decoration: none }
a.acdb, a.acdb .acdb-title, a.acdb .acdb-sub { color: #fff }
a.acdb .acdb-title em, a.acdb .acdb-brand em { color: var(--lima) }
a.acdb .acdb-sub { color: rgba(255,255,255,.78) }
a.intg2 { color: #fff }
.lb-row { text-decoration: none; color: inherit; }

/* ---------- KYC: utilidades que espera el script heredado ----------
   El asistente del KYC viene del panel antiguo sin tocar (para no romper la
   firma del contrato) y alterna dos clases de Bootstrap que aquí no existen. */
.d-none { display: none !important; }
.inp.is-invalid, .is-invalid { border-color: var(--neg) !important; }
.inp.is-invalid:focus { box-shadow: 0 0 0 3px rgba(224,87,83,.16) !important; }

/* Bloque de firma del contrato dentro de la tarjeta del KYC. */
.kyc-sign { border: 1px solid var(--line); border-radius: var(--r-ctrl); padding: 16px 18px; background: var(--bg); }
.kyc-sign-hd { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.kyc-sign-hd b { font-size: .95rem; }
.kyc-sign canvas { width: 100%; height: 190px; background: #fff; border: 1px dashed var(--line);
  border-radius: var(--r-ctrl); touch-action: none; cursor: crosshair; }
.kyc-sign-acts { display: flex; gap: 10px; margin-top: 12px; }
.kyc-sign-acts .btn, .kyc-sign-acts .btn-out { flex: 1; width: auto; }

/* ---------- Ofertas de proveedores: hilo con el proveedor ----------
   El prototipo dibuja la tarjeta de oferta pero no el chat (allí era una
   maqueta); en el panel real cada oferta es una conversación. */
.v2-h3 { display: flex; align-items: center; gap: 10px; font-size: 1.05rem; font-weight: 700;
  letter-spacing: -.01em; margin: 26px 0 12px; }
.sof-thread { display: flex; flex-direction: column; gap: 8px; max-height: 260px; overflow-y: auto;
  margin: 4px 0 14px; padding-right: 4px; }
.sof-msg { display: flex; justify-content: flex-start; }
.sof-msg.mine { justify-content: flex-end; }
.sof-bub { max-width: 78%; background: var(--chip); border-radius: 12px; padding: 9px 13px;
  font-size: .86rem; line-height: 1.5; }
.sof-bub span { display: block; margin-top: 4px; font-size: .72rem; color: var(--ink-3); }
.sof-msg.mine .sof-bub { background: var(--accent); color: #fff; }
.sof-msg.mine .sof-bub span { color: rgba(255,255,255,.72); }
:root[data-theme="dark"] .sof-msg.mine .sof-bub { color: #0A0A0E; }
:root[data-theme="dark"] .sof-msg.mine .sof-bub span { color: rgba(10,10,14,.62); }
.sof-reply { display: flex; gap: 8px; margin-top: auto; }
.sof-reply .inp { flex: 1; }

/* Mensajes de validación de los ficheros del KYC.
   checkForm() los rellena en cuanto carga la página, así que —como hacía
   Bootstrap en el panel antiguo— solo se enseñan cuando el campo está
   realmente marcado como inválido, no al entrar. */
.invalid-feedback { display: none; color: var(--neg); font-weight: 600; }
.kyc-up:has(input.is-invalid) .invalid-feedback,
.field:has(input.is-invalid) .invalid-feedback { display: block; }
.kyc-up:has(input.is-invalid) { border-color: var(--neg); }

/* ---------- Editar pedido ----------
   La pantalla existe en el prototipo como modal XL; aquí es página, así que el
   layout de dos columnas y la barra de acciones inferior son propios. El resto
   (tarjetas, tablas, campos, desplegables) sale del design system. */
.oe-grid { display: grid; grid-template-columns: minmax(0, 1fr) 400px; gap: 18px; align-items: start; }
.oe-main { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.oe-side { position: sticky; top: 18px; }
.oe-card { padding: 0; overflow: hidden; }
.oe-body { padding: 18px 20px 22px; display: flex; flex-direction: column; gap: 14px; }
.oe-acts { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.oe-acts .btn-out, .oe-acts .btn { width: auto; padding: 8px 14px; font-size: .82rem; }

/* fila de producto */
.oe-prod { display: flex; align-items: center; gap: 12px; }
.oe-prod-img { width: 46px; height: 46px; border-radius: 10px; background: var(--chip); flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; overflow: hidden; color: var(--ink-3); }
.oe-prod-img img { width: 100%; height: 100%; object-fit: cover; }
.oe-prod-img svg { width: 20px; height: 20px; }
.oe-prod-tx { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.oe-prod-name { border: none !important; background: transparent !important; padding: 0 !important;
  font-weight: 640; font-size: .92rem; height: auto !important; }
.oe-prod-tx .mono { font-size: .72rem; }

/* selector de cantidad */
.oe-qty { display: inline-flex; align-items: center; border: 1px solid var(--line); border-radius: var(--r-ctrl); overflow: hidden; }
.oe-qty .inp { width: 56px; text-align: center; border: none !important; border-radius: 0 !important;
  background: transparent !important; -moz-appearance: textfield; }
.oe-qty .inp::-webkit-outer-spin-button, .oe-qty .inp::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.oe-qty-b { width: 34px; height: 38px; border: none; background: var(--chip); color: var(--ink-2);
  font-size: 1.05rem; cursor: pointer; transition: .14s; }
.oe-qty-b:hover { background: var(--accent-soft); color: var(--accent); }

/* pie de la tarjeta de productos */
.oe-foot { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  padding: 16px 20px; border-top: 1px solid var(--line); background: var(--bg); }
.oe-envio { font-size: .88rem; color: var(--ink-2); }
.oe-total { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.oe-total-in { display: flex; align-items: center; gap: 8px; }
.oe-total-in .inp { width: 140px; text-align: right; font-family: var(--mono); font-weight: 700; font-size: 1.02rem; }
.oe-cur { font-family: var(--mono); color: var(--ink-3); font-size: .86rem; }

/* historial */
.oe-tl { padding: 6px 20px 20px; display: flex; flex-direction: column; }
.oe-tl-i { display: grid; grid-template-columns: 16px minmax(0, 1fr) auto; gap: 12px; padding: 13px 0;
  border-bottom: 1px solid var(--line); align-items: start; }
.oe-tl-i:last-child { border-bottom: none; }
.oe-tl-dot { width: 9px; height: 9px; border-radius: 50%; background: var(--line); margin-top: 6px; }
.oe-tl-i.manual .oe-tl-dot { background: var(--accent); }
.oe-tl-hd { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.oe-tl-tx p { margin: 5px 0 0; font-size: .86rem; color: var(--ink-2); line-height: 1.5; }
.oe-tl-date { font-size: .74rem; color: var(--ink-3); text-align: right; white-space: nowrap; line-height: 1.5; }

/* varios del lateral */
.oe-inline { display: flex; align-items: center; gap: 8px; }
.oe-inline .inp { flex: 1; min-width: 0; }
.oe-inline .btn-out, .oe-inline .btn { width: auto; padding: 10px 14px; flex-shrink: 0; }
.oe-sep { height: 1px; background: var(--line); margin: 4px 0; }
.oe-track { background: var(--chip); border-radius: var(--r-ctrl); padding: 14px 16px; display: flex; flex-direction: column; gap: 8px; }
.oe-track-code { font-size: 1rem; font-weight: 700; letter-spacing: .02em; }
.oe-track-acts { display: flex; gap: 8px; flex-wrap: wrap; }
.oe-track-acts .btn-out { width: auto; padding: 8px 13px; font-size: .8rem; }
.oe-track-old { margin: 4px 0 0; padding-left: 16px; font-size: .78rem; color: var(--ink-3); }

/* barra de acciones */
/* La barra sobresale hasta el borde del contenido (main lleva 24/32px de padding
   y 60px abajo) y se queda pegada al fondo mientras se edita. */
.oe-bar { position: sticky; bottom: -60px; z-index: 30; display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 18px -32px -60px; padding: 14px 32px calc(14px + 60px); background: var(--panel);
  border-top: 1px solid var(--line); box-shadow: 0 -8px 24px -14px rgba(20,20,26,.22); }

/* El dock flotante (WhatsApp + Primeros pasos) se sube por encima de la barra:
   si no, la tapa justo donde están Guardar y Confirmar. */
body:has(.oe-bar) .dockfab { bottom: 92px; }
.oe-dirty { display: none; align-items: center; gap: 7px; font-size: .84rem; font-weight: 600; color: var(--warn); }
.oe-dirty svg { width: 16px; height: 16px; }
.oe-bar.dirty .oe-dirty { display: inline-flex; }

/* modales internos: overlay fijo que solo se muestra/oculta */
.oe-ov { display: none; }
.oe-ov.open { display: flex; }
.oe-modal-acts { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.oe-carriers { display: flex; flex-direction: column; gap: 8px; }
.oe-carrier { display: flex; align-items: flex-start; gap: 11px; padding: 12px 14px; border: 1px solid var(--line);
  border-radius: var(--r-ctrl); cursor: pointer; transition: .14s; background: var(--bg); }
.oe-carrier:hover { border-color: var(--accent); }
.oe-carrier.off { opacity: .5; cursor: not-allowed; }
.oe-carrier:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.oe-carrier-tx { display: flex; flex-direction: column; gap: 2px; font-size: .88rem; }
.oe-carrier-tx .mut { font-size: .78rem; }

@media (max-width: 1100px) {
  .oe-grid { grid-template-columns: 1fr; }
  .oe-side { position: static; }
}
@media (max-width: 700px) {
  .oe-bar { margin: 18px -16px -60px; padding: 12px 16px calc(12px + 60px); }
  .oe-foot { flex-direction: column; align-items: stretch; }
  .oe-total { align-items: stretch; }
  .oe-total-in .inp { width: 100%; }
}

/* Cuentas del pedido (vista de solo lectura) */
.oe-costs { padding: 14px 20px 18px; border-top: 1px solid var(--line); display: flex; flex-direction: column; gap: 9px; }
.oe-cost { display: flex; align-items: center; justify-content: space-between; gap: 16px; font-size: .88rem; color: var(--ink-2); }
.oe-cost span { display: inline-flex; align-items: center; gap: 6px; }
.oe-cost b { font-weight: 700; color: var(--ink); }
.oe-cost.pos, .oe-cost.pos b { color: var(--pos); }
.oe-profit { margin-top: 4px; padding-top: 12px; border-top: 1px solid var(--line); font-size: .95rem; }
.oe-profit span { font-weight: 640; color: var(--ink); }
.oe-profit b { background: rgba(15,160,95,.12); color: var(--pos); padding: 5px 12px; border-radius: var(--r-chip); font-size: 1rem; }
.oe-info { display: inline-flex; color: var(--ink-3); cursor: help; }
.oe-info svg { width: 15px; height: 15px; }

/* ══════════════════════════════════════════════════════════════════
   CREAR PEDIDO — /app/orders/create

   El resumen lo calcula create-order-modal.js, que es el módulo del panel
   antiguo y pinta su propio HTML (tarjetas de transportadora y filas de
   producto) con clases de Bootstrap. Aquí se les da el aspecto del rediseño
   sin tocar el módulo, que lo comparten cinco vistas del panel viejo.
   ══════════════════════════════════════════════════════════════════ */

.co-ship { max-height: 30em; overflow-y: auto; overflow-x: hidden; padding-right: 4px; }

/* Tarjeta de transportadora → .ship-row del diseño */
.co-ship .card-list-shipping {
  display: flex; align-items: center; gap: 13px;
  padding: 11px 14px; margin-bottom: 10px;
  border: 1.5px solid var(--line); border-radius: 14px;
  background: var(--panel); cursor: pointer;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.co-ship .card-list-shipping:hover { border-color: var(--accent); }
.co-ship .card-list-shipping.border-orange { border-color: var(--accent); background: var(--accent-soft); }
.co-ship .card-list-shipping.no-coverage { opacity: .5; cursor: not-allowed; }
.co-ship .card-list-shipping.no-coverage:hover { border-color: var(--line); }
/* Sin ciudad elegida: gris y sin clic (el JS además quita pointer-events) */
.co-ship .card-list-shipping.pending-city { opacity: .5; cursor: not-allowed; }
.co-ship .card-list-shipping.pending-city:hover { border-color: var(--line); }
.co-ship .card-list-shipping.pending-city .shipping-rate-info { color: var(--ink-3); }
.co-ship .card-radio-label { display: flex; align-items: center; gap: 13px; width: 100%; margin: 0; cursor: inherit; }
.co-ship .card-radio-input { display: none; }
.co-ship .card-radio { display: flex; align-items: center; gap: 12px; width: 100%; text-align: left !important; }
.co-ship .card-radio img { width: 34px !important; height: 34px; object-fit: contain; flex-shrink: 0; }
.co-ship .card-radio .row { display: block; margin: 0; font-weight: 640; font-size: .9rem; color: var(--ink); }
.co-ship .card-radio br { display: none; }
.co-ship .shipping-rate-info {
  margin-left: auto !important; text-align: right;
  font-family: var(--mono); font-size: .8rem; font-weight: 600; color: var(--accent);
}

/* Filas de producto que añade el módulo */
.cp-tbl { width: 100%; margin-top: 4px; }
.cp-tbl td { padding: 9px 6px; vertical-align: middle; border-bottom: 1px solid var(--line); }
.cp-tbl tr:last-child td { border-bottom: 0; }
.cp-sel + .select2-container { width: 100% !important; }
.cp-stk { display: block; margin-top: 3px; font-size: .74rem; color: var(--accent); }
.product-qty-input { text-align: center; padding: 8px 6px; }

/* El módulo genera .form-control/.btn de Bootstrap: se traducen al sistema */
#createOrderModal .form-control,
#createOrderModal .form-control-sm {
  width: 100%; background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 9px;
  padding: 8px 10px; font: inherit; font-size: .86rem;
}
#createOrderModal .form-control:focus { outline: none; border-color: var(--accent); }
#createOrderModal .btn-outline-danger {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px;
  background: transparent; color: var(--neg); cursor: pointer;
}
#createOrderModal .btn-outline-danger:hover { border-color: var(--neg); background: rgba(224,49,49,.08); }
#createOrderModal .d-none { display: none !important; }
#createOrderModal .co-sr .sv { border: 1px solid var(--line); }
#createOrderModal .co-sum h4 { display: flex; align-items: center; justify-content: space-between; gap: 10px; }

@media (max-width: 900px) {
  .co-ship { max-height: none; }
}

/* ══════════════════════════════════════════════════════════════════
   FICHA DE PRODUCTO — /app/products/view/{id}

   El prototipo pintaba emojis en la galería; aquí hay fotos de verdad, así
   que la imagen grande se apila y solo se muestra la activa.
   ══════════════════════════════════════════════════════════════════ */

.pdx-img { position: absolute; max-width: 76%; max-height: 76%; object-fit: contain; opacity: 0; transition: opacity var(--t-fast); }
.pdx-img.on { opacity: 1; }
.pdx-thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.pdx-nav.prev svg { transform: rotate(180deg); }
.pdx-main .pdx-emoji svg { width: 84px; height: 84px; color: var(--ink-3); }

/* Cajas de información reutilizadas en packs y recursos */
.pd-box { padding: 14px 16px; border: 1px solid var(--line); border-radius: 13px; background: var(--bg); color: inherit; }
a.pd-box:hover { border-color: var(--accent); }

/* Barra de calificación del proveedor: tres tramos, uno por bloque de la nota
   (despachos, cumplimiento, postventa), igual que en el panel antiguo. */
.rate-bar.seg { display: flex; gap: 2px; }
.rate-bar.seg i { position: static; display: block; height: 100%; border-radius: 0; }
.rate-bar.seg i.s-desp { background: var(--neg); border-radius: 99px 0 0 99px; }
.rate-bar.seg i.s-cump { background: var(--warn); }
.rate-bar.seg i.s-post { background: var(--pos); border-radius: 0 99px 99px 0; }

/* ══════════════════════════════════════════════════════════════════
   CALCULADORA DE RENTABILIDAD — /app/profitability-calculator

   profitability-calculator.js va cambiando clases de estado sobre los mismos
   nodos (pc-hero-*, pc-be-marker-*, pc-pl-total-*). El prototipo no las tenía
   porque su demo no calculaba nada, así que se definen aquí.
   ══════════════════════════════════════════════════════════════════ */

/* Tarjeta de resultado: verde si gana, roja si pierde, neutra sin datos */
.pc-result.pc-hero-positive .pcr-num { color: var(--pos); }
.pc-result.pc-hero-negative .pcr-num { color: var(--neg); }
.pc-result.pc-hero-positive .pcr-tag { background: rgba(15,160,95,.12); color: var(--pos); }
.pc-result.pc-hero-negative .pcr-tag { background: rgba(224,49,49,.1); color: var(--neg); }
.pc-result.pc-hero-empty .pcr-num { color: var(--ink-3); }

/* Marca de la zona segura */
.safe-mark { z-index: 2; }
.safe-mark.pc-be-marker-gain { background: var(--pos); }
.safe-mark.pc-be-marker-loss { background: var(--neg); }
.safe-mark.pc-be-marker-empty { background: var(--ink-3); }
.safe-tip {
  position: absolute; bottom: calc(100% + 8px); left: 50%; transform: translateX(-50%);
  padding: 4px 9px; border-radius: 7px; white-space: nowrap;
  background: var(--ink); color: var(--panel);
  font-family: var(--mono); font-size: .7rem; font-weight: 600;
}

/* Fila de profit del desglose */
.pnl-row.pc-pl-total-positive b { color: var(--pos); }
.pnl-row.pc-pl-total-negative b { color: var(--neg); }

/* El enlace de "probar sin producto" es un <button> por accesibilidad */
button.pc-link { background: none; border: 0; font: inherit; cursor: pointer; }

/* El buscador de producto es un select2 */
#pc-product-search + .select2-container { width: 100% !important; }

/* El prototipo ponía la clase .on a mano al cambiar de escala; en la página el
   estado lo lleva el propio radio, así que se resuelve con CSS. */
.pc-radio label:focus-within { border-color: var(--accent); }
.pc-radio input:checked + span,
.pc-radio label:has(input:checked) { border-color: var(--accent); color: var(--accent); background: var(--accent-soft); }

/* Formularios de alta con panel de ayuda al lado (plantillas de texto). */
.tpl-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, .65fr); gap: 18px; align-items: start; }
@media (max-width: 1000px) { .tpl-grid { grid-template-columns: 1fr; } }

/* La flecha de "volver" apunta a la izquierda. */
.backlink svg { transform: rotate(180deg); }

/* ══════════════════════════════════════════════════════════════════
   ENTRADA (login, registro, recuperar)

   El script de validación del registro es el del panel antiguo y va marcando
   los campos con neon-focus-danger / neon-focus-success. Aquí se traducen al
   lenguaje del rediseño en vez de tocar el script, que es el que mide la
   captación y no interesa reescribir.
   ══════════════════════════════════════════════════════════════════ */

.ainput:has(.neon-focus-danger)  { border-color: var(--neg); }
.ainput:has(.neon-focus-success) { border-color: var(--pos); }

/* El script escribe el mensaje dentro del <strong>; se muestra solo si dice algo. */
.aerr:empty { display: none; }
.aerr:not(:empty) { display: flex; }
.aerr.text-danger  { color: var(--neg); }
.aerr.text-success { color: var(--pos); }
.aerr i { display: none; }   /* los iconos de FontAwesome que mete el script */

/* Teléfono con intl-tel-input dentro del campo del rediseño */
.ainput-tel { padding-left: 0; }
.ainput-tel .iti { flex: 1; min-width: 0; }
.ainput-tel .iti input { width: 100%; }
.iti__country-list { background: var(--panel); color: var(--ink); border-color: var(--line); }
.iti__country.iti__highlight { background: var(--chip); }
.iti__selected-dial-code { color: var(--ink-2); }

/* Recaptcha centrado en la tarjeta */
#input-recaptcha { display: flex; justify-content: center; }

/* El botón de registro va apagado hasta que el formulario vale */
.abtn.btn-register.is-invalid { background: var(--chip); color: var(--ink-3); box-shadow: none; }
.abtn.btn-register.is-invalid:hover { transform: none; }

/* ══════════════════════════════════════════════════════════════════
   ALTA DE CUENTA BANCARIA — /app/configuration/banks/create

   Esta pantalla conserva el formulario del panel antiguo entero (cinco tipos
   de cuenta, tres documentos con sus estados y una firma sobre canvas), así
   que aquí se traducen sus clases de Bootstrap al lenguaje del rediseño.
   Todo va acotado a .bank-legacy para no tocar nada más.
   ══════════════════════════════════════════════════════════════════ */

.bank-legacy .row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 20px; }
.bank-legacy .col-md-6, .bank-legacy .col-lg-6 { min-width: 0; }
.bank-legacy .col-md-12, .bank-legacy .col-lg-12, .bank-legacy .col-12 { grid-column: 1 / -1; }
@media (max-width: 760px) { .bank-legacy .row { grid-template-columns: 1fr; } }

.bank-legacy .mb-3 { margin-bottom: 18px; }
.bank-legacy .mb-2 { margin-bottom: 12px; }
.bank-legacy .mt-2 { margin-top: 10px; }

.bank-legacy .form-label {
  display: block; font-size: .82rem; font-weight: 600;
  margin-bottom: 7px; color: var(--ink-2);
}
.bank-legacy .text-danger { color: var(--neg); }
.bank-legacy .text-muted  { color: var(--ink-3); }
.bank-legacy .text-primary{ color: var(--accent); }
.bank-legacy .text-white  { color: #fff; }

.bank-legacy .form-control,
.bank-legacy .form-select,
.bank-legacy textarea {
  width: 100%; background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: 11px;
  padding: 11px 13px; font: inherit; font-size: .9rem;
}
.bank-legacy .form-control:focus,
.bank-legacy .form-select:focus,
.bank-legacy textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.bank-legacy input[type="file"].form-control { padding: 9px 12px; cursor: pointer; }
.bank-legacy .select2-container { width: 100% !important; }

.bank-legacy .card-title { font-size: 1rem; font-weight: 700; margin: 22px 0 14px; }
.bank-legacy hr { border: 0; border-top: 1px solid var(--line); margin: 20px 0; }

/* Estados de los documentos (verificado, pendiente, rechazado) */
.bank-legacy .badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 5px 11px; border-radius: var(--r-chip);
  font-size: .74rem; font-weight: 700; letter-spacing: .01em;
}
.bank-legacy .bg-success { background: rgba(15,160,95,.14); color: var(--pos); }
.bank-legacy .bg-warning { background: rgba(222,120,30,.14); color: var(--warn); }
.bank-legacy .bg-danger  { background: rgba(224,49,49,.12);  color: var(--neg); }
.bank-legacy .alert {
  padding: 12px 14px; border-radius: 12px; font-size: .85rem;
  border: 1px solid var(--line); background: var(--bg); margin-bottom: 14px;
}
.bank-legacy .alert-danger { border-color: var(--neg); background: rgba(224,49,49,.08); color: var(--neg); }

.bank-legacy .btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 9px 15px; border-radius: 10px; border: 1px solid var(--line);
  background: var(--panel); color: var(--ink);
  font: inherit; font-size: .85rem; font-weight: 600; cursor: pointer;
}
.bank-legacy .btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.bank-legacy .btn:disabled { opacity: .5; cursor: not-allowed; }
.bank-legacy .btn-success { background: var(--pos); border-color: var(--pos); color: #fff; }
.bank-legacy .btn-info    { background: var(--info); border-color: var(--info); color: #fff; }

.bank-legacy #signature-pad { background: var(--panel); border: 1px dashed var(--line) !important; border-radius: 12px; }
.bank-legacy .d-flex { display: flex; }
.bank-legacy .d-none { display: none !important; }
.bank-legacy .align-items-center { align-items: center; }
.bank-legacy .flex-fill { flex: 1; }
.bank-legacy .gap-2 { gap: 10px; }

/* Permisos del colaborador: manda el prototipo.
   Aqui habia una rejilla propia con checkbox del navegador y filas de 4px.
   El sistema ya trae .perm-grid4, .perm-card-hd, .perm-all y .pchk/.pk-box
   (casilla dibujada, filas de 8px 6px), asi que el formulario usa esas y
   estas de aqui sobraban. Solo queda el color de la etiqueta larga. */
.pchk > span:last-child { color: var(--ink-2); line-height: 1.35; }
.pchk:hover > span:last-child { color: var(--ink); }

/* ══════════════════════════════════════════════════════════════════
   ESTADÍSTICAS · Productos

   La tabla de rendimiento tiene 18 columnas y dos cabeceras (estado del pedido
   y rentabilidad), así que necesita scroll propio y la primera columna fija —
   si no, se pierde de vista qué producto estás leyendo.
   ══════════════════════════════════════════════════════════════════ */

.ep-wrap { max-height: 68vh; overflow: auto; }
.ep-tbl { min-width: 1500px; }
.ep-tbl th, .ep-tbl td { white-space: nowrap; }

.ep-tbl thead th { position: sticky; top: 0; z-index: 3; background: var(--panel); }
.ep-tbl .ep-grp-row th { top: 0; z-index: 4; }
.ep-tbl thead tr:nth-child(2) th { top: 34px; }

.ep-grp-row th {
  text-align: center; font-family: var(--mono); font-size: .62rem;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-3);
  border-bottom: 1px solid var(--line);
}
.ep-grp-row th + th { border-left: 1px solid var(--line); }

/* Primera columna fija: el nombre del producto siempre a la vista */
.ep-tbl th:first-child, .ep-tbl td:first-child {
  position: sticky; left: 0; z-index: 2; background: var(--panel);
  box-shadow: 1px 0 0 var(--line);
}
.ep-tbl thead th:first-child { z-index: 5; }
.ep-tbl tbody tr:hover td { background: var(--chip); }
.ep-tbl tbody tr:hover td:first-child { background: var(--chip); }

.ep-name { color: #3D619E; font-weight: 640; }
.ep-name:hover { text-decoration: underline; }

.ep-tbl .mut { font-weight: 400; }
.pos2 { color: var(--pos); }
.neg2 { color: var(--neg); }

/* Campo de gasto publicitario: lo teclea el vendedor */
.ep-gasto {
  display: flex; align-items: center; gap: 4px;
  background: var(--bg); border: 1px solid var(--line);
  border-radius: 9px; padding: 4px 9px; width: 104px;
}
.ep-gasto span { color: var(--ink-3); font-size: .8rem; }
.ep-gasto input {
  width: 100%; min-width: 0; border: 0; background: none;
  font-family: var(--mono); font-size: .84rem; color: var(--ink); padding: 3px 0;
}
.ep-gasto input:focus { outline: none; }
.ep-gasto:focus-within { border-color: var(--accent); }

.ep-tbl tfoot td {
  position: sticky; bottom: 0; z-index: 3;
  background: var(--bg); font-weight: 700;
  border-top: 1px solid var(--line);
}
.ep-tbl tfoot td:first-child { z-index: 4; }

/* Pestañas de estadísticas: son enlaces, no botones */
.est-tabs a.est-tab { text-decoration: none; }

/* Código de un solo uso (retirada de dinero) */
.otp-boxes { display: flex; justify-content: center; gap: 8px; }
.otp-input {
  width: 46px; height: 56px; text-align: center;
  font-family: var(--mono); font-size: 1.5rem; font-weight: 700; color: var(--ink);
  background: var(--bg); border: 1.5px solid var(--line); border-radius: 11px;
}
.otp-input:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.otp-big { text-align: center; font-family: var(--mono); font-size: 1.2rem; letter-spacing: .35rem; }
@media (max-width: 420px) { .otp-input { width: 38px; height: 48px; font-size: 1.2rem; } }

/* FAQ: artículo y listado de un tema */
.faq-art-h { font-size: 1.5rem; font-weight: 800; letter-spacing: -.02em; margin-bottom: 6px; }
.faq-art-body { color: var(--ink-2); line-height: 1.7; font-size: .95rem; }
.faq-art-body p { margin: 0 0 14px; }
.faq-art-body ul, .faq-art-body ol { margin: 0 0 14px 20px; }
.faq-art-body li { margin-bottom: 6px; }
.faq-art-body h2, .faq-art-body h3, .faq-art-body h4 { color: var(--ink); margin: 22px 0 10px; font-size: 1.05rem; }
.faq-art-body a { color: var(--accent); text-decoration: underline; }
.faq-art-body img { max-width: 100%; height: auto; border-radius: 10px; }
.faq-next:hover { border-color: var(--accent); }
.faq-next svg { width: 17px; height: 17px; color: var(--ink-3); }
.faq-arts { display: flex; flex-direction: column; padding: 4px; }
.faq-a { display: flex; align-items: center; gap: 12px; padding: 13px 16px; border-radius: 11px; color: var(--ink-2); }
.faq-a:hover { background: var(--chip); color: var(--ink); }
.faq-a span { flex: 1; font-size: .92rem; }
.faq-a svg { width: 17px; height: 17px; color: var(--ink-3); flex-shrink: 0; }

/* ══════════════════════════════════════════════════════════════════
   TICKETS — la conversación
   Lo del panel antiguo era el chat de la plantilla, con simplebar y
   avatares; aquí es una lista de burbujas y ya. Los mensajes propios
   van a la derecha.
   ══════════════════════════════════════════════════════════════════ */
.tk-card{padding:0;overflow:hidden}
.tk-hd{display:flex;align-items:center;justify-content:space-between;gap:14px;
       flex-wrap:wrap;padding:16px 20px;border-bottom:1px solid var(--line)}
.tk-hd-r{display:flex;align-items:center;gap:10px}

.tk-chat{display:flex;flex-direction:column;gap:12px;padding:20px;
         max-height:58vh;overflow-y:auto;background:var(--bg-2,transparent)}
.tk-msg{display:flex;justify-content:flex-start}
.tk-msg.mine{justify-content:flex-end}

.tk-bub{max-width:min(560px,78%);padding:11px 14px;border-radius:14px;
        background:var(--line);border-top-left-radius:4px}
.tk-msg.mine .tk-bub{background:var(--accent-soft);
        border-top-left-radius:14px;border-top-right-radius:4px}
.tk-bub p{margin:0;white-space:pre-wrap;word-break:break-word}
.tk-meta{margin-top:5px;font-size:.72rem;color:var(--ink-3)}
.tk-msg.mine .tk-meta{text-align:right}

.tk-send{display:flex;align-items:center;gap:10px;flex-wrap:wrap;
         padding:14px 20px;border-top:1px solid var(--line)}
.tk-send .inp[type="text"]{flex:1 1 260px}
.tk-send .inp[type="file"]{flex:0 1 240px;padding:7px 10px}
.tk-send.closed{justify-content:center;font-size:.86rem}

/* Fila de ticket con un mensaje del vendedor sin contestar. */
.tbl tr.row-nuevo > td{background:rgba(62,155,255,.06)}

@media (max-width:640px){
  .tk-bub{max-width:88%}
  .tk-chat{max-height:none}
}

/* Mesa de pagos: el color de la fila avisa de a quien se paga.
   Rojo = cuenta desactivada; ambar = sin KYC. */
.tbl tr.row-peligro > td{background:rgba(224,87,83,.10)}
.tbl tr.row-aviso   > td{background:rgba(222,120,30,.08)}

/* TOPBAR — que el título no eche abajo a los botones.
   `.top` es flex con wrap, y el bloque del título entra con su ancho natural:
   si el subtítulo es largo (Solicitud de producto, por ejemplo) la suma pasa
   del ancho disponible y el grupo de la derecha se cae a una segunda línea,
   flotando dentro del contenido. Con base 0 el título nunca fuerza el salto:
   ocupa lo que sobra y el subtítulo se parte solo. En móvil sigue saltando,
   que es lo que se quiere: ahí no caben los dos. */
@media (min-width: 1001px) {
    .top > div:not(.top-r) { flex: 1 1 0; min-width: 0; }
}

/* MENÚ DE PERFIL — cerrar sesión, aparte y en rojo.
   Estaba mezclado con «Mi perfil» y «Mi wallet», que es justo donde no
   debería: es la única entrada que te saca del panel. */
.pm-out { padding: 6px 8px 8px; border-top: 1px solid var(--line); }
.pm-i-out { width: 100%; background: none; border: none; font-family: inherit; text-align: left; color: var(--neg); }
.pm-i-out svg { color: var(--neg); }
.pm-i-out:hover { background: rgba(224,87,83,.10); }
.pm-i-out:hover svg { color: var(--neg); }

/* El saldo del menú iba a 1,28rem (20,5px) y el diseño lo pide a 1,04rem:
   compite con el nombre de la cuenta que hay justo encima. */
.pm-bal-l > b { font-size: 1.04rem; }

/* PEDIDOS — la dirección, a dos líneas.
   Sin tope, una dirección larga se lleva seis líneas de fila y la tabla deja
   de leerse de un vistazo. El texto entero sigue en el `title`. */
.ord-dir {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* Botón de filtrar: al ancho de su texto.
   `.btn` nace con width:100%; dentro de una barra de filtros con pocos
   campos (Mis facturas) eso lo estiraba de lado a lado. */
.sb-go { width: auto; }

/* En noche el azul del diseño se apaga demasiado sobre el panel oscuro. */
:root[data-theme="dark"] .ep-name { color: #7FA6DE; }

/* La cabecera agrupada («Estado del pedido» / «Rentabilidad») se iba a la
   derecha y desaparecía fuera de la tabla: `.ep-tbl th:not(:first-child)`
   alinea a la derecha las columnas de cifras y le ganaba en especificidad
   a `.ep-grp-row th`. Con el `.ep-tbl` delante empata y manda esta, que va
   después. */
.ep-tbl .ep-grp-row th { text-align: center; }

/* ENTRADA — la prueba social, dentro de la línea del pie.
   Inline a propósito: como bloque suelto, `.authx` (display:flex) la sacaba de
   la línea y la estiraba a toda la altura de la pantalla. Va sobre fondo
   oscuro, así que no puede tirar de --ink: ahí el token es el del panel claro. */
.authx-social {
    display: inline-flex; align-items: center; gap: 7px;
    margin-left: 10px; padding-left: 12px;
    border-left: 1px solid rgba(255,255,255,.16);
    font-family: var(--mono); font-size: .74rem; font-weight: 600;
    letter-spacing: .04em; color: rgba(255,255,255,.5);
}
.authx-social .dot-live {
    width: 7px; height: 7px; margin: 0; border-radius: 50%;
    background: var(--lima); box-shadow: 0 0 0 3px rgba(224,252,9,.18);
}
/* En pantalla estrecha, a su propia línea en vez de forzar el pie. */
@media (max-width: 460px) {
    .authx-foot { line-height: 1.7; }
    .authx-social { margin-left: 0; padding-left: 0; border-left: none; display: flex; justify-content: center; }
}

/* REGISTRO — nombre y apellido en la misma fila y medidor de contraseña. */
.a-duo { display: grid; grid-template-columns: 1fr 1fr; gap: 0 14px; }
@media (max-width: 480px) { .a-duo { grid-template-columns: 1fr; } }

.pw-meter { margin-top: 10px; }
.pw-segs { display: flex; gap: 5px; }
.pw-segs i {
    flex: 1; height: 4px; border-radius: 3px;
    background: rgba(255,255,255,.14); transition: background .18s;
}
/* El color del medidor dice el veredicto sin leer nada: rojo, ámbar, verde. */
.pw-meter.n1 .pw-segs i.on { background: var(--neg); }
.pw-meter.n2 .pw-segs i.on { background: var(--warn); }
.pw-meter.n3 .pw-segs i.on { background: var(--warn-soft); }
.pw-meter.n4 .pw-segs i.on { background: var(--pos-viv); }

.pw-reqs {
    list-style: none; display: flex; flex-wrap: wrap; gap: 4px 14px;
    margin: 9px 0 0; padding: 0;
    font-size: .74rem; color: rgba(255,255,255,.45);
}
.pw-reqs li::before { content: '○'; margin-right: 5px; }
.pw-reqs li.ok { color: var(--pos-viv); }
.pw-reqs li.ok::before { content: '●'; }

/* BARRA SUPERIOR EN MÓVIL — sitio para el título.
   El prototipo ya esconde la etiqueta del wallet y el nombre del perfil a
   700px, pero a 390px el importe sigue ocupando ~90px y al título le quedan
   41: «Inicio» se leía «Inici». Por debajo de 480 el monedero se queda en su
   icono (sigue siendo el enlace al wallet) y el título recupera su sitio. */
@media (max-width: 480px) {
    .top .wallet .wv { display: none; }
    .top .wallet { padding: 0; }
}


/* ESTADÍSTICAS · Productos — franja de totales y buscador de la tabla.
   La franja va oscura a propósito: separa los filtros de la tabla y da el
   resumen del rango de un vistazo, antes de entrar a leer fila por fila. */
.ep-strip {
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
    margin-top: 14px; padding: 0; overflow: hidden;
    background: var(--line);
    border-radius: var(--r-card);
}
@media (max-width: 760px) { .ep-strip { grid-template-columns: 1fr 1fr; } }
.eps-i {
    display: flex; flex-direction: column; gap: 6px;
    padding: 16px 20px; background: var(--negro);
}
:root[data-theme="dark"] .eps-i { background: #07070B; }
.eps-k {
    font-family: var(--mono); font-size: .6rem; font-weight: 600;
    letter-spacing: .12em; text-transform: uppercase; color: rgba(255,255,255,.45);
}
.eps-v { font-size: 1.28rem; font-weight: 800; letter-spacing: -.02em; color: #fff; }
.eps-v.eps-lima { color: var(--lima); }
.eps-v.eps-neg { color: var(--warn-soft); }

.ep-srch { max-width: 260px; margin-left: auto; }

/* CATÁLOGO PRIVADO — el nombre del producto, al mismo azul que en Estadísticas.
   Era el violeta de acento, que ahí compite con los botones: el mismo elemento
   salía de dos colores según la pantalla. */
.pv-name { color: #3D619E; }
:root[data-theme="dark"] .pv-name { color: #7FA6DE; }


/* ETIQUETAS — un nombre largo no puede empujar la tabla fuera de la pantalla.
   El badge es inline-block con white-space:nowrap; con 120 caracteres se salía
   del viewport. Se corta con puntos suspensivos y el nombre entero queda en el
   title de la celda. */
.tags-tbl td .bdg {
    /* En px, no en %: una celda de tabla ignora max-width salvo con
       table-layout:fixed, asi que el 100% no recortaba nada y una etiqueta de
       120 caracteres empujaba la tabla fuera de la pantalla. */
    max-width: 360px;
    overflow: hidden;
    text-overflow: ellipsis;
    vertical-align: bottom;
}


/* ── VERIFICACIÓN EN DOS PASOS ────────────────────────────────────────────
   Alta (/2fa/setup, dentro del panel) y segundo factor (/2fa/challenge, en
   el armazón de entrada). El campo del código comparte estilo en las dos. */
.tfa-wrap { padding: 30px }
.tfa-grid { display: grid; grid-template-columns: 300px 1fr; gap: 34px; align-items: start }
@media (max-width: 860px) { .tfa-grid { grid-template-columns: 1fr; gap: 26px } }

.tfa-qr-col { text-align: center }
/* El QR se genera en SVG sin tamaño fijo: se encaja aquí y sobre blanco
   siempre, que en tema oscuro un QR invertido no lo lee ninguna cámara. */
.tfa-qr {
    display: inline-block; padding: 14px; border-radius: 14px;
    background: #fff; border: 1px solid var(--line);
}
.tfa-qr svg { display: block; width: 220px; height: 220px }

.tfa-hint { margin: 16px 0 8px; font-size: .8rem; color: var(--ink-3); line-height: 1.5 }
.tfa-secret { display: flex; gap: 8px; align-items: center }
.tfa-secret .inp {
    text-align: center; letter-spacing: .12em; font-size: .8rem;
    font-variant-numeric: tabular-nums;
}

.tfa-steps { list-style: none; margin: 0 0 22px; padding: 0; display: grid; gap: 12px }
.tfa-steps li {
    display: flex; gap: 11px; align-items: flex-start;
    font-size: .88rem; color: var(--ink-2); line-height: 1.5;
}
.tfa-step-n {
    flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
    background: var(--accent-soft); color: var(--accent);
    font-size: .74rem; font-weight: 800; line-height: 22px; text-align: center;
}

/* Seis cifras bien separadas: es lo único que se teclea en toda la pantalla. */
.tfa-code {
    text-align: center; font-size: 1.5rem; font-weight: 700;
    letter-spacing: .42em; text-indent: .42em;
    font-variant-numeric: tabular-nums;
}

.tfa-actions { display: flex; gap: 10px; justify-content: flex-end; margin-top: 22px; flex-wrap: wrap }
@media (max-width: 520px) { .tfa-actions { justify-content: stretch } .tfa-actions > * { flex: 1 } }

.tfa-logout { margin-top: 20px; text-align: center }
.lnk-danger {
    background: none; border: 0; padding: 0; cursor: pointer;
    font-family: var(--font); font-size: .82rem; font-weight: 600;
    color: var(--neg); text-decoration: underline; text-underline-offset: 3px;
}
.lnk-danger:hover { opacity: .8 }

/* Icono en la cabecera de tarjeta (.et-hl es flex): el SVG del icono no trae
   width/height y como hijo de un elemento flexible se estiraba hasta llenar la
   caja — 221x221 medidos en la ficha de producto. */
.et-hl b svg { width: 16px; height: 16px; vertical-align: -2px; flex-shrink: 0 }

/* CREAR PEDIDO — que la columna del pedido pueda encoger.
   El ancho minimo de esta columna era lo que aplastaba a las otras dos: la
   tabla se mide por su contenido y un nombre de producto largo no parte. */
/* El min-width:720px genérico de .tbl es lo que sacaba la columna de cantidad
   fuera de la tarjeta: la tabla medía 720px dentro de una columna de ~400px. */
.co-col .cp-tbl { table-layout: fixed; width: 100%; min-width: 0 }
/* El botón de quitar producto, del tamaño de la celda (46px menos el padding). */
.co-col .cp-tbl .mini-btn.del { width: 34px; height: 34px; padding: 0 }
.co-col .cp-tbl .mini-btn.del svg { width: 15px; height: 15px }

/* CALCULADORA — filas del buscador de producto (select2 con miniatura).
   El tamaño vivía solo en profitability-calculator.css, que el rediseño no
   carga: la miniatura salía a tamaño natural (el placeholder es 1080x1080) y
   reventaba el desplegable. */
.pc-search-item { display: flex; align-items: center; gap: 12px; padding: 4px 0; min-width: 0 }
.pc-search-thumb { width: 40px; height: 40px; border-radius: 8px; object-fit: cover; background: var(--chip); flex-shrink: 0 }
.pc-search-info { min-width: 0; flex: 1 }
.pc-search-name { font-weight: 600; font-size: .88rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.pc-search-meta { font-size: .76rem; color: var(--ink-3); margin-top: 2px }

/* CREAR PEDIDO — aire entre bloques de la columna de datos del cliente.
   Los .field sueltos y los .field-grid se apilaban a 0px, así que el input de
   un campo quedaba pegado a la etiqueta del siguiente: se leía peor que la
   propia separación etiqueta-campo (7px). */
.co-col > .field + .field,
.co-col > .field + .field-grid,
.co-col > .field-grid + .field,
.co-col > .field-grid + .field-grid,
.co-col > .field + .albar,
.co-col > .field-grid + .albar,
.co-col > .albar + .field,
.co-col > .albar + .field-grid,
.co-col > div[id] + .field,
.co-col > div[id] + .field-grid { margin-top: 18px }
.co-col .cp-name, .co-col .cp-stk { display: block; word-break: break-word; overflow-wrap: anywhere }
.co-col .inp, .co-col select, .co-col .select2-container { max-width: 100% }
/* select2 calcula su ancho al arrancar y en la columna estrecha se pasaba
   de largo (580px medidos en una columna de 381). */
.co-col .select2-container { width: 100% !important }
.co-sr > span { min-width: 0; overflow-wrap: anywhere }

/* La barra de acciones se pega al fondo de la VENTANA; dentro de un modal eso
   la saca de la tarjeta. Ahi va como pie normal. */
.oe-bar.en-modal { position: static; margin: 18px 0 0; padding: 14px 0 0; border-radius: 0;
    border: 0; border-top: 1px solid var(--line); background: transparent; box-shadow: none }

/* C1 — el subtítulo de la pantalla, ya fuera de la barra superior. */
.pagesub { color: var(--ink-2); font-size: .9rem; line-height: 1.5; margin: 0 0 18px; max-width: 78ch }
@media (max-width: 700px) { .pagesub { margin-bottom: 14px } }


/* B1 — sin monoespaciada, lo que alinea las cifras de las tablas es esto.
   Va en :root para que lo herede todo; solo afecta a los digitos. */
:root { font-variant-numeric: tabular-nums }


/* ══ B2 · ESTADOS DE PEDIDO ═══════════════════════════════════════════════
   Un color por estado, el mismo en todas las vistas donde aparece (Mis
   pedidos, Resumen, widget de estados, historial del pedido, Seguimiento).

   Construccion: fondo al 14-16%, texto en el color pleno y borde de 1px del
   mismo color. El borde va en `.bdg` en transparente para que la caja mida
   igual con o sin el y el cambio de tema no mueva la tabla.

   En oscuro el color pleno no se lee sobre el fondo negro, asi que el texto
   usa la version aclarada y el borde sube de opacidad. */
:root {
    --cyan:      #0E9DB0;
    --indigo:    #5B5FE8;
    --alert:     #F2541B;
    --pos-viv:   #34C759;
    --neg-2:     #C13934;
    --warn-soft: #FCA254;
}

.bdg { border: 1px solid transparent }

.bdg-pos       { background: rgba(15,160,95,.14);  color: var(--pos);       border-color: rgba(15,160,95,.32) }
.bdg-pos-viv   { background: rgba(52,199,89,.15);  color: #1F9E45;          border-color: rgba(52,199,89,.34) }
.bdg-neg       { background: rgba(224,87,83,.14);  color: var(--neg);       border-color: rgba(224,87,83,.32) }
.bdg-neg-2     { background: rgba(193,57,52,.14);  color: var(--neg-2);     border-color: rgba(193,57,52,.32) }
.bdg-warn      { background: rgba(222,120,30,.15); color: var(--warn);      border-color: rgba(222,120,30,.32) }
.bdg-warn-soft { background: rgba(252,162,84,.20); color: #B96A15;          border-color: rgba(252,162,84,.42) }
.bdg-info      { background: rgba(62,155,255,.14); color: var(--info);      border-color: rgba(62,155,255,.32) }
.bdg-violet    { background: rgba(126,35,249,.14); color: var(--violet);    border-color: rgba(126,35,249,.32) }
.bdg-cyan      { background: rgba(14,157,176,.14); color: var(--cyan);      border-color: rgba(14,157,176,.32) }
.bdg-indigo    { background: rgba(91,95,232,.14);  color: var(--indigo);    border-color: rgba(91,95,232,.32) }
.bdg-mut2      { background: var(--line);          color: var(--ink-2);     border-color: transparent }

/* NOVEDAD pide actuar hoy: se lee antes que el resto de la fila. */
.bdg-alert {
    background: rgba(242,84,27,.15); color: var(--alert);
    border-color: rgba(242,84,27,.45); font-weight: 800;
}

:root[data-theme="dark"] .bdg-pos       { background: rgba(15,160,95,.20);  color: #4ADE80; border-color: rgba(74,222,128,.45) }
:root[data-theme="dark"] .bdg-pos-viv   { background: rgba(52,199,89,.20);  color: #6EE7A8; border-color: rgba(110,231,168,.45) }
:root[data-theme="dark"] .bdg-neg       { background: rgba(224,87,83,.20);  color: #FF7A72; border-color: rgba(255,122,114,.45) }
:root[data-theme="dark"] .bdg-neg-2     { background: rgba(193,57,52,.22);  color: #FF9088; border-color: rgba(255,144,136,.45) }
:root[data-theme="dark"] .bdg-info      { background: rgba(62,155,255,.20); color: #7CB4FF; border-color: rgba(124,180,255,.45) }
:root[data-theme="dark"] .bdg-violet    { background: rgba(126,35,249,.22); color: #B9A5FF; border-color: rgba(185,165,255,.45) }
:root[data-theme="dark"] .bdg-warn      { background: rgba(222,120,30,.20); color: #FBBF24; border-color: rgba(251,191,36,.42) }
:root[data-theme="dark"] .bdg-warn-soft { background: rgba(252,162,84,.20); color: #FCA254; border-color: rgba(252,162,84,.48) }
:root[data-theme="dark"] .bdg-cyan      { background: rgba(14,157,176,.22); color: #4DD4E8; border-color: rgba(77,212,232,.45) }
:root[data-theme="dark"] .bdg-indigo    { background: rgba(91,95,232,.24);  color: #9497FF; border-color: rgba(148,151,255,.48) }
:root[data-theme="dark"] .bdg-alert     { background: rgba(242,84,27,.24);  color: #FF7A47; border-color: rgba(255,122,71,.55) }
:root[data-theme="dark"] .bdg-mut2      { background: rgba(255,255,255,.07); color: var(--ink-2); border-color: rgba(255,255,255,.12) }

/* A8 — contexto del modal de novedad: el motivo en banda violeta y los ocho
   datos que hacen falta para decidir sin abrir el pedido en otra pestaña. */
.nov-ctx { padding: 0 24px; margin-top: 18px }
.nov-ctx-motivo {
    background: var(--accent-soft); border-left: 3px solid var(--accent);
    border-radius: 10px; padding: 12px 15px;
}
.nov-ctx-lab {
    display: block; font-size: .62rem; font-weight: 700;
    letter-spacing: .11em; text-transform: uppercase; color: var(--accent); margin-bottom: 4px;
}
.nov-ctx-motivo b { font-size: .96rem; font-weight: 700 }
.nov-ctx-motivo span#novCtxDetalle { display: block; margin-top: 4px; font-size: .82rem; color: var(--ink-2); line-height: 1.45 }

.nov-ctx-grid {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px 18px; margin-top: 14px;
    padding: 14px 0 2px; border-top: 1px solid var(--line);
}
@media (max-width: 780px) { .nov-ctx-grid { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
.nov-ctx-grid > div { min-width: 0 }
.nov-ctx-grid span {
    display: block; font-size: .6rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-3); margin-bottom: 2px;
}
.nov-ctx-grid b { font-size: .85rem; font-weight: 600; overflow-wrap: anywhere }
.modal-hd h3 .bdg { font-size: .62rem }


/* ══ ESTADISTICAS · RESUMEN ══════════════════════════════════════════════
   La pantalla de medidores, distinta del Dashboard. */

.gauge-row { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 18px }
@media (max-width: 1080px) { .gauge-row { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
@media (max-width: 560px)  { .gauge-row { grid-template-columns: 1fr } }

.gauge-card { padding: 20px; text-align: center }
.gauge-hd { display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 14px }
.gauge-dot { width: 9px; height: 9px; border-radius: 50%; flex-shrink: 0 }
.gauge-t {
    font-size: .64rem; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: var(--ink-3);
}

.gauge-ring { position: relative; width: 132px; margin: 0 auto }
.gauge-ring svg { width: 132px; height: 132px; transform: rotate(-90deg); display: block }
.gr-bg { fill: none; stroke: var(--line); stroke-width: 10 }
/* El anillo llega con dashoffset completo y el JS le da el suyo: la
   transicion es lo que lo dibuja. */
.gr-fg { fill: none; stroke-width: 10; stroke-linecap: round; transition: stroke-dashoffset 1.3s cubic-bezier(.19,1,.22,1) }
.gauge-num {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: 1.62rem; font-weight: 800; letter-spacing: -.03em; color: var(--ink);
    font-variant-numeric: tabular-nums;
}
.gauge-num span { font-size: .92rem; font-weight: 700; margin-left: 1px; color: var(--ink-3) }
.gauge-sub { margin-top: 12px; font-size: .78rem; color: var(--ink-2) }
.gauge-sub b { font-weight: 700; color: var(--ink) }

/* La banda de comparativa contra el periodo anterior. */
.navyband {
    display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 4px;
    background: linear-gradient(115deg, #171A3A 0%, #1D2043 58%, #232755 100%);
    border-radius: 18px; padding: 22px 26px; margin-bottom: 18px; color: #fff;
    box-shadow: 0 18px 44px -22px rgba(24, 8, 80, .55);
}
@media (max-width: 900px) { .navyband { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px 4px } }
@media (max-width: 480px) { .navyband { grid-template-columns: 1fr } }
.nb-i { padding: 0 14px; border-left: 1px solid rgba(255,255,255,.12); min-width: 0 }
.nb-i:first-child { border-left: 0; padding-left: 0 }
@media (max-width: 900px) { .nb-i:nth-child(3) { border-left: 0 } }
.nb-l {
    display: block; font-size: .6rem; font-weight: 700; letter-spacing: .12em;
    text-transform: uppercase; color: rgba(255,255,255,.52);
}
.nb-v { display: block; font-size: 1.55rem; font-weight: 800; letter-spacing: -.03em; margin: 5px 0 3px }
.nb-i.lima .nb-v { color: var(--lima) }
.nb-d { font-size: .74rem; font-weight: 600 }
.nb-d.up   { color: #6EE7A8 }
.nb-d.down { color: #FF9088 }
.nb-d.none { color: rgba(255,255,255,.46) }

/* Reparto por estado. */
.est-2col { display: grid; grid-template-columns: 1.35fr 1fr; gap: 18px; align-items: start }
@media (max-width: 1000px) { .est-2col { grid-template-columns: 1fr } }
.est-side { display: grid; gap: 18px }

.stlist { display: grid; gap: 9px }
.stl-row { display: grid; grid-template-columns: 170px 1fr 58px 54px; gap: 12px; align-items: center }
@media (max-width: 620px) { .stl-row { grid-template-columns: 1fr 52px 48px } .stl-bar { display: none } }
.stl-name { min-width: 0 }
.stl-bar { height: 7px; border-radius: 7px; background: var(--line); overflow: hidden }
.stl-bar span { display: block; height: 100%; border-radius: 7px; background: var(--accent); transition: width .9s cubic-bezier(.19,1,.22,1) }
.stl-n   { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums }
.stl-pct { text-align: right; font-size: .8rem; color: var(--ink-3); font-variant-numeric: tabular-nums }

/* Mini-KPI del dia. */
.minikpis { display: grid; grid-template-columns: 1fr 1fr; gap: 14px 18px }
.minikpis > div { min-width: 0 }
.minikpis span {
    display: block; font-size: .6rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--ink-3); margin-bottom: 3px;
}
.minikpis b { font-size: 1.14rem; font-weight: 800; letter-spacing: -.02em }
.minikpis b.neg { color: var(--neg) }

/* Barras de los dos ultimos meses. */
.mesbars { display: flex; gap: 22px; align-items: flex-end; justify-content: center; padding: 8px 0 0 }
.mb-col { text-align: center; flex: 0 0 74px }
.mb-stack { position: relative; height: 108px; display: flex; align-items: flex-end; justify-content: center }
.mb-tot, .mb-conf { position: absolute; bottom: 0; border-radius: 7px 7px 0 0; transition: height .9s cubic-bezier(.19,1,.22,1) }
.mb-tot  { width: 42px; background: var(--line) }
.mb-conf { width: 42px; background: var(--accent) }
.mb-lab { margin-top: 8px; font-size: .64rem; font-weight: 700; letter-spacing: .1em; color: var(--ink-3) }
.mb-n   { font-size: .78rem; color: var(--ink-2); margin-top: 2px; font-variant-numeric: tabular-nums }
.mb-growth {
    display: flex; align-items: center; justify-content: space-between;
    margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--line); font-size: .82rem;
}
.mb-growth b.pos { color: var(--pos) }
.mb-growth b.neg { color: var(--neg) }

.dr-upd { margin-left: auto; font-size: .74rem; color: var(--ink-3); display: flex; align-items: center; gap: 7px }
.dr-upd .refresh { display: inline-flex; color: var(--accent) }
.dr-upd .refresh svg { width: 15px; height: 15px }

/* A7 — motivos de rechazo y de devolución: nombre, barra, conteo y peso. */
.motivos { display: grid; gap: 10px }
.mot-row { display: grid; grid-template-columns: 1fr 96px 42px 52px; gap: 12px; align-items: center }
@media (max-width: 620px) { .mot-row { grid-template-columns: 1fr 40px 50px } .mot-bar { display: none } }
.mot-n { font-size: .84rem; color: var(--ink-2); min-width: 0; overflow-wrap: anywhere }
.mot-bar { height: 7px; border-radius: 7px; background: var(--line); overflow: hidden }
.mot-bar i { display: block; height: 100%; border-radius: 7px; background: var(--neg); transition: width .9s cubic-bezier(.19,1,.22,1) }
.motivos.dev .mot-bar i { background: var(--neg-2) }
.mot-c { text-align: right; font-weight: 700; font-variant-numeric: tabular-nums }
.mot-p { text-align: right; font-size: .8rem; color: var(--ink-3); font-variant-numeric: tabular-nums }

/* PARTE E — el widget de primeros pasos ya lleva a los vídeos.
   La fila entera abre el vídeo; el círculo es su propio botón (marcar es una
   decisión, no algo que pase de rebote por abrir el vídeo). */
.sp-step.has-video { cursor: pointer }
/* Reset del boton, PERO sin tocar el borde: es lo unico que dibuja el circulo
   de un paso sin marcar (fondo = el del popover, contenido vacio). Con
   `border:0` aqui —mas especifico que la regla de abajo— el circulo era
   literalmente invisible hasta pulsarlo. */
.sp-step .sp-dot { padding: 0; cursor: pointer; font: inherit }
.sp-play {
    flex: 0 0 auto; width: 26px; height: 26px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--chip); color: var(--ink-3);
    transition: background var(--t-fast), color var(--t-fast), transform var(--t-fast);
}
.sp-play svg { width: 11px; height: 11px; margin-left: 1px }
.sp-step.has-video:hover .sp-play { background: var(--accent); color: #fff; transform: scale(1.08) }

/* «Lanza campañas» tiene dos vídeos: dos chips en vez de un play. */
.sp-parts { display: flex; gap: 5px; flex: 0 0 auto }
.sp-part {
    border: 1px solid var(--line); background: var(--chip); color: var(--ink-2);
    border-radius: 7px; padding: 3px 8px; cursor: pointer;
    font-family: var(--font); font-size: .65rem; font-weight: 700; letter-spacing: .04em;
    transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.sp-part:hover { background: var(--accent); border-color: var(--accent); color: #fff }

/* D13 — el «!» de la pestaña Seguridad no tenía una sola regla: salía como
   texto gris plano. Es un aviso, así que se ve como un aviso. */
.ptab-badge {
    display: inline-flex; align-items: center; justify-content: center;
    width: 16px; height: 16px; margin-left: 6px; border-radius: 50%;
    background: var(--warn); color: #fff;
    font-size: .62rem; font-weight: 800; line-height: 1; vertical-align: 1px;
}

/* D13 — el aviso de la pestaña Fiscal salía pegado al párrafo de arriba. */
.ppane[data-pane="fiscal"] .albar { margin-top: 14px }

/* D13 — el banner de Shopify: la bolsa a un tamaño de marca y la frase
   corrida, sin los logotipos sueltos que había encima. */
.shopcard-tx b { display: block; font-size: 1rem; margin-bottom: 3px }
.shopcard-tx p { font-size: .86rem; color: var(--ink-2); line-height: 1.5 }
.shopcard-tx p b, .shopcard-tx p strong { font-weight: 800; color: var(--ink) }

/* D13 — el selector de idioma del menú de perfil: tres píldoras anchas
   iguales. `span{flex:1}` no hacía nada porque el span va dentro de un <a>
   que no es flexible, así que cada chip se encogía a su contenido (29x29). */
.pm-lang { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px }
.pm-lang a { display: block }
.pm-lang span { display: block; width: 100%; padding: 8px 0; font-size: .74rem }

/* D13 — el avatar salía negro y vacío: con foto se pinta un <img> y si ese
   fichero no existe queda una imagen rota. Si no carga, la inicial. */
.avatar .av-img { width: 100%; height: 100%; object-fit: cover }

/* D8 — API Webhooks: el verbo junto al campo y los eventos que enviamos. */
.wh-verb {
    display: flex; align-items: center; flex: 0 0 auto;
    padding: 0 12px; border-radius: 10px;
    background: var(--accent-soft); color: var(--accent);
    font-size: .68rem; font-weight: 800; letter-spacing: .08em;
}
.wh-events { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 18px 0 4px }
.wh-events-l {
    font-size: .6rem; font-weight: 700; letter-spacing: .11em;
    text-transform: uppercase; color: var(--ink-3); margin-right: 2px;
}
.wh-ev {
    background: var(--chip); border: 1px solid var(--line); border-radius: 8px;
    padding: 4px 10px; font-size: .72rem; font-weight: 600; color: var(--ink-2);
}

/* D11 — Mis usuarios. */
.attr-card { display: flex; align-items: center; gap: 20px; padding: 20px 24px; margin-bottom: 18px }
.attr-tx { flex: 1; min-width: 0 }
.attr-tx b { display: flex; align-items: center; gap: 10px; font-size: 1rem; margin-bottom: 4px; flex-wrap: wrap }
.attr-tx p { font-size: .85rem; color: var(--ink-2); line-height: 1.5 }

.ucell { display: flex; align-items: center; gap: 10px; min-width: 0 }
.uav {
    flex: 0 0 auto; width: 32px; height: 32px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--accent-soft); color: var(--accent);
    font-size: .72rem; font-weight: 800; letter-spacing: .02em;
}
.tg.tg-sm { display: inline-flex; align-items: center; gap: 9px }
.tg .tg-lbl { font-size: .82rem; font-weight: 600; color: var(--ink-2) }

/* D19 — la celda de fecha: el dia manda, la hora acompaña. */
.celda-fecha { display: block; white-space: nowrap; line-height: 1.35 }
.celda-fecha b { display: block; font-size: .84rem; font-weight: 600; font-variant-numeric: tabular-nums }
.celda-fecha span { display: block; font-size: .76rem; color: var(--ink-3); font-variant-numeric: tabular-nums }

/* D16 — la clave y su botón de copiar en la misma celda: dos iconos iguales en
   dos columnas no dejaban saber cuál era cuál. */
.keycell { display: flex; align-items: center; gap: 8px }
.keycell .mono { font-size: .78rem; color: var(--ink-2); letter-spacing: .01em; white-space: nowrap }

/* Chatby con su rosa, que es como se distingue del resto de plataformas. */
.bdg-chatby {
    background: rgba(255,99,216,.14); color: #C2379F;
    border-color: rgba(255,99,216,.36);
}
:root[data-theme="dark"] .bdg-chatby { background: rgba(255,99,216,.20); color: #FF9BE4; border-color: rgba(255,155,228,.45) }

/* D14 — desglose bajo el saldo: lo que se puede sacar hoy y lo retenido. */
.wal-split { display: flex; gap: 26px; margin: 10px 0 2px; flex-wrap: wrap }
.wal-split span { display: flex; flex-direction: column; gap: 1px }
.wal-split i {
    font-style: normal; font-size: .58rem; font-weight: 700;
    letter-spacing: .12em; text-transform: uppercase; opacity: .6;
}
.wal-split b { font-size: 1.02rem; font-weight: 800; letter-spacing: -.02em }
.wal-split .ret b { opacity: .72 }

/* D4 — cuenta atrás del evento: cuatro chips, no una cadena de texto. */
.tkt-count { display: flex; gap: 7px; margin: 8px 0 12px; flex-wrap: wrap }
.tc-u {
    display: flex; flex-direction: column; align-items: center; gap: 1px;
    min-width: 42px; padding: 7px 8px; border-radius: 10px;
    background: rgba(255,255,255,.10); border: 1px solid rgba(255,255,255,.14);
}
.tc-u b {
    font-size: 1.12rem; font-weight: 800; letter-spacing: -.02em; line-height: 1;
    font-variant-numeric: tabular-nums; color: var(--lima);
}
.tc-u i {
    font-style: normal; font-size: .52rem; font-weight: 700;
    letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.6);
}
.tc-ya { font-size: 1.1rem; font-weight: 800; color: var(--lima) }
.tkt-chip.lima { background: var(--lima); color: var(--negro); border-color: var(--lima); font-weight: 800 }
@media (max-width: 460px) { .tkt-count { gap: 5px } .tc-u { min-width: 38px; padding: 6px } }

/* D9 — la rejilla de medidores se adapta al numero real: con menos de cuatro
   dejaba un hueco. */
.pbi-gauges { grid-template-columns: repeat(auto-fit, minmax(210px, 1fr)) }
.pbig-hd { text-transform: uppercase; letter-spacing: .1em; font-size: .64rem; font-weight: 700 }
.pbig-s b { font-weight: 700; color: var(--ink) }


/* ── Estadisticas del admin: adquisicion, embudo por dia y contabilidad ──────
   Cinco piezas cortas que no existian en el vocabulario del rediseno. */

/* Segundo numero de un medidor (el «vs organico», el «(12%)»): mismo dato,
   menos peso, para que no compita con la cifra principal. */
.dk-pct { font-size: .95rem; font-weight: 600; color: var(--ink-3); letter-spacing: 0; margin-left: 4px }

/* Coletilla al final de una barra de filtros: la salvedad que hay que leer
   antes de interpretar el numero (el rango excluido, la fecha del cache). */
.filters-note { flex: 1 1 240px; font-size: .74rem; color: var(--ink-3); line-height: 1.45; align-self: center }
.filters-note b { color: var(--ink-2) }

/* Fila de totales: va en <tfoot> y se queda pegada abajo, que es de lo que
   sirve un total en una tabla que se desplaza. */
.tbl tfoot .tbl-total td {
    position: sticky; bottom: 0; z-index: 3;
    background: var(--panel-2, var(--panel)); border-top: 2px solid var(--line);
    font-variant-numeric: tabular-nums;
}

/* Fin de semana en el embudo por dia: se distingue del resto sin gritar. */
.tbl tbody tr.wf-finde td { background: color-mix(in srgb, var(--amber, #F0B84B) 7%, transparent) }

/* Lista de conclusiones bajo un grafico. */
.lst-lect { display: grid; gap: 7px; margin: 0; padding-left: 18px }
.lst-lect li { font-size: .85rem; color: var(--ink-2); line-height: 1.5 }
.lst-lect li b { color: var(--ink) }

/* ── Ranking por persona (General del admin) ─────────────────────────────────
   Cuatro listas cortas «quien hizo cuanto». El puesto va delante en un cuadro
   fijo para que los nombres queden alineados aunque el numero cambie de
   ancho, y la cifra a la derecha en tabular para poder compararlas de un
   vistazo sin leerlas una a una. */
.rk-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; max-height: 296px; overflow-y: auto }
.rk-list li { display: flex; align-items: center; gap: 12px; padding: 8px 10px; border-radius: 10px }
.rk-list li:nth-child(odd) { background: var(--bg) }
.rk-pos {
    flex: 0 0 24px; height: 24px; display: grid; place-items: center;
    border-radius: 7px; background: var(--accent-soft); color: var(--accent);
    font-family: var(--mono); font-size: .7rem; font-weight: 800;
}
.rk-list li:nth-child(1) .rk-pos { background: var(--accent); color: #fff }
.rk-name { flex: 1; min-width: 0; font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.rk-num { font-family: var(--mono); font-size: .85rem; font-variant-numeric: tabular-nums }
.rk-vacio { justify-content: center; color: var(--ink-3); font-size: .82rem; padding: 22px 0 }

/* Reparto por transportadora: pares nombre/numero que caben en una linea. */
.rk-carriers { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 8px }
.rk-carrier {
    display: flex; align-items: center; justify-content: space-between; gap: 10px;
    padding: 9px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--bg);
    font-size: .82rem;
}
.rk-carrier b { font-family: var(--mono); font-variant-numeric: tabular-nums }
.rk-carriers-tot { display: flex; gap: 18px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line) }
.rk-carriers-tot span { font-size: .78rem; color: var(--ink-3) }
.rk-carriers-tot b { font-family: var(--mono); color: var(--ink); margin-left: 5px }

/* Desplegable de productos dentro de una celda. En v2 no hay Bootstrap, asi
   que el acordeon es <details>: hace lo mismo y no necesita libreria. */
.det-prod > summary {
    cursor: pointer; list-style: none; font-size: .8rem; color: var(--accent);
    font-weight: 600; white-space: nowrap;
}
.det-prod > summary::-webkit-details-marker { display: none }
.det-prod > summary::after { content: " \25BE"; font-size: .7em }
.det-prod[open] > summary::after { content: " \25B4" }
.det-prod ul {
    list-style: none; margin: 8px 0 0; padding: 8px 10px; display: grid; gap: 5px;
    background: var(--bg); border: 1px solid var(--line); border-radius: 10px;
    min-width: 240px; max-height: 220px; overflow-y: auto;
}
.det-prod li { display: flex; gap: 12px; justify-content: space-between; font-size: .78rem }
.det-prod li b { font-family: var(--mono); flex-shrink: 0 }

/* ── Editor de producto (admin) ──────────────────────────────────────────────
   Dos columnas: a la izquierda lo que se escribe, a la derecha lo que se
   elige de una lista. Por debajo de 1100 px se apilan, y la de elegir va
   primera porque es la corta. */
.pform { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 16px; align-items: start }
.pform-side { display: block }
@media (max-width: 1100px) {
    .pform { grid-template-columns: minmax(0, 1fr) }
    .pform-side { order: -1 }
}

/* El pie va pegado abajo: en un formulario de cinco bloques, el boton de
   guardar cae fuera de pantalla y no se encuentra. */
.pform-foot {
    position: sticky; bottom: 0; z-index: 5;
    display: flex; justify-content: flex-end; align-items: center; gap: 12px;
    margin-top: 16px; padding: 14px 18px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
    box-shadow: 0 -8px 24px -18px rgba(0, 0, 0, .35);
}
.pfs-hd { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap }

.field-grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 14px }
.field-grid4 { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 14px }

/* ── Ordenar catalogo ────────────────────────────────────────────────────────
   Lista arrastrable. La fila entera es el asa, asi que el cursor lo dice. */
.ord-card { padding: 10px; margin-top: 16px }
.ord-list { max-height: 68vh; overflow-y: auto; display: grid; gap: 6px; padding: 4px }
.ord-item {
    display: flex; align-items: center; gap: 12px; padding: 8px 12px;
    border: 1px solid var(--line); border-radius: 12px; background: var(--panel);
    cursor: grab; user-select: none;
    transition: border-color var(--t-fast), background var(--t-fast), transform var(--t-fast);
}
.ord-item:hover { border-color: var(--accent) }
.ord-item:active { cursor: grabbing }
.ord-item.sel { border-color: var(--accent); background: var(--accent-soft) }
.ord-item img { width: 34px; height: 34px; border-radius: 9px; object-fit: cover; flex-shrink: 0 }
.ord-tx { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px }
.ord-tx b { font-size: .85rem; overflow: hidden; text-overflow: ellipsis; white-space: nowrap }
.ord-tx span { font-size: .7rem; color: var(--ink-3) }
.ord-stock {
    flex-shrink: 0; font-family: var(--mono); font-size: .78rem; font-weight: 700; color: var(--pos);
    background: var(--bg); border-radius: 8px; padding: 4px 10px;
}
/* Clase de arrastre de Sortable: el hueco que deja el elemento en movimiento. */
.sortable-ghost { opacity: .35 }

.ord-cat { border: 1px solid var(--line); border-radius: 14px; overflow: hidden; background: var(--bg) }
.ord-cat + .ord-cat { margin-top: 8px }
.ord-cat-h {
    display: flex; align-items: center; gap: 10px; padding: 11px 14px;
    cursor: grab; background: var(--panel); border-bottom: 1px solid var(--line);
}
.ord-cat-h svg { width: 15px; height: 15px; color: var(--ink-3); transition: transform var(--t-fast) }
.ord-cat-h.plegado svg { transform: rotate(-90deg) }
.ord-cat-h b { font-size: .85rem }
.ord-cat-p { display: grid; gap: 6px; padding: 10px }
.ord-cat-p.plegada { display: none }

/* ── Pagina de inicio · tarjetas de plantilla ────────────────────────────────
   La miniatura manda: es lo unico que distingue una plantilla de otra, asi
   que ocupa la mitad de la tarjeta y el texto va debajo, corto. */
.hpc-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 18px; margin-top: 16px }
.hpc {
    display: flex; flex-direction: column; overflow: hidden;
    background: var(--panel); border: 1px solid var(--line); border-radius: 16px;
    transition: border-color var(--t-fast), box-shadow var(--t-fast), transform var(--t-fast);
}
.hpc:hover { transform: translateY(-2px); box-shadow: 0 16px 34px -22px rgba(0, 0, 0, .4) }
.hpc.on { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) }

.hpc-img { position: relative; height: 170px; background: var(--bg); overflow: hidden }
.hpc-img img { width: 100%; height: 100%; object-fit: cover; object-position: top }
.hpc-ph { display: grid; place-items: center; height: 100%; color: var(--ink-3) }
.hpc-ph svg { width: 40px; height: 40px }

.hpc-badge {
    position: absolute; top: 10px; right: 10px; z-index: 2;
    background: var(--accent); color: #fff; border-radius: 8px;
    font-size: .64rem; font-weight: 800; letter-spacing: .04em; padding: 5px 11px;
}
.hpc-edit {
    position: absolute; bottom: 10px; right: 10px; z-index: 2;
    width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center;
    background: var(--accent); color: #fff; box-shadow: 0 4px 12px -4px rgba(0, 0, 0, .5);
    transition: transform var(--t-fast);
}
.hpc-edit:hover { transform: scale(1.06) }
.hpc-edit svg { width: 15px; height: 15px }

.hpc-body { display: flex; flex-direction: column; gap: 7px; padding: 16px 18px 18px; flex: 1 }
.hpc-body h4 { font-size: .92rem; font-weight: 700 }
.hpc-body p { flex: 1; font-size: .78rem; color: var(--ink-3); line-height: 1.5 }
.hpc-btn {
    display: block; width: 100%; text-align: center; margin-top: 4px;
    padding: 10px 16px; border: none; border-radius: 11px; cursor: pointer;
    background: var(--accent); color: #fff;
    font-family: var(--font); font-size: .8rem; font-weight: 700;
    transition: filter var(--t-fast);
}
.hpc-btn:hover { filter: brightness(1.08); color: #fff }
.hpc-btn.off { background: var(--bg); color: var(--ink-3); cursor: default; pointer-events: none }

.hp-prevbar { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; padding: 16px 20px; margin-top: 16px }
.hp-prevbar-t { font-size: .62rem; font-weight: 800; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-3) }
.hp-prev { padding: 22px; margin-top: 12px; overflow-x: auto }

/* ── Puente para el editor de plantillas ─────────────────────────────────────
   El editor trae su propio diseno; de Bootstrap solo usa el ARMAZON del modal
   y de las pestanas. Cargamos su JS (que no pinta) y el poco CSS que hace
   falta va aqui, acotado a .hp-legacy: meter la hoja de Bootstrap en una
   pagina del rediseno reiniciaria todo lo demas. */
.hp-legacy .modal {
    position: fixed; inset: 0; z-index: 1055; display: none;
    overflow-x: hidden; overflow-y: auto; outline: 0;
}
.hp-legacy .modal.show { display: block }
.hp-legacy .modal.fade .modal-dialog { transition: transform .25s ease-out; transform: translateY(-24px) }
.hp-legacy .modal.show .modal-dialog { transform: none }
.hp-legacy .modal-dialog { position: relative; margin: 1.75rem auto; pointer-events: none; max-width: 500px }
.hp-legacy .modal-content { position: relative; display: flex; flex-direction: column; pointer-events: auto; background: #fff; border-radius: 14px }
.hp-legacy .modal-header { display: flex; align-items: center; justify-content: space-between; gap: 12px }
.hp-legacy .modal-title { font-size: 1rem; font-weight: 700; margin: 0 }
.hp-legacy .btn-close {
    width: 30px; height: 30px; border: 0; border-radius: 9px; cursor: pointer;
    background: rgba(0, 0, 0, .05) no-repeat center/12px;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 16 16' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M.3.3a1 1 0 011.4 0L8 6.6 14.3.3a1 1 0 111.4 1.4L9.4 8l6.3 6.3a1 1 0 01-1.4 1.4L8 9.4l-6.3 6.3a1 1 0 01-1.4-1.4L6.6 8 .3 1.7a1 1 0 010-1.4z'/%3E%3C/svg%3E");
}
.hp-legacy .modal-backdrop { position: fixed; inset: 0; z-index: 1050; background: #000 }
.hp-legacy .modal-backdrop.show { opacity: .5 }
/* Bootstrap pone el backdrop al final del <body>, fuera de .hp-legacy. */
body > .modal-backdrop { position: fixed; inset: 0; z-index: 1050; background: #000; opacity: 0; transition: opacity .15s }
body > .modal-backdrop.show { opacity: .5 }
body.modal-open { overflow: hidden }

.hp-legacy .nav-tabs { display: flex; gap: 0; list-style: none; margin: 0; padding: 0 }
.hp-legacy .nav-item { margin: 0 }
.hp-legacy .nav-link { display: block; text-decoration: none; cursor: pointer }
.hp-legacy .tab-content > .tab-pane { display: none }
.hp-legacy .tab-content > .tab-pane.active { display: block }

.hp-legacy .form-label { display: block; font-size: .8rem; font-weight: 600; margin-bottom: 6px; color: #374151 }
.hp-legacy .form-control, .hp-legacy .form-select {
    width: 100%; padding: 9px 12px; border: 1px solid #d1d5db; border-radius: 9px;
    font-family: var(--font); font-size: .85rem; color: #111827; background: #fff;
}
.hp-legacy .form-control:focus, .hp-legacy .form-select:focus { outline: none; border-color: #F97316; box-shadow: 0 0 0 3px rgba(249, 115, 22, .16) }
.hp-legacy .btn {
    display: inline-flex; align-items: center; gap: 7px; cursor: pointer;
    padding: 9px 18px; border: 1px solid transparent; border-radius: 9px;
    font-family: var(--font); font-size: .82rem; font-weight: 600;
}
.hp-legacy .btn-secondary { background: #f3f4f6; color: #374151; border-color: #e5e7eb }
.hp-legacy .btn-primary { background: #F97316; color: #fff }
.hp-legacy .d-none { display: none !important }

/* ── Calendario del rediseno (C8) ─────────────────────────────────────────────
   Portado del prototipo tal cual: 248px de ancho, celdas de 31px, mes y ano
   seleccionables, rango tintado y pie con Borrar / Hoy. Todo por tokens, asi
   que sirve igual en claro y en oscuro. El JS esta en rocket-v2-datepicker.js.

   El calendario nativo del navegador se esconde: el input sigue siendo
   type=date —por el teclado y por como se envia el valor— pero quien pinta el
   calendario es este componente. */
input[type="date"]::-webkit-calendar-picker-indicator { display: none; -webkit-appearance: none }
input[type="date"]::-webkit-inner-spin-button { display: none }
input[type="date"] { cursor: pointer }

.dp-pop{position:absolute;z-index:9500;width:248px;background:var(--panel);border:1px solid var(--line);border-radius:14px;box-shadow:var(--sh-pop);padding:11px;opacity:0;transform:translateY(-5px) scale(.97);transform-origin:top left;transition:opacity .16s cubic-bezier(.19,1,.22,1),transform .16s cubic-bezier(.19,1,.22,1);pointer-events:none}
.dp-pop.open{opacity:1;transform:none;pointer-events:auto}
.dp-hd{display:flex;align-items:center;justify-content:space-between;padding:0 2px 7px}
.dp-title{font-weight:800;font-size:.86rem;letter-spacing:-.01em}
.dp-title-btn{display:inline-flex;align-items:center;gap:5px;background:none;border:none;color:var(--ink);cursor:pointer;font-family:var(--font);padding:4px 8px;margin-left:-8px;border-radius:9px;transition:background .15s}
.dp-title-btn:hover{background:var(--chip)}
.dp-title-btn svg{color:var(--ink-3)}
.dp-mgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;padding:5px 0 2px}
.dp-m{height:30px;border:none;background:var(--chip);border-radius:9px;font-family:var(--font);font-size:.72rem;font-weight:600;color:var(--ink);cursor:pointer;transition:background .12s,color .12s}
.dp-m:hover{background:var(--line)}
.dp-m.cur{box-shadow:inset 0 0 0 1.5px var(--accent)}
.dp-m.sel{background:var(--accent);color:#fff;font-weight:800}
.dp-nav{display:flex;gap:6px}
.dp-nav button{width:25px;height:25px;border-radius:8px;border:1px solid var(--line);background:transparent;color:var(--ink-2);cursor:pointer;display:flex;align-items:center;justify-content:center;transition:background .15s,color .15s}
.dp-nav button:hover{background:var(--chip);color:var(--ink)}
.dp-nav svg{width:12px;height:12px}
.dp-wk{display:grid;grid-template-columns:repeat(7,1fr);margin-bottom:1px}
.dp-wk span{text-align:center;font-family:var(--mono);font-size:.56rem;font-weight:600;letter-spacing:.1em;color:var(--ink-3);padding:3px 0}
.dp-grid{display:grid;grid-template-columns:repeat(7,1fr)}
.dp-day{position:relative;height:31px;padding:2px;border:none;background:transparent;background-clip:content-box;border-radius:10px;font-family:var(--font);font-size:.76rem;font-weight:600;color:var(--ink);cursor:pointer;transition:background .12s,color .12s}
.dp-day:hover{background-color:var(--chip)}
.dp-day.out{color:var(--ink-3);opacity:.4}
/* Fuera del rango posible (el «hasta» nunca por debajo del «desde»). */
.dp-day.off{color:var(--ink-3);opacity:.25;cursor:default;text-decoration:line-through}
.dp-day.off:hover{background-color:transparent}
.dp-hoy.off{opacity:.35;cursor:default}
.dp-aviso{margin-top:8px;padding:7px 9px;border-radius:9px;background:color-mix(in srgb,var(--neg) 10%,transparent);color:var(--neg);font-size:.72rem;font-weight:600;line-height:1.35}
.dp-day.today::after{content:'';position:absolute;bottom:4px;left:50%;transform:translateX(-50%);width:3px;height:3px;border-radius:50%;background:var(--accent)}
.dp-day.inrange{background-color:var(--accent-soft);background-clip:border-box;border-radius:0}
.dp-day.sel{background-color:var(--accent);color:#fff;font-weight:800}
.dp-day.sel.today::after{background:#fff}
.dp-ft{display:flex;justify-content:space-between;align-items:center;border-top:1px solid var(--line);margin-top:8px;padding:8px 3px 0}
.dp-ft button{background:none;border:none;font-family:var(--font);font-size:.76rem;font-weight:700;cursor:pointer;padding:2px 4px;border-radius:6px}
.dp-clear{color:var(--ink-3)}
.dp-clear:hover{color:var(--neg)}
.dp-hoy{color:var(--accent)}
.dp-hoy:hover{text-decoration:underline}

/* ── C7 · Separacion estandar entre bloques apilados ─────────────────────────
   24px en todo el panel; 32px dentro de un formulario largo, donde cada
   tarjeta es un paso y conviene mas aire.

   Va por la regla del HERMANO —todo bloque que siga a otro— y no por una lista
   de clases. Una lista se queda corta el dia que alguien mete un bloque nuevo,
   que es exactamente lo que paso: `.est-2col` no estaba en ella y Estadisticas
   se quedo con las tarjetas pegadas.

   Lo que va DENTRO de una rejilla (.co-grid, .est-2col, .dash-k8, .pbi-grid)
   se separa con su propio `gap` y no lo toca esta regla, que solo mira a los
   hijos directos de .main. */
.main > * + * { margin-top: 24px }

/* Lo que no es un bloque de la pagina y por tanto no entra en el estandar:
   el subtitulo va pegado a la cabecera, y los overlays de los modales son de
   posicion fija — un margen ahi no significa nada. */
.main > .pagesub { margin-top: 0 }
.main > .modal-ov { margin-top: 0 }
.main > script, .main > style, .main > template, .main > form[hidden] { margin-top: 0 }

/* Formulario largo: los pasos de Anadir/Editar tienda, el perfil bancario. */
.main > form > * + * { margin-top: 32px }
/* ...pero NO el form horizontal del rango de fechas del dashboard: ese margen
   bajaba las fechas ~14px respecto a los presets de 7/30/90 días. Y de paso,
   toda la fila a la misma altura (mismo criterio que C9 en .filters). */
.main > form.drange > * + * { margin-top: 0 }
.drange { --h-ctrl: 40px }
.drange .drseg, .drange .fdate, .drange .inp, .drange .btn-out { height: var(--h-ctrl); min-height: var(--h-ctrl) }
.drange .fdate, .drange .dr-go { display: inline-flex; align-items: center; padding-top: 0; padding-bottom: 0 }
.drange .drseg { align-items: center }

/* ── C9 · La fila de filtros, toda a la misma altura ─────────────────────────
   Cada control traia la suya: el desplegable 39px, la fecha 42 (el navegador
   le anade relleno propio), el boton de la lupa 44 y el de Excel 40. Cuatro
   alturas en una sola fila. Aqui se igualan.

   Solo dentro de `.filters`: fuera de la fila de filtros un campo puede
   necesitar otra altura y no hay por que forzarla. */
.filters { --h-ctrl: 40px }
.filters .inp,
.filters .btn,
.filters .btn-out,
.filters .btn-ghost2,
.filters .fdrop-btn,
.filters .select2-container .select2-selection--single {
    height: var(--h-ctrl);
    min-height: var(--h-ctrl);
    padding-top: 0;
    padding-bottom: 0;
    display: inline-flex;
    align-items: center;
}
.filters .inp { line-height: normal }
.filters select.inp { padding-right: 30px }

/* La fecha: sin el relleno interno que le pone el navegador, para que mida lo
   mismo que un desplegable de al lado. */
.filters input[type="date"].inp { padding: 0 12px }

/* La seleccion multiple de select2 se ajusta en rocket-v2-libs.css, que es
   donde vive su piel: ese fichero se carga DESPUES y gana la cascada. */
.filters .select2-container { align-self: center }

/* Los botones de la fila no llevan texto largo: que no se estiren de mas. */
.filters .btn { white-space: nowrap }

/* ── C9 · Campo de archivo con boton propio ──────────────────────────────────
   El boton de un <input type=file> lo escribe el NAVEGADOR y sale en su
   idioma: «Choose File» en un Chrome en ingles, que es lo que se vio en Nuevo
   perfil bancario. No hay forma de cambiarle el texto desde CSS, asi que el
   campo se envuelve (rocket-v2.js) y se ensena un boton nuestro mas el nombre
   del fichero elegido. El input real sigue ahi, solo que no se ve. */
.filebox {
    display: flex; align-items: center; gap: 10px;
    background: var(--bg); border: 1px solid var(--line); border-radius: 11px;
    padding: 6px 10px 6px 6px; cursor: pointer;
    transition: border-color var(--t-fast), background var(--t-fast);
}
.filebox:hover { border-color: var(--accent) }
.filebox:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft) }
.filebox input[type="file"] {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.filebox-btn {
    flex-shrink: 0; display: inline-flex; align-items: center; gap: 7px;
    background: var(--panel); border: 1px solid var(--line); border-radius: 8px;
    padding: 7px 13px; font-size: .8rem; font-weight: 700; color: var(--ink);
}
.filebox-btn svg { width: 14px; height: 14px; color: var(--ink-3) }
.filebox-name {
    min-width: 0; flex: 1; font-size: .8rem; color: var(--ink-3);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.filebox.tiene .filebox-name { color: var(--ink); font-weight: 600 }

/* La barra de filtros de Estadisticas usa .e2-filters, que ya venia en
   rocket-v2.css copiado del prototipo. La .statbar que habia aqui era un
   invento mio: cinco selects nativos apilados donde el diseno tiene una fila
   de desplegables propios. */

/* ── D1 · Tarjetas que se estiran a la altura de su vecina ───────────────── */
.est-flex { display: flex; flex-direction: column }
.est-grow { flex: 1; min-height: 0 }
.est-h3 { font-size: 1rem; font-weight: 700; margin: 4px 0 12px }

/* ── D1 · Embudo: los cuatro datos de pie ────────────────────────────────── */
.est-ministats {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 10px;
    margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--line);
}
.emini { text-align: center }
.emini .v { font-family: var(--mono); font-size: 1rem; font-weight: 800; letter-spacing: -.02em }
.emini .l { font-size: .68rem; color: var(--ink-3); margin-top: 3px; line-height: 1.35 }

/* ── D1 · Crecimiento mensual ────────────────────────────────────────────── */
.cg-wrap { display: flex; flex-direction: column; justify-content: center; gap: 18px }
.cg-hd { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; margin-bottom: 7px }
.cg-hd b { font-size: .86rem }
.cg-r { display: flex; align-items: center; gap: 8px }
.cg-tot { font-size: .76rem }

/* ── D1 · Estados de las ordenes: rejilla de 4, no lista de 1 ────────────────
   Y la barra va del COLOR DEL ESTADO, que es lo que deja leer la fila sin
   buscar el rotulo. Antes todas eran violetas. */
.est-states { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px 22px }
@media (max-width: 1100px) { .est-states { grid-template-columns: repeat(2, minmax(0, 1fr)) } }
@media (max-width: 620px)  { .est-states { grid-template-columns: 1fr } }
.est-st-top { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 7px }
.est-st-n { font-size: .88rem; font-weight: 800 }
.est-st-bar { display: flex; align-items: center; gap: 9px }
.est-st-bar .bh-track { flex: 1 }
.est-st-pct { font-size: .72rem; color: var(--ink-3); flex-shrink: 0; min-width: 44px; text-align: right }

.est-st[data-tono="pos"]       .bh-track i { background: var(--pos) }
.est-st[data-tono="pos-viv"]   .bh-track i { background: #1F9E45 }
.est-st[data-tono="neg"]       .bh-track i { background: var(--neg) }
.est-st[data-tono="neg-2"]     .bh-track i { background: var(--neg-2) }
.est-st[data-tono="warn"]      .bh-track i { background: var(--warn) }
.est-st[data-tono="warn-soft"] .bh-track i { background: var(--warn-soft) }
.est-st[data-tono="info"]      .bh-track i { background: var(--info) }
.est-st[data-tono="violet"]    .bh-track i { background: var(--violet) }
.est-st[data-tono="cyan"]      .bh-track i { background: var(--cyan) }
.est-st[data-tono="indigo"]    .bh-track i { background: var(--indigo) }
.est-st[data-tono="alert"]     .bh-track i { background: var(--neg) }
.est-st[data-tono="mut2"]      .bh-track i { background: var(--ink-3) }

/* ── D1 · Medidores: anillo mas fino y el % del tamano de la cifra ──────────
   El subtitulo iba pegado al anillo y quedaba tapado; ahora va debajo con
   aire y los numeros en negrita. */
.pbig-hd {
    display: flex; align-items: center; justify-content: center; gap: 7px;
    font-size: .74rem; font-weight: 700; color: var(--ink-2);
    letter-spacing: .04em; text-transform: uppercase; margin-bottom: 12px;
}
.pbig-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--g, var(--accent)) }
.pbig-bg { fill: none; stroke: var(--line); stroke-width: 9 }
.pbig-fg {
    fill: none; stroke-width: 9; stroke-linecap: round;
    transform: rotate(-90deg); transform-origin: 50% 50%;
    transition: stroke-dashoffset 1.3s cubic-bezier(.19, 1, .22, 1);
}
.pbig-c b { font-family: var(--mono); font-size: 1.34rem; font-weight: 800; letter-spacing: -.03em }
.pbig-s b { color: var(--ink); font-weight: 800 }
@media (prefers-reduced-motion: reduce) { .pbig-fg { transition: none } }

/* ── D4 · Redes de la tarjeta de comunidad ───────────────────────────────────
   Botones grandes cuadrados —icono arriba, rotulo debajo— al PIE de la
   tarjeta, con el separador de lineas a los lados. Antes eran pildoras planas
   en fila que dejaban la mitad inferior de la tarjeta vacia.

   `margin-top:auto` es lo que los empuja al fondo: la tarjeta es una columna
   flex y este es el ultimo bloque. */
.cmt-soc-k {
    margin-top: auto; display: flex; align-items: center; gap: 10px;
    font-family: var(--mono); font-size: .6rem; letter-spacing: .13em;
    text-transform: uppercase; color: var(--ink-3); font-weight: 600;
}
.cmt-soc-k::before, .cmt-soc-k::after { content: ""; flex: 1; height: 1px; background: var(--line) }

.cmt-socials2 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin-top: 12px }
.soc2 {
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
    padding: 19px 6px 15px; border-radius: 14px; border: 1.5px solid var(--line);
    color: var(--ink-2); cursor: pointer; text-decoration: none;
    transition: transform .16s, background .2s, color .2s, border-color .2s, box-shadow .2s;
}
.soc2 svg { width: 26px; height: 26px; transition: transform .16s }
.soc2 span { font-family: var(--mono); font-size: .62rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700 }
.soc2:hover { transform: translateY(-3px) }
.soc2:hover svg { transform: scale(1.12) }
/* Cada una con su marca al pasar por encima: es lo que las hace reconocibles
   sin leer el rotulo. */
.soc2.tk:hover { background: #010101; color: #fff; border-color: #010101; box-shadow: -3px -3px 0 #25F4EE, 3px 3px 0 #FE2C55 }
.soc2.ig:hover { background: radial-gradient(circle at 30% 110%, #FEDA75 0%, #FA7E1E 26%, #D62976 52%, #962FBF 76%, #4F5BD5 100%); color: #fff; border-color: transparent; box-shadow: 0 10px 24px -8px rgba(214,41,118,.55) }
.soc2.yt:hover { background: #FF0000; color: #fff; border-color: #FF0000; box-shadow: 0 10px 24px -8px rgba(255,0,0,.5) }
@media (prefers-reduced-motion: reduce) { .soc2, .soc2 svg { transition: none } .soc2:hover { transform: none } }

/* ── PARTE E · La pestanita de «Primeros pasos» ──────────────────────────────
   La X del boton flotante no lo elimina: lo repliega aqui. 24x112, pegada al
   borde derecho, con el rotulo en vertical; al pasar por encima se ensancha a
   30 para invitar a pulsarla. El texto va girado con CSS —es texto de verdad,
   no una imagen— para que se vea nitido a cualquier densidad. */
.fab-steps-tab {
    position: fixed; right: 0; top: 50%; transform: translateY(-50%);
    z-index: 340; display: none;
    width: 24px; height: 112px; padding: 0;
    border: none; border-radius: 11px 0 0 11px;
    background: var(--accent); color: #fff; cursor: pointer;
    box-shadow: -4px 0 16px -6px rgba(0, 0, 0, .45);
    transition: width .18s cubic-bezier(.19, 1, .22, 1);
}
.fab-steps-tab span {
    display: block; writing-mode: vertical-rl; transform: rotate(180deg);
    font-family: var(--font); font-size: 9px; font-weight: 800;
    letter-spacing: .16em; white-space: nowrap;
}
.fab-steps-tab:hover { width: 30px }
body.steps-min .fab-steps-tab { display: flex; align-items: center; justify-content: center }
body.steps-min .fab-steps { display: none }
@media (prefers-reduced-motion: reduce) { .fab-steps-tab { transition: none } }

/* ── PARTE E · El rail de los pasos, una linea continua ──────────────────────
   Eran rayitas sueltas y desalineadas. El circulo se ve en TODOS los pasos,
   tambien en los que faltan: si solo apareciera en los hechos, el usuario no
   sabria donde marcar los demas. */
.sp-rail { position: relative; display: flex; flex-direction: column; align-items: center; align-self: stretch }
.sp-line {
    flex: 1; width: 2px; min-height: 14px; margin-top: -1px;
    background: var(--line); border-radius: 1px;
}
.sp-step.done .sp-line { background: var(--accent); opacity: .45 }
.sp-dot {
    flex-shrink: 0; width: 22px; height: 22px; border-radius: 50%;
    display: grid; place-items: center; cursor: pointer;
    border: 2px solid var(--line); background: var(--panel); color: transparent;
    transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.sp-dot:hover { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft) }
.sp-dot svg { width: 12px; height: 12px }
.sp-step.done .sp-dot { background: var(--accent); border-color: var(--accent); color: #fff }

/* El play se enciende al pasar por la fila: en gris parecia deshabilitado. */
.sp-play { flex-shrink: 0; margin-left: auto; color: var(--ink-3); transition: color var(--t-fast), transform var(--t-fast) }
/* El texto ocupa el hueco para que el play quede pegado al borde derecho
   y no justo detras de la ultima palabra. */
.sp-step .sp-tx { flex: 1; min-width: 0 }
.sp-play svg { width: 15px; height: 15px }
.sp-step.has-video:hover .sp-play { color: var(--accent); transform: scale(1.12) }

/* Enlaces legales del pie de las pantallas de entrada (D21). */
.authx-legal { display: inline-flex; align-items: center; gap: 7px; margin-left: 10px }
.authx-legal a { color: var(--ink-3); text-decoration: none }
.authx-legal a:hover { color: var(--accent); text-decoration: underline }

/* Un select con select2 esconde el nativo: el borde rojo de error hay que
   pintarlo sobre el widget o el aviso no se ve. */
select.is-invalid + .select2-container .select2-selection,
select.inp-bad + .select2-container .select2-selection { border-color: var(--neg) !important; box-shadow: 0 0 0 3px rgba(224,87,83,.13) }

/* Cabecera del modal de rechazo: el pedido al que se refiere, de un vistazo. */
.rj-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; margin-bottom: 16px; border: 1px solid var(--line); border-radius: 12px; background: var(--bg) }
.rj-head b { display: block; font-size: 1rem; font-family: var(--mono) }
.rj-head span { font-size: .84rem; color: var(--ink-3) }

/* CALIDAD DE CLIENTE — el botón, a la misma altura que el campo de teléfono.
   Antes el botón se alineaba al fondo de la etiqueta entera, y como debajo del
   input colgaba el texto de ayuda quedaba ~25px por debajo. */
.cal-searchrow { align-items: flex-end }
.cal-searchrow .v2-field { margin-bottom: 0 }
.cal-searchrow .cal-go { width: auto; padding: 0 24px; height: 42px; flex-shrink: 0 }
.cal-searchrow .srch input { height: 42px; padding-top: 0; padding-bottom: 0 }

/* C9 bis · El boton de la barra, a ras de los campos.
   Los controles van dentro de .ff (etiqueta encima + campo), asi que la fila
   mide ~60px; el boton va suelto y con align-items:center quedaba flotando a
   media altura, ~10px por encima de la linea de los campos. */
.filters > .btn,
.filters > .btn-out,
.filters > .btn-ghost2,
.filters > a.btn-ghost2 { align-self: flex-end }
