{"id":"l-ds-2-4","courseId":"design-systems","lang":"ar","kind":"lesson","summary":"اقرأ الـ design tokens واكتبها بصيغة DTCG 2025.10 في JSON، مع الأنواع والمجموعات والأسماء المستعارة والـ deprecation، حتى يغذّي ملف tokens واحد Figma وCSS والتطبيقات الأصلية.","html":"<p>الـ CSS custom properties طريقة ممتازة لـ <em>استهلاك</em> الـ tokens على الويب، لكنها مكان سيئ لـ <em>تخزينها</em>. تطبيق iOS لا يستطيع قراءة ملف الأنماط، وFigma لا يستطيع استيراده، والسكربت الذي يفحص التباين عبر الـ themes يضطر إلى تحليل CSS ليجد القيم. لذلك تعيش tokens في Northwind في ملفات JSON، بالصيغة التي حدّدتها مجموعة Design Tokens Community Group (DTCG)، ويُولَّد كود كل منصّة منها.</p>\n<h2 id=\"sec-1\" tabindex=\"-1\">أين تقف الصيغة في 2026</h2>\n<p>الـ DTCG مجموعة مجتمعية (Community Group) تابعة لـ W3C، أعضاؤها من صانعي أدوات التصميم وفرق أنظمة تصميم كبيرة. في 28 أكتوبر 2025 نشرت أول إصدار مستقر من مواصفتها، <strong>2025.10</strong>، ويتكوّن من ثلاث وحدات: Format، وColor، ووحدة Resolver لتركيب المجموعات والـ themes.</p>\n<p>كن دقيقًا حين تصفها للآخرين. إنها تقرير مستقر من Community Group، وليست توصية رسمية من W3C (Recommendation)؛ فالمجموعات المجتمعية لا تُصدر معايير ويب رسمية. وعمليًا هي الصيغة التي تتقارب حولها الأدوات: Style Dictionary وTokens Studio وTerrazzo تطبّقها، وFigma يستورد المتغيّرات ويصدّرها كـ JSON بصيغة DTCG. لكن دعم الأجزاء الأحدث، مثل صيغة اللون ككائن ووحدة Resolver، ما زال متفاوتًا بين الأدوات، لذا افحص ما يقرؤه خط الإنتاج لديك فعلًا قبل تبنّي ميزة.</p>\n<h2 id=\"sec-2\" tabindex=\"-1\">تشريح ملف الـ tokens</h2>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">tokens/primitives.tokens.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><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\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"$type\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"blue\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"600\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">        \"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"colorSpace\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"srgb\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"components\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.122</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.353</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.878</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"hex\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#1f5ae0\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">        \"$description\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Northwind brand blue. Passes 4.5:1 on white.\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"white\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"colorSpace\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"srgb\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"components\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"hex\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"#ffffff\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"space\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"$type\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"dimension\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"4\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"unit\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"rem\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<p>اقرأه من الخارج إلى الداخل:</p>\n<ul>\n<li><strong>المجموعات (groups)</strong> كائنات متداخلة عادية (<code dir=\"ltr\">color</code>، <code dir=\"ltr\">blue</code>، <code dir=\"ltr\">space</code>). تنظّم الـ tokens وتشكّل المسار المستخدم في المراجع.</li>\n<li><strong>الـ token</strong> أي كائن فيه <code dir=\"ltr\">$value</code>. هنا <code dir=\"ltr\">color.blue.600</code> و<code dir=\"ltr\">space.4</code> هما الـ tokens.</li>\n<li><strong><code dir=\"ltr\">$type</code></strong> يحدّد نوع القيمة التي يحملها الـ token. وحين يُحدَّد على مجموعة، ترثه كل الـ tokens داخلها، ولهذا تعرّفه <code dir=\"ltr\">color</code> مرة واحدة.</li>\n<li><strong><code dir=\"ltr\">$description</code></strong> نص حرّ تعرضه الأدوات في المنتقيات والتوثيق.</li>\n</ul>\n<p>الخصائص التي تبدأ بـ <code dir=\"ltr\">$</code> محجوزة للصيغة، فلا يمكن أن تبدأ أسماء الـ tokens والمجموعات بـ <code dir=\"ltr\">$</code>. ولا يمكن أن تحتوي الأسماء أيضًا على <code dir=\"ltr\">{</code> أو <code dir=\"ltr\">}</code> أو <code dir=\"ltr\">.</code>، لأن هذه الرموز تنتمي إلى صيغة المراجع.</p>\n<h2 id=\"sec-3\" tabindex=\"-1\">الأنواع وأشكال القيم</h2>\n<p>لكل نوع شكل قيمة ثابت. هذه هي الأنواع التي ستستخدمها يوميًا:</p>\n<div class=\"table-wrap\" role=\"region\" aria-label=\"جدول قابل للتمرير\" tabindex=\"0\"><table><thead>\n<tr>\n<th><code dir=\"ltr\">$type</code></th>\n<th>مثال على <code dir=\"ltr\">$value</code></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td><code dir=\"ltr\">color</code></td>\n<td><code dir=\"ltr\">{ &quot;colorSpace&quot;: &quot;srgb&quot;, &quot;components&quot;: [1, 1, 1], &quot;hex&quot;: &quot;#ffffff&quot; }</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">dimension</code></td>\n<td><code dir=\"ltr\">{ &quot;value&quot;: 16, &quot;unit&quot;: &quot;px&quot; }</code> (الوحدة <code dir=\"ltr\">px</code> أو <code dir=\"ltr\">rem</code>)</td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">duration</code></td>\n<td><code dir=\"ltr\">{ &quot;value&quot;: 150, &quot;unit&quot;: &quot;ms&quot; }</code> (الوحدة <code dir=\"ltr\">ms</code> أو <code dir=\"ltr\">s</code>)</td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">fontWeight</code></td>\n<td><code dir=\"ltr\">600</code> أو <code dir=\"ltr\">&quot;semi-bold&quot;</code></td>\n</tr>\n<tr>\n<td><code dir=\"ltr\">number</code></td>\n<td><code dir=\"ltr\">1.5</code></td>\n</tr>\n</tbody>\n</table></div><p>وهناك أيضًا <code dir=\"ltr\">fontFamily</code> و<code dir=\"ltr\">cubicBezier</code>، إضافة إلى أنواع مركّبة تجمع عدّة قيم: <code dir=\"ltr\">typography</code> و<code dir=\"ltr\">shadow</code> و<code dir=\"ltr\">border</code> و<code dir=\"ltr\">transition</code> و<code dir=\"ltr\">gradient</code> و<code dir=\"ltr\">strokeStyle</code>.</p>\n<p>كائن اللون جديد في 2025.10. المسودّات الأقدم، وكثير من ملفات الـ tokens المتداولة، تخزّن نص hex بسيطًا. أما صيغة الكائن فتستطيع وصف ألوان خارج sRGB، مثل <code dir=\"ltr\">display-p3</code> أو <code dir=\"ltr\">oklch</code>، ولهذا حلّت محلّ النص. احتفظ بالـ <code dir=\"ltr\">hex</code> الاختياري للأدوات التي لا تفهم إلا sRGB.</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>الـ token الذي لا يوجد <code dir=\"ltr\">$type</code> في أي مكان من شجرته غير صالح، حتى لو بدت قيمته لونًا بوضوح. الصيغة تمنع الاستنتاج عن قصد، لأن <code dir=\"ltr\">&quot;16&quot;</code> قد يكون رقمًا أو حجم خط أو z-index. ضع <code dir=\"ltr\">$type</code> على مجموعاتك العليا، ونادرًا ما ستحتاج إلى التفكير فيه بعد ذلك.</p>\n</aside>\n<h2 id=\"sec-4\" tabindex=\"-1\">الأسماء المستعارة (aliases)</h2>\n<p>الطبقة الدلالية من الدروس السابقة تعيش في الصيغة نفسها، على شكل مراجع:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">tokens/semantic.tokens.json</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><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\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"$type\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"action\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"bg\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.blue.600}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"text\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.white}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"bg-hover\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.blue.700}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"bg-dark\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">        \"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.blue.700}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">        \"$deprecated\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Use color.action.bg-hover instead. Removed in 5.0.\"</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n<p>المرجع بالأقواس المعقوفة يسمّي token بمساره المفصول بنقاط، ويُحَلّ إلى قيمة <code dir=\"ltr\">$value</code> الكاملة لذلك الـ token. ويجب أن يشير إلى token، لا إلى مجموعة أبدًا. يمكن أن تتسلسل المراجع (من semantic إلى primitive)، ويجب أن ترفض الأداة المراجع الدائرية. وللحالة النادرة التي تحتاج فيها جزءًا من قيمة، مثل مكوّن لون واحد، تدعم الصيغة أيضًا مراجع JSON Pointer عبر <code dir=\"ltr\">$ref</code>.</p>\n<p>هذا جوهر ما تفعله كل أداة tokens مع الأسماء المستعارة:</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"js\" data-run=\"js\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">JavaScript</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn code-run\" data-action=\"run\" data-lang=\"js\" data-index=\"2\" aria-label=\"شغّل هذا المثال\"><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=\"M5 5a2 2 0 0 1 3.008-1.728l11.997 6.998a2 2 0 0 1 .003 3.458l-12 7A2 2 0 0 1 5 19z\"/></svg><span>تشغيل</span></button><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><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\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> tokens</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  color: {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    $type: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'color'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    blue: { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">600</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { $value: { colorSpace: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'srgb'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, components: [</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.122</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.353</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">0.878</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], hex: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'#1f5ae0'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } } },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    action: {</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">      bg: { $value: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'{color.blue.600}'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">      'bg-subtle'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { $value: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'{color.action.bg}'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  },</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">};</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> lookup</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">path</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> node</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> path.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">split</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'.'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">reduce</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">((</span><span style=\"color:#953800;--shiki-dark:#FFA657\">n</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">key</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=></span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> n?.[key], tokens);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  if</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">!</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">node </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">||</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> !</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'$value'</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> in</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> node)) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">throw</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> Error</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`{${</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">path</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}} is not a token`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> node;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">function</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> resolve</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#953800;--shiki-dark:#FFA657\">path</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">, </span><span style=\"color:#953800;--shiki-dark:#FFA657\">seen</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> []) {</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  if</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (seen.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">includes</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(path)) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">throw</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> new</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> Error</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">`circular reference: ${</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">[</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">seen</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">, </span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">path</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">].</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">join</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">' -> '</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">)</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">}`</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">$value</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">=</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> lookup</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(path);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  const</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> ref</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> =</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> typeof</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $value </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">===</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\"> 'string'</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\"> &#x26;&#x26;</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $value.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">match</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">/</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">^</span><span style=\"color:#116329;--shiki-light-font-weight:bold;--shiki-dark:#7EE787;--shiki-dark-font-weight:bold\">\\{</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">(</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">.</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">+</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">)</span><span style=\"color:#116329;--shiki-light-font-weight:bold;--shiki-dark:#7EE787;--shiki-dark-font-weight:bold\">\\}</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">$</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">/</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">  return</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> ref </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">?</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\"> resolve</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(ref[</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\">1</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">], [</span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">...</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">seen, path]) </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">:</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> $value;</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span>\n<span class=\"line\"></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">resolve</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'color.action.bg-subtle'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">).hex);</span></span>\n<span class=\"line\"><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">try</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> { </span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">resolve</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">'color.action'</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">); } </span><span style=\"color:#CF222E;--shiki-dark:#FF7B72\">catch</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> (e) { console.</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">log</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">(e.message); }</span></span></code></pre><div class=\"run-output\" data-run-output=\"2\" hidden></div></div>\n<h2 id=\"sec-5\" tabindex=\"-1\">ميزتان أخريان تستحقّان المعرفة</h2>\n<p><code dir=\"ltr\">$deprecated</code>، الظاهرة أعلاه على <code dir=\"ltr\">bg-dark</code> (اسم يصف المظهر، وهو ما حذّر منه درس التسمية)، تعلّم token بأنه في طريقه إلى الخروج. قيمتها <code dir=\"ltr\">true</code> أو نص يشرح ما يُستخدم بدلًا منه، ويمكن للأدوات أن تحذّر حين يختاره أحد. ستبني عملية deprecation كاملة حولها في القسم 4.</p>\n<p>ويمكن للمجموعات أيضًا أن ترث من مجموعات أخرى عبر <code dir=\"ltr\">$extends</code>، فتخصّص ما يختلف فقط. وهذا مفيد لمجموعة Tidewater التي تعيد استخدام معظم بنية Northwind. أما لتركيبات الفاتح والداكن والعلامات الكاملة، فوحدة Resolver تحدّد كيف تتركّب مجموعات الـ tokens المنفصلة والمعدِّلات، لكنها أحدث جزء في المواصفة، لذا ما زالت Northwind تجمّع الـ themes في خط إنتاج البناء الخاص بها. امتدادات الملفات الموصى بها هي <code dir=\"ltr\">.tokens</code> و<code dir=\"ltr\">.tokens.json</code>؛ وتستخدم Northwind الثاني حتى تلوّن المحرّرات الملفات كـ JSON.</p>\n<p>في التمرين التالي تراجع ملف tokens كما يراجعه خط الإنتاج، وتجد الأسطر التي سيرفضها. وبعدها تبني خط الإنتاج هذا بنفسك.</p>\n","toc":[{"id":"sec-1","text":"أين تقف الصيغة في 2026","level":2},{"id":"sec-2","text":"تشريح ملف الـ tokens","level":2},{"id":"sec-3","text":"الأنواع وأشكال القيم","level":2},{"id":"sec-4","text":"الأسماء المستعارة (aliases)","level":2},{"id":"sec-5","text":"ميزتان أخريان تستحقّان المعرفة","level":2}],"takeaways":["تخزّن صيغة DTCG الـ tokens ككائنات JSON فيها <code dir=\"ltr\">$value</code>، و<code dir=\"ltr\">$type</code> محدّد على الـ token نفسه أو موروث من مجموعته.","الأسماء المستعارة (aliases) تستخدم أقواسًا معقوفة ومسارات مفصولة بنقاط، مثل <code dir=\"ltr\">{color.blue.600}</code>، ويجب أن تشير إلى token لا إلى مجموعة.","منذ 2025.10 صارت قيمة اللون كائنًا فيه <code dir=\"ltr\">colorSpace</code> و<code dir=\"ltr\">components</code>، مع <code dir=\"ltr\">hex</code> اختياري كبديل احتياطي.","الإصدار 2025.10 هو أول إصدار مستقر لتقرير من W3C Community Group، وليس توصية رسمية من W3C (Recommendation)، ودعم الأدوات له ما زال متفاوتًا."],"further":[{"title":"Design Tokens specification reaches first stable version (W3C Community Group)","url":"https://www.w3.org/community/design-tokens/2025/10/28/design-tokens-specification-reaches-first-stable-version/"},{"title":"Design Tokens Community Group repository","url":"https://github.com/design-tokens/community-group"},{"title":"Modes for variables, including importing and exporting tokens (Figma)","url":"https://help.figma.com/hc/en-us/articles/15343816063383-Modes-for-variables"}],"quiz":[{"q":"<p>إلامَ يُحَلّ المرجع <code dir=\"ltr\">{color.action}</code> في هذا الملف؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"json\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">JSON</span><span class=\"code-actions\"><button type=\"button\" class=\"code-btn\" data-action=\"copy\" aria-label=\"نسخ الكود\"><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\"><rect width=\"14\" height=\"14\" x=\"8\" y=\"8\" rx=\"2\" ry=\"2\"/><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"/></svg><span>نسخ</span></button></span></div><pre class=\"shiki\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">{</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">  \"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"$type\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"color\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">,</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">    \"action\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: {</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"bg\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.blue.600}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> },</span></span>\n<span class=\"line\"><span style=\"color:#116329;--shiki-dark:#7EE787\">      \"text\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: { </span><span style=\"color:#116329;--shiki-dark:#7EE787\">\"$value\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">: </span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"{color.white}\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\"> }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">    }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">  }</span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">}</span></span></code></pre></div>\n","options":[{"text":"إلى قيمة <code dir=\"ltr\">color.action.bg</code>، لأنه أول token في المجموعة.","why":"لا توجد في الصيغة قاعدة «أول token»؛ يجب أن يسمّي المرجع token واحدًا بالضبط."},{"text":"إلى كائن يحتوي <code dir=\"ltr\">bg</code> و<code dir=\"ltr\">text</code> معًا.","why":"المراجع بالأقواس المعقوفة لا تُحَلّ إلا إلى <code dir=\"ltr\">$value</code> الخاص بـ token واحد، ولا تُحَلّ أبدًا إلى مجموعة كاملة."},{"text":"إلى النص “color”.","why":"الـ <code dir=\"ltr\">$type</code> الخاص بالمجموعة ترثه الـ tokens داخلها؛ وليس قيمة يمكن أن يعيدها مرجع."},{"text":"إلى لا شيء صالح؛ <code dir=\"ltr\">color.action</code> مجموعة، فالمرجع خطأ.","why":"صحيح. يجب أن تستهدف المراجع token، أي كائنًا فيه <code dir=\"ltr\">$value</code>."}],"answer":3},{"q":"<p>token ليس له <code dir=\"ltr\">$type</code>، ولا لأي مجموعة فوقه. وقيمته <code dir=\"ltr\">&quot;#1f5ae0&quot;</code>. ماذا يجب أن تفعل الأداة الملتزمة بالصيغة؟</p>","options":[{"text":"أن تستنتج أنه لون من البادئة <code dir=\"ltr\">#</code>.","why":"الصيغة تمنع تخمين الأنواع من القيم، لأن النص نفسه قد يعني أشياء مختلفة لأدوات مختلفة."},{"text":"أن تعامل الـ token كأنه غير صالح.","why":"صحيح. كل token يحتاج نوعًا صريحًا، إما عليه نفسه، أو موروثًا من مجموعة، أو من الـ token الذي يشير إليه."},{"text":"أن تعامله كـ token نصّي.","why":"النص (string) ليس نوعًا في الصيغة؛ ولا يمكن للأدوات أن ترجع إليه بصمت."}],"answer":1},{"q":"<p>يقول زميل «صارت DTCG معيارًا من W3C، فكل الأدوات تقرأ كل الميزات». ما التصحيح الدقيق؟</p>","options":[{"text":"إنها تقرير مستقر من Community Group وليست توصية رسمية من W3C، والأدوات تطبّقها بسرعات مختلفة.","why":"صحيح. الاستقرار يعني أن الصيغة لن تتغيّر من تحتك؛ لكنه لا يضمن بعدُ أن كل أداة تدعم كل نوع أو الـ Resolver."},{"text":"ما زالت مسودّة مبكرة لا تدعمها أي أداة.","why":"إصدار 2025.10 مستقر، وتدعمه Style Dictionary وTokens Studio وTerrazzo واستيراد المتغيّرات وتصديرها في Figma."},{"text":"إنها توصية رسمية من W3C، لكن لـ tokens الألوان فقط.","why":"ليست توصية رسمية أصلًا، وتغطّي أنواعًا كثيرة غير الألوان."},{"text":"إنها تحلّ محلّ الـ CSS custom properties في المتصفّحات.","why":"الصيغة ملف تبادل بين الأدوات؛ والمتصفّحات ما زالت تستهلك CSS يولّده خط إنتاج منها."}],"answer":0}],"exercise":{"kind":"spot-bug","language":"json","code":"{\n  \"color\": {\n    \"$type\": \"color\",\n    \"blue\": {\n      \"600\": { \"$value\": { \"colorSpace\": \"srgb\", \"components\": [0.122, 0.353, 0.878], \"hex\": \"#1f5ae0\" } },\n      \"700\": { \"$value\": { \"colorSpace\": \"srgb\", \"components\": [0.094, 0.282, 0.722], \"hex\": \"#1848b8\" } }\n    },\n    \"white\": { \"$value\": { \"colorSpace\": \"srgb\", \"components\": [1, 1, 1], \"hex\": \"#ffffff\" } },\n    \"action\": {\n      \"bg\": { \"$value\": \"{color.blue.600}\" },\n      \"bg.hover\": { \"$value\": \"{color.blue.700}\" },\n      \"text\": { \"$value\": \"{color.white}\" },\n      \"border\": { \"$value\": \"{color.blue}\" }\n    }\n  },\n  \"space\": {\n    \"$type\": \"dimension\",\n    \"inset-md\": { \"$value\": { \"value\": 16 } },\n    \"inset-lg\": { \"$value\": { \"value\": 24, \"unit\": \"px\" } }\n  },\n  \"radius\": {\n    \"control\": { \"$value\": { \"value\": 6, \"unit\": \"px\" } }\n  }\n}","bugLines":[11,13,18,22],"title":"جد ما سيرفضه خط الإنتاج","prompt":"<p>يتحقّق الـ CI في Northwind من كل ملف tokens وفق صيغة DTCG 2025.10 قبل البناء. هذا الملف يفشل. اختر <strong>كل سطر</strong> سترفضه أداة ملتزمة بالصيغة. افترض أن بقية الملف، بما فيها قيم الألوان، صحيحة.</p>\n","hints":["افحص كل اسم بحثًا عن رموز تحجزها صيغة المراجع.","افحص كل مرجع: هل يشير إلى token (كائن فيه <code dir=\"ltr\">$value</code>) أم إلى مجموعة؟","افحص نوع كل token: هل هو معرّف على الـ token أو على مجموعة أمّ، وهل تحتوي القيمة على كل الحقول المطلوبة؟"],"explanation":"<p>أربعة أسطر تخالف الصيغة:</p>\n<ul>\n<li><strong>السطر 11</strong>: يحتوي <code dir=\"ltr\">bg.hover</code> على نقطة، وهي محجوزة لمسارات المراجع. أعد تسميته إلى <code dir=\"ltr\">bg-hover</code>.</li>\n<li><strong>السطر 13</strong>: <code dir=\"ltr\">{color.blue}</code> يشير إلى مجموعة لا إلى token. يحتاج درجة محدّدة، مثل <code dir=\"ltr\">{color.blue.700}</code>.</li>\n<li><strong>السطر 18</strong>: قيمة <code dir=\"ltr\">dimension</code> يجب أن تتضمّن <code dir=\"ltr\">unit</code> (<code dir=\"ltr\">px</code> أو <code dir=\"ltr\">rem</code>)، حتى حين يبدو المعنى واضحًا: <code dir=\"ltr\">{ &quot;value&quot;: 16, &quot;unit&quot;: &quot;px&quot; }</code>.</li>\n<li><strong>السطر 22</strong>: لا يملك <code dir=\"ltr\">radius.control</code> أي <code dir=\"ltr\">$type</code>، ولا مجموعة <code dir=\"ltr\">radius</code> كذلك، فالـ token غير صالح. أضف <code dir=\"ltr\">&quot;$type&quot;: &quot;dimension&quot;</code> إلى مجموعة <code dir=\"ltr\">radius</code>.</li>\n</ul>\n","checkLabels":{}},"words":684,"readMinutes":4}