Skip to content

Design system unification - #5

Merged
sifferhans merged 30 commits into
masterfrom
design-system-unification
Sep 17, 2026
Merged

sifferhans merged 30 commits into
masterfrom
design-system-unification

Conversation

@sifferhans

Copy link
Copy Markdown
Contributor

Unified the admin- and userfacing designs, and implemented a proper shared component library / design system.

sifferhans and others added 30 commits September 16, 2026 13:11
The frontend carried four independent style regimes: Tailwind utilities
on the upload flow, `.admin-root` scoped CSS, `.send-root` scoped CSS,
and LoginGate with the palette inlined as hex. The two scoped sheets had
copy-pasted the same 15 custom properties, and their shared components
had already drifted apart.

Establish one source of truth and one component vocabulary:

- Declare all tokens in a Tailwind `@theme` block in style.css, so each
  is available both as a utility (`bg-surface-2`) and as a custom
  property (`var(--color-surface-2)`) from a single definition. Rename
  to a self-describing namespace: surface/line/ink/accent + status.
- Add assets/components.css, holding every primitive used by more than
  one surface: buttons, badges, token inputs, text inputs, cards, empty
  states, toasts, animations. Removes 73 duplicated rules from the two
  surface sheets.
- Resolve the drift that had accumulated between the copies:
  - `.chip` meant a read-only badge in Admin but a removable token in
    Send. Split into `.badge` (was Admin `.chip`, Send `.chip-sm`) and
    `.token`/`.token-input` (was Admin `.member-chip`/`.member-input`,
    Send `.chip`/`.chips`).
  - Button modifiers were `.btn-sm` in Admin but `.btn.sm` in Send;
    settle on the `btn-*` prefix. Admin's dense scale is now the base,
    Send's prominent scale is `.btn-lg`.
  - `.btn-danger` was outline in Admin and filled in Send; keep outline.
  - Text inputs were implicit `.field input` in Admin (no focus ring)
    and explicit `.inp` in Send (3px ring). One rule now serves both
    call sites, keeping Send's focus ring.
  - `@keyframes fb-fade` and `send-fade` were byte-identical; keep one
    `fb-` set.
- Tokenise LoginGate, which had hardcoded the palette and so would have
  silently ignored any token change.
- Move the page ground, font stack and selection colour onto `html`/
  `body` instead of re-declaring them per surface root.

RecipientChipInput tracked focus in a JS ref purely to drive the focus
ring; `:focus-within` covers it, so the ref and its two handlers go.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The Upload surface was still the original Tailwind light/dark theme —
gray-50 grounds, white cards, blue-500 accents — while Admin and Send
had moved to the dark navy palette. Same app, two visual languages.

Convert the seven remaining components to the shared system and promote
the primitives they turned out to share with Send:

- App chrome (page header, brand, tab nav, user menu, page title/sub)
  moves from send.css into components.css, so Upload and Send render the
  same header instead of each having its own.
- File intake (`.dropzone`, `.file-list`, `.file-item`) likewise: Send's
  compose form and the upload drop zone were separate implementations of
  the same component.
- Add a `.progress` primitive; the upload progress bar was the only one
  in the app and had its track and five state colours inline.
- Replace AuthMenu and SendUserMenu with one UserMenu. The two carried
  near-identical dropdown logic (open ref, document click-away, admin
  link, change user, sign out); AuthMenu was the superset, adding guest
  handling and the provider sign-in list.
- UploadForm, UploadList, UploadProgress, TargetSelector and
  FileUploader now use the shared card, field, input, badge, button and
  file-list primitives, with only genuinely local layout kept scoped.

Also finish centralising colour: the avatar gradient, provider tints,
BCC brand colours and LoginGate's error state were still literals. Every
palette value now resolves to a token — the only hex left outside the
@theme block is #fff/#000 and Microsoft's official logo swatches.

Two fixes found while verifying:

- `.admin-root button { color: inherit }` (and the send.css twin) is
  redundant with Tailwind's preflight, which applies the same reset in
  @layer base. Because these copies were unlayered they outranked the
  layered component rules, so `.btn-danger` rendered with ink-coloured
  text instead of danger. Removed both.
- Drop `@keyframes fb-spin`/`fb-fade`/`fb-slide` and `send-fade`/
  `send-pop` duplicates left in the surface sheets, plus the dead
  "layout variant switcher" prototype rules (unreferenced on master too).

Verified against a local instance: Upload, Send and Admin render with no
console errors, and injecting identical markup into each surface root
shows all 17 shared primitives computing byte-identical styles.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sifferhans
sifferhans merged commit b54a0e3 into master Sep 17, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant