docs(phase-6): UI design contract for renderer architecture refactor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
530c2b2158
commit
e7d12719ed
1 changed files with 150 additions and 0 deletions
150
.planning/phases/06-renderer-architecture/06-UI-SPEC.md
Normal file
150
.planning/phases/06-renderer-architecture/06-UI-SPEC.md
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
---
|
||||
phase: 6
|
||||
slug: renderer-architecture
|
||||
status: draft
|
||||
shadcn_initialized: false
|
||||
preset: none
|
||||
created: 2026-04-09
|
||||
---
|
||||
|
||||
# Phase 6 — UI Design Contract
|
||||
|
||||
> Visual and interaction contract for the renderer architecture refactor. This phase ships zero visual changes -- the contract documents the existing v1.0 visual baseline as a regression guard.
|
||||
|
||||
---
|
||||
|
||||
## Design System
|
||||
|
||||
| Property | Value |
|
||||
|----------|-------|
|
||||
| Tool | none |
|
||||
| Preset | not applicable |
|
||||
| Component library | Tabler (Kimai host app) |
|
||||
| Icon library | not applicable (no icons in this phase) |
|
||||
| Font | `var(--tblr-font-sans-serif)` (inherited from Kimai/Tabler) |
|
||||
|
||||
**Note:** This plugin renders inside a Kimai dashboard card (`@theme/embeds/card.html.twig`). All surface colors, fonts, and border styles inherit from Tabler CSS custom properties. No standalone design system is used or needed.
|
||||
|
||||
---
|
||||
|
||||
## Spacing Scale
|
||||
|
||||
Declared values from existing v1.0 CSS (must remain unchanged after refactor):
|
||||
|
||||
| Token | Value | Usage |
|
||||
|-------|-------|-------|
|
||||
| cell-gap | 2px | Gap between heatmap cells (SVG attribute, not CSS) |
|
||||
| tooltip-pad | 6px 10px | Tooltip internal padding |
|
||||
| wrapper-gap | 16px | Gap between heatmap SVG area and filter dropdown |
|
||||
| stats-gap | 16px | Gap between stat items in footer row |
|
||||
| stats-top | 12px | Padding above stats row |
|
||||
| filter-top | 20px | Padding above filter dropdown (desktop) |
|
||||
|
||||
Exceptions: Cell size and margins are controlled by `HeatmapConfig` in TypeScript (not CSS). These values must transfer unchanged to `DEFAULT_CONFIG` in the refactored code.
|
||||
|
||||
---
|
||||
|
||||
## Typography
|
||||
|
||||
All typography inherits from Kimai/Tabler. The plugin declares only two overrides:
|
||||
|
||||
| Role | Size | Weight | Line Height | Source |
|
||||
|------|------|--------|-------------|--------|
|
||||
| SVG label | 10px | 400 (normal) | default | `.heatmap-label` in heatmap.css |
|
||||
| Tooltip / Stats | 0.8125rem (13px) | 400 (normal) | default | `.heatmap-tooltip`, `.heatmap-stats` |
|
||||
| Stat value | 0.8125rem (13px) | 600 (semibold) | default | `.heatmap-stats .stat-value` |
|
||||
|
||||
No new typography tokens in this phase.
|
||||
|
||||
---
|
||||
|
||||
## Color
|
||||
|
||||
All colors use Tabler CSS custom properties. The plugin does not declare its own palette.
|
||||
|
||||
| Role | Value | Usage |
|
||||
|------|-------|-------|
|
||||
| Body text | `var(--tblr-body-color)` | SVG labels, stat values, tooltip text |
|
||||
| Surface | `var(--tblr-bg-surface)` | Tooltip background |
|
||||
| Surface secondary | `var(--tblr-bg-surface-secondary)` | Empty heatmap cells |
|
||||
| Border | `var(--tblr-border-color)` | Tooltip border |
|
||||
| Secondary text | `var(--tblr-secondary, #6c757d)` | Stat labels |
|
||||
| Heatmap scale | `['#9be9a8', '#40c463', '#30a14e', '#216e39']` | Cell fill intensity (4-step quantize) |
|
||||
|
||||
**Regression constraint:** The 4-color heatmap scale array must remain identical in `shared/color-scale.ts` after extraction. These are hardcoded GitHub-green values, not Tabler variables.
|
||||
|
||||
Accent reserved for: not applicable (no accent color in this phase).
|
||||
|
||||
---
|
||||
|
||||
## Copywriting Contract
|
||||
|
||||
Phase 6 introduces no new copy. Existing copy must survive the refactor unchanged:
|
||||
|
||||
| Element | Copy | Location after refactor |
|
||||
|---------|------|------------------------|
|
||||
| Tooltip: date line | `{formatted date}` | `shared/tooltip.ts` |
|
||||
| Tooltip: hours line | `{N}h {M}m` | `shared/tooltip.ts` |
|
||||
| Tooltip: entries line | `{N} entries` | `shared/tooltip.ts` |
|
||||
| Stats: streak | `Current streak: {N} days` | `shared/stats.ts` |
|
||||
| Stats: total | `Total: {N}h` | `shared/stats.ts` |
|
||||
| Stats: average | `Daily avg: {N}h` | `shared/stats.ts` |
|
||||
| Stats: busiest | `Busiest: {date}` | `shared/stats.ts` |
|
||||
| Empty state | No explicit empty state (heatmap renders with all-empty cells) | `renderers/year.ts` |
|
||||
| Error state | No explicit error state (console.error only) | `heatmap.ts` orchestrator |
|
||||
| Primary CTA | not applicable (no user actions beyond hover/click) | -- |
|
||||
| Destructive confirmation | not applicable (no destructive actions) | -- |
|
||||
|
||||
---
|
||||
|
||||
## Interaction Contract
|
||||
|
||||
No new interactions. Existing interactions must work identically after refactor:
|
||||
|
||||
| Interaction | Behavior | Must survive in |
|
||||
|-------------|----------|-----------------|
|
||||
| Cell hover | Show tooltip with date, hours, entry count | `shared/tooltip.ts` + renderer |
|
||||
| Cell click | Navigate to Kimai timesheet filtered by date | `RenderContext.onCellClick` callback |
|
||||
| Cell hover (weekend) | Same tooltip, slightly reduced opacity (0.65 vs 0.75) | `.heatmap-weekend:hover` CSS (unchanged) |
|
||||
| Filter select change | Re-render heatmap with filtered project data | `heatmap.ts` orchestrator via `HeatmapState.filters` |
|
||||
| Window resize | Re-render to fit container width | `heatmap.ts` orchestrator (resize listener) |
|
||||
|
||||
---
|
||||
|
||||
## Regression Checklist
|
||||
|
||||
These visual properties must be pixel-identical before and after the refactor:
|
||||
|
||||
- [ ] Cell border-radius: `rx=2 ry=2`
|
||||
- [ ] Cell hover opacity: `0.75` (normal), `0.65` (weekend)
|
||||
- [ ] Tooltip shadow: `0 2px 8px rgba(0,0,0,0.12)`
|
||||
- [ ] Tooltip border-radius: `4px`
|
||||
- [ ] Empty cell fill: `var(--tblr-bg-surface-secondary)`
|
||||
- [ ] Heatmap color scale: 4 greens `#9be9a8 #40c463 #30a14e #216e39`
|
||||
- [ ] Stats layout: flex row with `16px` gap, wrapping
|
||||
- [ ] SVG month/day labels: `10px` sans-serif
|
||||
- [ ] Filter dropdown position: right side on desktop, above on mobile (<1330px)
|
||||
- [ ] Scroll behavior: horizontal scroll on `.heatmap-svg-area`
|
||||
|
||||
---
|
||||
|
||||
## Registry Safety
|
||||
|
||||
| Registry | Blocks Used | Safety Gate |
|
||||
|----------|-------------|-------------|
|
||||
| not applicable | none | not applicable |
|
||||
|
||||
No component registries or third-party blocks in this phase.
|
||||
|
||||
---
|
||||
|
||||
## Checker Sign-Off
|
||||
|
||||
- [ ] Dimension 1 Copywriting: PASS
|
||||
- [ ] Dimension 2 Visuals: PASS
|
||||
- [ ] Dimension 3 Color: PASS
|
||||
- [ ] Dimension 4 Typography: PASS
|
||||
- [ ] Dimension 5 Spacing: PASS
|
||||
- [ ] Dimension 6 Registry Safety: PASS
|
||||
|
||||
**Approval:** pending
|
||||
Loading…
Add table
Reference in a new issue