/* Style.css — سُرى Design System
   ============================================================================
   THE TOKEN LAYER. Every value below is a decision; every value elsewhere in
   this file should be a *reference* to one of these. When you need a colour, a
   size, a radius, a duration or an easing curve, take it from here. If nothing
   here fits, the right move is almost always to widen a ramp — not to write a
   new literal. Scattered literals are exactly what makes a site read as
   machine-made rather than designed.

   Ramps are ordered light → dark for ink/gold, and dark → light for surfaces
   (this is a dark-first product). The `data-theme="light"` block near the end
   of this file re-points the *same* semantic tokens, which is why light mode
   needs no `!important` overrides.
   ========================================================================= */

:root {
    /* --- Gold ramp — the brand. Every gold in the product resolves here. --- */
    --gold-050: #ffe9c9;   /* faintest wash, highlights on gold surfaces      */
    --gold-100: #f1e2b8;
    --gold-200: #ffd27a;   /* glow / lit state                                */
    --gold-300: #e8c86a;
    --gold-400: #e3c585;   /* brand secondary — was --clr-brand-secondary     */
    --gold-500: #c69a4a;   /* THE brand gold — was --clr-brand-primary        */
    --gold-600: #c9a227;   /* saturated, for medals / emphasis                */
    --gold-700: #b07e2e;   /* pressed / deep                                  */
    --gold-800: #7c4c11;
    --gold-900: #1a1208;   /* gold-tinted near-black, for gold-on-dark fills   */

    /* Gold as alpha — for glows, rings and washes over unknown backdrops.
       Keeping the channel triplet in one place means a brand re-tint is a
       one-line change instead of a 200-site search-and-replace. */
    --gold-rgb: 198, 154, 74;
    --gold-a08: rgba(198, 154, 74, 0.08);
    --gold-a15: rgba(198, 154, 74, 0.15);
    --gold-a25: rgba(198, 154, 74, 0.25);
    --gold-a40: rgba(198, 154, 74, 0.40);
    --gold-a60: rgba(198, 154, 74, 0.60);

    /* --- Surfaces — dark → light. 1 is the page, 4 is the most raised. --- */
    --surface-0: #070d18;  /* deepest — behind everything                     */
    --surface-1: #0f172a;  /* page background (fallback under the loom)       */
    --surface-2: #131a2e;
    --surface-3: #1e293b;
    --surface-4: #2d4a63;  /* highest raised chrome                           */

    /* --- Ink — text, light → dark. --- */
    --ink-0: #ffffff;      /* pure, reserve for peaks                         */
    --ink-1: #f8fafc;      /* primary body text                               */
    --ink-2: #cbd5e1;      /* muted / secondary                               */
    --ink-3: #9ca3af;      /* tertiary, captions                              */
    --ink-4: #6b7280;      /* disabled                                        */
    --ink-inverse: #0f172a;/* text on light surfaces                          */

    /* The nav bar is a matte-black plate in EVERY theme — it is a physical
       object in the design, not a surface that follows the page. Its ink must
       therefore never flip with the theme, so it gets its own two tokens. */
    --plate-ink: #ffffff;
    --plate-ink-dim: #9ca3af;

    /* --- Semantic — meaning, not hue. Change the ramp, not the site. --- */
    --ok: #3aa655;
    --ok-soft: #d6f5de;
    --ok-deep: #264a37;
    --warn: #e0a13a;
    --warn-soft: #ffe9b0;
    --err: #d64541;
    --err-soft: #ffd9d7;
    --err-deep: #7a2e16;
    --info: #4a90d9;
    --info-soft: #dbe9f6;

    /* Letter/guess state — shared by كَلِمة, صندوق الحروف and أمثال. These are
       a *game* vocabulary, deliberately separate from --ok / --warn / --err so
       that re-tuning feedback colours never disturbs the letter grids. */
    --state-correct: #2e7d32;   --state-correct-edge: #4caf50;
    --state-present: #ef6c00;   --state-present-edge: #ff9800;
    --state-absent:  #374151;   --state-absent-edge:  #4b5563;

    /* --- السدو — the weave's own palette (src/core/loom.mjs reads these).
       Sadu is a crimson / cream / rust craft on black, not a gold monochrome;
       keeping these as tokens is what lets the cloth be re-tinted or themed
       without touching the painting code. --- */
    --sadu-cream:    #f2e4c9;
    --sadu-gold:     #e0a33e;
    --sadu-crimson:  #c1274a;
    --sadu-rust:     #e2652a;
    /* The one thread no traditional Sadu panel carries. That single wrong note
       is what stops the palette reading as folklore pastiche. */
    --sadu-cool:     #2f7d8c;
    /* The lit thread — the bright knot a weaver ties, and the star it becomes
       at night. It is not one colour: the light in a room at dusk is not the
       light at 3am, and using one gold for both is what made every hour read
       gold. Each phase names its own (see PHASES in src/core/loom.mjs). */
    --sadu-lit:      #ffd27a;   /* dusk · lamp gold */
    --sadu-lit-cool: #dbeaff;   /* deep · starlight */
    --sadu-lit-rose: #ff9fb2;   /* dawn · first colour in the sky */
    --sadu-lit-pale: #f6ecd8;   /* day  · no light of its own */
    --sadu-ground-1: #0b0f1a;
    --sadu-ground-2: #1c0d12;
    --sadu-ground-3: #0e1626;

    /* --- Spacing — 4px base. --- */
    --sp-1: 0.25rem;  --sp-2: 0.5rem;   --sp-3: 0.75rem;  --sp-4: 1rem;
    --sp-5: 1.25rem;  --sp-6: 1.5rem;   --sp-7: 2rem;     --sp-8: 2.5rem;
    --sp-9: 3rem;     --sp-10: 4rem;    --sp-11: 5rem;    --sp-12: 6rem;

    /* --- Radius. --- */
    --r-xs: 4px;
    --r-sm: 8px;
    --r-md: 12px;
    --r-lg: 16px;
    --r-xl: 24px;
    --r-full: 999px;

    /* --- Type scale. Arabic sits optically smaller than Latin at the same
       px, so the ramp is tighter at the low end than a Latin scale would be. */
    --fs-4xs: 0.55rem;
    --fs-3xs: 0.65rem;
    --fs-2xs: 0.72rem;
    --fs-xs:  0.80rem;
    --fs-sm:  0.85rem;
    --fs-md:  0.92rem;
    --fs-base: 1rem;
    --fs-lg:  1.15rem;
    --fs-xl:  1.25rem;
    --fs-2xl: 1.45rem;
    --fs-3xl: 1.65rem;
    --fs-4xl: 1.85rem;
    --fs-5xl: 2.3rem;
    --fs-6xl: 2.7rem;
    --fs-hero: clamp(2.2rem, 5vw, 3.8rem);
    --fs-display: clamp(3rem, 7vw, 5.5rem);

    /* --- Easing. Named, so motion across the product speaks one language.
       --ease-expo is the house curve: fast out, long soft settle. --- */
    --ease-expo:  cubic-bezier(0.16, 1, 0.30, 1);
    --ease-quart: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-back:  cubic-bezier(0.34, 1.56, 0.64, 1);
    --ease-soft:  cubic-bezier(0.25, 1, 0.30, 1);

    /* --- Duration. --- */
    --dur-1: 120ms;  --dur-2: 200ms;  --dur-3: 300ms;
    --dur-4: 400ms;  --dur-5: 600ms;  --dur-6: 900ms;

    /* --- Elevation. --- */
    --el-1: 0 2px 10px rgba(0, 0, 0, 0.20);
    --el-2: 0 4px 30px rgba(0, 0, 0, 0.25);
    --el-3: 0 10px 40px rgba(0, 0, 0, 0.35);
    --el-4: 0 22px 50px rgba(0, 0, 0, 0.45);

    /* --- Stacking. The only place a z-index should come from. --- */
    --z-loom: -2;
    --z-veil: -1;
    --z-content: 5;
    --z-nav: 50;
    --z-modal: 100;
    --z-fx: 9999;

    /* --- Legacy aliases -----------------------------------------------------
       Kept so nothing breaks mid-migration and so JS that reads these names
       keeps working. New code should use the ramp tokens above. --------- */
    --clr-bg-fallback: var(--surface-1);
    --clr-primary-glow: var(--gold-a15);
    --clr-text-main: var(--ink-1);
    --clr-text-muted: var(--ink-2);
    --clr-text-dark: var(--ink-inverse);
    --clr-brand-primary: var(--gold-500);
    --clr-brand-secondary: var(--gold-400);
    --clr-accent: var(--gold-700);

    /* Glassmorphism System */
    --glass-bg: rgba(255, 255, 255, 0.04);
    --glass-border: rgba(255, 255, 255, 0.08);
    --glass-border-hover: rgba(255, 255, 255, 0.18);
    --glass-blur: 24px;
    --glass-shadow:
        var(--el-2),
        inset 0 1px 1px rgba(255, 255, 255, 0.08);
    --glass-shadow-hover:
        var(--el-3),
        inset 0 1px 2px rgba(255, 255, 255, 0.15);

    /* Layout & Spacing */
    --transition-smooth: all var(--dur-4) var(--ease-expo);
    --transition-quick: all var(--dur-2) ease-out;
}

/* Glass blur is the single most expensive paint in the product (31 sites).
   On phones — where the GPU is weakest and the blur is least visible behind a
   small viewport — it is halved. Nothing else about the glass changes. */
@media (max-width: 768px) {
    :root { --glass-blur: 12px; }
}

/* --- Base & Reset Rules --- */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

html {
    scroll-snap-type: none;
    scroll-behavior: smooth;
    /* --font-scale is set by __sura.prefs (1 / 1.15 / 1.3 / 1.5) for accessibility zoom */
    font-size: calc(16px * var(--font-scale, 1));
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    height: 100%;
}

body {
    font-family: 'Reem Kufi', sans-serif;
    background-color: var(--clr-bg-fallback);
    color: var(--clr-text-main);
    overflow-x: hidden;
    overflow-y: hidden;
    height: 100vh;
    height: 100dvh;
    letter-spacing: normal !important;
    /* Every digit the same width. Without this, timers, scores and streak
       counters visibly twitch as they tick because `1` is narrower than `8`. */
    font-variant-numeric: tabular-nums;
}

/* ---- المؤشّر --------------------------------------------------------------
   الجَمل المؤشّر حُذف بقرار المالك (٨ أغسطس ٢٠٢٦): مؤشّر النظام يعود على كل
   الصفحة. أصولُه ما تزال في public/brand/ وscripts/assets/camel_cursor.js يعيد
   توليدها إن عاد القرار — فالحذف قاعدتان CSS لا أصول.                        */

/* Scrollbars are never painted anywhere in Sura — wheel, touch, keyboard and
   programmatic scrolling all still work, only the chrome is gone. Global so no
   container (modal, drawer, leaderboard) can grow a track of its own. */
* {
    scrollbar-width: none;       /* Firefox */
    -ms-overflow-style: none;    /* old Edge / IE */
}
*::-webkit-scrollbar {           /* Chrome / Safari / new Edge */
    width: 0;
    height: 0;
    display: none;
}

h1, h2, h3, h4, a, button, span, p, input, .logo-text, .btn-login, .btn-primary, .btn-secondary, .scroll-indicator, .hero-title, .hero-description {
    font-family: 'Reem Kufi', sans-serif;
    letter-spacing: normal !important;
}

/* --- Scrolling Single Page Snap Sections --- */
.scroll-section {
    scroll-snap-align: start;
    scroll-snap-stop: always;
    min-height: 100vh;
    min-height: 100dvh;
    width: 100%;
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    box-sizing: border-box;
    padding-top: 6rem;
    padding-bottom: 3rem;
}

/* --- Page-switch mode -------------------------------------------------------
   Each section is now a full-screen page shown ONE at a time; the navbar links
   and hero buttons switch between them instead of scrolling. app.js's
   manuallyMorphBackdrop() already toggles .active on the target <section> — we
   just use that class to show/hide. Higher specificity (.main-content > …) so
   it wins over .hero-section / .second-page / .third-page, which set their own
   position/display. Each page scrolls INTERNALLY when its content is tall. --- */
.main-content > .scroll-section {
    position: fixed;
    top: 0; left: 0; right: 0; bottom: 0;
    width: 100%;
    min-height: 0;
    display: none;                 /* only the .active page is visible */
    overflow-y: auto;
    overflow-x: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-align: none;
    z-index: 5;
}
.main-content > .scroll-section.active {
    display: flex;
    /* No opacity animation here. On iOS Safari an opacity keyframe on a fixed
       section that is re-shown from display:none can freeze at its 0% frame,
       hiding the ENTIRE page so only the background video shows. Switch instantly. */
}

/* A "swipe down" prompt makes no sense once pages are switched, not scrolled */
.scroll-indicator-container { display: none !important; }

/* Staggered Scroll Entrance Animations (GPU-Composited 60fps).
   The DEFAULT state is VISIBLE (opacity:1). This is the critical safety net:
   iOS Safari does not reliably (re)start an animation — or complete a transition —
   on a child whose fixed section was display:none and is shown again, which left
   the hero stuck invisible with only the background video behind it (the
   "main → games → main" and even fresh-load blank-hero bug). By defaulting to
   visible, content can NEVER be stuck hidden; the entrance below is pure decoration. */
.scroll-section .animate-fade-up {
    opacity: 1;
    transform: none;
}

/* Entrance motion, keyed on .active — TRANSFORM ONLY, opacity is never animated.
   The bug: main→games→main. On re-activation iOS Safari fails to restart this
   animation and freezes it at the `from` frame. If `from` set opacity:0 (as it
   used to), the hero stayed invisible — only the video showed. By animating just
   the transform, a frozen frame merely offsets the content a few px; opacity is
   always 1, so the text/buttons can NEVER disappear. */
.scroll-section.active .animate-fade-up {
    animation: fadeUpIn 0.7s var(--ease-quart) var(--stagger, 0s) both;
}
@keyframes fadeUpIn {
    from { transform: translateY(28px) scale(0.985); }
    to   { transform: translateY(0)    scale(1); }
}
/* reduced motion: no entrance travel — content is already visible by default */
@media (prefers-reduced-motion: reduce) {
    .scroll-section.active .animate-fade-up { animation: none; }
}

/* Staggered children inside active sections for cascading reveal */
.scroll-section.active .animate-fade-up:nth-child(1) { --stagger: 0s; }
.scroll-section.active .animate-fade-up:nth-child(2) { --stagger: 0.08s; }
.scroll-section.active .animate-fade-up:nth-child(3) { --stagger: 0.16s; }
.scroll-section.active .animate-fade-up:nth-child(4) { --stagger: 0.24s; }

/* --- Pre-loaded Video Pool Background --- */
.video-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    z-index: -2;
    overflow: hidden;
    background-color: var(--clr-bg-fallback);
}

/* Each video layer is a full-screen element; only the .active one is visible */
.video-layer {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0;
    transition: opacity 0.5s ease-out;
    will-change: opacity;
    pointer-events: none;
}

.video-layer.active {
    opacity: 1;
    transition: opacity 0.5s ease-out;
}

/* كان هنا `.loop-fade`: تُطفئ المقطع ٠٫٧ ثانية قبل نهايته وتعيده بعد بدايته،
   بحجّة إخفاء قطع الإعادة. وهي نفسها ما رآه المالك: «لمن ينعاد المقطع يختفي».
   و<video loop> يعيد نفسه بلا فجوة أصلًا، فلم يكن هناك قطعٌ يُخفى. حُذفت من
   هنا ومن main.js معها حلقة rAF كانت تدور طوال بقاء الزائر على الواجهة. */

/* النَّول — the woven backdrop. It is a sibling of the video layers inside
   .video-container, painted above them and below the vignette, so the two
   backdrop modes are interchangeable without touching any other rule.

   The cloth is COMPOSED, not tiled. Two panels of woven Sadu cross the screen
   on different rakes, at different scales and speeds — the slower, sparser one
   behind. That parallax is what turns a flat pattern into a space. Each panel
   is masked to nothing at both ends so it dissolves into its own threads
   instead of being visibly cut off by the viewport.

   All motion here is a CSS transform on a finished bitmap: the compositor
   slides it, and JavaScript runs zero frames for it. */
.loom-stage {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
    pointer-events: none;
}

/* The wrapper owns POSITION and RAKE (and the screen-fixed dissolve mask);
   the canvas inside owns the DRIFT. They have to be separate elements, or the
   mask would travel with the cloth and the dissolve would slide off-screen. */
.loom-strip {
    position: absolute;
    left: -25%;
    width: 150%;
    top: var(--strip-top, 30%);
    height: var(--strip-h, 240px);
    transform: rotate(var(--strip-angle, -13deg))
               translate3d(calc(var(--strip-in, 0) * 18%), 0, 0);
    transform-origin: center center;
    transition: transform var(--dur-6) var(--ease-expo);
    -webkit-mask-image: linear-gradient(90deg,
        transparent 0%, #000 var(--mask-a, 28%),
        #000 var(--mask-b, 68%), transparent 100%);
            mask-image: linear-gradient(90deg,
        transparent 0%, #000 var(--mask-a, 28%),
        #000 var(--mask-b, 68%), transparent 100%);
}
.loom-near { z-index: 2; filter: drop-shadow(0 24px 40px rgba(0, 0, 0, 0.55)); }
.loom-far  { z-index: 1; opacity: 0.55; }

/* الانجراف. كان محذوفًا (§٢: حركة دائمة بلا سبب = شاشة توقّف)، وأعاده المالك
   في ١٢ أغسطس ٢٠٢٦ للمسارين غير الواجهة. `loomSheen` لم يعُد ولا يعود.

   والمسافة `--drift-x` بلاطةٌ واحدة يحسبها loom.mjs، لا رقمٌ هنا: القفزة عند
   نهاية الدورة تساوي صفرًا فقط إن كانت المسافة دورةَ النسيج بالضبط.

   حركةُ `transform` وحدها على عنصرٍ لا يملك أحدٌ آخر تحويله: الشريط الأب يملك
   الميل والدخول، والشرائح الأبناء تملك التموّج. ONE OWNER PER PROPERTY. */
.loom-cloth {
    position: absolute;
    /* أطول من النطاق بهامش أعلى وأسفل يبتلع تموّج الشال، فيُرفع بنفس القدر
       ليبقى النسيج في موضعه تمامًا. */
    top: calc(-1 * var(--cloth-pad, 0px));
    left: 0;
}
/* ‏«زِقزاق» + الانجراف — انتقلا إلى JavaScript (١٥ أغسطس ٢٠٢٦)
   ------------------------------------------------------------------------
   كان هنا `@keyframes loom-pull` يحرّك `transform` مكتوبًا بـ
   ‏`calc(-1 * var(--drift-x))`، وفوقه تعليقٌ يقول إنّ المُركِّب يتولّاه.
   وكان ذلك **غير صحيح**: أيُّ حركةٍ تمرّ قيمتُها بمتغيّر CSS تُجبر المتصفّح
   على إعادة حساب الأنماط كلَّ إطار، فلا تصل إلى خيط المُركِّب أبدًا.

   والقياس (٤× خنقٍ للمعالج، ست ثوانٍ سكونٍ على مسار النشرة): ٣٦٧م.ث إعادةَ
   حسابِ أنماطٍ والانجرافُ موقوف، و٨٤٤م.ث وهو يعمل — نحو ٤٨٠م.ث ثمنًا لخلفيّةٍ
   ساكنة.

   فصار المسارُ يُبنى في `setDrift()` داخل src/core/loom.mjs بأرقامٍ صريحة
   عبر WAAPI. لا متغيّرَ في القيمة ⇒ لا حلَّ في الأنماط ⇒ يُركَّب فعلًا.
   وبوّابةُ المسار والسكون انتقلت معه إلى هناك: محرّكُ الحركة واحد.

   **لا تُعِد الحركةَ إلى هنا.** ما بقي في CSS هو `will-change` وحدَه. */
html[data-backdrop="loom"] .loom-cloth { will-change: transform; }
/* شرائح القماش: الشريحة التي تلمسها يدك وحدها تُعاد رسمها. لا will-change:
   الحركة هنا في محتوى اللوح لا في تحويله، ورفعها إلى طبقة مستقلّة يكلّف
   ذاكرة بلا مقابل. */
.loom-seg {
    position: absolute;
    top: 0;
    left: 0;
    display: block;
}

/* ---- المصباح: محذوف ------------------------------------------------------
   كان هنا `.loom-lamp` — هالة ذهبية تتبع المؤشّر بـ`mix-blend-mode: screen`.
   حذفها المالك، ولها سببان لا تُعاد لأجلهما:

   ذوقيًّا: هالةٌ تتبع الفأرة صارت توقيعَ كل موقع «مبهر» على الإنترنت. كانت
   تقول «أثر بصري» لا «سُرى».

   وتقنيًّا: طبقة بحجم الشاشة عليها blend mode تُجبر المتصفّح على إعادة تركيب
   المشهد كلّه مع كل حدث pointermove — أغلى شيء في الصفحة مقابل أقلّ أثر فيها.

   وبقي التفاعل الحقيقي تحتها: **الفكّ** (loom.mjs) — يدك تفكّ خيوط النسيج. */

/* Phones get one panel. Two crossing panels on a 375px screen is not depth,
   it is clutter — and the near one carries the fringe, which is the detail
   worth keeping. */
@media (max-width: 700px) {
    .loom-far { display: none; }
    .loom-near { filter: none; }
}

@media (prefers-reduced-motion: reduce) {
    .loom-strip { transition: none; }
    /* «حركة أقلّ» تُلغي الانجراف كليًّا — لا تُبطّئه. */
    /* الحركةُ نفسُها صار يمنعها `setDrift()` (لا تُنشَأ أصلًا تحت السكون).
       الباقي هنا رفعُ الطبقة: لا حركةَ ⇒ لا داعيَ لذاكرتها. */
    html[data-backdrop="loom"] .loom-cloth { will-change: auto; }
}
/* ---- أيّ خلفية لأيّ صفحة ---------------------------------------------------
   الفيديو للواجهة وحدها، والسدو لما بعدها. و`data-backdrop` تكتبها main.js مع
   كل تغيّر مسار.

   والنَّول **لا يُخفى أبدًا**، ولذلك سببٌ يخصّ السرعة لا الشكل: النسيج يُرسم في
   الإطار الأول بلا تحميل، فيقع تحت المقطع ويظهر فورًا، ثم يذوب المقطع فوقه متى
   وصل. فلا أحد ينتظر أمام سواد — وهذا وحده ما سمح بإعادة الفيديو أصلًا.

   والمقطع على غير الواجهة **متوقّف** (`pause()` في main.js) لا مخفيًّا فحسب:
   المتوقّف يكفّ عن فكّ الترميز، وهذا هو الفرق كله في سلاسة صفحة الألعاب. */
.video-layer  { z-index: 1; }
.video-overlay { z-index: 2; }

/* النَّول يتنحّى حين يقوم الفيلم.
   القماش وظيفته أن يُرسم في الإطار الأول بلا انتظار — فمتى صار الفيلم فعلًا على
   الشاشة (`data-film="up"` تكتبها main.js عند حدث `playing`) لم يعد له ما يفعله،
   ولا معنى لإبقاء لوحتَي canvas تُركَّبان تحت فيديو مُعتِم.

   وعلى الاتصال الضعيف (`still`) يبقى القماش متنحّيًا أيضًا: المعروض حينها هو
   إطارُ الفيلم الثابت (poster) يتحرّك بـGSAP، وهو مشهد كامل بذاته لا يحتاج
   نسيجًا تحته. والقماش يعود فورًا عند مغادرة الواجهة (تُنزع الخاصيّة). */
/* `[data-scene]` معها: القماش لا يتنحّى قبل أن يصير للفيلم ما يُعرَض. لو تنحّى
   على `data-film` وحدها لظهر سوادٌ بين اللحظتين — الصور وصلت، والمشهد لم
   يُرسَم بعد. (شرح البوّابة الثانية عند `.film-layer__img` أدناه.) */
html[data-film][data-scene] .loom-stage {
    opacity: 0;
    transition: opacity 700ms ease-out;
}

/* الـposter يملأ الإطار كما يملؤه الفيديو تمامًا. بدون هذا يعرضه المتصفّح
   بنسبته الأصلية داخل عنصر بمقاس الشاشة، فتظهر أشرطة سوداء على الجوانب. */
.video-layer { object-fit: cover; }

/* ---- المشهد المفصول الطبقات ------------------------------------------------
   بديل المقطع على الواجهة. المنطق كلّه في src/core/hero.mjs؛ هنا الهندسة
   وحدها — ولا حركة في هذه الكتلة إطلاقًا: كل ما يتحرّك تكتبه GSAP سطريًّا.

   والمفتاح واحد على <html>: `data-hero`. أحدهما يعمل والآخر يُخفى تمامًا،
   فالرجوع إلى المقطع تغييرُ كلمةٍ في الترميز لا حذفُ شيء.                    */
html[data-hero="story"] .video-layer { display: none; }
html[data-hero="film"]  .film-stage  { display: none; }

.film-stage {
    position: absolute;
    inset: 0;
    z-index: 1;              /* فوق النَّول، تحت التعتيم — نفس طبقة المقطع */
    overflow: hidden;        /* الفائض يُقصّ هنا، فلا يزحف على الصفحة */
    pointer-events: none;

    /* سماء الليل لونًا لا صورة. وهذا ليس تجميلًا بل **ضمان التغطية**: كل
       الطبقات تطفو فوق هذا التدرّج، فمهما ارتفعت أو هبطت في القصّة لا يمكن
       لحركةٍ أن تكشف فراغًا. الجولة الماضية ضمنت هذا بحسابِ فائضٍ لكل طبقة —
       وهو حسابٌ يصحّ ما دامت الطبقات لا تغادر الإطار، وقصّةٌ كاملة تُغادِره
       بالتعريف. اللونان من التوكنز (--surface-0 / --sadu-ground-3). */
    background: linear-gradient(180deg, #070d18 0%, #0b0f1a 55%, #0e1626 100%);
}

/* المشهد للواجهة وحدها — وهذا سطرٌ لا يُحذف.
   `.film-stage` ليست داخل قسمٍ من الأقسام، بل في حاوية الخلفية الثابتة، فهي
   تبقى على الشاشة في كل المسارات ما لم تُربط بالمسار صراحةً. وبدون هذه القاعدة
   تظلّ الصحراء مرسومةً فوق النَّول في صفحتَي الألعاب والنشرة — والصفحة تعمل
   تمامًا، فلا شيء يشتكي؛ الخلفية وحدها هي الخطأ. `.video-layer.active` كانت
   تفعل هذا ضمنًا، فذهب الضمان معها حين حلّ المشهد محلّها.                    */
html[data-backdrop="loom"] .film-stage {
    opacity: 0;
    transition: opacity 0.5s ease-out;
}
html[data-backdrop="video"] .film-stage {
    opacity: 1;
    transition: opacity 0.5s ease-out;
}

/* هندسة كل طبقة (left/top/width/height) **سطريّة في الترميز**، ومولَّدة من
   public/story/story.json بيد scripts/assets/story_assets.js. ثمانية مواضع × أربعة
   أرقام = ٣٢ رقمًا؛ نسخُ واحدٍ منها خطأً يزيح طبقةً بلا أن يكسر شيئًا يُلاحَظ،
   ولذلك لا يُكتب هنا ولا هناك رقمُ موضعٍ بيد. */
/* الإطار الحامل: نسبةٌ مقفلة تُغطّي الشاشة بالقصّ لا بالمطّ.
   بدونه تبقى نِسَب الطبقات رهينةَ نسبة الجهاز — الطقم العمودي مركَّبٌ على
   0.5625 وشاشة الجوّال 0.462، فيبقى مطٌّ 1.22× مهما دُقِّق التركيب، ولا يمكن
   ملاحقة كل جهاز بطقمٍ خاصّ. ومع الإطار تصير الطبقات الثماني في نظام
   إحداثيّاتٍ واحدٍ صلب، ونسبةُ كل صندوقٍ تساوي نسبةَ صورته على **أي** شاشة.
   `max()` تختار البُعد المُلزِم: أحدهما فقط يفوز، وكلاهما يعطي نفس المقياس. */
.film-frame {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: max(100vw, calc(100vh * var(--r)));
    height: max(100vh, calc(100vw * var(--ri)));
}
@media (orientation: portrait) {
    .film-frame {
        width: max(100vw, calc(100vh * var(--rp)));
        height: max(100vh, calc(100vw * var(--rpi)));
    }
}
.film-layer {
    position: absolute;
    /* الهندسة تأتي من متغيّراتٍ يكتبها المولّد على العنصر، لا من `left:` سطريّة.
       الفرق ليس أسلوبًا: خاصيّةٌ سطريّة تهزم كل قاعدةٍ في الورقة، فلا تستطيع
       media query أن تبدّلها. ومع المتغيّرات تبقى القيم في الترميز ويبقى
       **الاختيار** في CSS. */
    left: var(--ll);
    top: var(--lt);
    width: var(--lw);
    height: var(--lh);
    will-change: transform;
}
.film-layer picture { display: block; width: 100%; height: 100%; }

/* الإطار العمودي — تركيبٌ ثانٍ لا تحجيمٌ للأوّل.
   نسبة الإطار الأفقي 1.78 ونسبة شاشة الجوّال 0.46، فوضعُ الهندسة الأفقية في
   مسرحٍ عمودي كان يمطّ كل طبقة رأسيًّا 1.78÷0.46 = ٣٫٨٥×: القمر بيضاويًّا
   والمسافر عمودًا عرضه ٢١px. ولا يُصلحه `object-fit: cover` لأن قصّ الوسط على
   390×844 يُبقي ٢٦٪ من العرض فقط والمسافر عند 62.8٪ — فيُقَصّ خارج الكادر. */
@media (orientation: portrait) {
    .film-layer {
        left: var(--pl);
        top: var(--pt);
        width: var(--pw);
        height: var(--ph);
    }
}
.film-layer__img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: fill;        /* الصورة مقصوصةٌ على صندوقها أصلًا — لا قصَّ ثانٍ */
    will-change: transform;
}

/* «صورةٌ لم تصل لا تُرسَم» —————————————————————————————————————————————
   الطبقات تحمل مصادرها في `data-*` لا في `src` (السبب في index.html: ألّا
   يدفع الزائرُ الخفيف ثمنها). فتبقى لحظةً <img> بلا صورة **وبصندوقٍ كامل
   الحجم** من هذه الورقة — وكروم يرسم مثلها إطارًا رفيعًا فاتحًا، فيرى الزائر
   «خطوطًا بيضاء» مبعثرة على الشاشة. ثم تصل الثماني واحدةً واحدةً فينكشف أن
   المشهد صورٌ مركّبةٌ لا لوحةٌ واحدة. العَرَضان سببهما واحد: المسرح كان
   يُرسَم قبل أن يكتمل.

   والبوّابة كانت موجودةً أصلًا لكنّها لم تكن مربوطةً بالرسم: `data-film` لا
   تُكتب إلا بعد أن تصل الطبقات كلّها (الدالّة `up` في index.html — وتحسب
   الخطأ وصولًا، فلا تعلَق البوّابة أبدًا). فهنا تُربَط.

   `visibility` على الصور لا `opacity`، والتلاشي على `.film-frame` وحده: لا
   مالكَ آخر لشفافيّته، بينما شفافيّة `.film-stage` محجوزةٌ لتبديل الخلفيّات
   (`data-backdrop`) وشفافيّة الطبقات ممنوعةٌ أصلًا. ONE OWNER PER PROPERTY.

   وبوّابةٌ **ثانية** معها، `data-scene`، وهي علاجُ عَرَضٍ مختلف: «تظهر عناصر
   من الصور فجأةً ثم تختفي ثم يشتغل الهيرو». سببه أن حالة الطبقات قبل أن
   يمسّها JS هي **المشهد النهائي** (`layerY` عند الراحة = صفر، وهو ثابتٌ
   مقصود). فكان الترتيب: تصل الصور ← يُرسَم التصميم النهائي كاملًا ← تصل
   الحزمة فتقفز الطبقات إلى مواضع البداية خارج الإطار ← تبدأ القصّة. أي أن
   الزائر كان يرى نهاية الحكاية قبل أوّلها، ويرى معها أنّها قطعٌ تتحرّك.

   فالكشف صار يحتاج الاثنتين: `data-film` = «الصور وصلت» (يكتبها السكربت
   السطري)، و`data-scene` = «المشهد رُسم عند الإطار صفر» (تكتبها main.js بعد
   `HERO.enter()`). ولها شبكة أمانٍ زمنيّة هناك، فتعطُّل الحزمة لا يُبقي
   الواجهة خاليةً أبدًا. */
.film-layer__img,
.film-flat { visibility: hidden; }

html[data-film][data-scene] .film-layer__img,
html[data-film][data-scene] .film-flat { visibility: visible; }

.film-frame { opacity: 0; }
html[data-film][data-scene] .film-frame {
    opacity: 1;
    transition: opacity 0.6s ease-out;
}
@media (prefers-reduced-motion: reduce) {
    html[data-film][data-scene] .film-frame { transition: none; }
}
.film-flat {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

/* الوهج يُجمَع ولا يحجب. طبقات السماء مصدَّرةٌ معتمةً على أسود بلا قناة ألفا
   (وفّر ٩٥٪ من وزنها)، وscreen هو ما يُخفي الأسود ويُبقي الضوء — وهو أيضًا
   السلوك الفيزيائي الصحيح لضوء النجوم فوق سماء.

   والمزج على **الطبقة** لا على الصورة داخلها، وهذا فرقٌ يقرّر إن كان يعمل
   أصلًا: `.film-layer` عنصرٌ مُموضَعٌ بـ`z-index` صريح (أدناه)، أي أنّه سياق
   تكديسٍ مستقلّ. فالمزج على الصورة كان محبوسًا داخل طبقته: خلفيّةُ المزج لا
   تتعدّى أباها، وليس تحت الصورة داخل طبقتها **شيء** — فيمزج الأسودَ مع
   العدم ويخرج كما دخل. النتيجة صندوقٌ أسود حول الهلال يحجب درب التبانة تحته،
   وهو ما كان يُرى. وبنقل الخاصيّة إلى الطبقة تصير خلفيّةُ المزج هي `.film-frame`
   بكل ما رُسم فيه من طبقاتٍ أدنى — فيختفي الأسود ويبقى الضوء كما وُعد. */
.film-layer[data-blend="screen"] { mix-blend-mode: screen; }

/* ترتيب الرسم صريحٌ لا موروثٌ من ترتيب السطور: إعادةُ ترتيب سطرين في
   index.html كانت ستقلب المشهد رأسًا على عقب بلا خطأٍ في أي مكان. */
.film-layer[data-layer="stars"]     { z-index: 1; }
.film-layer[data-layer="milkyway"]  { z-index: 2; }
.film-layer[data-layer="moon"]      { z-index: 3; }
.film-layer[data-layer="dunes-far"] { z-index: 4; }
.film-layer[data-layer="town"]      { z-index: 5; }
.film-layer[data-layer="dunes-mid"] { z-index: 6; }
.film-layer[data-layer="dune-near"] { z-index: 7; }
.film-layer[data-layer="traveller"] { z-index: 8; }

/* نوافذ البلدة تُشعَل بقفزات، لا بتدرّج — «أضواءٌ تُفتَح» لا «صورةٌ تُبهَت».
   وهذا ما يُبقيها داخل استثناء «نافذة واحدة» في docs/architecture/identity.md §٢ شكلًا
   ومعنًى: خطوةٌ واحدة، بلا تدرّج، ومربوطةٌ بيد الزائر لا بمؤقّت.
   المصدر واحد `data-win` يكتبه المحرّك من windowStep() المُختبَرة. */
.film-layer[data-layer="town"] { transition: filter 0.28s steps(1, end); }
.film-stage[data-win="0"] .film-layer[data-layer="town"] { filter: brightness(0.18); }
.film-stage[data-win="1"] .film-layer[data-layer="town"] { filter: brightness(0.42); }
.film-stage[data-win="2"] .film-layer[data-layer="town"] { filter: brightness(0.64); }
.film-stage[data-win="3"] .film-layer[data-layer="town"] { filter: brightness(0.84); }
.film-stage[data-win="4"] .film-layer[data-layer="town"] { filter: none; }

/* سطور القصّة. **داخل المسرح لا داخل `#home`** — وهذا قرار سلامة لا ترتيب:
   المسرح شقيقُ `<main>` وليس حفيدَ `.scroll-section`، فمنعُ الـopacity في
   السطر ١١٨ (خلل iOS Safari) لا يسري عليه. لو وُضعت في القسم لجاز أن تتجمّد
   شفّافةً إلى الأبد عند أول رجوعٍ من صفحة الألعاب. */
.film-captions {
    position: absolute;
    inset-inline: 0;
    top: 22%;
    z-index: 9;
    text-align: center;
    pointer-events: none;
}
.film-caption {
    margin: 0;
    opacity: 0;                        /* الحالة الافتراضية صامتة؛ GSAP يرفعها */
    font-size: clamp(1.05rem, 2.4vw, 1.9rem);
    line-height: 1.9;
    color: var(--ink-2);
    text-shadow: 0 2px 24px rgba(7, 13, 24, 0.9);
}

/* اللوحة المسطّحة — المسار الضعيف وحده. تُعرض حين data-film="still".
   غلافها `<picture>` (ليأخذ الطقم العمودي) لا يأخذ صندوقًا: `display:contents`
   يُبقي الصورة وحدها في التخطيط، فتظلّ قواعد الموضع أدناه صحيحةً بحرفها. */
.film-stage > picture { display: contents; }
.film-flat {
    position: absolute;
    inset: 0;
    display: none;
}
html[data-film="still"] .film-flat  { display: block; }
html[data-film="still"] .film-layer { display: none; }

/* ---- لا مدرج: القصّة مقطعٌ يُعرض، لا مسافةٌ تُسحَب -------------------------
   كان هنا مدرجٌ بارتفاع ٣٠٠vh تُسحَب فيه القصّة بالتمرير على الشاشة، وعرضٌ
   تلقائيّ على اللمس وحده. بقرار المالك (٨ أغسطس ٢٠٢٦) صار العرض التلقائي هو
   السلوك الوحيد على كل جهاز — «خلّ الصور مقطع زي الجوال».

   فحُذف المدرج من هنا نهائيًّا لا أُخفي بقاعدة: إبقاؤه يعطي الزائر ٣٠٠vh من
   تمريرٍ ميّت فوق مشهدٍ يتحرّك بنفسه — وعدٌ لا يفي، وهو العطل نفسه الذي
   أُصلح مرّتين من قبل (المسار الضعيف، ثم اللمس). و`.hero-runway` نفسه ما زال
   في index.html عنصرًا فارغًا بلا قاعدةٍ تعطيه ارتفاعًا، أي بلا أثر.       */
html[data-hero="story"] #home {
    /* مركزةُ flex تقصّ أعلى المحتوى حين يفيض عن الحاوية. */
    justify-content: flex-start;
}
html[data-hero="story"] .hero-runway { display: none; }

/* `justify-content` وحده لا يفعل شيئًا على عنصرٍ غير flex — وبدون `display`
   هبط العنوان إلى أعلى القسم واصطدم بالمسبحة. */
html[data-hero="story"] .hero-inner-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    min-height: 100vh;
    transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ولأنه لا مدرج، يملأ العنوان الشاشة من أول إطار: الخاتمة حاضرةٌ قبل أن تبدأ
   الحكاية. هذه القاعدة تؤخّره حتى خاتمة المشهد — كانت محصورةً باللمس، وصارت
   على كل جهاز لأن العرض التلقائي صار على كل جهاز.
   `visibility` لا `opacity`: منعُ تحريك الشفافية على أحفاد `.scroll-section`
   (تجمّد إطار البداية على iOS Safari) قائم، وهذه حالةٌ مشتقّةٌ من سمةٍ لا
   حركة، فلا إطار بدايةٍ يعلق أصلًا.
   و`transform` وحده لا يكفي للإخفاء: إزاحةُ العنوان خارج الشاشة توسّع منطقة
   تمرير `#home` فتُرجع التمرير الميّت الذي حُذف المدرج لإزالته.
   السمة يضعها السكربت السطري ويرفعها `rest()` في story.mjs — وغيابُها هو
   الحالة الافتراضية، فأيُّ فشلٍ في JS يترك العنوان ظاهرًا كما كان. */
html[data-hero="story"][data-story="playing"] .hero-inner-content {
    visibility: hidden;
    transform: translateY(3.5rem);
}

/* حركةٌ أقلّ: لا مدرج، ولا قصّة، ولا will-change لطبقةٍ لن تتحرّك — رفعُها إلى
   طبقة تركيب مستقلّة يكلّف ذاكرة بلا مقابل. المشهد عند الراحة هو التصميم
   النهائي أصلًا، فحذفُ القصّة لا يترك نقصًا. */
@media (prefers-reduced-motion: reduce) {
    html[data-hero="story"] .hero-runway { display: none; }
    .film-layer, .film-layer__img, .film-flat { will-change: auto; }
    .film-layer[data-layer="town"] { transition: none; }
}

/* ---- ساعة السُّرى — the hour of the night --------------------------------
   سُرى is the night journey. `data-phase` is written on <html> by the loom from
   the player's LOCAL clock (dusk · deep · dawn · day), so the page is not a
   picture of night — it is in one. The cloth's own threads are re-ordered in
   loom.mjs; these rules carry the hour into the air around it.               */
html[data-backdrop="loom"][data-phase="dusk"]:not([data-theme="light"]) .video-overlay {
    background: radial-gradient(circle at 62% 78%, rgba(90, 34, 18, 0.24) 0%, rgba(28, 13, 18, 0.52) 48%, rgba(10, 8, 14, 0.82) 100%);
}
html[data-backdrop="loom"][data-phase="deep"]:not([data-theme="light"]) .video-overlay {
    background: radial-gradient(circle at 50% 42%, rgba(12, 20, 40, 0.18) 0%, rgba(8, 12, 26, 0.56) 46%, rgba(3, 5, 12, 0.90) 100%);
}
html[data-backdrop="loom"][data-phase="dawn"]:not([data-theme="light"]) .video-overlay {
    background: radial-gradient(circle at 38% 84%, rgba(96, 30, 52, 0.20) 0%, rgba(14, 22, 38, 0.50) 46%, rgba(7, 11, 24, 0.82) 100%);
}
html[data-backdrop="loom"][data-phase="day"]:not([data-theme="light"]) .video-overlay {
    background: radial-gradient(circle at 50% 30%, rgba(30, 38, 56, 0.14) 0%, rgba(18, 24, 40, 0.40) 52%, rgba(10, 15, 30, 0.70) 100%);
}

/* The hero's first line is rewritten when the hour turns, and it is REWOVEN
   rather than swapped: the shuttle passes right-to-left (the direction it
   travels on an Arabic loom), unwriting the old line and writing the new one
   behind itself. clip-path only — this line is a .scroll-section descendant
   and animating its opacity re-opens the iOS blank-hero bug (see :118). */
.hero-phase-line { display: inline-block; will-change: clip-path; }
.hero-phase-line.is-reweaving { animation: phaseReweave 440ms var(--ease-quart) both; }
@keyframes phaseReweave {
    0%   { clip-path: inset(0 0 0 0); }
    49%  { clip-path: inset(0 100% 0 0); }
    50%  { clip-path: inset(0 0 0 100%); }
    100% { clip-path: inset(0 0 0 0); }
}
@media (prefers-reduced-motion: reduce) {
    .hero-phase-line.is-reweaving { animation: none; }
}

/* Premium Vignette / Overlay Layer */
.video-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: radial-gradient(circle at center, rgba(15, 23, 42, 0.15) 0%, rgba(15, 23, 42, 0.45) 50%, rgba(10, 15, 30, 0.75) 100%);
    z-index: 1;
    pointer-events: none;
    transition: background var(--transition-smooth);
}

/* --- Floating Pill Navigation --- */
.header {
    position: fixed;
    top: 0; left: 0; right: 0;
    width: 100%;
    z-index: 200;
    pointer-events: auto;
}

/* ============================================================
   SuraNavbar — image-based misbaha navbar (3 states crossfade).
   Artwork: public/navbar/misbaha-{home,games,newsletter}.png (1915×210).
   Three glow states crossfade so the light "travels" across the
   beads on route change. Baked labels are masked with page navy and
   replaced by live Reem Kufi text we fully control.
   All functional IDs are preserved (#nav-container, .nav-link[data-target],
   #nav-logo, #login-button, #settings-button, #logout-button) so the
   existing app.js keeps driving nav + auth untouched.
   ============================================================ */
#nav-container,
.sura-drawer,
.sura-drawer-scrim {
    --navy:      #0A1628;
    --navy-deep: #060D18;
    --gold:      var(--gold-600);
    --gold-soft: var(--gold-300);
    --ivory:     #F5F1E8;
    --red-dim:   #d98a8a;
    --nav-h:     clamp(56px, 6.4vw, 82px);
    --nav-ease:  var(--ease-expo);
    --nav-font:  'Reem Kufi', system-ui, sans-serif;
}

.sura-navbar {
    position: relative;
    background: transparent;   /* the site's background video shows through */
}

/* stage is sized to the ARTWORK (height-driven, exact ratio) & centred, so it
   never letterboxes and the % hotspots land true on the beads. */
.sura-navbar__stage {
    position: relative;
    height: var(--nav-h);
    width: calc(var(--nav-h) * 1915 / 210);
    max-width: 100%;
    margin: 0 auto;
    container-type: inline-size;
}
.sura-navbar__img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: center;
    user-select: none;
    -webkit-user-drag: none;
    pointer-events: none;
    opacity: 0;
    transition: opacity 0.7s ease-in-out;
}
/* `[data-ready]` شرطٌ ثانٍ لنفس السبب الذي فوق: المسبحة صورةٌ بصندوقٍ كامل
   (748×82 على المكتب)، فما دامت في الطريق يرسم كروم مكانها إطارًا فاتحًا —
   وهو أطول «خطٍّ أبيض» عمرًا على الصفحة. تكتبها النصّية المضمّنة تحت الشريط
   مباشرةً عند وصول الصورة أو فشلها، ولها شبكة أمانٍ زمنيّة، فلا يمكن للشريط
   أن يبقى خفيًّا. */
.sura-navbar__img.is-active[data-ready] { opacity: 1; }

.sura-navbar__hotspots { position: absolute; inset: 0; }

/* baked labels are now erased from the PNGs themselves (transparent band),
   so no mask is needed — the live Reem Kufi labels sit over the video directly */
.nav-labels-mask { display: none; }

/* the ul is just a positioning layer for the labels */
.nav-links {
    position: absolute;
    inset: 0;
    margin: 0; padding: 0;
    list-style: none;
    pointer-events: none;
}
.nav-links li { position: static; }
.nav-indicator-pill { display: none; }

/* live Reem Kufi labels (the real .nav-link elements app.js already drives) */
.nav-link.nav-label {
    position: absolute;
    top: 54%;
    height: 24%;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    text-decoration: none;
    font-family: var(--nav-font);
    font-weight: 500;
    /* px bounds, not rem: the misbaha artwork is fixed-proportion, so nav text
       must track the artwork (cqw) and stay out of --font-scale's reach —
       otherwise accessibility zoom grows the labels past their slots and they
       collide with the account cluster. */
    font-size: clamp(11.5px, 1.7cqw, 16.3px);
    /* --font-scale is rem-based so px already escapes it, but Android Chrome
       folds the SYSTEM font-size preference into a text-autosizing multiplier
       that scales px too — which is the reported failure («لو شخص حط خط كبير»):
       the labels grow while the misbaha PNG behind them cannot, and each word
       walks off its own bead. Opted out here and ONLY here; the site's own zoom
       control in الإعدادات remains the accessible way to enlarge text, and it
       still governs every other word on the page. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    color: var(--ink-2);                                  /* lighter ink — reads over video */
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7);       /* legibility without a plate */
    cursor: pointer;
    border-radius: var(--r-sm);
    pointer-events: auto;
    z-index: 2;
    transition: color 0.25s ease, text-shadow 0.25s ease;
    white-space: nowrap;
}
.nav-link.nav-label:hover { color: #c9c4b6; }
.nav-link.nav-label.active {
    color: var(--gold-soft);
    text-shadow: 0 1px 4px rgba(0, 0, 0, 0.7), 0 0 14px rgba(201, 162, 39, 0.55);
    cursor: default;
}
.nav-link.nav-label:focus-visible { outline: 2px solid var(--gold-soft); outline-offset: 2px; }
.nav-label--home       { right: 28%; width: 20%; }
.nav-label--games      { right: 47%; width: 20%; }
.nav-label--newsletter { right: 65%; width: 20%; }

/* generic hotspot base (logo) */
.nav-hotspot {
    position: absolute;
    top: 0; height: 100%;
    display: block;
    background: transparent;
    border: 0; padding: 0; margin: 0;
    cursor: pointer;
    pointer-events: auto;
    border-radius: var(--r-sm);
    -webkit-tap-highlight-color: transparent;
}
.nav-hotspot[hidden] { display: none; }
.nav-hotspot:focus-visible { outline: 2px solid var(--gold-soft); outline-offset: -3px; }
.nav-hotspot--logo { right: 0; width: 22%; }

/* The سُرى lockup. The baked wordmark's old slot is only ~9% of the stage
   wide, and this lockup is a 2.3:1 horizontal composition — squeezed in there
   the fort and the sadu band collapse into a smudge. So it sits just past the
   tassel instead, in the empty margin beside the stage, where it can be big
   enough to actually read. Sized off the stage (%), never rem, so it scales
   with the artwork and stays out of --font-scale's reach — same rule as
   .nav-label. */
.nav-logo-mark {
    position: absolute;
    /* % here resolve against .nav-hotspot--logo (22% of the stage), not the
       stage itself — this offset clears the tassel tip at every width. */
    right: -60%;
    top: 8%;
    height: 62%;
    width: auto;
    user-select: none;
    -webkit-user-drag: none;
    pointer-events: none;
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55));
    transition: filter 0.45s var(--nav-ease, ease), transform 0.45s var(--nav-ease, ease);
}
.nav-hotspot--logo:hover .nav-logo-mark,
.nav-hotspot--logo:focus-visible .nav-logo-mark {
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55)) drop-shadow(0 0 12px rgba(201, 162, 39, 0.55));
    transform: translateY(-1px);
}

/* ---------- account cluster (far left, over the reserve beads) ---------- */
.nav-account {
    position: absolute;
    left: 1%; top: 0;
    height: 100%;
    width: auto;
    max-width: 24%;
    display: flex;
    align-items: flex-end;
    justify-content: flex-start;
    gap: 6.4px;
    padding-bottom: 6px;
    z-index: 3;
    font-family: var(--nav-font);
}
/* guest / signed-in share the same #login-button pill; app.js swaps its text */
#login-button.nav-login-bead {
    /* inline-BLOCK, not inline-flex, and the distinction is the whole bug:
       `text-overflow: ellipsis` is defined for block containers and does
       NOTHING on a flex container. As inline-flex the name became an anonymous
       flex item packed to the RTL start (the right edge), so when the cluster
       narrowed the box the overflow spilled LEFT and was clipped there —
       «Khalid» rendered as «halid», silently, with the ellipsis parked
       off-screen. app.js only ever writes textContent here (src/main.js:1504),
       never child elements, so the flex box bought nothing in exchange. */
    display: inline-block;
    text-align: center;
    background: var(--navy-deep);
    border: 1px solid var(--gold);
    color: var(--gold);
    font-family: var(--nav-font);
    font-weight: 500;
    font-size: clamp(10.9px, 1.3cqw, 13.8px);   /* px: immune to --font-scale (see .nav-label) */
    line-height: 1;
    padding: 0.45em 1em;
    border-radius: var(--r-full);
    cursor: pointer;
    white-space: nowrap;
    text-decoration: none;
    max-width: 12ch;
    overflow: hidden;
    text-overflow: ellipsis;
    /* The page is dir="rtl", so an RTL box holding a LATIN name puts the inline
       START at the right edge — and a narrowed box then clips the BEGINNING of
       the word while parking the ellipsis where nobody can see it. That is how
       «Khalid» rendered as «halid» with no «…» to hint at it (reported August
       2026 from a phone; reproduced at 1280px with a 14-character name, so it
       was never mobile-only).
       `plaintext` takes the paragraph direction from the first strong character
       instead of the parent: a Latin name lays out LTR and truncates at its own
       end, an Arabic name stays RTL and truncates at its end. Either way the
       first letter survives, which is the letter the player recognises. */
    unicode-bidi: plaintext;
    transition: background 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
#login-button.nav-login-bead:hover {
    background: var(--gold);
    color: var(--navy-deep);
    box-shadow: 0 0 16px -4px rgba(201, 162, 39, 0.6);
}
/* signed-in: bead reads as the account name (filled gold hint) */
#login-button.nav-login-bead[data-signed-in] {
    background: rgba(201, 162, 39, 0.12);
    color: var(--ivory);
    cursor: default;
}
.nav-iconbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 28px; height: 28px;
    background: transparent;
    border: 0;
    color: var(--gold);
    cursor: pointer;
    border-radius: var(--r-sm);
    flex: none;
    transition: filter 0.2s ease;
}
.nav-iconbtn svg { width: 17px; height: 17px; display: block; }
.nav-iconbtn:hover { filter: drop-shadow(0 0 6px rgba(201, 162, 39, 0.7)); }
.nav-iconbtn:focus-visible { outline: 2px solid var(--gold-soft); outline-offset: 1px; }
.nav-logout-btn {
    display: inline-flex;
    align-items: center;
    background: transparent;
    border: 1px solid rgba(217, 138, 138, 0.55);
    color: var(--red-dim);
    font-family: var(--nav-font);
    font-size: clamp(9.9px, 1.1cqw, 12.5px);   /* px: immune to --font-scale (see .nav-label) */
    line-height: 1;
    padding: 0.4em 0.8em;
    border-radius: var(--r-full);
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.2s ease, color 0.2s ease;
}
.nav-logout-btn[hidden] { display: none; }
.nav-logout-btn:hover { background: rgba(217, 138, 138, 0.14); color: #f0b6b6; }

.sr-only {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------- mobile (< 768px): the wide art is unusable → an inline text bar
   holding the real nav links (no hamburger). Everything is fixed px / clamp so
   it never grows with --font-scale and overflows the bar. --------------------*/
.sura-mbar { display: none; }
@media (max-width: 767px) {
    /* The wide misbaha art IS the navbar. On phones, scale the WHOLE ribbon to
       full width (locked ratio → no letterbox, % / cqw hotspots stay true) rather
       than hiding it behind a text strip. Flips the stage from height-driven to
       width-driven; everything overlaid (labels, logo, login/gear) scales with it. */
    .sura-navbar__stage {
        display: block;
        width: 100%;
        height: auto;
        aspect-ratio: 1915 / 210;
        max-width: none;
        margin: 0;
    }
    .sura-mbar { display: none; }   /* retire the text-strip substitute (kept in DOM as a fallback) */

    /* the ribbon is only ~40px tall on a phone — grow the transparent tap area to
       nearly the full bar height without enlarging the glyph */
    /* WHERE THE LABELS SIT VERTICALLY. Desktop puts them at `top: 54%` — in the
       transparent band BELOW the strand, so the beads stay clean. The July round
       changed mobile to `top: 8%; height: 84%` to enlarge the tap target, which
       as a side effect re-centred the text ON the beads: the box spanned almost
       the whole ribbon and flex-centring put the glyphs right across the bead
       row («لاصقين بالسبحة», reported August 2026).
       The proportions are identical at every width because the artwork ratio is
       locked, so restoring the desktop band restores the desktop look. The box
       still runs to the ribbon's bottom edge, which keeps a 22px tap target on a
       393pt phone — short of the 44px ideal, but the whole ribbon is only 43px,
       and row 2 below is where the large targets now live. */
    /* 2.9cqw, not 3.1: at 3.1 the longest label («الألعاب الذهنية») measured
       79px of ink inside a 79px slot — fitting exactly is not fitting, since any
       font-metric variance between engines spills it into its neighbour's bead.
       At 2.9 it measures 74/79 and keeps ~6% headroom on every width tested. */
    .nav-link.nav-label { top: 52%; height: 52%; font-size: clamp(11px, 2.9cqw, 14px); }

    /* WHY THE LABELS ARE RE-SPREAD HERE, AND WHY THE ACCOUNT CLUSTER LEAVES THE
       RIBBON (August 2026 — reported from a real phone, and it is arithmetic,
       not taste):
         the artwork is locked at 1915/210, so on a 393pt phone the ribbon is
         43pt TALL and 393pt WIDE. Into that strip the desktop layout packs the
         logo (~50), three Arabic labels (~220 with gaps) and the account
         cluster (~130) = ~400pt of content in 393pt of bar. It overflowed even
         with a short name.
         `.nav-account` capped itself at `max-width: 24%` = 94pt while holding
         ~160pt (12ch name pill + gear + «خروج»), so it spilled leftwards under
         `.nav-label--newsletter`, whose slot starts at 15% = 59pt — the exact
         overlap in the report. And because the cluster is RTL with
         `overflow: hidden`, the clip ate the START of the name: «Khalid» read
         as «halid», with no ellipsis to hint at it.
       No amount of clamp() fixes this: fluid sizing scales content into the
       space there is, and here there isn't enough. So on phones the ribbon
       carries art + logo + labels only, and the cluster drops to its own row
       directly beneath (`top: 100%`) — which needs no DOM change, so every id
       app.js drives (#login-button/#settings-button/#logout-button) stays put. */
    /* NO horizontal overrides here, and that is the point. The three slots at
       28% / 47% / 65% are aligned to the BEAD GROUPS in the artwork, and the
       ratio is locked, so the same percentages land on the same beads at every
       width. An earlier version of this round re-spread them to 26/48/74 to use
       the space the account cluster had vacated — which moved every word off its
       own segment and pushed «نشرة سُرى» onto the far knot. Measured after the
       revert: the longest label needs 66px of a 79px slot at 393pt, so there is
       headroom without touching the positions.
       `overflow: hidden` is the guarantee, not the layout: a longer label added
       later clips inside its own slot instead of sliding under its neighbour.
       And the font stays in px (clamp + cqw) so accessibility zoom — which
       scales --font-scale, not px — can never reintroduce the collision. */
    .nav-link.nav-label { overflow: hidden; }

    /* the سُرى wordmark normally sits in the empty margin PAST the tassel
       (right:-60%), but full-width mobile has no such margin → it fell off-screen.
       Bring it back onto the right end of the strand, over the tail beads. */
    .nav-logo-mark { right: 3%; top: 14%; height: 60%; }

    /* row 2 — the account cluster, under the ribbon rather than on it */
    .nav-account {
        top: 100%;
        left: 0;
        height: auto;
        width: 100%;
        max-width: none;
        align-items: center;
        /* the page is dir="rtl", so flex-END is the LEFT edge — which is where
           the cluster already lives on desktop. Keeping the side unchanged is
           deliberate: this round fixes a collision, it does not restyle the nav. */
        justify-content: flex-end;
        gap: 8px;
        padding: 5px 12px 7px;
        /* the ribbon art is transparent and the hero video runs behind it, so
           this row would otherwise float over moving footage. A short scrim
           fading to nothing keeps the pills legible without drawing a bar. */
        background: linear-gradient(to bottom, rgba(6, 13, 24, 0.72), rgba(6, 13, 24, 0));
    }
    /* the name is the point of the pill — give it the room the row now has. The
       12ch desktop cap is what forced the clip; past half the viewport an
       ellipsis is still better than pushing the gear off-screen. */
    #login-button.nav-login-bead {
        padding: 0.42em 0.95em;
        font-size: 13px;
        max-width: min(52vw, 26ch);
    }
    .nav-logout-btn { font-size: 12px; padding: 0.42em 0.8em; }
    .nav-iconbtn { width: 30px; height: 30px; }
    .nav-iconbtn svg { width: 17px; height: 17px; }

    .sura-mbar {
        display: none;
        align-items: center;
        gap: 0.35rem;
        height: 56px;
        padding: 0 0.6rem;
        background: var(--navy);
    }
    .sura-mbar__logo {
        display: inline-flex;
        align-items: center;
        text-decoration: none;
        flex: none;
    }
    .sura-mbar__logo img {
        height: 24px;
        width: auto;
        display: block;
        filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.5));
    }
    /* the three nav links, centred and allowed to shrink on tiny screens */
    .sura-mbar__links {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 0.1rem;
        flex: 1 1 auto;
        min-width: 0;
    }
    .sura-mbar__link {
        color: #cdd6e4;
        text-decoration: none;
        font-family: var(--nav-font);
        font-size: clamp(0.72rem, 3.3vw, 0.84rem);
        font-weight: 600;
        white-space: nowrap;
        padding: 0.4rem 0.34rem;
        border-radius: var(--r-sm);
        position: relative;
        transition: color 0.2s ease;
    }
    .sura-mbar__link.active { color: var(--gold); }
    .sura-mbar__link.active::after {
        content: "";
        position: absolute;
        left: 0.34rem; right: 0.34rem; bottom: 3px;
        height: 2px; border-radius: 2px;
        background: var(--gold);
        box-shadow: 0 0 8px rgba(201, 162, 39, 0.7);
    }
    /* account cluster (login bead + gear + logout), proxying the real controls */
    .sura-mbar__acct {
        display: inline-flex;
        align-items: center;
        gap: 0.2rem;
        flex: none;
    }
    .sura-mbar__login {
        font-family: var(--nav-font);
        font-size: var(--fs-xs);
        font-weight: 700;
        color: var(--navy);
        background: var(--gold);
        border: 0;
        border-radius: var(--r-full);
        padding: 0.32rem 0.65rem;
        cursor: pointer;
        max-width: 86px;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .sura-mbar__iconbtn {
        display: inline-flex;
        align-items: center; justify-content: center;
        width: 32px; height: 32px;
        background: transparent;
        border: 0;
        color: var(--gold);
        cursor: pointer;
        padding: 0;
        flex: none;
    }
    .sura-mbar__iconbtn svg { width: 19px; height: 19px; }
    .sura-mbar__logout { color: #e07a7a; }
}

/* side drawer (slides from the right in RTL) */
.sura-drawer-scrim {
    position: fixed; inset: 0;
    background: rgba(3, 8, 16, 0.6);
    opacity: 0; pointer-events: none;
    transition: opacity 0.3s ease;
    z-index: 240;
}
.sura-drawer-scrim.is-open { opacity: 1; pointer-events: auto; }
.sura-drawer {
    position: fixed;
    top: 0; right: 0; bottom: 0;
    width: min(78vw, 320px);
    background: var(--navy-deep);
    border-left: 1px solid rgba(201, 162, 39, 0.25);
    transform: translateX(100%);
    transition: transform 0.32s var(--nav-ease);
    z-index: 250;
    padding: 1.4rem 1.2rem;
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    font-family: var(--nav-font);
}
.sura-drawer.is-open { transform: translateX(0); }
.sura-drawer__close {
    align-self: flex-start;
    background: transparent; border: 0; color: var(--gold);
    font-size: var(--fs-3xl); line-height: 1; cursor: pointer; padding: 0 0 0.6rem;
}
.sura-drawer__link {
    display: flex; align-items: center; gap: 0.6rem;
    color: var(--ivory);
    text-decoration: none;
    font-size: var(--fs-base);
    padding: 0.85rem 0.4rem;
    border-bottom: 1px solid rgba(255,255,255,0.05);
    background: transparent; border-left: 0; border-right: 0; border-top: 0;
    font-family: inherit; text-align: right; cursor: pointer; width: 100%;
}
.sura-drawer__link.active { color: var(--gold); font-weight: 600; }
.sura-drawer__bead {
    width: 8px; height: 8px; border-radius: 50%;
    background: var(--gold);
    box-shadow: 0 0 8px rgba(201,162,39,0.8);
    flex: none; opacity: 0;
}
.sura-drawer__link.active .sura-drawer__bead { opacity: 1; }
.sura-drawer__account {
    margin-top: auto;
    padding-top: 1rem;
    border-top: 1px solid rgba(201, 162, 39, 0.25);
    display: flex; flex-direction: column; gap: 0.6rem;
}
.sura-drawer__acctbtn {
    display: flex; align-items: center; gap: 0.6rem;
    color: var(--ivory);
    background: transparent;
    border: 0;
    font-family: inherit;
    font-size: var(--fs-base);
    text-align: right;
    padding: 0.7rem 0.4rem;
    cursor: pointer;
    width: 100%;
}
.sura-drawer__acctbtn--danger { color: var(--red-dim); }

@media (prefers-reduced-motion: reduce) {
    .sura-navbar__img,
    .sura-drawer,
    .sura-drawer-scrim,
    #login-button.nav-login-bead { transition: none !important; }
}

/* kept only so legacy mobile-drawer JS has its element; never shown */
.mobile-toggle { display: none !important; }


/* --- Hero Layout & Main Content --- */
.main-content {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100dvh;
    position: relative;
}

.hero-section {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    text-align: center;
    padding: 2rem;
    max-width: 900px;
    margin: 0 auto;
    z-index: 10;
    gap: 1.5rem;
}

/* Main Heading */
.hero-title {
    font-family: 'Reem Kufi', sans-serif;
    font-size: 5rem;
    font-size: var(--fs-display);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: normal;
    text-align: center;
    text-decoration: none;
    padding-bottom: 0.12em; /* breathing room so tall fonts (Naskh) aren't clipped */
    color: var(--clr-text-main);
    max-width: 15ch;
    /* symmetric glow (no downward offset) — an offset shadow read as a line
       under each word with thin fonts like Tajawal. */
    filter: drop-shadow(0 0 14px rgba(0,0,0,0.30));
}

/* Description Subheading */
.hero-description {
    font-size: var(--fs-xl);
    font-size: clamp(1.05rem, 2.5vw, 1.35rem);
    font-weight: 500;
    line-height: 1.6;
    text-align: center;
    text-decoration: none;
    color: var(--clr-text-muted);
    max-width: 38ch;
    margin-inline: auto;
}

/* Hero Button Groups */
.hero-buttons {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 1rem;
}

/* ============================================================
   مرور الضوء — the hero is revealed by the lamp, not faded in
   ============================================================
   يُشتقّ هذا كله من docs/architecture/identity.md، لا من ذوق:

   §2 «حركة تُشاهَد ولا تُستدعى = ديكور» — أسقط المكوك السابق: عنصران يلعبان
       بأنفسهما عند كل زيارة، لا يستدعيهما أحد ولا يستجيبان لشيء. حُذفا.
   §2 «في السكون: لا شيء يتحرّك» — فلا حركة هنا إلا مرّة واحدة، ردًّا على
       وصولك، ثم صمت تامّ. ليست حلقة.

   ما بقي: المصباح (loom.mjs) يعبر الهيرو مرّة، والنصّ **يُكشف خلفه** سطرًا
   بعد سطر. لا عنصر زخرفي جديد إطلاقًا — الضوء الذي يكشف النصّ هو نفسه الضوء
   الذي ستحمله بمؤشّرك بعد ثانية. الفكرة الواحدة تُقدَّم بنفسها ثم تُسلَّم لك.

   التوقيت مشتقّ من `--sweep` التي تكتبها loom.mjs، لا مثبّت هنا: مدّة المرور
   تتغيّر بساعة الليل (أبطأ في العمق، أسرع في النهار)، ولو ثُبّت التوقيت في
   الطرفين لانفصل النصّ عن الضوء كلما تغيّرت الساعة.

   LINEAR وليس منحنى البيت — وهذا ليس خيار ذوق. الضوء يعبر بسرعة واحدة، فلو
   كان الكشف مخفَّفًا لسبق النصُّ الضوءَ ووصل قبل أن يُنسج. قِيس سابقًا مع
   --ease-quart: عند ١٥٠٠ms كان الضوء قد قطع ٧١% والأزرار مكشوفة ٨٤%.

   القيد (style.css:302): لا شيء هنا يحرّك `opacity` — كل هذه العناصر أحفاد
   `.scroll-section`، وiOS Safari يجمّد إطار `from` حين يعود قسم ثابت من
   `display:none` فيختفي الهيرو. الكشف بـ`clip-path` وحده، والنصّ opacity:1
   دائمًا، فيستحيل أن يعلق مخفيًّا. */

/* الافتراضي حين لا يوجد JS: مرور بمدّة معقولة، فلا تعلق الصفحة بلا كشف. */
:root { --sweep: 1150ms; }

/* الكشف صنفٌ يضيفه JS لا حالةٌ تُشتقّ من `.active` — والسببان مقيسان:
   ١. القاعدة القديمة كانت `html[data-booted] .hero-section.active …`، و
      `data-booted` تُكتب لحظة DOMContentLoaded بينما محتوى الهيرو محجوبٌ تحت
      `data-story="playing"` وخلف بوّابتَي الفيلم. فكان الكشف كلّه يُنفَق على
      نصٍّ لا يراه أحد، ثم يظهر النصّ بلا حركة: «مع الريلود ما تشتغل».
   ٢. إطار البداية في `weaveRTL` هو `inset(… 100%)` — أي نصٌّ **مخفيٌّ تمامًا**.
      كل ما قيل في :302 عن تجميد iOS Safari لإطار البداية عند عودة قسمٍ من
      `display:none` يسري عليه حرفيًّا، فأيُّ فشلٍ في تشغيل الحركة كان يترك
      النصّ مختفيًا: «مرات تختفي».
   بالصنف صارت حالة الراحة **بلا حركةٍ أصلًا**: يُضاف عند لحظة الكشف ويُزال عند
   `animationend` (وبشبكة أمانٍ زمنيّة)، فأسوأ ما يحدث «ظهر بلا حركة». */
.is-weaving {
    animation: weaveRTL var(--weave-dur, 0.53s) linear var(--weave-delay, 0s) both;
}
.is-weaving[data-weave="ltr"] { animation-name: weaveLTR; }

/* -20% أعلى وأسفل كي لا يقصّ الـclip هالةً أو نازلَ حرف. */
@keyframes weaveRTL {
    from { clip-path: inset(-20% 0 -20% 100%); }
    to   { clip-path: inset(-20% 0 -20% 0); }
}
@keyframes weaveLTR {
    from { clip-path: inset(-20% 100% -20% 0); }
    to   { clip-path: inset(-20% 0 -20% 0); }
}

/* ---- والقسمان الآخران يُكشفان كذلك ---------------------------------------
   هيرو منسوج بجانب صفحة ألعاب يظهر عنوانها بتلاشٍ = فكرة واحدة وبقيّتان.
   الانتقال بين المسارات فعلٌ منك، فالكشف هنا **مُستدعى** لا مُشاهَد. */
@media (prefers-reduced-motion: reduce) {
    .is-weaving { animation: none; }
}

/* Get Started primary white button */
.btn-primary {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0.9rem 2.2rem;
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    text-decoration: none;
    border-radius: var(--r-full);
    font-size: var(--fs-base);
    font-weight: 600;
    box-shadow: 0 4px 20px rgba(198, 154, 74, 0.28), 0 8px 30px rgba(0, 0, 0, 0.18);
    border: 1px solid var(--clr-brand-secondary);
    transition: var(--transition-smooth);
}

.btn-primary:hover {
    background: linear-gradient(135deg, var(--clr-brand-secondary), var(--clr-brand-primary));
    transform: translateY(-2px) scale(1.02);
    box-shadow: 0 8px 25px rgba(198, 154, 74, 0.4), 0 12px 40px rgba(0, 0, 0, 0.28);
}

.btn-primary:active {
    transform: translateY(0) scale(1);
}

/* Watch Demo Button */
.btn-secondary {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    background: transparent;
    border: none;
    cursor: pointer;
    font-size: var(--fs-base);
    font-weight: 600;
    color: var(--clr-text-main);
    padding: 0.9rem 1.5rem;
    border-radius: var(--r-full);
    transition: var(--transition-smooth);
    position: relative;
}

.play-icon {
    width: 20px;
    height: 20px;
    fill: currentColor;
    transition: var(--transition-smooth);
}

.btn-secondary:hover {
    color: var(--ink-0);
}

.btn-secondary:hover .play-icon {
    transform: scale(1.15) rotate(10deg);
}

.btn-secondary::after {
    content: '';
    position: absolute;
    bottom: 0.6rem;
    left: 1.5rem;
    right: 1.5rem;
    height: 1.5px;
    background-color: currentColor;
    transform: scaleX(0);
    transform-origin: left;
    transition: var(--transition-smooth);
}

.btn-secondary:hover::after {
    transform: scaleX(1);
}

/* --- Scroll Down Indicator --- */
.scroll-indicator-container {
    position: absolute;
    bottom: 2.5rem;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    opacity: 0;
    animation: fadeIn 1s ease-out 1s forwards;
}

.scroll-indicator {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    text-decoration: none;
    color: var(--clr-text-muted);
    font-size: var(--fs-2xs);
    font-weight: 700;
    letter-spacing: 0.15em;
    padding: 0.5rem 1.2rem;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--r-full);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    transition: var(--transition-smooth);
}

.scroll-arrow {
    width: 16px;
    height: 16px;
    fill: currentColor;
    animation: pulseArrow 2s infinite ease-in-out;
}

.scroll-indicator:hover {
    color: var(--clr-text-main);
    border-color: rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.06);
    transform: translateY(2px);
}

/* --- Floating Live Video Customizer --- */
.customizer-widget {
    position: fixed;
    bottom: 2rem;
    right: 2rem;
    z-index: 110;
}

/* Main pulsing floating action button */
.customizer-toggle {
    width: 52px;
    height: 52px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.05);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid var(--glass-border);
    color: var(--clr-text-main);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: var(--glass-shadow), 0 10px 30px rgba(0,0,0,0.3);
    transition: var(--transition-smooth);
    position: relative;
}

.customizer-icon {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    transition: var(--transition-smooth);
}

.customizer-toggle:hover {
    border-color: var(--glass-border-hover);
    box-shadow: var(--glass-shadow-hover);
    transform: rotate(30deg) scale(1.05);
    background: rgba(255, 255, 255, 0.08);
}

/* Tooltip on Hover */
.customizer-tooltip {
    position: absolute;
    right: calc(100% + 15px);
    top: 50%;
    transform: translateY(-50%) translateX(10px);
    background: rgba(15, 23, 42, 0.95);
    border: 1px solid rgba(255, 255, 255, 0.1);
    color: var(--clr-text-main);
    padding: 0.5rem 1rem;
    border-radius: var(--r-sm);
    font-size: var(--fs-sm);
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    box-shadow: 0 4px 15px rgba(0,0,0,0.3);
    transition: var(--transition-smooth);
}

.customizer-toggle:hover .customizer-tooltip {
    opacity: 1;
    transform: translateY(-50%) translateX(0);
}

/* Customizer Panel Settings Drawer */
.customizer-panel {
    position: absolute;
    bottom: calc(100% + 15px);
    right: 0;
    width: 320px;
    background: rgba(15, 23, 42, 0.85);
    backdrop-filter: blur(28px);
    -webkit-backdrop-filter: blur(28px);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-lg);
    box-shadow: 0 20px 50px rgba(0,0,0,0.5), var(--glass-shadow);
    padding: 1.5rem;
    opacity: 0;
    transform: translateY(15px) scale(0.95);
    pointer-events: none;
    transition: var(--transition-smooth);
    z-index: 120;
    overflow: hidden;
}

.customizer-panel::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    height: 4px;
    background: linear-gradient(90deg, var(--clr-brand-primary), var(--clr-brand-secondary));
}

.customizer-panel.active {
    opacity: 1;
    transform: translateY(0) scale(1);
    pointer-events: auto;
}

.panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
}

.panel-header h3 {
    font-size: var(--fs-xl);
    font-weight: 700;
}

.panel-close {
    background: transparent;
    border: none;
    color: var(--clr-text-muted);
    font-size: var(--fs-2xl);
    cursor: pointer;
    line-height: 1;
    transition: var(--transition-quick);
}

.panel-close:hover {
    color: var(--clr-text-main);
}

.panel-desc {
    font-size: var(--fs-xs);
    color: var(--clr-text-muted);
    line-height: 1.4;
    margin-bottom: 1.25rem;
}

.input-group {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    margin-bottom: 1.25rem;
}

.input-group label {
    font-size: var(--fs-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--clr-text-muted);
}

.input-wrapper {
    display: flex;
    gap: 0.5rem;
}

#video-url-input {
    flex: 1;
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--r-sm);
    padding: 0.6rem 0.8rem;
    color: var(--clr-text-main);
    font-family: inherit;
    font-size: var(--fs-sm);
    outline: none;
    transition: var(--transition-quick);
}

#video-url-input:focus {
    border-color: var(--clr-brand-primary);
    background: rgba(255, 255, 255, 0.08);
}

.btn-apply {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    border: none;
    border-radius: var(--r-sm);
    padding: 0.6rem 1rem;
    font-weight: 600;
    font-size: var(--fs-sm);
    cursor: pointer;
    transition: var(--transition-quick);
}

.btn-apply:hover {
    transform: translateY(-1px);
    box-shadow: 0 4px 10px rgba(198, 154, 74, 0.3);
}

/* Preset Buttons Grid */
.presets-section {
    margin-bottom: 1.25rem;
}

.presets-section h4, .settings-section h4 {
    font-size: var(--fs-2xs);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--clr-text-muted);
    margin-bottom: 0.6rem;
}

.presets-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.5rem;
}

.preset-btn {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    background: rgba(255, 255, 255, 0.04);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--r-sm);
    padding: 0.5rem 0.6rem;
    color: var(--clr-text-muted);
    font-size: var(--fs-xs);
    font-family: inherit;
    cursor: pointer;
    transition: var(--transition-quick);
}

.preset-btn:hover {
    color: var(--clr-text-main);
    border-color: rgba(255, 255, 255, 0.2);
    background: rgba(255, 255, 255, 0.08);
}

.preset-btn.active {
    color: var(--clr-text-main);
    border-color: var(--clr-brand-primary);
    background: rgba(198, 154, 74, 0.1);
}

.preset-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
}
.preset-dot.glass { background: #56ccf2; }
.preset-dot.particles { background: var(--gold-300); }
.preset-dot.tech { background: #bb6bd9; }
.preset-dot.serene { background: var(--ok); }

/* Overlay settings slider */
.range-control {
    display: flex;
    align-items: center;
    gap: 1rem;
}

#overlay-range {
    flex: 1;
    accent-color: var(--clr-brand-primary);
    cursor: pointer;
}

#overlay-value {
    font-size: var(--fs-xs);
    font-weight: 600;
    min-width: 32px;
    text-align: right;
}

/* --- Watch Demo Product Lightbox Modal --- */
.modal-backdrop {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background: rgba(10, 15, 30, 0.85);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    z-index: 150;
    display: flex;
    justify-content: center;
    align-items: center;
    opacity: 0;
    pointer-events: none;
    transition: var(--transition-smooth);
}

.modal-backdrop.active {
    opacity: 1;
    pointer-events: auto;
}

/* النوافذ لا تُهدَم: ثمانيَ عشرةَ منها مُركَّبةٌ دائمًا `display:flex` وتُخفى
   بـ`opacity:0` وحدها — فيبقى على الصفحة ثمانيةَ عشرَ ضبابًا بملء الشاشة
   لعناصر لا تُرى. الضباب على شيءٍ شفّافٍ تمامًا لا يعرضه أحد، وكلفته تُدفَع
   في كلّ إطارِ تمرير. قيس على «الرئيسية»: الضباب الظاهر الوحيد هناك هو هذا،
   وإطفاؤه وحده أعاد الإطار من 14ms إلى 7ms. لا أثر بصريّ البتّة. */
.modal-backdrop:not(.active) {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* والزجاج على المحتوى المرئيّ يُعلَّق أثناء التمرير وحده. `backdrop-filter`
   يُعيد رسم ما خلف العنصر في كلّ إطار، فيتضاعف زمن الإطار (‏7ms ← 14ms) وتسقط
   إطارات عند التمرير السريع. عند السكون — وهو حيث يُنظر إلى التصميم فعلًا —
   الزجاج كما هو تمامًا؛ وأثناء حركةٍ سريعة لا يُدرَك الفرق أصلًا.
   النوافذ المفتوحة مستثناة: ضبابها هو الخلفية نفسها ولا يجوز أن يومض. */
html.sura-scrolling .game-card,
html.sura-scrolling .filters-container,
html.sura-scrolling .filter-pill,
html.sura-scrolling .leaderboard-card,
html.sura-scrolling .featured-issue-section,
html.sura-scrolling .scroll-indicator {
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* Page behind a modal must not scroll or take taps. position:fixed (not just
   overflow:hidden) because iOS Safari happily rubber-bands a body that only
   has overflow:hidden; app.js restores the scroll offset on close. */
body.sura-modal-open {
    position: fixed;
    width: 100%;
    overflow: hidden;
}

.modal-container {
    position: relative;
    width: 90%;
    max-width: 900px;
    aspect-ratio: 16 / 9;
    background: #000000;
    border-radius: var(--r-lg);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 25px 60px rgba(0,0,0,0.6);
    overflow: hidden;
    transform: scale(0.95);
    transition: var(--transition-smooth);
}

.modal-backdrop.active .modal-container {
    transform: scale(1);
}

/* ─── خرزة الإغلاق ──────────────────────────────────────────────────────
   زر الإغلاق ليس دائرة عادية: هو خرزة مسبحة مركّبة على خيط ذهبي يمتد
   نحو داخل النافذة (لا نحو الحافة، تفاديًا للقص بفعل overflow).
   ::before يرسم الخيط + الخرزة الصغيرة المجاورة (طبقتا خلفية).
   ::after  يرسم حلقة الضوء التي تنطلق عند الدفع (.pushed من app.js).
   ───────────────────────────────────────────────────────────────────── */
.modal-close {
    position: absolute;
    top: 1rem;
    /* LOGICAL, not physical. `right: 1rem` on a dir="rtl" page puts the close
       button on the side where every heading BEGINS, so the bead sat over the
       first word of «إعدادات العرض», «حسابي», the game titles — most modals in
       the app (reported August 2026).
       `inset-inline-end` resolves to the LEFT here, which is where a close
       control belongs in RTL and where nothing starts. It also stays correct if
       a page is ever rendered LTR, which a hardcoded side does not. */
    inset-inline-end: 1rem;
    width: 38px;
    height: 38px;
    border-radius: 50%;
    /* اللمعة العلوية أولًا لتغطي مركز النقش، ثم أوجه محفورة، ثم جسم الخرزة */
    background:
        radial-gradient(circle at 34% 26%, rgba(255,255,255,0.30) 0%, rgba(255,255,255,0) 40%),
        radial-gradient(circle at 68% 78%, rgba(201,162,39,0.22) 0%, rgba(201,162,39,0) 55%),
        repeating-conic-gradient(from 0deg at 50% 50%,
            rgba(255,255,255,0.05) 0deg 9deg,
            rgba(0,0,0,0.28)       9deg 18deg),
        linear-gradient(155deg, #1d2a45 0%, #0c1322 62%, var(--surface-0) 100%);
    border: 1px solid rgba(201, 162, 39, 0.28);
    box-shadow:
        inset 0 -4px 9px rgba(0,0,0,0.65),
        inset 0 2px 3px rgba(255,255,255,0.10),
        0 5px 16px rgba(0,0,0,0.5);
    color: rgba(255,255,255,0.88);
    font-size: var(--fs-2xl);
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    z-index: 10;
    -webkit-tap-highlight-color: transparent;
    transition:
        box-shadow 0.45s var(--ease-expo),
        border-color 0.45s var(--ease-expo),
        color 0.4s var(--ease-expo),
        transform 0.4s var(--ease-back);
}

/* الخيط + الخرزة المجاورة */
.modal-close::before {
    content: '';
    position: absolute;
    top: 50%;
    right: calc(50% + 17px);      /* يبدأ عند حافة الخرزة، فلا يمرّ فوقها */
    width: 104px;
    height: 10px;
    transform: translateY(-50%);
    pointer-events: none;
    background:
        radial-gradient(circle 4px at 94px 5px,
            rgba(255,255,255,0.42) 0%, #0d1526 58%,
            rgba(201,162,39,0.55) 62%, rgba(201,162,39,0) 100%),
        linear-gradient(to right,
            rgba(201,162,39,0) 0%, rgba(201,162,39,0.5) 45%, var(--clr-brand-secondary, var(--gold-600)) 100%);
    background-repeat: no-repeat, no-repeat;
    background-size: 100% 10px, 100% 1.5px;
    background-position: 0 0, 0 center;
    opacity: 0.34;
    transition: opacity 0.45s var(--ease-expo), filter 0.45s var(--ease-expo);
}

/* حلقة الضوء عند الدفع */
.modal-close::after {
    content: '';
    position: absolute;
    inset: -2px;
    border-radius: 50%;
    border: 1.5px solid var(--clr-brand-secondary, var(--gold-600));
    opacity: 0;
    pointer-events: none;
}

.modal-close:hover {
    border-color: var(--clr-brand-secondary, var(--gold-600));
    color: var(--gold-300);
    box-shadow:
        inset 0 -4px 9px rgba(0,0,0,0.55),
        inset 0 2px 3px rgba(255,255,255,0.14),
        0 0 0 5px rgba(201,162,39,0.10),
        0 0 28px rgba(201,162,39,0.5);
}
.modal-close:hover::before { opacity: 0.95; filter: drop-shadow(0 0 6px rgba(201,162,39,0.7)); }

.modal-close:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px rgba(201,162,39,0.55), 0 5px 16px rgba(0,0,0,0.5);
}

/* الدفع: تميل الخرزة على الخيط وترتد، وتنطلق حلقة، وتلمع المجاورة */
.modal-close.pushed            { animation: beadPush 0.55s var(--ease-back); }
.modal-close.pushed::after     { animation: beadRipple 0.75s var(--ease-expo) forwards; }
.modal-close.pushed::before    { opacity: 1; filter: drop-shadow(0 0 10px rgba(201,162,39,0.95)); }

@keyframes beadPush {
    0%   { transform: translateX(0) rotate(0); }
    45%  { transform: translateX(-9px) rotate(-14deg) scale(0.94); }
    100% { transform: translateX(0) rotate(0) scale(1); }
}
@keyframes beadRipple {
    0%   { opacity: 0.85; transform: scale(0.75); }
    100% { opacity: 0;    transform: scale(2.1); }
}

@media (prefers-reduced-motion: reduce) {
    .modal-close, .modal-close::before, .modal-close::after {
        transition-duration: 0.01ms !important;
        animation: none !important;
    }
}


/* --- CSS Animations --- */
@keyframes slideUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

@keyframes fadeIn {
    from {
        opacity: 0;
    }
    to {
        opacity: 1;
    }
}

@keyframes pulseArrow {
    0%, 100% {
        transform: translateY(0);
    }
    50% {
        transform: translateY(4px);
    }
}

/* --- Responsive Media Queries --- */

/* Responsive Navbar and Layout under 768px (Tablet / Mobile) */
@media (max-width: 860px) {
    .header {
        top: 0;
        width: 100%;
    }

    /* Under 768px the misbaha art hides and a compact text bar + drawer show
       (see .sura-mbar / .sura-drawer above). */

    /* Adjust Hero Title size */
    .hero-title {
        line-height: 1.15;
    }
    
    .hero-buttons {
        flex-direction: column;
        gap: 1rem;
        width: 100%;
        max-width: 320px;
    }
    
    .btn-primary, .btn-secondary {
        width: 100%;
        text-align: center;
        justify-content: center;
    }
    
    .btn-secondary::after {
        display: none; /* remove hover line when in blocks */
    }
}

/* Adjust Customizer positions for smaller mobiles */
@media (max-width: 480px) {
    .customizer-widget {
        bottom: 1rem;
        right: 1rem;
    }
    
    .customizer-panel {
        width: 290px;
        right: -0.5rem;
    }
}

.hidden {
    display: none !important;
}

/* --- Second Page (Contemplative screen) --- */
/* --- Second Page (Contemplative screen & Premium Games Hub) --- */
.second-page {
    min-height: 100vh;
    width: 100%;
    position: relative;
    z-index: 1;
    /* top space scales with the floating controller navbar so the section
       header always clears it (the bar's visual bottom ≈ 18.3vw, capped). */
    padding: clamp(5.5rem, 21vw, 10.5rem) 2rem 4rem 2rem;
    /* top-align: this content is taller than the viewport, so centering would
       pull the header up under the navbar and cancel the padding. */
    justify-content: flex-start;
    overflow-y: auto;
}

/* Page-specific background video opacity rules for second.html */
.second-page-body .video-container .video-main.loaded {
    opacity: 0.6 !important;
}

.second-page-body .video-container .video-ambient.loaded {
    opacity: 0.27 !important; /* soft, matching ambient level */
}

/* --- Premium Games Hub Styling --- */
.games-container {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 3rem;
}

/* Games Section Header */
.games-header {
    text-align: center;
    max-width: 700px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
    z-index: 10;
}

.games-subtitle {
    font-size: var(--fs-md);
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.15em;
    color: var(--clr-brand-primary);
    filter: drop-shadow(0 2px 4px rgba(198, 154, 74, 0.3));
    animation: fadeIn 1s ease-out;
}

.games-title {
    font-size: var(--fs-hero);
    font-weight: 800;
    line-height: 1.15;
    color: var(--clr-text-main);
    animation: slideUp 0.8s var(--ease-expo) forwards;
}

.games-desc {
    font-size: var(--fs-lg);
    color: var(--clr-text-muted);
    line-height: 1.6;
    animation: slideUp 1s var(--ease-expo) 0.1s forwards;
}

/* Category Filter Pills */
.filters-container {
    display: flex;
    justify-content: center;
    gap: 1rem;
    flex-wrap: wrap;
    z-index: 10;
    animation: slideUp 1s var(--ease-expo) 0.2s forwards;
}

.filter-pill {
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid var(--glass-border);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    color: var(--clr-text-muted);
    padding: 0.65rem 1.6rem;
    font-size: var(--fs-md);
    font-weight: 500;
    border-radius: var(--r-full);
    cursor: pointer;
    transition: var(--transition-smooth);
}

.filter-pill:hover {
    border-color: var(--glass-border-hover);
    color: var(--clr-text-main);
    transform: translateY(-1px);
}

.filter-pill.active {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    font-weight: 600;
    border-color: transparent;
    box-shadow: 0 4px 15px rgba(198, 154, 74, 0.25);
}

/* Games Grid */
.games-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    gap: 2.2rem;
    width: 100%;
}

/* Game Card Base with entry slide */
.game-card {
    position: relative;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--r-lg);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    transition: 
        transform 0.5s var(--ease-expo),
        border-color 0.4s ease-out,
        box-shadow 0.4s ease-out,
        opacity 0.4s ease-out;
    cursor: pointer;
    box-shadow: var(--glass-shadow);
    will-change: transform;
    /* Resting state is the FINAL state: visible and untransformed.
       It used to be the HIDDEN state (opacity:0 + translateY) with the entrance
       filling `forwards`, which caused two problems:
         1. A CSS animation outranks author-normal declarations in the cascade, and
            `forwards` keeps applying its final frame for the life of the page — so
            the animation's own `transform: translateY(0)` permanently beat the
            `.game-card:hover` lift below. The shadow changed on hover; the card
            never actually rose. That hover has been dead for as long as it existed.
         2. Defaulting to invisible means any failure to run the animation leaves
            the cards blank — the same class of bug documented for the hero above.
       Now the entrance runs with `backwards` instead: the card is pinned to the
       `from` frame during its stagger delay, then RELEASES the animated properties
       when it finishes, handing transform back to :hover. */
    opacity: 1;
    transform: none;
}
/* fires fresh every time the section is shown, because the selector only starts
   matching when app.js adds .active — reliable across the display:none swap. */
.scroll-section.active .game-card {
    animation: cardsSlideUp 0.8s var(--ease-expo) var(--delay) backwards;
}

@keyframes cardsSlideUp {
    from {
        opacity: 0;
        transform: translateY(30px);
    }
}

/* ---- حين يتولّى GSAP -------------------------------------------------------
   `html.gsap-cards` تكتبها src/core/cards.mjs عند تحميلها. القاعدتان هنا هما كل
   ما تتنازل عنه CSS، ولا شيء غيرهما:

   ١. الدخول أعلاه يُلغى — لأن GSAP يشتغل بدلًا منه، ولأنه كان يحرّك `opacity`
      على حفيد `.scroll-section`، وهو تحديدًا نمط خلل iOS الموثّق في السطر ١١٨.
      حركة GSAP بالتحويل وحده، فذهب الخطر معه.
   ٢. `transition: transform` يُحذف — GSAP يكتب `transform` سطريًّا كل إطار،
      والانتقال فوقه يجعل كل إطار يطارد الذي قبله فتُرى الحركة ممسوحة لا حادّة.

   وما عدا ذلك يبقى لـCSS: الحدّ، والظلّ، والأقواس، وكل :hover ليس تحويلًا —
   لأن تلك يجب أن تكون فوريّة، وتمريرها عبر JS يضيف إطارًا إلى أكثر تفاعل
   يشعر به المستخدم. و`.game-card:hover { transform }` أدناه لا يُحذف: أسلوب
   GSAP السطري يتفوّق عليه تلقائيًّا، ويبقى هو احتياطًا لو لم يُحمّل JS. */
html.gsap-cards .scroll-section.active .game-card { animation: none; }
html.gsap-cards .game-card {
    transition:
        border-color 0.4s ease-out,
        box-shadow 0.4s ease-out;
}

/* no entrance travel when the visitor asked for less motion — the resting state
   is already the final one, so simply dropping the animation is correct here. */
@media (prefers-reduced-motion: reduce) {
    .scroll-section.active .game-card { animation: none; }
}

/* 3D card tilt & Golden brackets hover effects.
   The box-shadow here is the refined pass that used to live in a SECOND
   `.game-card:hover` block near the end of the file; being later it silently
   overrode this rule's shadow while leaving its transform, so the two had to be
   read together to know what a hover actually looked like. Merged into one. */
.game-card:hover {
    transform: translateY(-8px) scale(1.02);
    border-color: rgba(198, 154, 74, 0.25);
    box-shadow:
        0 22px 50px rgba(0, 0, 0, 0.45),
        0 0 28px rgba(198, 154, 74, 0.10);
}

/* Camera focus brackets */
.bracket {
    position: absolute;
    width: 12px;
    height: 12px;
    border-color: rgba(255, 255, 255, 0.15);
    border-style: solid;
    transition: var(--transition-smooth);
    pointer-events: none;
}

.bracket.top-left { top: 12px; left: 12px; border-width: 1.5px 0 0 1.5px; }
.bracket.top-right { top: 12px; right: 12px; border-width: 1.5px 1.5px 0 0; }
.bracket.bottom-left { bottom: 12px; left: 12px; border-width: 0 0 1.5px 1.5px; }
.bracket.bottom-right { bottom: 12px; right: 12px; border-width: 0 1.5px 1.5px 0; }

.game-card:hover .bracket {
    border-color: var(--clr-brand-secondary);
}
.game-card:hover .bracket.top-left { transform: translate(-3px, -3px); }
.game-card:hover .bracket.top-right { transform: translate(3px, -3px); }
.game-card:hover .bracket.bottom-left { transform: translate(-3px, 3px); }
.game-card:hover .bracket.bottom-right { transform: translate(3px, 3px); }

/* Card Headers & Footers info */
.card-header-info {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: var(--fs-2xs);
    font-weight: 500;
    color: var(--clr-text-muted);
    opacity: 0.7;
    letter-spacing: 0.1em;
}

.live-badge {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    padding: 0.2rem 0.6rem;
    border-radius: var(--r-xs);
    font-weight: bold;
    font-size: var(--fs-3xs);
    letter-spacing: 0;
    animation: pulseGlow 2s infinite;
}

@keyframes pulseGlow {
    0%, 100% { box-shadow: 0 0 5px rgba(198, 154, 74, 0.4); opacity: 0.9; }
    50% { box-shadow: 0 0 15px rgba(198, 154, 74, 0.8); opacity: 1; }
}

.card-footer-info {
    font-size: var(--fs-2xs);
    font-weight: 600;
    color: var(--clr-text-muted);
    opacity: 0.5;
    letter-spacing: 0.05em;
    text-transform: uppercase;
}

/* Inner board illustration container */
/* لوحةُ البطاقة حاويةُ استعلام: مقاساتُ ما بداخلها تُشتقّ من عرضها بـ`cqw`
   لا بالبكسل. الرسومُ كانت مقيسةً بالبكسل الثابت (خانةُ كَلِمة ٢٦px، خليّةُ
   النحلة ٣٢×٣٦ داخل صندوقٍ ١٢٠×١٠٠)، فبقيت صغيرةً مهما اتّسعت البطاقة —
   ثلاثُ لوحاتٍ من ستٍّ تسبح في فراغٍ أسود بينما تمتلئ الأخريان، فتُقرأ
   الشبكةُ ناقصةً لا طقمًا مصمَّمًا. */
.board-container {
    aspect-ratio: 16 / 11;
    container-type: inline-size;
    width: 100%;
    border-radius: var(--r-sm);
    overflow: hidden;
    position: relative;
    box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.25);
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255, 255, 255, 0.03);
    transition: var(--transition-smooth);
}

.game-card:hover .board-container {
    box-shadow: inset 0 2px 12px rgba(0, 0, 0, 0.4);
}

/* Materials & Textures Branding rules */
.texture-linen {
    background: radial-gradient(circle at center, #faf8f5 0%, #ede8de 100%);
    color: var(--surface-3);
}
.texture-paper {
    background: radial-gradient(circle at center, var(--ink-0) 0%, var(--ink-2) 100%);
    color: var(--surface-1);
}
.texture-palm {
    background: radial-gradient(circle at center, #111d13 0%, #060b07 100%);
    color: var(--ink-2);
}
.texture-sadu {
    background: radial-gradient(circle at center, #221412 0%, #0c0605 100%);
}
.texture-glazed {
    background: radial-gradient(circle at center, #2e0835 0%, #110214 100%);
}
.texture-basalt {
    background: radial-gradient(circle at center, var(--surface-2) 0%, #090c12 100%);
}
.texture-wax {
    background: radial-gradient(circle at center, #1f160f 0%, #0c0805 100%);
}
.texture-wool {
    background: radial-gradient(circle at center, #f1f1f5 0%, #d8d8e3 100%);
    color: var(--surface-3);
}
.texture-leather {
    background: radial-gradient(circle at center, #2b1d16 0%, #120b08 100%);
}
.texture-brass {
    background: radial-gradient(circle at center, #201712 0%, #0d0907 100%);
}
.texture-ivory {
    background: radial-gradient(circle at center, var(--ink-1) 0%, #eaeae1 100%);
}
.texture-volcanic {
    background: radial-gradient(circle at center, #0f1115 0%, #050608 100%);
}
/* Ember glows from the bottom, not the centre: قرّبها's whole mechanic is heat
   rising toward the answer, so the material carries the metaphor. */
.texture-ember {
    background: radial-gradient(ellipse at 50% 108%, #6b2410 0%, #2a0f08 45%, #0d0503 100%);
}
/* Frosted glass — لمحة is a glimpse through haze that clears clue by clue. */
.texture-glass {
    background: linear-gradient(160deg, #1c2b3a 0%, #0d151f 55%, var(--surface-0) 100%);
}

/* Vector boards grid elements styles */

/* Crosswords styles (Mini, Midi, Normal) */
.mini-crossword-vector, .midi-crossword-vector, .crossword-vector {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 0.6rem;
    background: rgba(0, 0, 0, 0.05);
    border-radius: var(--r-xs);
    transition: var(--transition-smooth);
}

.game-card:hover .mini-crossword-vector { transform: scale(1.05) rotate(-1deg); }
.game-card:hover .crossword-vector { transform: scale(1.04) rotate(1deg); }

.cross-row {
    display: flex;
    gap: 2px;
}

.cell {
    width: 18px;
    height: 18px;
    background: var(--ink-0);
    border: 0.5px solid rgba(0,0,0,0.15);
    position: relative;
    border-radius: 1px;
}

.cell.black {
    background: var(--surface-1) !important;
}

.cell.num::after {
    content: attr(data-num);
    position: absolute;
    top: 1px;
    right: 1px;
    font-size: 5px;
    font-weight: 700;
    color: #475569;
    line-height: 1;
}

.texture-linen .cell { background: #fafaf7; }
.texture-wool .cell { background: var(--ink-1); }

/* Strands SVG connections */
.strands-vector {
    width: 80%;
    height: 80%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.strands-svg {
    width: 100%;
    height: 100%;
}

.draw-line {
    stroke-dasharray: 400;
    stroke-dashoffset: 400;
    animation: drawPath 4s infinite alternate ease-in-out;
}

@keyframes drawPath {
    to { stroke-dashoffset: 0; }
}

.strands-svg circle {
    transition: fill 0.3s ease;
}
.game-card:hover .strands-svg circle {
    fill: #1a273b;
    filter: drop-shadow(0 0 4px rgba(254, 180, 123, 0.4));
}

/* Sadu Connections layout styles */
.connections-vector {
    display: flex;
    flex-direction: column;
    gap: 4px;
    gap: 2.4cqw;
    width: 86%;
    height: 86%;
    justify-content: center;
}

/* الصفُّ يأخذ حصّةً من الطول (`flex:1`) بدل أن يُملي طولَه من نسبةِ مربّعاته.
   بالمربّعات كانت الصفوفُ الأربعةُ تطلب طولًا يفوق ٩٠٪ المتاحة فيُقصّ الصفُّ
   الأخير في منتصفه — العيبُ الوحيدُ الظاهرُ في اللقطة. و`min-height:0` لازمة
   لأنّ الحدَّ الأدنى الضمنيَّ لعنصر flex هو محتواه، فبدونها لا ينكمش. */
.conn-row {
    display: flex;
    flex: 1;
    min-height: 0;
    gap: 4px;
    gap: 2.4cqw;
    width: 100%;
}

/* الصفُّ صندوقٌ يُحرَّك (`sura-snap` — آليّةُ اللعبة نفسها)، فلا يجوز
   `display:contents` هنا مهما بدا أنظفَ للشبكة: يمحو الصندوقَ فتسقط الحركة. */
.conn-block {
    flex: 1;
    min-width: 0;
    height: 100%;
    border-radius: var(--r-xs);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-4xs);
    font-weight: bold;
    color: var(--clr-text-main);
    box-shadow: 0 1px 3px rgba(0,0,0,0.2);
    transition: var(--transition-smooth);
}

/* كلماتُ تشابك تصل إلى خمسةِ حروف («صحراء»)، والمربّعُ يضيق بها، فالمقاسُ
   يتبع عرضَ اللوحة ويُمنع الالتفاف. */
.conn-block {
    font-size: var(--fs-4xs);
    font-size: 3.6cqw;
    white-space: nowrap;
}

.game-card:hover .conn-block {
    transform: scale(1.05);
}

.conn-block.clr-orange { background: #ab442d; border: 0.5px solid #d45e43; }
.conn-block.clr-green { background: var(--ok-deep); border: 0.5px solid var(--ok-deep); }
.conn-block.clr-amber { background: var(--gold-700); border: 0.5px solid var(--gold-400); }
.conn-block.clr-purple { background: #472652; border: 0.5px solid #6b3e7a; }

/* Glazed Tiles patterns styles */
.tiles-vector {
    width: 80%;
    height: 80%;
}

.tiles-svg {
    width: 100%;
    height: 100%;
    filter: drop-shadow(0 4px 10px rgba(0,0,0,0.3));
}

.tiles-svg polygon {
    transition: var(--transition-smooth);
}

.game-card:hover .tiles-svg polygon {
    filter: saturate(120%) brightness(110%);
}

/* Sudoku basalt styles */
.sudoku-vector {
    width: 85%;
    height: 85%;
    display: flex;
    align-items: center;
    justify-content: center;
}

.sudoku-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 3px;
    width: 90%;
    background: rgba(255,255,255,0.02);
    padding: 3px;
    border-radius: var(--r-xs);
    border: 1px solid rgba(255,255,255,0.08);
}

.s-cell {
    aspect-ratio: 1;
    background: rgba(255,255,255,0.04);
    border-radius: 2px;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-2xs);
    font-weight: 500;
    color: rgba(255,255,255,0.3);
    transition: var(--transition-smooth);
}

.s-cell.bold {
    color: var(--clr-text-main);
    font-weight: 700;
}

.s-cell.active {
    background: rgba(198, 154, 74, 0.15);
    border: 0.5px solid var(--clr-brand-primary);
    color: var(--clr-brand-secondary);
    font-weight: 700;
    box-shadow: 0 0 8px rgba(198, 154, 74, 0.2);
}

.game-card:hover .s-cell.active {
    transform: scale(1.08);
}

/* Spelling bee honeycomb structure */
.bee-vector {
    width: 90%;
    height: 90%;
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative;
}

/* الخليّةُ كانت ١٢٠×١٠٠ بكسلًا ثابتة. النِّسبةُ نفسها (٦:٥) محفوظةٌ هنا حتى
   لا ينضغط السداسيّ، والمواضع أدناه حُوّلت من البكسل إلى نسبةٍ من الصندوق
   بالقسمة على ١٢٠ عرضًا و١٠٠ طولًا — فالشكلُ هو الشكلُ، والحجمُ وحده تغيّر. */
.honeycomb {
    position: relative;
    width: 68%;
    aspect-ratio: 6 / 5;
}

.hex {
    position: absolute;
    width: 26.67%;
    height: 36%;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.1);
    clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: var(--transition-smooth);
}

.hex span {
    font-size: var(--fs-2xs);
    font-size: 4.8cqw;
    font-weight: bold;
    color: var(--clr-text-main);
}

.hex.center {
    background: rgba(255, 170, 0, 0.15) !important;
    border: 1px solid #ffaa00 !important;
    box-shadow: 0 0 10px rgba(255, 170, 0, 0.3);
}

.hex.center span {
    color: #ffcc00 !important;
}

.game-card:hover .hex {
    border-color: rgba(255, 170, 0, 0.4);
}

.game-card:hover .hex.center {
    transform: scale(1.1);
}

/* Positioning honeycomb pieces — النِّسبُ هي البكسلاتُ القديمة ÷ ١٢٠ و١٠٠ */
.hex.middle-center { top: 32%; left: 36.67%; }
.hex.top-left { top: 8%; left: 21.67%; }
.hex.top-right { top: 8%; left: 51.67%; }
.hex.middle-left { top: 32%; left: 6.67%; }
.hex.middle-right { top: 32%; left: 66.67%; }
.hex.bottom-left { top: 56%; left: 21.67%; }
.hex.bottom-right { top: 56%; left: 51.67%; }

/* Crossplay matching boards */
.crossplay-vector {
    display: flex;
    align-items: center;
    gap: 1.5rem;
}

.mini-board {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 4px;
    padding: 4px;
    background: rgba(255,255,255,0.02);
    border-radius: var(--r-xs);
    border: 1px solid rgba(255,255,255,0.06);
}

.c-dot {
    width: 16px;
    height: 16px;
    border-radius: 2px;
    background: rgba(255,255,255,0.04);
}

.c-dot.active {
    background: #d45e43;
    border: 0.5px solid #ffa08a;
}

.vs-indicator {
    animation: heartbeat 2s infinite ease-in-out;
}

@keyframes heartbeat {
    0%, 100% { transform: scale(1); opacity: 0.7; }
    50% { transform: scale(1.15); opacity: 1; }
}

/* Letter boxed container */
.letterboxed-vector {
    width: 85%;
    height: 85%;
}

.boxed-svg {
    width: 100%;
    height: 100%;
}

.boxed-svg circle {
    transition: var(--transition-smooth);
}

.game-card:hover .boxed-svg circle {
    fill: #1e1b18;
    stroke: var(--clr-brand-secondary);
}

/* Domino tiles layout */
.pips-vector {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
}

.domino-tile {
    width: 44px;
    height: 24px;
    background: #fafaf5;
    border: 1px solid #d5d5cd;
    border-radius: var(--r-xs);
    display: flex;
    position: relative;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15);
    transition: var(--transition-smooth);
}

.domino-tile.vertical {
    width: 24px;
    height: 44px;
    flex-direction: column;
}

.half-side {
    flex: 1;
    position: relative;
    padding: 3px;
    display: flex;
    align-items: center;
    justify-content: center;
}

.divider {
    background: #d5d5cd;
}

.domino-tile:not(.vertical) .divider {
    width: 1px;
    height: 100%;
}

.domino-tile.vertical .divider {
    height: 1px;
    width: 100%;
}

/* Domino dots patterns */
.dot {
    width: 3.5px;
    height: 3.5px;
    background: #a32a14;
    border-radius: 50%;
    position: absolute;
}

.d-top-left { top: 3px; left: 3px; }
.d-top-right { top: 3px; right: 3px; }
.d-bottom-left { bottom: 3px; left: 3px; }
.d-bottom-right { bottom: 3px; right: 3px; }
.d-center { top: calc(50% - 1.75px); left: calc(50% - 1.75px); }

.game-card:hover .domino-tile {
    transform: scale(1.05) rotate(4deg);
    box-shadow: 0 8px 15px rgba(0,0,0,0.25);
}

/* Wordle illustration vector board */
/* كلُّ سطرٍ بـ`cqw` مسبوقٌ ببديلٍ بالبكسل: المتصفّحُ الذي لا يعرف وحدات
   الحاوية يُسقط الإعلانَ كلَّه لا يتجاهل الوحدةَ وحدها، فتصير الفجوةُ صفرًا
   والخطُّ موروثًا. البديلُ أوّلًا والقيمةُ الحديثةُ بعده تغلبه عند دعمها. */
.wordle-vector {
    display: flex;
    flex-direction: column;
    gap: 4px;
    gap: 2.6cqw;
    width: 62%;
}

.w-row {
    display: flex;
    gap: 4px;
    gap: 2.6cqw;
    width: 100%;
}

/* `flex:1` + `aspect-ratio` بدل المقاس الثابت: الخاناتُ تتقاسم عرضَ الصفّ
   فتكبر مع البطاقة، ويبقى الصفّان في وسط اللوحة بوزنٍ بصريٍّ يماثل «قرّبها»
   و«لمحة» — وهما المعياران لأنّهما وحدهما كانا يملآن صندوقهما. */
.w-letter {
    flex: 1;
    aspect-ratio: 1;
    border-radius: 3px;
    border-radius: 1.4cqw;
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-sm);
    font-size: 6.4cqw;
    font-weight: bold;
    color: var(--clr-text-main);
    box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    transition: var(--transition-smooth);
}

.w-letter.state-correct {
    background: var(--state-correct);
    border: 0.5px solid var(--state-correct-edge);
}

.w-letter.state-present {
    background: var(--state-present);
    border: 0.5px solid var(--state-present-edge);
}

.w-letter.state-absent {
    background: var(--state-absent);
    border: 0.5px solid var(--state-absent-edge);
}

.game-card:hover .w-letter {
    transform: rotateX(360deg);
    transition-duration: 0.8s;
}

/* Active Game Card specific properties */
.active-card {
    border-color: rgba(198, 154, 74, 0.15);
    background: rgba(25, 20, 30, 0.6) !important;
}

.btn-play-now {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    padding: 0.65rem;
    margin-top: 0.5rem;
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    font-weight: 600;
    font-size: var(--fs-sm);
    border: none;
    border-radius: var(--r-sm);
    cursor: pointer;
    box-shadow: 0 4px 10px rgba(198, 154, 74, 0.2);
    transition: var(--transition-smooth);
}

.btn-play-now:hover {
    background: linear-gradient(135deg, var(--clr-brand-secondary), var(--clr-brand-primary));
    transform: translateY(-2px);
    box-shadow: 0 6px 15px rgba(198, 154, 74, 0.45);
}

/* Game Card General Typography */
.game-info {
    display: flex;
    flex-direction: column;
    gap: 0.4rem;
}

.game-english-title {
    font-size: var(--fs-3xs);
    font-weight: 600;
    letter-spacing: 0.15em;
    color: var(--clr-brand-secondary);
    opacity: 0.9;
}

.game-arabic-title {
    font-size: var(--fs-2xl);
    font-weight: 700;
    color: var(--clr-text-main);
}

.game-description {
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
    line-height: 1.4;
}

/* --- Playable Arabic Wordle Lightbox Modal --- */
.wordle-modal-container {
    position: relative;
    width: 90%;
    max-width: 480px;
    background: rgba(15, 23, 42, 0.85);
    backdrop-filter: blur(28px);
    -webkit-backdrop-filter: blur(28px);
    border-radius: var(--r-xl);
    border: 1px solid rgba(255, 255, 255, 0.1);
    box-shadow: 0 25px 60px rgba(0,0,0,0.6), var(--glass-shadow);
    overflow-y: auto;
    overflow-x: hidden;
    max-height: 94vh;
    transform: scale(0.95);
    transition: var(--transition-smooth);
    padding: 2.2rem 1.8rem;
    z-index: 160;
}

.modal-backdrop.active .wordle-modal-container {
    transform: scale(1);
}

.wordle-game-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.5rem;
    width: 100%;
}

.wordle-header {
    text-align: center;
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
}

.wordle-header h2 {
    font-size: var(--fs-4xl);
    font-weight: 800;
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
}

.wordle-header p {
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
}

/* Playable Wordle Board Grid */
.wordle-board {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.board-row {
    display: flex;
    gap: 6px;
}

.board-cell {
    width: 52px;
    height: 52px;
    border: 2px solid rgba(255, 255, 255, 0.15);
    background: rgba(255, 255, 255, 0.02);
    border-radius: var(--r-sm);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: var(--fs-2xl);
    font-weight: bold;
    color: var(--clr-text-main);
    transition: var(--transition-quick);
}

.board-cell.pop {
    transform: scale(1.08);
    border-color: rgba(255, 255, 255, 0.4);
}

.board-cell.correct {
    background: var(--state-correct) !important;
    border-color: var(--state-correct) !important;
    color: white;
}

.board-cell.present {
    background: var(--state-present) !important;
    border-color: var(--state-present) !important;
    color: white;
}

.board-cell.absent {
    background: var(--state-absent) !important;
    border-color: var(--state-absent) !important;
    color: var(--ink-3);
}

/* Wordle Message Toast */
.wordle-message {
    height: 20px;
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--clr-brand-secondary);
    text-align: center;
    opacity: 0;
    transition: opacity 0.3s ease;
}

.wordle-message.visible {
    opacity: 1;
}

/* Arabic Keyboard */
.wordle-keyboard {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
    margin-top: 0.5rem;
}

.kbd-row {
    display: flex;
    justify-content: center;
    gap: 4px;
    width: 100%;
}

.kbd-key {
    background: rgba(255, 255, 255, 0.05);
    border: 1px solid rgba(255, 255, 255, 0.05);
    color: var(--clr-text-main);
    border-radius: var(--r-sm);
    padding: 0.65rem 0.3rem;
    font-size: var(--fs-sm);
    font-weight: bold;
    cursor: pointer;
    flex: 1;
    min-width: 20px;
    text-align: center;
    user-select: none;
    transition: var(--transition-quick);
}

.kbd-key:hover {
    background: rgba(255, 255, 255, 0.15);
    transform: translateY(-1px);
}

.kbd-key.wide {
    flex: 1.8;
}

.kbd-key.correct {
    background: var(--state-correct) !important;
    color: white;
}

.kbd-key.present {
    background: var(--state-present) !important;
    color: white;
}

.kbd-key.absent {
    background: var(--state-absent) !important;
    color: var(--state-absent-edge);
    opacity: 0.6;
}

.wordle-actions {
    display: flex;
    justify-content: center;
    width: 100%;
    margin-top: 0.5rem;
    animation: fadeIn 0.5s ease-out;
}

.wordle-actions .btn-primary {
    width: 100%;
    max-width: 250px;
}

/* Responsive grid layouts adjustments */
@media (max-width: 768px) {
    .games-grid {
        grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
        gap: 1.5rem;
    }
    
    .second-page {
        /* keep the top clearance for the controller navbar on small screens */
        padding: clamp(5.5rem, 21vw, 10.5rem) 1.25rem 3rem 1.25rem;
    }
    
    .board-row {
        gap: 4px;
    }
    
    .board-cell {
        width: 44px;
        height: 44px;
        font-size: var(--fs-xl);
    }
    
    .kbd-key {
        padding: 0.5rem 0.15rem;
        font-size: var(--fs-2xs);
    }
}

/* Shake Animation for Input Errors */
@keyframes shake {
    0%, 100% { transform: translateX(0); }
    15%, 45%, 75% { transform: translateX(-6px); }
    30%, 60%, 90% { transform: translateX(6px); }
}

/* --- Sura Newsletter Page (third.html) Styles --- */
.third-page {
    min-height: 100vh;
    width: 100%;
    position: relative;
    z-index: 1;
    /* match the games page: clear the floating controller navbar */
    padding: clamp(5.5rem, 21vw, 10.5rem) 2rem 4rem 2rem;
    justify-content: flex-start;
    overflow-y: auto;
}

/* Page-specific background video opacity rules for third.html (80% opacity) */
.third-page-body .video-container .video-main.loaded {
    opacity: 0.8 !important;
}

.third-page-body .video-container .video-ambient.loaded {
    opacity: 0.35 !important; /* soft ambient level */
}

/* Page 3 Premium Transparency Overrides (Completely borderless and frameless so only content floats over the video) */
.third-page-body .featured-issue-section,
.third-page-body .leaderboard-card,
.third-page-body .week-card,
.third-page-body .archive-card,
.third-page-body .featured-preview-card {
    background: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    box-shadow: none !important;
}

.third-page-body .bracket {
    display: none !important;
}

/* Container */
.newsletter-container {
    max-width: 1280px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 3.5rem;
}

/* 1. TOP ROW: Split Featured Daily Issue */
.featured-issue-section {
    display: grid;
    grid-template-columns: 1.2fr 0.8fr;
    gap: 3rem;
    align-items: center;
    background: rgba(15, 23, 42, 0.3);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid rgba(255, 255, 255, 0.04);
    border-radius: var(--r-xl);
    padding: 3rem;
    box-shadow: var(--glass-shadow);
}

.featured-content-card {
    display: flex;
    flex-direction: column;
    gap: 1.25rem;
    text-align: right;
}

.issue-tag {
    font-size: var(--fs-md);
    font-weight: 600;
    color: var(--clr-brand-primary);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    filter: drop-shadow(0 2px 4px rgba(198, 154, 74, 0.2));
}

.featured-wordle-title {
    font-size: clamp(3rem, 6vw, 4.8rem);
    font-weight: 800;
    line-height: 1;
    color: var(--clr-text-main);
}

.featured-wordle-tagline {
    font-size: var(--fs-xl);
    font-weight: 500;
    color: var(--clr-brand-secondary);
    font-style: italic;
    line-height: 1.4;
}

.featured-wordle-desc {
    font-size: var(--fs-base);
    color: var(--clr-text-muted);
    line-height: 1.6;
    max-width: 55ch;
}

.featured-buttons {
    display: flex;
    gap: 1.5rem;
    margin-top: 1rem;
}

.btn-inline-icon {
    width: 18px;
    height: 18px;
    fill: currentColor;
}

/* Featured preview card right */
.featured-preview-card {
    position: relative;
    background: rgba(15, 23, 42, 0.5);
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--r-lg);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1rem;
    box-shadow: var(--glass-shadow);
    transform: rotate(2deg);
    transition: var(--transition-smooth);
}

.featured-preview-card:hover {
    transform: rotate(0deg) scale(1.02);
    border-color: rgba(198, 154, 74, 0.25);
    box-shadow: 0 15px 35px rgba(0, 0, 0, 0.35);
}

/* المعاينةُ الكبيرةُ تكبر بنسبة صندوقها لا بمقاسٍ ثابت — و`width`/`height`
   حُذفتا هنا عمدًا: كانتا تسبقان `flex:1` في الأولويّة فتُجمّدان الخانةَ عند
   ٣٦px مهما اتّسعت اللوحة. */
.wordle-vector.large-preview {
    width: 72%;
}

.large-preview .w-letter {
    font-size: var(--fs-xl);
    font-size: 8cqw;
    border-radius: var(--r-xs);
}

/* 2. MIDDLE ROW: Leaderboard & Subscription */
.newsletter-mid-grid {
    display: grid;
    grid-template-columns: 1.1fr 0.9fr;
    gap: 2.5rem;
    align-items: stretch;
}

/* The Leaderboard Card styling */
.leaderboard-card {
    position: relative;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--r-lg);
    padding: 2rem;
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    box-shadow: var(--glass-shadow);
}

.leaderboard-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    flex-wrap: wrap;
    gap: 1.2rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
    padding-bottom: 1.2rem;
}

.leaderboard-title-group {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}

.leaderboard-title-group h3 {
    font-size: var(--fs-3xl);
    font-weight: 700;
    color: var(--clr-text-main);
}

/* Leaderboard search wrapper */
.search-wrapper {
    position: relative;
    max-width: 220px;
    width: 100%;
}

#leaderboard-search {
    width: 100%;
    background: rgba(255, 255, 255, 0.03);
    border: 1px solid rgba(255, 255, 255, 0.08);
    border-radius: var(--r-full);
    padding: 0.5rem 1rem 0.5rem 2.2rem;
    color: var(--clr-text-main);
    font-size: var(--fs-sm);
    outline: none;
    transition: var(--transition-quick);
}

#leaderboard-search:focus {
    border-color: var(--clr-brand-primary);
    background: rgba(255, 255, 255, 0.06);
    box-shadow: 0 0 10px rgba(198, 154, 74, 0.15);
}

.search-icon {
    position: absolute;
    left: 0.85rem;
    top: 50%;
    transform: translateY(-50%);
    width: 16px;
    height: 16px;
    fill: var(--clr-text-muted);
    opacity: 0.6;
    pointer-events: none;
}

/* Leaderboard Table Styles */
/* Board-mode toggle (عام / يومي) + per-game selector */
.leaderboard-modes {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin: 0.2rem 0 1.1rem;
    flex-wrap: wrap;
}
.lb-mode-toggle {
    display: inline-flex;
    padding: 3px;
    border-radius: var(--r-full);
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.08);
}
.lb-mode-btn {
    appearance: none;
    border: 0;
    background: transparent;
    color: var(--clr-text-muted);
    font-family: inherit;
    font-size: var(--fs-xs);
    font-weight: 600;
    padding: 0.36rem 1.05rem;
    border-radius: var(--r-full);
    cursor: pointer;
    transition: var(--transition-quick);
}
.lb-mode-btn:hover { color: var(--clr-text, #f4ead6); }
.lb-mode-btn.active {
    background: linear-gradient(135deg, var(--gold-500), var(--gold-700));
    color: var(--gold-900);
    box-shadow: 0 2px 10px rgba(209,145,60,0.28);
}
.lb-game-select {
    appearance: none;
    font-family: inherit;
    font-size: var(--fs-xs);
    color: var(--clr-text, #f4ead6);
    background: rgba(255,255,255,0.04);
    border: 1px solid rgba(255,255,255,0.10);
    border-radius: var(--r-full);
    padding: 0.36rem 1rem;
    cursor: pointer;
}
.lb-game-select[hidden] { display: none; }
.lb-game-select option { color: var(--gold-900); }

.leaderboard-body {
    overflow-x: auto;
}

.leaderboard-table {
    width: 100%;
    border-collapse: collapse;
    text-align: right;
}

.leaderboard-table th {
    font-size: var(--fs-xs);
    font-weight: 600;
    color: var(--clr-text-muted);
    opacity: 0.6;
    text-transform: uppercase;
    padding-bottom: 0.85rem;
    border-bottom: 1px solid rgba(255,255,255,0.06);
}

.leaderboard-table td {
    padding: 0.9rem 0.5rem;
    font-size: var(--fs-md);
    border-bottom: 1px solid rgba(255,255,255,0.03);
    transition: var(--transition-quick);
}

.leaderboard-table tr {
    transition: var(--transition-quick);
}

.leaderboard-table tbody tr:hover td {
    background: rgba(255, 255, 255, 0.02);
    color: var(--ink-0);
}

.leaderboard-table tr.highlighted td {
    background: rgba(198, 154, 74, 0.08) !important;
    border-color: rgba(198, 154, 74, 0.25) !important;
    color: var(--clr-brand-secondary) !important;
    font-weight: bold;
}

.rank-col { width: 12%; text-align: center; }
.name-col { width: 48%; }

/* رتبة اللاعب — شارةٌ هادئة بجانب الاسم. تحلّ محلّ أيقونات الميداليات التي
   كانت تُقرأ مركزًا لا رتبة (شرح كامل عند `TIER_NAME` في main.js). لا لونَ
   ذهبيًّا هنا: الذهب لعمود المركز وحده، وإلا عاد الالتباس بلونٍ بدل رمز. */
.lb-empty {
    padding: 1.1em 0.6em;
    text-align: center;
    color: var(--ink-2, #9aa4b2);
    font-size: 0.86em;
}

.tier-chip {
    display: inline-block;
    margin-inline-start: 0.5em;
    padding: 0.1em 0.5em;
    border: 1px solid color-mix(in srgb, var(--ink-2, #9aa4b2) 34%, transparent);
    border-radius: 999px;
    font-size: 0.72em;
    font-weight: 400;
    color: var(--ink-2, #9aa4b2);
    vertical-align: middle;
    white-space: nowrap;
}
.time-col { width: 22%; font-family: monospace; font-size: var(--fs-base) !important; }
.score-col { width: 18%; font-weight: bold; }

/* Custom top ranks styling */
.top-rank td {
    font-size: var(--fs-base);
}

.bold-name {
    font-weight: 600;
    color: var(--clr-text-main);
}

.rank-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.35rem;
    font-weight: 700;
    font-size: var(--fs-sm);
    border-radius: var(--r-full);
    padding: 0.2rem 0.6rem;
    box-shadow: 0 2px 5px rgba(0,0,0,0.15);
}

.rank-badge.gold {
    background: rgba(255, 215, 0, 0.12);
    border: 0.5px solid var(--gold-200);
    color: var(--gold-200);
}

.rank-badge.silver {
    background: rgba(192, 192, 192, 0.12);
    border: 0.5px solid #c0c0c0;
    color: var(--ink-2);
}

.rank-badge.bronze {
    background: rgba(205, 127, 50, 0.12);
    border: 0.5px solid #cd7f32;
    color: #fca5a5;
}

.rank-icon-svg {
    width: 12px;
    height: 12px;
    fill: currentColor;
}

.gold-txt { color: var(--gold-200); }
.silver-txt { color: var(--ink-2); }
.bronze-txt { color: #fca5a5; }

/* ──────────────────────────────────────────────────────────────────
   رزنامة الأسبوع — بديل «مراسلات الفجر» (المالك، ١٢ أغسطس ٢٠٢٦)
   بطاقةُ اشتراكٍ بريديٍّ كانت مسرحًا: تختم ختمًا من الشمع ولا ترسل
   شيئًا إلى أحد. مكانها الآن جدولٌ يقول الحقيقة — أي صعوبةٍ في أي
   يوم، وبأي عدد — وهي المعلومة الوحيدة التي تجعل الزائر يعود غدًا.
   ─────────────────────────────────────────────────────────────────── */
.week-card {
    position: relative;
    background: rgba(15, 23, 42, 0.45);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid rgba(255, 255, 255, 0.05);
    border-radius: var(--r-lg);
    padding: 2.2rem;
    box-shadow: var(--glass-shadow);
    display: flex;
    flex-direction: column;
    gap: 1.35rem;
    min-height: 320px;
    text-align: right;
}

.week-head {
    display: flex;
    flex-direction: column;
    gap: 0.45rem;
}

.week-head h3 {
    font-size: var(--fs-2xl);
    font-weight: 800;
    color: var(--clr-text-main);
    line-height: 1.2;
}

.week-desc {
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
    line-height: 1.6;
    max-width: 44ch;
}

.week-table {
    width: 100%;
    border-collapse: collapse;
    font-size: var(--fs-sm);
}

.week-table thead th {
    padding: 0 0.4rem 0.55rem;
    font-size: var(--fs-xs);
    font-weight: 600;
    letter-spacing: normal;
    color: var(--clr-text-muted);
    opacity: 0.7;
    text-align: right;
    border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}

.week-table .wk-issue-col,
.week-table .wk-tier-col { text-align: center; }

.week-table td {
    padding: 0.52rem 0.4rem;
    border-bottom: 1px solid rgba(255, 255, 255, 0.04);
    color: var(--clr-text-muted);
    vertical-align: middle;
}

.week-table tr:last-child td { border-bottom: none; }

.wk-day {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    white-space: nowrap;
}

/* النقطة تحمل حالة اليوم بلونها وحده، فتُقرأ الرزنامة بلمحةٍ واحدة:
   ذهبيّةٌ ممتلئة = اليوم، باهتةٌ = مضى، مجوّفةٌ = لم يأتِ بعد. */
.wk-dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    flex: 0 0 auto;
    background: rgba(255, 255, 255, 0.18);
}

.wk-issue {
    text-align: center;
    font-variant-numeric: tabular-nums;
    opacity: 0.75;
}

.wk-tier { text-align: center; }

.wk-now {
    font-size: var(--fs-xs);
    font-weight: 700;
    color: var(--clr-text-dark);
    background: linear-gradient(135deg, var(--gold-300), var(--gold-500));
    border-radius: var(--r-full);
    padding: 0.06rem 0.5rem;
}

.week-row.past { opacity: 0.45; }

.week-row.past .wk-dot { background: rgba(255, 255, 255, 0.1); }

.week-row.next .wk-dot {
    background: transparent;
    box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}

.week-row.today td {
    background: linear-gradient(90deg, rgba(198, 154, 74, 0.14), rgba(198, 154, 74, 0));
    color: var(--clr-text-main);
}

.week-row.today .wk-day {
    font-weight: 700;
    color: var(--gold-200);
}

.week-row.today .wk-dot {
    background: var(--gold-300);
    box-shadow: 0 0 8px rgba(198, 154, 74, 0.8);
}

.week-row.today td:first-child {
    border-radius: 0 var(--r-sm) var(--r-sm) 0;
    box-shadow: inset -2px 0 0 0 var(--gold-400);
}

.week-foot {
    font-size: var(--fs-xs);
    color: var(--clr-text-muted);
    opacity: 0.65;
    line-height: 1.6;
    margin-top: auto;
}

/* ──────────────────────────────────────────────────────────────────
   شرائح «ألعاب اليوم» في بطاقة العدد
   ─────────────────────────────────────────────────────────────────── */
.daily-roster {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 0.2rem;
}

.dr-chip {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 0.18rem;
    position: relative;
    padding: 0.5rem 0.75rem;
    border: 1px solid rgba(255, 255, 255, 0.09);
    border-radius: var(--r-md);
    background: rgba(255, 255, 255, 0.035);
    color: var(--clr-text-main);
    font-family: inherit;
    font-size: var(--fs-sm);
    text-align: right;
    cursor: pointer;
    transition: transform 220ms var(--ease-expo), border-color 220ms ease, background 220ms ease;
}

.dr-chip:hover,
.dr-chip:focus-visible {
    transform: translateY(-2px);
    border-color: rgba(198, 154, 74, 0.45);
    background: rgba(198, 154, 74, 0.09);
}

.dr-chip.feat {
    border-color: rgba(198, 154, 74, 0.4);
    background: rgba(198, 154, 74, 0.07);
}

.dr-name { font-weight: 700; line-height: 1.2; }

.dr-meta {
    display: flex;
    align-items: center;
    gap: 0.38rem;
    font-size: var(--fs-xs);
    color: var(--clr-text-muted);
}

.dr-lv { font-variant-numeric: tabular-nums; }

/* لوحُ الصعوبة الواحد يخدم الشريحة والجدول معًا، فلا يفترق لونُ «صعب»
   في مكانين. */
.dr-tier {
    display: inline-block;
    padding: 0.05rem 0.45rem;
    border-radius: var(--r-full);
    font-size: var(--fs-xs);
    font-weight: 600;
    border: 1px solid currentColor;
    line-height: 1.5;
}

.dr-tier.t-easy    { color: #86c8a8; }
.dr-tier.t-medium  { color: var(--gold-200); }
.dr-tier.t-hard    { color: #e0a06a; }
.dr-tier.t-hardest { color: #e07a7a; }

.dr-tick {
    position: absolute;
    inset-inline-start: 0.5rem;
    top: 0.4rem;
    font-size: var(--fs-xs);
    color: #86c8a8;
}

.dr-chip.done {
    border-color: rgba(134, 200, 168, 0.35);
    background: rgba(134, 200, 168, 0.07);
}

.dr-chip.done .dr-name { opacity: 0.75; }

html[data-theme="light"] .week-card {
    background: rgba(255, 255, 255, 0.6);
    border-color: rgba(28, 25, 23, 0.1);
}

html[data-theme="light"] .week-table thead th { border-bottom-color: rgba(28, 25, 23, 0.14); }
html[data-theme="light"] .week-table td { border-bottom-color: rgba(28, 25, 23, 0.07); }
html[data-theme="light"] .wk-dot { background: rgba(28, 25, 23, 0.2); }
html[data-theme="light"] .week-row.next .wk-dot { box-shadow: inset 0 0 0 1px rgba(28, 25, 23, 0.3); }
html[data-theme="light"] .week-row.today .wk-day { color: var(--gold-800); }

html[data-theme="light"] .dr-chip {
    border-color: rgba(28, 25, 23, 0.14);
    background: rgba(28, 25, 23, 0.03);
}

html[data-theme="light"] .dr-tier.t-easy    { color: #2e7d5b; }
html[data-theme="light"] .dr-tier.t-medium  { color: var(--gold-800); }
html[data-theme="light"] .dr-tier.t-hard    { color: #a35c1e; }
html[data-theme="light"] .dr-tier.t-hardest { color: #a12a2a; }
html[data-theme="light"] .dr-tick           { color: #2e7d5b; }

@media (prefers-reduced-motion: reduce) {
    .dr-chip { transition: none; }
    .dr-chip:hover,
    .dr-chip:focus-visible { transform: none; }
}

/* 3. BOTTOM ROW: Archives */
.archives-section {
    display: flex;
    flex-direction: column;
    gap: 2.2rem;
    margin-top: 1rem;
}

.archives-header {
    text-align: center;
    max-width: 600px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.archive-main-title {
    font-size: var(--fs-5xl);
    font-weight: 800;
    color: var(--clr-text-main);
}

.archive-main-desc {
    font-size: var(--fs-base);
    color: var(--clr-text-muted);
    line-height: 1.5;
}

.archives-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
    gap: 2.2rem;
    width: 100%;
}

.archive-card {
    position: relative;
    background: rgba(15, 23, 42, 0.4);
    backdrop-filter: blur(var(--glass-blur));
    -webkit-backdrop-filter: blur(var(--glass-blur));
    border: 1px solid rgba(255, 255, 255, 0.04);
    border-radius: var(--r-lg);
    padding: 1.5rem;
    display: flex;
    flex-direction: column;
    gap: 1.2rem;
    box-shadow: var(--glass-shadow);
    cursor: pointer;
    transition: var(--transition-smooth);
    opacity: 0;
    transform: translateY(30px);
    animation: cardsSlideUp 0.8s var(--ease-expo) var(--delay) forwards;
}

.archive-card:hover {
    transform: translateY(-6px) scale(1.01);
    border-color: rgba(198, 154, 74, 0.2);
    box-shadow: 0 15px 35px rgba(0,0,0,0.35);
}

.archive-cover-num {
    font-size: 3rem;
    font-weight: 800;
    color: rgba(0,0,0,0.15);
    transition: var(--transition-smooth);
}

.texture-basalt .archive-cover-num {
    color: rgba(255,255,255,0.06);
}

.archive-card:hover .archive-cover-num {
    transform: scale(1.15) rotate(-5deg);
    color: rgba(198, 154, 74, 0.15);
}

.archive-info {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    text-align: right;
}

.archive-info h3 {
    font-size: var(--fs-xl);
    font-weight: 700;
    color: var(--clr-text-main);
}

.archive-info p {
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
    line-height: 1.45;
}

/* Tablet & Mobile styles overrides for Page 3 */
@media (max-width: 990px) {
    .featured-issue-section {
        grid-template-columns: 1fr;
        padding: 2rem;
        gap: 2.2rem;
    }
    
    .featured-content-card {
        order: 2;
    }
    
    .featured-preview-card {
        order: 1;
        max-width: 400px;
        margin: 0 auto;
    }
    
    .newsletter-mid-grid {
        grid-template-columns: 1fr;
        gap: 2rem;
    }
}

@media (max-width: 580px) {
    .featured-buttons {
        flex-direction: column;
        gap: 1rem;
    }
    
    .featured-buttons button {
        width: 100%;
        justify-content: center;
    }
    
    .leaderboard-header {
        flex-direction: column;
        align-items: stretch;
    }
    
    .search-wrapper {
        max-width: 100%;
    }
    
    .week-card { padding: 1.5rem; }
    .week-table { font-size: var(--fs-xs); }
    .dr-chip { flex: 1 1 auto; }
}

/* Premium Cover Image Styles for Past Archives */
.archive-cover-img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.6s var(--ease-expo) !important;
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
}

.archive-card:hover .archive-cover-img {
    transform: scale(1.08) rotate(1deg) !important;
}

/* Float cover numbers elegantly above the images */
.board-container .archive-cover-num {
    position: absolute;
    bottom: 1rem;
    left: 1.25rem;
    z-index: 10;
    font-size: var(--fs-6xl);
    font-weight: 800;
    color: rgba(255, 255, 255, 0.25) !important;
    text-shadow: 0 4px 10px rgba(0,0,0,0.3);
    transition: var(--transition-smooth);
}

.archive-card:hover .board-container .archive-cover-num {
    transform: translateY(-3px) scale(1.05);
    color: var(--clr-brand-secondary) !important;
    text-shadow: 0 4px 15px rgba(198, 154, 74, 0.4);
}

/* --- Cinematic Lens Defocus & Golden Light-Leak Transition --- */

/* 1. Deep Defocus / Bokeh on Background video main and ambient containers */
.video-container .video-main,
.video-container .video-ambient {
    transition: opacity 1.5s ease-in-out, filter 0.8s var(--ease-soft), transform 0.8s var(--ease-soft) !important;
}

.video-container.defocus .video-main,
.video-container.defocus .video-ambient {
    filter: blur(35px) saturate(145%) brightness(0.9) !important;
    transform: translate(-50%, -50%) scale(1.06) !important;
}

/* 2. Lightweight warm gold light leak flare */
.light-leak-flare {
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    height: 100dvh;
    z-index: 105; /* floats above the video overlay, below the content cards */
    pointer-events: none;
    opacity: 0;
    background: radial-gradient(circle at 60% 40%, rgba(209, 145, 60, 0.22) 0%, rgba(198, 154, 74, 0.12) 35%, transparent 70%);
    transition: opacity 0.8s var(--ease-soft);
    mix-blend-mode: screen;
    will-change: opacity;
}

.light-leak-flare.active {
    opacity: 1;
}

/* ============================================================
   New playable games (Connections, Sudoku, Spelling Bee)
   Shares the existing Wordle modal shell + design tokens.
   ============================================================ */

/* Shared: slightly wider container + scroll for richer boards */
.game-modal-container {
    max-width: 520px;
    max-height: 92vh;
    overflow-y: auto;
}

/* ── Games go full-bleed on phones ──────────────────────────────────────
   A 520px card floating over the live home page meant most of a phone
   screen was still the page behind: taps meant for the board landed on
   the backdrop and dismissed the round. Below 768px the game IS the
   screen — no gap to mis-tap, no page peeking through.
   dvh, not vh: vh ignores the mobile URL bar and the board's last row
   ends up under it.
   ───────────────────────────────────────────────────────────────────── */
@media (max-width: 768px) {
    .modal-backdrop.active .game-modal-container,
    .modal-backdrop.active .wordle-modal-container {
        width: 100%;
        max-width: none;
        height: 100dvh;
        max-height: 100dvh;
        border-radius: 0;
        border: 0;
        margin: 0;
        padding: 1.25rem 1rem calc(1.25rem + env(safe-area-inset-bottom));
        /* the scale-in reads as a jitter at full bleed */
        transform: none;
    }
    .modal-backdrop .game-modal-container,
    .modal-backdrop .wordle-modal-container { transform: none; }

    /* THE KEYBOARD MUST NEVER LEAVE THE SCREEN.
       The container is exactly 100dvh, but the wrapper's content is intrinsic —
       header + board + message + keyboard measured 754px tall. On a 780px test
       viewport that fits and everything looked fine; on a real iPhone, where
       Safari's URL bar leaves ~660px, the keyboard's bottom landed 94px BELOW
       the fold. The shell scrolls, so it was reachable — but a player sees a
       board and no keys and concludes the game is broken («ما يفتح الكيبورد»,
       reported August 2026). Reachable is not visible.
       So the wrapper fills the container and the BOARD is the part that gives:
       header and keyboard are `flex: none`, the board takes what is left and
       scrolls inside itself. `min-height: 0` is load-bearing — without it a flex
       item refuses to shrink below its content and the whole fix is inert.

       The container MUST become a flex column for any of that to work. It is a
       block by default, and `height: 100%` on a block child resolves against the
       parent's WHOLE content box — not the space that is left. The `.sura-hud`
       above the wrapper is 136px plus a 14px margin, so the wrapper measured its
       full 620px starting 150px down and overflowed by exactly that much, which
       pushed the keyboard further off-screen than before the fix. As a flex
       column the hud is a sibling item, the wrapper gets the remainder, and the
       arithmetic can no longer be wrong. */
    #wordle-modal .wordle-modal-container {
        display: flex;
        flex-direction: column;
    }
    #wordle-modal .sura-hud { flex: none; }
    #wordle-modal .wordle-game-wrapper {
        flex: 1 1 auto;
        min-height: 0;
        height: auto;
        gap: 0.7rem;
        flex-wrap: nowrap;
    }
    #wordle-modal .wordle-header,
    #wordle-modal .wordle-message,
    #wordle-modal .wordle-keyboard,
    #wordle-modal .wordle-actions { flex: none; }
    /* Shrink-only (`0 1 auto`), never grow: `1 1 auto` handed the board every
       spare pixel and it swelled from 294px to 478px. */
    #wordle-modal .wordle-board {
        flex: 0 1 auto;
        min-height: 0;
        overflow-y: auto;
        justify-content: flex-start;
    }
}

/* ---------- Connections (تشابك) ---------- */
.conn-solved {
    display: flex;
    flex-direction: column;
    gap: 6px;
    width: 100%;
}
.conn-solved-row {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    padding: 0.6rem;
    border-radius: var(--r-sm);
    color: var(--ink-0);
    text-align: center;
    animation: fadeIn 0.4s ease-out;
}
.conn-solved-row.clr-orange { background: #ab442d; }
.conn-solved-row.clr-green  { background: var(--ok-deep); }
.conn-solved-row.clr-amber  { background: var(--gold-700); }
.conn-solved-row.clr-purple { background: #472652; }
.conn-solved-row.clr-blue   { background: #25506b; }
.conn-solved-row.clr-rose   { background: #8a2f4d; }
.conn-solved-row.revealed { opacity: 0.55; }
.conn-solved-row.conn-decoy-row { background: #3a3f47; border: 1px dashed rgba(255,255,255,0.28); }
.conn-decoy-row .conn-theme::before { content: '⚠ '; }
.conn-theme { font-weight: 800; font-size: var(--fs-md); letter-spacing: 0.02em; }
.conn-words { font-size: var(--fs-sm); opacity: 0.92; }

.conn-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 6px;
    width: 100%;
}
.conn-tile {
    min-height: 62px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0.4rem 0.2rem;
    border-radius: var(--r-sm);
    border: 1px solid var(--glass-border);
    background: rgba(255, 255, 255, 0.05);
    color: var(--clr-text-main);
    font-family: 'Reem Kufi', sans-serif;
    font-weight: 700;
    font-size: var(--fs-md);
    cursor: pointer;
    user-select: none;
    transition: var(--transition-quick);
}
.conn-tile:hover { background: rgba(255, 255, 255, 0.12); transform: translateY(-1px); }
.conn-tile.selected {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    border-color: transparent;
    transform: translateY(-2px);
}

.conn-lives {
    display: flex;
    gap: 8px;
    justify-content: center;
    align-items: center;
}
.conn-dot {
    width: 12px; height: 12px;
    border-radius: 50%;
    background: var(--clr-brand-secondary);
    transition: var(--transition-quick);
}
.conn-dot.lost { background: rgba(255,255,255,0.15); transform: scale(0.8); }

.conn-controls {
    display: flex;
    gap: 8px;
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
}
.conn-btn {
    padding: 0.6rem 1rem;
    border-radius: var(--r-full);
    border: 1px solid var(--glass-border-hover);
    background: rgba(255,255,255,0.05);
    color: var(--clr-text-main);
    font-family: 'Reem Kufi', sans-serif;
    font-weight: 600;
    font-size: var(--fs-sm);
    cursor: pointer;
    transition: var(--transition-quick);
}
.conn-btn:hover:not(:disabled) { background: rgba(255,255,255,0.14); transform: translateY(-1px); }
.conn-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.conn-btn.primary {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
    border-color: transparent;
}
.conn-btn.active { background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary)); color: var(--clr-text-dark); }

/* ---------- Sudoku (سودوكو) ---------- */
.sudoku-timebar {
    display: flex;
    gap: 0.5rem;
    align-items: center;
    font-size: var(--fs-md);
    color: var(--clr-brand-secondary);
    font-weight: 700;
}
.sudoku-time-label { color: var(--clr-text-muted); font-weight: 500; }

.sudoku-board {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    width: 100%;
    max-width: 396px;
    aspect-ratio: 1 / 1;
    border: 2px solid rgba(255,255,255,0.35);
    border-radius: var(--r-sm);
    overflow: hidden;
    background: rgba(255,255,255,0.02);
}
.sudoku-cell {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 1px solid rgba(255,255,255,0.08);
    font-size: var(--fs-xl);
    font-weight: 600;
    color: var(--clr-brand-secondary);
    cursor: pointer;
    position: relative;
    transition: background 0.12s ease;
}
.sudoku-cell.bl { border-left: 2px solid rgba(255,255,255,0.35); }
.sudoku-cell.bt { border-top: 2px solid rgba(255,255,255,0.35); }
.sudoku-cell.given { color: var(--clr-text-main); font-weight: 800; cursor: default; background: rgba(255,255,255,0.04); }
.sudoku-cell.selected { background: rgba(198, 154, 74, 0.28); }
.sudoku-cell.same { background: rgba(198, 154, 74, 0.12); }
.sudoku-cell.conflict { color: #ff6b6b; background: rgba(255, 80, 80, 0.16); }
.sudoku-cell .s-notes {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    width: 100%; height: 100%;
    font-size: var(--fs-4xs);
    color: var(--clr-text-muted);
    line-height: 1;
}
.sudoku-cell .s-notes span { display: flex; align-items: center; justify-content: center; }

.sudoku-pad {
    display: grid;
    grid-template-columns: repeat(9, 1fr);
    gap: 5px;
    width: 100%;
}
.sudoku-key {
    aspect-ratio: 1 / 1;
    border-radius: var(--r-sm);
    border: 1px solid var(--glass-border);
    background: rgba(255,255,255,0.05);
    color: var(--clr-text-main);
    font-family: 'Reem Kufi', sans-serif;
    font-size: var(--fs-lg);
    font-weight: 700;
    cursor: pointer;
    transition: var(--transition-quick);
}
.sudoku-key:hover { background: rgba(255,255,255,0.15); transform: translateY(-1px); }

/* ---------- Spelling Bee (نحلة الإملاء) ---------- */
.bee-rankbar { width: 100%; display: flex; flex-direction: column; gap: 6px; }
.bee-rank { font-weight: 800; color: var(--clr-brand-secondary); font-size: var(--fs-md); }
.bee-progress { width: 100%; height: 8px; border-radius: var(--r-full); background: rgba(255,255,255,0.08); overflow: hidden; }
.bee-progress-fill {
    height: 100%; width: 0%;
    background: linear-gradient(90deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    border-radius: var(--r-full);
    transition: width 0.5s var(--ease-expo);
}
.bee-word {
    min-height: 2.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1px;
    font-size: var(--fs-3xl);
    font-weight: 800;
    letter-spacing: 0.04em;
    color: var(--clr-text-main);
}
.bee-word .wc-center { color: var(--clr-brand-primary); }
.bee-word .wc-bad { color: var(--ink-4); }
.bee-word .wc-ph { font-size: var(--fs-md); font-weight: 500; color: var(--clr-text-muted); letter-spacing: normal; }

.bee-hive { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.bee-row { display: flex; gap: 4px; }
.bee-cell {
    width: 64px; height: 72px;
    clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%);
    background: rgba(255, 255, 255, 0.08);
    border: none;
    color: var(--clr-text-main);
    font-family: 'Reem Kufi', sans-serif;
    font-size: var(--fs-3xl);
    font-weight: 800;
    cursor: pointer;
    transition: transform 0.12s ease, background 0.12s ease;
}
.bee-cell:hover { background: rgba(255,255,255,0.18); }
.bee-cell:active { transform: scale(0.92); }
.bee-cell.center {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--clr-text-dark);
}

.bee-found-head { width: 100%; text-align: right; font-size: var(--fs-xs); color: var(--clr-text-muted); font-weight: 600; }
.bee-found {
    width: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    max-height: 110px;
    overflow-y: auto;
}
.bee-chip {
    padding: 0.3rem 0.7rem;
    border-radius: var(--r-full);
    background: rgba(255,255,255,0.06);
    border: 1px solid var(--glass-border);
    font-size: var(--fs-xs);
    font-weight: 600;
    animation: fadeIn 0.3s ease-out;
}

@media (max-width: 768px) {
    .conn-tile { min-height: 54px; font-size: var(--fs-xs); }
    .sudoku-cell { font-size: var(--fs-base); }
    .sudoku-key { font-size: var(--fs-base); }
    .bee-cell { width: 54px; height: 62px; font-size: var(--fs-2xl); }
    .bee-word { font-size: var(--fs-2xl); }
}

/* ============================================================
   Sura platform chrome — HUD (flame · countdown · hint),
   toast, streak-saver banner, XP bar, badges, combo tracker.
   Reuses the existing glass tokens + brand coral.
   ============================================================ */
.sura-hud {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin: 0 0 0.9rem;
    padding: 0.45rem 0.6rem;
    /* The ✕ is absolutely positioned in the modal's inline-end corner (16px
       inset + 38px = a 54px strip) and the hud is always the container's first
       child, so its top row is the only content that can ever sit under it —
       and `.hint-btn`'s `margin-inline-start: auto` parks the hint counter
       precisely there. Measured overlapping at 393px AND 1280px, so this is a
       reservation, not a mobile patch. */
    padding-inline-end: 3.4rem;
    background: var(--glass-bg);
    border: 1px solid var(--glass-border);
    border-radius: var(--r-md);
    font-size: var(--fs-sm);
}
.sura-hud .hud-flame,
.sura-hud .hud-count {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    color: var(--clr-text-muted);
    font-weight: 600;
    white-space: nowrap;
}
.sura-hud .hud-flame b { color: var(--clr-brand-primary); font-size: var(--fs-base); }
.sura-hud .hud-clock { font-variant-numeric: tabular-nums; letter-spacing: 0.5px; }
.hint-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    margin-inline-start: auto;
    padding: 0.4rem 0.85rem;
    border-radius: var(--r-full);
    border: 1px solid rgba(198, 154, 74, 0.45);
    background: linear-gradient(135deg, rgba(198, 154, 74, 0.22), rgba(254, 180, 123, 0.14));
    color: var(--clr-text-main);
    font-family: inherit;
    font-weight: 700;
    font-size: var(--fs-xs);
    cursor: pointer;
    transition: var(--transition-quick);
}
.hint-btn:hover { border-color: var(--clr-brand-primary); transform: translateY(-1px); box-shadow: 0 4px 16px rgba(198, 154, 74, 0.25); }
.hint-btn .hint-left { color: var(--clr-brand-secondary); }
/* the free per-level hint, kept out of the daily number so that number
   only ever counts down */
.hint-btn .hint-gift { margin-inline-start: 0.28em; font-size: 0.92em; }
.hint-btn.spent { opacity: 0.5; filter: grayscale(0.6); cursor: not-allowed; }

/* لوحةُ التلميح — تحلّ محلّ الإشعار الزائل.
   التلميح معلومةٌ مرجعيّة دفع اللاعب ثمنها ويقرؤها وهو ينظر إلى اللوح، لا
   إخطارًا يقول «حدث شيء». تبقى حتّى يبدأ لوحًا جديدًا (`memo().reset()`).
   بلا حركةِ ظهور: §٢ تسمح باستجابةٍ للمس، وهذه نتيجةُ ضغطةٍ لا حركةَ سكون —
   لكنّ الظهور الفوريّ أصدق هنا، فالعين تكون على اللوح لا على اللوحة. */
.hint-panel {
    display: flex;
    align-items: flex-start;
    gap: 0.5rem;
    margin: 0.5rem 0 0.25rem;
    padding: 0.6rem 0.85rem;
    border-radius: var(--r-sm);
    border: 1px solid rgba(198, 154, 74, 0.38);
    border-inline-start: 3px solid var(--clr-brand-primary);
    background: rgba(198, 154, 74, 0.10);
    color: var(--clr-text-main);
    font-size: var(--fs-sm);
    line-height: 1.65;
    text-align: start;
}
.hint-panel.hidden { display: none; }
.hint-panel-ico { flex: none; font-size: 1.05em; line-height: 1.55; }
.hint-panel-text { min-width: 0; }

/* Floating toast (level-up / badge / hint) */
.sura-toast {
    position: fixed;
    left: 50%;
    bottom: 2.2rem;
    transform: translate(-50%, 24px);
    z-index: 200;
    max-width: min(90vw, 460px);
    padding: 0.85rem 1.2rem;
    border-radius: var(--r-md);
    background: rgba(15, 23, 42, 0.96);
    border: 1px solid var(--glass-border-hover);
    box-shadow: var(--glass-shadow-hover);
    color: var(--clr-text-main);
    font-weight: 600;
    font-size: var(--fs-md);
    text-align: center;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s ease, transform 0.35s var(--ease-expo);
}
.sura-toast.show { opacity: 1; transform: translate(-50%, 0); }
.sura-toast .t-ico { font-size: var(--fs-lg); margin-inline-end: 0.25rem; }
.sura-toast small { color: var(--clr-text-muted); font-weight: 500; }

/* Streak-saver banner */
.sura-saver {
    position: fixed;
    left: 50%;
    bottom: 2.2rem;
    transform: translate(-50%, 24px);
    z-index: 210;
    display: flex;
    align-items: center;
    gap: 0.9rem;
    flex-wrap: wrap;
    justify-content: center;
    max-width: min(92vw, 520px);
    padding: 0.9rem 1.2rem;
    border-radius: var(--r-lg);
    background: linear-gradient(135deg, rgba(255, 107, 53, 0.95), rgba(198, 154, 74, 0.92));
    box-shadow: 0 12px 40px rgba(255, 107, 53, 0.35);
    color: var(--ink-0);
    font-weight: 600;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.35s ease, transform 0.35s var(--ease-expo);
}
.sura-saver.show { opacity: 1; pointer-events: auto; transform: translate(-50%, 0); }
.sura-saver .saver-msg small { opacity: 0.85; font-weight: 500; }
.sura-saver .saver-btns { display: inline-flex; gap: 0.5rem; }
.sura-saver button {
    padding: 0.4rem 1rem;
    border-radius: var(--r-full);
    border: none;
    font-family: inherit;
    font-weight: 700;
    cursor: pointer;
}
.sura-saver .saver-yes { background: var(--ink-0); color: var(--clr-accent); }
.sura-saver .saver-no { background: rgba(255, 255, 255, 0.2); color: var(--ink-0); }

/* XP bar + badge shelf + combo tracker (account / grid hero) */
.xp-bar { height: 10px; border-radius: var(--r-full); background: var(--glass-bg); border: 1px solid var(--glass-border); overflow: hidden; }
.xp-bar > i { display: block; height: 100%; border-radius: var(--r-full); background: linear-gradient(90deg, var(--clr-brand-primary), var(--clr-brand-secondary)); transition: width 0.6s var(--ease-expo); }
.xp-row { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 0.4rem; }
.xp-level { font-weight: 700; color: var(--clr-brand-primary); }
.xp-pts { font-size: var(--fs-sm); color: var(--clr-text-muted); }
.badge-shelf { display: flex; flex-wrap: wrap; gap: 0.5rem; margin-top: 0.6rem; }
.badge-chip { display: inline-flex; align-items: center; gap: 0.3rem; padding: 0.3rem 0.7rem; border-radius: var(--r-full); background: var(--glass-bg); border: 1px solid var(--glass-border); font-size: var(--fs-xs); font-weight: 600; }
.badge-chip.locked { opacity: 0.35; filter: grayscale(1); }
.combo-tracker { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.35rem 0.85rem; border-radius: var(--r-full); background: var(--glass-bg); border: 1px solid var(--glass-border); font-weight: 700; }
.combo-tracker b { color: var(--clr-brand-primary); }
.countdown-badge { display: inline-flex; align-items: center; gap: 0.4rem; padding: 0.35rem 0.85rem; border-radius: var(--r-full); background: var(--glass-bg); border: 1px solid var(--glass-border); font-weight: 600; color: var(--clr-text-muted); }
.countdown-badge span { font-variant-numeric: tabular-nums; color: var(--clr-brand-secondary); letter-spacing: 0.5px; }
.daily-strip { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; margin: 0 auto 1.4rem; }
@media (max-width: 520px) { .daily-strip { gap: 0.4rem; font-size: var(--fs-sm); } }

/* ============================================================
   Letter Boxed (صندوق الحروف)
   ============================================================ */
.lb-theme { text-align: center; font-size: var(--fs-md); font-weight: 600; color: var(--clr-text-main); margin: 0.2rem auto 0.1rem; padding: 0.32rem 0.8rem; border-radius: var(--r-full); background: rgba(0, 124, 65, 0.16); border: 1px solid rgba(0, 124, 65, 0.4); width: fit-content; max-width: 90%; }
.lb-theme[hidden] { display: none; }
.lb-theme b { color: var(--ok); font-weight: 800; }
.lb-flag { font-size: var(--fs-md); }
.lb-used { text-align: center; color: var(--clr-text-muted); font-weight: 600; font-size: var(--fs-md); margin: 0.2rem 0 0.4rem; }
.lb-box { position: relative; width: 300px; height: 300px; max-width: 80vw; max-height: 80vw; margin: 0.4rem auto 1rem; }
.lb-box::before { content: ''; position: absolute; inset: 30px; border: 2px solid rgba(198, 154, 74, 0.5); border-radius: var(--r-sm); }
.lb-side { position: absolute; display: flex; }
.lb-top { top: 6px; left: 42px; right: 42px; justify-content: space-between; }
.lb-bottom { bottom: 6px; left: 42px; right: 42px; justify-content: space-between; }
.lb-left { left: 6px; top: 42px; bottom: 42px; flex-direction: column; justify-content: space-between; }
.lb-right { right: 6px; top: 42px; bottom: 42px; flex-direction: column; justify-content: space-between; }
.lb-letter {
    width: 48px; height: 48px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: var(--surface-1); border: 2px solid var(--clr-brand-secondary);
    color: var(--clr-text-main); font-family: inherit; font-size: var(--fs-2xl); font-weight: 700;
    cursor: pointer; transition: var(--transition-quick); position: relative; z-index: 2;
}
.lb-letter:hover { transform: scale(1.08); border-color: var(--clr-brand-primary); }
.lb-letter.used { background: var(--ok-deep); border-color: var(--ok-deep); }
.lb-letter.in-word { background: var(--clr-brand-primary); border-color: var(--ink-0); color: var(--ink-0); }
.lb-letter.active { box-shadow: 0 0 14px rgba(198, 154, 74, 0.8); }
.lb-word { min-height: 2.2rem; text-align: center; font-size: var(--fs-3xl); font-weight: 700; letter-spacing: 2px; color: var(--clr-text-main); }
.lb-word .wc-ph { color: var(--clr-text-muted); font-size: var(--fs-base); font-weight: 500; letter-spacing: 0; }
.lb-chain { display: flex; flex-wrap: wrap; gap: 0.3rem; justify-content: center; align-items: center; margin: 0.5rem 0; min-height: 1.6rem; }
.lb-chip { padding: 0.25rem 0.7rem; border-radius: var(--r-full); background: var(--glass-bg); border: 1px solid var(--glass-border); font-weight: 700; font-size: var(--fs-md); }
.lb-arrow { color: var(--clr-text-muted); font-size: var(--fs-lg); }
@media (max-width: 520px) {
    .lb-letter { width: 40px; height: 40px; font-size: var(--fs-lg); }
    .lb-word { font-size: var(--fs-2xl); }
}

/* ============================================================
   Strands (خيوط)
   ============================================================ */
.strands-topbar { display: flex; justify-content: space-between; align-items: center; margin: 0.2rem 0 0.6rem; font-size: var(--fs-md); color: var(--clr-text-muted); }
.strands-topbar b { color: var(--clr-brand-secondary); }
.strands-prog { font-weight: 700; color: var(--clr-brand-primary); }
.strands-board { display: grid; gap: 6px; justify-content: center; margin: 0 auto 0.6rem; max-width: 360px; }
.strand-cell {
    aspect-ratio: 1; min-width: 0; width: 100%;
    display: flex; align-items: center; justify-content: center;
    background: var(--glass-bg); border: 2px solid var(--glass-border);
    border-radius: 50%; color: var(--clr-text-main);
    font-family: inherit; font-size: var(--fs-xl); font-weight: 700;
    cursor: pointer; transition: background 0.15s ease, transform 0.15s ease, border-color 0.15s ease;
}
.strand-cell:hover { border-color: var(--glass-border-hover); }
.strand-cell.in-path { background: var(--clr-brand-primary); border-color: var(--ink-0); color: var(--ink-0); transform: scale(1.05); }
.strand-cell.found { color: var(--ink-0); border-width: 2px; }
.strand-cell.hint-cell { animation: strandPulse 0.8s ease-in-out infinite; border-color: var(--clr-brand-secondary); }
@keyframes strandPulse { 0%,100% { box-shadow: 0 0 0 0 rgba(254,180,123,0.6); } 50% { box-shadow: 0 0 0 8px rgba(254,180,123,0); } }
@media (max-width: 520px) { .strand-cell { font-size: var(--fs-base); } .strands-board { gap: 4px; max-width: 320px; } }

/* ---- أمثال (Proverbs) ---- */
/* الرقاقاتُ تلتفّ سطرين عمدًا: بسطرٍ واحدٍ يبقى ثلثا اللوحة فارغًا، وبسطرين
   تُقرأ كمثلٍ يُركَّب كلمةً كلمة — وهو فعلُ اللعبة نفسه. */
.amthal-vector { position: relative; width: 100%; height: 100%; display: flex; flex-wrap: wrap; align-content: center; justify-content: center; gap: 8px; gap: 3.4cqw; padding: 12px; padding: 6cqw; }
.amthal-vector .amthal-chip { display: inline-flex; align-items: center; justify-content: center; padding: 6px 12px; padding: 2.6cqw 5cqw; border-radius: var(--r-sm); font-weight: 700; font-size: var(--fs-xs); font-size: 6.6cqw; color: var(--ink-1); background: rgba(15, 23, 42, 0.78); border: 1px solid var(--gold-400); }
.amthal-vector .amthal-chip.c1 { transform: rotate(-5deg); }
.amthal-vector .amthal-chip.c2 { transform: rotate(3deg); background: linear-gradient(135deg, var(--gold-500), var(--gold-400)); color: var(--gold-900); border-color: transparent; }
.amthal-vector .amthal-chip.c3 { transform: rotate(-2deg); }
.amthal-vector .amthal-quote { position: absolute; top: 1cqw; right: 4cqw; font-size: 20cqw; line-height: 1; color: rgba(254, 180, 123, 0.5); font-family: Georgia, serif; }

/* ---- أمثال: اللوحةُ تؤدّي آليّةَ اللعبة بدل أن تصفها -------------------
   القيمُ منقولةٌ عن `.amthal-wbox` الحقيقيّة أعلاه (الخلفيّة 0.06، الحدّ
   1.5px‏/0.26، والمقفول `--ok-deep` على `--ok`) حتى تَعِدَ البطاقةُ بما
   خلفها بالضبط. و`.amthal-chip` يبقى كما هو: بطاقتا «كلمة ناقصة» و«رتّب
   السالفة» المخفيّتان ما زالتا تستعملانه. */
.amthal-scaffold { gap: 2.4cqw; }

/* `flex-basis:100%` يكسر السطر فينزل الصفُّ كاملًا تحت المعنى — وهو ترتيبُ
   اللعبة: المعنى أوّلًا ثمّ الصناديق. */
.amthal-scaffold .amthal-hint {
    flex: 0 0 100%;
    text-align: center;
    font-size: var(--fs-4xs);
    font-size: 3.8cqw;
    font-weight: 600;
    color: var(--clr-text-main);
    background: rgba(198, 154, 74, 0.12);
    border: 1px solid rgba(198, 154, 74, 0.34);
    border-radius: var(--r-sm);
    padding: 4px 8px;
    padding: 1.6cqw 3cqw;
    margin-bottom: 1.4cqw;
}

.amthal-scaffold .amthal-word {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    /* عرضٌ واحدٌ للثلاثة لا حدٌّ أدنى: صندوقُ النقاط أضيقُ من صندوق الكلمة،
       فلمّا انقلبت «ا····» إلى «الفرج» عند التمرير اتّسع الصندوقُ وانزاح
       الصفُّ كلُّه جانبًا — قفزةٌ رُئيت في اللقطة. و`border-box` عامٌّ في
       الملفّ (السطر ١٩٧) فالنسبةُ تشمل الحشوَ والحدّ. */
    flex: 0 0 26%;
    font-weight: 700;
    font-size: var(--fs-xs);
    font-size: 5.2cqw;
    color: var(--clr-text-main);
    background: rgba(255, 255, 255, 0.06);
    border: 1.5px solid rgba(255, 255, 255, 0.26);
    border-radius: var(--r-sm);
    padding: 5px 9px;
    padding: 2.2cqw 3.2cqw;
    transition: background 0.3s ease, border-color 0.3s ease, color 0.3s ease;
}

.amthal-scaffold .amthal-word.locked {
    background: var(--ok-deep);
    border-color: var(--ok);
    color: var(--ink-0);
}

/* الجوابُ مُضمَرٌ في الصفحة ويُبدَّل بـ`display` لا بالشفافيّة: تحريكُ
   `opacity` على أحفاد `.scroll-section` ممنوعٌ (§١١٨) لأنّ سفاري iOS يجمّد
   إطارَ البداية عند عودة القسم من `display:none` فيبقى النصُّ خفيًّا للأبد. */
.amthal-scaffold .aw-ans { display: none; font-style: normal; }
/* بلا `letter-spacing`: النصُّ عربيٌّ («ا····» ألفٌ ثمّ نقاطُها) والتباعدُ
   يفصل الحروفَ عن اتّصالها — قاعدةٌ قاطعةٌ في الهويّة، ولا استثناءَ لها هنا
   لمجرّد أنّ أغلبَ ما في الصندوق نقاط. */
.amthal-scaffold .aw-dots { font-style: normal; }

/* قرّبها — the guess input must dominate the row so the whole typed word shows.
   The global mobile rule (.btn-primary { width:100% }) otherwise blows the «خمّن»
   button up to full width and collapses the input to a sliver. Two IDs → wins
   everywhere without touching the global button rule. */
#warmer-input-row, #lamha-input-row { flex-wrap: nowrap; }
#warmer-input-row #warmer-input, #lamha-input-row #lamha-input { flex: 1 1 auto; min-width: 0; width: auto; }
#warmer-input-row #warmer-guess-btn, #lamha-input-row #lamha-guess-btn { flex: 0 0 auto; width: auto; padding: 0.6em 1.2em; white-space: nowrap; }

/* قرّبها — proximity bars running cold to hot. */
.warmer-vector { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 9px; padding: 14px 16px; }
.warmer-row { display: flex; align-items: center; gap: 8px; }
.warmer-word { flex: 0 0 42px; font-size: var(--fs-2xs); font-weight: 700; color: #f1d9c4; text-align: right; }
.warmer-bar { flex: 1; height: 8px; border-radius: var(--r-full); background: rgba(255, 255, 255, 0.09); overflow: hidden; }
.warmer-bar i { display: block; height: 100%; border-radius: var(--r-full); background: linear-gradient(90deg, var(--info), var(--gold-500), #ff5a2b); }
.warmer-tag { flex: 0 0 auto; font-size: var(--fs-xs); line-height: 1; }
.warmer-row.is-hot .warmer-word { color: #ffb27a; }
.game-card:hover .warmer-row.is-hot .warmer-tag { animation: warmer-flick 0.9s ease-in-out infinite; }
@keyframes warmer-flick {
    0%, 100% { transform: scale(1); }
    50% { transform: scale(1.22); }
}

/* لمحة — three clues fading in, each worth fewer stars than the last. */
.lamha-vector { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 7px; padding: 14px 16px; }
.lamha-clue { display: flex; align-items: center; gap: 7px; font-size: var(--fs-2xs); font-weight: 600; color: var(--info-soft); background: rgba(255, 255, 255, 0.05); border: 1px solid rgba(255, 255, 255, 0.09); border-radius: var(--r-sm); padding: 5px 8px; }
.lamha-num { flex: 0 0 15px; height: 15px; display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; background: var(--gold-600); color: var(--surface-1); font-size: var(--fs-3xs); font-weight: 800; }
.lamha-stars { margin-inline-start: auto; font-size: var(--fs-4xs); letter-spacing: -1px; }
/* Opacity is the reveal: clue 1 is sharp, clue 3 is still behind the glass. */
.lamha-clue.s3 { opacity: 1; }
.lamha-clue.s2 { opacity: 0.62; }
.lamha-clue.s1 { opacity: 0.32; }
.lamha-clue { transition: opacity 0.45s ease; }
.game-card:hover .lamha-clue.s2, .game-card:hover .lamha-clue.s1 { opacity: 1; }

/* زايد — a bidding ladder climbing to a fold. */
.zayid-vector { width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; gap: 6px; padding: 12px 16px; }
.zayid-vrow { display: flex; align-items: center; gap: 8px; font-size: var(--fs-2xs); font-weight: 700; border-radius: var(--r-sm); padding: 4px 8px; }
.zayid-vrow .zayid-vwho { flex: 0 0 34px; opacity: 0.7; font-size: var(--fs-3xs); }
.zayid-vrow .zayid-vbid { margin-inline-start: auto; }
.zayid-vrow.me { background: rgba(45, 74, 99, 0.4); border: 1px solid rgba(127, 178, 224, 0.4); color: var(--info-soft); }
.zayid-vrow.op { background: rgba(201, 162, 39, 0.14); border: 1px solid rgba(201, 162, 39, 0.4); color: var(--gold-100); }
.zayid-vrow.fold { background: rgba(214, 69, 65, 0.16); border: 1px dashed rgba(214, 69, 65, 0.55); color: var(--err-soft); }
.game-card:hover .zayid-vrow.fold { animation: warmer-flick 0.9s ease-in-out infinite; }

/* زايد — in-modal UI: mode toggle · score · bidding · rival · prove phase. */
.zayid-mode { display: flex; gap: 8px; justify-content: center; margin: 0 auto 0.6rem; }
.zayid-modebtn { font-family: inherit; font-size: var(--fs-md); font-weight: 700; color: var(--clr-text-main); background: rgba(255, 255, 255, 0.05); border: 1.5px solid rgba(255, 255, 255, 0.18); border-radius: var(--r-full); padding: 0.4em 1em; cursor: pointer; transition: all 0.18s ease; }
.zayid-modebtn.on { background: rgba(198, 154, 74, 0.22); border-color: var(--clr-brand-secondary); color: var(--gold-050); }
.zayid-score { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 0 auto 0.6rem; font-size: var(--fs-md); flex-wrap: wrap; }
.zayid-score .zayid-side { display: inline-flex; align-items: center; gap: 5px; }
.zayid-score .zayid-vs { opacity: 0.6; font-size: var(--fs-xs); }
.zayid-pip { width: 11px; height: 11px; border-radius: 50%; display: inline-block; border: 1.5px solid rgba(255, 255, 255, 0.28); }
.zayid-pip.p.f { background: #7fb2e0; border-color: #7fb2e0; }
.zayid-pip.o.f { background: var(--gold-500); border-color: var(--gold-500); }
.zayid-bid { text-align: center; min-height: 40px; margin-bottom: 0.5rem; }
.zayid-bidnum { font-size: var(--fs-base); font-weight: 700; margin-bottom: 0.55rem; color: var(--clr-text-main); }
.zayid-bidnum b { color: var(--clr-brand-secondary); font-size: 1.3em; }
.zayid-bidbtns { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.zayid-bidbtn { flex: 0 1 auto; min-width: 0; font-family: inherit; font-size: var(--fs-base); font-weight: 700; color: var(--surface-1); background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary)); border: 1px solid var(--clr-brand-secondary); border-radius: var(--r-sm); padding: 0.55em 1em; cursor: pointer; transition: transform 0.12s ease; }
.zayid-bidbtn:active { transform: scale(0.96); }
.zayid-fold { display: block; margin: 0.7rem auto 0; font-family: inherit; font-size: var(--fs-md); font-weight: 700; color: var(--err-soft); background: rgba(214, 69, 65, 0.16); border: 1.5px solid rgba(214, 69, 65, 0.5); border-radius: var(--r-sm); padding: 0.5em 1.4em; cursor: pointer; }
.zayid-turn { opacity: 0.7; font-style: italic; margin-top: 0.4rem; }
.zayid-pass { display: flex; flex-direction: column; align-items: center; gap: 0.8rem; padding: 1rem 0; line-height: 1.7; }
.zayid-rival { display: none; align-items: center; gap: 9px; justify-content: center; margin: 0.2rem auto 0.5rem; max-width: 520px; }
.zayid-rival.show { display: flex; }
.zayid-avatar { flex: 0 0 auto; font-size: var(--fs-2xl); }
.zayid-say { background: rgba(255, 255, 255, 0.06); border: 1px solid rgba(255, 255, 255, 0.16); border-radius: var(--r-md); padding: 0.5em 0.9em; font-size: var(--fs-md); line-height: 1.6; }
.zayid-say.call { background: rgba(214, 69, 65, 0.16); border-color: rgba(214, 69, 65, 0.45); }
.zayid-prove { max-width: 560px; margin: 0 auto; }
.zayid-prove-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; font-size: var(--fs-base); font-weight: 700; margin-bottom: 0.5rem; }
.zayid-prove-head b { color: var(--clr-brand-secondary); }
.zayid-timer { flex: 0 0 auto; font-variant-numeric: tabular-nums; }
.zayid-timer.low { color: #ff6b66; animation: warmer-flick 0.7s ease-in-out infinite; }
.zayid-prove-row { display: flex; flex-wrap: nowrap; gap: 0.5em; align-items: center; margin-bottom: 0.5rem; }
.zayid-prove-row #zayid-prove-input { flex: 1 1 auto; min-width: 0; width: auto; padding: 0.6em 0.8em; border: 1px solid rgba(201, 162, 39, 0.5); border-radius: var(--r-sm); background: rgba(0, 0, 0, 0.25); color: inherit; font-size: 1.05em; text-align: right; direction: rtl; }
.zayid-prove-row #zayid-prove-submit { flex: 0 0 auto; width: auto; padding: 0.6em 1.2em; white-space: nowrap; }
.zayid-chips { display: flex; flex-wrap: wrap; gap: 7px; justify-content: flex-start; margin-bottom: 0.5rem; }
.zayid-chip { display: inline-flex; align-items: center; gap: 5px; font-size: var(--fs-md); font-weight: 700; border-radius: var(--r-full); padding: 0.32em 0.75em; border: 1px solid transparent; }
.zayid-chip i { font-style: normal; font-size: 0.85em; opacity: 0.85; }
.zayid-chip.ok { background: rgba(58, 166, 85, 0.2); border-color: var(--ok); color: var(--ok-soft); }
.zayid-chip.bad { background: rgba(214, 69, 65, 0.18); border-color: var(--err); color: var(--err-soft); }
.zayid-chip.dup { background: rgba(201, 162, 39, 0.14); border-color: var(--gold-600); color: var(--gold-100); }
.zayid-chip.pending { background: rgba(255, 255, 255, 0.08); border-color: rgba(255, 255, 255, 0.25); opacity: 0.7; }
.zayid-banner { text-align: center; font-size: var(--fs-lg); font-weight: 800; border-radius: var(--r-md); padding: 0.7rem 1rem; margin-bottom: 0.6rem; }
.zayid-banner.win { background: rgba(58, 166, 85, 0.2); border: 1px solid var(--ok); color: var(--ok-soft); }
.zayid-banner.lose { background: rgba(80, 120, 160, 0.16); border: 1px solid var(--info); color: var(--info-soft); }
.zayid-final { text-align: center; font-size: var(--fs-lg); font-weight: 700; margin-bottom: 0.3rem; }

.amthal-meaning { text-align: center; font-size: var(--fs-base); font-weight: 600; color: var(--clr-text-main); background: rgba(198, 154, 74, 0.12); border: 1px solid rgba(198, 154, 74, 0.34); border-radius: var(--r-md); padding: 0.7rem 1rem; margin: 0.2rem auto 0.7rem; max-width: 520px; line-height: 1.7; }

/* direction:rtl (NOT flex-direction:row-reverse): the page is dir="rtl", so
   row-reverse flipped the words back to left-to-right and broke word order on
   wrapping (multi-line proverbs). Natural RTL flow lays word 1 at the right and
   wraps correctly. */
.amthal-type { display: flex; flex-wrap: wrap; direction: rtl; justify-content: center; gap: 9px; min-height: 54px; padding: 0.8rem 0.7rem; margin: 0 auto 0.7rem; max-width: 580px; border: 2px dashed rgba(255, 255, 255, 0.18); border-radius: var(--r-md); }
.amthal-wbox { font-family: inherit; font-size: var(--fs-lg); font-weight: 700; text-align: center; color: var(--clr-text-main); background: rgba(255, 255, 255, 0.06); border: 1.5px solid rgba(255, 255, 255, 0.26); border-radius: var(--r-sm); padding: 0.5rem 0.7rem; width: 7.2rem; max-width: 42vw; transition: border-color 0.18s ease, background 0.2s ease, box-shadow 0.2s ease; }
.amthal-wbox::placeholder { color: rgba(255, 255, 255, 0.32); font-weight: 500; }
.amthal-wbox:focus { outline: none; border-color: var(--clr-brand-secondary); box-shadow: 0 0 0 3px rgba(254, 180, 123, 0.25); }
.amthal-wbox.wrong { border-color: var(--err); background: rgba(214, 69, 65, 0.18); color: var(--err-soft); }
.amthal-wbox.correct { background: var(--ok-deep); border-color: var(--ok); color: var(--ink-0); }
.amthal-wbox.pop { animation: amthalPop 0.32s ease; }
@keyframes amthalPop { 0% { transform: scale(1); } 45% { transform: scale(1.14); box-shadow: 0 0 16px rgba(58, 166, 85, 0.7); } 100% { transform: scale(1); } }
.amthal-wbox.hint-cell { animation: strandPulse 0.8s ease-in-out infinite; border-color: var(--clr-brand-secondary); }
/* 16px is the iOS threshold: any smaller and Safari zooms the page on every
   input focus, which on a per-word grid is unusable. */
@media (max-width: 520px) { .amthal-wbox { font-size: 16px; width: 6rem; padding: 0.45rem 0.5rem; } .amthal-meaning { font-size: var(--fs-md); } }

/* ============================================================
   Tiles (زليج)
   ============================================================ */
.tiles-combo b { color: var(--clr-brand-primary); }
.tiles-board { display: grid; gap: 8px; justify-content: center; margin: 0 auto 0.6rem; max-width: 380px; }
.zellige-tile {
    aspect-ratio: 1; min-width: 0; width: 100%;
    display: flex; align-items: center; justify-content: center;
    background: radial-gradient(circle at 50% 40%, rgba(255,255,255,0.06), rgba(15,23,42,0.6));
    border: 2px solid var(--glass-border); border-radius: var(--r-md);
    cursor: pointer; transition: transform 0.15s ease, border-color 0.15s ease, opacity 0.4s ease;
}
.zellige-tile .zt-glyph { font-size: var(--fs-4xl); line-height: 1; color: var(--tile-accent, var(--gold-500)); text-shadow: 0 0 10px color-mix(in srgb, var(--tile-accent, var(--gold-500)) 50%, transparent); }
.zellige-tile:hover { transform: translateY(-2px); border-color: var(--tile-accent, var(--glass-border-hover)); }
.zellige-tile.sel { border-color: var(--ink-0); transform: scale(1.06); box-shadow: 0 0 14px var(--tile-accent, var(--gold-500)); }
.zellige-tile.wrong { animation: shake 0.4s ease; border-color: var(--err); }
.zellige-tile.matched { opacity: 0.12; pointer-events: none; transform: scale(0.9); }
.zellige-tile.hint-cell { animation: strandPulse 0.8s ease-in-out infinite; border-color: var(--clr-brand-secondary); }
@media (max-width: 520px) { .zellige-tile .zt-glyph { font-size: var(--fs-2xl); } .tiles-board { gap: 6px; max-width: 330px; } }

/* ============================================================
   Pips (نقاط)
   ============================================================ */
.pips-hint-label b { color: var(--clr-brand-secondary); }
.pips-board { display: grid; gap: 0; justify-content: center; margin: 0 auto 0.8rem; width: max-content; }
.pip-cell {
    position: relative; width: 64px; height: 64px;
    display: flex; align-items: center; justify-content: center;
    background: rgba(255,255,255,0.03); border: 1px solid rgba(255,255,255,0.06);
    color: var(--clr-text-muted); font-family: inherit; cursor: pointer; transition: background 0.15s ease;
}
.pip-cell.br-t { border-top: 3px solid rgba(198,154,74,0.55); }
.pip-cell.br-b { border-bottom: 3px solid rgba(198,154,74,0.55); }
.pip-cell.br-l { border-left: 3px solid rgba(198,154,74,0.55); }
.pip-cell.br-r { border-right: 3px solid rgba(198,154,74,0.55); }
.pip-cell.pending { background: rgba(198,154,74,0.25); }
.pip-cell.filled { background: var(--surface-1); color: var(--clr-text-main); }
.pip-cell.reg-ok::after { content: ''; position: absolute; inset: 0; box-shadow: inset 0 0 0 2px rgba(77,182,164,0.5); pointer-events: none; }
.pip-cell.reg-bad::after { content: ''; position: absolute; inset: 0; box-shadow: inset 0 0 0 2px rgba(239,108,108,0.5); pointer-events: none; }
.pip-badge { position: absolute; top: 2px; right: 4px; font-size: var(--fs-2xs); font-weight: 700; color: var(--clr-brand-secondary); }
.pip-face { display: grid; grid-template-columns: repeat(3, 6px); grid-template-rows: repeat(3, 6px); gap: 3px; }
.pip-face i { width: 6px; height: 6px; border-radius: 50%; background: transparent; }
.pip-face i.on { background: currentColor; }
.pips-hand { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; margin: 0.4rem 0 0.6rem; }
.pip-domino {
    display: inline-flex; align-items: center; gap: 6px;
    padding: 8px 10px; border-radius: var(--r-sm);
    background: var(--glass-bg); border: 2px solid var(--glass-border);
    color: var(--clr-text-main); cursor: pointer; transition: var(--transition-quick);
}
.pip-domino:hover { border-color: var(--clr-brand-primary); transform: translateY(-2px); }
.pip-domino .pip-div { width: 2px; height: 22px; background: var(--glass-border-hover); }
.pip-domino.placed { opacity: 0.28; pointer-events: none; }
@media (max-width: 520px) { .pip-cell { width: 54px; height: 54px; } }

/* ============================================================
   Round 3 — Accessibility: font family + color theme overrides
   ============================================================ */
/* Font family (opt-in via <html data-font>). !important wins over the
   broad 'Reem Kufi' rule + any inline font without touching base markup. */
html[data-font="tajawal"] body,
html[data-font="tajawal"] :where(h1,h2,h3,h4,h5,h6,a,button,span,p,input,div,li,label,small,strong,b,td,th) {
    font-family: 'Tajawal', sans-serif !important;
}
html[data-font="naskh"] body,
html[data-font="naskh"] :where(h1,h2,h3,h4,h5,h6,a,button,span,p,input,div,li,label,small,strong,b,td,th) {
    font-family: 'Noto Naskh Arabic', serif !important;
}

/* Light theme — the moving video STAYS visible (the user wants the clip, not a
   flat page). We float a soft translucent LIGHT veil over it so the footage
   reads as a calm pale backdrop, then force dark ink on everything that sits
   over it. Result: the clip still moves faintly behind frosted light, and no
   word ever blends into the background. */
html[data-theme="light"] {
    /* Re-point the RAMPS, not the individual rules. Because every surface and
       every text colour in the product resolves through these tokens, flipping
       them here is the whole of light mode — the `!important` overrides below
       survive only for the handful of places that paint over the video. */
    --surface-0: #ffffff;
    --surface-1: #f4f1ea;
    --surface-2: #ede8de;
    --surface-3: #d5d5cd;
    --surface-4: #c9c4b6;
    --ink-0: #120b08;
    --ink-1: #1c1917;
    --ink-2: #44403c;
    --ink-3: #6b7280;
    --ink-4: #8c8c95;
    --ink-inverse: #ffffff;
    /* Gold darkens a step so it still carries contrast on a pale surface. */
    --gold-400: #b8792c;
    --gold-500: #b07c2a;

    --clr-bg-fallback: var(--surface-1);
    --clr-text-main: var(--ink-1);
    --clr-text-muted: var(--ink-2);
    --glass-bg: rgba(255, 255, 255, 0.78);
    --glass-border: rgba(20, 20, 30, 0.12);
    --glass-border-hover: rgba(20, 20, 30, 0.28);
    --glass-shadow: 0 4px 30px rgba(0,0,0,0.10), inset 0 1px 1px rgba(255,255,255,0.6);
    --glass-shadow-hover: 0 10px 40px rgba(0,0,0,0.16), inset 0 1px 2px rgba(255,255,255,0.7);
}
html[data-theme="light"] body { color: var(--clr-text-main); }
/* keep the clip playing, just soften it so dark text stays readable on top */
html[data-theme="light"] .video-layer { filter: brightness(1.06) saturate(0.82); }
/* the dark vignette becomes a pale wash — a frosted light pane over the video */
html[data-theme="light"] .video-overlay {
    background: linear-gradient(180deg, rgba(248,245,238,0.78) 0%, rgba(244,241,234,0.82) 100%) !important;
    backdrop-filter: blur(2px);
    -webkit-backdrop-filter: blur(2px);
}
html[data-theme="light"] .modal-backdrop { background: rgba(40, 35, 30, 0.55); }
/* every text run that floats directly over the background must be dark ink (not
   the light/white treatment used on the dark video) — and drop the dark halos
   that turn into smudges on a light surface. */
html[data-theme="light"] :where(.hero-title, .hero-description, .hero-subtitle, .games-subtitle, .games-title, .game-arabic-title, .game-english-title, .nav-link, .live-badge, .section-label, .daily-strip, .daily-strip *, h1, h2, h3, h4, p, li, label, blockquote) {
    color: var(--clr-text-main) !important;
    text-shadow: none !important;
}
html[data-theme="light"] :where(.hero-description, .hero-subtitle, .games-subtitle, .game-english-title) { color: var(--clr-text-muted) !important; }
/* The nav is always the matte-black camera plate — keep its links light regardless of theme. */
html[data-theme="light"] .nav-link { color: var(--plate-ink-dim) !important; }
html[data-theme="light"] .nav-link:hover { color: var(--plate-ink) !important; }
html[data-theme="light"] .nav-link.active { color: var(--plate-ink) !important; }
html[data-theme="light"] .logo-text { color: var(--plate-ink) !important; }

/* High-contrast — maximum legibility: solid dark surfaces, bright text,
   bold borders, no blur. */
html[data-theme="contrast"] {
    --clr-bg-fallback: #000000;
    --clr-text-main: var(--ink-0);
    --clr-text-muted: var(--warn-soft);
    --clr-brand-primary: #ffb347;
    --glass-bg: rgba(0, 0, 0, 0.82);
    --glass-border: rgba(255, 255, 255, 0.55);
    --glass-border-hover: rgba(255, 255, 255, 0.9);
    --glass-blur: 0px;
    --glass-shadow: 0 0 0 2px rgba(255,255,255,0.25);
    --glass-shadow-hover: 0 0 0 2px rgba(255,255,255,0.5);
}
html[data-theme="contrast"] .video-overlay { background: rgba(0,0,0,0.9) !important; }
html[data-theme="contrast"] * { text-shadow: none !important; }

/* ============================================================
   Round 3 — Settings gear + settings modal controls
   ============================================================ */
/* Settings gear — small round molded console key (matches the nav console) */
/* Settings gear — machined dark control circle, matching the camera plate */
.settings-gear {
    display: inline-flex; align-items: center; justify-content: center;
    width: 40px; height: 40px; border-radius: 50%;
    background: radial-gradient(circle at 40% 35%, #2c2c30 0%, #141416 70%);
    border: 1px solid #000;
    color: #cfcfd6; cursor: pointer; margin-inline-end: 0.55rem;
    box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.12),
        inset 0 -2px 3px rgba(0, 0, 0, 0.6),
        0 1px 3px rgba(0, 0, 0, 0.5);
    transition: transform 0.12s ease, box-shadow 0.2s ease, color 0.2s ease;
}
.settings-gear:hover {
    color: var(--gold-100); transform: translateY(-1px) rotate(20deg);
    box-shadow:
        inset 0 1px 1px rgba(255, 255, 255, 0.16),
        inset 0 -2px 3px rgba(0, 0, 0, 0.6),
        0 3px 7px rgba(0, 0, 0, 0.55);
}
.settings-gear:active {
    transform: translateY(1px) rotate(20deg);
}
.settings-container { max-width: 480px; }

.seg-control {
    display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.5rem;
}
.seg-control button {
    flex: 1 1 auto; min-width: 64px; padding: 0.5rem 0.7rem;
    border-radius: var(--r-md); cursor: pointer; font: inherit; font-size: var(--fs-md);
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-text-muted); transition: var(--transition-quick);
}
.seg-control button:hover { border-color: var(--glass-border-hover); color: var(--clr-text-main); }
.seg-control button.active {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--gold-900); border-color: transparent; font-weight: 700;
}
.zoom-row { display: flex; align-items: center; gap: 0.8rem; margin-top: 0.7rem; }
.zoom-btn {
    width: 46px; height: 40px; border-radius: var(--r-md); cursor: pointer;
    font: inherit; font-weight: 700; font-size: var(--fs-base);
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-text-main); transition: var(--transition-quick);
}
.zoom-btn:hover { background: var(--glass-border-hover); }
.zoom-label { min-width: 56px; text-align: center; color: var(--clr-text-muted); font-weight: 600; }

/* ============================================================
   Round 5 — In-HUD level campaign bar + picker + «التالي ←»
   ============================================================ */
/* Two groups, one divider: primary actions on one side, behaviour toggles on the
   other. Six equal-weight controls in a flat wrapping row read as clutter and made
   «المستويات» compete with a mute button for attention. */
.lvl-bar { position: relative; display: flex; align-items: center; justify-content: space-between; gap: 0.6rem; flex-wrap: wrap; width: 100%; }
.lvl-main { display: inline-flex; align-items: center; gap: 0.4rem; flex-wrap: wrap; min-width: 0; }
.lvl-tools {
    display: inline-flex; align-items: center; gap: 0.25rem; flex: none;
    padding-inline-start: 0.5rem;
    border-inline-start: 1px solid var(--glass-border);
}
/* Every tool is the same 30px circle, so the group scans as one unit. */
.lvl-tools > button {
    width: 30px; height: 30px; border-radius: 50%; padding: 0; flex: none;
    display: inline-flex; align-items: center; justify-content: center;
    font: inherit; font-size: var(--fs-md); line-height: 1; cursor: pointer;
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-text-muted); transition: var(--transition-quick);
}
.lvl-tools > button:hover { color: var(--clr-brand-primary); border-color: var(--clr-brand-primary); transform: scale(1.08); }

/* الأيقونات: أربعة رسومٍ مرسومةٌ في `src/main.js` بدل أربعة ملفّات.
   The whole reason they are inline SVG and not images is this one line —
   `stroke: currentColor` means the icon is tinted by whatever colour the
   button already has, so hover, `.on`, `.off` and the reduced-contrast
   themes all keep working without a second asset. `stroke-width` is set
   here once, not baked into the paths, so a single edit retunes all four. */
.hud-ico {
    width: 17px; height: 17px; display: block; pointer-events: none;
    fill: none; stroke: currentColor;
    stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round;
}
/* «شرح» is the one a stuck player should reach for, so its drawing is a
   touch heavier than the toggles beside it. */
.demo-btn .hud-ico { stroke-width: 1.8; }
/* The star is the only icon with strokes that run close to each other; at the
   shared 1.6 they closed up and it rendered as a solid cog. Thinner here only. */
.rules-btn .hud-ico { stroke-width: 1.35; }
/* Muted reads as switched off, not merely a different picture. */
.mute-btn.off { color: var(--clr-text-muted); opacity: 0.72; }
.mute-btn.off:hover { opacity: 1; }
@media (max-width: 420px) { .lvl-bar { justify-content: center; } .lvl-tools { padding-inline-start: 0.4rem; } }
.lvl-info { font-size: var(--fs-xs); font-weight: 600; color: var(--clr-text-muted); white-space: nowrap; }
.lvl-info .lvl-num { color: var(--clr-text-main); }
.lvl-info .lvl-band.band-easy { color: var(--ok); }
.lvl-info .lvl-band.band-medium { color: var(--clr-brand-primary); }
.lvl-info .lvl-band.band-hard { color: var(--err); }
/* «تحدي اليوم» — the day's board beside the campaign ladder. Quiet by default
   (it is a mode switch, not a call to action), lit while the mode is on. */
.lvl-daily-btn.on { border-color: var(--clr-brand-primary); color: var(--clr-brand-primary); }
.lvl-info .lvl-left { color: var(--clr-text-muted); font-variant-numeric: tabular-nums; }
.lvl-info .lvl-streak { color: var(--clr-brand-primary); font-weight: 700; }
.lvl-pick-btn, .lvl-next-btn, .lvl-daily-btn {
    font: inherit; font-size: var(--fs-xs); font-weight: 600; cursor: pointer;
    padding: 0.28rem 0.66rem; border-radius: var(--r-sm);
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-text-main); transition: var(--transition-quick);
}
.lvl-pick-btn:hover, .lvl-daily-btn:hover { border-color: var(--clr-brand-primary); }
.lvl-next-btn {
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--gold-900); border-color: transparent; animation: nextPulse 1.4s ease-in-out infinite;
}
.lvl-next-btn:disabled { animation: none; cursor: default; opacity: 0.9; }
@keyframes nextPulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.05); } }
.lvl-picker {
    position: absolute; top: calc(100% + 8px); inset-inline-end: 0; z-index: 30;
    display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px;
    padding: 0.7rem; border-radius: var(--r-md); width: min(86vw, 320px);
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    box-shadow: var(--glass-shadow); backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
}
.lvl-cell {
    position: relative; font: inherit; font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
    aspect-ratio: 1; border-radius: var(--r-sm); border: 1px solid var(--glass-border);
    background: rgba(0,0,0,0.18); color: var(--clr-text-main); transition: var(--transition-quick);
    display: flex; align-items: center; justify-content: center;
}
.lvl-cell.band-easy { box-shadow: inset 0 -3px 0 rgba(72,187,120,0.55); }
.lvl-cell.band-medium { box-shadow: inset 0 -3px 0 rgba(255,179,71,0.55); }
.lvl-cell.band-hard { box-shadow: inset 0 -3px 0 rgba(245,101,101,0.55); }
.lvl-cell.cur { outline: 2px solid var(--clr-brand-primary); outline-offset: 1px; }
.lvl-cell.done { color: var(--ok); }
/* Sequential ladder: levels past the frontier are locked until earned. */
.lvl-cell.locked { opacity: 0.4; cursor: not-allowed; color: inherit; box-shadow: none; filter: grayscale(1); }
.lvl-cell.locked:hover { transform: none; border-color: transparent; }
.lvl-cell:not(.locked):hover { transform: translateY(-1px); border-color: var(--clr-brand-primary); }
.lvl-cell-mark { position: absolute; top: 1px; inset-inline-end: 3px; font-size: var(--fs-3xs); line-height: 1; }

.rules-btn {
    width: 30px; height: 30px; border-radius: 50%; cursor: pointer; flex: none;
    font-size: var(--fs-base); line-height: 1; padding: 0;
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-brand-secondary); transition: var(--transition-quick);
}
.rules-btn:hover { border-color: var(--clr-brand-primary); color: var(--clr-brand-primary); transform: scale(1.08); }

/* 🔊/🔇 — same affordance as ⓘ. Mute is a global pref, so it survives logout. */
.mute-btn {
    width: 30px; height: 30px; border-radius: 50%; cursor: pointer; flex: none;
    font-size: var(--fs-md); line-height: 1; padding: 0;
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    color: var(--clr-brand-secondary); transition: var(--transition-quick);
}
.mute-btn:hover { border-color: var(--clr-brand-primary); color: var(--clr-brand-primary); transform: scale(1.08); }

/* Guess budget: ● spent-vs-remaining pips. Goes amber at 2 left, so running
   out is always something the player saw coming. */
.budget-strip {
    display: flex; align-items: center; gap: 0.45rem;
    margin-top: 0.4rem; font-size: var(--fs-xs);
    color: var(--clr-text-muted, rgba(245,240,225,0.6));
}
.budget-strip .budget-pips { letter-spacing: 0.18em; color: var(--clr-brand-secondary); }
.budget-strip.low { color: var(--warn); }
.budget-strip.low .budget-pips { color: var(--warn); animation: budget-pulse 1.4s ease-in-out infinite; }
@keyframes budget-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.45; } }

/* «حاول من جديد ↻» — free retry, present on every end state. */
.retry-btn {
    font: inherit; font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
    margin-top: 0.5rem; padding: 0.4rem 0.9rem; border-radius: var(--r-sm);
    background: var(--glass-bg); border: 1px solid var(--clr-brand-secondary);
    color: var(--clr-brand-secondary); transition: var(--transition-quick);
}
.retry-btn:hover { border-color: var(--clr-brand-primary); color: var(--clr-brand-primary); transform: translateY(-1px); }
.retry-btn.hidden { display: none; }

/* Mid-round backdrop tap asks before discarding the round. */
.close-guard {
    position: absolute; left: 50%; bottom: 1.1rem; transform: translateX(-50%) translateY(12px);
    display: none; align-items: center; gap: 0.6rem;
    padding: 0.55rem 0.9rem; border-radius: var(--r-md);
    background: rgba(10, 22, 40, 0.96); border: 1px solid var(--clr-brand-secondary);
    color: var(--clr-text-main); font-size: var(--fs-sm); z-index: 40;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    opacity: 0; transition: opacity 0.22s ease, transform 0.22s ease;
}
.close-guard.show { display: flex; opacity: 1; transform: translateX(-50%) translateY(0); }
.close-guard button {
    font: inherit; font-weight: 700; cursor: pointer; padding: 0.3rem 0.7rem;
    border-radius: var(--r-sm); border: 1px solid var(--glass-border); background: transparent; color: inherit;
}
.close-guard .cg-stay { border-color: var(--clr-brand-secondary); color: var(--clr-brand-secondary); }
.close-guard .cg-go { opacity: 0.75; }

/* «تحدّي» — opt-in, off by default. The clock is a bonus, never a fail state.
   Sizing comes from `.lvl-tools > button`; the dashed border is what marks it as
   the one OFF-by-default toggle in the group. */
.rush-btn { border-style: dashed !important; background: transparent !important; }
.rush-btn:hover { color: var(--clr-brand-secondary) !important; border-color: var(--clr-brand-secondary) !important; }
.rush-btn.on {
    border-style: solid; border-color: var(--warn); color: var(--warn);
    background: rgba(224, 161, 58, 0.12);
}
.rush-clock { font-size: var(--fs-xs); font-weight: 700; color: var(--clr-brand-secondary); letter-spacing: 0.02em; }
.rush-clock.low { color: #e0733a; animation: budget-pulse 0.9s ease-in-out infinite; }
.rush-clock.done { color: var(--clr-text-muted, rgba(245,240,225,0.5)); font-weight: 500; }

/* Momentum chip — appears only once a streak is actually going. */
.rush-chip {
    display: none; font-size: var(--fs-xs); font-weight: 800; color: #e0733a;
    padding: 0.14rem 0.44rem; border-radius: var(--r-sm);
    background: rgba(224, 115, 58, 0.14); border: 1px solid rgba(224, 115, 58, 0.5);
}
.rush-chip.show { display: inline-block; animation: rush-pop 0.3s ease; }
@keyframes rush-pop { 0% { transform: scale(0.7); } 60% { transform: scale(1.15); } 100% { transform: scale(1); } }

@media (prefers-reduced-motion: reduce) {
    .rush-clock.low, .rush-chip.show { animation: none; }
}

@media (prefers-reduced-motion: reduce) {
    .budget-strip.low .budget-pips { animation: none; }
}

/* «▶ شرح» visual-demo button in each game HUD */
/* Sizing comes from `.lvl-tools > button`; this only carries the accent that
   marks «شرح» as the helpful one a stuck player should reach for. */
.demo-btn { color: var(--clr-brand-secondary) !important; border-color: var(--clr-brand-secondary) !important; }
/* First visit: pulse once so a new player notices the walkthrough exists. */
.demo-btn.nudge { animation: demoNudge 1.6s ease-in-out 3; }
@keyframes demoNudge {
    0%, 100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(224, 161, 58, 0.5); }
    50% { transform: scale(1.12); box-shadow: 0 0 0 6px rgba(224, 161, 58, 0); }
}

/* ---- Visual demo overlay (شرح مرئي) ---- */
.demo-modal {
    position: fixed; inset: 0; z-index: 270; display: none;
    align-items: center; justify-content: center; padding: 1rem;
    background: rgba(6, 8, 12, 0.72); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.demo-modal.active { display: flex; }
.demo-card {
    position: relative; width: min(94vw, 460px); border-radius: var(--r-lg); padding: 1.4rem 1.3rem 1.2rem;
    background: var(--glass-bg, var(--surface-2)); border: 1px solid var(--glass-border, rgba(255,255,255,0.12));
    box-shadow: 0 24px 70px rgba(0,0,0,0.5); text-align: center;
    animation: demoIn 0.28s cubic-bezier(0.2, 0.9, 0.3, 1.2);
}
@keyframes demoIn { from { opacity: 0; transform: translateY(14px) scale(0.97); } to { opacity: 1; transform: none; } }
.demo-close {
    position: absolute; inset-inline-end: 0.8rem; top: 0.8rem; width: 30px; height: 30px;
    border-radius: 50%; cursor: pointer; font-size: var(--fs-md); line-height: 1;
    background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--clr-text-muted);
}
.demo-close:hover { color: var(--clr-text-main); border-color: var(--clr-brand-primary); }
.demo-head { display: flex; align-items: center; justify-content: center; gap: 0.5rem; margin-bottom: 1rem; }
.demo-emoji { font-size: var(--fs-2xl); }
.demo-title { font-weight: 800; font-size: var(--fs-lg); color: var(--clr-text-main); }
.demo-tag {
    font-size: var(--fs-3xs); font-weight: 700; padding: 0.15rem 0.5rem; border-radius: var(--r-full);
    background: rgba(198,154,74,0.18); color: var(--clr-brand-primary); border: 1px solid rgba(198,154,74,0.4);
}
.demo-stage {
    min-height: 132px; display: flex; align-items: center; justify-content: center;
    padding: 1rem; margin-bottom: 0.9rem; border-radius: var(--r-md);
    background: rgba(255,255,255,0.04); border: 1px solid rgba(255,255,255,0.07);
}
.demo-stage.demo-pop { animation: demoPop 0.32s ease; }
@keyframes demoPop { from { opacity: 0.35; transform: scale(0.96); } to { opacity: 1; transform: none; } }
.demo-row { display: flex; gap: 7px; justify-content: center; flex-wrap: wrap; direction: rtl; }
.demo-cell {
    width: 44px; height: 44px; display: grid; place-items: center; border-radius: var(--r-sm);
    font-size: var(--fs-xl); font-weight: 800; color: var(--clr-text-main);
    background: rgba(255,255,255,0.06); border: 2px solid rgba(255,255,255,0.16);
}
.demo-tiles { display: flex; gap: 7px; justify-content: center; flex-wrap: wrap; max-width: 360px; direction: rtl; }
.demo-tile {
    padding: 0.5rem 0.7rem; border-radius: var(--r-sm); font-size: var(--fs-md); font-weight: 700;
    color: var(--clr-text-main); background: rgba(255,255,255,0.07); border: 1px solid rgba(255,255,255,0.16);
}
.demo-solved { padding: 0.7rem 0.9rem; border-radius: var(--r-md); font-weight: 700; color: var(--ink-0); font-size: var(--fs-md); max-width: 340px; }
.demo-sudoku {
    display: grid; grid-template-columns: repeat(9, 1fr); gap: 1px; background: rgba(255,255,255,0.14);
    border: 2px solid rgba(255,255,255,0.3); border-radius: var(--r-sm); overflow: hidden; width: 198px;
}
.demo-sq { aspect-ratio: 1; display: grid; place-items: center; background: var(--surface-3); font-size: var(--fs-2xs); font-weight: 700; color: var(--clr-text-main); }
.demo-sq.hl { background: var(--surface-4); box-shadow: inset 0 0 0 2px #7fb2e0; }
.demo-cap { color: var(--clr-text-main); font-size: var(--fs-base); line-height: 1.75; min-height: 3.2em; margin-bottom: 0.7rem; }
.demo-dots { display: flex; gap: 7px; justify-content: center; margin-bottom: 1rem; }
.demo-dot { width: 9px; height: 9px; border-radius: 50%; padding: 0; cursor: pointer; border: none; background: rgba(255,255,255,0.22); transition: var(--transition-quick); }
.demo-dot.on { background: var(--clr-brand-primary); transform: scale(1.25); }
.demo-nav { display: flex; gap: 0.5rem; justify-content: center; align-items: center; }
.demo-nav button {
    font: inherit; font-size: var(--fs-xs); font-weight: 700; cursor: pointer;
    padding: 0.4rem 0.9rem; border-radius: var(--r-sm);
    background: var(--glass-bg); border: 1px solid var(--glass-border); color: var(--clr-text-main);
    transition: var(--transition-quick);
}
.demo-nav button:hover:not(:disabled) { border-color: var(--clr-brand-primary); }
.demo-nav button:disabled { opacity: 0.4; cursor: default; }
.demo-play { background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary)) !important; color: var(--gold-900) !important; border-color: transparent !important; }

/* Shared rules modal (opened from card ⓘ and HUD ⓘ).
   Must sit ABOVE the game modals (z-index:150) and toasts (200/210) so the
   ⓘ opened from inside a game paints on top, not behind it. */
#rules-modal { z-index: 260; }
#rules-modal .auth-container { max-width: 460px; text-align: start; }
.rules-body { color: var(--clr-text-muted); line-height: 1.9; font-size: var(--fs-base); margin-top: 0.4rem; }
.rules-title-row { display: flex; align-items: center; gap: 0.6rem; }
.rules-title-row .rules-emoji { font-size: var(--fs-3xl); }

/* Small ⓘ chip on game cards */
.card-info-btn {
    width: 26px; height: 26px; border-radius: 50%; cursor: pointer; flex: none;
    font-size: var(--fs-md); line-height: 1; padding: 0; margin-inline-start: 0.4rem;
    background: rgba(0,0,0,0.35); border: 1px solid var(--glass-border);
    color: var(--clr-text-main); transition: var(--transition-quick);
}
.card-info-btn:hover { border-color: var(--clr-brand-primary); color: var(--clr-brand-primary); }

/* HUD buy-a-hint confirm chip */
.hint-buy { background: linear-gradient(135deg, #ffb347, var(--gold-500)) !important; color: var(--gold-900) !important; }

/* Hint highlights that act on the board */
.lb-letter.hint-cell { animation: strandPulse 0.8s ease-in-out infinite; border-color: var(--clr-brand-secondary); box-shadow: 0 0 14px var(--clr-brand-primary); }
.wordle-tile.hint-ghost, .board-cell.hint-ghost, [id^="cell-"].hint-ghost {
    color: var(--clr-brand-secondary) !important;
    border-color: var(--clr-brand-primary) !important;
    box-shadow: inset 0 0 14px rgba(198, 154, 74, 0.5);
    animation: strandPulse 0.8s ease-in-out infinite;
}
@media (max-width: 560px) {
    .hint-btn { font-size: 0; padding: 0.5rem 0.7rem; }
    .hint-btn .hint-ico, .hint-btn .hint-left { font-size: var(--fs-md); }
}

/* ============================================================
   Round 4 — mission ladder banner
   ============================================================ */
/* شاشة الانتظار حُذفت بقرار المالك (٨ أغسطس ٢٠٢٦) مع كل قواعدها
   (.app-loader / .al-* ومفاتيح alFill · alCamelWalk · alCamelBob · alDots ·
   alFlicker · alGlowPulse · loaderPulse). لا تُعَد: النسيج يُطلى في أول إطار،
   فما كانت تحجبه صفحةٌ جاهزة لا صفحةٌ تُحمَّل. */

/* Daily goal nudge — shown in the daily strip */
.daily-goal { display: inline-flex; align-items: center; gap: 0.4rem; font-size: var(--fs-xs); font-weight: 600; }
.daily-goal.done { color: var(--ok); }
.daily-goal .dg-check { font-size: var(--fs-base); }


/* ============================================================
   Round 16 — Button & UI polish (launch-grade, CSS-only)
   Unifies every interactive button into one premium language:
   consistent radius, a soft gold "sheen", a crisp tactile press,
   and an accessible gold focus ring. RTL-aware. Fully reversible
   — deleting this block restores the previous look.
   ============================================================ */

/* -- Shared accessible focus ring (keyboard nav only) --
   .card-info-btn and .filter-pill were the two real <button>s on the games hub with
   no focus style at all: reachable by Tab but invisible once reached. -- */
.btn-primary:focus-visible,
.btn-play-now:focus-visible,
.conn-btn:focus-visible,
.lvl-next-btn:focus-visible,
.lvl-pick-btn:focus-visible,
.lvl-daily-btn:focus-visible,
.hint-btn:focus-visible,
.card-info-btn:focus-visible,
.filter-pill:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--navy, #0A1628), 0 0 0 5px var(--clr-brand-secondary);
}

/* The card is a container, not a control — it holds two real buttons, so making it
   role="button" would nest interactive elements. Instead it mirrors the hover
   treatment whenever focus lands on anything inside it, so a keyboard user can see
   which card they are in without the card itself entering the tab order. */
.game-card:focus-within {
    border-color: rgba(198, 154, 74, 0.25);
    box-shadow:
        0 22px 50px rgba(0, 0, 0, 0.45),
        0 0 28px rgba(198, 154, 74, 0.10);
}
.game-card:focus-within::after { opacity: 1; }

/* -- Primary gold buttons: premium sheen + tactile press -- */
.btn-primary,
.btn-play-now,
.lvl-next-btn,
.conn-btn.primary {
    position: relative;
    overflow: hidden;
    /* crisp inner highlight (top) + inner shade (bottom) → 3D "coin" feel */
    box-shadow:
        0 4px 18px rgba(198, 154, 74, 0.30),
        inset 0 1px 0 rgba(255, 255, 255, 0.45),
        inset 0 -2px 6px rgba(122, 78, 20, 0.35);
}
/* moving glare that sweeps across on hover */
.btn-primary::before,
.btn-play-now::before,
.lvl-next-btn::before {
    content: '';
    position: absolute;
    top: 0; bottom: 0;
    width: 42%;
    left: -60%;
    background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.55), transparent);
    transform: skewX(-18deg);
    pointer-events: none;
    transition: left 0.55s var(--ease-expo);
}
.btn-primary:hover::before,
.btn-play-now:hover::before,
.lvl-next-btn:hover::before {
    left: 120%;
}
/* حلقة التركيز على الأزرار الذهبيّة تُعاد هنا بعد كتلة «العملة» أعلاه.
   الحلقة المشتركة و«.conn-btn.primary» بدرجة تخصيصٍ واحدة (0,2,0)، والكتلة
   الذهبيّة تليها في الملفّ — وعند التساوي يفوز الأخير، فكان ظلّ الراحة يبتلع
   الحلقة ويختفي أثر التركيز عن أربعة أزرارٍ أساسيّة في الألعاب (قِيس بإجبار
   :focus-visible عبر CDP). إعادتها بعد الكتلة تردّها بلا رفع تخصيصٍ ولا !important. */
.btn-primary:focus-visible,
.btn-play-now:focus-visible,
.lvl-next-btn:focus-visible,
.conn-btn.primary:focus-visible {
    outline: none;
    box-shadow: 0 0 0 3px var(--navy, #0A1628), 0 0 0 5px var(--clr-brand-secondary);
}

.btn-primary:active,
.btn-play-now:active,
.lvl-next-btn:active,
.conn-btn.primary:active {
    transform: translateY(1px) scale(0.985);
    box-shadow:
        0 2px 8px rgba(198, 154, 74, 0.28),
        inset 0 2px 5px rgba(122, 78, 20, 0.45);
}

/* -- Play-now: sliding arrow affordance (RTL → arrow points left) -- */
.btn-play-now { gap: 0.5rem; border-radius: var(--r-sm); letter-spacing: 0.01em; }
.btn-play-now::after {
    content: '←';
    display: inline-block;
    font-weight: 700;
    transform: translateX(6px);
    opacity: 0;
    transition: transform 0.35s var(--ease-expo), opacity 0.3s ease;
}
.btn-play-now:hover::after { transform: translateX(0); opacity: 1; }

/* -- Secondary glass buttons (conn-btn, lvl-pick): softer press -- */
.conn-btn:active:not(:disabled),
.lvl-pick-btn:active { transform: translateY(1px) scale(0.985); }
.conn-btn:not(.primary):hover:not(:disabled) {
    border-color: rgba(201, 162, 39, 0.55);
    box-shadow: 0 3px 14px rgba(0, 0, 0, 0.28);
}
.lvl-pick-btn:hover { box-shadow: 0 3px 12px rgba(0, 0, 0, 0.25); }

/* -- ⓘ rules chip: gentle lift so it reads as tappable -- */
.card-info-btn { transition: var(--transition-quick); }
.card-info-btn:hover { transform: scale(1.12); box-shadow: 0 0 0 3px rgba(201, 162, 39, 0.14); }

/* -- Game cards: refined gold edge-glow + top accent on hover -- */
.game-card::after {
    content: '';
    position: absolute;
    inset: 0;
    border-radius: inherit;
    padding: 1px;
    background: linear-gradient(135deg, rgba(201, 162, 39, 0.55), transparent 42%, transparent 58%, rgba(201, 162, 39, 0.35));
    -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite: xor;
            mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask-composite: exclude;
    opacity: 0;
    transition: opacity 0.4s ease-out;
    pointer-events: none;
}
.game-card:hover::after { opacity: 1; }
/* the `.game-card:hover` shadow that used to sit here is merged into the single
   hover rule above (search "3D card tilt") — one rule, one source of truth. */

@media (prefers-reduced-motion: reduce) {
    .btn-primary::before, .btn-play-now::before, .lvl-next-btn::before { display: none; }
    .btn-play-now::after { transform: none; opacity: 1; }
    .btn-primary:active, .btn-play-now:active, .lvl-next-btn:active,
    .conn-btn.primary:active, .conn-btn:active:not(:disabled), .lvl-pick-btn:active { transform: none; }
}




/* ---- Passive signup nudge -------------------------------------------------
   Deliberately NOT a modal. It appears after a win, the game stays playable
   behind it, and it retires itself. Bottom-anchored and inset-clamped so it
   never covers a game board or the thumb zone on a phone. */
.signup-nudge {
    position: fixed; z-index: 240;
    inset-inline: max(0.75rem, env(safe-area-inset-left)) max(0.75rem, env(safe-area-inset-right));
    bottom: calc(0.9rem + env(safe-area-inset-bottom));
    margin-inline: auto; width: min(440px, 100%);
    display: flex; align-items: center; gap: 0.6rem;
    padding: 0.7rem 0.85rem; border-radius: var(--r-lg);
    background: var(--glass-bg); border: 1px solid var(--glass-border);
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.45);
    backdrop-filter: blur(18px); -webkit-backdrop-filter: blur(18px);
    transform: translateY(130%); opacity: 0;
    transition: transform 0.42s var(--ease-quart), opacity 0.32s ease;
}
.signup-nudge.in { transform: translateY(0); opacity: 1; }
.signup-nudge .sn-ico { font-size: var(--fs-xl); flex: none; }
.signup-nudge .sn-text { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; flex: 1; }
.signup-nudge .sn-text b { font-size: var(--fs-sm); color: var(--clr-text-main); }
.signup-nudge .sn-text small { font-size: var(--fs-2xs); color: var(--clr-text-muted); line-height: 1.35; }
.signup-nudge .sn-cta {
    font: inherit; font-size: var(--fs-xs); font-weight: 700; cursor: pointer; flex: none;
    padding: 0.42rem 0.9rem; border-radius: var(--r-sm); border: none;
    background: linear-gradient(135deg, var(--clr-brand-primary), var(--clr-brand-secondary));
    color: var(--gold-900); transition: var(--transition-quick);
}
.signup-nudge .sn-cta:hover { transform: translateY(-1px); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.3); }
.signup-nudge .sn-x {
    font: inherit; font-size: var(--fs-lg); line-height: 1; cursor: pointer; flex: none;
    width: 26px; height: 26px; border-radius: 50%; padding: 0;
    background: transparent; border: none; color: var(--clr-text-muted);
    transition: var(--transition-quick);
}
.signup-nudge .sn-x:hover { color: var(--clr-text-main); background: rgba(255, 255, 255, 0.08); }
@media (prefers-reduced-motion: reduce) {
    .signup-nudge { transition: opacity 0.2s ease; transform: none; }
    .signup-nudge.in { transform: none; }
    .demo-btn.nudge { animation: none; }
}

/* ---- OAuth entry points ---------------------------------------------------- */
.auth-oauth { display: flex; flex-direction: column; gap: 0.5rem; margin-bottom: 1rem; }
.oauth-btn {
    display: flex; align-items: center; justify-content: center; gap: 0.6rem;
    width: 100%; padding: 0.68rem 1rem; border-radius: var(--r-md); cursor: pointer;
    font: inherit; font-size: var(--fs-md); font-weight: 600;
    background: rgba(255, 255, 255, 0.96); color: var(--surface-3);
    border: 1px solid rgba(0, 0, 0, 0.12);
    transition: var(--transition-quick);
}
.oauth-btn:hover { transform: translateY(-1px); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.28); }
.oauth-btn:disabled { opacity: 0.6; cursor: default; transform: none; box-shadow: none; }
.oauth-btn[data-provider="apple"] { background: #000; color: var(--ink-0); border-color: rgba(255, 255, 255, 0.22); }
.oauth-btn svg { flex: none; }
.auth-or {
    display: flex; align-items: center; gap: 0.7rem;
    margin-top: 0.3rem; color: var(--clr-text-muted); font-size: var(--fs-2xs);
}
.auth-or::before, .auth-or::after {
    content: ''; flex: 1; height: 1px; background: var(--glass-border);
}

/* ---- Signup wizard --------------------------------------------------------- */
.wiz-dots { display: flex; gap: 0.35rem; justify-content: center; margin-bottom: 1rem; }
.wiz-dot {
    width: 26px; height: 3px; border-radius: 2px;
    background: var(--glass-border); transition: background 0.3s ease;
}
.wiz-dot.on { background: var(--clr-brand-primary); }
/* Each step animates in so the flow reads as forward motion, not a redraw. */
.wiz-step { animation: wizIn 0.32s var(--ease-quart); }
.wiz-step[hidden] { display: none; }
@keyframes wizIn {
    from { opacity: 0; transform: translateX(14px); }
    to { opacity: 1; transform: translateX(0); }
}
.wiz-back { display: block; margin: 0.7rem auto 0; }
@media (prefers-reduced-motion: reduce) {
    .wiz-step { animation: none; }
    .oauth-btn:hover { transform: none; }
}


/* ── الدعوة الكبرى للتسجيل ───────────────────────────────────────────────
   تظهر مرة واحدة فقط، بعد ٣ مستويات أو رتبة 👑. تحتفي أولًا وتطلب ثانيًا،
   وتُغلق من ثلاث نقاط (الخرزة، «لاحقاً»، الخلفية) — فهي دعوة لا بوّابة.
   ترث .modal-backdrop/.modal-container فتأخذ قفل التمرير وخرزة الإغلاق مجانًا.
   ─────────────────────────────────────────────────────────────────────── */
.signup-bigask { z-index: 260; }
.signup-bigask .signup-bigask__box {
    width: min(92vw, 420px);
    max-width: 420px;
    aspect-ratio: auto;                     /* .modal-container forces 16/9 */
    background: linear-gradient(160deg, #16233d 0%, var(--navy-deep, var(--surface-0)) 100%);
    border: 1px solid rgba(201, 162, 39, 0.3);
    text-align: center;
}
.signup-bigask .sba-body { padding: 2.2rem 1.6rem 1.6rem; }
.signup-bigask .sba-ico { font-size: var(--fs-6xl); line-height: 1; margin-bottom: 0.5rem; }
.signup-bigask h3 { margin: 0 0 0.6rem; font-size: var(--fs-xl); color: var(--clr-brand-secondary, var(--gold-600)); }
.signup-bigask .sba-what { margin: 0 0 0.5rem; font-weight: 700; font-size: var(--fs-base); }
.signup-bigask .sba-warn { margin: 0 0 1.3rem; font-size: var(--fs-sm); opacity: 0.78; line-height: 1.7; }
.signup-bigask .sba-cta { width: 100%; }
.signup-bigask .sba-later {
    display: block; width: 100%; margin-top: 0.7rem;
    background: none; border: 0; cursor: pointer;
    color: rgba(255, 255, 255, 0.55); font-family: inherit; font-size: var(--fs-sm);
}
.signup-bigask .sba-later:hover { color: rgba(255, 255, 255, 0.85); }

/* ═══ الألعاب على الشاشات الكبيرة ═══════════════════════════════════════
   كانت اللعبة عمودًا بعرض ٥٢٠px وسط شاشة ١٤٤٠ — أقل من ثلث العرض،
   والباقي صفحةُ البيت مموّهة خلفها. النافذة توسّعت، والأهم: أسقف
   `max-width` للوحات ارتفعت، لأن الخلايا نفسها مرنة أصلًا
   (`1fr` + `aspect-ratio`) فما كان يخنقها إلا السقف.
   الخلايا ذات القياس الثابت بالـpx تكبر هنا يدويًا لتواكب اللوحة.
   ═══════════════════════════════════════════════════════════════════════ */
/* The nav bar (z-index 200) sits above the backdrop (150), so it painted over
   the game's HUD at every width. It is unusable while a modal is open anyway. */
body.sura-game-open .header { display: none; }

@media (min-width: 769px) {
    .modal-backdrop.active .game-modal-container,
    .modal-backdrop.active .wordle-modal-container {
        width: min(94vw, 880px);
        max-width: min(94vw, 880px);
        max-height: 94vh;
    }

    /* اللوحات المرنة: يكفي رفع السقف */
    .strands-board { max-width: 560px; gap: 9px; }
    .tiles-board   { max-width: 560px; gap: 11px; }
    /* vh-bound, not just px: the number pad sits below the grid and a
       520px board pushed it off screen on a 900px-tall display. */
    .sudoku-board  { max-width: min(520px, 46vh); }
    .conn-grid     { max-width: 640px; margin-inline: auto; gap: 9px; }

    /* لوحات بقياس ثابت: تكبر مع النافذة */
    .strand-cell   { font-size: var(--fs-3xl); }
    .zellige-tile .zt-glyph { font-size: var(--fs-6xl); }
    .sudoku-cell   { font-size: var(--fs-2xl); }
    .board-cell    { width: 68px; height: 68px; font-size: var(--fs-4xl); }
    .bee-cell      { width: 84px; height: 95px; font-size: var(--fs-5xl); }
    /* The rails are inset by a fixed px calibrated against the 300px box, so
       the letters CANNOT be grown on their own — the corner circles collide.
       Scale the whole geometry by the same 4/3 factor instead. */
    .lb-box    { width: 400px; height: 400px; }
    .lb-letter { width: 64px; height: 64px; font-size: var(--fs-4xl); }
    .lb-top    { top: 8px; left: 56px; right: 56px; }
    .lb-bottom { bottom: 8px; left: 56px; right: 56px; }
    .lb-left   { left: 8px; top: 56px; bottom: 56px; }
    .lb-right  { right: 8px; top: 56px; bottom: 56px; }

    /* النصوص الطويلة تتنفّس بدل ما تبقى بعرض عمود ضيّق */
    .amthal-meaning { max-width: 700px; font-size: var(--fs-lg); }
    .amthal-type    { max-width: 760px; }
}

/* ============================================================================
   Reduced motion — the INFINITE loops, gathered.
   The file already had nine `prefers-reduced-motion` blocks, but each was written
   next to whatever component it belonged to, and every one of them covered a
   one-shot entrance. The animations that never stop — a badge that pulses forever,
   a hint cell that throbs until you solve it, a timer that flashes while it runs —
   were the ones still playing for a visitor who explicitly asked the OS for less
   motion, which is exactly backwards: a finite entrance is a blink, an infinite
   loop is the thing that actually triggers vestibular discomfort.
   Collected in one block rather than scattered so the set stays auditable: if a
   new `infinite` animation is added anywhere, it belongs in this list.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
    /* pulseGlow — "العب الآن" badge on every game card */
    .live-badge { animation: none; }

    /* strandPulse — hint highlighting across five different game boards */
    .strand-cell.hint-cell,
    .amthal-wbox.hint-cell,
    .zellige-tile.hint-cell,
    .lb-letter.hint-cell,
    .wordle-tile.hint-ghost,
    .board-cell.hint-ghost,
    [id^="cell-"].hint-ghost { animation: none; }

    /* nextPulse — the «التالي» level-advance button */
    .lvl-next-btn { animation: none; }

    /* budget-pulse — low guess budget / low rush clock */
    .budget-strip.low .budget-pips,
    .rush-clock.low { animation: none; }

    /* warmer-flick — card hover teasers and the zayid countdown */
    .game-card:hover .warmer-row.is-hot .warmer-tag,
    .game-card:hover .zayid-vrow.fold,
    .zayid-timer.low { animation: none; }
}

/* ============================================================================
   المرحلة هـ — «أبلغ وقيّم». يحلّ محلّ «الأرشيف الأدبي» في آخر قسم الألعاب.

   ملاحظتان معماريّتان مقصودتان:

   ١. لا `opacity` في مدخل البطاقتين. `.archive-card` كان يبدأ من `opacity: 0`
      ويحرّكها، وهذه البطاقات أحفادُ `.scroll-section` تمامًا مثله — وقد ثبت أن
      سفاري iOS يُجمّد إطار `from` عند العودة إلى التبويب فتبقى الكتلة بيضاء.
      الكشف هنا بالإزاحة وحدها، وهو القرار نفسه المثبَّت في هيرو الصفحة.

   ٢. الحقول تُبنى بالتوكنز لا بألوان صريحة، فالوضع الفاتح يتبعها بلا كتلة
      ثانية — عدا الحدّ والخلفيّة الزجاجيّة اللذين يحتاجان نفاذيّةً مختلفة.
   ============================================================================ */
.feedback-section {
    display: flex;
    flex-direction: column;
    gap: 2.2rem;
    margin-top: 1rem;
}

.feedback-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
    gap: 1.6rem;
    width: 100%;
    /* stretch, not start: two cards of different content lengths ending at
       different heights is the single loudest sign of an unconsidered layout.
       The forms below push their submit row down with `margin-top: auto`. */
    align-items: stretch;
}

/* TRANSPARENT ON PURPOSE (owner's call: «خل الخلفيه شفافه»). This card used to
   be a frosted panel — `rgba(15,23,42,.4)` over a `backdrop-filter` blur — which
   made it the only opaque block in a page whose whole backdrop is the film or the
   Sadu weave. The fill and the blur are both gone: what remains is a hairline and
   the fields themselves, which carry their own contrast, so the backdrop reads
   straight through the card the way it does everywhere else on the page.
   Dropping the blur is also free performance — it was a full-size compositing
   pass on two large elements. */
.fb-card {
    position: relative;
    height: 100%;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-radius: var(--r-lg);
    padding: 1.5rem 1.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    /* No drop shadow: a shadow claims the card is a solid surface floating above
       the page, and it is not one any more. */
    transform: translateY(26px);
    animation: fbRise 0.7s var(--ease-expo) var(--delay, 0s) forwards;
    /* والنصّ يحمل هالته لا خلفيّته. الحقول عولجت بتعبئتها الخاصّة (أسفل)،
       لكنّ العناوين والشرح والتسميات بقيت حروفًا عاريةً فوق نقشٍ عالي التردّد
       فتذوب فيه. وإضافة خلفيّةٍ للبطاقة تنقض «خل الخلفيه شفافه» صراحةً، أمّا
       الظلّ فخاصّيّةُ نصٍّ لا خاصّيّةُ سطح: النقش يبقى مرئيًّا كاملًا خلف
       الحروف، والحروف تُقرأ. وهو يرث إلى كلّ الأحفاد، فلا قائمةَ عناصر
       تنحرف لاحقًا. */
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 10px rgba(0, 0, 0, 0.75);
}

/* إلّا الزرّ: حرفُه داكنٌ على ذهبٍ مضيء، فالهالة السوداء تلطّخه ولا تعينه. */
.fb-submit { text-shadow: none; }

@keyframes fbRise { to { transform: translateY(0); } }

@media (prefers-reduced-motion: reduce) {
    .fb-card { animation: none; transform: none; }
}

.fb-card:focus-within { border-color: rgba(198, 154, 74, 0.28); }

/* The head borrows the game cards' own hierarchy — a small Latin kicker over the
   Arabic title (`.game-english-title` / `.game-arabic-title`) — so this section
   reads as part of the site rather than a support form pasted onto it. The
   emoji that used to sit in the <h3> are gone for the same reason: nothing else
   on the page labels itself with one. */
.fb-card-head {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
    column-gap: 0.75rem;
    row-gap: 0.1rem;
}

.fb-kicker {
    grid-column: 1;
    font-size: var(--fs-3xs);
    font-weight: 600;
    letter-spacing: 0.15em;
    color: var(--clr-brand-secondary);
    opacity: 0.9;
}

.fb-title {
    grid-column: 1;
    font-size: var(--fs-2xl);
    font-weight: 700;
    color: var(--clr-text-main);
}

.fb-demo-btn {
    grid-column: 2;
    grid-row: 1 / span 2;
    position: relative;
    background: rgba(198, 154, 74, 0.05);
    border: 1px solid rgba(198, 154, 74, 0.28);
    color: var(--clr-brand-secondary);
    border-radius: 999px;
    padding: 0.38rem 0.9rem;
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
    transition: transform var(--dur-3) var(--ease-expo),
                color var(--dur-3) var(--ease-expo),
                border-color var(--dur-3) var(--ease-expo),
                background-color var(--dur-3) var(--ease-expo),
                box-shadow var(--dur-3) var(--ease-expo);
}

.fb-demo-btn:hover,
.fb-demo-btn:focus-visible {
    transform: translateY(-1px);
    color: var(--gold-300);
    background: rgba(198, 154, 74, 0.14);
    border-color: rgba(232, 200, 106, 0.55);
    box-shadow: 0 4px 16px rgba(198, 154, 74, 0.22);
}

.fb-demo-btn:active { transform: translateY(0) scale(0.97); }
.fb-demo-btn:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 3px; }

.fb-card-desc {
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
    line-height: 1.6;
    max-width: 46ch;
}

.fb-form {
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
    margin-top: 0.2rem;
    flex: 1;
}

.fb-field { display: flex; flex-direction: column; gap: 0.3rem; }

/* Dictation sits on the label line, not floating in the corner of the box. In
   the corner it read as a stray artifact — and in RTL it collided with the
   textarea's own resize grip, which is why that grip is gone too. */
.fb-label-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 0.6rem;
}

.fb-label {
    font-size: var(--fs-sm);
    font-weight: 700;
    color: var(--clr-text-main);
}

.fb-label em {
    font-style: normal;
    font-weight: 400;
    color: var(--clr-text-muted);
}

/* ── the star rating that rides with a suggestion ──────────────────────────
   Owner's call: «خل الاقتراح مع التقييم». It is optional, and says so in the
   label — a required star would rebuild the very ceremony that was cut from the
   report form.

   RTL: the row is `row-reverse` so the first star sits on the RIGHT, where an
   Arabic reader's eye starts. Left-to-right stars in an RTL card make «three of
   five» read backwards. */
.fb-optional {
    font-weight: 400;
    font-size: 0.86em;
    color: var(--clr-text-muted);
}

.fb-stars {
    display: flex;
    flex-direction: row-reverse;
    justify-content: flex-end;
    align-items: center;
    gap: 0.15rem;
    padding-top: 0.1rem;
}

.fb-star {
    background: none;
    border: 0;
    padding: 0.1rem 0.12rem;
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
    /* Unlit stars are outlines of the same gold, not grey: grey reads as
       disabled, and these are very much available. */
    color: rgba(255, 255, 255, 0.18);
    transition: color var(--dur-2, 0.2s) ease, transform var(--dur-2, 0.2s) var(--ease-expo, ease);
}

.fb-star.on { color: var(--gold-300); }

/* Hovering a star lights it AND every star before it, which is what makes the
   control legible without a legend. `~` walks forward in DOM order, and because
   the row is `row-reverse` that is visually backwards — i.e. exactly the lower
   ratings, which is the intent. */
.fb-stars:hover .fb-star { color: rgba(255, 255, 255, 0.18); }
.fb-stars .fb-star:hover,
.fb-stars .fb-star:hover ~ .fb-star { color: var(--gold-300); }

.fb-star:hover { transform: translateY(-2px); }
.fb-star:focus-visible {
    outline: 2px solid var(--gold-300);
    outline-offset: 2px;
    border-radius: 4px;
}

.fb-star-note {
    margin-inline-start: 0.5rem;
    font-size: var(--fs-sm);
    color: var(--clr-text-muted);
    /* Reserves its line so picking a star does not nudge the textarea down. */
    min-height: 1em;
}

@media (prefers-reduced-motion: reduce) {
    .fb-star { transition: color var(--dur-2, 0.2s) ease; }
    .fb-star:hover { transform: none; }
}

/* الحقول تحمل تباينها بنفسها.
   البطاقة شفّافةٌ بقرار المالك («خل الخلفيه شفافه») وتبقى كذلك — لكنّ النَّول
   (`.loom-near`، z-index 2، opacity 1) يمرّ قُطريًّا تحت قسم «أبلغ وقيّم»
   ببرتقاليٍّ مشبع، فيُقرأ من خلال البطاقة الشفّافة. وقيس على المقاسين: نصّ
   الحقل النائب يختفي في النقش، ونجوم التقييم على الجوّال لا تكاد تُميَّز عنه.
   والقسم المصاب هو **نموذج البلاغ** تحديدًا — أوّل ما يحتاجه إطلاقٌ أن يعمل.
   `0.22` كانت تكفي فوق الليل ولا تكفي فوق النقش؛ و`0.55` تُعيد الحقل حقلًا
   دون أن تُعيد للبطاقة خلفيّةً حُذفت عمدًا. */
.fb-form textarea,
.fb-select {
    width: 100%;
    background: rgba(0, 0, 0, 0.55);
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: var(--r-md);
    color: var(--clr-text-main);
    font-family: inherit;
    font-size: var(--fs-sm);
    line-height: 1.6;
    padding: 0.55rem 0.7rem;
    resize: none;
    transition: border-color var(--dur-2, 0.2s) ease;
}

.fb-form textarea:focus,
.fb-select:focus {
    outline: none;
    border-color: var(--clr-brand-secondary);
}

.fb-form textarea::placeholder { color: var(--clr-text-muted); opacity: 0.7; }

/* زرٌّ لا رابط. كان نصًّا عاريًا بجانب العنوان فلم يُقرأ زرًّا أصلًا (ملاحظة
   المالك: «زر المايك مو واضح»)، فصار حبّةً محدودةً بخلفيّة — والعرض ثابتٌ
   بأرقامٍ جدوليّة كي لا يرتجف العدّاد وهو يعدّ ثوانيك. */
.fb-mic {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    flex: 0 0 auto;
    border: 1px solid rgba(255, 255, 255, 0.16);
    background: rgba(255, 255, 255, 0.05);
    border-radius: 999px;
    padding: 0.24rem 0.62rem;
    color: var(--clr-text-muted);
    font-family: inherit;
    font-size: var(--fs-3xs);
    font-weight: 600;
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
    cursor: pointer;
    transition: color var(--dur-2, 0.2s) ease,
                border-color var(--dur-2, 0.2s) ease,
                background-color var(--dur-2, 0.2s) ease;
}

/* A drawn dot rather than the 🎙 glyph: the emoji rendered at a different
   weight and baseline than every other mark on the page, which is exactly what
   made the corner button look like a rendering artifact. */
.fb-mic-dot {
    position: relative;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 50%;
    background: currentColor;
    opacity: 0.55;
    transition: transform var(--dur-3) var(--ease-expo), opacity var(--dur-2) ease;
}

.fb-mic:hover,
.fb-mic:focus-visible {
    color: var(--gold-300);
    border-color: rgba(198, 154, 74, 0.55);
    background: rgba(198, 154, 74, 0.10);
}
.fb-mic:hover .fb-mic-dot { opacity: 1; transform: scale(1.15); }
.fb-mic:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 3px; }

/* السطر تحت الحقل يقول القاعدة بصريح العبارة، ولا يظهر إلا والمايك مفتوح:
   تحذيرٌ دائمٌ عن حالةٍ نادرة هو ضجيج. */
.fb-mic-hint {
    display: block;
    margin-top: 0.35rem;
    font-size: var(--fs-3xs);
    line-height: 1.5;
    color: #ffb4b4;
    opacity: 0.9;
}

/* Recording has to be unmistakable: a mic that looks the same whether or not it
   is listening is a privacy problem, not a styling one. */
.fb-mic.rec {
    color: #ff9d9d;
    border-color: rgba(224, 85, 85, 0.55);
    background: rgba(224, 85, 85, 0.12);
}

.fb-mic.rec .fb-mic-dot {
    opacity: 1;
    background: #e05555;
    animation: fbPulse 1.1s ease-in-out infinite;
}

/* حلقةٌ تتّسع وتتلاشى حول النقطة — «يستمع الآن» يُقرأ من طرف العين. */
.fb-mic.rec .fb-mic-dot::after {
    content: "";
    position: absolute;
    inset: -3px;
    border-radius: 50%;
    border: 1.5px solid #e05555;
    animation: fbRipple 1.6s var(--ease-expo) infinite;
}

@keyframes fbPulse { 50% { box-shadow: 0 0 0 4px rgba(220, 68, 68, 0.18); } }

@keyframes fbRipple {
    0%   { transform: scale(0.7); border-color: rgba(224, 85, 85, 0.9); }
    100% { transform: scale(2.2); border-color: rgba(224, 85, 85, 0); }
}

/* دوران ٩٠° عند التحويم: زرّ الإغلاق يقول «✕» ثم يقولها أوضح. */
.fb-thumb-x { transition: transform var(--dur-3) var(--ease-expo), background-color var(--dur-3) var(--ease-expo); }
.fb-thumb-x:hover { transform: rotate(90deg); background: rgba(224, 115, 111, 0.9); }
.fb-thumb-x:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 2px; }

/* السكون يُحترم: كلّ ما فوق زينةٌ لا رسالة، عدا لونَي «يسجّل» و«مُعطَّل». */
@media (prefers-reduced-motion: reduce) {
    .fb-mic.rec,
    .fb-mic.rec .fb-mic-dot,
    .fb-mic.rec .fb-mic-dot::after,
    .fb-submit:disabled,
    .fb-verdict.on,
    .fb-star.on { animation: none; }

    .fb-submit::after { display: none; }
    .fb-submit:hover:not(:disabled),
    .fb-demo-btn:hover,
    .fb-attach:hover,
    .fb-star:hover { transform: none; }

    .fb-verdicts.seg::before { transition: none; }
}

/* One child now, not two: the character counter that used to sit opposite the
   context line is gone with the 40-character minimum it enforced. So the row is
   no longer `space-between` — with a single child that would have parked the
   text on one edge for no reason. */
/* الوضع الفاتح: حدودُ ٦٪ بيضاء على ورقٍ فاتح = لا حدود. قِيس على لقطةٍ فعليّة —
   كانت حبّة المايك تختفي تمامًا، وهو نفس العطب الذي أُصلح لأجله أصلًا. */
html[data-theme="light"] .fb-mic {
    border-color: rgba(28, 25, 23, 0.22);
    background: rgba(28, 25, 23, 0.04);
}
html[data-theme="light"] .fb-mic:hover,
html[data-theme="light"] .fb-mic:focus-visible {
    border-color: var(--gold-600);
    background: rgba(198, 154, 74, 0.16);
}
html[data-theme="light"] .fb-mic.rec {
    color: #a12a2a;
    border-color: rgba(161, 42, 42, 0.5);
    background: rgba(224, 85, 85, 0.12);
}
html[data-theme="light"] .fb-mic.rec .fb-mic-dot { background: #b22a2a; }
html[data-theme="light"] .fb-mic-hint { color: #a12a2a; opacity: 1; }
html[data-theme="light"] .fb-strength-bar { background: rgba(28, 25, 23, 0.12); }

/* شريطٌ يُنسج لا يمتلئ: التعبئة تتحرّك من اليمين إلى اليسار — اتجاه المكوك على
   النَّول العربيّ ونفس اتجاه `weaveRTL` في الهيرو. `transform: scaleX` وحده
   (لا `width`) كي تبقى الحركة على المُركِّب بلا إعادة تخطيط عند كل ضغطة مفتاح. */
.fb-strength {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    margin-top: 0.15rem;
}

.fb-strength-bar {
    position: relative;
    flex: 1 1 auto;
    height: 3px;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.08);
    overflow: hidden;
}

.fb-strength-bar > i {
    position: absolute;
    inset: 0;
    transform-origin: 100% 50%;              /* من اليمين، كالمكوك */
    transform: scaleX(var(--v, 0));
    background: linear-gradient(90deg, var(--gold-600), var(--gold-300));
    transition: transform 420ms var(--ease-expo);
}

.fb-strength.full .fb-strength-bar > i {
    box-shadow: 0 0 10px rgba(201, 162, 39, 0.45);
}

.fb-strength-word {
    flex: 0 0 auto;
    font-size: var(--fs-3xs);
    color: var(--clr-text-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 60%;
}

.fb-strength.full .fb-strength-word { color: var(--gold-300); }

@media (prefers-reduced-motion: reduce) {
    .fb-strength-bar > i { transition: none; }
}

.fb-meter {
    display: flex;
    gap: 0.75rem;
    font-size: var(--fs-3xs);
    color: var(--clr-text-muted);
    padding-top: 0.15rem;
    border-top: 1px solid rgba(255, 255, 255, 0.05);
}

.fb-slice {
    opacity: 0.75;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* `margin-top: auto` is what keeps the two cards' submit rows on the same line
   even though the rating card has less above it. */
.fb-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    flex-wrap: wrap;
    margin-top: auto;
    padding-top: 0.5rem;
}

/* الزرّ الثانويّ: إطارٌ متقطّعٌ يصير مصمتًا حين يُقصَد، وأيقونة صورةٍ مرسومةٌ
   بالـCSS لا بإيموجي — الإيموجي يأتي بوزنه وخطّ أساسه فيبدو دخيلًا. */
.fb-attach {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: var(--fs-3xs);
    color: var(--clr-text-muted);
    cursor: pointer;
    border: 1px dashed rgba(255, 255, 255, 0.18);
    border-radius: 999px;
    padding: 0.42rem 0.95rem;
    background: rgba(255, 255, 255, 0.015);
    transition: color var(--dur-3) var(--ease-expo),
                border-color var(--dur-3) var(--ease-expo),
                background-color var(--dur-3) var(--ease-expo),
                transform var(--dur-3) var(--ease-expo);
}

/* إطارٌ صغيرٌ بنقطة = «صورة». شكلٌ محضٌ من الحدود، بلا أصلٍ خارجيّ. */
.fb-attach::before {
    content: "";
    width: 0.62rem;
    height: 0.52rem;
    border: 1.2px solid currentColor;
    border-radius: 2px;
    box-shadow: inset -1.6px -1.6px 0 -0.6px currentColor;
    transition: transform var(--dur-3) var(--ease-expo);
}

.fb-attach:hover,
.fb-attach:focus-within {
    color: var(--gold-300);
    border-color: rgba(198, 154, 74, 0.5);
    border-style: solid;
    background: rgba(198, 154, 74, 0.07);
    transform: translateY(-1px);
}

.fb-attach:hover::before { transform: rotate(-6deg) scale(1.08); }
.fb-attach:focus-within { outline: 2px solid rgba(227, 197, 133, 0.45); outline-offset: 3px; }

/* ---------------------------------------------------------------------------
   الزرّ الأساسيّ: ذهبٌ مصبوبٌ لا لونٌ مسطّح.
   ثلاث طبقاتٍ تصنع «المعدن»: تدرّجٌ رأسيّ (الجسم)، خطٌّ داخليّ فاتحٌ أعلى
   وداكنٌ أسفل (الحافّة المشطوفة)، وهالةٌ ذهبيّةٌ تحته (الوهج).
   والحركة كلّها `transform` و`box-shadow` — لا `opacity` على أحفاد
   `.scroll-section`، وهي القاعدة التي يجمّد خرقُها iOS Safari.
--------------------------------------------------------------------------- */
.fb-submit {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: linear-gradient(170deg, var(--gold-300) 0%, var(--gold-500) 52%, var(--gold-700) 100%);
    color: #17110a;
    border: none;
    border-radius: 999px;
    padding: 0.58rem 1.6rem;
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: 800;
    letter-spacing: normal;
    cursor: pointer;
    box-shadow:
        inset 0 1px 0 rgba(255, 246, 224, 0.55),
        inset 0 -1px 0 rgba(80, 48, 8, 0.35),
        0 2px 10px rgba(198, 154, 74, 0.22);
    transition: transform var(--dur-3) var(--ease-expo),
                box-shadow var(--dur-3) var(--ease-expo),
                filter var(--dur-3) var(--ease-expo);
}

/* بريقٌ يعبر الزرّ مرّةً عند التحويم. عرضه ٤٥٪ وميلُه ٢٠°، ويقف خارج الحافّة
   في الحالتين فلا يُرى إلا وهو يمرّ. */
.fb-submit::after {
    content: "";
    position: absolute;
    inset: -40% -60%;
    z-index: -1;
    background: linear-gradient(105deg,
        transparent 38%,
        rgba(255, 252, 240, 0.55) 48%,
        rgba(255, 252, 240, 0.75) 51%,
        transparent 62%);
    transform: translateX(-115%);
    transition: transform 720ms var(--ease-expo);
}

.fb-submit:hover:not(:disabled),
.fb-submit:focus-visible:not(:disabled) {
    transform: translateY(-2px);
    filter: saturate(1.06);
    box-shadow:
        inset 0 1px 0 rgba(255, 250, 232, 0.7),
        inset 0 -1px 0 rgba(80, 48, 8, 0.4),
        0 6px 20px rgba(198, 154, 74, 0.4),
        0 0 0 1px rgba(232, 200, 106, 0.35);
}

/* في RTL يعبر البريق من اليمين إلى اليسار — الاتّجاه الذي تقرأ به العين. */
.fb-submit:hover:not(:disabled)::after { transform: translateX(115%); }

.fb-submit:active:not(:disabled) {
    transform: translateY(1px) scale(0.985);
    box-shadow:
        inset 0 2px 6px rgba(80, 48, 8, 0.45),
        0 1px 4px rgba(198, 154, 74, 0.18);
}

.fb-submit:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 3px; }

/* «جارٍ الإرسال» حالةٌ لها شكل: شرائط تزحف بدل زرٍّ باهتٍ ميّت. */
.fb-submit:disabled {
    cursor: progress;
    color: rgba(23, 17, 10, 0.65);
    background-image:
        linear-gradient(170deg, var(--gold-300) 0%, var(--gold-500) 52%, var(--gold-700) 100%),
        repeating-linear-gradient(115deg,
            rgba(255, 255, 255, 0.16) 0 10px,
            rgba(0, 0, 0, 0.06) 10px 20px);
    background-size: 100% 100%, 200% 100%;
    background-blend-mode: normal, overlay;
    box-shadow: inset 0 1px 0 rgba(255, 246, 224, 0.3);
    animation: fbBusy 900ms linear infinite;
}

@keyframes fbBusy {
    to { background-position: 0 0, 40px 0; }
}

.fb-thumb { position: relative; align-self: flex-start; }

.fb-thumb img {
    max-width: 160px;
    max-height: 110px;
    border-radius: var(--r-md);
    border: 1px solid rgba(255, 255, 255, 0.12);
    display: block;
}

.fb-thumb-x {
    position: absolute;
    top: -8px;
    left: -8px;
    width: 1.5rem;
    height: 1.5rem;
    border-radius: 50%;
    border: none;
    background: rgba(0, 0, 0, 0.75);
    color: #fff;
    font-size: 0.75rem;
    cursor: pointer;
}

.fb-status { font-size: var(--fs-sm); min-height: 1.2em; color: var(--clr-text-muted); }
.fb-status.ok { color: #6fbf73; }
.fb-status.err { color: #e0736f; }

/* A segmented control, not three loose slabs. The three answers are one choice
   with three positions, and a single enclosing track says that where three
   equally-weighted bordered boxes said the opposite. */
.fb-verdicts {
    position: relative;
    display: flex;
    gap: 2px;
    padding: 3px;
    border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.28);
    box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.4), 0 1px 0 rgba(255, 255, 255, 0.04);
}

/* الإبهام المنزلق. الأزرار الثلاثة `flex: 1 1 0` فعرضها واحد، فتكفي خطوةٌ
   بنسبة ١٠٠٪. الصفحة RTL: البند رقم i يقع يسارًا بمقدار i، فالإزاحة سالبة.
   `--i` يضبطها JS عند الاختيار (`bindVerdicts`).
   محصورٌ بـ`.seg` لأن نسخة ما بعد الفوز `flex: 0 1 auto` بعرضٍ غير متساوٍ. */
.fb-verdicts.seg::before {
    content: "";
    position: absolute;
    top: 3px;
    bottom: 3px;
    right: 3px;
    width: calc((100% - 10px) / 3);
    border-radius: 999px;
    background: linear-gradient(165deg, rgba(232, 200, 106, 0.3), rgba(198, 154, 74, 0.16));
    box-shadow:
        inset 0 0 0 1px rgba(232, 200, 106, 0.5),
        inset 0 1px 0 rgba(255, 245, 220, 0.25),
        0 2px 10px rgba(198, 154, 74, 0.25);
    transform: translateX(calc(var(--i, 0) * -100% - var(--i, 0) * 2px)) scaleX(0.001);
    transform-origin: center;
    transition: transform 420ms var(--ease-expo);
    pointer-events: none;
}

/* لا يظهر قبل أوّل اختيار: `scaleX(0.001)` بدل `opacity: 0` — القاعدة نفسها. */
.fb-verdicts.seg.picked::before {
    transform: translateX(calc(var(--i, 0) * -100% - var(--i, 0) * 2px)) scaleX(1);
}

.fb-verdict {
    position: relative;
    z-index: 1;
    flex: 1 1 0;
    background: none;
    border: 0;
    border-radius: 999px;
    color: var(--clr-text-muted);
    font-family: inherit;
    font-size: var(--fs-sm);
    font-weight: 600;
    padding: 0.48rem 0.5rem;
    cursor: pointer;
    white-space: nowrap;
    transition: color var(--dur-3) var(--ease-expo), transform var(--dur-2) var(--ease-expo);
}

.fb-verdict:hover { color: var(--clr-text-main); }
.fb-verdict:active { transform: scale(0.96); }
.fb-verdict:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 2px; }

.fb-verdict.on {
    color: var(--gold-300);
    animation: fbPick 380ms var(--ease-expo);
}

/* الإبهام يوفّر الخلفيّة في النسخة المقسَّمة؛ أمّا نسخة ما بعد الفوز فتحتاج
   خلفيّتها الخاصّة. */
.fb-verdicts:not(.seg) .fb-verdict.on {
    background: rgba(198, 154, 74, 0.18);
    box-shadow: inset 0 0 0 1px rgba(198, 154, 74, 0.45);
}

@keyframes fbPick {
    0%   { transform: scale(0.94); }
    55%  { transform: scale(1.04); }
    100% { transform: scale(1); }
}

/* ونجومُ التقييم كذلك. زرٌّ لا يُرى قبل أن يُضغط ليس زرًّا — والنجوم كانت
   بلا أيّ أرضيّة فوقعت على نقش النَّول مباشرةً، وعلى الجوّال لم تكد تُميَّز
   عنه. حبّةٌ ضيّقة تلفّ الصفّ وحده (`width: max-content` قائمٌ أصلًا)، لا
   لوحًا يعيد ملء البطاقة الشفّافة. */
.fb-stars {
    display: flex;
    gap: 0.2rem;
    width: max-content;
    padding: 0.15rem 0.5rem;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 999px;
}

/* النجمة تُملأ بتدرّجٍ لا بلونٍ واحد — الحرف يُقصّ على التدرّج بـ
   `background-clip: text`، فيصير للنجمة قمّةٌ فاتحةٌ وقاعٌ عميق. */
.fb-star {
    background: none;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    color: rgba(198, 154, 74, 0.28);
    cursor: pointer;
    padding: 0 0.1rem;
    transform-origin: 50% 65%;
    transition: color var(--dur-2) var(--ease-expo),
                transform 340ms var(--ease-expo),
                filter var(--dur-3) var(--ease-expo);
}

/* التحويم يُشعل الصفّ كلّه بخفوت، والمؤشَّر عليه وحده يعلو. */
.fb-stars:hover .fb-star { color: rgba(198, 154, 74, 0.45); }
.fb-star:hover { transform: translateY(-2px) scale(1.12); }
.fb-star:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 2px; border-radius: 4px; }

.fb-star.on,
.fb-stars:hover .fb-star.on {
    background-image: linear-gradient(170deg, #fff2cf 0%, var(--gold-300) 38%, var(--gold-600) 100%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    filter: drop-shadow(0 1px 5px rgba(201, 162, 39, 0.45));
    animation: fbStar 420ms var(--ease-expo);
}

@keyframes fbStar {
    0%   { transform: scale(0.7) rotate(-14deg); }
    60%  { transform: scale(1.18) rotate(4deg); }
    100% { transform: scale(1) rotate(0); }
}

/* The post-win one-tap question. Lives inside the win panel, not here, but its
   look belongs with the rest of the rating UI. */
.rate-inline {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    align-items: center;
    margin-top: 0.9rem;
    padding-top: 0.9rem;
    border-top: 1px solid rgba(255, 255, 255, 0.08);
}

.rate-inline .rate-q { font-size: var(--fs-sm); color: var(--clr-text-muted); }
.rate-inline .fb-verdicts { justify-content: center; }
.rate-inline .fb-verdict { flex: 0 1 auto; padding: 0.4rem 0.8rem; }

/* اللوح العائم بعد الفوز. z-index 220 لأنّ نافذة اللعبة 150 والتوست 200/210،
   وهذا يُسأل فوق لوح الفوز نفسه. لا `opacity` في الحركة — القاعدة نفسها. */
.rate-sheet {
    position: fixed;
    inset-inline: 0;
    bottom: max(1rem, env(safe-area-inset-bottom));
    z-index: 220;
    display: flex;
    justify-content: center;
    pointer-events: none;
}

.rate-sheet .rate-inline {
    pointer-events: auto;
    margin-top: 0;
    padding: 0.85rem 1.1rem;
    border-top: 0;
    border: 1px solid var(--clr-border, rgba(255, 255, 255, 0.12));
    border-radius: 14px;
    background: var(--clr-surface-2, rgba(18, 18, 22, 0.94));
    backdrop-filter: blur(10px);
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
    max-width: min(94vw, 30rem);
    animation: fbRise 320ms cubic-bezier(0.22, 1, 0.36, 1) both;
}

@media (prefers-reduced-motion: reduce) {
    .rate-sheet .rate-inline { animation: none; transform: none; }
}

@media (max-width: 600px) {
    .fb-card { padding: 1.25rem 1.1rem; }
    .fb-actions { justify-content: stretch; }
    .fb-submit { flex: 1 1 100%; }
}

/* ============================================================================
   ما تبقّى من كتلة «الجَمل المضاء» بعد حذفه: قاعدةٌ واحدة لا علاقة لها بالجَمل.
   المعطّل لا يقول «انقر» — والمتصفّح لا يقولها وحده على <button disabled>.
   وموضعها آخر الملف ما زال مقصودًا: نحو أربعين قاعدة فوق تقول `cursor: pointer`
   بنفس درجة التخصيص، وعند التساوي يفوز الأخير.
   ============================================================================ */
@media (pointer: fine) {
    button:disabled, input:disabled, select:disabled, textarea:disabled,
    [aria-disabled="true"], .hint-btn.spent {
        cursor: not-allowed;
    }
}

/* ============================================================
   حركة اللوح — على الرسمة نفسها، لا فوقها
   ============================================================
   بديل طبقة لوتي التي حُذفت في ١٣ أغسطس ٢٠٢٦ بقرار المالك: «الحركات
   سيّئة، ما تناسب كل صورة، مو راكبة بالضبط عليها». وكان محقًّا، والعلّة
   في الأداة لا في الضبط — لوتي لوحٌ ثابت المقاس يُركَّب فوق البطاقة،
   وألواحُنا HTML مرنةٌ تتغيّر بعرض الشاشة. فكانت النتيجة رسمتين لشيءٍ
   واحد فوق بعضهما، ولو ضُبطت اليوم بالبكسل لانفكّت عند أوّل تعديل CSS.

   القاعدة هنا: **تتحرّك الخانةُ الحقيقيّةُ نفسها**. فهي منطبقةٌ دائمًا
   لأنّها هي الرسمة، وتتبع الشاشة لأنّها في التدفّق نفسه، وتكلفتها صفر
   بايت — لا مشغّل ولا ملفّ ولا طلبَ شبكة.

   ولا `opacity` في أيّ إطارٍ مفتاحيّ هنا. القاعدة في style.css:118-143:
   أحفاد `.scroll-section` لا تُحرَّك شفافيّتهم أبدًا — سفاري iOS يجمّد
   إطار `from` عند عودة قسمٍ ثابتٍ من display:none، فيبقى المحتوى خفيًّا
   إلى الأبد. كلّ ما هنا transform وfilter وborder-color.

   والتوقيت متدرّجٌ من اليمين إلى اليسار حيث للحركة اتّجاه: الألعاب
   عربيّة، والتتابع الذي يبدأ من اليسار يُقرأ لعبةً أخرى. */

/* ---- كَلِمة: الخانات الثماني تنقلب في مكانها، صفًّا بعد صفّ -------- */
.wordle-vector .w-row { perspective: 320px; }
@keyframes sura-flip {
    0%, 8%  { transform: rotateX(0deg); }
    46%     { transform: rotateX(-88deg); }
    100%    { transform: rotateX(0deg); }
}
.game-card:hover .wordle-vector .w-letter,
.game-card:focus-within .wordle-vector .w-letter {
    animation: sura-flip 0.52s ease-in-out both;
}
/* الابن الأوّل هو الأيمن في RTL، فالانقلاب يبدأ من اليمين. */
.game-card:hover .w-row:nth-child(1) .w-letter:nth-child(1) { animation-delay: 0.00s; }
.game-card:hover .w-row:nth-child(1) .w-letter:nth-child(2) { animation-delay: 0.08s; }
.game-card:hover .w-row:nth-child(1) .w-letter:nth-child(3) { animation-delay: 0.16s; }
.game-card:hover .w-row:nth-child(1) .w-letter:nth-child(4) { animation-delay: 0.24s; }
.game-card:hover .w-row:nth-child(2) .w-letter:nth-child(1) { animation-delay: 0.36s; }
.game-card:hover .w-row:nth-child(2) .w-letter:nth-child(2) { animation-delay: 0.44s; }
.game-card:hover .w-row:nth-child(2) .w-letter:nth-child(3) { animation-delay: 0.52s; }
.game-card:hover .w-row:nth-child(2) .w-letter:nth-child(4) { animation-delay: 0.60s; }

/* ---- نحلة: الخلايا السبع تُضاء من الوسط ثمّ دورانًا حول الحلقة ---- */
@keyframes sura-hex {
    0%, 100% { transform: scale(1); }
    45%      { transform: scale(1.18); }
}
.game-card:hover .honeycomb .hex,
.game-card:focus-within .honeycomb .hex {
    animation: sura-hex 0.46s ease-out both;
}
.game-card:hover .hex.middle-center { animation-delay: 0.00s; }
.game-card:hover .hex.top-right     { animation-delay: 0.08s; }
.game-card:hover .hex.middle-right  { animation-delay: 0.15s; }
.game-card:hover .hex.bottom-right  { animation-delay: 0.22s; }
.game-card:hover .hex.bottom-left   { animation-delay: 0.29s; }
.game-card:hover .hex.middle-left   { animation-delay: 0.36s; }
.game-card:hover .hex.top-left      { animation-delay: 0.43s; }

/* ---- تشابك: الصفّ يتماسك كوحدة — وهذه هي آليّة اللعبة بعينها ------ */
@keyframes sura-snap {
    0%, 100% { transform: translateX(0) scale(1); }
    38%      { transform: translateX(7px) scale(1.035); }
}
.game-card:hover .connections-vector .conn-row,
.game-card:focus-within .connections-vector .conn-row {
    animation: sura-snap 0.5s ease-out both;
}
.game-card:hover .conn-row:nth-child(1) { animation-delay: 0.00s; }
.game-card:hover .conn-row:nth-child(2) { animation-delay: 0.11s; }
.game-card:hover .conn-row:nth-child(3) { animation-delay: 0.22s; }
.game-card:hover .conn-row:nth-child(4) { animation-delay: 0.33s; }

/* ---- لمحة: كشفُ التلميحات موجودٌ أصلًا (انتقال شفافيّة، لا إطارات
        مفتاحيّة، فهو خارج حظر §١١٨). المضاف: الرقم ينبض مع كشف صفّه. -- */
@keyframes sura-clue {
    0%, 100% { transform: scale(1); }
    45%      { transform: scale(1.34); }
}
.game-card:hover .lamha-clue .lamha-num,
.game-card:focus-within .lamha-clue .lamha-num {
    animation: sura-clue 0.44s ease-out both;
}
.game-card:hover .lamha-clue.s3 .lamha-num { animation-delay: 0.00s; }
.game-card:hover .lamha-clue.s2 .lamha-num { animation-delay: 0.22s; }
.game-card:hover .lamha-clue.s1 .lamha-num { animation-delay: 0.44s; }

/* ---- قرّبها: الأشرطة تمتلئ على مسارها الحقيقيّ ---------------------
        العرض يبقى كما هو في السطر (١٨٪/٥٤٪/٨٨٪) — المتحرّك هو scaleX
        من الصفر إلى واحد، فينتهي كلّ شريطٍ عند نسبته المكتوبة بالضبط.
        والمنشأ **يمين** لا يسار: الشريط `display:block` داخل مسارٍ اتّجاهه
        rtl، فحافّته المثبَّتة هي اليمنى — قِيس: gapRight صفرٌ في الصفوف
        الثلاثة، وgapLeft ٩٩٫٢/٥٥٫٦/١٤٫٥ بكسل. بمنشأٍ يساريّ كان
        scaleX(0) يطويه إلى حافّته اليسرى فينفصل عن مثبته ويمتلئ من
        منتصف المسار — عيبٌ رُئي في اللقطة قبل أن يُصلَح. */
.warmer-bar i { transform-origin: right center; }
@keyframes sura-fill {
    from { transform: scaleX(0); }
    to   { transform: scaleX(1); }
}
.game-card:hover .warmer-bar i,
.game-card:focus-within .warmer-bar i {
    animation: sura-fill 0.55s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.game-card:hover .warmer-row:nth-child(1) .warmer-bar i { animation-delay: 0.00s; }
.game-card:hover .warmer-row:nth-child(2) .warmer-bar i { animation-delay: 0.14s; }
.game-card:hover .warmer-row:nth-child(3) .warmer-bar i { animation-delay: 0.28s; }

/* ---- أمثال: الكلمات تُقفَل يمينًا فيسارًا -------------------------
        كلّ رقاقةٍ تحمل دورانًا ثابتًا في تصميمها (c1 ‎-5°‎، c2 ‎3°‎،
        c3 ‎-2°‎)، وtransform خاصّيّةٌ واحدة لا تُجمَع — فلو حرّكناها بإطارٍ
        لا يذكر الدوران لاستقامت الرقاقة فجأةً وضاع التصميم. لذلك يُعاد
        دورانُ كلٍّ منها داخل إطاراتها. */
@keyframes sura-lock-c1 {
    0%, 100% { transform: rotate(-5deg) translateY(0) scale(1); }
    45%      { transform: rotate(-5deg) translateY(-7px) scale(1.07); }
}
@keyframes sura-lock-c2 {
    0%, 100% { transform: rotate(3deg) translateY(0) scale(1); }
    45%      { transform: rotate(3deg) translateY(-7px) scale(1.07); }
}
@keyframes sura-lock-c3 {
    0%, 100% { transform: rotate(-2deg) translateY(0) scale(1); }
    45%      { transform: rotate(-2deg) translateY(-7px) scale(1.07); }
}
.game-card:hover .amthal-chip.c1, .game-card:focus-within .amthal-chip.c1 {
    animation: sura-lock-c1 0.48s ease-out both; animation-delay: 0.00s;
}
.game-card:hover .amthal-chip.c2, .game-card:focus-within .amthal-chip.c2 {
    animation: sura-lock-c2 0.48s ease-out both; animation-delay: 0.13s;
}
.game-card:hover .amthal-chip.c3, .game-card:focus-within .amthal-chip.c3 {
    animation: sura-lock-c3 0.48s ease-out both; animation-delay: 0.26s;
}

/* ---- أمثال (البطاقة الحيّة): «تحقّق» يُقفل الكلمةَ الأخيرة -------------
   هذه لحظةُ اللعبة لا زخرفةً عليها: الكلمتان المقفولتان تنبضان، ثمّ تُقفَل
   الثالثة خضراءَ وتُستبدَل نقاطُها بالجواب. النبضةُ صدى `amthalPop`
   (style.css:4620) بالمقياس نفسه تقريبًا، فالبطاقةُ والمودالُ يتحرّكان
   بلغةٍ واحدة. والتتابعُ يمينًا فيسارًا لأنّ الابنَ الأوّلَ هو الأيمنُ في RTL. */
@keyframes sura-amthal-lock {
    0%, 100% { transform: scale(1); }
    45%      { transform: scale(1.11); }
}
.game-card:hover .amthal-scaffold .amthal-word,
.game-card:focus-within .amthal-scaffold .amthal-word {
    animation: sura-amthal-lock 0.44s ease-out both;
}
.game-card:hover .amthal-word.w1, .game-card:focus-within .amthal-word.w1 { animation-delay: 0.00s; }
.game-card:hover .amthal-word.w2, .game-card:focus-within .amthal-word.w2 { animation-delay: 0.13s; }
.game-card:hover .amthal-word.w3, .game-card:focus-within .amthal-word.w3 { animation-delay: 0.26s; }

.game-card:hover .amthal-scaffold .amthal-word.w3,
.game-card:focus-within .amthal-scaffold .amthal-word.w3 {
    background: var(--ok-deep);
    border-color: var(--ok);
    color: var(--ink-0);
    transition-delay: 0.26s;
}
.game-card:hover .amthal-scaffold .w3 .aw-dots,
.game-card:focus-within .amthal-scaffold .w3 .aw-dots { display: none; }
.game-card:hover .amthal-scaffold .w3 .aw-ans,
.game-card:focus-within .amthal-scaffold .w3 .aw-ans { display: inline; }

/* السكون هو الأصل، ومن طلب حركةً أقلّ لا يرى منها شيئًا. */
@media (prefers-reduced-motion: reduce) {
    .game-card:hover .w-letter,
    .game-card:hover .honeycomb .hex,
    .game-card:hover .conn-row,
    .game-card:hover .lamha-num,
    .game-card:hover .warmer-bar i,
    .game-card:hover .amthal-chip,
    .game-card:focus-within .w-letter,
    .game-card:focus-within .honeycomb .hex,
    .game-card:focus-within .conn-row,
    .game-card:focus-within .lamha-num,
    .game-card:focus-within .warmer-bar i,
    .game-card:hover .amthal-word,
    .game-card:focus-within .amthal-word,
    .game-card:focus-within .amthal-chip { animation: none; }

    /* القفلُ نفسه يبقى — هو معلومةٌ لا حركة — لكنّه يقع فورًا بلا تدرّجٍ
       ولا تأخير، فمن طلب حركةً أقلّ لا يرى انتقالًا. */
    .amthal-scaffold .amthal-word { transition: none; }
    .game-card:hover .amthal-scaffold .amthal-word.w3,
    .game-card:focus-within .amthal-scaffold .amthal-word.w3 { transition-delay: 0s; }
}

/* ============================================================================
   طبقةُ الاستجابة — «عند اللمس» من §٢ في `docs/architecture/identity.md`
   ----------------------------------------------------------------------------
   الوثيقة تصف سُرى بأنّها «هادئة، لكنّها تستجيب كآلةٍ دقيقة»، وتضع ثلاث قواعد:
   في السكون لا شيء يتحرّك · عند اللمس استجابةٌ خلال ١٠٠ms دقيقةٌ محسوبة، لا
   مطّاطة ولا مرحة · وبعد الاستجابة تتوقّف تمامًا، بلا ذيلٍ ولا نبضٍ ولا تكرار.

   والقياس قبل هذه الكتلة: من ٢٦ نوعًا تفاعليًّا، **ستّةٌ فقط** كان لها استجابةٌ
   محسوسة عند الضغط (.btn-primary · .btn-play-now · .conn-btn · .lvl-pick-btn ·
   .lvl-next-btn · .fb-demo-btn). والباقي يتلوّن عند التمرير ثمّ لا يقول شيئًا
   تحت الإصبع — وأكثر ما يُضغط في الموقع كلّه هو خلايا الألواح ومفاتيحها، وكانت
   كلّها صامتة.

   لماذا انتقالٌ لا @keyframes: الإطار المفتاحيّ له بدايةٌ ونهايةٌ يفرضهما هو،
   فيُنتج ذيلًا يعمل بعد رفع الإصبع. والانتقال يعود بمجرّد زوال :active — وهذا
   حرفيًّا «تتوقّف تمامًا».
   ولماذا ليست --ease-back: منحنى الارتداد يتجاوز الهدف ثمّ يعود، وهو تعريف
   «المطّاطة» التي منعتها §٢ نصًّا.

   ما لا تمسّه هذه الكتلة عمدًا:
     .game-card — GSAP يملك `transform` عليها (cards.mjs)، وقاعدةُ CSS هنا
       ستُهزم بالسطر المضمَّن على أيّ حال، فتبقى قاعدةً ميّتة تُربك من يقرأ.
     الستّة التي تستجيب أصلًا — لا تُكرَّر.
     .strand-cell.hint-cell وأخواتها — نبضُ التلميح حركةٌ **مُستدعاة** (اللاعب
       طلب التلميح) لا حركةَ سكون، وهو يحرّك box-shadow لا transform فلا يتصادم.
   ========================================================================== */
:root {
    /* ٩٠ms: تحت سقف §٢ (١٠٠ms) بهامشٍ يبتلع إطارًا ضائعًا على جهازٍ بطيء. */
    --press-t: 90ms;
    /* دخولٌ حادّ وخروجٌ مستقيم، بلا تجاوزٍ للهدف. */
    --press-e: cubic-bezier(0.2, 0, 0.2, 1);
}

/* ---------------------------------------------------------------------------
   تصحيحُ المقدار — لماذا رُفعت الأرقام بعد أوّل تنفيذ
   ---------------------------------------------------------------------------
   الجولة الأولى طبّقت القواعد صحيحةً وقِيست وهي تنطبق، ثمّ قال المالك إنّه
   «ما لاحظ تحركات تسوى». فقِيس المقدارُ نفسه بالبكسل بدل الاكتفاء بتطبيق
   القاعدة، والنتيجة أثبتت أنّه محقّ:

     مفتاح لوحة الحروف على جوّالٍ ٣٩٠px = ٢٦٫٢×٣٦  ← scale(0.94) يعني
       **٠٫٧٩ بكسل** أفقيًّا و١٫٠٨ رأسيًّا
     زرّ ⓘ = ٢٦×٢٦        ← ٠٫٣٩ بكسل
     زرّ الدخول العريض    ← ٠٫٢٣ بكسل رأسيًّا

   أي أنّ الاستجابة كانت **دون عتبة الإدراك البشريّ**. §٢ تقول «دقيقة
   ومحسوبة» — وهذا لا يعني «غير مرئيّة»؛ الدقّة وصفُ المنحنى والزمن، لا أمرٌ
   بأن يكون المقدار صفرًا.

   والعيب الثاني بنيويّ ولا يُصلحه رفعُ رقم: على الجوّال يقع كلّ الانضغاط
   **تحت الإصبع بالضبط**، فالإصبع يغطّي ما نُريه. ولذلك أُضيفت قناةٌ ثانية:
   حلقةٌ تُرسَم **خارج** حدود العنصر (`outline` + `outline-offset`) فتظهر
   حول الإصبع لا تحته، ولا تحرّك تخطيطًا ولا تصطدم بـ`box-shadow` القائمة.
   وهي **فوريّة**: تظهر مع :active وتزول معه، بلا انتقالٍ أصلًا — وهذا أشدّ
   التزامًا بـ«تتوقّف تمامًا، لا ذيل» من أيّ انتقال.
   ولونها وسمكها نفسُ حلقة `:focus-visible` عمدًا، كي تكون في الموقع كلّه
   علامةٌ واحدة تقول «لمستَ هذا» سواءٌ باللمس أو بلوحة المفاتيح.
   ------------------------------------------------------------------------ */
:root {
    --press-ring: 2px solid var(--gold-300);
    --press-ring-off: 2px;
}

/* --- أ. الأزرار العريضة: إزاحةٌ بلا تصغيرٍ يُذكر ------------------------
       التصغير على زرٍّ عريض يُقرأ ترنّحًا في الحوافّ لا ضغطًا، فحصّته 0.99. */
.btn-secondary,
.oauth-btn,
.nav-logout-btn,
.auth-link,
.lb-mode-btn {
    transition: transform var(--press-t) var(--press-e),
                border-color var(--dur-2) ease,
                color var(--dur-2) ease,
                background var(--dur-2) ease;
}
.btn-secondary:active,
.oauth-btn:active,
.nav-logout-btn:active,
.auth-link:active,
.lb-mode-btn:active {
    transform: translateY(2px) scale(0.975);
    outline: var(--press-ring);
    outline-offset: var(--press-ring-off);
}

/* --- ب. الأزرار الأيقونيّة الصغيرة ------------------------------------
       جسمٌ صغير يحتمل تصغيرًا أوضح، وبلا إزاحةٍ رأسيّة كي لا يقفز في شريطٍ
       مزدحم. و`.card-info-btn` و`.lvl-tools > button` لهما تكبيرٌ عند التمرير
       (1.12 و1.08)، فالضغط يُعاد إليهما نسبةً إلى ذلك التكبير لا إلى الحجم
       الأصليّ — وإلّا قفز الزرّ للخارج لحظةَ الضغط بدل أن ينضغط. */
.card-info-btn,
.lvl-daily-btn,
.lvl-tools > button,
.pw-toggle,
.nav-iconbtn,
.zoom-btn,
.btn-inline-icon {
    transition: transform var(--press-t) var(--press-e),
                border-color var(--dur-2) ease,
                color var(--dur-2) ease;
}
.card-info-btn:active,
.lvl-daily-btn:active,
.lvl-tools > button:active,
.pw-toggle:active,
.nav-iconbtn:active,
.zoom-btn:active,
.btn-inline-icon:active {
    outline: var(--press-ring);
    outline-offset: var(--press-ring-off);
    filter: brightness(0.88);
}
.lvl-daily-btn:active,
.pw-toggle:active,
.nav-iconbtn:active,
.zoom-btn:active,
.btn-inline-icon:active { transform: scale(0.86); }
/* هذان يكبران عند التمرير (1.12 و1.08)، فالضغط يُقاس نزولًا من ذلك التكبير
   لا من الحجم الأصليّ — وإلّا قفز الزرّ للخارج لحظةَ الضغط بدل أن ينضغط.
   والفارق المرئيّ هو المسافة بين الرقمين، فوُسّع: 1.12→0.94 و1.08→0.92. */
.card-info-btn:active      { transform: scale(0.94); }
.lvl-tools > button:active { transform: scale(0.92); }

/* --- ج. خلايا الألواح ومفاتيحها --------------------------------------
       هذه أكثر ما يُلمس في الموقع: عشراتُ الضغطات في الجولة الواحدة. وهي
       كانت الفجوة الكبرى — صامتةٌ تمامًا تحت الإصبع.
       `.sudoku-cell.given` مستثناةٌ لأنّها ليست قابلةً للّمس أصلًا
       (`cursor: default`)، واستجابةٌ منها تَعِد بتفاعلٍ لا يقع.
       و`.sudoku-key` و`.kbd-key` لهما رفعةٌ عند التمرير (‎-1px‎)، فالضغط يعيدهما
       إلى الصفر ويصغّرهما — فيُقرأ نزولًا حقيقيًّا لا وثبةً معكوسة.
       ولوحة مفاتيح «كَلِمة» صنفُها `.kbd-key` لا `.wordle-key`: الثانية صنفٌ
       ميّت في الورقة لا يحمله عنصرٌ واحد في الصفحة (قِيس: صفر في index.html
       وصفر في src/)، فاستهدافها كان يكتب قاعدةً لا تصيب شيئًا. */
.sudoku-cell,
.sudoku-key,
.bee-chip,
.strand-cell,
.pip-cell,
.amthal-wbox,
.kbd-key,
.lvl-cell {
    transition: transform var(--press-t) var(--press-e),
                border-color var(--dur-2) ease,
                background var(--dur-2) ease;
}
.sudoku-cell:not(.given):active,
.bee-chip:active,
.strand-cell:active,
.pip-cell:active,
.amthal-wbox:active,
.lvl-cell:not(.locked):active,
.sudoku-key:active,
.kbd-key:active {
    outline: var(--press-ring);
    outline-offset: var(--press-ring-off);
    filter: brightness(0.88);
}
.sudoku-cell:not(.given):active,
.bee-chip:active,
.strand-cell:active,
.pip-cell:active,
.amthal-wbox:active,
.lvl-cell:not(.locked):active { transform: translateY(2px) scale(0.86); }
.sudoku-key:active,
.kbd-key:active               { transform: translateY(0) scale(0.86); }

/* --- د. الحالات الخاصّة ------------------------------------------------ */

/* `.modal-close` تحمل `transform: translateY(-50%)` توسيطًا رأسيًّا، والـ
   transform خاصّيّةٌ واحدة غير تراكميّة — فضغطٌ يكتب `translateY(1px)` وحده
   يمسح التوسيط ويقذف الزرّ إلى أعلى الحافّة. فالتوسيط مُعادٌ هنا صراحةً.
   و`beadPush` القائمة عند النقر تغلب هذا الانتقال (الحركة تسبق الانتقال في
   ترتيب التطبيق)، فتبقى «دفعة الخرزة» كما هي ولا تُستبدل. */
.modal-close { transition: transform var(--press-t) var(--press-e), color var(--dur-2) ease; }
.modal-close:active {
    transform: translateY(-50%) scale(0.80);
    outline: var(--press-ring);
    outline-offset: var(--press-ring-off);
}

/* السبحة: الخرزُ نفسه مرسومٌ داخل الـPNG فلا يتحرّك، لكنّ الاسم يجلس فوق
   خرزته — فانضغاطُ الاسم يُقرأ انضغاطَ الخرزة تحته. والمسار النشط مستثنى:
   عليه `cursor: default` أصلًا، فوعدُ استجابةٍ منه كذب. */
.nav-link.nav-label {
    transition: color var(--dur-2) ease, text-shadow var(--dur-2) ease,
                transform var(--press-t) var(--press-e);
}
.nav-link.nav-label:not(.active):active {
    transform: translateY(2px) scale(0.90);
    color: var(--gold-300);
}

/* الشعار: استجابته كانت موجودةً لكن على ٤٥٠ms — خمسةُ أضعاف سقف §٢، فتصل
   بعد أن يكون المؤشّر قد غادر. اللمعة تبقى بطيئةً لأنّها إضاءةٌ لا استجابة،
   والحركة وحدها تُشدّ إلى السقف. */
/* اللمعة كانت على ٤٥٠ms، وهي مقبولةٌ للتمرير لكنّها صارت الآن قناةَ الاستجابة
   الثانية عند الضغط — و٤٥٠ms تعني أنّ الوميض يبدأ بعد رفع الإصبع ثمّ يخبو
   بعده، وهو «الذيل» الذي منعته §٢ نصًّا. فشُدَّت إلى سقف الاستجابة نفسه:
   تدخل مع الضغطة وتخرج معها، متناظرةً وبلا بقيّة. */
.nav-logo-mark {
    transition: filter var(--press-t) var(--press-e),
                transform var(--press-t) var(--press-e);
}
/* الاسم لا يأخذ حلقةً: إطارٌ حول كلمةٍ في شريط السبحة يُقرأ خطأً لا استجابة.
   فقناته الثانية لونٌ يقفز إلى الذهب — والحرفُ نفسه يبقى مرئيًّا بجانب
   الإصبع لأنّ الاسم يجلس فوق خرزته لا تحتها. */
.nav-hotspot--logo:active .nav-logo-mark {
    transform: translateY(2px) scale(0.93);
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55))
            drop-shadow(0 0 12px rgba(201, 162, 39, 0.85))
            brightness(1.12);
}

/* الستّة التي وصفتُها في الجولة الأولى بأنّ «انضغاطها محسوسٌ أصلًا» — والقياس
   كذّبني: `.lvl-pick-btn` عند scale(0.985) يتحرّك **٠٫٥٣ بكسل** في المحور
   الأفقيّ و٠٫٢٢ في الرأسيّ. أي أنّها كانت في الفجوة نفسها، وأنا أحصيتُها في
   العمود الصحيح لأنّ القاعدة موجودة، لا لأنّ العين تراها.
   فترفع مقدارها هنا وتأخذ الحلقة نفسها: أيّ شيءٍ لمستَه في الموقع يرسم
   العلامة ذاتها، فلا يتعلّم اللاعب لغتين. */
.btn-primary:active,
.btn-play-now:active,
.conn-btn:active,
.conn-btn:active:not(:disabled),
.conn-btn.primary:active,
.lvl-pick-btn:active,
.lvl-next-btn:active,
.fb-demo-btn:active {
    outline: var(--press-ring);
    outline-offset: var(--press-ring-off);
    transform: translateY(2px) scale(0.955);
}
/* `.fb-demo-btn` لا تُزاح: تجلس في صفٍّ مع أخواتها، والإزاحة الرأسيّة فيه
   تُقرأ اختلالَ محاذاةٍ لا ضغطًا. */
.fb-demo-btn:active { transform: translateY(0) scale(0.94); }

/* --- هـ. لوحة المفاتيح تستجيب كما يستجيب الإصبع ----------------------- */
.btn-secondary:focus-visible,
.oauth-btn:focus-visible,
.nav-logout-btn:focus-visible,
.auth-link:focus-visible,
.lb-mode-btn:focus-visible,
.pw-toggle:focus-visible,
.zoom-btn:focus-visible,
.btn-inline-icon:focus-visible,
.lvl-cell:focus-visible,
.lvl-tools > button:focus-visible,
.sudoku-cell:focus-visible,
.sudoku-key:focus-visible,
.bee-chip:focus-visible,
.strand-cell:focus-visible,
.pip-cell:focus-visible,
.amthal-wbox:focus-visible,
.kbd-key:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 2px; }

/* --- و. حركةٌ أقلّ: تبقى الاستجابة، وتذهب الحركة ----------------------
       الإلغاء التامّ يجعل الضغط صامتًا، وهو ليس المطلوب: من طلب حركةً أقلّ
       لم يطلب واجهةً ميّتة. فتُستبدل الإزاحة بتغميقٍ لحظيّ — استجابةٌ بلا
       إزاحةٍ في الفضاء، وهي المحرّك الحقيقيّ للدوار. */
@media (prefers-reduced-motion: reduce) {
    .btn-secondary:active, .oauth-btn:active, .nav-logout-btn:active,
    .auth-link:active, .lb-mode-btn:active,
    .lvl-daily-btn:active, .pw-toggle:active, .nav-iconbtn:active,
    .zoom-btn:active, .btn-inline-icon:active,
    .card-info-btn:active, .lvl-tools > button:active,
    .sudoku-cell:not(.given):active, .sudoku-key:active, .bee-chip:active,
    .strand-cell:active, .pip-cell:active, .amthal-wbox:active,
    .kbd-key:active, .lvl-cell:not(.locked):active,
    .nav-link.nav-label:not(.active):active,
    .nav-hotspot--logo:active .nav-logo-mark { transform: none; }

    .modal-close:active { transform: translateY(-50%); }

    .btn-secondary:active, .oauth-btn:active, .nav-logout-btn:active,
    .auth-link:active, .lb-mode-btn:active,
    .lvl-daily-btn:active, .pw-toggle:active, .nav-iconbtn:active,
    .zoom-btn:active, .btn-inline-icon:active, .card-info-btn:active,
    .sudoku-cell:not(.given):active, .sudoku-key:active, .bee-chip:active,
    .strand-cell:active, .pip-cell:active, .amthal-wbox:active,
    .kbd-key:active, .lvl-cell:not(.locked):active,
    .nav-link.nav-label:not(.active):active,
    .modal-close:active { filter: brightness(0.82); }

    /* والستّة التي كانت تستجيب قبل هذه الجولة تفقد استجابتها كاملةً تحت
       «حركة أقلّ» — قِيس على `.lvl-pick-btn`: الضغط يعطي `transform: none`
       ولا شيء غيره. فهي تأخذ التغميق نفسه، كي تكون القاعدة واحدةً على الموقع
       كلّه بدل أن تُطبَّق على ما أضفناه وحده. */
    /* ورفعُ مقدارها أعلاه جاء **بعد** قاعدة `transform: none` القديمة في
       نفس الملفّ (السطر ٥١٣٩)، فغلبها بالترتيب وأعاد الإزاحة إلى من طلب
       ألّا يُزاح شيء — قِيس: ٢٫٦٧ بكسل تحت «حركة أقلّ». فتُعاد هنا صراحةً. */
    .btn-primary:active, .btn-play-now:active, .conn-btn:active,
    .conn-btn:active:not(:disabled), .conn-btn.primary:active,
    .lvl-pick-btn:active, .lvl-next-btn:active,
    .fb-demo-btn:active { transform: none; filter: brightness(0.82); }

    /* الشعار يحمل ظلَّين في `filter` أصلًا، و`filter` خاصّيّةٌ واحدة تُستبدل
       بكاملها — فتغميقٌ مفرد يمحو الظلّين ويُسطّح الشعار لحظةَ الضغط. فيُعاد
       الظلّان هنا ويُضاف التغميق إليهما.
       (قِيس: بلا هذا السطر وسطرِ الاسم أعلاه، كان الضغط تحت «حركة أقلّ» بلا
       أيّ استجابة إطلاقًا — لا إزاحةٌ ولا تغميق.) */
    .nav-hotspot--logo:active .nav-logo-mark {
        filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.55))
                drop-shadow(0 0 12px rgba(201, 162, 39, 0.55))
                brightness(0.82);
    }
}

/* ============================================================
   شريطُ إعلان المالك — يُكتب من اللوحة أو البوت، ويُقرأ من site_settings
   ============================================================
   أسفلَ الشاشة لا أعلاها عن قصد: أعلاها يزاحم شريطَ التنقّل الثابت ويدفع
   الهيرو، وكلاهما مقيسٌ ومضبوط. وهنا لا يمسّ تخطيطَ عنصرٍ قائمٍ بحرف.

   الدخولُ انزلاقةٌ واحدةٌ ثمّ سكون (docs/architecture/identity.md §2): ينتقل مرّةً ويقف،
   ولا حركةَ دائمةً تسحب العين عن اللعب. وهو `transition` لا `@keyframes`،
   فلا يقترب من فخّ iOS المعروف في أُطر البداية. */
.sura-note {
    position: fixed;
    inset-inline: 12px;
    bottom: 12px;
    z-index: 900;                /* دون النوافذ: إعلانٌ لا يحجب لعبًا */
    display: flex;
    align-items: center;
    gap: 12px;
    max-width: 720px;
    margin-inline: auto;
    padding: 11px 14px;
    border: 1px solid rgba(201, 162, 39, 0.35);
    border-radius: 12px;
    background: rgba(24, 20, 14, 0.94);
    color: #f2ead8;
    font-size: 0.92rem;
    line-height: 1.6;
    box-shadow: 0 8px 28px rgba(0, 0, 0, 0.45);
    transform: translateY(16px);
    opacity: 0;
    transition: transform 0.28s ease, opacity 0.28s ease;
}

.sura-note.in {
    transform: translateY(0);
    opacity: 1;
}

.sura-note.warn {
    border-color: rgba(214, 122, 92, 0.55);
    background: rgba(38, 20, 15, 0.95);
}

.sura-note > span {
    flex: 1;
}

.sura-note-x {
    flex: 0 0 auto;
    width: 28px;
    height: 28px;
    border: 0;
    border-radius: 8px;
    background: rgba(255, 255, 255, 0.07);
    color: inherit;
    font-size: 1.15rem;
    line-height: 1;
    cursor: pointer;
}

.sura-note-x:hover {
    background: rgba(255, 255, 255, 0.14);
}

@media (prefers-reduced-motion: reduce) {
    .sura-note {
        transition: none;
        transform: none;
        opacity: 1;
    }
}


/* ============================================================
   تذييلُ الموقع — عنصران، لكلٍّ منهما فكرتُه
   ------------------------------------------------------------
   لا سطرَ «صُنع بيد فلان»: الشعارُ يقولها، والاسمُ الكامل في `aria-label`
   لمن يسمع الصفحة ولا يراها. وحُذفت الفواصلُ «·» معه — فاصلٌ بين عنصرين
   زخرفةٌ لا بنية.

   والفكرتان مختلفتان عمدًا لأنّ الوجهتَين مختلفتان: واحدةٌ تغادر الموقع
   إلى علامةٍ تجاريّةٍ لها لونُها، والأخرى تبقى فيه وتخضع لذهبِه.
   ============================================================ */
.sura-foot {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 1.5rem;
    margin-top: 3.5rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--glass-border);
}

/* ---- ١) LinkedIn: شارةٌ تُضاء ------------------------------------------
   في السكون شارةٌ باردة: الحرفان بأزرق لِنكدإن الرسميّ `#0A66C2` على أرضٍ
   شفّافة. وعند اللمس تنقلب الطبقتان — تمتلئ الأرضُ بالأزرق ويصير الحرفان
   بيضاء. هذا **مقلوبُ** الحالة لا تفتيحُها، وهو ما يجعلها شارةً لا زرًّا
   عامًّا بهالة.

   واللونُ يبقى أزرق في الحالتين: علامةٌ تجاريّةٌ لا تُصبَغ بذهب الموقع. */
.sura-foot__in {
    --in-blue: #0A66C2;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.42rem 0.85rem 0.42rem 0.7rem;
    border: 1px solid rgba(10, 102, 194, 0.42);
    border-radius: 8px;
    background: rgba(10, 102, 194, 0.08);
    color: var(--in-blue);
    font-size: 0.86rem;
    font-weight: 500;
    line-height: 1;
    text-decoration: none;
    /* السكونُ ساكن، والاستجابةُ تحت ١٠٠م.ث ثمّ تقف — docs/architecture/identity.md §٢ */
    transition: background-color 0.14s var(--ease-expo),
                border-color 0.14s var(--ease-expo),
                color 0.14s var(--ease-expo);
}

.sura-foot__in-mark {
    width: 17px;
    height: 17px;
    fill: currentColor;   /* الحرفان يتبعان لونَ الشارة في الحالتين */
    flex: none;
}

.sura-foot__in:hover,
.sura-foot__in:focus-visible {
    background: var(--in-blue);
    border-color: var(--in-blue);
    color: #fff;
}

.sura-foot__in:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 3px; }

/* في الوضع الفاتح تبقى الشارةُ نفسَها: الأزرقُ يقرأ على الورق كما على الليل. */
html[data-theme="light"] .sura-foot__in { background: rgba(10, 102, 194, 0.06); }

/* ---- ٢) الخصوصيّة: سطرٌ يُوقَّع -----------------------------------------
   لا إطارَ ولا أيقونة — رابطُ وثيقةٍ لا زرُّ إجراء. وفكرتُه أنّ الخطَّ
   الذهبيَّ تحته **يُرسَم من اليمين إلى اليسار** عند التحويم، كما يُوقَّع
   السطرُ العربيّ. ولذلك `transform-origin: right` لا `center`. */
.sura-foot__privacy {
    position: relative;
    color: var(--clr-text-muted);
    font-size: 0.86rem;
    text-decoration: none;
    padding-bottom: 3px;
    transition: color 0.14s var(--ease-expo);
}

.sura-foot__privacy::after {
    content: '';
    position: absolute;
    inset-inline: 0;
    bottom: 0;
    height: 1px;
    background: var(--gold-500);
    transform: scaleX(0);
    transform-origin: right;
    transition: transform 0.22s var(--ease-expo);
}

.sura-foot__privacy:hover,
.sura-foot__privacy:focus-visible { color: var(--gold-300); }
.sura-foot__privacy:hover::after,
.sura-foot__privacy:focus-visible::after { transform: scaleX(1); }
.sura-foot__privacy:focus-visible { outline: 2px solid var(--gold-300); outline-offset: 4px; }

/* السكونُ يُحترَم: التوقيعُ حركةٌ زخرفيّة، واللونُ وحدَه يكفي رسالةً. */
@media (prefers-reduced-motion: reduce) {
    .sura-foot__in,
    .sura-foot__privacy,
    .sura-foot__privacy::after { transition: none; }
    .sura-foot__privacy:hover::after { transform: none; }
}
