The desktop and the web dashboard each carried a private copy of the
cyberpunk / ember / midnight / mono palettes and they had drifted: the
dashboard's cyberpunk canvas was #040608 with a mint #9bffcf accent
while the desktop's was #000a00 with #00ff41, ember and midnight
disagreed on both canvas and accent, mono agreed only by luck.
Move the raw palette table for every built-in preset into
@hermes/shared (`THEME_PRESET_PALETTES`, apps/shared/src/theme-presets.ts)
and make it the single source of truth:
- apps/desktop/src/themes/presets.ts spreads its `colors` / `darkColors`
from the shared table; the OKLCH synthesis, terminal palettes and
typography stay in the desktop. Serialised BUILTIN_THEMES are
byte-identical to before, so the existing `--dt-primary-solid`
parity pins stay green untouched.
- web/src/themes/presets.ts projects each shared preset onto its
3-slot model through one pure function, `webPresetFromShared`
(background <- background, midground <- primary, warmGlow <- the
midground/ring accent), so cyberpunk / ember / midnight / mono now
render the desktop's palette. Web-only presets (default,
default-large, nous-blue, rose) are untouched.
- Invariant test (web): for every preset shared by both surfaces the
dashboard canvas equals the shared background and the projected text
colour keeps >= 3:1 contrast against it. Red on the previous hexes,
green now.
Why: one edit in one place should recolour a preset on every surface;
two hand-maintained tables guarantee the drift the audit found.