Skip to content

feat(design-system): TS token source-of-truth + light theme [Phase 1a]#616

Merged
barach6662001-bit merged 3 commits intomainfrom
replit/phase-1a-design-tokens
Apr 24, 2026
Merged

feat(design-system): TS token source-of-truth + light theme [Phase 1a]#616
barach6662001-bit merged 3 commits intomainfrom
replit/phase-1a-design-tokens

Conversation

@barach6662001-bit
Copy link
Copy Markdown
Owner

Phase 1a — Foundation

This is the first PR of the design-system overhaul. It introduces the foundation that every subsequent PR will build on. Zero breaking changes; the existing UI renders pixel-identically because every previous CSS variable name is preserved.


What changed

1. Tokens are now TypeScriptsrc/design-system/tokens/

File Contents
colors.ts palette primitives, semanticDark + semanticLight (mirror schemas), cropColors, chartColors
typography.ts Fluid clamp() scale (xs … display + eyebrow), weights, families, tracking
spacing.ts 4 px grid (0 … 24), incl. half-steps (0_5, 1_5)
radius.ts none / xs / sm / md / lg / xl / 2xl / pill
elevation.ts 5-level layered shadows (hairline + ambient + key) for both themes, plus brand glow
motion.ts Durations (instant / fast / base / slow / slower) + easings (standard / decelerate / accelerate / emphasized / spring)
breakpoints.ts xs / sm / md / lg / xl / 2xl + media-query helpers (incl. reducedMotion, hover)
zIndex.ts Centralised stack (dropdown → tooltip → banner)
index.ts Barrel + tokens (theme-independent) and themeTokens (theme-aware) namespaces

2. Generatorscripts/build-tokens.ts

  • Reads the TS tree, emits src/styles/tokens.css deterministically.
  • Emits :root (default = dark), [data-theme='dark'], and [data-theme='light'] blocks.
  • Preserves every legacy var name as alias so component CSS keeps working unchanged.
  • Banner at the top of the generated CSS warns against hand-editing.

3. New npm scripts

  • npm run build:tokens — regenerate CSS from TS (also runs automatically before npm run build).
  • npm run build:tokens:watch — for active token authoring.
  • New devDep: tsx@^4.19.2 (zero-config TS executor).

4. Light theme is now realsrc/theme/lightTheme.ts
Was an empty export {} stub. Now a full ThemeConfig mirroring darkTheme.ts. Theme switching is a single document.documentElement.dataset.theme = 'light' toggle — no React re-render required because every value resolves through CSS vars.


Why

Problem Solution
Tokens scattered between tokens.css (CSS vars), darkTheme.ts (raw hex), and component CSS — easy to drift One source: TS files, one generated CSS, one consumed by both AntD and modules
No type-safety on token usage in TS code SemanticTokenKey, FontScaleKey, SpacingKey etc. exported
Light theme advertised but unimplemented Full impl, ready to wire into a theme toggle
Type scale was static — broke on small/large screens Fluid clamp() ramps automatically
Single-layer shadows looked cheap on cards 5-level layered system (hairline + ambient + key)
Motion was three magic strings Durations + 5 easings + ready-made transitions
Z-index "stacking-context arms race" Centralised scale with semantic names

Compatibility — what reviewers should verify

Visual regression: pages should look identical. Only addition is the dormant [data-theme='light'] block. Every previous var name (--brand, --bg-page, --text-primary, --space-*, --radius-*, --shadow-*, --transition-*) is preserved.

  • darkTheme.ts is unchanged.
  • No component files modified.

Out of scope (next PRs)

  • 1b — Layout & typography primitives (Stack, Cluster, Container, Heading, Text)
  • 1c — Form & surface primitives (Button, Input, Field, Card, Surface) with full variant API
  • 1d — AppShell refactor (Sidebar / Topbar / ContentContainer system)
  • 1e — Storybook + Playwright visual regression infrastructure
  • 1f — Theme toggle UI (binds the now-real lightTheme to user preference)

Each of those will be its own focused PR.

Phase 1a of the design-system overhaul.

WHAT
- New folder `src/design-system/tokens/` holds all design tokens as TS:
  colors (palette + semanticDark + semanticLight + cropColors + chartColors),
  typography (fluid clamp() scale, weights, families, tracking),
  spacing (4 px grid), radius, elevation (5-level layered shadows for both
  themes), motion (durations + easings), breakpoints (+ media helpers),
  zIndex.
- New `scripts/build-tokens.ts` generates `src/styles/tokens.css` from the
  TS sources.  Adds a `build:tokens` npm script (run automatically before
  `build`); `build:tokens:watch` available for active editing.
- `src/styles/tokens.css` is now AUTO-GENERATED.  Banner at the top of the
  file warns against hand-edits.
- `lightTheme.ts` is now a real AntD ThemeConfig (was an empty stub).
  Theme switching is one DOM attribute toggle (`data-theme="light"`) — no
  React re-render required, because every value resolves through CSS vars.

WHY
- Single source of truth: tokens edited in TS, types flow to all consumers,
  CSS regenerates deterministically.
- Layered shadows + fluid typography + motion tokens unblock the rest of the
  design-system roll-out (primitives, AppShell, Storybook, visual reg).
- Light theme parity restores the user-facing dark/light toggle that has
  been advertised but unimplemented.

COMPATIBILITY
- Every existing CSS variable name is preserved (`--brand`, `--bg-page`,
  `--text-primary`, `--space-1`, `--radius-md`, `--shadow-md`, etc).
- Legacy aliases (`--bg-app`, `--color-primary`, `--transition-base`, …)
  remain as pointers to the new canonical names.
- `darkTheme.ts` is unchanged.
- No component files modified.  Existing pages render identically.

NEXT
- PR 1b — layout + typography primitives (Stack, Cluster, Container, Heading, Text)
- PR 1c — form + surface primitives (Button, Input, Field, Card, Surface)
- PR 1d — AppShell refactor
- PR 1e — Storybook + visual regression infrastructure
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c6d0695f87

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/package.json
"jsdom": "^25.0.1",
"typescript": "~5.6.2",
"typescript-eslint": "^8.0.0",
"tsx": "^4.19.2",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Update lockfile after adding tsx to devDependencies

This change adds tsx to frontend/package.json but does not update frontend/package-lock.json, which makes the frontend install/build path fail in CI and local Docker builds that run npm ci (see .github/workflows/ci.yml and frontend/Dockerfile). npm ci requires package.json and lockfile to match exactly, so this commit can block all frontend pipelines until the lockfile is regenerated and committed.

Useful? React with 👍 / 👎.

textTransform?: 'uppercase' | 'lowercase' | 'capitalize' | 'none';
}

export const fontScale: Record<string, FontStep> = {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve literal font scale keys for exported type safety

Typing fontScale as Record<string, FontStep> widens the key type, so FontScaleKey becomes just string instead of the intended union ('xs' | 'sm' | ...). That removes compile-time validation for token keys and undermines the typed token API introduced in this commit, allowing invalid font-scale names to pass type checks in downstream code.

Useful? React with 👍 / 👎.

- Add tsx@4.19.2 to package-lock.json (required by build:tokens script)
- Drop unused eslint-disable directive in build-tokens.ts

Local CI parity verified:
- npm run lint                  → 0 errors (only pre-existing warnings)
- npx tsc -b --noEmit           → clean
- npm run build (incl. tokens)  → succeeds
- npm test                      → 101/101 pass
@barach6662001-bit barach6662001-bit deleted the replit/phase-1a-design-tokens branch April 24, 2026 09:18
@barach6662001-bit barach6662001-bit restored the replit/phase-1a-design-tokens branch April 24, 2026 09:18
@barach6662001-bit barach6662001-bit merged commit 128a12a into main Apr 24, 2026
5 checks passed
@barach6662001-bit barach6662001-bit deleted the replit/phase-1a-design-tokens branch April 24, 2026 09:24
barach6662001-bit added a commit that referenced this pull request Apr 24, 2026
…ason-audit

docs: record PR #612 + #616 completion, tighten theme lock, add tech …
barach6662001-bit added a commit that referenced this pull request Apr 24, 2026
…[Phase 1f] (#625)

Finishes the DashboardV2 row-card migration. Both remaining sibling
  panels (OperationsTimeline in row 4, UpcomingPanel in row 5) now use
  the design-system <Card> primitive instead of the local `s.card`
  wrapper. Combined with Phase 1d (WarehouseSnapshot) and Phase 1e
  (AlertsPanel), every dashboard surface in this row is now driven by
  the same primitive.

  Wrapper migration (DashboardV2.tsx)
  -----------------------------------
  - <div className={s.card}><OperationsTimeline …/></div> → <Card>…</Card>
  - <div className={s.card}><UpcomingPanel …/></div>     → <Card>…</Card>

  Both sites are pure wrapper swaps. <Card> defaults
  (variant=subtle, radius=xl=16px, padding=5=20px, bordered=true) are
  an exact drop-in for the legacy `.card` rule, so the visual contract
  (background, border, radius, padding) is preserved. The internal
  list/item content of each panel is untouched.

  CSS dead-code removal (DashboardV2.module.css)
  ----------------------------------------------
  With both consumers gone, these rules become unreferenced and are
  deleted (≈39 lines):
  - .card                       (background, border, radius, padding, transition)
  - .card:hover                 (subtle background lift)
  - .card::before               (decorative top hairline)
  - .cardHeader                 (flex justify-between row, never used in DashboardV2.tsx)
  - .cardLink, .cardLink:hover  (eyebrow link button, never used in DashboardV2.tsx)
  A short tombstone comment is left in place so future readers see why
  the section is empty and where to look (Card primitive path).

  Out of scope
  ------------
  - No route changes
  - No API changes
  - No business-logic changes
  - No refactor of inner panel markup
  - No new dependencies
  - No Card highlight prop introduction
  - No new tests (spec: only update if coverage exists; none did)

  Verification (local)
  --------------------
  - frontend tsc -b: clean
  - frontend lint: 0 errors (warning count unchanged)
  - vitest design-system + dashboard subset: 67/67 passing
  - Full test + build run delegated to CI.

  Phase 1 status after this PR
  ----------------------------
  - ✅ 1a — TS tokens (#616)
  - ✅ 1b — Layout + Typography primitives (#620)
  - ✅ 1c — PageHeader migration (#621)
  - ✅ 1d — Surface + Card primitives + first dashboard adoption (#622)
  - ✅ 1e — AlertsPanel adoption (#624)
  - ✅ 1f — OperationsTimeline + UpcomingPanel adoption (this PR)

Co-authored-by: replit-agent <agent@replit.local>
barach6662001-bit added a commit that referenced this pull request Apr 27, 2026
…a/b/c (#641)

- Move PR #614 core (impersonation + /admin/users + /admin/audit-log) to Completed
- Promote PR #615 (Warehouse: grain receipt + inventory) to In progress
- Create new 'Deferred (post-core, before Phase B)' section for #614a/b/c
- Move #614a (/admin/system), #614b (/admin/catalogs), #614c (/admin/broadcast) to Deferred
- Reorder Upcoming to start with PR #616 (Notifications center)
- Update TZ.md: mark ПУНКТ 9 + 10 as [IN PROGRESS in PR #615]
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.

2 participants