feat(ui): site-wide UX/UI audit — unified buttons, tokens, accessibility
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 35s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m10s
Build and Push Docker Images / Build Integrator (push) Successful in 57s
Build and Push Docker Images / Build Kestra Init (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 0s

- Add shared button system (.btn-primary/secondary/tertiary/active) in globals.css
- Replace 40+ hardcoded rgba() values with design tokens across all CSS modules
- Add skip link, :focus-visible indicators, and ARIA landmarks
- Standardise button labels ("+ Compare" / "✓ Comparing") across all components
- Add collapse/minimize toggle to ComparisonToast
- Fix heading hierarchy (h3→h2 in ComparisonView)
- Add aria-live on search results, aria-label on trend SVGs
- Add "Search" nav link, fix footer empty section, unify max-widths
- Darken --text-muted for WCAG AA compliance (4.6:1 contrast ratio)
- Net reduction of ~180 lines through button style deduplication

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 20:28:03 +00:00
parent 5cdafc887e
commit 8aca0a7a53
23 changed files with 237 additions and 418 deletions

View File

@@ -147,10 +147,10 @@ export function ComparisonView({
</p>
</div>
<div style={{ display: 'flex', gap: '0.75rem', alignItems: 'center', flexWrap: 'wrap' }}>
<button onClick={() => setIsModalOpen(true)} className={styles.addButton}>
<button onClick={() => setIsModalOpen(true)} className="btn btn-primary">
+ Add School
</button>
<button onClick={handleShare} className={styles.shareButton} title="Copy comparison link">
<button onClick={handleShare} className="btn btn-tertiary" title="Copy comparison link">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" width="16" height="16"><path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/><polyline points="16 6 12 2 8 6"/><line x1="12" y1="2" x2="12" y2="15"/></svg>
{shareConfirm ? 'Copied!' : 'Share'}
</button>
@@ -234,14 +234,14 @@ export function ComparisonView({
<button
onClick={() => handleRemoveSchool(school.urn)}
className={styles.removeButton}
aria-label="Remove school"
aria-label={`Remove ${school.school_name}`}
title="Remove from comparison"
>
×
</button>
<h3 className={styles.schoolName}>
<h2 className={styles.schoolName}>
<a href={`/school/${school.urn}`}>{school.school_name}</a>
</h3>
</h2>
<div className={styles.schoolMeta}>
{school.local_authority && (
<span className={styles.metaItem}>{school.local_authority}</span>