From 83fb6e3ce7f80a9c287764df26b6245e0945a941 Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Mon, 7 Sep 2026 16:12:58 +0900 Subject: feat(workspaces): rework tile-grid visuals — Start-screen polish MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The home canvas now reads as a real Windows 8 Start screen instead of a cramped, edge-hugging list: - Geometry: the wide unit is DERIVED from the canvas height (4 rows fill it: unit=height/5 clamped to 112-184px, gap=unit/9, margin=unit/3 clamped 24-64px) — tiles are no longer tiny, and the tile field always carries a proportional outer margin (never compressed against the left edge). Tall mode keeps fluid columns with a taller 148px row + 12px gap. - Tiles take a per-workspace SATURATED tone (new pure tileTone(id): FNV-1a hash → one of the six theme-semantic colors) with tone-content text — the Win8 colored-tile identity. Starred is now a ★ badge (a tile keeps its own color), not a gray-tint override. - The tile face is the Win8 layout: small uppercase slug caption at the top, a bold span-aware title (lg → 3xl across 1×1 → 4×2), and a single-line stat row pinned to the bottom (count compacts to 'conv.' on 1×1 tiles, truncation-safe so narrow tiles never clip). - Selection is a high-contrast offset ring (visible on any tile color); tiles lift on hover; the pan arrow is a solid elevated circle. - Header gains a 'WORKSPACES' kicker; empty/loading states are centered and styled for the Start-screen canvas. Persisted data (order + spans only) and all interaction semantics (drag/FLIP, long-press, action bar, resize picker, create popover) are untouched. Tests: geometry derivation/clamping, tileTone determinism, wide-vs-compact count label — 1664 green. --- src/features/workspaces/ui/WorkspaceTile.test.ts | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/features/workspaces/ui/WorkspaceTile.test.ts') diff --git a/src/features/workspaces/ui/WorkspaceTile.test.ts b/src/features/workspaces/ui/WorkspaceTile.test.ts index 918aa1c..b76f709 100644 --- a/src/features/workspaces/ui/WorkspaceTile.test.ts +++ b/src/features/workspaces/ui/WorkspaceTile.test.ts @@ -48,10 +48,23 @@ describe("WorkspaceTile", () => { }); expect(screen.getByText("My Workspace")).toBeInTheDocument(); expect(screen.getByText("/my-ws")).toBeInTheDocument(); - expect(screen.getByText(/3 conversations/)).toBeInTheDocument(); + // A 1×1 tile is tight: the count compacts to "conv." (wide tiles spell it out). + expect(screen.getByText(/3 conv\./)).toBeInTheDocument(); expect(screen.getByText("1m")).toBeInTheDocument(); }); + it("spells out 'conversations' on a wide tile", () => { + render(WorkspaceTile, { + props: { + ws: fakeEntry(), + store: fakeStore(), + placement: fakePlacement({ colSpan: 2, rowSpan: 1 }), + onRenameEnd: () => {}, + }, + }); + expect(screen.getByText(/3 conversations/)).toBeInTheDocument(); + }); + it("shows the active indicator only when the active port says so", async () => { const { container, rerender } = render(WorkspaceTile, { props: { -- cgit v1.2.3