/*
 * سیستم طراحی بالنگ؛ تنها منبع ظاهر سایت (شرح و نمونه‌ها: docs/design-system.md و صفحه‌ی /ui/).
 *
 * ترتیب فایل: ۱ توکن‌ها، ۲ پایه، ۳ چیدمان، ۴ کارت و شبکه، ۵ دکمه، ۶ فرم، ۷ زبانه و جدول و صفحه‌بندی،
 * ۸ نشان و پیام، ۹ اجزای دامنه، ۱۰ نسخه‌ی نصبی. حرکت‌ها در motion.css است.
 *
 * قاعده‌ی توکن: فاصله، اندازه‌ی متن، گردی گوشه، سایه و ارتفاع کنترل فقط از متغیرهای پایین می‌آید.
 * عدد تازه ننویسید؛ اگر توکنی کم است، همان‌جا اضافه کنید.
 *
 * قاعده‌ها:
 *   ۱. هیچ رنگ ثابتی؛ فقط متغیرهای --brand-* (پالت پویا، core/brand.py) و رنگ‌هایی که با
 *      color-mix (یا oklch(from …)) از همان‌ها ساخته می‌شوند. سفید و سیاه خالص فقط برای ترکیب.
 *   ۲. فقط ویژگی‌های «منطقی» (margin-inline-start، inset-inline-end، text-align: start …)، نه
 *      left/right؛ تا همین یک فایل در فارسی (راست‌به‌چپ) و انگلیسی (چپ‌به‌راست) درست بچیند.
 *   ۳. هیچ فایلی از CDN؛ فونت وزیرمتن داخل پروژه است (static/fonts/vazirmatn، مجوز OFL کنارش).
 *   ۴. اول گوشی: چیدمان پایه برای صفحه‌ی باریک است و در صفحه‌ی پهن باز می‌شود.
 *   ۵. تم روشن و تاریک: اجزا فقط «رنگ‌های معنایی» پایین (--fg، --page، --card، --link …) را به کار
 *      می‌برند، نه مستقیم --brand-*. همین رنگ‌ها در تم تاریک مقدار دیگری می‌گیرند. تم تاریک خودکار از
 *      تنظیم دستگاه (prefers-color-scheme) پیروی می‌کند، مگر کاربر با دکمه‌ی سربرگ روشن یا تاریک را
 *      انتخاب کرده باشد (data-theme روی html؛ static/app/ui.js).
 */

/* پالت سرویس (به‌جای پالت پویای بالنگ). فقط این شش رنگ ثابت‌اند؛ بقیه از آن‌ها ساخته می‌شوند. */
:root {
  --brand-primary: #6CC3B0;   /* سبز فیروزه‌ای روشن: دکمه‌ی اصلی؛ متن رویش زغالی */
  --brand-secondary: #93ABCB; /* آبی خاکستری: نشان‌ها */
  --brand-ink: #22313A;       /* زغالی: متن */
  --brand-surface: #E6F0EE;   /* زمینه */
  --brand-accent: #B4533F;    /* آجری: پیوند، خطا */
  --brand-highlight: #E3B65E; /* زرد طلایی: برجسته */
}

@font-face {
  font-family: "Vazirmatn";
  src: url("../fonts/vazirmatn/Vazirmatn-wght.woff2") format("woff2");
  font-weight: 100 900; /* یک فایل با همه‌ی وزن‌ها (variable font) */
  font-style: normal;
  font-display: swap; /* تا فونت برسد، متن با فونت سیستم دیده می‌شود */
}

/* رنگ‌های معنایی تم روشن، همه ساخته‌شده از پالت */
:root {
  color-scheme: light;
  --fg: var(--brand-ink);
  --page: color-mix(in srgb, var(--brand-surface) 45%, white);
  --card: color-mix(in srgb, var(--brand-surface) 12%, white);
  --raised: color-mix(in srgb, var(--brand-surface) 30%, white);
  --head: color-mix(in srgb, var(--brand-surface) 50%, white);
  --field-bg: white;
  --line: color-mix(in srgb, var(--brand-ink) 14%, transparent);
  --muted: color-mix(in srgb, var(--brand-ink) 68%, var(--page));
  --link: var(--brand-accent);
  --bad-fg: var(--brand-accent);
  --stars: var(--brand-accent);
  --on-primary: var(--brand-ink); /* متن روی نارنجی همیشه زغالی (docs/brand.md) */
  --inverse-bg: var(--brand-ink);
  --inverse-fg: var(--card);
  --primary-hover: color-mix(in srgb, var(--brand-primary) 85%, var(--brand-ink));
  --accent-soft: color-mix(in srgb, var(--brand-accent) 12%, white);
  --secondary-soft: color-mix(in srgb, var(--brand-secondary) 22%, white);
  --highlight-soft: color-mix(in srgb, var(--brand-highlight) 28%, white);
  --good-soft: color-mix(in srgb, var(--brand-secondary) 45%, white);
  --track: color-mix(in srgb, var(--brand-ink) 7%, transparent);
  --splash-bg: var(--brand-surface);
  --logo-filter: none;
  /* رنگ سری‌های نمودار (apps/reports/charts.py) */
  --viz-1: var(--brand-primary);
  --viz-2: color-mix(in srgb, var(--brand-secondary) 80%, var(--brand-ink));
  --viz-3: var(--brand-accent);
  --viz-4: var(--brand-highlight);
  --viz-5: color-mix(in srgb, var(--brand-ink) 55%, white);
  --shadow-1: 0 1px 2px color-mix(in srgb, var(--brand-ink) 8%, transparent);
  --shadow-2: 0 2px 4px color-mix(in srgb, var(--brand-ink) 8%, transparent), 0 8px 20px color-mix(in srgb, var(--brand-ink) 10%, transparent);
  --shadow-3: 0 4px 8px color-mix(in srgb, var(--brand-ink) 10%, transparent), 0 16px 40px color-mix(in srgb, var(--brand-ink) 18%, transparent);
  /* ---------- توکن‌های اندازه؛ در هر دو تم یکی‌اند ---------- */
  --s-1: 4px; --s-2: 8px; --s-3: 12px; --s-4: 16px; --s-5: 24px; --s-6: 32px; --s-7: 48px;
  --fs-xs: 0.8125rem; --fs-sm: 0.9rem; --fs-md: 1rem; --fs-lg: 1.15rem; --fs-xl: 1.4rem;
  --fs-2xl: clamp(1.5rem, 4vw, 2rem);
  --r-sm: 8px; --r-md: 10px; --r-lg: 14px; --r-pill: 999px;
  --control: 44px; /* اندازه‌ی کافی برای لمس با انگشت */
  --control-sm: 36px;
  --gutter: var(--s-4);
  --card-pad: var(--s-4) var(--s-5);
  --page-max: 1200px; /* پهنای صفحه */
  --page-form: 560px; /* صفحه‌های تک‌فرمی */
  --form-max: 800px; /* پهن‌ترین فرم؛ ورودی تمام‌صفحه نداریم */
  --form-card: 850px; /* کارت همان فرم، با فاصله‌ی داخلی */
  --measure: 72ch; /* بیشترین پهنای متن خواندنی */
  --field-line: color-mix(in srgb, var(--fg) 25%, transparent);
  --focus: color-mix(in srgb, var(--brand-primary) 70%, transparent);
  --focus-soft: color-mix(in srgb, var(--brand-primary) 30%, transparent);
}

/* تم تاریک: انتخاب کاربر، یا تنظیم دستگاه وقتی کاربر چیزی انتخاب نکرده */
:root[data-theme="dark"] {
  color-scheme: dark;
  /* زمینه‌ها: زغالی پالت، تیره‌شده به سمت سیاه؛ هر لایه کمی روشن‌تر از زیرش */
  --page: color-mix(in srgb, var(--brand-ink) 58%, black);
  --card: color-mix(in srgb, var(--brand-ink) 78%, black);
  --raised: color-mix(in srgb, var(--brand-ink) 96%, black);
  --head: color-mix(in srgb, var(--brand-ink) 92%, black);
  --field-bg: color-mix(in srgb, var(--brand-ink) 48%, black);
  /* متن: سفید با ته‌رنگ کرم جو، نه خود کرم جو؛ تا پیوند و خطا از آن جدا بمانند */
  --fg: color-mix(in srgb, var(--brand-surface) 50%, white);
  --line: color-mix(in srgb, var(--brand-surface) 12%, transparent);
  --muted: color-mix(in srgb, var(--brand-surface) 62%, var(--page));
  /* پیوند نارنجی پالت؛ خطا قرمز مرجانی از فام آجری (روشن‌تر، پررنگ‌تر و کمی سرخ‌تر در oklch) */
  --link: var(--brand-primary);
  --bad-fg: color-mix(in srgb, var(--brand-accent) 45%, white); /* مرورگرهای قدیمی؛ پایین در @supports عوض می‌شود */
  --stars: var(--brand-highlight);
  --inverse-bg: var(--brand-surface);
  --inverse-fg: var(--brand-ink);
  --primary-hover: color-mix(in srgb, var(--brand-primary) 85%, white);
  --accent-soft: color-mix(in srgb, var(--bad-fg) 11%, var(--card));
  --secondary-soft: color-mix(in srgb, var(--brand-secondary) 22%, var(--card));
  --highlight-soft: color-mix(in srgb, var(--brand-highlight) 20%, var(--card));
  --good-soft: color-mix(in srgb, var(--brand-secondary) 34%, var(--card));
  --track: color-mix(in srgb, var(--brand-surface) 10%, transparent);
  --splash-bg: var(--page);
  --viz-2: var(--brand-secondary);
  --viz-3: var(--bad-fg);
  --viz-5: color-mix(in srgb, var(--brand-surface) 55%, var(--card));
  --logo-filter: invert(1) brightness(1.5); /* نوشته‌ی زغالی لوگو روی زمینه‌ی تیره روشن می‌شود */
  --shadow-1: 0 1px 2px color-mix(in srgb, black 35%, transparent);
  --shadow-2: 0 2px 4px color-mix(in srgb, black 35%, transparent), 0 8px 20px color-mix(in srgb, black 30%, transparent);
  --shadow-3: 0 4px 8px color-mix(in srgb, black 40%, transparent), 0 16px 40px color-mix(in srgb, black 45%, transparent);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    color-scheme: dark;
    /* زمینه‌ها: زغالی پالت، تیره‌شده به سمت سیاه؛ هر لایه کمی روشن‌تر از زیرش */
    --page: color-mix(in srgb, var(--brand-ink) 58%, black);
    --card: color-mix(in srgb, var(--brand-ink) 78%, black);
    --raised: color-mix(in srgb, var(--brand-ink) 96%, black);
    --head: color-mix(in srgb, var(--brand-ink) 92%, black);
    --field-bg: color-mix(in srgb, var(--brand-ink) 48%, black);
    /* متن: سفید با ته‌رنگ کرم جو، نه خود کرم جو؛ تا پیوند و خطا از آن جدا بمانند */
    --fg: color-mix(in srgb, var(--brand-surface) 50%, white);
    --line: color-mix(in srgb, var(--brand-surface) 12%, transparent);
    --muted: color-mix(in srgb, var(--brand-surface) 62%, var(--page));
    /* پیوند نارنجی پالت؛ خطا قرمز مرجانی از فام آجری (روشن‌تر، پررنگ‌تر و کمی سرخ‌تر در oklch) */
    --link: var(--brand-primary);
    --bad-fg: color-mix(in srgb, var(--brand-accent) 45%, white); /* مرورگرهای قدیمی؛ پایین در @supports عوض می‌شود */
    --stars: var(--brand-highlight);
    --inverse-bg: var(--brand-surface);
    --inverse-fg: var(--brand-ink);
    --primary-hover: color-mix(in srgb, var(--brand-primary) 85%, white);
    --accent-soft: color-mix(in srgb, var(--bad-fg) 11%, var(--card));
    --secondary-soft: color-mix(in srgb, var(--brand-secondary) 22%, var(--card));
    --highlight-soft: color-mix(in srgb, var(--brand-highlight) 20%, var(--card));
    --good-soft: color-mix(in srgb, var(--brand-secondary) 34%, var(--card));
    --track: color-mix(in srgb, var(--brand-surface) 10%, transparent);
    --splash-bg: var(--page);
    --viz-2: var(--brand-secondary);
    --viz-3: var(--bad-fg);
    --viz-5: color-mix(in srgb, var(--brand-surface) 55%, var(--card));
    --logo-filter: invert(1) brightness(1.5); /* نوشته‌ی زغالی لوگو روی زمینه‌ی تیره روشن می‌شود */
    --shadow-1: 0 1px 2px color-mix(in srgb, black 35%, transparent);
    --shadow-2: 0 2px 4px color-mix(in srgb, black 35%, transparent), 0 8px 20px color-mix(in srgb, black 30%, transparent);
    --shadow-3: 0 4px 8px color-mix(in srgb, black 40%, transparent), 0 16px 40px color-mix(in srgb, black 45%, transparent);
  }
}

/* خطا در تم تاریک: قرمز مرجانی با همان فام آجری پالت؛ روشنی و پررنگی در oklch تعیین می‌شود تا هم
   روی زمینه‌ی تیره خوانا باشد و هم با متن کرم و پیوند نارنجی اشتباه نشود. فقط جایی که مرورگر
   oklch(from …) را می‌فهمد؛ متغیر نامعتبر رنگ را بی‌اثر می‌کرد، پس جدا در @supports آمده است. */
@supports (color: oklch(from red l c h)) {
  :root[data-theme="dark"] { --bad-fg: oklch(from var(--brand-accent) 0.71 0.16 calc(h - 15)); }
  @media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) { --bad-fg: oklch(from var(--brand-accent) 0.71 0.16 calc(h - 15)); }
  }
}

/* ==========================================================================
   ۲. پایه
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; min-height: 100vh; display: flex; flex-direction: column;
  background: var(--page); color: var(--fg);
  font: var(--fs-md)/1.75 Vazirmatn, Tahoma, system-ui, sans-serif;
}
img { max-width: 100%; height: auto; }
a { color: var(--link); }
h1, h2, h3 { line-height: 1.4; margin: 0 0 var(--s-3); }
h1 { font-size: var(--fs-2xl); }
h2 { font-size: var(--fs-lg); }
h3 { font-size: var(--fs-md); }
p { margin: 0 0 var(--s-3); }
code { font-family: ui-monospace, Consolas, monospace; font-size: 0.85em; direction: ltr; unicode-bidi: isolate; }
.muted, .note, .hint { color: var(--muted); }
.note, .hint { font-size: var(--fs-sm); margin: 0; }
.pre { white-space: pre-line; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; inset-inline-start: var(--s-2); top: -60px; padding: var(--s-1) var(--s-3); border-radius: var(--r-sm);
        background: var(--inverse-bg); color: var(--inverse-fg); z-index: 100; }
.skip:focus { top: var(--s-2); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; }
input:focus-visible, textarea:focus-visible, select:focus-visible { outline: none; } /* حلقه‌ی فوکوس این‌ها در motion.css است */

/* ==========================================================================
   ۳. چیدمان صفحه
   ========================================================================== */
.wrap { width: 100%; max-width: var(--page-max); margin-inline: auto; padding-inline: var(--gutter); }
main.wrap { flex: 1; padding-block: var(--s-5) var(--s-7); }
.narrow { max-width: var(--page-form); margin-inline: auto; }
.narrow-wide { max-width: var(--form-max); }
.page-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-3); margin-block-end: var(--s-4); }
.page-head h1 { margin: 0; }
.page-head .badge { font-size: var(--fs-sm); }
.back-link { margin-block-end: var(--s-3); font-size: var(--fs-sm); }
.footer { border-top: 1px solid var(--line); padding-block: var(--s-4); color: var(--muted); font-size: var(--fs-sm); }

/* سربرگ */
.topbar { position: sticky; top: 0; z-index: 20; background: color-mix(in srgb, var(--card) 92%, transparent);
          backdrop-filter: blur(8px); border-bottom: 3px solid var(--brand-primary); }
.topbar-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); min-height: 56px; padding-block: var(--s-1); }
.brand { display: inline-flex; align-items: center; gap: var(--s-2); text-decoration: none; }
.brand-mark { width: 23px; height: 32px; }
.brand-word { width: 152px; height: 16px; filter: var(--logo-filter); }
.topnav { flex: 1; display: flex; flex-wrap: wrap; gap: var(--s-1); min-width: 0; }
.topnav a { padding: var(--s-1) var(--s-2); border-radius: var(--r-sm); color: var(--fg); text-decoration: none; white-space: nowrap; }
.topnav a[aria-current="page"], .topnav a:hover { background: var(--highlight-soft); }
.logout, .lang-switch { margin: 0; }
.theme-toggle, .nav-toggle { min-width: var(--control-sm); padding-inline: var(--s-2); font-size: var(--fs-md); }
.btn.nav-toggle { display: none; }
.nav-count { display: inline-block; min-width: 1.4em; padding: 0 5px; margin-inline-start: var(--s-1); border-radius: var(--r-pill);
             background: var(--bad-fg); color: var(--page); font-size: var(--fs-xs); font-weight: 700; text-align: center; }
/* زیر این پهنا منو با دکمه باز می‌شود، نه با اسکرول افقی. بی‌جاوااسکریپت منو باز و چندخطی می‌ماند. */
@media (max-width: 1100px) {
  .brand { margin-inline-end: auto; }
  .topnav { order: 9; flex-basis: 100%; }
  .js .btn.nav-toggle { display: inline-flex; }
  .js .topnav { display: none; }
  .js .topnav.is-open { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); padding-block: var(--s-2); }
}
@media (max-width: 420px) { .brand-word { display: none; } }

/* ==========================================================================
   ۴. کارت و شبکه
   ========================================================================== */
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--card-pad);
        box-shadow: var(--shadow-1); margin-block-end: var(--s-4); }
.card > :last-child { margin-block-end: 0; }
/* هر شبکه‌ی کارت: ستون‌های هم‌پهنا و ردیف‌های هم‌قد؛ کارت تک هم پهن نمی‌شود (auto-fill). */
.cards { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 260px), 1fr)); grid-auto-rows: 1fr; margin-block: var(--s-5); }
.cards-tight { margin-block: var(--s-2) var(--s-5); }
.cards .card, .grid-2 .card, .stats .card, .report-grid .card, .builder > .card { margin: 0; }
.cards > .card, .grid-2 > .card { display: flex; flex-direction: column; min-width: 0; }
.grid-2 { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); margin-block-end: var(--s-4); }
@media (min-width: 720px) { .grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.stats { display: grid; gap: var(--s-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 170px), 1fr)); grid-auto-rows: 1fr; margin-block-end: var(--s-4); }
.stat { display: flex; flex-direction: column; gap: var(--s-1); margin: 0; }
.stat strong { font-size: var(--fs-xl); }
/* پایین کارت: نشان در شروع خط و دکمه‌ها در انتهای آن (فارسی چپ، انگلیسی راست). */
.card-foot { margin-block-start: auto; padding-block-start: var(--s-3); display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2); }
.card-foot > p { margin: 0; }
.card-foot > .actions, .card-foot > .btn { margin-inline-start: auto; }
.card-foot-stack { flex-direction: column; align-items: flex-start; }
.card-foot-stack .muted { display: block; }
.card-link { display: flex; flex-direction: column; gap: var(--s-1); text-decoration: none; color: inherit; margin: 0; }
.card-link:hover { border-color: var(--brand-primary); }
.card-link .muted { font-size: var(--fs-sm); }
.cards > .card > form.form { flex: 1; align-content: start; }
.hero { display: grid; gap: var(--s-5); align-items: center; padding-block: var(--s-3); }
.hero-badge { width: min(48vw, 216px); justify-self: center; }
.hero .lead { font-size: var(--fs-lg); color: var(--muted); max-width: var(--measure); }
@media (min-width: 720px) { .hero { grid-template-columns: auto 1fr; gap: var(--s-6); } }
.facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: var(--s-1) var(--s-4); margin: 0 0 var(--s-3); }
.facts dt { color: var(--muted); }
.facts dd { margin: 0; overflow-wrap: anywhere; }
.plain-list { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s-2); }
.plain-list li { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2);
                 padding-block: var(--s-1); border-bottom: 1px solid var(--line); }
.plain-list li:last-child { border-bottom: 0; }
.plain-list form { margin: 0; }
.link-list { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-3); padding: 0; margin: 0; list-style: none; }
.steps { margin: 0; padding-inline-start: 1.4em; display: grid; gap: var(--s-1); }
.payment { border-bottom: 1px solid var(--line); padding-block: var(--s-2); }
.payment:last-child { border-bottom: 0; }
.payment p { margin: 0 0 var(--s-1); }

/* ==========================================================================
   ۵. دکمه
   قاعده‌ی جا: دکمه‌ی عمل در انتهای خط است؛ فارسی سمت چپ و انگلیسی سمت راست.
   ========================================================================== */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-1);
  min-height: var(--control); padding: var(--s-2) var(--s-4); border: 1px solid transparent; border-radius: var(--r-md);
  font: inherit; font-weight: 600; text-decoration: none; cursor: pointer; text-align: center;
}
.btn-sm { min-height: var(--control-sm); padding: var(--s-1) var(--s-3); font-size: var(--fs-sm); }
.btn-primary { background: var(--brand-primary); color: var(--on-primary); }
.btn-primary:hover { background: var(--primary-hover); }
.btn-secondary { background: var(--secondary-soft); color: var(--fg); border-color: var(--brand-secondary); }
.btn-ghost { background: transparent; color: var(--fg); border-color: var(--line); }
.btn-ghost:hover { background: var(--highlight-soft); }
.btn-danger { background: var(--brand-accent); color: white; }
.btn[aria-disabled="true"], .btn:disabled { opacity: 0.55; cursor: not-allowed; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }

/* ==========================================================================
   ۶. فرم
   یک ورودی هیچ‌وقت پهن‌تر از --form-max نمی‌شود. در کارت پهن، فیلدها دوستونه‌اند؛ متن بلند، گروه
   گزینه و دکمه‌ها همه‌ی ستون‌ها را می‌گیرند.
   ========================================================================== */
.form { display: grid; gap: var(--s-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
/* کارتی که فرم دارد از شروع خط می‌آید و پهن‌تر از فرم نمی‌شود؛ پس دکمه‌ی انتهای فرم همان انتهای کارت است. */
main .card:has(> .form), main .form.card { max-width: var(--form-card); }
.narrow .form, .builder .form { grid-template-columns: minmax(0, 1fr); }
.form > .msg, .form > p, .form > fieldset, .form > .actions, .form > .btn, .form > .form-wide,
.form > .field:has(textarea), .form > .field:has(.checks), .form > .field:has(.file-pick),
.form > .field:has(.radio-list), .form > .field:has(> .check) { grid-column: 1 / -1; }
.form > .btn { justify-self: end; }
.form > .actions { justify-content: flex-end; }
.form > .note { text-align: start; }
@media (max-width: 560px) {
  .form > .btn { justify-self: stretch; }
  .form > .actions > .btn { flex: 1; }
}
.field { display: grid; gap: var(--s-1); min-width: 0; align-content: start; }
.field label, .field > .label, fieldset.field legend { font-weight: 600; }
fieldset.field { border: 0; padding: 0; margin: 0; min-width: 0; }
fieldset.field legend { padding: 0; margin-block-end: var(--s-1); }
.field .error { color: var(--bad-fg); font-size: var(--fs-sm); margin: 0; }
input, select, textarea, .dd-button {
  width: 100%; min-height: var(--control); padding: var(--s-2) var(--s-3); font: inherit; color: var(--fg);
  background: var(--field-bg); border: 1px solid var(--field-line); border-radius: var(--r-md);
}
textarea { min-height: 96px; resize: vertical; display: block; }
input[type="color"] { width: 4rem; padding: 2px; }
.field.has-error input, .field.has-error select, .field.has-error textarea, .field.has-error .dd-button { border-color: var(--bad-fg); }
select {
  appearance: none; -webkit-appearance: none; cursor: pointer; padding-inline-end: var(--s-6);
  background-image: linear-gradient(45deg, transparent 50%, var(--muted) 50%), linear-gradient(135deg, var(--muted) 50%, transparent 50%);
  background-size: 6px 6px, 6px 6px; background-repeat: no-repeat; background-position: right 20px center, right 14px center;
}
[dir="rtl"] select { background-position: left 14px center, left 20px center; }
.checks { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); }
.check { display: inline-flex; align-items: center; gap: var(--s-2); font-weight: 400; min-height: var(--control-sm); cursor: pointer; }
.check input { width: 20px; height: 20px; min-height: 0; margin: 0; accent-color: var(--brand-primary); flex: none; }
.radio-list { display: grid; gap: var(--s-1); margin-block-end: var(--s-2); }
.radio-list .check { align-items: flex-start; padding: var(--s-2); border-radius: var(--r-sm); border: 1px solid var(--line); }
.radio-list .check input { margin-block-start: var(--s-1); }
.file-pick { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); cursor: pointer; }
.file-pick input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
.file-pick input[type="file"]:focus-visible + .btn { outline: 3px solid var(--focus); outline-offset: 2px; }
.file-name { font-size: var(--fs-sm); overflow-wrap: anywhere; }
form + .note { margin-block-start: var(--s-2); }
.inline-form { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; margin: 0; }
.inline-form input { width: 7rem; min-height: var(--control-sm); }
.copy-row { display: flex; gap: var(--s-2); }
.copy-row input { flex: 1; min-width: 0; font-size: var(--fs-sm); }
.percent-row { display: grid; grid-template-columns: minmax(0, 1fr) 8rem; gap: var(--s-2); align-items: center; }
.code-big { font: 700 var(--fs-xl)/1.2 ui-monospace, Consolas, monospace; letter-spacing: 0.15em; margin: var(--s-1) 0 var(--s-3); text-align: start; }
html[dir="rtl"] .code-big { text-align: end; }
.link-code { font-size: var(--fs-2xl); font-weight: 700; letter-spacing: 4px; text-align: center; margin: var(--s-2) 0; }
details > summary { cursor: pointer; }
details.card > summary { min-height: var(--s-6); }
details.card[open] > summary { margin-block-end: var(--s-3); }

/* فیلتر و جستجو: یک ردیف، هر فیلد اندازه‌ی معقول؛ دکمه در انتهای خط و هم‌سطح ورودی‌ها */
.filters { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--s-3); }
.filters > .field { flex: 1 1 180px; max-width: 260px; }
.filters > .field-search { flex: 2 1 280px; max-width: 420px; }
.filters > .filter-check { flex: 0 1 auto; max-width: none; align-self: flex-end; min-height: var(--control); align-items: center; display: flex; }
.filters > .btn { margin-inline-start: auto; flex: none; }
.filter-box > summary { font-weight: 600; }
@media (max-width: 560px) {
  .filters > .field, .filters > .field-search { flex-basis: 100%; max-width: none; }
  .filters > .btn { flex: 1; }
}

/* فهرست کشویی (static/app/select.js) */
.dd { position: relative; min-width: 0; }
.dd-native { position: absolute; inset: 0; opacity: 0; pointer-events: none; }
.dd-button { display: flex; align-items: center; justify-content: space-between; gap: var(--s-2); text-align: start; cursor: pointer; }
.dd-button:hover { border-color: color-mix(in srgb, var(--fg) 45%, transparent); }
.dd-button:focus-visible, .dd.is-open .dd-button { outline: none; border-color: var(--brand-primary); box-shadow: 0 0 0 3px var(--focus-soft); }
.dd-button:disabled { opacity: .55; cursor: not-allowed; }
.dd-value { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dd-value.is-placeholder { color: var(--muted); }
.dd-chevron { flex: none; width: 8px; height: 8px; margin-inline: var(--s-1) 2px; margin-block-end: var(--s-1);
              border-right: 2px solid var(--muted); border-bottom: 2px solid var(--muted); transform: rotate(45deg); }
.dd.is-open .dd-chevron { transform: rotate(225deg); margin-block: var(--s-1) 0; }
.dd-panel { position: absolute; inset-inline: 0; top: calc(100% + 6px); z-index: 40; padding: var(--s-1);
            background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); box-shadow: var(--shadow-3); }
.dd.dd-up .dd-panel { top: auto; bottom: calc(100% + 6px); }
.dd-title { display: none; }
.dd-search { min-height: var(--control-sm); margin-block-end: var(--s-1); }
.dd-list { list-style: none; margin: 0; padding: 0; max-height: 280px; overflow-y: auto; overscroll-behavior: contain; }
.dd-list li { display: flex; align-items: center; gap: var(--s-2); min-height: 40px; padding: var(--s-2) var(--s-3); border-radius: var(--r-sm); cursor: pointer; }
.dd-list li::before { content: ""; flex: none; width: 10px; height: 5px; border-left: 2px solid transparent; border-bottom: 2px solid transparent; transform: rotate(-45deg); margin-block-end: 3px; }
.dd-list li[aria-selected="true"] { font-weight: 700; }
.dd-list li[aria-selected="true"]::before { border-color: var(--brand-primary); }
.dd-list li.is-active { background: color-mix(in srgb, var(--brand-primary) 16%, var(--card)); }
.dd-list li.is-placeholder { color: var(--muted); }
.dd-list li[aria-disabled="true"] { opacity: .45; cursor: not-allowed; }
.dd-empty { margin: var(--s-2) var(--s-3); color: var(--muted); font-size: var(--fs-sm); }
.dd [hidden] { display: none !important; }
.dd.is-sheet::before { content: ""; position: fixed; inset: 0; z-index: 60; background: color-mix(in srgb, black 45%, transparent); }
.dd.is-sheet .dd-panel { position: fixed; inset-inline: 0; top: auto; bottom: 0; z-index: 61; max-height: 75vh; display: flex; flex-direction: column;
                         padding: var(--s-2) var(--s-3) calc(var(--s-3) + env(safe-area-inset-bottom)); border-radius: 18px 18px 0 0; border-bottom: 0; }
.dd.is-sheet .dd-panel::before { content: ""; align-self: center; width: 40px; height: 4px; margin-block: 2px var(--s-2); border-radius: 2px; background: var(--line); }
.dd.is-sheet .dd-title { display: block; padding: 0 var(--s-1) var(--s-2); font-weight: 700; border-bottom: 1px solid var(--line); margin-block-end: var(--s-1); }
.dd.is-sheet .dd-list { max-height: none; flex: 1; }
.dd.is-sheet .dd-list li { min-height: 48px; font-size: var(--fs-md); }
.dd-sheet-open, .dd-sheet-open body { overflow: hidden; }

/* ==========================================================================
   ۷. زبانه‌ی زیرین، جدول، صفحه‌بندی
   ========================================================================== */
/* زبانه‌ها چندخطی می‌شوند و هرگز افقی اسکرول نمی‌خورند. */
.tabs { display: flex; flex-wrap: wrap; gap: var(--s-1); border-bottom: 1px solid var(--line); margin-block-end: var(--s-4); }
.tabs a { display: inline-flex; align-items: center; gap: var(--s-1); padding: var(--s-2) var(--s-3); margin-block-end: -1px; color: var(--muted);
          text-decoration: none; font-size: var(--fs-sm); font-weight: 600; border-bottom: 2px solid transparent; border-radius: var(--r-sm) var(--r-sm) 0 0; }
.tabs a:hover { color: var(--fg); background: var(--track); }
.tabs a[aria-current="page"] { color: var(--fg); border-bottom-color: var(--brand-primary); }
.tabs .count { display: inline-block; min-width: 1.6em; padding-inline: var(--s-1); border-radius: var(--r-pill); text-align: center; background: var(--track); font-size: var(--fs-xs); }

/* جدول متن را می‌شکند تا در کادرش جا شود. وقتی کادر باریک است، هر ردیف یک برگه‌ی «برچسب: مقدار» می‌شود
   (برچسب را listing.js از سرستون می‌گذارد). اندازه از خود کادر گرفته می‌شود، نه از صفحه؛ پس جدول داخل
   ستون باریک گزارش هم درست است. بی‌جاوااسکریپت جدول اسکرول می‌خورد، تا چیزی از دست نرود. */
.table-wrap { container-type: inline-size; margin-block-end: var(--s-3); }
.table-wrap:has(.table:not(.has-labels)) { overflow-x: auto; }
.table { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
.table th, .table td { padding: var(--s-2) var(--s-3); text-align: start; vertical-align: middle; border-bottom: 1px solid var(--line); overflow-wrap: anywhere; }
.table th { font-weight: 700; background: var(--head); white-space: nowrap; }
.table tbody tr:last-child td { border-bottom: 0; }
.table tfoot th { background: transparent; }
.sort { color: inherit; text-decoration: none; }
.sort:hover { color: var(--link); }
.sort.is-active::after { content: " ▼"; font-size: 0.7em; }
.sort.is-active.is-asc::after { content: " ▲"; }
@container (max-width: 700px) {
  .table.has-labels thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
  .table.has-labels, .table.has-labels tbody, .table.has-labels tfoot { display: block; }
  .table.has-labels tr { display: block; padding-block: var(--s-2); border-bottom: 1px solid var(--line); }
  .table.has-labels tbody tr:last-child { border-bottom: 0; }
  .table.has-labels td, .table.has-labels tfoot th { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: center; gap: var(--s-1) var(--s-3);
                                                     padding: var(--s-1) 0; border: 0; text-align: end; }
  .table.has-labels td::before, .table.has-labels tfoot th::before { content: attr(data-label); color: var(--muted); font-weight: 600; text-align: start; }
  .table.has-labels td:empty { display: none; }
}
/* صفحه‌بندی: با اسکرول خودکار (listing.js)؛ پیوند فقط پشتیبان بی‌جاوااسکریپت و وقت خطاست. */
.pager { display: flex; align-items: center; justify-content: center; gap: var(--s-3); min-height: var(--control); margin-block: var(--s-3); }
.js .pager a { display: none; } /* پشتیبان؛ فقط هنگام خطا دیده می‌شود */
.js .pager.has-error a { display: inline-flex; }
.pager.is-loading::before { content: ""; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--muted); border-inline-end-color: transparent; animation: spin 700ms linear infinite; }
.ticket-list { display: grid; gap: var(--s-2); }
.ticket-row { display: grid; gap: var(--s-1); }
.ticket-row-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-2); }

/* ==========================================================================
   ۸. نشان، پیام، اعلان، راهنما
   ========================================================================== */
.badge { display: inline-block; padding: 1px var(--s-2); border-radius: var(--r-pill); font-size: var(--fs-xs); font-weight: 600; background: var(--secondary-soft); color: var(--fg); }
.badge-wait { background: var(--highlight-soft); }
.badge-bad { background: var(--accent-soft); color: var(--bad-fg); }
.badge-good { background: var(--good-soft); }
.msg { padding: var(--s-2) var(--s-3); border-radius: var(--r-md); border-inline-start: 4px solid var(--brand-secondary); background: var(--secondary-soft); margin-block-end: var(--s-3); }
.msg-error { border-color: var(--bad-fg); background: var(--accent-soft); }
.msg-success { border-color: var(--brand-secondary); }
.toast { position: fixed; inset-inline: var(--gutter); bottom: calc(var(--s-4) + env(safe-area-inset-bottom)); z-index: 60; max-width: 420px; margin-inline: auto;
         padding: var(--s-2) var(--s-4); border-radius: var(--r-md); background: var(--inverse-bg); color: var(--inverse-fg); text-align: center; box-shadow: var(--shadow-3); }
.toast[hidden] { display: none; }
.help { display: inline-flex; align-items: center; justify-content: center; width: 20px; height: 20px; margin-inline: var(--s-1); padding: 0;
        border: 1px solid currentColor; border-radius: 50%; background: transparent; color: inherit; opacity: 0.6;
        font: 700 12px/1 Vazirmatn, Tahoma, sans-serif; vertical-align: middle; cursor: help; position: relative; }
.help::before { content: ""; position: absolute; inset: -10px; }
.help:hover, .help[aria-expanded="true"] { opacity: 1; }
#help-pop { position: fixed; z-index: 1000; max-width: min(320px, calc(100vw - 24px)); padding: var(--s-2) var(--s-3); border-radius: var(--r-sm);
            background: var(--inverse-bg); color: var(--inverse-fg); font: var(--fs-sm)/1.8 Vazirmatn, Tahoma, sans-serif; text-align: start; white-space: pre-line; box-shadow: var(--shadow-3); }
#help-pop[hidden] { display: none; }
.avatar { display: inline-block; vertical-align: middle; border-radius: 50%; object-fit: cover; flex: none; border: 1px solid var(--line); background: var(--raised); margin-inline-end: var(--s-1); }
.avatar-sm { width: 24px; height: 24px; }
.avatar-md { width: 36px; height: 36px; }
.avatar-lg { width: 112px; height: 112px; margin: 0; }
.avatar-edit { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--s-4); }
.avatar-edit > div { flex: 1 1 200px; min-width: 0; display: grid; gap: var(--s-2); }
.avatar-form { display: grid; gap: var(--s-2); margin: 0; }
.avatar-form .actions, .avatar-edit form.confirm { display: flex; justify-content: flex-end; }

/* ==========================================================================
   ۹. اجزای دامنه
   ========================================================================== */
/* روزهای هفته */
.week { list-style: none; padding: 0; margin: var(--s-2) 0 0; display: grid; grid-template-columns: repeat(7, 1fr); gap: var(--s-1); }
.week li { text-align: center; padding: var(--s-1) 2px; border-radius: var(--r-sm); background: var(--card); border: 1px solid var(--line); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.week li.is-today { background: var(--brand-primary); border-color: var(--brand-primary); color: var(--on-primary); font-weight: 700; }
.week abbr { text-decoration: none; }
.week .day-short { display: none; }
@media (max-width: 640px) { .week .day-long { display: none; } .week .day-short { display: inline; } }
/* پلن هفتگی */
.week-plan { display: grid; gap: var(--s-3); grid-template-columns: minmax(0, 1fr); }
@media (min-width: 900px) { .week-plan { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.day { border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-3); background: var(--card); }
.day h3 { margin: 0 0 var(--s-2); }
.day-empty { opacity: 0.75; }
.activity { border-inline-start: 4px solid var(--brand-secondary); padding: var(--s-2) var(--s-3); margin-block-end: var(--s-2); border-radius: var(--r-sm); background: var(--raised); display: grid; gap: var(--s-1); }
.activity.is-done { border-inline-start-color: var(--brand-primary); background: var(--secondary-soft); }
.activity-head { display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--s-1); }
.activity form { margin: 0; }
.stars { color: var(--stars); letter-spacing: 1px; }
.instructions summary { color: var(--muted); font-size: var(--fs-sm); }
.materials { margin: 0; padding-inline-start: 1.2em; font-size: var(--fs-sm); }
.builder { display: grid; gap: var(--s-4); }
@media (min-width: 900px) { .builder { grid-template-columns: minmax(300px, 1fr) minmax(0, 2fr); align-items: start; } }
.material-media { width: 100%; max-height: 70vh; border-radius: var(--r-md); background: var(--card); }
/* کامنت */
.comments { margin-block-start: var(--s-1); }
.comments > summary { color: var(--link); font-size: var(--fs-sm); }
.comment-list { list-style: none; padding: 0; margin: var(--s-2) 0; display: grid; gap: var(--s-1); }
.comment { background: var(--raised); border-radius: var(--r-sm); padding: var(--s-1) var(--s-3); }
.comment.by-mentor { border-inline-start: 3px solid var(--brand-secondary); }
.comment.is-new { box-shadow: inset 0 0 0 1px var(--brand-highlight); }
.comment p { margin: var(--s-1) 0 0; }
.comment-meta { font-size: var(--fs-sm); }
.comment-actions { display: flex; gap: var(--s-1); margin-block-start: var(--s-1); }
.comment-form { display: flex; gap: var(--s-2); align-items: flex-end; max-width: var(--form-max); }
.comment-form textarea { flex: 1; min-height: 2.6em; }
/* گفت‌وگوی تیکت: پیام خود بیننده در شروع خط (فارسی راست، انگلیسی چپ) و طرف مقابل در انتهای آن */
.timeline { display: grid; gap: var(--s-2); margin-block: var(--s-3); }
.bubble { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-lg); padding: var(--s-2) var(--s-3); max-width: min(92%, var(--form-max)); }
.bubble.is-mine { justify-self: start; border-color: var(--brand-primary); }
.bubble.is-other { justify-self: end; background: var(--secondary-soft); }
.bubble p { margin: var(--s-1) 0 0; }
.event { text-align: center; font-size: var(--fs-sm); color: var(--muted); margin: 0; }
.event strong { color: var(--fg); }
/* جلسه‌ها و نوت */
.session-row { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-2); padding-block: var(--s-3); border-top: 1px solid var(--line); }
.session-row p { margin: var(--s-1) 0 0; }
.session-row > div:first-child { flex: 1 1 220px; min-width: 0; }
.session-row form { margin: 0; }
.session-notes { flex: 1 1 100%; min-width: 0; }
.session-notes > summary { padding-block: var(--s-1); }
.note-entry { border-inline-start: 3px solid var(--line); padding-inline-start: var(--s-3); margin-block: var(--s-2); overflow-wrap: anywhere; }
.note-entry > time { display: block; font-size: var(--fs-xs); }
.note-body > :first-child { margin-block-start: var(--s-1); }
.note-body > :last-child { margin-block-end: 0; }
.note-body h1, .note-body h2, .note-body h3 { font-size: var(--fs-md); margin-block: var(--s-2) var(--s-1); }
.note-body pre { white-space: pre-wrap; }
.note-form { display: grid; gap: var(--s-2); margin-block-start: var(--s-2); max-width: var(--form-max); }
.note-form textarea { min-height: 96px; }
.note-form > div:last-child { display: flex; justify-content: flex-end; }
.note-tools { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-1); }
.note-tools .btn { min-width: 40px; font-weight: 700; }
/* کارها */
.todo-list { list-style: none; padding: 0; margin: 0 0 var(--s-2); display: grid; gap: var(--s-1); }
.todo { display: flex; gap: var(--s-3); align-items: flex-start; padding: var(--s-2) var(--s-1); border-bottom: 1px solid var(--line); }
.todo:last-child { border-bottom: 0; }
.todo-tick { margin: 0; }
.tick { width: 30px; height: 30px; border-radius: var(--r-sm); border: 2px solid var(--brand-secondary); background: var(--field-bg);
        font: 700 18px/1 Vazirmatn, Tahoma, sans-serif; color: var(--on-primary); cursor: pointer; flex: none; }
.tick[aria-checked="true"], .tick.btn-primary { background: var(--brand-primary); border-color: var(--brand-primary); }
.todo-body { flex: 1; min-width: 0; }
.todo-body p { margin: 2px 0 0; }
.todo-meta { font-size: var(--fs-sm); }
.todo.is-done .todo-body strong { text-decoration: line-through; color: var(--muted); }
/* راهنماها */
.guide-body { overflow-wrap: anywhere; }
.guide-body > * { max-width: var(--measure); }
.guide-body h2 { font-size: var(--fs-xl); margin-block: var(--s-5) var(--s-2); padding-block-end: var(--s-1); border-bottom: 1px solid var(--line); }
.guide-body h3 { font-size: var(--fs-lg); margin-block: var(--s-4) var(--s-1); }
.guide-body table { width: 100%; max-width: none; border-collapse: collapse; margin-block: var(--s-2); font-size: var(--fs-sm); }
.guide-body th, .guide-body td { border: 1px solid var(--line); padding: var(--s-1) var(--s-2); text-align: start; vertical-align: top; }
.guide-body pre { white-space: pre-wrap; padding: var(--s-2); border: 1px solid var(--line); border-radius: var(--r-sm); }
.guide-body pre, .guide-body code { direction: ltr; unicode-bidi: isolate; text-align: left; }
/* گزارش و نمودار */
.report-grid { display: grid; gap: var(--s-4); grid-template-columns: minmax(0, 1fr); grid-auto-flow: dense; }
@media (min-width: 900px) { .report-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.report-grid .card { min-width: 0; }
.report-section.is-wide { grid-column: 1 / -1; }
.report-table { margin-block-start: var(--s-2); }
.report-table > summary { color: var(--link); font-size: var(--fs-sm); }
.viz { margin: 0; }
.viz figcaption { font-weight: 600; margin-block-end: var(--s-2); }
.viz-note { color: var(--muted); font-size: var(--fs-xs); margin: var(--s-2) 0 0; }
.viz-legend { display: flex; flex-wrap: wrap; gap: var(--s-1) var(--s-3); font-size: var(--fs-xs); color: var(--muted); margin-block-end: var(--s-2); }
.viz-key i, .viz-donut-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 3px; margin-inline-end: var(--s-1); vertical-align: middle; }
.viz-bars { display: flex; flex-direction: column; gap: var(--s-1); }
.viz-row { display: grid; grid-template-columns: minmax(70px, 34%) 1fr auto; align-items: center; gap: var(--s-2); padding: 2px var(--s-1); border-radius: var(--r-sm); font-size: var(--fs-sm); }
.viz-row:hover, .viz-row:focus-visible, .viz-pair:hover, .viz-pair:focus-visible { background: var(--track); outline: none; }
.viz-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viz-track { display: block; height: 14px; background: var(--track); border-radius: var(--s-1); }
.viz-bar { display: block; height: 14px; background: var(--viz-1); border-radius: var(--s-1); }
.viz-value { color: var(--muted); font-size: var(--fs-xs); white-space: nowrap; min-width: 3em; }
.viz-row-pair { align-items: start; }
.viz-pairs { display: flex; flex-direction: column; gap: 2px; grid-column: span 2; }
.viz-pair { display: grid; grid-template-columns: 1fr auto; gap: var(--s-2); align-items: center; border-radius: var(--r-sm); }
.viz-columns { display: flex; align-items: stretch; gap: 2px; height: 170px; padding-top: 18px; border-bottom: 1px solid var(--line); margin-bottom: 22px; }
.viz-colgroup { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.viz-cols { flex: 1; display: flex; align-items: flex-end; gap: 2px; }
.viz-stack { flex-direction: column; justify-content: flex-end; align-items: stretch; gap: 0; }
.viz-col { flex: 1; max-width: 26px; margin: 0 auto; border-radius: var(--s-1) var(--s-1) 0 0; }
.viz-stack .viz-col { flex: none; width: 70%; max-width: 26px; border-radius: 0; }
.viz-stack .viz-col:nth-child(2) { border-radius: var(--s-1) var(--s-1) 0 0; }
.viz-coltop { font-size: 0.7rem; color: var(--muted); text-align: center; white-space: nowrap; }
.viz-col:hover, .viz-col:focus-visible { filter: brightness(1.15); outline: none; }
.viz-axis { font-size: 0.68rem; color: var(--muted); text-align: center; height: 0; overflow: visible; white-space: nowrap; padding-top: var(--s-1); unicode-bidi: plaintext; }
.viz-line { width: 100%; height: auto; max-height: 320px; display: block; }
.viz-line .viz-path { fill: none; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.viz-line .viz-dot { stroke: var(--card); stroke-width: 2; }
.viz-line .viz-grid { stroke: var(--line); stroke-width: 1; }
.viz-line .viz-grid-soft { stroke-dasharray: 4 4; }
.viz-line .viz-tick { font-size: 12px; fill: var(--muted); }
.viz-funnel { display: grid; gap: var(--s-1); }
.viz-funnel-row { display: grid; grid-template-columns: minmax(90px, 30%) 1fr auto; gap: var(--s-2); align-items: center; font-size: var(--fs-sm); }
.viz-funnel-track { display: flex; justify-content: center; }
.viz-funnel-bar { display: block; min-height: 24px; line-height: 24px; text-align: center; border-radius: var(--r-sm); background: var(--viz-1); color: var(--on-primary); font-weight: 700; font-size: var(--fs-xs); white-space: nowrap; }
.viz-donut-wrap { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-4); }
.viz-donut { width: 150px; height: 150px; flex: none; }
.viz-donut .viz-arc:hover, .viz-donut .viz-arc:focus-visible { stroke-width: 32; outline: none; }
.viz-donut-total { font-size: 22px; font-weight: 700; fill: var(--fg); }
.viz-donut-legend { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s-1); font-size: var(--fs-sm); }
.viz-heatmap { display: grid; grid-template-columns: auto repeat(var(--cols), minmax(0, 1fr)); gap: 3px; font-size: var(--fs-xs); }
.viz-hm-head { text-align: center; color: var(--muted); direction: ltr; }
.viz-hm-label { padding-inline-end: var(--s-1); white-space: nowrap; }
.viz-hm-cell { min-height: 28px; display: flex; align-items: center; justify-content: center; border-radius: var(--s-1); background: color-mix(in srgb, var(--viz-1) calc(var(--level) * 100%), var(--track)); }
.bars { list-style: none; padding: 0; margin: 0 0 var(--s-3); display: grid; gap: var(--s-1); }
.bars li { display: grid; grid-template-columns: minmax(80px, 30%) 1fr auto; gap: var(--s-2); align-items: center; font-size: var(--fs-sm); }
.bar-track { display: block; height: 12px; border-radius: var(--s-1); background: var(--track); }
.bar { display: block; height: 12px; border-radius: var(--s-1); background: var(--brand-primary); min-width: 2px; }
.bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bar-value { white-space: nowrap; color: var(--muted); }
/* متن‌های سامانه و نمونه‌ی پالت */
.swatches { list-style: none; padding: 0; margin: 0; display: grid; gap: var(--s-2); grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.swatches li { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.swatch { width: var(--s-6); height: var(--s-6); border-radius: var(--r-sm); border: 1px solid var(--line); flex: none; }

/* ==========================================================================
   ۱۰. نسخه‌ی نصبی
   ========================================================================== */
.offline-bar { position: sticky; top: 0; z-index: 30; padding: var(--s-2) var(--gutter); text-align: center; background: var(--brand-highlight); color: var(--brand-ink); font-weight: 600; font-size: var(--fs-sm); }
.install-bar { position: fixed; inset-inline: var(--s-3); bottom: calc(var(--s-3) + env(safe-area-inset-bottom)); z-index: 50; display: flex; align-items: center; gap: var(--s-2);
               padding: var(--s-2) var(--s-3); border-radius: var(--r-lg); background: var(--card); border: 1px solid var(--line); box-shadow: var(--shadow-3); max-width: 520px; margin-inline: auto; }
.install-bar img { border-radius: var(--r-md); flex: none; }
.install-bar span { flex: 1; font-size: var(--fs-sm); }
.install-close { border: 0; background: none; font-size: var(--fs-xl); line-height: 1; padding: var(--s-1) var(--s-2); cursor: pointer; color: var(--muted); }
.splash { position: fixed; inset: 0; z-index: 2000; display: grid; place-items: center; background: var(--splash-bg); transition: opacity 0.4s; }
.splash img { width: min(46vw, 200px); height: auto; }
.splash-out { opacity: 0; }
.offline-page { text-align: center; padding-block: var(--s-6); max-width: 520px; }
.offline-page .card { text-align: start; }
