/* ==========================================================================
   VENDORHA — جلوه‌های پس‌زمینه
   --------------------------------------------------------------------------
   لایه‌های تزئینی که پشت محتوا می‌نشینند. همه `pointer-events: none`
   دارند تا کلیک و انتخاب متن را نگیرند.
   ========================================================================== */

.vfx-host {
  position: relative;
}

/* محتوای میزبان باید بالای لایه بماند.

   نکته: این قاعده روی `body` اعمال نمی‌شود. اگر بشود، همهٔ عناصر
   سطح‌بالا (کشوی سبد، مودال، منوی موبایل) `position: relative` و
   `z-index: 1` می‌گیرند و در یک لایهٔ مسطح حبس می‌شوند — کشویی باز
   نمی‌شود و صفحه قفل می‌کند. */
.vfx-host:not(body) > *:not(.vfx-layer) {
  position: relative;
  z-index: 1;
}

/* isolation هم فقط برای میزبان‌های محلی لازم است */
.vfx-host:not(body) { isolation: isolate; }

.vfx-layer {
  position: absolute;
  inset: 0;
  /* بدون این، لایه روی body عرض صفحه را بزرگ می‌کند و نوار اسکرول
     افقی می‌سازد. */
  max-width: 100%;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  border-radius: inherit;
}

/* لایه روی کل صفحه: body ممکن است بلندتر از دید باشد، پس لایه
   ثابت می‌ماند تا با اسکرول کش نیاید. */
body.vfx-host > .vfx-layer {
  position: fixed;
  inset: 0;
  z-index: -1;
}

/* ==========================================================================
   شفق قطبی
   ========================================================================== */
.vfx-aurora::before,
.vfx-aurora::after {
  content: "";
  position: absolute;
  inset: -45%;
  background:
    radial-gradient(38% 46% at 22% 30%, var(--vfx-c1) 0%, transparent 68%),
    radial-gradient(42% 52% at 78% 22%, var(--vfx-c2) 0%, transparent 68%),
    radial-gradient(46% 44% at 50% 82%, var(--vfx-c3) 0%, transparent 68%);
  animation: vfx-drift var(--vfx-dur, 16s) ease-in-out infinite alternate;
  will-change: transform;
}

.vfx-aurora::after {
  animation-duration: calc(var(--vfx-dur, 16s) * 1.6);
  animation-direction: alternate-reverse;
  opacity: .68;
}

@keyframes vfx-drift {
  from { transform: translate3d(-5%, -4%, 0) scale(1); }
  to   { transform: translate3d(5%, 4%, 0) scale(1.14); }
}

/* ==========================================================================
   گرادیان نفس‌کش
   ========================================================================== */
.vfx-gradient {
  animation: vfx-breathe var(--vfx-dur, 18s) ease-in-out infinite;
  will-change: background-position;
}

@keyframes vfx-breathe {
  0%   { background-position: 0% 50%; }
  50%  { background-position: 100% 50%; }
  100% { background-position: 0% 50%; }
}

/* ==========================================================================
   مش رنگی
   ========================================================================== */
.vfx-mesh {
  animation: vfx-mesh-move var(--vfx-dur, 24s) ease-in-out infinite alternate;
  will-change: transform, filter;
  filter: blur(30px);
}

@keyframes vfx-mesh-move {
  from { transform: scale(1) rotate(0deg); }
  to   { transform: scale(1.18) rotate(6deg); }
}

/* ==========================================================================
   موج‌ها
   ========================================================================== */
.vfx-waves span {
  position: absolute;
  inset-inline: -50%;
  bottom: -60%;
  height: 140%;
  border-radius: 43%;
  animation: vfx-wave linear infinite;
  will-change: transform;
}

@keyframes vfx-wave {
  from { transform: rotate(0deg) translateY(0); }
  to   { transform: rotate(360deg) translateY(0); }
}

/* ==========================================================================
   شبکه
   ========================================================================== */
.vfx-grid {
  background-size: 44px 44px;
  animation: vfx-grid-move var(--vfx-dur, 30s) linear infinite;
  will-change: background-position;
  -webkit-mask-image: radial-gradient(70% 70% at 50% 45%, #000 30%, transparent 100%);
  mask-image: radial-gradient(70% 70% at 50% 45%, #000 30%, transparent 100%);
}

@keyframes vfx-grid-move {
  from { background-position: 0 0; }
  to   { background-position: 44px 44px; }
}

/* ==========================================================================
   بافت دانه‌دار
   --------------------------------------------------------------------------
   نویز با SVG درون‌خطی ساخته می‌شود — بدون فایل تصویر.
   ========================================================================== */
.vfx-noise {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
  animation: vfx-noise-shift 8s steps(6) infinite;
  mix-blend-mode: overlay;
}

@keyframes vfx-noise-shift {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-4%, 3%); }
  40%  { transform: translate(3%, -4%); }
  60%  { transform: translate(-3%, -3%); }
  80%  { transform: translate(4%, 3%); }
  100% { transform: translate(0, 0); }
}

/* ==========================================================================
   نورافکن
   ========================================================================== */
.vfx-spotlight {
  background: radial-gradient(
    380px circle at var(--vfx-x, 50%) var(--vfx-y, 40%),
    var(--vfx-c1) 0%, transparent 72%);
  transition: background-position .2s ease-out;
}

/* ==========================================================================
   canvas
   ========================================================================== */
.vfx-canvas {
  display: block;
  width: 100%;
  height: 100%;
}

/* ==========================================================================
   پیش‌نمایش در ادمین و پنل
   ========================================================================== */
.vfx-preview {
  position: relative;
  height: 150px;
  border-radius: var(--r-md, 14px);
  overflow: hidden;
  background: var(--surface, #fff);
  border: 1px solid var(--line, #e2eae5);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: border-color .2s ease, box-shadow .2s ease,
              transform .2s ease;
}

.vfx-preview:hover {
  transform: translateY(-2px);
  box-shadow: var(--sh-md, 0 4px 12px rgba(0,0,0,.08));
}

.vfx-preview.is-picked {
  border-color: var(--green, #00A859);
  box-shadow: 0 0 0 3px var(--green-100, #D9F5E6);
}

.vfx-preview-label {
  position: relative;
  z-index: 2;
  font-size: .82rem;
  font-weight: 700;
  color: var(--ink, #101614);
  text-align: center;
  padding: 8px 12px;
  border-radius: 999px;
  background: var(--glass-bg-strong, rgba(255,255,255,.9));
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}

.vfx-grid-pick {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 14px;
  margin: 16px 0;
}

.vfx-note {
  font-size: .78rem;
  color: var(--slate, #566560);
  line-height: 1.9;
  margin-top: 6px;
}

/* ==========================================================================
   احترام به ترجیح کاربر
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .vfx-layer,
  .vfx-layer::before,
  .vfx-layer::after,
  .vfx-waves span { animation: none !important; }
}

/* ---------- صفحهٔ مدیریت جلوه‌ها ---------- */
.vfx-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin-top: 6px;
}

.vfx-meta small { font-size: .74rem; color: var(--slate); }

.vfx-item { display: flex; flex-direction: column; }

.vfx-make { margin-top: 8px; }
.vfx-make > summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
}
.vfx-make > summary::-webkit-details-marker { display: none; }

.vfx-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 10px;
  padding: 12px;
  border-radius: var(--r-md, 14px);
  background: var(--bg-subtle);
  border: 1px solid var(--line);
}

/* ==========================================================================
   سحابی — سه کانون نوری شناور
   --------------------------------------------------------------------------
   ⚠️ با `aurora` فرق دارد: سه لکه با حرکت **مستقل** و سرعت
   متفاوت، به‌علاوهٔ یک لایهٔ مه رنگی.

   نتیجه عمق بیشتری می‌سازد چون لایه‌ها روی هم می‌لغزند.

   رنگ‌ها از توکن‌های برند می‌آیند — سبز، نه آبی.
   ========================================================================== */
/*
  ⚠️ این‌جا `position` تعریف نمی‌شود — و همین باگ بود.

  قبلاً `position: relative` داشت. `.vfx-nebula` همیشه همراه
  `.vfx-layer` می‌آید و آن یکی `position: absolute` و
  `inset: 0` می‌دهد؛ این قاعده — که پایین‌تر در فایل است و
  ویژگی برابر دارد — آن را باطل می‌کرد.

  نتیجه: لایه از موقعیت مطلق بیرون می‌آمد و چون همهٔ فرزندانش
  مطلق‌اند، ارتفاعش **صفر** می‌شد. سه لکه ساخته می‌شدند ولی
  `overflow: hidden` همان لایهٔ صفرارتفاع کاملاً می‌بریدشان —
  یعنی جلوه به‌کلی نامرئی بود.

  اندازه‌گیری شد: بقیهٔ جلوه‌ها ۱۱۶۶×۳۱۸، سحابی ۱۱۶۶×۰. هیچ
  جلوهٔ دیگری `position` را بازنویسی نمی‌کند؛ این یکی هم نباید.

  ⚠️ `overflow` هم حذف شد — `.vfx-layer` خودش دارد.

  ⚠️ `isolation` می‌ماند: لکه‌ها `z-index` منفی دارند و باید
  داخل همین لایه بمانند، نه پشت میزبان.
*/
.vfx-nebula {
  isolation: isolate;
}

/* لایهٔ مه — پس‌زمینهٔ نرم */
.vfx-nebula::before {
  content: "";
  position: absolute; inset: -45%; z-index: -2;
  opacity: .42;
  filter: blur(52px);
  background:
    radial-gradient(36% 44% at 20% 28%,
                    var(--vfx-c1, #16A34A) 0%, transparent 62%),
    radial-gradient(32% 40% at 80% 22%,
                    var(--vfx-c2, #4ADE80) 0%, transparent 60%),
    radial-gradient(44% 48% at 60% 86%,
                    var(--vfx-c3, #0F5132) 0%, transparent 64%);
  animation: vfx-drift 24s ease-in-out infinite alternate;
  pointer-events: none;
}

/*
  سه لکهٔ مستقل.

  ⚠️ اندازه‌ها درصدیِ **خود لایه** است، نه `vw`/`vh`.

  قبلاً `52vw` و `min-width: 340px` بود؛ یعنی لکه‌ها همیشه به
  اندازهٔ پنجره حساب می‌شدند. روی پس‌زمینهٔ تمام‌صفحه درست
  درمی‌آمد، ولی داخل کارت پیش‌نمایش گالری — که چند صد پیکسل
  است — لکه‌ها چند برابر کادر می‌شدند و تقریباً همه‌شان بیرون
  می‌افتاد. ادمین جلوه را انتخاب می‌کرد و چیزی نمی‌دید.

  با درصد، همان ترکیب در هر اندازه‌ای بازتولید می‌شود: در
  پس‌زمینهٔ تمام‌صفحه تقریباً همان مقیاس قبلی، و در کارت کوچک
  یک نسخهٔ کوچک‌شدهٔ همان.

  ⚠️ دایره نیستند، بیضی‌اند — و عمدی.

  با `aspect-ratio: 1` در کادرِ پهن‌وکوتاه، لکه به اندازهٔ
  عرض بلند می‌شد و بیرون می‌زد. عرض و ارتفاعِ جدا یعنی لکه
  با هر دو بُعدِ میزبان کش می‌آید. با این حجم محوشدگی، چشم
  تفاوت بیضی و دایره را نمی‌بیند.

  ⚠️ محوشدگی هم باید با اندازه بزرگ و کوچک شود.

  `blur(90px)` روی کارت ۳۲۰ پیکسلی همه‌چیز را یکدست می‌کرد.
  حالا `--vfx-blur` است و لایهٔ تمام‌صفحه مقدار بزرگ‌تر
  می‌گیرد (قاعدهٔ `body.vfx-host` پایین‌تر).
*/
.vfx-nebula > .vfx-orb {
  position: absolute; z-index: -1;
  border-radius: 50%;
  filter: blur(var(--vfx-blur, 42px));
  will-change: transform;
  pointer-events: none;
}

.vfx-nebula > .vfx-orb:nth-child(1) {
  width: 74%; height: 118%;
  inset-inline-start: -14%; top: -30%;
  opacity: .62;
  background: radial-gradient(circle,
              var(--vfx-c1, #16A34A) 0%, transparent 68%);
  animation: vfx-orb1 26s ease-in-out infinite alternate;
}

.vfx-nebula > .vfx-orb:nth-child(2) {
  width: 60%; height: 96%;
  inset-inline-end: -16%; top: -8%;
  opacity: .52;
  background: radial-gradient(circle,
              var(--vfx-c2, #4ADE80) 0%, transparent 68%);
  animation: vfx-orb2 32s ease-in-out infinite alternate;
}

.vfx-nebula > .vfx-orb:nth-child(3) {
  width: 82%; height: 108%;
  inset-inline-start: 26%; bottom: -46%;
  opacity: .42;
  background: radial-gradient(circle,
              var(--vfx-c3, #0F5132) 0%, transparent 68%);
  animation: vfx-orb3 29s ease-in-out infinite alternate;
}

/*
  ⚠️ روی پس‌زمینهٔ تمام‌صفحه، محوشدگی باید بیشتر باشد.

  همان نرمیِ نسخهٔ قبل (۹۰ پیکسل)، بدون اینکه کارت کوچک
  گالری را یکدست و بی‌شکل کند.

  انتخابگر همان چیزی است که بالاتر لایهٔ تمام‌صفحه را
  `fixed` می‌کند — یعنی تنها جای واقعی «پس‌زمینهٔ صفحه».
*/
body.vfx-host > .vfx-layer.vfx-nebula { --vfx-blur: 90px; }

@keyframes vfx-drift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  50%  { transform: translate3d(3%, -3%, 0) scale(1.1); }
  100% { transform: translate3d(-3%, 2%, 0) scale(1.05); }
}
@keyframes vfx-orb1 {
  to { transform: translate3d(7vw, 9vh, 0) scale(1.18); }
}
@keyframes vfx-orb2 {
  to { transform: translate3d(-9vw, 12vh, 0) scale(1.12); }
}
@keyframes vfx-orb3 {
  to { transform: translate3d(6vw, -11vh, 0) scale(1.22); }
}

/* تم تیره — شدت کمتر تا متن خوانا بماند */
html[data-theme="dark"] .vfx-nebula::before { opacity: .28; }
html[data-theme="dark"] .vfx-nebula > .vfx-orb:nth-child(1) { opacity: .4; }
html[data-theme="dark"] .vfx-nebula > .vfx-orb:nth-child(2) { opacity: .3; }
html[data-theme="dark"] .vfx-nebula > .vfx-orb:nth-child(3) { opacity: .24; }

/* شدت */
.vfx-nebula.vfx-subtle::before { opacity: .22; }
.vfx-nebula.vfx-subtle > .vfx-orb { opacity: .24 !important; }
.vfx-nebula.vfx-strong::before { opacity: .6; }

/*
  ⚠️ در موبایل لکه‌ها کوچک‌تر و بدون انیمیشن.

  `filter: blur(90px)` روی سطح بزرگ پرهزینه است و باتری
  دستگاه‌های ضعیف را می‌خورد.
*/
@media (max-width: 640px) {
  .vfx-nebula > .vfx-orb {
    filter: blur(60px);
    animation: none;
  }
  .vfx-nebula::before {
    filter: blur(40px);
    animation: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .vfx-nebula::before,
  .vfx-nebula > .vfx-orb { animation: none !important; }
}

/* ==========================================================================
   فرم جلوه در پنل — انتخابگرهای رنگ
   --------------------------------------------------------------------------
   ⚠️ سه رنگ کنار هم، نه زیر هم.

   فرم داخل کارت باریک گالری می‌نشیند؛ سه ردیف جدا، دکمهٔ
   ذخیره را از دید بیرون می‌برد.
   ========================================================================== */
.fx-colors {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 8px;
  margin: 6px 0 10px;
}

.fx-colors .field { min-width: 0; }

/* ⚠️ برچسب باید در یک خط بماند.
   «رنگ یکم» در ستونِ یک‌سومِ کارتِ باریکِ گالری می‌شکست و ردیف
   رنگ‌ها دو برابر بلند می‌شد. */
.fx-colors .field > span {
  font-size: .78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.fx-colors input[type="color"] {
  inline-size: 100%;
  block-size: 38px;
  padding: 2px;
  border: 1px solid var(--line, #e2eae5);
  border-radius: var(--r-sm, 10px);
  background: var(--surface, #fff);
  cursor: pointer;
}

/* ⚠️ بدون این، سافاری و فایرفاکس حاشیهٔ داخلی خودشان را می‌گذارند */
.fx-colors input[type="color"]::-webkit-color-swatch-wrapper { padding: 0; }
.fx-colors input[type="color"]::-webkit-color-swatch {
  border: 0;
  border-radius: var(--r-xs, 7px);
}
