From 81eb572f3da98c7b57064b9c4767807246ad6296 Mon Sep 17 00:00:00 2001
From: dev
Date: Thu, 4 Jun 2026 21:28:43 +0200
Subject: [PATCH] feat(temas/color): group the palette by Radix taxonomy
The 31-scale library was a flat list, so the 6 tinted grays (gray/mauve/slate/
sage/olive/sand) looked like near-duplicates. Group it like Radix: Grises (tinted
neutrals) - Colores - Brillantes (light solids) - Metales, with a fallback "Otros"
bucket so no scale is ever dropped. Intro note explains the grays cluster because
they are near-neutral (chroma ~0.01) with a subtle per-accent hue tint. Verified
in-browser: 31 scales, none dropped/duped, 4 group labels.
Co-Authored-By: Claude Opus 4.8 (1M context)
---
web/routes/temas/color/+page.svelte | 68 +++++++++++++++++++++++------
1 file changed, 54 insertions(+), 14 deletions(-)
diff --git a/web/routes/temas/color/+page.svelte b/web/routes/temas/color/+page.svelte
index a103745a1..e366a7bc3 100644
--- a/web/routes/temas/color/+page.svelte
+++ b/web/routes/temas/color/+page.svelte
@@ -55,6 +55,34 @@
let theme = $state<'light' | 'dark'>('light')
const SCALE_NAMES = Object.keys(THEME_BASE_LIGHT_COLOR_SCALES)
+
+ // Radix's palette taxonomy — display grouping only (the library itself is flat).
+ // Any scale not listed falls into "Otros" so nothing is ever dropped.
+ const PALETTE_GROUPS: { label: string; names: readonly string[] }[] = [
+ { label: 'Grises (neutros tintados)', names: ['gray', 'mauve', 'slate', 'sage', 'olive', 'sand'] },
+ {
+ label: 'Colores',
+ names: [
+ 'tomato', 'red', 'ruby', 'crimson', 'pink', 'plum', 'purple', 'violet', 'iris',
+ 'indigo', 'blue', 'cyan', 'teal', 'jade', 'green', 'grass', 'brown', 'orange'
+ ]
+ },
+ { label: 'Brillantes (sólido claro)', names: ['amber', 'yellow', 'lime', 'mint', 'sky'] },
+ { label: 'Metales', names: ['gold', 'bronze'] }
+ ]
+ const paletteGroups = (() => {
+ const present = new Set(SCALE_NAMES)
+ const used = new Set()
+ const groups = PALETTE_GROUPS.map((g) => {
+ const names = g.names.filter((n) => present.has(n))
+ names.forEach((n) => used.add(n))
+ return { label: g.label, names }
+ }).filter((g) => g.names.length > 0)
+ const leftover = SCALE_NAMES.filter((n) => !used.has(n))
+ if (leftover.length) groups.push({ label: 'Otros', names: leftover })
+ return groups
+ })()
+
const ROLES = completeColorRoleMap(THEME_BASE_COLOR_ROLES)
const STEPS = COLOR_SCALE_STEPS
const SLOTS = COLOR_ROLE_SLOTS
@@ -335,7 +363,9 @@
paso 9. La paleta la trae el tema; el framework envía estas 31 (valores
Radix exactos, listos para autoría OKLCH). Es la librería fija de
referencia — el seed del builder NO la cambia: deriva los roles (arriba),
- que son escalas generadas nuevas, no miembros de esta lista.
+ que son escalas generadas nuevas, no miembros de esta lista. Agrupada como Radix — los
+ grises tintados (gray/mauve/slate/sage/olive/sand) se parecen porque son
+ casi-neutros (croma ~0.01): cada uno con un tinte de hue mínimo para armonizar con su acento.
@@ -347,20 +377,23 @@
{/each}
- {#each SCALE_NAMES as name}
-
-
{name}
-
- {#each STEPS as s}
-
- {/each}
+ {#each paletteGroups as group}
+
{group.label}
+ {#each group.names as name}
+
+
{name}
+
+ {#each STEPS as s}
+
+ {/each}
+
-
+ {/each}
{/each}
@@ -628,6 +661,13 @@
flex-direction: column;
gap: 3px;
}
+ .palette-group-label {
+ margin-block: var(--space-3) var(--space-1);
+ font-family: var(--font-family-mono, 'Roboto Mono', ui-monospace, monospace);
+ font-size: var(--font-size-xs);
+ font-weight: 600;
+ color: var(--color-content-secondary);
+ }
.scale-row {
display: flex;
align-items: center;