{"id":"l-fig-3-3","courseId":"figma-ui-design","lang":"ar","kind":"lesson","summary":"قرّر متى تنتمي قيمة ما إلى style ومتى إلى variable، وأنشئ في Steady ‏variables ألوان أولية (primitives) ودلالية (semantic) مرتبطة بالـ aliases، واربط الـ components بالمعاني بدل رموز hex الخام.","html":"<p>ابحث في ملف Steady عن رمز اللون #0F766E وستجده على أزرار التعليم، والزر الأساسي، وحلقة التركيز، ورابط، وحلقة تقدّم، مكتوبًا يدويًا في كل مرة. حين يطلب فريق العلامة التجارية تركوازيًا أميل إلى الأزرق قليلًا، تواجه البحث نفسه الذي واجهته في الدرس 3.1، لكن هذه المرة للون. والأسوأ أنه حين يأتي الوضع الداكن، ستحتاج بعض هذه الأماكن تركوازيًا أفتح وبعضها لا، ورمز hex لا يستطيع أن يخبرك أيّها.</p>\n<p>الـ styles والـ variables كلاهما يضع القيم في مكان واحد. لكنهما يحلّان مشكلتين مختلفتين قليلًا.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">الـ Styles: وحدات مركّبة قابلة لإعادة الاستخدام</h2>\n<p>الـ <strong>style</strong> حزمة مسمّاة من الخصائص البصرية. وقت كتابة هذا الدرس، في Figma ‏color styles وtext styles وeffect styles وlayout guide styles. خطّطت للـ text styles بالفعل في الدرس 1.3: <code dir=\"ltr\">Headline</code> هو عائلة خط وحجم ووزن وارتفاع سطر وتباعد حروف، كلها تُطبَّق بنقرة واحدة.</p>\n<p>تبرز فائدة الـ styles حين تكون القيمة <strong>مركّبة</strong>. الـ text style عدّة خصائص دفعة واحدة. والـ effect style يمكن أن يحمل ظلّين متراكبين. والـ color style يمكن أن يحمل تدرّجًا لونيًا أو عدّة تعبئات متراكبة. غيّر الـ style فتتحدّث كل طبقة تستخدمه.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">الـ Variables: قيم مفردة بقدرات إضافية</h2>\n<p>الـ <strong>variable</strong> يحمل قيمة خامًا واحدة. الأنواع الأساسية هي <strong>color</strong> و<strong>number</strong> و<strong>string</strong> و<strong>boolean</strong> (وأضاف Figma أنواعًا أخرى لأعمال الحركة منذ ذلك الحين). يمكنك ربط الـ variables بالتعبئات والحدود، ونصف قطر الزوايا، والـ gap، والـ padding، والعرض والارتفاع، والشفافية، وظهور الطبقة، ومحتوى النص، وكثير من خصائص الخط.</p>\n<p>ثلاثة أشياء تجعل الـ variables مختلفة عن الـ styles:</p>\n<ul>\n<li><strong>الـ Aliasing</strong>: يمكن للـ variable أن يشير إلى variable آخر من النوع نفسه، بدل أن يحمل قيمة خامًا.</li>\n<li><strong>الـ Modes</strong>: يمكن للـ variable أن يحمل قيمة مختلفة لكل mode، مثل الفاتح والداكن (الدرس التالي).</li>\n<li><strong>الـ Tokens</strong>: الـ variables تقابل بشكل وثيق الـ design tokens التي يستخدمها المطوّرون في الكود، ووقت كتابة هذا الدرس يمكنك تسجيل اسم كل variable في الكود للويب وiOS وAndroid ليعرضه Dev Mode.</li>\n</ul>\n<p>توجد الـ variables في <strong>collections</strong>، والشرطات المائلة في الأسماء تصنع مجموعات: <code dir=\"ltr\">color/text/primary</code> يقع في المجموعة <code dir=\"ltr\">color/text</code>.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">مستويان: الـ primitives والدلالية</h2>\n<p>النمط الذي تستخدمه معظم أنظمة التصميم، والذي يستخدمه Steady، فيه مستويان.</p>\n<p><strong>الـ Primitives</strong> هي لوحة الألوان الخام، مسمّاة بما هي عليه: <code dir=\"ltr\">teal/700</code> = #0F766E، و<code dir=\"ltr\">gray/500</code> = #6B7280، و<code dir=\"ltr\">white</code> = #FFFFFF. ليس لها رأي في مكان استخدامها.</p>\n<p><strong>الـ variables الدلالية (semantic)</strong> مسمّاة بما تُستخدم له، وكلٌّ منها alias لـ primitive: ‏<code dir=\"ltr\">color/action/primary</code> ← <code dir=\"ltr\">teal/700</code>، و<code dir=\"ltr\">color/text/secondary</code> ← <code dir=\"ltr\">gray/500</code>، و<code dir=\"ltr\">color/surface/default</code> ← <code dir=\"ltr\">white</code>. الـ components ترتبط <strong>فقط</strong> بالـ variables الدلالية.</p>\n<figure class=\"diagram\"><svg class=\"diagram-svg\" focusable=\"false\" viewBox=\"0 0 680 250\" role=\"img\" aria-labelledby=\"l-fig-3-3-t1\"><defs><marker id=\"arrow-l-fig-3-3-1\" viewBox=\"0 0 10 10\" refX=\"9\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\"><path d=\"M0 0 L10 5 L0 10 z\" class=\"d-arrowhead\"/></marker></defs>\n  <title id=\"l-fig-3-3-t1\">ثلاثة أعمدة. الـ primitives ‏teal 700 وgray 500 وwhite تغذّي الـ variables الدلالية action primary وtext secondary وsurface default، المرتبطة بدورها بتعبئة زر التعليم ونص الـ streak وخلفية الصف.</title>\n  <text class=\"d-label-strong\" x=\"110\" y=\"26\" text-anchor=\"middle\">Primitives</text>\n  <text class=\"d-label-strong\" x=\"340\" y=\"26\" text-anchor=\"middle\">الدلالية</text>\n  <text class=\"d-label-strong\" x=\"570\" y=\"26\" text-anchor=\"middle\">في الـ component</text>\n  <rect class=\"d-box\" x=\"30\" y=\"44\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"110\" y=\"69\" text-anchor=\"middle\">teal/700</text>\n  <rect class=\"d-box\" x=\"30\" y=\"114\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"110\" y=\"139\" text-anchor=\"middle\">gray/500</text>\n  <rect class=\"d-box\" x=\"30\" y=\"184\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"110\" y=\"209\" text-anchor=\"middle\">white</text>\n  <rect class=\"d-box-primary\" x=\"240\" y=\"44\" width=\"200\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"340\" y=\"69\" text-anchor=\"middle\">action/primary</text>\n  <rect class=\"d-box-primary\" x=\"240\" y=\"114\" width=\"200\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"340\" y=\"139\" text-anchor=\"middle\">text/secondary</text>\n  <rect class=\"d-box-primary\" x=\"240\" y=\"184\" width=\"200\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-code\" x=\"340\" y=\"209\" text-anchor=\"middle\">surface/default</text>\n  <rect class=\"d-box-accent\" x=\"490\" y=\"44\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-label\" x=\"570\" y=\"69\" text-anchor=\"middle\">تعبئة زر التعليم</text>\n  <rect class=\"d-box-accent\" x=\"490\" y=\"114\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-label\" x=\"570\" y=\"139\" text-anchor=\"middle\">نص الـ streak</text>\n  <rect class=\"d-box-accent\" x=\"490\" y=\"184\" width=\"160\" height=\"40\" rx=\"8\"/>\n  <text class=\"d-label\" x=\"570\" y=\"209\" text-anchor=\"middle\">خلفية الصف</text>\n  <path class=\"d-arrow\" d=\"M238 64 L192 64\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M238 134 L192 134\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M238 204 L192 204\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M488 64 L442 64\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M488 134 L442 134\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n  <path class=\"d-arrow\" d=\"M488 204 L442 204\" marker-end=\"url(#arrow-l-fig-3-3-1)\"/>\n</svg><figcaption>الـ components تشير إلى المعاني، والمعاني تشير إلى لوحة الألوان</figcaption></figure>\n<p>لماذا نتعب أنفسنا بالعمود الأوسط؟ لأن المعنى والقيمة يتغيّران لأسباب مختلفة. يغيّر فريق العلامة التجارية <code dir=\"ltr\">teal/700</code>، فيتبعه كل لون إجراء. ويغيّر الوضع الداكن ما يشير إليه <code dir=\"ltr\">color/action/primary</code>، فتتبعه ألوان الإجراءات وحدها، لا كل تركوازي في الملف. ولا يحتاج أيّ من التغييرين لمس component واحد.</p>\n<p>أرقام Steady تُعامَل بالطريقة نفسها: مجموعة <code dir=\"ltr\">space</code> (من <code dir=\"ltr\">space/1</code> = 4 إلى <code dir=\"ltr\">space/12</code> = 48، من الدرس 2.3) ومجموعة <code dir=\"ltr\">radius</code> ‏(<code dir=\"ltr\">radius/sm</code> = 8، و<code dir=\"ltr\">radius/md</code> = 12). اربط الـ padding في صف العادة بـ <code dir=\"ltr\">space/3</code> و<code dir=\"ltr\">space/4</code>، ونصف قطر زواياه بـ <code dir=\"ltr\">radius/md</code>.</p>\n<aside class=\"callout callout-mistake\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"/><path d=\"M12 9v4\"/><path d=\"M12 17h.01\"/></svg><span><span class=\"callout-kind\">خطأ شائع</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>أسماء دلالية تصف المظهر</span></p>\n<p><code dir=\"ltr\">color/teal-button</code> هو primitive يرتدي زيًّا دلاليًا. يوم يتحوّل الزر إلى الأزرق يصبح الاسم مضلّلًا، وفي الوضع الداكن قد لا يكون تركوازيًا أصلًا. سمِّ الـ variables الدلالية حسب الدور، مثل <code dir=\"ltr\">action/primary</code> أو <code dir=\"ltr\">text/secondary</code> أو <code dir=\"ltr\">border/default</code>، ودع القيمة تكون ما يحتاجه ذلك الدور.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">إبقاء المنتقي نظيفًا</h2>\n<p>إعدادان يُبقيان الناس على النظام. <strong>تحديد النطاق (scoping)</strong> يحصر الأماكن التي يُعرض فيها الـ variable: حدّد نطاق variables ‏<code dir=\"ltr\">space</code> بالـ gap والـ padding، فتتوقّف عن الظهور في منتقي نصف قطر الزوايا. و<strong>الإخفاء من النشر</strong> يُبقي الـ primitives خارج المكتبة التي تراها الملفات الأخرى، فلا يجد المصمّمون الذين يستخدمون المجموعة إلا الـ tokens الدلالية. كلا الإعدادين موجود في لوحة تعديل كل variable وقت كتابة هذا الدرس.</p>\n<h2 id=\"sec-5\" tabindex=\"-1\">استخدم الاثنين</h2>\n<p>الـ variables لم تحلّ محلّ الـ styles. التقسيم المعتاد هو: الـ variables للقيم المفردة (الألوان والمسافات ونصف قطر الزوايا والـ booleans) لأنها تقبل الـ aliases وتبدّل الـ modes؛ والـ text styles للخطوط، مع ربط أحجامها بـ number variables إذا احتجت أن تتغيّر حسب الـ mode؛ والـ effect styles للظلال؛ والـ color styles للتدرّجات أو التعبئات المتراكبة فقط. اربط تعبئة color style بـ variable، فتحصل على سهولة المركّب مع الـ modes الخاصة بالـ variable.</p>\n<aside class=\"callout callout-tip\" role=\"note\"><p class=\"callout-title\"><svg class=\"icon \" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\" focusable=\"false\"><path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"/><path d=\"M9 18h6\"/><path d=\"M10 22h4\"/></svg><span><span class=\"callout-kind\">نصيحة</span><span class=\"callout-sep\" aria-hidden=\"true\"> · </span>ابدأ بعدد قليل من الـ tokens الدلالية</span></p>\n<p>يحتاج Steady نحو اثني عشر لونًا دلاليًا: النص الأساسي والثانوي، والسطح الافتراضي والمرتفع، والحدّ الافتراضي، والإجراء الأساسي وحالته المضغوطة، وon-action (النص فوق التركوازي)، والنجاح، والخطر، والتركيز. أضف token حين يحتاج component حقيقي معنى غير موجود بعد، لا قبل ذلك.</p>\n</aside>\n<p>مع إشارة كل component إلى معانٍ، يصبح الوضع الداكن مسألة ما يشير إليه كل معنى، وهذا بالضبط ما تجيب عنه الـ modes في الدرس التالي.</p>\n","toc":[{"id":"sec-1","text":"الـ Styles: وحدات مركّبة قابلة لإعادة الاستخدام","level":2},{"id":"sec-2","text":"الـ Variables: قيم مفردة بقدرات إضافية","level":2},{"id":"sec-3","text":"مستويان: الـ primitives والدلالية","level":2},{"id":"sec-4","text":"إبقاء المنتقي نظيفًا","level":2},{"id":"sec-5","text":"استخدم الاثنين","level":2}],"takeaways":["الـ style يجمع عدّة خصائص في وحدة مركّبة قابلة لإعادة الاستخدام، مثل text style يضمّ نوع الخط وحجمه ووزنه وارتفاع السطر.","الـ variable يحمل قيمة خامًا واحدة (لونًا أو رقمًا أو نصًا أو boolean)، ويمكن أن يكون alias لـ variable آخر، ويمكن أن تتغيّر قيمته حسب الـ mode.","استخدم مستويين من الـ variables، الـ primitives للوحة الألوان الخام والـ tokens الدلالية للمعاني، واربط الـ components بالمستوى الدلالي وحده.","الـ text styles والـ effect styles وcolor styles متعدّدة التعبئة أو المتدرّجة ما زالت بلا مقابل من variable واحد، لذا تستخدم معظم الفرق النظامين معًا.","تحديد نطاق الـ variables ‏(scoping) وإخفاء الـ primitives من النشر يُبقيان منتقي الـ variables قصيرًا ويمنعان الناس من اللجوء إلى القيم الخام."],"further":[{"title":"Overview of variables, collections, and modes","url":"https://help.figma.com/hc/en-us/articles/14506821864087-Overview-of-variables-collections-and-modes"},{"title":"Guide to styles in Figma","url":"https://help.figma.com/hc/en-us/articles/360039238753-Guide-to-styles-in-Figma"},{"title":"Create and manage variables and collections","url":"https://help.figma.com/hc/en-us/articles/15145852043927-Create-and-manage-variables-and-collections"}],"quiz":[{"q":"<p>حالة Done في صف العادة تستخدم لون التعليم <code dir=\"ltr\">teal/700</code> مباشرة من مجموعة الـ primitives. في الـ sprint التالي تضيف الوضع الداكن. ما الذي سيتعطّل؟</p>","options":[{"text":"لا شيء، لأن الـ primitives تتبدّل تلقائيًا في الوضع الداكن.","why":"الـ primitives قيم خام ثابتة. التبديل مهمّة الـ variables الدلالية التي لها قيمة لكل mode."},{"text":"يرفض Figma نشر components مرتبطة بـ primitives.","why":"يسمح Figma بذلك. المشكلة أنك تخسر طبقة المعنى التي تبدّل الـ modes قيمها."},{"text":"يحتفظ الصف بالتركوازي الداكن في الوضع الداكن، لأنه لا شيء يقول إن هذا اللون يعني «إجراء» ويجب أن يتغيّر.","why":"صحيح. الربط بـ <code dir=\"ltr\">color/action/primary</code> بدلًا من ذلك يتيح للوضع الداكن توجيه هذا المعنى إلى تركوازي أفتح."},{"text":"يفقد صف العادة الـ variants الخاصة به.","why":"ربط الـ variables لا يؤثّر في الـ variants ولا في خصائص الـ component الأخرى."}],"answer":2},{"q":"<p>أيّ من هذه ينتمي إلى style لا إلى variable واحد؟</p>","options":[{"text":"تنسيق نص Headline، أي 17 px بوزن semibold وارتفاع سطر 24 px.","why":"صحيح. إنها مركّب من عدّة خصائص. الـ text style يجمعها، ويمكن مع ذلك ربط كل جزء منها بـ variable."},{"text":"الـ padding بمقدار 16 px في البطاقة.","why":"الـ padding رقم واحد، وهذا بالضبط ما وُجد الـ number variable من أجله."},{"text":"لون الإجراء الأساسي.","why":"لون واحد يجب أن يتغيّر حسب الـ mode هو color variable نموذجي."},{"text":"هل تلميح التهيئة الأولى (onboarding) ظاهر.","why":"قيمة true أو false تناسب boolean variable."}],"answer":0},{"q":"<p>ما الفائدة الأساسية من جعل <code dir=\"ltr\">color/text/secondary</code> ‏alias لـ <code dir=\"ltr\">gray/500</code> بدل كتابة #6B7280 فيه؟</p>","options":[{"text":"الـ aliases تجعل الملف أصغر.","why":"حجم الملف لا يكاد يتغيّر. الفائدة الحقيقية في الصيانة والمعنى."},{"text":"المطوّرون لا يستطيعون قراءة قيم hex الخام في Dev Mode.","why":"يعرض Dev Mode قيم hex بلا مشكلة. الفائدة هي سلسلة المعنى."},{"text":"الـ variables المرتبطة بـ alias لا يمكن تعديلها بالخطأ.","why":"يمكن دائمًا إعادة توجيه الـ aliases. إنها ليست قفلًا."},{"text":"تغيير الرمادي في لوحة الألوان مرة واحدة يحدّث كل معنى يشير إليه، ويمكن لكل mode أن يشير إلى مكان مختلف.","why":"صحيح. الـ aliases تفصل ما هو اللون عمّا يُستخدم له، فيبقى تغيير لوحة الألوان والـ modes تعديلًا واحدًا لكلٍّ منهما."}],"answer":3},{"q":"<p>يكتب مصمّم 15 في حقل الـ gap مع أن منتقي variables المسافات <code dir=\"ltr\">space</code> متاح. أيّ تغيير في الإعداد يثنيه عن ذلك على أفضل وجه؟</p>","options":[{"text":"حذف حقل الـ gap من إعدادات الملف.","why":"لا يمكنك إزالة الخصائص الأساسية. الهدف أن تجعل القيمة الصحيحة هي الأسهل."},{"text":"تحديد نطاق variables المسافات للـ gap والـ padding لتظهر أولًا هناك، ومراجعة القيم الخارجة عن النظام بفحص تصميمي قبل التسليم.","why":"صحيح. تحديد النطاق يُبقي المنتقي ملائمًا، والمراجعة تلتقط القيم المكتوبة يدويًا التي تسلّلت."},{"text":"إعادة تسمية كل variable مسافات بقيمته بالبكسل.","why":"أسماء مثل <code dir=\"ltr\">16</code> تخفي المعنى ولا تمنع أحدًا من كتابة 15."},{"text":"تحويل كل المسافات إلى text styles.","why":"الـ text styles تحمل إعدادات الخط، لا مسافات التخطيط."}],"answer":1}],"exercise":{"kind":"spot-bug","language":"json","code":"{\n  \"primitives\": {\n    \"teal/700\": \"#0F766E\",\n    \"gray/900\": \"#1A1A1A\",\n    \"gray/500\": \"#6B7280\",\n    \"gray/400\": \"#9CA3AF\",\n    \"gray/200\": \"#E5E7EB\",\n    \"white\":    \"#FFFFFF\"\n  },\n  \"semantic\": {\n    \"color/text/primary\":    \"{gray/900}\",\n    \"color/text/secondary\":  \"{gray/400}\",\n    \"color/surface/default\": \"{white}\",\n    \"color/border/default\":  \"{gray/200}\",\n    \"color/action/primary\":  \"#0F766E\",\n    \"color/teal-checkbox\":   \"{teal/700}\",\n    \"color/on-action\":       \"{white}\"\n  }\n}","bugLines":[12,15,16],"title":"راجع variables الألوان في Steady","prompt":"<p>هذا تصدير لـ variables الألوان في الوضع الفاتح في Steady. الصيغة <code dir=\"ltr\">{name}</code> تعني أن الـ variable ‏alias لـ variable آخر. قواعد المجموعة: الـ variables الدلالية تكون aliases لـ primitives (لا قيمًا خامًا أبدًا)، وتُسمّى حسب الدور (لا حسب المظهر أبدًا)، وكل لون نص يحقّق نسبة 4.5:1 على الأبيض. حدّد كل سطر يخالف قاعدة.</p>\n","hints":["افحص كل سطر دلالي من ثلاث جهات: هل هو alias، وهل الاسم دور، وهل ينجح لون النص في التباين؟","من الدرس 1.3: ‏#6B7280 على الأبيض يعطي 4.83:1، أما #9CA3AF على الأبيض فيعطي 2.54:1 فقط.","سطر يفشل في التباين، وسطر يكتب قيمة يدويًا، وسطر يسمّي لونًا حسب مظهره."],"explanation":"<p>السطر 12: ‏<code dir=\"ltr\">color/text/secondary</code> هو alias لـ <code dir=\"ltr\">gray/400</code> ‏(#9CA3AF)، الذي يعطي <strong>2.54:1</strong> على الأبيض ويفشل كلون نص. وجّهه إلى <code dir=\"ltr\">gray/500</code> ‏(4.83:1). السطر 15: ‏<code dir=\"ltr\">color/action/primary</code> يحمل <strong>قيمة hex خامًا</strong> بدل أن يكون alias لـ <code dir=\"ltr\">{teal/700}</code>، فلن يصله أي تغيير في لوحة الألوان، ويكسر نمط المستويين. السطر 16: ‏<code dir=\"ltr\">color/teal-checkbox</code> <strong>مسمّى حسب المظهر وحسب component واحد</strong>. أعِد تسميته باسم دور مثل <code dir=\"ltr\">color/action/primary</code> (المعنى نفسه، فيمكنك حذفه واستخدام ذلك) أو <code dir=\"ltr\">color/control/checked</code> إن احتاجت عناصر التحكم المعلَّمة token خاصًا بها.</p>\n","checkLabels":{}},"words":743,"readMinutes":4}