/* =============================================================================
   OrganicSystem — ERP Grid Responsive
   Shared by every GridView / DataGrid / table view. Layout only.

   - Grid always fits the content area (width + height adapt)
   - Only the grid scrolls horizontally (page never does)
   - Headers / totals stay column-aligned (DevExtreme sync preserved)
   - Selection / checkboxes keep working (no clip of fixed columns)
   ============================================================================= */

:root {
  --os-grid-host-min-height: 240px;
}

/* ---------- Page never scrolls horizontally ---------- */
html:has(body.os-app-shell),
html:has(body.os-module-shell),
html:has(body.os-report-layout),
body.os-app-shell,
body.os-module-shell,
body.os-report-layout,
body.os-app-shell .app-main,
body.os-module-shell .app-main,
body.os-app-shell .os-app-main,
body.os-module-shell .os-app-main,
body.os-app-shell .app-content,
body.os-module-shell .app-content,
body.os-app-shell .os-page-scroll,
body.os-module-shell .os-page-scroll,
body.os-app-shell > .container-fluid,
body.os-app-shell > .container-fluid > .os-app-main {
  max-width: 100% !important;
  overflow-x: clip !important;
}

/* Portrait/narrow: override legacy page-wide overflow-x: auto/scroll */
@media (orientation: portrait), (max-aspect-ratio: 1/1), (max-width: 991.98px) {
  html:has(body.os-app-shell:not(.login-shell)),
  html:has(body.os-module-shell),
  body.os-app-shell:not(.login-shell),
  body.os-module-shell,
  body.os-app-shell:not(.login-shell) > .container-fluid,
  body.os-app-shell:not(.login-shell) > .container-fluid > .os-app-main,
  body.os-app-shell:not(.login-shell) .os-page-scroll,
  body.os-app-shell:not(.login-shell) .os-page-scroll:has(.os-page-grid-view),
  body.os-app-shell:not(.login-shell) .os-page-scroll:has(.os-page-table-view),
  body.os-module-shell .module-main-page {
    overflow-x: clip !important;
  }
}

/* ---------- Grid hosts: contain width; height fills content area ---------- */
.os-page-grid-view,
.os-dx-grid,
.os-page-table-view,
.os-grid-fit-width,
main .dx-datagrid,
.app-content .dx-datagrid,
[data-os-page-grid="true"],
.plan-grid-panel > [id$="-grid"],
.ags-plan-page .dx-datagrid,
.rotation-page .dx-datagrid {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  box-sizing: border-box !important;
}

.os-page-grid-view,
.os-dx-grid {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: var(--os-grid-host-min-height);
  overflow: hidden !important; /* host clips; inner grid scrolls */
  position: relative;
}

/*
  Content-sized grid host: height is owned by page JS / DX (auto or px),
  NOT the viewport-fill flex contract. Do not force height:100% here —
  that creates an empty scroll viewport when the grid has zero rows.
*/
.os-dx-grid.os-dx-grid--content,
.os-dx-grid[data-os-grid-size="content"],
.os-page-grid-view.os-dx-grid--content,
.os-page-grid-view[data-os-grid-size="content"] {
  flex: 0 0 auto !important;
  flex-grow: 0 !important;
  align-self: stretch !important;
  min-height: 0 !important;
  max-height: none;
}

.os-page-grid-view > .dx-datagrid,
.os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) > .dx-datagrid,
.os-page-grid-view.dx-datagrid:not(.os-dx-grid--content):not([data-os-grid-size="content"]),
.os-dx-grid.dx-datagrid:not(.os-dx-grid--content):not([data-os-grid-size="content"]),
[data-os-page-grid="true"].dx-datagrid {
  flex: 1 1 auto;
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  min-height: 0 !important;
  height: 100% !important; /* fill-page hosts only; content-sized excluded above */
  max-height: 100% !important;
  overflow: hidden !important;
}

/* Content-sized AUTO: let DX size the widget box to content. */
.os-dx-grid.os-dx-grid--content[data-os-grid-height="auto"].dx-datagrid,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="auto"].dx-datagrid,
.os-dx-grid.os-dx-grid--content[data-os-grid-height="auto"] > .dx-datagrid,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="auto"] > .dx-datagrid {
  flex: 0 0 auto !important;
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
}

/* Content-sized FIXED: host height is owned by JS (px); keep flex from filling page. */
.os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"].dx-datagrid,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="fixed"].dx-datagrid,
.os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"] > .dx-datagrid,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="fixed"] > .dx-datagrid {
  flex: 0 0 auto !important;
  min-height: 0 !important;
}

/*
  Content-sized AUTO height: rowsview must NOT fill a leftover viewport.
  (Fill-page / scroll-engine rules below force height:100% + flex:1 — that is
  the empty white area on new Invoice Products with 0 rows.)
*/
.os-dx-grid.os-dx-grid--content[data-os-grid-height="auto"] .dx-datagrid-rowsview,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="auto"] .dx-datagrid-rowsview,
.os-dx-grid.os-dx-grid--content[data-os-grid-height="auto"] .dx-datagrid-rowsview .dx-scrollable-container,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="auto"] .dx-datagrid-rowsview .dx-scrollable-container {
  flex: 0 0 auto !important;
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
}

.os-dx-grid.os-dx-grid--content[data-os-grid-height="auto"] .dx-freespace-row,
.os-dx-grid[data-os-grid-size="content"][data-os-grid-height="auto"] .dx-freespace-row {
  height: 0 !important;
  min-height: 0 !important;
  max-height: 0 !important;
}

/* Page scroll hosts must NOT nest vertical scroll (content area owns it) */
.os-page-scroll:has(.os-page-grid-view),
.os-page-scroll:has(.os-dx-grid),
.os-page-scroll:has(.os-page-table-view),
.os-page-scroll:has(.dx-datagrid) {
  display: block !important;
  min-width: 0 !important;
  max-width: 100% !important;
  overflow-x: clip !important;
  overflow-y: visible !important;
  height: auto !important;
  max-height: none !important;
}

.os-page-scroll:has(.os-page-grid-view) > .os-page-grid-view,
.os-page-scroll:has(.os-dx-grid) > .os-dx-grid,
.os-page-scroll:has(.os-page-table-view) > .os-page-table-view {
  min-height: var(--os-grid-host-min-height);
  min-width: 0;
  max-width: 100%;
  height: auto !important;
}

/* ---------- Only the grid scrolls horizontally ---------- */
.os-page-grid-view .dx-datagrid,
.os-dx-grid .dx-datagrid,
main .dx-datagrid,
.app-content .dx-datagrid {
  overflow: hidden !important;
}

/* DevExtreme owns horizontal scroll on its scrollable surface */
.os-page-grid-view .dx-datagrid-rowsview,
.os-dx-grid .dx-datagrid-rowsview,
main .dx-datagrid-rowsview,
.app-content .dx-datagrid-rowsview,
.os-page-grid-view .dx-datagrid-headers .dx-datagrid-content,
.os-dx-grid .dx-datagrid-headers .dx-datagrid-content,
main .dx-datagrid-headers .dx-datagrid-content,
.os-page-grid-view .dx-datagrid-total-footer .dx-datagrid-content,
.os-dx-grid .dx-datagrid-total-footer .dx-datagrid-content,
main .dx-datagrid-total-footer .dx-datagrid-content {
  max-width: 100%;
}

/* Document-flow list grids (page owns Y): only when NOT in internal grid-scroll mode. */
html:not([data-os-grid-scroll="internal"]) .os-page-grid-view:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-scrollable-container,
html:not([data-os-grid-scroll="internal"]) .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-scrollable-container,
html:not([data-os-grid-scroll="internal"]) main .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-scrollable-container,
html:not([data-os-grid-scroll="internal"]) .app-content .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-scrollable-container {
  overflow-x: auto !important;
  overflow-y: visible !important;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
}

/* Document-flow list grids: rows grow with content.
   Do NOT apply when grids own Y (data-os-grid-scroll=internal) or fill markers. */
html:not([data-os-grid-scroll="internal"]) .os-page-grid-view:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-datagrid-rowsview,
html:not([data-os-grid-scroll="internal"]) .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-datagrid-rowsview,
html:not([data-os-grid-scroll="internal"]) main .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-datagrid-rowsview,
html:not([data-os-grid-scroll="internal"]) .app-content .os-dx-grid:not(.os-dx-grid--fill):not([data-os-grid-internal-scroll="1"]) .dx-datagrid-rowsview {
  overflow-x: auto !important;
  overflow-y: visible !important;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  min-height: 0 !important;
  height: auto !important;
  max-height: none !important;
}

/* Viewport-fitted grids (Mass Balance, PRS Balance, Comm, fill-page shells):
   keep a real vertical scrollport so DX column headers stay visible. */
.os-dx-grid.os-dx-grid--fill .dx-datagrid,
body.os-table-fill-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid,
body.os-table-fill-page .os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"] .dx-datagrid,
.ags-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid,
.prs-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid,
.ags-comm-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid,
.ags-mass-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid {
  height: 100% !important;
  max-height: 100% !important;
}

.os-dx-grid.os-dx-grid--fill .dx-datagrid-headers,
body.os-table-fill-page .os-dx-grid .dx-datagrid-headers,
.ags-balance-page .os-dx-grid .dx-datagrid-headers,
.prs-balance-page .os-dx-grid .dx-datagrid-headers,
.ags-comm-page .os-dx-grid .dx-datagrid-headers,
.ags-mass-balance-page .os-dx-grid .dx-datagrid-headers {
  /* DX headers are block-level scroll hosts; keep that (do not switch to table/grid). */
  display: block !important;
  visibility: visible !important;
  opacity: 1 !important;
  flex: 0 0 auto !important;
  height: auto !important;
  min-height: var(--os-grid-header-row-height, 36px) !important;
  /* Hidden X; scroll-container owns horizontal sync with the body. */
  overflow-x: hidden !important;
  overflow-y: visible !important;
  z-index: 2;
}

.os-dx-grid.os-dx-grid--fill .dx-datagrid-headers .dx-header-row > td,
.os-dx-grid.os-dx-grid--fill .dx-datagrid-headers .dx-datagrid-text-content,
body.os-table-fill-page .os-dx-grid .dx-datagrid-headers .dx-header-row > td,
body.os-table-fill-page .os-dx-grid .dx-datagrid-headers .dx-datagrid-text-content,
.ags-balance-page .os-dx-grid .dx-datagrid-headers .dx-header-row > td,
.ags-balance-page .os-dx-grid .dx-datagrid-headers .dx-datagrid-text-content,
.prs-balance-page .os-dx-grid .dx-datagrid-headers .dx-header-row > td,
.prs-balance-page .os-dx-grid .dx-datagrid-headers .dx-datagrid-text-content {
  visibility: visible !important;
  opacity: 1 !important;
  color: var(--os-color-grid-header-text) !important;
}

.os-dx-grid.os-dx-grid--fill .dx-datagrid-rowsview,
body.os-table-fill-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview,
body.os-table-fill-page .os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"] .dx-datagrid-rowsview,
body.os-table-fill-page .os-dx-grid[data-os-grid-size="content"][data-os-grid-height="fixed"] .dx-datagrid-rowsview,
.ags-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview,
.prs-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview,
.ags-comm-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview,
.ags-mass-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview {
  /* Y hidden here; native/simulated scrollport below owns both axes. */
  overflow-x: hidden !important;
  overflow-y: hidden !important;
  overscroll-behavior-x: contain;
  min-height: 0 !important;
  height: 100% !important;
  max-height: 100% !important;
  flex: 1 1 auto !important;
}

.os-dx-grid.os-dx-grid--fill .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"] .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid[data-os-grid-size="content"][data-os-grid-height="fixed"] .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
.ags-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
.prs-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
.ags-comm-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container,
.ags-mass-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-native .dx-scrollable-container {
  overflow-x: auto !important;
  overflow-y: auto !important;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  min-height: 0 !important;
  height: 100% !important;
  max-height: 100% !important;
  flex: 1 1 auto !important;
}

.os-dx-grid.os-dx-grid--fill .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid.os-dx-grid--content[data-os-grid-height="fixed"] .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid[data-os-grid-size="content"][data-os-grid-height="fixed"] .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
.ags-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
.prs-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
.ags-comm-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container,
.ags-mass-balance-page .os-dx-grid:not(.os-dx-grid--content):not([data-os-grid-size="content"]) .dx-datagrid-rowsview.dx-scrollable-simulated .dx-scrollable-container {
  overflow: hidden !important;
  min-height: 0 !important;
  height: 100% !important;
  max-height: 100% !important;
  flex: 1 1 auto !important;
}

/*
  Nested master-detail grids must size to content.
  Fill-page rules above use descendant selectors and would collapse detail rowsviews
  to a thin "Inv…" header strip inside .dx-master-detail-cell.
*/
.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell,
.ags-balance-page .os-dx-grid .dx-master-detail-cell,
.prs-balance-page .os-dx-grid .dx-master-detail-cell,
.ags-comm-page .os-dx-grid .dx-master-detail-cell,
.ags-mass-balance-page .os-dx-grid .dx-master-detail-cell,
body.os-table-fill-page .os-dx-grid .dx-master-detail-cell {
  display: block !important;
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  overflow: visible !important;
  padding: 0.35rem 0.5rem 0.5rem !important;
  background: var(--os-color-surface-muted, #f8fafc);
}

.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell > .dx-datagrid,
.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell .dx-datagrid,
.ags-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid,
.prs-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid,
.ags-comm-page .os-dx-grid .dx-master-detail-cell .dx-datagrid,
.ags-mass-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid,
body.os-table-fill-page .os-dx-grid .dx-master-detail-cell .dx-datagrid {
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  overflow: visible !important;
  flex: none !important;
}

.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell .dx-datagrid-headers,
.ags-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-headers,
.prs-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-headers,
.ags-comm-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-headers,
.ags-mass-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-headers,
body.os-table-fill-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-headers {
  height: auto !important;
  max-height: none !important;
  flex: 0 0 auto !important;
  overflow: visible !important;
}

.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell .dx-datagrid-rowsview,
.ags-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview,
.prs-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview,
.ags-comm-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview,
.ags-mass-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview,
body.os-table-fill-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview {
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  overflow: visible !important;
  flex: none !important;
}

.os-dx-grid.os-dx-grid--fill .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container,
.ags-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container,
.prs-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container,
.ags-comm-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container,
.ags-mass-balance-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container,
body.os-table-fill-page .os-dx-grid .dx-master-detail-cell .dx-datagrid-rowsview .dx-scrollable-container {
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  overflow-x: auto !important;
  overflow-y: visible !important;
  flex: none !important;
}

/* Detail grids: no empty freespace under the last data/summary row. */
.ags-balance-detail-grid .dx-freespace-row,
.prs-balance-detail-grid .dx-freespace-row,
.dx-master-detail-cell .dx-datagrid .dx-freespace-row {
  display: none !important;
  height: 0 !important;
  min-height: 0 !important;
  max-height: 0 !important;
}

.ags-balance-detail-grid .dx-freespace-row > td,
.prs-balance-detail-grid .dx-freespace-row > td,
.dx-master-detail-cell .dx-datagrid .dx-freespace-row > td {
  padding: 0 !important;
  border: 0 !important;
  height: 0 !important;
}

/* Headers / totals: keep DX table layout so columns stay aligned while scrolling */
.os-page-grid-view .dx-datagrid-headers,
.os-dx-grid .dx-datagrid-headers,
main .dx-datagrid-headers,
.os-page-grid-view .dx-datagrid-total-footer,
.os-dx-grid .dx-datagrid-total-footer,
main .dx-datagrid-total-footer,
.os-page-grid-view .dx-datagrid-rowsview,
.os-dx-grid .dx-datagrid-rowsview,
main .dx-datagrid-rowsview {
  width: 100% !important;
  max-width: 100% !important;
  box-sizing: border-box !important;
}

/* Header/body/footer column alignment contract:
   DevExtreme sets matching pixel widths on header + body tables and <col>s.
   NEVER override those with width:auto/100% — that is the root cause of
   header borders drifting from body borders (especially with a V-scrollbar).
   Banded grids: os-banded-grid-align.js owns the shared leaf-width / colgroup model. */
main .dx-datagrid-headers .dx-datagrid-table,
main .dx-datagrid-rowsview .dx-datagrid-table,
main .dx-datagrid-total-footer .dx-datagrid-table,
.os-dx-grid .dx-datagrid-headers .dx-datagrid-table,
.os-dx-grid .dx-datagrid-rowsview .dx-datagrid-table,
.os-dx-grid .dx-datagrid-total-footer .dx-datagrid-table,
.os-page-grid-view .dx-datagrid-headers .dx-datagrid-table,
.os-page-grid-view .dx-datagrid-rowsview .dx-datagrid-table,
.os-page-grid-view .dx-datagrid-total-footer .dx-datagrid-table {
  table-layout: fixed !important;
  border-collapse: separate !important;
  border-spacing: 0 !important;
  max-width: none !important;
  /* width: intentionally unset — DX / banded-align inline pixel width must win */
}

/* Fixed-column panes: same rule — do not force width:auto/100%. */
main .dx-datagrid-table-fixed,
.os-dx-grid .dx-datagrid-table-fixed,
.os-page-grid-view .dx-datagrid-table-fixed,
main .dx-datagrid-content-fixed .dx-datagrid-table,
.os-dx-grid .dx-datagrid-content-fixed .dx-datagrid-table,
.os-page-grid-view .dx-datagrid-content-fixed .dx-datagrid-table {
  max-width: none !important;
}

/* UI-GRID-1: header/footer gutter is applied in JS via padding-inline-end
   (OrganicSystemGridDefaults.syncColumnScrollbarCompensation). Force
   scrollbar-gutter:auto so a stable gutter never double-reserves with that pad. */
.os-page-grid-view .dx-datagrid-headers .dx-datagrid-scroll-container,
.os-dx-grid .dx-datagrid-headers .dx-datagrid-scroll-container,
.os-grid-container .dx-datagrid-headers .dx-datagrid-scroll-container,
main .dx-datagrid-headers .dx-datagrid-scroll-container,
.os-page-grid-view .dx-datagrid-total-footer .dx-datagrid-scroll-container,
.os-dx-grid .dx-datagrid-total-footer .dx-datagrid-scroll-container,
.os-grid-container .dx-datagrid-total-footer .dx-datagrid-scroll-container,
main .dx-datagrid-total-footer .dx-datagrid-scroll-container,
.os-page-grid-view .dx-datagrid-rowsview .dx-scrollable-container,
.os-dx-grid .dx-datagrid-rowsview .dx-scrollable-container,
.os-grid-container .dx-datagrid-rowsview .dx-scrollable-container,
main .dx-datagrid-rowsview .dx-scrollable-container {
  box-sizing: border-box !important;
  scrollbar-gutter: auto !important;
}

/* Global guarantee: data-grid column headers must never be suppressed. */
main .dx-datagrid-headers,
.os-dx-grid .dx-datagrid-headers,
.os-page-grid-view .dx-datagrid-headers {
  visibility: visible !important;
  opacity: 1 !important;
}

.os-page-grid-view .dx-datagrid-table,
.os-dx-grid .dx-datagrid-table,
main .dx-datagrid-table,
.os-page-grid-view .dx-datagrid-table-fixed,
.os-dx-grid .dx-datagrid-table-fixed,
main .dx-datagrid-table-fixed {
  /* Let DX manage column widths; never force host-stretch that desyncs header/body. */
  max-width: none !important;
}

/* Fixed / command / selection columns must not be clipped by host overflow */
.os-page-grid-view .dx-command-select,
.os-dx-grid .dx-command-select,
main .dx-datagrid .dx-command-select,
.os-page-grid-view .dx-command-edit,
.os-dx-grid .dx-command-edit,
main .dx-datagrid .dx-command-edit,
.os-page-grid-view .dx-datagrid-headers .dx-header-row > td.dx-command-select,
.os-page-grid-view .dx-datagrid-rowsview .dx-data-row > td.dx-command-select {
  overflow: visible !important;
}

/* Pager stays inside host width */
.os-page-grid-view .dx-datagrid-pager,
.os-dx-grid .dx-datagrid-pager,
main .dx-datagrid-pager {
  width: 100% !important;
  max-width: 100% !important;
  overflow-x: auto;
  overflow-y: hidden;
  box-sizing: border-box;
}

/* ---------- HTML table grid views ---------- */
/* Document-flow only; internal-scroll hosts keep constrained height + Y auto (os-scroll / scroll-engine). */
html:not([data-os-grid-scroll="internal"]) .os-page-table-view:not(.os-grid-container):not([data-os-grid-internal-scroll="1"]) {
  overflow-x: auto !important;
  overflow-y: visible !important;
  overscroll-behavior-x: contain;
  -webkit-overflow-scrolling: touch;
  height: auto !important;
  max-height: none !important;
}

.os-page-table-view.os-grid-container,
.os-page-table-view[data-os-grid-internal-scroll="1"],
html[data-os-grid-scroll="internal"] .os-page-table-view {
  overflow-x: auto !important;
  overflow-y: auto !important;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  min-height: 0 !important;
  height: var(--os-gc-height, 100%) !important;
  max-height: var(--os-gc-height, 100%) !important;
}

.os-page-table-view table:not(.os-desktop-form-table):not(.aps-site-table),
.table-responsive > table:not(.os-desktop-form-table):not(.aps-site-table),
.os-erp-data-table-host > table:not(.os-desktop-form-table):not(.aps-site-table),
.os-native-table-scroll > table:not(.os-desktop-form-table):not(.aps-site-table) {
  width: max-content;
  min-width: 100%;
  max-width: none; /* allow wider than host; host scrolls */
}

main .table-responsive,
main .os-erp-data-table-host,
main .os-native-table-scroll {
  width: 100%;
  max-width: 100%;
  min-width: 0;
  overflow-x: auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* ---------- Plan / dual grids ---------- */
.plan-grids-row,
.plan-grid-panel,
.plan-grid-panel-prev,
.plan-grid-panel-current {
  min-width: 0 !important;
  max-width: 100% !important;
}

.plan-grid-panel > [id$="-grid"],
.plan-grid-panel .dx-datagrid {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
}

/* ---------- Table-fill index pages ---------- */
body.os-table-fill-page .os-page-grid-view,
body.os-table-fill-page .os-dx-grid,
body.os-module-shell.os-table-fill-page .os-page-grid-view,
body.os-module-shell.os-table-fill-page .os-dx-grid {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
  overflow: hidden !important;
}

body.os-table-fill-page .dx-datagrid,
body.os-module-shell.os-table-fill-page .dx-datagrid {
  width: 100% !important;
  max-width: 100% !important;
}

/* ---------- Narrow viewports: adaptive height, no page x-scroll ---------- */
@media (max-width: 991.98px) {
  /* Document-flow only — internal grid-scroll keeps constrained host + Y auto */
  html:not([data-os-grid-scroll="internal"]) body.os-app-shell:not(.login-shell):not(.os-module-shell) .os-page-grid-view {
    width: 100% !important;
    max-width: 100% !important;
    min-height: var(--os-grid-host-min-height) !important;
    height: auto !important;
    overflow-x: clip !important;
    overflow-y: visible !important;
  }

  html:not([data-os-grid-scroll="internal"]) body.os-app-shell:not(.login-shell):not(.os-module-shell) .os-page-grid-view .dx-datagrid {
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    min-height: var(--os-grid-host-min-height) !important;
  }

  html:not([data-os-grid-scroll="internal"]) body.os-module-shell .os-page-grid-view:not(.os-grid-container):not(.os-dx-grid--fill),
  html:not([data-os-grid-scroll="internal"]) body.os-module-shell .os-dx-grid:not(.os-grid-container):not(.os-dx-grid--fill) {
    width: 100% !important;
    max-width: 100% !important;
    overflow-x: clip !important;
    overflow-y: visible !important;
  }

  html[data-os-grid-scroll="internal"] body.os-module-shell .os-page-grid-view,
  html[data-os-grid-scroll="internal"] body.os-module-shell .os-dx-grid,
  html[data-os-grid-scroll="internal"] body.os-app-shell .os-page-grid-view,
  html[data-os-grid-scroll="internal"] body.os-app-shell .os-dx-grid {
    width: 100% !important;
    max-width: 100% !important;
    overflow: hidden !important;
    min-height: 0 !important;
  }
}

/* Overlay lookup grids: stay inside popup, scroll inside */
.dx-dropdowneditor-overlay .dx-datagrid,
.dx-overlay-wrapper[class*="-popup"] .dx-datagrid,
.dx-overlay-wrapper[class*="-dropdown"] .dx-datagrid {
  width: 100% !important;
  max-width: 100% !important;
  min-width: 0 !important;
}

.dx-dropdowneditor-overlay .dx-datagrid-rowsview,
.dx-overlay-wrapper[class*="-popup"] .dx-datagrid-rowsview {
  overflow-x: auto !important;
  overflow-y: auto !important;
}

/* =============================================================================
   PHASE 3B — Grid visual standard (presentation only; scroll ownership unchanged)
   ============================================================================= */
:root {
  --os-grid-cell-pad-x: 0.35rem;
  --os-grid-empty-font: 0.875rem;
}

/* Prefer clean ERP borders over decorative elevation */
body.os-app-shell .dx-datagrid,
body.os-module-shell .dx-datagrid {
  box-shadow: none;
}

/* Data cells: consistent padding + middle align (overrides fit-width top align) */
.os-page-grid-view .dx-datagrid-rowsview .dx-data-row > td,
.os-dx-grid .dx-datagrid-rowsview .dx-data-row > td,
main .dx-datagrid-rowsview .dx-data-row > td,
.os-grid-fit-width .dx-datagrid-rowsview .dx-data-row > td {
  padding-inline: var(--os-grid-cell-pad-x) !important;
  vertical-align: middle !important;
}

/* Action / command cells stay centered */
.os-page-grid-view .dx-datagrid-rowsview .dx-data-row > td.dx-command-edit,
.os-dx-grid .dx-datagrid-rowsview .dx-data-row > td.dx-command-edit,
.os-page-grid-view .dx-datagrid-rowsview .dx-data-row > td.dx-command-select,
.os-dx-grid .dx-datagrid-rowsview .dx-data-row > td.dx-command-select,
.os-page-grid-view .dx-datagrid-headers .dx-header-row > td.dx-command-edit,
.os-dx-grid .dx-datagrid-headers .dx-header-row > td.dx-command-edit,
.os-page-grid-view .dx-datagrid-headers .dx-header-row > td.dx-command-select,
.os-dx-grid .dx-datagrid-headers .dx-header-row > td.dx-command-select {
  text-align: center !important;
  vertical-align: middle !important;
}

/* Numeric / end-aligned data cells keep readable tabular numbers */
.os-page-grid-view .dx-datagrid-rowsview .dx-data-row > td.dx-datagrid-align-right,
.os-dx-grid .dx-datagrid-rowsview .dx-data-row > td.dx-datagrid-align-right,
main .dx-datagrid-rowsview .dx-data-row > td.dx-datagrid-align-right {
  text-align: end !important;
  font-variant-numeric: tabular-nums;
}

/* Professional empty state.
   Do not force display when DX marks the node hidden (dx-hidden) —
   display:flex !important was overriding DX and leaving "No data"
   overlays on top of real rows. */
.os-page-grid-view .dx-datagrid-nodata:not(.dx-hidden),
.os-dx-grid .dx-datagrid-nodata:not(.dx-hidden),
main .dx-datagrid-nodata:not(.dx-hidden) {
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
  font-size: var(--os-grid-empty-font) !important;
  font-weight: 550;
  color: var(--os-color-text-muted, #64748b) !important;
  padding: 1.25rem 1rem !important;
  line-height: 1.4 !important;
}

/* RTL: keep header/action indicators on the logical end */
[dir="rtl"] .dx-datagrid-headers .dx-header-row > td .dx-column-indicators:not(.dx-visibility-hidden) {
  inset-inline-end: 2px;
  inset-inline-start: auto;
}

/* DevExtreme clones .dx-column-indicators with .dx-visibility-hidden as a width spacer.
   Theme rules must never force those clones (or their filter/sort icons) visible —
   that is the root cause of duplicated header filter icons project-wide. */
.dx-datagrid-headers .dx-header-row > td .dx-column-indicators.dx-visibility-hidden,
.dx-datagrid-headers .dx-band-row > td .dx-column-indicators.dx-visibility-hidden,
.os-page-grid-view .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden,
.os-dx-grid .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden,
main .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden {
  visibility: hidden !important;
  pointer-events: none !important;
}

.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-header-filter,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-header-filter-indicator,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-sort,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-sort-up,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-sort-down,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-icon,
.dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden [class*="dx-icon"],
.os-page-grid-view .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-header-filter,
.os-dx-grid .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-header-filter,
main .dx-datagrid-headers .dx-column-indicators.dx-visibility-hidden .dx-header-filter {
  visibility: hidden !important;
  opacity: 0 !important;
  pointer-events: none !important;
}
