/* ===========================================================
   Urealm — الجدار والبنر.

   ▸ **البطاقات موضوعةٌ لا متدفّقة.** يحسب `ui/Wall.js` موضع كلّ
     بطاقة ويكتبه في `--x/--y/--w`، فالترتيب يقرأ من فوق إلى تحت
     كما رُتّب. ولو تُركت لـ`columns` الأصليّة لملأت عمودًا كاملًا
     قبل أن تنتقل إلى الذي يليه، فيضيع ترتيب الأحدث.

   ▸ **والصندوق يقف قبل صورته.** `aspect-ratio` من نسبةٍ محفوظة مع
     العنصر، فالجدار كاملُ المقاسات من أوّل إطار ولا يقفز حين تصل
     الصور.

   ▸ **ولا مربّع أبيض في الانتظار:** علامة Urealm تحمل حالة الصورة
     الحقيقية، ومن لا صورة له يأخذ Hero لونيًا متحركًا وأيقونته.
   =========================================================== */

.wall {
  position: relative;
  inline-size: 100%;
  /* الارتفاع يكتبه الجدار بعد التوزيع؛ هذا يمنع ارتجافةً قبل أوّل
     قياس على الشاشات الضيّقة. */
  min-block-size: 40px;
}

.tile {
  position: absolute;
  /* الموضع منطقيّ أصلًا: `inset-inline-start` يبدأ من اليمين في RTL
     ومن اليسار في LTR. هذا يلغي ضرب `--x` في `--flip` داخل
     `translate`؛ الضرب في CSS غير ثابت في عارض الملف المحلي، وكان
     يستطيع دفع عمود كامل خارج المنفذ ثم يخفيه `overflow-x`. */
  inset-block-start: var(--y, 0px);
  inset-inline-start: var(--x, 0px);
  inline-size: var(--w);
  max-inline-size: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  color: inherit;
  text-decoration: none;
  border-radius: var(--r-lg);
}

/* **لا انتقال على `translate`.** قيمته الأولى `none`، فأوّل توزيعٍ
   ينزلق من الصفر: يفتح القارئُ الصفحةَ فيرى البطاقات تتسلّل إلى
   أماكنها بدل أن يجدها مبنيّة. والغاية من حفظ النسب سلفًا هي أن
   يقف الجدار كاملًا في أوّل إطار — فانتقالٌ هنا يهدم ما بُني له. */

.tile:hover { text-decoration: none; }

.tile__link {
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  min-inline-size: 0;
  color: inherit;
  text-decoration: none;
  border-radius: inherit;
}
.tile__link:hover { text-decoration: none; }
.tile__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 4px; }

.tile__menu {
  position: absolute;
  z-index: 9;
  inset-block-start: 6px;
  inset-inline-end: 6px;
  display: grid;
  place-items: center;
  inline-size: 36px;
  block-size: 36px;
  padding: 0;
  border: 1px solid rgb(255 255 255 / 16%);
  border-radius: 50%;
  background: rgb(8 9 11 / 48%);
  color: #fff;
  box-shadow: 0 4px 14px rgb(0 0 0 / 18%);
  opacity: .88;
  cursor: pointer;
  backdrop-filter: blur(9px) saturate(1.1);
  -webkit-backdrop-filter: blur(9px) saturate(1.1);
  -webkit-tap-highlight-color: transparent;
}
.tile:hover .tile__menu,
.tile__menu:focus-visible { opacity: 1; }
.tile__menu:active { transform: scale(.92); }

.tile__pin {
  position: absolute;
  z-index: 8;
  inset-block-start: 12px;
  inset-inline-start: 12px;
  display: grid;
  place-items: center;
  inline-size: 22px;
  block-size: 22px;
  color: #fff;
  mix-blend-mode: difference;
  filter: drop-shadow(0 1px 2px rgb(0 0 0 / 28%));
  pointer-events: none;
}

/* ----------------------- الصورة ----------------------- */

.tile__frame {
  position: relative;
  isolation: isolate;
  aspect-ratio: 1 / var(--ratio);
  inline-size: 100%;
  overflow: hidden;
  border-radius: var(--r-lg);
  background: var(--bg-surface-2);
  transition: box-shadow var(--dur-2) var(--ease), transform var(--dur-2) var(--ease-out);
}

/* الرفعة على البطاقة كلّها لا على إطارها: رفعتان تتراكبان فتقفز
   ثمانيةَ بكسلٍ زائدة ويُقصّ ظلّها. */
.tile:hover .tile__frame { box-shadow: var(--shadow-2); }

.tile__tiny,
.tile__img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  display: block;
}

/* اللُقيمة عشرون بكسلًا مكبّرة: التنعيم وحده يكفي، ولا حاجة لمرشّح. */
.tile__tiny { z-index: 1; filter: blur(0); transform: scale(1.04); }

.tile__img { z-index: 2; opacity: 0; transition: opacity var(--dur-3) var(--ease); }
.tile__frame[data-loaded="yes"] .tile__img { opacity: 1; }

/* ---------------- Hero تلقائي بلا صورة ----------------

   المعرّف يختار الألوان والمواضع والسرعة؛ لذلك الغلاف ثابت بين
   الجلسات لكنه لا يتكرر بين البطاقات. الطبقات تتحرك داخل الإطار
   وحده، فلا تغيّر مقاس الجدار ولا تسبب قفزة في التخطيط. */
.tile__frame[data-auto-hero="yes"],
.banner[data-auto-hero="yes"] {
  isolation: isolate;
  display: grid;
  place-items: center;
  background:
    linear-gradient(
      var(--hero-angle, 145deg),
      color-mix(in srgb, var(--hero-a) 42%, var(--bg-deep)),
      color-mix(in srgb, var(--hero-c) 34%, var(--bg-void))
    );
}

.tile__frame[data-auto-hero="yes"]::before,
.banner[data-auto-hero="yes"]::before {
  content: "";
  position: absolute;
  z-index: -2;
  inset: -36%;
  background:
    radial-gradient(circle at var(--hero-x1) var(--hero-y1), var(--hero-a), transparent 37%),
    radial-gradient(circle at var(--hero-x2) var(--hero-y2), var(--hero-b), transparent 42%),
    radial-gradient(circle at 52% 86%, var(--hero-c), transparent 38%);
  opacity: 0.76;
  transform: translate3d(-2%, -1%, 0) rotate(-4deg) scale(1.04);
  animation: auto-hero-drift var(--hero-duration, 18s) ease-in-out var(--hero-delay, 0s) infinite alternate;
}

.tile__frame[data-auto-hero="yes"]::after,
.banner[data-auto-hero="yes"]::after {
  content: "";
  position: absolute;
  z-index: -1;
  inset: 0;
  background:
    linear-gradient(115deg, rgb(255 255 255 / 13%), transparent 32% 68%, rgb(0 0 0 / 12%)),
    radial-gradient(circle at 50% 115%, rgb(255 255 255 / 11%), transparent 55%);
  mix-blend-mode: soft-light;
}

.tile__hero-icon {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
  inline-size: clamp(52px, 31%, 74px);
  aspect-ratio: 1;
  border: 1px solid rgb(255 255 255 / 24%);
  border-radius: 24px;
  color: rgb(255 255 255 / 92%);
  background: rgb(10 12 18 / 22%);
  box-shadow:
    0 18px 48px rgb(0 0 0 / 20%),
    inset 0 1px 0 rgb(255 255 255 / 17%);
  backdrop-filter: blur(12px) saturate(1.15);
  -webkit-backdrop-filter: blur(12px) saturate(1.15);
}

.banner .tile__hero-icon {
  inline-size: clamp(62px, 11vw, 88px);
  border-radius: 28px;
}

@keyframes auto-hero-drift {
  0% { transform: translate3d(-3%, -2%, 0) rotate(-5deg) scale(1.03); }
  48% { transform: translate3d(4%, 2%, 0) rotate(3deg) scale(1.12); }
  100% { transform: translate3d(-1%, 5%, 0) rotate(-1deg) scale(1.07); }
}

/* ---------------- حالة تحميل الصورة الحقيقية ---------------- */

.media-loader {
  position: absolute;
  z-index: 5;
  inset: 50% auto auto 50%;
  display: grid;
  place-items: center;
  inline-size: 64px;
  aspect-ratio: 1;
  translate: -50% -50%;
  color: var(--fg-soft);
  border-radius: 22px;
  background: color-mix(in srgb, var(--bg-void) 62%, transparent);
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--fg) 9%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  transition: opacity 260ms var(--ease), transform 260ms var(--ease);
}

.media-loader__orbit {
  position: absolute;
  inset: 6px;
  border: 1.5px solid color-mix(in srgb, var(--fg) 13%, transparent);
  border-block-start-color: color-mix(in srgb, var(--fg) 72%, transparent);
  border-radius: 50%;
  animation: media-loader-spin 1.1s linear infinite;
}

.media-loader__brand {
  opacity: 0.7;
  animation: media-loader-breathe 1.8s ease-in-out infinite;
}

[data-media-state="loaded"] .media-loader {
  opacity: 0;
  transform: scale(0.88);
  pointer-events: none;
}

[data-media-state="error"] .media-loader__orbit {
  border-color: color-mix(in srgb, var(--fg) 22%, transparent);
  animation-duration: 3.4s;
}

@keyframes media-loader-spin { to { rotate: 1turn; } }
@keyframes media-loader-breathe { 50% { opacity: 1; transform: scale(1.06); } }

/* ----------------------- ما تحت الصورة ----------------------- */

.tile__foot {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding-inline: var(--sp-1);
  min-inline-size: 0;
}

.tile__name {
  font-size: var(--t-sm);
  font-weight: var(--w-medium);
  color: var(--fg);
  line-height: var(--lh-snug);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  /* بعض الحروف العربية تتجاوز صندوقها البصري بجزء بكسل؛ لا نجعل
     قصّ المحور الأفقي يأكل أولها عند محاذاتها بالحافة. */
  padding-inline-start: 6px;
  padding-inline-end: 2px;
}

.tile__line { display: flex; align-items: center; gap: var(--sp-2); min-inline-size: 0; }

.tile__count {
  flex: none;
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  color: var(--fg-mute);
  font-variant-numeric: tabular-nums;
}

/* الوسم يقول نوع العالم بكلمة. محايدٌ لا مصبوغ: لو أخذ لون العالم
   لتزاحم مع جوّ البطاقة على العين، والوسم معلومةٌ لا زينة. */
.tile__tag {
  min-inline-size: 0;
  padding: 1px var(--sp-2);
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  font-size: var(--t-2xs);
  color: var(--fg-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ----------------------- البنر ----------------------- */

/* صورة العالم فوق صفحته كما في Notion: عريضةٌ تمتدّ إلى حافّتَي
   المنفذ، والاسم والوصف تحتها لا فوقها — النصّ على الصورة يحتاج
   تعتيمًا يُفسد الصورة، وتحتها يُقرأ بلا حيلة. */
.banner {
  position: relative;
  inline-size: 100%;
  aspect-ratio: 16 / 5;
  max-block-size: 260px;
  min-block-size: 120px;
  overflow: hidden;
  border-radius: clamp(16px, 2vw, 24px);
  border: 1px solid var(--line);
  background: var(--bg-surface-2);
}

/* بنر الرئيسيّة يحفظ الصورة كاملة (`contain`)، فيبقى حولها فراغ.
   والفراغ أسودُ محايد لا بلون الصورة السائد: اللون السائد كان يخرج
   شريطًا أحمر أو أخضر بجانبها فيبدو جزءًا ناقصًا منها.

   وكان يُكتب من JS سطرَ نمطٍ على العنصر، فبقي الصنف `banner--home`
   مُصدَرًا بلا قاعدةٍ واحدة تسمّيه — وهو ما التقطه مسحُ الأصناف
   اليتيمة. القاعدة هنا تحمل المعنى، والاستثناء بعدها. */
.banner--home { background: #000; }

/* ومن لا صورة له يأخذ Hero لونيًّا، فلا يُطمَس بالأسود. */
.banner--home[data-auto-hero="yes"] { background: none; }

.banner__img {
  position: absolute;
  inset: 0;
  inline-size: 100%;
  block-size: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity var(--dur-3) var(--ease);
}

.banner[data-loaded="yes"] .banner__img { opacity: 1; }

.realm-head {
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}

.realm-head__row { display: flex; align-items: center; gap: var(--sp-3); min-inline-size: 0; }
.realm-head__add { margin-inline-start: auto; flex: none; }

.realm-head__icon {
  flex: none;
  display: grid;
  place-items: center;
  inline-size: 40px;
  block-size: 40px;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--fg-soft);
}

.realm-head__name {
  margin: 0;
  min-inline-size: 0;
  font-family: var(--font-display);
  font-size: var(--t-2xl);
  font-weight: var(--w-medium);
  letter-spacing: var(--track-tight);
  line-height: var(--lh-tight);
}

.realm-head__desc {
  margin: 0;
  max-inline-size: var(--measure-text);
  color: var(--fg-soft);
  font-size: var(--t-sm);
  line-height: var(--lh-snug);
}

.realm-head__meta {
  font-family: var(--font-mono);
  font-size: var(--t-2xs);
  color: var(--fg-faint);
  font-variant-numeric: tabular-nums;
}

/* ================= بطاقة العالم: الجوّ واللونان =================

   العالم وعاءٌ لا محتوًى، فيُقرأ مختلفًا عن المساحة قبل أن يُقرأ
   عدّاده: نسبةٌ ثابتة، وجوٌّ من لونه، وحدٌّ مصبوغ.

   **واللونان لا يُطليان طلاءً.** يُمزجان بأرض الثيم بنسبٍ صغيرة
   (٧٪–١٨٪)، فمن اختار برتقاليًّا لا تخرج له بطاقةٌ برتقاليّة فاقعة
   على واجهةٍ أحاديّة اللون، بل أرضٌ محايدة فيها همسةٌ من لونه. */

.tile[data-kind="realm"][data-tinted="yes"] .tile__frame {
  background:
    radial-gradient(
      circle at 15% 0%,
      color-mix(in srgb, var(--accent-1) 18%, transparent),
      transparent 48%
    ),
    linear-gradient(
      145deg,
      color-mix(in srgb, var(--accent-1) 10%, var(--bg-surface)),
      color-mix(in srgb, var(--accent-2) 7%, var(--bg-surface))
    );
  border: 1px solid color-mix(in srgb, var(--accent-1) 34%, var(--line));
}

/* صبغةٌ فوق الصورة لا فيها: الصورة تبقى كما صوّرها صاحبها. */
.tile__tint {
  position: absolute;
  z-index: 3;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    135deg,
    color-mix(in srgb, var(--accent-1, transparent) 12%, transparent),
    color-mix(in srgb, var(--accent-2, transparent) 8%, transparent)
  );
}

/* وستارةٌ مستقلّة للقراءة: مهمّتها أن يُقرأ ما يُكتب فوق الصورة،
   فلا تُخلط بالصبغة — إحداهما ذوقٌ والأخرى وظيفة. */
.tile__scrim {
  position: absolute;
  z-index: 4;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    to bottom,
    transparent 35%,
    rgb(0 0 0 / 10%) 62%,
    rgb(0 0 0 / 58%) 100%
  );
}

.tile[data-kind="space"] .tile__scrim { opacity: 0.55; }

/* ----------------------- الحركة ----------------------- */

/* **التكبير يتركّب ولا يُمسَح.** لو كُتب `scale(1.06)` عند التحويم
   لألغى تكبير المستخدم وقفزت الصورة إلى قصٍّ لم يخترْه. فيُضرب
   عاملُ التحويم في تكبيره بدل أن يحلّ محلّه. */
.tile__img {
  --hover-scale: 1;

  transform: scale(calc(var(--cover-zoom, 1) * var(--hover-scale)));
  transition:
    opacity var(--dur-3) var(--ease),
    transform 560ms cubic-bezier(0.2, 0.72, 0.2, 1),
    filter 560ms cubic-bezier(0.2, 0.72, 0.2, 1);
}

.tile:hover .tile__img {
  --hover-scale: 1.06;

  filter: saturate(1.12) contrast(1.05);
}

.tile__frame { transition: box-shadow 560ms cubic-bezier(0.2, 0.72, 0.2, 1); }

/* **الرفعة على `transform` لا على `translate`.** `translate` يحمل
   موضعَ البطاقة في الجدار، وأيّ انتقالٍ عليه يجعل التوزيع الأوّل
   ينزلق من الصفر — وهو العطب نفسه الذي أُصلح أعلاه. والخاصّيّتان
   منفصلتان وتتركّبان، فتبقى الرفعة وحدها متحرّكة والموضع ثابتًا.

   وتُكتب `translateY(0)` صراحةً: القيمة الأولى `none` لا تُستكمَل
   إليها حركة. */
.tile {
  transform: translateY(0);
  transition: transform 560ms cubic-bezier(0.2, 0.72, 0.2, 1);
}

.tile:hover { transform: translateY(-8px); }

@media (prefers-reduced-motion: reduce) {
  .tile,
  .tile__img { transition: none; }

  .tile__frame[data-auto-hero="yes"]::before,
  .banner[data-auto-hero="yes"]::before,
  .media-loader__orbit,
  .media-loader__brand { animation: none; }

  .tile:hover { transform: none; }
  .tile:hover .tile__img { --hover-scale: 1; filter: none; }
}

/* البنر يقرأ نقطة التركيز والتكبير كالبطاقة: نافذته أعرض (١٦:٥)،
   فالموضع الذي ضبطه صاحب الصورة هو ما ينقذ رأس الوجه من القصّ. */
.banner__img { transform: scale(var(--cover-zoom, 1)); }

/* على الجوال البنر لا يصير شريطًا رفيعًا، والبطاقات تحته تبقى
   عمودين. النسبة 2.6:1 ما زالت بنرًا واضحًا لكنها تقارب ارتفاع بطاقة
   نصفية بدل أن تبدو البطاقة أضخم منها بثلاث مرّات. */
@media (max-width: 760px) {
  .tile__menu {
    inset-block-start: 5px;
    inset-inline-end: 5px;
    inline-size: 34px;
    block-size: 34px;
    opacity: .94;
  }
  .tile__pin { inset-block-start: 10px; inset-inline-start: 10px; }

  .banner {
    aspect-ratio: 2.6 / 1;
    min-block-size: 150px;
    max-block-size: 220px;
  }

  .wall { min-block-size: 28px; }

  .tile,
  .tile__frame { border-radius: 16px; }

  .tile { gap: var(--sp-2); }
  .tile__foot { padding-inline: 2px; }
  .tile__name { font-size: var(--t-xs); }
}
