/* ══════════════════════════════════════════════════════════════════════
   ERP COMPONENT LIBRARY
   Unified, token-driven component classes for the entire application.
   All colors / radii / spacing come from var(--erp-*) defined in app.css.
   ══════════════════════════════════════════════════════════════════════ */

/* ─────────────────────────────────────────────────────────
   CARD — soft elevation, no hard border
   ───────────────────────────────────────────────────────── */
.erp-card {
    background: var(--erp-surface);
    border-radius: var(--erp-radius-lg);
    box-shadow: var(--erp-shadow);
    overflow: hidden;
    transition: box-shadow .2s;
}
.erp-card:hover { box-shadow: var(--erp-shadow-md); }
.erp-card-header {
    padding: 14px 18px 10px;
    background: var(--erp-surface);
    color: var(--erp-text);
    font-weight: 600;
    font-size: 14px;
    display: flex;
    align-items: center;
    gap: var(--erp-gap-sm);
}
.erp-card-header > i { color: var(--erp-primary); }
.erp-card-header .erp-card-title { flex: 1; }
.erp-card-body { padding: 16px 18px 18px; }
.erp-card-body--flush { padding: 0; }
.erp-card-body--compact { padding: 4px 4px; }
.erp-card-body--scroll  { overflow-y: auto; flex: 1; min-height: 0; }

/* ─────────────────────────────────────────────────────────
   TOOLBAR — grouped icon buttons with vertical separators
   ───────────────────────────────────────────────────────── */
.erp-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 6px 12px;
    background: var(--erp-surface);
    border-bottom: 1px solid var(--erp-border);
    min-height: 48px;
    flex-wrap: wrap;
}
/* Object form: pin the action bar to the top of the scroll region (desktop) so the
   Save/actions stay visible when a long form scrolls. Mobile keeps its fixed bottom
   bar (see .erp-shell.is-mobile .erp-toolbar--object). */
.erp-shell:not(.is-mobile) .erp-toolbar--object {
    position: sticky;
    top: 0;
    z-index: 30;
}
.erp-toolbar--gradient {
    background: linear-gradient(135deg, var(--erp-primary-band) 0%, var(--erp-primary) 100%);
    color: #fff;
    border-bottom: 0;
}
.erp-toolbar--gradient .erp-tb-btn { color: rgba(255,255,255,.85); }
.erp-toolbar--gradient .erp-tb-btn:hover:not(:disabled) {
    background: rgba(255,255,255,.12);
    border-color: rgba(255,255,255,.2);
    color: #fff;
}

.erp-toolbar-left,
.erp-toolbar-right {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}
.erp-toolbar-right { margin-left: auto; }
.erp-toolbar-middle { flex: 1; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; justify-content: center; }
.erp-toolbar-middle--start { justify-content: flex-start; }

.erp-toolbar-title {
    font-weight: 600;
    font-size: 14px;
    color: var(--erp-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 280px;
}
.erp-toolbar--gradient .erp-toolbar-title { color: #fff; }

.erp-toolbar-sub {
    font-size: 11px;
    color: var(--erp-text-muted);
    margin-top: 1px;
}
.erp-toolbar--gradient .erp-toolbar-sub { color: rgba(255,255,255,.7); }

/* Toolbar button group */
.erp-tb-group {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 0 6px;
    border-right: 1px solid var(--erp-border);
}
.erp-toolbar--gradient .erp-tb-group { border-right-color: rgba(255,255,255,.18); }
.erp-tb-group:last-child { border-right: 0; }

.erp-tb-btn {
    /* Icon-only buttons stay a 32px square (min-width floor); buttons that ALSO carry a
       text label grow to fit it via auto width + horizontal padding, instead of the label
       overflowing the fixed box and overlapping the icon/neighbours. */
    min-width: 32px;
    height: 30px;
    padding: 0 8px;
    gap: 6px;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 1px solid transparent;
    border-radius: var(--erp-radius-sm);
    background: transparent;
    color: var(--erp-text);
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    transition: background .12s, border-color .12s, color .12s;
    position: relative;
}
.erp-tb-btn:hover:not(:disabled) {
    background: var(--erp-surface-alt);
    border-color: var(--erp-border);
}
.erp-tb-btn:disabled { opacity: .35; cursor: not-allowed; }
.erp-tb-btn.active {
    background: var(--erp-primary-tint);
    color: var(--erp-primary);
    border-color: var(--erp-primary);
}
.erp-tb-btn--success { color: var(--erp-success); }
.erp-tb-btn--danger  { color: var(--erp-danger);  }
.erp-tb-btn--warning { color: var(--erp-warning); }

/* Save button with pending unsaved changes — draw attention with a tinted
   fill and a small notification dot at the top-right corner. */
.erp-tb-btn--dirty {
    background: rgba(34,197,94,.12);
    border-color: rgba(34,197,94,.35);
}
.erp-tb-btn--dirty:hover:not(:disabled) {
    background: rgba(34,197,94,.18);
    border-color: var(--erp-success);
}
.erp-tb-dirty-dot {
    position: absolute;
    top: 3px; right: 3px;
    width: 7px; height: 7px;
    border-radius: 50%;
    background: var(--erp-warning);
    box-shadow: 0 0 0 2px var(--erp-surface);
}

/* Action buttons aggregated from ActionsList fields — wider so the label
   fits next to the icon; uses the primary accent so they read as the
   record's "operations". */
.erp-tb-btn--action {
    width: auto;
    min-width: 32px;
    padding: 0 10px;
    gap: 6px;
    color: var(--erp-primary);
    font-size: 12.5px;
    font-weight: 600;
}
.erp-tb-btn--action .erp-tb-btn-label {
    white-space: nowrap;
}
/* Child-grid "edit full details" popup — hosts an embedded object form (its own fields
   + nested grids). The width tier must go on the OUTER .erp-modal (the inner content is
   width:100%), same pattern as .erp-modal--lg/xl. Wide so the form's two-column field
   layout renders normally; the body scrolls so the sticky form toolbar stays visible. */
.erp-modal:has(> .erp-modal-content.erp-cg-popup) { width: min(1180px, 96vw); }
.erp-cg-popup-body { padding: 0; max-height: 82vh; overflow-y: auto; }

/* "Running…" indicator shown next to the Cancel button while an action's proc executes. */
.erp-tb-running {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 0 8px; font-size: 12.5px; font-weight: 600;
    color: var(--erp-text-soft, #64748b); white-space: nowrap;
}
.erp-tb-group--actions {
    flex-wrap: wrap;
}

/* AI Import button — wider with a label, violet AI accent. */
.erp-tb-btn--ai {
    width: auto; min-width: 32px;
    padding: 0 10px; gap: 6px;
    color: #7c3aed;
    font-size: 12.5px; font-weight: 600;
}
.erp-tb-btn--ai:hover:not(:disabled) {
    background: rgba(124,58,237,.10);
    border-color: rgba(124,58,237,.35);
    color: #6d28d9;
}
.erp-tb-btn--ai .erp-tb-btn-label { white-space: nowrap; }

/* AI import file drop-zone (inside the import modal). */
.ai-drop {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 8px;
    width: 100%; min-height: 120px;
    padding: 18px;
    border: 2px dashed var(--erp-border-strong);
    border-radius: var(--erp-radius);
    background: var(--erp-surface-alt);
    color: var(--erp-text-muted);
    cursor: pointer;
    text-align: center;
    transition: border-color .15s, background .15s, color .15s;
}
.ai-drop:hover { border-color: #7c3aed; color: #6d28d9; }
.ai-drop.has-file { border-style: solid; border-color: var(--erp-success); color: var(--erp-text); }
.ai-drop i { font-size: 26px; color: #7c3aed; }
.ai-drop.has-file i { color: var(--erp-success); }
.ai-drop input[type="file"] { display: none; }

/* Notification badge on a toolbar button */
.erp-tb-badge {
    position: absolute;
    top: -2px; right: -2px;
    min-width: 14px; height: 14px;
    padding: 0 4px;
    border-radius: 7px;
    background: var(--erp-danger);
    color: #fff;
    font-size: 9px;
    font-weight: 700;
    line-height: 14px;
    text-align: center;
}

/* Status pill (Locked / Awaiting Approval) */
.erp-pill {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 3px 10px;
    border-radius: 999px;
    font-size: 11.5px;
    font-weight: 500;
    border: 1px solid;
    line-height: 1.2;
}
.erp-pill--danger  { background: rgba(239,68,68,.1);  border-color: rgba(239,68,68,.25);  color: var(--erp-danger); }
.erp-pill--warning { background: rgba(245,158,11,.1); border-color: rgba(245,158,11,.25); color: var(--erp-warning); }
.erp-pill--success { background: rgba(34,197,94,.1);  border-color: rgba(34,197,94,.25);  color: var(--erp-success); }
.erp-pill--info    { background: var(--erp-primary-tint); border-color: rgba(37,99,235,.25); color: var(--erp-primary); }

/* Action button — solid, rounded rectangle, no gradient/glow. */
.erp-cta {
    background: var(--erp-primary);
    color: #fff !important;
    border: 1px solid transparent;
    border-radius: var(--erp-radius-sm);
    padding: 7px 14px;
    font-size: var(--erp-fs-toolbar);
    font-weight: 500;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    line-height: 1.2;
    transition: background .15s, border-color .15s, color .15s;
    white-space: nowrap;
    text-decoration: none;
    font-family: inherit;
}
.erp-cta:hover { background: var(--erp-primary-hover); color: #fff; }
.erp-cta:active { background: var(--erp-primary-active); }
.erp-cta:disabled {
    opacity: .55; cursor: not-allowed;
    background: var(--erp-primary);
}
.erp-cta--primary { background: var(--erp-primary); }
.erp-cta--primary:hover { background: var(--erp-primary-hover); }
.erp-cta--success { background: var(--erp-success); }
.erp-cta--success:hover { background: #16a34a; }
.erp-cta--danger  { background: var(--erp-danger); }
.erp-cta--danger:hover  { background: #dc2626; }
.erp-cta--warning { background: var(--erp-warning); color: #fff !important; }
.erp-cta--warning:hover { background: #d97706; }

/* Ghost / cancel variant — outlined neutral */
.erp-cta--ghost {
    background: var(--erp-surface);
    color: var(--erp-text) !important;
    border-color: var(--erp-border-strong);
}
.erp-cta--ghost:hover {
    background: var(--erp-surface-alt);
    color: var(--erp-text) !important;
    border-color: var(--erp-text-soft);
}

/* Subtle / "secondary" — primary tint background, primary text */
.erp-cta--subtle {
    background: var(--erp-primary-tint);
    color: var(--erp-primary) !important;
    border-color: transparent;
}
.erp-cta--subtle:hover {
    background: var(--erp-primary-tint);
    color: var(--erp-primary-hover) !important;
    filter: brightness(.97);
}

/* Size modifiers */
.erp-cta--sm { padding: 5px 10px; font-size: 12px; gap: 5px; }
.erp-cta--lg { padding: 10px 20px; font-size: 14px; gap: 8px; }

/* Row-action icon button — for grid command cells */
.erp-icon-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px; height: 24px;
    padding: 0;
    background: transparent;
    color: var(--erp-text-muted);
    border: 1px solid var(--erp-border);
    border-radius: var(--erp-radius-sm);
    cursor: pointer;
    font-size: 11px;
    transition: background .12s, color .12s, border-color .12s;
}
.erp-icon-btn:hover {
    background: var(--erp-primary-tint);
    color: var(--erp-primary);
    border-color: var(--erp-primary);
}
.erp-icon-btn--danger { color: var(--erp-danger); }
.erp-icon-btn--danger:hover {
    background: rgba(239,68,68,.1);
    color: var(--erp-danger);
    border-color: var(--erp-danger);
}
.erp-icon-btn--success { color: var(--erp-success); }
.erp-icon-btn--success:hover {
    background: rgba(34,197,94,.1);
    color: var(--erp-success);
    border-color: var(--erp-success);
}

/* Spinner sized to live inside a CTA on dark background */
.erp-spinner--on-dark {
    border-color: rgba(255,255,255,.3);
    border-top-color: #fff;
}

/* ─────────────────────────────────────────────────────────
   TABS — solid-blue active state
   ───────────────────────────────────────────────────────── */
.erp-tabs {
    display: flex;
    gap: 3px;
    padding: 2px;
    background: var(--erp-surface-alt);
    border-radius: var(--erp-radius);
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: thin;
    margin: 0 0 8px 0;
    list-style: none;
    width: fit-content;
    max-width: 100%;
}
.erp-tabs::-webkit-scrollbar { height: 4px; }
.erp-tabs::-webkit-scrollbar-thumb { background: var(--erp-border-strong); border-radius: 2px; }

.erp-tab {
    padding: 4px 13px;
    border: 0;
    background: transparent;
    color: var(--erp-text-muted);
    font-size: var(--erp-fs-tab);
    font-weight: 500;
    border-radius: var(--erp-radius-sm);
    cursor: pointer;
    transition: background .15s, color .15s, box-shadow .15s;
    white-space: nowrap;
    display: inline-flex;
    align-items: center;
    gap: 6px;
}
.erp-tab:hover {
    color: var(--erp-text);
}
.erp-tab.active {
    background: var(--erp-surface);
    color: var(--erp-primary) !important;
    font-weight: 600;
    box-shadow: var(--erp-shadow-sm);
}
.erp-tab .erp-tab-badge {
    background: rgba(255,255,255,.25);
    color: #fff;
    font-size: 10px;
    padding: 1px 6px;
    border-radius: 999px;
    font-weight: 700;
}

/* ─────────────────────────────────────────────────────────
   STANDALONE INPUT — for modals, filter rows, dialog forms
   (not wrapped in .erp-field-input, used directly)
   ───────────────────────────────────────────────────────── */
.erp-input {
    display: block;
    width: 100%;
    height: 34px;
    padding: 6px 10px;
    font-size: 13px;
    line-height: 1.2;
    font-family: inherit;
    color: var(--erp-text);
    background: var(--erp-input-bg);
    border: 1px solid transparent;
    border-radius: var(--erp-input-radius);
    transition: border-color .15s, box-shadow .15s, background .15s;
    box-sizing: border-box;
}
.erp-input::placeholder { color: var(--erp-text-soft); }
.erp-input:focus {
    background: var(--erp-surface);
    border-color: var(--erp-input-border-focus);
    box-shadow: 0 0 0 2px rgba(37,99,235,.15);
    outline: none;
}
.erp-input:disabled,
.erp-input[readonly] {
    background: var(--erp-input-bg-readonly);
    color: var(--erp-text-muted);
    cursor: not-allowed;
}
textarea.erp-input  { height: auto; min-height: 76px; resize: vertical; line-height: 1.45; }
select.erp-input    { padding-right: 26px; }

/* Optional small/large variants for dense / dialog headers */
.erp-input--sm { height: 30px; padding: 4px 8px; font-size: 12.5px; }
.erp-input--lg { height: 40px; padding: 8px 12px; font-size: 14px; }

[data-bs-theme="dark"] .erp-input {
    background: var(--erp-input-bg);
    color: var(--erp-text);
}

/* ─────────────────────────────────────────────────────────
   FORM FIELD — horizontal label + input, dense legacy-ERP look
   ───────────────────────────────────────────────────────── */
.erp-field {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 10px;
    min-height: 32px;
}
.erp-field-label {
    flex: 0 0 140px;        /* fixed px so inputs align across half- and full-row fields */
    color: var(--erp-label);
    font-size: var(--erp-fs-label);
    font-weight: 600;
    margin: 0;
    text-align: left;
    word-break: break-word;
    line-height: 1.2;
    padding-right: 4px;
    letter-spacing: .1px;
}
.erp-field-label.required::after {
    content: " *";
    color: var(--erp-success, #16a34a);   /* mandatory marker is GREEN (was red) */
    font-weight: 700;
    margin-left: 1px;
}
/* A mandatory field flagged empty on Save — red outline + a brief shake. */
.erp-field--invalid {
    outline: 2px solid var(--erp-danger, #dc2626);
    outline-offset: 2px; border-radius: 8px;
    animation: erp-invalid-shake .4s ease;
}
@keyframes erp-invalid-shake {
    0%, 100% { transform: translateX(0); }
    20%, 60% { transform: translateX(-4px); }
    40%, 80% { transform: translateX(4px); }
}

.erp-field-input { flex: 1 1 auto; min-width: 0; }

/* ── Plain HTML input — soft tint, subtle border ──────── */
.erp-field-input .form-control,
.erp-field-input input[type="text"],
.erp-field-input input[type="number"],
.erp-field-input input[type="date"],
.erp-field-input textarea,
.erp-field-input select {
    height: var(--erp-row-h);
    min-height: var(--erp-row-h);
    padding: 4px 10px;
    font-size: var(--erp-fs-input);
    border-radius: var(--erp-input-radius);
    border: 1px solid transparent;
    background: var(--erp-input-bg);
    color: var(--erp-text);
    transition: border-color .15s, box-shadow .15s, background .15s;
    width: 100%;
    box-sizing: border-box;
    font-family: inherit;
}
.erp-field-input textarea { height: auto; min-height: 48px; padding: 4px 8px; line-height: 1.4; }

.erp-field-input .form-control:focus,
.erp-field-input input:focus,
.erp-field-input textarea:focus,
.erp-field-input select:focus {
    border-color: var(--erp-input-border-focus);
    box-shadow: 0 0 0 2px rgba(37,99,235,.15);
    outline: none;
    background: var(--erp-surface);
}
.erp-field-input .form-control[disabled],
.erp-field-input .form-control[readonly],
.erp-field-input input[disabled],
.erp-field-input input[readonly] {
    background: var(--erp-input-bg-readonly);
    color: var(--erp-text-muted);
    cursor: not-allowed;
}

/* ── DX Blazor inputs — soft tint, no hard border ────── */
.erp-field-input .dxbl-edit,
.erp-field-input .dxbl-textbox,
.erp-field-input .dxbl-combobox,
.erp-field-input .dxbl-spin-edit,
.erp-field-input .dxbl-date-edit,
.erp-field-input .dxbl-memo {
    width: 100%;
    font-size: var(--erp-fs-input);
    border-radius: var(--erp-input-radius) !important;
    border: 1px solid transparent !important;
    background: var(--erp-input-bg) !important;
    transition: border-color .15s, box-shadow .15s, background .15s;
    min-height: var(--erp-row-h);
}
.erp-field-input .dxbl-edit:focus-within,
.erp-field-input .dxbl-textbox:focus-within,
.erp-field-input .dxbl-combobox:focus-within,
.erp-field-input .dxbl-spin-edit:focus-within,
.erp-field-input .dxbl-date-edit:focus-within,
.erp-field-input .dxbl-memo:focus-within {
    border-color: var(--erp-input-border-focus) !important;
    box-shadow: 0 0 0 2px rgba(37,99,235,.15);
    background: var(--erp-surface) !important;
}

/* Inner DX input element — strip its own border/bg, keep just the text */
.erp-field-input .dxbl-edit input,
.erp-field-input .dxbl-edit .dxbl-edit-input,
.erp-field-input .dxbl-edit textarea {
    background: transparent !important;
    border: 0 !important;
    box-shadow: none !important;
    padding: 0 8px !important;
    height: calc(var(--erp-row-h) - 2px) !important;
    min-height: calc(var(--erp-row-h) - 2px) !important;
    font-size: var(--erp-fs-input) !important;
    color: var(--erp-text) !important;
    line-height: 1.3;
}
.erp-field-input .dxbl-memo textarea {
    height: auto !important;
    min-height: 44px !important;
    line-height: 1.4 !important;
}

/* DX dropdown chevron + clear button — smaller, blue tint on hover */
.erp-field-input .dxbl-edit-btn,
.erp-field-input .dxbl-edit .dxbl-button {
    color: var(--erp-text-muted) !important;
    background: transparent !important;
    border: 0 !important;
    width: 24px !important;
    transition: color .12s, background .12s;
}
.erp-field-input .dxbl-edit-btn:hover,
.erp-field-input .dxbl-edit .dxbl-button:hover {
    color: var(--erp-primary) !important;
    background: rgba(37,99,235,.08) !important;
}

/* Read-only DX inputs get the gray-tint background */
.erp-field-input .dxbl-edit.dxbl-readonly,
.erp-field-input .dxbl-edit[disabled] {
    background: var(--erp-input-bg-readonly) !important;
    border-color: var(--erp-border-strong) !important;
}
.erp-field-input .dxbl-edit.dxbl-readonly input,
.erp-field-input .dxbl-edit[disabled] input {
    color: var(--erp-text-muted) !important;
}

/* Native checkbox used for CheckBox/Bit fields — sized & themed to match form */
.erp-field-input input[type="checkbox"].erp-checkbox {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--erp-primary);
    cursor: pointer;
    flex: 0 0 auto;
}
.erp-field-input input[type="checkbox"].erp-checkbox:disabled {
    cursor: not-allowed;
    opacity: .6;
}

/* Native radio used for RadioButton fields — one mutually-exclusive group per form */
.erp-field-input input[type="radio"].erp-radio {
    width: 18px;
    height: 18px;
    margin: 0;
    accent-color: var(--erp-primary);
    cursor: pointer;
    flex: 0 0 auto;
}
.erp-field-input input[type="radio"].erp-radio:disabled {
    cursor: not-allowed;
    opacity: .6;
}

/* DX checkbox — keep blue checkmark consistent */
.erp-field-input .dxbl-checkbox .dxbl-checkbox-icon {
    border-color: var(--erp-input-border) !important;
    border-radius: var(--erp-input-radius) !important;
}
.erp-field-input .dxbl-checkbox.dxbl-checked .dxbl-checkbox-icon {
    background: var(--erp-primary) !important;
    border-color: var(--erp-primary) !important;
}

/* Inline variant — checkbox sits left, label inline next to it */
.erp-field--inline {
    align-items: center;
}
.erp-field--inline .erp-field-label {
    flex: 0 0 auto;
    order: 2;
    padding-left: 6px;
    padding-right: 0;
    cursor: pointer;
}
.erp-field--inline .erp-field-input {
    flex: 0 0 auto;
    order: 1;
}

/* Memo / textarea field needs taller row */
.erp-field--memo { min-height: auto; align-items: flex-start; padding-top: 6px; padding-bottom: 6px; }
.erp-field--memo .erp-field-label { padding-top: 4px; }

/* ── Field-state backgrounds (mandatory / optional / disabled) ───────── */
/* Targets both plain HTML inputs and DevExpress wrappers so the tint is
   visible regardless of the underlying control. */
.erp-field--mandatory .erp-field-input .form-control,
.erp-field--mandatory .erp-field-input input[type="text"],
.erp-field--mandatory .erp-field-input input[type="number"],
.erp-field--mandatory .erp-field-input input[type="date"],
.erp-field--mandatory .erp-field-input textarea,
.erp-field--mandatory .erp-field-input select {
    background: var(--erp-input-bg-mandatory) !important;
}
.erp-field--mandatory .erp-field-input .dxbl-edit,
.erp-field--mandatory .erp-field-input .dxbl-textbox,
.erp-field--mandatory .erp-field-input .dxbl-combobox,
.erp-field--mandatory .erp-field-input .dxbl-spin-edit,
.erp-field--mandatory .erp-field-input .dxbl-date-edit,
.erp-field--mandatory .erp-field-input .dxbl-memo {
    background: var(--erp-input-bg-mandatory) !important;
}

.erp-field--optional .erp-field-input .form-control,
.erp-field--optional .erp-field-input input[type="text"],
.erp-field--optional .erp-field-input input[type="number"],
.erp-field--optional .erp-field-input input[type="date"],
.erp-field--optional .erp-field-input textarea,
.erp-field--optional .erp-field-input select {
    background: var(--erp-input-bg-optional) !important;
}
.erp-field--optional .erp-field-input .dxbl-edit,
.erp-field--optional .erp-field-input .dxbl-textbox,
.erp-field--optional .erp-field-input .dxbl-combobox,
.erp-field--optional .erp-field-input .dxbl-spin-edit,
.erp-field--optional .erp-field-input .dxbl-date-edit,
.erp-field--optional .erp-field-input .dxbl-memo {
    background: var(--erp-input-bg-optional) !important;
}

.erp-field--disabled .erp-field-input .form-control,
.erp-field--disabled .erp-field-input input,
.erp-field--disabled .erp-field-input textarea,
.erp-field--disabled .erp-field-input select {
    background: var(--erp-input-bg-disabled) !important;
}
.erp-field--disabled .erp-field-input .dxbl-edit,
.erp-field--disabled .erp-field-input .dxbl-textbox,
.erp-field--disabled .erp-field-input .dxbl-combobox,
.erp-field--disabled .erp-field-input .dxbl-spin-edit,
.erp-field--disabled .erp-field-input .dxbl-date-edit,
.erp-field--disabled .erp-field-input .dxbl-memo {
    background: var(--erp-input-bg-disabled) !important;
}

/* Restricted indicator below input */
.erp-field-help {
    font-size: 11px;
    color: var(--erp-text-muted);
    margin-top: 2px;
}

/* ─────────────────────────────────────────────────────────
   SWITCH — for boolean fields when "switch" style is wanted
   ───────────────────────────────────────────────────────── */
.erp-switch { position: relative; display: inline-block; width: 38px; height: 20px; flex-shrink: 0; }
.erp-switch input { display: none; }
.erp-switch-track {
    position: absolute; inset: 0;
    background: var(--erp-border-strong);
    border-radius: 10px;
    cursor: pointer;
    transition: background .15s;
}
.erp-switch-thumb {
    position: absolute;
    top: 2px; left: 2px;
    width: 16px; height: 16px;
    background: #fff;
    border-radius: 50%;
    box-shadow: var(--erp-shadow-sm);
    transition: left .15s, background .15s;
}
.erp-switch input:checked + .erp-switch-track { background: var(--erp-primary); }
.erp-switch input:checked + .erp-switch-track .erp-switch-thumb { left: 20px; }

/* ─────────────────────────────────────────────────────────
   GRID skin — soft, modern, no cell borders
   ───────────────────────────────────────────────────────── */
.erp-grid { border: 0 !important; font-size: var(--erp-fs-grid); }

/* HEADER ROW — covers ALL DxGrid v25 variations.
   DX renders the header in any of: <thead><th>, div.dxbl-grid-header,
   div[class*="grid-header-cell"], div.dxbl-grid-header-row, etc.
   We hit them all with broad selectors AND !important. */
.erp-grid thead tr:first-child th,
.erp-grid thead tr:first-child td,
.erp-grid .dxbl-grid-header-row,
.erp-grid .dxbl-grid-header-cell,
.erp-grid .dxbl-grid-header,
.erp-grid [class*="grid-header-row"],
.erp-grid [class*="grid-header-cell"] {
    background: var(--erp-surface-alt) !important;
    color: var(--erp-text-muted) !important;
    font-weight: 600 !important;
    font-size: 11.5px !important;
    letter-spacing: .4px !important;
    text-transform: uppercase !important;
    padding: 4px 10px !important;
    min-height: 28px !important;
    height: 28px !important;
    max-height: 28px !important;
    line-height: 1.2 !important;
    border: 0 !important;
    border-bottom: 1px solid var(--erp-border) !important;
    vertical-align: middle !important;
    box-sizing: border-box !important;
}

/* Force inner content blocks to NOT add extra height */
.erp-grid thead th *,
.erp-grid thead td *,
.erp-grid .dxbl-grid-header-cell *,
.erp-grid [class*="grid-header-cell"] * {
    color: var(--erp-text-muted) !important;
    white-space: nowrap !important;
    line-height: 1.2 !important;
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 0 !important;
    margin-bottom: 0 !important;
}

/* FILTER ROW — same broad approach */
.erp-grid thead tr:nth-child(2) th,
.erp-grid thead tr:nth-child(2) td,
.erp-grid .dxbl-grid-filter-row,
.erp-grid .dxbl-grid-filter-row-cell,
.erp-grid [class*="grid-filter-row"],
.erp-grid [class*="filter-row-cell"] {
    background: var(--erp-surface) !important;
    border-bottom: 1px solid var(--erp-border) !important;
    padding: 2px 6px !important;
    min-height: 28px !important;
    height: 28px !important;
    max-height: 28px !important;
    vertical-align: middle !important;
    box-sizing: border-box !important;
}
.erp-grid [class*="grid-filter-row"] * ,
.erp-grid [class*="filter-row-cell"] * {
    line-height: 1.2 !important;
}

/* Defeat any inline height DX may set on the inner cell-content wrappers
   (these wrappers are what often make the row taller than expected) */
.erp-grid [class*="grid-header-cell"] [class*="cell-content"],
.erp-grid [class*="grid-filter-row"] [class*="cell-content"],
.erp-grid thead [class*="cell-content"] {
    height: auto !important;
    min-height: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    line-height: 1.2 !important;
}

.erp-grid tbody tr td {
    padding: 6px 10px !important;
    border: 0 !important;
    font-size: var(--erp-fs-grid);
    vertical-align: middle !important;
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    max-width: 320px;
    height: 32px;
    color: var(--erp-text);
}
.erp-grid tbody tr td > *,
.erp-grid tbody tr td > * > * {
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
    max-width: 100%;
}

/* Subtle zebra only — no row borders */
.erp-grid tbody tr:nth-child(even) > td { background: var(--erp-surface-soft); }
.erp-grid tbody tr:hover > td {
    background: var(--erp-primary-tint) !important;
    cursor: pointer;
}
.erp-grid tbody tr.selected > td {
    background: var(--erp-primary-tint) !important;
    color: var(--erp-primary) !important;
    font-weight: 600;
    box-shadow: inset 3px 0 0 var(--erp-primary);
}

/* Filter row inputs */
.erp-filter-inp {
    width: 100%;
    border: 1px solid var(--erp-border-strong);
    border-radius: var(--erp-radius-sm);
    padding: 3px 6px;
    font-size: 12px;
    color: var(--erp-text);
    background: var(--erp-surface);
    font-family: inherit;
    outline: none;
    transition: border-color .15s, box-shadow .15s;
}
.erp-filter-inp:focus {
    border-color: var(--erp-primary);
    box-shadow: 0 0 0 2px rgba(37,99,235,.15);
}
.erp-filter-inp.has-value {
    border-color: var(--erp-primary);
    background: var(--erp-primary-tint);
}

/* ─────────────────────────────────────────────────────────
   PAGER
   ───────────────────────────────────────────────────────── */
.erp-pager {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    padding: 8px 14px;
    background: var(--erp-surface-alt);
    border-top: 1px solid var(--erp-border);
    font-size: 12.5px;
    flex-wrap: wrap;
}
.erp-pager-info,
.erp-pager-size { color: var(--erp-text-muted); white-space: nowrap; }
.erp-pager-nav { display: flex; align-items: center; gap: 4px; }
.erp-pg-btn {
    background: var(--erp-surface);
    border: 1px solid var(--erp-border);
    color: var(--erp-text);
    width: 30px; height: 28px;
    border-radius: var(--erp-radius-sm);
    cursor: pointer;
    font-weight: 600;
    transition: background .15s, color .15s, border-color .15s;
}
.erp-pg-btn:not(:disabled):hover {
    background: var(--erp-primary);
    border-color: var(--erp-primary);
    color: #fff;
}
.erp-pg-btn:disabled { opacity: .35; cursor: not-allowed; }
.erp-pg-num { padding: 0 8px; color: var(--erp-text); }
.erp-pg-num strong { color: var(--erp-primary); font-weight: 700; }
.erp-pg-select {
    border: 1px solid var(--erp-border);
    background: var(--erp-surface);
    color: var(--erp-text);
    border-radius: var(--erp-radius-sm);
    padding: 3px 8px;
    font-size: 12.5px;
    font-family: inherit;
}

/* ─────────────────────────────────────────────────────────
   STATE COMPONENTS — empty / loading / skeleton / alert
   ───────────────────────────────────────────────────────── */
.erp-empty {
    text-align: center;
    padding: 48px 20px;
    color: var(--erp-text-muted);
    font-size: 14px;
}
.erp-empty i {
    font-size: 36px;
    opacity: .35;
    margin-bottom: 12px;
    display: block;
}

.erp-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 30px;
    color: var(--erp-text-muted);
    font-size: 13px;
}
.erp-spinner {
    width: 18px; height: 18px;
    border-radius: 50%;
    border: 2px solid var(--erp-border);
    border-top-color: var(--erp-primary);
    animation: erp-spin .7s linear infinite;
    flex-shrink: 0;
}
@keyframes erp-spin { to { transform: rotate(360deg); } }

.erp-skeleton {
    background: linear-gradient(90deg,
        var(--erp-surface-alt) 0%,
        var(--erp-border) 50%,
        var(--erp-surface-alt) 100%);
    background-size: 200% 100%;
    animation: erp-skel 1.2s ease-in-out infinite;
    border-radius: var(--erp-radius-sm);
    height: 12px;
    display: block;
}
.erp-skeleton--line { height: 12px; margin: 4px 0; }
.erp-skeleton--block { height: 60px; }
.erp-skeleton--avatar { width: 36px; height: 36px; border-radius: 50%; }
@keyframes erp-skel { to { background-position: -200% 0; } }

.erp-alert {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    padding: 10px 14px;
    border-radius: var(--erp-radius);
    border-left: 3px solid;
    font-size: 13px;
    margin: 0 0 12px 0;
}
.erp-alert i { font-size: 16px; flex-shrink: 0; margin-top: 2px; }
.erp-alert--danger  { background: rgba(239,68,68,.08);  border-color: var(--erp-danger);  color: #b91c1c; }
.erp-alert--success { background: rgba(34,197,94,.08);  border-color: var(--erp-success); color: #15803d; }
.erp-alert--warning { background: rgba(245,158,11,.08); border-color: var(--erp-warning); color: #b45309; }
.erp-alert--info    { background: var(--erp-primary-tint); border-color: var(--erp-primary); color: var(--erp-primary-active); }
[data-bs-theme="dark"] .erp-alert--danger  { color: #fca5a5; }
[data-bs-theme="dark"] .erp-alert--success { color: #86efac; }
[data-bs-theme="dark"] .erp-alert--warning { color: #fde68a; }
[data-bs-theme="dark"] .erp-alert--info    { color: #93c5fd; }

/* ─────────────────────────────────────────────────────────
   CHILD GRID — inline editing toolbar + dirty dot
   ───────────────────────────────────────────────────────── */
.erp-cg-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--erp-gap);
    padding: 8px 14px;
    background: var(--erp-surface-alt);
    border-radius: var(--erp-radius) var(--erp-radius) 0 0;
}
.erp-cg-toolbar-left {
    display: flex; align-items: center; gap: 10px;
    flex: 1; min-width: 0;
    flex-wrap: wrap;
}
.erp-cg-toolbar-right { display: flex; align-items: center; gap: 8px; }
.erp-cg-count {
    font-size: 12px;
    font-weight: 600;
    color: var(--erp-text-muted);
    letter-spacing: .2px;
}
.erp-cg-confirm {
    font-size: 12px; font-weight: 600;
    color: var(--erp-danger, #ef4444);
    white-space: nowrap;
}

/* Dirty indicator dot (per-row in the action column) */
.erp-cg-rowactions {
    display: flex; align-items: center; gap: 4px;
    min-height: 24px;
}
.erp-cg-dot {
    width: 8px; height: 8px;
    border-radius: 50%;
    background: var(--erp-warning);
    box-shadow: 0 0 0 2px rgba(245,158,11,.18);
    flex-shrink: 0;
    margin-right: 4px;
}

/* Child grid — slightly different from drilldown (more compact, lighter header) */
.erp-grid--child thead tr:first-child th,
.erp-grid--child thead tr:first-child td {
    background: var(--erp-surface-alt, #f8fafc) !important;
    color: var(--erp-text) !important;
    text-transform: none !important;
    font-size: 12.5px !important;
    font-weight: 600 !important;
    letter-spacing: .1px !important;
    padding: 9px 10px !important;
    border-bottom: 1px solid var(--erp-border-strong, #d8e1ec) !important;
    white-space: nowrap;
}
.erp-grid--child thead tr:first-child th *,
.erp-grid--child thead tr:first-child td * {
    color: var(--erp-text) !important;
    font-weight: 600 !important;
}

/* Data cells — clean, consistent type and comfortable line-height. */
.erp-grid--child tbody tr td,
.erp-grid--child tbody tr td .erp-sheet-cell,
.erp-grid--child tbody tr td .erp-sheet-ro,
.erp-grid--child tbody tr td input,
.erp-grid--child tbody tr td .dxbl-text-edit input,
.erp-grid--child tbody tr td .dxbl-combobox {
    font-family: inherit;
    font-size: 13px;
    line-height: 1.45;
    color: var(--erp-text);
}
.erp-grid--child tbody tr:nth-child(even) > td {
    background: var(--erp-surface-soft, #fafbfd);
}
/* Soft full-row hover (no hard outline) — reads as a gentle highlight. */
.erp-grid--child tbody tr:hover > td {
    background: color-mix(in srgb, var(--erp-primary-tint) 55%, transparent) !important;
}

/* ── Decisive child-grid look ─────────────────────────────────────────
   app.css styles the DRILLDOWN grid via single-class `.dd-grid` rules
   (fixed 40px rows, hard hover accent, etc.). The child grid carries BOTH
   `.dd-grid` and `.erp-grid--child`, so these two-class selectors outrank
   app.css and guarantee the neat sheet look here regardless of load order. */
.dd-grid.erp-grid--child tbody tr td {
    height: auto !important;
    max-height: none !important;
    padding: 2px 8px !important;
    /* Soft gray gridlines (both directions) — visible but gentle. The token is
       light-gray in light mode and a muted gray in dark mode. */
    border-right: 1px solid var(--erp-border-strong) !important;
    border-bottom: 1px solid var(--erp-border-strong) !important;
    font-size: 11.5px !important;
    line-height: 1.35 !important;
    color: var(--erp-text) !important;
}
/* No double line where the cell border meets the rounded container edge. */
.dd-grid.erp-grid--child tbody tr td:last-child,
.dd-grid.erp-grid--child thead tr:first-child th:last-child,
.dd-grid.erp-grid--child thead tr:first-child td:last-child { border-right: 0 !important; }

.dd-grid.erp-grid--child thead tr:first-child th,
.dd-grid.erp-grid--child thead tr:first-child td {
    height: auto !important;
    padding: 6px 10px !important;
    border-right: 1px solid var(--erp-border-strong) !important;
    border-bottom: 1px solid var(--erp-border-strong) !important;
    background: var(--erp-surface-alt) !important;
    color: var(--erp-text) !important;
    font-size: 12.5px !important;
    font-weight: 600 !important;
    letter-spacing: .1px !important;
}
/* Gentle row hover — no inset left-accent bar (that's the drilldown look). */
.dd-grid.erp-grid--child tbody tr:hover > td {
    background: color-mix(in srgb, var(--erp-primary-tint) 55%, transparent) !important;
    box-shadow: none !important;
}
.dd-grid.erp-grid--child tbody tr:nth-child(even) > td {
    background: var(--erp-surface-soft, #fafbfd);
}

/* Inline edit cell — make the DX editors fit snugly */
.erp-grid--child .dxbl-grid-edit-cell input,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-edit,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-textbox,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-combobox,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-spin-edit,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-date-edit {
    border: 0 !important;
    background: var(--erp-primary-tint) !important;
    box-shadow: inset 0 0 0 2px var(--erp-primary);
    border-radius: var(--erp-input-radius) !important;
}

/* ── Neat, smooth rows ─────────────────────────────────────────────────
   Only soft HORIZONTAL separators between rows (no vertical gridlines, no
   crosshair) so the grid reads clean instead of busy/sharp. */
.erp-grid--child tbody tr td {
    border-right: 0 !important;
    border-bottom: 1px solid var(--erp-border) !important;
    padding: 5px 10px !important;
    vertical-align: middle;
}
.erp-grid--child thead tr:first-child th {
    border-right: 0 !important;
}
/* DevExpress virtual scrolling adds top/bottom spacer rows to reserve scroll
   height for off-screen rows. Our generic cell padding/border was giving these
   an empty ~row of height even when there's nothing to space (small grids),
   which showed as a blank row above and below the data. Strip their chrome so
   they collapse on small grids — but DO NOT force height:0 here: DevExpress
   sets these spacers' height INLINE to reserve scroll space for off-screen rows
   (e.g. height:48000px for a 2000-row grid). A `height:0 !important` overrides
   that inline height, collapsing the scroll track so the scrollbar jumps from
   the first page straight to the last and skips everything in between. With
   padding/border stripped, a spacer with no inline height already collapses to
   0 on small grids, while large virtualized grids keep their reserved height. */
.dd-grid.erp-grid--child tbody tr[dxbl-top-virtual-spacer-element] > td,
.dd-grid.erp-grid--child tbody tr[dxbl-bottom-virtual-spacer-element] > td,
.erp-grid--child tbody tr[dxbl-top-virtual-spacer-element] > td,
.erp-grid--child tbody tr[dxbl-bottom-virtual-spacer-element] > td {
    border: 0 !important;
    padding: 0 !important;
}
/* Empty grid (0 records) — don't reserve a tall blank area with gridlines. */
.erp-grid--child .dxbl-grid-empty-data-area {
    min-height: 0 !important;
    padding: 12px !important;
    border: 0 !important;
    color: var(--erp-text-soft);
    font-size: 12.5px;
}
/* The cell currently in edit mode reads as the active spreadsheet cell */
.erp-grid--child .dxbl-grid-edit-cell {
    padding: 1px !important;
    background: var(--erp-surface) !important;
}
/* Newly-added (unsaved) rows get a faint highlight, like a fresh Excel row */
.erp-grid--child tbody tr:has(.erp-cg-dot) > td {
    background: rgba(245, 158, 11, .06) !important;
}

/* ── Always-editable spreadsheet cells ────────────────────────────────
   Every data cell hosts a live editor. Keep them flat (borderless, no fill)
   so the grid looks like a sheet, and only reveal the editor chrome on focus. */
/* Bounded height so DevExpress virtual scrolling has a viewport (only on-screen
   rows render) AND the header stays frozen while the data area scrolls. The
   height comes from the grid field's configured size (--cg-h, set by ChildGrid);
   small/unsized grids fall back to 62vh. NOTE: the host wrapper must NOT add its
   own overflow — that would scroll the header too. The grid scrolls internally. */
/* Smooth, rounded outer edge around the whole sheet so the gridlines sit inside
   a soft frame rather than running to hard corners. */
.erp-cg-scroll {
    width: 100%;
    border: 1px solid var(--erp-border-strong);
    border-radius: 8px;
    overflow: hidden;
}
/* Large grids are paged (.erp-grid--sheet without .erp-grid--grow): the page
   scrolls natively inside this bounded height; a short last page just ends early. */
.erp-grid--sheet { max-height: var(--cg-h, 62vh); }
/* Small (non-paged) child grids grow to fit their rows — no inner scrollbar;
   the form/page scrolls instead. (Two classes → wins over .erp-grid--sheet.) */
.erp-grid--sheet.erp-grid--grow { max-height: none; }
/* Drag handle under the grid to resize its height (sets --cg-h on the wrapper). */
.erp-cg-resize {
    display: flex; align-items: center; justify-content: center;
    height: 14px; margin-top: 2px;
    cursor: ns-resize; color: var(--erp-text-soft);
    border-radius: 6px; user-select: none;
}
.erp-cg-resize:hover { background: var(--erp-surface-2, rgba(0,0,0,.04)); color: var(--erp-text); }
.erp-cg-resize i { font-size: 11px; pointer-events: none; }

/* ════════════════════════════════════════════════════════════════════
   DESIGN MODE — drag fields to reorder (developer field-layout editing)
   ════════════════════════════════════════════════════════════════════ */
.erp-design-hint {
    display: flex; align-items: center; gap: 8px;
    margin: 10px 12px; padding: 8px 12px;
    background: var(--erp-warning-tint, #fef3c7);
    border: 1px dashed var(--erp-warning, #f59e0b);
    border-radius: var(--erp-radius, 8px);
    font-size: 12.5px; color: var(--erp-text);
}
.erp-design-list {
    list-style: none; margin: 0; padding: 8px 12px 14px;
    display: flex; flex-direction: column; gap: 6px;
}
/* Design tab bar — draggable chips with a rename pencil. */
.erp-design-tabs {
    display: flex; flex-wrap: wrap; gap: 8px;
    margin-bottom: 12px; padding: 8px;
    border: 1px dashed var(--erp-warning, #f59e0b);
    border-radius: var(--erp-radius, 8px);
    background: var(--erp-warning-tint, #fef3c7);
}
.erp-design-tab-chip {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 5px 10px; cursor: grab; user-select: none;
    background: var(--erp-surface);
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    border-radius: var(--erp-radius-pill, 999px);
    font-size: 12.5px; font-weight: 600; color: var(--erp-text);
}
.erp-design-tab-chip.active { border-color: var(--erp-primary); color: var(--erp-primary); box-shadow: 0 0 0 2px var(--erp-primary-tint); }
.erp-design-tab-chip > i.fa-grip-vertical { color: var(--erp-text-soft); font-size: 11px; }
.erp-design-tab-edit {
    border: 0; background: transparent; cursor: pointer;
    color: var(--erp-text-soft); padding: 2px 4px; font-size: 11px;
}
.erp-design-tab-edit:hover { color: var(--erp-primary); }
.erp-design-item {
    display: flex; align-items: center; gap: 10px;
    padding: 8px 12px;
    background: var(--erp-surface);
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    border-radius: var(--erp-radius, 8px);
    cursor: grab; user-select: none;
    transition: box-shadow .12s, border-color .12s, background .12s;
}
.erp-design-item:hover {
    border-color: var(--erp-primary);
    box-shadow: 0 1px 6px rgba(37,99,235,.12);
}
.erp-design-item.is-dragging { opacity: .45; cursor: grabbing; }
.erp-design-grip    { color: var(--erp-text-soft); font-size: 13px; }
.erp-design-caption { font-size: 13.5px; font-weight: 600; color: var(--erp-text); flex: 1; min-width: 0; }
.erp-design-meta    { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.erp-design-badge {
    font-size: 10.5px; font-weight: 600; text-transform: lowercase;
    padding: 2px 8px; border-radius: var(--erp-radius-pill, 999px);
    background: var(--erp-primary-tint); color: var(--erp-primary);
}
.erp-design-field   { font-size: 11px; color: var(--erp-text-soft); }
/* Inline caption editor (EN + AR) */
.erp-design-capedit { display: flex; align-items: center; gap: 6px; flex: 1; min-width: 0; }
.erp-design-capinput {
    flex: 1; min-width: 80px;
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    border-radius: 6px; padding: 4px 8px;
    font: inherit; font-size: 13px; color: var(--erp-text);
    background: var(--erp-surface);
}
.erp-design-capinput:focus { outline: none; border-color: var(--erp-primary); box-shadow: 0 0 0 2px var(--erp-primary-tint); }
/* Move-to-tab dropdown */
.erp-design-tab {
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    background: var(--erp-surface-alt); color: var(--erp-text);
    border-radius: 6px; padding: 3px 6px;
    font: inherit; font-size: 11.5px; max-width: 120px; cursor: pointer;
}
.erp-design-tab:hover { border-color: var(--erp-primary); }
.erp-design-width {
    display: inline-flex; align-items: center; gap: 5px;
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    background: var(--erp-surface-alt);
    color: var(--erp-text); cursor: pointer;
    font-size: 11px; font-weight: 600;
    padding: 3px 8px; border-radius: var(--erp-radius-pill, 999px);
}
.erp-design-width:hover { border-color: var(--erp-primary); color: var(--erp-primary); }
.erp-design-btn {
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    background: var(--erp-surface-alt);
    color: var(--erp-text-soft); cursor: pointer;
    width: 28px; height: 26px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    font-size: 12px;
}
.erp-design-btn:hover { border-color: var(--erp-primary); color: var(--erp-primary); }
/* Checkbox list used by the copy-field-to-databases dialog. */
.erp-design-dblist {
    max-height: 240px; overflow-y: auto;
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    border-radius: 8px; padding: 6px;
}
.erp-check {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 8px; border-radius: 6px; cursor: pointer;
    font-size: 13px; color: var(--erp-text-soft);
}
.erp-check:hover { background: var(--erp-surface-alt); }
.erp-check input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; }
.erp-check--all { border-bottom: 1px solid var(--erp-border, #e6edf5); margin-bottom: 4px; }

/* Permission-grants preview (Copy permissions modal) */
.erp-perm-preview {
    max-height: 200px; overflow-y: auto;
    border: 1px solid var(--erp-border-strong, #d8e1ec);
    border-radius: 8px;
}
.erp-perm-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.erp-perm-table thead th {
    position: sticky; top: 0; z-index: 1;
    background: var(--erp-surface-alt, #f3f7fb);
    color: var(--erp-text-soft); font-weight: 600;
    text-align: center; padding: 6px 8px; white-space: nowrap;
    border-bottom: 1px solid var(--erp-border, #e6edf5);
}
.erp-perm-table tbody td {
    text-align: center; padding: 5px 8px;
    border-bottom: 1px solid var(--erp-border, #e6edf5);
}
.erp-perm-table tbody tr:last-child td { border-bottom: 0; }
.erp-perm-table .erp-perm-user { text-align: start; font-weight: 500; color: var(--erp-text); white-space: nowrap; }
.erp-perm-table .erp-perm-group { text-align: start; color: var(--erp-text-soft); white-space: nowrap; }
.erp-perm-table input[type="checkbox"] { width: 15px; height: 15px; cursor: pointer; }
.erp-perm-row--busy { opacity: .5; pointer-events: none; }
.erp-tb-btn--xs { padding: 2px 6px; font-size: 11px; line-height: 1; }
.erp-perm-yes { color: var(--erp-success, #1f9d57); }
.erp-perm-no  { color: var(--erp-text-muted, #9aa7b6); }

/* Active toggle (e.g. required is ON) — highlighted so the state is obvious. */
.erp-design-btn.is-on {
    border-color: var(--erp-danger, #ef4444);
    color: var(--erp-danger, #ef4444);
    background: rgba(239, 68, 68, .08);
}
/* Summary toggle ON — purple accent so it's distinct from "required". */
.erp-design-btn.is-summary {
    border-color: #8b5cf6;
    color: #8b5cf6;
    background: rgba(139, 92, 246, .1);
}
/* Hidden field — dimmed row + strike on the caption so it reads as "off". */
.erp-design-item.is-hidden { opacity: .55; background: var(--erp-surface-alt); }
.erp-design-item.is-hidden .erp-design-caption { text-decoration: line-through; }
/* Disabled field — small lock tint on the caption. */
.erp-design-item.is-disabled .erp-design-caption { color: var(--erp-text-muted); font-style: italic; }

/* Field-metadata editor modal (design mode → sliders button) */
.dc-label { font-size: 12px; font-weight: 600; color: var(--erp-text-soft, #64748b); }
.fmd-flags { display: flex; flex-wrap: wrap; gap: 14px; padding: 6px 0; font-size: 13px; }
.fmd-flags label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.fmd-section { border-top: 1px solid var(--bs-border-color); padding-top: 10px; margin-top: 12px;
    font-size: 12px; font-weight: 600; color: var(--erp-text-soft, #64748b);
    display: flex; align-items: center; gap: 6px; }
.fmd-details { margin-top: 10px; }
.fmd-details > summary { cursor: pointer; font-size: 13px; font-weight: 600;
    color: var(--erp-text-soft, #64748b); padding: 4px 0;
    list-style: none; display: flex; align-items: center; gap: 6px; }
.fmd-details > summary::before { content: "▸"; font-size: 10px; }
.fmd-details[open] > summary::before { content: "▾"; }
.fmd-details > summary .df-sec-on { font-size: 11px; font-weight: 700;
    background: #fef3c7; color: #92400e; border-radius: 4px; padding: 1px 5px; }

/* Freeze the header row: it stays put while only the data rows scroll. */
.erp-grid--sheet .dxbl-grid-header-content,
.erp-grid--sheet thead {
    position: sticky;
    top: 0;
    z-index: 4;
}
.erp-grid--sheet thead tr:first-child th {
    position: sticky;
    top: 0;
    z-index: 4;
}

.erp-grid--sheet tbody tr td { padding: 2px 8px !important; cursor: default; }
/* Virtual scrolling estimates ONE average row height from the first rendered
   rows and caches it. Our sheet cells host async editors (combo lookups, text
   editors) that aren't laid out yet at first measure, so the rows measured
   near-collapsed and the cached average came out far too small — then a tiny
   scroll converted into a huge row jump (e.g. 45 → 1950, skipping everything
   between). Pin a uniform height on DATA rows so the measurement is stable and
   correct regardless of editor render timing. Spacer rows are excluded:
   DevExpress sizes those itself to reserve off-screen scroll space. */
.erp-grid--sheet tbody tr:not([dxbl-top-virtual-spacer-element]):not([dxbl-bottom-virtual-spacer-element]) > td {
    height: 34px;
    box-sizing: border-box;
}
.erp-sheet-cell { width: 100% !important; }
.erp-combo-wrap { display: block; width: 100%; }
/* Inline hint shown under a field (e.g. why a lookup came back empty) */
.erp-field-hint { font-size: 11px; margin-top: 3px; line-height: 1.3; display: flex; align-items: flex-start; gap: 5px; }
.erp-field-hint--warn { color: var(--erp-warning, #f59e0b); word-break: break-word; }
.erp-sheet-ro   { color: var(--erp-text-muted); padding: 0 4px; }
.erp-sheet-cellwrap { width: 100%; }
/* Empty required cell flagged on Save */
.erp-sheet-invalid {
    outline: 2px solid var(--erp-danger, #ef4444);
    outline-offset: -1px;
    border-radius: 5px;
    background: rgba(239, 68, 68, .07);
}

/* Plain text & number cells stay flat until hover/focus (clean sheet look). */
.erp-grid--sheet .dxbl-text-edit,
.erp-grid--sheet .dxbl-spin-edit {
    border: 1px solid transparent !important;
    background: transparent !important;
    box-shadow: none !important;
    border-radius: 4px !important;
}
.erp-grid--sheet .dxbl-text-edit:hover,
.erp-grid--sheet .dxbl-spin-edit:hover {
    border-color: var(--erp-border) !important;
    background: var(--erp-surface) !important;
}
/* Lookups (combo/TextLink/Ledger) show a soft chrome so the dropdown button is
   visible without looking heavy. */
.erp-grid--sheet .dxbl-combobox {
    border: 1px solid transparent !important;
    background: transparent !important;
    border-radius: 4px !important;
}
.erp-grid--sheet .dxbl-combobox:hover {
    border-color: var(--erp-border) !important;
    background: var(--erp-surface) !important;
}
/* Combo editor buttons (clear ✕ + dropdown ⌄). In the Fluent theme these are
   .dxbl-edit-btn-clear / .dxbl-edit-btn-dropdown. Keep them out of the way: hidden
   until the row/cell is hovered or the combo is focused, so the sheet reads clean.
   The combo still opens by clicking the cell, so hiding the chevron is harmless. */
.erp-grid--sheet .dxbl-combobox :is(.dxbl-edit-btn-clear, .dxbl-edit-btn-dropdown) {
    opacity: 0;
    pointer-events: none;
    transition: opacity .12s ease;
}
.erp-grid--child tbody tr:hover .dxbl-combobox :is(.dxbl-edit-btn-clear, .dxbl-edit-btn-dropdown),
.erp-grid--sheet .dxbl-combobox:hover :is(.dxbl-edit-btn-clear, .dxbl-edit-btn-dropdown),
.erp-grid--sheet .dxbl-combobox:focus-within :is(.dxbl-edit-btn-clear, .dxbl-edit-btn-dropdown) {
    opacity: .85;
    pointer-events: auto;
}

/* ── Edit-mode polish ─────────────────────────────────────────────────
   Make the live editors look as clean as the read-only view. */
/* app.css normalises every cell child to inline-block + overflow:hidden +
   ellipsis (right for the read-only drilldown, wrong for editors — it squashes
   and clips them). Undo it for the editor wrappers so inputs fill the cell. */
.dd-grid.erp-grid--child tbody tr td > .erp-sheet-cellwrap,
.dd-grid.erp-grid--child tbody tr td > .erp-combo-wrap {
    display: block !important;
    width: 100% !important;
    max-width: none !important;
    overflow: visible !important;
    white-space: normal !important;
    vertical-align: middle;
}
.dd-grid.erp-grid--child tbody tr td .erp-sheet-cellwrap > * {
    max-width: none !important;
    overflow: visible !important;
}
/* Compact editors (SizeMode.Small handles most of it; trim the residual Fluent
   padding so rows stay short and the text aligns with the read-only view). */
.erp-grid--sheet .dxbl-text-edit,
.erp-grid--sheet .dxbl-spin-edit,
.erp-grid--sheet .dxbl-combobox {
    --dxbl-text-edit-padding-top: 1px !important;
    --dxbl-text-edit-padding-bottom: 1px !important;
    min-height: 26px !important;
}
.erp-grid--sheet .dxbl-text-edit input,
.erp-grid--sheet .dxbl-spin-edit input,
.erp-grid--sheet .dxbl-combobox input {
    font-size: 13px !important;
    color: var(--erp-text) !important;
    background: transparent !important;
}
/* One clean focus ring, identical across editor types. */
.erp-grid--sheet .dxbl-text-edit:focus-within,
.erp-grid--sheet .dxbl-spin-edit:focus-within,
.erp-grid--sheet .dxbl-combobox:focus-within {
    border-color: var(--erp-primary) !important;
    background: var(--erp-surface) !important;
    box-shadow: 0 0 0 2px var(--erp-primary-tint) !important;
}
/* Neutralise the legacy heavy-blue inline edit-cell tint/shadow. */
.erp-grid--child .dxbl-grid-edit-cell,
.erp-grid--child .dxbl-grid-edit-cell input,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-textbox,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-combobox,
.erp-grid--child .dxbl-grid-edit-cell .dxbl-spin-edit {
    background: transparent !important;
    box-shadow: none !important;
}

/* Date cell — editable text field (type a date) with a calendar icon that opens
   the controlled DxCalendar popover (see .erp-datepop). Flat until hover/focus so
   it reads like the rest of the sheet. */
.erp-sheet-datewrap {
    display: flex; align-items: center; gap: 2px;
    width: 100%;
    border: 1px solid transparent;
    border-radius: 4px;
}
.erp-sheet-datewrap:hover        { border-color: var(--erp-border); background: var(--erp-surface); }
.erp-sheet-datewrap:focus-within { border-color: var(--erp-primary); background: var(--erp-surface); box-shadow: 0 0 0 2px var(--erp-primary-tint); }
.erp-sheet-dateinput {
    flex: 1; min-width: 0;
    border: 0; background: transparent; outline: none;
    font: inherit; font-size: 13px; color: var(--erp-text);
    padding: 3px 4px 3px 6px;
}
.erp-sheet-dateinput::placeholder { color: var(--erp-text-soft); }
.erp-sheet-dateico {
    flex-shrink: 0;
    border: 0; background: transparent; cursor: pointer;
    color: var(--erp-primary);
    padding: 3px 6px; font-size: 12px;
    border-radius: 0 4px 4px 0;
}
.erp-sheet-dateico:hover { background: var(--erp-primary-tint); }

/* Form date field (DynamicField) — editable text + calendar icon that opens the
   DxCalendar popover. Styled to match the other form inputs (full width). */
.erp-date-field {
    display: flex; align-items: center; width: 100%;
    border: 1px solid var(--erp-input-border, var(--erp-border-strong));
    border-radius: var(--erp-input-radius, 6px);
    background: var(--erp-input-bg, #fff);
}
.erp-date-field:focus-within {
    border-color: var(--erp-primary);
    box-shadow: 0 0 0 2px var(--erp-primary-tint);
}
.erp-date-input {
    flex: 1; min-width: 0;
    border: 0; background: transparent; outline: none;
    font: inherit; color: var(--erp-text);
    padding: 6px 10px;
}
.erp-date-input::placeholder { color: var(--erp-text-soft); }
.erp-date-ico {
    flex-shrink: 0; border: 0; background: transparent; cursor: pointer;
    color: var(--erp-primary); padding: 6px 10px; border-radius: 0 6px 6px 0;
}
.erp-date-ico:hover { background: var(--erp-primary-tint); }

/* Date-picker popover (controlled DxCalendar) — fixed at root so it is never
   clipped by the grid's scroll viewer and always sits above the form/modal. */
.erp-datepop-backdrop {
    position: fixed; inset: 0; z-index: 11000;
    background: rgba(15, 23, 42, .28);
}
.erp-datepop {
    position: fixed; z-index: 11001;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    background: var(--erp-surface);
    border: 1px solid var(--erp-border);
    border-radius: var(--erp-radius-lg, 12px);
    box-shadow: var(--erp-shadow-xl, 0 20px 50px rgba(0,0,0,.25));
    width: min(340px, 94vw);
    display: flex; flex-direction: column; overflow: hidden;
}
.erp-datepop-head {
    display: flex; align-items: center; gap: 4px;
    padding: 11px 14px; border-bottom: 1px solid var(--erp-border);
    font-size: 14px; font-weight: 600; color: var(--erp-text);
}
.erp-datepop-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 10px; }
.erp-datepop-body .dxbl-calendar { width: 100%; }
.erp-datepop-time { display: flex; align-items: center; gap: 10px; }
.erp-datepop-time label { font-size: 13px; color: var(--erp-label); margin: 0; }
.erp-datepop-timeinput {
    flex: 1; font: inherit; font-size: 13px;
    border: 1px solid var(--erp-border); border-radius: var(--erp-input-radius, 6px);
    padding: 5px 8px; color: var(--erp-text); background: var(--erp-input-bg, #fff);
}
.erp-datepop-foot {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 14px; border-top: 1px solid var(--erp-border);
    background: var(--erp-surface-alt);
}

/* ── Formula / textexpression editors (DynamicField) ───────────────── */
.erp-fx { display: flex; flex-direction: column; gap: 6px; width: 100%; }

/* textexpression: input + icon button on one row */
.erp-fx--inline { flex-direction: row; align-items: center; gap: 6px; }
.erp-fx--inline .erp-input { flex: 1; min-width: 0; }

/* formula: multi-line textarea with the icon buttons stacked beside it */
.erp-fx-row { display: flex; align-items: flex-start; gap: 6px; width: 100%; }
.erp-fx-row .erp-fx-area { flex: 1; min-width: 0; }
.erp-fx-side { display: flex; flex-direction: column; gap: 4px; flex: 0 0 auto; }

/* Force a genuine multi-line box (beats textarea.erp-input's min-height). */
textarea.erp-fx-area {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 13px; line-height: 1.5; resize: vertical;
    height: auto; min-height: 88px;
}

/* Square-ish icon button so it lines up with the input height. */
.erp-fx-btn { flex: 0 0 auto; }

.erp-fx-msg {
    display: flex; align-items: flex-start; gap: 6px;
    font-size: 12.5px; padding: 6px 9px; border-radius: var(--erp-input-radius, 6px);
    word-break: break-word;
}
.erp-fx-msg.is-ok  { background: var(--erp-success-tint, #e8f6ed); color: var(--erp-success, #1a7f3c); }
.erp-fx-msg.is-err { background: var(--erp-danger-tint, #fdecec);  color: var(--erp-danger, #c0392b); }

/* Field-picker popup (shares the datepop backdrop) */
.erp-fx-pop {
    position: fixed; z-index: 12001;
    top: 50%; left: 50%; transform: translate(-50%, -50%);
    background: var(--erp-surface);
    border: 1px solid var(--erp-border);
    border-radius: var(--erp-radius-lg, 12px);
    box-shadow: var(--erp-shadow-xl, 0 20px 50px rgba(0,0,0,.25));
    width: min(420px, 94vw);
    display: flex; flex-direction: column; overflow: hidden;
}
.erp-fx-pop-body { padding: 12px 14px; display: flex; flex-direction: column; min-height: 0; }
.erp-fx-list {
    display: flex; flex-direction: column; gap: 3px;
    max-height: min(50vh, 380px); overflow-y: auto;
}
.erp-fx-chip {
    display: flex; flex-direction: column; gap: 1px;
    text-align: start; width: 100%;
    padding: 6px 9px; border: 1px solid transparent; border-radius: 7px;
    background: transparent; cursor: pointer; color: var(--erp-text);
}
.erp-fx-chip:hover { background: var(--erp-primary-tint); border-color: var(--erp-primary); }
.erp-fx-chip-name { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 13px; font-weight: 600; }
.erp-fx-chip-cap  { font-size: 11.5px; color: var(--erp-muted, #6b7280); }
.erp-grid--sheet .dxbl-text-edit:focus-within,
.erp-grid--sheet .dxbl-combobox:focus-within,
.erp-grid--sheet .dxbl-spin-edit:focus-within,
.erp-grid--sheet .dxbl-date-edit:focus-within {
    border-color: var(--erp-primary) !important;
    background: var(--erp-surface) !important;
    box-shadow: 0 0 0 2px var(--erp-primary-tint) !important;
}

/* ════════════════════════════════════════════════════════════════════
   ZP-DRAWER — floating side panel (Approvals / Discussions / Documents)
   Port of legacy ZoomERP.Panels.js, token-driven.
   ════════════════════════════════════════════════════════════════════ */

/* Toggle button — fixed at right edge, vertically centred */
.zp-toggle-btn {
    position: fixed;
    right: 18px; top: 50%;
    transform: translateY(-50%);
    width: 48px; height: 48px;
    border-radius: 50%;
    background: var(--erp-gradient-primary);
    color: #fff;
    border: none;
    box-shadow: 0 6px 18px rgba(37,99,235,.35);
    cursor: grab;            /* draggable (zpFloat) — click still toggles */
    touch-action: none;      /* let pointer-drag work on touch without scrolling */
    z-index: 4990;
    display: flex; align-items: center; justify-content: center;
    font-size: 18px;
    transition: transform .15s, box-shadow .15s;
}
.zp-toggle-btn:hover { transform: translateY(calc(-50% - 1px)); box-shadow: 0 10px 24px rgba(37,99,235,.45); }
.zp-toggle-badge {
    position: absolute;
    top: -2px; right: -2px;
    background: var(--erp-danger);
    color: #fff;
    font-size: 10px;
    font-weight: 700;
    min-width: 18px; height: 18px;
    border-radius: 9px;
    padding: 0 5px;
    display: inline-flex; align-items: center; justify-content: center;
    border: 2px solid var(--erp-surface);
    line-height: 1;
}

/* Backdrop — softens the page when drawer is open */
.zp-drawer-backdrop {
    position: fixed; inset: 0;
    background: rgba(15,23,42,.35);
    backdrop-filter: blur(2px);
    z-index: 4998;
    animation: zp-fade .2s ease;
}
@keyframes zp-fade { from { opacity: 0; } to { opacity: 1; } }

/* Drawer panel */
.zp-drawer {
    position: fixed;
    right: 0; top: 0;
    width: 380px; height: 100vh;
    background: var(--erp-surface);
    box-shadow: -8px 0 32px rgba(15,23,42,.18);
    z-index: 5000;
    display: flex; flex-direction: column;
    transform: translateX(105%);
    transition: transform .3s cubic-bezier(.4,0,.2,1);
}
.zp-drawer.open { transform: translateX(0); }

/* Tabs bar */
.zp-tabs {
    display: flex; align-items: stretch;
    background: var(--erp-primary-band);
    flex-shrink: 0;
}
.zp-tab {
    flex: 1;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: 4px;
    padding: 12px 4px 10px;
    background: transparent; border: 0;
    color: rgba(255,255,255,.65);
    cursor: pointer;
    font-size: 10.5px;
    font-family: inherit;
    transition: background .15s, color .15s;
    position: relative;
    line-height: 1;
}
.zp-tab i { font-size: 16px; }
.zp-tab:hover { color: #fff; }
.zp-tab.active {
    color: #fff;
    background: rgba(255,255,255,.10);
}
.zp-tab.active::after {
    content: '';
    position: absolute;
    bottom: 0; left: 0; right: 0;
    height: 3px;
    background: #fff;
    border-radius: 2px 2px 0 0;
}
.zp-tab-badge {
    position: absolute;
    top: 6px; right: 10px;
    background: var(--erp-danger);
    color: #fff;
    font-size: 9px; font-weight: 700;
    font-style: normal;
    min-width: 16px; height: 16px;
    border-radius: 8px;
    padding: 0 3px;
    display: inline-flex; align-items: center; justify-content: center;
    line-height: 1;
}

.zp-drawer-close {
    background: transparent; border: 0;
    color: rgba(255,255,255,.7);
    padding: 0 14px;
    cursor: pointer;
    font-size: 16px;
    flex-shrink: 0;
}
.zp-drawer-close:hover { color: #fff; }

/* Pane (only the active one shows) */
.zp-pane { display: none; flex: 1; flex-direction: column; overflow: hidden; min-height: 0; }
.zp-pane.active { display: flex; }
.zp-pane-body { flex: 1; overflow-y: auto; padding: 16px 14px; }

/* Empty state */
.zp-empty {
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    height: 160px;
    color: var(--erp-text-soft);
    gap: 10px; font-size: 13px;
    text-align: center;
    padding: 0 20px;
}
.zp-empty i { font-size: 32px; opacity: .35; }

/* ── Approvals timeline ──────────────────────────────────────── */
.zp-timeline { list-style: none; padding: 0; margin: 0; }
.zp-tl-item {
    display: flex; gap: 12px;
    padding-bottom: 18px;
    position: relative;
}
.zp-tl-item:not(:last-child)::before {
    content: '';
    position: absolute;
    left: 18px; top: 40px;
    width: 2px; height: calc(100% - 20px);
    background: var(--erp-border);
}
.zp-tl-avatar-img {
    width: 38px; height: 38px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--erp-surface-alt);
    border: 1.5px solid var(--erp-border);
}
.zp-tl-content { flex: 1; min-width: 0; }
.zp-tl-name { font-weight: 600; font-size: 13px; color: var(--erp-text); }
.zp-tl-date { font-size: 11px; color: var(--erp-text-soft); margin-top: 3px; }
.zp-tl-comment {
    font-size: 12px;
    color: var(--erp-text);
    margin-top: 6px;
    background: var(--erp-surface-alt);
    border-left: 3px solid var(--erp-border-strong);
    padding: 6px 10px;
    border-radius: 0 6px 6px 0;
}
.zp-tl-status {
    font-size: 10px; font-weight: 600;
    padding: 2px 8px;
    border-radius: 999px;
    white-space: nowrap;
    text-transform: capitalize;
}
.zp-tl-status.approved { background: rgba(34,197,94,.15);  color: #15803d; }
.zp-tl-status.waiting  { background: rgba(245,158,11,.15); color: #b45309; }
.zp-tl-status.rejected { background: rgba(239,68,68,.15);  color: #b91c1c; }

/* ── Discussions chat bubbles ───────────────────────────────── */
.zp-chat-list { display: flex; flex-direction: column; gap: 14px; }
.zp-msg { display: flex; gap: 8px; align-items: flex-end; }
.zp-msg.sent { flex-direction: row-reverse; }
.zp-msg-avatar {
    width: 32px; height: 32px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--erp-surface-alt);
    border: 1px solid var(--erp-border);
}
.zp-bubble {
    max-width: 78%;
    background: var(--erp-surface-alt);
    border-radius: 14px 14px 14px 4px;
    padding: 8px 12px;
    font-size: 13px;
    color: var(--erp-text);
    word-break: break-word;
    box-shadow: var(--erp-shadow-sm);
}
.zp-msg.sent .zp-bubble {
    background: var(--erp-primary);
    color: #fff;
    border-radius: 14px 14px 4px 14px;
}
.zp-bubble-name {
    font-size: 10.5px;
    font-weight: 600;
    color: var(--erp-text-muted);
    margin-bottom: 3px;
}
.zp-bubble-text { white-space: pre-wrap; }
.zp-bubble-time {
    font-size: 10px;
    color: var(--erp-text-soft);
    margin-top: 4px;
}
.zp-msg.sent .zp-bubble-time { color: rgba(255,255,255,.75); text-align: right; }

/* Composer */
.zp-composer {
    display: flex; gap: 10px;
    padding: 10px 12px;
    border-top: 1px solid var(--erp-border);
    background: var(--erp-surface);
    flex-shrink: 0;
    align-items: flex-end;
}
.zp-composer textarea {
    flex: 1;
    border: 1px solid var(--erp-border-strong);
    border-radius: 18px;
    padding: 8px 14px;
    font-size: 13px;
    resize: none;
    outline: none;
    background: var(--erp-surface-alt);
    font-family: inherit;
    max-height: 96px;
    transition: border-color .15s, background .15s;
}
.zp-composer textarea:focus {
    border-color: var(--erp-primary);
    background: var(--erp-surface);
}
.zp-composer button {
    width: 38px; height: 38px;
    border-radius: 50%;
    background: var(--erp-primary);
    color: #fff;
    border: none;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    font-size: 14px;
    transition: background .15s, transform .12s;
}
.zp-composer button:hover:not(:disabled) {
    background: var(--erp-primary-hover);
    transform: translateY(-1px);
}
.zp-composer button:disabled { opacity: .4; cursor: not-allowed; }

/* Pane body p-0 helper (Documents tab uses AttachmentsPanel's own padding) */
.zp-pane-body.p-0 { padding: 0 !important; }

/* ════════════════════════════════════════════════════════════════════
   ATTACHMENT ICON CARDS (legacy ZoomERP.Panels.js parity)
   2-col grid of clickable cards: image preview OR colored file icon
   + filename + extension.
   ════════════════════════════════════════════════════════════════════ */
.erp-attach-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
}
@media (min-width: 1024px) {
    .erp-attach-grid { grid-template-columns: repeat(3, 1fr); }
}

.erp-attach-card {
    position: relative;
    background: var(--erp-surface);
    border-radius: var(--erp-radius);
    box-shadow: var(--erp-shadow-sm);
    overflow: hidden;
    transition: transform .12s, box-shadow .15s;
}
.erp-attach-card:hover {
    transform: translateY(-2px);
    box-shadow: var(--erp-shadow-md);
}

.erp-attach-card-link {
    display: block;
    color: inherit;
    text-decoration: none;
}
.erp-attach-card-link:hover { color: inherit; text-decoration: none; }

.erp-attach-thumb {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    display: block;
    background: var(--erp-surface-alt);
}
.erp-attach-thumb-icon {
    width: 100%;
    aspect-ratio: 4 / 3;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: 36px;
    background: var(--erp-surface-alt);
}

.erp-attach-label {
    padding: 7px 10px 9px;
}
.erp-attach-name {
    font-size: 12px;
    font-weight: 500;
    color: var(--erp-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    line-height: 1.3;
}
.erp-attach-ext {
    font-size: 10.5px;
    color: var(--erp-text-soft);
    margin-top: 2px;
    text-transform: uppercase;
    letter-spacing: .3px;
}
.erp-attach-size {
    text-transform: none;
    letter-spacing: 0;
    margin-left: 2px;
}

/* Hover-only actions overlay (download / delete) */
.erp-attach-actions {
    position: absolute;
    top: 6px; right: 6px;
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity .15s;
    background: rgba(255,255,255,.85);
    backdrop-filter: blur(4px);
    border-radius: var(--erp-radius-sm);
    padding: 2px;
}
.erp-attach-card:hover .erp-attach-actions { opacity: 1; }
[data-bs-theme="dark"] .erp-attach-actions { background: rgba(15,23,42,.85); }

/* Mobile bottom sheet */
@media (max-width: 768px) {
    .zp-drawer {
        width: 100%;
        height: 85vh;
        max-height: 85vh;
        top: auto; bottom: 0; right: 0;
        transform: translateY(110%);
        border-radius: 18px 18px 0 0;
    }
    .zp-drawer.open { transform: translateY(0); }
    .zp-toggle-btn { right: 14px; top: 50%; bottom: auto; transform: translateY(-50%); }
    .zp-toggle-btn:hover { transform: translateY(calc(-50% - 1px)); }
}

/* ─────────────────────────────────────────────────────────
   APPROVAL ROW
   ───────────────────────────────────────────────────────── */
.erp-appr-row {
    display: flex;
    align-items: flex-start;
    gap: 12px;
    padding: 12px 0;
    border-bottom: 1px solid var(--erp-border);
}
.erp-appr-row:last-child { border-bottom: 0; }
.erp-appr-body { flex: 1; min-width: 0; }
.erp-appr-name {
    font-weight: 600;
    color: var(--erp-text);
    font-size: 13.5px;
}
.erp-appr-username {
    color: var(--erp-text-muted);
    font-weight: 400;
    font-size: 12px;
    margin-left: 4px;
}
.erp-appr-meta {
    color: var(--erp-text-muted);
    font-size: 11.5px;
    margin-top: 3px;
    display: flex;
    align-items: center;
}
.erp-appr-action {
    padding: 6px 0 4px 48px;   /* indent so it lines up under avatar */
    margin-top: 4px;
    border-top: 1px dashed var(--erp-border);
}

/* ─────────────────────────────────────────────────────────
   AVATAR
   ───────────────────────────────────────────────────────── */
.erp-avatar {
    width: 36px; height: 36px;
    border-radius: 50%;
    object-fit: cover;
    flex-shrink: 0;
    background: var(--erp-surface-alt);
    border: 1.5px solid var(--erp-border);
}
.erp-avatar--sm { width: 28px; height: 28px; }
.erp-avatar--lg { width: 44px; height: 44px; }
.erp-avatar--xl { width: 64px; height: 64px; }

/* ─────────────────────────────────────────────────────────
   MODAL — drop-in replacement for Bootstrap modals
   ───────────────────────────────────────────────────────── */
/* Defensive viewport-anchored backdrop so it always fills the screen even
   if an ancestor accidentally becomes a containing block for fixed. */
.erp-modal-backdrop {
    position: fixed !important;
    top: 0 !important; left: 0 !important;
    width: 100vw !important; height: 100vh !important;
    background: rgba(15,23,42,.55);
    z-index: 1050;
}

/* The visible modal box. Centered in the viewport; the same element holds
   the chrome (background / border-radius / shadow). Supports two markup
   patterns:
     A) modifier on .erp-modal itself:
        <div class="erp-modal erp-modal--lg">...children...</div>
     B) modifier on an inner .erp-modal-content wrapper:
        <div class="erp-modal"><div class="erp-modal-content erp-modal--lg">...</div></div>
   For B, :has() forwards the inner modifier's width to the outer box. */
.erp-modal {
    position: fixed;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 460px;
    max-width: calc(100vw - 40px);
    max-height: calc(100vh - 40px);
    background: var(--erp-surface);
    color: var(--erp-text);
    border-radius: var(--erp-radius-lg);
    box-shadow: var(--erp-shadow-lg);
    display: flex;
    flex-direction: column;
    overflow: hidden;
    z-index: 1055;
}

/* Width tiers — apply to the outer .erp-modal whether the modifier is
   declared directly on it or on an inner .erp-modal-content wrapper. */
.erp-modal.erp-modal--sm,
.erp-modal:has(> .erp-modal-content.erp-modal--sm) { width: 400px; }
.erp-modal.erp-modal--md,
.erp-modal:has(> .erp-modal-content.erp-modal--md) { width: 540px; }
.erp-modal.erp-modal--lg,
.erp-modal:has(> .erp-modal-content.erp-modal--lg) { width: 720px; }
.erp-modal.erp-modal--xl,
.erp-modal:has(> .erp-modal-content.erp-modal--xl) { width: 980px; }

/* Passthrough for the inner content wrapper used by Option B markup. */
.erp-modal-content {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

/* Status text colors */
.erp-text--primary { color: var(--erp-primary); }
.erp-text--success { color: var(--erp-success); }
.erp-text--warning { color: var(--erp-warning); }
.erp-text--danger  { color: var(--erp-danger); }
.erp-text--muted   { color: var(--erp-text-muted); }
.erp-modal-header {
    padding: 14px 18px;
    border-bottom: 1px solid var(--erp-border);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}
.erp-modal-title { font-size: 14px; font-weight: 600; color: var(--erp-text); margin: 0; }
.erp-modal-body { padding: 16px 18px; color: var(--erp-text-muted); font-size: 13px; }
.erp-modal-footer {
    padding: 10px 18px;
    border-top: 1px solid var(--erp-border);
    display: flex;
    justify-content: flex-end;
    gap: 8px;
}

/* ─────────────────────────────────────────────────────────
   FIELD ACCESSORIES — separator, section label, action menu
   ───────────────────────────────────────────────────────── */
.erp-field-separator {
    border: 0;
    border-top: 1px solid var(--erp-border);
    margin: 10px 0 4px;
}
/* Separator with a centered caption — two flex stretches draw the line
   either side of the text, like an HR with the label sitting on it. */
.erp-field-separator-row {
    display: flex;
    align-items: center;
    width: 100%;
    margin: 12px 0 6px;
    gap: 12px;
}
.erp-field-separator-row::before,
.erp-field-separator-row::after {
    content: "";
    flex: 1 1 0;
    height: 1px;
    background: var(--erp-border);
}
.erp-field-separator-text {
    flex: 0 0 auto;
    color: var(--erp-label);
    font-weight: 700;
    font-size: 11.5px;
    text-transform: uppercase;
    letter-spacing: .6px;
    padding: 0 4px;
    white-space: nowrap;
}
.erp-field-section-label {
    padding: 8px 10px 4px;
    border-bottom: 1px solid var(--erp-border);
    color: var(--erp-text-muted);
    font-size: 11.5px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .5px;
}

.erp-actionmenu-backdrop {
    position: fixed; inset: 0;
    z-index: 1040;
}
.erp-actionmenu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    z-index: 1050;
    background: var(--erp-surface);
    border: 1px solid var(--erp-border);
    border-radius: var(--erp-radius);
    box-shadow: var(--erp-shadow-lg);
    list-style: none;
    margin: 0;
    padding: 4px 0;
    max-height: 280px;
    overflow-y: auto;
}
.erp-actionmenu-item {
    display: flex;
    align-items: center;
    gap: 10px;
    width: 100%;
    padding: 8px 14px;
    border: 0;
    background: transparent;
    color: var(--erp-text);
    font-size: 13px;
    text-align: left;
    cursor: pointer;
    transition: background .12s;
}
.erp-actionmenu-item:hover { background: var(--erp-primary-tint); color: var(--erp-primary); }
.erp-actionmenu-item i { color: var(--erp-primary); font-size: 12px; }

/* ─────────────────────────────────────────────────────────
   RESPONSIVE — stack labels above inputs on small screens
   ───────────────────────────────────────────────────────── */
@media (max-width: 575px) {
    .erp-field {
        flex-direction: column;
        align-items: stretch;
    }
    .erp-field-label {
        flex: 0 0 auto;
        margin-bottom: 4px;
    }
}

/* ════════════════════════════════════════════════════════════════════
   APPROVAL FLOW PREVIEW — printable cycle diagram (formulas, no GUID).
   Ported from legacy ApprovalSetup "View Flow". Hardcoded light colours so
   the print copy is faithful regardless of theme.
   ════════════════════════════════════════════════════════════════════ */
.flow-doc-title { font-size:16px; font-weight:700; color:#1e293b; margin:4px 4px 12px; display:flex; align-items:center; gap:10px; }
.flow-wrap { display:flex; flex-direction:column; align-items:center; padding:8px 12px 16px; gap:0; }
.flow-terminal { padding:10px 32px; border-radius:50px; font-size:13px; font-weight:700; display:inline-flex; align-items:center; box-shadow:0 2px 8px rgba(0,0,0,.08); }
.flow-start { background:#dbeafe; color:#1d4ed8; border:2px solid #93c5fd; }
.flow-end   { background:#d1fae5; color:#065f46; border:2px solid #6ee7b7; }
.flow-arrow { padding:4px 0; display:flex; flex-direction:column; align-items:center; }
.flow-arrow-line { width:2px; height:20px; background:#e2e8f0; }
.flow-no-seq { padding:20px; text-align:center; color:#94a3b8; font-size:13px; }
.flow-no-apr { padding:8px 14px; font-size:12px; color:#94a3b8; font-style:italic; }

.flow-step-group { width:100%; max-width:640px; background:#fff; border:1.5px solid #e2e8f0; border-radius:14px; overflow:hidden; box-shadow:0 2px 8px rgba(0,0,0,.06); }
.flow-type-bar { display:flex; align-items:center; gap:8px; padding:7px 16px; font-size:11px; font-weight:700; color:#fff; letter-spacing:.3px; }
.flow-type-tag { background:rgba(255,255,255,.25); padding:1px 8px; border-radius:20px; font-size:10px; margin-left:auto; }

.flow-users-row { display:flex; flex-wrap:wrap; gap:10px; padding:14px 16px; justify-content:center; align-items:flex-start; }

.flow-user-card { display:flex; flex-direction:column; align-items:center; gap:5px; padding:10px 18px; background:#f8faff; border:1.5px solid #e2e8f0; border-radius:10px; min-width:90px; position:relative; }
.flow-user-avatar { width:38px; height:38px; border-radius:50%; background:#e0e7ff; display:flex; align-items:center; justify-content:center; color:#6366f1; font-size:16px; position:relative; }
.flow-user-badge { position:absolute; bottom:-2px; right:-4px; width:14px; height:14px; border-radius:50%; background:#f59e0b; display:flex; align-items:center; justify-content:center; font-size:7px; color:#fff; }
.flow-user-name { font-size:12px; font-weight:600; color:#1e293b; text-align:center; white-space:nowrap; }
.flow-user-plus { font-size:9px; color:#94a3b8; font-style:italic; }

.flow-formula-card { width:100%; background:#fffbeb; border:1.5px solid #fde68a; border-radius:10px; padding:12px 14px; position:relative; }
.flow-formula-head { display:flex; align-items:center; gap:7px; font-size:10px; font-weight:700; color:#92400e; text-transform:uppercase; letter-spacing:.4px; margin-bottom:6px; }

/* IIF decision tree */
.iif-tree { font-size:12px; }
.iif-node { margin-top:4px; }
.iif-cond-row { display:flex; align-items:center; gap:6px; margin-bottom:3px; }
.iif-cond-badge { display:inline-flex; align-items:center; gap:5px; background:#fef3c7; border:1px solid #fde68a; padding:2px 8px; border-radius:5px; font-size:11px; color:#92400e; font-family:monospace; word-break:break-word; }
.iif-branch { display:flex; align-items:flex-start; gap:6px; margin-bottom:3px; padding-left:12px; border-left:2px solid #e2e8f0; margin-left:6px; }
.iif-yes { background:#d1fae5; color:#065f46; padding:1px 6px; border-radius:4px; font-size:10px; font-weight:700; flex-shrink:0; margin-top:2px; }
.iif-no  { background:#fee2e2; color:#991b1b; padding:1px 6px; border-radius:4px; font-size:10px; font-weight:700; flex-shrink:0; margin-top:2px; }
.iif-leaf-user { display:inline-flex; align-items:center; gap:5px; background:#dbeafe; color:#1d4ed8; padding:2px 9px; border-radius:20px; font-size:11px; font-weight:600; }
.iif-leaf-skip { display:inline-flex; align-items:center; gap:4px; background:#f1f5f9; color:#64748b; padding:2px 8px; border-radius:20px; font-size:11px; font-style:italic; }

/* Print copy (rendered inside the print iframe) flows naturally across pages */
@media print {
    .flow-step-group { break-inside:avoid; box-shadow:none !important; }
    body { background:#fff; }
}

/* ── Mobile: list-as-cards (replaces the wide DxGrid on phones) ──────────── */
.dd-cards {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 4px 2px 80px;          /* bottom room for sticky bars */
    -webkit-overflow-scrolling: touch;
}
/* Mobile ROW card (inside .dd-cards). Scoped so it never affects the outer
   drilldown container, which also has the `.dd-card` class (`.card.dd-card`) —
   otherwise clicking the desktop grid shrank the whole card. */
.dd-cards .dd-card {
    position: relative;
    background: var(--erp-surface, #fff);
    border: 1px solid var(--erp-border, #e4e7ec);
    border-radius: 14px;
    padding: 14px 38px 14px 14px;   /* right room for chevron */
    box-shadow: 0 1px 2px rgba(16,24,40,.05);
    cursor: pointer;
    transition: background .12s, box-shadow .12s, transform .06s;
}
.dd-cards .dd-card:active { transform: scale(.985); background: var(--erp-surface-hover, #f9fafb); }
.dd-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-bottom: 6px;
}
.dd-card-title {
    font-weight: 700;
    font-size: 15px;
    color: var(--erp-text, #101828);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    flex: 1;
}
.dd-card-body { display: flex; flex-direction: column; gap: 3px; }
.dd-card-line {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    font-size: 13px;
    line-height: 1.45;
}
.dd-card-label { color: var(--erp-text-muted, #667085); flex-shrink: 0; }
.dd-card-value {
    color: var(--erp-text, #344054);
    font-weight: 500;
    text-align: right;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.dd-card-chev {
    position: absolute;
    top: 50%;
    inset-inline-end: 14px;
    transform: translateY(-50%);
    color: var(--erp-text-muted, #98a2b3);
    font-size: 13px;
}
[dir="rtl"] .dd-card-chev { transform: translateY(-50%) scaleX(-1); }
[dir="rtl"] .dd-card-value { text-align: left; }
[data-bs-theme="dark"] .dd-cards .dd-card { background: #1e293b; border-color: #334155; }
[data-bs-theme="dark"] .dd-cards .dd-card:active { background: #273449; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE OBJECT FORM  (scoped to .erp-shell.is-mobile — set live on resize)
   - single-column stacked fields
   - horizontally scrollable tabs
   - actions pinned to a sticky bottom bar with 44px tap targets
   ══════════════════════════════════════════════════════════════════════════ */
.erp-shell.is-mobile .erp-card-body--compact .row > [id^="fld-"] {
    flex: 0 0 100% !important;
    max-width: 100% !important;
}
.erp-shell.is-mobile .erp-field { flex-direction: column; align-items: stretch; }
.erp-shell.is-mobile .erp-field-label { margin-bottom: 4px; }
.erp-shell.is-mobile .erp-field-input { width: 100%; }

/* Larger, touch-friendly inputs */
.erp-shell.is-mobile .erp-field-input input,
.erp-shell.is-mobile .erp-field-input select,
.erp-shell.is-mobile .erp-field-input textarea,
.erp-shell.is-mobile .erp-field-input .dxbl-edit input { min-height: 42px; font-size: 16px; }

/* Tabs: one scrollable row, no wrap, no scrollbar chrome */
.erp-shell.is-mobile .erp-tabs {
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    gap: 4px;
    padding-bottom: 2px;
}
.erp-shell.is-mobile .erp-tabs::-webkit-scrollbar { display: none; }
.erp-shell.is-mobile .erp-tab { white-space: nowrap; flex: 0 0 auto; min-height: 40px; }

/* Sticky bottom action bar (object page toolbar only) */
.erp-shell.is-mobile .erp-toolbar--object {
    position: fixed;
    inset-inline: 0;
    bottom: 0;
    z-index: 40;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    gap: 6px;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin: 0;
    padding: 8px 10px calc(8px + env(safe-area-inset-bottom, 0px));
    background: var(--erp-surface, #fff);
    border-top: 1px solid var(--erp-border, #e4e7ec);
    box-shadow: 0 -2px 10px rgba(16,24,40,.08);
}
.erp-shell.is-mobile .erp-toolbar--object::-webkit-scrollbar { display: none; }
.erp-shell.is-mobile .erp-toolbar--object .erp-tb-btn,
.erp-shell.is-mobile .erp-toolbar--object .erp-cta {
    min-height: 44px;
    flex: 0 0 auto;
}
/* Keep the side widgets (presence/print/reload) from stretching the bar */
.erp-shell.is-mobile .erp-toolbar--object .erp-toolbar-right { margin-inline-start: auto; gap: 6px; }
[data-bs-theme="dark"] .erp-shell.is-mobile .erp-toolbar--object { background: #1e293b; border-color: #334155; }

/* Clear the fixed bottom bar so the last fields/grids aren't hidden behind it */
.erp-shell.is-mobile .erp-main { padding-bottom: 76px; }

/* Full-width, larger primary buttons in the bottom bar */
.erp-shell.is-mobile .erp-toolbar--object .erp-tb-btn-label { font-size: 13px; }

/* ── Mobile child grid → stacked card editor ─────────────────────────────── */
.erp-cg-cards { display: flex; flex-direction: column; gap: 10px; padding: 2px; }
.erp-cg-card-empty {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 28px 0; color: var(--erp-text-muted, #98a2b3); font-size: 14px;
}
.erp-cg-card-empty i { font-size: 24px; opacity: .6; }
.erp-cg-card {
    border: 1px solid var(--erp-border, #e4e7ec);
    border-radius: 12px;
    background: var(--erp-surface, #fff);
    overflow: hidden;
}
.erp-cg-card.is-dirty { border-color: #fec84b; box-shadow: 0 0 0 1px #fec84b inset; }
.erp-cg-card-head {
    display: flex; align-items: center; gap: 8px;
    padding: 8px 12px;
    background: var(--erp-surface-hover, #f9fafb);
    border-bottom: 1px solid var(--erp-border, #e4e7ec);
}
.erp-cg-card-no {
    font-weight: 700; font-size: 13px; color: var(--erp-text-muted, #667085);
    min-width: 20px;
}
.erp-pill--xs { font-size: 10px; padding: 1px 7px; }
.erp-cg-card-del {
    border: none; background: transparent; color: #d92d20;
    width: 36px; height: 36px; border-radius: 8px; font-size: 15px; cursor: pointer;
}
.erp-cg-card-del:active { background: rgba(217,45,32,.1); }
.erp-cg-card-fields { display: flex; flex-direction: column; padding: 6px 12px 12px; gap: 10px; }
.erp-cg-card-field { display: flex; flex-direction: column; gap: 4px; }
.erp-cg-card-label {
    font-size: 12px; font-weight: 600; color: var(--erp-text-muted, #667085);
}
.erp-cg-card-input .erp-sheet-cell,
.erp-cg-card-input .dxbl-edit { width: 100%; min-height: 42px; }
.erp-cg-card-input .erp-sheet-ro { font-size: 14px; color: var(--erp-text, #344054); }
[data-bs-theme="dark"] .erp-cg-card { background: #1e293b; border-color: #334155; }
[data-bs-theme="dark"] .erp-cg-card-head { background: #273449; border-color: #334155; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE GLOBAL POLISH  (.erp-shell.is-mobile)
   - dialogs become full-screen sheets so cramped 460px popups don't appear
   - 44px minimum tap targets and slightly larger base type
   ══════════════════════════════════════════════════════════════════════════ */
.erp-shell.is-mobile .erp-modal,
.erp-shell.is-mobile .erp-modal.erp-modal--sm,
.erp-shell.is-mobile .erp-modal.erp-modal--md,
.erp-shell.is-mobile .erp-modal.erp-modal--lg,
.erp-shell.is-mobile .erp-modal.erp-modal--xl,
.erp-shell.is-mobile .erp-modal:has(> .erp-modal-content) {
    top: 0; left: 0;
    transform: none;
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    border-radius: 0;
}
.erp-shell.is-mobile .erp-modal-body { flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch; }
.erp-shell.is-mobile .erp-modal-footer { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }
/* The modal footer's action buttons go full-width and tall for thumbs */
.erp-shell.is-mobile .erp-modal-footer .erp-cta,
.erp-shell.is-mobile .erp-modal-footer .erp-tb-btn { min-height: 44px; flex: 1 1 auto; justify-content: center; }

/* Comfortable tap targets across interactive chrome on phones */
.erp-shell.is-mobile .erp-cta,
.erp-shell.is-mobile .erp-icon-btn,
.erp-shell.is-mobile .erp-tb-btn { min-height: 40px; }
.erp-shell.is-mobile { font-size: 15px; }

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE MODULE NAVIGATION
   Full-screen launcher (grid of module tiles) → drill into a module's object
   list (the existing aside, shown full-width with the rail hidden).
   ══════════════════════════════════════════════════════════════════════════ */
/* On a phone the desktop rail+tree aside is fully replaced by the launcher. */
.erp-shell.is-mobile .erp-sidebar { display: none; }

/* Back arrow in the drill-down header */
.erp-mnav-back {
    width: 40px; height: 40px; border: none; background: transparent;
    color: var(--erp-text); font-size: 17px; cursor: pointer; border-radius: 8px;
    margin-inline-end: 4px;
}
.erp-mnav-back:active { background: var(--erp-surface-alt); }
[dir="rtl"] .erp-mnav-back i { transform: scaleX(-1); }

/* Sub-category (folder) and object tile icons use neutral/muted fills */
.erp-mnav-ico--folder { background: #94a3b8; }
.erp-mnav-ico--obj    { background: #64748b; }

/* Empty-level placeholder spans the whole grid */
.erp-mnav-empty {
    grid-column: 1 / -1;
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    padding: 40px 0; color: var(--erp-text-muted); font-size: 14px;
}
.erp-mnav-empty i { font-size: 26px; opacity: .6; }

/* Full-screen launcher overlay */
.erp-mnav {
    position: fixed; inset: var(--erp-nav-h, 56px) 0 0 0;
    z-index: 1310;
    background: var(--erp-bg, #f8fafc);
    display: flex; flex-direction: column;
    animation: mnav-in .2s ease;
}
@keyframes mnav-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
.erp-mnav-head {
    display: flex; align-items: center; justify-content: space-between;
    padding: 14px 16px;
    border-bottom: 1px solid var(--erp-border);
    background: var(--erp-surface);
}
.erp-mnav-title {
    flex: 1 1 auto; min-width: 0;
    font-size: 17px; font-weight: 700; color: var(--erp-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.erp-mnav-x {
    width: 40px; height: 40px; border: none; background: transparent;
    color: var(--erp-text-muted); font-size: 20px; cursor: pointer; border-radius: 8px;
}
.erp-mnav-x:active { background: var(--erp-surface-alt); }
/* Toolbar actions / targets dropdown (anchors the .erp-actionmenu popup) */
.erp-tb-dropdown { position: relative; display: inline-flex; }
.erp-tb-dropdown .erp-actionmenu {
    left: 0; right: auto;
    min-width: 220px; max-width: 360px;
    z-index: 1060;
}
/* Targets sit on the toolbar's right edge → open the menu aligned to the right
   so it never overflows the viewport. */
.erp-tb-dropdown .erp-actionmenu--end { left: auto; right: 0; }
.erp-tb-dropdown .erp-actionmenu-item { white-space: normal; line-height: 1.3; }
.erp-tb-dropdown .erp-actionmenu-item:disabled { opacity: .5; cursor: not-allowed; }
[dir="rtl"] .erp-tb-dropdown .erp-actionmenu { left: auto; right: 0; text-align: right; }
[dir="rtl"] .erp-tb-dropdown .erp-actionmenu--end { right: auto; left: 0; }

/* Targets toolbar button — same shape as Actions, teal accent to set it apart.
   (Without this it fell back to the 32px square icon button and looked cramped.) */
.erp-tb-btn--target {
    width: auto; min-width: 32px;
    padding: 0 10px; gap: 6px;
    color: #0d9488;
    font-size: 12.5px; font-weight: 600;
}
.erp-tb-btn--target:hover:not(:disabled) {
    background: rgba(13,148,136,.10);
    border-color: rgba(13,148,136,.30);
    color: #0f766e;
}
.erp-tb-btn--target .erp-tb-btn-label { white-space: nowrap; }
.erp-tb-caret { font-size: 11px; margin-inline-start: 4px; opacity: .8; }

/* Target popup — the linked object's form shown chrome-less in a large modal.
   Sits ABOVE the tab host chrome (topnav 1300 / wb-bar 1250) which otherwise
   overlapped the tall modal. */
.erp-modal-backdrop--top { z-index: 1500; }

/* DevExpress wraps every OPEN popup/dropdown in .dxbl-popup-cell (position:absolute, inline
   z-index:0). THAT cell is the stacking context, so raising the inner .dxbl-dropdown can't escape
   it. The cell sits below whichever app layer hosts the combo, so the option list paints BEHIND
   it: the value shows in the box, but the list is hidden (typing still matches it). This bites
   EVERY popup that contains a combo — the tree / "open target" modal (1501), the field & object
   meta-edit popups and ChildGrid "Edit full details" (.erp-modal/.erp-cg-popup = 1055), the chat
   drawer (.zp-drawer = 5000), etc. Lift the CELL above ALL of them in one shot. (Only the
   standalone date-picker overlay sits higher at 11001, and it hosts no DevExpress combos.) The
   .dxbl-modal-root line covers the narrow/mobile bottom-sheet render mode. */
.dxbl-popup-cell,
.dxbl-modal > .dxbl-modal-root:has(.dxbl-edit-dropdown) { z-index: 12000 !important; }
/* Center WITHOUT transform: translate. .erp-modal centers via transform:translate(-50%,-50%),
   but a transformed ancestor re-bases position:fixed descendants — which breaks the DevExpress
   DxComboBox dropdown overlay inside this modal (it opens but renders off-position/clipped, so it
   looks "empty"). This modal is a fixed size, so inset:0 + margin:auto centers it transform-free,
   letting embedded-form combos (tree popup, "open target") drop down correctly. */
.erp-target-modal {
    inset: 0; margin: auto; transform: none;
    width: 92vw; max-width: 1100px; height: 90vh; max-height: 90vh; z-index: 1501;
}
.erp-target-modal-body { padding: 0; overflow-y: auto; flex: 1 1 auto; background: var(--erp-bg); }

/* Target control button (opens a linked object; field value = GUID) */
.erp-target-btn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.erp-target-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.erp-grid--sheet .erp-target-btn { padding: 2px 8px; min-height: 26px; }

/* Launcher search box (search objects across every module) */
.erp-mnav-search {
    display: flex; align-items: center; gap: 10px;
    margin: 12px 16px 0;
    padding: 0 12px;
    height: 44px;
    background: var(--erp-surface-alt);
    border: 1px solid var(--erp-border);
    border-radius: 12px;
}
.erp-mnav-search:focus-within { border-color: var(--erp-primary); background: var(--erp-surface); }
.erp-mnav-search-ico { color: var(--erp-text-muted); font-size: 14px; flex-shrink: 0; }
.erp-mnav-search-input {
    flex: 1; min-width: 0; border: none; outline: none; background: transparent;
    font-size: 15px; color: var(--erp-text); font-family: inherit;
}
.erp-mnav-search-input::placeholder { color: var(--erp-text-muted); }
.erp-mnav-search-clear {
    border: none; background: transparent; color: var(--erp-text-muted);
    font-size: 14px; cursor: pointer; padding: 6px; flex-shrink: 0;
    display: inline-flex; align-items: center;
}

.erp-mnav-grid {
    flex: 1 1 auto; overflow-y: auto; -webkit-overflow-scrolling: touch;
    display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px;
    padding: 16px 16px calc(24px + env(safe-area-inset-bottom, 0px)) 16px;
    align-content: start;
}
.erp-mnav-tile {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: 10px; padding: 18px 10px; min-height: 132px;
    background: var(--erp-surface);
    border: 1px solid var(--erp-border);
    border-radius: 16px; cursor: pointer;
    transition: transform .06s, box-shadow .12s;
}
.erp-mnav-tile:active { transform: scale(.97); box-shadow: var(--erp-shadow-sm); }
.erp-mnav-ico {
    width: 52px; height: 52px; flex-shrink: 0; border-radius: 14px;
    display: flex; align-items: center; justify-content: center;
    color: #fff; font-size: 22px;
}
.erp-mnav-label {
    font-size: 13px; font-weight: 600; color: var(--erp-text);
    text-align: center; line-height: 1.25;
    /* Reserve two lines so a wrapping module name stays INSIDE the card
       (and 1- vs 2-line tiles keep a uniform height). */
    min-height: 2.5em;
    display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
[data-bs-theme="dark"] .erp-mnav { background: #0f172a; }

/* ══════════════════════════════════════════════════════════════════════════
   USER-TO-USER CHAT  (header button + slide-in panel)
   ══════════════════════════════════════════════════════════════════════════ */
.chat-widget { position: relative; display: inline-flex; }
.chat-btn { position: relative; }

.chat-backdrop { position: fixed; inset: 0; z-index: 1490; }
.chat-panel {
    position: fixed;
    top: var(--erp-nav-h, 56px);
    inset-inline-end: 0;
    width: 380px; max-width: 96vw;
    height: calc(100vh - var(--erp-nav-h, 56px));
    background: var(--erp-surface);
    border-inline-start: 1px solid var(--erp-border);
    box-shadow: var(--erp-shadow-lg);
    z-index: 1491;
    display: flex; flex-direction: column;
    animation: chat-in .18s ease;
}
@keyframes chat-in { from { transform: translateX(20px); opacity: 0; } to { transform: none; opacity: 1; } }

.chat-head {
    display: flex; align-items: center; gap: 8px;
    padding: 10px 12px; min-height: 52px;
    border-bottom: 1px solid var(--erp-border);
    background: var(--erp-surface-alt);
}
.chat-head-title { flex: 1; font-weight: 700; font-size: 15px; color: var(--erp-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-iconbtn {
    width: 34px; height: 34px; border: none; background: transparent;
    color: var(--erp-text-muted); border-radius: 8px; cursor: pointer; font-size: 15px;
    display: inline-flex; align-items: center; justify-content: center;
}
.chat-iconbtn:hover { background: var(--erp-surface); color: var(--erp-primary); }
.chat-iconbtn--muted { color: var(--erp-warning, #f59e0b); }
[dir="rtl"] .chat-iconbtn .fa-arrow-left { transform: scaleX(-1); }

.chat-body { flex: 1 1 auto; display: flex; flex-direction: column; min-height: 0; overflow: hidden; }

/* Thread list */
.chat-threadrow {
    display: flex; align-items: center; gap: 10px;
    width: 100%; padding: 10px 12px; border: 0; background: transparent;
    border-bottom: 1px solid var(--erp-border); cursor: pointer; text-align: start;
}
.chat-threadrow:hover { background: var(--erp-surface-alt); }
.chat-threadrow.is-unread .chat-threadrow-title { font-weight: 700; }
.chat-threadrow-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-threadrow-title { font-size: 14px; color: var(--erp-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-threadrow-last  { font-size: 12px; color: var(--erp-text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-threadrow-side  { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; flex-shrink: 0; }
.chat-threadrow-time  { font-size: 11px; color: var(--erp-text-muted); }
.chat-unread {
    background: var(--erp-primary); color: #fff; font-size: 11px; font-weight: 700;
    min-width: 18px; height: 18px; padding: 0 5px; border-radius: 9px;
    display: inline-flex; align-items: center; justify-content: center;
}
.chat-avatar {
    width: 38px; height: 38px; flex-shrink: 0; border-radius: 50%;
    background: var(--erp-primary); color: #fff; font-size: 13px; font-weight: 700;
    display: inline-flex; align-items: center; justify-content: center;
}
.chat-avatar--group { background: #6366f1; }

/* New-chat user picker */
.chat-newbar { display: flex; align-items: center; gap: 8px; padding: 10px 12px 4px; }
.chat-search {
    flex: 1; height: 36px; padding: 0 12px; font-size: 13px;
    border: 1px solid var(--erp-border); border-radius: 8px; background: var(--erp-surface-alt);
    color: var(--erp-text); outline: none; margin: 0 12px;
}
.chat-newbar .chat-search { margin: 0; }
.chat-search:focus { border-color: var(--erp-primary); background: var(--erp-surface); }
.chat-grouptoggle { display: inline-flex; align-items: center; gap: 5px; font-size: 12.5px; color: var(--erp-text-muted); white-space: nowrap; }
.chat-userlist { flex: 1; overflow-y: auto; margin-top: 6px; }
.chat-userrow {
    display: flex; align-items: center; gap: 10px; width: 100%;
    padding: 8px 12px; border: 0; background: transparent; cursor: pointer; text-align: start;
}
.chat-userrow:hover { background: var(--erp-surface-alt); }
.chat-userrow.is-sel { background: var(--erp-primary-tint); }
.chat-userrow-name { flex: 1; font-size: 13.5px; color: var(--erp-text); }
.chat-userrow-chk { color: var(--erp-primary); }
.chat-creategroup {
    margin: 10px 12px; padding: 9px 12px; border: 0; border-radius: 8px;
    background: var(--erp-primary); color: #fff; font-weight: 600; font-size: 13px; cursor: pointer;
}
.chat-creategroup:disabled { opacity: .5; cursor: not-allowed; }

/* Messages */
.chat-messages {
    flex: 1 1 auto; min-height: 0;       /* allow it to shrink so overflow-y scrolls */
    overflow-y: auto; overscroll-behavior: contain;
    padding: 12px; display: flex; flex-direction: column; gap: 6px; background: var(--erp-bg);
    scrollbar-width: thin; scrollbar-color: var(--erp-border-strong, #cbd5e1) transparent;
}
.chat-messages::-webkit-scrollbar { width: 8px; }
.chat-messages::-webkit-scrollbar-thumb { background: var(--erp-border-strong, #cbd5e1); border-radius: 8px; }
.chat-messages::-webkit-scrollbar-track { background: transparent; }
.chat-msg {
    max-width: 78%; align-self: flex-start;
    background: var(--erp-surface); border: 1px solid var(--erp-border);
    border-radius: 12px; padding: 7px 10px; position: relative;
}
.chat-msg.is-mine { align-self: flex-end; background: var(--erp-primary); border-color: var(--erp-primary); color: #fff; }
.chat-msg-from { display: block; font-size: 11px; font-weight: 700; color: var(--erp-primary); margin-bottom: 2px; }
.chat-msg-body { font-size: 13.5px; white-space: pre-wrap; word-break: break-word; }
.chat-msg-time { display: block; font-size: 10px; opacity: .65; text-align: end; margin-top: 2px; }

.chat-composer { display: flex; align-items: flex-end; gap: 8px; padding: 10px 12px; border-top: 1px solid var(--erp-border); background: var(--erp-surface); }
.chat-input {
    flex: 1; resize: none; max-height: 96px; min-height: 38px;
    padding: 9px 12px; font-size: 13.5px; font-family: inherit;
    border: 1px solid var(--erp-border); border-radius: 18px; background: var(--erp-surface-alt);
    color: var(--erp-text); outline: none;
}
.chat-input:focus { border-color: var(--erp-primary); background: var(--erp-surface); }
.chat-send {
    width: 40px; height: 40px; flex-shrink: 0; border: 0; border-radius: 50%;
    background: var(--erp-primary); color: #fff; cursor: pointer; font-size: 15px;
}
.chat-send:disabled { opacity: .4; cursor: not-allowed; }

.chat-empty { display: flex; flex-direction: column; align-items: center; gap: 6px; padding: 48px 16px; color: var(--erp-text-muted); }
.chat-empty i { font-size: 30px; opacity: .5; }

/* Mobile: full-screen panel */
.erp-shell.is-mobile .chat-panel { width: 100vw; max-width: 100vw; }

[data-bs-theme="dark"] .chat-msg.is-mine { color: #fff; }

/* Chat online-presence dots */
.chat-avatar-wrap { position: relative; flex-shrink: 0; display: inline-flex; }
.chat-dot {
    position: absolute; bottom: 0; inset-inline-end: 0;
    width: 11px; height: 11px; border-radius: 50%;
    background: #22c55e; border: 2px solid var(--erp-surface);
}
.chat-online-label { font-size: 11px; color: #16a34a; font-weight: 600; margin-inline-start: auto; }
.chat-head-title { display: flex; flex-direction: column; min-width: 0; }
.chat-head-name { font-weight: 700; font-size: 15px; color: var(--erp-text);
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-head-sub { font-size: 11px; color: var(--erp-text-muted); line-height: 1.2; }
.chat-head-sub.is-online { color: #16a34a; }
.chat-head-sub.is-online::before {
    content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%;
    background: #22c55e; margin-inline-end: 5px; vertical-align: middle;
}

/* Chat typing indicator */
.chat-typing {
    display: flex; align-items: center; gap: 8px;
    padding: 4px 14px; font-size: 12px; color: var(--erp-text-muted);
    font-style: italic;
}
.chat-typing-dots { display: inline-flex; gap: 3px; align-items: center; }
.chat-typing-dots span {
    width: 6px; height: 6px; border-radius: 50%; background: var(--erp-text-muted);
    display: inline-block; opacity: .4; animation: chat-typing-bounce 1.2s infinite ease-in-out;
}
.chat-typing-dots span:nth-child(2) { animation-delay: .2s; }
.chat-typing-dots span:nth-child(3) { animation-delay: .4s; }
@keyframes chat-typing-bounce {
    0%, 60%, 100% { transform: translateY(0); opacity: .4; }
    30% { transform: translateY(-4px); opacity: 1; }
}

/* Chat attachments — message images/files, composer buttons, pending preview */
.chat-msg-img { max-width: 220px; max-height: 220px; border-radius: 8px; display: block; cursor: pointer; }
.chat-msg.is-mine .chat-msg-img { margin-left: auto; }
.chat-msg-file {
    display: inline-flex; align-items: center; gap: 8px; max-width: 220px;
    padding: 8px 10px; border-radius: 8px; background: rgba(0,0,0,.06);
    color: inherit; text-decoration: none; font-size: 13px;
}
.chat-msg.is-mine .chat-msg-file { background: rgba(255,255,255,.18); }
.chat-msg-file:hover { text-decoration: underline; }

.chat-attach {
    width: 36px; height: 36px; flex-shrink: 0; border: 0; background: transparent;
    color: var(--erp-text-muted); border-radius: 8px; cursor: pointer; font-size: 15px;
}
.chat-attach:hover { background: var(--erp-surface-alt); color: var(--erp-primary); }

.chat-pending {
    display: flex; align-items: center; gap: 10px;
    margin: 0 12px; padding: 8px 10px;
    background: var(--erp-surface-alt); border: 1px solid var(--erp-border); border-radius: 10px;
}
.chat-pending-img { max-height: 60px; max-width: 90px; border-radius: 6px; }
.chat-pending-file { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--erp-text); }
.chat-pending-x {
    margin-inline-start: auto; border: 0; background: transparent; color: var(--erp-text-muted);
    cursor: pointer; font-size: 14px; width: 28px; height: 28px; border-radius: 6px;
}
.chat-pending-x:hover { background: var(--erp-surface); color: var(--erp-danger); }

/* Chat help button + record-link chips + support avatar */
.chat-help-btn { color: var(--erp-warning, #d97706); }
.chat-help-btn:hover:not(:disabled) { background: rgba(217,119,6,.12); color: #b45309; }
.chat-reflink {
    display: inline-flex; align-items: center; gap: 5px;
    margin: 2px 0; padding: 3px 9px; border: 0; border-radius: 8px;
    background: rgba(99,102,241,.14); color: #4338ca; font-size: 12.5px; font-weight: 600;
    cursor: pointer; max-width: 100%; vertical-align: middle;
}
.chat-msg.is-mine .chat-reflink { background: rgba(255,255,255,.22); color: #fff; }
.chat-reflink:hover { background: rgba(99,102,241,.25); }
.chat-reflink i { font-size: 11px; }
.chat-avatar--support { background: #f59e0b; }

/* Preferences popup (avatar + password) */
.topnav-dd-btn { width: 100%; border: 0; background: transparent; font-family: inherit; cursor: pointer; text-align: start; }
/* Sit above the --top backdrop (z 1500) so it isn't dimmed by it. */
.prefs-modal { z-index: 1501; }
.prefs-body { padding: 18px 20px; }
.prefs-section-title { font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .6px; color: var(--erp-text-muted); margin-bottom: 10px; }
.prefs-avatar-row { display: flex; align-items: center; gap: 16px; }
.prefs-avatar { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 2px solid var(--erp-border); background: var(--erp-surface-alt); flex-shrink: 0; }
.prefs-avatar-actions { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; }
.prefs-hint { font-size: 11px; color: var(--erp-text-muted); }
.prefs-divider { height: 1px; background: var(--erp-border); margin: 18px 0; }
.prefs-field { margin-bottom: 10px; }
.prefs-field label { display: block; font-size: 12.5px; color: var(--erp-text-muted); margin-bottom: 4px; }
.prefs-field .form-control { width: 100%; }
.prefs-msg { font-size: 12.5px; margin: 4px 0 8px; }
.prefs-msg.is-ok { color: #16a34a; }
.prefs-msg.is-err { color: var(--erp-danger, #dc2626); }
.erp-cta.disabled { opacity: .6; pointer-events: none; }

/* Chat avatars use the user's photo (/api/userphoto) */
.chat-avatar { overflow: hidden; }
.chat-avatar-img { width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block; }
.chat-msg-from { display: flex; align-items: center; gap: 5px; }
.chat-msg-from-img { width: 16px; height: 16px; border-radius: 50%; object-fit: cover; flex-shrink: 0; }
.chat-head-avatar { flex-shrink: 0; }
.chat-head-avatar .chat-avatar { width: 34px; height: 34px; }

/* PictureBox field — image preview + upload/replace (DynamicField) */
.erp-imgfield { display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
.erp-imgfield-preview { max-width: 240px; max-height: 240px; border: 1px solid var(--erp-border); border-radius: 8px; object-fit: contain; background: #fff; padding: 4px; }
.erp-imgfield-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px; width: 160px; height: 120px; border: 1px dashed var(--erp-border-strong); border-radius: 8px; color: var(--erp-text-soft); font-size: 12px; }
.erp-imgfield-empty i { font-size: 26px; }
.erp-imgfield-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.erp-imgfield-pick { cursor: pointer; margin: 0; }
.erp-imgfield-pick input[type=file] { display: none; }

/* ── Employee self-service portal (mobile) ─────────────────────────────── */
.portal-shell { min-height: 100vh; background: var(--erp-bg, #f5f6f8); display: flex; flex-direction: column; overflow-x: hidden; }
.portal-top {
    position: sticky; top: 0; z-index: 10;
    display: flex; align-items: center; justify-content: space-between;
    padding: 12px 16px; color: #fff;
    background: linear-gradient(135deg, var(--erp-primary, #2563eb), var(--erp-primary-band, #1e3a5f));
    box-shadow: 0 2px 12px rgba(0,0,0,.18);
}
.portal-top-id { display: flex; align-items: center; gap: 11px; min-width: 0; flex: 1 1 auto; }
.portal-top-id > div { min-width: 0; }   /* let the name truncate instead of wrapping/pushing the buttons */
.portal-top-id > i {
    font-size: 18px; width: 40px; height: 40px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.18); border: 1px solid rgba(255,255,255,.25);
}
.portal-name { font-weight: 700; font-size: 15px; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.portal-emp { font-size: 12px; opacity: .8; }
.portal-top-actions { display: flex; gap: 7px; flex-shrink: 0; }
.portal-iconbtn {
    width: 38px; height: 38px; border-radius: 10px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    color: #fff; background: rgba(255,255,255,.14); text-decoration: none;
    border: 1px solid rgba(255,255,255,.10); cursor: pointer; font-size: 15px;
    transition: background .15s, transform .12s, border-color .15s;
}
.portal-iconbtn:hover {
    background: rgba(255,255,255,.28); color: #fff;
    transform: translateY(-1px); border-color: rgba(255,255,255,.32);
}
.portal-iconbtn:active { transform: translateY(0); }
.portal-iconbtn--exit:hover { background: rgba(239,68,68,.9); border-color: transparent; }

/* Overflow ("more") menu. Desktop: wrapper/panel are display:contents so the moved
   buttons sit inline on the header bar as before, and the kebab is hidden. The mobile
   block below turns the panel into a dropdown popover. */
.portal-overflow-wrap     { display: contents; }
.portal-overflow          { display: contents; }
.portal-overflow-toggle   { display: none; }
.portal-overflow-backdrop { display: none; }

/* Phones/tablets: collapse the secondary header buttons into the kebab "more" menu,
   leaving only the bell, the kebab and sign-out on the bar. */
@media (max-width: 768px) {
    .portal-overflow-wrap   { display: inline-flex; position: relative; }
    .portal-overflow-toggle { display: flex; }
    .portal-overflow-backdrop {
        display: block; position: fixed; inset: 0; z-index: 1290; background: transparent;
    }
    .portal-overflow {
        display: none; position: absolute; top: calc(100% + 8px); inset-inline-end: 0;
        flex-flow: row wrap; justify-content: flex-end; gap: 6px;
        max-width: 188px; padding: 10px; z-index: 1300;
        background: var(--erp-surface); border: 1px solid var(--erp-border);
        border-radius: 12px; box-shadow: 0 14px 36px rgba(15,23,42,.24);
    }
    .portal-overflow.open { display: flex; }
    /* Recolor the moved buttons for the light dropdown surface (header buttons are
       white-on-translucent, which would be invisible on the popover). */
    .portal-overflow .portal-iconbtn {
        width: 42px; height: 42px; color: var(--erp-text);
        background: var(--erp-input-bg, rgba(15,23,42,.05));
        border-color: var(--erp-border);
    }
    .portal-overflow .portal-iconbtn:hover {
        background: var(--erp-primary-tint); color: var(--erp-primary);
        border-color: transparent;
    }
}

/* Phones: tighten the header so the identity + visible action buttons fit one row. */
@media (max-width: 480px) {
    .portal-top { padding: 10px 12px; gap: 8px; }
    .portal-top-actions { gap: 5px; }
    .portal-iconbtn { width: 34px; height: 34px; font-size: 14px; border-radius: 9px; }
    .portal-top-id { gap: 9px; }
    .portal-top-id > i { width: 36px; height: 36px; font-size: 16px; }
    .portal-name { font-size: 14px; }
    .portal-body { padding: 14px 12px; }
}

/* Notification bell badge (PortalBell) — sits on the header icon button. */
.portal-bell-badge {
    position: absolute; top: -3px; inset-inline-end: -3px; min-width: 17px; height: 17px;
    padding: 0 4px; border-radius: 9px; background: #ef4444; color: #fff;
    font-size: 10px; font-weight: 700; line-height: 17px; text-align: center;
    box-shadow: 0 0 0 2px var(--erp-primary);
}

/* ── Appearance picker (ThemePicker, .tp-*) ─────────────────────────── */
.tp-wrap { position: relative; }
.tp-backdrop { position: fixed; inset: 0; z-index: 1090; }
.tp-pop {
    position: absolute; top: calc(100% + 8px); right: 0; z-index: 1100;
    width: 232px; background: var(--bs-body-bg); color: var(--erp-text);
    border: 1px solid var(--bs-border-color); border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0,0,0,.20); padding: 12px;
}
[dir="rtl"] .tp-pop { right: auto; left: 0; }
.tp-title { display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.tp-title i { color: var(--erp-primary); }
.tp-mode-row { display: flex; gap: 8px; margin-bottom: 12px; }
.tp-mode-btn {
    flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px;
    padding: 8px; border: 1px solid var(--bs-border-color); border-radius: 8px;
    background: var(--bs-body-bg); color: var(--erp-text); cursor: pointer;
    font-size: 12.5px; font-weight: 600; transition: border-color .15s, background .15s;
}
.tp-mode-btn:hover { border-color: var(--erp-primary); }
.tp-mode-btn.active { border-color: var(--erp-primary); background: var(--erp-primary-tint); color: var(--erp-primary); }
.tp-accent-label { font-size: 11.5px; color: var(--erp-text-soft); margin-bottom: 7px; }
.tp-accent-row { display: grid; grid-template-columns: repeat(6, 1fr); gap: 7px; }
.tp-swatch {
    width: 24px; height: 24px; border-radius: 50%; border: 2px solid transparent;
    cursor: pointer; padding: 0; box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .12s;
}
.tp-swatch:hover { transform: scale(1.12); }
.tp-swatch.selected { box-shadow: 0 0 0 2px var(--bs-body-bg), 0 0 0 4px var(--erp-primary); }
.portal-body { flex: 1; padding: 16px; max-width: 720px; margin: 0 auto; width: 100%; }

/* Company branding band at the top of the portal home */
.portal-co {
    display: flex; flex-direction: column; align-items: center; gap: 8px;
    text-align: center; margin: 4px 0 14px;
}
.portal-co-logo {
    max-height: 60px; max-width: 200px; object-fit: contain;
    background: #fff; border-radius: 12px; padding: 8px;
    box-shadow: 0 4px 14px rgba(15,23,42,.10); border: 1px solid var(--bs-border-color);
}
.portal-co-name { font-size: 16px; font-weight: 700; color: var(--erp-text); }

.portal-greeting { margin: 4px 2px 16px; }
.portal-greeting-hi { font-size: 13px; color: var(--erp-text-soft); }
.portal-greeting-name { font-size: 22px; font-weight: 700; color: var(--erp-text); }

/* Home hero banner — company branding + avatar + welcome */
.portal-hero {
    background:
        radial-gradient(at 90% 0%, rgba(255,255,255,.12), transparent 55%),
        linear-gradient(135deg, var(--erp-primary), var(--erp-primary-band, #1e3a5f));
    color: #fff; border-radius: 14px; padding: 10px 14px; margin-bottom: 14px;
    box-shadow: 0 6px 16px rgba(37,99,235,.22);
}
.portal-hero-co { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.portal-hero-logo {
    max-height: 24px; max-width: 120px; object-fit: contain;
    /* Transparent so a white logo reads on the hero's brand-colour gradient (the chip's
       position is the dark primary end). Was a white tile (hid a white logo). */
    background: transparent; border-radius: 8px; padding: 1px 3px;
}
.portal-hero-coname { font-size: 13px; font-weight: 600; opacity: .95; }
.portal-hero-main { display: flex; align-items: center; gap: 12px; }
.portal-hero-avatar {
    position: relative;
    width: 56px; height: 56px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 16px; font-weight: 800; color: #fff;
    background: rgba(255,255,255,.18); border: 2px solid rgba(255,255,255,.4);
    overflow: hidden; cursor: pointer;
}
.portal-hero-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.portal-hero-avatar-blank { font-size: 22px; opacity: .8; }
.portal-hero-avatar-overlay {
    position: absolute; inset: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(0,0,0,.45); border-radius: 50%;
    font-size: 18px; color: #fff;
    opacity: 0; transition: opacity .18s;
    pointer-events: none;
}
.portal-hero-avatar:hover .portal-hero-avatar-overlay,
.portal-hero-avatar--busy .portal-hero-avatar-overlay { opacity: 1; }
.portal-hero-greet { min-width: 0; flex: 1; }
.portal-hero-hi { font-size: 12px; opacity: .85; }
.portal-hero-name { font-size: 17px; font-weight: 800; line-height: 1.15; }
.portal-hero-role { font-size: 12px; opacity: .92; margin-top: 1px; }
.portal-hero-id { font-size: 11.5px; opacity: .7; margin-top: 1px; }
.portal-hero-details {
    display: flex; flex-wrap: wrap; gap: 4px 14px; margin-top: 5px;
}
.portal-hero-details span {
    display: flex; align-items: center; gap: 4px;
    font-size: 11.5px; opacity: .88; color: #fff;
}
.portal-hero-details i { font-size: 10px; opacity: .75; }
.portal-hero-photo-err { margin-top: 4px; font-size: 11px; color: #fca5a5; }

/* Connection footer (server / database) — desktop only */
.portal-footer {
    display: none;
    align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap;
    margin-top: 24px; padding-top: 14px;
    border-top: 1px solid var(--bs-border-color);
    font-size: 12px; color: var(--erp-text-soft);
}
.portal-footer i { opacity: .7; }
.portal-footer-sep { opacity: .5; }
@media (min-width: 768px) { .portal-footer { display: flex; } }

.portal-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px; }
.portal-tile {
    background: var(--bs-body-bg); border: 1px solid var(--bs-border-color);
    border-radius: 14px; padding: 18px 12px; min-height: 110px;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
    cursor: pointer; text-align: center; transition: transform .15s, box-shadow .2s, border-color .2s;
}
.portal-tile:hover { transform: translateY(-3px); border-color: var(--bs-primary); box-shadow: 0 8px 22px rgba(15,23,42,.12); }
.portal-tile:active { transform: translateY(-1px); }
.portal-tile-ico {
    width: 50px; height: 50px; border-radius: 14px; font-size: 21px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(14,165,233,.12); color: #0ea5e9;
    transition: transform .15s;
}
.portal-tile:hover .portal-tile-ico { transform: scale(1.06); }
.portal-tile-name { font-size: 13px; font-weight: 600; color: var(--bs-body-color); line-height: 1.3; }

/* Section heading above the service tiles */
.portal-sec-head {
    display: flex; align-items: center; gap: 8px;
    font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: .4px;
    color: var(--erp-text-soft); margin: 18px 2px 10px;
}
.portal-sec-head i { color: var(--bs-primary); font-size: 12px; }

.portal-empty { text-align: center; color: var(--erp-text-soft); padding: 48px 16px; }
.portal-empty i { font-size: 32px; opacity: .4; display: block; margin-bottom: 10px; }

.portal-card {
    background: var(--bs-body-bg); border: 1px solid var(--bs-border-color);
    border-radius: 14px; padding: 20px; max-width: 420px; margin: 8px auto;
}
.portal-card-title { display: flex; align-items: center; gap: 8px; font-size: 18px; font-weight: 700; margin: 0 0 6px; }
.portal-card-sub { font-size: 13px; color: var(--erp-text-soft); margin: 0 0 14px; }

/* Portal object (record list) */
.portal-objhead { display: flex; align-items: center; gap: 10px; margin: 2px 0 14px; }
.portal-back {
    width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
    border: 1px solid var(--bs-border-color); background: var(--bs-body-bg);
    display: flex; align-items: center; justify-content: center; cursor: pointer;
    color: var(--erp-text);
}
.portal-back:hover { border-color: var(--bs-primary); color: var(--bs-primary); }
.portal-objtitle { font-size: 18px; font-weight: 700; margin: 0; color: var(--erp-text); }
.portal-records { display: flex; flex-direction: column; gap: 10px; }
.portal-record {
    background: var(--bs-body-bg); border: 1px solid var(--bs-border-color);
    border-radius: 12px; padding: 14px 16px;
}
/* Tappable approval-status pill on a record card (PortalObject list) — own row,
   right-aligned, so a long "Waiting for {name}" can ellipsize without overlapping. */
.portal-rec-badgerow { display: flex; justify-content: flex-end; margin-bottom: 6px; }
.portal-rec-badge {
    display: inline-flex; align-items: center; gap: 5px; max-width: 100%;
    font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .3px;
    padding: 3px 9px; border-radius: 999px; cursor: pointer;
    border: 1px solid transparent; font-family: inherit;
    background: var(--bs-secondary-bg, rgba(0,0,0,.05)); color: var(--erp-text-soft);
    transition: filter .15s, transform .1s;
}
.portal-rec-badge:hover  { filter: brightness(.96); }
.portal-rec-badge:active { transform: scale(.97); }
.portal-rec-badge > i    { flex-shrink: 0; }
.portal-rec-badge-txt    { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portal-rec-badge-caret  { font-size: 9px; opacity: .8; }
.portal-rec-badge.waiting  { background: color-mix(in srgb, var(--erp-warning) 16%, transparent); color: var(--erp-warning); }
.portal-rec-badge.approved { background: color-mix(in srgb, var(--erp-success) 16%, transparent); color: var(--erp-success); }
.portal-rec-badge.rejected { background: color-mix(in srgb, var(--erp-danger) 16%, transparent);  color: var(--erp-danger); }
/* Inline approver list revealed under a card when the badge is tapped */
.portal-rec-appr {
    margin-top: 10px; padding-top: 8px;
    border-top: 1px dashed var(--bs-border-color);
    cursor: default;
}
.portal-record-title { font-size: 15px; font-weight: 700; color: var(--erp-text); margin-bottom: 6px; }
.portal-record-line { display: flex; justify-content: space-between; gap: 12px; font-size: 13px; padding: 2px 0; }
.portal-record-label { color: var(--erp-text-soft); }
.portal-record-val { color: var(--erp-text); font-weight: 500; text-align: right; }

/* Tappable record (drilldown into the form) */
.portal-record--tap { cursor: pointer; transition: border-color .15s, box-shadow .2s, transform .15s; }
.portal-record--tap:hover { border-color: var(--bs-primary); box-shadow: 0 4px 16px rgba(0,0,0,.07); transform: translateY(-1px); }

/* Add button in the object header (pushed to the right) */
.portal-add {
    margin-left: auto; width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0;
    border: none; background: var(--erp-primary); color: #fff; cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    box-shadow: 0 2px 8px rgba(37,99,235,.30);
}
.portal-add:hover { background: var(--erp-primary-hover); }

/* "Filing as <employee>" banner on the record form */
.portal-record-for {
    display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600;
    color: var(--erp-text-soft); padding: 8px 12px; margin-bottom: 12px;
    background: var(--bs-secondary-bg, rgba(0,0,0,.03)); border-radius: 10px;
}
.portal-record-for i { color: var(--erp-primary); }

.portal-head-actions { margin-left: auto; display: flex; gap: 8px; }
.portal-head-actions .portal-add--ghost { margin-left: 0; }
.portal-add--ghost { background: var(--bs-body-bg); border: 1px solid var(--bs-border-color); color: var(--erp-text); box-shadow: none; margin-left: 8px; }
.portal-add--ghost:hover { border-color: var(--bs-primary); color: var(--bs-primary); background: var(--bs-body-bg); }

/* Collapsible field sections (tabs after the first) on the portal record form */
.portal-section { border-top: 1px solid var(--bs-border-color); margin-top: 12px; padding-top: 4px; }
.portal-section-head {
    width: 100%; display: flex; align-items: center; justify-content: space-between;
    background: none; border: none; cursor: pointer; padding: 10px 2px;
    font-size: 14px; font-weight: 700; color: var(--erp-text);
}
.portal-section-head i { color: var(--erp-text-soft); font-size: 12px; transition: transform .15s; }
.portal-section-head.open i { color: var(--bs-primary); }
.portal-section-body { padding-top: 6px; }
/* A child grid rendered inside a tab section (vs its own card) */
.portal-grid-block { margin-top: 10px; }
.portal-grid-block .portal-card-title { margin-bottom: 8px; }

/* Sticky bottom action bar (Save / Delete / Send) */
.portal-actionbar {
    position: sticky; bottom: 0; z-index: 5;
    display: flex; gap: 10px; padding: 12px 0 14px; flex-wrap: wrap;
    background: linear-gradient(to top, var(--bs-body-bg) 70%, transparent);
    max-width: 420px; margin: 0 auto;
}
/* Keep action buttons from being squeezed below a tappable width when several
   appear together (e.g. Reject + Approve, or Delete + Send + Save) on a phone. */
.portal-actionbar > .erp-cta { min-width: 120px; }
.portal-actionbar > .erp-cta.flex-fill { flex: 1 1 140px; }

/* Save in the header (mirrors the main object form): primary colour, dirty-aware.
   Disabled (greyed) until there are unsaved edits; while dirty a pulsing dot
   badge flags pending changes. */
.portal-add--save { position: relative; }
.portal-add--save:disabled {
    background: var(--bs-secondary-bg, #e2e8f0); color: var(--erp-text-soft);
    box-shadow: none; cursor: default;
}
.portal-add--save.is-dirty::after {
    content: ""; position: absolute; top: 5px; inset-inline-end: 5px;
    width: 8px; height: 8px; border-radius: 50%;
    background: #fff; box-shadow: 0 0 0 2px var(--erp-primary);
    animation: portal-dirty-pulse 1.4s ease-in-out infinite;
}
@keyframes portal-dirty-pulse { 0%,100% { opacity: 1; } 50% { opacity: .35; } }

/* Approval status list */
.portal-appr-list { display: flex; flex-direction: column; gap: 4px; }
.portal-appr { display: flex; align-items: flex-start; gap: 10px; padding: 8px 0; border-bottom: 1px solid var(--bs-border-color); }
.portal-appr:last-child { border-bottom: none; }
.portal-appr-dot { width: 10px; height: 10px; border-radius: 50%; margin-top: 4px; flex-shrink: 0; background: var(--erp-text-soft); }
.portal-appr-dot.waiting  { background: var(--erp-warning); }
.portal-appr-dot.approved { background: var(--erp-success); }
.portal-appr-dot.rejected { background: var(--erp-danger); }
.portal-appr-main { flex: 1; min-width: 0; }
.portal-appr-who { font-weight: 600; font-size: 13px; color: var(--erp-text); }
.portal-appr-title { font-size: 12px; color: var(--erp-text-soft); }
.portal-appr-cmt { font-size: 12px; color: var(--erp-text-soft); font-style: italic; }
.portal-appr-status { font-size: 11px; font-weight: 700; text-transform: uppercase; align-self: center; }
.portal-appr-status.waiting  { color: var(--erp-warning); }
.portal-appr-status.approved { color: var(--erp-success); }
.portal-appr-status.rejected { color: var(--erp-danger); }
/* Approver avatar (photo) with a status dot overlay + acted-on timestamp */
.portal-appr-avatar { position: relative; width: 34px; height: 34px; flex-shrink: 0; }
.portal-appr-avatar img {
    width: 34px; height: 34px; border-radius: 50%; object-fit: cover; display: block;
    background: var(--bs-secondary-bg, #e2e8f0); border: 1px solid var(--bs-border-color);
}
.portal-appr-avatar .portal-appr-dot {
    position: absolute; bottom: -1px; inset-inline-end: -1px; margin: 0;
    width: 11px; height: 11px; border: 2px solid var(--bs-body-bg);
}
.portal-appr-time {
    font-size: 11.5px; color: var(--erp-text-soft);
    display: flex; align-items: center; gap: 5px; margin-top: 2px;
}

/* Send-for-approval button in the record header (next to Save / Print) */
.portal-head-actions .portal-add--send { margin-left: 8px; background: var(--erp-warning); box-shadow: 0 2px 8px rgba(0,0,0,.18); }
.portal-add--send:hover:not(:disabled) { filter: brightness(.95); }
.portal-add--send:disabled { opacity: .6; cursor: default; }

/* Documents / attachments */
.portal-files { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
.portal-file { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--bs-border-color); border-radius: 10px; }
.portal-file-name { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; text-decoration: none; color: var(--erp-text); font-size: 13px; font-weight: 500; }
.portal-file-name span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.portal-file-name i { color: var(--erp-primary); }
.portal-file-size { font-size: 11px; color: var(--erp-text-soft); flex-shrink: 0; }
.portal-file-del { border: none; background: none; color: var(--erp-text-soft); cursor: pointer; padding: 4px; border-radius: 6px; flex-shrink: 0; }
.portal-file-del:hover { color: var(--erp-danger); background: rgba(239,68,68,.08); }
.portal-upload-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.portal-upload-row label { cursor: pointer; margin: 0; }

/* Desktop: portal/MSS body fills the available width (no centered cap) + 2-column
   record fields (mobile stays single-column). */
@media (min-width: 768px) {
    .portal-body { max-width: none; }
    .portal-form .portal-card { max-width: 100%; }
    .portal-form .portal-actionbar { max-width: 100%; }
}

/* ── Home: employee profile card ───────────────────────────── */
.portal-profile { display: flex; align-items: center; gap: 14px; max-width: 100%; }
.portal-profile-avatar {
    width: 54px; height: 54px; border-radius: 50%; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    font-size: 20px; font-weight: 700; color: #fff; background: var(--erp-primary);
    box-shadow: 0 4px 12px rgba(37,99,235,.30);
}
.portal-profile-main { min-width: 0; }
.portal-profile-name { font-size: 17px; font-weight: 700; color: var(--erp-text); line-height: 1.2; }
.portal-profile-sub { font-size: 13px; color: var(--erp-text-soft); margin-top: 2px; }
.portal-profile-id { font-size: 12px; color: var(--erp-text-soft); opacity: .8; margin-top: 1px; }

.portal-info-grid {
    display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 8px; margin: 0 auto 8px; max-width: 420px;
}
.portal-info {
    display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--erp-text);
    background: var(--bs-body-bg); border: 1px solid var(--bs-border-color);
    border-radius: 10px; padding: 8px 10px; min-width: 0;
}
.portal-info i { color: var(--erp-primary); width: 16px; text-align: center; flex-shrink: 0; }
.portal-info span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Actionable "Update my details" chip in the info grid. */
.portal-info--action {
    cursor: pointer; font: inherit; font-size: 12.5px; text-align: start;
    color: var(--erp-primary); border-color: var(--erp-primary); background: transparent;
    transition: background .15s ease, transform .1s ease;
}
.portal-info--action:hover { background: color-mix(in srgb, var(--erp-primary) 10%, transparent); transform: translateY(-1px); }
/* Current-value hint under a profile edit field. */
.portal-field-hint { display: block; margin-top: 4px; font-size: 11.5px; color: var(--erp-text-soft); }

/* ── Home: leave balance card ──────────────────────────────── */
.portal-balance {
    display: flex; align-items: center; gap: 14px; max-width: 420px; margin: 0 auto 8px;
    background: linear-gradient(135deg, var(--erp-primary), var(--erp-primary-hover, #1d4ed8));
    color: #fff; border-radius: 14px; padding: 16px 18px;
    box-shadow: 0 4px 16px rgba(37,99,235,.25);
}
.portal-balance-ico {
    width: 46px; height: 46px; border-radius: 12px; flex-shrink: 0;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,.18); font-size: 20px;
}
.portal-balance-num { font-size: 26px; font-weight: 800; line-height: 1; }
.portal-balance-unit { font-size: 13px; font-weight: 600; opacity: .85; margin-inline-start: 6px; }
.portal-balance-lbl { font-size: 13px; opacity: .9; margin-top: 4px; }
.portal-balance-lines {
    max-width: 420px; margin: 0 auto 8px; display: flex; flex-direction: column; gap: 4px;
}
.portal-balance-line {
    display: flex; justify-content: space-between; gap: 12px; font-size: 12.5px;
    padding: 6px 10px; border: 1px solid var(--bs-border-color); border-radius: 8px;
    background: var(--bs-body-bg); color: var(--erp-text);
}

@media (min-width: 768px) {
    .portal-info-grid, .portal-balance, .portal-balance-lines { max-width: 100%; }
}

/* Portal auth (login + change password) */
.portal-auth-bg {
    min-height: 100vh; display: flex; align-items: center; justify-content: center;
    padding: 20px; background: linear-gradient(135deg, var(--erp-primary) 0%, var(--erp-primary-band, #1e3a5f) 100%);
}
.portal-auth-card {
    width: 100%; max-width: 380px; background: var(--bs-body-bg);
    border-radius: 18px; padding: 28px 24px; box-shadow: 0 12px 40px rgba(0,0,0,.25);
}
.portal-auth-header { text-align: center; margin-bottom: 20px; }
.portal-auth-logo {
    width: 66px; height: 66px; margin: 0 auto 14px; border-radius: 20px;
    display: flex; align-items: center; justify-content: center; font-size: 28px;
    background: linear-gradient(135deg, var(--erp-primary), var(--erp-primary-band, #1e3a5f));
    color: #fff; box-shadow: 0 8px 20px rgba(37,99,235,.35);
}
/* Remembered company logo — tile on the brand PRIMARY colour so a white/mono logo reads. */
.portal-auth-logo--img {
    width: 84px; height: 84px; background: var(--erp-primary); padding: 10px;
    box-shadow: 0 6px 18px rgba(15,23,42,.18);
}
.portal-auth-logo--img img { width: 100%; height: 100%; object-fit: contain; display: block; }
.portal-auth-title { font-size: 20px; font-weight: 700; margin: 0 0 4px; color: var(--erp-text); }
.portal-auth-sub { font-size: 13px; color: var(--erp-text-soft); margin: 0; }
.portal-auth-hint { margin-top: 14px; font-size: 12px; color: var(--erp-text-soft); text-align: center; line-height: 1.5; }

.portal-field { margin-bottom: 14px; }
.portal-field > label { display: block; font-size: 13px; font-weight: 600; color: var(--erp-text); margin-bottom: 5px; }
.portal-field .erp-input { width: 100%; }
/* iOS Safari force-zooms the page when a focused field is < 16px. The portal is
   a phone-first surface (.portal-shell, not .erp-shell.is-mobile), so size its
   inputs at 16px to suppress the auto-zoom-on-focus. */
.portal-shell input,
.portal-shell select,
.portal-shell textarea,
.portal-shell .erp-input,
.portal-shell .dxbl-edit input { font-size: 16px; }
.portal-remember { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--erp-text); cursor: pointer; }
.portal-login-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 14px; }
.portal-forgot-link { font-size: 13px; color: var(--erp-primary); text-decoration: none; white-space: nowrap; }
.portal-forgot-link:hover { text-decoration: underline; }
.portal-auth-footer a { color: var(--erp-primary); text-decoration: none; }
.portal-auth-footer a:hover { text-decoration: underline; }
.portal-card-sub { font-size: 13px; color: var(--erp-text-soft); margin: 0 0 14px; }
.w-100 { width: 100%; }

/* Login: gradient backdrop accents + card top sheen */
.portal-auth-bg {
    background:
        radial-gradient(at 20% 20%, rgba(255,255,255,.10), transparent 45%),
        radial-gradient(at 80% 80%, rgba(255,255,255,.06), transparent 45%),
        linear-gradient(135deg, var(--erp-primary) 0%, var(--erp-primary-band, #1e3a5f) 100%);
}
.portal-auth-card { border: 1px solid rgba(255,255,255,.06); animation: portal-pop .25s ease; }
@keyframes portal-pop { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }

/* Login: input with leading icon + password eye */
.portal-inwrap { position: relative; }
.portal-inwrap-ico {
    position: absolute; top: 50%; left: 12px; transform: translateY(-50%);
    color: var(--erp-text-soft); font-size: 14px; pointer-events: none;
}
.portal-in { width: 100%; height: 46px; padding-left: 38px !important; padding-right: 40px !important; }
.portal-inwrap-eye {
    position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
    background: none; border: none; color: var(--erp-text-soft); cursor: pointer; padding: 6px; font-size: 14px;
}
.portal-inwrap-eye:hover { color: var(--bs-primary); }
[dir="rtl"] .portal-inwrap-ico { left: auto; right: 12px; }
[dir="rtl"] .portal-in { padding-left: 40px !important; padding-right: 38px !important; }
[dir="rtl"] .portal-inwrap-eye { right: auto; left: 8px; }
.portal-auth-footer { margin-top: 18px; text-align: center; font-size: 11px; color: var(--erp-text-soft); }

/* ── Print-report format menu (DynamicObject toolbar) ─────────────────── */
.do-print-menu { position: relative; display: inline-flex; }
.do-print-backdrop { position: fixed; inset: 0; z-index: 1090; }
.do-print-dropdown {
    position: absolute; top: calc(100% + 4px); inset-inline-end: 0; z-index: 1091;
    min-width: 220px; max-width: 320px; padding: 6px;
    background: var(--bs-body-bg); border: 1px solid var(--erp-border);
    border-radius: 10px; box-shadow: 0 10px 30px rgba(15,23,42,.16);
}
.do-print-item {
    display: flex; align-items: center; gap: 9px; width: 100%;
    padding: 8px 10px; border: none; background: none; cursor: pointer;
    font-size: 13px; color: var(--erp-text); text-align: start; border-radius: 7px;
}
.do-print-item:hover { background: var(--erp-primary-tint); color: var(--erp-primary); }
.do-print-item > span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.do-print-item > i:first-child { color: #d6336c; }
.do-print-default { color: #f59e0b; font-size: 11px; }

/* ── Record-history modal (DynamicObject toolbar) ──────────────────────── */
.do-hist-chip {
    display: inline-flex; align-items: center; gap: 6px;
    font-size: 12px; font-weight: 600;
    border-radius: 20px; padding: 4px 12px;
}

/* ── Child-grid Excel-mapping setup (developer) ────────────────────────── */
.cg-map-opts { display: flex; align-items: flex-end; gap: 16px; flex-wrap: wrap; margin-bottom: 10px; }
.cg-map-opts .dyn-field { min-width: 200px; }
.cg-map-check { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; }
.cg-map-hint { font-size: 12px; color: var(--erp-text-soft,#64748b); margin: 6px 0 10px; }
.cg-map-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
.cg-map-row { display: flex; align-items: center; gap: 6px; }
.cg-map-row select { flex: 1; min-width: 0; }
.cg-map-num {
    flex: 0 0 auto; width: 26px; height: 26px; border-radius: 6px;
    display: inline-flex; align-items: center; justify-content: center;
    background: var(--erp-primary-tint); color: var(--erp-primary);
    font-size: 12px; font-weight: 700;
}

/* ── Action-button designer modal (DynamicObject design mode) ──────────── */
.ad-fieldpick { display: flex; align-items: flex-end; gap: 8px; margin-bottom: 12px; flex-wrap: wrap; }
.ad-fieldpick .dc-label { display: block; }
.ad-fieldpick select { max-width: 300px; }
.ad-fieldpick > button { flex: 0 0 auto; }
.ad-create { margin-bottom: 12px; padding: 12px; border: 1px dashed var(--erp-border,#cbd5e1); border-radius: 8px; background: var(--erp-surface-alt,#f8fafc); }
.ad-head { display: flex; align-items: center; gap: 8px; margin: 4px 0 8px; font-size: 13px; font-weight: 600; }
.ad-head > button { margin-inline-start: auto; }
.ad-table { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.ad-table th { text-align: left; font-size: 11px; color: var(--erp-text-soft,#64748b); padding: 3px 6px; }
.ad-table td { padding: 5px 6px; border-top: 1px solid var(--erp-border,#eef1f5); vertical-align: middle; }
.ad-table code { font-size: 12px; }
.ad-edit { margin-top: 12px; padding: 12px; border: 1px solid var(--erp-border,#e2e8f0); border-radius: 8px; background: var(--erp-surface-alt,#f8fafc); }
.ad-form { display: grid; grid-template-columns: 1fr 1fr; gap: 10px 14px; }
.ad-form .dyn-field { min-width: 0; }
.ad-flags { display: flex; gap: 16px; flex-wrap: wrap; margin: 10px 0; font-size: 13px; }
.ad-flags label { display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.ad-buttons { display: flex; gap: 8px; }
@media (max-width: 640px) { .ad-form { grid-template-columns: 1fr; } }

/* ── PWA "Add to Home Screen" help sheet (iOS, portal) ─────────────────── */
.pwa-help-backdrop { position: fixed; inset: 0; z-index: 1190; background: rgba(15,23,42,.45); }
.pwa-help-sheet {
    position: fixed; z-index: 1191; left: 50%; bottom: 16px; transform: translateX(-50%);
    width: min(420px, calc(100vw - 24px)); padding: 18px 18px 16px;
    background: var(--bs-body-bg); border: 1px solid var(--erp-border);
    border-radius: 16px; box-shadow: 0 -8px 40px rgba(15,23,42,.25);
}
.pwa-help-title { font-weight: 700; font-size: 15px; display: flex; align-items: center; gap: 8px; margin-bottom: 10px; color: var(--erp-text); }
.pwa-help-steps { margin: 0 0 14px; padding-inline-start: 20px; display: flex; flex-direction: column; gap: 8px; font-size: 13.5px; color: var(--erp-text); }
.pwa-help-steps i { color: var(--erp-primary); margin: 0 3px; }

/* ══════════════════════════════════════════════════════════════════════════
   ENVIRONMENT BADGE  (TEST / LIVE) — driven by ZoomERP:Environment, always visible
   in both the main-app top bar and the portal header so users never confuse a
   test publish with the live one.
   ══════════════════════════════════════════════════════════════════════════ */
.env-badge {
    display: inline-flex; align-items: center; gap: 5px;
    padding: 2px 9px; border-radius: 999px;
    font-size: 11px; font-weight: 800; letter-spacing: .6px; line-height: 1.6;
    text-transform: uppercase; white-space: nowrap; user-select: none;
    border: 1px solid transparent;
}
.env-badge i { font-size: 10px; }
/* TEST: loud amber so it can't be missed */
.env-badge--test {
    background: #b45309; color: #fff; border-color: #92400e;
    box-shadow: 0 0 0 2px rgba(180,83,9,.20);
}
/* LIVE: calm green confirmation */
.env-badge--live {
    background: rgba(22,163,74,.12); color: #15803d; border-color: rgba(22,163,74,.35);
}
[data-bs-theme="dark"] .env-badge--live { color: #4ade80; }
/* Portal header places it under the name; keep it compact */
.env-badge--portal { padding: 1px 8px; font-size: 10px; margin-inline-start: 8px; }
