FN-6830: use theme accent for sidebar active states

Align the left sidebar selected and resize states with each active dashboard theme.

- Switch active left-sidebar item color and background to the shared --accent token.
- Update the resize-handle focus and hover accent to follow theme accent colors.
- Add a CSS regression test and documentation for the theme-accent invariant.
- Define shared typography tokens and replace an optional-step danger fallback with an existing error token.

Files changed:
 docs/dashboard-guide.md                            |  2 +-
 .../left-sidebar-active-accent.css.test.ts         | 38 ++++++++++++++++++++++
 .../dashboard/app/components/LeftSidebarNav.css    | 10 +++---
 .../app/components/WorkflowOptionalStepsPanel.css  |  2 +-
 packages/dashboard/app/styles.css                  |  3 ++
 5 files changed, 48 insertions(+), 7 deletions(-)

Fusion-Task-Id: FN-6830

Fusion-Task-Lineage: add8e9cd-4b91-45a1-a848-a54dd1083723
This commit is contained in:
gsxdsm
2026-06-21 11:28:08 -07:00
parent e412a1c1c6
commit c9146e15b2
5 changed files with 48 additions and 7 deletions

View File

@@ -27,7 +27,7 @@ When enabled on desktop or tablet project screens, the sidebar contains the prim
While the sidebar is active on desktop/tablet project screens, Board and List workflow controls move into the Header slot that replaces the hidden view toggle. Board and List share one workflow dropdown: each workflow row includes an inline edit action, and a persistent **New workflow** action remains at the bottom of the dropdown while the workflow list scrolls. The standalone workflow row above the board/list content is removed in this mode. When the flag is off, outside project screens, or on mobile, workflow controls remain inline with the same consolidated dropdown.
The footer collapse toggle uses the same row styling as other sidebar items: expanded mode shows a **Collapse** label, while collapsed rail mode hides the label and keeps the icon-only button accessible through its label/title. The expanded width can still be resized from the right-edge separator. Collapsed state and expanded width are saved in browser `localStorage` (`fusion:left-sidebar-collapsed` and `fusion:left-sidebar-width`) and restored on reload.
The footer collapse toggle uses the same row styling as other sidebar items: expanded mode shows a **Collapse** label, while collapsed rail mode hides the label and keeps the icon-only button accessible through its label/title. The active nav-item highlight and the resize-handle hover/focus accent track the active color theme's `--accent` token across all themes, so shadcn, forest, ocean, and other themes no longer show a fixed blue selected state. The expanded width can still be resized from the right-edge separator. Collapsed state and expanded width are saved in browser `localStorage` (`fusion:left-sidebar-collapsed` and `fusion:left-sidebar-width`) and restored on reload.
On mobile viewports (`<=768px`), the sidebar is not rendered even when the experiment is enabled. The existing bottom `MobileNavBar` remains the navigation surface.

View File

@@ -0,0 +1,38 @@
import { readFileSync } from "node:fs";
import path from "node:path";
import { describe, expect, it } from "vitest";
const APP_ROOT = path.resolve(__dirname, "..");
const LEFT_SIDEBAR_CSS_PATH = path.join(APP_ROOT, "components", "LeftSidebarNav.css");
function readLeftSidebarCss(): string {
return readFileSync(LEFT_SIDEBAR_CSS_PATH, "utf8");
}
function extractRuleBody(source: string, selector: string): string {
const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const match = source.match(new RegExp(`${escapedSelector}\\s*\\{([\\s\\S]*?)\\}`));
expect(match, `${selector} rule should exist in LeftSidebarNav.css`).not.toBeNull();
return match?.[1] ?? "";
}
describe("left sidebar active accent CSS", () => {
/**
* FNXC:DashboardStyling 2026-06-21-11:16:
* jsdom cannot resolve custom properties reliably, so the left-sidebar theme-accent invariant is guarded by raw CSS text. The active item and resize handle must reference the universal --accent token and must not regress to workflow todo status tokens.
*/
it("uses the theme accent token for active item and resize handle styling", () => {
const source = readLeftSidebarCss();
const activeItemBody = extractRuleBody(source, ".left-sidebar-nav__item--active");
expect(activeItemBody).toContain("var(--accent)");
expect(activeItemBody).not.toContain("var(--todo)");
expect(activeItemBody).not.toContain("var(--todo-bg)");
expect(activeItemBody).not.toContain("var(--status-todo-bg)");
expect(source).toMatch(
/\.left-sidebar-nav__resize-handle:hover::after,\s*\.left-sidebar-nav__resize-handle:focus-visible::after\s*\{[\s\S]*?background:\s*var\(--accent\);[\s\S]*?\}/,
);
expect(source).not.toContain("--todo");
});
});

View File

@@ -87,12 +87,12 @@ The collapse toggle lives in the footer above Settings instead of floating on th
}
/*
FNXC:DashboardStyling 2026-06-20-20:56:
The active sidebar item must use the defined --status-todo-bg token so the dashboard CSS token-validity gate stays green. FN-6809 replaces the undefined --todo-bg reference without changing the rendered todo status treatment.
FNXC:DashboardStyling 2026-06-21-11:16:
The left sidebar active highlight and resize accent must use the per-theme --accent token so the selected state reflects the active color theme instead of the workflow todo-status blue. FN-6830 keeps this requirement in the base sidebar rules so every theme inherits it without per-theme overrides.
*/
.left-sidebar-nav__item--active {
background: var(--status-todo-bg);
color: var(--todo);
background: color-mix(in srgb, var(--accent) 15%, transparent);
color: var(--accent);
}
.left-sidebar-nav__icon-wrap {
@@ -161,7 +161,7 @@ The narrower resizable sidebar must preserve row rhythm by truncating labels ins
.left-sidebar-nav__resize-handle:hover::after,
.left-sidebar-nav__resize-handle:focus-visible::after {
background: var(--todo);
background: var(--accent);
}
.left-sidebar-nav__resize-handle:focus-visible {

View File

@@ -89,7 +89,7 @@
}
.wf-optional-step-remove:hover:not(:disabled) {
color: var(--danger, #ef4444);
color: var(--color-error);
}
.wf-optional-steps-add {

View File

@@ -122,6 +122,9 @@ html {
--font-mono: "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
/* FNXC:DashboardStyling 2026-06-19-05:50: FN-6703 defines the xs font-size token so tokenized mobile mailbox tabs satisfy the dashboard CSS token-validity guard without relying on an undefined fallback. */
--font-size-xs: 0.8rem;
/* FNXC:DashboardStyling 2026-06-21-11:24: Dashboard components must use defined typography tokens so the raw CSS token-validity gate catches real missing custom properties instead of shared type-scale omissions. */
--font-size-base: 1rem;
--line-height-tight: 1.25;
/* Spacing Scale */
--space-xs: 4px;