Skip to Content

Design System

Kinetrix Design System

The rules Kilter is designed and built with: color, type, spacing, elevation, motion and components. Generated from DESIGN.md on every build.

Last changed , in commit aab0bd0.

#Tokens

The values at the top of DESIGN.md. Screens and components are built from 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 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. Motion is allowed to be fun: a bounce, an overshoot, something crossing the screen or a burst of confetti is fine where a moment earns it.

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, on Fluent 2's and Material 3's own tempos, and nothing leaves in a hurry; the one spring is for objects coming to rest. Things arrive by opacity and a few pixels of travel from whatever opened them, a press ripples from where it landed, and 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. Two things show more than one hue at once. One 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 other is confetti (the Earned Moment Rule), which is paper in the workspace's own palette, the colors its tags and columns are already drawn in, and which is gone inside two seconds and means only that something was finished.

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.

The Reader's Palette Rule. A contrast theme the reader forces on every page (Windows' own, or any other) replaces every color above with a handful of theirs, drops the shadows and lays every fill down to their ground. Whatever this interface says with a fill or a shadow alone is then said in their palette's own words, the way the system's own controls say it: the current page, a picked chip, the chosen segment and a switch that is on are the highlight with its text, a ticked box fills with it, and a picked card wears a two pixel ring of it. A border kept only to hold a box's size stays out of sight rather than coming back as a box around every quiet control. The one thing that keeps its own colors is a code for a camera, which is read dark on light whatever the reader chose.

#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, the note or the sheet under the pointer while it is being carried, and nothing else.
  • Stuck (three layers): paper, which is glued along its top edge and free along the other three: a sticky note, and a list's sheet on the Todo desk. 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 paper.

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 One Column Rule. A page whose body is a centered column (a form, a dashboard) gives its header the same column: the title stands over the first letter of the content it names, at every window width, rather than at the window's edge a few hundred pixels to its left. A page whose body runs the full width (a board, a calendar, a list such as the reminders or the people) runs its header the full width too. A list is full width because a desk's screen serves it better than a phone's column down the middle of it. Panes side by side do the same across: every pane header is one height, so the rules under a list and under the thing open beside it are one line, and a pane with a second line to offer (a search) puts it in a band of its own below the rule.

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.

The Upright Phone Rule. On a phone the application is upright only. Every page is laid out for a phone held upright, and on its side a phone leaves a strip under the bar too short to be a page. A browser tab cannot refuse a rotation, so a phone on its side is covered by one notice, Turn Your Phone Upright, in the top layer above any open dialog, and turning it back uncovers the page exactly as it was; an installed copy on Android is asked to hold the screen upright instead. A phone is a touch screen whose short side is under 600 pixels, so a tablet turns freely, and the screen's orientation decides it, never the viewport's, which the keyboard turns sideways on every upright phone.

#6. Motion

Motion clarifies and never performs. It shows where something came from, where it went or that a state changed; it never announces itself, never blocks input, and never moves large areas of the screen. It is Microsoft's and Google's motion, taken whole where it can be and translated where it cannot: the tempos, the curves, the short journey from an anchor that Fluent 2 and the Azure DevOps console give a popover, Material's ripple and its fade-through. What is translated is the transform, because a transform softens text.

#Tempo

  • Durations. Feedback to a press at 150ms. A change in place (a hover, a color, a border, a switch's track changing color) at 250ms. An arrival (a menu, a popover) at 350ms, and an indicator moving to its selection (a segmented control's plate, the plate under the current page) at the same 350ms. A switch's knob, which is what says which way the switch went, rides the spring below instead. A tooltip, which is small and close, arrives at 250ms. A layout change (a dialog, a disclosure) at 450ms. An exit at 200ms. Every one is a step both Fluent 2 and Material 3 publish, on the fifty millisecond grid the two share, so a choice can be checked against either system's table.
  • Travel. A surface that came from somewhere travels the last few pixels of the way as it fades in: a menu, a list of options or the search panel ten pixels away from the control it hangs from, down from one it hangs under and up from one it was flipped above; a tooltip four; a dialog or a toast sixteen, rising into place. Ten is the distance Fluent 2's popovers and the Azure DevOps callouts travel. The journey is layout, a margin or an offset, and never a transform, so the words make the trip already laid out where they will land. Nothing travels on the way out: an exit is a fade where the thing is.
  • 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. One curve overshoots, and it is a spring, sampled from a damped one rather than drawn: it passes its rest by an eighth and settles in two small swings over 600ms. It moves objects knocked into rest (the mark, the bell, a switch's knob, a destination catching what was thrown to it) and never a surface arriving or anything carrying words.
  • 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 200ms and a view in 250ms. Nothing slides and nothing rises; the only movement is a 3% scale from the center, which has no direction for the eye to follow. The one view that slides is one a finger turned, which goes the way it was pushed (the Turned View Rule). What is inside a page arrives with it rather than cascading in after it.
  • The pointer. A list row answers the pointer at 150ms, in and out alike, rather than the 250ms every other hover takes: a pointer crosses four rows of an agenda in less time than one 250ms fade, and a list holding three half-lit rows reads as a flicker. For a while the fill arrived with no fade at all and only faded out, and a fill that snapped on read as a different kind of answer from every button's. At 150ms a sweep still lights one row at a time, and it is a fade all the same.
  • 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.

#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. Whatever travels as it arrives travels as layout, a margin or an offset moving a box whose words are already where they will land. A press is a fill, never a scale, and a ripple is a fill spreading: a painted gradient under the label, never a layer over it. 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, the small scale of a page crossfade, and, on a touch screen, which draws its text in grayscale and has no subpixel antialiasing to lose, a dialog's rise and a view or a dialog following the finger that moves it.

The Page Changes First Rule. A page change never waits for the server. The rail, the address and the crossfade all move on the click, and the page draws at once: from the copy of that page the server gave last time, when this tab has written nothing and nobody else in the workspace has changed anything since, and otherwise from the page's skeleton. The answer replaces a copy only when it says something different, and never after a write made while the copy was up, because the page's own state is then the newer of the two. A first load of an address is still rendered whole on the server; a skeleton is never sent as a document.

The Waiting Line Rule. While a page is waiting on an answer, a two pixel line in the accent runs across the top of the window, where the consoles of the large cloud platforms draw theirs. It covers the two moments the rule above left looking finished: a page drawn from its kept copy while the real answer is out, and a page holding its old contents while a board or a filter loads. It waits 200ms before it shows, so an answer that is quick draws nothing, and it leaves without waiting. A standalone spinner is held back the same way; a button's own spinner is not, because it answers a press. Under reduced motion the moving band is dropped and the still track remains.

The Arriving Row Rule. A row that joins a list after the list drew arrives under the veil, and its neighbors close up or make room at the reorder duration: comments, checklist lines, attachments, passkeys, tags and the members list follow the reminders list here. Content that replaces a skeleton inside a card is unveiled rather than cut.

The Skeleton Is the Page Rule. A page waiting for its data is drawn from its own pieces: the real PageHeader with its real title and the line under it, which never wait on anything, the real PageBody at the page's width, real rows, cards and panes, and bones only where the data decides. PageSkeleton has one shape per page, and a new page gets its own rather than borrowing the nearest. A line of words that has not arrived is a SkeletonText in the words' own role, so it is as tall as they will be. A skeleton that guessed at the page's sizes was a few pixels wrong everywhere, and the whole page stepped when it landed: the calendar waited as a month and opened on a week, and every header drew a button and a tab strip whether its page had them or not.

The Gathered Selection Rule. Several picked cards dragged as one are seen to become one and to come apart again. As the drag begins a copy of each traveler flies to the card in the hand, moved as layout like every carried copy, fading over the last of the trip, while the card in the hand grows the edges of one or two cards beneath it and wears their count. Where it is let go they come out from under it, one a beat after another, to the places they landed; let go over nothing, they come out from under it where it started and go home. Both take the reorder duration, so they finish with the gap the drag is closing, and both are nothing at all when motion is off.

The Fading State Rule. Whatever changes its ink, fill, edge, underline or opacity with its state (hover, focus, press, picked, aria-*, data-*, or a class swapped in a script) fades between the two on app-transition, or a row's app-row, or a motion-* utility: never a raw transition, a duration-150 or ease-linear, because the tempo and the curve are tokens. app-transition carries color, fill, edge, text-decoration-color, SVG fill and stroke, shadow and opacity, and no layout. A link's underline is always drawn and fades from transparent to its ink (the Fading Underline), because an underline switched on cannot be animated. A strike through finished words is the same argument drawn: it runs through them from the first letter to the last a beat after the box is ticked, as a pen would, and is taken back from the end when the box is cleared, one pixel of the words' own ink lying under them rather than a decoration switched on over them (the Drawn Strike). A glyph that changes (copy to check, open to shut) is two glyphs crossfading, never one swapped between frames. Words keep the Crisp Text Rule: a label's ink fades, the label itself never does.

The Earned Moment Rule. One moment is celebrated, and it is a thing finished whole: the last line of a list ticked. The box that finished it throws a short burst of confetti, paper in the workspace's own palette that leaves in a cone, slows in the air, turns over as it falls and is gone inside two seconds, over everything and in the way of nothing, so the next list can be ticked while it falls; the success phrase plays with it, as the one sound for the act. Every line before the last is the box's own check and the drawn strike, and nothing more, because a list of ten that threw confetti ten times would have spent it by the third. Under reduced motion there is no confetti at all, since it is traveling motion, and the phrase still plays. A moment that wants the same treatment is weighed against this one: something finished, whole, by the reader's own hand. Two others have passed: the last line of a card's checklist ticked, which is the same act on a smaller list, and the last card still to be done moved into a done column, which finishes the board the way the last line finishes a list. A card moved into Done with others still to do is only put down. The paper falls over an open dialog, since a card's list is ticked inside one.

The Traveling Plate Rule. The current destination in the rail, and the current tab in the list beside Settings, is marked by one plate that travels to it, the way a segmented control's plate does, rather than by one row going dark and another lighting up somewhere else with nothing between them. The phone's bar has no plate: its current tab is tinted whole in the accent's soft fill, with no pill behind the glyph, and the glyph of the tab chosen gives under the thumb and springs back. A row standing on the plate paints no fill of its own once the plate is there; before the page is running, it marks itself. A tap on the bar's tab that is already current takes the page back to its top.

The Turned View Rule. A view that steps through time (the calendar's month, its day and its list) is turned by a finger drawn sideways across it, as the arrows in its header turn it: toward the left for the next, toward the right for the one before. It follows the finger at half its pace and never far, so the hand feels it give; past the line, or flung, it goes on out the way it was pushed and the next comes in from the other side, with a tap heard and felt as it turns; short of it, it springs back. Only a stroke that is plainly sideways, so the page still scrolls, a hold is still a carry, and a stroke at the very edge of the screen is still the system's back gesture. The week is never turned this way, at any width: on a phone its days scroll sideways, and that stroke is kept for the scroll. Under reduced motion nothing follows or slides, and the stroke still turns it.

The Pulled Sheet Rule. On a phone, where a dialog is the whole screen, its header can be taken and pulled down. The panel follows the finger, showing the dimmed page it covered; let go far enough, or flung, it closes from wherever it was dropped, fading where it is as every exit does, and short of that it springs back into place. The header's own controls are still pressed rather than pulled, and the body still scrolls.

The Theme From the Hand Rule. A change of theme spreads from where it was chosen: a circle of the new theme grows from under the press, or from the focused control, until it has reached the furthest corner, over the old theme held still. What the circle uncovers is the new theme finished, with no color fading inside it. Under reduced motion, or where the browser cannot hold the old window still, it changes at once.

The Rolling Count Rule. A count that changes in front of the reader turns over like the wheel of a meter: going up, the new figure rolls in from below and the old one off the top; going down, the other way. The figures travel as layout inside the count's own box, a pill's round one included, so they stay crisp. A count drawn with the page is simply there.

The Thrown Capture Rule. A capture whose destination is out of sight is seen to go there. A reminder captured on the overview or on a board lifts out of the box as a slip of ruled paper, arcs across the window to Reminders in the navigation, and the glyph there swells and settles as it catches it. A card is never thrown, since it opens, or appears on the board, where the reader is already looking. Nothing is thrown under reduced motion or to a destination that is not on screen.

The Knocked Object Rule. A few objects answer on the spring. The mark tips a few degrees off kilter under a hand and rocks back upright when it leaves. The bell swings from its crown when something new arrives in a tab in view. A switch's knob runs a pixel past its stop and settles. A box ticked by the reader sends a ring out from its edge. A tab chosen on the phone's bar gives under the thumb and springs back. Each is a glyph or a shape with no words on it, and none of them plays for a state that was already there when the page drew: a list of finished things does not ring as it loads, and the bell does not swing for what was waiting at sign in.

The Felt Touch Rule. On a phone that can vibrate, what is heard is also felt, and only that: a few milliseconds of the motor for a latch, a lift, a landing or a send, a short pattern in the rhythm of a phrase, and nothing for a notification, which the phone already buzzes for. It has its own switch beside Interface Sounds, because a phone on silent is where a sound is unwanted and a buzz is not, and the switch is shown only where there is a motor to drive.

#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.

  • Scale: every step moves together (the Proportional Control Rule below), all in rem, so the row grows with the fluid root and the text size setting:

    Size Height Side padding Gap Type Glyph Icon button glyph
    sm 32 10 6 12 (text-xs) 12 14
    md 36 12 8 14 (text-sm) 14 16
    lg 44 16 10 16 (text-base) 16 20

    Weight is medium at every size. A choice chip is a button's size step for step, a field and a segment share the height and the type, and a segment shares the side padding.

  • 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, an underline that fades in on hover) and Bare (no chrome, inherits color) for a title that is the row's hit target. Fineprint is the link in an agreement line: the sentence's own ink with a hairline underline at rest, the accent under the pointer. The underline stays, because a link that looks like the words around it is notice a court can refuse.

  • Press: a labeled button answers a mouse or a pen with Material's ripple: ten percent of its ink spreading from the point the press landed to the far corner in 450ms, inside its own edges, held while the press is and fading once it is over and has lasted 225ms, so a quick click sees all of it. A finger gets the flat wash instead, the whole control at once: a ripple starts as a dot, and on a control with no resting edge that dot is all a thumb could see of it, so every tap read as the control shrinking and growing back. A key press, a control too small for a ripple to be read in (a checkbox, a switch) and every control with motion off answer with a flat wash of eight percent instead, and nothing moves either way. 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 switch past its 20, a checkbox past its 16, each by exactly what it falls short. Every control means every control, and the ones that are not shaped like buttons are the ones it is easiest to forget: the switch on a settings row, the logo that goes home, and the heading that is also a control, which takes the inline size to go without a plate and is not thereby a word in a sentence. An inline button standing alone on its line (the hours folded out of a day, a strip's one action, a badge that opens a menu) reaches the same way. A row in a list of destinations touches its neighbors and cannot reach past them, so under a coarse pointer it stands the full 44 instead. A segment is the one that cannot grow its own target, because the box it sits in scrolls sideways and a box that scrolls one way clips the other: the scroller makes the room instead, invisibly, so the track stays exactly as tall as it is on a desk and the plate keeps its three-pixel gutter on every side. A row in a menu or a select's list is the other: its neighbors touch it, so it cannot reach past its own box, and it stands a medium button tall (36) under a thumb instead. At the full 44 a menu of small words was mostly empty band, and a thumb that misses one row lands on the next rather than on nothing.

  • Loading: a button waiting on its answer never changes size. One with a glyph trades the glyph for a spinner; one without keeps its label in place, in no ink, and draws the spinner over the middle of it, so Save does not widen and push Cancel along a footer.

  • Focus: the one focus treatment, everywhere: a two-pixel Signal Blue outline, offset two pixels, only on keyboard focus. One exception, and it is the app's own decision rather than the browser's: on a desk, a dialog's Close button wears the ring the moment the dialog opens, whatever opened it, and lets it go on the first blur or press. On a touch screen it does not: the dialog itself takes focus, with no ring.

#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.

#Segmented Controls

  • Every segment is one width, the widest label's, so the plate travels between them without growing or shrinking: a choice reads as a move, not as the control changing size. Stretched across a phone they share the row equally, and a track too narrow for them scrolls rather than wraps.

#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 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 dialog, unfolding as it arrives. A note shows their faces in its header instead (AlsoViewing), named on hover and to a screen reader: a note is typed in continuously, and a callout above it pushed the text down under the writer's caret. 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%.
  • Search: a slower search still running turns the glass in front of the field into a spinner, in the room the glass had. Nothing appears under the field, which would push the list beneath it down on every search.
  • 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 (44 under a finger), control radius, icon then label, label hidden when the rail collapses to 56px, which it does below 1280 pixels: a tablet on its side, a small laptop and a window sharing a monitor all want that width for the page. 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. A page that is part of another has no row of its own: the planner is the calendar's, opened from the calendar's header, and the Calendar row stays current while it is open; the palette still jumps to it by name. People is left off where there is nobody else to show: a personal workspace, or any workspace of one.
  • Bottom bar (phone): the same items stacked, icon over a tiny label, 52px tall plus the safe-area inset, the current one on a pill behind its glyph. The five primary destinations only; every other page on the rail but Settings (which is in the account menu) is listed first in the top bar's More menu, from the same navigation model.
  • 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. Three parts: the two ends share the bar equally and the palette's door holds its width between them, so it stays at the middle of the bar when a face or the offline notice joins the far end. 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.
  • Shortcut hints (Ctrl K on the palette's door, Ctrl+Enter under a form) are printed only on a desk, the desk: variant: a pointer that hovers and aims finely. Never by width, because a tablet is as wide as a laptop and has no Ctrl key, and a narrow window on a desk still has one.
  • 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 as they travel ten pixels away from their control, 350ms on the enter curve, and fade out where they are in 200ms on the exit curve. Overlay shadow, container radius.
  • Dialogs fade in as they rise sixteen pixels into place over 450ms on the enter curve, while the backdrop dims over the same 450ms 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 rises the same way, and is pulled down by its header to close (the Pulled Sheet Rule). On a desk a dialog opens with focus on its Close button, ring on and tooltip shown, so the way out is the first thing seen. On a touch screen (pointer: coarse) it opens with focus on the dialog itself and nothing on the X: a ring and a "Close" label there read as the button already pressed, and a phone's X is where every phone app keeps it. A dialog with a field that asks for focus itself (autofocus) opens on the field instead, on either, because typing is what the reader came to do.
  • Tooltips are the app's own, never the browser's: overlay shadow, detail strong type, a 250ms fade with four pixels of travel, shown on hover after 400ms and on keyboard focus at once.
  • Toasts rise sixteen pixels from the bottom edge as they fade in, the way Azure DevOps and Material bring theirs up, and fade out where they are. They sit over an open dialog and answer a press there: one raised from inside Card Details is read and used where it was raised, not under the backdrop. The same holds over the upright notice, and over a menu, a list or the command palette opened while a toast is up. Only a tooltip is drawn above one, and the paper that passes over for a moment (a celebration's, a thrown capture's), which a press goes straight through.

#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 keyboard reaching one shows the row's set; a click leaves nothing up once the pointer has gone, since a click leaves no ring either, and a menu button stays for as long as its menu is open.
  • 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.
  • A table wider than its frame scrolls inside the frame, and fades its far edge while more of it is off to that side, as a segmented control's track does, so the cut says there is more rather than looking like the end.

#Named Rules

The Proportional Control Rule. A labeled control's height, side padding, gap, type and glyph step with its size, together, from one table: the glyph beside a label is the label's own type size, and an icon button's glyph is the same share of its box at every size. A call site never writes a text-*, font-*, h-*, px-* or gap-* onto a sized Button, IconButton or ChoiceChip; it picks a size. The gap lives on the size rather than the shell, because two gaps on one element let the stylesheet choose, and it chose gap-2 over every gap-1.5 written.

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.5rem 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 Rounded Fill Rule. A fill that arrives on hover or on press is an object, not a band: it has the control radius at its corners, and it fades in and fades out on a duration token, never snapping. A row in a panel and an item in a menu are inset one unit from the panel's sides so the rounded fill sits inside the edge rather than on it; the words stay where they were, because the unit taken from the sides is given back as padding. The exceptions are a table, whose rows are cells sharing their edges, so a table row fades and stays square, and the notes list, whose rows run the list's full width like the pages of a stack: a picked note is a square band from edge to edge, the open note's hairline is square beside it, and a run of picked notes is one band with the list's hairlines between them. The same fill, the same corners and the same tempo on every surface is what lets a person stop noticing hover at all, which is the point of it. A picked row and the open row's hairline follow the same corners in every state, and a run of picked rows squares only the corners two of them share, fading the change with the fill so the selection never changes shape after it has changed color.

The Flat Divider Rule. A line drawn to separate one row from the next is its own flat layer, never a border on a box that also carries the control radius: a border follows its own box's corners, so a border-b on a rounded row curls upward at both ends instead of running straight to them. ListRow's divided rule draws it this way, behind the row rather than as one of its sides, and that is the one place a divider between rows is built (the Recipe Rule); nothing hand-rolls one beside it.

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, a todo list's sheet, a line on a todo list. 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 or a list 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, the column or the line. Everything a drag can do is also in the thing's own menu, for a keyboard and for a thumb that would rather not drag.

A press that has lasted long enough to mean it says so, before the thing has gone anywhere: a card or a chip held under a hand takes the picked treatment, and a sticky note takes the raised shadow it wears while it is carried, which is what paper does instead. Half the wait a finger's carry needs, so on a touch screen there is a moment of "I have this" between the finger landing and the thing leaving. It is feedback and not a selection: nothing is added to what is picked, and letting go puts it back exactly as it was found.

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 (notes, a conversation's history, a board's archive) 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. A list that is one card among others stacked on a page (the reminders' groups; on Settings, the account's Devices and Recent Activity, and the workspace's Members, Invitations and Tags) pages by eight instead: a reveal there grew the card as long as the account's history and carried every card under it down with it, which is the wrong answer on a page somebody scrolls to reach the next card. Eight is the number for a list that could get long, not a cap dressed up as a feature: 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 selection treatment answers to one word rather than one state: a surface is picked out of a list, or picked up under a hand, and both are this surface being the one in question. What it never means is two different things at once, which is why a hold puts it back on release rather than leaving a selection behind it.

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 350ms, leave at 200ms, change in place at 250ms, and fall to one millisecond under reduced motion.
  • Do arrive by opacity, with a few pixels of travel from what opened the surface: a surface with its own fill fades and travels as layout, and words on a surface that is already there are unveiled.
  • Do answer a labeled control's press with a fill: a ripple from a mouse or a pen, a flat wash from a finger or a key. 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 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 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.