wren/glyph Public Public: anyone can read this; nobody can change it.

forked from apps/glyph

workbenchthis machine
Files 308f4625e0ac59206bd37f1f78c4ecba8ca65968
381 lines · 7.3 KB · ~2.1k tok Raw History
1
/* The look, in the tokens' words. Every value that is a choice — a colour, a
2
   space, a radius, a size — is a var(--…) from /tokens.css, which
3
   design/tokens.json compiles to at boot; `bun run lint:design` refuses a raw
4
   colour here. Light and dark are the tokens' business, not this file's. */
5
6
/* The page. */
7
html {
8
  -webkit-text-size-adjust: 100%;
9
  text-size-adjust: 100%;
10
}
11
body {
12
  margin: 0;
13
  background: var(--color-bg);
14
  color: var(--color-fg);
15
  font: var(--text-base) / var(--leading-body) var(--font-sans);
16
}
17
.page {
18
  max-width: 60rem;
19
  margin: 0 auto;
20
  padding: var(--space-5) var(--space-4) var(--space-6);
21
}
22
.head {
23
  display: flex;
24
  flex-wrap: wrap;
25
  justify-content: space-between;
26
  align-items: flex-start;
27
  gap: var(--space-3) var(--space-4);
28
  margin-bottom: var(--space-5);
29
}
30
h1 {
31
  margin: 0;
32
  font-size: var(--text-xl);
33
  font-weight: 650;
34
  letter-spacing: -0.01em;
35
  line-height: var(--leading-tight);
36
}
37
p {
38
  margin: 0;
39
}
40
a {
41
  color: var(--color-accent);
42
  text-decoration-thickness: 1px;
43
  text-underline-offset: 0.15em;
44
}
45
code,
46
.mono {
47
  font-family: var(--font-mono);
48
  font-size: var(--text-sm);
49
}
50
:focus-visible {
51
  outline: 2px solid var(--color-accent);
52
  outline-offset: 2px;
53
}
54
.muted {
55
  color: var(--color-muted);
56
}
57
.you {
58
  color: var(--color-muted);
59
  white-space: nowrap;
60
}
61
62
/* Blocks. */
63
.card {
64
  background: var(--color-surface);
65
  border: 1px solid var(--color-line);
66
  border-radius: var(--radius-md);
67
  padding: var(--space-4);
68
  margin-bottom: var(--space-5);
69
}
70
.row {
71
  display: flex;
72
  align-items: center;
73
  gap: var(--space-2);
74
}
75
.list {
76
  list-style: none;
77
  margin: 0;
78
  padding: 0;
79
}
80
.note {
81
  display: flex;
82
  justify-content: space-between;
83
  align-items: flex-start;
84
  gap: var(--space-3);
85
  padding: var(--space-3) 0;
86
  border-top: 1px solid var(--color-line);
87
}
88
.note:first-child {
89
  border-top: 0;
90
}
91
.note p {
92
  overflow-wrap: anywhere;
93
}
94
.note small {
95
  font-size: var(--text-sm);
96
}
97
.empty {
98
  padding: var(--space-6) var(--space-4);
99
  text-align: center;
100
  color: var(--color-muted);
101
  border: 1px dashed var(--color-line);
102
  border-radius: var(--radius-md);
103
}
104
footer {
105
  margin-top: var(--space-6);
106
  font-size: var(--text-sm);
107
  display: grid;
108
  gap: var(--space-1);
109
}
110
footer code {
111
  overflow-wrap: anywhere;
112
}
113
114
/* Drawing. */
115
.compose {
116
  display: grid;
117
  gap: var(--space-3);
118
}
119
.label {
120
  font-weight: 600;
121
}
122
.prompt {
123
  padding: var(--space-3);
124
  resize: vertical;
125
  line-height: var(--leading-body);
126
}
127
.wrap {
128
  flex-wrap: wrap;
129
}
130
.tight {
131
  gap: var(--space-1);
132
}
133
.spacer {
134
  flex: 1;
135
}
136
.kinds {
137
  display: flex;
138
  flex-wrap: wrap;
139
  gap: var(--space-2);
140
  margin: 0;
141
  padding: 0;
142
  border: 0;
143
}
144
.examples {
145
  display: flex;
146
  flex-wrap: wrap;
147
  gap: var(--space-2);
148
}
149
.examples[hidden] {
150
  display: none;
151
}
152
.chip {
153
  display: inline-flex;
154
  align-items: center;
155
  gap: var(--space-2);
156
  min-height: var(--size-tap);
157
  padding: 0 var(--space-3);
158
  font: inherit;
159
  font-size: var(--text-sm);
160
  color: var(--color-fg);
161
  background: var(--color-bg);
162
  border: 1px solid var(--color-line);
163
  border-radius: var(--radius-pill);
164
  cursor: pointer;
165
  text-decoration: none;
166
}
167
.chip:hover {
168
  border-color: var(--color-muted);
169
}
170
.chip:has(input:checked),
171
.chip[aria-current] {
172
  border-color: var(--color-accent);
173
  color: var(--color-accent);
174
  font-weight: 600;
175
}
176
.chip input {
177
  accent-color: var(--color-accent);
178
  margin: 0;
179
}
180
.palettes {
181
  margin-bottom: var(--space-4);
182
}
183
.dots {
184
  display: inline-flex;
185
  gap: 3px;
186
  padding: 4px;
187
  border-radius: var(--radius-pill);
188
  border: 1px solid var(--color-line);
189
}
190
.dots i {
191
  width: 10px;
192
  height: 10px;
193
  border-radius: 50%;
194
}
195
.drawing {
196
  padding: var(--space-4) 0;
197
  border-top: 1px solid var(--color-line);
198
}
199
.drawing:first-child {
200
  border-top: 0;
201
}
202
.drawing-head {
203
  display: flex;
204
  justify-content: space-between;
205
  align-items: flex-start;
206
  gap: var(--space-3);
207
  margin-bottom: var(--space-3);
208
}
209
.prompt-text {
210
  font-weight: 600;
211
  overflow-wrap: anywhere;
212
}
213
.tiles {
214
  display: grid;
215
  grid-template-columns: repeat(2, minmax(0, 1fr));
216
  gap: var(--space-3);
217
}
218
@media (min-width: 720px) {
219
  .tiles {
220
    grid-template-columns: repeat(4, minmax(0, 1fr));
221
  }
222
}
223
.tile-wrap {
224
  margin: 0;
225
  display: grid;
226
  gap: var(--space-1);
227
}
228
.tile {
229
  aspect-ratio: 1;
230
  border-radius: var(--radius-md);
231
  border: 1px solid var(--color-line);
232
  display: grid;
233
  place-items: center;
234
  overflow: hidden;
235
}
236
.tile img {
237
  width: 72%;
238
  height: 72%;
239
  transition: transform 160ms ease;
240
}
241
.tile:hover img {
242
  transform: scale(1.06);
243
}
244
.tile.pending {
245
  animation: pulse 1.4s ease-in-out infinite;
246
}
247
@keyframes pulse {
248
  50% {
249
    opacity: 0.45;
250
  }
251
}
252
figcaption {
253
  display: flex;
254
  flex-wrap: wrap;
255
  align-items: center;
256
  justify-content: space-between;
257
  gap: 0 var(--space-1);
258
  min-width: 0;
259
}
260
/* The name has its own line on a narrow tile; the buttons follow. */
261
figcaption .name {
262
  flex: 1 0 100%;
263
  padding-top: var(--space-1);
264
}
265
.name {
266
  font-size: var(--text-sm);
267
  font-weight: 600;
268
  overflow: hidden;
269
  text-overflow: ellipsis;
270
  white-space: nowrap;
271
}
272
.small {
273
  font-size: var(--text-sm);
274
}
275
.button.small {
276
  padding: 0 var(--space-2);
277
}
278
.error {
279
  color: var(--color-danger);
280
  overflow-wrap: anywhere;
281
}
282
[hidden] {
283
  display: none !important;
284
}
285
286
/* Controls: at least 44px on a side, keyboard and mouse alike. */
287
.input {
288
  flex: 1;
289
  min-width: 0;
290
  min-height: var(--size-tap);
291
  padding: 0 var(--space-3);
292
  font: inherit;
293
  font-size: max(16px, var(--text-base));
294
  color: inherit;
295
  background: var(--color-bg);
296
  border: 1px solid var(--color-line);
297
  border-radius: var(--radius-md);
298
}
299
.input::placeholder {
300
  color: var(--color-muted);
301
}
302
.button {
303
  min-height: var(--size-tap);
304
  padding: 0 var(--space-4);
305
  font: inherit;
306
  font-weight: 600;
307
  color: var(--color-accent-fg);
308
  background: var(--color-accent);
309
  border: 1px solid transparent;
310
  border-radius: var(--radius-md);
311
  cursor: pointer;
312
  white-space: nowrap;
313
  text-decoration: none;
314
  display: inline-flex;
315
  align-items: center;
316
}
317
.button:hover {
318
  filter: brightness(1.08);
319
}
320
.button-quiet {
321
  color: var(--color-muted);
322
  background: transparent;
323
  padding: 0 var(--space-3);
324
}
325
.button-quiet:hover {
326
  color: var(--color-fg);
327
  border-color: var(--color-line);
328
  filter: none;
329
}
330
.pill {
331
  display: inline-block;
332
  padding: 0.1rem 0.6rem;
333
  font-size: var(--text-sm);
334
  font-weight: 600;
335
  color: var(--color-muted);
336
  border: 1px solid var(--color-line);
337
  border-radius: var(--radius-pill);
338
}
339
.pill[data-env="production"] {
340
  color: var(--color-accent);
341
  border-color: currentColor;
342
}
343
344
/* A word from the last request, shown once, gone in a moment. */
345
.toast {
346
  position: fixed;
347
  left: 50%;
348
  bottom: var(--space-5);
349
  transform: translateX(-50%);
350
  max-width: calc(100% - 2 * var(--space-4));
351
  padding: var(--space-3) var(--space-4);
352
  color: var(--color-toast-fg);
353
  background: var(--color-toast-bg);
354
  border-radius: var(--radius-pill);
355
  box-shadow: 0 8px 24px var(--color-shadow);
356
  animation: toast 6s forwards;
357
}
358
@keyframes toast {
359
  0%,
360
  85% {
361
    opacity: 1;
362
  }
363
  100% {
364
    opacity: 0;
365
    visibility: hidden;
366
  }
367
}
368
/* Motion is a courtesy: whoever asked for less gets none. */
369
@media (prefers-reduced-motion: reduce) {
370
  *,
371
  *::before,
372
  *::after {
373
    animation-duration: 0.01ms !important;
374
    animation-iteration-count: 1 !important;
375
    transition-duration: 0.01ms !important;
376
    scroll-behavior: auto !important;
377
  }
378
  .toast {
379
    animation: none;
380
  }
381
}
↑↓ navigate ↵ open esc close
↑↓ navigate ↵ open esc close

Keyboard shortcuts