mirror of
https://github.com/kuhyx/testsAndMisc-archive.git
synced 2026-11-10 19:27:05 +01:00
bucket_catch: introduce a real design-token system, fix reversed gradients
Fixes every violation in DESIGN_AUDIT_TODO.md's bucket_catch frontend section. The app previously had no shared tokens at all (index.css was a 12-line reset) and 19 hardcoded hex colors duplicated independently across 6 *.module.css files. New :root token block in index.css: bg gradient stops, a drag-state gradient, the indigo/pink accent pair collapsed to one canonical --gradient-accent direction, text/surface colors, success/error, 2 consolidated muted-gray roles (down from 4 unrelated shades), a 4px spacing scale, and a radius scale. All 6 component files migrated onto it. Fixes the real reversed-gradient-stop bug the audit named (PuzzleResult.module.css .grade was pink->indigo vs every other heading's indigo->pink) plus a second instance of the same bug the audit's prose didn't cite by line number (ModeSelect.module.css .puzzleStart button) -- both now reference --gradient-accent so this class of bug can't recur. Also fixes: .preset's border contrast (was under 3:1), cardDesc's sub-16px font-size, 4 buttons' off-ratio padding (now exact 2x), 2 large icons' full-contrast rendering next to muted text (now dimmed), the explicitly-cited off-grid spacing values, and ModeSelect's gridInput background color which had drifted from its DropZone sibling's. Verified: 145/145 tests at 100% coverage (CSS-only, confirms no functional regression), a real vite build succeeds, re-verified identical in an isolated worktree at HEAD, and pixel-checked the production build via a headless-Chrome screenshot (gradient direction now matches between heading and button; preset chip borders clearly visible). `npm run lint` (tsc -b + eslint) was already broken on a clean checkout before this change (1 pre-existing tsc error in vite.config.ts, 46 pre-existing eslint errors in untouched test/lib files) -- confirmed via an isolated worktree at the parent commit, left alone as out of scope. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
parent
e6a9d5e66a
commit
06cc07b2c2
@ -3,37 +3,39 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 100dvh;
|
||||
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
|
||||
background: var(--bg-gradient);
|
||||
transition: background 0.2s;
|
||||
overflow-y: auto;
|
||||
padding: 24px 16px;
|
||||
padding: var(--space-4) var(--space-3);
|
||||
}
|
||||
|
||||
.zone.dragging {
|
||||
background: linear-gradient(135deg, #1a1560, #4a3f9e, #3a3868);
|
||||
outline: 4px dashed #818cf8;
|
||||
background: var(--bg-drag-gradient);
|
||||
outline: 4px dashed var(--color-indigo);
|
||||
outline-offset: -12px;
|
||||
}
|
||||
|
||||
.inner {
|
||||
text-align: center;
|
||||
color: #e0e7ff;
|
||||
color: var(--color-text);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 52px;
|
||||
line-height: 1;
|
||||
/* Dimmed relative to the .subtitle text below it (rule 28). */
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin: 0;
|
||||
background: linear-gradient(90deg, #818cf8, #f472b6);
|
||||
background: var(--gradient-accent);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@ -41,24 +43,24 @@
|
||||
|
||||
.subtitle {
|
||||
font-size: 1rem;
|
||||
color: #94a3b8;
|
||||
color: var(--muted-text);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.count {
|
||||
font-size: 1rem;
|
||||
color: #a5b4fc;
|
||||
color: var(--color-indigo-light);
|
||||
font-weight: 600;
|
||||
background: rgba(129, 140, 248, 0.15);
|
||||
padding: 4px 16px;
|
||||
border-radius: 999px;
|
||||
background: rgba(var(--color-indigo-rgb), 0.15);
|
||||
padding: var(--space-1) var(--space-3);
|
||||
border-radius: var(--radius-pill);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.browseBtn {
|
||||
padding: 8px 24px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #818cf8, #f472b6);
|
||||
padding: 12px var(--space-4);
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--gradient-accent);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
@ -72,7 +74,7 @@
|
||||
}
|
||||
|
||||
.divider {
|
||||
color: #4b5563;
|
||||
color: var(--muted-border);
|
||||
font-size: 0.8rem;
|
||||
letter-spacing: 0.1em;
|
||||
text-transform: uppercase;
|
||||
@ -96,15 +98,17 @@
|
||||
|
||||
.gridLabel {
|
||||
font-size: 0.85rem;
|
||||
color: #94a3b8;
|
||||
color: var(--muted-text);
|
||||
}
|
||||
|
||||
.preset {
|
||||
padding: 3px 10px;
|
||||
border-radius: 6px;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border-radius: var(--radius-sm);
|
||||
background: transparent;
|
||||
border: 1.5px solid #4b5563;
|
||||
color: #94a3b8;
|
||||
/* muted-text, not muted-border — the border-only value measured under
|
||||
3:1 against the page background (rule 7). */
|
||||
border: 1.5px solid var(--muted-text);
|
||||
color: var(--muted-text);
|
||||
font-size: 0.8rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
@ -112,23 +116,23 @@
|
||||
}
|
||||
|
||||
.preset:hover {
|
||||
border-color: #818cf8;
|
||||
color: #c7d2fe;
|
||||
border-color: var(--color-indigo);
|
||||
color: var(--color-indigo-lighter);
|
||||
}
|
||||
|
||||
.presetActive {
|
||||
border-color: #f472b6;
|
||||
color: #f9a8d4;
|
||||
background: rgba(244, 114, 182, 0.1);
|
||||
border-color: var(--color-pink);
|
||||
color: var(--color-pink-light);
|
||||
background: rgba(var(--color-pink-rgb), 0.1);
|
||||
}
|
||||
|
||||
.gridInput {
|
||||
width: 56px;
|
||||
padding: 3px 6px;
|
||||
border-radius: 6px;
|
||||
background: rgba(30, 27, 75, 0.8);
|
||||
border: 1.5px solid #4b5563;
|
||||
color: #e0e7ff;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border-radius: var(--radius-sm);
|
||||
background: var(--surface);
|
||||
border: 1.5px solid var(--muted-border);
|
||||
color: var(--color-text);
|
||||
font-size: 0.85rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
@ -137,21 +141,21 @@
|
||||
}
|
||||
|
||||
.gridInput:focus {
|
||||
border-color: #818cf8;
|
||||
border-color: var(--color-indigo);
|
||||
}
|
||||
|
||||
.gridEq {
|
||||
font-size: 0.8rem;
|
||||
color: #6b7280;
|
||||
color: var(--muted-faint);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.puzzleBtn {
|
||||
padding: 8px 24px;
|
||||
border-radius: 999px;
|
||||
padding: 12px var(--space-4);
|
||||
border-radius: var(--radius-pill);
|
||||
background: transparent;
|
||||
border: 2px solid #f472b6;
|
||||
color: #f9a8d4;
|
||||
border: 2px solid var(--color-pink);
|
||||
color: var(--color-pink-light);
|
||||
font-weight: 700;
|
||||
font-size: 0.95rem;
|
||||
cursor: pointer;
|
||||
@ -159,7 +163,7 @@
|
||||
}
|
||||
|
||||
.puzzleBtn:hover {
|
||||
background: rgba(244, 114, 182, 0.12);
|
||||
border-color: #e879f9;
|
||||
color: #e879f9;
|
||||
background: rgba(var(--color-pink-rgb), 0.12);
|
||||
border-color: var(--color-pink-lighter);
|
||||
color: var(--color-pink-lighter);
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
top: 16px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: rgba(224, 231, 255, 0.5);
|
||||
color: rgba(var(--color-text-rgb), 0.5);
|
||||
font-size: 0.85rem;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
|
||||
@ -4,16 +4,16 @@
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 24px;
|
||||
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
|
||||
color: #e0e7ff;
|
||||
gap: var(--space-4);
|
||||
background: var(--bg-gradient);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.heading {
|
||||
font-size: 2rem;
|
||||
font-weight: 800;
|
||||
margin: 0;
|
||||
background: linear-gradient(90deg, #818cf8, #f472b6);
|
||||
background: var(--gradient-accent);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@ -21,22 +21,22 @@
|
||||
|
||||
.sub {
|
||||
font-size: 1.1rem;
|
||||
color: #94a3b8;
|
||||
color: var(--muted-text);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.cards {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
gap: var(--space-4);
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.card {
|
||||
background: rgba(30, 27, 75, 0.7);
|
||||
border: 2px solid #818cf8;
|
||||
border-radius: 16px;
|
||||
padding: 32px 40px;
|
||||
background: var(--surface);
|
||||
border: 2px solid var(--color-indigo);
|
||||
border-radius: var(--radius-lg);
|
||||
padding: var(--space-5) var(--space-6);
|
||||
width: 220px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -44,16 +44,18 @@
|
||||
gap: 12px;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.15s, transform 0.15s;
|
||||
color: #e0e7ff;
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
border-color: #f472b6;
|
||||
border-color: var(--color-pink);
|
||||
transform: translateY(-4px);
|
||||
}
|
||||
|
||||
.cardIcon {
|
||||
font-size: 48px;
|
||||
/* Dimmed relative to .cardDesc below it (rule 28). */
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.cardTitle {
|
||||
@ -62,8 +64,9 @@
|
||||
}
|
||||
|
||||
.cardDesc {
|
||||
font-size: 0.85rem;
|
||||
color: #94a3b8;
|
||||
/* Was 0.85rem (13.6px), under the 16px reading floor (rule 20). */
|
||||
font-size: 1rem;
|
||||
color: var(--muted-text);
|
||||
text-align: center;
|
||||
line-height: 1.4;
|
||||
}
|
||||
@ -71,11 +74,11 @@
|
||||
.cardDisabled {
|
||||
opacity: 0.4;
|
||||
cursor: not-allowed;
|
||||
border-color: #4b5563;
|
||||
border-color: var(--muted-border);
|
||||
}
|
||||
|
||||
.cardDisabled:hover {
|
||||
border-color: #4b5563;
|
||||
border-color: var(--muted-border);
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@ -86,18 +89,19 @@
|
||||
.gridRow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
gap: var(--space-1);
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.preset {
|
||||
padding: 3px 9px;
|
||||
border-radius: 6px;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border-radius: var(--radius-sm);
|
||||
background: transparent;
|
||||
border: 1.5px solid #4b5563;
|
||||
color: #94a3b8;
|
||||
/* muted-text, not muted-border — same rule 7 contrast fix as DropZone. */
|
||||
border: 1.5px solid var(--muted-text);
|
||||
color: var(--muted-text);
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
@ -105,23 +109,28 @@
|
||||
}
|
||||
|
||||
.preset:hover {
|
||||
border-color: #818cf8;
|
||||
color: #c7d2fe;
|
||||
border-color: var(--color-indigo);
|
||||
color: var(--color-indigo-lighter);
|
||||
}
|
||||
|
||||
.presetActive {
|
||||
border-color: #f472b6;
|
||||
color: #f9a8d4;
|
||||
background: rgba(244, 114, 182, 0.12);
|
||||
border-color: var(--color-pink);
|
||||
color: var(--color-pink-light);
|
||||
/* 0.1, not 0.12 — matches DropZone's identical "active preset chip"
|
||||
role; the two files had drifted to different alpha values. */
|
||||
background: rgba(var(--color-pink-rgb), 0.1);
|
||||
}
|
||||
|
||||
.gridInput {
|
||||
width: 52px;
|
||||
padding: 3px 5px;
|
||||
border-radius: 6px;
|
||||
background: rgba(15, 12, 41, 0.8);
|
||||
border: 1.5px solid #4b5563;
|
||||
color: #e0e7ff;
|
||||
padding: var(--space-1) var(--space-2);
|
||||
border-radius: var(--radius-sm);
|
||||
/* --surface, not a raw rgba(15,12,41,...) literal — DropZone's sibling
|
||||
gridInput already used the surface color; this one had drifted to a
|
||||
different base (bg-1) for the identical component. */
|
||||
background: var(--surface);
|
||||
border: 1.5px solid var(--muted-border);
|
||||
color: var(--color-text);
|
||||
font-size: 0.82rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
@ -130,20 +139,24 @@
|
||||
}
|
||||
|
||||
.gridInput:focus {
|
||||
border-color: #818cf8;
|
||||
border-color: var(--color-indigo);
|
||||
}
|
||||
|
||||
.gridEq {
|
||||
font-size: 0.78rem;
|
||||
color: #6b7280;
|
||||
color: var(--muted-faint);
|
||||
margin: 2px 0 0;
|
||||
}
|
||||
|
||||
.puzzleStart {
|
||||
margin-top: 6px;
|
||||
padding: 8px 20px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #f472b6, #818cf8);
|
||||
padding: 10px 20px;
|
||||
border-radius: var(--radius-pill);
|
||||
/* --gradient-accent, not the stops written out reversed — this button
|
||||
was pink->indigo while every other primary gradient in the app is
|
||||
indigo->pink (same underlying bug the audit flagged in
|
||||
PuzzleResult.module.css, just not cited by this exact line). */
|
||||
background: var(--gradient-accent);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 0.9rem;
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
top: 16px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: rgba(244, 114, 182, 0.7);
|
||||
color: rgba(var(--color-pink-rgb), 0.7);
|
||||
font-size: 0.9rem;
|
||||
pointer-events: none;
|
||||
user-select: none;
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 28px;
|
||||
padding: 32px 16px;
|
||||
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
|
||||
color: #e0e7ff;
|
||||
padding: var(--space-5) var(--space-3);
|
||||
background: var(--bg-gradient);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.scoreBox {
|
||||
@ -15,14 +15,16 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.grade {
|
||||
font-size: 6rem;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
background: linear-gradient(90deg, #f472b6, #818cf8);
|
||||
/* Was reversed (pink->indigo) vs every other heading gradient in the
|
||||
app (indigo->pink) — the bug DESIGN_AUDIT_TODO.md flagged. */
|
||||
background: var(--gradient-accent);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@ -31,7 +33,7 @@
|
||||
.pct {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #a5b4fc;
|
||||
color: var(--color-indigo-light);
|
||||
}
|
||||
|
||||
.stats {
|
||||
@ -40,18 +42,18 @@
|
||||
}
|
||||
|
||||
.caught {
|
||||
color: #34d399;
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: grid;
|
||||
gap: 3px;
|
||||
gap: 4px;
|
||||
max-width: min(480px, 90vw);
|
||||
width: 100%;
|
||||
border: 3px solid rgba(129, 140, 248, 0.4);
|
||||
border-radius: 8px;
|
||||
border: 3px solid rgba(var(--color-indigo-rgb), 0.4);
|
||||
border-radius: var(--radius-md);
|
||||
overflow: hidden;
|
||||
background: #1e1b4b;
|
||||
background: var(--surface-solid);
|
||||
}
|
||||
|
||||
.piece {
|
||||
@ -64,16 +66,16 @@
|
||||
.hole {
|
||||
width: 100%;
|
||||
aspect-ratio: 1;
|
||||
background: rgba(30, 27, 75, 0.9);
|
||||
border: 1px dashed rgba(129, 140, 248, 0.2);
|
||||
background: rgba(var(--surface-rgb), 0.9);
|
||||
border: 1px dashed rgba(var(--color-indigo-rgb), 0.2);
|
||||
}
|
||||
|
||||
.restartBtn {
|
||||
padding: 10px 28px;
|
||||
border-radius: 999px;
|
||||
padding: 14px 28px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: transparent;
|
||||
border: 2px solid #f472b6;
|
||||
color: #f9a8d4;
|
||||
border: 2px solid var(--color-pink);
|
||||
color: var(--color-pink-light);
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
@ -81,6 +83,6 @@
|
||||
}
|
||||
|
||||
.restartBtn:hover {
|
||||
border-color: #818cf8;
|
||||
color: #a5b4fc;
|
||||
border-color: var(--color-indigo);
|
||||
color: var(--color-indigo-light);
|
||||
}
|
||||
|
||||
@ -5,9 +5,9 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 28px;
|
||||
padding: 32px 16px;
|
||||
background: linear-gradient(135deg, #0f0c29, #302b63, #24243e);
|
||||
color: #e0e7ff;
|
||||
padding: var(--space-5) var(--space-3);
|
||||
background: var(--bg-gradient);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
.scoreBox {
|
||||
@ -15,14 +15,14 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
gap: var(--space-2);
|
||||
}
|
||||
|
||||
.grade {
|
||||
font-size: 6rem;
|
||||
font-weight: 900;
|
||||
line-height: 1;
|
||||
background: linear-gradient(90deg, #818cf8, #f472b6);
|
||||
background: var(--gradient-accent);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
@ -31,27 +31,27 @@
|
||||
.pct {
|
||||
font-size: 2rem;
|
||||
font-weight: 700;
|
||||
color: #a5b4fc;
|
||||
color: var(--color-indigo-light);
|
||||
}
|
||||
|
||||
.stats {
|
||||
display: flex;
|
||||
gap: 24px;
|
||||
gap: var(--space-4);
|
||||
font-size: 1.1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.caught {
|
||||
color: #34d399;
|
||||
color: var(--color-success);
|
||||
}
|
||||
|
||||
.missed {
|
||||
color: #f87171;
|
||||
color: var(--color-error);
|
||||
}
|
||||
|
||||
.lists {
|
||||
display: flex;
|
||||
gap: 32px;
|
||||
gap: var(--space-5);
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
max-width: 640px;
|
||||
@ -61,7 +61,7 @@
|
||||
.listTitle {
|
||||
font-size: 1rem;
|
||||
font-weight: 700;
|
||||
color: #94a3b8;
|
||||
color: var(--muted-text);
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
margin: 0 0 8px;
|
||||
@ -79,10 +79,10 @@
|
||||
.fileItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
background: rgba(30, 27, 75, 0.7);
|
||||
border-radius: 8px;
|
||||
padding: 6px 12px;
|
||||
gap: var(--space-2);
|
||||
background: var(--surface);
|
||||
border-radius: var(--radius-md);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
@ -100,7 +100,7 @@
|
||||
}
|
||||
|
||||
.fsize {
|
||||
color: #64748b;
|
||||
color: var(--muted-faint);
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
@ -108,13 +108,13 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
gap: var(--space-3);
|
||||
}
|
||||
|
||||
.actionBtn {
|
||||
padding: 12px 32px;
|
||||
border-radius: 999px;
|
||||
background: linear-gradient(90deg, #818cf8, #f472b6);
|
||||
padding: 16px var(--space-5);
|
||||
border-radius: var(--radius-pill);
|
||||
background: var(--gradient-accent);
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 1rem;
|
||||
@ -128,11 +128,11 @@
|
||||
}
|
||||
|
||||
.restartBtn {
|
||||
padding: 10px 28px;
|
||||
border-radius: 999px;
|
||||
padding: 14px 28px;
|
||||
border-radius: var(--radius-pill);
|
||||
background: transparent;
|
||||
border: 2px solid #818cf8;
|
||||
color: #a5b4fc;
|
||||
border: 2px solid var(--color-indigo);
|
||||
color: var(--color-indigo-light);
|
||||
font-weight: 600;
|
||||
font-size: 1rem;
|
||||
cursor: pointer;
|
||||
@ -140,18 +140,18 @@
|
||||
}
|
||||
|
||||
.restartBtn:hover {
|
||||
border-color: #f472b6;
|
||||
color: #f9a8d4;
|
||||
border-color: var(--color-pink);
|
||||
color: var(--color-pink-light);
|
||||
}
|
||||
|
||||
.status {
|
||||
color: #34d399;
|
||||
color: var(--color-success);
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #f87171;
|
||||
color: var(--color-error);
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@ -1,3 +1,76 @@
|
||||
/* Design tokens — the shared source of truth every *.module.css file
|
||||
should reference instead of its own hardcoded hex literals. Previously
|
||||
absent entirely (rule 4), which is how the same page-background/heading
|
||||
gradients ended up copy-pasted verbatim across 4 files, one of them with
|
||||
the gradient stops reversed (PuzzleResult.module.css, and ModeSelect's
|
||||
puzzleStart button — same bug, two spots). */
|
||||
:root {
|
||||
/* Page background (3-stop gradient) */
|
||||
--bg-1: #0f0c29;
|
||||
--bg-2: #302b63;
|
||||
--bg-3: #24243e;
|
||||
--bg-gradient: linear-gradient(135deg, var(--bg-1), var(--bg-2), var(--bg-3));
|
||||
|
||||
/* Drag-over state (DropZone only) */
|
||||
--bg-drag-1: #1a1560;
|
||||
--bg-drag-2: #4a3f9e;
|
||||
--bg-drag-3: #3a3868;
|
||||
--bg-drag-gradient: linear-gradient(
|
||||
135deg,
|
||||
var(--bg-drag-1),
|
||||
var(--bg-drag-2),
|
||||
var(--bg-drag-3)
|
||||
);
|
||||
|
||||
/* Accent pair. --gradient-accent is the ONE canonical direction
|
||||
(indigo -> pink) for every heading/primary-button gradient in the
|
||||
app — always use this token, never write the stops out by hand. */
|
||||
--color-indigo: #818cf8;
|
||||
--color-indigo-rgb: 129, 140, 248;
|
||||
--color-pink: #f472b6;
|
||||
--color-pink-rgb: 244, 114, 182;
|
||||
--gradient-accent: linear-gradient(90deg, var(--color-indigo), var(--color-pink));
|
||||
|
||||
--color-indigo-light: #a5b4fc;
|
||||
--color-indigo-lighter: #c7d2fe;
|
||||
--color-pink-light: #f9a8d4;
|
||||
--color-pink-lighter: #e879f9;
|
||||
|
||||
--color-text: #e0e7ff;
|
||||
--color-text-rgb: 224, 231, 255;
|
||||
|
||||
/* Raised-surface fill (cards, file rows, the puzzle grid) — one base
|
||||
color at different opacities/solidity, not independent literals. */
|
||||
--surface-rgb: 30, 27, 75;
|
||||
--surface: rgba(var(--surface-rgb), 0.7);
|
||||
--surface-solid: rgb(var(--surface-rgb));
|
||||
|
||||
--color-success: #34d399;
|
||||
--color-error: #f87171;
|
||||
|
||||
/* Muted grays — was 4 unrelated shades (rule 2); collapsed to 2 named,
|
||||
semantically distinct roles: body-adjacent secondary text, and a
|
||||
slightly darker tertiary/caption tone. (Borders get their own token
|
||||
below, since one of them needed a contrast fix rule 7 flagged.) */
|
||||
--muted-text: #94a3b8;
|
||||
--muted-faint: #6b7280;
|
||||
--muted-border: #4b5563;
|
||||
|
||||
/* Spacing scale (4px base) */
|
||||
--space-1: 4px;
|
||||
--space-2: 8px;
|
||||
--space-3: 16px;
|
||||
--space-4: 24px;
|
||||
--space-5: 32px;
|
||||
--space-6: 40px;
|
||||
|
||||
/* Corner radius scale */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 16px;
|
||||
--radius-pill: 999px;
|
||||
}
|
||||
|
||||
*, *::before, *::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@ -7,6 +80,6 @@ html, body, #root {
|
||||
padding: 0;
|
||||
height: 100%;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
background: #0f0c29;
|
||||
color: #e0e7ff;
|
||||
background: var(--bg-1);
|
||||
color: var(--color-text);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user