/* ===========================================================================
   بخش‌های صفحهٔ اصلی — لایهٔ ساختار. فاز ۵۸.۳
   ===========================================================================

   این فایل **بخش‌های صفحهٔ اصلی** را می‌چیند و بس. مقیاس‌ها، دکمه، کارت،
   حلقهٔ focus و اسکلتِ بارگذاری در `foundation.css`‌اند که فاز ۵۹.۱
   ساختش؛ اینجا فقط مصرف می‌شوند.

   هر مقدارِ دیداری از توکن‌های فاز ۵۲.۶ می‌آید (`--theme-accent`،
   `--theme-radius`، `--theme-density`، `--theme-shadow`, …) که هر قالب
   مقدارِ خودش را برایشان دارد.

   یعنی همین یک فایل در fastkart سبز و گرد است و در wolmart می‌تواند
   تیره و تیز باشد، بدونِ یک خط تفاوت — و قالبی که بخواهد بیشتر از این
   فرق کند، در `theme-design.css` خودش هرچه اینجاست را بازنویسی می‌کند.

   ── چرا یک لایهٔ مشترک، وقتی قرار است قالب‌ها مستقل باشند ──────────────

   «مستقل» یعنی هر قالب markup و ظاهرِ خودش را دارد، نه اینکه هر قالب
   چرخ را از نو بسازد. ریتمِ عمودی و مقیاسِ تایپوگرافی **تصمیمِ زیبایی‌شناسی
   نیستند**، مهندسیِ خوانایی‌اند؛ چهار نسخهٔ کمی متفاوتشان یعنی سه‌تایشان
   بدترند.

   آنچه اینجا **نیست** و عمداً نیست: رنگ، سایه، فونت، شکلِ کارت. آن‌ها
   جایی‌اند که قالب‌ها واقعاً باید فرق کنند.

   ── یک واژگان، نه دو ──────────────────────────────────────────────────

   فاز ۵۸.۱ نوارِ افقی را `.home-band-slider` نامید و داخلِ
   `static/frontend/fastkart/css/theme-design.css` گذاشتش. دو مشکل داشت:
   نامش با بقیهٔ این لایه هم‌خانواده نبود، و — مهم‌تر — سه قالبِ دیگر که
   همان partial را ارث می‌برند، آن CSS را **نداشتند**؛ یعنی نوارِ محصولِ
   کالامارکت یک ستونِ عمودیِ تمام‌عرض بود.

   حالا همه‌چیز `hs-` است و همه‌چیز اینجاست، و هر چهار master این فایل را
   لینک می‌کنند.

   ── فاز ۵۹.۱ نیمی از این فایل را برداشت ───────────────────────────────

   `.hs-container`، `.hs-button`، `.hs-placeholder`، `.hs-sr-only`، حلقهٔ
   focus و هدفِ لمسیِ ۴۴px همه اینجا بودند. هیچ‌کدام مخصوصِ صفحهٔ اصلی
   نبودند و صفحهٔ دسته و سبد هم همان‌ها را می‌خواستند، پس به
   `foundation.css` رفتند و نامشان `ds-` شد.
   =========================================================================== */

:root {
    /* فاصلهٔ عمودیِ بینِ بخش‌ها — تنها مقیاسی که مخصوصِ صفحهٔ اصلی است.
       بقیهٔ مقیاس‌ها (`--ds-text-*`, `--ds-space-*`) در
       `foundation.css`‌اند و اینجا فقط مصرف می‌شوند. */
    --hs-section-gap: var(--ds-space-5);

    /* بلندیِ کاشیِ تبلیغاتی. سه اندازه، چون تنظیمِ `height` سه گزینه دارد. */
    --hs-tile-short: 8rem;
    --hs-tile-medium: 13rem;
    --hs-tile-tall: 19rem;
}

/* ---------------------------------------------------------------------------
   پوستهٔ هر بخش
   --------------------------------------------------------------------------- */

.hs-section {
    padding-block: var(--hs-section-gap);
}

/* بخشِ اول فاصلهٔ بالایی ندارد: زیرِ هدر می‌نشیند و فاصلهٔ دوبل، صفحه را
   با یک نوارِ خالی شروع می‌کند. */
.hs-section:first-child {
    padding-block-start: 0;
}

/* ---------------------------------------------------------------------------
   سرِ بخش — تیتر، زیرتیتر، و لینکِ «همه»
   --------------------------------------------------------------------------- */

.hs-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--ds-space-3);
    margin-block-end: var(--ds-space-4);
    flex-wrap: wrap;
}

.hs-head__titles { min-width: 0; }

/* `h2` است و نه `h1`: تیترِ صفحه یکی است و در پوسته نشسته. پرشِ سطح —
   `h1` بعد `h4` — چیزی است که صفحه‌خوان‌ها با آن ناوبری می‌کنند و خرابش
   می‌کند. (ui-ux-pro-max ← Accessibility / Heading Hierarchy) */
.hs-title {
    font-size: var(--ds-text-2xl);
    font-weight: 800;
    line-height: 1.25;
    margin: 0;
    color: var(--theme-ink, #222);
    font-family: var(--theme-font, inherit);
}

.hs-subtitle {
    font-size: var(--ds-text-sm);
    line-height: 1.6;
    margin: var(--ds-space-1) 0 0;
    color: var(--theme-ink-muted, #6b7280);
}

.hs-head__link {
    font-size: var(--ds-text-sm);
    font-weight: 600;
    color: var(--theme-accent, #0da487);
    text-decoration: none;
    white-space: nowrap;
    padding: var(--ds-space-1) var(--ds-space-2);
    border-radius: var(--theme-radius-sm, 4px);
}

.hs-head__link:hover { text-decoration: underline; }

/* ---------------------------------------------------------------------------
   شبکه و نوارِ افقی — دو چیدمانی که هر نوارِ محصول می‌تواند بگیرد
   --------------------------------------------------------------------------- */

/* `--theme-columns` یک تنظیمِ قالب است (پیش‌فرض ۴). `auto-fit` با
   `minmax` یعنی روی صفحهٔ باریک خودش کم می‌شود بدونِ media query.

   ── چرا `auto-fit` و نه `repeat(var(--theme-columns), 1fr)` — فاز ۷۵ ──

   ستونِ ثابت یعنی نواری که سه کالا دارد، در شبکهٔ شش‌ستونه سه سلولِ
   خالی می‌گذارد: نصفِ نوار سفید می‌ماند و بیننده فکر می‌کند صفحه
   نیمه‌بارگذاری شده. روی فروشگاهِ واقعی این حالتِ عادیِ هر دسته‌ای
   است که کالای کمی دارد.

   `auto-fit` ستونِ خالی را جمع می‌کند، پس همان سه کارت تمامِ عرض را
   می‌گیرند. عددِ `--theme-columns` هنوز تصمیم‌گیرنده است: پهنای
   کمینهٔ هر ستون از رویش حساب می‌شود، پس وقتی کالا به اندازهٔ کافی
   باشد دقیقاً همان‌قدر ستون درمی‌آید. */
.hs-grid {
    display: grid;
    gap: var(--ds-space-3);
    grid-template-columns: repeat(
        auto-fit, minmax(min(180px, 100%), 1fr));
}

@media (min-width: 992px) {
    .hs-grid {
        grid-template-columns: repeat(auto-fit, minmax(
            max(180px, calc(
                (100% - (var(--theme-columns, 4) - 1) * var(--ds-space-3))
                / var(--theme-columns, 4))), 1fr));
    }
}

/* نوارِ افقیِ بدونِ جاوااسکریپت. `scroll-snap` همان کار را می‌کند و در هر
   چهار قالب یکسان رفتار می‌کند؛ مرورگری که نداشته باشد یک نوارِ افقیِ
   قابلِ اسکرول می‌بیند، نه صفحهٔ خراب. همان استدلالِ `page_builder`. */
.hs-rail {
    display: flex;
    gap: var(--ds-space-3);
    overflow-x: auto;
    /* `proximity` و نه `mandatory` — فاز ۷۵.
       با `mandatory` مرورگر **موظف** است همیشه روی یکی از نقطه‌های
       توقف بایستد، و هر تغییرِ چیدمان (رسیدنِ تصویرِ تنبل، عوض‌شدنِ
       ارتفاعِ کارت) می‌تواند نوار را به نقطهٔ دیگری ببرد. نتیجه‌اش
       نواری بود که خودبه‌خود جابه‌جا شده و اولین کالایش نصفه دیده
       می‌شد. `proximity` وقتی نزدیک باشی می‌چسباند و بقیهٔ وقت‌ها
       دست به نوار نمی‌زند. */
    scroll-snap-type: x proximity;
    padding-block-end: var(--ds-space-2);
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
}

.hs-rail > * {
    flex: 0 0 auto;
    width: min(220px, 70vw);
    scroll-snap-align: start;
}

/* نواری که سه کالا دارد، تمامِ عرض را ندارد و به لبه می‌چسبد: نصفِ بخش
   سفید می‌ماند و مثلِ یک شبکهٔ خراب دیده می‌شود — فاز ۷۵.

   با `margin: auto` روی دو سرِ نوار و نه با `justify-content: center`:
   حاشیهٔ خودکار فقط فضای **مثبت** را می‌بلعد، پس نواری که از عرض
   بیشتر است هیچ حاشیه‌ای نمی‌گیرد و از ابتدا بریده نمی‌شود.
   `safe center` هم همین را وعده می‌دهد ولی همه‌جا رعایت نمی‌شود، و
   قیمتِ اشتباهش کارتی است که با اسکرول هم به آن نمی‌رسی. */
.hs-rail > :first-child { margin-inline-start: auto; }
.hs-rail > :last-child  { margin-inline-end: auto; }

.hs-rail--narrow > * { width: min(150px, 45vw); }

/* نوارِ «فروشِ ویژه»: کارت‌ها کمی بزرگ‌تر از نوارِ معمولی، چون این
   پرتقاضاترین نوارِ صفحه است. فاز ۷۵. */
.hs-rail--deal > * { width: min(240px, 72vw); }

/* نواری که هیچ محتوایی نداشت، فاصلهٔ خالی هم نگذارد. */
.hs-rail:empty { display: none; }

/* ---------------------------------------------------------------------------
   کاشی‌های تبلیغاتی
   --------------------------------------------------------------------------- */

.hs-tiles {
    display: grid;
    gap: var(--ds-space-3);
    grid-template-columns: 1fr;
}

@media (min-width: 768px) {
    .hs-tiles--two   { grid-template-columns: repeat(2, 1fr); }
    .hs-tiles--three { grid-template-columns: repeat(3, 1fr); }
    .hs-tiles--four  { grid-template-columns: repeat(2, 1fr); }
    .hs-tiles--six   { grid-template-columns: repeat(3, 1fr); }

    /* موزائیک: کاشیِ یکم دو ستون و دو ردیف می‌گیرد، سه‌تای بعدی کنارش
       می‌نشینند. همان چیدمانی که `index.html` با شش کلاسِ بوت‌استرپ
       می‌ساخت، اینجا با چهار خط grid. */
    .hs-tiles--hero {
        grid-template-columns: repeat(3, 1fr);
        grid-auto-rows: 1fr;
        /* کاشیِ کوچکی که بعد از کاشیِ بزرگ می‌آید، سلولِ خالیِ
           مانده را پر کند و ردیفِ تازه باز نکند — فاز ۷۵. */
        grid-auto-flow: dense;
    }
    .hs-tiles--hero > :first-child {
        grid-column: span 2;
        grid-row: span 2;
    }

    /* موزائیک با سه کاشی دقیقاً پر می‌شود (۲×۲ به‌علاوهٔ دو سلول).
       کاشیِ چهارم تنها می‌ماند و یک ردیفِ دوسومْ سفید می‌سازد، پس
       تمامِ عرض را می‌گیرد و ردیف بسته می‌شود — فاز ۷۵. */
    .hs-tiles--hero > :nth-child(4):last-child {
        grid-column: 1 / -1;
    }
}

@media (min-width: 1200px) {
    .hs-tiles--four { grid-template-columns: repeat(4, 1fr); }
    .hs-tiles--six  { grid-template-columns: repeat(6, 1fr); }
}

.hs-tile {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--theme-radius, 8px);
    background: var(--theme-accent-soft, #f3f4f6);
    text-decoration: none;
    color: inherit;
    min-height: var(--hs-tile-height, var(--hs-tile-medium));
}

.hs-tiles--short .hs-tile { --hs-tile-height: var(--hs-tile-short); }
.hs-tiles--tall .hs-tile  { --hs-tile-height: var(--hs-tile-tall); }

/* کاشیِ بزرگِ موزائیک دو برابرِ بقیه است، پس ارتفاعِ ثابتش را کنار
   می‌گذارد و از grid ارتفاع می‌گیرد. */
.hs-tiles--hero > :first-child { min-height: 0; }

.hs-tile__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .35s ease;
}

.hs-tile:hover .hs-tile__image { transform: scale(1.04); }

/* پوششِ ملایم زیرِ نوشته‌ها. بدونِ آن، متنِ روشن روی یک بنرِ روشن
   ناخواناست — و کدام بنر روشن است چیزی نیست که CSS بداند، پس همیشه
   می‌آید و فقط جایی که متن هست. */
.hs-tile__body {
    position: absolute;
    inset-block-end: 0;
    inset-inline: 0;
    padding: var(--ds-space-4) var(--ds-space-3) var(--ds-space-3);
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--ds-space-1);
    background: linear-gradient(
        to top,
        color-mix(in srgb, #000 62%, transparent),
        transparent);
    color: #fff;
}

.hs-tile__title {
    font-size: var(--ds-text-lg);
    font-weight: 800;
    line-height: 1.35;
    margin: 0;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}

.hs-tiles--hero > :first-child .hs-tile__title,
.hs-tiles--wide .hs-tile__title {
    font-size: var(--ds-text-2xl);
}

.hs-tile__subtitle {
    font-size: var(--ds-text-sm);
    line-height: 1.6;
    margin: 0;
    text-shadow: 0 1px 3px rgba(0, 0, 0, .5);
}

/* روی کاشی، دکمه فقط یک فاصلهٔ بالایی اضافه می‌گیرد. خودِ دکمه
   `.ds-button`ِ `foundation.css` است و نشانه‌گذاری هر دو کلاس را
   می‌گذارد (`class="ds-button hs-tile__button"`). */
.hs-tile__button { margin-block-start: var(--ds-space-2); }

/* ---------------------------------------------------------------------------
   نوار مزیت‌ها
   --------------------------------------------------------------------------- */

.hs-features {
    display: grid;
    gap: var(--ds-space-3);
    grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr));
}

.hs-feature {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    padding: var(--ds-space-3);
    border-radius: var(--theme-radius, 8px);
    background: var(--theme-accent-soft, #f8fafc);
    transition: transform .2s ease;
}

.hs-feature:hover { transform: translateY(-2px); }

.hs-feature__icon {
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    object-fit: contain;
}

.hs-feature__title {
    font-size: var(--ds-text-base);
    font-weight: 700;
    margin: 0;
    color: var(--theme-ink, #222);
}

.hs-feature__text {
    font-size: var(--ds-text-xs);
    line-height: 1.6;
    margin: 2px 0 0;
    color: var(--theme-ink-muted, #6b7280);
}

/* ---------------------------------------------------------------------------
   دسته‌بندی و برند
   --------------------------------------------------------------------------- */

.hs-categories {
    display: grid;
    gap: var(--ds-space-3);
    /* `auto-fit` و کمینهٔ بزرگ‌تر — فاز ۷۵: با ۱۳۰ پیکسل، ردیفِ آخر
       معمولاً یک کارتِ تنها داشت و شبکه ناتمام دیده می‌شد. */
    grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
}

.hs-category {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-3) var(--ds-space-2);
    border-radius: var(--theme-radius, 8px);
    border: 1px solid var(--theme-line, #e5e7eb);
    text-decoration: none;
    text-align: center;
    background: var(--theme-surface, #fff);
    transition: border-color .2s ease, box-shadow .2s ease;
}

.hs-category:hover {
    border-color: var(--theme-accent, #0da487);
    box-shadow: 0 4px 14px color-mix(in srgb, var(--theme-accent, #0da487) 14%, transparent);
}

/* تصویرِ دسته تمامِ پهنای کارت را می‌گیرد و مربع می‌ماند — فاز ۷۵.
   ۶۴ پیکسلِ قبلی برای نشانِ یک دسته کوچک بود و کارت عملاً یک کلمهٔ
   داخلِ کادر می‌شد؛ و جای خالی در آن اندازه هیچ‌چیزِ خواندنی نداشت. */
.hs-category img {
    width: 100%;
    aspect-ratio: 1;
    height: auto;
    object-fit: cover;
    border-radius: calc(var(--theme-radius, 8px) - 2px);
    background: var(--theme-accent-soft, #f3f4f6);
}

.hs-category__name {
    font-size: var(--ds-text-sm);
    font-weight: 600;
    color: var(--theme-ink, #222);
    line-height: 1.4;
}

/* فهرستِ عمودی — چیدمانِ سومِ `category_grid`. */
.hs-categories--list {
    grid-template-columns: 1fr;
    gap: 0;
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: var(--theme-radius, 8px);
    overflow: hidden;
}

.hs-categories--list .hs-category {
    flex-direction: row;
    justify-content: flex-start;
    text-align: start;
    border: 0;
    border-block-end: 1px solid var(--theme-line, #e5e7eb);
    border-radius: 0;
}

.hs-categories--list .hs-category:last-child { border-block-end: 0; }
.hs-categories--list .hs-category img { width: 32px; height: 32px; }

.hs-brands {
    display: grid;
    gap: var(--ds-space-3);
    grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr));
    align-items: stretch;
}

.hs-brand {
    display: grid;
    place-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-3);
    border-radius: var(--theme-radius, 8px);
    border: 1px solid var(--theme-line, #e5e7eb);
    background: var(--theme-surface, #fff);
    text-decoration: none;
    color: var(--theme-ink, #222);
    transition: border-color .2s ease;
}

.hs-brand:hover { border-color: var(--theme-accent, #0da487); }
.hs-brand img {
    width: 100%;
    max-width: 100%;
    aspect-ratio: 2 / 1;
    height: auto;
    object-fit: contain;
}
.hs-brand__name { font-size: var(--ds-text-xs); font-weight: 600; }

/* ---------------------------------------------------------------------------
   فهرستِ رتبه‌ای — بخشِ `top_products`
   --------------------------------------------------------------------------- */

.hs-ranked {
    display: grid;
    gap: var(--ds-space-2);
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
    list-style: none;
    margin: 0;
    padding: 0;
}

.hs-ranked__item {
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    padding: var(--ds-space-2);
    border-radius: var(--theme-radius, 8px);
    border: 1px solid var(--theme-line, #e5e7eb);
    background: var(--theme-surface, #fff);
    text-decoration: none;
    color: inherit;
}

.hs-ranked__item:hover { border-color: var(--theme-accent, #0da487); }

/* شمارهٔ رتبه — چیزی که این فهرست را از یک فهرستِ معمولی جدا می‌کند. */
.hs-ranked__number {
    flex: 0 0 auto;
    display: grid;
    place-items: center;
    width: 1.9rem;
    height: 1.9rem;
    border-radius: 50%;
    background: var(--theme-accent-soft, #ecfdf5);
    color: var(--theme-accent-strong, #0da487);
    font-size: var(--ds-text-xs);
    font-weight: 800;
}

.hs-ranked__thumb {
    flex: 0 0 auto;
    width: 56px;
    height: 56px;
    object-fit: contain;
    border-radius: var(--theme-radius-sm, 4px);
}

.hs-ranked__name {
    font-size: var(--ds-text-sm);
    font-weight: 600;
    line-height: 1.5;
    margin: 0;
    /* دو خط و بعد سه‌نقطه: نامِ محصولاتِ این فروشگاه بلندند و بدونِ این،
       ردیف‌های یک فهرست ارتفاع‌های مختلف می‌گیرند. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* ---------------------------------------------------------------------------
   متن آزاد و خبرنامه
   --------------------------------------------------------------------------- */

.hs-rich {
    max-width: 70ch;               /* طولِ خطِ خوانا — نه عرضِ صفحه */
    font-size: var(--ds-text-base);
    line-height: 1.9;
    color: var(--theme-ink-muted, #4b5563);
}

.hs-rich--center { margin-inline: auto; text-align: center; }
.hs-rich--left { margin-inline-end: auto; text-align: left; }

.hs-newsletter {
    display: grid;
    gap: var(--ds-space-3);
    padding: var(--ds-space-5);
    border-radius: var(--theme-radius-lg, 16px);
    background: var(--theme-accent-soft, #ecfdf5);
    text-align: center;
    background-size: cover;
    background-position: center;
}

.hs-newsletter__form {
    display: flex;
    gap: var(--ds-space-2);
    max-width: 460px;
    margin-inline: auto;
    width: 100%;
}

.hs-newsletter__form input {
    flex: 1 1 auto;
    min-width: 0;
    padding: var(--ds-space-2) var(--ds-space-3);
    border-radius: var(--theme-radius, 8px);
    border: 1px solid var(--theme-line, #d1d5db);
    font: inherit;
}

/* ---------------------------------------------------------------------------
   مقاله و ویدیو
   --------------------------------------------------------------------------- */

.hs-articles {
    display: grid;
    gap: var(--ds-space-4);
    grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 1fr));
}

.hs-article {
    /* `relative` برای نشانِ «نمونه» — فاز ۷۶. بدونش آن نشانِ
       `absolute` نزدیک‌ترین جدِ جای‌دار را پیدا می‌کرد، که روی این
       کارت هیچ‌کدام نبودند: سه نشانِ مقاله سرِ خودِ صفحه می‌نشستند. */
    position: relative;
    display: flex;
    flex-direction: column;
    border-radius: var(--theme-radius, 8px);
    overflow: hidden;
    border: 1px solid var(--theme-line, #e5e7eb);
    background: var(--theme-surface, #fff);
    text-decoration: none;
}

.hs-article img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.hs-article__body { padding: var(--ds-space-3); }

.hs-article__title {
    font-size: var(--ds-text-lg);
    font-weight: 700;
    line-height: 1.5;
    margin: 0;
    color: var(--theme-ink, #222);
}

/* ویدیو همان کارتِ مقاله است با یک نشانهٔ پخش رویش.
   دو شبه‌عنصر: دایره، و مثلثی که با `clip-path` از یک مربع بریده می‌شود.
   بدونِ فایلِ تصویر و بدونِ وابستگی به فونتِ آیکون — یعنی در هر چهار قالب
   کار می‌کند حتی اگر آن قالب FontAwesome نداشته باشد. */
.hs-article--video .hs-article__media { position: relative; }

.hs-article--video .hs-article__media::before,
.hs-article--video .hs-article__media::after {
    content: '';
    position: absolute;
    inset: 0;
    margin: auto;
    pointer-events: none;
}

.hs-article--video .hs-article__media::before {
    width: 3.5rem;
    height: 3.5rem;
    border-radius: 50%;
    background: color-mix(in srgb, var(--theme-accent, #0da487) 88%, transparent);
}

.hs-article--video .hs-article__media::after {
    width: 1rem;
    height: 1.1rem;
    background: #fff;
    /* رأس به چپ، چون رابطِ فارسی راست‌به‌چپ است و «جلو» یعنی چپ. */
    clip-path: polygon(100% 0, 100% 100%, 0 50%);
}

/* ---------------------------------------------------------------------------
   ترجیحِ حرکتِ کمتر
   --------------------------------------------------------------------------- */

/* حرکت را برای کسی که خواسته باشد خاموش می‌کند. این یک ترجیح است، نه یک
   سلیقه: بعضی‌ها با انیمیشن سرگیجه می‌گیرند. */
@media (prefers-reduced-motion: reduce) {
    .hs-tile__image,
    .hs-feature,
    .hs-brand,
    .hs-category { transition: none; }
    .hs-tile:hover .hs-tile__image { transform: none; }
    .hs-feature:hover { transform: none; }
    .hs-rail { scroll-behavior: auto; }
}

/* ===========================================================================
   سه بخشی که فاز ۷۵ اضافه کرد
   ===========================================================================

   گزارش: «قالبِ اولیه چقدر بزرگ و چشم‌نواز بود… درسته که داینامیکش کردیم،
   ولی نباید تبدیل به یک قالبِ ساده بشه.»

   چهارده بخشِ قبلی همه یک شکل بودند: یک نوارِ تمام‌عرض، زیرِ نوارِ قبلی.
   صفحه‌ای که از بالا تا پایین همین است — هرچقدر هم محتوا داشته باشد —
   «ساده» به‌نظر می‌رسد. سه چیزی که اینجا اضافه شد، سه شکافِ همان صفحهٔ
   اولیه‌اند: تایپوگرافیِ روی تصویر، ترکیبِ افقی، و فوریتِ واقعی.

   مثلِ بقیهٔ این فایل، هیچ رنگِ سفت‌کدشده‌ای اینجا نیست: همه‌چیز از
   توکن‌های `--theme-*` و `--ds-*` می‌آید، پس هر قالبی که این‌ها را ارث
   ببرد، با هویتِ خودش رندر می‌شود.
   =========================================================================== */

/* ---------------------------------------------------------------------------
   hero — بنرِ بزرگِ بالای صفحه
   --------------------------------------------------------------------------- */

.hs-hero {
    position: relative;
    /* تمام‌عرض، حتی داخلِ ظرفی که padding دارد: این بنر باید از لبه تا
       لبه برود، و همان است که «بزرگ» نشانش می‌دهد. */
    width: 100%;
    overflow: hidden;
    margin-block-end: var(--hs-section-gap);
    background: var(--ds-surface-2, #f1f5f9);
}

.hs-hero--short  { --hs-hero-height: clamp(14rem, 30vw, 22rem); }
.hs-hero--medium { --hs-hero-height: clamp(18rem, 38vw, 30rem); }
.hs-hero--tall   { --hs-hero-height: clamp(22rem, 46vw, 38rem); }
.hs-hero--full   { --hs-hero-height: min(88vh, 46rem); }

/* رادیوها فقط حالت نگه می‌دارند و دیده نمی‌شوند. `position: absolute` و
   نه `display: none`: گرهی که نمایش ندارد، فوکوس هم نمی‌گیرد و آن‌وقت
   ناوبری با صفحه‌کلید می‌شکند. */
.hs-hero__radio {
    position: absolute;
    opacity: 0;
    pointer-events: none;
    width: 1px;
    height: 1px;
}

.hs-hero__stage {
    position: relative;
    height: var(--hs-hero-height, 30rem);
}

.hs-hero__slide {
    position: absolute;
    inset: 0;
    opacity: 0;
    visibility: hidden;
    transition: opacity .45s ease;
}

/* هر رادیو، اسلایدِ هم‌شمارهٔ خودش را روشن می‌کند.
   `~` روی خواهرها کار می‌کند، پس رادیوها باید **پیش از** صحنه بیایند. */
.hs-hero__radio:nth-of-type(1):checked ~ .hs-hero__stage .hs-hero__slide:nth-child(1),
.hs-hero__radio:nth-of-type(2):checked ~ .hs-hero__stage .hs-hero__slide:nth-child(2),
.hs-hero__radio:nth-of-type(3):checked ~ .hs-hero__stage .hs-hero__slide:nth-child(3) {
    opacity: 1;
    visibility: visible;
}

.hs-hero__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* پوشش، تا متنِ روشن روی تصویرِ روشن هم خوانا بماند. مالک از قبل
   نمی‌داند تصویری که آپلود می‌کند روشن است یا تیره. */
.hs-hero__slide::after {
    content: '';
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.hs-hero--overlay-none  .hs-hero__slide::after { display: none; }
.hs-hero--overlay-soft  .hs-hero__slide::after { background: rgba(0, 0, 0, .28); }
.hs-hero--overlay-strong .hs-hero__slide::after { background: rgba(0, 0, 0, .5); }

/* ── سایهٔ کناری همان سمتی را تیره کند که متن آنجاست — فاز ۷۵ ────────
   گرادیانِ CSS از `direction` پیروی نمی‌کند، پس یک تعریفِ ثابت یعنی
   نیمی از انتخاب‌ها متن را روی روشن‌ترین جای تصویر می‌گذارند: سفید
   روی سفید، که خوانده نمی‌شود. */
.hs-hero--overlay-side  .hs-hero__slide::after {
    background: linear-gradient(to left,
        rgba(0, 0, 0, .72) 0%, rgba(0, 0, 0, .45) 45%, rgba(0, 0, 0, 0) 78%);
}
.hs-hero--overlay-side.hs-hero--text-left .hs-hero__slide::after {
    background: linear-gradient(to right,
        rgba(0, 0, 0, .72) 0%, rgba(0, 0, 0, .45) 45%, rgba(0, 0, 0, 0) 78%);
}
.hs-hero--overlay-side.hs-hero--text-center .hs-hero__slide::after {
    background: linear-gradient(to top,
        rgba(0, 0, 0, .68) 0%, rgba(0, 0, 0, .3) 60%, rgba(0, 0, 0, .1) 100%);
}

.hs-hero__inner {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    z-index: 1;
}

.hs-hero__body {
    max-width: min(34rem, 92%);
    color: #fff;
    /* سایهٔ متن، لایهٔ دومِ همان مسئلهٔ خوانایی: اگر مالک پوشش را خاموش
       کند، متن هنوز روی تصویرِ شلوغ خوانده می‌شود. */
    text-shadow: 0 1px 12px rgba(0, 0, 0, .45);
}

.hs-hero--text-center .hs-hero__inner { justify-content: center; text-align: center; }
.hs-hero--text-center .hs-hero__body  { margin-inline: auto; }
/* ── «راست» یعنی راستِ تصویر، نه «انتهای جهتِ نوشتار» — فاز ۷۵ ──────
   `flex-start`/`flex-end` در صفحهٔ راست‌به‌چپ برعکس می‌شوند، پس
   انتخابِ «راست» متن را به چپ می‌برد و مالک فکر می‌کند تنظیم کار
   نمی‌کند. `left`/`right` فیزیکی‌اند و دقیقاً همان چیزی را می‌گویند
   که در فرم نوشته شده؛ اعلانِ منطقیِ قبلشان برای مرورگرِ قدیمی‌تر
   می‌ماند و در همین صفحهٔ راست‌به‌چپ همان نتیجه را می‌دهد. */
.hs-hero--text-left  .hs-hero__inner {
    justify-content: flex-end;
    justify-content: left;
}
.hs-hero--text-right .hs-hero__inner {
    justify-content: flex-start;
    justify-content: right;
}

.hs-hero__eyebrow {
    font-size: var(--ds-text-sm);
    font-weight: 700;
    letter-spacing: .04em;
    margin: 0 0 var(--ds-space-2);
    padding: .35em 1em;
    display: inline-block;
    border-radius: 999px;
    background: var(--theme-accent, #0da487);
    color: #fff;
    text-shadow: none;
}

.hs-hero__title {
    font-size: clamp(1.6rem, 4.4vw, 3.1rem);
    font-weight: 800;
    line-height: 1.25;
    margin: 0 0 var(--ds-space-2);
}

.hs-hero__subtitle {
    font-size: clamp(.95rem, 1.6vw, 1.15rem);
    line-height: 2;
    margin: 0 0 var(--ds-space-3);
    opacity: .93;
}

.hs-hero__button { text-shadow: none; }

.hs-hero__dots {
    position: absolute;
    inset-block-end: var(--ds-space-3);
    inset-inline: 0;
    display: flex;
    justify-content: center;
    gap: var(--ds-space-2);
    z-index: 2;
}

.hs-hero__dot {
    width: 2.25rem;
    height: .35rem;
    border-radius: 999px;
    background: rgba(255, 255, 255, .45);
    cursor: pointer;
    transition: background .2s, width .2s;
}

.hs-hero__dot:hover { background: rgba(255, 255, 255, .75); }

.hs-hero__radio:nth-of-type(1):checked ~ .hs-hero__dots .hs-hero__dot:nth-child(1),
.hs-hero__radio:nth-of-type(2):checked ~ .hs-hero__dots .hs-hero__dot:nth-child(2),
.hs-hero__radio:nth-of-type(3):checked ~ .hs-hero__dots .hs-hero__dot:nth-child(3) {
    background: #fff;
    width: 3.25rem;
}

@media (max-width: 640px) {
    /* روی موبایل، متنِ وسط‌چین بهتر می‌نشیند: ستونِ باریک، هر چینشِ
       دیگری را به یک ستونِ کج تبدیل می‌کند. */
    .hs-hero__inner { justify-content: center; text-align: center; }
    .hs-hero__body { margin-inline: auto; }
    .hs-hero--full { --hs-hero-height: 70vh; }
}

/* ---------------------------------------------------------------------------
   split_promo — بنر و محصولات، کنارِ هم
   --------------------------------------------------------------------------- */

.hs-split {
    display: grid;
    grid-template-columns: minmax(0, 17rem) minmax(0, 1fr);
    gap: var(--ds-space-4);
    align-items: stretch;
}

/* `order` و نه دو تعریفِ جدا از شبکه: محتوای HTML یکی است و فقط جای
   دیداری‌اش عوض می‌شود.

   ── و چرا ستون‌ها هم باید جابه‌جا شوند — فاز ۷۵ ────────────────────

   `order` فقط تصمیم می‌گیرد کدام عنصر در کدام **سلول** بنشیند؛
   اندازهٔ ستون‌ها سرِ جایشان می‌مانند. یعنی با `order` تنها، محصولات
   به ستونِ ۱۷ریمی می‌رفتند و بنر تمامِ باقی صفحه را می‌گرفت: یک
   تصویرِ غول‌پیکر و یک ستونِ باریکِ تک‌کارته. اندازه‌ها هم باید با
   محتوا جابه‌جا شوند. */
.hs-split--left {
    grid-template-columns: minmax(0, 1fr) minmax(0, 17rem);
}
.hs-split--left .hs-split__banner { order: 2; }
.hs-split--left .hs-split__products { order: 1; }

.hs-split--no-banner { grid-template-columns: minmax(0, 1fr); }

.hs-split__banner {
    position: relative;
    display: block;
    overflow: hidden;
    border-radius: var(--theme-radius, 12px);
    min-height: 22rem;
    color: #fff;
    text-decoration: none;
}

.hs-split__image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform .5s ease;
}

.hs-split__banner:hover .hs-split__image { transform: scale(1.05); }

.hs-split__body {
    position: relative;
    z-index: 1;
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    padding: var(--ds-space-4);
    background: linear-gradient(to top,
        rgba(0, 0, 0, .75) 0%, rgba(0, 0, 0, .25) 55%, rgba(0, 0, 0, 0) 100%);
    text-shadow: 0 1px 10px rgba(0, 0, 0, .4);
}

.hs-split__title {
    font-size: var(--ds-text-xl);
    font-weight: 800;
    margin: 0 0 var(--ds-space-1);
}

.hs-split__subtitle {
    font-size: var(--ds-text-sm);
    margin: 0 0 var(--ds-space-3);
    opacity: .92;
}

.hs-split__button { align-self: flex-start; text-shadow: none; }

.hs-split__products { min-width: 0; }

/* شبکهٔ فشرده‌تر، چون این ستون از یک بخشِ تمام‌عرض باریک‌تر است و کارتِ
   بزرگ داخلش دو ستونه می‌ماند.

   `auto-fit` و نه `auto-fill` — همان استدلالی که سرِ `.hs-grid` نوشته
   شده: ستونِ خالی باید جمع شود، نه اینکه نیمی از نوار سفید بماند. */
.hs-grid--compact {
    grid-template-columns: repeat(auto-fit, minmax(clamp(9rem, 16vw, 12rem), 1fr));
}

/* ── مرزِ شکست ۹۹۲ است و نه ۹۰۰ — فاز ۷۵ ───────────────────────────
   شبکهٔ محصولات در همان ۹۹۲ به ستون‌های تمام می‌رسد. با دو مرزِ
   متفاوت، یک نوارِ ۹۰۱ تا ۹۹۱ پیکسلی می‌ماند که در آن بنر و محصولات
   کنارِ هم‌اند ولی شبکه هنوز قاعدهٔ صفحهٔ باریک را دارد — باریک‌ترین
   جایی که بنر کنارِ محصول معنا دارد، از آن هم باریک‌تر است. */
@media (max-width: 991.98px) {
    .hs-split { grid-template-columns: minmax(0, 1fr); }
    .hs-split--left { grid-template-columns: minmax(0, 1fr); }
    /* روی موبایل بنر همیشه اول می‌آید، هر سمتی که انتخاب شده باشد:
       ترتیبِ «راست/چپ» در یک ستون معنا ندارد. */
    .hs-split--left .hs-split__banner { order: 0; }
    .hs-split--left .hs-split__products { order: 0; }
    .hs-split__banner { min-height: 14rem; }
}

/* ---------------------------------------------------------------------------
   countdown_deal — فروشِ ویژه با مهلت
   --------------------------------------------------------------------------- */

.hs-deal {
    position: relative;
    padding-block: var(--ds-space-5);
    margin-block-end: var(--hs-section-gap);
    background: var(--ds-surface-2, #f1f5f9);
    background-size: cover;
    background-position: center;
}

/* زمینهٔ تیره زیرِ تصویر، تا متن و کارت‌ها روی هر تصویری خوانا بمانند.

   `.86` و نه `.72` — فاز ۷۵: تصویری که نوشته یا خط دارد (و جانشینِ
   سیدر هر دو را دارد) از پشتِ پردهٔ رقیق‌تر پیدا بود و پشتِ کارت‌های
   سفید نویز می‌ساخت. یک نوارِ «فروشِ ویژه» باید زمینه‌اش بماند
   زمینه. */
.hs-deal--imaged::before {
    content: '';
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .86);
}

.hs-deal > * { position: relative; z-index: 1; }

.hs-deal__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--ds-space-3);
    margin-block-end: var(--ds-space-4);
}

.hs-deal__titles { flex: 1 1 14rem; min-width: 0; }

.hs-deal__title {
    font-size: var(--ds-text-2xl);
    font-weight: 800;
    margin: 0;
}

.hs-deal__subtitle {
    font-size: var(--ds-text-sm);
    margin: var(--ds-space-1) 0 0;
    opacity: .8;
}

.hs-deal__timer {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: .55rem 1rem;
    border-radius: 999px;
    background: var(--theme-accent, #0da487);
    color: #fff;
}

.hs-deal__timer-label { font-size: var(--ds-text-xs); opacity: .9; }

/* عدد با ارقامِ هم‌عرض، وگرنه هر ثانیه پهنای جعبه می‌پرد. */
.hs-deal__clock {
    font-size: var(--ds-text-lg);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.hs-deal--imaged .hs-deal__title,
.hs-deal--imaged .hs-deal__subtitle { color: #fff; }

@media (max-width: 640px) {
    .hs-deal__head { justify-content: center; text-align: center; }
    .hs-deal__titles { flex-basis: 100%; }
}


/* ---------------------------------------------------------------------------
   کارت‌های هم‌قد — فاز ۷۵
   ---------------------------------------------------------------------------

   نامِ کالا یک خط است یا دو، و بدونِ این قاعده کارت‌ها هرکدام به قدِ
   متنِ خودشان درمی‌آیند. نتیجه‌اش ردیفی از کارت‌های ناهم‌ارتفاع است که
   دکمه‌های «افزودن به سبد»شان روی یک خط نمی‌نشینند.

   اینجا فقط **قد** داده می‌شود و نه چیدمانِ داخلِ کارت: هر قالب کارتِ
   خودش را دارد و این فایل نباید نامِ هیچ‌کدامشان را بداند. توزیعِ
   فضای داخلی کارِ خودِ قالب است — در فست‌کارت، `theme-design.css`. */

.hs-grid > *,
.hs-rail > * {
    height: 100%;
}


/* ---------------------------------------------------------------------------
   دو اصلاحِ چیدمانی — فاز ۷۵
   --------------------------------------------------------------------------- */

/* ── خبرنامه روی تصویر ──────────────────────────────────────────────
   همان قاعده‌ای که `hs-deal--imaged` دارد: زمینه باید زمینه بماند. */
.hs-newsletter--imaged { position: relative; isolation: isolate; }

.hs-newsletter--imaged::before {
    content: '';
    position: absolute;
    inset: 0;
    z-index: -1;
    border-radius: inherit;
    background: rgba(15, 23, 42, .78);
}

.hs-newsletter--imaged .hs-title,
.hs-newsletter--imaged .hs-subtitle { color: #fff; }

/* ── شبکهٔ محصولاتِ کنارِ بنر، ستونِ ثابت ─────────────────────────────
   `auto-fit` اینجا به پهنای ستونِ باقی‌مانده وابسته است و هر بار عددِ
   دیگری درمی‌آورد: پنج ستون با هشت کالا یعنی ردیفِ دومِ سه‌تایی و یک
   گوشهٔ خالی. چهار ستونِ ثابت با همان هشت کالا دو ردیفِ کامل می‌دهد —
   و زیرِ ۹۹۲ پیکسل دوباره به همان `auto-fit` برمی‌گردد. */
@media (min-width: 992px) {
    .hs-split .hs-grid--compact {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }
}

/* ---------------------------------------------------------------------------
   نشانِ «نمونه» — فاز ۷۶
   ---------------------------------------------------------------------------

   وقتی فروشگاه هنوز کالا یا دسته‌ای ندارد، بخش‌ها ردیفِ نمونه نشان
   می‌دهند تا چیدمان کامل دیده شود (`appearance/home/samples.py`).
   ردیفِ نمونه‌ای که شبیهِ ردیفِ واقعی باشد، همان چیزی است که فردا کسی
   در یک گزارش به‌عنوان فروش می‌شمردش. پس نشان می‌خورد. */

.hs-sample-badge {
    /* هر کارتی که این نشان را می‌گیرد باید خودش `position: relative`
       باشد، وگرنه نشان نزدیک‌ترین جدِ جای‌دار را پیدا می‌کند و سرِ
       صفحه می‌نشیند. `tests/test_home_sections.py` جدولِ کارت‌ها را
       دارد؛ کارتِ تازه باید همان‌جا هم اضافه شود. */
    position: absolute;
    inset-block-start: var(--ds-space-2);
    inset-inline-start: var(--ds-space-2);
    z-index: 2;
    padding: .15rem .5rem;
    border-radius: 999px;
    font-size: var(--ds-text-xs);
    font-weight: 700;
    line-height: 1.6;
    color: #fff;
    background: rgba(15, 23, 42, .72);
    pointer-events: none;
}

/* ---------------------------------------------------------------------------
   کاشیِ دسته‌بندی — فاز ۷۶
   ---------------------------------------------------------------------------

   جای `hs-category`ِ کادردار را گرفت: تصویرِ گِرد روی زمینهٔ ملایم و
   نامِ زیرش، همان شکلی که قالب برای دسته‌بندی‌هایش دارد. کادرِ سفیدِ
   قبلی روی صفحه‌ای که بقیه‌اش بنر و کارتِ رنگی بود، خالی به نظر
   می‌رسید. */

.hs-cat-tile {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--ds-space-2);
    text-align: center;
    text-decoration: none;
    color: var(--theme-ink, #222);
    height: 100%;
}

.hs-cat-tile__media {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 1;
    border-radius: 50%;
    overflow: hidden;
    background: var(--theme-accent-soft, #f3f4f6);
    transition: transform .25s ease, box-shadow .25s ease;
}

.hs-cat-tile__media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.hs-cat-tile:hover .hs-cat-tile__media {
    transform: translateY(-4px);
    box-shadow: 0 10px 24px color-mix(
        in srgb, var(--theme-accent, #0da487) 22%, transparent);
}

.hs-cat-tile__name {
    font-size: var(--ds-text-sm);
    font-weight: 600;
    line-height: 1.5;
}

@media (prefers-reduced-motion: reduce) {
    .hs-cat-tile:hover .hs-cat-tile__media { transform: none; }
}

/* ---------------------------------------------------------------------------
   کاشیِ تبلیغاتی روی نشانه‌گذاریِ خودِ قالب — فاز ۷۶
   ---------------------------------------------------------------------------

   `banner-contain`ِ قالب ارتفاعش را از خودِ تصویر می‌گیرد. برای بنری که
   مالک آپلود می‌کند این یعنی سه کاشیِ کنارِ هم با سه قدِ متفاوت، و
   برای تصویرِ جانشینِ ۱۲۰۰×۹۰۰ یعنی کاشیِ بسیار بلند که کلِ صفحه را
   می‌بلعد.

   قد از تنظیمِ «بلندیِ کاشی» می‌آید — همان سه گزینه‌ای که در پنل هست —
   و تصویر با `cover` داخلش می‌نشیند. یعنی مالک هر تصویری با هر نسبتی
   بگذارد، ردیف مرتب می‌ماند. */

.hs-banners .hs-banner {
    height: var(--hs-tile-height, var(--hs-tile-medium));
}

.hs-banners--short .hs-banner { --hs-tile-height: var(--hs-tile-short); }
.hs-banners--tall  .hs-banner { --hs-tile-height: var(--hs-tile-tall); }

/* موزائیک: کاشیِ اول دو برابرِ عرض دارد، پس قدِ بلندتر هم می‌خواهد
   وگرنه یک نوارِ پهن و کوتاه می‌شود. */
@media (min-width: 1200px) {
    .hs-banners [class*="col-xl-6"] .hs-banner {
        height: calc(var(--hs-tile-height, var(--hs-tile-medium)) * 1.25);
    }
}

.hs-banner > picture {
    display: block;
    width: 100%;
    height: 100%;
}

.hs-banner > picture > img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* بنرِ تمام‌عرض: یکی است و ردیف ندارد، پس قدش را خودش می‌گیرد. */
.hs-banners--wide .hs-banner {
    height: var(--hs-tile-height, var(--hs-tile-medium));
}
