Skip to Content

Design System

Kinetrix Design System

The rules Kilter is designed and built with: color, type, spacing, elevation, motion and components. This page is generated from DESIGN.md in the Kinetrix repository every time the site is built.

Last changed , in commit d3f6ba0.

#Tokens

The values listed at the top of DESIGN.md. Screens use these values instead of writing their own, and components are defined in terms of them.

#Colors

Palette

signal-blue #056ffa
signal-blue-hover #1264ce
signal-blue-ink #1264ce
signal-blue-soft #f0f6fe
signal-blue-line #bad7fc
paper #f4f4f4
panel #ffffff
panel-hover #f4f4f4
inset #f4f4f4
inset-hover #e8e8e8
hairline #bcbcbc
hairline-strong #949494
graphite #141414
slate #565656
ash #6f6f6f
alarm-red #bc2e24
amber #a96704
leaf-green #0d824b

Tones

tone-accent-bg #ecf4fd
tone-accent-ink #1757ab
tone-danger-bg #f9d9d7
tone-danger-ink #8a1c15
tone-warning-bg #fef3e2
tone-warning-ink #8b5504
tone-success-bg #e6f9f0
tone-success-ink #097241

Dark Theme

night-paper #141414
night-panel #1f1f1f
night-inset #1a1a1a
night-hairline #4b4b4b
night-ink #fafafa
night-signal-blue #2881f6
night-signal-blue-ink #599ef8

#Typography

RoleSizeWeightTrackingLine Height
page1.125rem600-0.025emNot set
section0.875rem600Not setNot set
body0.875rem400Not set1.25rem
detail0.75rem400Not set1rem
micro0.6875rem400Not set1rem
overline0.6875rem6000.025emNot set
mono0.75rem400Not setNot set
figure1.25rem600-0.025em1

Font stacks, in order of preference:

  • Open Sans Variable, Open Sans, Segoe UI Variable, Segoe UI, -apple-system, BlinkMacSystemFont, system-ui, sans-serif
  • Cascadia Code, JetBrains Mono, ui-monospace, SFMono-Regular, Menlo, monospace

#Radius

NameValueSample
control0.375rem
container0.5rem
full9999px

#Spacing

NameValueSample
3xs2px
2xs4px
xs6px
sm8px
md12px
lg16px
xl20px

#Components

ComponentProperties
button-primarybackgroundColor signal-bluetextColor panelrounded control (0.375rem)height 36pxpadding 0 12pxtypography body
button-primary-hoverbackgroundColor signal-blue-hover
button-secondarybackgroundColor paneltextColor graphiterounded control (0.375rem)height 36pxpadding 0 12px
button-secondary-hoverbackgroundColor panel-hover
button-ghostbackgroundColor transparenttextColor slaterounded control (0.375rem)height 36pxpadding 0 12px
button-ghost-hoverbackgroundColor insettextColor graphite
button-dangerbackgroundColor alarm-redtextColor panelrounded control (0.375rem)height 36pxpadding 0 12px
icon-buttonbackgroundColor transparenttextColor slaterounded control (0.375rem)size 36px
inputbackgroundColor paneltextColor graphiterounded control (0.375rem)height 36pxpadding 0 10pxtypography body
cardbackgroundColor paneltextColor graphiterounded container (0.5rem)padding 12px
panelbackgroundColor paneltextColor graphiterounded container (0.5rem)padding 0
chipbackgroundColor transparenttextColor slaterounded control (0.375rem)height 32pxpadding 0 8pxtypography detail
chip-selectedbackgroundColor signal-blue-softtextColor signal-blue-ink
nav-itembackgroundColor transparenttextColor slaterounded control (0.375rem)height 36pxpadding 0 8pxtypography body
nav-item-activebackgroundColor signal-blue-softtextColor signal-blue-ink
callout-accentbackgroundColor tone-accent-bgtextColor tone-accent-inkrounded container (0.5rem)padding 12px
callout-dangerbackgroundColor tone-danger-bgtextColor tone-danger-inkrounded container (0.5rem)padding 12px

#1. Overview

Creative North Star: "The Precision Instrument"

Kilter is a tool someone chose, not one they were sold. It reads like a well-made instrument on a desk: every edge is one pixel, every radius and gap comes from a closed scale, and nothing on the screen is there to be interesting. The person using it has six other things open and a question ("what needs me today?") that the overview answers without a click. Density is a feature: more on screen, less scrolling, space spent only where it aids scanning.

The system decides, not the screen. Color, radius, spacing, elevation, type, motion and icon size each come from one scale, defined once, and a screen composes from that vocabulary: it never invents a hex value, a pixel size, a type size, a press treatment or an icon size of its own. The rules are checked by the build rather than by review, because a hand-built exception looks fine on its own and only becomes a problem at the seventeenth. Delight here is precision: the ring that turns the panel's corner, the fill that answers a press, the menu that fades in exactly where it was placed.

What it rejects outright: the playful consumer app (bouncing or elastic motion, mascots, confetti, emoji in empty states, celebratory language) and the generic SaaS template (gradient heroes, big-number stat cards, grids of identical icon-and-heading cards, purple-to-blue gradients, decorative glassmorphism). If a screen could belong to any product in the category, it is wrong.

Key Characteristics:

  • One accent hue (blue, 214 degrees) for everything interactive or selected; three signal hues, each meaning exactly one thing; everything else gray.
  • Every edge is one pixel. The focus ring is the only two-pixel line.
  • Type is a single humanist sans at a tight scale; roles, not sizes, are named.
  • Flat surfaces with one hairline and one step of ambient shadow. Overlays float on a second, deeper step.
  • Motion decelerates everywhere, at the comfortable middle of Fluent's and Material's tempos, and nothing leaves in a hurry. Things arrive by opacity; nothing that carries text is transformed, so words stay crisp while they arrive.
  • Reduced motion, 150% text scale and full keyboard operation are constraints, not modes.

#2. Colors

A restrained palette: untinted neutrals stepped from paper to graphite, one signal blue that means "interactive", and three signal hues confined to tonal containers and short status text.

#Primary

  • Signal Blue (#056ffa, hue 214): the one interactive color. Primary buttons, the current navigation row, the picked ring, the focus ring, the marquee band, links in prose. It is the blue in the logo and the favicon, and every accent step is derived from this hue.
  • Signal Blue Ink (#1264ce): the same hue as text, on light surfaces, where the fill would fail contrast. Selected titles, accent-toned labels.
  • Signal Blue Soft (#f0f6fe) with Signal Blue Line (#bad7fc): the fill and hairline of anything selected or current: the active navigation row, a picked chip, a picked card.

#Neutral

  • Paper (#f4f4f4): the application background, and the frame around a page: the top bar, the side rail and the bottom bar sit on it, and so does the header of a page that is a set of things. The frame recedes and the work stands off it.
  • Panel (#ffffff): every card, panel, dialog and field surface, and the sheets that are a whole page, such as a list beside its detail.
  • Inset (#f4f4f4): a recessed area inside a panel, and the hover fill of ghost controls and rows. Inset is Paper: a recess in a panel goes down to the desk the panel sits on, which is why anything inset that sits directly on Paper (a board column, a segmented track) carries a hairline to be seen by.
  • Inset Hover (#e8e8e8): the hover fill of something that is already inset, such as a subtle control.
  • Hairline (#bcbcbc) and Hairline Strong (#949494): every border and divider, and the border a hovered control earns.
  • Graphite (#141414): the thing itself: titles, names, values, body copy.
  • Slate (#565656): supporting text, a description, a ghost control's ink.
  • Ash (#6f6f6f): metadata: dates, counts, placeholders, overlines.

There are exactly three ink levels and nothing between them. The night palette swaps the same roles onto Night Paper (#141414), Night Panel (#1f1f1f), Night Inset (#1a1a1a), Night Hairline (#4b4b4b) and Night Ink (#fafafa), and lifts the accent to Night Signal Blue (#2881f6), with Night Signal Blue Ink (#599ef8) so accent text clears contrast on the dark panel.

#Tertiary

The signal hues. Each is far enough from the accent, and from each other, to read as a signal rather than a color, and each means one thing:

  • Alarm Red (#bc2e24): destructive, overdue, failed. Never decoration.
  • Amber (#a96704): pending, warning, needs attention soon.
  • Leaf Green (#0d824b): done, verified, delivered.

Each signal also has a tonal quartet (background, hairline, heading ink, body ink) generated together and contrast-checked, for callouts and tinted rows: Tone Accent (#ecf4fd / #1757ab), Tone Danger (#f9d9d7 / #8a1c15), Tone Warning (#fef3e2 / #8b5504), Tone Success (#e6f9f0 / #097241).

#Named Rules

The One Signal Rule. Signal Blue means interactive or selected and nothing else. It is never a heading color, never a decoration, never a background for content. If it is on more than about a tenth of a screen, something is wrong.

The Gray-Or-Meaning Rule. A color is one of the three signals meaning its one thing, or it is gray. Nothing is colored to be interesting, and every status also carries an icon and a written label so the interface survives grayscale. The one place more than one hue appears at once is the ring the assistant draws while it is changing something on screen: a turning spectrum around the card, row or chip, gone a moment after it finishes. Nothing else looks like it, so it cannot be mistaken for selected, due or yours.

The Generated Palette Rule. No hex value is written by hand. Every color is generated from one accent hue and three signal hues, and the neutral steps are solved from the contrast each role has to reach rather than picked and then measured, so both themes are held to the same numbers. The build fails if any text-on-surface pair drops below 4.5:1 in either theme.

#3. Typography

  • Display font: Open Sans Variable, then Segoe UI, then the system sans.
  • Body font: the same.
  • Mono font: Cascadia Code, then JetBrains Mono, then the system mono.

Character: one humanist sans at every size, set tight. Hierarchy comes from a step or two of scale and a step of weight, never from a second family. It reads as a tool's interface, not a document, and matches the platform text around it on every operating system.

#Hierarchy

Roles, not sizes. A screen names a role and never a size, and each role carries its own ink level, so two descriptions on two screens cannot land at different grays.

  • Page (600, 1.125rem, tracking -0.025em): the one page title. Graphite.
  • Section (600, 0.875rem): a panel heading, a dialog title. Graphite.
  • Body (400, 0.875rem) and Body Strong (500): content, titles in rows, labels on controls. Graphite.
  • Detail (400, 0.75rem) and Detail Strong (500): supporting text, a description under a title. Slate.
  • Micro (400, 0.6875rem) and Micro Strong (500): metadata: dates, counts, locations. Ash.
  • Overline (600, 0.6875rem, uppercase, tracking 0.025em): a group label inside a panel. Ash.
  • Tiny (400, 0.625rem): the smallest legible mark, for a collapsed band or a count inside a 14px badge. Ash.
  • Figure (600, 1.25rem, no line height of its own): the one number on a stat tile, centered on its digits. Graphite.
  • Code (mono, 0.75rem): a value quoted verbatim inside running text, the last four characters of a key. Graphite.

The root size is fluid by default, clamp(15px, 14.6px + 0.114vw, 18px), and the whole interface is sized in rem, so the user's text scale (90 to 150%) resizes layout and not just type. Long prose, such as a note, is held to a reading measure rather than running the width of its pane.

#Named Rules

The Named Role Rule. No screen sets a font size, a weight or a line height of its own. A component that needs a heavier value, or a looser line for a paragraph of explanation, grows an option for it; it does not accept a one-off size from the screen that uses it.

The Two Digits Rule. Counts use tabular figures inside a circle sized to two digits (one, at the small size), so 1 and 99 are the same circle. A count too long for its circle turns it into a capsule, on purpose, and nothing else changes its shape.

#4. Elevation

Flat surfaces, structured by hairlines, with two steps of ambient shadow for surfaces and no more. Depth is conveyed by the hairline first: a panel is a panel because it has a one-pixel border on Paper, not because it floats. The shadow confirms it from the corner of the eye, and the fill says which layer a thing is on: Paper for the frame, Panel for the work.

#Shadow Vocabulary

The geometry is the same in both themes and only the opacity changes. The values below are the light theme's; the dark theme's are several times stronger, because a shadow on a dark page has less light to take away.

  • Raised (box-shadow: 0 1px 2px rgb(0 0 0 / 0.04), 0 6px 16px -4px rgb(0 0 0 / 0.03)): every panel and card, and the primary, secondary and danger buttons. One step off the page: a one-pixel contact line and a wide ambient fall-off under it, so the surface reads as resting on Paper rather than drawn on it.
  • Overlay (box-shadow: 0 16px 40px rgb(0 0 0 / 0.1), 0 4px 12px rgb(0 0 0 / 0.06)): a menu, a popover, a tooltip, a dialog. The only surfaces allowed to float over content, reaching noticeably higher than Raised so the two steps are never mistaken for one.
  • Drag (box-shadow: 0 3px 6px -1px rgb(0 0 0 / 0.16), 0 20px 44px rgb(0 0 0 / 0.16)): the card under the pointer while it is being carried, and nothing else.
  • Stuck (three layers): a sticky note, which is glued along its top edge and free along the other three. A contact line where it touches the page, and a soft fall under the edge that lifts away. Nothing else is glued down at one end, so nothing else wears it.

#Named Rules

The Two Steps Rule. A surface is on the page, or over it. There is no third step for a surface, no hover lift, and no shadow that grows on hover: a hovered control changes its fill and its edge, never its height. The two shadows outside the steps belong to objects rather than surfaces: a card being carried, and a sticky note.

The Frame Recedes Rule. The chrome is the desk, not a surface on it. The top bar, the side rail and the bottom bar are Paper with a hairline, the same fill as the ground a page's panels sit on, so the eye reads two layers and only two: the frame and the ground together, and the work standing off them. A page that is a set of things (the overview, reminders, settings) has a Paper header with Panel things under it; a page that is one sheet (notes beside their editor, conversations beside the one being read) is Panel edge to edge, its pane headers included. Once the page scrolls under the top bar, the bar trades its hairline for the Raised shadow over a translucent Paper fill, so what passes beneath it reads as passing beneath. Nothing else in the chrome is Panel, because a white bar over white panels was the flatness this rule replaced: every surface at one height, told apart by hairlines alone.

The One Pixel Rule. Every edge in the interface is a single pixel: a border, a hover ring, a picked ring, the marquee, the hairline on the open row. A picked surface drops its own border under the ring so it never doubles to two. The focus ring is two pixels because it must be found from across the room; the color picker's thumbs wear two pixels of white to stay visible on any hue. Those are the only exceptions.

#5. Layout

#Named Rules

The One Gutter Rule. A page's header and its body are inset by the same amount, on every page and at every width: 1rem on a phone and 1.5rem from the small breakpoint up. A board's columns scroll edge to edge by taking that gutter back rather than by having a smaller one, and a reading pane (a note, a conversation) uses the same inset. Inside a surface the insets are the row's: 0.75rem across a row, a menu item and a pane header, 0.5rem above and below a column header, and 0.625rem above and below a row. Nothing is inset by an amount of its own.

The Centerline Rule. Everything on a row shares its centerline: the control at its end, the date, the badge, the icon before its text, a dialog's close button beside its title, a page's actions beside its heading, a toast's icon and dismiss beside its message. Nothing on a row is aligned to its top and nudged down by a guess at where the first line's middle is. The one composed exception is a row whose second line is indented under its title (the agenda, a reminder): its checkbox shares the title's line, because the indent says the control governs the title, and that line is itself centered.

The Pixel Grid Rule. Every box lands on a whole pixel, and every vertical length is an even number of them. Sizes are rem so the interface grows with the text scale, and the root size is fluid, so a rem is almost never a whole number of pixels. Every spacing step, line height, glyph size and circle is rounded where it is defined, vertical lengths to two pixels so that whatever is centered lands on a whole pixel, and anything positioned by script rounds its coordinates. A one-pixel edge then has one pixel to be drawn in, and an animation ends exactly where its element already is, instead of jumping a pixel the moment it finishes.

#6. Motion

Motion clarifies and never performs. It shows where something went or that a state changed; it never announces itself, never blocks input, and never moves large areas of the screen.

#Tempo

  • Durations. Feedback (a press, a toggle) at 160ms. A change in place (a hover, a color, a border) at 240ms. An arrival (a menu, a tooltip, a popover) at 340ms. A layout change (a dialog, a disclosure) at 440ms. An exit at 220ms.
  • Curves. Everything decelerates. An arrival rides an emphasized deceleration that spreads the motion across its whole duration, an exit rides an ease out into nothing, and a change in place keeps a quartic ease out. There is no accelerating curve: a surface leaving on one is at its fastest the instant it disappears, and reads as cut rather than faded.
  • Pages. A page changes by fade-through, and so does a page changing one of its own views. The outgoing half is gone before the incoming half begins, a page in 300ms and a view in 340ms. Nothing slides and nothing rises; the only movement is a 4% scale from the center, which has no direction for the eye to follow. What is inside a page arrives with it rather than cascading in after it.
  • The pointer. A list row's hover fill arrives with the pointer instead of fading in: a pointer crosses four rows of an agenda in less time than one 240ms fade takes, and a list holding three half-lit rows reads as a flicker. It still fades out, and everything else a row animates fades both ways.
  • Reduced motion. Under reduced motion, whether it comes from the operating system or from the in-app setting that overrides it in either direction, every duration falls to one millisecond. Anything that moves stays legible with the movement removed.
  • Nothing bounces, overshoots or moves elastically.

#Named Rules

The Crisp Text Rule. Nothing that carries text is ever transformed, and nothing transparent ever fades. An animating transform, or a fade on an element with no fill of its own, is drawn on a compositor layer, and text on a compositor layer loses its subpixel antialiasing until the animation ends: on a Windows screen, ClearType switches off for the length of the animation and snaps back on at the end of it. So there are exactly two ways for something to arrive, and one question decides which. A surface that paints its own fill (a menu, a toast, a dialog's panel, a callout, a column) fades itself, and its text stays crisp over the opaque fill. Words on a surface that is already there (a page, a validation message, a confirm strip, a disclosure's content, a list replacing itself, an empty state) are unveiled: a layer in the surface's own color lies over them and lifts, which looks identical and leaves the words on the surface the whole time. A press is a fill, never a scale. The two indicators that move, a toggle's knob and a segmented control's plate, move as layout, and a caret that turns is two carets crossfading. The transforms that remain are the reorder of a dragged or moving item, while the eye is on the thing that moved, and the small scale of a page crossfade.

#7. Components

Every control comes from one component library. A screen never builds its own button, link, field, select, text area, form or dialog, and every control has default, hover, focus, active, disabled and loading states.

#Buttons

  • Shape: softly squared (0.375rem radius), 36px tall at the default size (32 small, 44 large), always with a border so filled and outlined variants occupy identical space.
  • Primary: Signal Blue fill, white text, a one-pixel edge a step darker than the fill, one step of raised shadow. Hover moves fill and edge together to the hover blue.
  • Secondary: Panel fill, Graphite text, Hairline edge, raised. Hover moves to Panel Hover and Hairline Strong.
  • Ghost: transparent, no visible edge until hover, when it earns a fill and a hairline: a toolbar of bordered icons is noise, but a reached control should feel like an object. Quiet is the same with no plate, for a glyph on a row that already hovers.
  • Heading: a title that is also a control, such as the name of the open board.
  • Danger: Alarm Red fill, for the one destructive action at the end of a form. Danger Ghost for a delete living in a row: quiet until reached.
  • Link in prose (accent ink, underline on hover) and Bare (no chrome, inherits color) for a title that is the row's hit target.
  • Press: a labeled button answers with a wash of eight percent of its ink, laid inside its own edges for as long as it is held, and nothing moves. An icon button takes no wash, because on a control that is only a glyph the wash reads as a box appearing behind it, and its glyph holds still. A button set inline in a sentence takes none either, because it has no padding for a wash to sit in (the Padded Fill Rule). On a coarse pointer every control's hit area extends invisibly to the 44-point platform minimum: a button past its 36 pixels (32 at the small size), a checkbox past its 16, each by exactly what it falls short.
  • Focus: the one focus treatment, everywhere: a two-pixel Signal Blue outline, offset two pixels, only on keyboard focus.

#Chips

  • Style: transparent, Hairline edge, Slate text, control radius, 32px tall, detail type.
  • State: picked is Signal Blue Soft on Signal Blue Line with Signal Blue Ink, and the pressed state is announced to assistive technology. Weekday pickers, capture destinations, theme and text size choices are all this one chip.

#Cards / Containers

  • Corner Style: container radius (0.5rem) on every surface that holds other things: cards, panels, dialogs, popovers, columns. Control radius (0.375rem) on everything interactive. Full round only for circles and pills.
  • Background: Panel on Paper.
  • Shadow Strategy: raised, always; never more.
  • Border: one Hairline. A hovered card earns Hairline Strong.
  • Internal Padding: 12px on a card, 10px on a board card. A card made of full-bleed rows has none: the rows are divided by hairlines, and the last row takes the card's bottom corners so a picked ring turns with them.
  • Picked: one treatment everywhere: Signal Blue Soft fill, a one-pixel Signal Blue ring inset and following the corners, Signal Blue Ink title. Open (as distinct from picked) is a one-pixel ring in the ink color. The ring is always there, transparent until the surface is picked, so being picked or unpicked transitions the ring's color rather than popping a box that did not exist a moment before. A board column being carried is the one deliberate exception: the ring alone, with the fill left off, because a column already holds cards that wear the fill themselves.
  • Somebody else is here: a card, note or event whose editor someone else in the workspace also has open shows a Signal Blue Soft callout naming them, at the top of the same editor. It is a notice, not a lock: nothing stops either person from saving.

#Inputs / Fields

  • Style: Panel fill, Hairline edge, control radius, 36px tall at the default size (32 small, 44 large), Graphite text, Ash placeholder. A bare variant carries no chrome, for a title that is edited in place.
  • Focus: the same two-pixel Signal Blue outline every control has.
  • Error / Disabled: an invalid field's focus ring turns Alarm Red and the message sits beneath it, announced as it appears; disabled is Inset fill at 60%.
  • Validation is the app's own: a form never shows the browser's validation popup.
  • Addresses: every view is a path and every section is one more segment: /settings/notifications is the tab, and /settings/notifications/how-you-are-told is the card on it, which arrives centered in view wearing the picked ring (the same ring, because being pointed at by a link and being picked are the same statement about the same box). A panel's heading links to its own address, so the reference can be copied from the panel itself; Escape takes the ring off. A view the page does not have (a typed /settings/foo) falls back to the remembered one and is corrected in place, with no history entry.
  • Side rail (desktop): 36px rows, control radius, icon then label, label hidden when the rail collapses to 56px. Resting rows are Slate on nothing; hover lifts to Panel with a Hairline; the current row is Signal Blue Soft on Signal Blue Line with Signal Blue Ink, and is announced as the current page. A press lays the same wash over the row as over a button; nothing on it moves.
  • Bottom bar (phone): the same items stacked, icon over a tiny label, 52px tall plus the safe-area inset.
  • Top bar: the workspace switcher, the door to the command palette, the assistant, who else is in the workspace right now, notifications and the account menu. The logo is a link home and hovers like a navigation row. The command palette opens as a panel beneath its own door, at the door's width, rather than as a modal; below the small breakpoint the door is a glyph.
  • Icons: one family, Phosphor, in two weights: filled for the navigation rail, the bottom bar, option tiles, the assistant mark and the notifications bell, regular for icons beside text and metadata. A screen sizes an icon by where it sits, from a scale of four: 12 beside metadata, 14 beside body text, 16 in a control and 18 on a tile. A component may size its own glyph against its own label.
  • Menus and selects fade in where they were placed, 340ms on the enter curve, and fade out in 220ms on the exit curve. Overlay shadow, container radius.
  • Dialogs fade in over 440ms on the enter curve while the backdrop dims over the same 440ms on its own curve. The animation is on the panel, which paints its own fill. On a phone the panel is the whole screen and fades the same way.
  • Tooltips are the app's own, never the browser's: overlay shadow, detail strong type, a 240ms fade, shown on hover after 400ms and on keyboard focus at once.

#Lists

  • A list is rows, divided by the surface's own hairline, with everything on a row on one centerline. A list built from plain rows with a gap between them is not a list.
  • A row's secondary controls (its menu, its delete) stay out of the way until the row is reached under a mouse, and are simply there under a thumb.
  • The now line marks the present moment. On a time axis it is a hairline in the alarm hue with a dot on its left end; in a list it is a line above the next item, cut to the width of the glyph column, with how long until it begins beside it. It is never a rule across a list, which reads as a divider. Its word and its hue step down as the wait grows: Now in the alarm hue inside five minutes, Soon in amber inside the hour, Later in gray past it.
  • Code blocks have a strip naming their language and a control that copies the whole block, in mono type on the inset fill behind one hairline. There is no syntax coloring in the application: one accent and three signal hues each mean one thing, and code in six colors would be the loudest object on the screen. A copy control says Copied in itself for a moment and never raises a toast.

#Named Rules

The Surface Controls Rule. A transparent control has no colors of its own. Its ink, its hover fill and its hover edge are the surface's: Slate and Inset on the page, Signal Blue Ink and Signal Blue Soft on a picked card or row, the tone's own inside a callout. A control dropped onto any surface belongs to it without being told, and picking or unpicking the surface recolors every control on it at once.

The Padded Fill Rule. Anything whose background changes on hover or on press has room inside that background, so the fill never touches the words or the glyph it holds: a row keeps 0.75rem at its sides, a button its own padding, a chip or a menu item the padding it was drawn with. A row whose words line up with the text around it keeps them there and reaches its fill out past them into the margin, rather than losing its padding. Something with no room for a plate takes no plate, on hover or on press, and answers with its ink instead: a link in a sentence, a title that is its row's target, a heading that is also a control. A fill drawn tight around a line of words reads as a highlighter mark, not as a control.

The Pointer Rule. Every enabled button shows a pointer on hover, and no disabled control does, whichever way it was disabled.

The Grabbable Thing Rule. Anything that can be picked up and moved wears an open hand while it can be, and a closed one for as long as it is held, never a pointer or an arrow: a board's cards and columns, a calendar occurrence, a sticky note. On a touch screen, picking a thing up and scrolling past it are the same gesture until the finger has been down a moment, so a board waits that moment out before a touch becomes a drag: a swipe meant for the page underneath still scrolls, and only a hold long enough to mean it lifts the card or the column.

The Recipe Rule. A pattern built by hand in two places becomes a shared component, with options that agree with its neighbors. Every copy is replaced, and a hand-built copy is refused from then on.

The Reveal, Don't Render Rule. A list that can grow without real bound (reminders, notes, a workspace's tags, a conversation's history) shows eight rows to start and grows by eight each time the row at its foot is reached, whether by a click or by the scroll that carries it into view. Eight is the number for a list that could get long, not a cap dressed up as a feature: a workspace's members, a board's columns and a card's tags are shown whole. A list laid out by clock time rather than list order, such as a calendar day, has no next eight and is exempt. A board's column opens with twenty-four cards and grows by twelve, because a column is a tall list in a short box. A page that stacks several such lists pages each of them instead, eight rows a page, so a long group never pushes the others out of reach.

#8. Writing

The voice is short and factual. It says what happened and what is true, and it does not narrate: no exclamation marks, no encouragement, no personality in error messages. It is written in American English, and no dash is ever used as punctuation.

#Named Rules

The Title Case Rule. Every label is Title Case and every sentence is a sentence. A label names a thing or a control: a heading, a button, a menu item, a tab, a chip, a badge, a field's label, a tooltip, a dialog's or an empty state's title. Small words (a, an, the, and, but, or, nor, so, yet, of, to, in, on, for, with, by, at, from, as, into, onto, per, via, vs) stay lowercase unless first or last; an initialism stays as it is. A sentence (a description, a hint, a question, a toast, body copy, a link inside a sentence) keeps sentence case and ends in a period, so the two are told apart by their shape and never by taste. The build refuses a label that is not Title Case, and names it.

The Failure Rule. A failure is told in three parts and never in one: the sentence about what was being done ("Could not move the card."), the reason in the server's words or a line on what to do, and the code with the request's reference ("K104 · ref 7F3A2C1D") in the micro role beneath, with a way to copy all of it. A toast that said only the first part was true and useless; the code is the part support asks for, so it is on the screen that failed. Validation guidance ("Give the event a title.") is not a failure and carries no code.

The One of Each Rule. There is one selection treatment, one focus treatment, one empty state and one loading state. A page that fetches its own data shows the shape of what is coming, then the page, then one honest empty state.

The Manual Path Rule. With no model connected, the application is complete, not degraded. An affordance that cannot work is absent, not grayed out and not shown failing. What the assistant already made (a stored summary, a title it wrote) is a record of what happened and stays; a live offer to do something with a model does not appear.

#9. Do's and Don'ts

#Do:

  • Do compose every screen from the component library and the shared vocabulary. The checks are the floor, not the ceiling.
  • Do keep every edge one pixel (#bcbcbc light, #4b4b4b dark) and let the picked ring replace a surface's border rather than stack on it.
  • Do keep every box on a whole pixel and every height on an even one.
  • Do use Signal Blue (#056ffa) only for what is interactive or selected, and each signal hue for exactly its one meaning, always with an icon and a word beside it.
  • Do name a type role (page, section, body, detail, micro, overline, tiny, figure, code) and let it carry its ink level.
  • Do compose the arrangement, not just the control: a title with its description, a pane header, a list beside its detail, a row with its menu. The second time a shape is built by hand, it becomes a component.
  • Do start an unbounded list at eight rows and grow it, or page it where it is one of several lists stacked on a page.
  • Do size an icon by where it sits.
  • Do enter at 340ms, leave at 220ms, change in place at 240ms, and fall to one millisecond under reduced motion.
  • Do arrive by opacity alone: a surface with its own fill fades, and words on a surface that is already there are unveiled.
  • Do answer a labeled control's press with a fill. Nothing scales.
  • Do keep the app complete without AI: hide an affordance that cannot work rather than show it failing.
  • Do write short, factual copy: labels in Title Case, sentences in sentence case ending in a period.
  • Do keep the one gutter. A screen that needs a different inset is a screen the scale is wrong for, not an exception.

#Don't:

  • Don't invent a hex value, a pixel size, a shadow, a radius or a duration on a screen. Everything comes from the token layer.
  • Don't use a colored stripe wider than one pixel down the side of a card, row, callout or alert.
  • Don't use gradient text, decorative blur or glassmorphism, or a hero metric card with a big number and a small label.
  • Don't use gradient heroes, grids of identical icon-and-heading cards, or purple-to-blue gradients.
  • Don't bounce, overshoot or use elastic motion, and don't let anything travel across the screen.
  • Don't transform anything that carries text, on arrival, on press or on hover, and don't fade an element that has no fill of its own.
  • Don't use mascots, illustrations, confetti, emoji in empty states or celebratory language.
  • Don't use the browser's own chrome: no native tooltips, validation popups, focus rings or disclosure markers.
  • Don't lay content beside a stretched control and count on the stretch to catch a tap. A phone gives the tap to the nearest thing under the finger, so put the contents inside the control.
  • Don't put gray text on a colored surface; a tonal container sets its own ink for everything inside it.
  • Don't invent a second selection treatment, a second focus treatment, a second empty state or a second loading state.
  • Don't reach for a modal first. The card detail, the reminder editor and the confirm strip are inline or in place wherever the flow allows it, and a name is typed where the name is shown: a one-line question in a box that fills a phone is the whole screen asking for four words.
  • Don't render the whole of a list that can grow past a first look.