# مرحله ۱۴ — بسته‌ی کامل گرافیک: خلاصه

بزرگ‌ترین مرحله تا الان (۱۳ زیرمرحله). فایل «پیش‌گفتار ذهن باز» رو اول خوندم و جدی گرفتم — چند جا عمداً از Spec فراتر رفتم و پایین توضیح دادم کجا و چرا.

## فایل‌های جدید

| فایل | زیرمرحله | نقش |
|---|---|---|
| `brand.php` | ۱۴.۰۱ + ۱۴.۰۲ | **منبع واحد حقیقت** رنگ و فونت. هر رنگ هم Hex هم RGB داره. صدا زدن یه رنگ خارج از پالت، Exception می‌ده — یعنی «رنگ دلخواه» از نظر فنی ممکن نیست، نه فقط ممنوع. |
| `assets/css/brand-tokens.css` | ۱۴.۰۱ + ۱۴.۱۰ | توکن‌های CSS مینی‌اپ، تم روشن/تاریک، RTL، کامپوننت‌های پایه. |
| `assets/icons/*.svg` | ۱۴.۰۳ | ۱۸ آیکون مفهومی + ۵ بج سطح ربات (چک‌لیست ۱۵ تا خواسته بود). |
| `graphics.php` | ۱۴.۰۴–۱۴.۰۸ | موتور GD: نمودار سیگنال، کارت کیف‌پول، رسید تراکنش، کارت پروفایل، بنر خوش‌آمدگویی. |
| `api.php` | ۱۴.۰۰ | API مینی‌اپ با اعتبارسنجی HMAC-SHA256. |
| `test-graphics.php` | ۱۴.۱۲ | QA خودکار. |
| `fonts/README.md` | ۱۴.۰۲ | راهنمای نصب فونت‌ها + جدول حجم. |

## نتایج تست خودکاری که همین‌جا اجرا کردم

**تطبیق رنگ (چک‌لیست ۱۴.۱۲ ردیف ۱):** هر ۱۵ رنگ مشترک بین `brand.php` و CSS، به‌علاوه هر ۶ رنگ تم روشن، دقیقاً یکی هستن. ✅

**کنتراست WCAG:** هر ۸ ترکیب رنگ/پس‌زمینه پاس شدن. یه نکته‌ی مهم اینجا پیدا شد:

> چک‌لیست ۱۴.۰۱ حدس زده بود «طلایی روی مشکی ممکنه کم‌کنتراست بشه». تست نشون داد برعکسه: طلایی روی مشکی عالیه (**۸.۶۲:۱**)، ولی طلایی روی **پس‌زمینه‌ی روشن** فاجعه‌ست (**۲.۱۰:۱** — مردود). برای همین یه رنگ جدید به پالت اضافه کردم که در Spec نبود: `gold_on_light` (`#8A661C`) که ۴.۹۱:۱ می‌ده. تم روشن خودکار ازش استفاده می‌کنه.

**ماسک شماره کارت:** هر ۳ فرمت (پیوسته، با خط تیره، با فاصله) درست ماسک می‌شن و مبالغ معمولی («۱,۲۵۰,۰۰۰ تومان») دست‌نخورده می‌مونن. ✅

## جاهایی که از Spec فراتر رفتم (طبق پیش‌گفتار)

1. **`gold_on_light`** — بالا توضیح داده شد. بدون این، تم روشن عملاً ناخوانا بود.
2. **بج‌ها فقط با رنگ از هم جدا نمی‌شن.** Spec گفته بود هر سطح یه رنگ داشته باشه. من به هرکدوم **شکل قاب متفاوت** هم دادم (دایره / دایره / دایره / چندضلعی / مربع‌گرد) به‌علاوه نماد داخلی متفاوت. دلیل: کاربر کوررنگ با تفاوت صرفاً رنگی، Pro و Personal رو از هم تشخیص نمی‌ده.
3. **کلاس `.num` در CSS** — هر عدد مالی `direction: ltr; unicode-bidi: isolate` می‌گیره. بدون این، الگوریتم Bidi وسط متن فارسی/عربی، اعداد منفی رو جابه‌جا نشون می‌ده. این همون مشکلیه که مرحله ۳ برای پیام متنی حل کرده بود؛ اینجا برای مینی‌اپ تکرارش کردم.
4. **`prefers-reduced-motion`** — همه‌ی انیمیشن‌ها برای کاربرهایی که این تنظیم رو فعال کردن خاموش می‌شن. برای بعضی افراد حرکت باعث سرگیجه‌ی واقعی می‌شه.
5. **ضدهم‌پوشانی برچسب‌های نمودار** — چک‌لیست ۱۴.۰۴ فقط گفته بود «نباید هم‌پوشانی داشته باشن». یه الگوریتم واقعی نوشتم که خط‌ها رو مرتب می‌کنه و هر برچسبی که کمتر از ۲۰ پیکسل به قبلی نزدیکه، هل می‌ده پایین — به‌علاوه یه پس‌زمینه‌ی نیمه‌شفاف زیر هر برچسب تا روی خط قیمت گم نشه.

## اتصال به ربات (واقعاً وصل شد، نه فقط ساخته شد)
- **سیگنال‌ها** حالا با نمودار ارسال می‌شن (`sendPhoto` به‌جای `sendMessage`).
- **صفحه‌ی کیف‌پول** با کارت گرافیکی موجودی.
- هر دو با **Fallback کامل**: اگه GD نصب نباشه، فونت نباشه، یا تولید عکس شکست بخوره، دقیقاً همون پیام متنی قبلی ارسال می‌شه. نبودِ عکس هیچ‌وقت باعث نمی‌شه سیگنال به کاربر نرسه.
- `graphics.php` با `is_file` چک می‌شه و هر استفاده‌ای `class_exists` داره — یعنی اگه فایل‌های گرافیک رو آپلود نکنید، ربات **دقیقاً مثل قبل** کار می‌کنه.

## امنیت API (۱۴.۰۰)
- هویت **فقط** از `initData` امضاشده‌ی تلگرام. کاربر نمی‌تونه با دست‌کاری `chat_id` موجودی یکی دیگه رو ببینه.
- `hash_equals` برای مقایسه (ضد Timing Attack)، و رد کردن `initData` قدیمی‌تر از ۱ ساعت (ضد Replay).
- **فقط-خواندنی**: هیچ عملیات مالی (واریز/معامله/برداشت) از API ممکن نیست — همه باید از مسیر ربات با تأییدهای مراحل ۹–۱۲ رد بشن.
- مقصد برداشت حتی برای خود کاربر ماسک می‌شه (ممکنه در کش مرورگر بمونه).

## ⚠️ کارهای باقی‌مونده روی سرور شما

1. **فونت‌ها رو نصب کنید** — `fonts/README.md` رو ببینید. بدون این، عکس‌ها ساخته می‌شن ولی متن فارسی/چینی/کره‌ای به‌صورت مربع خالی درمیاد. حجم کل ~۳۷ مگابایت (Noto SC و KR بزرگن).
2. **`php -m | grep gd`** — اگه نبود: `apt install php-gd`.
3. **`php test-graphics.php` رو اجرا کنید** — پوشه‌ی `qa-output/` می‌سازه با کارت پروفایل هر ۲۱ زبون + نمودارها + رسیدها.
4. **پوشه‌ی `qa-output/` رو باز کنید و با چشم نگاه کنید.** این تنها بخشیه که هیچ اسکریپتی نمی‌تونه جای شما انجام بده: شکستگی متن، ظاهر RTL فارسی/عربی/عبری، خوانایی چینی در اندازه‌ی کوچیک.
5. `api.php` رو در مسیر وب بذارید (برخلاف `.env` که باید بیرون باشه).

## زیرمرحله‌های ۱۴.۰۹ و ۱۴.۱۱
انیمیشن (۱۴.۰۹) و وایرفریم کامل مینی‌اپ (۱۴.۱۱) عمداً به مرحله ۱۵ موکول شدن، چون هر دو صفحه‌های واقعی مینی‌اپ رو لازم دارن که مرحله ۱۵ می‌سازتشون. پایه‌شون آماده‌ست: توکن‌های CSS، `prefers-reduced-motion`، و کلاس‌های کامپوننت همه توی `brand-tokens.css` هستن.
