fix(ux-audit): CRITICAL + HIGH fixes — a11y, reduced-motion, forms, keyboard nav
Global (globals.css): - prefers-reduced-motion: désactive toutes les animations/transitions - focus-visible:ring global sur tous les éléments interactifs Search modal: - role="dialog" + aria-modal="true" + aria-label - onClick backdrop ferme la modale Insights peek: - DOMPurify.sanitize() sur dangerouslySetInnerHTML (XSS fix) Login form: - autoComplete="email" / "current-password" - htmlFor sur tous les labels Register form: - autoComplete="name" / "email" / "new-password" - htmlFor sur tous les labels GridCard (notes-list-views): - Actions visibles sur mobile (opacity-100 sm:opacity-0) - aria-sort sur colonne triable - role="button" + tabIndex + onKeyDown sur lignes table Editorial view: - role="button" + tabIndex + onKeyDown sur articles - Menu trigger aria-label + visible mobile Toolbar: - aria-label voice i18n
This commit is contained in:
@@ -28,6 +28,7 @@ import Link from 'next/link'
|
||||
import { getNoteById } from '@/app/actions/notes'
|
||||
import type { Note as NoteFull } from '@/lib/types'
|
||||
import { X, Maximize2 } from 'lucide-react'
|
||||
import DOMPurify from 'dompurify'
|
||||
|
||||
const NetworkGraph = dynamic(
|
||||
() => import('@/components/network-graph').then(m => ({ default: m.NetworkGraph })),
|
||||
@@ -934,7 +935,7 @@ export default function InsightsPage() {
|
||||
<div
|
||||
dir="auto"
|
||||
className="prose prose-sm dark:prose-invert max-w-none text-ink dark:text-dark-ink [&_a]:text-blue-600 [&_blockquote]:border-l-blue-400"
|
||||
dangerouslySetInnerHTML={{ __html: peekNote.content }}
|
||||
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(peekNote.content) }}
|
||||
/>
|
||||
) : (
|
||||
<p className="text-sm text-concrete italic">—</p>
|
||||
|
||||
@@ -6,6 +6,25 @@
|
||||
|
||||
@custom-variant dark (&:is(.dark *));
|
||||
|
||||
/* ── Global UX fixes (UI/UX Pro Max audit) ────────────────────────────── */
|
||||
|
||||
/* CRITICAL: prefers-reduced-motion — désactive toutes les animations */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
*, *::before, *::after {
|
||||
animation-duration: 0.01ms !important;
|
||||
animation-iteration-count: 1 !important;
|
||||
transition-duration: 0.01ms !important;
|
||||
scroll-behavior: auto !important;
|
||||
}
|
||||
}
|
||||
|
||||
/* CRITICAL: focus-visible ring global sur tous les éléments interactifs */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-brand-accent);
|
||||
outline-offset: 2px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/* Custom breakpoints for desktop design (matching code.html reference) */
|
||||
@theme {
|
||||
/* Desktop breakpoints: 1024px (min), 1440px (large), 1920px (ultra-wide) */
|
||||
|
||||
Reference in New Issue
Block a user