Update OKF docs bundle, README, and CLAUDE.md for today's features

Documents the shift planning and closure/payroll modules (new tables,
routes, stores), the dark redesign, and the docker-compose-broken-host
workaround. Adds CLAUDE.md pointing agents at docs/. Translates README to
English and keeps host-specific infrastructure details out of the repo.
This commit is contained in:
Michal Pemcak
2026-08-16 18:35:56 +02:00
parent f917ed06a8
commit 94933cac5c
19 changed files with 728 additions and 106 deletions

View File

@@ -1,45 +1,97 @@
---
type: Design Language
title: TUI monochrome design system
description: How the light-mono-tui design language is implemented in this app's CSS.
resource: frontend/src/styles/tui.css
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-12T00:00:00Z
timestamp: 2026-08-16T00:00:00Z
---
# TUI monochrome design system
# Dark modern design system
The full design language spec lives outside this bundle at
`~/doc/concepts/ui/light-mono-tui.md` (grey background, black type/borders,
mono font, inverted active/hover states, no accent color, no radius, no
shadow). This doc covers how EatMe implements it.
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).
`frontend/src/styles/tui.css` defines the tokens (`--bg`, `--fg`, `--muted`,
`--hover`, `--empty`, `--panel`, `--font`) and the component classes built on
them: `.tabs`/`.tab`, `.btn`/`.btn-block`/`.btn-ghost`, `.panel`,
`.field-row`, `.list`/`.row`, `.badge` (`-solid`, `-dashed`, `-double`),
`.stat-grid`/`.stat-tile`, `.login-card`.
# 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
`<input type="date">` 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
Built for this app, following the same rules (square edges, monochrome,
1px borders) rather than introducing new visual language:
- **`.bar-chart-*`** (`frontend/src/components/BarChart.tsx`) — the
per-employee daily-hours chart. Y-axis labels + a repeating 1px
`--empty`-colored gridline background at 25% steps computed from a
"nice" rounded max (`Math.ceil` to the next whole hour); bars are solid
`--fg`, `--muted` on hover; 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.
- **`.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 [>]`
bordered strip, styled like the design language's tab strip. Deliberately
placed *inside* the employee-detail panel next to the chart it controls,
not as a page-level control — an earlier version put it at the top of the
whole admin stats page, which tested as confusing ("can't browse history
on the chart") since it was visually disconnected from what it affected.
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)