docs(07): fix UI-SPEC typography to 2-weight contract

Collapse 3 font weights (400/500/600) to 2 (400/600) per checker
requirement. Labels now use semibold (600) instead of medium (500).
Also improves CTA labels and adds focal point declaration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-20 20:30:50 +02:00
parent 272af4ec98
commit 3c937e68bc

View File

@@ -48,14 +48,16 @@ Exceptions: Sticky allocation bar uses 12px vertical padding (py-3) for visual c
| Role | Size | Weight | Line Height | | Role | Size | Weight | Line Height |
|------|------|--------|-------------| |------|------|--------|-------------|
| Body | 14px | 400 (regular) | 1.5 | | Body | 14px | 400 (regular) | 1.5 |
| Label | 14px | 500 (medium) | 1.4 | | Label | 14px | 600 (semibold) | 1.4 |
| Heading | 20px | 600 (semibold) | 1.2 | | Heading | 20px | 600 (semibold) | 1.2 |
| Display | 28px | 600 (semibold) | 1.2 | | Display | 28px | 600 (semibold) | 1.2 |
Only two weights are used: 400 (regular) for body text and 600 (semibold) for labels, headings, and display. No medium (500) weight exists in this contract.
Usage in wizard: Usage in wizard:
- **Display (28px/600):** Wizard page title "Set up your budget" (step 1 heading area) - **Display (28px/600):** Wizard page title "Set up your budget" (step 1 heading area)
- **Heading (20px/600):** Step card titles ("Monthly Income", "Recurring Items", "Review") - **Heading (20px/600):** Step card titles ("Monthly Income", "Recurring Items", "Review")
- **Label (14px/500):** Category group headers (e.g., "Bills", "Variable Expenses"), stepper step labels, "Remaining to allocate" label, form field labels - **Label (14px/600):** Category group headers (e.g., "Bills", "Variable Expenses"), stepper step labels, "Remaining to allocate" label, form field labels
- **Body (14px/400):** Preset item names, amounts, helper text, step descriptions - **Body (14px/400):** Preset item names, amounts, helper text, step descriptions
--- ---
@@ -69,9 +71,11 @@ Usage in wizard:
| Accent (10%) | `oklch(0.55 0.15 260)` (--primary) | Active stepper step indicator, primary CTA buttons, step number circles (active) | | Accent (10%) | `oklch(0.55 0.15 260)` (--primary) | Active stepper step indicator, primary CTA buttons, step number circles (active) |
| Destructive | `oklch(0.6 0.2 25)` (--destructive) | Negative "remaining to allocate" text, validation error text | | Destructive | `oklch(0.6 0.2 25)` (--destructive) | Negative "remaining to allocate" text, validation error text |
**Focal point:** The primary CTA button ("Next Step" / "Complete Setup") in the bottom-right of the card is the single focal point on every step. It is the only large accent-colored element in the viewport, drawing the eye to the next action.
Accent reserved for: Accent reserved for:
- Active step circle in the stepper (filled primary background) - Active step circle in the stepper (filled primary background)
- "Next" and "Complete Setup" primary buttons - "Next Step" and "Complete Setup" primary buttons
- Income input focus ring - Income input focus ring
- Completed step checkmark icon color - Completed step checkmark icon color
@@ -99,7 +103,7 @@ Additional semantic colors used (existing tokens):
| Component | Where | | Component | Where |
|-----------|-------| |-----------|-------|
| `Card`, `CardHeader`, `CardContent` | Wizard step container, review summary | | `Card`, `CardHeader`, `CardContent` | Wizard step container, review summary |
| `Button` | Next, Back, Skip, Skip setup, Complete Setup | | `Button` | Next Step, Go Back, Skip Step, Skip setup, Complete Setup |
| `Input` | Income amount (step 1), per-item amount editing (step 2) | | `Input` | Income amount (step 1), per-item amount editing (step 2) |
| `Badge` | Category type indicators next to preset items | | `Badge` | Category type indicators next to preset items |
| `Label` | Form field labels | | `Label` | Form field labels |
@@ -137,12 +141,12 @@ Full viewport height, centered content:
Position: Above the card, inside the content wrapper Position: Above the card, inside the content wrapper
Layout: flex items-center justify-center gap-8 Layout: flex items-center justify-center gap-8
Each step: Each step:
- Circle: 32px (w-8 h-8), centered number text (14px/500) - Circle: 32px (w-8 h-8), centered number text (14px/600)
- Active: bg-primary text-primary-foreground - Active: bg-primary text-primary-foreground
- Completed: bg-primary text-primary-foreground with Check icon (16px) - Completed: bg-primary text-primary-foreground with Check icon (16px)
- Upcoming: bg-muted text-muted-foreground border border-border - Upcoming: bg-muted text-muted-foreground border border-border
- Connector line between steps: h-px w-16 bg-border (completed: bg-primary) - Connector line between steps: h-px w-16 bg-border (completed: bg-primary)
- Step label below circle: text-xs font-medium text-muted-foreground (active: text-foreground) - Step label below circle: text-xs font-semibold text-muted-foreground (active: text-foreground)
Clickable: Completed steps and current step only (not future steps) Clickable: Completed steps and current step only (not future steps)
Margin below stepper: 24px (mb-6) before the card Margin below stepper: 24px (mb-6) before the card
``` ```
@@ -158,20 +162,20 @@ CardContent: space-y-6
Bottom navigation row (inside CardContent, at the bottom): Bottom navigation row (inside CardContent, at the bottom):
- flex justify-between items-center pt-4 border-t border-border - flex justify-between items-center pt-4 border-t border-border
- Left: Back button (variant="ghost", hidden on step 1) + Skip button (variant="ghost", text-muted-foreground) - Left: Go Back button (variant="ghost", hidden on step 1) + Skip Step button (variant="ghost", text-muted-foreground)
- Right: Next button (variant="default", primary) or Complete Setup button (step 3) - Right: Next Step button (variant="default", primary) or Complete Setup button (step 3)
``` ```
### Step 1 — Income ### Step 1 — Income
``` ```
Card content: Card content:
- Label: "Monthly net income" (14px/500) - Label: "Monthly net income" (14px/600)
- Input row: flex items-center gap-2 - Input row: flex items-center gap-2
- Input: type="number", w-full, text-right, text-lg (18px), pre-filled "3000" - Input: type="number", w-full, text-right, text-lg (18px), pre-filled "3000"
- Currency suffix: text-muted-foreground text-sm, shows profile currency (e.g., "EUR") - Currency suffix: text-muted-foreground text-sm, shows profile currency (e.g., "EUR")
- Helper text below: "Enter your total monthly take-home pay" (14px/400, text-muted-foreground) - Helper text below: "Enter your total monthly take-home pay" (14px/400, text-muted-foreground)
- Validation: if empty or <= 0 on Next click, show destructive text below input: "Please enter a positive income amount" - Validation: if empty or <= 0 on Next Step click, show destructive text below input: "Please enter a positive income amount"
``` ```
### Step 2 — Recurring Items ### Step 2 — Recurring Items
@@ -180,7 +184,7 @@ Card content:
Allocation bar (sticky): Allocation bar (sticky):
- Position: sticky top-0 z-10, inside the card content area - Position: sticky top-0 z-10, inside the card content area
- Layout: flex justify-between items-center py-3 px-4 bg-muted border-b border-border - Layout: flex justify-between items-center py-3 px-4 bg-muted border-b border-border
- Left: "Remaining to allocate" (14px/500) - Left: "Remaining to allocate" (14px/600)
- Right: formatted amount (16px/600) - Right: formatted amount (16px/600)
- Positive or zero: text-on-budget (green) - Positive or zero: text-on-budget (green)
- Negative: text-destructive (red) - Negative: text-destructive (red)
@@ -189,7 +193,7 @@ Allocation bar (sticky):
Category groups (6 groups, ordered: income, bill, variable_expense, debt, saving, investment): Category groups (6 groups, ordered: income, bill, variable_expense, debt, saving, investment):
- CategoryGroupHeader: flex items-center gap-2 pt-4 pb-2 - CategoryGroupHeader: flex items-center gap-2 pt-4 pb-2
- Colored dot: w-2.5 h-2.5 (10px) circle using category color token - Colored dot: w-2.5 h-2.5 (10px) circle using category color token
- Group label: label (14px/500) using categoryLabels from palette.ts - Group label: label (14px/600) using categoryLabels from palette.ts
- Item count badge: text-xs text-muted-foreground "(4 items)" - Item count badge: text-xs text-muted-foreground "(4 items)"
- Separator below header: border-border - Separator below header: border-border
@@ -216,7 +220,7 @@ Default checked state:
Card content: Card content:
- Read-only summary, no editable fields - Read-only summary, no editable fields
- Income row: flex justify-between py-2 - Income row: flex justify-between py-2
- "Monthly income" (14px/500) - "Monthly income" (14px/600)
- Formatted amount (14px/600) - Formatted amount (14px/600)
- Separator - Separator
- Selected items grouped by category type (same order as step 2) - Selected items grouped by category type (same order as step 2)
@@ -226,7 +230,7 @@ Card content:
- Amount (14px/400, text-right) - Amount (14px/400, text-right)
- Separator - Separator
- Totals section: space-y-1 pt-2 - Totals section: space-y-1 pt-2
- "Total expenses" row: flex justify-between, 14px/500 - "Total expenses" row: flex justify-between, 14px/600
- "Remaining" row: flex justify-between, 16px/600 - "Remaining" row: flex justify-between, 16px/600
- Positive: text-on-budget - Positive: text-on-budget
- Negative: text-destructive - Negative: text-destructive
@@ -237,7 +241,7 @@ Card content:
### Skip Controls ### Skip Controls
``` ```
Per-step skip: Ghost button "Skip" in the bottom-left nav area Per-step skip: Ghost button "Skip Step" in the bottom-left nav area
- Advances to next step without saving current step data - Advances to next step without saving current step data
- On step 3 skip: same as "Skip setup" (exits wizard) - On step 3 skip: same as "Skip setup" (exits wizard)
@@ -256,13 +260,13 @@ Global skip: "Skip setup" link/button
| Action | Behavior | | Action | Behavior |
|--------|----------| |--------|----------|
| Click "Next" (step 1) | Validate income > 0. If valid, transition to step 2. If invalid, show inline error. | | Click "Next Step" (step 1) | Validate income > 0. If valid, transition to step 2. If invalid, show inline error. |
| Click "Next" (step 2) | No validation required (0 items selected is valid). Transition to step 3. | | Click "Next Step" (step 2) | No validation required (0 items selected is valid). Transition to step 3. |
| Click "Back" | Return to previous step. Preserve all entered data. | | Click "Go Back" | Return to previous step. Preserve all entered data. |
| Click stepper circle (completed) | Navigate to that step. Preserve all data. | | Click stepper circle (completed) | Navigate to that step. Preserve all data. |
| Click stepper circle (future) | No action. Cursor: default. | | Click stepper circle (future) | No action. Cursor: default. |
| Click "Complete Setup" (step 3) | Create categories + template items via API. On success: clear localStorage, set setup_completed=true, redirect to dashboard with toast. | | Click "Complete Setup" (step 3) | Create categories + template items via API. On success: clear localStorage, set setup_completed=true, redirect to dashboard with toast. |
| Click "Skip" (per-step) | Advance to next step without current step data. Step 1 skip: income stays at default or last entered value. Step 2 skip: uncheck all items. | | Click "Skip Step" (per-step) | Advance to next step without current step data. Step 1 skip: income stays at default or last entered value. Step 2 skip: uncheck all items. |
| Click "Skip setup" (global) | Exit wizard entirely. Clear localStorage. Mark setup_completed=true. Redirect to dashboard. No toast. | | Click "Skip setup" (global) | Exit wizard entirely. Clear localStorage. Mark setup_completed=true. Redirect to dashboard. No toast. |
| Page refresh mid-wizard | Restore wizard at the same step with all entered data from localStorage. | | Page refresh mid-wizard | Restore wizard at the same step with all entered data from localStorage. |
@@ -285,7 +289,7 @@ Cleared on: wizard completion OR skip setup
| State | Behavior | | State | Behavior |
|-------|----------| |-------|----------|
| Wizard loading (useFirstRunState pending) | Show centered Skeleton matching card dimensions (max-w-2xl, h-64) | | Wizard loading (useFirstRunState pending) | Show centered Skeleton matching card dimensions (max-w-2xl, h-64) |
| Completion API in progress | "Complete Setup" button shows spinner + disabled. Back/Skip also disabled. | | Completion API in progress | "Complete Setup" button shows spinner + disabled. Go Back/Skip Step also disabled. |
| Completion API failure | Toast (sonner, variant destructive): "Could not save your template. Please try again." Button re-enables. Data preserved. | | Completion API failure | Toast (sonner, variant destructive): "Could not save your template. Please try again." Button re-enables. Data preserved. |
| Partial completion failure | If categories created but template items fail: toast with "Some items could not be saved. Check your template page." Redirect to dashboard anyway. | | Partial completion failure | If categories created but template items fail: toast with "Some items could not be saved. Check your template page." Redirect to dashboard anyway. |
@@ -317,9 +321,9 @@ All copy must have i18n keys in both `en.json` and `de.json`. Keys live under a
| Step 3 remaining label | Remaining | `setup.step3.remainingLabel` | | Step 3 remaining label | Remaining | `setup.step3.remainingLabel` |
| Step 3 empty | No items selected. You can add items to your template later. | `setup.step3.empty` | | Step 3 empty | No items selected. You can add items to your template later. | `setup.step3.empty` |
| Stepper labels | Income / Items / Review | `setup.steps.1` / `setup.steps.2` / `setup.steps.3` | | Stepper labels | Income / Items / Review | `setup.steps.1` / `setup.steps.2` / `setup.steps.3` |
| Next button | Next | `setup.next` | | Next button | Next Step | `setup.next` |
| Back button | Back | `setup.back` | | Back button | Go Back | `setup.back` |
| Skip button | Skip | `setup.skip` | | Skip button | Skip Step | `setup.skip` |
| Skip setup link | Skip setup | `setup.skipSetup` | | Skip setup link | Skip setup | `setup.skipSetup` |
| Complete button | Complete Setup | `setup.complete` | | Complete button | Complete Setup | `setup.complete` |
| Success toast | Template created! Your first budget will appear automatically. | `setup.toast.success` | | Success toast | Template created! Your first budget will appear automatically. | `setup.toast.success` |