/* ═══════════════════════════════════════════════════════════════════════════
   TARTIB TOKENS — the palette, the direction, the chrome
   brand/tartib-tokens.css → /brand/tartib-tokens.css

   ⚠️ SAFE FOR ANY PAGE TO LINK. Variables, the top bar and RTL only — no
   .card, no .btn, nothing that could collide with a dashboard that already
   owns those names. The Assets SPA links THIS file and keeps its own
   components; the hub and HR link this plus tartib-ui.css below.

   Hussain, 22 Aug 2026: "make all the dashboards have the same style and theme,
   but with a little colour-coding difference so it will be easy to work with —
   this includes Assets and any other dashboard we create."

   ⚠️ THE ONE RULE THAT MAKES COLOUR CODING WORK.
   The accent identifies the MODULE. The semantic palette describes the DATA.
   They must never borrow each other's colours. If red means "HR" in the chrome
   and "expired" in a table on the same screen, a person stops reading colour as
   meaning and starts ignoring it — and the expiry board is the one screen where
   that costs money. So:

     --accent      changes per dashboard.  Chrome only: the module chip, the
                   active nav item, links, focus rings, primary buttons.
     --ok/--warn/  IDENTICAL EVERYWHERE, on every dashboard, for all time.
     --bad/--info  Green is fine, amber is soon, red is wrong, blue is a note.

   Accents are chosen to sit away from those four hues, which is why HR is teal
   rather than the red it wears as a tile: a red sidebar on a page full of red
   expiry warnings is exactly the collision above.

   ADDING A DASHBOARD: link this file, put data-app="yourname" on <body>, and
   add one line to the accent block. Nothing else.
   ═══════════════════════════════════════════════════════════════════════════ */

:root{
  /* ── neutrals: the same paper under every product ──────────────────────── */
  --bg:#F0F4F8;
  --surface:#FFFFFF;
  --surface-2:#F7F9FC;
  --line:#E2E8F0;
  --line-soft:#EDF2F7;
  --ink:#08222D;          /* headings, table values                          */
  --body:#3E5C68;         /* running text                                    */
  --mute:#6E8894;         /* labels, captions, empty states                  */

  /* ── the Tartib chrome: navy bar, whatever the module ─────────────────── */
  --chrome:#08222D;
  --chrome-ink:#FFFFFF;
  --chrome-mute:rgba(255,255,255,.62);
  --chrome-fill:rgba(255,255,255,.13);

  /* ── SEMANTIC. Do not change these per dashboard, ever. ───────────────── */
  --ok:#0C7C5A;      --ok-bg:#F0FDF4;      --ok-line:#0C7C5A;
  --warn:#B45309;    --warn-bg:#FFF7ED;    --warn-line:#F97316;
  --bad:#DC2626;     --bad-bg:#FEF2F2;     --bad-line:#DC2626;
  --info:#2563EB;    --info-bg:#EFF6FF;    --info-line:#3B82F6;

  /* ── form ─────────────────────────────────────────────────────────────── */
  --r:12px; --r-sm:9px; --r-pill:99px;
  --shadow:0 1px 3px rgba(8,34,45,.07),0 1px 2px rgba(8,34,45,.05);
  --shadow-md:0 4px 12px rgba(8,34,45,.10);
  --shadow-lg:0 20px 50px rgba(8,34,45,.15);
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
  --sans:"Almarai",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;

  /* Default accent = Tartib itself. A dashboard that forgets its data-app
     gets the brand rather than a broken variable. */
  --accent:#00BEEC; --accent-deep:#078EAF; --accent-ink:#0A5A76;
  --accent-wash:rgba(0,190,236,.12);
  --accent-on:#04303F;    /* text that sits ON the accent                    */
}

/* ── THE COLOUR CODING ──────────────────────────────────────────────────────
   One hue each, far enough apart to tell at a glance, none of them borrowed
   from the semantic four above. */
[data-app="workspace"]{                     /* the hub — Tartib itself       */
  --accent:#00BEEC; --accent-deep:#078EAF; --accent-ink:#0A5A76;
  --accent-wash:rgba(0,190,236,.12); --accent-on:#04303F;
}
[data-app="hr"]{                            /* HR & Gov — teal, as Koobs was */
  --accent:#0D9488; --accent-deep:#0F766E; --accent-ink:#115E59;
  --accent-wash:rgba(13,148,136,.12); --accent-on:#FFFFFF;
}
[data-app="assets"]{                        /* Assets — indigo, already its own */
  --accent:#4F46E5; --accent-deep:#4338CA; --accent-ink:#3730A3;
  --accent-wash:rgba(79,70,229,.12); --accent-on:#FFFFFF;
}
[data-app="pos"]{                           /* reserved                      */
  --accent:#7C3AED; --accent-deep:#6D28D9; --accent-ink:#5B21B6;
  --accent-wash:rgba(124,58,237,.12); --accent-on:#FFFFFF;
}
[data-app="loyalty"]{                       /* reserved                      */
  --accent:#DB2777; --accent-deep:#BE185D; --accent-ink:#9D174D;
  --accent-wash:rgba(219,39,119,.12); --accent-on:#FFFFFF;
}

*{box-sizing:border-box}
body{margin:0;background:var(--bg);color:var(--body);font-family:var(--sans);
     font-size:15px;line-height:1.6;-webkit-font-smoothing:antialiased}
a{color:var(--accent-deep);text-decoration:none}
button{font-family:inherit;cursor:pointer}
.ar{font-family:'Almarai',sans-serif}
.mut{color:var(--mute);font-size:13px}

/* ═══ THE TENANT'S OWN MARK ═════════════════════════════════════════════════
   Hussain: "show the tenant logo on the topbar after the keypad, then the
   brand name, then the word Workspace."

       [keypad] [logo] Koobs Cafe  Workspace

   ⚠️ THE LOGO IS OPTIONAL AND THE BAR MUST SURVIVE IT BEING ABSENT. The first
   version of the hub used an <img> for the wordmark, the file 404'd on a
   tenant host, and the chrome was left nameless — which is why it became text
   in the first place. So the name is ALWAYS rendered; the logo sits in front
   of it when the tenant has one, and removes itself on error. A business with
   no logo yet sees its name, not a broken-image glyph. */
.logo{height:28px;width:auto;max-width:132px;object-fit:contain;border-radius:6px;
  background:rgba(255,255,255,.08);padding:2px 5px;flex-shrink:0}
.brand{display:flex;align-items:center;gap:10px;min-width:0}
.brand .co{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:190px}
.word{font-size:11px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--accent);opacity:.95;white-space:nowrap}
@media(max-width:520px){ .logo{max-width:84px} .brand .co{max-width:110px} .word{display:none} }

/* ── the language switch ────────────────────────────────────────────────── */
.lang{display:flex;background:var(--chrome-fill);border-radius:var(--r-pill);padding:2px;gap:2px;flex-shrink:0}
.lang button{font:inherit;font-size:11.5px;font-weight:800;color:rgba(255,255,255,.72);
  background:none;border:0;border-radius:var(--r-pill);padding:4px 11px;line-height:1.5}
.lang button.on{background:var(--accent);color:var(--accent-on)}
.lang button:hover:not(.on){color:#fff}

/* ═══ ARABIC ════════════════════════════════════════════════════════════════
   Direction is a document property, so it is set once on <html> and every
   layout below follows from it rather than from a per-component flag.

   ⚠️ NUMBERS, DATES AND MONEY STAY LTR. An Arabic HR screen still shows
   2026-11-12 and 290.000 left-to-right — flipping a date string is not
   translation, it is corruption, and a renewal date read backwards is a
   renewal missed. Anything in --mono is pinned. */
html[dir="rtl"] body{font-family:'Almarai',var(--sans)}
html[dir="rtl"] .side{border-right:0;border-left:1px solid var(--line)}
html[dir="rtl"] .nav{text-align:right}
html[dir="rtl"] .table th,html[dir="rtl"] td{text-align:right}
html[dir="rtl"] .num,
html[dir="rtl"] [class*="num"],
html[dir="rtl"] .table th.num{direction:ltr;text-align:left;unicode-bidi:isolate}
html[dir="rtl"] .stat .v{direction:ltr;text-align:right;unicode-bidi:isolate}
html[dir="rtl"] .grp{text-align:right}
@media(max-width:900px){ html[dir="rtl"] .side{border-left:0;border-bottom:1px solid var(--line)} }
/* A date or an amount anywhere, in either direction, is left-to-right. */
.ltr,time,.money{direction:ltr;unicode-bidi:isolate}

/* ⚠️ THE SAFETY NET FOR ANYTHING NOT TRANSLATED YET.
   An English sentence sitting inside an RTL document is re-ordered by the
   bidi algorithm: "9 branches between them" renders as "branches 9 between
   them", and a trailing full stop jumps to the front of the line. That is not
   a translation gap, it is corruption — the words are wrong, not merely
   English. Any string still in English while the page is Arabic gets isolated
   so it reads correctly until it is translated. */
html[dir="rtl"] .en{direction:ltr;unicode-bidi:isolate;display:inline-block;text-align:left}

/* ── top bar ────────────────────────────────────────────────────────────── */
.top{position:sticky;top:0;z-index:40;background:var(--chrome);color:var(--chrome-ink);
  height:56px;display:flex;align-items:center;gap:14px;padding:0 18px}
/* The module's own colour, on the smallest surface that identifies it. */
.mark{width:30px;height:30px;border-radius:8px;background:var(--accent-wash);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:12px;
  letter-spacing:-.5px;color:var(--accent);flex-shrink:0}
.co{font-weight:800;font-size:15px;color:var(--accent)}
.ttl{font-weight:700;font-size:15px;color:var(--chrome-ink)}
.sub{color:var(--chrome-mute);font-size:12.5px}
.sp{flex:1}
.btn-out{font:inherit;font-size:12.5px;font-weight:700;color:#fff;background:var(--chrome-fill);
  border:0;border-radius:8px;padding:7px 14px;text-decoration:none;display:inline-block}
.btn-out:hover{background:rgba(255,255,255,.22)}

/* ═══ THE BAR'S OWN CONTROLS ════════════════════════════════════════════════
   Keypad, language, profile — the same three on every page, in the same
   order, at the same size. */
.key-btn{width:32px;height:32px;border-radius:8px;border:0;background:var(--chrome-fill);
  color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0}
.key-btn:hover{background:rgba(255,255,255,.24)}

.prof-wrap{position:relative;flex-shrink:0}
.prof-chip{display:flex;align-items:center;gap:5px;background:none;border:0;padding:2px;border-radius:99px}
.prof-chip:hover{background:var(--chrome-fill)}
.prof-av{width:30px;height:30px;border-radius:50%;color:#fff;display:flex;align-items:center;
  justify-content:center;font-weight:700;font-size:11.5px;flex-shrink:0}
.prof-av.lg{width:38px;height:38px;font-size:14px}
.prof-caret{color:rgba(255,255,255,.6);font-size:10px}
.prof-panel{position:absolute;top:calc(100% + 9px);inset-inline-end:0;width:264px;background:var(--surface);
  border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow-lg);z-index:60;padding:5px 0;display:none}
.prof-panel.open{display:block}
.prof-head{display:flex;align-items:center;gap:11px;padding:13px 15px}
.prof-nm{display:block;font-weight:700;font-size:13px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prof-em{display:block;font-size:11.5px;color:var(--mute);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.prof-chips{display:flex;flex-wrap:wrap;gap:5px;padding:0 15px 10px}
.prof-tag{font-size:10.5px;font-weight:700;color:var(--accent-ink);background:var(--accent-wash);padding:2px 7px;border-radius:5px}
.prof-sep{border-top:1px solid var(--line-soft);margin:4px 0}
.prof-link{display:block;width:100%;text-align:start;padding:10px 15px;font:inherit;font-size:13px;
  font-weight:600;color:var(--ink);background:none;border:0;text-decoration:none}
.prof-link:hover{background:var(--surface-2)}
.prof-link.danger{color:var(--bad)}

/* ── the keypad's launcher ──────────────────────────────────────────────── */
.apps-ov{position:fixed;inset:0;background:rgba(8,34,45,.45);z-index:80;display:flex;
  align-items:flex-start;justify-content:center;padding:78px 16px 16px}
.apps-ov[hidden]{display:none}
.apps-box{background:var(--surface);border-radius:var(--r);box-shadow:var(--shadow-lg);
  width:100%;max-width:560px;max-height:70vh;display:flex;flex-direction:column;overflow:hidden}
.apps-hd{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid var(--line-soft)}
.apps-hd b{color:var(--ink);font-size:14px}
.apps-x{background:none;border:0;font-size:15px;color:var(--mute);padding:4px 8px}
.apps-bd{padding:16px 18px 20px;overflow-y:auto}
.apps-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:10px}
.app-go{display:flex;flex-direction:column;align-items:center;gap:7px;padding:14px 8px;border-radius:var(--r-sm);
  border:1px solid var(--line-soft);background:var(--surface-2);text-decoration:none;transition:border-color .12s,transform .12s}
.app-go:hover{border-color:var(--accent);transform:translateY(-2px)}
.app-go.here{border-color:var(--accent);background:var(--accent-wash)}
.app-go-i{width:34px;height:34px;border-radius:9px;background:var(--accent-wash);color:var(--accent-ink);
  display:flex;align-items:center;justify-content:center;font-weight:800;font-size:14px}
.app-go-n{font-size:11.5px;font-weight:700;color:var(--ink);text-align:center;line-height:1.25}
.apps-empty{color:var(--mute);font-size:13.5px;text-align:center;padding:24px 0}

.spin{width:22px;height:22px;border:2.5px solid var(--line);border-top-color:var(--accent);
  border-radius:50%;animation:t-sp .7s linear infinite;margin:30px auto}
@keyframes t-sp{to{transform:rotate(360deg)}}

@media(max-width:760px){
  /* ⚠️ The bar is the thing that overflows on a phone, not the tables — seven
     un-wrapping flex items in a 390px row. Learned on the HR dashboard. */
  .top{gap:9px;padding:0 12px}
  .top .sub,.top .who{display:none}
  .ttl{font-size:13.5px}
}
@media(max-width:420px){ .ttl{display:none} }
