Fix WCAG AA color contrast violations across all pages
All checks were successful
CI / backend-lint (push) Successful in 9s
CI / actions-lint (push) Successful in 15s
CI / frontend-lint (push) Successful in 21s

Replace incorrect perceived-brightness formula in Stats progress bars
with proper WCAG relative luminance calculation, and convert type bar
colors to hex values for reliable contrast detection. Add light: variant
classes to status badges, yellow/purple text, and admin nav links across
17 files. Darken light-mode status-active token and text-tertiary/muted
tokens. Add aria-labels to admin filter selects and flex-wrap for mobile
overflow on AdminEvolutions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-20 20:48:16 +01:00
parent a12478f24b
commit 4fbfcf9b29
18 changed files with 109 additions and 80 deletions

View File

@@ -59,9 +59,9 @@ function sortEncounters(encounters: EncounterDetail[], key: TeamSortKey): Encoun
}
const statusStyles: Record<RunStatus, string> = {
active: 'bg-green-900/40 text-green-300',
completed: 'bg-blue-900/40 text-blue-300',
failed: 'bg-red-900/40 text-red-300',
active: 'bg-green-900/40 text-green-300 light:bg-green-100 light:text-green-800',
completed: 'bg-blue-900/40 text-blue-300 light:bg-blue-100 light:text-blue-800',
failed: 'bg-red-900/40 text-red-300 light:bg-red-100 light:text-red-800',
}
function formatDuration(start: string, end: string) {
@@ -801,7 +801,7 @@ export function RunEncounters() {
})}
</p>
{run.genlocke && (
<p className="text-sm text-purple-400 mt-1 font-medium">
<p className="text-sm text-purple-400 light:text-purple-700 mt-1 font-medium">
Leg {run.genlocke.legOrder} of {run.genlocke.totalLegs} &mdash;{' '}
{run.genlocke.genlockeName}
</p>
@@ -811,7 +811,7 @@ export function RunEncounters() {
{isActive && run.rules?.shinyClause && (
<button
onClick={() => setShowShinyModal(true)}
className="px-3 py-1 text-sm border border-yellow-600 text-yellow-400 rounded-full font-medium hover:bg-yellow-900/20 transition-colors"
className="px-3 py-1 text-sm border border-yellow-600 text-yellow-400 light:text-amber-700 light:border-amber-600 rounded-full font-medium hover:bg-yellow-900/20 light:hover:bg-amber-50 transition-colors"
>
&#10022; Log Shiny
</button>
@@ -1153,7 +1153,7 @@ export function RunEncounters() {
bulkRandomize.mutate()
}
}}
className="px-2.5 py-1 text-xs font-medium rounded-lg border border-purple-600 text-purple-400 hover:bg-purple-900/20 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
className="px-2.5 py-1 text-xs font-medium rounded-lg border border-purple-600 text-purple-400 light:text-purple-700 light:border-purple-500 hover:bg-purple-900/20 light:hover:bg-purple-50 disabled:opacity-40 disabled:cursor-not-allowed transition-colors"
>
{bulkRandomize.isPending ? 'Randomizing...' : 'Randomize All'}
</button>
@@ -1358,7 +1358,7 @@ export function RunEncounters() {
</div>
<div onClick={(e) => e.stopPropagation()}>
{isDefeated ? (
<span className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-full bg-green-900/40 text-green-300">
<span className="inline-flex items-center gap-1 px-2 py-1 text-xs font-medium rounded-full bg-green-900/40 text-green-300 light:bg-green-100 light:text-green-800">
Defeated &#10003;
</span>
) : isActive ? (