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

   این فایل **بخش‌های صفحهٔ اصلی** را می‌چیند و بس. مقیاس‌ها، دکمه، کارت،
   حلقهٔ 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;
}

/* ---------------------------------------------------------------------------
   فهرستِ عمودیِ دسته‌ها — چیدمانِ «list»ِ `category_grid`

   «شبکهٔ دسته‌بندی در حالتِ فهرستِ عمودی کلِ صفحه را می‌گیرد.» می‌گرفت: هر
   دسته یک ردیفِ تمام‌عرض با یک تصویرِ ۳۲ پیکسلی بود — جدولی به پهنای صفحه
   با یک کلمه در هر سطر.

   حالا شکلش را **جای خودش** تعیین می‌کند و نه پهنای پنجره (container
   query): در ستونِ باریکِ کنارِ محصولات یک منوی کناری است — همان چیزی که
   «فهرستِ عمودی» قرار بود باشد — و در عرضِ کامل، فهرستی چندستونه از
   ردیف‌های فشرده.
   --------------------------------------------------------------------------- */

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

.hs-catlist__item {
    position: relative;
    display: flex;
    align-items: center;
    gap: var(--ds-space-3);
    min-height: 56px;
    padding: var(--ds-space-2) var(--ds-space-3);
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: var(--theme-radius, 8px);
    background: var(--theme-surface, #fff);
    color: var(--theme-ink, #222);
    text-decoration: none;
    transition: border-color .2s ease, background-color .2s ease, color .2s ease;
}

.hs-catlist__item img {
    flex: 0 0 40px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
    object-fit: cover;
    background: var(--theme-accent-soft, #f3f4f6);
}

.hs-catlist__name {
    flex: 1 1 auto;
    min-width: 0;
    font-size: var(--ds-text-sm);
    font-weight: 600;
    line-height: 1.5;
    overflow-wrap: anywhere;
}

.hs-catlist__chev {
    flex: 0 0 16px;
    width: 16px;
    height: 16px;
    opacity: .45;
    transition: transform .2s ease, opacity .2s ease;
}

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

.hs-catlist__item:hover .hs-catlist__chev { opacity: 1; transform: translateX(-3px); }

.hs-catlist .hs-sample-badge { inset-block-start: 4px; inset-inline-start: auto; inset-inline-end: 36px; }

/* در ستونِ باریک: یک کارتِ پیوسته با خطِ جداکننده، مثلِ منوی دسته‌های
   فروشگاه‌های بزرگ. */
@container (max-width: 22rem) {
    .hs-catlist {
        gap: 0;
        border: 1px solid var(--theme-line, #e5e7eb);
        border-radius: var(--theme-radius, 8px);
        overflow: hidden;
        background: var(--theme-surface, #fff);
    }
    .hs-catlist__item {
        border: 0;
        border-radius: 0;
        border-block-end: 1px solid var(--theme-line, #e5e7eb);
        min-height: 52px;
    }
    .hs-catlist li:last-child .hs-catlist__item { border-block-end: 0; }
    .hs-catlist__item:hover,
    .hs-catlist__item:focus-visible { background: var(--theme-accent-soft, #f3f4f6); }
}

/* ---------------------------------------------------------------------------
   برندها — `brand_strip`

   «یک برند مثلِ یک بنرِ بزرگ کلِ صفحه را می‌گیرد.» علتش `auto-fit` با
   `1fr` بود: ستون‌هایی که جا مانده‌اند فرو می‌ریزند و ستون‌های باقی‌مانده
   کش می‌آیند تا ردیف پر شود. با `auto-fill` و پهنای بیشینه، ستون‌ها
   هم‌اندازه می‌مانند و ردیف وسطِ صفحه می‌نشیند — یک برند یک کارت است.
   --------------------------------------------------------------------------- */

.hs-brands {
    list-style: none;
    margin: 0;
    padding: 0;
}

/* فلکسِ پیچان با پهنای ثابت و نه grid: `auto-fill` خانه‌های خالیِ ته ردیف را
   نگه می‌دارد و یک برندِ تنها گوشهٔ راست می‌ماند؛ فلکس با `center` ردیفِ
   ناتمام را وسط می‌چیند. */
.hs-brands--grid,
.hs-brands--logos {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--ds-space-3);
}

.hs-brands--grid > li { flex: 0 0 auto; width: clamp(8.5rem, 22vw, 10.5rem); }

.hs-brand {
    position: relative;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--ds-space-2);
    height: 100%;
    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, box-shadow .2s ease, transform .2s ease;
}

.hs-brand:hover,
.hs-brand:focus-visible {
    border-color: var(--theme-accent, #0da487);
    box-shadow: 0 6px 18px color-mix(in srgb, var(--theme-accent, #0da487) 14%, transparent);
    transform: translateY(-2px);
}

.hs-brand__logo {
    display: grid;
    place-items: center;
    width: 100%;
    aspect-ratio: 3 / 2;
}

.hs-brand__logo img {
    max-width: 100%;
    max-height: 100%;
    width: auto;
    height: auto;
    object-fit: contain;
}

.hs-brand__name {
    font-size: var(--ds-text-xs);
    font-weight: 600;
    text-align: center;
    line-height: 1.5;
}

/* دیوارِ لوگو: خانه‌های کوچک‌ترِ بی‌سایه، بی‌فاصلهٔ اضافه — برای ستونِ
   باریک یا فروشگاهی با برندهای زیاد. */
.hs-brands--logos { gap: var(--ds-space-2); }
.hs-brands--logos > li { flex: 0 0 auto; width: 7.5rem; }

.hs-brands--logos .hs-brand { padding: var(--ds-space-2); }
.hs-brands--logos .hs-brand:hover { transform: none; box-shadow: none; }

/* لوگوی خاکستری تا وقتی رویش نرفته‌ای — دیوارِ لوگو آرام می‌ماند و برندِ
   زیرِ اشاره رنگ می‌گیرد. */
@media (hover: hover) {
    .hs-brands--logos .hs-brand__logo img { filter: grayscale(1); opacity: .75; transition: filter .2s ease, opacity .2s ease; }
    .hs-brands--logos .hs-brand:hover .hs-brand__logo img { filter: none; opacity: 1; }
}

/* نوارِ افقی: کارت‌ها همان کارت‌اند، در `hs-rail`. */
.hs-brands--rail .hs-brand { height: 100%; }

/* ---------------------------------------------------------------------------
   فهرستِ رتبه‌ای — بخشِ `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; }
    .hs-brand:hover, .hs-brand:focus-visible { transform: none; }
    .hs-catlist__item:hover .hs-catlist__chev { transform: none; }
}

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

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

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

   مثلِ بقیهٔ این فایل، هیچ رنگِ سفت‌کدشده‌ای اینجا نیست: همه‌چیز از
   توکن‌های `--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));
}

/* ==========================================================================
   فاز ۷۷ — بخش‌هایی که از یازده صفحهٔ اصلیِ قالبِ اصلی آمدند
   ==========================================================================

   هشت نوعِ تازه اضافه شد و هفت‌تایشان **یک خط CSS هم لازم نداشتند**:
   `deal-box`, `bank-offer`, `review-box`, `offer-product`,
   `product-list`, `shop-category-box`, `category-box-list`,
   `tab-style-color` همه از قبل در `minified-style.css`ِ خودِ قالب
   هستند. همین بود که باعث شد بخش‌های تازه شبیهِ بقیهٔ فروشگاه
   دربیایند و نه شبیهِ چیزی که کسی بعداً چسبانده.

   آنچه اینجا می‌آید فقط شکافِ باقی‌مانده است:

   ۱ `cate-box` که در بستهٔ اصلی هست و در نسخهٔ این پروژه نیست؛
   ۲ چند `hs-*` که چسبِ بینِ نشانه‌گذاریِ قالب و نوارِ افقیِ ماست.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   کاشیِ فشردهٔ دسته — سبکِ `panel` در `category_strip`
   --------------------------------------------------------------------------

   از `css/style.css`ِ بستهٔ اصلی آمده، جایی که زیرِ
   `.category-panel .category-panel-slider .cate-box` نوشته شده بود.

   دو تغییرِ عمدی نسبت به اصل:

   * انتخابگر تخت شد. اصل سه سطح والد می‌خواست — `section.category-panel`
     و بعد `div.category-panel-slider` — که هر دو فقط برای slick وجود
     داشتند. ما نوارمان `hs-rail` است، پس آن دو والد هیچ‌وقت نمی‌آیند و
     قاعده هیچ‌وقت اجرا نمی‌شد.
   * `margin-top: -50px`ِ `.category-panel` نیامد. آن عدد برای صفحه‌ای
     بود که این نوار را عمداً روی بنرِ بالای سرش می‌کشید. اینجا بخش هر
     جای صفحه می‌تواند بنشیند، و یک حاشیهٔ منفیِ ثابت یعنی هرجا جز آن
     یک جا، روی بخشِ قبلی می‌افتد.

   اندازه‌ها همان `calc()`های سیالِ اصل‌اند: قالب همه‌جا همین کار را
   می‌کند و عددِ ثابت گذاشتن اینجا یعنی این یک کاشی، تنها چیزی باشد
   که با بقیهٔ صفحه هم‌نفس نیست.
   -------------------------------------------------------------------------- */

.cate-box {
    position: relative;
    display: block;
    text-align: center;
    background-color: #f8f8f8;
    padding: calc(19px + 16 * (100vw - 320px) / 1600)
             calc(11px + 4 * (100vw - 320px) / 1600);
    border-radius: 8px;
    overflow: hidden;
    border: 1px solid transparent;
    transition: all .3s ease-in-out;
}

.cate-box:hover { border-color: #ddd; }

.cate-box img {
    width: calc(39px + 6 * (100vw - 320px) / 1600);
    height: calc(39px + 6 * (100vw - 320px) / 1600);
    object-fit: contain;
    margin: 0 auto;
    transition: all .3s ease-in-out;
}

.cate-box span {
    display: block;
    font-size: calc(14px + 2 * (100vw - 320px) / 1600);
    margin-top: calc(6px + 4 * (100vw - 320px) / 1600);
    margin-bottom: -3px;
    color: #222;
}

/* --------------------------------------------------------------------------
   عرضِ کارت در نوارهای تازه
   --------------------------------------------------------------------------

   `hs-rail > *` پیش‌فرض `min(220px, 70vw)` است، که اندازهٔ کارتِ محصول
   است. دو نوارِ تازه کارتِ هم‌اندازه ندارند:

   `--wide`    کارتِ دستهٔ سبکِ «کارتی» تصویر و دکمه دارد و در ۲۲۰
               پیکسل دکمه‌اش زیرِ تصویر می‌شکند.
   `--banner`  بنر تمام‌عرض است؛ ۲۲۰ پیکسل از آن یک تمبر می‌سازد.
               `85vw` روی موبایل عمدی است: لبهٔ بنرِ بعدی پیداست، که
               تنها نشانهٔ بصریِ «اینجا می‌شود اسکرول کرد» است.
   -------------------------------------------------------------------------- */

.hs-rail--wide > *   { width: min(300px, 78vw); }
.hs-rail--banner > * { width: min(760px, 85vw); }

/* قدِ بنر در نوار.
   `.hs-banners .hs-banner { height: … }` قدِ کاشی را می‌دهد، ولی به
   ظرفِ شبکه بسته است و نوارِ `banner_carousel` آن ظرف را ندارد. بدونِ
   این خط، `.banner-contain` قدش را از محتوایش می‌گیرد و چون تصویر
   `position:absolute` است، آن محتوا هیچ است: بخش فقط عنوانش را نشان
   می‌داد و زیرش خالی بود. در مرورگر دیده شد، نه در تست. */
.hs-rail--banner .hs-banner {
    height: var(--hs-tile-height, var(--hs-tile-medium));
}

/* --------------------------------------------------------------------------
   شمارندهٔ داخلِ کارتِ `deal_grid`
   --------------------------------------------------------------------------

   همان `hs-deal__timer` است که `countdown_deal` دارد، ولی آن یکی سرِ
   یک بخشِ تمام‌عرض می‌نشیند و این یکی کفِ یک کارتِ باریک. بدونِ این
   دو خط، برچسب و ساعت کنارِ هم می‌مانند و کارت را پهن می‌کنند.
   -------------------------------------------------------------------------- */

.hs-deal__timer--card {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem;
    margin-top: .75rem;
    /* بازنشانیِ قرصِ سبز — و این تزئینی نیست.
       `.hs-deal__timer` برای سرِ یک بخشِ تمام‌عرض ساخته شده: قرصی
       پررنگ که باید از دور دیده شود. همان قرص کفِ یک کارتِ باریک
       بزرگ‌ترین چیزِ کارت می‌شود و نامِ کالا را می‌بلعد. */
    padding: 0;
    border-radius: 0;
    background: none;
    color: inherit;
    font-size: .85em;
}

.hs-deal__timer--card .hs-deal__timer-label { color: #4a5568; }

.hs-deal__timer--card .hs-deal__clock {
    font-size: 1em;
    color: var(--theme-color, #0da487);
    font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   نشانِ «نمونه» در سطرِ فشرده
   --------------------------------------------------------------------------

   `hs-sample-badge` یک برچسبِ مطلق روی تصویر است و در سطرِ یک‌خطیِ
   `product_columns` جا نمی‌شود — روی نام می‌افتد. این یکی در جریانِ
   عادیِ متن می‌نشیند.

   چرا اصلاً نشان لازم است: کالای نمونه‌ای که از کالای واقعی
   تشخیص داده نشود، فردا در یک گزارش به‌عنوان فروش شمرده می‌شود.
   -------------------------------------------------------------------------- */

.hs-sample-tag {
    display: inline-block;
    padding: 0 .4em;
    border-radius: 4px;
    background: #fff3cd;
    color: #7a5b00;
    font-size: .72em;
    line-height: 1.6;
}

/* --------------------------------------------------------------------------
   نوارِ پیشنهادِ تمام‌عرض
   --------------------------------------------------------------------------

   `banner-contain` خودِ قالب ارتفاعش را از تصویرِ `picture.bg-img`ِ
   داخلش می‌گیرد. این نوار تصویرِ محتوایی ندارد — زمینه‌اش تزئینی است
   و با `background-image` می‌آید — پس بدونِ یک ارتفاعِ اعلام‌شده به
   بلندیِ متنش جمع می‌شود و دیگر یک «نوار» نیست.

   `min-height` و نه `height`: متنِ بلندتر باید بتواند نوار را بکشد،
   نه اینکه از آن بزند بیرون.
   -------------------------------------------------------------------------- */

.hs-offer-band {
    min-height: clamp(160px, 22vw, 280px);
    display: flex;
    align-items: center;
    background-size: cover;
    background-position: center;
    background-color: var(--theme-color, #0da487);
    border-radius: 10px;
    overflow: hidden;
}

.hs-offer-band .banner-details { width: 100%; }
.hs-offer-band--light, .hs-offer-band--light .offer-text { color: #fff; }
.hs-offer-band--dark,  .hs-offer-band--dark .offer-text  { color: #222; }

/* بدونِ زمینه، نوار یک مستطیلِ رنگیِ تخت است — و فاز ۷۷ یک گرادیان
   رویش گذاشت. مالک هنوز «تخت» دیدش:

     «یه بخش گذاشتی ارسالِ رایگان … اونجا عکس پیشفرض نذاشتی براش.»

   حق داشت: گرادیانِ دو-توقفه از یک رنگِ تخت فقط کمی بهتر است.

   حالا یک تصویرِ تزئینیِ واقعی روی آن گرادیان می‌نشیند
   (`_shared/img/offer-band.svg`) — دایره‌ها و موج‌های **سفیدِ
   کم‌شفاف**. یعنی رنگِ نوار هنوز از توکنِ پنل می‌آید و تصویر فقط
   بافت می‌دهد؛ عوض‌کردنِ رنگِ قالب اینجا هم دیده می‌شود.

   SVG و نه PNG: دو کیلوبایت، در هر اندازه تیز، و هیچ کالا یا لوگوی
   فروشگاهِ دیگری در خودش ندارد. */
.hs-offer-band:not([style]) {
    background-image:
        url('/static/frontend/_shared/img/offer-band.svg'),
        linear-gradient(120deg,
            var(--theme-color, #0da487) 0%,
            color-mix(in srgb, var(--theme-color, #0da487) 72%, #000) 100%);
    background-size: cover, cover;
    background-position: center, center;
    background-repeat: no-repeat, no-repeat;
}

/* دکمه روی نوار، هم‌رنگِ خودِ نوار بود: قالب `theme-bg-color` داشت که
   `background: var(--theme-color) !important` می‌گذارد. یعنی تنها
   چیزی که دکمه را دکمه نشان می‌داد، گوشه‌های گردش بود.

   راه‌حل برداشتنِ آن کلاس از قالب بود و نه جنگیدن با `!important`
   از اینجا: وقتی طرفِ مقابل `!important` است، حذفِ علت از اضافه‌کردنِ
   یک `!important`ِ دوم تمیزتر است. */
.hs-offer-band__cta {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    padding: .6rem 1.4rem;
    border-radius: 999px;
    background: #fff;
    color: var(--theme-color, #0da487);
    font-weight: 700;
    box-shadow: 0 8px 20px rgba(0, 0, 0, .18);
    transition: transform .2s ease, box-shadow .2s ease;
}

.hs-offer-band__cta:hover {
    color: var(--theme-color, #0da487);
    transform: translateY(-1px);
    box-shadow: 0 12px 26px rgba(0, 0, 0, .24);
}

/* متنِ نوار روی بافت باید بخواند. سایهٔ نرم و نه کادر: کادر یک شیء
   تازه است، سایه فقط لبهٔ حرف را از بافت جدا می‌کند. */
.hs-offer-band--light .offer-text,
.hs-offer-band--light .coupon-code {
    text-shadow: 0 1px 12px rgba(0, 0, 0, .22);
}

/* --------------------------------------------------------------------------
   کدِ تخفیف باید همان‌طور خوانده شود که تایپ شده
   --------------------------------------------------------------------------

   فونتِ سایت `iranyekan` است و رقمِ لاتین را با گلیفِ فارسی نشان
   می‌دهد. برای قیمت و تاریخ این دقیقاً چیزی است که می‌خواهیم؛ برای
   کدِ تخفیف یک اشکالِ واقعی است:

       در DOM:            MEHR10
       چیزی که دیده می‌شود: MEHR۱۰

   دکمهٔ «کپی» درست کار می‌کند — مقدارِ `data-copy` دست‌نخورده است —
   ولی مشتری‌ای که کد را از روی صفحه **می‌خواند و تایپ می‌کند** عددی
   را وارد می‌کند که سرور نمی‌شناسد. و بعد فکر می‌کند کد منقضی شده.

   `font-family` و نه `font-variant-numeric`: جایگزینیِ رقم اینجا
   انتخابِ خودِ فونت است و نه یک ویژگیِ OpenTypeِ خاموش‌شدنی، پس تنها
   راهش فونتِ دیگری است. پشته عمداً عمومی است تا روی هر سیستمی چیزی
   پیدا شود.
   -------------------------------------------------------------------------- */

/* ── چرا اینجا `!important` هست و این یک بار درست است ────────────────

   قاعدهٔ فونتِ قالب این است:

       body, button, input, optgroup, select, textarea, …
       { font-family: "iranyekan", iransans !important }

   `!important` روی انتخابگری با وزنِ تقریباً صفر. یعنی هیچ انتخابگرِ
   عادی — هرچند بلند، هرچند بعدتر بارگذاری‌شده — از آن قوی‌تر نیست.
   تنها چیزی که یک اعلانِ `!important` را می‌برد، `!important`ِ دیگری
   است.

   نسخهٔ اولِ همین بلوک بدونِ `!important` نوشته شد، با این استدلال که
   «`!important` بدهی است». استدلال عموماً درست است و اینجا غلط بود:
   قاعده بی‌اثر ماند و کدِ تخفیف همچنان `MEHR۱۰` دیده می‌شد. وقتی
   طرفِ مقابل `!important` است، نگذاشتنش یک انتخابِ تمیز نیست — یک
   قاعدهٔ بی‌اثر است.

   دامنه عمداً تنگ است: فقط جایی که رقمِ لاتین باید لاتین بماند. */

.hs-code,
.hs-offer-band .coupon-code span,
.bank-section .bank-offer .bank-footer h4 input {
    font-family: "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
    letter-spacing: .04em;
}

/* قاعدهٔ قالب `pointer-events: none` هم می‌گذارد، که دقیقاً چیزی را
   می‌کشد که این `<input>` برایش انتخاب شده بود: اگر جاوااسکریپت اجرا
   نشود، کاربر باید بتواند کد را دستی انتخاب کند.

   اینجا `!important` لازم نیست — آن اعلان معمولی است و انتخابگرِ
   هم‌وزنِ ما که بعدتر می‌آید، می‌بردش. */
.bank-section .bank-offer .bank-footer h4 input {
    pointer-events: auto;
    user-select: all;
}

/* ==========================================================================
   نوارِ افقیِ دسته — `category_strip`
   ==========================================================================

   ── چرا این قاعده‌ها اینجا کپی شده‌اند و از قالب قرض گرفته نشده‌اند ──

   ظاهرِ این کارت‌ها در `minified-style.css` هست، ولی به والدش بسته:

       .category-section-2 .category-slider .shop-category-box a.circle-1

   اولین تلاش این بود که همان نام‌ها را روی نوار بگذاریم. کار کرد — و
   یک چیزِ دیگر را هم روشن کرد. `js/slick/custom_slick.js` که این قالب
   روی هر صفحه بار می‌کند، خطِ اولش این است:

       $(".category-slider").slick({ slidesToShow: 8, ... })

   یعنی آن کلاس فقط ظاهر نمی‌دهد؛ یک کاروسلِ slick هم روشن می‌کند که
   کارت‌ها را در trackِ خودش می‌چیند. `hs-rail` که `display:flex` است
   با آن می‌جنگد، و نتیجه در مرورگر کارت‌هایی به عرضِ ۲۲ پیکسل با
   کلاسِ `slick-cloned` بود.

   دو راه بود: یا نوار را به slick بسپاریم، یا ظاهر را پورت کنیم.
   دومی انتخاب شد، به همان دلیلی که `_products.html` از فاز ۵۸ دارد:
   نواری که با CSS اسکرول می‌شود، بدونِ جاوااسکریپت هم یک نوار است.
   با slick، بدونِ جاوااسکریپت یک ستونِ عمودیِ بی‌شکل است.

   مقدارها بدونِ تغییر از همان فایل آمده‌اند، جز جایی که کامنت خلافش
   را می‌گوید.
   -------------------------------------------------------------------------- */

/* ── سبکِ `circle` ──────────────────────────────────────────────────── */

.hs-catstrip .shop-category-box {
    position: relative;
    padding-top: 14px;
    text-align: center;
}

.hs-catstrip .shop-category-box a {
    display: block;
    position: relative;
}

/* دایرهٔ رنگی پشتِ تصویر. `z-index` منفی نیامد — در اصل هست و آنجا
   لازم بود چون والدِ slick زمینهٔ خودش را داشت؛ اینجا والدی نیست که
   دایره پشتش گم شود، و `z-index:-1` روی بعضی مرورگرها کلِ شبه‌عنصر
   را زیرِ زمینهٔ صفحه می‌برد. */
.hs-catstrip .shop-category-box a::before {
    content: "";
    position: absolute;
    top: -14px;
    inset-inline-start: 0;
    width: 100%;
    height: 100%;
    border-radius: 100px;
    transition: all .3s ease-in-out;
}

.hs-catstrip .shop-category-box a.circle-1::before { background-color: #fff9d8; }
.hs-catstrip .shop-category-box a.circle-2::before { background-color: #fff2ec; }
.hs-catstrip .shop-category-box a.circle-3::before { background-color: #fce9e9; }
.hs-catstrip .shop-category-box a.circle-4::before { background-color: #fcf1ff; }

.hs-catstrip .shop-category-box a img {
    position: relative;
    width: calc(87px + (110 - 87) * ((100vw - 320px) / (1920 - 320)));
    margin: 0 auto;
    transition: all .3s ease-in-out;
}

.hs-catstrip .shop-category-box:hover a::before { border-radius: 11px; }
.hs-catstrip .shop-category-box:hover a img { transform: scale(1.04); }

.hs-catstrip .shop-category-box .category-name {
    position: relative;
    text-align: center;
    margin: 16px auto 0;
}

.hs-catstrip .shop-category-box .category-name h6 {
    margin: 0 auto;
    font-size: calc(13px + (15 - 13) * ((100vw - 320px) / (1920 - 320)));
    letter-spacing: 0;
    transition: all .3s ease-in-out;
}

/* ── سبکِ `boxed` ───────────────────────────────────────────────────── */

.hs-catstrip .category-box-list {
    position: relative;
    z-index: 0;
    padding: 20px;
    border-radius: 15px;
    background-color: #f1f1f3;
    overflow: hidden;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list::after {
    content: "";
    position: absolute;
    inset: 0;
    background: rgba(var(--theme-color-rgb, 13 164 135), .15);
    z-index: -1;
    opacity: 0;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list:hover { background-color: #fff; }
.hs-catstrip .category-box-list:hover::after { opacity: 1; }

.hs-catstrip .category-box-list .category-name {
    display: block;
    margin-bottom: 20px;
    color: #222;
}

.hs-catstrip .category-box-list .category-name h4 {
    font-weight: 600;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list .category-name h6 {
    margin-top: 5px;
    color: #4a5568;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list:hover .category-name h4 {
    font-weight: 700;
    color: var(--theme-color, #0da487);
}

.hs-catstrip .category-box-list:hover .category-name h6 { color: #222; }

.hs-catstrip .category-box-list .category-box-view { position: relative; }
.hs-catstrip .category-box-list a { display: block; position: relative; }

.hs-catstrip .category-box-list a img {
    margin: 0 auto;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list:hover a img {
    opacity: .7;
    transform: scale(1.03);
}

.hs-catstrip .category-box-list .shop-button {
    position: absolute;
    bottom: -20px;
    inset-inline-start: 50%;
    transform: translateX(50%);
    opacity: 0;
    background-color: var(--theme-color, #0da487);
    color: #fff;
    font-size: 14px;
    font-weight: 600;
    padding: 10px 20px;
    white-space: nowrap;
    transition: all .3s ease-in-out;
}

.hs-catstrip .category-box-list:hover .shop-button { opacity: 1; bottom: 17px; }
.hs-catstrip .category-box-list .shop-button i { margin-inline-end: 6px; font-size: 12px; }

/* دکمه‌ای که فقط با hover پیدا می‌شود، روی لمس هرگز پیدا نمی‌شود.
   کلِ کارت لینک است، پس روی موبایل دکمه حذف می‌شود و نه اینکه
   نیمه‌پنهان بماند. */
@media (hover: none) {
    .hs-catstrip .category-box-list .shop-button { display: none; }
}

/* ==========================================================================
   ریتمِ عمودیِ صفحهٔ اصلی — یک صاحب، فاز ۷۸
   ==========================================================================

   ── چه چیزی خراب بود، با عدد ──────────────────────────────────────────

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

       gap=   0  pt=44px pb= 0px   hs-hero
       gap=  40  pt=40px pb=40px   hs-section
       gap=   0  pt=44px pb=32px   banner-section
       gap= 240  pt=44px pb=32px   banner-section      ← دویست‌وچهل
       gap= 240  pt=32px pb=32px   section-t-space

   سه دستگاهِ فاصله‌گذاری هم‌زمان کار می‌کردند:

   ۱ `section,.section-t-space{padding-top:calc(30px + …)}` در
     `minified-style.css` — یک انتخابگرِ **عنصری**، یعنی به هر
     `<section>`ی در سند می‌خورد، از جمله hero؛
   ۲ `.section-b-space{padding-bottom:…}` از همان فایل؛
   ۳ `padding-block`ِ خودِ بخش‌های ما.

   هرجا دوتا از این سه با هم می‌افتادند، فاصله جمع می‌شد.

   ── چرا `gap`ِ فلکس و نه اصلاحِ آن سه قاعده ───────────────────────────

   می‌شد `section` را از آن انتخابگر برداشت، ولی آن قاعده برای صفحهٔ
   دسته و سبد و پرداخت هم هست و دست‌زدن به آن، سه صفحهٔ دیگر را برای
   رفعِ یک صفحه به خطر می‌اندازد.

   `gap` خاصیتی دارد که هیچ‌کدام از آن سه ندارند: **جمع نمی‌شود**.
   بینِ هر دو بخش دقیقاً یکی است، اولین فرزند فاصلهٔ ابتدایی ندارد، و
   margin collapse هم در کار نیست. یعنی ریتم یک صاحب پیدا می‌کند و
   اضافه‌کردنِ بخشِ بیست‌وششم فردا، هیچ حسابی را به هم نمی‌زند.

   دامنه‌اش `.hs-home` است و نه `body`: بقیهٔ صفحه‌ها دست‌نخورده
   می‌مانند.
   -------------------------------------------------------------------------- */

.hs-home {
    display: flex;
    flex-direction: column;
    gap: var(--hs-section-gap);
    /* «آخرین المانی که در صفحهٔ اصلی اضافه می‌کنی به فوتر می‌چسبد.» `gap` فقط **بینِ**
       بخش‌هاست؛ بعد از آخری هیچ فاصله‌ای نبود چون بخش‌ها حاشیهٔ بیرونیِ خودشان را
       کنار گذاشته‌اند (پایین). همان فاصلهٔ میانِ بخش‌ها، زیرِ آخری هم. */
    padding-bottom: var(--hs-section-gap);
}

/* بخش‌ها دیگر فاصلهٔ **بیرونی** ندارند — آن کارِ `gap` است.
   `!important` لازم نیست: این قاعده بعدتر بار می‌شود و انتخابگرش
   (۰,۲,۱) از `section,.section-t-space` (۰,۱,۱) سنگین‌تر است. */
.hs-home > section {
    padding-block: 0;
    margin-block: 0;
}

/* استثنا: بخشی که **زمینهٔ خودش را رنگ می‌کند** بدونِ پدینگِ درونی،
   متنش به لبهٔ رنگ می‌چسبد. این‌ها فاصله‌شان را از دست نمی‌دهند، فقط
   دیگر آن را به همسایه‌شان تحمیل نمی‌کنند. */
.hs-home > section.hs-deal,
.hs-home > section.hs-newsletter,
.hs-home > .hs-band {
    padding-block: var(--hs-section-gap);
}

/* و اولین بخش به هدر می‌چسبد. hero تمام‌عرض است و هر فاصله‌ای بالایش
   یک نوارِ سفید بینِ هدر و تصویر می‌سازد — همان چیزی که گزارش شد. */
.hs-home > :first-child {
    padding-block-start: 0;
}

/* لبه‌ها تنظیمِ قالب‌اند (`{% home_edges %}`): hero به هدر می‌چسبد، نوارِ محصول نه؛ و
   پایین را مالک انتخاب می‌کند. */
.hs-home.hs-home--top-gap { padding-block-start: var(--hs-section-gap); }
.hs-home.hs-home--bottom-flush { padding-block-end: 0; }

/* ==========================================================================
   کاروسلِ نوارهای افقی — فاز ۷۸
   ==========================================================================

   `home-rails.js` دورِ هر `hs-rail` یک `hs-rail-wrap` می‌پیچد و دو دکمه
   کنارش می‌گذارد — ولی **فقط روی دستگاهی که اشاره‌گرِ دقیق دارد**. روی
   موبایل هیچ‌کدام از این‌ها ساخته نمی‌شود و نوار همان نوارِ لمسی می‌ماند.

   یعنی قاعده‌های زیر روی موبایل هیچ عنصری برای اعمال‌شدن پیدا نمی‌کنند،
   و این عمدی است: یک `@media` که بخواهد همان را بگوید، یک شرطِ دوم است
   که باید با شرطِ جاوااسکریپت هم‌گام بماند.
   -------------------------------------------------------------------------- */

.hs-rail-wrap {
    position: relative;
}

/* دکمه بیرونِ نوار می‌نشیند و نه رویش: روی کارتِ محصول نشستن یعنی
   پوشاندنِ تصویر و دکمهٔ سبدی که زیرش است. */
.hs-rail__nav {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    z-index: 2;

    /* ۴۴×۴۴ حتی روی دسکتاپ: حداقلِ هدفِ اشاره‌گر، و اندازه‌ای که از
       دور هم دیده می‌شود. */
    width: 44px;
    height: 44px;
    display: grid;
    place-items: center;

    border: 1px solid rgba(0, 0, 0, .08);
    border-radius: 50%;
    background: #fff;
    color: #222;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .12);
    cursor: pointer;
    transition: opacity .2s ease, background-color .2s ease, color .2s ease;
}

.hs-rail__nav svg { width: 20px; height: 20px; }

.hs-rail__nav:hover:not(:disabled) {
    background: var(--theme-color, #0da487);
    color: #fff;
}

.hs-rail__nav:focus-visible {
    outline: 2px solid var(--theme-color, #0da487);
    outline-offset: 2px;
}

/* غیرفعال و نه پنهان: دکمه‌ای که ناپدید شود جای دکمهٔ دیگر را عوض
   می‌کند و دستِ کاربر را گم می‌کند. */
.hs-rail__nav:disabled {
    opacity: .35;
    cursor: default;
    box-shadow: none;
}

/* جهت‌ها منطقی‌اند و نه چپ/راست: در راست‌به‌چپ «قبلی» سمتِ راست است،
   و `inset-inline` خودش این را می‌داند. */
.hs-rail__nav--prev { inset-inline-start: -10px; }
.hs-rail__nav--next { inset-inline-end: -10px; }

/* نواری که همه‌اش جا می‌شود دکمه نمی‌خواهد — دو دکمهٔ همیشه‌خاموش،
   نویز است. */
.hs-rail-wrap--static .hs-rail__nav { display: none; }

/* روی دسکتاپ اسکرول‌بارِ نوار دیگر لازم نیست: دکمه کارش را می‌کند و
   نوارِ خاکستریِ پایین فقط شلوغی است. روی لمس دست‌نخورده می‌ماند،
   چون آنجا اصلاً `hs-rail-wrap` ساخته نشده. */
.hs-rail-wrap .hs-rail {
    scrollbar-width: none;
    padding-block-end: 0;
}

.hs-rail-wrap .hs-rail::-webkit-scrollbar { display: none; }

/* ── حسِ اپلیکیشن روی موبایل ──────────────────────────────────────────

   خواسته این بود: «کاملا حس یک اپلیکیشن رو به کاربر بده. شبیه اپ های
   فروشگاهی که کاربر با کشیدن انگشت محصولات رو اسکرول x میکنه.»

   سه چیز این حس را می‌سازند و هر سه فقط روی لمس اعمال می‌شوند:

   ۱ نوار تا **لبهٔ صفحه** می‌رود و در حاشیهٔ ظرف نمی‌ماند. کارتی که
     لبه را لمس می‌کند، می‌گوید «ادامه دارد»؛ کارتی که ۱۶ پیکسل
     مانده به لبه تمام می‌شود، می‌گوید «همین بود».
   ۲ `scroll-padding` تا کارتِ بعدی درست زیرِ انگشت بایستد.
   ۳ `overscroll-behavior-x: contain` تا کشیدنِ نوار تا انتها، صفحه را
     عقب نبرد — همان چیزی که در اپ‌ها آزاردهنده است.
   -------------------------------------------------------------------------- */

@media (hover: none) {
    .hs-rail {
        /* از لبه تا لبه، بدونِ اینکه ظرف پهن‌تر شود. */
        margin-inline: calc(-1 * var(--hs-edge, 12px));
        padding-inline: var(--hs-edge, 12px);
        scroll-padding-inline-start: var(--hs-edge, 12px);
        overscroll-behavior-x: contain;
        scrollbar-width: none;
    }

    .hs-rail::-webkit-scrollbar { display: none; }

    /* حاشیهٔ خودکارِ فاز ۷۵ که نوارِ کم‌کارت را وسط می‌چیند، روی موبایل
       کنار می‌رود: آنجا نوار باید از لبه شروع شود، وگرنه اولین کارت
       وسطِ صفحه می‌افتد و نوار شبیه یک ردیفِ ناقص می‌شود. */
    .hs-rail > :first-child { margin-inline-start: 0; }
    .hs-rail > :last-child  { margin-inline-end: 0; }
}

/* ==========================================================================
   فروشِ ویژه — بازطراحی، فاز ۷۸
   ==========================================================================

   «شبیه واقعا بخش های فروش ویژه سایت های معروف باید بشه.»

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

.hs-deal {
    /* گرادیانِ گرم به‌جای خاکستریِ خنثی: فروشِ ویژه باید از بقیهٔ صفحه
       جدا دیده شود، و رنگ ارزان‌ترین راهِ این کار است. وقتی مالک
       تصویری بگذارد، `--imaged` رویش می‌نشیند. */
    background: linear-gradient(135deg, #16233a 0%, #23324f 55%, #2d3f63 100%);
    color: #fff;
    border-radius: var(--theme-radius, 12px);
    overflow: hidden;
}

.hs-deal__grid {
    display: grid;
    grid-template-columns: minmax(15rem, 20rem) minmax(0, 1fr);
    gap: var(--ds-space-4);
    align-items: center;
}

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

/* نوارِ کوچکِ بالای عنوان. کارش یک چیز است: در یک نگاه بگوید این
   بخش با بقیهٔ نوارهای محصول فرق دارد. */
.hs-deal__flag {
    display: inline-flex;
    align-items: center;
    gap: .4em;
    padding: .3em .85em;
    border-radius: 999px;
    background: #f59e0b;
    color: #1f2937;
    font-size: var(--ds-text-xs);
    font-weight: 700;
}

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

.hs-deal__subtitle {
    margin: var(--ds-space-1) 0 0;
    font-size: var(--ds-text-sm);
    color: rgba(255, 255, 255, .78);
}

/* ── ساعت ──────────────────────────────────────────────────────────── */

.hs-clock { margin-block-start: var(--ds-space-3); }

.hs-clock__label {
    display: block;
    font-size: var(--ds-text-xs);
    color: rgba(255, 255, 255, .7);
    margin-block-end: .4em;
}

/* `dir="ltr"` روی ظرف است و نه اینجا: ترتیبِ روز→ساعت→دقیقه→ثانیه در
   هر زبانی از چپ خوانده می‌شود، مثلِ خودِ ساعت. */
.hs-clock__boxes {
    display: flex;
    gap: .4rem;
}

/* انتخابگر عمداً سنگین است. پروژه یک قاعدهٔ سراسری دارد —
   `:not(.ck-content) span { display: inline-block }` با وزنِ (۰,۲,۱) —
   که یک `.hs-clock__box`ِ ساده (۰,۱,۰) را می‌برد. این را در مرورگر
   دیدیم و نه در فایل: خانه‌ها `display:block` می‌گرفتند و برچسبِ
   «ساعت» کنارِ عدد می‌نشست به‌جای زیرش.

   `span.hs-clock__box` وزنِ برابر دارد و چون بعدتر بار می‌شود،
   می‌برد — بدونِ `!important`. */
.hs-clock__boxes span.hs-clock__box {
    display: grid;
    justify-items: center;
    gap: .15em;
    min-width: 3.1rem;
    padding: .45rem .3rem;
    border-radius: 10px;
    background: rgba(255, 255, 255, .12);
    border: 1px solid rgba(255, 255, 255, .16);
}

.hs-clock__box b {
    font-size: var(--ds-text-xl);
    font-weight: 800;
    line-height: 1;
    /* رقمِ هم‌عرض، وگرنه هر ثانیه پهنای خانه می‌پرد و ردیف می‌لرزد. */
    font-variant-numeric: tabular-nums;
    font-family: "Segoe UI", Roboto, Arial, sans-serif;
}

.hs-clock__box small {
    font-size: .62rem;
    color: rgba(255, 255, 255, .7);
}

.hs-deal__cta {
    display: inline-flex;
    align-items: center;
    gap: .5em;
    margin-block-start: var(--ds-space-3);
    padding: .6rem 1.2rem;
    border-radius: 999px;
    background: #fff;
    color: #16233a;
    font-weight: 700;
    transition: transform .2s ease, box-shadow .2s ease;
}

.hs-deal__cta:hover {
    color: #16233a;
    transform: translateY(-1px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, .25);
}

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

/* کارتِ سفید روی زمینهٔ تیره، با همان گردیِ بقیهٔ صفحه. */
.hs-deal .product-box-4 {
    background: #fff;
    border-radius: var(--theme-radius, 12px);
}

@media (max-width: 991.98px) {
    /* روی موبایل ستونِ فوریت بالا می‌رود و تمام‌عرض می‌شود: در یک ستونِ
       باریک، «کنارِ هم» معنا ندارد. */
    .hs-deal__grid { grid-template-columns: minmax(0, 1fr); }
    .hs-clock__boxes { justify-content: flex-start; }
}

/* ===========================================================================
   فاز ۷۸ — سه بخشی که مالک «ضعیف» خواندشان
   ===========================================================================

   «اون بخشی که به صورت تب نشون میدی … خیلی ساده و معمولی هست.»
   «بخش یک نگاهِ سریع … از لحاظ ui ضعیفه.»
   «بخش نظرات مشتریان خیلی ضعیف کار شده.»

   هر سه یک ریشه داشتند و نه سه‌تا: **نبودِ ظرف**. هر سه یک ردیف
   محتوا بودند روی زمینهٔ صفحه، بدونِ لبه‌ای که بگوید کجا شروع
   می‌شوند و کجا تمام. چشمی که مرز نبیند، سلسله‌مراتب هم نمی‌بیند.

   پس جوابِ هر سه یکی است: یک قاب، یک سرِ مشخص، و یک حالتِ فعال یا
   ماوس که ثابت کند این چیز **زنده** است.

   همهٔ رنگ‌ها از توکن‌های پنل می‌آیند تا تغییرِ رنگِ قالب اینجا هم
   دیده شود — همان مرزی که `docs/23-design-system.md` §۱۰ کشیده.
   =========================================================================== */

/* ── محصولات با تب ───────────────────────────────────────────────── */

.hs-tabdeck__shell {
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: calc(var(--theme-radius, 12px) + 6px);
    background: #fff;
    overflow: hidden;
}

.hs-tabdeck__head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: var(--ds-space-3);
    padding: var(--ds-space-4);
    /* سرِ قاب کمی روشن‌تر از بدنه: مرزِ «کنترل» و «محتوا» بدونِ خطِ
       اضافه. */
    background: linear-gradient(
        180deg,
        var(--theme-accent-soft, #f1f5f9),
        transparent);
    border-block-end: 1px solid var(--theme-line, #e5e7eb);
}

/* `_band_heading` برای حالتِ تنها ساخته شده و فاصلهٔ زیرش را خودش
   می‌گذارد. داخلِ یک ردیفِ افقی آن فاصله یک شکافِ بی‌دلیل است. */
.hs-tabdeck__head .title {
    margin-block-end: 0;
    flex: 1 1 14rem;
}

.hs-tabdeck__nav {
    display: flex;
    flex-wrap: nowrap;
    gap: var(--ds-space-2);
    margin: 0;
    padding: 0;
    list-style: none;
    /* روی صفحهٔ باریک نوار افقی می‌شود و نه چندسطری: چهار قرص در دو
       سطر، سرِ قاب را دو برابر می‌کند. */
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
}

.hs-tabdeck__nav::-webkit-scrollbar { display: none; }

.hs-tabdeck__tab {
    display: inline-flex;
    align-items: center;
    gap: .45em;
    /* ۴۴ پیکسلِ ارتفاع: کمترین هدفِ لمسی. */
    min-height: 44px;
    padding: .45rem 1rem;
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: 999px;
    background: #fff;
    color: var(--theme-title, #222);
    font-size: var(--ds-text-sm);
    font-weight: 600;
    white-space: nowrap;
    scroll-snap-align: start;
    transition: background-color .18s ease, color .18s ease,
                border-color .18s ease, box-shadow .18s ease;
}

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

/* تفاوتِ حالتِ فعال **فقط** رنگِ متن نیست: زمینه، لبه و سایه هم عوض
   می‌شوند. راهنمای ui-ux-pro-max این را شرطِ `state-clarity`
   می‌داند و دلیلش هم کاربرِ کم‌بینا است. */
.hs-tabdeck__tab.active {
    background: var(--theme-accent, #0da487);
    border-color: var(--theme-accent, #0da487);
    color: #fff;
    box-shadow: 0 6px 16px color-mix(
        in srgb, var(--theme-accent, #0da487) 28%, transparent);
}

.hs-tabdeck__tab-count {
    display: inline-block;
    min-width: 1.6em;
    padding: .05em .35em;
    border-radius: 999px;
    background: var(--theme-accent-soft, #f1f5f9);
    color: var(--theme-accent-strong, #0da487);
    font-size: var(--ds-text-xs);
    font-weight: 700;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.hs-tabdeck__tab.active .hs-tabdeck__tab-count {
    background: rgba(255, 255, 255, .22);
    color: #fff;
}

.hs-tabdeck__body { padding: var(--ds-space-4); }

/* ── نظر مشتریان ─────────────────────────────────────────────────── */

/* بندِ رنگی: بخشی که زمینهٔ خودش را دارد، از همسایه‌هایش جدا دیده
   می‌شود. `hs-band` همان قلابی است که ریتمِ عمودیِ فاز ۷۸ برای همین
   حالت گذاشت — پدینگِ درونی می‌گیرد و فاصله‌اش را به بخشِ بعدی
   تحمیل نمی‌کند. */
.hs-voices {
    background:
        radial-gradient(
            120% 100% at 50% 0%,
            var(--theme-accent-soft, #f0fdf4) 0%,
            transparent 70%),
        var(--ds-surface-2, #f8fafc);
}

.hs-voice {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: var(--ds-space-2);
    padding: calc(var(--ds-space-4) + .4rem) var(--ds-space-4)
             var(--ds-space-4);
    margin: 0;
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: calc(var(--theme-radius, 12px) + 4px);
    background: #fff;
    overflow: hidden;
    transition: transform .2s ease, box-shadow .2s ease;
}

/* نوارِ رنگیِ بالای کارت. یک شبه‌عنصر و نه یک `<div>`: تزئین است و
   در درختِ دسترس‌پذیری نباید باشد. */
.hs-voice::before {
    content: "";
    position: absolute;
    inset-block-start: 0;
    inset-inline: 0;
    height: 4px;
    background: linear-gradient(
        90deg,
        var(--theme-accent, #0da487),
        color-mix(in srgb, var(--theme-accent, #0da487) 35%, #fff));
}

.hs-voice:hover {
    transform: translateY(-3px);
    box-shadow: var(--theme-shadow, 0 12px 28px rgba(15, 23, 42, .1));
}

/* گیومه بزرگ است و کم‌رنگ: باید در **حاشیهٔ** دید بیفتد و نه وسطِ
   آن. جای انتهای سطر (چپ در فارسی) را می‌گیرد چون ابتدای سطر جای
   ستاره‌هاست، و دو نشانه روی هم یعنی هیچ‌کدام دیده نمی‌شوند. */
.hs-voice__mark {
    position: absolute;
    inset-block-start: .2rem;
    inset-inline-end: .9rem;
    font-size: 6rem;
    line-height: 1;
    color: color-mix(
        in srgb, var(--theme-accent, #0da487) 14%, transparent);
    font-family: Georgia, "Times New Roman", serif;
    pointer-events: none;
    user-select: none;
}

.hs-voice__stars {
    color: #f59e0b;
    font-size: var(--ds-text-base);
    letter-spacing: .14em;
}

.hs-voice__text {
    position: relative;
    margin: 0;
    font-size: var(--ds-text-lg);
    line-height: 2;
    color: var(--theme-body, #4a5568);
    /* کارت‌ها در یک ردیف هم‌قدند و نظرها هم‌اندازه نیستند: این خط
       متن را به بالا هل می‌دهد تا امضا همیشه ته کارت بنشیند. */
    flex: 1 1 auto;
}

.hs-voice__who {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    margin-block-start: var(--ds-space-2);
    padding-block-start: var(--ds-space-3);
    border-block-start: 1px solid var(--theme-line, #e5e7eb);
}

.hs-voice__face {
    flex: 0 0 auto;
    width: 3rem;
    height: 3rem;
    border-radius: 50%;
    object-fit: cover;
    /* حلقهٔ نازکِ دورِ عکس: بدونش عکسِ روشن با زمینهٔ سفید یکی
       می‌شود. */
    box-shadow: 0 0 0 2px #fff,
                0 0 0 3px color-mix(
                    in srgb, var(--theme-accent, #0da487) 35%, transparent);
}

.hs-voice__who span.hs-voice__face--letter {
    display: grid;
    place-items: center;
    background: var(--theme-accent-soft, #ecfdf5);
    color: var(--theme-accent-strong, #0da487);
    font-size: var(--ds-text-lg);
    font-weight: 700;
}

.hs-voice__who span.hs-voice__name {
    display: grid;
    gap: .1em;
    min-width: 0;
}

.hs-voice__name b {
    font-size: var(--ds-text-sm);
    font-weight: 700;
    color: var(--theme-title, #222);
}

.hs-voice__name small {
    font-size: var(--ds-text-xs);
    color: var(--theme-body, #6b7280);
}

/* ── ستون‌های محصول ──────────────────────────────────────────────── */

.hs-stack {
    display: flex;
    flex-direction: column;
    border: 1px solid var(--theme-line, #e5e7eb);
    border-radius: calc(var(--theme-radius, 12px) + 4px);
    background: #fff;
    overflow: hidden;
}

.hs-stack__head {
    display: flex;
    align-items: center;
    gap: .5em;
    margin: 0;
    padding: var(--ds-space-3);
    background: var(--theme-accent-soft, #f1f5f9);
    border-block-end: 1px solid var(--theme-line, #e5e7eb);
    font-size: var(--ds-text-base);
    font-weight: 700;
    color: var(--theme-title, #222);
}

.hs-stack__dot {
    width: .55rem;
    height: .55rem;
    border-radius: 50%;
    background: var(--theme-accent, #0da487);
    flex: 0 0 auto;
}

.hs-stack__list {
    margin: 0;
    padding: 0;
    list-style: none;
}

.hs-stack__row + .hs-stack__row {
    border-block-start: 1px solid var(--theme-line, #f1f5f9);
}

.hs-stack__link {
    display: flex;
    align-items: center;
    gap: var(--ds-space-2);
    padding: var(--ds-space-2) var(--ds-space-3);
    transition: background-color .18s ease;
}

.hs-stack__link:hover,
.hs-stack__link:focus-visible {
    background: var(--theme-accent-soft, #f8fafc);
}

.hs-stack__link:hover .hs-stack__name { color: var(--theme-accent, #0da487); }
.hs-stack__link:hover .hs-stack__thumb img { transform: scale(1.06); }

.hs-stack__link span.hs-stack__rank {
    display: grid;
    place-items: center;
    flex: 0 0 auto;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    background: var(--theme-accent-soft, #ecfdf5);
    color: var(--theme-accent-strong, #0da487);
    font-size: var(--ds-text-xs);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.hs-stack__thumb {
    flex: 0 0 auto;
    width: 3.75rem;
    height: 3.75rem;
    border-radius: var(--theme-radius, 12px);
    background: var(--ds-surface-2, #f8fafc);
    overflow: hidden;
    display: block;
}

.hs-stack__thumb img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    transition: transform .25s ease;
}

.hs-stack__link span.hs-stack__meta {
    display: grid;
    gap: .15em;
    min-width: 0;
}

.hs-stack__name {
    font-size: var(--ds-text-sm);
    font-weight: 600;
    color: var(--theme-title, #222);
    /* دو خط و بعد «…»: نامِ چهارخطی ارتفاعِ ستون‌ها را نامساوی
       می‌کند و کلِ ردیف را می‌شکند. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    transition: color .18s ease;
}

.hs-stack__price {
    font-size: var(--ds-text-sm);
    font-weight: 700;
    color: var(--theme-accent-strong, #0da487);
}

.hs-stack__price del {
    margin-inline-start: .4em;
    font-weight: 400;
    font-size: var(--ds-text-xs);
    color: #9ca3af;
}

/* برچسبِ «نمونه» داخلِ یک گرید است و گرید فرزندش را کش می‌دهد. بدونِ
   این خط، یک قرصِ زردِ تمام‌عرض زیرِ قیمت می‌نشیند. */
.hs-stack__meta .hs-sample-tag { justify-self: start; }

/* ===========================================================================
   شش شبکهٔ نامتقارنِ کاشی — فاز ۷۸
   ===========================================================================

   «باید چندین چیدمان و حالت کنار هم وجود داشته باشه که تم خیلی خفن و
   بزرگ بشه.»

   ── چرا `grid-template-areas` و نه ستونِ بوت‌استرپ ────────────────────

   شش چیدمانِ قبلی با `row`/`col` نوشته شده بودند و کار می‌کردند، چون
   همه‌شان یک ردیف بودند. این شش‌تا نیستند: هر کدام دستِ‌کم یک کاشی
   دارند که روی **دو ردیف** کشیده می‌شود، و `col-*` این را ندارد.

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

   ── ارتفاع ──────────────────────────────────────────────────────────

   در شبکهٔ دوردیفه، قدِ کاشی دیگر مالِ خودِ کاشی نیست؛ مالِ ردیف است.
   `grid-auto-rows` آن را می‌دهد و `.hs-mosaic .hs-banner` کاشی را
   تا ته خانه‌اش می‌کشد. ضریب‌ها (۰.۸ / ۰.۶۸ / ۰.۶۲) از این می‌آیند
   که دو ردیف روی هم باید کمی بلندتر از یک کاشیِ تنها شود و نه دو
   برابرِ آن — دو برابر یعنی یک بلوکِ غول‌آسا وسطِ صفحه.

   ── و روی موبایل ────────────────────────────────────────────────────

   هیچ‌کدام از این‌ها روی صفحهٔ باریک معنا ندارند: شش ستون در ۳۷۵
   پیکسل یعنی شش نوارِ ۶۰ پیکسلی. زیرِ ۹۹۲ پیکسل نقشه کنار می‌رود و
   همه یک ستون می‌شوند — با `grid-area: auto` که نقشه را باطل کند،
   وگرنه مرورگر هنوز دنبالِ خانهٔ `a` می‌گردد.
   =========================================================================== */

.hs-mosaic {
    display: grid;
    gap: var(--ds-space-3);
    --hs-row: calc(var(--hs-tile-medium) * .68);
    grid-auto-rows: minmax(var(--hs-row), auto);
}

.hs-banners--short.hs-mosaic { --hs-row: calc(var(--hs-tile-short) * .8); }
.hs-banners--tall.hs-mosaic  { --hs-row: calc(var(--hs-tile-tall) * .62); }

/* قدِ کاشی از خانه می‌آید و نه از توکنِ `--hs-tile-height`. این قاعده
   بعد از `.hs-banners .hs-banner` می‌آید و وزنِ برابر دارد، پس
   می‌برد. */
.hs-mosaic .hs-banner {
    height: 100%;
    min-width: 0;
}

@media (min-width: 992px) {
    .hs-mosaic > :nth-child(1) { grid-area: a; }
    .hs-mosaic > :nth-child(2) { grid-area: b; }
    .hs-mosaic > :nth-child(3) { grid-area: c; }
    .hs-mosaic > :nth-child(4) { grid-area: d; }
    .hs-mosaic > :nth-child(5) { grid-area: e; }
    .hs-mosaic > :nth-child(6) { grid-area: f; }

    /* ویترین — از `home-section`ِ index-4 قالبِ اصلی: یک پنلِ بزرگ،
       یک بلندِ کنارش، و دو کوچکِ روی هم. */
    .hs-mosaic--showcase {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        grid-template-areas:
            "a a b c"
            "a a b d";
    }

    /* دوسوم و یک‌سوم — ساده‌ترینِ نامتقارن‌ها. */
    .hs-mosaic--split {
        grid-template-columns: repeat(3, minmax(0, 1fr));
        grid-template-areas: "a a b";
    }

    /* یکی پهن بالا، دوتا زیرش. */
    .hs-mosaic--stack {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-areas:
            "a a"
            "b c";
    }

    /* برج: یک کاشیِ بلندِ کناری و دو کاشیِ روی هم. */
    .hs-mosaic--tower {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-areas:
            "a b"
            "a c";
    }

    /* یک بزرگ و چهار کوچک. */
    .hs-mosaic--five {
        grid-template-columns: repeat(4, minmax(0, 1fr));
        grid-template-areas:
            "a a b c"
            "a a d e";
    }

    /* موزائیکِ شش‌تایی: هیچ دو خانه‌ای هم‌اندازه نیستند. */
    .hs-mosaic--mosaic {
        grid-template-columns: repeat(6, minmax(0, 1fr));
        grid-template-areas:
            "a a a b b c"
            "a a a d e f";
    }
}

@media (max-width: 991.98px) {
    /* نقشه باطل می‌شود و نه فقط نادیده گرفته: بدونِ `grid-area: auto`
       مرورگر هنوز دنبالِ خانهٔ نام‌دار می‌گردد و یک ردیفِ ضمنی
       می‌سازد. */
    .hs-mosaic > * { grid-area: auto; }
    .hs-mosaic { grid-template-columns: minmax(0, 1fr); }

    /* دو ستون برای چیدمان‌هایی که کاشیِ کوچکِ زیاد دارند — یک ستونِ
       شش‌تایی روی موبایل یعنی شش اسکرول تا ته یک بخشِ تبلیغاتی. */
    .hs-mosaic--five,
    .hs-mosaic--mosaic,
    .hs-mosaic--showcase {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* و کاشیِ اول در آن دو ستون، تمامِ عرض را می‌گیرد: بزرگ‌ترین
       کاشی روی موبایل هم باید بزرگ‌ترین بماند. */
    .hs-mosaic--five > :first-child,
    .hs-mosaic--mosaic > :first-child,
    .hs-mosaic--showcase > :first-child {
        grid-column: 1 / -1;
    }
}


/* ==========================================================================
   بخش‌ها کنارِ هم — `appearance/home/layout.py`
   ==========================================================================

   «بتونیم بخش‌ها رو کنارِ هم بزاریم؛ مثلاً یک نوارِ عمودیِ دسته‌بندی کنارِ
   یک بخشِ محصولات.»

       .hs-row-band    یک فرزندِ `.hs-home`، پس ریتمِ `gap`ِ صفحه را می‌گیرد
         .<ظرفِ قالب>  همان ظرفی که partialهای خودِ قالب دارند
           .hs-row     فلکس؛ ستون‌ها به نسبتِ سهمشان
             .hs-col   یک بخشِ کامل، با ظرفِ درونیِ خنثی‌شده

   ── چرا `flex-grow` و نه درصد ─────────────────────────────────────────

   ستونی که بخشش چیزی نداشت (`home-sections.js` جای خالی را برمی‌دارد) باید
   جایش را به همسایه بدهد. با درصدِ ثابت یک چهارمِ خالی می‌ماند؛ با نسبت،
   همسایه کلِ ردیف را می‌گیرد.

   ── و چرا container query ─────────────────────────────────────────────

   شبکهٔ محصولِ بوت‌استرپ با پهنای **پنجره** ستون می‌گیرد: پنج کارت در
   صفحهٔ پهن. همان شبکه در یک ستونِ سه‌چهارم پنج کارتِ باریک می‌شد. هر
   ستون ظرفِ پرس‌وجوست و شبکه‌های درونش با پهنای **ستون** می‌شکنند.
   ========================================================================== */

.hs-row {
    display: flex;
    align-items: stretch;
    gap: var(--hs-row-gap, var(--ds-space-4, 1.5rem));
}

/* ── ارتفاع در ردیف — `layout.FITS`، docs/40 §۴ ─────────────────────────
   ستون‌ها هم‌قدِ بلندترین ستون‌اند (`align-items: stretch`). هر بخش انتخاب
   می‌کند با این ارتفاع چه کند:

     هم‌قد (`fit-stretch`، پیش‌فرض)   محتوایی که برای کشیده‌شدن ساخته شده پخش می‌شود:
                                     ردیف‌های فهرستِ دسته به یک نسبت بلندتر (یعنی
                                     فاصلهٔ عمودیِ بیشتر، نه جای خالی زیرِ فهرست) و هر
                                     بلوکی با `.hs-stretch` — تصویرِ بنر — ستون را پر می‌کند.
     از بالا / وسط                   بخش به اندازهٔ خودش می‌ماند.

   کشیدن فقط برای بخشی است که چیزی کشیدنی دارد (`:has(…)`): شبکهٔ محصولِ کنارش
   دست نمی‌خورد. و فقط از تبلت به بالا — زیرِ آن ستون‌ها روی هم‌اند. */
.hs-col--fit-top { align-self: flex-start; }
.hs-col--fit-center { align-self: center; }
@media (min-width: 992px) {
    .hs-col--fit-stretch { display: flex; flex-direction: column; }
    .hs-col--fit-stretch > :is(section, .hs-section):has(.hs-catlist, .hs-stretch) {
        flex: 1 1 auto; display: flex; flex-direction: column;
    }
    .hs-col--fit-stretch > :is(section, .hs-section):has(.hs-catlist, .hs-stretch)
        > :is(.container-fluid-lg, .container, .ds-container, .wm-wrap, .km-wrap, .bd-wrap) {
        flex: 1 1 auto; display: flex; flex-direction: column;
    }
    .hs-col--fit-stretch .hs-catlist { flex: 1 1 auto; display: flex; flex-direction: column; }
    /* فقط رشد، هرگز کوچک‌شدن (`flex-shrink: 0`): فهرستی بلندتر از ستونِ کناری اندازهٔ
       خودش را نگه می‌دارد و این بار ستونِ کناری است که هم‌قدِ آن می‌شود. */
    .hs-col--fit-stretch .hs-catlist > li { flex: 1 0 auto; display: flex; }
    .hs-col--fit-stretch .hs-catlist__item { flex: 1 1 auto; }
    .hs-col--fit-stretch .hs-stretch { flex: 1 0 auto; }
    /* کارتِ متن و خبرنامه: محتوا وسطِ کارتِ کشیده، نه چسبیده به بالایش */
    .hs-col--fit-stretch .hs-stretch { display: flex; flex-direction: column; justify-content: center; }
}

.hs-col {
    container-type: inline-size;
    min-width: 0;
    flex: 1 1 0;
}

.hs-col--w75 { flex-grow: 9; }
.hs-col--w66 { flex-grow: 8; }
.hs-col--w50 { flex-grow: 6; }
.hs-col--w33 { flex-grow: 4; }
.hs-col--w25 { flex-grow: 3; }

.hs-col:empty { display: none; }

/* بخشِ درونِ ستون نه فاصلهٔ عمودیِ خودش را دارد (کارِ `gap`ِ صفحه است) و نه
   ظرفِ افقی (کارِ ظرفِ ردیف است). `!important` برای پدینگِ ظرف لازم است:
   `container-fluid-lg`ِ فست‌کارت پدینگش را با `!important` می‌دهد. */
.hs-row .hs-col > section,
.hs-row .hs-col > .hs-section {
    padding-block: 0;
    margin-block: 0;
}

.hs-row .hs-col > section > :is(.container-fluid-lg, .container, .ds-container, .wm-wrap, .km-wrap, .bd-wrap) {
    max-width: none;
    width: auto;
    margin-inline: 0;
    padding-inline: 0 !important;
}

/* جای خالیِ بخشِ تنبل درونِ ستون: همان ارتفاعِ رزروشده، بی‌ظرفِ دوم. */
.hs-col > .hs-section--lazy { padding-block: 0; }
.hs-col > .hs-section--lazy .ds-container { max-width: none; padding-inline: 0; }

/* زیرِ تبلت ستون‌ها روی هم می‌افتند، به ترتیبِ فهرست. */
@media (max-width: 991.98px) {
    .hs-row {
        flex-direction: column;
        align-items: stretch;
        gap: var(--hs-section-gap);
    }
    .hs-col { flex: 0 0 auto; width: 100%; }
}

/* منوی کناریِ دسته‌ها روی موبایل یک ستونِ نه‌ردیفه بالای محصولات بود —
   یک صفحه اسکرول پیش از اولین کالا. زیرِ تبلت همان فهرست یک نوارِ افقیِ
   اسکرول‌خور از تراشه‌هاست، مثلِ دسته‌های بالای اپ‌های فروشگاهی. */
@media (max-width: 991.98px) {
    .hs-row .hs-col .hs-catlist {
        display: flex;
        gap: var(--ds-space-2);
        overflow-x: auto;
        scroll-snap-type: x proximity;
        border: 0;
        border-radius: 0;
        background: none;
        padding-block-end: var(--ds-space-1, 4px);
        scrollbar-width: none;
    }
    .hs-row .hs-col .hs-catlist::-webkit-scrollbar { display: none; }
    .hs-row .hs-col .hs-catlist > li { flex: 0 0 auto; scroll-snap-align: start; }
    .hs-row .hs-col .hs-catlist__item {
        min-height: 44px;
        padding: 4px 6px 4px 14px;
        border: 1px solid var(--theme-line, #e5e7eb);
        border-radius: 999px;
    }
    .hs-row .hs-col .hs-catlist li:last-child .hs-catlist__item { border-block-end: 1px solid var(--theme-line, #e5e7eb); }
    .hs-row .hs-col .hs-catlist__item img { width: 34px; height: 34px; flex-basis: 34px; }
    .hs-row .hs-col .hs-catlist__name { white-space: nowrap; }
    .hs-row .hs-col .hs-catlist__chev { display: none; }
}

/* ── شبکه‌های درونِ ستون، به پهنای ستون ─────────────────────────────────
   انتخابگرها از `.hs-col` شروع می‌شوند تا بخشِ تمام‌عرض دست نخورد. */
.hs-col .product-list-section > *,
.hs-col .hs-cat-grid > * { flex: 0 0 auto; }

@container (max-width: 35rem) {
    .hs-col .product-list-section > * { width: 50%; }
    .hs-col .hs-cat-grid > * { width: 33.333%; }
}
@container (min-width: 35.01rem) and (max-width: 52rem) {
    .hs-col .product-list-section > * { width: 33.333%; }
    .hs-col .hs-cat-grid > * { width: 20%; }
}
@container (min-width: 52.01rem) and (max-width: 72rem) {
    .hs-col .product-list-section > * { width: 25%; }
    .hs-col .hs-cat-grid > * { width: 16.666%; }
}
@container (min-width: 72.01rem) {
    .hs-col .product-list-section > * { width: 20%; }
    .hs-col .hs-cat-grid > * { width: 16.666%; }
}

