npm.io
3.90.0 • Published 5d ago

@design.estate/dees-catalog

Licence
MIT
Version
3.90.0
Deps
22
Size
15.1 MB
Vulns
0
Weekly
1.4K
Install scriptsThis package runs scripts during installation (preinstall/install/postinstall)

Theme Token Migration (bdTheme → --dees-* tokens)

Status: WS1 in progress — vocabulary approved 2026-06-12. Decisions: (1) the three text tokens below were added to 00theme.ts; (2) shadow tokens are theme-aware (themeDefaults.shadowsDark); (3) consolidation mapping approved as listed; (4) the post-consolidation unique tail uses :host([gobright]) (goBright reflects as an attribute since @design.estate/dees-element 2.3.0) instead of remaining on bdTheme.

Goal: zero cssManager.bdTheme() call sites in ts_web outside ts_web/elements/00theme.ts. 00theme.ts is the single sanctioned bridge — the --dees-* tokens are themselves implemented via bdTheme() there, so the runtime theme-switch mechanism does not change. Components only ever consume var(--dees-*).

Inventory (2026-06-12)

  • 1,651 bdTheme() call sites across 129 files (demos included): 1,622 single-line literal (clustered below), 22 multi-line literal (handled like any literal during sweeps), 7 with dynamic arguments
  • 546 distinct (light, dark) pairs after color normalization
  • 91 pairs / 397 sites match an existing token exactly or within Δ≤6 per RGB channel (visual no-op)
  • 7 pairs / 50 sites look like flipped arguments (light/dark swapped) — see "Suspected bugs"
  • 432 pairs / 1,155 sites need consolidation (mostly zinc/gray/slate/ad-hoc palette generations expressing the same semantics) — see mapping table
  • 16 pairs / 20 sites are non-color values (shadows, borders shorthand, gradients, filters)
  • Dynamic-argument calls live in only 3 components: dees-progressbar (3), dees-spinner (2), dees-searchbar (2)

Analysis tooling: tsx .nogit/debug/analyze-bdtheme.ts regenerates .nogit/debug/bdtheme-analysis.json (full cluster → file data) and the ratchet baseline counts.

Approved vocabulary additions (in 00theme.ts since 2026-06-12)

New color tokens in IThemeColors / themeDefaultStyles — values taken from the dominant existing usage, so adopting them is a visual no-op at those sites:

Token Light Dark Replaces (sites)
--dees-color-text-success hsl(142.1 76.2% 36.3%) hsl(142.1 70.6% 45.3%) green-600/500 pairs (~13)
--dees-color-text-error #dc2626 #f87171 red-600/400 pairs (~10)
--dees-color-text-warning hsl(38 92% 45%) hsl(38 92% 55%) amber pairs (~4)

Shadow tokens become theme-aware (today they are static; found usage consistently wants stronger shadows in dark mode). Light values unchanged:

Token Light (unchanged) Dark (new)
--dees-shadow-xs 0 1px 2px 0 rgb(0 0 0 / 0.05) 0 1px 2px 0 rgb(0 0 0 / 0.2)
--dees-shadow-sm 0 1px 3px rgba(0, 0, 0, 0.1) 0 1px 3px rgba(0, 0, 0, 0.3)
--dees-shadow-md 0 2px 8px rgba(0, 0, 0, 0.15) 0 2px 8px rgba(0, 0, 0, 0.35)
--dees-shadow-lg 0 4px 12px rgba(0, 0, 0, 0.15) 0 4px 12px rgba(0, 0, 0, 0.4)

Mechanism for the post-consolidation tail (genuinely component-unique theme pairs, e.g. terminal/chart palettes): goBright reflects as the gobright attribute since @design.estate/dees-element 2.3.0, so such sites use plain :host([gobright]) { ... } CSS for component-local light/dark styling without bdTheme and without growing the global vocabulary (rule R6).

Migration rules (precedence order)

  1. R1 — exact/near token match (Δ≤6/channel on both light and dark): replace with the token. Visual no-op.
  2. R2 — semantic consolidation: palette-generation duplicates (zinc/gray/slate/ad-hoc) map to the canonical token for their role (see table). Small intentional shifts: blue-tinted grays become neutral grays. Pick the token by role (text vs border vs surface), not by raw distance.
  3. R3 — alpha tints of a semantic color: color-mix(in srgb, var(--dees-color-X) N%, transparent) instead of a dedicated pair.
  4. R4 — flipped arguments: confirm against rendered output, then fix to the token (these are bugs — the light theme currently shows dark-theme values). Never "preserve" a flip by mapping it to swapped tokens, except intentional inverted-contrast UI (tooltips already have --dees-color-tooltip-*).
  5. R5 — non-color values: shadows → --dees-shadow-*; spacing/radius/transition literals → their scales when the value matches; composite values (gradients, checkerboards) → compose from color tokens inside the gradient.
  6. R6 — genuinely unique pairs (after R1–R5, expected rare): component-local :host([gobright]) CSS (dark value as default, bright override).

00colors.ts (legacy constants, 10 files) is retired during sweeps: blue/blueActive → accent/link tokens per role (note: #0050b9 → #3b82f6 is a visible shift, check each site), text → text tokens.

Consolidation mapping (clusters ≥7 sites; tail follows the same role rules)

Sites Pair (light | dark) → Token Shift
45 #09090b | #fafafa --dees-color-text-primary none
27 hsl(0 0% 89.8%) | hsl(0 0% 14.9%) --dees-color-border-default none
25 #71717a | #a1a1aa --dees-color-text-muted dark dims slightly
25 #e5e7eb | #27272a --dees-color-border-default none
24 hsl(215.3 25% 8.8%) | hsl(210 40% 98%) --dees-color-text-primary blue-gray → neutral
24 #e5e7eb | #374151 --dees-color-border-default dark border darkens (wysiwyg blocks)
23 #3b82f6 | #60a5fa --dees-color-link none
22 hsl(215.4 16.3% 56.9%) | hsl(215 20.2% 55.1%) --dees-color-text-muted blue-gray → neutral
19 #3b82f6 | #3b82f6 --dees-color-accent-primary none
19 #666 | #999 --dees-color-text-muted minor
18 hsl(210 40% 96.1%) | hsl(215 20.2% 16.8%) --dees-color-badge-default-bg near none (secondary surface)
18 hsl(215.4 16.3% 46.9%) | hsl(215 20.2% 65.1%) --dees-color-text-muted dark dims
18 hsl(210 20% 98%) | hsl(215 27.9% 16.9%) --dees-color-badge-default-bg slate → neutral (datepicker family)
16 #71717a | #71717a --dees-color-text-muted becomes theme-aware (improvement)
16 #9ca3af | #6b7280 --dees-color-text-muted light darkens (placeholders)
15 hsl(222.2 47.4% 51.2%) | hsl(217.2 91.2% 59.8%) --dees-color-accent-primary light brightens
15 hsl(0 0% 95.1%) | hsl(0 0% 14.9%) --dees-color-badge-default-bg near none
14 hsl(220 8.9% 46.1%) | hsl(215 20.2% 65.1%) --dees-color-text-muted dark dims
13 #18181b | #fff --dees-color-tooltip-bg near none
13 #000000 | #ffffff per-site: usually text-primary manual (R4 check: some intentional pure contrast)
13 hsl(0 0% 45.1%) | hsl(0 0% 63.9%) --dees-color-text-muted dark dims slightly
13 #374151 | #e5e7eb per-site: text-secondary or text-primary manual (emphasized text, dark value sits between tokens)
13 hsl(215 16% 45%) | hsl(215 16% 75%) --dees-color-text-secondary dark dims
12 #6b7280 | #9ca3af --dees-color-text-muted minor
11 #71717a | #888 --dees-color-text-muted minor
11 #111827 | #f9fafb --dees-color-text-primary near none
10 #dc2626 | #f87171 --dees-color-text-error (new) none
10 #ffffff | #000000 per-site (inverse surfaces) manual
10 #a1a1aa | #666 per-site (storage-browser family) manual, flip-suspect
10 #333 | #fff --dees-color-text-primary light deepens
10 hsl(214.3 31.8% 91.4%) | hsl(217.2 32.6% 17.5%) --dees-color-border-default slate → neutral
10 hsl(0 0% 50%) | hsl(0 0% 60%) --dees-color-text-muted minor
9 #e5e7eb | #3f3f46 --dees-color-border-default dark darkens
9 hsl(0 0% 88%) | hsl(0 0% 20%) --dees-color-border-default minor
9 #d1d9e0 | #30363d --dees-color-border-default github palette → neutral (markdownoutlet)
8 hsl(142.1 76.2% 36.3%) | hsl(142.1 70.6% 45.3%) --dees-color-text-success (new) none
8 #e5e7eb | #333 --dees-color-border-default minor
8 hsl(0 0% 20%) | hsl(0 0% 90%) per-site: text-secondary/text-primary manual
8 hsl(224 71.4% 4.1%) | hsl(210 20% 98%) --dees-color-text-primary near none
8 hsl(0 0% 95%) | hsl(0 0% 9%) --dees-color-code-block-bg near none
7 #999 | #666 --dees-color-text-muted faint/disabled text, both shift
7 hsl(222.2 47.4% 51.2% / 0.1) | hsl(217.2 91.2% 59.8% / 0.1) color-mix(accent-primary 10%) (R3) near none
7 hsl(0 0% 100%) | hsl(224 71.4% 4.1%) --dees-color-bg-primary none
7 hsl(0 72.2% 50.6%) | hsl(0 62.8% 30.6%) --dees-color-accent-error dark brightens (destructive buttons) — review
7 hsl(215.3 25% 26.7%) | hsl(217.9 10.6% 74.9%) --dees-color-text-secondary dark dims
7 #d1d5db | #4b5563 --dees-color-border-strong dark darkens

Suspected bugs (flipped light/dark arguments — fix via R4 during sweeps)

Sites Pair (light | dark) Looks like Files
23 hsl(0 0% 9%) | hsl(0 0% 95%) code-block-bg flipped chart-log demo, table demo (terminal panels — verify: may be intentional always-dark panels; if so, use literal dark values, not a flip)
12 hsl(0 0% 15%) | hsl(0 0% 90%) border-default flipped dataview-statusobject, input-checkbox
9 hsl(0 0% 63.9%) | hsl(0 0% 45.1%) text-secondary flipped dropdown, statusobject
6 #333 | #ccc border-strong flipped profiledropdown, pagination
3 #a1a1aa | #404040 badge-default-fg flipped storage-browser
3 hsl(0 0% 15%) | hsl(0 0% 93.9%) badge-default-bg flipped input-richtext, input-text
3 hsl(142.1 70.6% 45.3%) | hsl(142.1 76.2% 36.3%) text-success flipped (locate during sweep)
2 #262626 | #e5e5e5 border-default flipped appui-mainmenu, simple-appdash

Sweep order (WS1, after vocabulary approval)

  1. Add approved tokens to 00theme.ts (+ IThemeColors), release.
  2. The 49 files currently using both systems (finish what's started; fastest surface reduction).
  3. 00group-input + form infrastructure (incl. datepicker slate re-skin)
  4. 00group-dataview (table styles.ts, storage-browser family incl. flip-suspects)
  5. 00group-overlay, 00group-layout
  6. 00group-appui, 00group-simple
  7. 00group-chart, 00group-media, 00group-workspace, remaining groups + demos
  8. Dynamic-call components (progressbar, spinner, searchbar) — restructure their color props to accept tokens/CSS values rather than light/dark pairs.

Per sweep: pnpm build, pnpm test, wcctools demo screenshots in both themes (before/after), node scripts/check-bdtheme-ratchet.cjs --update-baseline, focused commit per group.

Ratchet

scripts/check-bdtheme-ratchet.cjs (runs first in pnpm test):

  • counts bdTheme( occurrences per file under ts_web/, excluding ts_web/elements/00theme.ts
  • fails if any file exceeds its count in scripts/bdtheme-baseline.json, or if a file not in the baseline uses bdTheme at all
  • --update-baseline rewrites the baseline after a sweep (counts may only shrink; the script refuses to raise them)

Keywords