/* ============================================================================
   vx-design.css — the mobile-first design system for CFD Manager.
   TWO TIERS, both safe (loaded only when vx_redesign(); every selector carries `vx`):
     · body.vx-on     — FULL redesign (font/bg/box-sizing + chrome + launcher). For pages
                        explicitly redesigned (menuemisor today).
     · body.vx-chrome — LIGHT: ONLY the injected nav chrome (app-bar + bottom-nav + sheet)
                        + a content offset. NO font/bg/box-sizing change → safe to stamp on
                        any legacy page (auto-injected by vx_autochrome.php for allowlisted users).
   Chrome COMPONENTS are scoped to bare `.vx-*` (they exist only where injected, so they
   cannot bleed) and work under BOTH tiers. Breakpoints: compact ≤640 · medium 641-1024 · expanded >1024.
   ============================================================================ */

/* ---- Tokens (custom properties are harmless globally; values used only under .vx-* ) ---- */
:root{
  --vx-ink:#0f172a; --vx-mut:#64748b; --vx-line:#e8edf3; --vx-bg:#eef2f7;
  --vx-accent:#2563eb; --vx-accent-d:#1d4ed8;
  --vx-ok:#15803d; --vx-warn:#b45309; --vx-crit:#dc2626;
  --vx-grad: linear-gradient(120deg,#0b1220,#1e3a8a 70%,#2563eb);
  --vx-card:#ffffff;
  --vx-radius:16px; --vx-radius-sm:11px;
  --vx-shadow:0 1px 2px rgba(16,24,40,.05),0 14px 36px rgba(16,24,40,.10);
  --vx-shadow-lg:0 8px 16px rgba(16,24,40,.08),0 28px 60px rgba(16,24,40,.16);
  --vx-appbar-h:56px; --vx-bottomnav-h:60px; --vx-rail-w:240px;
  --vx-z-appbar:50; --vx-z-rail:40; --vx-z-bottomnav:60; --vx-z-sheet:80; --vx-z-toast:90;
  --vx-font:'Inter',-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  /* premium consultacfd additions (consultacfd-premium plan) — reuse the rest of the tokens above */
  --vx-surface-2:#f7f9fc; --vx-radius-lg:20px;
  --vx-num:'SF Mono',ui-monospace,'Roboto Mono',Menlo,Consolas,monospace;  /* tabular money */
  /* v3 transaction-card (grids-modal-premium-v3 plan) — the 2-line reference card */
  --vx-card-pad:16px; --vx-card-gap:12px; --vx-card-radius:16px;
}

/* ============================================================================
   TIER 1 — FULL base (body.vx-on ONLY). Heavy: font / background / box-sizing.
   ============================================================================ */
body.vx-on{
  margin:0; font-family:var(--vx-font); color:var(--vx-ink);
  background:linear-gradient(180deg,#f4f7fb,var(--vx-bg)); min-height:100vh;
  font-size:14.5px; line-height:1.55; -webkit-text-size-adjust:100%;
  padding-bottom:calc(var(--vx-bottomnav-h) + env(safe-area-inset-bottom,0px));
}
body.vx-on *{ box-sizing:border-box; }
@media (min-width:821px){ body.vx-on{ padding-bottom:0; } }

/* ============================================================================
   TIER 2 — LIGHT chrome offset (body.vx-chrome). NO font/bg/box-sizing change:
   only push content clear of the sticky app-bar + fixed bottom-nav. Box-sizing is
   confined to the injected chrome subtree so it never touches legacy content.
   ============================================================================ */
body.vx-chrome{
  padding-top:calc(var(--vx-appbar-h) + env(safe-area-inset-top,0px));
  padding-bottom:calc(var(--vx-bottomnav-h) + env(safe-area-inset-bottom,0px));
}
/* On auto-injected (legacy) pages the app-bar is FIXED so it sits flush to the viewport top regardless of the
   page's own body margin; padding-top above offsets the content. (menuemisor uses the sticky default instead.) */
body.vx-chrome .vx-appbar{ position:fixed; top:0; left:0; right:0; }
@media (min-width:821px){ body.vx-chrome{ padding-top:64px; padding-bottom:0; } }
.vx-appbar, .vx-appbar *, .vx-bottomnav, .vx-bottomnav *,
.vx-sheet, .vx-sheet *, .vx-sheet-backdrop{ box-sizing:border-box; }

/* Declutter the redundant legacy header on auto-chromed pages — the app-bar already gives you logo + home +
   emisor. The hero logo + logout-padlock/home icons are duplicates on EVERY width (critic: they burn ~80px of
   desktop above the grid and clash with the flat chrome); the corner-GIF frame hides on mobile only. */
body.vx-chrome img[src*="48-home"],
body.vx-chrome img[src*="Home-32"],
body.vx-chrome img[src*="48-security"],
body.vx-chrome img[src$="/logo.png"]{ display:none; }
body.vx-chrome .vx-appbar img[src$="/logo.png"]{ display:inline-block; }
@media (max-width:820px){
  body.vx-chrome img[src*="corner-"],
  body.vx-chrome .tbl_top_corner,
  body.vx-chrome .tbl_bottom_corner,
  body.vx-chrome img[src*="48-home"],
  body.vx-chrome img[src*="Home-32"],
  body.vx-chrome img[src*="48-security"],
  body.vx-chrome img[src$="/logo.png"]{ display:none; }
  body.vx-chrome .vx-appbar img[src$="/logo.png"]{ display:inline-block; }   /* keep the app-bar's own logo */
  /* app-bar declutter on the phone: the two unlabeled icon circles (Folios / Emisores) are mystery buttons —
     both destinations live in the "Más" sheet. Logo + emisor + Salir is enough chrome. */
  .vx-appbar .vx-icbtn{ display:none!important; }
  .vx-appbar .vx-emisor{ max-width:52vw; font-size:13px; opacity:1; }
  /* bottom-nav: readable labels; few-tab pages (emisores) center instead of flinging to the corners */
  .vx-bottomnav{ justify-content:center; }
  .vx-bottomnav a{ flex:1 1 0; max-width:130px; font-size:11.5px; }
  /* pager: a quiet centered control, not a ragged white strip */
  body.vx-chrome .ui-jqgrid-pager, body.vx-on .ui-jqgrid-pager{ background:transparent!important; border:0!important; }
  body.vx-chrome .ui-jqgrid-pager .ui-pg-table, body.vx-on .ui-jqgrid-pager .ui-pg-table{ margin:0 auto!important; }
}

/* NO sideways scroll on auto-chromed pages (the viejito's finding): shrink the usual overflow culprits to the
   viewport on mobile — fixed-width inputs/selects/textareas, big images, and wide layout tables — WITHOUT a global
   box-sizing/font change. jqGrid catalogs are already carded above; menuemisor is vx-on (unaffected). This is the
   per-page form reflow, applied generically so every current + future chrome page fits the couch. */
@media (max-width:820px){
  body.vx-chrome img{ max-width:100%; height:auto; }
  /* inline-width controls are the overflow drivers (e.g. style="width:560px") — make them FILL their cell
     instead of demanding fixed px, so the layout table can finally collapse to the viewport. */
  body.vx-chrome input[style*="width"],
  body.vx-chrome select[style*="width"],
  body.vx-chrome textarea[style*="width"]{ width:100%!important; max-width:100%!important; box-sizing:border-box; }
  /* any other oversized control just gets capped. */
  body.vx-chrome input:not([type=checkbox]):not([type=radio]):not([type=image]),
  body.vx-chrome select,
  body.vx-chrome textarea{ max-width:100%!important; box-sizing:border-box; }
  /* drop fixed pixel widths on layout tables so they share the viewport (table-layout:fixed = real cap). */
  body.vx-chrome table[style*="width"],
  body.vx-chrome table[width]{ width:100%!important; max-width:100%!important; table-layout:fixed; }
  body.vx-chrome table{ max-width:100%!important; }
  /* wrap long unbreakable tokens (emails/RFCs) without chopping normal words mid-letter. */
  /* `anywhere` (not break-word) also shrinks min-content, so flex/grid value cells can actually wrap
     long unbreakable tokens (emails/RFCs) instead of clipping at the card edge. */
  body.vx-chrome td, body.vx-chrome th{ overflow-wrap:anywhere; word-break:normal; }
  /* the jqGrid caption/titlebar is redundant on a phone (the page already names itself) and its theme color is
     near-white (rgb 234,245,247) → it reads as a faint/broken title. Hide it in the carded mobile view. */
  body.vx-chrome .ui-jqgrid-titlebar{ display:none!important; }
  /* make the pager's tiny nav controls tappable on the couch. */
  body.vx-chrome .ui-jqgrid-pager td.ui-pg-button,
  body.vx-chrome .ui-jqgrid-pager .ui-pg-button{ min-height:34px; padding:4px 6px; }
  body.vx-chrome .ui-jqgrid-pager .ui-pg-input{ min-height:30px; }
  /* legacy page-frame / jqGrid container: the page is wrapped in a ~994px fixed-width `.tbl_bckgrnd_brite` table
     (header cells width:320/334/320) centered by <div align="center">, so on a phone the cage overflows AND a
     phantom column shoves the grid into the right half (the emisores.php mess). Fix: STACK the frame table — turn
     its rows/cells into full-width blocks — so its sections sit one under the other and the grid fills the screen.
     (The direct-child selectors only hit the frame's own cells; the nested jqGrid is carded by the rules above.) */
  body.vx-chrome table.tbl_bckgrnd_brite,
  body.vx-chrome table.tbl_bckgrnd_brite > tbody,
  body.vx-chrome table.tbl_bckgrnd_brite > tbody > tr,
  body.vx-chrome table.tbl_bckgrnd_brite > tbody > tr > td{ display:block!important; width:auto!important; max-width:100%!important; }
  body.vx-chrome #gridContainer,
  body.vx-chrome [id^="div_wrapper_"]{ width:auto!important; max-width:100%!important; }
  body.vx-chrome div[align="center"]{ width:auto!important; max-width:100%!important; }
  /* page header zone (the legacy txt_title cell): readable intro + the action link as a real button */
  body.vx-chrome td.txt_title{ padding:14px 16px 12px!important; font-family:var(--vx-font); font-size:14px;
    line-height:1.5; color:#3b4a5f; background:transparent!important; }
  body.vx-chrome td.txt_title br{ display:none; }
  /* On the known catalog pages, the legacy instruction sentence ("da clic en el Nombre...") is noise doing
     header duty. Mute it and give the page a REAL title; the search + chevroned cards explain themselves. */
  body.vx-page-emisores td.txt_title, body.vx-page-receptores td.txt_title, body.vx-page-productos td.txt_title,
  body.vx-page-clavessat td.txt_title, body.vx-page-empleados td.txt_title, body.vx-page-proveedores td.txt_title,
  body.vx-page-clientesdirectos td.txt_title, body.vx-page-conceptosnomina td.txt_title,
  body.vx-page-usuarios td.txt_title, body.vx-page-bancocuentas td.txt_title, body.vx-page-contcuentas td.txt_title,
  body.vx-page-notificaciones td.txt_title, body.vx-page-contratos td.txt_title,
  body.vx-page-plantillasusuarios td.txt_title,
  body.vx-page-contparametros td.txt_title, body.vx-page-contcuentamovs td.txt_title,
  body.vx-page-contcuentamovsgral td.txt_title, body.vx-page-bancocuentamovs td.txt_title{
    font-size:0!important; line-height:0!important; padding:18px 16px 6px!important; }
  body.vx-chrome td.txt_title::before{ display:block; font-size:22px; line-height:1.25; font-weight:800;
    color:#0b1526; letter-spacing:-.01em; font-family:var(--vx-font); }
  body.vx-page-emisores td.txt_title::before{ content:"Elige tu emisor"; }
  body.vx-page-receptores td.txt_title::before{ content:"Clientes"; }
  body.vx-page-productos td.txt_title::before{ content:"Productos y Servicios"; }
  body.vx-page-clavessat td.txt_title::before{ content:"Claves del SAT"; }
  body.vx-page-empleados td.txt_title::before{ content:"Empleados"; }
  body.vx-page-proveedores td.txt_title::before{ content:"Proveedores"; }
  body.vx-page-clientesdirectos td.txt_title::before{ content:"Clientes Directos"; }
  body.vx-page-conceptosnomina td.txt_title::before{ content:"Conceptos de N\00f3mina"; }
  body.vx-page-usuarios td.txt_title::before{ content:"Usuarios"; }
  body.vx-page-bancocuentas td.txt_title::before{ content:"Cuentas Bancarias"; }
  body.vx-page-contcuentas td.txt_title::before{ content:"Cuentas Contables"; }
  body.vx-page-notificaciones td.txt_title::before{ content:"Notificaciones"; }
  body.vx-page-contratos td.txt_title::before{ content:"Contratos"; }
  body.vx-page-plantillasusuarios td.txt_title::before{ content:"Plantillas de Usuarios"; }
  body.vx-page-contparametros td.txt_title::before{ content:"Par\00e1metros de Contabilidad"; }
  body.vx-page-contcuentamovs td.txt_title::before{ content:"Movimientos Contables"; }
  body.vx-page-contcuentamovsgral td.txt_title::before{ content:"Movimientos Contables"; }
  body.vx-page-bancocuentamovs td.txt_title::before{ content:"Movimientos Bancarios"; }
  body.vx-chrome td.txt_title a{ display:flex; width:max-content; align-items:center; gap:8px; margin-top:12px;
    background:linear-gradient(120deg,var(--vx-accent),var(--vx-accent-d)); color:#fff!important; text-decoration:none;
    border-radius:999px; padding:10px 18px; font-weight:700; font-size:14px; box-shadow:0 6px 16px rgba(37,99,235,.25); }
  body.vx-chrome td.txt_title a img{ display:none!important; }
  body.vx-chrome td.txt_title .txt_title_add{ color:#fff!important; font-size:14px!important; }
}

/* ============================================================================
   CHROME COMPONENTS — bare `.vx-*` (work under both tiers; inject-anywhere-safe).
   ============================================================================ */

/* ---- App bar (sticky top) ---- */
.vx-appbar{
  position:sticky; top:0; z-index:var(--vx-z-appbar);
  background:var(--vx-grad); color:#fff; box-shadow:0 6px 28px rgba(15,23,42,.22);
  padding:0 16px; padding-top:env(safe-area-inset-top,0px);
  height:calc(var(--vx-appbar-h) + env(safe-area-inset-top,0px));
  display:flex; align-items:center; gap:12px;
  font-family:var(--vx-font);
}
.vx-appbar .vx-brand{ display:flex; align-items:center; gap:10px; font-weight:800; font-size:15px; min-width:0; color:#fff; text-decoration:none; }
.vx-appbar .vx-brand img{ height:30px; width:auto; }
.vx-appbar .vx-emisor{ font-weight:600; opacity:.9; font-size:12.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:46vw; }
.vx-appbar .vx-spacer{ flex:1; }
.vx-appbar a, .vx-appbar button{ color:#dbe7ff; text-decoration:none; }
.vx-appbar .vx-usermenu{ background:rgba(255,255,255,.14); border:1px solid rgba(255,255,255,.22); color:#fff;
  border-radius:999px; padding:7px 13px; font-size:13px; font-weight:700; cursor:pointer; }
.vx-appbar .vx-icbtn{ display:inline-flex; align-items:center; justify-content:center;
  width:38px; height:38px; border-radius:999px; font-size:19px; text-decoration:none; color:#eaf1ff;
  background:rgba(255,255,255,.12); border:1px solid rgba(255,255,255,.18); }
.vx-appbar .vx-icbtn:hover{ background:rgba(255,255,255,.22); }
/* "Menu" pill — the primary nav entry on DESKTOP (where the bottom-nav is hidden); opens the "Mas" sheet. */
.vx-appbar .vx-appbar-menu{ display:none; align-items:center; gap:6px; }
@media (min-width:821px){ .vx-appbar{ height:64px; padding:0 24px; } .vx-appbar .vx-brand{ font-size:16px; } .vx-appbar .vx-emisor{ max-width:none; }
  .vx-appbar .vx-appbar-menu{ display:inline-flex; } }

/* ---- Bottom nav (mobile) ---- */
.vx-bottomnav{ position:fixed; left:0; right:0; bottom:0; z-index:var(--vx-z-bottomnav);
  background:#fff; border-top:1px solid var(--vx-line); display:flex;
  padding-bottom:env(safe-area-inset-bottom,0px); box-shadow:0 -6px 24px rgba(16,24,40,.08);
  font-family:var(--vx-font); }
.vx-bottomnav a{ flex:1; display:flex; flex-direction:column; align-items:center; gap:2px;
  padding:8px 4px; min-height:var(--vx-bottomnav-h); color:var(--vx-mut); text-decoration:none; font-size:10.5px; font-weight:700; }
.vx-bottomnav a .ico{ font-size:21px; line-height:1; }
.vx-bottomnav a.active{ color:var(--vx-accent); position:relative; }
.vx-bottomnav a.active::before{ content:""; position:absolute; top:0; left:50%; transform:translateX(-50%);
  width:26px; height:3px; border-radius:0 0 3px 3px; background:var(--vx-accent); }
@media (min-width:821px){ .vx-bottomnav{ display:none; } }

/* ---- Bottom-sheet / modal (generic + "Más") ---- */
.vx-sheet-backdrop{ position:fixed; inset:0; background:rgba(15,23,42,.45); z-index:var(--vx-z-sheet); display:none; }
.vx-sheet-backdrop.open{ display:block; }
.vx-sheet{ position:fixed; left:0; right:0; bottom:0; z-index:81; /* NOT calc(var()+1): no-space calc is invalid → z:auto → backdrop painted ON TOP (dimmed sheet + dead taps) */
  background:#fff; color:var(--vx-ink); border-radius:18px 18px 0 0;
  padding:18px 18px calc(18px + env(safe-area-inset-bottom,0px));
  box-shadow:0 -10px 40px rgba(0,0,0,.25); transform:translateY(100%);
  transition:transform .25s cubic-bezier(.2,.7,.2,1), opacity .2s ease;
  opacity:0; pointer-events:none;   /* hidden at rest (both mobile slide-up and desktop modal) */
  overflow:visible; max-height:86vh; font-family:var(--vx-font); }
.vx-sheet.open{ transform:translateY(0); opacity:1; pointer-events:auto; }
@media (min-width:861px){
  .vx-sheet{ left:50%; right:auto; bottom:auto; top:50%; transform:translate(-50%,-50%) scale(.96);
    width:min(560px,92vw); border-radius:18px; }
  .vx-sheet.open{ transform:translate(-50%,-50%) scale(1); opacity:1; pointer-events:auto; }
}
.vx-sheet-grab{ width:42px; height:5px; border-radius:999px; background:#d7dee8; margin:0 auto 12px; }
.vx-sheet-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; }
.vx-sheet-title{ margin:0; font-size:17px; font-weight:800; }
.vx-sheet-x{ border:none; background:#f1f5f9; width:34px; height:34px; border-radius:999px; font-size:20px;
  line-height:1; color:#475569; cursor:pointer; }
.vx-mas-scroll{ overflow:auto; max-height:64vh; -webkit-overflow-scrolling:touch; }
.vx-mas-group{ margin-bottom:14px; }
.vx-mas-grouptitle{ font-size:11.5px; font-weight:800; letter-spacing:.05em; text-transform:uppercase;
  color:var(--vx-mut); margin:0 0 6px 4px; }
.vx-mas-link{ display:flex; align-items:center; gap:12px; padding:12px; border-radius:12px;
  text-decoration:none; color:var(--vx-ink); font-weight:700; font-size:15px; min-height:48px; }
/* the theme's a:visited (0,1,1) out-specifies .vx-mas-link (0,1,0) -> visited rows turned legacy-teal
   ("Claves SAT" looked like a different species). Pin every state for ALL chrome links. */
.vx-mas-link:link, .vx-mas-link:visited, .vx-mas-link:hover{ color:var(--vx-ink); text-decoration:none; }
.vx-bottomnav a:link, .vx-bottomnav a:visited{ color:var(--vx-mut); }
.vx-bottomnav a.active:link, .vx-bottomnav a.active:visited{ color:var(--vx-accent); }
.vx-appbar a:link, .vx-appbar a:visited{ color:#dbe7ff; }
.vx-mas-link .ico{ font-size:20px; width:26px; text-align:center; }
.vx-mas-link:active{ background:#eef4ff; }
.vx-sheet-x{ min-width:44px; min-height:44px; }

/* Floating "Generar" action (counter app, nvocfd40) — a thumb-reachable shortcut that clicks the page's own
   stamp trigger. Sits above the bottom-nav. Mobile/tablet only (desktop shows the form's own button). */
.vx-fab-timbrar{ position:fixed; right:14px; z-index:65;
  bottom:calc(var(--vx-bottomnav-h) + env(safe-area-inset-bottom,0px) + 12px);
  display:inline-flex; align-items:center; gap:8px; min-height:52px; padding:0 22px; border:none;
  border-radius:999px; font-family:var(--vx-font); font-weight:800; font-size:16px; color:#fff; cursor:pointer;
  background:linear-gradient(120deg,var(--vx-ok),#0f6b34); box-shadow:0 12px 30px rgba(15,23,42,.30); }
.vx-fab-timbrar:active{ transform:translateY(1px); }
@media (min-width:821px){ .vx-fab-timbrar{ display:none; } }

/* ============================================================================
   RESPONSIVE jqGrid — one transform for EVERY catalog (Clientes/Productos/Proveedores/ClavesSAT/Empleados/…).
   On <=1024px each grid row becomes a labeled card (labels supplied by js2/vx-grid.js via data-vxlabel).
   Scoped to redesigned bodies; jqGrid's inline styles are non-!important, so our !important wins. Desktop = the
   real grid, untouched. Works under both tiers (vx-chrome auto-chromed pages + vx-on).
   ============================================================================ */
@media (max-width:820px){
  /* gray canvas so white cards actually SEPARATE (white-on-white was unreadable) */
  body.vx-chrome{ background:#e9eef5!important; }
  body.vx-chrome .ui-jqgrid, body.vx-on .ui-jqgrid,
  body.vx-chrome .ui-jqgrid-view, body.vx-on .ui-jqgrid-view{ width:100%!important; }
  /* hide the fixed header table (labels now live in the cards) + the resize/scroll chrome */
  body.vx-chrome .ui-jqgrid-hdiv, body.vx-on .ui-jqgrid-hdiv,
  body.vx-chrome .ui-jqgrid-hbox, body.vx-on .ui-jqgrid-hbox,
  body.vx-chrome .ui-jqgrid-resize-mark, body.vx-on .ui-jqgrid-resize-mark{ display:none!important; }
  /* jqGrid's invisible first row (zero-height width-setter cells) leaks tick-mark artifacts when stacked — kill it */
  body.vx-chrome .ui-jqgrid-btable tr.jqgfirstrow, body.vx-on .ui-jqgrid-btable tr.jqgfirstrow{ display:none!important; }
  /* un-fix the scrolling body so it grows with content + give the card column air */
  body.vx-chrome .ui-jqgrid-bdiv, body.vx-on .ui-jqgrid-bdiv{ width:100%!important; height:auto!important; overflow:visible!important; padding:4px 16px 10px!important; box-sizing:border-box; }
  body.vx-chrome .ui-jqgrid-btable, body.vx-on .ui-jqgrid-btable,
  body.vx-chrome .ui-jqgrid-btable>tbody, body.vx-on .ui-jqgrid-btable>tbody{ display:block!important; width:100%!important; }
  /* === v3 TRANSACTION CARD — each row → a 2-line card (reference: name+amount / date·type + status pill). =====
     Layout is driven by data-vxrole (stamped read-only by js2/vx-grid.js): line 1 = NAME (bold, ellipsis) +
     AMOUNT (bold, tabular, right); line 2 = META (date · type, muted) + STATUS pill (right). Pure-data noise is
     hidden; cells carrying an action control are parked in a strip below. minmax(0,1fr) on col1 = ellipsis-safe,
     no track blowout. (Replaces the v2 stacked label/value "chorizo".) */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow{
    display:grid!important; grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"vxname vxamt" "vxmeta vxstat";
    column-gap:12px; row-gap:5px; align-items:center;
    width:auto!important; height:auto!important; margin:0 0 var(--vx-card-gap); padding:var(--vx-card-pad);
    border:1px solid var(--vx-line)!important; border-radius:var(--vx-card-radius); background:var(--vx-card)!important;
    box-shadow:var(--vx-shadow); overflow:hidden; transition:transform .12s ease; }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow:active, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow:active{ transform:scale(.992); }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow:nth-child(2n), body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow:nth-child(2n){ background:var(--vx-card)!important; }
  /* hide pure-data noise (version, subtotal, IVA, retenciones, moneda, TC, audit, id, merged type, non-winner
     status). Ancestor chain out-specifies any generic rule (hard-won). Cells carrying a clickable control are
     KEPT (next rule) so per-row actions survive on catalogs. */
  body.vx-chrome .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]),
  body.vx-on .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]),
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="metahidden"],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="metahidden"]{ display:none!important; }
  body.vx-chrome .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]):is(:has(a),:has(button),:has([onclick])),
  body.vx-on .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]):is(:has(a),:has(button),:has([onclick])){
    display:flex!important; grid-column:1 / -1; justify-content:flex-end; align-items:center; gap:10px;
    padding:8px 0 0!important; margin-top:4px; border:0!important; border-top:1px solid var(--vx-line)!important;
    background:transparent!important; }
  /* line 1 — NAME (the anchor) */
  body.vx-chrome tr.jqgrow>td[data-vxrole="name"], body.vx-on tr.jqgrow>td[data-vxrole="name"]{
    grid-area:vxname; min-width:0; padding:0!important; border:0!important; background:transparent!important;
    font-size:16.5px; line-height:1.3; font-weight:700; color:var(--vx-ink);
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="name"] a, body.vx-on tr.jqgrow>td[data-vxrole="name"] a{ color:inherit!important; font-weight:inherit; text-decoration:none; }
  /* (2026-07-12, found while fixing usuarios.php) a 2-line hero+sub name cell (.vx-name-main + .vx-name-sub,
     from cleanNameRow's "nombre<br>rfc" split OR mergeIdentifierRow's separate-cell merge) was silently
     CLIPPED: white-space:nowrap above makes CSS Grid size this cell's auto-height as if it were ONE line
     tall (that's what nowrap communicates to the grid sizing algorithm), even though .vx-name-main/-sub are
     separate display:block children that need 2 lines' worth of height — so the 2nd line rendered mostly
     hidden by this cell's own overflow:hidden. Confirmed live on the ALREADY-SHIPPED receptores.php card
     (the RFC sub-line was clipped to a barely-visible sliver) -- a real, previously-undiscovered bug, not
     just a usuarios.php-only issue. Each child already handles its own single-line ellipsis
     (.vx-name-main sets its own overflow/text-overflow at line ~2170 below), so the PARENT no longer needs
     to clip -- only override when a 2-line child is actually present, so plain single-line name cells
     (Productos' description, doc grids) keep their original nowrap-ellipsis behavior untouched. */
  body.vx-chrome tr.jqgrow>td[data-vxrole="name"]:has(.vx-name-sub), body.vx-on tr.jqgrow>td[data-vxrole="name"]:has(.vx-name-sub){
    white-space:normal!important; overflow:visible!important; height:auto!important; }
  /* line 1 — AMOUNT (tabular, right, DARK like the reference). High specificity + !important to beat the v2
     "accent money" rule (td[aria-describedby$="_total"] -> blue) on the CARD only — desktop keeps its accent. */
  body.vx-chrome .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"],
  body.vx-on .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"]{
    grid-area:vxamt; justify-self:end; padding:0!important; border:0!important; background:transparent!important;
    font-weight:700!important; font-size:16px; color:var(--vx-ink)!important; font-variant-numeric:tabular-nums; white-space:nowrap; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="amount"] *, body.vx-on tr.jqgrow>td[data-vxrole="amount"] *{ color:inherit!important; }
  /* line 2 — META (date · type, muted) ; vx-grid.js merges the two cells into .vx-meta (originals kept hidden) */
  body.vx-chrome tr.jqgrow>td[data-vxrole="meta"], body.vx-on tr.jqgrow>td[data-vxrole="meta"],
  body.vx-chrome tr.jqgrow>td[data-vxrole="date"], body.vx-on tr.jqgrow>td[data-vxrole="date"],
  body.vx-chrome tr.jqgrow>td[data-vxrole="type"], body.vx-on tr.jqgrow>td[data-vxrole="type"]{
    grid-area:vxmeta; min-width:0; padding:0!important; border:0!important; background:transparent!important;
    font-size:13.5px; font-weight:600; color:var(--vx-mut); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  body.vx-chrome tr.jqgrow .vx-meta-orig, body.vx-on tr.jqgrow .vx-meta-orig{ display:none!important; }   /* preserved-but-hidden originals (meta merge + name "- RFC" strip) */
  /* line 2 — STATUS (the labeled pill, right). The card pill carries a WORD (Vigente/Cancelado/Sin timbrar/…)
     via data-vxstlabel (set by vx-grid.js), overriding the desktop glyph-only ::after. Semantic color by polarity. */
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"], body.vx-on tr.jqgrow>td[data-vxrole="status"]{
    grid-area:vxstat; justify-self:end; padding:0!important; border:0!important; background:transparent!important; white-space:nowrap; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"].vx-st[data-vxstlabel]::after,
  body.vx-on tr.jqgrow>td[data-vxrole="status"].vx-st[data-vxstlabel]::after{
    content:attr(data-vxstlabel)!important; display:inline-flex; align-items:center; min-width:0!important; height:auto;
    padding:4px 11px!important; border-radius:999px; font:700 12px/1.2 var(--vx-font)!important; letter-spacing:.01em; white-space:nowrap; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"].vx-st-yes[data-vxstlabel]::after,
  body.vx-on tr.jqgrow>td[data-vxrole="status"].vx-st-yes[data-vxstlabel]::after{ background:#dcfce7; color:#15803d; box-shadow:inset 0 0 0 1px rgba(21,128,61,.22); }
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"].vx-st-no[data-vxstlabel]::after,
  body.vx-on tr.jqgrow>td[data-vxrole="status"].vx-st-no[data-vxstlabel]::after{ background:#f1f5f9; color:#64748b; box-shadow:inset 0 0 0 1px rgba(15,23,42,.08); }
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"].vx-st-crit[data-vxstlabel]::after,
  body.vx-on tr.jqgrow>td[data-vxrole="status"].vx-st-crit[data-vxstlabel]::after{ background:#fef2f2; color:#b91c1c; box-shadow:inset 0 0 0 1px rgba(185,28,28,.20); }
  body.vx-chrome tr.jqgrow>td[data-vxrole="status"].vx-st-warn[data-vxstlabel]::after,
  body.vx-on tr.jqgrow>td[data-vxrole="status"].vx-st-warn[data-vxstlabel]::after{ background:#fff7ed; color:#b45309; box-shadow:inset 0 0 0 1px rgba(180,83,9,.20); }
  body.vx-chrome tr.jqgrow>td a, body.vx-on tr.jqgrow>td a{ min-height:30px; display:inline-flex; align-items:center; }
  /* SELECTION (Step 05): document-grid cards get a leading checkbox column (grid-area vxsel, spans both card rows).
     The checkbox is injected by js2/vx-bulk.js (gated, mobile). Scoped to document pages so catalog cards are
     unchanged. The card becomes 3 columns: [checkbox] [name|meta] [amount|status]. */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow{
    grid-template-columns:auto minmax(0,1fr) auto;
    grid-template-areas:"vxsel vxname vxamt" "vxsel vxmeta vxstat"; }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox{
    grid-area:vxsel; align-self:center; display:flex; align-items:center; justify-content:center;
    margin:0 2px 0 -4px; padding:10px; min-width:44px; min-height:44px; cursor:pointer; -webkit-tap-highlight-color:transparent; }
  body.vx-chrome .vx-selbox .vx-selcb{
    -webkit-appearance:none; appearance:none; width:24px; height:24px; margin:0; border:2px solid #c4d2e3;
    border-radius:7px; background:#fff; cursor:pointer; position:relative; flex:0 0 auto; transition:border-color .12s, background .12s; }
  body.vx-chrome .vx-selbox .vx-selcb:checked{ background:var(--vx-accent); border-color:var(--vx-accent); }
  body.vx-chrome .vx-selbox .vx-selcb:checked::after{
    content:""; position:absolute; left:7px; top:3px; width:6px; height:11px; border:solid #fff; border-width:0 2.5px 2.5px 0; transform:rotate(45deg); }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow.vx-selected{ box-shadow:inset 0 0 0 2px var(--vx-accent), var(--vx-shadow); }
  /* sticky bulk-action bar (appears on >=1 selected); sits above the bottom-nav */
  body.vx-bb-open .ui-jqgrid-bdiv, body.vx-bb-open{ scroll-padding-bottom:120px; }
  body.vx-bb-open #gbox_gr_vx_CFDs_Emitidos_01{ margin-bottom:96px; }
  .vx-bulkbar{ position:fixed; left:10px; right:10px; bottom:calc(var(--vx-bottomnav-h) + 8px + env(safe-area-inset-bottom,0px));
    z-index:75; display:none; align-items:center; gap:10px; padding:11px 12px 11px 16px; border-radius:16px;
    background:#0f172a; color:#fff; box-shadow:0 12px 34px rgba(16,24,40,.34); font-family:var(--vx-font);
    transform:translateY(8px); opacity:0; transition:transform .18s ease, opacity .18s ease; }
  .vx-bulkbar.vx-bb-show{ display:flex; transform:translateY(0); opacity:1; }
  .vx-bb-count{ font:700 14px/1.1 var(--vx-font); white-space:nowrap; }
  .vx-bb-acts{ display:flex; gap:7px; margin-left:auto; }
  .vx-bb-btn{ -webkit-tap-highlight-color:transparent; cursor:pointer; border:0; border-radius:10px;
    padding:9px 13px; font:700 13px/1 var(--vx-font); color:#fff; background:rgba(255,255,255,.14); transition:background .12s; }
  .vx-bb-btn:active{ background:rgba(255,255,255,.28); }
  .vx-bb-xml, .vx-bb-pdf{ background:var(--vx-accent); }
  .vx-bb-xml:active, .vx-bb-pdf:active{ background:var(--vx-accent-d); }
  .vx-bb-cancel{ background:rgba(220,38,38,.20); box-shadow:inset 0 0 0 1px rgba(248,113,113,.45); color:#fecaca; }
  .vx-bb-cancel:active{ background:rgba(220,38,38,.34); }
  .vx-bb-clear{ background:transparent; box-shadow:inset 0 0 0 1px rgba(255,255,255,.28); }
  @media (prefers-reduced-motion:reduce){ .vx-bulkbar{ transition:none!important; } }
  /* bulk-cancel confirm dialog content (the irreversible gate) */
  #vx-bc-dlg{ font-family:var(--vx-font); }
  #vx-bc-dlg .vx-bc-warn{ font-size:14.5px; line-height:1.5; margin:2px 0 10px; }
  #vx-bc-dlg .vx-bc-irrev{ color:var(--vx-crit); }
  #vx-bc-dlg .vx-bc-list{ list-style:none; margin:0 0 12px; padding:8px 10px; max-height:140px; overflow:auto;
    background:var(--vx-surface-2); border:1px solid var(--vx-line); border-radius:10px; font-size:12.5px; color:var(--vx-mut); }
  #vx-bc-dlg .vx-bc-list li{ padding:2px 0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  #vx-bc-dlg .vx-bc-mlabel{ display:block; font-weight:700; font-size:13px; margin:0 0 4px; }
  #vx-bc-dlg .vx-bc-motivo{ width:100%; box-sizing:border-box; min-height:42px; padding:0 10px; border:1.5px solid #cdd8e6; border-radius:10px; font-size:15px; background:#fff; }
  #vx-bc-dlg .vx-bc-note{ font-size:12px; color:var(--vx-mut); margin:8px 0 10px; line-height:1.4; }
  #vx-bc-dlg .vx-bc-ack{ display:flex; gap:8px; align-items:flex-start; font-size:13.5px; font-weight:600; color:var(--vx-ink); }
  #vx-bc-dlg .vx-bc-ack input{ margin-top:2px; width:18px; height:18px; }
  /* the destructive confirm button: restrained red, never the visual default */
  .ui-dialog-buttonpane .vx-bc-confirm{ background:var(--vx-crit)!important; border-color:var(--vx-crit)!important; color:#fff!important; font-weight:700!important; }
  /* DOCUMENT grids (emitidos/nóminas/compras/pagos): a tap opens the full toolbar in the modal, so keep the card
     reference-clean — hide the inline action cells too (the catalog keep-rule above is overridden here, two body
     classes => higher specificity). Catalogs keep their inline shortcuts. */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]),
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]),
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]),
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td:not([data-vxrole]){ display:none!important; }
  /* the FAB must NEVER cover the last form field (mis-tap = a fiscal action): generous scroll clearance */
  body.vx-page-nvocfd40{ padding-bottom:185px!important; }
  /* quick-filter (injected by vx-grid.js) + filtered-out cards */
  .vx-gridfilter{ padding:2px 16px 12px; }
  .vx-gridfilter input::placeholder{ color:#64748b; opacity:1; }
  .vx-gridfilter-msg{ margin-top:10px; padding:12px 14px; background:#fff7ed; border:1px solid #fdba74;
    border-radius:12px; color:#9a3412; font-family:var(--vx-font); font-size:14px; font-weight:600; }
  /* F4 (hoisted 2026-06-22): .vx-emptystate / .vx-empty-hide / .vx-daterange were here but MOBILE-ONLY (inside this
     @media max-width:820 block). ensureEmptyState() + vx-daterange.js run at ALL widths, so on desktop the card/bar
     showed UNSTYLED and the pager/export never hid. Moved to a top-level (width-agnostic) block AFTER this @media —
     see "VX-F4 WIDTH-AGNOSTIC" below. Only the phone tweaks stay width-scoped. */
  .vx-gridfilter input{ width:100%; box-sizing:border-box; min-height:46px; padding:0 16px; font-size:16px;
    font-family:var(--vx-font); border:1.5px solid #cdd8e6; border-radius:999px; background:#fff;
    box-shadow:0 1px 3px rgba(16,24,40,.06); outline:none; }
  .vx-gridfilter input:focus{ border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow.vx-filter-hide,
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow.vx-filter-hide{ display:none!important; }
  /* desktop-only power tools are noise on a phone: the pager's cryptic icon toolbar + the report configurator */
  body.vx-chrome .ui-jqgrid-pager td[id$="_left"], body.vx-on .ui-jqgrid-pager td[id$="_left"]{ display:none!important; }
  body.vx-chrome [id^="div_crtbl"], body.vx-chrome [id$="_cr_01"],
  body.vx-on [id^="div_crtbl"], body.vx-on [id$="_cr_01"]{ display:none!important; }
  /* pager: let it wrap instead of fixed-width overflow */
  body.vx-chrome .ui-jqgrid-pager, body.vx-on .ui-jqgrid-pager{ width:100%!important; height:auto!important; }
  body.vx-chrome .ui-jqgrid-pager .ui-pg-table, body.vx-on .ui-jqgrid-pager .ui-pg-table{ width:auto!important; }
}

/* === VX-F4 WIDTH-AGNOSTIC (2026-06-22) — hoisted OUT of the @media(max-width:820) above: the empty-state card, the
   pager/export declutter, and the date-range bar must apply on DESKTOP too (ensureEmptyState + vx-daterange.js run at
   ALL widths; previously these were mobile-only so desktop showed them unstyled / never hid the pager). === */
.vx-emptystate{ margin:6px 16px 12px; padding:22px 18px; background:#fff; border:1px dashed #c4d2e3;
  border-radius:14px; color:#51627a; font-family:var(--vx-font); font-size:15px; font-weight:600; text-align:center; }
/* hide the now-pointless legacy pager + export-icon row on a friendly-empty grid (vx-grid.js marks them while empty).
   Doubled class = 3 classes of specificity to beat the .tbl_bckgrnd_brite frame display:block!important rule. */
body.vx-chrome .vx-empty-hide.vx-empty-hide, body.vx-on .vx-empty-hide.vx-empty-hide{ display:none!important; }
/* date-range bar (vx-daterange.js) — surfaces the document-grid range the reskin hid (unreachable on BOTH viewports). */
.vx-daterange{ display:flex; flex-wrap:wrap; align-items:flex-end; gap:10px; margin:8px 16px 12px; padding:12px 14px;
  background:#fff; border:1px solid var(--vx-line,#e2e8f0); border-radius:14px; box-shadow:0 1px 3px rgba(16,24,40,.06);
  font-family:var(--vx-font); }
.vx-daterange .vx-dr-icon{ font-size:20px; line-height:40px; }
.vx-daterange .vx-dr-field{ display:flex; flex-direction:column; gap:2px; }
.vx-daterange .vx-dr-cap{ font-size:11px; font-weight:700; color:#64748b; text-transform:uppercase; letter-spacing:.4px; }
.vx-daterange .vx-dr-input{ min-height:40px; padding:0 12px; font-size:16px; font-family:var(--vx-font);
  border:1.5px solid #cdd8e6; border-radius:10px; background:#fff; color:#1a2233; outline:none; box-sizing:border-box; }
.vx-daterange .vx-dr-input:focus{ border-color:var(--vx-accent,#2563eb); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
.vx-daterange .vx-dr-go{ min-height:40px; padding:0 22px; margin-left:auto; font-size:15px; font-weight:800;
  color:#fff; background:var(--vx-accent,#2563eb); border:0; border-radius:10px; cursor:pointer;
  box-shadow:0 4px 12px rgba(37,99,235,.22); }
.vx-daterange .vx-dr-go:hover{ filter:brightness(1.05); }
/* iter5 UX: type context chip (Cotizaciones/Notas) — visual signal of which doc type the range applies to */
.vx-daterange .vx-dr-typechip{ display:inline-flex; align-items:center; gap:6px; padding:6px 12px; margin-right:2px;
  font-size:13px; font-weight:700; color:#1e293b; background:#eff6ff; border:1px solid #bfdbfe; border-radius:999px;
  white-space:nowrap; }
@media (max-width:820px){
  .vx-daterange .vx-dr-field{ flex:1 1 calc(50% - 5px); }
  .vx-daterange .vx-dr-input{ width:100%; }
  .vx-daterange .vx-dr-go{ margin-left:0; flex:1 1 100%; min-height:46px; }
  .vx-daterange .vx-dr-typechip{ flex:1 1 100%; justify-content:center; }
}

/* DESKTOP fit for auto-chromed pages: the legacy frame (#gridContainer fixed side-cells + the
   window.width-sized wrapper) overflows the viewport by ~26px → horizontal scrollbar. Cap it. */
@media (min-width:821px){
  body.vx-chrome{ overflow-x:hidden; }
  /* the page scroll root is <html>, NOT body — body{overflow-x:hidden} alone does NOT stop the legacy
     corner-frame table (tbl_bckgrnd_brite, ~window-width + corner cells) from giving a real ~6–26px
     horizontal scrollbar. Clip at the scroll root. :has is supported in the pilot's Chrome and degrades
     gracefully (rule ignored → pre-existing behavior, no regression) on older engines. */
  html:has(body.vx-chrome), html:has(body.vx-on){ overflow-x:hidden; }
  body.vx-chrome #gridContainer, body.vx-on #gridContainer{ width:100%!important; max-width:100%!important; }
  body.vx-chrome [id^="div_wrapper_"], body.vx-on [id^="div_wrapper_"]{ max-width:100%!important; overflow-x:auto; }
}

/* ============================================================================
   GRIDS PREMIUM — DESKTOP (>=821px), pilot-only (this file loads only under vx_redesign()). Every jqGrid
   (.ui-jqgrid) becomes a premium data table in the SAME language as the consultacfd document: one elevated
   container, a calm uppercase muted header row, hairline-separated rows, soft zebra + hover. We touch ONLY
   chrome (background / color / border / VERTICAL padding) and NEVER column widths or horizontal padding — jqGrid
   keeps its own table-layout:fixed width model, so the split header(htable)/body(btable) column alignment is
   preserved (measured: th left == td left ±1px). Scoped to both tiers (vx-chrome autochrome + vx-on). [Step 02]
   ============================================================================ */
@media (min-width:821px){
  /* breathing room so the card doesn't hug the viewport edges (premium = generous margins) */
  body.vx-chrome #gridContainer, body.vx-on #gridContainer{ padding:6px 26px 40px!important; box-sizing:border-box; }
  /* the grid container -> elevated card */
  body.vx-chrome .ui-jqgrid, body.vx-on .ui-jqgrid{
    background:var(--vx-card)!important; border:1px solid var(--vx-line)!important; border-radius:var(--vx-radius-lg)!important;
    box-shadow:var(--vx-shadow)!important; overflow:hidden; font-family:var(--vx-font); margin:4px 0 0!important; }
  /* strip jQuery-UI gradients/borders off the view + header/body divs so the card surface shows through */
  body.vx-chrome .ui-jqgrid-view, body.vx-on .ui-jqgrid-view,
  body.vx-chrome .ui-jqgrid-hdiv, body.vx-on .ui-jqgrid-hdiv,
  body.vx-chrome .ui-jqgrid-hbox, body.vx-on .ui-jqgrid-hbox,
  body.vx-chrome .ui-jqgrid-bdiv, body.vx-on .ui-jqgrid-bdiv{ background:transparent!important; border:0!important; }
  /* let the body GROW (no internal vertical scrollbar) — the page scrolls instead. This also makes the body table
     the SAME width as the header table (an internal scrollbar would render btable ~15px narrower and drift the
     column alignment). No nested scroll reads more premium too. (Per page jqGrid caps rows, so height is bounded.) */
  body.vx-chrome .ui-jqgrid-bdiv, body.vx-on .ui-jqgrid-bdiv{ height:auto!important; max-height:none!important; overflow:visible!important; }
  /* header row -> calm uppercase muted, LEFT-aligned, airy */
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th, body.vx-on .ui-jqgrid .ui-jqgrid-htable th{
    background:var(--vx-surface-2)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important;
    color:var(--vx-mut)!important; font:700 11px/1.35 var(--vx-font)!important; letter-spacing:.04em; text-transform:uppercase;
    text-align:left!important; padding:13px 16px!important; box-sizing:border-box!important; }
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th .ui-jqgrid-sortable,
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th .ui-jqgrid-sortable{ color:var(--vx-mut)!important; text-align:left!important; }
  /* body cells -> ink text, LEFT-aligned, GENEROUS height, hairline rows, no legacy vertical borders/gradients */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td{
    border-color:var(--vx-line)!important; border-right:0!important; color:var(--vx-ink); text-align:left!important;
    padding:13px 16px!important; vertical-align:middle; background-image:none!important; font-size:13.5px; box-sizing:border-box!important; }
  /* the per-column filter inputs row must also box-size so its cells don't drift the header width */
  body.vx-chrome .ui-jqgrid .ui-search-toolbar th, body.vx-on .ui-jqgrid .ui-search-toolbar th{ box-sizing:border-box!important; }
  /* jqGrid sizes the BODY table from its hidden first "measuring" row (tr.jqgfirstrow). It is NOT a .jqgrow, so the
     padding/border-box rules above miss it — leaving it content-box with legacy padding, which inflates every body
     column ~5px and drifts it right of the header. Zero its padding + border-box so body columns == header widths. */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgfirstrow>td, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgfirstrow>td{
    box-sizing:border-box!important; padding:0!important; }
  /* clean white rows + hairline + a calm hover (no zebra — premium reads cleaner) */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow:nth-child(2n), body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow:nth-child(2n){ background:var(--vx-card)!important; }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow:hover>td, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow:hover>td{ background:var(--vx-surface-2)!important; }
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow.ui-state-highlight>td, body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow.ui-state-highlight>td{ background:#eef4fc!important; }

  /* IDENTITY cell (vx-grid.js): monogram avatar + name anchor (the signature premium touch) */
  body.vx-chrome .ui-jqgrid-btable td.vx-idcell, body.vx-on .ui-jqgrid-btable td.vx-idcell{ padding-top:10px!important; padding-bottom:10px!important; }
  body.vx-chrome .vx-idwrap, body.vx-on .vx-idwrap{ display:inline-flex; align-items:center; gap:12px; min-width:0; max-width:100%; }
  body.vx-chrome .vx-ava, body.vx-on .vx-ava{ flex:none; width:36px; height:36px; border-radius:50%; display:inline-flex; align-items:center; justify-content:center; font:600 13px/1 var(--vx-font); letter-spacing:.02em; }
  body.vx-chrome .vx-idname, body.vx-on .vx-idname{ min-width:0; font-size:14px; font-weight:600; color:var(--vx-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  body.vx-chrome .vx-idname a, body.vx-on .vx-idname a{ color:var(--vx-ink)!important; text-decoration:none; }
  body.vx-chrome .ui-jqgrid-btable td.vx-idcell:hover .vx-idname a, body.vx-on .ui-jqgrid-btable td.vx-idcell:hover .vx-idname a{ color:var(--vx-accent-d)!important; }

  /* secondary identifier (RFC) -> muted monospace, recedes under the name */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="rfc" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="rfc" i]{
    color:var(--vx-mut)!important; font-family:ui-monospace,Menlo,Consolas,monospace; font-size:12.5px; letter-spacing:.01em; }
  /* dates never wrap to two ugly lines in a narrow column */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_db" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_db" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="fecha" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="cambio" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_db" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_db" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="fecha" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="cambio" i]{ white-space:nowrap!important; padding-left:10px!important; padding-right:10px!important; font-size:12.5px; color:var(--vx-mut)!important; }
  /* header labels WRAP to a second line instead of trimming ("TIMBRADO"->"TIM", "TOTAL PESOS" etc.) in the
     dense document grids. Bottom-aligned so multi-line headers sit on the same baseline as single-line ones. */
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th, body.vx-on .ui-jqgrid .ui-jqgrid-htable th{
    white-space:normal!important; overflow:visible; vertical-align:bottom!important; line-height:1.25!important; }
  /* footer totals row (.ui-jqgrid-ftable) must box-size + match body padding so the Totales line up under the
     money columns (the footer table was rendering ~69px wider than the body and drifting the totals). */
  body.vx-chrome .ui-jqgrid-ftable td, body.vx-on .ui-jqgrid-ftable td{
    box-sizing:border-box!important; padding:11px 16px!important; vertical-align:middle!important;
    border:0!important; border-top:1px solid var(--vx-line)!important; background:var(--vx-surface-2)!important; }
  body.vx-chrome .ui-jqgrid-sdiv, body.vx-on .ui-jqgrid-sdiv{ overflow:visible!important; }

  /* per-column filter row -> refined (rounded, subtle) instead of raw boxes */
  body.vx-chrome .ui-jqgrid .ui-search-toolbar th, body.vx-on .ui-jqgrid .ui-search-toolbar th{
    background:var(--vx-card)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important; padding:8px 14px!important; }
  body.vx-chrome .ui-jqgrid .ui-search-toolbar input, body.vx-chrome .ui-jqgrid .ui-search-toolbar select,
  body.vx-on .ui-jqgrid .ui-search-toolbar input, body.vx-on .ui-jqgrid .ui-search-toolbar select{
    width:100%!important; box-sizing:border-box; height:34px!important; border:1px solid var(--vx-line)!important;
    border-radius:9px!important; background:var(--vx-surface-2)!important; color:var(--vx-ink)!important;
    font:400 13px var(--vx-font)!important; padding:0 11px!important; }
  body.vx-chrome .ui-jqgrid .ui-search-toolbar input:focus, body.vx-on .ui-jqgrid .ui-search-toolbar input:focus{
    border-color:var(--vx-accent)!important; box-shadow:0 0 0 3px rgba(37,99,235,.12)!important; outline:0; background:var(--vx-card)!important; }
}

/* ============================================================================
   EMISOR PICKER (emisores.php) — a clean, tappable NAME-FIRST list, not a 5-field labeled card.
   The generic jqGrid transform stamps NOMBRE:/RFC:/FACTURA:/ENTERPRISE:/ALTA: on every one of ~50 rows = eye
   strain, and wrong for a picker (you just tap a company). Here: big name, small RFC, drop the rest + the labels.
   ============================================================================ */
@media (max-width:820px){
  /* Ancestors (.ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable) are added ONLY to out-specify the generic card rule's
     double :not() so these picker rules win. HIDE every cell by default (incl. the hidden EmisorID/encEmisorID
     GUID columns + tipo/enterprise/alta noise), then WHITELIST name + rfc. Never blanket display:block jqGrid cells. */
  body.vx-page-emisores .ui-jqgrid-btable>tbody>tr.jqgrow{ padding:16px 40px 16px 18px; position:relative; }
  /* chevron affordance: this is a PICKER — the card must look tappable */
  body.vx-page-emisores .ui-jqgrid-btable>tbody>tr.jqgrow::after{
    content:"\203A"; position:absolute; right:16px; top:50%; transform:translateY(-58%);
    font-size:26px; line-height:1; color:#9fb0c5; font-family:var(--vx-font); }
  body.vx-page-emisores .ui-jqgrid-btable>tbody>tr.jqgrow:active{ background:#eef4ff!important; border-color:#bcd0f0!important; }
  body.vx-page-emisores .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby]{ display:none!important; }
  body.vx-page-emisores .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td::before{ content:none!important; }
  body.vx-page-emisores .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre"]{
    display:block!important; border:0!important; padding:0!important; text-align:left!important; white-space:normal!important;
    font-size:17px; font-weight:800; color:#0b1526; line-height:1.3; font-family:var(--vx-font); }
  body.vx-page-emisores .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_rfc"]{
    display:block!important; border:0!important; padding:0!important; text-align:left!important; white-space:normal!important;
    font-size:13px; font-weight:600; color:#51627a; margin-top:4px; letter-spacing:.05em; font-family:var(--vx-font); }
}

/* ============================================================================
   NVOCFD40 RESKIN v1 (the counter app) — CSS-ONLY, body.vx-page-nvocfd40, mobile ≤820.
   RESTYLE ONLY: zero changes to the PHP/fields/ids/JS/dogwatcher/validation/POST. The user's own
   nvocfd40-responsive layer does the width reflow; this harmonizes it with the app design language.
   ============================================================================ */
@media (max-width:820px){
  body.vx-page-nvocfd40 #divNvoCFD{ padding:0 4px; }
  /* page title: orange-italic legacy -> app ink, no italics */
  body.vx-page-nvocfd40 .txt_16px{ font-family:var(--vx-font); font-size:20px!important; line-height:1.25; padding:6px 8px 2px; display:block; }
  body.vx-page-nvocfd40 .txt_16px em, body.vx-page-nvocfd40 .txt_16px strong{ font-style:normal!important; color:#0b1526!important; }
  body.vx-page-nvocfd40 .txt_16px em.txt_orangecolor{ color:#0b1526!important; }
  /* section legends ("Datos del Receptor:") + section title cells -> app section headers */
  body.vx-page-nvocfd40 fieldset{ border:0!important; margin:0; padding:0; }
  body.vx-page-nvocfd40 legend.tbl_title, body.vx-page-nvocfd40 td.tbl_title{
    background:transparent!important; border:0!important; padding:14px 4px 6px!important;
    font-family:var(--vx-font)!important; font-size:12.5px!important; font-weight:800!important;
    letter-spacing:.06em; text-transform:uppercase; color:#5d7290!important; }
  body.vx-page-nvocfd40 legend.tbl_title em, body.vx-page-nvocfd40 td.tbl_title em,
  body.vx-page-nvocfd40 td.tbl_title strong{ font-style:normal!important; color:inherit!important; }
  /* labels: one voice (Inter, slate), keep the red required star */
  body.vx-page-nvocfd40 #NvoCFD strong{ font-family:var(--vx-font); font-size:13.5px; color:#334155; }
  body.vx-page-nvocfd40 #NvoCFD .txt_redcolor{ color:var(--vx-crit)!important; }
  /* fields: touch-sized, app-styled (16px also kills mobile zoom-on-focus) */
  body.vx-page-nvocfd40 #NvoCFD input[type="text"],
  body.vx-page-nvocfd40 #NvoCFD select,
  body.vx-page-nvocfd40 #NvoCFD textarea{
    min-height:46px; font-size:16px!important; font-family:var(--vx-font);
    padding:8px 12px!important; border:1.5px solid #cbd5e1!important; border-radius:10px!important;
    background:#fff; box-sizing:border-box; margin:3px 0 7px; }
  body.vx-page-nvocfd40 #NvoCFD textarea{ min-height:74px; }
  body.vx-page-nvocfd40 #NvoCFD input.readonly, body.vx-page-nvocfd40 #NvoCFD input[readonly]{
    background:#f1f5f9!important; color:#475569; border-color:#dbe3ec!important; }
  body.vx-page-nvocfd40 #NvoCFD input:focus, body.vx-page-nvocfd40 #NvoCFD select:focus,
  body.vx-page-nvocfd40 #NvoCFD textarea:focus{ outline:none; border-color:var(--vx-accent)!important;
    box-shadow:0 0 0 3px rgba(37,99,235,.12); }
  /* sections as cards */
  body.vx-page-nvocfd40 #DatosReceptor, body.vx-page-nvocfd40 #TablaCamposCFDI,
  body.vx-page-nvocfd40 #Totales{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:10px 12px!important; margin:6px 0 12px; box-shadow:0 1px 3px rgba(16,24,40,.06),0 8px 22px rgba(16,24,40,.06); }
  /* conceptos: contained card with its own horizontal scroll (table structure untouched for cfd.js) */
  body.vx-page-nvocfd40 #scrollconceptos{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:8px!important; margin:6px 0 12px; max-height:60vh!important; overflow:auto!important;
    height:auto!important; min-height:70px; /* empty list collapses instead of reserving a 350px void */ }
  body.vx-page-nvocfd40 #Conceptos{ min-width:640px; }
  body.vx-page-nvocfd40 td.tbl_title_1{
    background:#eef2f7!important; color:#334155!important; font-family:var(--vx-font);
    font-size:11.5px!important; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
    padding:7px 6px!important; border:0!important; }
  /* the tiny 20px "Modificar datos del Cliente" icon: real tap target + a visible label */
  body.vx-page-nvocfd40 a:has(> img[src*="20-edit"]){
    display:inline-flex; align-items:center; gap:6px; min-height:40px; padding:6px 12px;
    background:#eff6ff; border:1px solid #bfdbfe; border-radius:999px; text-decoration:none;
    font-family:var(--vx-font); font-size:13px; font-weight:700; color:#1d4ed8!important; margin:4px 0; }
  body.vx-page-nvocfd40 a:has(> img[src*="20-edit"])::after{ content:"Editar datos del cliente"; }
  body.vx-page-nvocfd40 a:has(> img[src*="20-edit"]) img{ width:16px!important; height:16px!important; }
  /* big legacy action icons in the totals row: comfortable tap targets, centered */
  body.vx-page-nvocfd40 a:has(> img[src*="48-tache"]), body.vx-page-nvocfd40 #hrefConfirmaCFD33{
    display:inline-flex; padding:6px; }
  /* the add-concepto dialog inherits the field styling via #CFD_CONCEPTO */
  body.vx-page-nvocfd40 #CFD_CONCEPTO input[type="text"], body.vx-page-nvocfd40 #CFD_CONCEPTO select,
  body.vx-page-nvocfd40 #CFD_CONCEPTO textarea{
    min-height:44px; font-size:16px!important; font-family:var(--vx-font);
    padding:8px 12px!important; border:1.5px solid #cbd5e1!important; border-radius:10px!important; box-sizing:border-box; }

  /* ---- TOTALS: one line per total (the legacy inline @media768 stacks each <td> -> 3 lines each) -------------
     Each totals row is [label] [middle %/blank] [$ + amount]. We turn the <tr> into a wrapping flex ledger row:
     label on the left, the $ amount on the right, on ONE line. The big Observaciones cell (rowspan=12) keeps its
     own full-width line via flex-basis:100%. Structure/ids/JS untouched -- pure layout.
     NOTE: the legacy rules live in an inline <style> that loads AFTER this file, so at equal specificity they win
     the tie. We add the always-present `.nvocfd40-responsive` body class to every selector -> (1 id, 2 class) beats
     the legacy (1 id, 1 class) cleanly, no source-order dependence. */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr{
    display:flex!important; flex-wrap:wrap; align-items:center; justify-content:space-between;
    gap:2px 10px; padding:7px 2px!important; border-bottom:1px solid #eef2f7; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td{
    display:block!important; width:auto!important; flex:0 0 auto; text-align:left;
    padding:0!important; border:0!important; }
  /* the label cell grows and pushes the amount to the right edge */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_rightaligned{ flex:1 1 auto; width:auto!important; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_rightaligned > strong{ font-size:14px; color:#334155; font-weight:700; }
  /* amount value cell: shrink to content, right side; NOT the legacy 100%-wide cell */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_leftaligned{
    display:inline-flex!important; align-items:center; gap:4px; width:auto!important; flex:0 0 auto; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_leftaligned > strong{ color:#64748b; }
  /* the % / middle cell (Descuento / Retenciones) stays inline + narrow */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_centered{ width:auto!important; flex:0 0 auto; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td.txt_centered input{ width:74px!important; max-width:74px!important; min-height:40px; text-align:right!important;
    padding:6px 8px!important; border:1.5px solid #cbd5e1!important; border-radius:9px!important; box-sizing:border-box; }
  /* the amount fields: app-styled, compact, right-aligned (beat legacy input{width:100%!important}) */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales input[type="text"]{
    width:128px!important; max-width:44vw!important; min-height:40px; font-size:15px!important; text-align:right!important;
    padding:6px 10px!important; border:1.5px solid #cbd5e1!important; border-radius:9px!important; box-sizing:border-box; margin:0!important; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales input.readonly,
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales input[readonly]{ background:#f1f5f9!important; color:#334155; border-color:#dbe3ec!important; }
  /* the Observaciones block (rowspan=12) gets its OWN full-width line, not jammed beside Suma */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td[rowspan]{ flex:1 1 100%!important; width:100%!important; order:-1; height:auto!important; }
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr > td[rowspan] #Observaciones{ width:100%!important; }
  /* drop the empty spacer row whose only payload is the hidden #motivoDescuento field (blank bordered gap) */
  body.vx-page-nvocfd40.nvocfd40-responsive #Totales > tbody > tr:has(> td > #motivoDescuento){ display:none!important; }
}

/* ============================================================================
   STYLE15 FORM RESKIN — shared premium form block. CSS-ONLY, gated (this file loads only under vx_redesign()),
   width-agnostic (desktop + mobile). RESTYLE ONLY: zero changes to form names/fields/ids/JS/POST — the legacy
   `tbl_bckgrnd_brite` corner-frame + `style15` label/input table become a premium centered card with stacked
   premium fields + labeled actions. Scoped to body.vx-chrome :is(the 3 style15-form pages) — 2-class specificity,
   out-ranks the legacy theme CSS.
     D5: nvoemisor (alta de Emisor; form[name=NvoEmisor]; save = <a><img 48-save>).
     D3: nvoseriesyfolios + modseriesyfolios (alta/edición de Series y Folios; form[name=ModSeriesFolios];
         save = <input type="image" 48-save> — gets the accent-pill rule below since <input> can't take ::after).
   ============================================================================ */
  /* center wrapper -> normal flow; drop the legacy 994px corner-frame to a contained premium card */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) > div[align="center"]{ text-align:left!important; padding:0 12px; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite{
    width:100%!important; max-width:680px!important; margin:14px auto 28px!important; border-collapse:separate;
    background:var(--vx-card)!important; border:1px solid var(--vx-line)!important; border-radius:var(--vx-radius-lg)!important;
    box-shadow:var(--vx-shadow)!important; overflow:hidden; font-family:var(--vx-font); }
  /* hide the decorative corner-gif rows (top + bottom) — the card has real corners now */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner),
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_bottom_corner){ display:none!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite > tbody > tr > td{
    display:block!important; width:auto!important; max-width:100%!important; padding:0!important; background:transparent!important; }
  /* the masthead row (logo + home icon) is redundant under the app-bar (brand + Menú/Salir already there) — hide the
     whole row so the card opens straight on the form, not on an ~80px empty band. (The form's own Back-to-emisores +
     the app-bar nav preserve every route.) */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite > tbody > tr:has(img[src="images/logo.png"]){ display:none!important; }
  /* + the legacy &nbsp; spacer row right after it (a ~54px empty band before the form) */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.tbl_bckgrnd_brite > tbody > tr:has(img[src="images/logo.png"]) + tr{ display:none!important; }
  /* intro copy -> calm muted lede */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style5{ font-family:var(--vx-font)!important; color:var(--vx-mut)!important;
    font-size:13.5px!important; line-height:1.55; padding:4px 20px!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style5 strong{ color:var(--vx-ink)!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) .style17{ color:var(--vx-crit,#dc2626)!important; }
  /* the form table -> stacked rows (label above field), generous spacing */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]){ padding:6px 20px 18px; display:block; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15{ width:100%!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 > tbody > tr{ display:block!important; margin:0 0 12px; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 > tbody > tr > td{
    display:block!important; width:auto!important; padding:0!important; border:0!important; background:transparent!important; }
  /* "Datos generales:" section label */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 td.style5:first-child + td.style5,
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 td.style5{ font-size:12px!important; font-weight:800!important;
    letter-spacing:.06em; text-transform:uppercase; color:#5d7290!important; padding:6px 0 2px!important; }
  /* field labels (td.style14 -> calm uppercase) */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style14{ padding:0 0 5px!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style14 strong{ font-family:var(--vx-font); font-size:12.5px; font-weight:700;
    letter-spacing:.03em; color:#475569; }
  /* premium fields (full width, touch-sized, focus ring) — 16px also kills mobile zoom-on-focus */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]) input[type="text"],
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]) input[type="password"],
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]) select{
    width:100%!important; max-width:100%!important; box-sizing:border-box; min-height:46px;
    font-size:16px!important; font-family:var(--vx-font); color:var(--vx-ink);
    padding:10px 13px!important; border:1.5px solid #cbd5e1!important; border-radius:11px!important; background:#fff; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]) input:focus,
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) :is(form[name="NvoEmisor"],form[name="ModSeriesFolios"]) select:focus{
    outline:none; border-color:var(--vx-accent)!important; box-shadow:0 0 0 3px rgba(37,99,235,.12); }
  /* dividers (td.style2 hr) -> calm hairline */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style2 hr{ border:0!important; border-top:1px solid var(--vx-line)!important; margin:4px 0!important; color:transparent; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style2 br{ display:none; }
  /* action row -> LABELED pill buttons (a Necio user must see which one saves). The bare floppy/arrow icons are
     hidden; the <a> keeps its href/onclick. Save = primary (accent), Cancelar = secondary (ghost). Save first so the
     primary action leads. */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 > tbody > tr:has(td.style16){ display:flex!important;
    flex-direction:row-reverse; justify-content:flex-end; align-items:center; gap:12px; margin-top:14px; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 > tbody > tr:has(td.style16) > td{ display:inline-flex!important; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style16 a,
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 a:has(> img[src*="48-save"]){
    display:inline-flex!important; align-items:center; justify-content:center; gap:8px; min-height:46px;
    padding:11px 22px; border-radius:999px; font-family:var(--vx-font); font-weight:700; font-size:14px;
    text-decoration:none; cursor:pointer; transition:filter .12s, background .12s; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style16 a img,
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 a:has(> img[src*="48-save"]) img{ display:none!important; }
  /* Guardar — primary */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 a:has(> img[src*="48-save"]){
    background:linear-gradient(120deg,var(--vx-accent),var(--vx-accent-d)); color:#fff!important; box-shadow:0 6px 16px rgba(37,99,235,.25); }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 a:has(> img[src*="48-save"]):hover{ filter:brightness(1.06); }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) table.style15 a:has(> img[src*="48-save"])::after{ content:"Guardar"; }
  /* Cancelar — secondary/ghost */
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style16 a{ background:var(--vx-surface-2); color:#475569!important; border:1px solid var(--vx-line); }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style16 a:hover{ background:#eef2f7; }
  body.vx-chrome:is(.vx-page-nvoemisor,.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios) td.style16 a::after{ content:"Cancelar"; }
  /* D3 forms: the save control is <input type="image" src=48-save> (can't take ::after / can't hide the image
     part) — so style the input itself as the primary accent pill (the floppy glyph rides on it; the intro copy
     "da clic en la imagen de Guardar" labels it). Same look-and-feel as the nvoemisor <a> Guardar pill. */
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.style15 input[type="image"][src*="48-save"]{
    box-sizing:border-box; min-height:46px; padding:7px 22px; border:0; border-radius:999px; cursor:pointer;
    background:linear-gradient(120deg,var(--vx-accent),var(--vx-accent-d)); box-shadow:0 6px 16px rgba(37,99,235,.25);
    transition:filter .12s; }
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.style15 input[type="image"][src*="48-save"]:hover{ filter:brightness(1.06); }

/* ============================================================================
   CFDI CREATION FORMS RESKIN — CSS-ONLY, mobile <=820. Shared :is() block for nvonomina + nvocfdpago33 +
   nvocfditraslado + nvocfditrasladocartaporte (+ nvacompra joins for the shared conceptos/totals/action rules).
   The CFDI nómina (payroll-receipt) creation form — twin of nvocfd40 (same #divNvoCFD/#NvoCFD/
   #DatosReceptor/#scrollconceptos/#Conceptos/#Totales ids, same tbl_title/tbl_title_1/txt_* classes),
   BUT it ships NO own inline responsive layer — so this block ALSO carries the WIDTH REFLOW base
   (nvocfd40 got that from its inline <style>). No .nvocfd40-responsive specificity hack needed here
   (nothing to out-rank). RESTYLE ONLY: zero changes to PHP/fields/ids/JS — concJSON, agregaConceptoNomina,
   ConfirmaCFD33, the SDI/totals calc, the datepickers are all untouched.
   ============================================================================ */
@media (max-width:820px){
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD{ padding:0 4px; }
  /* ---- REFLOW BASE: collapse the fixed 1152px frame + its corner row to one fluid column ---- */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD > table.tbl_bckgrnd_brite,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD > table.tbl_bckgrnd_brite > tbody,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr > td{
    display:block!important; width:100%!important; box-sizing:border-box; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }
  /* page title: app ink, no italics (matches nvocfd40) */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) .txt_16px{ font-family:var(--vx-font); font-size:20px!important; line-height:1.25; padding:6px 8px 2px; display:block; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) .txt_16px em, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) .txt_16px strong{ font-style:normal!important; color:#0b1526!important; }
  /* section legends + title cells -> calm uppercase app section headers */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) fieldset{ border:0!important; margin:0; padding:0; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) legend.tbl_title, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title{
    background:transparent!important; border:0!important; padding:14px 4px 6px!important;
    font-family:var(--vx-font)!important; font-size:12.5px!important; font-weight:800!important;
    letter-spacing:.06em; text-transform:uppercase; color:#5d7290!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) legend.tbl_title em, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title em,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title strong{ font-style:normal!important; color:inherit!important; }
  /* labels one voice; keep the red required star */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD strong{ font-family:var(--vx-font); font-size:13.5px; color:#334155; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD .txt_redcolor{ color:var(--vx-crit)!important; }
  /* fields: touch-sized 16px app inputs (16px also kills iOS zoom-on-focus). Beats the inline width:NN% */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD input[type="text"],
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD select,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD textarea{
    width:100%!important; min-height:46px; font-size:16px!important; font-family:var(--vx-font);
    padding:8px 12px!important; border:1.5px solid #cbd5e1!important; border-radius:10px!important;
    background:#fff; box-sizing:border-box; margin:3px 0 7px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD textarea{ min-height:74px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD input.readonly, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD input[readonly]{
    background:#f1f5f9!important; color:#475569; border-color:#dbe3ec!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD input:focus, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD select:focus,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #divNvoCFD textarea:focus{ outline:none; border-color:var(--vx-accent)!important;
    box-shadow:0 0 0 3px rgba(37,99,235,.12); }
  /* sections as cards */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #DatosReceptor, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #TablaCamposCFDI,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:10px 12px!important; margin:6px 0 12px; box-shadow:0 1px 3px rgba(16,24,40,.06),0 8px 22px rgba(16,24,40,.06); }
  /* conceptos: contained card with its own horizontal scroll (table structure untouched) */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #scrollconceptos{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:8px!important; margin:6px 0 12px; max-height:60vh!important; overflow:auto!important;
    height:auto!important; min-height:70px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Conceptos{ min-width:640px; }
  /* the standalone 6-col conceptos header squishes to illegible vertical text at 390px AND doesn't align
     with the horizontally-scrolled #Conceptos data — hide it on mobile (nómina's single auto
     "PAGO DE NÓMINA" line is self-evident; the money lives in the Totales ledger below). */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #ConceptosTitulos > tbody > tr:has(> td.tbl_title_1){ display:none!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title_1{
    background:#eef2f7!important; color:#334155!important; font-family:var(--vx-font);
    font-size:11.5px!important; font-weight:700; text-transform:uppercase; letter-spacing:.04em;
    padding:7px 6px!important; border:0!important; }
  /* nómina-only: stack the two 49% desglose floats (Percepción / Deducción) to full width */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #rPercepcion_div, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #rDeduccion_div{
    float:none!important; width:100%!important; margin:0 0 10px!important; border:1px solid #d8e0ea!important;
    border-radius:12px; padding:8px 10px; box-sizing:border-box; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #rPercepcion_tbl th, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #rDeduccion_tbl th{
    font-family:var(--vx-font); font-size:11.5px; color:#5d7290; text-transform:uppercase; letter-spacing:.04em; }

  /* ---- TOTALES: one line per total (label left + $amount right), ported from nvocfd40 (no double-class
         needed — nvonomina has no inline totals style). Rows: Percepciones / Deducciones / Neto a pagar. ---- */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr{
    display:flex!important; flex-wrap:wrap; align-items:center; justify-content:space-between;
    gap:2px 10px; padding:7px 2px!important; border-bottom:1px solid #eef2f7; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td{
    display:block!important; width:auto!important; flex:0 0 auto; text-align:left; padding:0!important; border:0!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td.txt_rightaligned{ flex:1 1 auto; width:auto!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td.txt_rightaligned > strong{ font-size:14px; color:#334155; font-weight:700; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td.txt_leftaligned{
    display:inline-flex!important; align-items:center; gap:4px; width:auto!important; flex:0 0 auto; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td.txt_leftaligned > strong{ color:#64748b; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td.txt_centered{ width:auto!important; flex:0 0 auto; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales input[type="text"]{
    width:140px!important; max-width:46vw!important; min-height:42px; font-size:15px!important; text-align:right!important;
    padding:6px 10px!important; border:1.5px solid #cbd5e1!important; border-radius:9px!important; box-sizing:border-box; margin:0!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales input.readonly, body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales input[readonly]{
    background:#f1f5f9!important; color:#334155; border-color:#dbe3ec!important; }
  /* the Observaciones block (rowspan=6) gets its OWN full-width line */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td[rowspan]{ flex:1 1 100%!important; width:100%!important; order:-1; height:auto!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr > td[rowspan] #Observaciones,
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales #Observaciones1{ width:100%!important; }
  /* NETO A PAGAR = the emphasized grand total */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr:has(#NetoaPagar) > td.txt_rightaligned > strong{ color:var(--vx-accent-d); font-size:16px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr:has(#NetoaPagar) #NetoaPagar{ color:var(--vx-accent-d); font-weight:800; }
  /* footer actions: Generar (48-palomita) is the full-width primary; Home/Limpiar = secondary chips */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales > tbody > tr:has(a > img[src*="48-palomita"]){ justify-content:center; gap:14px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="48-palomita"]){
    display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:50px; padding:10px 22px;
    background:var(--vx-accent); border-radius:14px; text-decoration:none; box-shadow:0 6px 18px rgba(37,99,235,.28); }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="48-palomita"])::after{ content:"Generar Recibo"; font-family:var(--vx-font); font-weight:800; font-size:15px; color:#fff; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="48-palomita"]) img{ width:26px!important; height:26px!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="48-tache"]){
    display:inline-flex; align-items:center; justify-content:center; min-height:50px; min-width:50px; padding:8px;
    background:#fff; border:1px solid #d8e0ea; border-radius:14px; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="48-tache"]) img{ width:24px!important; height:24px!important; }
  /* aguinaldo trigger -> labeled chip */
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="28-nomina-agui"]){
    display:inline-flex; align-items:center; gap:6px; min-height:42px; padding:6px 12px; margin:6px 0;
    background:#eff6ff; border:1px solid #bfdbfe; border-radius:999px; text-decoration:none;
    font-family:var(--vx-font); font-size:13px; font-weight:700; color:#1d4ed8!important; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="28-nomina-agui"])::after{ content:"Aguinaldo"; }
  body:is(.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) a:has(> img[src*="28-nomina-agui"]) img{ width:18px!important; height:18px!important; }
}

/* ============================================================================
   NVACOMPRA RESKIN — CSS-ONLY, body.vx-page-nvacompra, mobile <=820.
   The purchase (compra) creation form. It does NOT use the #divNvoCFD/#NvoCFD/#DatosReceptor skeleton:
   its frame is div[align=center] > table.tbl_bckgrnd_brite (994px), form #NvaCompra, sections
   #DatosProveedor/#MonedayTC. The SHARED rules (conceptos scroll-card, totals flex, action chips,
   header-hide, calm section headers) already reach it via the :is() group above; this block adds the
   reflow base + inputs + proveedor/moneda cards it needs on its own ids. RESTYLE ONLY — no PHP/field/JS touch.
   ============================================================================ */
@media (max-width:820px){
  body.vx-page-nvacompra div[align="center"]{ padding:0 4px; }
  /* reflow base: collapse the 994px frame + its corner row to one fluid column */
  body.vx-page-nvacompra div[align="center"] > table.tbl_bckgrnd_brite,
  body.vx-page-nvacompra div[align="center"] > table.tbl_bckgrnd_brite > tbody,
  body.vx-page-nvacompra div[align="center"] > table.tbl_bckgrnd_brite > tbody > tr,
  body.vx-page-nvacompra div[align="center"] > table.tbl_bckgrnd_brite > tbody > tr > td{
    display:block!important; width:100%!important; box-sizing:border-box; }
  body.vx-page-nvacompra div[align="center"] > table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }
  /* fields: touch-sized 16px (kills iOS zoom), full-width — beats inline width:NN% */
  body.vx-page-nvacompra #NvaCompra input[type="text"],
  body.vx-page-nvacompra #NvaCompra select,
  body.vx-page-nvacompra #NvaCompra textarea{
    width:100%!important; min-height:46px; font-size:16px!important; font-family:var(--vx-font);
    padding:8px 12px!important; border:1.5px solid #cbd5e1!important; border-radius:10px!important;
    background:#fff; box-sizing:border-box; margin:3px 0 7px; }
  body.vx-page-nvacompra #NvaCompra input.readonly, body.vx-page-nvacompra #NvaCompra input[readonly]{
    background:#f1f5f9!important; color:#475569; border-color:#dbe3ec!important; }
  body.vx-page-nvacompra #NvaCompra input:focus, body.vx-page-nvacompra #NvaCompra select:focus,
  body.vx-page-nvacompra #NvaCompra textarea:focus{ outline:none; border-color:var(--vx-accent)!important;
    box-shadow:0 0 0 3px rgba(37,99,235,.12); }
  body.vx-page-nvacompra #NvaCompra strong{ font-family:var(--vx-font); font-size:13.5px; color:#334155; }
  body.vx-page-nvacompra #NvaCompra .txt_redcolor{ color:var(--vx-crit)!important; }
  /* proveedor + moneda sections as cards (the #Totales card comes from the shared :is() group) */
  body.vx-page-nvacompra #DatosProveedor, body.vx-page-nvacompra #MonedayTC{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:10px 12px!important; margin:6px 0 12px; box-shadow:0 1px 3px rgba(16,24,40,.06),0 8px 22px rgba(16,24,40,.06); }
  body.vx-page-nvacompra legend.tbl_title, body.vx-page-nvacompra td.tbl_title{
    background:transparent!important; border:0!important; padding:14px 4px 6px!important;
    font-family:var(--vx-font)!important; font-size:12.5px!important; font-weight:800!important;
    letter-spacing:.06em; text-transform:uppercase; color:#5d7290!important; }
  body.vx-page-nvacompra legend.tbl_title em, body.vx-page-nvacompra td.tbl_title em,
  body.vx-page-nvacompra td.tbl_title strong{ font-style:normal!important; color:inherit!important; }
  /* nvacompra's #Totales is NOT the label/amount ledger shape (it wraps a nested width:100% table + a
     textarea), so the shared totals-flex from the :is() group makes the nested table's width resolve to
     ~1e6px. Neutralize the flex here — keep #Totales a normal (reflowed) table. */
  body.vx-page-nvacompra #Totales > tbody > tr{ display:table-row!important; }
  body.vx-page-nvacompra #Totales > tbody > tr > td{ display:table-cell!important; width:auto!important; flex:none!important; }
  body.vx-page-nvacompra #Totales table{ max-width:100%!important; }
  /* footer actions: Generar (48-cart-OK -> ConfirmaCompra) = full-width primary pill; Limpiar (48-cart-BAD) = chip */
  body.vx-page-nvacompra a:has(> img[src*="48-cart-OK"]){
    display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:50px; padding:10px 22px;
    background:var(--vx-accent); border-radius:14px; text-decoration:none; box-shadow:0 6px 18px rgba(37,99,235,.28); }
  body.vx-page-nvacompra a:has(> img[src*="48-cart-OK"])::after{ content:"Generar Compra"; font-family:var(--vx-font); font-weight:800; font-size:15px; color:#fff; }
  body.vx-page-nvacompra a:has(> img[src*="48-cart-OK"]) img{ width:26px!important; height:26px!important; }
  body.vx-page-nvacompra a:has(> img[src*="48-cart-BAD"]){
    display:inline-flex; align-items:center; justify-content:center; min-height:50px; min-width:50px; padding:8px;
    background:#fff; border:1px solid #d8e0ea; border-radius:14px; }
  body.vx-page-nvacompra a:has(> img[src*="48-cart-BAD"]) img{ width:24px!important; height:24px!important; }
  body.vx-page-nvacompra img[src*="48-blank"]{ display:none!important; }
}

/* ============================================================================
   CREATION-FORMS per-form overrides (CSS-only, mobile <=820).
   The shared :is() block fits nvonomina + traslado + cartaporte (true label/amount + #NetoaPagar ledgers),
   but (a) nvocfdpago33's #Totales is a colspan summary (Monto del pago/aplicado/disponible), NOT the ledger
   shape — so neutralize the totals-flex there (keep it a normal table, like nvacompra); and (b) the shared
   48-palomita button is labelled "Generar Recibo" (nómina-specific) — relabel it per form.
   ============================================================================ */
@media (max-width:820px){
  /* (a) pago33 totals: revert the shared flex to a normal reflowed table (direct classed cells + inputs too) */
  body.vx-page-nvocfdpago33 #Totales > tbody > tr{ display:table-row!important; }
  body.vx-page-nvocfdpago33 #Totales > tbody > tr > td,
  body.vx-page-nvocfdpago33 #Totales > tbody > tr > td.txt_rightaligned,
  body.vx-page-nvocfdpago33 #Totales > tbody > tr > td.txt_leftaligned,
  body.vx-page-nvocfdpago33 #Totales > tbody > tr > td.txt_centered{
    display:table-cell!important; width:auto!important; flex:none!important; }
  body.vx-page-nvocfdpago33 #Totales input[type="text"]{ width:auto!important; max-width:none!important; }
  body.vx-page-nvocfdpago33 #Totales table{ max-width:100%!important; }
  /* (b) correct the primary-button copy per form (nvonomina keeps "Generar Recibo" from the shared rule) */
  body.vx-page-nvocfdpago33 a:has(> img[src*="48-palomita"])::after{ content:"Generar Pago"!important; }
  body.vx-page-nvocfditraslado a:has(> img[src*="48-palomita"])::after{ content:"Generar Traslado"!important; }
  body.vx-page-nvocfditrasladocartaporte a:has(> img[src*="48-palomita"])::after{ content:"Generar Carta Porte"!important; }
  body.vx-page-nvoretencion a:has(> img[src*="48-palomita"])::after{ content:"Generar Retención"!important; }
  /* (c) nvoretencion-only: its footer actions live in a nested table.txt_leftaligned that the reflow base never
     collapses, so table-layout:auto gave the colspan action cell only ~60px and the longer "Generar Retención"
     label wrapped letter-by-letter. Collapse just THIS action row's chain to block (the same move the reflow base
     makes elsewhere) so the cell spans full width, then make Generar a full-width primary over the Limpiar chip. */
  body.vx-page-nvoretencion #NvoCFD tr:has(> td a img[src*="48-palomita"]),
  body.vx-page-nvoretencion #NvoCFD tr:has(> td a img[src*="48-palomita"]) > td{ display:block!important; width:100%!important; }
  body.vx-page-nvoretencion #NvoCFD tr:has(> td a img[src*="48-palomita"]) > td:not(:has(a)){ display:none!important; } /* drop the empty spacer cell */
  body.vx-page-nvoretencion #NvoCFD td:has(> a img[src*="48-palomita"]){ text-align:center; }
  body.vx-page-nvoretencion a:has(> img[src*="48-palomita"]){ width:100%; box-sizing:border-box; }
  body.vx-page-nvoretencion a:has(> img[src*="48-palomita"])::after{ white-space:nowrap; }
}

/* ============================================================================
   CREATION-FORMS DESKTOP PREMIUM — CSS-ONLY, gated, desktop >=821.
   The 6 creation forms (nvocfd40 · nvonomina · nvocfdpago33 · nvocfditraslado · nvocfditrasladocartaporte ·
   nvacompra) got the mobile reskin above; on DESKTOP they still render in their NATIVE legacy multi-column
   layout (the generic frame-collapse rules are mobile-only @media<=820, verified by brace balance + live render:
   frameRadius 0, native 1152/1069px widths, no h-scroll). This block is PURELY ADDITIVE — it lays the legacy
   table on a premium centered SHEET and calms the 2010 blue-banner typography, WITHOUT touching any column
   `width` or `table-layout`, so nothing shifts. Ports the shipped consultacfd desktop-sheet vocabulary.
   FISCAL-SAFE: no PHP/JS/field/onclick touch; #NetoaPagar/#Totales are read for styling only.
   ============================================================================ */
@media (min-width:821px){
  /* calm page canvas + breathing room around the sheet (the frame's direct parent on all 6:
     #divNvoCFD[align=center] for the 5 CFDI forms, the top div[align=center] for nvacompra) */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion){ background:linear-gradient(180deg,#f4f7fb,var(--vx-bg)); }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) div[align="center"]:has(> table.tbl_bckgrnd_brite){ padding:26px 16px 56px!important; box-sizing:border-box; }
  /* frame -> premium centered sheet. NO width / NO table-layout change (native columns hold). */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) div[align="center"] > table.tbl_bckgrnd_brite{
    margin:0 auto!important; background:var(--vx-card)!important; border:1px solid var(--vx-line)!important;
    border-radius:var(--vx-radius-lg)!important; box-shadow:var(--vx-shadow)!important;
    border-collapse:separate!important; border-spacing:0!important; overflow:hidden; color:var(--vx-ink); font-family:var(--vx-font); }
  /* drop the 2010 corner-gif chrome — the card's own radius replaces it (logo/home cells kept) */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) img.tbl_top_corner,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) img.tbl_bottom_corner{ display:none!important; }
  /* page title -> calm app heading (no italics) */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) :is(.txt_16px,.txt_size14px){ font-family:var(--vx-font)!important; color:var(--vx-ink)!important; font-style:normal!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) :is(.txt_16px,.txt_size14px) em,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) :is(.txt_16px,.txt_size14px) strong{ font-style:normal!important; color:var(--vx-ink)!important; }
  /* section banners (Datos del Receptor / Proveedor / extra) -> calm uppercase app labels */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title{
    background:var(--vx-surface-2)!important; color:var(--vx-mut)!important; border:0!important;
    border-top:1px solid var(--vx-line)!important; border-bottom:1px solid var(--vx-line)!important;
    font-family:var(--vx-font)!important; font-weight:800!important; font-size:11.5px!important;
    letter-spacing:.06em; text-transform:uppercase; padding:11px 16px!important; text-align:left!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title em,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title strong{ font-style:normal!important; color:var(--vx-mut)!important; font-weight:800!important; }
  /* fieldset legends carry the same banner on some forms (nvocfd40 "Datos del Receptor:") — legends can't span
     a row, so render them as a clean uppercase section LABEL (not a blue tab), no border band. */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) legend.tbl_title{
    background:transparent!important; color:var(--vx-mut)!important; border:0!important;
    font-family:var(--vx-font)!important; font-weight:800!important; font-size:11.5px!important;
    letter-spacing:.06em; text-transform:uppercase; padding:2px 0 6px!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) legend.tbl_title em,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) legend.tbl_title strong{ font-style:normal!important; color:var(--vx-mut)!important; font-weight:800!important; }
  /* conceptos COLUMN headers -> calm uppercase band. Kill the blue on EVERY tbl_title_1 cell (incl. the
     OBSERVACIONES title-INPUT cell), but apply the uppercase header TYPOGRAPHY only to non-input header cells
     (:not(:has(> input))) — robust across the <strong><em> (nvonomina/nvacompra) and bare <em> (nvocfd40) markups. */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title_1{
    background:var(--vx-surface-2)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title_1:not(:has(> input)){
    color:var(--vx-mut)!important; font-family:var(--vx-font)!important; font-weight:800!important;
    font-size:11px!important; letter-spacing:.04em; text-transform:uppercase; padding:9px 8px!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title_1:not(:has(> input)) em,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) td.tbl_title_1:not(:has(> input)) strong{ font-style:normal!important; color:var(--vx-mut)!important; font-weight:800!important; }
  /* TOTALES: tabular money; #NetoaPagar = the emphasized grand total (pago33 has none -> no-op) */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales input{ font-variant-numeric:tabular-nums; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales #NetoaPagar{ color:var(--vx-accent-d)!important; font-weight:800!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvacompra,.vx-page-nvoretencion) #Totales tr:has(#NetoaPagar) > td.txt_rightaligned > strong{ color:var(--vx-accent-d)!important; }
  /* CONSERVATIVE input polish: nicer border/radius/focus, readonly muted. NO `width:` declaration — and box-sizing
     :border-box pins the OUTER box to the existing inline width, so table columns never shift. (Honest note: these
     pages are body.vx-chrome, where legacy inputs were the browser default content-box, so a pixel-width input
     loses the ~2px the default border used to add OUTSIDE the declared width → it renders ~2px narrower. That's a
     deliberate, cosmetic-only tightening; the alternative — content-box + padding/border — would GROW the box and
     risk overflowing the fixed cells.) */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD input[type="text"],
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD select,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD textarea,
  body.vx-page-nvacompra #NvaCompra input[type="text"],
  body.vx-page-nvacompra #NvaCompra select,
  body.vx-page-nvacompra #NvaCompra textarea{
    box-sizing:border-box; border:1px solid #cbd5e1!important; border-radius:8px!important;
    padding:4px 8px!important; background:#fff!important; font-family:var(--vx-font); }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD input.readonly,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD input[readonly],
  body.vx-page-nvacompra #NvaCompra input.readonly, body.vx-page-nvacompra #NvaCompra input[readonly]{
    background:#f1f5f9!important; color:#475569; border-color:#dbe3ec!important; }
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD input:focus,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD select:focus,
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfdpago33,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvoretencion) #divNvoCFD textarea:focus,
  body.vx-page-nvacompra #NvaCompra input:focus, body.vx-page-nvacompra #NvaCompra select:focus,
  body.vx-page-nvacompra #NvaCompra textarea:focus{ outline:none!important; border-color:var(--vx-accent)!important; box-shadow:0 0 0 3px rgba(37,99,235,.12)!important; }
}

/* ============================================================================
   CONSULTACFD / document-view RESKIN — CSS-ONLY, gated, mobile <=820.
   Surfaces: full-page consultacfd (body.vx-page-consultacfd) + sibling consultacompra
   (body.vx-page-consultacompra) + the AJAX dialog (body.vx-chrome #CFD, opened from the emitidos grid).
   The legacy view is a 900px FIXED table with teal `tbl_title_1` banners and 50/50 float columns — crushed on a
   phone. We make the frame fluid, stack the float halves, restyle banners to the app language, and put the
   6-column conceptos table in a horizontal-scroll card. ZERO PHP edits (autochrome supplies the slug). Desktop
   (>=821) keeps the legacy look untouched. The print/PDF "ticket" tables (mm widths) live OUTSIDE the 900px
   frame, so the frame-descendant selectors never touch them.
   ============================================================================ */
@media (max-width:820px){
  /* --- frame -> fluid. KEEP .table_fixed's own table-layout:fixed (it scales the 10/880/10 columns
         proportionally to the phone width). Forcing table-layout:auto here + hiding the spacer cells broke the
         column model and collapsed the content column to ~0 (text wrapped one char per line). So: width only. --- */
  /* --- HARD safety net: no horizontal page scroll on a phone, ever. The only overflow-x:hidden in this file was
         desktop-only (@media min-width:821px), so phones had no clamp -> a single leaking child shifted the whole
         page. Clamp the consulta surfaces themselves (scoped to vx, so legacy pages are untouched). --- */
  body.vx-page-consultacfd, body.vx-page-consultacompra{ overflow-x:hidden!important; max-width:100%; }
  body.vx-chrome #CFD{ overflow-x:hidden!important; max-width:100%; }
  /* the consulta dialog (#CFD becomes a jQuery UI .ui-dialog, opened from the emitidos grid — auto on a single
     result) had a hardcoded 930px width; cfd.js now caps it to the viewport, and this is the CSS belt: no jQuery
     UI dialog on a chromed phone may exceed the screen. */
  body.vx-chrome .ui-dialog{ max-width:100vw!important; box-sizing:border-box; }
  body.vx-chrome .ui-dialog.vx-doc-dialog{ width:100%!important; max-width:100vw!important; box-sizing:border-box; }
  /* the element that actually scrolled in the dialog is .ui-dialog-content (clientWidth 388, scrollWidth 938) */
  body.vx-chrome .ui-dialog .ui-dialog-content{ overflow-x:hidden!important; max-width:100%!important; box-sizing:border-box!important; }
  /* === DIALOG/FULL-PAGE PARITY ===  #CFD.vx-doc must FILL the dialog box (NOT shrink to its 900px child), so the
     frame's width:100% resolves against a real width instead of against the 900 table itself (the self-referential
     base that left the frame at 924). This REPLACES the old width:auto, which made #CFD shrink-wrap the table. */
  body.vx-chrome #CFD.vx-doc{ width:100%!important; max-width:100%!important; box-sizing:border-box; padding:0!important; overflow-x:hidden!important; }
  /* the consultacfd.php:470 wrapper (now .vx-doc-frame) was display:block;width:auto (shrink-to-fit the 900
     table). Force it to fill so the frame's 100% has a concrete base in BOTH render modes. */
  body.vx-page-consultacfd .vx-doc-frame, body.vx-page-consultacompra .vx-doc-frame,
  body.vx-chrome #CFD.vx-doc .vx-doc-frame{ width:100%!important; max-width:100%!important; box-sizing:border-box; }
  /* FULL-WIDTH on mobile: the legacy doc is one table.table_fixed with a 10px/880px/10px column model. Under
     table-layout:fixed at phone width that model collapsed the CONTENT into a ~31% center column (measured: every
     section 119px of 382) with dead gutters either side — "one thin column running down". Fix: drop the table
     column model entirely on a phone — stack the table / tbody / tr / direct-td as FULL-WIDTH blocks (same proven
     technique as the conceptos table). Every section then fills the frame. The 10px gutter cells are removed; the
     nested conceptos/totals/cert tables live DEEPER (inside a content td) so they keep their own layout. */
  body.vx-page-consultacfd table[style*="900px"],
  body.vx-page-consultacompra table[style*="900px"],
  body.vx-chrome #CFD table[style*="900px"]{ display:block!important; width:100%!important; max-width:100%!important; box-sizing:border-box!important; border-radius:14px; }
  body.vx-page-consultacfd table[style*="900px"] > tbody, body.vx-page-consultacompra table[style*="900px"] > tbody,
  body.vx-chrome #CFD table[style*="900px"] > tbody{ display:block!important; width:100%!important; }
  body.vx-page-consultacfd table[style*="900px"] > tbody > tr, body.vx-page-consultacompra table[style*="900px"] > tbody > tr,
  body.vx-chrome #CFD table[style*="900px"] > tbody > tr{ display:block!important; width:100%!important; }
  body.vx-page-consultacfd table[style*="900px"] > tbody > tr > td, body.vx-page-consultacompra table[style*="900px"] > tbody > tr > td,
  body.vx-chrome #CFD table[style*="900px"] > tbody > tr > td{ display:block!important; width:100%!important; max-width:100%!important; box-sizing:border-box!important; }
  /* drop the pure-spacer gutter cells (10px) — they'd otherwise be empty full-width blocks */
  body.vx-page-consultacfd table[style*="900px"] > tbody > tr > td[style*="10px"],
  body.vx-chrome #CFD table[style*="900px"] > tbody > tr > td[style*="10px"]{ display:none!important; }
  body.vx-page-consultacfd table[style*="900px"] td, body.vx-chrome #CFD table[style*="900px"] td{ font-family:var(--vx-font); }
  /* hide the redundant hero logo & corner gifs (the app-bar already shows logo + home) */
  body.vx-page-consultacfd img.tbl_top_corner, body.vx-page-consultacfd img.tbl_bottom_corner,
  body.vx-page-consultacfd table[style*="900px"] td.txt_centered > img[src$="/logo.png"]{ display:none!important; }

  /* --- contain floats so the 50/50 column parents keep their height (else they collapse to ~0) --- */
  body.vx-page-consultacfd #cfd_tr1, body.vx-page-consultacfd #cfd_tr2, body.vx-page-consultacfd #cfd_DatosCFD,
  body.vx-chrome #CFD #cfd_tr1, body.vx-chrome #CFD #cfd_tr2, body.vx-chrome #CFD #cfd_DatosCFD{ display:flow-root; }

  /* --- stack the top-level 50/50 float columns full-width (cramped side-by-side on a phone) --- */
  body.vx-page-consultacfd #cfd_ToolBar, body.vx-page-consultacfd #cfd_DatosCFD,
  body.vx-page-consultacfd #cfd_Receptor, body.vx-page-consultacfd #cfd_QR,
  body.vx-page-consultacfd #cfd_ImporteLetra, body.vx-page-consultacfd #cfd_Totales,
  body.vx-page-consultacfd #cfd_Fecha, body.vx-page-consultacfd #cfd_SerieyFolio, body.vx-page-consultacfd #cfd_DatosSAT,
  body.vx-chrome #CFD #cfd_ToolBar, body.vx-chrome #CFD #cfd_DatosCFD, body.vx-chrome #CFD #cfd_Receptor,
  body.vx-chrome #CFD #cfd_QR, body.vx-chrome #CFD #cfd_ImporteLetra, body.vx-chrome #CFD #cfd_Totales,
  body.vx-chrome #CFD #cfd_Fecha, body.vx-chrome #CFD #cfd_SerieyFolio, body.vx-chrome #CFD #cfd_DatosSAT{
    width:100%!important; float:none!important; margin:0 0 10px!important; }

  /* --- teal tbl_title_1 banners -> app section headers --- */
  body.vx-page-consultacfd .tbl_title_1, body.vx-page-consultacompra .tbl_title_1, body.vx-chrome #CFD .tbl_title_1{
    background:#eef2f7!important; color:#334155!important; border:0!important; border-radius:8px;
    font-family:var(--vx-font)!important; font-weight:800!important; font-size:12px!important;
    letter-spacing:.04em; text-transform:uppercase; padding:9px 10px!important; }
  body.vx-page-consultacfd .tbl_title_1 strong, body.vx-page-consultacfd .tbl_title_1 b,
  body.vx-page-consultacompra .tbl_title_1 strong, body.vx-page-consultacompra .tbl_title_1 b,
  body.vx-chrome #CFD .tbl_title_1 strong, body.vx-chrome #CFD .tbl_title_1 b{ color:#334155!important; font-weight:800!important; }

  /* --- action toolbar: FALLBACK (icon row) — used if js2/vx-toolbar.js doesn't run (graceful degradation) --- */
  body.vx-page-consultacfd #cfd_ToolBar, body.vx-chrome #CFD #cfd_ToolBar{
    display:flex!important; flex-wrap:wrap; gap:12px; align-items:center; justify-content:center; padding:6px 0 12px; }
  body.vx-page-consultacfd #cfd_ToolBar img[src*="48-blank"], body.vx-chrome #CFD #cfd_ToolBar img[src*="48-blank"]{ display:none!important; }
  body.vx-page-consultacfd #cfd_ToolBar a, body.vx-chrome #CFD #cfd_ToolBar a{ display:inline-flex; padding:4px; }
  body.vx-page-consultacfd #cfd_ToolBar img, body.vx-chrome #CFD #cfd_ToolBar img{ width:46px!important; height:46px!important; }


  /* --- conceptos: STACKED card-per-concepto (Step 04). The 6-col fixed table is unreadable at phone widths
         (numbers wrap 2-3 lines, headers illegible). Make table/tbody/tr/td display:block so each concepto is a
         card and each value a labeled line via ::before. colspan=6 spacers + colspan=5 SAT-detail are full-width
         blocks (display:block ignores colspan) so they can NEVER be column-hidden. Works in BOTH modes. --- */
  body.vx-page-consultacfd #cfd_tr3, body.vx-page-consultacompra #cfd_tr3, body.vx-chrome #CFD #cfd_tr3{
    overflow-x:hidden!important; background:transparent; border:0; padding:0; margin:8px 0; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos, body.vx-page-consultacompra #cfd_Tabla_Conceptos,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos{ display:block!important; width:100%!important; max-width:100%!important; table-layout:auto!important; border-collapse:collapse; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tbody, body.vx-page-consultacompra #cfd_Tabla_Conceptos tbody,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tbody{ display:block!important; width:100%; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr, body.vx-page-consultacompra #cfd_Tabla_Conceptos tr,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr{ display:block!important; width:100%; box-sizing:border-box; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td, body.vx-page-consultacompra #cfd_Tabla_Conceptos td,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos td{
    display:block!important; width:auto!important; max-width:100%!important; box-sizing:border-box;
    text-align:left!important; border:0!important; padding:2px 12px!important; font-size:13px;
    overflow-wrap:anywhere!important; word-break:break-word!important; white-space:normal!important; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos thead, body.vx-page-consultacompra #cfd_Tabla_Conceptos thead,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos thead{ display:none!important; }   /* labels move into each cell */
  /* the data row is the only tr with 6 cells -> card head; SAT-detail (colspan=5+1) bottom-joins; spacers hide */
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tbody > tr:has(> td:nth-child(6)),
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tbody > tr:has(> td:nth-child(6)){
    background:#fff; border:1px solid #d8e0ea!important; border-radius:12px 12px 0 0; margin:10px 0 0; padding:8px 0 4px; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tbody > tr:has(> td[colspan="5"]),
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tbody > tr:has(> td[colspan="5"]){
    background:#fff; border:1px solid #d8e0ea!important; border-top:0!important; border-radius:0 0 12px 12px; margin:0 0 10px; padding:0 0 8px; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tbody > tr:has(> td[colspan="6"]),
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tbody > tr:has(> td[colspan="6"]){ display:none!important; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td[colspan="5"], body.vx-chrome #CFD #cfd_Tabla_Conceptos td[colspan="5"]{
    font-size:11px!important; color:#5b6675; padding:2px 12px 6px!important; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td[colspan="5"] li, body.vx-chrome #CFD #cfd_Tabla_Conceptos td[colspan="5"] li{ list-style:none; display:block; margin:1px 0; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td[colspan="5"] hr, body.vx-chrome #CFD #cfd_Tabla_Conceptos td[colspan="5"] hr{ display:none; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td[colspan="5"] + td, body.vx-chrome #CFD #cfd_Tabla_Conceptos td[colspan="5"] + td{ display:none!important; }
  /* per-cell labels, scoped to the 6-col data row so colspan cells never get one */
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td::before{
    display:inline-block; min-width:78px; font-weight:700; color:#64748b; font-size:10px; text-transform:uppercase; letter-spacing:.03em; margin-right:6px; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(1)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(1)::before{ content:"C\00f3 digo"; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(2)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(2)::before{ content:"Cantidad"; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(3),
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(3){ font-weight:600; color:#0f172a; padding-top:6px!important; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(3)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(3)::before{ content:"Descripci\00f3 n"; display:block; margin-bottom:2px; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(4)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(4)::before{ content:"Unidad"; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(5)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(5)::before{ content:"Valor Uni."; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(6),
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(6){ font-weight:800; color:#0f172a; font-size:14px; padding-top:5px!important; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(6)::before,
  body.vx-chrome #CFD #cfd_Tabla_Conceptos tr:has(> td:nth-child(6)) > td:nth-child(6)::before{ content:"Importe"; }
  /* no-:has fallback: plain readable block stack, spacers hidden, NO real column ever hidden */
  @supports not selector(:has(*)){
    body.vx-page-consultacfd #cfd_Tabla_Conceptos td[colspan="6"], body.vx-chrome #CFD #cfd_Tabla_Conceptos td[colspan="6"]{ display:none!important; }
    body.vx-page-consultacfd #cfd_Tabla_Conceptos td.tbl_bdr_left:not([colspan]),
    body.vx-chrome #CFD #cfd_Tabla_Conceptos td.tbl_bdr_left:not([colspan]){ border-top:1px solid #d8e0ea!important; margin-top:10px; padding-top:8px!important; font-weight:700; }
  }

  /* (the legacy fixed 430px timbrado box no longer exists — vx_timbrado.php now emits a fluid .vx-timbrado
      panel with inline max-width:100%, so the old div[style*="430px"] clamp was removed as dead.) */

  /* --- readable body cells + clean borders --- */
  body.vx-page-consultacfd table[style*="900px"] td, body.vx-chrome #CFD table[style*="900px"] td{ font-size:13px; }
  body.vx-page-consultacfd .tbl_bdr, body.vx-page-consultacfd .tbl_bdr_not_top,
  body.vx-chrome #CFD .tbl_bdr, body.vx-chrome #CFD .tbl_bdr_not_top{ border-color:#e2e8f0!important; }

  /* --- pagos subgrid wrapper: inline width:880px (consultacfd.php:1656). The desktop [id^="div_wrapper_"] clamp
         is min-width:821 only, so on a phone this 880px box leaks. Clamp to the card; let the dense jqGrid
         inner-scroll within its own card (the one place horizontal scroll is acceptable, contained). --- */
  body.vx-page-consultacfd #div_wrapper_gr_vx_PagoaCFDs_01,
  body.vx-chrome #CFD #div_wrapper_gr_vx_PagoaCFDs_01{
    width:100%!important; max-width:100%!important; overflow-x:auto!important; -webkit-overflow-scrolling:touch; box-sizing:border-box; }

  /* --- UX polish (Step 05/06/07/09) --- */
  /* toolbar: un-float the inner action wrappers so the flex row lays them out cleanly (no stray floats) */
  body.vx-page-consultacfd #cfd_ToolBar > div, body.vx-chrome #CFD #cfd_ToolBar > div{ float:none!important; display:inline-flex; }
  /* receptor / cert: a calm key-value read — the receptor name stands out, long tokens (RFC, cert #, UUID) wrap */
  body.vx-page-consultacfd #cfd_Receptor, body.vx-chrome #CFD #cfd_Receptor,
  body.vx-page-consultacfd #cfd_DatosSAT, body.vx-chrome #CFD #cfd_DatosSAT{ font-size:13px; line-height:1.5; overflow-wrap:anywhere; }
  /* totals: a tight right-aligned ledger; the grand Total stands out */
  body.vx-page-consultacfd #cfd_Totales, body.vx-chrome #CFD #cfd_Totales{ font-size:13px; }
  body.vx-page-consultacfd #cfd_Totales .tbl_bdr.txt_rightaligned, body.vx-chrome #CFD #cfd_Totales .tbl_bdr.txt_rightaligned{ font-weight:700; }
  /* QR (stamped case): native px is oversized on a phone -> cap to a comfortable square, centered. */
  body.vx-page-consultacfd #cfd_QR img, body.vx-chrome #CFD #cfd_QR img{ width:160px!important; height:auto!important; max-width:60vw; display:block; margin:6px auto 0; }
  /* dialog chrome: app-styled title bar + a >=44px close tap target (jQuery UI default ~20px is a poor finger
     target). Draw our own x so we don't depend on the theme sprite. */
  body.vx-chrome .ui-dialog .ui-dialog-titlebar{
    background:#eef2f7!important; border:0!important; border-radius:14px 14px 0 0!important;
    padding:10px 52px 10px 14px!important; min-height:44px; box-sizing:border-box; position:relative; }
  body.vx-chrome .ui-dialog .ui-dialog-title{
    font-family:var(--vx-font)!important; font-weight:800!important; font-size:14px!important; color:#334155!important;
    letter-spacing:.01em; line-height:1.3; white-space:normal!important; width:auto!important; float:none!important; }
  body.vx-chrome .ui-dialog .ui-dialog-titlebar-close{
    position:absolute!important; top:50%; right:8px; margin:0!important; transform:translateY(-50%);
    width:44px!important; height:44px!important; border-radius:12px!important; display:flex!important; align-items:center; justify-content:center; }
  body.vx-chrome .ui-dialog .ui-dialog-titlebar-close .ui-icon{ display:none!important; }
  body.vx-chrome .ui-dialog .ui-dialog-titlebar-close::before{ content:"\00d7"; font:700 24px/1 var(--vx-font); color:#475569; }
}

/* ============================================================================
   ENHANCED ACTION BAR + ICON SYSTEM — applies at ALL widths (relocated out of the mobile media query
   2026-06-14 so the desktop pilot gets the premium toolbar too). Pilot-gated via js.php; the bar exists only
   when vx-toolbar.js enhanced it (#cfd_ToolBar.vx-tb-enhanced), so these rules are inert otherwise.
   ============================================================================ */
  /* === ENHANCED ACTION BAR (js2/vx-toolbar.js adds .vx-tb-enhanced + labels + flex order) ===================
     Labeled, collapsible: PRIMARY (PDF/Email/XML, 3-up) · "Más acciones ▾" · MORE (collapsed) · DANGER (Cancelar,
     red, last). Cures the Pinche Viejito Necio "¿y ahora qué?" — every action is now named, deduped, and the
     destructive one is isolated. Mobile-only (the JS enhances only <=820); desktop keeps the icon row above. */
  /* === COMPACT one-line action bar (asked: "all in one line, not the whole screen") =====================
     A tight ROW of small tiles (PDF/Email/XML + a "Más" tile) that hugs its content; the overflow actions and
     Cancelar live in a premium dropdown DRAWER that opens under it. Gated, mobile-only. */
  body.vx-page-consultacfd #cfd_ToolBar.vx-tb-enhanced, body.vx-chrome #CFD #cfd_ToolBar.vx-tb-enhanced{
    display:block!important; text-align:center; float:none!important; width:auto!important; max-width:100%;
    box-sizing:border-box; margin:0 auto 10px!important; padding:0!important; min-height:0!important;
    line-height:0; background:transparent; border:0; box-shadow:none; }
  /* enhanced bar shows ONLY the row + dropdown — hide leftover legacy strays (an <hr> separator, the emptied
     #ModificaCFD wrapper, loose spacer imgs, deduped links) that were wasting ~90px of vertical space */
  #cfd_ToolBar.vx-tb-enhanced > :not(.vx-tb-row):not(.vx-tb-drawer){ display:none!important; }
  /* the single line — inline-flex so it hugs content and centers via the block parent's text-align */
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-row{ display:inline-flex!important; vertical-align:top; flex-wrap:nowrap; gap:7px; align-items:stretch; max-width:100%; line-height:1.1; }
  /* a compact tile button (base) */
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn{
    position:relative; display:flex!important; flex-direction:column; align-items:center; justify-content:center; gap:5px;
    width:58px; min-height:60px; padding:7px 3px; box-sizing:border-box; text-decoration:none; cursor:pointer;
    border:1px solid rgba(15,23,42,.10); border-radius:14px; background:linear-gradient(180deg,#ffffff,#f6f8fc); color:#0f172a;
    font:600 10.5px/1.1 var(--vx-font); text-align:center; -webkit-tap-highlight-color:transparent;
    box-shadow:0 1px 2px rgba(15,23,42,.05); transition:transform .13s ease, background .18s ease, box-shadow .18s ease; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn:active{ transform:scale(.94); }
  /* the glyph chip */
  #cfd_ToolBar.vx-tb-enhanced .vx-tbic{
    display:flex; align-items:center; justify-content:center; width:34px; height:34px; border-radius:10px;
    background:#eef4fc; color:#1d4ed8; box-shadow:inset 0 0 0 1px rgba(29,78,216,.08); }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn img{ width:20px!important; height:20px!important; }
  /* ICON SYSTEM (vx-icons.js): dated raster glyphs -> crisp inline <svg>; stroke follows currentColor. */
  body.vx-on svg.vx-ico, body.vx-chrome svg.vx-ico{
    display:inline-block; width:1.25em; height:1.25em; vertical-align:-0.18em; flex:none;
    fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round; color:inherit; }
  body.vx-on svg.vx-ico--check, body.vx-chrome svg.vx-ico--check{ color:#15803d; }   /* Pagado / Provisto */
  body.vx-on svg.vx-ico--x,     body.vx-chrome svg.vx-ico--x{ color:#b91c1c; }       /* No pagado / No provisto */
  body.vx-on svg.vx-ico--sm,    body.vx-chrome svg.vx-ico--sm{ width:16px; height:16px; vertical-align:-3px; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbic svg.vx-ico{ width:20px; height:20px; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn-lbl{ display:block; white-space:nowrap; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--dup{ display:none!important; }
  /* PRIMARY tiles (PDF/Email/XML) — blue accent label */
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--primary .vx-tbtn-lbl{ color:#1d4ed8; font-weight:700; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--primary:active{ background:linear-gradient(180deg,#f5f8ff,#e9f1fe); }
  /* "Más" tile — neutral; sits LAST in the row (primaries carry inline order 11-13); chevron rotates on open */
  #cfd_ToolBar.vx-tb-enhanced .vx-tbmore-toggle{ order:50; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbmore-toggle .vx-tbic{ background:#f1f5f9; color:#475569; box-shadow:inset 0 0 0 1px rgba(15,23,42,.06); font:700 18px/1 var(--vx-font); }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbmore-chev{ transition:transform .26s ease; }
  #cfd_ToolBar.vx-tb-enhanced.vx-tb-open .vx-tbmore-toggle .vx-tbmore-chev{ transform:rotate(180deg); }
  /* DROPDOWN DRAWER — premium card under the row, animated (grid 0fr -> 1fr) */
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-drawer{
    display:grid!important;   /* !important beats the legacy `#CFD #cfd_ToolBar > div{display:inline-flex}` (2-id) in dialog mode — else the grid 0fr collapse is ignored and the dropdown shows full-height */
    grid-template-rows:0fr; transition:grid-template-rows .26s ease; width:min(330px,100%); margin:0 auto; text-align:left; line-height:1.3; }
  #cfd_ToolBar.vx-tb-enhanced.vx-tb-open .vx-tb-drawer{ grid-template-rows:1fr; margin-top:8px; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-drawer-inner{
    overflow:hidden; min-height:0; display:flex; flex-direction:column; visibility:hidden; transition:visibility 0s .26s;
    background:#fff; border:1px solid rgba(15,23,42,.08); border-radius:16px; box-shadow:0 16px 36px -12px rgba(15,23,42,.28); }
  #cfd_ToolBar.vx-tb-enhanced:not(.vx-tb-open) .vx-tb-drawer-inner{ border-color:transparent; box-shadow:none; }
  #cfd_ToolBar.vx-tb-enhanced.vx-tb-open .vx-tb-drawer-inner{ visibility:visible; transition:visibility 0s 0s; }
  /* the overflow actions + Cancelar inside the dropdown render as list rows (chip - label - chevron) */
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-drawer-inner .vx-tbtn{
    width:auto; flex-direction:row; justify-content:flex-start; align-items:center; gap:12px; text-align:left;
    min-height:54px; padding:9px 14px; border:0; border-bottom:1px solid rgba(15,23,42,.06); border-radius:0;
    background:transparent; box-shadow:none; font-size:14px; font-weight:600; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-drawer-inner .vx-tbtn:last-child{ border-bottom:0; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tb-drawer-inner .vx-tbtn .vx-tbtn-lbl{ flex:1; white-space:normal; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--more .vx-tbic{ width:36px; height:36px; border-radius:10px; background:#f1f5f9; color:#475569; box-shadow:inset 0 0 0 1px rgba(15,23,42,.05); }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--more::after{ content:"\203A"; color:#cbd5e1; font:700 22px/1 var(--vx-font); }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--more:active{ background:#f8fafc; }
  /* DANGER (Cancelar) — last row in the dropdown, restrained red */
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--danger{ order:90; color:#dc2626; font-weight:700; }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--danger .vx-tbic{ background:#fef2f2; color:#dc2626; box-shadow:inset 0 0 0 1px rgba(220,38,38,.12); }
  #cfd_ToolBar.vx-tb-enhanced .vx-tbtn--danger:active{ background:#fff5f5; }

/* ============================================================================
   CONSULTACFD PREMIUM — DESKTOP (>=821px), PILOT-ONLY (this file loads only under vx_redesign()).
   The whole CFDI document becomes a premium centered sheet for the pilot on desktop; non-pilot users
   never load vx-design.css, so desktop stays byte-legacy for them. Filled by the consultacfd-premium loop.
   ============================================================================ */
@media (min-width:821px){
  /* --- Loop 3: the enhanced toolbar is premium on DESKTOP too — full-width (display:block from the relocated
     .vx-tb-enhanced rule); un-float the cert block so it stacks cleanly BELOW (cleaner than the legacy 50/50). --- */
  body.vx-page-consultacfd #cfd_DatosCFD, body.vx-chrome #CFD #cfd_DatosCFD{ float:none!important; width:100%!important; clear:both; }
  /* --- Step 02: the CFDI document becomes a premium CENTERED SHEET (full-page) --- */
  body.vx-page-consultacfd{ background:linear-gradient(180deg,#f4f7fb,var(--vx-bg)); }
  body.vx-page-consultacfd .vx-doc-frame{ padding:30px 16px 52px; }
  body.vx-page-consultacfd table[style*="900px"]{
    margin:0 auto!important; background:var(--vx-card)!important; border:1px solid var(--vx-line)!important;
    border-radius:var(--vx-radius-lg)!important; box-shadow:var(--vx-shadow)!important;
    border-collapse:separate!important; overflow:hidden; }
  /* drop the 2010 corner-gif table chrome (the card's own radius replaces it) */
  body.vx-page-consultacfd img[src*="corner-up"]{ display:none!important; }
  /* breathing room inside the sheet (table-layout:fixed keeps the column at 880 — padding stays inside) */
  body.vx-page-consultacfd table[style*="900px"] > tbody > tr > td[style*="880px"]{ padding-left:30px!important; padding-right:30px!important; }
  /* dialog mode on desktop: the #CFD dialog supplies the frame. The legacy `.table_fixed` (table-layout:fixed)
     reads its column model from the FIRST row — but in dialog mode the first frame row is a colspan=3 spanner,
     so fixed layout fell back to THREE EQUAL ~300px columns, starving the 880px content cell (cert/receptor/QR
     crushed to ~128px — "ACCOUNT & / BUSSINES / CONSULTANT", one word per line). Full-page never hits this
     (its first row is the real [gutter, 880, gutter]). CSS-only cure: switch the DESKTOP dialog frame to
     table-layout:auto so the column model is computed from the inline 880px content cell across ALL rows,
     and let the table fill the dialog. (Mobile is unaffected — it lives in the @media max-width:820 block.) */
  body.vx-chrome #CFD table[style*="900px"]{ width:100%!important; max-width:100%!important; margin:0!important; table-layout:auto!important; box-sizing:border-box; }
  body.vx-chrome #CFD table[style*="900px"] > tbody > tr > td[style*="880px"]{ width:auto!important; max-width:100%!important; box-sizing:border-box; }
  body.vx-chrome #CFD table[style*="900px"] > tbody > tr > td[style*="10px"]{ width:0!important; padding:0!important; }
  /* the dialog scroll container: at mainstream desktop widths the frame fits (902<930) so NO bar shows; on a
     genuinely narrow desktop window (<~940px) the legacy ~880px document (jqGrid pager + <hr> set a fixed floor
     that resists CSS) would otherwise be clipped — for a FISCAL document, a contained horizontal scroll that
     keeps every amount reachable beats clipping the right edge. `auto` gives both. */
  body.vx-chrome .ui-dialog .ui-dialog-content{ overflow-x:auto!important; }

  /* --- Step 03: premium section headers (the 2017 blue banners -> calm app section labels) --- */
  body.vx-page-consultacfd .tbl_title_1, body.vx-chrome #CFD .tbl_title_1{
    background:var(--vx-surface-2)!important; color:var(--vx-mut)!important;
    border:0!important; border-top:1px solid var(--vx-line)!important; border-bottom:1px solid var(--vx-line)!important;
    border-radius:0!important; font-family:var(--vx-font)!important; font-weight:800!important; font-size:11.5px!important;
    letter-spacing:.06em; text-transform:uppercase; padding:11px 16px!important; text-align:left!important; }
  body.vx-page-consultacfd .tbl_title_1 strong, body.vx-page-consultacfd .tbl_title_1 b,
  body.vx-chrome #CFD .tbl_title_1 strong, body.vx-chrome #CFD .tbl_title_1 b{ color:var(--vx-mut)!important; font-weight:800!important; }
  /* refined body typography + hairline separators inside the sheet */
  body.vx-page-consultacfd table[style*="900px"]{ color:var(--vx-ink); font-family:var(--vx-font); }

  /* --- Steps 06/07: conceptos + totals premium (desktop) — readable rows + tabular-aligned money --- */
  body.vx-page-consultacfd #cfd_Tabla_Conceptos, body.vx-chrome #CFD #cfd_Tabla_Conceptos,
  body.vx-page-consultacfd #cfd_Totales, body.vx-chrome #CFD #cfd_Totales{ font-variant-numeric:tabular-nums; }
  body.vx-page-consultacfd #cfd_Tabla_Conceptos td, body.vx-chrome #CFD #cfd_Tabla_Conceptos td{
    padding:10px 12px!important; border-bottom:1px solid var(--vx-line)!important; vertical-align:top; }
  /* emphasize the grand TOTAL line (bold accent) — the strong/last money the eye should land on */
  body.vx-page-consultacfd #cfd_Totales strong, body.vx-page-consultacfd #cfd_Totales b,
  body.vx-chrome #CFD #cfd_Totales strong, body.vx-chrome #CFD #cfd_Totales b{ color:var(--vx-accent-d); font-weight:800; }
}

/* ============================================================================
   ANSWER HEADER (Step 04) — Folio · Total · Estado premium summary card. Emitted by consultacfd.php as a gated
   full-width row (pilot only) so it renders natively in BOTH modes (full-page + #CFD dialog) and BOTH platforms.
   Not width-gated: it only exists when vx_redesign() emitted it, and is vx/page-scoped (no leak).
   ============================================================================ */
body.vx-page-consultacfd .vx-doc-summary, body.vx-chrome #CFD .vx-doc-summary{
  display:flex; flex-wrap:wrap; gap:10px; margin:14px 16px 4px; padding:14px 16px;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-radius);
  box-shadow:0 1px 2px rgba(15,23,42,.05); box-sizing:border-box; }
body.vx-page-consultacfd .vx-doc-summary .vx-sum-cell, body.vx-chrome #CFD .vx-doc-summary .vx-sum-cell{
  flex:1 1 30%; min-width:92px; display:flex; flex-direction:column; gap:4px; }
body.vx-page-consultacfd .vx-doc-summary .vx-sum-k, body.vx-chrome #CFD .vx-doc-summary .vx-sum-k{
  font:700 10.5px/1 var(--vx-font); letter-spacing:.06em; text-transform:uppercase; color:var(--vx-mut); }
body.vx-page-consultacfd .vx-doc-summary .vx-sum-v, body.vx-chrome #CFD .vx-doc-summary .vx-sum-v{
  font:700 16px/1.2 var(--vx-font); color:var(--vx-ink); }
body.vx-page-consultacfd .vx-doc-summary .vx-sum-total, body.vx-chrome #CFD .vx-doc-summary .vx-sum-total{
  font-size:21px; color:var(--vx-accent-d); font-variant-numeric:tabular-nums; }
body.vx-page-consultacfd .vx-doc-summary .vx-sum-pill, body.vx-chrome #CFD .vx-doc-summary .vx-sum-pill{
  align-self:flex-start; display:inline-flex; align-items:center; gap:6px; padding:4px 11px; border-radius:999px;
  font:700 13px/1.3 var(--vx-font); }
body.vx-page-consultacfd .vx-doc-summary.vx-est-ok .vx-sum-pill, body.vx-chrome #CFD .vx-doc-summary.vx-est-ok .vx-sum-pill{ background:#ecfdf5; color:#15803d; }
body.vx-page-consultacfd .vx-doc-summary.vx-est-warn .vx-sum-pill, body.vx-chrome #CFD .vx-doc-summary.vx-est-warn .vx-sum-pill{ background:#fff7ed; color:#b45309; }
body.vx-page-consultacfd .vx-doc-summary.vx-est-cancel .vx-sum-pill, body.vx-chrome #CFD .vx-doc-summary.vx-est-cancel .vx-sum-pill{ background:#fef2f2; color:#dc2626; }
body.vx-page-consultacfd .vx-doc-summary.vx-est-neutral .vx-sum-pill, body.vx-chrome #CFD .vx-doc-summary.vx-est-neutral .vx-sum-pill{ background:#f1f5f9; color:#475569; }
/* estado glyph for one-glance recognition (CSS-only, no markup change) */
body.vx-page-consultacfd .vx-doc-summary .vx-sum-pill::before, body.vx-chrome #CFD .vx-doc-summary .vx-sum-pill::before{ font-weight:900; font-size:.95em; line-height:1; }
body.vx-page-consultacfd .vx-doc-summary.vx-est-ok .vx-sum-pill::before, body.vx-chrome #CFD .vx-doc-summary.vx-est-ok .vx-sum-pill::before{ content:"\2713"; }      /* check */
body.vx-page-consultacfd .vx-doc-summary.vx-est-cancel .vx-sum-pill::before, body.vx-chrome #CFD .vx-doc-summary.vx-est-cancel .vx-sum-pill::before{ content:"\2715"; }  /* cross */
body.vx-page-consultacfd .vx-doc-summary.vx-est-warn .vx-sum-pill::before, body.vx-chrome #CFD .vx-doc-summary.vx-est-warn .vx-sum-pill::before{ content:"\26A0"; }      /* warning */
body.vx-page-consultacfd .vx-doc-summary.vx-est-neutral .vx-sum-pill::before, body.vx-chrome #CFD .vx-doc-summary.vx-est-neutral .vx-sum-pill::before{ content:"\2022"; } /* dot */
@media (min-width:821px){
  body.vx-page-consultacfd .vx-doc-summary, body.vx-chrome #CFD .vx-doc-summary{ margin:18px 30px 6px; padding:16px 20px; gap:14px; }
  body.vx-page-consultacfd .vx-doc-summary .vx-sum-cell, body.vx-chrome #CFD .vx-doc-summary .vx-sum-cell{ flex:1 1 0; }
}

/* ============================================================================
   CERT + RECEPTOR key-value premium (Step 05) — CSS-ONLY, both platforms, both render modes, pilot-gated
   (this file loads only under vx_redesign(), so non-pilot users stay byte-legacy automatically).
   We do NOT touch the PHP markup: it is not gated, so a per-field <span> grid would diverge the non-pilot
   byte-legacy guarantee. Instead we lean on the legacy structure that already exists:
     · CERTIFICACIÓN cell (#cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned): every VALUE is in <strong>, the
       LABELs are plain text — so muted cell text + dark <strong> renders a clean key→value contrast, and the
       long fiscal codes (UUID, cert #, cert SAT #) wrap + go tabular.
     · RECEPTOR cell (#cfd_Receptor td.tbl_bdr_not_top): the name+RFC is the only <strong>; método/forma/uso
       are plain text — so the <strong> becomes the anchor (dark, slightly larger) and the payment metadata
       reads as calm secondary (muted). Both selectors are scoped to their block so no other tbl_bdr_not_top
       cell (obser, conceptos, totals, receptor↔cert) is affected.
   ============================================================================ */
/* CERTIFICACIÓN — muted labels, dark tabular <strong> values, long codes wrap */
body.vx-page-consultacfd #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned,
body.vx-chrome #CFD #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned{
  color:var(--vx-mut); line-height:1.85; letter-spacing:.004em; }
body.vx-page-consultacfd #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned strong,
body.vx-chrome #CFD #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned strong{
  color:var(--vx-ink); font-weight:700; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; }
/* RECEPTOR — name+RFC (<strong>) is the anchor; payment metadata (plain text) is calm secondary */
body.vx-page-consultacfd #cfd_Receptor td.tbl_bdr_not_top, body.vx-chrome #CFD #cfd_Receptor td.tbl_bdr_not_top{
  color:var(--vx-mut); line-height:1.7; }
body.vx-page-consultacfd #cfd_Receptor td.tbl_bdr_not_top strong, body.vx-chrome #CFD #cfd_Receptor td.tbl_bdr_not_top strong{
  color:var(--vx-ink); font-weight:700; font-size:13.5px; line-height:1.45; overflow-wrap:anywhere; }
@media (min-width:821px){
  /* a touch more air on desktop where the sheet is roomy */
  body.vx-page-consultacfd #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned,
  body.vx-chrome #CFD #cfd_DatosCFD td.tbl_bdr_not_top.txt_leftaligned{ line-height:1.75; }
  body.vx-page-consultacfd #cfd_Receptor td.tbl_bdr_not_top strong,
  body.vx-chrome #CFD #cfd_Receptor td.tbl_bdr_not_top strong{ font-size:14.5px; }
}

/* ============================================================================
   MODAL/DOC COMPACTION (desktop) — reclaim the wasted top third so the user isn't forced to scroll past
   half-empty bands. CSS-only, pilot-gated, both render modes. Tighter bands + the certification key-values
   flow into TWO columns (an unstamped CFDI shows 5 lines, 2-3 of them empty — 2 columns ~halves the height).
   ============================================================================ */
@media (min-width:821px){
  /* answer header: tighter card */
  body.vx-page-consultacfd .vx-doc-summary, body.vx-chrome #CFD .vx-doc-summary{ margin:12px 30px 4px!important; padding:11px 18px!important; }
  /* every section-header band: tighter vertical rhythm */
  body.vx-page-consultacfd .tbl_title_1, body.vx-chrome #CFD .tbl_title_1{ padding-top:7px!important; padding-bottom:7px!important; }
  /* certification key-values -> 2 columns (halves the block height; empties no longer cost a full line each) */
  body.vx-page-consultacfd #cfd_DatosSAT td.tbl_bdr_not_top.txt_leftaligned,
  body.vx-chrome #CFD #cfd_DatosSAT td.tbl_bdr_not_top.txt_leftaligned{ column-count:2; column-gap:34px; line-height:1.65!important; padding-top:8px!important; padding-bottom:8px!important; }
  /* the FECHA | Serie-Folio strip is low-density + largely echoes the answer header -> compact it to a thin strip */
  body.vx-page-consultacfd #cfd_Fecha .tbl_bdr_not_top, body.vx-page-consultacfd #cfd_SerieyFolio .tbl_bdr_not_top,
  body.vx-chrome #CFD #cfd_Fecha .tbl_bdr_not_top, body.vx-chrome #CFD #cfd_SerieyFolio .tbl_bdr_not_top{ padding-top:5px!important; padding-bottom:5px!important; }
  /* trim the structural <br/> gap below the FECHA strip */
  body.vx-page-consultacfd #cfd_DatosCFD>br, body.vx-chrome #CFD #cfd_DatosCFD>br{ display:none; }
  /* tighten the enhanced toolbar's top/bottom margin so it hugs the answer header */
  body.vx-page-consultacfd #cfd_ToolBar.vx-tb-enhanced, body.vx-chrome #CFD #cfd_ToolBar.vx-tb-enhanced{ margin:2px auto 6px!important; }

  /* MERGED ACTION BAR: vx-toolbar.js moved #cfd_ToolBar INTO .vx-doc-summary on desktop, so FOLIO·TOTAL·ESTADO
     and the buttons sit on ONE line. The summary becomes a single nowrap row; the bar is pushed to the right. */
  body.vx-page-consultacfd .vx-doc-summary.vx-sum-hasbar, body.vx-chrome #CFD .vx-doc-summary.vx-sum-hasbar{
    align-items:center; flex-wrap:nowrap; gap:20px; position:relative; }
  body.vx-page-consultacfd .vx-doc-summary.vx-sum-hasbar .vx-sum-cell, body.vx-chrome #CFD .vx-doc-summary.vx-sum-hasbar .vx-sum-cell{ flex:0 1 auto; }
  body.vx-page-consultacfd .vx-doc-summary #cfd_ToolBar.vx-tb-enhanced, body.vx-chrome #CFD .vx-doc-summary #cfd_ToolBar.vx-tb-enhanced{
    margin:0 0 0 auto!important; width:auto!important; flex:none; position:relative; }
  /* the "Más" drawer drops below the bar (absolute) so it doesn't stretch the one-line summary */
  body.vx-page-consultacfd .vx-doc-summary #cfd_ToolBar .vx-tb-drawer, body.vx-chrome #CFD .vx-doc-summary #cfd_ToolBar .vx-tb-drawer{
    position:absolute!important; top:100%; right:0; width:300px!important; margin:6px 0 0!important; z-index:30; }
}

/* ============================================================================
   TIER 1 EXTRAS — full redesign content, body.vx-on ONLY (menuemisor today).
   ============================================================================ */

/* ---- Layout: container + (desktop) rail ---- */
body.vx-on .vx-shell{ display:block; }
body.vx-on .vx-container{ max-width:1100px; margin:0 auto; padding:16px; }
@media (min-width:641px){ body.vx-on .vx-container{ padding:22px; } }
@media (min-width:821px){
  body.vx-on .vx-shell{ display:grid; grid-template-columns:var(--vx-rail-w) 1fr; align-items:start; }
  body.vx-on .vx-container{ padding:26px 32px; max-width:1180px; }
}

/* ---- Cards + grid ---- */
body.vx-on .vx-card{ background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-radius);
  box-shadow:var(--vx-shadow); padding:18px 20px; }
body.vx-on a.vx-card, body.vx-on button.vx-card{ display:block; text-decoration:none; color:inherit; cursor:pointer;
  transition:transform .12s,box-shadow .2s,border-color .15s; }
body.vx-on a.vx-card:hover, body.vx-on button.vx-card:hover{ transform:translateY(-2px); box-shadow:var(--vx-shadow-lg); border-color:#cdd9ea; }
body.vx-on .vx-grid{ display:grid; grid-template-columns:1fr; gap:14px; }
@media (min-width:480px){ body.vx-on .vx-grid{ grid-template-columns:repeat(2,1fr); } }
@media (min-width:861px){ body.vx-on .vx-grid{ grid-template-columns:repeat(3,1fr); } }
@media (min-width:821px){ body.vx-on .vx-grid{ grid-template-columns:repeat(4,1fr); gap:16px; } }
body.vx-on .vx-launch{ text-align:left; }
body.vx-on .vx-launch .ico{ display:inline-flex; align-items:center; justify-content:center; width:46px; height:46px;
  border-radius:13px; background:linear-gradient(135deg,#eef4ff,#dbe7ff); font-size:24px; }
body.vx-on .vx-launch h3{ margin:8px 0 2px; font-size:15.5px; font-weight:800; }
body.vx-on .vx-launch p{ margin:0; color:var(--vx-mut); font-size:12.5px; }

/* ---- Launcher header + groups ---- */
body.vx-on .vx-launcher-wrap{ display:block; }
body.vx-on .vx-hello{ margin:4px 2px 18px; }
body.vx-on .vx-h1{ margin:0; font-size:22px; font-weight:800; letter-spacing:-.01em; }
body.vx-on .vx-sub{ margin:2px 0 0; color:var(--vx-mut); font-size:14px; font-weight:600; }
body.vx-on .vx-lgroup{ margin:0 0 22px; }
body.vx-on .vx-lgroup-title{ margin:0 0 10px; font-size:13px; font-weight:800; letter-spacing:.04em;
  text-transform:uppercase; color:var(--vx-mut); }

/* ---- Buttons / inputs (for redesigned pages) ---- */
body.vx-on .vx-btn{ display:inline-flex; align-items:center; justify-content:center; gap:8px; min-height:44px;
  padding:11px 18px; border:none; border-radius:var(--vx-radius-sm); font:inherit; font-weight:800; font-size:15px;
  cursor:pointer; text-decoration:none; transition:filter .15s,transform .08s; }
body.vx-on .vx-btn:active{ transform:translateY(1px); }
body.vx-on .vx-btn--go{ background:linear-gradient(120deg,var(--vx-accent),var(--vx-accent-d)); color:#fff; }
body.vx-on .vx-btn--ghost{ background:#fff; color:#334155; border:1.5px solid #dbe3ec; }
body.vx-on .vx-btn--danger{ background:#fff; color:var(--vx-crit); border:1.5px solid #fecaca; }
body.vx-on .vx-btn:not(:disabled):hover{ filter:brightness(1.05); }
body.vx-on .vx-btn:disabled{ opacity:.5; cursor:not-allowed; }
body.vx-on .vx-field{ margin-bottom:14px; }
body.vx-on .vx-field label{ display:block; font-size:13px; font-weight:700; margin-bottom:5px; }
body.vx-on .vx-input{ width:100%; min-height:44px; padding:11px 13px; border:1.5px solid #dbe3ec; border-radius:var(--vx-radius-sm);
  font:inherit; font-size:16px; transition:border-color .15s,box-shadow .15s; }
body.vx-on .vx-input:focus{ outline:none; border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.12); }

/* ---- Side rail (desktop, menuemisor) ---- */
body.vx-on .vx-rail{ display:none; }
@media (min-width:821px){
  body.vx-on .vx-rail{ display:block; position:sticky; top:64px; align-self:start; padding:18px 12px;
    height:calc(100vh - 64px); overflow:auto; }
  body.vx-on .vx-rail a{ display:flex; align-items:center; gap:11px; padding:11px 13px; border-radius:11px;
    color:#334155; text-decoration:none; font-weight:700; font-size:14px; margin-bottom:3px; }
  body.vx-on .vx-rail a .ico{ font-size:19px; }
  body.vx-on .vx-rail a:hover{ background:#eef4ff; color:var(--vx-accent); }
  body.vx-on .vx-rail a.active{ background:#e7efff; color:var(--vx-accent); }
}

/* ---- Launcher (compact/medium) vs legacy menu (expanded) — XOR by size (menuemisor) ---- */
body.vx-on .vx-page-frame{ display:none; }
@media (min-width:821px){
  body.vx-on .vx-launcher-wrap{ display:none; }
  body.vx-on .vx-page-frame{ display:block; text-align:left; width:auto; }
  body.vx-on table.vx-menu-shell{ width:100%!important; background:transparent!important; border:0!important; }
  body.vx-on table.vx-menu-shell > tbody > tr:first-child,
  body.vx-on table.vx-menu-shell > tbody > tr:last-child{ display:none; }
}

/* ---- Misc ---- */
body.vx-on .vx-actionbar{ position:sticky; bottom:calc(var(--vx-bottomnav-h) + env(safe-area-inset-bottom,0px));
  background:rgba(255,255,255,.96); backdrop-filter:saturate(1.4) blur(6px); border-top:1px solid var(--vx-line);
  padding:12px 16px; display:flex; align-items:center; gap:12px; z-index:30; }
@media (min-width:821px){ body.vx-on .vx-actionbar{ bottom:0; } }
body.vx-on .vx-skel{ background:linear-gradient(90deg,#eef2f7 25%,#f6f9fc 37%,#eef2f7 63%); background-size:400% 100%;
  animation:vx-shimmer 1.3s infinite; border-radius:10px; }
@keyframes vx-shimmer{ from{background-position:100% 0} to{background-position:0 0} }
@media (prefers-reduced-motion:reduce){ body.vx-on *{ animation:none!important; transition:none!important; } }
.vx-appbar, .vx-bottomnav, .vx-sheet{ }
@media (prefers-reduced-motion:reduce){ .vx-sheet{ transition:none!important; } }
body.vx-on .num{ font-variant-numeric:tabular-nums; }

/* ============================================================================
   GRIDS PREMIUM — CELL LANGUAGE (money · dates · identity · answer), both platforms, both tiers.
   Positional via aria-describedby$=/id$= (jqGrid sets td aria-describedby="<grid>_<col>" and th id the same)
   — NO colModel/markup change. The file is pilot-gated (loads only under vx_redesign()). [Step 04]
   ============================================================================ */
/* identity noise: encrypted id columns are never meaningful to a human -> hide both platforms (never the
   click target or the subgrid toggle, so safe; if a grid already has them hidden:true this is a no-op) */
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="_enc" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby*="_enc" i],
body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id*="_enc" i],
body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id*="_enc" i]{ display:none!important; }

/* money: tabular figures on both platforms (digits line up) */
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="total" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="monto" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="saldo" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="importe" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="retencion" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuento" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuentox100" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="iva" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="debitos" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="creditos" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="precio" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cambio" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="indirectos" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="exento" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="total" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="monto" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="saldo" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="importe" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="retencion" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuento" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuentox100" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="iva" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="debitos" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="creditos" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="precio" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cambio" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="indirectos" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="exento" i]{ font-variant-numeric:tabular-nums; }

/* the answer column (name/serie/folio/descripcion) -> dark anchor (the eye's entry point) */
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_serie" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_folio" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descripcion" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descripción" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_obranombre" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_variable" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_referencia" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_serie" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_folio" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descripcion" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descripción" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_obranombre" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_variable" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_referencia" i]{ color:var(--vx-ink)!important; font-weight:700; }

/* audit metadata (alta/ultimo_cambio + who) -> calm muted secondary (declutter every catalog) */
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_db" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="ultimo_cambio" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_por" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="ultimo_cambio_por" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_modificado" i],
body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_modificada" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_db" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="ultimo_cambio" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta_por" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="ultimo_cambio_por" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_alta" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_modificado" i],
body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_modificada" i]{ color:var(--vx-mut)!important; font-weight:500; }

@media (min-width:821px){
  /* desktop table: money columns right-aligned (header + body) so amounts line up as a ledger */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="total" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="monto" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="saldo" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="importe" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="retencion" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuento" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuentox100" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="iva" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="debitos" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="creditos" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="precio" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cambio" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="indirectos" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="exento" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="total" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="monto" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="saldo" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="importe" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="retencion" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuento" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="descuentox100" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="iva" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="debitos" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="creditos" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="precio" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cambio" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="indirectos" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="exento" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="total" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="totalmxn" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="monto" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="saldo" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="importe" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="retencion" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="descuento" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="descuentox100" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="iva" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="debitos" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="creditos" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="precio" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="cambio" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="indirectos" i],
  body.vx-chrome .ui-jqgrid .ui-jqgrid-htable th[id$="exento" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="total" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="totalmxn" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="monto" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="saldo" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="importe" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="retencion" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="descuento" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="descuentox100" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="iva" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="debitos" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="creditos" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="precio" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="cambio" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="indirectos" i],
  body.vx-on .ui-jqgrid .ui-jqgrid-htable th[id$="exento" i]{ text-align:right!important; }
  /* total / saldo: the accent money the eye should land on */
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_total" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_saldo" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cfdtotal" i],
  body.vx-chrome .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cfdsaldo" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_total" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="totalmxn" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_saldo" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cfdtotal" i],
  body.vx-on .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="cfdsaldo" i]{ color:var(--vx-accent-d)!important; font-weight:700; }
}

/* ============================================================================
   GRIDS PREMIUM — STATUS PILLS + ACTION CHIPS (both platforms, both tiers). [Step 05]
   Status pills: cells tagged vx-st-yes/vx-st-no by vx-grid.js (reads the legacy tick/cross icon, read-only)
   render as a premium estado pill with a glyph; the original <img> is hidden. Action chips: the action
   <a> (borrar/Facturar/Ventas/Movimientos) becomes a tinted chip (borrar=danger red, others=primary blue).
   ============================================================================ */
/* hide the legacy tick/cross raster behind a tagged status cell */
body.vx-chrome .ui-jqgrid-btable td.vx-st img,
body.vx-on .ui-jqgrid-btable td.vx-st img{ display:none!important; }
/* the pill (glyph set per polarity below) */
body.vx-chrome .ui-jqgrid-btable td.vx-st::after,
body.vx-on .ui-jqgrid-btable td.vx-st::after{ display:inline-flex; align-items:center; justify-content:center;
  min-width:26px; height:26px; padding:0 10px; border-radius:999px; font:800 13px/1 var(--vx-font); }
body.vx-chrome .ui-jqgrid-btable td.vx-st-yes::after,
body.vx-on .ui-jqgrid-btable td.vx-st-yes::after{ content:"\2713"; background:#dcfce7; color:#15803d; box-shadow:inset 0 0 0 1px rgba(21,128,61,.22); }
body.vx-chrome .ui-jqgrid-btable td.vx-st-no::after,
body.vx-on .ui-jqgrid-btable td.vx-st-no::after{ content:"\2715"; background:#f1f5f9; color:#94a3b8; box-shadow:inset 0 0 0 1px rgba(15,23,42,.08); }

/* action chips: tint the action <a> (it keeps its onclick/img — purely visual) */
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="borrar" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="borrar" i] a,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="facturar" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="facturar" i] a,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="ventas" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="ventas" i] a,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a{
  display:inline-flex!important; align-items:center; justify-content:center; width:30px; height:30px;
  border-radius:9px; box-shadow:inset 0 0 0 1px rgba(15,23,42,.06); transition:background .15s ease; }
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="borrar" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="borrar" i] a{ background:#fef2f2; box-shadow:inset 0 0 0 1px rgba(220,38,38,.14)!important; }
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="facturar" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="facturar" i] a,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="ventas" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="ventas" i] a,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a{ background:#eef4fc; box-shadow:inset 0 0 0 1px rgba(29,78,216,.12)!important; }
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="borrar" i] a img,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="borrar" i] a img,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="facturar" i] a img,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="facturar" i] a img,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="ventas" i] a img,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="ventas" i] a img,
body.vx-chrome .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a img,
body.vx-on .ui-jqgrid-btable td[aria-describedby$="movimientos" i] a img{ width:16px!important; height:16px!important; }

/* ============================================================================
   GRIDS PREMIUM — EDGES: cellattr→pill, subgrids, ledger footer totals, pager. [Step 06]
   ============================================================================ */
/* cellattr fill -> calm neutral pill (vx-grid.js wrapped the text; the harsh full-cell color is gone). The text
   itself carries the meaning (PERCEPCION/DEDUCCION/etc.), so a neutral pill reads premium without losing info. */
body.vx-chrome .ui-jqgrid-btable .vx-cellpill, body.vx-on .ui-jqgrid-btable .vx-cellpill{
  display:inline-flex; align-items:center; padding:2px 10px; border-radius:999px; background:var(--vx-surface-2);
  color:var(--vx-ink); font:700 11.5px/1.5 var(--vx-font); letter-spacing:.02em; box-shadow:inset 0 0 0 1px var(--vx-line); }
/* kill the legacy gridFondo* full-cell color fill (the text now lives in the pill above) */
body.vx-chrome .ui-jqgrid-btable td[class*="gridFondo" i], body.vx-on .ui-jqgrid-btable td[class*="gridFondo" i]{ background:transparent!important; }
/* preserve the color-code as a SOFT pill by class (Verde=percepción green, Rojo=deducción red, Amarillo=amber) */
body.vx-chrome .ui-jqgrid-btable td.gridFondoVerde .vx-cellpill, body.vx-on .ui-jqgrid-btable td.gridFondoVerde .vx-cellpill{ background:#ecfdf5; color:#15803d; box-shadow:inset 0 0 0 1px rgba(21,128,61,.14); }
body.vx-chrome .ui-jqgrid-btable td.gridFondoRojo .vx-cellpill, body.vx-on .ui-jqgrid-btable td.gridFondoRojo .vx-cellpill{ background:#fef2f2; color:#dc2626; box-shadow:inset 0 0 0 1px rgba(220,38,38,.14); }
body.vx-chrome .ui-jqgrid-btable td[class*="Amarillo" i] .vx-cellpill, body.vx-on .ui-jqgrid-btable td[class*="Amarillo" i] .vx-cellpill{ background:#fffbeb; color:#b45309; box-shadow:inset 0 0 0 1px rgba(180,83,9,.14); }

@media (min-width:821px){
  /* subgrids: the nested line-items grid reads as INSIDE the parent card (inset surface, no own shadow/border) */
  body.vx-chrome .ui-subgrid .ui-jqgrid, body.vx-on .ui-subgrid .ui-jqgrid{
    box-shadow:none!important; border:0!important; border-radius:0!important; background:var(--vx-surface-2)!important; }
  body.vx-chrome .ui-subgrid, body.vx-on .ui-subgrid{ background:var(--vx-surface-2)!important; }
  body.vx-chrome .ui-subgrid .ui-jqgrid-htable th, body.vx-on .ui-subgrid .ui-jqgrid-htable th{ background:#eef2f7!important; }

  /* ledger footer totals (footerrow:true -> .ui-jqgrid-ftable / .ui-jqgrid-sdiv): the accent summary line */
  body.vx-chrome .ui-jqgrid-sdiv, body.vx-on .ui-jqgrid-sdiv{ background:var(--vx-surface-2)!important; border:0!important; border-top:1px solid var(--vx-line)!important; }
  body.vx-chrome .ui-jqgrid-ftable td, body.vx-on .ui-jqgrid-ftable td{
    background:transparent!important; border:0!important; color:var(--vx-accent-d)!important; font-weight:800!important;
    font-variant-numeric:tabular-nums; padding-top:10px!important; padding-bottom:10px!important; }

  /* pager: calm premium footer — muted record count, tidy controls, top hairline */
  body.vx-chrome .ui-jqgrid-pager, body.vx-on .ui-jqgrid-pager{
    background:var(--vx-surface-2)!important; border:0!important; border-top:1px solid var(--vx-line)!important;
    min-height:42px; color:var(--vx-mut)!important; }
  body.vx-chrome .ui-jqgrid-pager .ui-pg-input, body.vx-on .ui-jqgrid-pager .ui-pg-input{
    border:1px solid var(--vx-line)!important; border-radius:8px!important; min-height:26px; }
  body.vx-chrome .ui-jqgrid-pager .ui-pg-table td, body.vx-on .ui-jqgrid-pager .ui-pg-table td{ color:var(--vx-mut)!important; }
}

/* document grids: tighter HEADER padding (padding-only — does NOT change column width, so no header/body desync)
   so the status labels fit the columns now widened in the colModel (Activo/Timbrado/version). [pilot CSS] */
body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-htable th,
body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-htable th,
body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-htable th{ padding-left:7px!important; padding-right:7px!important; }
/* ============================================================================
   MOBILE — document-grid ANSWER CARD + modal cleanup. Phone grid = card stack (no header, display:block) so
   hiding columns is SAFE. Ancestor chain (.ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable) out-specifies the
   generic card rule's :not() so the hides win. [pilot CSS]
   ============================================================================ */
@media (max-width:820px){
  /* hide breakdown noise on document-grid cards (keep estado·serie·folio·name·fecha·total·saldo·pagado) */
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_version" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_subTotal" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuento" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuentox100" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAimporte" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_ISRretencion" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAretencion" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_totalMXN" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Moneda" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TipoCambio" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_tipoDeComprobante" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_evinuxTipoCFD" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Provisto" i],
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TomardeInventario" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_version" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_subTotal" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuento" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuentox100" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAimporte" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_ISRretencion" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAretencion" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_totalMXN" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Moneda" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TipoCambio" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_tipoDeComprobante" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_evinuxTipoCFD" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Provisto" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TomardeInventario" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_version" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_subTotal" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuento" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_descuentox100" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAimporte" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_ISRretencion" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_IVAretencion" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_totalMXN" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Moneda" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TipoCambio" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_tipoDeComprobante" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_evinuxTipoCFD" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_Provisto" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_TomardeInventario" i]{ display:none!important; }
  /* receptor name = the card anchor (bigger, no label, first) */
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i]{ font-size:16px!important; font-weight:700!important; order:-1; }
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i]::before,
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i]::before,
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_nombre" i]::before{ content:none!important; }
  /* TOTAL = the prominent number */
  body.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_total" i],
  body.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_total" i],
  body.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[aria-describedby$="_total" i]{ font-size:18px!important; font-weight:800!important; color:var(--vx-accent-d)!important; }

  /* MODAL mobile: drop the redundant Serie/Folio box (folio is in the answer header) */
  body.vx-chrome #CFD #cfd_SerieyFolio, body.vx-page-consultacfd #cfd_SerieyFolio{ display:none!important; }
  body.vx-chrome #CFD #cfd_Fecha, body.vx-page-consultacfd #cfd_Fecha{ width:100%!important; float:none!important; }
  /* estado pill never wraps */
  body.vx-chrome #CFD .vx-doc-summary .vx-sum-pill, body.vx-page-consultacfd .vx-doc-summary .vx-sum-pill{ white-space:nowrap; }
  /* certification: tighter stacked key-value */
  body.vx-chrome #CFD #cfd_DatosSAT td.tbl_bdr_not_top.txt_leftaligned, body.vx-page-consultacfd #cfd_DatosSAT td.tbl_bdr_not_top.txt_leftaligned{ line-height:1.55!important; }
}

/* ============================================================================
   v3 MODAL "SMART RECEIPT" accordion (Step 06) — mobile-only collapse of low-value reference sections
   (Certificación, QR) so the CFDI modal opens to hero + receptor + conceptos + totals, not a chorizo.
   js2/vx-doc.js tags `.vx-acc-section` then builds a `.vx-acc-tog` toggle + `.vx-acc-collapsed` (mobile only).
   Desktop never collapses (rules live in @media max-width:820). Print unaffected (media=screen).
   ============================================================================ */
@media (max-width:820px){
  /* the toggle button (one tap to reveal a reference section): [label] [muted preview] ……… [chevron] */
  body.vx-chrome #CFD .vx-acc-tog, body.vx-page-consultacfd .vx-acc-tog, body.vx-page-consultacompra .vx-acc-tog{
    display:flex; width:100%; box-sizing:border-box; align-items:center; gap:10px;
    margin:10px 0 0; padding:13px 16px; background:var(--vx-surface-2); border:1px solid var(--vx-line);
    border-radius:12px; font:700 14px/1.2 var(--vx-font); color:var(--vx-ink); text-align:left; cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:background .15s ease; }
  body.vx-chrome #CFD .vx-acc-tog:active, body.vx-page-consultacfd .vx-acc-tog:active{ background:#eef2f7; }
  body.vx-chrome #CFD .vx-acc-label, body.vx-page-consultacfd .vx-acc-label{ flex:0 0 auto; }
  body.vx-chrome #CFD .vx-acc-prev, body.vx-page-consultacfd .vx-acc-prev{
    flex:1 1 auto; min-width:0; color:var(--vx-mut); font-weight:600; font-size:12.5px; font-variant-numeric:tabular-nums;
    white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:right; }
  body.vx-chrome #CFD .vx-acc-tog::after, body.vx-page-consultacfd .vx-acc-tog::after, body.vx-page-consultacompra .vx-acc-tog::after{
    content:"\25BE"; flex:0 0 auto; margin-left:auto; font-size:13px; color:var(--vx-mut); transition:transform .2s ease; transform:rotate(-90deg); }  /* ▾ -> points right (collapsed) */
  body.vx-chrome #CFD .vx-acc-tog[aria-expanded="true"]::after, body.vx-page-consultacfd .vx-acc-tog[aria-expanded="true"]::after,
  body.vx-page-consultacompra .vx-acc-tog[aria-expanded="true"]::after{ transform:rotate(0deg); }  /* ▾ down (expanded) */
  /* the collapsed section: hidden until the toggle is tapped */
  body.vx-chrome #CFD .vx-acc-collapsed, body.vx-page-consultacfd .vx-acc-collapsed, body.vx-page-consultacompra .vx-acc-collapsed{ display:none!important; }
  /* respect reduced-motion: no chevron spin */
  @media (prefers-reduced-motion:reduce){
    body.vx-chrome #CFD .vx-acc-tog, body.vx-page-consultacfd .vx-acc-tog,
    body.vx-chrome #CFD .vx-acc-tog::after, body.vx-page-consultacfd .vx-acc-tog::after{ transition:none!important; }
  }
}

/* ============================================================================
   v3 TRANSACTION CARD — final overrides (placed LAST so equal-specificity wins by source order).
   The card AMOUNT is DARK like the pilot's reference. The v2 "accent money" rules color td[_total]/[totalmxn]
   blue at (0,6,4) specificity on the document grids; this matches that specificity but comes later, and is
   scoped to @media max-width:820 so DESKTOP keeps its shipped blue accent. Card-only, gated, reversible.
   ============================================================================ */
@media (max-width:820px){
  body.vx-chrome .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"],
  body.vx-on .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"]{
    color:var(--vx-ink)!important; font-size:16px!important; font-weight:700!important; }
}

/* ============================================================================
   v5 (2026-06-15) — mobile document-grid card, matched to the pilot's reference:
     line 1 = NAME (big bold)            $AMOUNT (big bold)   [checkbox top-right]
     line 2 = short-date · type-badge · estado (plain) ............ timbrado ✓ (right)
   PILOT ONLY (body.vx-chrome), the 4 document grids; appended LAST so it wins over the
   all-users overrides.css page-shell. Desktop, non-pilot, and catalog cards untouched.
   ============================================================================ */
@media (max-width:820px){
  /* (a) TOP RECLAIM — only the document grids (leave nvocfd40 / forms / catalogs alone) */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-page-shell::before,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-page-shell::before,
  body.vx-chrome.vx-page-consultacompras .vx-page-shell::before,
  body.vx-chrome.vx-page-consultapagosacfds .vx-page-shell::before{ display:none!important; }
  body.vx-chrome.vx-page-consultacfdemitidos table.vx-page-shell,
  body.vx-chrome.vx-page-consultanominasemitidas table.vx-page-shell,
  body.vx-chrome.vx-page-consultacompras table.vx-page-shell,
  body.vx-chrome.vx-page-consultapagosacfds table.vx-page-shell{ background:transparent!important; padding:0!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-section-shell,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-section-shell,
  body.vx-chrome.vx-page-consultacompras .vx-section-shell,
  body.vx-chrome.vx-page-consultapagosacfds .vx-section-shell{
    margin:0!important; padding:0!important; background:transparent!important; border:0!important; box-shadow:none!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-gridfilter,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-gridfilter,
  body.vx-chrome.vx-page-consultacompras .vx-gridfilter,
  body.vx-chrome.vx-page-consultapagosacfds .vx-gridfilter{ padding:4px 14px 8px!important; }

  /* (b) CARD LAYOUT — name|amount|checkbox over meta|·|timbrado (checkbox now top-right, timbrado bottom-right) */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow{
    grid-template-columns:minmax(0,1fr) auto auto!important;
    grid-template-areas:"vxname vxamt vxsel" "vxmeta vxmeta vxtimb"!important;
    column-gap:12px!important; row-gap:6px!important; padding:14px!important; margin-bottom:10px!important; align-items:center!important; }

  /* NAME + AMOUNT = the two heroes */
  body.vx-chrome.vx-page-consultacfdemitidos tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultanominasemitidas tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultacompras tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultapagosacfds tr.jqgrow>td[data-vxrole="name"]{
    font-size:20px!important; font-weight:800!important; color:var(--vx-ink)!important; align-self:center; }
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"],
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"],
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"],
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"]{
    align-self:center; font-size:20px!important; font-weight:800!important; color:var(--vx-ink)!important;
    font-variant-numeric:tabular-nums; letter-spacing:-.01em; }
  body.vx-chrome.vx-page-consultacfdemitidos tr.jqgrow>td[data-vxrole="amount"]::before,
  body.vx-chrome.vx-page-consultanominasemitidas tr.jqgrow>td[data-vxrole="amount"]::before,
  body.vx-chrome.vx-page-consultacompras tr.jqgrow>td[data-vxrole="amount"]::before,
  body.vx-chrome.vx-page-consultapagosacfds tr.jqgrow>td[data-vxrole="amount"]::before{ content:"$"; opacity:.85; font-weight:700; margin-right:1px; }

  /* META line — short-date · type badge · estado (one muted row, left) */
  body.vx-chrome.vx-page-consultacfdemitidos tr.jqgrow>td[data-vxrole="meta"] .vx-meta,
  body.vx-chrome.vx-page-consultanominasemitidas tr.jqgrow>td[data-vxrole="meta"] .vx-meta,
  body.vx-chrome.vx-page-consultacompras tr.jqgrow>td[data-vxrole="meta"] .vx-meta,
  body.vx-chrome.vx-page-consultapagosacfds tr.jqgrow>td[data-vxrole="meta"] .vx-meta{
    display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  body.vx-chrome tr.jqgrow .vx-meta-date{ font-size:13.5px; font-weight:600; color:var(--vx-mut); }
  body.vx-chrome tr.jqgrow .vx-type-badge{ font-size:11px; font-weight:700; letter-spacing:.02em; color:var(--vx-accent);
    background:#eaf1fe; padding:2px 8px; border-radius:999px; line-height:1.45; }
  body.vx-chrome tr.jqgrow .vx-estado{ font-size:13.5px; font-weight:600; color:var(--vx-mut); }
  body.vx-chrome tr.jqgrow .vx-estado-crit{ color:var(--vx-crit); }

  /* TIMBRADO ✓ (bottom-right): green check when stamped, faint dash when not */
  body.vx-chrome tr.jqgrow>td[data-vxrole="timbrado"]{
    grid-area:vxtimb; justify-self:end; align-self:center; padding:0!important; border:0!important;
    background:transparent!important; font-size:0; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="timbrado"] > *{ display:none!important; }   /* drop legacy icon + green cell-fill box -> bare check */
  body.vx-chrome tr.jqgrow>td[data-vxrole="timbrado"].vx-st-yes::after{ content:"\2713"; font-size:19px; font-weight:800; color:var(--vx-ok); background:none!important; box-shadow:none!important; padding:0!important; }
  body.vx-chrome tr.jqgrow>td[data-vxrole="timbrado"].vx-st-no::after{ content:"\2014"; font-size:15px; font-weight:700; color:#94a3b8; background:none!important; box-shadow:none!important; padding:0!important; }

  /* CHECKBOX — top-right, clean rounded square */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox{
    grid-area:vxsel; align-self:center; justify-self:end; margin:0 0 0 4px!important; padding:6px!important; min-width:34px!important; min-height:34px!important; }
  body.vx-chrome .vx-selbox .vx-selcb{ width:22px!important; height:22px!important; border-color:#cbd6e6!important; }
}

/* ============================================================================
   v6 (2026-06-15) — COUCH WORKSPACE. PILOT ONLY (body.vx-chrome), the 4 document grids,
   appended LAST so it wins. Fixed command zone + the card river as the only scroll surface:
   (Step 03) reclaim the legacy corner/logo header row; (Step 02) the search pins under the
   app-bar (only the list scrolls); (Step 04) compact ~75px cards; (Step 05) edge-to-edge.
   Desktop, non-pilot, nvocfd40, the modal and catalogs untouched (per-page scoped).
   ============================================================================ */
@media (max-width:820px){
  /* (Step 03) RECLAIM TOP — the first row of the legacy frame is the corner/logo/home strip; the app-bar already
     gives brand + home, and its images are all display:none, but the row still eats ~66px. Drop it. */
  body.vx-chrome.vx-page-consultacfdemitidos table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner),
  body.vx-chrome.vx-page-consultanominasemitidas table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner),
  body.vx-chrome.vx-page-consultacompras table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner),
  body.vx-chrome.vx-page-consultapagosacfds table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }

  /* (Step 02a) the legacy frame has overflow:hidden (overrides.css) which would trap position:sticky inside it —
     relax it on the doc pages so the sticky search anchors to the viewport. (Root h-scroll guard still holds.) */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-page-shell,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-page-shell,
  body.vx-chrome.vx-page-consultacompras .vx-page-shell,
  body.vx-chrome.vx-page-consultapagosacfds .vx-page-shell{ overflow-x:clip; overflow-y:visible; }

  /* (Step 02b) FIXED HEADER — the search pins flush under the app-bar; the list scrolls beneath it. */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-gridfilter,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-gridfilter,
  body.vx-chrome.vx-page-consultacompras .vx-gridfilter,
  body.vx-chrome.vx-page-consultapagosacfds .vx-gridfilter{
    position:sticky!important; top:var(--vx-appbar-h)!important; z-index:30;
    margin:0!important; padding:8px 10px!important; background:var(--vx-bg);
    box-shadow:0 8px 14px -12px rgba(16,24,40,.35); }

  /* (Step 04) COMPACT CARD — squeeze whitespace first (heroes keep their size). Target ~75px. */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow{
    padding:10px 12px!important; row-gap:2px!important; margin:0 10px 8px 10px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultanominasemitidas tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultacompras tr.jqgrow>td[data-vxrole="name"],
  body.vx-chrome.vx-page-consultapagosacfds tr.jqgrow>td[data-vxrole="name"]{ line-height:1.15!important; }

  /* (Step 05) WIDEN — zero the legacy frame / section / grid side padding so the card river goes edge-to-edge
     (the 10px card gutter above is the only breathing room). */
  body.vx-chrome.vx-page-consultacfdemitidos table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-chrome.vx-page-consultanominasemitidas table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-chrome.vx-page-consultacompras table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-chrome.vx-page-consultapagosacfds table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-chrome.vx-page-consultacfdemitidos .vx-section-shell,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-section-shell,
  body.vx-chrome.vx-page-consultacompras .vx-section-shell,
  body.vx-chrome.vx-page-consultapagosacfds .vx-section-shell,
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid,
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-view,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-view,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-view,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-view,
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-bdiv{ padding-left:0!important; padding-right:0!important; }
}

/* v6-tune (2026-06-15) — hit the targets the measurements exposed:
   (a) the selbox was 46px (min-height 34 + padding) — the card's height FLOOR, not the text. Shrink it so the
       card lands ~72px (heroes keep their 20px). (b) a residual ~13px sits on the body/frame left — zero it so
       the river is truly edge-to-edge (the 10px card margin is the only gutter). Doc pages only, mobile, pilot. */
@media (max-width:820px){
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow > .vx-selbox{
    padding:4px!important; min-width:0!important; min-height:0!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-btable>tbody>tr.jqgrow,
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-btable>tbody>tr.jqgrow{ padding:8px 12px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos,
  body.vx-chrome.vx-page-consultanominasemitidas,
  body.vx-chrome.vx-page-consultacompras,
  body.vx-chrome.vx-page-consultapagosacfds,
  body.vx-chrome.vx-page-consultacfdemitidos table.tbl_bckgrnd_brite,
  body.vx-chrome.vx-page-consultanominasemitidas table.tbl_bckgrnd_brite,
  body.vx-chrome.vx-page-consultacompras table.tbl_bckgrnd_brite,
  body.vx-chrome.vx-page-consultapagosacfds table.tbl_bckgrnd_brite{ padding-left:0!important; padding-right:0!important; margin-left:0!important; margin-right:0!important; }
}
/* v6-tune2: the .vx-page-frame wrapper (overrides.css) adds padding-left/right:12px — the last side gutter. Zero it
   on the doc pages so the card river is truly edge-to-edge (the 10px card margin is the only breathing room). */
@media (max-width:820px){
  body.vx-chrome.vx-page-consultacfdemitidos .vx-page-frame,
  body.vx-chrome.vx-page-consultanominasemitidas .vx-page-frame,
  body.vx-chrome.vx-page-consultacompras .vx-page-frame,
  body.vx-chrome.vx-page-consultapagosacfds .vx-page-frame{ padding-left:0!important; padding-right:0!important; }
}

/* v6 friction (2026-06-15) — the list owns the gesture: contain the scroll so the whole page never rubber-bands
   / pull-to-refreshes past the river (native-app feel). Doc pages, mobile, pilot. */
@media (max-width:820px){
  body.vx-chrome.vx-page-consultacfdemitidos,
  body.vx-chrome.vx-page-consultanominasemitidas,
  body.vx-chrome.vx-page-consultacompras,
  body.vx-chrome.vx-page-consultapagosacfds{ overscroll-behavior-y:contain; }
}

/* ============================================================================
   CLIENTES MODULE (2026-06-15) — catalog cards: un-stack the per-row actions + the couch workspace.
   GENERALIZED 2026-06-16 to also cover PROVEEDORES (docs/plans/proveedores-module-premium): the workspace shell
   below is scoped to :is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) (Clientes + Proveedores) and the modal to
   :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO). PILOT/admin ONLY (body.vx-chrome), mobile. The .vx-actions row applies to any
   catalog whose card has >=2 actions (vx-grid.js buildActionsRow moves them). Desktop / non-pilot / documents untouched.
   ============================================================================ */
@media (max-width:820px){
  /* (Step 02) UN-STACK — the 4 action <td>s were each a full-width row (the tower). vx-grid.js moves their controls
     into ONE .vx-actions strip; render it as a single tidy chip row at the card bottom. */
  body.vx-chrome tr.jqgrow > .vx-actions[data-vxrole="actions"]{
    grid-column:1 / -1; display:flex; gap:8px; justify-content:flex-end; align-items:center; flex-wrap:wrap;
    margin-top:8px; padding-top:8px; border-top:1px solid var(--vx-line); }
  body.vx-chrome tr.jqgrow .vx-act{ display:inline-flex; align-items:center; justify-content:center;
    min-width:42px; min-height:42px; padding:6px; border-radius:11px; background:var(--vx-surface-2);
    box-shadow:inset 0 0 0 1px var(--vx-line); -webkit-tap-highlight-color:transparent; }
  body.vx-chrome tr.jqgrow .vx-act img{ width:24px!important; height:24px!important; }
  body.vx-chrome tr.jqgrow .vx-act:active{ background:var(--vx-line); }       /* press feedback */
  /* (Iter5) action hierarchy: the #1 job is the accent primary; the destructive one (borrar) is de-emphasized and
     ordered last so the viejito doesn't tap it by reflex. Catalog-aware: nvocfd (Clientes=nueva factura) /
     nvacompra (Proveedores=nueva compra) are the primaries; doctosporcobrar/doctosporpagar and ventas/compras mid. */
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="nvocfd"],
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="nvacompra"]{ order:1; background:var(--vx-accent); box-shadow:none; }
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="nvocfd"] img,
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="nvacompra"] img{ filter:brightness(0) invert(1); }   /* white glyph on accent */
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="doctosporcobrar"],
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="doctosporpagar"]{ order:2; }
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="ventas"],
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="compras"]{ order:3; }
  body.vx-chrome tr.jqgrow .vx-act[data-vxact="borrar"]{ order:9; opacity:.55; }

  /* (Iter5) name hero + muted RFC sub-line: vx-grid.js split "<b>nombre<br>rfc</b>" into .vx-name-main + .vx-name-sub */
  body.vx-chrome tr.jqgrow td[data-vxrole="name"] .vx-name-main{ display:block; font-weight:800; color:var(--vx-ink);
    font-size:15.5px; line-height:1.25; overflow:hidden; text-overflow:ellipsis; }
  body.vx-chrome tr.jqgrow td[data-vxrole="name"] .vx-name-sub{ display:block; font-weight:600; color:var(--vx-mut);
    font-size:11.5px; letter-spacing:.02em; margin-top:1px; font-family:var(--vx-num); }
  /* (Productos 2026-06-16) plain-description catalogs (productos) have NO name+RFC split, so the bare name cell would
     inherit the legacy column's center align — left-align it so the description reads as a proper card hero. Scoped to
     the catalog group: a no-op for receptores/proveedores (their .vx-name-main is already left). */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) tr.jqgrow>td[data-vxrole="name"]{ text-align:left!important; }

  /* (Iter5) a $0 balance is the calm default — don't shout it (vx-grid.js classes vx-amt-zero). Must out-specify the
     amount-dark override (the long .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable prefix, !important) — match it + the class. */
  body.vx-chrome .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"].vx-amt-zero,
  body.vx-on .ui-jqgrid .ui-jqgrid-view .ui-jqgrid-btable>tbody>tr.jqgrow>td[data-vxrole="amount"].vx-amt-zero{ color:var(--vx-mut)!important; font-weight:600!important; }

  /* (Iter5) inactive client (legacy txt_cfdcancelado row) reads CALM — muted card, not red noise */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-btable>tbody>tr.jqgrow.txt_cfdcancelado{ opacity:.6; }

  /* (Iter5) catalog new-record CTA in the fixed header (vx-grid.js ensureCatalogNewCta via VX_CATALOG_CTA -> nuevoReceptor / nuevoProveedor) */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-gridfilter-cta{ display:flex; gap:8px; align-items:stretch; flex-wrap:nowrap; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-gridfilter-cta input[type="search"]{ flex:1 1 auto; min-width:0; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-ctabar{ display:flex; justify-content:flex-end; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-newcta{ flex:0 0 auto; display:inline-flex; align-items:center; gap:6px;
    min-height:46px; padding:0 16px; border:0; border-radius:13px; background:var(--vx-accent); color:#fff;
    font-weight:800; font-size:14.5px; white-space:nowrap; -webkit-tap-highlight-color:transparent;
    box-shadow:0 10px 22px -12px rgba(37,99,235,.7); }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-newcta:active{ background:var(--vx-accent-d); }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-newcta .vx-newcta-plus{ font-size:20px; line-height:1; font-weight:400; margin-top:-1px; }

  /* (Step 03) WORKSPACE for Clientes — same engine as the v6 document grids. */
  /* reclaim the legacy corner/logo row */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }
  /* fixed search header (only the list scrolls); clip the wide pager without breaking sticky */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-page-shell,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite{ overflow-x:clip; overflow-y:visible; }   /* receptores has no .vx-page-shell — clip the frame table itself */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-gridfilter{
    position:sticky!important; top:var(--vx-appbar-h)!important; z-index:30;
    margin:0!important; padding:8px 10px!important; background:var(--vx-bg);
    box-shadow:0 8px 14px -12px rgba(16,24,40,.35); }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral){ overscroll-behavior-y:contain; }
  /* edge-to-edge: zero the legacy frame side padding + a small card gutter */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-page-frame,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .vx-section-shell,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-view,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-bdiv,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite > tbody > tr > td{ padding-left:0!important; padding-right:0!important; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-btable>tbody>tr.jqgrow{ margin-left:10px!important; margin-right:10px!important; padding:12px 14px!important; }
}

/* ============================================================================
   CATALOG GRID — CAP TO VIEWPORT (2026-06-22). The couch-workspace deliberately let the jqGrid body GROW so the whole
   PAGE scrolled (the global rules: line ~273 mobile + ~462 desktop set .ui-jqgrid-bdiv to height:auto/overflow:visible).
   With a large catalog (e.g. productos = 58 rows) that grows the grid — and its pager — far past the viewport (measured
   on emisor 58: desktop body 4468px tall, pager at y=4314 on a 900px screen; mobile 6140px tall). Per owner: the grid
   must NOT grow beyond the viewport on desktop OR mobile. Cap the body to a viewport-relative max-height with an
   INTERNAL scroll, so the page fits the screen and the pager stays visible. Scoped to the catalog :is() group; the
   (0,3,1) specificity + later source order out-rank the global (0,2,1) bdiv rules. DISPLAY-ONLY (no JS, no data path).
   Offsets are measured: desktop = bdiv top ~295 (appbar + title + 99px header) + pager 48 + slack; mobile = sticky-
   filter bdiv top ~143 + pager 43 + fixed bottom-nav 60 + slack. height:auto keeps short catalogs from showing an
   empty scrollbox; max-height caps the long ones. ============================================================================ */
@media (min-width:821px){
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-bdiv{
    height:auto!important; max-height:max(200px, calc(100vh - 420px))!important; overflow-y:auto!important; }
  /* FULL-BLEED desktop: line ~449 sets `body.vx-chrome #gridContainer{ padding:6px 26px 40px }` (an ID rule that
     out-specifies any class rule). For catalogs, override it BY ID with a tight gutter — padding-left:0 (the legacy
     10px corner column already supplies a small left inset so the grid reads symmetric vs the ~10px right) + a small
     8px bottom so the grid fills the height instead of leaving 40px of dead space. Left-align the centered frame and
     zero the inner cell/wrapper/view padding. Do NOT force width:100% — the frame is an auto-layout table, so a
     %-width makes the grid cell content-driven and shrinkToFit falls back to the natural column sum (overflow). The
     inline JS keeps the frame at window.width-20 (explicit, viewport-relative px); paired with shrinkToFit
     (productos.php, pilot) the columns refit that width — no horizontal scroll. */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) #gridContainer{ padding:6px 10px 8px 0!important; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) > div[align="center"]{ text-align:left!important; }
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) [id^="div_wrapper_"],
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-view{ padding-left:0!important; padding-right:0!important; }
  /* the legacy frame's decorative bottom corner row (td.tbl_bottom_corner + an empty colspan cell) adds ~90px of dead
     space under the grid — hide it so the grid fills to the bottom (the top corner row stays: it holds the title +
     "Registrar un Producto" CTA on desktop). */
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_bottom_corner){ display:none!important; }
}
@media (max-width:820px){
  body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) .ui-jqgrid-bdiv{
    height:auto!important; max-height:max(220px, calc(100dvh - 330px))!important; overflow-y:auto!important; }
}
/* the legacy "Configurador de Reportes" block (configuradordereportes.js body-appends #<Page>_cr_01) hangs orphaned
   below the catalog grid in the reskin — hide it for pilot catalog pages (non-pilot legacy keeps it). */
body.vx-chrome:is(.vx-page-receptores,.vx-page-proveedores,.vx-page-productos,.vx-page-empleados,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral) [id$="_cr_01"]{ display:none!important; }

/* CLIENTES MODAL (2026-06-15) — consultaReceptor/nuevoReceptor open receptor.php (cliente) or empleado.php into the
   :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) jQuery-UI dialog at a fixed 960px -> crushed on a phone. Make it full-width + one readable column.
   CSS/layout ONLY — never touches the form fields, the CambioItem dirty-watcher, or the save path. Pilot, mobile. */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(:is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO)){
    width:100vw!important; max-width:100vw!important; left:0!important; right:0!important;
    top:var(--vx-appbar-h)!important; height:auto!important; max-height:calc(100dvh - var(--vx-appbar-h))!important;
    border-radius:0!important; box-sizing:border-box; }
  /* the dialog opens with a fixed inline height:625 (receptor.js) -> on a short phone the lower add-rows fall off
     screen with no scroll. Cap the content to the viewport and let it scroll (Save stays reachable either way). */
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO){ width:auto!important; max-width:100%!important; box-sizing:border-box;
    height:auto!important; max-height:calc(100dvh - var(--vx-appbar-h) - 44px)!important; overflow-y:auto!important; -webkit-overflow-scrolling:touch; }
  /* one-column reflow: the legacy form table/cells stack full-width */
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) table{ width:100%!important; max-width:100%!important; table-layout:auto!important; }
  /* docs/plans/responsive-dialogs/04 — la pieza que faltaba: table>100% no ayuda si la
     <td> original no crece con ella. Un input forzado a width:100% se quedaba atrapado
     en su celda de ancho fijo -> el "$"/label se veía arriba del input en vez de a su
     izquierda. Mismo reflujo tr/td que ya se usó en los pasos 01-03. */
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) table > tbody > tr,
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) table > tbody > tr > td{
    display:block!important; width:100%!important; text-align:left!important; }
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) input:not([type=checkbox]):not([type=radio]):not([type=image]),
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) select,
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) textarea{ width:100%!important; max-width:100%!important; box-sizing:border-box; min-height:42px; font-size:16px!important; }
}

/* CLIENTES MODAL — DESKTOP upgrade (2026-06-15): the desktop grid is already premium (shared engine), but the
   client edit dialog kept the legacy form chrome. Give it a calm premium surface + consistent inputs. CSS ONLY —
   NEVER touches field widths (inline %), the CambioItem dirty-watcher, or the save path. Pilot, desktop. */
@media (min-width:821px){
  body.vx-chrome .ui-dialog:has(:is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO)){ border-radius:var(--vx-radius-lg)!important; overflow:hidden;
    box-shadow:0 30px 70px -28px rgba(15,23,42,.55)!important; border:1px solid var(--vx-line)!important; }
  body.vx-chrome .ui-dialog:has(:is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO)) .ui-dialog-titlebar{ background:var(--vx-surface-2)!important;
    border:0!important; border-bottom:1px solid var(--vx-line)!important; }
  /* section heading "-= Datos generales =-" -> calm uppercase label */
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) .txt_size14px{ display:inline-block; color:var(--vx-mut); text-transform:uppercase;
    letter-spacing:.06em; font-size:11.5px!important; }
  /* inputs: premium border/radius/focus — width stays the legacy inline %; box-sizing keeps the % honored */
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) input:not([type=checkbox]):not([type=radio]):not([type=image]):not([type=hidden]),
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) select,
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) textarea{ box-sizing:border-box; min-height:36px; padding:4px 10px;
    border:1px solid var(--vx-line); border-radius:10px; background:#fff; }
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) input:focus, body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) select:focus,
  body.vx-chrome :is(#CFD_RECEPTOR,#CFD_PROVEEDOR,#CFD_PRODUCTO) textarea:focus{ outline:0; border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
}

/* ============================================================================
   ADDENDA RESKIN — CSS-ONLY, gated, the addenda fragment (nvocfdaddendas.php).
   The fragment is require_once'd INSIDE #divNvoCFD on the premium creation forms, so its inputs ALREADY inherit the
   creation-forms premium (16px, border-radius:10px, #cbd5e1 border, full-width for the free-flow blocks). The honest
   gap this block closes: (1) the legacy pure-blue (#0000FF) `.txt_bluecolor` labels are off-brand → calm slate at all
   widths; (2) on the phone the addenda fields just append to the form → a section card + block labels group them.
   RESTYLE ONLY: never set a container <div>'s `display` (cfd.js show/hide + the INE per-entity repeater + the Carta
   Porte #AddendaCartaPortetbl toggle own it); never touch any field name/id/maxlength/onKeyPress/onchange/onblur.
   Scope = the 4 parents that include the fragment, addenda family by id^="Addenda".
   ============================================================================ */
/* (1) calm the legacy bright-blue labels — wrong on every width */
body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) :is([id^="Addenda"]) .txt_bluecolor{ color:#334155!important; }
/* (1b) Carta Porte (the longest block, multi-section): turn its Origen/Destino/Transporte/Conductor sub-headers
   (strong.txt15px) into calm section dividers so the long form reads in chunks. Structural — applies all widths.
   Correct-by-construction: Carta Porte renders only on tipoDeComprobante=trasladocp (capability-gated, not reachable
   by vxtest), so this is contract-styled, not screenshot-verified. */
body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) #AddendaCartaPorte .txt15px{
  display:block; margin-top:14px; padding-top:10px; border-top:1px solid var(--vx-line,#e2e8f0); font-size:14px; font-weight:800; color:#0f172a; }

@media (max-width:820px){
  /* (2) section card — groups the addenda as a recognizable, distinct section (light tint vs the white form body, so
     the user sees "this is the client's addenda"). White inputs sit on the tint. Container display stays JS-owned.
     `:not(#Addenda_div)` skips the bare label/hidden-input wrapper (no card needed). */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) :is([id^="Addenda"]):not(table):not(#Addenda_div){
    background:var(--vx-bg,#f8fafc); border:1px solid var(--vx-line,#e2e8f0); border-radius:14px; padding:14px; margin:12px 0; }
  /* flatten any addenda card NESTED inside another addenda so there's no card-within-a-card. The real nested case is
     the INE per-entity repeater: #AddendaINEEntidad{n} are genuine descendants of #AddendaINE (nvocfdaddendas.php:676).
     (AddendaIF/AddendaOC are SIBLINGS of AddendaSPC, not descendants — they get single cards either way; this
     descendant-combinator rule simply doesn't touch them.) Adversarial-review fold. */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) :is([id^="Addenda"]) :is([id^="Addenda"]):not(table){
    background:transparent; border:0; border-radius:0; padding:0; margin:0; }
  /* labels block-level so each sits above its field (the free-flow blocks); calmer rhythm.
     STYLE-A 5-col grids (Walmart/Comex/FEMSA) keep their fixed grid: all required fields stay visible (no
     off-screen scroll that could hide a required field); a true 1-field-per-line for those 2-row tables would need a
     PHP markup change (out of this CSS-only scope) — see Decision D1. The calm labels + card already de-noise them. */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) :is([id^="Addenda"]) strong{
    display:block; margin:8px 0 3px; font-family:var(--vx-font); }
  /* STYLE-A: trim heavy label wrapping (5 lines -> ~2) so the compact grid reads cleaner; inputs stay full-cell */
  body:is(.vx-page-nvocfd40,.vx-page-nvonomina,.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte) :is(#AddendaWalmart,#AddendaComex,#AddendaFEMSAJDV) strong{
    font-size:11.5px; line-height:1.25; }
}

/* ============================================================================
   NVOPDV / POS RESKIN — CSS-ONLY, gated, body.vx-page-nvopdv (the Punto de Venta register, evinuxTipoCFD=NOTA).
   DEDICATED block (POS UX != the document forms — we do NOT join the creation-forms :is()). RESTYLE ONLY: never touch
   fields/ids/handlers, CobraPDV()/nuevoCFD()/actualizaCantidades()/the F-key router, the jQuery-UI dialogs' position,
   or the QZ/print path. Cobrar writes a NOTA + decrements inventory — never fired in tests.
   ============================================================================ */
@media (max-width:820px){
  /* --- CART as a receipt: the fixed 4-col header squishes ("Ca/nti/da/d") on a phone; hide it and let each row
     self-describe as "qty · description · importe · ✕". The separate <hr> rows become a row border. --- */
  /* F4: the Cobrar button is the LAST element; the global 60px nav reserve is ~equal to the 61px fixed nav, so its
     bottom edge grazed the bar. Give the POS extra bottom clearance so Cobrar sits comfortably ABOVE the nav. */
  body.vx-page-nvopdv{ padding-bottom:calc(var(--vx-bottomnav-h) + 40px + env(safe-area-inset-bottom,0px))!important; }
  body.vx-page-nvopdv #ConceptosTitulos > thead{ display:none; }
  /* the cart goes block-based so each row is a flex line at 100% of the scroll box (a flex <tr> left inside a
     display:table shrink-wraps to content and overflows the page → block + min-width:0 lets the description shrink+wrap) */
  body.vx-page-nvopdv #Conceptos, body.vx-page-nvopdv #Conceptos > tbody{ display:block; width:100%; }
  body.vx-page-nvopdv #Conceptos tr[data-hr="1"]{ display:none; }
  body.vx-page-nvopdv #Conceptos tr[data-rownum]:not([data-hr="1"]){
    display:flex; width:100%; box-sizing:border-box; align-items:center; gap:10px; padding:9px 4px; border-bottom:1px solid var(--vx-line,#e2e8f0); }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td{ width:auto!important; padding:0; border:0; }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td:nth-child(1){ flex:0 0 auto; min-width:34px; text-align:center; color:var(--vx-accent-d,#1e40af); }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td:nth-child(2){ flex:1 1 0; min-width:0; text-align:left!important; overflow-wrap:anywhere; }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td:nth-child(2) .txt_dark{ text-align:left; }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td:nth-child(3){ flex:0 0 auto; text-align:right!important; }
  body.vx-page-nvopdv #Conceptos tr[data-rownum] td:nth-child(4){ flex:0 0 auto; }
  body.vx-page-nvopdv #scrollconceptos{ min-height:120px; }

  /* --- TOTALES is a nested table the generic collapse doesn't reach. Collapse it to block so we own the layout: the 3
     value rows (SUBTOTAL / DESCUENTO / TOTAL) become right-aligned label+value lines (spacer dropped, no "SUBTO/TAL"
     wrap); the last <tr> (entry form + actions) stacks full-width. TOTAL is the hero the cashier reads. --- */
  body.vx-page-nvopdv #Totales, body.vx-page-nvopdv #Totales > tbody{ display:block; width:100%; }
  body.vx-page-nvopdv #Totales > tbody > tr{ display:block; width:100%; box-sizing:border-box; }
  /* value rows (have a right-aligned cell) -> flex label + value, right-aligned */
  body.vx-page-nvopdv #Totales > tbody > tr:has(td.txt_rightaligned){ display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; gap:6px 10px; padding:2px 6px; }
  /* hide the empty spacer cells — BUT keep the one carrying cashier feedback (#statusCuantosConceptos count +
     #statusProductoBuscado "PRODUCTO NO ENCONTRADO" scan error); show it full-width above the TOTAL (order:-1). */
  body.vx-page-nvopdv #Totales > tbody > tr:has(td.txt_rightaligned) > td[colspan]:not(:has(#statusCuantosConceptos)){ display:none; }
  body.vx-page-nvopdv #Totales > tbody > tr:has(td.txt_rightaligned) > td[colspan]:has(#statusCuantosConceptos){ flex:1 1 100%; order:-1; text-align:center; padding:0; }
  body.vx-page-nvopdv #Totales > tbody > tr:has(td.txt_rightaligned) > td.txt_rightaligned{ display:block; width:auto!important; padding:0; flex:0 0 auto; }  /* width:auto!important beats the inline style="width:25%" so nowrap labels don't clip */
  body.vx-page-nvopdv #Totales > tbody > tr:has(td.txt_rightaligned) > td.txt_rightaligned:not(:has(input)){ white-space:nowrap; }  /* nowrap labels only */
  body.vx-page-nvopdv #Totales #DescuentoGlobalx100{ width:48px!important; }
  body.vx-page-nvopdv #Totales #DescuentoGlobalScreen{ width:84px!important; }
  body.vx-page-nvopdv #Totales > tbody > tr:has(#NetoaPagar){ border-top:2px solid var(--vx-line,#e2e8f0); margin-top:6px; padding-top:8px; }
  body.vx-page-nvopdv #Totales input.netoapagar{ box-sizing:border-box; width:110px!important; }  /* consistent value width so each row stays one line */
  body.vx-page-nvopdv #NetoaPagar{ font-size:26px!important; font-weight:800; color:var(--vx-accent-d,#1e40af); width:120px!important; height:auto; text-align:right; }
  /* entry+action row (no right-aligned cell): its two tds stack full-width so the entry bar + actions get the viewport */
  body.vx-page-nvopdv #Totales > tbody > tr:not(:has(td.txt_rightaligned)) > td{ display:block; width:100%!important; padding:4px 0; }

  /* --- ACTIONS: Cobrar is the full-width primary; Limpiar a secondary chip (the 48-blank spacer is dropped). The legacy
     "(F2)" <strong> inside the Cobrar link is hidden (our ::after label already says "Cobrar (F2)"). --- */
  body.vx-page-nvopdv img[src*="48-blank"]{ display:none; }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"]) strong{ display:none; }
  body.vx-page-nvopdv td:has(> a > img[src*="60-caja-registradora"]){ display:flex!important; flex-direction:column; gap:10px; align-items:stretch; }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"]){
    display:flex; align-items:center; justify-content:center; gap:10px; min-height:56px; order:2;
    background:var(--vx-accent,#2563eb); border-radius:14px; text-decoration:none; box-shadow:0 6px 18px rgba(37,99,235,.28); }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"])::after{ content:"Cobrar (F2)"; color:#fff; font-weight:800; font-size:18px; font-family:var(--vx-font); }
  body.vx-page-nvopdv a:has(> img[src*="48-tache"]){
    display:flex; align-items:center; justify-content:center; gap:6px; min-height:44px; order:1;
    background:#fff; border:1px solid var(--vx-line,#e2e8f0); border-radius:12px; text-decoration:none; }
  body.vx-page-nvopdv a:has(> img[src*="48-tache"])::after{ content:"Limpiar"; color:#475569; font-weight:700; font-family:var(--vx-font); }
}
@media (min-width:821px){
  /* NVOPDV desktop register: keep the native 994px table layout (no width/table-layout change) — just premium chrome:
     a calm sheet, a clear Cobrar primary button (not a bare icon), an accent TOTAL, and input polish. */
  body.vx-page-nvopdv #divNvoCFD > table.tbl_bckgrnd_brite{ border-radius:14px; box-shadow:var(--vx-shadow,0 10px 30px rgba(2,6,23,.10)); }
  body.vx-page-nvopdv #NetoaPagar{ font-size:22px; font-weight:800; color:var(--vx-accent-d,#1e40af); }
  body.vx-page-nvopdv img[src*="48-blank"]{ display:none; }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"]){
    display:inline-flex; align-items:center; gap:10px; min-height:48px; padding:8px 22px;
    background:var(--vx-accent,#2563eb); border-radius:12px; box-shadow:0 6px 18px rgba(37,99,235,.28); text-decoration:none; }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"]) strong{ display:none; }
  body.vx-page-nvopdv a:has(> img[src*="60-caja-registradora"])::after{ content:"Cobrar (F2)"; color:#fff; font-weight:800; font-size:16px; font-family:var(--vx-font); }
  body.vx-page-nvopdv a:has(> img[src*="48-tache"]){
    display:inline-flex; align-items:center; gap:6px; min-height:40px; padding:6px 14px;
    background:#fff; border:1px solid var(--vx-line,#e2e8f0); border-radius:10px; text-decoration:none; }
  body.vx-page-nvopdv a:has(> img[src*="48-tache"])::after{ content:"Limpiar"; color:#475569; font-weight:700; font-family:var(--vx-font); }
  body.vx-page-nvopdv #pPAPDV, body.vx-page-nvopdv #cPAPDV{ border:1px solid #cbd5e1; border-radius:8px; padding:6px 8px; box-sizing:border-box; }
}

/* NVOPDV — UX: the cash dialog (#CFD_COBRA_PDV, the money moment) reads touch-friendly: big RECIBE entry + a HUGE
   CAMBIO the cashier reads back. STYLE CONTENT ONLY — never the dialog's display/position/z-index (jQuery-UI owns those,
   and CobraPDV() is never fired in tests). Applies at all widths. */
body.vx-page-nvopdv #CFD_COBRA_PDV td{ font-size:16px; padding:8px 10px; }
body.vx-page-nvopdv #CFD_COBRA_PDV #cpdvTotal{ font-size:18px!important; width:140px!important; text-align:right; box-sizing:border-box; }
body.vx-page-nvopdv #CFD_COBRA_PDV #cpdvRecibe{ font-size:24px!important; min-height:48px; width:140px!important; text-align:right; box-sizing:border-box; border:1px solid #cbd5e1; border-radius:8px; }
body.vx-page-nvopdv #CFD_COBRA_PDV #cpdvRecibe:focus{ outline:none; border-color:var(--vx-accent,#2563eb); box-shadow:0 0 0 3px rgba(37,99,235,.12); }
body.vx-page-nvopdv #CFD_COBRA_PDV #cpdvCambio{ font-size:28px!important; font-weight:800; color:var(--vx-accent-d,#1e40af); width:140px!important; text-align:right; box-sizing:border-box; }

@media (max-width:820px){
  /* NVOPDV — UX: scan/qty entry as one clean row (qty compact, code grows = the primary scan field).
     The legacy entry sits in a <div style="float:left"> that shrink-wraps to content — neutralize it to full-width so
     the flex form has a width cap (else it overflows the page). */
  body.vx-page-nvopdv div:has(> #FormpPAPDV){ float:none!important; width:100%; box-sizing:border-box; }
  body.vx-page-nvopdv #FormpPAPDV{ display:flex; align-items:center; gap:8px; width:100%; box-sizing:border-box; }
  body.vx-page-nvopdv #FormpPAPDV #cPAPDV{ flex:0 0 64px; width:64px!important; text-align:center; }
  body.vx-page-nvopdv #FormpPAPDV #pPAPDV{ flex:1 1 auto; width:auto!important; min-width:0; }
}

/* ============================================================================
   D4 — Reports & tools (2026-06-23). Gated under .vx-page-*; display-only, no PHP/save-path change.
   ============================================================================ */

/* --- informes: legacy monthly-reports dashboard. Calm the orange tbl_title_1 banner + modern type
   (applies all widths); make the 994px corner-frame fit a phone (the viewport is now device-width). --- */
body.vx-page-informes td.tbl_title_1{
  background:#eef2f7!important; color:#334155!important; font-family:var(--vx-font);
  font-size:12px!important; font-weight:800!important; text-transform:uppercase; letter-spacing:.03em;
  padding:9px 8px!important; border:0!important; }
body.vx-page-informes td.tbl_title_1 strong{ font-weight:800!important; color:#334155!important; }
/* CONTENT links only — scoped to the legacy frame so the autochrome appbar/bottom-nav <a> (brand/Salir/folios) keep their chrome color */
body.vx-page-informes .tbl_bckgrnd_brite a{ color:var(--vx-accent-d)!important; }
/* "Reporte aún no generado" / unstamped months: a calm warn, not alarm-red */
body.vx-page-informes .tbl_bckgrnd_brite .txt_redcolor{ color:var(--vx-warn)!important; }

@media (max-width:820px){
  /* neutralize the legacy fixed pixel widths so the frame + content reflow to the phone width */
  body.vx-page-informes table.tbl_bckgrnd_brite{ width:100%!important; max-width:100%!important; }
  body.vx-page-informes table[style*="width: 994"]{ width:100%!important; max-width:100%!important; }
  body.vx-page-informes td[style*="width: 974"],
  body.vx-page-informes td[style*="width: 334"],
  body.vx-page-informes td[style*="width: 320"]{ width:auto!important; max-width:100%!important; }
  body.vx-page-informes .tbl_bckgrnd_brite img[src*="logo.png"]{ max-width:100%; height:auto; }
  body.vx-page-informes table[name="Informes"] td{ font-size:11.5px!important; padding:4px 3px!important; }
  body.vx-page-informes td.tbl_title_1{ font-size:10px!important; padding:6px 3px!important; letter-spacing:0; }
}

/* --- inventarioaldia: a bare echo'd stock report. Give the table a readable card + a calm header row.
   Self-contained (no dependence on the FULL tier) so it reads well under LIGHT auto-chrome too. --- */
body.vx-page-inventarioaldia .vx-inv{ font-family:var(--vx-font); color:var(--vx-ink); text-align:center; }
body.vx-page-inventarioaldia table.vx-invtable{
  width:100%; max-width:780px; margin:10px auto 14px; border-collapse:collapse; text-align:left;
  background:var(--vx-card); border:1px solid var(--vx-line); border-radius:var(--vx-radius-sm);
  overflow:hidden; box-shadow:var(--vx-shadow); }
body.vx-page-inventarioaldia table.vx-invtable td{
  padding:8px 12px; border-bottom:1px solid var(--vx-line); font-size:13.5px; }
body.vx-page-inventarioaldia table.vx-invtable tr:first-child td{
  background:#eef2f7; color:#334155; font-weight:800; text-transform:uppercase;
  font-size:11px; letter-spacing:.03em; }

/* ============================================================================
   D9 — Import / Conversion wizards (2026-06-23). 39 admin-only (nivel 5) pages: conv*1/2, convxls2cfdi*,
   convxmls2cfdi_imm*, nvaconv1/2. All share the legacy 994px corner-frame (table.tbl_bckgrnd_brite + 974/334/320
   fixed-width cells) — same archetype as informes. autochrome already chromes them + rewrites the width=1024
   viewport to device-width, so the ONLY gap is mobile h-scroll from the fixed frame. CSS-only, display-only.
   Scoped via attribute selectors over the whole family (vx-page-conv* + vx-page-nvaconv*) — no per-file edits.
   ALL rules content-scoped under the frame table so they can never reach the autochrome appbar (D4 lesson:
   img[src*=logo.png] is shared with the appbar brand logo). ============================================ */
@media (max-width:820px){
  body.vx-chrome[class*="vx-page-conv"] table[class*="tbl_bckgrnd_brite"],
  body.vx-chrome[class*="vx-page-nvaconv"] table[class*="tbl_bckgrnd_brite"]{ width:100%!important; max-width:100%!important; }
  /* nvaconv1/2 (+ some conv steps) use the OTHER legacy frame class, table.style1 (900px inline) — cap it too. */
  body.vx-chrome[class*="vx-page-conv"] table.style1,
  body.vx-chrome[class*="vx-page-nvaconv"] table.style1{ width:100%!important; max-width:100%!important; }
  body.vx-chrome[class*="vx-page-conv"]  table[class*="tbl_bckgrnd_brite"] td[style*="width: 974"],
  body.vx-chrome[class*="vx-page-conv"]  table[class*="tbl_bckgrnd_brite"] td[style*="width: 334"],
  body.vx-chrome[class*="vx-page-conv"]  table[class*="tbl_bckgrnd_brite"] td[style*="width: 320"],
  body.vx-chrome[class*="vx-page-nvaconv"] table[class*="tbl_bckgrnd_brite"] td[style*="width: 974"],
  body.vx-chrome[class*="vx-page-nvaconv"] table[class*="tbl_bckgrnd_brite"] td[style*="width: 334"],
  body.vx-chrome[class*="vx-page-nvaconv"] table[class*="tbl_bckgrnd_brite"] td[style*="width: 320"]{ width:auto!important; max-width:100%!important; }
  body.vx-chrome[class*="vx-page-conv"]  table[class*="tbl_bckgrnd_brite"] img[src*="logo.png"],
  body.vx-chrome[class*="vx-page-nvaconv"] table[class*="tbl_bckgrnd_brite"] img[src*="logo.png"]{ max-width:100%; height:auto; }
  /* the mapping/preview content (td.style5, often a wide <pre>/table) scrolls inside its cell, not the page */
  body.vx-chrome[class*="vx-page-conv"]  td.style5,
  body.vx-chrome[class*="vx-page-nvaconv"] td.style5{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  body.vx-chrome[class*="vx-page-conv"]  td.style5 pre,
  body.vx-chrome[class*="vx-page-nvaconv"] td.style5 pre{ white-space:pre-wrap; word-break:break-word; }
}

/* ============================================================================
   D8 — addenda-walmartdatos (2026-06-23). Niche Walmart-addenda data popup (reached from the addendas flow).
   Single body per request (if GET form / else POST window.close confirmation), so autochrome chromes it; it just
   carried a legacy teal body bg (de-teal'd in PHP) + a style1 700px corner-frame + a style15 label/input form.
   CSS-only here; gated; scoped to ONLY this page (vx-page-addenda-walmart*, not addendas/nvocfdaddendas).
   Content-scoped under .style1 so the appbar brand logo is never touched. ===================================== */
@media (max-width:820px){
  body.vx-chrome[class*="vx-page-addenda-walmart"] table.style1{ width:100%!important; max-width:100%!important; }
  body.vx-chrome[class*="vx-page-addenda-walmart"] table.style1 td[style*="width: 870"],
  body.vx-chrome[class*="vx-page-addenda-walmart"] table.style1 td[style*="width: 670"]{ width:auto!important; max-width:100%!important; }
  body.vx-chrome[class*="vx-page-addenda-walmart"] table.style1 img[src*="logo.png"]{ max-width:100%; height:auto; }
}
/* calm, readable style15 form fields (applies all widths; the form is the page's whole point) */
body.vx-chrome[class*="vx-page-addenda-walmart"] table.style15 input[type="text"]{
  min-height:40px; padding:7px 10px; border:1px solid #cbd5e1; border-radius:9px;
  font-family:var(--vx-font); font-size:14px; box-sizing:border-box; max-width:100%; }
body.vx-chrome[class*="vx-page-addenda-walmart"] table.style15 input[type="text"]:focus{
  outline:none; border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.12); }

/* ============================================================================
   FIX 2026-06-23 — restore the HORIZONTAL scrollbar on the wide "consulta" grids (desktop).
   Reported by a real user (GRUPO GABIA, consultacfdemitidos): "no tiene las barras para desplazamiento a la
   derecha e izquierda ... la información que va a la derecha no se visualiza." These grids are built with
   shrinkToFit:false (fixed column widths whose sum exceeds the viewport — measured 1606px table inside a 1324px
   card). The desktop premium block above set .ui-jqgrid{overflow:hidden} (rounded-card clip) + the body div to
   height:auto / overflow:visible (so the body grows and the PAGE scrolls vertically). Together those removed
   jqGrid's native horizontal scrollbar: the wide table overflowed the body div (visible) and was then clipped by
   the card (hidden), with html/body overflow-x:hidden preventing any page-level horizontal scroll → the right
   columns (Total, Saldo, ...) were unreachable.
   Fix: cap the body div to the viewport and restore overflow:auto, so BOTH scrollbars stay IN VIEW, the header
   stays pinned above and the Totales footer below. Because the table is fixed-width (shrinkToFit:false), the
   header and body tables are the SAME width and jqGrid syncs their scrollLeft, so a vertical scrollbar does NOT
   drift the columns (the alignment hazard that motivated the height:auto rule only affects shrinkToFit:true grids
   whose body is stretched to the container). Scoped to the 4 consulta grids only — the fit-to-width catalogs keep
   their own vertical cap and nothing else changes. Pilot/rollout-gated (this file loads only under vx_redesign()).
   ============================================================================ */
@media (min-width:821px){
  body.vx-chrome.vx-page-consultacfdemitidos    .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacfdemitidos        .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultanominasemitidas     .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultacompras         .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacompras             .ui-jqgrid-bdiv,
  body.vx-chrome.vx-page-consultapagosacfds      .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultapagosacfds          .ui-jqgrid-bdiv{
    height:auto!important;
    /* the grid body starts ~439px down (app-bar + date-range bar + caption + column header); leave room for it
       plus the pager (~48px) so the body, its scrollbars AND the pager all stay within the viewport (measured). */
    max-height:max(240px, calc(100vh - 510px))!important;
    overflow:auto!important;                                /* the LEFT-RIGHT scrollbar the user is missing (+ in-view vertical) */
  }
  /* keep the Totales footer aligned with the body while scrolling sideways (jqGrid syncs sdiv.scrollLeft;
     overflow:visible cannot scroll, so make the footer clip instead) */
  body.vx-chrome.vx-page-consultacfdemitidos     .ui-jqgrid-sdiv,
  body.vx-on.vx-page-consultacfdemitidos         .ui-jqgrid-sdiv,
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-sdiv,
  body.vx-on.vx-page-consultanominasemitidas     .ui-jqgrid-sdiv,
  body.vx-chrome.vx-page-consultacompras         .ui-jqgrid-sdiv,
  body.vx-on.vx-page-consultacompras             .ui-jqgrid-sdiv,
  body.vx-chrome.vx-page-consultapagosacfds      .ui-jqgrid-sdiv,
  body.vx-on.vx-page-consultapagosacfds          .ui-jqgrid-sdiv{ overflow-x:hidden!important; }
}

/* ============================================================================
   FIX 2026-07-01 — the OUTER overflow the earlier h-scroll fix (block above) could not reach.
   ROOT CAUSE (measured live @1366: #gridContainer=1446px, 80px past the viewport, clipped by
   html{overflow-x:hidden}): the inline page JS sizes the grid wrapper to `windowWidth-40` (1326px),
   but the desktop premium block then wraps it in #gridContainer with padding:6px 26px 40px (+52px) plus
   the two 10px legacy corner cells. 1326 + ~72 > viewport → the whole shell (and the "Ver" button, and
   the right end of the body's own h-scrollbar) is shoved off-screen and clipped. The JS subtracts 40; the
   CSS chrome adds ~72 — that mismatch is the bug. Prior attempts toggled the INNER bdiv scroll (which
   already works via the block above) or targeted #divNvoCFD (which doesn't exist on this page → no-op).
   FIX: on desktop, CAP the wrapper (and the legacy shell #gridContainer) to a viewport-relative PIXEL
   width instead of the stale JS `windowWidth-40`. A vw cap is a stable reference the legacy auto-layout
   <table> cannot feedback-expand against (a plain width:100% child does — it balloons the shell to ~2076px).
   96px leaves room for the premium container padding (52) + the two 10px corner cells + the scrollbar.
   `autowidth` then measures a fitted width at grid-init, so the shell fits the viewport, the columns scale
   to fit, and the body's own overflow:auto (block above) keeps any residual columns reachable IN VIEW.
   CSS-only, scoped to the 4 wide consulta grids, pilot/rollout-gated. No JS, no fiscal path touched. */
/* RETIRED 2026-07-01 (step 07): this vw-cap ("fit with margins") block previously held the 3 sibling consulta
   pages. All 4 consulta grids are now FULL-BLEED — consultacfdemitidos in the block below + the 3 siblings in
   the "FULL-BLEED CONSOLE — SIBLINGS" block further down. The root-cause history above is kept for reference. */

/* ============================================================================
   FULL-BLEED CONSOLE — consultacfdemitidos (2026-07-01, plan: docs/plans/grid-fullbleed-console/).
   Make the grid fill the viewport below the fixed app bar: edge-to-edge + top-to-bottom ("the blue square").
   ROOT margin sources (measured live @1366): overrides.css .vx-page-frame{max-width:1480-1520;padding:12}
   + overrides.css body.vx-report-page #gridContainer{width:min(1480px,100%);margin:0 auto} (centered cap) +
   vx-design premium #gridContainer{padding:6 26 40} + the legacy corner/spacer <td width:10> cells + card
   radius. This block overrides ALL of them for THIS page only. CSS-only, desktop-only, gated, no fiscal path.
   Horizontal + top-flush + card here; vertical fill in the block right after. ============================ */
@media (min-width:821px){
  /* 1) FRAME — kill the overrides.css width cap + 12px gutter → true full width */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-page-frame,
  body.vx-on.vx-page-consultacfdemitidos     .vx-page-frame{
    max-width:none!important; width:100%!important; margin:0!important; padding:0!important;
  }
  /* 2) SHELL #gridContainer — full viewport width, no centered 1480 cap, no side/top/bottom padding/margin */
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer,
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer{
    width:100vw!important; max-width:100vw!important; min-width:0!important;   /* 100vw is a FIXED length; width:100% here feedback-balloons the shell to ~1968px via jqGrid autowidth */
    margin:0!important; padding:0!important; box-sizing:border-box!important;
    border-collapse:collapse!important; border-spacing:0!important;   /* kill the default 2px table border-spacing */
  }
  /* 3) remove the legacy corner/spacer cells entirely (empty &nbsp; cells that otherwise flank the 100vw
        wrapper and push the shell ~30px past the viewport) + hide the rounded-corner GIFs (full-bleed = no round) */
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer > tbody > tr > td[style*="width: 10px"],
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer > tbody > tr > td[style*="width: 10px"]{
    display:none!important;
  }
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer img.tbl_top_corner,
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer img.tbl_top_corner{ display:none!important; }
  /* 3b) zero the grid-row cell padding (the colspan=3 <td> holding the wrapper carries 4px each side → +8px
        past the viewport). Direct-child scope keeps the grid cells' own inner padding untouched. */
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer > tbody > tr > td,
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer > tbody > tr > td{
    padding-left:0!important; padding-right:0!important;
  }
  /* 4) WRAPPER — fill the shell edge-to-edge. 100vw (viewport-anchored, proven stable); NOT width:100% inside
        the legacy auto-<table> (that feedback-expands the shell to ~2076px). Zero the .vx-section-shell padding
        (its desktop padding:0 override is mobile-gated) so the grid truly reaches both edges. */
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer [id^="div_wrapper_"],
  body.vx-on.vx-page-consultacfdemitidos     #gridContainer [id^="div_wrapper_"]{
    width:100vw!important; max-width:100vw!important; margin:0!important; padding-left:0!important; padding-right:0!important;
    box-sizing:border-box!important; overflow-x:auto;
  }
  /* 5) CARD — full-bleed surface, not a floating card: drop radius/shadow/side border/top margin */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid{
    border-radius:0!important; box-shadow:none!important; border-left:0!important; border-right:0!important;
    border-top:0!important; margin:0!important;
  }
  /* 6) TOP-FLUSH — remove the 12px gap so the surface meets the app bar (frame padding already 0 above; also
        zero the premium block's top padding + the card's 4px top margin) */
  body.vx-chrome.vx-page-consultacfdemitidos #gridContainer{ padding-top:0!important; }
}

/* ============================================================================
   FULL-BLEED CONSOLE — VERTICAL FILL (consultacfdemitidos, 2026-07-01). The grid BODY grows to fill the
   viewport height: a FIXED height (not height:auto) so it fills the SPARSE case (few rows → tall body with the
   rows at top) AND scrolls internally in the DENSE case (many rows). The offset reserves the stack above the
   body (app bar + date-range bar + caption + column header + filter row ≈ 330px) and below it (Totales footer +
   pager + export-icons row ≈ 140px) so the whole console fits with NO page scroll. Supersedes the consulta
   h-scroll block's `height:auto; max-height:calc(100vh-510)` for THIS page (more specific + later). TUNED live
   against the realistic multi-row state (ABRN, wide date range). ============================================ */
@media (min-width:821px){
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv{
    height:calc(100vh - 545px)!important;
    max-height:calc(100vh - 545px)!important;
    min-height:120px!important;   /* graceful on short viewports: body shrinks (scrolls) instead of forcing a page scroll; ~665px+ tall fits with zero page scroll */
    overflow:auto!important;   /* vertical scroll when rows exceed the fill height + the horizontal scroll for wide columns */
  }
  /* COMMAND-BAR reconcile (grid-command-bar, 2026-07-06): when the command bar is present the export icon-wall
     is folded away (freeing ~130px below) and the date bar moved into the sticky bar — so the 545 offset now
     OVER-reserves, leaving a bottom gap on the desktop full-bleed console. Gated on body.vx-gridbar so the
     no-command-bar fallback keeps 545. Placed BEFORE the tablet block so the tablet's dvh offset (later, more
     specific media) still wins on touch tablets. Reclaims the gap -> the grid fills the viewport + more rows. */
  body.vx-gridbar.vx-page-consultacfdemitidos .ui-jqgrid-bdiv{
    height:calc(100vh - 420px)!important;
    max-height:calc(100vh - 420px)!important;
  }
}

/* ============================================================================
   FULL-BLEED CONSOLE — UX POLISH (consultacfdemitidos, 2026-07-01, lens 5). Two trust/coherence touches:
   (1) a SLIM, VISIBLE scrollbar on the body so the ~195px horizontal scroll to the money columns is
       DISCOVERABLE (the original GRUPO GABIA complaint was "can't see/reach the right columns"); and
   (2) CENTER the empty-state message in the now-tall body so a no-results search reads as intentional,
       not broken. Scoped to consultacfdemitidos, desktop, gated. Cosmetic only. ============================ */
@media (min-width:821px){
  /* discoverable scrollbars (WebKit/Blink — the pilot's Chrome) */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv::-webkit-scrollbar,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv::-webkit-scrollbar{ height:12px; width:12px; }
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv::-webkit-scrollbar-thumb,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv::-webkit-scrollbar-thumb{
    background:var(--vx-line); border-radius:8px; border:3px solid var(--vx-card); }
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv::-webkit-scrollbar-thumb:hover,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv::-webkit-scrollbar-thumb:hover{ background:var(--vx-mut); }
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv{ scrollbar-width:thin; }   /* Firefox */
  /* empty state centered in the tall fill body → looks intentional, not a broken empty canvas.
     Scoped to `[style*="display: block"]` — the state vx-grid.js sets ONLY when the grid is empty (it inline-sets
     display:none when rows exist). This centers WITHOUT force-showing the div on populated grids (that pushed the
     body down ~275px → page overflow). */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-emptystate[style*="display: block"],
  body.vx-on.vx-page-consultacfdemitidos     .vx-emptystate[style*="display: block"]{
    display:flex!important; align-items:center; justify-content:center;
    min-height:calc(100vh - 545px); box-sizing:border-box; }
}

/* ============================================================================
   FULL-BLEED CONSOLE — SIBLINGS (2026-07-01, plan step 07). Rolls the consultacfdemitidos console out to the
   3 sibling consulta grids: consultanominasemitidas, consultacompras, consultapagosacfds. The HORIZONTAL/top/
   card/UX rules are IDENTICAL to emitidos (shared via :is()); only the VERTICAL fill offset differs per page
   because their top chrome differs (nominas/compras have NO date-range bar → lower bdiv.top). Offsets measured
   live @1366 against multi-row DATA emisors: nominas bdivTop225+below250≈475, compras 243+199≈442, pagos
   311+211≈522 → rounded up slightly (small bottom gap beats page overflow). Same pitfalls as emitidos apply:
   100vw not width:100% (autowidth balloon); emptystate centering gated on [style*="display: block"].
   CSS-only, desktop-only, pilot-gated, no fiscal path. ======================================================= */
@media (min-width:821px){
  /* 1) FRAME full width */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .vx-page-frame,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .vx-page-frame{
    max-width:none!important; width:100%!important; margin:0!important; padding:0!important;
  }
  /* 2) SHELL 100vw (fixed length — NOT width:100%, which balloons the legacy <table> via jqGrid autowidth) */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer{
    width:100vw!important; max-width:100vw!important; min-width:0!important;
    margin:0!important; padding:0!important; box-sizing:border-box!important;
    border-collapse:collapse!important; border-spacing:0!important;
  }
  /* 3) remove legacy corner/spacer cells + corner GIFs */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer > tbody > tr > td[style*="width: 10px"],
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer > tbody > tr > td[style*="width: 10px"]{
    display:none!important;
  }
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer img.tbl_top_corner,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer img.tbl_top_corner{ display:none!important; }
  /* 3b) zero grid-row cell padding */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer > tbody > tr > td,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer > tbody > tr > td{
    padding-left:0!important; padding-right:0!important;
  }
  /* 4) WRAPPER 100vw */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer [id^="div_wrapper_"],
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer [id^="div_wrapper_"]{
    width:100vw!important; max-width:100vw!important; margin:0!important; padding-left:0!important; padding-right:0!important;
    box-sizing:border-box!important; overflow-x:auto;
  }
  /* 5) CARD full-bleed */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid{
    border-radius:0!important; box-shadow:none!important; border-left:0!important; border-right:0!important;
    border-top:0!important; margin:0!important;
  }
  /* 6) TOP-FLUSH */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer{ padding-top:0!important; }
  /* 7) UX — discoverable scrollbars */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-bdiv::-webkit-scrollbar,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-bdiv::-webkit-scrollbar{ height:12px; width:12px; }
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-bdiv::-webkit-scrollbar-thumb,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-bdiv::-webkit-scrollbar-thumb{ background:var(--vx-line); border-radius:8px; border:3px solid var(--vx-card); }
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-bdiv{ scrollbar-width:thin; }
  /* 8) UX — empty state centered (gated on the shown state, like emitidos) */
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .vx-emptystate[style*="display: block"],
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .vx-emptystate[style*="display: block"]{
    display:flex!important; align-items:center; justify-content:center; min-height:calc(100vh - 480px); box-sizing:border-box; }
}
/* PER-PAGE VERTICAL FILL — offsets differ (measured multi-row @1366); come AFTER the consulta h-scroll block
   (max-height:calc(100vh-510)) so they win, same specificity + later. */
@media (min-width:821px){
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultanominasemitidas     .ui-jqgrid-bdiv{
    height:calc(100vh - 430px)!important; max-height:calc(100vh - 430px)!important; min-height:120px!important; overflow:auto!important; }
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacompras     .ui-jqgrid-bdiv{
    height:calc(100vh - 385px)!important; max-height:calc(100vh - 385px)!important; min-height:120px!important; overflow:auto!important; }
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultapagosacfds     .ui-jqgrid-bdiv{
    height:calc(100vh - 476px)!important; max-height:calc(100vh - 476px)!important; min-height:120px!important; overflow:auto!important; }
}
/* EMPTY-STATE collapse — when vx-grid.js shows the empty-state card (display:block), the empty body div still
   holds its fixed fill height (calc(100vh-Npx)) → the two STACK (~680px) and page-scroll the console. Collapse
   the empty body so only the centered empty card remains. :has() is supported in the pilot Chrome; degrades to
   the pre-fix (bounded) behavior on older engines. All 4 consulta pages. */
@media (min-width:821px){
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-view:has(.vx-emptystate[style*="display: block"]) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-view:has(.vx-emptystate[style*="display: block"]) .ui-jqgrid-bdiv{
    display:none!important;
  }
}

/* ============================================================================
   FULL-BLEED CONSOLE — consultas + consultacartaporte (2026-07-16). Brings the two NEW consult grids to the
   SAME edge-to-edge, top-to-bottom "the grid IS the container" treatment as consultacfdemitidos (owner:
   "make the new grids look like it — full width, full height, no vertical scrolling"). Kept as an ISOLATED
   block (NOT folded into the 4-page :is() lists above) so it can carry the two things these pages need
   without any risk to the working 4:
     1) consultas wraps its pills/head/range in #vxc_wrap{max-width:1600;margin:0 auto}. Left alone, the
        100vw grid-wrapper rule would overflow that centred cap → horizontal page scroll (measured live:
        gridContainer 92px past a 1440 viewport). So #vxc_wrap is neutralised here; the controls keep a
        modest gutter while the grid goes truly flush.
     2) NO fixed bdiv height here (unlike the 4 siblings' calc(100vh-Npx)): the pills row WRAPS at narrow
        widths / many types, so a magic-number offset would page-scroll for real emisors. The grid BODY
        height is owned by JS (vxcFillGridHeight, in each page) which measures the live chrome and fills to
        the viewport bottom → grid-internal scroll, never a page scroll. The bottom corner row is hidden so
        the JS footer reserve is just the pager (predictable).
   CSS-only layout; desktop-only; no fiscal path. ============================================================ */
@media (min-width:821px){
  /* 1) FRAME — kill the overrides.css max-width cap + gutter → true full width */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) .vx-page-frame,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     .vx-page-frame{
    max-width:none!important; width:100%!important; margin:0!important; padding:0!important; }
  /* 2) SHELL #gridContainer — 100vw FIXED length (width:100% feedback-balloons the legacy <table> via jqGrid autowidth) */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer{
    width:100vw!important; max-width:100vw!important; min-width:0!important;
    margin:0!important; padding:0!important; box-sizing:border-box!important;
    border-collapse:collapse!important; border-spacing:0!important; }
  /* 3) remove the legacy corner/spacer cells (top AND bottom) + corner GIFs → flush + a predictable footer */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer > tbody > tr > td.tbl_top_corner,
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer > tbody > tr > td.tbl_bottom_corner,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer > tbody > tr > td.tbl_bottom_corner,
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer > tbody > tr > td[style*="width: 10px"],
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer > tbody > tr > td[style*="width: 10px"]{
    display:none!important; }
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer img.tbl_top_corner,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer img.tbl_top_corner,
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer img.tbl_bottom_corner,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer img.tbl_bottom_corner{ display:none!important; }
  /* 3b) zero the grid-row cell padding (the colspan=3 <td> otherwise carries 4px each side → past viewport) */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer > tbody > tr > td,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer > tbody > tr > td{
    padding-left:0!important; padding-right:0!important; }
  /* 3c) consultas ONLY — neutralise the centred #vxc_wrap cap so the 100vw wrapper aligns to the viewport
        (else a 100vw grid inside a 1600px-centred parent overflows to the right). */
  body.vx-chrome.vx-page-consultas #vxc_wrap,
  body.vx-on.vx-page-consultas     #vxc_wrap{ max-width:none!important; margin:0!important; padding:0!important; }
  /* 3d) keep the controls off the very edge (grid stays flush; the pills/caption/date bar get a small gutter) */
  body.vx-chrome.vx-page-consultas :is(#vxc_pills,#vxc_head,#vxc_range),
  body.vx-on.vx-page-consultas     :is(#vxc_pills,#vxc_head,#vxc_range){ padding-left:16px!important; padding-right:16px!important; }
  /* 4) WRAPPER — fill the shell edge-to-edge (100vw, viewport-anchored, proven stable) */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer [id^="div_wrapper_"],
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer [id^="div_wrapper_"]{
    width:100vw!important; max-width:100vw!important; margin:0!important; padding-left:0!important; padding-right:0!important;
    box-sizing:border-box!important; overflow-x:auto; }
  /* 5) CARD — full-bleed surface, not a floating card */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) .ui-jqgrid,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     .ui-jqgrid{
    border-radius:0!important; box-shadow:none!important; border-left:0!important; border-right:0!important;
    border-top:0!important; margin:0!important; }
  /* 6) TOP-FLUSH */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) #gridContainer,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     #gridContainer{ padding-top:0!important; }
  /* 7) UX — discoverable slim scrollbars on the fill body (same as emitidos) */
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) .ui-jqgrid-bdiv::-webkit-scrollbar,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     .ui-jqgrid-bdiv::-webkit-scrollbar{ height:12px; width:12px; }
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) .ui-jqgrid-bdiv::-webkit-scrollbar-thumb,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     .ui-jqgrid-bdiv::-webkit-scrollbar-thumb{ background:var(--vx-line); border-radius:8px; border:3px solid var(--vx-card); }
  body.vx-chrome:is(.vx-page-consultas,.vx-page-consultacartaporte) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-consultas,.vx-page-consultacartaporte)     .ui-jqgrid-bdiv{ scrollbar-width:thin; }
}

/* ============================================================================
   MODAL SAFETY (2026-07-01) — the consultacfd DOCUMENT opens as a MODAL (#CFD / .ui-dialog) ON the consulta
   pages, so body stays vx-page-consulta*. The full-bleed WRAPPER rule is anchored to `#gridContainer` (all 4
   main page grids live in that shell; the doc modal has NO #gridContainer — it's in .ui-dialog) so it never
   matches the doc's own grid wrapper (which carries an inline width:880px). NOTE: `.vx-page-frame` is NOT a
   valid anchor — nominas/pagos templates render the grid OUTSIDE .vx-page-frame. This belt-and-suspenders
   block ALSO hard-neutralizes any grid inside #CFD/.ui-dialog (cap only, never width:auto → let the inline
   880 stand) in case a rule is ever added without the #gridContainer anchor. */
@media (min-width:821px){
  /* cap ONLY (no width:auto) — the doc sets an inline width:880px on its wrapper (consultacfd.php); let that
     stand so the doc's grid autowidths to its designed 880px. Forcing width:auto here overrode the inline 880
     → resolved to the grid-driven cell (1050) → modal overflow. max-width:100% is just a safety ceiling. */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds,.vx-page-consultas,.vx-page-consultacartaporte) :is(#CFD,.ui-dialog) [id^="div_wrapper_"],
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds,.vx-page-consultas,.vx-page-consultacartaporte)     :is(#CFD,.ui-dialog) [id^="div_wrapper_"]{
    max-width:100%!important;
  }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds,.vx-page-consultas,.vx-page-consultacartaporte) :is(#CFD,.ui-dialog) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds,.vx-page-consultas,.vx-page-consultacartaporte)     :is(#CFD,.ui-dialog) .ui-jqgrid-bdiv{
    height:auto!important; max-height:none!important; display:block!important;
  }
}

/* ============================================================================
   FIX 2026-06-23 (generalized) — the SAME horizontal-scroll restore for every OTHER wide shrinkToFit:false grid
   (banking, accounting, payroll, admin lists), so non-consulta users (e.g. a banking/payroll user) don't hit the
   identical clipped-right-columns bug GRUPO GABIA reported on consultacfdemitidos. The global desktop premium block
   (.ui-jqgrid{overflow:hidden} + .ui-jqgrid-bdiv{overflow:visible}) removed jqGrid's native h-scrollbar for ANY grid
   wider than its card; these 15 grids are all full-page (own viewport, autochromed) and shrinkToFit:false — fixed
   column widths summing wider than the card. shrinkToFit:false ⇒ header and body tables are the SAME fixed width and
   jqGrid syncs scrollLeft, so a vertical scrollbar does NOT drift columns. None has the date-range bar, so the body
   starts ~360px down → a slightly smaller offset (430) fills more of the viewport than the consulta block's 510.
   EXCLUDES the fit-to-width catalogs (receptores/proveedores/productos/empleados — their own overflow-y cap) and the
   document pages consultacfd/consultacompra (special reskinned single-doc views, not plain list grids).
   ============================================================================ */
@media (min-width:821px){
  body.vx-chrome:is(.vx-page-emisores,.vx-page-usuarios,.vx-page-plantillasusuarios,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral,.vx-page-contparametros,.vx-page-clientesdirectos,.vx-page-conceptosnomina,.vx-page-pagosacfd,.vx-page-notificaciones,.vx-page-edes,.vx-page-contratos) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-emisores,.vx-page-usuarios,.vx-page-plantillasusuarios,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral,.vx-page-contparametros,.vx-page-clientesdirectos,.vx-page-conceptosnomina,.vx-page-pagosacfd,.vx-page-notificaciones,.vx-page-edes,.vx-page-contratos) .ui-jqgrid-bdiv{
    height:auto!important;
    max-height:max(240px, calc(100vh - 430px))!important;
    overflow:auto!important;     /* the LEFT-RIGHT scrollbar (+ in-view vertical), same as the consulta grids */
  }
  body.vx-chrome:is(.vx-page-emisores,.vx-page-usuarios,.vx-page-plantillasusuarios,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral,.vx-page-contparametros,.vx-page-clientesdirectos,.vx-page-conceptosnomina,.vx-page-pagosacfd,.vx-page-notificaciones,.vx-page-edes,.vx-page-contratos) .ui-jqgrid-sdiv,
  body.vx-on:is(.vx-page-emisores,.vx-page-usuarios,.vx-page-plantillasusuarios,.vx-page-bancocuentas,.vx-page-bancocuentamovs,.vx-page-contcuentas,.vx-page-contcuentamovs,.vx-page-contcuentamovsgral,.vx-page-contparametros,.vx-page-clientesdirectos,.vx-page-conceptosnomina,.vx-page-pagosacfd,.vx-page-notificaciones,.vx-page-edes,.vx-page-contratos) .ui-jqgrid-sdiv{ overflow-x:hidden!important; }
}

/* ============================================================================
   Hub CFDI quick-search bar (vx_shell.php → vx_render_cfdi_search). A GET form that deep-links
   consultacfdemitidos.php with the page's own TipoBusquedaCFD + BuscaCFD fields. Loads only under vx_redesign().
   Styled to match the F4 date-range bar (.vx-daterange): rounded inputs, accent submit, vx-design tokens.
   ============================================================================ */
.vx-cfdi-search{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; margin:0 0 16px; padding:12px 14px;
  background:var(--vx-card,#fff); border:1px solid var(--vx-line,#e2e8f0); border-radius:var(--vx-radius-lg,14px);
  box-shadow:var(--vx-shadow,0 1px 3px rgba(0,0,0,.06)); font-family:var(--vx-font); }
.vx-cfdi-search__cap{ font-weight:800; color:var(--vx-ink,#1a2233); font-size:14px; white-space:nowrap; }
.vx-cfdi-search__sel, .vx-cfdi-search__in{ min-height:40px; padding:0 12px; font-size:16px; font-family:var(--vx-font);
  border:1.5px solid #cdd8e6; border-radius:10px; background:#fff; color:#1a2233; outline:none; box-sizing:border-box; }
.vx-cfdi-search__sel{ flex:0 0 auto; }
.vx-cfdi-search__in{ flex:1 1 220px; min-width:0; }
.vx-cfdi-search__sel:focus, .vx-cfdi-search__in:focus{ border-color:var(--vx-accent,#2563eb); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
.vx-cfdi-search__go{ min-height:40px; min-width:48px; padding:0 16px; font-size:18px; line-height:1; cursor:pointer;
  color:#fff; background:var(--vx-accent,#2563eb); border:0; border-radius:10px; box-shadow:0 4px 12px rgba(37,99,235,.22); }
.vx-cfdi-search__go:hover{ filter:brightness(1.05); }
@media (max-width:820px){
  .vx-cfdi-search__cap{ flex:1 1 100%; }
  .vx-cfdi-search__sel{ flex:1 1 calc(45% - 4px); }
  .vx-cfdi-search__in{ flex:1 1 100%; }
  .vx-cfdi-search__go{ flex:1 1 100%; }
}

/* ============================================================================
   Tier B — DESKTOP hub band (menuemisor): the Buscar bar + date presets, which on
   mobile live in the launcher (display:none ≥821px). Shown ONLY on desktop; on
   mobile the launcher already serves them. The display:none DEFAULT is width-
   AGNOSTIC (top-level) so it's hidden on mobile; the desktop @media reveals it.
   ============================================================================ */
.vx-deskhub{ display:none; }
@media (min-width:821px){
  body.vx-on .vx-deskhub{ display:block; margin:0 0 18px; }
  body.vx-on .vx-deskhub .vx-cfdi-search{ margin:0 0 10px; }
  body.vx-on .vx-deskhub-presets{ display:flex; flex-wrap:wrap; align-items:center; gap:8px; }
  body.vx-on .vx-deskhub-presets .vx-dh-lbl{ font-weight:800; font-size:13px; color:#64748b; margin-right:2px; }
  body.vx-on .vx-deskhub-chip{ display:inline-flex; align-items:center; gap:6px; padding:7px 14px; border-radius:999px;
    background:var(--vx-card,#fff); border:1.5px solid #dbe3ec; color:#334155; text-decoration:none;
    font-weight:700; font-size:13px; font-family:var(--vx-font); transition:border-color .15s,color .15s,background .15s; }
  body.vx-on .vx-deskhub-chip .ico{ font-size:15px; line-height:1; }
  body.vx-on .vx-deskhub-chip:hover{ border-color:var(--vx-accent,#2563eb); color:var(--vx-accent,#2563eb); background:#f5f9ff; }
}

/* === consultacfdemitidos + consultacfd — premium cert for the LISTING + DETAIL pages === */
/* CSS-only. body.vx-page-consultacfdemitidos + body.vx-page-consultacfd scoped. */

body.vx-page-consultacfdemitidos #divNvoCFD,
body.vx-page-consultacfd #cfd_tr0_1{ box-sizing:border-box; }

@media (max-width:820px){
  body.vx-page-consultacfdemitidos #divNvoCFD{ padding:0 8px; }
  body.vx-page-consultacfdemitidos #divNvoCFD > .tbl_bckgrnd_brite,
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite{ width:100%!important; max-width:100%!important; }
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite{ width:100%!important; max-width:100%!important; }
  /* reflow base: collapse the 1152px frame to a fluid column */
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite > tbody,
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr,
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr > td,
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite > tbody,
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite > tbody > tr,
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite > tbody > tr > td{
    display:block!important; width:100%!important; box-sizing:border-box; }
  /* hide the corner image row */
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite > tbody > tr:has(> td.tbl_top_corner){ display:none!important; }
  /* fields full-width 16px on mobile (iOS zoom-kill) */
  body.vx-page-consultacfdemitidos #divNvoCFD input[type="text"],
  body.vx-page-consultacfdemitidos #divNvoCFD select,
  body.vx-page-consultacfd #cfd_tr0_1 input[type="text"],
  body.vx-page-consultacfd #cfd_tr0_1 select{
    width:100%!important; min-height:44px; font-size:16px!important; font-family:var(--vx-font);
    padding:8px 12px!important; border:1.5px solid #cdd8e6!important; border-radius:10px!important;
    background:#fff; box-sizing:border-box; margin:3px 0 7px; }
  /* sections as cards (fieldset-style) */
  body.vx-page-consultacfdemitidos fieldset,
  body.vx-page-consultacfd fieldset{ border:0!important; margin:0; padding:0; }
  body.vx-page-consultacfdemitidos legend.tbl_title,
  body.vx-page-consultacfd legend.tbl_title{
    background:transparent!important; border:0!important; padding:14px 4px 6px!important;
    font-family:var(--vx-font)!important; font-size:12.5px!important; font-weight:800!important;
    letter-spacing:.06em; text-transform:uppercase; color:#5d7290!important; }
}

@media (min-width:821px){
  /* Listing page: full-width (not a centered card — the grid needs the viewport). */
  body.vx-page-consultacfdemitidos #divNvoCFD{
    margin:8px 0 80px; padding:12px 16px 24px;
    background:#fff; border-radius:18px; box-shadow:0 6px 24px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.04);
    border:1px solid #e2e8f0;
  }
  body.vx-page-consultacfdemitidos #divNvoCFD > .tbl_bckgrnd_brite,
  body.vx-page-consultacfdemitidos #divNvoCFD > table.tbl_bckgrnd_brite{ width:100%!important; max-width:100%!important; box-shadow:none!important; border:0!important; background:transparent!important; }
  /* Detail page: centered card (it's a detail view, not a grid). */
  body.vx-page-consultacfd #cfd_tr0_1{ max-width:960px; margin:16px auto 80px; padding:24px 24px 80px;
    background:#fff; border-radius:18px; box-shadow:0 6px 24px rgba(16,24,40,.06), 0 1px 3px rgba(16,24,40,.04);
    border:1px solid #e2e8f0; }
  body.vx-page-consultacfd #cfd_tr0_1 > table.tbl_bckgrnd_brite{ width:100%!important; max-width:100%!important; box-shadow:none!important; border:0!important; background:transparent!important; }
  body.vx-page-consultacfd fieldset{ border:1px solid #e2e8f0; border-radius:12px; padding:14px 16px; margin:0 0 14px; background:#fafbfc; }
  body.vx-page-consultacfdemitidos #divNvoCFD strong,
  body.vx-page-consultacfd #cfd_tr0_1 strong{ font-family:var(--vx-font); font-size:13px; font-weight:600; color:#475569; }
}

/* ============================================================================
   EMAIL-CFD MODAL — premium + mobile-certified (2026-07-02, plan: docs/plans/emailcfd-premium/).
   enviaemail.php is a FRAGMENT loaded into the #EMAIL jQuery UI dialog by emailCFD() (js2/cfd.js). It has NO
   body class (autochrome skips fragments), so everything scopes under the container classes the JS adds:
   .vx-email-dialog (the .ui-dialog widget) + .vx-email-frame (the content). Inert without this file (non-pilot).
   Send flow (validationEngine, autocomplete, agregaDestinatario, POST) is 100% untouched — CSS only.
   ============================================================================ */

/* ---- DESKTOP (>=821px): tighten the dialog to a form-sized premium card ---- */
@media (min-width:821px){
  .ui-dialog.vx-email-dialog{ max-width:min(760px,96vw)!important; border-radius:var(--vx-radius-lg)!important; box-shadow:var(--vx-shadow)!important; }
  .vx-email-frame{ font-family:var(--vx-font); }
  .vx-email-frame table{ width:100%!important; max-width:100%!important; }   /* kill the fixed 900px outer table */
}

/* ---- MOBILE (<=820px): FULL-SCREEN SHEET + reflow the fixed table to stacked full-width fields ---- */
@media (max-width:820px){
  /* full-screen sheet (jQuery UI inline-sizes .ui-dialog to 960x625 → override) */
  .ui-dialog.vx-email-dialog{
    position:fixed!important; inset:0!important; top:0!important; left:0!important;
    width:100vw!important; max-width:100vw!important; height:100vh!important; height:100dvh!important;
    max-height:100vh!important; max-height:100dvh!important; border-radius:0!important; box-sizing:border-box; }
  .ui-dialog.vx-email-dialog .ui-dialog-content{
    width:auto!important; height:auto!important; max-height:calc(100dvh - 46px)!important;
    overflow-y:auto!important; overflow-x:hidden!important; -webkit-overflow-scrolling:touch; box-sizing:border-box; }
  /* reflow: the fixed 900px outer table + the inner label/field table collapse to full-width blocks */
  .vx-email-frame table, .vx-email-frame > div, .vx-email-frame{ width:100%!important; max-width:100%!important; box-sizing:border-box; }
  .vx-email-frame table, .vx-email-frame tbody, .vx-email-frame tr, .vx-email-frame td{
    display:block!important; width:100%!important; max-width:100%!important; box-sizing:border-box!important; }
  /* drop the empty 10px spacer gutter cells */
  .vx-email-frame td[style*="width: 10px"]{ display:none!important; }
  /* label rows: label sits ABOVE its field, left-aligned */
  .vx-email-frame td.txt_rightaligned{ text-align:left!important; padding:10px 0 3px!important; }
  .vx-email-frame td.txt_leftaligned{ padding:0 0 6px!important; }
  /* fields: full-width, 16px (kills iOS auto-zoom), touch height */
  .vx-email-frame input[type="text"]{ width:100%!important; box-sizing:border-box; min-height:46px; font-size:16px!important; padding:0 12px; }
  .vx-email-frame textarea{ width:100%!important; box-sizing:border-box; min-height:180px; font-size:16px!important; padding:10px 12px; }
  /* recipient + attachment areas wrap, never overflow */
  .vx-email-frame #crDestinatarios_div{ width:100%!important; box-sizing:border-box; }
}

/* ---- EMAIL-CFD MODAL — labeled action buttons (iter5 UX). The legacy 48px image icons (back arrow / mail
   envelope / +) carried no text → users couldn't tell Enviar from Regresar. enviaemail.php now adds text
   labels + .vx-email-send/.vx-email-back/.vx-email-add on the SAME anchors (onclicks untouched). Skin them as
   premium pills; the icon shrinks into the pill. ---- */
.vx-email-frame .vx-email-send, .vx-email-frame .vx-email-back, .vx-email-frame .vx-email-add{
  display:inline-flex!important; align-items:center; gap:8px; text-decoration:none!important; box-sizing:border-box;
  border-radius:10px; font:600 14px var(--vx-font); cursor:pointer; vertical-align:middle; }
.vx-email-frame .vx-email-send{ background:var(--vx-accent); color:#fff!important; padding:11px 22px; border:0; box-shadow:var(--vx-shadow); }
.vx-email-frame .vx-email-send:hover{ background:var(--vx-accent-d); }
.vx-email-frame .vx-email-back{ background:var(--vx-surface-2); color:var(--vx-ink)!important; padding:11px 20px; border:1px solid var(--vx-line); }
.vx-email-frame .vx-email-back:hover{ background:var(--vx-card); border-color:var(--vx-mut); }
.vx-email-frame .vx-email-add{ background:var(--vx-surface-2); color:var(--vx-ink)!important; padding:6px 12px; border:1px solid var(--vx-line); font-size:13px; }
.vx-email-frame .vx-email-add:hover{ border-color:var(--vx-accent); color:var(--vx-accent-d)!important; }
.vx-email-frame .vx-email-send img, .vx-email-frame .vx-email-back img{ width:18px!important; height:18px!important; }
.vx-email-frame .vx-email-add img{ width:13px!important; height:13px!important; }
.vx-email-frame .vx-email-btnlbl{ white-space:nowrap; }
@media (max-width:820px){
  /* full-width, thumb-sized actions on the sheet */
  .vx-email-frame .vx-email-send, .vx-email-frame .vx-email-back{ display:flex!important; width:100%!important; justify-content:center; min-height:50px; margin:6px 0!important; }
  .vx-email-frame .vx-email-add{ min-height:44px; }
}

/* ============================================================================
   vx_alert ENGINE — premium alert/confirm card (2026-07-02, plan P0:
   docs/plans/redesign-completion/02_p0-vx-alert-engine.md).
   vx_alert() / vx_alert_cfd() / vx_alert_compra() (js2/vxutil.js) add class
   .vx-alert to the .ui-dialog widget in their open callback. This block styles
   ONLY that marker: a premium card + a filled primary "Aceptar" pill + a phone-safe
   width. BEHAVIOR UNTOUCHED (buttons / messages / autoClose / the eval'd
   extra*Func callbacks all unchanged). Inert without this file (pilot-gated) so the
   ~275 non-pilot alert call sites stay byte-identical legacy. Higher specificity
   (.ui-dialog.vx-alert = 2 classes) beats the generic body.vx-chrome .ui-dialog cap.
   ============================================================================ */
body.vx-chrome .ui-dialog.vx-alert{
  max-width:96vw!important; box-sizing:border-box;   /* respect the caller's width (default 400, a few 500) — only stop it exceeding the screen */
  border-radius:var(--vx-radius-lg)!important; box-shadow:0 24px 60px -20px rgba(15,23,42,.5)!important;
  border:1px solid var(--vx-line)!important; overflow:hidden; }
body.vx-chrome .ui-dialog.vx-alert .ui-dialog-content{ max-width:100%!important; overflow-x:hidden!important;
  line-height:1.55; color:var(--vx-ink); }
body.vx-chrome .ui-dialog.vx-alert .ui-dialog-buttonpane{ border:0!important; background:transparent!important; padding:.4rem .9rem 1rem!important; }
body.vx-chrome .ui-dialog.vx-alert .ui-dialog-buttonpane .ui-button{
  background:var(--vx-accent)!important; color:#fff!important; border:0!important;
  border-radius:10px!important; padding:.55rem 1.2rem!important; font-weight:600!important; min-width:96px; cursor:pointer; }
body.vx-chrome .ui-dialog.vx-alert .ui-dialog-buttonpane .ui-button:hover{ background:var(--vx-accent-d)!important; }
body.vx-chrome .ui-dialog.vx-alert .ui-dialog-buttonpane .ui-button:focus{ outline:0; box-shadow:0 0 0 3px rgba(37,99,235,.4)!important; }
@media (max-width:820px){
  body.vx-chrome .ui-dialog.vx-alert{ max-width:94vw!important; width:94vw!important; max-height:calc(100dvh - 32px)!important; }   /* long messages scroll instead of overflowing a short phone */
  body.vx-chrome .ui-dialog.vx-alert .ui-dialog-content{ max-height:calc(100dvh - 150px)!important; overflow-y:auto!important; }
  body.vx-chrome .ui-dialog.vx-alert .ui-dialog-buttonpane .ui-button{ width:100%; }
}

/* ============================================================================
   EDIT-FORM MODAL CLUSTER — generalized (2026-07-02, plan P1b/c/d:
   docs/plans/redesign-completion/). Extends the PROVEN "CLIENTES MODAL" :has()
   recipe (see above, ~line 2260) to the rest of the catalog / ledger / payment
   edit-form dialogs. Each opens a legacy fixed-width fragment (.load().dialog())
   into one of these dedicated #CFD_* containers; a floating .ui-dialog never inherits
   body.vx-page-*, so we scope by the (case-sensitive, host-declared) container id.
   CSS / LAYOUT ONLY — never touches field names/values, the CambioItem dirty-watcher,
   the save functions, or the XML/PAC path. Pilot-gated (inert without this file).
   The trio (#CFD_PRODUCTO/PROVEEDOR/RECEPTOR) stays owned by the CLIENTES MODAL block;
   this covers the rest. EXCLUDES #CFD (doc modal = .vx-doc), #EMAIL (= .vx-email),
   and pagoacompra (generic divIDHijo container -> deferred to P1b).
   ============================================================================ */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(:is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA)){
    width:100vw!important; max-width:100vw!important; left:0!important; right:0!important;
    top:var(--vx-appbar-h)!important; height:auto!important; max-height:calc(100dvh - var(--vx-appbar-h))!important;
    border-radius:0!important; box-sizing:border-box; }
  /* the fragment opens with a fixed inline height (425/600/625) -> cap to viewport + scroll (Save stays reachable) */
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA){
    width:auto!important; max-width:100%!important; box-sizing:border-box;
    height:auto!important; max-height:calc(100dvh - var(--vx-appbar-h) - 44px)!important; overflow-y:auto!important; -webkit-overflow-scrolling:touch; }
  /* one-column reflow: the legacy fixed-width form table/cells stack full-width, 16px (no iOS zoom) */
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) table{ width:100%!important; max-width:100%!important; table-layout:auto!important; }
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) input:not([type=checkbox]):not([type=radio]):not([type=image]),
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) select,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) textarea{ width:100%!important; max-width:100%!important; box-sizing:border-box; min-height:42px; font-size:16px!important; }
  /* Selectize.js (.ToSelectize -> .selectize-control) hides the real <select> and renders its own box that
     inherits the legacy inline width (e.g. 400px) -> the styling above misses it. Reflow the visible control. */
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) .selectize-control,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) .selectize-input{ width:100%!important; max-width:100%!important; box-sizing:border-box; font-size:16px!important; }
}
@media (min-width:821px){
  /* desktop: contain the legacy 900-960px dialog to a premium card + calm chrome (never a width cap tighter than content) */
  body.vx-chrome .ui-dialog:has(:is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA)){
    max-width:min(980px,96vw)!important; border-radius:var(--vx-radius-lg)!important; overflow:hidden;
    box-shadow:0 30px 70px -28px rgba(15,23,42,.55)!important; border:1px solid var(--vx-line)!important; }
  body.vx-chrome .ui-dialog:has(:is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA)) .ui-dialog-titlebar{
    background:var(--vx-surface-2)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important; }
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) table,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) .selectize-control{ max-width:100%!important; }
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) input:not([type=checkbox]):not([type=radio]):not([type=image]):not([type=hidden]),
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) select,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) textarea{ box-sizing:border-box; min-height:36px; padding:4px 10px; max-width:100%;
    border:1px solid var(--vx-line); border-radius:10px; background:#fff; }
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) input:focus,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) select:focus,
  body.vx-chrome :is(#CFD_CONTCUENTA,#CFD_CONTCUENTAMOV,#CFD_CONTPAR,#CFD_CONTRATO,#CFD_BANCOCUENTA,#CFD_BANCOCUENTAMOV,#CFD_PAGOACFD,#CFD_CLIENTEDIRECTO,#CFD_NOTIFICACION,#CFD_ConceptoNomina,#CFD_PlantillaUsuario,#CFD_EDE,#CFD_PAGOACOMPRA) textarea:focus{ outline:0; border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
}

/* ============================================================================
   CFD_PAGOACFD + CFD_ConceptoNomina — el reflujo tr/td que el cluster de arriba nunca
   tuvo (docs/plans/responsive-dialogs/01). Regla NUEVA y SEPARADA a propósito — el
   cluster de 13 ids de arriba nunca se toca/edita (hallazgo HIGH del panel de revisión
   del plan: editar ese selector compartido habría afectado a los otros 11 diálogos sin
   verificarlos). Sin esto, un input forzado a width:100% seguía atrapado en su <td> de
   ancho fijo original — el "$" se quedaba arriba del input en vez de a su izquierda.
   ============================================================================ */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(#CFD_PAGOACFD) table > tbody > tr,
  body.vx-chrome .ui-dialog:has(#CFD_PAGOACFD) table > tbody > tr > td,
  body.vx-chrome .ui-dialog:has(#CFD_ConceptoNomina) table > tbody > tr,
  body.vx-chrome .ui-dialog:has(#CFD_ConceptoNomina) table > tbody > tr > td{
    display:block!important; width:100%!important; text-align:left!important; }
}

/* ============================================================================
   CFD_COMPRA — "Ver/Editar Compra" (docs/plans/responsive-dialogs/02). Cero cobertura
   previa (ni CSS ni JS) — el diálogo menos atendido de todo el grupo. Bloque nuevo
   completo, mismo idioma que los demás (:has() individual, nunca el cluster compartido).
   ============================================================================ */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA){ max-width:100vw!important; }
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) table,
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) input,
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) select,
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) textarea{ width:100%!important; max-width:100%!important; }
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) table > tbody > tr,
  body.vx-chrome .ui-dialog:has(#CFD_COMPRA) table > tbody > tr > td{
    display:block!important; width:100%!important; text-align:left!important; }
}

/* ============================================================================
   CFD_CONCEPTO + CFD_CFDI_PAGO (docs/plans/responsive-dialogs/03). El registro JS de
   estos dos ids vive en cada página consumidora (nvocfditraslado.php/nvocfd33.php,
   nvocfdpago33.php), NUNCA en cfd.js — ver el comentario en cfd.js mismo para el porqué
   (nvocfd40.php/Carta Porte ya tienen su propio mecanismo para CFD_CONCEPTO). Esta CSS,
   en cambio, SÍ es segura de aplicar ampliamente: nvocfd40/Carta Porte ya traen su PROPIO
   reflujo equivalente para este id, así que esta regla es redundante ahí en el peor caso,
   nunca conflictiva (dos reglas CSS con el mismo efecto no compiten como sí lo hacen dos
   handlers JS).
   ============================================================================ */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO){ max-width:100vw!important; }
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) table,
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) input,
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) select,
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) textarea{ width:100%!important; max-width:100%!important; }
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) table > tbody > tr,
  body.vx-chrome .ui-dialog:has(#CFD_CONCEPTO) table > tbody > tr > td{
    display:block!important; width:100%!important; text-align:left!important; }
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO){ max-width:100vw!important; }
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) table,
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) input,
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) select,
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) textarea{ width:100%!important; max-width:100%!important; }
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) table > tbody > tr,
  body.vx-chrome .ui-dialog:has(#CFD_CFDI_PAGO) table > tbody > tr > td{
    display:block!important; width:100%!important; text-align:left!important; }
}

/* ============================================================================
   P2 — menuemisor DESKTOP HUB body (2026-07-02, plan docs/plans/redesign-completion/07).
   The #1 daily page: the app-bar + side rail + deskhub band are already premium, but the
   BODY is a legacy jQuery-UI tab widget (#MenuEmisortabs) inside the .vx-menu-shell whose
   catalog links are plain rows separated by loose <br/><hr/><br/>. Option B (restyle in
   place): premium pill tabs + card-style link rows. CSS-ONLY, scoped to the menuemisor page
   AND #MenuEmisortabs (jQuery-UI tab classes are shared → the #id scope prevents any leak to
   dialogs/other widgets). EVERY legacy link preserved (zero nav-parity risk). Pilot-gated
   (this file only loads under vx_redesign()). Inert on mobile (#MenuEmisortabs is inside the
   desktop-only legacy table; the mobile launcher is shown instead).
   ============================================================================ */
body.vx-page-menuemisor #MenuEmisortabs.ui-tabs{ border:0!important; background:transparent!important; padding:0!important; }
/* tab bar -> CONSOLE UNDERLINE TABS (2026-07-02: replaced the ragged pill row per owner "art as software,
   less stress"). One baseline, the active tab marked by a 2px accent underline; the strip SCROLLS instead of
   wrapping (never orphans "Nómina/Datos Propios" onto a 2nd line). Calm: one accent, no floating buttons. */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav{ background:transparent!important; border:0!important;
  border-bottom:1px solid var(--vx-line)!important; border-radius:0; padding:0!important; margin:0 0 2px!important;
  display:flex; flex-wrap:nowrap; gap:22px; overflow-x:auto; overflow-y:hidden; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav::-webkit-scrollbar{ height:0; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li{ background:transparent!important; border:0!important; margin:0!important; padding:0!important; float:none!important; top:0!important; flex:0 0 auto;
  box-shadow:none!important; border-radius:0!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a{ float:none!important; display:block; padding:11px 2px!important;
  border:0!important; border-bottom:2px solid transparent!important; border-radius:0!important; background:transparent!important;
  color:var(--vx-mut)!important; font-weight:600; white-space:nowrap; transition:color .15s, border-color .15s; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a:hover{ color:var(--vx-ink)!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li.ui-tabs-active a,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li.ui-state-active a{ color:var(--vx-accent-d)!important; border-bottom-color:var(--vx-accent)!important; }
/* calm focus: drop the boxy mouse-click focus ring (jQuery-UI/browser) but KEEP a soft ring for keyboard nav */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a:focus{ outline:none!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a:focus-visible{ outline:2px solid var(--vx-accent)!important; outline-offset:3px; border-radius:6px; }
/* a small leading icon per tab — matches the emoji icon language of the side rail. Keyed by the STABLE tab
   href (not nth-child), so it's robust to the permission-gated tab set: a tab that isn't rendered simply has
   no rule, and custom PestanasInicio tabs (#tabs-CFDS<n>) gracefully get none. */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a::before{ margin-right:7px; font-size:.95em; vertical-align:-1px; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Catalogos"]::before{ content:"\1F4C1"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Bancos"]::before{ content:"\1F3E6"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Compras"]::before{ content:"\1F6D2"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-CFDS"]::before{ content:"\1F9FE"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Traslados"]::before{ content:"\1F69A"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Notas"]::before{ content:"\1F4DD"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Cotizaciones"]::before{ content:"\1F4C4"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-NOMINA"]::before{ content:"\1F4B0"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-RETENCION"]::before{ content:"\1F4D1"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-Contabilidad"]::before{ content:"\1F4CA"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-nav li a[href="#tabs-DatosPropios"]::before{ content:"\1F3E2"; }
/* panel: the CARD is the <li> (2026-07-02 v2). The richer Facturas/Compras tabs mix "Emitir" ACTION links with
   "Consultar entre las fechas" FORM blocks in the same grid — the old "the <a> is the card" + equal-height model
   made action cards tall-and-empty and crammed the forms. Now the <li> is the card; an action link fills it
   (icon · title · chevron), and a date-range form lays out with styled controls + an accent button. Grid sizes
   to content (align-items:start) so nothing stretches into empty space. Responsive (auto-fit). */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel{ border:0!important; background:transparent!important; padding:18px 2px 6px!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel ul{ list-style:none!important; margin:0!important; padding:0!important;
  display:block!important; column-width:340px; column-gap:14px; }   /* masonry: cards pack tight, no row-height gaps; 1 col on a phone */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel hr{ display:none!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li{ margin:0 0 14px!important; list-style:none; background:#fff;
  break-inside:avoid; -webkit-column-break-inside:avoid; overflow:hidden;
  border:1px solid var(--vx-line); border-radius:14px; transition:border-color .15s, box-shadow .15s, transform .1s; }
/* --- ACTION card: a li that is a plain link (no form) — the <a> fills the whole card --- */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:not(:has(input,select)) br{ display:none!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:not(:has(input,select)):hover{ border-color:var(--vx-accent); box-shadow:0 8px 20px rgba(37,99,235,.10); transform:translateY(-1px); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a{ display:flex; align-items:center; gap:13px; min-height:64px;
  padding:16px 16px; color:var(--vx-ink)!important; text-decoration:none; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a .menuemisor{ font-weight:600; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a em{ font-style:normal; color:var(--vx-accent-d); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a img{ display:none!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a::before{ content:"\1F4C4"; flex:0 0 auto; width:40px; height:40px;
  border-radius:11px; background:rgba(37,99,235,.12); display:inline-flex; align-items:center; justify-content:center; font-size:21px; }
/* PRIMARY "create/emit" cards (Emitir CFDI / Pago / Traslado / Retención / Nómina, Registrar Compra) — the main
   call-to-action on each tab. A soft accent wash + accent border + accent title so the eye lands on it first. */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvocfd"]),
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvonomina"]),
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvoretencion"]),
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvacompra"]){ background:rgba(37,99,235,.055); border-color:rgba(37,99,235,.30); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvocfd"]):hover,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvonomina"]):hover,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvoretencion"]):hover,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvacompra"]):hover{ border-color:var(--vx-accent); box-shadow:0 10px 24px rgba(37,99,235,.16); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvocfd"]) a .menuemisor,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvonomina"]) a .menuemisor,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvoretencion"]) a .menuemisor,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvacompra"]) a .menuemisor{ color:var(--vx-accent-d); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvocfd"]) a::after,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvonomina"]) a::after,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvoretencion"]) a::after,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(a[href^="nvacompra"]) a::after{ color:var(--vx-accent); opacity:.9; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a::after{ content:"\203A"; margin-left:auto; flex:0 0 auto; color:var(--vx-mut);
  font-size:20px; line-height:1; opacity:.55; transition:transform .15s, color .15s, opacity .15s; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a:hover::after{ color:var(--vx-accent); transform:translateX(3px); opacity:1; }
/* --- FORM card: a li with date/select controls — a titled block with tidy fields + an accent action button --- */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select){ padding:15px 16px; line-height:1.9; color:var(--vx-ink); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) .menuemisor{ font-weight:600; color:var(--vx-ink); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) em{ font-style:normal; color:var(--vx-accent-d); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) input[type=text]{ height:33px; border:1px solid #cfd8e3!important;
  border-radius:8px; padding:0 9px; margin:3px 5px 3px 0; background:#fff; vertical-align:middle; box-sizing:border-box; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) input[type=text]:focus{ outline:none; border-color:var(--vx-accent)!important; box-shadow:0 0 0 3px rgba(37,99,235,.14); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) select{ height:33px; border:1px solid #cfd8e3!important; border-radius:8px;
  padding:0 7px; margin:3px 5px 3px 0; background:#fff; vertical-align:middle; box-sizing:border-box; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) a{ min-height:0; display:inline-flex; align-items:center; gap:7px;
  padding:9px 15px; margin-top:4px; border-radius:9px; background:var(--vx-accent); color:#fff!important; text-decoration:none; font-weight:600; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) a:hover{ filter:brightness(1.06); }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) a::before,
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) a::after{ display:none!important; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li:has(input,select) a img{ display:inline-block!important; width:18px; height:18px; filter:brightness(0) invert(1); opacity:.95; }
/* per-destination row glyph (keyed by the href — a hidden/renamed link simply falls back to the default) */
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="receptores.php"]::before{ content:"\1F465"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="clientesdirectos.php"]::before{ content:"\1F465"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="productos.php"]::before{ content:"\1F4E6"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="proveedores.php"]::before{ content:"\1F4C7"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="clavesSAT.php"]::before{ content:"\1F511"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="empleados.php"]::before{ content:"\1F464"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="conceptosnomina.php"]::before{ content:"\1F4B5"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="notificaciones.php"]::before{ content:"\1F514"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="contratos.php"]::before{ content:"\1F4C3"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="bancocuentas.php"]::before{ content:"\1F3E6"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="bancocuentamovs.php"]::before{ content:"\1F501"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvacompra.php"]::before{ content:"\1F6D2"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="consultacompras.php"]::before{ content:"\1F50D"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvocfd"]::before{ content:"\1F9FE"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvocfditraslado"]::before{ content:"\1F69A"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="consultacfdemitidos.php"]::before{ content:"\1F50D"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="seriesyfolios.php"]::before{ content:"\1F522"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="informes.php"]::before{ content:"\1F4C8"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvoretencion"]::before{ content:"\1F4D1"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvonomina"]::before{ content:"\1F4B0"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="contcuentas.php"]::before{ content:"\1F4CA"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="contcuentamovsgral.php"]::before{ content:"\1F4CA"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="contparametros.php"]::before{ content:"\2699\FE0F"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="nvoemisor"]::before{ content:"\1F3E2"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="emisores.php"]::before{ content:"\1F3E2"; }
body.vx-page-menuemisor #MenuEmisortabs .ui-tabs-panel li a[href^="modcertificado.php"]::before{ content:"\1F4DC"; }

/* ============================================================================
   P3 — POS register dialogs (2026-07-02, plan docs/plans/redesign-completion/08).
   The nvopdv register pops the product picker (#CFD_BUSCA_PROD 800px), multi-price
   (#CFD_MULTIPLE_PRECIO_PDV 700px), cobrador (#CFD_COBRA_PDV 400px) and thermal ticket
   (#CFD_TICKET) — all overflow a phone. CSS-ONLY, scoped to the nvopdv page + these
   container ids. **cfd.js is BYTE-UNTOUCHED** — the POS money engine (CobraPDV / vx_pos_money /
   generaTicket / QZ print) is sacred, so this is a marker-free pure-:has() reskin, NOT a JS
   tagger. Pilot-gated (this file only loads under vx_redesign()). The whole file is
   media="screen" -> the thermal receipt print (printElement / QZ raw-print) is NEVER affected.
   Cobrador FIELD styling already lives in the NVOPDV block above (~2421, big RECIBE/CAMBIO);
   this adds the dialog-shell reflow only (its inputs are intentionally excluded from the 16px
   rule so the 24/28px cash entry is preserved).
   ============================================================================ */
@media (min-width:821px){
  /* desktop: contain the 700-800px dialogs to a premium card */
  body.vx-page-nvopdv .ui-dialog:has(:is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV,#CFD_COBRA_PDV,#CFD_TICKET)){
    max-width:min(860px,96vw)!important; border-radius:var(--vx-radius-lg)!important; overflow:hidden;
    box-shadow:0 30px 70px -28px rgba(15,23,42,.55)!important; border:1px solid var(--vx-line)!important; }
  body.vx-page-nvopdv .ui-dialog:has(:is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV,#CFD_COBRA_PDV,#CFD_TICKET)) .ui-dialog-titlebar{
    background:var(--vx-surface-2)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important; }
}
@media (max-width:820px){
  /* mobile: full-screen sheet */
  body.vx-page-nvopdv .ui-dialog:has(:is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV,#CFD_COBRA_PDV,#CFD_TICKET)){
    position:fixed!important; inset:0!important; width:100vw!important; height:100dvh!important; max-width:100vw!important; border-radius:0!important; }
  /* content reflow: fit + scroll (Cobrar/scan stay reachable) */
  body.vx-page-nvopdv :is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV,#CFD_COBRA_PDV){
    width:auto!important; max-width:100%!important; height:auto!important;
    max-height:calc(100dvh - var(--vx-appbar-h) - 44px)!important; overflow:auto!important; -webkit-overflow-scrolling:touch; box-sizing:border-box; }
  body.vx-page-nvopdv :is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV,#CFD_COBRA_PDV) table{ width:100%!important; max-width:100%!important; }
  /* 16px iOS-zoom-kill on the picker + multi-price inputs ONLY (cobrador keeps its 24/28px cash entry) */
  body.vx-page-nvopdv :is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV) input:not([type=hidden]),
  body.vx-page-nvopdv :is(#CFD_BUSCA_PROD,#CFD_MULTIPLE_PRECIO_PDV) select{ font-size:16px!important; box-sizing:border-box; }
  /* ticket: keep the thermal receipt width for print fidelity; center it + let the sheet scroll */
  body.vx-page-nvopdv #CFD_TICKET{ overflow:auto!important; -webkit-overflow-scrolling:touch; }
  body.vx-page-nvopdv #CFD_TICKET_INNER{ margin:0 auto; }
}

/* ============================================================================
   P4 — legacy entry twins + bulk-nómina dialog (2026-07-02, plan docs/plans/redesign-completion/09).
   CSS-ONLY, pilot-gated. Two surfaces need work; the nvocfd/nvocfd33/nvonomina32 twins are ALREADY covered by
   the generic mobile input-reflow (line ~98) — verified hScroll=0 on a phone, no rule needed.
   ============================================================================ */
/* 4.1 div_NominaMasiva — the empleados bulk-payroll island (empleados.php:601, a 940px box with a 930px inner
   scroll table) is .show()'d, moved into #CFD_MAN_INFO and dialogized (receptor.js:954). Scope by its unique id
   (never touch display — jQuery UI toggles it). Mobile: full-screen sheet + reflow the inner scroll box. */
@media (max-width:820px){
  body.vx-chrome .ui-dialog:has(#div_NominaMasiva){ position:fixed!important; inset:0!important; width:100vw!important; height:100dvh!important; max-width:100vw!important; border-radius:0!important; }
  body.vx-chrome #div_NominaMasiva{ width:auto!important; max-width:100%!important; height:auto!important; box-sizing:border-box; }
  body.vx-chrome #div_PreNomina{ width:100%!important; max-width:100%!important; height:auto!important; max-height:calc(100dvh - var(--vx-appbar-h) - 190px)!important; overflow:auto!important; -webkit-overflow-scrolling:touch; }
}
@media (min-width:821px){
  body.vx-chrome .ui-dialog:has(#div_NominaMasiva){ max-width:min(980px,96vw)!important; border-radius:var(--vx-radius-lg)!important; overflow:hidden;
    box-shadow:0 30px 70px -28px rgba(15,23,42,.55)!important; border:1px solid var(--vx-line)!important; }
  body.vx-chrome .ui-dialog:has(#div_NominaMasiva) .ui-dialog-titlebar{ background:var(--vx-surface-2)!important; border:0!important; border-bottom:1px solid var(--vx-line)!important; }
}
/* 4.3 div_EmailAutomatico — an inline toggle section on the doc-creation pages (nvocfd/nvocfd40/nvocfditraslado
   cartaporte/nvonomina32). Its label[width:15%] + input pairs sit adjacent → on a phone the label bleeds into the
   input. Stack both to full-width blocks. Unique id → one rule covers every page. Never touches field name/value. */
@media (max-width:820px){
  body.vx-chrome #div_EmailAutomatico label,
  body.vx-chrome #div_EmailAutomatico input[style*="width"]{ display:block!important; width:100%!important; box-sizing:border-box; }
  body.vx-chrome #div_EmailAutomatico label{ margin-top:8px; font-weight:600; }
}

/* ============================================================================
   CANCELLED-ROW CUE on the consulta/document grids (2026-07-02). A cancelled CFDI/pago carries the legacy
   .txt_cfdcancelado row class (consultapagosacfds' rowattr was fixed to read the pago's own Activo='NO' — it had
   checked the always-empty CFDActivo). The premium grid overrides the legacy #ee8181 red, so re-surface a CALM
   "a bit red" cue so the user sees at a glance the row is cancelled. Document/consulta grids only (catalog pages
   already calm the class to opacity:.6 above, ~line 2185). CSS-only, pilot-gated.
   ============================================================================ */
body.vx-chrome:is(.vx-page-consultapagosacfds,.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras) .ui-jqgrid-btable>tbody>tr.jqgrow.txt_cfdcancelado>td{
  background:rgba(220,38,38,.07)!important; color:#b91c1c!important; }
body.vx-chrome:is(.vx-page-consultapagosacfds,.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras) .ui-jqgrid-btable>tbody>tr.jqgrow.txt_cfdcancelado>td:first-child{
  box-shadow:inset 3px 0 0 var(--vx-crit,#dc2626); }
/* keep the cue on hover / selected */
body.vx-chrome:is(.vx-page-consultapagosacfds,.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras) .ui-jqgrid-btable>tbody>tr.jqgrow.txt_cfdcancelado:hover>td,
body.vx-chrome:is(.vx-page-consultapagosacfds,.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras) .ui-jqgrid-btable>tbody>tr.jqgrow.txt_cfdcancelado.ui-state-highlight>td{
  background:rgba(220,38,38,.12)!important; }

/* ============================================================================
   TABLET CONSOLE DENSITY (tablet-grid-density plan, 2026-07-05, iter2). The full-bleed consulta console
   (.ui-jqgrid-bdiv = calc(100vh - Npx)) was TUNED for a TALL desktop monitor @1366. On a LANDSCAPE TABLET
   (wide, but only ~700-834 tall) the SAME desktop-calibrated chrome — caption 27 + date bar 81 + column
   header 99 + filter row 55 + 76px rows — leaves ~199px of body = ~2.6 rows (Naxielly's Galaxy Tab).

   This block SHRINKS the chrome bands and RECOMPUTES the per-page bdiv offset so the SAME console shows ~8-10
   rows. GATED to touch tablets only: `(any-pointer:coarse)` is true when ANY pointer is coarse (a tablet's
   touchscreen — even with a keyboard folio attached) and false on a desktop short window (no touch), so desktop
   is provably untouched; the width bounds (min-width:821) keep phones (already card-per-row) out. Placed at EOF
   so it wins the per-page offset rules (equal specificity, later source order) ONLY when this media query
   matches; when it doesn't (desktop/phone), the original rules stand unchanged.

   SAFETY: presentation-only (no query/colModel/XML/save). VERTICAL padding only → column alignment
   (th.left == td.left) is preserved. The filter row is COMPACTED, never `display:none` — jqGrid's
   toggleToolbar sets inline display on tr.ui-search-toolbar, so !important-hiding it would strand the pin
   reveal (memory: never !important-display a JS-toggled element). Reversible: delete this block.
   `dvh` (dynamic viewport) is used for the offset so the tablet browser's collapsing URL bar can't clip the
   last row; on an engine without dvh the declaration is dropped and the desktop `100vh - Npx` rule gracefully
   stands (the pre-change bounded behavior). ============================================================ */
@media (any-pointer:coarse) and (min-width:821px) and (max-height:900px){
  /* 1) redundant caption (visible on the tablet because titlebar{display:none} is max-width:820 only) -> gone */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-titlebar,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-titlebar{ display:none!important; }

  /* 2) column header: KEEP the wrap (labels must not truncate) but cut the 13px vertical padding (~99->~58) */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid .ui-jqgrid-htable th,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid .ui-jqgrid-htable th{
    padding-top:6px!important; padding-bottom:6px!important; line-height:1.15!important; }

  /* 3) body rows: denser — 13px->6px vertical padding + 13px text (rowH ~76 -> ~44, nearly 2x rows). Horizontal
        padding untouched (it governs column-width alignment). The identity monogram shrinks with the row. */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-btable>tbody>tr.jqgrow>td,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-btable>tbody>tr.jqgrow>td{
    padding-top:6px!important; padding-bottom:6px!important; font-size:13px!important; line-height:1.25!important; }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-btable td.vx-idcell,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-btable td.vx-idcell{ padding-top:5px!important; padding-bottom:5px!important; }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .vx-ava,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .vx-ava{ width:28px!important; height:28px!important; font-size:12px!important; }

  /* 4) filter row: COMPACT (never hide — search stays discoverable + usable). Shorter inputs (~55->~34) */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid .ui-search-toolbar th,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid .ui-search-toolbar th{ padding-top:3px!important; padding-bottom:3px!important; }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid .ui-search-toolbar input,
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid .ui-search-toolbar select,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid .ui-search-toolbar input,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid .ui-search-toolbar select{ min-height:30px!important; height:30px!important; }

  /* 5) date-range bar (consultacfdemitidos): slim one-liner (~81->~46). The DESDE/HASTA caption labels drop —
        a date input is self-evident. */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange{ margin:4px 12px!important; padding:6px 10px!important; gap:8px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-input,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-input{ min-height:32px!important; font-size:15px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-go,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-go{ min-height:32px!important; padding:0 16px!important; }
  /* KEEP the Desde/Hasta captions (a user must not have to guess which field is "from"/"to") but INLINE them —
     caption beside the input keeps the bar one line (no vertical cost) AND keeps it legible. */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-field,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-field{ flex-direction:row!important; align-items:center!important; gap:6px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-cap,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-cap{ margin:0!important; font-size:11px!important; }

  /* 6) BELOW the body: the export icon row wastes ~214px via decorative 48-blank/32-separator spacer images.
        Collapse the spacers (pure spacing, NOT buttons) and pack the real export icons tighter — EVERY export
        button (XLS/DOC/PDF/XML-zip) stays clickable, just denser. Reclaims the space straight into row count. */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer img[src*="48-blank"],
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer img[src*="48-blank"]{ display:none!important; }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer img[src*="32-separator"],
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer img[src*="32-separator"]{ display:none!important; }
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) #gridContainer a > img[src*="32-"],
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     #gridContainer a > img[src*="32-"]{ width:28px!important; height:28px!important; margin:0 3px!important; }

  /* 7) the legacy "Configurador de Reportes" panel (#<page>_cr_01, body-appended by configuradordereportes.js)
        is a desktop power-feature that hangs below the console — pure noise on a tablet, and it steals rows.
        Hide it on tablet (already hidden on pilot catalog pages; desktop consulta keeps it). Reclaims ~40-60px
        straight into the row count. */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) [id$="_cr_01"],
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     [id$="_cr_01"]{ display:none!important; }
}

/* per-page bdiv fill offset RECOMPUTED for tablet (chrome shrunk ~126px). Values TUNED LIVE @744 in iter2/3
   (measured: reserve = bdiv.top + Totales + pager + export row, no page overflow). Uses dvh (see block header). */
@media (any-pointer:coarse) and (min-width:821px) and (max-height:900px){
  /* Each rule declares vh FIRST then dvh: engines without dvh keep the tablet vh value (NOT the desktop 545
     fallback → grid stays usable); dvh engines (pilot Chrome) use the URL-bar-safe dvh. min-height:120 from the
     desktop per-page rule still applies (not overridden) → very short viewports floor gracefully (page scrolls
     instead of a negative height). */
  body.vx-chrome.vx-page-consultacfdemitidos .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacfdemitidos     .ui-jqgrid-bdiv{
    height:calc(100vh - 430px)!important; height:calc(100dvh - 430px)!important;
    max-height:calc(100vh - 430px)!important; max-height:calc(100dvh - 430px)!important; }
  body.vx-chrome.vx-page-consultanominasemitidas .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultanominasemitidas     .ui-jqgrid-bdiv{
    height:calc(100vh - 340px)!important; height:calc(100dvh - 340px)!important;
    max-height:calc(100vh - 340px)!important; max-height:calc(100dvh - 340px)!important; }
  body.vx-chrome.vx-page-consultacompras .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultacompras     .ui-jqgrid-bdiv{
    height:calc(100vh - 295px)!important; height:calc(100dvh - 295px)!important;
    max-height:calc(100vh - 295px)!important; max-height:calc(100dvh - 295px)!important; }
  body.vx-chrome.vx-page-consultapagosacfds .ui-jqgrid-bdiv,
  body.vx-on.vx-page-consultapagosacfds     .ui-jqgrid-bdiv{
    height:calc(100vh - 392px)!important; height:calc(100dvh - 392px)!important;
    max-height:calc(100vh - 392px)!important; max-height:calc(100dvh - 392px)!important; }
  /* tablet min-height floor: the desktop rule's 120px is a touch tall for a short tablet, forcing ~5px page
     overflow in the sparse (1-row) case. 96px still shows a row + slack and keeps the console page-scroll-free.
     Populated grids exceed this anyway (offset governs), so no effect there. */
  body.vx-chrome:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .ui-jqgrid-bdiv,
  body.vx-on:is(.vx-page-consultacfdemitidos,.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .ui-jqgrid-bdiv{ min-height:96px!important; }
}

/* ============================================================================
   TABLET CONSOLE — HARDENING (tablet-grid-density, 2026-07-05, iter3). Edge cases the core block didn't cover:
   (a) EMPTY-STATE height must track the TABLET offset (the desktop rule centers in calc(100vh-545) → a negative
       box on a short tablet); (b) PORTRAIT tablets (mobile branch, min-width 700-820) get the 202px stacked
       date bar compacted (the "widgets too tall" complaint in portrait) WITHOUT touching phones (<700).
   ============================================================================ */
@media (any-pointer:coarse) and (min-width:821px) and (max-height:900px){
  /* empty-state centered in the TABLET-sized body (matches the recomputed offsets above). max(120px, …) FLOOR
     so a very short tablet (height <= 430px still matches this @media) can't drive the min-height NEGATIVE →
     invalid → the message box would collapse instead of centering (adversarial review, iter6). */
  body.vx-chrome.vx-page-consultacfdemitidos .vx-emptystate[style*="display: block"],
  body.vx-on.vx-page-consultacfdemitidos     .vx-emptystate[style*="display: block"]{
    min-height:max(120px, calc(100vh - 430px))!important; min-height:max(120px, calc(100dvh - 430px))!important; }
  body.vx-chrome:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds) .vx-emptystate[style*="display: block"],
  body.vx-on:is(.vx-page-consultanominasemitidas,.vx-page-consultacompras,.vx-page-consultapagosacfds)     .vx-emptystate[style*="display: block"]{
    min-height:max(120px, calc(100vh - 340px))!important; min-height:max(120px, calc(100dvh - 340px))!important; }
}
/* PORTRAIT tablets: the stacked date-range bar is ~202px (Desde / Hasta / full-width Ver). Compact it to a
   tight two-up + inline Ver (~110px) so the card grid gets the height. Bounded to 700-820px + touch so phones
   (<700) and desktop keep their current bars. */
@media (any-pointer:coarse) and (min-width:700px) and (max-width:820px){
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange{ margin:6px 12px!important; padding:8px 12px!important; gap:8px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-field,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-field{ flex:1 1 calc(50% - 44px)!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-go,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-go{ flex:0 0 auto!important; margin-left:auto!important; min-height:40px!important; }
  body.vx-chrome.vx-page-consultacfdemitidos .vx-daterange .vx-dr-input,
  body.vx-on.vx-page-consultacfdemitidos     .vx-daterange .vx-dr-input{ min-height:38px!important; }
}

/* ============================================================================
   GRID COMMAND BAR (grid-command-bar plan, 2026-07-06). ONE bar docked flush under the app-bar that hosts the
   period control (the relocated .vx-daterange) + an "Exportar ▾" menu (the folded export icon-wall) and hides
   the retired legacy zones. Built by js2/vx-gridbar.js (presentation-only: it MOVES existing nodes, never
   rewrites an export/query/save handler). Gated (loaded under vx_redesign) + page-scoped via body.vx-gridbar.
   Reversible: kill-switch in the JS, or delete this block. ============================================ */
body.vx-gridbar .vx-gb-bar{
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  position:sticky; top:var(--vx-appbar-h,56px); z-index:45;
  margin:0; padding:8px 16px; background:var(--vx-card,#fff);
  border-bottom:1px solid var(--vx-line,#e6ebf2); font-family:var(--vx-font);
}
@media (min-width:821px){ body.vx-gridbar .vx-gb-bar{ top:64px; padding:8px 26px; } }
body.vx-gridbar .vx-gb-context{ font-weight:700; font-size:14px; color:var(--vx-ink,#0f172a); white-space:nowrap; }
body.vx-gridbar .vx-gb-slot{ display:flex; align-items:center; gap:8px; position:relative; }
body.vx-gridbar .vx-gb-spacer{ flex:1; }

/* the relocated date-range: it already carries its own .vx-daterange styling; inside the bar make it inline + slim */
body.vx-gridbar .vx-gb-period .vx-daterange{ margin:0!important; padding:0!important; border:0!important; background:transparent!important; box-shadow:none!important; gap:8px!important; }
body.vx-gridbar .vx-gb-period .vx-dr-icon{ line-height:normal!important; }
body.vx-gridbar .vx-gb-period .vx-dr-input{ min-height:34px!important; }
body.vx-gridbar .vx-gb-period .vx-dr-go{ min-height:34px!important; }

/* the Exportar ▾ button + dropdown menu */
body.vx-gridbar .vx-gb-btn{ display:inline-flex; align-items:center; gap:7px; min-height:38px; padding:0 14px;
  border-radius:10px; border:1px solid var(--vx-line,#e6ebf2); background:var(--vx-card,#fff);
  font:700 13.5px/1 var(--vx-font); color:var(--vx-ink,#0f172a); cursor:pointer; }
body.vx-gridbar .vx-gb-btn:hover{ background:var(--vx-surface-2,#f7f9fc); border-color:var(--vx-mut,#8a97a8); }
body.vx-gridbar .vx-gb-caret{ font-size:11px; color:var(--vx-mut,#64748b); }
body.vx-gridbar .vx-gb-menu{ display:none; position:absolute; top:calc(100% + 6px); right:0; min-width:230px; z-index:60;
  background:var(--vx-card,#fff); border:1px solid var(--vx-line,#e6ebf2); border-radius:12px;
  box-shadow:var(--vx-shadow-lg,0 8px 16px rgba(16,24,40,.08),0 28px 60px rgba(16,24,40,.16)); padding:6px; }
body.vx-gridbar .vx-gb-export.vx-gb-open .vx-gb-menu{ display:block; }
body.vx-gridbar .vx-gb-menu-item{ display:flex!important; align-items:center; gap:11px; padding:10px 12px; border-radius:9px;
  color:var(--vx-ink,#0f172a)!important; text-decoration:none!important; font-size:14px; font-weight:600; cursor:pointer; }
body.vx-gridbar .vx-gb-menu-item:hover,
body.vx-gridbar .vx-gb-menu-item:focus{ background:var(--vx-surface-2,#f7f9fc); outline:none; }
body.vx-gridbar .vx-gb-menu-item:focus-visible{ box-shadow:inset 0 0 0 2px var(--vx-accent,#2563eb); }
/* clean colored FORMAT badge (XLS/DOC/PDF/XML) — text is the darker shade of the same family */
body.vx-gridbar .vx-gb-mi-badge{ width:34px; height:22px; flex:none; display:inline-flex; align-items:center; justify-content:center;
  border-radius:6px; font:700 10px/1 var(--vx-font); letter-spacing:.03em; }
body.vx-gridbar .vx-gb-badge-xls{ background:#e7f5ee; color:#0f6e56; }
body.vx-gridbar .vx-gb-badge-doc{ background:#e6f1fb; color:#0c447c; }
body.vx-gridbar .vx-gb-badge-pdf{ background:#fcebeb; color:#a32d2d; }
body.vx-gridbar .vx-gb-badge-xml{ background:#f1efe8; color:#444441; }
body.vx-gridbar .vx-gb-badge-gen{ background:var(--vx-surface-2,#f7f9fc); color:var(--vx-mut,#64748b); }

/* hide the retired legacy zones on command-bar pages. #gridContainer raises specificity so the mobile
   `td{display:block!important}` reflow rule can't un-hide the residual export wall (was showing on phone). */
body.vx-gb-exports-folded #gridContainer .vx-gb-residual{ display:none!important; }
body.vx-gb-exports-folded .vx-gb-residual{ display:none!important; }
body.vx-gb-cfg-retired [id$="_cr_01"]{ display:none!important; }   /* belt: if the configurador div sits outside the residual td */

/* MOBILE: the bar wraps to two tidy lines; the export menu opens flush */
@media (max-width:820px){
  body.vx-gridbar .vx-gb-bar{ padding:8px 12px; gap:8px; }
  body.vx-gridbar .vx-gb-context{ flex:1 1 100%; }
  body.vx-gridbar .vx-gb-period .vx-dr-input{ min-height:38px!important; }
  body.vx-gridbar .vx-gb-menu{ right:auto; left:0; }
}

/* ============================================================================
   HUB v2 — "FISCAL CONSOLE" visual layer (v3, owner round 3).
   Plan: docs/plans/menuemisor-hub-v2/. Flag: config_hub.php (vx_hub_v2()).
   THE GRID LAW: strict uniform matrix — display:grid + stretch + one-line clamps.
   masonry (multi-column fill) stays BANNED (guarded by tests/test_hub_v2.php).
   THE SHEET: each group is ONE bounded panel (the workbook page); the active tab is
   FUSED to it (margin-bottom:-1px over the panel border). Cards are lattice rows
   separated by hairlines — no floating islands, no shadows, no transforms.
   ONE ACCENT: --vx-accent appears only on the active tab's inset bar, the .primary
   rail/icon, hover ink, focus rings and submit buttons. Everything else is slate.
   Scoped to body.vx-page-menuemisor; mobile (<821px) keeps the launcher untouched.
   Fallback: flag off = block inert; no JS = stacked panels, everything reachable.
   ============================================================================ */
body.vx-page-menuemisor .vx-hub{ display:none; }

@media (min-width:821px){
  body.vx-page-menuemisor.vx-hubv2-on .vx-page-frame{ display:none; }

  body.vx-page-menuemisor.vx-hubv2-on .vx-hub{
    /* WIDTH LOCK (owner bug report): the shell shrink-wraps its column, so max-width alone let
       every tab pick its own width — the workbook visibly resized on each click. width: locks it. */
    display:block; width:1120px; max-width:96vw; margin:8px auto 56px; padding:0 18px;
    box-sizing:border-box;
    /* console palette — derived from the shared tokens, scoped here */
    --vxh-line:var(--vx-line,#e8edf3);   /* interior hairlines */
    --vxh-edge:#d9e1ea;                  /* sheet perimeter (1 step stronger) */
    --vxh-paper:#ffffff;                 /* the sheet */
    --vxh-well:#f8fafc;                  /* footer console / hover wash */
    --vxh-canvas:#f4f7fb;                /* the sheet's writing area (tiles sit on it) */
    --vxh-icon:#64748b;                  /* quiet slate iconography */
    --vxh-ghost:#b3c0d0;                 /* chevrons, tertiary marks */
  }

  /* the deskhub date-preset chip rows (Facturas/Cotizaciones/Notas: Hoy…) are REDUNDANT under
     the hub — the workbook's Consultar page owns those consults (owner request 2026-07-07).
     Hidden only when the hub is on; the flag-off/legacy page keeps them. Buscar bar stays. */
  body.vx-page-menuemisor.vx-hubv2-on .vx-deskhub-presets{ display:none; }

  /* ---- TAB RAIL: real workbook tabs, fused to the sheet ------------------- */
  body.vx-page-menuemisor .vx-hub-pills{ display:flex; flex-wrap:wrap; align-items:flex-end;
    gap:2px; margin:0; padding:0; position:relative; z-index:2; }
  body.vx-page-menuemisor .vx-hub-pills a{ display:inline-block; padding:9px 16px 10px;
    font-size:13px; font-weight:600; line-height:1.25; letter-spacing:.01em;
    color:var(--vx-mut); text-decoration:none; border:1px solid transparent; border-bottom:0;
    border-radius:8px 8px 0 0; transition:color .12s, background-color .12s; }
  body.vx-page-menuemisor .vx-hub-pills a:visited{ color:var(--vx-mut); }
  body.vx-page-menuemisor .vx-hub-pills a:hover{ color:var(--vx-ink); background:rgba(15,23,42,.045); }
  body.vx-page-menuemisor .vx-hub-pills a:focus-visible{ outline:2px solid var(--vx-accent); outline-offset:-2px; }
  /* the lit tab: white, bordered, dropped -1px over the sheet edge, 2px accent crown */
  body.vx-page-menuemisor .vx-hub-pills a.on,
  body.vx-page-menuemisor .vx-hub-pills a.on:hover,
  body.vx-page-menuemisor .vx-hub-pills a.on:visited{
    background:var(--vxh-paper); border-color:var(--vxh-edge); color:var(--vx-ink);
    margin-bottom:-1px; padding-bottom:11px; box-shadow:inset 0 2px 0 var(--vx-accent); }
  /* no-JS (never .tabbed): the rail is a plain anchor strip over stacked sheets */
  body.vx-page-menuemisor .vx-hub:not(.tabbed) .vx-hub-pills{
    border-bottom:1px solid var(--vxh-edge); margin-bottom:16px; }

  /* ---- THE SHEET: one bounded panel per group ----------------------------- */
  body.vx-page-menuemisor .vx-hub-group{ background:var(--vxh-paper);
    border:1px solid var(--vxh-edge); border-radius:10px; overflow:hidden;
    margin:0 0 20px; scroll-margin-top:86px; position:relative; }
  /* tabbed: square the corner the tab docks into (the folder silhouette) */
  body.vx-page-menuemisor .vx-hub.tabbed .vx-hub-group{ border-radius:0 10px 10px 10px; margin:0; }

  /* group header: a console strip in stacked/no-JS mode… */
  body.vx-page-menuemisor .vx-hub-group h2{ margin:0; padding:9px 16px; font-size:11px;
    font-weight:700; letter-spacing:.08em; text-transform:uppercase; color:var(--vx-mut);
    background:var(--vxh-well); border-bottom:1px solid var(--vxh-line); }
  /* …but in the workbook the lit tab already names the page: visually gone, kept for AT */
  body.vx-page-menuemisor .vx-hub.tabbed .vx-hub-group h2{ position:absolute; width:1px; height:1px;
    margin:-1px; padding:0; border:0; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%);
    white-space:nowrap; background:none; }

  /* ---- THE GRID LAW: 3 uniform columns of crafted tiles on the sheet canvas ---
     (owner round 4: "too flat" -> tiles regain depth; "width jumps" -> width locked above) */
  body.vx-page-menuemisor .vx-hub-grid{ display:grid;
    grid-template-columns:repeat(3,minmax(0,1fr)); gap:10px; align-items:stretch;
    padding:14px; background:var(--vxh-canvas); }

  body.vx-page-menuemisor .vx-hub-card{ display:flex; align-items:center; gap:12px;
    min-height:66px; padding:12px 14px;
    background:linear-gradient(180deg,#ffffff 0%,#fbfcfe 100%);
    border:1px solid #e3e9f1; border-radius:12px;
    box-shadow:0 1px 2px rgba(16,24,40,.05);
    text-decoration:none; color:var(--vx-ink); overflow:hidden;
    position:relative; transition:box-shadow .14s, border-color .14s, background-color .14s; }
  /* hover = deeper shadow + accent edge; still NO translate — nothing floats */
  body.vx-page-menuemisor .vx-hub-card:hover{ border-color:rgba(37,99,235,.45);
    box-shadow:0 3px 10px rgba(37,99,235,.12), 0 1px 2px rgba(16,24,40,.05);
    background:#ffffff; }
  /* theme-bleed armor (legacy themes paint a:hover/:visited orange — seen live) */
  body.vx-page-menuemisor .vx-hub-card,
  body.vx-page-menuemisor .vx-hub-card:hover,
  body.vx-page-menuemisor .vx-hub-card:visited,
  body.vx-page-menuemisor .vx-hub-card:active{ color:var(--vx-ink); }
  body.vx-page-menuemisor .vx-hub-card:focus-visible{ outline:2px solid var(--vx-accent); outline-offset:-2px; }

  /* icon chip: tinted accent tile — one hue, real presence (the anti-flat move) */
  body.vx-page-menuemisor .vx-hub-card .ic{ flex:0 0 auto; width:40px; height:40px;
    border-radius:10px; border:1px solid rgba(37,99,235,.16);
    background:linear-gradient(180deg,rgba(37,99,235,.10),rgba(37,99,235,.05));
    color:var(--vx-accent-d); display:inline-flex; align-items:center; justify-content:center;
    font-size:18px; /* fallback if a raw glyph ever lands here */ }
  body.vx-page-menuemisor .vx-hub-card .ic svg{ width:20px; height:20px; display:block; }
  body.vx-page-menuemisor .vx-hub-card:hover .ic{ border-color:rgba(37,99,235,.35);
    background:linear-gradient(180deg,rgba(37,99,235,.16),rgba(37,99,235,.08)); }

  /* LEFT-aligned two-line type block, both lines clamped to one line */
  body.vx-page-menuemisor .vx-hub-card .tx{ min-width:0; flex:1 1 auto; text-align:left; }
  body.vx-page-menuemisor .vx-hub-card .tx b{ display:block; font-size:14px; font-weight:650;
    letter-spacing:-.005em; color:var(--vx-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  body.vx-page-menuemisor .vx-hub-card .tx small{ display:block; margin-top:1px; font-size:12px;
    color:var(--vx-mut); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  body.vx-page-menuemisor .vx-hub-card:hover .tx b{ color:var(--vx-accent-d); }

  /* chevron: ghost until the row is live */
  body.vx-page-menuemisor .vx-hub-card .ch{ flex:0 0 auto; display:inline-flex;
    color:var(--vxh-ghost); font-size:17px; line-height:1; opacity:.55;
    transition:opacity .12s, color .12s; }
  body.vx-page-menuemisor .vx-hub-card .ch svg{ width:16px; height:16px; display:block; }
  body.vx-page-menuemisor .vx-hub-card:hover .ch{ opacity:1; color:var(--vx-accent); }

  /* badge: functional alert, tabular digits */
  body.vx-page-menuemisor .vx-hub-card .bd{ flex:0 0 auto; background:#dc2626; color:#fff;
    border-radius:999px; padding:1px 7px; font-size:11px; font-weight:700;
    font-variant-numeric:tabular-nums; }

  /* THE action of each page: accent-washed tile + rail — unmissable, still calm */
  body.vx-page-menuemisor .vx-hub-card.primary{
    background:linear-gradient(180deg,rgba(37,99,235,.07),rgba(37,99,235,.03));
    border-color:rgba(37,99,235,.38); box-shadow:inset 3px 0 0 var(--vx-accent), 0 1px 2px rgba(16,24,40,.05); }
  body.vx-page-menuemisor .vx-hub-card.primary:hover{
    box-shadow:inset 3px 0 0 var(--vx-accent), 0 3px 10px rgba(37,99,235,.14); }
  body.vx-page-menuemisor .vx-hub-card.primary .ic{ color:#fff; border-color:var(--vx-accent);
    background:linear-gradient(180deg,var(--vx-accent),var(--vx-accent-d)); }
  body.vx-page-menuemisor .vx-hub-card.primary .tx b{ color:var(--vx-accent-d); }

  /* ---- CONSULT BAND: the sheet's footer console (solid, aligned, attached) - */
  body.vx-page-menuemisor .vx-hub-consultas{ margin:0; display:block;
    background:var(--vxh-well); border-top:1px solid var(--vxh-edge); }
  body.vx-page-menuemisor .vx-hub-form{ display:flex; align-items:center; flex-wrap:wrap;
    gap:8px 10px; padding:9px 16px; margin:0; background:transparent; border:0;
    border-bottom:1px solid var(--vxh-line); border-radius:0; font-size:12.5px; color:var(--vx-ink); }
  body.vx-page-menuemisor .vx-hub-form:last-child{ border-bottom:0; }
  /* fixed label column — every row's controls start on the same vertical */
  body.vx-page-menuemisor .vx-hub-form .fl{ flex:0 0 110px; font-size:10.5px; font-weight:700;
    letter-spacing:.08em; text-transform:uppercase; color:var(--vx-mut); }
  body.vx-page-menuemisor .vx-hub-form label{ display:inline-flex; align-items:center; gap:5px;
    color:var(--vx-ink); font-size:12.5px; }
  body.vx-page-menuemisor .vx-hub-form input[type=text],
  body.vx-page-menuemisor .vx-hub-form select{ height:32px; padding:0 9px;
    border:1px solid #cfd8e3; border-radius:6px; font-size:12.5px; background:#fff;
    color:var(--vx-ink); font-variant-numeric:tabular-nums; }
  body.vx-page-menuemisor .vx-hub-form input[type=text]:focus,
  body.vx-page-menuemisor .vx-hub-form select:focus{ outline:none;
    border-color:var(--vx-accent); box-shadow:0 0 0 3px rgba(37,99,235,.13); }
  body.vx-page-menuemisor .vx-hub-form input[type=radio]{ accent-color:var(--vx-accent); }
  body.vx-page-menuemisor .vx-hub-form select.wide{ max-width:280px; }
  body.vx-page-menuemisor .vx-hub-form button{ margin-left:auto; height:32px; border:0;
    border-radius:6px; padding:0 16px; background:var(--vx-accent); color:#fff;
    font-weight:600; font-size:12.5px; cursor:pointer; transition:background-color .12s; }
  body.vx-page-menuemisor .vx-hub-form button:hover{ background:var(--vx-accent-d); }
  body.vx-page-menuemisor .vx-hub-form button:focus-visible{ outline:2px solid var(--vx-accent-d); outline-offset:2px; }
}

/* narrow desktop: the lattice steps to 2 columns, rows stay 62px */
@media (min-width:821px) and (max-width:1105px){
  body.vx-page-menuemisor .vx-hub-grid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
}

/* HUB v2 WORKBOOK mode mechanics (PRESERVED VERBATIM — the tab driver contract).
   .tabbed + .on come from the inline script; no JS = stacked sheets, nothing lost. */
@media (min-width:821px){
  body.vx-page-menuemisor.vx-hubv2-on .vx-hub.tabbed .vx-hub-group{ display:none; }
  body.vx-page-menuemisor.vx-hubv2-on .vx-hub.tabbed .vx-hub-group.on{ display:block; }
}
/* HUB v2 WORKBOOK fixed-page graft (panel synthesis, judges x2): every tab flips to a sheet of
   the SAME physical size — one object, many pages. display:flex OVERRIDES the display:block
   mechanic above on purpose (the literal stays for the guard + the no-JS path); the consult
   footer pins to the sheet's foot, blank paper fills the rest like a real workbook page. */
@media (min-width:821px){
  body.vx-page-menuemisor.vx-hubv2-on .vx-hub.tabbed .vx-hub-group.on{
    display:flex; flex-direction:column; min-height:432px; }
  body.vx-page-menuemisor.vx-hubv2-on .vx-hub.tabbed .vx-hub-group.on .vx-hub-consultas{ margin-top:auto; }
}

/* ============================================================================
   MOBILE — Series y Folios (owner 2026-07-17: "not mobile compatible at all"). Two legacy pages the generic
   reskin left cramped on a phone. CSS-only, mobile-gated, presentation-only (no field/name/JS/POST change).
   (A) nvoseriesyfolios.php + modseriesyfolios.php — the style15 FORM. The shared STYLE15 block (above) stacks
       the rows, but an INTERMEDIATE `<table width:100%>` wrapper (not style15 itself) collapsed to ~60px on a
       phone, dragging every field down to 60px. Force the whole nested-table chain full-width + fields fill.
   (B) seriesyfolios.php — the style8 folios TABLE (8 fixed-% columns) was squished to 390px with headers
       wrapping one letter per line. Convert to a card-per-row list with a label on each field. ========= */
@media (max-width:820px){
  /* (A) FORM — the form lived inside a `td.txt_leftaligned` (~100px) of an INTERMEDIATE table, which pinned
     style15 + every field to ~60px. Block-ify ALL nested tables/rows/cells inside the card so the whole thing
     stacks full-width (the outer tbl_bckgrnd_brite frame is handled by the STYLE15 block above; this hits the
     tables NESTED inside it). Then the fields fill. */
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.tbl_bckgrnd_brite table,
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.tbl_bckgrnd_brite table > tbody,
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.tbl_bckgrnd_brite table > tbody > tr,
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.tbl_bckgrnd_brite table > tbody > tr > td{
    display:block!important; width:100%!important; max-width:100%!important; box-sizing:border-box; }
  body.vx-chrome:is(.vx-page-nvoseriesyfolios,.vx-page-modseriesyfolios,.vx-page-nvoemisor,.vx-page-modemisor) table.style15 :is(input[type="text"],select){
    width:100%!important; max-width:100%!important; min-width:0!important; box-sizing:border-box;
    min-height:44px; font-size:16px!important; padding:9px 12px!important; border:1.5px solid #cbd5e1!important; border-radius:10px!important; background:#fff; }

  /* (B) TABLE — style8 folios list -> card per row */
  body.vx-chrome.vx-page-seriesyfolios table.style8{ display:block!important; width:100%!important; border:0!important; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody{ display:block!important; }
  /* hide the header row (1) + the &nbsp; spacer row (2) — the label moves onto each card via ::before */
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr:nth-child(1),
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr:nth-child(2){ display:none!important; }
  /* each remaining data row -> a card */
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr{
    display:block!important; margin:0 0 12px; padding:10px 14px; background:var(--vx-card,#fff);
    border:1px solid var(--vx-line,#e2e8f0); border-radius:14px; box-shadow:var(--vx-shadow,0 1px 3px rgba(0,0,0,.06)); }
  /* each cell -> a "Label ..... Value" row */
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td{
    display:flex!important; justify-content:space-between; align-items:baseline; gap:12px; width:auto!important;
    padding:6px 0!important; border:0!important; border-bottom:1px solid #f1f5f9!important; text-align:right!important; font-size:14px; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:last-child{ border-bottom:0!important; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td::before{
    content:""; text-align:left; color:var(--vx-mut,#64748b); font-weight:600; font-size:12.5px; white-space:nowrap; }
  /* data rows carry 8 tds in a fixed order: [action] Serie · FolioMin · FolioMax · FolioActual · Tipo · Nombre · Expirados */
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(1){ justify-content:flex-end; border-bottom:0!important; padding-bottom:2px!important; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(2)::before{ content:"Serie"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(3)::before{ content:"Folio mínimo"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(4)::before{ content:"Folio máximo"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(5)::before{ content:"Folio actual"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(6)::before{ content:"Tipo"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(7)::before{ content:"Nombre"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(8)::before{ content:"Expirados"; }
  body.vx-chrome.vx-page-seriesyfolios table.style8 > tbody > tr > td:nth-child(2) strong{ font-size:16px; }
}

/* ============================================================================
   MOBILE — convxls2cfdi1 (Batch 2, 2026-07-18). The page's upload UI already reflows; the only breakage is
   the 12-column "expected Excel columns" REFERENCE table (RFC · MÉTODO DE PAGO · … · TOTAL) which squished
   into 390px with each header wrapping one letter per line. It's a read-only reference (the exact column
   order the .xlsx must have), so let it SCROLL HORIZONTALLY with readable columns instead of collapsing.
   CSS-only, mobile-gated. ================================================================================ */
@media (max-width:820px){
  body.vx-chrome.vx-page-convxls2cfdi1 table.tbl_bdr{
    display:block!important; overflow-x:auto; -webkit-overflow-scrolling:touch; width:100%!important; }
  body.vx-chrome.vx-page-convxls2cfdi1 table.tbl_bdr > tbody{ display:table; width:auto; min-width:660px; }
  body.vx-chrome.vx-page-convxls2cfdi1 table.tbl_bdr th,
  body.vx-chrome.vx-page-convxls2cfdi1 table.tbl_bdr td{ white-space:nowrap; padding:6px 10px!important; font-size:12px; }
}

/* ============================================================================
   MOBILE — contbc (Balanza de Comprobación, 2026-07-18). The each()/date crash is fixed in PHP; the balance
   table (table.bc: Cuenta · Descripción · Saldo Inicial · Débitos · Créditos · Saldo Final) fits at 390px but
   the money columns broke mid-number ("24,406.0 0"). Keep the numeric columns (3+) on one line and let the
   table scroll horizontally so figures stay readable; the Descripción column still wraps. CSS-only, mobile. */
@media (max-width:820px){
  body.vx-chrome.vx-page-contbc table.bc{ display:block!important; overflow-x:auto; -webkit-overflow-scrolling:touch; }
  /* min-width > viewport => the table SCROLLS (readable columns) instead of squishing everything into 390px */
  body.vx-chrome.vx-page-contbc table.bc > tbody{ display:table; min-width:600px; }
  body.vx-chrome.vx-page-contbc table.bc th,
  body.vx-chrome.vx-page-contbc table.bc td{ font-size:12px; padding:5px 8px!important; white-space:nowrap; }
  /* Descripción (col 2) is the only long text — let it wrap within a bounded width so the rest stays compact */
  body.vx-chrome.vx-page-contbc table.bc th:nth-child(2),
  body.vx-chrome.vx-page-contbc table.bc td:nth-child(2){ white-space:normal; min-width:150px; max-width:170px; }
  body.vx-chrome.vx-page-contbc table.bc th:nth-child(n+3),
  body.vx-chrome.vx-page-contbc table.bc td:nth-child(n+3){ text-align:right; }
}

/* ============================================================================
   MOBILE — CFDI-form conceptos card, siblings (Batch 3, 2026-07-18). nvocfd40 wraps its line-items in a
   contained white CARD with its own scroll (css ~L648). The sibling creation forms (nvocfditraslado &c.)
   share the same #scrollconceptos/#Conceptos ids + already scroll, but lacked the card chrome — so their
   conceptos section read as a bare scroll strip. Give them the same card polish for consistency. Additive
   (nvocfd40 untouched); the #Conceptos min-width keeps the columns readable and scrolling INSIDE the card
   (never pushing the page) once populated. CSS-only, mobile-gated. =========================================== */
@media (max-width:820px){
  body:is(.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvocfdpago33,.vx-page-nvonomina,.vx-page-nvacompra,.vx-page-nvoretencion) #scrollconceptos{
    background:#fff!important; border:1px solid #d8e0ea!important; border-radius:14px;
    padding:8px!important; margin:6px 0 12px; max-height:60vh!important; overflow:auto!important; height:auto!important; min-height:70px; }
  body:is(.vx-page-nvocfditraslado,.vx-page-nvocfditrasladocartaporte,.vx-page-nvocfdpago33,.vx-page-nvonomina,.vx-page-nvacompra,.vx-page-nvoretencion) #Conceptos{ min-width:640px; }
}
