@design-intelligence/ghost 0.20.0 → 0.21.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/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/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +23 -8
- package/dist/commands/init-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/init-payloads/median/anti-goal.median.md +86 -0
- package/dist/init-payloads/median/median-tells.md +117 -0
- package/dist/init-payloads/skeleton/glossary.md +44 -0
- package/dist/init-payloads/skeleton/grammar.color-roles.md +26 -0
- package/dist/init-payloads/skeleton/grammar.conversation.md +23 -0
- package/dist/init-payloads/skeleton/grammar.hierarchy.md +39 -0
- package/dist/init-payloads/skeleton/grammar.motion.md +24 -0
- package/dist/init-payloads/skeleton/grammar.rhythm.md +23 -0
- package/dist/init-payloads/skeleton/grammar.surfaces.md +26 -0
- package/dist/init-payloads/skeleton/index.md +27 -0
- package/dist/init-payloads/skeleton/signature.palette.md +24 -0
- package/dist/init-payloads/skeleton/signature.shape.md +19 -0
- package/dist/init-payloads/skeleton/signature.temperature.md +20 -0
- package/dist/init-payloads/skeleton/signature.type.md +22 -0
- package/dist/init-payloads/vessel-light/anti-goal.median.md +86 -0
- package/dist/init-payloads/vessel-light/anti-goal.tells.md +37 -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/values.md +51 -0
- package/dist/init-payloads/vessel-light/glossary.md +45 -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.hierarchy.md +48 -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 +37 -0
- package/dist/init-payloads/vessel-light/manifest.yml +2 -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 +388 -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 +69 -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 +60 -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 +242 -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 +37 -0
- package/dist/init-payloads/vessel-light/signature.type.md +36 -0
- package/dist/review/resolve.d.ts +2 -2
- package/dist/review/resolve.d.ts.map +1 -1
- package/dist/review/resolve.js +8 -4
- package/dist/review/resolve.js.map +1 -1
- package/dist/review/review-packet.d.ts +2 -0
- package/dist/review/review-packet.d.ts.map +1 -1
- package/dist/review/review-packet.js +9 -1
- package/dist/review/review-packet.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.d.ts +7 -1
- package/dist/scan/fingerprint-package.d.ts.map +1 -1
- package/dist/scan/fingerprint-package.js +25 -12
- package/dist/scan/fingerprint-package.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 +83 -11
- package/dist/scan/templates.js.map +1 -1
- package/dist/skill-bundle/SKILL.md +1 -0
- package/dist/skill-bundle/references/adapting-a-starter.md +102 -0
- package/dist/skill-bundle/references/authoring-scenarios.md +40 -1
- package/dist/skill-bundle/references/blocks.md +1 -1
- package/dist/skill-bundle/references/capture.md +5 -5
- 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
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Surface roles and the closed elevation set — gather for any card, popover, modal, dialog, scrim, or bordered container; flat is the default, borders are structural, exactly three elevation tiers."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/primitives.css
|
|
5
|
+
- materials/ref/composition.overlay.html
|
|
6
|
+
- "**/*.html"
|
|
7
|
+
- "**/*.css"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
Surface is the only way an element gets a background, border, radius, or
|
|
11
|
+
shadow. If a container needs visual treatment, it first needs a surface role.
|
|
12
|
+
|
|
13
|
+
The vocabulary is closed: role, padding, radius, border, and elevation. These
|
|
14
|
+
axes create enough range for page flow, cards, popovers, muted blocks,
|
|
15
|
+
accents, and dark moments without inventing one-off boxes.
|
|
16
|
+
|
|
17
|
+
The default surface is flat: no border, no shadow. We do not outline
|
|
18
|
+
everything to prove layout exists.
|
|
19
|
+
|
|
20
|
+
The elevation tiers are exactly three: card, popover, modal. Elevation
|
|
21
|
+
implies hierarchy — a card sits in the document flow, a popover floats above
|
|
22
|
+
the flow, a modal interrupts the task. Pick the tier that matches the
|
|
23
|
+
interaction; never write a custom shadow because the composition feels flat,
|
|
24
|
+
and never pair a low tier with an interrupting role or give a routine card
|
|
25
|
+
modal gravity. Component shadows belong to the primitives that own them;
|
|
26
|
+
never borrow them for layout.
|
|
27
|
+
|
|
28
|
+
Borders are structural, especially for inputs and overlays. They are not
|
|
29
|
+
decorative frames around ordinary text — reject borders as decoration,
|
|
30
|
+
especially around assistant text, and use space, tone, and type hierarchy
|
|
31
|
+
instead.
|
|
32
|
+
|
|
33
|
+
The overlay reference shows the interrupting end of the system: background
|
|
34
|
+
scrim, modal radius, modal shadow, compact header, clear footer. Copy its
|
|
35
|
+
hierarchy when a user must stop and decide.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Always read first: Vessel's design language as a raw HTML/CSS steering packet for agents."
|
|
3
|
+
materials:
|
|
4
|
+
- materials/tokens.css
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
vessel-light is Vessel without the React package: the design language as a
|
|
8
|
+
repo-local steering packet for agents writing raw HTML and CSS.
|
|
9
|
+
|
|
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
|
+
them — they are worked examples to copy from, not a framework to import.
|
|
13
|
+
|
|
14
|
+
The corpus carries three trust tiers. Grammar and the median floor are law:
|
|
15
|
+
safe to consume verbatim, unchanged by any adaptation. Signature nodes are
|
|
16
|
+
dials awaiting your values: each states Vessel's current answer and stands
|
|
17
|
+
until you replace it. Registers are conditions: editorial, email, and
|
|
18
|
+
data-density each name the situation where parts of the default contract
|
|
19
|
+
invert. Gather against the actual task and pull only the nodes whose
|
|
20
|
+
conditions apply, because truths from the wrong register are poison, not
|
|
21
|
+
context.
|
|
22
|
+
|
|
23
|
+
The reset raises the floor; only the fingerprint escapes the median.
|
|
24
|
+
|
|
25
|
+
Monochrome comes first. Status color is functional language for danger,
|
|
26
|
+
success, warning, and information — never atmosphere. Atmosphere exists, but
|
|
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.
|
|
30
|
+
|
|
31
|
+
The fingerprint protects the taste that disappears when an agent freehands:
|
|
32
|
+
quiet surfaces, deliberate spacing, one obvious action, and restrained
|
|
33
|
+
motion.
|
|
34
|
+
|
|
35
|
+
When a requested UI is not covered by a ref, compose from the grammar. Do
|
|
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.
|
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
*,
|
|
2
|
+
*::before,
|
|
3
|
+
*::after {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
body {
|
|
8
|
+
background: var(--background);
|
|
9
|
+
color: var(--foreground);
|
|
10
|
+
font-family: var(--font-sans);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* surface — defaults: background/foreground, radius-md, no padding, no border, no elevation. */
|
|
14
|
+
.surface {
|
|
15
|
+
background: var(--background);
|
|
16
|
+
color: var(--foreground);
|
|
17
|
+
border: 0;
|
|
18
|
+
border-radius: var(--radius-md);
|
|
19
|
+
box-shadow: none;
|
|
20
|
+
}
|
|
21
|
+
.surface--card {
|
|
22
|
+
background: var(--card);
|
|
23
|
+
color: var(--card-foreground);
|
|
24
|
+
}
|
|
25
|
+
.surface--popover {
|
|
26
|
+
background: var(--popover);
|
|
27
|
+
color: var(--popover-foreground);
|
|
28
|
+
}
|
|
29
|
+
.surface--muted {
|
|
30
|
+
background: var(--muted);
|
|
31
|
+
color: var(--foreground);
|
|
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
|
+
.surface--pad-xs {
|
|
43
|
+
padding: 8px;
|
|
44
|
+
}
|
|
45
|
+
.surface--pad-sm {
|
|
46
|
+
padding: 12px;
|
|
47
|
+
}
|
|
48
|
+
.surface--pad-md {
|
|
49
|
+
padding: 16px;
|
|
50
|
+
}
|
|
51
|
+
.surface--pad-lg {
|
|
52
|
+
padding: 24px;
|
|
53
|
+
}
|
|
54
|
+
.surface--radius-sm {
|
|
55
|
+
border-radius: var(--radius-sm);
|
|
56
|
+
}
|
|
57
|
+
.surface--radius-md {
|
|
58
|
+
border-radius: var(--radius-md);
|
|
59
|
+
}
|
|
60
|
+
.surface--radius-lg {
|
|
61
|
+
border-radius: var(--radius-lg);
|
|
62
|
+
}
|
|
63
|
+
.surface--radius-surface {
|
|
64
|
+
border-radius: var(--radius-surface);
|
|
65
|
+
}
|
|
66
|
+
.surface--radius-control {
|
|
67
|
+
border-radius: var(--radius-control);
|
|
68
|
+
}
|
|
69
|
+
.surface--border {
|
|
70
|
+
border: 1px solid var(--border);
|
|
71
|
+
}
|
|
72
|
+
.surface--border-input {
|
|
73
|
+
border: 1px solid var(--input);
|
|
74
|
+
}
|
|
75
|
+
.surface--elevation-card {
|
|
76
|
+
box-shadow: var(--shadow-card);
|
|
77
|
+
}
|
|
78
|
+
.surface--elevation-popover {
|
|
79
|
+
box-shadow: var(--shadow-popover);
|
|
80
|
+
}
|
|
81
|
+
.surface--elevation-modal {
|
|
82
|
+
box-shadow: var(--shadow-modal);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/* stack — defaults: column, gap-md(16px), stretch. Write class="stack" and you get vessel rhythm. */
|
|
86
|
+
.stack {
|
|
87
|
+
display: flex;
|
|
88
|
+
flex-direction: column;
|
|
89
|
+
gap: var(--gap-md);
|
|
90
|
+
align-items: stretch;
|
|
91
|
+
justify-content: flex-start;
|
|
92
|
+
flex-wrap: nowrap;
|
|
93
|
+
}
|
|
94
|
+
.stack--row {
|
|
95
|
+
flex-direction: row;
|
|
96
|
+
}
|
|
97
|
+
.stack--gap-none {
|
|
98
|
+
gap: 0;
|
|
99
|
+
}
|
|
100
|
+
.stack--gap-xs {
|
|
101
|
+
gap: var(--gap-xs);
|
|
102
|
+
}
|
|
103
|
+
.stack--gap-sm {
|
|
104
|
+
gap: var(--gap-sm);
|
|
105
|
+
}
|
|
106
|
+
.stack--gap-md {
|
|
107
|
+
gap: var(--gap-md);
|
|
108
|
+
}
|
|
109
|
+
.stack--gap-lg {
|
|
110
|
+
gap: var(--gap-lg);
|
|
111
|
+
}
|
|
112
|
+
.stack--gap-xl {
|
|
113
|
+
gap: var(--gap-xl);
|
|
114
|
+
}
|
|
115
|
+
.stack--align-start {
|
|
116
|
+
align-items: flex-start;
|
|
117
|
+
}
|
|
118
|
+
.stack--align-center {
|
|
119
|
+
align-items: center;
|
|
120
|
+
}
|
|
121
|
+
.stack--align-end {
|
|
122
|
+
align-items: flex-end;
|
|
123
|
+
}
|
|
124
|
+
.stack--align-baseline {
|
|
125
|
+
align-items: baseline;
|
|
126
|
+
}
|
|
127
|
+
.stack--justify-center {
|
|
128
|
+
justify-content: center;
|
|
129
|
+
}
|
|
130
|
+
.stack--justify-end {
|
|
131
|
+
justify-content: flex-end;
|
|
132
|
+
}
|
|
133
|
+
.stack--justify-between {
|
|
134
|
+
justify-content: space-between;
|
|
135
|
+
}
|
|
136
|
+
.stack--wrap {
|
|
137
|
+
flex-wrap: wrap;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/* text — defaults: body, 14px, relaxed, foreground. */
|
|
141
|
+
.text {
|
|
142
|
+
margin: 0;
|
|
143
|
+
color: var(--foreground);
|
|
144
|
+
font-family: var(--font-sans);
|
|
145
|
+
font-size: var(--text-body-size);
|
|
146
|
+
line-height: 1.625;
|
|
147
|
+
}
|
|
148
|
+
.text--display {
|
|
149
|
+
font-size: var(--heading-display-font-size);
|
|
150
|
+
font-weight: 400;
|
|
151
|
+
line-height: 1;
|
|
152
|
+
letter-spacing: var(--heading-display-letter-spacing);
|
|
153
|
+
}
|
|
154
|
+
.text--headline {
|
|
155
|
+
font-size: var(--text-headline-size);
|
|
156
|
+
font-weight: 400;
|
|
157
|
+
line-height: 1.25;
|
|
158
|
+
letter-spacing: -0.025em;
|
|
159
|
+
}
|
|
160
|
+
.text--title {
|
|
161
|
+
font-size: var(--text-title-size);
|
|
162
|
+
font-weight: 600;
|
|
163
|
+
line-height: 1;
|
|
164
|
+
letter-spacing: -0.025em;
|
|
165
|
+
}
|
|
166
|
+
.text--label {
|
|
167
|
+
font-size: var(--label-font-size);
|
|
168
|
+
font-weight: var(--label-font-weight);
|
|
169
|
+
line-height: var(--label-line-height);
|
|
170
|
+
letter-spacing: var(--label-letter-spacing);
|
|
171
|
+
}
|
|
172
|
+
.text--mono {
|
|
173
|
+
font-family: var(--font-mono);
|
|
174
|
+
font-size: var(--text-body-size);
|
|
175
|
+
line-height: 1.5;
|
|
176
|
+
}
|
|
177
|
+
.text--muted {
|
|
178
|
+
color: var(--muted-foreground);
|
|
179
|
+
}
|
|
180
|
+
.text--inverse {
|
|
181
|
+
color: var(--primary-foreground);
|
|
182
|
+
}
|
|
183
|
+
.text--success {
|
|
184
|
+
color: var(--success);
|
|
185
|
+
}
|
|
186
|
+
.text--warning {
|
|
187
|
+
color: var(--warning);
|
|
188
|
+
}
|
|
189
|
+
.text--info {
|
|
190
|
+
color: var(--info);
|
|
191
|
+
}
|
|
192
|
+
.text--destructive {
|
|
193
|
+
color: var(--destructive);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/* button — defaults: primary pill, 36px high, centered, fast focusable action. */
|
|
197
|
+
.button {
|
|
198
|
+
display: inline-flex;
|
|
199
|
+
align-items: center;
|
|
200
|
+
justify-content: center;
|
|
201
|
+
gap: var(--gap-sm);
|
|
202
|
+
min-width: 0;
|
|
203
|
+
height: var(--control-height);
|
|
204
|
+
padding: 8px 24px;
|
|
205
|
+
border: 1px solid transparent;
|
|
206
|
+
border-radius: var(--radius-control);
|
|
207
|
+
background: var(--primary);
|
|
208
|
+
color: var(--primary-foreground);
|
|
209
|
+
box-shadow: none;
|
|
210
|
+
font: inherit;
|
|
211
|
+
font-size: var(--text-body-size);
|
|
212
|
+
line-height: 1;
|
|
213
|
+
text-decoration: none;
|
|
214
|
+
white-space: nowrap;
|
|
215
|
+
cursor: pointer;
|
|
216
|
+
transition:
|
|
217
|
+
background var(--duration-fast) var(--ease-spring),
|
|
218
|
+
border-color var(--duration-fast) var(--ease-spring),
|
|
219
|
+
box-shadow var(--duration-fast) var(--ease-spring),
|
|
220
|
+
opacity var(--duration-fast) var(--ease-spring);
|
|
221
|
+
}
|
|
222
|
+
.button:hover {
|
|
223
|
+
box-shadow: var(--shadow-btn);
|
|
224
|
+
}
|
|
225
|
+
.button:focus-visible {
|
|
226
|
+
outline: none;
|
|
227
|
+
border-color: var(--ring);
|
|
228
|
+
box-shadow: 0 0 0 1px var(--ring);
|
|
229
|
+
}
|
|
230
|
+
.button:disabled,
|
|
231
|
+
.button[aria-disabled="true"] {
|
|
232
|
+
pointer-events: none;
|
|
233
|
+
opacity: 0.5;
|
|
234
|
+
}
|
|
235
|
+
.button--primary {
|
|
236
|
+
background: var(--primary);
|
|
237
|
+
color: var(--primary-foreground);
|
|
238
|
+
}
|
|
239
|
+
.button--secondary {
|
|
240
|
+
background: var(--muted);
|
|
241
|
+
color: var(--foreground);
|
|
242
|
+
}
|
|
243
|
+
.button--ghost {
|
|
244
|
+
background: transparent;
|
|
245
|
+
color: var(--foreground);
|
|
246
|
+
}
|
|
247
|
+
.button--ghost:hover,
|
|
248
|
+
.button--secondary:hover,
|
|
249
|
+
.button--outline:hover {
|
|
250
|
+
background: var(--muted);
|
|
251
|
+
}
|
|
252
|
+
.button--destructive {
|
|
253
|
+
background: var(--destructive);
|
|
254
|
+
color: var(--destructive-foreground);
|
|
255
|
+
}
|
|
256
|
+
.button--outline {
|
|
257
|
+
background: var(--background);
|
|
258
|
+
color: var(--foreground);
|
|
259
|
+
border-color: var(--input);
|
|
260
|
+
}
|
|
261
|
+
.button--link {
|
|
262
|
+
padding-inline: 4px;
|
|
263
|
+
background: transparent;
|
|
264
|
+
color: var(--foreground);
|
|
265
|
+
text-decoration: underline;
|
|
266
|
+
text-underline-offset: 3px;
|
|
267
|
+
transition: color var(--duration-fast) var(--ease-spring);
|
|
268
|
+
}
|
|
269
|
+
.button--link:hover {
|
|
270
|
+
background: transparent;
|
|
271
|
+
color: var(--muted-foreground);
|
|
272
|
+
box-shadow: none;
|
|
273
|
+
}
|
|
274
|
+
.button--size-xs {
|
|
275
|
+
height: 24px;
|
|
276
|
+
padding: 4px 8px;
|
|
277
|
+
gap: var(--gap-xs);
|
|
278
|
+
font-size: 12px;
|
|
279
|
+
}
|
|
280
|
+
.button--size-sm {
|
|
281
|
+
height: 32px;
|
|
282
|
+
padding: 6px 16px;
|
|
283
|
+
gap: 6px;
|
|
284
|
+
}
|
|
285
|
+
.button--size-lg {
|
|
286
|
+
height: 40px;
|
|
287
|
+
padding: 8px 32px;
|
|
288
|
+
}
|
|
289
|
+
.button--icon,
|
|
290
|
+
.button--icon-sm,
|
|
291
|
+
.button--icon-xs,
|
|
292
|
+
.button--icon-lg {
|
|
293
|
+
padding: 0;
|
|
294
|
+
}
|
|
295
|
+
.button--icon {
|
|
296
|
+
width: var(--control-height);
|
|
297
|
+
height: var(--control-height);
|
|
298
|
+
}
|
|
299
|
+
.button--icon-xs {
|
|
300
|
+
width: 24px;
|
|
301
|
+
height: 24px;
|
|
302
|
+
}
|
|
303
|
+
.button--icon-sm {
|
|
304
|
+
width: 32px;
|
|
305
|
+
height: 32px;
|
|
306
|
+
}
|
|
307
|
+
.button--icon-lg {
|
|
308
|
+
width: 40px;
|
|
309
|
+
height: 40px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/* field — defaults: label plus pill input with input border, muted placeholder, ring focus, compact error. */
|
|
313
|
+
.field {
|
|
314
|
+
display: flex;
|
|
315
|
+
flex-direction: column;
|
|
316
|
+
gap: var(--gap-sm);
|
|
317
|
+
}
|
|
318
|
+
.label {
|
|
319
|
+
display: flex;
|
|
320
|
+
gap: var(--gap-sm);
|
|
321
|
+
color: var(--foreground);
|
|
322
|
+
font-size: var(--text-body-size);
|
|
323
|
+
line-height: 1;
|
|
324
|
+
user-select: none;
|
|
325
|
+
}
|
|
326
|
+
.input {
|
|
327
|
+
display: flex;
|
|
328
|
+
width: 100%;
|
|
329
|
+
min-width: 0;
|
|
330
|
+
height: var(--control-height);
|
|
331
|
+
padding: 4px 12px;
|
|
332
|
+
border: 1px solid var(--input);
|
|
333
|
+
border-radius: var(--radius-input);
|
|
334
|
+
background: transparent;
|
|
335
|
+
color: var(--foreground);
|
|
336
|
+
font: inherit;
|
|
337
|
+
font-size: 16px;
|
|
338
|
+
outline: none;
|
|
339
|
+
transition:
|
|
340
|
+
border-color var(--duration-fast) var(--ease-spring),
|
|
341
|
+
box-shadow var(--duration-fast) var(--ease-spring);
|
|
342
|
+
}
|
|
343
|
+
.input::placeholder {
|
|
344
|
+
color: var(--muted-foreground);
|
|
345
|
+
}
|
|
346
|
+
.input:hover {
|
|
347
|
+
border-color: var(--border);
|
|
348
|
+
}
|
|
349
|
+
.input:focus,
|
|
350
|
+
.input:focus-visible {
|
|
351
|
+
border-color: var(--ring);
|
|
352
|
+
box-shadow: 0 0 0 1px var(--ring);
|
|
353
|
+
}
|
|
354
|
+
.input[aria-invalid="true"] {
|
|
355
|
+
border-color: var(--destructive);
|
|
356
|
+
box-shadow: 0 0 0 1px var(--destructive);
|
|
357
|
+
}
|
|
358
|
+
.input--textarea {
|
|
359
|
+
min-height: 64px;
|
|
360
|
+
height: auto;
|
|
361
|
+
padding: 12px;
|
|
362
|
+
resize: vertical;
|
|
363
|
+
border-radius: var(--radius-md);
|
|
364
|
+
line-height: 1.5;
|
|
365
|
+
}
|
|
366
|
+
.input--select {
|
|
367
|
+
align-items: center;
|
|
368
|
+
justify-content: space-between;
|
|
369
|
+
cursor: default;
|
|
370
|
+
}
|
|
371
|
+
.input--checkbox {
|
|
372
|
+
width: 16px;
|
|
373
|
+
height: 16px;
|
|
374
|
+
padding: 0;
|
|
375
|
+
flex: 0 0 16px;
|
|
376
|
+
border-radius: var(--radius-sm);
|
|
377
|
+
accent-color: var(--primary);
|
|
378
|
+
}
|
|
379
|
+
.field-error {
|
|
380
|
+
color: var(--destructive);
|
|
381
|
+
font-size: 12px;
|
|
382
|
+
line-height: 1.4;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* scrim — default overlay wash uses the tokenized alpha surface. */
|
|
386
|
+
.scrim {
|
|
387
|
+
background: var(--dark-40);
|
|
388
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<!-- ghost ref annotations
|
|
2
|
+
normative-for: grammar.conversation — the whole grammar: assistant turns as plain text on the page surface (no bubble, border, or fill), user turns as compact muted surfaces aligned right, tool calls collapsed to a one-line labeled summary with status (mono detail only after expansion), one bordered prompt surface with an empty writing region and a single control row below, exactly one primary send. grammar.surfaces — no borders as decoration around assistant text. signature.shape — surface radius on the prompt surface and user turns.
|
|
3
|
+
incidental: all copy; the 720px thread width and turn max-widths; the specific attach/mention controls; the billing subject matter.
|
|
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 — Conversation</title>
|
|
11
|
+
<link rel="stylesheet" href="../tokens.css" />
|
|
12
|
+
<link rel="stylesheet" href="../primitives.css" />
|
|
13
|
+
<style>
|
|
14
|
+
body { margin: 0; min-height: 100vh; display: grid; place-items: center; padding: 24px; }
|
|
15
|
+
main { width: min(100%, 720px); height: min(760px, calc(100vh - 48px)); }
|
|
16
|
+
section[aria-label="Conversation thread"] { overflow: auto; flex: 1; }
|
|
17
|
+
article[data-turn="user"] { max-width: 80%; margin-left: auto; }
|
|
18
|
+
article[data-turn="assistant"] { max-width: 92%; }
|
|
19
|
+
textarea[aria-label="Prompt"] { min-height: 96px; }
|
|
20
|
+
</style>
|
|
21
|
+
</head>
|
|
22
|
+
<body>
|
|
23
|
+
<main class="stack stack--gap-md">
|
|
24
|
+
<section class="stack stack--gap-lg" aria-label="Conversation thread">
|
|
25
|
+
<article class="surface surface--muted surface--pad-md surface--radius-surface" data-turn="user">
|
|
26
|
+
<p class="text">Can you make the billing page feel calmer without losing the upgrade prompt?</p>
|
|
27
|
+
</article>
|
|
28
|
+
|
|
29
|
+
<article class="stack stack--gap-sm" data-turn="assistant">
|
|
30
|
+
<p class="text">Yes. I would reduce the number of competing panels, keep the plan state explicit, and move the upgrade prompt into a single bordered decision area.</p>
|
|
31
|
+
<p class="text">The page should feel like account infrastructure first, promotion second.</p>
|
|
32
|
+
</article>
|
|
33
|
+
|
|
34
|
+
<details class="surface surface--muted surface--pad-sm surface--radius-surface surface--border stack stack--gap-sm" aria-label="Collapsed tool call">
|
|
35
|
+
<summary class="stack stack--row stack--justify-between stack--align-center stack--gap-sm">
|
|
36
|
+
<span class="text text--label">Inspecting tokens</span>
|
|
37
|
+
<span class="text text--label text--success">Completed</span>
|
|
38
|
+
</summary>
|
|
39
|
+
<pre class="text text--mono text--muted">read packages/vessel/src/components/billing-card.tsx</pre>
|
|
40
|
+
</details>
|
|
41
|
+
|
|
42
|
+
<article class="stack stack--gap-sm" data-turn="assistant">
|
|
43
|
+
<p class="text">Use one card surface for the current plan, muted rows for secondary facts, and a primary action only where the user can commit. Keep helper copy short and concrete.</p>
|
|
44
|
+
</article>
|
|
45
|
+
|
|
46
|
+
<article class="surface surface--muted surface--pad-md surface--radius-surface" data-turn="user">
|
|
47
|
+
<p class="text">Show me the smallest set of changes.</p>
|
|
48
|
+
</article>
|
|
49
|
+
</section>
|
|
50
|
+
|
|
51
|
+
<form class="surface surface--border-input surface--pad-sm surface--radius-surface stack stack--gap-sm" aria-label="Prompt input">
|
|
52
|
+
<textarea class="input input--textarea" aria-label="Prompt" placeholder="Ask Vessel to revise the interface"></textarea>
|
|
53
|
+
<div class="stack stack--row stack--justify-between stack--align-center stack--gap-sm">
|
|
54
|
+
<div class="stack stack--row stack--gap-xs stack--align-center">
|
|
55
|
+
<button class="button button--ghost button--icon-sm" type="button" aria-label="Attach">+</button>
|
|
56
|
+
<button class="button button--ghost button--icon-sm" type="button" aria-label="Mention">@</button>
|
|
57
|
+
</div>
|
|
58
|
+
<button class="button button--primary button--icon-sm" type="submit" aria-label="Send">↵</button>
|
|
59
|
+
</div>
|
|
60
|
+
</form>
|
|
61
|
+
</main>
|
|
62
|
+
</body>
|
|
63
|
+
</html>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
<!-- ghost ref annotations
|
|
2
|
+
normative-for: register.editorial — display-scale hero with the single sanctioned kicker (one per page — repeating it on every section is the median tell), --section-padding-vertical rhythm, the sanctioned full-bleed dark band via --surface-dark-*, the pull quote as visual punctuation, one primary action per page. signature.type — the editorial heading scale (--heading-display-*, --heading-section-*) used where the words are the composition, product text variants (title, label, body) inside the features. grammar.hierarchy — the inverse tone on the dark surface. signature.palette — the editorial volume: exactly two expression hues per page (periwinkle tinting the dark band, amber accenting the pull quote), controls monochrome.
|
|
3
|
+
incidental: all copy; the specific hue assignments (any two of the five expression hues satisfy the budget); the three-feature grid count; content max-widths.
|
|
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 — Editorial Landing</title>
|
|
11
|
+
<link rel="stylesheet" href="../tokens.css" />
|
|
12
|
+
<link rel="stylesheet" href="../primitives.css" />
|
|
13
|
+
<style>
|
|
14
|
+
body { margin: 0; }
|
|
15
|
+
.page { width: min(calc(100% - (var(--page-container-side-gutter) * 2)), var(--page-container-max-width)); margin-inline: auto; }
|
|
16
|
+
.section { padding-block: var(--section-padding-vertical); }
|
|
17
|
+
.hero { min-height: calc(var(--section-padding-vertical) * 5); justify-content: center; }
|
|
18
|
+
.label-kicker { text-transform: uppercase; }
|
|
19
|
+
.display-heading { max-width: calc(var(--page-container-side-gutter) * 48); font-size: var(--heading-display-font-size); font-weight: var(--heading-display-font-weight); line-height: var(--heading-display-line-height); letter-spacing: var(--heading-display-letter-spacing); }
|
|
20
|
+
.reading-line { max-width: calc(var(--page-container-side-gutter) * 32); font-size: var(--body-reading-size); line-height: var(--body-reading-line-height); letter-spacing: var(--body-reading-letter-spacing); }
|
|
21
|
+
.section-heading { max-width: calc(var(--page-container-side-gutter) * 36); margin-bottom: var(--section-heading-margin-bottom); font-size: var(--heading-section-font-size); font-weight: var(--heading-section-font-weight); line-height: var(--heading-section-line-height); letter-spacing: var(--heading-section-letter-spacing); }
|
|
22
|
+
/* expression budget: two hues per page — periwinkle tints the dark band, amber accents the pull quote */
|
|
23
|
+
.dark-band { width: 100vw; margin-left: calc(50% - 50vw); background: color-mix(in srgb, var(--expression-2) 12%, var(--surface-dark)); color: var(--surface-dark-text); }
|
|
24
|
+
.dark-inner { width: min(calc(100% - (var(--page-container-side-gutter) * 2)), var(--page-container-max-width)); margin-inline: auto; padding-block: var(--section-padding-vertical); }
|
|
25
|
+
.dark-muted { color: var(--surface-dark-muted); }
|
|
26
|
+
.feature-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(calc(var(--page-container-side-gutter) * 12), 1fr)); gap: var(--section-heading-margin-bottom); }
|
|
27
|
+
.feature { border-top: 1px solid var(--surface-dark-border); padding-top: var(--page-container-side-gutter); }
|
|
28
|
+
.pullquote { max-width: calc(var(--page-container-side-gutter) * 48); margin: 0; font-size: var(--pullquote-size); font-weight: var(--pullquote-weight); line-height: var(--pullquote-line-height); letter-spacing: var(--pullquote-letter-spacing); padding-left: var(--page-container-side-gutter); position: relative; }
|
|
29
|
+
.pullquote::before { content: "\201C"; position: absolute; left: 0; top: 0; color: var(--expression-1); font-size: var(--pullquote-size); line-height: 1; }
|
|
30
|
+
</style>
|
|
31
|
+
</head>
|
|
32
|
+
<body>
|
|
33
|
+
<main>
|
|
34
|
+
<section class="page section hero stack stack--gap-lg stack--align-start" aria-labelledby="hero-title">
|
|
35
|
+
<p class="text text--label text--muted label-kicker">Independent review layer</p>
|
|
36
|
+
<h1 class="text display-heading" id="hero-title">Make every generated screen answer to the same brand memory.</h1>
|
|
37
|
+
<p class="text reading-line text--muted">Vessel keeps interface materials plain, inspectable, and close to the repo so agents can preserve the feel behind the product, not just the surface.</p>
|
|
38
|
+
<a class="button button--primary" href="#material-system">Review materials</a>
|
|
39
|
+
</section>
|
|
40
|
+
|
|
41
|
+
<section class="dark-band" id="material-system" aria-labelledby="system-title">
|
|
42
|
+
<div class="dark-inner">
|
|
43
|
+
<h2 class="text text--inverse section-heading" id="system-title">A small set of primitives carries the whole system.</h2>
|
|
44
|
+
<div class="feature-grid">
|
|
45
|
+
<article class="feature stack stack--gap-sm">
|
|
46
|
+
<p class="text text--label dark-muted">Density</p>
|
|
47
|
+
<h3 class="text text--title">Compact by default</h3>
|
|
48
|
+
<p class="text dark-muted">Controls stay close to their labels. Surfaces reserve padding for decisions, not decoration.</p>
|
|
49
|
+
</article>
|
|
50
|
+
<article class="feature stack stack--gap-sm">
|
|
51
|
+
<p class="text text--label dark-muted">Restraint</p>
|
|
52
|
+
<h3 class="text text--title">Monochrome first</h3>
|
|
53
|
+
<p class="text dark-muted">Contrast, rhythm, and type scale do the work before color is asked to explain status.</p>
|
|
54
|
+
</article>
|
|
55
|
+
<article class="feature stack stack--gap-sm">
|
|
56
|
+
<p class="text text--label dark-muted">Trust</p>
|
|
57
|
+
<h3 class="text text--title">Every action is explicit</h3>
|
|
58
|
+
<p class="text dark-muted">Buttons name the commitment. Secondary copy clarifies consequence without trying to persuade.</p>
|
|
59
|
+
</article>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
</section>
|
|
63
|
+
|
|
64
|
+
<section class="page section" aria-label="Editorial note">
|
|
65
|
+
<blockquote class="pullquote">The interface should feel authored even when an agent produced the first pass.</blockquote>
|
|
66
|
+
</section>
|
|
67
|
+
</main>
|
|
68
|
+
</body>
|
|
69
|
+
</html>
|