From 34b4542da40c8abd85f2010d0fdd66111c3e6ae5 Mon Sep 17 00:00:00 2001 From: Chris Sherwood Date: Mon, 31 Aug 2026 09:02:11 -0700 Subject: [PATCH] fix(dashboard): show the color picker swatches solid The swatches reused the tile tint, which is 10% opacity. That reads well across a 190px card and makes six 28px squares indistinguishable from one another, so the picker looked like six empty outlines. Caught by looking at it. Each color now carries a solid class alongside its tint: the picker shows the color at full strength, the tile stays subtle. A test asserts the swatch class is solid rather than an opacity variant, since reaching for the tint again is the obvious mistake. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01F8Mgg1vd2eKSs8StZiuyMV --- admin/constants/link_tile_colors.ts | 11 +++++++++++ admin/inertia/components/LinkTileModal.tsx | 6 ++++-- admin/tests/unit/link_tile.spec.ts | 9 ++++++++- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/admin/constants/link_tile_colors.ts b/admin/constants/link_tile_colors.ts index e100db06..e7302b21 100644 --- a/admin/constants/link_tile_colors.ts +++ b/admin/constants/link_tile_colors.ts @@ -9,6 +9,11 @@ * dashed border and the external-link marker are what carry that, not the hue. * The tint is deliberately light so the distinction survives every option. * + * `bg` is the tile tint and `swatch` is the same color at full strength. They + * differ on purpose: a 10% tint reads well across a 190px card but makes six + * 28px picker swatches indistinguishable from each other, so the picker shows + * the color solid while the tile stays subtle. + * * Class names are written out in full and never interpolated. Tailwind scans * source text for literal class strings, so a computed name like * `bg-desert-${id}/10` would be silently dropped from the build. @@ -16,6 +21,7 @@ export const LINK_TILE_COLORS = [ { id: 'green', + swatch: 'bg-desert-green', label: 'Green', border: 'border-desert-green/70', bg: 'bg-desert-green/10', @@ -23,6 +29,7 @@ export const LINK_TILE_COLORS = [ }, { id: 'olive', + swatch: 'bg-desert-olive', label: 'Olive', border: 'border-desert-olive/70', bg: 'bg-desert-olive/10', @@ -30,6 +37,7 @@ export const LINK_TILE_COLORS = [ }, { id: 'orange', + swatch: 'bg-desert-orange', label: 'Orange', border: 'border-desert-orange/70', bg: 'bg-desert-orange/10', @@ -37,6 +45,7 @@ export const LINK_TILE_COLORS = [ }, { id: 'red', + swatch: 'bg-desert-red', label: 'Red', border: 'border-desert-red/70', bg: 'bg-desert-red/10', @@ -44,6 +53,7 @@ export const LINK_TILE_COLORS = [ }, { id: 'sand', + swatch: 'bg-desert-sand', label: 'Sand', border: 'border-desert-sand/70', bg: 'bg-desert-sand/20', @@ -51,6 +61,7 @@ export const LINK_TILE_COLORS = [ }, { id: 'stone', + swatch: 'bg-desert-stone', label: 'Stone', border: 'border-desert-stone/70', bg: 'bg-desert-stone/10', diff --git a/admin/inertia/components/LinkTileModal.tsx b/admin/inertia/components/LinkTileModal.tsx index 7f3d6c4f..8d744c2c 100644 --- a/admin/inertia/components/LinkTileModal.tsx +++ b/admin/inertia/components/LinkTileModal.tsx @@ -167,8 +167,10 @@ export default function LinkTileModal({ aria-label={option.label} aria-pressed={color === option.id} onClick={() => setColor(option.id)} - className={`h-7 w-7 rounded border-2 border-dashed transition-transform ${option.border} ${option.bg} ${ - color === option.id ? 'scale-110 ring-2 ring-offset-1 ring-desert-green' : '' + className={`h-7 w-7 rounded transition-transform ${option.swatch} ${ + color === option.id + ? 'scale-110 ring-2 ring-offset-2 ring-text-primary' + : 'opacity-70 hover:opacity-100' }`} /> ))} diff --git a/admin/tests/unit/link_tile.spec.ts b/admin/tests/unit/link_tile.spec.ts index 96810366..bed078ef 100644 --- a/admin/tests/unit/link_tile.spec.ts +++ b/admin/tests/unit/link_tile.spec.ts @@ -122,7 +122,14 @@ test('every link tile color ships complete, literal Tailwind classes', () => { assert.ok(option.border.startsWith('border-desert-'), option.id) assert.ok(option.bg.startsWith('bg-desert-'), option.id) assert.ok(option.marker.startsWith('text-desert-'), option.id) - assert.ok(!`${option.border}${option.bg}${option.marker}`.includes('${'), option.id) + // The swatch is the same color solid; a tint that works on a card is + // indistinguishable at 28px. + assert.ok(option.swatch.startsWith('bg-desert-'), option.id) + assert.ok(!option.swatch.includes('/'), `${option.id} swatch must be solid`) + assert.ok( + !`${option.border}${option.bg}${option.marker}${option.swatch}`.includes('${'), + option.id + ) } })