From 36c8260d7d73475a087bada074dd161098541ac5 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Mon, 9 Nov 2026 12:36:28 -0600 Subject: [PATCH 1/3] docs(design): add U0 unified workspace samples (#1873) Eight static screens for PRD 1.20 phase U, for Jason's approval before U1-U5 are built: sidebar with collapsible Organizations and org marks, cross-org dashboard, org dashboard with docs, KPIs, metrics, sessions and a settings index, projects across orgs, one inbox, Kanban and list tasks with tracker badges, side-by-side panes, and agents at root, org and project level. Mock data only: three orgs (Home, Distinctly Digital, Forge), ten projects, no real names or credentials. workspace.css imports tokens.css and marks each extension EXT 1-10. render.mjs serves the samples on 127.0.0.1 port 0 and renders 32 PNGs at 1440x900 and 390x844, light and dark, failing on script errors, failed requests, sideways scroll or unloaded fonts. No WebUI code changes. --- .../01-sidebar.html | 98 ++++ .../02-dashboard.html | 87 ++++ .../03-org-dashboard.html | 92 ++++ .../04-projects.html | 164 +++++++ .../05-inbox.html | 83 ++++ .../06-tasks.html | 119 +++++ .../07-side-by-side.html | 88 ++++ .../08-agents.html | 86 ++++ .../2026-11-09-unified-workspace/render.mjs | 92 ++++ .../workspace.css | 448 ++++++++++++++++++ 10 files changed, 1357 insertions(+) create mode 100644 docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/04-projects.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/05-inbox.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/06-tasks.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/08-agents.html create mode 100644 docs/design/samples/2026-11-09-unified-workspace/render.mjs create mode 100644 docs/design/samples/2026-11-09-unified-workspace/workspace.css diff --git a/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html b/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html new file mode 100644 index 000000000..825b267c1 --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html @@ -0,0 +1,98 @@ + + + + + +Sidebar · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +
Shell
+

Sidebar

Every organization stays in view. There is no organization switcher: selecting an organization opens its dashboard, and its projects sit in the group below.

+
+
+
+ +
+
+
+
ProjectsBy orgFlat
+ +
+
+
Organizations collapsed. The row keeps the count and the three marks, so nothing disappears from view.
+
+
+ +
Projects flat, sorted by activity. Each row leads with its organization's mark.
+
+
+ +
Selected, bus unreachable, and an item waiting. Status is a symbol plus a word, never colour alone.
+
+
+
    +
  1. The org mark is a tile in the organization's theme colour with its initials (or an uploaded image), always beside the name. The type icon on the right (business, coding, personal) is the third cue the owner asked for.
  2. +
  3. Plus on the Organizations row starts the organization editor (11-07 ruling 6); it is tied to mosaic org create ID --from FILE.
  4. +
  5. Settings no longer holds an "Existing organization" select. Organization settings open from each org dashboard.
  6. +
  7. Open state of each group and the By org / Flat choice are remembered per viewer.
  8. +
  9. On a phone the sidebar becomes a drawer behind the menu button, with the same groups.
  10. +
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html b/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html new file mode 100644 index 000000000..87b97e83d --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html @@ -0,0 +1,87 @@ + + + + + +Dashboard · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Dashboard

Today7 days30 days
+

All 3 organizations and 10 projects. Totals add up every organization you belong to; each tile breaks them down by organization.

+
+
Needs you3items + +
111
oldest 52 min
+
Sessions74 working + +
3211
1 waiting · 1 error · 1 idle
+
Open tasks10 + +
532
2 done this week
+
Projects108 active + +
433
2 paused
+
Model spend$38.407 days + +
$21.10$15.60$1.70
of $110 in weekly limits
+
+
+
+

Activity across organizations

newest first, every busAll activity
+
  1. coder pushed 3 commits on #41 Rate limiter · Forge · API gateway
  2. copywriter saved V-112 Launch email, draft 2 · Distinctly Digital · Spring launch
  3. reviewer stopped: model provider timed out · Forge · Web app
  4. editor asked you: keep the revised ending? · Distinctly Digital · The Lantern Coast
  5. assistant flagged the insurance renewal · Home · Household admin
  6. montage-producer rendered teaser cut 3 of 4 · Distinctly Digital · Spring launch
  7. chief raised a gated decision: merge the rate limiter · Forge · API gateway
  8. chief created V-120 Logo shortlist in Vikunja · Distinctly Digital · Brand refresh
  9. you closed #9 Order seed potatoes · Home · Garden plan
+

Tasks by state

all trackersOpen tasks
+
+
To do5212
In progress321
Review211
Done this week211
+
+
+
+

Needs you

Inbox
+
  • Merge the rate limiter branch into main?Forge · API gateway · chiefgated
  • Chapter 7: keep the revised ending?Distinctly Digital · The Lantern Coast · editorwithin-role
  • Home insurance renews in 12 days. Compare the two quotes now?Home · Household admin · assistantroutine
+

Sessions now

Agents
+
+ +
Agent and projectStatus
assistant · All organizationsworking with you
coder · API gatewayworking 65 min
copywriter · Spring launchworking 38 min
montage-producer · Spring launchworking 72 min
editor · The Lantern Coastwaiting on you
reviewer · Web apperror timeout
planner · Household adminidle since 09:10
+
+
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html new file mode 100644 index 000000000..579233f01 --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html @@ -0,0 +1,92 @@ + + + + + +Distinctly Digital · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +
Organizations › Distinctly Digital
+
+ +

Distinctly Digital

+
+ Restart bus + Reload organization file + Open in a pane +
+
Businessid ddigitalTracker: Vikunjabus read 4 s agoRestart and reload are trailed human actions; no agent can take them.
+
+
System typesCodingCreative writingMarketingMosaic MontageBusiness managementEach project picks from these; none is required.
+ +
+
+

KPIs

defined in the organization fileEdit KPIs
+
+
Subscribers2,480+6.2% in 30 days · goal 3,000
+
Launch pieces7of 12
+
Novel draft61,200wordstarget 90,000 · 68%
+
Tasks closed1830 days · +4 on last month
+
+

Metrics

measured by the bus
+
+
Spend this week$21.10of $60
+
Agent hours31.57 days
+
Decision wait22min median
+
Open tasks52 in progress · 1 review
+
+

Active agent sessions

3 running, 1 idleAll agents
+
+ + + + +
AgentProject and taskModelStatus
copywriterSpring launchV-112 Launch email, draft 2sonnet-5.5 Changeworking 38 min
montage-producerSpring launchV-118 Teaser reel, 30 s cutsonnet-5.5 Changeworking 1 h 12 min
editorThe Lantern CoastV-97 Chapter 7 revisionopus-5.5 Changewaiting on you
chiefOrganizationroutes work from the assistantopus-5.5 Changeidle
+
+
+

Settings

every setting, with where its value comes from
+
  • IdentityDistinctly Digital · ddigital · Businessorg fileOpen
  • AppearanceRosewood theme · DD avatarorg fileOpen
  • System types5 of 5 installed enabledorg fileOpen
  • Projects4 projects · 3 with a remote, 1 local onlyorg fileOpen
  • Agents and roles5 org · 2 project · 3 from your rootorg + rootOpen
  • Models and providersYour shared proxy · editor runs opus-5.5overrideOpen
  • Task trackerVikunja module · project DDorg fileOpen
  • ChannelsDiscord off · daily email digestorg fileOpen
  • Launch limits4 sessions at once · $60 a weekorg fileOpen
  • Routing and arbiterschief routes · editor arbitrates copyorg fileOpen
  • Members and invitesYou (owner) · invites arrive in Phase Mnot builtOpen
  • BusRunning · local-only checkoutsystemOpen
  • Archive or deleteRemoves this organization's tasks and data onlydangerOpen
+
+
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/04-projects.html b/docs/design/samples/2026-11-09-unified-workspace/04-projects.html new file mode 100644 index 000000000..de6322e7e --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/04-projects.html @@ -0,0 +1,164 @@ + + + + + +Projects · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Projects

New project
+

10 projects in 3 organizations, sorted by latest activity. Every row names its organization by mark, colour edge and type icon.

+
+ Filter by name +
All 10Distinctly Digital4Forge3Home3
+ StatusActive, paused +
SortActivityNameOrgStatus
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
OrganizationProjectStatusSystem typesSessionsOpen tasksNeeds youLast activity↓Git
ForgeAPI gatewayapi-gateway2 min ago · coder pushed 3 commits on #41activeCoding1 working212 min agocoder pushed 3 commits on #41remote
Distinctly DigitalSpring launchspring-launch4 min ago · copywriter saved draft 2activeMarketing Creative writing Mosaic Montage2 working204 min agocopywriter saved draft 2remote
ForgeWeb appwebapp11 min ago · reviewer stopped: provider timeoutactiveCoding1 error1011 min agoreviewer stopped: provider timeoutremote
Distinctly DigitalThe Lantern Coastnovel-draft17 min ago · editor asked about chapter 7activeCreative writing1 waiting1117 min agoeditor asked about chapter 7local only
HomeHousehold adminhousehold30 min ago · assistant flagged a renewalactiveBusiness management1 idle1130 min agoassistant flagged a renewallocal only
Distinctly DigitalBrand refreshbrand-refresh1 h ago · chief created V-120activeMarketing Mosaic Montagenone101 h agochief created V-120remote
HomeGarden plangarden1 h ago · #9 marked doneactivenonenone001 h ago#9 marked donelocal only
Distinctly DigitalMonthly newsletternewsletteryesterday · V-121 createdactiveMarketing Creative writingnone10yesterdayV-121 createdremote
ForgeCLI toolscli-tools12 days ago · #29 donepausedCodingnone0012 days ago#29 doneremote
HomeTrip planning 2027travel3 weeks ago · #14 createdpausednonenone103 weeks ago#14 createdlocal only
+

Sorting by Org groups the rows under each organization's header. Paused projects stay listed, dimmed, and the Status filter hides them.

+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html b/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html new file mode 100644 index 000000000..a630cb903 --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html @@ -0,0 +1,83 @@ + + + + + +Inbox · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Inbox

+

3 items need you, from 3 organizations. Each row names where it came from. Seen is not resolution: an item leaves only when it is answered.

+
+
All 3Distinctly Digital1Forge1Home1
+
Needs youSeenAnswered
+
+
+ + + +
SourceNeedsClassWaiting
ForgeAPI gateway · chiefForge · API gateway · chiefMerge the rate limiter branch into main?decision 4f2a91 · seen 14:05gatedgated52 min
Distinctly DigitalThe Lantern Coast · editor sessionDistinctly Digital · The Lantern Coast · editorChapter 7: keep the revised ending?decision 7c03e2 · not seenwithin-rolewithin-role17 min
HomeHousehold admin · assistantHome · Household admin · assistantHome insurance renews in 12 days. Compare the two quotes now?decision b19d40 · not seenroutineroutine30 min
+

Answered today

kept for 24 hours, then in the trail
+
+ + +
Distinctly DigitalSpring launch · copywriterDistinctly Digital · Spring launchUse the shorter subject line?answered 11:40 by you · option 2done
ForgeWeb app · reviewer sessionForge · Web appRetry with the fallback model?expired 10:02 · no answer neededexpired
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html b/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html new file mode 100644 index 000000000..0527fd8fe --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html @@ -0,0 +1,119 @@ + + + + + +Tasks · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Tasks

KanbanListNew task
+

12 tasks from 3 organizations. Each organization keeps its own task store; this view reads all of them and writes each change back to the store it came from.

+
TrackersDistinctly Digital VikunjaForge built-inHome built-inIds keep their tracker's form: V-112 is Vikunja, #41 is built in. Archiving an organization removes only its tasks.
+
+
All 12Distinctly Digital5Forge4Home3
+ ProjectAll 10 + AssigneeAnyone +
Find a task
+
+
+

To do

5
+
#44built-in
+
Settings page: model picker
+
Web app
+
+
V-120Vikunja
+
Logo shortlist
+
Brand refresh
+
+
V-121Vikunja
+
November issue outline
+
Monthly newsletter
+
+
#12built-in
+
Insurance renewal comparison
+
Household adminneeds you
+
+
#14built-in
+
Shortlist ferry dates
+
Trip planning 2027
+
+

In progress

3
+
#41built-in
+
Rate limiter: per-key buckets
+
API gatewaycoder
+
+
V-112Vikunja
+
Launch email, draft 2
+
Spring launchcopywriter
+
+
V-118Vikunja
+
Teaser reel, 30 s cut
+
Spring launchmontage-producer
+
+

Review

2
+
#38built-in
+
Load test at 2k rps
+
API gatewayreviewer
+
+
V-97Vikunja
+
Chapter 7 revision
+
The Lantern Coasteditor, on you
+
+

Done

2
+
#29built-in
+
zsh completion
+
CLI tools
+
+
#9built-in
+
Order seed potatoes
+
Garden plan
+
+
+
+

List layout

same filters, one row per task, grouped by state
+
+ +
OrgIdTaskProjectStateAssignee
#44built-inSettings page: model pickerWeb appWeb appTo donobody
V-120VikunjaLogo shortlistBrand refreshBrand refreshTo donobody
V-121VikunjaNovember issue outlineMonthly newsletterMonthly newsletterTo donobody
#12built-inInsurance renewal comparisonHousehold adminHousehold adminTo doyou
#14built-inShortlist ferry datesTrip planning 2027Trip planning 2027To donobody
#41built-inRate limiter: per-key bucketsAPI gatewayAPI gatewayIn progresscoder
V-112VikunjaLaunch email, draft 2Spring launchSpring launchIn progresscopywriter
V-118VikunjaTeaser reel, 30 s cutSpring launchSpring launchIn progressmontage-producer
#38built-inLoad test at 2k rpsAPI gatewayAPI gatewayReviewreviewer
V-97VikunjaChapter 7 revisionThe Lantern CoastThe Lantern CoastRevieweditor
#29built-inzsh completionCLI toolsCLI toolsDonenobody
#9built-inOrder seed potatoesGarden planGarden planDonenobody
+
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html b/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html new file mode 100644 index 000000000..f83f7fc1a --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html @@ -0,0 +1,88 @@ + + + + + +Side by side · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Side by side

2 panes · each pane reads its own organization's bus and keeps its own state + Spring launch API gateway + Add pane
+
+
+
Spring launchDistinctly Digital
+
+
OverviewTasksSessionsDocs
+
Open tasks2
Sessions2working
Needs you0
+

copywriter · live

V-112 Launch email, draft 2
+
14:26 read brand-voice.md, launch-plan.md
+14:27 drafted subject lines (3), kept the shortest
+14:28 saved drafts/launch-email-v2.md  182 words
+14:29 next: tighten the call to action
+▍
+

montage-producer · live

V-118 Teaser reel
+
13:55 rendered cut 3 of 4  00:30  1080x1920
+14:10 waiting on the music bed licence check
+▍
+

Activity

+
  1. copywriter saved V-112 Launch email, draft 2 · Distinctly Digital · Spring launch
  2. montage-producer rendered teaser cut 3 of 4 · Distinctly Digital · Spring launch
  3. chief updated the launch plan · Distinctly Digital · Spring launch
+
+
+
API gatewayForge
+
+
OverviewTasksSessionsDocs
+
Open tasks2
Sessions1working
Needs you1gated
+
  • Merge the rate limiter branch into main?chief · 52 min · Open in inboxgated
+

coder · live

#41 Rate limiter: per-key buckets
+
14:30 npm test  312 passed, 0 failed
+14:31 bench: 2,140 rps at p99 41 ms
+14:32 pushed 3 commits to rate-limiter-41
+14:32 waiting for review
+▍
+

Activity

+
  1. coder pushed 3 commits on #41 Rate limiter · Forge · API gateway
  2. chief raised a gated decision: merge the rate limiter · Forge · API gateway
  3. load-tester finished run 7 of 7 · Forge · API gateway
+
+
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/08-agents.html b/docs/design/samples/2026-11-09-unified-workspace/08-agents.html new file mode 100644 index 000000000..8fe167c5c --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/08-agents.html @@ -0,0 +1,86 @@ + + + + + +Agents · U0 sample + + + + +
+
+ + Mosaic Stack + U0 sample + +
Read 3 of 3 organization buses · 4 s agoOP
+
+ + +
+ +

Agents

Edit root agents
+

Agents are defined at three levels. A project can use the union of your root agents, its organization's agents and its own. Every agent except the assistant works inside one organization.

+
assistantrootworkingWorks acrossOne shared memory. Talks with you and hands each organization's work to its chief; it does not direct agents, create tasks or launch sessions.
+
+
Distinctly Digital
Forge
Home
+
rootYour root configuration. Only you change it. Each organization runs its own copy, with memory, files and credentials kept in that organization.
+
Distinctly Digitalidlereviewer copyidleresearcher copy
+
Forgeerrorreviewer copyidleresearcher copy
+
Homeidleresearcher copyreviewer turned off for Home
+
orgDefined in the organization file. The chief hires and fires here; you can override any setting.
+
Distinctly Digitalidlechiefworkingcopywriterwaitingeditorworkingmontage-producer
+
Forgeidlechiefworkingcoder
+
Homeidlechiefidleplanner
+
projectDefined in one project and available only there. The chief hires and fires here too.
+
Distinctly Digitalidlesocial-scheduler Spring launchidlecontinuity-checker The Lantern Coast
+
Forgeidleload-tester API gateway
+
Homenone
+
+
+
+

Available in a project

Spring launch
+
+ +
AgentLevelDefined inMemoryStatusModel
assistantrootYour root configurationShared across all organizationsworkingopus-5.5 Change
reviewerrootYour root configurationThis organization onlyidlesonnet-5.5 Change
researcherrootYour root configurationThis organization onlyidlesonnet-5.5 Change
chieforgDistinctly Digital fileThis organization onlyidleopus-5.5 Change
copywriterorgDistinctly Digital fileThis organization onlyworkingsonnet-5.5 Change
editororgDistinctly Digital fileThis organization onlywaitingopus-5.5 Change
montage-producerorgDistinctly Digital fileThis organization onlyworkingsonnet-5.5 Change
social-schedulerprojectSpring launch projectThis organization onlyidlehaiku-5.5 Change
+

Not available here: continuity-checker (The Lantern Coast only) and every Forge or Home agent.

+
+
+

Who changes what

+
+

root You add, change and remove root agents. The chief cannot.

+

org project The chief hires and fires to meet your needs, within the role rules. Each hire lands in the trail.

+

override You can change any agent's settings at any level, at any time. An override shows where it was set.

+

Changing an agent's model is a trailed human action, applied to its running session on reload.

+
+
+
+
+ +
+ + diff --git a/docs/design/samples/2026-11-09-unified-workspace/render.mjs b/docs/design/samples/2026-11-09-unified-workspace/render.mjs new file mode 100644 index 000000000..0947f7aa7 --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/render.mjs @@ -0,0 +1,92 @@ +// Renders the U0 samples to PNG with headless Chromium: every page at 1440x900 and 390x844, +// light and dark (prefers-color-scheme, no data-mode), 32 shots for 8 pages. +// Usage: node render.mjs +// Serves the repository over HTTP on 127.0.0.1, port 0, because Chromium refuses cross-file SVG +// under file://. Only docs/design/ and the WebUI font directory are served. +// Checks each shot: no script error, no failed request, no sideways page scroll, fonts loaded. +import { createServer } from 'node:http'; +import { readFile, mkdir } from 'node:fs/promises'; +import { join, normalize, extname, dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { browser } from '../../../../packages/webui/tests/browser.mjs'; + +const here = dirname(fileURLToPath(import.meta.url)); +const repo = normalize(join(here, '../../../..')); +const out = process.argv[2]; +if (!out) { console.error('usage: node render.mjs '); process.exit(2); } +await mkdir(out, { recursive: true }); + +const ALLOW = ['docs/design/', 'packages/webui/src/public/assets/fonts/']; +const TYPES = { '.html': 'text/html', '.css': 'text/css', '.svg': 'image/svg+xml', '.woff2': 'font/woff2', '.js': 'text/javascript' }; +const failed = []; +const server = createServer(async (req, res) => { + const path = normalize(decodeURIComponent(new URL(req.url, 'http://x').pathname)).replace(/^\/+/, ''); + if (path === 'favicon.ico') { res.writeHead(204).end(); return; } + if (path.includes('..') || !ALLOW.some((a) => path.startsWith(a))) { failed.push(`403 ${path}`); res.writeHead(403).end(); return; } + try { + const body = await readFile(join(repo, path)); + res.writeHead(200, { 'content-type': TYPES[extname(path)] ?? 'application/octet-stream' }).end(body); + } catch { failed.push(`404 ${path}`); res.writeHead(404).end(); } +}); +await new Promise((r) => server.listen(0, '127.0.0.1', r)); +const base = `http://127.0.0.1:${server.address().port}/docs/design/samples/2026-11-09-unified-workspace/`; + +const PAGES = ['01-sidebar', '02-dashboard', '03-org-dashboard', '04-projects', '05-inbox', '06-tasks', '07-side-by-side', '08-agents']; +const SIZES = [[1440, 900], [390, 844]]; +const THEMES = ['light', 'dark']; +const CHECK = `(() => { + const vw = innerWidth, wide = []; + for (const el of document.querySelectorAll('body *')) { + const r = el.getBoundingClientRect(); + if (!r.width || r.right <= vw + 1) continue; + let clipped = false; + for (let p = el.parentElement; p && p !== document.body; p = p.parentElement) { + const s = getComputedStyle(p); + if (/(auto|hidden|scroll|clip)/.test(s.overflowX) || s.position === 'fixed' && s.display === 'none') { clipped = true; break; } + } + if (!clipped && getComputedStyle(el).visibility !== 'hidden') wide.push(el.tagName.toLowerCase() + (el.className && typeof el.className === 'string' ? '.' + el.className.trim().split(/\\s+/).join('.') : '')); + } + const faces = [...document.fonts].map((f) => f.family.replace(/"/g, '') + ' ' + f.weight + ' ' + f.status); + return { sw: document.documentElement.scrollWidth, cw: document.documentElement.clientWidth, wide: wide.slice(0, 8), faces, + manrope800: document.fonts.check('800 16px Manrope'), dark: matchMedia('(prefers-color-scheme: dark)').matches, + canvas: getComputedStyle(document.body).backgroundColor }; +})()`; + +const b = await browser({ machine: false }); +const errors = []; +b.on('Runtime.exceptionThrown', (p) => errors.push(p.exceptionDetails?.exception?.description ?? p.exceptionDetails?.text)); +b.on('Runtime.consoleAPICalled', (p) => { if (p.type === 'error') errors.push(p.args.map((a) => a.value ?? a.description).join(' ')); }); +const report = []; +let bad = 0; +try { + for (const [w, h] of SIZES) { + await b.viewport(w, h); + for (const theme of THEMES) { + await b.call('Emulation.setEmulatedMedia', { features: [{ name: 'prefers-color-scheme', value: theme }] }); + for (const name of PAGES) { + errors.length = 0; failed.length = 0; + await b.navigate(base + name + '.html'); + await new Promise((r) => setTimeout(r, 250)); + const info = await b.evaluate(CHECK); + const file = `${name}-${w}-${theme}.png`; + await b.screenshot(join(out, file)); + const problems = []; + if (errors.length) problems.push('script: ' + errors.join(' | ')); + if (failed.length) problems.push('requests: ' + failed.join(', ')); + if (info.sw > info.cw) problems.push(`sideways scroll ${info.sw}>${info.cw}`); + if (info.wide.length) problems.push('past the edge: ' + info.wide.join(', ')); + if (info.faces.some((f) => !f.endsWith('loaded') && !f.endsWith('unloaded'))) problems.push('fonts: ' + info.faces.join(', ')); + if (!info.faces.some((f) => f.startsWith('Manrope') && f.endsWith('loaded') && !f.endsWith('unloaded'))) problems.push('Manrope not loaded'); + if (info.dark !== (theme === 'dark')) problems.push('theme emulation failed'); + if (problems.length) bad++; + report.push({ file, canvas: info.canvas, problems }); + } + } + } +} finally { + await b.close(); + server.close(); +} +for (const r of report) console.log(`${r.problems.length ? 'FAIL' : 'ok '} ${r.file} ${r.canvas}${r.problems.length ? '\n ' + r.problems.join('\n ') : ''}`); +console.log(`${report.length} shots, ${bad} with problems`); +process.exit(bad ? 1 : 0); diff --git a/docs/design/samples/2026-11-09-unified-workspace/workspace.css b/docs/design/samples/2026-11-09-unified-workspace/workspace.css new file mode 100644 index 000000000..bdbf9d188 --- /dev/null +++ b/docs/design/samples/2026-11-09-unified-workspace/workspace.css @@ -0,0 +1,448 @@ +/* U0 unified workspace samples, 2026-11-09. Static mocks, not product code. + Colours, type, spacing and radii come from tokens.css. The few additions are marked EXT + and listed in the U0 design report; nothing here redefines a token. */ +@import url("../../tokens.css"); + +/* Fonts: the WebUI's self-hosted files, so the samples render with no network. The four + manrope-*.woff2 files are one variable font (weights 200 to 800), so one face covers 400-800. */ +@font-face{font-family:"Manrope";font-style:normal;font-weight:200 800;font-display:swap;src:url("../../../../packages/webui/src/public/assets/fonts/manrope-400.woff2") format("woff2")} +@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:400;font-display:swap;src:url("../../../../packages/webui/src/public/assets/fonts/jetbrains-mono-400.woff2") format("woff2")} +@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:500;font-display:swap;src:url("../../../../packages/webui/src/public/assets/fonts/jetbrains-mono-500.woff2") format("woff2")} +@font-face{font-family:"JetBrains Mono";font-style:normal;font-weight:700;font-display:swap;src:url("../../../../packages/webui/src/public/assets/fonts/jetbrains-mono-700.woff2") format("woff2")} + +/* EXT 1: org identity colours. Each organization's mark takes the action colour of the palette + its theme uses (11-07 ruling 7), copied from tokens.json for the three sample palettes, with + that palette's onAction for the initials. The shell keeps the user's own palette. */ +:root{--org-grove:#377752;--org-rosewood:#a53b72;--org-atlantic:#19719a;--org-on:#ffffff} +@media (prefers-color-scheme:dark){:root:not([data-mode="light"]):not([data-mode="dim"]){--org-grove:#8fcca9;--org-rosewood:#d487af;--org-atlantic:#73c3e8;--org-on:#10141a}} +:root[data-mode="dark"]{--org-grove:#8fcca9;--org-rosewood:#d487af;--org-atlantic:#73c3e8;--org-on:#10141a} +:root[data-mode="dim"]{--org-grove:#8fcca9;--org-rosewood:#dc9ebe;--org-atlantic:#73c3e8;--org-on:#10141a} +[data-org="home"]{--org:var(--org-grove)} +[data-org="ddigital"]{--org:var(--org-rosewood)} +[data-org="forge"]{--org:var(--org-atlantic)} + +*{box-sizing:border-box} +html{-webkit-text-size-adjust:100%} +html,body{height:100%} +body{margin:0;background:var(--canvas);color:var(--text);font:400 14px/1.5 var(--font)} +h1,h2,h3,h4{color:var(--strong);margin:0;line-height:1.2;text-wrap:balance} +p{margin:0} +a{color:var(--action)} +code,kbd,.mono{font-family:var(--mono);font-size:12.5px} +kbd{border:1px solid var(--line);border-bottom-width:2px;border-radius:4px;padding:0 .35em;background:var(--surface);color:var(--strong);white-space:nowrap;font-size:11px} +button,select,input{font:inherit;color:inherit} +:focus-visible{outline:2px solid var(--focus);outline-offset:2px} +.tnum{font-variant-numeric:tabular-nums} +.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap} +svg.i{width:18px;height:18px;flex:none;fill:none;stroke:currentColor;stroke-width:1.75;stroke-linecap:round;stroke-linejoin:round} +svg.i.sm{width:15px;height:15px} +.label{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)} +.note{font-size:13px;color:var(--muted)} +.muted{color:var(--muted)} +.sim{display:inline-flex;align-items:center;gap:4px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--accent);border:1px dashed var(--accent);border-radius:4px;padding:0 5px;white-space:nowrap} + +/* ---------- shell: command bar, section list, main, inspector (d3 layout) ---------- */ +.app{display:grid;grid-template-columns:240px minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);height:100vh} +.app.with-insp{grid-template-columns:240px minmax(0,1fr) minmax(300px,360px)} +.cmdbar{grid-column:1/-1;display:flex;align-items:center;gap:12px;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--surface);min-width:0} +.cmdbar .mk{display:flex;align-items:center;gap:8px;font-weight:800;color:var(--strong);letter-spacing:-.01em;white-space:nowrap;text-decoration:none} +.cmdbar .mk svg{width:20px;height:auto;color:var(--action)} +.cmdbar .menu{display:none;border:1px solid var(--line);background:var(--canvas);border-radius:var(--r);padding:4px;color:var(--strong)} +.cmdk{flex:1;max-width:520px;display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--canvas);border-radius:var(--r);padding:5px 10px;color:var(--muted);text-align:left;min-width:0} +.cmdk span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.fresh{display:flex;align-items:center;gap:8px;margin-left:auto;font-size:12px;color:var(--muted);white-space:nowrap} +.fresh b{color:var(--success);font-weight:600} +.me{display:inline-grid;place-items:center;width:28px;height:28px;border-radius:50%;background:var(--raised);color:var(--strong);font-weight:700;font-size:12px;flex:none} + +.side{border-right:1px solid var(--line);background:var(--surface);overflow:auto;scrollbar-width:thin;scrollbar-color:var(--line) transparent;padding:10px 8px 14px;display:flex;flex-direction:column;gap:2px;min-height:0} +.nav{display:flex;align-items:center;gap:9px;padding:5px 8px;border-radius:var(--r);color:var(--text);text-decoration:none;font-weight:600;font-size:13.5px;min-width:0} +.nav:hover{background:var(--raised)} +.nav[aria-current="page"]{background:color-mix(in srgb,var(--action) 13%,var(--surface));color:var(--strong)} +.nav[aria-current="page"] svg.i{color:var(--action)} +.nav .t{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.n{margin-left:auto;font:600 11px var(--mono);color:var(--muted);font-variant-numeric:tabular-nums} +.n.hot{color:var(--surface);background:var(--danger);border-radius:999px;padding:0 6px} +.side hr,.specimen .mini hr{border:0;border-top:1px solid var(--line);margin:6px 4px} +.side .foot{margin-top:auto;padding-top:8px} + +/* EXT 2: collapsible sidebar group. A label row with a chevron; closed groups keep their count. */ +.grp{display:flex;flex-direction:column;gap:1px} +.grp-h{display:flex;align-items:center;gap:6px;padding:10px 8px 4px;color:var(--muted)} +.grp-h .label{flex:1} +.grp-h svg.i{width:14px;height:14px;transition:transform .15s} +.grp-h[aria-expanded="false"] svg.chev{transform:rotate(-90deg)} +.grp-h .seg{margin-left:auto} +.seg{display:inline-flex;border:1px solid var(--line);border-radius:var(--r);overflow:hidden;background:var(--surface)} +.seg > span,.seg > button{border:0;background:none;padding:2px 8px;color:var(--muted);font-size:12px;font-weight:600;display:inline-flex;align-items:center;gap:5px;white-space:nowrap} +.seg [aria-pressed="true"]{background:var(--action);color:var(--onAction)} +.seg.xs > span{padding:0 6px;font-size:11px} + +/* EXT 3: org mark. Avatar tile in the org's colour with its initials (or image), always beside the + name or initials in text: colour is never the only cue. Sizes 16, 20, 28, 44. */ +.av{display:inline-grid;place-items:center;flex:none;width:20px;height:20px;border-radius:5px;background:var(--org,var(--muted));color:var(--org-on);font:700 9.5px/1 var(--font);letter-spacing:.02em} +.av.xs{width:16px;height:16px;border-radius:4px;font-size:8.5px;letter-spacing:0} +.av.md{width:28px;height:28px;border-radius:7px;font-size:12px} +.av.lg{width:44px;height:44px;border-radius:10px;font-size:17px} +.av.all{background:var(--raised);color:var(--strong)} +.orgref{display:inline-flex;align-items:center;gap:6px;white-space:nowrap;color:var(--strong);font-weight:600} +.orgref.quiet{color:var(--text);font-weight:500} +.org-row .ic{color:var(--muted)} +.org-row .ic svg.i{width:15px;height:15px} +/* Org edge: a 3px stripe in the org colour on cards, rows and panes that belong to one org. */ +.edge{box-shadow:inset 3px 0 0 var(--org)} + +.pgroup{display:flex;flex-direction:column;gap:1px;margin-bottom:4px} +.pgroup-h{display:flex;align-items:center;gap:7px;padding:4px 8px 2px;font-size:12px;font-weight:700;color:var(--strong)} +.pgroup-h svg.i{width:13px;height:13px;color:var(--muted)} +.proj{padding-left:20px;padding-top:3px;padding-bottom:3px;font-weight:500;font-size:13px} +.proj .dot-s{font:400 12px/1 var(--glyph);width:12px;text-align:center} + +.main{overflow:auto;min-width:0;min-height:0;padding:18px 24px 28px} +.crumb{font-size:12.5px;color:var(--muted);margin-bottom:4px;display:flex;gap:6px;align-items:center;flex-wrap:wrap} +.crumb a{color:var(--muted)} +.vh{display:flex;flex-wrap:wrap;gap:8px 14px;align-items:center;margin-bottom:14px} +.vh h1{font-size:28px;font-weight:800;letter-spacing:-.02em} +.vh .sub{flex-basis:100%;font-size:13.5px;color:var(--muted)} +.vh .right{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap} +h2.sec{font-size:20px;font-weight:800;letter-spacing:-.015em} +h3.q{font-size:16px;font-weight:700} +.sec-h{display:flex;align-items:baseline;gap:10px;margin:22px 0 8px;flex-wrap:wrap} +.sec-h h2,.sec-h h3{font-size:15px;font-weight:700} +.sec-h .note{flex:1} +.sec-h a{font-size:13px;font-weight:600;text-decoration:none} + +.panel{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);padding:16px;min-width:0} +.panel.tight{padding:12px 14px} +.grid{display:grid;gap:var(--gap)} +.g2{grid-template-columns:repeat(2,minmax(0,1fr))} +.g3{grid-template-columns:repeat(3,minmax(0,1fr))} +.g4{grid-template-columns:repeat(4,minmax(0,1fr))} +.g5{grid-template-columns:repeat(5,minmax(0,1fr))} +.split{display:grid;gap:16px;grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);align-items:start} + +/* status vocabulary: symbol plus word, never colour alone */ +.dot{display:inline-flex;align-items:center;gap:6px;white-space:nowrap} +/* EXT 10, status glyph font: Manrope has no geometric shapes, and the generic fallback (Liberation Sans here) + draws the waiting half-circle at half the size of the dot. Name fonts that draw all five at one size. */ +:root{--glyph:"DejaVu Sans","Segoe UI Symbol","Apple Symbols","Noto Sans Symbols 2",var(--font)} +.dot b{font:400 13px/1 var(--glyph);width:14px;text-align:center} +.s-working b{color:var(--success)}.s-waiting b{color:var(--warning)}.s-error b{color:var(--danger)} +.s-offline b,.s-idle b,.s-unknown b{color:var(--muted)} +.chip{display:inline-flex;align-items:center;gap:5px;font-size:12px;font-weight:600;padding:1px 7px;border-radius:4px;background:var(--raised);color:var(--strong);white-space:nowrap} +.chip.gated{background:color-mix(in srgb,var(--danger) 14%,var(--surface));color:var(--danger)} +.chip.block{background:var(--danger);color:var(--surface)} +.chip.cross{background:color-mix(in srgb,var(--accent) 16%,var(--surface));color:var(--accent)} +.chip.within,.chip.routine{background:var(--raised);color:var(--muted)} +.chip.warn{background:color-mix(in srgb,var(--warning) 16%,var(--surface));color:var(--warning)} +.chip.ok{background:color-mix(in srgb,var(--success) 15%,var(--surface));color:var(--success)} +.chip.outline{background:none;border:1px solid var(--line);color:var(--text);font-weight:500} +.chips{display:flex;gap:6px;flex-wrap:wrap;align-items:center} +.chips .f{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--surface);border-radius:999px;padding:2px 10px 2px 4px;font-size:12.5px;font-weight:600;color:var(--text);white-space:nowrap} +.chips .f.plain{padding-left:10px} +.chips .f[aria-pressed="true"]{background:var(--strong);color:var(--surface);border-color:var(--strong)} +.chips .f .av{width:18px;height:18px;border-radius:999px;font-size:8.5px;letter-spacing:0} +.chips .f .n{margin-left:2px;color:inherit;opacity:.8} + +.btn{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--surface);border-radius:var(--r);padding:4px 10px;font-size:13px;font-weight:600;color:var(--strong);white-space:nowrap;text-decoration:none} +.btn.pri{background:var(--action);border-color:var(--action);color:var(--onAction)} +.btn.ghost{border-color:transparent;background:none;color:var(--muted)} +.btn svg.i{width:15px;height:15px} +.sel{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--surface);border-radius:var(--r);padding:3px 8px;font-size:13px;color:var(--strong);white-space:nowrap} +.sel .label{font-size:10px} +.sel svg.i{width:13px;height:13px;color:var(--muted)} +.search{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--surface);border-radius:var(--r);padding:3px 8px;color:var(--muted);font-size:13px;min-width:180px} +.toolbar{display:flex;flex-wrap:wrap;gap:8px 10px;align-items:center;margin-bottom:12px} +.toolbar .right{margin-left:auto;display:flex;gap:8px;align-items:center;flex-wrap:wrap} + +/* dense tables */ +.tbl{overflow-x:auto;border:1px solid var(--line);border-radius:var(--r-table);background:var(--surface)} +table{border-collapse:collapse;width:100%;font-size:13px} +th{font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);text-align:left;padding:7px 10px;border-bottom:1px solid var(--line);white-space:nowrap;background:var(--surface)} +th.sorted{color:var(--strong)} +th .ar{font-family:var(--mono);margin-left:3px;color:var(--action)} +td{padding:7px 10px;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent);vertical-align:middle} +tr:last-child td{border-bottom:0} +td.num,th.num{text-align:right;font-variant-numeric:tabular-nums} +td.mono{font-family:var(--mono);font-size:12.5px;white-space:nowrap} +td .t1{color:var(--strong);font-weight:600} +td .t2{display:block;font-size:12px;color:var(--muted)} +tbody tr.row[aria-selected="true"]{background:color-mix(in srgb,var(--action) 10%,var(--surface));box-shadow:inset 3px 0 0 var(--action)} +tbody tr.dim td{color:var(--muted)} + +/* EXT 4: metric tile with a per-org breakdown. The total is the headline; the stacked bar and the + labelled list under it carry the same numbers by org, so the bar is never read on colour alone. */ +.tile{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-table);padding:12px 14px;min-width:0;display:grid;gap:6px;align-content:start} +.tile .big{font-size:24px;font-weight:800;color:var(--strong);letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.1} +.tile .big small{font-size:13px;font-weight:600;color:var(--muted);letter-spacing:0;margin-left:4px} +.tile .delta{font-size:12px;color:var(--muted)} +.tile .delta b{color:var(--success);font-weight:600} +.tile .delta b.down{color:var(--danger)} +.bar{display:flex;height:6px;border-radius:3px;overflow:hidden;background:var(--raised);gap:2px} +.bar i{display:block;background:var(--org,var(--action))} +.by{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:12px;color:var(--text)} +.by span{display:inline-flex;align-items:center;gap:4px;white-space:nowrap;font-variant-numeric:tabular-nums} +.by .av{width:14px;height:14px;border-radius:3px;font-size:7px} + +/* activity trail across orgs */ +.trail{list-style:none;margin:0;padding:0;border:1px solid var(--line);border-radius:var(--r-table);background:var(--surface)} +.trail li{display:grid;grid-template-columns:48px 20px minmax(0,1fr);gap:10px;padding:7px 12px;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent);font-size:13px;align-items:center} +.trail li:last-child{border-bottom:0} +.trail time{font-family:var(--mono);font-size:12px;color:var(--muted)} +.trail .what{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.trail .what b{color:var(--strong);font-weight:600} +.trail .what .src{color:var(--muted)} + +/* needs-you list (inbox rows on dashboards) */ +.needs{list-style:none;margin:0;padding:0;display:grid;gap:8px} +.needs li{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:4px 10px;align-items:center;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-table);padding:9px 12px} +.needs .q{color:var(--strong);font-weight:600;font-size:13.5px} +.needs .src{grid-column:2;font-size:12px;color:var(--muted)} +.needs .chip{grid-row:1/3;grid-column:3} + +.kv{display:grid;grid-template-columns:auto 1fr;gap:5px 12px;margin:0;font-size:13px} +.kv dt{color:var(--muted)} +.kv dd{margin:0;color:var(--strong);min-width:0;overflow-wrap:anywhere} + +/* EXT 5: settings index. Every configurable is one row: group, current value, where the value comes + from, and a link to its editor. The dashboard reaches every setting without showing all inline. */ +.cfg{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));border:1px solid var(--line);border-radius:var(--r-table);background:var(--surface);overflow:hidden} +.cfg li{display:grid;grid-template-columns:22px minmax(0,1fr) auto;gap:2px 10px;align-items:center;padding:9px 12px;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent);border-right:1px solid color-mix(in srgb,var(--line) 60%,transparent)} +.cfg li:nth-child(2n){border-right:0} +.cfg li:nth-last-child(-n+2){border-bottom:0} +.cfg svg.i{color:var(--muted);width:16px;height:16px} +.cfg .k{font-weight:600;color:var(--strong);font-size:13px} +.cfg .v{grid-column:2;font-size:12px;color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.cfg .go{grid-row:1/3;grid-column:3;font-size:12.5px;font-weight:600;text-decoration:none} +.src-tag{font:500 11px var(--mono);color:var(--accent)} + +.docs{list-style:none;margin:0;padding:0;display:grid;gap:2px} +.docs li{display:grid;grid-template-columns:18px minmax(0,1fr) auto;gap:10px;align-items:center;padding:6px 4px;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent);font-size:13px} +.docs li:last-child{border-bottom:0} +.docs svg.i{width:16px;height:16px;color:var(--muted)} +.docs .d{color:var(--strong);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.docs time{font-size:12px;color:var(--muted);white-space:nowrap} + +/* org header on the org dashboard */ +.orghead{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:14px} +.orghead h1{font-size:28px;font-weight:800;letter-spacing:-.02em;display:flex;align-items:center;gap:10px} +.orghead h1 svg.i{width:20px;height:20px;color:var(--muted)} +.orghead .meta{flex-basis:100%;display:flex;flex-wrap:wrap;gap:4px 14px;font-size:13px;color:var(--muted);margin-top:-6px;padding-left:58px} +.orghead .right{margin-left:auto;display:flex;gap:8px;flex-wrap:wrap} +.typechips{display:flex;flex-wrap:wrap;gap:6px} + +/* EXT 6: Kanban. Columns by state; a card carries the org mark, the task id from its tracker, the + project and the assignee's status. Cards from several orgs share one column. */ +.board{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;align-items:start} +.col{background:color-mix(in srgb,var(--raised) 55%,var(--canvas));border:1px solid var(--line);border-radius:var(--r-lg);padding:8px;display:grid;gap:8px;min-width:0} +.col-h{display:flex;align-items:center;gap:8px;padding:2px 4px} +.col-h h3{font-size:13px;font-weight:700} +.col-h .n{margin-left:0} +.col-h .mix{margin-left:auto;display:flex;gap:2px} +.kcard{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-table);padding:8px 10px 8px 12px;display:grid;gap:5px;min-width:0} +.kcard .top{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)} +.kcard .top .id{font:500 11.5px var(--mono);color:var(--muted)} +.kcard .top .trk{margin-left:auto} +.kcard .tt{color:var(--strong);font-weight:600;font-size:13px;line-height:1.35} +.kcard .bot{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--muted);flex-wrap:wrap} +.kcard.you{border-color:color-mix(in srgb,var(--warning) 55%,var(--line))} +/* EXT 7: tracker badge. Names the task tracker module behind an org: built-in or Vikunja. */ +.trk{display:inline-flex;align-items:center;gap:4px;font:600 10.5px var(--mono);letter-spacing:.02em;padding:0 5px;border-radius:3px;border:1px solid var(--line);color:var(--muted);white-space:nowrap} +.trk.vik{border-style:dashed;color:var(--accent);border-color:color-mix(in srgb,var(--accent) 60%,var(--line))} +.trackers{display:flex;flex-wrap:wrap;gap:6px 16px;align-items:center;font-size:12.5px;color:var(--text);padding:8px 12px;border:1px solid var(--line);border-radius:var(--r-table);background:var(--surface);margin-bottom:12px} +.trackers > span{display:inline-flex;align-items:center;gap:6px} + +/* EXT 8: side-by-side panes. Each pane has its own header with the org mark and edge, and its own + scroll; panes never share state. Two panes at 1440; one pane with a pane switcher on a phone. */ +.panes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:0;height:100%;min-height:0} +.pane{display:flex;flex-direction:column;min-width:0;min-height:0;border-right:1px solid var(--line)} +.pane:last-child{border-right:0} +.pane-h{display:flex;align-items:center;gap:8px;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--surface);box-shadow:inset 0 3px 0 var(--org);min-width:0} +.pane-h .ttl{font-weight:700;color:var(--strong);overflow:hidden;text-overflow:ellipsis;white-space:nowrap} +.pane-h .ttl small{font-weight:500;color:var(--muted);margin-left:6px} +.pane-h .tools{margin-left:auto;display:flex;gap:2px} +.pane-h .tools span{display:inline-grid;place-items:center;width:26px;height:26px;border-radius:var(--r);color:var(--muted)} +.pane-body{overflow:auto;padding:14px;min-height:0;flex:1} +.pane-tabs{display:none} +.main.flush{padding:0;overflow:hidden;display:flex;flex-direction:column} +.panebar{display:flex;align-items:center;gap:10px;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--canvas);flex-wrap:wrap} +.panebar h1{font-size:16px;font-weight:700} + +/* EXT 9: agent level badge and the three-level map. */ +.lvl{display:inline-flex;align-items:center;gap:4px;font:700 10.5px var(--font);letter-spacing:.06em;text-transform:uppercase;padding:1px 6px;border-radius:3px;white-space:nowrap} +.lvl.root{background:var(--strong);color:var(--surface)} +.lvl.org{background:color-mix(in srgb,var(--org,var(--action)) 18%,var(--surface));color:var(--strong);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--org,var(--action)) 50%,transparent)} +.lvl.proj{background:none;color:var(--text);box-shadow:inset 0 0 0 1px var(--line)} +.levels{display:grid;grid-template-columns:200px repeat(3,minmax(0,1fr));border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;background:var(--surface)} +.levels > div{padding:10px 12px;border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent);border-right:1px solid color-mix(in srgb,var(--line) 60%,transparent);min-width:0} +.levels > div:nth-child(4n){border-right:0} +.levels .lh{background:color-mix(in srgb,var(--raised) 45%,var(--surface));display:grid;gap:4px;align-content:start} +.levels .lh small{font-size:11.5px;color:var(--muted);line-height:1.35} +.levels .lh .lvl{justify-self:start} +.levels .oh{display:flex;align-items:center;gap:8px;font-weight:700;color:var(--strong);background:color-mix(in srgb,var(--raised) 45%,var(--surface))} +.levels .span3{grid-column:2/5;border-right:0} +.levels .last{border-bottom:0} +.agent{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:999px;padding:2px 10px 2px 8px;font-size:12.5px;font-weight:600;color:var(--strong);background:var(--canvas);white-space:nowrap;margin:2px 4px 2px 0} +.agent .dot b{width:auto} +.agent.assist{border-color:var(--action);background:color-mix(in srgb,var(--action) 10%,var(--surface))} +.agent.cos{border-style:solid} +.agent small{font-weight:500;color:var(--muted)} +.inst{display:flex;flex-wrap:wrap;gap:4px;margin-top:6px} +.span-band{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:8px 12px;border-radius:var(--r-table);border:1px solid var(--action);background:color-mix(in srgb,var(--action) 8%,var(--surface));font-size:13px;color:var(--strong)} +.span-band .orgs{display:flex;gap:4px} + +/* inspector */ +.insp{border-left:1px solid var(--line);background:var(--surface);overflow:auto;min-height:0;display:flex;flex-direction:column} +.insp header{display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:1px solid var(--line);position:sticky;top:0;background:var(--surface);z-index:1} +.insp header .x{margin-left:auto;color:var(--muted);display:inline-flex} +.insp .body{padding:14px;display:grid;gap:14px} +.insp h3{font-size:16px;font-weight:700} +.opts{list-style:none;margin:0;padding:0;display:grid;gap:8px} +.opts li{border:1px solid var(--line);border-radius:var(--r-table);padding:9px 10px;display:grid;gap:6px;background:var(--canvas)} +.opts li.rec{border-color:var(--action)} +.opts .k{font:700 13px var(--mono);color:var(--strong)} +.opts .row{display:flex;gap:8px;align-items:center;flex-wrap:wrap} +.cmd{display:flex;gap:6px;align-items:center;min-width:0} +.cmd code{flex:1;min-width:0;overflow-x:auto;white-space:nowrap;background:var(--surface);border:1px solid var(--line);border-radius:4px;padding:3px 6px;font-size:12px;color:var(--strong)} +ol.hist{list-style:none;margin:0;padding:0;display:grid;gap:6px;font-size:12.5px} +ol.hist li{display:grid;grid-template-columns:48px 1fr;gap:8px} +ol.hist time{font-family:var(--mono);color:var(--muted)} +.auth{border:1px solid var(--line);border-left:3px solid var(--org,var(--action));border-radius:0 6px 6px 0;padding:8px 10px;background:var(--canvas);font-size:13px;color:var(--strong)} + +/* inbox list */ +.ibx td.src{white-space:nowrap} +.ibx .q{color:var(--strong);font-weight:600} +.ibx .via{display:block;font-size:12px;color:var(--muted)} + +/* sidebar details: add button, collapsed marks, project rail */ +.grp-h .add{display:inline-grid;place-items:center;width:22px;height:22px;border-radius:var(--r);color:var(--muted);border:1px solid var(--line)} +.grp-h .n{margin-left:0} +.collapsed-marks{display:flex;gap:4px;padding:0 8px 6px 28px} +.pgroup .projs{margin-left:17px;border-left:2px solid var(--org);display:flex;flex-direction:column;gap:1px} +.pgroup .proj{padding-left:10px} +.proj.flat{padding-left:8px} +.proj .n{font-family:var(--font);font-weight:500;font-size:11px} +.s-ok b{color:var(--success)} + +/* tasks by state on the main dashboard */ +.states{display:grid;gap:8px} +.srow{display:grid;grid-template-columns:112px 24px minmax(0,1fr) auto;gap:10px;align-items:center;font-size:13px} +.srow .sl{color:var(--strong);font-weight:600} +.srow .sn{font:700 13px var(--mono);color:var(--strong);text-align:right} +.srow .bar{height:8px;max-width:100%} +.needs li > .av{grid-row:1/3} + +/* settings index, one column, with the destructive row set apart */ +.cfg.one{grid-template-columns:minmax(0,1fr)} +.cfg.one li{grid-template-columns:18px 132px minmax(0,1fr) auto auto;gap:0 10px;border-right:0;padding:7px 12px} +.cfg.one .v{grid-column:3;grid-row:1} +.cfg.one .src-tag{grid-column:4;grid-row:1} +.cfg.one .go{grid-column:5;grid-row:1} +.cfg.one li:nth-last-child(2){border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent)} +.cfg li.danger .k,.cfg li.danger svg.i,.cfg li.danger .go{color:var(--danger)} + +/* live transcript, mini tiles and sub tabs inside a pane */ +.term{margin:0;font:400 12px/1.55 var(--mono);background:var(--canvas);color:var(--text);border:1px solid var(--line);border-radius:var(--r-table);padding:8px 10px;white-space:pre-wrap;overflow-wrap:anywhere} +.term .m{color:var(--muted)} +.term .c{color:var(--action)} +.mini-tiles .tile{padding:8px 10px;gap:2px} +.mini-tiles .tile .big{font-size:20px} +.subtabs{display:flex;gap:2px;border-bottom:1px solid var(--line);margin:-4px 0 12px} +.subtabs span{padding:4px 10px;font-size:13px;font-weight:600;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px} +.subtabs [aria-current="page"]{color:var(--strong);border-bottom-color:var(--org,var(--action))} +.rules{display:grid;gap:10px;font-size:13px} +.rules p{display:flex;gap:6px;flex-wrap:wrap;align-items:baseline} + +/* one-line session rows on the main dashboard */ +.sess td.who{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:0;width:100%} +.sess td.who .orgref{vertical-align:middle} +.sess td.st{white-space:nowrap} + +/* docs row on the org dashboard */ +.docrow{margin-top:8px} +.docrow .doc{display:inline-flex;align-items:center;gap:5px;border:1px solid var(--line);background:var(--surface);border-radius:var(--r);padding:2px 8px;font-size:12.5px;font-weight:600;color:var(--strong);text-decoration:none;white-space:nowrap} +.docrow .doc svg.i{width:14px;height:14px;color:var(--muted)} +.docrow .doc small{font-weight:500;color:var(--muted)} +.docrow .more{font-size:13px;font-weight:600;text-decoration:none;margin-left:4px} + +/* source line inside a row, used on a phone where the source column is hidden */ +.msrc{align-items:center;gap:5px;font-size:12px;color:var(--muted);margin-bottom:2px} +.av.mob{display:none} + +/* phone-only labels and rows; desktop hides them */ +.show-m,.mlabel{display:none} +td .t2.show-m{display:none} + +/* mobile strip and drawer */ +.strip{display:none} +.specimen{display:grid;gap:14px;grid-template-columns:repeat(3,minmax(0,1fr));align-items:start} +.specimen .mini{border:1px solid var(--line);border-radius:var(--r-lg);background:var(--surface);padding:8px;display:flex;flex-direction:column;gap:2px} +.specimen figcaption{font-size:12.5px;color:var(--muted);margin-top:6px} +.specimen figure{margin:0} +.callouts{margin:14px 0 0;padding:0 0 0 18px;display:grid;gap:6px;font-size:13px} +.callouts b{color:var(--strong)} + +@media (max-width:1100px){ + .app.with-insp{grid-template-columns:220px minmax(0,1fr)} + .app.with-insp .insp{position:fixed;right:0;top:49px;bottom:0;width:min(380px,100%);box-shadow:-12px 0 30px -12px color-mix(in srgb,#000 35%,transparent);z-index:10} + .g5{grid-template-columns:repeat(3,minmax(0,1fr))} +} +@media (max-width:760px){ + .app,.app.with-insp{display:block;height:auto;min-height:100vh} + .cmdbar{position:sticky;top:0;z-index:20;gap:8px;padding:8px 12px} + .cmdbar .menu{display:inline-flex} + .cmdbar .mk span,.cmdbar .sim,.fresh .wide{display:none} + .cmdk{max-width:none} + .cmdk kbd{display:none} + .fresh{margin-left:0} + .side{display:none} + .strip{display:flex;gap:2px;overflow-x:auto;padding:6px 8px;border-bottom:1px solid var(--line);background:var(--surface)} + .strip .nav{white-space:nowrap;flex:none} + .app.drawer .side{display:flex;position:fixed;inset:49px 0 0 0;z-index:30;border-right:0;padding:10px 12px 20px} + .app.drawer .strip{display:none} + .main{padding:14px 16px 24px;overflow:visible} + .vh h1,.orghead h1{font-size:24px} + .g2,.g3,.g4,.g5,.split,.specimen{grid-template-columns:minmax(0,1fr)} + .g4.keep2,.g5.keep2{grid-template-columns:repeat(2,minmax(0,1fr))} + .app.with-insp .insp{position:static;display:flex;width:auto;box-shadow:none;border-left:0;border-top:1px solid var(--line);margin:0 0 24px} + .show-m,td .t2.show-m{display:block} + span.show-m{display:inline-flex} + span.msrc.show-m{display:flex} + .av.mob{display:inline-grid;margin-right:6px;vertical-align:-3px} + .strip{scrollbar-width:none} + .g5.keep2 > :last-child:nth-child(odd){grid-column:1/-1} + .sec-h .note{flex-basis:100%;order:3} + .grid.g3.mini-tiles{grid-template-columns:repeat(3,minmax(0,1fr))} + .mini-tiles .tile .big{font-size:18px} + .mini-tiles .tile .big small{display:block;margin-left:0;font-size:11.5px} + .cfg.one li{grid-template-columns:18px minmax(0,1fr) auto auto;gap:2px 10px} + .cfg.one .k{grid-column:2;grid-row:1} + .cfg.one .src-tag{grid-column:3;grid-row:1} + .cfg.one .go{grid-column:4;grid-row:1/3} + .cfg.one .v{grid-column:2/4;grid-row:2} + .mlabel{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:700;color:var(--strong);margin-bottom:6px} + .board,.tasklist .sec-h{display:none} + .vh .seg .kb{background:none;color:var(--muted)} + .vh .seg .ls{background:var(--action);color:var(--onAction)} + .srow{grid-template-columns:92px 20px minmax(0,1fr)} + .srow .by{grid-column:1/-1} + .cfg{grid-template-columns:minmax(0,1fr)} + .cfg li{border-right:0} + .cfg li:nth-last-child(2){border-bottom:1px solid color-mix(in srgb,var(--line) 60%,transparent)} + .orghead .meta{padding-left:0;margin-top:0} + .orghead .right{margin-left:0} + .levels{grid-template-columns:minmax(0,1fr)} + .levels > div{border-right:0} + .levels .span3{grid-column:auto} + .levels .hide-m{display:none} + .panes{grid-template-columns:minmax(0,1fr);height:auto} + .pane{border-right:0} + .pane.alt{display:none} + .pane-tabs{display:flex} + .main.flush{overflow:visible} + .hide-m{display:none} + .trail li{grid-template-columns:42px 18px minmax(0,1fr);gap:8px} + .trail .what{white-space:normal} + .toolbar .right{margin-left:0} + .search{min-width:0;flex:1} +} +@media (prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}} -- 2.54.0 From 1cc09a1cad14369b5e03e14508e3d1095378b501 Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Mon, 9 Nov 2026 12:38:03 -0600 Subject: [PATCH 2/3] docs(design): match U0 org dashboard sessions to the main dashboard count (#1873) The org dashboard listed an idle chief as a session, so Distinctly Digital showed four sessions there and three on the main dashboard. The chief has no running session; it stays on the agents screen. --- .../samples/2026-11-09-unified-workspace/03-org-dashboard.html | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html index 579233f01..0f827cb75 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html +++ b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html @@ -72,12 +72,11 @@
Decision wait22min median
Open tasks52 in progress · 1 review
-

Active agent sessions

3 running, 1 idleAll agents
+

Active agent sessions

2 working, 1 waiting on youAll agents
-
AgentProject and taskModelStatus
copywriterSpring launchV-112 Launch email, draft 2sonnet-5.5 Changeworking 38 min
montage-producerSpring launchV-118 Teaser reel, 30 s cutsonnet-5.5 Changeworking 1 h 12 min
editorThe Lantern CoastV-97 Chapter 7 revisionopus-5.5 Changewaiting on you
chiefOrganizationroutes work from the assistantopus-5.5 Changeidle
-- 2.54.0 From af674e14c13010b83788699e49582bc7657cb0db Mon Sep 17 00:00:00 2001 From: Jason Woltje Date: Mon, 9 Nov 2026 13:26:39 -0600 Subject: [PATCH 3/3] docs(design): keep the WebUI four-tile logo in the U0 samples; record U0 approval (#1873) Jason approved the U0 screens on 11-09 with one change: keep the temporary logo the site already uses. The samples drew the design system's Relay placeholder; they now draw the WebUI's four-tile mark with the same fills as processing.css. The direction doc records the approval verbatim, the deferred Montage name, and the open-question defaults phase U takes. --- .../01-sidebar.html | 2 +- .../02-dashboard.html | 6 +-- .../03-org-dashboard.html | 2 +- .../04-projects.html | 2 +- .../05-inbox.html | 2 +- .../06-tasks.html | 2 +- .../07-side-by-side.html | 2 +- .../08-agents.html | 4 +- .../workspace.css | 4 +- ...11-09_unified-workspace-owner-direction.md | 39 ++++++++++++++++++- 10 files changed, 52 insertions(+), 13 deletions(-) diff --git a/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html b/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html index 825b267c1..3fe2cf327 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html +++ b/docs/design/samples/2026-11-09-unified-workspace/01-sidebar.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html b/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html index 87b97e83d..f47be9a20 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html +++ b/docs/design/samples/2026-11-09-unified-workspace/02-dashboard.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
@@ -51,7 +51,7 @@
111
oldest 52 min
Sessions74 working -
3211
1 waiting · 1 error · 1 idle
+
3211
1 waiting · 1 error · 1 idle
Open tasks10
532
2 done this week
@@ -76,7 +76,7 @@
  • Merge the rate limiter branch into main?Forge · API gateway · chiefgated
  • Chapter 7: keep the revised ending?Distinctly Digital · The Lantern Coast · editorwithin-role
  • Home insurance renews in 12 days. Compare the two quotes now?Home · Household admin · assistantroutine

Sessions now

Agents
- +
Agent and projectStatus
assistant · All organizationsworking with you
coder · API gatewayworking 65 min
copywriter · Spring launchworking 38 min
montage-producer · Spring launchworking 72 min
editor · The Lantern Coastwaiting on you
reviewer · Web apperror timeout
planner · Household adminidle since 09:10
assistant · All organizationsworking with you
coder · API gatewayworking 65 min
copywriter · Spring launchworking 38 min
montage-producer · Spring launchworking 72 min
editor · The Lantern Coastwaiting on you
reviewer · Web apperror timeout
planner · Household adminidle since 09:10
diff --git a/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html index 0f827cb75..f40e155a3 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html +++ b/docs/design/samples/2026-11-09-unified-workspace/03-org-dashboard.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/04-projects.html b/docs/design/samples/2026-11-09-unified-workspace/04-projects.html index de6322e7e..68bed4388 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/04-projects.html +++ b/docs/design/samples/2026-11-09-unified-workspace/04-projects.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html b/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html index a630cb903..9f0a4f852 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html +++ b/docs/design/samples/2026-11-09-unified-workspace/05-inbox.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html b/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html index 0527fd8fe..2891eb4c3 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html +++ b/docs/design/samples/2026-11-09-unified-workspace/06-tasks.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html b/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html index f83f7fc1a..673504a6e 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html +++ b/docs/design/samples/2026-11-09-unified-workspace/07-side-by-side.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
diff --git a/docs/design/samples/2026-11-09-unified-workspace/08-agents.html b/docs/design/samples/2026-11-09-unified-workspace/08-agents.html index 8fe167c5c..5d0cfa242 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/08-agents.html +++ b/docs/design/samples/2026-11-09-unified-workspace/08-agents.html @@ -11,7 +11,7 @@
- Mosaic Stack + Mosaic Stack U0 sample
Read 3 of 3 organization buses · 4 s agoOP
@@ -45,7 +45,7 @@

Agents

Edit root agents

Agents are defined at three levels. A project can use the union of your root agents, its organization's agents and its own. Every agent except the assistant works inside one organization.

-
assistantrootworkingWorks acrossOne shared memory. Talks with you and hands each organization's work to its chief; it does not direct agents, create tasks or launch sessions.
+
assistantrootworkingWorks acrossOne shared memory. Talks with you and hands each organization's work to its chief; it does not direct agents, create tasks or launch sessions.
Distinctly Digital
Forge
Home
rootYour root configuration. Only you change it. Each organization runs its own copy, with memory, files and credentials kept in that organization.
diff --git a/docs/design/samples/2026-11-09-unified-workspace/workspace.css b/docs/design/samples/2026-11-09-unified-workspace/workspace.css index bdbf9d188..3c5a0b846 100644 --- a/docs/design/samples/2026-11-09-unified-workspace/workspace.css +++ b/docs/design/samples/2026-11-09-unified-workspace/workspace.css @@ -46,7 +46,9 @@ svg.i.sm{width:15px;height:15px} .app.with-insp{grid-template-columns:240px minmax(0,1fr) minmax(300px,360px)} .cmdbar{grid-column:1/-1;display:flex;align-items:center;gap:12px;padding:8px 14px;border-bottom:1px solid var(--line);background:var(--surface);min-width:0} .cmdbar .mk{display:flex;align-items:center;gap:8px;font-weight:800;color:var(--strong);letter-spacing:-.01em;white-space:nowrap;text-decoration:none} -.cmdbar .mk svg{width:20px;height:auto;color:var(--action)} +.cmdbar .mk svg{width:24px;height:auto} +/* The WebUI's temporary four-tile logo (index.html, processing.css), kept by owner ruling 11-09 until a real mark is chosen. */ +.mosaic-logo{flex:none;fill:var(--action)}.mosaic-logo rect:nth-child(2){fill:color-mix(in srgb,var(--action) 75%,var(--strong))}.mosaic-logo rect:nth-child(4){fill:color-mix(in srgb,var(--action) 45%,var(--canvas))} .cmdbar .menu{display:none;border:1px solid var(--line);background:var(--canvas);border-radius:var(--r);padding:4px;color:var(--strong)} .cmdk{flex:1;max-width:520px;display:flex;align-items:center;gap:8px;border:1px solid var(--line);background:var(--canvas);border-radius:var(--r);padding:5px 10px;color:var(--muted);text-align:left;min-width:0} .cmdk span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap} diff --git a/docs/plans/2026-11-09_unified-workspace-owner-direction.md b/docs/plans/2026-11-09_unified-workspace-owner-direction.md index a7833e506..350781ad9 100644 --- a/docs/plans/2026-11-09_unified-workspace-owner-direction.md +++ b/docs/plans/2026-11-09_unified-workspace-owner-direction.md @@ -231,8 +231,45 @@ into another user's organization, and access checks on the cross-org read model. The design lands with Phase U so the read model has membership from the start. +## U0 approval (11-09, 19:26Z) + +Owner text, verbatim: + +> The U0 screen designs look good. We need to retain the temporary logo +> already used in the site. +> I don't like these module names either. It isn't clicking for me. That may +> need to be a later decision. + +What follows from it: + +1. The samples in `docs/design/samples/2026-11-09-unified-workspace/` are the + acceptance target for U2 to U5. +2. The WebUI's four-tile mark stays the logo. The samples now draw it in + place of the design system's Relay placeholder, and the build does not + adopt Relay. +3. The Montage module name stays open. Two naming rounds produced no pick. + The label "Mosaic Montage" stays until Jason names it; nothing in phase U + depends on the name. + +The ten open questions in the U0 report were not answered one by one. Under +the lead's standing authority to decide routine choices, phase U takes the +report's recommendations, and Jason can overturn any of them: + +- Every decide command copied from a shared view carries `--org`. +- The chief may propose a root-level hire only as a gated inbox item the user + approves. +- An org's colour is its own theme's action colour, the same for every member. +- Side by side on a phone is a two-way switch with one pane visible. +- Sidebar projects default to By org, remembered per viewer. +- Tasks on a phone default to List, with Kanban one tap away. +- The CLI verbs for the new header controls are `mosaic org reload ` and + `mosaic console restart`, added before U2 wires the buttons. +- Members and invites shows in the settings index, labelled "not built". +- Messages becomes Assistant. Docs live on org dashboards and in panes. Queue + opens from each org dashboard. + ## Open items -- The final name for the Mosaic Montage module. +- The final name for the Mosaic Montage module (deferred by Jason, 11-09). - Which "sign-in (model proxy)" step Jason hit. F3 inventories every manual step on the dev instance and reports it. -- 2.54.0