/*!
 * QUIPU Design System — COMPONENTES (q-*)
 * Version: 1.7.7  ·  Build: 2026-06-26
 * ----------------------------------------------------------------
 * Componentes base extraídos por RESPONSABILIDAD (no desde una
 * pantalla — Regla N.º 21). Contrato funcional en
 * auditoria/00-GOBIERNO/DS-COMPONENT-CANONICAL-MODEL.md.
 *
 * REGLAS:
 *  · N.º 9  — NO redefine clases base de Bootstrap/AdminLTE/plugins.
 *             Solo define el espacio de nombres propio .q-*.
 *  · N.º 12 — consume EXCLUSIVAMENTE tokens --q-* (cero hex sueltos).
 *  · Carga ÚLTIMA en la cascada. Aditivo: ninguna vista usa aún q-*,
 *    por lo que el impacto visual es CERO hasta migrar pantallas.
 *
 * Alcance v1.1.0 (4 familias base ≈ 70% del ERP):
 *   q-panel · q-btn · q-form(group/label/input/select) · q-table
 *   (q-modal/q-badge/q-amount/q-pagination llegan al migrar sus patrones)
 * ================================================================ */

/* ========================= q-panel =========================
   Responsabilidad: agrupar y nombrar una unidad funcional.
   Madurez: Beta · Owner: Design System · Depende de: — */
.q-panel{
  background:var(--q-panel-bg);
  border:var(--q-border-width) solid var(--q-panel-border);
  border-radius:var(--q-panel-radius);
  box-shadow:var(--q-shadow-card);
  overflow:hidden;
  margin-bottom:var(--q-panel-gap);   /* ritmo: panel → panel */
}
.q-panel__header{
  display:flex; align-items:center; justify-content:space-between; gap:var(--q-space-2);
  min-height:var(--q-panel-header-h);          /* altura compacta */
  padding:0 var(--q-panel-header-pad-x);        /* vertical lo centra el flex (aire equilibrado) */
  background:var(--q-panel-header-bg);
  color:var(--q-panel-header-fg);
  font-size:var(--q-font-size-md);
  font-weight:var(--q-font-weight-bold);
  text-transform:uppercase;
  letter-spacing:.04em;
}
/* Acciones dentro del header (p. ej. chevron de collapse) heredan el fg del header */
.q-panel__header a, .q-panel__header a:hover, .q-panel__header .bi{ color:inherit; text-decoration:none; }
/* pageContext — el encabezado antepone el contexto del documento (definido por la página
   en layout.php vía --q-page-context + .q-has-context). Capacidad del DS, no texto por vista.
   El contexto va atenuado para que el título propio del panel mantenga la jerarquía. */
.q-has-context .q-panel__header strong::before{ content:var(--q-page-context) " — "; font-weight:var(--q-font-weight-regular); }
/* Puente para vistas-formulario aún no migradas a q-panel (newsale/newoc/newrecipe…):
   el contexto se antepone en las cabeceras legacy de sección (.card-header > strong,
   el patrón equivalente a .q-panel__header strong) y en el título principal (.card-title).
   Hereda el color del header (blanco sobre navy), igual que cotización.
   Transitorio: al migrar la vista a q-panel, esta regla deja de aplicar sola. */
.q-has-context .card-header > strong:not(.q-no-context)::before,
.q-has-context .card-header .card-title:not(.q-no-context)::before{ content:var(--q-page-context) " — "; font-weight:var(--q-font-weight-regular); }
/* .q-no-context = opt-out: un header de sublistado/tabla que NO es sección del documento */
.q-panel__body{ padding:var(--q-panel-body-padding); }
/* ritmo: fila → fila dentro del panel (capa de compat sobre .q-campo de Bootstrap, scopeada) */
.q-panel__body .q-campo{ margin-bottom:var(--q-form-row-gap); }
.q-panel__footer{
  padding:var(--q-space-3) var(--q-space-4);
  border-top:var(--q-border-width) solid var(--q-border);
}
/* Variante soft: cabecera clara = listado/resultado */
.q-panel--soft > .q-panel__header{
  background:var(--q-surface-2);
  color:var(--q-color-primary);
}

/* ========================= q-btn =========================
   Responsabilidad: ejecutar una acción y comunicar su consecuencia.
   Madurez: Beta · Owner: Design System · Depende de: —
   Equivalencia: misma jerarquía = misma altura; lado a lado = mismo ancho. */
.q-btn{
  display:inline-flex; align-items:center; justify-content:center;
  gap:var(--q-space-2);
  height:var(--q-btn-h-m); min-width:var(--q-btn-minw-m);
  padding:0 var(--q-space-4);
  border:var(--q-border-width) solid var(--q-btn-border);
  border-radius:var(--q-btn-radius);
  font-family:var(--q-font-family);
  font-size:var(--q-font-size-md);
  font-weight:var(--q-btn-weight);
  line-height:1; white-space:nowrap; cursor:pointer;
  background:var(--q-btn-bg); color:var(--q-btn-fg);
  transition:background var(--q-duration-fast) var(--q-ease), filter var(--q-duration-fast) var(--q-ease);
}
/* Estados automáticos por color (filter, no override de fondo → conserva el color de la acción) */
.q-btn:hover{ filter:brightness(.94); }
.q-btn:focus{ outline:none; box-shadow:var(--q-focus-shadow); }
.q-btn:active{ filter:brightness(.88); }
.q-btn:disabled, .q-btn.is-disabled{ opacity:var(--q-opacity-disabled); cursor:not-allowed; }
.q-btn.is-loading{ pointer-events:none; opacity:var(--q-opacity-muted); }
/* Jerarquías por intención */
.q-btn--primary{ background:var(--q-color-primary); color:var(--q-color-on-primary); }
.q-btn--success{ background:var(--q-color-success); color:var(--q-color-on-success); }
.q-btn--danger{  background:var(--q-color-danger);  color:var(--q-color-on-danger); }
.q-btn--info{    background:var(--q-color-info);    color:var(--q-color-on-info); }
.q-btn--warning{ background:var(--q-color-warning); color:var(--q-color-on-warning); }
.q-btn--secondary, .q-btn--ghost{
  background:var(--q-surface); color:var(--q-text-1); border-color:var(--q-border);
}
.q-btn--secondary:hover, .q-btn--ghost:hover{ background:var(--q-surface-2); }
/* ── GUÍA SEMÁNTICA DE ACCIONES (Regla N.º 28): color = significado, igual en todo el ERP.
      Usar SIEMPRE el modificador de acción; foreground AA por token (nunca elegir color a mano).
      Estados (hover/active/disabled) automáticos vía .q-btn base. ── */
.q-btn--search{   background:var(--q-action-search);   color:var(--q-on-action-search); }
.q-btn--open{     background:var(--q-action-open);     color:var(--q-on-action-open); }
.q-btn--new{      background:var(--q-action-new);      color:var(--q-on-action-new); }
.q-btn--save{     background:var(--q-action-save);     color:var(--q-on-action-save); }
.q-btn--edit{     background:var(--q-action-edit);     color:var(--q-on-action-edit); }
.q-btn--delete{   background:var(--q-action-delete);   color:var(--q-on-action-delete); }
.q-btn--print{    background:var(--q-action-print);    color:var(--q-on-action-print); }
.q-btn--pdf{      background:var(--q-action-pdf);      color:var(--q-on-action-pdf); }
.q-btn--export{   background:var(--q-action-export);   color:var(--q-on-action-export); }
.q-btn--download{ background:var(--q-action-download); color:var(--q-on-action-download); }
.q-btn--refresh{  background:var(--q-action-refresh);  color:var(--q-on-action-refresh); }
.q-btn--cancel{   background:var(--q-action-cancel);   color:var(--q-on-action-cancel); }
/* Tamaños · forma como 2.º distintivo:
   M/L = barra de herramientas (radio medio, presencia). S = acción de fila (cuadrada, más redondeada). */
/* UX-BAN-004: el icono hereda `--q-font-size-md` del boton base, pensado para los
   botones grandes. En la accion de fila se queda una talla por debajo, para que el
   glifo baje con el boton en vez de llenarlo. */
.q-btn--s{ height:var(--q-btn-h-s); min-width:var(--q-btn-h-s); padding:0 var(--q-space-1); gap:var(--q-space-1); border-radius:var(--q-btn-radius-s); color:var(--q-on-action); font-size:var(--q-font-size-sm); }
.q-btn--l{ height:var(--q-btn-h-l); min-width:var(--q-btn-minw-l); padding:0 var(--q-space-6); font-size:var(--q-font-size-lg); }
/* ── Rótulo en lugar de ícono (UX-BAN-001) ───────────────────────────────────
   Tres de los botones de la bandeja -A4, XML y CDR- llevaban íconos de documento casi
   idénticos y había que interpretarlos uno por uno. Ahora llevan la palabra y NADA más:
   acompañarla de una hoja genérica volvía a acercarlos entre sí, que era el problema.

   La referencia de tamaño es el botón de la impresora. Se conservan la altura y el
   relleno de `q-btn--s`, y el texto va al mismo cuerpo que los íconos de la fila, para
   que toda la columna se lea como un solo juego. */
.q-btn--rot{ padding:0 var(--q-space-1); }
.q-btn--rot .q-btn__rot{ font-size:var(--q-font-size-xs); font-weight:700; letter-spacing:.02em; line-height:1; }

/* Solo ícono (compacto, cuadrado) — toolbars densos; ícono blanco para look vívido */
.q-btn--icon{ min-width:var(--q-btn-h-m); width:var(--q-btn-h-m); padding:0; color:var(--q-on-action); }

/* ── Guardia de contraste del contenido (ADITIVO · no cambia ningún color existente) ──────────
   Problema: cuando un .q-btn es un <a>, el legacy `a:hover/:focus/:active{color:…}` (0,1,1) le gana
   a `.q-btn--x{color}` (0,1,0) y el texto/ícono pierde contraste con el fondo.
   Solución DS (sin !important): exponer el foreground de cada variante como variable --q-btn-fg
   (mismo valor/token que ya usan) y REAFIRMARLO en todos los estados. Esta hoja carga después de
   AdminLTE, así que la regla de estado (0,1,1) vence al a:hover legacy por orden de cascada. */
.q-btn--primary { --q-btn-fg:var(--q-color-on-primary); }
.q-btn--success { --q-btn-fg:var(--q-color-on-success); }
.q-btn--danger  { --q-btn-fg:var(--q-color-on-danger); }
.q-btn--info    { --q-btn-fg:var(--q-color-on-info); }
.q-btn--warning { --q-btn-fg:var(--q-color-on-warning); }
.q-btn--secondary, .q-btn--ghost { --q-btn-fg:var(--q-text-1); }
.q-btn--search  { --q-btn-fg:var(--q-on-action-search); }
.q-btn--open    { --q-btn-fg:var(--q-on-action-open); }
.q-btn--new     { --q-btn-fg:var(--q-on-action-new); }
.q-btn--save    { --q-btn-fg:var(--q-on-action-save); }
.q-btn--edit    { --q-btn-fg:var(--q-on-action-edit); }
.q-btn--delete  { --q-btn-fg:var(--q-on-action-delete); }
.q-btn--print   { --q-btn-fg:var(--q-on-action-print); }
.q-btn--pdf     { --q-btn-fg:var(--q-on-action-pdf); }
.q-btn--export  { --q-btn-fg:var(--q-on-action-export); }
.q-btn--download{ --q-btn-fg:var(--q-on-action-download); }
.q-btn--refresh { --q-btn-fg:var(--q-on-action-refresh); }
.q-btn--cancel  { --q-btn-fg:var(--q-on-action-cancel); }
.q-btn--s, .q-btn--icon { --q-btn-fg:var(--q-on-action); }
.q-btn:hover, .q-btn:focus, .q-btn:active { color:var(--q-btn-fg); }

/* Variante SECUNDARIA "outline" (acción secundaria reutilizable en todo el ERP):
   fondo claro + borde/texto/ícono azules. El hover actúa sobre el FONDO (tinte azul) + elevación
   suave, sin oscurecer el contenido. Pareja natural de una acción primaria .q-btn--primary. */
.q-btn--outline-primary{
  background:var(--q-surface, #fff);
  color:var(--q-color-primary);
  --q-btn-fg:var(--q-color-primary);
  border-color:var(--q-outline-primary-border, #BFDBFE);
}
.q-btn--outline-primary:hover{
  background:var(--q-primary-050, #EFF6FF); filter:none;
  transform:translateY(-1px); box-shadow:0 4px 12px rgba(37,99,235,.18);
}
.q-btn--outline-primary:active{ transform:translateY(1px); filter:none; box-shadow:0 2px 6px rgba(37,99,235,.16); }

/* ===================== q-timeline ========================
   Responsabilidad: comunicar el avance de un proceso paso a paso.
   Madurez: Beta · Owner: Design System · Reutilizable (alquiler, producción, taller, logística…).
   El ESTADO (clase modificadora) define color E ícono — NO clases de color sueltas. Iconografía
   100% Bootstrap Icons (vía ::before y por punto de código: aquí no hay un elemento propio al
   que ponerle la clase bi-*). Conector = línea + flecha por CSS (sin caracteres Unicode).
   UPG-ICO-001 (05-sep-2026): los cuatro glifos venían de Font Awesome. Al retirarse esa
   librería no habrían dado ningún error: los cuatro pasos se habrían quedado mudos. */
.q-timeline{ display:flex; flex-wrap:wrap; align-items:center; gap:2px 0; }
.q-timeline__step{
  display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  font-size:12px; font-weight:700; color:var(--q-text-2);
}
.q-timeline__step::before{
  font-family:"bootstrap-icons"; font-weight:normal; font-size:13px; line-height:1;
  display:inline-block; width:1em; text-align:center;
}
/* Estados: color (token DS) + ícono (glifo de Bootstrap Icons), ambos derivados de la clase */
.q-timeline__step--pending   { color:var(--q-text-3, #94A3B8); }
.q-timeline__step--pending::before   { content:"\f28a"; }                  /* bi-circle (contorno) */
.q-timeline__step--completed { color:var(--q-color-success); }
.q-timeline__step--completed::before { content:"\f26a"; }                  /* bi-check-circle-fill */
.q-timeline__step--progress  { color:var(--q-color-warning); }
.q-timeline__step--progress::before  { content:"\f288"; }                  /* bi-circle-half */
.q-timeline__step--cancelled { color:var(--q-color-danger); }
.q-timeline__step--cancelled::before { content:"\f622"; }                  /* bi-x-circle-fill */
/* Conector: línea horizontal + punta de flecha, íntegramente en CSS */
.q-timeline__link{
  flex:0 0 auto; align-self:center; width:26px; height:2px;
  background:var(--q-border, #CBD5E1); margin:0 8px; position:relative;
}
.q-timeline__link::after{
  content:""; position:absolute; right:-1px; top:50%; transform:translateY(-50%);
  border-left:6px solid var(--q-border, #CBD5E1);
  border-top:4px solid transparent; border-bottom:4px solid transparent;
}
@media (max-width:640px){
  .q-timeline__link{ width:14px; margin:0 5px; }
  .q-timeline__step{ font-size:11.5px; }
}

/* ======================= q-badge =========================
   Etiqueta de estado compacta (píldora). Color = significado (por token DS). Reutilizable
   en bandejas/tablas de cualquier módulo. NO usar texto plano para estados. */
.q-badge{
  display:inline-flex; align-items:center; gap:5px;
  font-size:11px; font-weight:800; line-height:1; white-space:nowrap;
  padding:4px 10px; border-radius:999px; text-transform:uppercase; letter-spacing:.02em;
}
/* Dos líneas (UX-BAN-002): «Aceptado por SUNAT» en una sola línea obligaba a una
   columna desproporcionada para lo que dice. Partido en dos, ocupa la mitad de ancho
   y se lee igual. */
.q-badge--2l{ display:inline-block; white-space:normal; line-height:1.22; text-align:center; }

.q-badge--info{    background:var(--q-info-050,#EFF6FF);    color:var(--q-info-700,#1D4ED8); }
.q-badge--success{ background:var(--q-success-050,#ECFDF5); color:var(--q-success-700,#047857); }
.q-badge--danger{  background:var(--q-danger-050,#FEF2F2);  color:var(--q-danger-700,#B91C1C); }
.q-badge--warning{ background:var(--q-warning-050,#FFFBEB); color:var(--q-warning-700,#B45309); }
.q-badge--neutral{ background:var(--q-neutral-100,#F1F5F9); color:var(--q-neutral-600,#475569); }

/* ======================= q-form ==========================
   Responsabilidad: capturar un dato y etiquetarlo legible.
   Madurez: Beta · Owner: Design System · Depende de: — */
.q-form-group{ margin-bottom:var(--q-space-3); }
.q-label{
  display:block; margin-bottom:var(--q-space-1);
  font-size:var(--q-font-size-sm); color:var(--q-text-2);
}
.q-input, .q-select, .q-textarea{
  width:100%; box-sizing:border-box;
  padding:0 var(--q-space-2);
  border:var(--q-border-width) solid var(--q-input-border);
  border-radius:var(--q-input-radius);
  font-family:var(--q-font-family); font-size:var(--q-font-size-md);
  color:var(--q-text-1); background:var(--q-surface);
}
.q-input, .q-select{ height:var(--q-input-h); }
.q-textarea{ height:auto; min-height:calc(var(--q-input-h) * 2); padding:var(--q-space-2); }
/* ============ FOCO OFICIAL DEL ERP (único · visible · color del DS) ============
   border + inset = borde nítido de 2px en el color de foco, sin glow ni layout shift.
   Idéntico en q-input, q-select, Select2 y DataTables (adapters). */
.q-input:focus, .q-select:focus, .q-textarea:focus{
  outline:none;
  border-color:var(--q-input-focus);
  box-shadow:var(--q-focus-shadow);
}
/* Mata el outline del navegador en TODO control de bandeja/formulario DS (sin tocar el foco DS) */
.q-panel input:focus, .q-panel select:focus, .q-panel textarea:focus,
.q-panel .select2-selection:focus, .q-panel .select2-search__field:focus,
.q-panel .form-control:focus,
.q-panel .dataTables_filter input:focus, .q-panel .dataTables_length select:focus{ outline:none !important; }
/* Box-shadow HEREDADO solo en controles NO-DS (Bootstrap / buscador interno de Select2): fuera */
.q-panel .form-control:focus, .q-panel .select2-search__field:focus{ box-shadow:none !important; }
.q-input:disabled, .q-select:disabled, .q-textarea:disabled{
  background:var(--q-surface-2); opacity:var(--q-opacity-muted);
}
/* Estado inválido */
.q-form-group.is-invalid .q-input,
.q-form-group.is-invalid .q-select{ border-color:var(--q-color-danger); }

/* ======================= q-table =========================
   Responsabilidad: presentar datos tabulares y resaltar totales.
   Madurez: Beta · Owner: Design System · Depende de: q-btn · q-badge · q-pagination */
.q-table{ width:100%; border-collapse:collapse; font-size:var(--q-font-size-md); }
.q-table thead th{
  background:var(--q-table-header-bg); color:var(--q-table-header-fg);
  text-align:left; padding:var(--q-space-2) var(--q-space-3);
  font-size:var(--q-font-size-xs); font-weight:var(--q-font-weight-bold);
  text-transform:uppercase; letter-spacing:.03em;
  border-bottom:2px solid var(--q-table-border);
}
/* Bandeja (DataTables): cabecera tematizable por token + títulos centrados */
.q-table.datatable thead th{
  background:var(--q-table-bandeja-header-bg); color:var(--q-table-bandeja-header-fg);
  text-align:center; border-bottom:2px solid var(--q-table-bandeja-header-accent);
}
.q-table tbody td{ padding:var(--q-table-row-py) var(--q-space-3); line-height:var(--q-line-height-tight); border-top:var(--q-border-width) solid var(--q-table-border); }
.q-table tbody tr:hover{ background:var(--q-table-hover); }
/* TOTAL protagonista — cierra visualmente la tabla (línea de acento + énfasis) */
.q-table tfoot td, .q-table__total{
  background:var(--q-surface-2); color:var(--q-text-1);
  padding:var(--q-space-2) var(--q-space-3);
  border-top:3px solid var(--q-table-bandeja-header-accent);
  font-weight:var(--q-font-weight-bold);
}
/* Acción de fila = q-btn tamaño S (úsese: class="q-btn q-btn--s ...") · separación mínima (2px) */
.q-table-action{ display:inline-flex; gap:2px; flex-wrap:nowrap; align-items:center; vertical-align:middle; }
/* UX-BAN-006 · la especificidad tiene que ganarle a la regla de celda de más abajo.
   Escrito como `.q-table-action .q-btn{margin:0 1px}` no servía de nada: dentro de una
   tabla manda `.q-table tbody td .q-btn--s{margin:2px}`, que puntua más alto, y el
   agrupador quedaba decorativo — nadie lo usaba. El `gap` ya separa; los márgenes sobran. */
.q-table tbody td .q-table-action .q-btn{ margin:0; }
/* Variante en rejilla: los botones se acomodan en filas de N en vez de una tira
   larga. Es un cambio de forma, no de contenido — la columna deja de competir en
   ancho con las que llevan texto y crece a lo alto, que es lo que sobra en una fila.
   `auto` en las columnas y no `1fr`: los botones son cuadrados de tamaño fijo y
   estirarlos para rellenar la celda los deformaría. */
.q-table-action--rejilla{ display:inline-grid; grid-template-columns:repeat(3, auto); justify-content:start; }
/* Columna de acciones. Quien decide el reparto en filas es la rejilla del agrupador,
   no el `nowrap`: éste sólo evita que se parta el rótulo de la cabecera. El
   `text-align` reemplaza al style en línea que traía la celda. El ancho se sigue
   declarando en el <th>: DataTables lo lee al construirse y no vuelve a mirar la
   hoja de estilos — cambiarlo por CSS no tiene efecto. */
.q-table th.q-col-acciones, .q-table td.q-col-acciones{ white-space:nowrap; text-align:left; }
/* Separación de botones de acción directamente en una celda (sin wrapper) — centralizado, sin inline en vistas */
.q-table tbody td .q-btn--s{ margin:2px; }
/* Acciones dentro de celda (con o sin texto) = look vívido: texto/ícono blanco — igual criterio que q-btn--s */
.q-table tbody td .q-btn{ color:var(--q-on-action); }

/* ===================== LAYOUT / FORM HELPERS =====================
   Piezas de composición de formularios (antes en el pilot). Solo tokens. */

/* q-form-canvas — lienzo del formulario: fija el ritmo navbar → primer panel.
   Reconcilia el gap deseado contra el padding del .content de AdminLTE (15px). */
.q-form-canvas{ margin-top:calc(var(--q-layout-navbar-gap) - 15px); }

/* q-amount — valor monetario clave destacado */
.q-amount{ font-weight:var(--q-font-weight-bold); color:var(--q-color-primary); font-size:var(--q-font-size-md); }

/* q-toolbar — barra de Bandeja: filtros + acciones en UNA fila (acciones a la derecha) */
.q-toolbar{ display:flex; flex-wrap:wrap; align-items:flex-end; gap:10px; margin:0 0 var(--q-space-2); }
.q-toolbar__field{ flex:1 1 150px; min-width:140px; }
.q-toolbar__field--wide{ flex:2 1 220px; }
/* `--wide` crece al doble que un campo normal, y eso funciona mientras COMPITA con
   otros campos en su fila. Solo en la suya no compite con nadie —las acciones se van a
   la derecha con `margin-left:auto`— y se lleva el ancho entero: en la bandeja de
   cotizaciones, Cliente ocupaba los ~900 px de la segunda línea mientras los seis
   filtros de arriba se apretaban a 150 px cada uno.
   `--half` mantiene «más ancho que los demás» pero con techo: no crece, y su ancho de
   partida es la mitad de lo que ocupaba. Sigue encogiendo en pantallas estrechas. */
.q-toolbar__field--half{ flex:0 1 450px; }
/* Salto de fila dentro de la barra: un item que ocupa el ancho completo y no
   pinta nada. Lo que venga detrás empieza en una línea nueva. */
.q-toolbar__break{ flex:0 0 100%; height:0; margin:0; padding:0; }
.q-toolbar__actions{ margin-left:auto; display:flex; flex-wrap:wrap; justify-content:flex-end; align-items:flex-end; gap:var(--q-space-2); }
/* Separador entre grupos de acciones por intención (Buscar/Limpiar | Nuevo/Descargar).
   Buscar y Limpiar operan sobre el FILTRO; Nuevo y Descargar, sobre los DATOS. Pegados
   en una tira se leen como variantes de lo mismo, y el vecino de Limpiar acaba pulsado
   por error. Una línea fina y un poco de aire dicen que ahí cambia el tema.

   UPG-ICO-003 (05-sep-2026): `flex:0 0 auto` sólo hace algo si el padre es flex. Fuera
   de `.q-toolbar__actions` el <span> se quedaba en `display:inline`, y en inline el
   `width`/`height` no se aplican: el separador NO SE VEÍA, sin error ni hueco. Con
   `inline-block` funciona en los dos sitios — dentro del toolbar flex y dentro de un
   `col-md-*` corriente, que es como está la barra en la mayoría de las vistas. */
.q-toolbar__sep{
  display:inline-block; vertical-align:middle;   /* fuera de un contenedor flex */
  flex:0 0 auto; align-self:center;              /* dentro de .q-toolbar__actions */
  width:1px; height:24px; background:var(--q-border);
  margin:0 var(--q-space-2);
}
/* Botones del toolbar: ancho según contenido (compactos) + texto/ícono SIEMPRE blanco
   (look vívido uniforme solicitado; nota: blanco sobre verde/naranja queda bajo AA por decisión visual). */
.q-toolbar__actions .q-btn{ min-width:auto; padding:0 var(--q-space-3); color:var(--q-on-action); }

/* q-form-actions — pie de formulario: acciones principales centradas con separación */
.q-form-actions{ display:flex; flex-wrap:wrap; justify-content:center; align-items:center; gap:var(--q-space-3); padding:var(--q-space-4) 0; }

/* q-capture-row — toolbar de captura de alta densidad (Producto absorbe, numéricos fijos) */
.q-capture-row{ display:flex; flex-wrap:wrap; align-items:flex-end; gap:10px; margin-left:0 !important; margin-right:0 !important; }   /* = newsale: neutraliza el -15px de .q-form-h .q-campo para alinear con el panel inferior */
.q-capture-row > div{ float:none !important; padding:0 !important; margin:0 !important; width:auto; }
.q-capture-row > div .q-input, .q-capture-row > div .q-select{ max-width:none; }
.q-capture-row__grow{ flex:1 1 240px; min-width:240px; }   /* Producto absorbe el sobrante */
/* Anchos del patrón Detalle (= newsale): Unidad · Precio · Precio · Cantidad · Acción */
.q-capture-row > div:nth-child(2){ flex:0 0 140px; width:140px; }   /* Unidad: 140px para mostrar completa la unidad comercial (CR-001: "PAQUETE (PK)"). Producto (__grow) absorbe el sobrante; los demás fijos no se desplazan. */
.q-capture-row > div:nth-child(3){ flex:0 0 120px; width:120px; }
.q-capture-row > div:nth-child(4){ flex:0 0 120px; width:120px; }
.q-capture-row > div:nth-child(5){ flex:0 0 90px;  width:90px; }
.q-capture-row > div:nth-child(6){ flex:0 0 auto; }   /* Agregar: ancho propio, alineado al fondo */

/* ===================== ADAPTERS (plugins) =====================
   Regla N.º 24: los plugins NO forman parte del DS. El DS certifica
   ADAPTERS que mapean el DOM del plugin al contrato de un q-*,
   consumiendo SOLO tokens.  Patrón: plugin -> q-*-adapter -> q-* -> tokens.
   Scopeados (opt-in) para migración controlada por pantalla.
   Futuros: q-datepicker-adapter, q-autocomplete-adapter, q-datatable-adapter…
   ============================================================== */

/* Select2 v4 -> q-select. Activo con .q-select-adapter (opt-in) O dentro de cualquier .q-panel
   (pantallas migradas) → foco/altura/borde únicos del DS; elimina el borde negro nativo. */
.q-select-adapter .select2-container,
.q-panel .select2-container{ width:100% !important; }
.q-select-adapter .select2-container--default .select2-selection--single,
.q-panel .select2-container--default .select2-selection--single{
  height:var(--q-input-h);
  border:var(--q-border-width) solid var(--q-input-border);
  border-radius:var(--q-input-radius);
  background:var(--q-surface);
}
.q-select-adapter .select2-container--default .select2-selection--single .select2-selection__rendered,
.q-panel .select2-container--default .select2-selection--single .select2-selection__rendered{
  line-height:calc(var(--q-input-h) - 2px);
  padding-left:var(--q-space-2);
  color:var(--q-text-1);
  font-size:var(--q-font-size-md);
}
.q-select-adapter .select2-container--default .select2-selection--single .select2-selection__arrow,
.q-panel .select2-container--default .select2-selection--single .select2-selection__arrow{
  height:calc(var(--q-input-h) - 2px);
}
.q-select-adapter .select2-container--default.select2-container--focus .select2-selection--single,
.q-select-adapter .select2-container--default.select2-container--open .select2-selection--single,
.q-panel .select2-container--default.select2-container--focus .select2-selection--single,
.q-panel .select2-container--default.select2-container--open .select2-selection--single{
  border-color:var(--q-input-focus) !important;          /* vence el rojo de skin-peru */
  box-shadow:var(--q-focus-shadow) !important;
}
/* Dropdown Select2 (se porta al <body>, fuera de .q-panel → regla global):
   opción resaltada/seleccionada en AZUL del DS, no el rojo de skin-peru. UN solo color de selección. */
.select2-container--default .select2-results__option--highlighted[aria-selected]{
  background-color:var(--q-color-primary) !important; color:var(--q-color-on-primary) !important;
}
.select2-container--default .select2-results__option[aria-selected="true"]{
  background-color:var(--q-color-primary-light) !important; color:var(--q-text-1) !important;
}
/* Quita el outline nativo del control Select2 (causa del foco "distorsionado") */
.q-select-adapter .select2-selection:focus,
.q-panel .select2-selection:focus,
.q-panel .select2-selection--single:focus{ outline:none; }


/* ════════════════════════════════════════════════════════════════
   §RWD-Q · RESPONSIVE MOVIL de formularios del Design System (q-*)
   ----------------------------------------------------------------
   modern.css solo da responsive a las vistas legacy (.card-body
   .q-form-h). Las vistas q-* (COTIZACION / newquote) usan
   .q-panel__body y quedaban con la rejilla Bootstrap cruda en el
   telefono. Estrategia (igual que el motor legacy):
     - <=767px : el form-group pasa a flex; por defecto 1 columna.
     - 576-767 : campos cortos a 2 columnas (tablet chica).
     - <=575px : 1 columna (telefono), sin texto cortado.
   El escritorio (>=768px) NO se altera.
   ════════════════════════════════════════════════════════════════ */
@media (max-width: 767px) {
  .content .q-panel__body .q-campo {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: flex-end !important;
    gap: 8px !important;
    margin-left: 0 !important;
    margin-right: 0 !important;
    margin-bottom: 10px !important;
  }
  .content .q-panel__body .q-campo > [class*="col-"] {
    float: none !important;
    padding-left: 0 !important;
    padding-right: 0 !important;
    flex: 1 1 100% !important;
    max-width: 100% !important;
    min-width: 0 !important;
  }
  .content .q-panel__body .q-campo > [style*="padding-top"] {
    padding-top: 0 !important;
    flex: 1 1 100% !important;
    max-width: 100% !important;
  }
  .content .q-panel__body .q-campo > [style*="padding-top"] > .q-btn,
  .content .q-panel__body .q-campo > [style*="padding-top"] > .btn {
    width: 100% !important;
    justify-content: center !important;
  }
  .content .q-panel__body .q-campo .q-input,
  .content .q-panel__body .q-campo .q-select,
  .content .q-panel__body .q-campo .select2-container { max-width: 100% !important; }
  .content .q-panel__body { padding-left: 12px !important; padding-right: 12px !important; }
}
@media (min-width: 576px) and (max-width: 767px) {
  .content .q-panel__body .q-campo > .col-md-1,
  .content .q-panel__body .q-campo > .col-md-2,
  .content .q-panel__body .q-campo > .col-md-3 {
    flex: 1 1 calc(50% - 8px) !important;
    max-width: calc(50% - 8px) !important;
  }
}
