/* ================================================================
   شَهمات — سیستمِ طراحی  (نسخه‌ی «باشگاهِ شطرنجِ پرمیوم / عاجی-سبز»)
   ----------------------------------------------------------------
   پس‌زمینه‌ی گرمِ عاجی/کِرِم، لهجه‌ی سبزِ کدر/جنگلی به‌جای کهربایی،
   تخته‌ی سبز/کِرِم، شعاعِ گردیِ متعادل، و سایه‌های بسیار سبک.

   نام‌های متغیر عمداً دست‌نخورده مانده‌اند (--ink، --panel، --firuzeh،
   --r-sm و…) — چیزی که عوض شده فقط مقدارهاست، نه معماری. این یعنی هر
   قاعده‌ی دیگری در این فایل (و هر var() در app.js/board.js) بدونِ نیاز
   به تغییر خودش را با پوسته‌ی جدید هماهنگ می‌کند. حالتِ روشن اکنون
   طرحِ اصلی/پیش‌فرض است (تصویرِ مرجع روشن است)؛ حالتِ تیره همچنان از
   طریقِ سوییچِ تنظیمات در دسترس است، با همان زبانِ بصری.

   به‌روزرسانیِ بعدی: پالتِ حالتِ تیره (بلوکِ پایه‌ی :root، خط ۲۸ به بعد)
   با یک طرحِ «پرمیوم/مینیمال» جدید جایگزین شد — پس‌زمینه‌ی تقریباً مشکی
   (#0D0F12/#191D22)، لهجه‌ی کهربایی/طلاییِ کدر (#D6A85F) به‌جای طلاییِ
   روشنِ قبلی. حالتِ روشن و تمِ تخته دست‌نخورده ماندند. یک توکنِ تازه هم
   اضافه شد: --bg-secondary، مخصوصِ پس‌زمینه‌ی نوار/سایدبارِ ناوبری (یک
   پله تیره‌تر از --panel)؛ در حالتِ روشن برابرِ --panel تعریف شده تا
   ظاهرِ روشن هیچ تغییری نکند.

     ۱. توکن‌ها (روشن/تیره + تمِ تخته)   ۶. صفحه‌ی بازی
     ۲. پایه و ریست                      ۷. پازل/درس/آموزش/مختصات
     ۳. پوسته: سربرگ، مقصدها، ناوبری     ۸. تحلیل
     ۴. المان‌های پایه                   ۹. پروفایل
     ۵. تخته                            ۱۰. فهرست‌ها، شیت‌ها، گفت‌وگو
                                        ۱۱. سه اندازه‌ی صفحه

   سه اندازه، نه بیشتر:  گوشی <768 · تبلت 768–1099 · دسکتاپ ≥1100
   هیچ منبعِ خارجی‌ای لود نمی‌شود: نه فونت، نه آیکون، نه تصویر.
   ================================================================ */

/* ================================================================
   ۱. توکن‌ها
   ================================================================ */
:root {
  /* --- سطوح و متن (تیره — پالتِ پرمیوم/مینیمالِ جدید + لهجه‌ی کهربایی) --- */
  --ink: #0D0F12;         /* پس‌زمینه‌ی صفحه — تقریباً مشکی (primary) */
  --panel: #191D22;       /* کارت (surface) */
  --raised: #20252B;      /* ورودی، دکمه‌ی خنثی، سطحِ داخلِ کارت (elevated/hover) */
  --line: #292F36;
  --text: #E8EAED;
  --muted: #9AA2AD;
  --faint: #68717C;

  /* --- ناحیه‌ی ثانویه: نوارِ ناوبری/سایدبار — یک پله تیره‌تر از --panel --- */
  --bg-secondary: #13161A;

  /* --- رنگِ برند: کهربایی/طلاییِ کدر — لهجه، نه رنگِ غالب --- */
  --firuzeh: #D6A85F;
  --firuzeh-dim: #E2B970;   /* حالتِ hover — کهربایی روشن‌تر */
  --on-accent: #0D0F12;     /* متنِ روی رنگِ برند — تیره، چون کهربایی اینجا روشن است */
  --accent-soft: rgba(214, 168, 95, 0.10);
  --saffron: #D98F4E;       /* کهربایی/نارنجیِ ثانویه — برای تاکتیک/هشدار، عمداً از طلاییِ اصلی جداست (دست‌نخورده) */
  --danger: #D66B6B;        /* قرمزِ کدر */
  --good: #65B889;          /* برد — سبزِ کدر */
  --live: #6E9FD1;          /* وضعیتِ «زنده/آنلاین/اطلاع‌رسانی» — جدا از --good */
  --live-soft: rgba(110, 159, 209, 0.14);

  /* نمودارِ روندِ ریتینگ (app.js این دو را درون‌خط صدا می‌زند) */
  --violet: var(--firuzeh);
  --champagne: var(--saffron);

  /* --- کیفیتِ حرکت: یک‌جا تعریف می‌شود تا نمودار، فهرست و نشان یکی بمانند --- */
  --c-blunder: #D66B6B;
  --c-mistake: #D9895C;
  --c-inaccuracy: #D9C15A;
  --c-good: #7FB06F;
  --c-best: #D6A85F;
  --c-brilliant: #4FA0C9;  /* تنها لهجه‌ی سرد — عمداً، تا «درخشان» همیشه چشم‌گیر بماند (دست‌نخورده) */
  --c-book: #68717C;

  /* --- دسته‌های صفحه‌ی یادگیری: هر دسته یک رنگِ تعریف‌شده،
     تا آیکون/کارت/نوارِ پیشرفتش همیشه هماهنگ بمانند --- */
  --cat-checkmates: var(--danger);
  --cat-checkmates-soft: rgba(214, 107, 107, 0.16);
  --cat-tactics: var(--saffron);
  --cat-tactics-soft: rgba(217, 143, 78, 0.16);
  --cat-endgames: var(--good);
  --cat-endgames-soft: rgba(101, 184, 137, 0.16);
  --cat-openings: var(--firuzeh);
  --cat-openings-soft: var(--accent-soft);

  /* --- شکل و فاصله — شعاعِ متعادل، نه کپسولیِ اغراق‌شده --- */
  --r-sm: 8px;
  --r: 14px;
  --r-md: 18px;
  --r-lg: 24px;
  --r-xl: 30px;
  --r-pill: 999px;
  --s1: 4px; --s2: 8px; --s3: 12px; --s4: 16px; --s5: 24px; --s6: 32px;
  --gutter: 16px;
  --content-w: 640px;

  /* --- سایه‌ها: مقدارِ sm/md عمداً دست‌نخورده مانده — همین دو روی تخته هم
     صدا زده می‌شوند (.board { box-shadow: var(--shadow-md) }) و کاربر صریح
     خواسته سایه/حاشیه‌ی تخته حتی یک پیکسل عوض نشود. --- */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.28), inset 0 1px 0 rgba(238, 241, 239, 0.03);
  --shadow-md: 0 8px 22px -6px rgba(0, 0, 0, 0.45), 0 2px 5px -1px rgba(0, 0, 0, 0.3);
  --shadow-glow-accent: 0 0 16px -3px rgba(214, 168, 95, 0.22);

  --fa: "Vazirmatn", "Shabnam", "IRANSansX", "IRANSans", system-ui, -apple-system, "Segoe UI", Roboto, Tahoma, sans-serif;
  /* فونتِ نمایشی — فقط برای واژه‌نگاشتِ لاتینِ برند (نسخه‌ی انگلیسی)، نه
     برای متنِ فارسی: حروفِ فارسی در این فونت‌ها موجود نیستند و اگر روی
     متنِ فارسی اعمال شود، مرورگر به یک سریفِ پیش‌فرضِ ناهماهنگ برمی‌گردد.
     استیچ برای فارسی «Dana»/«Newsreader» پیشنهاد داده، ولی چون این فونت‌ها
     این‌جا self-host نشده‌اند (و پروژه هیچ منبعِ خارجی لود نمی‌کند)، حسِ
     «سرلوحِ ادیتوریال» با وزنِ سنگین‌ترِ همان Vazirmatn شبیه‌سازی می‌شود —
     نه یک فونتِ متفاوت. نگاه کن به headline-fa زیر. */
  --font-display: "Newsreader", "Bodoni Moda", Georgia, serif;
  --font-headline-fa: "Vazirmatn", "Shabnam", system-ui, sans-serif; /* همان --fa، برای تأکید صریح */
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;

  /* مقدارِ پیش‌فرض/آبشاری: تا وقتی app.js اجرا نشده همین 100dvh مرورگر
     استفاده می‌شود. به‌محضِ اجرا، app.js این متغیر را با اندازه‌ی واقعیِ
     visualViewport (به پیکسل) بازنویسی می‌کند — چون خودِ 100dvh مرورگر
     دقیقاً همان لحظه‌ای که صفحه غیرقابل‌اسکرول می‌شود (صفحاتِ immersive)
     می‌تواند در حالتِ گذرای نوار آدرس قفل بماند. */
  --app-100dvh: 100dvh;

  /* --- تخته: رنگِ ثابت، مستقل از روشن/تیره‌بودنِ ظاهرِ برنامه ---
     قبلاً با تغییرِ appearance بین این پالت و پالتِ روشن سوییچ می‌کرد؛
     کاربر صریح خواست تخته ربطی به تمِ سایت نداشته باشد — پس همین یک
     پالت (هم‌رنگ با پیش‌نمایشِ «firuzeh» در سوییچرِ تمِ تخته) همیشه است،
     چه appearance روشن باشد چه تیره چه خودکار. تم‌های اختیاریِ تخته
     (.theme-wood/-blue/-night پایین‌تر) همچنان جدا و روی خودشان کار
     می‌کنند. */
  --sq-light: #eee9da;
  --sq-dark: #7c9473;
  --hl-last: rgba(75, 124, 89, 0.30);
  --hl-sel: rgba(75, 124, 89, 0.38);
  --hint-ink: rgba(36, 39, 31, 0.28);
  --hint-ink-d: rgba(36, 39, 31, 0.44);
  --coord-l: var(--sq-dark);
  --coord-d: var(--sq-light);

  /* سبک کلاسیک: پرکنندگی تخت، خط دور تیره، جزئیات داخلی به رنگ مخالف —
     این‌ها رنگِ خودِ مهره‌اند، بخشی از هویتِ برند نیستند، دست‌نخورده می‌مانند */
  --pw-fill: #ffffff;
  --pw-stroke: #16171a;
  --pw-detail: #16171a;
  --pb-fill: #1d1e20;
  --pb-stroke: #000000;
  --pb-detail: #ffffff;

  color-scheme: dark;
}

/* ---------------------------------------------------------------- روشن
   فقط توکن‌ها عوض می‌شوند، نه هیچ قاعده‌ی چیدمانی. هر رنگی که در ادامه‌ی
   فایل نوشته می‌شود باید از همین توکن‌ها بیاید — وگرنه حالتِ روشن جا
   می‌ماند. */
:root[data-appearance="light"] {
  --ink: #EEF1EF;
  --panel: #FFFFFF;
  --raised: #E7E9E9;
  --line: #E0E1E1;
  --text: #1A2126;
  --muted: #5D6F6E;
  --faint: #96A6A5;
  --bg-secondary: var(--panel);   /* حالتِ روشن تغییری نکرده — سایدبار همان رنگِ کارت می‌ماند */

  --firuzeh: #8D5F0C;
  --firuzeh-dim: #764F07;
  --on-accent: #ffffff;
  --accent-soft: rgba(141, 95, 12, 0.12);
  --saffron: #B06726;
  --danger: #AE3629;
  --good: #4C8A66;
  --live: #41968B;
  --live-soft: rgba(65, 150, 139, 0.12);

  --c-blunder: #AE3629;
  --c-mistake: #AE5828;
  --c-inaccuracy: #AE9528;
  --c-good: #5B8A4C;
  --c-best: #8D5F0C;
  --c-brilliant: #327EA4;
  --c-book: #96A6A5;

  --cat-checkmates-soft: rgba(174, 54, 41, 0.13);
  --cat-tactics-soft: rgba(176, 103, 38, 0.14);
  --cat-endgames-soft: rgba(76, 138, 102, 0.14);

  --shadow-sm: 0 1px 2px rgba(26, 33, 38, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.5);
  --shadow-md: 0 10px 24px -8px rgba(26, 33, 38, 0.12), 0 2px 5px -1px rgba(26, 33, 38, 0.06);
  --shadow-glow-accent: 0 0 16px -4px rgba(141, 95, 12, 0.18);

  color-scheme: light;
}

/* «خودکار» = هیچ data-appearance ای روی <html> نیست، پس تصمیم با دستگاه
   است. همان توکن‌های روشنِ بالا، فقط با شرطِ رسانه. */
@media (prefers-color-scheme: light) {
  :root:not([data-appearance="dark"]):not([data-appearance="light"]) {
    --ink: #EEF1EF;
    --panel: #FFFFFF;
    --raised: #E7E9E9;
    --line: #E0E1E1;
    --text: #1A2126;
    --muted: #5D6F6E;
    --faint: #96A6A5;
    --bg-secondary: var(--panel);
    --firuzeh: #8D5F0C;
    --firuzeh-dim: #764F07;
    --on-accent: #ffffff;
    --accent-soft: rgba(141, 95, 12, 0.12);
    --saffron: #B06726;
    --danger: #AE3629;
    --good: #4C8A66;
    --live: #41968B;
    --live-soft: rgba(65, 150, 139, 0.12);
    --c-blunder: #AE3629;
    --c-mistake: #AE5828;
    --c-inaccuracy: #AE9528;
    --c-good: #5B8A4C;
    --c-best: #8D5F0C;
    --c-brilliant: #327EA4;
    --c-book: #96A6A5;
    --cat-checkmates-soft: rgba(174, 54, 41, 0.13);
    --cat-tactics-soft: rgba(176, 103, 38, 0.14);
    --cat-endgames-soft: rgba(76, 138, 102, 0.14);
    --shadow-sm: 0 1px 2px rgba(26, 33, 38, 0.04), inset 0 1px 0 rgba(255, 255, 255, 0.5);
    --shadow-md: 0 10px 24px -8px rgba(26, 33, 38, 0.12), 0 2px 5px -1px rgba(26, 33, 38, 0.06);
    --shadow-glow-accent: 0 0 16px -4px rgba(141, 95, 12, 0.18);
    color-scheme: light;
  }
}

/* ---------------------------------------------------------- تمِ تخته
   کلاسِ تکی روی body (نگاه کن به applySettings در app.js). فقط رنگِ خانه‌ها
   را عوض می‌کند، نه ظاهرِ برنامه را. این سه تمِ اختیاری همان‌طور که بودند
   می‌مانند — تمِ پیش‌فرضِ جدید (دودی/زغالی) در بالا تعریف شد. */
.theme-wood {
  --sq-light: #f0d9b5;
  --sq-dark: #b58863;
  --hint-ink: rgba(60, 34, 18, 0.30);
  --hint-ink-d: rgba(52, 26, 10, 0.46);
}
.theme-blue {
  --sq-light: #e9eef7;
  --sq-dark: #b3c3da;
  --hint-ink: rgba(30, 48, 78, 0.28);
  --hint-ink-d: rgba(30, 48, 78, 0.34);
  --hl-last: rgba(246, 212, 84, 0.55);
  --hl-sel: rgba(112, 196, 132, 0.5);
  --coord-l: #93a7c6;
  --coord-d: #f2f6fc;
}
.theme-night {
  --sq-light: #b7c1d1;
  --sq-dark: #3d4a63;
  --hint-ink: rgba(14, 18, 30, 0.32);
  --hint-ink-d: rgba(226, 236, 255, 0.32);
}

/* ================================================================
   ۲. پایه
   ================================================================ */
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; }
body {
  background: var(--ink);
  color: var(--text);
  font-family: var(--fa);
  font-size: 15px;
  line-height: 1.7;
  overflow-x: hidden;
  overscroll-behavior-y: none;
  -webkit-font-smoothing: antialiased;
}
button { font: inherit; color: inherit; cursor: pointer; border: 0; background: none; }
input, select, textarea { font: inherit; }
h1, h2, h3 { line-height: 1.35; }
.hidden { display: none !important; }

/* حلقه‌ی فوکوس فقط برای کیبورد — لمس نباید حلقه بگذارد. */
:focus-visible { outline: 2px solid var(--firuzeh); outline-offset: 2px; }

/* ================================================================
   ۳. پوسته
   ================================================================ */
.wrap {
  max-width: var(--content-w);
  margin: 0 auto;
  padding: var(--s3) var(--gutter) var(--s5);
}
/* وقتی نوار پایین باز است، محتوا نباید زیرش پنهان شود */
body.has-bottom-nav .wrap {
  padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
}
/* وقتی دکمه‌ی شناورِ «بازی» هم روی صفحه است (فقط صفحه‌ی خانه)، محتوا باید
   جای بیشتری برای آن هم کنار بگذارد — وگرنه ته‌ِ کارتِ گفت‌وگوی عمومی
   درست زیرِ این دکمه‌ی شناور گیر می‌افتد. ارتفاعِ دکمه (~44px) + فاصله‌اش
   تا نوار (var(--s3)) + یک نفسِ کوچک اضافه (var(--s4)). */
body.has-play-fab .wrap {
  padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px) + 44px + var(--s3) + var(--s4));
}

/* ---------------------------------------------------------------- سربرگ */
/* بالاتر از پنلِ چت (z-index:45) می‌ماند — وگرنه بک‌دراپِ تمام‌صفحه‌ی چت
   جلوی فلش بازگشت و تنظیمات را می‌گرفت و راهی برای خروج از بازی، حین باز
   بودنِ چت، نمی‌ماند. */
header {
  position: relative; z-index: 46;
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--s2); height: 52px; margin-bottom: var(--s3);
}
.brand { display: flex; align-items: center; gap: var(--s2); font-weight: 700; font-size: 16px; }
/* لوگوی تصویری: دو فایل (فارسی/انگلیسی)، فقط یکی بسته به زبانِ فعلیِ
   صفحه دیده می‌شود — همون قاعده‌ای که پیش‌ازاین فقط فونتِ #brandText را
   عوض می‌کرد (نگاه کن به لِیبل‌های lang/dir زیر)، حالا خودِ عکس را. هر دو
   فایل پس‌زمینه‌ی شفاف دارند، پس نیازی به رنگِ پس‌زمینه نیست. خودش کلیک‌
   پذیر است (میان‌برِ صفحه‌ی اصلی، نگاه کن به listenerِ brandText در app.js)
   — آیکونِ مربعیِ قدیمی که این کار را می‌کرد برداشته شده. */
.brand-logo-wrap { display: inline-flex; align-items: center; cursor: pointer; }
.brand-logo { display: block; height: 30px; width: auto; }
.brand-logo-en { display: none; }
:lang(en) .brand-logo-fa, [dir="ltr"] .brand-logo-fa { display: none; }
:lang(en) .brand-logo-en, [dir="ltr"] .brand-logo-en { display: block; }
/* الان لوگو کنارِ دکمه‌ی برگشت هم می‌ماند (نه فقط جایگزینش) — این
   position:relative برای همان جهشِ عرضِ قدیمی لازم بود که دیگر وجود ندارد،
   ولی برای موقعیت‌دهیِ باقیِ محتوای سربرگ همچنان نگه داشته شده. */
#brandBox { position: relative; }
#btnBack svg { transform: scaleX(-1); }  /* در نوشتار راست‌به‌چپ، «عقب» یعنی راست */

.hdr-right { display: flex; align-items: center; gap: var(--s1); }
.who { font-size: 12.5px; color: var(--muted); text-align: start; line-height: 1.3; unicode-bidi: plaintext; }
.who-btn { display: flex; align-items: center; gap: var(--s2); padding: 3px; border-radius: var(--r-pill); }
.who-btn:hover { background: var(--panel); }
.who b { display: block; color: var(--text); font-variant-numeric: tabular-nums; font-size: 14px; font-weight: 700; }
.ava.sm { width: 26px; height: 26px; border-radius: 8px; font-size: 11px; }

.icon-btn {
  /* flex-shrink صفر: بدون این، وقتی سربرگ روی گوشیِ باریک شلوغ می‌شود
     مرورگر دکمه‌ها را تا زیرِ ۳۰ پیکسل جمع می‌کند — هم نامنظم می‌شوند هم
     از حداقلِ اندازه‌ی لمسی می‌افتند. */
  flex: 0 0 auto;
  width: 36px; height: 36px; border-radius: var(--r-pill); display: grid; place-items: center;
  background: transparent; border: 1px solid transparent; font-size: 16px; color: var(--muted);
  position: relative; /* .badge-dot به همین تکیه می‌کند */
  transition: background 0.12s, color 0.12s;
}
.icon-btn:hover { background: var(--panel); color: var(--text); }
.icon-btn svg { width: 18px; height: 18px; }

.badge-dot {
  position: absolute; inset-inline-end: 5px; top: 5px; width: 8px; height: 8px;
  border-radius: 50%; background: var(--danger); border: 2px solid var(--ink);
}
.badge-count {
  position: absolute; inset-inline-end: 1px; top: 1px; min-width: 16px; height: 16px;
  padding: 0 3px; border-radius: 99px; background: var(--danger); border: 2px solid var(--ink);
  color: #fff; font-size: 10px; font-weight: 700; line-height: 12px;
  display: flex; align-items: center; justify-content: center;
}

/* ---------------------------------------------------------- نوارِ ناوبری */
#bottomNav {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 40;
  display: flex; max-width: 560px; margin: 0 auto;
  background: var(--bg-secondary); border-top: 1px solid var(--line);
  padding: var(--s1) var(--s1) calc(var(--s1) + env(safe-area-inset-bottom, 0px));
  box-shadow: var(--shadow-md);
}
.bn-tab {
  flex: 1; display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 7px 2px; border-radius: var(--r); color: var(--muted);
  min-width: 0; transition: color 0.12s;
}
.bn-tab .ic {
  width: auto; height: auto; background: none; border: 0; display: block;
}
.bn-tab .ic svg { width: 21px; height: 21px; display: block; }
.bn-tab .lbl {
  font-size: 10.5px; line-height: 1.2; max-width: 100%;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.bn-tab.active { color: var(--firuzeh); }
.bn-tab:active { background: var(--raised); }
.bn-tab-desktop { display: none; } /* فقط دسکتاپ — نگاه کن به CSS دسکتاپ */
.bn-tab-mobile-play { display: none; } /* فقط موبایل — نگاه کن به بخشِ ۱۱ (گوشیِ باریک) */
/* دکمه‌ی منوی همبرگری یک لایه‌ی div اضافه دارد (برای جایگاهِ پنلِ
   شناور، نگاه کن به .nav-menu-panel پایین‌تر) — پس خودش هم باید مثلِ
   بقیه‌ی .bn-tabها flex:1 بگیرد، وگرنه فقط به‌اندازه‌ی محتوا جمع می‌شود
   و ردیفِ نوار نامتقارن می‌شود. */
.nav-menu-wrap { display: flex; flex: 1; min-width: 0; }

/* ------------------------------------------------------------- بخش‌بندی
   هر مقصد از چند «بخش» ساخته می‌شود: یک عنوانِ کوچکِ خارج از کارت، و بعد
   کارت‌ها یا ردیف‌های ناوبری. همین یک الگو جای بنتوی قبلی را می‌گیرد. */
.sec { margin-bottom: var(--s5); }
.sec:last-child { margin-bottom: 0; }
.sec-title {
  margin: 0 0 var(--s3); font-size: 13px; font-weight: 700;
  color: var(--muted); letter-spacing: 0.02em;
}
.sec-sub { margin: -8px 0 var(--s3); font-size: 13px; color: var(--muted); }

/* ================================================================
   ۴. المان‌های پایه
   ================================================================ */
.card {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); padding: var(--s4); margin-bottom: var(--s3);
  box-shadow: var(--shadow-sm);
}
.card:last-child { margin-bottom: 0; }
.card h2 { margin: 0 0 var(--s3); font-size: 15px; font-weight: 700; }
.card-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--s2); margin-bottom: var(--s2);
}
.card-head h2 { margin: 0; }
.hint-text { margin: 0 0 var(--s3); color: var(--muted); font-size: 13px; unicode-bidi: plaintext; }

/* سرتیترِ روز در تقویمِ مهلت‌های مکاتبه‌ای */
.cal-day-head {
  font-size: 11.5px; font-weight: 700; color: var(--muted);
  padding: var(--s2) 0 4px; unicode-bidi: plaintext;
}
.cal-day-head:not(:first-child) { border-top: 1px solid var(--line); margin-top: var(--s2); }
.hint-text:last-child { margin-bottom: 0; }

/* --------------------------------------------------------------- دکمه‌ها */
.btn {
  display: block; width: 100%; padding: 11px var(--s4); border-radius: var(--r-pill);
  background: var(--raised); border: 1px solid var(--line); font-weight: 700;
  font-size: 14px; text-align: center;
  transition: background 0.12s, border-color 0.12s, transform 0.06s;
}
.btn + .btn, .btn + .row, .row + .btn { margin-top: var(--s2); }
.btn:hover { border-color: var(--muted); }
.btn:active { transform: scale(0.985); }
.btn.primary {
  background: var(--firuzeh); color: var(--on-accent); border-color: transparent;
  box-shadow: var(--shadow-sm);
}
.btn.primary:hover { background: var(--firuzeh-dim); border-color: transparent; color: #ffffff; }
/* دکمه‌ی اصلیِ یک صفحه — بلندتر، تا در یک نگاه پیدا شود */
.btn.lg { padding: 14px var(--s4); font-size: 15px; }
.btn.sm { padding: 6px var(--s3); font-size: 12.5px; border-radius: var(--r-pill); width: auto; display: inline-flex;
          align-items: center; justify-content: center; gap: 6px; }
.btn.warn { color: var(--danger); border-color: transparent; background: transparent; }
.btn.warn:hover { background: var(--raised); border-color: var(--danger); }
.btn.ghost { background: transparent; }
.btn.ghost:hover { background: var(--raised); }
.btn:disabled { opacity: 0.4; cursor: default; }
.btn.sm svg { width: 13px; height: 13px; }

.link-cta {
  color: var(--firuzeh); font-size: 13px; font-weight: 600; padding: 6px var(--s1);
  white-space: nowrap;
}

.row { display: flex; gap: var(--s2); }
.row > * { flex: 1; }
.row.tight { margin-top: var(--s2); }
/* دکمه‌های پخشِ تحلیل (اول/عقب/جلو/آخر) باید صرف‌نظر از زبانِ رابط همیشه
   با همان ترتیبِ استاندارد (⏮ ◀ ▶ ⏭) دیده شوند — مثل ساعت و نماد حرکت،
   جهتشان قراردادی است نه زبانی، پس LTR ثابت می‌مانند. */
.an-controls { direction: ltr; }

/* ------------------------------------------------------ ردیفِ ناوبری
   الگویِ اصلیِ «لایه‌لایه بودن»: چیزی که یک قدم دورتر است، نه یک کارتِ باز
   روی همین صفحه، بلکه یک ردیفِ یک‌خطی است که به صفحه‌ی خودش می‌رود. */
.nav-list {
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); overflow: hidden;
}
.nav-row {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: var(--s3) var(--s4); text-align: start;
  border-bottom: 1px solid var(--line);
  transition: background 0.12s;
}
.nav-row:last-child { border-bottom: 0; }
/* ردیفِ غیرفعال برای مهمان — کلیک هنوز کار می‌کند (گیتِ «این برای اعضاست»
   را باز می‌کند)، فقط ظاهرش می‌گوید فعلاً در دسترس نیست. */
.nav-row.is-locked { opacity: .5; }
.nav-row.is-locked:hover, .nav-row.is-locked:active { background: transparent; }
.nav-row:hover { background: var(--raised); }
.nav-row:active { background: var(--raised); }
.nr-ic {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: var(--r-sm);
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--firuzeh);
}
.nr-ic svg { width: 17px; height: 17px; }
.nr-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.nr-title { font-weight: 600; font-size: 14px; }
.nr-sub {
  font-size: 12px; color: var(--muted); line-height: 1.5;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.nr-chev { flex: 0 0 auto; color: var(--muted); display: grid; place-items: center; }
.nr-chev svg { width: 15px; height: 15px; }
/* در راست‌به‌چپ، «جلو» یعنی چپ — آیکونِ chevron رو به چپ رسم شده، پس در
   حالتِ چپ‌به‌راست باید آینه شود. */
:root[dir="ltr"] .nr-chev svg, html[dir="ltr"] .nr-chev svg { transform: scaleX(-1); }

/* ================================================================
   بازطراحیِ صفحه‌ی خانه — هیرو، اقدام‌های سریع، نوارِ دوستان، پوسترها،
   دکمه‌ی شناورِ بازی. همه بدونِ هیچ عکس یا فونتِ خارجی: گرادیان‌های CSS و
   همان آیکون‌های SVGِ درون‌خطِ پروژه.
   ================================================================ */

/* ---------------------------------------------------------- نوارِ دوستان */
#friendsList.friend-strip {
  display: flex; gap: var(--s2); overflow-x: auto; padding: 2px 2px 4px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
}
#friendsList.friend-strip::-webkit-scrollbar { display: none; }
#friendsList.friend-strip .friend-row {
  flex: 0 0 78px; display: flex; flex-direction: column; align-items: center;
  gap: 4px; text-align: center; padding: var(--s2) 2px; border-radius: var(--r-sm);
}
#friendsList.friend-strip .friend-row:hover { background: var(--raised); }
#friendsList.friend-strip .ava.sm { width: 42px; height: 42px; font-size: 15px; }
#friendsList.friend-strip .fr-info { display: flex; flex-direction: column; align-items: center; gap: 1px; }
#friendsList.friend-strip .fr-name {
  font-size: 12px; max-width: 74px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
#friendsList.friend-strip .fr-meta { font-size: 10.5px; }
#friendsList.friend-strip .dot { margin-top: 1px; }

/* ------------------------------------------------------------- هیرو */
/* هیروی عکسی: مثلِ بقیه‌ی کارت‌های عکسیِ سایت — بدونِ کراپِ CSS، بدونِ
   لایه‌ی تیره‌ی پشتِ نوشته (فقط سایه‌ی متن). نوشته+دکمه روی نیمه‌ی خالیِ
   خودِ عکس می‌نشینند؛ عمداً «راستِ فیزیکی» (نه inset-inline-*) چون آن
   نیمه‌ی خالی نقطه‌ای ثابت روی خودِ تصویر است، نه وابسته به جهتِ صفحه —
   همان دلیلِ card-title-chip بالاتر در همین فایل. */
.home-hero-photo { overflow: hidden; position: relative; }
.home-hero-photo-body {
  position: absolute; top: 0; bottom: 0; right: 0; width: 50%;
  display: flex; flex-direction: column; justify-content: center;
  gap: var(--s2); padding: var(--s4);
}
.home-hero-quote {
  margin: 0; width: 100%; box-sizing: border-box;
  font-size: 14px; font-weight: 700; line-height: 1.5; text-align: start;
  color: #fffdf9; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}
/* دکمه پایه‌اش width:100% است (.btn) — این‌جا باید عرضِ طبیعیِ خودش را
   بگیرد وگرنه کلِ نیمه‌ی عکس را می‌پوشاند (باگی که رویِ گوشی خیلی به‌چشم
   می‌آمد). align-self هم بی‌اثر بود چون width صریح روی .btn برنده می‌شد. */
.home-hero-photo-body .btn {
  width: auto; align-self: flex-start; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}

/* روی موبایل عکس کوتاه‌تر می‌نشیند (عرضِ تمامِ صفحه، نسبتِ ابعادِ پهن)،
   پس نوشته/دکمه جمع‌وجورتر می‌شوند تا توی همون نیمه‌ی خالی جا شوند. */
@media (max-width: 767px) {
  .home-hero-quote { font-size: 12px; line-height: 1.45; }
  .home-hero-photo-body { padding: var(--s3); gap: 6px; }
  .home-hero-photo-body .btn { padding: 7px var(--s3); font-size: 12.5px; }
}

/* ------------------------------------------------ نوارِ افقیِ ریتینگ‌ها */
/* جایگزینِ کارتِ پروفایلِ برداشته‌شده: همان زبانِ بصریِ speed-card (پروفایل)
   را وام می‌گیرد، فقط توی یک ردیفِ اسکرول‌پذیرِ افقی به‌جای گریدِ ثابت —
   روی گوشی جا نمی‌شود همه‌شان کنار هم، پس با انگشت رد می‌شوند. */
.hss-row {
  display: flex; gap: var(--s2); overflow-x: auto; padding-bottom: 2px;
  scrollbar-width: none; -webkit-overflow-scrolling: touch;
}
.hss-row::-webkit-scrollbar { display: none; }
.hss-card { flex: 0 0 92px; }
.hss-card.skel { min-height: 84px; opacity: 0.5; }

/* ------------------------------------------------------- اقدام‌های سریع */
.qa-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); }
/* استفاده‌ی دوباره از همین زبانِ بصری در صفحه‌ی یادگیری — فقط موبایل،
   نگاه کن به بخشِ ۱۱ (گوشیِ باریک) برای display:grid شدنش. */
.learn-quick { display: none; }
/* نوارِ افقیِ دسته‌های یادگیری — فقط موبایل (همان‌جا). */
.learn-cats { display: none; }
/* ردیفِ «ادامه بده» — فقط موبایل (همان‌جا، هیرویِ هابِ یادگیری). */
.continue-row { display: none; }
/* برچسب/ردیفِ سطح بالای هیرویِ یادگیری — فقط موبایل (همان‌جا). */
.hero-kicker, .hero-meta-row { display: none; }
.qa-card {
  display: flex; flex-direction: column; align-items: flex-start; text-align: start; gap: 4px;
  width: 100%; min-height: 92px;
}
.qa-ic {
  width: 32px; height: 32px; border-radius: var(--r-sm); flex: 0 0 auto;
  display: grid; place-items: center; background: var(--accent-soft); color: var(--firuzeh);
  margin-bottom: 2px;
}
.qa-ic svg { width: 16px; height: 16px; }
.qa-title { font-weight: 700; font-size: 13.5px; }
.qa-sub { font-size: 11.5px; color: var(--muted); line-height: 1.5; }
.qa-card-head { display: flex; align-items: center; gap: var(--s2); margin-bottom: 2px; }
.qa-card-head .qa-ic { margin-bottom: 0; }
.qa-card-head .qa-title { font-size: 13px; }
.qa-list-card { min-height: auto; grid-column: 1 / -1; }
.qa-list-card .grow, .qa-list-card .friend-row { font-size: 12.5px; }
.qa-list-card .grow { padding: var(--s2) 0; }

/* ------------------------------------------------- بازی‌های اخیر + کناری */
.home-lower-grid { display: flex; flex-direction: column; gap: var(--s4); }
.home-side { display: flex; flex-direction: column; gap: var(--s3); }
.home-quote-card { display: flex; flex-direction: column; gap: var(--s2); }
.sec-title.sm { font-size: 13px; margin: 0 0 2px; }

/* بنرِ تورنمنت — همون زبانِ بصریِ هیروی خانه (بدونِ کراپِ CSS، بدونِ
   لایه‌ی تیره، فقط سایه‌ی متن)، این‌بار نوشته روی نیمه‌ی چپِ خودِ عکس
   می‌نشیند چون گوشه‌ی خالیِ همین عکس آن‌جاست (فیزیکی left، به همون دلیلِ
   قبلی — نه inset-inline-*). یک دکمه است، نه فقط کارت: کلیکش
   openTournaments را صدا می‌زند. */
.home-tour-banner { display: block; width: 100%; text-align: start; overflow: hidden; position: relative; }
.home-tour-banner-body {
  position: absolute; top: 0; bottom: 0; left: 0; width: 56%;
  display: flex; flex-direction: column; justify-content: center;
  gap: 4px; padding: var(--s3);
}
.home-tour-banner-title {
  margin: 0; width: 100%; box-sizing: border-box;
  font-size: 13px; font-weight: 800; line-height: 1.4; text-align: start;
  color: #fffdf9; text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}
.home-tour-banner-sub {
  margin: 0; width: 100%; box-sizing: border-box;
  font-size: 11px; font-weight: 600; line-height: 1.4; text-align: start;
  color: rgba(255, 253, 249, 0.85); text-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
}

.home-ach-card {
  display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: start;
}
.home-ach-card .qa-ic { margin-bottom: 0; }
.ach-info { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
.ach-info b { font-size: 13px; font-weight: 700; }
.wl-bar.sm { height: 5px; }
.wl-bar.sm .w { background: var(--firuzeh); }

.home-quote { font-size: 13px; line-height: 1.7; margin: 0; color: var(--text); font-style: italic; }
.home-quote-by { font-size: 11.5px; color: var(--muted); }

/* ---------------------------------------------------------- سرِ دوستان */
.friends-head {
  display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s3);
}
.friends-head .sec-title { margin-bottom: 0; }

/* -------------------------------------------------------- شیتِ شروعِ بازی
   دقیقاً همان الگوی .chat-panel — بک‌دراپ + شیتِ پایین‌چسب با انیمیشنِ rise. */
.play-panel { position: fixed; inset: 0; z-index: 45; }
.play-backdrop { position: absolute; inset: 0; background: rgba(18, 16, 14, 0.55); }
.play-sheet {
  position: absolute; inset-inline: 0; bottom: 0; max-width: 560px; margin: 0 auto;
  max-height: 86vh; overflow-y: auto;
  background: var(--panel); border-radius: var(--r-lg) var(--r-lg) 0 0;
  border: 1px solid var(--line); border-bottom: 0; animation: rise 0.16s ease-out;
  padding: 0 var(--s4) calc(var(--s4) + env(safe-area-inset-bottom, 0px));
}
.play-sheet-head {
  position: sticky; top: 0; background: var(--panel);
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s4) 0 var(--s3); font-weight: 700; font-size: 15px;
}

/* --------------------------------------------------- دکمه‌ی شناورِ بازی */
.play-fab {
  position: fixed; z-index: 41; inset-inline: 0; margin-inline: auto; width: max-content;
  bottom: calc(72px + env(safe-area-inset-bottom, 0px) + var(--s3));
  display: flex; align-items: center; gap: var(--s2);
  padding: 12px 22px; border-radius: 99px;
  background: var(--firuzeh); color: var(--on-accent); font-weight: 700; font-size: 14px;
  box-shadow: 0 6px 18px rgba(18, 16, 14, 0.32);
  transition: transform 0.15s ease, opacity 0.2s ease;
}
.play-fab:active { transform: scale(0.96); }
/* وقتی کاربر تا کارتِ گفت‌وگوی عمومی اسکرول می‌کند، دکمه محو می‌شود تا
   دستش اشتباهی به آن نخورد؛ با برگشتن به بالا دوباره ظاهر می‌شود (نگاه
   کن به fabFadeObserver در app.js). */
.play-fab.faded { opacity: 0; pointer-events: none; }
.play-fab svg { width: 17px; height: 17px; }

/* ------------------------------------------------------------- ورودی‌ها */
label.field { display: block; margin-bottom: var(--s3); font-size: 13px; color: var(--muted); }
label.field .opt { color: var(--muted); font-weight: 400; }
/* ردیفِ برچسب+کنترل — کنارِ هم به‌جای زیرِ هم، چون کنترل‌های کوچک
   (چک‌باکس، سگمنت) بلوکِ جداگانه فضایِ خالیِ اضافه می‌سازند. */
.field-row {
  display: flex; align-items: center; gap: var(--s3);
  margin-bottom: var(--s3); font-size: 13px;
}
.field-row input[type=checkbox] { width: 18px; height: 18px; flex: 0 0 auto; }
.field-row > .lbl { flex: 0 0 auto; color: var(--muted); }
.field-row > .seg { flex: 1; margin: 0; }

select, input[type=text], input[type=password], input[type=number], textarea {
  width: 100%; margin-top: var(--s1); padding: 11px var(--s3); border-radius: var(--r-sm);
  background: var(--ink); color: var(--text); border: 1px solid var(--line);
}
select:focus, input:focus, textarea:focus { outline: none; border-color: var(--firuzeh); }
/* توضیحاتِ کلاب فارسی است — برخلافِ pgnBox (تنها استفاده‌ی دیگرِ textarea)
   که notation لاتین/LTR است، پس این دو باید جهتِ raw textarea را override کنند. */
textarea { font-family: var(--fa); font-size: 13px; resize: vertical; direction: ltr; text-align: left; }
#ccDesc, #ecDesc { direction: rtl; text-align: right; }
/* پرشدنِ خودکارِ مرورگر (autofill) رنگِ پس‌زمینه را با یک لایه‌ی داخلیِ خودش
   عوض می‌کند که هیچ background معمولی رویش اثر ندارد — فقط این ترفند جواب
   می‌دهد: یک سایه‌ی داخلیِ به‌اندازه‌ی کل فیلد، هم‌رنگِ خودِ فیلد. */
input:-webkit-autofill, input:-webkit-autofill:hover,
input:-webkit-autofill:focus, input:-webkit-autofill:active {
  -webkit-box-shadow: 0 0 0 1000px var(--ink) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
}
.otp-input {
  text-align: center; font-size: 22px; letter-spacing: 8px;
  font-variant-numeric: tabular-nums; margin-bottom: var(--s3);
}

/* دکمه‌ی گوگل عمداً رنگِ برندِ خودش را ندارد: صفحه یک دکمه‌ی اصلیِ
   فیروزه‌ای دارد و دو دکمه‌ی پررنگ کنارِ هم یعنی هیچ‌کدام اصلی نیست.
   لوگو کارِ شناسایی را می‌کند، رنگ لازم نیست. */
.btn-google {
  display: flex; align-items: center; justify-content: center; gap: var(--s2);
}
.btn-google svg { flex: none; }

/* جداکننده‌ی «یا» — خطی در دو طرفِ کلمه */
.auth-or {
  display: flex; align-items: center; gap: var(--s3);
  margin: var(--s4) 0; color: var(--muted); font-size: 12px;
}
.auth-or::before, .auth-or::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}

/* ------------------------------------------------------------- سگمنت */
.seg {
  display: flex; background: var(--ink); border: 1px solid var(--line);
  border-radius: var(--r-sm); padding: 3px; margin: var(--s1) 0 var(--s3);
}
.seg button {
  flex: 1; padding: 8px 4px; border-radius: 7px; color: var(--muted);
  font-weight: 600; font-size: 13px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background 0.12s, color 0.12s;
}
.seg button[aria-pressed="true"] { background: var(--panel); color: var(--text); }
/* سگمنتِ انتخابِ حالتِ بازی — بزرگ‌تر، چون تصمیمِ اصلیِ صفحه‌ی خانه است */
.seg-lg button { padding: 11px 4px; font-size: 14px; }
.seg-lg button[aria-pressed="true"] { background: var(--firuzeh); color: var(--on-accent); }

/* ست مهره چهار گزینه با نامِ بلند دارد («پیش‌فرض سرور»، «خانگی (Staunton)»)؛
   در یک ردیف هیچ عرضی کافی نیست، پس این یکی به دو سطر می‌شکند. */
#pieceSetSeg { flex-wrap: wrap; }
#pieceSetSeg button { flex: 1 1 auto; min-width: 104px; }

/* ردیفِ انتخابِ گونه: با ۷ گزینه (استاندارد + ۶ واریانت) توی یک پیلِ
   segmented جا نمی‌شد و از کادر بیرون می‌زد (flex-wrap با min-width
   ثابت روی چندتا آیتم قابل‌اعتماد نبود) — یک گرید با تعداد ستونِ ثابت
   همیشه داخل عرضِ کارت می‌ماند، هرچقدر هم متنِ برچسب بلند باشد. هر دکمه
   حالا مرزِ خودش را دارد (نه یک پیلِ مشترک) چون هفت‌تایی دیگر واقعاً یک
   «سگمنتِ» دوتاسه‌گزینه‌ای نیست. */
.variant-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px;
  margin: var(--s1) 0 var(--s3);
}
.variant-grid button {
  padding: 8px 4px; border-radius: 7px; border: 1px solid var(--line);
  background: var(--ink); color: var(--muted); font-weight: 600; font-size: 12px;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.variant-grid button[aria-pressed="true"] {
  background: var(--panel); color: var(--text); border-color: var(--firuzeh);
}

/* ------------------------------------------------- برچسب و نشانه‌ها */
.tag { font-size: 12px; color: var(--muted); }
.tag.tour-status-running,  .tag.cm-status-running  { color: var(--firuzeh); }
.tag.tour-status-scheduled,.tag.cm-status-pending  { color: var(--saffron); }
.tag.tour-status-finished, .tag.cm-status-finished { color: var(--muted); }
.tag.tour-status-cancelled,
.tag.cm-status-declined, .tag.cm-status-cancelled  { color: var(--danger); }
/* حرکتِ تأییدنشده‌ی بازیِ مکاتبه‌ای — نگاه کن به corrMineRowHtml در app.js */
.tag.corr-pending { color: var(--saffron); font-weight: 700; }

.soon {
  display: inline-block; margin-top: var(--s1); font-size: 11px; font-weight: 700;
  color: var(--saffron); background: var(--accent-soft);
  border: 1px solid var(--line); padding: 3px var(--s3); border-radius: 100px;
}
.premium-badge {
  display: inline-flex; align-items: center; gap: 4px; margin-inline-start: var(--s2);
  font-size: 11px; font-weight: 700; vertical-align: middle;
  background: var(--saffron); color: var(--ink);
  padding: 2px 8px; border-radius: 100px;
}
.premium-badge svg { width: 12px; height: 12px; }

/* ------------------------------------------------- «بیشتر»ِ بازشونده */
.more-toggle {
  display: flex; align-items: center; justify-content: center; gap: var(--s2);
  margin-bottom: var(--s3); color: var(--muted); font-size: 13px;
}
.more-toggle .chev {
  width: 8px; height: 8px; border-inline-end: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(45deg);
  transition: transform 0.15s;
}
.more-toggle[aria-expanded="true"] .chev { transform: rotate(-135deg); }

/* -------------------------------------------------------- سطحِ بازی */
.levels { display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--s1); margin: var(--s2) 0; }
.lv {
  padding: 10px 0; border-radius: 8px; background: var(--raised); border: 1px solid var(--line);
  color: var(--muted); font-weight: 700; font-variant-numeric: tabular-nums; font-size: 14px;
}
.lv[aria-pressed="true"] { background: var(--firuzeh); color: var(--on-accent); border-color: transparent; }
.lv-name { font-size: 13px; color: var(--muted); }
.lv-name b { color: var(--text); }

/* ------------------------------------------------- شخصیتِ ربات */
.personas {
  display: flex; gap: var(--s2); overflow-x: auto; padding-bottom: 2px; margin-bottom: var(--s3);
  scrollbar-width: none;
}
.personas::-webkit-scrollbar { display: none; }
.persona {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 10px 14px; border-radius: 12px; background: var(--raised); border: 1px solid var(--line);
  color: var(--muted); min-width: 76px;
}
.persona .ic { font-size: 20px; line-height: 1; }
.persona .nm { font-size: 12px; font-weight: 600; white-space: nowrap; }
.persona[aria-pressed="true"] { background: var(--firuzeh); color: var(--on-accent); border-color: transparent; }
.persona[aria-pressed="true"] .nm { color: var(--on-accent); }

/* --------------------------------------------------- کنترلِ زمان (شبکه) */
/* جایگزینِ <select> بومیِ مرورگر برای انتخابِ زمان — شبیهِ لیچس، اما با
   توکن‌های خودمان (پس‌زمینه/برجسته‌سازی همان .lv بالاست) تا حسِ اپ عوض نشود. */
.tc-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2);
  margin: var(--s1) 0 var(--s3);
}
.tc-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 3px; padding: 12px 4px; border-radius: var(--r-sm);
  background: var(--raised); border: 1px solid var(--line);
  transition: background 0.12s, border-color 0.12s, transform 0.1s;
}
.tc-btn:active { transform: scale(0.97); }
.tc-time { font-size: 15px; font-weight: 700; color: var(--text); font-variant-numeric: tabular-nums; }
.tc-cat { font-size: 11.5px; color: var(--muted); }
.tc-btn[aria-pressed="true"] { background: var(--firuzeh); border-color: transparent; }
.tc-btn[aria-pressed="true"] .tc-time,
.tc-btn[aria-pressed="true"] .tc-cat { color: var(--on-accent); }

/* نوارِ باریکِ «زمانِ فعلی» — بسته است تا شبکه فقط وقتِ لازم باز شود؛
   ظاهرش عمداً شبیهِ همان <select> قدیمی است (پس‌زمینه‌ی --ink) تا در جریانِ
   فرم گم نشود. */
.tc-current {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  width: 100%; margin-top: var(--s1); padding: 11px var(--s3); border-radius: var(--r-sm);
  background: var(--ink); border: 1px solid var(--line); color: var(--text); font-size: 14px;
}
.tc-current-time { font-weight: 700; }
.tc-current-cat { color: var(--muted); font-size: 12.5px; margin-inline-start: 6px; }
.tc-current .chev {
  flex: 0 0 auto; width: 8px; height: 8px; border-inline-end: 2px solid currentColor;
  border-bottom: 2px solid currentColor; transform: rotate(45deg);
  transition: transform 0.15s; color: var(--muted);
}
.tc-current[aria-expanded="true"] .chev { transform: rotate(-135deg); }

/* کاشیِ «دلخواه» — همان ظاهرِ بقیه، فقط یک نشانه‌ی ریزِ گوشه تا از پیش‌فرض‌ها
   جدا دیده شود وقتی هنوز چیزی انتخاب نشده. */
.tc-btn-custom { position: relative; }
.tc-btn-custom::after {
  content: "⚙"; position: absolute; top: 4px; inset-inline-end: 6px;
  font-size: 10px; color: var(--muted); opacity: 0.7;
}
.tc-btn-custom[aria-pressed="true"]::after { color: var(--on-accent); opacity: 0.9; }

/* دیالوگِ کوچکِ زیرِ شبکه برای واردکردنِ دقیقه/افزایش — با کلیک روی کاشیِ
   دلخواه باز می‌شود، به‌جایِ این‌که خودِ کاشی بی‌واسطه انتخاب شود. */
.tc-custom-dialog {
  grid-column: 1 / -1; display: flex; flex-direction: column; gap: var(--s2);
  padding: var(--s3); border-radius: var(--r-sm);
  background: var(--raised); border: 1px solid var(--line);
}
.tc-custom-dialog label {
  display: flex; align-items: center; justify-content: space-between;
  font-size: 13.5px; color: var(--muted); gap: var(--s2);
}
.tc-custom-dialog input[type="number"] {
  width: 80px; padding: 8px 10px; border-radius: var(--r-sm);
  background: var(--ink); border: 1px solid var(--line); color: var(--text);
  font-size: 14px; text-align: center; font-variant-numeric: tabular-nums;
}

/* دکمه‌ی آیکونی — نوارِ ابزارِ صفحه‌ی بازی و شیت‌ها */
.ic {
  position: relative;
  width: 40px; height: 40px; flex: 0 0 auto; border-radius: var(--r-sm);
  display: grid; place-items: center; background: var(--raised);
  border: 1px solid var(--line); transition: transform 0.06s, background 0.12s;
}
.ic:hover { background: var(--panel); }
.ic:active { transform: scale(0.92); }
.ic svg { width: 19px; height: 19px; }
.ic.warn { color: var(--danger); }
.ic.active { background: var(--firuzeh); color: var(--on-accent); border-color: transparent; }
.ic:disabled { opacity: 0.35; }
.ic.sm { width: 34px; height: 34px; background: transparent; border-color: transparent; }
.ic.sm:disabled { opacity: 0.25; }

/* ================================================================
   ۵. تخته — هندسه‌ی این بخش کارکردی است، نه تزئینی: نسبت‌ها و درصدها
   دقیقاً همان‌اند که board.js موقعِ جای‌گذاریِ مهره‌ها حساب می‌کند.
   ================================================================ */
.board {
  position: relative; width: 100%; aspect-ratio: 1; direction: ltr;
  border-radius: var(--r-sm); overflow: hidden; touch-action: none; user-select: none;
  box-shadow: var(--shadow-md);
}
/* درگِ بومیِ مرورگر روی تخته باید کاملاً خاموش باشد.
   `touch-action` و `user-select` این کار را نمی‌کنند — آن‌ها اسکرول و
   انتخابِ متن را می‌گیرند، ولی drag-and-drop بومی مکانیزمِ جداگانه‌ای است.
   بدونِ این، نگه‌داشتنِ انگشت روی یک مهره در کرومِ اندروید یک درگِ بومی
   شروع می‌کند و مرورگر یک «کارتِ شبح» می‌کشد: یک مستطیلِ گردگوشه کمی
   بزرگ‌تر از خانه، با اسنپ‌شاتِ کوچک‌شده‌ی خودِ مهره داخلش، که پس‌زمینه‌اش
   را از رنگِ صفحه می‌گیرد (در تمِ تیره تیره، در تمِ روشن سفید). همان مربعی
   که موقعِ زدنِ مهره یک لحظه پیدا و محو می‌شد.
   درگِ خودِ مهره‌ها با pointer events پیاده شده و به این ربطی ندارد. */
.board, .board * {
  -webkit-user-drag: none;
  user-drag: none;
  -webkit-touch-callout: none;
}
.board > div { position: absolute; inset: 0; }
.arrows {
  position: absolute; inset: 0; width: 100%; height: 100%;
  z-index: 3; pointer-events: none; overflow: visible;
}
.arrow-shaft { stroke: var(--arrow-color); stroke-width: 0.16; stroke-linecap: round; stroke-linejoin: round; opacity: 0.85; }
.arrow-head { fill: var(--arrow-color); opacity: 0.85; }
/* رنگِ هر فلش با کلاسِ خودش مشخص می‌شود (نه با data-tone روی svg)، چون حالا
   ممکن است چند فلش هم‌زمان با رنگ‌های متفاوت روی تخته باشند: فلشِ راهنما،
   فلش‌های دستیِ کاربر (کلیک راست)، و پیش‌نمایشِ فلشِ در حالِ کشیدن. */
.tone-hint { --arrow-color: var(--saffron); }
.tone-best { --arrow-color: var(--c-best); }
.tone-user { --arrow-color: #15a12a; }
.tone-draft { --arrow-color: #15a12a; opacity: 0.45; }
/* خطِ دوم/سومِ multipv در حالتِ کاوش — کم‌رنگ‌تر از بهترین‌حرکت تا اولویت
   بصری همیشه روشن باشد: خطِ اول پررنگ، بقیه فقط برای مقایسه. */
.tone-pv2 { --arrow-color: #3b82c4; }
.tone-pv2.arrow-shaft, .tone-pv2.arrow-head { opacity: 0.6; }
.tone-pv3 { --arrow-color: #8a8f98; }
.tone-pv3.arrow-shaft, .tone-pv3.arrow-head { opacity: 0.45; }
.badges { z-index: 4; pointer-events: none; }
/* نشانِ روی خانه — دقیقاً مثلِ .mk اندازه‌اش می‌شود (۱۲.۵٪ از تخته)، ولی
   خودِ دایره‌ی رنگی داخلش روی گوشه‌ی بالا-راستِ همان خانه می‌نشیند تا هم
   مهره را کامل نپوشاند هم از لبه‌ی تخته بیرون نزند. */
.sqbadge { position: absolute; top: 0; left: 0; width: 12.5%; height: 12.5%; }
.sqbadge .dot {
  position: absolute; top: -7px; right: -7px; width: 22px; height: 22px;
  border-radius: 50%; display: flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px var(--panel); color: #fff;
}
.sqbadge .dot svg { width: 13px; height: 13px; display: block; }
/* تاجِ پایانِ بازی — روی گوشه‌ی بالا-راستِ خانه‌ی شاهِ برنده، تا با یک نگاه
   معلوم شود بازی تمام شده، نه اینکه صفحه هنگ کرده (مخصوصاً در تحلیلِ
   بازی‌های بزرگان که نتیجه فوری روی صفحه نوشته نمی‌شود). */
.crown { z-index: 5; pointer-events: none; }
.king-crown {
  position: absolute; top: 0; left: 0; width: 12.5%; height: 12.5%;
  display: flex; align-items: flex-start; justify-content: flex-end;
}
.king-crown::after {
  content: "👑"; position: absolute; top: -10px; right: -6px; font-size: 20px;
  line-height: 1; filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.6));
}
.sqs { display: grid; grid-template-columns: repeat(8, 1fr); grid-template-rows: repeat(8, 1fr); }
.sq { position: relative; }
.sq.l { background: var(--sq-light); }
.sq.d { background: var(--sq-dark); }
.sq i {
  position: absolute; font-style: normal; font-weight: 700; font-size: 9px;
  opacity: 0.75; line-height: 1;
}
.sq.l i { color: var(--coord-l); }
.sq.d i { color: var(--coord-d); }
.sq .cf { bottom: 2px; right: 3px; }
.sq .cr { top: 2px; left: 3px; }
/* با چرخاندن تخته (سیاه)، ردیفِ حروف و ستونِ اعدادِ عوض می‌شود (نگاه کن به
   fileLabelRow/rankLabelCol در board.js — طوری حساب می‌شوند که حروف/عدد
   همیشه از گوشه‌ی خانه‌ی a1 شروع شوند)، ولی این دو قانونِ بالا لنگرِ ثابت
   داشتند، پس برچسب‌ها به‌جای چسبیدن به لبه‌ی بیرونیِ تخته، سمتِ داخل
   می‌افتادند (حرف روی ردیفِ بالا ولی لنگرش «پایین»، عدد روی ستونِ راست
   ولی لنگرش «چپ»). این‌جا با چرخشِ ۱۸۰ درجه‌ی خودِ لنگر درست می‌شود. */
.board.flipped .sq .cf { bottom: auto; top: 2px; right: auto; left: 3px; }
.board.flipped .sq .cr { top: auto; bottom: 2px; left: auto; right: 3px; }

.marks, .hints { pointer-events: none; }
.mk, .hint, .pc { position: absolute; top: 0; left: 0; width: 12.5%; height: 12.5%; }

/* ستاره‌های تمرینِ حرکتِ مهره‌ها — زیرِ لایه‌ی مهره‌ها می‌نشینند (ترتیبِ
   لایه‌ها در _build در board.js) تا وقتی مهره روی ستاره می‌رود، خودِ مهره
   دیده شود نه ستاره. جمع‌شده حذف نمی‌شود، فقط کم‌رنگ و کوچک می‌ماند تا
   مسیرِ طی‌شده پیدا باشد. */
.stars { pointer-events: none; }
.star {
  position: absolute; top: 0; left: 0; width: 12.5%; height: 12.5%;
  display: grid; place-items: center;
}
.star svg {
  width: 62%; height: 62%; display: block;
  fill: var(--saffron, #e0a92e);
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.35));
  animation: star-pulse 1.8s ease-in-out infinite;
}
.star.done svg { fill: var(--muted); opacity: 0.32; width: 40%; height: 40%; animation: none; }
@keyframes star-pulse {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.12); }
}

.mk.last { background: var(--hl-last); }
.mk.sel { background: var(--hl-sel); }
.mk.hover { box-shadow: inset 0 0 0 3px rgba(255, 255, 255, 0.6); }
.mk.check {
  background: radial-gradient(circle, rgba(239, 68, 68, 0.95) 8%, rgba(239, 68, 68, 0.45) 40%, transparent 72%);
}
/* پیش‌حرکت رنگ جدا دارد تا با حرکت آخر و انتخاب قاطی نشود */
.mk.pre { background: rgba(140, 120, 220, 0.55); }
.hint.pre { background: radial-gradient(circle, rgba(140, 120, 220, 0.5) 0 15%, transparent 15.5%); }
/* نقطه و حلقه با گرادیان ساخته می‌شوند تا با اندازه‌ی تخته مقیاس بخورند.
   خانه‌ی تیره جوهر پررنگ‌تری لازم دارد، وگرنه نقطه گم می‌شود. */
.hint { background: radial-gradient(circle, var(--hint-ink) 0 17%, transparent 17.5%); }
.hint.on-d { --hint-ink: var(--hint-ink-d); }
.hint.cap { background: radial-gradient(circle, transparent 0 60%, var(--hint-ink) 60.5% 76%, transparent 76.5%); }

/* هایلایتِ خانه با کلیک راستِ ساده — مثلِ فلش، رنگِ سبزِ نیمه‌شفاف. */
.userhi { pointer-events: none; }
.mk.userhi { background: rgba(21, 161, 42, 0.55); }
.mk.userhi-red { background: rgba(239, 68, 68, 0.6); }

.pc {
  z-index: 2; cursor: grab;
  /* کِرو قبلی خیلی جلوبار بود (۲۵٪ زمان = ۷۵٪ مسافت)، یعنی مهره یهو
     می‌جهید و بعد آرام می‌خزید — با مدتِ طولانی‌تر این حس بدتر هم می‌شد.
     این کِرو (شبیهِ material standard easing) شتاب‌گیری و ترمزِ متعادل‌تری
     دارد، طبیعی‌تر می‌نشیند. */
  transition: transform 0.4s cubic-bezier(0.4, 0, 0.2, 1);
  /* عمداً `will-change: transform` اینجا نیست. قبلاً بود و یعنی هر ۳۲ مهره
     یک لایه‌ی GPUِ دائمی می‌گرفتند. روی گوشی، کروم گاهی لایه‌ای را که هنوز
     رستر نکرده به‌شکلِ یک مستطیلِ تخت می‌کشد — همان مربعِ تیره‌ای که موقعِ
     حرکت/ساخته‌شدنِ مهره‌ها دیده می‌شد. کروم برای خودِ ترنزیشن به‌هرحال
     لایه می‌سازد؛ نگه‌داشتنِ دائمی‌اش فقط حافظه‌ی GPU می‌خورد. */
}
.pc svg { width: 100%; height: 100%; display: block; transition: transform 0.14s; }
.pc .body { stroke-width: 1.3; stroke-linejoin: round; stroke-linecap: round; }
.pc .ln { fill: none; stroke-linecap: round; }
.pc .dt { stroke: none; }
.pc.c-w .body { fill: var(--pw-fill); stroke: var(--pw-stroke); }
.pc.c-w .ln { stroke: var(--pw-detail); }
.pc.c-w .dt { fill: var(--pw-detail); }
.pc.c-b .body { fill: var(--pb-fill); stroke: var(--pb-stroke); }
/* بدون این، مهره‌ی سیاه روی خانه‌ی تیره سیلوئتش را از دست می‌دهد — خط دورش
   هم سیاه است. هاله بر حسب em است تا با اندازه‌ی خانه مقیاس بخورد. */
.pc.c-b svg { filter: drop-shadow(0 0 0.022em rgba(255, 255, 255, 0.55)); }
.pc.c-b .ln { stroke: var(--pb-detail); }
.pc.c-b .dt { fill: var(--pb-detail); }
.pc.dragging { z-index: 9; transition: none; cursor: grabbing; }
.pc.dragging svg { transform: scale(1.14); filter: drop-shadow(0 6px 8px rgba(18, 16, 14, 0.45)); }
/* مهره‌ی خورده‌شده اصلاً محو نمی‌شود: دست‌نخورده سرِ جایش می‌ماند تا مهره‌ی
   زننده برسد، و همان لحظه — از زیرِ مهره‌ای که رویش نشسته — حذف می‌شود.
   همان کاری که اپ‌های بومی می‌کنند و تمیزترین حالت است.
   چرا فید حذف شد: قبلاً `transition: opacity .2s` بود و کروم روی اندروید
   وسطِ آن فید، به‌جای خودِ مهره یک مستطیلِ تیره‌ی تخت روی خانه می‌کشید —
   آرتیفکتِ رستر شدنِ لایه‌ی GPU، چون opacity روی المانی انیمیت می‌شد که هم
   `will-change: transform` داشت هم یک SVG با `filter` داخلش. بدونِ انیمیشنِ
   opacity اصلاً لایه‌ی جدایی ساخته نمی‌شود و آرتیفکت موضوعیت ندارد.
   z-index هم پایین‌تر از `.pc` است تا مهره‌ی رسیده رویش بیفتد، نه زیرش. */
.pc.gone { z-index: 1; transition: none; pointer-events: none; }
.pc.appear { animation: pop 0.24s ease-out; }
@keyframes pop { from { opacity: 0; } to { opacity: 1; } }

/* ================================================================
   ۶. صفحه‌ی بازی
   ================================================================ */
.pl { display: flex; align-items: center; gap: var(--s3); padding: var(--s2) 2px; }
.ava {
  width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center;
  font-weight: 800; font-size: 15px; flex: 0 0 auto;
  background: var(--raised); color: var(--firuzeh); border: 1px solid var(--line);
}
.pl.bot .ava { color: var(--saffron); }
.ava svg { width: 78%; height: 78%; }
.ava img { width: 100%; height: 100%; object-fit: cover; border-radius: inherit; }
.ava .body { fill: currentColor; stroke: none; }
.ava .dt { fill: var(--panel); }
.pl .info { flex: 1; min-width: 0; }
.pl .nm {
  font-weight: 600; font-size: 14px; white-space: nowrap;
  /* اسمِ کاربر همیشه باید کنار آواتار بماند، در هر دو زبان. با
     unicode-bidi: plaintext (که در جاهای دیگر برای اسم/متنِ آزادِ کاربر
     به‌کار می‌رود) ترازِ متن بر اساسِ اولین حرفِ *خودِ اسم* تعیین می‌شود، نه
     جهتِ صفحه — یعنی یک اسمِ لاتین (مثلاً Arian) روی سایتِ فارسی، چپ‌چین
     می‌شد، ولی چون این .nm همیشه توی یک باکسِ عریضِ flex:1 است (نه یک
     span با عرضِ هم‌اندازه‌ی متن)، همان چپ‌چین شدن باعث می‌شد متن از
     آواتار (که در چیدمانِ راست‌به‌چپ سمتِ راست است) فاصله بگیرد و برود
     ته‌ِ چپِ باکس، کنارِ ساعت. isolate برخلافِ plaintext، جهتِ متن را
     برای شکل‌گیریِ حروف از خودِ محتوا می‌گیرد ولی ترازش را از جهتِ صفحه —
     یعنی همیشه سمتِ آواتار می‌ماند، چه اسم فارسی باشد چه لاتین. */
  overflow: hidden; text-overflow: ellipsis; unicode-bidi: isolate;
}
.pl .nm span { color: var(--muted); font-weight: 400; font-size: 12px; }
.taken {
  display: flex; align-items: center; height: 17px; margin-top: 1px; direction: ltr;
  max-width: 100%; overflow: hidden;
}
.taken .pc-mini {
  position: static; width: 16px; height: 16px; margin-inline-start: -5px;
  flex: 0 0 auto; opacity: 0.8;
}
.taken .pc-mini:first-child { margin-inline-start: 0; }
.taken .pc-mini svg { width: 100%; height: 100%; display: block; }
.taken .adv { font-size: 12px; font-weight: 700; color: var(--muted); margin-inline-start: 5px; }

.pl .report-btn {
  flex: 0 0 auto; width: 26px; height: 26px; border-radius: 8px; color: var(--muted);
  display: grid; place-items: center; opacity: 0.6; background: transparent; border: none;
}
.pl .report-btn svg { width: 14px; height: 14px; }
.pl .report-btn:active { opacity: 1; background: var(--raised); }

/* ساعت */
.clk {
  flex: 0 0 auto; display: flex; flex-direction: column; align-items: flex-end; gap: 3px;
  min-width: 62px; direction: ltr;
  font-family: var(--font-mono);
}
.clk .t {
  font-variant-numeric: tabular-nums; font-weight: 800; font-size: 17px; line-height: 1;
  color: var(--muted); letter-spacing: -0.3px;
}
.clk .bar { width: 100%; height: 3px; border-radius: var(--r-pill); background: var(--line); overflow: hidden; }
/* «فعال» = دقیقاً همان الگویِ timer-box.active در طرحِ جدید: رنگِ متن پررنگ
   می‌شود و یک حلقه‌ی نرمِ هم‌رنگِ لهجه دورِ کل ردیفِ بازیکن می‌نشیند. */
.pl.on { border-radius: var(--r-sm); box-shadow: 0 0 0 2px var(--accent-soft); }
.pl.on .clk .t { color: var(--text); }
.pl.on .clk .bar { background: var(--firuzeh); }
.pl.low .clk .t { color: var(--danger); }
.pl.low .clk .bar { background: var(--danger); }

/* نوار حرکت‌ها: فقط حرکت جاری؛ لمسِ متن، فهرست کامل را در یک شیت باز
   می‌کند. قبلاً این بخش سه ردیفِ کامل و نزدیک ۲۵۰ پیکسل بود. */
.move-strip {
  margin-top: var(--s2); direction: ltr; display: flex; align-items: center; gap: 2px;
  padding: 3px; border-radius: var(--r-sm); background: var(--panel); border: 1px solid var(--line);
  font-family: var(--font-mono);
}
.ms-label {
  flex: 1; min-width: 0; text-align: center; padding: 7px 4px; border-radius: 8px;
  font-size: 14px; font-weight: 700; font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.ms-label:active { background: var(--raised); }
/* ICON_CHEVRON/ICON_CHEVRON_BAR رو به چپ رسم شده‌اند (برای اولین/قبلی)؛
   بعدی/آخرین همان آیکون را آینه می‌کنند تا یک SVG کمتر لازم باشد. */
#revNext svg, #revLast svg { transform: scaleX(-1); }
#wMoveStrip { justify-content: center; }
#wMsLabel { flex: none; }

.toolbar {
  margin-top: var(--s2); display: flex; align-items: center;
  justify-content: space-between; gap: var(--s2);
}
#spectate .toolbar { justify-content: center; }

/* منوی باز شونده: به‌جای شیت مودال، همین‌جا زیر نوار ابزار باز می‌شود —
   چیزی که تازه گذاشته‌ای همان‌جا می‌ماند، نه اینکه پرده بیفتد رویش. */
.more-panel {
  margin-top: var(--s2); padding: var(--s3); border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line);
}
.more-panel > .row + .row,
.more-panel > button + .row,
.more-panel > .row + button,
.more-panel > button + button { margin-top: var(--s2); }

/* منوی همبرگریِ نوارِ ناوبری — برخلافِ .more-panel بالا (که در جریانِ
   عادیِ صفحه باز می‌شود)، این یکی باید روی نوارِ ثابت/سایدبارِ ثابت شناور
   شود، نه محتوا را جابه‌جا کند. .nav-menu-wrap مرجعِ position برای پنل
   است — روی هر دو حالتِ نوار (ردیفِ افقیِ گوشی، ستونِ عمودیِ دسکتاپ) پنل
   درست بالای دکمه می‌ایستد (نگاه کن به initNavMenu در app.js). */
.nav-menu-wrap { position: relative; }
.nav-menu-panel {
  position: absolute; z-index: 50; bottom: 100%; inset-inline-end: 0;
  margin-bottom: var(--s2); min-width: 190px; padding: var(--s2);
  border-radius: var(--r); background: var(--panel); border: 1px solid var(--line);
  box-shadow: var(--shadow-md);
}
.nav-menu-item {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: var(--s3); border-radius: var(--r-sm); font-size: 14px; font-weight: 600;
  color: var(--text); text-align: start;
}
.nav-menu-item .ic-wrap { width: 18px; height: 18px; display: flex; flex: 0 0 auto; color: var(--muted); }
.nav-menu-item .ic-wrap svg { width: 100%; height: 100%; display: block; }
.nav-menu-item:hover { background: var(--raised); }
#btnNavMenu.active { background: var(--raised); color: var(--text); }

/* نوار «حریف از بازی رفت» — عمداً بالای دکمه‌ها و زیر فهرست حرکت‌هاست تا
   وسط تخته را نگیرد ولی قابل چشم‌پوشی هم نباشد.

   اسمِ کلاس عمداً `gone-bar` است، نه `gone`. قبلاً `gone` بود و چون این رول
   هیچ محدودیتی نداشت، به *هر* المانی با آن کلاس می‌چسبید — از جمله مهره‌ی
   خورده‌شده (`.pc.gone` در board.js) و فلشِ Storm (`.storm-flash.gone`).
   نتیجه‌اش این بود که مهره‌ی خورده‌شده لحظه‌ای به یک کارتِ گردگوشه با
   پس‌زمینه‌ی --panel و لبه‌ی --saffron تبدیل می‌شد و padding/flex هم SVG‌اش
   را کوچک و وسط‌چین می‌کرد — همان «مربعی» که موقعِ زدنِ مهره پیدا می‌شد و
   رنگش با تم عوض می‌شد. */
.gone-bar {
  margin-top: var(--s3); padding: 11px var(--s3); border-radius: var(--r-sm); font-size: 14px;
  background: var(--panel); border: 1px solid var(--saffron);
  display: flex; align-items: center; gap: var(--s3);
}
.gone-bar .dot {
  width: 9px; height: 9px; border-radius: 50%; flex: 0 0 auto;
  background: var(--saffron); animation: gone-pulse 1.4s ease-in-out infinite;
}
.gone-bar .cd {
  margin-inline-start: auto; font-variant-numeric: tabular-nums;
  font-weight: 800; color: var(--saffron); direction: ltr;
}
@keyframes gone-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .25; } }

.banner {
  margin-top: var(--s3); padding: 11px var(--s3); border-radius: var(--r-sm); font-size: 14px;
  background: var(--panel); border: 1px solid var(--line);
}
.banner.good { border-color: var(--firuzeh); }
.banner.bad { border-color: var(--danger); }
.banner .link { direction: ltr; display: inline-block; color: var(--firuzeh); word-break: break-all; }
.invite-link-row {
  display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; direction: ltr;
}
.icon-btn.tiny { width: 26px; height: 26px; }
.icon-btn.tiny svg { width: 14px; height: 14px; }

/* نوار هشدار مرور — باید واضح باشد که تخته موقعیت زنده را نشان نمی‌دهد */
.reviewing { border-color: var(--saffron) !important; }
.review-bar {
  margin-top: var(--s2); padding: 9px var(--s3); border-radius: var(--r-sm);
  background: var(--accent-soft); border: 1px solid var(--saffron);
  font-size: 13px; display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
}
.review-bar button {
  padding: 5px var(--s3); border-radius: 8px; background: var(--saffron);
  color: var(--ink); font-weight: 700; font-size: 12px;
}
/* سربرگ صفحه‌ی مرور — جای نوار دقت که در حالت مرور هنوز محاسبه نشده */
.rp-head {
  display: flex; align-items: baseline; gap: var(--s2); padding: 10px var(--s3);
  background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r-sm); margin-bottom: var(--s3);
}
.rp-head .who { font-weight: 700; }
.rp-head .meta { color: var(--muted); font-size: 12px; margin-inline-start: auto; }

.promo { display: flex; gap: var(--s2); }
.promo button {
  flex: 1; aspect-ratio: 1; border-radius: var(--r-sm);
  background: var(--raised); border: 1px solid var(--line); padding: 6px;
}
.promo button:active { background: var(--firuzeh); }
.promo .pc { position: static; width: 100%; height: 100%; }

/* ================================================================
   ویرایشگرِ تخته
   ================================================================ */
/* پالت: همان الگویِ .promo button، فقط شبکه‌ای به‌جای یک ردیف چون ۱۳
   گزینه‌اند (۶ مهره‌ی سفید + ۶ سیاه + پاک‌کن)، نه ۴. */
.editor-palette {
  display: grid; grid-template-columns: repeat(6, 1fr); gap: var(--s1);
  margin: var(--s3) 0;
}
.editor-pc-btn {
  aspect-ratio: 1; border-radius: var(--r-sm); background: var(--raised);
  border: 1px solid var(--line); padding: 5px; touch-action: none;
}
.editor-pc-btn .pc { position: static; width: 100%; height: 100%; }
.editor-pc-btn[aria-pressed="true"] { background: var(--firuzeh); border-color: transparent; }
.editor-pc-btn.editor-eraser {
  grid-column: 1 / span 6; display: flex; align-items: center; justify-content: center;
  aspect-ratio: auto; padding: 9px 0;
}
.editor-pc-btn.editor-eraser svg { width: 20px; height: 20px; color: var(--muted); }
.editor-pc-btn.editor-eraser[aria-pressed="true"] svg { color: var(--on-accent); }

.editor-toolbar { margin: var(--s3) 0; }

.editor-castle-row {
  display: flex; flex-wrap: wrap; gap: var(--s3); margin: var(--s3) 0;
  font-size: 13px; color: var(--muted);
}
.editor-castle-row label { display: flex; align-items: center; gap: 6px; }
.editor-castle-row input:disabled + span { opacity: 0.4; }

/* مهره‌ی شناور حینِ درگ — از پالت یا از خودِ تخته، با pointerهایِ سراسری
   دنبالِ نشانگر/انگشت می‌آید تا رهاشدن (نگاه کن به editorStartDrag در
   app.js). دو کلاس عمداً با هم — .pc برایِ رنگ/شکلِ SVG، این یکی فقط
   برایِ موقعیت‌دهیِ ثابت روی صفحه؛ دو کلاس هم مشخصیتش را از .pcِ تنها
   بالاتر می‌برد تا مطمئن باشیم بدونِ وابستگی به ترتیبِ فایل برنده می‌شود. */
.editor-drag-ghost.pc { position: fixed; z-index: 999; pointer-events: none; }

/* ================================================================
   ۷. پازل، تخته‌ی آزاد، درس، آموزشِ مهره‌ها، مختصات
   ================================================================ */

/* ------------------------------------------- کارت‌های تصویریِ حالت‌های پازل
   هر کارت یک عکسِ واقعی دارد که تمامِ کارت را پر می‌کند: عکس با
   width:100%;height:auto در جریانِ عادی می‌نشیند، پس اندازه‌ی کارت دقیقاً
   اندازه‌ی خودِ عکس است — نه کراپ می‌شود، نه فضای خالی می‌ماند. نوشته‌ها
   (تیتر/زیرتیتر/دکمه) با position:absolute روی پایینِ همان عکس می‌نشینند؛
   به‌جای یک لایه‌ی تیره‌ی پشتِ نوشته فقط از سایه‌ی متنی برای خوانایی استفاده
   شده — بنا به خواسته‌ی صریح، عکس تیره نمی‌شود. */
/* ---------------------------------------------- داشبوردِ پازل
   کارتِ آمارِ بالای صفحه‌ی پازل — سه‌کاشیِ عملکرد/بازی‌شده/حل‌شده با همان
   .pf-mini-row/.pf-mini پروفایل (بدونِ تعریفِ دوباره)، رادارِ SVG
   دست‌ساز (radarChart در app.js)، و ردیفِ «X تا برای مرور» با همان
   .nav-row معمول، فقط با یک خطِ جداکننده‌ی بالا چون تنها ردیفِ داخلِ
   کارت است (نه داخلِ .nav-list). */
/* ---------------------------------------------- داشبوردِ پازل
   پیش‌فرض بسته: فقط ردیفِ عنوان+خلاصه (.puzzle-dash-toggle، با همان
   chev/aria-expanded ِ .more-toggle، فقط چیده‌شده کنارِهم به‌جایِ
   وسط‌چین). بدنه‌ی باز‌شونده (.more-panel معمول) سه‌کاشیِ عملکرد/
   بازی‌شده/حل‌شده را با همان .pf-mini-row/.pf-mini پروفایل نشان می‌دهد
   (بدونِ تعریفِ دوباره)، رادارِ SVG دست‌ساز (radarChart در app.js)، و
   ردیفِ «X تا برای مرور» با همان .nav-row معمول، با یک خطِ جداکننده‌ی
   بالا چون تنها ردیفِ داخلِ این پنل است (نه داخلِ .nav-list). */
.puzzle-dash-card { padding-bottom: var(--s2); }
.puzzle-dash-card .more-toggle.puzzle-dash-toggle {
  justify-content: flex-start; align-items: center; width: 100%; margin-bottom: 0;
  background: none; border: none; padding: 0; text-align: start;
}
.puzzle-dash-toggle-title { flex: 0 0 auto; font-weight: 700; font-size: 14.5px; color: var(--text); }
.puzzle-dash-brief {
  flex: 1; min-width: 0; text-align: start; font-size: 12.5px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pd-radar { margin: var(--s3) auto 0; max-width: 300px; }
.pd-radar svg { display: block; width: 100%; height: auto; }
.puzzle-dash-replay {
  margin-top: var(--s3); padding-top: var(--s3);
  border-top: 1px solid var(--line); border-bottom: 0 !important;
}

.puzzle-banner { display: block; width: 100%; height: auto; border-radius: var(--r-lg); margin-bottom: var(--s4); }
.mode-hero, .mode-card { overflow: hidden; display: flex; flex-direction: column; text-align: start; width: 100%; }
/* حاشیه‌ی نازکِ کِرِم دورِ کارت‌ها از border و inset-shadowِ خودِ .card
   می‌آمد (نه از کراپِ عکس) — اینجا برای کارت‌های عکسی هر دو خاموش می‌شوند
   تا عکس درست تا لبه‌ی گردِ کارت برسد. */
.card.photo-card { padding: 0; border: none; box-shadow: none; }
.photo-card { position: relative; }
.photo-card-img { display: block; width: 100%; height: auto; }
.photo-card-body { position: absolute; inset-inline: 0; inset-block-end: 0; padding: var(--s3) var(--s4) var(--s4); }

/* شبکه‌ی دوستونه: با stretch پیش‌فرضِ گرید، هر ردیف به‌اندازه‌ی بلندترین
   عکسِ همان ردیف کشیده می‌شد و زیرِ عکسِ کوتاه‌تر یک نوارِ نازک از
   پس‌زمینه‌ی کِرِمِ کارت دیده می‌شد — همان «حاشیه‌ی سفید» که کراپ به‌نظر
   می‌رسید. با start هر کارت دقیقاً هم‌اندازه‌ی عکسِ خودش می‌ماند. */
.mode-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3); align-items: start; }
.mode-card-title { font-weight: 700; font-size: 14px; margin: 0 0 2px; }
.mode-card-sub { font-size: 12px; line-height: 1.5; margin: 0 0 var(--s2); }
.mode-card-stat { font-size: 11.5px; font-weight: 700; margin: -2px 0 var(--s2); }
.mode-card .btn { margin-top: auto; align-self: flex-start; }

.photo-card-body h2, .photo-card-body h3,
.photo-card-body .hint-text, .photo-card-body .mode-card-title,
.photo-card-body .mode-card-sub, .photo-card-body .mode-card-stat,
.photo-card-body .streak .n, .photo-card-body .streak .lbl,
.photo-card-body .tag {
  color: #fffdf9;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}
.photo-card-body .mode-card-sub { color: #eae6d8; }
.photo-card-body .btn { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); }

/* تیترِ هیرویِ پازلِ روزانه: به‌جای نشستن توی بلوکِ پایین، مثلِ یک چیپِ
   کوچیک روی گوشه‌ی خالیِ خودِ عکس می‌نشیند. عمداً از left/right فیزیکی
   استفاده شده نه inset-inline-*: گوشه‌ی خالیِ عکس یک نقطه‌ی ثابت روی خودِ
   تصویر است، ربطی به جهتِ فارسی/انگلیسیِ صفحه ندارد — با منطقی‌ها، عوضِ
   زبان جای چیپ را هم (غلط) عوض می‌کرد. فقط داخلِ photo-card اسکوپ شده،
   card-head جای دیگر دست‌نخورده می‌ماند. */
.photo-card > .card-head.pos-tl,
.photo-card > .card-head.pos-tr {
  position: absolute; top: 0; margin: 0;
  padding: var(--s3) var(--s4) 0; gap: var(--s2);
}
.photo-card > .card-head.pos-tl { left: 0; }
.photo-card > .card-head.pos-tr { right: 0; }
.photo-card > .card-head.pos-tl h2, .photo-card > .card-head.pos-tl .tag,
.photo-card > .card-head.pos-tr h2, .photo-card > .card-head.pos-tr .tag {
  color: #fffdf9;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}

/* بلوکِ محتوای Battle: چون تقریباً تمامِ پایینِ این عکس را مهره‌ها گرفته‌اند
   (نه فقط یک گوشه)، بلوک را کلاً برد بالا — نوارِ بالای عکس، جایی که فقط
   قوسِ خالیِ پس‌زمینه‌ست. */
.photo-card-body.pos-top { inset-block-start: 0; inset-block-end: auto; padding: var(--s3) var(--s4) 0; }

/* تیترِ کارت‌های کوچیک: یک چیپِ ثابت روی گوشه‌ی خالیِ همان عکس (هر کارت
   طبقِ خودِ عکسش — بعضی بالا-چپ، بعضی بالا-راست)، مستقل از زبان/جهتِ
   صفحه (همان دلیلِ بالا: left/right فیزیکی). در هر دو حالتِ جمع‌وباز سرِ
   جایش می‌ماند. */
.card-title-chip {
  position: absolute; top: 0; margin: 0;
  padding: var(--s2) var(--s3);
  color: #fffdf9;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}
.card-title-chip.pos-tl { left: 0; }
.card-title-chip.pos-tr { right: 0; }

/* بازوبسته‌شدنِ کارت: پیش‌فرض فقط تیتر دیده می‌شود؛ با لمسِ کارت (نه
   دکمه) card-more (توضیح+دکمه) روی پایینِ عکس ظاهر می‌شود و خودِ کارت
   یک‌کم روی بقیه بزرگ می‌شود — نگاه کن به wireExpandableModeCards در
   app.js. */
.expandable { transition: transform 0.22s ease, box-shadow 0.22s ease; }
.expandable.is-expanded { transform: scale(1.045); z-index: 3; box-shadow: var(--shadow-md); }
.card-more {
  position: absolute; inset-inline: 0; inset-block-end: 0;
  padding: var(--s3) var(--s4) var(--s4);
  opacity: 0; transform: translateY(6px); pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.is-expanded .card-more { opacity: 1; transform: translateY(0); pointer-events: auto; }
.card-more .mode-card-sub, .card-more .mode-card-stat {
  color: #eae6d8;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55), 0 3px 14px rgba(0, 0, 0, 0.4);
}
.card-more .mode-card-stat { color: #fffdf9; }
.card-more .btn { box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3); }
@media (prefers-reduced-motion: reduce) {
  .expandable, .expandable.is-expanded, .card-more { transition: none; }
  .star svg { animation: none; }
}

/* کارتِ عریضِ Battle — دیگر ردیفی نیست؛ مثلِ بقیه یک عکسِ تمام‌عرض با
   نوشته‌های رویش، فقط در شبکه دو ستون را با هم می‌گیرد. */
.mode-card.wide { grid-column: 1 / -1; }

.puzzle-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s2) 2px var(--s3); font-size: 14px; color: var(--muted);
}
.puzzle-head b { color: var(--text); font-variant-numeric: tabular-nums; }

/* زنجیره‌ی حل‌های پشت‌سرِ هم */
.streak { display: flex; align-items: center; gap: 6px; }
.streak .n {
  font-weight: 800; font-size: 17px; font-variant-numeric: tabular-nums;
  color: var(--text); transition: color 0.3s;
}
.streak .lbl { font-size: 12px; color: var(--muted); }
/* سه پله: عادی، طلایی، داغ */
.streak.warm .n { color: var(--saffron); }
.streak.hot .n { color: #ff6a3d; }
.streak .flame { width: 0; opacity: 0; transition: width 0.3s, opacity 0.3s; }
.streak.hot .flame { width: 15px; opacity: 1; }
.streak .flame svg { width: 100%; height: 21px; display: block; }
.streak .f-out { fill: #ff6a3d; }
.streak .f-in { fill: #ffd24a; }
.streak.hot .flame svg { animation: flicker 1.1s ease-in-out infinite; transform-origin: 50% 90%; }
@keyframes flicker {
  0%, 100% { transform: scale(1) rotate(0deg); }
  30%      { transform: scale(1.1, 0.95) rotate(-3deg); }
  60%      { transform: scale(0.95, 1.08) rotate(2deg); }
}
/* پرش کوتاه موقع بالا رفتن عدد */
.streak.pop .n { animation: streakpop 0.45s cubic-bezier(0.2, 1.6, 0.4, 1); }
@keyframes streakpop {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.55); }
  100% { transform: scale(1); }
}
.daily-status-row { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }

/* ------------------------------------------------------ Puzzle Rush */
.rush-head { gap: var(--s3); }
.rush-timer, .storm-timer {
  font-weight: 800; font-size: 20px; font-variant-numeric: tabular-nums;
  color: var(--text); transition: color 0.2s;
}
.rush-timer.low { color: var(--danger); }
.rush-score, .storm-score { display: flex; align-items: center; gap: 4px; font-weight: 800; font-size: 17px; color: var(--saffron); }
.rush-score .ic, .storm-score .ic { width: 18px; height: 18px; display: flex; }
.rush-score .ic svg { width: 100%; height: 100%; }
.rush-score.pop { animation: streakpop 0.45s cubic-bezier(0.2, 1.6, 0.4, 1); }
.rush-lives { display: flex; gap: 4px; }
.rush-lives .life {
  width: 12px; height: 12px; border-radius: 50%; background: var(--danger);
  transition: transform 0.25s, opacity 0.25s;
}
.rush-lives .life.lost { background: var(--line); opacity: 0.5; transform: scale(0.7); }

/* رنگِ مهره‌ی خودِ کاربر — ثابت و همیشه‌دیدنی، نه فقط یک پیامِ گذرا،
   چون هر پازلِ تازه‌ی Rush می‌تواند رنگِ کاربر را عوض کند. */
.rush-color {
  display: flex; align-items: center; gap: 6px; justify-content: center;
  padding: 2px 0 var(--s2); font-size: 13px; color: var(--muted); font-weight: 600;
}
.rush-color .dot {
  width: 13px; height: 13px; border-radius: 50%; border: 1.5px solid var(--line);
  background: #fff;
}
.rush-color .dot.black { background: #1d1e20; }

/* ------------------------------------------------------ Puzzle Storm */
.storm-head { gap: var(--s3); }
.storm-score .ic svg { width: 100%; height: 100%; }
.storm-score.pop { animation: streakpop 0.45s cubic-bezier(0.2, 1.6, 0.4, 1); }
.storm-combo { display: flex; align-items: center; gap: 4px; font-size: 13px; color: var(--muted); }
.storm-combo .n { font-weight: 800; font-size: 15px; color: var(--text); font-variant-numeric: tabular-nums; }

/* پیامِ گذرا و بزرگِ «+۷» یا «−۱۰» بالای تخته — چند صدم‌ثانیه دیده
   می‌شود و محو می‌شود، جدا از banner معمولی چون باید فوری و چشمگیر باشد. */
.storm-flash {
  text-align: center; font-weight: 800; font-size: 22px; font-variant-numeric: tabular-nums;
  padding: 2px 0; transition: opacity 0.4s;
}
.storm-flash.good { color: var(--good); }
.storm-flash.bad { color: var(--danger); }
.storm-flash.gone { opacity: 0; }

.rush-result {
  text-align: center; padding: var(--s4) var(--s3); margin-top: var(--s3);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
}
.rush-result h2 { margin: 0 0 4px; font-size: 22px; }
.rush-result .record { color: var(--saffron); font-weight: 700; }
.cheer { animation: cheerin 0.35s ease-out; }
@keyframes cheerin { from { opacity: 0; transform: translateY(6px); } }

/* ------------------------------------------------------ مرورِ تم‌های پازل */
.theme-group-title {
  margin: var(--s4) 0 var(--s2); font-size: 13px; font-weight: 700;
  color: var(--muted); letter-spacing: 0.02em;
}
.theme-group-title:first-child { margin-top: 0; }
.theme-grid {
  display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s3);
}
.theme-tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
  padding: var(--s3); text-align: right; cursor: pointer; font-family: inherit;
  transition: border-color 0.15s;
}
.theme-tile:active { border-color: var(--firuzeh); }
.theme-tile .theme-name { font-weight: 700; font-size: 14px; }
.theme-bar {
  width: 100%; height: 6px; border-radius: 3px; background: var(--line); overflow: hidden;
}
.theme-bar-fill { height: 100%; background: var(--firuzeh); border-radius: 3px; }
.theme-mastery-n { font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* ------------------------------------------------------ Puzzle Battle */
.battle-vs-bar {
  display: flex; align-items: center; justify-content: center; gap: var(--s4);
  padding: var(--s2) 0 var(--s3);
}
.battle-side { display: flex; flex-direction: column; align-items: center; gap: 2px; min-width: 64px; }
.battle-side .n { font-weight: 800; font-size: 24px; font-variant-numeric: tabular-nums; color: var(--text); }
.battle-side.opp .n { color: var(--muted); }
.battle-side .mistakes { min-height: 14px; color: var(--danger); font-size: 12px; letter-spacing: 2px; }
.battle-vs-bar .vs { font-weight: 700; font-size: 12px; color: var(--muted); }
#battleResult {
  text-align: center; padding: var(--s4) var(--s3); margin-top: var(--s3);
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r);
}
#battleResult h2 { margin: 0 0 4px; font-size: 22px; }
#battleResult .btn { margin-top: var(--s2); width: 100%; }
#battleLobby .card h3 { margin: 0 0 4px; font-size: 15px; font-weight: 700; }
#battleQueueStatus { text-align: center; }

/* فهرستِ حرکت‌های تخته‌ی آزاد */
.moves {
  margin-top: var(--s3); padding: 9px var(--s3); border-radius: var(--r-sm); background: var(--panel);
  border: 1px solid var(--line); max-height: 96px; overflow-y: auto;
  font-size: 13px; color: var(--muted); direction: ltr; text-align: left;
  font-variant-numeric: tabular-nums; word-spacing: 3px;
}
.moves b { color: var(--text); font-weight: 600; }

/* ---------------------------------------------------------- درس
   از خاصیت‌های منطقی (inline-start/end) استفاده می‌شود نه left/right،
   چون همین صفحه هم در فارسی راست‌به‌چپ است هم در انگلیسی چپ‌به‌راست. */
.lesson-head {
  padding: var(--s3) var(--s4); background: var(--panel); border: 1px solid var(--line);
  border-radius: var(--r); margin-bottom: var(--s3);
}
.lesson-head h2 { margin: 0 0 var(--s1); font-size: 17px; }
.lesson-head .sum { color: var(--muted); font-size: 13px; line-height: 1.6; }
.lesson-head .bar {
  height: 4px; border-radius: 2px; background: var(--line);
  margin-top: var(--s3); overflow: hidden;
}
.lesson-head .bar i { display: block; height: 100%; background: var(--firuzeh); transition: width .25s ease; }

/* اندازه‌ی این ناحیه (نه هرکدام از سه بچه‌اش جدا) ثابت است — وگرنه رشد یا
   پنهان/آشکار شدنِ هرکدام، دکمه‌های زیرِ کل ناحیه را جابه‌جا می‌کرد. برای
   محتوای بلندتر از جا، خودِ همین ناحیه اسکرول می‌شود. */
.lesson-dynamic { height: 190px; overflow-y: auto; }

/* تخته‌ی مربی: خط‌ها روی هم جمع می‌شوند و تا حرکت بعدیِ کاربر می‌مانند.
   قبلاً هر پیام پیام قبلی را پاک می‌کرد و توضیحِ حرکت، پیش از خوانده شدن،
   زیر جوابِ حریف و «نوبت توست» دفن می‌شد. */
.coach {
  margin-top: var(--s3); border-radius: var(--r); background: var(--panel);
  border: 1px solid var(--line); font-size: 14px; line-height: 1.75;
}
.coach.empty { display: none; }
.coach .line { padding: 11px var(--s4); border-inline-start: 3px solid var(--line); }
.coach .line + .line { border-top: 1px solid var(--line); }
.coach .line.bad { border-inline-start-color: var(--c-blunder); }
.coach .line.good { border-inline-start-color: var(--firuzeh); }
.coach .mv { font-weight: 800; direction: ltr; display: inline-block; }

.turn-hint { margin-top: var(--s2); font-size: 14px; color: var(--muted); }

.why-box {
  margin-top: var(--s3); padding: var(--s3) var(--s4); border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line);
}
.why-box .q { font-weight: 700; margin-bottom: var(--s2); }
.why-box button { display: block; width: 100%; margin-top: 6px; text-align: start; }

/* -------------------------------------------------- فهرستِ درس‌ها، گروه‌بندی‌شده
   هر دسته (کیش‌مات/تاکتیک/آخربازی/افتتاحیه) رنگِ خودش را دارد — از
   --cat و --cat-soft که روی خودِ .lesson-group به‌صورت inline ست می‌شوند
   (نگاه کن به loadLessons در app.js) و به همه‌ی فرزندان ارث می‌رسد. */
.lesson-group { margin-bottom: var(--s5); }
.lesson-group:last-child { margin-bottom: 0; }

.lesson-group-head { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s3); }
.lesson-group-ic {
  width: 36px; height: 36px; border-radius: 11px; flex: 0 0 auto;
  display: grid; place-items: center;
  background: var(--cat-soft); color: var(--cat);
}
.lesson-group-ic svg { width: 19px; height: 19px; }
.lesson-group-name { font-weight: 800; font-size: 15px; }
.lesson-group-count {
  margin-inline-start: auto; font-size: 11.5px; font-weight: 600; color: var(--muted);
  background: var(--raised); padding: 3px 10px; border-radius: 999px;
}

.lesson-cards { display: flex; flex-direction: column; gap: var(--s2); }
.lesson-card {
  display: flex; align-items: center; gap: var(--s3); width: 100%;
  padding: var(--s3); border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line);
  border-inline-start: 3px solid var(--cat);
  text-align: start; cursor: pointer;
  transition: transform .12s ease, box-shadow .12s ease;
}
.lesson-card:hover { box-shadow: var(--shadow-md); }
.lesson-card:active { transform: scale(.98); }
.lesson-card-ic {
  width: 32px; height: 32px; border-radius: 10px; flex: 0 0 auto;
  display: grid; place-items: center; background: var(--cat-soft); color: var(--cat);
}
.lesson-card-ic svg { width: 17px; height: 17px; }
.lesson-card-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.lesson-card-title { font-weight: 700; font-size: 14.5px; }
.lesson-card-meta { display: flex; align-items: center; gap: 7px; font-size: 11.5px; color: var(--muted); flex-wrap: wrap; }
.lesson-level-pill { padding: 2px 8px; border-radius: 999px; background: var(--raised); font-weight: 700; }
.lesson-level-pill.beginner { color: var(--good); }
.lesson-level-pill.intermediate { color: var(--saffron); }
.lesson-level-pill.advanced { color: var(--danger); }

/* سرفصل‌های «به‌زودی»: همان کارت، ولی خاموش و بدون کلیک — تا کاربر نقشه‌ی
   راهِ کامل را ببیند، نه فقط چیزی که همین امروز ساخته شده. */
.lesson-card-planned { cursor: default; opacity: .55; border-inline-start-style: dashed; }
.lesson-card-planned:hover { box-shadow: none; }
.lesson-soon-pill {
  padding: 2px 8px; border-radius: 999px; background: var(--raised); font-weight: 700;
  color: var(--muted);
}

/* -------------------------------------------------- کاوشگر افتتاحیه */
.opening-book-moves { display: flex; flex-wrap: wrap; gap: var(--s2); margin-top: var(--s2); }
.ob-move {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: var(--s2) var(--s4); min-width: 64px;
  border-radius: var(--r-sm); background: var(--raised); border: 1px solid var(--line);
}
.ob-move .mv { font-weight: 700; }
.ob-move .meta { font-size: 11px; color: var(--muted); }

/* ------------------------------------------ آموزشِ حرکتِ مهره‌ها */
/* نوارِ کوچکِ پیش‌نمایش — یک ردیف آیکونِ مهره، هرکدام وضعیتِ خودش را نشان می‌دهد */
.tut-chapters { display: flex; gap: var(--s2); margin: var(--s2) 0 var(--s3); }
.tut-chip {
  flex: 1; aspect-ratio: 1; border-radius: var(--r-sm); display: grid; place-items: center;
  background: var(--raised); border: 1px solid var(--line); position: relative;
}
.tut-chip svg { width: 60%; height: 60%; opacity: 0.9; }
.tut-chip.locked { opacity: 0.35; }
.tut-chip.done { background: var(--firuzeh); border-color: transparent; }
.tut-chip.done svg { opacity: 1; }
.tut-chip .badge {
  position: absolute; inset-inline-end: -3px; top: -3px; width: 16px; height: 16px;
  border-radius: 50%; background: var(--saffron); display: grid; place-items: center;
}
.tut-chip .badge svg { width: 70%; height: 70%; opacity: 1; }

.tut-chapter-row {
  display: flex; align-items: center; gap: var(--s3); padding: 11px var(--s3);
  border-radius: var(--r-sm); background: var(--raised); margin-bottom: var(--s2);
}
.tut-chapter-row:last-child { margin-bottom: 0; }
.tut-chapter-row .ic {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: var(--r-sm);
  background: var(--panel); display: grid; place-items: center;
}
.tut-chapter-row .ic svg { width: 65%; height: 65%; }
.tut-chapter-row .info { flex: 1; min-width: 0; }
.tut-chapter-row .nm { font-weight: 700; }
.tut-chapter-row .meta { font-size: 12px; color: var(--muted); }
.tut-chapter-row.locked { opacity: 0.45; }
.tut-chapter-row .status { flex: 0 0 auto; color: var(--muted); }
.tut-chapter-row .status svg { width: 18px; height: 18px; }
.tut-chapter-row.done .status { color: var(--firuzeh); }

.tut-play-head {
  display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--s1);
}
.tut-play-head h2 { font-size: 17px; margin: 0; }
.tut-play-head span { font-size: 13px; color: var(--muted); }
/* همان تصمیمِ ارتفاعِ‌ثابتِ درس — توضیح یا بازخورد نباید دکمه‌ی زیرش را جابه‌جا کند. */
.tut-coach {
  margin-top: var(--s3); padding: var(--s4); border-radius: var(--r);
  background: var(--panel); border: 1px solid var(--line);
  font-size: 14px; line-height: 1.8; height: 92px; overflow-y: auto;
}
.tut-coach .feedback { margin-top: var(--s2); font-weight: 700; }
.tut-coach .feedback.bad { color: var(--c-blunder); }
.tut-coach .feedback.good { color: var(--firuzeh); }

/* شمارشگرِ تمرینِ ستاره‌ای — ستاره‌های جمع‌شده و تعدادِ حرکت، زیرِ متنِ
   مربی. تعدادِ حرکت عمداً سقف ندارد: هدفِ این تمرین یاد گرفتنِ خودِ حرکت
   است، نه بهینه‌بازی. */
.tut-stars {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  margin-top: var(--s3); padding-top: var(--s2); border-top: 1px solid var(--line);
  font-size: 13px;
}
.tut-stars-count { font-weight: 700; color: var(--saffron); }
.tut-stars-moves { color: var(--muted); font-variant-numeric: tabular-nums; }

/* ---------------------------------------------------- تمرینِ مختصات
   تخته‌ی خودش را دارد (نه S.board مشترک) چون هیچ منطقِ حرکتِ مهره‌ای لازم
   ندارد — فقط ۶۴ خانه‌ی کلیک‌پذیر. کلاسِ .board همان است که board.js هم
   استفاده می‌کند، پس رنگ و محدودیتِ اندازه رایگان به ارث می‌رسد. */
.coord-field { margin: var(--s3) 0; }
.coord-field > span { display: block; font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.coord-field .seg { margin: 0; }
.coord-legend {
  margin: var(--s3) 0; padding: 10px var(--s3); border-radius: var(--r-sm);
  background: var(--raised); border: 1px solid var(--line);
}
.coord-legend b { display: block; font-size: 13px; margin-bottom: 4px; color: var(--text); }
.coord-legend p { margin: 0; font-size: 12.5px; line-height: 1.7; color: var(--muted); }

.coord-hud { display: flex; align-items: center; justify-content: space-between; margin-bottom: var(--s3); }
.coord-timer {
  font-size: 22px; font-weight: 800; font-variant-numeric: tabular-nums;
  color: var(--text); direction: ltr;
}
.coord-timer.low { color: var(--danger); }
.coord-score-badge {
  padding: 6px var(--s3); border-radius: var(--r-sm); background: var(--panel);
  border: 1px solid var(--line); color: var(--muted); font-size: 13px;
}
.coord-score-badge b { color: var(--firuzeh); font-size: 15px; font-variant-numeric: tabular-nums; margin-inline-end: 3px; }

/* اسمِ خانه («e4») همیشه لاتین و چپ‌به‌راست می‌ماند — دقیقاً مثلِ SAN در
   فهرستِ حرکت‌ها، چون یک نمادِ بین‌المللی است نه متن. */
.coord-prompt {
  text-align: center; margin: var(--s1) 0 var(--s3); font-weight: 800;
  font-size: 40px; letter-spacing: 0.02em; direction: ltr; color: var(--text);
}
.coord-prompt.name-mode { font-size: 15px; font-weight: 600; direction: rtl; color: var(--muted); }

.coord-board .sq { cursor: pointer; }
.coord-board .sq.hl-target { box-shadow: inset 0 0 0 4px var(--saffron); }
.coord-board .sq.flash-good { background: var(--good) !important; }
.coord-board .sq.flash-bad { background: var(--danger) !important; }
/* مهره‌ها فقط تزئینی‌اند (چیدمانِ ثابت، بدونِ حرکت) — pointer-events خاموش
   تا کلیک/لمس، حتی درست روی یک مهره، همیشه به خانه‌ی زیرش برسد. */
.coord-board .pcs, .coord-board .pc { pointer-events: none; }

.coord-keypad { margin-top: var(--s3); }
/* حرف/رقم همیشه چپ‌به‌راست می‌ماند (a→h و 1→8) — این هم نمادِ بین‌المللیِ
   شطرنج است نه متنِ فارسی؛ وگرنه در صفحه‌ی راست‌به‌چپ برعکس می‌نشستند. */
.coord-keyrow { display: flex; gap: var(--s1); margin-bottom: var(--s1); direction: ltr; }
.coord-keyrow:last-child { margin-bottom: 0; }
.key-btn {
  flex: 1; padding: 11px 0; border-radius: 8px; background: var(--raised);
  border: 1px solid var(--line); color: var(--text); font-weight: 700; font-size: 15px;
}
.key-btn.sel { background: var(--firuzeh); color: var(--on-accent); border-color: transparent; }
.coord-final-score {
  text-align: center; font-size: 48px; font-weight: 800; color: var(--firuzeh);
  margin: 6px 0 2px; font-variant-numeric: tabular-nums;
}
.coord-new-best { text-align: center; color: var(--saffron); font-weight: 700; margin-top: var(--s1); }

/* ================================================================
   ۸. تحلیل بازی
   ================================================================ */
.opening {
  display: flex; align-items: center; gap: var(--s2); padding: 9px var(--s3);
  margin-bottom: var(--s3); border-radius: var(--r-sm); background: var(--panel);
  border: 1px solid var(--line); font-size: 13px;
}
.opening .eco {
  flex: 0 0 auto; font-size: 11px; font-weight: 800; padding: 2px 7px;
  border-radius: 6px; background: var(--raised); color: var(--saffron);
  direction: ltr; font-variant-numeric: tabular-nums;
}
.opening .nm {
  min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; unicode-bidi: plaintext;
}

.pbar { height: 6px; border-radius: 99px; background: var(--raised); overflow: hidden; }
.pbar i { display: block; height: 100%; width: 0; background: var(--firuzeh); transition: width 0.2s; }
.tut-progress { margin: var(--s2) 0 var(--s3); }
.tut-progress-label { font-size: 13px; color: var(--text); margin-bottom: 6px; }

.acc-row { display: flex; align-items: center; gap: var(--s3); margin-bottom: var(--s2); }
.acc {
  flex: 1; text-align: center; padding: 6px; border-radius: var(--r-sm);
  background: var(--panel); border: 1px solid var(--line);
}
.acc b { display: block; font-size: 16px; font-variant-numeric: tabular-nums; }
.acc span { font-size: 11px; color: var(--muted); }
.acc-mid { font-size: 12px; color: var(--muted); direction: ltr; }

.graph {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden; margin-bottom: var(--s2); direction: ltr;
}
.graph svg { display: block; width: 100%; height: 52px; }
.graph .area { fill: var(--text); }
.graph .mid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 3 3; }
.graph .cursor { stroke: var(--saffron); stroke-width: 1.5; }
.graph .mk { r: 3; }

/* اندازه‌ی ثابت — وگرنه با هر حرکت که طولِ توضیح عوض می‌شود، دکمه‌های
   زیرش (و کل ادامه‌ی صفحه) بالا/پایین می‌پرند. */
.an-move {
  margin-top: var(--s3); padding: 11px var(--s3); border-radius: var(--r-sm);
  background: var(--panel); border: 1px solid var(--line); font-size: 14px;
  height: 92px; overflow-y: auto;
}
.an-move .head { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s1); }
.an-move .mv { font-weight: 700; direction: ltr; }
.an-move .tag {
  font-size: 12px; padding: 2px 9px 2px 7px; border-radius: 99px; font-weight: 700;
  color: #1c1a17; display: inline-flex; align-items: center; gap: 4px;
}
.an-move .tag-ic { width: 13px; height: 13px; flex: 0 0 auto; display: inline-flex; }
.an-move .tag-ic svg { width: 100%; height: 100%; display: block; }
.an-move .why { color: var(--muted); font-size: 13px; line-height: 1.8; }
.an-move .alt { color: var(--saffron); direction: ltr; display: inline-block; font-weight: 700; }

.movelist {
  margin-top: var(--s3); padding: var(--s2); border-radius: var(--r-sm); background: var(--panel);
  border: 1px solid var(--line); max-height: 150px; overflow-y: auto;
  display: grid; grid-template-columns: 34px 1fr 1fr; gap: 2px 4px;
  direction: ltr; font-size: 13px;
}
.movelist .no { color: var(--muted); text-align: end; padding: 4px 2px; font-variant-numeric: tabular-nums; }
.movelist .m {
  padding: 4px 6px; border-radius: 6px; cursor: pointer;
  display: flex; align-items: center; gap: 5px;
}
.movelist .m.on { background: var(--raised); }
.movelist .m .dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; }

.summary { margin-top: var(--s3); display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; }
.summary div {
  background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s2) var(--s1); text-align: center; font-size: 12px; color: var(--muted);
}
.summary b { display: block; font-size: 17px; font-variant-numeric: tabular-nums; }

/* ---- حالتِ کاوش در صفحه‌ی تحلیل (multipv + eval زنده) ---- */
.explore-panel { margin-top: var(--s2); }
.evalbar { display: flex; align-items: center; gap: var(--s2); margin-bottom: var(--s2); }
.evalbar-track {
  flex: 1; height: 10px; border-radius: 5px; background: #2b2b2b; overflow: hidden;
}
.evalbar-track i {
  display: block; height: 100%; background: #eee; width: 50%;
  transition: width 0.25s ease; will-change: width;
}
.evalbar b {
  font-variant-numeric: tabular-nums; font-size: 13px; min-width: 42px;
  text-align: center; direction: ltr;
}
.explore-sofar {
  color: var(--muted); font-size: 13px; min-height: 18px; margin-bottom: var(--s2);
  direction: ltr; text-align: start; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.explore-lines { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--s2); }
.exline {
  display: flex; gap: var(--s2); align-items: baseline; padding: 6px 8px;
  border-radius: var(--r-sm); background: var(--panel); border: 1px solid var(--line); font-size: 13px;
}
.exline b { min-width: 44px; font-variant-numeric: tabular-nums; direction: ltr; text-align: center; flex: 0 0 auto; }
.exline span {
  color: var(--muted); direction: ltr; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; text-align: start;
}
.exline.muted { color: var(--muted); justify-content: center; }
.exline.over { justify-content: center; font-weight: 700; }
.exline.t1 b { color: var(--c-best); }
.exline.t2 b { color: #3b82c4; }
.exline.t3 b { color: #8a8f98; }

/* ---- لحظاتِ حساس + Retry Mistake ---- */
.critical-panel { margin-top: var(--s3); }

.an-tabs-mobile { margin-top: var(--s3); }
/* فقط زیرِ ۱۱۰۰px: بالاتر از آن #anBody خودش هر دو گروه را کنارِ هم
   نشان می‌دهد (نگاه کن به چیدمانِ دسکتاپ)، پس سوییچ نه لازم است نه
   دیده می‌شود. عمداً max-width است، نه هم‌سویِ بقیه‌ی فایل که
   min-width‌محور است — چون summary از display:grid استفاده می‌کند و
   یک override با مقدارِ حدسی آن را خراب می‌کرد؛ این‌طور عنصر اصلاً
   دست‌نخورده می‌ماند، فقط این قانون بالاتر از ۱۱۰۰px وجود ندارد. */
@media (max-width: 1099.98px) {
  .an-tab-hide { display: none; }
}
@media (min-width: 1100px) {
  .an-tabs-mobile { display: none; }
}
.critical-panel h3 { font-size: 14px; margin-bottom: var(--s2); color: var(--muted); }
.critical-list { display: flex; flex-direction: column; gap: 8px; }
.crit-card {
  display: flex; flex-direction: column; gap: 4px; padding: var(--s2);
  border-radius: var(--r-sm); background: var(--panel); border: 1px solid var(--line);
}
.crit-card .head { display: flex; align-items: center; gap: var(--s2); }
.crit-card .mv { font-weight: 700; direction: ltr; }
.crit-card .why { color: var(--muted); font-size: 13px; line-height: 1.7; }
.crit-card .line { color: var(--muted); font-size: 12px; direction: ltr; text-align: start; }
.crit-card .retryBtn { align-self: flex-start; margin-top: 4px; }

.retry-panel { margin-top: var(--s2); }
.retry-msg {
  min-height: 40px; padding: var(--s2); border-radius: var(--r-sm);
  background: var(--panel); border: 1px solid var(--line); font-size: 13px; margin-bottom: var(--s2);
}
.retry-msg.good { border-color: var(--c-best); color: var(--c-best); }
.retry-msg.bad { border-color: var(--c-blunder); color: var(--c-blunder); }

/* ================================================================
   ۹. پروفایل
   ================================================================ */
.pf-head { text-align: center; padding: var(--s2) 0 var(--s4); }
.pf-ava-wrap { position: relative; width: 88px; margin: 0 auto var(--s3); }
.ava.xl { width: 88px; height: 88px; border-radius: 24px; font-size: 32px; }
.pf-ava-edit {
  position: absolute; inset-inline-end: -4px; bottom: -4px; width: 30px; height: 30px;
  border-radius: 50%; background: var(--firuzeh); color: var(--on-accent);
  border: 3px solid var(--ink); display: grid; place-items: center;
}
.pf-ava-edit svg { width: 15px; height: 15px; }
.pf-name { font-size: 20px; font-weight: 800; }
.pf-bio {
  color: var(--muted); font-size: 13.5px; margin-top: var(--s1); line-height: 1.6;
  max-width: 320px; margin-inline: auto; white-space: pre-wrap; overflow-wrap: anywhere;
  unicode-bidi: plaintext;
}
.pf-bio.empty { font-style: italic; opacity: 0.7; }
.pf-actions { justify-content: center; margin-top: var(--s3); }
.pf-actions > * { flex: 0 0 auto; }
.pf-follow-counts { justify-content: center; gap: var(--s4); margin-top: var(--s2); }
.pf-follow-count {
  background: none; border: none; padding: 2px 4px; cursor: pointer;
  font-size: 13px; color: var(--muted);
}
.pf-follow-count b { color: var(--text); font-weight: 800; }
.pf-member {
  margin-top: var(--s3); display: inline-flex; align-items: center; gap: 6px;
  font-size: 12px; color: var(--muted); background: var(--panel); border: 1px solid var(--line);
  padding: 5px var(--s3); border-radius: 100px;
}
.pf-member svg { width: 13px; height: 13px; }

/* روند کلی: ریتینگ بزرگ + نوار سه‌رنگِ برد/باخت/مساوی */
.pf-rating-row { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--s3); }
.pf-rating-row .num { font-size: 30px; font-weight: 800; font-variant-numeric: tabular-nums; }
.pf-rating-row .lbl { font-size: 12px; color: var(--muted); }
.wl-bar { height: 8px; border-radius: 100px; overflow: hidden; display: flex; background: var(--raised); }
.wl-bar span { height: 100%; }
.wl-bar .w { background: var(--good); }
.wl-bar .d { background: var(--muted); opacity: 0.5; }
.wl-bar .l { background: var(--danger); }
.wl-legend { display: flex; justify-content: space-between; margin-top: var(--s2); font-size: 12px; color: var(--muted); }
.wl-legend b { color: var(--text); font-variant-numeric: tabular-nums; }
.wl-legend .w b { color: var(--good); }
.wl-legend .l b { color: var(--danger); }

/* ریتینگ به تفکیک سرعت */
.pf-speed-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s2); }
.speed-card {
  background: var(--raised); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s3); text-align: center;
}
.speed-card .ic {
  width: 30px; height: 30px; margin: 0 auto 6px; border-radius: var(--r-sm);
  background: var(--panel); color: var(--firuzeh);
}
.speed-card .ic svg { width: 16px; height: 16px; }
.speed-card .r { font-size: 19px; font-weight: 800; font-variant-numeric: tabular-nums; }
.speed-card .g { font-size: 11.5px; color: var(--muted); margin-top: 2px; }
.speed-card.empty .r { color: var(--muted); font-size: 13px; font-weight: 600; }

/* پازل و تورنمنت، کنار هم */
.pf-mini-row { display: flex; gap: var(--s3); }
.pf-mini { flex: 1; text-align: center; }
.pf-mini .t { font-size: 12px; color: var(--muted); margin-bottom: var(--s1); }
.pf-mini .v { font-size: 17px; font-weight: 800; }

/* روندِ ریتینگ */
.trend { margin-top: var(--s2); }
.spark { width: 100%; height: 140px; display: block; overflow: visible; }
.spark-foot { display: flex; align-items: baseline; gap: var(--s3); margin-top: var(--s3); flex-wrap: wrap; }
.spark-now { font-size: 26px; font-weight: 800; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.spark-delta { font-size: 13px; font-weight: 700; }

/* ------------------------------------------------------ Chess Insights */
.ins-grid, .ins-phase-row { display: flex; gap: var(--s3); margin-bottom: var(--s3); }
.ins-stat { flex: 1; text-align: center; padding: var(--s2) 0; background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-sm); }
.ins-stat .v { font-size: 18px; font-weight: 800; font-variant-numeric: tabular-nums; }
.ins-stat .l { font-size: 11px; color: var(--muted); margin-top: 2px; }

.ins-phase { flex: 1; text-align: center; }
.ins-phase-bar { height: 6px; border-radius: 99px; background: var(--panel); border: 1px solid var(--line); overflow: hidden; margin-bottom: 4px; }
.ins-phase-bar i { display: block; height: 100%; background: var(--firuzeh); border-radius: 99px; }
.ins-phase-lbl { font-size: 11px; color: var(--muted); }
.ins-phase-val { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }

.ins-op-group { margin-bottom: var(--s3); }
.ins-op-title { font-size: 12px; color: var(--muted); margin-bottom: var(--s2); font-weight: 600; }
.ins-op-row { display: flex; align-items: center; gap: var(--s2); margin-bottom: 6px; font-size: 13px; }
.ins-op-row .mv { width: 42px; flex-shrink: 0; font-weight: 700; direction: ltr; text-align: left; }
.ins-op-row .bar { flex: 1; height: 6px; border-radius: 99px; background: var(--panel); border: 1px solid var(--line); overflow: hidden; }
.ins-op-row .bar i { display: block; height: 100%; background: var(--saffron); border-radius: 99px; }
.ins-op-row .pct { width: 40px; flex-shrink: 0; text-align: end; font-variant-numeric: tabular-nums; color: var(--muted); }

.ins-weakness {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s3); margin-top: var(--s2); background: var(--panel);
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.ins-weakness-text { font-size: 13px; }
.ins-weakness-text b { color: var(--saffron); }
.spark-delta.up { color: var(--good); }
.spark-delta.down { color: var(--danger); }
.spark-range { font-size: 12px; color: var(--faint); margin-inline-start: auto; }

/* اتاق افتخارات */
.trophy-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s2); }
.trophy {
  aspect-ratio: 1; border-radius: var(--r); display: flex; flex-direction: column;
  align-items: center; justify-content: center; gap: var(--s1); background: var(--raised);
  border: 1px solid var(--line); position: relative;
}
.trophy .badge { width: 36px; height: 36px; border-radius: 50%; display: grid; place-items: center; }
.trophy .badge svg { width: 18px; height: 18px; }
.trophy.locked .badge { background: var(--panel); color: var(--muted); opacity: 0.55; }
.trophy.locked .nm { color: var(--muted); opacity: 0.55; }
.trophy[data-tier="bronze"]:not(.locked) .badge { background: #b9743c; color: #2a1608; }
.trophy[data-tier="silver"]:not(.locked) .badge { background: #b3bfc6; color: #1c2529; }
.trophy[data-tier="gold"]:not(.locked)   .badge { background: #dbaa46; color: #2c1c04; }
.trophy .nm {
  font-size: 10px; text-align: center; line-height: 1.3; padding: 0 3px;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
}
.trophy .pin {
  position: absolute; inset-inline-end: 6px; top: 6px; width: 14px; height: 14px;
  color: var(--muted); opacity: 0.6;
}
.trophy .pin svg { width: 100%; height: 100%; }

/* شیتِ توضیح یک دستاورد */
.ach-sheet-badge {
  width: 60px; height: 60px; border-radius: 50%; margin: 0 auto var(--s3);
  display: grid; place-items: center;
}
.ach-sheet-badge svg { width: 28px; height: 28px; }
.ach-progress {
  height: 8px; border-radius: 100px; background: var(--raised);
  overflow: hidden; margin-top: var(--s3);
}
.ach-progress i { display: block; height: 100%; background: var(--firuzeh); }

/* ================================================================
   ۱۰. فهرست‌ها، شیت‌ها، گفت‌وگو
   ================================================================ */
/* ردیفِ بازی — تاریخچه و بازی‌های در جریان */
.grow {
  display: flex; align-items: center; gap: var(--s3); padding: var(--s3) 0;
  border-bottom: 1px solid var(--line);
}
.grow:last-child { border-bottom: 0; }
.grow .res {
  flex: 0 0 auto; display: inline-block; font-size: 15px; font-weight: 800;
  line-height: 1; margin-inline-start: var(--s1);
}
.grow .res.win { color: var(--c-good); }
.grow .res.loss { color: var(--c-blunder); }
.grow .res.draw, .grow .res.unfinished { color: var(--saffron); }
.grow .info { flex: 1; min-width: 0; }
.grow .who { display: block; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.grow .meta { display: block; font-size: 12px; color: var(--muted); }
.grow button {
  padding: 6px var(--s3); border-radius: 8px; background: var(--raised);
  border: 1px solid var(--line); font-size: 13px; font-weight: 600; flex: 0 0 auto;
}
.grow button.go { background: var(--firuzeh); color: var(--on-accent); border-color: transparent; }
.history-list-full { max-height: 60vh; overflow-y: auto; margin: var(--s1) 0; }

.lobby-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: 1px solid var(--line); font-size: 14px;
}
.lobby-row:last-child { border-bottom: 0; }
.lobby-row button, .watch-row button {
  padding: 7px var(--s4); border-radius: 8px; background: var(--firuzeh);
  color: var(--on-accent); font-weight: 700; flex: 0 0 auto;
}

.watch-row {
  display: flex; align-items: center; gap: var(--s3); padding: 11px 0;
  border-bottom: 1px solid var(--line);
}
.watch-row:last-child { border-bottom: 0; }
.watch-row .live-dot {
  width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto;
  background: var(--danger); animation: gone-pulse 1.4s ease-in-out infinite;
}
.watch-row .vs { flex: 1; min-width: 0; font-size: 14px; }
.watch-row .vs b { font-weight: 700; }
.watch-row .vs .meta { display: block; font-size: 12px; color: var(--muted); margin-top: 2px; }

/* ------------------------------------------------------------- دوستان */
.friend-search { margin-bottom: var(--s3); }
.friend-search input { margin-top: 0; }
.friend-row { display: flex; align-items: center; gap: var(--s3); padding: 9px 0; }
.friend-row + .friend-row { border-top: 1px solid var(--line); }
.fr-info { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.fr-name {
  font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; unicode-bidi: plaintext;
}
.fr-meta { font-size: 12px; color: var(--muted); }
.friend-row .dot { width: 8px; height: 8px; border-radius: 50%; flex: 0 0 auto; background: var(--faint); }
.friend-row .dot.on { background: var(--good); }
/* .btn پایه display:block و width:100% است — ولی این دکمه‌ی کوچک باید کنارِ
   نام و ریتینگ در یک ردیفِ افقی بنشیند، نه کلِ عرض را بگیرد. */
.friend-row .btn.sm, .fr-status { display: inline-flex; width: auto; flex: 0 0 auto; }
.fr-status { font-size: 12px; color: var(--muted); white-space: nowrap; }
/* ردیفِ خودم — همان حسِ رده‌ی خودم توی تورنمنت */
.friend-row.mine, .tour-standing-row.mine {
  background: var(--accent-soft); border-radius: var(--r-sm);
  padding-inline: var(--s2); margin-inline: calc(var(--s2) * -1);
}

/* ----------------------------------------------------------- تورنمنت */
.tour-detail-head { display: flex; align-items: center; justify-content: space-between; gap: var(--s2); }
.tour-detail-head h2 { margin: 0; flex: 1; min-width: 0; }
#cdAvatar.editable { cursor: pointer; }
#cdAvatar.editable:active { opacity: 0.7; }
.club-pinned {
  margin: var(--s2) 0 0; padding: var(--s2); border-radius: var(--r-sm);
  background: var(--raised); border: 1px solid var(--line); font-size: 14px;
}

/* ------------------------------------------------- سربرگِ صفحه‌ی کلاب
   آواتارِ کمی بزرگ‌تر از حالتِ استاندارد + اسم/تعدادِ عضو زیرِ هم، و دکمه‌ی
   سه‌نقطه‌ی منو ته‌ِ ردیف — بجایِ اینکه «ترکِ کلاب»/«ویرایش» همیشه به شکلِ
   دکمه‌ی پهن روی کارت بمانند. */
.ava.lg { width: 56px; height: 56px; border-radius: 16px; font-size: 21px; }
.club-head-row { align-items: flex-start; }
.club-head-titles { flex: 1; min-width: 0; }
.club-head-titles h2 { margin: 0 0 3px; }
.club-head-row .tag { margin-top: 4px; }
.club-menu-btn { flex: 0 0 auto; }
#cdJoinRow:empty { display: none; }

/* ناوبریِ فرعیِ کلاب (مسابقات/تورنمنت‌ها/رده‌بندی): چیپ‌هایِ فشرده و
   اسکرول‌شونده‌ی افقی — دقیقاً همان قاعده‌ی .personas — تا هیچ‌وقت از
   عرضِ کارت بیرون نزنند، حتی روی باریک‌ترین گوشی. */
.club-nav {
  display: flex; gap: var(--s2); margin-top: var(--s3);
  overflow-x: auto; padding-bottom: 2px; scrollbar-width: none;
}
.club-nav::-webkit-scrollbar { display: none; }
.club-nav-btn {
  flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  padding: 9px 15px; border-radius: 100px; white-space: nowrap;
  background: var(--raised); border: 1px solid var(--line);
  color: var(--text); font-size: 13px; font-weight: 700;
  transition: background 0.12s, transform 0.06s;
}
.club-nav-btn:active { transform: scale(0.97); }
.club-nav-btn .ic-wrap { width: 15px; height: 15px; display: flex; flex: 0 0 auto; color: var(--firuzeh); }
.club-nav-btn .ic-wrap svg { width: 100%; height: 100%; display: block; }

/* آمار و افتخاراتِ کلاب — همان کاشیِ .speed-card و همان .trophy-grid که
   پروفایل دارد، فقط با گرید و داده‌ی مخصوصِ کلاب. */
.club-stats-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--s2); }
.club-badges { margin-top: var(--s3); }
.club-badges.hidden { margin-top: 0; }
.tour-countdown {
  display: inline-block; margin: 2px 0 var(--s3); padding: 6px var(--s4); border-radius: 100px;
  background: var(--accent-soft); border: 1px solid var(--firuzeh);
  color: var(--firuzeh); font-weight: 700; font-size: 13px; direction: ltr; unicode-bidi: isolate;
}
.tour-standing-row { padding: var(--s2) 0; }
.tour-rank { flex: 0 0 22px; text-align: center; font-size: 12.5px; font-weight: 700; color: var(--muted); }
.tour-standing-row:nth-child(1) .tour-rank,
.tour-standing-row:nth-child(2) .tour-rank,
.tour-standing-row:nth-child(3) .tour-rank { color: var(--saffron); }
.tour-score { flex: 0 0 auto; font-weight: 800; font-size: 15px; color: var(--text); }
.tour-streak {
  display: inline-flex; align-items: center; gap: 2px; margin-inline-start: 5px;
  font-size: 11px; font-weight: 700; color: var(--saffron); vertical-align: middle;
}
.tour-streak svg { width: 12px; height: 12px; }
.tour-fmt-badge {
  display: inline-block; margin-inline-start: 6px; padding: 1px 8px; border-radius: 100px;
  font-size: 10.5px; font-weight: 700; vertical-align: middle;
  background: var(--accent-soft); color: var(--firuzeh);
}
#tdRoundTabs { margin-bottom: var(--s3); flex-wrap: wrap; }
.cmd-score {
  font-size: 22px; font-weight: 800; letter-spacing: -0.01em;
  margin: var(--s1) 0 var(--s3); direction: ltr; unicode-bidi: isolate;
}

/* ---------------------------------------------------------------- شیت‌ها */
.sheet {
  position: fixed; inset: 0; z-index: 50; display: grid; place-items: center; padding: var(--s5);
  background: rgba(18, 16, 14, 0.68); animation: fade 0.16s ease-out;
}
.sheet .card {
  max-width: 360px; width: 100%; margin: 0;
  max-height: 86vh; overflow-y: auto;
  animation: rise 0.2s cubic-bezier(0.2, 0.8, 0.3, 1);
}
@keyframes fade { from { opacity: 0; } }
@keyframes rise { from { transform: translateY(14px); opacity: 0; } }

.result { text-align: center; }
.result .big { font-size: 26px; font-weight: 800; margin-bottom: 2px; }
.result .big.win { color: var(--firuzeh); }
.result .big.lose { color: var(--danger); }
.result .big.draw { color: var(--saffron); }
.result .why { color: var(--muted); font-size: 14px; margin-bottom: var(--s1); }
.result .delta { font-size: 14px; margin-bottom: var(--s3); font-variant-numeric: tabular-nums; }
.result .delta b.up { color: var(--firuzeh); }
.result .delta b.down { color: var(--danger); }

.stepper { display: flex; align-items: center; gap: var(--s3); }
.stepper button {
  width: 30px; height: 30px; border-radius: 8px; background: var(--raised);
  border: 1px solid var(--line); font-weight: 700; font-size: 17px;
}
.stepper b { min-width: 20px; text-align: center; font-variant-numeric: tabular-nums; }

.opt-row {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s3);
  padding: var(--s3) 0; border-bottom: 1px solid var(--line);
  /* اجازه‌ی شکستن به خطِ بعد: ردیفِ «ست مهره» چهار گزینه دارد و در عرضِ
     شیت هر کدام به ~۷۰ پیکسل می‌رسید، یعنی «Cburnett» و «خانگی» با سه‌نقطه
     بریده می‌شدند. با min-width فقط همان ردیف پایین می‌رود، نه بقیه. */
  flex-wrap: wrap;
}
.opt-row:last-of-type { border-bottom: 0; }
.opt-row > .seg { flex: 1 1 auto; min-width: 220px; margin: 0; }
.swatches { display: flex; gap: 6px; }
.swatch {
  width: 34px; height: 26px; border-radius: 7px; border: 2px solid transparent;
  overflow: hidden; display: flex;
}
.swatch[aria-pressed="true"] { border-color: var(--firuzeh); }
.swatch i { flex: 1; }
.toggle {
  width: 46px; height: 27px; border-radius: 99px; background: var(--raised);
  border: 1px solid var(--line); position: relative; flex: 0 0 auto;
}
.toggle::after {
  content: ""; position: absolute; top: 2px; right: 2px; width: 21px; height: 21px;
  border-radius: 50%; background: var(--muted); transition: 0.16s;
}
.toggle[aria-pressed="true"] { background: var(--firuzeh); border-color: transparent; }
.toggle[aria-pressed="true"]::after { right: calc(100% - 23px); background: var(--on-accent); }

.toast {
  position: fixed; bottom: 18px; right: 50%; transform: translateX(50%);
  background: var(--panel); border: 1px solid var(--line); padding: 10px var(--s4);
  border-radius: var(--r-sm); font-size: 13px; z-index: 60; max-width: 90vw;
  animation: rise 0.18s ease-out; unicode-bidi: plaintext;
  box-shadow: 0 6px 20px rgba(18, 16, 14, 0.25);
}

/* ------------------------------------------------------------- گفت‌وگو */
.chat-panel { position: fixed; inset: 0; z-index: 45; }
.chat-backdrop { position: absolute; inset: 0; background: rgba(4, 8, 9, 0.55); }
.chat-sheet {
  position: absolute; inset-inline: 0; bottom: 0; max-width: 560px; margin: 0 auto;
  max-height: 72vh; display: flex; flex-direction: column;
  background: var(--panel); border-radius: var(--r-lg) var(--r-lg) 0 0;
  border: 1px solid var(--line); border-bottom: 0; animation: rise 0.16s ease-out;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.chat-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s4) var(--s4) 6px; font-weight: 700;
}
.chat-hint { padding: 0 var(--s4) var(--s3); font-size: 11.5px; color: var(--muted); margin: 0; }
.chat-list { flex: 1; overflow-y: auto; padding: var(--s1) var(--s4); min-height: 120px; }
.chat-msg { display: flex; gap: var(--s2); padding: 7px 0; align-items: flex-start; }
.chat-msg .who { font-size: 12.5px; font-weight: 700; white-space: nowrap; flex: 0 0 auto; unicode-bidi: normal; }
.chat-msg.mine .who { color: var(--firuzeh); }
.chat-msg .who .tag { font-weight: 400; color: var(--muted); font-size: 11px; }
/* نشانِ پریمیوم کنارِ اسم */
.chat-msg .who .pro {
  font-weight: 400; font-size: 10.5px; color: var(--saffron);
  border: 1px solid currentColor; border-radius: 5px; padding: 0 3px;
  margin-inline-start: 4px; vertical-align: 1px;
}
.chat-msg .txt { font-size: 13.5px; line-height: 1.6; overflow-wrap: anywhere; flex: 1; unicode-bidi: plaintext; }
.chat-msg .report-btn {
  flex: 0 0 auto; width: 24px; height: 24px; border-radius: 8px; color: var(--muted);
  display: grid; place-items: center; opacity: 0.6;
}
.chat-msg .report-btn svg { width: 13px; height: 13px; }
.chat-msg.muted { opacity: 0.4; }
.chat-empty { text-align: center; color: var(--muted); font-size: 13px; padding: var(--s5) 0; }

.chat-input-row {
  display: flex; gap: var(--s2);
  padding: var(--s3) var(--s4) calc(var(--s3) + env(safe-area-inset-bottom, 0px));
  border-top: 1px solid var(--line);
}
.chat-input-row input {
  flex: 1; background: var(--raised); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: 10px var(--s4); font-size: 14px; color: var(--text); margin-top: 0;
}
.chat-input-row .ic { flex: 0 0 auto; }

/* ---------------------------------------------------------- شیتِ ایموجی
   دقیقاً همان الگوی .chat-panel — بک‌دراپ + شیتِ پایین‌چسب — چون یک
   نمونه‌ی مشترک بینِ هر سه گفت‌وگو (بازی/عمومی/کلاب) است. */
.emoji-panel { position: fixed; inset: 0; z-index: 50; }
.emoji-backdrop { position: absolute; inset: 0; background: rgba(4, 8, 9, 0.55); }
.emoji-sheet {
  position: absolute; inset-inline: 0; bottom: 0; max-width: 560px; margin: 0 auto;
  max-height: 50vh; display: flex; flex-direction: column;
  background: var(--panel); border-radius: var(--r-lg) var(--r-lg) 0 0;
  border: 1px solid var(--line); border-bottom: 0; animation: rise 0.16s ease-out;
  padding-bottom: env(safe-area-inset-bottom, 0px);
}
.emoji-grid {
  display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px;
  overflow-y: auto; padding: var(--s2) var(--s3) var(--s4);
}
.emoji-opt {
  font-size: 22px; line-height: 1; padding: 8px 0; border-radius: var(--r-sm);
  display: grid; place-items: center;
}
.emoji-opt:active { background: var(--raised); }

/* گفت‌وگوی عمومی — همان ظاهرِ پیام‌های بالا، ولی داخلِ یک کارت به‌جای
   شیتِ تمام‌صفحه. ارتفاع سقف دارد تا کارت صفحه را نبلعد. */
.lobby-chat-list {
  max-height: 240px; overflow-y: auto; margin-top: 6px;
  border-radius: var(--r-sm); background: var(--ink); padding: 2px var(--s3);
}
.lobby-chat-list .chat-msg { padding: 6px 0; }
/* ردیف‌هایی که فشارِ طولانی رویشان منو باز می‌کند (پیامِ خودِ کاربر ندارد) */
.lobby-chat-list .chat-msg[data-idx] { cursor: pointer; }
.lobby-chat-list .ava.sm { margin-inline-end: 2px; }
.lobby-chat-list .chat-empty { padding: var(--s4) 0; }
#lobbyChatCard .chat-input-row { border-top: 0; padding: var(--s3) 0 0; }

/* ================================================================
   ۱۱. سه اندازه‌ی صفحه
   ----------------------------------------------------------------
   گوشی زیرِ ۷۶۸ (پیش‌فرضِ همه‌ی قواعدِ بالا) · تبلت ۷۶۸ تا ۱۰۹۹ ·
   دسکتاپ از ۱۱۰۰. هیچ بریک‌پوینتِ دیگری در این فایل نیست.
   ================================================================ */

/* ---------------------------------------------------------- گوشیِ باریک */
/* بازطراحیِ موبایلِ صفحه‌ی خانه، طبقِ screenshot مرجع — فقط همین بریک‌پوینت
   (حداکثر ۷۶۷px، یعنی دقیقاً همان بازه‌ی «گوشی» که بالای همین بخش هم
   تعریف شده). هیچ‌کدام از این قاعده‌ها از این بریک‌پوینت بیرون نمی‌رود، پس
   تبلت (۷۶۸+) و دسکتاپ (۱۱۰۰+) دقیقاً همان‌طور که بودند می‌مانند —
   بلوک‌های تبلت/دسکتاپ پایین‌ترِ همین فایل دست‌نخورده‌اند. کلاس‌ها و
   idهای واقعی هم دست‌نخورده‌اند، فقط ابعاد/تراکم/چیدمانِ همین بریک‌پوینت
   عوض شده. */
@media (max-width: 767px) {
  /* اقدام‌های سریع: «تازه‌ها» حذف شد؛ فقط پازل روزانه و یادگیری مانده‌اند.
     دوستونه‌ی پیش‌فرضِ qa-grid (بالاتر در همین فایل) همین‌جا هم به‌خودیِ‌خود
     کافی است — دیگر override نمی‌خواهد، هرکدام نیمِ عرضِ ردیف را می‌گیرند و
     با هم تمامِ عرضِ صفحه را پر می‌کنند. فقط بزرگ‌تر شده‌اند نسبت به قبل:
     آیکونِ درشت‌تر، عنوانِ بزرگ‌تر، توضیحِ کامل (نه یک‌خطِ بریده‌ی قبلی).
     qa-list-card (بازی‌های در جریان) همچنان تمام‌عرض می‌ماند
     (grid-column:1/-1 از قبل تعریف شده). */
  .qa-grid > .qa-card:not(.qa-list-card) {
    min-height: 128px; padding: var(--s4);
  }
  .qa-grid > .qa-card:not(.qa-list-card) .qa-ic { width: 40px; height: 40px; }
  .qa-grid > .qa-card:not(.qa-list-card) .qa-ic svg { width: 20px; height: 20px; }
  .qa-grid > .qa-card:not(.qa-list-card) .qa-title { font-size: 15px; line-height: 1.3; }
  .qa-grid > .qa-card:not(.qa-list-card) .qa-sub { font-size: 12.5px; }

  /* بازی‌های در جریان: روی موبایل باید کاملاً واضح باشد — دکمه‌ی «ادامه
     بازی» تمام‌عرض، زیرِ اطلاعاتِ بازی (نه کنارش، جا تنگ می‌شود). */
  #ongoingCard .grow { flex-wrap: wrap; row-gap: var(--s2); }
  #ongoingCard .grow .res { display: none; }
  #ongoingCard .grow .info { flex: 1 1 100%; }
  #ongoingCard .grow button.go {
    flex: 1 1 100%; order: 3; padding: 11px; font-size: 14px; text-align: center;
  }
  #ongoingCard .grow button:not(.go) { order: 2; }

  /* دکمه‌ی شناورِ بازی دیگر لازم نیست — تبِ «بازی» در نوارِ پایین همان
     نقش را دارد (نگاه کن به navPlayMobile در index.html/app.js). */
  #playFab { display: none !important; }

  /* شیتِ «شروعِ بازی» روی موبایل فقط فضای «بینِ سربرگ و نوارِ پایین» را
     می‌گیرد: نه زیرِ نوار می‌رود و نه روی لوگو/آیتم‌های سربرگ می‌افتد.
     مقدارِ دقیقِ این دو فاصله را layoutPlaySheet در app.js از روی ارتفاعِ
     واقعیِ سربرگ و نوار می‌سنجد و روی #playSheet می‌گذارد (--play-top و
     --play-bottom)؛ مقدارِ پیش‌فرضِ زیر فقط تا لحظه‌ی اولِ سنجش است. اگر
     محتوا از این فضا بلندتر باشد، داخلِ خودِ شیت اسکرول می‌شود. */
  .play-panel {
    --play-top: 64px;
    --play-bottom: calc(58px + env(safe-area-inset-bottom, 0px));
  }
  .play-sheet {
    bottom: var(--play-bottom);
    max-height: calc(100% - var(--play-top) - var(--play-bottom));
    border-bottom: 1px solid var(--line);
    padding-bottom: var(--s3);
  }
  .play-sheet-head { padding: var(--s3) 0 var(--s2); }

  /* نوارِ پایین: «بازی» (تبِ تازه، فقط بازکننده‌ی همان شیتِ شروعِ بازی —
     مسیر/صفحه‌ی تازه‌ای نیست) و «اجتماع» هم دیده می‌شوند؛ «تحلیل» و
     «پروفایل» فقط از نوار برداشته می‌شوند تا جا برای این دو باز شود —
     خودِ صفحه‌هایشان و مسیرشان دست‌نخورده‌اند: پروفایل از آواتارِ سربرگ
     در دسترس است (همان‌جا که همیشه بوده، نگاه کن به توضیحِ whoBtn چند
     خط پایین‌تر)، تحلیل هم از دکمه‌های «تحلیل» روی ردیف‌های تاریخچه. */
  .bn-tab-mobile-play { display: flex; }
  .bn-tab-desktop { display: flex; }
  #navAnalysis, #navProfile { display: none; }

  /* ============================================================
     هاب یادگیری — بازطراحیِ موبایل (نگاه کن به یادداشتِ بالای فایل:
     مسیر یادگیری، نه کتابخانه‌ی قابلیت‌ها). فقط این بخش؛ دسکتاپ/تبلت از
     این @media خارج‌اند و دست‌نخورده می‌مانند.
     ============================================================ */

  /* گرید کارتیِ میان‌برها دیگر روی موبایل نشان داده نمی‌شود — همان سه
     مقصد حالا در «موضوعات بیشتر» (.learn-explore-sec پایین‌تر) به‌شکلِ
     ردیفِ ساده می‌آیند تا صفحه شبیهِ داشبورد نشود. */
  .learn-explore-sec { display: block; margin-top: var(--s2); }
  .learn-explore-sec .nav-list { box-shadow: none; }
  .learn-explore-sec .nr-ic { width: 30px; height: 30px; }
  .learn-explore-sec .nr-ic svg { width: 15px; height: 15px; }
  .learn-explore-sec .nr-title { font-weight: 500; font-size: 13.5px; }

  /* نوارِ افقیِ دسته‌ها — تب‌های تخت و ساده، بدونِ آیکون/شمارنده (همان
     الگویِ اسکرولِ افقیِ پروژه)؛ یک حالتِ انتخاب با سبزِ کدر. */
  .learn-cats {
    display: flex; gap: var(--s2); overflow-x: auto; padding: 2px 2px var(--s2);
    margin-bottom: var(--s3); scroll-snap-type: x proximity; -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .learn-cats::-webkit-scrollbar { display: none; }
  .learn-cat-chip {
    flex: 0 0 auto; scroll-snap-align: start; display: flex; align-items: center;
    background: var(--panel); border: 1px solid var(--line); border-radius: var(--r-pill);
    padding: 9px 16px; white-space: nowrap;
  }
  .learn-cat-chip:active { transform: scale(0.96); }
  .learn-cat-chip.active { background: var(--firuzeh); border-color: var(--firuzeh); }
  .learn-cat-chip.active .learn-cat-name { color: var(--on-accent); }
  .learn-cat-ic, .learn-cat-sub { display: none; }
  .learn-cat-name { font-size: 13px; font-weight: 600; }

  /* هیروی مسیرِ یادگیری: یک برچسبِ کوچک، سطح + شمارنده، توضیحِ کوتاه،
     یک نوارِ پیشرفتِ ظریف، یک دکمه — همین. ردیفِ آیکونِ فصل‌ها
     (homeChapterPreview) و عنوانِ کارتِ دسکتاپ (card-head) اینجا کنار
     می‌روند تا هیرو شلوغ نشود؛ دسکتاپ همان‌طور که بود می‌ماند. */
  #tutorialCard { display: flex; flex-direction: column; }
  #tutorialCard .card-head, #tutorialCard #homeChapterPreview { display: none; }
  .hero-kicker {
    display: block; order: 0; font-size: 12px; font-weight: 700; color: var(--firuzeh);
    margin-bottom: 6px;
  }
  .hero-meta-row { display: flex; order: 1; align-items: center; gap: var(--s2); margin-bottom: var(--s2); }
  .hero-progress-count { font-size: 12.5px; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
  #tutorialCard #tutProgressLine { order: 2; margin: 0 0 var(--s2); }
  #tutorialCard .hint-text { order: 3; }
  #tutorialCard #btnTutorialOpen { order: 4; margin-top: var(--s2); }

  /* ردیفِ «ادامه بده» — زیرِ هیرو، اقدامِ اصلیِ بعدی. کارتِ خودش را دارد
     (یکی از سه جایی که استفاده از کارت روی این صفحه مجاز است). */
  .continue-row {
    display: block; background: var(--panel); border: 1px solid var(--line);
    border-radius: var(--r-lg); padding: var(--s4); margin-bottom: var(--s3); box-shadow: var(--shadow-sm);
  }
  .continue-item { display: flex; align-items: center; gap: var(--s3); width: 100%; text-align: start; }
  .continue-item-ic {
    flex: 0 0 auto; width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center;
    background: var(--accent-soft); color: var(--firuzeh);
  }
  .continue-item-ic svg { width: 20px; height: 20px; }
  .continue-item-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 5px; }
  .continue-item-title { font-weight: 700; font-size: 14px; }
  .continue-item-meta { font-size: 12px; color: var(--muted); }
  .continue-item .pbar { margin-top: 2px; }

  /* فهرستِ درس‌ها: کارتِ بیرونی برداشته می‌شود (کارت داخل کارت نه)، هر
     درس یک ردیفِ فشرده با جداکننده‌ی نازک است، نه یک کارتِ جدا. */
  #lessonListCard {
    background: none; border: 0; box-shadow: none; padding: 0; margin-bottom: var(--s5);
  }
  /* عنوانِ کارت («یادگیری شطرنج») به یک برچسبِ ساده‌ی بخش تبدیل می‌شود —
     همان ظاهرِ .sec-title، نه h2 بزرگِ توی کارت؛ توضیحِ زیرش (hint-text)
     برای خلوت‌ماندنِ صفحه اینجا حذف می‌شود. */
  #lessonListCard .card-head { margin-bottom: var(--s3); }
  #lessonListCard .card-head h2 {
    font-size: 13px; font-weight: 700; color: var(--muted); letter-spacing: 0.02em;
  }
  #lessonListCard .hint-text { display: none; }
  #lessonList .lesson-group-head { margin-bottom: var(--s2); }
  #lessonList .lesson-group-ic { width: 22px; height: 22px; background: none; }
  #lessonList .lesson-group-ic svg { width: 15px; height: 15px; }
  #lessonList .lesson-group-name { font-size: 13.5px; }
  #lessonList .lesson-group-count { background: none; padding: 0; }
  #lessonList .lesson-cards { gap: 0; }
  #lessonList .lesson-card {
    background: none; border: 0; border-bottom: 1px solid var(--line);
    border-inline-start: 0; border-radius: 0; padding: var(--s3) 2px; box-shadow: none !important;
  }
  #lessonList .lesson-group:last-child .lesson-card:last-child { border-bottom: 0; }
  #lessonList .lesson-card-ic { width: 30px; height: 30px; }
  #lessonList .lesson-level-pill { background: none; padding: 0; }
  #lessonList .lesson-soon-pill { background: none; padding: 0; }
}

/* سربرگ روی گوشی جا برای نام و ریتینگ ندارد: پنج چیز کنارِ هم (اعلان،
   صندوق، کاربر، ورود، تنظیمات) بعلاوه‌ی لوگو از عرضِ ۳۹۰ بیشتر می‌شود.
   خودِ آواتار می‌ماند (درِ ورودِ پروفایل است) و متن از ۴۴۰ به بالا برمی‌گردد
   — همان اطلاعات یک تب آن‌طرف‌تر، در پروفایل، کامل هست. */
@media (max-width: 439px) {
  .who-btn .who { display: none; }
}

@media (max-width: 380px) {
  :root { --gutter: 12px; }
  .bn-tab .lbl { font-size: 9.5px; }
  .trophy-grid { grid-template-columns: repeat(3, 1fr); }
  .levels { gap: 3px; }
}

/* ---------------------------------------------------------------- تبلت */
@media (min-width: 768px) {
  :root { --gutter: 24px; --content-w: 720px; }

  header { height: 60px; }
  .brand { font-size: 17px; }
  .brand-logo { height: 34px; }

  /* نوار پایین وسط‌چین و کوتاه‌تر می‌ماند — تبلت هنوز دستی است، پس
     ناوبری هم پایین می‌ماند، فقط کشیده نمی‌شود. */
  #bottomNav { max-width: 560px; border-inline: 1px solid var(--line); border-radius: var(--r-lg) var(--r-lg) 0 0; }

  /* دو ستون آنجا که محتوا واقعاً دوتایی است */
  .pf-speed-grid { grid-template-columns: repeat(4, 1fr); }
  .club-stats-grid { grid-template-columns: repeat(4, 1fr); }
  .trophy-grid { grid-template-columns: repeat(6, 1fr); }
  .summary { gap: var(--s2); }

  /* صفحه‌های تخته‌دار: تخته نباید روی تبلت غول‌آسا شود */
  #play, #puzzle, #lesson, #analysis, #explore, #anBoardTool, #spectate, #tutorialPlay, #coord {
    max-width: 520px; margin-inline: auto;
  }

  /* دکمه‌ی شناورِ بازی حالا تنها درِ ورود به شیتِ «شروعِ بازی» است — پس
     برخلافِ قبل، از تبلت به بالا هم باید بماند (بخشِ inline‌ای که با
     نوار/ریل جایگزین شود دیگر وجود ندارد). */

  /* خانه از تبلت به بالا: اقدام‌های سریع سه‌ستونه (چهارمی وقتی بازی‌های
     در جریان هم هست می‌ریزد پایین)؛ نوارِ ریتینگ‌ها هم کمی جادارتر. */
  .hss-card { flex-basis: 112px; }
  .qa-grid { grid-template-columns: repeat(3, 1fr); }
}

/* -------------------------------------------------------------- دسکتاپ */
@media (min-width: 1100px) {
  :root {
    --gutter: 32px; --content-w: 1000px;
    --sidebar-w: 232px;
  }

  /* سایدبارِ عمودیِ ثابت، چسبیده به لبه‌ی inline-start — که در این اپِ
     راست‌به‌چپ سمتِ راستِ صفحه است، هم‌جهت با «عقب» (نگاه کن به کامنتِ
     #btnBack بالاتر در همین فایل). قبلاً (طرحِ Stitch) نوارِ افقیِ بالای
     سربرگ بود؛ حالا طبقِ سند یک سایدبار است که هیچ‌وقت خودش تصمیم به
     پنهان‌شدن نمی‌گیرد — فقط حینِ صفحه‌های غوطه‌ور (بازی/پازل/درس/...)
     مخفی می‌شود (نگاه کن به showNav در app.js)، دقیقاً همان رفتارِ
     قبلی، فقط شکلش عوض شده. محتوای اصلی با padding-inline-start روی
     body کنارش جا می‌شود؛ صفحه‌های غوطه‌ور چون position:fixed با
     inset:0 دارند اصلاً به این padding کاری ندارند و تمام‌عرض می‌مانند —
     که چون سایدبار همان‌جا مخفی است، درست هم همین است. */
  /* padding فقط وقتی اعمال می‌شود که سایدبار واقعاً دیده می‌شود.
     immersive-screen را خودِ show() در app.js از قبل روی body می‌گذارد
     (برای body.immersive-screen{overflow:hidden} که همین‌جا پایین‌تر
     هست) — همان کلاس اینجا هم استفاده می‌شود: بدونش، حینِ صفحه‌های
     غوطه‌ور که سایدبار مخفی است، این فاصله‌ی رزروشده خالی می‌ماند و
     سربرگ/محتوا یک شکافِ بی‌دلیل کنارشان می‌بینند. */
  body:not(.immersive-screen) {
    padding-inline-start: var(--sidebar-w);
  }

  header {
    position: sticky; top: 0; z-index: 47;
    height: 72px;
    background: var(--panel); border-bottom: 1px solid var(--line);
    margin: 0 calc(var(--gutter) * -1) var(--s5);
    padding-inline: var(--gutter);
  }
  .brand { font-size: 17px; }
  .brand-logo { height: 38px; }
  #bottomNav {
    position: fixed; top: 72px; bottom: 0; inset-inline-start: 0;
    width: var(--sidebar-w); max-width: none;
    display: flex; flex-direction: column; align-items: stretch;
    gap: 2px; padding: var(--s3) var(--s2); overflow-y: auto;
    margin: 0; box-shadow: none;
    background: var(--panel); border-inline-end: 1px solid var(--line);
    z-index: 40;
  }

  .bn-tab {
    flex: 0 0 auto; flex-direction: row; justify-content: flex-start;
    gap: var(--s3); padding: 11px var(--s3); border-radius: var(--r);
    font-weight: 600; width: 100%;
  }
  .bn-tab .ic { display: flex; flex: 0 0 auto; }
  .bn-tab .lbl { font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
  .bn-tab.active { background: var(--accent-soft); color: var(--firuzeh); }
  .bn-tab:hover:not(.active) { background: var(--raised); }
  /* پروفایل روی طرحِ افقیِ قبلی برای صرفه‌جوییِ جا حذف می‌شد (از آواتارِ
     whoBtn باز می‌شد)؛ روی سایدبار جا هست، پس مثلِ بقیه‌ی ردیف‌ها می‌ماند. */
  .bn-tab-desktop { display: flex; }

  /* منوی همبرگری — ته‌ِ سایدبار (margin-top:auto در ستونِ فلکس، خودِ
     wrap را از بقیه‌ی ردیف‌ها جدا نگه می‌دارد). */
  .nav-menu-wrap { flex: 0 0 auto; margin-top: auto; width: 100%; }

  body.has-bottom-nav .wrap { padding-bottom: 0; }

  /* مقصدهای فهرستی دو ستونه می‌شوند. ستون‌ها به‌جای grid استفاده می‌شوند
     چون کارت‌ها ارتفاعِ خیلی متفاوتی دارند و grid ردیف‌ها را هم‌ارتفاع
     می‌کند که فضای خالیِ زشت می‌سازد. */
  #more .sec, #learn .sec { break-inside: avoid; }
  #home > .sec:last-child, #more, #learn { column-gap: var(--s5); }
  #more, #learn { column-count: 2; }
  #more > .sec, #learn > .sec {
    break-inside: avoid; -webkit-column-break-inside: avoid;
    display: inline-block; width: 100%;
  }

  /* صفحه‌های تخته‌دار وسط‌چین و محدود می‌مانند */
  #play, #puzzle, #lesson, #explore, #spectate, #tutorialPlay, #coord {
    max-width: 560px; margin-inline: auto;
  }
  #watch, #profile, #auth, #tutorial, #train { max-width: 780px; margin-inline: auto; }

  /* تحلیل/مرور: بردمحور، ولی روی دسکتاپ عریض‌تر — تخته وسط، فهرستِ
     حرکت‌ها/خلاصه/لحظاتِ حساس کنارش، نه زیرش. ترتیبِ DOM دست‌نخورده
     می‌ماند (دقیقاً همان اصلی که #home با grid-template-areas دارد)؛
     فقط هر عنصر با grid-column به ستونِ خودش می‌رود. anShareRow چون با
     دو ردیفِ دیگر کلاسِ «row tight» را مشترک داشت یک id گرفت تا اینجا
     بدونِ ابهام هدف گرفته شود. */
  #analysis { max-width: 980px; margin-inline: auto; }
  #anBody {
    display: grid; grid-template-columns: minmax(0, 1fr) 380px;
    gap: 0 var(--s5); align-items: start;
  }
  #anBody > * { grid-column: 2; }
  #anAcc, #anHead, #anOpening, #anGraph, #anBoardHost, #anMove,
  .an-controls, #anExplore, #anExplorePanel, #btnAnalyseNow {
    grid-column: 1;
  }

  /* تخته‌ی تحلیلِ مستقل (ابزار) — همان الگوی #anBody بالا: تخته و
     نوار/خط‌هایِ eval زیرِ آن در ستونِ یک، فهرستِ حرکت‌ها و بقیه‌ی
     کنترل‌ها در ستونِ کناری. */
  #anBoardTool { max-width: 980px; margin-inline: auto; }
  #abBody {
    display: grid; grid-template-columns: minmax(0, 1fr) 380px;
    gap: 0 var(--s5); align-items: start;
  }
  #abBody > * { grid-column: 2; }
  #abBoardHost, #abEvalBar, #abLines, .an-controls, #abBoardControls {
    grid-column: 1;
  }

  /* صفحه‌ی خانه: روی دسکتاپ عریض‌تر می‌شود، ولی دیگر شبکه‌ی چندناحیه‌ای
     نیست — هر بخش (هیرو/نوارِ ریتینگ‌ها/اقدام‌های سریع/بازی‌های اخیر+آمار/
     ادامه‌بده/اجتماع) تمام‌عرضِ همین ستون است؛ فقط بخشِ پایینی خودش داخلش
     دوستونه می‌شود (نگاه کن به .home-lower-grid پایین‌تر). ترتیبِ DOM همان
     ترتیبِ دیداری است، چیزی جابه‌جا نشده. */
  #home { max-width: 900px; margin-inline: auto; }
  .qa-grid { grid-template-columns: repeat(4, 1fr); }
  .home-lower-grid { flex-direction: row; align-items: flex-start; }
  .home-lower-grid .home-history { flex: 1; min-width: 0; }
  .home-lower-grid .home-side { flex: 0 0 280px; }

  .sheet .card { max-width: 400px; }
  .chat-sheet {
    max-width: 420px; inset-inline-start: auto; inset-inline-end: var(--s5);
    border-radius: var(--r-lg) var(--r-lg) 0 0;
  }

  .pf-speed-grid { grid-template-columns: repeat(4, 1fr); }
  .trophy-grid { grid-template-columns: repeat(7, 1fr); }
}

/* ---------------------------------------------------------- مانیتورِ پهن */
@media (min-width: 1500px) {
  :root { --content-w: 1120px; }

  /* بازآرایی‌ِ ریزِ صفحه‌ی خانه روی مانیتورِ پهن — مقادیر عیناً از یک
     بازبینیِ دستی/بصری (جابه‌جایی/تغییرِ اندازه با ماوس) کپی شده‌اند، نه
     حدسی. اگر بعداً به‌نظر نادرست آمد، دوباره در همین ویوپورت (≥1500px)
     بازبینی و اینجا اصلاح شود. */
  #appShell { width: 1110px; }

  #lobbyChatCard { position: relative; top: 203px; }

  #btnHomeCommunityOpen {
    position: relative; height: 69.7969px; left: 1px; top: -1px; width: 897px;
  }
  .home-community .nav-list { position: relative; top: 218px; }

  .home-history > .card { position: relative; top: 367px; width: 900px; }
  .home-history > .sec-title {
    position: relative; left: var(--s4); top: 409.547px; width: 337px; height: 61.0938px;
  }

  #homeAchCard { position: relative; left: -20px; top: -266.016px; width: 909px; }
  .home-side > .home-quote-card { position: relative; left: -20px; top: -27px; width: 648px; }

  #homeTourBanner { left: -20px; top: 66.1094px; }
  #homeTourBanner > .photo-card-img {
    width: 905px; height: 226.297px; position: relative; top: 0.007775px;
  }
  .home-tour-banner-body { width: 233.156px; height: 166.297px; }
  .home-tour-banner-title { position: relative; left: 40px; top: 35.0078px; }
  .home-tour-banner-sub { position: relative; left: 39px; top: 31px; }

  #btnHomeHeroPlay {
    position: relative; left: 217px; top: 84px; width: 147.625px; height: 63.5px;
  }
  .home-hero-quote {
    position: relative; left: 189px; top: 2px; width: 430px; height: var(--r-xl);
    font-size: var(--r-md);
  }

  #playFab { width: 137.641px; left: 846px; top: 755.203px; height: 56.8125px; }
  #playFab span:last-child { position: relative; left: 7.67249px; top: 0; }
  #playFabIcon > svg {
    height: 29px; width: 19px; position: relative; left: 9.495px; top: 3.26251px;
  }
  #playFabIcon > svg > path { position: relative; left: 14.8199px; top: 0; }

  /* روی مانیتورِ پهن، دوستونی‌بودنِ #learn (نگاه کن به بخشِ دسکتاپِ ≥1100px
     بالاتر) جا برای این‌همه کارت/ردیف نمی‌گذارد و ستونِ سمت‌راست خیلی باریک
     می‌ماند؛ اینجا تک‌ستونی می‌شود تا هر آیتم عرضِ کاملِ #appShell (منهایِ
     gutter) را بگیرد — دقیقاً همان اثری که روی #tutorialCard/#lessonListCard/
     .learn-explore-sec .nav-list و ردیف‌های تویش (btnOpenBook/btnCoordOpen/
     btnMastersHome، هر سه width:100% از پدرشان) دیده شد. عرض‌ها را تک‌تک
     ثابت نکردم چون بازتابِ همین یک تغییر است، نه تنظیمِ دستیِ جداگانه روی
     هرکدام. */
  #learn { column-count: 1; }

  body.has-bottom-nav { position: relative; left: 0; top: 0; }

  /* #more هم تک‌ستونی می‌شود، ولی برخلافِ #learn تا لبه کشیده نمی‌شود —
     محتوایش (چهار ردیفِ ناوبریِ ساده + یک دکمه‌ی «گزینه‌های پیشرفته») نیازی
     به عرضِ کاملِ appShell ندارد، پس فقط تا ۸۳۲px باز می‌شود. */
  #more { max-width: 832px; margin-inline: auto; column-count: 1; }

  /* #tutorial یکی از صفحه‌های «غوطه‌ور» است (نگاه کن به immersiveScreens در
     app.js): با show() از appShell به #screenLayer منتقل می‌شود، پس سقفِ
     ۷۸۰pxِ خودِ #tutorial (بالاتر، بخشِ دسکتاپِ ≥1100px) روی آن اثر ندارد —
     در آن حالت، سقفِ عمومیِ همه‌ی صفحه‌های غوطه‌ور حاکم است
     (#screenLayer > main > *، پیش‌فرض ۵۶۰px). این‌جا فقط برایِ #tutorial (نه
     بقیه‌ی صفحه‌های غوطه‌ور مثلِ #puzzle/#lesson/#coord) به همان ۷۸۰pxِ
     آشنا باز شد؛ کارت/دکمه‌ی تویش چون عرض‌شان از پدر ارث می‌رسد (width:100%)
     خودشان همراهش پهن می‌شوند، بدونِ نیاز به تنظیمِ جداگانه. */
  #tutorial > .sec { max-width: 780px; }
  #screenLayer > #tutorial { background: var(--accent-soft); }
  #tutorial > .sec > .card { background-color: var(--cat-openings-soft); }
}

/* ================================================================
   صفحه‌های متمرکز (بازی/پازل/درس/…)
   ----------------------------------------------------------------
   این صفحه‌ها از جریانِ خانه بیرون می‌آیند و به #screenLayer منتقل می‌شوند
   (نگاه کن به show() در app.js) تا کلِ ارتفاع را بگیرند.

   نکته‌ی مهم برای گوشی: تخته باید *بدونِ اسکرول* جا شود. ارتفاعِ در دسترس
   با --app-100dvh حساب می‌شود نه 100dvh مرورگر، چون دقیقاً همان لحظه‌ای که
   صفحه غیرقابل‌اسکرول می‌شود، مقدارِ 100dvh می‌تواند در حالتِ گذرای نوارِ
   آدرس قفل بماند و تخته کشیده/فشرده رندر شود (app.js آن را اندازه می‌گیرد).
   ================================================================ */
#screenLayer:empty { display: none; }
#screenLayer > main {
  position: fixed; inset: 0; z-index: 30; overflow-y: auto;
  background: var(--ink);
  padding: 62px var(--gutter) var(--s4);
  max-width: none;
  /* روی گوشیِ بلند، تخته عرض‌محدود است و زیرِ نوارِ ابزار فضای مرده می‌ماند؛
     محتوا وسط‌چینِ عمودی می‌شود تا تخته به مرکزِ دید بیاید. کلیدواژه‌ی safe
     یعنی اگر محتوا از صفحه بلندتر شد، به‌جای بریدنِ بالا به شروع برگردد. */
  display: flex; flex-direction: column; justify-content: safe center;
}
#screenLayer > main > * { flex: 0 0 auto; }
body.immersive-screen { overflow: hidden; }

/* سقفِ ارتفاعِ تخته: کلِ صفحه منهای سربرگ، دو ردیفِ بازیکن، نوارِ حرکت‌ها
   و نوارِ ابزار. عدد از جمعِ همان‌ها می‌آید، نه از حدس. */
#screenLayer > #play .board { max-width: min(100%, calc(var(--app-100dvh) - 300px)); margin-inline: auto; }
/* width: 100% لازم است و حذف‌شدنی نیست: این عنصرها خودشان آیتمِ فلکس‌اند و
   margin-inline: auto در یک ستونِ فلکس، کشیده‌شدن در محورِ عرضی را خاموش
   می‌کند. آن‌وقت عرض از محتوا می‌آید — و محتوا خودِ .board با width: 100%
   است، یعنی حلقه‌ای که به صفر ختم می‌شود و تخته اصلاً دیده نمی‌شود. */
#screenLayer > #puzzle #boardHost,
#screenLayer > #spectate #watchBoardHost,
#screenLayer > #explore #exploreHost,
#screenLayer > #tutorialPlay #tutBoardHost,
#screenLayer > #lesson #lsBoardHost,
#screenLayer > #openbook #obBoardHost {
  width: 100%;
  max-width: min(100%, calc(var(--app-100dvh) - 330px));
  margin-inline: auto;
}

/* ستونِ فرعیِ صفحه‌ی بازی. روی گوشی هیچ اثری ندارد (display: contents)،
   پس چیدمانِ گوشی همان تک‌ستونیِ ساده می‌ماند. */
.play-rail { display: contents; }

@media (min-width: 1100px) {
  /* صفحه‌ی متمرکز زیرِ header استیکی جا می‌شود؛ دیگر ریلی نیست که کنارش بنشیند */
  #screenLayer > main { padding-top: 96px; }
  #screenLayer > main > * { max-width: 560px; margin-inline: auto; }

  /* روی دسکتاپ wrapper واقعی می‌شود: تخته یک ستون، ابزارها ستونِ کناری —
     مستقل از اینکه تخته چقدر بلند است. */
  #screenLayer > #play {
    display: grid; align-content: start; justify-content: center;
    grid-template-columns: minmax(0, 560px) 300px;
    grid-template-areas: "top rail" "board rail" "bottom rail";
    column-gap: var(--s5);
  }
  #screenLayer > #play > * { max-width: none; }
  #screenLayer > #play > #plTop { grid-area: top; }
  #screenLayer > #play > #board { grid-area: board; }
  #screenLayer > #play > #plBottom { grid-area: bottom; }
  #screenLayer > #play .play-rail {
    grid-area: rail; align-self: start;
    display: flex; flex-direction: column; gap: var(--s2);
  }
  #screenLayer > #play .move-strip, #screenLayer > #play .toolbar { margin-top: 0; }
  #screenLayer > #play .board { max-width: min(100%, calc(var(--app-100dvh) - 190px)); }
}

/* ================================================================
   دسترس‌پذیری
   ================================================================ */
@media (prefers-reduced-motion: reduce) {
  *, .pc { transition: none !important; animation: none !important; }
}
