/* ═══════════════════════════════════════════════════════════════════════════
   ریست + راست‌به‌چپ + پوسته‌ی مشترک

   پوسته در سه بریک‌پوینت سه شکل دارد:
     < 768   نوار بالا + تب پایین + منوی کشویی (برگر)
     768-1023 همان — تبلت لمسی است و تب پایین در دسترس شست می‌ماند
     ≥ 1024  ساید‌بار ثابت ۲۴۰ جای هر سه را می‌گیرد؛ نه برگر، نه کشو، نه تب پایین

   همه‌ی فاصله‌ها با logical properties نوشته شده‌اند (inline-start/end)، پس
   چیدمان RTL بدون هیچ override ای کار می‌کند.
   ═══════════════════════════════════════════════════════════════════════════ */

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

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  direction: rtl;
  font-family: var(--font-base);
  font-size: var(--fs-md);
  font-weight: var(--fw-reg);
  line-height: var(--lh-body);
  color: var(--color-text);
  background: var(--color-bg);
  display: flex;
  min-height: 100vh;
  min-height: 100dvh; /* روی موبایل ۱۰۰vh زیر نوار آدرس می‌رود و تب پایین دیده نمی‌شود */
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img {
  max-width: 100%;
}

button {
  font-family: inherit;
  cursor: pointer;
}

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

a {
  color: inherit;
}

:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

.skip-link {
  position: absolute;
  inset-inline-start: -9999px;
  top: 0;
  z-index: calc(var(--z-modal) + 1);
  background: var(--color-surface);
  padding: var(--space-xl) var(--space-2xl);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
}
.skip-link:focus {
  inset-inline-start: var(--space-xl);
  top: var(--space-xl);
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ═══════════════ اسکلت ═══════════════ */

.app-shell {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/*
  ویوها ارتفاعشان را با calc(100vh - var(--topbar-height) - var(--tabs-height))
  حساب می‌کنند. در مسیرهایی که نوار بالا یا تب پایین وجود ندارد، صرفِ مخفی‌کردن
  عنصر کافی نیست — خود توکن هم باید صفر شود وگرنه یک نوار خالی ته صفحه می‌ماند.
  تنها چیزی که باید در آن جهت رزرو بماند حاشیه امن دستگاه است.
*/
body:not(.has-topbar) {
  --topbar-height: var(--safe-top);
}
body:not(.has-tabs) {
  --tabs-height: var(--safe-bottom);
}

/* ═══════════════ نوار بالا (موبایل و تبلت) ═══════════════ */

.app-topbar {
  flex: 0 0 auto;
  min-height: var(--topbar-height);
  /* بدون display اینجا — وگرنه ویژگی hidden بی‌اثر می‌شود */
  align-items: center;
  gap: var(--space-lg);
  padding: calc(var(--safe-top) + var(--space-xl))
           calc(var(--page-margin) + var(--safe-start))
           var(--space-xl)
           calc(var(--page-margin) + var(--safe-end));
  background: var(--color-surface);
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
}
.app-topbar:not([hidden]) {
  display: flex;
}

.app-topbar__menu-btn {
  flex: 0 0 32px;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--color-text);
  display: grid;
  place-items: center;
}
.app-topbar__menu-btn svg {
  width: 32px;
  height: 32px;
}

.app-topbar__who {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-inline-start: auto;
  min-width: 0;
}

.app-topbar__greeting {
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  color: var(--color-text);
  text-align: end;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}

.app-topbar__avatar {
  flex: 0 0 52px;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  object-fit: cover;
}

/* ═══════════════ محتوا ═══════════════ */

.view-root {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-xl)
           calc(var(--page-margin) + var(--safe-start))
           var(--space-3xl)
           calc(var(--page-margin) + var(--safe-end));
}

/*
  حاشیه امن عمودی: وقتی نوار بالا/تب پایین وجود دارد خودشان آن را جذب می‌کنند.
  در مسیرهای بدون پوسته هیچ‌کس جذبش نمی‌کرد و روی آیفون ناچ‌دار محتوا زیر ناچ
  (۵۹px) و زیر خط Home Indicator (۳۴px) می‌رفت.
*/
body:not(.has-topbar) .view-root {
  padding-top: calc(var(--space-xl) + var(--safe-top));
}
body:not(.has-tabs) .view-root {
  padding-bottom: calc(var(--space-3xl) + var(--safe-bottom));
}

/* ستون محتوا — همه‌ی صفحات محتوایشان را داخل این می‌گذارند */
.container {
  width: 100%;
  max-width: var(--content-max);
  margin-inline: auto;
}

/* ستون باریک — فرم‌ها و صفحات احراز هویت */
.container--narrow {
  max-width: 420px;
}

/* ستون ابزار — ماشین‌حساب و مشابه؛ در دسکتاپ چیدمان افقی می‌گیرد */
.container--tool {
  max-width: 640px;
}

/*
  گرید کارت — تعداد ستون در طرح تأییدشده قطعی است: ۲ / ۳ / ۴.

  نسخه‌ی قبلی از `auto-fill` با کف `--card-min: 165px` استفاده می‌کرد و همین
  شکننده بود: هر ظرفی باریک‌تر از ۳۴۲ (مثلاً گوشی ۳۷۵ پیکسلی، یا صفحه‌ی
  معلم‌یار که پدینگ خودش را هم دارد) بی‌صدا به یک ستون می‌افتاد. تعداد ستون
  یک تصمیم طراحی است، نه نتیجه‌ی جانبیِ عرض ظرف — پس صریح نوشته می‌شود و
  --card-min فقط برای گریدهایی می‌ماند که عمداً سیال‌اند.
*/
.grid-cards {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--grid-row-gap) var(--grid-gutter);
}

@media (min-width: 768px) {
  .grid-cards { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (min-width: 1024px) {
  .grid-cards { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ═══════════════ آیکون ناوبری ═══════════════
   آیکون‌ها SVG اکسپورت‌شده از همان آیکون‌پک فیگما هستند، ولی به‌جای <img>
   به‌صورت mask رندر می‌شوند تا رنگشان از currentColor بیاید. این تنها راهی است
   که استیت فعال (تغییر رنگ) بدون ساختن نسخه‌ی دوم هر آیکون کار می‌کند. */

/*
  مسیر آیکون‌ها باید همین‌جا در CSS تعریف شود، نه در style ای که در index.html
  نوشته می‌شود: url() داخل یک custom property نسبت به فایلی که آن property را
  اعلام کرده حل می‌شود. اگر در HTML بنویسیم، مرورگر آن را نسبت به css/base.css
  حساب می‌کند و به css/assets/... می‌رسد که وجود ندارد.
*/
:root {
  --icon-home:      url("../assets/images/shell/nav/home.svg");
  --icon-classroom: url("../assets/images/shell/nav/classroom.svg");
  --icon-theater:   url("../assets/images/shell/nav/theater.svg");
  --icon-lab:       url("../assets/images/shell/nav/lab.svg");
  --icon-trip:      url("../assets/images/shell/nav/trip.svg");
  --icon-menu:      url("../assets/images/shell/nav/menu.svg");
}

.nav-icon {
  display: block;
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
  background-color: currentColor;
  -webkit-mask: var(--icon) center / contain no-repeat;
  mask: var(--icon) center / contain no-repeat;
}
.nav-icon--menu {
  width: 32px;
  height: 32px;
  flex-basis: 32px;
}

/* ═══════════════ تب پایین (موبایل و تبلت) ═══════════════ */

.app-tabs {
  flex: 0 0 auto;
  min-height: var(--tabs-height);
  padding-bottom: var(--safe-bottom);
  padding-inline: var(--safe-start) var(--safe-end);
  grid-template-columns: repeat(5, minmax(0, 1fr));
  align-items: center;
  background: var(--color-surface);
  box-shadow: var(--shadow-xs-top);
  position: sticky;
  bottom: 0;
  z-index: var(--z-tabs);
}
.app-tabs:not([hidden]) {
  display: grid;
}

.app-tabs__btn {
  background: none;
  border: none;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-md);
  border-radius: var(--radius-lg);
  font-size: var(--fs-xs);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  color: var(--color-text-muted);
  min-width: 0;
  overflow: hidden;
}
.app-tabs__btn svg {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
}
.app-tabs__btn span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* استیت فعال: آیکون Bold + تغییر رنگ — یکسان برای هر پنج تب */
.app-tabs__btn.is-active {
  color: var(--color-accent);
  font-weight: var(--fw-bold);
}
.app-tabs__btn.is-active svg {
  stroke-width: 2;
}

.app-tabs__btn[aria-disabled="true"] {
  color: var(--color-text-subtle);
  cursor: not-allowed;
  pointer-events: none;
}
/* آیکون‌های ناوبری <span> با mask-image هستند، نه <svg> — سلکتور قبلی به هیچ
   المانی نمی‌خورد و کد مرده بود. رنگ خودش از currentColor کم‌رنگ می‌شود؛ این
   opacity فقط کمی بیشتر عقبش می‌برد. */
.app-tabs__btn[aria-disabled="true"] .nav-icon {
  opacity: 0.55;
}

/* ═══════════════ ساید‌بار (دسکتاپ) ═══════════════ */

.app-sidebar {
  /* بدون display اینجا — hidden باید کار کند */
  flex: 0 0 var(--sidebar-width);
  width: var(--sidebar-width);
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-3xl) var(--space-2xl)
           calc(var(--space-3xl) + var(--safe-bottom));
  background: var(--color-surface);
  border-inline-start: 1px solid var(--color-border);
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
  z-index: var(--z-sidebar);
}
.app-sidebar:not([hidden]) {
  display: flex;
}

.app-sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: 0 var(--space-lg) var(--space-2xl);
}
.app-sidebar__brand img {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
}
.app-sidebar__brand b {
  font-size: var(--fs-md);
  font-weight: var(--fw-bold);
}

.app-sidebar__item {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
  width: 100%;
  padding: var(--space-xl);
  border: 0;
  border-radius: var(--radius-lg);
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  color: var(--color-text-muted);
  text-align: start;
  text-decoration: none;
}
.app-sidebar__item svg {
  width: 24px;
  height: 24px;
  flex: 0 0 24px;
}
.app-sidebar__item:hover {
  background: var(--color-surface-alt);
}
.app-sidebar__item.is-active {
  background: var(--color-accent-soft);
  color: var(--color-accent);
  font-weight: var(--fw-bold);
}
.app-sidebar__item.is-active svg {
  stroke-width: 2;
}
.app-sidebar__item[aria-disabled="true"] {
  color: var(--color-text-subtle);
  cursor: not-allowed;
  pointer-events: none;
}
.app-sidebar__item[aria-disabled="true"] .nav-icon {
  opacity: 0.55;
}

.app-sidebar__tag {
  margin-inline-start: auto;
  font-size: var(--fs-2xs);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  background: var(--color-surface-alt);
  color: var(--color-text-subtle);
  padding: 2px var(--space-lg);
  border-radius: var(--radius-full);
}

.app-sidebar__sep {
  height: 1px;
  background: var(--color-border);
  margin: var(--space-lg);
}

.app-sidebar__spacer {
  flex: 1 1 auto;
}

/* گزینه‌ی «بیشتر» — جایگزین منوی برگر در وب */
.app-sidebar__more > summary {
  list-style: none;
}
.app-sidebar__more > summary::-webkit-details-marker {
  display: none;
}
.app-sidebar__chevron {
  margin-inline-start: auto;
  width: 16px;
  height: 16px;
  flex: 0 0 16px;
  color: var(--color-text-subtle);
  transition: transform 0.18s ease;
}
.app-sidebar__more[open] > summary .app-sidebar__chevron {
  transform: rotate(180deg);
}

.app-sidebar__subgroup {
  padding: var(--space-md) 0 var(--space-lg);
}
.app-sidebar__subgroup h4 {
  margin: var(--space-lg) 0 var(--space-md);
  padding-inline-start: var(--space-xl);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-demi);
  line-height: var(--lh-tight);
  letter-spacing: 0.04em;
  color: var(--color-text-subtle);
}
.app-sidebar__sublink {
  display: block;
  width: 100%;
  padding: 7px var(--space-xl);
  margin-inline-start: var(--space-2xl);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
  color: var(--color-text-muted);
  text-align: start;
  text-decoration: none;
}
.app-sidebar__sublink:hover {
  background: var(--color-surface-alt);
  color: var(--color-text);
}
.app-sidebar__sublink.is-active {
  background: var(--color-accent-soft);
  color: var(--color-accent);
  font-weight: var(--fw-demi);
}

.app-sidebar__profile {
  display: flex;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-lg);
  margin-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}
.app-sidebar__profile img {
  width: 36px;
  height: 36px;
  flex: 0 0 36px;
  border-radius: 50%;
  object-fit: cover;
}
.app-sidebar__profile b {
  display: block;
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
}
.app-sidebar__profile small {
  display: block;
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

/* ═══════════════ منوی کشویی — فقط موبایل و تبلت ═══════════════ */

.side-menu {
  position: fixed;
  inset-inline-start: 0; /* در dir=rtl یعنی چسبیده به لبه راست */
  top: 0;
  bottom: 0;
  width: min(80vw, 320px);
  background: var(--color-surface);
  box-shadow: var(--shadow-md);
  transform: translateX(100%);
  transition: transform 0.25s ease, visibility 0s linear 0.25s;
  visibility: hidden;
  z-index: var(--z-side-menu);
  display: flex;
  flex-direction: column;
  padding: calc(var(--space-2xl) + var(--safe-top))
           calc(var(--space-2xl) + var(--safe-start))
           calc(var(--space-2xl) + var(--safe-bottom))
           var(--space-2xl);
}
.side-menu.is-open {
  transform: translateX(0);
  visibility: visible;
  transition: transform 0.25s ease, visibility 0s;
}
/* روتر روی مسیرهای بدون نوار بالا منو را inert می‌کند — نباید دیده هم بشود */
.side-menu[inert],
.side-menu[inert].is-open {
  transform: translateX(100%);
  visibility: hidden;
}

.side-menu-backdrop {
  position: fixed;
  inset: 0;
  background: var(--color-backdrop);
  z-index: calc(var(--z-side-menu) - 1);
}

.side-menu__header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: var(--space-2xl);
  color: var(--color-text-muted);
  font-size: var(--fs-xs);
}

.side-menu__list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.side-menu__group-title {
  margin: var(--space-2xl) 0 var(--space-md);
  padding-inline-start: var(--space-xl);
  font-size: var(--fs-2xs);
  font-weight: var(--fw-demi);
  line-height: var(--lh-tight);
  letter-spacing: 0.04em;
  color: var(--color-text-subtle);
}
.side-menu__group-title:first-child {
  margin-top: 0;
}

.side-menu__link {
  display: block;
  width: 100%;
  padding: var(--space-xl);
  border: 0;
  border-radius: var(--radius-lg);
  background: none;
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  color: var(--color-text);
  text-align: start;
  text-decoration: none;
}
.side-menu__link:hover {
  background: var(--color-surface-alt);
}

.side-menu__logout {
  border: none;
  background: none;
  color: var(--color-danger);
  padding: var(--space-xl) 0;
  text-align: start;
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
}

/* ═══════════════ سوییچ بریک‌پوینت پوسته ═══════════════ */

@media (min-width: 1024px) {
  /* ساید‌بار جای نوار بالا، تب پایین و منوی کشویی را می‌گیرد */
  body.has-sidebar .app-topbar,
  body.has-sidebar .app-tabs {
    display: none !important;
  }
  body.has-sidebar {
    --topbar-height: 0px;
    --tabs-height: 0px;
  }
  body.has-sidebar .side-menu,
  body.has-sidebar .side-menu-backdrop {
    display: none !important;
  }
  body.has-sidebar .view-root {
    padding-top: var(--space-3xl);
  }
}

/* زیر ۱۰۲۴ ساید‌بار هرگز دیده نمی‌شود، حتی اگر روتر آن را روشن کرده باشد */
@media (max-width: 1023px) {
  .app-sidebar {
    display: none !important;
  }
}

/* ═══════════════ حالت placeholder صفحات ═══════════════ */

.view-placeholder {
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-xl);
  text-align: center;
  padding: var(--space-4xl);
  color: var(--color-text-muted);
}
.view-placeholder:not([hidden]) {
  display: flex;
}

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

/* ═══════════════════════════════════════════════════════════════════════════
   عنوان صفحه — کلاس مشترک

   بدون این کلاس، هر صفحه عنوانش را خودش تعریف می‌کرد و نتیجه ۶ سایز مختلف شد
   (۱۶/۵۰۰ و ۱۶/۶۰۰ و ۱۸/۵۰۰ و ۱۸/۷۰۰ و ۲۰/۶۰۰ و ۳۲/۷۰۰) و رمپ دسکتاپ هیچ‌جا
   پیاده نشده بود. این کلاس همان رمپ تأییدشده‌ی طرح ریسپانسیو است:

       موبایل ۱۶  →  تبلت ۲۴  →  دسکتاپ ۳۲   (همه DemiBold 600)

   وزن ۶۰۰ از خود فیگما آمده، نه از حدس: عنوان صفحه آنجا داخل کامپوننت مشترکِ
   نوار بالا (919:2236) است و هر ۶۲ نمونه‌اش IRANSansXFaNum DemiBold 16 هستند.

   هر عنوانِ اصلیِ صفحه باید این کلاس را بگیرد. سرتیترهای داخل صفحه (مثل
   «درس‌های پایه اول») عنوان صفحه نیستند و این کلاس را نمی‌گیرند.

   سلکتور عمداً `h1.page-title` است نه `.page-title`: استایل‌شیت هر صفحه بعد از
   این فایل به head اضافه می‌شود، پس با specificity برابر همیشه برنده می‌شد و
   این کلاس بی‌اثر می‌ماند. یک درجه specificity بیشتر، رمپ را قطعی می‌کند.
   ═══════════════════════════════════════════════════════════════════════════ */
h1.page-title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-demi);
  line-height: var(--lh-tight);
  color: var(--color-text);
}

@media (min-width: 768px) {
  h1.page-title { font-size: var(--fs-2xl); }
}

@media (min-width: 1024px) {
  h1.page-title { font-size: var(--fs-4xl); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   نوار بالای صفحه — کلاس مشترک

   الگوی «[اکشن] عنوان [اکشن]» که در فیگما تقریباً هر صفحه‌ی داخلی دارد
   (Component 2 / 919:2228). تا الان هر صفحه نسخه‌ی خودش را تکرار می‌کرد —
   با همان مارجین‌های منفی برای تمام‌عرض‌شدن — که شش بار کپی شده بود.

   مارجین منفی لازم است چون ظرف صفحه پدینگ افقی دارد ولی این نوار باید
   لبه‌تا‌لبه سفید باشد، دقیقاً مثل فیگما.
   ═══════════════════════════════════════════════════════════════════════════ */
.page-topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-lg);
  margin-block-start: calc(-1 * (var(--space-xl) + var(--safe-top)));
  margin-inline: calc(-1 * (var(--page-margin) + var(--safe-start)))
                 calc(-1 * (var(--page-margin) + var(--safe-end)));
  margin-block-end: var(--space-2xl);
  padding-block: calc(var(--space-xl) + var(--safe-top)) var(--space-xl);
  padding-inline: calc(var(--space-2xl) + var(--safe-start))
                  calc(var(--space-3xl) + var(--safe-end));
  background: var(--color-surface);
}
.page-topbar > .page-title { text-align: center; }

/* دکمه‌ی متنی «بازگشت» با آیکون — فیگما: ارتفاع ۳۲، رادیوس ۴، متن ۱۲/Medium، آیکون ۲۰ */
.page-back {
  display: inline-flex;
  align-items: center;
  gap: var(--space-md);
  height: 32px;
  padding-inline: var(--space-lg);
  border: 0;
  border-radius: var(--radius-sm);
  background: none;
  font: inherit;
  font-size: var(--fs-xs);
  font-weight: var(--fw-med);
  line-height: var(--lh-tight);
  color: var(--color-text);
  cursor: pointer;
}
.page-back:hover { background: var(--color-surface-alt); }
.page-back img { width: 20px; height: 20px; flex: 0 0 20px; }
.page-topbar > .page-back:first-child { justify-self: start; }
.page-topbar > .page-back:last-child  { justify-self: end; }

/* ═══════════════════════════════════════════════════════════════════════════
   بلوک معرفی بالای صفحه‌های فهرستی

   هر سه صفحه‌ی PDFs (11245:161796)، Folders (11252:194971) و Videos
   (11252:194978) عیناً یک بلوک دارند: عنوان ۱۶ و زیرعنوان ۱۴/Medium خاکستری،
   وسط‌چین، با فاصله‌ی ۲. چون یکی است اینجا مشترک تعریف شده تا سه نسخه‌ی
   واگرا نشود.
   ═══════════════════════════════════════════════════════════════════════════ */
.page-intro {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  text-align: center;
}

.page-intro__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-demi);
  line-height: 1.4;
  color: var(--neutral-black);
}

.page-intro__sub {
  margin: 0;
  font-size: var(--fs-sm);
  font-weight: var(--fw-med);
  line-height: var(--lh-body);
  color: var(--neutral-500);
}

@media (min-width: 768px) {
  .page-intro__title { font-size: var(--fs-xl); }
  .page-intro__sub { font-size: var(--fs-md); }
}
@media (min-width: 1024px) {
  .page-intro__title { font-size: var(--fs-2xl); }
  .page-intro__sub { font-size: var(--fs-lg); }
}

/* ═══════════════════════════════════════════════════════════════════════════
   نگهبان سراسری [hidden]

   قرارداد این کدبیس نوشتن `:not([hidden])` روی هر قانونی است که display می‌دهد.
   ولی یادرفتنش خطای بی‌صدا می‌سازد: عنصر با hidden=true روی صفحه می‌ماند و کل
   محتوا را می‌پوشاند — دقیقاً اتفاقی که برای لایه‌ی بارگذاری صفحه‌ی ثبت‌نام افتاد.

   این قانون آن دسته خطا را برای همیشه می‌بندد. `:not([hidden])`های موجود بعد از
   این فقط افزونگی بی‌ضررند و لازم نیست حذف شوند.
   ═══════════════════════════════════════════════════════════════════════════ */
[hidden] {
  display: none !important;
}
