/* ============================================================
   MIX Gestión · mix-polish.css — CAPA DE PULIDO (aditiva)
   ------------------------------------------------------------
   Se carga DESPUÉS de mix-ds.css / atelier.css (y mobile.css).
   Solo presentación: no cambia lógica, datos ni comportamiento.
   Revertir = quitar el <link> (no hay nada más que deshacer).

   Reglas de la capa
   · Todo con tokens del sistema (--radius*, --accent, --border…): respeta
     los 11 temas, data-radius, data-density y el modo claro/oscuro.
   · Movimiento SOLO con transform / opacity / color / background / border /
     box-shadow estático. Cero blur, cero filter, cero animar tamaño.
   · prefers-reduced-motion y data-motion="off" lo apagan todo.
   ============================================================ */

/* ─────────────── 0 · TOKENS ─────────────── */
:root {
  /* movimiento */
  --mp-ease: cubic-bezier(.2, .7, .2, 1);          /* salida suave */
  --mp-ease-io: cubic-bezier(.4, 0, .2, 1);
  --mp-d1: 110ms;                                   /* hover, foco, press */
  --mp-d2: 170ms;                                   /* popovers, toasts */
  --mp-d3: 240ms;                                   /* modales, paneles */

  /* sombras (claro). Escala corta: 1 reposo · 2 hover · pop flotantes */
  --mp-sh-rgb: 20 20 30;
  --mp-sh-1: 0 1px 2px rgb(var(--mp-sh-rgb) / .05);
  --mp-sh-2: 0 2px 8px rgb(var(--mp-sh-rgb) / .08), 0 1px 2px rgb(var(--mp-sh-rgb) / .05);
  --mp-sh-pop: 0 12px 32px rgb(var(--mp-sh-rgb) / .16), 0 2px 6px rgb(var(--mp-sh-rgb) / .08);
  --mp-scrim: rgb(12 12 18 / .5);                   /* sin blur: fondo plano */

  /* radios semánticos (siguen a data-radius) */
  --mp-r-ctl: var(--radius-sm);                     /* inputs, botones, chips */
  --mp-r-card: var(--radius);                       /* cards, tablas, KPIs */
  --mp-r-pop: var(--radius-lg);                     /* modales, paneles, menús */

  /* texto terciario con contraste AA para 11px (--text-3 solo da 3.2:1 sobre blanco) */
  --mp-text-3: color-mix(in srgb, var(--text-3) 45%, var(--text-muted));

  --mp-ring: 0 0 0 3px color-mix(in srgb, var(--accent) 22%, transparent);
  --mp-invalid-ring: 0 0 0 3px color-mix(in srgb, var(--danger) 20%, transparent);
}
/* temas oscuros: la sombra no se ve, se separa con borde; las flotantes sí llevan */
html:is([data-theme="noche"], [data-theme="dark"], [data-theme="graphite"], [data-theme="forest"], [data-theme="indigo"], [data-theme="atelier-noche"]) {
  --mp-sh-rgb: 0 0 0;
  --mp-sh-1: none;
  --mp-sh-2: 0 0 0 1px rgb(255 255 255 / .03), 0 4px 14px rgb(0 0 0 / .35);
  --mp-sh-pop: 0 16px 40px rgb(0 0 0 / .55), 0 0 0 1px rgb(255 255 255 / .04);
  --mp-scrim: rgb(0 0 0 / .62);
}
/* sin movimiento: preferencia del sistema o del panel «Estilo» */
@media (prefers-reduced-motion: reduce) {
  :root { --mp-d1: 0ms; --mp-d2: 0ms; --mp-d3: 0ms; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
}
html[data-motion="off"] { --mp-d1: 0ms; --mp-d2: 0ms; --mp-d3: 0ms; }

@keyframes mp-fade { from { opacity: 0; } }
@keyframes mp-pop { from { opacity: 0; transform: translateY(8px) scale(.985); } }
@keyframes mp-drop { from { opacity: 0; transform: translateY(-4px); } }
@keyframes mp-rise { from { opacity: 0; transform: translateY(14px); } }
@keyframes mp-spin { to { transform: rotate(360deg); } }
@keyframes mp-shimmer { to { transform: translateX(100%); } }

/* ─────────────── 1 · CAMBIO DE PÁGINA ───────────────
   Fundido de 120 ms entre pantallas (View Transitions entre documentos;
   Chrome/Edge 126+, el resto navega normal). Solo el root: NO se nombran
   sidebar/topbar porque un view-transition-name ancla los position:fixed
   hijos (mismo problema que tuvo `.content{animation:mixIn}` en 08/2026). */
@media screen and (prefers-reduced-motion: no-preference) {
  @view-transition { navigation: auto; }
  ::view-transition-old(root) { animation: mp-fade-out 90ms linear both; }
  ::view-transition-new(root) { animation: mp-fade-in 150ms var(--mp-ease) both; }
}
@keyframes mp-fade-in { from { opacity: 0; } }
@keyframes mp-fade-out { to { opacity: 0; } }

/* ─────────────── 2 · FOCO UNIFICADO ───────────────
   mix-ds ponía border-radius:2px al enfocar (el control «se cuadraba» al
   recibir foco). Se devuelve el radio propio y se agrega un filete oscuro
   para que el amarillo se vea también sobre fondo blanco. */
:where(a, button, [tabindex], summary):focus-visible {
  outline: 2px solid var(--mix-amarillo); outline-offset: 2px;
  box-shadow: 0 0 0 1px color-mix(in srgb, var(--text) 55%, transparent);
}
a:focus-visible { border-radius: var(--radius-xs); }
button:focus-visible, .btn:focus-visible, select:focus-visible { border-radius: var(--mp-r-ctl); }
input:focus-visible, textarea:focus-visible { border-radius: var(--mp-r-ctl); }
.card:focus-visible, .kpi-c:focus-visible { border-radius: var(--mp-r-card); }
.sidebar-menu a:focus-visible { outline-offset: -2px; box-shadow: none; }

/* ─────────────── 3 · BOTONES ─────────────── */
button, .btn {
  border-radius: var(--mp-r-ctl);
  transition: background-color var(--mp-d1) var(--mp-ease), border-color var(--mp-d1) var(--mp-ease),
              color var(--mp-d1) var(--mp-ease), box-shadow var(--mp-d1) var(--mp-ease), scale var(--mp-d1) var(--mp-ease);
}
button:active:not(:disabled), .btn:active:not(.disabled) { scale: .975; }
button:disabled, .btn:disabled, .btn.disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; box-shadow: none; pointer-events: none; }
.btn-primary:hover, .btn.primary:hover, .btn-save:hover { box-shadow: var(--mp-sh-2); }
.btn-primary:active, .btn.primary:active, .btn-save:active { box-shadow: none; }

/* <a class="btn-sec"> sin .btn (18 casos reales, ver feedback 15/09): le da caja.
   :where() = especificidad 0, así .btn-sm y cualquier padding propio siguen ganando. */
:where(a.btn-sec, a.btn-secondary, a.btn-primary, a.btn-ghost, a.btn-danger, a.btn-ok, a.btn-success, a.btn-warn, a.btn-exp, a.btn-cancel, a.btn-save, a.btn-del, a.btn-action):not(.btn) {
  font-family: inherit; cursor: pointer; font-size: .8125rem; font-weight: 500; line-height: 1;
  padding: 0 12px; min-height: var(--input-h); display: inline-flex; align-items: center; justify-content: center;
  gap: 6px; border-radius: var(--mp-r-ctl); white-space: nowrap; text-decoration: none; vertical-align: middle;
}

/* estado «cargando» (opcional, se agrega la clase o aria-busy desde donde ya se deshabilita el botón) */
.btn.is-loading, button.is-loading, button[aria-busy="true"], .btn[aria-busy="true"] {
  position: relative; color: transparent !important; pointer-events: none;
}
.btn.is-loading::after, button.is-loading::after, button[aria-busy="true"]::after, .btn[aria-busy="true"]::after {
  content: ""; position: absolute; width: 14px; height: 14px; left: calc(50% - 7px); top: calc(50% - 7px);
  border: 2px solid var(--text-muted); border-right-color: transparent; border-radius: 50%; animation: mp-spin .7s linear infinite;
}
.btn-primary.is-loading::after, .btn-primary[aria-busy="true"]::after { border-color: var(--accent-text); border-right-color: transparent; }

/* botones de icono de la barra: mismo timing */
.menu-colapsar, .hamburger-btn, .topbar .mix-kbtn, .topbar .mix-prefs-btn, .topbar .btn-top, .mix-user-btn, .modal-close, .ar-close, .aviso-x, .notif-x {
  transition: background-color var(--mp-d1) var(--mp-ease), color var(--mp-d1) var(--mp-ease), border-color var(--mp-d1) var(--mp-ease), transform var(--mp-d1) var(--mp-ease);
}

/* ─────────────── 4 · FORMULARIOS ─────────────── */
input, select, textarea {
  border-radius: var(--mp-r-ctl);
  transition: border-color var(--mp-d1) var(--mp-ease), box-shadow var(--mp-d1) var(--mp-ease), background-color var(--mp-d1) var(--mp-ease);
}
input:focus, select:focus, textarea:focus { box-shadow: var(--mp-ring) !important; }
input[readonly]:not([type="checkbox"]):not([type="radio"]), textarea[readonly] { background: var(--surface-2); color: var(--text-muted); }
input:disabled, select:disabled, textarea:disabled, fieldset:disabled input { opacity: .55; cursor: not-allowed; background: var(--surface-2); }
label:has(> input:disabled), label:has(> select:disabled) { color: var(--mp-text-3); cursor: not-allowed; }

/* error: nativo tras interactuar (:user-invalid) o marcado por la pantalla (.is-invalid / aria-invalid) */
/* :user-invalid solo marca valores cargados e invalidos (email/pattern/rango): un required VACIO no se pinta de rojo */
input:user-invalid:not(:required), select:user-invalid:not(:required), textarea:user-invalid:not(:required),
input:user-invalid:required:not(:placeholder-shown), textarea:user-invalid:required:not(:placeholder-shown),
input.is-invalid, select.is-invalid, textarea.is-invalid, [aria-invalid="true"] {
  border-color: var(--danger); background-color: color-mix(in srgb, var(--danger-bg) 55%, var(--bg-input));
}
input:user-invalid:not(:required):focus, select:user-invalid:not(:required):focus, textarea:user-invalid:not(:required):focus,
input:user-invalid:required:not(:placeholder-shown):focus, textarea:user-invalid:required:not(:placeholder-shown):focus,
input.is-invalid:focus, select.is-invalid:focus, textarea.is-invalid:focus, [aria-invalid="true"]:focus {
  border-color: var(--danger) !important; box-shadow: var(--mp-invalid-ring) !important;
}
.field-hint { display: block; margin-top: 4px; font-size: var(--t-micro); color: var(--mp-text-3); }
.field-error { display: block; margin-top: 4px; font-size: var(--t-micro); color: var(--danger); font-weight: 500; }
::placeholder { color: var(--mp-text-3); opacity: .85; }
input[type="file"]::file-selector-button {
  font: inherit; font-size: var(--t-dato); font-weight: 500; margin-right: 10px; padding: 4px 10px; cursor: pointer;
  border: 1px solid var(--border-strong); border-radius: var(--radius-xs); background: var(--surface); color: var(--text);
  transition: background-color var(--mp-d1) var(--mp-ease);
}
input[type="file"]::file-selector-button:hover { background: var(--surface-hover); }
/* autocompletado de Chrome: sin el fondo amarillo/azul que rompe el modo oscuro */
input:-webkit-autofill, select:-webkit-autofill, textarea:-webkit-autofill {
  -webkit-text-fill-color: var(--text); caret-color: var(--text); transition: background-color 9999s ease-out 0s;
}
input[type="checkbox"], input[type="radio"] { cursor: pointer; transition: scale var(--mp-d1) var(--mp-ease); }
input[type="checkbox"]:active, input[type="radio"]:active { scale: .88; }
input[type="checkbox"]:disabled, input[type="radio"]:disabled { cursor: not-allowed; }
.filtros label, .filtros-d label, .toolbar label { color: var(--mp-text-3); }
.mix-switch { transition: background-color var(--mp-d2) var(--mp-ease); }
.mix-switch::after { transition: transform var(--mp-d2) var(--mp-ease); }

/* ─────────────── 5 · SUPERFICIES ─────────────── */
.card, .dash-card, .es-card, .panel, .box, .socio-card, .card-p, .kpi, .kpi-c, .kpi-card, .stat {
  border-radius: var(--mp-r-card); box-shadow: var(--mp-sh-1);
  transition: background-color var(--mp-d1) var(--mp-ease), border-color var(--mp-d1) var(--mp-ease), box-shadow var(--mp-d2) var(--mp-ease), translate var(--mp-d2) var(--mp-ease);
}
/* los de estado (.kpi.warn…) conservan su inset: tienen mayor especificidad que lo de arriba */
a > .card:hover, a > .kpi-c:hover, .card[onclick]:hover, .kpi-c[onclick]:hover, .card.click:hover, a > .kpi:hover {
  background: var(--surface-hover); border-color: var(--border-strong); box-shadow: var(--mp-sh-2); translate: 0 -1px;
}
a > .card:active, .card[onclick]:active, .card.click:active, a > .kpi-c:active { translate: 0 0; box-shadow: var(--mp-sh-1); }
.kpi .l, .kpi-c small, .kpi small, .kpi-label, .stat .l, .cifra-rotulo { color: var(--mp-text-3); }
.cifra-pie, .pantalla-fecha { color: var(--text-muted); }
.table-wrap, .tabla-wrap, .tbl-wrap { border-radius: var(--mp-r-card); box-shadow: var(--mp-sh-1); }
.bar, .bar > i, .progress, .progress > i { transition: width var(--mp-d3) var(--mp-ease); }
hr { border-top-color: var(--border); }

/* ─────────────── 6 · TABLAS ─────────────── */
@media screen { thead th { color: var(--mp-text-3); } }
tbody td { transition: background-color var(--mp-d1) linear; }
tbody tr[onclick], tbody tr.click, tbody tr[data-href], tbody tr.clickable { cursor: pointer; }
tbody tr:focus-within td { background: var(--surface-hover); }
tbody tr:active td { background: var(--surface-2); }
.table-wrap:focus-visible { outline-offset: -2px; }
td.vacio, td.empty, td .sin-datos { color: var(--text-muted); text-align: center; padding: var(--e5) var(--e3); }
.pagination a, .pagination span, .paginado a, .paginado span { transition: background-color var(--mp-d1) var(--mp-ease), color var(--mp-d1) var(--mp-ease); }
/* tablas anchas dentro de un wrap: el primer scroll muestra que hay más (sombra lateral solo con transform/opacity no aplica; se deja el scroll nativo) */
.table-wrap { overscroll-behavior-x: contain; }

/* ─────────────── 7 · BADGES / CHIPS / PESTAÑAS ─────────────── */
.badge, .tag, .pill { border-radius: var(--radius-xs); }
.chips a, .chips button, .chip, .ar-pill, .seg > a, .seg > button, .tabs a, .tabs button, .subnav a, .pestanas a, .pestanas button {
  transition: background-color var(--mp-d1) var(--mp-ease), color var(--mp-d1) var(--mp-ease), border-color var(--mp-d1) var(--mp-ease), box-shadow var(--mp-d1) var(--mp-ease);
}
.seg { border-radius: var(--mp-r-ctl); }
.seg > a, .seg > button { border-radius: calc(var(--mp-r-ctl) - 2px); }
.tabs a, .tabs button, .subnav a, .pestanas a, .pestanas button { border-radius: var(--mp-r-ctl) var(--mp-r-ctl) 0 0; }
.tabs a:hover, .tabs button:hover, .subnav a:hover, .pestanas a:hover { background: var(--surface-2); }
.tabs a.active, .subnav a.active, .pestanas a.active, .tabs [aria-selected="true"] { background: transparent; }
.chip:active, .chips a:active, .chips button:active { scale: .97; }

/* ─────────────── 8 · AVISOS / VACÍOS / ERROR ─────────────── */
.aviso, .alert, .alerta { border-radius: var(--mp-r-ctl); animation: mp-drop var(--mp-d2) var(--mp-ease) backwards; }
.aviso-x { transition: background-color var(--mp-d1) var(--mp-ease), color var(--mp-d1) var(--mp-ease); }
.empty-state, .sin-datos, .vacio { border-radius: var(--mp-r-card); background: color-mix(in srgb, var(--surface-2) 45%, transparent); }
.empty-state svg, .vacio svg { color: var(--mp-text-3); }
.error, .form-error { border-radius: var(--mp-r-ctl); }
.error[role="alert"], .form-error[role="alert"] { animation: mp-drop var(--mp-d2) var(--mp-ease) backwards; }
.ok-msg, .form-ok { border-radius: var(--mp-r-ctl); }

/* ─────────────── 9 · CARGANDO (skeleton) ───────────────
   Brillo que barre la pieza con transform (compuesto en GPU). Con
   movimiento reducido queda el tono plano. */
.skeleton, .mixfx-skel { animation: none; border-radius: var(--radius-xs); }
.skeleton::after, .mixfx-skel::after {
  content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 7%, transparent), transparent);
  animation: mp-shimmer 1.3s var(--mp-ease-io) infinite;
}
.skel-line { display: block; height: 12px; margin: 8px 0; border-radius: var(--radius-xs); background: var(--surface-2); position: relative; overflow: hidden; }
.skel-line::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 7%, transparent), transparent); animation: mp-shimmer 1.3s var(--mp-ease-io) infinite; }
.skel-line.w-40 { width: 40%; } .skel-line.w-60 { width: 60%; } .skel-line.w-80 { width: 80%; }
.skel-kpi { height: 74px; border-radius: var(--mp-r-card); background: var(--surface-2); position: relative; overflow: hidden; }
.skel-kpi::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%); background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--text) 7%, transparent), transparent); animation: mp-shimmer 1.3s var(--mp-ease-io) infinite; }
.mix-spinner { display: inline-block; width: 16px; height: 16px; border: 2px solid var(--border-strong); border-top-color: var(--accent); border-radius: 50%; animation: mp-spin .7s linear infinite; vertical-align: middle; }
.mix-loader { transition: transform var(--mp-d3) var(--mp-ease), opacity var(--mp-d3) linear; }

/* ─────────────── 10 · MODALES, MENÚS, TOASTS ───────────────
   Aparecen con opacity+transform (el display none→flex dispara la animación,
   sirve tanto para .show/.open como para style.display='flex' inline).
   Se saca el backdrop-filter:blur (costaba GPU en las cajas): fondo plano. */
.modal-bg, .modal-overlay, .ar-modal, .overlay, .mix-cmdk, .sidebar-overlay, .kbd-help-overlay,
html:is([data-theme="atelier"],[data-theme="atelier-noche"]) .atelier-launcher {
  background: var(--mp-scrim); -webkit-backdrop-filter: none; backdrop-filter: none;
}
dialog::backdrop { background: var(--mp-scrim); -webkit-backdrop-filter: none; backdrop-filter: none; }
.modal-bg.show, .modal-overlay.show, .ar-modal.show, .overlay.show, .modal-bg.open, .modal-overlay.open,
.mix-cmdk.open, .kbd-help-overlay.show, .sidebar-overlay.show { animation: mp-fade var(--mp-d2) linear backwards; }
.modal, .modal-card, .modal-box, .ar-modal-box, dialog, .mix-cmdk-box, .kbd-help-panel {
  border-radius: var(--mp-r-pop); box-shadow: var(--mp-sh-pop);
}
.modal-bg.show > *, .modal-overlay.show > *, .ar-modal.show > *, .overlay.show > *, .modal-bg.open > *, .modal-overlay.open > *,
.mix-cmdk.open .mix-cmdk-box, .kbd-help-overlay.show .kbd-help-panel, dialog[open] {
  animation: mp-pop var(--mp-d3) var(--mp-ease) backwards;
}
dialog[open]::backdrop { animation: mp-fade var(--mp-d2) linear backwards; }
/* fill-mode backwards: al terminar no queda ningun transform aplicado (no ancla position:fixed). .mp-no-anim lo apaga si hiciera falta */
.mp-no-anim, .mp-no-anim > * { animation: none !important; }
.modal-box, .modal-card, .ar-modal-box, .mix-cmdk-list, .notif-panel, .mix-prefs-body { overscroll-behavior: contain; }
.modal-head, .ar-modal-top { border-radius: var(--mp-r-pop) var(--mp-r-pop) 0 0; }
.modal-foot, .ar-modal-foot { border-radius: 0 0 var(--mp-r-pop) var(--mp-r-pop); }

.mix-dd, .notif-panel { border-radius: var(--mp-r-card); box-shadow: var(--mp-sh-pop); transform-origin: top right; }
.mix-dd.open, .notif-panel.show { animation: mp-drop var(--mp-d2) var(--mp-ease) backwards; }
.mix-dd a, .mix-dd button, .notif-item, .mix-cmdk-it { transition: background-color var(--mp-d1) linear, color var(--mp-d1) linear; }
.sn-drop-menu { box-shadow: var(--mp-sh-pop); border-radius: var(--mp-r-card); }
.mix-prefs-bg { background: var(--mp-scrim); animation: mp-fade var(--mp-d2) linear backwards; }
.mix-prefs-panel { box-shadow: var(--mp-sh-pop); animation-duration: var(--mp-d3); animation-timing-function: var(--mp-ease); }
.mix-prefs-opt { transition: border-color var(--mp-d1) var(--mp-ease), background-color var(--mp-d1) var(--mp-ease), box-shadow var(--mp-d1) var(--mp-ease); }

.mixfx-toast { border-radius: var(--mp-r-ctl); box-shadow: var(--mp-sh-pop); animation: mp-rise var(--mp-d2) var(--mp-ease) backwards; }
.mixfx-toast.out { animation: mp-fade var(--mp-d2) linear reverse forwards; }
[data-tip]:hover::after { animation: mp-fade var(--mp-d1) linear backwards; }

/* ─────────────── 11 · SIDEBAR ─────────────── */
.sidebar-menu a { transition: background-color var(--mp-d1) var(--mp-ease), color var(--mp-d1) var(--mp-ease); }
.sidebar-menu a:active { background-color: var(--bg-sidebar-active); }
.sidebar { transition: transform var(--mp-d3) var(--mp-ease), background-color var(--mp-d1) linear; }
.sidebar-sep .chev { transition: transform var(--mp-d2) var(--mp-ease); }
.sidebar-buscar input, .sidebar input[type="search"] { border-radius: var(--mp-r-ctl); }

/* ─────────────── 12 · ENLACES Y SELECCIÓN ─────────────── */
a { transition: color var(--mp-d1) var(--mp-ease); }
.content a:not([class]):hover { text-decoration: underline; text-underline-offset: 2px; }
/* (scrollbar global eliminado: mix-ds.css ya estiliza ::-webkit-scrollbar y scrollbar-width/color lo anularia) */

/* ─────────────── 13 · CELULAR ─────────────── */
@media (max-width: 900px) {
  .main { overflow-x: clip; }                                   /* clip no crea scroller: el sticky de la barra sigue andando */
  .content { padding-bottom: max(var(--e7), env(safe-area-inset-bottom)); }
  .content :where(td, th, .card, .kpi, .badge) { overflow-wrap: break-word; }
  .content :where(pre, code) { max-width: 100%; overflow-x: auto; }
  .btn, button { touch-action: manipulation; }                  /* sin demora de 300 ms ni zoom por doble toque */
  .topbar { padding-left: max(10px, env(safe-area-inset-left)); padding-right: max(10px, env(safe-area-inset-right)); }
  .mixfx-toasts { left: 10px; right: 10px; bottom: max(10px, env(safe-area-inset-bottom)); }
  .mixfx-toast { min-width: 0; max-width: none; }
  .sidebar { transition: transform var(--mp-d3) var(--mp-ease) !important; }
}
/* modales como hoja inferior en celular */
@media (max-width: 600px) {
  .modal-bg.show, .modal-overlay.show, .ar-modal.show, .overlay.show, .modal-bg.open, .modal-overlay.open { align-items: flex-end; padding: 0; }
  .modal-box, .modal-card, .ar-modal-box { width: 100%; max-height: 92vh; max-height: 92dvh; border-radius: var(--mp-r-pop) var(--mp-r-pop) 0 0; }
  .modal-bg.show > *, .modal-overlay.show > *, .ar-modal.show > *, .overlay.show > *, .modal-bg.open > *, .modal-overlay.open > * { animation-name: mp-sheet; }
  .modal-head, .ar-modal-top { border-radius: var(--mp-r-pop) var(--mp-r-pop) 0 0; }
  .modal-foot, .ar-modal-foot { border-radius: 0; flex-wrap: wrap; }
  .modal-foot > .btn, .modal-foot > button { flex: 1 1 120px; }
  .tabs, .subnav { mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent); -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 24px), transparent); }
}
@keyframes mp-sheet { from { transform: translateY(24px); opacity: .6; } }

/* ─────────────── 14 · UTILIDADES OPCIONALES ─────────────── */
.mp-fade-in { animation: mp-fade var(--mp-d3) linear backwards; }
.mp-rise-in { animation: mp-rise var(--mp-d3) var(--mp-ease) backwards; }
/* lista que entra escalonada: poner style="--i:N" no hace falta; con nth-child alcanza para las primeras filas */
.mp-stagger > :nth-child(1) { animation-delay: 0ms; } .mp-stagger > :nth-child(2) { animation-delay: 30ms; }
.mp-stagger > :nth-child(3) { animation-delay: 60ms; } .mp-stagger > :nth-child(4) { animation-delay: 90ms; }
.mp-stagger > :nth-child(n+5) { animation-delay: 120ms; }
.mp-stagger > * { animation: mp-rise var(--mp-d3) var(--mp-ease) backwards; }

/* ─────────────── 15 · IMPRESIÓN ─────────────── */
@media print {
  *, *::before, *::after { animation: none !important; transition: none !important; box-shadow: none !important; }
  .skeleton, .mixfx-skel, .mp-spinner { display: none !important; }
}

/* 02/11/2026 · KPI que no se sale de su tarjeta: la cifra se achica sola solo si no entra (container query).
   Solo en grillas de KPI (el ancho de la tarjeta lo da la grilla, no el contenido).
   QA 02/11: la version con :where() tenia especificidad 0 y perdia contra ".kpi .v" de mix-ds.css; ahora iguala (0,3,1) y gana por orden. */
@supports (container-type: inline-size) {
  :is(.kpis, .kpi-grid, .tm-kpis) > :is(.kpi, .kpi-c, .kpi-card, .kpi-d, .stat) { container-type: inline-size; }
  html :is(.kpis, .kpi-grid, .tm-kpis) > :is(.kpi, .kpi-c, .kpi-card, .kpi-d, .stat) :is(.v, b, .kpi-valor, .kpi-value) {
    font-size: min(var(--kpi-cifra), calc(100cqi / 8.4));
    white-space: nowrap; max-width: 100%;
  }
}

/* 02/11/2026 · QA visual real (render headless 1366/1920/390):
   1) grillas de 2 columnas que se ensanchaban con tablas anchas y sacaban la pagina del ancho (Cockpit, Medios de pago, Notas de credito):
      las celdas de la grilla pueden achicarse y lo ancho scrollea adentro de la tarjeta. */
.ck-grid2 > *, .cols2 > *, .grid-2 > *, .steps > .step { min-width: 0; }
.ck-grid2 > .card, .cols2 > .card, .nc-wrap .step { overflow-x: auto; }
/* 2) boton verde "Exportar Excel" (Auditoria de cajas): el texto salia gris sobre verde, ilegible */
a.btn-export, a.btn-export:link, a.btn-export:visited, a.btn-export:hover { color: #fff !important; }
/* 3) celular: barra superior con el titulo aplastado a 64 px ("Tablon de..."): se saca el icono de chat (ya esta el boton flotante) y se ajustan los botones */
@media (max-width: 480px) {
  .topbar-user .chat-quick { display: none; }
  .topbar-user { gap: 2px; }
  .topbar-user .theme-toggle, .topbar-user .notif-bell { min-width: 34px; width: 34px; }
  .topbar-title .crumb-actual { font-size: 15px; }
}
/* 4) celular: botones con texto largo (pasos de Carga de facturas / Notas de credito) se salian de su caja: pasan a 2 renglones */
@media (max-width: 600px) {
  .step .btn, .step button, .filtros .btn, .card > .filtros > a.btn { white-space: normal; max-width: 100%; line-height: 1.25; text-align: center; }
  .card > h3 { flex-wrap: wrap; }
}

/* 02/11/2026 · QA2 (pendientes visuales):
   1) encabezado fijo de las listas (.tabla-listado y similares): la barra de arriba es sticky en top:0 y tapaba el encabezado (top:0);
      ahora se pega justo debajo de la barra. No aplica dentro de contenedores con scroll propio (ahi top:0 es lo correcto). */
.tabla-listado thead th:not(.table-wrap *, .modal-box *, .pp-grid *),
.tabla-retiros thead th:not(.table-wrap *, .modal-box *, .pp-grid *),
table.tabla thead th:not(.table-wrap *, .modal-box *, .pp-grid *),
.resp-table thead th:not(.table-wrap *, .modal-box *, .pp-grid *) { top: var(--topbar-h, 52px); }
/* 2) importes de listas: el signo $ no se separa de la cifra */
.tabla-listado td.r, .tabla-listado td.num, .tabla-p td.num { white-space: nowrap; }
/* 3) celular: la barra superior de pantallas con muchos botones (ficha de articulo) se pasaba 5 px del ancho */
@media (max-width: 480px) {
  header.topbar { padding-left: 8px; padding-right: 8px; }
  header.topbar .topbar-user { gap: 2px; }
  header.topbar .topbar-user .mix-isec-ind { margin-right: 0; }
}
/* 02/11/2026 · QA2: la tabla de Pagos tenia overflow:hidden (esquinas redondas) y eso anulaba el encabezado fijo: se muestra el borde y el sticky anda */
table.tabla-listado.p2-sticky { overflow: visible; }
