Motivka

Design System Cleanup

Resolved all open bugs and 32 ad-hoc tasks accumulated across six phases of the design system redesign, covering token cleanup, card deduplication, form accessibility, navigation hardening, and motif atom fixes.

1 Phases
6 Tasks
3 Bugs Fixed
1 Days

The Problem

Six phases of the design system redesign had landed successfully, but each phase review surfaced bugs and ad-hoc improvement tasks that were deferred to avoid scope creep. I had accumulated 5 open high-severity bugs and 32 ad-hoc tasks (18 medium, 14 low) across Phases 3 through 6. These included hardcoded colour values scattered through components, unused tokens cluttering app.css, DOM performance issues in form transitions, accessibility gaps in navigation and form components, and Storybook coverage holes for new variants.

Left unfixed, these issues would erode the consistency the redesign was meant to establish. I did not want to start Phase 7 (Documentation) with known broken patterns -- that would mean documenting the wrong state and then having to update the docs again.

What I Built

I structured the cleanup as 6 tasks grouped by domain to maximise parallelism, running across two repositories (motivka and motif).

Bug fixes. The Toast component referenced an undefined --accent-red token for its focus outline. SkeletonHero used an orphaned .card-glass class that applied no styling. The motif Select atom used non-semantic data-invalid instead of aria-invalid. All three were straightforward fixes once identified.

Token and colour cleanup. I replaced hardcoded navy rgba values in ChatMessage with color-mix using design tokens. Hardcoded sunset rgba in card-glass hover became var(--accent-secondary-border). I created 12 new category tokens (--category-*-bg and --category-*-border for 6 categories) to replace inline oklch() that lacked Firefox fallbacks. The unused accent opacity and gradient tokens from Phase 3 were consumed in SolutionCard, TestimonialsSection, SectionHeader, and TableOfContents -- fulfilling the original design intent rather than deleting them.

Card system cleanup. I replaced :global(.card-compact) styles with scoped CSS, confirmed and removed unused badge, badgeColour, and accentColour props from CardCompact, and added missing Admin Ghost and As Link stories to Card.

Form system cleanup. The FormGroup component had a race condition where previousHadError was captured after branching logic instead of before. I rewrote it to capture at the top of the $effect. DOM thrashing from JavaScript-driven visibility toggling was replaced with CSS-driven visibility via a data-state attribute. I added aria-describedby wiring with a documented accessibility contract and made the hardcoded "Looks good" success message configurable via a prop.

Navigation and content polish. The Breadcrumb component was using array indices as keys, which I replaced with item.href ?? item.label. Header had a double requestAnimationFrame pattern that I simplified to CSS-driven data-transitions-ready. I extracted a shared isCurrentRoute utility with unit tests, adopted by Header, MobileMenu, and AdminNavMain. The Footer SVG flag got proper role="presentation" and aria-hidden="true" attributes.

Motif atom fixes. I created a shared form-states.css with a .motif-form-control class for consistent focus rings. The Select component was using --bg-primary (a public token) for its admin focus ring, which I replaced with a theme-aware --select-bg. Error ring width was standardised to 4px across all atoms. Input and Textarea got explicit data-valid="true" instead of implicit attribute presence.

Key Decisions

  • Cleanup before documentation -- fixes land first so Phase 7 docs naturally reflect the corrected state.
  • Consume unused tokens, do not delete them -- accent opacity and gradient tokens were intentionally created in Phase 3. Removing and re-adding later would be backwards.
  • Remove confirmed-unused Card code -- builder greps for usage; if zero hits, delete. Lean codebase over speculative preservation.
  • Deduplicate via shared CSS, not new components -- new components would need their own stories, tests, and barrel exports. Overkill for cleanup.
  • Cross-repo task isolation -- motif work ran as a separate task without worktree isolation to avoid cross-repo complexity.

What is Next

With zero open bugs and only one remaining low-severity ad-hoc task (extracting a shared categoryColourMap utility), the design system is clean enough to document properly. Phase 7 will generate feature verification guides that reflect the actual corrected state of every component.

Features Delivered

Bug Fixes (Wave 1)

  • Fixed Toast undefined --accent-red token reference
  • Fixed SkeletonHero orphaned .card-glass class
  • Fixed motif Select non-semantic data-invalid attribute

Token and Colour Cleanup (Wave 2)

  • Replaced hardcoded rgba values with design tokens in ChatMessage
  • Created 12 category tokens for Firefox-compatible colour variants
  • Consumed unused accent opacity tokens in SolutionCard and TestimonialsSection
  • Consumed unused gradient tokens in SectionHeader and TableOfContents

Card System Cleanup (Wave 2)

  • Replaced :global(.card-compact) with scoped CSS
  • Removed confirmed-unused badge/badgeColour/accentColour props
  • Added Admin Ghost and As Link Storybook stories

Form System Cleanup (Wave 2)

  • Fixed FormGroup previousHadError race condition
  • Replaced DOM thrashing with CSS-driven data-state visibility
  • Added aria-describedby accessibility contract
  • Made success message configurable via prop

Navigation and Content Polish (Wave 2)

  • Fixed Breadcrumb array index keys
  • Simplified Header double rAF to CSS-driven transitions
  • Extracted shared isCurrentRoute utility with unit tests
  • Added Footer SVG flag accessibility attributes

Motif Atom Fixes (Wave 1)

  • Created shared form-states.css with .motif-form-control class
  • Fixed Select admin focus ring public token leak
  • Standardised error ring width to 4px across all atoms
  • Changed Input/Textarea to explicit data-valid attribute

Bugs Fixed

  • BUG-014
  • BUG-015
  • BUG-016

Key Decisions

  • D-DS-07:
  • D-DS-08:
  • D-DS-09:
  • D-C02:
  • D-C03:
  • D-C04:
  • D-C05: