/* ═══════════════════════════════════════════════════════════════════════════
   GULFLEDGER DESIGN SYSTEM v2 · gl-design-system.v2.css
   ──────────────────────────────────────────────────────────────────────────
   COMPONENT LAYER — loaded after gl-design-system.css (tokens). Additive:
   v1 token file stays untouched so browser caches remain valid.

   Contents:
     1. Typography lockdown   — one family, tabular numerals, no DM Mono
     2. Icons                 — .gl-i sizing/coloring for gl-icons.svg
     3. Buttons               — .gl-btn (+primary/ghost/danger/sm)
     4. Cards                 — .gl-card, .gl-card-hdr, .gl-card-title
     5. Badges & pills        — .gl-badge (+status variants)
     6. KPI stats             — .gl-kpi row + card
     7. Skeleton loading      — .gl-skel (shimmer)
     8. Empty states          — .gl-empty
     9. Tables                — .gl-table base rhythm
    10. Page rhythm           — .gl-page, .gl-page-head utilities

   THREE PRINCIPLES (same as v1, in priority order):
     1. Trusted    — institutional calm, restraint, consistency
     2. Effortless — minimal cognitive load, easy on the eye
     3. Saudi      — embedded culturally, not bolted on
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 1. TYPOGRAPHY LOCKDOWN ──────────────────────────────────────────────
   One family everywhere. Numbers: same family + tabular-nums (no DM Mono).
   Kills the coding-font aesthetic; numbers align in tables natively. */
.num, .row-num, .row-amount, .stat-val, .mono,
.cashflow-val, .gl-amount {
  font-family: var(--font-sans) !important;
  font-variant-numeric: tabular-nums;
  /* plaintext: digits render LTR internally while the element's ALIGNMENT
     follows the page direction — RTL pages anchor values right, LTR left.
     (direction:ltr here was left-anchoring KPI values on Arabic pages.) */
  unicode-bidi: plaintext;
  unicode-bidi: isolate;
  letter-spacing: -0.01em;
}
h1, h2, h3, h4, .gl-display { font-family: var(--font-sans); }

/* ── 2. ICONS ────────────────────────────────────────────────────────────
   <svg class="gl-i"><use href="/gl-icons.svg#i-invoice"/></svg>
   Inherit color from parent text. Sizes: sm 14 / base 18 / lg 24 / xl 32. */
.gl-i {
  width: 18px; height: 18px;
  flex-shrink: 0;
  vertical-align: -3px;
  display: inline-block;
}
.gl-i-sm { width: 14px; height: 14px; vertical-align: -2px; }
.gl-i-lg { width: 24px; height: 24px; vertical-align: -5px; }
.gl-i-xl { width: 32px; height: 32px; }
/* Icon inside a tinted circle — replaces big decorative emoji */
.gl-i-disc {
  width: 42px; height: 42px;
  border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  flex-shrink: 0;
}
.gl-i-disc .gl-i { width: 20px; height: 20px; vertical-align: 0; }
.gl-i-disc.is-warning { background: var(--color-status-warning-bg); color: var(--color-status-warning); }
.gl-i-disc.is-info    { background: var(--color-status-info-bg);    color: var(--color-status-info); }
.gl-i-disc.is-danger  { background: var(--color-status-danger-bg);  color: var(--color-status-danger); }
.gl-i-disc.is-neutral { background: var(--color-bg-subtle);         color: var(--color-text-muted); }

/* ── 3. BUTTONS ──────────────────────────────────────────────────────── */
.gl-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 16px;
  min-height: var(--tap-min, 40px);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg-surface);
  color: var(--color-text-default);
  font-family: var(--font-sans);
  font-size: var(--text-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background var(--motion-fast), border-color var(--motion-fast), color var(--motion-fast);
  text-decoration: none;
  white-space: nowrap;
}
.gl-btn:hover { background: var(--color-bg-subtle); border-color: var(--color-border-strong); }
.gl-btn:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.gl-btn.is-primary {
  background: var(--color-primary);
  border-color: var(--color-primary);
  color: var(--color-text-on-primary);
}
.gl-btn.is-primary:hover { background: var(--color-primary-hover); border-color: var(--color-primary-hover); }
.gl-btn.is-ghost { border-color: transparent; background: transparent; color: var(--color-text-muted); }
.gl-btn.is-ghost:hover { background: var(--color-bg-subtle); color: var(--color-text-default); }
.gl-btn.is-danger { color: var(--color-status-danger); border-color: var(--color-status-danger-bg); }
.gl-btn.is-danger:hover { background: var(--color-status-danger-bg); }
.gl-btn.is-sm { padding: 6px 12px; min-height: 32px; font-size: var(--text-xs); }
.gl-btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* ── 4. CARDS ────────────────────────────────────────────────────────── */
.gl-card {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
}
.gl-card.is-interactive {
  cursor: pointer;
  transition: border-color var(--motion-base) var(--ease-out), box-shadow var(--motion-base) var(--ease-out), transform var(--motion-base) var(--ease-out);
  text-decoration: none; color: inherit; display: block;
}
.gl-card.is-interactive:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-md);
  transform: translateY(-1px);
}
.gl-card-hdr {
  display: flex; justify-content: space-between; align-items: center; gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.gl-card-title {
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-text-strong);
  display: inline-flex; align-items: center; gap: 8px;
}
.gl-card-title .gl-i { color: var(--color-text-muted); }
.gl-card-link {
  font-size: var(--text-xs); font-weight: 600;
  color: var(--color-primary); text-decoration: none;
  display: inline-flex; align-items: center; gap: 4px;
}
.gl-card-link:hover { text-decoration: underline; }

/* ── 5. BADGES & PILLS ───────────────────────────────────────────────── */
.gl-badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 11px; font-weight: 700;
  line-height: 1.4;
  background: var(--color-status-neutral-bg);
  color: var(--color-status-neutral);
}
.gl-badge.is-success { background: var(--color-status-success-bg); color: var(--color-status-success); }
.gl-badge.is-warning { background: var(--color-status-warning-bg); color: var(--color-status-warning); }
.gl-badge.is-danger  { background: var(--color-status-danger-bg);  color: var(--color-status-danger); }
.gl-badge.is-info    { background: var(--color-status-info-bg);    color: var(--color-status-info); }
.gl-badge.is-primary { background: var(--color-primary-soft);      color: var(--color-primary); }
.gl-badge .gl-i-sm { width: 12px; height: 12px; vertical-align: -1.5px; }

/* ── 6. KPI STATS ────────────────────────────────────────────────────── */
.gl-kpi-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-4);
  margin-bottom: var(--space-6);
}
@media (max-width: 980px) { .gl-kpi-row { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .gl-kpi-row { grid-template-columns: 1fr 1fr; gap: var(--space-2); } }
.gl-kpi {
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5);
  min-width: 0;
}
.gl-kpi-label {
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--color-text-muted);
  display: flex; align-items: center; gap: 6px;
  margin-bottom: var(--space-2);
}
.gl-kpi-val {
  font-size: var(--text-2xl);
  font-weight: 800;
  color: var(--color-text-strong);
  font-variant-numeric: tabular-nums;
  direction: ltr; unicode-bidi: isolate;
  letter-spacing: -0.015em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.gl-kpi-sub {
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  margin-top: var(--space-1);
}
.gl-kpi-val.is-positive { color: var(--color-status-success); }
.gl-kpi-val.is-negative { color: var(--color-status-danger); }

/* ── 7. SKELETON LOADING ─────────────────────────────────────────────── */
.gl-skel {
  position: relative;
  overflow: hidden;
  background: var(--color-bg-subtle);
  border-radius: var(--radius-sm);
  color: transparent !important;
  user-select: none;
  min-height: 1em;
}
.gl-skel::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(90deg, transparent, rgba(255,255,255,0.55), transparent);
  animation: gl-shimmer 1.4s infinite;
  transform: translateX(-100%);
}
[dir="rtl"] .gl-skel::after { animation-name: gl-shimmer-rtl; }
@keyframes gl-shimmer     { to { transform: translateX(100%);  } }
@keyframes gl-shimmer-rtl { to { transform: translateX(-200%); } }
@media (prefers-reduced-motion: reduce) { .gl-skel::after { animation: none; } }

/* ── 8. EMPTY STATES ─────────────────────────────────────────────────── */
.gl-empty {
  text-align: center;
  padding: var(--space-10) var(--space-5);
  color: var(--color-text-muted);
}
.gl-empty .gl-i-disc { margin-bottom: var(--space-3); }
.gl-empty-title { font-size: var(--text-sm); font-weight: 600; color: var(--color-text-default); margin-bottom: var(--space-1); }
.gl-empty-sub { font-size: var(--text-xs); color: var(--color-text-faint); max-width: 320px; margin: 0 auto var(--space-4); line-height: 1.5; }

/* ── 9. TABLE RHYTHM ─────────────────────────────────────────────────── */
.gl-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.gl-table th {
  text-align: start;
  font-size: var(--text-xs); font-weight: 600;
  color: var(--color-text-muted);
  padding: var(--space-2) var(--space-3);
  border-bottom: 1px solid var(--color-border);
  white-space: nowrap;
}
.gl-table td {
  padding: var(--space-3);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-default);
  vertical-align: middle;
}
.gl-table tbody tr { transition: background var(--motion-fast); }
.gl-table tbody tr:hover { background: var(--color-bg-page); }
.gl-table td.is-amount { font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate; text-align: end; font-weight: 600; }

/* ── 10. PAGE RHYTHM ─────────────────────────────────────────────────── */
.gl-page-head {
  display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-4);
  margin-bottom: var(--space-6);
  flex-wrap: wrap;
}
.gl-page-title { font-size: var(--text-xl); font-weight: 800; color: var(--color-text-strong); letter-spacing: -0.01em; }
.gl-page-sub { font-size: var(--text-sm); color: var(--color-text-muted); margin-top: 2px; }
.gl-section-gap { margin-bottom: var(--space-6); }


/* ── 11. CANONICAL MODAL ─────────────────────────────────────────────
   THE modal for the whole product. No page defines its own modal CSS.
   Structure:
     <div class="gl-modal-overlay" id="...">
       <div class="gl-modal is-sm|（default）|is-lg">
         <div class="gl-modal-head">
           <div><h3>Title</h3><div class="gl-modal-sub">subtitle</div></div>
           <button class="gl-modal-close">✕</button>
         </div>
         <div class="gl-modal-body">…fields…</div>
         <div class="gl-modal-foot"><div class="gl-modal-actions">…buttons…</div></div>
       </div>
     </div> */
.gl-modal-overlay {
  position: fixed; inset: 0;
  background: rgba(20, 28, 24, 0.45);
  backdrop-filter: blur(3px);
  z-index: 9000;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 6vh 16px 16px;
  overflow-y: auto;
  animation: glOvIn .14s ease-out;
}
@keyframes glOvIn { from { opacity: 0; } to { opacity: 1; } }
.gl-modal {
  background: var(--color-bg-surface);
  border-radius: 14px;
  width: 100%;
  max-width: 560px;
  box-shadow: 0 24px 64px rgba(0,0,0,0.22);
  display: flex;
  flex-direction: column;
  animation: glMdIn .18s cubic-bezier(0.16,1,0.3,1);
}
.gl-modal.is-sm { max-width: 440px; }
.gl-modal.is-lg { max-width: 760px; }
@keyframes glMdIn { from { opacity: 0; transform: translateY(10px) scale(0.985); } to { opacity: 1; transform: none; } }
.gl-modal-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 14px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--color-border);
}
.gl-modal-head h3 {
  font-size: 16px; font-weight: 800; color: var(--color-text-strong);
  letter-spacing: -0.01em; line-height: 1.3; margin: 0;
}
.gl-modal-sub { font-size: 12px; color: var(--color-text-muted); margin-top: 3px; line-height: 1.45; }
.gl-modal-close {
  width: 32px; height: 32px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-surface); color: var(--color-text-muted);
  font-size: 14px; cursor: pointer; line-height: 1;
  transition: all var(--motion-fast);
}
.gl-modal-close:hover { background: var(--color-bg-subtle); color: var(--color-text-strong); }
.gl-modal-body { padding: 18px 22px; overflow-y: auto; max-height: 72vh; }
.gl-modal-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 22px;
  border-top: 1px solid var(--color-border);
}
.gl-modal-actions { display: flex; gap: 8px; margin-inline-start: auto; }
/* Phone: bottom sheet */
@media (max-width: 560px) {
  .gl-modal-overlay { padding: 0; align-items: flex-end; }
  .gl-modal, .gl-modal.is-sm, .gl-modal.is-lg {
    max-width: 100%; border-radius: 16px 16px 0 0;
    animation: glMdUp .2s cubic-bezier(0.16,1,0.3,1);
  }
  @keyframes glMdUp { from { transform: translateY(40px); opacity: 0.6; } to { transform: none; opacity: 1; } }
  .gl-modal-body { max-height: 66vh; }
}

/* ── 12. CANONICAL FORM FIELDS ──────────────────────────────────────
   <div class="gl-field">
     <label class="gl-label">Name <span class="gl-req">*</span></label>
     <input type="text" …>
     <div class="gl-hint">helper</div>
   </div>
   Grids: <div class="gl-row cols-2"> two .gl-field children </div> */
.gl-field { margin-bottom: 14px; min-width: 0; }
.gl-field:last-child { margin-bottom: 0; }
.gl-label {
  display: flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600; color: var(--color-text-strong);
  margin-bottom: 6px;
}
.gl-req { color: var(--color-text-faint); font-weight: 400; font-size: 12px; }
.gl-field input:not([type="checkbox"]):not([type="radio"]),
.gl-field select,
.gl-field textarea {
  width: 100%;
  min-height: 40px;
  padding: 9px 12px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-bg-surface);
  font-family: var(--font-sans);
  font-size: 13.5px;
  color: var(--color-text-strong);
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.gl-field textarea { resize: vertical; min-height: 72px; }
.gl-field input:focus, .gl-field select:focus, .gl-field textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.gl-field input::placeholder, .gl-field textarea::placeholder { color: var(--color-text-faint); }
.gl-field input[readonly] { background: var(--color-bg-subtle); cursor: not-allowed; }
.gl-field.has-error input, .gl-field.has-error select {
  border-color: var(--color-status-danger);
  box-shadow: 0 0 0 3px var(--color-status-danger-bg);
}
.gl-hint { font-size: 11.5px; color: var(--color-text-muted); margin-top: 5px; line-height: 1.45; }
.gl-error { font-size: 11.5px; color: var(--color-status-danger); margin-top: 5px; }
.gl-row { display: grid; gap: 12px; }
.gl-row.cols-2 { grid-template-columns: 1fr 1fr; }
.gl-row.cols-3 { grid-template-columns: 1fr 1fr 1fr; }
@media (max-width: 640px) { .gl-row.cols-2, .gl-row.cols-3 { grid-template-columns: 1fr; } }
.gl-form-divider {
  display: flex; align-items: center; gap: 10px;
  margin: 18px 0 14px;
  font-size: 11px; font-weight: 700; color: var(--color-text-faint);
  text-transform: uppercase; letter-spacing: .05em;
}
.gl-form-divider::after { content: ''; flex: 1; height: 1px; background: var(--color-border); }


/* ── 13. LEGACY FORM ALIASES ────────────────────────────────────────
   inventory / purchasing / finance / invoices already use a shared
   vocabulary (.modal-overlay/.modal/.modal-box + .field/.field-label/
   .field-row) but each page had drifted local values. Those local rules
   are deleted; THIS layer styles the legacy selectors with the canonical
   values, so every existing form adopts the standard without markup
   changes. New forms should use .gl-modal-* / .gl-field directly. */
.modal-overlay {
  display: none; position: fixed; inset: 0;
  background: rgba(20,28,24,0.45);
  backdrop-filter: blur(3px);
  z-index: 9000;
  align-items: flex-start; justify-content: center;
  padding: 6vh 16px 16px; overflow-y: auto;
}
.modal-overlay.open, .modal-overlay.show { display: flex; animation: glOvIn .14s ease-out; }
.modal, .modal-box {
  background: var(--color-bg-surface);
  border-radius: 14px;
  width: 100%; max-width: 560px;
  box-shadow: 0 24px 64px rgba(0,0,0,0.22);
  display: flex; flex-direction: column;
  animation: glMdIn .18s cubic-bezier(0.16,1,0.3,1);
  max-height: 88vh;
}
.modal-box { max-width: 680px; } /* invoice forms are denser — keep their proportion */
.modal-head {
  display: flex; justify-content: space-between; align-items: flex-start; gap: 14px;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--color-border);
  flex-shrink: 0;
}
.modal-title {
  font-size: 16px; font-weight: 800; color: var(--color-text-strong);
  letter-spacing: -0.01em; line-height: 1.3;
}
.modal-sub { font-size: 12px; color: var(--color-text-muted); margin-top: 3px; line-height: 1.45; }
.modal-close {
  width: 32px; height: 32px; flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-surface); color: var(--color-text-muted);
  font-size: 14px; cursor: pointer; line-height: 1;
  transition: all var(--motion-fast);
}
.modal-close:hover { background: var(--color-bg-subtle); color: var(--color-text-strong); }
.modal-body { padding: 18px 22px; overflow-y: auto; flex: 1; }
.modal-foot {
  display: flex; justify-content: space-between; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 14px 22px;
  border-top: 1px solid var(--color-border);
  flex-shrink: 0;
}
@media (max-width: 560px) {
  .modal-overlay { padding: 0; align-items: flex-end; }
  .modal, .modal-box { max-width: 100%; border-radius: 16px 16px 0 0; animation: glMdUp .2s cubic-bezier(0.16,1,0.3,1); }
}

/* Legacy fields → canonical control look */
.field { margin-bottom: 14px; min-width: 0; }
.field-label {
  display: flex; align-items: center; gap: 5px;
  font-size: 12.5px; font-weight: 600; color: var(--color-text-strong);
  margin-bottom: 6px;
}
.field-hint { font-size: 11.5px; color: var(--color-text-muted); margin-top: 5px; line-height: 1.45; }
.field input:not([type="checkbox"]):not([type="radio"]),
.field select,
.field textarea {
  width: 100%; min-height: 40px;
  padding: 9px 12px;
  border: 1px solid var(--color-border);
  border-radius: 8px;
  background: var(--color-bg-surface);
  font-family: var(--font-sans);
  font-size: 13.5px;
  color: var(--color-text-strong);
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.field textarea { resize: vertical; min-height: 72px; }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.field input::placeholder, .field textarea::placeholder { color: var(--color-text-faint); }
.field input[readonly] { background: var(--color-bg-subtle); cursor: not-allowed; }
.field-row { display: grid; gap: 12px; margin-bottom: 0; }
.field-row.double { grid-template-columns: 1fr 1fr; }
.field-row.triple { grid-template-columns: 1fr 1fr 1fr; }
.field-row.single { grid-template-columns: 1fr; }
@media (max-width: 640px) { .field-row.double, .field-row.triple { grid-template-columns: 1fr; } }


/* ── 14. CANONICAL TOP NAV ──────────────────────────────────────────
   One nav for the whole product. Pages must NOT define .topnav/.app-nav
   rules locally. */
.topnav{height:44px;min-height:44px;box-sizing:border-box;background:var(--navy);padding:10px 24px;display:flex;justify-content:space-between;align-items:center;position:sticky;top:0;z-index:200;}
.nav-logo{display:flex;align-items:center;gap:10px;}
.nav-name{font-family:var(--font-sans);font-weight:800;letter-spacing:-0.02em;font-size:20px;color:#fff;}
.nav-bars{display:flex;flex-direction:column;gap:3px;cursor:pointer;}
.nav-bar{width:18px;height:2px;background:#fff;border-radius:2px;}
.nav-right{display:flex;align-items:center;gap:10px;}
.app-nav{height:44px;min-height:44px;box-sizing:border-box;background:var(--blue);padding:8px 20px;display:flex;align-items:center;gap:2px;overflow-x:auto;scrollbar-width:none;position:sticky;top:44px;z-index:199;}
.app-nav::-webkit-scrollbar{display:none;}
.app-nav-link{padding:5px 14px;font-size:14px;font-weight:500;color:rgba(255,255,255,0.7);text-decoration:none;border-radius:7px;white-space:nowrap;transition:all .12s;}
.app-nav-link:hover{color:#fff;background:rgba(255,255,255,0.10);}
.app-nav-link.active{color:#fff;background:rgba(255,255,255,0.16);font-weight:700;}

/* ── 15. CANONICAL DATA GRID ────────────────────────────────────────
   .tbl (invoices/inventory/finance/purchasing), .r-table (reports),
   .team-table (settings) all alias to one grid language. Financial
   statements (.report-table) keep their own institutional styling. */
.tbl, .r-table, .team-table {
  width: 100%; border-collapse: collapse; font-size: var(--text-sm);
}
.tbl th, .r-table th, .team-table th {
  text-align: start;
  padding: 10px 14px;
  background: var(--color-bg-subtle);
  color: var(--color-text-muted);
  font-size: 11px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em;
  white-space: nowrap;
  border-bottom: 1px solid var(--color-border);
}
.tbl td, .r-table td, .team-table td {
  padding: 11px 14px;
  border-bottom: 1px solid var(--color-border);
  vertical-align: middle;
  color: var(--color-text-default);
}
.tbl tbody tr, .r-table tbody tr, .team-table tbody tr { transition: background var(--motion-fast); }
.tbl tbody tr:hover, .r-table tbody tr:hover, .team-table tbody tr:hover { background: var(--color-bg-page); }
.tbl tr:last-child td, .r-table tr:last-child td, .team-table tr:last-child td { border-bottom: none; }
.tbl td.num, .r-table td.num, .team-table td.num,
.tbl td.is-amount, .r-table td.is-amount {
  font-variant-numeric: tabular-nums; direction: ltr; unicode-bidi: isolate;
  text-align: end; font-weight: 600;
}
.table-wrap { overflow-x: auto; border: 1px solid var(--color-border); border-radius: var(--radius-lg); background: var(--color-bg-surface); }


/* ── 16. CANONICAL TOOLBAR (search + filters above tables) ──────────
   One filter language for every list view. Controls are 38px, wrap
   gracefully, and selects stay compact instead of crowding the row. */
.toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 10px; flex-wrap: wrap;
  margin-bottom: 14px;
}
.toolbar-left { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; flex: 1; min-width: 0; }
.search-wrap { position: relative; flex: 1 1 220px; max-width: 320px; min-width: 170px; }
.search-icon {
  position: absolute; inset-inline-start: 11px; top: 50%; transform: translateY(-50%);
  color: var(--color-text-faint); pointer-events: none; display: inline-flex;
}
.search-wrap input, .search-input {
  width: 100%; min-height: 38px;
  padding: 8px 12px; padding-inline-start: 34px;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-surface);
  font-family: var(--font-sans); font-size: 13px;
  color: var(--color-text-strong);
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.search-wrap input:focus, .search-input:focus {
  outline: none; border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
.filter-select, .toolbar select {
  min-height: 38px; padding: 8px 10px;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-surface);
  font-family: var(--font-sans); font-size: 12.5px;
  color: var(--color-text-default);
  max-width: 190px;
  transition: border-color var(--motion-fast), box-shadow var(--motion-fast);
}
.filter-select:focus, .toolbar select:focus {
  outline: none; border-color: var(--color-primary);
  box-shadow: 0 0 0 3px var(--color-primary-soft);
}
@media (max-width: 640px) {
  .search-wrap { max-width: 100%; flex-basis: 100%; }
  .filter-select, .toolbar select { flex: 1; max-width: none; }
}

/* Language switch relocated inside the profile dropdown */
.profile-lang-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 8px 14px;
  font-size: 13px; color: var(--color-text-default);
}
.profile-lang-row .lang-switch { display: inline-flex; gap: 2px; }
.profile-lang-row .lang-btn {
  padding: 3px 9px; font-size: 12px; cursor: pointer;
  border: 1px solid var(--color-border); background: var(--color-bg-surface);
  color: var(--color-text-muted); border-radius: 6px; font-family: var(--font-sans); font-weight: 600;
}
.profile-lang-row .lang-btn.on { background: var(--color-primary); border-color: var(--color-primary); color: #fff; }


/* ── 18. PROFILE IDENTITY HEADER ────────────────────────────────────
   Account context at the top of the avatar menu (GitHub/Linear/QBO
   pattern): business name strong, user email muted. Injected by
   gl-command.js from currentBiz/currentUser. */
.profile-id { padding: 11px 14px 9px; }
.profile-id-biz {
  font-size: 13.5px; font-weight: 800; color: var(--color-text-strong);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 230px;
}
.profile-id-user {
  font-size: 11.5px; color: var(--color-text-muted); margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 230px;
  direction: ltr; text-align: start; unicode-bidi: isolate;
}

/* ── 19. LISTBAR PROGRESSIVE FILTERS ────────────────────────────────
   Toolbars keep search + ONE primary filter inline; extra filters move
   into a popover behind a "فلاتر" button with an active-count badge.
   Applied automatically by gl-command.js (glListbar). */
.lb-btn {
  display: inline-flex; align-items: center; gap: 7px;
  min-height: 38px; padding: 8px 12px;
  border: 1px solid var(--color-border); border-radius: 8px;
  background: var(--color-bg-surface);
  font-family: var(--font-sans); font-size: 12.5px; font-weight: 600;
  color: var(--color-text-default); cursor: pointer;
  transition: border-color var(--motion-fast), background var(--motion-fast);
  position: relative;
}
/* ── Per-filter clear ✕ + active highlight (glDecorateFilter) ──────────
   A filter-select that holds a non-default value gets a green "active"
   look and an inline ✕ to clear just that one filter. Default = plain. */
.gl-filter-holder { position: relative; display: inline-flex; align-items: center; }
.gl-filter-holder .filter-select.is-active {
  border-color: var(--color-primary);
  color: var(--color-primary);
  background: var(--color-primary-soft);
  font-weight: 600;
  padding-inline-end: 30px;   /* room for the ✕ */
}
.gl-filter-clear {
  position: absolute; inset-inline-end: 7px; top: 50%; transform: translateY(-50%);
  width: 17px; height: 17px; border: none; border-radius: 50%;
  background: var(--color-primary); color: #fff;
  font-size: 9px; line-height: 1; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  padding: 0; transition: background var(--motion-fast);
}
.gl-filter-clear:hover { background: var(--color-primary-strong, #005028); }
/* Pill group (.filter-group) active highlight + its clear ✕ */
.filter-group.has-active { border-color: var(--color-primary); }
.filter-group.has-active .filter-btn.active { background: var(--color-primary); color: #fff; }
.gl-pills-clear { inset-inline-end: -7px; top: -7px; transform: none; width: 16px; height: 16px; border: 1.5px solid var(--color-bg-surface); }
/* Inside the Filters popover, selects are full-width block; keep the ✕ aligned */
.lb-pop .gl-filter-holder { display: block; margin-bottom: 8px; }
.lb-pop .gl-filter-holder:last-child { margin-bottom: 0; }
.lb-pop .gl-filter-holder .filter-select { margin-bottom: 0; }
/* ── Toolbar action group (pinned right, never wraps away from edge) ──── */
/* ── Compliance hint — the clear blue used ONLY for must-not-miss
   regulatory points (GOSI, ZATCA, VAT thresholds, EOSB basis). Reserved
   so the blue keeps meaning "compliance"; ordinary hints stay muted. */
.gl-hint-compliance, .field-hint.is-compliance, .section-sub.is-compliance {
  color: var(--color-status-info) !important;
  font-weight: 500;
}
.toolbar-right { display: inline-flex; align-items: center; gap: 8px; flex-shrink: 0; margin-inline-start: auto; }
.toolbar-right .btn { min-height: 38px; }
/* Icon-only refresh button — square, aligned with the rest */
.btn-icon {
  width: 38px; height: 38px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
}
.lb-btn:hover { background: var(--color-bg-subtle); border-color: var(--color-border-strong); }
.lb-btn .gl-i { width: 15px; height: 15px; color: var(--color-text-muted); }
.lb-badge {
  min-width: 17px; height: 17px; padding: 0 5px; border-radius: 9px;
  background: var(--color-primary); color: #fff;
  font-size: 10.5px; font-weight: 800; line-height: 17px; text-align: center;
}
.lb-wrap { position: relative; }
.lb-pop {
  position: absolute; top: calc(100% + 6px); inset-inline-start: 0;
  z-index: 500; min-width: 250px;
  background: var(--color-bg-surface);
  border: 1px solid var(--color-border); border-radius: 12px;
  box-shadow: 0 12px 36px rgba(0,0,0,0.14);
  padding: 12px;
  display: none;
}
.lb-pop.open { display: block; animation: glMdIn .14s cubic-bezier(0.16,1,0.3,1); }
.lb-pop .filter-select { width: 100%; max-width: none; margin-bottom: 8px; display: block; }
.lb-pop .filter-select:last-child { margin-bottom: 0; }
.lb-pop-label { font-size: 10.5px; font-weight: 700; color: var(--color-text-faint); text-transform: uppercase; letter-spacing: .05em; margin-bottom: 8px; }
.lb-pop-foot { border-top: 1px solid var(--color-border); margin-top: 10px; padding-top: 9px; display: flex; flex-direction: column; gap: 6px; }
.lb-pop-foot a { font-size: 12px; color: var(--color-primary); text-decoration: none; font-weight: 600; }
.lb-pop-foot a:hover { text-decoration: underline; }
@media (max-width: 640px) { .lb-pop { inset-inline-start: auto; inset-inline-end: 0; } }

/* ── Custom date range (glPeriodCustom) ── */
.gl-range-wrap { display: inline-flex; align-items: center; gap: 5px; }
.gl-range-in {
  min-height: 38px; padding: 6px 8px; border: 1px solid var(--color-primary);
  border-radius: 8px; background: var(--color-primary-soft, #F4FAF7);
  font-family: var(--font-sans); font-size: 12px; color: var(--color-primary);
}
.gl-range-sep { color: var(--color-text-muted); font-size: 12px; }
.lb-pop .gl-range-wrap { display: flex; margin-top: 6px; }

/* ═══════════════════════════════════════════════════════════════════════════
   POLISH LAYER (v2.1) — site-wide cosmetic unification, July 2026
   Additive sections 11–17. Same principles: Trusted · Effortless · Saudi.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── 11. CANONICAL TYPOGRAPHY ────────────────────────────────────────────
   One family across the entire product. Pages historically declared their
   own body fonts (Tajawal here, IBM Plex there, DM Sans elsewhere) which
   bypassed the token system — this override outranks them all, so no HTML
   edits are needed. IBM Plex Sans Arabic leads: professional weight range,
   excellent Arabic/Latin metric harmony, reads "bank", not "blog". */
:root {
  --font-sans: 'IBM Plex Sans Arabic', 'Tajawal', 'Segoe UI', system-ui, sans-serif;
}
body, input, select, textarea, button {
  font-family: var(--font-sans) !important;
}
code, pre, .font-mono {
  font-family: ui-monospace, 'Courier New', monospace !important;
}
body { -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }

/* ── 12. PAGE ENTRY & MOTION ─────────────────────────────────────────────
   A 180ms settle on load — the page arrives, it doesn't pop. Interactive
   elements get a consistent micro-transition. Users who ask the OS for
   reduced motion get exactly that. */
@keyframes glPageIn {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
body { animation: glPageIn 0.18s ease-out; }
.gl-fade-in { animation: glPageIn 0.22s ease-out; }
a, button, .btn, .gl-btn, .tab, .status-pill, .badge,
input, select, .je-card, .gl-card {
  transition: background-color .13s ease, border-color .13s ease,
              color .13s ease, box-shadow .13s ease, transform .13s ease;
}
button:active, .btn:active, .gl-btn:active { transform: translateY(1px); }
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── 13. FOCUS — ONE RING EVERYWHERE ─────────────────────────────────────
   Keyboard users get the same calm green ring on every interactive element;
   mouse clicks don't flash it (focus-visible only). */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: 6px;
}

/* ── 14. TABLES — SHARED RHYTHM FOR EVERY GRID ───────────────────────────
   Covers the page-local table classes so all grids read as one family:
   quiet headers, hairline rows, gentle hover, tabular numerals. */
.db-table th, .r-table th, .gl-table th, .slip-tbl .sec td {
  font-size: 11.5px; font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase;
  color: var(--color-text-muted, #888780);
}
.db-table td, .r-table td, .gl-table td { border-bottom: 1px solid #F0EFE9; }
.db-table tbody tr, .r-table tbody tr, .gl-table tbody tr {
  transition: background-color .12s ease;
}
.db-table tbody tr:hover, .r-table tbody tr:hover, .gl-table tbody tr:hover {
  background: #FAFAF7;
}
.db-table td.num, .r-table td.num, table td.row-amount {
  font-variant-numeric: tabular-nums;
}
.gl-sticky thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--color-surface, #fff);
  box-shadow: 0 1px 0 #E3E1DA;
}

/* ── 15. INPUT HARMONY ───────────────────────────────────────────────────
   Same border, radius, and focus treatment across the product's fields
   (normalizes look only — layout/sizing stays with each page). */
input[type="text"], input[type="number"], input[type="date"],
input[type="email"], input[type="password"], input[type="search"],
select, textarea {
  border-radius: 8px;
  accent-color: var(--color-primary);
}
input::placeholder, textarea::placeholder { color: #B4B2A9; }

/* ── 16. SCROLLBARS ──────────────────────────────────────────────────────
   Slim and quiet — content is the interface, not the chrome. */
* { scrollbar-width: thin; scrollbar-color: #D6D4CC transparent; }
*::-webkit-scrollbar { width: 8px; height: 8px; }
*::-webkit-scrollbar-thumb { background: #D6D4CC; border-radius: 8px; }
*::-webkit-scrollbar-thumb:hover { background: #B4B2A9; }
*::-webkit-scrollbar-track { background: transparent; }

/* ── 17. HEAVY-LIST RENDERING (opt-in speed) ─────────────────────────────
   Add .gl-cv to long lists/sections: the browser skips rendering
   off-screen content. Zero risk to layout when applied to lists. */
.gl-cv { content-visibility: auto; contain-intrinsic-size: auto 600px; }

/* ── 18. THE TABLE CONTRACT ──────────────────────────────────────────────
   ONE alignment model for every grid, both directions:

     · Text columns   → text-align:start  (RTL: right · LTR: left)
     · Number columns → text-align:end    (RTL: left  · LTR: right)
                        digits themselves stay LTR (tabular, isolated)
     · Actions        → .ctr (centered)

   RULES: the SAME class goes on the header cell as on its body cells —
   th.num above td.num — that is what keeps headers and content aligned.
   Headers never wrap; body cells may wrap unless .nowrap; cells that
   host inputs get .cell-input (input fills the cell, no squeeze-wrap).
   Logical values mean zero per-language CSS: flipping dir just works. */
.db-table th, .db-table td,
.r-table th,  .r-table td,
.gl-table th, .gl-table td,
.tbl th, .tbl td,
.drawer-table th, .drawer-table td,
.receipt-items-table th, .receipt-items-table td {
  text-align: start;
}
.db-table th.num, .db-table td.num,
.r-table th.num,  .r-table td.num,
.gl-table th.num, .gl-table td.num,
.tbl th.num, .tbl td.num,
.drawer-table th.num, .drawer-table td.num,
.receipt-items-table th.num, .receipt-items-table td.num,
.db-table td.row-amount, .r-table td.row-amount {
  text-align: end !important;
}
.db-table td.num, .r-table td.num, .gl-table td.num, .tbl td.num,
.db-table td.row-amount, .r-table td.row-amount {
  direction: ltr; unicode-bidi: isolate;
  font-variant-numeric: tabular-nums;
}
.db-table th, .r-table th, .gl-table th, .tbl th,
.drawer-table th, .receipt-items-table th { white-space: nowrap; }
.db-table .ctr, .r-table .ctr, .gl-table .ctr, .tbl .ctr { text-align: center !important; }
.db-table .nowrap, .r-table .nowrap, .gl-table .nowrap { white-space: nowrap; }
.db-table td.cell-input, .r-table td.cell-input, .gl-table td.cell-input {
  white-space: nowrap;
}
.db-table td.cell-input input, .db-table td.cell-input select,
.r-table td.cell-input input,  .r-table td.cell-input select,
.gl-table td.cell-input input, .gl-table td.cell-input select {
  width: 100%; min-width: 70px; box-sizing: border-box;
}

/* ── 19. BRAND MARK IN THE HEADER ────────────────────────────────────────
   Larger, unmissable, and readable on the dark header: "Gulf" solid white,
   "Ledger" in the soft gold accent — visible in both themes and both
   directions. Bars scale with the mark. */
.nav-logo { gap: 9px !important; }
.nav-logo .nav-name {
  font-size: 21px !important;
  font-weight: 800 !important;
  letter-spacing: -0.01em;
  color: #FFFFFF !important;
}
/* Accent from the brand's own green family — light mint, coherent with the
   Saudi-green palette and clearly readable on the dark header. */
.nav-logo .nav-name span { color: #9FD9B8 !important; }
.nav-logo .nav-bars { transform: scale(1.25); transform-origin: center; }
@media (max-width: 560px){ .nav-logo .nav-name { font-size: 18px !important; } }

/* ── 20. LANGUAGE FLAGS ──────────────────────────────────────────────────
   The switcher speaks visually: Saudi flag = Arabic, UK flag = English. */
.lang-btn { font-size: 17px !important; line-height: 1 !important; padding: 4px 8px !important; }

/* ── 21. LANDING-PAGE CLARITY, APP-WIDE ──────────────────────────────────
   The landing page reads better because its ink is a green-undertone
   near-black (#0D2618) on a near-white ground, and its secondary text is
   a living green rather than flat gray. Replicated here with two
   moderations fit for dense data UIs: the ground stays a whisper off
   pure white (cards keep their separation), and muted text uses a
   desaturated green (readable at table density without shouting). */
:root {
  --ink: #0D2618;
  --color-text: #0D2618;
  --bg: #FAFAF7;
  --color-text-muted: #5B7263;
  --muted: #5B7263;
}
body { color: #0D2618; }
h1, h2, h3, h4 { color: #0D2618; }

/* contract extension: accounting compliance reports + branch report grids */
.report-table th, .report-table td, .br-table th, .br-table td { text-align: start; }
.report-table th.num, .report-table td.num, .br-table th.num, .br-table td.num { text-align: end !important; }
.report-table th, .br-table th { white-space: nowrap; }

/* ── 22. ACTION BUTTON STANDARD ──────────────────────────────────────────
   One scale for action buttons sitewide. Section/page primary actions are
   FULL size and live at the section header's end; .btn-sm is reserved for
   table-row and inline actions only. Icons always accompany primary
   actions and reflect the function. */
.btn, .gl-btn { min-height: 38px; padding: 8px 16px; font-size: 14px;
  display: inline-flex; align-items: center; gap: 7px; border-radius: 9px; }
.btn .gl-i, .gl-btn .gl-i { width: 16px; height: 16px; flex: 0 0 auto; }
.btn-sm { min-height: 30px; padding: 4px 10px; font-size: 12.5px; }

/* ── 23. DRAWER PRESENTATION (the record-editing law) ────────────────────
   Record-holding dialogs present as side drawers: full height, docked at
   the logical end (right in LTR, left in RTL), list stays visible behind.
   Applied by adding .gl-as-drawer to the dialog overlay — the form markup
   and all open/close logic stay untouched. Modals remain modals for
   transactional moments; documents remain pages. */
@keyframes glDrawerIn { from { translate: 0 10px; opacity: 0; } to { translate: 0 0; opacity: 1; } }
.gl-as-drawer { justify-content: flex-end !important; align-items: stretch !important; padding: 0 !important; }
.gl-as-drawer > .modal,
.gl-as-drawer > .modal-box,
.gl-as-drawer > .gl-modal {
  position: fixed; top: 0; inset-inline-end: 0; bottom: 0;
  height: 100vh; max-height: 100vh;
  width: min(560px, 94vw);
  margin: 0; border-radius: 0;
  overflow-y: auto;
  box-shadow: 0 0 48px rgba(13, 38, 24, 0.22);
  animation: glDrawerIn 0.2s ease-out;
}
.gl-as-drawer .modal-head,
.gl-as-drawer .gl-modal-head {
  position: sticky; top: 0; background: #fff; z-index: 2;
  border-bottom: 1px solid #EFEDE7;
}

/* ── 24. KPI CARD STANDARD (slim, purchasing spec) ───────────────────────
   One silhouette for every KPI/stat card family sitewide: slim padding,
   uniform type scale, equal heights. Covers .stat-card (finance/inventory/
   audit/purchasing), .stat (dashboard/invoices/detail views), and .br-kpi
   (branch report). Drawer-internal stats and marketing mocks excluded. */
.stat-card, .stat, .br-kpi {
  background: #fff;
  border: 1px solid #E3E1DA;
  border-radius: 10px !important;
  padding: 12px 14px !important;
  min-height: 76px;
  display: flex; flex-direction: column; justify-content: center; gap: 3px;
  box-sizing: border-box;
}
.stat-card .label, .stat-card .stat-label, .stat .stat-label,
.br-kpi .br-kpi-label, .br-kpi-label {
  font-size: 11.5px !important; font-weight: 700;
  letter-spacing: 0.03em; color: #5B7263 !important;
  text-transform: none;
}
.stat-card .value, .stat-card .stat-value, .stat .stat-value,
.br-kpi .br-kpi-val, .br-kpi-val {
  font-size: 20px !important; font-weight: 800;
  color: #0D2618 !important; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
.stat-card .sub, .stat .stat-sub {
  font-size: 11px !important; color: #8A9B8F;
}

/* ── 25. FORM IDENTITY (one language for every dialog) ───────────────────
   Creation popups and edit drawers share one visual grammar: a titled head
   with the brand accent, consistent field rhythm, a separated footer.
   Mode is behavioral (popup=create, drawer=edit) — identity is shared. */
.modal-overlay .modal-head, .modal-overlay .gl-modal-head{
  border-bottom: 2px solid #0E5232 !important;
  padding-bottom: 10px !important; margin-bottom: 14px;
}
.modal-overlay .modal-title{
  font-size: 16px !important; font-weight: 800 !important;
  color: #0D2618 !important; letter-spacing: .01em;
}
.modal-overlay:not(.gl-as-drawer) > .modal,
.modal-overlay:not(.gl-as-drawer) > .modal-box,
.modal-overlay:not(.gl-as-drawer) > .gl-modal{
  border-radius: 14px; max-height: 88vh; overflow-y: auto;
  box-shadow: 0 24px 64px rgba(13,38,24,.28);
}
.modal-overlay .field-label{ font-weight: 700; }
.modal-overlay .modal-foot{ border-top: 1px solid #EFEDE7 !important; }

/* ── 26. SCAN AFFORDANCE (compact, professional) ────────────────────────
   Barcode entry is a slim inline pill, not a form row: monospace, scan
   glyph, sits inside a section header line. */
.gl-scan-pill{
  display: inline-flex; align-items: center; gap: 6px;
  border: 1.5px dashed #9DB8A8; border-radius: 999px;
  padding: 3px 10px; background: #F4F8F5;
}
.gl-scan-pill input{
  border: none !important; outline: none; background: transparent;
  width: 150px; font-size: 12.5px; direction: ltr;
  font-variant-numeric: tabular-nums;
}
.gl-scan-pill .gl-scan-ic{ font-size: 13px; color: #0E5232; }
