--- type: Design Language title: Dark modern design system description: How EatMe's dark, sharp-edged, amber-accent design system is implemented in frontend/src/styles/theme.css. resource: frontend/src/styles/theme.css tags: [frontend, design, css] timestamp: 2026-08-16T00:00:00Z --- # Dark modern design system Replaced the original light monochrome TUI style (mono font, `~/doc/concepts/ui/light-mono-tui.md`) on 2026-08-16, on explicit request — the TUI look read as dated to the app's actual end users. All tokens and component classes live in `frontend/src/styles/theme.css` (was `tui.css` — renamed since "TUI" stopped being an accurate description). # Rules this design follows - **Dark background, sharp corners.** `--radius-lg`/`--radius`/`--radius-sm` are all `0` — deliberately, per explicit user preference against rounded corners even in an otherwise "modern SaaS" direction. - **One accent color, used sparingly.** `--accent` (warm amber, `#f2a93b`) marks state, not decoration: the active tab, "this shift is mine", today's calendar cell, focus rings. It is *not* used as a per-card or per-row accent border. - **No colored border-left/border-right accent stripes.** Explicitly rejected during design — a common AI-generated-UI tic. Emphasis instead comes from filled backgrounds (`.badge-solid`, `.tab.active`, `.calendar-slot.is-mine`) or a full inset ring around the whole element (`.month-calendar-cell.is-today`, `.month-calendar-day-btn.is-selected`), never a single colored edge. - **System sans-serif for body text**, `--font-mono` reserved for numbers/ timestamps that benefit from tabular alignment (`.stat-value`, calendar time chips, the bar chart's axis labels) — a common dashboard convention (Linear, Vercel), not an all-monospace TUI throwback. - **Neutral hairline dividers**, not colored ones. `.list`/`.row`, `.stat-grid`, and the calendar grid all use a 1px `--border`-colored gap/border for internal separators. - **`color-scheme: dark`** is set globally so native form controls (date/ time pickers, number spinners) render dark by default — otherwise bare `` etc. render as light-mode browser chrome floating in an otherwise-dark page, which is what a generic `input, select` base rule plus this fixes. # Tokens `--bg`, `--surface` (panels), `--surface-hover`, `--surface-2` (nested/ input backgrounds), `--border`, `--border-strong`, `--fg`, `--muted`, `--muted-2`, `--accent`, `--accent-strong`, `--accent-fg` (text color for content sitting *on* the accent), `--radius-lg`/`--radius`/`--radius-sm` (all `0`), `--shadow-sm`/`--shadow-md`, `--font`, `--font-mono`. # Component classes Same class names as the previous TUI stylesheet — this was a pure CSS rewrite, no component file needed to change: `.tabs`/`.tab`, `.btn`/`.btn-block`/`.btn-ghost`, `.panel`, `.field-row`, `.list`/`.row`, `.badge` (`-solid`, `-dashed` — both restyled as pills, no more literal dashed border), `.stat-grid`/`.stat-tile`, `.login-card`, `.month-calendar-*`, `.calendar-slot`/`.calendar-chip`. `.badge-double` (from the old TUI system) was dropped — it had no remaining usages. There's intentionally only one `.btn` visual style (no `.btn-primary`) — introducing a primary/secondary distinction would have meant touching every component that renders a button to classify its actions, which was out of scope for a CSS-only redesign pass. # App-specific additions - **`.bar-chart-*`** (`frontend/src/components/BarChart.tsx`) — bars are `--accent`-filled with a rounded top edge only, y-axis and day labels in `--font-mono`; day-of-month labels render in a *separate* flex row below the fixed-height bar track (not nested inside each bar's percentage- height column) specifically to avoid the bars visually overlapping the labels. - **`.month-nav`** (`frontend/src/components/MonthNav.tsx`) — `[<] label [>]` segmented-control strip. Placed *inside* the panel it controls (employee detail chart, shift calendar, closure card), not as a page-level control — an earlier version put it at the top of the whole admin stats page, which tested as confusing since it was visually disconnected from what it affected. - **`.month-calendar-*`** (`frontend/src/components/MonthCalendar.tsx`) — shared 7-column Monday-first grid used by both [`ShiftPlanning`](/docs/frontend/index.md) (employee) and [`ShiftPlanManager`](/docs/frontend/index.md) (admin), via a `renderDay(dateStr, dayNumber)` render-prop rather than two separate calendar implementations. The employee view renders interactive slot buttons directly in each cell; the admin view renders compact read-only chips and a day-select button, since full slot editing (capacity, notes, assign dropdown) doesn't fit in a calendar cell — clicking a day opens a detail panel below the grid instead. # Related - [Zustand stores](./stores.md) - [System overview](/docs/architecture/overview.md)