@design-intelligence/ghost 0.21.0 → 0.22.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/README.md +47 -33
- package/dist/commands/fingerprint-commands.d.ts.map +1 -1
- package/dist/commands/fingerprint-commands.js +1 -6
- package/dist/commands/fingerprint-commands.js.map +1 -1
- package/dist/commands/gather-command.d.ts.map +1 -1
- package/dist/commands/gather-command.js +26 -30
- package/dist/commands/gather-command.js.map +1 -1
- package/dist/commands/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +1 -6
- package/dist/commands/init-command.js.map +1 -1
- package/dist/commands/pull-command.d.ts.map +1 -1
- package/dist/commands/pull-command.js +12 -19
- package/dist/commands/pull-command.js.map +1 -1
- package/dist/commands/pulse-command.js +1 -10
- package/dist/commands/pulse-command.js.map +1 -1
- package/dist/ghost-core/catalog/assemble.d.ts +0 -4
- package/dist/ghost-core/catalog/assemble.d.ts.map +1 -1
- package/dist/ghost-core/catalog/assemble.js +0 -10
- package/dist/ghost-core/catalog/assemble.js.map +1 -1
- package/dist/ghost-core/catalog/index.d.ts +1 -1
- package/dist/ghost-core/catalog/index.d.ts.map +1 -1
- package/dist/ghost-core/catalog/index.js +1 -1
- package/dist/ghost-core/catalog/index.js.map +1 -1
- package/dist/ghost-core/catalog/menu.d.ts +1 -11
- package/dist/ghost-core/catalog/menu.d.ts.map +1 -1
- package/dist/ghost-core/catalog/menu.js +1 -6
- package/dist/ghost-core/catalog/menu.js.map +1 -1
- package/dist/ghost-core/catalog/types.d.ts +0 -6
- package/dist/ghost-core/catalog/types.d.ts.map +1 -1
- package/dist/ghost-core/glossary.d.ts +0 -13
- package/dist/ghost-core/glossary.d.ts.map +1 -1
- package/dist/ghost-core/glossary.js +0 -7
- package/dist/ghost-core/glossary.js.map +1 -1
- package/dist/ghost-core/index.d.ts +2 -2
- package/dist/ghost-core/index.d.ts.map +1 -1
- package/dist/ghost-core/index.js +1 -1
- package/dist/ghost-core/index.js.map +1 -1
- package/dist/ghost-core/package-manifest.d.ts +7 -0
- package/dist/ghost-core/package-manifest.d.ts.map +1 -1
- package/dist/ghost-core/package-manifest.js +10 -0
- package/dist/ghost-core/package-manifest.js.map +1 -1
- package/dist/init-payloads/median/median-tells.md +25 -25
- package/dist/init-payloads/skeleton/brand.md +22 -0
- package/dist/init-payloads/skeleton/context.conversation.md +24 -0
- package/dist/init-payloads/skeleton/foundation.color.md +39 -0
- package/dist/init-payloads/skeleton/foundation.composition.md +30 -0
- package/dist/init-payloads/skeleton/foundation.controls.md +29 -0
- package/dist/init-payloads/skeleton/foundation.layout.md +45 -0
- package/dist/init-payloads/skeleton/foundation.motion.md +34 -0
- package/dist/init-payloads/skeleton/foundation.type.md +44 -0
- package/dist/init-payloads/skeleton/foundation.voice.md +29 -0
- package/dist/init-payloads/skeleton/glossary.md +27 -32
- package/dist/init-payloads/vessel-light/anti-goal.tells.md +5 -4
- package/dist/init-payloads/vessel-light/checks/shape-matches-job.md +43 -0
- package/dist/init-payloads/vessel-light/glossary.md +0 -1
- package/dist/init-payloads/vessel-light/grammar.color-roles.md +2 -2
- package/dist/init-payloads/vessel-light/grammar.deletion.md +35 -0
- package/dist/init-payloads/vessel-light/grammar.hierarchy.md +13 -3
- package/dist/init-payloads/vessel-light/grammar.job.md +54 -0
- package/dist/init-payloads/vessel-light/index.md +20 -24
- package/dist/init-payloads/vessel-light/manifest.yml +1 -0
- package/dist/init-payloads/vessel-light/materials/primitives.css +15 -52
- package/dist/init-payloads/vessel-light/materials/ref/composition.editorial.html +12 -7
- package/dist/init-payloads/vessel-light/materials/ref/composition.overlay.html +8 -2
- package/dist/init-payloads/vessel-light/materials/ref/composition.table.html +3 -3
- package/dist/init-payloads/vessel-light/materials/tokens.css +27 -78
- package/dist/init-payloads/vessel-light/signature.temperature.md +7 -0
- package/dist/init-payloads/vessel-light/signature.type.md +6 -5
- package/dist/observability-events.d.ts +0 -3
- package/dist/observability-events.d.ts.map +1 -1
- package/dist/observability-events.js.map +1 -1
- package/dist/review/resolve.d.ts +1 -2
- package/dist/review/resolve.d.ts.map +1 -1
- package/dist/review/resolve.js +4 -5
- package/dist/review/resolve.js.map +1 -1
- package/dist/review/review-packet.d.ts +0 -1
- package/dist/review/review-packet.d.ts.map +1 -1
- package/dist/review/review-packet.js +0 -19
- package/dist/review/review-packet.js.map +1 -1
- package/dist/scan/check-files.d.ts.map +1 -1
- package/dist/scan/check-files.js +0 -15
- package/dist/scan/check-files.js.map +1 -1
- package/dist/scan/check-scaffold.js +2 -2
- package/dist/scan/check-scaffold.js.map +1 -1
- package/dist/scan/fingerprint-package-lint.d.ts +8 -0
- package/dist/scan/fingerprint-package-lint.d.ts.map +1 -0
- package/dist/scan/fingerprint-package-lint.js +284 -0
- package/dist/scan/fingerprint-package-lint.js.map +1 -0
- package/dist/scan/fingerprint-package-loader.d.ts.map +1 -1
- package/dist/scan/fingerprint-package-loader.js +2 -29
- package/dist/scan/fingerprint-package-loader.js.map +1 -1
- package/dist/scan/fingerprint-package.d.ts +9 -7
- package/dist/scan/fingerprint-package.d.ts.map +1 -1
- package/dist/scan/fingerprint-package.js +18 -231
- package/dist/scan/fingerprint-package.js.map +1 -1
- package/dist/scan/node-files.d.ts.map +1 -1
- package/dist/scan/node-files.js +1 -3
- package/dist/scan/node-files.js.map +1 -1
- package/dist/scan/templates.d.ts.map +1 -1
- package/dist/scan/templates.js +43 -35
- package/dist/scan/templates.js.map +1 -1
- package/dist/skill-bundle/SKILL.md +15 -13
- package/dist/skill-bundle/references/adapting-a-starter.md +62 -60
- package/dist/skill-bundle/references/authoring-scenarios.md +6 -8
- package/dist/skill-bundle/references/brief.md +5 -6
- package/dist/skill-bundle/references/capture.md +47 -36
- package/dist/skill-bundle/references/concrete-tiers.md +95 -0
- package/dist/skill-bundle/references/recall.md +6 -12
- package/dist/skill-bundle/references/schema.md +15 -24
- package/dist/skill-bundle/references/self-check.md +2 -2
- package/dist/skill-bundle/references/steering-audit.md +7 -10
- package/package.json +1 -1
- package/dist/init-payloads/skeleton/grammar.color-roles.md +0 -26
- package/dist/init-payloads/skeleton/grammar.conversation.md +0 -23
- package/dist/init-payloads/skeleton/grammar.hierarchy.md +0 -39
- package/dist/init-payloads/skeleton/grammar.motion.md +0 -24
- package/dist/init-payloads/skeleton/grammar.rhythm.md +0 -23
- package/dist/init-payloads/skeleton/grammar.surfaces.md +0 -26
- package/dist/init-payloads/skeleton/index.md +0 -27
- package/dist/init-payloads/skeleton/signature.palette.md +0 -24
- package/dist/init-payloads/skeleton/signature.shape.md +0 -19
- package/dist/init-payloads/skeleton/signature.temperature.md +0 -20
- package/dist/init-payloads/skeleton/signature.type.md +0 -22
- package/dist/skill-bundle/references/wild.md +0 -30
- /package/dist/init-payloads/median/{anti-goal.median.md → cliche.median.md} +0 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Layout — stacks with five gap steps, surface roles, three elevation tiers, the two radius roles, and misuse; radius values are an open question. Read before laying anything out."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
All layout is stacks. Rhythm comes from relationships between siblings, not
|
|
8
|
+
from isolated margins pasted onto whichever element was last touched. The
|
|
9
|
+
gap steps are exactly five: `--gap-xs` through `--gap-xl`. Choose the gap
|
|
10
|
+
that states the relationship; do not tune by single pixels to make a
|
|
11
|
+
screenshot pass. The default is column, medium gap. Columns are for almost
|
|
12
|
+
everything — forms, cards, modal bodies, settings, page sections. Rows are
|
|
13
|
+
conditional: controls, metadata lines, paired label/value moments. If a row
|
|
14
|
+
wraps awkwardly, it wanted to be a column.
|
|
15
|
+
|
|
16
|
+
Surface is the only way an element gets a background, border, radius, or
|
|
17
|
+
shadow. The vocabulary is closed: role, padding, radius, border, elevation.
|
|
18
|
+
The default surface is flat — no border, no shadow. We do not outline
|
|
19
|
+
everything to prove layout exists.
|
|
20
|
+
|
|
21
|
+
The elevation tiers are exactly three: card, popover, modal. Elevation
|
|
22
|
+
implies hierarchy — a card sits in flow, a popover floats above it, a modal
|
|
23
|
+
interrupts the task. Pick the tier that matches the interaction.
|
|
24
|
+
|
|
25
|
+
Borders are structural — inputs and overlays — not decorative frames around
|
|
26
|
+
ordinary text. Use space, tone, and type hierarchy instead.
|
|
27
|
+
|
|
28
|
+
## Radius
|
|
29
|
+
|
|
30
|
+
Open — ask the human; do not freehand. The fixed relationship: controls and
|
|
31
|
+
surfaces carry different radius roles, and the two never swap. Buttons and
|
|
32
|
+
inputs take `--radius-control`; cards and containers take
|
|
33
|
+
`--radius-surface`. One radius for what you click, one for what contains.
|
|
34
|
+
The open question: how round is a control, and how round is a surface? When
|
|
35
|
+
answered, restate this section as the brand's current answer. Until then,
|
|
36
|
+
choose provisional values and label them.
|
|
37
|
+
|
|
38
|
+
## Misuse
|
|
39
|
+
|
|
40
|
+
- No ad-hoc margins between siblings — they hide the rhythm. Change the
|
|
41
|
+
stack gap or split the stack.
|
|
42
|
+
- No custom shadows because a composition feels flat, and no modal gravity
|
|
43
|
+
on a routine card. Component shadows belong to the primitives that own
|
|
44
|
+
them.
|
|
45
|
+
- Never one radius everywhere by reflex.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Motion — evidence of state change, three durations and one ease, nothing loops, and misuse; the ease's character is an open question shared with voice. Read for any transition or hover treatment."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Motion is evidence of a state change. It confirms hover, press, reveal,
|
|
8
|
+
collapse, entrance, exit, and spatial movement. It does not entertain.
|
|
9
|
+
|
|
10
|
+
The entire vocabulary is three duration roles and one ease. Fast is for
|
|
11
|
+
hover and press. Normal is for reveals, fades, and small state changes. Slow
|
|
12
|
+
is reserved for spatial transitions where the user needs to understand
|
|
13
|
+
movement. Prefer opacity and small transforms.
|
|
14
|
+
|
|
15
|
+
In editorial and marketing contexts, entrances may be staged — scroll
|
|
16
|
+
reveals and section transitions are part of editorial rhythm, still built
|
|
17
|
+
from the three durations and the one ease. In product UI the same staging is
|
|
18
|
+
decoration.
|
|
19
|
+
|
|
20
|
+
## Character
|
|
21
|
+
|
|
22
|
+
Open — ask the human; do not freehand. Motion and voice share one
|
|
23
|
+
temperature: however warm or cool the brand's words are, its movement
|
|
24
|
+
matches. See the voice foundation for the other half of this answer. The
|
|
25
|
+
open question here: what character does the one ease carry? When answered,
|
|
26
|
+
restate this section. Until then, use a quiet standard ease and label it
|
|
27
|
+
provisional.
|
|
28
|
+
|
|
29
|
+
## Misuse
|
|
30
|
+
|
|
31
|
+
- Nothing loops except explicit loading states. Decorative pulsing,
|
|
32
|
+
floating, glowing, and attention-seeking keyframes are off-language.
|
|
33
|
+
- No novelty easings because a surface feels static.
|
|
34
|
+
- If removing an animation does not reduce comprehension, it was decoration.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Type — six text variants, seven tones, the one-voice rule, and misuse; the typeface is an open question. Read for any view that contains text."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Hierarchy is a closed vocabulary, not a size slider. Every piece of text
|
|
8
|
+
picks from a named set; anything outside the set is a broken primitive, not
|
|
9
|
+
a variant.
|
|
10
|
+
|
|
11
|
+
The text variants are exactly six: display, headline, title, body, label,
|
|
12
|
+
mono. Variant names are jobs. Display leads a rare editorial moment.
|
|
13
|
+
Headline names a section. Title anchors a card, dialog, or compact region.
|
|
14
|
+
Body carries reading. Label names structure — field labels, category tags,
|
|
15
|
+
metadata, compact status. Mono carries code and machine detail.
|
|
16
|
+
|
|
17
|
+
The tones are exactly seven: default, muted, inverse, success, warning,
|
|
18
|
+
info, destructive. Tone is part of the message. Hierarchy starts with tone
|
|
19
|
+
and weight before size — a secondary note usually wants muted body or label,
|
|
20
|
+
not a smaller custom font. If prose needs emphasis, improve the sentence
|
|
21
|
+
before adding a style.
|
|
22
|
+
|
|
23
|
+
The heading scale is editorial: it exists for pages composed outside the
|
|
24
|
+
text variants — heroes and editorial moments. Product UI never mixes the two
|
|
25
|
+
vocabularies in one view. A modal title is not a poster.
|
|
26
|
+
|
|
27
|
+
Balanced text is for headings and compact statements, never long body copy.
|
|
28
|
+
|
|
29
|
+
## Typeface
|
|
30
|
+
|
|
31
|
+
Open — ask the human; do not freehand. The fixed relationship: one typeface
|
|
32
|
+
is the voice of the interface, everywhere, with a mono partner only for
|
|
33
|
+
code, tool detail, and machine output. The open question: what typeface is
|
|
34
|
+
this brand's voice, what mono partners it, and what rhythm does the
|
|
35
|
+
editorial heading scale carry? When answered, restate this section as the
|
|
36
|
+
brand's current answer. Until then, choose a quiet provisional pair and
|
|
37
|
+
label it provisional.
|
|
38
|
+
|
|
39
|
+
## Misuse
|
|
40
|
+
|
|
41
|
+
- No faked hierarchy with arbitrary font sizes. Choose the variant that
|
|
42
|
+
matches the job.
|
|
43
|
+
- Status tones appear only when the words carry that state meaning.
|
|
44
|
+
- Never a second display face to make a view feel branded.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Voice and tone — copy states facts, no performed personality, and misuse; warmth is an open question shared with motion. Read for any copy."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
Copy states what happened, what is possible, or what the user must decide.
|
|
8
|
+
It does not perform personality. Confidence comes from precision, not
|
|
9
|
+
enthusiasm.
|
|
10
|
+
|
|
11
|
+
Voice and motion carry the same temperature: a brand whose copy is warm does
|
|
12
|
+
not move coldly, and a brand whose copy is spare does not bounce. When you
|
|
13
|
+
set one, check the other.
|
|
14
|
+
|
|
15
|
+
## Warmth
|
|
16
|
+
|
|
17
|
+
Open — ask the human; do not freehand. The open question: how warm or cool
|
|
18
|
+
does this brand sound — and, by the shared temperature, how does it move?
|
|
19
|
+
See the motion foundation for the other half. When answered, restate this
|
|
20
|
+
section as the brand's current answer. Until then, write plainly and label
|
|
21
|
+
the tone provisional.
|
|
22
|
+
|
|
23
|
+
## Misuse
|
|
24
|
+
|
|
25
|
+
- No exclamation points as a substitute for having something to say.
|
|
26
|
+
- No apologizing for the interface ("Oops!"). State the fact and the next
|
|
27
|
+
step.
|
|
28
|
+
- Never restate this section as answered when it was your own provisional
|
|
29
|
+
choice.
|
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
---
|
|
2
2
|
kinds:
|
|
3
|
-
- name:
|
|
4
|
-
- name:
|
|
5
|
-
- name:
|
|
6
|
-
- name: anti-goal
|
|
7
|
-
posture: guard
|
|
3
|
+
- name: foundation
|
|
4
|
+
- name: context
|
|
5
|
+
- name: cliche
|
|
8
6
|
---
|
|
9
7
|
|
|
10
|
-
#
|
|
8
|
+
# foundation
|
|
11
9
|
|
|
12
|
-
The
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
The core elements — color, type, controls, layout, motion, voice — plus
|
|
11
|
+
composition, the rules for assembling them into a view. Each foundation
|
|
12
|
+
node is a chapter: usage rules that hold no matter what the brand values
|
|
13
|
+
turn out to be, the brand's open questions (unanswered in this starter,
|
|
14
|
+
marked as decisions only a human can make), and the chapter's misuse list.
|
|
15
|
+
Follow the usage rules as written. Never fill in an open value and present
|
|
16
|
+
it as the brand's.
|
|
16
17
|
|
|
17
|
-
#
|
|
18
|
+
# context
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
before setting any value a dial governs.
|
|
20
|
+
Where the defaults bend: a context names a situation — an AI conversation
|
|
21
|
+
thread, a data-dense console, a transactional email — and states only what
|
|
22
|
+
inverts there. Read a context only when its situation matches the task.
|
|
23
|
+
Rules from the wrong context are contamination, not guidance.
|
|
24
24
|
|
|
25
|
-
#
|
|
25
|
+
# cliche
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
task. This starter declares the kind and ships no register nodes: registers
|
|
32
|
-
invert answered defaults, and the dials are not answered yet.
|
|
33
|
-
|
|
34
|
-
# anti-goal
|
|
35
|
-
|
|
36
|
-
What this package refuses, each reject paired with its replacement.
|
|
37
|
-
`anti-goal.median` is the model's floor, not the brand's taste. Gather
|
|
38
|
-
anti-goals before styling anything greenfield.
|
|
27
|
+
The defaults a generative model falls back on when no brand is steering it.
|
|
28
|
+
These are nobody's brand. Each entry pairs the tired move with the honest
|
|
29
|
+
replacement. Gather before styling anything greenfield; enforced by paired
|
|
30
|
+
checks at review.
|
|
39
31
|
|
|
40
32
|
---
|
|
41
33
|
|
|
42
|
-
The
|
|
43
|
-
|
|
44
|
-
|
|
34
|
+
The cover node (`brand.md`, declared in the manifest) is the one page always
|
|
35
|
+
in context: what the brand is, its temperature, and the refusals only it
|
|
36
|
+
makes. The ghost skill's `adapting-a-starter` recipe is the procedure for
|
|
37
|
+
growing this skeleton into a real fingerprint: write the cover, answer each
|
|
38
|
+
chapter's open question, prune the cliches your chapters absorb, then add
|
|
39
|
+
materials and refs.
|
|
@@ -4,7 +4,9 @@ description: "Failure modes specific to this brand's own signature — gather al
|
|
|
4
4
|
|
|
5
5
|
These are the near-misses of Vessel's own signature: outputs that got close
|
|
6
6
|
enough to cite the brand and still missed it. Each reject names its
|
|
7
|
-
replacement.
|
|
7
|
+
replacement. When a tell fires, the fix direction is always toward the
|
|
8
|
+
token, the role, or deletion — never toward adding a compensating style on
|
|
9
|
+
top of the miss.
|
|
8
10
|
|
|
9
11
|
Reject rectangular buttons. A rectangular button is not a variant; it is a
|
|
10
12
|
different design system → controls take `--radius-control`, the pill.
|
|
@@ -21,9 +23,8 @@ Vessel; it is a different brand.
|
|
|
21
23
|
Reject custom shadows that sit near a tier → the exact tier — card, popover,
|
|
22
24
|
or modal — chosen by interaction importance.
|
|
23
25
|
|
|
24
|
-
Reject borrowing `--shadow-btn`
|
|
25
|
-
|
|
26
|
-
the three tiers.
|
|
26
|
+
Reject borrowing `--shadow-btn` for layout → component shadows belong to the
|
|
27
|
+
primitives that own them; layout elevation comes from the three tiers.
|
|
27
28
|
|
|
28
29
|
Reject editorial display type in product UI, and product type timidity in
|
|
29
30
|
editorial → each register keeps its own vocabulary; a modal title is not a
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Shape matches the job
|
|
3
|
+
description: Flags views composed for the wrong reader job — a form styled as a table, an announcement headline over a reviewable artifact, a live state presented as settled fact, a second primary, or a skeleton loader standing in for content.
|
|
4
|
+
severity: high
|
|
5
|
+
references:
|
|
6
|
+
- grammar.job
|
|
7
|
+
- grammar.deletion
|
|
8
|
+
- grammar.hierarchy
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Apply this check to diffs that add or restructure a view. Classify the
|
|
12
|
+
reader's job first — what they do next with the view — then judge the
|
|
13
|
+
composition against the ref that job routes to. These flags catch the
|
|
14
|
+
template-convergence failure: a plausible layout applied to a job it does
|
|
15
|
+
not fit.
|
|
16
|
+
|
|
17
|
+
Flag a view whose job routes to one ref but whose composition imitates
|
|
18
|
+
another — a submit-and-done task laid out as a dashboard of cards, a
|
|
19
|
+
records-scanning task rendered as prose sections, a stop-and-decide moment
|
|
20
|
+
inlined into the page instead of interrupting it. (`grammar.job`)
|
|
21
|
+
|
|
22
|
+
Flag an announcement headline in display or headline type above an artifact
|
|
23
|
+
the reader will review — "Here's your draft", "Your plan is ready", "All
|
|
24
|
+
set". The artifact opens the view; status lives in quiet metadata or
|
|
25
|
+
nowhere. (`grammar.job`)
|
|
26
|
+
|
|
27
|
+
Flag a live or ongoing value presented without its freshness — no timestamp
|
|
28
|
+
or "updated" line in muted metadata near the figure. A moving value styled
|
|
29
|
+
as a settled fact misleads. (`grammar.job`)
|
|
30
|
+
|
|
31
|
+
Flag recommendation or verdict framing where the decision belongs to the
|
|
32
|
+
reader and the system cannot honestly rank the options. Present the
|
|
33
|
+
material; withhold the verdict. (`grammar.job`)
|
|
34
|
+
|
|
35
|
+
Flag a second primary-variant action in a view, and flag a promoted primary
|
|
36
|
+
on a view that honestly earns none — a steady status view, an open
|
|
37
|
+
comparison. Zero is a valid spend of `--primary-budget`.
|
|
38
|
+
(`grammar.hierarchy`)
|
|
39
|
+
|
|
40
|
+
Flag skeleton loaders, placeholder shimmer, or staged construction where
|
|
41
|
+
content will land — and any element that cannot name what breaks if it is
|
|
42
|
+
removed. The fix is demotion or deletion, never more emphasis.
|
|
43
|
+
(`grammar.deletion`)
|
|
@@ -11,8 +11,8 @@ may not author around them. Raw color values are implementation detail, never
|
|
|
11
11
|
product language.
|
|
12
12
|
|
|
13
13
|
Author with semantic roles: `background`, `foreground`, `card`, `popover`,
|
|
14
|
-
`primary`, `secondary`, `muted`, `
|
|
15
|
-
|
|
14
|
+
`primary`, `secondary`, `muted`, `border`, `input`, `ring`, and the status
|
|
15
|
+
roles. If a container needs a color, it first needs a role.
|
|
16
16
|
|
|
17
17
|
The status roles — destructive, success, warning, info — exist only when
|
|
18
18
|
meaning demands them. Destructive means destructive or error. Success means
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "The deletion pass — every element must name what breaks if it goes; the fix for a crowded view is always demotion or deletion, never more emphasis; surfaces arrive settled, with no skeleton theater. Gather as the final pass over any composition, and whenever a view feels crowded, busy, or dressed up."
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
Restraint is not a mood; it is a test every element has to pass. Before a
|
|
6
|
+
view ships, run the pass: each label, divider, icon, caption, and helper
|
|
7
|
+
line must name what breaks if it is removed. If nothing breaks, delete it.
|
|
8
|
+
Convention is not a reason — "forms usually have this" keeps nothing.
|
|
9
|
+
|
|
10
|
+
The test has a direction. When a view is crowded, or two elements compete
|
|
11
|
+
for attention, the fix is always demotion or deletion — never adding
|
|
12
|
+
emphasis to the loser. Raising the volume of one element to beat another
|
|
13
|
+
starts an arms race the composition always loses; removing the weaker claim
|
|
14
|
+
ends it.
|
|
15
|
+
|
|
16
|
+
Some deletions we have already made, permanently: no decorative dividers
|
|
17
|
+
where a gap step states the relationship; no icons that restate their
|
|
18
|
+
adjacent label; no tooltips explaining obvious controls; no onboarding
|
|
19
|
+
chrome on routine views; no credibility costume — a small factual source or
|
|
20
|
+
timestamp line beats a dashboard of gauges.
|
|
21
|
+
|
|
22
|
+
A view also arrives settled. No skeleton loaders, no placeholder shimmer
|
|
23
|
+
promising content that is not there — a fake page is hedging rendered as UI.
|
|
24
|
+
While work is genuinely pending, show the smallest true statement (a quiet
|
|
25
|
+
loading state, per the motion doctrine's loop exception) and nothing else.
|
|
26
|
+
When content lands, it lands in its final position: no reflow, no staggered
|
|
27
|
+
construction, no element arriving late to shift its neighbors.
|
|
28
|
+
|
|
29
|
+
Do: a settings page whose every row survives the what-breaks question, with
|
|
30
|
+
one primary action and gaps doing the dividing. Never: the same page with
|
|
31
|
+
icon-per-row decoration, a divider under every group, a progress shimmer on
|
|
32
|
+
load, and a bolded second CTA competing for the eye.
|
|
33
|
+
|
|
34
|
+
After everything deletable is gone, whatever remains is unmistakably the
|
|
35
|
+
point.
|
|
@@ -28,9 +28,13 @@ wants muted body or label, not a smaller custom font. If the prose needs
|
|
|
28
28
|
emphasis, improve the sentence before adding a style.
|
|
29
29
|
|
|
30
30
|
The control emphasis ladder is exactly five rungs: primary, secondary,
|
|
31
|
-
outline, ghost, link.
|
|
32
|
-
else steps down the ladder. Primary is
|
|
33
|
-
complete — if two buttons both look
|
|
31
|
+
outline, ghost, link. At most one primary action per view is the rule
|
|
32
|
+
(`--primary-budget: 1`); everything else steps down the ladder. Primary is
|
|
33
|
+
for the action the screen exists to complete — if two buttons both look
|
|
34
|
+
primary, the hierarchy failed. And some views honestly earn none: a steady
|
|
35
|
+
status view or an open comparison has no action the screen exists to
|
|
36
|
+
complete, and promoting one anyway puts the system's thumb on the scale.
|
|
37
|
+
Zero is a valid spend.
|
|
34
38
|
Destructive is a meaning, not a rung: it is rare, it names the destructive
|
|
35
39
|
act directly, and it is never borrowed for urgency, emphasis, or brand heat.
|
|
36
40
|
|
|
@@ -40,6 +44,12 @@ guidance, not decoration. Errors state facts next to the field that caused
|
|
|
40
44
|
them — do not hide field errors in modals, toasts, or generic banners when
|
|
41
45
|
the user needs to fix one input.
|
|
42
46
|
|
|
47
|
+
Figures that will be compared or scanned — amounts, counts, dates in
|
|
48
|
+
columns, any metric — set in tabular numerals (`--numeric-tabular`), with
|
|
49
|
+
the unit tight to the number. Proportional figures in a data column wobble,
|
|
50
|
+
and a wobbling column reads as sloppy arithmetic. Mono already carries this
|
|
51
|
+
for machine detail; the rule extends to any numeric data in product UI.
|
|
52
|
+
|
|
43
53
|
Balanced text is for headings and compact statements. Do not balance long
|
|
44
54
|
body copy into jagged reading.
|
|
45
55
|
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "The routing rule — name the reader's job before composing anything; the job picks the ref to imitate and the register that applies, never the topic. Gather first for any new view, before structure exists."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/ref/composition.form.html
|
|
5
|
+
- materials/ref/composition.table.html
|
|
6
|
+
- materials/ref/composition.editorial.html
|
|
7
|
+
- materials/ref/composition.overlay.html
|
|
8
|
+
- materials/ref/composition.conversation.html
|
|
9
|
+
- materials/ref/email.html
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
Before any structure exists, name what the reader does next with the view.
|
|
13
|
+
The topic never picks the shape; the reader's job does. A billing question
|
|
14
|
+
is not "a billing page" — it is a form to fill, a table to scan, a decision
|
|
15
|
+
to confirm, or a thread to continue, and each of those is a different
|
|
16
|
+
composition. A view built for the wrong job does not merely look off; it
|
|
17
|
+
misleads.
|
|
18
|
+
|
|
19
|
+
The jobs and where they route:
|
|
20
|
+
|
|
21
|
+
- **Fill something in** — settings, signup, any submit-and-done task → the
|
|
22
|
+
form ref. Stacked labels and fields, one submit, secondary escape.
|
|
23
|
+
- **Scan and compare records** — lists, audits, anything with rows and
|
|
24
|
+
figures → the table ref, in the data-density register.
|
|
25
|
+
- **Read a narrative** — a landing page, an announcement, a story → the
|
|
26
|
+
editorial ref, in the editorial register.
|
|
27
|
+
- **Stop and decide** — a confirmation, a destructive act, a choice that
|
|
28
|
+
interrupts the task → the overlay ref. The decision is the view.
|
|
29
|
+
- **Converse with the system** — an AI thread, an agent console, a prompt
|
|
30
|
+
composer → the conversation ref.
|
|
31
|
+
- **Be notified elsewhere** — receipts, alerts, anything that lands in an
|
|
32
|
+
inbox → the email ref, in the email register.
|
|
33
|
+
|
|
34
|
+
Read the request's verbs, not its nouns: "edit / set up / submit" routes to
|
|
35
|
+
form; "compare / list / review the records" to table; "announce / tell the
|
|
36
|
+
story" to editorial; "confirm / are you sure" to overlay; "ask / draft with
|
|
37
|
+
me" to conversation. When two jobs fold into one request, build for the job
|
|
38
|
+
the reader performs on this view, now — the other job is the next view. When
|
|
39
|
+
a job fits none of these, compose from the grammar and say so; do not force
|
|
40
|
+
the nearest ref.
|
|
41
|
+
|
|
42
|
+
Three shapes lie about the job, and we refuse them everywhere:
|
|
43
|
+
|
|
44
|
+
- A view whose content is an artifact the reader will review — a draft, a
|
|
45
|
+
filled form, a generated plan — leads with the artifact, never with an
|
|
46
|
+
announcement headline. "Here's your draft" in display type demotes the
|
|
47
|
+
actual deliverable; the artifact sitting there with its actions is the
|
|
48
|
+
statement that it is ready.
|
|
49
|
+
- A view reporting a live or ongoing state carries its freshness — "updated
|
|
50
|
+
2 min ago" — in quiet metadata. Presenting a moving value as a settled
|
|
51
|
+
fact is a small lie the reader eventually catches.
|
|
52
|
+
- A view where the decision belongs to the reader presents the material and
|
|
53
|
+
withholds the verdict. Recommendation framing on a choice the system
|
|
54
|
+
cannot honestly make is manufactured confidence, and it reads that way.
|
|
@@ -5,33 +5,29 @@ materials:
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
vessel-light is Vessel without the React package: the design language as a
|
|
8
|
-
|
|
8
|
+
steering packet for agents writing raw HTML and CSS.
|
|
9
9
|
|
|
10
10
|
The contract is narrow. Style only with the tokens. Compose only with the
|
|
11
|
-
closed sets the grammar enumerates. Imitate the refs when the task matches
|
|
12
|
-
|
|
11
|
+
closed sets the grammar enumerates. Imitate the refs when the task matches —
|
|
12
|
+
worked examples to copy from, not a framework to import.
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
conditions apply, because truths from the wrong register are poison, not
|
|
21
|
-
context.
|
|
14
|
+
Grammar and the median floor are safe verbatim, unchanged by any adaptation.
|
|
15
|
+
Signature nodes state Vessel's current answer and stand until you replace
|
|
16
|
+
them. Registers — editorial, email, and data-density — name the situations
|
|
17
|
+
where parts of the default contract invert; pull only the nodes whose
|
|
18
|
+
conditions match the task, because truths from the wrong register are
|
|
19
|
+
poison, not context.
|
|
22
20
|
|
|
23
|
-
|
|
21
|
+
Monochrome comes first. Status color is functional language — danger,
|
|
22
|
+
success, warning, information — never atmosphere. Atmosphere is catered: a
|
|
23
|
+
five-hue expression palette whose volume rises with the register, from
|
|
24
|
+
charts-only in product to two hues in editorial, and never on controls.
|
|
24
25
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
it is catered: a five-hue expression palette whose volume rises with the
|
|
28
|
-
register, from charts-only in product to two hues in editorial, and never on
|
|
29
|
-
controls.
|
|
26
|
+
It protects the taste that disappears when an agent freehands: quiet
|
|
27
|
+
surfaces, deliberate spacing, one obvious action, restrained motion.
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
not invent a new styling system. If the result needs a new pattern, the new
|
|
37
|
-
pattern should come from observed drift, not anticipation.
|
|
29
|
+
Name the reader's job before composing anything — the job picks the ref and
|
|
30
|
+
the register, never the topic. When a requested UI is not covered by a ref,
|
|
31
|
+
compose from the grammar; do not invent a new styling system. Before
|
|
32
|
+
anything ships, run the deletion pass: every element names what breaks if
|
|
33
|
+
it goes, and the view arrives settled.
|
|
@@ -30,42 +30,24 @@ body {
|
|
|
30
30
|
background: var(--muted);
|
|
31
31
|
color: var(--foreground);
|
|
32
32
|
}
|
|
33
|
-
.surface--accent {
|
|
34
|
-
background: var(--accent);
|
|
35
|
-
color: var(--accent-foreground);
|
|
36
|
-
}
|
|
37
|
-
.surface--dark {
|
|
38
|
-
background: var(--surface-dark);
|
|
39
|
-
color: var(--surface-dark-text);
|
|
40
|
-
border-color: var(--surface-dark-border);
|
|
41
|
-
}
|
|
42
33
|
.surface--pad-xs {
|
|
43
|
-
padding:
|
|
34
|
+
padding: var(--gap-sm);
|
|
44
35
|
}
|
|
45
36
|
.surface--pad-sm {
|
|
46
|
-
padding: 12px;
|
|
37
|
+
padding: 12px; /* off-scale surface geometry: between --gap-sm and --gap-md */
|
|
47
38
|
}
|
|
48
39
|
.surface--pad-md {
|
|
49
|
-
padding:
|
|
40
|
+
padding: var(--gap-md);
|
|
50
41
|
}
|
|
51
42
|
.surface--pad-lg {
|
|
52
|
-
padding:
|
|
43
|
+
padding: var(--gap-lg);
|
|
53
44
|
}
|
|
54
45
|
.surface--radius-sm {
|
|
55
46
|
border-radius: var(--radius-sm);
|
|
56
47
|
}
|
|
57
|
-
.surface--radius-md {
|
|
58
|
-
border-radius: var(--radius-md);
|
|
59
|
-
}
|
|
60
|
-
.surface--radius-lg {
|
|
61
|
-
border-radius: var(--radius-lg);
|
|
62
|
-
}
|
|
63
48
|
.surface--radius-surface {
|
|
64
49
|
border-radius: var(--radius-surface);
|
|
65
50
|
}
|
|
66
|
-
.surface--radius-control {
|
|
67
|
-
border-radius: var(--radius-control);
|
|
68
|
-
}
|
|
69
51
|
.surface--border {
|
|
70
52
|
border: 1px solid var(--border);
|
|
71
53
|
}
|
|
@@ -121,9 +103,6 @@ body {
|
|
|
121
103
|
.stack--align-end {
|
|
122
104
|
align-items: flex-end;
|
|
123
105
|
}
|
|
124
|
-
.stack--align-baseline {
|
|
125
|
-
align-items: baseline;
|
|
126
|
-
}
|
|
127
106
|
.stack--justify-center {
|
|
128
107
|
justify-content: center;
|
|
129
108
|
}
|
|
@@ -143,25 +122,25 @@ body {
|
|
|
143
122
|
color: var(--foreground);
|
|
144
123
|
font-family: var(--font-sans);
|
|
145
124
|
font-size: var(--text-body-size);
|
|
146
|
-
line-height:
|
|
125
|
+
line-height: var(--text-body-line-height);
|
|
147
126
|
}
|
|
148
127
|
.text--display {
|
|
149
128
|
font-size: var(--heading-display-font-size);
|
|
150
|
-
font-weight:
|
|
151
|
-
line-height:
|
|
129
|
+
font-weight: var(--heading-display-font-weight);
|
|
130
|
+
line-height: var(--heading-display-line-height);
|
|
152
131
|
letter-spacing: var(--heading-display-letter-spacing);
|
|
153
132
|
}
|
|
154
133
|
.text--headline {
|
|
155
134
|
font-size: var(--text-headline-size);
|
|
156
135
|
font-weight: 400;
|
|
157
136
|
line-height: 1.25;
|
|
158
|
-
letter-spacing: -
|
|
137
|
+
letter-spacing: var(--text-heading-letter-spacing);
|
|
159
138
|
}
|
|
160
139
|
.text--title {
|
|
161
140
|
font-size: var(--text-title-size);
|
|
162
141
|
font-weight: 600;
|
|
163
142
|
line-height: 1;
|
|
164
|
-
letter-spacing: -
|
|
143
|
+
letter-spacing: var(--text-heading-letter-spacing);
|
|
165
144
|
}
|
|
166
145
|
.text--label {
|
|
167
146
|
font-size: var(--label-font-size);
|
|
@@ -201,7 +180,7 @@ body {
|
|
|
201
180
|
gap: var(--gap-sm);
|
|
202
181
|
min-width: 0;
|
|
203
182
|
height: var(--control-height);
|
|
204
|
-
padding:
|
|
183
|
+
padding: var(--gap-sm) var(--gap-lg);
|
|
205
184
|
border: 1px solid transparent;
|
|
206
185
|
border-radius: var(--radius-control);
|
|
207
186
|
background: var(--primary);
|
|
@@ -237,8 +216,8 @@ body {
|
|
|
237
216
|
color: var(--primary-foreground);
|
|
238
217
|
}
|
|
239
218
|
.button--secondary {
|
|
240
|
-
background: var(--
|
|
241
|
-
color: var(--foreground);
|
|
219
|
+
background: var(--secondary);
|
|
220
|
+
color: var(--secondary-foreground);
|
|
242
221
|
}
|
|
243
222
|
.button--ghost {
|
|
244
223
|
background: transparent;
|
|
@@ -271,43 +250,27 @@ body {
|
|
|
271
250
|
color: var(--muted-foreground);
|
|
272
251
|
box-shadow: none;
|
|
273
252
|
}
|
|
274
|
-
.button--size-xs {
|
|
275
|
-
height: 24px;
|
|
276
|
-
padding: 4px 8px;
|
|
277
|
-
gap: var(--gap-xs);
|
|
278
|
-
font-size: 12px;
|
|
279
|
-
}
|
|
280
253
|
.button--size-sm {
|
|
281
254
|
height: 32px;
|
|
282
|
-
padding: 6px
|
|
255
|
+
padding: 6px var(--gap-md);
|
|
283
256
|
gap: 6px;
|
|
284
257
|
}
|
|
285
258
|
.button--size-lg {
|
|
286
259
|
height: 40px;
|
|
287
|
-
padding:
|
|
260
|
+
padding: var(--gap-sm) var(--gap-xl);
|
|
288
261
|
}
|
|
289
262
|
.button--icon,
|
|
290
|
-
.button--icon-sm
|
|
291
|
-
.button--icon-xs,
|
|
292
|
-
.button--icon-lg {
|
|
263
|
+
.button--icon-sm {
|
|
293
264
|
padding: 0;
|
|
294
265
|
}
|
|
295
266
|
.button--icon {
|
|
296
267
|
width: var(--control-height);
|
|
297
268
|
height: var(--control-height);
|
|
298
269
|
}
|
|
299
|
-
.button--icon-xs {
|
|
300
|
-
width: 24px;
|
|
301
|
-
height: 24px;
|
|
302
|
-
}
|
|
303
270
|
.button--icon-sm {
|
|
304
271
|
width: 32px;
|
|
305
272
|
height: 32px;
|
|
306
273
|
}
|
|
307
|
-
.button--icon-lg {
|
|
308
|
-
width: 40px;
|
|
309
|
-
height: 40px;
|
|
310
|
-
}
|
|
311
274
|
|
|
312
275
|
/* field — defaults: label plus pill input with input border, muted placeholder, ring focus, compact error. */
|
|
313
276
|
.field {
|