# Design Notes — todo.martin-bierschenk.de v2

> Visual reference: `Todo Calendar Redesign v2.html`
> Aesthetic: 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)

1. **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.
2. **Touch JSX + CSS only.** New CSS variables / Tailwind tokens are fine; new state, new effects, new dependencies are not.
3. **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.
4. **Keep existing component file structure** (`WeeklyCalendarView.tsx`, `TaskList.tsx`, `CalendarEventModal.tsx`, etc.). Only edit them.
5. **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**: `Fraunces` italic — used **only** for the small quote in the header bar
- **Mono / numerals**: `Geist Mono` if needed; otherwise rely on `font-variant-numeric: tabular-nums` for 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)` or `0 4px 16px rgba(0,0,0,.06)`. Never bigger.
- Hover surfaces: `rgba(0,0,0,.05)` for icons, `rgba(0,0,0,.025)–.04` for text hits

### Motion

- All transitions: `120–180ms`, `cubic-bezier(.2,.8,.2,1)` for sliding panels, plain `ease` for 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×64px` chevron 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-2` 13px/500; quote = `--ink-4` 12px italic; ellipsize at ~480px

### 3.2 Left rail (`lside`)

Order, top to bottom:
1. **Date nav cluster** — `«  ‹` row, "Heute" pill (uppercase, hairline border), `›  »` row
2. Hairline separator
3. **View flyout** — calendar icon; on hover, flyout reveals: Einfach / Kalender / Liste / Kanban / Ziel
4. **Day-count flyout** — grid icon; flyout: 1 / 2 / 3 / 5 / 7
5. **Zeitfenster flyout** — clock icon; flyout: 15m / 20m / 30m / 60m
6. Hairline separator
7. Action icons (vertical stack): plus, calendar-pick, projects, recurring, target, focus
8. Hairline separator
9. Undo, redo, sync, download, print
10. Hairline separator
11. **Light/dark toggle** (single sun/moon icon — toggles, not two icons)
12. **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, padding `10px 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 `--ink` underline below each header
- **Today**: weekday in `--accent` red 700, blue-grey `--accent-soft` background, 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 (`--line` color, 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 `--accent` red across the today column, with an 8×8 dot on the left and a small time pill (`HH:MM`) on the right with `bg: 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 tasks
- `money` — finance / banking
- `book` — Legasthenie / Nachhilfe
- `home` — Garde / home
- `key`, `cake`, `car` — category notes
- `bolt` — focus / quick task
- `pin`, `info` — generic

### 3.7 Anyday tasks (`tasks`)

- Section background: `--tasks-bg` (`#f4f2ee` warm light grey)
- 6-up grid of white list cards (`--paper`, 1px `--line`, 8px radius, `min-height: 200px`, padding `12px 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-soft` underneath
- **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

### 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-auth` wiring, 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

1. **`feat(design): add tokens`** — CSS variables / tailwind extend, no markup changes
2. **`feat(design): app shell + header + corner buttons`** — top-level layout
3. **`feat(design): left rail`** — collapse old toolbar into rail with flyouts
4. **`feat(design): right settings drawer`** — slide-in panel
5. **`feat(design): day grid`** — hairline rules, no verticals, today wash, day headers
6. **`feat(design): all-day strip`** — solid chip pills
7. **`feat(design): events`** — source-coloured cards + note variant + source icons
8. **`feat(design): anyday tasks`** — segmented tabs + 6-up white cards on warm grey
9. **`chore(design): typography pass`** — Geist + Fraunces, sizes from §1
10. **`chore(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 `theme` system 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.*
