@design-intelligence/ghost 0.20.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/checks-command.d.ts.map +1 -1
- package/dist/commands/checks-command.js +8 -1
- package/dist/commands/checks-command.js.map +1 -1
- 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 +23 -13
- 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/commands/review-command.d.ts.map +1 -1
- package/dist/commands/review-command.js +1 -0
- package/dist/commands/review-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/cliche.median.md +86 -0
- package/dist/init-payloads/median/median-tells.md +117 -0
- 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 +39 -0
- package/dist/init-payloads/vessel-light/anti-goal.median.md +86 -0
- package/dist/init-payloads/vessel-light/anti-goal.tells.md +38 -0
- package/dist/init-payloads/vessel-light/checks/conversation-grammar.md +20 -0
- package/dist/init-payloads/vessel-light/checks/median-tells.md +103 -0
- package/dist/init-payloads/vessel-light/checks/motion-restraint.md +20 -0
- package/dist/init-payloads/vessel-light/checks/relationships.md +33 -0
- package/dist/init-payloads/vessel-light/checks/shape-matches-job.md +43 -0
- package/dist/init-payloads/vessel-light/checks/values.md +51 -0
- package/dist/init-payloads/vessel-light/glossary.md +44 -0
- package/dist/init-payloads/vessel-light/grammar.color-roles.md +30 -0
- package/dist/init-payloads/vessel-light/grammar.conversation.md +30 -0
- package/dist/init-payloads/vessel-light/grammar.deletion.md +35 -0
- package/dist/init-payloads/vessel-light/grammar.hierarchy.md +58 -0
- package/dist/init-payloads/vessel-light/grammar.job.md +54 -0
- package/dist/init-payloads/vessel-light/grammar.motion.md +27 -0
- package/dist/init-payloads/vessel-light/grammar.rhythm.md +27 -0
- package/dist/init-payloads/vessel-light/grammar.surfaces.md +35 -0
- package/dist/init-payloads/vessel-light/index.md +33 -0
- package/dist/init-payloads/vessel-light/manifest.yml +3 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Black.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Bold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-ExtraBold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Light.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Medium.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-Regular.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/fonts/HKGrotesk-SemiBold.woff2 +0 -0
- package/dist/init-payloads/vessel-light/materials/primitives.css +351 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.conversation.html +63 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.editorial.html +74 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.form.html +89 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.overlay.html +66 -0
- package/dist/init-payloads/vessel-light/materials/ref/composition.table.html +104 -0
- package/dist/init-payloads/vessel-light/materials/ref/email.html +80 -0
- package/dist/init-payloads/vessel-light/materials/tokens.css +191 -0
- package/dist/init-payloads/vessel-light/register.data-density.md +39 -0
- package/dist/init-payloads/vessel-light/register.editorial.md +41 -0
- package/dist/init-payloads/vessel-light/register.email.md +43 -0
- package/dist/init-payloads/vessel-light/signature.palette.md +45 -0
- package/dist/init-payloads/vessel-light/signature.shape.md +27 -0
- package/dist/init-payloads/vessel-light/signature.temperature.md +44 -0
- package/dist/init-payloads/vessel-light/signature.type.md +37 -0
- 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 +3 -4
- package/dist/review/resolve.d.ts.map +1 -1
- package/dist/review/resolve.js +12 -9
- package/dist/review/resolve.js.map +1 -1
- package/dist/review/review-packet.d.ts +2 -1
- package/dist/review/review-packet.d.ts.map +1 -1
- package/dist/review/review-packet.js +9 -20
- 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.d.ts +1 -0
- package/dist/scan/check-scaffold.d.ts.map +1 -1
- package/dist/scan/check-scaffold.js +17 -1
- 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 +16 -8
- package/dist/scan/fingerprint-package.d.ts.map +1 -1
- package/dist/scan/fingerprint-package.js +41 -241
- 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/packed-payloads.d.ts +4 -0
- package/dist/scan/packed-payloads.d.ts.map +1 -0
- package/dist/scan/packed-payloads.js +55 -0
- package/dist/scan/packed-payloads.js.map +1 -0
- package/dist/scan/templates.d.ts +20 -2
- package/dist/scan/templates.d.ts.map +1 -1
- package/dist/scan/templates.js +106 -26
- package/dist/scan/templates.js.map +1 -1
- package/dist/skill-bundle/SKILL.md +16 -13
- package/dist/skill-bundle/references/adapting-a-starter.md +104 -0
- package/dist/skill-bundle/references/authoring-scenarios.md +42 -5
- package/dist/skill-bundle/references/blocks.md +1 -1
- package/dist/skill-bundle/references/brief.md +5 -6
- package/dist/skill-bundle/references/capture.md +52 -41
- 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 +2 -2
- package/dist/scan/steering-template.d.ts +0 -8
- package/dist/scan/steering-template.d.ts.map +0 -1
- package/dist/scan/steering-template.js +0 -266
- package/dist/scan/steering-template.js.map +0 -1
- package/dist/skill-bundle/references/wild.md +0 -30
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<!-- ghost ref annotations
|
|
2
|
+
normative-for: register.data-density — the two smallest gap steps (--gap-xs, --gap-sm) as cell padding, mono tabular numerals right-aligned, muted-first hierarchy, hairline row borders with no zebra striping, small radius on the data surface (surface--radius-sm), status as a text label in one functional color family, hover confirmation at --duration-fast. grammar.hierarchy — label + title header pairing, secondary export action stepping down the ladder.
|
|
3
|
+
incidental: all customer names, emails, invoice ids, and amounts; the four-row count; the billing domain; the max content width.
|
|
4
|
+
-->
|
|
5
|
+
<!doctype html>
|
|
6
|
+
<html lang="en">
|
|
7
|
+
<head>
|
|
8
|
+
<meta charset="utf-8" />
|
|
9
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
10
|
+
<title>Vessel Light — Data Table</title>
|
|
11
|
+
<link rel="stylesheet" href="../tokens.css" />
|
|
12
|
+
<link rel="stylesheet" href="../primitives.css" />
|
|
13
|
+
<style>
|
|
14
|
+
body { margin: 0; min-height: 100vh; padding: var(--page-container-side-gutter); }
|
|
15
|
+
main { width: min(100%, calc(var(--page-container-side-gutter) * 56)); margin-inline: auto; }
|
|
16
|
+
.table-surface { overflow: hidden; }
|
|
17
|
+
table { width: 100%; border-collapse: collapse; }
|
|
18
|
+
th, td { padding: var(--gap-xs) var(--gap-sm); border-bottom: 1px solid var(--border); text-align: left; font-size: var(--text-body-size); line-height: 1.5; }
|
|
19
|
+
th { color: var(--muted-foreground); font-weight: 500; }
|
|
20
|
+
tbody tr { transition: background var(--duration-fast) var(--ease-spring); }
|
|
21
|
+
tbody tr:hover { background: var(--muted); }
|
|
22
|
+
tbody tr:last-child td { border-bottom: 0; }
|
|
23
|
+
.cell-secondary { color: var(--muted-foreground); }
|
|
24
|
+
.cell-number { font-family: var(--font-mono); font-variant-numeric: tabular-nums; text-align: right; }
|
|
25
|
+
.status { color: var(--success); font-size: 12px; font-weight: 600; line-height: 1.4; }
|
|
26
|
+
.align-right { text-align: right; }
|
|
27
|
+
</style>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<main class="stack stack--gap-lg">
|
|
31
|
+
<header class="stack stack--row stack--justify-between stack--align-end stack--gap-md stack--wrap">
|
|
32
|
+
<div class="stack stack--gap-xs">
|
|
33
|
+
<p class="text text--label text--muted">Billing console</p>
|
|
34
|
+
<h1 class="text text--title">Recent payments</h1>
|
|
35
|
+
</div>
|
|
36
|
+
<button class="button button--secondary button--size-sm" type="button">Export CSV</button>
|
|
37
|
+
</header>
|
|
38
|
+
|
|
39
|
+
<section class="surface surface--card surface--border surface--radius-sm table-surface" aria-label="Recent payments table">
|
|
40
|
+
<table>
|
|
41
|
+
<thead>
|
|
42
|
+
<tr>
|
|
43
|
+
<th scope="col">Customer</th>
|
|
44
|
+
<th scope="col">Plan</th>
|
|
45
|
+
<th scope="col">Invoice</th>
|
|
46
|
+
<th scope="col" class="align-right">Amount</th>
|
|
47
|
+
<th scope="col">Status</th>
|
|
48
|
+
</tr>
|
|
49
|
+
</thead>
|
|
50
|
+
<tbody>
|
|
51
|
+
<tr>
|
|
52
|
+
<td>
|
|
53
|
+
<div class="stack stack--gap-none">
|
|
54
|
+
<span>Northstar Studio</span>
|
|
55
|
+
<span class="cell-secondary">design@northstar.example</span>
|
|
56
|
+
</div>
|
|
57
|
+
</td>
|
|
58
|
+
<td class="cell-secondary">Team</td>
|
|
59
|
+
<td class="cell-secondary">VS-1048</td>
|
|
60
|
+
<td class="cell-number">$96.00</td>
|
|
61
|
+
<td><span class="status">Paid</span></td>
|
|
62
|
+
</tr>
|
|
63
|
+
<tr>
|
|
64
|
+
<td>
|
|
65
|
+
<div class="stack stack--gap-none">
|
|
66
|
+
<span>Common Room</span>
|
|
67
|
+
<span class="cell-secondary">ops@common.example</span>
|
|
68
|
+
</div>
|
|
69
|
+
</td>
|
|
70
|
+
<td class="cell-secondary">Business</td>
|
|
71
|
+
<td class="cell-secondary">VS-1047</td>
|
|
72
|
+
<td class="cell-number">$240.00</td>
|
|
73
|
+
<td><span class="status">Paid</span></td>
|
|
74
|
+
</tr>
|
|
75
|
+
<tr>
|
|
76
|
+
<td>
|
|
77
|
+
<div class="stack stack--gap-none">
|
|
78
|
+
<span>Field Notes Lab</span>
|
|
79
|
+
<span class="cell-secondary">admin@fieldnotes.example</span>
|
|
80
|
+
</div>
|
|
81
|
+
</td>
|
|
82
|
+
<td class="cell-secondary">Team</td>
|
|
83
|
+
<td class="cell-secondary">VS-1046</td>
|
|
84
|
+
<td class="cell-number">$96.00</td>
|
|
85
|
+
<td><span class="status">Paid</span></td>
|
|
86
|
+
</tr>
|
|
87
|
+
<tr>
|
|
88
|
+
<td>
|
|
89
|
+
<div class="stack stack--gap-none">
|
|
90
|
+
<span>Atlas Review</span>
|
|
91
|
+
<span class="cell-secondary">finance@atlas.example</span>
|
|
92
|
+
</div>
|
|
93
|
+
</td>
|
|
94
|
+
<td class="cell-secondary">Starter</td>
|
|
95
|
+
<td class="cell-secondary">VS-1045</td>
|
|
96
|
+
<td class="cell-number">$24.00</td>
|
|
97
|
+
<td><span class="status">Paid</span></td>
|
|
98
|
+
</tr>
|
|
99
|
+
</tbody>
|
|
100
|
+
</table>
|
|
101
|
+
</section>
|
|
102
|
+
</main>
|
|
103
|
+
</body>
|
|
104
|
+
</html>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<!-- ghost ref annotations
|
|
3
|
+
normative-for: register.email — the inverted material contract: table layout, 600px wrapper, inline styles, system font stack, hardcoded hex hand-transcribed from tokens.css (each annotated below with its source token), bulletproof pill button, surface radius on the card, exactly one expressive moment in one hue (the amber header band). signature.shape — the radius values (20px surface, 999px control) surviving without token names. signature.palette — monochrome spine, one hue, quiet factual copy, no celebration.
|
|
4
|
+
incidental: all copy, amounts, dates, and receipt numbers; the choice of amber for the one expressive moment (any single expression hue qualifies); the receipt subject matter.
|
|
5
|
+
|
|
6
|
+
hex transcription map (single source: materials/tokens.css — re-transcribe if a token changes):
|
|
7
|
+
#ffffff = --color-white (background)
|
|
8
|
+
#1a1a1a = --color-gray-900 (foreground / primary)
|
|
9
|
+
#999999 = --color-gray-500 (muted-foreground)
|
|
10
|
+
#e8e8e8 = --color-gray-200 (border)
|
|
11
|
+
#f6b44a = --expression-1 (amber)
|
|
12
|
+
border-radius 20px = --radius-surface; 999px = --radius-control
|
|
13
|
+
-->
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="utf-8" />
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
18
|
+
<title>Payment receipt</title>
|
|
19
|
+
</head>
|
|
20
|
+
<!-- #ffffff = --color-white; #1a1a1a = --color-gray-900 -->
|
|
21
|
+
<body style="margin:0; padding:0; background:#ffffff; color:#1a1a1a; font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', Arial, sans-serif;">
|
|
22
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="width:100%; background:#ffffff;"><!-- #ffffff = --color-white -->
|
|
23
|
+
<tr>
|
|
24
|
+
<td align="center" style="padding:32px 16px;">
|
|
25
|
+
<table role="presentation" width="600" cellspacing="0" cellpadding="0" border="0" style="width:100%; max-width:600px;">
|
|
26
|
+
<tr>
|
|
27
|
+
<td style="padding:0 0 16px 0; font-size:11px; line-height:1.2; letter-spacing:0.12em; font-weight:600; text-transform:uppercase; color:#999999;">Vessel</td><!-- #999999 = --color-gray-500 -->
|
|
28
|
+
</tr>
|
|
29
|
+
<tr>
|
|
30
|
+
<!-- the one expressive moment: amber band (#f6b44a = --expression-1), one hue, nothing else colored; #e8e8e8 = --color-gray-200; 20px = --radius-surface -->
|
|
31
|
+
<td style="border:1px solid #e8e8e8; border-top:4px solid #f6b44a; border-radius:20px; padding:24px; background:#ffffff;">
|
|
32
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0">
|
|
33
|
+
<tr>
|
|
34
|
+
<td style="padding:0 0 8px 0; font-size:24px; line-height:1.25; letter-spacing:-0.025em; font-weight:400; color:#1a1a1a;">Payment receipt</td><!-- #1a1a1a = --color-gray-900 -->
|
|
35
|
+
</tr>
|
|
36
|
+
<tr>
|
|
37
|
+
<td style="padding:0 0 24px 0; font-size:14px; line-height:1.625; color:#999999;">Your payment for the Team plan has been received. A copy of this receipt is available in billing settings.</td>
|
|
38
|
+
</tr>
|
|
39
|
+
<tr>
|
|
40
|
+
<td style="padding:0 0 24px 0;">
|
|
41
|
+
<table role="presentation" width="100%" cellspacing="0" cellpadding="0" border="0" style="border-top:1px solid #e8e8e8; border-bottom:1px solid #e8e8e8;"><!-- #e8e8e8 = --color-gray-200 -->
|
|
42
|
+
<tr>
|
|
43
|
+
<td style="padding:12px 0; font-size:14px; line-height:1.5; color:#999999;">Receipt number</td>
|
|
44
|
+
<td align="right" style="padding:12px 0; font-size:14px; line-height:1.5; color:#1a1a1a;">VS-1048</td>
|
|
45
|
+
</tr>
|
|
46
|
+
<tr>
|
|
47
|
+
<td style="padding:12px 0; border-top:1px solid #e8e8e8; font-size:14px; line-height:1.5; color:#999999;">Billing date</td>
|
|
48
|
+
<td align="right" style="padding:12px 0; border-top:1px solid #e8e8e8; font-size:14px; line-height:1.5; color:#1a1a1a;">July 7, 2026</td>
|
|
49
|
+
</tr>
|
|
50
|
+
<tr>
|
|
51
|
+
<td style="padding:12px 0; border-top:1px solid #e8e8e8; font-size:14px; line-height:1.5; color:#999999;">Amount paid</td>
|
|
52
|
+
<td align="right" style="padding:12px 0; border-top:1px solid #e8e8e8; font-size:14px; line-height:1.5; color:#1a1a1a;">$96.00</td>
|
|
53
|
+
</tr>
|
|
54
|
+
</table>
|
|
55
|
+
</td>
|
|
56
|
+
</tr>
|
|
57
|
+
<tr>
|
|
58
|
+
<td align="left" style="padding:0 0 24px 0;">
|
|
59
|
+
<table role="presentation" cellspacing="0" cellpadding="0" border="0">
|
|
60
|
+
<tr>
|
|
61
|
+
<!-- #1a1a1a = --color-gray-900 (primary); 999px = --radius-control -->
|
|
62
|
+
<td bgcolor="#1a1a1a" style="border-radius:999px; padding:10px 24px;">
|
|
63
|
+
<a href="https://example.com/billing" style="display:inline-block; font-size:14px; line-height:1; color:#ffffff; text-decoration:none;">View receipt</a>
|
|
64
|
+
</td>
|
|
65
|
+
</tr>
|
|
66
|
+
</table>
|
|
67
|
+
</td>
|
|
68
|
+
</tr>
|
|
69
|
+
<tr>
|
|
70
|
+
<td style="font-size:12px; line-height:1.4; color:#999999;">If you have billing questions, reply to this email and include the receipt number.</td>
|
|
71
|
+
</tr>
|
|
72
|
+
</table>
|
|
73
|
+
</td>
|
|
74
|
+
</tr>
|
|
75
|
+
</table>
|
|
76
|
+
</td>
|
|
77
|
+
</tr>
|
|
78
|
+
</table>
|
|
79
|
+
</body>
|
|
80
|
+
</html>
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/* Vessel Light materials contract: style only with these custom properties; never hardcode colors, shadows, or timing. */
|
|
2
|
+
|
|
3
|
+
@font-face {
|
|
4
|
+
font-family: "HK Grotesk";
|
|
5
|
+
src: url("fonts/HKGrotesk-Light.woff2") format("woff2");
|
|
6
|
+
font-weight: 300;
|
|
7
|
+
font-style: normal;
|
|
8
|
+
font-display: swap;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
@font-face {
|
|
12
|
+
font-family: "HK Grotesk";
|
|
13
|
+
src: url("fonts/HKGrotesk-Regular.woff2") format("woff2");
|
|
14
|
+
font-weight: 400;
|
|
15
|
+
font-style: normal;
|
|
16
|
+
font-display: swap;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@font-face {
|
|
20
|
+
font-family: "HK Grotesk";
|
|
21
|
+
src: url("fonts/HKGrotesk-Medium.woff2") format("woff2");
|
|
22
|
+
font-weight: 500;
|
|
23
|
+
font-style: normal;
|
|
24
|
+
font-display: swap;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@font-face {
|
|
28
|
+
font-family: "HK Grotesk";
|
|
29
|
+
src: url("fonts/HKGrotesk-SemiBold.woff2") format("woff2");
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
font-style: normal;
|
|
32
|
+
font-display: swap;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@font-face {
|
|
36
|
+
font-family: "HK Grotesk";
|
|
37
|
+
src: url("fonts/HKGrotesk-Bold.woff2") format("woff2");
|
|
38
|
+
font-weight: 700;
|
|
39
|
+
font-style: normal;
|
|
40
|
+
font-display: swap;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
@font-face {
|
|
44
|
+
font-family: "HK Grotesk";
|
|
45
|
+
src: url("fonts/HKGrotesk-ExtraBold.woff2") format("woff2");
|
|
46
|
+
font-weight: 800;
|
|
47
|
+
font-style: normal;
|
|
48
|
+
font-display: swap;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@font-face {
|
|
52
|
+
font-family: "HK Grotesk";
|
|
53
|
+
src: url("fonts/HKGrotesk-Black.woff2") format("woff2");
|
|
54
|
+
font-weight: 900;
|
|
55
|
+
font-style: normal;
|
|
56
|
+
font-display: swap;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
:root {
|
|
60
|
+
--font-sans: "HK Grotesk", system-ui, sans-serif;
|
|
61
|
+
--font-mono: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
|
|
62
|
+
|
|
63
|
+
--color-white: #ffffff;
|
|
64
|
+
|
|
65
|
+
--color-gray-100: #f0f0f0;
|
|
66
|
+
--color-gray-200: #e8e8e8;
|
|
67
|
+
--color-gray-300: #e5e5e5;
|
|
68
|
+
--color-gray-400: #cccccc;
|
|
69
|
+
--color-gray-500: #999999;
|
|
70
|
+
--color-gray-900: #1a1a1a;
|
|
71
|
+
|
|
72
|
+
--color-red-200: #f94b4b;
|
|
73
|
+
--color-blue-200: #5c98f9;
|
|
74
|
+
--color-green-200: #91cb80;
|
|
75
|
+
--color-yellow-200: #fbcd44;
|
|
76
|
+
|
|
77
|
+
/* Radius dials: --radius-surface on what contains, --radius-control on what
|
|
78
|
+
you click. Everything else derives from these two answers. */
|
|
79
|
+
--radius-surface: 20px;
|
|
80
|
+
--radius-control: 999px;
|
|
81
|
+
--radius: var(--radius-surface);
|
|
82
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
83
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
84
|
+
--radius-input: var(--radius-control);
|
|
85
|
+
|
|
86
|
+
--gap-xs: 4px;
|
|
87
|
+
--gap-sm: 8px;
|
|
88
|
+
--gap-md: 16px;
|
|
89
|
+
--gap-lg: 24px;
|
|
90
|
+
--gap-xl: 32px;
|
|
91
|
+
|
|
92
|
+
--text-body-size: 14px;
|
|
93
|
+
--text-body-line-height: 1.625;
|
|
94
|
+
--text-title-size: 18px;
|
|
95
|
+
--text-headline-size: 24px;
|
|
96
|
+
--text-heading-letter-spacing: -0.025em;
|
|
97
|
+
|
|
98
|
+
--control-height: 36px;
|
|
99
|
+
|
|
100
|
+
--background: var(--color-white);
|
|
101
|
+
--foreground: var(--color-gray-900);
|
|
102
|
+
--card: var(--background);
|
|
103
|
+
--card-foreground: var(--foreground);
|
|
104
|
+
--popover: var(--background);
|
|
105
|
+
--popover-foreground: var(--foreground);
|
|
106
|
+
--primary: var(--color-gray-900);
|
|
107
|
+
--primary-foreground: var(--color-white);
|
|
108
|
+
--secondary: var(--color-gray-100);
|
|
109
|
+
--secondary-foreground: var(--foreground);
|
|
110
|
+
--muted: var(--color-gray-100);
|
|
111
|
+
--muted-foreground: var(--color-gray-500);
|
|
112
|
+
--destructive: var(--color-red-200);
|
|
113
|
+
--destructive-foreground: var(--color-white);
|
|
114
|
+
--success: var(--color-green-200);
|
|
115
|
+
--warning: var(--color-yellow-200);
|
|
116
|
+
--info: var(--color-blue-200);
|
|
117
|
+
--border: var(--color-gray-200);
|
|
118
|
+
--input: var(--color-gray-300);
|
|
119
|
+
--ring: var(--color-gray-400);
|
|
120
|
+
|
|
121
|
+
--dark-40: rgba(26, 26, 26, 0.4);
|
|
122
|
+
|
|
123
|
+
/* Elevation is a closed set of three tiers (card, popover, modal);
|
|
124
|
+
--shadow-btn belongs to the button primitive, not the tiers. */
|
|
125
|
+
--shadow-btn: 0 2px 8px rgba(76, 76, 76, 0.15);
|
|
126
|
+
--shadow-card: 0 2px 8px rgba(76, 76, 76, 0.15);
|
|
127
|
+
--shadow-popover: 0 8px 30px rgba(0, 0, 0, 0.12);
|
|
128
|
+
--shadow-modal: 0 20px 60px rgba(0, 0, 0, 0.2);
|
|
129
|
+
|
|
130
|
+
--surface-dark: #0a0a0a;
|
|
131
|
+
--surface-dark-text: #f5f5f5;
|
|
132
|
+
--surface-dark-muted: rgba(255, 255, 255, 0.5);
|
|
133
|
+
--surface-dark-border: rgba(255, 255, 255, 0.08);
|
|
134
|
+
|
|
135
|
+
--heading-display-font-size: clamp(64px, 8vw, 96px);
|
|
136
|
+
--heading-display-line-height: 0.88;
|
|
137
|
+
--heading-display-letter-spacing: -0.05em;
|
|
138
|
+
--heading-display-font-weight: 900;
|
|
139
|
+
--heading-section-font-size: clamp(44px, 5vw, 64px);
|
|
140
|
+
--heading-section-line-height: 0.95;
|
|
141
|
+
--heading-section-letter-spacing: -0.035em;
|
|
142
|
+
--heading-section-font-weight: 700;
|
|
143
|
+
--heading-sub-font-size: clamp(28px, 3vw, 40px);
|
|
144
|
+
--heading-sub-line-height: 1;
|
|
145
|
+
--heading-sub-letter-spacing: -0.02em;
|
|
146
|
+
--heading-sub-font-weight: 700;
|
|
147
|
+
|
|
148
|
+
--body-reading-size: clamp(1rem, 1.3vw, 1.25rem);
|
|
149
|
+
--body-reading-line-height: 1.65;
|
|
150
|
+
--body-reading-letter-spacing: -0.01em;
|
|
151
|
+
--label-font-size: 11px;
|
|
152
|
+
--label-letter-spacing: 0.12em;
|
|
153
|
+
--label-font-weight: 600;
|
|
154
|
+
--label-line-height: 1.2;
|
|
155
|
+
--pullquote-size: clamp(1.5rem, 3vw, 2.5rem);
|
|
156
|
+
--pullquote-line-height: 1.3;
|
|
157
|
+
--pullquote-weight: 300;
|
|
158
|
+
--pullquote-letter-spacing: -0.02em;
|
|
159
|
+
|
|
160
|
+
--page-container-max-width: 1440px;
|
|
161
|
+
--page-container-side-gutter: 20px;
|
|
162
|
+
--section-padding-vertical: 100px;
|
|
163
|
+
--section-heading-margin-bottom: 75px;
|
|
164
|
+
|
|
165
|
+
--ease-spring: cubic-bezier(0.33, 1, 0.68, 1);
|
|
166
|
+
--duration-fast: 0.15s; /* hover and press — confirmation, not performance */
|
|
167
|
+
--duration-normal: 0.2s; /* reveals, fades, small state changes */
|
|
168
|
+
--duration-slow: 0.4s; /* spatial transitions only; editorial entrances */
|
|
169
|
+
|
|
170
|
+
/* Budgets — countable rules, checked per view, not moods.
|
|
171
|
+
A budget of one means at most one; zero is a valid spend. */
|
|
172
|
+
--primary-budget: 1; /* primary actions per view — and some views honestly earn none */
|
|
173
|
+
--expression-budget-product: 0; /* expression hues in product UI — charts only, never the chrome */
|
|
174
|
+
--expression-budget-email: 1; /* expressive moments per message, one hue */
|
|
175
|
+
--expression-budget-editorial: 2; /* expression hues per page, atmosphere allowed */
|
|
176
|
+
|
|
177
|
+
/* Numerals in data — tabular figures so columns align and deltas read. */
|
|
178
|
+
--numeric-tabular: "tnum" 1;
|
|
179
|
+
|
|
180
|
+
/* Expression palette — the brand's five hues, volume-gated by register.
|
|
181
|
+
Product: charts only. Data-density: one hue family for status.
|
|
182
|
+
Email: exactly one expressive moment. Editorial: atmosphere, max two
|
|
183
|
+
hues per page. Never on interactive controls in any register.
|
|
184
|
+
The refs demonstrate hues 1 and 2; hues 3-5 are declared inventory —
|
|
185
|
+
no register renders all five at once (see signature.palette). */
|
|
186
|
+
--expression-1: #f6b44a; /* amber */
|
|
187
|
+
--expression-2: #7585ff; /* periwinkle */
|
|
188
|
+
--expression-3: #d76a6a; /* clay */
|
|
189
|
+
--expression-4: #d185e0; /* orchid */
|
|
190
|
+
--expression-5: #91cb80; /* sage */
|
|
191
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Data-dense consoles — gather for tables, dashboards, logs, and monitoring; compresses product rhythm to the two smallest gap steps, mono numerals, muted-first."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/ref/composition.table.html
|
|
5
|
+
- materials/primitives.css
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Condition: this node applies to data-dense surfaces — tables, dashboards,
|
|
9
|
+
transaction logs, and admin consoles.
|
|
10
|
+
|
|
11
|
+
Data density inverts the settings-page rhythm. Operators need scan speed
|
|
12
|
+
before they need breathing room.
|
|
13
|
+
|
|
14
|
+
Use the two smallest gap steps (`--gap-xs`, `--gap-sm`) where forms use the
|
|
15
|
+
medium step. Tight adjacency is meaning when rows compare against rows.
|
|
16
|
+
|
|
17
|
+
Numerals are mono so columns align. A ragged amount column is a broken
|
|
18
|
+
instrument.
|
|
19
|
+
|
|
20
|
+
Hierarchy is muted-first. Data is the default plane, labels are muted, and
|
|
21
|
+
emphasis is rare enough to stay useful.
|
|
22
|
+
|
|
23
|
+
Data surfaces take the small radius. A surface-radius table cell is costume —
|
|
24
|
+
the signature radius (see signature.shape) belongs on cards, not cells.
|
|
25
|
+
|
|
26
|
+
Status is a text label with at most one functional color family per view.
|
|
27
|
+
|
|
28
|
+
Charts inside a console follow the product carve-out from the palette
|
|
29
|
+
signature: expression hues live inside the plot area only. Outside the plot,
|
|
30
|
+
the one-status-hue cap holds — chart color never leaks into rows, badges, or
|
|
31
|
+
headers. More status color turns monitoring into confetti.
|
|
32
|
+
|
|
33
|
+
No zebra striping. Hairline borders carry rows with less noise and more
|
|
34
|
+
trust.
|
|
35
|
+
|
|
36
|
+
Hover confirmation uses the fast duration. It should acknowledge targeting,
|
|
37
|
+
not animate the table.
|
|
38
|
+
|
|
39
|
+
Generous whitespace is drift here. Wasted density makes operators scroll.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Editorial and landing surfaces — gather for heroes, marketing pages, pull quotes, and full-bleed dark moments; inverts product type restraint."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/ref/composition.editorial.html
|
|
5
|
+
- materials/tokens.css
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Condition: this node applies to marketing, landing, and editorial surfaces —
|
|
9
|
+
never to product UI.
|
|
10
|
+
|
|
11
|
+
Editorial surfaces invert the product type rules. Display scale is not an
|
|
12
|
+
indulgence here; it is the job.
|
|
13
|
+
|
|
14
|
+
Use the `--heading-display-*` tokens — size, line height, and weight — when
|
|
15
|
+
the words are the composition. The display tier belongs to this register (see
|
|
16
|
+
signature.type for the scale's character).
|
|
17
|
+
|
|
18
|
+
Section rhythm uses `--section-padding-vertical`, not a product stack
|
|
19
|
+
stretched until it looks important.
|
|
20
|
+
|
|
21
|
+
The sanctioned dramatic moment is the full-bleed dark section. Use the
|
|
22
|
+
`--surface-dark-*` family and let contrast carry the scene.
|
|
23
|
+
|
|
24
|
+
Pull quotes are visual punctuation for longform. They interrupt reading with
|
|
25
|
+
judgment, not decoration.
|
|
26
|
+
|
|
27
|
+
The tracked uppercase label is the kicker grammar. It gives the page a hard
|
|
28
|
+
editorial edge before the headline lands.
|
|
29
|
+
|
|
30
|
+
Monochrome remains the spine, but editorial is the loud end of the expression
|
|
31
|
+
ladder (see signature.palette): up to two expression hues per page as
|
|
32
|
+
atmosphere — a tinted dark section, a colored pull-quote accent, a duotone
|
|
33
|
+
image moment. Commit to few colors at scale; variety is where expression
|
|
34
|
+
collapses into decoration.
|
|
35
|
+
|
|
36
|
+
There is one primary action per page, and it keeps the control radius from
|
|
37
|
+
signature.shape. Editorial confidence does not excuse competing calls to
|
|
38
|
+
action.
|
|
39
|
+
|
|
40
|
+
A hero built at product scale reads as timid. Timidity is drift here, exactly
|
|
41
|
+
as spectacle is drift in product UI.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Transactional email — gather ONLY for email; inverts the token contract: inline styles, hardcoded hex transcribed from tokens.css, table layout, system fonts."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/ref/email.html
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Condition: this node applies only to email. In any other medium, everything
|
|
8
|
+
below is a violation.
|
|
9
|
+
|
|
10
|
+
Email clients do not honor the web contract. Custom properties, external
|
|
11
|
+
stylesheets, flex layout, and webfonts are unreliable materials here.
|
|
12
|
+
|
|
13
|
+
Email inverts the material contract deliberately. Transcribe token values by
|
|
14
|
+
hand instead of referencing tokens — every hex below is a transcription of
|
|
15
|
+
`materials/tokens.css`, which stays the single source; if a token changes,
|
|
16
|
+
re-transcribe.
|
|
17
|
+
|
|
18
|
+
Use `#1a1a1a` (`--color-gray-900`, foreground) for text, `#999999`
|
|
19
|
+
(`--color-gray-500`, muted) for muted text, and `#e8e8e8` (`--color-gray-200`,
|
|
20
|
+
border) for borders when the email needs the Vessel palette.
|
|
21
|
+
|
|
22
|
+
Keep the surface radius on cards and the control radius on buttons (see
|
|
23
|
+
signature.shape). The values survive even when the token names cannot travel.
|
|
24
|
+
|
|
25
|
+
Build with table layout, a 600px wrapper, predictable cells, and bulletproof
|
|
26
|
+
buttons. Email fidelity is made from boring structure.
|
|
27
|
+
|
|
28
|
+
HK Grotesk falls back to the system stack. The voice must survive without the
|
|
29
|
+
font file.
|
|
30
|
+
|
|
31
|
+
The soul survives the body swap: monochrome spine, quiet factual copy, one
|
|
32
|
+
primary action, no celebration.
|
|
33
|
+
|
|
34
|
+
Email gets exactly one expressive moment: a header band or the figure that
|
|
35
|
+
matters, in one expression hue, transcribed by hand like every value here —
|
|
36
|
+
amber is `#f6b44a` (`--expression-1`). One moment, one hue. A receipt is
|
|
37
|
+
allowed one degree of warmth; it is not allowed a palette.
|
|
38
|
+
|
|
39
|
+
Do not add further color to compensate for email constraints. Constraint is
|
|
40
|
+
not permission to perform.
|
|
41
|
+
|
|
42
|
+
Hardcoding hex here is fidelity, not drift. The check exemption is the
|
|
43
|
+
condition itself.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Gather whenever color beyond the base roles is in question, in any register. The palette dial: a monochrome spine plus a closed expression set whose volume rises with the register — this brand's current answer is gray plus five named hues."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/tokens.css
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This is Vessel's answer to palette — it stands until you replace it.
|
|
8
|
+
|
|
9
|
+
The relationship is fixed: one brand at different volumes. A monochrome spine
|
|
10
|
+
is the default atmosphere in every medium — calm, legible, and resistant to
|
|
11
|
+
novelty — and a closed expression set supplies the atmosphere, with volume
|
|
12
|
+
set by register, never by taste.
|
|
13
|
+
|
|
14
|
+
Vessel's current answer: the base palette is monochrome gray, and the
|
|
15
|
+
expression palette is five named hues and only these — amber
|
|
16
|
+
(`--expression-1`), periwinkle (`--expression-2`), clay (`--expression-3`),
|
|
17
|
+
orchid (`--expression-4`), sage (`--expression-5`). Expressive color outside
|
|
18
|
+
this set is not expression; it is another brand. An invented hue is not a
|
|
19
|
+
bolder Vessel; it is a different brand.
|
|
20
|
+
|
|
21
|
+
The volume ladder, by register:
|
|
22
|
+
|
|
23
|
+
Product UI: expression lives only in data visualization. A chart may use the
|
|
24
|
+
hues; the interface around it stays monochrome.
|
|
25
|
+
|
|
26
|
+
Data-dense consoles: one hue family may mark status. Nothing atmospheric.
|
|
27
|
+
Charts inside a console keep the product carve-out — hues stay inside the
|
|
28
|
+
plot area and never leak into rows, badges, or headers.
|
|
29
|
+
|
|
30
|
+
Email: exactly one expressive moment per message — a header band or the
|
|
31
|
+
figure that matters. One hue, quiet everywhere else.
|
|
32
|
+
|
|
33
|
+
Editorial: expression is sanctioned atmosphere — a tinted dark section, a
|
|
34
|
+
colored pull-quote accent, a duotone moment. Never more than two hues per
|
|
35
|
+
page. Loudness comes from commitment to few colors at scale, not variety.
|
|
36
|
+
|
|
37
|
+
Two constants that outrank the ladder: expression never touches what you
|
|
38
|
+
click — buttons, inputs, and links stay monochrome in every register — and
|
|
39
|
+
the status roles are not expression; they keep their meanings everywhere and
|
|
40
|
+
never moonlight as atmosphere.
|
|
41
|
+
|
|
42
|
+
To adapt: edit the `--expression-*` values (and the gray ramp, if the spine
|
|
43
|
+
changes) in `materials/tokens.css` and restate this node's current answer.
|
|
44
|
+
The ladder — a quiet spine, a closed hue set, register-gated volume — is the
|
|
45
|
+
part worth keeping.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Gather before setting any radius or corner treatment. The shape dial: controls take --radius-control, surfaces take --radius-surface — this brand's current answer is pills on controls and a 20px signature radius on surfaces."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/tokens.css
|
|
5
|
+
- materials/primitives.css
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is Vessel's answer to shape — it stands until you replace it.
|
|
9
|
+
|
|
10
|
+
The relationship is fixed: controls and surfaces carry different radius
|
|
11
|
+
roles, and the two never swap. Buttons and text inputs use
|
|
12
|
+
`--radius-control`; cards and other surfaces use `--radius-surface`.
|
|
13
|
+
|
|
14
|
+
Vessel's current answer: controls are pills (`--radius-control: 999px`) and
|
|
15
|
+
surfaces take the 20px signature radius (`--radius-surface: 20px`). The pill
|
|
16
|
+
is Vessel's most visible control signature; a rectangular button is not a
|
|
17
|
+
variant, it is a different design system. Never give a button the surface
|
|
18
|
+
radius — a rectangular button is the fastest tell that the output is not
|
|
19
|
+
Vessel.
|
|
20
|
+
|
|
21
|
+
20px is a considered position: rounder than default shadcn, but not bubbly.
|
|
22
|
+
Use the radius system as restraint, not as decoration.
|
|
23
|
+
|
|
24
|
+
To adapt: edit the `--radius-control` and `--radius-surface` values in
|
|
25
|
+
`materials/tokens.css` and restate this node's current answer. The
|
|
26
|
+
role split — one radius for what you click, one for what contains — is the
|
|
27
|
+
part worth keeping.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Gather for any copy and for motion character. The temperature dial: how the brand sounds and how it moves — this brand's current answer is factual, quiet, never celebratory, with resolved spring motion."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/tokens.css
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
This is Vessel's answer to temperature — it stands until you replace it.
|
|
8
|
+
|
|
9
|
+
The relationship is fixed: voice and motion carry the same temperature. Copy
|
|
10
|
+
states what happened, what is possible, or what the user must decide — it
|
|
11
|
+
does not perform personality — and motion confirms rather than entertains.
|
|
12
|
+
|
|
13
|
+
Vessel's current answer in words: product UI is the default register —
|
|
14
|
+
factual, quiet, sentence case, and free of applause. No exclamation marks;
|
|
15
|
+
celebration is not reassurance. Confirmations are quiet: "Changes saved",
|
|
16
|
+
never "Awesome!" The system should sound reliable, not excited by basic
|
|
17
|
+
competence. Errors name the problem and the fix in the place where the user
|
|
18
|
+
can act; a vague failure banner is evasion. Buttons name the act — "Delete
|
|
19
|
+
account", "Save changes", "Invite member", not "Do it" or "Let's go".
|
|
20
|
+
Destructive copy is direct because the risk is direct; softening the verb
|
|
21
|
+
makes the interface less honest. Vessel never celebrates at the user. Trust
|
|
22
|
+
comes from precision, restraint, and naming the truth plainly.
|
|
23
|
+
|
|
24
|
+
The voice is a mechanical edit, not a mood — apply it as transformations:
|
|
25
|
+
"Sorry, nothing here yet!" → "Nothing yet". "Awesome, your changes have been
|
|
26
|
+
saved!" → "Changes saved". "Oops! Something went wrong" → "Payment failed —
|
|
27
|
+
card expired". "You might want to consider updating your billing info" →
|
|
28
|
+
"Update your billing info". Strip the apology, the applause, and the hedge;
|
|
29
|
+
keep the fact and the fix.
|
|
30
|
+
|
|
31
|
+
Vessel's current answer in motion: three durations — `--duration-fast`,
|
|
32
|
+
`--duration-normal`, `--duration-slow` — and one ease, `--ease-spring`, which
|
|
33
|
+
should feel resolved without feeling elastic. Hover confirms with color and
|
|
34
|
+
background shifts at the fast duration, not levitation.
|
|
35
|
+
|
|
36
|
+
Condition: editorial surfaces switch register. Short declarative confident
|
|
37
|
+
fragments are correct in heroes and section headings. That same editorial
|
|
38
|
+
confidence is wrong in a settings form — product copy serves the task before
|
|
39
|
+
it serves the voice. Email copy uses the product voice: factual, not
|
|
40
|
+
campaign-like.
|
|
41
|
+
|
|
42
|
+
To adapt: rewrite this node's current answers in your brand's voice and edit
|
|
43
|
+
the duration and ease values in `materials/tokens.css`. The coupling — words
|
|
44
|
+
and motion sharing one temperature — is the part worth keeping.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Gather for any text, and for heroes, landing pages, and editorial moments. The type dial: one voice typeface plus a mono for machine detail, with an editorial heading scale kept separate from product text — this brand's current answer is HK Grotesk."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/tokens.css
|
|
5
|
+
- materials/fonts/*.woff2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is Vessel's answer to type — it stands until you replace it.
|
|
9
|
+
|
|
10
|
+
The relationship is fixed: one typeface is the voice of the interface,
|
|
11
|
+
everywhere, with a mono variant only for code, tool detail, and machine
|
|
12
|
+
output. The heading scale is editorial — its tokens exist for pages composed
|
|
13
|
+
outside the text variants — and product UI never mixes the two vocabularies
|
|
14
|
+
in one view.
|
|
15
|
+
|
|
16
|
+
Vessel's current answer: HK Grotesk. vessel-light ships it as its embedded
|
|
17
|
+
voice — here, `tokens.css` is canonical.
|
|
18
|
+
|
|
19
|
+
The heading scale is editorial: display, section, and sub each carry their
|
|
20
|
+
own rhythm (`--heading-display-*`, `--heading-section-*`, `--heading-sub-*`).
|
|
21
|
+
Display sizes use tight tracking and sub-1 line heights because the words
|
|
22
|
+
behave like composition, not paragraph text. Card-level headings inside
|
|
23
|
+
editorial features use the product `title` variant — the scale does not reach
|
|
24
|
+
below sub.
|
|
25
|
+
|
|
26
|
+
Labels are small, semibold, and tracked wide. They should feel precise, never
|
|
27
|
+
loud. Body text keeps the established reading sizes with relaxed line height;
|
|
28
|
+
do not shrink important prose until it becomes legal copy.
|
|
29
|
+
|
|
30
|
+
Condition: display and section scale are for editorial or hero moments.
|
|
31
|
+
Product UI lives in headline, title, body, label, and mono. A modal title is
|
|
32
|
+
not a poster. When in doubt, make type quieter and layout clearer.
|
|
33
|
+
|
|
34
|
+
To adapt: swap the font files, edit `--font-sans`, `--font-mono`, and the
|
|
35
|
+
heading tokens in `materials/tokens.css`, and restate this node's current
|
|
36
|
+
answer. The one-voice rule and the editorial/product vocabulary split are the
|
|
37
|
+
parts worth keeping.
|