@issuegraph/editor 0.4.0 → 0.10.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 +31 -6
- package/dist/a11y/baseline.d.ts +182 -0
- package/dist/a11y/baseline.d.ts.map +1 -0
- package/dist/a11y/baseline.js +430 -0
- package/dist/a11y/baseline.js.map +1 -0
- package/dist/audit/styles.d.ts +1 -1
- package/dist/audit/styles.d.ts.map +1 -1
- package/dist/audit/styles.js +1 -1
- package/dist/create/draft.d.ts +17 -0
- package/dist/create/draft.d.ts.map +1 -1
- package/dist/create/draft.js +19 -0
- package/dist/create/draft.js.map +1 -1
- package/dist/create/keys.d.ts +70 -5
- package/dist/create/keys.d.ts.map +1 -1
- package/dist/create/keys.js +78 -17
- package/dist/create/keys.js.map +1 -1
- package/dist/firstpass/candidates.d.ts +17 -1
- package/dist/firstpass/candidates.d.ts.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/overlay/render.d.ts.map +1 -1
- package/dist/overlay/render.js +54 -14
- package/dist/overlay/render.js.map +1 -1
- package/dist/overlay/styles.d.ts +1 -1
- package/dist/overlay/styles.d.ts.map +1 -1
- package/dist/overlay/styles.js +40 -0
- package/dist/overlay/styles.js.map +1 -1
- package/dist/picker/render.d.ts +26 -16
- package/dist/picker/render.d.ts.map +1 -1
- package/dist/picker/render.js +25 -36
- package/dist/picker/render.js.map +1 -1
- package/dist/picker/styles.d.ts +7 -7
- package/dist/picker/styles.d.ts.map +1 -1
- package/dist/picker/styles.js +7 -36
- package/dist/picker/styles.js.map +1 -1
- package/dist/picker/view.d.ts +8 -4
- package/dist/picker/view.d.ts.map +1 -1
- package/dist/picker/view.js +4 -3
- package/dist/picker/view.js.map +1 -1
- package/dist/picker/words.d.ts +12 -10
- package/dist/picker/words.d.ts.map +1 -1
- package/dist/picker/words.js +12 -8
- package/dist/picker/words.js.map +1 -1
- package/dist/scale/ladder.d.ts.map +1 -1
- package/dist/scale/ladder.js +10 -3
- package/dist/scale/ladder.js.map +1 -1
- package/dist/scale/render.d.ts.map +1 -1
- package/dist/scale/render.js +9 -1
- package/dist/scale/render.js.map +1 -1
- package/dist/workspace/chrome.d.ts +1 -1
- package/dist/workspace/chrome.d.ts.map +1 -1
- package/dist/workspace/chrome.js +48 -0
- package/dist/workspace/chrome.js.map +1 -1
- package/dist/workspace/firstpass.d.ts +166 -0
- package/dist/workspace/firstpass.d.ts.map +1 -0
- package/dist/workspace/firstpass.js +151 -0
- package/dist/workspace/firstpass.js.map +1 -0
- package/dist/workspace/host.d.ts +200 -10
- package/dist/workspace/host.d.ts.map +1 -1
- package/dist/workspace/host.js +420 -42
- package/dist/workspace/host.js.map +1 -1
- package/dist/workspace/inspector.d.ts +45 -1
- package/dist/workspace/inspector.d.ts.map +1 -1
- package/dist/workspace/inspector.js +11 -0
- package/dist/workspace/inspector.js.map +1 -1
- package/dist/workspace/mount.d.ts +52 -5
- package/dist/workspace/mount.d.ts.map +1 -1
- package/dist/workspace/mount.js +1366 -58
- package/dist/workspace/mount.js.map +1 -1
- package/dist/workspace/recovery.d.ts +155 -0
- package/dist/workspace/recovery.d.ts.map +1 -0
- package/dist/workspace/recovery.js +156 -0
- package/dist/workspace/recovery.js.map +1 -0
- package/dist/workspace/render.d.ts +402 -1
- package/dist/workspace/render.d.ts.map +1 -1
- package/dist/workspace/render.js +941 -35
- package/dist/workspace/render.js.map +1 -1
- package/dist/workspace/styles.d.ts +1 -1
- package/dist/workspace/styles.d.ts.map +1 -1
- package/dist/workspace/styles.js +554 -41
- package/dist/workspace/styles.js.map +1 -1
- package/package.json +3 -3
package/dist/workspace/styles.js
CHANGED
|
@@ -83,6 +83,43 @@ export const workspaceStylesheet = `
|
|
|
83
83
|
grid-area: header;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
/* SECTION 17a's HEADER: what backlog this is, how much of it is encoded, what
|
|
87
|
+
is wrong with it, how fresh the read is, and the way into a first pass. One
|
|
88
|
+
row, baseline-aligned, with the first-pass entry pushed to the far end --
|
|
89
|
+
the frame's only primary action on this surface.
|
|
90
|
+
|
|
91
|
+
NOTHING HERE MOVES, for the reason the whole sheet holds: the audit count
|
|
92
|
+
lives in this row, and section 17d asks for a count that never does. The
|
|
93
|
+
guard on that is a literal scan over these bytes, comments included, so the
|
|
94
|
+
words it looks for must not appear even in prose explaining their absence. */
|
|
95
|
+
.ig-workspace-header {
|
|
96
|
+
display: flex;
|
|
97
|
+
align-items: baseline;
|
|
98
|
+
flex-wrap: wrap;
|
|
99
|
+
gap: var(--ig-space);
|
|
100
|
+
padding: var(--ig-space-tight) var(--ig-space);
|
|
101
|
+
border-bottom: var(--ig-stroke) solid var(--ig-line);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.ig-workspace-identity {
|
|
105
|
+
color: var(--ig-text);
|
|
106
|
+
font-family: var(--ig-font-mono);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/* The one place the accent is spent on this surface, on the only action that
|
|
110
|
+
starts something. The frame draws it as the header's primary control. */
|
|
111
|
+
.ig-workspace-firstpass {
|
|
112
|
+
margin-left: auto;
|
|
113
|
+
background: var(--ig-accent);
|
|
114
|
+
color: var(--ig-bg);
|
|
115
|
+
border: none;
|
|
116
|
+
border-radius: var(--ig-radius);
|
|
117
|
+
padding: var(--ig-space-tight) var(--ig-space);
|
|
118
|
+
font-family: var(--ig-font-ui);
|
|
119
|
+
font-size: var(--ig-font-size-small);
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
}
|
|
122
|
+
|
|
86
123
|
.ig-zone[data-zone='rail'] {
|
|
87
124
|
grid-area: rail;
|
|
88
125
|
/* The rail scrolls; the window slides underneath. */
|
|
@@ -107,14 +144,30 @@ export const workspaceStylesheet = `
|
|
|
107
144
|
|
|
108
145
|
An inset box-shadow rather than a border: a border changes the row's box and
|
|
109
146
|
would shift every marked row against its neighbours, which is a layout jump
|
|
110
|
-
the eye reads as movement.
|
|
111
|
-
|
|
147
|
+
the eye reads as movement.
|
|
148
|
+
|
|
149
|
+
IT DREW A 330px CYAN BLOCK UNTIL #122, and the comment above it — unchanged
|
|
150
|
+
here because it was right — is how the defect survived. --ig-spine-width is
|
|
151
|
+
§16b's SPINE CARD WIDTH (330), not a stroke; the sentence "the width is the
|
|
152
|
+
theme's spine, so the bar scales with the rest of the rail" reads as a
|
|
153
|
+
scaling argument and is a token mix-up. --ig-accent is the cyan the panel
|
|
154
|
+
spends once on the number an operator acts on, and it is not the attention
|
|
155
|
+
colour. This rule is more specific than audit/styles.ts's correct one, so
|
|
156
|
+
it silently won.
|
|
157
|
+
|
|
158
|
+
AND ITS TEST PASSED THROUGHOUT. styles.test.ts matched the rule and
|
|
159
|
+
asserted it EXISTED; it never asserted what the declaration resolves to, so
|
|
160
|
+
it was green about a string rather than about a property. The test below it
|
|
161
|
+
now reads the values.
|
|
162
|
+
|
|
163
|
+
ONE TREATMENT FOR ALL FOUR SEVERITIES, which is also a correction. §17d
|
|
164
|
+
names exactly one ambient mark — "a 2px gold left-bar on the affected rail
|
|
165
|
+
row" — and puts the severity distinction in the findings list, which is
|
|
166
|
+
host-side. The misleading variant this replaces gave the LEAST urgent
|
|
167
|
+
severity ("clearing is bookkeeping, not urgency") the alarm colour while
|
|
168
|
+
every other finding got cyan, inverting the design it came from. */
|
|
112
169
|
.ig-zone[data-zone='rail'] [data-ig-audit] {
|
|
113
|
-
box-shadow: inset var(--ig-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
.ig-zone[data-zone='rail'] [data-ig-audit='misleading'] {
|
|
117
|
-
box-shadow: inset var(--ig-spine-width) 0 0 0 var(--ig-state-invalid);
|
|
170
|
+
box-shadow: inset var(--ig-stroke-audit) 0 0 0 var(--ig-edge-serialize-with);
|
|
118
171
|
}
|
|
119
172
|
|
|
120
173
|
/* THE ROWS OUTSIDE THE WINDOW, AS HEIGHT. The rail scrolls, so without a spacer
|
|
@@ -142,9 +195,16 @@ export const workspaceStylesheet = `
|
|
|
142
195
|
--ig-rail-rows is the count, set inline by the renderer. What remains
|
|
143
196
|
approximate is only VARIABLE row height — a row carrying holds is taller than
|
|
144
197
|
a bare one — so the scrollbar stays proportional rather than exact. Measuring
|
|
145
|
-
that needs a mount, which this package does not have.
|
|
198
|
+
that needs a mount, which this package does not have.
|
|
199
|
+
|
|
200
|
+
THE PITCH IS THE FLOOR ALONE NOW. Layer 1's section 16 pass separates its rows
|
|
201
|
+
with the panel's own hairlines instead of a margin — a row is
|
|
202
|
+
--ig-row-min-height of content and a hairline, with no gap to add — so the sum
|
|
203
|
+
this used to take double-counted a gap that is no longer there. The row is
|
|
204
|
+
content-sized above that floor, which is the same approximation the note above
|
|
205
|
+
already describes, at a slightly larger typical size. */
|
|
146
206
|
.ig-rail-spacer {
|
|
147
|
-
height: calc(
|
|
207
|
+
height: calc(var(--ig-row-min-height) * var(--ig-rail-rows, 0));
|
|
148
208
|
}
|
|
149
209
|
|
|
150
210
|
.ig-inspector {
|
|
@@ -154,12 +214,28 @@ export const workspaceStylesheet = `
|
|
|
154
214
|
padding: var(--ig-space);
|
|
155
215
|
}
|
|
156
216
|
|
|
157
|
-
.
|
|
217
|
+
/* TWO EMPTIES, ONE TREATMENT. "Nothing is selected" and "this issue is related
|
|
218
|
+
to nothing" are different facts and the panel states each in its own place —
|
|
219
|
+
but they are the same KIND of statement, a quiet line where content would be,
|
|
220
|
+
and giving them separate looks would suggest a distinction that is not
|
|
221
|
+
there. */
|
|
222
|
+
.ig-inspector-empty,
|
|
223
|
+
.ig-inspector-none {
|
|
158
224
|
margin: 0;
|
|
159
225
|
color: var(--ig-text-muted);
|
|
160
226
|
font-size: var(--ig-font-size-small);
|
|
161
227
|
}
|
|
162
228
|
|
|
229
|
+
/* The panel's heading row: the name at one end, the way out at the other.
|
|
230
|
+
Baseline-aligned rather than centred, so a heading in caps and a button in
|
|
231
|
+
sentence case sit on one line rather than on two optical ones. */
|
|
232
|
+
.ig-inspector-head {
|
|
233
|
+
display: flex;
|
|
234
|
+
align-items: baseline;
|
|
235
|
+
justify-content: space-between;
|
|
236
|
+
gap: var(--ig-space-tight);
|
|
237
|
+
}
|
|
238
|
+
|
|
163
239
|
.ig-inspector-issue {
|
|
164
240
|
display: flex;
|
|
165
241
|
flex-direction: column;
|
|
@@ -172,21 +248,6 @@ export const workspaceStylesheet = `
|
|
|
172
248
|
color: var(--ig-text);
|
|
173
249
|
}
|
|
174
250
|
|
|
175
|
-
.ig-inspector-key {
|
|
176
|
-
font-family: var(--ig-font-mono);
|
|
177
|
-
color: var(--ig-text-muted);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.ig-inspector-position {
|
|
181
|
-
margin: 0;
|
|
182
|
-
font-family: var(--ig-font-mono);
|
|
183
|
-
color: var(--ig-text-muted);
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
.ig-inspector-position[data-ready='true'] {
|
|
187
|
-
color: var(--ig-station-ready);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
251
|
.ig-inspector-holds {
|
|
191
252
|
list-style: none;
|
|
192
253
|
margin: 0;
|
|
@@ -232,14 +293,59 @@ export const workspaceStylesheet = `
|
|
|
232
293
|
gap: var(--ig-space-tight);
|
|
233
294
|
}
|
|
234
295
|
|
|
235
|
-
|
|
296
|
+
/* SECTION 17a DRAWS EVERY INSPECTOR HEADING IN CAPS -- WHY RANK 2,
|
|
297
|
+
RELATIONSHIPS, ADD RELATIONSHIP -- so the treatment is shared rather than
|
|
298
|
+
spelled per heading. Tracking widens with the caps because letterforms at a
|
|
299
|
+
small size need it; that is what --ig-tracking-label is for. */
|
|
300
|
+
.ig-inspector-heading,
|
|
301
|
+
.ig-inspector-name,
|
|
302
|
+
.ig-why-rank-heading {
|
|
236
303
|
margin: 0;
|
|
237
304
|
font-size: var(--ig-font-size-small);
|
|
238
305
|
color: var(--ig-text-muted);
|
|
306
|
+
text-transform: uppercase;
|
|
307
|
+
letter-spacing: var(--ig-tracking-label);
|
|
239
308
|
}
|
|
240
309
|
|
|
241
|
-
.
|
|
242
|
-
|
|
310
|
+
/* THE EXPLANATION, SECTION 17a's WHOLE POINT FOR THIS ZONE. The clauses are
|
|
311
|
+
inline spans so the block reads as one sentence rather than a list of
|
|
312
|
+
findings: the reader asked one question. */
|
|
313
|
+
.ig-why-rank {
|
|
314
|
+
display: flex;
|
|
315
|
+
flex-direction: column;
|
|
316
|
+
gap: var(--ig-space-tight);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.ig-why-rank-sentence {
|
|
320
|
+
margin: 0;
|
|
321
|
+
color: var(--ig-text-body);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/* Each clause keeps a space after it so the sentence does not run together.
|
|
325
|
+
A margin rather than a literal space in the markup: the text is host-authored
|
|
326
|
+
and the package does not add characters to it. */
|
|
327
|
+
.ig-why-rank-sentence > * + * {
|
|
328
|
+
margin-left: var(--ig-space-micro);
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
/* THE PANEL'S THREE QUIET BUTTONS SHARE ONE TREATMENT — clear, '+ add' and
|
|
333
|
+
cancel. They are the same affordance at three moments (leave this selection,
|
|
334
|
+
begin a relationship, abandon the draft) and drawing them three ways would
|
|
335
|
+
invent a hierarchy the design does not state. The destructive controls are
|
|
336
|
+
deliberately NOT in this set: a row's '✕' is a glyph in the row's own slot,
|
|
337
|
+
and the mount's delete button carries its own danger treatment.
|
|
338
|
+
|
|
339
|
+
ALIGNMENT IS NOT PART OF THE TREATMENT, and putting it here was a silent
|
|
340
|
+
contradiction. 'align-self: flex-start' belongs to the two buttons in
|
|
341
|
+
'.ig-inspector-add', a COLUMN, where without it they stretch to the panel's
|
|
342
|
+
full width. The clear button sits in '.ig-inspector-head', a baseline row —
|
|
343
|
+
and 'align-self' beats the container's 'align-items', so it overrode the
|
|
344
|
+
baseline that rule's own comment says it is there to get. Declared where each
|
|
345
|
+
is true instead. */
|
|
346
|
+
.ig-inspector-clear,
|
|
347
|
+
.ig-inspector-addbutton,
|
|
348
|
+
.ig-inspector-cancel {
|
|
243
349
|
background: var(--ig-surface-2);
|
|
244
350
|
color: var(--ig-text-body);
|
|
245
351
|
border: var(--ig-stroke) solid var(--ig-line);
|
|
@@ -250,7 +356,9 @@ export const workspaceStylesheet = `
|
|
|
250
356
|
cursor: pointer;
|
|
251
357
|
}
|
|
252
358
|
|
|
253
|
-
.ig-inspector-clear:focus-visible
|
|
359
|
+
.ig-inspector-clear:focus-visible,
|
|
360
|
+
.ig-inspector-addbutton:focus-visible,
|
|
361
|
+
.ig-inspector-cancel:focus-visible {
|
|
254
362
|
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
255
363
|
outline-offset: var(--ig-space-tight);
|
|
256
364
|
}
|
|
@@ -264,8 +372,21 @@ export const workspaceStylesheet = `
|
|
|
264
372
|
gap: var(--ig-space-tight);
|
|
265
373
|
}
|
|
266
374
|
|
|
375
|
+
/* IT WRAPS RATHER THAN TRUNCATES, which is '.ig-picker-direction''s rule
|
|
376
|
+
inherited along with §17b's statement. A qualified reference is long —
|
|
377
|
+
'owner/repo#602' — the inspector is a fixed 40-character track with no
|
|
378
|
+
horizontal scroll, and a row that cannot wrap pushes its trailing controls
|
|
379
|
+
out of the zone entirely. A statement whose object is cut off says something
|
|
380
|
+
other than what the format holds, and a flip a reader cannot reach is the
|
|
381
|
+
affordance this row exists to offer.
|
|
382
|
+
|
|
383
|
+
ON THE ROW AND ON THE STATEMENT BOTH. The row wraps so the slot and the flip
|
|
384
|
+
drop to a second line rather than overflow; '.ig-relationship-select' below
|
|
385
|
+
wraps so the reference pair does the same inside it. Wrapping one without the
|
|
386
|
+
other leaves the other overflowing. */
|
|
267
387
|
.ig-relationship {
|
|
268
388
|
display: flex;
|
|
389
|
+
flex-wrap: wrap;
|
|
269
390
|
gap: var(--ig-space-tight);
|
|
270
391
|
align-items: baseline;
|
|
271
392
|
padding: var(--ig-space-tight);
|
|
@@ -274,37 +395,70 @@ export const workspaceStylesheet = `
|
|
|
274
395
|
background: var(--ig-surface);
|
|
275
396
|
}
|
|
276
397
|
|
|
277
|
-
/*
|
|
278
|
-
|
|
279
|
-
|
|
398
|
+
/* HUE BY FIELD, ONCE, FOR EVERY ELEMENT THAT CARRIES 'data-edge'. From the
|
|
399
|
+
theme's own edge tokens — the same channel layer 1 uses — so a relationship
|
|
400
|
+
reads the same colour in the row and in the kind-list entry it was chosen
|
|
401
|
+
from as it does on the canvas. The refusal capsule is deliberately NOT in
|
|
402
|
+
this set: its whole border is the invalid state's dotted stroke, and a hue on
|
|
403
|
+
its left edge would overwrite the half of that a reader looks for first.
|
|
404
|
+
|
|
405
|
+
WRITTEN PER FIELD RATHER THAN FROM A 'data-edge'-KEYED TOKEN, because CSS has
|
|
406
|
+
no way to build 'var(--ig-edge-' + attr() + ')': 'attr()' is usable in
|
|
407
|
+
'content' and nowhere a custom property name is read. Five rules is the cost
|
|
408
|
+
of that, and the alternative the package rejected is a token per hue set
|
|
409
|
+
inline by the renderer, which moves a theme value into markup.
|
|
410
|
+
|
|
411
|
+
ONE SELECTOR LIST PER FIELD, AND THAT IS THE POINT OF THIS BLOCK. The kind
|
|
412
|
+
list arrived with a verbatim second copy of these five rules under
|
|
413
|
+
'.ig-kind-option' — same five fields, same five tokens — under a comment
|
|
414
|
+
claiming the file should not hold two ways of reading the theme while it
|
|
415
|
+
held the same way twice. A sixth field is now one line here, not two. */
|
|
416
|
+
.ig-relationship[data-edge='blocked-by'],
|
|
417
|
+
.ig-kind-option[data-edge='blocked-by'] {
|
|
280
418
|
border-left-color: var(--ig-edge-blocked-by);
|
|
281
419
|
}
|
|
282
420
|
|
|
283
|
-
.ig-relationship[data-edge='duplicate-of']
|
|
421
|
+
.ig-relationship[data-edge='duplicate-of'],
|
|
422
|
+
.ig-kind-option[data-edge='duplicate-of'] {
|
|
284
423
|
border-left-color: var(--ig-edge-duplicate-of);
|
|
285
424
|
}
|
|
286
425
|
|
|
287
|
-
.ig-relationship[data-edge='serialize-with']
|
|
426
|
+
.ig-relationship[data-edge='serialize-with'],
|
|
427
|
+
.ig-kind-option[data-edge='serialize-with'] {
|
|
288
428
|
border-left-color: var(--ig-edge-serialize-with);
|
|
289
429
|
}
|
|
290
430
|
|
|
291
|
-
.ig-relationship[data-edge='together-with']
|
|
431
|
+
.ig-relationship[data-edge='together-with'],
|
|
432
|
+
.ig-kind-option[data-edge='together-with'] {
|
|
292
433
|
border-left-color: var(--ig-edge-together-with);
|
|
293
434
|
}
|
|
294
435
|
|
|
295
|
-
.ig-relationship[data-edge='decomposed-from']
|
|
436
|
+
.ig-relationship[data-edge='decomposed-from'],
|
|
437
|
+
.ig-kind-option[data-edge='decomposed-from'] {
|
|
296
438
|
border-left-color: var(--ig-edge-decomposed-from);
|
|
297
439
|
}
|
|
298
440
|
|
|
441
|
+
/* THE DESCRIPTION'S BOX, WHETHER OR NOT A CONTROL IS WRAPPING IT. A row's head
|
|
442
|
+
is a button and a phantom capsule's is a plain span -- 'render.ts' withholds
|
|
443
|
+
the selector for an edge the landed document does not carry -- and the two
|
|
444
|
+
occupy the row identically: they fill it, so the reason wraps under them
|
|
445
|
+
rather than squeezing the reference out, and their parts sit on one baseline.
|
|
446
|
+
Declared once, so the capsule cannot come to sit differently from the row it
|
|
447
|
+
stands in for. */
|
|
448
|
+
.ig-relationship-select,
|
|
449
|
+
.ig-relationship-name {
|
|
450
|
+
flex: 1;
|
|
451
|
+
display: flex;
|
|
452
|
+
flex-wrap: wrap;
|
|
453
|
+
gap: var(--ig-space-tight);
|
|
454
|
+
align-items: baseline;
|
|
455
|
+
}
|
|
456
|
+
|
|
299
457
|
/* The button fills its row, so the whole relationship is the hit target rather
|
|
300
458
|
than the words inside it. Transparent and borderless: the li already carries
|
|
301
459
|
the border and the hue, and a second box around it would read as two
|
|
302
460
|
controls. */
|
|
303
461
|
.ig-relationship-select {
|
|
304
|
-
flex: 1;
|
|
305
|
-
display: flex;
|
|
306
|
-
gap: var(--ig-space-tight);
|
|
307
|
-
align-items: baseline;
|
|
308
462
|
background: none;
|
|
309
463
|
border: none;
|
|
310
464
|
padding: 0;
|
|
@@ -320,8 +474,15 @@ export const workspaceStylesheet = `
|
|
|
320
474
|
outline-offset: var(--ig-space-tight);
|
|
321
475
|
}
|
|
322
476
|
|
|
477
|
+
/* The glyph and its word are one phrase, so they get their own gap rather than
|
|
478
|
+
inheriting the row's — which spaces the phrase from the reference beside it,
|
|
479
|
+
a wider relationship. NOT a literal space character in the markup: the word
|
|
480
|
+
is the vocabulary's and this package does not add characters to it, which is
|
|
481
|
+
the same rule the why-rank sentence's clauses are spaced by. */
|
|
323
482
|
.ig-relationship-kind {
|
|
324
|
-
|
|
483
|
+
display: inline-flex;
|
|
484
|
+
gap: var(--ig-space-micro);
|
|
485
|
+
align-items: baseline;
|
|
325
486
|
color: var(--ig-text-body);
|
|
326
487
|
}
|
|
327
488
|
|
|
@@ -329,5 +490,357 @@ export const workspaceStylesheet = `
|
|
|
329
490
|
font-family: var(--ig-font-mono);
|
|
330
491
|
color: var(--ig-text-muted);
|
|
331
492
|
}
|
|
493
|
+
|
|
494
|
+
/* THE RIGHT-HAND SLOT, WHOSE THREE OCCUPANTS ARE EXCLUSIVE. Two of them are
|
|
495
|
+
statements and one is a control, and they are drawn as such: the state and
|
|
496
|
+
the inbound marker are quiet label text, the remove is a button.
|
|
497
|
+
'.ig-relationship-flip' below is NOT one of the three: it sits beside the
|
|
498
|
+
slot on the selected row, because it is neither a statement about the row nor
|
|
499
|
+
a destructive act on it. */
|
|
500
|
+
.ig-relationship-state,
|
|
501
|
+
.ig-relationship-inbound {
|
|
502
|
+
align-self: center;
|
|
503
|
+
color: var(--ig-text-muted);
|
|
504
|
+
font-size: var(--ig-font-size-small);
|
|
505
|
+
text-transform: uppercase;
|
|
506
|
+
letter-spacing: var(--ig-tracking-label);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
/* The selected row names the state the canvas is drawing a halo for, so it
|
|
510
|
+
takes the focus hue rather than the muted one — one selection, one colour,
|
|
511
|
+
across the zones. */
|
|
512
|
+
.ig-relationship-state[data-ig-state='selected'] {
|
|
513
|
+
color: var(--ig-focus);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/* A GLYPH BUTTON, SIZED BY ITS GLYPH. No border and no fill: the row already
|
|
517
|
+
carries a border, and a second box inside it would read as two controls —
|
|
518
|
+
the same reasoning '.ig-relationship-select' records. */
|
|
519
|
+
.ig-relationship-remove {
|
|
520
|
+
align-self: center;
|
|
521
|
+
background: none;
|
|
522
|
+
border: none;
|
|
523
|
+
padding: 0 var(--ig-space-tight);
|
|
524
|
+
color: var(--ig-text-muted);
|
|
525
|
+
font-family: inherit;
|
|
526
|
+
font-size: inherit;
|
|
527
|
+
line-height: 1;
|
|
528
|
+
cursor: pointer;
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
.ig-relationship-remove:focus-visible {
|
|
532
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
533
|
+
outline-offset: var(--ig-space-tight);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/* §17b's FLIP, AT THE ROW'S END. It is drawn last and needs no margin of its
|
|
537
|
+
own to get there: '.ig-relationship-select' above carries 'flex: 1', so the
|
|
538
|
+
statement takes the free space and everything after it is already pushed to
|
|
539
|
+
the end — which is where frame 17b draws this control. A 'margin-left: auto'
|
|
540
|
+
here would be inert, and a comment crediting it would be an explanation that
|
|
541
|
+
outlived the thing it explained.
|
|
542
|
+
|
|
543
|
+
A BORDERED CONTROL RATHER THAN THE REMOVE'S BARE GLYPH, which is the frame's
|
|
544
|
+
own distinction and not decoration: '✕' is a mark a reader recognises without
|
|
545
|
+
a box, and 'flip' is a word that would otherwise read as part of the sentence
|
|
546
|
+
it sits beside. The border is what says it is pressable.
|
|
547
|
+
|
|
548
|
+
ITS FOCUS RING IS NOT OPTIONAL, and it takes the offset the row's OTHER two
|
|
549
|
+
controls already use rather than the one it was born with. This rule came
|
|
550
|
+
from the picker's sheet, where the ring sat a hairline out;
|
|
551
|
+
'.ig-relationship-select' and '.ig-relationship-remove' share this row and
|
|
552
|
+
both ring at '--ig-space-tight', and one control ringing tighter than its
|
|
553
|
+
neighbours reads as a rendering fault rather than as a distinction. This is
|
|
554
|
+
the control §17b calls the guard against the most common encoding mistake; a
|
|
555
|
+
keyboard reader who cannot see where they are has it and not its affordance. */
|
|
556
|
+
.ig-relationship-flip {
|
|
557
|
+
align-self: center;
|
|
558
|
+
background: var(--ig-surface);
|
|
559
|
+
color: var(--ig-text-body);
|
|
560
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
561
|
+
border-radius: var(--ig-radius);
|
|
562
|
+
padding: 0 var(--ig-space-tight);
|
|
563
|
+
font-family: inherit;
|
|
564
|
+
font-size: var(--ig-font-size-small);
|
|
565
|
+
line-height: inherit;
|
|
566
|
+
cursor: pointer;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.ig-relationship-flip:focus-visible {
|
|
570
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
571
|
+
outline-offset: var(--ig-space-tight);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/* A REFUSED EDIT, IN THE ROW IT WOULD HAVE BEEN. It borrows the ghost the
|
|
575
|
+
canvas draws for the same state — a dotted edge in the invalid hue — so the
|
|
576
|
+
line and the row a reader looks between are recognisably one fact.
|
|
577
|
+
NO OPACITY HERE. 'overlay/grammar.ts' holds the opacity every write state is
|
|
578
|
+
drawn at, on the record that a second copy would drift; what this sheet
|
|
579
|
+
contributes is the structure. */
|
|
580
|
+
.ig-relationship-refused {
|
|
581
|
+
display: flex;
|
|
582
|
+
flex-wrap: wrap;
|
|
583
|
+
gap: var(--ig-space-tight);
|
|
584
|
+
align-items: baseline;
|
|
585
|
+
padding: var(--ig-space-tight);
|
|
586
|
+
border: var(--ig-stroke) dotted var(--ig-state-invalid);
|
|
587
|
+
border-radius: var(--ig-radius);
|
|
588
|
+
background: var(--ig-surface);
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
.ig-relationship-reason {
|
|
592
|
+
color: var(--ig-state-invalid);
|
|
593
|
+
font-size: var(--ig-font-size-small);
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/* A REFUSAL ON A RELATIONSHIP THAT IS STILL THERE. The row stays — it names a
|
|
597
|
+
real edge and its remove control still works — so this marks it rather than
|
|
598
|
+
replacing it: the capsule's dotted stroke, and room for the reason to wrap
|
|
599
|
+
under the row rather than squeezing the reference out of it.
|
|
600
|
+
BORDER-STYLE ONLY, NOT BORDER-COLOR: the field's hue is on the left edge from
|
|
601
|
+
the block above, and a shorthand here would overwrite it and take the row's
|
|
602
|
+
one colour channel away on exactly the rows carrying the most information. */
|
|
603
|
+
.ig-relationship[data-ig-code] {
|
|
604
|
+
flex-wrap: wrap;
|
|
605
|
+
border-style: dotted;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/* THE CREATE STEP, WHICHEVER STEP IT IS. One box holds '+ add' on its own and
|
|
609
|
+
the numbered list with its cancel, because they are one place in the panel
|
|
610
|
+
the reader returns to rather than two that happen to alternate. */
|
|
611
|
+
.ig-inspector-add {
|
|
612
|
+
display: flex;
|
|
613
|
+
flex-direction: column;
|
|
614
|
+
gap: var(--ig-space-tight);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
/* Sized by their own words rather than stretched across the column — see the
|
|
618
|
+
quiet-button rule above, which deliberately does not carry this. */
|
|
619
|
+
.ig-inspector-addbutton,
|
|
620
|
+
.ig-inspector-cancel {
|
|
621
|
+
align-self: flex-start;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
/* WHOSE DRAFT THIS IS, drawn only when it is not the panel's subject. Quiet and
|
|
625
|
+
small, like every other line that states a fact rather than offering an act:
|
|
626
|
+
it is a caption on the step below it, not a heading over it. The reference
|
|
627
|
+
inside keeps layer 1's '.ig-id' treatment, so the issue reads the same here
|
|
628
|
+
as it does in the why-rank sentence. */
|
|
629
|
+
.ig-inspector-source {
|
|
630
|
+
margin: 0;
|
|
631
|
+
color: var(--ig-text-muted);
|
|
632
|
+
font-size: var(--ig-font-size-small);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
.ig-kind-list {
|
|
636
|
+
list-style: none;
|
|
637
|
+
margin: 0;
|
|
638
|
+
padding: 0;
|
|
639
|
+
display: flex;
|
|
640
|
+
flex-direction: column;
|
|
641
|
+
gap: var(--ig-space-micro);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/* Full width, so the whole entry is the hit target and the digits form a
|
|
645
|
+
readable column down the left — which is what makes the list legible as a
|
|
646
|
+
set of KEYS rather than as five buttons that happen to start with a number. */
|
|
647
|
+
.ig-kind-option {
|
|
648
|
+
width: 100%;
|
|
649
|
+
display: flex;
|
|
650
|
+
gap: var(--ig-space-tight);
|
|
651
|
+
align-items: baseline;
|
|
652
|
+
background: var(--ig-surface);
|
|
653
|
+
color: var(--ig-text-body);
|
|
654
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
655
|
+
border-radius: var(--ig-radius);
|
|
656
|
+
padding: var(--ig-space-tight);
|
|
657
|
+
font-family: inherit;
|
|
658
|
+
font-size: var(--ig-font-size-small);
|
|
659
|
+
text-align: left;
|
|
660
|
+
cursor: pointer;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
.ig-kind-option:focus-visible {
|
|
664
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
665
|
+
outline-offset: var(--ig-space-tight);
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
.ig-kind-digit {
|
|
669
|
+
font-family: var(--ig-font-mono);
|
|
670
|
+
color: var(--ig-text-muted);
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/* §17b's RECOVERY CARDS. An unsettled write the reader can still act on, drawn
|
|
674
|
+
where they made it.
|
|
675
|
+
THE HUE COMES FROM THE STATE, through the same custom properties the canvas
|
|
676
|
+
draws the line with — so a card and the edge it is about are recognisably one
|
|
677
|
+
fact, and a host retheming the palette moves both at once. The tokens are
|
|
678
|
+
named per state below rather than set once, because '--ig-state-failed' and
|
|
679
|
+
'--ig-state-conflict' are different channels and a shared variable here would
|
|
680
|
+
be a third place the pairing could drift.
|
|
681
|
+
NO OPACITY, for the reason the refusal capsule states: 'overlay/grammar.ts'
|
|
682
|
+
holds what each write state is drawn at, and this sheet contributes structure. */
|
|
683
|
+
.ig-recovery-region {
|
|
684
|
+
display: flex;
|
|
685
|
+
flex-direction: column;
|
|
686
|
+
gap: var(--ig-space-tight);
|
|
687
|
+
margin-top: var(--ig-space);
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.ig-recovery-list {
|
|
691
|
+
list-style: none;
|
|
692
|
+
margin: 0;
|
|
693
|
+
padding: 0;
|
|
694
|
+
display: flex;
|
|
695
|
+
flex-direction: column;
|
|
696
|
+
gap: var(--ig-space-tight);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.ig-recovery {
|
|
700
|
+
display: flex;
|
|
701
|
+
flex-direction: column;
|
|
702
|
+
gap: var(--ig-space-tight);
|
|
703
|
+
padding: var(--ig-space-tight);
|
|
704
|
+
border-radius: var(--ig-radius);
|
|
705
|
+
background: var(--ig-surface);
|
|
706
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/* GHOST + THE ✕ THE CANVAS DRAWS. §17b gives a failed write a ghosted line with
|
|
710
|
+
a cross terminal; the card carries the same hue so the two read together. */
|
|
711
|
+
.ig-recovery[data-ig-state='failed'] {
|
|
712
|
+
border-color: var(--ig-state-failed);
|
|
713
|
+
border-style: dashed;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
/* THE GOLD DOUBLE RULE. §17b draws a conflict as a doubled line holding two
|
|
717
|
+
versions. 'border-style: double' is the card's half of that grammar — the
|
|
718
|
+
LINE's half is the 'second-version' mark, which needs a position this layer
|
|
719
|
+
does not have and is issue #102's. */
|
|
720
|
+
.ig-recovery[data-ig-state='conflict'] {
|
|
721
|
+
border-color: var(--ig-state-conflict);
|
|
722
|
+
border-style: double;
|
|
723
|
+
border-width: calc(var(--ig-stroke) * 3);
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
.ig-recovery-name {
|
|
727
|
+
margin: 0;
|
|
728
|
+
font-size: var(--ig-font-size-small);
|
|
729
|
+
font-weight: 600;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
.ig-recovery[data-ig-state='failed'] .ig-recovery-name {
|
|
733
|
+
color: var(--ig-state-failed);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.ig-recovery[data-ig-state='conflict'] .ig-recovery-name {
|
|
737
|
+
color: var(--ig-state-conflict);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
.ig-recovery-reason,
|
|
741
|
+
.ig-recovery-refresh-error {
|
|
742
|
+
margin: 0;
|
|
743
|
+
font-size: var(--ig-font-size-small);
|
|
744
|
+
color: var(--ig-text-muted);
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.ig-recovery-refresh-detail {
|
|
748
|
+
font-family: var(--ig-font-mono);
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/* THE THREE RESOLUTIONS, IN A ROW AND NEVER IN A MENU. §17b lists them as
|
|
752
|
+
peers; nesting one behind a disclosure would rank them, and the one that
|
|
753
|
+
would end up hidden is 'view diff' — the one that lets a reader decide
|
|
754
|
+
between the other two. */
|
|
755
|
+
.ig-recovery-actions {
|
|
756
|
+
display: flex;
|
|
757
|
+
flex-wrap: wrap;
|
|
758
|
+
gap: var(--ig-space-tight);
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
.ig-recovery-action {
|
|
762
|
+
background: var(--ig-surface);
|
|
763
|
+
color: var(--ig-text-body);
|
|
764
|
+
border: var(--ig-stroke) solid var(--ig-line);
|
|
765
|
+
border-radius: var(--ig-radius);
|
|
766
|
+
padding: var(--ig-space-tight);
|
|
767
|
+
font-family: inherit;
|
|
768
|
+
font-size: var(--ig-font-size-small);
|
|
769
|
+
cursor: pointer;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
.ig-recovery-action:focus-visible {
|
|
773
|
+
outline: var(--ig-focus-ring) solid var(--ig-focus);
|
|
774
|
+
outline-offset: var(--ig-space-tight);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.ig-recovery-action[aria-pressed='true'] {
|
|
778
|
+
border-color: var(--ig-focus);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
/* TWO SIDES, SIDE BY SIDE, AND NOTHING BETWEEN THEM THAT COMBINES THEM. The
|
|
782
|
+
layout is the design constraint: there is no column for a merged result,
|
|
783
|
+
because there is no merged result to put in one. */
|
|
784
|
+
.ig-recovery-diff {
|
|
785
|
+
display: flex;
|
|
786
|
+
flex-direction: column;
|
|
787
|
+
gap: var(--ig-space-tight);
|
|
788
|
+
padding-top: var(--ig-space-tight);
|
|
789
|
+
border-top: var(--ig-stroke) solid var(--ig-line);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/* ONE SIDE OF THE DIFFERENCE. Stacked rather than columned: at a panel's width
|
|
793
|
+
two columns give each side about half of an already narrow zone, and a
|
|
794
|
+
relationship row is a sentence rather than a cell. */
|
|
795
|
+
.ig-recovery-side {
|
|
796
|
+
display: flex;
|
|
797
|
+
flex-direction: column;
|
|
798
|
+
gap: var(--ig-space-tight);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
.ig-recovery-side-name {
|
|
802
|
+
margin: 0;
|
|
803
|
+
font-size: var(--ig-font-size-small);
|
|
804
|
+
color: var(--ig-text-muted);
|
|
805
|
+
font-weight: 400;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
.ig-recovery-edges,
|
|
809
|
+
.ig-recovery-issues {
|
|
810
|
+
list-style: none;
|
|
811
|
+
margin: 0;
|
|
812
|
+
padding: 0;
|
|
813
|
+
display: flex;
|
|
814
|
+
flex-direction: column;
|
|
815
|
+
gap: var(--ig-space-tight);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
.ig-recovery-edge,
|
|
819
|
+
.ig-recovery-issue {
|
|
820
|
+
display: flex;
|
|
821
|
+
flex-wrap: wrap;
|
|
822
|
+
gap: var(--ig-space-tight);
|
|
823
|
+
align-items: baseline;
|
|
824
|
+
font-size: var(--ig-font-size-small);
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
/* BOTH TITLES, NEITHER STRUCK THROUGH. A strike-out would say the old one is
|
|
828
|
+
gone, which is exactly the judgement this card must not make for the reader. */
|
|
829
|
+
.ig-recovery-was,
|
|
830
|
+
.ig-recovery-now {
|
|
831
|
+
color: var(--ig-text-muted);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
.ig-recovery-now {
|
|
835
|
+
color: var(--ig-state-conflict);
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.ig-recovery-diff-empty {
|
|
839
|
+
margin: 0;
|
|
840
|
+
padding-top: var(--ig-space-tight);
|
|
841
|
+
border-top: var(--ig-stroke) solid var(--ig-line);
|
|
842
|
+
font-size: var(--ig-font-size-small);
|
|
843
|
+
color: var(--ig-text-muted);
|
|
844
|
+
}
|
|
332
845
|
`;
|
|
333
846
|
//# sourceMappingURL=styles.js.map
|