Skip to content
ThorbisInterface Guidelines (opens in a new tab)
Resources

Product

Inventing a page, a tool, or a canvas.

SKILL.md.agents/skills/thorbis-product/

Follow the skill selection policy and shared Linear baseline. For mobile-app work, the Native contract (D-025) is required.

Scope and required context
Linear baseline: This skill specializes one part of Thorbis; it does not introduce another product grammar. Preserve quiet chrome, one dominant work region, structured density, stable action neighborhoods, contextual surfaces, visible keyboard paths, durable state, and role-adaptive mobile. Use the Thorbis × Linear pattern matrix only when the owning pattern is ambiguous.
Mobile platform gate (D-025): Every mobile-app task requires the Native contract, HIG-001–HIG-022, and relevant live Apple Human Interface Guidelines (opens in a new tab). Apple HIG governs iOS/iPadOS behavior over conflicting web/Linear rules. Cite rule IDs and topic URLs in specifications, component contracts, PRs, and release evidence. Android retains host conventions. Normative requirements and exceptions have one owner: Native.

How Thorbis acts and feels. Open this when you invent something new.

This is its own skill. Drop it at .agents/skills/product.md. Pick this file. Do not average it with the others.

Live: https://design.thorbis.com/skills/product

Rules is what we ship. Research is the homework. `DESIGN.md` is the constitution. `AGENTS.md` is the contract. UI is craft. Linear is the baseline for shell geometry. Native is the device. This chapter is the join: the new thing sits in the shell we already have, and a dispatcher cannot tell it was added last week.

This skill holds: D-001 (fill a pattern or name the gap), D-002 (the page does not own chrome), D-006 D-007 D-012 (search, then stop if nothing fits), D-013 D-014 (surface must earn its role; no desktop drawer), D-009 (states exist), D-015 (preference where people differ).

Homework: Linear, Vercel, Cursor. Grammar, not costume. Ryo Lu, the designer ships; the workbench is the product. Aman Sanger, agents follow a file; they do not invent taste. Michael Truell, a conversation is fine for a sketch; the constitution is for the ship.

If the surface is marketing or first-run, stop. Use Cinematic. Name the mode: router, explore, film, or store. One idea per scene. D-022.

thorbis-product-SKILL.md

What this skill owns

  • The product feel. Quiet chrome. Precise work. Easy to look at. Easy to understand.
  • How new work enters the 90% shell.
  • When a new occupant is allowed, and when you must stop and name a gap.
  • The test at the end of every invention.

It does not own pixel tokens (Color, Type). It does not own inverted-L measures or surface roles; those come from the shared Linear baseline and DESIGN.md. It does not own iOS chrome (Native). Read those after the join is right.

First

Answer these, in order, before you draw. Write the answers down. If you cannot, you are not ready.

  1. Who is holding it, and what just interrupted them? Dispatcher at 7 a.m. Tech in a crawlspace. Owner closing the books.
  2. Which profile? Workbench, Guided, Evidence, or Showcase. One. Do not mix.
  3. What is the one action on this view? Dispatch. Arrive. Save invoice. Add a step. Everything else is quieter.
  4. Is this a place, a transaction, or context? Route, modal, popover, inspector, peek, or inline. Not a desktop drawer. D-013. D-014.
  5. Which room already exists? List, Board, Record, Schedule, Inbox, Search, Settings, Guided, Evidence, Canvas. Fill that room. The occupant table is below.
  6. What already exists in the kit? Search the registry. D-007. Native control, then the kit, then last a new primitive. D-006.

Do not offer a menu of looks. Make the call. Then invent only the occupant, never the chrome.

The feel

Thorbis is the cleanest thing they touch all day. That is not a slogan. It is a test.

A screen is easy to look at when:

  • One grey family. Canvas, chrome, sheet, well. No extra grey you invented.
  • One accent. Electric blue. It points. It does not paint.
  • A fill is one mix. No gradient. No solid colored border on the leading or trailing edge of a row. D-018.
  • Media holds its hole. A list that continues shows it. D-019.
  • Outline at rest. Fill when this is the place. D-020.
  • Overlay is a mix, not a blur. D-021.
  • Type does the hierarchy. 32 / 16 / 14 / 13 / 12. No costume font. No kicker.
  • Regions meet by tone. No 1px line around a room.
  • Depth is a whisper. Rest, sink, lift, overlay. Nothing else.

A screen is easy to understand when:

  • You know where you are from the location bar.
  • You know what the work is from the sheet. Street first. 114 Oak, then the leak.
  • You know the one action without hunting. It is a commit. Ink.
  • Status is a word. Open. En route. On site. Not a green blob.
  • Empty names the one action. No steps yet. Add a step.
  • Errors name the problem and the exit. Not “Oops.”
  • Words are ours. Job, stop, tech, truck. Not ticket, agent, resource.

If a new thing needs a legend to be read, it is not Thorbis yet.

Customize

Prefer a preference when the work varies person to person. D-015.

Theme. Density. This list (columns, sort, group). Saved views. Default place. Pinned places.

The default ships finished. If they must open Display before the board works, you built a kit.

Do not let them rewrite the inverted L, the tokens, or the words. Do not put a hex picker in Settings. Do not put five display options on Arrive. A shared invoice does not wear their Light theme as the document.

Display for this list lives on the view bar. Shop-wide facts live in Settings. Persist what is theirs. The URL holds what is shareable.

The 90% shell

Most of Thorbis is one app. The chrome does not change. The occupant does.

canvas
  sidebar          places you can go
  main
    location bar   where you are
    view bar       how this work is sliced
    sheet          the work
      inspector    optional, one selected thing

This is the inverted L. The sheet is the product. The page does not own the sidebar, the location bar, or the view bar. D-002.

Allowed occupants of that shell:

ListPage BoardPage RecordWorkspace ScheduleTimeline InboxPage SearchPage SettingsPage GuidedFlow EvidencePage CanvasWorkspace

A new feature is almost always a new occupant of the sheet, or a new row inside an occupant you already have. It is almost never a new shell.

Fail if you invent:

  • A second header
  • A second sidebar
  • A floating toolbar that hides the location bar
  • A card grid that is the page
  • A dashboard of equal buttons
  • A desktop drawer doing a page’s job
  • A new color language “because this tool is spatial”

The operator does not relearn the app because you shipped Workflow.

How a new thing joins

Follow this. Do not skip.

1. Name the room

If the work is a list of jobs, it is List. If it is a job, it is Record. If it is time against trucks, it is Schedule. If it is find-and-compare, it is Search. If it is one field action, it is Guided. If it is a number that must be right, it is Evidence. If the work is spatial, a graph, a map of steps, Brain, Workflow, it is Canvas.

If none of those is true, stop. Write the gap. Do not invent a page-local shell. D-012.

2. Keep the chrome

Same sidebar. Same location bar. Same view bar. Same sheet. Same inspector slot.

The new thing fills the sheet. It may use the inspector. It may add a view-bar slice. It may add a command. It does not add a chrome row.

3. Dress it in our surfaces

Thing on the new surfaceIt isToken
The empty planeCanvas. Not a working surface.bg
A node, a card, a step, a truckA sheetpanel
An input on that nodeA wellfield
The title of the nodeTypefg
The caption, the edge, the handleMarkermarker
The selected node, the live edge, focusAccentaccent
The one actionA commit. Ink.fg fill, inverse type

Same fill as the parent is illegal. A node is not a flat sticker on the sheet. It is a small sheet: 14px radius, tone, optional 1px rim if the thumb must find it. Selected is accent, the way a live row is accent. Not a new selection kit.

4. Keep the words and the type

Inter on the work. Geist Mono on IDs and money. Sentence case. Prefer a mark. When a control has a word, it names the action: Save invoice, not Continue, not + Node. D-016.

Street first even on a graph. The node is 114 Oak, not N-1842. If the node is a step, the title is the verb: Dispatch, Arrive, Invoice. Not Function_3.

5. Keep the keys

⌘K still goes or does. / may filter this view. J K move the selectable thing. Enter opens. Space peeks. Esc closes the top layer or deselects. C still quick-creates when create exists.

Hover is color, gated to a real mouse. Focus is an accent ring. Selected is a fill or a mark. They are not the same.

Shortcut-only is a defect. D-008.

6. Keep the states

Empty, loading, error, disabled, permission, destructive. Designed. D-009.

A canvas with no nodes is empty, not a blank void. Name the action. A failed save sits under the field or as a page banner if the page is the problem. A missing permission does not leak the invoice.

7. Keep the phone

The inverted L collapses. Sidebar becomes command. Inspector becomes a bottom sheet. The sheet stays the work. A spatial view may pan and zoom. It does not become a squeezed desktop. 44px for anything that stands alone. Native.

Spatial work

Workflow. Brain. A map of steps. A graph of nodes. This is Canvas. It is a room, not a second product.

The sheet is the plane. Nodes sit on it the way jobs sit on a list. The location bar names the graph. The view bar slices it. The inspector holds the selected node. Adding a node is a commit or a C modal, not a costume palette.

A third-party graph library is infrastructure. Its default theme is a costume. Strip it. Tokens only. No neon edges. No alien selection. No library watermark. No second typeface from the package.

Color, type, motion

Do not invent a palette because the tool feels “creative.”

  • Brand, focus, the live thing: accent. One blue.
  • Status: success, danger, info, warning. Words first.
  • Olive, forest, pumpkin, burnt: extras. Fun. Not a job. Not a node type system.
  • Light is a retune, not an invert. The same grammar. Color.

Type scale does not grow because the canvas is big. A node title is 14 / 500 or 16 / 500. It is not 32. 32 is the page. Type.

Motion: frequency first. Panning a canvas is the work, not an animation. Selecting a node is color, not a bounce. Connecting an edge may take 120ms ease-out on transform and opacity. Keyboard is instant. Motion.

Composition

Name the occupant after the job: WorkflowCanvas, BrainGraph, JobMap. Not SmartBoard. Not InfiniteCanvas.

Export pieces, not flags. The shell owns chrome. The occupant owns the work. A canvas component does not paint a sidebar. Composition.

Search the registry. If CanvasWorkspace exists, fill it. If it does not, name the gap, then add it as an occupant of AppShell, not as a new app.

Never

  • A new shell for a new idea
  • A second visual language “for this tool”
  • React Flow, Mapbox, or FullCalendar wearing their factory clothes
  • Neon edges, glow handles, a rainbow of node types
  • A floating HUD that covers the location bar
  • Mini-map chrome that shouts louder than the graph
  • N-1842 as the title of a node
  • A desktop drawer that holds the canvas
  • Marketing copy on a workbench canvas
  • Hex, text-white, or a raw shadow in product code
  • Linear purple, Linear dress, or “Issue”
  • Mixing Workbench density with Showcase theater on one view
  • A hex picker, a theme store, or a Guided flow with display options
  • A default that is broken until they open Settings
  • A gradient, mesh, or fade, unless the brief named that wash
  • A solid colored border on the leading or trailing edge of a row, a node, or a card

Audit

  • Person, profile, one action, and surface are named
  • The room is named. The occupant fills the 90% shell
  • No second header, no second sidebar, no extra chrome row
  • Tokens only. One accent. Regions have no borders
  • Nodes / cards / rows use panel, well, type, marker. Selected is accent
  • Trade words. Street first. Status is a word
  • J K, ⌘K, Escape, Space. A visible path for the one action
  • Empty, loading, error exist
  • 390px: inspector is a bottom sheet. No squeezed desktop
  • Light and dark. Theme still sticks
  • A preference exists where people differ, or you named why not. D-015
  • A dispatcher would believe this was always here

Two failures: do not ship.

Done

Name the person, the profile, the room, the surface, and the one action. Name the occupant you filled. Name anything you refused, including a library theme you stripped. If you named a gap instead of inventing a shell, that is success.

Rooms

The 90% shell is one app. These are the occupants of the sheet. Fill one. Do not invent a sixteenth chrome.

AppShell owns canvas, sidebar, location, view, sheet, inspector. Measures live in the shared Linear baseline. This skill is the join.

Same chrome

SlotJobA new feature mayA new feature may not
SidebarPlaces you can goAdd a place if it is durablePut filters, a second logo, or the new tool’s tree here
Location barWhere you areName this graph, this job, this listBecome a marketing header or a toolbar
View barHow this work is sliced. Density. This list’s display.Add a slice: Map / List, All / Leaks. A density control.Become a second location, a floating HUD, or shop-wide Settings
SheetThe workBe a list, a board, a record, a canvasBe a stack of cards that is the page
InspectorContext beside the workShow the selected row or nodeBecome a second app or a desktop drawer

One main landmark. One inverted L. The operator does not relearn the app when the occupant changes.

Occupants

RoomOwnerThe sheet holdsOne actionNot
ListListPageRows. Street first.Create a job. Dispatch the selection.A dashboard above the list
BoardBoardPageColumns of status wordsMove a job. Open it.A second color language per column
RecordRecordWorkspaceIdentity, feed, the jobThe primary verb on this jobA chat toy. A squeezed inspector
ScheduleScheduleTimelineTime on the spine. Trucks as rowsPlace a stopA month-grid costume
InboxInboxPageThe thread. The job beside itReply. Turn it into a jobA Messenger
SearchSearchPageResults. Split previewOpen. Refine.A bigger ⌘K
SettingsSettingsPageA column of settingsSave this sectionOne Save for five topics. A hex picker. Display that belongs on the view bar
GuidedGuidedFlowOne stepArrive. Capture. Send.A squeezed board
EvidenceEvidencePageQuestion, number, tableTrust the numberMotion. A blue wash
CanvasCanvasWorkspaceA plane of nodes, steps, or a mapAdd a step. Run. Select.A second product. A library theme

Guided and Evidence may drop the inverted L. Name that. Everything else keeps it.

Showcase is not a room of this shell. Cinematic.

Canvas

Workflow and Brain live here. So does any spatial work that is still the shop: a graph of steps, a map of stops, a tree of automations.

  • The plane is the sheet, sitting on the canvas. Nodes are small sheets.
  • Location names the graph: After-hours leak or Brain.
  • View bar slices: Map / List, or All / Leaks / HVAC.
  • Inspector is the selected node. Properties, not a second canvas.
  • Create is a commit or a C modal. Not a costume stencil well that covers the location bar.
  • List is still legal. A canvas that cannot become a list is a trap for a dispatcher on a phone.

If the spatial thing is a month calendar of the shop, stop. That is Schedule, or a named gap. Do not fake Schedule inside Canvas.

Portal

The customer-facing Guided flow. Not a workbench. One action. The customer does not see the inverted L. They see a sheet and a commit. Do not pour Admin into the portal.

When nothing fits

Stop. Write the gap. A named gap is work. A page-local shell is drift. D-012.

Do not add a room because a library came with a layout. The library sits inside a room we already named.

New surface

How to invent something so it belongs. Constitution: DESIGN.md. Feel: Product. Shell: shared Linear baseline. Craft: UI.

Do this in order. Write the answers. Then build.

Protocol

  1. Person. Dispatcher, tech, or owner. Device. What interrupted them.
  2. Profile. Workbench, Guided, Evidence, or Showcase. One.
  3. One action. The verb on this view.
  4. Surface. Route, modal, popover, inspector, peek, or inline. D-013. Not a desktop drawer. D-014.
  5. Room. List, Board, Record, Schedule, Inbox, Search, Settings, Guided, Evidence, Canvas.
  6. Search. Token, primitive, occupant, component. D-007. If CanvasWorkspace exists, fill it.
  7. Gap. If nothing fits, name it and stop. D-012. Do not invent a shell so the ticket can close.
  8. Join. The new thing occupies the sheet. Chrome stays. Inspector stays available.
  9. Dress. Panel, well, type, marker, one accent. Strip any library theme.
  10. Words. Ours. Street first. Sentence case. The button is the verb.
  11. Keys. ⌘K / J K Enter Space Esc C. Visible path. D-008.
  12. States. Empty, loading, error, disabled, permission, destructive. D-009.
  13. Narrow. 390px. Inspector is a bottom sheet. 44px if it stands alone.
  14. Both themes. Light is a retune. The choice persists.
  15. Audit. The checklist on Product. Two failures: do not ship.

Report: person, profile, room, surface, one action, reused, refused, how you checked.

Worked: a canvas of nodes

The ask: “Build a canvas component with nodes.”

Answers, written down

QuestionAnswer
PersonDispatcher. Office. Keyboard. Building an after-hours leak path.
ProfileWorkbench
One actionAdd a step. Second: select a step and edit it.
SurfaceRoute. The graph is durable. Shareable. Revisit it.
RoomCanvas
OccupantCanvasWorkspace on the sheet of AppShell
Create a stepModal (C) or a commit on the sheet. One task.
Edit a stepInspector. Stays beside the plane.
Change a typePopover on the node or in the inspector
Peek a job the step points atSpace. Do not navigate away.

Not a new app. Not a drawer. Not Showcase.

What the page is

AppShell
  sidebar            Jobs, Schedule, Inbox, Workflow, Brain, Books
  location bar       Workflow · After-hours leak
  view bar           Map | List
  sheet              CanvasWorkspace
    plane            bg. Pan and zoom are the work.
    node             panel. 14px radius. Title is the verb.
    selected node    accent rim or accent wash at 8%. Same as a live row.
    edge             marker. 1px. No neon. No arrows that shout.
    handle           field circle. 8–10px. Findable. Not a candy gem.
  inspector          The selected step. Name, when, who, the job it points at.

Location, view, sheet. No extra chrome row. No floating library toolbar over the location bar. Zoom, undo, snap: view-bar actions or a quiet cluster on the sheet, 28px chrome, 13 / 500, color-only hover.

How a node looks

  • Fill panel. On the plane (bg) it lifts by tone, not a drop-shadow stack.
  • Title 14 / 500 fg. Dispatch to on-call. Not Node 4. Not N-1842.
  • Caption 12 / 500 marker. After 5pm · Mike.
  • Status is a word on the node, same words as the rest of the app.
  • Selected: accent. Focus: accent ring. Hover: slightly brighter panel. Three different things.
  • Nested inputs on the node are wells. They do not appear until the inspector, unless the edit is inline and tiny.
  • Radius 14 on the node. Inner controls: inner = outer − padding. UI.

Do not color nodes by type with olive / forest / pumpkin. Type is a word or a quiet Phosphor Regular 16 mark. Extras are not a type system.

How the library is used

A graph package is allowed as infrastructure. Its CSS is not.

Strip:

  • The factory color palette
  • The factory selection box
  • The factory minimap chrome
  • The factory attribution
  • The factory typeface
  • Glow, dash animations, emoji nodes

Keep:

  • Pan, zoom, connect, snap
  • Our tokens on every node, edge, handle, and control
  • Our focus ring
  • Our empty, loading, and error

If the package cannot be undressed, do not use it. Name the gap. Draw the plane with what we own.

Keys and mouse

InputResult
Click empty planeDeselect
Click a nodeSelect. Inspector fills.
Drag a nodeMove. 120ms is not required. The hand is the motion.
Drag a handleConnect. Edge is marker until drop, then it stays marker.
J KMove selection through nodes
EnterFocus the inspector, or open the linked job
SpacePeek the linked job
CAdd a step. Modal.
⌘KGo or do. “Add a step.” “Open 114 Oak.”
EscDeselect, or close the modal, or close peek
/Filter nodes on this graph, or jump to List

A trackpad pans. A mouse with no modifier may drag the plane when not on a node. Hover is gated.

Empty, loading, error

  • Empty: the plane is still the sheet. Centered, not a hero. No steps yet. Commit: Add a step.
  • Loading: the last graph shape, waiting. Not a spinner in a void.
  • Error: Could not save this step. Check the name. Under the field if the field is the problem. A banner if the page is offline.
  • Permission: You cannot edit this workflow. Do not show the hidden nodes.

Phone

  • Sidebar is gone. Places live in command.
  • Location and a short view bar stay.
  • The plane is the sheet. Pan and zoom with fingers.
  • Inspector is a bottom sheet when a node is selected.
  • Add a step is a 44px commit, reachable by the thumb.
  • List view is the default if the graph is unusable at 390px. Map is still offered. Do not ship a squeezed desktop editor.

What you refuse

  • A second product called “the canvas app”
  • A rainbow of node types
  • Mini-map larger than a postage stamp, or styled like a game HUD
  • auto layout that fights the dispatcher’s placement without a way to turn it off
  • Animation on ⌘K
  • Light theme that inverts the graph into a different language

Done line

Workbench. Canvas. Route. One action: add a step. Occupant: CanvasWorkspace. Reused: AppShell, inspector, commit, well, accent for selected. Refused: the library theme, a new shell, type-as-color. Checked: desktop, 390px, keyboard, both themes.

Other inventions, same join

AskRoomSheet holdsInspector holdsRefuse
A map of today’s stopsCanvas or ScheduleThe map, or time as the spineThe selected stopA consumer map skin
A photo of the leakRecordThe feed. The photo is evidence on the jobThe photo’s metaA lightbox as the page
A customer portal statusGuidedOne sheet. One commit,The workbench L
An invoice PDF viewEvidenceThe question and $186.00,Motion. Accent wash
Chat with the shopInboxThe threadThe jobA Messenger costume
A report builderEvidence or CanvasThe question, then the tableThe selected metricA BI dashboard of equal cards

If the ask is “make it pop,” you are being asked to break the feel. Do not. Quiet chrome. Precise work.

Stop conditions

Stop and name the gap when:

  • You need a second header to make the tool make sense
  • You need a color the tokens do not have
  • You need a desktop drawer because a route felt like too much work
  • You cannot name the room
  • You cannot name the one action
  • The library cannot wear our surfaces

A named gap is the right output. A costume is not.

Applied bookmark research

Reviewed 2026-09-06. These are Thorbis applications and review exercises, not replacements for DESIGN.md, COMPONENTS.md, or the owning skill. Linear remains the operational baseline. External advice that conflicts with the constitution stays out.

These worked examples are not a claim that the product behaviors have been implemented or verified.

Make the task easier, not the screen busier

Owning skill: product.

A feature can look complete while the dispatcher still has to reconstruct context or wait for unrelated content.

Start from one person, interruption, and completed task. Keep the current job and its next action usable while optional evidence arrives. Treat the real constraint as part of the brief, not something polished away afterward.

Thorbis example: For assigning a tech, show the job, relevant availability, and the consequence of the assignment. Do not make the dispatcher traverse a marketing-style sequence or a new shell to finish a routine task.

Verify: Walk through the task with representative long and missing records. Check that the essential action remains understandable when optional content is slow or unavailable. Record the result rather than claiming a performance improvement without measurement.

Do not import: No additional shell, feature hero, framework migration, or new dependency. Keep the approved surface role.

Evidence: Design Engineer Principles (opens in a new tab); How we think about design (opens in a new tab); Component Architecture for React Server Components (opens in a new tab). Source access limits.

All 26 sources and review limits.

All skills

The bundle includes every skill. Use Resources to choose the smallest context for a task.

Loading search…

Loading search. You can close this message and keep reading.