مبانی طراحی
توکنها کوچکترین واحدهای سیستماند: رنگ، قلم، فاصله، شعاع، سایه، آیکون و حرکت. هیچ مقدار خامی خارج از این توکنها در کد محصول نباید ظاهر شود. نسخهٔ تعاملی همین صفحه را با سواچهای زنده نشان میدهد (با تغییر پوسته روشن/تاریک، همهچیز عوض میشود).
۱. رنگها
پالت از شش نقش ساخته شده: پسزمینه، سطح، متن، خط، برند و معنایی — بهعلاوهٔ یک پالت ۸رنگی مقولهای برای تقویمها و رویدادها. هر توکن در پوستهٔ تاریک معادل روشنشدهٔ خودش را دارد؛ کامپوننتها هرگز رنگ خام نمیبینند.
برند — آبی واحد #2563EB
یک آبی واحد در کل محصول (وب و موبایل). آبی برند رنگِ کنش است: دکمهٔ اصلی، حالت فعال، لینک — و هیچجای دیگری.
| توکن | مقدار |
|---|---|
--brand | #2563EB (تاریک: #8FB4FF) |
--brand-deep | #004AC6 |
--brand-container | ۱۱٪ |
--on-brand-container | #0B2E6B |
سطوح — نردبان پنجپلهای
جداسازی سطحها با خط انجام میشود، نه سایه؛ سایه فقط برای لایههای شناور (§۴).
| توکن | روشن | تاریک | کاربرد نمونه |
|---|---|---|---|
--bg | #FBFBFC | #101318 | پشت صفحهٔ اصلی و ستونهای تقویم |
--surface | #FFFFFF | #181C22 | کارت، دیالوگ، نوار بالا |
--surface-1 | #F5F6F8 | #1F242B | هاور دکمهٔ outline، زمینهٔ فرمهای داخل دیالوگ |
--surface-2 | #EFEFF2 | #262B33 | هاور آیکونباتن، سلولهای خالی ماه |
--surface-3 | #E8E9ED | #2E343D | سوییچ خاموش، ریلهای عقبتر |
متن و خط
--fg #1B1E24 (اصلی) · --muted #565D6A (ثانویه) · --faint #8A909C
(کمکی) · --border · --border-strong
رنگهای معنایی
قرمز تعطیلات با قرمز خطا عمداً متفاوتاند: تعطیلات دادهٔ تقویم است، خطا پیام سیستم.
| توکن | روشن | تاریک | فقط کجا |
|---|---|---|---|
--holiday | #D41317 | #FF8A80 | روز جمعه و تعطیلات، تاریخ موعد گذشته، دکمهٔ حذف |
--error | #BA1A1A | #FFB4AB | خطای اعتبارسنجی فرم، شکست عملیات |
--warn + --warn-container | #9A5B00 | #F5C064 | بنر تعارض همگامسازی، پیامهای احتیاطی |
--ok | #067A57 | #8AD8B4 | وضعیت «انجامشده»، تأیید موفق |
پالت مقولهای تقویمها — ۸ رنگ
هر تقویمِ کاربر یکی از این هشت رنگ را میگیرد (--ev-1..8: آبی، سبز، فیروزهای،
کهربایی، قرمز، صورتی، بنفش، قهوهای)؛ رویدادها، نقطهها و چکباکسها همه از رنگ
تقویمِ والد رنگ میگیرند. در پوستهٔ تاریک همین رنگها با color-mix روشن میشوند.
بایدر / نبایدر
- ✅ آبی برند فقط برای اکشن اصلی و حالت فعال — در هر نما حداکثر یک دکمهٔ پر.
- ✅ قرمز تعطیلات فقط روی دادهٔ تقویم (روز، تاریخ، موعد) و دکمهٔ حذف.
- ✅ همهٔ رنگهای جدید از توکنها یا
color-mixروی توکنها ساخته میشوند. - ❌ هگز خام جدید در کامپوننتها — پوستهٔ تاریک را میشکند.
- ❌ قرمز تعطیلات برای برچسب «جدید»، بج تخفیف یا دکوراسیون.
- ❌ گرادیان روی سطوح بزرگ؛ سایهدادن بهجای خط برای جداسازی کارتهای درونصفحه.
۲. تایپوگرافی
یک خانوادهٔ واحد: Dana. برای محصول دادهمحورِ راستچین، خانوادهٔ تک هم سادهتر است و هم رندر ارقام فارسی را در همهٔ وزنها یکدست نگه میدارد؛ تمایز سلسلهمراتب با اندازه و وزن ساخته میشود، نه فونت دوم.
| مقیاس | px / وزن / line-height | کجا |
|---|---|---|
| عنوان صفحه | ۲۸ / ۸۰۰ / 1.30 | view h1 · docs h1 |
| عنوان بخش و دیالوگ بزرگ | ۲۱ / ۸۰۰ / 1.35 | section h2 |
| عنوان دیالوگ و کارت | ۱۷ / ۷۰۰ / 1.35 | .dialog-head h2 |
| متن بدنه | ۱۵ / ۴۰۰–۵۰۰ / 1.65 | body base |
| دکمه و برچسب فرم | ۱۴ / ۶۰۰ / 1.00 | .btn · label |
| متن رابط فشرده | ۱۳.۵ / ۵۰۰ / 1.60 | .tabpill · .menu · .toast |
| چیپ و برچسب کوچک | ۱۲.۵ / ۵۰۰ / 1.60 | .chip |
| عدد روز و خطای فیلد | ۱۲ / ۵۰۰ / 1.60 | .mday · .err |
| نشان و سرستون هفته | ۱۱ / ۷۰۰ / 1.60 | .badge · .wrow |
محصول فعلاً وزنهای ۴۰۰–۷۰۰ را self-host میکند (وب و مستندات) و ارقام فارسی
را در کد تولید میکند (utils/persianUtils)؛ پروتوتایپها Dana FaNum
(ارقام تعبیهشده، تا وزن ۸۰۰) دارند. هنگام پیادهسازی وزنهای ۸۰۰ عنوانها، فونت
باندل را گسترش بده.
قواعد ارقام فارسی
| قاعده | مثال | ابزار |
|---|---|---|
| همهٔ اعداد نمایشی فارسیاند | ۷ شهریور · ۰۹:۳۰ · ۱۵ رویداد | J.fa(n) — رقمفرد |
| اعداد دورقمی با صفر ابتدایی | ۰۹:۰۵ | J.fa2(n) |
| ورودی کاربر با رقم فارسی پذیرفته و نرمال میشود | «۰۹۱۲…» ← 0912… | J.en(str) |
| اعداد جدولی همعرض میمانند | 08:00 ← 09:00 ← 10:00 | کلاس .num (tabular-nums) |
| letter-spacing در متن فارسی هرگز افزایش نمییابد | — | — |
۳. فاصله و شکل
واحد پایه ۴ پیکسل است؛ همهٔ فاصلهها مضرب آناند: 4 · 8 · 12 · 16 · 20 · 24 · 32 · 44 — «۴ و ۸ داخل کامپوننت (گپ آیکون-متن) · ۱۲ و ۱۶ بین فیلدها و بخشها · ۲۰ و ۲۴ پدینگ بدنهٔ دیالوگ و کارت · ۳۲+ بین بخشهای صفحه · ۴۴ حداقل هدف لمسی».
| شعاع | توکن | کجا |
|---|---|---|
| 8 | --r-sm | آیتم منو، بلاک کد، سواچ |
| 10 | — | فیلد ورودی، سلکت، جعبهٔ OTP |
| 12 | --r-md | دکمه، کارت، منو، توست (پیشفرض کامپوننتها) |
| 16 | --r-lg | دیالوگ دسکتاپ |
| 24 | --r-xl | گوشههای بالای برگهٔ پایین موبایل |
| کامل | 99px | چیپ، تب قرصی، نشان، دکمهٔ آیکونی، روزهای تقویم |
قاعدهٔ ترکیب: یک نما حداکثر سه شعاع متفاوت همزمان نشان میدهد؛ نزدیکترین شعاع به مقیاس رند میشود، مقدار سفارشی ساخته نمیشود.
۴. سایه و عمق
هرچیز «شناور روی صفحه» سایه دارد، هرچیز «داخل صفحه» با خط جدا میشود:
- سایه ۱ — هاور دکمه، کارت ساده
- سایه ۲ — FAB، توست
- سایه ۳ — منو، دیالوگ
- اسکریم — پشت دیالوگ ۴۵٪ + بلور ۳px
✅ سایه فقط وقتی عنصر روی محتوا شناور میشود؛ پشتصحنه با اسکریم + بلور ملایم
کمرنگ میشود. ❌ سایه روی کارتهای داخل صفحه (خط 1px --border کافی است)؛ سایههای
رنگی یا چندلایهٔ نمایشی.
۵. آیکونوگرافی
SVG درونخطی با قرارداد ثابت: شبکهٔ ۲۴×۲۴، ضخامت خط ۱٫۸، انتهای گرد، بدون
پرشدگی، رنگ از currentColor. ایموجی هیچوقت جای آیکون رابط نمینشیند (ایموجی فقط
دادهٔ کاربر است — نام تقویمها).
| اندازه | کجا |
|---|---|
| 24 | FAB، ریل ناوبری |
| 20 | دکمهٔ آیکونی استاندارد (40px) |
| 17 | آیکون داخل دکمهٔ متنی و آیتم منو |
| 16 | دکمهٔ آیکونی کوچک (30px) و متادیتای فشرده |
<svg viewBox="0 0 24 24" width="20" height="20"
fill="none" stroke="currentColor" stroke-width="1.8"
stroke-linecap="round" stroke-linejoin="round">…</svg>
همیشه width و height صریح روی SVG بنویسید — SVG بدون ابعاد در چیدمان فلکس
باد میکند.
۶. حرکت
حرکت باید کارِ رابط را توضیح دهد: از کجا آمد، کجا میرود. یک منحنی واحد:
| مقدار | کاربرد |
|---|---|
--ease: cubic-bezier(.2,0,0,1) | همهٔ ترنزیشنها — شتابگیری سریع، فرود نرم (امضای MD3) |
| 80–120ms · transform | فشردن دکمه (translateY 1px)، مقیاس FAB |
| 150–160ms · رنگ/خط/پسزمینه | هاور چیپ، دکمه، آیکونباتن |
| 180–240ms · transform+opacity | باز/بستهشدن دیالوگ (14px جابهجایی + محو)، توست، اسکریم |
| 800ms · چرخش خطی | اسپینر بارگذاری |
prefers-reduced-motion همهٔ انیمیشنها را به ۰٫۰۱ms میرساند — کامپوننتهای
جدید نباید این را دور بزنند. فقط transform و opacity انیمیت میشوند؛
عرض/ارتفاع هرگز.
۷. جهت و تقویم جلالی
راستچین بودن و تقویم جلالی جزو بنیادها هستند، نه تنظیمات منطقهای.
راستچین اصیل
| بهجای | بنویس | چرا |
|---|---|---|
margin-left / right | margin-inline-start / end | با جهت سند خودکار برمیگردد |
left / right (position) | inset-inline-start / end | مثل بالا |
text-align: right | text-align: start | پیشفرض RTL خودش درست است |
| آیکون جهتدار بدون قرینه | قرینه در RTL | فلشهای «بعدی/قبلی» ماه باید معنی درست بدهند |
| رقم و ساعت بهارث از جهت متن | .ltr یا unicode-bidi هدفمند | 09:30 در جملهٔ فارسی نباید 30:09 شود |
شبکهٔ هفته و تعطیلات
هفته از شنبه شروع میشود؛ سرستونها «ش ی د س چ پ ج» (آرایهٔ J.WD_SHORT).
جمعه همیشه قرمز است و روزهای تعطیل ثابت شمسی هم — با همان --holiday.
قرمز = جمعه/تعطیل · توپ آبی = امروز (پر برند) · حلقه = انتخابشده.
تعطیلات ثابت شمسی
جدول J.HOLIDAYS (ماه-روز جلالی): ۱ تا ۴ فروردین (نوروز) · ۱۲ و ۱۳ فروردین
(جمهوری اسلامی و طبیعت) · ۱۵ خرداد · ۱۳ آبان · ۲۲ بهمن · ۱۴ اسفند · ۲۹ اسفند
(ملی شدن نفت). J.isHoliday(date) جمعهها را هم شامل میشود.
API موتور جلالی
| تابع | خروجی | مثال |
|---|---|---|
J.dateToJ(date) | {jy, jm, jd} | ← ۱۴۰۵/۶/۷ |
J.jToDate(j) | Date میلادی | برای محاسبات و مقایسه |
J.todayJ() | امروز جلالی | لنگر «امروز» در همهٔ نماها |
J.fmtJ(j) / fmtJMed / fmtJFull | رشتهٔ تاریخ | «۷ شهریور ۱۴۰۵» / «۷ شهریور» / «شنبه ۷ شهریور ۱۴۰۵» |
J.isHoliday(j) · isFriday(j) | boolean | رنگکردن روز، خطخوردن موعد |
J.jDaysInMonth(jy, jm) | ۲۹/۳۰/۳۱ | ساخت شبکهٔ ماه با کبیس دقیق |
J.jAddDays(j, n) · cmpJ(a, b) | جابهجایی / مقایسه | رویدادهای چندروزه، مرتبسازی |
سال کبیسی با الگوریتم ۳۳سالهٔ محاسبه میشود و در برابر تاریخهای مرجع (۱ فروردین ۱۴۰۵ = 21 March 2026) تست شده است.