/* ==========================================================================
   SHA LAB LIS — Design system
   Logical properties throughout so RTL (Kurdish / Arabic) mirrors correctly.
   ========================================================================== */

/* ------------------------------------------------------------- tokens ---- */
:root {
  --brand-50:#eef7f6; --brand-100:#d3ecea; --brand-200:#a7d9d5; --brand-300:#6fc0ba;
  --brand-400:#3aa39c; --brand-500:#128a83; --brand-600:#0d6f6a; --brand-700:#0d5955;
  --brand-800:#0f4744; --brand-900:#103b39;

  --accent-500:#2563eb; --accent-600:#1d4ed8;
  --ok-50:#ecfdf5;  --ok-500:#10b981;  --ok-600:#059669;  --ok-700:#047857;
  --warn-50:#fffbeb;--warn-500:#f59e0b;--warn-600:#d97706; --warn-700:#b45309;
  --dang-50:#fef2f2;--dang-500:#ef4444;--dang-600:#dc2626; --dang-700:#b91c1c;
  --info-50:#eff6ff;--info-500:#3b82f6;--info-600:#2563eb;
  --purple-500:#8b5cf6; --pink-500:#ec4899;

  --bg:#f1f5f9;
  --surface:#ffffff;
  --surface-2:#f8fafc;
  --surface-3:#f1f5f9;
  --border:#e2e8f0;
  --border-strong:#cbd5e1;
  --text:#0f172a;
  --text-2:#475569;
  --text-3:#94a3b8;
  --text-inv:#ffffff;

  --shadow-xs:0 1px 2px rgba(15,23,42,.06);
  --shadow-sm:0 1px 3px rgba(15,23,42,.08),0 1px 2px rgba(15,23,42,.04);
  --shadow:0 4px 12px rgba(15,23,42,.08),0 2px 4px rgba(15,23,42,.04);
  --shadow-lg:0 12px 32px rgba(15,23,42,.12),0 4px 8px rgba(15,23,42,.06);
  --shadow-xl:0 24px 60px rgba(15,23,42,.18);

  --r-xs:6px; --r-sm:8px; --r:12px; --r-lg:16px; --r-xl:22px; --r-full:999px;
  --sidebar-w:262px; --sidebar-w-collapsed:68px; --topbar-h:60px;
  --fs:14px;
  --font-latin:'Inter','Segoe UI',system-ui,-apple-system,'Helvetica Neue',Arial,sans-serif;
  --font-arabic:'Noto Kufi Arabic','Segoe UI',Tahoma,'Geeza Pro',system-ui,sans-serif;
  --font-mono:'JetBrains Mono','SF Mono',Menlo,Consolas,monospace;
  --font:var(--font-latin);
  --t-fast:120ms cubic-bezier(.4,0,.2,1);
  --t:200ms cubic-bezier(.4,0,.2,1);
}

html[data-theme="dark"] {
  --bg:#0b1220;
  --surface:#111c2e;
  --surface-2:#16233a;
  --surface-3:#1c2c46;
  --border:#243349;
  --border-strong:#33465f;
  --text:#e8eef7;
  --text-2:#9db0c9;
  --text-3:#64748b;
  --brand-50:#0f2c2b; --brand-100:#123c39;
  --ok-50:#0d2b22; --warn-50:#2e2410; --dang-50:#331717; --info-50:#122036;
  --shadow-sm:0 1px 3px rgba(0,0,0,.4);
  --shadow:0 4px 14px rgba(0,0,0,.45);
  --shadow-lg:0 16px 40px rgba(0,0,0,.55);
  --shadow-xl:0 24px 60px rgba(0,0,0,.65);
}

html[lang="ku"], html[lang="ar"] { --font:var(--font-arabic); }

/* --------------------------------------------------------------- base ---- */
*,*::before,*::after { box-sizing:border-box; }
html { font-size:var(--fs); -webkit-text-size-adjust:100%; }
body {
  margin:0; background:var(--bg); color:var(--text); font-family:var(--font);
  font-size:1rem; line-height:1.55; -webkit-font-smoothing:antialiased;
}
h1,h2,h3,h4,h5 { margin:0; font-weight:650; line-height:1.3; letter-spacing:-.01em; }
h1{font-size:1.5rem} h2{font-size:1.25rem} h3{font-size:1.05rem} h4{font-size:.95rem}
p{margin:0 0 .6em}
a{color:var(--brand-600);text-decoration:none} a:hover{text-decoration:underline}
img{max-width:100%}
button,input,select,textarea{font:inherit;color:inherit}
::selection{background:var(--brand-200);color:var(--brand-900)}
[hidden]{display:none !important}
/* English numerals everywhere, even in Kurdish/Arabic UI */
body,input,select,textarea,table{font-variant-numeric:tabular-nums;}
.num,.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:plaintext}

::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:99px;border:2px solid var(--bg)}
::-webkit-scrollbar-thumb:hover{background:var(--text-3)}

/* -------------------------------------------------------------- layout --- */
.app{display:flex;min-height:100vh}
.sidebar{
  inline-size:var(--sidebar-w); flex:0 0 var(--sidebar-w);
  background:linear-gradient(180deg,var(--brand-800),var(--brand-900));
  color:#dbeeed; position:sticky; inset-block-start:0; block-size:100vh;
  display:flex; flex-direction:column; z-index:40; transition:inline-size var(--t);
}
.sidebar__brand{
  display:flex;align-items:center;gap:10px;padding:14px 16px;
  border-block-end:1px solid rgba(255,255,255,.09); min-block-size:var(--topbar-h);
}
.sidebar__logo{
  inline-size:36px;block-size:36px;border-radius:10px;flex:0 0 36px;
  background:linear-gradient(135deg,var(--brand-300),var(--brand-500));
  display:grid;place-items:center;font-weight:800;color:#04201f;font-size:15px;
  box-shadow:0 2px 8px rgba(0,0,0,.25);
}
.sidebar__title{font-weight:700;font-size:.95rem;color:#fff;line-height:1.15;white-space:nowrap}
.sidebar__sub{font-size:.68rem;color:#93c9c5;letter-spacing:.08em;text-transform:uppercase}
.sidebar__nav{flex:1;overflow-y:auto;padding:8px 8px 20px;scrollbar-width:thin}
.sidebar__nav::-webkit-scrollbar-thumb{background:rgba(255,255,255,.18);border-color:transparent}
.nav-group{margin-block-start:10px}
.nav-group__label{
  font-size:.66rem;text-transform:uppercase;letter-spacing:.1em;color:#7fb3af;
  padding:8px 12px 4px;font-weight:700;white-space:nowrap;
  /* It is a button now, so strip the control chrome and fill the rail. */
  display:flex;align-items:center;gap:6px;inline-size:100%;
  background:none;border:0;cursor:pointer;font-family:inherit;text-align:start;
  transition:color var(--t-fast);
}
.nav-group__label:hover{color:#bfe3e0}
.nav-group__label > span{flex:1;min-inline-size:0}
.nav-group__chev{inline-size:13px;block-size:13px;opacity:.7;transition:transform var(--t-fast)}
/* Folded groups keep their heading; only the links go. */
.nav-group.is-collapsed .nav-group__items{display:none}
.nav-group.is-collapsed .nav-group__chev{transform:rotate(-90deg)}
html[dir="rtl"] .nav-group.is-collapsed .nav-group__chev{transform:rotate(90deg)}
/* A rail collapsed to icons has no room for headings at all. */
.sidebar.is-collapsed .nav-group__items{display:block}
.nav-item{
  display:flex;align-items:center;gap:10px;padding:8px 11px;border-radius:9px;
  color:#c6e2e0;font-size:.86rem;cursor:pointer;white-space:nowrap;
  transition:background var(--t-fast),color var(--t-fast);text-decoration:none;
}
.nav-item:hover{background:rgba(255,255,255,.09);color:#fff;text-decoration:none}
.nav-item.is-active{background:var(--brand-500);color:#fff;font-weight:600;box-shadow:var(--shadow-sm)}
.nav-item__icon{inline-size:19px;block-size:19px;flex:0 0 19px;opacity:.92}
.nav-item__badge{
  margin-inline-start:auto;background:var(--dang-500);color:#fff;font-size:.66rem;
  padding:1px 6px;border-radius:99px;font-weight:700;
}
.sidebar.is-collapsed{inline-size:var(--sidebar-w-collapsed);flex-basis:var(--sidebar-w-collapsed)}
/* Folded to icons: the wording goes, the icon itself must stay. */
.sidebar.is-collapsed .sidebar__title,.sidebar.is-collapsed .sidebar__sub,
.sidebar.is-collapsed .nav-group__label,
.sidebar.is-collapsed .nav-item > span:not(.nav-item__icon),
.sidebar.is-collapsed .nav-item__badge{display:none}
.sidebar.is-collapsed .nav-item{justify-content:center;padding:9px}

/* The mega panel hangs from the header, so the column is its containing block. */
.main{flex:1;min-inline-size:0;display:flex;flex-direction:column;position:relative}
.topbar{
  block-size:var(--topbar-h);background:var(--surface);border-block-end:1px solid var(--border);
  display:flex;align-items:center;gap:12px;padding-inline:16px;position:sticky;inset-block-start:0;z-index:30;
}
.content{padding:18px;flex:1;min-inline-size:0}

/* ------------------------------------------------------------------ charts */
/* Entry animations. Every one is a transform or an opacity so the browser can
   run it on the compositor; nothing here triggers layout. */
.ch-anim{animation-duration:.62s;animation-fill-mode:both;animation-timing-function:cubic-bezier(.22,.68,.34,1)}

@keyframes chDraw{from{stroke-dashoffset:1}to{stroke-dashoffset:0}}
.ch-draw{stroke-dasharray:1;animation-name:chDraw;animation-duration:.95s;
  animation-timing-function:cubic-bezier(.35,.62,.28,1)}

@keyframes chFade{from{opacity:0}to{opacity:1}}
.ch-fade{animation-name:chFade}

@keyframes chPop{from{opacity:0;transform:scale(.2)}to{opacity:1;transform:scale(1)}}
.ch-pop{animation-name:chPop;animation-duration:.4s;transform-box:fill-box;transform-origin:center}

@keyframes chGrow{from{transform:scaleY(0)}to{transform:scaleY(1)}}
.ch-grow{animation-name:chGrow;transform-box:fill-box;transform-origin:bottom}

@keyframes chArc{from{opacity:0;transform:rotate(-24deg) scale(.94)}to{opacity:1;transform:rotate(0) scale(1)}}
.ch-arc{animation-name:chArc;animation-duration:.7s}

@keyframes chWiden{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.ch-widen{animation-name:chWiden;transform-origin:inline-start center}

/* A value that changed since the last refresh nudges once, so the eye catches
   what moved without the whole card redrawing. */
@keyframes chBump{0%{transform:translateY(0)}30%{transform:translateY(-3px)}100%{transform:translateY(0)}}
.is-bumped{animation:chBump .5s cubic-bezier(.3,.7,.4,1)}

/* A quiet pulse showing the screen is following live data. */
/* The dashboard says plainly that it is following live data. */
.live-badge{
  display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:99px;
  background:var(--ok-50);color:var(--ok-600);font-weight:600;
}
.live-dot{
  inline-size:7px;block-size:7px;border-radius:50%;background:var(--ok-500);
  flex:0 0 7px;box-shadow:0 0 0 0 var(--ok-500);animation:livePulse 2.4s ease-out infinite;
}
@keyframes livePulse{
  0%{box-shadow:0 0 0 0 rgba(16,185,129,.55)}
  70%{box-shadow:0 0 0 7px rgba(16,185,129,0)}
  100%{box-shadow:0 0 0 0 rgba(16,185,129,0)}
}

/* Anyone who has asked their system for less motion gets the finished state. */
@media (prefers-reduced-motion:reduce){
  .ch-anim,.is-bumped,.live-dot{animation:none !important}
  .ch-draw{stroke-dasharray:none}
}

/* ---------------------------------------------------------------- mega menu */
/* In menu layout the rail is gone entirely and the header carries the brand,
   so the whole width belongs to the worklist and report tables. */
.app--menu .sidebar{display:none}
.app--menu .main{inline-size:100%}

.topbar__brand{
  display:flex;align-items:center;gap:9px;text-decoration:none;color:inherit;
  padding-inline-end:6px;
}
.topbar__brand:hover{text-decoration:none}
.topbar__logo{
  inline-size:30px;block-size:30px;border-radius:8px;flex:0 0 30px;
  background:linear-gradient(140deg,var(--brand-600),var(--brand-800));
  color:#fff;font-weight:800;font-size:.72rem;display:grid;place-items:center;letter-spacing:.02em;
}
.topbar__brandtext{display:flex;flex-direction:column;line-height:1.15}
.topbar__title{font-weight:700;font-size:.84rem;color:var(--text)}
.topbar__sub{font-size:.62rem;color:var(--text-3);letter-spacing:.08em}

/* ------------------------------------------------------- the SHA mark ---- */
/* A badge that keeps moving, so the header says the system is awake. Every
   stroke reads a token, so one mark serves the light layout and the dark
   console; nothing here is a fixed colour. */
.sha-mark{
  inline-size:32px;block-size:32px;flex:0 0 32px;display:grid;place-items:center;
  line-height:0;
}
.sha-mark svg{inline-size:100%;block-size:100%;overflow:visible}

/* The glow underneath, breathing slowly. */
.sha-mark__halo{
  fill:var(--brand-500);opacity:.14;
  transform-origin:50% 50%;
  animation:sha-mark-breathe 3.6s ease-in-out infinite;
}
/* An open ring that sweeps round: two arcs with a gap, turning. */
.sha-mark__ring{
  fill:none;stroke:var(--brand-500);stroke-width:2.5;stroke-linecap:round;
  stroke-dasharray:34 79;             /* two short arcs, wide gaps between */
  transform-origin:50% 50%;
  animation:sha-mark-spin 5.5s linear infinite;
}
/* The disc the trace is drawn on. */
.sha-mark__core{fill:var(--brand-600);opacity:.16}
/* The trace is two layers, the way a monitor draws one: the whole line sits
   there faintly, and a bright head runs along it. One layer alone reads as a
   stub of colour; together they read as a reading being taken. */
.sha-mark__track{
  fill:none;stroke:var(--brand-400);stroke-width:2.2;opacity:.32;
  stroke-linecap:round;stroke-linejoin:round;
}
.sha-mark__trace{
  fill:none;stroke:var(--accent-500);stroke-width:2.6;
  stroke-linecap:round;stroke-linejoin:round;
  stroke-dasharray:14 48;
  animation:sha-mark-run 2.4s cubic-bezier(.55,0,.35,1) infinite;
}

@keyframes sha-mark-spin{to{transform:rotate(360deg)}}
@keyframes sha-mark-breathe{
  0%,100%{transform:scale(.86);opacity:.10}
  50%    {transform:scale(1.04);opacity:.22}
}
@keyframes sha-mark-run{
  0%  {stroke-dashoffset:62}
  70% {stroke-dashoffset:-14}
  100%{stroke-dashoffset:-14}   /* a beat of rest before the next sweep */
}

/* Asked not to animate: the mark still reads, it just stops moving. */
@media (prefers-reduced-motion:reduce){
  .sha-mark__halo,.sha-mark__ring,.sha-mark__trace{animation:none}
  .sha-mark__halo{opacity:.16;transform:scale(1)}
  .sha-mark__trace{stroke-dasharray:none}
  .sha-mark__track{opacity:0}          /* the full trace is drawn once, brightly */
}

/* ------------------------------------------------ quick way back home ---- */
/* The dashboard is the screen everyone returns to, so it keeps its own button
   in the header instead of living one click deep inside the menu. */
/* The laboratory's name, its clock, and the mark that says the system is awake.
   The pro skin restyles this into its own pill; these are the base rules, so
   the classic layout is not left with unstyled text where the badge should be. */
.topbar__live{
  display:flex;align-items:center;gap:9px;flex:0 0 auto;
  padding:4px 12px 4px 6px;
  border:1px solid var(--border);border-radius:var(--r-full);
  background:var(--surface-2);
  text-decoration:none;color:inherit;white-space:nowrap;
  transition:border-color var(--t),background var(--t);
}
.topbar__live:hover{
  text-decoration:none;border-color:var(--brand-300);background:var(--brand-50);
}
.topbar__live-clock{font-family:var(--font-mono);font-size:.74rem;color:var(--text-3)}
.topbar__live-text{display:grid;line-height:1.15}
.topbar__live-tag{
  font-size:.56rem;letter-spacing:.2em;text-transform:uppercase;color:var(--brand-600);
}
.topbar__live-name{font-size:.8rem;font-weight:700;color:var(--text)}
/* On a narrow header the middle block is the first thing to go — the mark and
   the way home both survive in the header proper. */
@media (max-width:1100px){ .topbar__live{display:none} }
.topbar__home{flex:0 0 auto;gap:7px}
.topbar__home.is-active{
  background:var(--brand-50);color:var(--brand-700);
}
@media (max-width:900px){ .topbar__home span{display:none} }

/* Fixed, not absolute: the header is sticky, so a panel hanging off the page
   flow would scroll away from the button that opened it. */
.mega{
  position:fixed;inset-inline:0;inset-block-start:var(--topbar-h);
  background:var(--surface);border-block-end:1px solid var(--border);
  box-shadow:var(--shadow-lg);z-index:35;padding:16px 18px 20px;
  max-block-size:calc(100vh - var(--topbar-h));overflow-y:auto;
  animation:slideUp var(--t-fast) both;
}
.mega-scrim{position:fixed;inset:0;background:rgba(15,23,42,.28);z-index:29}

.mega__search{position:relative;max-inline-size:420px;margin-block-end:14px}
.mega__search .input{padding-inline-start:34px}
html[dir="rtl"] .mega__search .input{padding-inline-start:11px;padding-inline-end:34px}
.mega__search .search-box__icon{
  position:absolute;inset-inline-start:10px;inset-block-start:50%;transform:translateY(-50%);
  color:var(--text-3);pointer-events:none;display:flex;
}
.mega__search .search-box__icon .icon{inline-size:16px;block-size:16px}

.mega__cols{
  display:grid;gap:8px 22px;
  grid-template-columns:repeat(auto-fill,minmax(190px,1fr));
  align-items:start;
}
.mega__col{min-inline-size:0;break-inside:avoid}
.mega__heading{
  font-size:.66rem;text-transform:uppercase;letter-spacing:.09em;color:var(--text-3);
  font-weight:700;padding:6px 8px 5px;border-block-end:1px solid var(--border);
  margin-block-end:4px;
}
.mega__link{
  display:flex;align-items:center;gap:9px;padding:7px 8px;border-radius:8px;
  color:var(--text);font-size:.85rem;text-decoration:none;white-space:nowrap;
  transition:background var(--t-fast),color var(--t-fast);
}
.mega__link:hover{background:var(--brand-50);color:var(--brand-700);text-decoration:none}
.mega__link.is-active{background:var(--brand-500);color:#fff;font-weight:600}
.mega__icon{display:flex;color:var(--text-3);flex:0 0 auto}
.mega__link:hover .mega__icon,.mega__link.is-active .mega__icon{color:inherit}
.mega__icon .icon{inline-size:16px;block-size:16px}
.mega__empty{padding:26px;text-align:center;color:var(--text-3);font-size:.86rem}

/* The panel is the only navigation on a phone, so give it the full height. */
@media (max-width:640px){
  .mega{padding:12px}
  .mega__cols{grid-template-columns:1fr;gap:4px}
  .topbar__brandtext{display:none}
}
.page-head{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap;margin-block-end:16px}
.page-head__text{flex:1;min-inline-size:200px}
.page-head h1{font-size:1.45rem}
.page-head p{color:var(--text-2);font-size:.87rem;margin:2px 0 0}
.page-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}

/* --------------------------------------------------------------- cards --- */
.card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  box-shadow:var(--shadow-xs);overflow:hidden;
}
.card__head{
  padding:13px 16px;border-block-end:1px solid var(--border);display:flex;
  align-items:center;gap:10px;flex-wrap:wrap;background:var(--surface);
}
.card__head h3{font-size:.98rem;flex:1;min-inline-size:120px}
.card__body{padding:16px}
.card__body--flush{padding:0}
.card__foot{padding:12px 16px;border-block-start:1px solid var(--border);background:var(--surface-2);
  display:flex;gap:8px;align-items:center;flex-wrap:wrap}

.grid{display:grid;gap:14px}
.grid--stats{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}
.grid--2{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
.grid--3{grid-template-columns:repeat(auto-fit,minmax(260px,1fr))}
.grid--4{grid-template-columns:repeat(auto-fit,minmax(200px,1fr))}

.stat{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:14px 15px;display:flex;gap:12px;align-items:flex-start;
  box-shadow:var(--shadow-xs);transition:transform var(--t-fast),box-shadow var(--t-fast);
  position:relative;overflow:hidden;
}
.stat[role="button"],.stat.is-clickable{cursor:pointer}
.stat.is-clickable:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.stat::before{content:"";position:absolute;inset-block:0;inset-inline-start:0;inline-size:3px;background:var(--brand-500)}
.stat--ok::before{background:var(--ok-500)} .stat--warn::before{background:var(--warn-500)}
.stat--dang::before{background:var(--dang-500)} .stat--info::before{background:var(--info-500)}
.stat--purple::before{background:var(--purple-500)}
.stat__icon{
  inline-size:38px;block-size:38px;border-radius:10px;display:grid;place-items:center;
  background:var(--brand-50);color:var(--brand-600);flex:0 0 38px;
}
.stat__icon .icon{inline-size:19px;block-size:19px}
.stat--ok .stat__icon{background:var(--ok-50);color:var(--ok-600)}
.stat--warn .stat__icon{background:var(--warn-50);color:var(--warn-600)}
.stat--dang .stat__icon{background:var(--dang-50);color:var(--dang-600)}
.stat--info .stat__icon{background:var(--info-50);color:var(--info-600)}
.stat--purple .stat__icon{background:#f3eefe;color:var(--purple-500)}
.stat__body{min-inline-size:0;flex:1}
.stat__label{font-size:.76rem;color:var(--text-2);font-weight:600;letter-spacing:.01em}
.stat__value{font-size:1.5rem;font-weight:700;line-height:1.2;margin-block-start:2px;
  font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:plaintext;text-align:start}
.stat__hint{font-size:.72rem;color:var(--text-3);margin-block-start:2px}
.stat__delta{font-size:.72rem;font-weight:600}
.stat__delta--up{color:var(--ok-600)} .stat__delta--down{color:var(--dang-600)}

/* ------------------------------------------------------------- buttons --- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:7px;
  padding:8px 14px;border-radius:var(--r-sm);border:1px solid transparent;
  background:var(--brand-600);color:#fff;font-weight:600;font-size:.855rem;
  cursor:pointer;transition:all var(--t-fast);white-space:nowrap;text-decoration:none;
  line-height:1.3;
}
.btn:hover{background:var(--brand-700);text-decoration:none;box-shadow:var(--shadow-sm)}
.btn:active{transform:translateY(1px)}
.btn:disabled,.btn.is-disabled{opacity:.5;cursor:not-allowed;transform:none;box-shadow:none}
/* Inline icons have a viewBox but no intrinsic size, so they stretch to fill
   their container unless told otherwise. This is the single default; the
   component rules that follow are more specific and still win. */
.icon{inline-size:18px;block-size:18px;flex:0 0 auto}

.btn svg{inline-size:16px;block-size:16px;flex:0 0 16px}
.btn--ghost{background:transparent;color:var(--text-2);border-color:var(--border)}
.btn--ghost:hover{background:var(--surface-3);color:var(--text);border-color:var(--border-strong)}
.btn--soft{background:var(--brand-50);color:var(--brand-700);border-color:transparent}
.btn--soft:hover{background:var(--brand-100)}
.btn--danger{background:var(--dang-600)} .btn--danger:hover{background:var(--dang-700)}
.btn--ok{background:var(--ok-600)} .btn--ok:hover{background:var(--ok-700)}
.btn--warn{background:var(--warn-600)} .btn--warn:hover{background:var(--warn-700)}
.btn--dark{background:#334155} .btn--dark:hover{background:#1e293b}
.btn--sm{padding:5px 10px;font-size:.79rem;border-radius:var(--r-xs)}
.btn--sm svg{inline-size:14px;block-size:14px;flex-basis:14px}
.btn--lg{padding:11px 20px;font-size:.95rem}
.btn--icon{padding:7px;inline-size:34px;block-size:34px}
.btn--icon.btn--sm{inline-size:28px;block-size:28px;padding:5px}
.btn--block{inline-size:100%}
.btn-group{display:inline-flex;border-radius:var(--r-sm);overflow:hidden;border:1px solid var(--border)}
.btn-group .btn{border-radius:0;border:0;border-inline-end:1px solid var(--border)}
.btn-group .btn:last-child{border-inline-end:0}

/* --------------------------------------------------------------- forms --- */
.field{margin-block-end:13px}
.field__label{
  display:block;font-size:.79rem;font-weight:600;color:var(--text-2);margin-block-end:5px;
}
.field__label .req{color:var(--dang-500);margin-inline-start:2px}
.field__hint{font-size:.73rem;color:var(--text-3);margin-block-start:4px}
.field__error{font-size:.75rem;color:var(--dang-600);margin-block-start:4px;font-weight:500}
.input,.select,.textarea{
  inline-size:100%;padding:8px 11px;border:1px solid var(--border-strong);
  border-radius:var(--r-sm);background:var(--surface);color:var(--text);
  transition:border-color var(--t-fast),box-shadow var(--t-fast);font-size:.87rem;
}
.input:focus,.select:focus,.textarea:focus{
  outline:none;border-color:var(--brand-500);box-shadow:0 0 0 3px var(--brand-100);
}
.input:disabled,.select:disabled,.textarea:disabled{background:var(--surface-3);color:var(--text-3);cursor:not-allowed}
.input.is-invalid,.select.is-invalid{border-color:var(--dang-500);box-shadow:0 0 0 3px var(--dang-50)}
.textarea{min-block-size:76px;resize:vertical;line-height:1.5}
.select{
  appearance:none;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;padding-inline-end:30px;
}
html[dir="rtl"] .select{background-position:left 10px center;padding-inline-end:11px;padding-inline-start:30px}
.input[type="date"],.input[type="time"],.input[type="datetime-local"]{direction:ltr;text-align:start}
.form-row{display:grid;gap:12px;grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}
.form-row--2{grid-template-columns:repeat(auto-fit,minmax(240px,1fr))}
.form-row--3{grid-template-columns:repeat(3,1fr)}
.checkbox,.radio{display:inline-flex;align-items:center;gap:8px;cursor:pointer;font-size:.86rem;user-select:none}
.checkbox input,.radio input{inline-size:16px;block-size:16px;accent-color:var(--brand-600);cursor:pointer;margin:0}
/* Print options read as a checklist, one decision per line. */
.print-opts{display:flex;flex-direction:column;gap:9px}
.print-opt{align-items:flex-start;line-height:1.45}
.print-opt input{margin-block-start:2px;flex:0 0 16px}
.switch{position:relative;display:inline-flex;align-items:center;gap:9px;cursor:pointer;font-size:.86rem}
.switch input{position:absolute;opacity:0;pointer-events:none}
.switch__track{
  inline-size:38px;block-size:21px;border-radius:99px;background:var(--border-strong);
  transition:background var(--t-fast);position:relative;flex:0 0 38px;
}
.switch__track::after{
  content:"";position:absolute;inset-block-start:2px;inset-inline-start:2px;
  inline-size:17px;block-size:17px;border-radius:50%;background:#fff;
  transition:transform var(--t-fast);box-shadow:var(--shadow-xs);
}
.switch input:checked + .switch__track{background:var(--brand-500)}
.switch input:checked + .switch__track::after{transform:translateX(17px)}
html[dir="rtl"] .switch input:checked + .switch__track::after{transform:translateX(-17px)}
.input-group{display:flex;align-items:stretch}
.input-group .input{border-start-end-radius:0;border-end-end-radius:0}
.input-group__addon{
  display:flex;align-items:center;padding:0 11px;background:var(--surface-3);
  border:1px solid var(--border-strong);border-inline-start:0;
  border-start-end-radius:var(--r-sm);border-end-end-radius:var(--r-sm);
  font-size:.82rem;color:var(--text-2);white-space:nowrap;
}

/* -------------------------------------------------------------- tables --- */
.table-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
table.table{inline-size:100%;border-collapse:collapse;font-size:.85rem}
.table th{
  text-align:start;padding:10px 12px;background:var(--surface-2);color:var(--text-2);
  font-weight:650;font-size:.75rem;text-transform:uppercase;letter-spacing:.04em;
  border-block-end:1px solid var(--border);white-space:nowrap;position:sticky;inset-block-start:0;z-index:2;
}
.table th.sortable{cursor:pointer;user-select:none}
.table th.sortable:hover{color:var(--brand-600)}
.table td{padding:9px 12px;border-block-end:1px solid var(--border);vertical-align:middle}
.table tbody tr{transition:background var(--t-fast)}
.table tbody tr:hover{background:var(--surface-2)}
.table tbody tr.is-clickable{cursor:pointer}
.table tbody tr.is-selected{background:var(--brand-50)}
.table--compact td{padding:6px 10px} .table--compact th{padding:7px 10px}
.table__empty{text-align:center;padding:44px 20px;color:var(--text-3)}
.table td.num,.table th.num{text-align:end;font-variant-numeric:tabular-nums;direction:ltr;unicode-bidi:plaintext}
html[dir="rtl"] .table td.num,html[dir="rtl"] .table th.num{text-align:start}
.table .col-actions{inline-size:1%;white-space:nowrap;text-align:end}
.row-actions{display:inline-flex;gap:4px}

.pagination{
  display:flex;align-items:center;gap:8px;justify-content:space-between;
  padding:11px 14px;border-block-start:1px solid var(--border);flex-wrap:wrap;
  background:var(--surface-2);font-size:.82rem;color:var(--text-2);
}
.pagination__pages{display:flex;gap:4px;align-items:center}
.page-btn{
  min-inline-size:30px;block-size:30px;border:1px solid var(--border);background:var(--surface);
  border-radius:var(--r-xs);cursor:pointer;font-size:.8rem;color:var(--text-2);
  display:inline-flex;align-items:center;justify-content:center;padding:0 7px;
}
.page-btn:hover:not(:disabled){border-color:var(--brand-400);color:var(--brand-600)}
.page-btn.is-active{background:var(--brand-600);color:#fff;border-color:var(--brand-600);font-weight:600}
.page-btn:disabled{opacity:.4;cursor:not-allowed}

/* -------------------------------------------------------------- badges --- */
.badge{
  display:inline-flex;align-items:center;gap:4px;padding:2px 9px;border-radius:var(--r-full);
  font-size:.735rem;font-weight:650;background:var(--surface-3);color:var(--text-2);
  white-space:nowrap;line-height:1.6;
}
.badge--ok{background:var(--ok-50);color:var(--ok-700)}
.badge--warn{background:var(--warn-50);color:var(--warn-700)}
.badge--dang{background:var(--dang-50);color:var(--dang-700)}
.badge--info{background:var(--info-50);color:var(--info-600)}
.badge--brand{background:var(--brand-50);color:var(--brand-700)}
.badge--purple{background:#f3eefe;color:#6d28d9}
.badge--outline{background:transparent;border:1px solid var(--border-strong)}
.badge__dot{inline-size:6px;block-size:6px;border-radius:50%;background:currentColor;flex:0 0 6px}
.badge--pulse .badge__dot{animation:pulse 1.6s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}

.flag{font-weight:700;font-size:.78rem;padding:1px 6px;border-radius:5px;display:inline-block;min-inline-size:26px;text-align:center}
.flag--H{background:var(--warn-50);color:var(--warn-700)}
.flag--L{background:var(--info-50);color:var(--info-600)}
.flag--HH{background:var(--dang-600);color:#fff}
.flag--LL{background:var(--dang-600);color:#fff}
.flag--A{background:var(--dang-50);color:var(--dang-700)}
.flag--N{background:var(--ok-50);color:var(--ok-700)}

/* -------------------------------------------------------------- modals --- */
.modal-backdrop{
  position:fixed;inset:0;background:rgba(15,23,42,.55);backdrop-filter:blur(3px);
  display:flex;align-items:center;justify-content:center;z-index:200;padding:18px;
  animation:fade var(--t) both;
}
@keyframes fade{from{opacity:0}to{opacity:1}}
@keyframes slideUp{from{opacity:0;transform:translateY(14px) scale(.985)}to{opacity:1;transform:none}}
.modal{
  background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-xl);
  inline-size:min(600px,100%);max-block-size:92vh;display:flex;flex-direction:column;
  animation:slideUp var(--t) both;
}
.modal--lg{inline-size:min(900px,100%)}
.modal--xl{inline-size:min(1200px,100%)}
.modal--sm{inline-size:min(420px,100%)}
.modal__head{
  padding:15px 18px;border-block-end:1px solid var(--border);display:flex;
  align-items:center;gap:10px;
}
.modal__head h3{flex:1;font-size:1.05rem}
.modal__body{padding:18px;overflow-y:auto;flex:1}
.modal__foot{
  padding:13px 18px;border-block-start:1px solid var(--border);display:flex;
  gap:9px;justify-content:flex-end;background:var(--surface-2);flex-wrap:wrap;
}
.modal__close{
  background:transparent;border:0;cursor:pointer;color:var(--text-3);padding:5px;
  border-radius:var(--r-xs);display:grid;place-items:center;
}
.modal__close:hover{background:var(--surface-3);color:var(--text)}

/* -------------------------------------------------------------- toasts --- */
.toasts{
  position:fixed;inset-block-end:20px;inset-inline-end:20px;z-index:400;
  display:flex;flex-direction:column;gap:9px;max-inline-size:400px;
}
.toast{
  background:var(--surface);border:1px solid var(--border);border-inline-start:3px solid var(--brand-500);
  border-radius:var(--r-sm);box-shadow:var(--shadow-lg);padding:11px 14px;
  display:flex;gap:10px;align-items:flex-start;animation:slideIn var(--t) both;
}
@keyframes slideIn{from{opacity:0;transform:translateX(24px)}to{opacity:1;transform:none}}
html[dir="rtl"] .toast{animation-name:slideInRtl}
@keyframes slideInRtl{from{opacity:0;transform:translateX(-24px)}to{opacity:1;transform:none}}
.toast--ok{border-inline-start-color:var(--ok-500)}
.toast--warn{border-inline-start-color:var(--warn-500)}
.toast--error{border-inline-start-color:var(--dang-500)}
.toast__icon{flex:0 0 18px;margin-block-start:1px}
.toast--ok .toast__icon{color:var(--ok-600)}
.toast--warn .toast__icon{color:var(--warn-600)}
.toast--error .toast__icon{color:var(--dang-600)}
.toast__body{flex:1;min-inline-size:0}
.toast__title{font-weight:650;font-size:.86rem}
.toast__msg{font-size:.8rem;color:var(--text-2);word-break:break-word}

/* --------------------------------------------------------------- misc ---- */
.spinner{
  inline-size:18px;block-size:18px;border:2px solid var(--border-strong);
  border-block-start-color:var(--brand-500);border-radius:50%;animation:spin .7s linear infinite;
}
@keyframes spin{to{transform:rotate(360deg)}}
.spinner--lg{inline-size:34px;block-size:34px;border-width:3px}
.loading-box{display:grid;place-items:center;padding:56px;gap:12px;color:var(--text-3);font-size:.85rem}
.skeleton{background:linear-gradient(90deg,var(--surface-3) 25%,var(--surface-2) 50%,var(--surface-3) 75%);
  background-size:200% 100%;animation:shimmer 1.4s infinite;border-radius:var(--r-xs)}
@keyframes shimmer{to{background-position:-200% 0}}

.empty{display:grid;place-items:center;gap:10px;padding:48px 20px;text-align:center;color:var(--text-3)}
.empty__icon{inline-size:52px;block-size:52px;opacity:.35}
.empty__title{font-weight:650;color:var(--text-2);font-size:.95rem}

.tabs{display:flex;gap:2px;border-block-end:1px solid var(--border);overflow-x:auto;scrollbar-width:none}
.tabs::-webkit-scrollbar{display:none}
.tab{
  padding:9px 15px;cursor:pointer;font-size:.86rem;font-weight:600;color:var(--text-2);
  border-block-end:2px solid transparent;white-space:nowrap;background:none;border-inline:0;border-block-start:0;
}
.tab:hover{color:var(--brand-600)}
.tab.is-active{color:var(--brand-700);border-block-end-color:var(--brand-600)}

.chip{
  display:inline-flex;align-items:center;gap:6px;padding:4px 11px;border-radius:var(--r-full);
  background:var(--surface-3);font-size:.79rem;border:1px solid transparent;cursor:pointer;
  transition:all var(--t-fast);color:var(--text-2);
}
.chip:hover{background:var(--border)}
.chip.is-active{background:var(--brand-600);color:#fff;font-weight:600}
.chip__x{cursor:pointer;opacity:.6;display:inline-flex} .chip__x:hover{opacity:1}

.toolbar{
  display:flex;gap:9px;align-items:center;flex-wrap:wrap;padding:11px 14px;
  border-block-end:1px solid var(--border);background:var(--surface-2);
}
.toolbar .input,.toolbar .select{inline-size:auto;min-inline-size:130px}
.toolbar__spacer{flex:1}

.search-box{position:relative;flex:1;min-inline-size:180px;max-inline-size:400px}
.search-box .input{padding-inline-start:34px}
.search-box__icon{
  position:absolute;inset-inline-start:10px;inset-block-start:50%;transform:translateY(-50%);
  color:var(--text-3);pointer-events:none;display:flex;
}
.search-box__icon .icon{inline-size:16px;block-size:16px}
html[dir="rtl"] .search-box .input{padding-inline-start:11px;padding-inline-end:34px}

.dropdown{position:relative}
.dropdown__menu{
  position:absolute;inset-block-start:calc(100% + 6px);inset-inline-end:0;background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r);box-shadow:var(--shadow-lg);
  min-inline-size:210px;padding:5px;z-index:100;animation:slideUp var(--t-fast) both;
  max-block-size:70vh;overflow-y:auto;
}
.dropdown__item{
  display:flex;align-items:center;gap:9px;padding:8px 11px;border-radius:var(--r-xs);
  cursor:pointer;font-size:.85rem;color:var(--text);white-space:nowrap;
}
.dropdown__item:hover{background:var(--surface-3);text-decoration:none}
.dropdown__item.is-active{background:var(--brand-50);color:var(--brand-700);font-weight:600}
.dropdown__divider{block-size:1px;background:var(--border);margin:5px 0}
.dropdown__label{font-size:.7rem;text-transform:uppercase;letter-spacing:.06em;color:var(--text-3);padding:6px 11px 3px;font-weight:700}

.avatar{
  inline-size:33px;block-size:33px;border-radius:50%;background:var(--brand-500);color:#fff;
  display:grid;place-items:center;font-weight:700;font-size:.8rem;flex:0 0 33px;text-transform:uppercase;
}
.avatar--sm{inline-size:26px;block-size:26px;flex-basis:26px;font-size:.68rem}
.avatar--lg{inline-size:52px;block-size:52px;flex-basis:52px;font-size:1.15rem}

.divider{block-size:1px;background:var(--border);margin:14px 0;border:0}
.section-title{
  font-size:.75rem;text-transform:uppercase;letter-spacing:.07em;color:var(--text-3);
  font-weight:700;margin-block:16px 8px;
  display:flex;align-items:center;gap:7px;
}
.section-title .icon{inline-size:15px;block-size:15px;color:var(--brand-500)}
.kv{display:grid;grid-template-columns:auto 1fr;gap:6px 14px;font-size:.85rem;align-items:baseline}
.kv dt{color:var(--text-2);font-weight:600}
.kv dd{margin:0;color:var(--text)}

.alert{
  padding:11px 14px;border-radius:var(--r-sm);font-size:.85rem;display:flex;gap:10px;
  align-items:flex-start;border:1px solid transparent;
}
.alert--info{background:var(--info-50);color:var(--info-600);border-color:#bfdbfe}
.alert--ok{background:var(--ok-50);color:var(--ok-700);border-color:#a7f3d0}
.alert--warn{background:var(--warn-50);color:var(--warn-700);border-color:#fde68a}
.alert--dang{background:var(--dang-50);color:var(--dang-700);border-color:#fecaca}
.alert__icon{flex:0 0 18px;margin-block-start:1px}

.progress{block-size:6px;background:var(--surface-3);border-radius:99px;overflow:hidden}
.progress__bar{block-size:100%;background:var(--brand-500);transition:inline-size var(--t)}

.text-muted{color:var(--text-2)} .text-dim{color:var(--text-3)}
.text-ok{color:var(--ok-600)} .text-warn{color:var(--warn-600)} .text-dang{color:var(--dang-600)}
.text-brand{color:var(--brand-600)}
.text-sm{font-size:.8rem} .text-xs{font-size:.73rem} .text-lg{font-size:1.05rem}
.fw-6{font-weight:600} .fw-7{font-weight:700}
.text-center{text-align:center} .text-end{text-align:end} .text-start{text-align:start}
.nowrap{white-space:nowrap}
.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.flex{display:flex} .flex-col{flex-direction:column} .items-center{align-items:center}
.items-start{align-items:flex-start} .justify-between{justify-content:space-between}
.justify-center{justify-content:center} .justify-end{justify-content:flex-end}
.gap-1{gap:4px} .gap-2{gap:8px} .gap-3{gap:12px} .gap-4{gap:16px}
.flex-1{flex:1} .flex-wrap{flex-wrap:wrap} .w-full{inline-size:100%}
.mt-0{margin-block-start:0} .mt-1{margin-block-start:6px} .mt-2{margin-block-start:12px}
.mt-3{margin-block-start:18px} .mb-1{margin-block-end:6px} .mb-2{margin-block-end:12px}
.mb-3{margin-block-end:18px} .p-0{padding:0} .p-2{padding:12px} .p-3{padding:18px}
.hidden{display:none}

/* --------------------------------------------------------------- login --- */
.login-page{
  min-block-size:100vh;display:grid;grid-template-columns:1fr;place-items:center;
  background:
    radial-gradient(1200px 600px at 15% -10%, rgba(18,138,131,.28), transparent 60%),
    radial-gradient(900px 500px at 110% 110%, rgba(37,99,235,.22), transparent 55%),
    linear-gradient(160deg,#0c1a2b,#0f2c2b 55%,#0b1220);
  padding:20px;position:relative;overflow:hidden;
}
.login-page::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px, rgba(255,255,255,.06) 1px, transparent 0);
  background-size:26px 26px;
}
.login-card{
  inline-size:min(430px,100%);background:var(--surface);border-radius:var(--r-xl);
  box-shadow:0 30px 70px rgba(0,0,0,.4);padding:32px;position:relative;z-index:1;
}
.login-logo{
  inline-size:60px;block-size:60px;border-radius:17px;margin-inline:auto;
  background:linear-gradient(135deg,var(--brand-400),var(--brand-700));
  display:grid;place-items:center;color:#fff;font-weight:800;font-size:1.4rem;
  box-shadow:0 8px 22px rgba(13,111,106,.4);
}
.login-title{text-align:center;margin-block-start:14px;font-size:1.35rem}
.login-sub{text-align:center;color:var(--text-2);font-size:.83rem;margin-block-end:22px}
.lang-switch{display:flex;gap:6px;justify-content:center;margin-block-end:20px}
.lang-btn{
  padding:5px 13px;border-radius:var(--r-full);border:1px solid var(--border);
  background:var(--surface);cursor:pointer;font-size:.8rem;color:var(--text-2);font-weight:600;
}
.lang-btn.is-active{background:var(--brand-600);color:#fff;border-color:var(--brand-600)}
.login-foot{text-align:center;margin-block-start:20px;font-size:.74rem;color:var(--text-3)}

/* ------------------------------------------------------------ responsive - */
.mobile-toggle{display:none}
@media (max-width:1024px){
  .sidebar{
    position:fixed;inset-block:0;inset-inline-start:0;transform:translateX(-100%);
    transition:transform var(--t);box-shadow:var(--shadow-xl);
  }
  html[dir="rtl"] .sidebar{inset-inline-start:auto;inset-inline-end:0;transform:translateX(100%)}
  .sidebar.is-open{transform:translateX(0)}
  .mobile-toggle{display:inline-flex}
  .sidebar-scrim{position:fixed;inset:0;background:rgba(15,23,42,.5);z-index:39}
}
@media (max-width:768px){
  .content{padding:12px}
  .grid--stats{grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px}
  .stat{padding:11px} .stat__value{font-size:1.25rem}
  .page-head h1{font-size:1.2rem}
  .toasts{inset-inline:12px;inset-block-end:12px;max-inline-size:none}
  .modal{max-block-size:96vh}
  .topbar{padding-inline:10px;gap:8px}
}

/* The header carries nine controls, which will not fit on a phone. Below this
   width each keeps its icon and drops its label, and search moves into the
   menu panel, which already has its own. */
@media (max-width:820px){
  .topbar{gap:6px}
  .topbar > .search-box{display:none}
  .topbar__brandtext{display:none}
  #branchDd .truncate,#langDd span:not(.icon),#userDd .truncate{display:none}
  #branchDd .btn,#langDd .btn,#userDd .btn{padding-inline:8px}
  #megaBtn span{display:none}
  #megaBtn{padding-inline:10px}
}
@media print{
  .sidebar,.topbar,.page-actions,.toolbar,.pagination,.toasts,.no-print{display:none !important}
  .content{padding:0} body{background:#fff}
  .card{border:0;box-shadow:none}
}

/* ===========================================================================
   Additions used by the analyzer, finance, inventory and public screens.
   Aliases keep older class names working in both light and dark themes,
   because `var()` resolves in the context where it is used.
   =========================================================================== */
:root {
  --text-dim: var(--text-3);
  --border-soft: var(--border);
  --danger-600: var(--dang-600);
  --danger-300: var(--dang-500);
}

/* Row that needs attention (low stock, expired batch, rejected sample) */
.table tbody tr.is-danger { background: color-mix(in srgb, var(--dang-500) 7%, transparent); }
.table tbody tr.is-danger:hover { background: color-mix(in srgb, var(--dang-500) 12%, transparent); }

/* Connection indicator for analyzers and gateways */
.status-dot {
  width: 9px; height: 9px; border-radius: 50%; flex: 0 0 9px;
  background: var(--text-3); box-shadow: 0 0 0 3px color-mix(in srgb, var(--text-3) 18%, transparent);
}
.status-dot--ok   { background: var(--ok-500);   box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok-500) 22%, transparent); }
.status-dot--info { background: var(--accent-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent-500) 22%, transparent); }
.status-dot--warn { background: var(--warn-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn-500) 22%, transparent); }
.status-dot--dang { background: var(--dang-500); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dang-500) 22%, transparent); }
.status-dot--off  { background: var(--text-3);  box-shadow: none; opacity: .55; }

/* `alert--danger` is the spelling used by the newer screens */
.alert--danger {
  background: var(--dang-50);
  border-color: color-mix(in srgb, var(--dang-500) 35%, transparent);
  color: var(--dang-700);
}

/* Tab strips that can overflow on narrow screens (Settings) */
.tabs--scroll { overflow-x: auto; scrollbar-width: thin; }
.tabs--scroll::-webkit-scrollbar { height: 4px; }
.tabs--scroll .tab { white-space: nowrap; }

/* ---------------------------------------------------------------- messages */
.msg-list { display: flex; flex-direction: column; }
.msg-row {
  display: flex; gap: 12px; padding: 12px 14px; cursor: pointer;
  border-block-end: 1px solid var(--border); transition: background var(--t-fast);
}
.msg-row:last-child { border-block-end: 0 }
.msg-row:hover { background: var(--surface-2) }
/* An unread message is marked down its leading edge, which stays correct in
   both directions rather than always sitting on the left. */
.msg-row.is-unread { background: var(--brand-50); box-shadow: inset 3px 0 0 0 var(--brand-500) }
html[dir="rtl"] .msg-row.is-unread { box-shadow: inset -3px 0 0 0 var(--brand-500) }
.msg-row__main { flex: 1; min-inline-size: 0 }
.msg-row__head { display: flex; align-items: center; gap: 7px; flex-wrap: wrap }
.msg-row__from { font-weight: 700; font-size: .87rem }
.msg-row__subject { font-weight: 600; margin-block-start: 2px; font-size: .87rem }
.msg-row__preview {
  color: var(--text-2); font-size: .82rem; margin-block-start: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.msg-row__meta { text-align: end; flex: 0 0 auto; display: flex; flex-direction: column; gap: 3px }

.msg-people {
  max-block-size: 240px; overflow-y: auto; border: 1px solid var(--border);
  border-radius: var(--r-xs); margin-block-start: 6px;
}
.msg-person {
  display: flex; align-items: center; gap: 9px; padding: 7px 10px; cursor: pointer;
  border-block-end: 1px solid var(--border); font-size: .85rem;
}
.msg-person:last-child { border-block-end: 0 }
.msg-person:hover { background: var(--surface-2) }
.msg-person.is-on { background: var(--brand-50) }
.msg-person__name { font-weight: 600 }
.msg-person__role { color: var(--text-3); font-size: .76rem; margin-inline-start: auto }

.msg-thread { display: flex; flex-direction: column; gap: 10px }
.msg-bubble { padding: 10px 12px; border-radius: var(--r); background: var(--surface-2) }
.msg-bubble.is-mine { background: var(--brand-50) }
.msg-bubble__head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-block-end: 5px }
.msg-bubble__body { white-space: pre-wrap; line-height: 1.6; font-size: .88rem }
.msg-readers { margin-block-start: 14px }
.msg-reader {
  display: flex; align-items: center; justify-content: space-between;
  padding: 5px 0; border-block-end: 1px solid var(--border); font-size: .84rem;
}

/* ---- Price list grid --------------------------------------------------- */
/* A price cell that no longer matches what was loaded, so the row is easy to
   find before saving. */
.input--sm{padding-block:4px;padding-inline:8px;font-size:.86rem}
.input.is-dirty{
  border-color:var(--brand-500);
  background:var(--brand-50);
  font-weight:700;
}

/* ---- Navigation picker (Settings → Navigation) ------------------------- */
.nav-pick{display:grid;gap:2px}
.nav-pick__row{
  display:flex;align-items:center;gap:10px;
  padding:7px 8px;border-radius:8px;cursor:pointer;
}
.nav-pick__row:hover{background:var(--surface-2)}
.nav-pick__row input{position:absolute;opacity:0;pointer-events:none}
.nav-pick__name{font-weight:600}
/* The path is a reminder that a hidden entry is only hidden, not gone. */
.nav-pick__path{margin-inline-start:auto;opacity:.6}
@media (max-width:640px){ .nav-pick__path{display:none} }

/* ---- Sidebar folding, group counts, extras group ----------------------- */
/* The fold button belongs to the desktop: on a phone the menu is a drawer and
   the hamburger already opens it. */
.desk-only{display:inline-flex}
@media (max-width:1024px){ .desk-only{display:none} }

/* A folded menu also drops the pieces that only make sense at full width. */
.sidebar.is-collapsed .sidebar__user-text,
.sidebar.is-collapsed .sidebar__user-icon,
.sidebar.is-collapsed .sidebar__filter,
.sidebar.is-collapsed .sidebar__live,
.sidebar.is-collapsed .nav-group__count{display:none}
.sidebar.is-collapsed .sidebar__user{justify-content:center;padding-inline:0}
.sidebar.is-collapsed .sidebar__brand{justify-content:center}

/* How many entries a group holds — used by the extras group, which is long. */
.nav-group__count{
  font-size:.62rem;font-weight:700;padding:1px 6px;border-radius:99px;
  background:rgba(255,255,255,.12);color:inherit;
}

/* Static section headings: same row as the foldable kind, minus the control. */
.nav-group__label--static{
  display:flex;align-items:center;gap:6px;inline-size:100%;
  text-align:start;cursor:default;
}

/* ---- Live alerts -------------------------------------------------------- */
/* Arrivals from elsewhere in the laboratory. They stack away from the toasts
   so a confirmation of your own action never covers an instrument's delivery. */
.alerts{
  position:fixed;inset-block-start:calc(var(--topbar-h) + 18px);inset-inline-end:18px;
  z-index:60;display:flex;flex-direction:column;gap:10px;
  inline-size:min(370px,calc(100vw - 32px));pointer-events:none;
}
.alert-card{
  pointer-events:auto;
  display:flex;gap:11px;align-items:flex-start;
  padding:13px 14px;border-radius:var(--r);
  background:var(--surface);border:1px solid var(--border);
  border-inline-start:3px solid var(--info-500);
  box-shadow:var(--shadow-lg);
  animation:alertIn 220ms cubic-bezier(.2,.9,.3,1) both;
}
.alert-card.is-leaving{opacity:0;transform:translateY(-6px);transition:opacity .2s,transform .2s}
@keyframes alertIn{from{opacity:0;transform:translateY(-10px) scale(.98)}to{opacity:1;transform:none}}

.alert-card__icon{flex:0 0 auto;display:grid;place-items:center;
  inline-size:32px;block-size:32px;border-radius:9px;
  background:var(--info-50);color:var(--info-600)}
.alert-card__body{flex:1;min-inline-size:0}
.alert-card__title{font-weight:700;font-size:.9rem;line-height:1.3}
.alert-card__text{font-size:.8rem;color:var(--text-2);margin-block-start:2px;
  overflow-wrap:anywhere}
.alert-card__link{display:inline-block;margin-block-start:7px;font-size:.78rem;font-weight:600}
.alert-card__close{
  flex:0 0 auto;background:none;border:0;cursor:pointer;color:var(--text-3);
  padding:2px;border-radius:6px;line-height:0;
}
.alert-card__close:hover{color:var(--text)}

.alert-card--success{border-inline-start-color:var(--ok-500)}
.alert-card--success .alert-card__icon{background:var(--ok-50);color:var(--ok-600)}
.alert-card--warn{border-inline-start-color:var(--warn-500)}
.alert-card--warn .alert-card__icon{background:var(--warn-50);color:var(--warn-600)}
/* A critical value does not time out and does not blend in. */
.alert-card--critical{border-inline-start-color:var(--dang-500)}
.alert-card--critical .alert-card__icon{background:var(--dang-50);color:var(--dang-600)}
.alert-card--critical .alert-card__title{color:var(--dang-600)}

@media (max-width:640px){
  .alerts{inset-inline:12px;inline-size:auto;inset-block-start:calc(var(--topbar-h) + 8px)}
}
@media (prefers-reduced-motion:reduce){ .alert-card{animation:none} }

/* ---- List page chrome --------------------------------------------------- */
/* The heading carries the icon that stands for the screen, and the trail back
   to the front page, so a screen reached from anywhere still says where it is. */
.page-head__title{display:flex;align-items:center;gap:10px}
.page-head__badge{
  display:grid;place-items:center;inline-size:36px;block-size:36px;
  border-radius:10px;background:var(--brand-50);color:var(--brand-600);flex:0 0 auto;
}
.crumbs{
  display:flex;align-items:center;gap:6px;flex-wrap:wrap;
  font-size:.76rem;color:var(--text-3);
  padding:5px 11px;border:1px solid var(--border);border-radius:var(--r-full);
  background:var(--surface);align-self:center;
}
.crumbs__link{color:var(--text-2);text-decoration:none}
.crumbs__link:hover{color:var(--brand-600)}
.crumbs__sep{opacity:.5}
.crumbs__here{color:var(--text);font-weight:600}
@media (max-width:820px){ .crumbs{display:none} }

/* Row count and the take-it-with-you buttons sit with the filters. */
.toolbar__field{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.toolbar__label{font-size:.76rem;color:var(--text-3)}
.select--sm{padding-block:4px;padding-inline:8px;font-size:.82rem;width:auto;min-inline-size:64px}
.export-bar{display:inline-flex;align-items:center;gap:4px;flex-wrap:wrap}

/* The tick column and the row number stay narrow and quiet. */
.col-pick{inline-size:38px}
.col-pick input{cursor:pointer}
.col-no{inline-size:52px;font-variant-numeric:tabular-nums}

/* Row actions read as deliberate buttons, not faint glyphs.
   Toned by what the button does rather than by a class each page remembers to
   add, so an action a screen adds for itself is dressed the same as the two
   every list has. */
.row-actions{display:inline-flex;gap:5px;align-items:center}
.row-actions .btn{
  border:1px solid transparent;
  inline-size:30px;block-size:28px;
  border-radius:8px;
  background:var(--surface-3);
  color:var(--text-2);
}
.row-actions .btn:hover{background:var(--border-strong);color:var(--text)}
.row-actions .btn[data-edit]{background:var(--brand-500);color:#fff}
.row-actions .btn[data-edit]:hover{background:var(--brand-600);color:#fff}
.row-actions .btn[data-del]{background:var(--dang-600);color:#fff}
.row-actions .btn[data-del]:hover{background:var(--dang-700);color:#fff}
.row-act--edit{background:var(--brand-500);color:#fff}
.row-act--del{background:var(--dang-600);color:#fff}

/* A person's name is what the eye hunts for down a long table, so it is set
   apart from the codes and figures around it rather than blending in. */
.name-pill{
  display:inline-block;max-inline-size:100%;
  padding:4px 11px;border-radius:var(--r-full);
  background:var(--surface-3);border:1px solid var(--border);
  font-weight:700;font-size:.82rem;line-height:1.3;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;vertical-align:middle;
}

/* ---- Report tools ------------------------------------------------------- */
/* Nine small buttons per row, wrapped into a block rather than a long line, so
   the column stays narrow and every tool is still one click away. */
.tools{display:flex;flex-wrap:wrap;gap:4px;max-inline-size:156px}
.tools .btn{
  inline-size:28px;block-size:26px;border-radius:7px;
  border:1px solid transparent;color:#fff;
}
.tools .tool--brand{background:var(--brand-500)}   .tools .tool--brand:hover{background:var(--brand-600);color:#fff}
.tools .tool--slate{background:var(--surface-3);color:var(--text-2)}
.tools .tool--slate:hover{background:var(--border-strong);color:var(--text)}
.tools .tool--dang{background:var(--dang-600)}     .tools .tool--dang:hover{background:var(--dang-700);color:#fff}
.tools .tool--ok{background:var(--ok-600)}         .tools .tool--ok:hover{background:var(--ok-700);color:#fff}
.tools .tool--warn{background:var(--warn-600)}     .tools .tool--warn:hover{background:var(--warn-700);color:#fff}
.tools .tool--purple{background:var(--purple-500)} .tools .tool--purple:hover{filter:brightness(.92);color:#fff}
.tools .tool--plain{background:var(--surface-3);color:var(--text-2)}

/* ---- Report state pill -------------------------------------------------- */
/* The state doubles as the control that changes it, so it looks pressable —
   and carries a small mark when a person, not the work, decided it. */
.status-pill{
  display:inline-flex;align-items:center;gap:6px;
  padding:6px 12px;border-radius:var(--r-full);
  border:1px solid transparent;cursor:pointer;
  font-weight:700;font-size:.78rem;color:#fff;
  font-family:inherit;white-space:nowrap;
  transition:filter var(--t-fast),transform var(--t-fast);
}
.status-pill:hover:not(:disabled){filter:brightness(1.08);transform:translateY(-1px)}
.status-pill:disabled{cursor:default}
.status-pill .icon{inline-size:14px;block-size:14px}
.status-pill--warn{background:var(--warn-600)}
.status-pill--info{background:var(--brand-500)}
.status-pill--danger{background:var(--dang-600)}
.status-pill--ok{background:var(--ok-600)}
.status-pill__manual{
  margin-inline-start:2px;opacity:.85;font-size:.72rem;
  border-inline-start:1px solid rgba(255,255,255,.35);padding-inline-start:6px;
}

/* ---- Wide tables: keep the actions reachable ---------------------------- */
/* A row of a dozen columns pushes its buttons off the side of the screen, and
   a button you have to go looking for may as well not be there. The tools
   column is pinned to the edge the table scrolls away from, so it is in reach
   at every scroll position. */
.col-tools{
  position:sticky;inset-inline-end:0;z-index:2;
  background:var(--surface);
  /* Wide enough for a row of five, so a full toolbox is two rows and not five.
     A width attribute alone loses the argument with the other columns. */
  min-inline-size:186px;
}
.table tbody tr:hover .col-tools{background:var(--surface-2)}
.table thead .col-tools{background:var(--surface-2)}
/* A hairline marks it as pinned rather than merely last. */
.col-tools::before{
  content:"";position:absolute;inset-block:0;inset-inline-start:0;
  inline-size:1px;background:var(--border);
}
/* The columns a bench can do without when the screen is not wide enough for
   all of them. Nothing is lost: the export and the invoice still carry them. */
@media (max-width:1500px){ .col-wide{display:none} }

/* ---- Signature pad ------------------------------------------------------ */
/* Ink is black on white wherever it is drawn, because that is where it ends
   up: on a printed report, not on this screen. */
.sig__preview,.sig__pad{
  inline-size:100%;block-size:120px;border-radius:var(--r);
  border:1px dashed var(--border-strong);background:#fff;
  display:grid;place-items:center;
}
.sig__preview img{max-block-size:104px;max-inline-size:96%;object-fit:contain}
.sig__pad{cursor:crosshair;touch-action:none;display:block}

/* Chosen work on the invoice, grouped the way the sheet is read. */
.pick-group + .pick-group{margin-block-start:14px}
.pick-group .section-title{display:flex;align-items:center;gap:8px}
