kimai-plugin-heatmap/.planning/phases/06-renderer-architecture/06-UI-SPEC.md
2026-04-09 00:25:52 +02:00

5.7 KiB

phase slug status shadcn_initialized preset created
6 renderer-architecture draft false none 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