# Design principles

Package: @commenda/pathfinder@0.1.0
Page: /docs/foundations/design-rules

Use these principles alongside the guidance on each component page.

## Source coverage [#source-coverage]

| Sheet                                                                                                  | Reviewed frame | Coverage here                                              |
| ------------------------------------------------------------------------------------------------------ | -------------- | ---------------------------------------------------------- |
| [Color](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=5-5)                    | `164:2`        | Scale jobs, neutral roles, contrast, avatars, migration    |
| [Typography](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=5-6)               | `165:2`        | Role selection, weights, leading, tracking, semantics      |
| [Spacing, radius and size](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=5-7) | `165:17`       | Spacing jobs, radius, controls, icons, widths, focus       |
| [Elevation and borders](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=5-8)    | `165:29`       | Surface recipes, border states, sticky edges               |
| [Motion](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=472-17719)             | `472:17720`    | Principles, presets, all 12 recipes, constants, exceptions |
| [Layout](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=237-2)                 | `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 [#color-rules]

Source: [Color frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=164-2). Values: [Color reference](/docs/foundations/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 [#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 [#typography-rules]

Source: [Typography frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=165-2). Values: [Typography](/docs/foundations/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 [#spacing-radius-and-sizing-rules]

Source: [Dimensions frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=165-17). Values: [Sizing and elevation](/docs/foundations/sizing-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 [#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 [#elevation-and-border-rules]

Source: [Elevation frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=165-29).

| 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 [#motion-rules]

Source: [Motion frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=472-17720). Values: [Motion tokens](/docs/foundations/motion).

| 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-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 [#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 [#layout-rules]

Source: [Layout frame](https://www.figma.com/design/dn7BkGYEfIyP0o2zfesfVh/The-System?node-id=238-2). Full dimensions: [Layout guidance](/docs/foundations/layout).

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