DESIGN SYSTEM · v1
نظام التصميم
مرجع حيّ لجميع المكوّنات الأساسية في نور. يستخدمه المساهمون لمعرفة ما هو متاح، وكيفية استدعائه، وكيف يبدو في الإنتاج.
الألوان والطباعة
نظام الألوان مبنيّ على إيفوري + التيركوازي العميق + الرملي الدافئ. تستخدم الواجهة Cairo و Tajawal للنص، و Amiri للعناوين والاقتباسات.
وضع النهار
وضع الليل (Midnight)
font-amiri (عناوين)
لكُلّ شيءٍ سببٌ ونتيجة
font-tajawal (نص)
هذا نصٌ تجريبيّ بخطّ تجوّل يُستعمل في المتن.
font-cairo (واجهة)
أزرار وعناصر التحكّم تستخدم Cairo
Card
حاوية أساسية بإطار خفيف وظلّ ناعم. مكوّنات فرعية: CardHeader، CardBody، CardTitle.
عنوان البطاقة
محتوى البطاقة هنا — نصّ، نموذج، أو أي عنصر يستحقّ التأطير.
<Card>
<CardHeader>
<CardTitle>عنوان البطاقة</CardTitle>
</CardHeader>
<CardBody>
محتوى البطاقة هنا — نصّ، نموذج، أو أي عنصر آخر.
</CardBody>
</Card>حُم على هذه البطاقة
سترتفع قليلًا مع ظلّ أعمق.
<Card className="card-hover cursor-pointer">
<CardBody>...</CardBody>
</Card>Input / Textarea
حقول إدخال نموذجية بإطار رمليّ خفيف وحلقة تركيز تيركوازية.
<Input placeholder="ابحث في المصادر..." />
<Input type="email" placeholder="example@domain.com" dir="ltr" /><Textarea placeholder="اكتب ملاحظاتك..." rows={4} />Badge
شارات صغيرة لإبراز حالة أو وسم. خمسة متغيّرات: default, teal, sand, rose, ochre.
<Badge>افتراضي</Badge>
<Badge variant="teal">جديد</Badge>
<Badge variant="sand">رملي</Badge>
<Badge variant="rose">عاجل</Badge>
<Badge variant="ochre">مميّز</Badge>Toast
إشعارات قصيرة تظهر أسفل اليسار. تستدعى بشكل أمري عبر hook useToast(). الـ Toaster مثبّت في الـ layout الجذري.
import { useToast } from "@/lib/use-toast";
const toast = useToast();
toast.success("تم الحفظ", "حُفظت المسودة بنجاح");
toast.error("فشلت العملية", "تأكّد من اتصالك بالشبكة");
toast.info("معلومة", "هذه نسخة تجريبية");Confirm Dialog
تأكيد بسيط (نعم/لا) باستدعاء أمري ينتظر قرار المستخدم. يُستخدم بدلًا من window.confirm().
import { confirm } from "@/components/ui/confirm-dialog";
const ok = await confirm({
title: "حذف المسودة؟",
description: "لا يمكن التراجع.",
confirmLabel: "حذف",
variant: "destructive",
});
if (ok) deleteDraft();Prompt Dialog
حقل إدخال نصّي أمري. يدعم نوع الحقل (text/url/email) واتجاه الكتابة. يُستخدم بدلًا من window.prompt().
import { promptText } from "@/components/ui/confirm-dialog";
// نصّ عربي عادي
const name = await promptText({
title: "ما اسمك؟",
placeholder: "مثلًا: محمد العتيبي",
});
// رابط (LTR)
const url = await promptText({
title: "إدراج رابط",
inputType: "url",
inputDir: "ltr",
defaultValue: "https://",
});Skeleton
عناصر تحميل بنبضة هادئة. أربعة مستويات: Skeleton الأساسي، CardSkeleton، ListItemSkeleton، TextSkeleton.
<Skeleton className="h-6 w-40" />
<Skeleton className="h-4 w-full" />
<Skeleton className="h-10 w-32 rounded-lg" /><CardSkeleton />
<ListItemSkeleton />
<TextSkeleton lines={4} />Empty State
رسالة وسطية تُعرض عندما لا توجد بيانات. يدعم أيقونة، عنوانًا، وصفًا، وزرّ إجراء.
<EmptyState
icon={<BookMarked className="w-8 h-8" />}
title="لا توجد مصادر بعد"
description="ابدأ بحفظ المصادر من مكتبة البحث."
action={<Button><Search className="w-4 h-4" />ابدأ البحث</Button>}
/>لا توجد مسودات
ابدأ بكتابة مسودة جديدة.
<EmptyState
variant="compact"
icon={<FileText className="w-6 h-6" />}
title="لا توجد مسودات"
description="ابدأ بكتابة مسودة جديدة."
/>