/* ============================================================================
   app.css — Operator Console theme for the Saudi recruitment platform
   Arabic-RTL first. Plain CSS, no build step. Used directly by Django templates.

   Fonts are fully self-hosted (no external CDN, PDPL/privacy + availability): Cairo (sans,
   variable) and IBM Plex Mono (mono, weights 400/500/600) via @font-face below.

   Aesthetic: calm, dense, trustworthy back-office. One confident accent
   (institutional jade/teal, grounded in the Musaned gov-rail world the
   operators live in), cool-paper neutrals, scannable tables and boards.
   Signature: the stage rail — the Request state machine made visible.
   ========================================================================== */

/* IBM Plex Mono — mono face for IDs / رقم السيرة / refs (--font-mono). Self-hosted (no CDN),
   latin subset, three weights matching the prior CDN load (OFL). */
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:400; font-display:swap;
  src:url("../fonts/IBMPlexMono-400.79936b18df9f.woff2") format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:500; font-display:swap;
  src:url("../fonts/IBMPlexMono-500.b1c8a895f5fd.woff2") format('woff2');
}
@font-face{
  font-family:'IBM Plex Mono'; font-style:normal; font-weight:600; font-display:swap;
  src:url("../fonts/IBMPlexMono-600.5a2ce7798732.woff2") format('woff2');
}

/* Cairo — the official platform typeface (Google Fonts, OFL). Self-hosted (no CDN)
   as a variable font: one Arabic + one Latin subset cover every weight 100–900. */
@font-face{
  font-family:'Cairo'; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("../fonts/Cairo-arabic.4d90a59cb181.woff2") format('woff2');
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088E,U+08A0-08FF,U+200C-200E,U+2010-2011,U+204F,U+2E41,U+FB50-FDFF,U+FE70-FEFC;
}
@font-face{
  font-family:'Cairo'; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("../fonts/Cairo-latin.3c9597566d23.woff2") format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215;
}

/* ----------------------------------------------------------------------------
   1. DESIGN TOKENS
   ------------------------------------------------------------------------- */
/* 1a. SHARED (non-themeable) tokens — spacing, radii, type, layout, motion.
   Every COLOR/SHADOW token is theme-scoped below (1b dark = default, 1c light)
   so a single [data-theme] attribute on <html> flips the whole app. Keep token
   NAMES stable across themes so all screens re-colour automatically. */
:root {
  /* --- Typography --- */
  --font-sans: 'Cairo', 'IBM Plex Sans Arabic', system-ui, 'Segoe UI', Tahoma, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace; /* IDs, رقم السيرة, refs */

  --fs-display: 1.5rem;    /* 24px — page title */
  --fs-h2:      1.125rem;  /* 18px — section heading */
  --fs-h3:      1rem;      /* 16px */
  --fs-body:    0.875rem;  /* 14px — default UI text */
  --fs-sm:      0.8125rem; /* 13px — meta, table cells */
  --fs-xs:      0.75rem;   /* 12px — labels, captions, pills */

  --lh-tight:   1.3;
  --lh-body:    1.6;       /* Arabic reads better with generous leading */

  --fw-regular: 400;
  --fw-medium:  500;
  --fw-semi:    600;
  --fw-bold:    700;

  /* Latin/mono readout tracking — safe, NEVER applied to Arabic glyphs. */
  --data-track: .01em;

  /* --- Spacing (4px base) --- */
  --sp-1: 0.25rem;  --sp-2: 0.5rem;  --sp-3: 0.75rem; --sp-4: 1rem;
  --sp-5: 1.25rem;  --sp-6: 1.5rem;  --sp-8: 2rem;    --sp-10: 2.5rem; --sp-12: 3rem;

  /* --- Radius --- */
  --r-sm: 6px;   --r-md: 8px;   --r-lg: 12px;   --r-pill: 999px;

  /* --- Layout --- */
  --shell-side:  248px;   /* sidebar width */
  --shell-top:   56px;    /* topbar height */
  --content-max: 1400px;

  --dur: 140ms;
  --ease: cubic-bezier(.2,.6,.2,1);

  /* focus ring formula (resolves the themed --accent-ring at point of use) */
  --sh-focus: 0 0 0 3px var(--accent-ring);
}

/* 1b. DARK THEME — "لوحة القيادة" cockpit. This is the DEFAULT (bare :root),
   so the app renders dark even with JS disabled / no data-theme attribute.
   Near-black charcoal surfaces + one luminous jade signal + status glows. */
:root,
:root[data-theme="dark"] {
  /* --- Charcoal surface stack (canvas darkest → surface raised) --- */
  --canvas:        #0a0d10;   /* app backdrop */
  --surface:       #141a20;   /* cards, panels, rows (raised) */
  --surface-2:     #1e262e;   /* headers / hover / wells (a notch lighter = lift) */
  --surface-3:     #0d1116;   /* deep inset / empty pips */
  --ink:           #e8edf2;   /* primary text — AA on surface */
  --ink-1:         #e8edf2;   /* high-contrast fill/text alias */
  --ink-2:         #9fb0bd;   /* secondary text */
  --ink-3:         #7f909d;   /* tertiary / meta / captions (AA on --surface: ~5:1) */
  --ink-on-accent: #04140d;   /* dark glyph on luminous jade */
  --line:          #232c35;   /* hairline borders */
  --line-strong:   #2e3a45;   /* emphasized borders, dividers */

  /* --- The one accent: luminous jade — a precise signal, never a wash --- */
  --accent:        #1fd18a;   /* primary action / signal */
  --accent-hover:  #38d99b;
  --accent-press:  #16b57a;
  --accent-soft:   #10251d;   /* dark jade tint for active nav / soft badges */
  --accent-ring:   rgba(31,209,138,.40);

  /* --- Functional (glow on dark) --- */
  --danger:        #ff5a5f;
  --danger-hover:  #ff7a7e;
  --danger-soft:   #2a1613;
  --warn:          #ffb020;
  --warn-soft:     #2a2010;
  --ok:            #35d07f;
  --ok-soft:       #0f2a1c;
  --info:          #4aa8ff;
  --info-soft:     #132639;

  /* --- Semantic STATUS colors — dark tint bg + luminous fg + vivid dot --- */
  --st-new-bg:        #1a2230;  --st-new-fg:        #9fb6d8;  --st-new-dot:        #6b7c97;
  --st-reserved-bg:   #2a2211;  --st-reserved-fg:   #e6a93a;  --st-reserved-dot:   #c98a12;
  --st-visa-bg:       #1c1f3a;  --st-visa-fg:       #9296f2;  --st-visa-dot:       #5a5fd6;
  --st-active-bg:     #10281d;  --st-active-fg:     #4fd88a;  --st-active-dot:     #2f9d54;
  --st-transfer-bg:   #0e2a2c;  --st-transfer-fg:   #3cc9d4;  --st-transfer-dot:   #1d949e;
  --st-rental-bg:     #211a33;  --st-rental-fg:     #bd91e2;  --st-rental-dot:     #8b53c4;
  --st-closed-bg:     #1b2320;  --st-closed-fg:     #9fada6;  --st-closed-dot:     #8a948f;
  --st-cancelled-bg:  #2a1512;  --st-cancelled-fg:  #ff8681;  --st-cancelled-dot:  #cf4239;
  /* Worker-lifecycle S2: ink for the "current" step node (sits on --warn). */
  --step-current-ink: #3a2700;

  /* --- Shadows (deep black — panels lift off the charcoal backdrop) --- */
  --sh-sm: 0 1px 2px rgba(0,0,0,.35);
  --sh-md: 0 2px 8px rgba(0,0,0,.40), 0 12px 32px rgba(0,0,0,.45);
  --sh-lg: 0 16px 48px rgba(0,0,0,.60);
}

/* 1c. LIGHT THEME — today's institutional cool-paper palette, unchanged. */
:root[data-theme="light"] {
  /* --- Brand & neutrals (cool paper, ink with a faint green-gray cast) --- */
  --canvas:        #eef1ef;   /* app background — cool paper, not stark white */
  --surface:       #ffffff;   /* cards, panels, rows */
  --surface-2:     #f6f8f7;   /* table headers, subtle fills, hover */
  --surface-3:     #e6ebe8;   /* deeper inset (rarely used) */
  --ink:           #16211d;   /* primary text — near-black, green-gray cast */
  --ink-1:         #16211d;   /* high-contrast fill/text alias */
  --ink-2:         #45524d;   /* secondary text */
  --ink-3:         #6b7873;   /* tertiary / meta / captions */
  --ink-on-accent: #ffffff;
  --line:          #dde3e0;   /* hairline borders */
  --line-strong:   #c7d0cc;   /* emphasized borders, dividers */

  /* --- The one accent: institutional jade/teal (the Musaned/gov-rail world) --- */
  --accent:        #0f6e5a;   /* primary action */
  --accent-hover:  #0b5a49;
  --accent-press:  #084538;
  --accent-soft:   #e3f0ec;   /* tinted fill for selected / active nav */
  --accent-ring:   #88c4b5;   /* focus ring */

  /* --- Functional --- */
  --danger:        #b3261e;
  --danger-hover:  #971c16;
  --danger-soft:   #fbe9e7;
  --warn:          #9a6700;
  --warn-soft:     #fdf3df;
  --ok:            #1e7a3e;
  --ok-soft:       #e6f2ea;
  --info:          #2a5d9f;
  --info-soft:     #e8f0f9;

  /* --- Semantic STATUS colors, one per case stage ---------------------------
     Soft tinted background + saturated foreground + a solid dot, so a pill is
     readable, calm, and instantly distinguishable in a dense board/table.    */
  --st-new-bg:        #eef1f4;  --st-new-fg:        #41526b;  --st-new-dot:        #6b7c97;  /* جديد */
  --st-reserved-bg:   #fbf0d8;  --st-reserved-fg:   #8a5a00;  --st-reserved-dot:   #c98a12;  /* تم الحجز */
  --st-visa-bg:       #e8eafc;  --st-visa-fg:       #3b3f9c;  --st-visa-dot:       #5a5fd6;  /* التأشيرة */
  --st-active-bg:     #e2f1e7;  --st-active-fg:     #1e7a3e;  --st-active-dot:     #2f9d54;  /* نشط / قيد الخدمة */
  --st-transfer-bg:   #def0f1;  --st-transfer-fg:   #0e6b73;  --st-transfer-dot:   #1d949e;  /* نقل / تنازل */
  --st-rental-bg:     #efe7f7;  --st-rental-fg:     #6a3a98;  --st-rental-dot:     #8b53c4;  /* تأجير */
  --st-closed-bg:     #eceeed;  --st-closed-fg:     #5a655f;  --st-closed-dot:     #8a948f;  /* مغلق / مكتمل */
  --st-cancelled-bg:  #fbe7e6;  --st-cancelled-fg:  #a52b23;  --st-cancelled-dot:  #cf4239;  /* ملغي */
  /* Worker-lifecycle S2: ink for the "current" step node (sits on --warn). */
  --step-current-ink: #ffffff;

  /* --- Shadows (low, layered — a calm tool, not a floaty app) --- */
  --sh-sm: 0 1px 2px rgba(16,33,29,.06), 0 1px 1px rgba(16,33,29,.04);
  --sh-md: 0 2px 4px rgba(16,33,29,.06), 0 4px 12px rgba(16,33,29,.07);
  --sh-lg: 0 8px 28px rgba(16,33,29,.14);
}

/* ----------------------------------------------------------------------------
   2. RESET & BASE
   ------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--canvas);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* RTL default. Set dir="rtl" lang="ar" on <html>. */
[dir="rtl"] { direction: rtl; }

h1, h2, h3, h4 { margin: 0; font-weight: var(--fw-semi); line-height: var(--lh-tight); color: var(--ink); }
p { margin: 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* IMPORTANT RTL/Arabic rule: never letter-space Arabic — it breaks the
   connected glyphs. Letter-spacing is opt-in via .u-label for Latin only. */

/* Numerals & codes: keep Latin/Western digits LTR-isolated, tabular for tables */
.num, .u-mono { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-feature-settings: "tnum"; }
/* The comment above promised isolation for years and the rule below it never delivered any.
   `unicode-bidi:isolate` is content-agnostic, so it is safe on the .num spans that still wrap
   Arabic — `direction:ltr` is NOT (it reorders «90 يوماً» into «يوماً 90») and stays withheld
   until every .num wraps digits ONLY. And a digit run never breaks across lines: «450,000.00»
   split over two lines is a second way of reading a different number.
   Design plan: .orbit/reviews/s2-s4-design-320.md §2 (C2/C3). */
.num { unicode-bidi: isolate; white-space: nowrap; }
bdi, .ltr { unicode-bidi: isolate; }
.tnum { font-variant-numeric: tabular-nums; }

::selection { background: var(--accent-soft); }

/* Visible keyboard focus everywhere */
:focus-visible {
  outline: none;
  box-shadow: var(--sh-focus);
  border-radius: var(--r-sm);
}

/* Custom scrollbars — quiet */
* { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb { background: var(--line-strong); border-radius: var(--r-pill); border: 2px solid var(--canvas); }

/* ----------------------------------------------------------------------------
   3. APP SHELL (RTL: sidebar on the right, topbar across the top)
   ------------------------------------------------------------------------- */
.app {
  display: grid;
  grid-template-columns: 1fr var(--shell-side);   /* content | sidebar (RTL) */
  grid-template-rows: var(--shell-top) 1fr;
  grid-template-areas:
    "topbar  topbar"
    "main    sidebar";
  min-height: 100vh;
}

.topbar {
  grid-area: topbar;
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding-inline: var(--sp-5);
  background: var(--surface);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 30;
}
.topbar__brand { display: flex; align-items: center; gap: var(--sp-3); font-weight: var(--fw-semi); font-size: var(--fs-h3); }
.topbar__brand .mark {
  width: 28px; height: 28px; border-radius: var(--r-sm);
  background: var(--accent); color: var(--ink-on-accent);
  display: grid; place-items: center; font-weight: var(--fw-bold); font-size: var(--fs-sm);
}
.topbar__spacer { flex: 1; }
.topbar__search {
  flex: 0 1 360px;
  display: flex; align-items: center; gap: var(--sp-2);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding-inline: var(--sp-3); height: 36px;
}
.topbar__search input { border: 0; background: transparent; outline: none; width: 100%; font: inherit; color: var(--ink); }
.topbar__search:focus-within { border-color: var(--accent-ring); box-shadow: var(--sh-focus); }
.topbar__user { display: flex; align-items: center; gap: var(--sp-2); }

.sidebar {
  grid-area: sidebar;
  background: var(--surface);
  border-inline-start: 1px solid var(--line);  /* the edge facing the content */
  padding: var(--sp-4) var(--sp-3);
  display: flex; flex-direction: column; gap: var(--sp-1);
  position: sticky; top: var(--shell-top); height: calc(100vh - var(--shell-top));
  overflow-y: auto;
}
.nav-group__label {
  font-size: var(--fs-xs); color: var(--ink-3); font-weight: var(--fw-semi);
  padding: var(--sp-3) var(--sp-3) var(--sp-2);
}
.nav-link {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  color: var(--ink-2); font-weight: var(--fw-medium); font-size: var(--fs-body);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
  text-decoration: none; position: relative;
}
.nav-link:hover { background: var(--surface-2); color: var(--ink); text-decoration: none; }
.nav-link.is-active { background: var(--accent-soft); color: var(--accent); font-weight: var(--fw-semi); }
.nav-link.is-active::before {
  /* active marker on the inline-start edge (RTL-aware) */
  content: ""; position: absolute; inset-inline-start: 0; top: 18%; bottom: 18%;
  width: 3px; border-radius: var(--r-pill); background: var(--accent);
}
.nav-link .ico { width: 18px; height: 18px; flex: none; color: currentColor; opacity: .85; }
.nav-link .count {
  margin-inline-start: auto; font-family: var(--font-mono); font-size: var(--fs-xs);
  background: var(--surface-2); color: var(--ink-3); padding: 1px var(--sp-2); border-radius: var(--r-pill);
}
.nav-link.is-active .count { background: #ffffff; color: var(--accent); }

/* ---- Sidebar sections (S1) — collapsible <details class="nav-parent"> tree ----------------
   A parent SUMMARY looks like a nav-link but toggles its child list; children nest under a
   connector line (RTL-aware via logical properties). Native <details> gives the a11y + toggle;
   the inline script persists open/closed per browser and force-opens the active section. */
.nav-parent { margin: 0; }
.nav-parent__row {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  color: var(--ink-2); font-weight: var(--fw-medium); font-size: var(--fs-body);
  cursor: pointer; user-select: none; list-style: none;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.nav-parent__row::-webkit-details-marker { display: none; }   /* kill the native ▶ marker */
.nav-parent__row:hover { background: var(--surface-2); color: var(--ink); }
.nav-parent__row:focus-visible { outline: none; box-shadow: var(--sh-focus); }
.nav-parent__row .ico { width: 18px; height: 18px; flex: none; color: currentColor; opacity: .85; }
.nav-parent__chev {
  width: 16px; height: 16px; flex: none; margin-inline-start: auto; opacity: .55;
  transition: transform var(--dur) var(--ease);
}
.nav-parent[open] > .nav-parent__row .nav-parent__chev { transform: rotate(180deg); }
/* a section holding the active route reads as lightly active on its summary */
.nav-parent:has(.nav-link.is-active) > .nav-parent__row { color: var(--ink); }

.nav-sub {
  list-style: none; margin: var(--sp-1) 0 var(--sp-2); padding: 0;
  margin-inline-start: 21px;                     /* aligns the rail under the summary icon centre */
  border-inline-start: 1px solid var(--line);
}
.nav-sub li { position: relative; }
.nav-sub li::before {                            /* the connector tick from the rail into the row */
  content: ""; position: absolute; inset-inline-start: 0; top: 50%;
  width: var(--sp-3); height: 1px; background: var(--line);
}
.nav-sub .nav-link { padding-inline-start: var(--sp-4); font-size: var(--fs-sm); }
.nav-badge {                                     /* approvals + WA unread badge in the tree */
  margin-inline-start: auto; font-size: 11px; padding: 1px var(--sp-2); border-radius: var(--r-pill);
}
@media (prefers-reduced-motion: reduce) { .nav-parent__chev { transition: none; } }

.main {
  grid-area: main;
  padding: var(--sp-6) var(--sp-6) var(--sp-12);
  /* clip (not hidden): same horizontal-overflow backstop, but WITHOUT registering .main as the
     scroll container — so position:sticky descendants (e.g. .case-aside / .cd2-aside) bind to the
     window and actually stick. `hidden` silently broke every in-page sticky panel. */
  overflow-x: clip;
}
.main__inner { max-width: var(--content-max); margin-inline: auto; }

/* Page header band */
.page-head { display: flex; align-items: flex-start; gap: var(--sp-4); margin-bottom: var(--sp-5); flex-wrap: wrap; }
.page-head__titles { flex: 1; min-width: 0; }
.page-title { font-size: var(--fs-display); font-weight: var(--fw-semi); }
.page-sub { color: var(--ink-3); font-size: var(--fs-sm); margin-top: 2px; }
.page-head__actions { display: flex; gap: var(--sp-2); align-items: center; }

/* Breadcrumb */
.crumbs { display: flex; gap: var(--sp-2); align-items: center; color: var(--ink-3); font-size: var(--fs-sm); margin-bottom: var(--sp-3); }
.crumbs a { color: var(--ink-3); }
.crumbs .sep { opacity: .5; }
/* directional chevron flips automatically because layout is RTL; use » as a neutral mark */

/* Linked page tabs — separate URL per tab, current one marked active server-side (NOT a
   client-side JS panel-switcher). Introduced for Settings › التأجير بالساعة
   (templates/core/_hourly_settings_tabs.html); generic enough to reuse anywhere a
   multi-page section wants an underline tab bar instead of the sidebar's nav-parent tree. */
.tabs { display: flex; gap: var(--sp-1); border-bottom: 1px solid var(--line); margin-bottom: var(--sp-5); overflow-x: auto; }
.tab { display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); border-bottom: 2px solid transparent; margin-bottom: -1px; color: var(--ink-3); font-size: var(--fs-body); font-weight: var(--fw-medium); text-decoration: none; white-space: nowrap; transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.tab:hover { color: var(--ink); text-decoration: none; }
.tab.is-active { color: var(--accent); border-bottom-color: var(--accent); font-weight: var(--fw-semi); }

/* ----------------------------------------------------------------------------
   4. CARDS & PANELS
   ------------------------------------------------------------------------- */
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--sh-sm);
}
.card__head {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4) var(--sp-5);
  border-bottom: 1px solid var(--line);
}
.card__title { font-size: var(--fs-h3); font-weight: var(--fw-semi); }
.card__head .spacer { flex: 1; }
.card__body { padding: var(--sp-5); }
.card__body--flush { padding: 0; }
.card__foot { padding: var(--sp-3) var(--sp-5); border-top: 1px solid var(--line); display: flex; gap: var(--sp-2); }

/* Stat tiles — restrained: a label, a tabular number, a small delta. No gradient. */
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--sp-4); }
.stat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--sp-4) var(--sp-5); }
.stat__label { font-size: var(--fs-xs); color: var(--ink-3); font-weight: var(--fw-medium); }
.stat__value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 1.625rem; font-weight: var(--fw-semi); margin-top: 2px; letter-spacing: -.01em; }
.stat__delta { font-size: var(--fs-xs); margin-top: var(--sp-1); }
.stat__delta.up { color: var(--ok); }
.stat__delta.down { color: var(--danger); }

/* F2 (doc-expiry report) — a leading accent bar + colored value keyed to the traffic-light
   band. Report-local but still token-driven, so dark/light follow automatically. */
.stat--danger { border-inline-start: 3px solid var(--danger); }
.stat--warn   { border-inline-start: 3px solid var(--warn); }
.stat--muted  { border-inline-start: 3px solid var(--ink-3); }
.stat--accent { border-inline-start: 3px solid var(--accent); }
.stat--danger .stat__value { color: var(--danger); }
.stat--warn   .stat__value { color: var(--warn); }
.stat--muted  .stat__value { color: var(--ink-2); }

/* ----------------------------------------------------------------------------
   5. STATUS PILLS — one per case stage (the semantic status system)
   ------------------------------------------------------------------------- */
.pill {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 2px var(--sp-3) 2px var(--sp-2);
  border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); line-height: 1.7;
  white-space: nowrap;
}
.pill::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; opacity: .9; flex: none; }

/* Mobile scroll hint (reviewer nit): a horizontally-scrollable table gets an inner edge fade
   on the side hiding more columns (RTL: content overflows leftward). JS toggles the classes.
   The fade is the SURFACE colour, not black: on the dark theme a black shadow over #141a20 is
   black on black, so the affordance ran correctly and was invisible exactly where the screen is
   narrowest. Deriving it from var(--surface) makes the content fade INTO the card in both
   themes and needs no second declaration (design plan §3). */
.table-wrap.has-hscroll { box-shadow: inset 24px 0 16px -16px var(--surface); }
.table-wrap.has-hscroll.at-hend { box-shadow: none; }
/* …and a fade is not a sentence. The line below is inserted by _base.html after any wrap that
   REALLY scrolls, and CSS keeps it honest: it is visible only while there is more to reach, and
   disappears at the end of the run — a hint that stays up after the last column is a fake
   affordance (§7). */
.scroll-hint {
  display: none; align-items: center; gap: 6px;
  margin-top: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3);
}
.table-wrap.has-hscroll + .scroll-hint { display: inline-flex; }
.table-wrap.has-hscroll.at-hend + .scroll-hint { display: none; }
.scroll-hint svg {
  width: 13px; height: 13px; flex: none;
  stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}

/* Active-filter chip — shows which dashboard drill-in is applied to a list, with an × to clear. */
.filter-chip-row { margin-top: var(--sp-2); }
.filter-chip {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  padding: 3px var(--sp-2) 3px var(--sp-3);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--accent-soft, rgba(15,110,90,.08)); color: var(--ink-1);
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
}
.filter-chip__clear {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  color: var(--ink-2); text-decoration: none; font-size: 15px; line-height: 1;
}
.filter-chip__clear:hover { background: var(--line); color: var(--ink-1); }
.filter-chip__clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* F2 (doc-expiry report) — band-filter chips reuse .filter-chip but as a navigational TOGGLE:
   inactive = surface, active = accent-soft. Scoped under .doc-report so the always-on
   accent-soft appearance of the global applied-filter chip (above) is untouched elsewhere. */
.doc-report .filter-chip {
  background: var(--surface); color: var(--ink-2);
  cursor: pointer; text-decoration: none;
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.doc-report .filter-chip:hover { border-color: var(--ink-3); color: var(--ink-1); text-decoration: none; }
.doc-report .filter-chip.is-active { background: var(--accent-soft); border-color: transparent; color: var(--ink-1); }
.filter-chip__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.filter-chip__n { font-family: var(--font-mono); opacity: .85; }

/* F2 date cell — Gregorian (mono) over the secondary Hijri line; and the remaining-days cell. */
.date-cell { display: flex; flex-direction: column; line-height: 1.35; }
.date-cell .greg { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: var(--fs-sm); color: var(--ink); }
.date-cell .hijri { font-size: var(--fs-xs); color: var(--ink-3); }
.rem { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: var(--fw-semi); }
.rem--over { color: var(--danger); }
.rem--soon { color: var(--warn); }
.rem--none { color: var(--ink-3); }
.rem__unit { font-family: var(--font-sans); font-weight: var(--fw-regular); font-size: var(--fs-xs); color: var(--ink-3); margin-inline-start: 2px; white-space: nowrap; }

/* F1 housing report — worker identity cell (round initials avatar + name) + exception strip.
   Token-driven; mirrors the inbox-item avatar idiom. */
.cell-worker { display: inline-flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.ava { width: 30px; height: 30px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--line); display: grid; place-items: center; color: var(--ink-3); font-weight: var(--fw-semi); font-size: var(--fs-xs); flex: none; }
.cell-worker__name { font-weight: var(--fw-medium); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cell-worker__nat { color: var(--ink-3); font-size: var(--fs-xs); }
.exc-strip { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); padding: var(--sp-3) var(--sp-4); }
.exc-strip__label { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink-2); display: inline-flex; align-items: center; gap: var(--sp-2); }
.exc-strip__label::before { content: "\2691"; color: var(--danger); }
.exc-strip .badge { font-size: var(--fs-sm); padding: 3px var(--sp-3); text-decoration: none; }
.exc-strip a.badge:hover { text-decoration: none; filter: brightness(1.08); }

/* Severity filter chips on the "needs action" panel — interactive (client-side row filter). */
.sev-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px var(--sp-3); border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface, #fff); color: var(--ink-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); cursor: pointer;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.sev-chip:hover { border-color: var(--ink-3, #9aa5a0); color: var(--ink-1); }
.sev-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.sev-chip.is-active { background: var(--ink-1); border-color: var(--ink-1); color: #fff; }
.sev-chip--danger.is-active { background: var(--danger); border-color: var(--danger); }
.sev-chip--warn.is-active { background: var(--warn); border-color: var(--warn); color: #3a2700; }

/* S2 (F6/F7): the one-tap bucket bar — segmented, pre-canned status filters with count
   badges. Token-driven (dark/light follow automatically), RTL-safe (pure flex, no
   directional offsets), wraps on phones. */
.bucket-bar {
  display: flex; flex-wrap: wrap; gap: 2px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 2px;
  margin: var(--sp-3) 0 var(--sp-1);
}
.bucket-bar__seg {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--ink-2);
  padding: var(--sp-1) var(--sp-3); border-radius: var(--r-sm);
  min-height: 32px; text-decoration: none; white-space: nowrap;
}
.bucket-bar__seg:hover { color: var(--ink-1); text-decoration: none; }
.bucket-bar__seg:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.bucket-bar__seg.is-active {
  background: var(--surface); color: var(--ink-1);
  box-shadow: var(--sh-sm); font-weight: var(--fw-semi);
}
.bucket-bar__count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; padding: 0 var(--sp-1); border-radius: var(--r-pill);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); line-height: 1.6;
  background: var(--line); color: var(--ink-2);
}
.bucket-bar__seg.is-active .bucket-bar__count { background: var(--accent-soft); color: var(--accent); }

/* S2 (F8): the one-tap nationality chips row (directly above «تصفية متقدمة»). */
.nat-chip-row { display: flex; flex-wrap: wrap; gap: var(--sp-2); margin: var(--sp-1) 0 var(--sp-2); }
.nat-chip {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: 3px var(--sp-3); border-radius: var(--r-pill);
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-2);
  font-size: var(--fs-xs); font-weight: var(--fw-semi); text-decoration: none;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.nat-chip:hover { border-color: var(--ink-3); color: var(--ink-1); text-decoration: none; }
.nat-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.nat-chip.is-active { background: var(--accent); border-color: var(--accent); color: #fff; }
.nat-chip__count { opacity: .85; }

.pill--new        { background: var(--st-new-bg);        color: var(--st-new-fg); }
.pill--reserved   { background: var(--st-reserved-bg);   color: var(--st-reserved-fg); }
.pill--visa       { background: var(--st-visa-bg);       color: var(--st-visa-fg); }
.pill--active     { background: var(--st-active-bg);     color: var(--st-active-fg); }
.pill--transfer   { background: var(--st-transfer-bg);   color: var(--st-transfer-fg); }
.pill--rental     { background: var(--st-rental-bg);     color: var(--st-rental-fg); }
.pill--closed     { background: var(--st-closed-bg);     color: var(--st-closed-fg); }
.pill--cancelled  { background: var(--st-cancelled-bg);  color: var(--st-cancelled-fg); }

/* F2 document-expiry traffic-light pills — semantic tokens only (theme-aware, no hardcoded
   color). Green «ساري» / yellow «قريب الانتهاء» / red «منتهي» + gray «بدون تاريخ». The 15-day
   critical band adds `.pill--pulse`, which pulses the pill's leading dot. */
.pill--ok      { background: var(--ok-soft);     color: var(--ok); }
.pill--warn    { background: var(--warn-soft);   color: var(--warn); }
.pill--danger  { background: var(--danger-soft); color: var(--danger); }
.pill--muted   { background: var(--surface-2);   color: var(--ink-3); }
.pill--pulse::before { animation: pill-pulse 1.4s ease-in-out infinite; }
@keyframes pill-pulse { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: .3; transform: scale(.6); } }
@media (prefers-reduced-motion: reduce) { .pill--pulse::before { animation: none; } }

/* Tiny dot-only status indicator for dense tables */
.dot { width: 9px; height: 9px; border-radius: 50%; display: inline-block; vertical-align: middle; }
.dot--new{background:var(--st-new-dot)} .dot--reserved{background:var(--st-reserved-dot)}
.dot--visa{background:var(--st-visa-dot)} .dot--active{background:var(--st-active-dot)}
.dot--transfer{background:var(--st-transfer-dot)} .dot--rental{background:var(--st-rental-dot)}
.dot--closed{background:var(--st-closed-dot)} .dot--cancelled{background:var(--st-cancelled-dot)}

/* Generic badges (counts, tags, flow labels) */
.badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: 1px var(--sp-2); border-radius: var(--r-sm);
  font-size: var(--fs-xs); font-weight: var(--fw-medium);
  background: var(--surface-2); color: var(--ink-2); border: 1px solid var(--line);
}
.badge--accent { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.badge--danger { background: var(--danger-soft); color: var(--danger); border-color: transparent; }
.badge--warn   { background: var(--warn-soft); color: var(--warn); border-color: transparent; }
.badge--info   { background: var(--info-soft); color: var(--info); border-color: transparent; }
/* flow tags */
.badge--istiqdam { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
.badge--tanazul  { background: var(--st-transfer-bg); color: var(--st-transfer-fg); border-color: transparent; }
.badge--tajeer   { background: var(--st-rental-bg); color: var(--st-rental-fg); border-color: transparent; }

/* ----------------------------------------------------------------------------
   6. SIGNATURE — THE STAGE RAIL (the Request state machine, made visible)
   A segmented progress rail; the current stage is filled in its own status
   color, done stages in muted accent, future stages hollow.
   ------------------------------------------------------------------------- */
.stage-rail { display: flex; align-items: stretch; gap: 3px; width: 100%; }
.stage-rail__seg {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: var(--sp-1);
}
.stage-rail__bar {
  height: 6px; border-radius: var(--r-pill);
  background: var(--line);          /* future */
  transition: background var(--dur) var(--ease);
}
.stage-rail__seg.is-done  .stage-rail__bar { background: var(--accent); opacity: .55; }
.stage-rail__seg.is-current .stage-rail__bar { background: var(--accent); }
.stage-rail__label {
  font-size: 0.6875rem; color: var(--ink-3); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.stage-rail__seg.is-current .stage-rail__label { color: var(--ink); font-weight: var(--fw-semi); }

/* Narrow phones: step the rail label down so a multi-word stage name still reads in full.
   The designer named ≤360px «منطقة الخطر الوحيدة» and prescribed exactly this — a font-size
   step, component untouched — rather than shortening a label (.orbit/reviews/s1-design.md §2/§3).
   The إيجار rail is the only one feeding four two-word Arabic names into four flex:1 segments, so
   at 320px «مرحلة الخدمة» ellipsised on the CURRENT, bolded segment: the owner's own word,
   unreadable on the narrowest common phone. Verified by rendered pixels at 320 and 375, not by a
   measurement — an earlier scrollWidth check watched .stage-rail__seg, whose overflow never
   clips, and so reported clean while the label inside it was cut. */
@media (max-width: 360px) {
  .stage-rail { gap: 2px; }
  .stage-rail__label { font-size: 0.625rem; letter-spacing: -0.01em; }
}

/* Compact rail variant for case cards on the board (no labels) */
.stage-rail--mini .stage-rail__bar { height: 4px; }

/* ----------------------------------------------------------------------------
   7. DATA TABLES (dense, scannable, RTL text-align: start)
   ------------------------------------------------------------------------- */
/* The scroll boundary for wide data tables: never wider than its container, and it
   scrolls its overflow horizontally instead of letting the table clip under main's
   overflow:hidden. min-width:0 lets it shrink inside any flex/grid parent. */
.table-wrap { overflow-x: auto; border-radius: var(--r-lg); max-width: 100%; min-width: 0; -webkit-overflow-scrolling: touch; }
table.data { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
table.data thead th {
  text-align: start; font-weight: var(--fw-semi); color: var(--ink-3); font-size: var(--fs-xs);
  background: var(--surface-2); padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line); position: sticky; top: 0; z-index: 1;
  white-space: nowrap;
}
table.data tbody td { padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line); color: var(--ink); vertical-align: middle; }
table.data tbody tr { transition: background var(--dur) var(--ease); }
table.data tbody tr:hover { background: var(--surface-2); }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data .cell-id { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-3); }
table.data .cell-name { font-weight: var(--fw-medium); }
table.data .cell-num { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: start; }
table.data .cell-actions { text-align: end; white-space: nowrap; }
table.data tr.is-selected { background: var(--accent-soft); }

.t-meta { color: var(--ink-3); font-size: var(--fs-xs); }

/* ----------------------------------------------------------------------------
   7b. OPERATIONS GRID — direction ج «شبكة العمليات» (owner pick 2026-08-11)
   A shared card layer AROUND table.data (extends it, never forks it): toolbar
   (server-wired search + applied-filter chips) → sticky-scroll table with
   column dividers + dense 40px rows → foot (honest money sums + the pager).
   Every color is an existing theme var — no new hex (R-9). No page-size
   control: zero server capability = absent from the DOM, never disabled
   (CLAUDE.md §7, R-3/R-7). The bulk bar + checkbox column below shipped WITH
   their first real action (POST /cases/bulk/assign/, 2026-08-11) and render
   only for users the endpoint itself would accept (admin/supervisor).
   ------------------------------------------------------------------------- */
.ops-grid {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-sm); overflow: hidden;
}
.ops-toolbar {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px;
  padding: 12px 16px; border-bottom: 1px solid var(--line);
}
.ops-search {
  background: var(--surface-2); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 6px 12px; font-size: var(--fs-sm); font-family: inherit; min-width: 240px;
}
.ops-search::placeholder { color: var(--ink-3); }
.ops-search:focus { outline: none; border-color: var(--accent); box-shadow: var(--sh-focus); }
.ops-chip {
  display: inline-flex; align-items: center; gap: 6px;
  background: var(--accent-soft); color: var(--accent);
  border-radius: var(--r-pill); padding: 3px 12px;
  font-size: var(--fs-xs); font-weight: var(--fw-semi); text-decoration: none;
  transition: background var(--dur) var(--ease);
}
.ops-chip__x { opacity: .7; font-weight: var(--fw-bold); }
/* «مسح الكل» — the dashed-transparent chip token from the design plan §1. */
.ops-chip--clear {
  background: transparent; border: 1px dashed var(--line-strong); color: var(--ink-3);
}
/* The vertical scroll boundary the sticky thead binds to (live-verified 2026-08-11:
   thead pins at wrap-top with an opaque --surface-2 bg while the wrap scrolls).
   Combine with .table-wrap so the existing RTL h-scroll hint keeps working. */
.ops-scroll {
  max-height: max(430px, calc(100dvh - var(--shell-top) - 260px));
  overflow: auto;
}
/* table.data.ops-table (not .ops-table alone): the base `table.data thead th` block above
   out-specifies a lone class chain, which silently restored the roomy padding — the owner
   picked the dense grid, so the dense grid must actually win the cascade. */
table.data.ops-table thead th { padding: 9px 14px; z-index: 2; border-bottom-color: var(--line-strong); }
table.data.ops-table tbody td { padding: 9px 14px; }
/* RTL-logical column dividers; row height lands at ≈40px with the dense padding. */
.ops-table th:not(:last-child), .ops-table td:not(:last-child) { border-inline-end: 1px solid var(--line); }
/* Header sort links (server-side ?sort= — GET reloads, zero JS). */
.ops-table th .th-in {
  display: inline-flex; align-items: center; gap: 4px;
  color: inherit; text-decoration: none;
}
.ops-table th.is-sorted, .ops-table th.is-sorted .th-in { color: var(--accent); }
.ops-foot {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px;
  padding: 11px 16px; border-top: 1px solid var(--line); font-size: var(--fs-sm);
}
.ops-foot__sum { color: var(--ink-3); }
.ops-foot__sum b { color: var(--ink); font-weight: var(--fw-semi); }
.ops-foot .spacer, .ops-toolbar .spacer { flex: 1; }
.ops-foot .pager { margin: 0; }
/* Bulk bar (تعيين الموظف المسؤول جماعياً) — hidden until n>0 selections (.is-on via JS;
   a <noscript> style in the template reveals it for the no-JS fallback). */
[data-ops-bulk] { margin: 0; }
.ops-bulkbar {
  display: none; align-items: center; flex-wrap: wrap; gap: 10px;
  background: var(--accent-soft); padding: 9px 16px;
  border-bottom: 1px solid var(--line);
  font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--accent);
}
.ops-bulkbar.is-on { display: flex; }
.ops-bulkbar .spacer { flex: 1; }
/* the shared .select is 100%-width by default — inline control here, not a form row */
.ops-bulkbar .ops-bulkbar__staff { width: auto; min-width: 220px; }
.ops-bulkbar__act {
  font-size: var(--fs-xs); font-weight: var(--fw-semi); font-family: inherit;
  padding: 2px 12px; border: 1px solid var(--accent-ring); border-radius: var(--r-sm);
  background: var(--surface); color: var(--accent); cursor: pointer;
  transition: background var(--dur) var(--ease);
}
.ops-bulkbar__act:hover { background: var(--surface-2); }
/* Checkbox column: 38px, centered, NO divider after it (design plan §1). */
.ops-table th.cell-check, .ops-table td.cell-check {
  width: 38px; padding-inline: 10px; text-align: center; border-inline-end: 0;
}
.cell-check input[type="checkbox"] {
  width: 15px; height: 15px; accent-color: var(--accent);
  display: block; margin-inline: auto; cursor: pointer;
}
/* Selected row: --accent-soft fill (base rule, §7 table.data) + a 3px jade bar on the
   inline-start (right, RTL) edge — painted on the first cell because border-collapse
   swallows a box-shadow set on the <tr> itself. */
.ops-table tbody tr.is-selected td:first-child { box-shadow: inset -3px 0 0 var(--accent); }
@media (max-width: 640px) {
  .ops-hide-sm { display: none; }             /* dropped columns stay on the detail page */
  .ops-scroll { max-height: none; }           /* page scrolls; header stops sticking — accepted */
  .ops-scroll .ops-table { min-width: 640px; }/* remaining columns h-scroll inside the wrap */
  .ops-toolbar .ops-search { flex-basis: 100%; min-width: 0; }
  .ops-foot { justify-content: center; }
}

/* ----------------------------------------------------------------------------
   8. KANBAN PIPELINE BOARD (columns + draggable case cards)
   ------------------------------------------------------------------------- */
.board {
  display: flex; gap: var(--sp-4); align-items: flex-start;
  overflow-x: auto; padding-bottom: var(--sp-4); scroll-snap-type: x proximity;
}
.board__col {
  flex: 0 0 300px; max-width: 300px;
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  display: flex; flex-direction: column; max-height: calc(100vh - 220px);
  scroll-snap-align: start;
}
.board__col-head {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3) var(--sp-4);
  border-bottom: 1px solid var(--line);
  position: sticky; top: 0; background: var(--surface-2); border-radius: var(--r-lg) var(--r-lg) 0 0;
}
.board__col-head .name { font-weight: var(--fw-semi); font-size: var(--fs-sm); }
.board__col-head .count { margin-inline-start: auto; }
/* the column gets a thin top accent in its stage color */
.board__col-head::before { content:""; width: 9px; height: 9px; border-radius: 50%; flex: none; background: var(--ink-3); }
.board__col[data-stage="new"]       .board__col-head::before { background: var(--st-new-dot); }
.board__col[data-stage="reserved"]  .board__col-head::before { background: var(--st-reserved-dot); }
.board__col[data-stage="visa"]      .board__col-head::before { background: var(--st-visa-dot); }
.board__col[data-stage="active"]    .board__col-head::before { background: var(--st-active-dot); }
.board__col[data-stage="transfer"]  .board__col-head::before { background: var(--st-transfer-dot); }
.board__col[data-stage="rental"]    .board__col-head::before { background: var(--st-rental-dot); }
.board__col[data-stage="closed"]    .board__col-head::before { background: var(--st-closed-dot); }
.board__col[data-stage="cancelled"] .board__col-head::before { background: var(--st-cancelled-dot); }

.board__col-body { padding: var(--sp-3); display: flex; flex-direction: column; gap: var(--sp-3); overflow-y: auto; }

.case-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: var(--sp-3) var(--sp-3) var(--sp-3);
  box-shadow: var(--sh-sm);
  cursor: grab;
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease);
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.case-card:hover { box-shadow: var(--sh-md); border-color: var(--line-strong); }
.case-card:active { cursor: grabbing; }
.case-card.is-dragging { transform: rotate(-1deg); box-shadow: var(--sh-lg); }
.case-card__top { display: flex; align-items: center; gap: var(--sp-2); }
.case-card__id { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-3); }
.case-card__top .spacer { flex: 1; }
.case-card__customer { display: flex; align-items: center; gap: var(--sp-2); }
.case-card__name { font-weight: var(--fw-semi); font-size: var(--fs-body); }
.case-card__line { display: flex; align-items: center; gap: var(--sp-2); color: var(--ink-3); font-size: var(--fs-xs); }
.case-card__foot { display: flex; align-items: center; gap: var(--sp-2); margin-top: 2px; }
.case-card__foot .spacer { flex: 1; }
/* SLA / age chip — turns warm then hot */
.age { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-3); }
.age.warm { color: var(--warn); } .age.hot { color: var(--danger); font-weight: var(--fw-semi); }

/* ----------------------------------------------------------------------------
   9. WORKER CARD (catalog tile)
   ------------------------------------------------------------------------- */
.worker-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  overflow: hidden; box-shadow: var(--sh-sm);
  transition: box-shadow var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.worker-card:hover { box-shadow: var(--sh-md); border-color: var(--line-strong); }
.worker-card__head { display: flex; gap: var(--sp-3); padding: var(--sp-4); }
.worker-card__photo {
  width: 56px; height: 56px; border-radius: var(--r-md); flex: none; object-fit: cover;
  background: var(--surface-2); border: 1px solid var(--line);
  display: grid; place-items: center; color: var(--ink-3); font-weight: var(--fw-semi);
}
.worker-card__id { font-family: var(--font-mono); font-size: var(--fs-xs); color: var(--ink-3); }
.worker-card__name { font-weight: var(--fw-semi); font-size: var(--fs-h3); }
.worker-card__meta { color: var(--ink-3); font-size: var(--fs-sm); }
.worker-card__body { padding: 0 var(--sp-4) var(--sp-4); display: flex; flex-direction: column; gap: var(--sp-3); }
.worker-card__attrs { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); font-size: var(--fs-sm); }
.worker-card__attr { display: flex; gap: var(--sp-1); color: var(--ink-2); }
.worker-card__attr b { font-weight: var(--fw-semi); color: var(--ink); }
.worker-card__foot { display: flex; align-items: center; gap: var(--sp-2); padding-top: var(--sp-3); border-top: 1px solid var(--line); }

/* skill rating meter (8-axis ضعيف→ممتاز) — quiet bars */
.rating { display: flex; align-items: center; gap: var(--sp-2); }
.rating__track { display: flex; gap: 2px; }
.rating__pip { width: 14px; height: 5px; border-radius: var(--r-pill); background: var(--line); }
.rating__pip.on { background: var(--accent); }

/* ----------------------------------------------------------------------------
   10. BUTTONS
   ------------------------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--sp-2);
  font: inherit; font-weight: var(--fw-semi); font-size: var(--fs-body);
  padding: var(--sp-2) var(--sp-4); height: 36px;
  border-radius: var(--r-md); border: 1px solid transparent; cursor: pointer;
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
  white-space: nowrap; user-select: none;
}
.btn:disabled, .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }
.btn .ico { width: 16px; height: 16px; }

.btn--primary { background: var(--accent); color: var(--ink-on-accent); }
.btn--primary:hover { background: var(--accent-hover); }
.btn--primary:active { background: var(--accent-press); }

.btn--secondary { background: var(--surface); color: var(--ink); border-color: var(--line-strong); }
.btn--secondary:hover { background: var(--surface-2); border-color: var(--ink-3); }

.btn--ghost { background: transparent; color: var(--ink-2); }
.btn--ghost:hover { background: var(--surface-2); color: var(--ink); }

.btn--danger { background: var(--danger); color: #fff; }
.btn--danger:hover { background: var(--danger-hover); }
.btn--danger-soft { background: var(--danger-soft); color: var(--danger); }
.btn--danger-soft:hover { background: #f6dad7; }
/* Dark theme: the light-pink hover flashes illegibly (2.3:1) — tint from the danger token. */
:root[data-theme="dark"] .btn--danger-soft:hover { background: color-mix(in srgb, var(--danger) 20%, transparent); }

.btn--sm { height: 30px; padding: var(--sp-1) var(--sp-3); font-size: var(--fs-sm); }
.btn--icon { width: 36px; padding: 0; }
.btn--icon.btn--sm { width: 30px; }
.btn--block { width: 100%; }

/* gated / approval-required action — visually marks §8 human-gate buttons */
.btn--gated { position: relative; }
.btn--gated::after {
  content: "بانتظار اعتماد"; position: absolute; inset-block-start: -8px; inset-inline-start: 50%;
  transform: translateX(50%); font-size: 0.625rem; font-weight: var(--fw-semi);
  background: var(--warn); color: #fff; padding: 0 var(--sp-2); border-radius: var(--r-pill);
  white-space: nowrap; opacity: 0; pointer-events: none;
}

/* ----------------------------------------------------------------------------
   11. FORMS — inputs, selects, labels, fields
   ------------------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--sp-2); margin-bottom: var(--sp-4); }
.field__label { font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--ink-2); }
.field__label .req { color: var(--danger); margin-inline-start: 2px; }
.field__hint { font-size: var(--fs-xs); color: var(--ink-3); }
.field__error { font-size: var(--fs-xs); color: var(--danger); }

.input, .select, .textarea {
  font: inherit; font-size: var(--fs-body); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-md); padding: var(--sp-2) var(--sp-3); height: 38px; width: 100%;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.textarea { height: auto; min-height: 88px; padding: var(--sp-3); resize: vertical; line-height: var(--lh-body); }
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.input:hover, .select:hover, .textarea:hover { border-color: var(--ink-3); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: var(--sh-focus);
}
.input.is-invalid, .select.is-invalid, .textarea.is-invalid { border-color: var(--danger); }
.input:disabled, .select:disabled { background: var(--surface-2); color: var(--ink-3); cursor: not-allowed; }

/* RTL select arrow on the inline-start (left in RTL) side */
.select {
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236b7873' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: left var(--sp-3) center;
  padding-inline-start: var(--sp-8);
}

/* input with a leading control / unit (e.g. SAR) — RTL aware */
.input-group { display: flex; align-items: stretch; }
.input-group .input { border-radius: 0; }
.input-group > :first-child { border-start-start-radius: var(--r-md); border-end-start-radius: var(--r-md); }
.input-group > :last-child  { border-start-end-radius: var(--r-md); border-end-end-radius: var(--r-md); }
.input-group .addon {
  display: inline-flex; align-items: center; padding-inline: var(--sp-3);
  background: var(--surface-2); border: 1px solid var(--line-strong);
  color: var(--ink-3); font-size: var(--fs-sm); white-space: nowrap;
}
.input-group .addon + .input { border-inline-start: 0; }
.input-group .input + .addon { border-inline-start: 0; }

/* checkbox / switch */
.switch { position: relative; display: inline-flex; align-items: center; gap: var(--sp-2); cursor: pointer; }
.switch input { position: absolute; opacity: 0; }
.switch .track { width: 38px; height: 22px; border-radius: var(--r-pill); background: var(--line-strong); transition: background var(--dur) var(--ease); flex: none; }
.switch .track::after { content:""; position: absolute; inset-block-start: 3px; inset-inline-start: 3px; width: 16px; height: 16px; border-radius: 50%; background: #fff; box-shadow: var(--sh-sm); transition: inset-inline-start var(--dur) var(--ease); }
.switch input:checked + .track { background: var(--accent); }
.switch input:checked + .track::after { inset-inline-start: 19px; }
.switch input:focus-visible + .track { box-shadow: var(--sh-focus); }

/* segmented filter control (flow / view toggles) */
.segmented { display: inline-flex; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md); padding: 2px; gap: 2px; }
.segmented button, .segmented a { display: inline-flex; align-items: center; font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium); border: 0; background: transparent; color: var(--ink-2); padding: var(--sp-1) var(--sp-3); border-radius: var(--r-sm); cursor: pointer; height: 30px; text-decoration: none; }
.segmented a:hover { color: var(--ink); text-decoration: none; }
.segmented button.is-active, .segmented a.is-active { background: var(--surface); color: var(--ink); box-shadow: var(--sh-sm); font-weight: var(--fw-semi); }

/* toolbar / filter row */
.toolbar { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; margin-bottom: var(--sp-4); }
.toolbar .spacer { flex: 1; }

/* ----------------------------------------------------------------------------
   12. DEFINITION LISTS (case / worker detail key-value rows)
   ------------------------------------------------------------------------- */
.kv { display: grid; grid-template-columns: max-content 1fr; gap: var(--sp-3) var(--sp-5); align-items: baseline; }
.kv dt { color: var(--ink-3); font-size: var(--fs-sm); }
.kv dd { margin: 0; color: var(--ink); font-size: var(--fs-body); font-weight: var(--fw-medium); }
.kv dd .num { font-weight: var(--fw-semi); }

/* timeline (StateTransition audit trail) */
.timeline { display: flex; flex-direction: column; gap: 0; }
.timeline__item { display: grid; grid-template-columns: auto 1fr; gap: var(--sp-3); padding-bottom: var(--sp-4); position: relative; }
.timeline__rail { display: flex; flex-direction: column; align-items: center; }
.timeline__dot { width: 11px; height: 11px; border-radius: 50%; background: var(--accent); border: 2px solid var(--surface); box-shadow: 0 0 0 1px var(--accent); margin-top: 3px; }
.timeline__line { flex: 1; width: 2px; background: var(--line); margin-top: 2px; }
.timeline__item:last-child .timeline__line { display: none; }
.timeline__body { padding-bottom: var(--sp-2); }
.timeline__title { font-weight: var(--fw-medium); font-size: var(--fs-sm); }
.timeline__time { color: var(--ink-3); font-size: var(--fs-xs); font-family: var(--font-mono); }

/* ----------------------------------------------------------------------------
   13. EMPTY STATES
   ------------------------------------------------------------------------- */
.empty { text-align: center; padding: var(--sp-12) var(--sp-6); color: var(--ink-3); }
.empty__art {
  width: 56px; height: 56px; margin: 0 auto var(--sp-4); border-radius: var(--r-lg);
  background: var(--surface-2); display: grid; place-items: center; color: var(--ink-3);
  border: 1px solid var(--line);
}
.empty__title { font-size: var(--fs-h3); font-weight: var(--fw-semi); color: var(--ink-2); }
.empty__text { font-size: var(--fs-sm); margin-top: var(--sp-2); max-width: 42ch; margin-inline: auto; }
.empty__actions { margin-top: var(--sp-4); display: flex; gap: var(--sp-2); justify-content: center; }

/* ----------------------------------------------------------------------------
   14. INBOX LIST (WhatsApp leads)
   ------------------------------------------------------------------------- */
.inbox-item { display: flex; gap: var(--sp-3); padding: var(--sp-3) var(--sp-4); border-bottom: 1px solid var(--line); cursor: pointer; transition: background var(--dur) var(--ease); }
.inbox-item:hover { background: var(--surface-2); }
.inbox-item.is-unread { background: var(--accent-soft); }
.inbox-item.is-unread .inbox-item__name { font-weight: var(--fw-bold); }
.inbox-item__avatar { width: 38px; height: 38px; border-radius: 50%; background: var(--surface-2); border: 1px solid var(--line); display: grid; place-items: center; color: var(--ink-3); font-weight: var(--fw-semi); flex: none; }
.inbox-item__main { flex: 1; min-width: 0; }
.inbox-item__row { display: flex; align-items: center; gap: var(--sp-2); }
.inbox-item__name { font-weight: var(--fw-medium); font-size: var(--fs-body); }
.inbox-item__time { margin-inline-start: auto; font-size: var(--fs-xs); color: var(--ink-3); font-family: var(--font-mono); }
.inbox-item__preview { color: var(--ink-3); font-size: var(--fs-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ----------------------------------------------------------------------------
   15. UTILITIES
   ------------------------------------------------------------------------- */
.u-label { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--ink-3); }
.u-label--latin { letter-spacing: .04em; text-transform: uppercase; } /* Latin-only — never on Arabic */
.u-muted { color: var(--ink-3); }
.u-ink2 { color: var(--ink-2); }
.u-right { text-align: end; } .u-center { text-align: center; }
.u-nowrap { white-space: nowrap; }
.u-flex { display: flex; align-items: center; gap: var(--sp-2); }
.u-flex-col { display: flex; flex-direction: column; gap: var(--sp-2); }
.u-between { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.u-wrap { flex-wrap: wrap; }
.u-grow { flex: 1; min-width: 0; }
.u-divider { height: 1px; background: var(--line); border: 0; margin: var(--sp-4) 0; }
.u-vdivider { width: 1px; align-self: stretch; background: var(--line); }
.u-hidden { display: none !important; }
.u-mt-2{margin-top:var(--sp-2)} .u-mt-4{margin-top:var(--sp-4)} .u-mt-6{margin-top:var(--sp-6)}
.u-mb-2{margin-bottom:var(--sp-2)} .u-mb-4{margin-bottom:var(--sp-4)} .u-mb-6{margin-bottom:var(--sp-6)}
.grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-4); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-4); }
.grid-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: var(--sp-4); }
/* Let grid tracks shrink below their content's min-content width. Without this a grid cell
   holding a wide element (a .table-wrap with a min-width'd table, a long code, a nowrap row)
   keeps its track at that min-width and pushes the whole grid past the viewport. min-width:0
   restores shrinkability so the inner overflow-x:auto (e.g. .table-wrap) actually scrolls. */
.grid-2 > *, .grid-3 > *, .grid-cards > * { min-width: 0; }

/* ----------------------------------------------------------------------------
   16. RESPONSIVE
   ------------------------------------------------------------------------- */
@media (max-width: 960px) {
  /* minmax(0,1fr) lets the single column shrink below its content's min-content width,
     so non-shrinkable topbar chrome can't force the whole grid wider than the viewport. */
  .app { grid-template-columns: minmax(0, 1fr); grid-template-areas: "topbar" "main"; }
  /* (mobile sidebar becomes the off-canvas drawer — see §18) */
  /* Collapse ALL two/three-column card rows to a single column. !important is deliberate:
     several page templates set an inline grid-template-columns (e.g. "1.4fr 1fr") for their
     desktop layout, and a normal media-query rule can't beat an inline style — so those rows
     would otherwise stay multi-column on phones and clip content under main's overflow:hidden. */
  .grid-2, .grid-3 { grid-template-columns: 1fr !important; }
  body { overflow-x: hidden; }         /* backstop against any residual horizontal scroll */
}
@media (max-width: 600px) {
  .main { padding: var(--sp-4); }
  .topbar__search { display: none; }
  .stats { grid-template-columns: 1fr 1fr; }
  /* Compact the topbar so it fits a phone viewport: icon-only actions, truncated brand. */
  .topbar { gap: var(--sp-2); padding-inline: var(--sp-3); }
  .topbar__user > div, .topbar__user form span { display: none; }
  .topbar__brand { min-width: 0; }
  .topbar__brand span:last-of-type { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  /* Dense data tables stay legible by scrolling inside their .table-wrap rather than
     crushing every column to unreadable widths. The wrap already has overflow-x:auto. */
  .table-wrap table.data { min-width: 600px; }
  /* Stack the page header so a wide actions cluster (segmented filters, buttons) drops
     below the title instead of squeezing the subtitle into a sliver. */
  .page-head { flex-direction: column; align-items: stretch; gap: var(--sp-3); }
  .page-head__actions { flex-wrap: wrap; }
  /* Inline filter forms in the header (e.g. finance reports' date range) must wrap their
     own controls too — the actions wrapper wrapping isn't enough if the form is a non-wrap
     flex row of date inputs + a button. Let its fields drop to a new line and shrink. */
  .page-head__actions form { flex-wrap: wrap; }
  .page-head__actions form .input,
  .page-head__actions form label { min-width: 0; }
  /* Toolbars (filter rows) wrap comfortably and their trailing meta drops to a new line. */
  .toolbar > .spacer { flex-basis: 100%; height: 0; }
}

/* ----------------------------------------------------------------------------
   17. MOTION — one calm system; respect reduced-motion
   ------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .apq2-panel { animation: none; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

/* ----------------------------------------------------------------------------
   18. SIDEBAR — desktop collapse (icon rail) + mobile/tablet drawer
   Desktop ≥961px: the sidebar collapses to a 68px icon rail; hovering a link
   reveals a label flyout. State lives on <html data-sidebar> (persisted in
   localStorage, applied pre-paint so there's no flash).
   ≤960px (phones + iPad portrait): the sidebar becomes an off-canvas drawer
   that slides in from the inline-start edge, with a scrim and a close button.
   ------------------------------------------------------------------------- */

/* sidebar becomes a column so the collapse control can sit pinned at the foot */
.sidebar__head { display: none; }           /* only rendered in drawer mode */
.sidebar > nav { display: flex; flex-direction: column; gap: var(--sp-1); }
.sidebar__foot { margin-top: auto; padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.sidebar__collapse {
  display: inline-flex; align-items: center; gap: var(--sp-3); width: 100%;
  background: transparent; border: 0; cursor: pointer; color: var(--ink-3);
  font: inherit; font-size: var(--fs-sm); font-weight: var(--fw-medium);
  padding: var(--sp-2) var(--sp-3); border-radius: var(--r-md);
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.sidebar__collapse:hover { background: var(--surface-2); color: var(--ink); }
.sidebar__collapse .ico { width: 18px; height: 18px; flex: none; transition: transform var(--dur) var(--ease); }

/* --- collapsed icon rail (desktop only) --- */
:root[data-sidebar="collapsed"] { --shell-side: 68px; }
@media (min-width: 961px) {
  :root[data-sidebar="collapsed"] .sidebar { padding-inline: var(--sp-2); }
  :root[data-sidebar="collapsed"] .nav-link { justify-content: center; padding-inline: 0; }
  :root[data-sidebar="collapsed"] .nav-link .ico { opacity: 1; }
  /* the existing label span turns into a hover flyout, no markup change needed */
  :root[data-sidebar="collapsed"] .nav-link span:not(.count) {
    position: absolute; inset-inline-end: calc(100% + 10px); top: 50%;
    transform: translateY(-50%) scale(.96); transform-origin: 100% 50%;
    background: var(--ink); color: var(--canvas); padding: 5px 10px; border-radius: var(--r-sm);
    font-size: var(--fs-sm); font-weight: var(--fw-medium); white-space: nowrap;
    box-shadow: var(--sh-md); opacity: 0; pointer-events: none; z-index: 60;
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  }
  :root[data-sidebar="collapsed"] .nav-link:hover span:not(.count),
  :root[data-sidebar="collapsed"] .nav-link:focus-visible span:not(.count) { opacity: 1; transform: translateY(-50%) scale(1); }
  :root[data-sidebar="collapsed"] .nav-link .count { display: none; }
  /* the active link keeps its edge marker; add a small filled dot so state reads on the rail */
  :root[data-sidebar="collapsed"] .nav-link.is-active::after {
    content: ""; position: absolute; inset-inline-end: 8px; top: 8px; width: 6px; height: 6px;
    border-radius: 50%; background: var(--accent);
  }
  /* group labels shrink to a hairline divider */
  :root[data-sidebar="collapsed"] .nav-group__label { font-size: 0; padding: var(--sp-2) var(--sp-2) 0; }
  :root[data-sidebar="collapsed"] .nav-group__label::before { content: ""; display: block; height: 1px; background: var(--line); }
  :root[data-sidebar="collapsed"] .sidebar__collapse { justify-content: center; padding-inline: 0; }
  :root[data-sidebar="collapsed"] .sidebar__collapse span { display: none; }
  :root[data-sidebar="collapsed"] .sidebar__collapse .ico { transform: scaleX(-1); }
  /* S1 sections on the rail: show only the parent icon; hide the chevron + children. The
     summary label becomes a hover flyout, mirroring .nav-link; an active section gets a dot. */
  :root[data-sidebar="collapsed"] .nav-parent__row { justify-content: center; padding-inline: 0; position: relative; }
  :root[data-sidebar="collapsed"] .nav-parent__chev { display: none; }
  :root[data-sidebar="collapsed"] .nav-parent__row .ico { opacity: 1; }
  :root[data-sidebar="collapsed"] .nav-sub { display: none; }
  :root[data-sidebar="collapsed"] .nav-parent__row > span {
    position: absolute; inset-inline-end: calc(100% + 10px); top: 50%;
    transform: translateY(-50%) scale(.96); transform-origin: 100% 50%;
    background: var(--ink); color: var(--canvas); padding: 5px 10px; border-radius: var(--r-sm);
    font-size: var(--fs-sm); font-weight: var(--fw-medium); white-space: nowrap;
    box-shadow: var(--sh-md); opacity: 0; pointer-events: none; z-index: 60;
    transition: opacity var(--dur) var(--ease), transform var(--dur) var(--ease);
  }
  :root[data-sidebar="collapsed"] .nav-parent__row:hover > span,
  :root[data-sidebar="collapsed"] .nav-parent__row:focus-visible > span { opacity: 1; transform: translateY(-50%) scale(1); }
  :root[data-sidebar="collapsed"] .nav-parent:has(.nav-link.is-active) > .nav-parent__row::after {
    content: ""; position: absolute; inset-inline-end: 8px; top: 8px; width: 6px; height: 6px;
    border-radius: 50%; background: var(--accent);
  }
}

/* --- mobile / iPad-portrait drawer (≤960px) --- */
.topbar__menu { display: none; }             /* hamburger — shown ≤960 */
.drawer-scrim { display: none; }
.drawer-toggle { position: absolute; opacity: 0; pointer-events: none; }

@media (max-width: 960px) {
  .topbar__menu { display: inline-flex; }
  /* sidebar stays in the DOM (fixed, off-canvas) so it can slide */
  .sidebar {
    position: fixed; inset-block: 0; inset-inline-start: 0; z-index: 55;
    width: min(86vw, 300px); height: 100dvh; max-height: 100dvh;
    /* docked at the RTL start edge (right); slide it off that edge to hide.
       translateX is physical, so the inline-start (right) edge hides with +100%. */
    transform: translateX(calc(100% + 12px));
    transition: transform .24s var(--ease);
    box-shadow: var(--sh-lg); padding: var(--sp-3);
    display: flex; border-inline-start: 0;
  }
  /* LTR safety: hide toward the physical left instead. */
  [dir="ltr"] .sidebar { transform: translateX(calc(-1 * (100% + 12px))); }
  .sidebar__head {
    display: flex; align-items: center; gap: var(--sp-2);
    padding: var(--sp-1) var(--sp-1) var(--sp-3); margin-bottom: var(--sp-2);
    border-bottom: 1px solid var(--line);
  }
  .sidebar__head .brand { display: flex; align-items: center; gap: var(--sp-2); font-weight: var(--fw-semi); font-size: var(--fs-h3); }
  .sidebar__head .brand .mark {
    width: 26px; height: 26px; border-radius: var(--r-sm); background: var(--accent); color: var(--ink-on-accent);
    display: grid; place-items: center; font-weight: var(--fw-bold); font-size: var(--fs-sm);
  }
  .sidebar__head .close { margin-inline-start: auto; }
  .sidebar__foot { display: none; }          /* no rail-collapse in drawer mode */

  .drawer-toggle:checked ~ .app .sidebar { transform: translateX(0); }

  .drawer-scrim {
    display: block; position: fixed; inset: 0; z-index: 50;
    background: rgba(16,33,29,.42); opacity: 0; pointer-events: none;
    transition: opacity .24s var(--ease);
  }
  .drawer-toggle:checked ~ .app .drawer-scrim { opacity: 1; pointer-events: auto; }

  /* comfortable touch targets in the drawer */
  .sidebar .nav-link { padding: var(--sp-3); min-height: 44px; }
  .sidebar .nav-group__label { padding-top: var(--sp-4); }
  body.drawer-open { overflow: hidden; }     /* set by JS to lock scroll behind the drawer */
}

/* ----------------------------------------------------------------------------
   19. TASKS (المهام) — instrument pulse · command composer · agenda rail
   Works without JS: priority is radio-driven, complete/reopen are POST forms,
   the composer options are visible by default (JS only collapses them).
   Re-designed 2026-07-04 (de-slopped per owner): quiet count tiles (colour only
   on non-zero urgent counts), grouped list on a timeline rail whose nodes are
   coloured only for overdue/today, rows inside plain cards. No decoration.
   ------------------------------------------------------------------------- */

/* --- instrument pulse (the 3 counters) --- */
/* the whole tasks column is capped — full-bleed rows on a 1400px canvas read as
   dead space when titles are short; ~1000px keeps rows dense (owner feedback) */
.tasks-pulse, .tasks-pulse ~ .composer, .tasks-pulse ~ .toolbar, .tasks-pulse ~ .task-groups, .tasks-pulse ~ .card { max-width: 1000px; }
.pulse-tile { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--sp-3) var(--sp-4); }
.pulse-tile__value { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 1.6rem; font-weight: var(--fw-bold); line-height: 1.15; color: var(--ink); }
.pulse-tile__label { font-size: var(--fs-xs); color: var(--ink-3); font-weight: var(--fw-medium); }
/* colour is a signal, not decoration: only a non-zero urgent count earns it */
.pulse-tile--overdue .pulse-tile__value { color: var(--danger); }
.pulse-tile--today   .pulse-tile__value { color: var(--warn); }
.pulse-tile--zero    .pulse-tile__value { color: var(--ink-3); }

/* --- command composer --- */
.composer {
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-lg); padding: var(--sp-3) var(--sp-4);
  box-shadow: var(--sh-sm); margin-bottom: var(--sp-6);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.composer.is-focused { border-color: var(--accent); box-shadow: var(--sh-focus), var(--sh-md); }
.composer__row { display: flex; align-items: center; gap: var(--sp-3); }
.composer__circle {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 2px dashed var(--line-strong); color: var(--ink-3);
  display: grid; place-items: center; font-size: 1rem; line-height: 1;
  transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.composer__circle::after { content: "+"; font-weight: var(--fw-semi); }
.composer.is-focused .composer__circle { border-style: solid; border-color: var(--accent); background: var(--accent-soft); color: var(--accent); }
.composer__input { flex: 1; min-width: 0; border: 0; outline: none; background: transparent; font: inherit; font-size: var(--fs-h3); color: var(--ink); padding: var(--sp-1) 0; }
.composer__input::placeholder { color: var(--ink-3); font-weight: var(--fw-regular); }
.composer__hint { font-size: var(--fs-xs); color: var(--ink-3); white-space: nowrap; }
/* options: visible by default (no-JS safe); JS adds .js-composer to collapse until focus */
.composer__options { display: flex; gap: var(--sp-4); flex-wrap: wrap; align-items: flex-end; margin-top: var(--sp-3); padding-top: var(--sp-3); border-top: 1px solid var(--line); }
.js-composer .composer__options { display: none; }
.js-composer.composer.is-focused .composer__options { display: flex; }
.composer__opt { display: flex; flex-direction: column; gap: var(--sp-2); }
.composer__opt > span { font-size: var(--fs-xs); color: var(--ink-3); font-weight: var(--fw-medium); }
.composer__opt .select, .composer__opt .input { height: 34px; }
.composer__opt--grow { flex: 1; min-width: 180px; }
.composer__opt--grow .textarea { min-height: 34px; height: 34px; }
.composer__spacer { flex: 1; }

/* priority segmented radios */
.prio-pick { display: inline-flex; gap: 4px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-md); padding: 2px; }
.prio-pick label { display: inline-flex; align-items: center; gap: var(--sp-2); padding: var(--sp-1) var(--sp-3); height: 30px; border-radius: var(--r-sm); cursor: pointer; font-size: var(--fs-sm); color: var(--ink-2); position: relative; }
.prio-pick input { position: absolute; opacity: 0; width: 0; height: 0; }
.prio-pick .pdot { width: 7px; height: 7px; border-radius: 50%; flex: none; }
.pdot--high { background: var(--danger); } .pdot--normal { background: var(--info); } .pdot--low { background: var(--ink-3); }
.prio-pick label:has(input:checked) { background: var(--surface); box-shadow: var(--sh-sm); color: var(--ink); font-weight: var(--fw-semi); }
.prio-pick label:has(input:focus-visible) { box-shadow: var(--sh-focus); }

/* --- agenda rail: the grouped list hangs on a timeline --- */
.task-groups { position: relative; display: flex; flex-direction: column; gap: var(--sp-6); padding-inline-start: 26px; }
/* node colour = urgency only; everything else stays quiet */
.task-group--overdue { --g-c: var(--danger); }

/* rows live inside a lifted card per group */
.task-list { background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--sh-sm); overflow: hidden; }

/* the complete/reopen check */
.task-check { flex: none; width: 24px; height: 24px; margin-top: 1px; border-radius: 50%; border: 2px solid var(--line-strong); background: var(--surface); cursor: pointer; display: grid; place-items: center; padding: 0; transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
/* end-of-row meta column (left in RTL): date · assignee · priority at a fixed scan line */
.task-side { margin-inline-start: auto; display: flex; align-items: center; gap: var(--sp-4); flex: none; }
.task-meta__item .ico { width: 13px; height: 13px; opacity: .85; flex: none; }
a.task-meta__item { text-decoration: none; } a.task-meta__item:hover { color: var(--accent); }
.task-actions { display: inline-flex; gap: var(--sp-1); opacity: 0; transition: opacity var(--dur) var(--ease); }
@media (hover: none) { .task-actions { opacity: 1; } }   /* touch: always show actions */

/* mobile: keep the rail, tighten the tiles */
@media (max-width: 640px) {
  .task-row { flex-wrap: wrap; align-items: flex-start; }
  .task-side { flex-basis: 100%; margin-inline-start: calc(24px + var(--sp-3)); gap: var(--sp-3); }
  .tasks-pulse { gap: var(--sp-2); }
  .pulse-tile { padding: var(--sp-2) var(--sp-3); }
  .pulse-tile__value { font-size: 1.25rem; }
  .task-groups { padding-inline-start: 20px; }
  .task-group__node { inset-inline-start: -20px; width: 14px; height: 14px; }
}

/* ----------------------------------------------------------------------------
   20. THEME SYSTEM — the ∞ brand mark, the light/dark toggle, and the handful
   of dark-scoped overrides for spots that hard-coded a colour (white-on-accent
   fills, etc.). Tokens in §1 do the heavy lifting; these are the exceptions.
   ------------------------------------------------------------------------- */

/* --- the ∞ brand mark (per-tenant logo replaces it when the office uploads one) --- */
.mark { overflow: hidden; }
.mark .mark-svg { width: 68%; height: auto; display: block; }
/* light: a filled jade chip with a contrasting ∞ */
.topbar__brand .mark,
.sidebar__head .brand .mark { color: var(--ink-on-accent); }

/* dark: a recessed chip with a luminous jade ∞ + soft glow (matches direction-2) */
:root[data-theme="dark"] .topbar__brand .mark,
:root[data-theme="dark"] .sidebar__head .brand .mark {
  background: #0f1a16; border: 1px solid var(--line-strong); color: var(--accent);
}
:root[data-theme="dark"] .mark .mark-svg { filter: drop-shadow(0 0 4px rgba(31,209,138,.35)); }

/* --- Topbar theme toggle (sun in dark → offer light; moon in light → offer dark) --- */
.theme-toggle .ico { transition: opacity var(--dur) var(--ease); }
.theme-toggle__sun { display: none; }
:root[data-theme="dark"] .theme-toggle__sun  { display: block; }
:root[data-theme="dark"] .theme-toggle__moon { display: none; }

/* --- Dark ambient backdrop (very low-alpha jade/blue glow, not a wash) --- */
:root[data-theme="dark"] body {
  background:
    radial-gradient(1100px 600px at 88% -10%, rgba(31,209,138,.05), transparent 60%),
    radial-gradient(900px 500px at 0% 110%, rgba(74,168,255,.04), transparent 55%),
    var(--canvas);
  background-attachment: fixed;
}
:root[data-theme="dark"] ::selection { background: rgba(31,209,138,.28); color: #fff; }

/* --- Dark shell surfaces read as instrument panels (subtle vertical grade) --- */
:root[data-theme="dark"] .topbar  { background: linear-gradient(180deg, var(--surface), var(--canvas)); }
:root[data-theme="dark"] .sidebar { background: linear-gradient(180deg, var(--surface), var(--canvas)); }

/* --- Dark fixes for spots that hard-coded a light-on-colour value --- */
/* active nav count chip was solid #ffffff → use a dark chip with jade text */
:root[data-theme="dark"] .nav-link.is-active .count { background: var(--surface-2); color: var(--accent); }
/* severity/filter "الكل" active chip fills with --ink-1 (now light in dark) → dark text */
:root[data-theme="dark"] .sev-chip.is-active { color: var(--canvas); }
:root[data-theme="dark"] .sev-chip--danger.is-active { color: #0a0d10; }

/* =========================================================================
   Cases — scale-first requests surface (faceted filters · pagination · segments)
   All theme-token based (dark + light), RTL-native, responsive to mobile.
   ========================================================================= */
.input--sm, .select--sm { height: 32px; padding: var(--sp-1) var(--sp-2); font-size: var(--fs-sm); }

/* Applied-filter chip row extras */
.filter-chip__reset { margin-inline-start: var(--sp-2); color: var(--ink-3); text-decoration: none; align-self: center; }
.filter-chip__reset:hover { color: var(--accent); text-decoration: underline; }

/* Collapsible faceted filter panel */
.filters { border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface); margin: var(--sp-3) 0 var(--sp-5); }
.filters__summary { display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3) var(--sp-4); font-weight: var(--fw-semi); font-size: var(--fs-sm); color: var(--ink-1); cursor: pointer; list-style: none; }
.filters__summary::-webkit-details-marker { display: none; }
.filters__summary .ico { width: 16px; height: 16px; color: var(--ink-3); }
.filters[open] .filters__summary { border-bottom: 1px solid var(--line); }
.filters__grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--sp-3) var(--sp-4); padding: var(--sp-4); }
.filters__grid .field { margin-bottom: 0; }
.filters__actions { grid-column: 1 / -1; display: flex; gap: var(--sp-2); justify-content: flex-start; }
.filters__save { display: flex; gap: var(--sp-2); align-items: center; padding: 0 var(--sp-4) var(--sp-4); flex-wrap: wrap; }
.filters__save .input { max-width: 220px; }
@media (max-width: 900px) { .filters__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 560px) { .filters__grid { grid-template-columns: 1fr; } }

/* Dropdown (saved segments) — pure CSS via <details> */
.dropdown { position: relative; display: inline-block; }
.dropdown > summary { list-style: none; cursor: pointer; }
.dropdown > summary::-webkit-details-marker { display: none; }
.dropdown__menu { position: absolute; inset-block-start: calc(100% + 4px); min-width: 220px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-md); box-shadow: var(--sh-md); padding: var(--sp-1); z-index: 40; }
.dropdown__menu--end { inset-inline-end: 0; }
.dropdown__row { display: flex; align-items: center; gap: var(--sp-1); }
.dropdown__item { flex: 1; display: block; padding: var(--sp-2) var(--sp-3); border-radius: var(--r-sm); color: var(--ink-1); text-decoration: none; font-size: var(--fs-sm); }
.dropdown__item:hover { background: var(--surface-2); color: var(--accent); }
.dropdown__del { margin: 0; }
.dropdown__empty { padding: var(--sp-2) var(--sp-3); }

/* Board "+N more" overflow tag (board view is capped, never renders 100k cards) */
.board__more { display: block; text-align: center; padding: var(--sp-2); margin-top: var(--sp-1); font-size: var(--fs-xs); color: var(--ink-3); text-decoration: none; border: 1px dashed var(--line); border-radius: var(--r-sm); }
.board__more:hover { color: var(--accent); border-color: var(--accent); }

/* Pagination controls — RTL: prev (›) sits at the start, next (‹) at the end */
.pager { display: flex; align-items: center; gap: var(--sp-1); justify-content: center; margin: var(--sp-5) 0; flex-wrap: wrap; }
.pager__btn, .pager__page { display: inline-flex; align-items: center; justify-content: center; min-width: 32px; height: 32px; padding: 0 var(--sp-2); border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--surface); color: var(--ink-1); text-decoration: none; font-size: var(--fs-sm); font-variant-numeric: tabular-nums; }
.pager__btn:hover, .pager__page:hover { border-color: var(--accent); color: var(--accent); }
.pager__page.is-active { background: var(--accent); border-color: var(--accent); color: var(--canvas); font-weight: var(--fw-semi); }
.pager__btn.is-disabled { color: var(--ink-3); border-color: var(--line); background: var(--surface-2); cursor: default; pointer-events: none; }

/* ----------------------------------------------------------------------------
   21. APPROVAL QUEUE (طابور الاعتماد) — the decision desk.
   Design plan: docs/design/approvals-queue-redesign-2026-07-04.md
   Dossier + decision rail per card; status bucket-bar; slim record-only posture
   strip; pure-CSS <details> reject overlay (backdrop = the open summary's fixed
   ::after → click-outside dismisses with zero JS); the ختم القرار stamp on
   decided cards; 7-day TTL pips. Colour = signal only.
   ------------------------------------------------------------------------- */

/* --- header readout: the oldest pending wait (§4.1) --- */
.apq2-oldest {
  display: inline-flex; align-items: center; gap: var(--sp-2);
  font-size: var(--fs-sm); color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: var(--sp-1) var(--sp-3); background: var(--surface);
}
.apq2-oldest b { color: var(--warn); font-weight: var(--fw-semi); }
.apq2-oldest .ico { width: 14px; height: 14px; color: var(--warn); flex: none; }

/* --- record-only posture strip (§4.2) — replaces the amber banner --- */
.apq2-posture {
  display: flex; gap: var(--sp-3); align-items: baseline; flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--warn); border-radius: var(--r-md);
}
.apq2-posture > strong { color: var(--ink-1); font-size: var(--fs-sm); }
.apq2-posture__more { display: inline; }
.apq2-posture__more > summary {
  list-style: none; cursor: pointer; display: inline;
  color: var(--ink-3); font-size: var(--fs-xs);
}
.apq2-posture__more > summary::-webkit-details-marker { display: none; }
.apq2-posture__more > summary:hover { color: var(--accent); }
.apq2-posture__more[open] > summary { display: none; }

/* رحلة الوصول — the flight-number mismatch strip (clone .apq2-posture with a --danger accent)
   + the «تتبّع رحلة أخرى…» disclosure (summary styled like .apq2-posture__more). Existing tokens
   only, so both dark and light themes resolve correctly. */
.flight-mismatch {
  display: flex; gap: var(--sp-3); align-items: baseline; flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4); margin-bottom: var(--sp-4);
  background: var(--surface); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--danger); border-radius: var(--r-md);
}
.flight-mismatch > strong { color: var(--ink-1); font-size: var(--fs-sm); }
.flight-track-more > summary {
  list-style: none; cursor: pointer; display: inline;
  color: var(--ink-3); font-size: var(--fs-xs);
}
.flight-track-more > summary::-webkit-details-marker { display: none; }
.flight-track-more > summary:hover { color: var(--accent); }
.flight-track-more[open] > summary { display: none; }

/* --- the queue + decision card (§4.4) --- */
.apq2 { display: flex; flex-direction: column; gap: var(--sp-3); }
.apq2-card {
  display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 0;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  /* NO overflow:hidden — the reject popover must escape the card */
}
.apq2-card--pending { border-inline-start: 3px solid var(--warn); }
.apq2-dossier { min-width: 0; padding: var(--sp-4) var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3); }
.apq2-rail {
  border-inline-start: 1px solid var(--line); padding: var(--sp-4) var(--sp-5);
  display: flex; flex-direction: column; gap: var(--sp-3); position: relative;
}

/* identity row (§4.5) — one line, the message hangs off its sender */
.apq2-who { display: flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2) var(--sp-3); }
.apq2-who__id { display: inline-flex; align-items: center; gap: var(--sp-2); text-decoration: none; color: inherit; min-width: 0; }
.apq2-who__id strong { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.apq2-who__id:hover strong { color: var(--accent); }
.apq2-who__avatar { width: 32px; height: 32px; font-size: 12px; flex: none; }
.apq2-who__case {
  font-size: var(--fs-xs); text-decoration: none; color: var(--ink-2);
  border: 1px solid var(--line); border-radius: var(--r-pill); padding: 0 var(--sp-2);
}
.apq2-who__case:hover { color: var(--accent); border-color: var(--accent); }
.apq2-who__meta { display: inline-flex; align-items: center; flex-wrap: wrap; gap: var(--sp-2); font-size: var(--fs-xs); color: var(--ink-3); }
.apq2-dot { width: 3px; height: 3px; border-radius: 50%; background: var(--line-strong); flex: none; }

/* message (§4.6) */
.apq2-label { font-size: var(--fs-sm); font-weight: var(--fw-semi); color: var(--ink-2); }
.apq2-bubble {
  max-width: 52ch; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-md); border-start-start-radius: 2px;
  padding: var(--sp-2) var(--sp-3); font-size: var(--fs-sm); line-height: 1.7;
  box-shadow: var(--sh-sm);
}
.apq2-foot { display: flex; align-items: center; gap: var(--sp-3); flex-wrap: wrap; }
.apq2-key { font-family: var(--font-mono); font-size: 0.65rem; color: var(--ink-3); letter-spacing: var(--data-track); direction: ltr; unicode-bidi: embed; }

/* decision rail states (§4.7) */
.apq2-state {
  align-self: flex-start; font-size: var(--fs-xs); font-weight: var(--fw-semi);
  border-radius: var(--r-pill); padding: 2px var(--sp-3);
  color: var(--warn); background: var(--warn-soft);
}
.apq2-age { font-size: var(--fs-xs); color: var(--ink-3); }
.apq2-age--stale { color: var(--warn); font-weight: var(--fw-semi); }
.apq2-rail .btn--primary { width: 100%; justify-content: center; }
.apq2-recordonly { font-size: var(--fs-xs); color: var(--ink-3); margin-top: auto; }
.apq2-decided { font-size: var(--fs-xs); color: var(--ink-3); }
.apq2-decided b { color: var(--ink-2); font-weight: var(--fw-semi); }
.apq2-note { font-size: var(--fs-sm); color: var(--ink-2); }

/* the 7-day TTL pips — the expiry rule as visible structure */
.apq2-ttl { display: flex; align-items: center; gap: var(--sp-2); }
.apq2-ttl__pips { display: inline-flex; gap: 3px; }
.apq2-ttl__pips i {
  width: 10px; height: 4px; border-radius: 2px;
  background: var(--surface-3); border: 1px solid var(--line);
}
.apq2-ttl__pips i.on { background: var(--accent); border-color: transparent; }
.apq2-ttl--last .apq2-ttl__pips i.on { background: var(--warn); }
.apq2-ttl__text { font-size: var(--fs-xs); color: var(--ink-3); }

/* --- the reject overlay (§4.8) — pure-CSS <details> popover --- */
.apq2-reject > summary { list-style: none; cursor: pointer; }
.apq2-reject > summary::-webkit-details-marker { display: none; }
.apq2-reject__btn {
  display: flex; justify-content: center; width: 100%;
  font-size: var(--fs-sm); color: var(--danger);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3);
  transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.apq2-reject__btn:hover { background: var(--danger-soft); border-color: var(--danger); }
.apq2-reject__btn:focus-visible { outline: none; box-shadow: var(--sh-focus); }
.apq2-reject .if-open { display: none; }
.apq2-reject[open] .if-open { display: inline; }
.apq2-reject[open] .if-closed { display: none; }

/* THE BACKDROP IS THE OPEN SUMMARY'S FIXED PSEUDO-ELEMENT — clicking anywhere on
   it toggles the details closed: click-outside-to-dismiss with zero JavaScript. */
.apq2-reject[open] > summary::after {
  content: ""; position: fixed; inset: 0; z-index: 60;
  background: rgba(4, 8, 12, .55);
}
.apq2-reject[open] > .apq2-reject__btn { position: relative; z-index: 70; }

.apq2-panel {
  position: absolute; inset-inline-end: var(--sp-4); inset-block-start: auto;
  width: min(380px, calc(100vw - 2rem)); z-index: 70;
  background: var(--surface); border: 1px solid var(--line-strong);
  border-radius: var(--r-lg); box-shadow: var(--sh-lg);
  padding: var(--sp-5); display: flex; flex-direction: column; gap: var(--sp-3);
  animation: apq2-pop var(--dur) var(--ease);
}
@keyframes apq2-pop { from { opacity: 0; transform: translateY(-4px); } }
.apq2-panel__title { margin: 0; font-size: var(--fs-h3); font-weight: var(--fw-semi); }
.apq2-panel__recap { margin: 0; font-size: var(--fs-sm); color: var(--ink-2); }
.apq2-panel form { display: flex; flex-direction: column; gap: var(--sp-3); }
.apq2-panel__note { width: 100%; }
.apq2-panel__actions { display: flex; justify-content: flex-end; }

/* preset reason chips */
.apq2-chiprow { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.apq2-chip { position: relative; }
.apq2-chip input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.apq2-chip span {
  display: inline-flex; padding: var(--sp-1) var(--sp-3); border-radius: var(--r-pill);
  border: 1px solid var(--line); font-size: var(--fs-xs); color: var(--ink-2); cursor: pointer;
}
.apq2-chip input:checked + span { border-color: var(--danger); color: var(--danger); background: var(--danger-soft); }
.apq2-chip input:focus-visible + span { box-shadow: var(--sh-focus); }

/* --- ختم القرار — the decision stamp (§7, the signature) --- */
.apq2-stamp {
  align-self: flex-start; display: inline-flex; flex-direction: column; gap: 2px;
  border: 2px solid currentColor; border-radius: var(--r-sm);
  padding: var(--sp-2) var(--sp-3); transform: rotate(-1.5deg);
  font-weight: var(--fw-bold); font-size: var(--fs-sm); line-height: var(--lh-tight);
}
.apq2-stamp--ok     { color: var(--ok);     background: var(--ok-soft); }
.apq2-stamp--danger { color: var(--danger); background: var(--danger-soft); }
.apq2-stamp small   { font-weight: var(--fw-regular); font-size: 0.65rem; opacity: .8; }

/* positive empty state: the desk itself is stamped done (§4.9) */
.apq2-clear { display: flex; flex-direction: column; align-items: center; gap: var(--sp-4); padding: var(--sp-12) var(--sp-4); text-align: center; }
.apq2-clear .apq2-stamp { font-size: var(--fs-h2); transform: rotate(1.5deg); align-self: center; }
.apq2-clear p { margin: 0; color: var(--ink-3); font-size: var(--fs-sm); max-width: 52ch; }

/* mobile (§3c): rail becomes a footer row; the panel becomes a bottom sheet */
@media (max-width: 900px) {
  .apq2-card { grid-template-columns: 1fr; }
  .apq2-rail { border-inline-start: 0; border-top: 1px solid var(--line); }
  .apq2-rail .btn--primary { width: auto; flex: 1; }
  .apq2-rail { flex-direction: row; flex-wrap: wrap; align-items: center; }
  .apq2-recordonly { margin-top: 0; flex-basis: 100%; }
  .apq2-reject { flex: 1; }
}
@media (max-width: 640px) {
  .apq2-panel {
    position: fixed; inset-inline: 0; inset-block-end: 0; inset-block-start: auto;
    width: auto; border-radius: var(--r-lg) var(--r-lg) 0 0; max-height: 80vh; overflow: auto;
  }
}

/* ============================================================================
   §22  QUICK SEARCH  (بحث سريع)
   The fast one-tap facet rows above «تصفية متقدمة» on the requests surface
   (later: customers/workers). Tokens only — dark/light both resolve. Chip visuals
   are reused verbatim from .nat-chip (§5); this adds only the panel + row shell.
   Rows WRAP (like every chip row) — no horizontal scroll; .main is overflow-x:hidden.
   ========================================================================== */
.quick-search {
  display: grid; gap: var(--sp-2);
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  padding: var(--sp-3) var(--sp-4); margin: var(--sp-3) 0;
}
.quick-search__row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-2); }
.quick-search__label {
  min-inline-size: 6.5rem; color: var(--ink-2);
  font-size: var(--fs-sm); font-weight: var(--fw-semi);
}
.quick-search__more { align-self: center; }
@media (max-width: 480px) {
  .quick-search__label { flex-basis: 100%; min-inline-size: 0; }
}

/* --- Client Twin — the «اقتراح أولوية» tier badge + thread bar (docs/design/client-twin-v1) --- */
/* A ranking HINT (G6), never a verdict: muted chips, not loud alarms; jade earned only at «جاد». */
.twin-badge {
  display: inline-flex; align-items: center; gap: var(--sp-1);
  padding: 1px var(--sp-2); border-radius: var(--r-pill);
  font-size: var(--fs-xs); line-height: 1.6; white-space: nowrap;
  border: 1px solid var(--line); color: var(--ink-2); background: var(--surface-2);
}
.twin-badge__dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .8; }
.twin-badge__label { font-weight: 600; }
.twin-badge__manual {
  font-size: 10px; font-weight: 700; padding: 0 4px; border-radius: var(--r-sm);
  background: var(--surface-3); color: var(--ink-3);
}
.twin-badge--hot   { color: var(--accent); background: var(--accent-soft); border-color: transparent; }
.twin-badge--warm  { color: var(--warn);   background: var(--warn-soft);   border-color: transparent; }
.twin-badge--cold  { color: var(--ink-3);  background: var(--surface-2); }
.twin-badge--pending,
.twin-badge--unscored { color: var(--ink-3); background: transparent; }
.twin-badge--pending .twin-badge__dot { opacity: .4; }

.wa-ctier { grid-column: 2; justify-self: start; margin-top: 2px; }

/* Thread-header twin bar: badge + why-line on one side, the G1/G3 quick actions on the other. */
.wa-twin {
  display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-4); border-bottom: 1px solid var(--line);
  background: var(--surface); flex-wrap: wrap;
}
.wa-twin__main { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.wa-twin__hint { font-size: var(--fs-xs); color: var(--ink-3); }
/* The why-line — the transparency of «اقتراح أولوية» — is ALWAYS shown in full (owner request
   2026-07-05: no click-to-expand); it wraps across lines. Hover still surfaces it via the title. */
.wa-twin__why {
  margin: 0; min-width: 0;
  font-size: var(--fs-sm); color: var(--ink-2);
  max-width: 72ch; overflow-wrap: anywhere; line-height: 1.5;
}
.wa-twin__acts { display: flex; align-items: center; gap: var(--sp-2); position: relative; }
.wa-twin__override { position: relative; }
.wa-twin__override > summary { list-style: none; cursor: pointer; }
.wa-twin__override > summary::-webkit-details-marker { display: none; }
.wa-twin__pop {
  position: absolute; inset-inline-end: 0; top: calc(100% + 4px); z-index: 20;
  background: var(--surface); border: 1px solid var(--line-strong); border-radius: var(--r-md);
  padding: var(--sp-3); box-shadow: 0 8px 24px rgba(0,0,0,.28); min-width: 16rem;
  display: flex; flex-direction: column; gap: var(--sp-2);
}
.wa-twin__popacts { display: flex; flex-wrap: wrap; gap: var(--sp-2); }

/* ============================================================================
   §23  CASE DETAIL — request "cockpit" head: key-facts hero, action command bar,
   money-figures well, and the situational status-spine. Token-only (dark+light),
   RTL-native. Kills the 50/50 tall-vs-short dead space of the old card rows.
   ========================================================================== */

/* --- 23a/23b (case-hero strip + case-actionbar command bar) REMOVED 2026-07-06:
   superseded by §24 Option B (sticky key-panel) + §25 (dense fact grid); the
   case_detail.html markup no longer references .case-hero* / .case-actionbar*. --- */

/* --- 23c. تفاصيل الطلب internal split (long fields | money well) ------------ */
.case-detail-split { display: grid; grid-template-columns: 1.3fr 1fr; gap: var(--sp-5) var(--sp-6); align-items: start; }
@media (max-width: 720px) { .case-detail-split { grid-template-columns: 1fr; } }

/* --- 23d. رسوم الدفع money well (a filled panel, not empty space) ----------- */
.fee-figures {
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-md); padding: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-3);
}
.fee-figures__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--sp-3); }
.fee-figures__k { font-size: var(--fs-sm); color: var(--ink-3); }
.fee-figures__v { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-weight: var(--fw-semi); color: var(--ink); }
.fee-figures__v--lg { font-size: var(--fs-h2); }
.fee-figures__v--out   { color: var(--warn); }
.fee-figures__v--clear { color: var(--ok); }
.fee-figures__row--total { border-top: 1px dashed var(--line-strong); padding-top: var(--sp-3); }
.fee-meter { height: 6px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; }
.fee-meter__fill { display: block; height: 100%; background: var(--accent); border-radius: var(--r-pill); }

/* --- 23e. Situational band: a shared label + a status spine so the lower band
   stops reading as ragged squares. Colour = state only. --------------------- */
.band-label {
  display: flex; align-items: center; gap: var(--sp-3);
  margin: var(--sp-8) 0 var(--sp-4);
  color: var(--ink-3); font-size: var(--fs-xs); font-weight: var(--fw-semi);
}
.band-label::before, .band-label::after { content: ""; height: 1px; background: var(--line); flex: 1; }
.card--flag        { border-inline-start: 3px solid var(--line-strong); }
.card--flag-warn   { border-inline-start-color: var(--warn); }
.card--flag-danger { border-inline-start-color: var(--danger); }
.card--flag-ok     { border-inline-start-color: var(--ok); }
.card--flag-info   { border-inline-start-color: var(--info); }

/* ==========================================================================
   §24  CASE DETAIL — Option B: sticky key-panel + scrolling detail.
   The stage rail stays full-width above; below it a two-column shell places
   an always-visible key panel on the START side (RTL → right): (1) الإجراء
   التالي pinned first, (2) identity, (3) money glance — beside the scrolling
   detail column. Collapses to one column (panel first) under 960px.
   Token-only, theme-aware, RTL-native. REPLACES §23a hero + §23b action bar.
   ========================================================================== */
.case-shell {
  display: grid;
  grid-template-columns: minmax(300px, 340px) minmax(0, 1fr);
  gap: var(--sp-5) var(--sp-6);
  align-items: start;
  margin-top: var(--sp-6);            /* was the hero's top gap; keeps rhythm under the rail */
}

/* the key panel: sticky under the 56px sticky topbar; its own scroll if it
   ever outgrows the viewport (الإجراء التالي stays reachable at its top). */
.case-aside {
  position: sticky;
  top: calc(var(--shell-top) + var(--sp-4));           /* 56px topbar + breathing room ≈ 72px */
  display: flex; flex-direction: column; gap: var(--sp-4);
  max-height: calc(100vh - var(--shell-top) - var(--sp-6));
  overflow-y: auto;
  overscroll-behavior: contain;
}
.case-main { min-width: 0; }           /* block flow — preserves existing u-mb-* card spacing */

/* (1) الإجراء التالي — accent-edged card so the pinned command reads first */
.case-aside__act { border-color: var(--accent-soft); }
.case-aside__act .card__body { display: flex; flex-direction: column; gap: var(--sp-3); }
.case-aside__label {
  font-size: var(--fs-xs); font-weight: var(--fw-semi);
  letter-spacing: .02em; color: var(--accent);
}
/* stacked, full-width action buttons — verbatim button markup, laid out vertically */
.case-aside__acts { display: flex; flex-direction: column; gap: var(--sp-2); }
.case-aside__acts form { margin: 0; }
.case-aside__acts .btn { width: 100%; justify-content: center; }

/* (2) identity block */
.case-aside__id  { display: flex; flex-direction: column; gap: var(--sp-3); }
.case-aside__who { display: flex; align-items: center; gap: var(--sp-3); min-width: 0; }
.case-aside__ava {
  width: 38px; height: 38px; border-radius: var(--r-pill); flex: none;
  display: grid; place-items: center; font-weight: var(--fw-bold);
  background: var(--accent-soft); color: var(--accent);
}
.case-aside__ava--worker { background: var(--surface-2); color: var(--ink-2); }
.case-aside__who b    { display: block; font-size: var(--fs-body); line-height: var(--lh-tight);
                        white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.case-aside__who span { font-size: var(--fs-xs); color: var(--ink-3); }
.case-aside__row { display: flex; align-items: center; justify-content: space-between; gap: var(--sp-3); }
.case-aside__k   { font-size: var(--fs-sm); color: var(--ink-3); }
.case-aside__flags { display: flex; flex-wrap: wrap; gap: var(--sp-1) var(--sp-2); }

/* (3) money glance reuses .fee-figures / .fee-meter verbatim — no new rules. */

@media (max-width: 960px) {
  .case-shell { grid-template-columns: 1fr; }
  .case-aside { position: static; max-height: none; overflow: visible; }
}
@media (prefers-reduced-motion: reduce) { .case-aside { scroll-behavior: auto; } }

/* ==========================================================================
   §25  CASE DETAIL — fact list of clean property ROWS (owner-approved 2026-07-06).
   Replaces the earlier bordered auto-fit tile grid ("squares"): the fact list is
   now a borderless single-column list of `label | value` rows — gray label
   (--ink-3, regular) beside a dark value (--ink, regular), hierarchy by COLOR
   not weight. ONE hairline --line divider sits BETWEEN rows (no per-cell borders,
   no grid-gap seam bg); subtle --surface-2 hover; muted "—" empties recede; long
   values truncate with ellipsis (+ a title attr on the markup for hover). Also the
   الأطراف two-up split (customer | worker). Token-only, theme-aware, RTL-native.
   ========================================================================== */
.facts {
  display: flex;
  flex-direction: column;
}
.fact {
  display: grid;
  grid-template-columns: 140px 1fr;   /* fixed label rail → values align down the list */
  align-items: baseline;              /* label + value share a baseline; a wrapped long label top-aligns cleanly instead of centre-floating */
  gap: var(--sp-3);
  padding: var(--sp-2) var(--sp-1);    /* 8px vertical rhythm; 4px inset keeps hover off the edge */
  border-radius: var(--r-sm);
  min-width: 0;
}
.fact + .fact {
  border-top: 1px solid var(--line);   /* ONE hairline between rows — not around cells */
}
.fact:hover {
  background: var(--surface-2);         /* subtle row lift, both themes */
}
.fact__k {
  font-size: var(--fs-sm);
  font-weight: var(--fw-regular);
  color: var(--ink-3);                  /* gray label */
  line-height: var(--lh-tight);
}
.fact__v {
  font-size: var(--fs-body);
  font-weight: var(--fw-regular);       /* NOT bold — owner correction */
  color: var(--ink);                    /* dark value; contrast vs gray label = the hierarchy */
  min-width: 0;                         /* allow the ellipsis in a grid track */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;              /* FREE TEXT ONLY (see below); title="" is then MANDATORY */
}
/* ---------------- «الرقم يظهر كاملًا» — the number is shown in full ----------------
   The declaration above carries every fact value in the product, and on a box holding a figure
   it is a licence to paint a DIFFERENT figure. The clip lands at the end of the line; in an
   Arabic box the end of the line is its LEFT edge; and a Latin digit run is an inner LTR island
   whose left edge holds its HIGH-ORDER digits. So 4,500,000.00 renders as «…0000.00» — smaller,
   well-formed, unsuspicious, and with nothing on screen to tell the reader anything was lost.
   The engines do not even agree on which half survives, so one amount clips to two different
   numbers in two different browsers.
   The rule, product-wide: no element carrying money — or any digit run whose meaning depends on
   its leading digits (national ID, iqama, IBAN, phone, case no, dates) — may truncate, abbreviate
   or ellipsise at any viewport. When the space runs out the PROSE yields, not the number.
   Truncation stays legitimate for free text alone (names, notes), and there title="" stops being
   optional. Basis: WCAG 2.1 SC 1.4.10 Reflow — clipped text is lost content, and here the loss is
   undetectable. Design plan: .orbit/reviews/s2-s4-design-320.md §2; proof:
   core/tests/test_rental_screen_browser_r5.py (geometric, three engines).
   BOTH markup spellings are covered deliberately: the class on the BOX (`class="fact__v num"` —
   which is exactly where the reported rental defect lived) and the class, or a <bdi>, on a CHILD.
   A fix written with :has() alone leaves the reported defect standing verbatim. */
.fact__v.num,
.fact__v:has(.num),
.fact__v:has(bdi) {
  white-space: normal;                  /* the BOX may wrap … */
  overflow: visible;
  text-overflow: clip;
}
.fact__v .num,
.fact__v bdi {
  display: inline-block;                /* … and the digit run is ONE atom: an inline box cannot
                                           clip, cannot be measured (clientWidth is 0 on it, and
                                           the engines disagree on scrollWidth), and can be split
                                           across lines. An inline-BLOCK can do none of those. */
  white-space: nowrap;                  /* the figure never breaks internally */
}
.fact__v .num,
.fact__v.num {
  font-weight: var(--fw-regular);       /* numbers stay regular; mono + tabular inherited from .num */
}
.fact__v--mut {
  color: var(--ink-3);                  /* muted empty "—" recedes; no --ink-4 in this app */
  font-weight: var(--fw-regular);
}
.fact--span2 {
  grid-column: auto;                    /* neutralised: the old 2-col span is now just a normal row */
}
/* Under 480px (an EXISTING breakpoint — §22 uses it) a key/value row is not a row, it is a
   STACK: the 140px label rail eats 57% of the 246px a 320px phone actually offers, leaving 94px
   for the value. Stacked, the figure owns the full width of the card. Above 480px NOTHING here
   changes — desktop density is not spent paying for a phone problem. */
@media (max-width: 480px) {
  .fact {
    grid-template-columns: 1fr;
    gap: 2px;
    padding-block: var(--sp-3);
  }
}

/* الأطراف — customer | worker two-up; stacks under 720px */
.parties { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
@media (max-width: 720px) { .parties { grid-template-columns: 1fr; } }

/* a compact entity subhead: label + optional trailing badge/profile link */
.subhead { display: flex; align-items: center; gap: var(--sp-2); margin-bottom: var(--sp-2); }

/* ============================================================================
   Worker-lifecycle S2 — «دورة الحياة» card (variant A, horizontal stepper) +
   the ?phase= facet dots. Token-driven, RTL-safe (logical props), both themes,
   prefers-reduced-motion safe. Copied from .orbit/design/lifecycle-view-mockups.html.
   ========================================================================= */

/* Journey-phase pills — traffic tokens per the 4 phases (owner directive):
   مرشّحة=accent · قيد الإجراء=warn · نشطة=ok · غادرت=muted. */
.pill--phase-prospect { background: var(--accent-soft); color: var(--accent); }
.pill--phase-pre      { background: var(--warn-soft);   color: var(--warn); }
.pill--phase-active   { background: var(--ok-soft);     color: var(--ok); }
.pill--phase-departed { background: var(--surface-2);   color: var(--ink-3); }
/* a slightly larger headline pill for the two-axis head */
.pill--lg { font-size: var(--fs-sm); padding: 4px var(--sp-4) 4px var(--sp-3); }

/* a tiny phase dot before the ?phase= facet label (colour-keys to the phase pills) */
.bucket-bar__dot { width: 8px; height: 8px; border-radius: 50%; flex: none; }
.bucket-bar__dot--prospect    { background: var(--accent); }
.bucket-bar__dot--pre_arrival { background: var(--warn); }
.bucket-bar__dot--in_service  { background: var(--ok); }
.bucket-bar__dot--departed    { background: var(--ink-3); }

/* Worker identity strip at the top of the lifecycle card */
.lc-id { display: flex; align-items: center; gap: var(--sp-3); }
.lc-id__ava { width: 44px; height: 44px; border-radius: var(--r-md); background: var(--surface-2); border: 1px solid var(--line); display: grid; place-items: center; color: var(--ink-3); font-weight: var(--fw-semi); font-size: var(--fs-sm); flex: none; }
.lc-id__name { font-weight: var(--fw-semi); font-size: var(--fs-h3); }
.lc-id__meta { color: var(--ink-3); font-size: var(--fs-xs); }

/* THE TWO-AXIS HEAD — «المرحلة» and «التوفّر» as two labelled, separated facts,
   never one merged status line (the نشطة+معلّقة disambiguator). */
.lc-axes { display: flex; align-items: stretch; gap: var(--sp-5); flex-wrap: wrap; margin-top: var(--sp-4); }
.lc-axis { display: flex; flex-direction: column; gap: var(--sp-2); }
.lc-axis__label { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--ink-3); }
.lc-axis__sep { width: 1px; align-self: stretch; background: var(--line); }

/* Shared step-node states */
.lc-node { border-radius: 50%; display: grid; place-items: center; font-family: var(--font-mono); font-weight: var(--fw-semi); background: var(--surface); border: 2px solid var(--line); color: var(--ink-3); flex: none; }
.is-done .lc-node { background: var(--ok); border-color: var(--ok); color: #fff; }
.is-current .lc-node { background: var(--warn); border-color: var(--warn); color: var(--step-current-ink); box-shadow: 0 0 0 4px var(--warn-soft); }

/* Step-status legend */
.lc-legend { display: flex; flex-wrap: wrap; gap: var(--sp-2) var(--sp-4); margin-top: var(--sp-4); font-size: var(--fs-xs); color: var(--ink-3); }
.lc-legend span { display: inline-flex; align-items: center; gap: var(--sp-2); }
.lc-legend i { width: 12px; height: 12px; border-radius: 50%; flex: none; font-style: normal; display: grid; place-items: center; font-size: 9px; }
.lc-legend .i-done { background: var(--ok); color: #fff; }
.lc-legend .i-current { background: var(--warn); }
.lc-legend .i-todo { background: var(--surface); border: 2px solid var(--line); }

/* الشكل أ: horizontal stepper (RTL progress rail) */
.lc-stepper { position: relative; display: flex; margin-top: var(--sp-3); }
.lc-stepper::before { content: ""; position: absolute; top: 14px; inset-inline: 15px; height: 2px; background: var(--line); z-index: 0; }
.lc-stepper__fill { position: absolute; top: 14px; inset-inline-start: 15px; height: 2px; background: var(--ok); border-radius: var(--r-pill); z-index: 0; }
.lc-step { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: var(--sp-2); position: relative; z-index: 1; text-align: center; padding: 0 2px; }
.lc-step .lc-node { width: 30px; height: 30px; font-size: var(--fs-xs); }
.lc-step__label { font-size: 0.6875rem; line-height: 1.35; color: var(--ink-3); }
.lc-step.is-current .lc-step__label { color: var(--ink); font-weight: var(--fw-semi); }
.lc-step.is-done .lc-step__label { color: var(--ink-2); }

/* نشطة context block (shown instead of the tracker when phase != pre_arrival) */
.lc-context { display: flex; flex-wrap: wrap; align-items: center; gap: var(--sp-3) var(--sp-5); padding: var(--sp-4) var(--sp-5); border: 1px solid var(--line); border-radius: var(--r-md); background: var(--surface-2); margin-top: var(--sp-4); }
.lc-context__label { font-size: var(--fs-xs); font-weight: var(--fw-semi); color: var(--ink-3); }
.lc-context__value { font-weight: var(--fw-semi); }

/* ----------------------------------------------------------------------------
   CV-EXTRACT UX (2026-07-09) — the "intelligent upload" experience.
   (a) .cvx-overlay: staged AI-progress theater shown while the CV uploads +
       extracts (worker_cv_upload.html). (b) .cv-propose: the accept-chip for an
       AI-proposed value on a still-empty field (worker_form.html). Tokens only —
       both themes come free from the inverted token set.
   ------------------------------------------------------------------------- */
.cvx-overlay { position: fixed; inset: 0; z-index: 90; display: none;
  align-items: center; justify-content: center;
  background: color-mix(in srgb, var(--bg) 72%, transparent);
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); }
.cvx-overlay.is-on { display: flex; }
.cvx-card { width: min(420px, calc(100vw - var(--sp-6))); padding: var(--sp-6);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg, 0 18px 48px rgb(0 0 0 / .25)); }
.cvx-card__title { display: flex; align-items: center; gap: var(--sp-2);
  font-weight: var(--fw-semi); margin-bottom: var(--sp-2); }
.cvx-card__title .ico { width: 18px; height: 18px; flex: 0 0 auto; color: var(--accent); }
.cvx-card__sub { font-size: var(--fs-xs); color: var(--ink-3); margin-bottom: var(--sp-4); }
.cvx-steps { display: flex; flex-direction: column; gap: var(--sp-3); }
.cvx-step { display: flex; align-items: center; gap: var(--sp-3);
  color: var(--ink-3); font-size: var(--fs-sm); transition: color .3s; }
.cvx-step__dot { flex: 0 0 auto; width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--line); display: inline-flex; align-items: center;
  justify-content: center; transition: border-color .3s, background .3s; }
.cvx-step__dot .ico { width: 12px; height: 12px; display: none; }
.cvx-step.is-active { color: var(--ink); }
.cvx-step.is-active .cvx-step__dot { border-color: var(--accent);
  border-inline-start-color: transparent; animation: cvx-spin .8s linear infinite; }
.cvx-step.is-done { color: var(--ink-2); }
.cvx-step.is-done .cvx-step__dot { border-color: var(--accent);
  background: var(--accent-soft); animation: none; }
.cvx-step.is-done .cvx-step__dot .ico { display: block; color: var(--accent); }
@keyframes cvx-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .cvx-step.is-active .cvx-step__dot { animation: none; border-inline-start-color: var(--accent); }
}

.cv-propose { display: inline-flex; align-items: center; gap: var(--sp-2);
  margin-top: var(--sp-2); padding: var(--sp-1) var(--sp-3);
  border: 1px dashed var(--accent); border-radius: var(--r-pill, 999px);
  background: var(--accent-soft); color: var(--accent);
  font-size: var(--fs-xs); font-family: inherit; cursor: pointer;
  transition: background .15s, transform .1s; }
.cv-propose:hover { background: color-mix(in srgb, var(--accent-soft) 60%, var(--accent) 12%); }
.cv-propose:active { transform: scale(.98); }
.cv-propose .ico { width: 14px; height: 14px; }
.cv-propose__use { font-weight: var(--fw-semi); text-decoration: underline;
  text-underline-offset: 3px; }

/* =============================================================================================
   Walk-in quick capture — Concept C slide-over (owner decision 2026-07-09)
   docs/design/walkin-quick-capture-concept-2026-07-09.md
   ============================================================================================= */
.walkin-btn kbd { margin-inline-start: 2px; }
kbd {
  font-family: var(--font-mono); font-size: 11px; background: var(--surface-2);
  border: 1px solid var(--line-strong); border-bottom-width: 2px; border-radius: 5px;
  padding: 1px 6px; color: var(--ink-2);
}
.field__label .opt { color: var(--ink-3); font-weight: 400; font-size: var(--fs-xs); }

.wk-scrim {
  position: fixed; inset: 0; z-index: 58; background: rgba(16,33,29,.42);
  opacity: 0; pointer-events: none; transition: opacity var(--dur) var(--ease);
}
.wk-scrim.is-open { opacity: 1; pointer-events: auto; }
.wk-scrim[hidden] { display: block; } /* stay in the layout for the fade-out; JS re-adds [hidden] after */

/* RTL is the app's only direction (html[dir=rtl]) — enters from the physical left edge. */
.wk-panel {
  position: fixed; top: 0; bottom: 0; left: 0; width: min(420px, 94vw);
  background: var(--surface); border-inline-end: 1px solid var(--line);
  box-shadow: var(--sh-lg); z-index: 59; display: flex; flex-direction: column;
  transform: translateX(-100%); transition: transform var(--dur) var(--ease);
}
.wk-panel.is-open { transform: translateX(0); }
.wk-panel[hidden] { display: flex; }
.wk-panel__head { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line); }
.wk-panel__mark { width: 28px; height: 28px; border-radius: var(--r-sm); background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; flex: none; }
.wk-panel__mark .ico { width: 16px; height: 16px; }
.wk-panel__title { font-size: var(--fs-h3); font-weight: var(--fw-semi); }
.wk-panel__sub { font-size: var(--fs-xs); color: var(--ink-3); }
.wk-panel__body { flex: 1; overflow-y: auto; padding: var(--sp-5); }
.wk-panel__foot { display: flex; align-items: center; gap: var(--sp-3); padding: var(--sp-4) var(--sp-5); border-top: 1px solid var(--line); background: var(--surface-2); flex-wrap: wrap; }

.wk-banner {
  display: flex; align-items: flex-start; gap: var(--sp-2); padding: var(--sp-3);
  margin-bottom: var(--sp-3); border-radius: var(--r-md); background: var(--accent-soft);
  color: var(--ink-1, var(--ink)); font-size: var(--fs-sm);
}
.wk-banner .ico { width: 16px; height: 16px; flex: none; color: var(--accent); margin-top: 2px; }
.wk-banner a { font-weight: var(--fw-semi); }
.wk-hint--match { color: var(--accent); }

.wk-chips { display: flex; flex-wrap: wrap; gap: var(--sp-2); }
.wk-chip {
  display: inline-flex; align-items: center; gap: 6px; font: inherit; font-size: var(--fs-sm);
  font-weight: var(--fw-medium); padding: 6px var(--sp-3); border-radius: var(--r-pill);
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-2);
  cursor: pointer; transition: background var(--dur) var(--ease), border-color var(--dur) var(--ease), color var(--dur) var(--ease);
}
.wk-chip:hover { border-color: var(--accent); color: var(--ink); }
.wk-chip.is-active { background: var(--accent); border-color: var(--accent); color: var(--ink-on-accent); font-weight: var(--fw-semi); }
.wk-chip:focus-visible { outline: none; box-shadow: var(--sh-focus); }

.wk-more { border: 1px dashed var(--line-strong); border-radius: var(--r-md); margin-top: var(--sp-4); }
.wk-more summary {
  list-style: none; display: flex; align-items: center; gap: var(--sp-2); padding: var(--sp-3);
  cursor: pointer; font-size: var(--fs-sm); font-weight: var(--fw-medium); color: var(--ink-2);
}
.wk-more summary::-webkit-details-marker { display: none; }
.wk-more summary .ico { width: 14px; height: 14px; transition: transform var(--dur) var(--ease); }
.wk-more[open] summary .ico { transform: rotate(180deg); }
.wk-more__body { padding: 0 var(--sp-3) var(--sp-3); }

body.walkin-open { overflow: hidden; }

@media (max-width: 900px) {
  .walkin-btn__lbl, .walkin-btn__kbd { display: none; }
  .walkin-btn { width: 36px; padding: 0; }
  .wk-panel { width: 100vw; }
}

/* =============================================================================
   §27 المهام — tasks-ledger v2 («د», owner-approved; design of record
   design/tasks-ledger-v2-mockup.html). REPLACES §26 (the mywork/brich/whyline card
   idiom — superseded, ledger v2 is ONE table, not cards on a timeline). Copied
   verbatim from the mockup's candidate CSS; classes that were mockup-scoped under
   .mockD now scope under .tasks-ledger (the page wrapper). Token-only; both
   themes inherit through the vars. .filter-chip / .pager already exist elsewhere
   in this file (reused, not redeclared) — only their page-scoped states are added.
   ============================================================================= */
.thead-mk { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-bottom: 12px; }
.page-title-mk { font-size: 22px; font-weight: 800; margin: 0; }
.thead-mk .spacer { flex: 1; }
.pulse3 { display: grid; grid-template-columns: repeat(3, minmax(120px, 180px)); gap: 10px; margin-bottom: 12px; }
.chiprow { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
/* .filter-chip already exists (applied-filter chip elsewhere); the ledger's chips are a
   TOGGLE row (inactive = surface, active = accent-soft) — mirrors .doc-report's own
   scoped variant of the same reused class. */
.tasks-ledger .filter-chip {
  background: var(--surface); color: var(--ink-2); cursor: pointer; text-decoration: none;
  transition: border-color .12s ease, color .12s ease, background .12s ease;
}
.tasks-ledger .filter-chip:hover { border-color: var(--ink-3); color: var(--ink-1); text-decoration: none; }
.tasks-ledger .filter-chip.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-ring); }

/* the task-rail: NEUTRAL (jade stays reserved for case rails) + labeled = two channels */
.trail2 { display: flex; flex-direction: column; gap: 3px; width: 104px; flex: none; }
.trail2 .bars { display: flex; gap: 3px; }
.trail2 .bars i { flex: 1; height: 3px; border-radius: 999px; background: var(--line); }
.trail2 .bars i.d { background: var(--ink-3); }
.trail2 .bars i.c { background: var(--ink); }
.trail2.blocked .bars i.c { background: var(--danger); }
.trail2 small { font-size: 10.5px; color: var(--ink-3); line-height: 1.3; }
.trail2.blocked small { color: var(--danger); }

/* severity: color + SHAPE (▲ حرجة، ● عالية، ○ عادية) */
.sev { font-size: 11px; width: 16px; flex: none; display: inline-block; text-align: center; }
.sev.crit { color: var(--danger); }
.sev.hi { color: var(--warn); }
.sev.nrm { color: var(--ink-3); }

/* time column: encodes TIME ONLY */
.cd { font-family: var(--font-mono); font-variant-numeric: tabular-nums; font-size: 12.5px; white-space: nowrap; }
.cd.hot { color: var(--danger); font-weight: 600; }
.cd.warm { color: var(--warn); }
.cd.ok { color: var(--ink-3); }

/* the NOW divider — a static hairline INSIDE the ledger, no animation */
tr.nowrow td { padding: 0 !important; border-bottom: 0 !important; }
.nowbar { display: flex; align-items: center; gap: 10px; padding: 2px 14px; }
.nowbar hr { flex: 1; border: 0; border-top: 1px solid var(--accent); opacity: .6; margin: 0; }
.nowbar span { font-family: var(--font-mono); font-size: 10.5px; color: var(--accent); font-weight: 600; letter-spacing: .02em; }

.tasks-ledger tr.ovd td:first-child { border-inline-start: 3px solid var(--danger); }
.tasks-ledger .grp td {
  background: var(--surface-2); color: var(--ink-3); font-size: 11.5px; font-weight: 700;
  letter-spacing: .05em; padding: 5px 14px; border-bottom: 1px solid var(--line-strong);
}
.tasks-ledger .grp .n { font-family: var(--font-mono); margin-inline-start: 6px; }
.tasks-ledger table.data td { padding-block: 9px; }
.tasks-ledger .tt { font-weight: 600; font-size: 13.5px; }
.tasks-ledger .tt .num { font-size: 12px; color: var(--ink-3); }
.xrow { background: var(--surface-3); }
.xrow td { padding: 12px 16px !important; }
.kvline { display: flex; gap: 26px; flex-wrap: wrap; }
.kvline dl { display: grid; grid-template-columns: max-content 1fr; gap: 2px 14px; margin: 0; font-size: 12.5px; }
.kvline dt { color: var(--ink-3); }
.kvline dd { margin: 0; color: var(--ink); }
.xacts { display: flex; gap: 8px; margin-top: 10px; flex-wrap: wrap; }

/* the ledger's own expand chevron (.xtoggle) — a bare icon button, no chrome until hovered */
.xtoggle {
  flex: none; width: 20px; height: 20px; margin-inline-end: 4px; border: 0; background: transparent;
  color: var(--ink-3); cursor: pointer; display: inline-grid; place-items: center; padding: 0;
  border-radius: var(--r-sm); vertical-align: middle;
}
.xtoggle:hover { color: var(--accent); background: var(--surface-2); }
.xtoggle[aria-expanded="true"] svg { transform: rotate(90deg); }
.xtoggle svg { transition: transform var(--dur) var(--ease); }

/* topbar bell (S4): the live my-tasks counter */
.bell-wrap { position: relative; display: inline-flex; }
.bell-count {
  position: absolute; top: -4px; inset-inline-end: -4px; min-width: 17px; height: 17px;
  border-radius: 999px; background: var(--danger); color: #fff; font-size: 10.5px;
  font-weight: var(--fw-semi); display: grid; place-items: center; padding: 0 4px;
  font-variant-numeric: tabular-nums; pointer-events: none;
}

/* ============================================================================
   §  Website-order desk ring — the transient toast + the per-device mute toggle.
   Fired by weblead_ring.js on the SSE `web-lead` event. Theme-aware via the
   inverting surface/ink/line/accent tokens; RTL-aware; a sheet on phones.
   ========================================================================== */
.weblead-toasts {
  position: fixed; inset-block-end: var(--sp-4); inset-inline-start: var(--sp-4);
  display: flex; flex-direction: column; gap: var(--sp-2);
  z-index: 200; pointer-events: none; max-width: min(360px, calc(100vw - 2 * var(--sp-4)));
}
.weblead-toast {
  display: flex; align-items: center; gap: var(--sp-2);
  padding: var(--sp-3); background: var(--surface); color: var(--ink);
  border: 1px solid var(--line); border-inline-start: 3px solid var(--accent);
  border-radius: var(--r-md); box-shadow: var(--sh-lg);
  text-decoration: none; pointer-events: auto;
  opacity: 0; transform: translateY(8px); transition: opacity .22s ease, transform .22s ease;
}
.weblead-toast.is-in { opacity: 1; transform: translateY(0); }
.weblead-toast.is-leaving { opacity: 0; transform: translateY(8px); }
a.weblead-toast:hover { background: var(--surface-2); }
.weblead-toast__ico { color: var(--accent); display: inline-flex; flex: 0 0 auto; }
.weblead-toast__text { font-size: var(--fs-sm); font-weight: var(--fw-medium); line-height: 1.3; flex: 1 1 auto; }
.weblead-toast__x {
  flex: 0 0 auto; background: transparent; border: 0; color: var(--ink-3);
  font-size: 18px; line-height: 1; cursor: pointer; padding: 0 2px;
}
.weblead-toast__x:hover { color: var(--ink); }

/* mute toggle: show the speaker glyph when on, the muted glyph when off */
#weblead-mute .weblead-mute__off { display: none; }
#weblead-mute.is-off .weblead-mute__on { display: none; }
#weblead-mute.is-off .weblead-mute__off { display: inline; }
#weblead-mute.is-off { color: var(--ink-3); }

/* Web Push opt-in (#push-enable): default shows the slashed bell (off); .is-on = subscribed on
   this device → plain bell in the accent. Mirrors #weblead-mute's two-glyph swap. */
#push-enable .push-enable__on { display: none; }
#push-enable.is-on .push-enable__off { display: none; }
#push-enable.is-on .push-enable__on { display: inline; }
#push-enable.is-on { color: var(--accent); }

@media (max-width: 600px) {
  .weblead-toasts { inset-inline: var(--sp-3); inset-block-end: var(--sp-3); max-width: none; }
}
