@graphty/visual-review 0.0.1 → 0.1.1

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.
@@ -0,0 +1,503 @@
1
+ :root {
2
+ --bg: #f6f7f9;
3
+ --fg: #1d2127;
4
+ --muted: #5c6470;
5
+ --card: #ffffff;
6
+ --line: #d5d9df;
7
+ --accent: #1c64d8;
8
+ --ok: #1d7a3a;
9
+ --bad: #b3261e;
10
+ --warn: #8a5a00;
11
+ color-scheme: light dark;
12
+ }
13
+
14
+ @media (prefers-color-scheme: dark) {
15
+ :root {
16
+ --bg: #16181c;
17
+ --fg: #e6e8eb;
18
+ --muted: #9aa3ad;
19
+ --card: #1f2227;
20
+ --line: #353a42;
21
+ --accent: #6ea4ff;
22
+ --ok: #5cc27d;
23
+ --bad: #ff7a70;
24
+ --warn: #e0b04c;
25
+ }
26
+ }
27
+
28
+ * {
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ /* The page is one screen: the header on top, and main scrolling under it. */
33
+ body {
34
+ display: flex;
35
+ flex-direction: column;
36
+ height: 100vh;
37
+ height: 100dvh;
38
+ margin: 0;
39
+ font:
40
+ 14px/1.4 system-ui,
41
+ sans-serif;
42
+ background: var(--bg);
43
+ color: var(--fg);
44
+ }
45
+
46
+ header {
47
+ display: flex;
48
+ gap: 16px;
49
+ align-items: center;
50
+ padding: 8px 16px;
51
+ border-bottom: 1px solid var(--line);
52
+ background: var(--card);
53
+ flex: none;
54
+ }
55
+
56
+ #home {
57
+ font-weight: 700;
58
+ }
59
+
60
+ #home,
61
+ #copy-link {
62
+ flex: none;
63
+ white-space: nowrap;
64
+ }
65
+
66
+ #status {
67
+ margin-left: auto;
68
+ color: var(--muted);
69
+ }
70
+
71
+ #status.error,
72
+ .error {
73
+ color: var(--bad);
74
+ }
75
+
76
+ main {
77
+ flex: 1;
78
+ min-height: 0;
79
+ overflow: auto;
80
+ padding: 16px;
81
+ }
82
+
83
+ a {
84
+ color: var(--accent);
85
+ }
86
+
87
+ button {
88
+ font: inherit;
89
+ padding: 4px 10px;
90
+ border: 1px solid var(--line);
91
+ border-radius: 4px;
92
+ background: var(--card);
93
+ color: var(--fg);
94
+ cursor: pointer;
95
+ }
96
+
97
+ button[aria-pressed="true"] {
98
+ border-color: var(--accent);
99
+ box-shadow: inset 0 0 0 1px var(--accent);
100
+ }
101
+
102
+ button:disabled {
103
+ opacity: 0.5;
104
+ cursor: default;
105
+ }
106
+
107
+ button.link {
108
+ border: none;
109
+ background: none;
110
+ padding: 0;
111
+ color: var(--accent);
112
+ }
113
+
114
+ button.primary {
115
+ background: var(--accent);
116
+ border-color: var(--accent);
117
+ color: #fff;
118
+ }
119
+
120
+ button.accept {
121
+ border-color: var(--ok);
122
+ color: var(--ok);
123
+ }
124
+
125
+ button.reject {
126
+ border-color: var(--bad);
127
+ color: var(--bad);
128
+ }
129
+
130
+ .card {
131
+ background: var(--card);
132
+ border: 1px solid var(--line);
133
+ border-radius: 6px;
134
+ padding: 12px 16px;
135
+ margin-bottom: 16px;
136
+ }
137
+
138
+ .card h2 {
139
+ margin: 0 0 4px;
140
+ font-size: 16px;
141
+ }
142
+
143
+ .meta {
144
+ color: var(--muted);
145
+ margin: 4px 0;
146
+ }
147
+
148
+ table {
149
+ border-collapse: collapse;
150
+ width: 100%;
151
+ }
152
+
153
+ th,
154
+ td {
155
+ text-align: left;
156
+ padding: 4px 8px;
157
+ border-top: 1px solid var(--line);
158
+ }
159
+
160
+ .badge {
161
+ display: inline-block;
162
+ padding: 0 6px;
163
+ margin: 0 4px;
164
+ border: 1px solid var(--line);
165
+ border-radius: 10px;
166
+ font-size: 12px;
167
+ font-weight: 400;
168
+ }
169
+
170
+ .badge.warn,
171
+ .badge.unstable,
172
+ .badge.failed {
173
+ border-color: var(--warn);
174
+ color: var(--warn);
175
+ }
176
+
177
+ .badge.accept,
178
+ .badge.new {
179
+ border-color: var(--ok);
180
+ color: var(--ok);
181
+ }
182
+
183
+ .badge.reject,
184
+ .badge.removed {
185
+ border-color: var(--bad);
186
+ color: var(--bad);
187
+ }
188
+
189
+ .badge.changed,
190
+ .badge.moved,
191
+ .badge.exclude {
192
+ border-color: var(--accent);
193
+ color: var(--accent);
194
+ }
195
+
196
+ .toolbar {
197
+ display: flex;
198
+ flex-wrap: wrap;
199
+ gap: 8px;
200
+ align-items: center;
201
+ margin-bottom: 12px;
202
+ }
203
+
204
+ .spacer {
205
+ flex: 1;
206
+ }
207
+
208
+ .component {
209
+ margin-bottom: 20px;
210
+ }
211
+
212
+ .component h3 {
213
+ display: flex;
214
+ gap: 12px;
215
+ align-items: center;
216
+ margin: 0 0 8px;
217
+ font-size: 15px;
218
+ }
219
+
220
+ .stories {
221
+ display: flex;
222
+ flex-wrap: wrap;
223
+ gap: 12px;
224
+ }
225
+
226
+ /* One story, its modes (light and dark) side by side under its name. */
227
+ .story {
228
+ border: 1px solid var(--line);
229
+ border-radius: 6px;
230
+ padding: 6px;
231
+ background: var(--card);
232
+ }
233
+
234
+ .story-name {
235
+ font-size: 12px;
236
+ font-weight: 600;
237
+ margin-bottom: 4px;
238
+ word-break: break-all;
239
+ }
240
+
241
+ .modes {
242
+ display: flex;
243
+ gap: 6px;
244
+ }
245
+
246
+ .tile {
247
+ display: flex;
248
+ flex-direction: column;
249
+ gap: 4px;
250
+ align-items: flex-start;
251
+ padding: 6px;
252
+ width: 200px;
253
+ text-align: left;
254
+ }
255
+
256
+ .tile img,
257
+ .tile .noimage {
258
+ width: 100%;
259
+ aspect-ratio: 4 / 3;
260
+ object-fit: contain;
261
+ background: repeating-conic-gradient(#8882 0 25%, transparent 0 50%) 0 0 / 16px 16px;
262
+ }
263
+
264
+ .tile .noimage {
265
+ display: grid;
266
+ place-items: center;
267
+ color: var(--warn);
268
+ }
269
+
270
+ .tile.decided {
271
+ opacity: 0.6;
272
+ }
273
+
274
+ /* A tile and, under it, its decision with an Undo: a button cannot hold another button. */
275
+ .tile-box {
276
+ display: flex;
277
+ flex-direction: column;
278
+ gap: 4px;
279
+ width: 200px;
280
+ }
281
+
282
+ .decision {
283
+ display: flex;
284
+ flex-wrap: wrap;
285
+ gap: 2px 6px;
286
+ align-items: baseline;
287
+ font-size: 12px;
288
+ font-weight: 600;
289
+ }
290
+
291
+ /* The whole reason, wrapped: it is the point of the line. */
292
+ .decision .what {
293
+ flex: 1;
294
+ min-width: 0;
295
+ overflow-wrap: anywhere;
296
+ }
297
+
298
+ .decision.accept .what {
299
+ color: var(--ok);
300
+ }
301
+
302
+ .decision.reject .what {
303
+ color: var(--bad);
304
+ }
305
+
306
+ .decision.exclude .what {
307
+ color: var(--accent);
308
+ }
309
+
310
+ .decision button {
311
+ padding: 0 8px;
312
+ font-size: 12px;
313
+ font-weight: 400;
314
+ }
315
+
316
+ .decision .meta {
317
+ margin: 0;
318
+ font-weight: 400;
319
+ white-space: nowrap;
320
+ }
321
+
322
+ .error-list .decision .what {
323
+ flex: none;
324
+ max-width: 60ch;
325
+ }
326
+
327
+ .tile .name {
328
+ font-size: 12px;
329
+ word-break: break-all;
330
+ }
331
+
332
+ .number {
333
+ font-weight: 700;
334
+ font-variant-numeric: tabular-nums;
335
+ }
336
+
337
+ /* The story last opened, when the grid comes back. */
338
+ .tile.current,
339
+ .error-list li.current {
340
+ outline: 3px solid var(--accent);
341
+ outline-offset: 2px;
342
+ opacity: 1;
343
+ }
344
+
345
+ .errors {
346
+ border: 1px solid var(--bad);
347
+ border-radius: 6px;
348
+ padding: 8px 12px;
349
+ margin-bottom: 20px;
350
+ }
351
+
352
+ .errors h3 {
353
+ color: var(--bad);
354
+ margin: 0 0 4px;
355
+ }
356
+
357
+ .error-list li {
358
+ margin: 6px 0;
359
+ }
360
+
361
+ .error-list .reason {
362
+ color: var(--bad);
363
+ }
364
+
365
+ #filter,
366
+ #goto {
367
+ min-width: 220px;
368
+ font: inherit;
369
+ padding: 4px 8px;
370
+ border: 1px solid var(--line);
371
+ border-radius: 4px;
372
+ background: var(--card);
373
+ color: var(--fg);
374
+ }
375
+
376
+ /* The story screen fills main: its controls, then the two panes taking all the height left. */
377
+ .story-view {
378
+ display: flex;
379
+ flex-direction: column;
380
+ height: 100%;
381
+ }
382
+
383
+ .story-view > * {
384
+ flex: none;
385
+ }
386
+
387
+ .story-view h2 {
388
+ margin: 0 0 4px;
389
+ font-size: 18px;
390
+ }
391
+
392
+ .stage {
393
+ display: flex;
394
+ gap: 16px;
395
+ flex: 1 1 0;
396
+ min-height: 200px;
397
+ }
398
+
399
+ /* Two panes of the same size, whatever each holds. */
400
+ .stage figure {
401
+ display: flex;
402
+ flex-direction: column;
403
+ flex: 1 1 0;
404
+ min-width: 0;
405
+ margin: 0;
406
+ }
407
+
408
+ .frame {
409
+ position: relative;
410
+ display: flex;
411
+ flex: 1 1 0;
412
+ min-height: 0;
413
+ overflow: auto;
414
+ border: 1px solid var(--line);
415
+ }
416
+
417
+ /* At fit the pictures are sized to the pane; a rounding pixel never adds a scroll bar. */
418
+ .stage.zoom-fit .frame {
419
+ overflow: hidden;
420
+ }
421
+
422
+ /* No image on this side: a quiet empty frame, its label says why. */
423
+ .frame.empty {
424
+ border-style: dashed;
425
+ }
426
+
427
+ /* Centred while it fits; auto margins drop to 0 when it overflows, so every part scrolls in. */
428
+ .sheet {
429
+ position: relative;
430
+ display: grid;
431
+ flex: none;
432
+ margin: auto;
433
+ }
434
+
435
+ .sheet > img,
436
+ .sheet > canvas {
437
+ grid-area: 1 / 1;
438
+ display: block;
439
+ max-width: none;
440
+ background: repeating-conic-gradient(#8882 0 25%, transparent 0 50%) 0 0 / 16px 16px;
441
+ }
442
+
443
+ /* Hard pixels only from 4x: below that the smoothed image reads more like the real one. */
444
+ .sheet > .crisp {
445
+ image-rendering: pixelated;
446
+ }
447
+
448
+ .boxmark {
449
+ position: absolute;
450
+ box-sizing: border-box;
451
+ border: 2px solid #d000d0;
452
+ pointer-events: none;
453
+ }
454
+
455
+ .label {
456
+ font-weight: 600;
457
+ margin-bottom: 4px;
458
+ white-space: nowrap;
459
+ overflow: hidden;
460
+ text-overflow: ellipsis;
461
+ }
462
+
463
+ .console-block {
464
+ margin-top: 8px;
465
+ }
466
+
467
+ .console-block .console {
468
+ max-height: 30vh;
469
+ overflow: auto;
470
+ margin: 4px 0 0;
471
+ }
472
+
473
+ .console {
474
+ background: var(--card);
475
+ border: 1px solid var(--line);
476
+ padding: 8px;
477
+ white-space: pre-wrap;
478
+ }
479
+
480
+ .actions {
481
+ display: flex;
482
+ flex-wrap: wrap;
483
+ gap: 8px;
484
+ align-items: center;
485
+ padding-top: 8px;
486
+ }
487
+
488
+ #reason {
489
+ flex: 1;
490
+ min-width: 240px;
491
+ font: inherit;
492
+ padding: 4px 8px;
493
+ border: 1px solid var(--line);
494
+ border-radius: 4px;
495
+ background: var(--card);
496
+ color: var(--fg);
497
+ }
498
+
499
+ .tile .moved-from {
500
+ font-size: 12px;
501
+ word-break: break-all;
502
+ color: var(--accent);
503
+ }