/*! variables.css */
/* ==========================================================================
   Design tokens
   Derived from the reference screenshots: a near-white neutral canvas, white
   cards with large radii and hairline borders, one crimson brand accent, an
   ink-black call-to-action, and soft tinted chips for status.
   Every value below is referenced by variable; no component hard-codes a hex.
   ========================================================================== */

:root {
  /* --- Brand ------------------------------------------------------------ */
  --brand-crimson:      #E4123A;
  --brand-crimson-dark: #C20E30;
  --brand-crimson-soft: #FDECEF;

  /* --- Neutral ramp ----------------------------------------------------- */
  --n-0:   #FFFFFF;
  --n-25:  #FAFBFC;
  --n-50:  #F5F6F8;
  --n-75:  #F1F2F4;
  --n-100: #ECEDF0;
  --n-200: #E2E4E8;
  --n-300: #CFD3D9;
  --n-400: #ADB3BB;
  --n-500: #8A9099;
  --n-600: #666C75;
  --n-700: #454A52;
  --n-800: #2A2E34;
  --n-900: #16181C;
  --n-950: #0D0E11;

  /* --- Semantic hues (base / soft tint / strong text) ------------------- */
  --hue-green:   #17A34A;  --hue-green-soft:   #E6F6EC;  --hue-green-ink:   #0F7536;
  --hue-blue:    #2E7BF6;  --hue-blue-soft:    #E8F1FE;  --hue-blue-ink:    #1B5BC4;
  --hue-amber:   #E29100;  --hue-amber-soft:   #FDF3E1;  --hue-amber-ink:   #9A6200;
  --hue-orange:  #F0761A;  --hue-orange-soft:  #FEF0E5;  --hue-orange-ink:  #B45309;
  --hue-red:     #E5484D;  --hue-red-soft:     #FDEBEC;  --hue-red-ink:     #B4272C;
  --hue-violet:  #7C5CFC;  --hue-violet-soft:  #F0EDFE;  --hue-violet-ink:  #5638D4;
  --hue-indigo:  #4F5BD5;  --hue-indigo-soft:  #ECEEFC;  --hue-indigo-ink:  #363FA8;
  --hue-teal:    #12A594;  --hue-teal-soft:    #E4F6F4;  --hue-teal-ink:    #0C7466;
  --hue-crimson: #E4123A;  --hue-crimson-soft: #FDECEF;  --hue-crimson-ink: #A80C29;
  --hue-slate:   #8A9099;  --hue-slate-soft:   #F1F2F4;  --hue-slate-ink:   #454A52;

  /* --- Radius ----------------------------------------------------------- */
  --r-xs:   6px;
  --r-sm:   10px;
  --r-md:   14px;
  --r-lg:   18px;
  --r-xl:   24px;
  --r-2xl:  30px;
  --r-full: 999px;

  /* --- Spacing ---------------------------------------------------------- */
  --s-1: 4px;   --s-2: 8px;   --s-3: 12px;  --s-4: 16px;
  --s-5: 20px;  --s-6: 24px;  --s-7: 32px;  --s-8: 40px;
  --s-9: 48px;  --s-10: 64px;

  /* --- Typography ------------------------------------------------------- */
  --font-sans: 'Vazirmatn', 'Segoe UI', 'Tahoma', system-ui, -apple-system, sans-serif;

  --t-2xs: 10.5px;
  --t-xs:  11.5px;
  --t-sm:  12.5px;
  --t-md:  13.5px;
  --t-base:14.5px;
  --t-lg:  16px;
  --t-xl:  19px;
  --t-2xl: 23px;
  --t-3xl: 29px;
  --t-4xl: 36px;

  --lh-tight: 1.35;
  --lh-base:  1.75;

  --fw-normal: 400;
  --fw-medium: 500;
  --fw-semi:   600;
  --fw-bold:   700;

  /* --- Layout ----------------------------------------------------------- */
  --sidebar-w:          254px;
  --sidebar-w-collapsed: 74px;
  --topbar-h:           68px;
  --content-max:        1560px;

  /* --- Motion ----------------------------------------------------------- */
  --ease: cubic-bezier(.4, 0, .2, 1);
  --dur-fast: 120ms;
  --dur:      190ms;
  --dur-slow: 320ms;

  --z-drawer: 60;
  --z-modal:  80;
  --z-toast:  90;
}

/* Users who prefer less motion get none of it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    transition-duration: .001ms !important;
  }
}


/*! themes.css */
/* ==========================================================================
   Themes
   Light is the reference design. Dark is the same system re-pointed at the
   dark end of the neutral ramp — same radii, same spacing, same component
   anatomy — so nothing needs a dark-only rule beyond these variables.
   ========================================================================== */

:root,
[data-theme='light'] {
  color-scheme: light;

  --color-bg:            var(--n-50);
  --color-surface:       var(--n-0);
  --color-card:          var(--n-0);
  --color-card-muted:    var(--n-50);
  --color-inset:         var(--n-75);

  --color-sidebar:       var(--n-0);
  --color-sidebar-hover: var(--n-50);
  --color-sidebar-active:var(--n-900);
  --color-header:        rgba(255, 255, 255, .82);

  --color-border:        var(--n-100);
  --color-border-strong: var(--n-200);
  --color-divider:       var(--n-75);

  --color-text:          var(--n-900);
  --color-text-soft:     var(--n-700);
  --color-muted:         var(--n-500);
  --color-faint:         var(--n-400);
  --color-on-accent:     #FFFFFF;

  --color-primary:       var(--hue-blue);
  --color-primary-hover: var(--hue-blue-ink);
  --color-primary-soft:  var(--hue-blue-soft);

  /* The ink button from the reference: near-black on light, white on dark. */
  --color-ink:           var(--n-900);
  --color-ink-hover:     var(--n-800);
  --color-on-ink:        #FFFFFF;

  --color-input:         var(--n-0);
  --color-input-border:  var(--n-200);
  --color-input-focus:   var(--n-900);
  --color-placeholder:   var(--n-400);

  --color-hover:         var(--n-50);
  --color-active:        var(--n-75);
  --color-selected:      var(--n-75);

  --color-success: var(--hue-green);  --color-success-soft: var(--hue-green-soft);  --color-success-ink: var(--hue-green-ink);
  --color-warning: var(--hue-amber);  --color-warning-soft: var(--hue-amber-soft);  --color-warning-ink: var(--hue-amber-ink);
  --color-danger:  var(--hue-red);    --color-danger-soft:  var(--hue-red-soft);    --color-danger-ink:  var(--hue-red-ink);
  --color-info:    var(--hue-blue);   --color-info-soft:    var(--hue-blue-soft);   --color-info-ink:    var(--hue-blue-ink);

  --shadow-xs: 0 1px 2px rgba(16, 18, 22, .04);
  --shadow-sm: 0 1px 3px rgba(16, 18, 22, .05), 0 1px 2px rgba(16, 18, 22, .03);
  --shadow-md: 0 6px 20px rgba(16, 18, 22, .07);
  --shadow-lg: 0 16px 44px rgba(16, 18, 22, .11);
  --shadow-ring: 0 0 0 3px rgba(228, 18, 58, .13);

  --gradient-hero: linear-gradient(115deg, #FDE8E4 0%, #FBE9F1 28%, #EAE8FB 62%, #E4F0FB 100%);
  --scrim: rgba(16, 18, 22, .38);
}

[data-theme='dark'] {
  color-scheme: dark;

  --color-bg:            #0D0E11;
  --color-surface:       #141619;
  --color-card:          #17191D;
  --color-card-muted:    #1B1E22;
  --color-inset:         #1F2227;

  --color-sidebar:       #141619;
  --color-sidebar-hover: #1F2227;
  --color-sidebar-active: #FFFFFF;
  --color-header:        rgba(20, 22, 25, .84);

  --color-border:        #24272C;
  --color-border-strong: #31353B;
  --color-divider:       #1F2227;

  --color-text:          #E9EBEE;
  --color-text-soft:     #C3C8CF;
  --color-muted:         #949BA5;
  --color-faint:         #6E7681;
  --color-on-accent:     #FFFFFF;

  --color-primary:       #3B82F6;
  --color-primary-hover: #60A5FA;
  --color-primary-soft:  rgba(59, 130, 246, .16);

  /* Inverted on dark so the primary CTA keeps the same visual weight. */
  --color-ink:           #F4F5F7;
  --color-ink-hover:     #FFFFFF;
  --color-on-ink:        #101216;

  --color-input:         #1B1E22;
  --color-input-border:  #2C3036;
  --color-input-focus:   #6E7681;
  --color-placeholder:   #6E7681;

  --color-hover:         #1F2227;
  --color-active:        #24272C;
  --color-selected:      #22262B;

  --color-success: #3DD07E;  --color-success-soft: rgba(61, 208, 126, .13);  --color-success-ink: #6FE0A2;
  --color-warning: #F0B429;  --color-warning-soft: rgba(240, 180, 41, .13);  --color-warning-ink: #F7C95C;
  --color-danger:  #FF6169;  --color-danger-soft:  rgba(255, 97, 105, .13);  --color-danger-ink:  #FF8A90;
  --color-info:    #5A9BFF;  --color-info-soft:    rgba(90, 155, 255, .13);  --color-info-ink:    #85B6FF;

  --hue-green-soft:   rgba(61, 208, 126, .13);  --hue-green-ink:   #6FE0A2;  --hue-green:   #3DD07E;
  --hue-blue-soft:    rgba(90, 155, 255, .13);  --hue-blue-ink:    #85B6FF;  --hue-blue:    #5A9BFF;
  --hue-amber-soft:   rgba(240, 180, 41, .13);  --hue-amber-ink:   #F7C95C;  --hue-amber:   #F0B429;
  --hue-orange-soft:  rgba(255, 145, 60, .13);  --hue-orange-ink:  #FFB077;  --hue-orange:  #FF913C;
  --hue-red-soft:     rgba(255, 97, 105, .13);  --hue-red-ink:     #FF8A90;  --hue-red:     #FF6169;
  --hue-violet-soft:  rgba(154, 128, 255, .14); --hue-violet-ink:  #B7A2FF;  --hue-violet:  #9A80FF;
  --hue-indigo-soft:  rgba(122, 133, 255, .13); --hue-indigo-ink:  #A4ACFF;  --hue-indigo:  #7A85FF;
  --hue-teal-soft:    rgba(35, 199, 179, .13);  --hue-teal-ink:    #5FDBCB;  --hue-teal:    #23C7B3;
  --hue-crimson-soft: rgba(255, 61, 95, .14);   --hue-crimson-ink: #FF7D93;  --hue-crimson: #FF3D5F;
  --hue-slate-soft:   rgba(148, 155, 165, .13); --hue-slate-ink:   #B4BAC3;  --hue-slate:   #949BA5;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, .5);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, .55);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, .6);
  --shadow-lg: 0 20px 52px rgba(0, 0, 0, .68);
  --shadow-ring: 0 0 0 3px rgba(255, 61, 95, .22);

  --gradient-hero: linear-gradient(115deg, #2A1C24 0%, #2A1D2A 30%, #201F33 65%, #182430 100%);
  --scrim: rgba(0, 0, 0, .62);
}


/*! base.css */
/* ==========================================================================
   Base: reset, Persian typography, RTL defaults, scrollbars, focus rings
   ========================================================================== */

@font-face {
  font-family: 'Vazirmatn';
  src: url('fonts/Vazirmatn-Variable.woff2') format('woff2-variations'),
       url('fonts/Vazirmatn-Variable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-sans);
  font-size: var(--t-base);
  line-height: var(--lh-base);
  font-weight: var(--fw-normal);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: 'ss02' 1;
  transition: background-color var(--dur) var(--ease), color var(--dur) var(--ease);
}

/* Persian digits render best slightly tighter than Latin ones. */
body { font-variant-numeric: proportional-nums; }

h1, h2, h3, h4, h5, h6 {
  margin: 0;
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: -.01em;
}

h1 { font-size: var(--t-2xl); }
h2 { font-size: var(--t-xl); }
h3 { font-size: var(--t-lg); }
h4 { font-size: var(--t-base); }

p { margin: 0 0 var(--s-3); }
p:last-child { margin-bottom: 0; }

a {
  color: inherit;
  text-decoration: none;
  transition: color var(--dur-fast) var(--ease);
}

img, svg, video { max-width: 100%; display: block; }
svg { flex: none; }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}

button { cursor: pointer; background: none; border: none; padding: 0; }
button:disabled { cursor: not-allowed; }

ul, ol { margin: 0; padding: 0; list-style: none; }

hr {
  border: none;
  border-top: 1px solid var(--color-divider);
  margin: var(--s-5) 0;
}

/* Keyboard focus only — pointer users never see the ring. */
:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}
:focus:not(:focus-visible) { outline: none; }

::selection {
  background: var(--color-primary-soft);
  color: var(--color-text);
}

::placeholder { color: var(--color-placeholder); }

/* Scrollbars styled to disappear into the surface they sit on. */
* { scrollbar-width: thin; scrollbar-color: var(--color-border-strong) transparent; }
::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--color-border-strong);
  border-radius: var(--r-full);
  border: 2px solid transparent;
  background-clip: content-box;
}
::-webkit-scrollbar-thumb:hover { background: var(--color-faint); background-clip: content-box; }

/* Screen-reader only. */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* Latin fragments (emails, phone numbers, codes) inside RTL text. */
.ltr { direction: ltr; unicode-bidi: isolate; }
.num { font-feature-settings: 'tnum' 1; letter-spacing: 0; }

/* Page-level structure ---------------------------------------------------- */

.app {
  display: flex;
  min-height: 100vh;
  min-height: 100dvh;
}

.app__main {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.app__content {
  flex: 1;
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
  padding: var(--s-5) var(--s-6) var(--s-9);
}

@media (max-width: 900px) {
  .app__content { padding: var(--s-4) var(--s-4) calc(var(--s-9) + 64px); }
}

/* Print: drop the chrome, keep the content. */
@media print {
  .sidebar, .topbar, .no-print { display: none !important; }
  .app__content { padding: 0; max-width: none; }
  .card { break-inside: avoid; border-color: #ddd; }
}


/*! components/buttons.css */
/* ==========================================================================
   Buttons — ink primary (the black CTA in the reference), quiet secondary,
   circular icon buttons, and the small arrow affordance used on cards.
   ========================================================================== */

.btn {
  --btn-h: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  height: var(--btn-h);
  padding-inline: var(--s-5);
  border-radius: var(--r-sm);
  border: 1px solid transparent;
  font-size: var(--t-md);
  font-weight: var(--fw-semi);
  line-height: 1;
  white-space: nowrap;
  user-select: none;
  transition: background-color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              transform var(--dur-fast) var(--ease),
              box-shadow var(--dur-fast) var(--ease);
}

.btn:active:not(:disabled) { transform: translateY(1px); }
.btn:disabled { opacity: .5; }
.btn svg { width: 17px; height: 17px; }

/* Primary call to action: near-black on light, near-white on dark. */
.btn--ink {
  background: var(--color-ink);
  color: var(--color-on-ink);
}
.btn--ink:hover:not(:disabled) { background: var(--color-ink-hover); }

/* Brand accent — used sparingly, for destructive-adjacent confirmations. */
.btn--primary {
  background: var(--color-primary);
  color: #fff;
}
.btn--primary:hover:not(:disabled) { background: var(--color-primary-hover); }

.btn--secondary {
  background: var(--color-card);
  border-color: var(--color-border-strong);
  color: var(--color-text);
}
.btn--secondary:hover:not(:disabled) {
  background: var(--color-hover);
  border-color: var(--color-faint);
}

.btn--soft {
  background: var(--color-inset);
  color: var(--color-text-soft);
}
.btn--soft:hover:not(:disabled) { background: var(--color-active); color: var(--color-text); }

.btn--ghost {
  background: transparent;
  color: var(--color-muted);
}
.btn--ghost:hover:not(:disabled) { background: var(--color-hover); color: var(--color-text); }

.btn--danger {
  background: var(--color-danger);
  color: #fff;
}
.btn--danger:hover:not(:disabled) { filter: brightness(.94); }

.btn--danger-soft {
  background: var(--color-danger-soft);
  color: var(--color-danger-ink);
}
.btn--danger-soft:hover:not(:disabled) { background: var(--color-danger); color: #fff; }

.btn--success { background: var(--color-success); color: #fff; }

/* Sizes ------------------------------------------------------------------- */
.btn--sm { --btn-h: 32px; padding-inline: var(--s-3); font-size: var(--t-sm); border-radius: var(--r-xs); }
.btn--lg { --btn-h: 46px; padding-inline: var(--s-6); font-size: var(--t-base); border-radius: var(--r-md); }
.btn--block { display: flex; width: 100%; }
.btn--pill { border-radius: var(--r-full); }

/* Circular icon button — the reference's top-bar controls. */
.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--r-full);
  border: 1px solid var(--color-border);
  background: var(--color-card);
  color: var(--color-muted);
  position: relative;
  transition: background-color var(--dur-fast) var(--ease),
              color var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease);
}
.icon-btn:hover { background: var(--color-hover); color: var(--color-text); border-color: var(--color-border-strong); }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn--sm { width: 30px; height: 30px; }
.icon-btn--sm svg { width: 14px; height: 14px; }
.icon-btn--bare { border-color: transparent; background: transparent; }
.icon-btn--active { background: var(--color-ink); border-color: var(--color-ink); color: var(--color-on-ink); }

/* Spinner in icon-only buttons */
.icon-btn.is-loading svg,
.icon-btn:has(.spinner) svg,
.corner-btn.is-loading svg,
.corner-btn:has(.spinner) svg {
  display: none !important;
}

.icon-btn .spinner,
.corner-btn .spinner {
  width: 14px;
  height: 14px;
  border-width: 2px;
  margin: auto;
}

.icon-btn--sm .spinner {
  width: 12px;
  height: 12px;
  border-width: 1.8px;
  margin: auto;
}

/* Unread dot on the notification bell. */
.icon-btn__dot {
  position: absolute;
  top: 6px;
  inset-inline-end: 7px;
  width: 7px;
  height: 7px;
  border-radius: var(--r-full);
  background: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-card);
}

/* The small ↗ affordance in the corner of reference cards. */
.corner-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--color-inset);
  color: var(--color-muted);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.corner-btn:hover { background: var(--color-ink); color: var(--color-on-ink); }
.corner-btn svg { width: 13px; height: 13px; }

/* Segmented control (list/board toggles, calendar day/week/month). */
.segmented {
  display: inline-flex;
  padding: 3px;
  gap: 2px;
  background: var(--color-inset);
  border-radius: var(--r-sm);
}
.segmented__item {
  padding: 6px var(--s-4);
  border-radius: var(--r-xs);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: var(--color-muted);
  transition: all var(--dur-fast) var(--ease);
  white-space: nowrap;
}
.segmented__item:hover { color: var(--color-text); }
.segmented__item--active {
  background: var(--color-card);
  color: var(--color-text);
  font-weight: var(--fw-semi);
  box-shadow: var(--shadow-xs);
}

/* Mobile quick-action bar under a customer header. */
.quick-actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(72px, 1fr));
  gap: var(--s-2);
}
.quick-action {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: var(--s-3) var(--s-2);
  border-radius: var(--r-md);
  background: var(--color-inset);
  color: var(--color-text-soft);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  text-align: center;
  transition: background-color var(--dur-fast) var(--ease);
}
.quick-action:hover { background: var(--color-active); }
.quick-action svg { width: 18px; height: 18px; color: var(--color-muted); }


/*! components/cards.css */
/* ==========================================================================
   Cards — white surface, hairline border, large radius, near-zero shadow.
   This is the single most repeated shape in the reference design.
   ========================================================================== */

.card {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-xl);
  padding: var(--s-5);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}

.card--flush   { padding: 0; overflow: hidden; }
.card--tight   { padding: var(--s-4); }
.card--roomy   { padding: var(--s-6); }
.card--muted   { background: var(--color-card-muted); }
.card--plain   { border-radius: var(--r-lg); }
.card--hover:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-sm); }
.card--raised  { box-shadow: var(--shadow-sm); }

.card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-3);
  margin-bottom: var(--s-4);
  flex-wrap: wrap;   /* a long title must push its action down, not overlap it */
}
.card--flush > .card__head { padding: var(--s-5) var(--s-5) 0; margin-bottom: var(--s-4); }

.card__title {
  font-size: var(--t-lg);
  font-weight: var(--fw-bold);
  letter-spacing: -.01em;
}
.card__subtitle {
  font-size: var(--t-sm);
  color: var(--color-muted);
  font-weight: var(--fw-normal);
  margin-top: 2px;
}
.card__foot {
  margin-top: var(--s-4);
  padding-top: var(--s-4);
  border-top: 1px solid var(--color-divider);
}

/* Stat tile — icon chip, big figure, muted caption, corner affordance.
   The corner sits out of flow so the figure can own the bottom of the tile;
   on phones the whole thing flips to a compact horizontal row (see below). */
.stat {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-xl);
  padding: var(--s-4) var(--s-5) var(--s-5);
  min-height: 128px;
  color: inherit;
  overflow: hidden;
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease);
}
.stat::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: transparent;
  transition: background var(--dur) var(--ease);
  pointer-events: none;
}
.stat:hover { border-color: var(--color-border-strong); }
.stat--link { text-decoration: none; cursor: pointer; }
.stat--link:hover { box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.stat--link:hover .stat__corner { background: var(--color-ink); color: var(--color-on-ink); }

/* Opposite edge from the icon chip: left in RTL, right in LTR. */
.stat__corner {
  position: absolute;
  top: var(--s-4);
  inset-inline-end: var(--s-4);
  width: 26px;
  height: 26px;
  border-radius: var(--r-md);
  background: var(--color-inset);
  color: var(--color-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.stat__corner svg { width: 13px; height: 13px; }

.stat__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  border-radius: var(--r-md);
  background: var(--color-inset);
  color: var(--color-muted);
  flex: none;
}
.stat__icon svg { width: 18px; height: 18px; }

/* Tinted variant, matching the coloured tiles in the third reference. */
.stat__icon--tinted { border-radius: var(--r-md); }
.stat__icon--green  { background: var(--hue-green-soft);  color: var(--hue-green-ink); }
.stat__icon--blue   { background: var(--hue-blue-soft);   color: var(--hue-blue-ink); }
.stat__icon--amber  { background: var(--hue-amber-soft);  color: var(--hue-amber-ink); }
.stat__icon--red    { background: var(--hue-red-soft);    color: var(--hue-red-ink); }
.stat__icon--violet { background: var(--hue-violet-soft); color: var(--hue-violet-ink); }
.stat__icon--teal   { background: var(--hue-teal-soft);   color: var(--hue-teal-ink); }
.stat__icon--orange { background: var(--hue-orange-soft); color: var(--hue-orange-ink); }
.stat__icon--indigo { background: var(--hue-indigo-soft); color: var(--hue-indigo-ink); }
.stat__icon--crimson{ background: var(--hue-crimson-soft);color: var(--hue-crimson-ink); }
.stat__icon--slate  { background: var(--hue-slate-soft);  color: var(--hue-slate-ink); }

.stat__body { margin-top: auto; min-width: 0; }
.stat__value {
  display: block;
  text-wrap: balance;
  font-size: var(--t-2xl);
  font-weight: var(--fw-bold);
  line-height: 1.15;
  letter-spacing: -.025em;
  color: var(--color-text);
}
.stat__label {
  display: block;
  font-size: var(--t-xs);
  color: var(--color-muted);
  margin-top: 4px;
  line-height: 1.5;
}
.stat__caption {
  display: block;
  font-size: var(--t-xs);
  color: var(--color-faint);
  margin-top: 3px;
}
.stat__delta {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  margin-top: var(--s-2);
}
.stat__delta--up   { color: var(--color-success); }
.stat__delta--down { color: var(--color-danger); }

/* Hero card — the soft pastel gradient panel from the reference. */
.hero-card {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  padding: var(--s-4) var(--s-5) var(--s-5);
  background: var(--gradient-hero);
  border: 1px solid transparent;
  min-height: 128px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  color: var(--color-text);
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--dur) var(--ease);
}
.hero-card:hover { box-shadow: var(--shadow-md); }
.hero-card__value {
  font-size: var(--t-3xl);
  font-weight: var(--fw-bold);
  letter-spacing: -.03em;
  line-height: 1.1;
  margin-top: var(--s-1);
}
.hero-card__label { font-size: var(--t-xs); font-weight: var(--fw-semi); color: var(--color-text-soft); text-transform: uppercase; letter-spacing: .06em; }
.hero-card__meta  { font-size: var(--t-xs); color: var(--color-text-soft); margin-top: var(--s-2); }

/* Banner — the alert strip at the top of the third reference. */
.banner {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-4);
  border-radius: var(--r-lg);
  background: var(--color-card);
  border: 1px solid var(--color-border);
}
.banner__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px;
  height: 46px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--color-danger-soft);
  color: var(--color-danger);
}
.banner__icon svg { width: 21px; height: 21px; }
.banner__text { flex: 1; min-width: 0; font-size: var(--t-md); color: var(--color-text-soft); }
.banner--warning .banner__icon { background: var(--color-warning-soft); color: var(--color-warning-ink); }
.banner--info    .banner__icon { background: var(--color-info-soft);    color: var(--color-info-ink); }
.banner--success .banner__icon { background: var(--color-success-soft); color: var(--color-success-ink); }

@media (max-width: 640px) {
  .banner { flex-direction: column; align-items: flex-start; }
  .card { padding: var(--s-4); border-radius: var(--r-lg); }

  /* Phones get a compact horizontal tile: chip, then figure and label beside
     it. The desktop layout reserves room for a corner action and pushes the
     figure to the bottom, which on a phone is ~130px of mostly empty card —
     five of those cost four screens of scrolling to read five numbers. */
  .stat {
    flex-direction: row;
    align-items: center;
    gap: var(--s-3);
    min-height: 0;
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r-lg);
    transform: none !important; /* no lift on touch */
  }
  .stat__body { margin-top: 0; flex: 1; }
  .stat__corner { display: none; }
  .stat__icon { width: 36px; height: 36px; border-radius: var(--r-md); }
  .stat__icon svg { width: 17px; height: 17px; }
  .stat__value { font-size: var(--t-md); font-weight: var(--fw-bold); line-height: 1.3; }
  .stat__label { font-size: var(--t-2xs); margin-top: 2px; }
  .stat__caption { font-size: var(--t-2xs); }
  .stat__delta { margin-top: var(--s-1); }

  /* Currency figures carry long strings ("۷۷.۳ میلیارد تومان") next to long
     labels; at half width they wrap to three ragged lines. Marked `wide`,
     they take the row — which also matches their importance. */
  .grid .stat--wide { grid-column: 1 / -1; }

  /* The headline figure earns the full width rather than half of it. */
  .grid .hero-card {
    grid-column: 1 / -1;
    min-height: 0;
    padding: var(--s-4) var(--s-4) var(--s-5);
  }
  .hero-card__value { font-size: var(--t-2xl); }
}

/* Avatars ----------------------------------------------------------------- */

.avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  flex: none;
  border-radius: var(--r-full);
  background: var(--color-inset);
  color: var(--color-text-soft);
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  overflow: hidden;
  user-select: none;
}
.avatar--sm { width: 30px; height: 30px; font-size: var(--t-xs); }
.avatar--lg { width: 52px; height: 52px; font-size: var(--t-lg); }
.avatar--xl { width: 68px; height: 68px; font-size: var(--t-xl); }

.avatar--green   { background: var(--hue-green-soft);   color: var(--hue-green-ink); }
.avatar--blue    { background: var(--hue-blue-soft);    color: var(--hue-blue-ink); }
.avatar--amber   { background: var(--hue-amber-soft);   color: var(--hue-amber-ink); }
.avatar--red     { background: var(--hue-red-soft);     color: var(--hue-red-ink); }
.avatar--violet  { background: var(--hue-violet-soft);  color: var(--hue-violet-ink); }
.avatar--teal    { background: var(--hue-teal-soft);    color: var(--hue-teal-ink); }
.avatar--orange  { background: var(--hue-orange-soft);  color: var(--hue-orange-ink); }
.avatar--indigo  { background: var(--hue-indigo-soft);  color: var(--hue-indigo-ink); }
.avatar--crimson { background: var(--hue-crimson-soft); color: var(--hue-crimson-ink); }
.avatar--slate   { background: var(--hue-slate-soft);   color: var(--hue-slate-ink); }

.avatar-stack { display: flex; }
.avatar-stack .avatar { border: 2px solid var(--color-card); }
.avatar-stack .avatar + .avatar { margin-inline-start: -10px; }

/* Person cell used in tables and lists. */
.person { display: flex; align-items: center; gap: var(--s-3); min-width: 0; }
.person__name { font-weight: var(--fw-semi); font-size: var(--t-md); }
.person__meta { font-size: var(--t-xs); color: var(--color-muted); }

/* Session item — active device/browser row in profile page. -------------- */

.session-item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  border-radius: var(--r-md);
  border: 1px solid var(--color-border);
  background: var(--color-card);
  transition: border-color var(--dur-fast) var(--ease), background var(--dur-fast) var(--ease);
}

.session-item--current {
  background: var(--color-inset);
  border-color: var(--color-border);
}

.session-item__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--hue-slate-soft);
  color: var(--hue-slate-ink);
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.session-item__icon--active {
  background: var(--hue-green-soft);
  color: var(--hue-green-ink);
}

.session-item__body {
  flex: 1;
  min-width: 0;
}

.session-item__top {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}

.session-item__device {
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--color-text);
}

.session-item__current-badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 2px 8px;
  border-radius: var(--r-full);
  background: var(--hue-green-soft);
  color: var(--hue-green-ink);
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
}

.session-item__dot {
  width: 6px;
  height: 6px;
  border-radius: var(--r-full);
  background: currentColor;
  flex: none;
  animation: pulse-dot 1.8s ease-in-out infinite;
}

.session-item__meta {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-wrap: wrap;
  margin-top: 3px;
  font-size: var(--t-xs);
  color: var(--color-muted);
}

.session-item__sep { color: var(--color-faint); }

.session-item__ip {
  font-variant-numeric: tabular-nums;
  letter-spacing: .02em;
}

.session-item__action { flex: none; }

.session-item__revoke {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: var(--r-md);
  border: 1px solid transparent;
  background: transparent;
  color: var(--color-muted);
  cursor: pointer;
  transition: background var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}

.session-item__revoke:hover {
  background: var(--color-danger-soft);
  color: var(--color-danger);
  border-color: var(--color-danger-soft);
}

.session-item__active-dot {
  display: block;
  width: 10px;
  height: 10px;
  border-radius: var(--r-full);
  background: var(--hue-green);
  box-shadow: 0 0 0 3px var(--hue-green-soft);
  margin: auto 12px;
  animation: pulse-dot 1.8s ease-in-out infinite;
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; }
  50%       { opacity: .5; }
}


/*! components/badges.css */
/* ==========================================================================
   Badges, chips, pills, progress
   ========================================================================== */

.badge {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 4px 10px;
  border-radius: var(--r-full);
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  line-height: 1.6;
  white-space: nowrap;
  background: var(--hue-slate-soft);
  color: var(--hue-slate-ink);
}
.badge svg { width: 12px; height: 12px; }
.badge--sm { padding: 2px 8px; font-size: var(--t-2xs); }
.badge--lg { padding: 6px 14px; font-size: var(--t-sm); }
.badge--square { border-radius: var(--r-xs); }

.badge--green   { background: var(--hue-green-soft);   color: var(--hue-green-ink); }
.badge--blue    { background: var(--hue-blue-soft);    color: var(--hue-blue-ink); }
.badge--amber   { background: var(--hue-amber-soft);   color: var(--hue-amber-ink); }
.badge--orange  { background: var(--hue-orange-soft);  color: var(--hue-orange-ink); }
.badge--red     { background: var(--hue-red-soft);     color: var(--hue-red-ink); }
.badge--violet  { background: var(--hue-violet-soft);  color: var(--hue-violet-ink); }
.badge--indigo  { background: var(--hue-indigo-soft);  color: var(--hue-indigo-ink); }
.badge--teal    { background: var(--hue-teal-soft);    color: var(--hue-teal-ink); }
.badge--crimson { background: var(--hue-crimson-soft); color: var(--hue-crimson-ink); }
.badge--slate   { background: var(--hue-slate-soft);   color: var(--hue-slate-ink); }

.badge--solid          { color: #fff; }
.badge--solid.badge--green   { background: var(--hue-green); }
.badge--solid.badge--red     { background: var(--hue-red); }
.badge--solid.badge--amber   { background: var(--hue-amber); }
.badge--solid.badge--blue    { background: var(--hue-blue); }
.badge--solid.badge--crimson { background: var(--hue-crimson); }

/* Small leading dot for stage/status legibility at a glance. */
.badge__dot {
  width: 6px; height: 6px;
  border-radius: var(--r-full);
  background: currentColor;
  flex: none;
}

/* Counter pill on nav items and tabs. */
.count-pill {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding-inline: 6px;
  border-radius: var(--r-full);
  background: var(--color-inset);
  color: var(--color-muted);
  font-size: var(--t-2xs);
  font-weight: var(--fw-bold);
}
.count-pill--accent { background: var(--color-primary); color: #fff; }
.count-pill--danger { background: var(--color-danger-soft); color: var(--color-danger-ink); }

/* Progress bar ------------------------------------------------------------ */

.progress {
  height: 7px;
  border-radius: var(--r-full);
  background: var(--color-inset);
  overflow: hidden;
}
.progress__bar {
  height: 100%;
  border-radius: var(--r-full);
  background: var(--color-ink);
  transition: width var(--dur-slow) var(--ease);
}
.progress--lg { height: 10px; }
.progress__bar--green  { background: var(--hue-green); }
.progress__bar--amber  { background: var(--hue-amber); }
.progress__bar--red    { background: var(--hue-red); }
.progress__bar--blue   { background: var(--hue-blue); }
.progress__bar--violet { background: var(--hue-violet); }

/* Ring gauge — the "340 Day" badge in the third reference. */
.ring {
  position: relative;
  width: 74px;
  height: 74px;
  flex: none;
}
.ring svg { transform: rotate(-90deg); width: 100%; height: 100%; }
.ring__track { stroke: var(--color-inset); }
.ring__value {
  stroke: var(--color-success);
  stroke-linecap: round;
  transition: stroke-dashoffset var(--dur-slow) var(--ease);
}
.ring__label {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-size: var(--t-md);
  font-weight: var(--fw-bold);
  line-height: 1.1;
}
.ring__label small { font-size: var(--t-2xs); font-weight: var(--fw-normal); color: var(--color-muted); }
.ring--sm { width: 54px; height: 54px; }
.ring--lg { width: 96px; height: 96px; }

/* Toggle switch ----------------------------------------------------------- */

.switch { display: inline-flex; align-items: center; gap: var(--s-3); cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch__track {
  position: relative;
  width: 40px; height: 23px;
  border-radius: var(--r-full);
  background: var(--color-border-strong);
  transition: background-color var(--dur) var(--ease);
  flex: none;
}
.switch__track::after {
  content: '';
  position: absolute;
  top: 3px;
  inset-inline-start: 3px;
  width: 17px; height: 17px;
  border-radius: var(--r-full);
  background: #fff;
  box-shadow: var(--shadow-xs);
  transition: transform var(--dur) var(--ease);
}
.switch input:checked + .switch__track { background: var(--color-success); }
.switch input:checked + .switch__track::after { transform: translateX(-17px); }
.switch input:focus-visible + .switch__track { box-shadow: var(--shadow-ring); }

/* Left-to-right layouts (should any exist) flip the knob the other way. */
[dir='ltr'] .switch input:checked + .switch__track::after { transform: translateX(17px); }


/*! components/forms.css */
/* ==========================================================================
   Forms — single-column on mobile by default, quiet borders, clear focus.
   ========================================================================== */

.field { display: flex; flex-direction: column; gap: 7px; min-width: 0; }

.label {
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--color-text-soft);
  display: flex;
  align-items: center;
  gap: 5px;
}
.label__required { color: var(--color-primary); }
.label__hint { font-weight: var(--fw-normal); color: var(--color-faint); font-size: var(--t-xs); }

.input,
.select,
.textarea {
  width: 100%;
  min-height: 42px;
  padding: 10px var(--s-4);
  border-radius: var(--r-sm);
  border: 1px solid var(--color-input-border);
  background: var(--color-input);
  color: var(--color-text);
  font-size: var(--t-md);
  font-family: inherit;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.input:hover, .select:hover, .textarea:hover { border-color: var(--color-border-strong); }

.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: var(--color-input-focus);
  box-shadow: 0 0 0 3px var(--color-inset);
}

.textarea { min-height: 96px; resize: vertical; line-height: 1.8; }

.select {
  appearance: none;
  padding-inline-end: var(--s-8);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%238A9099' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: left var(--s-4) center;
  cursor: pointer;
}
[data-theme='dark'] .select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23949BA5' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
}

.input--error, .select--error, .textarea--error {
  border-color: var(--color-danger);
  background: var(--color-danger-soft);
}

.field__error {
  font-size: var(--t-xs);
  color: var(--color-danger);
  display: flex;
  align-items: center;
  gap: 4px;
}
.field__help { font-size: var(--t-xs); color: var(--color-muted); }

/* Input with a leading icon (search, phone, currency). */
.input-group { position: relative; display: flex; align-items: center; }
.input-group .input { padding-inline-start: var(--s-8); }
.input-group__icon {
  position: absolute;
  inset-inline-start: var(--s-3);
  color: var(--color-faint);
  pointer-events: none;
  display: flex;
}
.input-group__icon svg { width: 16px; height: 16px; }
.input-group__suffix {
  position: absolute;
  inset-inline-end: var(--s-3);
  font-size: var(--t-xs);
  color: var(--color-muted);
  pointer-events: none;
}
.input-group--suffixed .input { padding-inline-end: var(--s-9); }

.input-group--pw .input {
  padding-inline-end: 38px;
  direction: ltr;
  text-align: left;
}

.input-group__toggle-pw {
  position: absolute;
  inset-inline-end: 6px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border: none;
  background: transparent;
  color: var(--color-muted);
  border-radius: var(--r-xs);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.input-group__toggle-pw:hover {
  color: var(--color-text);
  background: var(--color-hover);
}
.input-group__toggle-pw svg {
  width: 16px;
  height: 16px;
}

/* Checkbox / radio -------------------------------------------------------- */

.check {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
  font-size: var(--t-md);
  user-select: none;
}
.check input {
  appearance: none;
  width: 18px; height: 18px;
  flex: none;
  border: 1.5px solid var(--color-border-strong);
  border-radius: 5px;
  background: var(--color-input);
  transition: all var(--dur-fast) var(--ease);
  position: relative;
}
.check input[type='radio'] { border-radius: var(--r-full); }
.check input:checked {
  background: var(--color-ink);
  border-color: var(--color-ink);
}
.check input:checked::after {
  content: '';
  position: absolute;
  inset: 0;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-size: 11px;
  background-repeat: no-repeat;
  background-position: center;
}
[data-theme='dark'] .check input:checked::after {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23101216' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
}
.check input[type='radio']:checked::after {
  background-image: none;
  background: #fff;
  border-radius: var(--r-full);
  inset: 4px;
}

/* Choice cards — used for reminder offsets, loss reasons, target types. */
.choice-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: var(--s-2); }
.choice {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3);
  border: 1px solid var(--color-border);
  border-radius: var(--r-sm);
  font-size: var(--t-sm);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}
.choice:hover { border-color: var(--color-border-strong); background: var(--color-hover); }
.choice--active {
  border-color: var(--color-ink);
  background: var(--color-inset);
  font-weight: var(--fw-semi);
}
/* The real control is hidden behind the label, so the label has to carry both
   states itself — otherwise a keyboard user gets no focus ring at all, and the
   selected option only looks selected until the next click. */
.choice input { position: absolute; opacity: 0; }
.choice:has(input:checked) {
  border-color: var(--color-ink);
  background: var(--color-inset);
  font-weight: var(--fw-semi);
}
.choice:has(input:focus-visible) {
  border-color: var(--color-ink);
  box-shadow: var(--shadow-ring);
}

/* Small colour dot inside a `.choice` — the note colour picker. */
.choice__swatch {
  width: 14px;
  height: 14px;
  border-radius: var(--r-full);
  flex: none;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .08);
}

/* Compact color picker swatches ------------------------------------------- */

.color-picker {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}

.color-swatch {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border-radius: var(--r-full);
  border: 1px solid var(--color-border);
  background: var(--color-card);
  color: var(--color-text-soft);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}

.color-swatch:hover {
  border-color: var(--color-border-strong);
  background: var(--color-hover);
  color: var(--color-text);
}

.color-swatch--active {
  border-color: var(--color-ink);
  background: var(--color-inset);
  color: var(--color-text);
  font-weight: var(--fw-semi);
  box-shadow: 0 0 0 1px var(--color-ink);
}

.color-swatch__dot {
  width: 12px;
  height: 12px;
  border-radius: var(--r-full);
  flex: none;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.12);
}

/* Form layout ------------------------------------------------------------- */

.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s-4); }
.form-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.form-grid__full { grid-column: 1 / -1; }

@media (max-width: 760px) {
  .form-grid, .form-grid--3 { grid-template-columns: minmax(0, 1fr); }
}

.form-section + .form-section { margin-top: var(--s-6); padding-top: var(--s-6); border-top: 1px solid var(--color-divider); }
.form-section__title { font-size: var(--t-md); font-weight: var(--fw-bold); margin-bottom: var(--s-4); }

.form-actions {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-6);
  padding-top: var(--s-5);
  border-top: 1px solid var(--color-divider);
}
@media (max-width: 560px) {
  .form-actions { flex-direction: column-reverse; align-items: stretch; }
  .form-actions .btn { width: 100%; }
}

/* Filter bar -------------------------------------------------------------- */

.filters {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.filters .select, .filters .input { min-height: 38px; font-size: var(--t-sm); width: auto; min-width: 132px; }
.filters .input-group { width: auto; }
.filters .input-group .input { min-width: 148px; }
.filters__search { flex: 1; min-width: 200px; }
.filters__search .input { width: 100%; }

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 10px 5px 8px;
  border-radius: var(--r-full);
  background: var(--color-inset);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
}
.filter-chip button { display: flex; color: var(--color-faint); }
.filter-chip button:hover { color: var(--color-danger); }
.filter-chip svg { width: 12px; height: 12px; }

/* Active filters, rendered as chips that are always fully visible. Hiding
   applied filters — behind a scroll or behind a button — means the reader
   cannot tell what is shaping the numbers in front of them. */
.filter-summary {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  flex-wrap: wrap;
}
.filter-summary .filter-chip a { display: flex; color: var(--color-faint); }
.filter-summary .filter-chip a:hover { color: var(--color-danger); }
.filter-summary__clear {
  font-size: var(--t-xs);
  color: var(--color-muted);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.filter-summary__clear:hover { color: var(--color-danger); }

/* The extra selects live in a wrapper that dissolves on desktop, so one set
   of inputs serves both the inline bar and the phone sheet. */
.filters__toggle { display: none; }

@media (min-width: 761px) {
  /* `display: contents` dissolves the wrapper, but `visibility` still
     inherits — without resetting it the inline selects would go invisible
     along with every other closed drawer. */
  .filters--summary .filters__more { display: contents; visibility: visible; }
  .filters--summary .filters__more-chrome { display: none; }

  /* The selects themselves already show the state at this width, so the
     chips would only repeat it — keep just the reset. */
  .filter-summary .filter-chip { display: none; }
  .filter-summary { justify-content: flex-end; }
}

/* Phones: period stays inline, the rest moves into a sheet, and the chips
   above carry the state. A four-select bar otherwise wraps to three rows and
   pushes every number below the fold. */
@media (max-width: 760px) {
  .filters--summary { flex-wrap: nowrap; }
  .filters--summary > .select { flex: 1; min-width: 0; }
  .filters__toggle { display: inline-flex; flex: none; }
  .filters--summary .filters__more { padding: var(--s-4); gap: var(--s-3); }
  .filters--summary .filters__more .select { width: 100%; }
  .filters--summary .filters__more-chrome { display: flex; }
  .filters__more .drawer__head { padding: 0 0 var(--s-3); margin-bottom: var(--s-1); }
  .filters__more .drawer__foot { padding: var(--s-3) 0 0; }
}

/* Custom Searchable Select ------------------------------------------------ */

.custom-select {
  position: relative;
  width: 100%;
}

.custom-select__trigger {
  width: 100%;
  min-height: 42px;
  padding: 10px var(--s-4);
  border-radius: var(--r-sm);
  border: 1px solid var(--color-input-border);
  background: var(--color-input);
  color: var(--color-text);
  font-size: var(--t-md);
  font-family: inherit;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-2);
  cursor: pointer;
  text-align: start;
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.custom-select__trigger:hover {
  border-color: var(--color-border-strong);
}

.custom-select__trigger:focus,
.custom-select__trigger[aria-expanded='true'] {
  outline: none;
  border-color: var(--color-input-focus);
  box-shadow: 0 0 0 3px var(--color-inset);
}

.custom-select__label {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.custom-select__icon {
  color: var(--color-faint);
  flex: none;
  transition: transform var(--dur-fast) var(--ease);
}

.custom-select__trigger[aria-expanded='true'] .custom-select__icon {
  transform: rotate(180deg);
}

.custom-select__dropdown {
  position: absolute;
  top: calc(100% + 4px);
  inset-inline-start: 0;
  inset-inline-end: 0;
  z-index: 100;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  padding: 6px;
}

.custom-select__search-wrap {
  position: relative;
  display: flex;
  align-items: center;
  padding-bottom: 6px;
  border-bottom: 1px solid var(--color-divider);
}

.custom-select__search-icon {
  position: absolute;
  inset-inline-start: 10px;
  color: var(--color-faint);
  pointer-events: none;
}

.custom-select__search-input {
  width: 100%;
  height: 36px;
  padding: 6px var(--s-3);
  padding-inline-start: 32px;
  border: 1px solid var(--color-border);
  border-radius: var(--r-xs);
  background: var(--color-inset);
  color: var(--color-text);
  font-size: var(--t-sm);
  font-family: inherit;
}

.custom-select__search-input:focus {
  outline: none;
  border-color: var(--color-input-focus);
}

.custom-select__options {
  max-height: 180px;
  overflow-y: auto;
  margin-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.custom-select__option {
  padding: 8px var(--s-3);
  border-radius: var(--r-xs);
  font-size: var(--t-sm);
  color: var(--color-text-soft);
  cursor: pointer;
  user-select: none;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}

.custom-select__option:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

.custom-select__option--selected {
  background: var(--color-inset);
  color: var(--color-ink);
  font-weight: var(--fw-semi);
}

.custom-select__empty {
  padding: var(--s-3);
  text-align: center;
  font-size: var(--t-sm);
  color: var(--color-faint);
}


/*! components/tables.css */
/* ==========================================================================
   Tables — airy rows, hairline dividers, no zebra striping. On narrow
   screens each row becomes a card rather than a horizontally-cropped table.
   ========================================================================== */

.table-wrap { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--t-md);
}

.table thead th {
  padding: var(--s-3) var(--s-4);
  text-align: start;
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  color: var(--color-muted);
  white-space: nowrap;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-card);
}

.table tbody td {
  padding: var(--s-4);
  border-bottom: 1px solid var(--color-divider);
  vertical-align: middle;
}

.table tbody tr:last-child td { border-bottom: none; }
.table tbody tr { transition: background-color var(--dur-fast) var(--ease); }
.table tbody tr:hover { background: var(--color-hover); }

.table--compact tbody td { padding: var(--s-3) var(--s-4); }
.table--compact thead th { padding: var(--s-2) var(--s-4); }

.table__num { font-variant-numeric: tabular-nums; white-space: nowrap; }
.table__actions { width: 1%; white-space: nowrap; text-align: end; }
.table__primary { font-weight: var(--fw-semi); }
.table__sub { font-size: var(--t-xs); color: var(--color-muted); margin-top: 1px; }

/* Sortable header. */
.table__sort {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: inherit;
  font: inherit;
}
.table__sort:hover { color: var(--color-text); }
.table__sort svg { width: 12px; height: 12px; opacity: .5; }
.table__sort--active { color: var(--color-text); }
.table__sort--active svg { opacity: 1; }

/* Sticky first column for wide tables on desktop. */
.table--sticky-first th:first-child,
.table--sticky-first td:first-child {
  position: sticky;
  inset-inline-start: 0;
  background: var(--color-card);
  z-index: 1;
}
.table--sticky-first tbody tr:hover td:first-child { background: var(--color-hover); }

/* Mobile: rows become stacked cards using data-label attributes. */
@media (max-width: 820px) {
  /* Leave table layout entirely. Kept as `display: table`, the browser sizes
     the box from the widest cell's min-content, so on a narrow phone the
     cards grow past the viewport and their contents get clipped. */
  .table--responsive,
  .table--responsive tbody { display: block; width: 100%; }
  .table--responsive thead { display: none; }

  /* …and with the table no longer able to exceed it, the wrapper must not
     offer a scrollbar that now scrolls nothing. */
  .table-wrap:has(.table--responsive) { overflow-x: visible; }

  .table--responsive tbody tr {
    display: block;
    padding: var(--s-4);
    border: 1px solid var(--color-border);
    border-radius: var(--r-lg);
    margin-bottom: var(--s-3);
    background: var(--color-card);
    max-width: 100%;
  }
  .table--responsive tbody tr:hover { background: var(--color-card); }
  .table--responsive tbody td {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-3);
    padding: 6px 0;
    border: none;
    max-width: 100%;
  }
  .table--responsive tbody td::before {
    content: attr(data-label);
    font-size: var(--t-xs);
    color: var(--color-muted);
    font-weight: var(--fw-medium);
    flex: 0 1 auto;
    max-width: 42%;          /* a long label must not squeeze out the value */
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .table--responsive tbody td[data-label='']::before { display: none; }

  /* Without this the value side refuses to shrink below its content width
     and pushes itself off the card — names, badges and money all did. */
  .table--responsive tbody td > * { min-width: 0; }
  .table--responsive tbody td > .num,
  .table--responsive tbody td > span:not([class]) {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  /* The first column is the record's identity on every list. As a card it is
     the title, not a label/value pair — so it drops the label, takes the full
     width, and wraps instead of truncating. A half-readable name
     («آژانس تبلیغاتی …») is the one thing a card must never do. */
  .table--responsive tbody td:first-child {
    display: block;
    padding-bottom: var(--s-3);
    margin-bottom: var(--s-2);
    border-bottom: 1px solid var(--color-divider);
  }
  .table--responsive tbody td:first-child::before { display: none; }

  .table--responsive tbody td:first-child .person__name,
  .table--responsive tbody td:first-child .person__meta,
  .table--responsive tbody td:first-child .table__primary,
  .table--responsive tbody td:first-child .table__sub,
  .table--responsive tbody td:first-child .truncate {
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
    overflow-wrap: anywhere;
  }
  .table--responsive tbody td:first-child .person__name,
  .table--responsive tbody td:first-child .table__primary {
    font-size: var(--t-base);
    font-weight: var(--fw-bold);
    line-height: 1.5;
  }
  /* `width: 1%` is a table-layout trick to keep the actions column tight.
     Once the row is a block card it collapses the cell to a few pixels and
     the menu button spills out of it. */
  .table--responsive .table__actions {
    width: auto;
    justify-content: flex-end;
    text-align: start;
  }

  /* A 208px menu hanging off a ~290px card lands outside it. The default
     anchor already opens it inward from the trigger; it just needs to be
     capped to what the screen can actually show. */
  .table--responsive .dropdown__menu {
    min-width: 0;
    width: max-content;
    max-width: min(240px, calc(100vw - var(--s-9)));
  }
}

/* Pagination -------------------------------------------------------------- */

.pagination {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--color-divider);
  flex-wrap: wrap;
}
.pagination__info { font-size: var(--t-sm); color: var(--color-muted); }
.pagination__pages { display: flex; align-items: center; gap: 4px; }
.pagination__page {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 34px;
  height: 34px;
  padding-inline: 8px;
  border-radius: var(--r-xs);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  color: var(--color-text-soft);
  transition: all var(--dur-fast) var(--ease);
}
.pagination__page:hover { background: var(--color-hover); }
.pagination__page--active { background: var(--color-ink); color: var(--color-on-ink); font-weight: var(--fw-semi); }
.pagination__page--disabled { opacity: .4; pointer-events: none; }
.pagination__page svg { width: 15px; height: 15px; }

/* List rows (used where a table would be overkill) ------------------------ */

.list-row {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  transition: background-color var(--dur-fast) var(--ease);
}
.list-row:hover { background: var(--color-hover); }
.list-row + .list-row { margin-top: 2px; }
.list-divided > * + * { border-top: 1px solid var(--color-divider); }

/* Unread emphasis — the notification list and similar feeds. */
.list-row--unread { background: var(--color-inset); }
.list-row--unread:hover { background: var(--color-hover); }
.list-row__unread-dot {
  width: 8px;
  height: 8px;
  border-radius: var(--r-full);
  background: var(--color-primary);
  flex: none;
}

.data-list { display: grid; gap: var(--s-3); }
.data-list__item { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.data-list__key { font-size: var(--t-sm); color: var(--color-muted); flex: none; }
.data-list__value { font-size: var(--t-md); font-weight: var(--fw-medium); text-align: end; min-width: 0; }


/*! components/sidebar.css */
/* ==========================================================================
   Sidebar — the reference uses a horizontal pill nav, which cannot carry a
   fifteen-item CRM. This keeps its visual language (pill active state, thin
   icons, generous spacing) in a vertical rail that scales.
   ========================================================================== */

.sidebar {
  width: var(--sidebar-w);
  flex: none;
  background: var(--color-sidebar);
  border-inline-end: 1px solid var(--color-border);
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  z-index: 40;
  transition: width var(--dur) var(--ease);
}

.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  height: var(--topbar-h);
  padding-inline: var(--s-5);
  flex: none;
}
/* Brand lockup ------------------------------------------------------------
   The artwork already contains the wordmark, so the brand block is just the
   image (optionally over a tagline) rather than a mark plus a text name. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--s-3);
  min-width: 0;
}
.brand--stacked {
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}
.brand__img {
  width: auto;
  max-width: 100%;
  object-fit: contain;
  object-position: right center;
  display: block;
}
[dir='ltr'] .brand__img { object-position: left center; }
.brand__tagline {
  font-size: var(--t-2xs);
  color: var(--color-muted);
  white-space: nowrap;
}

/* The mark is mid-blue on transparency and reads on both canvases; on dark it
   just needs a touch more presence. */
[data-theme='dark'] .brand__img { filter: brightness(1.12); }

.sidebar__name { font-weight: var(--fw-bold); font-size: var(--t-lg); letter-spacing: -.02em; }
.sidebar__tag  { font-size: var(--t-2xs); color: var(--color-muted); margin-top: -3px; }

.sidebar__nav {
  flex: 1;
  overflow-y: auto;
  padding: var(--s-2) var(--s-3) var(--s-5);
}

.sidebar__section { margin-top: var(--s-5); }
.sidebar__section:first-child { margin-top: 0; }
.sidebar__section-title {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
  color: var(--color-faint);
  padding: 0 var(--s-3) var(--s-2);
  letter-spacing: .04em;
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: 9px var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--t-md);
  font-weight: var(--fw-medium);
  color: var(--color-muted);
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
  position: relative;
}
.nav-item + .nav-item { margin-top: 2px; }
.nav-item svg { width: 18px; height: 18px; flex: none; }
.nav-item:hover { background: var(--color-sidebar-hover); color: var(--color-text); }

.nav-item--active {
  background: var(--color-sidebar-active);
  color: var(--color-on-ink);
  font-weight: var(--fw-semi);
}
.nav-item--active:hover { background: var(--color-sidebar-active); color: var(--color-on-ink); }
.nav-item__badge { margin-inline-start: auto; }
.nav-item--active .count-pill { background: rgba(255, 255, 255, .2); color: #fff; }
[data-theme='dark'] .nav-item--active .count-pill { background: rgba(0, 0, 0, .18); color: var(--color-on-ink); }

.sidebar__foot {
  flex: none;
  padding: var(--s-3);
  border-top: 1px solid var(--color-border);
}

/* The user card at the foot of the rail. */
.user-card {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2);
  border-radius: var(--r-md);
  width: 100%;
  transition: background-color var(--dur-fast) var(--ease);
}
.user-card:hover { background: var(--color-sidebar-hover); }
.user-card__name { font-size: var(--t-md); font-weight: var(--fw-semi); }
.user-card__role { font-size: var(--t-2xs); color: var(--color-muted); }

/* Mobile drawer ----------------------------------------------------------- */

.sidebar__close { display: none; }

@media (max-width: 1100px) {
  .sidebar {
    position: fixed;
    inset-block: 0;
    inset-inline-start: 0;
    transform: translateX(100%);
    box-shadow: var(--shadow-lg);
    z-index: var(--z-drawer);
    /* Off-canvas navigation stays out of the tab order until it is opened. */
    visibility: hidden;
    transition: transform var(--dur) var(--ease), width var(--dur) var(--ease), visibility 0s linear var(--dur);
  }
  [dir='ltr'] .sidebar { transform: translateX(-100%); }
  .sidebar--open {
    transform: translateX(0);
    visibility: visible;
    transition: transform var(--dur) var(--ease), width var(--dur) var(--ease);
  }
  .sidebar__close { display: inline-flex; margin-inline-start: auto; }
}

.scrim {
  position: fixed;
  inset: 0;
  background: var(--scrim);
  backdrop-filter: blur(2px);
  z-index: calc(var(--z-drawer) - 1);
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur) var(--ease);
}
.scrim--visible { opacity: 1; pointer-events: auto; }

/* Bottom tab bar for phones — the five most-used destinations. */
.tabbar {
  display: none;
  position: fixed;
  inset-inline: 0;
  bottom: 0;
  z-index: 45;
  background: var(--color-card);
  border-top: 1px solid var(--color-border);
  padding: 6px var(--s-2) calc(6px + env(safe-area-inset-bottom, 0px));
}
.tabbar__inner { display: flex; align-items: stretch; justify-content: space-around; }
.tabbar__item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 3px;
  padding: 6px 10px;
  border-radius: var(--r-sm);
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  color: var(--color-muted);
  flex: 1;
}
.tabbar__item svg { width: 20px; height: 20px; }
.tabbar__item--active { color: var(--color-text); }
.tabbar__item--active svg { color: var(--color-primary); }

@media (max-width: 700px) {
  .tabbar { display: block; }
}


/* ==========================================================================
   Phone menu sheet
   Fifteen identical rows are hard to scan; as cards each destination gets an
   icon, a colour and a line of explanation, two per row.
   ========================================================================== */

.menu-sheet__section {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
  color: var(--color-faint);
  letter-spacing: .04em;
  margin: var(--s-4) 0 var(--s-2);
}
.menu-sheet__section:first-child { margin-top: 0; }

.menu-sheet__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s-2);
}

.menu-card {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4) var(--s-4);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  background: var(--color-card);
  color: inherit;
  min-height: 104px;
  transition: border-color var(--dur-fast) var(--ease), background-color var(--dur-fast) var(--ease);
}
.menu-card:hover { border-color: var(--color-border-strong); background: var(--color-hover); }
.menu-card:active { background: var(--color-active); }

.menu-card__top { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); }

.menu-card__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px; height: 40px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--hue-slate-soft);
  color: var(--hue-slate-ink);
}
.menu-card__icon--blue    { background: var(--hue-blue-soft);    color: var(--hue-blue-ink); }
.menu-card__icon--teal    { background: var(--hue-teal-soft);    color: var(--hue-teal-ink); }
.menu-card__icon--violet  { background: var(--hue-violet-soft);  color: var(--hue-violet-ink); }
.menu-card__icon--indigo  { background: var(--hue-indigo-soft);  color: var(--hue-indigo-ink); }
.menu-card__icon--amber   { background: var(--hue-amber-soft);   color: var(--hue-amber-ink); }
.menu-card__icon--orange  { background: var(--hue-orange-soft);  color: var(--hue-orange-ink); }
.menu-card__icon--green   { background: var(--hue-green-soft);   color: var(--hue-green-ink); }
.menu-card__icon--crimson { background: var(--hue-crimson-soft); color: var(--hue-crimson-ink); }
.menu-card__icon--slate   { background: var(--hue-slate-soft);   color: var(--hue-slate-ink); }

.menu-card__label { font-size: var(--t-md); font-weight: var(--fw-semi); margin-top: auto; }
.menu-card__desc  { font-size: var(--t-2xs); color: var(--color-muted); }

/* The page you are on, marked the same way the rail marks it. */
.menu-card--active {
  background: var(--color-sidebar-active);
  border-color: var(--color-sidebar-active);
}
.menu-card--active .menu-card__label,
.menu-card--active .menu-card__desc { color: var(--color-on-ink); }
.menu-card--active .menu-card__desc { opacity: .7; }
.menu-card--active:hover { background: var(--color-sidebar-active); }

/* A section with a single destination takes the row rather than leaving half
   of it blank — it reads as a header for what follows. */
.menu-sheet__grid > .menu-card:only-child {
  grid-column: 1 / -1;
  flex-direction: row;
  align-items: center;
  gap: var(--s-3);
  min-height: 0;
  padding: var(--s-3) var(--s-4);
}
.menu-sheet__grid > .menu-card:only-child .menu-card__top { flex: none; }
.menu-sheet__grid > .menu-card:only-child .menu-card__label { margin-top: 0; }
.menu-sheet__grid > .menu-card:only-child .menu-card__desc { margin-inline-start: auto; }

.menu-account {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  color: inherit;
}
.menu-account:hover { background: var(--color-hover); }
.menu-account__name { font-size: var(--t-md); font-weight: var(--fw-semi); }
.menu-account__role { font-size: var(--t-2xs); color: var(--color-muted); }

.menu-sheet__row { display: flex; gap: var(--s-2); margin-top: var(--s-2); }

/* The sheet covers every width where the rail is off-canvas; above that the
   rail is present and the sheet must never open. */
@media (min-width: 1101px) {
  #menu-modal { display: none !important; }
}

/* Roomier grid once there is more than a phone's width to work with. */
@media (min-width: 641px) and (max-width: 1100px) {
  .menu-sheet__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}


/*! components/header.css */
/* ==========================================================================
   Topbar — page title on one side, search and controls on the other, with
   the reference's grouped circular icon buttons.
   ========================================================================== */

.topbar {
  position: sticky;
  top: 0;
  z-index: 35;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  height: var(--topbar-h);
  padding-inline: var(--s-6);
  background: var(--color-header);
  backdrop-filter: saturate(180%) blur(14px);
  border-bottom: 1px solid var(--color-border);
}

/* The menu button must appear wherever the rail is hidden. The rail goes
   off-canvas at 1100px, so anything narrower needs this — between 901px and
   1100px there was previously no way to reach navigation at all. */
.topbar__menu { display: none; }
@media (max-width: 1100px) {
  .topbar__menu { display: inline-flex; }
}

.topbar__notes-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: 6px 12px;
  border-radius: var(--r-full);
  background: var(--color-inset);
  color: var(--color-text-soft);
  font-size: var(--t-sm);
  font-weight: var(--fw-medium);
  transition: all var(--dur-fast) var(--ease);
  text-decoration: none;
}

.topbar__notes-btn:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

.topbar__notes-btn--active {
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-weight: var(--fw-semi);
}

.topbar__title { font-size: var(--t-xl); font-weight: var(--fw-bold); letter-spacing: -.02em; }
.topbar__subtitle { font-size: var(--t-sm); color: var(--color-muted); }

.topbar__controls {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-inline-start: auto;
}

/* Grouped icon buttons inside one pill, as in the first reference. */
.icon-group {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  border-radius: var(--r-full);
  background: var(--color-inset);
}
.icon-group .icon-btn { border-color: transparent; background: transparent; width: 34px; height: 34px; }
.icon-group .icon-btn:hover { background: var(--color-card); }

/* Global search ----------------------------------------------------------- */

.searchbar { position: relative; width: 340px; max-width: 100%; }
.searchbar .input { min-height: 38px; border-radius: var(--r-full); background: var(--color-inset); border-color: transparent; }
.searchbar .input:focus { background: var(--color-card); border-color: var(--color-input-focus); }

.search-results {
  position: absolute;
  top: calc(100% + 8px);
  inset-inline: 0;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: var(--s-2);
  max-height: 420px;
  overflow-y: auto;
  z-index: 50;
}
.search-results__group { padding: var(--s-2) var(--s-3) 4px; font-size: var(--t-2xs); color: var(--color-faint); font-weight: var(--fw-semi); }
.search-result {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
}
.search-result:hover, .search-result--active { background: var(--color-hover); }
.search-result__name { font-size: var(--t-md); font-weight: var(--fw-medium); }
.search-result__meta { font-size: var(--t-xs); color: var(--color-muted); }

/* Page header (inside content, below the topbar) --------------------------- */

.page-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s-4);
  margin-bottom: var(--s-5);
  flex-wrap: wrap;
}
.page-head__title {
  font-size: var(--t-2xl);
  font-weight: var(--fw-bold);
  letter-spacing: -.025em;
  display: flex;
  align-items: center;
  gap: var(--s-3);
}
.page-head__note { font-size: var(--t-md); color: var(--color-muted); font-weight: var(--fw-normal); }
.page-head__actions { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }

.breadcrumb { display: flex; align-items: center; gap: 6px; font-size: var(--t-sm); color: var(--color-muted); margin-bottom: 6px; }
.breadcrumb a:hover { color: var(--color-text); }
.breadcrumb svg { width: 13px; height: 13px; opacity: .6; }

@media (max-width: 900px) {
  .topbar { padding-inline: var(--s-4); gap: var(--s-2); }
  .searchbar { width: auto; flex: 1; }
  .page-head__title { font-size: var(--t-xl); }
}


/*! components/modals.css */
/* ==========================================================================
   Modals, drawers, dropdowns, toasts, tooltips
   ========================================================================== */

.modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-4);
  opacity: 0;
  pointer-events: none;
  /* `opacity: 0` hides a dialog from the eye but not from the keyboard: Tab
     still walks into its fields, and a date field reached that way would pop
     its picker open over a page with no dialog in sight. `visibility` takes
     the whole subtree out of the tab order and out of hit testing; delaying
     it by the fade duration keeps the closing animation visible. */
  visibility: hidden;
  transition: opacity var(--dur) var(--ease), visibility 0s linear var(--dur);
}
.modal--open {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity var(--dur) var(--ease);
}

.modal__backdrop { position: absolute; inset: 0; background: var(--scrim); backdrop-filter: blur(3px); }

.modal__panel {
  position: relative;
  width: 100%;
  max-width: 520px;
  max-height: calc(100dvh - var(--s-8));
  display: flex;
  flex-direction: column;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-xl);
  box-shadow: var(--shadow-lg);
  transform: translateY(10px) scale(.99);
  transition: transform var(--dur) var(--ease);
  overflow: hidden;
}
.modal--open .modal__panel { transform: none; }

.modal__panel--sm { max-width: 400px; }
.modal__panel--lg { max-width: 720px; }
.modal__panel--xl { max-width: 940px; }

.modal__panel > form {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  overflow: hidden;
}

.modal__head {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-5) var(--s-5) var(--s-4);
  flex: none;
}
.modal__title { font-size: var(--t-lg); font-weight: var(--fw-bold); }
.modal__desc  { font-size: var(--t-sm); color: var(--color-muted); margin-top: 3px; }
.modal__close { margin-inline-start: auto; }

.modal__body { padding: 0 var(--s-5) var(--s-5); overflow-y: auto; flex: 1; min-height: 0; overscroll-behavior: contain; }

.modal__foot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--s-2);
  padding: var(--s-4) var(--s-5);
  border-top: 1px solid var(--color-divider);
  flex: none;
}

/* Confirmation dialog icon. */
.modal__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 46px; height: 46px;
  flex: none;
  border-radius: var(--r-md);
  background: var(--color-danger-soft);
  color: var(--color-danger);
}
.modal__icon--warning { background: var(--color-warning-soft); color: var(--color-warning-ink); }
.modal__icon--info    { background: var(--color-info-soft);    color: var(--color-info-ink); }
.modal__icon--success { background: var(--color-success-soft); color: var(--color-success-ink); }
.modal__icon svg { width: 21px; height: 21px; }

/* On phones a modal becomes a bottom sheet — easier to reach one-handed. */
@media (max-width: 640px) {
  .modal { align-items: flex-end; padding: 0; }
  .modal__panel {
    max-width: none;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    max-height: 92dvh;
    transform: translateY(100%);
  }
  .modal--open .modal__panel { transform: none; }
  .modal__panel::before {
    content: '';
    display: block;
    width: 38px; height: 4px;
    border-radius: var(--r-full);
    background: var(--color-border-strong);
    margin: var(--s-3) auto 0;
  }
  .modal__foot { padding-bottom: calc(var(--s-4) + env(safe-area-inset-bottom, 0px)); }
  .modal__foot .btn { flex: 1; }
}

/* Side drawer (record detail, filters on desktop) -------------------------- */

.drawer {
  position: fixed;
  inset-block: 0;
  inset-inline-end: 0;
  width: 460px;
  max-width: 100vw;
  z-index: var(--z-modal);
  background: var(--color-card);
  border-inline-start: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  display: flex;
  flex-direction: column;
  transform: translateX(-100%);
  /* Off-canvas, not gone: see the note on `.modal`. */
  visibility: hidden;
  transition: transform var(--dur) var(--ease), visibility 0s linear var(--dur);
}
[dir='ltr'] .drawer { transform: translateX(100%); }
.drawer--open {
  transform: none;
  visibility: visible;
  transition: transform var(--dur) var(--ease);
}

.drawer__head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-4) var(--s-5);
  border-bottom: 1px solid var(--color-divider);
  flex: none;
}
.drawer__body { flex: 1; overflow-y: auto; padding: var(--s-5); }
.drawer__foot { flex: none; padding: var(--s-4) var(--s-5); border-top: 1px solid var(--color-divider); display: flex; gap: var(--s-2); }

/* Filters become a bottom sheet on phones. */
@media (max-width: 640px) {
  .drawer {
    inset-block: auto 0;
    inset-inline: 0;
    width: auto;
    max-height: 88dvh;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-inline-start: none;
    border-top: 1px solid var(--color-border);
    transform: translateY(100%);
  }
  .drawer--open { transform: none; }
}

/* Dropdown menu ----------------------------------------------------------- */

.dropdown { position: relative; display: inline-flex; }

.dropdown__menu {
  position: absolute;
  top: calc(100% + 6px);
  inset-inline-end: 0;
  min-width: 208px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: 5px;
  z-index: 55;
  opacity: 0;
  transform: translateY(-4px);
  pointer-events: none;
  /* Closed menus stay out of the tab order — see the note on `.modal`. A page
     with a menu per table row otherwise buries the next real control behind
     dozens of invisible stops. */
  visibility: hidden;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease),
              visibility 0s linear var(--dur-fast);
  max-height: 70vh;
  overflow-y: auto;
}
.dropdown__menu--open {
  opacity: 1;
  transform: none;
  pointer-events: auto;
  visibility: visible;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
}
.dropdown__menu--start { inset-inline: 0 auto; }
.dropdown__menu--wide { min-width: 300px; }

.dropdown__item {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  padding: 8px var(--s-3);
  border-radius: var(--r-xs);
  font-size: var(--t-md);
  color: var(--color-text-soft);
  text-align: start;
  transition: background-color var(--dur-fast) var(--ease), color var(--dur-fast) var(--ease);
}
.dropdown__item:hover { background: var(--color-hover); color: var(--color-text); }
.dropdown__item svg { width: 16px; height: 16px; color: var(--color-faint); }
.dropdown__item:hover svg { color: var(--color-muted); }
.dropdown__item--danger { color: var(--color-danger); }
.dropdown__item--danger:hover { background: var(--color-danger-soft); color: var(--color-danger-ink); }
.dropdown__item--danger svg { color: currentColor; }
.dropdown__item--active { background: var(--color-inset); color: var(--color-text); font-weight: var(--fw-semi); }

.dropdown__label { padding: var(--s-2) var(--s-3) 4px; font-size: var(--t-2xs); color: var(--color-faint); font-weight: var(--fw-semi); }
.dropdown__divider { height: 1px; background: var(--color-divider); margin: 5px 0; }

/* Toasts ------------------------------------------------------------------ */

.toasts {
  position: fixed;
  bottom: var(--s-5);
  inset-inline-start: var(--s-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  pointer-events: none;
  max-width: min(400px, calc(100vw - var(--s-8)));
}

.toast {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;
  animation: toast-in var(--dur) var(--ease);
}
.toast--leaving { animation: toast-out var(--dur) var(--ease) forwards; }

.toast__icon { display: flex; flex: none; margin-top: 2px; }
.toast__icon svg { width: 17px; height: 17px; }
.toast--success .toast__icon { color: var(--color-success); }
.toast--error   .toast__icon { color: var(--color-danger); }
.toast--warning .toast__icon { color: var(--color-warning); }
.toast--info    .toast__icon { color: var(--color-info); }

.toast__title { font-size: var(--t-md); font-weight: var(--fw-semi); }
.toast__body  { font-size: var(--t-sm); color: var(--color-muted); margin-top: 1px; }
.toast__close { color: var(--color-faint); flex: none; }

@keyframes toast-in  { from { opacity: 0; transform: translateY(12px); } }
@keyframes toast-out { to { opacity: 0; transform: translateY(8px) scale(.98); } }

@media (max-width: 640px) {
  .toasts { inset-inline: var(--s-3); bottom: calc(var(--s-3) + 68px); max-width: none; }
}

/* Tooltip ----------------------------------------------------------------- */

.tip { position: relative; }
.tip::after {
  content: attr(data-tip);
  position: absolute;
  bottom: calc(100% + 7px);
  inset-inline-start: 50%;
  transform: translateX(50%) translateY(3px);
  background: var(--color-ink);
  color: var(--color-on-ink);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  padding: 5px 9px;
  border-radius: var(--r-xs);
  white-space: nowrap;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease), transform var(--dur-fast) var(--ease);
  z-index: 100;
}
.tip:hover::after { opacity: 1; transform: translateX(50%); }
[dir='ltr'] .tip::after { transform: translateX(-50%) translateY(3px); }
[dir='ltr'] .tip:hover::after { transform: translateX(-50%); }

/* Tooltip positioned below the element (e.g. topbar / header controls) */
.tip--bottom::after,
.tip--down::after,
.topbar .tip::after,
.header .tip::after {
  bottom: auto;
  top: calc(100% + 7px);
  transform: translateX(50%) translateY(-3px);
}

.tip--bottom:hover::after,
.tip--down:hover::after,
.topbar .tip:hover::after,
.header .tip:hover::after {
  transform: translateX(50%);
}

[dir='ltr'] .tip--bottom::after,
[dir='ltr'] .tip--down::after,
[dir='ltr'] .topbar .tip::after,
[dir='ltr'] .header .tip::after {
  transform: translateX(-50%) translateY(-3px);
}

[dir='ltr'] .tip--bottom:hover::after,
[dir='ltr'] .tip--down:hover::after,
[dir='ltr'] .topbar .tip::after,
[dir='ltr'] .header .tip:hover::after {
  transform: translateX(-50%);
}

/* Tabs -------------------------------------------------------------------- */

.tabs {
  display: flex;
  align-items: center;
  gap: var(--s-1);
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}
.tabs::-webkit-scrollbar { display: none; }

.tab {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  font-size: var(--t-md);
  font-weight: var(--fw-medium);
  color: var(--color-muted);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  white-space: nowrap;
  transition: color var(--dur-fast) var(--ease), border-color var(--dur-fast) var(--ease);
}
.tab:hover { color: var(--color-text); }
.tab--active { color: var(--color-text); border-bottom-color: var(--color-ink); font-weight: var(--fw-semi); }
.tab svg { width: 16px; height: 16px; }

/* Empty, loading and error states ----------------------------------------- */

.empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--s-9) var(--s-5);
  gap: var(--s-3);
}
.empty__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 60px; height: 60px;
  border-radius: var(--r-lg);
  background: var(--color-inset);
  color: var(--color-faint);
  margin-bottom: var(--s-1);
}
.empty__icon svg { width: 26px; height: 26px; }
.empty__title { font-size: var(--t-lg); font-weight: var(--fw-bold); }
.empty__text { font-size: var(--t-md); color: var(--color-muted); max-width: 380px; }

.skeleton {
  background: linear-gradient(90deg, var(--color-inset) 25%, var(--color-hover) 37%, var(--color-inset) 63%);
  background-size: 400% 100%;
  animation: shimmer 1.3s ease-in-out infinite;
  border-radius: var(--r-xs);
}
.skeleton--text  { height: 12px; margin-bottom: 8px; }
.skeleton--title { height: 20px; width: 40%; margin-bottom: var(--s-3); }
.skeleton--card  { height: 132px; border-radius: var(--r-xl); }
.skeleton--row   { height: 52px; margin-bottom: var(--s-2); border-radius: var(--r-sm); }
.skeleton--avatar{ width: 38px; height: 38px; border-radius: var(--r-full); }

@keyframes shimmer { 0% { background-position: 100% 50%; } 100% { background-position: 0 50%; } }

.spinner {
  width: 17px; height: 17px;
  border: 2px solid currentColor;
  border-top-color: transparent;
  border-radius: var(--r-full);
  animation: spin .7s linear infinite;
  flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

/* Inline alert ------------------------------------------------------------ */

.alert {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  font-size: var(--t-md);
  background: var(--color-info-soft);
  color: var(--color-info-ink);
}
.alert svg { width: 17px; height: 17px; flex: none; margin-top: 3px; }
.alert--warning { background: var(--color-warning-soft); color: var(--color-warning-ink); }
.alert--danger  { background: var(--color-danger-soft);  color: var(--color-danger-ink); }
.alert--success { background: var(--color-success-soft); color: var(--color-success-ink); }
.alert__title { font-weight: var(--fw-semi); }


/*! components/calendar.css */
/* ==========================================================================
   Jalali calendar — month grid, week and day views, and the date picker.
   Week starts Saturday; Friday is the weekend column.
   ========================================================================== */

.cal { display: flex; flex-direction: column; }

.cal__toolbar {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  flex-wrap: wrap;
}
.cal__month { font-size: var(--t-lg); font-weight: var(--fw-bold); min-width: 148px; }
.cal__nav { display: flex; align-items: center; gap: var(--s-1); }

.cal__weekdays {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  border-bottom: 1px solid var(--color-border);
}
.cal__weekday {
  padding: var(--s-2) var(--s-3);
  text-align: center;
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  color: var(--color-muted);
}
.cal__weekday--holiday { color: var(--color-primary); }

.cal__grid {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  grid-auto-rows: minmax(112px, auto);
}

.cal__day {
  border-inline-start: 1px solid var(--color-divider);
  border-bottom: 1px solid var(--color-divider);
  padding: 6px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
  transition: background-color var(--dur-fast) var(--ease);
}
.cal__day:nth-child(7n) { border-inline-start: none; }
.cal__day:hover { background: var(--color-hover); }
.cal__day--outside { background: var(--color-card-muted); }
.cal__day--outside .cal__daynum { color: var(--color-faint); }
.cal__day--holiday .cal__daynum { color: var(--color-primary); }

.cal__daynum {
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--color-text-soft);
  width: 25px; height: 25px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-full);
  flex: none;
}
.cal__day--today .cal__daynum { background: var(--color-ink); color: var(--color-on-ink); }

.cal__event {
  display: flex;
  align-items: center;
  gap: 5px;
  padding: 3px 6px;
  border-radius: var(--r-xs);
  font-size: var(--t-2xs);
  font-weight: var(--fw-medium);
  background: var(--hue-slate-soft);
  color: var(--hue-slate-ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: filter var(--dur-fast) var(--ease);
}
.cal__event:hover { filter: brightness(.96); }
.cal__event--blue   { background: var(--hue-blue-soft);   color: var(--hue-blue-ink); }
.cal__event--violet { background: var(--hue-violet-soft); color: var(--hue-violet-ink); }
.cal__event--teal   { background: var(--hue-teal-soft);   color: var(--hue-teal-ink); }
.cal__event--amber  { background: var(--hue-amber-soft);  color: var(--hue-amber-ink); }
.cal__event--orange { background: var(--hue-orange-soft); color: var(--hue-orange-ink); }
.cal__event--green  { background: var(--hue-green-soft);  color: var(--hue-green-ink); }
.cal__event--red    { background: var(--hue-red-soft);    color: var(--hue-red-ink); }
.cal__event__dot { width: 5px; height: 5px; border-radius: var(--r-full); background: currentColor; flex: none; }
.cal__more { font-size: var(--t-2xs); color: var(--color-muted); padding-inline: 6px; }

/* Week and day views: an agenda list, which reads better than a time grid
   on the phones this will mostly be used from. */
.cal__agenda { display: flex; flex-direction: column; }
.cal__agenda-day { border-bottom: 1px solid var(--color-divider); padding: var(--s-4) 0; }
.cal__agenda-day:last-child { border-bottom: none; }
.cal__agenda-head { display: flex; align-items: baseline; gap: var(--s-2); margin-bottom: var(--s-3); }
.cal__agenda-date { font-size: var(--t-md); font-weight: var(--fw-bold); }
.cal__agenda-weekday { font-size: var(--t-sm); color: var(--color-muted); }
.cal__agenda-day--today .cal__agenda-date { color: var(--color-primary); }

.event-row {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-3);
  border-radius: var(--r-md);
  transition: background-color var(--dur-fast) var(--ease);
}
.event-row:hover { background: var(--color-hover); }
.event-row__time {
  font-size: var(--t-sm);
  font-weight: var(--fw-semi);
  color: var(--color-text-soft);
  width: 52px;
  flex: none;
  font-variant-numeric: tabular-nums;
}
.event-row__bar { width: 3px; border-radius: var(--r-full); background: var(--hue-slate); align-self: stretch; flex: none; }
.event-row__bar--blue { background: var(--hue-blue); }
.event-row__bar--violet { background: var(--hue-violet); }
.event-row__bar--teal { background: var(--hue-teal); }
.event-row__bar--amber { background: var(--hue-amber); }
.event-row__bar--orange { background: var(--hue-orange); }
.event-row__title { font-size: var(--t-md); font-weight: var(--fw-semi); }
.event-row__meta { font-size: var(--t-xs); color: var(--color-muted); display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; margin-top: 2px; }

/* Selected day + its agenda ------------------------------------------------ */

.cal__dots { display: none; }

/* Day sheet: the agenda for one day, opened from the grid. */
.cal__daysheet { max-height: min(60vh, 520px); }
.cal__daysheet .event-row { border-radius: var(--r-md); }
.cal__daysheet .event-row + .event-row { border-top: 1px solid var(--color-divider); border-radius: 0; }
.cal__daysheet .event-row:first-child { border-radius: var(--r-md) var(--r-md) 0 0; }
.cal__daysheet .event-row:last-child  { border-radius: 0 0 var(--r-md) var(--r-md); }
.cal__daysheet .event-row:only-child  { border-radius: var(--r-md); }

/* A selected day stays marked while its sheet is open. */
.cal__day--selected { background: var(--color-inset); }
.cal__day--selected .cal__daynum { background: var(--color-primary); color: #fff; }

/* Every day is now tappable, so say so. */
.cal__day { cursor: pointer; }

/* Phones ------------------------------------------------------------------
   A ~45px cell cannot hold a title, so the titles come out and a dot per
   event goes in; the day's real agenda opens underneath on tap. */
@media (max-width: 820px) {
  .cal__grid { grid-auto-rows: minmax(58px, auto); }
  .cal__day {
    padding: 5px 2px;
    align-items: center;
    gap: 4px;
  }
  .cal__daynum { width: 25px; height: 25px; font-size: var(--t-sm); }

  .cal__event, .cal__more { display: none; }

  .cal__dots {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-height: 8px;      /* reserved even when empty, so rows stay even */
    flex-wrap: nowrap;
  }
  .cal__dot {
    width: 5px;
    height: 5px;
    border-radius: var(--r-full);
    background: var(--hue-slate);
    flex: none;
  }
  .cal__dot--blue   { background: var(--hue-blue); }
  .cal__dot--violet { background: var(--hue-violet); }
  .cal__dot--teal   { background: var(--hue-teal); }
  .cal__dot--amber  { background: var(--hue-amber); }
  .cal__dot--orange { background: var(--hue-orange); }
  .cal__dot--green  { background: var(--hue-green); }
  .cal__dot--red    { background: var(--hue-red); }
  .cal__dots-more { font-size: 9px; color: var(--color-faint); line-height: 1; }

  .cal__daysheet { max-height: 58vh; }
}

/* Jalali date picker ------------------------------------------------------- */

.datepicker {
  position: absolute;
  /* Above the modal layer: a picker opened from a field inside a dialog is
     appended to <body>, so anything less leaves it rendering behind that
     dialog and the days unclickable. */
  z-index: calc(var(--z-modal) + 1);
  width: 286px;
  padding: var(--s-3);
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
}
.datepicker__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s-2); }
.datepicker__title { font-size: var(--t-md); font-weight: var(--fw-bold); }
.datepicker__grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 2px; }
.datepicker__weekday { text-align: center; font-size: var(--t-2xs); color: var(--color-muted); padding: 4px 0; font-weight: var(--fw-semi); }
.datepicker__day {
  aspect-ratio: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-xs);
  font-size: var(--t-sm);
  color: var(--color-text-soft);
  transition: all var(--dur-fast) var(--ease);
}
.datepicker__day:hover { background: var(--color-hover); }
.datepicker__day--outside { color: var(--color-faint); }
.datepicker__day--today { font-weight: var(--fw-bold); color: var(--color-primary); }
.datepicker__day--selected { background: var(--color-ink); color: var(--color-on-ink); font-weight: var(--fw-semi); }
.datepicker__foot { display: flex; gap: var(--s-2); margin-top: var(--s-2); padding-top: var(--s-2); border-top: 1px solid var(--color-divider); }

/* On a phone a 286px panel anchored to an input lands half off-screen and its
   28px day cells are below the comfortable tap target. As a sheet it gets the
   full width and 44px targets. */
@media (max-width: 640px) {
  .datepicker--sheet {
    position: fixed;
    inset-inline: 0;
    top: auto;
    bottom: 0;
    width: auto;
    z-index: calc(var(--z-modal) + 1);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-inline: none;
    border-bottom: none;
    padding: var(--s-3) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-lg);
    animation: sheet-up var(--dur) var(--ease);
  }
  .datepicker--sheet::before {
    content: '';
    display: block;
    width: 38px; height: 4px;
    border-radius: var(--r-full);
    background: var(--color-border-strong);
    margin: 0 auto var(--s-3);
  }
  .datepicker--sheet .datepicker__head { margin-bottom: var(--s-3); }
  .datepicker--sheet .datepicker__title { font-size: var(--t-lg); }
  .datepicker--sheet .datepicker__grid { gap: 4px; }
  .datepicker--sheet .datepicker__day {
    font-size: var(--t-base);
    border-radius: var(--r-sm);
    min-height: 44px;          /* comfortable thumb target */
  }
  .datepicker--sheet .datepicker__weekday { font-size: var(--t-xs); padding: var(--s-2) 0; }
  .datepicker--sheet .datepicker__foot { margin-top: var(--s-3); padding-top: var(--s-3); }
  .datepicker--sheet .datepicker__foot .btn { min-height: 42px; }
}

@keyframes sheet-up { from { transform: translateY(100%); } }

/* Time Picker Popover ---------------------------------------------------- */

.timepicker {
  position: absolute;
  z-index: calc(var(--z-modal) + 2);
  width: 310px;
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-lg);
  padding: var(--s-3);
  display: none;
  font-family: inherit;
}

.timepicker__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: var(--s-2);
  border-bottom: 1px solid var(--color-divider);
  margin-bottom: var(--s-3);
}

.timepicker__title {
  font-size: var(--t-sm);
  font-weight: var(--fw-bold);
}

.timepicker__section-title {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
  color: var(--color-muted);
  margin-bottom: 6px;
}

.timepicker__presets {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 4px;
  max-height: 110px;
  overflow-y: auto;
  padding-inline-end: 2px;
  margin-bottom: var(--s-3);
}

.timepicker__preset {
  padding: 5px 2px;
  border-radius: var(--r-xs);
  border: 1px solid var(--color-border);
  background: var(--color-inset);
  color: var(--color-text-soft);
  font-size: var(--t-xs);
  font-weight: var(--fw-medium);
  text-align: center;
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}

.timepicker__preset:hover {
  border-color: var(--color-border-strong);
  background: var(--color-hover);
  color: var(--color-text);
}

.timepicker__preset--selected {
  background: var(--color-ink);
  color: var(--color-on-ink);
  border-color: var(--color-ink);
}

.timepicker__columns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-2);
  border-top: 1px solid var(--color-divider);
  padding-top: var(--s-2);
}

.timepicker__col-title {
  font-size: var(--t-2xs);
  font-weight: var(--fw-semi);
  color: var(--color-muted);
  text-align: center;
  margin-bottom: 4px;
}

.timepicker__col-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  max-height: 100px;
  overflow-y: auto;
  padding-inline-end: 2px;
}

.timepicker__cell {
  padding: 4px 2px;
  border-radius: var(--r-xs);
  font-size: var(--t-xs);
  color: var(--color-text-soft);
  text-align: center;
  cursor: pointer;
  transition: all var(--dur-fast) var(--ease);
}

.timepicker__cell:hover {
  background: var(--color-hover);
  color: var(--color-text);
}

.timepicker__cell--selected {
  background: var(--color-ink);
  color: var(--color-on-ink);
  font-weight: var(--fw-semi);
}

@media (max-width: 640px) {
  .timepicker--sheet {
    position: fixed;
    inset-inline: 0;
    top: auto;
    bottom: 0;
    width: auto;
    z-index: calc(var(--z-modal) + 2);
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    border-inline: none;
    border-bottom: none;
    padding: var(--s-3) var(--s-4) calc(var(--s-4) + env(safe-area-inset-bottom, 0px));
    box-shadow: var(--shadow-lg);
    animation: sheet-up var(--dur) var(--ease);
  }

  .timepicker--sheet::before {
    content: '';
    display: block;
    width: 38px;
    height: 4px;
    border-radius: var(--r-full);
    background: var(--color-border-strong);
    margin: 0 auto var(--s-3);
  }

  .timepicker--sheet .timepicker__presets {
    max-height: 140px;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
  }

  .timepicker--sheet .timepicker__preset {
    padding: 8px 4px;
    font-size: var(--t-sm);
  }

  .timepicker--sheet .timepicker__col-list {
    max-height: 120px;
  }

  .timepicker--sheet .timepicker__cell {
    padding: 6px 2px;
    font-size: var(--t-sm);
  }
}


/*! components/timeline.css */
/* ==========================================================================
   Activity timeline — one vertical rule, a marker per entry, and an explicit
   old → new pair for value changes.
   ========================================================================== */

.timeline { position: relative; padding-inline-start: var(--s-6); }
.timeline::before {
  content: '';
  position: absolute;
  inset-block: 8px 8px;
  inset-inline-start: 13px;
  width: 1.5px;
  background: var(--color-divider);
}

.timeline__item { position: relative; padding-bottom: var(--s-5); }
.timeline__item:last-child { padding-bottom: 0; }

.timeline__marker {
  position: absolute;
  inset-inline-start: calc(var(--s-6) * -1);
  top: 1px;
  width: 27px; height: 27px;
  border-radius: var(--r-full);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--hue-slate-soft);
  color: var(--hue-slate-ink);
  border: 2.5px solid var(--color-card);
}
.timeline__marker svg { width: 13px; height: 13px; }
.timeline__marker--green  { background: var(--hue-green-soft);  color: var(--hue-green-ink); }
.timeline__marker--blue   { background: var(--hue-blue-soft);   color: var(--hue-blue-ink); }
.timeline__marker--violet { background: var(--hue-violet-soft); color: var(--hue-violet-ink); }
.timeline__marker--amber  { background: var(--hue-amber-soft);  color: var(--hue-amber-ink); }
.timeline__marker--red    { background: var(--hue-red-soft);    color: var(--hue-red-ink); }
.timeline__marker--teal   { background: var(--hue-teal-soft);   color: var(--hue-teal-ink); }
.timeline__marker--slate  { background: var(--hue-slate-soft);  color: var(--hue-slate-ink); }

.timeline__head { display: flex; align-items: baseline; gap: var(--s-2); flex-wrap: wrap; }
.timeline__who  { font-size: var(--t-md); font-weight: var(--fw-semi); }
.timeline__when { font-size: var(--t-xs); color: var(--color-faint); }
.timeline__what { font-size: var(--t-md); color: var(--color-text-soft); margin-top: 2px; }

.timeline__change {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  background: var(--color-inset);
  font-size: var(--t-sm);
  flex-wrap: wrap;
}
.timeline__old { color: var(--color-muted); text-decoration: line-through; text-decoration-color: var(--color-faint); }
.timeline__new { font-weight: var(--fw-semi); }
.timeline__arrow { color: var(--color-faint); display: flex; }
.timeline__arrow svg { width: 13px; height: 13px; }

/* Compact variant for the dashboard "recent activity" card. */
.timeline--compact .timeline__item { padding-bottom: var(--s-4); }
.timeline--compact .timeline__marker { width: 23px; height: 23px; }
.timeline--compact .timeline__marker svg { width: 11px; height: 11px; }


/*! components/pipeline.css */
/* ==========================================================================
   Pipeline board — horizontally scrolling columns on desktop, and on touch
   devices the same cards with an explicit stage selector instead of drag.
   ========================================================================== */

.board {
  display: flex;
  gap: var(--s-3);
  overflow-x: auto;
  padding-bottom: var(--s-4);
  scroll-snap-type: x proximity;
  min-height: 420px;
}

.board__col {
  width: 290px;
  flex: none;
  display: flex;
  flex-direction: column;
  background: var(--color-card-muted);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  scroll-snap-align: start;
  max-height: calc(100dvh - 240px);
}

.board__head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-3) var(--s-4);
  border-bottom: 1px solid var(--color-border);
  flex: none;
}
.board__dot { width: 8px; height: 8px; border-radius: var(--r-full); flex: none; }
.board__title { font-size: var(--t-md); font-weight: var(--fw-bold); }
.board__sum { font-size: var(--t-2xs); color: var(--color-muted); margin-top: 1px; }

.board__body {
  flex: 1;
  overflow-y: auto;
  padding: var(--s-3);
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  min-height: 90px;
}

.board__col--over .board__body { background: var(--color-primary-soft); border-radius: var(--r-md); }

.deal {
  background: var(--color-card);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  padding: var(--s-3);
  cursor: grab;
  transition: box-shadow var(--dur-fast) var(--ease),
              border-color var(--dur-fast) var(--ease),
              opacity var(--dur-fast) var(--ease);
  touch-action: manipulation;
}
.deal:hover { border-color: var(--color-border-strong); box-shadow: var(--shadow-sm); }
.deal:active { cursor: grabbing; }
.deal--dragging { opacity: .45; }

.deal__name { font-size: var(--t-md); font-weight: var(--fw-semi); }
.deal__company { font-size: var(--t-xs); color: var(--color-muted); margin-top: 1px; }
.deal__meta { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); margin-top: var(--s-3); }
.deal__value { font-size: var(--t-sm); font-weight: var(--fw-bold); }
.deal__foot { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-3); padding-top: var(--s-3); border-top: 1px solid var(--color-divider); }
.deal__overdue { color: var(--color-danger); }

/* Drop placeholder that follows the pointer between columns. */
.deal-ghost {
  height: 62px;
  border: 1.5px dashed var(--color-border-strong);
  border-radius: var(--r-md);
  background: var(--color-hover);
}

@media (max-width: 640px) {
  .board { gap: var(--s-2); }
  .board__col { width: 84vw; max-height: none; }
}

/* Funnel chart (stacked bars, widest first) -------------------------------- */

.funnel { display: flex; flex-direction: column; gap: var(--s-2); }
.funnel__row { display: flex; align-items: center; gap: var(--s-3); }
.funnel__label { width: 120px; flex: none; font-size: var(--t-sm); color: var(--color-text-soft); }
.funnel__track { flex: 1; height: 30px; background: var(--color-inset); border-radius: var(--r-xs); overflow: hidden; }
.funnel__bar {
  height: 100%;
  border-radius: var(--r-xs);
  display: flex;
  align-items: center;
  padding-inline: var(--s-2);
  font-size: var(--t-xs);
  font-weight: var(--fw-semi);
  color: #fff;
  min-width: 2px;
  transition: width var(--dur-slow) var(--ease);
}
.funnel__count { width: 56px; flex: none; text-align: end; font-size: var(--t-sm); font-weight: var(--fw-semi); }

@media (max-width: 640px) {
  .funnel__label { width: 84px; font-size: var(--t-xs); }
  .funnel__count { width: 40px; }
}


/*! components/charts.css */
/* ==========================================================================
   Charts — hand-rolled SVG. No chart library, so nothing to keep in sync
   with the theme: every stroke and fill reads a CSS variable.
   ========================================================================== */

.chart { width: 100%; position: relative; }
.chart svg { width: 100%; height: auto; overflow: visible; display: block; }

.chart__grid line { stroke: var(--color-divider); stroke-width: 1; }
.chart__axis text { fill: var(--color-faint); font-size: 10.5px; font-family: var(--font-sans); }

.chart__line { fill: none; stroke-width: 2.5; stroke-linecap: round; stroke-linejoin: round; }
.chart__line--primary { stroke: var(--color-ink); }
.chart__line--accent  { stroke: var(--color-primary); }
.chart__area { fill: url(#chart-fade); opacity: .13; }

.chart__dot { fill: var(--color-card); stroke-width: 2.5; r: 3.5; }
.chart__dot--primary { stroke: var(--color-ink); }

.chart__bar {
  fill: var(--color-ink);
  transition: opacity var(--dur-fast) var(--ease);
}
.chart__bar:hover { opacity: .78; }
.chart__bar--muted { fill: var(--color-border-strong); }
.chart__bar--green { fill: var(--hue-green); }
.chart__bar--red   { fill: var(--hue-red); }
.chart__bar--blue  { fill: var(--hue-blue); }

.chart__legend { display: flex; align-items: center; gap: var(--s-4); flex-wrap: wrap; margin-top: var(--s-3); }
.chart__legend-item { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-xs); color: var(--color-muted); }
.chart__legend-swatch { width: 9px; height: 9px; border-radius: 3px; flex: none; }

/* Donut used for source / loss-reason splits. */
.donut { display: flex; align-items: center; gap: var(--s-5); flex-wrap: wrap; }
.donut__svg { width: 148px; height: 148px; flex: none; }
.donut__svg circle { fill: none; stroke-width: 17; transition: stroke-dasharray var(--dur-slow) var(--ease); }
.donut__center {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.donut__total { font-size: var(--t-xl); font-weight: var(--fw-bold); line-height: 1; }
.donut__caption { font-size: var(--t-2xs); color: var(--color-muted); }
.donut__wrap { position: relative; width: 148px; height: 148px; flex: none; }
.donut__legend { flex: 1; min-width: 170px; display: flex; flex-direction: column; gap: var(--s-2); }
.donut__row { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-sm); }
.donut__row .grow { color: var(--color-text-soft); }
.donut__value { font-weight: var(--fw-semi); font-variant-numeric: tabular-nums; }

/* Sparkline in stat tiles. */
.spark { height: 34px; }
.spark path { fill: none; stroke: var(--color-ink); stroke-width: 2; stroke-linecap: round; }

/* Horizontal ranking bars (top salespeople, cities). */
.rank { display: flex; flex-direction: column; gap: var(--s-3); }
.rank__row { display: flex; align-items: center; gap: var(--s-3); }
.rank__body { flex: 1; min-width: 0; }
.rank__head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-2); margin-bottom: 5px; }
.rank__name {
  font-size: var(--t-md);
  font-weight: var(--fw-medium);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}
.rank__value {
  font-size: var(--t-sm);
  font-weight: var(--fw-bold);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  flex: none;
}


/*! components/auth.css */
/* ==========================================================================
   Sign-in — a single centred card on the neutral canvas, with a soft
   gradient panel alongside on wide screens.
   ========================================================================== */

.auth {
  min-height: 100dvh;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--color-bg);
}

.auth__panel {
  position: relative;
  overflow: hidden;
  margin: var(--s-4);
  border-radius: var(--r-2xl);
  background: var(--gradient-hero);
  padding: var(--s-9);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.auth__panel-title { font-size: var(--t-3xl); font-weight: var(--fw-bold); letter-spacing: -.03em; max-width: 420px; line-height: 1.4; }
.auth__panel-text { font-size: var(--t-base); color: var(--color-text-soft); max-width: 400px; margin-top: var(--s-4); }

.auth__form-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--s-6);
}
.auth__form { width: 100%; max-width: 372px; }
.auth__logo { display: flex; align-items: center; gap: var(--s-3); margin-bottom: var(--s-7); }
.auth__title { font-size: var(--t-2xl); font-weight: var(--fw-bold); letter-spacing: -.025em; }
.auth__subtitle { font-size: var(--t-md); color: var(--color-muted); margin-top: var(--s-2); margin-bottom: var(--s-6); }

/* Demo account switcher shown only when seeded demo data is present. */
.demo-accounts { margin-top: var(--s-6); padding-top: var(--s-5); border-top: 1px solid var(--color-divider); }
.demo-accounts__title { font-size: var(--t-xs); color: var(--color-faint); margin-bottom: var(--s-3); font-weight: var(--fw-semi); }
.demo-account {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  width: 100%;
  padding: var(--s-2) var(--s-3);
  border-radius: var(--r-sm);
  border: 1px solid var(--color-border);
  text-align: start;
  transition: all var(--dur-fast) var(--ease);
}
.demo-account + .demo-account { margin-top: 5px; }
.demo-account:hover { border-color: var(--color-border-strong); background: var(--color-hover); }
.demo-account__name { font-size: var(--t-sm); font-weight: var(--fw-semi); }
.demo-account__role { font-size: var(--t-2xs); color: var(--color-muted); }

@media (max-width: 980px) {
  .auth { grid-template-columns: 1fr; }
  .auth__panel { display: none; }
}


/*! utilities.css */
/* ==========================================================================
   Utilities — a deliberately small set. Anything used more than twice
   becomes a component instead.
   ========================================================================== */

.stack        { display: flex; flex-direction: column; }
.row          { display: flex; align-items: center; }
.row-start    { display: flex; align-items: flex-start; }
.between      { display: flex; align-items: center; justify-content: space-between; }
.center       { display: flex; align-items: center; justify-content: center; }
.wrap         { flex-wrap: wrap; }
.grow         { flex: 1; min-width: 0; }
.shrink-0     { flex: none; }

.g-1 { gap: var(--s-1); } .g-2 { gap: var(--s-2); } .g-3 { gap: var(--s-3); }
.g-4 { gap: var(--s-4); } .g-5 { gap: var(--s-5); } .g-6 { gap: var(--s-6); } .g-7 { gap: var(--s-7); } .g-8 { gap: var(--s-8); }

.mt-1 { margin-top: var(--s-1); } .mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); } .mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); } .mt-6 { margin-top: var(--s-6); } .mt-7 { margin-top: var(--s-7); } .mt-8 { margin-top: var(--s-8); }
.mb-1 { margin-bottom: var(--s-1); } .mb-2 { margin-bottom: var(--s-2); }
.mb-3 { margin-bottom: var(--s-3); } .mb-4 { margin-bottom: var(--s-4); }
.mb-5 { margin-bottom: var(--s-5); } .mb-6 { margin-bottom: var(--s-6); }
.mb-7 { margin-bottom: var(--s-7); } .mb-8 { margin-bottom: var(--s-8); }

.t-2xs { font-size: var(--t-2xs); } .t-xs { font-size: var(--t-xs); }
.t-sm  { font-size: var(--t-sm); }  .t-md { font-size: var(--t-md); }
.t-lg  { font-size: var(--t-lg); }  .t-xl { font-size: var(--t-xl); }
.t-2xl { font-size: var(--t-2xl); } .t-3xl { font-size: var(--t-3xl); }

.fw-normal { font-weight: var(--fw-normal); }
.fw-medium { font-weight: var(--fw-medium); }
.fw-semi   { font-weight: var(--fw-semi); }
.fw-bold   { font-weight: var(--fw-bold); }

.muted   { color: var(--color-muted); }
.faint   { color: var(--color-faint); }
.soft    { color: var(--color-text-soft); }
.danger  { color: var(--color-danger); }
.success { color: var(--color-success); }
.warning { color: var(--color-warning); }
.primary { color: var(--color-primary); }

.truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.clamp-2 {
  display: -webkit-box; -webkit-line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}

.hidden      { display: none !important; }
.mobile-only { display: none; }

@media (max-width: 900px) {
  .desktop-only { display: none !important; }
  .mobile-only  { display: revert; }
  .mobile-only.row { display: flex; }
}

/* Responsive column grid used by every dashboard and form. */
.grid { display: grid; gap: var(--s-5); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.grid-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.grid-auto { grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); }

.span-2 { grid-column: span 2; }
.span-3 { grid-column: span 3; }

@media (max-width: 1280px) {
  .grid-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .grid-3, .grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .span-2, .span-3 { grid-column: span 2; }
}
/* `grid-2` carries big content panels — charts, tables, timelines. Two of
   those side by side on a phone squeezes each to ~150px and shreds the text,
   so they stack early. */
@media (max-width: 760px) {
  .grid-2 { grid-template-columns: minmax(0, 1fr); }
}

/* `grid-3/4/5` carry compact tiles, which stay two-up all the way down —
   one-per-row turns a five-tile summary into four screens of scrolling. */
@media (max-width: 560px) {
  .grid-3, .grid-4, .grid-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .span-2, .span-3 { grid-column: span 2; }
  .grid { gap: var(--s-3); }
  /* Anything that genuinely needs the full width opts in. */
  .grid-1-on-phone { grid-template-columns: minmax(0, 1fr) !important; }
}


