# قالب «راقي» (`raqi`): ملاحظات التصميم

> بوتيك تحريري هادئ للأزياء والعبايات والعطور والبخور. يقوم على صور سخيّة وطباعة راقية وحركة قليلة هادئة وحكاية لكل قطعة. على الجوال تظهر القطعة كاملة واسمها وسعرها وزر الشراء في الشاشة الأولى.
> قالب حقيقي لمحرّك `docs/THEME_ENGINE.md`: كل قرار بصري يأتي من الإعدادات العامة (§1) والأقسام (§2) وقوالب الصفحات (§3).
> المتجر «دار سَنا» وكل المنتجات والأسعار والأرقام والآراء في النموذج **مثال**.

ابدأ من `index.html`. فيه قائمة الشاشات وإطاران حيّان بعرض 375px و1280px. زر «جرّب هوية التاجر» يبدّل 3 لوحات تاجر، فتتغيّر الصفحة والإطاران معًا، و`theme.css` لا يتغيّر.

---

## 1. الفكرة البصرية

| المبدأ | كيف يظهر |
| --- | --- |
| **الهدوء فخامة** | مساحات واسعة (`--sf-section-y` يصل إلى 112px على المكتب)، خطوط شعرية (hairlines) بدل الصناديق، لون واحد قوي على الأكثر في الشاشة |
| **التحرير لا الكتالوج** | عناوين كبيرة بخط العنوان (`--r-display` حتى 68px)، «حواجب» مرقّمة (`01 — الأقسام`) يتبعها خط رفيع، اقتباس بارز (pull-quote) في قسم الحكاية |
| **الصورة هي البطل** | صور 3:4 / 4:5 كبيرة، تكبير بطيء جدًا عند المرور (900ms) على الأجهزة ذات المؤشر فقط (`hover:hover and pointer:fine`، فلا يعلق التكبير عند اللمس)، شبكة تصنيفات متدرّجة (الأعمدة الزوجية تنزل 48px). في صفحة المنتج على الجوال سقف الصورة `60svh` والصورة تُعرض **كاملة** (`contain`) فوق أرضية `surface-muted` كي يظهر الاسم والسعر معها دون قصّ القطعة. الصور تستقرّ بتلاشٍ ناعم 450ms عند وصولها (§7) |
| **حكاية المنتج** | صفحة المنتج فيها «حكاية القطعة» (وصف التاجر بأسلوب تحريري)، شريط حقائق ثلاثي (القماش · التطريز · القصّة)، و«شريط تفاصيل» يعرض صورتين من صور المنتج نفسه بحجم كبير. لا بيانات جديدة، فقط عرض أفضل لما يُدخله التاجر |
| **التوقيع: «إطار راقي»** | إطار شعري مزاح 14px خلف صورة الـ hero (`.frame::before`) بلون `--sf-border` وزاوية `--sf-radius-card`. يتبع لوحة التاجر وزواياه تلقائيًا |
| **مسار الثقة بلا استعراض** | السلة والدفع والتتبّع (TE §3.4) تتبع الإعدادات العامة فقط. الفخامة فيها من الطباعة: خطوات مرقّمة بدوائر شعرية، ورقم الطلب بخط العنوان الكبير. لا صور زخرفية ولا حركة غير التغذية الراجعة |

**ما ليس في القالب عمدًا:** ظلال زخرفية، تدرّجات لونية، زجاج ضبابي في المحتوى، عدّادات وهمية، نجوم تقييم، أيقونات مكتبات ثقيلة. الأيقونات SVG خطية مضمّنة (`<symbol>`)، والرأس وحده يستخدم `backdrop-filter` خفيفًا.

---

## 2. لماذا هو قالب «حقيقي» للمحرّك

1. `theme.css` لا يحتوي **أي لون أو خط أو زاوية مكتوبة مباشرة**. يقرأ فقط متغيّرات `--sf-*` التي يكتبها المحرّك في `<style id="sf-vars">` داخل `<head>` (TE §1.2، §4.7).
2. متغيّرات القالب الداخلية `--r-*` كلها **مشتقّة** من `--sf-*` بـ `color-mix()` (مثل `--r-hair` و`--r-veil`)، أو قيم هندسية لا هوية فيها (عرض المحتوى، المنحنى، مقاسات العناوين).
3. الإعدادات البنيوية تُكتب كخصائص على `<html>`: `data-header` (`header.layout`) و`data-motion` (`motion`)، ويختار CSS التخطيط منها.
4. **إثبات حيّ:** `demo-tools.js` (للنموذج فقط) يعيد كتابة `<style id="sf-vars">` وخصائص `<html>`، تمامًا كما تفعل المعاينة الفورية في المحرّر عبر `postMessage` (TE §4.7). تتغيّر الألوان والخطوط والزوايا وشكل الأزرار والبطاقات ونسبة الصور وتخطيط الرأس ونبرة التذييل وشريط الإعلان، دون أي تعديل على `theme.css`. ونقرة «أظهر حدود الأقسام» تكشف أن الرئيسية مكوّنة فقط من `SectionInstance` بالترتيب (`data-section="type · style"`).

### 2.1 المتغيّرات التي يستهلكها القالب، ومصدر كل منها
| المتغيّر | مصدره في الإعدادات | ملاحظة |
| --- | --- | --- |
| `--sf-bg, --sf-fg, --sf-fg-muted, --sf-surface, --sf-surface-muted, --sf-border` | `colors.background` عبر `resolveStorePalette()` | |
| `--sf-primary, --sf-primary-fg, --sf-primary-hover, --sf-link, --sf-ring` | `colors.primary` | المحرّك يفحص `--sf-ring` و`--sf-link` مقابل `bg` فقط. لذلك على الأسطح المقلوبة (`.tone-dark`، التذييل، الإعلان، شريط المعاينة) يعيد القالب تعريفهما إلى `currentColor` |
| `--sf-accent, --sf-accent-fg, --sf-accent-text` | `colors.accent` | الشارات وأسعار العروض والخط الجانبي للاقتباس |
| `--sf-danger, --sf-success, --sf-warning` | ثابتة من القالب، تُصحَّح مقابل الخلفية | |
| `--sf-font-heading, --sf-font-body, --sf-heading-weight, --sf-text-base` | `typography.pair`, `typography.scale` | |
| `--sf-radius-control, --sf-radius-card, --sf-radius-sheet` | `shape.radius` (§1.4) | |
| `--sf-btn-radius, --sf-btn-bg/fg/bd(-hover), --sf-btn2-*` | `buttons.style` (+ الألوان) | الزر الثانوي مشتق كما في §1.1 |
| `--sf-card-bg, --sf-card-bd, --sf-card-shadow, --sf-card-pad, --sf-card-ratio` | `cards.style`, `cards.imageRatio` | `raised` = ظل xs فقط |
| `--sf-gap, --sf-section-y` | `density` | |
| `--sf-dur` | `motion` | 0ms عند `none` |
| `--sf-announce-bg/fg` | `announcement.tone` | |
| `--sf-footer-bg/fg/muted` | `footer.tone` | |

> **مقترح للعقد (فجوة R-01):** TE §1.2 يعرّف متغيّرات الألوان فقط. هذا القالب يحتاج أن يكتب المحرّك أيضًا متغيّرات الشكل أعلاه (أزرار، بطاقات، كثافة، حركة، إعلان، تذييل) كمخرجات **موحّدة لكل القوالب**، من دالة مثل `resolveShapeVars(settings)` في `packages/contracts/src/themes-palette.ts`. بهذا لا يعيد كل قالب اشتقاق `buttons.style=outline` بطريقته.

---

## 3. اللوحات الجاهزة (`presets.ts`)، وهي نفسها المستخدمة في مبدّل النموذج

| المفتاح | الاسم | الخلفية / الأساسي / التمييز | الخط | الزوايا | الأزرار | البطاقات | الصورة | الرأس | التذييل |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| `ivory` (افتراضي) | عاج | `#F6F1EA` / `#2A231E` / `#8A5A2E` | `kufi-plex` | `none` | `solid` | `plain` | `3:4` | `logo_center` | `dark` |
| `night` | ليل العود | `#15120E` / `#C9A46A` / `#E3C48F` (خلفية داكنة) | `kufi-tajawal` | `sm` | `outline` | `bordered` | `3:4` | `logo_center` | `dark` |
| `rose` | ورد طائفي | `#FBF4F1` / `#7B2D44` / `#A8432F` | `readex-plex` | `lg` | `pill` | `raised` | `4:5` | `logo_start` | `brand` |

قيم `palette` في `demo-tools.js` تمثّل **مخرجات** `resolveStorePalette()` لهذه الألوان. تحقّقتُ منها بحساب WCAG (سكربت محلي):

| الزوج | عاج | ليل العود | ورد طائفي | الحد |
| --- | --- | --- | --- | --- |
| النص / الخلفية | 15.4 | 15.8 | 14.8 | ≥ 7 |
| النص الثانوي / الخلفية | 6.4 | 7.9 | 6.5 | ≥ 4.5 |
| النص الثانوي / `surface-muted` | 5.7 | 6.6 | 5.8 | ≥ 4.5 |
| حدّ الحقول / الخلفية | 3.3 | 3.9 | 3.3 | ≥ 3 |
| نص الزر / الأساسي | 13.8 | 8.0 | 9.1 | ≥ 4.5 |
| الرابط / الخلفية | 13.8 | 9.1 | 8.4 | ≥ 4.5 |
| نص الشارة / التمييز | 5.9 | 11.2 | 6.0 | ≥ 4.5 |
| سعر العرض (`accent-text`) / الخلفية | 5.2 | 11.2 | 5.5 | ≥ 4.5 |
| خطر · نجاح · تحذير / الخلفية | 6.4 · 5.7 · 5.6 | 7.7 · 9.4 · 10.3 | 6.6 · 5.9 · 5.8 | ≥ 4.5 |
| نص التذييل / خلفيته | 15.4 | 16.6 | 9.1 | ≥ 4.5 |

**أسطح لا يفحصها المحرّك** (كانت هي مصدر الإخفاقات في مراجعة الوصولية، وأصلحت كلها في `theme.css`):

| السطح | المشكلة السابقة | الإصلاح |
| --- | --- | --- |
| `.tone-dark` (قسم «حكايتنا») | حلقة التركيز 1.12–1.77، الزر الثانوي يختفي عند المرور (1.08)، خط الاقتباس 1.41–2.94 | `--sf-ring` و`--sf-link` = `currentColor`، أزرار القسم تستخدم الزوج المقلوب (`bg` على `fg`) في الحالة العادية وعند المرور، خط الاقتباس `currentColor`. حُذف الـ style المضمّن من الزر |
| التذييل، الإعلان، شريط المعاينة | حلقة التركيز 1.00–1.23 | `--sf-ring: currentColor` (≥ 4.5 بالبناء لأن النص نفسه مفحوص) |
| نص البانر فوق الصورة | التعتيم 35–45% خلف العنوان فقط (2.4–3.4 فوق صورة فاتحة) | تدرّج `66% ← 55% عند 45% ← 0 عند 80%`، أي ≥ 55% خلف كل سطر نص (≈ 4.7 أسوأ حالة). الادعاء السابق «يُستوفى `overlay ≥ 35`» كان غير كافٍ، والمقترح R-08 يرفع الحد في العقد |

---

## 4. دعم الإعدادات العامة (TE §1.1)

القالب يدعم **كل** المفاتيح. القيود التي يعلنها الـ manifest (`settings.allow`):

| المفتاح | القيم المسموحة في راقي | السبب |
| --- | --- | --- |
| `shape.radius` | `none, sm, md, lg` (بلا `xl`) | الزوايا الكبيرة جدًا تكسر الطابع التحريري. `xl` يُقرَّب إلى `lg` عند التبديل (§4.6) |
| `cards.imageRatio` | `3:4, 4:5` (بلا `1:1`) | صور الأزياء طولية. `1:1` يُقرَّب إلى `4:5` |
| `density` | `comfortable` فقط | الكثافة تناقض الهدوء. من يحتاج `compact` يختار `souq` |
| `header.layout` | `logo_center, logo_start` | `logo_start_nav_below` غير مصمَّم بعد (يمكن إضافته في minor) |
| `motion` | `none, subtle` (+ `expressive` المقترح، §7) | |
| الباقي | كل القيم | `typography.pair` كل الأزواج مسموحة، والموصى به `kufi-plex`, `kufi-tajawal`, `readex-plex`, `plex` |

الافتراضات: `ivory` · `typography.scale=normal` · `buttons.style=solid` · `cards.style=plain` · `cards.showSecondImage=false` (مدعوم: الصورة الثانية عند المرور على المكتب فقط، `lazy`) · `header.sticky=true` · `header.transparentOverHero=false` (الـ hero نوعه `split` فلا يتحقّق شرط الشفافية) · `header.showSearch=icon` (حقل بحث خطّي ظاهر على المكتب. على الجوال المكبّرة تفتح صف بحث `#search` تحت الرأس: حقل 52px بـ `name=q` و`enterkeyhint=search`، يعمل بـ `:target` بلا JS ويأخذ التركيز مع JS. النموذج نفسه في أعلى القائمة الجانبية. في الإنتاج `action="/search"`، وفي النموذج يذهب إلى صفحة التصنيف مع تنبيه يوضّح ذلك) · `announcement.tone=primary` · `footer.tone=dark` · `social.floatingWhatsapp=false` (لا يُخفي الصور. قسم `whatsapp_cta` يؤدي الدور).

---

## 5. الأقسام (TE §2.4) ومتغيّراتها في راقي

| النوع | المتغيّرات المدعومة | الافتراضي في راقي | في النموذج |
| --- | --- | --- | --- |
| `hero` | `split`, `image`, `slider`, `video_lite` | `split` · `height=tall` · `textPosition=below` على الجوال · إطار التوقيع | ✔ الرئيسية |
| `categories` | `tiles`, `circles`, `list` | `tiles` 3:4 · `mobileLayout=scroll` · تدرّج زوجي على المكتب | ✔ |
| `new_arrivals` | `grid`, `carousel` | `grid` · `columnsDesktop=4` · `count=4` | ✔ |
| `image_text` | `imagePosition` start/end · `tone` | `tone=dark` · 4:5 · pull-quote من أول سطر غامق في `body` | ✔ «حكايتنا» |
| `featured_products` | `grid`, `carousel` | `carousel` (scroll-snap) | ✔ «طقوس المساء» |
| `banner` | `full`, `contained`, `two_up` | `two_up` · 4:5 | ✔ |
| `testimonials` | `grid`, `carousel` | `grid` على المكتب، تمرير على الجوال · `showQuoteMark` · بلا نجوم | ✔ (مثال، لا يُنشر) |
| `trust_badges` | `row`, `grid` · `line` | `row` · `line` · مشتقّة من البيانات | ✔ |
| `faq` | `separated`, `boxed` | `separated` · `openFirst` · `<details>` | ✔ |
| `whatsapp_cta` | `strip`, `card` | `strip` · `tone=muted` | ✔ |
| `product_grid` | كالشبكة + `showCategoryChips` | يُعاد استخدام بطاقة المنتج نفسها | مكوّن الشبكة نفسه |
| `offers` | `grid`, `carousel` · `tone` | `tone=default`. العدّاد نص ثابت + `<time>` وجزيرة `countdown` فقط مع `endsAt` حقيقي | غير مرسوم (لا عرض حقيقي في المثال) |
| `best_sellers` | كالشبكة + `showRank` | الرتبة رقم لاتيني رفيع فوق البطاقة | غير مرسوم (يُخفى بلا مبيعات حقيقية) |
| `rich_text` | `align`, `width`, `tone` | `narrow` · `center` | يُرسم بأنماط `.desc`/`.rt` |
| `brand_logos`, `newsletter` | `row_scroll`/`grid` · `whatsapp_channel` | | غير مرسوم |

الحد الأدنى الإلزامي في TE §2.5 كله مغطّى.

### 5.1 الأقسام الافتراضية (`defaultSections`) بالترتيب المرسوم في `home.html`
`hero(split)` → `categories(tiles)` → `new_arrivals(grid/4)` → `image_text(dark)` → `featured_products(carousel)` → `banner(two_up)` → `testimonials(grid, sample)` → `trust_badges(row)` → `faq(separated)` → `whatsapp_cta(strip)`.
10 أقسام مفعّلة (الحد 12). 3 أقسام منتجات (الحد 4). صورة `fetchpriority=high` واحدة (صورة الـ hero) وكل ما بعدها `lazy`.
يصلح كقالب مبدئي بديل لـ `starter.fashion` و`starter.perfume` (TE §6.2) لمن يريد طابعًا تحريريًا أكثر من `noor`/`oud`.

### 5.2 قوالب الصفحات (TE §3)
- **المنتج** `templates.product`: `gallery(slider + thumbs=side على المكتب)` → `title` → `price(showSaveAmount)` → `stock(lowStockText)` → `variants(swatches للون · buttons للمقاس)` → `quantity` → `buy(showBuyNow)` → `delivery_payment` → `whatsapp_ask` → `description(collapsedLines=all، عرض تحريري)` → `custom_text×2` (دليل المقاسات، العناية) → `related(4)`. شريط الشراء الثابت مفعّل على الجوال (مقفل).
  الإضافة الوحيدة الخاصة بالقالب: «شريط التفاصيل» يعرض الصورتين 3 و4 من معرض المنتج نفسه بحجم كبير (إعداد style مقترح `description.detailStrip: bool`).
  **الجوال:** مسار التنقّل مخفي (يبقى `BreadcrumbList` في JSON-LD) ويحلّ محلّه «‹ رجوع» في الرأس. الشريحة بسقف `min(4:3 من العرض، 60svh)` والصورة كاملة بلا قصّ (`contain`)، والنقاط (هدف 44px) فوقها بدل صف مستقل. **شريط الشراء الثابت ظاهر من الشاشة الأولى** بالسعر وزر رئيسي واحد «أضف إلى السلة» (أو «اختر المقاس» إن لم يُختر مقاس)، ويتنحّى فقط ما دامت أزرار الصفحة نفسها ظاهرة (IntersectionObserver يبدّل `body.bb-off`)، فلا يظهر زرّان معًا. «اطلب الآن» داخل الصفحة فقط. بلا JS يبقى الشريط ظاهرًا دائمًا كما يفرض القفل. **لا مقاس مختار مسبقًا**. تغيير اللون يبدّل الصورة الأولى وصورتها المصغّرة ونصها البديل والسعر.
  **الإضافة إلى السلة (JS):** `fetch` مع `Idempotency-Key` (المفتاح نفسه ما دام الاختيار نفسه، فإعادة المحاولة لا تُضيف مرتين)، الأزرار معطّلة أثناء الإرسال فقط بنص «جارٍ الإضافة…»، مهلة 20 ثانية، وعند الفشل تنبيه ثابت «لا يوجد اتصال، لم تُضف القطعة. اختياراتك محفوظة» مع «أعد المحاولة». عند النجاح تُفتح ورقة «أُضيفت إلى السلة» (بطاقة في الزاوية على المكتب) ويتحدّث عدّاد السلة. `pageshow` يعيد الأزرار دائمًا. بلا JS أو من `file://` يُرسَل النموذج عاديًا.
- **التصنيف** `templates.collection`: `mobileColumns=2` · `desktopColumns=3` · `filters=sheet_sidebar` · `showSubcategoryChips=true` · `showCategoryBanner=true` · `defaultSort=newest` · `pagination=pages`.
  **رأس التصنيف:** على الجوال سطر واحد فيه العنوان والعدد. الوصف وصورة التصنيف تظهر من 900px فقط، ويُعطى الجوال مصدرًا بحجم 1×1 بكسل عبر `<picture>`، ومع `Save-Data` يحذف الخادم الصورة. أول بطاقتين `fetchpriority=high` بلا `lazy`، والبانر لم يعد يأخذ أولوية التحميل.
- **السلة والدفع والتتبّع**: بلا أقسام (TE §3.4). تتبع الإعدادات العامة فقط، برأس مبسّط في الدفع والتتبّع.

---

## 6. الشاشات

| الملف | المواصفة | أهم القرارات |
| --- | --- | --- |
| `home.html` | 01 | مبنية من الأقسام فقط. على الجوال يأتي النص تحت الصورة (`textPosition=below`) فلا نص فوق صورة بلا تعتيم. صورة الـ hero بسقف `46svh` والزر يأتي بصريًا تحت العنوان مباشرة (ترتيب DOM لم يتغيّر)، فيظهر العنوان والزر في الشاشة الأولى على 375×667 (أسفل الزر ≈ 605px) |
| `category.html` | 02 | رأس تحريري · شرائح فرعية · ترتيب يُطبَّق بزر «تطبيق» الظاهر دائمًا (لا إرسال عند التغيير، WCAG 3.2.2) · عمود فلاتر على المكتب وورقة سفلية `:target` على الجوال · الفلاتر النشطة قابلة للإزالة · النافد في آخر القائمة |
| `product.html` | 03 | متغيّرات بتوفّر حقيقي لكل تركيبة (المقاس غير المتاح مشطوب ومعلَن لقارئ الشاشة) · السعر بعلامة المنطقة الكاملة `ر.ي (صنعاء)` · سطر المغترب `≈ ر.س` «تقريبي» · «بقيت 3 قطع» من المخزون فقط · ملخّص التوصيل والدفع مشتق · زرّا «أضف إلى السلة / اطلب الآن» داخل نموذج حقيقي (نص المواصفة، انظر §13) |
| `cart.html` | 04 | كل سطر `<form>` مستقل · حذف بنص لا بأيقونة · كود خصم مطبّق · التوصيل «يُحسب بعد إدخال العنوان» · «الإجمالي التقريبي» بالعلامة الكاملة · الزر ثابت في منطقة الإبهام |
| `checkout.html` | 05 | رأس مبسّط فيه «الدفع عند الاستلام» مشتقًا من الوسائل المفعّلة بدل ادعاء «دفع آمن» لا يمكن التحقق منه · صفحة واحدة بأربع خطوات مفتوحة · المحافظة (بلا اختيار مسبق) ← المديرية ← **أقرب معلم (إلزامي)**، والحقول الاختيارية (الحي، الشارع، الموقع، الملاحظة) مطويّة في سطرين «إضافة …» · تحقق خفيف عند الإرسال: ملخّص `role="alert"` بروابط + رسالة تحت كل حقل + تركيز على أول خطأ، والزر يبقى مفعّلًا · الزر لا يحمل إجماليًا قبل معرفة رسوم التوصيل · شريط التأكيد الثابت يعود إلى مكانه في الصفحة أثناء الكتابة فلا يركب فوق لوحة المفاتيح · عند الإرسال يتغيّر نص الزر فقط إلى «جارٍ إرسال طلبك…» ويبقى الإجمالي ظاهرًا، بعد 20 ث «جارٍ التحقق من طلبك…»، بعد 45 ث «أعد المحاولة» بالمفتاح نفسه، و`pageshow` يعيد الأزرار بعد الرجوع · تغيير المحفظة يبدّل الرقم وزر النسخ · المحافظات غير المغطّاة في آخر القائمة معطّلة · طرق التوصيل تتغيّر حسب المحافظة · الدفع عند الاستلام (+رسوم) أو تحويل محفظة: المستفيد والرقم والنسخ والمبلغ الدقيق ثم «حوّلت الآن + رقم العملية» أو «سأحوّل بعد الطلب» · زر التأكيد يحمل الإجمالي |
| `tracking.html` | 07 | رقم الطلب بخط العنوان · خط زمني من السجل الحقيقي فقط بلا مواعيد مخترعة · الاسم الأول والمعلم والجوال المقنّع فقط · واتساب كزر ثانوي · بحث برقم الطلب والجوال + «طلباتك على هذا الجهاز» |

كل شاشة فيها لوحة **«حالات الشاشة»** للمراجعة: فارغ، تحميل (skeleton بنفس الأبعاد)، خطأ، بلا اتصال، نفاد، رسائل تحقق، وغيرها.

---

## 7. الحركة

- **`subtle`** (قيمة العقد والافتراضي في راقي): تغذية راجعة (لون/خط سفلي/دوران أيقونة) بمدة `--sf-motion` = 160ms، والتكبير البطيء للصور عند المرور بالمؤشر فقط، **و«استقرار الصور»**: كل صورة منتج/قسم تظهر بتلاشٍ ناعم (opacity 0→1 خلال 450ms) فوق أرضية `surface-muted` لحظة وصولها. هذه الإيماءة البطيئة الأنيقة الوحيدة، ويراها كل متسوّق بما فيه اللمس، وتخفي التحميل التدريجي على 3G. تعمل بسطر JS مشترك في `<head>` (≈ 200 بايت: يضيف `.js` قبل أول رسم و`.in` عند `load/error`). لا تُطبَّق على صورة LCP (`fetchpriority=high`) كي لا تؤخّرها، ولا بلا JS، ولا مع `motion=none` أو تقليل الحركة.
- **`expressive`** (**مقترح، فجوة R-02**، ليس في العقد بعد. المبدّل في النموذج يسمّيه «مقترح» ولا يجعله افتراضيًا): كشف بطيء لمرة واحدة عند أول رسم. صورة الـ hero تنكشف كستارة (`clip-path` + تصغير من 1.06، 900ms)، ونصوص الـ hero ترتفع بتتابع 110ms. البطاقات تظهر عند التمرير بـ `animation-timeline: view()` فقط في المتصفحات التي تدعمها، وغيرها يعرض المحتوى فورًا بلا JS.
- كل الحركة CSS فقط، وكلها تُلغى بـ `prefers-reduced-motion: reduce` (قاعدة شاملة `!important`). مع `motion=none` تصبح `--sf-dur` = 0.
- لا شيء يتحرك تلقائيًا ولا شيء يتكرّر: لا شرائح تلقائية ولا نبض.

---

## 8. الأداء والإنترنت الضعيف (مقاس فعليًا على الملفات)

مقاس بـ `gzip -9` بعد جولة التحسين (2026-10-01):

| الملف | خام | gzip |
| --- | --- | --- |
| `theme.css` (كل الشاشات، ما يُشحن) | 58 KB بالتعليقات · 46.9 KB مصغّرًا | 12.5 KB بالتعليقات · **9.5 KB مصغّرًا** (ما يُشحن فعلًا؛ حد `base.css` في TE ≤ 12 KB. القالب يحلّ محلّه ولا يُضاف فوقه) |
| `demo.css` (لوحات الحالات، حدود الأقسام، فهرس الشاشات) | 3 KB | 1.1 KB (**نموذج فقط، لا يُشحن**. فُصل عن `theme.css`) |
| JS صفحة المنتج (سطر الرأس + جزيرتان، غير مصغّر) | 8.8 KB | **4.2 KB** (مصغّرًا ≈ 3 KB) |
| JS الدفع (سطر الرأس + الجزيرة، غير مصغّر) | 8.1 KB | 3.9 KB (المواصفة ≤ 25 KB) |
| JS السلة / التصنيف / الرئيسية | 2.5 / 1.8 / 1.4 KB | 1.2 / 1.0 / 0.8 KB |
| HTML صفحة المنتج (مع JS والأيقونات، ومع لوحة الحالات التي لا تُشحن) | 33 KB | 10.2 KB |
| `demo-tools.js` | 14 KB | 5.1 KB (**نموذج فقط**) |

| ما يُنقل فعليًا (تقدير للإنتاج) | قبل | بعد |
| --- | --- | --- |
| الخطوط | 3 ملفات من مضيف خارجي (≈ 90–110 KB) | **ملفان**: العنوان 700 + النص 400 (لا يوجد Plex 700: كل نص عريض يستخدم خط العنوان، فلا عريض مزيّف). الهدف ≈ 55–65 KB بعد التقسيم للعربية والأرقام |
| صور صفحة المنتج على 3G | ≈ 250–550 KB (Chrome يجلب صور `lazy` من مسافة ≈ 2500px على الشبكات البطيئة) | الشريحة 1 فقط (`fetchpriority=high`). الشرائح 2–4 وشريط التفاصيل بـ `data-src` وجزيرة IntersectionObserver (هامش 300px)، أو عند لمس المعرض، ومعها `<noscript>` لمن بلا JS. المصغّرات مخفية على الجوال (نقاط CSS بدلها) |
| صورة التصنيف | كانت `fetchpriority=high` على الجوال | مكتب فقط. أول بطاقتين تأخذان الأولوية |

⇒ صفحة المنتج بلا صور ولا خطوط ≈ **24 KB gzip** (HTML + CSS + JS)، أي ربع حد 100KB.

- **الصور:** النموذج يستخدم SVG بديلة خفيفة في `img/`. في الإنتاج كل صورة `<img srcset="…/320.webp 320w, …/640.webp 640w, …/1024.webp 1024w" sizes="…">` مع `width/height` ثابتة و`aspect-ratio` من `--sf-card-ratio` (لا CLS) و`decoding=async`. قيم `sizes` في راقي: البطاقة `(min-width:1200px) 25vw, (min-width:768px) 30vw, 50vw` · المعرض `(min-width:900px) 50vw, 100vw` · الـ hero `(min-width:900px) 58vw, 100vw` · السلة والدفع `96px`/`56px`. صورة واحدة `fetchpriority=high` لكل صفحة (اثنتان في التصنيف). الصورة الثانية في البطاقة (عند المرور) للمكتب فقط و`lazy`.
- **المصغّرات الصغيرة:** أصغر نسخة في العقد 320w، فمصغّرة 56–96px تكلّف ≈ 15 KB. مقترح R-09: نسخة 160w للمصغّرات.
- **الخطوط:** النموذج يحمّل ملفين من Google Fonts للتسهيل فقط. الإنتاج يستضيفهما ذاتيًا `/_fonts/<pair>.css` (immutable) مع خطوط بديلة مضبوطة بـ `size-adjust`/`ascent-override` كي لا يقفز النص عند التبديل، ويُحمَّل مسبقًا ملف النص 400 وحده. مع `Save-Data` ملف 400 وحده.
- **بلا JS:** القائمة وورقة الفلاتر بـ `:target`، والأسئلة والكوبون والملخّص بـ `<details>`، والمعرض بـ scroll-snap وروابط `#g1`، وكل نموذج يُرسَل عاديًا، وتفاصيل التحويل تظهر بـ `:has()` (ومن لا يدعمها يراها دائمًا)، والمديريات بزر «عرض المديريات» الذي يظهر فقط بلا JS.
- **لا مكتبات** ولا أطر ولا طلبات خارجية (عدا الخطوط في النموذج).

---

## 9. الوصولية والاتجاه

- خصائص منطقية فقط (`inline/block`, `inset-inline-start`…). لا `left/right` في التخطيط. الاستثناء الوحيد `translateX` في الدرج/الورقة لأنه حركة لا تخطيط، واتجاهها صحيح لـ RTL.
- أهداف لمس ≥ 44px بلا استثناء (نقاط المعرض 44×44 والنقطة المرئية 6px، الشرائح، صفوف الاختيار، روابط التذييل، النسخ، أزرار الكمية في السلة، الفلاتر النشطة)، والنقطة غير النشطة بلون `--sf-border` (≥ 3:1)، ونص الـ placeholder بلون `--sf-fg-muted` (≥ 4.5:1)، وحقول 52px بخط 16px (لا تكبير تلقائي في iOS)، وحلقة تركيز ظاهرة `--sf-ring` (و`currentColor` على الأسطح المقلوبة، §3)، ورابط «تخطَّ إلى المحتوى»، ورسائل الحالة بـ `role="status"/"alert"`، والمقاس غير المتاح له `aria-label` «غير متوفر».
- **التركيز لا يختفي خلف الأشرطة الثابتة (WCAG 2.4.11):** بدل `scroll-margin` الثابت 88px صار `scroll-padding` على `html`: 72px أعلى الجوال، 136px على المكتب، +56px في الصفحات التي فيها شريط أدوات ثابت (التصنيف)، و128px أسفل الصفحة حين يوجد شريط شراء أو تأكيد ثابت على الجوال.
- **القائمة وورقة الفلاتر وصف البحث** حوارات حقيقية مع JS: تأخذ التركيز عند الفتح، وما خلفها `inert` مع `aria-modal`، و`Esc` أو زر الإغلاق يعيد التركيز إلى الزر الذي فتحها. بلا JS تبقى `:target` تعمل.
- الأرقام والأسعار لاتينية `tabular-nums`، والأرقام الطويلة (المحفظة، رقم العملية، رقم الطلب) بـ `dir="ltr"`.
- الأزرار المعطّلة لها دائمًا نص يشرح السبب («نفدت الكمية»، «أكمل الحد الأدنى»، «بانتظار الاتصال…»). لا زر معطّل صامت ولا زر وهمي: لا بوابات دفع إلكتروني ولا اشتراك برقم هاتف.

## 10. محتوى «مثال»

كل صورة وبطاقة ورأي ونص وعنوان ورقم في النموذج يحمل شارة **مثال** أو كلمة «مثال» صراحة (TE §6.3). شريط المعاينة أعلى كل صفحة يذكّر بذلك. المتجر المنشور لا يرسم `sample` أبدًا. حالة «منتج توضيحي» (زر معطّل) معروضة في لوحة حالات صفحة المنتج، وهي ما يراه التاجر في معاينة القالب المبدئي قبل إضافة منتجاته. أما بقية النموذج فيُحاكي متجرًا حيًّا ليمكن تجربة المسار كاملًا (منتج ← سلة ← دفع ← تتبّع).

---

## 11. فجوات ومقترحات لمالك `THEME_ENGINE.md`

| # | المقترح | السبب |
| --- | --- | --- |
| R-01 | توحيد مخرجات الشكل من المحرّك (`--sf-btn-*`, `--sf-card-*`, `--sf-gap`, `--sf-section-y`, `--sf-dur`, `--sf-announce-*`, `--sf-footer-*`, `--sf-radius-*`, `--sf-card-ratio`) | §2.1 أعلاه: حتى لا يشتق كل قالب الإعدادات بطريقته |
| R-02 | قيمة `motion: 'expressive'` اختيارية في الـ manifest (القوالب التي لا تعلنها تقرّبها إلى `subtle`) | §7. تبقى CSS فقط وتُلغى بتقليل الحركة |
| R-03 | إعداد style لكتلة الوصف `description.detailStrip: bool` | «شريط التفاصيل» في صفحة المنتج |
| R-04 | سطر «≈ ر.س» يحتاج `Store.showSarHint` وسعر الصرف (فجوة F03 الموجودة) | النموذج يعرضه بنص «تقريبي» |
| R-05 | `header.layout=logo_start_nav_below` لم يُصمَّم في راقي | مسموح بقيمتين فقط حتى يُصمَّم |
| R-06 | نصوص الواجهة الثابتة (أزرار الشراء، تسميات الدفع، رسائل السلة) تأتي من كتالوج نصوص المنصّة، لا من القالب، مع إعداد متجر لنبرة الخطاب | القالب لا يجب أن يفرض على التاجر صوتًا لم يختره (§13، UX-3) |
| R-07 | `resolveStorePalette()` يخرج أيضًا `--sf-ring-inverse` و`--sf-footer-ring` ويفحص الحلقة ≥ 3:1 مقابل كل سطح تُرسم عليه (الخلفية، `fg` للأقسام المقلوبة، التذييل، الإعلان) | راقي يحلّها محليًا بـ `currentColor`، لكن كل قالب سيقع في الخطأ نفسه |
| R-08 | رفع حد التعتيم في TE §2.4: ≥ 55 خلف نص عادي، ≥ 45 حين يكون النص كبيرًا فقط (بدل ≥ 35) | عند 35% يقيس النص الأبيض 2.4 فوق صورة فاتحة. يحتاج تعديل `themes*.ts` واختباراته، فتُرك لمالك العقد |
| R-09 | نسخة صورة 160w للمصغّرات (سلة، دفع، تتبّع، مصغّرات المعرض على المكتب) | أصغر نسخة اليوم 320w |
| R-10 | تقسيم CSS القالب: `base.css` (المتغيّرات، الرأس، الأزرار، النماذج، التذييل ≈ 4–5 KB gz) + ملف لكل قسم (`sec-hero.css`، `sec-product-grid.css`…) + ملف لكل قالب صفحة (منتج، مسار الثقة). المحرّك يضمّن الأساس وأقسام `homeSections` الموجودة فقط، ويربط الباقي `immutable` | راقي اليوم 9.5 KB gz مصغّرًا لكل الشاشات (تحت 12 KB)، لكن الرئيسية تشحن أنماط الدفع والعكس. التقسيم قرار في المحرّك لا في القالب، والحدود معلّمة بعناوين `/* ---------- … ---------- */` في `theme.css` |
| R-11 | سطر JS مشترك في `<head>` يكتبه المحرّك لكل القوالب (يضيف `.js` قبل أول رسم و`.in` للصور عند التحميل) | «استقرار الصور» في §7، ويمنع وميض العناصر `nojs-only` |

## 12. الملفات

```
design/themes/raqi/
├─ index.html        قائمة الشاشات + إطاران حيّان 375/1280
├─ home.html         الرئيسية (أقسام فقط)
├─ category.html     التصنيف + الفلاتر
├─ product.html      صفحة المنتج
├─ cart.html         السلة
├─ checkout.html     الدفع (صفحة واحدة)
├─ tracking.html     تتبّع الطلب
├─ theme.css         ملف القالب الوحيد، يقرأ --sf-* فقط
├─ demo.css          لوحات الحالات + حدود الأقسام + فهرس الشاشات (نموذج فقط)
├─ demo-tools.js     مبدّل اللوحات (نموذج فقط، يحاكي المعاينة الحيّة)
├─ img/*.svg         صور مثال بديلة خفيفة
└─ NOTES.md          هذا الملف
```
للتشغيل محليًا: `python -m http.server` داخل المجلد ثم افتح `index.html`. الصفحات تعمل أيضًا بفتحها مباشرة كملفات.

---

## 13. الرد على المراجعات (UX · الوصولية · الأداء) — 2026-10-01

طُبّق كل ما يلي في الملفات. ما رُفض أو طُبّق بشكل مختلف مشروح في الجدول الثاني.

### 13.1 ما طُبّق
| # | الملاحظة | ما تغيّر |
| --- | --- | --- |
| UX-1 | لا بحث حقيقي على الجوال | المكبّرة تفتح صف بحث `#search` (حقل 52px، `name=q`، `enterkeyhint=search`، تركيز مع JS)، والنموذج نفسه أعلى القائمة الجانبية، و`data-prod-action="/search"`. صفحة التصنيف تعرض تنبيه «نموذج» بالكلمة المبحوث عنها |
| UX-2 | الاسم والسعر تحت الطيّة في المنتج | سقف الصورة `56svh` على الجوال، النقاط فوق الصورة، الحاجب مخفي على الجوال، مسار التنقّل مخفي ومعه «‹ رجوع» في الرأس، شريط الشراء يظهر بعد تجاوز الأزرار فقط |
| UX-2 | التصنيف: أول بطاقة تحت الطيّة، والبانر يأخذ الأولوية | عنوان + عدد في سطر، الوصف والصورة من 900px، مصدر 1×1 للجوال، أول بطاقتين `fetchpriority=high` |
| UX-3 | نصوص بصيغة المؤنث فقط | كل نصوص المسار بصيغة المواصفة المحايدة: «أضف إلى السلة / اطلب الآن / اكتشف المجموعة / اختر المديرية / حوّل / توافق / وفّرت / أكمل الحد الأدنى / توقيت التحويل» |
| UX | تغيير اللون لا يغيّر الصورة | الجزيرة تبدّل الصورة الأولى ومصغّرتها ونصها البديل وتعيد المعرض للبداية |
| UX | مديرية مختارة مسبقًا | «اختر المديرية» هو الخيار الافتراضي، والحقل إلزامي |
| UX | «دفع آمن» في رأس الدفع | استُبدل بوسيلة مفعّلة فعلًا («الدفع عند الاستلام»)، ويُخفى إن لم تكن مفعّلة |
| UX | الشريط الثابت فوق لوحة المفاتيح | أثناء التركيز في أي حقل نصّي يعود شريط التأكيد إلى مكانه في الصفحة |
| UX | التكبير يعلق عند اللمس | كل تكبير بالمرور داخل `@media (hover:hover) and (pointer:fine)` |
| UX · States | حالة الإرسال وتبديل المحفظة غير موصولين | الإرسال يضع `aria-busy` و«جارٍ إرسال طلبك…» على كل أزرار التأكيد. تغيير المحفظة يبدّل الرقم واسمها وقيمة النسخ |
| UX | فتح القائمة يحمّل الرئيسية | روابط الإغلاق `href="#"` والجزيرة تمنع التنقّل وتعيد التركيز |
| A11Y-B1 | الحلقة تختفي على الأسطح الداكنة | `--sf-ring: currentColor` على `.tone-dark, .ftr, .announce, .pv-bar` |
| A11Y-B2 | الأزرار والروابط في `.tone-dark` تختفي | قواعد الزوج المقلوب للزرّين ولحالة المرور، `--sf-link: currentColor`، خط الاقتباس `currentColor`، حذف الـ style المضمّن |
| A11Y-B3 | النص فوق البانر باهت | التدرّج الجديد ≥ 55% خلف كل سطر |
| A11Y-M1 | التركيز تحت الرأس والأشرطة الثابتة | `scroll-padding` حسب الصفحة (§9) |
| A11Y-M2 | القائمة وورقة الفلاتر ليست حوارات | جزيرة 0.6 KB: تركيز، `inert`، `aria-modal`، `Esc`، إعادة التركيز |
| PERF-1 | 3 ملفات خطوط | ملفان فقط في كل الصفحات و`demo-tools.js` |
| PERF-2 | صور `lazy` تُجلب على أي حال | `data-src` + IntersectionObserver + `<noscript>` للشرائح 2–4 وشريط التفاصيل |
| PERF | CSS النموذج يُشحن مع القالب | فُصل `demo.css`، و`theme.css` = 11.1 KB |

### 13.2 ما رُفض أو طُبّق بشكل مختلف
| الملاحظة | القرار | السبب |
| --- | --- | --- |
| UX-2: إظهار شريط الشراء بعد خروج `#price-block` | **طُبّق على أزرار الشراء بدل كتلة السعر** | إن ظهر الشريط بعد السعر مباشرة يرى المتسوّق زرّي شراء مكرّرين (الشريط والنموذج) أثناء اختيار المقاس، ويغطّي الشريط الحقول. الظهور بعد تجاوز الأزرار يحقق الهدف (الشراء في متناول الإبهام دائمًا) بلا تكرار |
| UX-3: أخذ كل النصوص من كتالوج المنصّة | **طُبّق جزئيًا: صيغة محايدة الآن + مقترح R-06** | الكتالوج والإعداد ليسا في العقد بعد، ولا يملكهما القالب. القالب يستخدم نصوص المواصفة كما هي حتى يوجد الكتالوج |
| PERF-1: استضافة الخطوط ذاتيًا مع `size-adjust` في النموذج | **مؤجّل للإنتاج** | النموذج ملفات ثابتة بلا خادم ولا ملفات خطوط في المستودع. القرار موثّق في §8 ويطبّقه مسار `/_fonts/` في المحرّك |
| PERF: استبدال المصغّرات بنقاط CSS | **على الجوال فقط** | على الجوال كانت مخفية أصلًا. على المكتب المصغّرات الجانبية جزء من `gallery.thumbs=side` في المواصفة، والحل الصحيح نسخة 160w (R-09) |
| A11Y follow-ups للمحرّك (`--sf-ring-inverse`، حد التعتيم 55/45) | **مقترحات R-07 وR-08** | تغيّر العقد واختبارات `themes*.ts`، فتُترك لمالك `THEME_ENGINE.md`. راقي نفسه مستوفٍ الآن |
| الحركة البطيئة موجودة فقط في `expressive` غير الموجودة في العقد | **أُبقيت كمقترح (R-02)، والافتراضي `subtle`** — *حُدّث في §14: صار في `subtle` تلاشٍ ناعم للصور* | الهدوء يأتي من الطباعة والمساحات لا من الحركة. وصف القالب في أعلى هذا الملف صُحّح كي لا يَعِد بحركة بطيئة |

---

## 14. جولة الصقل الثانية (UX · الوصولية · الأداء) — 2026-10-03

تحقّقتُ من السلوك في متصفح داخل إطار 375×667 (قياسات DOM، وليس Lighthouse): المقاس الناقص، الإضافة الناجحة، الفشل وإعادة المحاولة بالمفتاح نفسه، ملخّص أخطاء الدفع، وموضع الزر في الشاشة الأولى.

### 14.1 ما طُبّق
| # | الملاحظة | ما تغيّر |
| --- | --- | --- |
| UX-1 | الصورة تقصّ العباءة الطويلة على الجوال | الشريحة بسقف `min(4:3 من العرض، 60svh)` والصورة `object-fit: contain` فوق `surface-muted`: القطعة كاملة دائمًا بالأكمام والذيل. على 375×667 أسفل السعر عند ≈ 597px (مع شريط المعاينة) فوق شريط الشراء مباشرة |
| UX-2 | لا زر شراء قريب في الشاشة الأولى | شريط الشراء ظاهر من البداية بالسعر وزر رئيسي واحد، ويتنحّى فقط ما دامت أزرار الصفحة ظاهرة (`bb-off`). حُذف «اطلب الآن» من الشريط وبقي في الصفحة |
| UX-2 | المقاس 56 مختار مسبقًا | لا اختيار مسبق. الأزرار تقول «اختر المقاس»، والنقر يمرّر إلى المجموعة ويُظهر «اختر المقاس أولًا» ويركّز على أول مقاس متوفر. بلا JS يوقف `required` الإرسال. سطر المخزون قبل الاختيار «متوفر · اختر المقاس» والسعر يتبع اللون |
| UX-3 | الإضافة بلا حالة «جارٍ…» ولا تعافٍ | اعتراض بـ `fetch` + `Idempotency-Key` ثابت للاختيار نفسه، تعطيل أثناء الإرسال فقط، مهلة 20 ث، تنبيه ثابت مع «أعد المحاولة» (الاختيارات محفوظة)، ورقة «أُضيفت إلى السلة» حيّة + تحديث عدّاد السلة ونصه لقارئ الشاشة، `pageshow` يعيد الأزرار |
| UX-3 | زر الدفع يعلق معطّلًا ويضيع الإجمالي | النص في `<span class="lbl">` والإجمالي في عنصر مستقل. `pageshow` يعيد الأزرار. 20 ث ← «جارٍ التحقق من طلبك…» + «لا تغلق الصفحة… لن يُكرَّر طلبك». 45 ث ← «أعد المحاولة» مفعّل بالمفتاح نفسه. حدث `offline` يطمئن المتسوّق |
| UX-4 | الدفع طويل ولا تحقق | الحي والشارع والموقع في `<details>` «إضافة تفاصيل للعنوان»، والملاحظة في «إضافة ملاحظة للمتجر»: 7 حقول ظاهرة. المحافظة بلا اختيار مسبق والمديرية معطّلة حتى تُختار، وطرق التوصيل تظهر بعدها. تحقق عند الإرسال بملخّص `role="alert"` بروابط تركّز الحقل، رسالة تحت كل حقل مع `aria-invalid` و`aria-describedby`، تركيز أول خطأ، والزر يبقى مفعّلًا. بلا JS يعمل تحقق المتصفح (أُزيل `novalidate` من الوسم، والجزيرة تضعه برمجيًا) |
| UX-4 | (ملحق) إجمالي غير صحيح قبل معرفة التوصيل | الزر لا يعرض إجماليًا حتى تُعرف الرسوم، والملخّص يقول «63,500 ر.ي + التوصيل»، ومبلغ التحويل يظهر بعد اختيار المحافظة |
| UX-5 | الشاشة الأولى في الرئيسية صورة بلا رسالة | صورة الـ hero بسقف `46svh` و`object-position: 50% 22%`، الحاجب مخفي على الجوال، والزر يأتي بصريًا تحت العنوان. أسفل الزر ≈ 605px على 375×667 في الإنتاج |
| UX-5 | لا فخامة بطيئة على الجوال | «استقرار الصور» (تلاشٍ 450ms) جزء من `subtle` (§7) |
| A11Y-M1 | الترتيب يُرسَل عند التغيير | حُذف الإرسال التلقائي، وزر «تطبيق» ظاهر دائمًا |
| A11Y-M2 | الـ placeholder يفشل AA | `::placeholder { color: var(--sf-fg-muted); opacity: 1 }` للحقول والبحث وtextarea |
| A11Y-M3 | تصادم التشكيل في العناوين | `.hero-title` و`.plp-head h1` و`.logo b` = 1.4، `.btn` = 1.5، و`.ord-no` بقي 1.1 (أرقام فقط) |
| A11Y-M4 | «بقيت 1 قطع» | دالة `pcs()`: قطعة واحدة · قطعتان · 3–10 قطع · 11+ قطعة، في المنتج والسلة (العنوان وعدّاد الرأس ونصه). «المتاح قطعتان فقط». «بقيت 3 قطع» الثابتة في السلة صحيحة فبقيت |
| A11Y-M5 | أهداف لمس أقل من 44px | النقاط 44×44 (النقطة المرئية 6px)، `.chip` و`.check` و`.ftr li a` و`.copy` و`.toolbar .btn-2` وكمية السلة و`.active-filters a` كلها 44px، وروابط ملخّص الأخطاء 44px |
| A11Y-M6 | النقطة غير النشطة 1.3:1 | `var(--sf-border)` (3.3 / 3.9 / 3.3) |
| UX | (وجدتُه أثناء العمل) «حين تختارن قطعة» في سلة فارغة | «حين تختار قطعة» (صيغة محايدة، UX-3 السابقة) |

### 14.2 ما رُفض أو طُبّق بشكل مختلف
| الملاحظة | القرار | السبب |
| --- | --- | --- |
| UX-1: صورة 4:5 بسقف 62svh مع `object-position: 50% 15%` | **`contain` بسقف 60svh بدل القصّ الموجَّه** | أي `cover` بنسبة أقصر من 3:4 يقصّ شيئًا: مع 50% 15% يضيع الذيل بدل الأكمام. الهدف «القطعة كاملة» لا يتحقق إلا بـ `contain`، والأرضية `surface-muted` تجعل الهامش الجانبي (≈ 30px) يبدو كإطار عرض. 62svh كان سيدفع السعر خلف الشريط الثابت |
| UX-2: إظهار الشريط من البداية «دائمًا» | **ظاهر من البداية، ويتنحّى فقط فوق أزرار الصفحة** | بهذا لا يظهر زرّا «أضف إلى السلة» معًا على الشاشة، وهو ما طلبته المراجعة نفسها («لا تتكرر الأزرار»). يخالف رسم المواصفة 03 (زرّان في الشريط، يظهر بعد السعر) عن قصد ولسبب المراجعة نفسه |
| UX-3: إعادة إرسال تلقائية ×3 في الدفع (المواصفة 05) | **في الإنتاج فقط** | النموذج يُرسَل كنموذج HTML عادي إلى صفحة ثابتة، فلا يمكن إعادة المحاولة تلقائيًا دون خادم. المحاكاة: «جارٍ التحقق» عند 20 ث ثم «أعد المحاولة» يدويًا بالمفتاح نفسه. موثّق في رأس الجزيرة |
| PERF-1: استضافة الخطوط ذاتيًا | **مؤجّل للإنتاج (كما في §13.2)**، والمراجعة قبلت ذلك | لا ملفات خطوط ولا خادم في النموذج. الخطة في §8 |
| PERF-2: تقسيم `theme.css` حسب الأقسام | **مقترح للمحرّك (R-10 محدَّث)، لم يُقسَّم الملف في النموذج** | المصغّر 9.5 KB gz لكل الشاشات، تحت حد 12 KB. التضمين حسب `homeSections` يقرّره المحرّك عند الرسم، والقالب جاهز له: الأقسام مفصولة بعناوين واضحة ولا تعتمد على بعضها |
| A11Y: القائمة «minor» (17 ملاحظة) | **لم تصلني كاملة** | نص المراجعة انقطع بعد M6، فلم أرَ الملاحظات الصغرى ولا فشلَي تباين الواجهة الآخرين المذكورين فيها. طُبّق كل ما وصل. M5 وM6 يغطيان على الأرجح جزءًا منها (أهداف اللمس، النقاط) |
| حجم JS | زاد من 2.5 إلى ≈ 4.2 KB gz (غير مصغّر) في المنتج | ثمن الإضافة الحقيقية والتعافي والتحقق. يبقى أقل من 5% من حد 100 KB |
