Composition

Same parts. Different compositions.

01 — The compositions

8 of them, and what is in each

A

Meeting room

/

aside-right
not mounted
work-area
not mounted
B

Entity list

/planner, /design

aside-right
nothing to have context about yet
work-area
not mounted
D

Section hub

/content, /dashboards, /reports, /events/[category], /contacts

E

Chat

/chat/[chatId] — and /rg, /localization, /checklist/[checklistId], /edit, whose main is the same persistent chat

aside-right
toggled by 07
work-area
not mounted
F

Chat with context

The same pages as E, with the context column open

G

Chat with work area

/planner/[planId], /design/[designKitId], /content, /contacts/[contactId], /dashboards/[dashboardId], /reports/[reportId], /rg, /localization

H

Work area expanded

The same pages as G, with main unmounted

main
not mounted
aside-right
not mounted
02 — The parts

23 parts, and what each one is for

Every part of every screen above, numbered once. A number belongs to a component rather than a position, so 06 is the breadcrumb wherever it appears, and it carries its column’s colour with it.

partwhat it ison click
aside-left
01The mark

The logo, in the rail’s header. The only thing on screen that belongs to the product rather than to anything you have open.

Not decided

02Rail

Collapses the rail, at the right of its header beside the mark. The name is mine — the notes do not have one. It is the only control in the rail that is not a destination.

Collapses or opens aside-left. Nothing else moves

03Main nav

The product’s areas. The rail is how you get between screens, so nothing belonging to one screen goes here.

Goes to that area of the product

04Chats

Recent conversations across everything, not just the thing you have open.

Opens that conversation in main

05Settings

Account, theme, the rest. Pinned to the rail’s footer.

Not decided

main
06Breadcrumb

The way back out, at the left of the header bar. Leaving a chat calls setCurrentChat(null) — a state change, not a route. The work area uses the same component in its own header, which is why it carries this number there too.

Back to the hub — setCurrentChat(null)

07Context toggle

ContextAsideButton, at the right of the same bar. It opens and closes aside-right without touching what is in main.

Opens or closes aside-right. Nothing else moves

08AskOdinEntry

The composer. It runs two ways. On an entity it is anchored to that entity’s URN, so the chat comes back in its conversation list, and it is retitled because the day’s greeting says the wrong thing on one thing’s board: contextUrn, heading, brief={false}, navigate={false}. In the meeting room it takes none of those — a chat there belongs to no one thing — and the greeting and the brief are the room’s own voice moment.

Starts a chat. On a hub it replaces the hub in main; in the meeting room it goes to /chat

09HubProcessSection

What this kind of entity would do for you. Inert on purpose — nothing in it clicks and no card carries a count, because there is no source for those numbers yet. A step gains a click and a count together.

Nothing. Inert until a step has a count behind it

10EntityAgendaBoard

What is waiting on you here. Empty for anything that is not a plan, because proposals carry a planId. Render it anyway: it is where entity proposals will land.

Not decided — nothing lands here yet outside a plan

11Entity selector

Which plan, which design kit. The list pages have no name in the notes yet, so this is what it does rather than what it is called. The one screen where main is not a conversation.

Opens that plan or kit, which lands on its hub

12ChatTable

The conversations. selectChatRowsForContexts(chats, [urn]).

Opens that chat in main

13ContextualChatPane

The conversation itself, once one is current. Which one is driven by the fc-current-chat cookie rather than the route.

23Agenda header

The meeting room’s own header: a heading, where every other screen carries a breadcrumb. There is nothing above the meeting room to go back to.

Nothing. It is a title, not a control

24The ranked feed

What Odin has for you, in five sections — Setup, Critical, Attention, Proposals, Healthy. Attention comes before Proposals because work already running is tended before new work is planned. The five share one accordion, so opening a section closes the rest, and a section with nothing in it leaves the board rather than standing there empty.

A card opens its own detail; the chat is reached from inside that

25List mini dashboard

What the list adds up to, above the list itself: how many, and in what state. It is about the set rather than any one of them, which is why it sits here and not on a hub. A list of names is a poor first thing to meet. Nothing draws it on /planner or /design yet, so this is what it does rather than what it is called.

Not decided

aside-right
14Context

The column’s own header. There are two of these columns, one per occupant of main, and this is the header of whichever is showing.

The toggle is the control; the header itself does nothing

15BriefPreview

The brief. Part of the hub’s fixed list.

Opens the brief in the work area

16GuidelinesSection

The guidelines. Fixed too.

Opens the guidelines in the work area

17NavRowsSection

The contents. Every row is a door into the work area, never a thing that opens where it sits.

Opens that row’s thing in the work area

18Mentions

What the conversation has named. First in the column because it is the part that fills soonest — anything you type at Odin can put something here.

Opens what the row names in the work area

work-area
21Close and expand

Two controls at the right of the work area’s header. Close unmounts it and returns you to main. Expand is how you get to composition H: it unmounts main instead, and the work area has the width to itself. The names are mine — the notes do not have them.

Close returns to main; expand unmounts it — composition H

22The thing

One, never two. Opened by a row in the context column, by Odin from inside a chat, or by a chat that begins about it.

03 — The question

Every column answers one thing

App layout says what the columns are. This page says what goes in them. The whole of it comes down to asking, of anything you are about to place, which column’s question it answers.

A column that answers two questions has stopped being a column and become a page.

04 — What each one takes

And what it turns away

mainthe conversation
takes
  • The hub, when no chat is current
  • A chat, once one is
  • The breadcrumb out of it
not
  • A tool. Opening a plan used to land on a calendar, and that is the thing hubs undid
  • A second occupant of any kind — the column holds one
aside-rightthe context of what is in main
takes
  • Rows that open something: a brief, a guideline, a piece of contents
  • For a hub, the same list every time, per entity type
  • For a chat, what that conversation has touched
not
  • The thing itself. A row is a door, not a drawer
  • Anything the occupant of main did not bring with it
work-areawhat you are working on
takes
  • One thing, open
  • Its own chrome, in the pane’s card snippet
not
  • A second thing beside the first
  • Anything that would survive you changing conversation
aside-leftthe app
takes
  • The product’s own navigation
not
  • Anything belonging to the screen you are on. It is how you get between screens, not part of any one of them
05 — Doors

The context column opens things, it does not hold them

Every row in a context column is a door into the work area. That is the whole contract, and it is what keeps the two columns from doing each other’s job.

The work area can be opened three ways: a row in the context column, Odin opening something from inside a chat, or a chat that starts out about a thing. All three land in the same place, which is why a row that expands where it sits breaks more than it looks like it should — it gives one of the three a second destination.

They may be shown together

The layout allows aside-right and work-area side by side. The hubs choose to swap them. That is a product decision, not a layout constraint, and it should not be repeated as though the layout forced it.

06 — Not in a pane

Five things that go somewhere else

A pane that draws its own frame

Chrome goes in the card snippet. A pane that frames its own body stops matching the ones beside it the moment either changes.

A width inside the content

width: 480px on body content is a named anti-pattern, and so is an inline --dialog-max-width. The column owns the width.

A row that expands where it sits

The context column is doors. Something that opens in place makes the work area optional, and then two places show the same thing.

A second thing in the work area

It holds one. Two means you have built a layout inside a layout, and the outer one stops being able to help.

Navigation in a screen’s own pane

If it gets you somewhere else it belongs to the rail. A pane that navigates competes with the thing that already does.

07 — Deciding

Four questions, in order

For anything that does not obviously belong anywhere. Ask them in this order and stop at the first one that answers.

Does it belong to the conversation or to the thing?

The conversation goes in main. The thing goes in the work area, and the way to it goes in the context column.

Would it survive changing conversation?

If yes it is not context — context comes and goes with its occupant. If no it does not belong in the work area, which stays put while main changes.

Is it a door or a room?

Doors go in the context column, rooms in the work area. A row that expands in place is neither, and is the commonest way this gets broken.

Could it be needed on another screen?

Then it belongs to aside-left, or to nothing.

Proposed, not ruled on

These four are consistent with what is built, but nobody has agreed them. They are on the page so they can be argued with, not because they are settled.