Browse documents

Skeuomorphism — Phased Rollout

The redesign ships in 8 phases, ordered so the highest-leverage, lowest-risk work lands first (the shared token layer + primitives repaint the whole app at once). Each phase lists scope, files, acceptance criteria, and status.

Legend: ✅ Shipped · 🟡 In progress · ⏳ Planned.


Phase 0 — Tokens & material system ✅

Scope. The elevation/material foundation everything else builds on: two material colours (--tactile-hi/lo), the five elevation shadows (raised, raised-hover, floating, well, pressed), the --sheen-top gradient, and the .sheen / .glass utilities — all with light and dark values. Tailwind boxShadow mappings so components can use shadow-raised etc.

Files. app/globals.css (tokens + utilities), tailwind.config.ts (boxShadow).

Acceptance.

  • All five shadow-* utilities resolve in light and dark.
  • .sheen and .glass render, .glass has a @supports fallback.
  • No component hardcodes a shadow.

Status. ✅ Shipped.


Phase 1 — Core primitives ✅

Scope. The shared UI kit that appears on every screen — repainting these transforms ~80% of the surface area:

  • Card → raised material (sheen shadow-raised, softened border).
  • Button (primary / secondary / outline / destructive / ghost) → tactile: sheen + shadow-raised, hover lift, :active press-in; ghost stays flat.
  • Input / Select / Textarea → recessed wells (bg-surface-sunken shadow-well) that flatten to a plain field on focus.

Files. components/ui/{card,button,input,select,textarea}.tsx.

Acceptance.

  • KPI tiles and cards read as raised panels; inputs read as carved wells.
  • Buttons visibly lift on hover and press on click; disabled buttons stay flat.
  • tsc clean; existing pages unchanged structurally.

Status. ✅ Shipped. (Evidence: docs/engineering/qa-evidence/skeu-chiller.png.)


Phase 2 — Navigation & chrome ⏳

Scope.

  • Top bar.glass (frosted, translucent) with a hairline bottom border; content scrolls under it.
  • Sidebar → a raised rail; the active nav item becomes a pressed/recessed pill (selected = pushed in), inactive items flat with hover lift.
  • Page headers, tabs (active tab raised, inactive recessed), breadcrumbs, command palette (⌘K) as a floating glass panel.

Files. components/app/{topbar,sidebar,page-header}.tsx (or equivalents in components/admin/ui), lib/nav.tsx consumers, command-palette component.

Acceptance. Top bar is frosted over scrolled content; the current route's nav item is unmistakably "pressed"; keyboard focus and contrast preserved.


Phase 3 — Data surfaces ⏳

Scope.

  • Tables → raised container, inset header strip, subtle zebra; row hover lifts faintly.
  • KPI tiles → refine the Phase-1 Card treatment (tighter sheen, value emphasis).
  • Meters / progress barsinset track (well) with a raised fill — a physical gauge; reuse for load bars, circuit share bars, NILM stacked bar, staging load.
  • Badges / status pills → subtle inset chips; keep icon+label+colour for status (UX_patterns §3.1).
  • Sparkline framing → seat charts in a faint recessed plate.

Files. table components, components/**/console.tsx bar/meter markup, components/ui/badge.tsx.

Acceptance. Progress/meter tracks look carved with a raised fill; tables have clear header/body depth; contrast on status pills ≥ AA.


Phase 4 — Module consoles (CPMS / EMS) ⏳

Scope. The operator surfaces get true physical controls:

  • Control panels → toggle switches as physical rockers (on = raised knob shifted, off = recessed), demand/limit inputs as wells, "Apply/Execute/Reconcile" as tactile primaries.
  • Enabled/Sheddable toggles in the chiller/energy tables → physical switch styling.
  • Plant schematic → pipes with a soft bevel, equipment blocks as raised modules, running state with an emissive glow; loops read as depth.
  • Gauges (efficiency, forecast peak) → recessed dial faces with a raised needle/arc.

Files. components/chillers/*, components/energy/*, components/fdd/findings-panel.tsx, components/chillers/plant-schematic.tsx.

Acceptance. Toggles read as switches; schematic has depth; no regression in the QA E2E flows (docs/engineering/qa_results_e2e.md).


Phase 5 — Overlays & feedback ⏳

Scope. Everything transient uses glass + shadow-floating:

  • Dialog / Sheet / Popover / Dropdown / Tooltip → floating glass panels.
  • Toasts / notifications → floating cards that slide + settle.
  • Skeleton loaders → shimmer over a well; empty states → recessed plate with a raised icon.

Files. components/ui/dialog.tsx, popover/tooltip/toast components, skeleton/empty-state components.

Acceptance. Overlays float above content with frosted material; focus trap and Esc unaffected; motion respects reduced-motion.


Phase 6 — Dashboards & widgets 🟡

Shipped — all dashboard widgets.

  • Widget frames (both grid + mobile renderers) → raised material panels (sheen shadow-raised, softened border, recessed header strip).
  • Drag interaction → a dragged widget lifts to shadow-floating; the drop placeholder reads as a recessed well cut into the canvas (react-grid-layout classes styled in globals.css).
  • Widget internals → meter/share bars become carved tracks (shadow-well) with glossy fills (sheen); sparklines are seated in a recessed "screen" plate with a soft area fill; the radial gauge has a recessed dial + raised (drop-shadowed) arc.

Files. components/dashboards/dashboard-canvas.tsx (frames), components/dashboards/widgets.tsx (Sparkline, bars, gauge), app/globals.css (rgl drag/placeholder). Evidence: evidence/dashboard-widgets.png.

Remaining ⏳.

  • Dashboard canvas → a faintly recessed "board" the widgets sit on.
  • Per-theme accents → verify elevation reads well under each [data-dashboard-theme] (ocean/forest/sunset/violet/midnight).
  • TV / war-room → higher-contrast material for at-a-distance legibility.

Acceptance. Dragging a widget visibly lifts it ✅; widget frames + internals are material ✅; canvas board depth + per-theme contrast ⏳.


Phase 7 — Polish: dark-mode, a11y, performance, visual regression ⏳

Scope.

  • Dark-mode depth tuning — verify highlight/shadow balance on every surface in dark.
  • Contrast audit — automated WCAG AA check on text and non-text (control edges, focus rings) after material is applied.
  • Reduced-motion — confirm lift/press degrade to instant.
  • Performance — cap shadow layers, ensure backdrop-filter is only on chrome/overlays, check paint cost on large tables/dashboards; promote animating layers with will-change only where needed.
  • Cross-browserbackdrop-filter fallback verified (Safari/Firefox).
  • Visual regression — capture before/after screenshots of key pages via ego lite and diff.

Files. globals.css tuning, a11y/perf audit notes under this folder.

Acceptance. AA contrast everywhere; no jank on dashboards/tables; glass falls back gracefully; reduced-motion honoured; screenshots archived.


Sequencing & risk

  • 0 → 1 are done and are the biggest visual win (shared kit). Safe: additive tokens + class swaps, tsc clean, no structural change.
  • 2 → 6 are independent and can run in parallel after Phase 1; each is scoped to a component group.
  • 7 is the gate before calling the redesign complete.
  • Rollback is trivial per phase: the changes are class-level; reverting a component restores the flat look without touching logic.