/* ==========================================================================
   Patels Fashion ERP - server.css
   The few styles the server-driven build needs on top of the prototype design system (app.css, components.css,
   pages.css stay exactly as the client approved them): loading + error states of tables and forms, clickable rows,
   the pill DataTables shows while the Yajra endpoint answers.
   ========================================================================== */

/* ---- server-side DataTable: "Loading…" pill over the table, rows dimmed meanwhile ---- */
.dt-container { position: relative; }
.dt-container div.dt-processing {
  position: absolute; top: 50%; left: 50%; width: auto; margin: -20px 0 0; padding: 8px 16px; z-index: 12; transform: translateX(-50%);
  display: inline-flex; align-items: center; gap: 10px; white-space: nowrap; font-size: 13px; font-weight: 600; color: var(--erp-text);
  background: var(--erp-surface); border: 1px solid var(--erp-border); border-radius: 999px; box-shadow: var(--erp-shadow-md);
}
.dt-container div.dt-processing .spinner-border { color: var(--erp-primary); }
.table-card.erp-table-busy table.erp-table tbody { opacity: .45; transition: opacity .15s; }
table.erp-table.row-clickable tbody tr { cursor: pointer; }
/* first load: no "No records yet" flash while the first answer is on its way */
table.erp-first-load tbody td.dt-empty > * { visibility: hidden; }

/* ---- generic busy area (ERP.ui.loading) ---- */
.erp-is-loading { position: relative; }
.erp-is-loading > :not(.erp-loading-mask) { opacity: .45; pointer-events: none; }
.erp-loading-mask {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 12; display: inline-flex; align-items: center; gap: 10px;
  padding: 8px 16px; font-size: 13px; font-weight: 600; background: var(--erp-surface); border: 1px solid var(--erp-border); border-radius: 999px; box-shadow: var(--erp-shadow-md);
}
.erp-loading-mask .spinner-border { color: var(--erp-primary); }

/* ---- server validation messages ---- */
.invalid-feedback[data-server] { display: block; }
.select2-container.is-invalid .select2-selection,
select.is-invalid + .select2-container--bootstrap-5 .select2-selection { border-color: var(--c-danger); }
select.is-invalid + .select2-container--bootstrap-5.select2-container--focus .select2-selection,
select.is-invalid + .select2-container--bootstrap-5.select2-container--open .select2-selection { box-shadow: 0 0 0 .25rem rgba(var(--c-danger-rgb, 220, 53, 69), .18); }

/* ---- busy buttons keep their size ---- */
.btn[aria-busy="true"] { pointer-events: none; }
.btn .spinner-border-sm { width: 1em; height: 1em; border-width: .15em; }

/* ---- keyboard / screen-reader navigation ---- */
/* "Skip to content": the first Tab stop of every screen, visible only while it has the focus */
.skip-link { position: fixed; top: 8px; left: 8px; z-index: 3000; padding: 8px 14px; border-radius: 8px; background: var(--erp-primary); color: #fff; font-weight: 600; font-size: 13px; text-decoration: none; transform: translateY(-200%); }
.skip-link:focus { transform: none; color: #fff; }
#erp-page:focus { outline: 0; }
/* the links of a collapsed sidebar group are not Tab stops (they are only clipped by the 0fr grid row, still focusable): hidden once the close animation ended */
.sb-item:not(.open) > .sb-sub, .sb-subgroup:not(.open) > .sb-sub { visibility: hidden; transition: grid-template-rows .26s ease, visibility 0s linear .26s; }

/* the prototype's soft buttons (.btn-soft) show no ring when they take the keyboard focus (found by qa/a11y-parity.js) */
.btn-soft:focus-visible { outline: 2px solid var(--t, var(--erp-primary)); outline-offset: 2px; }

/* ---- very long unbroken text (a pasted URL, 60 letters without a space, hostile input) ----
   A word that does not fit its box breaks inside the box, and nothing inside the page can widen the page itself (found by the
   hostile-text crawl of docs/modules/review-ec.md: 16 of 511 pages scrolled sideways). `overflow-wrap: anywhere` only acts on a
   word that does not fit its line, so normal text and the prototype's layout are untouched; `clip` (not `hidden`) keeps sticky
   headers working. Tables keep their own horizontal scroll. */
.erp-content { overflow-x: clip; }
.erp-content :where(.side-kv, .info-row, .rt-node, .qt-kv, .st-opt, .link-card, .kv-value, .ir-v, .cell-title, .cell-sub, .lc-t, .lc-s) { overflow-wrap: anywhere; min-width: 0; }
/* ... but inside a box that scrolls on its own (DataTables body, .table-responsive) the prototype's `break-word` stays: `anywhere` shrinks the min-content of the
   cells and re-distributes the columns of tight tables by a few px (sales order lines, found by qa/visual-regression.js); a hostile long word there scrolls
   inside its table, never the page. */
.erp-content :where(.dt-layout-table, .table-responsive) :where(.side-kv, .info-row, .rt-node, .qt-kv, .st-opt, .link-card, .kv-value, .ir-v, .cell-title, .cell-sub, .lc-t, .lc-s) { overflow-wrap: break-word; }
