/* =============================================================================
   افکت‌ها، انیمیشن‌ها و امضای بصریِ هر قالب
   -----------------------------------------------------------------------------
   این فایل عمداً جداست تا فایل‌های قالب (editorial.css / soft.css) و
   public-shell.css دست‌نخورده بمانند.

   تقسیم کار بین سه قالب:
     • کلاسیک  → حرکت کم و رسمی؛ تصویر دست‌نخورده. (شخصیت: محافظه‌کار)
     • مینیمال → قالبِ «حرکت»؛ پرده‌ی بازشونده، محو تایپوگرافیک، ورود آبشاری.
     • نرم     → قالبِ «رنگ»؛ فیلتر رنگی تصاویر و سایه‌های هم‌رنگِ برند.

   همه‌ی موارد از --pub-primary / --pub-dark تغذیه می‌شوند، پس با تغییر رنگ
   سازمانی در مدیریت، افکت‌ها هم همان رنگ را می‌گیرند.
   هیچ انیمیشنی با prefers-reduced-motion اجرا نمی‌شود.
   ============================================================================= */

:root {
    --rv-dur: .62s;
    --rv-ease: cubic-bezier(.22, .61, .36, 1);
    --rv-step: 55ms;      /* فاصله‌ی ورود پیاپی اعضای یک گروه */
    --rv-rise: 16px;
}

/* ---------- ۱) موتور مشترکِ نمایان‌شدن ----------
   عمداً با animation نوشته شده، نه transition: کارت‌ها transition مخصوصِ hover
   دارند و اگر ورود هم transition بود، لیستِ transition همدیگر را پاک می‌کردند
   و تأخیرِ آبشاری از بین می‌رفت. animation با transition تداخل ندارد. */
.rv { opacity: 0; }

.rv.is-in {
    animation-duration: var(--rv-dur);
    animation-timing-function: var(--rv-ease);
    animation-delay: calc(var(--rv-i, 0) * var(--rv-step));
    animation-fill-mode: both;
    animation-name: rv-fade;
}

.rv.rv-up.is-in { animation-name: rv-up; }
.rv.rv-zoom.is-in { animation-name: rv-zoom; }
.rv.rv-wipe.is-in { animation-name: rv-wipe; }

@keyframes rv-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes rv-up {
    from { opacity: 0; transform: translateY(var(--rv-rise)); }
    to { opacity: 1; transform: none; }
}

@keyframes rv-zoom {
    from { opacity: 0; transform: scale(.94); }
    to { opacity: 1; transform: none; }
}

/* پرده‌ی بازشونده — در RTL از راست باز می‌شود */
@keyframes rv-wipe {
    from { opacity: 0; clip-path: inset(0 0 0 100%); }
    to { opacity: 1; clip-path: inset(0 0 0 0); }
}

@keyframes rv-wipe-ltr {
    from { opacity: 0; clip-path: inset(0 100% 0 0); }
    to { opacity: 1; clip-path: inset(0 0 0 0); }
}

[dir="ltr"] .rv.rv-wipe.is-in { animation-name: rv-wipe-ltr; }

/* عنوان‌ها در قالب مینیمال: محو + نشستنِ فاصله‌ی حروف */
.rv-head { opacity: 0; }

.rv-head.is-in {
    animation: rv-head .82s var(--rv-ease) calc(var(--rv-i, 0) * var(--rv-step)) both;
}

@keyframes rv-head {
    from { opacity: 0; transform: translateY(14px); filter: blur(7px); letter-spacing: .04em; }
    to { opacity: 1; transform: none; filter: blur(0); letter-spacing: inherit; }
}

/* ---------- ۲) تصاویر: ورود نرم پس از بارگذاری ---------- */
.img-in {
    opacity: 0;
    transform: scale(1.03);
    transition: opacity .6s var(--rv-ease), transform .8s var(--rv-ease);
}

.img-in.is-loaded {
    opacity: 1;
    transform: none;
}

/* ---------- ۳) جدول‌ها: ورود سطر‌به‌سطر ---------- */
.tbl-in tbody > tr { opacity: 0; }

.tbl-in.is-in tbody > tr {
    animation: rv-row .45s var(--rv-ease) calc(var(--rv-i, 0) * 45ms) both;
}

@keyframes rv-row {
    from { opacity: 0; transform: translateY(9px); }
    to { opacity: 1; transform: none; }
}

/* =============================================================================
   قالب ۱ — کلاسیک: حرکت کم، رسمی، بدون دست‌کاری تصویر
   ============================================================================= */
body.public-theme-classic {
    --rv-dur: .48s;
    --rv-step: 40ms;
    --rv-rise: 10px;
}

body.public-theme-classic .post-classic,
body.public-theme-classic .prod-card,
body.public-theme-classic .svc-card,
body.public-theme-classic .public-card {
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}

body.public-theme-classic .post-classic:hover,
body.public-theme-classic .prod-card:hover,
body.public-theme-classic .svc-card:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--pub-primary) 55%, #d9d9d9);
    box-shadow: 0 8px 20px rgba(0, 0, 0, .07);
}

/* =============================================================================
   قالب ۲ — مینیمال: قالبِ «حرکت»
   پرده‌ای که از لبه‌ی شروع باز می‌شود + محوِ تایپوگرافیک + ورود آبشاری
   ============================================================================= */
body.public-theme-editorial {
    --rv-dur: .78s;
    --rv-ease: cubic-bezier(.16, 1, .3, 1);
    --rv-step: 72ms;
    --rv-rise: 22px;
}

/* تصویر: کمی بزرگ‌تر وارد می‌شود و سر جایش می‌نشیند */
body.public-theme-editorial .img-in { transform: scale(1.07); }

/* کارت: خطِ رنگیِ برند از لبه‌ی شروع رشد می‌کند */
body.public-theme-editorial .post-classic,
body.public-theme-editorial .prod-card,
body.public-theme-editorial .svc-card {
    position: relative;
    transition: transform .35s var(--rv-ease), box-shadow .35s var(--rv-ease);
}

body.public-theme-editorial .post-classic::after,
body.public-theme-editorial .prod-card::after,
body.public-theme-editorial .svc-card::after {
    content: "";
    position: absolute;
    inset-block-end: 0;
    inset-inline-start: 0;
    block-size: 2px;
    inline-size: 0;
    background: var(--pub-primary);
    transition: inline-size .4s var(--rv-ease);
}

body.public-theme-editorial .post-classic:hover,
body.public-theme-editorial .prod-card:hover,
body.public-theme-editorial .svc-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 14px 30px rgba(0, 0, 0, .08);
}

body.public-theme-editorial .post-classic:hover::after,
body.public-theme-editorial .prod-card:hover::after,
body.public-theme-editorial .svc-card:hover::after { inline-size: 100%; }

/* تصویر کارت: بزرگ‌نماییِ آرام داخل قابِ ثابت */
body.public-theme-editorial .prod-cover,
body.public-theme-editorial .cover-img {
    transition: transform .6s var(--rv-ease);
}

body.public-theme-editorial .prod-card:hover .prod-cover,
body.public-theme-editorial .post-classic:hover .cover-img { transform: scale(1.05); }

/* =============================================================================
   قالب ۳ — نرم: قالبِ «رنگ»
   تصاویر با فیلترِ ملایم و پوششِ هم‌رنگِ برند؛ روی هوور رنگِ کامل برمی‌گردد
   ============================================================================= */
body.public-theme-soft {
    --rv-dur: .66s;
    --rv-ease: cubic-bezier(.34, 1.4, .64, 1);
    --rv-step: 60ms;
    --rv-rise: 14px;
    --tint: color-mix(in srgb, var(--pub-primary) 26%, transparent);
    --glow: color-mix(in srgb, var(--pub-primary) 24%, transparent);
}

/* قابِ تصویر: فیلتر رنگی + لایه‌ی تینتِ برند */
body.public-theme-soft .prod-card > a,
body.public-theme-soft .img-thumbnail-variant-1 figure,
body.public-theme-soft .tinted {
    position: relative;
    display: block;
    overflow: hidden;
}

body.public-theme-soft .prod-card > a::after,
body.public-theme-soft .img-thumbnail-variant-1 figure::after,
body.public-theme-soft .tinted::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--tint);
    mix-blend-mode: color;
    opacity: 1;
    transition: opacity .45s var(--rv-ease);
    pointer-events: none;
}

body.public-theme-soft .prod-cover,
body.public-theme-soft .cover-img,
body.public-theme-soft .img-thumbnail-variant-1 figure img {
    filter: saturate(.68) contrast(1.05) brightness(1.02);
    transition: filter .45s var(--rv-ease), transform .6s var(--rv-ease);
}

body.public-theme-soft .prod-card:hover > a::after,
body.public-theme-soft .img-thumbnail-variant-1 figure:hover::after,
body.public-theme-soft .tinted:hover::after { opacity: 0; }

body.public-theme-soft .prod-card:hover .prod-cover,
body.public-theme-soft .img-thumbnail-variant-1 figure:hover img {
    filter: saturate(1.06) contrast(1) brightness(1);
    transform: scale(1.045);
}

/* سایه‌ی هم‌رنگِ برند به‌جای سایه‌ی خاکستری */
body.public-theme-soft .post-classic,
body.public-theme-soft .prod-card,
body.public-theme-soft .svc-card,
body.public-theme-soft .public-card {
    transition: transform .38s var(--rv-ease), box-shadow .38s var(--rv-ease);
}

body.public-theme-soft .post-classic:hover,
body.public-theme-soft .prod-card:hover,
body.public-theme-soft .svc-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 20px 44px var(--glow);
}

/* شست‌وشوی رنگیِ بسیار ملایم پشت بخش‌های روشن */
body.public-theme-soft .bg-gray-lighter {
    background-image:
        radial-gradient(120% 80% at 100% 0%, color-mix(in srgb, var(--pub-primary) 9%, transparent) 0%, transparent 62%),
        radial-gradient(100% 70% at 0% 100%, color-mix(in srgb, var(--pub-dark) 6%, transparent) 0%, transparent 58%);
}

/* سرصفحه‌ی جدول با تهِ‌رنگِ برند */
body.public-theme-soft .tbl-in thead th {
    background: color-mix(in srgb, var(--pub-primary) 12%, #fff);
    border-block-end-color: color-mix(in srgb, var(--pub-primary) 34%, #e6e6e6);
}

body.public-theme-soft .tbl-in tbody > tr:hover {
    background: color-mix(in srgb, var(--pub-primary) 6%, transparent);
}

/* =============================================================================
   احترام به تنظیم کاربر: بدون حرکت
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {

    /* همه‌چیز بی‌درنگ در جای نهایی خودش دیده می‌شود.
       فیلترِ رنگیِ قالب «نرم» عمداً دست‌نخورده می‌ماند: آن یک تصمیم طراحی است،
       نه حرکت — و حذفش ظاهرِ قالب را عوض می‌کند نه راحتیِ کاربر را. */
    .rv,
    .rv.is-in,
    .rv-head,
    .rv-head.is-in,
    .img-in,
    .tbl-in tbody > tr,
    .tbl-in.is-in tbody > tr {
        opacity: 1 !important;
        transform: none !important;
        clip-path: none !important;
        letter-spacing: inherit !important;
        animation: none !important;
        transition: none !important;
    }

    .rv-head,
    .rv-head.is-in { filter: none !important; }

    /* حرکت‌های هوور و اسلایدر */
    body.public-theme-classic .post-classic,
    body.public-theme-classic .prod-card,
    body.public-theme-classic .svc-card,
    body.public-theme-classic .public-card,
    body.public-theme-editorial .post-classic,
    body.public-theme-editorial .prod-card,
    body.public-theme-editorial .svc-card,
    body.public-theme-editorial .prod-cover,
    body.public-theme-editorial .cover-img,
    body.public-theme-soft .post-classic,
    body.public-theme-soft .prod-card,
    body.public-theme-soft .svc-card,
    body.public-theme-soft .public-card,
    body.public-theme-soft .prod-cover,
    body.public-theme-soft .cover-img,
    body.public-theme-soft .img-thumbnail-variant-1 figure img {
        transition: none !important;
    }

    body.public-theme-soft .home-swiper .swiper-slide.is-active { animation: none !important; }
}

/* =============================================================================
   امضاهای بصری تکمیلی هر قالب — افزودنیِ سطح‌دوم
   -----------------------------------------------------------------------------
   همه‌چیز فقط opacity/transform/box-shadow است؛ هیچ قاعده‌ای عرض، ارتفاع یا
   جای عناصر را تغییر نمی‌دهد تا ساختار صفحات دست‌نخورده بماند.
   رنگ‌ها از متغیرهای مدیریت (--pub-primary / --pub-dark) می‌آیند.
   ============================================================================= */

/* ---------- نوار پیشرفت مطالعه (هر سه قالب، امضای متفاوت) ----------
   فقط در مرورگرهایی که Scroll-Driven Animations دارند فعال می‌شود؛
   بقیه مرورگرها اصلاً نمی‌بینندش (@supports) و هیچ‌چیز تغییر نمی‌کند. */
@supports (animation-timeline: scroll()) {
    .page::after {
        content: "";
        position: fixed;
        top: 0;
        inset-inline: 0;
        block-size: 3px;
        z-index: 3000;
        pointer-events: none;
        background: linear-gradient(90deg,
            var(--pub-dark, #20242b),
            var(--pub-primary, #f6d014));
        transform: scaleX(0);
        transform-origin: 100% 50%; /* در RTL از راست پر می‌شود */
        animation: theme-progress linear both;
        animation-timeline: scroll(root block);
    }

    [dir="ltr"] .page::after { transform-origin: 0 50%; }

    @keyframes theme-progress {
        from { transform: scaleX(0); }
        to { transform: scaleX(1); }
    }

    /* امضای هر قالب */
    body.public-theme-classic .page::after { block-size: 3px; }
    body.public-theme-editorial .page::after { block-size: 2px; }
    body.public-theme-soft .page::after {
        block-size: 4px;
        border-radius: 99px;
        box-shadow: 0 0 12px var(--glow, color-mix(in srgb, var(--pub-primary) 24%, transparent));
    }
}

/* =============================================================================
   قالب ۱ — کلاسیک: برقِ عبوریِ ملایم روی دکمه‌ی اصلی (لمسِ رسمی و مطمئن)
   ============================================================================= */
body.public-theme-classic .button-primary {
    position: relative;
    overflow: hidden;
}

body.public-theme-classic .button-primary::before {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: -80%;
    inline-size: 55%;
    transform: skewX(-18deg);
    background: linear-gradient(90deg, transparent, rgba(255, 255, 255, .38), transparent);
    transition: inset-inline-start .55s ease;
    pointer-events: none;
}

body.public-theme-classic .button-primary:hover::before {
    inset-inline-start: 130%;
}

/* =============================================================================
   قالب ۲ — مینیمال: خطِ برند زیر تیترها هنگام ورود «رشد» می‌کند
   (فقط وقتی JS فعال است و موتور ورود، کلاس rv-head را داده باشد)
   ============================================================================= */
body.public-theme-editorial .heading-decorated::after {
    transition: transform .8s var(--rv-ease, cubic-bezier(.16, 1, .3, 1)) .15s;
    transform-origin: 100% 50%; /* از سمت شروع (راست) رشد می‌کند */
}

body.public-theme-editorial .heading-decorated.rv-head:not(.is-in)::after {
    transform: scaleX(0);
}

/* =============================================================================
   قالب ۳ — نرم: هاله‌ی تنفسِ برند پشت هیرو + درخشش دکمه‌ی اصلی
   ============================================================================= */
body.public-theme-soft .home-hero {
    position: relative;
}

body.public-theme-soft .home-hero::after {
    content: "";
    position: absolute;
    inset: 0;
    pointer-events: none;
    background: radial-gradient(62% 55% at 50% 45%,
        var(--glow, color-mix(in srgb, var(--pub-primary) 24%, transparent)),
        transparent 72%);
    opacity: .5;
}

@media (prefers-reduced-motion: no-preference) {
    body.public-theme-soft .home-hero::after {
        animation: sf-breathe 9s ease-in-out infinite;
    }

    @keyframes sf-breathe {
        0%, 100% { opacity: .32; transform: scale(1); }
        50% { opacity: .68; transform: scale(1.05); }
    }
}

body.public-theme-soft .button-primary {
    transition: box-shadow .4s var(--rv-ease, ease), transform .3s var(--rv-ease, ease);
}

body.public-theme-soft .button-primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 12px 28px var(--glow, color-mix(in srgb, var(--pub-primary) 24%, transparent));
}

/* =============================================================================
   ورودِ اولیه‌ی صفحه (Load Choreography) — سبکِ هر قالب
   -----------------------------------------------------------------------------
   • فقط CSS است: بدون وابستگی به JS. اگر اسکریپت اجرا نشود هم محتوا گم نمی‌شود،
     چون «backwards» فقط تا لحظه‌ی شروع انیمیشن پنهان می‌کند و انیمیشن CSS همیشه
     اجرا می‌شود — همان باگ معروفِ WOW (مطب پنهان تا اسکرول) اینجا ممکن نیست.
   • فقط عناصر قطعاً بالای صفحه (هدر، هیرو، تیتر صفحه) — نه کل صفحه.
   • همه‌چیز opacity/transform/filter است؛ هیچ ویژگی چیدمانی عوض نمی‌شود.
   ============================================================================= */
.page-header { animation: ld-fade .8s var(--rv-ease) backwards; }

.home-hero .home-hero__inner,
.home-swiper .home-slide-copy { animation: ld-hero 1s var(--rv-ease) .25s backwards; }

.page-hero .container { animation: ld-hero .9s var(--rv-ease) .15s backwards; }

/* امضای هر قالب */
body.public-theme-classic :is(.page-header, .home-hero .home-hero__inner, .home-swiper .home-slide-copy, .page-hero .container) {
    animation-name: ld-up;
}

body.public-theme-editorial :is(.page-header, .home-hero .home-hero__inner, .home-swiper .home-slide-copy, .page-hero .container) {
    animation-name: ld-blur;
}

body.public-theme-editorial .home-swiper .home-slide-copy { animation-duration: .85s; }

body.public-theme-soft :is(.page-header, .home-hero .home-hero__inner, .home-swiper .home-slide-copy, .page-hero .container) {
    animation-name: ld-zoom;
}

@keyframes ld-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes ld-up {
    from { opacity: 0; transform: translateY(14px); }
    to { opacity: 1; transform: none; }
}

@keyframes ld-blur {
    from { opacity: 0; transform: translateY(18px); filter: blur(8px); }
    to { opacity: 1; transform: none; filter: blur(0); }
}

@keyframes ld-zoom {
    from { opacity: 0; transform: scale(.96) translateY(10px); }
    to { opacity: 1; transform: none; }
}

/* =============================================================================
   تایمینگ اسکرول — کندتر و نرم‌تر (حسِ «حرکت»، نه «پرش»)
   ============================================================================= */
body.public-theme-classic {
    --rv-dur: .85s;
    --rv-step: 70ms;
    --rv-rise: 22px;
    --rv-ease: cubic-bezier(.22, .8, .32, 1);
}

body.public-theme-editorial { --rv-dur: .95s; --rv-step: 80ms; --rv-rise: 26px; }

body.public-theme-soft {
    --rv-dur: 1s;
    --rv-step: 75ms;
    --rv-rise: 20px;
    /* فنرِ ملایم‌تر: اوجِ کمتر از قبل تا حسِ پرش ندهد */
    --rv-ease: cubic-bezier(.3, 1.12, .45, 1);
}

/* موبایل: کوتاه‌تر از دسکتاپ، اما نه آن‌قدر سریع که شبیه پرش باشد */
@media (max-width: 575.98px) {
    body.public-theme-classic { --rv-dur: .65s; --rv-step: 55ms; --rv-rise: 14px; }
    body.public-theme-editorial { --rv-dur: .7s; --rv-step: 60ms; --rv-rise: 18px; }
    body.public-theme-soft { --rv-dur: .75s; --rv-step: 58ms; --rv-rise: 15px; }

    .page-header,
    .home-hero .home-hero__inner,
    .home-swiper .home-slide-copy,
    .page-hero .container { animation-duration: .65s; }
}

/* =============================================================================
   احترام مجدد به «کاهش حرکت» برای بخش‌های تازه
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
    .page::after { display: none; }

    .page-header,
    .home-hero .home-hero__inner,
    .home-swiper .home-slide-copy,
    .page-hero .container {
        animation: none !important;
        opacity: 1 !important;
        transform: none !important;
        filter: none !important;
    }

    body.public-theme-classic .button-primary { overflow: visible; }
    body.public-theme-classic .button-primary::before { display: none; }
}

/* =============================================================================
   تقویت امضای حرکتِ کلاسیک و نرم (مینیمال از قبل قوی است)
   -----------------------------------------------------------------------------
   کلاسیک  → ورود از کنار + خطِ رنگی که زیر کارت رشد می‌کند (سلیقه‌ی رسمی)
   نرم     → بزرگ‌نماییِ محسوس + درخشش ملایم هنگام ورود (شخصیتِ رنگیِ پرشور)
   هیچ‌کدام عرض/ارتفاع را تغییر نمی‌دهند — فقط transform/opacity/box-shadow.
   ============================================================================= */

/* ---------- کلاسیک: ورود از سمتِ شروع (راست در RTL، چپ در LTR) ---------- */
body.public-theme-classic .rv.rv-up.is-in { animation-name: cl-slide; }

@keyframes cl-slide {
    from { opacity: 0; transform: translateX(var(--cl-from-x, 26px)) translateY(10px); }
    to { opacity: 1; transform: none; }
}

[dir="ltr"] body.public-theme-classic .rv.rv-up.is-in,
html[lang="en"] body.public-theme-classic .rv.rv-up.is-in { --cl-from-x: -26px; }

/* خطِ رنگ برند زیر کارت که هنگام ورود رشد می‌کند */
body.public-theme-classic .post-classic,
body.public-theme-classic .prod-card,
body.public-theme-classic .svc-card {
    position: relative;
}

body.public-theme-classic .post-classic::after,
body.public-theme-classic .prod-card::after,
body.public-theme-classic .svc-card::after {
    content: "";
    position: absolute;
    inset-block-end: 0;
    inset-inline-start: 0;
    block-size: 2px;
    inline-size: 0;
    background: var(--pub-primary);
    transition: inline-size .55s var(--rv-ease) .1s;
    pointer-events: none;
}

body.public-theme-classic :is(.post-classic, .prod-card, .svc-card).is-in::after {
    inline-size: 100%;
}

/* ---------- نرم: بزرگ‌نماییِ محسوس‌تر + درخششِ ورود ---------- */
body.public-theme-soft .rv.rv-zoom { --zoom-from: .88; }

body.public-theme-soft .rv.rv-zoom.is-in { animation-name: sf-zoom-glow; }

@keyframes sf-zoom-glow {
    from {
        opacity: 0;
        transform: scale(.88) translateY(18px);
        box-shadow: 0 0 0 0 var(--glow);
    }
    to {
        opacity: 1;
        transform: none;
        box-shadow: 0 0 44px -12px var(--glow, color-mix(in srgb, var(--pub-primary) 24%, transparent));
    }
}

/* فروکشِ درخشش بعد از نشستن کارت (باقی‌ماندن سایه‌ی دائم، شلوغ می‌شد)
   هشدار: این keyframes فقط «box-shadow» را انیمیت می‌کند — مطلقاً opacity/transform نه.
   قبلاً وقتی عنصر همان ابتدا در کادر دید بود (watch: is-in + is-done هم‌زمان) این
   انیمیشن *جایگزینِ* rv-zoom می‌شد و چون opacity تعریف‌نشده‌اش از rv-zoom به ارث
   نمی‌رسید، کارت جزئیات محصول/مطلب با opacity:0 دائمی محو می‌ماند. */
body.public-theme-soft .rv.rv-zoom.is-in.is-done {
    animation: sf-glow-settle .7s ease .1s both;
}

@keyframes sf-glow-settle {
    from { box-shadow: 0 0 44px -12px var(--glow, color-mix(in srgb, var(--pub-primary) 24%, transparent)); }
    to { box-shadow: 0 10px 30px rgba(23, 35, 55, .06); }
}

/* تیترهای قالب نرم: ورود با فاصله‌گذاریِ حروف (هم‌خانواده‌ی محوِ تایپوگرافیک) */
body.public-theme-soft .rv-head.is-in {
    animation-name: sf-head-trace;
}

@keyframes sf-head-trace {
    from { opacity: 0; transform: translateY(16px); letter-spacing: .06em; filter: blur(4px); }
    to { opacity: 1; transform: none; letter-spacing: inherit; filter: blur(0); }
}

/* تیترهای قالب کلاسیک: ورودِ رسمی با خطِ زیرینِ کوتاه‌شونده */
body.public-theme-classic .rv-head.is-in {
    animation-name: cl-head;
}

@keyframes cl-head {
    from { opacity: 0; transform: translateY(12px); }
    to { opacity: 1; transform: none; }
}

/* انیمیشن لود هیرو هم در کلاسیک و نرم محسوس‌تر */
body.public-theme-classic .page-header { animation-name: ld-fade; }
body.public-theme-soft .page-header { animation-name: ld-zoom; }

/* ---------- تور ایمنی نهایی: هیچ محتوایی هرگز نامرئی نمی‌ماند ----------
   هر عنصر rv که وارد شده (is-in) و دوره‌ی انیمیشنش تمام شده (is-done)، باید
   دیده شود — مستقل از اینکه انیمیشنِ جایگزینِ قالب چیست. قانونِ is-done با
   !important هر حالتِ «پایانِ opacity صفر» را پاک می‌کند؛ ورودِ درحال‌اجرای
   عناصری که هنوز is-done ندارند دست‌نخورده می‌ماند و انیمیشن‌های ورودی را
   نمی‌شکند (fill-mode: both خودشان نهایت را تضمین می‌کنند). */
.rv.is-in.is-done {
    opacity: 1 !important;
}

.rv-head.is-in.is-done {
    opacity: 1 !important;
}

.tbl-in.is-in.is-done tbody > tr {
    opacity: 1 !important;
}
