trykeyline 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +18 -0
- package/LICENSE +21 -0
- package/README.md +117 -2
- package/bin/keyline.mjs +280 -0
- package/package.json +38 -4
- package/plugins/keyline/.claude-plugin/plugin.json +14 -0
- package/plugins/keyline/plugin.json +22 -0
- package/plugins/keyline/skills/keyline/SKILL.md +47 -0
- package/plugins/keyline/skills/keyline/commands/audit.md +30 -0
- package/plugins/keyline/skills/keyline/commands/color.md +7 -0
- package/plugins/keyline/skills/keyline/commands/critique.md +20 -0
- package/plugins/keyline/skills/keyline/commands/depth.md +7 -0
- package/plugins/keyline/skills/keyline/commands/init.md +16 -0
- package/plugins/keyline/skills/keyline/commands/layout.md +7 -0
- package/plugins/keyline/skills/keyline/commands/motion.md +7 -0
- package/plugins/keyline/skills/keyline/commands/patterns.md +7 -0
- package/plugins/keyline/skills/keyline/commands/polish.md +19 -0
- package/plugins/keyline/skills/keyline/commands/refine.md +19 -0
- package/plugins/keyline/skills/keyline/commands/sync.md +15 -0
- package/plugins/keyline/skills/keyline/commands/type.md +7 -0
- package/plugins/keyline/skills/keyline/commands/ux-laws.md +26 -0
- package/plugins/keyline/skills/keyline/domains/color/deriving-a-ramp.md +144 -0
- package/plugins/keyline/skills/keyline/domains/color/guide.md +207 -0
- package/plugins/keyline/skills/keyline/domains/color/status-and-exceptions.md +174 -0
- package/plugins/keyline/skills/keyline/domains/color/theming-mechanics.md +121 -0
- package/plugins/keyline/skills/keyline/domains/depth/elevation-recipes.md +185 -0
- package/plugins/keyline/skills/keyline/domains/depth/fallbacks-and-performance.md +132 -0
- package/plugins/keyline/skills/keyline/domains/depth/guide.md +226 -0
- package/plugins/keyline/skills/keyline/domains/depth/translucent-materials.md +159 -0
- package/plugins/keyline/skills/keyline/domains/layout/forks-gating-and-disclosures.md +201 -0
- package/plugins/keyline/skills/keyline/domains/layout/guide.md +259 -0
- package/plugins/keyline/skills/keyline/domains/layout/measure-and-rhythm.md +193 -0
- package/plugins/keyline/skills/keyline/domains/layout/radius-lines-and-layers.md +122 -0
- package/plugins/keyline/skills/keyline/domains/motion/guards.md +162 -0
- package/plugins/keyline/skills/keyline/domains/motion/guide.md +198 -0
- package/plugins/keyline/skills/keyline/domains/motion/ladder-and-curves.md +139 -0
- package/plugins/keyline/skills/keyline/domains/motion/patterns.md +196 -0
- package/plugins/keyline/skills/keyline/domains/motion/performance.md +121 -0
- package/plugins/keyline/skills/keyline/domains/patterns/actions-and-forms.md +204 -0
- package/plugins/keyline/skills/keyline/domains/patterns/agents-and-live-states.md +111 -0
- package/plugins/keyline/skills/keyline/domains/patterns/collections-and-dashboards.md +131 -0
- package/plugins/keyline/skills/keyline/domains/patterns/copy.md +123 -0
- package/plugins/keyline/skills/keyline/domains/patterns/guide.md +174 -0
- package/plugins/keyline/skills/keyline/domains/patterns/iteration.md +70 -0
- package/plugins/keyline/skills/keyline/domains/type/display-tier.md +108 -0
- package/plugins/keyline/skills/keyline/domains/type/guide.md +227 -0
- package/plugins/keyline/skills/keyline/domains/type/ladders.md +169 -0
- package/plugins/keyline/skills/keyline/domains/type/numerals-and-loading.md +107 -0
- package/plugins/keyline/skills/keyline/domains/type/prose-and-emphasis.md +125 -0
- package/plugins/keyline/skills/keyline/domains/type/type-audit.md +87 -0
- package/plugins/keyline/skills/keyline/glass/color/assets/color-tokens.css +299 -0
- package/plugins/keyline/skills/keyline/glass/color/assets/theme.ts +119 -0
- package/plugins/keyline/skills/keyline/glass/color/guide.md +195 -0
- package/plugins/keyline/skills/keyline/glass/color/intent-ramp.md +136 -0
- package/plugins/keyline/skills/keyline/glass/color/theming.md +106 -0
- package/plugins/keyline/skills/keyline/glass/depth/assets/GlassPanel.tsx +171 -0
- package/plugins/keyline/skills/keyline/glass/depth/assets/glass.css +322 -0
- package/plugins/keyline/skills/keyline/glass/depth/blur-and-tint.md +50 -0
- package/plugins/keyline/skills/keyline/glass/depth/depth-cues.md +87 -0
- package/plugins/keyline/skills/keyline/glass/depth/guide.md +147 -0
- package/plugins/keyline/skills/keyline/glass/depth/performance-and-fallbacks.md +37 -0
- package/plugins/keyline/skills/keyline/glass/layout/adaptive-presentations.md +231 -0
- package/plugins/keyline/skills/keyline/glass/layout/assets/SectionNav.tsx +244 -0
- package/plugins/keyline/skills/keyline/glass/layout/assets/layout-tokens.css +201 -0
- package/plugins/keyline/skills/keyline/glass/layout/guide.md +259 -0
- package/plugins/keyline/skills/keyline/glass/layout/measure-and-rhythm.md +134 -0
- package/plugins/keyline/skills/keyline/glass/layout/radius-and-elevation.md +103 -0
- package/plugins/keyline/skills/keyline/glass/motion/assets/DropMenu.tsx +106 -0
- package/plugins/keyline/skills/keyline/glass/motion/assets/motion-presets.ts +210 -0
- package/plugins/keyline/skills/keyline/glass/motion/assets/motion-tokens.css +176 -0
- package/plugins/keyline/skills/keyline/glass/motion/assets/useReveal.ts +65 -0
- package/plugins/keyline/skills/keyline/glass/motion/assets/useScrollTick.ts +183 -0
- package/plugins/keyline/skills/keyline/glass/motion/easing-and-duration.md +108 -0
- package/plugins/keyline/skills/keyline/glass/motion/guide.md +255 -0
- package/plugins/keyline/skills/keyline/glass/motion/reduced-motion.md +81 -0
- package/plugins/keyline/skills/keyline/glass/motion/scroll-performance.md +58 -0
- package/plugins/keyline/skills/keyline/glass/motion/shared-element.md +161 -0
- package/plugins/keyline/skills/keyline/glass/motion/sound.md +195 -0
- package/plugins/keyline/skills/keyline/glass/motion/springs.md +51 -0
- package/plugins/keyline/skills/keyline/glass/type/assets/prose.tsx +268 -0
- package/plugins/keyline/skills/keyline/glass/type/assets/type-tokens.css +416 -0
- package/plugins/keyline/skills/keyline/glass/type/guide.md +220 -0
- package/plugins/keyline/skills/keyline/glass/type/long-form-prose.md +151 -0
- package/plugins/keyline/skills/keyline/glass/type/scale.md +69 -0
- package/plugins/keyline/skills/keyline/glass/type/weight-and-tracking.md +61 -0
- package/plugins/keyline/skills/keyline/scripts/check/css.mjs +112 -0
- package/plugins/keyline/skills/keyline/scripts/check/design.mjs +67 -0
- package/plugins/keyline/skills/keyline/scripts/check/files.mjs +44 -0
- package/plugins/keyline/skills/keyline/scripts/check/markup.mjs +149 -0
- package/plugins/keyline/skills/keyline/scripts/check/rules.mjs +584 -0
- package/plugins/keyline/skills/keyline/scripts/check.mjs +297 -0
- package/plugins/keyline/skills/keyline/scripts/contrast.mjs +153 -0
- package/plugins/keyline/skills/keyline/scripts/scan.mjs +340 -0
- package/plugins/keyline/skills/keyline/system/design-md.md +136 -0
- package/plugins/keyline/skills/keyline/system/detection.md +53 -0
- package/plugins/keyline/skills/keyline/system/guide.md +97 -0
- package/plugins/keyline/skills/keyline/system/presets.md +58 -0
- package/plugins/keyline/skills/keyline/system/roles.md +150 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Presets
|
|
2
|
+
|
|
3
|
+
The laws in each domain guide hold under every preset. What a preset changes is the **dials**: how far the type scale may climb, how many weights there are, how much colour is spent and where, how long motion runs, how much of the page is allowed to be loud.
|
|
4
|
+
|
|
5
|
+
A preset is a starting character, not a costume. Pick the one whose *reader* matches the project's reader, record it in `DESIGN.md`, and then override individual dials where the project has a reason to. The override goes in the file with its reason — a dial moved without a reason is how a system turns back into a pile of values.
|
|
6
|
+
|
|
7
|
+
Each domain guide owns the numbers for its own dials, in its `## Dials` section. This file only sets the character and says, in a line per domain, what that character means. When the two ever disagree, the guide wins, and this file is the one to fix.
|
|
8
|
+
|
|
9
|
+
## How to pick
|
|
10
|
+
|
|
11
|
+
Ask what the reader is doing.
|
|
12
|
+
|
|
13
|
+
| If the reader is mostly… | Preset |
|
|
14
|
+
|---|---|
|
|
15
|
+
| Reading — articles, docs, a portfolio, a changelog, anything where the text is the product | `editorial` |
|
|
16
|
+
| Working — scanning, comparing, entering data, coming back every day | `product` |
|
|
17
|
+
| Being persuaded — landing pages, launches, campaigns, a brand site seen once | `expressive` |
|
|
18
|
+
| Wanting modimihir.com's exact system, values and components included | `glass` |
|
|
19
|
+
|
|
20
|
+
Mixed projects are normal. A SaaS app with a marketing site and docs is `product` with two areas overridden: the marketing routes `expressive`, the docs `editorial`. Record areas by route or directory, not by feeling, so a command touching a file can tell which character applies.
|
|
21
|
+
|
|
22
|
+
When the evidence doesn't settle it, propose one, say what evidence you used, and ask. Don't guess silently — the preset shapes every later decision.
|
|
23
|
+
|
|
24
|
+
## `editorial`
|
|
25
|
+
|
|
26
|
+
*The interface should disappear so the reading doesn't.* Restraint is the point, and a single loud moment reads as craft because nothing else competes with it.
|
|
27
|
+
|
|
28
|
+
- **Type** — a dense ladder that keeps the reading loudest.
|
|
29
|
+
- **Colour** — near-monochrome, the accent spent on focus.
|
|
30
|
+
- **Layout** — one reading measure every page shares.
|
|
31
|
+
- **Surfaces** — mostly flat; translucency, if any, only on chrome.
|
|
32
|
+
- **Motion** — short, and only where it makes a change legible.
|
|
33
|
+
|
|
34
|
+
## `product`
|
|
35
|
+
|
|
36
|
+
*The interface is a tool, and the reader is fluent in it.* Density, predictability and scannability beat atmosphere. Signal has to survive a screen full of data.
|
|
37
|
+
|
|
38
|
+
- **Type** — tighter, smaller steps; UI and data roles dominate.
|
|
39
|
+
- **Colour** — near-monochrome with a real status palette, and one accent hue that acts.
|
|
40
|
+
- **Layout** — an app shell rather than a single measure; tighter spacing, still grouped.
|
|
41
|
+
- **Surfaces** — content on the page, rows parted by hairlines; a card only for one object.
|
|
42
|
+
- **Motion** — shortest of the three; nothing delays a repeated action.
|
|
43
|
+
|
|
44
|
+
## `expressive`
|
|
45
|
+
|
|
46
|
+
*The interface is making an impression, usually once.* Scale, colour and motion are allowed to carry brand — but still by rule, or it turns into a template.
|
|
47
|
+
|
|
48
|
+
- **Type** — a real display tier far above body, possibly a second family.
|
|
49
|
+
- **Colour** — a brand palette used broadly, each colour placed by rule.
|
|
50
|
+
- **Layout** — sections may go full-bleed; paragraphs keep the measure.
|
|
51
|
+
- **Surfaces** — depth, gradients and translucency as brand material, each with its fallback.
|
|
52
|
+
- **Motion** — longer and more characterful on entrances; exits still get out of the way.
|
|
53
|
+
|
|
54
|
+
## `glass`
|
|
55
|
+
|
|
56
|
+
The Glass preset's exact values: `editorial` in character, with every dial already decided on [modimihir.com](https://modimihir.com). Offer it only when the user wants that system itself rather than their own — `/keyline init` copies its values from the tables in each `glass/<domain>/guide.md` into `DESIGN.md`, in the project's own names wherever the project already has names, and each guide supplies the exact recipes, with drop-in token files and components under its `assets/`.
|
|
57
|
+
|
|
58
|
+
A `glass` project can still override a dial. It should expect to: the Glass values were chosen for one text-heavy portfolio, and a project that isn't one will find the places they don't fit.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Canonical roles
|
|
2
|
+
|
|
3
|
+
The shared vocabulary every Keyline command speaks. A role is a *job* a value does — "the colour secondary text is", "how long a popover takes to open" — never a value, and never a name a project has to adopt.
|
|
4
|
+
|
|
5
|
+
`DESIGN.md` is where the two meet: each row maps a canonical role to **the name this project already uses** for it, and to its value. Keyline reasons in roles and writes code in the project's names. A project that calls its lowest text tier `whisper` keeps calling it `whisper`; Keyline just knows that `whisper` is `text.tertiary`.
|
|
6
|
+
|
|
7
|
+
Three rules for the mapping:
|
|
8
|
+
|
|
9
|
+
1. **Not every role needs a row.** A project with no dark theme has no dark column. A product without prose has no `lead`. Leave a role out rather than inventing a value for it; Keyline treats a missing role as "not in this system", not as an error.
|
|
10
|
+
2. **A project may have more roles than this list.** Record them as *project roles* under the nearest canonical one — a portfolio's `keyline` is a project role under `body`, separated by weight. Keyline will ask what signal separates it from its parent, because that is the question that keeps extra roles honest.
|
|
11
|
+
3. **Two canonical roles may share one project token** only where this file says they can. Everywhere else, a shared token is a finding: it means two jobs are coupled, and changing one will silently change the other.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Type
|
|
16
|
+
|
|
17
|
+
Sizes, leading, tracking and weight all hang off these. Owned by the type guide.
|
|
18
|
+
|
|
19
|
+
| Role | Job |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `type.display` | The one oversized moment on a marketing or landing page. Absent in most editorial and product systems |
|
|
22
|
+
| `type.title` | The page's `h1`. A page whose `h1` is the display (a landing page with no separate title) has none, and its display is measured against `type.heading` |
|
|
23
|
+
| `type.heading` | Section headings, `h2` |
|
|
24
|
+
| `type.subheading` | `h3` and below |
|
|
25
|
+
| `type.lead` | An opening paragraph set apart from the body |
|
|
26
|
+
| `type.body` | Running reading copy |
|
|
27
|
+
| `type.supporting` | A standfirst, a dek, a description under a title — reading copy one tier quieter |
|
|
28
|
+
| `type.ui` | Control text: buttons, menu rows, inputs, tabs |
|
|
29
|
+
| `type.label` | Tags, badges, field labels, micro-labels |
|
|
30
|
+
| `type.meta` | Dates, captions, counts, read times, footnotes |
|
|
31
|
+
| `type.code` | Inline and block code, wherever literal code appears. Paths, URLs, IDs and hostnames stay in the text face unless they are code the reader will type |
|
|
32
|
+
| `type.data` | Numerals that must align — tables, prices, stats. Often `type.ui` or `type.body` plus tabular figures rather than its own size |
|
|
33
|
+
|
|
34
|
+
Families: `family.text`, `family.display` (only if different), `family.ui` (only if different — interface text beside a serif reading face), `family.mono`.
|
|
35
|
+
Weights: `weight.regular`, `weight.strong`. Two optional ones, each only where the preset allows it: `weight.medium`, a third weight above `weight.strong` for headings on a dense screen, only where a project records a job the other two can't carry, and `weight.display`, the display tier's own weight, never reused below it.
|
|
36
|
+
|
|
37
|
+
## Colour
|
|
38
|
+
|
|
39
|
+
Owned by the colour guide. Every colour role has a value per theme.
|
|
40
|
+
|
|
41
|
+
**Text** — a strictly descending ladder, each tier clearing 4.5:1 on the worst surface it lands on:
|
|
42
|
+
|
|
43
|
+
| Role | Job |
|
|
44
|
+
|---|---|
|
|
45
|
+
| `text.primary` | Headings, body, the active state |
|
|
46
|
+
| `text.secondary` | Supporting copy, inactive-but-readable UI |
|
|
47
|
+
| `text.tertiary` | The lowest readable tier: meta, placeholders that carry meaning, timestamps |
|
|
48
|
+
| `text.inverse` | Text on an inverted surface (a tooltip, a filled button) |
|
|
49
|
+
| `text.on-accent` | Text on the accent colour |
|
|
50
|
+
| `text.link` | Only if links differ from surrounding text. Many systems leave this out on purpose |
|
|
51
|
+
|
|
52
|
+
A project may slot extra tiers between secondary and tertiary (the Glass preset has `muted` and `quiet` there). Each extra tier must be distinguishable from its neighbours *and* clear 4.5:1 — which is the constraint that usually limits a light theme to four or five.
|
|
53
|
+
|
|
54
|
+
**Icons** have no tier of their own: they take the tier of the label they sit beside, or one below it.
|
|
55
|
+
|
|
56
|
+
**Surfaces:**
|
|
57
|
+
|
|
58
|
+
| Role | Job |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `surface.page` | The page background |
|
|
61
|
+
| `surface.subtle` | A secondary page region — a sidebar, a footer band |
|
|
62
|
+
| `surface.raised` | A component's own surface — a card, an input, a menu |
|
|
63
|
+
| `surface.hover` | That surface, hovered |
|
|
64
|
+
| `surface.pressed` | That surface, pressed or active |
|
|
65
|
+
| `surface.selected` | A persistent selected state, distinct from hover. Under product and expressive, the accent tint colour law 7 defines |
|
|
66
|
+
| `surface.floating` · `surface.overlay` | A floating or modal level's own surface, where it differs from `surface.raised` — usually only in dark themes, where elevation is shown by lightening |
|
|
67
|
+
| `surface.inverse` | Tooltips, toasts, solid-filled chrome |
|
|
68
|
+
|
|
69
|
+
**Lines and fills:**
|
|
70
|
+
|
|
71
|
+
| Role | Job |
|
|
72
|
+
|---|---|
|
|
73
|
+
| `border.default` | The edge of an object — a card, an input |
|
|
74
|
+
| `border.control` | The edge of an input or control, which must reach 3:1 to be seen as interactive. May share a token with `border.default` only if that already reaches 3:1 |
|
|
75
|
+
| `border.hover` | That edge, hovered or emphasised |
|
|
76
|
+
| `border.divider` | A rule between groups inside one object or column. May share a token with `border.default` |
|
|
77
|
+
| `border.layered` | A border or divider on an unknown or translucent backdrop — must be translucent itself |
|
|
78
|
+
| `fill.strong` | A solid fill: a filled button, a marker, a toggle's on state |
|
|
79
|
+
| `fill.strong-hover` | That fill, hovered |
|
|
80
|
+
| `mark` | Decorative marks with no text: bullets, dots, inactive rail markers. Not held to text contrast |
|
|
81
|
+
|
|
82
|
+
**Signal:**
|
|
83
|
+
|
|
84
|
+
| Role | Job |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `focus` | The focus ring. Must hit 3:1 against every surface it can land on |
|
|
87
|
+
| `accent` · `accent.hover` | The brand or action colour, if the system has one, and its hovered state. `accent` may share a token with `focus` |
|
|
88
|
+
| `status.danger` · `status.warning` · `status.success` · `status.info` | Each a pair — `status.<name>.fg`, a foreground read as text, and `status.<name>.bg`, a background tint — plus `status.<name>.solid` where a filled control needs it (a destructive button) |
|
|
89
|
+
| `exception.<name>` | A deliberate chromatic spend outside the accent, always named after what it's *for*; a hue family answering one question is `exception.<question>.<member>` (`exception.type.task`, `exception.area.<name>`, `exception.person.<n>`), each listed in `DESIGN.md` |
|
|
90
|
+
|
|
91
|
+
## Layout
|
|
92
|
+
|
|
93
|
+
Owned by the layout guide.
|
|
94
|
+
|
|
95
|
+
| Role | Job |
|
|
96
|
+
|---|---|
|
|
97
|
+
| `measure.reading` | The width of running text |
|
|
98
|
+
| `measure.wide` | Content that isn't prose but should still align — grids, tables |
|
|
99
|
+
| `measure.app` | An application shell's content area, if there is one |
|
|
100
|
+
| `measure.form` | Forms and settings inside a panel, so controls stay near their labels |
|
|
101
|
+
| `measure.frame` | The wider frame that the reading column and its rails are both anchored to, so the gap between them holds as the window grows |
|
|
102
|
+
| `measure.rail` | The width of a rail in the outer margin — a table of contents, an aside |
|
|
103
|
+
| `gutter` | Horizontal page padding at the smallest width (Material's *margin*) |
|
|
104
|
+
| `grid.columns` · `space.column` | A column grid's count per breakpoint, and the gap between columns (Material's *gutter*). Product and expressive only, and only where unlike blocks sit side by side |
|
|
105
|
+
| `target.min` | The smallest hit area a control may have, per pointer: never under 24px fine or 44px on touch, which a preset's dial may raise |
|
|
106
|
+
| `space.tight` | Inside a group — a label and its value, items in a list |
|
|
107
|
+
| `space.group` | Between groups inside a section |
|
|
108
|
+
| `space.section` | Between sections |
|
|
109
|
+
| `space.heading-above` · `space.heading-below` | The asymmetric pair around a heading. Their *ratio* is the rule, not their values |
|
|
110
|
+
| `radius.pill` · `radius.small` · `radius.control` · `radius.card` · `radius.container` | Smallest to outermost. Concentric corners obey inner = outer − padding; anything away from a corner takes a radius for its size |
|
|
111
|
+
| `hairline.chrome` · `hairline.object` · `rule.emphasis` | Divider weight inside chrome, the edge of an object, and a deliberate heavy rule (a quote bar, a focus ring) |
|
|
112
|
+
| `z.below` · `z.raised` · `z.popover` · `z.dismiss` · `z.nav` · `z.overlay` · `z.toast` · `z.skip-link` | The stacking ladder, low to high (layout law 7) |
|
|
113
|
+
| `bp.<name>` | Breakpoints, named for what changes at them, not for devices |
|
|
114
|
+
|
|
115
|
+
## Surfaces and depth
|
|
116
|
+
|
|
117
|
+
Owned by the depth guide.
|
|
118
|
+
|
|
119
|
+
| Role | Job |
|
|
120
|
+
|---|---|
|
|
121
|
+
| `elevation.flat` | In the page — separated by a border or a surface step, no shadow |
|
|
122
|
+
| `elevation.raised` | Lifted slightly — a card that can be picked up, a sticky header |
|
|
123
|
+
| `elevation.floating` | Over content, dismissable — menus, popovers, hover cards |
|
|
124
|
+
| `elevation.overlay` | Over everything, modal — dialogs, sheets |
|
|
125
|
+
| `material.opaque` | A solid surface |
|
|
126
|
+
| `material.translucent` | A see-through surface, if the system uses them at all. Tiers, when there are several, are named by how little is known about the backdrop: `.soften` (a backdrop meant to stay recognisable), `.chrome` (content scrolling under fixed chrome), `.defensive` (anything, including other glass) |
|
|
127
|
+
| `scrim` | The dimming layer behind a modal |
|
|
128
|
+
|
|
129
|
+
Each elevation level is a *bundle* — a surface, an edge, a shadow and a z-layer. The depth guide checks the bundle, not the parts.
|
|
130
|
+
|
|
131
|
+
## Motion
|
|
132
|
+
|
|
133
|
+
Owned by the motion guide.
|
|
134
|
+
|
|
135
|
+
| Role | Job |
|
|
136
|
+
|---|---|
|
|
137
|
+
| `duration.instant` | Press feedback, focus rings |
|
|
138
|
+
| `duration.micro` | Opacity and colour on hover |
|
|
139
|
+
| `duration.state` | Small state changes: colour, background, icon swaps, small transforms |
|
|
140
|
+
| `duration.popover` | Something small appearing: a hover card, a menu, a chevron |
|
|
141
|
+
| `duration.overlay` | Something large appearing or collapsing: a sheet, a region, a reveal |
|
|
142
|
+
| `duration.route` | A page transition |
|
|
143
|
+
| `duration.theme` | Every colour on the page changing at once — only when the page itself switches theme |
|
|
144
|
+
| `ease.standard` | The one curve almost everything uses |
|
|
145
|
+
| `ease.colour` | For colour-only interpolation, where an overshooting curve would wobble |
|
|
146
|
+
| `ease.exit` · `duration.exit` | Only if exits deliberately use a different curve, or a duration of their own rather than a shorter tier |
|
|
147
|
+
| `ease.floor` | A curve that never passes its target, for tracks carrying a property that can't go below zero (blur, scale to nothing) when `ease.standard` overshoots |
|
|
148
|
+
| `spring.<character>` | Springs named by how they feel — `snappy`, `soft`, `playful` — never by their numbers |
|
|
149
|
+
|
|
150
|
+
`duration.*` values must increase with the size of the change. That is the one rule a project can't rename away.
|