Skip to main content
Design system

OneSpot Design System

The reference for tokens, primitives, and product patterns. Every module is built on this.

v0.17 alpha
What OneSpot is

The story

OneSpot is the place an organization works as one. It collapses the most expensive flow in any team — going from dialogue to a documented decision and back out as learning — into five modules. Each module is opinionated, each module is for sale on its own, and the design system makes them feel like one product.

The journey
  1. 01
    Discuss

    Open a thread. Hash it out together.

  2. 02
    Decide

    Capture context, decision, action. Vote. Lock it.

  3. 03
    Broadcast

    Broadcast the decision. See who's seen it.

  4. 04
    Learn

    Turn the why into a course. Issue badges.

  5. 05
    Share

    File the artefacts. Make them findable forever.

Principle

Decisions over discussion

Threads run on, decisions don’t. Every visible affordance nudges toward capturing what was decided, not what was said.

Principle

Read receipts, not silence

We default to legible distribution. If something matters, we know who’s seen it and who hasn’t.

Principle

Modular, not monolithic

Buy what you need. Disable what you don’t. The sidebar reflects only what your org actually uses.

How a screen is built

App anatomy

◆ Org
Modules
Home
Decide
Broadcast
Learn
◆ OrgSearch…⌘K
Eyebrow
Page title
Optional description
Sidebar
Driven by the module registry. Role-aware. Collapses below 1024 px.
Topbar
Org switcher · Command (⌘K) · Theme · Notifications · Profile.
Page body
Always wrapped in PageHeader + PageBody.
Tokens

Color

Neutral spine is fixed across the product. The org’s brand color drives only --primary (CTAs, focus, active). Module hues are semantic and never overridden by an org.

Neutral
Background
--bg
Elevated
--bg-elevated
Surface
--surface
Surface 2
--surface-2
Border
--border
Border strong
--border-strong
Brand scale — derived from the org's color
50
100
200
300
400
500
600
700
800
900
950
Module hues — accent only, never surface
Discuss
--m-discuss
Accent only
Decide
--m-decide
Accent only
Broadcast
--m-broadcast
Accent only
Learn
--m-learn
Accent only
Share
--m-share
Accent only
Tokens

Typography

Display · Geist · 38/1.05
The place your org works as one.
2xl · Geist · 24/1.2
Discuss, decide, broadcast.
Base · Inter · 14/1.5
Body copy at 14px with Inter at default density. Use this for product UI and most paragraphs. Line length should stay under 75 characters for legibility.
Eyebrow · Inter 12 · uppercase tracking-wider
Section labels and metadata
Mono · Geist Mono
const decision = "immutable";
Primitives

Buttons

Variants
Sizes
With icons
Primitives

Form

68%
Primitives

Badges & module badges

DefaultSolidOutlineSuccessWarningDangerImmutable
DiscussDecideBroadcastLearnShare
Primitives

Tabs

Primitives

Avatars

SLJWMCPKDA
SL
JW
MC
PK
+4
SL
JW
MC
PK
DA
LP
Avatar colour picker — profile editor & onboarding
JR
Primitives

Overlays

Dialog
Dropdown menu
Popover
Tooltip
Primitives

Feedback

Toasts (sonner)
Empty state
No decisions here yet

When a thread reaches resolution, capture it as a decision. Records are immutable once finalized.

Primitives

Loading states

Skeleton (matches the eventual layout)
Composites · added in v0.4

Composers & CRUD

Every “New X” button in OneSpot opens one of two shapes — a full-page ComposerShell for substantial records, or a FormDialog for short forms. Destructive actions go through a ConfirmDialog. Pickers with weight (format, audience, role) use the RadioCardGroup.

ComposerShell — the full-page form layout
New thread
Untitled discussion
Untitled discussion

A composer is always sticky-header + breadcrumb + Cancel / Save draft / Primary on the right.

Body

Use ComposerShell when the form has three or more sections, sidebar metadata, or a draft state.

FormDialog & ConfirmDialog

FormDialog wraps any short form (Invite, Upload resource, New collection, Vote). ConfirmDialog is the destructive variant — always used for Archive, Cancel invite, Discard draft.

RadioCardGroup — large weighted picker
Select — short option picker
Archive vs Delete — the policy
Archive (default)

Every published record archives. Threads, decisions, broadcasts, courses, resources, groups — all keep their history and can be restored. Records in OneSpot are immutable: when reality changes you supersede or archive, never delete.

Delete (only drafts & invites)

The only things that truly delete are drafts (your private work-in-progress) and pending invites (you cancel them). Everything else is auditable history.

Composites · added in v0.5

Tags, markdown & links

The depth layer every record shares: classify with tags, write bodies in markdown, attach files, and link records across modules. All dependency-free and metadata-only.

MarkdownEditor — toolbar + Write/Preview

Used for every body field — thread messages, decision context/decision/action, broadcast body, and lesson text blocks. The renderer covers headings, bold/italic, code, links, lists, and blockquotes.

Markdown renderer (read view)

Inline code, bold, italic, and a link.

  1. Ordered
  2. List
Quoted line.
TagInput — chips + autocomplete
#governance#q2
#governance#q2#wellbeing
TagFilterBar — list filtering (OR semantics)
Tags
AttachmentField — multi-file, metadata only
LinkRecordsDialog & inline record cards

LinkRecordsDialog is a searchable multi-select for attaching decisions, resources, courses, or threads. Selected links render as inline cards — siblings of the existing decision card:

ShareGuide
ResourceCardInline

Linked resource.

Learn
CourseCardInline

Related training.

Discuss
ThreadCardInline

Source discussion.

LessonBlockBuilder — the course author surface

At /demo/learn/[course]/[lesson]/edit, lessons are assembled from six block kinds — text (markdown), image, video, link, files, and quiz — each add / reorder / removable. The quiz builder captures questions, options, the correct answer, and a pass threshold. Seed courses are read-only; create a course to author lessons.

TextImageVideoLinkFilesQuiz
Composites

Product patterns

These are the recognizable, repeated building blocks of OneSpot. Each one tells the user where they are in the journey and what they can do next.

Onboarding checklist (first-run setup)

Finish setting up

1/7
Stat cards (dashboard, insights)
Open threads
14 +3
This week
Read rate
78% +12pt
Last 30 days
Time to decide
6d -2d
Median
Quick action cards (home dashboard)
Start a thread
Open a discussion
New decision
Capture a call + rationale
New broadcast
Send an org-wide update
Dashboard widget — populated & empty state

Latest broadcasts

2
  • Q1 all-hands recapUpdate
  • Updated PTO policyUpdate

Continue learning

No courses yet.

Create a course
Module card (Your spaces)
DecideImmutable decision records
LearnCourses, lessons & certificates
Decision record — Context / Decision / Action
Context

Q4 pulse showed persistent burnout. Output capacity remains flat.

Decision

Run a 12-week 4-day work week pilot starting April 1.

Action

Marcus drafts on-call rota by March 7. Priya updates handbook.

Lifecycle tracker
1
Draft
2
Discussion
3
Voting
4
Decided
5
Broadcast
Read receipt bar (broadcasts)
18 / 24
75%
Thread row
MC

Q1 partnership pipeline — Toronto site

NewStrategy

We've had three intro meetings this week. Suggesting we narrow to two for proposal stage…

Marcus Chen·8h ago·7 replies
SL
JW
MC
Message + reactions
SL
Sarah LawsonExecutive Director· 2h

Strong agree on the council. Can you share the brief from Tuesday's call before we commit?

👍4🔥2
File pills
Course card (compact)
Drip
Writing Decision Records
One lesson per weekday for two weeks. Earn a badge on completion.
Module marketplace card

Decide

Core

Immutable decision records with lifecycle tracking.

$29 / org / mo
Active
Composites

Dates & actions

Both rows are tied to the source thread or decision and auto-archive when their date passes. Action items track an owner, a due date, and a status — overdue items get flagged red.

Action item row — owner, due, status
Draft the on-call rota for the 4-day pilot
In progressDue Aug 29Marcus Chenview decision
Update the staff handbook with the new schedule
To doDue Sep 5Priya Khannaview decision
Brief the board at the March 21 meeting
To doDue Sep 19Sarah Lawsonview decision
Run vendor RFP and security review
Overdue2d overdueMarcus Chenview decision
Composites

Votes & reminders

Primitives

Audience & chips

Audience badge — derived from scope kind
Everyone in the spaceLeadershipExecutive Directors7 specific members
Audience scope picker
Everyone in the space
Audience picker — who can view + who can post (groups & permissions)
Who can view
Who can post / reply

Viewers who can’t post see the content read-only. Org admins can always view and post.

Reaction bar — emoji reactions on a message (Discuss)
Poll card — quick poll with live tallies (Discuss)
How should we narrow the shortlist?
10 votes · closes Friday · you voted
Read receipt bar — broadcast read tracking (default + compact)
18/24
18/24
File dropzone — click or drag to pick a file (Share uploads)
Thread state chip
OpenResolvedReopened
From-decision flag (Share resources)
Engagement counters
  • 412
  • 261
  • 0
  • 184
  • 122
  • 0
  • 122
Composites

Earned badges

Each course awards a badge on completion. Render earned vs. unearned with dashed outline and grayscale on unearned.

OneSpot Initiate
Completed the platform tour.
Decision Drafter
Can write a record that doesn't need a meeting to interpret.
Facilitator
Ran a meeting that ended with a decided record.
OneSpot Initiate
Completed the platform tour.
Composites

Lesson blocks

Six block types compose a lesson: text, image, video, link, supporting files, and quiz. Mix freely.

Text

Decisions live in one place and stay readable forever. That's the whole reason OneSpot exists.

Image
Threads spawn decisions, not the other way around.
Video
youtube
Why we work this way
External link
Open FacilitationLab course

About 4 hours self-paced.

Open
Supporting files
Supporting files
Quiz

Check your understanding

Pass: 2 of 2
  1. Q1. A decision record's three sections are…
  2. Q2. When reality changes after a Decided record, you…
Tokens

Roles

Four roles, layered cake of permissions (Platform → Space → Group → Broadcast → Team) underneath. Visible labels with their tone:

Executive DirectorModeratorTeam MemberViewer
How OneSpot speaks

Voice & writing

OneSpot is a leadership communication platform. The voice is warm and human with quiet confidence: a caring colleague who keeps the team informed, never a compliance tool that watches them. We turn ideas into decisions, and decisions into action.

Celebrate, don't surveil

Read receipts power a warm nudge, never a scoreboard. Write “send a nudge,” never “chase,” “monitor,” or “enforce.”

Warm, with quiet confidence

Sound like a caring colleague, not a policy memo. “Know your team is informed” beats “ensure compliance.”

Leaders across organizations

Assume the reader does not share your building or your inbox. Say “the group,” “the council,” “your team,” not “your company.”

Decisions keep their context

Every decision names the why. Institutional memory is the point, so write so a colleague a year out can follow it cold.

Direct, not chatty

“New decision” beats “Start a brand-new decision.” Strip filler. Verbs at the front.

Canadian spelling, active voice

Colour, organize, behaviour, finalize. “The council decided to migrate email,” not “Email migration was decided.”

Words we reach for
collaboratedecidebroadcastnudgeinformedinvolvementinstitutional memorycontextimmutable recordfollow throughthe councilwarm
Words we avoid
monitortrackenforcecomplianceemployeespingsync upleverageutilizesurveilchasescoreboard
In practice
Ensure all employees have acknowledged the update.
See who has read it, and nudge anyone who hasn't.
Email migration was decided by the committee.
The committee decided to migrate email.
No items.
No decisions yet. Capture the first one to start the record.
Guidelines

Do / don't

Do
  • Reserve the brand color for CTAs and active state.
  • Use module hues only as accents and badges.
  • Use one elevation level per surface.
  • Keep row heights consistent (36 px default).
  • Match skeletons to the eventual layout.
  • Make empty states teach.
Don’t
  • Don’t tint surfaces with the brand color.
  • Don’t mix serif and sans in the same surface.
  • Don’t use module hues for body text.
  • Don’t override --primary per-screen.
  • Don’t put a spinner where a skeleton fits.
  • Don’t write “Loading…” — show structure.