One system, every surface.
Tokens, type, space, elevation and motion — the layer every ai.com surface consumes. Marketing, product, docs, desktop and mobile, in light and dark, from one source.
The ai.com design system, extracted from the brand's two canonical artifacts — landing.html (v4 "quiet sky") and strategy-deck.html (identity slides) — and extended to cover the whole platform: product UI, marketing, docs, desktop and mobile, in light and dark.
This page is its own proof. Everything on it is built from the semantic tokens defined below — flip the theme toggle in the sidebar and the entire system re-renders. Components marked Canonical come directly from the source files; components marked Extended are new, derived strictly from the system's rules to cover product needs the marketing pages never had (forms, toasts, navigation shells, mobile).
night-muted standardized to #9DA1B2 (landing used #A7A9BC), danger on dark standardized to #FF7A87 (landing used #FF8A96), and glass opacity standardized to 0.72 (landing hero 0.55, deck 0.75). The mint "verified" green existed only as raw rgba values in landing.html — it is now a first-class token.Principles.
Quiet Sky in five rules. Everything else in this document is these rules applied at smaller scales.
| # | Principle | What it means in practice |
|---|---|---|
| 1 | One color carries the brand | A single cyan accent with three readings — #0FA8CE as the color, #0B86A6 for small text and pressed states on light, #5FD4F2 lifted for the night. No gradients, anywhere. No second hue. |
| 2 | The accent means something | Cyan appears only where it carries meaning: live dots, the agent's word, active states, checkpoints. Never in body text, never as decoration. Danger red appears only on Deny and Stop. |
| 3 | Near-black night, soft glow | Dark surfaces are near-black (#0A0D12) with a faint cyan horizon and at most one slow aurora band. Texture you feel, not atmosphere that shouts. No violet, no neon-on-black. |
| 4 | The dot is the material | The dot in ai·com is the brand's particle: live pips, agent avatars, status dots, the page-scale dot lattice. Its glow (0 0 10px accent) marks anything alive right now. |
| 5 | Trust is visible, not badged | Every safety claim is a component you can watch: the checkpoint card, the verified-done strip, the Stop pill. No seals, no badge walls, no trust theater. |
Always
- Ink pills for primary actions on light; white pills on dark.
- Soft geometry: pills at 99px, cards at 16–20px. No sharp corners.
- Onest for everything — including numbers. Nothing is ever monospaced in product or marketing UI.
- Layered, soft shadows; glass panels with gentle backdrop blur on dark.
Never
- No gradients — anywhere. One color carries the brand.
- No violet, no purple skies. Dusk-toned darks read entertainment, not work.
- No neon-on-black. Dark zones glow softly; they never buzz.
- No badge walls, seals, or trust theater. No accent color in body text.
Both lists verbatim from strategy-deck.html slide 11. Canonical
A near-black night, one cyan accent.
Two palettes — day and night — that were born as the landing page's light and dark zones, formalized here as the platform's light and dark themes. Components never touch primitives; they consume the semantic layer, which is what makes theming a variable swap.
Primitives Canonical
The raw brand values. The first eight are the deck's own swatch row; the rest appear throughout landing.html and are codified here.
Mint is the "verified / live" green — it appears only on evidence of completed, verified work (done strips, live chips). It is never a general success color for UI chrome. Night 2 and Night 3 are the product dark-mode surface steps, derived from the landing's glass base rgb(13,17,23). Extended
Semantic tokens Extended
What components actually use. One name, two values — the theme decides which. This table is the heart of the system; the full copy-paste CSS lives in Tokens & implementation.
| Token | Light | Dark | Use for |
|---|---|---|---|
| --bg | Canvas #FBFBFD | Night #0A0D12 | The page. Nothing else sits below it. |
| --surface-1 | #FFFFFF | #0D1117 | Cards, frames, panels — anything raised off the page |
| --surface-2 | #F7F7FA | #12161F | Nested wells inside cards: mocks, code wells, input strips |
| --surface-3 | #FDFDFE | #0F131B | Barely-raised rows, table headers |
| --text-1 | Ink #0E0E14 | Night ink #EDEEF4 | Headings, primary copy, values |
| --text-2 | Muted #5B5B66 | Night muted #9DA1B2 | Body copy, descriptions |
| --text-3 | Faint #8A8A94 | Night faint #7E8095 | Metadata, timestamps, decorative labels only |
| --border | ink @ 8% | night-ink @ 9% | Hairlines, dividers, card edges |
| --border-strong | ink @ 14% | night-ink @ 18% | Ghost buttons, inputs, interactive edges |
| --fill | ink @ 4.5% | night-ink @ 5% | Chips, hovers, quiet fills |
| --accent | #0FA8CE | #5FD4F2 | Live dots, active states, meters, focus rings |
| --accent-text | #0B86A6 | #5FD4F2 | Small/bold accent text — eyebrows, checkmarks, working labels |
| --accent-tint / --accent-border | accent @ 8% / 30% | accent-night @ 10% / 30% | Checkpoint cards, agent-tinted fills, selected states |
| --danger | #C24558 | #FF7A87 | Deny and Stop. Nothing else. |
| --ok / --ok-text | #2BD9A9 / #14795C | #2BD9A9 / #8FE0C4 | Verified done, live-now chips |
| --btn-primary-bg / -fg | Ink / white | Night ink / night | The primary pill — ink on light, white on dark, by brand rule |
| --bubble-agent | #F4F4F8 | night-ink @ 7% | Agent message bubbles |
| --glass | white @ 78% | rgb(13,17,23) @ 72% | Floating nav, overlay panels — always with backdrop blur 8–14px |
Rules of light Canonical
How color behaves
- One accent, three readings — the theme picks the reading; components just say
--accent. - Primary buttons are ink pills in light, white pills on dark. The accent is never a button fill.
- Text never renders in raw accent on light — small accent text uses
--accent-text(#0B86A6), which exists precisely for contrast. - Tints (8–10%) carry meaning-fills: checkpoints, agent bubbles, selection. Fills (
--fill) are meaning-free.
Color anti-patterns
- Accent as decoration, in body text, or as a background for large areas.
- Danger anywhere except Deny / Stop / destructive confirmation.
- Mint as a general success color — it marks verified outcomes only.
- New hues. If a state needs a color, it maps to accent, danger, mint, or neutrals.
One family, soft geometry.
Onest is the only typeface, everywhere — display to caption, marketing to product, including every number. Nothing in the brand is ever monospaced (code samples in internal docs are the sole exception).
| Style | Size | Weight | Tracking | Line height | Notes |
|---|---|---|---|---|---|
| Display | 64px · clamp(46, 7vw, 80) hero | 700–800 | −0.035 to −0.04em | 1.02 | Marketing heroes, deck titles. Never inside product chrome. |
| Title 1 | 36–44px · clamp(30, 3.8vw, 40) | 600–700 | −0.025em | 1.08–1.12 | Section / page titles |
| Title 2 | 18–22px | 700 | −0.02em | 1.2 | Card and feature headings |
| Title 3 | 14.5–16px | 600–700 | −0.015em | 1.3 | Row titles, list headings |
| Body lg | 16–17px | 400–500 | 0 | 1.6–1.65 | Marketing body, ledes |
| Body / UI | 13.5–14px | 400–500 | 0 | 1.5–1.55 | Product default: bubbles, descriptions |
| Small | 12.5–13px | 400–600 | 0 | 1.45–1.5 | Secondary rows, steps, provenance |
| Caption | 12px | 400–500 | 0 | 1.4 | Timestamps, footnotes — --text-3 |
| Eyebrow | 12px | 700 | +0.1em, uppercase | 1 | Section markers — --accent-text or --text-3 |
| Micro label | 10–11px | 700–800 | +0.06–0.09em, uppercase | 1 | Chips, tags, panel titles. Decorative — never the only carrier of meaning. |
Numbers and stats are set in Onest 600. Emphasis inside body copy is weight 600 in --text-1 — not italic, not accent color. On mobile, body/UI never drops below 13px and captions never below 11px.
A 4px rhythm and soft geometry.
Spacing steps on a 4px base. Radii come in six named stops — pills for anything interactive and small, soft rectangles for containers.
Spacing scale Extended
Usage anchors from the sources: gaps between cards 12–18 · card padding 24–28 · frame padding 18–20 · section padding 96 desktop / 80 tablet / 64 mobile · marketing container padding-inline 28.
Radius Canonical
Pills for buttons, chips, and floating nav. Frames (chat windows, hero scenes) at 20–24. Cards at 16. Nested cards and callouts at 12–14. Controls (inputs) at 12. Tiny nested elements at 8. Message bubbles: 14 with a 4px "speaker corner" pointing at the sender. No sharp corners, anywhere.
Layout & breakpoints Extended
| Context | Spec | Source |
|---|---|---|
| Marketing container | max-width 1160 · padding-inline 28 | landing.html |
| Deck / doc content | max-width 1000–1060 | strategy-deck, product-spec |
| App shell (desktop) | rail 250–260 · main flexible (content max 980) · right panel 320 collapsible | product-spec app map |
| Breakpoints | 1024 tablet (rail collapses, grids halve) · 640 mobile (single column, bottom nav) | standardized — deck's 1000/560 folds into these |
| Grid gaps | 18 between cards on desktop, 12–14 on mobile | landing bento / team grids |
| Touch targets | ≥ 44 × 44 px on mobile; inputs grow to 44px height | extended |
Soft light, glass, and the night sky.
Depth comes from layered shadows and surface steps, not borders alone. Dark zones add glass and — in marketing only — the aurora.
| Level | Token / recipe | Use |
|---|---|---|
| Flat | --bg, no shadow | The page itself |
| Raised | --surface-1 + --shadow-soft + --border | Cards, panels, rows |
| Floating | --surface-1 + --shadow-card | Frames, modals, popovers, hero scenes |
| Glass | --glass + backdrop-blur 8–14px + --border-strong | Floating nav, overlay chrome, dark-zone cards |
| Hover lift | translateY(-4px) + shadow-soft → shadow-card, 250ms | Interactive cards only — never rows or list items |
The dusk treatment Canonical
Marketing dark zones (hero, finale, deck title slides) sit on the night with a faint cyan horizon rising from the bottom edge and one aurora band drifting on a 22–30s loop, blurred 70px. Optional film grain at 4% opacity. Product dark mode uses none of this — it is flat night surfaces; the glow belongs to the brand's front door, not to work.
The dusk recipe: radial cyan horizon at 14% from the bottom · linear cyan wash at 4.5% from the top · one aurora band, blur 70px, drifting 22s alternate. This band is the entire permitted atmosphere.
Calm, physical, brief.
One easing curve everywhere. Transform and opacity only — nothing animates layout. Ambient motion exists solely in marketing dark zones.
| Token | Value | Use |
|---|---|---|
| --ease | cubic-bezier(0.22, 1, 0.36, 1) | Every transition and entrance. The only curve. |
| --t-fast · 200ms | buttons, toggles, links, color shifts | Micro-interactions |
| --t-base · 250ms | card hover lift, chips | Component state |
| --t-slow · 300ms | nav, theme flip, panel slide | Chrome |
| --t-reveal · 500ms | fade + translateY(14–16px), stagger 90ms | Scroll-in reveals, first paint |
The named motions Canonical
pip-pulse marks anything live. bar-run (1.8s) is the agent working. spin is a short determinate wait. Ambient loops — orbit float 7s, aurora 22–30s, marquee 36s — are marketing-only. Every animation dies under prefers-reduced-motion; reveals render visible, spinners become static.
The library.
Every component in both themes — the global toggle flips this whole page; the paired panels below pin one theme each so you can compare side by side. All of it consumes semantic tokens only.
Buttons Canonical
Primary is an ink pill on light and a white pill on dark — by rule, not preference. Ghost carries secondary actions; quiet is for tertiary; deny is text-only danger. Sizes: lg 15/13×26 (marketing CTAs), md 13/8×15 (product default), sm 12/6×12 (dense rows).
Chips, labels & badges Canonical
Chips are quiet fills for neutral facts. Labels are micro-type pills that classify — solid for the highest rank, accent-tinted for meaningful states, outlined neutral for the rest. The glass badge carries a live pip in heroes and headers.
The dot & avatars Canonical
People are photographs; agents are the dot. The agent avatar is a solid accent circle with a pulsing halo ring — one glance separates human from agent in any thread. Pips come in 6 / 7 / 8px; a glowing pip means live right now.
Sizes: 40 (headers, member rows) · 26 (threads) · 20 (dense mocks). The pulse ring animates at 2.6s. In shared Rooms every agent message carries both the dot avatar and its owner's name — "mika · Maya's agent" — attribution is structural, not stylistic.
Messages & threads Canonical
The fused human + agent timeline. User bubbles are primary-colored pills with the speaker corner bottom-right; agent bubbles are quiet fills, corner top-left. Steps render inside agent bubbles with cyan checks. A working line always carries Stop.
The checkpoint card Canonical
The product's core interaction, identical anatomy everywhere: state line ("Needs you…"), the concrete action, provenance, and the three verbs. Accent tint + accent border — the only card that ships with meaning built into its fill. Deny is always text-only, always last.
Verified done Canonical
The only place mint appears: work confirmed by the independent verifier, with evidence. The check circle is mint, the claim is text-1, evidence is expandable.
6 emails in Sent match approved drafts · recipients match contact list · no bounces after 15 min
Panels, rows & toggles Canonical
The panel is the product's list container: micro-label title, hairline-divided rows, metadata right-aligned in text-3. The toggle is 38×21 with the accent as its on-state.
Forms Extended
The marketing pages have no inputs, so these are derived: surface-1 fields, 12px radius, strong border idle, accent border + 3px tint ring on focus. Labels 12.5/600; errors in danger with a plain sentence. 42px tall on desktop, 44px on mobile.
Tables Canonical
Micro-label headers on surface-3, hairline rows, key column bold in text-1, everything else text-2. Wide tables scroll inside their container — the page never scrolls horizontally.
Progress & meters Canonical
Meters are 7px pills — accent fill for budgets and usage, switching to danger only past a warning threshold. The indeterminate working bar belongs to the agent alone.
Toasts & empty states Extended
Toasts are floating frames with an intent pip — accent for information, mint only for verified outcomes, danger for failures. They enter with the reveal motion, bottom-right on desktop, above the tab bar on mobile. Empty states are one sentence plus one action — designed, never defaulted.
The same system at thumb scale.
Below 640px the rail becomes a five-slot tab bar, checkpoints become bottom sheets, and everything interactive grows to a 44px target. Nothing changes visual language.
single column · cards full-width
section padding 64 → 20 inline
| Rule | Spec |
|---|---|
| Tab bar | 5 slots max · 56px + safe-area inset · labels 10px/600 · active = accent-text + tint. Approvals keeps its count badge. |
| Checkpoint sheet | Bottom sheet, radius 20 20 0 0, grabber 36×4. Verbs stack full-width if they don't fit in a row. Deny never collapses into a menu. |
| Touch | ≥44×44 targets · inputs 44px tall · row tap-areas full-bleed |
| Type | Body/UI floors at 13px, captions at 11px. Display scales via the clamp() ramps — no separate mobile scale. |
| Threads | Bubbles widen to 88% max-width · avatars drop to 20px · working line + Stop always visible, never behind a swipe |
| Grids | 4-col → 2-col at 1024 → 1-col at 640 (landing's own collapse pattern). Card gaps 18 → 12. |
| Motion | Ambient marketing loops (orbit float, marquee) switch off below 1024 — the landing already does this; keep it platform law. |
Contrast, focus, motion.
The palette's roles encode its contrast math. Approximate ratios below — re-verify when any value changes.
| Pair | ≈ Ratio | Verdict |
|---|---|---|
| Ink on Canvas | 18 : 1 | AAA everywhere |
| Muted on Canvas | 6.5 : 1 | AA all sizes — the body-copy pair |
| Faint on Canvas | 3.3 : 1 | Fails AA for small text — decorative metadata only, never the sole carrier of meaning |
| Accent deep on white | 4.2 : 1 | 700-weight labels and eyebrows only; body copy never renders in accent (brand rule) |
| Night ink on Night | 17 : 1 | AAA everywhere |
| Night muted on Night | 7 : 1 | AA all sizes |
| Accent night on Night | 11 : 1 | AA — why raw #0FA8CE (6.8:1, thin strokes) is lifted on dark |
Non-negotiables
- Focus is always visible: 2px
--focus-ringoutline, offset 2 — on every interactive element, both themes. - The three checkpoint verbs are keyboard-operable in DOM order: approve, review, deny. Pending checkpoints announce to assistive tech.
- Live pips and working bars pair with text ("working…") — color and motion never carry state alone.
prefers-reduced-motioncollapses every animation to ≤0.01ms; reveals render visible; ambient loops stop.- Both themes declare
color-schemeso native controls, scrollbars, and form widgets match.
Practices
- Icon-free design means labels do the work — keep them; never reduce a verb to a glyph.
- Agent avatars carry
aria-labelnaming the owner ("Maya's agent"). - Hit areas ≥44px on touch; row taps cover the full row, not just the title.
- Skip-link pattern from landing.html (sr-only, surfaces on focus) ships in every shell.
Tokens, ready to ship.
Drop this in as tokens.css. Theming API: set data-theme="light|dark" on <html>; omit it and honor prefers-color-scheme with the tiny bootstrap below. Scoped theming (a pinned-dark hero inside a light page) is the same variables on a .theme-dark wrapper.
| Convention | Rule |
|---|---|
| Components use semantic only | A component referencing a primitive (--cyan, --ink) is a review flag — it will break in the other theme. The two sanctioned exceptions: the toggle's on-state and meter fills may use --cyan when they must read identically on both themes. |
| Naming | --{concept}-{variant}: surfaces and text are numbered by prominence (1 = strongest). Component tokens (--btn-primary-bg) exist only where a semantic pair genuinely flips between themes. |
| Breakpoints | 1024 and 640, hard-coded in media queries (CSS vars don't reach them) — keep them in a comment block at the top of every stylesheet. |
| Adding a token | New tokens need: both theme values, a row in the semantic table, and a component that uses it. No speculative tokens. |
| Dark ≠ dusk | Product dark mode is flat night surfaces. The aurora, grain, and glow recipes are marketing-only and never ship inside the app shell. |
The remap.
Before a line of v2.0 was written, sixteen screenshots of the July 2026 product were audited and every visual violation catalogued — twenty-two of them. Each one became a rule with a binding replacement. This table is the migration checklist: when all rows are cleared, the product is on Quiet Sky.
| # | Where seen | Current | Quiet Sky replacement |
|---|---|---|---|
| R1 | Priorities, Today's Brief, sparkles, selected day, "Discuss" links | Purple/violet as the "AI" color | Delete the violet family. Agent presence = the dot system: --accent pips, --accent-tint fills, --accent-text labels. Sparkle glyphs retired. |
| R2 | Skills & Apps hero | Pink→purple gradient headline | Title 1 in --text-1. Gradient text does not exist anywhere. |
| R3 | Calendar event | Green "Join call" fill | Primary pill. Live-ness = glowing pip + "Live" ds-label--ok, never a green button. |
| R4 | DM / Room timelines | Slack-style colored usernames | Names in --text-1 600. Identity = avatar + name, never name color. |
| R5 | Discover tab | Orange "Update available" chip | ds-label--accent. Orange is not a system color. |
| R6 | Priority advisory line | Orange warning text | --text-2 + neutral pip. Danger only for destructive/stop. Urgency is copy + placement, not paint. |
| R7 | Sidebar logo, user avatar | Crimson square mark | The ai·com wordmark — ink letters + accent dot. Human avatars become circles. |
| R8 | Communication Health | Gold/brown meter | ds-meter: accent fill, danger past the warn threshold only. |
| R9 | Wiki, dashboards, meeting links | Default blue hyperlinks | --accent-text, weight 500–600, underline on hover only. |
| R10 | Wiki paths, Vault secrets, metric chips | Monospace + red inline-code in chrome | Onest. Source refs become neutral chips. Monospace survives only inside authored code blocks in content. |
| R11 | "Today 9 PM" chip | Red/pink date chip | Neutral chip; accent + live pip only when it is happening now. Danger is never a time color. |
| R12 | Knowledge graph nodes + legend | Rainbow categorical palette | Concept = accent · Synthesis = ink · Source = hollow neutral · Service = mint. No new hues. |
| R13 | Agent avatars | Letter squares + "ai" badge, indistinguishable from humans | ds-ava--agent: solid accent circle with a pulsing halo. Attribution ("mika · Maya's agent") is structural. |
| R14 | My Apps / Marketplace cards | Dark thumbnails with purple gradient art | --surface-2 wells at --r-inner, centered glyph or live preview. No gradients, no dark islands on light. |
| R15 | Every CTA in the product | Four unrelated button systems — black pill, black rect, white rect, green fill | One system: ds-btn pills only — primary / ghost / quiet / deny, sizes lg·md·sm. The corner is always a pill. |
| R16 | Every tab row | Three competing tab patterns | Two, by rule: segmented ds-tabs for views of the same data; underline ds-tabs-line for sections/documents. Never mixed in one header row. |
| R17 | Priority card actions | Unlabeled icon-only actions in accent purple | Quiet icon buttons, --text-3 at rest, hover --text-1. Tooltip and aria-label, not either. |
| R18 | Notification popover, modals | Flat white sheets, mixed paddings, gray pill search | --surface-1 + --r-frame + --shadow-card, hairline header, ds-input search recipe. |
| R19 | Danger zone rows | Orange "Delete account" text | --danger row + danger icon; confirmation follows the checkpoint pattern. |
| R20 | The whole product | Light mode only | Every surface ships both themes from semantic tokens: data-theme on <html>, prefers-color-scheme default, per-user persistence. |
| R21 | Empty recaps ("No recap yet") | Italic gray placeholder | A designed empty state: one sentence + one action. Italics do not exist in the system. |
| R22 | Selected sidebar item | Floating white card + border | --accent-tint fill + --accent-text at --r-tight. Hover = --fill. No shadows in the rail. |
R15, in miniature Remapped
The highest-visibility row, and the clearest illustration of what a remap actually does. Four button systems existed because four screens each solved the same problem locally. One system means one decision — which priority is this? — and the shape follows from the answer.
Four radii, three fills, two type treatments, one meaning: "press me".
One shape. Priority is carried by fill, and liveness by the pip — never by hue on the button itself (R3).
Migration order
The order matters: it front-loads the visible wins and leaves the switch that looks hardest for last, when it has become trivial.
- Ship
tokens.cssand Onest; add the theme bootstrap. - Replace the four button systems with
ds-btn(R15) — the highest-visibility win. - Kill the violet family, gradient text and sparkles (R1, R2); land the dot and agent avatar (R13).
- Normalize tabs (R16), sidebar states (R22), links (R9), monospace (R10).
- Component by component, then page sign-off against the per-surface checklists.
- Enable dark mode last. If steps 1–5 used semantic tokens honestly, it is a switch, not a project.
Compliance is not a matter of opinion: migration/quiet-sky-audit.mjs counts violations by rule with zero dependencies, so every phase has a number that goes down. Rules tagged exact are driven to zero; heuristic rules flag for review and are never CI-gated.
One grid, one stroke, one filled shape.
106 drawings that have to sit beside each other in a 260px rail without any of them shouting. That only happens if they are constructed, not collected.
The family Extended
| Property | Value | Why |
|---|---|---|
| Grid | 24 × 24, 20 × 20 live area | 2px of air on every side, so an icon never collides with its neighbour's hit area |
| Stroke | 1.5px, round caps and joins | Optically matched to Onest at 13.5px body weight; Lucide-compatible |
| Corner radius | 2 | The smallest radius that still reads as intentional at 14px |
| Keylines | square 18 · circle 20 · portrait 16×20 · landscape 20×16 | Equal optical mass, not equal bounding boxes |
| The particle | Ø3, filled — the only filled element | It is the brand mark appearing inside the icon set; nothing else earns a fill |
| Sizes | 14 inline · 16 buttons and meta · 18 navigation · 20 headers | Four sizes, no interpolation |
Every glyph is measured after rendering: a script rasterizes the whole family and flags any drawing that misses its keyline by more than 1.8px. Craft you would never consciously notice — but you would feel a rail where one icon sits 2px heavy than its neighbours.
Colour roles
--text-3at rest in chrome — rails, headers, toolbars.--text-2in content rows, beside body text.--text-1on hover and when active.--accentonly when the icon is the state signal — the live pip, the selected item's mark.
Never
- Decorative colour. An icon is not a place to add a hue.
- Filled squares, emoji-as-icons in chrome, or a second stroke weight.
- The sparkle / wand / star glyph — retired platform-wide. The agent's mark is the dot, not a magic wand.
- An icon-only button without both an
aria-labeland a tooltip.
All 106, one grid
Rendered live from the shipped sprite, inlined at the top of this document — one request, one cache entry, consumed as <svg class="ic ic--18"><use href="#ic-{name}"/></svg>. Icons take currentColor, so this whole grid re-colours with the theme.
Logotype & the dot Canonical
Onest draws the tittle on the i and the period as the same circle. The logotype is built on exactly that rhyme: the dot above the i and the dot in ai·com are the identical particle, placed twice — and only one of them is lit. Every downstream asset — app icon, agent avatar, status pip, favicon — is that one particle at a different size.
| Construction | Value | Why |
|---|---|---|
| The particle | Ø172 units, on the y=264 spine | The same circle as the i's tittle, on the same optical line |
| Clearances | 175 left / 130 right — deliberately unequal | A curve falls away from its tangent point, so an equal gap would look wider against the c than against the i's flat stem |
| Tracking | −25 display · −18 UI | The UI cut is a real optical size, not the display file scaled |
| Clear space | One x-height on all four sides | Minimum, not target |
| Minimum size | 72px display · 48px UI · below 24px, the particle alone | Under 24px the letters stop being letters, and the dot is the mark anyway |
| Halo | Ring at 2.25× the particle radius | Marks "working right now" without a second colour |
The dashed box is the floor, not the target.
Display · UI cut · the particle alone, below 24px.
Never re-set the wordmark in live type. Typing ai.com in Onest gives you a period at the wrong size sitting on the baseline. The masters are outlined vector paths, so no font has to load and nothing reflows — the letterfit is fixed forever. That rhyme between the tittle and the dot is the mark, and typing it destroys it. Every wordmark on this page, including the one in the sidebar, is <use href="#logo-display"/>.
One scale, no raw numbers.
Ad-hoc z-index values are how a popover ends up under a sticky header. The scale is closed; components consume the token.
| Token | Value | What sits here |
|---|---|---|
| --z-base | 0 | Page content |
| --z-raised | 100 | Sticky page and table headers, the composer bar |
| --z-rail | 200 | Sidebar rail, right panel |
| --z-popover | 300 | Dropdowns, menus, pickers, notifications |
| --z-drawer | 400 | Mobile sheets, side drawers |
| --z-scrim | 500 | The modal backdrop |
| --z-modal | 600 | Modals, the command palette |
| --z-toast | 700 | Toasts — above modals, so a confirmation from a modal action stays visible |
| --z-tooltip | 800 | Tooltips — last, because they attach to whatever has focus |
Nothing in product code may use a raw z-index. A component that needs to sit between two steps is a signal the scale is wrong — and the scale gets fixed, not the component.
Focus & dismissal
- One scroll-lock owner. The innermost open layer locks
body, records the position and restores it on close. Nested overlays never double-lock. - Focus moves into the layer on open — first interactive element, or the heading for a long modal — and returns to the trigger on close.
- Modal-class layers trap focus. Popovers do not; they close on outside click,
Esc, or a scroll of the surface beneath.
Non-negotiable
Esccloses the topmost layer and nothing else.- A layer opened from the keyboard must be dismissible from the keyboard, without a pointer. No exceptions.
- No raw
z-index, and no "just this once" value between two steps.
Waiting is a designed state.
The product is asynchronous end to end — every surface can be waiting on a model, a tool call, or a person. So waiting is not an absence to be covered up; it has its own rules. What the user sees is chosen by how long the wait is expected to be, not by what is convenient to build.
The loading ladder Extended
| Expected wait | Show | Never |
|---|---|---|
| < 120ms | Nothing — render the result. | A flash of skeleton; it reads as a bug |
| 120ms – 1s | The destination's skeleton. | A spinner |
| 1s – 10s | Skeleton + a working line naming the task ("Reading 132 issues…"). | An indeterminate bar with no words |
| > 10s | Working line + Stop pill + ds-steps. | Blocking the whole surface |
| Streaming | Stream into place; the cursor is a ds-pip--live. | A percentage you cannot honour |
Two hard rules. A spinner never appears alone — if you cannot describe the work, you cannot ask someone to wait for it. And a skeleton never breathes for more than ten seconds; past that it has become a lie, and the surface must escalate to a working line with a Stop.
Skeletons Extended
Skeletons mirror the real layout — same line count, same widths (last line 60%), same avatar sizes — because the jump on load is the defect, not the skeleton. One opacity breath at 1.6s, rows staggered 60ms. No sweeping shimmer: the system has no gradients, and a diagonal sweep on near-black reads as a rendering artifact. Skeletons are aria-hidden; the region carries aria-busy="true" and the working line is the live region.
Optimistic — and the one thing that never is
| Action | Optimistic | On failure |
|---|---|---|
| Send a message | Bubble at 60% opacity, no timestamp | Gains a --danger hairline + "Retry" |
| Check a priority item | Checkbox fills, title strikes through | Reverts with a toast naming the reason |
| React | Chip appears in accent-tint | Chip removes itself; no toast — too small to interrupt for |
| Approve a checkpoint | Never. | — |
The exception is the rule that matters: approvals, denials and Stop are never optimistic. A checkpoint that looks approved before the server agrees is a trust failure — and trust is the thing this product sells.
Empty, loading, error — three states, three renderings
Empty
- One designed sentence in
--text-2+ one primary action, in a dashed--border-strongcontainer at--r-card. - Never italic, never bare (R21).
Loading
- The skeleton. Never the empty state's copy — "nothing here" and "not here yet" are different claims.
Error
- A plain sentence in
--danger: what happened, and the next step. Plus "Try again" asds-btn--ghost. - No codes, no stack traces, no apology.
No recap yet — your agent writes one after the first call of the day.
It is called Command Center. It behaves like one.
Every shortcut below is discoverable from ⌘/ and from the palette — a shortcut that exists only in the docs does not exist.
The command palette Extended
Modal-class layer at --z-modal, width 640, top-anchored at 14vh — not centred, because the list grows downward and centring makes it jump. Selection moves with ↑ ↓; hover sets selection too, so pointer and keyboard always agree. An empty query shows Recent and the five most-used commands, not everything. No results offers "Ask your agent instead" — the palette is a front door to the agent, not a dead end.
The keyboard map
| Key | Does | Where |
|---|---|---|
| ⌘K | Open the command palette | Everywhere |
| ⌘/ | Shortcuts sheet | Everywhere |
| ⌘. | Stop the agent | Anywhere an agent is working |
| Esc | Close the topmost layer, return focus | Everywhere |
| G then C W A K L | Go to Command Center · Workflows · Skills & Apps · Knowledge · Calendar | Everywhere |
| J K or ↑ ↓ | Move through the focused list | Lists, timelines, notifications |
| ⏎ | Open / expand the focused row | Lists |
| E / S | Hide / snooze the focused row | Priorities, awaiting reply |
| A R D | Approve · Review · Deny | The focused checkpoint |
| ⌘⏎ / ⇧⏎ | Send / newline | Composer |
| ⌘F | Search this surface | Rooms, Knowledge |
A shortcut never fires while a text field has focus except ⌘-combinations. Single-letter shortcuts require the list to hold focus, not the page.
Density Extended
Two densities, one set of components. Density changes space only — never type size, never radius, never stroke. Set with data-density="compact" on the app root. Compact is for tables, rooms and long lists on large screens; it is never the default on touch, where 44px is the floor.
| Comfortable (default) | Compact | |
|---|---|---|
| Row height | 44px | 36px |
| Section gap | 24px | 16px |
| Card padding | 16–18px | 12–14px |
| Table cell | 11px 18px | 7px 14px |
| Composer min-height | 44px | 36px |
Drag & reorder
Only two things reorder: priority items and workflow steps. Everything else sorts. The row lifts to --shadow-card at 0.98 scale and 92% opacity; a 2px accent line marks the drop position. No ghost image, no rotation. The keyboard equivalent is mandatory — Space picks up, ↑ ↓ move, Space drops, Esc cancels, all announced through a live region ("Moved to position 2 of 6"). Drop is optimistic; failure restores the original order with a toast.
What one colour does to a chart.
Quiet Sky has one accent and no gradients. That is not a limitation to work around — it decides the chart system.
The law
- Magnitude is one hue. The cyan ramp, light → dark. The default for every chart in the product.
- Identity is position and direct labels — not colour. Two or three series get ramp steps plus an end-label each.
- Beyond three series: small multiples, or fold the tail into "Other". Never a generated hue.
- Status colours are reserved. Mint and danger are state, never series 2, and always ship with an icon and a word.
Which means
- There is no diverging ramp — there is no second hue to build one from. Polarity is two stacked fills with a 2px gap, both labelled.
- There is no amber. Orange was deleted (R5, R6), so "warning" is copy and placement, not paint.
- There is no pie chart. Three or more parts are bars.
- Never a dual-axis chart. Two scales become two charts, or index to a common base.
Which form the data gets
| The data's job | Form |
|---|---|
| One headline number | Stat tile — no plot |
| Magnitude across categories | Horizontal bars, sorted by value |
| Change over time | Line, 2px |
| Part-to-whole, 2 parts | Single stacked bar with a 2px gap + both labels |
| Part-to-whole, 3+ parts | Bars, not a pie. The system has no pie chart. |
The ramps — validated, not chosen Extended
Both ramps pass the ordinal checks — monotone lightness, adjacent ΔL ≥ 0.06, light-end contrast ≥ 2:1 against that mode's own surface, single hue. Measured: the light ramp's lightest step #5FBFE0 reads 2.03:1 against --bg with a 3° hue spread across all five steps; the dark ramp's #057D95 reads 3.94:1 against #0D1117 at a 1° spread. The dark steps are selected, not inverted — derived against night and validated there, rather than computed from the light hexes. What does flip is the anchor: --chart-5 is always the largest value and always carries the most contrast against its surface — darkest on canvas, brightest on night. Get that backwards and "most" becomes the least visible mark on the chart. For two series use --chart-4 and --chart-2, not the ends, where one of the pair goes dim in one theme.
Charts
Bars capped at 24px thick with a 4px rounded data-end and a square baseline · lines 2px with an end-marker ringed 2px in the surface colour · hairline solid grid, never dashed · values at the tip and the line-end only, never on every point · a 2px surface gap between touching fills · text wears text tokens, never the data colour.
| Connector | Requests |
|---|---|
| Slack | 412 |
| Gmail | 338 |
| Calendar | 214 |
| Linear | 156 |
| Notion | 92 |
| Connector | Requests |
|---|---|
| Slack | 412 |
| Gmail | 338 |
| Calendar | 214 |
| Linear | 156 |
| Notion | 92 |
| Month | Handled by agent | Escalated |
|---|---|---|
| Aug | 18 | 12 |
| Nov | 34 | 19 |
| Feb | 52 | 24 |
| May | 70 | 32 |
| Jul | 88 | 44 |
| Month | Handled by agent | Escalated |
|---|---|---|
| Aug | 18 | 12 |
| Nov | 34 | 19 |
| Feb | 52 | 24 |
| May | 70 | 32 |
| Jul | 88 | 44 |
Every chart ships a hover layer and a table view behind a quiet toggle — the "View as table" buttons above are live. That is the accessibility contract, and it is also what people copy into a document. In print the table always wins: the chart drops and the numbers stay.
Stat tiles, meters, sparklines & stacks
A delta chip always carries an arrow and a number — never colour alone. Bars cap at 24px thick; the meter track is 7px; the sparkline is 2px at 28px tall with an 8px end-dot. Avatar stacks cap at four faces with a 2px surface ring each and an overflow +N chip — and an agent is never folded into the overflow. You must always be able to see that an agent is in the room.
Tables
Micro-label headers on --surface-3, hairline rows, sticky header at --z-raised with a hairline that appears only once scrolled. Sort: one column at a time, chevrons-up-down in --text-3 resolving to a single chevron in --accent-text when active; sort state lives in the URL. Selection: a 44px checkbox column, indeterminate in the header when partial, and a selection bar that replaces the toolbar. Prefer "Load more" over numbered pages for feeds — and never infinite scroll on a surface that has a footer. Numerals are Onest 600, tabular in columns and proportional in prose.
The same rule as the accent.
The sound identity is part of this system, not a side project — and like cyan, it only fires where it carries meaning. QuietSkySound.play(name).
| Sound | Fires when | Tier |
|---|---|---|
| signature | First launch of a session, and nowhere else | attention |
| send | You send a message | ambient |
| tap | A human message arrives in the room you are looking at | ambient |
| ping | A DM arrives | ambient |
| mention | You are mentioned | attention |
| checkpoint | The agent needs you | attention |
| done | A verified-done strip lands | attention |
| live | A call starts, or a workflow begins a run | ambient |
| callEnd | A call ends | ambient |
| stopped | You pressed Stop | attention |
| error | An action failed | attention |
Silent
- Never on hover, scroll, typing, focus change or navigation.
- Never for something you are already looking at — an arriving message in the focused room plays
tap; the same message while you are typing in it plays nothing. - Never two sounds inside 400ms. The later wins.
- Muted entirely during a call except
stoppedanderror.
Always
- Attention-tier is off until the user opts in; ambient respects the OS setting.
- A sound never carries information alone. Every sound accompanies a visible change — it is a second channel, never the only one.
The event map and the rules are ratified; the sounds themselves are not. A wide slate of candidates is being auditioned under the same test as the accent — it only fires where it carries meaning. Nothing final yet, which is why there is nothing to play on this page.
Paper is a ninth surface.
People print approvals, briefs and health tables, and a system that only exists on a screen fails at the moment someone takes it into a room.
Force the light theme — night surfaces waste ink and lose every hairline. Drop the rail, the mode switch and all hover-only chrome; they have nothing to say on paper. Cards lose their shadow and keep their hairline. Charts print their table view, not the plot: the numbers survive a photocopier and the marks do not. Every card and table carries break-inside: avoid. Page one gets the wordmark, the surface name and the date — a printout with no provenance is a rumour.
ai.com · Quiet Sky design system v2.0 · August 2026 · Internal · Foundations sources: landing.html (v4), strategy-deck.html (slides 11–12), product-spec.html. Application layer: app-design-system.md (Parts A–M) · migration/quiet-sky-audit.mjs · product screenshot audit, July 2026. Canonical = extracted verbatim; Extended = derived under the system's rules; Remapped = added because the audit found a violation. Terminology per the ratified glossary: Workflows (formerly Routines). Companion docs: quiet-sky-story.html (how this came together) · product-spec.html · strategy-deck.html (the July 2026 brand strategy, archived).