/* ==========================================================================
   Clino design system.
   Loaded AFTER Vuexy's core.css / theme-default.css, and works by retheming
   them rather than replacing them: Bootstrap 5 reads its colours from --bs-*
   custom properties, so overriding those tokens re-skins every button, badge,
   table and form control the existing pages already use. Nothing had to be
   rewritten to adopt this file.

   Structure
     1. Font
     2. Tokens (light)      -- the complete palette lives here
     3. Tokens (dark)       -- redefines ONLY the tokens
     4. Bootstrap bridge    -- maps our tokens onto --bs-*
     5. Layout: shell, sidebar, drawer, topbar
     6. Components: KPI, cards, tables, chips, heatmap, filters, states
     7. Utilities

   Dark mode is driven by [data-theme] on <html>, set by clino-shell.js from
   the user's saved choice or their OS preference. Every colour below is a
   token so the two themes cannot drift apart -- a literal hex inside a
   component rule is the bug this structure exists to prevent.
   ========================================================================== */

/* -- 1. Font ------------------------------------------------------------- */
/* Bundled locally, deliberately NOT loaded from Google Fonts: this product is
   deployed for clinics in Iran, where that host is unreliable, and a
   dashboard whose Persian text falls back to Tahoma mid-load looks broken.
   The variable font covers every weight in one 109 KB request. */
@font-face {
  font-family: "Vazirmatn";
  src: url("../fonts/vazirmatn/Vazirmatn-Variable.woff2") format("woff2-variations"),
       url("../fonts/vazirmatn/Vazirmatn-Regular.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
}

:root {
  --clino-font: "Vazirmatn", "Segoe UI", Tahoma, "Iranian Sans", sans-serif;
  /* Digits, device IDs and serial numbers stay Latin and monospaced. */
  --clino-mono: "SFMono-Regular", ui-monospace, "Cascadia Mono", Consolas, monospace;
}

/* -- 2. Tokens: light ---------------------------------------------------- */
:root {
  /* Brand. A blue-teal rather than a corporate blue: it reads as clinical
     without reading as a hospital IT system, and it stays legible as a chart
     stroke on both grounds. */
  --c-primary:        #0e7490;
  --c-primary-strong: #0b5c72;
  --c-primary-soft:   #e0f2f7;
  --c-primary-line:   #b6e0ea;

  /* Semantic. Fixed meanings across the whole app: green is "as expected",
     amber is "needs a look", red is "acted on now". Never decorative. */
  --c-success:      #15803d;
  --c-success-soft: #e4f4ea;
  --c-warning:      #b45309;
  --c-warning-soft: #fdf1de;
  --c-danger:       #b91c1c;
  --c-danger-soft:  #fbe9e9;
  --c-info:         var(--c-primary);
  --c-info-soft:    var(--c-primary-soft);

  /* Neutrals, biased very slightly cool so they sit with the brand rather
     than fighting it. */
  --c-bg:        #f4f7f9;
  --c-surface:   #ffffff;
  --c-surface-2: #eef3f6;
  --c-ink:       #10202b;
  --c-ink-2:     #3a4d59;
  --c-muted:     #6b8091;
  --c-line:      #dde6ec;
  --c-line-soft: #eaf0f4;

  /* Chart series. One ordered ramp, used in the same order everywhere, so a
     device is the same colour on the dashboard and in the report. */
  --s1: #0e7490;
  --s2: #7c3aed;
  --s3: #ea580c;
  --s4: #15803d;
  --s5: #db2777;
  --s6: #0284c7;
  --s7: #a16207;
  --s8: #4f46e5;

  --radius:    12px;
  --radius-sm: 8px;
  --shadow:    0 1px 2px rgba(16, 32, 43, .04), 0 6px 18px -10px rgba(16, 32, 43, .18);
  --shadow-lg: 0 12px 40px -16px rgba(16, 32, 43, .35);

  --sidebar-w: 248px;
  --topbar-h:  62px;
}

/* -- 3. Tokens: dark ----------------------------------------------------- */
/* Not an inversion. Surfaces lift toward the viewer instead of the page
   getting brighter, the brand desaturates so it does not glow against a dark
   ground, and the semantic trio is lightened to keep its contrast on a dark
   card -- a "success" green that passes on white fails on #101c22. */
[data-theme="dark"] {
  --c-primary:        #38bdd4;
  --c-primary-strong: #67d3e5;
  --c-primary-soft:   #0d2b33;
  --c-primary-line:   #17505e;

  --c-success:      #4ade80;
  --c-success-soft: #0d2a1a;
  --c-warning:      #fbbf24;
  --c-warning-soft: #2e2312;
  --c-danger:       #f87171;
  --c-danger-soft:  #2f1618;
  --c-info:         var(--c-primary);
  --c-info-soft:    var(--c-primary-soft);

  --c-bg:        #0a1216;
  --c-surface:   #101c22;
  --c-surface-2: #16262e;
  --c-ink:       #e8f1f5;
  --c-ink-2:     #bacbd4;
  --c-muted:     #8ba3af;
  --c-line:      #21353f;
  --c-line-soft: #1a2b33;

  --s1: #38bdd4;
  --s2: #a78bfa;
  --s3: #fb923c;
  --s4: #4ade80;
  --s5: #f472b6;
  --s6: #38bdf8;
  --s7: #fbbf24;
  --s8: #818cf8;

  --shadow:    0 1px 2px rgba(0, 0, 0, .5), 0 8px 24px -12px rgba(0, 0, 0, .7);
  --shadow-lg: 0 16px 48px -20px rgba(0, 0, 0, .85);
}

/* -- 4. Bootstrap bridge ------------------------------------------------- */
/* This block is what lets the existing pages inherit the redesign without
   being touched. Keep it in sync with the tokens above. */
:root,
[data-theme="dark"] {
  --bs-primary:      var(--c-primary);
  --bs-primary-rgb:  14, 116, 144;
  --bs-body-bg:      var(--c-bg);
  --bs-body-color:   var(--c-ink);
  --bs-body-font-family: var(--clino-font);
  --bs-border-color: var(--c-line);
  --bs-secondary-color: var(--c-muted);
  --bs-emphasis-color:  var(--c-ink);
  --bs-heading-color:   var(--c-ink);
  --bs-link-color:      var(--c-primary);
  --bs-link-hover-color: var(--c-primary-strong);
  --bs-card-bg:      var(--c-surface);
  --bs-border-radius: var(--radius-sm);
}

html, body {
  font-family: var(--clino-font);
  background: var(--c-bg);
  color: var(--c-ink);
}

body {
  font-size: 14.5px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  margin: 0;
}

h1, h2, h3, h4, h5, h6 { color: var(--c-ink); font-weight: 600; letter-spacing: 0; }
a { color: var(--c-primary); }
hr { border-color: var(--c-line); opacity: 1; }

.text-muted { color: var(--c-muted) !important; }
.card {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}
.card-header {
  background: transparent;
  border-bottom: 1px solid var(--c-line-soft);
  padding: 16px 20px;
}
.card-body { padding: 20px; }

.btn-primary {
  --bs-btn-bg: var(--c-primary);
  --bs-btn-border-color: var(--c-primary);
  --bs-btn-hover-bg: var(--c-primary-strong);
  --bs-btn-hover-border-color: var(--c-primary-strong);
  --bs-btn-color: #fff;
  --bs-btn-hover-color: #fff;
}
[data-theme="dark"] .btn-primary { --bs-btn-color: #06222a; --bs-btn-hover-color: #06222a; }

/* Segmented controls (the metric switchers). Bootstrap's own
   .btn-outline-secondary.active resolves to a light grey fill, which on a dark
   card renders as a white slab -- the giveaway that a dark theme was applied
   to the page but not to its controls. */
.btn-outline-secondary {
  --bs-btn-color: var(--c-ink-2);
  --bs-btn-border-color: var(--c-line);
  --bs-btn-bg: var(--c-surface);
  --bs-btn-hover-color: var(--c-ink);
  --bs-btn-hover-bg: var(--c-surface-2);
  --bs-btn-hover-border-color: var(--c-line);
  --bs-btn-active-color: var(--c-primary);
  --bs-btn-active-bg: var(--c-primary-soft);
  --bs-btn-active-border-color: var(--c-primary-line);
}
.btn-outline-primary {
  --bs-btn-color: var(--c-primary);
  --bs-btn-border-color: var(--c-primary-line);
  --bs-btn-bg: transparent;
  --bs-btn-hover-color: #fff;
  --bs-btn-hover-bg: var(--c-primary);
  --bs-btn-hover-border-color: var(--c-primary);
}
[data-theme="dark"] .btn-outline-primary { --bs-btn-hover-color: #06222a; }

.form-control, .form-select {
  background: var(--c-surface);
  border-color: var(--c-line);
  color: var(--c-ink);
  border-radius: var(--radius-sm);
}
.form-control:focus, .form-select:focus {
  border-color: var(--c-primary);
  box-shadow: 0 0 0 3px var(--c-primary-soft);
  background: var(--c-surface);
  color: var(--c-ink);
}
.form-control::placeholder { color: var(--c-muted); }

.table { --bs-table-color: var(--c-ink); --bs-table-bg: transparent; }
.table > :not(caption) > * > * { border-bottom-color: var(--c-line-soft); }
.table thead th {
  color: var(--c-muted);
  font-weight: 600;
  font-size: 12.5px;
  background: var(--c-surface-2);
  border-bottom: 1px solid var(--c-line);
  white-space: nowrap;
}

/* Focus is visible everywhere. A keyboard user in a clinic is not an edge
   case; it is anyone whose hands are busy. */
:focus-visible { outline: 2px solid var(--c-primary); outline-offset: 2px; }

/* -- 5. Shell ------------------------------------------------------------ */
.clino-app { min-height: 100vh; background: var(--c-bg); }

.clino-sidebar {
  position: fixed;
  inset-block: 0;
  inset-inline-start: 0;
  width: var(--sidebar-w);
  background: var(--c-surface);
  border-inline-end: 1px solid var(--c-line);
  display: flex;
  flex-direction: column;
  z-index: 1045;
  transition: transform .22s ease;
}
.clino-brand {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 18px 20px;
  border-bottom: 1px solid var(--c-line-soft);
}
.clino-brand-mark {
  width: 34px; height: 34px;
  border-radius: 10px;
  background: linear-gradient(135deg, var(--c-primary), var(--c-primary-strong));
  color: #fff;
  display: grid; place-items: center;
  font-size: 18px;
  flex: none;
}
.clino-brand-name { font-weight: 700; font-size: 19px; letter-spacing: .01em; }
.clino-brand-sub { font-size: 11.5px; color: var(--c-muted); line-height: 1.2; }

.clino-nav { padding: 12px 12px 20px; overflow-y: auto; flex: 1; }
.clino-nav-section {
  font-size: 11px;
  color: var(--c-muted);
  padding: 14px 10px 6px;
  letter-spacing: .04em;
}
.clino-nav a {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  color: var(--c-ink-2);
  text-decoration: none;
  font-size: 14.5px;
  margin-bottom: 2px;
  transition: background .14s ease, color .14s ease;
}
.clino-nav a i { font-size: 19px; flex: none; }
.clino-nav a:hover { background: var(--c-surface-2); color: var(--c-ink); }
.clino-nav a.active {
  background: var(--c-primary-soft);
  color: var(--c-primary);
  font-weight: 600;
}
/* The active marker sits on the INLINE start, so it follows RTL without a
   second rule. */
.clino-nav a.active::before {
  content: "";
  width: 3px; height: 20px;
  border-radius: 3px;
  background: var(--c-primary);
  margin-inline-start: -12px;
  margin-inline-end: 9px;
}
.clino-nav a.disabled { opacity: .45; pointer-events: none; }
.clino-nav-soon {
  margin-inline-start: auto;
  font-size: 10.5px;
  color: var(--c-muted);
  border: 1px solid var(--c-line);
  border-radius: 20px;
  padding: 0 7px;
}

/* -- 5b. Sidebar: dark in BOTH themes -----------------------------------
   The navigation column is the app's fixed frame. Letting it follow the
   theme means the whole window changes weight when someone flips to dark,
   and the content area -- the part that actually carries the data -- stops
   being the brightest thing on screen. A constant dark rail keeps the eye
   where the numbers are.

   Its palette is declared ON .clino-sidebar rather than in :root, so nothing
   outside the rail inherits a dark ground. The accent is the teal from the
   logo's wifi arc, not --c-primary: #0e7490 is tuned for white and goes
   muddy against #111c2b. */
.clino-sidebar {
  --side-bg:        #111c2b;
  --side-bg-2:      #1b2a3d;
  --side-line:      rgba(255, 255, 255, .09);
  --side-ink:       #e9eff6;
  --side-ink-2:     #a7b7c9;
  --side-muted:     #74859a;
  --side-active-bg: rgba(94, 207, 224, .14);
  --side-active:    #5ecfe0;

  background: var(--side-bg);
  border-inline-end: 1px solid var(--side-line);
  color: var(--side-ink);
}

.clino-sidebar .clino-brand {
  flex-direction: column;
  align-items: flex-start;
  gap: 5px;
  padding: 18px 18px 16px;
  border-bottom: 1px solid var(--side-line);
}
/* Width-constrained rather than height-constrained: the lockup is wider than
   it is tall, so the width is what has to survive the narrow rail. */
.clino-brand-logo {
  display: block;
  width: 152px;
  max-width: 100%;
  height: auto;
}
.clino-sidebar .clino-brand-sub { color: var(--side-muted); }

.clino-sidebar .clino-nav-section { color: var(--side-muted); }
.clino-sidebar .clino-nav a { color: var(--side-ink-2); }
.clino-sidebar .clino-nav a:hover { background: var(--side-bg-2); color: var(--side-ink); }
.clino-sidebar .clino-nav a.active {
  background: var(--side-active-bg);
  color: var(--side-active);
}
.clino-sidebar .clino-nav a.active::before { background: var(--side-active); }
.clino-sidebar .clino-nav-soon {
  color: var(--side-muted);
  border-color: var(--side-line);
}
/* Firefox and WebKit, so the scroll track does not flash white on a dark
   rail when the menu is long enough to scroll. */
.clino-sidebar .clino-nav { scrollbar-color: var(--side-bg-2) transparent; }
.clino-sidebar .clino-nav::-webkit-scrollbar { width: 8px; }
.clino-sidebar .clino-nav::-webkit-scrollbar-thumb {
  background: var(--side-bg-2);
  border-radius: 8px;
}

.clino-main { margin-inline-start: var(--sidebar-w); min-width: 0; }

.clino-topbar {
  position: sticky;
  top: 0;
  z-index: 1030;
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 20px;
  background: color-mix(in srgb, var(--c-bg) 88%, transparent);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--c-line);
}
.clino-page-title { font-size: 17px; font-weight: 600; margin: 0; }
.clino-page-sub { font-size: 12px; color: var(--c-muted); margin: 0; line-height: 1.3; }
.clino-topbar-actions { margin-inline-start: auto; display: flex; align-items: center; gap: 8px; }

.clino-iconbtn {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  color: var(--c-ink-2);
  cursor: pointer;
  font-size: 19px;
  flex: none;
}
.clino-iconbtn:hover { background: var(--c-surface-2); color: var(--c-ink); }

.clino-user { display: flex; align-items: center; gap: 9px; }
.clino-avatar {
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--c-primary-soft);
  color: var(--c-primary);
  display: grid; place-items: center;
  font-weight: 600;
  font-size: 14px;
  flex: none;
}
.clino-user-name { font-size: 13.5px; font-weight: 600; line-height: 1.2; }
.clino-user-role { font-size: 11.5px; color: var(--c-muted); line-height: 1.2; }

.clino-content { padding: 22px 20px 60px; max-width: 1560px; }

.clino-backdrop {
  position: fixed; inset: 0;
  background: rgba(8, 20, 26, .5);
  z-index: 1040;
  opacity: 0; pointer-events: none;
  transition: opacity .2s ease;
}
.clino-menu-toggle { display: none; }

/* Mobile: the sidebar becomes a drawer. Nothing here shrinks the desktop
   layout -- the drawer is a different component that happens to share the
   markup. */
@media (max-width: 991.98px) {
  .clino-sidebar { transform: translateX(100%); box-shadow: var(--shadow-lg); }
  html[dir="ltr"] .clino-sidebar { transform: translateX(-100%); }
  body.clino-drawer-open .clino-sidebar { transform: translateX(0); }
  body.clino-drawer-open .clino-backdrop { opacity: 1; pointer-events: auto; }
  .clino-main { margin-inline-start: 0; }
  .clino-menu-toggle { display: grid; }
  .clino-content { padding: 16px 14px 80px; }
  .clino-topbar { padding: 0 14px; }
  .clino-page-sub { display: none; }
}

/* -- 6. Components ------------------------------------------------------- */

/* KPI. Compact by instruction: a clinic owner should read the whole row in one
   glance, not scroll through six tall cards. */
.kpi-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(168px, 1fr));
}
.kpi {
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  padding: 15px 16px;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}
.kpi-head { display: flex; align-items: center; gap: 8px; }
.kpi-icon {
  width: 30px; height: 30px;
  border-radius: 9px;
  display: grid; place-items: center;
  font-size: 17px;
  flex: none;
  background: var(--c-primary-soft);
  color: var(--c-primary);
}
.kpi-icon.success { background: var(--c-success-soft); color: var(--c-success); }
.kpi-icon.warning { background: var(--c-warning-soft); color: var(--c-warning); }
.kpi-icon.danger  { background: var(--c-danger-soft);  color: var(--c-danger); }
.kpi-label { font-size: 12.5px; color: var(--c-muted); }
.kpi-value {
  font-size: 27px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--c-ink);
  font-variant-numeric: tabular-nums;
}
.kpi-foot { font-size: 11.5px; color: var(--c-muted); display: flex; align-items: center; gap: 6px; }

/* Trend chips. Deliberately quiet -- §14: this is a clinic dashboard, not a
   trading terminal. */
.trend { display: inline-flex; align-items: center; gap: 3px; font-size: 11.5px; font-weight: 600; }
.trend.up   { color: var(--c-success); }
.trend.down { color: var(--c-danger); }
.trend.flat { color: var(--c-muted); }

.chip {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: 12px; font-weight: 500;
  padding: 3px 10px;
  border-radius: 20px;
  border: 1px solid transparent;
  white-space: nowrap;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip.plain::before { display: none; }
.chip-online   { background: var(--c-success-soft); color: var(--c-success); }
.chip-offline  { background: var(--c-surface-2);    color: var(--c-muted); }
.chip-warning  { background: var(--c-warning-soft); color: var(--c-warning); }
.chip-danger   { background: var(--c-danger-soft);  color: var(--c-danger); }
.chip-info     { background: var(--c-primary-soft); color: var(--c-primary); }

.section-title { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 12px; flex-wrap: wrap; }
.section-title h2 { font-size: 16px; margin: 0; font-weight: 600; }
.section-title .hint { font-size: 12px; color: var(--c-muted); }

/* Date range filter */
.clino-filter { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.clino-range-btn {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius-sm);
  padding: 8px 14px;
  color: var(--c-ink);
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
}
.clino-range-btn:hover { border-color: var(--c-primary-line); }
.clino-range-btn .ti { color: var(--c-primary); font-size: 17px; }

/* .clino-range-host already establishes the containing block (see below).
   What was missing is the anchoring: the panel was `position:absolute` with
   every offset left at `auto`, so it fell back to its static position and ran
   off the edge of a desktop viewport. On mobile .clino-filter wraps onto its
   own line, which gave it room by accident -- which is exactly why the bug
   looked mobile-only. js/clino-daterange.js::positionPop() handles the rest. */
.clino-pop {
  position: absolute;
  top: calc(100% + 6px);
  inset-inline-start: 0;
  z-index: 1060;
  /* A 1366x768 laptop cannot show a full Jalali month plus presets plus the
     weekday picker. Scroll the panel rather than letting it run past the fold,
     and contain the scroll so the page behind does not move with it. */
  max-height: min(72vh, 540px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--c-surface);
  border: 1px solid var(--c-line);
  border-radius: var(--radius);
  box-shadow: var(--shadow-lg);
  padding: 14px;
  width: min(340px, calc(100vw - 28px));
}
.clino-quick { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.clino-quick button {
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  border-radius: var(--radius-sm);
  padding: 7px 8px;
  font-size: 13px;
  color: var(--c-ink-2);
  cursor: pointer;
}
.clino-quick button:hover { background: var(--c-surface-2); }
.clino-quick button.active {
  background: var(--c-primary-soft);
  border-color: var(--c-primary-line);
  color: var(--c-primary);
  font-weight: 600;
}
.clino-pop-label { font-size: 12px; color: var(--c-muted); margin: 14px 0 6px; }

/* Weekday picker. Big enough to hit with a thumb -- §4. */
.clino-weekdays { display: flex; gap: 5px; flex-wrap: wrap; }
.clino-weekdays button {
  min-width: 40px;
  height: 38px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  color: var(--c-ink-2);
  font-size: 13px;
  cursor: pointer;
}
.clino-weekdays button.active {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: #fff;
  font-weight: 600;
}
[data-theme="dark"] .clino-weekdays button.active { color: #06222a; }

/* Inline notice. Used for the coverage banner: how much machine activity has
   nobody standing behind it. Deliberately a quiet strip rather than an alert
   card -- it is information a clinic acts on when convenient, not a fault. */
.note-inline {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 15px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--c-line);
  background: var(--c-surface);
  font-size: 13.5px;
  color: var(--c-ink-2);
  margin-bottom: 14px;
  flex-wrap: wrap;
}
.note-inline > span { flex: 1 1 260px; min-width: 0; }
.note-inline > i { font-size: 20px; flex: none; }
.note-inline.warn { border-color: var(--c-warning); background: var(--c-warning-soft); }
.note-inline.warn > i { color: var(--c-warning); }
.note-inline.ok { border-color: var(--c-success); background: var(--c-success-soft); }
.note-inline.ok > i { color: var(--c-success); }
.note-inline strong { color: var(--c-ink); }

/* Jalali calendar (js/clino-daterange.js) */
.clino-range-host { position: relative; }
.cal-nav { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
.cal-nav .clino-iconbtn { width: 32px; height: 32px; font-size: 16px; }
.cal-title { text-align: center; font-weight: 600; font-size: 13.5px; margin-bottom: 8px; }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-dow {
  text-align: center;
  font-size: 11px;
  color: var(--c-muted);
  padding-bottom: 4px;
}
.cal-day {
  /* 34px minimum: a calendar cell that cannot be hit with a thumb is a
     desktop calendar shown on a phone -- §4. */
  min-height: 34px;
  border: 1px solid transparent;
  background: transparent;
  border-radius: var(--radius-sm);
  color: var(--c-ink-2);
  font-size: 12.5px;
  cursor: pointer;
  font-variant-numeric: tabular-nums;
}
.cal-day:hover:not(:disabled) { background: var(--c-surface-2); }
.cal-day.today { border-color: var(--c-primary-line); font-weight: 600; }
.cal-day.in-range { background: var(--c-primary-soft); color: var(--c-primary); border-radius: 0; }
.cal-day.edge {
  background: var(--c-primary);
  border-color: var(--c-primary);
  color: #fff;
  font-weight: 600;
}
[data-theme="dark"] .cal-day.edge { color: #06222a; }
.cal-day.future { opacity: .32; cursor: not-allowed; }

/* Heatmap */
.heat-wrap { overflow-x: auto; padding-bottom: 4px; }
.heat-grid { display: grid; gap: 3px; min-width: max-content; }
.heat-cell {
  width: 100%;
  aspect-ratio: 1;
  min-width: 22px;
  border-radius: 4px;
  background: var(--c-surface-2);
  cursor: default;
}
.heat-label { font-size: 11.5px; color: var(--c-muted); white-space: nowrap; padding-inline-end: 8px; align-self: center; }
.heat-hour  { font-size: 10.5px; color: var(--c-muted); text-align: center; font-variant-numeric: tabular-nums; }
.heat-legend { display: flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--c-muted); }
.heat-legend .heat-cell { width: 15px; min-width: 15px; height: 15px; }

/* Loading, empty, error. §21-23: never a blank table, never a raw API error. */
.skel {
  background: linear-gradient(90deg, var(--c-surface-2) 25%, var(--c-line-soft) 37%, var(--c-surface-2) 63%);
  background-size: 400% 100%;
  animation: skel 1.3s ease-in-out infinite;
  border-radius: 6px;
}
@keyframes skel { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }
.skel-line { height: 12px; margin-bottom: 8px; }
.skel-kpi  { height: 92px; border-radius: var(--radius); }
.skel-chart{ height: 300px; border-radius: var(--radius); }

.state-box { text-align: center; padding: 40px 20px; }
.state-icon {
  width: 54px; height: 54px;
  border-radius: 16px;
  display: grid; place-items: center;
  margin: 0 auto 14px;
  font-size: 26px;
  background: var(--c-surface-2);
  color: var(--c-muted);
}
.state-box.error .state-icon { background: var(--c-danger-soft); color: var(--c-danger); }
.state-title { font-weight: 600; margin-bottom: 5px; }
.state-text  { color: var(--c-muted); font-size: 13.5px; margin-bottom: 16px; }

/* Tables that survive a phone. Below the breakpoint each row becomes a card
   with its own labels -- §4 explicitly rules out just shrinking the desktop
   table. */
.clino-table-wrap { overflow-x: auto; }
.clino-table { width: 100%; margin: 0; }
.clino-table td { padding: 11px 14px; vertical-align: middle; font-size: 13.5px; }
.clino-table th { padding: 10px 14px; }
.clino-table tbody tr:hover { background: var(--c-surface-2); }

@media (max-width: 767.98px) {
  .clino-table.stacked thead { display: none; }
  .clino-table.stacked tbody tr {
    display: block;
    border: 1px solid var(--c-line);
    border-radius: var(--radius-sm);
    margin-bottom: 10px;
    padding: 6px 4px;
    background: var(--c-surface);
  }
  .clino-table.stacked tbody td {
    display: flex;
    justify-content: space-between;
    gap: 14px;
    border: 0;
    padding: 6px 12px;
  }
  .clino-table.stacked tbody td::before {
    content: attr(data-label);
    color: var(--c-muted);
    font-size: 12.5px;
    flex: none;
  }
  .clino-table.stacked tbody td:empty { display: none; }
}

/* Numbers and identifiers. Persian digits everywhere a person reads a count;
   Latin monospace for anything a person types into a support ticket. */
.num { font-variant-numeric: tabular-nums; }
.ltr { direction: ltr; unicode-bidi: isolate; display: inline-block; }
code, .mono { font-family: var(--clino-mono); direction: ltr; unicode-bidi: isolate; }
code {
  background: var(--c-surface-2);
  border: 1px solid var(--c-line);
  border-radius: 5px;
  padding: 1px 6px;
  font-size: 12px;
  color: var(--c-ink-2);
}

/* ApexCharts sits inside our cards, so its chrome has to follow the tokens
   too -- a tooltip that stays white in dark mode is the giveaway that a
   dashboard was themed only skin-deep. */
.apexcharts-tooltip {
  background: var(--c-surface) !important;
  border: 1px solid var(--c-line) !important;
  box-shadow: var(--shadow-lg) !important;
  color: var(--c-ink) !important;
}
.apexcharts-tooltip-title {
  background: var(--c-surface-2) !important;
  border-bottom: 1px solid var(--c-line) !important;
  font-family: var(--clino-font) !important;
}
.apexcharts-xaxistooltip, .apexcharts-yaxistooltip {
  background: var(--c-surface) !important;
  border-color: var(--c-line) !important;
  color: var(--c-ink) !important;
}
.apexcharts-text, .apexcharts-legend-text {
  font-family: var(--clino-font) !important;
  fill: var(--c-muted);
  color: var(--c-muted) !important;
}
.apexcharts-gridline { stroke: var(--c-line-soft); }

/* -- 7. Utilities -------------------------------------------------------- */
.stack { display: flex; flex-direction: column; gap: 18px; }
.row-gap { display: flex; flex-wrap: wrap; gap: 12px; }
.grow { flex: 1 1 0; min-width: 0; }
.muted-sm { font-size: 12px; color: var(--c-muted); }
.nowrap { white-space: nowrap; }

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