Skip to content

feat(ui): refine the light theme and retire AppShell for the workspace kit - #50

Merged
yyyyaaa merged 13 commits into
mainfrom
phat/light-theme-tokens
Oct 5, 2026
Merged

yyyyaaa merged 13 commits into
mainfrom
phat/light-theme-tokens

Conversation

@yyyyaaa

@yyyyaaa yyyyaaa commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Refines the builtin light theme for the dashboard and Blocks surfaces, polishes components to use the new tiers, and replaces AppShell/AppBar with the workspace kit.

Light theme

Token Before After
background 98% white
border / sidebar-border 95% (drawn at 60%) / 92% 92% at full strength
input 89% 87%
accent 96% 95%
subtle-foreground 50% (3.9:1) 44% (≥4.5:1 on white and sidebar)
card ring (shadow-card) outset 5.5% inset 8%
  • White content, 97% sidebar, 92% hairlines: regions separate without heavier lines; stays neutral (no ivory/grain).
  • Card edges are drawn inset in both modes, so overflow containers can no longer clip them (the light-only cut-off).
  • Dark mode is unchanged; theme-tuning defaults and playground presets track the new values.

Components

  • Structural borders use one hairline weight; decorative thread/trace lines stay soft.
  • DialogHeader variant="band", SheetHeader/SheetFooter variant="band"; adopted by Data Rooms dialogs and sheets.
  • TableGroupRow + tableGroupRowClass (billing catalog adopts it).
  • Status Badge/ToneBadge fills read on white (light only).
  • TextShimmer sweeps toward the page colour in light mode, so running agents visibly shimmer.
  • Sidebar scroll body leaves room for focus rings.
  • Access map: picker follows its prompt; map and inheritance panel share a top edge.

Framed shell

WorkspaceShell framed sits the workspace in a rounded, hairline frame on a canvas one tier past the sidebar. All five templates pass it through.

<DataRooms framed {...props} />

AppShell → workspace kit

flowchart LR
  subgraph Before
    CK1[console-kit-core] -->|types only| AS[app-shell] --> AB[app-bar] --> SB[shadcn sidebar]
    CK1 --> WK1[workspace-kit]
  end
  subgraph After
    CK2[console-kit-core] --> WK2["workspace-kit (+ brand/account/nav types)"]
  end
Loading
  • Removes app-shell and app-bar (components, stories, test, exports, registry items).
  • Brand/account/navigation types move into workspace-kit; the console kit uses them, so console-kit installs no longer pull app-shell, app-bar, or sidebar.
  • Registry docs, agent skill, and smoke install point at workspace-kit.

Storybook

  • Fullscreen stories are no longer padded or offset; the canvas follows the Theme toolbar instead of a forced white body.

Review in Storybook: Templates/DataRooms (Room: Q&A, Access map, Framed shell), Templates/AgentsBuilder (Chat, Framed shell), UI/Dialog → Banded Header, UI/Sheet → Banded, UI/Table → Grouped, Workspace Kit/Shell.

yyyyaaa added 12 commits October 5, 2026 11:41
Move the builtin light theme to a white workspace: content and cards are
white, the sidebar sits at 97%, and hairlines run at a full-strength 90%
instead of a 60% wash of 95%, so regions separate without heavier lines.

- border 95% -> 90%, sidebar-border 92% -> 90%, input 89% -> 87%,
  accent 96% -> 95%, background 98% -> white
- light-only default hairline drops the /60 opacity; dark is unchanged
- subtle-foreground 50% -> 44% so hints clear AA on white and the sidebar
- card ring 0.055 -> 0.08 (hover 0.075 -> 0.11) to hold edges on white
- link follows its rule onto the white page (0.549 -> 0.559)
- theme tuning defaults and playground presets track the new hairline,
  keeping dark's ring at 0.10
Move border and sidebar-border from 90% to 92% (#ebebeb): regions still
separate, but a 1px line reads finer.
Table rows and footers, accordion dividers, stack headers and panel edges,
code and diff separators, and borders that are a component's only edge now
use the full border token instead of a softened /50-/80 wash. Thread and
trace guide lines stay soft on purpose.
Light shadow-card drew its hairline outside the box, so any card flush with
an overflow edge lost it (dark already drew it inset). Draw it inset in both
modes, apply surfaceInsetClass's 1px padding in both modes, and give the
sidebar scroll body room for the first control's focus ring without moving
anything.
DialogHeader gains variant="band", mirroring the default footer; SheetHeader
and SheetFooter gain the same variant, bleeding to the panel edges. Data
Rooms dialogs and sheets adopt them.
TableGroupRow opens a group of body rows with a tinted, hairline-bounded
heading; workspace templates get tableGroupRowClass, which the billing
catalog adopts. Table header and footer bands share one tint.
Badge status variants move from an 8% to a 14% fill (12% for error) and
ToneBadge to a 14% fill under a softer border, so pills read on a white
page. Dark keeps its previous values.
The sweep ran toward the foreground colour, which on a light page only
darkened grey text a step. Sweep toward the page colour in light mode; dark
keeps its glint.
Move the person picker out of the view header to follow "Pick a person to
see where their access reaches.", announce the result after it, and span
that row across the map and inheritance panel so both share a top edge.
The preview padded every story, so fullscreen shells were offset and
overflowed both ways, and Storybook's backgrounds forced a white body in
dark mode. Skip the padding for fullscreen stories, drop the viewport-sized
wrapper, and let html/body paint --background. Template frames that relied
on the hidden padding now add it themselves.
WorkspaceShell's framed prop sits the workspace in a rounded, hairline-edged
frame on a canvas one tier darker than the sidebar; className moves to the
canvas. The five templates pass it through, and the billing feature pack
declares it in its public props.
The console kit already renders WorkspaceShell and only borrowed AppShell's
types, which made every console-kit-core install pull app-shell, app-bar,
and the shadcn sidebar. Move the brand, account, and navigation types into
workspace-kit (links use NavRowLinkProps), retarget the console kit, and
delete both components with their stories, test, exports, and registry
items. Registry docs, the agent skill, and smoke install point at
workspace-kit. The console kit's brand and account props are now typed
WorkspaceBrand and WorkspaceAccount (same shape for the fields it reads).
@tenki-reviewer

tenki-reviewer Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Review complete. 🟡 2 medium

💬 Inline comments (1)

📍 Findings outside the diff (1) — 🟡 1 medium — defects on lines GitHub can't attach comments to

🟡 Medium — Remove app-bar/app-shell exports without deprecation · packages/ui/package.json

The patch deletes the app-bar.tsx/app-shell.tsx sources, the ./app-bar and ./app-shell subpath entries from packages/ui/package.json, the corresponding App* named and type exports from packages/ui/src/index.ts, and the matching registry entries in packages/ui/registry.json. Any external consumer of the published @constructive-io/ui package importing these paths or names fails resolution at install/type-check time with no deprecation window, and the Workspace* replacements are not shape-compatible drop-ins (e.g. WorkspaceAccountAction requires exactly one of href/onSelect).


The migration moves all five workspace templates onto WorkspaceShell/WorkspaceNavigation from workspace-kit, deletes the app-shell/app-bar subpath exports, and introduces a framed shell mode that draws its own rounded border and re-routes caller className to the outer canvas. Dialog and Sheet gain band header/footer variants, Table gains a group-row class, and the light theme shifts to a pure-white background with stronger borders and inset hairline shadows kept in sync across theme.ts, theme-tuning.ts, globals.css, and registry.json.

Files Change
packages/ui/src/components/workspace-kit/* Shell/nav/primitives rewrite adding framed mode, band variants, and new exported contracts
packages/ui/src/components/{agents-builder,data-rooms,billing-*,storage}/* Templates migrated to WorkspaceShell with framed prop plumbing; TableGroupRow adoption
apps/blocks/src/blocks/console-kit/*, apps/blocks/src/lib/feature-packs.ts ConsoleKit retyped onto workspace-kit nav types; feature-pack manifest gains framed
packages/ui/{package.json,registry.json,scripts/build-registry.ts,src/index.ts} app-bar/app-shell exports removed; workspace-kit subpath and registry entries added
packages/ui/src/{theme.ts,theme-tuning.ts,styles/globals.css} Light theme retune (white background, border 92%, inset hairline shadow recipe)
packages/ui/{.storybook/preview.ts,src/stories/*,test/*} Storybook decorator rewritten for theme-painted backgrounds; stories and theme tests updated for the new shell
apps/registry/scripts/smoke-install.ts, apps/registry/REGISTRY.md, docs Smoke-install expectations and docs updated for the workspace-kit layout

Reviewed commit: cf588cf

@tenki-reviewer tenki-reviewer Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR replaces the deleted AppShell/AppBar components with the workspace-kit shell/nav contracts, threads a new framed mode through every template, and retunes the light theme.

Key findings

sidebar={sidebar}
defaultSidebarCollapsed={defaultSidebarCollapsed}
framed={framed}
className={cn('rounded-xl border border-border', className)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 bug · medium

Framed StorageBrowser double-frames its canvas

In framed mode WorkspaceShell draws its own rounded-xl border border-border shadow-xs on the shell and re-routes the caller's className onto the outer canvas div (packages/ui/src/components/workspace-kit/shell.tsx:132), but StorageBrowser still bakes rounded-xl border border-border into that className (packages/ui/src/components/storage/storage-browser.tsx:342). The legacy frame classes therefore land on the full-bleed canvas, producing a doubled edge that defeats the frame's one-tier-darker look. Every other framed caller passes className through without built-in frame classes, so StorageBrowser is the odd one out.

📋 Prompt for AI Agents

In packages/ui/src/components/storage/storage-browser.tsx at line 342, change the WorkspaceShell className prop from className={cn('rounded-xl border border-border', className)} to className={framed ? className : cn('rounded-xl border border-border', className)}. WorkspaceShell routes className to the canvas div when framed is true and already draws its own rounded border on the shell (workspace-kit/shell.tsx:132), so leaving the frame classes unconditional draws a second border around the whole canvas.

The console-kit contracts now import the workspace kit through the app's
@/components/ui alias, and scripts/inspect-console-kit.ts type-checks those
contracts under tsconfig.scripts.json, which only mapped @/* to the app
source. Mirror the app's alias so both configs resolve the same files.
@yyyyaaa
yyyyaaa merged commit 7e9f277 into main Oct 5, 2026
4 checks passed
@yyyyaaa
yyyyaaa deleted the phat/light-theme-tokens branch October 5, 2026 07:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant