Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
28cfe9e
feat(theme): clean-modern light mode across theme surfaces
HanSur94 Jul 8, 2026
fa5801b
docs(quick-260708-v8k): clean-modern light mode
HanSur94 Jul 8, 2026
2b6d44e
feat(dashboard): Phase 1 UI refresh — grid breathing room
HanSur94 Jul 8, 2026
cae1f46
docs(quick-260708-w1d): dashboard UI refresh Phase 1 breathing room
HanSur94 Jul 8, 2026
20dd255
feat(dashboard): Phase 2 UI refresh — hide floating axes toolbars
HanSur94 Jul 8, 2026
6f3475f
docs(quick-260708-waf): dashboard UI refresh Phase 2 hide axes toolbars
HanSur94 Jul 8, 2026
9ec3b49
feat(dashboard): Phase 3 UI refresh — title header band (fix overlap)
HanSur94 Jul 9, 2026
b8f0bd6
docs(quick-260709-cw9): dashboard UI refresh Phase 3 title header band
HanSur94 Jul 9, 2026
642b704
feat(dashboard): Phase 4 UI refresh — adaptive KPI number card
HanSur94 Jul 9, 2026
4967d00
docs(quick-260709-dcq): dashboard UI refresh Phase 4 adaptive KPI card
HanSur94 Jul 9, 2026
33f3167
fix(theme): restore light tab active/inactive contrast
HanSur94 Jul 9, 2026
b43aa3a
fix(dashboard): MultiStatus painted every sensor alarm-red
HanSur94 Jul 9, 2026
95e1d00
docs(quick-260709-ekv): MultiStatus all-red dot fix
HanSur94 Jul 9, 2026
4b95245
feat(dashboard): custom-drawn toolbar shim, hide native controls (gp9)
HanSur94 Jul 9, 2026
7a294af
feat(dashboard): active-state repaint of custom toolbar pills (gp9)
HanSur94 Jul 9, 2026
f252501
docs(design): 1:1 Pencil→MATLAB light-mode design spec
HanSur94 Jul 9, 2026
f65d830
docs(quick-260709-gp9): custom-drawn dashboard toolbar (light mock re…
HanSur94 Jul 9, 2026
5345671
feat(260709-ikg): hide folded chrome buttons (X/V/A/L/+) behind Visib…
HanSur94 Jul 9, 2026
619ff9e
feat(260709-ikg): overflow menu button drives the folded chrome actions
HanSur94 Jul 9, 2026
195637b
feat(260709-ikg): anchor OverflowMenuButton in reflowChrome_
HanSur94 Jul 9, 2026
cc8876c
docs(quick-260709-ikg): widget-chrome overflow menu (light mock redli…
HanSur94 Jul 9, 2026
e08c004
Merge remote-tracking branch 'origin/main' into claude/light-mode-des…
HanSur94 Jul 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion .planning/STATE.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
---
id: 260708-v8k
slug: clean-modern-light-mode
title: Clean-modern light mode across the three theme surfaces
status: in_progress
created: 2026-07-08
type: quick
---

# Quick Task 260708-v8k: Clean-modern light mode

## Goal

Redesign the FastSense **light** theme with a "clean modern" identity (crisp white
widget surfaces on a soft neutral-gray canvas, blue `#2563EB` accent, hairline cool
borders, semantic green/amber/red status). Palette approved via a Pencil mockup.
Keep everything cheap to render in MATLAB (flat fills, 1px borders, solid arcs) and
fully backward-compatible (no field renames, no API change, legacy preset aliases
intact, **dark preset output byte-identical**).

## Tasks

### Task 1 — FastSenseTheme.m light preset
- **files:** `libs/FastSense/FastSenseTheme.m`
- **action:** In `getPreset`, rewrite the `'light'`/legacy-alias struct values:
- `Background [0.961 0.965 0.973]`
- `AxesColor [1 1 1]`
- `ForegroundColor [0.208 0.255 0.333]`
- `GridColor [0.914 0.929 0.949]`
- `GridAlpha 0.7`
- `GridStyle '-'`
- `LineColorOrder 'muted'` (unchanged)
- `ThresholdColor [0.937 0.267 0.267]`
- leave `ThresholdStyle`, `ViolationMarker`, `ViolationSize`, `BandAlpha`,
`FontName`, `FontSize`, `TitleFontSize`, `LineWidth` unchanged.
- **dark preset untouched.**
- **verify:** `t=FastSenseTheme('light')` returns the new values; `FastSenseTheme('default')`
aliases to light; `FastSenseTheme('dark')` unchanged.
- **done:** light struct reflects the approved palette.

### Task 2 — DashboardTheme.m light branch + per-preset status colors
- **files:** `libs/Dashboard/DashboardTheme.m`
- **action:** In `getDashboardDefaults`, rewrite the `'light'` (`otherwise`) branch:
- `DashboardBackground [0.961 0.965 0.973]`, `WidgetBackground [1 1 1]`,
`WidgetBorderColor [0.898 0.910 0.925]`, `ToolbarBackground [0.976 0.980 0.984]`,
`ToolbarFontColor [0.392 0.455 0.545]`, `DragHandleColor [0.145 0.388 0.922]`,
`DropZoneColor [0.918 0.945 0.996]`, `GridLineColor [0.914 0.929 0.949]`,
`GroupHeaderBg [0.933 0.949 0.969]`, `GroupHeaderFg [0.118 0.161 0.231]`,
`GroupBorderColor [0.898 0.910 0.925]`, `TabActiveBg [0.918 0.945 0.996]`,
`TabInactiveBg [0.933 0.949 0.969]`. Keep `MarkerPlantLog` and
`CurrentViewBoxColor` light values.
- Make `StatusOkColor`/`StatusWarnColor`/`StatusAlarmColor` **per-preset**: set them
in BOTH switch branches — dark keeps `[0.31 0.80 0.64]`/`[0.91 0.63 0.27]`/`[0.91 0.27 0.38]`;
light uses `[0.086 0.639 0.290]`/`[0.961 0.620 0.043]`/`[0.937 0.267 0.267]`.
Guard the shared-defaults assignment of those three with `if ~isfield` so it no
longer overrides the per-preset values.
- **verify:** `DashboardTheme('light')` reflects new values; `DashboardTheme('dark')`
is byte-identical to the pre-change output (compare via isequaln on all fields).
- **done:** light branch reflects approved palette, dark unchanged.

### Task 3 — CompanionTheme.m (no edit) + verification
- **files:** none (verification only)
- **action:** Confirm `CompanionTheme.get('light')` inherits the new palette:
`Accent == DragHandleColor == [0.145 0.388 0.922]`, `LineColors` derived from muted.
- **verify:** construct all three light themes + dark; run theme-related test files.
- **done:** companion light inherits correctly; tests green (modulo known env failures).

## Must-haves
- Light palette matches the approved Pencil mockup hex→RGB values.
- Dark preset output unchanged (backward compatibility).
- No field renamed or removed; legacy preset aliases still resolve to light.
- Only flat-render primitives (no gradient/shadow fields introduced).
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
id: 260708-v8k
slug: clean-modern-light-mode
status: complete
date: 2026-07-08
commit: 28cfe9e2
---

# Quick Task 260708-v8k — Summary

## What shipped

A redesigned **clean-modern light mode** for FastSense, designed in Pencil and
translated 1:1 into the existing MATLAB theme structs. Crisp white widget
surfaces on a soft neutral-gray canvas (`#F5F6F8`), blue `#2563EB` accent,
hairline cool borders, and a crisp semantic green/amber/red status trio.

Every value maps to a flat-render primitive (solid fills, 1px borders, solid
arcs, native dashed threshold) — no gradients, shadows, blur, or transparency
stacks — so the theme stays cheap for MATLAB to draw.

## Changes

- **`libs/FastSense/FastSenseTheme.m`** — rewrote the `'light'`/legacy-alias
preset: `Background [0.961 0.965 0.973]`, `ForegroundColor [0.208 0.255 0.333]`,
`GridColor [0.914 0.929 0.949]`, `GridAlpha 0.7`, `ThresholdColor [0.937 0.267 0.267]`.
`LineColorOrder` kept as `'muted'`. Dark preset untouched.
- **`libs/Dashboard/DashboardTheme.m`** — rewrote the light branch (surfaces,
hairline borders, blue drag/drop accent, cool group/tab backgrounds). Made
`StatusOkColor`/`StatusWarnColor`/`StatusAlarmColor` **per-preset** with a
guarded (`if ~isfield`) shared fallback, so light gets its crisp trio
`[0.086 0.639 0.290]`/`[0.961 0.620 0.043]`/`[0.937 0.267 0.267]` while dark
keeps its original values.
- **`CompanionTheme.m`** — no edit; `Accent` and `LineColors` derive from
DashboardTheme, so the light palette flows through automatically.
- **Tests** — updated `TestTheme.m` (3) and `TestFastSenseTheme.m` (1) light
`Background` assertions to the new value.

## Verification

- Light values match the approved Pencil palette (checked field-by-field in MATLAB).
- **Dark preset byte-identical**: `isequaln` = 1 for both `FastSenseTheme('dark')`
and `DashboardTheme('dark')` vs a pre-change baseline snapshot.
- Legacy aliases (`default`, `ocean`, `scientific`, `industrial`) resolve to light.
- Companion inherits: `Accent == DragHandleColor == [0.145 0.388 0.922]`.
- Test suites green: TestTheme 12/12, TestDashboardTheme 6/6, TestFastSenseTheme
11/11, TestStatusWidget 11/11, companion theme-walker 36/36.

## Backward compatibility

No field renamed or removed; no API change; legacy preset aliases intact; dark
preset unchanged. Existing dashboards/scripts/serialized themes keep working.

## Design source

Pencil mockups (two frames — "FastSense Light — Dashboard" and
"FastSense Light — Companion") in `pencil-halo.pen`, using FastSense-namespaced
`fs-*` tokens that carry the exact hex→RGB values applied here.
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
id: 260708-w1d
slug: dashboard-refresh-breathing-room
title: Dashboard UI refresh — Phase 1 "breathing room" (gutters + padding)
status: in_progress
created: 2026-07-08
type: quick
---

# Quick Task 260708-w1d — Dashboard UI refresh, Phase 1: breathing room

## Goal

First slice of the approved Pencil redesign: give the dashboard grid gutters +
outer padding so widgets read as separated cards on the canvas. Cheapest,
highest-impact step. `DashboardLayout.computePosition` already consumes
`GapH`/`GapV`/`Padding`, and `allocatePanels` already draws a `line` border
(`WidgetBorderColor` on `WidgetBackground`) per cell — they just default to 0,
so the grid renders flush. This task supplies tasteful values via the theme and
wires them in. No layout math changes.

## Tasks

### Task 1 — Theme fields
- **files:** `libs/Dashboard/DashboardTheme.m`
- **action:** In the shared-defaults block (applies to both presets), add three
additive fields:
- `WidgetGapH = 0.006`
- `WidgetGapV = 0.010`
- `DashboardPad = [0.008 0.010 0.008 0.010]` (normalized `[L B R T]`)
Additive only — no field renamed/removed; dark output unchanged apart from the
three new fields.
- **verify:** `DashboardTheme('light')` and `('dark')` both expose the fields.
- **done:** fields present with correct defaults.

### Task 2 — Wire layout to theme
- **files:** `libs/Dashboard/DashboardEngine.m`
- **action:** In the render path where `themeStruct` is available, just before
`allocatePanels` (near the `obj.Layout.ContentArea` assignment ~line 510), set:
- `obj.Layout.GapH = <theme.WidgetGapH or 0.006>`
- `obj.Layout.GapV = <theme.WidgetGapV or 0.010>`
- `obj.Layout.Padding = <theme.DashboardPad or [0.008 0.010 0.008 0.010]>`
Use `isfield` guards so older serialized themes lacking the fields still get the
refreshed spacing (fall back to the new defaults, not 0).
- **verify:** rendered dashboard shows gutters + edge padding; no overlap/scroll break.
- **done:** grid reads as separated cards.

### Task 3 — Verify (MATLAB, orchestrator-run)
- **files:** none
- **action:** render `example_dashboard_all_widgets` (light), exportapp screenshot,
eyeball for gutters/padding + separated cards + no clipping. Run
`TestDashboardLayout`, `TestDashboardEngine` and adjacent suites.
- **done:** visual confirms spacing; suites green (modulo known-env failures).

## Must-haves
- Widgets visibly separated by gutters; dashboard has outer edge padding.
- No widget overlap; scrolling still works when content exceeds viewport.
- Additive theme fields only; dark preset otherwise unchanged; existing dashboards
still render (spaced, not broken).
- `DashboardLayout` constructed directly (no theme) keeps `Gap=0` for existing tests.
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
id: 260708-w1d
slug: dashboard-refresh-breathing-room
status: complete
date: 2026-07-08
commit: 2b6d44e3
---

# Quick Task 260708-w1d — Summary

## What shipped

Phase 1 of the dashboard UI refresh: **grid breathing room**. The dashboard grid
now has inter-widget gutters + outer canvas padding, so widgets read as separated
cards instead of a flush wall of panels. First and cheapest slice of the approved
Pencil redesign.

## Changes

- **`libs/Dashboard/DashboardTheme.m`** — added three additive shared theme fields:
`WidgetGapH = 0.006`, `WidgetGapV = 0.010`,
`DashboardPad = [0.008 0.010 0.008 0.010]` (normalized `[L B R T]`).
- **`libs/Dashboard/DashboardEngine.m`** — before `allocatePanels`, set
`Layout.GapH/GapV/Padding` from the theme, `isfield`-guarded with fallbacks to
the new defaults (so older serialized themes still get the spacing).
- **`DashboardLayout.m`** — untouched; `computePosition` already consumes these
knobs and `allocatePanels` already draws the hairline cell border.

## Verification (live MATLAB)

- Rendered `example_dashboard_all_widgets` (light, 18 widgets): visible gutters +
edge padding, widgets read as separated cards, no overlap, scrolling intact.
Screenshot captured (`scratchpad/phase1_gutters.png`).
- Suites green: `TestDashboardLayout` 8/8, `TestDashboardEngine` 18/18,
`TestDashboardTheme` 6/6.
- `TestDashboardDetach/testDetachButtonInjected` fails — **confirmed pre-existing**
(fails identically on the clean baseline via git-stash A/B), not a regression.
Tracked as a separate task.

## Backward compatibility

Additive theme fields only; no field renamed/removed. Dashboards built with a
directly-constructed `DashboardLayout` (no theme) keep `Gap=0`. Existing dashboards
still render — just spaced.

## Next (redesign roadmap)

Phase 2 — de-clutter widget chrome (hide axes toolbars + collapse the per-widget
`X V A L` button strip). Phases 3–6: card headers, KPI/status cards, toolbar
refresh, color polish. See the Pencil frames "FastSense — Current UI (as-is)" and
"FastSense — Redesigned UI".
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
id: 260708-waf
slug: dashboard-refresh-hide-axes-toolbars
title: Dashboard UI refresh — Phase 2 (de-clutter): hide per-axes MATLAB toolbars
status: in_progress
created: 2026-07-08
type: quick
---

# Quick Task 260708-waf — Phase 2: hide the floating axes toolbars

## Goal

De-clutter the dashboard by removing the redundant floating MATLAB axes
exploration toolbar (download / brush / datatips / pan / zoom-in / zoom-out /
home) that renders on every plot widget. The dashboard already provides its own
controls (per-widget button bar + time navigator), so the per-axes toolbar is
pure visual noise — the approved Pencil redesign removes it entirely.

Scope note: this phase is **only** the axes-toolbar suppression. The `X V A L`
axis-toggle + `^`/`+` button-strip consolidation (hover/overflow) is deferred to
its own phase — it is interaction-sensitive and hover-hiding fights MATLAB's
uifigure primitives, so it deserves separate, careful work.

## Tasks

### Task 1 — Central suppression hook
- **files:** `libs/Dashboard/DashboardLayout.m`
- **action:** In `realizeWidget` (the single central point every widget renders
through), after `widget.render(...)` and before `widget.markRealized()`, call a
new private static helper `hideAxesToolbars_(widget.hCellPanel)`. The helper does
`findall(root,'Type','axes')` and sets each axes' `Toolbar.Visible = 'off'`,
per-axes try/catch so a toolbar-less or stale axes never aborts the realize pass.
Central placement covers all 14 axes-bearing widget types and re-applies on
scroll-realize.
- **verify:** rendered dashboard shows no floating axes toolbars; widgets still
render; no errors.
- **done:** toolbars gone across all plot widgets.

### Task 2 — Verify (MATLAB, orchestrator-run)
- **files:** none
- **action:** render `example_dashboard_all_widgets` (light), exportapp screenshot,
confirm the 7-icon axes toolbars are gone from the plots. Run
`TestDashboardEngine`, `TestDashboardLayout`, and a couple of plot-widget suites
(`TestScatterWidget`/`TestHistogramWidget`) to confirm rendering still works.
- **done:** visual confirms toolbars gone; suites green (modulo known-env failures).

## Must-haves
- Floating axes toolbars no longer appear on dashboard plot widgets.
- All widgets still render; no functional regression (button bar, zoom via scroll,
detach, etc. unaffected).
- Change confined to the central realize hook + one helper; no per-widget edits.
- Standalone (non-dashboard) FastSense plots are unaffected (helper only runs in
the dashboard realize path).
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
id: 260708-waf
slug: dashboard-refresh-hide-axes-toolbars
status: complete
date: 2026-07-08
commit: 20dd2559
---

# Quick Task 260708-waf — Summary

## What shipped

Phase 2 of the dashboard UI refresh — **de-clutter**. The redundant floating
MATLAB axes exploration toolbar (download / brush / datatips / pan / zoom-in /
zoom-out / home) no longer appears on dashboard plot widgets. It's pure noise —
the dashboard already has its own controls (widget button bar + time navigator),
and the Pencil redesign removed it.

## Change

- **`libs/Dashboard/DashboardLayout.m`**
- `realizeWidget`: after each `widget.render(...)`, call the new private static
helper `hideAxesToolbars_(widget.hCellPanel)`. Central point → covers all 14
axes-bearing widget types and re-applies on scroll-realize.
- `hideAxesToolbars_`: `findall(root,'Type','axes')` then set each
`Toolbar.Visible='off'`, per-axes try/catch.

Scope: **axes-toolbar suppression only.** The `X V A L` axis-toggle + `^`/`+`
button-strip consolidation is deferred to its own phase (interaction-sensitive;
hover-hiding fights uifigure primitives).

## Verification (live MATLAB)

- `example_dashboard_all_widgets` (light, 18 widgets): before/after `exportapp`
compare — the floating toolbars are gone from every visible plot
(`scratchpad/phase2_no_toolbars.png` vs `phase1_gutters.png`).
- 3 axes still report `Toolbar.Visible='on'` but are `Visible='off'` overlay axes
(recreated by resize-time relayout after the realize hook) — they render nothing,
confirmed by the screenshot.
- Suites green: `TestDashboardLayout` 8/8, `TestDashboardEngine` 18/18,
`TestScatterWidget` 5/5, `TestHeatmapWidget` 5/5.

## Backward compatibility / safety

Change confined to the central realize hook + one helper; no per-widget edits.
No functional regression — button bar, detach, zoom-via-scroll unaffected.
Standalone (non-dashboard) FastSense plots are untouched (the helper only runs in
the dashboard realize path).

## Next

Phase 3 — card headers & title hierarchy (fix titles overlapping plots; consistent
header row per widget). Then KPI/status cards, toolbar refresh, color polish.
Deferred: the `X V A L`/`^`/`+` button-strip consolidation.
Loading
Loading