14 KiB
Design Notes — todo.martin-bierschenk.de v2
Visual reference:
Todo Calendar Redesign v2.htmlAesthetic: Minimal Scandinavian / TeuxDeux-style hairline editorial Goal: a calm, airy, paper-like weekly planner. Restyle only — no logic, routing, data, sync, or component-API changes.
0 · Rules of engagement (read first)
- Do not change behaviour. Keep all existing hooks, server actions, NextAuth wiring, calendar sync, recurring-task logic, drag-and-drop, keyboard shortcuts, and component prop shapes exactly as they are.
- Touch JSX + CSS only. New CSS variables / Tailwind tokens are fine; new state, new effects, new dependencies are not.
- One component per commit. Visual restyles are easy to review (and revert) when scoped. Suggested order: tokens → layout shell → day grid → all-day strip → events → tasks (anyday) → left rail → right settings → header.
- Keep existing component file structure (
WeeklyCalendarView.tsx,TaskList.tsx,CalendarEventModal.tsx, etc.). Only edit them. - Where this doc and the HTML mock disagree, the mock wins for visuals. Where the mock and the existing code disagree on behaviour, the existing code wins.
1 · Design tokens
Add these as CSS custom properties (or extend tailwind.config.js theme.extend). All other colors should be derived from these.
Color
keep the colors for now
Calendar-source palette (event chips, muted on purpose — they should not compete with the today-red):
| Source | Background | Border-left | Title color | Meta color |
|---|---|---|---|---|
| Default/work | #eef2f7 |
#6c87a8 |
#2b3f57 |
#6c87a8 |
Family (.fam) |
#fbeef0 |
#b85a6a |
#5a2530 |
#99536a |
Finance (.fin) |
#f6f0e2 |
#a88a3c |
#4a3a14 |
#8a6f2a |
Dev/GitHub (.dev) |
#ecf3ed |
#5a7a4a |
#2c4527 |
#5a7a4a |
Note (.note) |
transparent | none | var(--ink-2) |
var(--ink-4) |
All-day chip palette (solid pills above the day headers):
| Variant | Background | Text |
|---|---|---|
| Default | #b8b8b0 |
#fff |
Family (.fam) |
#e88a8a |
#fff |
Special (.special, anniversaries, milestones) |
#f4d588 |
#6b4f10 |
Typography
- UI / sans:
Geist, fallback-apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif - Editorial / serif:
Frauncesitalic — used only for the small quote in the header bar - Mono / numerals:
Geist Monoif needed; otherwise rely onfont-variant-numeric: tabular-numsfor any clock/date/count
Body letter-spacing: -0.005em baseline.
| Role | Size | Weight | LH | Other |
|---|---|---|---|---|
| Section h3 | 16px | 600 | 1.2 | |
Day name (.dn) |
16px | 600 | 1 | uppercase, letter-spacing: 0.04em |
| Day name — today | 16px | 700 | 1 | color: --accent |
Day date (.dnum) |
11px | 400 | 1 | uppercase, tabular-nums, color: --ink-4 |
Header KW (.wk) |
13px | 500 | — | letter-spacing: 0.02em |
| Header quote | 12px | 400 | — | Fraunces italic, --ink-4 |
| Event title | 12px | 500 | 1.25 | |
| Event note title | 11.5px | 400 | 1.25 | |
| Event meta / time | 10.5px | 400 | — | tabular-nums |
| All-day chip | 11px | 500 | 1.2 | |
List heading (h4) |
12px | 500 | — | uppercase, letter-spacing: 0.04em |
| List item | 12px | 400 | 1.35 | |
| Hour label | 10px | 400 | — | tabular-nums, color: --ink-5 |
| Tasks tab | 12px | 500/600 | — | active is 600 |
| Tab counter chip | 10.5px | 500 | 1.4 | tabular-nums |
Spacing & geometry
- Left rail: 56px wide, fixed
- Right settings drawer: 360px wide, slides in from the right (
transform: translateX(100%)→translateX(0),cubic-bezier(.2,.8,.2,1)250ms) - Permanent top header: 36px tall, white, hairline bottom
- Day grid hour-row height: 56px
- Day grid column gap: 20px
- Day grid horizontal padding: 24px
- Border radius: 4px (events), 6px (corner buttons, inputs), 7–8px (list cards, segmented pills), 10px (tasks tab pill container)
- All shadows are tiny:
0 1px 2px rgba(0,0,0,.06)or0 4px 16px rgba(0,0,0,.06). Never bigger. - Hover surfaces:
rgba(0,0,0,.05)for icons,rgba(0,0,0,.025)–.04for text hits
Motion
- All transitions:
120–180ms,cubic-bezier(.2,.8,.2,1)for sliding panels, plaineasefor hover - The right drawer is the only large transform; everything else is opacity / background swaps
2 · Layout shell
┌─────────────────────────── header (36px, always visible) ───┐
│ KW 19 | 4–10. Mai 2026 "quote…" │
├──────┬────────────────────────────────────────────────┬─────┤
│ │ all-day strip │ │
│ left │────────────────────────────────────────────────│ rt │
│ rail │ day-headers row │ drw │
│ 56px │────────────────────────────────────────────────│ 360 │
│ │ day grid (hours × columns) │ px │
│ │────────────────────────────────────────────────│ off │
│ │ tasks (anyday) — warm grey, 6 white list cards │ scr │
└──────┴────────────────────────────────────────────────┴─────┘
- The toolbar is gone. Only two floating icon buttons remain: a sidebar-toggle top-left of the header, a search top-right.
- The right drawer is hidden by default. A small
18×64pxchevron tab on the right edge toggles it; the gear icon in the left rail also toggles it.
3 · Component-by-component restyle guide
3.1 Top header (header)
position: sticky/absolute,top: 0, height 36px, white, hairline bottom- Centered:
KW WW | 4–10. Mai 2026• faint Fraunces italic quote - Text colors: KW =
--ink-213px/500; quote =--ink-412px italic; ellipsize at ~480px
3.2 Left rail (lside)
Order, top to bottom:
- Date nav cluster —
« ‹row, "Heute" pill (uppercase, hairline border),› »row - Hairline separator
- View flyout — calendar icon; on hover, flyout reveals: Einfach / Kalender / Liste / Kanban / Ziel
- Day-count flyout — grid icon; flyout: 1 / 2 / 3 / 5 / 7
- Zeitfenster flyout — clock icon; flyout: 15m / 20m / 30m / 60m
- Hairline separator
- Action icons (vertical stack): plus, calendar-pick, projects, recurring, target, focus
- Hairline separator
- Undo, redo, sync, download, print
- Hairline separator
- Light/dark toggle (single sun/moon icon — toggles, not two icons)
- User avatar at the bottom (
margin-top: auto)
Icons are 16px, currentColor, in 36×36 hit-targets, border-radius: 8px, hover background rgba(0,0,0,.05). Active state uses --accent-soft background + --accent color.
Flyouts pop right of the rail with a subtle pointer triangle.
3.3 All-day strip (allday)
- Grid:
56px [hour gutter pad] repeat(N, 1fr), column gap 20px, padding10px 24px 0 - Per-day column:
min-height: 56px, vertical stack of chips, gap 3px - Chips are solid colored pills (see palette table). No icons, no date pips inside.
- Today's column gets
background: var(--accent-soft)with extra horizontal padding - Small uppercase label "GANZTAGS" 9px in left gutter
3.4 Day headers (days + dayh)
- Grid identical to all-day strip (same column gaps for alignment)
- Each header: small MAI 6 date on top, large MITTWOCH weekday name below, both uppercase
- 2px solid
--inkunderline below each header - Today: weekday in
--accentred 700, blue-grey--accent-softbackground, centered, padding 6px 8px, 1px ink underline - Weekend (Sat/Sun): weekday red, underline red
3.5 Day grid body (body)
- No vertical lines between days — the column gap (20px) is the separator. This is the TeuxDeux move.
- Horizontal hour rules only (
--linecolor, 1px), one per hour - Hour labels in the left gutter, 10px,
--ink-5, right-aligned, sitting on the rule (background-cut) - Today column gets
background: var(--accent-soft)(full height) - Now-line: 1px
--accentred across the today column, with an 8×8 dot on the left and a small time pill (HH:MM) on the right withbg: var(--bg)for clean cutout
3.6 Events (ev)
Two visual modes:
Timed event card — coloured background by source, 2px left-border accent, border-radius: 4px, padding: 8px 10px. Title row has an inline 16px source icon (.t .src) before the text. Synced events show a small sync arrow at top-right (.sync, opacity .55). Meta line: HH:MM – HH:MM · Location.
Note event (.ev.note) — for todos placed at a time but without a duration block: transparent background, no border-left, no rounding, just small inline icon + text. Used for github-source items, key/cake/car category notes, etc.
Source icon mapping (16px, currentColor SVG):
git— github / dev tasksmoney— finance / bankingbook— Legasthenie / Nachhilfehome— Garde / homekey,cake,car— category notesbolt— focus / quick taskpin,info— generic
3.7 Anyday tasks (tasks)
- Section background:
--tasks-bg(#f4f2eewarm light grey) - 6-up grid of white list cards (
--paper, 1px--line, 8px radius,min-height: 200px, padding12px 12px 8px) - Card heading: 6px colored dot · uppercase project name · count chip on right
- Each item: 9×9 unchecked box (1px
--ink-5) · text · hairline--line-softunderneath - Tabs above the grid are a segmented-pill control:
- Container:
inline-flex,padding: 4px,bg: rgba(0,0,0,.05),border-radius: 10px - Active tab: white pill, weight 600, shadow
0 1px 2px rgba(0,0,0,.06), 0 0 0 1px rgba(0,0,0,.04) - Inactive: text
--ink-3, hover white-50 background - Each tab has a count chip — small grey rounded-rect, tabular-nums
- Container:
3.8 Right settings drawer (rside)
- 360px white panel, slides in from right edge
- Vertical icon-tab strip across the top (settings, globe, link, sync, box, user, palette, spark)
- Each row: small label (11px
--ink-3, weight 500) + input/checkbox/segmented control - Inputs: 1px
--line, 6px radius, 7px 10px padding, 13px--ink-2 - Help text under fields: 10px
--ink-4 - Sections separated by full-bleed
--line<hr> - Close
×top-right; clicking the gear icon in the left rail or the edge tab toggles it
3.9 Floating corner buttons
- 28×28, 6px radius,
top: 8px - Left: sidebar-toggle. Right: search.
- These sit on top of the header bar.
4 · Iconography
All icons are 16px, currentColor, 1.4 stroke-width SVG, drawn on a 20×20 viewBox, no fill (line-art). Examples: cal, list, kanban, target, grid, clock, search, plus, proj, repeat, bolt, moon, sun, setg, sync, print, user, download, sidebar, chevL/R, eye, undo, redo, refresh, sliders, globe, link, box, palette, spark, info, money, git, book, home, car, key, cake.
Hover icons go from --ink-3 → --ink. Active state for view/filter icons goes from --ink-3 → --accent on --accent-soft background.
5 · What to keep from the existing app
- All data shapes, server actions, API routes
next-authwiring, middleware- Drag-and-drop calendar event editing
- Recurring task logic
- Calendar-sync flows (Google etc.)
- Keyboard shortcuts
- Print view (we can restyle it, but keep the print route)
6 · Suggested PR breakdown
feat(design): add tokens— CSS variables / tailwind extend, no markup changesfeat(design): app shell + header + corner buttons— top-level layoutfeat(design): left rail— collapse old toolbar into rail with flyoutsfeat(design): right settings drawer— slide-in panelfeat(design): day grid— hairline rules, no verticals, today wash, day headersfeat(design): all-day strip— solid chip pillsfeat(design): events— source-coloured cards + note variant + source iconsfeat(design): anyday tasks— segmented tabs + 6-up white cards on warm greychore(design): typography pass— Geist + Fraunces, sizes from §1chore(design): icon set swap— 16px line-art set
Each PR small enough to eyeball. After step 9 the app should look like the mock; step 10 is polish.
7 · Open questions for the engineer
- Is Geist already loaded? If not, add it via
next/font(don't pull from Google Fonts at runtime). - Does the existing
themesystem support multiple accent colors per calendar source, or is that a new concept? If new, hold off on the per-source event colors and ship the today-red + neutral-event scheme first. - Confirm dark mode is in scope — the mock is light-only; tokens for dark would need to be derived in a follow-up.
End of notes. When in doubt, open Todo Calendar Redesign v2.html in a browser and copy what you see.