Design principles
Shared guidance for color, typography, spacing, motion, and accessible layouts.
Use these principles alongside the guidance on each component page.
Source coverage
| Sheet | Reviewed frame | Coverage here |
|---|---|---|
| Color | 164:2 | Scale jobs, neutral roles, contrast, avatars, migration |
| Typography | 165:2 | Role selection, weights, leading, tracking, semantics |
| Spacing, radius and size | 165:17 | Spacing jobs, radius, controls, icons, widths, focus |
| Elevation and borders | 165:29 | Surface recipes, border states, sticky edges |
| Motion | 472:17720 | Principles, presets, all 12 recipes, constants, exceptions |
| Layout | 238:2 | Shell, grid, responsive policy, content and overlay widths |
Coverage is of the displayed foundation guidance. Historical usage counts, decorative example copy, and the referenced external Color scales.oklch.json file are not treated as implementation requirements; that JSON file was not retrieved. Values and visual examples are in the corresponding foundation reference pages.
Color rules
Source: Color frame. Values: Color reference.
| ID | Figma guidance |
|---|---|
| COLOR-01 | Use eight ten-step scales plus background; background/subtle is an alias of Soft Pearl 100. The same names are intended for future dark values; dark values are not currently defined. |
| COLOR-02 | Steps 100/200/300 are default/hover/active light fills. Steps 400/500/600 are default/hover/strong colored borders. Steps 700/800 are solid fill/hover. Steps 900/1000 are secondary/primary text and icons on light fills. |
| COLOR-03 | The scales were designed in OKLCH, but hex values ship in code and Figma. Contrast labels in Figma compare against white; 4.5 or greater is the sheet's normal-text threshold. Check the actual pair rather than inferring accessibility from the step. |
| COLOR-04 | Blue is brand, links, focus and info; Red is error/destructive; Amber is warning; Green is success; Purple, Rose and Orange are accents. Amber and Orange solid fills take dark text; Amber 700 uses 1000 text. |
| COLOR-05 | Avatar tones are matched fill/initial pairs, chosen from a stable user ID. Use them only for initials, not status colors. Figma describes these pairs as AA; verify the actual rendered text size and pair when implementing. |
| COLOR-06 | Use white background for cards, inputs, menus and dialogs; subtle for the chat conversation, sidebar and canvas around white cards. |
| COLOR-07 | Retire the old utility layer, fg/text split, cool-gray ramp, primary-hover-300 and irregular Soft Pearl 10/25/1050 steps. Info blue and indigo merge into Blue; violet becomes Purple. This is a migration direction, not an instruction to remove legacy application tokens in this PR. |
| COLOR-08 | Retired #EDECEB and #EAE7E0 merge into Soft Pearl 300 #EDEAE3. #F3F0E7 and #403B36 retire; dark fills use 1000. #FCFBF8 becomes 100. Disabled text moves from #B1ADA7 to 600 #A6A29C. |
Soft pearl jobs
| Step | Intended use |
|---|---|
| 100 | Canvas behind cards |
| 200 | Row hover and table headers |
| 300 | Hairlines, wells, tags and selected fills |
| 400 | Control borders and fill hover |
| 500 | Border hover |
| 600 | Strong borders and disabled text |
| 700 | Placeholders and quiet icons |
| 800 | Tertiary/helper text |
| 900 | Secondary text and default icons |
| 1000 | Primary text and tooltip fills |
Typography rules
Source: Typography frame. Values: Typography.
| ID | Figma guidance |
|---|---|
| TYPE-01 | Choose the job first: Heading for titles, Label for compact single-line controls/cells, Copy for wrapping content. The product has 17 Inter styles, replacing 33; Display leaves the product library. |
| TYPE-02 | Use one Heading/24 page title. Heading/32 is for metrics and empty-state headlines; 20 for section/dialog titles; 18 for cards/panels; 15 for form blocks/sidebar groups. |
| TYPE-03 | Label/15 is for large buttons/inputs and navigation; Label/13 is the product default for table cells, inputs, small/medium buttons, menus and tabs; Label/12 is for badges, headers, timestamps and single-line tooltips. Strong labels mark values, selections and button labels. |
| TYPE-04 | Copy/15 is for chat, dialog bodies and documents; Copy/13 for descriptions, help and multiline table cells; Copy/12 for helpers, multiline tooltips and footnotes. Strong Copy is inline emphasis. |
| TYPE-05 | Use only weights 400, 500 and 600. Heading is 600; Label Strong is 500; Copy Strong is 600. Text recipes carry no color: choose Soft Pearl 1000, 900 or 800 by role. |
| TYPE-06 | Heading level follows document structure, never the font size. Tables and metrics use tabular figures. |
| TYPE-07 | Label/13 uses 16px leading: small controls are 16 + 6 + 6 = 28px; medium controls are 16 + 8 + 8 = 32px. Control height follows leading and padding. |
| TYPE-08 | Tracking is 0 at 12/13px, −1% at 15px, −1.5% at 18/20px, −2% at 24/32px. Pathfinder represents these percentages as em. |
Pathfinder implementation: typography classes do not force nowrap or choose an HTML element. Controls retain wrapping and may grow for long content or enlarged text; the single-line role is not permission to clip content.
Spacing, radius and sizing rules
Source: Dimensions frame. Values: Sizing and elevation.
| ID | Figma guidance |
|---|---|
| SIZE-01 | Bind every padding and gap to the spacing scale. Off-scale spacing such as 10px or 14px is an override to correct, not a new token. This rule applies to spacing; radius/lg remains 10px. |
| SIZE-02 | Spacing 8xl–11xl (80–160px baseline) is for page/section layout, never component interiors. |
| SIZE-03 | Buttons, split buttons and icon buttons use radius/md (8px) at every size; inputs/other controls use sm (6px); menus/popovers lg (10px); cards/panels/dialogs xl (12px); sheets 2xl (16px); pills full. Component guidance specifies exceptions. |
| SIZE-04 | Nested corner radius equals the outer radius minus the intervening padding. Pathfinder implementation must avoid negative CSS radii; the sheet does not define a negative-result policy. |
| SIZE-05 | Bind control height to tokens. xs 24px is for icon buttons inside controls; sm 28px for dense tables/toolbars/filters; md 32px is default; lg 36px for prominent actions; xl 40px for hero/empty-state actions. |
| SIZE-06 | Icons: xs 12px for dense tables/badges; sm 16px is default in sm/md controls; md 20px in lg/xl controls; lg 24px for featured icons/empty states. |
| SIZE-07 | Containers use a 0.5px hairline, interactive control edges use 1px, and focus uses a 2px Blue 700 ring offset 2px outside the element. |
Spacing jobs
| Token | Intended use |
|---|---|
| none / 0 | No gap |
| xxs / 2 | Icon-to-text inside badges/tags |
| xs / 4 | Dense-control gaps and badge padding |
| sm / 6 | Icon-to-label inside buttons/menu items |
| md / 8 | Related-control gaps and vertical input padding |
| lg / 12 | Horizontal control padding and list-item gaps |
| xl / 16 | Form-field gaps and compact card padding |
| 2xl / 20 | Docked-chat and sheet panel padding |
| 3xl / 24 | Card/dialog padding and groups inside panels |
| 4xl / 32 | Form blocks and page sections |
| 5xl / 40 | Major page regions |
| 6xl / 48 | Page sections on wide layouts |
| 7xl / 64 | Outer page margins on 1440px frames; depending on layout context |
| 8xl–11xl / 80–160 | Page and section layout only |
Radius/none is for square tables/full-bleed panels; xs is for checkboxes, small badges and tags; sm also covers OTP slots/tooltips; md also covers menu items, badges, small cards and wells; xl also covers the chat composer; full also covers avatars, switches and dots. Old xxs/3xl/4xl radius names are removed.
Generic container widths: xxs 320 for narrow menus/popovers; xs 384 for content tooltips/filter popovers; sm 480 for small dialogs; md 560 for default dialogs; lg 640 for wide dialogs/sheets; xl 768 for a form column; 2xl 1024 for document reading; 3xl 1280 for content maximum; 4xl 1440 for the design frame; 5xl 1600 for wide dashboards; 6xl 1920 for Full HD. These generic containers and named product-layout widths serve different purposes; do not interchange the two scales.
Pathfinder implementation: token lengths use rem at a 16px baseline, with px for strokes/full radius. Control sizes are minimum baselines when content needs to grow.
Elevation and border rules
Source: Elevation frame.
| ID | Figma guidance |
|---|---|
| ELEV-01 | Start flat: white background, Soft Pearl 300 hairline, radius xl, no shadow. Separate surfaces with a hairline and a neutral fill step before adding elevation. |
| ELEV-02 | A floating surface pairs its shadow with a hairline. Choose elevation by job, never by visual shadow size; a shadow alone is not a full recipe. |
| ELEV-03 | Inputs are flat. Buttons and segmented controls use control elevation with radius md. Other elevation specimens show radius xl; component-specific radius belongs to its component guidance. |
| ELEV-04 | Use raised for hover-lifted cards/dragged items; soft for the composer and fields resting on the page; menu for trigger-anchored dropdowns/popovers/tooltips; panel for docked/floating panes; modal for dialogs. |
| ELEV-05 | A sticky header/footer gets a Soft Pearl 300 hairline where content scrolls beneath it. |
| ELEV-06 | Shadows use neutral #121212, never a tinted color. |
| ELEV-07 | Border states: Soft Pearl 400 default, 500 hover, 600 strong; Blue 700 selected; Red 600 invalid. Control states use 1px. Focus is Blue 700 at 2px with 2px outside offset. |
Motion rules
Source: Motion frame. Values: Motion tokens.
| ID | Figma guidance |
|---|---|
| MOTION-01 | Motion explains origin: menus come from their trigger, toasts from their edge, inserted rows from the insertion point. Change state on the same element rather than blinking it out and recreating it. |
| MOTION-02 | Press feedback begins on pointer down, within 100ms, without waiting for the network. Large surfaces (cards, rows, radio cards) never scale on press; only their control does. |
| MOTION-03 | Every transition uses a token or documented recipe. If none fits, add a recipe to the design before implementing an independent transition. Raw timings/curves are overrides. |
| MOTION-04 | Springs are for movement; durations are for color, exits and CSS-only fallbacks. Closing never bounces; use fast/out, described as roughly 70% of opening time. |
| MOTION-05 | Bounce is reserved for success and direct manipulation. Never bounce data, errors, readable content or toasts. Keep readable surfaces steady. |
| MOTION-06 | Prefer transform and opacity. Animate size only when the element itself changes size, such as stateful buttons or expanding sections. Prefer one moving part; other parts change color/text/opacity in place. |
| MOTION-07 | Keyboard-initiated menus, tabs, radios and toggles change instantly. Keyboard presses never scale. |
| MOTION-08 | Reduced motion replaces springs with a 150ms out-eased fade and removes scale, offset and blur. Loading indicators may continue. |
| MOTION-09 | Only disclosure chevrons rotate (accordions/table groups). Menu-trigger chevrons stay still; the held hover fill indicates an open menu. |
| MOTION-10 | Animate toward the current target so interruption continues from the present state; never restart from a fixed origin. |
| MOTION-11 | Duration-based transitions stay at or below 300ms except sheets; the deliberate row also mentions whole-page transitions, recorded as an unresolved exception below. |
| MOTION-12 | Prototype with the specified Figma spring settings to match the intended product feel. The package exports duration/bounce presets, not an animation engine. |
Preset jobs and prototype settings
| Preset | Product duration / bounce | Figma stiffness / damping / mass | Intended use |
|---|---|---|---|
| Snappy | 0.2s / 0 | 685 / 52.4 / 1 | Presses, switches, checkboxes, opening menus |
| Smooth | 0.3s / 0.15 | 305 / 29.7 / 1 | Indicators, expansion, size/layout changes, toasts, dialogs, rows; apply no-bounce restrictions before implementation |
| Expressive | 0.4s / 0.25 | 171 / 19.6 / 1 | Success only, never expansion/data/errors |
Durations: instant/100ms for hover/press color; fast/150ms for exits, disclosure chevrons, focus and checkbox ticks; base/200ms for menus/tooltips/selects without springs; slow/300ms for panels/dialogs without springs; deliberate/500ms for sheets with the Vaul curve. Easing/out is for entering, pressing, responding and every exit; in-out moves between screen positions; standard/ease is only for color/hover.
Component recipes
These are documented targets, not animations currently shipped by Pathfinder. Preserve keyboard and reduced-motion overrides above.
| ID | Recipe | Figma behavior and intended components |
|---|---|---|
| RECIPE-01 | Press | Snappy: pointer-down scale 0.97, or 0.94 for 16px checkbox/radio controls; release to 1. Buttons, icon/split buttons, checkbox/radio. |
| RECIPE-02 | Hover | Instant + standard; color only, never movement or scale. Every control. |
| RECIPE-03 | Open from trigger | Snappy: opacity 0→1, scale 0.96→1, anchored offset 4px. Exit opacity 0/scale 0.98. Source prose says 120ms but names fast/150ms. Dropdown/select/date picker/popover/tooltip; tooltip has 100ms delay. Keyboard opening is instant. |
| RECIPE-04 | Enter and exit | Smooth: backdrop fades; dialog rises 8px and scales 0.96→1. Exit fades/scales to 0.98 using fast. Dialog/confirmation. |
| RECIPE-05 | Slide in | Sheet enters from its edge over deliberate with cubic-bezier(0.32, 0.72, 0, 1). Drag closes past 25% or velocity 0.4; velocity units are unspecified. |
| RECIPE-06 | Change state | Current content exits with 1px blur in 90ms; next content arrives on snappy; width follows with smooth. Loading/done buttons, copy icons, file upload. |
| RECIPE-07 | Sliding indicator | Position and width move together on smooth; a darker copy of labels is clipped to the indicator. Tabs/segmented controls; switch thumb uses snappy. |
| RECIPE-08 | Expand and collapse | Height expands as content fades up 4px on smooth; collapse uses fast without bounce. Accordion, alert details, grouped table rows. |
| RECIPE-09 | Swap a value | Crossfade the entire value once: 80ms out, 150ms in through 1px blur. No per-digit roll. Badge counts, table numbers, progress labels. |
| RECIPE-10 | Add and remove | Append at end: fade only. Insert elsewhere/remove: fade while following items move with transforms. Fast + snappy; stagger 30ms for at most 5 items, then show the rest together. Rows, lists, tags, toast stacks. |
| RECIPE-11 | Success | Expressive check: scale from 0.4 and rotate 20° into place. Completion/copy/upload/success-toast feedback; do not bounce the readable toast surface. |
| RECIPE-12 | Loading | The only looping motion. Fade in after 150ms so fast responses do not flash a loader. Skeleton/progress/progress ring. |
Distances: anchored 4px, overlay/list-row 8px, edge-toast 16px. Text blur is 1px for swaps; icon blur is 3px. Enter/exit scales are 0.96/0.98, with the success check's separate 0.4 start. These constants belong to complete recipes, not individually configurable theme variables. The icon-blur row mentions rolling digits despite the value-swap recipe forbidding them; use the whole-value recipe.
Layout rules
Source: Layout frame. Full dimensions: Layout guidance.
| ID | Figma guidance |
|---|---|
| LAYOUT-01 | Start from Layout / App shell at 1440×900; review at widths 1280 and 1024 before handoff. |
| LAYOUT-02 | Client app below 768px shows the desktop-only message; partner pages are an exception. 768–1023 works but is not a design target. This is a product routing policy, not a package-level viewport restriction. |
| LAYOUT-03 | Shell: sidebar 208px expanded/56px collapsed, 8px gutters, white main card with 12px radius and 0.5px hairline, optional 44px breadcrumb, 24px content padding, optional 400px aside. |
| LAYOUT-04 | Use 12 fluid columns with 24px gutters in main content, 16px in asides/sheets. Map existing half/third form layouts to spans 6/4. Use spans instead of per-screen fixed widths. |
| LAYOUT-05 | Full is the default content width; Wide caps at 1200px; Reading is centered at 720px. Change content width rather than overriding the 24px page padding. |
| LAYOUT-06 | Use scale gaps: 8px within groups, 16/24px between cards, 32/48px between page sections. |
| LAYOUT-07 | Use the specified sheet/dialog sizes. The source says content beyond lg should become a page, but also lists xl/full dialogs; this needs a design decision. |
Pathfinder implementation: the package currently exports breakpoint and generic width tokens. It does not yet export an app shell, a layout-width scale, Sheet or Dialog. Documenting their intended geometry does not migrate enterprise routing or layout.