Design system 0.6.0

Build

Components

25 components in eight families, rendered live with the system's own CSS. The markup uses the app's class names, so the HTML you see is the HTML to write. Toggle the theme in the top bar to see both.

Actions

Button, Icon button and tool, Pill and segment.Open on its own ↗
Guidelines and props

Button, Icon button and tool, Pill and segment. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

Button

The HeyGoal button: a verb-first label, 44 tall, one primary per row, placed last.

<Button variant="primary" icon="plus">Add task</Button>
  • variant: secondary (default), primary (the accent fill), ghost, danger. danger + armed is the second click of a two-click erase.
  • size: compact (36) for a later density mode.
  • disabled: while a PDF builds.

IconButton

A 40 px button that is only an icon. Always give it a label; it becomes the tooltip and the accessible name.

<IconButton icon="edit" label="Edit project" />
  • variant: default; ink on a pastel card (project cards, Home tiles); tool, the round 36 px edit-mode button on a card.

Pill

A filter pill with a count, for a closed set such as Open, Done, All. Put a row of them in .pills.

<Pill selected count={6}>Open</Pill>
  • selected: the current filter, drawn in --text.
  • count: the number of items the filter would show.

Segment

One choice of two or three, as in Settings: Full / Icons / Hidden, Free / Premium, Full / Reduced / System.

<Segment label="Motion" options={["Full", "Reduced", "System"]} value="System" onChange={setMotion} />
  • options: strings, or { value, label }.
  • label: the group name screen readers announce.

Inputs

Text, select and date; checkbox and task check; color pill and swatches; client field.Open on its own ↗
Guidelines and props

Text, select and date; checkbox and task check; color pill and swatches; client field. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

Checkbox

A native checkbox with its label, such as Multi-task in the Tasks add row.

<Checkbox label="Multi-task" />
  • In an add row it takes the 44 px height so its label centres with the boxes.

ClientField

A text field for a client name that shows the matching client color, or a ring for a new client.

<ClientField value={name} onChange={e => setName(e.target.value)} clients={[{ name: "Northwind", color: "sky" }]} />
  • Empty: no pill. A match: the client color. No match: a ring, meaning a new client will be created.

ColorPill

The add-row control that shows the chosen color and opens the swatch picker.

<ColorPill color="sage" />
  • color: a palette name. It lifts 2 px on hover and presses to .95.

DateRange

Two small labelled date fields, start and due, for the add rows.

<DateRange start="" due="" />
  • The labels sit above the boxes, so the row aligns on the bottom edge.

Input

A text, number or date field, 44 tall, with the accent focus ring and halo.

<Input placeholder="Add a task" aria-label="Task title" />
  • Pass any input attribute. In an add row it lines up on the bottom edge with the other 44 px boxes.

Select

A 44 px select. A placeholder option reads muted until a choice is made (Priority); color fills it with a project color.

<Select placeholder="Priority" options={["High", "Medium", "Low", "Backburner"]} aria-label="Priority" />
  • placeholder: a disabled first option shown in --muted.
  • color: a palette name; the select takes that fill with ink text (the project picker in Notes and Quick access).

Swatches

The palette as round swatches for picking a project, client or accent color.

<Swatches colors={["lime", "sage", "sky", "peach"]} value="sage" onChange={setColor} />
  • The picked swatch gets the --text outline. Swatches scale to 1.14 on hover.

TaskCheck

The 24 px box on a task or expense row. A tick pops once, on the click that made it.

<TaskCheck checked={done} onToggle={setDone} label="Send storyboard v2 for review" />
  • label: the task title, so the box announces what it ticks.

Containers

Tile, project card, panel, dialog, account menu, help bubble, floating timer.Open on its own ↗
Guidelines and props

Tile, project card, panel, dialog, account menu, help bubble, floating timer. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

AccountMenu

The account menu: who is signed in, Account, Settings, then Sign in or Sign out.

<AccountMenu name="Gabriel Rocha" detail="Not signed in" items={[{ label: "Account", icon: "user" }, { label: "Settings", icon: "gear" }]} />
  • Arrow keys move through the rows; Escape closes and returns focus to the account card.

Dialog

A modal dialog for a choice. Destructive actions do not use it: they act at once and offer Undo in the toast.

<Dialog open={open} title="Expense categories" onClose={() => setOpen(false)}>…</Dialog>
  • It uses the native dialog, so focus moves in, the page behind is inert, and Escape closes it.

FloatingTimer

The glass timer card that floats at the content edge while a timer runs.

<FloatingTimer time="1:24:07" what="Holiday campaign · Storyboard revisions" />
  • paused: the time turns --muted and the dot amber, without the pulse.

HelpBubble

The ? bubble that defines a number where it appears. Every money figure gets one.

<HelpBubble text="Still owed = earned minus received — everything the project is still owed, whether or not it is on an invoice yet." />
  • Shows on hover and on focus. Never uppercase, never tracked, even inside a kicker.

Panel

A flat panel for a section of a page: a surface, a 1 px edge, no shadow. It never lifts.

<Panel title="At a glance">…</Panel>
  • zone: inv, proj, exp or pay adds the Billing 3 px top strip.
  • colored: a palette name turns it into a pastel Home section; everything inside switches to ink.

ProjectCard

A project card: the project color, its status, name, client, three stats and the money line. It lifts 9 px on hover.

<ProjectCard name="Holiday campaign" client="Northwind" clientColor="sky" price="US$6,500.00 fixed" stats={[{ label: "Hours", value: "6.5h" }, { label: "Open tasks", value: 1 }, { label: "Deadline", value: "Oct 18" }]} />
  • actions: IconButton variant="ink" for invoice, report, edit, delete.
  • status: Active, On hold or Done.

Tile

A Home tile: a pastel card with one big number that links to its page. It lifts 9 px on hover.

<Tile icon="clock" label="Time" value="4.3h" detail="logged this week" color="lime" />
  • color: a palette name; the text is always --ink.
  • value sizes itself to the tile (the big-number style).

Feedback

Toast, status pill, live dot, meter.Open on its own ↗
Guidelines and props

Toast, status pill, live dot, meter. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

LiveDot

The 8 px dot of a running timer: it pulses while it runs and turns amber, still, when paused.

<LiveDot /> <LiveDot paused />
  • Always next to words that say the same thing (Tracking, Paused).

Meter

A flat meter for a fraction (3 of 5 done) or a range (day 4 of 12). The number is always written beside it.

<Meter value={3} max={5} label="3 of 5 done" />
  • variant: default (8 px) or start (the Getting started card, 6 px).

StatusPill

An invoice status pill. The word is always there; the color only repeats it.

<StatusPill state="overdue" />
  • state: draft, sent, paid or overdue.

Toast

The toast: what happened, then the way back. Destructive actions complete at once and put Undo here.

<Toast message="Task deleted" action="Undo" onAction={undo} />
  • action: Undo, or a named action such as "Use full motion" or "Show it".
  • contained keeps it inside its parent for mockups.

Data

List row and table, calendar, kicker and page head.Open on its own ↗
Guidelines and props

List row and table, calendar, kicker and page head. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

CalendarMonth

The Calendar month: own items as chips, external calendars as tinted chips, ranges as span bars.

<CalendarMonth days={days} onPick={setDay} />
  • Span bars: a project range is filled, a task range outlined. s and e round the first and last day.
  • Today carries the accent mark; the picked day the accent ring.

DataTable

A table for money and time: muted headers, numbers right-aligned and tabular, rows that tint on hover.

<DataTable columns={[{ key: "p", label: "Project" }, { key: "h", label: "Hours", num: true }]} rows={[{ p: "Holiday campaign", h: "6.5h" }]} />
  • num: right-aligned tabular figures. A row with paid: true reads muted.

Kicker

The small uppercase label over a number or a section, the only uppercase in HeyGoal.

<Kicker zone="project" help={<HelpBubble text="…" />}>Still owed</Kicker>
  • zone: invoices, project, expenses or payments adds the zone dot.
  • help: a HelpBubble, which stays in sentence case.

ListRow

A row in a list: the task check, the title, a meta line, and row actions on the right. Rows only tint.

<ul className="list"><ListRow title="Render 9:16 social cut" meta={["Product launch reel", "Due today"]} /></ul>
  • Put rows in a ul.list (a card) or ul.list.flat (inside a panel).
  • meta items can be nodes: a priority dot, a late date (.late).

PageHead

The head of every page: an optional kicker, the title, one line under it, and tools on the right.

<PageHead title="Billing" sub="What each project earned, what you spent on it, what it is still owed — and the invoices that ask for it." tools={<Button variant="primary" icon="invoice">New invoice</Button>} />
  • The title uses the display style; tracking sits on the style, so it never reaches a pill inside.

Shell

Top bar and phone bar, sidebar, account card states.Open on its own ↗
Guidelines and props

Top bar and phone bar, sidebar, account card states. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

AccountCard

The card at the bottom of the menu that names the person and the sync state, and opens the account menu.

<AccountCard name="Gabriel Rocha" status="synced" statusText="Signed in · Synced" initials="GR" />
  • status: plain, synced, idle, syncing, offline, error, conflict, or out (signed out, dashed). The color always comes with the words in statusText.

FrontDoor

The web app's sign-in screen: the wordmark, then the card with Google and an email link.

<FrontDoor phase="login" contained />
  • phase: intro, login or sent. contained keeps it inside its parent (for mockups) instead of covering the window.

Sidebar

The 248 px menu with the current link highlighted, the theme button and the account card at the bottom.

<Sidebar items={[{ id: "hub", label: "Home", icon: "home" }, { id: "tasks", label: "Tasks", icon: "check" }]} current="hub"><AccountCard name="Gabriel Rocha" status="synced" statusText="Synced" initials="GR" /></Sidebar>
  • mode: full (248) or icons (76).
  • editing: arrange mode, with grips and the pinned item locked.
  • wipe: plays the highlight wipe on the current link, for a page change.

TopBar

The 56 px glass top bar with the logo. phone gives the phone bar: logo, timer chip, avatar and menu button. It never names the page.

<TopBar phone timer="1:24:07" initials="GR" />
  • menuHidden: shows the show-menu button on desktop.
  • phone: the bar used at 860 px and under.
  • paused: the timer chip dot turns amber and stops pulsing.

Domain

Invoice sheet, Getting started, quick access item, note item.Open on its own ↗
Guidelines and props

Invoice sheet, Getting started, quick access item, note item. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

InvoiceSheet

The printable invoice: paper-white in both themes, the same rows the PDF writer draws in Helvetica.

<InvoiceSheet number="INV-0102" date="Sep 24" due="Oct 8" billTo={"Acme Co.\nAcme Corporation"} items={[{ desc: "Product launch reel — animation and edit (8.25h)", qty: "8.25", unit: "US$95.00", amount: "US$783.75" }]} total="US$783.75" />
  • paid: adds the Paid stamp in --paper-good.
  • Print drops the shadow and the radius.

NoteItem

A note in the Notes list: the title, the date and time, the image count. The open note carries its project color as a bar.

<NoteItem title="Holiday campaign: client feedback" when="Today · 9:40 AM" color="blush" current />
  • color: the project palette name, shown as the 4 px bar on the open note.

QuickItem

A Quick access item: a link or a snippet, with its project tag in the project color. It lifts on hover.

<QuickItem title="Frame.io review" detail="app.frame.io" project="Holiday campaign" projectColor="blush" />
  • type: link or snippet (image items use the same card with a thumbnail).

StartCard

The Getting started card: five steps (done, next with its button, pending), the meter, and where the data lives.

<StartCard steps={[{ title: "Add a client", state: "done" }, { title: "Start a project", state: "next", action: <Button size="compact">Add a project</Button> }]} where="Saved in this browser only, until you sign in" />
  • The storage line names the real setup. Demo content is marked and never counts.

Icon

Icon: one glyph from the 20 px set, at 16, 20 or 24, in currentColor.Open on its own ↗
Guidelines and props

Icon: one glyph from the 20 px set, at 16, 20 or 24, in currentColor. Markup uses the app's class names, so the same HTML works in the vanilla-JS app; the React twins in the source set the same classes.

Icon

One glyph from the HeyGoal icon set, 20 px grid, in currentColor. Use it for every icon; never draw new SVGs.

<Icon name="invoice" size={20} />
  • name: one of the 52 names (home, check, folder, clock, receipt, note, user, gear, plus, trash, tick, invoice, report, edit, …).
  • size: 16 in text and pills, 20 in menus and controls, 24 in the phone bar. Nothing in between.
  • title: gives the icon an accessible name; leave it off when the icon sits beside a word.
HeyGoal design system 0.6.0 · generated from tokens.json and the component CSS in design-system\HeyGoal design system · works offline, open any page in a browser.