a11y: WCAG AA contrast + ARIA roles + focus management across all pages
- css/ls.css: --text-3 #8898AA → #56687A (5.1:1 contrast), min-height 44px on .btn-primary/.btn-ghost/.sb-link, new .icon-btn utility (44×44px) - js/api.js: lsConfirm — role=dialog, aria-modal, aria-labelledby, Tab focus trap, restore focus on close; lsToast — aria-live=polite on container, role=alert on errors; live quiz — role=dialog, role=radiogroup, role=radio, aria-checked, keyboard support - test-run.html: q-opt divs — role=radio/checkbox, aria-checked, tabindex, keyboard enter/space; confirm modal — role=dialog, aria-modal; btn-flag — aria-pressed; dots — aria-label, aria-current; touch targets 44px - board.html: btn-del-ann — aria-label; reaction buttons — aria-label, aria-pressed - All 18 HTML files: replace hardcoded color:#8898AA with color:var(--text-3) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+5
-3
@@ -714,7 +714,8 @@
|
||||
/* ════════════════════════════════════════
|
||||
ANNOUNCEMENT CARD
|
||||
════════════════════════════════════════ */
|
||||
const EMOJIS = ['<svg class="ic" viewBox="0 0 24 24"><path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>', '<svg class="ic" viewBox="0 0 24 24"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>️', '<svg class="ic" viewBox="0 0 24 24"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 3z"/></svg>'];
|
||||
const EMOJIS = ['<svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M7 10v12"/><path d="M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z"/></svg>', '<svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/></svg>️', '<svg class="ic" viewBox="0 0 24 24" aria-hidden="true"><path d="M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 3z"/></svg>'];
|
||||
const REACTION_LABELS = ['Нравится', 'Обожаю', 'Огонь'];
|
||||
|
||||
function renderAnnouncement(a, delay, fresh) {
|
||||
const key = `ann_${a.id}`;
|
||||
@@ -725,11 +726,12 @@
|
||||
|
||||
const rxHtml = EMOJIS.map((em, idx) => {
|
||||
const count = rxState[idx] ? 1 : 0;
|
||||
return `<button class="reaction-btn ${rxState[idx] ? 'active' : ''}" onclick="toggleReaction(${a.id},${idx},this)">${em}${count ? ` ${count}` : ''}</button>`;
|
||||
const lbl = rxState[idx] ? `Убрать «${REACTION_LABELS[idx]}»` : `${REACTION_LABELS[idx]}`;
|
||||
return `<button class="reaction-btn ${rxState[idx] ? 'active' : ''}" onclick="toggleReaction(${a.id},${idx},this)" aria-label="${lbl}" aria-pressed="${rxState[idx] ? 'true' : 'false'}">${em}${count ? ` <span aria-hidden="true">${count}</span>` : ''}</button>`;
|
||||
}).join('');
|
||||
|
||||
const delBtn = isTeacher
|
||||
? `<button class="btn-del-ann" onclick="deleteAnnouncement(${a.id})" title="Удалить"><i data-lucide="x" style="width:13px;height:13px"></i></button>` : '';
|
||||
? `<button class="btn-del-ann" onclick="deleteAnnouncement(${a.id})" aria-label="Удалить объявление"><i data-lucide="x" style="width:13px;height:13px" aria-hidden="true"></i></button>` : '';
|
||||
|
||||
return `<div class="card card-announcement" style="${delay}">
|
||||
<div class="card-strip"></div>
|
||||
|
||||
Reference in New Issue
Block a user