/* ============================================================
   ATRAK CRM — shared stylesheet (RTL, dark-first, matches the main site)
   ============================================================ */

/* ---------- the interface font, served from this server ----------
   Vazirmatn used to be pulled from cdn.jsdelivr.net as a render-blocking
   stylesheet, which was the single slowest thing about opening the CRM for the
   people who actually use it: a third-party host, reached from Iranian
   connections where it is routinely slow and sometimes unreachable, and nothing
   painted until it answered or the browser gave up.

   This is the variable font — one 108 KB file covering every weight from 100 to
   900 — rather than the nine separate weight files the CDN's font-face sheet
   declared. The interface uses 400, 500, 600, 700 and 800, so the single
   variable file is smaller than the weights alone would have been, and it is
   one request instead of two (stylesheet, then font).

   font-display: swap so text is readable immediately in the fallback and
   re-renders when the real face arrives; a blank page is never the better
   trade for a support desk. */
@font-face {
  font-family: "Vazirmatn";
  src: url("fonts/Vazirmatn.woff2") format("woff2-variations"),
       url("fonts/Vazirmatn.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --bg: #05070d; --bg-2: #080c16; --bg-3: #0c1120;
  --surface: rgba(255,255,255,.035); --surface-2: rgba(255,255,255,.06);
  --line: rgba(255,255,255,.09); --line-soft: rgba(255,255,255,.05);
  --text: #eaf0ff; --muted: #8b96b0; --faint: #5d6782;
  --c1: #3ddbd9; --c2: #7c5cff; --c3: #ff8a5c;
  --ok: #37d69a; --warn: #ffc14d; --bad: #ff6b7a;
  --grad: linear-gradient(115deg, var(--c1), var(--c2) 62%, #b98cff);
  --shadow: 0 24px 70px -28px rgba(0,0,0,.85);
  --r-sm: 10px; --r: 16px; --r-lg: 24px;
  --ease: cubic-bezier(.22,1,.36,1);
  --font: "Vazirmatn", "Segoe UI", Tahoma, sans-serif;
  --mono: ui-monospace, "Cascadia Mono", Consolas, monospace;
}

:root[data-theme="light"] {
  --bg: #f4f6fb; --bg-2: #ffffff; --bg-3: #eef1f8;
  --surface: #ffffff; --surface-2: #f7f9fd;
  --line: rgba(12,20,45,.12); --line-soft: rgba(12,20,45,.07);
  --text: #0d1428; --muted: #55607d; --faint: #8d97b0;
  --c1: #0aa6b8; --c2: #5b3ff0;
  --ok: #12a870; --warn: #b8860b; --bad: #d6455a;
  --shadow: 0 20px 50px -30px rgba(20,30,70,.3);
}

* { box-sizing: border-box; }
body {
  margin: 0; font-family: var(--font); background: var(--bg); color: var(--text);
  line-height: 1.8; -webkit-font-smoothing: antialiased;
}
h1,h2,h3,h4 { margin: 0; line-height: 1.4; font-weight: 700; letter-spacing: -.01em; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
button, input, select, textarea { font: inherit; color: inherit; }
svg { display: block; }
::selection { background: var(--c2); color: #fff; }

.grad { background: var(--grad); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; }
.mono { font-family: var(--mono); letter-spacing: .02em; }
.muted { color: var(--muted); }
.hidden { display: none !important; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5rem;
  padding: .7rem 1.35rem; border-radius: 999px; cursor: pointer; white-space: nowrap;
  border: 1px solid var(--line); background: var(--surface-2); font-size: .92rem; font-weight: 600;
  transition: transform .25s var(--ease), border-color .25s, background .25s, opacity .25s;
}
.btn:hover:not(:disabled) { transform: translateY(-2px); border-color: color-mix(in srgb, var(--c1) 45%, transparent); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn--primary { background: var(--grad); color: #04060c; border-color: transparent; }
.btn--ghost { background: transparent; }
.btn--sm { padding: .45rem 1rem; font-size: .84rem; }
.btn--full { width: 100%; }
.btn--danger { border-color: color-mix(in srgb, var(--bad) 45%, transparent); color: var(--bad); }

.icon-btn {
  width: 38px; height: 38px; flex: none; display: grid; place-items: center; cursor: pointer;
  border-radius: 50%; border: 1px solid var(--line); background: var(--surface);
  transition: border-color .25s, transform .25s;
}
.icon-btn:hover { border-color: color-mix(in srgb, var(--c1) 50%, transparent); transform: rotate(-10deg); }
.icon-btn svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
.ic-sun { display: none; }
:root[data-theme="light"] .ic-sun { display: block; }
:root[data-theme="light"] .ic-moon { display: none; }

/* ---------- fields ---------- */
.field { display: grid; gap: .4rem; }
.field > span { font-size: .84rem; color: var(--muted); }
.field input, .field select, .field textarea {
  width: 100%; padding: .72rem .9rem; border-radius: var(--r-sm); resize: vertical;
  border: 1px solid var(--line); background: var(--bg-3); font-size: .93rem;
  transition: border-color .2s, box-shadow .2s;
}
:root[data-theme="light"] .field input,
:root[data-theme="light"] .field select,
:root[data-theme="light"] .field textarea { background: #fff; }
.field input::placeholder, .field textarea::placeholder { color: var(--faint); }
.field :focus { outline: none; border-color: color-mix(in srgb, var(--c1) 60%, transparent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--c1) 14%, transparent); }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: .9rem; }

/* ---------- badges ---------- */
.badge {
  display: inline-flex; align-items: center; gap: .35rem; padding: .22rem .7rem;
  border-radius: 999px; font-size: .76rem; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent;
}
.badge::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.st-new  { color: var(--c1);   background: color-mix(in srgb, var(--c1) 13%, transparent);  border-color: color-mix(in srgb, var(--c1) 32%, transparent); }
.st-work { color: var(--warn); background: color-mix(in srgb, var(--warn) 13%, transparent); border-color: color-mix(in srgb, var(--warn) 32%, transparent); }
.st-wait { color: var(--c2);   background: color-mix(in srgb, var(--c2) 15%, transparent);  border-color: color-mix(in srgb, var(--c2) 35%, transparent); }
.st-done { color: var(--ok);   background: color-mix(in srgb, var(--ok) 13%, transparent);   border-color: color-mix(in srgb, var(--ok) 32%, transparent); }
.st-shut { color: var(--faint);background: var(--surface); border-color: var(--line); }
.st-stop { color: var(--bad);  background: color-mix(in srgb, var(--bad) 13%, transparent);  border-color: color-mix(in srgb, var(--bad) 32%, transparent); }
/* Blocked on the client, not on us — its own colour so it can't be mistaken at
   a glance for either "we're working on it" or "it's finished". */
.st-hold { color: var(--c3);   background: color-mix(in srgb, var(--c3) 13%, transparent);  border-color: color-mix(in srgb, var(--c3) 34%, transparent); }

/* Overdue markers. Deliberately a different shape from .badge so an SLA
   warning never reads as another ticket status. */
.chip {
  display: inline-flex; align-items: center; gap: .3rem; padding: .16rem .55rem;
  border-radius: 6px; font-size: .73rem; font-weight: 600; white-space: nowrap;
  border: 1px solid transparent;
}
.chip--bad  { color: var(--bad);  background: color-mix(in srgb, var(--bad) 12%, transparent);
              border-color: color-mix(in srgb, var(--bad) 34%, transparent); }
.chip--warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 13%, transparent);
              border-color: color-mix(in srgb, var(--warn) 34%, transparent); }
.chip--ok   { color: var(--ok);   background: color-mix(in srgb, var(--ok) 12%, transparent);
              border-color: color-mix(in srgb, var(--ok) 32%, transparent); }

/* A dot on a ticket the customer has spoken on and nobody has answered. */
.dot-new {
  width: 8px; height: 8px; border-radius: 50%; flex: none; display: inline-block;
  background: var(--c3); box-shadow: 0 0 0 3px color-mix(in srgb, var(--c3) 22%, transparent);
}

.pri { font-size: .74rem; padding: .18rem .6rem; border-radius: 7px; border: 1px solid var(--line); color: var(--muted); }
.pri-high     { color: var(--c3);  border-color: color-mix(in srgb, var(--c3) 40%, transparent); }
.pri-critical { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 50%, transparent);
                background: color-mix(in srgb, var(--bad) 10%, transparent); font-weight: 700; }

/* ---------- shell / topbar ---------- */
.top {
  position: sticky; top: 0; z-index: 30; background: var(--bg);
  border-block-end: 1px solid var(--line-soft);
}
.top__in {
  width: min(1400px, calc(100% - 2.5rem)); margin-inline: auto; height: 68px;
  display: flex; align-items: center; gap: 1rem;
}
.brand { display: inline-flex; align-items: center; gap: .65rem; }
/* The mark is either the organisation's logo image or the fallback SVG, so the
   box is sized on the wrapper and the child just fills it. */
.brand svg,
.brand #brandMark { width: 34px; height: 34px; flex: none; display: inline-block; }
.brand b { font-size: .98rem; font-weight: 800; display: block; line-height: 1.2; }
.brand i { font-style: normal; font-family: var(--mono); font-size: .58rem; letter-spacing: .2em; color: var(--faint); }

.tabs { display: flex; gap: .25rem; margin-inline-start: 1.5rem; }
.tabs button {
  padding: .45rem .95rem; border-radius: 999px; border: 1px solid transparent; cursor: pointer;
  background: transparent; color: var(--muted); font-size: .9rem; transition: .25s;
}
.tabs button:hover { color: var(--text); background: var(--surface); }
.tabs button.on { color: var(--text); background: var(--surface-2); border-color: var(--line); }

.who { margin-inline-start: auto; display: flex; align-items: center; gap: .7rem; font-size: .87rem; }
.who__name { text-align: end; line-height: 1.3; }
.who__name b { display: block; font-size: .9rem; }
.who__name span { color: var(--faint); font-size: .76rem; }

.wrap { width: min(1400px, calc(100% - 2.5rem)); margin: 2rem auto 4rem; }

/* ============================================================
   admin console — right sidebar layout

   The support desk grew past a header full of tabs, so the admin console (only)
   moves its navigation into a fixed sidebar. It sits at the inline-start edge,
   which in this RTL app is the right — exactly where the menu was asked for.
   The customer portal and the login page keep the plain .top header above; this
   block is scoped to .app so it never touches them.
   ============================================================ */
.app { display: flex; align-items: stretch; min-height: 100vh; }

.side {
  position: sticky; top: 0; align-self: flex-start;
  width: 240px; flex: none; height: 100vh; box-sizing: border-box;
  display: flex; flex-direction: column; gap: 1rem;
  padding: 1.1rem .8rem; background: var(--bg-2);
  border-inline-end: 1px solid var(--line-soft);   /* divider facing the content */
}
.side__brand { display: flex; align-items: center; justify-content: space-between; padding-inline: .4rem; }
.side .tabs {
  flex: 1; min-height: 0; overflow-y: auto;
  flex-direction: column; gap: .15rem; margin: 0; width: 100%;
}
.side .tabs button {
  width: 100%; text-align: start; padding: .62rem .9rem; border-radius: var(--r-sm);
  display: flex; align-items: center; gap: .5rem;
}
/* A small count sitting on a tab. There was no shared rule for this — the admin
   console styled its own — so the portal's poll count would have rendered as a
   bare digit. */
.tab-badge {
  display: inline-grid; place-items: center; min-inline-size: 1.25rem;
  padding: 0 .32rem; margin-inline-start: .4rem;
  border-radius: 999px; font-size: .72rem; line-height: 1.55;
  background: var(--surface-2); color: var(--muted);
}
/* Red, for a count that is asking for something. Used by the نظرسنجی tab: a
   person who closed the pop-up said "not now", and this is what keeps that
   promise visible without nagging them again on every sign-in. */
.tab-badge--alert { background: var(--bad); color: #fff; font-weight: 700; }

.side .tabs button .tab-badge { margin-inline-start: auto; }   /* float the count to the row end */
.side__foot {
  border-block-start: 1px solid var(--line-soft); padding: .8rem .4rem 0;
  display: grid; gap: .7rem;
}
.side__foot-actions { display: flex; align-items: center; gap: .6rem; }
.side__close, .side__scrim { display: none; }        /* mobile-only affordances */

/* Inside the sidebar layout the content area takes the rest of the row and caps
   its own reading width, instead of the header layout's centred column. */
.app .wrap {
  flex: 1; min-width: 0; width: auto; max-width: 1180px;
  margin: 2rem auto 4rem; padding-inline: 1.6rem;
}

.side__foot .who__name { text-align: start; }

/* Slim bar with the burger, shown only when the sidebar is a drawer. */
.appbar { display: none; align-items: center; gap: .7rem; margin-block-end: 1.2rem; }
.appbar b { font-size: 1rem; font-weight: 800; }

/* Below this width the sidebar becomes an off-canvas drawer (slides in from the
   right, the inline-start edge in RTL) with a burger in the appbar. The
   `.side .tabs order/overflow` resets undo the header's .tabs media rule, which
   would otherwise push the tab list below the footer and scroll it sideways. */
@media (max-width: 900px) {
  .side {
    position: fixed; top: 0; bottom: 0; right: 0; left: auto;
    width: 268px; height: 100vh; z-index: 60;
    transform: translateX(100%); transition: transform .3s var(--ease);
    box-shadow: var(--shadow);
  }
  .side--open { transform: none; }
  .side .tabs { order: 0; overflow-x: visible; overflow-y: auto; }
  .side__close { display: grid; }
  .side__scrim {
    display: block; position: fixed; inset: 0; z-index: 55;
    background: rgba(0,0,0,.5); opacity: 0; pointer-events: none; transition: opacity .3s;
  }
  .side__scrim.on { opacity: 1; pointer-events: auto; }
  .appbar { display: flex; }
  .app .wrap { padding-inline: 1rem; margin-block: 0 3rem; max-width: none; }
}

/* ---------- cards / panels ---------- */
.panel {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface);
  padding: 1.5rem;
}
.panel__h { display: flex; align-items: center; justify-content: space-between; gap: 1rem; margin-block-end: 1.2rem; flex-wrap: wrap; }
.panel__h h2 { font-size: 1.1rem; }

/* ---------- toast ---------- */
#toast {
  position: fixed; inset-block-end: 1.5rem; inset-inline-start: 50%; translate: 50% 0; z-index: 90;
  display: grid; gap: .5rem; justify-items: center; pointer-events: none;
}
.toast {
  padding: .75rem 1.3rem; border-radius: 999px; font-size: .9rem; font-weight: 600;
  border: 1px solid var(--line); background: var(--bg-2); box-shadow: var(--shadow);
  animation: pop .35s var(--ease);
}
.toast.bad { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 45%, transparent); }
.toast.good { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 45%, transparent); }
@keyframes pop { from { opacity: 0; transform: translateY(12px); } }

/* ---------- empty state ---------- */
.empty { text-align: center; padding: 3.5rem 1rem; color: var(--muted); }
.empty svg { width: 46px; height: 46px; margin: 0 auto 1rem; stroke: var(--faint); fill: none; stroke-width: 1.4; }

/* ---------- confirm / prompt overlay ----------
   Used instead of window.confirm()/prompt(): those are native browser dialogs
   that freeze the entire tab (including devtools and any automation attached
   to it) until a human dismisses them by hand. */
.ov { position: fixed; inset: 0; z-index: 80; display: none; place-items: center; padding: 1.5rem; }
.ov.open { display: grid; }
.ov__bg { position: absolute; inset: 0; background: rgba(0,0,0,.68); }
.ov__box {
  position: relative; width: min(420px, 100%); background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 1.6rem; box-shadow: var(--shadow); animation: ov-rise .25s var(--ease);
  display: grid; gap: 1rem;
}
.ov__box p { font-size: .93rem; line-height: 1.8; white-space: pre-line; }
.ov__box input {
  padding: .72rem .9rem; border-radius: var(--r-sm); border: 1px solid var(--line);
  background: var(--bg-3); font-size: .93rem;
}
.ov__box input:focus { outline: none; border-color: color-mix(in srgb, var(--c1) 60%, transparent); }
.ov__actions { display: flex; gap: .6rem; }
.ov__actions .btn { flex: 1; }
@keyframes ov-rise { from { opacity: 0; transform: translateY(10px); } }

/* ---------- form dialog (openDlg) ----------
   Lived inline in admin.html until the portal needed it too, for a liaison
   managing their company's accounts. A shared component whose styles sit on one
   page renders unstyled on the other, so both halves live here now. */
.dlg { position: fixed; inset: 0; z-index: 70; display: none; }
.dlg.open { display: grid; place-items: center; padding: 1.5rem; }
.dlg__bg { position: absolute; inset: 0; background: rgba(0,0,0,.68); }
.dlg__box {
  position: relative; width: min(520px, 100%); max-height: 88svh; overflow-y: auto;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 1.7rem; box-shadow: var(--shadow); animation: rise .3s var(--ease);
}
@keyframes rise { from { opacity: 0; transform: translateY(14px); } }

/* ---------- spinner ---------- */
.spin {
  width: 22px; height: 22px; margin: 2.5rem auto; border-radius: 50%;
  border: 2px solid var(--line); border-top-color: var(--c1); animation: rot .7s linear infinite;
}
@keyframes rot { to { rotate: 360deg; } }

/* ---------- attachments ---------- */
.atts { display: grid; gap: .5rem; margin-block: .9rem; }
.att {
  display: flex; align-items: center; gap: .75rem; padding: .5rem .7rem;
  border: 1px solid var(--line-soft); border-radius: var(--r-sm); background: var(--surface);
}
.att__thumb { flex: none; width: 46px; height: 46px; border-radius: 8px; overflow: hidden;
              border: 1px solid var(--line); background: var(--bg-3); }
.att__thumb img { width: 100%; height: 100%; object-fit: cover; }
.att__ic { flex: none; width: 46px; height: 46px; display: grid; place-items: center;
           border-radius: 8px; border: 1px solid var(--line); background: var(--bg-3); color: var(--faint); }
.att__ic svg { width: 20px; height: 20px; }
.att__meta { display: grid; min-width: 0; gap: .1rem; flex: 1; }
.att__meta a { font-size: .87rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.att__meta a:hover { color: var(--c1); }
.att__meta span { font-size: .75rem; color: var(--faint); }
.att .icon-btn { width: 30px; height: 30px; }
.att .icon-btn svg { width: 13px; height: 13px; }

/* The file picker itself — a drop target that also works as a plain button. */
.drop {
  display: flex; align-items: center; gap: .6rem; padding: .7rem .9rem; cursor: pointer;
  border: 1px dashed var(--line); border-radius: var(--r-sm); background: var(--bg-3);
  color: var(--muted); font-size: .85rem; transition: border-color .2s, color .2s;
}
.drop:hover, .drop.over { border-color: color-mix(in srgb, var(--c1) 55%, transparent); color: var(--text); }
.drop svg { width: 17px; height: 17px; flex: none; }
.drop input[type="file"] { display: none; }
.drop__names { font-size: .78rem; color: var(--c1); }

/* Files chosen but not yet sent. Tighter than a saved attachment row: this is a
   working list the person is still editing, not a record of what was filed. */
.atts--staged { gap: .35rem; margin-block: .5rem 0; }
.atts--staged .att { padding: .35rem .55rem; }
.atts--staged .att__ic { width: 32px; height: 32px; }
.atts--staged .att__ic svg { width: 15px; height: 15px; }
.atts--staged .att__meta b { font-size: .84rem; overflow: hidden;
                             text-overflow: ellipsis; white-space: nowrap; }

/* ---------- what the priorities mean ---------- */
.prio-help {
  border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: var(--bg-3); padding: .7rem .85rem;
}
.prio-help > b { display: block; font-size: .84rem; margin-block-end: .5rem; }
.prio-help p { font-size: .76rem; color: var(--faint); margin: .55rem 0 0; line-height: 1.7; }

.prio-guide { list-style: none; margin: 0; padding: 0; display: grid; gap: .4rem; }
.prio-guide li {
  display: grid; grid-template-columns: auto 1fr; gap: .2rem .55rem; align-items: baseline;
  font-size: .8rem; line-height: 1.6;
}
.prio-guide li .pri { justify-self: start; }
.prio-guide li span { color: var(--text); }
/* The promised reply time sits under the description, indented past the tag. */
.prio-guide li i { grid-column: 2; font-style: normal; font-size: .73rem; color: var(--faint); }

/* Why an urgent option is unavailable right now. Marked out from the guide
   above, because it is about this moment rather than about the meanings. */
.prio-help__shut {
  margin-block-start: .6rem; padding: .5rem .65rem;
  border-inline-start: 3px solid var(--warn); border-radius: var(--r-sm);
  background: color-mix(in srgb, var(--warn) 9%, transparent);
}
.prio-help__shut p { margin: 0; font-size: .78rem; line-height: 1.75; color: var(--text); }
.prio-help__shut p + p { margin-block-start: .35rem; }

/* ---------- rating ---------- */
.stars { color: var(--warn); letter-spacing: .1em; font-size: .95rem; white-space: nowrap; }
.stars__off { color: var(--line); }

.rate-pick { display: flex; flex-direction: row-reverse; justify-content: flex-end; gap: .15rem; }
.rate-pick input { position: absolute; opacity: 0; pointer-events: none; }
.rate-pick label {
  cursor: pointer; font-size: 1.7rem; line-height: 1; color: var(--line);
  transition: color .15s, transform .15s;
}
/* Row is reversed, so "this star and every star before it in the DOM" is the
   sibling selector — which paints the chosen star and all the lower ones. */
.rate-pick input:checked ~ label,
.rate-pick label:hover,
.rate-pick label:hover ~ label { color: var(--warn); }
.rate-pick label:hover { transform: scale(1.12); }
.rate-pick input:focus-visible + label { outline: 2px solid var(--c1); outline-offset: 3px; border-radius: 4px; }

.rate-box {
  border: 1px solid color-mix(in srgb, var(--warn) 30%, transparent);
  background: color-mix(in srgb, var(--warn) 7%, transparent);
  border-radius: var(--r); padding: 1.1rem 1.2rem; margin-block: 1.2rem; display: grid; gap: .8rem;
}
.rate-box h3 { font-size: .95rem; }

/* ---------- company approval ----------
   Its own block rather than another .msg in the thread: an approval is a
   decision with a name and a time attached, and it has to be findable months
   later without reading the whole conversation. */
.appr {
  display: grid; gap: .5rem; padding: 1rem 1.15rem; border-radius: var(--r);
  border: 1px solid var(--line); background: var(--surface); margin-block: 1.1rem;
}
.appr--wait { border-color: color-mix(in srgb, var(--c3) 40%, transparent);
              background: color-mix(in srgb, var(--c3) 8%, transparent); }
.appr--ok   { border-color: color-mix(in srgb, var(--ok) 34%, transparent);
              background: color-mix(in srgb, var(--ok) 7%, transparent); }
.appr--no   { border-color: color-mix(in srgb, var(--bad) 34%, transparent);
              background: color-mix(in srgb, var(--bad) 7%, transparent); }
.appr__h { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; font-size: .93rem; font-weight: 700; }
.appr__note { font-size: .9rem; }
.appr__meta { font-size: .78rem; color: var(--faint); }
.appr__actions { display: flex; gap: .5rem; flex-wrap: wrap; margin-block-start: .3rem; }
.appr__past { display: grid; gap: .3rem; font-size: .82rem; color: var(--muted); }

/* The liaison's own "these are waiting on you" list, above their ticket list. */
.appr-queue { display: grid; gap: .5rem; margin-block-end: 1.2rem; }
.appr-queue button {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap; width: 100%; cursor: pointer;
  text-align: start; padding: .75rem .95rem; border-radius: var(--r-sm);
  border: 1px solid color-mix(in srgb, var(--c3) 40%, transparent);
  background: color-mix(in srgb, var(--c3) 8%, transparent); color: inherit;
  font-size: .88rem; transition: transform .25s var(--ease);
}
.appr-queue button:hover { transform: translateY(-2px); }
.appr-queue .mono { color: var(--faint); font-size: .78rem; }

/* ---------- "act as user" banner (portal, CEO impersonation) ---------- */
.actas-bar {
  position: sticky; top: 0; z-index: 70;
  display: flex; align-items: center; justify-content: center; gap: 1rem; flex-wrap: wrap;
  padding: .6rem 1.2rem; font-size: .86rem; font-weight: 600;
  color: #04060c; background: var(--warn);
  border-block-end: 1px solid color-mix(in srgb, var(--warn) 60%, #000);
}
.actas-bar b { font-weight: 800; }
.actas-bar .btn { background: rgba(0,0,0,.14); border-color: rgba(0,0,0,.25); color: #04060c; }
.actas-bar .btn:hover:not(:disabled) { background: rgba(0,0,0,.22); }

/* ---------- time tracking (ticket detail) ---------- */
.timelog { display: grid; gap: .6rem; margin-block: 1rem; }
.timelist { display: grid; gap: .4rem; }
.timelist li {
  display: flex; align-items: center; gap: .6rem; flex-wrap: wrap;
  padding: .5rem .7rem; border: 1px solid var(--line-soft); border-radius: var(--r-sm);
  background: var(--surface); font-size: .84rem;
}
.timelist li b { color: var(--c1); }
.timelist li span:nth-of-type(1) { flex: 1; min-width: 0; }
.timeadd { display: grid; grid-template-columns: 90px 1fr auto; gap: .5rem; align-items: end; }
@media (max-width: 560px) { .timeadd { grid-template-columns: 1fr; } }

/* ---------- working-hours / holiday settings ---------- */
/* direction pinned so the day pills always read Saturday→Friday (right to left)
   regardless of any inherited direction on the container. */
.daypick { display: flex; direction: rtl; gap: .4rem; flex-wrap: wrap; }
.daypick label {
  display: inline-flex; align-items: center; gap: .35rem; cursor: pointer;
  padding: .4rem .8rem; border: 1px solid var(--line); border-radius: 999px;
  font-size: .84rem; user-select: none;
}
.daypick input { width: auto; }
.holidaytable td { vertical-align: middle; }
.holidaytable .off { color: var(--faint); font-size: .78rem; }

/* ---------- location map picker ---------- */
.mappick {
  position: relative; width: 100%; height: 280px; overflow: hidden; cursor: grab;
  border: 1px solid var(--line); border-radius: var(--r-sm); background: var(--bg-3);
  touch-action: none; user-select: none;
}
.mappick.drag { cursor: grabbing; }
.mappick__layer { position: absolute; inset: 0; }
.mappick__layer img { position: absolute; width: 256px; height: 256px; pointer-events: none; }
/* A fixed pin at the centre — the map pans under it, so the centre is the chosen point. */
.mappick__pin {
  position: absolute; inset-block-start: 50%; inset-inline-start: 50%;
  width: 22px; height: 22px; margin-inline-start: -11px; margin-block-start: -22px;
  pointer-events: none; z-index: 3;
  color: var(--bad); filter: drop-shadow(0 2px 2px rgba(0,0,0,.4));
}
.mappick__zoom {
  position: absolute; inset-block-start: .5rem; inset-inline-start: .5rem; z-index: 4;
  display: grid; gap: .25rem;
}
.mappick__zoom button {
  width: 32px; height: 32px; border-radius: 8px; cursor: pointer; font-size: 1.1rem; font-weight: 700;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text); display: grid; place-items: center;
}
.mappick__attr {
  position: absolute; inset-block-end: 0; inset-inline-end: 0; z-index: 4;
  font-size: .62rem; background: rgba(0,0,0,.5); color: #fff; padding: .1rem .35rem; border-start-start-radius: 6px;
}
.mappick__search {
  position: absolute; inset-block-start: .5rem; inset-inline-end: .5rem; z-index: 5; width: min(260px, 62%);
}
.mappick__search input {
  width: 100%; padding: .45rem .7rem; border-radius: 8px; font-size: .84rem;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
}
.mappick__results {
  margin-block-start: .25rem; background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; max-height: 190px; overflow-y: auto; box-shadow: var(--shadow);
}
.mappick__results button {
  display: block; width: 100%; text-align: start; padding: .5rem .7rem; cursor: pointer;
  border: none; border-block-end: 1px solid var(--line-soft); background: transparent; color: var(--text);
  font-size: .8rem; line-height: 1.5;
}
.mappick__results button:hover { background: var(--surface-2); }
.mappick__none { padding: .5rem .7rem; font-size: .8rem; color: var(--faint); }

/* ---------- monthly report ---------- */
.monthbar { display: flex; gap: .6rem; align-items: end; flex-wrap: wrap; margin-block-end: 1rem; }

/* ---------- SLA panel ---------- */
.metrics { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: .8rem; }
.metric { padding: .95rem 1.1rem; border: 1px solid var(--line); border-radius: var(--r); background: var(--surface); }
.metric b { display: block; font-size: 1.5rem; font-weight: 800; line-height: 1.3; }
.metric span { color: var(--muted); font-size: .8rem; }
.metric--bad b { color: var(--bad); }
.metric--ok b { color: var(--ok); }

/* ============================================================
   responsive — shared across the login page, the customer portal
   and the support desk

   The CRM is used from three quite different places: a technician at a desk,
   the CEO on a laptop, and a customer filing a request from their phone while
   standing next to the broken machine. Only the first of those was ever
   designed for, so the rules below are about the other two.
   ============================================================ */

/* Tablets and small laptops. */
@media (max-width: 900px) {
  .wrap { width: calc(100% - 2rem); margin-block: 1.4rem 3rem; }
  .top__in { width: calc(100% - 2rem); }
  .panel { padding: 1.2rem; border-radius: var(--r); }
}

/* The header carries a brand, up to seven Persian tab labels and an account
   block. They stop fitting one line long before the page content does — at
   768px the tabs were wrapping and pushing the brand onto three lines — so the
   header gets its own, earlier breakpoint: identity on top, tabs underneath as
   a single strip that scrolls sideways. */
@media (max-width: 900px) {
  .top__in {
    height: auto; flex-wrap: wrap; padding-block: .6rem;
    row-gap: .2rem;
  }
  .tabs {
    order: 3; width: 100%; margin-inline-start: 0;
    overflow-x: auto; padding-block-end: .3rem;
    scrollbar-width: none;                       /* the strip is short; a bar
                                                    under it just adds noise */
    -webkit-overflow-scrolling: touch;
  }
  .tabs::-webkit-scrollbar { display: none; }
  .tabs button { flex: none; white-space: nowrap; }

  .brand b { font-size: .9rem; white-space: nowrap; }
  .brand i { display: none; }
  .who { gap: .4rem; }
  .who__name b { font-size: .84rem; white-space: nowrap; }
  .who__name span { display: none; }
}

@media (max-width: 700px) {
  /* Two-up field rows stop being readable well before this width. */
  .row { grid-template-columns: 1fr; }

  /* 16px is the threshold below which iOS Safari zooms the page in when a
     field takes focus, then leaves the reader stranded at that zoom level. */
  .field input, .field select, .field textarea, .ov__box input { font-size: 16px; }

  .panel__h { gap: .6rem; }
  .panel__h h2 { font-size: 1.02rem; }

  /* Comfortable thumb targets. */
  .btn { padding: .8rem 1.3rem; }
  .btn--sm { padding: .55rem 1rem; }
  .icon-btn { width: 42px; height: 42px; }

  .ov { padding: 1rem; }
  .ov__box { padding: 1.3rem; }
  .ov__actions { flex-direction: column-reverse; }   /* confirm nearest the thumb */
  .ov__actions .btn { width: 100%; }

  /* A centred dialog sits behind the on-screen keyboard, so it becomes a sheet
     anchored to the bottom edge where a thumb can reach it. */
  .dlg { padding: 0; align-items: end; }
  .dlg__box {
    width: 100%; max-height: 92svh; border-radius: var(--r-lg) var(--r-lg) 0 0;
    padding: 1.3rem; animation: sheet .3s var(--ease);
  }
  @keyframes sheet { from { transform: translateY(100%); } }

  #toast { inset-inline: 1rem; inset-block-end: 1rem; translate: none; }
  .toast { width: 100%; text-align: center; }

  .atts { gap: .4rem; }
  .att { padding: .45rem .55rem; gap: .55rem; }
  .att__thumb, .att__ic { width: 40px; height: 40px; }

  .metrics { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: .6rem; }
  .metric { padding: .8rem .9rem; }
  .metric b { font-size: 1.3rem; }

  .empty { padding: 2.5rem .5rem; }
}

@media (max-width: 420px) {
  .wrap { width: calc(100% - 1.4rem); }
  .top__in { width: calc(100% - 1.4rem); }
  .panel { padding: 1rem; }
  .metrics { grid-template-columns: 1fr 1fr; }
  .rate-pick label { font-size: 1.5rem; }
}

/* ============================================================
   Instructions ("راهنما") tab — the role-scoped guide from helpHtml().
   ============================================================ */
.help__intro { color: var(--muted); margin-block-end: 1.2rem; max-width: 70ch; }
.help__test {
  background: rgba(255,193,77,.12); border: 1px solid rgba(255,193,77,.4);
  color: var(--text); border-radius: var(--r-sm);
  padding: .75rem 1rem; margin-block-end: 1.2rem; font-size: .92rem;
}
/* One column, not a masonry of tiles. The sections are collapsed by default, so
   what the reader sees first is a list of headings — a table of contents — and
   several columns of those scan far worse than one. */
.help__grid { display: grid; gap: .6rem; align-items: start; }

/* ---------- نظرسنجی: the 1–10 scale ----------
   Ten buttons rather than a dropdown, so the whole scale is visible and
   answering is one tap. They wrap on a narrow screen rather than shrinking to
   unreadable, and the row scrolls only as a last resort. */
/* The bundled brand mark, painted from its alpha mask in the current text
   colour — dark on the light theme, light on the dark one, from a single asset
   and with no white box behind it. An uploaded logo renders as a normal <img>
   instead and keeps its own colours. */
.brand-mark {
  display: block; inline-size: 100%; block-size: 100%;
  background-color: currentColor;
  -webkit-mask: url('/assets/logo-mask.png') center / contain no-repeat;
          mask: url('/assets/logo-mask.png') center / contain no-repeat;
}

.poll-scale { display: flex; gap: .35rem; flex-wrap: wrap; }
.poll-dot {
  inline-size: 2.4rem; block-size: 2.4rem; flex: none;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--surface); color: var(--muted);
  font: inherit; font-size: .88rem; cursor: pointer;
  transition: .18s var(--ease);
}
.poll-dot:hover { border-color: color-mix(in srgb, var(--c1) 50%, transparent); color: var(--text); }
.poll-dot.on {
  background: var(--c1); border-color: var(--c1); color: #fff; font-weight: 700;
}
.poll-dot:focus-visible { outline: 2px solid var(--c1); outline-offset: 2px; }
.poll-ends {
  display: flex; justify-content: space-between;
  font-size: .74rem; color: var(--faint); margin-block-start: .35rem;
}
@media (max-width: 480px) {
  .poll-dot { inline-size: 2.1rem; block-size: 2.1rem; font-size: .8rem; }
}

/* Tabs across the role guides. */
.help__tabs { display: flex; gap: .3rem; flex-wrap: wrap; margin-block-end: 1.1rem; }
.help__tabs button {
  padding: .4rem .9rem; border-radius: 999px; cursor: pointer; font: inherit; font-size: .84rem;
  border: 1px solid var(--line); background: transparent; color: var(--muted); transition: .25s;
}
.help__tabs button:hover { color: var(--text); }
.help__tabs button.on { background: var(--surface-2); color: var(--text); border-color: var(--line); }

.help__card {
  background: var(--surface); border: 1px solid var(--line-soft);
  border-radius: var(--r); padding: 1.1rem 1.2rem;
}
/* The heading is now the <summary>, which has to look and behave like one:
   clickable across its whole width, with a marker that turns as it opens. */
.help__card > summary {
  font-size: 1rem; font-weight: 700; color: var(--c1); cursor: pointer;
  list-style: none; display: flex; align-items: center; gap: .55rem;
}
.help__card > summary::-webkit-details-marker { display: none; }
.help__card > summary::before {
  content: '';
  width: .5rem; height: .5rem; flex: none;
  border-inline-end: 2px solid currentColor; border-block-end: 2px solid currentColor;
  transform: rotate(-45deg);          /* points into the text in RTL: ‹ */
  transition: transform .2s var(--ease);
}
.help__card[open] > summary::before { transform: rotate(45deg); }
.help__card[open] > summary {
  margin-block-end: .7rem; padding-block-end: .55rem;
  border-block-end: 1px solid var(--line-soft);
}
.help__card > summary:focus-visible { outline: 2px solid var(--c1); outline-offset: 3px; border-radius: 4px; }
.help__steps { list-style: decimal; padding-inline-start: 1.3rem; display: grid; gap: .5rem; }
.help__steps li { line-height: 1.75; font-size: .93rem; }
.help__steps b { font-weight: 700; }
.help__foot { color: var(--faint); font-size: .88rem; margin-block-start: 1.4rem; }

.help__card--note p { line-height: 1.75; font-size: .93rem; margin-block-end: .6rem; }
.help__card--note p:last-child { margin-block-end: 0; }
.help__list { list-style: disc; padding-inline-start: 1.3rem; display: grid; gap: .5rem; margin: 0; }
.help__list li { line-height: 1.75; font-size: .93rem; }
.help__list b { font-weight: 700; }
.help__deflist { display: grid; grid-template-columns: max-content 1fr; gap: .35rem 1rem; margin: 0 0 .8rem; }
.help__deflist dt { font-weight: 700; color: var(--c1); white-space: nowrap; }
.help__deflist dd { margin: 0; line-height: 1.7; font-size: .92rem; color: var(--muted); }
.help__tip {
  background: var(--surface-2); border-radius: var(--r-sm);
  padding: .6rem .8rem; font-size: .87rem; color: var(--muted); margin: 0;
}

/* Any table wide enough to need it scrolls inside its own box rather than
   pushing the page sideways. Applied to the wrapper the pages already use. */
.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.table-wrap table { min-width: 560px; }

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ============================================================
   Staging banner (CRM_TEST_MODE=1). A fixed 30px strip across the top of every
   page of the test instance. Because it overlays the viewport top, the sticky
   headers/sidebar/detail that sit at top:0 are pushed down by exactly its
   height; the high-specificity html.has-test-banner rules win over the base and
   the mobile-drawer rules regardless of source order. Zero footprint on
   production, where the html class is never added.
   ============================================================ */
#testBanner {
  position: fixed; inset-block-start: 0; inset-inline: 0; z-index: 200;
  height: 30px; display: flex; align-items: center; justify-content: center;
  padding-inline: 1rem; box-sizing: border-box;
  font-size: .78rem; font-weight: 700; letter-spacing: .01em;
  color: #201400; text-align: center; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
  background: repeating-linear-gradient(45deg, #ffc14d, #ffc14d 14px, #f4ad2e 14px, #f4ad2e 28px);
  border-block-end: 1px solid rgba(0,0,0,.35);
}
html.has-test-banner body { padding-block-start: 30px; }
html.has-test-banner { scroll-padding-block-start: 30px; }
html.has-test-banner .top,
html.has-test-banner .side,
html.has-test-banner .actas-bar,
html.has-test-banner .detail { inset-block-start: 30px; }
html.has-test-banner .side { height: calc(100vh - 30px); }
html.has-test-banner .app { min-height: calc(100vh - 30px); }
