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
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:
@@ -9,6 +9,7 @@ import styles from './ComparisonToast.module.css';
|
||||
export function ComparisonToast() {
|
||||
const { selectedSchools, clearAll, removeSchool } = useComparison();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [collapsed, setCollapsed] = useState(false);
|
||||
const pathname = usePathname();
|
||||
|
||||
useEffect(() => {
|
||||
@@ -24,31 +25,48 @@ export function ComparisonToast() {
|
||||
|
||||
return (
|
||||
<div className={styles.toastContainer}>
|
||||
<div className={styles.toastContent}>
|
||||
<div className={`${styles.toastContent} ${collapsed ? styles.toastCollapsed : ''}`}>
|
||||
<div className={styles.toastHeader}>
|
||||
<span className={styles.toastTitle}>
|
||||
<span className={styles.toastBadge}>{selectedSchools.length}</span>
|
||||
{selectedSchools.length === 1 ? 'school' : 'schools'} selected
|
||||
</span>
|
||||
<button
|
||||
onClick={() => setCollapsed(!collapsed)}
|
||||
className={styles.collapseBtn}
|
||||
aria-label={collapsed ? 'Expand comparison panel' : 'Minimize comparison panel'}
|
||||
>
|
||||
<svg viewBox="0 0 16 16" fill="none" width="14" height="14">
|
||||
{collapsed ? (
|
||||
<path d="M4 10L8 6L12 10" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||
) : (
|
||||
<path d="M4 6L8 10L12 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" />
|
||||
)}
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div className={styles.schoolList}>
|
||||
{selectedSchools.map(school => (
|
||||
<div key={school.urn} className={styles.schoolItem}>
|
||||
<span className={styles.schoolName} title={school.school_name}>
|
||||
{school.school_name.length > 28 ? school.school_name.slice(0, 28) + '…' : school.school_name}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => removeSchool(school.urn)}
|
||||
className={styles.removeSchoolBtn}
|
||||
aria-label={`Remove ${school.school_name}`}
|
||||
>×</button>
|
||||
{!collapsed && (
|
||||
<>
|
||||
<div className={styles.schoolList}>
|
||||
{selectedSchools.map(school => (
|
||||
<div key={school.urn} className={styles.schoolItem}>
|
||||
<span className={styles.schoolName} title={school.school_name}>
|
||||
{school.school_name.length > 28 ? school.school_name.slice(0, 28) + '…' : school.school_name}
|
||||
</span>
|
||||
<button
|
||||
onClick={() => removeSchool(school.urn)}
|
||||
className={styles.removeSchoolBtn}
|
||||
aria-label={`Remove ${school.school_name}`}
|
||||
>×</button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className={styles.toastActions}>
|
||||
<button onClick={clearAll} className={styles.btnClear}>Clear all</button>
|
||||
<Link href="/compare" className={styles.btnCompare}>Compare Now</Link>
|
||||
</div>
|
||||
<div className={styles.toastActions}>
|
||||
<button onClick={clearAll} className="btn btn-tertiary btn-sm" style={{ color: 'rgba(250,247,242,0.7)', borderColor: 'rgba(255,255,255,0.15)' }}>Clear all</button>
|
||||
<Link href="/compare" className={styles.btnCompare}>Compare Now</Link>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user