trykeyline 0.0.0-stage → 0.1.0
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 +37 -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/skills/keyline/SKILL.md +57 -0
- package/plugins/keyline/skills/keyline/commands/audit.md +25 -0
- package/plugins/keyline/skills/keyline/commands/color.md +7 -0
- package/plugins/keyline/skills/keyline/commands/critique.md +43 -0
- package/plugins/keyline/skills/keyline/commands/depth.md +7 -0
- package/plugins/keyline/skills/keyline/commands/init.md +15 -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 +29 -0
- package/plugins/keyline/skills/keyline/commands/sync.md +17 -0
- package/plugins/keyline/skills/keyline/commands/type.md +7 -0
- package/plugins/keyline/skills/keyline/domains/color/deriving-a-ramp.md +144 -0
- package/plugins/keyline/skills/keyline/domains/color/guide.md +243 -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 +191 -0
- package/plugins/keyline/skills/keyline/domains/depth/fallbacks-and-performance.md +132 -0
- package/plugins/keyline/skills/keyline/domains/depth/guide.md +255 -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 +284 -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 +234 -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 +216 -0
- package/plugins/keyline/skills/keyline/domains/patterns/iteration.md +78 -0
- package/plugins/keyline/skills/keyline/domains/type/display-tier.md +108 -0
- package/plugins/keyline/skills/keyline/domains/type/guide.md +251 -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 +90 -0
- package/plugins/keyline/skills/keyline/glass/color/assets/color-tokens.css +319 -0
- package/plugins/keyline/skills/keyline/glass/color/assets/theme.ts +119 -0
- package/plugins/keyline/skills/keyline/glass/color/guide.md +222 -0
- package/plugins/keyline/skills/keyline/glass/color/intent-ramp.md +136 -0
- package/plugins/keyline/skills/keyline/glass/color/theming.md +112 -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 +216 -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 +199 -0
- package/plugins/keyline/skills/keyline/glass/layout/guide.md +258 -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 +102 -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 +286 -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 +192 -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 +414 -0
- package/plugins/keyline/skills/keyline/glass/type/guide.md +222 -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 +294 -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 +101 -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, with an article's title clearly opening the piece (up to 2.25 × body); index and chrome titles lower. Two weights. A sans for interface text is allowed beside a serif reading face. Roles that share a size separate on weight, leading or a rule.
|
|
29
|
+
- **Colour** — near-monochrome. One accent, spent on focus. At most one further chromatic exception, justified structurally. Links usually in the text colour.
|
|
30
|
+
- **Layout** — one reading measure every page shares; rails and asides live outside it. Generous, asymmetric vertical rhythm.
|
|
31
|
+
- **Surfaces** — mostly flat. Elevation reserved for things that float; translucency, if any, only on chrome.
|
|
32
|
+
- **Motion** — short, and only where it makes a change legible. Nothing loops. One set piece, at most, once a session.
|
|
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. Two weights, strong at 500; labels in sentence case, never uppercase eyebrows. Tabular figures on every number, scoped to numeric elements.
|
|
39
|
+
- **Colour** — near-monochrome neutral ground with a real status palette (danger, warning, success, info), each a foreground/background pair. One accent hue for primary action, focus, selection (the current nav item on a 25% accent tint with accent icon and label) and the primary data series, and no second highlight hue. Brand colour already in the design stays where it has a job. Colour marks what needs a person, not what is finished. Colour for meaning, never for decoration.
|
|
40
|
+
- **Layout** — an app shell rather than a single measure: one navigation surface — a sidebar holding every destination, no top bar repeating it — then content and an optional inspector, every page under its own header bar, forms and settings capped at a form measure. Improving one screen keeps the navigation it has. Sections stack, each opened by its heading, and peer sections are parted by a full-bleed hairline; no bento mosaics or stat tiles. That is the default for a new system; an existing design keeps its own section device (`commands/refine.md`, the limits). Tighter spacing, still grouped asymmetrically. Prose inside the product (settings help, empty-state copy) still sits at a reading measure.
|
|
41
|
+
- **Surfaces** — content on the page, rows parted by hairlines; a data table may take one hairline frame; a settings group that saves together takes a hairline panel; a card only for one object, never a card in a card. A clear, small elevation ladder: flat page, raised cards, floating menus, modal overlays. Hairlines do more work than shadows.
|
|
42
|
+
- **Motion** — shortest of the three. State feedback is near-instant; nothing delays a repeated action. Springs only where something is dragged or thrown.
|
|
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 for it. Display, title and section headings fluid. Wider scale, still assigned to roles rather than derived from a ratio. Tracking correction matters most here.
|
|
49
|
+
- **Colour** — a brand palette used broadly, with rules about where each colour may go. Chromatic exceptions still named and counted, just more of them.
|
|
50
|
+
- **Layout** — sections may break the reading measure and go full-bleed; the measure still governs any paragraph longer than two lines.
|
|
51
|
+
- **Surfaces** — depth, gradients and translucency allowed as brand material, each with its fallback.
|
|
52
|
+
- **Motion** — longer and more characterful on entrances; exits still get out of the way. A few set pieces, each once. Reduced motion still gets a real alternative.
|
|
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 `glass/` into `DESIGN.md`, in the project's own names wherever the project already has names, and `glass/<domain>/guide.md` supplies the exact recipes, with drop-in token files and components under each `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 middle weight for dense UI 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 at about 25% over its surface, carrying `accent.ink` at 4.5:1 |
|
|
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 that clears 4.5:1 as text, and `status.<name>.bg`, a background tint — plus `status.<name>.solid` where a filled control needs it (a destructive button). Required in product systems, usually absent in editorial ones |
|
|
89
|
+
| `exception.<name>` | A deliberate chromatic spend outside the accent — one per system in editorial, a few in expressive; in product none by default, plus one hue family per question the reader can't answer at a glance, named `exception.<question>.<member>` (`exception.type.task`, `exception.area.<name>`, `exception.person.<n>`), each listed in `DESIGN.md`. Always named after what it's *for* |
|
|
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, ≈ 640–760px, 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: 24px under a fine pointer, 44px on touch |
|
|
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. `z.toast` sits over modals, because a notification about a modal's action must not hide behind it |
|
|
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` | 0 — 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.
|