[Mappe·Shared] Token foundation close-out (radius/shadow/avatar-palette tokens, tag-sand naming, theme key) #854
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Shared component · Story 1 close-out. Part of #853.
Context
frontend/src/routes/layout.cssalready defines ~95% ofDESIGN_RULES §1. This issue closes the remaining gaps the audit found so the rest of the work has a complete token substrate.Scope (
frontend/src/routes/layout.css,src/app.html)--radius-sm:2px; --radius-md:4px; --radius-full:9999pxas first-class:roottokens (today only in Tailwind utilities / the handoffcolors_and_type.css). Radius is theme-invariant — no dark override needed.--shadow-smand--shadow-mdas first-class:roottokens with explicit dark-mode values in the@media (prefers-color-scheme: dark)/.darkblock. A navy-on-sand shadow is near-invisible on dark surfaces; dark cards need their own shadow value so the 3px-mint-top-border card signature retains its lift.$lib/shared/(e.g.$lib/shared/avatarPalette.ts). This is the single source of truth — both<Avatar>(person domain) and the tag-dot colors must import from here. Do not create a parallel CSS token set for the same 10 values; a TS constant avoids drift and is boundary-safe for both$lib/person/and$lib/tag/consumers pereslint.config.js.--c-tag-sand(the name already shipped inlayout.css; value stays#9a8040). Correct the handoff doc (colors_and_type.css) to use--c-tag-sand— do not rename the live token.theme(currentlocalStoragekey used by the boot script insrc/app.htmlandThemeToggle). Do not migrate tofa-theme; update the handoff docs to reflecttheme. This avoids a client-state migration across the rolling deploy and keeps the existingt === 'dark' || t === 'light'allow-list guard intact (see Security note below).Out of Scope
personFormat.ts's existing 5-color hashing to the new 10-color palette here. Rewiring existing avatar consumers belongs to the Avatar issue that this unblocks.Security note (implementer)
The boot script in
src/app.htmlruns before Svelte hydration and writes directly todocument.documentElement. Retain thet === 'dark' || t === 'light'allow-list guard when reading fromlocalStorage— never write a raw, unvalidated localStorage value intosetAttribute. This is the only untrusted-input-to-DOM path in this change.Acceptance
--radius-sm,--radius-md,--radius-fullpresent in:root--shadow-sm,--shadow-mdpresent in:rootand in the dark-mode block with distinct values$lib/shared/avatarPalette.ts; all 10 colors pass ≥4.5:1 contrast against the initials foreground color in both light and dark themes--c-tag-sandis the sole name acrosslayout.cssand the handoff doc; no--c-tag-sand-tagremainstheme; handoff docs updated; boot script insrc/app.htmlsetsdata-themeon<html>via a render-blocking<script>in<head>before first paint (no flash of wrong theme on hard reload withtheme=darkin localStorage)npm run lintandnpm run checkpass; no new raw hex or Tailwind color classes introduced in touched filesDepends on: none. Blocks: Avatar (uses the palette constant). Refs:
DESIGN_RULES §1,DESIGN_RULES §5, EPIC Story 1.marcel referenced this issue2026-06-16 14:00:10 +02:00
marcel referenced this issue2026-06-16 14:00:57 +02:00
marcel referenced this issue2026-06-16 14:01:06 +02:00
marcel referenced this issue2026-06-16 14:01:48 +02:00
marcel referenced this issue2026-06-16 14:02:09 +02:00
marcel referenced this issue2026-06-16 14:02:21 +02:00
marcel referenced this issue2026-06-16 14:02:31 +02:00
marcel referenced this issue2026-06-16 14:02:38 +02:00
marcel referenced this issue2026-06-16 14:03:06 +02:00
marcel referenced this issue2026-06-16 14:03:34 +02:00