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:
Maxim Dolgolyov
2026-04-16 11:42:38 +03:00
parent 3a4623a60a
commit 26ba289019
22 changed files with 362 additions and 299 deletions
+5 -5
View File
@@ -204,7 +204,7 @@
.km-qtest-close {
width: 32px; height: 32px; border-radius: 9px; border: 1.5px solid #E8EBF0;
background: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center;
color: #8898AA; transition: all .15s;
color: var(--text-3); transition: all .15s;
}
.km-qtest-close:hover { border-color: #ef4444; color: #ef4444; }
.km-qtest-close svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; }
@@ -214,7 +214,7 @@
}
.km-qtest-pbar { flex: 1; height: 4px; border-radius: 99px; background: #E8EBF0; overflow: hidden; }
.km-qtest-pfill { height: 100%; border-radius: 99px; background: linear-gradient(90deg, #9B5DE5, #06D6E0); transition: width .3s; }
.km-qtest-ptext { font-size: 0.72rem; font-weight: 700; color: #8898AA; min-width: 36px; text-align: right; }
.km-qtest-ptext { font-size: 0.72rem; font-weight: 700; color: var(--text-3); min-width: 36px; text-align: right; }
.km-qtest-q {
font-size: 0.95rem; font-weight: 600; color: #0F172A; line-height: 1.6;
margin-bottom: 16px;
@@ -249,7 +249,7 @@
font-family: 'Unbounded', sans-serif; font-size: 2rem; font-weight: 800;
margin-bottom: 6px;
}
.km-qtest-result-label { font-size: 0.88rem; color: #8898AA; margin-bottom: 20px; }
.km-qtest-result-label { font-size: 0.88rem; color: var(--text-3); margin-bottom: 20px; }
.km-qtest-result-btn {
padding: 12px 28px; border-radius: 99px; border: none;
background: linear-gradient(135deg, #9B5DE5, #7C3AED);
@@ -1681,7 +1681,7 @@ async function startQuickTest(node) {
const topicId = node.id.replace('topic_', '');
document.getElementById('qtest-title').textContent = 'Тест: ' + node.label;
document.getElementById('qtest-body').innerHTML =
'<div style="text-align:center;padding:40px;color:#8898AA"><div class="km-spinner" style="margin:0 auto 12px;width:24px;height:24px;border-width:3px"></div>Загрузка вопросов...</div>';
'<div style="text-align:center;padding:40px;color:var(--text-3)"><div class="km-spinner" style="margin:0 auto 12px;width:24px;height:24px;border-width:3px"></div>Загрузка вопросов...</div>';
document.getElementById('km-qtest').classList.add('open');
try {
@@ -1696,7 +1696,7 @@ async function startQuickTest(node) {
};
if (!_qt.questions.length) {
document.getElementById('qtest-body').innerHTML =
'<div style="text-align:center;padding:40px;color:#8898AA">Нет вопросов по этой теме</div>';
'<div style="text-align:center;padding:40px;color:var(--text-3)">Нет вопросов по этой теме</div>';
return;
}
renderQuestion();