feat: Worker portal Stage 1 — design system extraction (Askama partials + CSS utility classes)

Description

Extract the 2026-05-14 design package's Design System.html + foundations.jsx + components.jsx into the canopy-web codebase as reusable Askama partials and CSS utility classes. The outcome is that every existing canopy-web template can be rewritten to use these primitives without changing routing or business logic. Low risk, high leverage. Independent of composability runtime work.

This is Stage 1 of the worker portal redesign and the only stage that does not block on the Stage 2 ADRs.

Acceptance Criteria

  • Component primitives extracted to services/canopy-web/templates/_primitives/*.html:
    • PanelFrame (titled panel with optional overline + actions slot)
    • Overline (small-caps section header)
    • GoldRule (decorative section divider)
    • BigNumber (large numeric callout with optional label)
    • HeroStrip (full-width hero banner)
    • LeafGlyph (orchard motif decoration)
    • StatusPill (state badge with semantic color tokens)
    • MoneyCell (right-aligned currency cell for tables)
  • Four panel-state utility classes added to services/canopy-web/static/css/canopy-web.css:
    • cy-pulse keyframe animation
    • .cy-skeleton (loading placeholder)
    • .cy-error-block (error state container)
    • .cy-empty-state (editorial empty state)
  • At least one existing canopy-web template rewritten end-to-end using the new primitives to validate the API shape (suggest: dashboard or a single case-detail tab)
  • No CSP violations introduced; inline styles avoided per security baseline
  • Playwright smoke pass: zero regressions on existing 50+ canopy-web tests
  • axe-core WCAG 2.1 AA clean for the rewritten template

Design answers (2026-05-19)

  • Primitive list freshness: extract as-is. The 8 primitives all read from --orchard-* variables; the post-delivery palette shipping via !295 (merged) didn't change their internals.
  • Are any components.jsx primitives intentionally omitted? No — the 8 above are the complete set for Stage 1.

Phase-1.5 follow-up

When design authored the empty/loading/error states for the panel kit, four more first-class primitives emerged. They land as a follow-up (#505 (closed)) that runs in parallel with Stage 2/3, not gating Stage 1: EmptyState, Skeleton, SkeletonRow, ErrorBlock. The four CSS-only panel-state utility classes in this issue's AC still ship as-is in Stage 1; #505 (closed) upgrades them to proper Askama-macro primitives once Stage 1 lands.

Context & References

  • Tracking issue: #460
  • Epic: &51
  • Plan: worker-portal-redesign.adoc, Stage 1
  • Follow-up: #505 (closed) (Stage 1.5 panel-state primitives upgrade)
  • Design package origin: 2026-05-14 external delivery (354 KB, 15 HTML canvases, ~13,700 LOC of .jsx reference, HANDOFF.md)
  • Files: services/canopy-web/templates/_primitives/, services/canopy-web/static/css/canopy-web.css

Labels

type::feature, priority::medium, program::infrastructure, service::web, workflow::ready, compliance::wcag-21-aa

Edited by Ghost User