/* ==========================================================================
   BodegaManager — Sistema de diseño
   Paleta sobria (verde petróleo + neutros fríos). Pensada para transmitir
   confianza, control y profesionalismo.
   ========================================================================== */

@font-face {
  font-family: 'InterVar';
  src: url('../vendor/fonts/inter-variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Marca */
  --brand-50:  #ecfdf7;
  --brand-100: #d1fae8;
  --brand-200: #a7f3d5;
  --brand-300: #6ee7bf;
  --brand-400: #34d3a6;
  --brand-500: #12a086;
  --brand-600: #0e7c6b;
  --brand-700: #0b6357;
  --brand-800: #0a4f46;
  --brand-900: #08403a;

  /* Neutros */
  --gray-25:  #fcfdfe;
  --gray-50:  #f7f9fc;
  --gray-100: #eef2f7;
  --gray-200: #e3e8ef;
  --gray-300: #cdd5df;
  --gray-400: #9aa4b2;
  --gray-500: #697586;
  --gray-600: #4b5565;
  --gray-700: #364152;
  --gray-800: #202939;
  --gray-900: #121926;

  /* Semánticos */
  --ok-50:#ecfdf3;   --ok-500:#12805c;   --ok-700:#0b6045;
  --warn-50:#fffaeb; --warn-500:#b54708; --warn-700:#93370d;
  --dan-50:#fef3f2;  --dan-500:#c8362c;  --dan-700:#a02b22;
  --info-50:#eff6ff; --info-500:#2563eb; --info-700:#1d4ed8;

  /* Superficies */
  --bg:            var(--gray-50);
  --surface:       #ffffff;
  --surface-alt:   var(--gray-50);
  --border:        var(--gray-200);
  --border-strong: var(--gray-300);
  --text:          var(--gray-900);
  --text-soft:     var(--gray-600);
  --text-muted:    var(--gray-500);

  /* Sidebar */
  --side-bg:      #0d1b24;
  --side-bg-2:    #10242f;
  --side-text:    #a9bcc7;
  --side-text-hi: #ffffff;
  --side-border:  rgba(255,255,255,.07);

  /* Formas */
  --r-sm: 6px;
  --r:    10px;
  --r-lg: 14px;
  --r-xl: 18px;

  --sh-xs: 0 1px 2px rgba(16,24,40,.05);
  --sh-sm: 0 1px 3px rgba(16,24,40,.08), 0 1px 2px rgba(16,24,40,.04);
  --sh-md: 0 4px 12px -2px rgba(16,24,40,.08), 0 2px 6px -2px rgba(16,24,40,.05);
  --sh-lg: 0 12px 28px -6px rgba(16,24,40,.12), 0 4px 10px -4px rgba(16,24,40,.06);
  --sh-xl: 0 24px 48px -12px rgba(16,24,40,.18);

  --sidebar-w: 258px;
  --topbar-h: 64px;

  /* Alto real del teclado en pantalla, que app.js mantiene al día leyendo
     visualViewport. En Android el teclado NO encoge el viewport de layout,
     así que sin esto todo lo que va `position:fixed; bottom:0` (la barra de
     cobro y el carrito del POS) queda oculto detrás del teclado justo
     cuando el vendedor está escribiendo en el buscador. */
  --teclado: 0px;
  /* Alto medido de la barra de cobro del POS (lo fija pos.js) */
  --pos-bar-h: 5.6rem;

  /* Overrides Bootstrap */
  --bs-primary: var(--brand-600);
  --bs-primary-rgb: 14,124,107;
  --bs-body-font-family: 'InterVar', 'Segoe UI', system-ui, -apple-system, sans-serif;
  --bs-body-color: var(--text);
  --bs-body-bg: var(--bg);
  --bs-border-color: var(--border);
  --bs-link-color: var(--brand-600);
  --bs-link-hover-color: var(--brand-700);
  --bs-border-radius: var(--r);
}

* { -webkit-tap-highlight-color: transparent; }

html, body { height: 100%; }

body {
  font-family: var(--bs-body-font-family);
  background: var(--bg);
  color: var(--text);
  font-size: .9375rem;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  font-feature-settings: 'cv05' 1, 'cv11' 1;
}

h1,h2,h3,h4,h5,h6 { font-weight: 650; letter-spacing: -.012em; color: var(--text); }

::selection { background: var(--brand-100); color: var(--brand-900); }

/* Scrollbars discretos */
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: var(--gray-300); border-radius: 20px; border: 3px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: var(--gray-400); background-clip: content-box; border: 3px solid transparent; }

.num { font-variant-numeric: tabular-nums; font-feature-settings: 'tnum' 1; }

/* ==========================================================================
   1. LOGIN
   ========================================================================== */
.auth-wrap { min-height: 100vh; display: grid; grid-template-columns: 1.05fr .95fr; }

.auth-hero {
  position: relative;
  background: linear-gradient(155deg, #0b1d26 0%, #0d3b38 55%, #0e7c6b 140%);
  color: #fff;
  padding: 3.5rem 4rem;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.auth-hero::before {
  content: ''; position: absolute; inset: 0;
  background:
    radial-gradient(900px 420px at 88% 8%, rgba(18,160,134,.30), transparent 62%),
    radial-gradient(600px 380px at 6% 96%, rgba(37,99,235,.18), transparent 60%);
}
.auth-hero::after {
  content: ''; position: absolute; inset: 0; opacity: .5;
  background-image: linear-gradient(rgba(255,255,255,.045) 1px, transparent 1px),
                    linear-gradient(90deg, rgba(255,255,255,.045) 1px, transparent 1px);
  background-size: 46px 46px;
  -webkit-mask-image: radial-gradient(ellipse 85% 75% at 50% 40%, #000 30%, transparent 78%);
          mask-image: radial-gradient(ellipse 85% 75% at 50% 40%, #000 30%, transparent 78%);
}
.auth-hero > * { position: relative; z-index: 1; }

.auth-hero h1 { color: #fff; font-size: clamp(1.9rem, 2.7vw, 2.7rem); line-height: 1.16; font-weight: 700; letter-spacing: -.025em; }
.auth-hero p.lead-sub { color: rgba(255,255,255,.72); font-size: 1.02rem; max-width: 30rem; }

.flow-chain { display: flex; flex-direction: column; gap: .35rem; margin-top: 2rem; }
.flow-chain .fc-item {
  display: flex; align-items: center; gap: .7rem;
  background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.09);
  border-radius: var(--r); padding: .6rem .85rem;
  font-size: .875rem; color: rgba(255,255,255,.9);
  backdrop-filter: blur(6px);
}
.flow-chain .fc-item i { color: var(--brand-300); font-size: 1rem; }
.flow-chain .fc-arrow { color: rgba(255,255,255,.28); font-size: .8rem; padding-left: 1.1rem; line-height: 1; }

.auth-panel { display: flex; align-items: center; justify-content: center; padding: 2.5rem; background: var(--surface); }
.auth-card { width: 100%; max-width: 400px; }

.auth-logo { display: flex; align-items: center; gap: .7rem; margin-bottom: 2.25rem; }
.brand-mark {
  width: 42px; height: 42px; border-radius: 11px; flex: 0 0 42px;
  background: linear-gradient(150deg, var(--brand-500), var(--brand-700));
  color: #fff; display: grid; place-items: center; font-size: 1.24rem;
  box-shadow: 0 4px 12px rgba(14,124,107,.32);
}
.brand-name { font-weight: 700; font-size: 1.16rem; letter-spacing: -.02em; line-height: 1.1; }
.brand-tag  { font-size: .715rem; color: var(--text-muted); letter-spacing: .02em; }

.demo-hint {
  background: var(--brand-50); border: 1px dashed var(--brand-300);
  border-radius: var(--r); padding: .8rem .95rem; font-size: .82rem; color: var(--brand-800);
}
.demo-hint code { background: #fff; border: 1px solid var(--brand-200); padding: .08rem .4rem; border-radius: 5px; color: var(--brand-800); font-weight: 600; }

/* Selector de perfil: se entra de un solo toque, sin escribir credenciales */
.role-pick { display: flex; flex-direction: column; gap: .65rem; }
.role-btn {
  display: flex; align-items: center; gap: .9rem; width: 100%; text-align: left;
  background: #fff; border: 1px solid var(--border-strong); border-radius: var(--r-lg);
  padding: .85rem 1rem; transition: transform .16s, box-shadow .16s, border-color .16s;
}
.role-btn:hover, .role-btn:focus-visible {
  border-color: var(--brand-500); box-shadow: var(--sh-md); transform: translateY(-2px); outline: none;
}
.role-btn:active { transform: translateY(0); }
.role-btn .rb-ico {
  width: 46px; height: 46px; flex: 0 0 46px; border-radius: 12px;
  display: grid; place-items: center; font-size: 1.32rem;
}
.role-btn .rb-name { font-weight: 650; font-size: .98rem; line-height: 1.2; letter-spacing: -.01em; }
.role-btn .rb-user { font-size: .775rem; color: var(--text-muted); line-height: 1.3; }
.role-btn .rb-desc { font-size: .765rem; color: var(--text-muted); margin-top: .2rem; line-height: 1.35; }
.role-btn .rb-go { margin-left: auto; color: var(--gray-400); font-size: 1.05rem; transition: .16s; flex: 0 0 auto; }
.role-btn:hover .rb-go { color: var(--brand-600); transform: translateX(3px); }
.role-btn.cargando { pointer-events: none; opacity: .75; border-color: var(--brand-500); }

@media (max-width: 575.98px) {
  .role-btn { padding: .75rem .85rem; gap: .7rem; }
  .role-btn .rb-ico { width: 40px; height: 40px; flex-basis: 40px; font-size: 1.15rem; }
  .role-btn .rb-desc { display: none; }
}

@media (max-width: 991.98px) {
  .auth-wrap { grid-template-columns: 1fr; }
  .auth-hero { display: none; }
  .auth-panel { min-height: 100vh; background: var(--bg); }
  .auth-card { background: var(--surface); padding: 1.9rem 1.6rem; border-radius: var(--r-lg); box-shadow: var(--sh-md); border: 1px solid var(--border); }
}

/* ==========================================================================
   2. SHELL / SIDEBAR / TOPBAR
   ========================================================================== */
.app-shell { display: flex; min-height: 100vh; }

.sidebar {
  width: var(--sidebar-w); flex: 0 0 var(--sidebar-w);
  background: linear-gradient(180deg, var(--side-bg) 0%, var(--side-bg-2) 100%);
  color: var(--side-text);
  display: flex; flex-direction: column;
  position: fixed; inset: 0 auto 0 0; z-index: 1045;
  transition: transform .26s cubic-bezier(.4,0,.2,1);
}
.sidebar-head {
  height: var(--topbar-h); flex: 0 0 var(--topbar-h);
  display: flex; align-items: center; gap: .65rem;
  padding: 0 1.1rem; border-bottom: 1px solid var(--side-border);
}
.sidebar-head .brand-name { color: #fff; font-size: 1.02rem; }
.sidebar-head .brand-tag  { color: rgba(255,255,255,.45); }
.sidebar-head .brand-mark { width: 34px; height: 34px; flex-basis: 34px; font-size: 1.02rem; border-radius: 9px; }

.sidebar-nav { flex: 1; overflow-y: auto; padding: .85rem .65rem 1.4rem; }
.sidebar-nav::-webkit-scrollbar { width: 6px; }
.sidebar-nav::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border: none; }

.nav-section {
  font-size: .655rem; text-transform: uppercase; letter-spacing: .09em;
  color: rgba(255,255,255,.32); font-weight: 650;
  padding: 1rem .75rem .35rem;
}
.nav-item {
  display: flex; align-items: center; gap: .72rem;
  padding: .56rem .75rem; border-radius: 8px;
  color: var(--side-text); text-decoration: none;
  font-size: .875rem; font-weight: 500;
  position: relative; transition: background .13s, color .13s;
  cursor: pointer; margin-bottom: 1px;
}
.nav-item i:first-child { font-size: 1.02rem; width: 1.28rem; text-align: center; opacity: .82; flex: 0 0 auto; }
.nav-item:hover { background: rgba(255,255,255,.06); color: #fff; }
.nav-item.active { background: rgba(18,160,134,.16); color: #fff; font-weight: 600; }
.nav-item.active i:first-child { color: var(--brand-300); opacity: 1; }
.nav-item.active::before {
  content: ''; position: absolute; left: -.65rem; top: 50%; transform: translateY(-50%);
  width: 3px; height: 20px; border-radius: 0 3px 3px 0; background: var(--brand-400);
}
.nav-item .nav-badge {
  margin-left: auto; font-size: .68rem; font-weight: 700;
  background: var(--dan-500); color: #fff; border-radius: 20px;
  padding: .08rem .42rem; min-width: 20px; text-align: center; line-height: 1.4;
}
.nav-item .nav-badge.warn { background: var(--warn-500); }

.sidebar-foot { padding: .75rem .65rem 1rem; border-top: 1px solid var(--side-border); }
.side-user {
  display: flex; align-items: center; gap: .65rem; padding: .5rem .6rem;
  border-radius: 9px; background: rgba(255,255,255,.05);
}
.side-user .avatar { width: 32px; height: 32px; font-size: .76rem; flex: 0 0 32px; }
.side-user .su-name { color: #fff; font-size: .82rem; font-weight: 600; line-height: 1.2; }
.side-user .su-role { color: rgba(255,255,255,.45); font-size: .7rem; }

.sidebar-backdrop {
  position: fixed; inset: 0; background: rgba(13,27,36,.5); z-index: 1040;
  opacity: 0; pointer-events: none; transition: opacity .22s; backdrop-filter: blur(2px);
}

.main { flex: 1; min-width: 0; margin-left: var(--sidebar-w); display: flex; flex-direction: column; }

.topbar {
  height: var(--topbar-h); position: sticky; top: 0; z-index: 1030;
  /* Opaco por defecto: en los Android donde `backdrop-filter` no está
     disponible, un fondo al 88% deja ver el contenido pasando por debajo
     de la barra y parece que el sistema está roto. El cristal se activa
     solo si el navegador lo soporta de verdad. */
  background: #fff;
  border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 1rem; padding: 0 1.5rem;
}
@supports ((backdrop-filter: blur(4px)) or (-webkit-backdrop-filter: blur(4px))) {
  .topbar {
    background: rgba(255,255,255,.88);
    -webkit-backdrop-filter: blur(10px) saturate(180%);
            backdrop-filter: blur(10px) saturate(180%);
  }
}
.topbar h1 { font-size: 1.075rem; font-weight: 650; margin: 0; line-height: 1.2; }
.topbar .tb-sub { font-size: .765rem; color: var(--text-muted); line-height: 1.2; }

.btn-icon {
  width: 38px; height: 38px; border-radius: 9px; border: 1px solid transparent;
  background: transparent; color: var(--text-soft);
  display: inline-grid; place-items: center; font-size: 1.08rem;
  transition: background .14s, color .14s; position: relative; flex: 0 0 auto;
}
.btn-icon:hover { background: var(--gray-100); color: var(--text); }
.btn-icon .dot {
  position: absolute; top: 7px; right: 7px; width: 8px; height: 8px;
  background: var(--dan-500); border: 2px solid #fff; border-radius: 50%;
}

.topbar-search { position: relative; max-width: 330px; flex: 1; }
.topbar-search i { position: absolute; left: .78rem; top: 50%; transform: translateY(-50%); color: var(--gray-400); font-size: .95rem; }
.topbar-search input {
  width: 100%; height: 38px; padding: 0 .8rem 0 2.3rem;
  border: 1px solid var(--border); border-radius: 9px; background: var(--gray-50);
  font-size: .855rem; outline: none; transition: .15s;
}
.topbar-search input:focus { background: #fff; border-color: var(--brand-400); box-shadow: 0 0 0 3.5px rgba(18,160,134,.13); }
.topbar-search kbd {
  position: absolute; right: .5rem; top: 50%; transform: translateY(-50%);
  font-size: .66rem; background: #fff; border: 1px solid var(--border);
  border-bottom-width: 2px; border-radius: 5px; padding: .08rem .32rem; color: var(--text-muted);
}

.page { padding: 1.5rem; flex: 1; }
.page-head { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; margin-bottom: 1.25rem; }
.page-head .ph-title { font-size: 1.32rem; font-weight: 680; letter-spacing: -.02em; margin: 0; }
.page-head .ph-desc { color: var(--text-muted); font-size: .875rem; margin: .15rem 0 0; }
.page-head .ph-actions { margin-left: auto; display: flex; gap: .5rem; flex-wrap: wrap; }

@media (max-width: 991.98px) {
  .sidebar { transform: translateX(-100%); box-shadow: var(--sh-xl); }
  body.sidebar-open .sidebar { transform: translateX(0); }
  body.sidebar-open .sidebar-backdrop { opacity: 1; pointer-events: auto; }
  .main { margin-left: 0; }
  .topbar { padding: 0 1rem; }
  .page { padding: 1rem; }
  .topbar-search { display: none; }
}
@media (max-width: 575.98px) {
  .page-head .ph-actions { margin-left: 0; width: 100%; }
  .page-head .ph-actions .btn { flex: 1; }
}

/* ==========================================================================
   3. AVATARES / CARDS / TABLAS
   ========================================================================== */
.avatar {
  width: 36px; height: 36px; border-radius: 50%; flex: 0 0 36px;
  display: inline-grid; place-items: center;
  font-size: .8rem; font-weight: 650; letter-spacing: .01em;
  background: var(--brand-100); color: var(--brand-800);
}
.avatar.sm { width: 28px; height: 28px; flex-basis: 28px; font-size: .67rem; }
.avatar.lg { width: 48px; height: 48px; flex-basis: 48px; font-size: 1rem; }
.avatar.a1 { background:#e0e7ff; color:#3730a3 } .avatar.a2 { background:#fef3c7; color:#92400e }
.avatar.a3 { background:#fce7f3; color:#9d174d } .avatar.a4 { background:#dbeafe; color:#1e40af }
.avatar.a5 { background:#ede9fe; color:#5b21b6 } .avatar.a6 { background:#ccfbf1; color:#115e59 }

.card-pro {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-lg); box-shadow: var(--sh-xs);
}
.card-hd {
  padding: 1rem 1.15rem; border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: .75rem; flex-wrap: wrap;
}
.card-hd h3 { font-size: .955rem; font-weight: 650; margin: 0; }
.card-hd .ch-sub { font-size: .775rem; color: var(--text-muted); margin: .1rem 0 0; }
.card-hd .ch-actions { margin-left: auto; display: flex; gap: .4rem; align-items: center; }
.card-bd { padding: 1.15rem; }
.card-bd.tight { padding: .7rem; }
.card-bd.flush { padding: 0; }

/* Tarjetas de indicador */
.stat {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 1.1rem 1.15rem; box-shadow: var(--sh-xs); height: 100%;
  position: relative; overflow: hidden; transition: box-shadow .18s, transform .18s;
}
.stat:hover { box-shadow: var(--sh-md); transform: translateY(-1px); }
.stat::after {
  content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--accent, var(--brand-500)); opacity: .9;
}
.stat-top { display: flex; align-items: flex-start; justify-content: space-between; gap: .5rem; margin-bottom: .55rem; }
.stat-label { font-size: .715rem; font-weight: 650; text-transform: uppercase; letter-spacing: .055em; color: var(--text-muted); }
.stat-ico {
  width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
  font-size: 1rem; background: var(--ico-bg, var(--brand-50)); color: var(--accent, var(--brand-600));
  flex: 0 0 34px;
}
.stat-value { font-size: 1.6rem; font-weight: 690; letter-spacing: -.028em; line-height: 1.12; }
.stat-value small { font-size: .95rem; font-weight: 600; color: var(--text-muted); }
.stat-foot { font-size: .765rem; color: var(--text-muted); margin-top: .4rem; display: flex; align-items: center; gap: .3rem; flex-wrap: wrap; }
.trend { font-weight: 650; display: inline-flex; align-items: center; gap: .18rem; }
.trend.up { color: var(--ok-500); } .trend.down { color: var(--dan-500); }

/* Tabla */
.table-wrap { overflow-x: auto; }
.table-pro { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .865rem; }
.table-pro thead th {
  background: var(--gray-50); color: var(--text-soft);
  font-size: .705rem; font-weight: 680; text-transform: uppercase; letter-spacing: .05em;
  padding: .68rem .9rem; text-align: left; white-space: nowrap;
  border-bottom: 1px solid var(--border); border-top: 1px solid var(--border);
  position: sticky; top: 0; z-index: 2;
}
.table-pro thead th:first-child { padding-left: 1.15rem; }
.table-pro thead th:last-child  { padding-right: 1.15rem; }
.table-pro tbody td { padding: .72rem .9rem; border-bottom: 1px solid var(--gray-100); vertical-align: middle; }
.table-pro tbody td:first-child { padding-left: 1.15rem; }
.table-pro tbody td:last-child  { padding-right: 1.15rem; }
.table-pro tbody tr { transition: background .1s; }
.table-pro tbody tr:hover { background: var(--gray-25); }
.table-pro tbody tr:last-child td { border-bottom: none; }
.table-pro .t-right { text-align: right; }
.table-pro .t-center { text-align: center; }
.table-pro .t-nowrap { white-space: nowrap; }
.t-main { font-weight: 600; color: var(--text); line-height: 1.3; }
.t-sub  { font-size: .765rem; color: var(--text-muted); line-height: 1.3; }
.t-code { font-family: ui-monospace, 'Cascadia Code', Consolas, monospace; font-size: .78rem; color: var(--text-soft); background: var(--gray-50); border: 1px solid var(--border); padding: .1rem .4rem; border-radius: 5px; white-space: nowrap; }

.row-actions { display: flex; gap: .15rem; justify-content: flex-end; }
.row-actions .btn-act {
  width: 30px; height: 30px; border-radius: 7px; border: none; background: transparent;
  color: var(--gray-400); display: inline-grid; place-items: center; font-size: .93rem; transition: .13s;
}
.row-actions .btn-act:hover { background: var(--gray-100); color: var(--text); }
.row-actions .btn-act.danger:hover { background: var(--dan-50); color: var(--dan-500); }
.row-actions .btn-act.ok:hover { background: var(--ok-50); color: var(--ok-500); }

/* ==========================================================================
   4. BADGES / BOTONES / FORMULARIOS
   ========================================================================== */
.badge-soft {
  display: inline-flex; align-items: center; gap: .3rem;
  font-size: .715rem; font-weight: 650; padding: .2rem .55rem;
  border-radius: 20px; border: 1px solid transparent; white-space: nowrap; line-height: 1.5;
}
.badge-soft::before { content: ''; width: 5px; height: 5px; border-radius: 50%; background: currentColor; flex: 0 0 5px; }
.badge-soft.no-dot::before { display: none; }
.badge-soft.ok    { background: var(--ok-50);   color: var(--ok-700);   border-color: #a6f4c5; }
.badge-soft.warn  { background: var(--warn-50); color: var(--warn-700); border-color: #fedf89; }
.badge-soft.dan   { background: var(--dan-50);  color: var(--dan-700);  border-color: #fecdca; }
.badge-soft.info  { background: var(--info-50); color: var(--info-700); border-color: #b2ddff; }
.badge-soft.gray  { background: var(--gray-100);color: var(--gray-700); border-color: var(--gray-200); }
.badge-soft.brand { background: var(--brand-50);color: var(--brand-800);border-color: var(--brand-200); }

.btn { font-weight: 600; font-size: .865rem; border-radius: 9px; padding: .5rem .95rem; transition: .15s; }
.btn:focus-visible { box-shadow: 0 0 0 3.5px rgba(18,160,134,.22); }
.btn-primary { background: var(--brand-600); border-color: var(--brand-600); box-shadow: var(--sh-xs); }
.btn-primary:hover, .btn-primary:focus { background: var(--brand-700); border-color: var(--brand-700); }
.btn-primary:active { background: var(--brand-800) !important; border-color: var(--brand-800) !important; }
.btn-outline-secondary { color: var(--text-soft); border-color: var(--border-strong); background: #fff; }
.btn-outline-secondary:hover { background: var(--gray-50); color: var(--text); border-color: var(--gray-400); }
.btn-light-soft { background: var(--gray-100); color: var(--text-soft); border: 1px solid transparent; }
.btn-light-soft:hover { background: var(--gray-200); color: var(--text); }
.btn-danger-soft { background: var(--dan-50); color: var(--dan-700); border: 1px solid #fecdca; }
.btn-danger-soft:hover { background: #fee4e2; color: var(--dan-700); }
.btn-lg { padding: .72rem 1.3rem; font-size: .95rem; border-radius: 10px; }
.btn-sm { padding: .34rem .7rem; font-size: .8rem; border-radius: 7px; }

.form-label { font-size: .81rem; font-weight: 600; color: var(--text-soft); margin-bottom: .32rem; }
.form-label .req { color: var(--dan-500); }
.form-control, .form-select {
  border: 1px solid var(--border-strong); border-radius: 9px;
  padding: .52rem .75rem; font-size: .88rem; color: var(--text); background-color: #fff;
  transition: border-color .14s, box-shadow .14s;
}
.form-control:focus, .form-select:focus {
  border-color: var(--brand-400); box-shadow: 0 0 0 3.5px rgba(18,160,134,.13);
}
.form-control::placeholder { color: var(--gray-400); }
.form-control:disabled, .form-select:disabled, .form-control[readonly] { background: var(--gray-50); color: var(--text-muted); }
.form-text { font-size: .765rem; color: var(--text-muted); }
.input-group-text { background: var(--gray-50); border-color: var(--border-strong); color: var(--text-muted); font-size: .85rem; border-radius: 9px; font-weight: 600; }
.form-check-input:checked { background-color: var(--brand-600); border-color: var(--brand-600); }
.form-check-input:focus { border-color: var(--brand-400); box-shadow: 0 0 0 3.5px rgba(18,160,134,.13); }
.form-check-label { font-size: .865rem; }

/* Selector de segmentos */
.seg { display: inline-flex; background: var(--gray-100); border-radius: 9px; padding: 3px; gap: 2px; }
.seg button {
  border: none; background: transparent; color: var(--text-soft);
  font-size: .8rem; font-weight: 600; padding: .34rem .72rem; border-radius: 7px;
  transition: .14s; white-space: nowrap;
}
.seg button:hover { color: var(--text); }
.seg button.active { background: #fff; color: var(--brand-700); box-shadow: var(--sh-sm); }

/* Modales */
.modal-content { border: none; border-radius: var(--r-lg); box-shadow: var(--sh-xl); }
.modal-header { border-bottom: 1px solid var(--border); padding: 1.1rem 1.35rem; align-items: flex-start; }
.modal-title { font-size: 1.05rem; font-weight: 650; }
.modal-header .mh-sub { font-size: .8rem; color: var(--text-muted); margin: .1rem 0 0; }
.modal-body { padding: 1.35rem; }
.modal-footer { border-top: 1px solid var(--border); padding: .9rem 1.35rem; background: var(--gray-50); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.modal-backdrop.show { opacity: .42; }
.dropdown-menu {
  border: 1px solid var(--border); border-radius: var(--r); box-shadow: var(--sh-lg);
  padding: .35rem; font-size: .865rem;
}
.dropdown-item { border-radius: 7px; padding: .45rem .7rem; font-weight: 500; }
.dropdown-item:active { background: var(--brand-600); }
.dropdown-header { font-size: .7rem; text-transform: uppercase; letter-spacing: .05em; font-weight: 680; color: var(--text-muted); }

/* Estado vacío */
.empty { text-align: center; padding: 3rem 1.5rem; color: var(--text-muted); }
.empty i { font-size: 2.4rem; color: var(--gray-300); display: block; margin-bottom: .7rem; }
.empty h4 { font-size: 1rem; color: var(--text-soft); margin-bottom: .3rem; }
.empty p { font-size: .85rem; margin: 0 auto; max-width: 24rem; }

/* Toasts */
.toast-stack {
  position: fixed; top: 1rem; right: 1rem; z-index: 1090;
  display: flex; flex-direction: column; gap: .55rem; width: 350px; max-width: calc(100vw - 2rem);
}
.toast-pro {
  background: #fff; border: 1px solid var(--border); border-left: 3px solid var(--brand-500);
  border-radius: var(--r); box-shadow: var(--sh-lg); padding: .8rem .9rem;
  display: flex; gap: .7rem; align-items: flex-start;
  animation: toastIn .3s cubic-bezier(.16,1,.3,1);
}
.toast-pro.hiding { animation: toastOut .22s forwards; }
.toast-pro .ti { font-size: 1.12rem; line-height: 1.2; flex: 0 0 auto; color: var(--brand-600); }
.toast-pro .tt { font-weight: 650; font-size: .855rem; line-height: 1.3; }
.toast-pro .tm { font-size: .795rem; color: var(--text-muted); line-height: 1.35; margin-top: .1rem; }
.toast-pro .tx { margin-left: auto; background: none; border: none; color: var(--gray-400); font-size: .95rem; padding: 0 .1rem; }
.toast-pro.ok   { border-left-color: var(--ok-500); }   .toast-pro.ok .ti   { color: var(--ok-500); }
.toast-pro.warn { border-left-color: var(--warn-500); } .toast-pro.warn .ti { color: var(--warn-500); }
.toast-pro.dan  { border-left-color: var(--dan-500); }  .toast-pro.dan .ti  { color: var(--dan-500); }
.toast-pro.info { border-left-color: var(--info-500); } .toast-pro.info .ti { color: var(--info-500); }
@keyframes toastIn  { from { opacity: 0; transform: translateX(24px) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes toastOut { to { opacity: 0; transform: translateX(24px) scale(.97); } }

/* Notificaciones */
.notif-menu { width: 372px; max-width: calc(100vw - 1.5rem); padding: 0; }
.notif-hd { padding: .8rem 1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; }
.notif-hd h6 { margin: 0; font-size: .89rem; font-weight: 650; }
.notif-list { max-height: 390px; overflow-y: auto; }
.notif {
  display: flex; gap: .7rem; padding: .75rem 1rem; border-bottom: 1px solid var(--gray-100);
  text-decoration: none; color: inherit; transition: background .12s;
}
.notif:hover { background: var(--gray-50); }
.notif.unread { background: var(--brand-50); }
.notif.unread:hover { background: var(--brand-100); }
.notif .ni { width: 32px; height: 32px; border-radius: 8px; display: grid; place-items: center; font-size: .95rem; flex: 0 0 32px; }
.notif .nt { font-size: .835rem; font-weight: 600; line-height: 1.3; }
.notif .nm { font-size: .785rem; color: var(--text-muted); line-height: 1.35; }
.notif .nd { font-size: .715rem; color: var(--gray-400); margin-top: .18rem; }
.notif-foot { padding: .55rem; text-align: center; }

/* Alertas del panel */
.alert-row {
  display: flex; align-items: center; gap: .75rem; padding: .72rem .85rem;
  border-radius: var(--r); border: 1px solid; margin-bottom: .5rem; font-size: .855rem;
}
.alert-row:last-child { margin-bottom: 0; }
.alert-row i { font-size: 1.05rem; flex: 0 0 auto; }
.alert-row .ar-act { margin-left: auto; font-weight: 650; font-size: .79rem; text-decoration: none; white-space: nowrap; }
.alert-row.warn { background: var(--warn-50); border-color: #fedf89; color: var(--warn-700); }
.alert-row.dan  { background: var(--dan-50);  border-color: #fecdca; color: var(--dan-700); }
.alert-row.info { background: var(--info-50); border-color: #b2ddff; color: var(--info-700); }
.alert-row.ok   { background: var(--ok-50);   border-color: #a6f4c5; color: var(--ok-700); }
.alert-row .ar-act { color: inherit; }

/* Ranking */
.rank-item { display: flex; align-items: center; gap: .8rem; padding: .6rem 0; border-bottom: 1px solid var(--gray-100); }
.rank-item:last-child { border-bottom: none; }
.rank-n {
  width: 25px; height: 25px; border-radius: 7px; background: var(--gray-100); color: var(--text-soft);
  display: grid; place-items: center; font-size: .745rem; font-weight: 700; flex: 0 0 25px;
}
.rank-item:nth-child(1) .rank-n { background: var(--brand-600); color: #fff; }
.rank-item:nth-child(2) .rank-n { background: var(--brand-200); color: var(--brand-800); }
.rank-item:nth-child(3) .rank-n { background: var(--brand-100); color: var(--brand-700); }
.rank-bar { height: 5px; border-radius: 20px; background: var(--gray-100); overflow: hidden; margin-top: .3rem; }
.rank-bar span { display: block; height: 100%; border-radius: 20px; background: var(--brand-500); }

/* Actividad */
.act-item { display: flex; gap: .8rem; padding: .62rem 0; }
.act-item + .act-item { border-top: 1px solid var(--gray-100); }
.act-ico { width: 32px; height: 32px; border-radius: 9px; display: grid; place-items: center; font-size: .93rem; flex: 0 0 32px; }
.act-t { font-size: .855rem; font-weight: 600; line-height: 1.3; }
.act-m { font-size: .785rem; color: var(--text-muted); }
.act-time { margin-left: auto; font-size: .735rem; color: var(--gray-400); white-space: nowrap; }

/* Utilidades */
.hr-soft { height: 1px; background: var(--border); border: none; margin: 1rem 0; opacity: 1; }
.text-muted-2 { color: var(--text-muted) !important; }
.fs-xs { font-size: .765rem; } .fs-sm { font-size: .845rem; }
.money-pos { color: var(--ok-500); font-weight: 650; }
.money-neg { color: var(--dan-500); font-weight: 650; }
.chart-box { position: relative; width: 100%; }
.skeleton { background: linear-gradient(90deg, var(--gray-100) 25%, var(--gray-200) 37%, var(--gray-100) 63%); background-size: 400% 100%; animation: sk 1.4s infinite; border-radius: 6px; }
@keyframes sk { 0% { background-position: 100% 50% } 100% { background-position: 0 50% } }
.view-enter { animation: viewIn .26s cubic-bezier(.16,1,.3,1); }
@keyframes viewIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }

/* El POS entra solo con opacidad: un `transform` en el contenedor rompería
   el posicionamiento fijo de la barra de cobro y del carrito deslizante. */
.pos-page.view-enter { animation: viewInSuave .22s ease; }
@keyframes viewInSuave { from { opacity: 0; } to { opacity: 1; } }

/* ==========================================================================
   5. PUNTO DE VENTA (POS)
   ========================================================================== */
.pos-grid {
  display: grid; grid-template-columns: minmax(0,1fr) 400px; gap: 1rem;
  height: calc(100vh - var(--topbar-h) - 2rem);
}
/* `min-width: 0` es imprescindible: un elemento de rejilla arranca con
   `min-width: auto`, o sea que se niega a encogerse por debajo del ancho
   mínimo de su contenido. Si un solo hijo pide más ancho del que hay, la
   columna entera crece y saca del encuadre toda la pantalla, que es lo que
   pasaba en el celular. Con esto el ancho del contenedor manda siempre. */
.pos-left, .pos-right { display: flex; flex-direction: column; min-height: 0; min-width: 0; }
.pos-panel {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
  display: flex; flex-direction: column; min-height: 0; min-width: 0; flex: 1; box-shadow: var(--sh-xs);
}
.pos-search, .cat-chips, .prod-grid, .cart-body, .cart-foot { min-width: 0; }
.pos-search { padding: .85rem; border-bottom: 1px solid var(--border); }
.pos-search .ps-input { position: relative; }

/* Este bloque llevaba `d-flex` de Bootstrap en el marcado, que se compila
   como `display:flex !important`. El !important gana SIEMPRE a una regla
   normal, por mucha especificidad que tenga, así que el `display:none` del
   bloque móvil no lo ocultaba nunca: el texto de ayuda seguía ahí en el
   celular, estirando el panel del punto de venta más ancho que la pantalla.
   Al traer el flex a la clase propia, la regla móvil vuelve a mandar. */
.pos-search .ayuda-pos { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; min-width: 0; }
.pos-search .ayuda-pos > span { min-width: 0; }
.pos-search .ps-input i { position: absolute; left: .85rem; top: 50%; transform: translateY(-50%); color: var(--gray-400); font-size: 1.05rem; }
.pos-search .ps-input input {
  width: 100%; height: 46px; padding: 0 .9rem 0 2.55rem; font-size: .95rem;
  border: 1px solid var(--border-strong); border-radius: 10px; outline: none; transition: .15s;
}
.pos-search .ps-input input:focus { border-color: var(--brand-500); box-shadow: 0 0 0 3.5px rgba(18,160,134,.13); }

/* Esta fila se arrastra en horizontal a propósito, pero se cortaba en seco
   contra el borde del panel y parecía contenido roto. El degradado del final
   avisa de que hay más categorías a la derecha. */
.cat-chips {
  display: flex; gap: .35rem; overflow-x: auto; padding: .7rem .85rem;
  border-bottom: 1px solid var(--border); scrollbar-width: none;
}
/* Solo mientras quede algo a la derecha (lo marca pos.js): un degradado
   permanente haría parecer cortada la última categoría al llegar al final. */
.cat-chips.tiene-mas {
  -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
          mask-image: linear-gradient(90deg, #000 calc(100% - 28px), transparent);
}
.cat-chips::-webkit-scrollbar { display: none; }
.chip {
  border: 1px solid var(--border-strong); background: #fff; color: var(--text-soft);
  font-size: .795rem; font-weight: 600; padding: .3rem .72rem; border-radius: 20px;
  white-space: nowrap; transition: .14s;
}
.chip:hover { background: var(--gray-50); color: var(--text); }
.chip.active { background: var(--brand-600); border-color: var(--brand-600); color: #fff; }

.prod-grid {
  flex: 1; overflow-y: auto; padding: .85rem;
  display: grid; grid-template-columns: repeat(auto-fill, minmax(146px, 1fr));
  gap: .65rem; align-content: start;
}
.prod-tile {
  border: 1px solid var(--border); border-radius: var(--r); background: #fff;
  padding: .7rem; cursor: pointer; text-align: left; transition: .14s; position: relative;
  display: flex; flex-direction: column; min-height: 128px;
  /* `height: 100%` fuerza que la tarjeta ocupe toda la altura de su fila.
     Los <button> no siempre se estiran solos como elemento de rejilla según
     el navegador, y sin esto las tarjetas de nombre corto quedaban más bajas
     y el precio de cada una caía a una altura distinta. */
  height: 100%;
}
.prod-tile:hover { border-color: var(--brand-400); box-shadow: var(--sh-md); transform: translateY(-2px); }
.prod-tile:active { transform: translateY(0); }
.prod-tile.out { opacity: .5; cursor: not-allowed; }
.prod-tile.out:hover { transform: none; box-shadow: none; border-color: var(--border); }
.pt-emoji {
  width: 40px; height: 40px; border-radius: 9px; background: var(--gray-50);
  display: grid; place-items: center; font-size: 1.28rem; margin-bottom: .5rem; border: 1px solid var(--gray-100);
}
/* El nombre ocupa siempre dos líneas exactas, tenga una o dos. Es lo que
   alinea de verdad la rejilla: el bloque de precio y stock arranca a la
   misma altura en todas las tarjetas de la fila. Lo que no entra se corta
   con puntos suspensivos en vez de empujar la tarjeta. */
.pt-name {
  font-size: .81rem; font-weight: 600; line-height: 1.28; margin-bottom: .12rem;
  min-height: calc(2 * 1.28em);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.pt-meta {
  font-size: .715rem; color: var(--text-muted); margin-bottom: .45rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.pt-foot { margin-top: auto; display: flex; align-items: baseline; justify-content: space-between; gap: .3rem; }
.pt-price { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.pt-stock { flex: 0 0 auto; }
.pt-price { font-size: .95rem; font-weight: 690; color: var(--brand-700); letter-spacing: -.02em; }
.pt-stock { font-size: .69rem; font-weight: 650; color: var(--text-muted); }
.pt-stock.low { color: var(--warn-500); } .pt-stock.zero { color: var(--dan-500); }
.prod-tile .pt-flag {
  position: absolute; top: .45rem; right: .45rem; font-size: .62rem; font-weight: 700;
  padding: .05rem .35rem; border-radius: 5px; text-transform: uppercase; letter-spacing: .03em;
}
.pt-flag.low  { background: var(--warn-50); color: var(--warn-700); }
.pt-flag.zero { background: var(--dan-50);  color: var(--dan-700); }

.cart-head { padding: .85rem 1rem; border-bottom: 1px solid var(--border); display: flex; align-items: center; gap: .6rem; }
.cart-head h3 { font-size: .95rem; font-weight: 650; margin: 0; }
.cart-count { background: var(--brand-600); color: #fff; font-size: .7rem; font-weight: 700; border-radius: 20px; padding: .1rem .45rem; min-width: 21px; text-align: center; }
.cart-body { flex: 1; overflow-y: auto; padding: .5rem .6rem; min-height: 90px; }
.cart-line { display: flex; gap: .6rem; padding: .55rem .4rem; border-radius: 9px; transition: background .12s; }
.cart-line:hover { background: var(--gray-50); }
.cart-line + .cart-line { border-top: 1px solid var(--gray-100); }
.cl-info { flex: 1; min-width: 0; }
.cl-name { font-size: .825rem; font-weight: 600; line-height: 1.28; }
.cl-price { font-size: .74rem; color: var(--text-muted); }
.cl-right { text-align: right; display: flex; flex-direction: column; align-items: flex-end; gap: .28rem; }
.cl-total { font-size: .875rem; font-weight: 680; letter-spacing: -.015em; }
.qty { display: inline-flex; align-items: center; border: 1px solid var(--border-strong); border-radius: 7px; overflow: hidden; background: #fff; }
.qty button { width: 26px; height: 26px; border: none; background: #fff; color: var(--text-soft); font-size: .85rem; display: grid; place-items: center; transition: .12s; }
.qty button:hover { background: var(--gray-100); color: var(--text); }
.qty input { width: 38px; height: 26px; border: none; border-left: 1px solid var(--border); border-right: 1px solid var(--border); text-align: center; font-size: .8rem; font-weight: 650; outline: none; padding: 0; }
/* Cantidad de un producto a granel en el carrito. Se toca para volver a
   pesarlo: un botón de "+1" no significa nada cuando se vende por kilos. */
.btn-peso {
  display: inline-flex; align-items: center; gap: .35rem;
  border: 1px solid var(--brand-200); background: var(--brand-50); color: var(--brand-800);
  border-radius: 7px; padding: .2rem .55rem;
  font-size: .8rem; font-weight: 650; transition: .14s;
}
.btn-peso:hover { background: var(--brand-100); border-color: var(--brand-400); }
.pt-por { font-size: .68rem; font-weight: 600; color: var(--text-muted); margin-left: .05rem; }

.cl-del { background: none; border: none; color: var(--gray-400); font-size: .88rem; padding: 0 .1rem; }
.cl-del:hover { color: var(--dan-500); }

.cart-foot { border-top: 1px solid var(--border); padding: .85rem 1rem 1rem; background: var(--gray-50); border-radius: 0 0 var(--r-lg) var(--r-lg); }
.sum-line { display: flex; justify-content: space-between; align-items: center; font-size: .845rem; color: var(--text-soft); margin-bottom: .35rem; }
.sum-total { display: flex; justify-content: space-between; align-items: baseline; padding-top: .6rem; margin-top: .35rem; border-top: 1px dashed var(--border-strong); }
.sum-total .st-lbl { font-size: .82rem; font-weight: 680; text-transform: uppercase; letter-spacing: .05em; color: var(--text-soft); }
.sum-total .st-val { font-size: 1.62rem; font-weight: 700; letter-spacing: -.03em; color: var(--brand-700); }

/* `repeat(5, 1fr)` deja un suelo de min-content en cada columna: con las
   cinco etiquetas (Efectivo, Yape, Plin, Tarjeta, Crédito) la fila se negaba
   a encoger por debajo de su ancho natural y desbordaba el carrito en
   pantallas de 320px. Con minmax(0,1fr) las etiquetas parten de línea. */
.pay-methods { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: .32rem; margin: .7rem 0; }
.pay-m { overflow-wrap: anywhere; }
.pay-m {
  border: 1px solid var(--border-strong); background: #fff; border-radius: 9px;
  padding: .45rem .2rem; text-align: center; transition: .14s; font-size: .66rem; font-weight: 650; color: var(--text-soft);
}
.pay-m i { display: block; font-size: 1.05rem; margin-bottom: .1rem; }
.pay-m:hover { border-color: var(--brand-400); color: var(--text); }
.pay-m.active { border-color: var(--brand-600); background: var(--brand-50); color: var(--brand-800); box-shadow: 0 0 0 1px var(--brand-600) inset; }

/* Elementos exclusivos de la versión móvil del POS */
.pos-bar, .cart-grip, .pos-backdrop { display: none; }

@media (max-width: 1199.98px) {
  .pos-grid { grid-template-columns: minmax(0,1fr) 350px; }
}

/* --------------------------------------------------------------------------
   POS en tablet y celular:
   catálogo a pantalla completa + barra de cobro fija + carrito deslizante.
   -------------------------------------------------------------------------- */
@media (max-width: 991.98px) {
  /* iOS amplía la página entera al enfocar cualquier campo con menos de 16px
     de letra, y luego no la vuelve a alejar solo. En el punto de venta
     saltaba al tocar el selector de cliente, el descuento o la cantidad del
     carrito, que son `-sm` de Bootstrap (14px). El cambio visual es mínimo y
     quita el salto. */
  .form-control, .form-select, .form-control-sm, .form-select-sm,
  .qty input, textarea { font-size: 16px; }
  .qty input { width: 48px; }

  .pos-page { padding: .7rem .7rem 0; }

  .pos-grid {
    /* `1fr` a secas deja un suelo de min-content y la columna puede
       desbordar; `minmax(0,1fr)` la ata al ancho disponible. */
    grid-template-columns: minmax(0, 1fr); gap: 0;
    /* Se resta la barra de cobro (alto real, no un número mágico) y el
       teclado en pantalla, para que la rejilla de productos siga siendo
       recorrible mientras se escribe. */
    height: calc(100vh - var(--topbar-h) - var(--pos-bar-h) - var(--teclado));
    height: calc(100dvh - var(--topbar-h) - var(--pos-bar-h) - var(--teclado));
    min-height: 190px;
  }

  .pos-search { padding: .7rem; }
  .pos-search .ps-input input { height: 48px; font-size: 1rem; }
  .pos-search .ayuda-pos { display: none; }
  .cat-chips { padding: .55rem .7rem; }
  .chip { padding: .38rem .8rem; }

  .prod-grid {
    grid-template-columns: repeat(auto-fill, minmax(142px, 1fr));
    gap: .55rem; padding: .7rem;
  }
  .prod-tile { min-height: 112px; padding: .6rem; }
  .prod-tile:active { transform: scale(.97); }
  .pt-emoji { width: 34px; height: 34px; font-size: 1.1rem; margin-bottom: .4rem; }
  .pt-name { font-size: .8rem; }

  /* --- Barra fija de cobro --- */
  .pos-bar {
    display: flex; align-items: center; gap: .75rem;
    position: fixed; left: 0; right: 0; bottom: var(--teclado); z-index: 1035;
    transition: bottom .18s ease;
    background: #fff; border-top: 1px solid var(--border);
    box-shadow: 0 -4px 20px rgba(16,24,40,.10);
    padding: .6rem calc(.85rem + env(safe-area-inset-right, 0px))
             calc(.6rem + env(safe-area-inset-bottom, 0px))
             calc(.85rem + env(safe-area-inset-left, 0px));
  }
  /* Con el teclado abierto la barra ya no toca el borde de la pantalla:
     el hueco del gesto de navegación sobraría. */
  body.teclado-abierto .pos-bar { padding-bottom: .6rem; }
  .pos-bar .pb-cart {
    position: relative; width: 42px; height: 42px; flex: 0 0 42px;
    border-radius: 11px; background: var(--brand-50); color: var(--brand-600);
    display: grid; place-items: center; font-size: 1.2rem;
  }
  .pos-bar .pb-count {
    position: absolute; top: -5px; right: -5px; min-width: 20px; height: 20px;
    border-radius: 20px; background: var(--brand-600); color: #fff;
    font-size: .68rem; font-weight: 700; display: grid; place-items: center;
    padding: 0 5px; border: 2px solid #fff;
  }
  .pos-bar .pb-label { font-size: .7rem; color: var(--text-muted); font-weight: 600; line-height: 1.2; }
  .pos-bar .pb-total { font-size: 1.22rem; font-weight: 700; letter-spacing: -.03em; color: var(--brand-700); line-height: 1.15; }
  .pos-bar .pb-vacio { font-size: .82rem; color: var(--text-muted); line-height: 1.3; }
  .pos-bar .btn { margin-left: auto; white-space: nowrap; }
  .pos-bar.tiene-items .pb-cart { animation: latido .3s ease; }
  @keyframes latido { 50% { transform: scale(1.14); } }

  /* --- Carrito como panel inferior --- */
  .pos-backdrop {
    display: block; position: fixed; inset: 0; z-index: 1042;
    background: rgba(13,27,36,.45); backdrop-filter: blur(2px);
    opacity: 0; pointer-events: none; transition: opacity .25s;
  }
  body.cart-open .pos-backdrop { opacity: 1; pointer-events: auto; }

  .pos-right {
    position: fixed; left: 0; right: 0; bottom: var(--teclado); z-index: 1043;
    height: min(90dvh, 660px); max-height: 90vh;
    transform: translateY(101%);
    transition: transform .3s cubic-bezier(.32,.72,0,1), visibility .3s;
    visibility: hidden;
  }
  body.cart-open .pos-right { transform: translateY(0); visibility: visible; }
  body.cart-open { overflow: hidden; }

  .pos-right .pos-panel {
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-bottom: none;
    box-shadow: 0 -14px 44px rgba(16,24,40,.22);
  }
  .cart-grip { display: block; padding: .5rem 0 .1rem; text-align: center; flex: 0 0 auto; }
  .cart-grip span { display: inline-block; width: 40px; height: 4px; border-radius: 20px; background: var(--gray-300); }
  .cart-head { padding-top: .55rem; }
  .cart-body { max-height: none; }
  .cart-foot { padding-bottom: calc(1rem + env(safe-area-inset-bottom, 0px)); }

  /* Objetivos táctiles más cómodos */
  .qty button { width: 34px; height: 32px; font-size: 1rem; }
  .qty input { width: 44px; height: 32px; font-size: .875rem; }
  .cl-del { font-size: 1.05rem; padding: .2rem .35rem; }
  .btn-peso { padding: .38rem .75rem; font-size: .875rem; }
  .cart-line { padding: .65rem .45rem; }
  .pay-m { padding: .55rem .2rem; font-size: .68rem; }
  .pay-m i { font-size: 1.15rem; }
  #btnCobrar { padding: .85rem 1rem; font-size: 1rem; }
}

@media (max-width: 400px) {
  .prod-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pos-bar .pb-total { font-size: 1.1rem; }
  .pos-bar .btn { padding: .55rem .75rem; font-size: .82rem; }
}

/* ==========================================================================
   5b. ESCÁNER DE CÓDIGO DE BARRAS
   ========================================================================== */
.scan-wrap {
  position: relative; width: 100%; aspect-ratio: 4 / 3;
  background: #0d1b24; border-radius: var(--r); overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.scan-wrap video { width: 100%; height: 100%; object-fit: cover; display: block; }
.scan-overlay { position: absolute; inset: 0; pointer-events: none; }

/* Oscurecido alrededor del marco con cuatro franjas fijas.
   Antes se resolvía con `box-shadow: 0 0 0 100vmax` sobre el marco: en un
   celular eso es una sombra de más de 800px de extensión que el navegador
   repinta encima del vídeo en cada fotograma, y era la causa principal de
   que el escáner fuera a tirones en Android. Cuatro rectángulos opacos
   cuestan cero. Los porcentajes derivan del marco (78% x 42%):
   (100-42)/2 = 29% arriba y abajo, (100-78)/2 = 11% a los lados. */
.scan-dim { position: absolute; background: rgba(13,27,36,.45); }
.scan-dim.arriba { top: 0; left: 0; right: 0; height: 29%; }
.scan-dim.abajo  { bottom: 0; left: 0; right: 0; height: 29%; }
.scan-dim.izq    { top: 29%; bottom: 29%; left: 0; width: 11%; }
.scan-dim.der    { top: 29%; bottom: 29%; right: 0; width: 11%; }

.scan-marco {
  position: absolute; left: 11%; top: 29%; width: 78%; height: 42%;
  border-radius: 12px;
  outline: 2px solid rgba(255,255,255,.85);
  outline-offset: -2px;
}
.scan-marco::before, .scan-marco::after {
  content: ''; position: absolute; width: 26px; height: 26px;
  border: 3px solid var(--brand-400); border-radius: 4px;
}
.scan-marco::before { top: -3px; left: -3px; border-right: none; border-bottom: none; }
.scan-marco::after { bottom: -3px; right: -3px; border-left: none; border-top: none; }
/* La línea ocupa todo el alto del marco y solo se ve su borde superior:
   así el `translateY` en porcentaje se mide contra el alto del marco y la
   animación va por `transform` (compositor) en vez de por `top` (layout). */
.scan-laser {
  position: absolute; left: 6%; right: 6%; top: 0; height: 100%;
  pointer-events: none;
  animation: laser 2s ease-in-out infinite;
}
.scan-laser::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 2px;
  background: linear-gradient(90deg, transparent, var(--brand-400), transparent);
  box-shadow: 0 0 8px var(--brand-400);
}
@keyframes laser { 0%,100% { transform: translateY(8%); } 50% { transform: translateY(88%); } }
.scan-estado {
  position: absolute; left: 50%; bottom: .7rem; transform: translateX(-50%);
  background: rgba(13,27,36,.82); color: #fff; border-radius: 20px;
  padding: .35rem .85rem; font-size: .8rem; font-weight: 600; white-space: nowrap;
  display: flex; align-items: center; max-width: 92%; overflow: hidden; text-overflow: ellipsis;
}
.scan-estado.ok { background: var(--ok-500); }

/* Bootstrap Icons baja el glifo un .125em (`vertical-align: -.125em` en
   `.bi::before`) para que se asiente bien junto a un texto. En un botón que
   solo lleva icono eso lo deja descolgado hacia abajo, que es lo que se veía
   en el botón de la cámara. Convirtiendo la <i> en contenedor flex, el
   `vertical-align` de su ::before deja de aplicarse y el icono queda
   centrado de verdad. Solo para los controles que son icono y nada más. */
.btn-scan i, .btn-icon > i, .qty button i, .cl-del i, .pos-bar .pb-cart > i {
  display: flex; align-items: center; justify-content: center; line-height: 1;
}

/* Botón de escaneo dentro de campos y buscadores */
.btn-scan {
  border: 1px solid var(--border-strong); background: #fff; color: var(--text-soft);
  border-radius: 9px; padding: 0 .7rem; display: inline-flex; align-items: center;
  gap: .35rem; font-size: .82rem; font-weight: 600; transition: .14s;
}
.btn-scan:hover { border-color: var(--brand-500); color: var(--brand-700); background: var(--brand-50); }
.pos-search .ps-input .btn-scan {
  position: absolute; right: .4rem; top: 50%; transform: translateY(-50%); height: 36px;
}
.pos-search .ps-input input { padding-right: 7.2rem; }
@media (max-width: 575.98px) {
  /* Sin el texto, el botón pasa a ser un cuadrado: se le fija el ancho y se
     centra el contenido, en vez de dejarlo con el relleno lateral del modo
     con etiqueta. */
  .pos-search .ps-input .btn-scan .btn-scan-txt { display: none; }
  .pos-search .ps-input .btn-scan {
    width: 38px; padding: 0; justify-content: center; font-size: 1.05rem;
  }
  .pos-search .ps-input input { padding-right: 3.6rem; }
  /* Antes aquí se forzaba `aspect-ratio: 3/4`. Con la cámara del celular
     (16:9 apaisada) y `object-fit: cover`, una caja vertical recorta el 58%
     del ancho de la imagen: justo la dimensión que hace falta para leer un
     código de barras. En 4/3 solo se pierde el 25%. */
}

/* ==========================================================================
   6. TICKET
   ========================================================================== */
.ticket {
  /* `max-width` es obligatorio: en un celular estrecho el modal de venta
     registrada deja menos de 300px de hueco y el comprobante se salía por
     la derecha, justo en la pantalla que se ve después de cada venta. */
  width: 300px; max-width: 100%; margin: 0 auto; background: #fff; padding: 1.15rem 1.05rem;
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace; font-size: .755rem;
  color: #1a1a1a; line-height: 1.55; border: 1px solid var(--border); border-radius: 6px;
  box-shadow: var(--sh-sm);
}
.ticket .tk-c { text-align: center; }
.ticket .tk-biz { font-size: .95rem; font-weight: 700; letter-spacing: .04em; }
.ticket .tk-sep { border-top: 1px dashed #b6b6b6; margin: .55rem 0; }
.ticket .tk-row { display: flex; justify-content: space-between; gap: .5rem; }
.ticket .tk-row.total { font-weight: 700; font-size: .875rem; }
.ticket .tk-it { margin-bottom: .3rem; }
.ticket .tk-it .n { font-weight: 600; }
.ticket .tk-thanks { text-align: center; margin-top: .6rem; font-weight: 700; }
.ticket-bg { background: var(--gray-100); padding: 1.35rem .5rem; border-radius: var(--r); }

.sale-ok {
  text-align: center; padding: .4rem 0 1rem;
}
.sale-ok .so-ico {
  width: 62px; height: 62px; border-radius: 50%; background: var(--ok-50); color: var(--ok-500);
  display: grid; place-items: center; font-size: 2rem; margin: 0 auto .7rem;
  animation: pop .45s cubic-bezier(.16,1.3,.4,1);
}
@keyframes pop { 0% { transform: scale(.4); opacity: 0 } 100% { transform: scale(1); opacity: 1 } }
.sale-ok h3 { font-size: 1.15rem; margin-bottom: .18rem; }
.sale-ok p { color: var(--text-muted); font-size: .87rem; margin: 0; }

/* Contenedor de impresión: ticket.js monta aquí el comprobante.
   Fuera de la impresión no se ve. */
#bmImpresion { display: none; }

@media print {
  /* Se ocultan los hermanos con `display:none` y no con `visibility:hidden`:
     lo segundo deja los elementos ocupando su sitio y salían páginas en
     blanco antes del ticket. */
  body > *:not(#bmImpresion) { display: none !important; }
  #bmImpresion { display: block !important; }
  #bmImpresion .ticket {
    width: 76mm; max-width: 100%; margin: 0;
    border: none; box-shadow: none; border-radius: 0;
  }
  @page { size: 76mm auto; margin: 4mm; }
}

/* ==========================================================================
   7. VARIOS DE MÓDULO
   ========================================================================== */
.kv { display: flex; justify-content: space-between; gap: 1rem; padding: .48rem 0; border-bottom: 1px solid var(--gray-100); font-size: .865rem; }
.kv:last-child { border-bottom: none; }
.kv .k { color: var(--text-muted); }
.kv .v { font-weight: 600; text-align: right; }

.mini-stat { display: flex; align-items: center; gap: .75rem; padding: .8rem .9rem; border: 1px solid var(--border); border-radius: var(--r); background: #fff; height: 100%; }
.mini-stat .ms-ico { width: 38px; height: 38px; border-radius: 10px; display: grid; place-items: center; font-size: 1.08rem; flex: 0 0 38px; }
.mini-stat .ms-val { font-size: 1.22rem; font-weight: 690; letter-spacing: -.02em; line-height: 1.15; }
.mini-stat .ms-lbl { font-size: .745rem; color: var(--text-muted); font-weight: 550; }

.bg-ok-50{background:var(--ok-50)!important}      .text-ok{color:var(--ok-500)!important}
.bg-warn-50{background:var(--warn-50)!important}  .text-warn{color:var(--warn-500)!important}
.bg-dan-50{background:var(--dan-50)!important}    .text-dan{color:var(--dan-500)!important}
.bg-info-50{background:var(--info-50)!important}  .text-info-2{color:var(--info-500)!important}
.bg-brand-50{background:var(--brand-50)!important}.text-brand{color:var(--brand-600)!important}
.bg-gray-100{background:var(--gray-100)!important}.text-gray{color:var(--gray-500)!important}

.cash-flow-row { display: flex; align-items: center; gap: .8rem; padding: .62rem 0; border-bottom: 1px solid var(--gray-100); }
.cash-flow-row:last-child { border-bottom: none; }
.cash-flow-row .cf-ico { width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center; font-size: .95rem; flex: 0 0 34px; }
.cash-flow-row .cf-l { font-size: .865rem; font-weight: 600; }
.cash-flow-row .cf-s { font-size: .755rem; color: var(--text-muted); }
.cash-flow-row .cf-v { margin-left: auto; font-weight: 680; font-size: .935rem; letter-spacing: -.015em; }

.perm-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px,1fr)); gap: .5rem; }
.perm-item { display: flex; align-items: center; gap: .5rem; padding: .5rem .7rem; border: 1px solid var(--border); border-radius: 8px; font-size: .82rem; background: #fff; }
.perm-item i { font-size: .95rem; }
.perm-item.yes { border-color: #a6f4c5; background: var(--ok-50); color: var(--ok-700); }
.perm-item.no { color: var(--gray-400); background: var(--gray-50); }

.role-card { border: 1px solid var(--border); border-radius: var(--r-lg); padding: 1.05rem; background: #fff; height: 100%; transition: .16s; }
.role-card:hover { box-shadow: var(--sh-md); }
.role-card .rc-ico { width: 42px; height: 42px; border-radius: 11px; display: grid; place-items: center; font-size: 1.2rem; margin-bottom: .7rem; }

.step-num {
  width: 26px; height: 26px; border-radius: 50%; background: var(--brand-600); color: #fff;
  display: inline-grid; place-items: center; font-size: .75rem; font-weight: 700; flex: 0 0 26px;
}

.filter-bar { display: flex; gap: .5rem; flex-wrap: wrap; align-items: flex-end; }
.filter-bar .fb-item { min-width: 138px; flex: 1 1 138px; }
.filter-bar .fb-item .form-label { font-size: .74rem; margin-bottom: .22rem; }

.tag-list { display: flex; flex-wrap: wrap; gap: .25rem; }
.tag { font-size: .715rem; background: var(--gray-100); color: var(--text-soft); padding: .1rem .45rem; border-radius: 5px; white-space: nowrap; }

.progress-thin { height: 6px; border-radius: 20px; background: var(--gray-100); overflow: hidden; }
.progress-thin > div { height: 100%; border-radius: 20px; transition: width .4s; }

.hover-lift { transition: transform .16s, box-shadow .16s; }
.hover-lift:hover { transform: translateY(-2px); box-shadow: var(--sh-md); }

@media (max-width: 767.98px) {
  .stat-value { font-size: 1.4rem; }
  .table-pro { font-size: .82rem; }
  .table-pro thead th, .table-pro tbody td { padding: .6rem .7rem; }
  .table-pro thead th:first-child, .table-pro tbody td:first-child { padding-left: .85rem; }
  .table-pro thead th:last-child, .table-pro tbody td:last-child { padding-right: .85rem; }
  .modal-body { padding: 1.1rem; }
  .toast-stack { top: auto; bottom: 1rem; right: .75rem; left: .75rem; width: auto; }
}

/* ==========================================================================
   8. PANEL DE FUGAS  ("Dónde se te está yendo la plata")
   ==========================================================================
   El resto del tablero responde "cuánto vendí". Esto responde "dónde estoy
   perdiendo", que es la pregunta que de verdad quita el sueño. Va arriba del
   todo y en soles: un porcentaje no mueve a nadie, "S/ 450 de fiado vencido"
   sí. Cada fila lleva a la pantalla donde se arregla. */
.fugas { border-color: #fde3c0; }
.fugas .card-hd { background: linear-gradient(180deg, var(--warn-50), transparent); border-bottom: none; }

.fuga {
  display: flex; align-items: center; gap: .8rem;
  padding: .7rem .1rem; text-decoration: none; color: inherit;
  border-top: 1px solid var(--gray-100); transition: background .12s;
}
.fuga:first-child { border-top: none; }
.fuga:hover { background: var(--gray-50); }
.fuga:hover .fuga-cta { color: var(--brand-600); }

.fuga-ico {
  width: 38px; height: 38px; border-radius: 10px; flex: 0 0 38px;
  display: grid; place-items: center; font-size: 1.05rem;
}
.fuga-ico > i { display: flex; align-items: center; justify-content: center; line-height: 1; }
.fuga-tit { font-size: .875rem; font-weight: 650; color: var(--text); line-height: 1.3; }
.fuga-sub {
  font-size: .765rem; color: var(--text-muted); line-height: 1.35; margin-top: .1rem;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.fuga-monto { font-size: 1.02rem; font-weight: 700; letter-spacing: -.02em; color: var(--dan-500); line-height: 1.2; }
.fuga-cta { font-size: .7rem; font-weight: 600; color: var(--text-muted); transition: color .12s; white-space: nowrap; }

@media (max-width: 575.98px) {
  .fuga { gap: .6rem; padding: .65rem .1rem; }
  .fuga-ico { width: 34px; height: 34px; flex-basis: 34px; font-size: .95rem; }
  .fuga-sub { -webkit-line-clamp: 3; }
  .fuga-monto { font-size: .92rem; }
  .fugas .card-hd { flex-wrap: wrap; }
}
