:root{
  --ink:#231F18;
  --ink-soft:#5B5346;
  --gold:#A9782F;
  --gold-deep:#7C5A22;
  --gold-soft:#E7D9B8;
  --paper:#FAF6EC;
  --surface:#FFFFFF;
  --surface-2:#F3EDDD;
  --line:#E3D9C2;
  --ok:#3F7D58;
  --ok-soft:#E4F1E8;
  --danger:#B23B3B;
  --danger-soft:#F7E6E4;
  --amber:#95610C;
  --amber-soft:#FBEDD4;
  --info:#1D5FA8;
  --info-soft:#E3EDF9;
  --shadow: 0 1px 2px rgba(35,31,24,.06), 0 8px 24px -12px rgba(35,31,24,.18);
  --radius: 14px;
  --radius-sm: 9px;
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --ink:#F1EADC;
    --ink-soft:#C8BEA9;
    --gold:#D6B15E;
    --gold-deep:#EFCF8C;
    --gold-soft:#3A331F;
    --paper:#1B1712;
    --surface:#25201A;
    --surface-2:#2E271D;
    --line:#41392A;
    --ok:#7FBF98;
    --ok-soft:#22301F;
    --danger:#E28080;
    --danger-soft:#3A2220;
    --amber:#E3B15C;
    --amber-soft:#3A2E14;
    --info:#6FA8DC;
    --info-soft:#20334A;
    --shadow: 0 1px 2px rgba(0,0,0,.35), 0 8px 28px -12px rgba(0,0,0,.55);
  }
}
:root[data-theme="dark"]{
  --ink:#F1EADC;
  --ink-soft:#C8BEA9;
  --gold:#D6B15E;
  --gold-deep:#EFCF8C;
  --gold-soft:#3A331F;
  --paper:#1B1712;
  --surface:#25201A;
  --surface-2:#2E271D;
  --line:#41392A;
  --ok:#7FBF98;
  --ok-soft:#22301F;
  --danger:#E28080;
  --danger-soft:#3A2220;
  --amber:#E3B15C;
  --amber-soft:#3A2E14;
  --info:#6FA8DC;
  --info-soft:#20334A;
  --shadow: 0 1px 2px rgba(0,0,0,.35), 0 8px 28px -12px rgba(0,0,0,.55);
}
*{ box-sizing:border-box; }
html,body{ height:100%; }
body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:"Tajawal","Segoe UI",Tahoma,sans-serif;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing:antialiased;
}
h1,h2,h3,.display{ font-family:"Cairo","Tajawal",sans-serif; text-wrap:balance; }
button, input, select, textarea{ font-family:inherit; font-size:inherit; color:inherit; }
::selection{ background:var(--gold-soft); }
a{ color:var(--gold-deep); }
:focus-visible{ outline:2px solid var(--gold); outline-offset:2px; border-radius:4px; }

.app-shell{ min-height:100vh; display:flex; }

/* ---------- auth (sign in / set up account) ---------- */
.auth-shell{ position:relative; min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; background:var(--paper); }
.auth-actions-row{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
.auth-actions-row button{ flex:1 1 auto; min-width:90px; }
.auth-card{
  width:100%; max-width:380px; background:var(--surface); border:1px solid var(--line); border-radius:16px;
  padding:30px 28px; box-shadow:0 10px 34px rgba(0,0,0,.10);
}
.auth-brand{ display:flex; flex-direction:column; align-items:center; gap:10px; margin-bottom:22px; text-align:center; }
.auth-brand img{ width:76px; height:76px; border-radius:50%; object-fit:cover; box-shadow:0 0 0 2px var(--line), var(--shadow); }
.auth-brand .name{ font-weight:800; font-size:15px; color:var(--ink); }
.auth-card h2{ font-size:18px; margin:0 0 6px; text-align:center; }
.auth-card p.hint{ margin:0 0 14px; font-size:12.5px; color:var(--ink-soft); line-height:1.6; }
.auth-card form{ display:flex; flex-direction:column; gap:12px; margin-top:4px; }

/* ---------- branch management ---------- */
.branch-logo-row{ display:flex; align-items:center; gap:12px; margin-top:4px; flex-wrap:wrap; }
.branch-logo-row img{ width:52px; height:52px; border-radius:50%; object-fit:cover; flex:none; box-shadow:0 0 0 1.5px var(--line); }
/* signature/stamp previews are rectangular images, not circular avatars —
   shown on a white card so a transparent PNG reads correctly in dark mode too */
.branch-imgpick-row img{ width:auto; height:56px; max-width:180px; border-radius:6px; object-fit:contain; background:#fff; padding:4px; box-shadow:0 0 0 1.5px var(--line); }

/* ---------- permissions ---------- */
.permgrid{ display:flex; flex-direction:column; gap:9px; margin-top:8px; }
.permrow{ display:flex; align-items:center; gap:9px; font-size:13px; cursor:pointer; }
.permrow input{ width:auto; accent-color:var(--gold); }
.permlist{ list-style:none; margin:6px 0 0; padding:0; display:flex; flex-direction:column; gap:5px; font-size:13px; }
.permlist li.perm-off{ color:var(--ink-soft); }

/* ---------- form-layout editor (extra columns/fields) ---------- */
.extrafield-list{ display:flex; flex-direction:column; gap:8px; margin-top:8px; }
.extrafield-row{ display:flex; align-items:center; gap:8px; }
.extrafield-row input[type="text"]{ flex:1 1 auto; min-width:0; }
.extrafield-row select{ flex:0 0 auto; width:auto; }
.extrafield-row .icon-btn{ flex:0 0 auto; }

/* ---------- Tatheer Group ownership credit ---------- */
.tatheer-credit{
  display:flex; align-items:center; gap:10px; margin-top:14px; padding-top:14px;
  border-top:1px solid var(--line); font-size:10.5px; color:var(--ink-soft); line-height:1.4;
}
.tatheer-credit img{ width:36px; height:36px; border-radius:50%; object-fit:cover; flex:none; box-shadow:0 0 0 1.5px var(--line); }
.auth-card .tatheer-credit.auth-credit{
  flex-direction:column; justify-content:center; text-align:center; gap:8px; margin-top:18px; padding-top:16px;
}
.auth-card .tatheer-credit.auth-credit img{ width:64px; height:64px; box-shadow:0 0 0 2px var(--line), var(--shadow); }
.auth-card .tatheer-credit.auth-credit span{ font-size:11px; line-height:1.7; }
.auth-card .tatheer-credit.auth-credit.no-logo{ gap:0; }
.nowrap{ white-space:nowrap; }
.sheet-footer-credit{
  display:flex; align-items:center; justify-content:center; gap:6px; margin-top:4px; padding-top:4px;
  border-top:1px solid rgba(255,255,255,.15); font-size:8.5px; color:#c9bd9e; font-weight:600;
}
.sheet-footer-credit img{ width:16px; height:16px; border-radius:50%; object-fit:cover; flex:none; box-shadow:0 0 0 1px rgba(255,255,255,.25); }

/* ---------- sidebar ---------- */
.sidebar{
  width:236px; flex:none; background:var(--surface); border-inline-start:1px solid var(--line);
  display:flex; flex-direction:column; padding:22px 18px; gap:26px;
}
.brand{ display:flex; align-items:center; gap:10px; }
.brand img{ width:40px; height:40px; border-radius:9px; object-fit:cover; box-shadow:var(--shadow); }
.brand .name{ font-family:"Cairo",sans-serif; font-weight:800; font-size:15px; line-height:1.25; }
.brand .name span{ display:block; font-family:"Tajawal",sans-serif; font-weight:500; font-size:10.5px; color:var(--ink-soft); letter-spacing:.04em; }

/* Permanent "awaiting approval" box — always visible to anyone who can
   approve here, whether or not anything is currently pending; the blue
   badge is the only part that switches on/off with the pending count. */
.notif-panel-btn{
  display:flex; align-items:center; gap:10px; width:100%; text-align:start;
  background:var(--surface-2); border:1px solid var(--line); border-radius:var(--radius-sm);
  padding:10px 12px; cursor:pointer; font-weight:700; font-size:13.5px; color:var(--ink-soft);
  transition:background .15s, border-color .15s, color .15s;
}
.notif-panel-btn:hover{ background:var(--surface); }
.notif-panel-btn.has-pending{
  background:var(--info-soft); border-color:var(--info); color:var(--info);
}
.notif-panel-btn .notif-bell{ font-size:15px; }
.notif-panel-btn .notif-label{ flex:1; }
.notif-badge{
  background:var(--info); color:var(--surface); border-radius:999px;
  min-width:21px; height:21px; padding:0 6px; display:inline-flex; align-items:center; justify-content:center;
  font-size:11.5px; font-weight:800;
}

.nav{ display:flex; flex-direction:column; gap:4px; }
.nav button{
  display:flex; align-items:center; gap:10px; text-align:start; border:none; background:transparent;
  color:var(--ink-soft); padding:10px 12px; border-radius:var(--radius-sm); cursor:pointer; font-weight:600; font-size:14px;
  transition:background .15s, color .15s;
}
.nav button:hover{ background:var(--surface-2); color:var(--ink); }
.nav button.active{ background:var(--gold-soft); color:var(--gold-deep); }
.nav button .ico{ width:18px; text-align:center; opacity:.85; }

.sidebar-foot{ margin-top:auto; font-size:11.5px; color:var(--ink-soft); line-height:1.6; }
.sidebar-foot b{ color:var(--ink); }
.storage-note{ display:block; margin-bottom:8px; color:var(--ok); font-weight:700; font-size:11px; }
/* "الإبلاغ عن غياب / إجازة اليوم" status badge in the sidebar footer
   (2026-09-08 feature) — a small warm-toned box so a signed-in user's own
   out-of-office state is impossible to miss next to the logout button. */
.ooo-active-badge{ background:#FBEFD6; border:1px solid #E3C687; border-radius:8px; padding:6px 8px; font-size:11px; font-weight:700; color:#7A5A17; line-height:1.4; }
.ooo-active-badge .hint{ font-weight:500; color:#8a7f63; }
.langToggle{ width:100%; justify-content:center; }
.langThemeRow{ display:flex; gap:6px; margin-top:auto; }
.langThemeRow button{ flex:1; justify-content:center; min-width:0; }
.backupBtns{ display:flex; flex-direction:column; gap:6px; margin-top:8px; }
.backupBtns .btn{ width:100%; justify-content:center; }

/* ---------- main ---------- */
.main{ flex:1; min-width:0; padding:28px 32px 60px; }
.topbar{ display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:22px; flex-wrap:wrap; }
.topbar h1{ margin:0; font-size:22px; font-weight:800; }
.topbar p{ margin:4px 0 0; color:var(--ink-soft); font-size:13px; }
.topbar-titlewrap{ min-width:0; }
.topbar-nav{ display:flex; gap:6px; margin-bottom:8px; }

.btn{
  display:inline-flex; align-items:center; gap:8px; border:1px solid transparent; border-radius:999px;
  padding:10px 18px; font-weight:700; font-size:13.5px; cursor:pointer; transition:transform .1s, box-shadow .15s, background .15s;
  white-space:nowrap;
}
.btn:active{ transform:scale(.97); }
.btn-gold{ background:var(--gold); color:#241C0E; box-shadow:var(--shadow); }
.btn-gold:hover{ background:var(--gold-deep); }
.btn-ghost{ background:transparent; color:var(--ink); border-color:var(--line); }
.btn-ghost:hover{ background:var(--surface-2); }
.btn-danger{ background:transparent; color:var(--danger); border-color:var(--danger); }
.btn-danger:hover{ background:var(--danger-soft); }
.btn-sm{ padding:6px 12px; font-size:12.5px; border-radius:8px; }
.btn[disabled]{ opacity:.5; cursor:not-allowed; }

.card{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow); }
.pad{ padding:22px; }

/* ---------- list ---------- */
.toolbar{ display:flex; gap:10px; align-items:center; margin-bottom:14px; flex-wrap:wrap; }
.search{
  flex:1; min-width:200px; display:flex; align-items:center; gap:8px; background:var(--surface);
  border:1px solid var(--line); border-radius:999px; padding:9px 16px; color:var(--ink-soft);
}
.search input{ border:none; background:transparent; outline:none; flex:1; color:var(--ink); font-size:13.5px; }
.seg{ display:flex; background:var(--surface-2); border-radius:999px; padding:3px; gap:2px; }
.seg button{ border:none; background:transparent; padding:7px 14px; border-radius:999px; font-weight:700; font-size:12.5px; color:var(--ink-soft); cursor:pointer; }
.seg button.active{ background:var(--surface); color:var(--ink); box-shadow:var(--shadow); }

table.doclist{ width:100%; min-width:680px; border-collapse:collapse; font-size:13.5px; }
table.doclist td, table.doclist th{ white-space:nowrap; }
table.doclist th{ text-align:start; padding:10px 14px; color:var(--ink-soft); font-weight:700; font-size:12px; border-bottom:1px solid var(--line); }
table.doclist td{ padding:12px 14px; border-bottom:1px solid var(--line); vertical-align:middle; }
table.doclist tr:last-child td{ border-bottom:none; }
table.doclist tr:hover td{ background:var(--surface-2); }
/* the reports screen's data table gets a fully ruled grid (outer frame +
   column/row dividers) like the printed documents' line-items table, rather
   than doclist's plain bottom-rule-only rows — a report is read cell by
   cell, so the grid is what makes it feel like a structured report. */
.report-table-wrap{ overflow-x:auto; }
table.report-table{ border:1px solid var(--line); }
table.report-table th, table.report-table td{ border:1px solid var(--line); }
table.report-table tbody tr:nth-child(even) td{ background:var(--surface-2); }
/* the reports screen's column-totals row (see renderReports) — sits in a
   <tfoot>, styled to read as a summary line rather than another data row */
table.report-table tfoot td{ background:var(--surface-2); border-top:2px solid var(--gold-deep); font-size:13px; }
table.report-table td.amount, table.report-table th{ white-space:nowrap; }
.pill{ display:inline-flex; align-items:center; gap:6px; padding:3px 11px; border-radius:999px; font-size:11.5px; font-weight:700; }
.pill-inv{ background:var(--gold-soft); color:var(--gold-deep); }
.pill-cn{ background:var(--danger-soft); color:var(--danger); }
.pill-pwi{ background:#DDEAF0; color:#2E6B7A; }
.pill-quote{ background:#DCEBF7; color:#2B6493; }
.pill-mpr{ background:#E1F0E6; color:#2E7D50; }
.pill-mpo{ background:#EAE1F5; color:#6B3FA0; }
.pill-ftr{ background:#FCE8D6; color:#A85E1C; }
.pill-cdr{ background:var(--surface-2); color:var(--ink-soft); }
.pill-plan{ background:#D9F0EE; color:#1E7A72; }
.pill-wrq{ background:#F6E1E8; color:#A23A5E; }
.pill-wlpo{ background:#E3E4F7; color:#3F4696; }
.pill-pending{ background:var(--amber-soft); color:var(--amber); }
.pill-approved{ background:var(--ok-soft); color:var(--ok); }
.pill-rejected{ background:var(--danger-soft); color:var(--danger); }
.pill-revision{ background:var(--gold-soft); color:var(--gold-deep); }
.pill-skipped{ background:var(--surface-2); color:var(--ink-soft); }
.pill-inprogress{ background:#DCEBF7; color:#2B6493; }
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .pill-pwi{ background:#163238; color:#8AC9D6; }
  :root:not([data-theme="light"]) .pill-quote{ background:#1C3244; color:#8EC2ED; }
  :root:not([data-theme="light"]) .pill-mpr{ background:#1B3323; color:#8FD6A8; }
  :root:not([data-theme="light"]) .pill-mpo{ background:#2C2140; color:#C6A7EC; }
  :root:not([data-theme="light"]) .pill-ftr{ background:#3A2814; color:#F0B67D; }
  :root:not([data-theme="light"]) .pill-plan{ background:#123531; color:#7FD4CA; }
  :root:not([data-theme="light"]) .pill-wrq{ background:#3A1B26; color:#E79DB8; }
  :root:not([data-theme="light"]) .pill-wlpo{ background:#211F3D; color:#ACB0EC; }
  :root:not([data-theme="light"]) .pill-inprogress{ background:#1C3244; color:#8EC2ED; }
}
:root[data-theme="dark"] .pill-pwi{ background:#163238; color:#8AC9D6; }
:root[data-theme="dark"] .pill-quote{ background:#1C3244; color:#8EC2ED; }
:root[data-theme="dark"] .pill-mpr{ background:#1B3323; color:#8FD6A8; }
:root[data-theme="dark"] .pill-mpo{ background:#2C2140; color:#C6A7EC; }
:root[data-theme="dark"] .pill-ftr{ background:#3A2814; color:#F0B67D; }
:root[data-theme="dark"] .pill-plan{ background:#123531; color:#7FD4CA; }
:root[data-theme="dark"] .pill-wrq{ background:#3A1B26; color:#E79DB8; }
:root[data-theme="dark"] .pill-wlpo{ background:#211F3D; color:#ACB0EC; }
:root[data-theme="dark"] .pill-inprogress{ background:#1C3244; color:#8EC2ED; }
.rowbtns{ display:flex; gap:6px; justify-content:flex-end; }
.amount{ font-weight:700; }
.empty{ text-align:center; padding:60px 20px; color:var(--ink-soft); }
.empty .big{ font-size:36px; margin-bottom:10px; }

/* ---------- ملف المشروع (Project File) — see renderProjectFile in app.js.
   The project's name in the projects list (renderProjects) is clickable —
   same entry point as the "📁 فتح الملف" button next to it. */
.projname-link{ cursor:pointer; color:var(--gold); }
.projname-link:hover{ text-decoration:underline; }
.projfile-header{ display:flex; align-items:center; gap:14px; margin-bottom:16px; flex-wrap:wrap; }
.projfile-title{ font-family:"Cairo",sans-serif; font-weight:800; font-size:20px; }
.projfile-tabs{
  display:flex; gap:6px; flex-wrap:wrap; margin-bottom:16px;
  border-bottom:1px solid var(--line); padding-bottom:0;
}
.projfile-tab{
  border:none; background:transparent; color:var(--ink-soft); cursor:pointer;
  padding:10px 14px; font-size:13px; font-weight:700; border-radius:10px 10px 0 0;
  border-bottom:2px solid transparent; transition:color .15s, border-color .15s, background .15s;
}
.projfile-tab:hover{ color:var(--ink); background:var(--surface-2); }
.projfile-tab.active{ color:var(--gold); border-bottom-color:var(--gold); }
.projfile-stats{ display:grid; grid-template-columns:repeat(auto-fit, minmax(150px, 1fr)); gap:12px; }
.projfile-stat{
  border:1px solid var(--line); border-radius:12px; padding:14px; text-align:center;
  background:var(--surface-2);
}
.projfile-stat-icon{ font-size:20px; margin-bottom:6px; }
.projfile-stat-value{ font-family:"Cairo",sans-serif; font-weight:800; font-size:16px; }
.projfile-stat-label{ font-size:11.5px; color:var(--ink-soft); margin-top:4px; }

/* ---------- form ---------- */
.form-grid{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.form-grid.full,.field.full{ grid-column:1/-1; }
.field label{ display:block; font-size:12.5px; font-weight:700; color:var(--ink-soft); margin-bottom:6px; }
.field .hint{ font-weight:400; color:var(--ink-soft); font-size:11px; }
.field input, .field select, .field textarea{
  width:100%; border:1px solid var(--line); background:var(--paper); color:var(--ink);
  border-radius:10px; padding:10px 12px; font-size:13.5px; transition:border-color .15s;
}
.field input:focus, .field select:focus, .field textarea:focus{ border-color:var(--gold); }
.field textarea{ resize:vertical; min-height:56px; }
.field-static{
  width:100%; border:1px dashed var(--line); background:var(--surface-2); color:var(--ink-soft);
  border-radius:10px; padding:10px 12px; font-size:13.5px; min-height:20px; box-sizing:border-box;
}
/* amount-in-words preview (invoice/credit form): always computed live from
   the total, in both Arabic and English — never typed by hand, see
   amountWordsBilingual in app.js. */
.amount-words-preview{ line-height:1.7; }
.section-title{ font-family:"Cairo",sans-serif; font-weight:800; font-size:15px; margin:26px 0 12px; display:flex; align-items:center; gap:10px; }
.section-title::after{ content:""; flex:1; height:1px; background:var(--line); }

.typeToggle{ display:flex; gap:10px; }
.typeToggle button{
  flex:1; border:1.5px solid var(--line); background:var(--surface); border-radius:12px; padding:14px; cursor:pointer;
  text-align:center; font-weight:700; font-size:13.5px; color:var(--ink-soft); transition:.15s;
}
.typeToggle button.active{ border-color:var(--gold); background:var(--gold-soft); color:var(--gold-deep); }

table.lines{ width:100%; border-collapse:collapse; margin-top:6px; }
table.lines th{ text-align:start; font-size:11.5px; color:var(--ink-soft); padding:0 8px 8px; font-weight:700; }
table.lines td{ padding:5px 6px; vertical-align:middle; }
table.lines td input, table.lines td select{ width:100%; border:1px solid var(--line); background:var(--paper); border-radius:8px; padding:8px 9px; font-size:13px; font-family:inherit; color:var(--ink); }
table.lines td.num{ text-align:center; }
table.lines .val{ font-weight:700; text-align:center; min-width:88px; }

/* unit quick-pick (line items + item catalog): a plain native <select> of
   ready-made units (a "custom" option switches it for a free-text input) —
   deliberately built from plain <select>/<input>/<button> only, after a
   custom floating-dropdown version proved unreliable to open/click on some
   setups. Native form controls behave the same everywhere. */
.unit-picker{ display:flex; align-items:stretch; gap:4px; width:100%; }
.unit-picker .unit-input{ flex:1 1 auto; min-width:0; }
.unit-back-btn{
  flex:none; border:1px solid var(--line); background:var(--paper); color:var(--ink-soft);
  cursor:pointer; font-size:15px; line-height:1; border-radius:8px; padding:8px 10px;
}
.unit-back-btn:hover{ background:var(--surface-2); color:var(--ink); }
.line-actions{ text-align:center; }

/* units management page: read-only reference chips for the built-in list,
   shown below the editable table of hand-added custom units. */
.unit-chip-wrap{ display:flex; flex-wrap:wrap; gap:8px; }
.unit-chip{
  display:inline-block; border:1px solid var(--line); background:var(--surface-2); color:var(--ink-soft);
  border-radius:999px; padding:5px 12px; font-size:12.5px;
}

/* quick-add: a small link-style button under a picker <select> that opens
   the quick-add modal (customer/project/consultant) without leaving the
   document form — see QUICK_ADD/renderQuickAddModal in app.js. */
.quick-add-btn{
  display:inline-block; margin-top:6px; border:none; background:transparent; color:var(--gold-deep);
  font-size:12px; font-weight:700; cursor:pointer; padding:2px 0; text-decoration:underline; text-underline-offset:2px;
}
.quick-add-btn:hover{ color:var(--gold); }
.modal-overlay{
  position:fixed; inset:0; background:rgba(20,16,8,.45); display:flex; align-items:center; justify-content:center;
  padding:20px; z-index:500;
}
.modal-box{ width:100%; max-width:480px; max-height:90vh; overflow-y:auto; }
.icon-btn{ border:none; background:transparent; color:var(--ink-soft); cursor:pointer; padding:6px; border-radius:8px; font-size:15px; line-height:1; }
.icon-btn:hover{ background:var(--danger-soft); color:var(--danger); }
.addline{ margin-top:10px; }

.docTypeField select{ font-weight:700; }

/* ---------- attachments ---------- */
.attach-list{ display:flex; flex-direction:column; gap:6px; margin-bottom:8px; }
.attach-row{
  display:flex; align-items:center; gap:8px; border:1px solid var(--line); border-radius:10px;
  padding:6px 10px; background:var(--surface-2);
}
.attach-row a{ display:flex; align-items:center; gap:8px; flex:1; min-width:0; color:var(--ink); text-decoration:none; }
.attach-row a:hover .attach-name{ text-decoration:underline; }
.attach-thumb{ width:28px; height:28px; border-radius:6px; object-fit:cover; flex:none; box-shadow:0 0 0 1px var(--line); }
.attach-ico{ font-size:16px; flex:none; }
.attach-name{ font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
#attachInput{ margin-top:2px; }

.totalsBox{ margin-top:18px; display:flex; justify-content:flex-start; }
.totalsBox table{ border-collapse:collapse; min-width:300px; }
.totalsBox td{ padding:7px 12px; font-size:13.5px; }
.totalsBox td:first-child{ color:var(--ink-soft); }
.totalsBox td:last-child{ font-weight:700; text-align:left; direction:ltr; }
.totalsBox tr.grand td{ border-top:1px solid var(--line); font-size:16px; font-weight:800; padding-top:12px; color:var(--gold-deep); }

.adjToggle{ background:none; border:none; color:var(--gold-deep); font-weight:700; font-size:12.5px; cursor:pointer; padding:4px 0; margin-top:14px; }
.adjGrid{ display:grid; grid-template-columns:repeat(4,1fr); gap:12px; margin-top:12px; }

.formfoot{ display:flex; justify-content:flex-end; gap:10px; margin-top:26px; padding-top:18px; border-top:1px solid var(--line); }
.err{ color:var(--danger); font-size:12.5px; margin-top:4px; }
.banner{ padding:10px 16px; border-radius:10px; font-size:13px; margin-bottom:16px; display:flex; align-items:center; gap:8px; }
.banner-warn{ background:var(--danger-soft); color:var(--danger); }
.banner-ok{ background:var(--ok-soft); color:var(--ok); }

/* flash-banner: transient error/notice "toast" messages — VIEW.error/notice,
   AUTHVIEW.error/notice (login/signup screen), and the quick-add / switch-user
   / quick-branch-switch modal equivalents. Unlike plain .banner above (which
   stays in normal document flow — e.g. the ever-visible budget-variance
   warning), these are meant to be noticed the instant they appear regardless
   of scroll position, so they float centered on screen above everything else
   (including open modals), pop in, then either auto-fade after a few seconds
   or can be dismissed early with a tap/click — wired once via a delegated
   click handler near the .unit-back-btn one further down in app.js. */
.flash-banner{
  position:fixed; top:50%; left:50%; transform:translate(-50%,-50%);
  z-index:9999; max-width:min(92vw,560px); width:max-content;
  padding:16px 22px; border-radius:14px; font-size:14.5px; font-weight:700;
  display:flex; align-items:center; gap:10px; text-align:center; line-height:1.5;
  box-shadow:0 12px 40px rgba(0,0,0,.28), 0 0 0 1px rgba(0,0,0,.06);
  cursor:pointer;
  animation: flashBannerIn .22s cubic-bezier(.2,.9,.3,1), flashBannerOut .45s ease 5s forwards;
}
.flash-banner-warn{ background:var(--danger-soft); color:var(--danger); }
.flash-banner-ok{ background:var(--ok-soft); color:var(--ok); }
@keyframes flashBannerIn{ from{ opacity:0; transform:translate(-50%,-50%) scale(.9); } to{ opacity:1; transform:translate(-50%,-50%) scale(1); } }
@keyframes flashBannerOut{ from{ opacity:1; } to{ opacity:0; visibility:hidden; pointer-events:none; } }
@media print{ .flash-banner{ display:none; } }

/* the approval-workflow status banner shown above a document — on-screen
   only (it lives outside .sheet). @media print's own `body *{
   visibility:hidden }` rule keeps it from being PAINTED either way, but
   that alone doesn't remove its LAYOUT height — see the explicit
   .approval-banner/.approval-cycle-wrap{ display:none } print rule
   further down (same fix as the print-pagination sidebar bug elsewhere in
   this file): needed once a document's print output can put .sheet back
   into normal flow after this banner (the approval-cycle-log page, see
   approvalLogPageHtml, wraps the main .sheet in .multipkg-print, which
   sets .sheet{position:static} — unlike the single-.sheet case's
   position:absolute, which happens to ignore preceding flow siblings
   regardless of their hidden height). Reuses .banner's own base layout/
   spacing, just with its own pending/approved color pair. */
.approval-banner{ padding:10px 16px; border-radius:10px; font-size:13px; margin-bottom:16px; display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; width:800px; max-width:100%; }
.approval-banner-pending{ background:var(--amber-soft); color:var(--amber); font-weight:700; }
.approval-banner-approved{ background:var(--ok-soft); color:var(--ok); font-weight:700; }
.approval-banner-rejected{ background:var(--danger-soft); color:var(--danger); font-weight:700; }
.approval-banner-revision{ background:var(--gold-soft); color:var(--gold-deep); font-weight:700; }

/* the multi-stage approval cycle: an ordered timeline of stages shown
   inside the approval banner, plus the reject/revision note box that
   appears when the current approver picks one of those two actions. */
.approval-cycle-wrap{ width:800px; max-width:100%; margin-bottom:16px; }
.approval-timeline{ display:flex; flex-direction:column; gap:6px; }
.approval-stage-item{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:8px 12px; border-radius:8px; background:var(--surface-2); font-size:12.5px; }
.approval-stage-item .stage-idx{ font-weight:800; opacity:.6; min-width:16px; }
.approval-stage-item .stage-role{ font-weight:700; min-width:110px; }
.approval-stage-item .stage-person{ color:var(--ink-soft); }
.approval-stage-item .stage-meta{ margin-inline-start:auto; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.approval-stage-item .stage-note{ width:100%; font-size:11.5px; color:var(--ink-soft); background:var(--surface); border-radius:6px; padding:6px 10px; }
/* bare .stage-note (no .approval-stage-item ancestor) — the simple
   (no-cycle) approval banner's own rejected/revision note, shown directly
   inside .approval-banner rather than inside a stage timeline row; same
   look as the stage version above. */
.approval-banner .stage-note{ width:100%; font-size:11.5px; color:var(--ink-soft); background:var(--surface); border-radius:6px; padding:6px 10px; }
.approval-actions{ width:100%; display:flex; gap:8px; flex-wrap:wrap; margin-top:8px; }
.approval-note-box{ width:100%; margin-top:8px; display:flex; flex-direction:column; gap:8px; }
.approval-note-box textarea{ width:100%; min-height:64px; resize:vertical; }
.approval-stage-row{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; padding:6px 0; }
.approval-stage-row .approval-stage-label{ min-width:160px; font-weight:700; }
.approval-stage-row select{ flex:1; min-width:180px; }
.approval-role-row{ display:flex; align-items:center; gap:8px; margin-bottom:6px; }
.approval-role-row .approval-role-name{ flex:1; }
.approval-user-check{ display:inline-flex; align-items:center; gap:4px; font-size:12.5px; font-weight:400; }

/* ---------- approval policy view (see renderApprovalPolicy) ----------
   Lives inside .sheet like any other printable document, so — matching
   every other element styled inside .sheet elsewhere in this file — it
   uses fixed hex colors (the light-theme values) rather than the
   var(--...) tokens: a printed/printable page stays paper-white and
   ink-dark regardless of the app's own light/dark toggle. */
.policy-sheet{ text-align:right; }
.policy-header{ text-align:center; margin-bottom:16px; padding-bottom:12px; border-bottom:2px solid #E3D9C2; }
.policy-header h1{ font-size:19px; margin:0 0 4px; }
.policy-header .en-sub{ font-size:12px; }
.policy-intro-note{ background:#F3EDDD; border-radius:8px; padding:10px 14px; font-size:12px; margin-bottom:18px; line-height:1.6; }
.policy-section{ margin-bottom:18px; }
.policy-section h2{ font-size:14.5px; margin:0 0 10px; padding-bottom:5px; border-bottom:1px solid #E3D9C2; }
.policy-ar{ margin:0 0 2px; direction:rtl; text-align:right; font-size:12.5px; line-height:1.7; }
.policy-en{ margin:0 0 10px; direction:ltr; text-align:left; font-size:11px; line-height:1.6; color:#5B5346; font-style:italic; }
.policy-def{ margin-bottom:10px; }
.policy-def-term{ font-weight:800; font-size:12.5px; margin-bottom:3px; color:#7C5A22; }
.policy-table{ width:100%; border-collapse:collapse; margin-bottom:6px; }
.policy-table th, .policy-table td{ border:1px solid #E3D9C2; padding:6px 10px; font-size:11.5px; text-align:right; vertical-align:top; }
.policy-table th{ background:#F3EDDD; font-weight:700; }
.policy-levels{ display:flex; flex-direction:column; gap:10px; }
.policy-level{ background:#F3EDDD; border-radius:8px; padding:10px 14px; }
.policy-level-badge{ display:inline-block; font-weight:800; font-size:11px; padding:2px 9px; border-radius:999px; background:#E7D9B8; color:#7C5A22; margin-bottom:4px; }
.policy-steps{ counter-reset:policystep; list-style:none; margin:0; padding:0; }
.policy-steps li{ counter-increment:policystep; position:relative; padding-inline-start:28px; margin-bottom:10px; }
.policy-steps li::before{ content:counter(policystep); position:absolute; inset-inline-start:0; top:1px; width:19px; height:19px; border-radius:50%; background:#7C5A22; color:#fff; font-size:10.5px; font-weight:800; display:flex; align-items:center; justify-content:center; }
.policy-chain{ font-weight:600; }
.policy-roles-list{ font-size:12px; color:#5B5346; margin:0; }
.policy-footnote{ margin-top:18px; padding-top:10px; border-top:1px dashed #E3D9C2; font-size:10.5px; color:#5B5346; }
.policy-figure{ margin:14px 0; text-align:center; }
.policy-figure img{ max-width:100%; height:auto; display:block; margin:0 auto; border:1px solid #E3D9C2; border-radius:10px; box-shadow:0 4px 14px rgba(35,31,24,.12); }
.policy-figure figcaption{ margin-top:8px; font-size:11px; color:#5B5346; line-height:1.7; max-width:640px; margin-inline:auto; }
@media print{
  .policy-figure img{ max-width:90%; box-shadow:none; }
}

/* ---------- approval-cycle log page (see approvalLogPageHtml) ----------
   A second .sheet page auto-attached to the print output of any document
   that has an approval cycle configured (d.approvals non-empty) — his
   request that a printed document carry proof of its approval trail
   ("حتى يعطى للعميل او للمستند اهمية"). Lives inside .sheet like the
   approval-policy page above, so — matching that same rule — it uses
   fixed hex colors instead of var(--...) tokens: this must read the same
   on a printed page regardless of the app's current light/dark theme,
   unlike the on-screen approval-cycle-wrap banner (approvalCycleBannerHtml)
   which intentionally uses theme tokens because it is never printed. */
.alog-title{ text-align:center; font-weight:800; font-size:16px; margin-bottom:4px; }
.alog-sub{ text-align:center; font-size:11.5px; color:#5B5346; margin-bottom:16px; }
.alog-table{ width:100%; border-collapse:collapse; font-size:12px; }
.alog-table th, .alog-table td{ border:1px solid #E3D9C2; padding:7px 10px; text-align:right; vertical-align:top; }
.alog-table th{ background:#F3EDDD; font-weight:700; }
.alog-badge{ display:inline-block; padding:3px 10px; border-radius:999px; font-size:11px; font-weight:700; white-space:nowrap; }
.alog-pending{ background:#FBEDD4; color:#95610C; }
.alog-approved{ background:#E4F1E8; color:#3F7D58; }
.alog-rejected{ background:#F7E6E4; color:#B23B3B; }
.alog-revision{ background:#E7D9B8; color:#7C5A22; }
.alog-skipped{ background:#F3EDDD; color:#5B5346; }
.alog-final{ margin-top:16px; padding:10px 14px; border-radius:8px; background:#F3EDDD; font-size:12.5px; font-weight:700; text-align:center; }

/* ---------- printable document ---------- */
.docwrap{ display:flex; flex-direction:column; align-items:center; gap:18px; }
.docactions{ display:flex; gap:10px; }
.sheet{
  /* z-index:0 (with position:relative) is required, not decorative — it
     makes .sheet establish its OWN stacking context, so .sheet-watermark's
     z-index:-1 below is scoped to just behind THIS sheet's own white
     background. Without it, that -1 escapes to whichever ANCESTOR actually
     establishes the nearest stacking context (the sidebar layout, a modal,
     whatever the document happens to be nested inside at the time) — which
     is a different container with a different size/position on every
     screen, so the watermark was landing stretched/misplaced/effectively
     wrong there instead of tiled behind this sheet — reported as the
     watermark looking "مقلوب" (flipped/off). Confirmed by an isolated
     repro: identical CSS renders the watermark invisible without this line,
     correctly tiled with it.
  */
  position:relative; z-index:0; overflow:hidden; width:800px; max-width:100%; background:#FFFFFF; color:#231F18; border-radius:10px; box-shadow:var(--shadow);
  padding:9px 24px 10px; font-family:"Tajawal",sans-serif; font-size:14px;
}
/* branch logo tiled small and faint across the whole page — his pick from
   the 4 redesign proposals ("المقترح الصغيرى المتكرره بالصفحة كاملة"),
   replacing the old single large centered logo. Purely decorative. Opacity
   lowered from an original .07 (still felt too prominent to him — "اقل
   وضوحا مما هى عليه الان") to .035, then to .02 on his follow-up request to
   tone it down further still ("تقليل الوضوح الخاص به"). direction:ltr is
   pinned explicitly (independent of whatever dir the surrounding sheet is
   in) so background-position:0 0 always anchors the tile grid to the
   physical top-left corner — browsers disagree on how a background image's
   position/repeat origin is resolved under direction:rtl, and on at least
   one real setup this was reported as the watermark looking "مقلوب"
   (flipped/off); pinning ltr here removes that ambiguity regardless of
   which way the page around it reads. */
.sheet-watermark{
  position:absolute; inset:0; z-index:-1; direction:ltr;
  background-repeat:repeat; background-position:top left;
  background-size:70px auto; opacity:.02; pointer-events:none;
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.sheet-header-img{ display:block; width:100%; height:auto; }
/* logo centered, Arabic name pushed to the right edge and the English name
   to the left edge — a fixed brand layout (direction:rtl) independent of
   the document's own language toggle, so the letterhead always reads the
   same way regardless of dir on the .sheet root. */
.sheet-header-generic{
  display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:12px;
  background:#231F18; color:#fff; border-radius:9px; padding:9px 18px; direction:rtl;
}
.sheet-header-generic img{ width:38px; height:38px; border-radius:50%; object-fit:cover; justify-self:center; box-shadow:0 0 0 2px rgba(255,255,255,.25); }
.sheet-header-generic .co-name-ar{ font-size:14px; font-weight:800; line-height:1.3; text-align:right; }
.sheet-header-generic .co-name-en{ font-size:10.5px; font-weight:600; color:#D6B15E; line-height:1.3; text-align:left; }
.sheet-badge-row{ display:flex; justify-content:center; margin:7px 0 3px; }
.sheet-badge{ background:var(--gold-deep); color:#fff; font-weight:800; font-size:13.5px; border-radius:9px; padding:6px 24px; text-align:center; }
/* Footer row: the dark address/contacts bar plus the customer-rating QR
   card beside it. Originally the QR sat INSIDE the dark bar itself (a small
   44px code on a dark background, sharing its full-bleed width) — his
   complaint was that this buried it ("تظهر داخل الشريط السفلى") and made it
   easy to miss. Now they're two separate siblings in .sheet-footer-row: the
   dark bar no longer stretches to the sheet's full width (max-width below)
   per his "تقليل عرض الشريط الداكن", and the QR is its OWN white card
   outside that dark frame ("جعل الكود خارج الاطار"), bigger and higher-
   contrast so it reads at a glance. Falls back to a single centered bar
   with no gap when there's no QR to show (ratingBoxHtml empty — see
   sheetFooterHtml), so a branch with no rating URL configured looks exactly
   like before. */
.sheet-footer-row{ display:flex; align-items:stretch; justify-content:center; gap:12px; margin-top:6px; }
.sheet-footer{ background:#231F18; color:#fff; border-radius:9px; padding:6px 16px 5px; display:flex; align-items:center; justify-content:center; flex:1 1 auto; max-width:100%; min-width:0; }
/* .sheet-footer-row-withqr is added by sheetFooterHtml only when there's a
   rating QR to show beside the bar — a plain :has() selector would do the
   same thing, but this app has a documented history of print/rendering
   quirks on his specific setup, so the explicit modifier class is the safer
   bet over relying on a newer CSS selector at print time. */
.sheet-footer-row-withqr .sheet-footer{ max-width:74%; }
.sheet-footer-main{ flex:1 1 0; min-width:0; text-align:center; }
.sheet-footer-addr{ font-size:10px; font-weight:600; line-height:1.25; }
.sheet-footer .en-sub{ color:#cfc4a6; }
.sheet-footer-contacts{ display:flex; flex-wrap:wrap; justify-content:center; gap:3px 14px; margin-top:4px; padding-top:4px; border-top:1px solid rgba(255,255,255,.15); font-size:9.5px; }
.sheet-footer-contacts b{ color:#D6B15E; font-weight:700; }
.sheet-footer-qr-outside{
  flex:none; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
  background:#fff; border:1.5px solid #231F18; border-radius:10px; padding:7px 12px;
}
.sheet-footer-qr-outside .sheet-footer-qr-code{ width:60px; height:60px; }
.sheet-footer-qr-code svg{ display:block; width:100%; height:100%; }
.sheet-footer-qr-outside span{ font-size:8.5px; color:#231F18; font-weight:700; white-space:nowrap; }
@media print{
  .sheet-footer-qr-outside{ -webkit-print-color-adjust:exact; print-color-adjust:exact; }
}
/* A branch's own uploaded footer image (co.footerImg) replaces the dark
   structured address/contacts block above with a plain full-width image —
   same idea as .sheet-header-img for the header. The per-document rating
   QR box, when present, still sits beside it via the shared flex row. */
.sheet-footer-imgmode{ background:transparent; padding:0; border-radius:0; }
.sheet-footer-img-el{ display:block; width:100%; height:auto; }
/* Header/customer-info block made more compact (tighter row padding/
   height, narrower label column) than before, freeing vertical room for
   the larger line-items text and the enlarged signature/stamp below —
   his "منطقة بيانات الفاتورة وبيانات العميل تأخذ مساحة كبيرة" — while the
   text itself stays the same size or slightly larger (see the bumped
   table.doctable/pillsrow/netbar/wordsline sizes below), not smaller. */
.sheet-meta{ display:flex; gap:10px; margin-top:7px; }
.sheet-meta-box{ flex:1; border:1px solid #E3D9C2; border-radius:9px; overflow:hidden; }
.sheet-meta-box .row{ display:flex; border-bottom:1px solid #E3D9C2; font-size:11.5px; }
.sheet-meta-box .row:last-child{ border-bottom:none; }
.sheet-meta-box .row .l{ background:#F3EDDD; padding:3px 6px; font-weight:700; width:100px; flex:none; line-height:1.25; text-align:center; }
.sheet-meta-box .row .v{ padding:3px 6px; flex:1; line-height:1.3; text-align:center; }
.en-sub{ display:block; font-size:9.5px; font-weight:500; color:#8a7f63; margin-top:1px; }
.two-col{ display:flex; gap:10px; margin-top:7px; }
.party-single{ margin-top:7px; display:flex; gap:10px; align-items:stretch; }
.partybox{ flex:1; min-width:0; border-radius:9px; overflow:hidden; border:1px solid #E3D9C2; }
.partybox .head{ background:#231F18; color:#fff; text-align:center; font-weight:800; font-size:12px; padding:4px; }
.partybody{ padding:5px 9px; font-size:11.5px; line-height:1.4; }
.qrbox{ flex:0 0 auto; width:132px; height:132px; padding:7px; box-sizing:border-box; border:1px solid #E3D9C2; border-radius:9px; background:#fff; display:flex; align-items:center; justify-content:center; }
.qrbox svg{ display:block; width:100%; height:100%; }
/* Caption under the QR explaining what it's for (2026-09-08 follow-up) —
   wraps the existing .qrbox so it keeps behaving the same wherever it's
   dropped in (a plain block under the company-info rows, or as a flex
   item beside the customer partybox in .party-single). */
.qrbox-wrap{ flex:0 0 auto; display:flex; flex-direction:column; align-items:center; gap:4px; }
.qrbox-caption{ font-size:8.5px; color:#6b5f45; font-weight:700; text-align:center; max-width:132px; line-height:1.3; }
/* WLPO start/duration/end info, living beside the QR inside the
   company-info box (2026-09-08: first tried as its own horizontal table
   below the meta row, then moved here per his "قوم بوضع التواريخ فى
   المنطقة المجاورة للكود ... بدل من ترك المنطقة فارغه" — fills the empty
   space next to the QR instead of sitting in its own row). .qr-with-dates
   holds the QR (.qrbox-wrap, unchanged, flex:0 0 auto) plus this compact
   stack of three rows filling the rest of the box's width. */
.qr-with-dates{ display:flex; align-items:center; gap:10px; margin-top:6px; }
.wlpo-dates-aside{ flex:1; min-width:0; border:1px solid #E3D9C2; border-radius:9px; overflow:hidden; }
.wlpo-dates-aside .row{ display:flex; border-bottom:1px solid #E3D9C2; font-size:10.5px; }
.wlpo-dates-aside .row:last-child{ border-bottom:none; }
.wlpo-dates-aside .row .l{ background:#F3EDDD; padding:2px 6px; font-weight:700; width:92px; flex:none; line-height:1.2; text-align:center; }
.wlpo-dates-aside .row .v{ padding:2px 6px; flex:1; line-height:1.25; text-align:center; }
.projbar-row{ display:flex; justify-content:center; margin-top:9px; }
.projbar{ background:var(--gold-deep); color:#fff; text-align:center; font-weight:800; font-size:12px; padding:6px 20px; border-radius:9px; }
/* a fully ruled grid (outer frame + column/row dividers) rather than just a
   bottom rule per row — used by every document type's line-items table
   (both the formal invoice/credit view and the simpler request-type view,
   since both share this class). */
/* Enlarged per his "حجم الخطوط المستخدمة داخل النماذج صغيرة جدا" — this is
   the table the customer actually reads (line items/prices), so it gets
   the biggest bump of any print element here. */
table.doctable{ width:100%; border-collapse:collapse; margin-top:8px; font-size:12.5px; border:1px solid #231F18; }
table.doctable th{ background:#231F18; color:#fff; padding:5px 5px; font-weight:700; font-size:11px; line-height:1.3; border:1px solid #4a4030; }
table.doctable td{ padding:4px 5px; border:1px solid #E3D9C2; text-align:center; }
table.doctable td.desc{ text-align:start; }
table.doctable tbody tr:nth-child(even) td{ background:#FBF8EE; }
.pillsrow{ display:flex; gap:7px; margin-top:8px; }
.pillsrow .p{ flex:1; border-radius:8px; overflow:hidden; text-align:center; border:1px solid #E3D9C2; }
.pillsrow .p .l{ background:var(--gold-deep); color:#fff; font-size:10px; font-weight:700; padding:4px 3px; }
.pillsrow .p .v{ padding:5px 3px; font-weight:800; font-size:13px; }
.netbar{ margin-top:8px; background:#231F18; color:#fff; border-radius:9px; display:flex; justify-content:space-between; align-items:center; padding:8px 14px; font-weight:800; font-size:14px; }
.wordsline{ margin-top:7px; border:1px solid #E3D9C2; border-radius:9px; padding:5px 11px; font-size:11.5px; line-height:1.45; }
.closing-row{ display:flex; gap:12px; margin-top:8px; align-items:stretch; }
.closing-main{ flex:1; min-width:0; }
.closing-main .wordsline:first-child{ margin-top:0; }
.closing-aside{ flex:0 0 176px; display:flex; flex-direction:column; }
.stampbox{ flex:1; min-height:48px; margin-top:10px; border:1.5px dashed #cfc4a6; border-radius:9px; display:flex; align-items:center; justify-content:center; font-size:9.5px; font-weight:700; color:#a89a76; text-align:center; padding:4px; }
/* an uploaded branch stamp image replaces the dashed placeholder with a
   solid-bordered box sized to hold it, instead of the "stamp here" hint —
   a modest fixed basis (not flex:1) keeps a real stamp graphic at a
   natural, physical-stamp size instead of stretching to fill the aside
   column, while staying free to shrink so a signed sheet still fits one
   printed page exactly like the unsigned placeholder did. Enlarged per his
   "حجم الختم والتوقيع صغيرين جدا" — the header/customer-info and
   approval-date compaction elsewhere on this sheet free up the vertical
   room this needed. */
.stampbox.stampbox-img{ flex:0 1 92px; min-height:66px; border-style:solid; border-color:#E3D9C2; padding:3px; }
.stampbox.stampbox-img img{ max-width:100%; max-height:100%; object-fit:contain; }
.sigline{ border-top:1px solid #cfc4a6; padding-top:4px; margin-top:24px; font-size:10px; color:#7A705B; }
/* an uploaded manager-signature image sits in the gap above the sign-here
   line, in roughly the same vertical budget the blank margin-top:24 gap
   used to reserve for a handwritten signature — so a signed sheet keeps
   the same overall height as an unsigned one. Enlarged alongside the stamp
   above, same reason. */
.sig-img{ display:block; align-self:center; max-height:42px; max-width:170px; width:auto; object-fit:contain; margin:6px auto 0; }
.sigline.sigline-signed{ margin-top:2px; }

/* explicit page box: browser default print margins are often generous
   (roughly 1in on every side) and are the single biggest reason a
   short document spills onto a second page — reclaiming that space
   here is the highest-leverage fix for the "fit on one page" request. */
@page{ size:A4; margin:8mm 9mm; }

/* Reports (renderReports/renderAgingReport) carry a lot of columns — type/
   no/date/party/branch plus subtotal/vat/discount/retention/advance/
   otherAdj/net/currency, up to 13 in a cross-branch report — that never
   comfortably fit a portrait page's ~184mm usable width; on screen they
   just scroll sideways, but that scrolling doesn't exist on a printed page
   so the extra columns were silently clipped off. Printed landscape instead
   (his own request) so every column stays on the sheet. Chrome's support
   for a named @page (the standard "different page size for this one
   element" mechanism) turned out too unreliable to depend on here, so the
   actual orientation flip happens in JS instead — printWithTitle() injects
   a temporary style element (an "at page, size A4 landscape" rule) right
   before window.print() when asked to, and removes it again after.
   .sheet-report below only supplies that landscape page's own content-box
   width/height — every other document (invoice, credit note, quote,
   contract…) never gets that extra style element, so it keeps the normal
   portrait @page above, unaffected. */

@media print{
  /* The real cause of "even a simple/short document prints as 2 pages"
     (his report): visibility:hidden below keeps every hidden element's
     LAYOUT intact — only its paint is suppressed — so .app-shell (a flex
     row, min-height:100vh) still stretches to fit .sidebar's full natural
     height (every nav group, expanded, easily taller than one A4 page) even
     though the sidebar is invisible. That phantom height was what pushed
     the print job to a second, near-blank page, regardless of how short the
     actual printed .sheet was. Confirmed with an isolated repro: identical
     print CSS without this rule produced 2 pages for the shortest possible
     document; with it, 1. .sheet itself is unaffected — it's already lifted
     out of this layout entirely (position:absolute below) — this only
     collapses its now-pointless siblings. */
  .sidebar{ display:none !important; }
  /* Same phantom-layout-height bug as .sidebar above, but hitting .docwrap
     itself: the approval-cycle-log page (see approvalLogPageHtml) wraps its
     main .sheet in .multipkg-print, whose print rule sets
     .sheet{position:static} instead of the single-page case's
     position:absolute — so .sheet is no longer lifted out of layout
     entirely, and now sits at its real in-flow position, right after
     whatever else is invisibly still taking up space around it: the app's
     own top bar (.topbar) and any on-screen notice/error banner sitting in
     <main> beside .docwrap, plus, inside .docwrap itself, anything besides
     the actual sheet(s) — .docactions, the approval banner, the payments/
     email panels a document view can append after its sheet. Rather than
     naming each of those individually (and re-breaking the next time one
     is added), collapse everything in both spots except the printable
     content itself. .sheet/.multipkg-print are unaffected either way — a
     single .sheet is already lifted out of this layout via
     position:absolute below; a multipkg-print package needs to stay in
     flow for its own page-break mechanics to work, which is exactly why
     this couldn't just be ".sheet, .sheet *{ visibility:visible }" like
     everything else here. Confirmed via an isolated .sheet bounding-rect
     measurement: top:183px without this rule, top:0 with it.
     Two routes (the reports screen and the aging report) render their own
     filters card / bucket summary / .sheet-report directly as children of
     <main> — never wrapped in .docwrap at all — so .sheet/.multipkg-print
     have to stay excepted at the <main> level too, not just inside
     .docwrap, or this would blank out those screens' printed output
     instead of just tidying up the space above it. */
  /* .pp-print-ancestor (added transiently by printWithTitle()'s
     markPrintAncestors() right before window.print(), removed right after)
     exempts a specific chain of wrapper elements from the blanket hide rule
     below — needed for any printable .sheet that isn't a DIRECT child of
     .main/.docwrap the way the primary single-document print path is (e.g.
     the profile print tab's #printSheet sits inside a tabbed ".homepage"
     screen, several levels of ordinary "card"/tab markup deep). Without
     this, the exact same phantom-height bug this whole block was written to
     fix reappears one level removed: the non-.sheet wrapper chain around
     the .sheet gets display:none'd same as everything else, which (unlike
     plain visibility:hidden) removes the .sheet from rendering ENTIRELY
     too, since a display:none ancestor can't be un-hidden by any override
     on a descendant — producing a fully BLANK printed page instead of just
     an extra one. Confirmed via an isolated Playwright repro: the profile
     print tab's own #printSheet had a real, correctly-styled bounding box
     on screen but computed to no box at all (display:none inherited from
     its .homepage ancestor) once print media + this rule applied.
     Marked elements keep their ordinary (small) natural height instead of
     being removed outright — see markPrintAncestors' comment for why that
     residual height is harmless here, unlike the sidebar's. */
  .main > *:not(.docwrap):not(.sheet):not(.multipkg-print):not(.pp-print-ancestor){ display:none !important; }
  .docwrap > *:not(.sheet):not(.multipkg-print){ display:none !important; }
  body *{ visibility:hidden; }
  .sheet, .sheet *{ visibility:visible; }
  /* Without this, Chrome only prints background colors/images when the
     print dialog's own "Background graphics" checkbox is turned on — off
     by default, and most people never notice it. Every styled part of this
     document (the dark header/footer, the gold title pill, the tinted meta
     boxes, the VAT pills, table header shading, the watermark) relies on a
     background color to read correctly, so leaving that to a checkbox meant
     the printed PDF came out as plain white boxes with thin borders while
     the on-screen view stayed fully styled. print-color-adjust:exact forces
     Chrome to print those backgrounds regardless of that checkbox. */
  .sheet, .sheet *{ -webkit-print-color-adjust:exact; print-color-adjust:exact; color-adjust:exact; }
  .sheet{
    position:absolute; left:50%; top:0; transform:translateX(-50%); margin:0; box-shadow:none; border-radius:0;
    /* fit exactly within the @page content box above (210mm - 2*9mm) so
       nothing is ever clipped or auto-scaled unpredictably by the printer/driver */
    width:192mm; max-width:100%;
    padding:10px 14px 6px;
    /* Real bug he reported testing a longer WLPO: a document whose content
       actually needs a 2nd printed page lost its footer (and sometimes the
       tail of .closing-row) entirely — neither visible on the overflow
       page nor anywhere after. Root cause, confirmed with an isolated
       Playwright+PDF repro: the base (screen) .sheet rule above sets
       overflow:hidden (needed there, to clip the tiled watermark cleanly
       to this card's rounded corners) and nothing in THIS print rule ever
       resets it, so it was still in effect here. .sheet only ever gets a
       min-height, never a fixed height, so on screen that's harmless — the
       box always grows to fit its content. In print, though, this box is
       position:absolute and effectively spans the full stack of physical
       pages its content fragments across; some content past the end of
       page 1 was being clipped by that inherited overflow:hidden instead
       of flowing onto page 2 like the rest. overflow:visible here restores
       normal fragmentation — a short document (the overwhelming majority)
       is completely unaffected, since nothing in it ever exceeds this
       box's own bounds either way. */
    overflow:visible;
    /* stack header→body→footer in normal flow (unaffected — flex items
       still fragment across printed pages exactly like block children do)
       so a document that fits on one page gets min-height's leftover space
       absorbed by .sheet-footer's margin-top:auto below, pinning the
       footer to the bottom of that page; a document too long to fit just
       grows past min-height like any block box, and the footer lands
       right after the real last line of content — on whichever page that
       is — instead of the fixed min-height ever cutting content off. Kept
       a little under the true 281mm content box (297 - 2×8mm), matching
       the same safety margin .sheet-coverbg already uses below, so this
       never itself forces a stray near-empty extra page. */
    display:flex; flex-direction:column; min-height:265mm;
  }
  .sheet-report{
    /* the wider/shorter landscape page (see printWithTitle()'s injected
       @page override above): 297mm - 2×9mm width, 210mm - 2×8mm height,
       same safety margin under the true height as .sheet's own above. */
    width:279mm;
    min-height:178mm;
  }
  .sheet-footer{ margin-top:auto; }
  /* Attachment/supporting-file preview pages (filePreviewPageHtml — the
     claim package's IBAN/payment-sheet/license pages, and every regular
     document's own per-attachment pages) — a real pagination bug he
     reported from his own printed invoice: the page title ended up
     alone on one nearly-blank page, then the certificate image alone on
     the next with no header/footer, sometimes even the footer stranded
     alone on a further page.
     Measured root cause (confirmed with Playwright, not guessed): the
     header + title + footer together only need roughly 60mm of the
     ~281mm printable page height, so there'd be plenty of room — but a
     rendered PDF page/photo is displayed at its natural aspect ratio
     with only max-width:100% capping it, and a source page shaped like
     a normal A4/Letter document already needs ~270mm of height at that
     width. Header+title+image+footer together then need well over one
     physical page, and since a single <img> can never be split across
     a printed page break, the browser has no choice but to move the
     WHOLE image to the next page once it doesn't fit in the space left
     after the header+title — stranding the header+title alone with a
     big blank remainder, and leaving the image (and then the footer)
     to share whatever pages come after.
     Fix: cap how tall the attachment image is allowed to print at
     (.attach-preview-img below) to a value comfortably smaller than the
     printable page height minus a generous allowance for header+title+
     footer — chosen well above what a generic header/footer actually
     measures (~60mm) so a branch with a taller custom header/footer
     image still has slack. That keeps a normal single-page certificate
     or photo entirely on ONE page together with its header, title and
     footer, matching every other printed page in this app; a genuinely
     multi-page attachment (several stacked images under one title)
     still naturally flows onto further pages, which is expected. */
  .attach-preview-img{ max-height:195mm; width:auto; }
  .docactions{ display:none !important; }
  /* the on-screen approval banner (simple or multi-stage) and the
     WhatsApp "print then continue" banner — never painted anyway (see
     `body *{ visibility:hidden }` above), but needs its LAYOUT height
     removed too now that a document with an approval-cycle log page
     wraps its main .sheet in .multipkg-print, which puts .sheet back
     into normal flow (position:static) right after these banners in the
     DOM — see the comment on .approval-banner further up. */
  .approval-banner, .approval-cycle-wrap{ display:none !important; }
  /* if a document genuinely can't fit on one page (many line items), let it
     flow to a second page but break at sensible points, never mid-row/mid-block */
  .sheet-header-generic, .sheet-badge-row, .sheet-meta, .qr-with-dates, .two-col, .party-single,
  .partybox, .projbar-row, .pillsrow, .netbar, .wordsline, .closing-row,
  .sheet-footer, table.doctable tr, table.report-table tr{
    page-break-inside:avoid; break-inside:avoid;
  }
  table.doctable thead, table.report-table thead{ display:table-header-group; }
  /* the report table's own horizontal scroller (see .report-table-wrap):
     on screen it scrolls sideways, but print has no scrolling, so a
     scrolled-off column would otherwise just be silently clipped instead
     of printed — let it lay out at its full width instead (the wider
     .sheet-report page above, plus the tighter font/padding here, is what
     actually gets every column to fit without clipping or a horizontal
     print overflow). */
  .report-table-wrap{ overflow:visible; }
  table.report-table{ font-size:10.5px; }
  table.report-table th, table.report-table td{ padding:4px 6px; white-space:normal; word-break:break-word; }
}

/* ============================================================= multi-page document packages (claim package, contract package)
   Some print outputs are several .sheet pages in sequence instead of the
   usual single .sheet: the claim package (cover + claim request + proforma-
   invoice copy + IBAN certificate + payment-schedule copy) and the contract
   package (cover + details + payment schedule + closing). The generic
   .sheet print rule above absolutely-positions every .sheet at the same
   spot (correct for a single page); wrapping a package's pages in
   .multipkg-print overrides that back to normal in-flow stacking with an
   explicit page break between each one. Shared by both packages so the
   page-break mechanics never have to be duplicated. */
.multipkg-print{ display:flex; flex-direction:column; align-items:center; gap:18px; }
.multipkg-page-label{ width:800px; max-width:100%; font-weight:800; font-size:13px; opacity:.7; margin-bottom:-6px; }
@media print{
  .multipkg-print .sheet{ position:static; transform:none; margin:0 auto; page-break-after:always; break-after:page; }
  .multipkg-print .sheet:last-child{ page-break-after:auto; break-after:auto; }
  .multipkg-page-label{ display:none; }
}

/* ============================================================= إدارة العقود: auto-generated contract cover + closing pages
   The first and last pages of every printed contract package (see
   renderContractPackage) — a full-bleed architectural/blueprint background
   (CONTRACT_COVER_BG, the same unbranded image for every branch) tinted
   with the app's own gold brand color so it reads as part of this system
   rather than a random photo, with the branch's real letterhead (logo/
   name/address, via sheetHeaderHtml/sheetFooterHtml) printed on top. */
.sheet-coverbg{
  /* background-image itself is set inline per-render (app.js) from
     CONTRACT_COVER_BG, since head.html's asset placeholders are not part
     of build.py's substitution pass — only app.js's are; this class just
     supplies the shared sizing/layout so every renderer of it looks alike. */
  background-size: cover; background-position: center; min-height: 260mm;
  display:flex; flex-direction:column;
}
.sheet-coverbg .sheet-header-generic .co-name-ar,
.sheet-coverbg .sheet-header-generic .co-name-en{ text-shadow:0 1px 3px rgba(255,255,255,.6); }
.cover-title-block{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center;
  gap:14px; padding:30px 24px;
}
.cover-title-block .cover-kicker{ font-size:13px; font-weight:700; letter-spacing:.03em; color:var(--gold-deep); }
.cover-title-block .cover-main{ font-size:26px; font-weight:800; max-width:640px; }
.cover-title-block .cover-sub{ font-size:14px; font-weight:600; opacity:.85; }
.cover-title-block table{ margin:14px auto 0; font-size:13px; background:rgba(255,255,255,.72); border-radius:10px; }
.cover-title-block table td{ padding:6px 16px; }
.closing-title-block{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; gap:10px;
  padding:30px 24px;
}
.closing-title-block .closing-main{ font-size:30px; font-weight:800; }
@media print{
  .sheet-coverbg{ min-height: 265mm; }
}

/* ============================================================= المطالبات المالية: claim-package cover + closing (from a Preliminary
   Works Invoice — see renderClaimPackageFromDoc). A clean bordered frame
   with a small house-icon accent, modeled on a real claim cover he shared
   as a sample, instead of the blueprint-background style above — his own
   distinct style for this specific package. --claim-accent is set inline
   per-render from that branch's own logo (see branchAccentColor in
   app.js), so the border/icon color is genuinely per-branch, not a single
   fixed brand color. */
.claimcover-sheet{
  background:#fff;
  display:flex; flex-direction:column;
  min-height:260mm;
  padding:6px 4px 0;
}
/* His follow-up request on this specific cover/closing design: a watermark
   here too, but NOT the small tiled repeating pattern every other printed
   page uses (.sheet-watermark above) — "شعار واحد فقط فى منتصف الورقة
   فقط", one single logo, centered on the page, nothing repeating. Sized
   large and low-opacity so it reads as a background texture behind the
   bordered frame rather than competing with the big centered title text.
   Same direction:ltr/no-repeat-position pinning as .sheet-watermark, for
   the same reason (background-position resolved consistently regardless of
   the page's own text direction). */
.claimcover-watermark{
  position:absolute; inset:0; z-index:-1; direction:ltr;
  background-repeat:no-repeat; background-position:center center;
  background-size:60% auto; opacity:.05; pointer-events:none;
  -webkit-print-color-adjust:exact; print-color-adjust:exact;
}
.claimcover-frame{
  flex:1; position:relative;
  margin:6px 2px 14px;
  border:2px solid var(--claim-accent, #A9782F);
  border-radius:3px;
  display:flex; flex-direction:column;
  padding:34px 30px 26px;
}
.claimcover-icon{
  position:absolute; top:16px; inset-inline-start:18px;
  width:64px; height:46px;
}
.claimcover-kicker{
  font-size:13px; font-weight:700; letter-spacing:.08em; text-transform:uppercase;
  color:var(--claim-accent, #A9782F);
  /* physical left, opposite the house icon (top-right) so the two never
     collide regardless of the page's own text direction */
  text-align:left;
}
.claimcover-body, .claimclosing-body{
  flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; gap:22px;
}
/* Very large, bold, page-filling title — matching the reference sample's
   big centered cover-title treatment (his explicit request:
   "اجعل الخطوط كبيرة جدا كما كان فى النموذج الذى ارسلته لك"). */
.claimcover-body .claimcover-title{ font-size:42px; font-weight:800; max-width:640px; line-height:1.3; }
.claimclosing-body .claimcover-title{ font-size:56px; font-weight:800; }
.claimcover-code{ font-size:16px; font-weight:600; opacity:.75; direction:ltr; }
.claimcover-body table{ margin:14px auto 0; font-size:14px; background:rgba(0,0,0,.03); border-radius:10px; }
.claimcover-body table td{ padding:8px 18px; }
@media print{
  .claimcover-sheet{ min-height:265mm; }
}

/* ============================================================= مولد رموز QR: floating tool, available on every screen
   A single always-available button (fixed to the side of the screen, not
   tied to any one page/route) opens a small generator: free text/link, a
   contact card, a WiFi network, or manually-added custom fields — encoded
   with the same self-contained QR encoder (var QR) every printed sheet's
   rating/invoice QR already uses. See renderQrFab/renderQrToolModal/QR_DRAFT. */
.qr-fab{
  position:fixed; inset-inline-end:22px; bottom:26px; z-index:480;
  width:52px; height:52px; border-radius:50%; border:none; cursor:pointer;
  background:linear-gradient(135deg, var(--gold), var(--gold-deep)); color:#fff;
  font-size:22px; display:flex; align-items:center; justify-content:center;
  box-shadow:0 6px 18px rgba(0,0,0,.22); transition:transform .15s ease;
}
.qr-fab:hover{ transform:scale(1.06); }
.qr-modal-box{ width:100%; max-width:620px; max-height:92vh; overflow-y:auto; }
.qr-mode-tabs{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:14px; }
.qr-mode-tabs button{
  border:1px solid var(--line); background:var(--surface-2); color:var(--ink-soft);
  padding:7px 14px; border-radius:999px; font-size:12.5px; font-weight:700; cursor:pointer;
}
.qr-mode-tabs button.active{ background:var(--gold); border-color:var(--gold); color:#fff; }
.qr-layout{ display:flex; gap:20px; flex-wrap:wrap; align-items:flex-start; }
.qr-form-col{ flex:1 1 260px; min-width:240px; }
.qr-preview-col{ flex:0 0 200px; display:flex; flex-direction:column; align-items:center; gap:10px; }
.qr-preview-wrap{
  position:relative; width:180px; height:180px; display:flex; align-items:center; justify-content:center;
  background:#fff; border-radius:12px; box-shadow:0 0 0 1px var(--line); padding:6px;
}
.qr-preview-wrap svg{ width:100%; height:100%; }
.qr-preview-logo{
  /* kept small (~14% of the code's width) since the QR encoder below fixes
     error-correction at level M (~15% recoverable) — a bigger overlay risks
     covering enough real modules to make the code unreliable to scan */
  position:absolute; width:26px; height:26px; border-radius:50%; background:#fff; padding:3px;
  box-shadow:0 0 0 1px var(--line); object-fit:contain;
}
.qr-preview-empty{ font-size:12px; color:var(--ink-soft); text-align:center; padding:0 10px; }
.qr-capacity{ width:100%; max-width:180px; }
.qr-capacity-bar{ height:5px; border-radius:4px; background:var(--surface-2); overflow:hidden; }
.qr-capacity-bar-fill{ height:100%; background:var(--gold); transition:width .15s ease; }
.qr-capacity-bar-fill.qr-capacity-over{ background:var(--danger); }
.qr-capacity-label{ font-size:11px; color:var(--ink-soft); margin-top:3px; text-align:center; }
.qr-custom-row{ display:flex; gap:8px; margin-bottom:6px; }
.qr-custom-row input{ flex:1; }
.qr-history{ margin-top:20px; border-top:1px solid var(--line); padding-top:14px; }
.qr-history-item{
  display:flex; align-items:center; gap:10px; padding:8px 0; border-bottom:1px solid var(--line);
}
.qr-history-item:last-child{ border-bottom:none; }
.qr-history-item .qr-history-info{ flex:1; min-width:0; }
.qr-history-item .qr-history-label{ font-weight:700; font-size:13px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.qr-history-item .qr-history-meta{ font-size:11.5px; color:var(--ink-soft); }

/* ============================================================= redesign: grouped collapsible sidebar nav */
.nav button.navtop{ margin-bottom:2px; }
.navgroup{ display:flex; flex-direction:column; margin-top:2px; }
.navgroup-head{
  display:flex; align-items:center; gap:10px; width:100%; text-align:start; border:none; background:transparent;
  color:var(--ink-soft); padding:9px 10px; border-radius:var(--radius-sm); font-weight:700; font-size:13.5px; cursor:pointer;
}
.navgroup-head:hover{ background:var(--surface-2); color:var(--ink); }
.navgroup.open .navgroup-head{ color:var(--ink); }
.navgroup-head .ico{ width:18px; text-align:center; opacity:.85; }
.navgroup-title{ flex:1; }
.navgroup-chev{ font-size:11px; opacity:.75; }
.navgroup-body{ display:none; flex-direction:column; gap:2px; padding-inline-start:26px; margin-top:2px; }
.navgroup.open .navgroup-body{ display:flex; }
.navgroup-body button{
  display:flex; align-items:center; gap:9px; width:100%; text-align:start; border:none; background:transparent;
  color:var(--ink-soft); padding:8px 10px; border-radius:8px; font-weight:600; font-size:13px; cursor:pointer;
}
.navgroup-body button:hover{ background:var(--surface-2); color:var(--ink); }
.navgroup-body button.active{ background:var(--gold-soft); color:var(--gold-deep); font-weight:700; }
.navgroup-body button .ico{ width:16px; text-align:center; opacity:.9; }
#sidebarAddBranchBtn{ color:var(--gold-deep); }

/* ============================================================= redesign: topbar quick-search / command-menu triggers */
.topbar-actions{ display:flex; align-items:center; gap:8px; }
.topbar-iconbtn{
  border:1px solid var(--line); background:var(--surface); color:var(--ink); border-radius:999px;
  width:38px; height:38px; display:inline-flex; align-items:center; justify-content:center; font-size:15px; cursor:pointer;
}
.topbar-iconbtn:hover{ background:var(--surface-2); }
.topbar-iconbtn.active{ background:var(--gold-soft); border-color:var(--gold); color:var(--gold-deep); }

/* ============================================================= redesign: "أوامر النظام" command menu */
.cmdmenu{ max-width:340px; }
.cmdmenu-title{ font-family:'Cairo','Tajawal',sans-serif; font-weight:800; font-size:14.5px; margin-bottom:10px; }
.cmdmenu-list{ display:flex; flex-direction:column; gap:2px; }
.menuitem{
  display:flex; align-items:center; gap:11px; width:100%; text-align:start; border:none; background:transparent;
  color:var(--ink); padding:10px 12px; font-weight:600; font-size:13.5px; cursor:pointer; border-radius:8px;
}
.menuitem:hover{ background:var(--surface-2); }
.menuitem.cmdmenu-danger{ color:var(--danger); }
.menuitem.cmdmenu-danger:hover{ background:var(--danger-soft); }
.menuicon{ width:20px; text-align:center; font-size:14.5px; flex:none; }

/* ============================================================= redesign: quick "استعلام" search modal */
.qsmodal-head{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; margin-bottom:14px; }
.qsmodal-head h2{ margin:0 0 4px; font-size:16.5px; font-weight:800; }
.qsmodal-head p{ margin:0; font-size:12px; color:var(--ink-soft); }
.qsmodal-body input{
  width:100%; border:1.5px solid var(--gold); background:var(--paper); color:var(--ink); border-radius:11px;
  padding:11px 16px; font-size:14px; font-family:inherit; outline:none;
}
.qsmodal table.doclist tr{ cursor:pointer; }

/* ============================================================= redesign: friendly "no permission" screen */
.nopermcard{ max-width:460px; margin:10px auto; text-align:center; padding:36px 32px 30px; }
.noperm-illustration{
  width:88px; height:88px; margin:0 auto 16px; border-radius:50%; background:var(--danger-soft);
  display:flex; align-items:center; justify-content:center; font-size:38px;
}
.nopermcard h2{ margin:0 0 8px; font-size:18px; font-weight:800; }
.nopermcard p{ margin:0 0 22px; color:var(--ink-soft); font-size:13.5px; line-height:1.7; }

/* ============================================================= redesign: grouped permissions grid (toggle switches) */
/* Scoped to .permtogglerow specifically (permCheckboxRow's own output) —
   .permrow itself stays untouched so the unrelated checkbox lists that
   also use it (branch-approval picker, form-layout column toggles) keep
   their original plain layout. */
.permgroup{ background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; }
.permgroup-head{
  display:flex; align-items:center; gap:8px; padding:10px 14px; font-family:'Cairo','Tajawal',sans-serif;
  font-weight:800; font-size:12.5px; color:var(--gold-deep); border-bottom:1px solid var(--line); background:var(--surface-2);
}
.permgroup-ico{ font-size:13px; }
.permtogglerow{ justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--line); }
.permtogglerow:last-child{ border-bottom:none; }
.permtogglerow:hover{ background:var(--surface-2); }
.permrow-label{ flex:1; }
.permswitch{ position:relative; width:40px; height:23px; flex:none; }
.permswitch input{ position:absolute; inset:0; opacity:0; margin:0; cursor:pointer; width:100%; height:100%; }
.permswitch-track{ position:absolute; inset:0; border-radius:999px; background:var(--line); transition:background .15s; pointer-events:none; }
.permswitch-track::after{
  content:""; position:absolute; top:3px; inset-inline-start:3px; width:17px; height:17px; border-radius:50%;
  background:#fff; box-shadow:var(--shadow); transition:inset-inline-start .15s;
}
.permswitch input:checked ~ .permswitch-track{ background:var(--ok); }
.permswitch input:checked ~ .permswitch-track::after{ inset-inline-start:20px; }
.permswitch input:focus-visible ~ .permswitch-track{ outline:2px solid var(--gold); outline-offset:2px; }

/* ============================================================= redesign: home dashboard */
.homegrid{ display:grid; grid-template-columns:1fr 1fr; gap:18px; }
.homecard{ display:flex; flex-direction:column; }
.grouphead{ display:flex; align-items:center; gap:9px; margin-bottom:16px; }
.groupdot{ width:9px; height:9px; border-radius:50%; flex:none; }
.groupdot.dot-gold{ background:var(--gold); }
.groupdot.dot-info{ background:var(--info); }
.groupdot.dot-ok{ background:var(--ok); }
.groupdot.dot-amber{ background:var(--amber); }
.groupdot.dot-danger{ background:var(--danger); }
.grouptitle{ font-family:'Cairo','Tajawal',sans-serif; font-weight:800; font-size:14.5px; }
.grouptitle .hint{ font-weight:500; font-size:11px; color:var(--ink-soft); }
.tilesgrid{ display:grid; grid-template-columns:repeat(3, minmax(0,1fr)); gap:4px; }
.tile{ display:flex; flex-direction:column; align-items:center; gap:8px; padding:12px 6px; border-radius:12px; cursor:pointer; text-align:center; position:relative; }
.tile:hover{ background:var(--surface-2); }
.tile .badge{
  width:52px; height:52px; border-radius:16px; display:flex; align-items:center; justify-content:center;
  font-size:22px; flex:none; background:var(--surface-2); color:var(--ink);
}
.tile[data-nav="new"] .badge, .tile[data-nav="list"] .badge{ background:var(--gold-soft); color:var(--gold-deep); }
.homegrid > div:nth-child(2) .tile .badge{ background:var(--info-soft); color:var(--info); }
.homegrid > div:nth-child(3) .tile .badge{ background:var(--ok-soft); color:var(--ok); }
.homegrid > div:nth-child(4) .tile .badge{ background:var(--amber-soft); color:var(--amber); }
.tilelabel{ font-size:12.5px; font-weight:700; color:var(--ink); line-height:1.35; }
.tile.has-flyout:hover .tile-flyout, .tile.has-flyout:focus-within .tile-flyout{ display:flex; }
.tile-flyout{
  display:none; flex-direction:column; position:absolute; top:6px; z-index:20;
  inset-inline-end:calc(100% + 10px); width:210px; background:var(--surface); border:1px solid var(--line);
  border-radius:12px; box-shadow:0 18px 40px rgba(35,31,24,.22); padding:8px; text-align:start;
}
.tile-flyout-title{ padding:8px 10px 6px; font-size:11px; font-weight:800; color:var(--ink-soft); font-family:'Cairo',sans-serif; }
.flyitem{
  display:flex; align-items:center; gap:10px; width:100%; text-align:start; border:none; background:transparent;
  color:var(--ink); padding:9px 12px; font-weight:600; font-size:13px; cursor:pointer; border-radius:8px;
}
.flyitem:hover{ background:var(--ok-soft); color:var(--ok); }

@media (max-width: 860px){
  .app-shell{ flex-direction:column; }
  .sidebar{ width:100%; flex-direction:row; align-items:center; border-inline-start:none; border-bottom:1px solid var(--line); }
  .nav{ flex-direction:row; }
  .sidebar-foot{ display:none; }
  .form-grid{ grid-template-columns:1fr; }
  .adjGrid{ grid-template-columns:repeat(2,1fr); }
  .main{ padding:18px; }
  .homegrid{ grid-template-columns:1fr; }
  .tile-flyout{ position:fixed; inset-inline:16px; top:auto; width:auto; }
}
