{"checkpoints":{"s-a11y-1":[{"q":"<p>يقول أحد مديري Ticketly: «2% فقط من عملائنا أخبرونا أن لديهم إعاقة، فإمكانية الوصول يمكن أن تنتظر». ما أقوى ردّ؟</p>","options":[{"text":"الإعاقة لا يُبلَّغ عنها بما يكفي، والقيود المؤقتة والظرفية تطال عددًا أكبر بكثير، والبيع لعملاء في الاتحاد الأوروبي يرتّب التزامات قانونية","why":"صحيح. نحو شخص من كل ستة لديه إعاقة ملموسة، وكثيرون لا يُفصحون عنها أبدًا، والإصلاحات نفسها تساعد من لديهم معصم مكسور أو وهج على الشاشة أو اتصال بطيء."},{"text":"أوافق، لأن WCAG لا تنطبق إلا حين تزيد نسبة المستخدمين ذوي الإعاقة على 5%","why":"ليس في WCAG أي عتبة للاستخدام. إنها تصف المحتوى، لا حجم الجمهور."},{"text":"أوافق، لكن لنُضِف سكربت overlay لإمكانية الوصول احتياطًا","why":"الـ overlays لا تُصلح الكود الأساسي، وتبقى الصفحة الافتراضية معطوبة لأكثر الناس حاجة إليها."}],"answer":0},{"q":"<p>يستخدم كريم جهاز تبديل واحدًا. يمرّ برنامج المسح على عناصر التحكّم في Ticketly لكنه لا يتوقّف أبدًا عند عنصر “Select” في خريطة المقاعد، وهو div عليه معالج نقر. لماذا؟</p>","options":[{"text":"برامج التبديل لا تعمل إلا على الأجهزة المحمولة","why":"الوصول بأجهزة التبديل يعمل على سطح المكتب والهاتف. المشكلة في العنصر، لا في المنصّة."},{"text":"يحتاج الـ div إلى حجم خط أكبر","why":"الحجم لا يؤثّر في توقّف المسح عند العنصر؛ قابلية التركيز هي التي تؤثّر."},{"text":"مستخدمو أجهزة التبديل لا يستطيعون ضغط إلا الروابط، لا الأزرار","why":"تستطيع برامج التبديل تفعيل أي عنصر تحكّم قابل للتركيز، بما في ذلك الأزرار."},{"text":"مسح أجهزة التبديل ينتقل بين العناصر القابلة للتركيز، والـ div الذي ليس عليه إلا معالج نقر غير قابل للتركيز","why":"صحيح. يعتمد مستخدمو أجهزة التبديل على قابلية التشغيل نفسها بلوحة المفاتيح التي يعتمد عليها غيرهم. والزر الحقيقي يُصلح المشكلة."}],"answer":3},{"q":"<p>رابط «تحتاج إلى مساعدة؟» في Ticketly يقع في الترويسة في معظم الصفحات لكنه ينتقل إلى التذييل في خطوات الدفع. أيّ معيار في WCAG 2.2 معرّض للمخالفة؟</p>","options":[{"text":"2.4.11 Focus Not Obscured (Minimum)","why":"يتعلّق هذا المعيار بإخفاء العناصر التي عليها التركيز خلف محتوى آخر، لا بمكان ظهور المساعدة."},{"text":"3.2.6 Consistent Help","why":"صحيح. معيار جديد في 2.2 بالمستوى A: آليات المساعدة المتكرّرة عبر الصفحات يجب أن تظهر بالترتيب النسبي نفسه."},{"text":"3.3.7 Redundant Entry","why":"يتعلّق معيار Redundant Entry بعدم مطالبة المستخدمين بإعادة إدخال معلومات قدّموها من قبل."},{"text":"2.5.8 Target Size (Minimum)","why":"حجم الهدف يتعلّق بمساحة عنصر التحكّم، لا بموضعه عبر الصفحات."}],"answer":1},{"q":"<p>زر يعرض أيقونة سلة مهملات والنص المرئي “Delete ticket”، لكن NVDA يُعلن “Remove, button”. ما التفسير؟</p>","options":[{"text":"يختصر NVDA نصوص الأزرار الطويلة تلقائيًا","why":"تقرأ قارئات الشاشة الاسم المتاح كما هو؛ ولا تختصره ولا تعيد صياغته."},{"text":"يُقرأ النص البديل لأيقونة السلة بدلًا من النص","why":"لو كان للأيقونة نص بديل لأُضيف إلى المحتوى، لا أن يحلّ محلّه."},{"text":"خاصية aria-label=“Remove” تتجاوز النص المرئي، وهذا يكسر أيضًا معيار Label in Name لمستخدمي التحكّم الصوتي","why":"صحيح. aria-label تحلّ محلّ المحتوى بوصفها الاسم. احذفها، أو اجعلها تبدأ بـ “Delete ticket”."},{"text":"الزر تنقصه خاصية title","why":"الـ title آخر ملاذ ولن تتجاوز أي شيء؛ فالاسم المُعلَن يأتي من مصدر أعلى أولوية."}],"answer":2},{"q":"<p>Ticketly شركة من 40 موظفًا مقرّها خارج الاتحاد الأوروبي، تبيع تذاكر المهرجانات عبر الإنترنت لعملاء في ألمانيا. هل يعنيها قانون إمكانية الوصول الأوروبي؟</p>","options":[{"text":"نعم؛ خدمات التجارة الإلكترونية المقدَّمة للمستهلكين في الاتحاد الأوروبي تقع ضمن نطاقه، واستثناء الشركات متناهية الصغر لا يشمل إلا من لديها أقل من 10 موظفين","why":"صحيح. منذ 28 يونيو 2025 ينطبق القانون على الخدمات المشمولة المقدَّمة داخل الاتحاد الأوروبي، أيًّا كان مقرّ الشركة."},{"text":"لا، لأن الشركة ليس مقرّها في الاتحاد الأوروبي","why":"يتبع القانون مكان تقديم الخدمات للمستهلكين، لا مكان تسجيل الشركة."},{"text":"لا، لأن تذاكر الفعاليات لا يشملها أي قانون لإمكانية الوصول","why":"التجارة الإلكترونية من الخدمات التي يشملها القانون، وتذاكر النقل مشمولة أيضًا."}],"answer":0}],"s-a11y-2":[{"q":"<p>نموذج البحث في موقع Ticketly يقع في الترويسة. أيّ كود يكشفه بوصفه landmark من نوع search؟</p>","options":[{"text":"<code dir=\"ltr\">&lt;div class=&quot;search&quot;&gt;&lt;form&gt;…&lt;/form&gt;&lt;/div&gt;</code>","why":"الـ div الذي عليه كلاس ليس له دور landmark، فلا يظهر في قائمة الـ landmarks."},{"text":"<code dir=\"ltr\">&lt;form&gt;…&lt;/form&gt;</code> بلا اسم","why":"لا يصبح الـ form ‏landmark إلا حين يكون له اسم متاح، وحتى حينها يكون landmark من نوع form لا search."},{"text":"<code dir=\"ltr\">&lt;nav class=&quot;search&quot;&gt;…&lt;/nav&gt;</code>","why":"عنصر nav مخصّص لروابط التنقّل. واستخدامه للبحث سيعطي المنطقة وصفًا خاطئًا."},{"text":"<code dir=\"ltr\">&lt;search&gt;&lt;form&gt;…&lt;/form&gt;&lt;/search&gt;</code>","why":"صحيح. يقابل عنصر search الـ landmark من نوع search. وفي الكود الأقدم سترى أيضًا form role=“search”."}],"answer":3},{"q":"<p>عنصر “Download your tickets (PDF)” يجلب الملف من ‎/bookings/123/tickets.pdf. أيّ عنصر هو الصحيح؟</p>","options":[{"text":"رابط: <code dir=\"ltr\">&lt;a href=&quot;/bookings/123/tickets.pdf&quot;&gt;Download your tickets (PDF, 200 KB)&lt;/a&gt;</code>","why":"صحيح. إنه يذهب إلى مورد له عنوان URL، فهو رابط. وذكر نوع الملف وحجمه يضبط توقّعات المستخدم."},{"text":"زر يستدعي fetch() ويفتح الملف","why":"إعادة صنع التنقّل بسكربت تُفقدك سلوك الروابط مثل الفتح في تبويب جديد أو نسخ العنوان."},{"text":"div منسّق كزر وعليه role=“link”","why":"هذا يحتاج إلى tabindex ومعالجة للمفاتيح ليعمل، والرابط الحقيقي يفعل ذلك كله أصلًا."}],"answer":0},{"q":"<p>تطلب صفحة الدفع تاريخ الميلاد في ثلاثة حقول (اليوم والشهر والسنة) تحت نص مرئي واحد هو “Date of birth”. ما أفضل كود؟</p>","options":[{"text":"عنصر label واحد تشير for فيه إلى حقل اليوم","why":"الـ label لا يسمّي إلا عنصر تحكّم واحدًا، فيبقى الشهر والسنة بلا اسم."},{"text":"aria-label=“Date of birth” على الحقول الثلاثة","why":"ستحصل الحقول الثلاثة على الاسم نفسه، فلا يستطيع المستخدمون التمييز بين اليوم والشهر والسنة."},{"text":"fieldset يكون الـ legend فيه “Date of birth”، مع labels هي Day وMonth وYear، وقيم autocomplete هي bday-day وbday-month وbday-year","why":"صحيح. الـ legend يسمّي المجموعة، ولكل حقل label خاص به، والتعبئة التلقائية تعمل."}],"answer":2},{"q":"<p>الزر <code dir=\"ltr\">&lt;button&gt;&lt;img src=&quot;calendar.svg&quot; alt=&quot;calendar&quot;&gt;&lt;/button&gt;</code> يضيف الفعالية إلى تقويم المستخدم. ما الذي يجب أن يتغيّر؟</p>","options":[{"text":"لا شيء؛ للزر اسم","why":"له اسم، لكن “calendar” تصف الصورة، لا ما يفعله ضغط الزر."},{"text":"يجب أن يصف الـ alt الفعل، مثل “Add to calendar”","why":"صحيح. في الصور الوظيفية، يسمّي النص البديل الفعل أو الوجهة."},{"text":"يجب أن يكون الـ alt فارغًا لأن الأيقونات زخرفية","why":"هذه الأيقونة هي المحتوى الوحيد للزر، فالـ alt الفارغ سيترك الزر بلا اسم إطلاقًا."},{"text":"يجب أن تحصل الصورة على role=“button”","why":"عنصر button يوفّر الدور أصلًا. المشكلة في الاسم."}],"answer":1},{"q":"<p>جدول مواعيد المهرجان في Ticketly جدول فيه أسماء المسارح في الأعلى والأوقات في العمود الأول. ما الذي يجعل كل خلية تُعلن وقتها ومسرحها؟</p>","options":[{"text":"خط عريض في العمود الأول والصف الأول","why":"الخط العريض بصري فقط ولا يُكشف كمعلومات عناوين."},{"text":"فقرة ملخّص فوق الجدول","why":"الملخّص يساعد على التوجّه لكنه لا يربط العناوين بكل خلية."},{"text":"role=“grid” على الجدول","why":"الـ grid مخصّص للـ widgets التفاعلية الشبيهة بجداول البيانات، ويضيف توقّعات للوحة المفاتيح لا يحتاجها جدول مواعيد."},{"text":"th scope=“col” للمسارح، وth scope=“row” للأوقات، وcaption","why":"صحيح. عندها تُعلن قارئات الشاشة عنواني الصف والعمود كلما تنقّل المستخدمون بين الخلايا."}],"answer":3}],"s-a11y-3":[{"q":"<p>العنصر <code dir=\"ltr\">&lt;div class=&quot;card&quot; tabindex=&quot;0&quot; onclick=&quot;openEvent()&quot;&gt;</code> يتلقّى التركيز، لكن ضغط Enter لا يفعل شيئًا. لماذا؟</p>","options":[{"text":"الـ tabindex يجعله قابلًا للتركيز فقط؛ والتفعيل بلوحة المفاتيح غير موصول، لأن Enter لا يطلق حدث click على div","why":"صحيح. استخدم رابطًا (فهو يفتح صفحة فعالية) فتحصل على التركيز وEnter والدور الصحيح مجانًا."},{"text":"خاصية onclick لا تعمل إلا مع الفأرة في بعض المتصفّحات","why":"يُطلَق onclick مع النقرات الحقيقية في كل المتصفّحات؛ لكن المفاتيح لا تطلقه أبدًا على div."},{"text":"يجب أن تكون قيمة tabindex هي 1 ليعمل Enter","why":"الـ tabindex الموجب لا يغيّر إلا ترتيب التركيز ويسبّب أخطاء في الترتيب. ولا علاقة له بالتفعيل."}],"answer":0},{"q":"<p>زر الإغلاق المخصّص في نافذة الحجز يحذف عنصر النافذة من الـ DOM. وبعد ذلك يقفز تركيز لوحة المفاتيح إلى أعلى الصفحة. ما أفضل إصلاح؟</p>","options":[{"text":"أضِف tabindex=“-1” إلى body ليجد التركيز مكانًا يذهب إليه","why":"التركيز يسقط إلى body أصلًا. المشكلة أنه يجب أن يعود إلى عنصر التحكّم الذي فتح النافذة."},{"text":"أضِف aria-live إلى النافذة ليُعلَن إغلاقها","why":"الإعلان لا يعيد المستخدم إلى حيث كان."},{"text":"أغلقها بـ dialog.close() ليعيد المتصفّح التركيز إلى العنصر الذي فتحها، أو انقل التركيز إليه صراحةً قبل حذف أي شيء","why":"صحيح. يتابع المستخدمون من حيث بدؤوا بدلًا من إعادة التنقّل في الصفحة كلها بـ Tab."},{"text":"احذف زر الإغلاق واعتمد على Escape وحده","why":"كثير من المستخدمين لا يعرفون Escape، ومستخدمو اللمس ليس لديهم مفتاح Escape."}],"answer":2},{"q":"<p>بينما يكتب المستخدم في مربع البحث في Ticketly، يتغيّر عدّاد مثل “12 events found”. ما أفضل طريقة لإعلانه؟</p>","options":[{"text":"انقل التركيز إلى العدّاد بعد كل ضغطة مفتاح","why":"هذا سيسحب المستخدم من الحقل الذي يكتب فيه."},{"text":"عنصر role=“status” موجود منذ تحميل الصفحة، ويُحدَّث حين يتوقّف المستخدم عن الكتابة","why":"صحيح. تُعلن الـ live region المهذّبة العدد دون نقل التركيز، وانتظار التوقّف يمنع سيل الإعلانات."},{"text":"role=“alert” على العدّاد حتى لا يفوت أبدًا","why":"الإعلانات الحازمة مع كل ضغطة مفتاح تقاطع صدى الكتابة الخاص بالمستخدم، وهذا مُرهِق."},{"text":"ضع العدد في الـ placeholder الخاص بالحقل","why":"الـ placeholder لا يُعلَن عند تغيّره ويختفي بينما يكتب المستخدم."}],"answer":1},{"q":"<p>في tablist، تنقل مفاتيح الأسهم التركيز بين التبويبات، لكن اللوحة لا تتغيّر إلا حين يضغط المستخدم Enter أو Space. هل هذا تطبيق صحيح لنمط التبويبات في APG؟</p>","options":[{"text":"لا، يشترط APG أن تتغيّر اللوحات بمجرد أن يتلقّى التبويب التركيز","why":"يصف APG التفعيل التلقائي والتفعيل اليدوي كليهما."},{"text":"لا، يجب أن تُفعَّل التبويبات بمفتاح Tab","why":"ينقل Tab خارج الـ tablist إلى اللوحة. ومفاتيح الأسهم هي التي تنقل بين التبويبات."},{"text":"فقط إن كان كل تبويب رابطًا أيضًا","why":"التبويبات ليست روابط؛ والروابط إلى صفحات أخرى تنقّل، لا widget تبويبات."},{"text":"نعم؛ هذا تفعيل يدوي، ويُوصى به حين يكون عرض اللوحة بطيئًا، مثلًا لأنها تحمّل بيانات","why":"صحيح. التفعيل التلقائي يناسب اللوحات الفورية؛ واليدوي يتجنّب تحميل كل لوحة يمرّ بها المستخدم بالأسهم."}],"answer":3},{"q":"<p>لدينا <code dir=\"ltr\">&lt;button aria-controls=&quot;events-menu&quot;&gt;Events&lt;/button&gt;</code> و<code dir=\"ltr\">&lt;ul id=&quot;events-menu&quot; aria-expanded=&quot;true&quot;&gt;</code>. لا يقول NVDA أبدًا “expanded” عند الزر. لماذا؟</p>","options":[{"text":"مكان aria-expanded هو الزر الذي يتحكّم في المحتوى، لا القائمة","why":"صحيح. عنصر التحكّم هو من يحمل الحالة؛ انقل الخاصية إليه وحدّثها مع كل تبديل."},{"text":"يجب حذف aria-controls لكي تعمل aria-expanded","why":"aria-controls اختيارية، لكنها لا تمنع aria-expanded من العمل."},{"text":"aria-expanded لا تعمل إلا على عناصر عليها role=“menu”","why":"aria-expanded مدعومة على الأزرار والروابط والـ comboboxes وغيرها. وأزرار الـ disclosure تستخدمها طوال الوقت."}],"answer":0}],"s-a11y-4":[{"q":"<p>عنوان قسم في Ticketly بحجم 24px وخط عادي، ونسبة تباينه 3.2:1. هل يحقّق معيار 1.4.3 في المستوى AA؟</p>","options":[{"text":"لا، كل النصوص تحتاج إلى 4.5:1","why":"للنص الكبير عتبة أقل، لأن الحروف الأكبر أسهل قراءةً عند تباين أقل."},{"text":"لا، العناوين تحتاج إلى 7:1","why":"نسبة 7:1 هي عتبة AAA للنص العادي؛ وليست مطلوبة في AA."},{"text":"نعم؛ 24px تُعدّ نصًا كبيرًا، والنص الكبير يحتاج إلى 3:1","why":"صحيح. النص الكبير لا يقلّ عن 24px بخط عادي أو 18.66px بخط عريض، ويحتاج إلى 3:1."},{"text":"نعم، لأن العناوين مستثناة من اشتراطات التباين","why":"العناوين نصوص وهي مشمولة. إنها تنجح هنا بسبب حجمها، لا بسبب استثناء."}],"answer":2},{"q":"<p>عند viewport بعرض 320px، يُعاد تدفّق صفحة Ticketly، لكن جدول مواعيد المهرجان العريض يتمرّر أفقيًا داخل حاويته الخاصة. هل يخالف هذا معيار 1.4.10 Reflow؟</p>","options":[{"text":"لا؛ المحتوى الذي يحتاج إلى بُعدين، مثل جداول البيانات، مستثنى، ما دامت بقية الصفحة يُعاد تدفّقها","why":"صحيح. اقصر التمرير على حاوية الجدول (واجعل تلك الحاوية قابلة للتمرير بلوحة المفاتيح) بدلًا من الصفحة كلها."},{"text":"نعم؛ لا يجوز أن يتمرّر أي شيء أفقيًا أبدًا","why":"يستثني المعيار صراحةً المحتوى الذي يتطلّب تخطيطًا ثنائي الأبعاد."},{"text":"نعم، ما لم يُستبدل الجدول بصورة","why":"صورة الجدول ستحذف البيانات عن قارئات الشاشة وتخالف معايير أخرى."}],"answer":0},{"q":"<p>ما الاسم المتاح لحقل البحث؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"html\" data-index=\"0\"><div class=\"code-head\"><span class=\"code-title\">HTML</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\">&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">input</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> id</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"q\"</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> placeholder</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Search events\"</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> aria-labelledby</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"go\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span>\n<span class=\"line\"><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">button</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> id</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"go\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>Search&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">button</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span></code></pre></div>\n","options":[{"text":"“Search events”","why":"الـ placeholder ملاذ أخير فقط، يُستخدم حين لا يوفّر أي شيء آخر اسمًا."},{"text":"لا اسم، لأن aria-labelledby لا يمكن أن تشير إلى زر","why":"يمكن لـ aria-labelledby أن تشير إلى أي عنصر فيه نص."},{"text":"“Search events Search”","why":"الأسماء لا تجمع بين المصادر؛ المصدر الأعلى أولوية يفوز."},{"text":"“Search”","why":"صحيح. لـ aria-labelledby الأولوية العليا، فيصبح نص الزر اسم الحقل."}],"answer":3},{"q":"<p>يستخدم الشريط الرئيسي في Ticketly تأثير parallax: تتحرّك الخلفية بسرعة مختلفة عند التمرير. وقد ضبط أحد المستخدمين Reduce motion في نظام تشغيله. ماذا يجب أن يحدث؟</p>","options":[{"text":"لا شيء؛ الـ parallax ينطلق بتمرير المستخدم نفسه، فهو مقبول","why":"الحركة التي يطلقها التفاعل قد تسبّب الدوار أيضًا؛ ولهذا بالضبط وُجد تفضيل تقليل الحركة."},{"text":"داخل media query من نوع prefers-reduced-motion: reduce، أوقف الـ parallax واعرض خلفية ثابتة","why":"صحيح. يبقى المحتوى، وتزول الحركة الكبيرة التي قد تثير أعراض الاضطرابات الدهليزية."},{"text":"اعرض نافذة حوار تسأل المستخدم إن كان يريد الحركات","why":"أجاب المستخدم أصلًا في إعدادات نظامه. احترم تفضيله دون أن تسأله مرة أخرى."}],"answer":1},{"q":"<p>يطلق Ticketly نسخة عربية كاملة من موقعه. ما الذي يوضع على العنصر الجذر؟</p>","options":[{"text":"<code dir=\"ltr\">&lt;html lang=&quot;en&quot; dir=&quot;rtl&quot;&gt;</code>","why":"ستبقى اللغة إنجليزية، فتستخدم قارئات الشاشة صوتًا إنجليزيًا للنص العربي."},{"text":"<code dir=\"ltr\">&lt;html lang=&quot;ar&quot;&gt;</code> فقط، مع direction: rtl في CSS","why":"الاتجاه جزء من معنى المحتوى ومكانه الكود، لا ملف الأنماط وحده."},{"text":"<code dir=\"ltr\">&lt;html dir=&quot;auto&quot;&gt;</code>","why":"القيمة auto مخصّصة للنصوص مجهولة الاتجاه مثل مدخلات المستخدمين. أما لصفحة عربية معروفة، فصرّح بالاتجاه ومعه اللغة."},{"text":"<code dir=\"ltr\">&lt;html lang=&quot;ar&quot; dir=&quot;rtl&quot;&gt;</code>","why":"صحيح. تختار lang الصوت العربي وميزات اللغة الأخرى؛ وتضبط dir الاتجاه الأساسي للصفحة كلها."}],"answer":3}],"s-a11y-5":[{"q":"<p>يعلِّم axe تباين النص الأبيض فوق صورة المهرجان بأنه “needs review” لا مخالفة. ماذا تفعل؟</p>","options":[{"text":"افحصه يدويًا مقابل أفتح جزء من الصورة خلف النص، وأضِف طبقة معتمة إن فشل","why":"صحيح. لا يستطيع axe معرفة البكسلات التي خلف النص، فلا بدّ أن يقيسه إنسان."},{"text":"تجاهله، فهو ليس مخالفة","why":"تعني “needs review” أن الأداة لم تستطع الحسم، لا أن المحتوى نجح."},{"text":"عطّل قاعدة color-contrast ليبقى التقرير نظيفًا","why":"هذا يُخفي كل إخفاقات التباين المستقبلية في الموقع، لا هذا الإخفاق وحده."}],"answer":0},{"q":"<p>أثناء اختبار نموذج باستخدام NVDA، تؤدّي كتابة الحرف “h” في حقل نصي إلى القفز إلى العنوان التالي بدلًا من الكتابة. ما الذي يحدث؟</p>","options":[{"text":"الحقل للقراءة فقط","why":"الحقل المخصّص للقراءة فقط لن يجعل NVDA يقفز إلى العناوين؛ سيرفض الإدخال فحسب."},{"text":"تخطيط لوحة المفاتيح في NVDA معطوب ويحتاج إلى إعادة تثبيت","why":"لا شيء معطوب. هكذا صُمّم وضع التصفّح ليعمل."},{"text":"NVDA ما زال في وضع التصفّح، حيث الحروف مفاتيح للتنقّل؛ اضغط Enter أو NVDA+Space للانتقال إلى وضع التركيز","why":"صحيح. وإن لم يبدّل NVDA تلقائيًا أبدًا، فتحقّق من أن الحقل حقل إدخال حقيقي لا عنصر مخصّص بلا دور."},{"text":"في الصفحة عناوين كثيرة جدًا","why":"عدد العناوين لا علاقة له بكتابة الحروف من عدمها."}],"answer":2},{"q":"<p>أول تشغيل لـ Playwright مع axe على Ticketly يبلّغ عن 340 مخالفة في أنحاء الموقع. ما الخطوة التالية الأكثر فاعلية؟</p>","options":[{"text":"أوقف الفحص حتى يتوفّر وقت لإصلاح كل شيء","why":"من دون الفحص، تُضاف مخالفات جديدة كل أسبوع، فلا يزداد الـ backlog إلا تضخّمًا."},{"text":"أصلح المخالفات بالترتيب الذي يسردها به axe","why":"ترتيب axe ليس ترتيب أولويات. الأثر في المهام الحقيقية هو ما يجب أن يحسم."},{"text":"أضِف خصائص aria-label حيثما يشتكي axe","why":"إضافة ARIA لإسكات أداة تُنشئ في الغالب مشكلات جديدة، مثل أسماء لا تطابق التسميات المرئية."},{"text":"سجّل المخالفات الحالية كخطّ أساس، واجعل الـ CI يفشل على الجديدة فقط، وأصلح خطّ الأساس بدءًا بمسار الدفع","why":"صحيح. يوقف خطّ الأساس التراجعات فورًا بينما يُسدَّد الدَّين القائم بحسب الأثر."}],"answer":3},{"q":"<p>أيّ ملاحظة تدقيق يجب أن تُصنَّف حرجة؟</p>","options":[{"text":"فاصل زخرفي يُعلَن على أنه “graphic”","why":"هذا يضيف ضجيجًا لكنه لا يمنع أحدًا من إتمام مهمة، فهو طفيف."},{"text":"مصيدة لوحة مفاتيح داخل نموذج الدفع المضمَّن","why":"صحيح. لا يستطيع مستخدمو لوحة المفاتيح إتمام الدفع ولا مغادرة النموذج، وهذا يعيق أهمّ مهمة في الموقع."},{"text":"نص رابط في التذييل يقول “More”","why":"نص الرابط المبهم مشكلة حقيقية، لكنه نادرًا ما يعيق مهمة. إنه متوسط في أقصى الأحوال."},{"text":"نص رمادي في التذييل بتباين 4.2:1","why":"يخالف معيار 1.4.3 ويجب إصلاحه، لكنه لا يعيق مهمة أساسية، فليس حرجًا."}],"answer":1},{"q":"<p>يقول مزوّد أداة المحادثة المباشرة في Ticketly إنها «متوافقة تمامًا مع WCAG». ماذا تفعل؟</p>","options":[{"text":"اطلب تقرير توافق إمكانية الوصول (Accessibility Conformance Report) الخاص بهم، وأدرج الأداة في اختباراتك أنت بلوحة المفاتيح وقارئ الشاشة","why":"صحيح. عوائق أدوات الأطراف الثالثة هي عوائق مستخدميك، والادّعاءات لا تساوي أكثر من الاختبارات التي تقف خلفها."},{"text":"اقبل الادّعاء، فالمزوّدون مسؤولون قانونيًا عن أدواتهم","why":"على موقعك، يصطدم مستخدموك بعوائق الأداة، وقد تتقاسم المسؤولية عنها."},{"text":"استبعد الأداة من نطاق التدقيق ليبقى التقرير مركّزًا","why":"استبعاد ميزة يستخدمها الناس للحصول على المساعدة يُخفي جزءًا من التجربة قد يكون غير سهل الوصول."}],"answer":0}]},"final":[{"q":"<p>أيّ تغيير يُصلح أكبر عدد من المشكلات دفعة واحدة؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"html\" data-index=\"1\"><div class=\"code-head\"><span class=\"code-title\">HTML</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\">&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">span</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> class</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"link\"</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> onclick</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"</span><span style=\"color:#8250DF;--shiki-dark:#D2A8FF\">go</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">('/faq')\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>FAQ&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">span</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span></code></pre></div>\n","options":[{"text":"أضِف tabindex=“0”","why":"هذا يجعله قابلًا للتركيز، لكنه يبقى بلا دور رابط، ولا يستجيب لـ Enter، ولا يمكن فتحه في تبويب جديد."},{"text":"أضِف role=“link”","why":"الدور يغيّر الإعلان فقط؛ ويبقى العنصر غير قابل للتركيز وبلا دعم للوحة المفاتيح."},{"text":"أضِف aria-label=“FAQ”","why":"الـ span يحتوي النص FAQ أصلًا. والتسمية على span عامّ تُتجاهَل ولا تُصلح شيئًا."},{"text":"استبدله بـ <code dir=\"ltr\">&lt;a href=&quot;/faq&quot;&gt;FAQ&lt;/a&gt;</code>","why":"صحيح. الرابط الحقيقي يأتي بالدور، والتركيز، والتفعيل بـ Enter، ودعم التبويب الجديد، ويعمل دون JavaScript."}],"answer":3},{"q":"<p>تستخدم أزرار Ticketly نصًا أبيض بحجم 14px على #5b3cc4، بنسبة 7.27:1. كيف يُقيَّم هذا وفق معايير التباين في WCAG؟</p>","options":[{"text":"يفشل في AA، لأن النص الصغير يحتاج إلى 10:1","why":"لا توجد عتبة 10:1. يحتاج AA إلى 4.5:1 للنص العادي."},{"text":"ينجح في AA ‏(4.5:1) وفي AAA أيضًا (7:1) للنص العادي","why":"صحيح. 7.27 أعلى من العتبتين كلتيهما."},{"text":"ينجح في AA فقط لأن الأزرار تُعدّ نصًا كبيرًا","why":"حجم النص، لا نوع العنصر، هو ما يحدّد ما يُعدّ كبيرًا. و14px بخط عادي نص عادي."}],"answer":1},{"q":"<p>يُرسَل نموذج تسجيل طويل وفيه ثلاثة أخطاء. إلى أين يجب أن يذهب التركيز؟</p>","options":[{"text":"إلى ملخّص أخطاء في الأعلى يسرد المشكلات الثلاث كروابط إلى حقولها","why":"صحيح. يسمع المستخدمون عدد المشكلات ويستطيعون القفز إلى كلٍّ منها."},{"text":"لا مكان؛ الإطارات الحمراء تُظهر أيّ الحقول خاطئة","why":"اللون وحده يخالف معيار 1.4.1، ومن دون تغيير في التركيز لا يعرف مستخدمو قارئ الشاشة أن شيئًا حدث."},{"text":"إلى زر الإرسال، ليحاول المستخدم مرة أخرى","why":"سيبقى التركيز حيث المستخدم أصلًا، ولن يخبره شيء بما حدث من خطأ."}],"answer":0},{"q":"<p>زر تبديل لتنسيق النص يستخدم <code dir=\"ltr\">aria-pressed</code>، وتتبدّل تسميته أيضًا من “Bold” إلى “Unbold” عند ضغطه. ما المشكلة؟</p>","options":[{"text":"aria-pressed لا تعمل إلا على مربّعات الاختيار","why":"aria-pressed هي الحالة الصحيحة لأزرار التبديل."},{"text":"يجب أن تستخدم أزرار التبديل aria-expanded بدلًا منها","why":"aria-expanded مخصّصة لعناصر التحكّم التي تُظهر محتوى آخر وتُخفيه."},{"text":"تغيير التسمية والحالة معًا يعطي إعلانًا مربكًا مثل “Unbold, toggle button, pressed”؛ أبقِ التسمية ثابتة","why":"صحيح. إما تسمية ثابتة مع aria-pressed، وإما تسمية متغيّرة دونها، لا الاثنتان معًا."}],"answer":2},{"q":"<p>يحذف مستخدم آخر تذكرة في سلّته، فيختفي زر Remove الذي ضغطه. إلى أين يجب أن يذهب التركيز؟</p>","options":[{"text":"لا مكان؛ المتصفّح يتولّى الأمر","why":"يُسقط المتصفّح التركيز إلى body، فتبدأ ضغطة Tab التالية من أعلى الصفحة."},{"text":"إلى شعار الموقع","why":"هذا يُخرج المستخدم من السياق الذي كان يعمل فيه."},{"text":"إلى أول رابط في التذييل","why":"هذا بعيد عن السلة ولا يعطي أي استجابة بشأن ما حدث."},{"text":"إلى عنوان السلة أو رسالة «سلّتك فارغة» صارت قابلة للتركيز بـ tabindex=“-1”","why":"صحيح. يبقى المستخدم في سياقه ويسمع نتيجة ما فعله."}],"answer":3},{"q":"<p>زرّا أيقونتين بحجم 20 × 20 px والمسافة بين مركزيهما 30 px. هل يحقّقان معيار 2.5.8 Target Size (Minimum)؟</p>","options":[{"text":"لا، كل هدف يجب ألا يقلّ عن 24 × 24 px","why":"يوجد استثناء المسافة للأهداف الأصغر من الحدّ."},{"text":"نعم، بموجب استثناء المسافة: الدوائر بقطر 24 px المتمركزة على كل هدف لا تتداخل مع بعضها ولا مع الهدف الآخر","why":"صحيح. مع 30 px بين المركزين، تبقى الدوائر ذات نصف القطر 12 px منفصلة. ومع ذلك فالأهداف الأكبر أرفق بالمستخدمين."},{"text":"نعم، لأن أزرار الأيقونات مستثناة","why":"ليس لأزرار الأيقونات استثناء خاص؛ الاستثناءات للأهداف داخل النص، والمكافئات، وما يتحكّم فيه المتصفّح، والضرورية فقط."}],"answer":1},{"q":"<p>مقال إنجليزي في Ticketly يقتبس مراجعة فرنسية داخل blockquote. ماذا تشترط WCAG؟</p>","options":[{"text":"<code dir=\"ltr\">lang=&quot;fr&quot;</code> على الـ blockquote، لتتحوّل قارئات الشاشة إلى النطق الفرنسي (3.1.2 Language of Parts)","why":"صحيح. المقاطع بلغة أخرى تحصل على خاصية lang خاصة بها."},{"text":"<code dir=\"ltr\">dir=&quot;rtl&quot;</code> على الـ blockquote","why":"الفرنسية تُكتب من اليسار إلى اليمين. والخاصية dir تتعلّق بالاتجاه، لا باللغة."},{"text":"لا شيء، لأن الصفحة عليها lang=“en” أصلًا","why":"لغة الصفحة تغطّي المحتوى الإنجليزي فقط. والمقاطع بلغات أخرى تحتاج إلى lang خاصة بها."}],"answer":0},{"q":"<p>بعد كل نقرة على Add to basket، يستخدم Ticketly ‏<code dir=\"ltr\">role=&quot;alert&quot;</code> ليقول “Ticket added”. ما المشكلة؟</p>","options":[{"text":"التنبيهات (alerts) لا تُعلنها قارئات الشاشة أبدًا","why":"التنبيهات تُعلَن، وفورًا، وهذه هي المشكلة بالذات."},{"text":"الـ live regions لا يمكن أن تحتوي كلمة “added”","why":"أي نص يمكن إعلانه من live region."},{"text":"الـ alert حازمة وتقاطع الكلام؛ ورسالة التأكيد الروتينية يجب أن تستخدم role=“status”","why":"صحيح. احتفظ بالـ alert للرسائل النادرة والعاجلة، مثل فشل الدفع."},{"text":"يجب أن تكون الرسالة في عنوان الصفحة بدلًا من ذلك","why":"تغيير العنوان لا يُعلَن بشكل موثوق، وهو إساءة استخدام للعنوان."}],"answer":2},{"q":"<p>أيّ طريقة اختبار ستكشف أن نافذة حوار مشروطة تترك تركيز لوحة المفاتيح على الصفحة التي خلفها؟</p>","options":[{"text":"فحص axe للصفحة والنافذة مغلقة","why":"والنافذة مغلقة لا يوجد ما يُختبر، وسلوك التركيز يحتاج إلى تفاعل على أي حال."},{"text":"فحص تباين الألوان بمنتقي الألوان في أدوات المطوّر","why":"التباين لا علاقة له بوجهة التركيز."},{"text":"التحقّق من صحة كود HTML","why":"قد يكون الكود صحيحًا تمامًا بينما سلوك التركيز معطوب."},{"text":"فتح النافذة بلوحة المفاتيح وضغط Tab، أو مراقبة document.activeElement","why":"صحيح. إدارة التركيز تتعلّق بالسلوك عبر الزمن، وهو ما يراه فورًا شخص يختبر تفاعليًا."}],"answer":3},{"q":"<p>ما الخطأ في هذا الرابط؟</p>\n<div class=\"code-block\" dir=\"ltr\" data-lang=\"html\" data-index=\"2\"><div class=\"code-head\"><span class=\"code-title\">HTML</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\">&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">a</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> href</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"/artists/nour\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">>&#x3C;</span><span style=\"color:#116329;--shiki-dark:#7EE787\">img</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> src</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"nour.jpg\"</span><span style=\"color:#0550AE;--shiki-dark:#79C0FF\"> alt</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">=</span><span style=\"color:#0A3069;--shiki-dark:#A5D6FF\">\"Nour Quartet\"</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">> Nour Quartet&#x3C;/</span><span style=\"color:#116329;--shiki-dark:#7EE787\">a</span><span style=\"color:#1F2328;--shiki-dark:#E6EDF3\">></span></span></code></pre></div>\n","options":[{"text":"تحتاج الصورة إلى role=“img”","why":"لعناصر img دور الصورة أصلًا."},{"text":"يصبح الاسم “Nour Quartet Nour Quartet”؛ ويجب أن تحمل الصورة alt=“” لأن النص يسمّي الرابط أصلًا","why":"صحيح. حين يوجد نص للرابط، فالصورة التي بداخله ولا تفعل سوى تكراره يجب أن تُعلَّم بأنها زخرفية."},{"text":"لا يمكن أن تحتوي الروابط صورًا","why":"يمكن أن تحتوي الروابط صورًا؛ لكن يجب أن يناسب النص البديل السياق."}],"answer":1},{"q":"<p>أيّ هذه المعايير في WCAG 2.2 من المستوى AAA، فلا يُشترط لادّعاء التوافق بالمستوى AA؟</p>","options":[{"text":"2.4.13 Focus Appearance","why":"صحيح. يضع حدًّا أدنى لحجم مؤشّرات التركيز وتباينها في المستوى AAA. أما AA فيشترط مؤشّرًا مرئيًا (2.4.7) لا يُحجب بالكامل (2.4.11)."},{"text":"2.5.8 Target Size (Minimum)","why":"هذا من المستوى AA ومطلوب: أهداف لا تقلّ عن 24 × 24 بكسل CSS أو حولها مسافة كافية."},{"text":"3.3.8 Accessible Authentication (Minimum)","why":"هذا من المستوى AA ومطلوب: لا اختبار للوظائف الإدراكية دون بديل أو آلية مساعدة."},{"text":"2.4.11 Focus Not Obscured (Minimum)","why":"هذا من المستوى AA ومطلوب: لا يجوز أن تُخفى العناصر التي عليها التركيز بالكامل خلف محتوى وضعه صاحب الموقع."}],"answer":0},{"q":"<p>يمرّر كود JavaScript في Ticketly شريطًا متحرّكًا (carousel) للفنانين تلقائيًا. كيف يجب أن يحترم الكود تفضيل تقليل الحركة؟</p>","options":[{"text":"افحص <code dir=\"ltr\">navigator.reducedMotion</code> قبل البدء","why":"لا توجد خاصية كهذه. يُقرأ التفضيل عبر media query."},{"text":"اسأل المستخدم عبر confirm() عند كل تحميل للصفحة","why":"ضبط المستخدمون التفضيل في أنظمتهم أصلًا. وسؤالهم مرة أخرى إزعاج."},{"text":"افحص <code dir=\"ltr\">window.matchMedia('(prefers-reduced-motion: reduce)').matches</code> ولا تبدأ التمرير التلقائي حين تكون true، مع الإبقاء على زر الإيقاف المؤقت في الحالتين","why":"صحيح. احترم تفضيل النظام، وأبقِ زر الإيقاف المؤقت الذي يشترطه معيار 2.2.2 لكل من سواهم."}],"answer":2}],"glossary":[{"id":"situational-disability","term":"الإعاقة الظرفية (situational disability)","definition":"قيد مؤقت تسبّبه الظروف لا جسد الشخص، مثل وهج على الشاشة أو غرفة صاخبة أو حمل رضيع بذراع واحدة. والتصاميم التي تخدم الإعاقات الدائمة تساعد هنا في الغالب أيضًا.","lesson":"l-a11y-1-1"},{"id":"assistive-technology","term":"التقنيات المساعدة (assistive technology)","definition":"برمجيات أو أجهزة يستخدمها الناس لتشغيل الحاسوب بطريقة تناسبهم، مثل قارئات الشاشة وبرامج التكبير وأجهزة التبديل والتحكّم الصوتي. وهي تقرأ الصفحة عبر شجرة إمكانية الوصول.","lesson":"l-a11y-1-2"},{"id":"accessibility-tree","term":"شجرة إمكانية الوصول (accessibility tree)","definition":"شجرة مبسّطة يبنيها المتصفّح من الـ DOM وCSS، لكل عقدة فيها دور واسم وأي حالات أو قيمة. والتقنيات المساعدة تقرأ هذه الشجرة، لا البكسلات على الشاشة.","lesson":"l-a11y-1-2"},{"id":"screen-reader","term":"قارئ الشاشة (screen reader)","definition":"برنامج مساعد يحوّل شجرة إمكانية الوصول إلى كلام منطوق أو إلى طريقة برايل، ويتيح للمستخدمين التنقّل عبر العناوين والـ landmarks والروابط وحقول النماذج. ومن أشهرها JAWS وNVDA وVoiceOver وTalkBack.","lesson":"l-a11y-1-2"},{"id":"visually-hidden","term":"النص المخفي بصريًا (visually hidden text)","definition":"نص يُقَصّ بـ CSS إلى مربع بحجم 1px فيبقى في شجرة إمكانية الوصول دون أن يشغل مساحة مرئية. وعلى عكس display: none، ما زالت قارئات الشاشة تُعلنه.","lesson":"l-a11y-1-2"},{"id":"wcag","term":"WCAG","definition":"إرشادات إمكانية الوصول إلى محتوى الويب، وهي معيار W3C للمحتوى سهل الوصول. ينظّم الإصدار 2.2، المنشور في أكتوبر 2023، معايير نجاح قابلة للاختبار تحت أربعة مبادئ وثلاثة مستويات توافق.","lesson":"l-a11y-1-3"},{"id":"pour","term":"POUR","definition":"المبادئ الأربعة في قمّة WCAG: يجب أن يكون المحتوى قابلًا للإدراك (Perceivable)، وقابلًا للتشغيل (Operable)، وقابلًا للفهم (Understandable)، ومتينًا (Robust). ويقع كل إرشاد ومعيار نجاح تحت أحدها.","lesson":"l-a11y-1-3"},{"id":"conformance-level","term":"مستوى التوافق (A، AA، AAA)","definition":"المستوى الذي يقع فيه معيار النجاح، والذي يُعلَن عنده التوافق. المستوى AA، الذي يتضمّن كل معايير A، هو الهدف الذي تشترطه معظم القوانين والسياسات.","lesson":"l-a11y-1-3"},{"id":"european-accessibility-act","term":"قانون إمكانية الوصول الأوروبي (European Accessibility Act)","definition":"التوجيه الأوروبي 2019/882، الساري منذ 28 يونيو 2025، الذي يشترط أن تكون المنتجات والخدمات المشمولة، مثل التجارة الإلكترونية والخدمات المصرفية وبيع التذاكر، سهلة الوصول. ومعياره المرجعي EN 301 549 يقابل WCAG 2.1 AA، وقد نُشر تحديثه المبني على WCAG 2.2 عام 2026.","lesson":"l-a11y-1-3"},{"id":"landmark","term":"Landmark","definition":"منطقة في الصفحة لها دور يستطيع مستخدمو قارئ الشاشة عرض قائمة بها والقفز إليها، مثل banner وnavigation وmain وcontentinfo. وتُنشئها عناصر HTML مثل header وnav وmain وfooter.","lesson":"l-a11y-2-1"},{"id":"autocomplete-token","term":"قيمة autocomplete (autocomplete token)","definition":"قيمة لخاصية autocomplete في HTML، مثل name أو email أو cc-number، تعلن الغرض من الحقل فيستطيع المتصفّح تعبئته. وهي تحقّق معيار WCAG ‏1.3.5 Identify Input Purpose.","lesson":"l-a11y-2-3"},{"id":"alt-text","term":"النص البديل (alt text)","definition":"البديل النصي للصورة، ويُكتب في خاصية alt. يجب أن ينقل غرض الصورة في سياقها: ما تُظهره إن كانت معلوماتية، أو ما تفعله إن كانت رابطًا أو زرًّا.","lesson":"l-a11y-2-4"},{"id":"decorative-image","term":"الصورة الزخرفية (decorative image)","definition":"صورة لا تضيف أي معلومة في سياقها، مثل فاصل أو صورة للأجواء. تحصل على خاصية alt فارغة (alt=“”) فتتخطّاها قارئات الشاشة بدلًا من قراءة اسم ملفها.","lesson":"l-a11y-2-4"},{"id":"focus-order","term":"ترتيب التركيز (focus order)","definition":"التسلسل الذي ينتقل به مفتاح Tab بين العناصر القابلة للتركيز. وهو يتبع ترتيب الـ DOM، فيجب أن يطابق الكود ترتيب القراءة المرئي، ولا يجوز أبدًا استخدام قيم tabindex موجبة.","lesson":"l-a11y-3-1"},{"id":"focus-visible","term":":focus-visible","definition":"pseudo-class في CSS يطابق حين يقرّر المتصفّح أن التركيز يجب أن يظهر، كما في التنقّل بلوحة المفاتيح. وتنسيقه بإطار قوي يمنح مستخدمي لوحة المفاتيح مؤشّرًا واضحًا دون إظهار الحلقات عند النقر بالفأرة.","lesson":"l-a11y-3-1"},{"id":"skip-link","term":"رابط التخطّي (skip link)","definition":"رابط في أول الصفحة تمامًا، مخفي عادةً حتى يتلقّى التركيز، يقفز إلى المحتوى الرئيسي. يتيح لمستخدمي لوحة المفاتيح تجاوز التنقّل المتكرّر، محقّقًا معيار WCAG ‏2.4.1 Bypass Blocks.","lesson":"l-a11y-3-1"},{"id":"modal-dialog","term":"نافذة الحوار المشروطة (modal dialog)","definition":"نافذة تحجب بقية الصفحة حتى تُغلق. وعنصر dialog الأصلي المفتوح بـ showModal() ينقل التركيز إلى داخله، ويجعل الصفحة inert، ويُغلق بـ Escape، ويعيد التركيز بعد ذلك.","lesson":"l-a11y-3-2"},{"id":"inert","term":"inert","definition":"خاصية في HTML تُخرج العنصر وكل ما بداخله من التركيز والتفاعل بالمؤشّر وشجرة إمكانية الوصول. وهي مناسبة للأدراج المغلقة واللوحات الواقعة خارج الشاشة والمحتوى الذي خلف طبقة مخصّصة.","lesson":"l-a11y-3-2"},{"id":"aria","term":"ARIA","definition":"اختصار Accessible Rich Internet Applications، وهي مجموعة خصائص للأدوار والحالات والخصائص تغيّر ما تكشفه شجرة إمكانية الوصول. لا تضيف أي سلوك أبدًا، لذا يُفضَّل HTML الأصلي حيثما وُجد.","lesson":"l-a11y-3-3"},{"id":"live-region","term":"Live region","definition":"عنصر تُعلن قارئات الشاشة تغييرات محتواه دون نقل التركيز. ‏role=“status” مهذّبة وrole=“alert” حازمة؛ ويجب أن تكون المنطقة موجودة قبل أن يتغيّر نصها.","lesson":"l-a11y-3-3"},{"id":"apg","term":"دليل ARIA Authoring Practices ‏(APG)","definition":"دليل من W3C يصف أنماط الـ widgets الشائعة مثل التبويبات والـ disclosure ونافذة الحوار وزر القائمة، مع الأدوار والحالات وتفاعل لوحة المفاتيح الذي يتوقّعه المستخدمون من كلٍّ منها.","lesson":"l-a11y-3-4"},{"id":"roving-tabindex","term":"Roving tabindex","definition":"تقنية للـ widgets المركّبة لا يحمل فيها tabindex=“0” إلا العنصر النشط، بينما تحمل البقية “-1”. فيكون الـ widget محطة Tab واحدة، وتنقل مفاتيح الأسهم التركيز والقيمة 0 بين العناصر.","lesson":"l-a11y-3-4"},{"id":"contrast-ratio","term":"نسبة التباين (contrast ratio)","definition":"مقياس WCAG للفرق في الإضاءة النسبية بين لونين، من 1:1 إلى 21:1. يحتاج المستوى AA إلى 4.5:1 للنص العادي، و3:1 للنص الكبير وللعناصر غير النصية الضرورية.","lesson":"l-a11y-4-1"},{"id":"reflow","term":"إعادة التدفّق (reflow)","definition":"معيار WCAG ‏1.4.10: يجب أن يتّسع المحتوى لـ viewport عرضه 320 بكسل CSS دون تمرير أفقي، وهو عرض نافذة بعرض 1280px عند تكبير 400%. وجداول البيانات والخرائط مستثناة.","lesson":"l-a11y-4-2"},{"id":"prefers-reduced-motion","term":"prefers-reduced-motion","definition":"media feature في CSS تعكس إعداد نظام التشغيل لدى المستخدم لتقليل الحركة. استخدمها لاستبدال الحركات الكبيرة بتلاشٍ أو لحذفها، مراعاةً للمصابين باضطرابات دهليزية.","lesson":"l-a11y-4-2"},{"id":"accessible-name","term":"الاسم المتاح (accessible name)","definition":"النص الذي يعرّف العنصر للتقنيات المساعدة. تحسبه المتصفّحات من aria-labelledby، ثم aria-label، ثم التسمية الأصلية مثل label أو alt، ثم المحتوى، ثم title.","lesson":"l-a11y-4-3"},{"id":"label-in-name","term":"Label in Name","definition":"معيار WCAG ‏2.5.3: حين يكون لعنصر التحكّم نص مرئي، يجب أن يحتوي اسمه المتاح ذلك النص، ويُفضَّل أن يكون في بدايته، ليستطيع مستخدمو التحكّم الصوتي تفعيله بنطق ما يرونه.","lesson":"l-a11y-4-3"},{"id":"logical-properties","term":"الخصائص المنطقية (logical properties)","definition":"خصائص CSS مثل margin-inline-start وpadding-inline-end تتبع اتجاه الكتابة بدلًا من الجهات الفيزيائية، فتنعكس التخطيطات تلقائيًا في اللغات التي تُكتب من اليمين إلى اليسار مثل العربية.","lesson":"l-a11y-4-4"},{"id":"axe-core","term":"axe-core","definition":"محرّك قواعد مفتوح المصدر لإمكانية الوصول من شركة Deque، يعمل داخل الصفحة ويبلّغ عن المخالفات مع الإشارة إلى معايير WCAG. وهو يشغّل axe DevTools وتدقيق إمكانية الوصول في Lighthouse وتكاملات اختبار مثل ‎@axe-core/playwright.","lesson":"l-a11y-5-1"},{"id":"browse-mode","term":"وضع التصفّح (browse mode)","definition":"وضع في NVDA يقرأ فيه مؤشّر افتراضي الصفحة، وتقفز الحروف المفردة بين العناصر، مثل H للعناوين. أما وضع التركيز (focus mode) فيرسل ضغطات المفاتيح إلى العنصر الذي عليه التركيز للكتابة.","lesson":"l-a11y-5-2"}]}