/* اوميكسوس — الفني · iOS design, one stylesheet for the iPhone shell, the
   Android build and the browser (docs/2026-09-22-ios-redesign.md).
   Every colour is a token with a light and a dark value; the html element
   carries .dark when the dark set is in force (app.js decides from the
   picker and the phone). Light is the default. Content surfaces carry no
   shadow; glass (blur) is for the bars that float over content only. */
:root{
  color-scheme:light;
  --bg:#F2F2F7;--card:#FFFFFF;--card2:#F2F2F7;
  --fill:rgba(120,120,128,.12);--fill2:rgba(120,120,128,.2);
  --ink:#000000;--muted:rgba(60,60,67,.6);--faint:rgba(60,60,67,.3);--hair:rgba(60,60,67,.29);
  --accent:#0077C8;--accent2:#005FA3;--accent-ink:#0077C8;--accent-soft:rgba(0,119,200,.12);
  --accent-grad:var(--accent);
  --on-accent:#FFFFFF;--on-red:#FFFFFF;
  --accent-glow-wide:rgba(0,119,200,.35);
  --green:#34C759;--green-soft:rgba(52,199,89,.16);--green-halo:rgba(52,199,89,.22);--ok:#1F7A35;
  --red:#FF3B30;--red-soft:rgba(255,59,48,.12);--red-glow:rgba(255,59,48,.3);--red-halo:rgba(255,59,48,.35);
  --amber:#FF9500;--amber-soft:rgba(255,149,0,.14);--amber-ink:#B25E00;--teal:#1f9d8f;
  --shadow:none;
  --shadow-lg:0 20px 60px rgba(0,0,0,.28);
  --sheet-shadow:0 -6px 30px rgba(0,0,0,.12);
  --seg-on:#FFFFFF;--seg-shadow:0 3px 8px rgba(0,0,0,.12),0 3px 1px rgba(0,0,0,.04);
  --glass:rgba(249,249,249,.8);--tabs-bg:rgba(249,249,249,.78);--glass-edge:rgba(255,255,255,.6);
  --scrim:rgba(0,0,0,.4);--alarm-scrim:rgba(0,0,0,.45);
  --sheet-grip:rgba(60,60,67,.3);
  --toast-bg:rgba(28,28,30,.92);--toast-ink:#FFFFFF;
  --empty-ic:rgba(60,60,67,.3);--ghost-line:rgba(60,60,67,.29);
  --sw-off:#E9E9EA;--sw-knob:#FFFFFF;--sw-knob-shadow:0 3px 8px rgba(0,0,0,.15),0 1px 1px rgba(0,0,0,.16);
  --bub-shadow:none;
  --bub-in:#E9E9EB;--bub-in-ink:#000000;--bub-in-meta:rgba(60,60,67,.6);
  --bub-out:#0077C8;--bub-out-tail:#0077C8;--bub-out-ink:#FFFFFF;--bub-out-meta:rgba(255,255,255,.78);
  --bub-peer:#F2F2F7;--bub-peer-ink:#000000;--bub-peer-line:rgba(60,60,67,.2);
  --bub-div:rgba(120,120,128,.12);
  --quote-bg:rgba(0,0,0,.05);--quote-ink:rgba(60,60,67,.7);--quote-me-bg:rgba(255,255,255,.18);--quote-me-line:rgba(255,255,255,.85);
  --link-in:#0077C8;--link-out:#FFFFFF;--orig-line:rgba(0,0,0,.14);
  --file-chip:rgba(0,0,0,.07);--file-chip-me:rgba(255,255,255,.2);
  --tick:rgba(255,255,255,.75);--tick-read:#9BEBFF;--tick-fail:#FFD1CE;
  --media-ph:rgba(0,0,0,.06);
  --media-scrim:rgba(0,0,0,.42);--media-scrim-strong:rgba(0,0,0,.5);--media-ink:#FFFFFF;
  --spin-track:rgba(255,255,255,.5);--spin-head:#FFFFFF;
  --vn-av:rgba(120,120,128,.3);--vn-av-me:rgba(255,255,255,.28);
  --vn-mic-bg:#FFFFFF;--vn-mic-shadow:0 1px 3px rgba(0,0,0,.2);
  --vn-play:#0077C8;--vn-play-me:#FFFFFF;
  --vn-bars:rgba(60,60,67,.35);--vn-bars-me:rgba(255,255,255,.5);--vn-played:#0077C8;--vn-played-me:#FFFFFF;
  --vn-knob:#0077C8;--vn-knob-me:#FFFFFF;--vn-knob-shadow:0 1px 3px rgba(0,0,0,.3);
  --vn-foot:rgba(60,60,67,.6);--vn-foot-me:rgba(255,255,255,.78);
  --vn-rate:rgba(0,0,0,.07);--vn-rate-ink:rgba(60,60,67,.8);
  --vn-rate-me:rgba(255,255,255,.22);--vn-rate-ink-me:#FFFFFF;
  /* The case disc: one flat system colour each, all dark enough for white
     12px bold (5:1 and up). Same values in the dark set. */
  --tone-new:#0077C8;--tone-arch:#6E6E73;--tone-late:#D70015;--tone-warr:#C93400;--tone-shop:#8944AB;--tone-back:#1F7A35;
  --shop-tag:#8944AB;
  --tab-h:58px;--nav-h:44px;--r:16px;
}
:root.dark{
  color-scheme:dark;
  --bg:#000000;--card:#1C1C1E;--card2:#2C2C2E;
  --fill:rgba(120,120,128,.24);--fill2:rgba(120,120,128,.32);
  --ink:#FFFFFF;--muted:rgba(235,235,245,.6);--faint:rgba(235,235,245,.3);--hair:rgba(84,84,88,.65);
  --accent:#38BDF8;--accent2:#0EA5E9;--accent-ink:#38BDF8;--accent-soft:rgba(56,189,248,.18);
  --on-accent:#0B1A2B;--on-red:#FFFFFF;
  --accent-glow-wide:rgba(56,189,248,.35);
  --green:#30D158;--green-soft:rgba(48,209,88,.18);--green-halo:rgba(48,209,88,.24);--ok:#30D158;
  --red:#FF453A;--red-soft:rgba(255,69,58,.16);--red-glow:rgba(255,69,58,.3);--red-halo:rgba(255,69,58,.35);
  --amber:#FF9F0A;--amber-soft:rgba(255,159,10,.16);--amber-ink:#FF9F0A;--teal:#1f9d8f;
  --shadow-lg:0 20px 60px rgba(0,0,0,.6);
  --sheet-shadow:0 -6px 30px rgba(0,0,0,.5);
  --seg-on:#636366;--seg-shadow:0 3px 8px rgba(0,0,0,.3);
  --glass:rgba(28,28,30,.74);--tabs-bg:rgba(28,28,30,.72);--glass-edge:rgba(255,255,255,.12);
  --scrim:rgba(0,0,0,.55);--alarm-scrim:rgba(0,0,0,.6);
  --sheet-grip:rgba(235,235,245,.3);
  --toast-bg:rgba(44,44,46,.94);--toast-ink:#FFFFFF;
  --empty-ic:rgba(235,235,245,.3);--ghost-line:rgba(84,84,88,.65);
  --sw-off:#39393D;--sw-knob:#FFFFFF;--sw-knob-shadow:0 3px 8px rgba(0,0,0,.4);
  --bub-in:#262629;--bub-in-ink:#FFFFFF;--bub-in-meta:rgba(235,235,245,.6);
  --bub-out:#0B6BC7;--bub-out-tail:#0B6BC7;--bub-out-ink:#FFFFFF;--bub-out-meta:rgba(255,255,255,.78);
  --bub-peer:#2C2C2E;--bub-peer-ink:#FFFFFF;--bub-peer-line:rgba(84,84,88,.65);
  --bub-div:rgba(120,120,128,.24);
  --quote-bg:rgba(255,255,255,.08);--quote-ink:rgba(235,235,245,.75);--quote-me-bg:rgba(0,0,0,.22);--quote-me-line:rgba(255,255,255,.85);
  --link-in:#38BDF8;--link-out:#FFFFFF;--orig-line:rgba(255,255,255,.18);
  --file-chip:rgba(255,255,255,.1);--file-chip-me:rgba(255,255,255,.16);
  --tick:rgba(255,255,255,.7);--tick-read:#9BEBFF;--tick-fail:#FFB4AE;
  --media-ph:rgba(255,255,255,.06);
  --media-scrim:rgba(0,0,0,.5);--media-scrim-strong:rgba(0,0,0,.55);--media-ink:#FFFFFF;
  --spin-track:rgba(255,255,255,.4);--spin-head:#FFFFFF;
  --vn-av:rgba(120,120,128,.35);--vn-av-me:rgba(255,255,255,.22);
  --vn-mic-bg:#1C1C1E;--vn-mic-shadow:0 1px 3px rgba(0,0,0,.5);
  --vn-play:#FFFFFF;--vn-play-me:#FFFFFF;
  --vn-bars:rgba(235,235,245,.35);--vn-bars-me:rgba(255,255,255,.45);--vn-played:#38BDF8;--vn-played-me:#FFFFFF;
  --vn-knob:#38BDF8;--vn-knob-me:#FFFFFF;--vn-knob-shadow:0 1px 3px rgba(0,0,0,.5);
  --vn-foot:rgba(235,235,245,.6);--vn-foot-me:rgba(255,255,255,.78);
  --vn-rate:rgba(255,255,255,.12);--vn-rate-ink:rgba(235,235,245,.8);
  --vn-rate-me:rgba(255,255,255,.18);--vn-rate-ink-me:#FFFFFF;
  --shop-tag:#BF5AF2;
}

/* base */
*{box-sizing:border-box;margin:0;padding:0}
html{background:var(--bg)}html,body{height:100%}
body{background:var(--bg);color:var(--ink);direction:rtl;font-size:17px;line-height:1.35;
  font-family:-apple-system,"SF Pro Text","SF Arabic",system-ui,"Segoe UI",Roboto,"Noto Naskh Arabic UI",sans-serif;
  -webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;overscroll-behavior-y:none}
/* iPhone Safari: no pinch, no double-tap zoom, no zoom on focus (17px inputs) */
html,body{touch-action:manipulation;-webkit-text-size-adjust:100%}
svg{display:block}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
input,select,textarea{font:inherit}
/* Nothing in the app shows a scrollbar; every list still scrolls. */
*{scrollbar-width:none;-ms-overflow-style:none}
*::-webkit-scrollbar{display:none;width:0;height:0}
@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}}

/* shell — no header anywhere: the tab bar says where he is. The top inset is
   the status bar of the native shell (edge to edge); a Home Screen app and
   the Android build sit under an opaque bar and read it as zero. */
.app{max-width:560px;margin:0 auto;min-height:100dvh;display:flex;flex-direction:column}
html.kb-up .app{padding-bottom:var(--kb,0px)}
.screen{flex:1;padding:calc(10px + env(safe-area-inset-top,0px)) 16px calc(var(--tab-h) + 12px + env(safe-area-inset-bottom,0px) + 24px);display:none}
.screen.on{display:block}
.screen.on.rise{animation:rise .22s cubic-bezier(.32,.72,.35,1)}
@keyframes rise{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
/* a number that wants him: the row's unread count, a cut's count, the tab badge (owner, 2026-09-23: «ينبض») */
@keyframes beat{0%,100%{transform:scale(1)}50%{transform:scale(1.22)}}
/* The beat lives on the filter bars only (owner, 2026-09-24): the bar is the summary; rows and tabs beating too was noise. */
.seg .fchip b{animation:beat 1.5s ease-in-out infinite}

/* The inbox opens with its filters — an iOS segmented control stuck to the
   top. Once the list scrolls under it, it turns to glass. */
.filters{position:sticky;top:0;z-index:20;margin:calc(-10px - env(safe-area-inset-top,0px)) -16px 12px;
  padding:calc(8px + env(safe-area-inset-top,0px)) 16px 8px;transition:background .18s,box-shadow .18s}
.app.scrolled .filters{background:var(--glass);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);
  box-shadow:0 1px 0 var(--hair)}
/* the ring's gap reads the bar behind it once the bar is glass */
.app.scrolled .filters .avatar.live{box-shadow:0 0 0 2px transparent,0 0 0 4.5px var(--green)}
.app.scrolled .filters .avatar.off{box-shadow:0 0 0 2px transparent,0 0 0 4.5px var(--red)}
/* The inbox cuts share the chip class the tests know; inside the control
   they are segments and nothing of the chip may leak through. */
.seg .fchip{display:inline-flex;justify-content:center;align-items:center;gap:3px;flex:1;min-height:32px;border-radius:7px;
  background:transparent;color:var(--ink);padding:0 4px;font-size:13px;font-weight:500;white-space:nowrap;box-shadow:none}
.seg .fchip.on{background:var(--seg-on);color:var(--ink);font-weight:600;box-shadow:var(--seg-shadow)}
/* The count is a quiet number beside its word — Apple never badges a
   segment; the red oval belongs to the tab bar alone. */
.seg .fchip b{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:var(--accent);color:var(--on-accent);font-size:11.5px;font-weight:600;margin:0;font-variant-numeric:tabular-nums}
.seg .fchip.on b{background:var(--accent);color:var(--on-accent)}
/* The bar over the cuts: his picture and the search field. */
.sbar{display:flex;align-items:center;gap:10px;margin-bottom:10px}
.avatar.me-av{width:40px;height:40px;font-size:17px;font-weight:600;overflow:hidden;padding:0;cursor:pointer;flex:none}
.avatar.me-av.big{width:48px;height:48px;font-size:20px}
.avatar img{width:100%;height:100%;object-fit:cover;border-radius:50%;display:block}
.search{flex:1;min-width:0;display:flex;align-items:center;gap:6px;background:var(--fill);border-radius:10px;min-height:36px;padding:0 10px;color:var(--muted)}
.search .s-ic svg{width:17px;height:17px;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round}
/* 17px: iPhone Safari zooms into any smaller field */
.search input{flex:1;min-width:0;background:transparent;border:0;outline:none;font-size:17px;color:var(--ink);min-height:36px;padding:0;font-family:inherit;-webkit-appearance:none;appearance:none}
.search input::placeholder{color:var(--faint)}
.search input::-webkit-search-cancel-button,.search input::-webkit-search-decoration{display:none;-webkit-appearance:none}
.search .s-x{width:26px;height:26px;border-radius:50%;background:var(--fill2);color:var(--muted);display:none;place-items:center;flex:none}
.search .s-x svg{width:12px;height:12px}
.search.has .s-x{display:grid}
.arch-row{display:flex;justify-content:center;padding:4px 0 8px}
.arch-link{border-radius:999px;padding:0 16px;min-height:36px;background:var(--fill);color:var(--accent);font-size:15px;font-weight:600}
.arch-link.on{background:var(--accent);color:var(--on-accent)}
/* Offline: the gate that withholds work says so, with the way back. */
.offline{display:flex;align-items:center;justify-content:space-between;gap:10px;background:var(--amber-soft);color:var(--amber-ink);
  border-radius:12px;padding:8px 8px 8px 14px;margin:0 0 12px;font-size:15px;font-weight:600}
.offline button{background:var(--accent);color:var(--on-accent);border-radius:999px;padding:0 14px;min-height:34px;font-weight:600;font-size:15px;flex:none}

/* groups — the inset grouped list of iOS: one surface, hairlines inside */
.card{background:var(--card);border-radius:var(--r);padding:16px;margin-bottom:16px}
h2{font-size:13px;font-weight:600;margin:0 0 10px;color:var(--muted)}
.hint{font-size:13px;color:var(--muted);line-height:1.5}

/* inbox filters: one scrollable row of capsules, the active one tinted */
.fchips{display:flex;gap:8px;overflow-x:auto;padding:2px 0 12px;margin:0}
.fchip{flex:none;display:inline-flex;align-items:center;gap:6px;white-space:nowrap;border-radius:999px;padding:0 14px;min-height:34px;
  font-size:15px;font-weight:500;background:var(--fill);color:var(--ink);transition:background .15s,color .15s}
.fchip b{font-weight:600;font-variant-numeric:tabular-nums}
.fchip.on{background:var(--accent);color:var(--on-accent)}
.fchips.inline{padding:0 0 12px;margin:0}
/* The period belongs beside the word it qualifies, not on a line of its own. */
.card-head{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-bottom:12px}
.card-head h2{margin:0;flex:none}
.card-head .fchips.inline{padding:0;margin:0;flex:1;justify-content:flex-end}
.card-head .fchip{min-height:28px;padding:0 11px;font-size:13px}

/* chat list: one card per conversation, air between them (owner's call:
   «مفصلة»), the case disc as the one signature */
.chat-list{display:flex;flex-direction:column;gap:10px;margin-bottom:12px}
.chat-list .card{margin:0}
.chat-wrap{position:relative;overflow:hidden;border-radius:var(--r)}
.chat-list > .chat-row{border-radius:var(--r)}
/* The panels a swipe reveals under the row: archive behind the row's start
   (a drag to the left), the call behind its end (a drag to the right). */
.chat-under{position:absolute;inset:0;display:flex;align-items:center;gap:8px;padding:0 20px;
  color:#fff;font-size:13px;font-weight:600;opacity:0;transition:opacity .12s}
.chat-under.arch{justify-content:flex-start;background:var(--tone-arch)}
.chat-under.call{justify-content:flex-end;background:var(--green)}
.chat-wrap.swipe-on.dir-l .chat-under.arch,.chat-wrap.swipe-on.dir-r .chat-under.call{opacity:1}
.chat-under svg{width:22px;height:22px;stroke:currentColor;fill:none}
.chat-row.swiping{transition:none}
.chat-row{position:relative;touch-action:pan-y;display:flex;gap:12px;align-items:center;padding:12px 16px;min-height:44px;cursor:pointer;
  background:var(--card);transition:background .15s,scale .15s;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
/* today's appointment on the row, red once its time has passed */
.ap-chip{font-size:12px;font-weight:600;color:var(--accent-ink);background:var(--accent-soft);border-radius:999px;padding:3px 9px;white-space:nowrap;font-variant-numeric:tabular-nums}
.ap-chip.late{color:var(--red);background:var(--red-soft)}
/* a press gives a little under the finger; `scale` leaves the swipe's transform alone */
.chat-row:active{background:var(--card2);scale:.985}
.need-row{transition:scale .15s}.need-row:active{scale:.985}
@media (prefers-reduced-motion:reduce){.chat-row:active,.need-row:active{scale:1}}
.avatar{width:44px;height:44px;border-radius:50%;flex:none;display:grid;place-items:center;font-weight:600;font-size:17px;
  background:var(--tone-new);color:#fff;position:relative}
.avatar.word{font-size:12px;font-weight:700}
/* The technician: his picture or his name, and a ring that says whether
   jobs reach him — green on, red off. A shadow, not a child: the circle
   clips its children for the picture. */
.avatar.big{width:48px;height:48px;font-size:20px;font-weight:600}
.avatar.live{box-shadow:0 0 0 2px var(--bg),0 0 0 4.5px var(--green)}
.avatar.off{box-shadow:0 0 0 2px var(--bg),0 0 0 4.5px var(--red)}
.card .avatar.live{box-shadow:0 0 0 2px var(--card),0 0 0 4.5px var(--green)}
.card .avatar.off{box-shadow:0 0 0 2px var(--card),0 0 0 4.5px var(--red)}
.avatar .nm-s{font-size:11px;font-weight:700;letter-spacing:-.2px;line-height:1}
.avatar.big .nm-s{font-size:13px}
.card.profile{padding:12px 16px}
.avatar.arch{background:var(--tone-arch)}
.avatar.late{background:var(--tone-late)}
.avatar.warr{background:var(--tone-warr)}
.avatar.shop{background:var(--tone-shop)}
.avatar.back{background:var(--tone-back)}
/* The owner is on this customer: the technician must not walk past it. */
.avatar.word.esc{background:var(--tone-late)}
/* The escalated disc breathes through a ring that only scales and fades: a box-shadow
   animation repaints every escalated row on every frame. */
.avatar.word.esc::after{content:'';position:absolute;inset:0;border-radius:50%;box-shadow:0 0 0 6px var(--red-halo);pointer-events:none;
  animation:escpulse 1.5s ease-in-out infinite}
@keyframes escpulse{0%{opacity:1;transform:scale(.92)}55%,100%{opacity:0;transform:scale(1.18)}}
.chat-mid{flex:1;min-width:0}
/* name line: the name, then today's appointment or the wait at its end */
.chat-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.chat-name{flex:1;min-width:0;font-weight:600;font-size:17px;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chat-dev{margin-top:1px;font-size:15px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chat-dev .dev{display:inline;max-width:100%;font-size:15px;color:var(--muted);font-weight:400;background:none;padding:0}
/* message line: the last line, the clock at its end on every row */
.chat-last{display:flex;align-items:baseline;justify-content:space-between;gap:8px;font-size:15px;color:var(--muted);margin-top:1px}
.chat-last .txt{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.chat-time{flex:none;font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
.pin-mark{flex:none;display:inline-flex;color:var(--muted);margin-inline-end:4px}.pin-mark svg{width:14px;height:14px}
/* the unread count on the disc's corner, ringed so it reads on any disc colour */
.av-wrap{position:relative;flex:none}
.badge{position:absolute;top:-5px;inset-inline-start:-7px;min-width:20px;height:20px;border-radius:10px;background:var(--accent);color:var(--on-accent);font-size:12px;font-weight:600;
  display:grid;place-items:center;padding:0 6px;font-variant-numeric:tabular-nums;box-shadow:0 0 0 2px var(--card)}
.cap-card .empty{color:var(--amber-ink)}
.wait-tag{font-size:12px;font-weight:600;color:var(--amber-ink);background:var(--amber-soft);border-radius:999px;padding:3px 9px;white-space:nowrap}
/* The SLA: half an hour unanswered is an amber edge, an hour a red one */
.chat-row.sla-warn::before,.chat-row.sla-bad::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;width:4px;background:var(--amber)}
.chat-row.sla-bad::before{background:var(--red)}
.wait-tag.sla-warn,.wait-tag.sla-bad{font-weight:700}
.wait-tag.sla-bad{color:var(--red);background:var(--red-soft)}
.chat-side .amt{font-weight:600;color:var(--ok);font-size:15px;font-variant-numeric:tabular-nums}
.chat-side .amt.zero{color:var(--faint);font-weight:400}
.chip-call{display:inline-block;font-size:12px;font-weight:600;padding:1px 8px;border-radius:999px;background:var(--accent);color:var(--on-accent);margin-inline-end:6px;vertical-align:middle}
.chip-tech{display:inline-block;font-size:12px;font-weight:600;padding:1px 8px;border-radius:999px;background:var(--fill);color:var(--muted);margin-inline-end:6px;vertical-align:middle}
/* The customer's number, under his name in the inbox and in the thread, and
   on its own line on an unclaimed card for the owner's board. Who receives the
   number at all is the server's decision (ADR-004 and the owner's scrub
   switch); this only shows what was sent. */

/* thread */
/* The bottom edge follows the keyboard (--kb, set by the shell's will-show
   event) on the iPhone keyboard's own curve; the strip it uncovers while
   rising is painted in the composer's colour so the keyboard slides over
   white, not over the page; and while the keyboard is up the home-indicator
   padding folds away — the keyboard sits where the indicator was. */
html.kb-anim .thread{transition:bottom .25s cubic-bezier(.38,.7,.125,1)}
.thread::after{content:'';position:absolute;inset-inline:0;top:100%;height:var(--kb,0px);background:var(--card);pointer-events:none}
html.kb-anim .composer{transition:padding-bottom .25s cubic-bezier(.38,.7,.125,1)}
html.kb-up .composer{padding-bottom:8px}
.thread{position:fixed;top:0;inset-inline:0;bottom:var(--kb,0px);background:var(--card);z-index:50;display:none;flex-direction:column;max-width:560px;margin:0 auto}
.thread.on{display:flex;animation:slidein .26s cubic-bezier(.32,.72,.35,1)}
@keyframes slidein{from{transform:translateX(-28px);opacity:.4}to{transform:none;opacity:1}}
.th-top{display:flex;align-items:center;gap:8px;padding:calc(6px + env(safe-area-inset-top,0px)) 8px 6px 12px;min-height:calc(var(--nav-h) + 8px);
  background:var(--glass);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);border-bottom:1px solid var(--hair)}
.th-back{width:44px;height:44px;display:grid;place-items:center;border-radius:50%;color:var(--accent);flex:none}
.th-back svg{width:26px;height:26px}
.th-back:active{opacity:.5}
/* The name is a button: the customer's card is one tap away. */
.th-info{flex:1;min-width:0;display:flex;align-items:center;gap:10px;text-align:start;padding:2px 4px 2px 0;border-radius:12px;color:inherit}
.th-info:active{opacity:.55}
.th-text{flex:1;min-width:0}
/* The job's state under the name: only when there is something to say. */
.th-state{display:flex;gap:6px;padding:6px 16px 8px;overflow-x:auto;scrollbar-width:none;background:var(--card);border-bottom:1px solid var(--hair)}
.th-state::-webkit-scrollbar{display:none}
/* The owner's escalation: the complaint at the top of the thread, and on the row. */
.esc-banner{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:8px 16px;background:var(--red-soft);border-bottom:1px solid var(--hair)}
.esc-h{display:flex;flex-wrap:wrap;gap:8px;font-size:13px;color:var(--muted)}
.esc-h b{color:var(--red);font-weight:700}
button.esc-h{inline-size:100%;align-items:center;background:none;border:0;padding:0;font:inherit;font-size:13px;color:var(--muted);text-align:start;cursor:pointer;min-block-size:32px}
.esc-chev{margin-inline-start:auto;display:inline-flex;transition:transform .2s}
.esc-chev svg{inline-size:18px;block-size:18px}
.esc-banner.open .esc-chev{transform:rotate(180deg)}
.esc-banner:not(.open){gap:2px;padding-block:6px}
.esc-banner:not(.open) .esc-t{display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical;overflow:hidden;white-space:normal;max-block-size:none;font-size:14px}
.esc-banner:not(.open) .act-btn{display:none}
.esc-t{font-size:15px;line-height:1.45;white-space:pre-line;overflow-wrap:anywhere;max-block-size:30vh;overflow-y:auto}
.esc-sheet .esc-banner{border-radius:14px;border-bottom:0;margin-block-end:8px}
.esc-sheet .esc-t{max-block-size:18vh}
.esc-sheet .jp-msgs{max-block-size:38vh;margin-block-end:8px}
.esc-sheet .arch-acts{margin-block-start:12px}
.esc-sheet .arch-acts .act-btn{text-decoration:none;min-height:44px}.field textarea{resize:none;font:inherit;line-height:1.45}
.esc-line{display:flex;align-items:baseline;gap:6px;font-size:14px;color:var(--red);margin-top:1px;min-width:0}
.esc-line b{flex:none;font-weight:700}
.esc-line span{flex:none}
.esc-line .txt{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.st-chip{flex:none;font-size:12px;font-weight:600;border-radius:999px;padding:3px 9px;white-space:nowrap;background:var(--fill);color:var(--muted);font-variant-numeric:tabular-nums}
.st-chip.acc{background:var(--accent-soft);color:var(--accent-ink)}
.st-chip.warn{background:var(--amber-soft);color:var(--amber-ink)}
.st-chip.bad{background:var(--red-soft);color:var(--red)}
.st-chip.shop{color:var(--shop-tag)}
.th-name{font-weight:600;font-size:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.th-meta{font-size:12px;color:var(--muted);margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.th-top .avatar{width:36px;height:36px;font-size:11px}
/* A filled disc so the call reads as a button, not a decoration. */
.th-call{width:36px;height:36px;flex:none;display:grid;place-items:center;border-radius:50%;
  background:var(--accent-soft);color:var(--accent);transition:transform .12s}
.th-call svg{width:18px;height:18px}
.th-call:active{transform:scale(.92)}
.th-msgs{flex:1;touch-action:pan-y;overflow-y:auto;overflow-x:hidden;padding:12px 16px 10px;display:flex;flex-direction:column;gap:0}
.thread.loading .th-msgs::after{content:"جاري تحميل المحادثة...";display:block;text-align:center;font-size:13px;color:var(--muted);padding:12px}
/* Bubble geometry: consecutive bubbles from one side are one run — the first
   wears the tail, the rest sit 2px under it, a new run opens with 8px */
/* Nothing in a bubble is the phone's to select, drag or preview: a long press
   on a photo lifted it with iOS's «+» badge and a blue tint (owner, 2026-09-24). */
.bub,.bub .ph,.bub .ph img,.bub .ph video,.bub a{-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;-webkit-user-drag:none}
.bub{position:relative;touch-action:pan-y;overflow-wrap:anywhere;max-width:78%;min-width:72px;border-radius:18px;padding:8px 12px 9px;font-size:17px;line-height:1.35;margin:8px 0 0;border:0}
.bub.cont{margin-top:2px}
.bub.has-media.cont{margin-top:6px}
.bub.cust{align-self:flex-start;background:var(--bub-in);color:var(--bub-in-ink)}
.bub.me{align-self:flex-end;background:var(--bub-out);color:var(--bub-out-ink)}
.bub.cust:not(.cont),.bub.peer:not(.cont){border-end-start-radius:4px}
.bub.me:not(.cont),.bub.bot:not(.cont){border-end-end-radius:4px}
/* the tail is a real wedge, masked out of the bubble's own colour */
.bub::after{content:"";position:absolute;bottom:0;width:10px;height:14px;pointer-events:none;
  --tail:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 14'%3E%3Cpath d='M0 0L0 14L10 14Q2 11 0 0Z' fill='%23000'/%3E%3C/svg%3E");
  -webkit-mask:var(--tail) no-repeat 0 0/100% 100%;mask:var(--tail) no-repeat 0 0/100% 100%}
.bub.cust::after{inset-inline-start:-9px;background:var(--bub-in)}
.bub.peer::after{inset-inline-start:-9px;background:var(--bub-peer)}
.bub.me::after{inset-inline-end:-9px;transform:scaleX(-1);background:var(--bub-out-tail)}
.bub.bot::after{inset-inline-end:-9px;transform:scaleX(-1);background:var(--card2)}
.bub.cont::after,.bub.div::after{display:none}
/* a browser without masking would draw the tail as a bare rectangle */
@supports not ((-webkit-mask-image:none) or (mask-image:none)){.bub::after{display:none}}
/* the time and the ticks ride the end of the last line, and take a line of
   their own only when that line has no room for them */
.bub .t{float:inline-end;margin-inline-start:9px;margin-block-start:4px;position:relative;top:3px;
  font-size:11px;line-height:1;white-space:nowrap;color:var(--bub-in-meta);font-variant-numeric:tabular-nums}
/* over a picture the clock is an overlay, not part of any line */
.bub.has-media .t{float:none;position:absolute;inset-block-end:6px;inset-inline-end:11px;margin:0;top:auto}
.bub.me .t{color:var(--bub-out-meta)}
.mspace{display:inline-block;width:44px;height:1px}
.bub:not(.has-media) .mspace{display:none}
.bub.me .mspace{width:68px}
.bub.bot .mspace{width:46px}
.bub.has-orig{padding-bottom:22px}
/* The quoted line: a bar down its leading edge, the author over the words. */
.bub .q{display:block;border-inline-start:3px solid var(--accent);border-radius:8px;background:var(--quote-bg);
  padding:6px 9px;margin:0 0 6px;font-size:14px;line-height:1.35;overflow:hidden}
.bub .q b{display:block;font-size:12px;font-weight:600;color:var(--accent-ink);margin-bottom:1px}
.bub .q span{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;color:var(--quote-ink)}
.bub.me .q{border-inline-start-color:var(--quote-me-line);background:var(--quote-me-bg)}
.bub.me .q b{color:var(--quote-me-line)}
.bub.me .q span{color:var(--bub-out-ink);opacity:.9}
/* Dragged toward the reply; it springs back the moment the finger leaves. */
.bub.rswipe{transition:none;will-change:transform;-webkit-user-select:none;user-select:none}
/* Until it is playing the frame is the round button's; the finger that lands
   anywhere else on it is answering the line, not driving the player. */
.bub .ph.vid:not(.on) video{pointer-events:none}
.bub.rgo{box-shadow:0 0 0 2px var(--accent-glow-wide)}
/* The bar over the composer: what this message is answering. */
.rbar{flex-basis:100%;min-width:0;order:-1;display:flex;align-items:center;gap:8px;padding:0 0 4px}
.rbar .q{flex:1;min-width:0;border-inline-start:3px solid var(--accent);border-radius:8px;background:var(--fill);
  padding:6px 9px;font-size:14px;line-height:1.35}
.rbar .q b{display:block;font-size:12px;font-weight:600;color:var(--accent-ink)}
.rbar .q span{display:block;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rbar .rx{flex:none;width:32px;height:32px;border-radius:50%;background:transparent;border:0;color:var(--muted);
  display:grid;place-items:center;cursor:pointer}
.rbar .rx svg{width:18px;height:18px}
.chk{display:flex;align-items:center;gap:10px;font-size:17px}.chk input{width:22px;height:22px;accent-color:var(--accent)}
.tpick{display:flex;gap:8px}.tpick select{flex:1;min-width:0}
.bub a{color:var(--link-in);text-decoration:underline;word-break:break-all;font-weight:600}.bub.me a{color:var(--link-out)}
.bub a.tel{unicode-bidi:isolate;font-weight:600;white-space:nowrap}
.bub .orig{font-size:13px;opacity:.7;margin-top:4px;padding-top:4px;border-top:1px dashed var(--orig-line)}
.bub.short{text-align:center}
/* A one-word bubble still has to hold its clock; the ticks make mine wider. */
.bub.me,.bub.bot{min-width:92px}
.bub.div{min-width:0;align-self:center;max-width:92%;background:var(--bub-div);color:var(--muted);font-size:12px;font-weight:600;border:0;padding:4px 12px;border-radius:999px;text-align:center;margin:16px auto 4px}
/* The unread line runs the width of the thread: he sees at a glance where he
   stopped reading. */
.bub.div.unread{align-self:stretch;max-width:none;border-radius:8px;background:var(--accent-soft);color:var(--accent-ink);margin:14px 0 6px}
.bub.peer{align-self:flex-start;background:var(--bub-peer);color:var(--bub-peer-ink);border:1px solid var(--bub-peer-line)}
.bub.peer .who{font-size:12px;font-weight:600;color:var(--accent-ink);margin-bottom:2px}
.bub .t .tick{display:inline-block;vertical-align:-3px;margin-inline-start:6px}
.bub .t .tick svg{width:15px;height:13px;stroke:var(--tick)}
.bub .t .tick.read svg{stroke:var(--tick-read)}
.bub .t .tick.fail svg{stroke:var(--tick-fail)}
.bub.bot{align-self:flex-end;background:var(--card2);color:var(--muted);font-size:15px;border:1px dashed var(--hair)}
.bub.bot .t{color:var(--faint)}
.bub a.file{display:inline-block;padding:6px 12px;border-radius:999px;background:var(--file-chip);color:inherit;text-decoration:none;font-size:15px}
.bub.me a.file{background:var(--file-chip-me)}
.gone{font-size:13px;color:var(--faint)}
.bub.me .gone{color:var(--bub-out-meta)}
.fail-note{clear:both;font-size:13px;line-height:1.4;color:var(--tick-fail);margin-top:6px;font-weight:500}
/* action capsules over the composer: tinted labels on a fill, the primary one solid */
/* Two he taps every day and «المزيد»: three equal thirds, no gap left over (owner, 2026-09-22). */
.th-actions{display:flex;gap:8px;padding:8px 16px;border:0}
.act-btn{flex:1 1 0;min-width:0;display:inline-flex;align-items:center;justify-content:center;gap:5px;border-radius:999px;padding:0 10px;font-size:15px;font-weight:600;min-height:40px;border:0;
  background:var(--fill);color:var(--accent);white-space:nowrap}
.act-btn:active{opacity:.6}
.act-btn.primary{background:var(--accent);color:var(--on-accent)}
.act-btn.more svg{width:20px;height:20px;fill:currentColor}
.act-btn.danger{color:var(--red)}
.arm{background:var(--red)!important;color:var(--on-red)!important}
.lock-note{display:block;width:calc(100% - 32px);margin:0 16px 8px;background:var(--red-soft);color:var(--ink);border:0;border-radius:12px;padding:12px;font:inherit;font-size:15px;line-height:1.45;text-align:start}
button.lock-note{cursor:pointer}
.lock-note.warn{background:var(--amber-soft)}
.win-note{margin:0 16px 8px;background:var(--amber-soft);color:var(--ink);border-radius:12px;padding:10px 12px;font-size:15px;line-height:1.4}
.arch-note{margin:0 16px calc(env(safe-area-inset-bottom,0px) + 16px);background:var(--card2);border-radius:12px;padding:14px;
  text-align:center;font-size:15px;font-weight:600;color:var(--muted)}
.arch-note span{font-weight:400;font-size:13px;color:var(--faint)}
.call-bar{display:flex;align-items:center;justify-content:space-between;gap:10px;margin:0 16px calc(env(safe-area-inset-bottom,0px) + 16px);background:var(--card2);border-radius:12px;padding:12px 14px;font-size:15px;line-height:1.5}
.call-bar b{font-size:17px}
.call-btn{background:var(--accent);color:var(--on-accent);border-radius:999px;padding:0 18px;font-weight:600;text-decoration:none;flex:none;min-height:44px;display:inline-flex;align-items:center}

/* the composer: a hairline field holding the text box, the paperclip and the
   camera, with the round accent button — mic while empty, send once there is
   text — outside it. Glass under it, like every bar over the messages. */
.composer{position:relative;display:flex;flex-wrap:wrap;align-items:flex-end;gap:8px;padding:8px 12px calc(env(safe-area-inset-bottom,0px) + 8px);border:0;
  background:var(--glass);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);border-top:1px solid var(--hair);
  -webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.cpill{flex:1;min-width:0;display:flex;align-items:flex-end;gap:1px;background:var(--card);border:1px solid var(--hair);border-radius:22px;
  padding:2px 4px;transition:border-color .15s}
.cpill:focus-within{border-color:var(--accent)}
.composer textarea{flex:1;min-width:0;background:transparent;border:0;border-radius:0;padding:8px 10px;color:var(--ink);outline:none;
  min-height:38px;max-height:118px;font-size:17px;font-family:inherit;line-height:1.35;resize:none;overflow-y:auto;-webkit-user-select:text;user-select:text}
.composer textarea::placeholder{color:var(--faint)}
.cpill .att,.cpill .cam{width:36px;height:36px;margin-bottom:1px;border-radius:50%;background:transparent;display:grid;place-items:center;flex:none;transition:transform .12s}
.cpill .att svg,.cpill .cam svg{width:22px;height:22px;stroke:var(--muted);fill:none}
.cpill .att:active,.cpill .cam:active{transform:scale(.9)}
/* Held down, the camera is recording, not shooting. */
.cpill .cam.held{color:var(--red);transform:scale(1.12)}
.composer.recing .att{visibility:hidden;pointer-events:none}
.send{width:44px;height:44px;border-radius:50%;background:var(--accent);display:grid;place-items:center;flex:none;transition:transform .12s}
.send svg{width:20px;height:20px;stroke:var(--on-accent)}
.send:active{transform:scale(.94)}
/* No callout, no selection, no drag: iOS turns a long press into its own
   menu unless the button AND its parent opt out. */
#mainBtn{touch-action:none;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none;will-change:transform;transition:transform .08s}
#mainBtn.press{transform:scale(.94)}
/* the glyph inside the button is never the touch target: the timer repaint
   would detach the node the touch was bound to */
#mainBtn svg,.cpill .cam svg,.cpill .att svg{pointer-events:none}
.composer.recing .cpill{border-color:var(--red)}
.composer textarea.recing{color:var(--red);-webkit-user-select:none;user-select:none;pointer-events:none}
.composer textarea.recing::placeholder{color:var(--red);opacity:.9;animation:recblink 1.2s infinite}
@keyframes recblink{0%,100%{opacity:.9}50%{opacity:.45}}
/* the hold: the mic follows the finger toward the X, the hint fades as it
   goes, the lock pill rises to meet it. */
.rec-lock{position:absolute;inset-inline-end:14px;bottom:calc(100% + 6px);display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 10px;border-radius:999px;background:var(--card);box-shadow:var(--shadow-lg);font-size:11px;color:var(--muted);transition:transform .1s;animation:lockbob 1.1s ease-in-out infinite;pointer-events:none;z-index:5}
.rec-lock svg{width:18px;height:18px;stroke:var(--accent-ink)}
.rec-lock.on{background:var(--accent);color:var(--on-accent);animation:none}
.rec-lock.on svg{stroke:var(--on-accent)}
.rec-lock.hidden{display:none}
@keyframes lockbob{0%,100%{translate:0 0}50%{translate:0 -4px}}
.cpill .cancel{background:var(--red)}
.cpill .cancel svg{stroke:var(--on-red)}
.composer textarea:disabled{opacity:.9}
.composer .send.rec{background:var(--red);animation:recpulse 1.2s infinite}
@keyframes recpulse{0%,100%{box-shadow:0 0 0 0 var(--red-halo)}50%{box-shadow:0 0 0 10px transparent}}
/* the recording row takes the text box's place inside the field */
.cpill.recing textarea{display:none}
#recRow{flex:1;min-width:0;min-height:38px;display:flex;align-items:center;gap:10px;padding:0 12px;font-variant-numeric:tabular-nums}
.rec-dot{width:9px;height:9px;border-radius:50%;background:var(--red);flex:none;animation:recblink 1.2s infinite}
#recRow.opening .rec-dot{background:var(--muted);animation:none}
.rec-time{font-size:15px;font-weight:600;color:var(--red);flex:none;direction:ltr}
#recRow.opening .rec-time{color:var(--muted);font-weight:500;font-size:14px}
#recHint{flex:1;min-width:0;display:flex;align-items:center;justify-content:center;gap:4px;font-size:13px;color:var(--muted);white-space:nowrap;overflow:hidden;transition:opacity .05s}
#recHint svg{width:15px;height:15px;flex:none;stroke:var(--muted);animation:hintnudge 1s ease-in-out infinite}
/* Locked: the middle of the row is the pause; paused: the resume. The X deletes, the button sends. */
#recRow .rec-mid{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;height:30px;padding:0 12px;border-radius:999px;background:var(--fill);color:var(--ink);font-size:13px;font-weight:600}
#recRow .rec-mid.on{background:var(--accent);color:var(--on-accent)}
#recRow .rec-mid svg{width:15px;height:15px;stroke:currentColor;animation:none}
#recRow.paused .rec-dot{background:var(--muted);animation:none}
#recRow.paused .rec-time{color:var(--muted)}
@keyframes hintnudge{0%,100%{translate:0 0}50%{translate:4px 0}}
@media (max-width:360px){#recHint span{display:none}}

/* media bubble: the picture fills the bubble edge to edge, the time rides its
   bottom corner on a soft scrim, a caption sits under it in the same bubble */
.bub.has-media{padding:3px}
.bub.md-img:has(.ph),.bub.md-vid:has(.ph){padding:0;max-width:72%}
.bub.md-file,.bub.has-media:not(:has(.ph)):not(:has(.vn)){padding:8px 12px}
.bub .ph{display:block;position:relative;border-radius:inherit;overflow:hidden;width:100%;max-height:340px;
  background:var(--media-ph);box-shadow:0 0 0 1px var(--hair)}
.bub img,.bub video{display:block;width:100%;height:100%;max-width:100%;object-fit:cover;border-radius:inherit;background:transparent;
  opacity:0;transition:opacity .2s}
.bub .ph.ready img,.bub .ph.ready video{opacity:1}
/* The picture sets the bubble's width, so a caption wraps inside the frame and
   never stretches the bubble past it. */
.bub.md-img,.bub.md-vid{width:min(268px,72vw)}
.bub .ph:not(.ready){background:linear-gradient(100deg,var(--media-ph) 30%,var(--card2) 50%,var(--media-ph) 70%);
  background-size:220% 100%;animation:phwait 1.1s linear infinite}
@keyframes phwait{from{background-position:180% 0}to{background-position:-40% 0}}
.bub .ph:not(.ready) .vplay{display:none}
/* It did not arrive. An empty frame says nothing; this says what happened
   and takes the tap that asks for it again. */
.ph-fail{display:none}
.bub .ph.failed{background:var(--media-ph);animation:none}
.bub .ph.failed img,.bub .ph.failed video,.bub .ph.failed .vplay{display:none}
.bub .ph.failed .ph-fail{display:flex;align-items:center;justify-content:center;text-align:center;
  position:absolute;inset:0;padding:10px;font-size:13px;font-weight:600;color:var(--muted);cursor:pointer}
.bub.has-cap .ph{border-end-start-radius:4px;border-end-end-radius:4px}
.bub .cap{padding:6px 10px 18px;font-size:17px;line-height:1.35}
.bub.md-img:has(.ph) .t,.bub.md-vid:has(.ph) .t{inset-block-end:7px;inset-inline-end:8px;color:var(--media-ink);background:var(--media-scrim);border-radius:999px;padding:2px 8px;
}
.bub.md-img:has(.ph) .t .tick svg,.bub.md-vid:has(.ph) .t .tick svg{stroke:var(--media-ink)}
.bub.has-cap.md-img .t,.bub.has-cap.md-vid .t{background:none;padding:0;backdrop-filter:none;-webkit-backdrop-filter:none;
  inset-block-end:6px;inset-inline-end:11px;color:var(--bub-in-meta)}
.bub.me.has-cap .t{color:var(--bub-out-meta)}
.bub .vplay{position:absolute;inset:0;margin:auto;width:54px;height:54px;border-radius:50%;
  background:var(--media-scrim-strong);display:grid;place-items:center}
.bub .vplay svg{width:26px;height:26px;color:var(--media-ink);margin-inline-start:3px}
.bub .ph.on .vplay{display:none}
.bub .ph.on video{max-height:none;object-fit:contain}
/* an upload still in flight: the picture is already there, dimmed, spinning */
.bub .up{display:none;position:absolute;inset:0;margin:auto;width:30px;height:30px;border-radius:50%;
  border:2.5px solid var(--spin-track);border-top-color:var(--spin-head);animation:vspin .8s linear infinite}
.bub.pending .up{display:block}
.bub.pending img,.bub.pending video{opacity:.55}
.ph.vid.wait{display:grid;place-items:center;width:100%;background:var(--card2)}
@keyframes vspin{to{transform:rotate(360deg)}}

/* voice note — one 44px row (avatar, play button, waveform) with a single
   small line under the wave carrying the length, the speed pill and the
   unplayed dot */
.bub.md-aud{padding:6px 8px 6px;max-width:88%}
.vn{display:flex;flex-direction:column;gap:1px;min-width:min(272px,68vw)}
.vn-row{display:flex;align-items:center;gap:10px;min-height:42px}
/* The sender's face sits on the bubble's outer edge and the play button faces
   it across the wave: incoming reads avatar-left, play-right; mine, mirrored. */
.vn-av{order:3}.vn-play{order:1}.vn-mid{order:2}
.bub.me .vn-av{order:1}.bub.me .vn-play{order:3}
.vn audio{display:none}
.vn-av{position:relative;width:44px;height:44px;flex:none;border-radius:50%;display:grid;place-items:center;font-size:16px;font-weight:600;
  color:#fff;background:var(--vn-av)}
.bub.me .vn-av{background:var(--vn-av-me)}
/* The mic says whether the note has been heard: grey until it is, then blue. */
.vn-mic{position:absolute;bottom:-1px;inset-inline-end:-1px;width:16px;height:16px;padding:2.5px;border-radius:50%;
  color:var(--vn-bars);background:var(--vn-mic-bg);box-shadow:var(--vn-mic-shadow);transition:color .15s}
.vn.heard .vn-mic{color:var(--vn-played)}
.bub.me .vn-mic{color:var(--vn-bars-me)}
.bub.me .vn.heard .vn-mic{color:var(--vn-played-me)}
.vn-play{width:30px;height:30px;flex:none;display:grid;place-items:center;border-radius:50%;color:var(--vn-play);transition:transform .12s}
.bub.me .vn-play{color:var(--vn-play-me)}
.vn-play:active{transform:scale(.92)}
.vn-play svg{width:22px;height:22px}
.vn-play .ic-pause,.vn.playing .vn-play .ic-play{display:none}
.vn.playing .vn-play .ic-pause{display:block}
.vn-mid{flex:1;min-width:0;display:flex;align-items:center}
.vn-wave{position:relative;flex:1;min-width:0;height:26px;display:flex;align-items:center;touch-action:none;cursor:pointer}
/* Playback runs away from the play button: right to left on an incoming note,
   left to right on the technician's own, whose row is mirrored. */
.bub.me .vn-wave{direction:ltr}
.vn-bars{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%}
.vn-bars i{width:2px;flex:none;border-radius:2px;background:var(--vn-bars);transition:background .1s}
.vn-bars i.on{background:var(--vn-played)}
.bub.me .vn-bars i{background:var(--vn-bars-me)}
.bub.me .vn-bars i.on{background:var(--vn-played-me)}
.bub.cust .vn-bars,.bub.peer .vn-bars{color:var(--vn-bars)}
.bub.bot .vn-bars{color:var(--muted)}
.bub.me .vn-bars{color:var(--vn-bars-me)}
.vn-knob{position:absolute;top:50%;width:11px;height:11px;margin-top:-5.5px;margin-inline-start:-5.5px;border-radius:50%;
  background:var(--vn-knob);box-shadow:var(--vn-knob-shadow);pointer-events:none}
.bub.me .vn-knob{background:var(--vn-knob-me)}
.vn-foot{display:flex;align-items:center;height:14px;font-size:11px;color:var(--vn-foot);font-variant-numeric:tabular-nums;
  padding-inline-start:54px}
.bub.me .vn-foot{color:var(--vn-foot-me)}
.vn-t{flex:none}
/* the pill holds its room from the first paint, so the line never shifts */
.vn-rate{display:none;width:44px;height:44px;flex:none;place-items:center;border-radius:50%;order:3;
  font-size:13px;font-weight:700;background:var(--vn-rate);color:var(--vn-rate-ink);font-variant-numeric:tabular-nums}
.vn.started .vn-rate{display:grid}
.vn.started .vn-av{display:none}
.bub.me .vn-rate{order:1;background:var(--vn-rate-me);color:var(--vn-rate-ink-me)}
.vn.loading .vn-play{opacity:.55}
.vn.loading .vn-play svg{animation:vnspin 1s linear infinite}
@keyframes vnspin{to{transform:rotate(360deg)}}

/* broadcast cards: one group per job — a header row, label/value rows the way
   iOS lays out details, and the one prominent button */
.job-card{background:var(--card);border-radius:var(--r);padding:0 16px 16px;margin-bottom:16px;border:0}
/* the compact card: one glance, one button */
.board-bar{margin:0 0 12px}
.hist-bar{margin:0 0 4px}
.hist-search{margin:0 0 10px}
.seg.quiet .fchip b{animation:none}
.hist-h{display:flex;align-items:baseline;gap:8px;margin:14px 6px 8px;font-size:17px;font-weight:700}
.hist-h small{font-size:13px;color:var(--muted);font-weight:400}
/* a closed job's line stops at two lines; the whole of it is in the chat */
.hist-row .chat-last{display:-webkit-box;-webkit-line-clamp:2;line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.chat-side .amt.neg{color:var(--red)}
.arch-acts{display:flex;gap:8px;justify-content:center;margin-top:10px}
.arch-note .arch-acts .act-btn{margin:0;display:inline-flex;align-items:center;justify-content:center;gap:6px;text-decoration:none}
.arch-note .act-btn.dim{opacity:.5}
.arch-acts svg{width:16px;height:16px;stroke:currentColor;fill:none}
.jp-meta{font-size:13px;color:var(--muted);display:flex;align-items:center;justify-content:center;flex-wrap:wrap;gap:4px 8px;margin-top:4px}
.jp-meta svg{width:14px;height:14px;stroke:currentColor;fill:none}
.jp-meta a{color:var(--accent-ink);text-decoration:none;font-weight:600}
.jp-msgs{display:flex;flex-direction:column;padding:6px 2px 4px;max-height:50vh;overflow-y:auto;overscroll-behavior:contain;background:var(--card2);border-radius:14px}
.jp-claim{margin-top:12px}
/* A card's preview scrolls as ONE list: a scroller inside the sheet's own
   scroller let the finger move the sheet instead of the talk on the iPhone, and
   the end of the conversation could not be reached. Claim and refuse stay
   pinned under it. */
.jp .jp-msgs{max-height:none;overflow:visible}
.jp-foot{position:sticky;bottom:-4px;background:var(--card);padding-block:4px 8px;margin-inline:-4px;padding-inline:4px}
.seg .fchip b.late{background:var(--red)}
.job-card.compact.late::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:4px;background:var(--red)}
.job-age.late{color:var(--red);background:var(--red-soft)}
.job-card.compact{padding:12px 14px 12px;margin-bottom:10px;position:relative;overflow:hidden}
.job-card.compact.fresh::before{content:"";position:absolute;inset-inline-start:0;top:0;bottom:0;width:4px;background:var(--accent)}
.jc-top{display:flex;align-items:center;gap:10px;margin-bottom:4px}
.jc-top .job-id{font-size:14px;color:var(--muted);font-weight:600;font-variant-numeric:tabular-nums}
.job-age.fresh{color:var(--accent-ink);background:var(--accent-soft)}
.jc-dev{font-size:18px;font-weight:700;line-height:1.25;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-fault{font-size:15px;color:var(--ink);opacity:.8;margin-top:1px;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.jc-foot{display:flex;align-items:center;gap:10px;margin-top:10px}
.jc-no{min-height:40px;padding:0 14px;border-radius:999px;font-size:15px;color:var(--red);background:var(--card2);flex:none;margin-inline-start:auto}
.jc-place{display:inline-flex;align-items:center;gap:4px;font-size:14px;color:var(--muted);flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.jc-place svg{width:15px;height:15px;stroke:currentColor;fill:none;flex:none}
.jc-phone{font-size:14px;color:var(--accent-ink);text-decoration:none;font-variant-numeric:tabular-nums}
.claim.sm{width:auto;margin:0;min-height:40px;padding:0 20px;border-radius:999px;font-size:16px;flex:none}
.call-add{display:flex;align-items:center;justify-content:center;gap:8px;width:100%;margin:4px 0 16px}
.call-add svg{width:18px;height:18px;stroke:currentColor;fill:none}
.job-id{font-weight:600;color:var(--ink);font-size:17px}
.job-age{margin-inline-start:auto;font-size:13px;color:var(--amber-ink);font-weight:600;background:var(--amber-soft);border-radius:999px;padding:3px 10px}
.claim{width:100%;margin-top:14px;background:var(--accent);color:var(--on-accent);border-radius:12px;padding:0 16px;font-size:17px;font-weight:600;min-height:50px;transition:transform .12s,opacity .12s}
.claim:active{transform:scale(.98);opacity:.9}

/* appointments */
/* المواعيد: a hero for the day, then a timeline per day */
.cal-hero{margin:0 0 6px;padding:18px 18px 16px;border-radius:20px;background:linear-gradient(135deg,var(--accent) 0%,#0a4f8a 100%);color:#fff;box-shadow:0 10px 26px rgba(0,119,200,.22)}
.cal-hero-n{font-size:44px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.5px}
.cal-hero-t{font-size:15px;opacity:.88;margin-top:4px}
.cal-hero-next{margin-top:12px;padding-top:12px;border-top:1px solid rgba(255,255,255,.22);font-size:15px;font-weight:600;display:flex;align-items:center;gap:8px}
.cal-near{margin-top:12px;background:rgba(255,255,255,.18);color:#fff;border-radius:999px;padding:8px 14px;font-weight:600;font-size:14px;display:inline-flex;gap:6px;align-items:center;min-height:36px}
.cal-near.on{background:#fff;color:var(--accent)}
.cal-near svg{width:16px;height:16px;stroke:currentColor;fill:none;stroke-width:2}
.ap-pill.km{color:var(--muted);background:var(--card2)}
.chip-km{font-size:12px;color:var(--muted);background:var(--card2);border-radius:999px;padding:2px 8px;margin-inline-end:6px;font-variant-numeric:tabular-nums}
.cal-hero-next .dot{width:8px;height:8px;border-radius:50%;background:#fff;flex:none;animation:beat 1.5s ease-in-out infinite}
.cal-day{margin-top:12px}
.cal-h{display:flex;align-items:baseline;gap:8px;margin:0 6px 8px;font-size:17px;font-weight:700}
.cal-h small{font-size:13px;color:var(--muted);font-weight:400;flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.cal-h b{font-size:12px;font-weight:600;color:var(--accent-ink);background:var(--accent-soft);border-radius:999px;padding:2px 9px;font-variant-numeric:tabular-nums}
.cal-list{padding:2px 14px}
.ap-row{display:flex;gap:10px;align-items:center;padding:12px 0;min-height:66px;cursor:pointer;position:relative}
.ap-row + .ap-row{border-top:1px solid var(--hair)}
.ap-tl{width:14px;align-self:stretch;position:relative;flex:none}
.ap-tl::before{content:"";position:absolute;inset-inline-start:6px;top:-12px;bottom:-12px;width:2px;background:var(--hair)}
.ap-row:first-child .ap-tl::before{top:50%}
.ap-row:last-child .ap-tl::before{bottom:50%}
.ap-dot{position:absolute;top:50%;inset-inline-start:2px;width:10px;height:10px;margin-top:-5px;border-radius:50%;background:var(--card,#fff);border:2px solid var(--muted);box-sizing:border-box}
.ap-row.next .ap-dot{background:var(--accent);border-color:var(--accent);box-shadow:0 0 0 4px var(--accent-soft)}
.ap-row.late .ap-dot{border-color:var(--red)}
.ap-row.past .ap-dot{background:var(--hair);border-color:var(--hair)}
.ap-row.past .ap-mid,.ap-row.past .ap-time{opacity:.6}
.ap-time{min-width:60px;text-align:center;font-variant-numeric:tabular-nums;flex:none}
.ap-time b{display:block;font-size:19px;font-weight:700;color:var(--accent-ink);line-height:1.1}
.ap-time small{font-size:11px;color:var(--muted)}
.ap-row.late .ap-time b{color:var(--red)}
.ap-mid{flex:1;min-width:0}
.ap-name{font-weight:600;font-size:17px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.avatar.done{background:var(--tone-back)}
.ap-job{font-size:14px;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ap-meta{font-size:13px;color:var(--muted);margin-top:1px}
.ap-side{display:flex;flex-direction:column;align-items:flex-end;gap:6px;flex:none}
.ap-pill{font-size:12px;font-weight:600;border-radius:999px;padding:3px 9px;white-space:nowrap;color:var(--accent-ink);background:var(--accent-soft);font-variant-numeric:tabular-nums}
.ap-pill.late{color:var(--red);background:var(--red-soft)}
.hint.near{margin:-4px 0 12px;color:var(--accent-ink);background:var(--accent-soft);border-radius:10px;padding:8px 12px}
.cal-hold{margin-top:12px}
.cu-row{display:flex;gap:10px;align-items:center;padding:12px 0;min-height:58px;cursor:pointer}
.cu-row + .cu-row{border-top:1px solid var(--hair)}
.cu-row.late .ap-meta{color:var(--red)}
.ap-map{width:36px;height:36px;border-radius:50%;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent-ink)}
.ap-map svg{width:18px;height:18px;stroke:currentColor;fill:none}

/* me / stats */
.stat-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
/* انا: a band with his picture over it, his status as a pill, grouped settings */
.card.pf{padding:0;overflow:hidden}
.pf-status{display:inline-flex;align-items:center;gap:8px;padding:5px 6px;flex:none;border-radius:999px;background:var(--fill);font-size:15px;font-weight:600;color:var(--muted)}
.pf-status.on{color:var(--ok);background:rgba(52,199,89,.13)}
.pf-status .sw{transform:scale(.72);margin:-4px}
.card.grp h2{margin-bottom:2px}
.pref-row.stack{flex-wrap:wrap}.pref-row.stack .seg{width:100%;margin-top:8px}
.pref-row svg{width:16px;height:16px;stroke:var(--faint);fill:none;flex:none;transform:scaleX(-1)}
.pref-row.danger{color:var(--red);justify-content:center;font-weight:600;width:100%;font-size:17px}
/* the account: his name and the way out, one line */
.card.acct-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px}
.acct-name{font-size:17px;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acct-out{color:var(--red);font-weight:600;font-size:17px;min-height:44px;padding:0 4px;flex:none}
/* الاداء: a big ring with its trend, four tiles, one step to take, what pulls it down */
.perf-ring{--p:0;--ring:var(--accent);width:112px;height:112px;border-radius:50%;flex:none;display:grid;place-items:center;position:relative;background:conic-gradient(var(--ring) calc(var(--p)*1%),var(--fill) 0);margin-bottom:6px}
.perf-ring::before{content:"";position:absolute;inset:9px;border-radius:50%;background:var(--card)}
.perf-ring b{position:relative;font-size:38px;font-weight:700;line-height:1;font-variant-numeric:tabular-nums;letter-spacing:-.5px}
.perf-ring.good{--ring:var(--ok)}.perf-ring.ok{--ring:var(--teal)}.perf-ring.mid{--ring:var(--amber-ink)}.perf-ring.bad{--ring:var(--red)}
.perf-grade{font-size:22px;font-weight:700}
.perf-delta{font-size:13px;font-weight:600;border-radius:999px;padding:3px 10px;background:var(--fill);color:var(--muted)}
.perf-delta.up{color:var(--ok);background:rgba(52,199,89,.14)}.perf-delta.down{color:var(--red);background:var(--red-soft)}
.perf-sub{font-size:13px;color:var(--muted)}
.perf-tiles{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.perf-tile{--tone:var(--accent);background:var(--card2);border-radius:14px;padding:12px 12px 11px;display:flex;flex-direction:column;gap:2px;border-inline-start:3px solid var(--tone)}
.perf-tile.good{--tone:var(--ok)}.perf-tile.ok{--tone:var(--teal)}.perf-tile.mid{--tone:var(--amber-ink)}.perf-tile.bad{--tone:var(--red)}.perf-tile.none{--tone:var(--faint)}
.perf-tile b{font-size:26px;font-weight:700;line-height:1.1;color:var(--tone);font-variant-numeric:tabular-nums}
.perf-tile .l{font-size:14px;font-weight:600;margin-top:2px}.perf-tile .s{font-size:12px;color:var(--muted)}
.perf-coach{display:flex;align-items:center;gap:10px;margin-top:8px;padding:9px 12px;border-radius:12px;background:var(--accent-soft);color:var(--accent-ink);font-size:14px;font-weight:600}
.perf-coach svg{width:18px;height:18px;stroke:currentColor;fill:none;flex:none}
.perf-issues{margin-top:14px;padding-top:10px;border-top:1px solid var(--hair)}.perf-issues.clean{font-size:14px;color:var(--ok);padding-top:12px}
.perf-nh{font-size:14px;font-weight:600;margin-bottom:4px}
.perf-issue{display:flex;align-items:center;gap:10px;width:100%;min-height:42px;padding:0 2px;text-align:start;font-size:15px;color:var(--ink)}
.perf-issue + .perf-issue{border-top:1px solid var(--hair)}
.perf-issue i{width:8px;height:8px;border-radius:50%;background:var(--red);flex:none}
.perf-issue span{flex:1;min-width:0}
.perf-issue svg{width:16px;height:16px;stroke:var(--faint);fill:none;flex:none;transform:scaleX(-1)}
/* the compact card: a small ring beside the grade, four thin bars, the
   negatives behind one row */
.perf-periods{margin:0 0 12px}
.perf-top{display:flex;align-items:center;gap:12px;padding:0 0 8px}
.perf-ring.sm{width:60px;height:60px;margin:0}
.perf-ring.sm::before{inset:6px}
.perf-ring.sm b{font-size:22px;letter-spacing:-.3px}
.perf-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.perf-line{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.perf-top .perf-grade{font-size:20px}
.perf-rows{display:flex;flex-direction:column}
.perf-row{--tone:var(--accent);display:grid;grid-template-columns:auto 1fr auto;align-items:baseline;column-gap:6px;padding:7px 0}
.perf-row.good{--tone:var(--ok)}.perf-row.ok{--tone:var(--teal)}.perf-row.mid{--tone:var(--amber-ink)}.perf-row.bad{--tone:var(--red)}.perf-row.none{--tone:var(--faint)}
.perf-row .l{font-size:15px;font-weight:600}
.perf-row .s{font-size:12px;color:var(--muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.perf-row b{font-size:15px;font-weight:700;color:var(--tone);font-variant-numeric:tabular-nums}
.perf-bar{grid-column:1/-1;display:block;height:4px;border-radius:2px;background:var(--fill);margin-top:6px;overflow:hidden}
.perf-bar i{display:block;height:100%;border-radius:2px;background:var(--tone);transition:width .5s ease}
@starting-style{.perf-bar i{width:0 !important}}
@media (prefers-reduced-motion:reduce){.perf-bar i{transition:none}}
.perf-more{display:flex;align-items:center;gap:8px;width:100%;min-height:44px;margin-top:8px;border-top:1px solid var(--hair);font-size:14px;font-weight:600;color:var(--ink);text-align:start}
.perf-more span{flex:1}
.perf-more b{min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--red-soft);color:var(--red);font-size:12px;display:inline-grid;place-items:center}
.perf-more svg{width:16px;height:16px;stroke:var(--faint);fill:none;flex:none;transform:rotate(-90deg);transition:transform .2s}
.perf-more.open svg{transform:rotate(90deg)}
.perf-more + .perf-issues{margin-top:0;padding-top:0;border-top:0}
/* ارباحك: the periods, then one amount and what it came from */
.earn-periods{margin:0 0 14px}
.earn-sum{display:flex;align-items:baseline;gap:6px;color:var(--ok);white-space:nowrap}
.earn-sum b{font-size:40px;font-weight:700;line-height:1.05;letter-spacing:-.5px;font-variant-numeric:tabular-nums}
.earn-sum small{font-size:17px;font-weight:600}
.earn-sub{font-size:14px;color:var(--muted);margin-top:6px}
.earn-deal{font-size:13px;color:var(--muted);margin-top:8px;padding-top:8px;border-top:1px solid var(--hair)}
.stat{background:var(--card2);border-radius:12px;padding:14px;border:0}
.stat .n{font-size:28px;font-weight:700;margin-top:2px;font-variant-numeric:tabular-nums;letter-spacing:-.3px;line-height:1.2}
.stat .l{font-size:13px;color:var(--muted)}
.stat.money .n{color:var(--ok)}
/* the amount and its unit stay one line; the unit reads smaller */
.stat .n{white-space:nowrap}
.stat .n small{font-size:15px;font-weight:600;margin-inline-start:4px}
/* appearance picker: the iOS segmented control */
.seg{display:flex;gap:2px;background:var(--fill);border-radius:9px;padding:2px}
.seg-b{flex:1;min-height:32px;border-radius:7px;padding:0 6px;font-size:13px;font-weight:500;color:var(--ink);transition:background .15s}
.seg-b.on{background:var(--seg-on);box-shadow:var(--seg-shadow);font-weight:600}
/* the iOS switch: 51 by 31, green when on */
.sw{width:51px;height:31px;border-radius:16px;background:var(--sw-off);position:relative;transition:background .25s;flex:none;border:0}
.sw::after{content:"";position:absolute;top:2px;inset-inline-start:2px;width:27px;height:27px;border-radius:50%;background:var(--sw-knob);
  box-shadow:var(--sw-knob-shadow);transition:inset-inline-start .25s cubic-bezier(.32,.72,.35,1)}
.sw.on{background:var(--green)}
.sw.on::after{inset-inline-start:22px}
/* the same switch as a form checkbox in a sheet */
.field input.sw{-webkit-appearance:none;appearance:none;width:51px;height:31px;min-height:0;padding:0;margin:0;background:var(--sw-off);box-shadow:none}
.field input.sw:checked{background:var(--green)}
.field input.sw:checked::after{inset-inline-start:22px}
.field .chk{display:flex;font-size:17px;color:var(--ink);margin-bottom:0}
.chk.sw-row{justify-content:space-between;min-height:44px}
.field .chk input:not(.sw){width:22px;height:22px;min-height:0;padding:0;flex:none}
/* What the notification switch actually sends, one line each. */
.pref-row{display:flex;align-items:center;gap:12px;margin-top:12px;padding-top:12px;border-top:1px solid var(--hair);min-height:44px;cursor:pointer}
.pref-row.first{margin-top:0;padding-top:0;border-top:0}
.pref-txt{flex:1;min-width:0;font-size:17px;font-weight:400;color:var(--ink)}
.pref-txt span{display:block;font-weight:400;font-size:13px;color:var(--muted);margin-top:2px}
/* The app updates itself; the number is a quiet line that still forces one. */
.ver{text-align:center;font-size:12px;color:var(--faint);padding:8px 0 16px;cursor:pointer}
.ghost{border:0;border-radius:12px;padding:0 14px;font-size:17px;color:var(--accent);width:100%;text-align:center;margin-top:8px;min-height:44px;background:var(--card2)}
.ghost:active{background:var(--fill2)}
.empty{display:flex;flex-direction:column;align-items:center;gap:12px;color:var(--muted);font-size:15px;padding:40px 0;text-align:center;line-height:1.5}
.empty svg{width:40px;height:40px;stroke-width:1.3;color:var(--empty-ic)}

/* the owner watching the whole team from the technician app */
.team-list{margin-top:14px}
.team-row{display:flex;align-items:center;gap:10px;padding:12px 0;min-height:44px}
.team-row + .team-row{border-top:1px solid var(--hair)}
.tm-mid{flex:1;min-width:0}
.tm-name{display:flex;align-items:center;gap:8px;font-weight:600;font-size:17px}
.tm-dot{width:9px;height:9px;border-radius:50%;background:var(--faint);flex:none}
.tm-dot.on{background:var(--green);box-shadow:0 0 0 3px var(--green-halo)}
.tm-sub{font-size:13px;color:var(--muted);margin-top:3px}
.tm-sub b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.tm-sub span{white-space:nowrap}
/* «يحتاج تدخلك»: a row is the job, why it needs him, and the way to it */
.need-row{cursor:pointer}
.need-why{flex:none;font-size:13px;font-weight:600;color:var(--red);background:color-mix(in srgb,var(--red) 12%,transparent);border-radius:999px;padding:4px 10px}
.need-row svg{width:16px;height:16px;stroke:var(--faint);fill:none;flex:none;transform:scaleX(-1)}
.need-more{display:block;width:100%;min-height:44px;margin-top:4px;border-top:1px solid var(--hair);color:var(--accent-ink);font-size:15px;font-weight:600}
/* the owner's home: four counts, what needs him, the team */
.oh-tiles{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin:0 0 12px}
.oh-tile{background:var(--card);border-radius:var(--r);padding:14px 16px;display:flex;flex-direction:column;align-items:flex-start;gap:2px;text-align:start;transition:scale .15s}
.oh-tile:active{scale:.97}
.oh-tile b{font-size:30px;font-weight:700;line-height:1.1;font-variant-numeric:tabular-nums;color:var(--ink)}
.oh-tile span{font-size:14px;color:var(--muted);font-weight:500}
.oh-tile.bad b{color:var(--red)}.oh-tile.warn b{color:var(--amber-ink)}
.oh-pill{flex:none;font-size:12px;font-weight:600;border-radius:999px;padding:3px 9px;white-space:nowrap}
.oh-pill.bad{color:var(--red);background:var(--red-soft)}.oh-pill.warn{color:var(--amber-ink);background:var(--amber-soft)}
/* one technician's chats: the way back and whose they are */
.oh-head{display:flex;align-items:center;gap:8px;margin:0 0 8px}
.oh-head b{font-size:20px;font-weight:700}
.oh-back{display:inline-flex;align-items:center;gap:2px;color:var(--accent-ink);font-size:17px;min-height:44px;padding-inline-end:6px}
.oh-back svg{width:22px;height:22px;stroke:currentColor;fill:none}
/* the control's new jobs and the jobs he has not handed on: a row is the job and its one button */
.seat-new .team-row,.seat-held .team-row{gap:8px}
.seat-new .tm-mid,.seat-held .tm-mid{cursor:pointer}
.act-btn.sm{min-height:36px;padding:0 16px;flex:none}
.oh-perf{margin-inline-start:auto;min-height:36px;padding:0 14px;border-radius:999px;background:var(--accent-soft);color:var(--accent-ink);font-size:14px;font-weight:600}
.oh-tiles + .card + .card + .ctl-hand,.card + .ctl-hand{margin-top:4px}
@media (prefers-reduced-motion:reduce){.oh-tile:active{scale:1}}
/* the owner's المواعيد: a chosen count is ringed, the team is a cut under them */
.oh-tile.on{box-shadow:inset 0 0 0 2px var(--accent)}
.cal-seg{margin:0 0 12px;overflow-x:auto;scrollbar-width:none}
.cal-seg::-webkit-scrollbar{display:none}
.cal-all{display:block;margin:0 auto 4px;min-height:44px;color:var(--accent-ink);font-size:15px;font-weight:600}
/* the control's own day sorted by where he stands: the hero's button on the page */
.cal-near.own{display:flex;margin:0 auto 8px;background:var(--accent-soft);color:var(--accent-ink)}
.ap-name .chip-tech{margin-inline-start:6px}
/* the owner's الطلبات: three counts in one row when the control is on */
.oh-tiles.three{grid-template-columns:repeat(3,1fr)}
.oh-tiles.three .oh-tile span{font-size:13px}
.jc-foot .oh-pill{margin-inline-start:auto}
/* the owner's السجل: the window, two pickers, the search, one summing line */
.rec-periods{margin:0 0 10px}
.rec-tools{display:flex;gap:8px;margin:0 0 10px}
.rec-pick{flex:1;display:inline-flex;align-items:center;justify-content:space-between;gap:6px;min-height:44px;padding:0 14px;border-radius:12px;background:var(--card);color:var(--ink);font-size:15px;font-weight:500}
.rec-pick.on{color:var(--accent-ink);box-shadow:inset 0 0 0 1.5px var(--accent)}
.rec-pick svg{width:16px;height:16px;stroke:var(--faint);fill:none;flex:none}
.rec-sum{margin:2px 6px 4px;font-size:15px;color:var(--muted)}
.rec-sum b{color:var(--ink);font-weight:700;font-variant-numeric:tabular-nums}
.rec-span{display:block;font-size:13px;color:var(--faint);margin-bottom:2px}
.as-btn.on{color:var(--accent-ink);font-weight:600}
.tm-open{flex:none;font-size:13px;font-weight:600;color:var(--accent-ink);background:var(--accent-soft);border-radius:999px;padding:4px 10px}

/* The microphone check: every step in front of whoever is holding the phone,
   so a report comes back as a fact instead of «ما يشتغل». */
.mic-log{margin-top:10px;display:flex;flex-direction:column;gap:6px}
.mic-step{display:flex;flex-direction:column;gap:2px;padding:8px 10px;border-radius:10px;background:var(--card2);border:1px solid var(--hair)}
.mic-step b{font-size:15px;font-weight:600}
.mic-step span{font-size:13px;color:var(--muted);word-break:break-word;direction:ltr;text-align:start}
.mic-step.ok b{color:var(--ok)}
.mic-step.bad b{color:var(--red)}
.mic-step.warn b{color:var(--amber-ink)}
.mic-step.run b{color:var(--muted)}
.mic-step.run{border-style:dashed}
.mic-play{width:100%;margin-top:10px}

/* tab bar: a glass capsule floating over the content, five equal tabs, the
   selected one filled and tinted, a red badge for what needs him */
.tabs:empty{display:none}
.tabs{position:fixed;bottom:calc(12px + env(safe-area-inset-bottom,0px));inset-inline:16px;max-width:528px;margin:0 auto;height:var(--tab-h);
  border-radius:999px;background:var(--tabs-bg);backdrop-filter:blur(24px) saturate(1.4);-webkit-backdrop-filter:blur(24px) saturate(1.4);
  box-shadow:0 8px 32px rgba(0,0,0,.14),inset 0 0 0 .5px var(--glass-edge);display:flex;z-index:40;padding:0 4px}
.tab{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;color:var(--muted);font-size:10px;font-weight:500;position:relative;min-height:44px;transition:color .18s;border-radius:999px}
.tab svg{width:26px;height:26px;stroke-width:1.6;transition:transform .18s}
.tab.on{color:var(--accent);font-weight:600}
.tab .tbadge{position:absolute;top:7px;inset-inline-start:calc(50% + 6px);min-width:18px;height:18px;border-radius:9px;
  background:var(--red);color:var(--on-red);font-size:11px;font-weight:600;display:grid;place-items:center;padding:0 5px;font-variant-numeric:tabular-nums}

/* login */
.login{min-height:calc(100dvh - 80px);display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:24px;text-align:center}
html.kb-anim .login{transition:padding-bottom .25s cubic-bezier(.38,.7,.125,1)}
html.kb-up .login{padding-bottom:calc(24px + var(--kb,0px))}
/* The Omixus mark itself, drawn in the accent. */
.login-logo{width:88px;height:88px;display:grid;place-items:center;color:var(--accent);margin-bottom:8px}
.login-logo svg{width:100%;height:100%}
.login-title{font-size:28px;font-weight:700;color:var(--ink);letter-spacing:-.3px}
/* Balanced lines: no last word left alone on a line of its own. */
.login-sub{font-size:15px;color:var(--muted);line-height:1.5;white-space:nowrap}
.login-in{width:min(78vw,300px);background:var(--card);color:var(--ink);border:1px solid var(--hair);border-radius:12px;padding:13px 16px;
  font-size:17px;text-align:center;outline:none;direction:ltr;margin-top:8px;min-height:50px}
.login-in::placeholder{color:var(--faint)}
.login-in:focus{border-color:var(--accent)}
.login-in.code{font-size:26px;letter-spacing:8px;font-variant-numeric:tabular-nums}
.login-go{width:min(78vw,300px);background:var(--accent);color:var(--on-accent);border-radius:12px;
  padding:0 16px;font-size:17px;font-weight:600;min-height:50px}
.login-go:disabled{opacity:.5}
.login-alt{font-size:15px;color:var(--accent);font-weight:400;padding:8px;min-height:44px}
.login-demo{margin-top:22px;font-size:13px;color:var(--muted);padding:8px;min-height:44px}

/* call-style appointment alarm, drawn like a system alert on glass */
.alarm{position:fixed;inset:0;z-index:90;display:none;background:var(--alarm-scrim);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.alarm.on{display:grid;place-items:center}
.alarm-card{width:min(86vw,300px);background:var(--card);border-radius:24px;padding:24px 20px 16px;text-align:center;
  box-shadow:var(--shadow-lg);animation:rise .3s cubic-bezier(.32,.72,.35,1)}
.alarm-pulse{width:64px;height:64px;border-radius:50%;margin:0 auto 14px;display:grid;place-items:center;color:var(--on-accent);
  background:var(--accent);animation:alarmpulse 1.4s infinite}
.alarm-pulse svg{width:30px;height:30px;stroke:var(--on-accent)}
@keyframes alarmpulse{0%,100%{box-shadow:0 0 0 0 var(--accent-glow-wide)}50%{box-shadow:0 0 0 16px transparent}}
.alarm-title{font-size:13px;font-weight:600;color:var(--accent-ink);margin-bottom:4px}
.alarm-name{font-size:20px;font-weight:700;color:var(--ink)}
.alarm-meta{font-size:13px;color:var(--muted);margin-top:4px}
.alarm-time{font-size:34px;font-weight:700;color:var(--ink);margin:10px 0 18px;font-variant-numeric:tabular-nums;letter-spacing:-.5px;direction:ltr}
.alarm-btns{display:flex;gap:10px}
.ab{flex:1;border-radius:12px;padding:0 12px;font-size:17px;font-weight:600;min-height:50px}
.ab.ok{background:var(--fill);color:var(--accent)}
.ab.go{background:var(--accent);color:var(--on-accent)}

/* the iOS alert: 270 wide, glass, one question, two buttons */
.dialog-wrap{position:fixed;inset:0;z-index:95;display:none}
.dialog-wrap.on{display:grid;place-items:center}
.dialog-wrap .scrim{position:absolute;inset:0;background:var(--scrim)}
.alert{position:relative;width:270px;background:var(--glass);backdrop-filter:blur(30px) saturate(1.4);-webkit-backdrop-filter:blur(30px) saturate(1.4);
  border-radius:14px;text-align:center;overflow:hidden;box-shadow:var(--shadow-lg);animation:rise .2s cubic-bezier(.32,.72,.35,1)}
.al-title{font-size:17px;font-weight:600;padding:19px 16px 4px}
.al-body{font-size:13px;color:var(--muted);padding:0 16px 16px;line-height:1.4}
.al-btns{display:flex;border-top:1px solid var(--hair)}
.al-b{flex:1;min-height:44px;font-size:17px;color:var(--accent)}
.al-b + .al-b{border-inline-start:1px solid var(--hair)}
.al-b.primary{font-weight:600}
.al-b.danger{color:var(--red);font-weight:600}
.ghost.small{min-height:36px;font-size:15px;margin-top:10px}

/* sheet */
.sheet-wrap{position:fixed;inset:0;z-index:60;display:none}
.sheet-wrap.on{display:block}
.scrim{position:absolute;inset:0;background:var(--scrim)}
.sheet{position:absolute;bottom:var(--kb,0px);inset-inline:0;max-width:560px;margin:0 auto;background:var(--card);border:0;touch-action:none;
  border-radius:20px 20px 0 0;padding:8px 16px calc(env(safe-area-inset-bottom,0px) + 16px);
  animation:up .3s cubic-bezier(.32,.72,.35,1);box-shadow:var(--sheet-shadow)}
/* Under the keyboard a sheet rises with the edge (the frame no longer shrinks),
   its indicator padding folds, and a tall one scrolls instead of leaving the screen. */
html.kb-anim .sheet{transition:bottom .25s cubic-bezier(.38,.7,.125,1)}
html.kb-up .sheet{padding-bottom:16px;max-height:calc(100dvh - var(--kb,0px) - env(safe-area-inset-top,0px) - 8px);overflow-y:auto;touch-action:pan-y}
.sheet::before{content:"";display:block;width:36px;height:5px;border-radius:3px;background:var(--sheet-grip);margin:2px auto 14px}
@keyframes up{from{transform:translateY(100%)}to{transform:none}}
/* The sheet rises from the bottom edge over a fading scrim, and slides back
   down the same way when it closes (sheetClose keeps it drawn as .out). */
.sheet-wrap.on .scrim{animation:scrimin .3s ease-out}
.sheet-wrap.out{display:block;pointer-events:none}
.sheet-wrap.out .sheet{animation:down .24s cubic-bezier(.32,.72,.35,1) forwards}
.sheet-wrap.out .scrim{animation:scrimout .24s ease-in forwards}
@keyframes down{from{transform:none}to{transform:translateY(100%)}}
@keyframes scrimin{from{opacity:0}to{opacity:1}}
@keyframes scrimout{from{opacity:1}to{opacity:0}}
@media (prefers-reduced-motion:reduce){.sheet-wrap.out{display:none}.sheet-wrap.on .scrim,.sheet{animation:none}}
.sheet h3{font-size:17px;font-weight:600;margin-bottom:16px;text-align:center}
/* the row's menu: an iOS action sheet — a head, a list of choices, cancel apart */
.as-head{text-align:center;padding:2px 8px 12px}
.as-head b{display:block;font-size:15px;font-weight:600}
.as-head span{display:block;font-size:13px;color:var(--muted);margin-top:2px}
/* The message menu, WhatsApp's way: a small card on the message, a tap elsewhere closes it. */
.bmenu-wrap{position:fixed;inset:0;z-index:70;background:rgba(0,0,0,.06)}
.bmenu{position:absolute;width:168px;background:var(--card);border-radius:14px;box-shadow:0 12px 32px rgba(0,0,0,.22),0 0 0 1px var(--hair);overflow:hidden;animation:bpop .14s cubic-bezier(.2,.8,.3,1);transform-origin:top center}
@keyframes bpop{from{opacity:0;transform:scale(.92)}to{opacity:1;transform:none}}
.bmenu button{display:flex;align-items:center;justify-content:space-between;width:100%;padding:0 14px;min-height:46px;font-size:16px;color:var(--ink);text-align:start}
.bmenu button + button{border-top:1px solid var(--hair)}
.bmenu button svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8;color:var(--muted)}
@media (prefers-reduced-motion:reduce){.bmenu{animation:none}}
.go.danger,.sheet .go.danger{background:var(--red)}
.cd-preview{background:var(--card2);border-radius:14px;padding:12px 14px;font-size:16px;line-height:1.6;margin:6px 0 14px}
.digest-text{white-space:pre-line;line-height:1.75;font-size:16px;padding:2px 2px 0}
.as-list{background:var(--card2);border-radius:14px;overflow:hidden}
.as-btn{display:flex;align-items:center;gap:12px;width:100%;min-height:52px;padding:0 16px;font-size:17px;color:var(--accent);text-align:start}
.as-btn + .as-btn{border-top:1px solid var(--hair)}
.as-btn > span{flex:1}
.as-btn > span + svg{transform:scaleX(-1);color:var(--muted)}
.as-btn svg{width:22px;height:22px;stroke:currentColor;fill:none;stroke-width:1.8;flex:none;transform:none}
.as-btn:active{background:var(--fill)}
.as-cancel{display:block;width:100%;min-height:52px;margin-top:10px;border-radius:14px;background:var(--card2);color:var(--accent);font-size:17px;font-weight:600}
.field{margin-bottom:12px}
.field label{display:block;font-size:13px;color:var(--muted);margin-bottom:6px}
.field input,.field select,.field textarea{width:100%;background:var(--card2);border:0;border-radius:10px;padding:12px 14px;color:var(--ink);outline:none;min-height:44px;font-size:17px}
.field input::placeholder{color:var(--faint)}
.field input:focus{box-shadow:0 0 0 2px var(--accent-soft)}
.wchips{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.wchip{border-radius:999px;padding:6px 12px;background:var(--card2);color:var(--accent-ink);font-size:14px;min-height:34px}
/* the part's invoice in the close sheet (ADR-064) */
.inv-need{font-weight:400;font-size:13px;color:var(--muted);margin-inline-start:6px}
.inv-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.inv-row .inv-pick{display:flex;align-items:center;justify-content:center;gap:8px;margin-top:0}
.inv-row .inv-pick svg{width:20px;height:20px}
.inv-thumb{width:56px;height:56px;border-radius:10px;object-fit:cover;background:var(--card2)}
.inv-st{font-size:15px;color:var(--muted)}
.inv-act{border:0;border-radius:999px;padding:6px 14px;background:var(--card2);color:var(--accent-ink);font-size:14px;min-height:44px}
.inv-st.ok{color:var(--ok)}
.inv-st.bad{color:var(--red)}
.inv-full{display:block;width:100%;max-height:70vh;object-fit:contain;border-radius:12px;background:var(--card2)}
.qlist{margin-bottom:12px}
.qrow{display:flex;align-items:center;gap:10px;padding:5px 0}
.qrow label{flex:1;font-size:16px}
.qrow input{width:120px;background:var(--card2);border:0;border-radius:10px;padding:10px 12px;color:var(--ink);font-size:17px;min-height:44px;text-align:center;outline:none}
.qrow.other input:first-child{flex:1;text-align:start}
.hist-more{width:100%;margin:12px 0}
.sheet .go{width:100%;background:var(--accent);color:var(--on-accent);border-radius:12px;padding:0 16px;font-weight:600;font-size:17px;margin-top:8px;min-height:50px}
.sheet .go:disabled{opacity:.4}
/* a required choice in a sheet: one of the group on */
.wchip.on{background:var(--accent);color:var(--on-accent)}
.seg.pick .seg-b{min-height:40px;font-size:15px}
.as-list[data-pick] .as-btn{color:var(--ink)}
.as-list[data-pick] .as-btn.on{color:var(--accent-ink)}
.as-list[data-pick] .as-btn.on::after{content:'';flex:none;width:7px;height:13px;margin-inline-end:4px;border:solid currentColor;border-width:0 2.5px 2.5px 0;transform:translateY(-2px) rotate(45deg)}
.toast{position:fixed;bottom:calc(var(--tab-h) + 32px + env(safe-area-inset-bottom,0px));inset-inline:0;margin-inline:auto;width:max-content;max-width:calc(100% - 32px);transform:translateY(16px);
  background:var(--toast-bg);color:var(--toast-ink);padding:10px 20px;border-radius:999px;font-size:15px;font-weight:600;z-index:80;opacity:0;pointer-events:none;transition:.25s;white-space:nowrap;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px)}
.toast.show{opacity:1;transform:none}

/* the thread's «المزيد»: two groups, the final ones red */
.as-list + .as-list{margin-top:10px}
.as-btn.danger{color:var(--red)}
/* The customer's card: head, contact, the job, his history with this technician. */
.cs{max-height:calc(88vh - 48px);overflow-y:auto;overscroll-behavior:contain;touch-action:pan-y;-webkit-overflow-scrolling:touch;margin:0 -4px;padding:0 4px 4px}
.cs-head{display:flex;flex-direction:column;align-items:center;gap:3px;padding:0 0 14px;text-align:center}
.cs-head .avatar{width:64px;height:64px;font-size:17px;margin-bottom:5px}
.cs-name{font-size:20px;font-weight:700}
.cs-sub{font-size:13px;color:var(--muted)}
.cs-chips{display:flex;flex-wrap:wrap;justify-content:center;gap:6px;margin-top:8px}
.cs-title{display:flex;justify-content:space-between;align-items:baseline;gap:8px;font-size:13px;font-weight:600;color:var(--muted);padding:16px 12px 6px}
.cs-total{font-variant-numeric:tabular-nums;color:var(--ok)}
.cs-total.neg{color:var(--red)}
.cs-group{background:var(--card2);border-radius:14px;overflow:hidden}
.cs-row{display:flex;align-items:center;gap:12px;width:100%;min-height:50px;padding:0 14px;font-size:16px;color:var(--ink);text-align:start;text-decoration:none}
.cs-row + .cs-row{border-top:1px solid var(--hair)}
.cs-row svg,.cs-hit svg{width:20px;height:20px;stroke:currentColor;fill:none;stroke-width:1.8;color:var(--accent);flex:none;transform:none}
.cs-row > svg:last-child:not(:first-child){width:16px;height:16px;color:var(--faint);stroke-width:2.2}
.cs-row .k{color:var(--muted);font-size:15px;flex:none}
.cs-row .v{flex:1;min-width:0;text-align:end;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cs-row .v.num{font-variant-numeric:tabular-nums;direction:ltr;font-weight:600;color:var(--accent)}
.cs-row .v.start{text-align:start;color:var(--muted);font-size:14px;white-space:normal;padding:12px 0}
.cs-row.dim{color:var(--muted)}
.cs-row.dim svg{color:var(--faint)}
.cs-hit{display:flex;align-items:center;gap:12px;flex:1;min-width:0;min-height:50px;text-align:start;font-size:16px;color:var(--ink)}
.cs-copy{width:36px;height:36px;border-radius:50%;background:var(--fill);display:grid;place-items:center;flex:none;color:var(--accent)}
.cs-copy svg{width:18px;height:18px}
.cs-copy:active,.cs-row:active,.cs-hit:active{opacity:.6}
.cs-row.job{padding-block:8px}
.cs-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.cs-t{font-size:16px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cs-row .sub{font-size:12px;color:var(--muted)}
.cs-amt{flex:none;font-weight:600;font-variant-numeric:tabular-nums;color:var(--ok);font-size:15px}
.cs-amt.zero{color:var(--faint);font-weight:400}
.cs-amt.neg{color:var(--red)}

/* «انزل لاخر مسج»: a round button over the thread, on only when he is a screen up */
.to-end{position:absolute;inset-inline-start:16px;bottom:140px;width:40px;height:40px;border-radius:50%;background:var(--card);color:var(--accent);
  box-shadow:0 2px 10px rgba(0,0,0,.18),0 0 0 1px var(--hair);display:none;place-items:center;z-index:3}
.to-end.on{display:grid;animation:pop .18s cubic-bezier(.32,.72,.35,1)}
@keyframes pop{from{transform:scale(.6);opacity:0}to{transform:none;opacity:1}}
.to-end svg{width:22px;height:22px;stroke:currentColor;fill:none}
.to-end .n{position:absolute;top:-6px;inset-inline-end:-6px;min-width:20px;height:20px;padding:0 6px;border-radius:10px;background:var(--accent);color:var(--on-accent);font-size:12px;font-weight:700;display:none;place-items:center;font-variant-numeric:tabular-nums}
.to-end .n.on{display:grid}
/* the picture viewer: black, over everything; a tap or a pull down closes it, a double tap zooms */
.viewer{position:fixed;inset:0;z-index:80;background:#000;display:none}
.viewer.on{display:block;animation:vwfade .16s}
@keyframes vwfade{from{opacity:0}to{opacity:1}}
.vw-body{position:absolute;inset:0;overflow:auto;display:flex;align-items:center;justify-content:center;touch-action:pan-x pan-y;-webkit-overflow-scrolling:touch}
.vw-body img{max-width:100%;max-height:100%;object-fit:contain;-webkit-user-select:none;user-select:none;-webkit-touch-callout:none}
.viewer.zoom .vw-body{display:block}
.viewer.zoom .vw-body img{max-width:none;max-height:none;width:220%}
.vw-x{position:absolute;z-index:2;top:calc(10px + env(safe-area-inset-top,0px));inset-inline-start:12px;width:40px;height:40px;border-radius:50%;background:rgba(255,255,255,.16);color:#fff;display:grid;place-items:center}
.vw-x svg{width:20px;height:20px;stroke:currentColor;fill:none}
/* the first day marker sits right under the head, not a step below it (owner, 2026-09-22) */
.th-msgs > .bub.div:first-child{margin-top:2px}
/* the server's knock wears its label; a failed line offers its words back */
.bub.bot .who{font-size:12px;font-weight:600;color:var(--amber-ink);margin-bottom:3px}
.fail-note .resend{display:inline-block;margin-inline-start:8px;padding:2px 10px;border-radius:999px;background:var(--red-soft);color:var(--red);font-size:12px;font-weight:600;vertical-align:middle}
/* a closed chat offers the next job for the same customer (ADR-041) */
.arch-note .act-btn{display:flex;margin:10px auto 0;min-height:36px;padding:0 18px;font-size:14px}
/* «يفكر»: the customer put it off — a quiet tag, not a wait (ADR-042) */
.think-tag{font-size:12px;font-weight:600;color:var(--muted);background:var(--fill);border-radius:999px;padding:3px 9px;white-space:nowrap}
/* a time in his own line offers itself as the appointment (one tap) */
.appt-hint{display:flex;align-items:center;gap:10px;margin:0 16px 8px;padding:8px 8px 8px 12px;border-radius:14px;background:var(--accent-soft);color:var(--accent-ink);font-size:14px;animation:pop .18s cubic-bezier(.32,.72,.35,1)}
.appt-hint span{flex:1;min-width:0}
.appt-hint b{font-weight:700;font-variant-numeric:tabular-nums}
.appt-hint .ah-yes{min-height:32px;padding:0 14px;border-radius:999px;background:var(--accent);color:var(--on-accent);font-size:14px;font-weight:600}
.appt-hint .ah-no{width:32px;height:32px;border-radius:50%;display:grid;place-items:center;color:var(--accent-ink);opacity:.7}
.appt-hint .ah-no svg{width:16px;height:16px;stroke:currentColor;fill:none}
/* the customer's pin in the strip: a chip that opens the map */
.st-chip.link{display:inline-flex;align-items:center;gap:4px;text-decoration:none}
.st-chip.link svg{width:13px;height:13px;stroke:currentColor;fill:none;stroke-width:2}

/* Touch floor: every small control is reached through an invisible 44pt ring,
   so a thumb lands on it without anything moving on screen. */
.search .s-x,.vn-play,.rbar .rx,.appt-hint .ah-no,.th-call,.cpill .att,.cpill .cam,.cs-copy,.ap-map,.act-btn,.jc-no{position:relative}
.search .s-x::before{content:'';position:absolute;inset:-9px}
.vn-play::before{content:'';position:absolute;inset:-7px}
.rbar .rx::before,.appt-hint .ah-no::before{content:'';position:absolute;inset:-6px}
.th-call::before,.cpill .att::before,.cpill .cam::before,.cs-copy::before,.ap-map::before{content:'';position:absolute;inset:-4px}
.to-end::before,.vw-x::before,.act-btn::before,.jc-no::before{content:'';position:absolute;inset:-2px}


/* The iPhone shell draws UIKit's own tab bar and lifts the web view's bottom
   safe area by its height, so the web bar and its reserved strip step aside. */
html.ntabs{--tab-h:0px}
html.ntabs .tabs{display:none}

/* Control mode (ADR-054). The control's per-technician cut sits under the
   inbox cuts; a row carries what the technician said from the door. */
.tech-seg{margin-top:8px;overflow-x:auto;scrollbar-width:none}
.tech-seg::-webkit-scrollbar{display:none}
.tech-seg .seg-b{flex:0 0 auto;padding-inline:14px}
.sig-chip{display:inline-block;font-size:12px;font-weight:600;padding:1px 8px;border-radius:999px;background:var(--accent-soft);color:var(--accent-ink);margin-inline-end:6px;vertical-align:middle}
.sig-chip.done{background:var(--green-soft);color:var(--ok)}
.sig-chip.warn{background:var(--amber-soft);color:var(--amber-ink)}
.th-actions.exec .act-btn.primary svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:2}
.tr-row{flex-wrap:wrap;row-gap:2px;padding-block:8px}
.tr-row .tr-name{flex:1;color:var(--ink);font-weight:600}
.tr-row .tr-sub{flex-basis:100%;padding-inline-start:21px;font-size:13px;color:var(--muted)}
.tr-row.dim{opacity:.45}
/* the hand-over list: the fact in words, the counts under it, the best fit marked */
.tr-row .tr-day{flex-basis:100%;padding-inline-start:21px;font-size:13px;color:var(--accent-ink)}
.tr-row .tr-clash{flex-basis:100%;padding-inline-start:21px;font-size:13px;font-weight:600;color:var(--red)}
.tr-need{margin:6px 4px 12px;text-align:center}
.tr-row .tr-line{flex-basis:100%;padding-inline-start:21px;font-size:14px;color:var(--ink)}
.tr-row .tr-fit{flex:0 0 auto;width:auto;font-size:12px;font-weight:700;color:var(--ok);background:var(--green-soft);border-radius:999px;padding:2px 9px}
/* the best fit is tinted, not outlined: an outline is clipped by the list's rounded corners */
.tr-row.fit{background:var(--green-soft)}
.ctl-card .stat-grid{grid-template-columns:1fr 1fr}
.ctl-badge{font-size:12px;font-weight:700;color:var(--on-accent);background:var(--accent);border-radius:999px;padding:3px 10px}
button.team-row{width:100%;background:none;border:0;text-align:start;color:inherit;font:inherit}
button.team-row > svg{width:16px;height:16px;stroke:var(--faint);fill:none;stroke-width:2;flex:none;transform:scaleX(-1)}
.tm-sub b.bad{color:var(--red)}
.ctl-hand{margin-top:12px;display:flex;align-items:center;justify-content:center;gap:8px}
.ctl-hand svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8}
.ctl-offer h2{margin-bottom:6px}
.ctl-offer .arch-acts{margin-top:12px}
.job-card.offer{opacity:.85}

/* The day's report (owner, 2026-10-03: «رتبها في جدول في مربعات»): tiles,
   the reasons as chips, the money as a ledger, the open work as a strip, and
   the team as a table. */
.dg .card-head{margin-bottom:12px}
.dg-day{font-size:13px;color:var(--muted)}
.dg-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:8px}
.dg-tile{background:var(--card2);border-radius:14px;padding:12px 8px;text-align:center;display:flex;flex-direction:column;gap:4px}
.dg-tile b{font-size:26px;font-weight:700;color:var(--ink);font-variant-numeric:tabular-nums;line-height:1.1}
.dg-tile span{font-size:13px;color:var(--muted)}
.dg-tile.good b{color:var(--ok)}
.dg-tile.bad b{color:var(--red)}
.dg-why{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.dg-chip{font-size:13px;color:var(--muted);background:var(--fill);border-radius:999px;padding:4px 10px}
.dg-chip b{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
.dg-ledger{margin-top:14px;border-radius:14px;background:var(--card2);padding:4px 14px}
.dg-row{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:44px;font-size:15px;color:var(--ink)}
.dg-row + .dg-row{border-top:1px solid var(--hair)}
.dg-row b{font-weight:600;font-variant-numeric:tabular-nums}
.dg-row.off{color:var(--muted)}
.dg-row.off b{font-weight:500}
.dg-row.sum{font-weight:600}
.dg-row.mine b{color:var(--accent-ink);font-size:17px}
.dg-strip{display:grid;grid-auto-flow:column;grid-auto-columns:1fr;gap:8px;margin-top:12px}
.dg-strip > div{border:1px solid var(--hair);border-radius:12px;padding:8px;text-align:center;display:flex;flex-direction:column;gap:2px}
.dg-strip b{font-size:18px;font-weight:700;font-variant-numeric:tabular-nums}
.dg-strip span{font-size:12px;color:var(--muted)}
.dg-strip .bad b{color:var(--red)}
.dg-table{margin-top:14px;border:1px solid var(--hair);border-radius:14px;overflow:hidden}
.dg-tr{display:grid;grid-template-columns:1.4fr repeat(4,1fr);align-items:center;min-height:40px;padding-inline:12px;font-size:14px;font-variant-numeric:tabular-nums}
.dg-tr + .dg-tr{border-top:1px solid var(--hair)}
.dg-tr span:not(:first-child){text-align:center}
.dg-tr.head{background:var(--card2);font-size:12px;color:var(--muted);font-weight:600}

/* The owner's report: the periods, then pages he swipes — the team, then one
   technician a page — with dots under them. */
.dg-periods{margin:0 0 10px}
.dg-span{font-size:13px;color:var(--muted);margin:-4px 0 10px}
.dg.busy .dg-pager{opacity:.5;transition:opacity .2s}
.dg-pager{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none;gap:16px;overscroll-behavior-x:contain}
.dg-pager::-webkit-scrollbar{display:none}
.dg-page{flex:0 0 100%;scroll-snap-align:start;min-width:0}
.dg-ph{display:flex;align-items:center;gap:8px;font-size:17px;margin-bottom:10px}
.dg-dots{display:flex;justify-content:center;gap:6px;margin-top:12px}
.dg-dots button{width:8px;height:8px;border-radius:50%;background:var(--hair);padding:0;position:relative}
.dg-dots button::before{content:'';position:absolute;inset:-18px -4px}
.dg-dots button.on{background:var(--accent);width:20px;border-radius:999px}

/* «انا» opens on one row: the picture, the name and role, the switch. */
.pf-row{display:flex;align-items:center;gap:12px;padding:12px 16px}
.pf-row .avatar.me-av{width:52px;height:52px;font-size:20px;flex:none}
.pf-text{flex:1;min-width:0}
.pf-name{font-size:19px;font-weight:700;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pf-role{font-size:13px;color:var(--muted);margin-top:2px}
/* the control's time sheet: the team near the job, a time after each one's visit */
.team-near{background:var(--card2);border-radius:12px;padding:8px 12px;margin:0 0 12px}
.tn-h{font-size:13px;font-weight:600;color:var(--muted);margin:2px 0 4px}
.tn-row{display:flex;align-items:center;gap:8px;padding:7px 0}
.tn-row + .tn-row{border-top:1px solid var(--hair)}
.tn-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.tn-mid b{display:flex;align-items:center;gap:6px;font-size:15px}
.tn-mid span{font-size:13px;color:var(--muted)}
.slot-chip{flex:none;min-height:36px;padding:0 12px;border-radius:999px;background:var(--accent-soft);color:var(--accent-ink);font-size:14px;font-weight:600}
.slot-chip.on{background:var(--accent);color:var(--on-accent)}
/* a look at one technician's day, from the hand-over and the time sheets */
.tr-look{flex:none;margin-inline-start:21px;margin-top:4px;min-height:32px;padding:0 12px;border-radius:999px;background:var(--fill);color:var(--accent-ink);font-size:13px;font-weight:600}
.tn-row .tr-look{margin:0}
.td-h{font-size:13px;font-weight:600;color:var(--muted);margin:10px 6px 4px}
.td-head{display:flex;align-items:center;gap:8px;justify-content:center;margin:2px 0 10px}
.td-head b{font-size:19px}
.td-head span{font-size:13px;color:var(--muted)}
.td-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:6px;margin:0 0 6px}
.td-stats div{background:var(--card2);border-radius:12px;padding:8px 4px;display:flex;flex-direction:column;align-items:center;gap:1px}
.td-stats b{font-size:20px;font-variant-numeric:tabular-nums}
.td-stats span{font-size:12px;color:var(--muted)}
.td-list{margin:0;background:var(--card2)}
.td-loose{display:grid;grid-template-columns:1fr 1fr;gap:6px}
.td-chip{background:var(--card2);border-radius:12px;padding:8px 10px;display:flex;flex-direction:column;gap:1px;min-width:0}
.td-chip b{font-size:14px}
.td-chip span{font-size:13px;color:var(--ink)}
.td-chip small{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
