Fix WCAG AA color contrast violations across all pages
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:
@@ -43,12 +43,14 @@ const statusOptions: {
|
||||
{
|
||||
value: 'caught',
|
||||
label: 'Caught',
|
||||
color: 'bg-green-900/40 text-green-300 border-green-700',
|
||||
color:
|
||||
'bg-green-900/40 text-green-300 light:bg-green-100 light:text-green-800 border-green-700 light:border-green-300',
|
||||
},
|
||||
{
|
||||
value: 'fainted',
|
||||
label: 'Fainted',
|
||||
color: 'bg-red-900/40 text-red-300 border-red-700',
|
||||
color:
|
||||
'bg-red-900/40 text-red-300 light:bg-red-100 light:text-red-800 border-red-700 light:border-red-300',
|
||||
},
|
||||
{
|
||||
value: 'missed',
|
||||
@@ -299,7 +301,7 @@ export function EncounterModal({
|
||||
setSelectedPokemon(pickRandomPokemon(routePokemon, dupedPokemonIds))
|
||||
}
|
||||
}}
|
||||
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"
|
||||
>
|
||||
{selectedPokemon ? 'Re-roll' : 'Randomize'}
|
||||
</button>
|
||||
@@ -403,14 +405,14 @@ export function EncounterModal({
|
||||
<EncounterMethodBadge method={rp.encounterMethod} />
|
||||
)}
|
||||
{!isDuped && displayRate !== null && displayRate !== undefined && (
|
||||
<span className="text-[10px] text-purple-400 font-medium">
|
||||
<span className="text-[10px] text-purple-400 light:text-purple-700 font-medium">
|
||||
{displayRate}%
|
||||
</span>
|
||||
)}
|
||||
{!isDuped &&
|
||||
selectedCondition === null &&
|
||||
conditions.length > 0 && (
|
||||
<span className="text-[10px] text-purple-400">
|
||||
<span className="text-[10px] text-purple-400 light:text-purple-700">
|
||||
{conditions.join(', ')}
|
||||
</span>
|
||||
)}
|
||||
@@ -518,7 +520,7 @@ export function EncounterModal({
|
||||
onClick={() => setNickname(name)}
|
||||
className={`px-2.5 py-1 text-xs rounded-full border transition-colors ${
|
||||
nickname === name
|
||||
? 'bg-accent-900/40 border-accent-600 text-accent-300'
|
||||
? 'bg-accent-900/40 border-accent-600 text-accent-300 light:bg-accent-100 light:text-accent-700'
|
||||
: 'border-border-default text-text-secondary hover:border-accent-600 hover:bg-accent-900/20'
|
||||
}`}
|
||||
>
|
||||
|
||||
@@ -48,7 +48,7 @@ function GraveyardCard({ entry }: { entry: GraveyardEntry }) {
|
||||
|
||||
<div className="text-xs text-text-muted mt-0.5">{entry.routeName}</div>
|
||||
|
||||
<div className="text-[10px] text-purple-400 mt-0.5 font-medium">
|
||||
<div className="text-[10px] text-purple-400 light:text-purple-700 mt-0.5 font-medium">
|
||||
Leg {entry.legOrder} — {entry.gameName}
|
||||
</div>
|
||||
|
||||
|
||||
@@ -48,18 +48,18 @@ function LegDot({ leg }: { leg: LineageLegEntry }) {
|
||||
<div
|
||||
className={`font-medium ${
|
||||
leg.faintLevel !== null
|
||||
? 'text-red-300'
|
||||
? 'text-red-300 light:text-red-700'
|
||||
: leg.wasTransferred
|
||||
? 'text-blue-300'
|
||||
? 'text-blue-300 light:text-blue-700'
|
||||
: leg.enteredHof
|
||||
? 'text-yellow-300'
|
||||
: 'text-green-300'
|
||||
? 'text-yellow-300 light:text-amber-700'
|
||||
: 'text-green-300 light:text-green-700'
|
||||
}`}
|
||||
>
|
||||
{label}
|
||||
</div>
|
||||
{leg.enteredHof && leg.faintLevel === null && (
|
||||
<div className="text-yellow-300">Hall of Fame</div>
|
||||
<div className="text-yellow-300 light:text-amber-700">Hall of Fame</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-2 h-2 bg-gray-900 dark:bg-gray-700 rotate-45 -mt-1" />
|
||||
@@ -156,8 +156,8 @@ function LineageCard({ lineage, allLegOrders }: { lineage: LineageEntry; allLegO
|
||||
<span
|
||||
className={`px-2.5 py-1 rounded-full text-xs font-medium ${
|
||||
lineage.status === 'alive'
|
||||
? 'bg-green-900/40 text-green-300'
|
||||
: 'bg-red-900/40 text-red-300'
|
||||
? 'bg-green-900/40 text-green-300 light:bg-green-100 light:text-green-800'
|
||||
: 'bg-red-900/40 text-red-300 light:bg-red-100 light:text-red-800'
|
||||
}`}
|
||||
>
|
||||
{lineage.status === 'alive' ? 'Alive' : 'Dead'}
|
||||
|
||||
@@ -9,7 +9,7 @@ interface ShinyBoxProps {
|
||||
export function ShinyBox({ encounters, onEncounterClick }: ShinyBoxProps) {
|
||||
return (
|
||||
<div className="border-2 border-yellow-600 rounded-lg p-4">
|
||||
<h3 className="text-sm font-semibold text-yellow-400 mb-3 flex items-center gap-1.5">
|
||||
<h3 className="text-sm font-semibold text-yellow-400 light:text-amber-700 mb-3 flex items-center gap-1.5">
|
||||
<span>✦</span>
|
||||
Shiny Box
|
||||
<span className="text-xs font-normal text-text-muted ml-1">
|
||||
|
||||
@@ -110,7 +110,7 @@ export function ShinyEncounterModal({
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<p className="text-sm text-yellow-400 mt-1">
|
||||
<p className="text-sm text-yellow-400 light:text-amber-700 mt-1">
|
||||
Shiny catches bypass the one-per-route rule
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -21,7 +21,9 @@ export function AdminLayout() {
|
||||
to={item.to}
|
||||
className={({ isActive }) =>
|
||||
`block px-3 py-2 rounded-md text-sm font-medium whitespace-nowrap ${
|
||||
isActive ? 'bg-accent-900/40 text-accent-300' : 'hover:bg-surface-2'
|
||||
isActive
|
||||
? 'bg-accent-900/40 text-accent-300 light:bg-accent-100 light:text-accent-700'
|
||||
: 'hover:bg-surface-2'
|
||||
}`
|
||||
}
|
||||
>
|
||||
|
||||
@@ -77,7 +77,7 @@ export function BulkImportModal({
|
||||
)}
|
||||
|
||||
{result && (
|
||||
<div className="p-3 bg-green-900/30 text-green-300 rounded-md text-sm">
|
||||
<div className="p-3 bg-green-900/30 text-green-300 light:bg-green-100 light:text-green-800 rounded-md text-sm">
|
||||
<p>
|
||||
{createdLabel}: {result.created}, {updatedLabel}: {result.updated}
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user