fix: accessibility, theming, and focus-visibility improvements
Addresses critical and high-severity findings from UI audit: - C1: Define missing CSS tokens (--hover, --bg-primary/secondary/tertiary) fixing broken hover states and Slides Builder backgrounds - C2: Chart colors now read CSS custom properties at render-time via getChartTheme(), adapting tooltip, ticks, and grid to dark mode - C3: Multi-select ARIA fixed — label elements now carry role="option" and aria-selected for valid listbox semantics - H1/M1: Remove unused --gold and duplicate --primary tokens; replace all var(--primary) with var(--accent) throughout App.css - H3/H4: Focus-visible outlines added to all custom interactive elements (chips, controls, year buttons, hero button, multi-select trigger) - H5: access-badge--full hardcoded colors replaced with design tokens - H7: aria-pressed added to all chart toggle buttons - L1: Hardcoded #fff/white replaced with var(--text-inverse) - M4: index.html now preloads DM Serif Display, Outfit, and IBM Plex Sans Arabic — all fonts actually used in the app Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -303,7 +303,7 @@ function AltMultiSelect({ value, options, onChange, allLabel, countLabel, clearL
|
||||
<div className="altms-dropdown" role="listbox" aria-multiselectable="true">
|
||||
<div className="altms-list">
|
||||
{options.map(opt => (
|
||||
<label key={opt} className={`altms-option${value.includes(opt)?' altms-option--checked':''}`}>
|
||||
<label key={opt} role="option" aria-selected={value.includes(opt)} className={`altms-option${value.includes(opt)?' altms-option--checked':''}`}>
|
||||
<input type="checkbox" className="altms-check" checked={value.includes(opt)} onChange={() => toggle(opt)} aria-label={opt} />
|
||||
<span className="altms-check-box">{value.includes(opt) && <svg width="10" height="8" viewBox="0 0 10 8" fill="none"><path d="M1 4L3.5 6.5L9 1" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"/></svg>}</span>
|
||||
<span className="altms-opt-label">{opt}</span>
|
||||
@@ -611,6 +611,15 @@ export default function PeriodSelectorDemo({ data, seasons, includeVAT, allowedM
|
||||
.alt-page-title { font-size:1.75rem; }
|
||||
.alt-chart-header { flex-direction:column; }
|
||||
}
|
||||
|
||||
/* ── focus-visible ── */
|
||||
.alt-chip:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.alt-ctrl:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.alt-yr-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.dalt-hero-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.altms-trigger:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.altms-clear:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
.alt-cancel:focus-visible, .alt-apply:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
||||
`}</style>
|
||||
|
||||
<Link to={L.backTo} className="alt-back">
|
||||
@@ -659,9 +668,9 @@ export default function PeriodSelectorDemo({ data, seasons, includeVAT, allowedM
|
||||
<div className="alt-chart-header">
|
||||
<h3 className="alt-chart-title">{L.trendTitle}</h3>
|
||||
<div className="alt-chart-controls">
|
||||
{metricOpts.map(o => <button key={o.value} type="button" className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
|
||||
{metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
|
||||
<div className="alt-ctrl-sep" />
|
||||
{granOpts.map(o => <button key={o.value} type="button" className={`alt-ctrl${gran===o.value?' alt-ctrl-on':''}`} onClick={() => setGran(o.value)}>{o.label}</button>)}
|
||||
{granOpts.map(o => <button key={o.value} type="button" aria-pressed={gran===o.value} className={`alt-ctrl${gran===o.value?' alt-ctrl-on':''}`} onClick={() => setGran(o.value)}>{o.label}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="alt-chart-wrap"><Line data={trendData} options={chartOpts} /></div>
|
||||
@@ -670,7 +679,7 @@ export default function PeriodSelectorDemo({ data, seasons, includeVAT, allowedM
|
||||
<div className="alt-chart-header">
|
||||
<h3 className="alt-chart-title">{L.museumTitle}</h3>
|
||||
<div className="alt-chart-controls">
|
||||
{metricOpts.map(o => <button key={o.value} type="button" className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
|
||||
{metricOpts.map(o => <button key={o.value} type="button" aria-pressed={metric===o.value} className={`alt-ctrl${metric===o.value?' alt-ctrl-on':''}`} onClick={() => setMetric(o.value)}>{o.label}</button>)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="alt-chart-wrap"><Bar data={museumData} options={chartOpts} /></div>
|
||||
|
||||
Reference in New Issue
Block a user