@issuegraph/viewer 0.12.0 → 0.13.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.
Files changed (43) hide show
  1. package/README.md +13 -0
  2. package/dist/index.d.ts +5 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/mount.d.ts +20 -1
  7. package/dist/mount.d.ts.map +1 -1
  8. package/dist/mount.js +228 -18
  9. package/dist/mount.js.map +1 -1
  10. package/dist/navigation.d.ts +26 -3
  11. package/dist/navigation.d.ts.map +1 -1
  12. package/dist/navigation.js +34 -2
  13. package/dist/navigation.js.map +1 -1
  14. package/dist/parts.d.ts +15 -1
  15. package/dist/parts.d.ts.map +1 -1
  16. package/dist/parts.js +35 -1
  17. package/dist/parts.js.map +1 -1
  18. package/dist/projections/graph.d.ts.map +1 -1
  19. package/dist/projections/graph.js +42 -17
  20. package/dist/projections/graph.js.map +1 -1
  21. package/dist/projections/linear.d.ts +25 -2
  22. package/dist/projections/linear.d.ts.map +1 -1
  23. package/dist/projections/linear.js +16 -8
  24. package/dist/projections/linear.js.map +1 -1
  25. package/dist/projections/tree.d.ts.map +1 -1
  26. package/dist/projections/tree.js +2 -1
  27. package/dist/projections/tree.js.map +1 -1
  28. package/dist/recede.d.ts +40 -0
  29. package/dist/recede.d.ts.map +1 -0
  30. package/dist/recede.js +67 -0
  31. package/dist/recede.js.map +1 -0
  32. package/dist/scene.d.ts +1 -1
  33. package/dist/scene.d.ts.map +1 -1
  34. package/dist/scene.js +5 -3
  35. package/dist/scene.js.map +1 -1
  36. package/dist/selection.d.ts +65 -0
  37. package/dist/selection.d.ts.map +1 -0
  38. package/dist/selection.js +127 -0
  39. package/dist/selection.js.map +1 -0
  40. package/dist/styles.d.ts.map +1 -1
  41. package/dist/styles.js +142 -13
  42. package/dist/styles.js.map +1 -1
  43. package/package.json +1 -1
@@ -0,0 +1,65 @@
1
+ /**
2
+ * The selection set: what the reader has selected, and how a gesture changes it.
3
+ *
4
+ * It owns the set and nothing else, as `recede.ts` owns receding. Every later
5
+ * step that builds a set — the mount's pointer and key input, an editor's —
6
+ * reads its gesture rules here, so no shell writes a rule of its own.
7
+ *
8
+ * A SELECTION IS TAGGED, NEVER A BARE STRING. `nextSelection` takes and returns
9
+ * a `ViewerSelection`, so it always knows an issue from a relationship and never
10
+ * guesses from the shape of a string. The tag is decided once, at the edge, by
11
+ * `viewerSelectionOf`, against the document.
12
+ *
13
+ * THE STORED FORM is `string | readonly string[] | null` — the shape
14
+ * `RecedeSelection.key` already takes. One issue or one relationship is a
15
+ * string; two or more issues are a frozen array in addition order. An empty or
16
+ * one-key array is never stored, so a single selection has exactly one
17
+ * spelling and every single-key caller keeps working unchanged.
18
+ */
19
+ import type { NormalizedDocument } from './document.ts';
20
+ export type ViewerSelection = {
21
+ readonly kind: 'none';
22
+ } | {
23
+ readonly kind: 'edge';
24
+ readonly edgeId: string;
25
+ } | {
26
+ readonly kind: 'issues';
27
+ readonly keys: readonly string[];
28
+ };
29
+ /** What the reader did, as the set rules read it. */
30
+ export type SelectionGesture = {
31
+ readonly kind: 'replace' | 'toggle' | 'range';
32
+ readonly key: string;
33
+ } | {
34
+ readonly kind: 'edge';
35
+ readonly edgeId: string;
36
+ } | {
37
+ readonly kind: 'clear';
38
+ } | {
39
+ readonly kind: 'limit-to-one';
40
+ };
41
+ /** A selection as hosts store it and the projections draw it. */
42
+ export type StoredSelection = string | readonly string[] | null;
43
+ /** Below this width a box is narrow, and a set narrows to one issue. */
44
+ export declare const NARROW_WIDTH = 640;
45
+ /** The selection after `gesture`, over the issues in `rankOrder`. */
46
+ export declare function nextSelection(current: ViewerSelection, gesture: SelectionGesture, rankOrder: readonly string[]): ViewerSelection;
47
+ /**
48
+ * A stored selection, tagged by the document: a string one of its edges'
49
+ * identities matches is a relationship, and any other string is an issue.
50
+ */
51
+ export declare function viewerSelectionOf(document: NormalizedDocument, selected: StoredSelection): ViewerSelection;
52
+ /** The stored form: never an empty or a one-key array. */
53
+ export declare function storedSelectionOf(selection: ViewerSelection): StoredSelection;
54
+ /** Whether two selections are the same, by value and in addition order. */
55
+ export declare function sameSelection(a: ViewerSelection, b: ViewerSelection): boolean;
56
+ /** Whether a box is narrow: under 640 wide, and not the all-zero box of an unlaid-out element. */
57
+ export declare function isNarrowBox(box: {
58
+ readonly width: number;
59
+ readonly height: number;
60
+ }): boolean;
61
+ /** Every key a stored selection names, in addition order. */
62
+ export declare function selectedKeysOf(selected: StoredSelection | undefined): readonly string[];
63
+ /** Whether a stored selection names `key`. */
64
+ export declare function isSelectedKey(selected: StoredSelection | undefined, key: string): boolean;
65
+ //# sourceMappingURL=selection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.d.ts","sourceRoot":"","sources":["../src/selection.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAExD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzB;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAElE,qDAAqD;AACrD,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,OAAO,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GACvE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAC1B;IAAE,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAEtC,iEAAiE;AACjE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;AAEhE,wEAAwE;AACxE,eAAO,MAAM,YAAY,MAAM,CAAC;AAiDhC,qEAAqE;AACrE,wBAAgB,aAAa,CAC3B,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,gBAAgB,EACzB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,eAAe,CASjB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,eAAe,GAAG,eAAe,CAO1G;AAED,0DAA0D;AAC1D,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,eAAe,GAAG,eAAe,CAM7E;AAQD,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,eAAe,GAAG,OAAO,CAM7E;AAED,kGAAkG;AAClG,wBAAgB,WAAW,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAG7F;AAED,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAGvF;AAED,8CAA8C;AAC9C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,eAAe,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAEzF"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * The selection set: what the reader has selected, and how a gesture changes it.
3
+ *
4
+ * It owns the set and nothing else, as `recede.ts` owns receding. Every later
5
+ * step that builds a set — the mount's pointer and key input, an editor's —
6
+ * reads its gesture rules here, so no shell writes a rule of its own.
7
+ *
8
+ * A SELECTION IS TAGGED, NEVER A BARE STRING. `nextSelection` takes and returns
9
+ * a `ViewerSelection`, so it always knows an issue from a relationship and never
10
+ * guesses from the shape of a string. The tag is decided once, at the edge, by
11
+ * `viewerSelectionOf`, against the document.
12
+ *
13
+ * THE STORED FORM is `string | readonly string[] | null` — the shape
14
+ * `RecedeSelection.key` already takes. One issue or one relationship is a
15
+ * string; two or more issues are a frozen array in addition order. An empty or
16
+ * one-key array is never stored, so a single selection has exactly one
17
+ * spelling and every single-key caller keeps working unchanged.
18
+ */
19
+ import { edgeIdentity } from '@issuegraph/core';
20
+ /** Below this width a box is narrow, and a set narrows to one issue. */
21
+ export const NARROW_WIDTH = 640;
22
+ const NONE = Object.freeze({ kind: 'none' });
23
+ function issues(keys) {
24
+ return keys.length === 0 ? NONE : { kind: 'issues', keys: Object.freeze([...keys]) };
25
+ }
26
+ /** The issue keys of a selection, in addition order; none for a relationship. */
27
+ function issueKeys(selection) {
28
+ return selection.kind === 'issues' ? selection.keys : [];
29
+ }
30
+ function toggled(current, key) {
31
+ const keys = issueKeys(current);
32
+ return keys.includes(key) ? issues(keys.filter((member) => member !== key)) : issues([...keys, key]);
33
+ }
34
+ /** `keys`, with `key` moved to the end — added last, wherever it was. */
35
+ function addedLast(keys, key) {
36
+ return [...keys.filter((member) => member !== key), key];
37
+ }
38
+ /**
39
+ * A Shift range: from the most recently added key to `key`, in rank order.
40
+ *
41
+ * The keys between are appended walking from the anchor, so a range upward
42
+ * adds the nearer keys first; keys already present stay where they are; the
43
+ * clicked key ends the set. With no issue to extend from it is a replace, and
44
+ * when either end has no rank the clicked key is added alone.
45
+ */
46
+ function ranged(current, key, rankOrder) {
47
+ const keys = issueKeys(current);
48
+ const anchor = keys.at(-1);
49
+ if (anchor === undefined)
50
+ return issues([key]);
51
+ const from = rankOrder.indexOf(anchor);
52
+ const to = rankOrder.indexOf(key);
53
+ if (from === -1 || to === -1)
54
+ return issues(addedLast(keys, key));
55
+ const step = to > from ? 1 : -1;
56
+ const between = Array.from({ length: Math.abs(to - from) }, (_, index) => rankOrder[from + step * (index + 1)])
57
+ .filter((member) => member !== undefined && !keys.includes(member));
58
+ return issues(addedLast([...keys, ...between], key));
59
+ }
60
+ function limitedToOne(current) {
61
+ const last = issueKeys(current).at(-1);
62
+ return current.kind === 'issues' && last !== undefined ? issues([last]) : current;
63
+ }
64
+ /** The selection after `gesture`, over the issues in `rankOrder`. */
65
+ export function nextSelection(current, gesture, rankOrder) {
66
+ switch (gesture.kind) {
67
+ case 'replace': return issues([gesture.key]);
68
+ case 'toggle': return toggled(current, gesture.key);
69
+ case 'range': return ranged(current, gesture.key, rankOrder);
70
+ case 'edge': return { kind: 'edge', edgeId: gesture.edgeId };
71
+ case 'clear': return NONE;
72
+ case 'limit-to-one': return limitedToOne(current);
73
+ }
74
+ }
75
+ /**
76
+ * A stored selection, tagged by the document: a string one of its edges'
77
+ * identities matches is a relationship, and any other string is an issue.
78
+ */
79
+ export function viewerSelectionOf(document, selected) {
80
+ if (selected === null)
81
+ return NONE;
82
+ if (typeof selected === 'string') {
83
+ const isEdge = document.edges.some((edge) => edgeIdentity(edge.field, edge.from, edge.to) === selected);
84
+ return isEdge ? { kind: 'edge', edgeId: selected } : issues([selected]);
85
+ }
86
+ return issues([...new Set(selected)]);
87
+ }
88
+ /** The stored form: never an empty or a one-key array. */
89
+ export function storedSelectionOf(selection) {
90
+ switch (selection.kind) {
91
+ case 'none': return null;
92
+ case 'edge': return selection.edgeId;
93
+ case 'issues': return storedKeys(selection.keys);
94
+ }
95
+ }
96
+ function storedKeys(keys) {
97
+ if (keys.length === 0)
98
+ return null;
99
+ if (keys.length === 1)
100
+ return keys[0] ?? null;
101
+ return Object.freeze([...keys]);
102
+ }
103
+ /** Whether two selections are the same, by value and in addition order. */
104
+ export function sameSelection(a, b) {
105
+ if (a.kind === 'edge' && b.kind === 'edge')
106
+ return a.edgeId === b.edgeId;
107
+ if (a.kind === 'issues' && b.kind === 'issues') {
108
+ return a.keys.length === b.keys.length && a.keys.every((key, index) => b.keys[index] === key);
109
+ }
110
+ return a.kind === b.kind;
111
+ }
112
+ /** Whether a box is narrow: under 640 wide, and not the all-zero box of an unlaid-out element. */
113
+ export function isNarrowBox(box) {
114
+ const unmeasured = box.width === 0 && box.height === 0;
115
+ return box.width < NARROW_WIDTH && !unmeasured;
116
+ }
117
+ /** Every key a stored selection names, in addition order. */
118
+ export function selectedKeysOf(selected) {
119
+ if (selected === null || selected === undefined)
120
+ return [];
121
+ return typeof selected === 'string' ? [selected] : selected;
122
+ }
123
+ /** Whether a stored selection names `key`. */
124
+ export function isSelectedKey(selected, key) {
125
+ return selectedKeysOf(selected).includes(key);
126
+ }
127
+ //# sourceMappingURL=selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection.js","sourceRoot":"","sources":["../src/selection.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AA+PH,eAAO,MAAM,gBAAgB,QAqhD5B,CAAC"}
1
+ {"version":3,"file":"styles.d.ts","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAqQH,eAAO,MAAM,gBAAgB,QAkpD5B,CAAC"}
package/dist/styles.js CHANGED
@@ -22,6 +22,7 @@
22
22
  * hairlines — and a host that wants the panel suppressed overrides the four
23
23
  * properties on `.ig-viewer`.
24
24
  */
25
+ import { RECEDE_ALPHA } from "./recede.js";
25
26
  /**
26
27
  * §17j's rail density, written once and emitted under two keys.
27
28
  *
@@ -274,6 +275,9 @@ ${scope} .ig-slot[aria-expanded='true'] .ig-badge[data-priority='query'] {
274
275
  }
275
276
  `;
276
277
  }
278
+ /** `RECEDE_ALPHA` as a `color-mix` share, so a receded station's ring and a
279
+ * receded line draw at one strength from one source. */
280
+ const RECEDE_PERCENT = `${RECEDE_ALPHA * 100}%`;
277
281
  export const viewerStylesheet = `
278
282
  .ig-viewer {
279
283
  background: var(--ig-bg);
@@ -897,7 +901,12 @@ ${railDensity(".ig-viewer[data-density='dense']")}
897
901
  );
898
902
  }
899
903
 
904
+ /* A SELECTED ROW IS FILLED WITH --ig-surface, the stronger of the two
905
+ surfaces. --ig-surface-2 is what a receded row takes, so a selected row never
906
+ reads as receded. background-color, not the shorthand, so a held row keeps
907
+ its hatch when it is selected. */
900
908
  .ig-slot[aria-current='true'] {
909
+ background-color: var(--ig-surface);
901
910
  box-shadow: inset var(--ig-band-rail) 0 0 var(--ig-accent);
902
911
  }
903
912
 
@@ -905,13 +914,20 @@ ${railDensity(".ig-viewer[data-density='dense']")}
905
914
  look — so clicking a gutter, excluded or tracker-held node set aria-current on
906
915
  the group and changed nothing a reader could see. A pointer does not normally
907
916
  raise :focus-visible either, so those selections had no visible state at all
908
- on the channel most likely to make them. Same accent the rail uses, so one
909
- selection reads the same whichever surface drew it. */
917
+ on the channel most likely to make them. A SELECTED NODE IS INVERTED — the
918
+ text colour fills it and its label takes --ig-bg — the same
919
+ look a selected card takes, so one selection reads the same whichever
920
+ surface drew it. */
910
921
  .ig-node-group[aria-current='true'] .ig-node {
911
- stroke: var(--ig-accent);
922
+ fill: var(--ig-text);
923
+ stroke: var(--ig-text);
912
924
  stroke-width: calc(var(--ig-stroke) * 2);
913
925
  }
914
926
 
927
+ .ig-node-group[aria-current='true'] .ig-node-label {
928
+ fill: var(--ig-bg);
929
+ }
930
+
915
931
  /* The rank track: figure over dot, centred, so the title column starts at one
916
932
  x on every row whether or not the row has a number to print. */
917
933
  .ig-rank-cell {
@@ -1016,16 +1032,17 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1016
1032
  overflow-wrap: anywhere;
1017
1033
  }
1018
1034
 
1019
- .ig-slot[data-held='true'] .ig-title,
1020
1035
  .ig-footer .ig-title {
1021
1036
  color: var(--ig-text-body);
1022
1037
  }
1023
1038
 
1024
- /* A held row's CONTENT recedes, not its position. The frame dims the body and
1025
- leaves the rank track at full strength, so the row still reads as occupying
1026
- the slot it would have taken. */
1027
- .ig-slot[data-held='true'] .ig-row-body {
1028
- opacity: 0.72;
1039
+ /* A held row's CONTENT recedes, not its position. The body's text turns muted
1040
+ and the rank track stays at full strength, so the row still reads as
1041
+ occupying the slot it would have taken. By colour, never by opacity: fading
1042
+ the text would drop it below the contrast the theme's text roles promise. */
1043
+ .ig-slot[data-held='true'] .ig-row-body,
1044
+ .ig-slot[data-held='true'] .ig-title {
1045
+ color: var(--ig-text-muted);
1029
1046
  }
1030
1047
 
1031
1048
  /* The isolated-issue tally sits directly on the panel, outside the padded
@@ -1330,7 +1347,7 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1330
1347
  /* THE RANKED ROW'S SELECTED BAND, and its fill: one selection, one look,
1331
1348
  whichever part of the list it was made in. */
1332
1349
  .ig-footer-row[aria-current='true'] {
1333
- background: color-mix(in srgb, var(--ig-accent) var(--ig-tint-fill), transparent);
1350
+ background: var(--ig-surface);
1334
1351
  box-shadow: inset var(--ig-band-rail) 0 0 var(--ig-accent);
1335
1352
  }
1336
1353
 
@@ -1440,7 +1457,7 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1440
1457
  .ig-card[data-column='right'] {
1441
1458
  background: transparent;
1442
1459
  border-style: dashed;
1443
- opacity: 0.8;
1460
+ color: var(--ig-text-muted);
1444
1461
  }
1445
1462
 
1446
1463
  .ig-card[data-exclusion='true'] {
@@ -1451,7 +1468,14 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1451
1468
  .ig-card[data-held='true'] {
1452
1469
  background: transparent;
1453
1470
  border-style: dashed;
1454
- opacity: 0.75;
1471
+ color: var(--ig-text-muted);
1472
+ }
1473
+
1474
+ /* The card's own text roles set their colour, so the card's muted colour has
1475
+ to be named on them too, or only the unstyled text would dim. */
1476
+ .ig-card[data-column='right'] .ig-title,
1477
+ .ig-card[data-held='true'] .ig-title {
1478
+ color: var(--ig-text-muted);
1455
1479
  }
1456
1480
 
1457
1481
  .ig-card[data-now='true'] {
@@ -1464,9 +1488,23 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1464
1488
  border-color: var(--ig-accent);
1465
1489
  }
1466
1490
 
1491
+ /* A SELECTED CARD IS INVERTED: filled with --ig-text, every text on it in
1492
+ --ig-bg. Every descendant is named, because the card's
1493
+ text roles set their own colours and a chip or badge tinted for the light
1494
+ ground would vanish on the dark one. Each member of a selected set is drawn
1495
+ this way; what is outside the set recedes. */
1467
1496
  .ig-rail-row[aria-current='true'] .ig-card {
1468
- border-color: var(--ig-accent);
1497
+ background: var(--ig-text);
1498
+ border-color: var(--ig-text);
1499
+ border-style: solid;
1469
1500
  box-shadow: 0 0 0 var(--ig-band-rail) color-mix(in srgb, var(--ig-accent) var(--ig-tint-border), transparent);
1501
+ color: var(--ig-bg);
1502
+ }
1503
+
1504
+ .ig-rail-row[aria-current='true'] .ig-card * {
1505
+ background: transparent;
1506
+ border-color: var(--ig-bg);
1507
+ color: var(--ig-bg);
1470
1508
  }
1471
1509
 
1472
1510
  /* The station column: a disc on the spine, carrying the rank the row would
@@ -1619,6 +1657,97 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1619
1657
  .ig-terminal[data-edge='duplicate-of'] { color: var(--ig-edge-duplicate-of); }
1620
1658
  .ig-terminal[data-edge='decomposed-from'] { color: var(--ig-edge-decomposed-from); }
1621
1659
 
1660
+ /* ── what recedes around a selection ───────────────────────────────────── */
1661
+
1662
+ /* EVERYTHING THAT DOES NOT TOUCH THE SELECTION RECEDES, so its neighbours read
1663
+ first. The graph stamps data-recede='true' on each receding card row, spine
1664
+ station, footer row, line and terminal, and the list stamps each receding
1665
+ order row and footer row; these rules draw the stamp.
1666
+
1667
+ NO RULE HERE USES opacity OR filter. Fading a card by opacity fades its text
1668
+ below the contrast the theme's text roles promise, so a card recedes by
1669
+ colour instead: the second surface, with muted labels, and a list row
1670
+ recedes the same way a card does. A line or terminal
1671
+ recedes by stroke-opacity and fill-opacity on the stamped element itself,
1672
+ never on a kind's class, so the legend's samples never dim. No rule touches
1673
+ a dash, a border style or a stroke width: those carry each kind's line.
1674
+
1675
+ THESE RULES COME LAST AND MATCH OR BEAT EVERY VARIANT'S SPECIFICITY, so a
1676
+ held, unit, gutter or now card still recedes the same way. styles.test.ts
1677
+ checks that order. */
1678
+ .ig-canvas path[data-recede='true'],
1679
+ .ig-canvas circle[data-recede='true'] {
1680
+ fill-opacity: ${RECEDE_ALPHA};
1681
+ stroke-opacity: ${RECEDE_ALPHA};
1682
+ }
1683
+
1684
+ .ig-rail-row[data-recede='true'] .ig-card {
1685
+ background: var(--ig-surface-2);
1686
+ }
1687
+
1688
+ /* A LIST ROW TAKES THE CARD'S GROUND through background-color alone, so a held
1689
+ row keeps its hatch, which is a background-image, on the second surface. The
1690
+ panel class lifts each rule to the card rule's specificity. The footer rule
1691
+ is scoped to the list, whose root and detached footer both carry ig-linear,
1692
+ because the graph draws its footer rows without a ground. */
1693
+ .ig-viewer .ig-slot[data-recede='true'],
1694
+ .ig-linear .ig-footer-row[data-recede='true'] {
1695
+ background-color: var(--ig-surface-2);
1696
+ }
1697
+
1698
+ .ig-rail-row[data-recede='true'] .ig-title,
1699
+ .ig-rail-row[data-recede='true'] .ig-id,
1700
+ .ig-rail-row[data-recede='true'] .ig-hold,
1701
+ .ig-rail-row[data-recede='true'] .ig-unit-note,
1702
+ .ig-slot[data-recede='true'] .ig-title,
1703
+ .ig-slot[data-recede='true'] .ig-id,
1704
+ .ig-slot[data-recede='true'] .ig-hold,
1705
+ .ig-slot[data-recede='true'] .ig-unit-note,
1706
+ .ig-footer-row[data-recede='true'] .ig-title,
1707
+ .ig-linear .ig-footer-row[data-recede='true'] .ig-id {
1708
+ color: var(--ig-text-muted);
1709
+ }
1710
+
1711
+ /* The priority tag keeps its words and loses its chip, so a receded card
1712
+ carries no filled shape that competes with the kept ones. The border turns
1713
+ transparent rather than going, so the tag keeps its size and nothing moves. */
1714
+ .ig-rail-row[data-recede='true'] .ig-badge[data-priority],
1715
+ .ig-slot[data-recede='true'] .ig-badge[data-priority] {
1716
+ background: transparent;
1717
+ border-color: transparent;
1718
+ color: var(--ig-text);
1719
+ }
1720
+
1721
+ /* A RECEDED STATION MIXES ITS OWN COLOURS WITH THE PAGE GROUND, never with
1722
+ transparent and never by opacity: the station has to stay opaque, because
1723
+ it sits on the spine line and covers it. Mixing over --ig-bg also makes what
1724
+ is drawn equal to what the contrast test composites. Each variant names its
1725
+ own hue, in the same order the variants above set it.
1726
+
1727
+ THE RANK NUMERAL IS TEXT AND KEEPS 4.5:1 ON WHAT IT SITS ON. A ring, dashed
1728
+ or serialize station is hollow, so its numeral sits on --ig-bg and reads
1729
+ --ig-text-muted, like every other receded label. A filled station's numeral
1730
+ sits on its mixed fill instead, and --ig-text-muted there falls under 4.5:1
1731
+ in both themes, so it reads --ig-text, which clears it. theme.test.ts
1732
+ measures both. */
1733
+ .ig-spine-station[data-recede='true'] {
1734
+ border-color: color-mix(in srgb, var(--ig-station-ready) ${RECEDE_PERCENT}, var(--ig-bg));
1735
+ color: var(--ig-text-muted);
1736
+ }
1737
+
1738
+ .ig-spine-station[data-fill='filled'][data-recede='true'] {
1739
+ background: color-mix(in srgb, var(--ig-station-ready) ${RECEDE_PERCENT}, var(--ig-bg));
1740
+ color: var(--ig-text);
1741
+ }
1742
+
1743
+ .ig-spine-station[data-fill='dashed'][data-recede='true'] {
1744
+ border-color: color-mix(in srgb, var(--ig-station-held) ${RECEDE_PERCENT}, var(--ig-bg));
1745
+ }
1746
+
1747
+ .ig-spine-station[data-wait='serialize'][data-recede='true'] {
1748
+ border-color: color-mix(in srgb, var(--ig-edge-serialize-with) ${RECEDE_PERCENT}, var(--ig-bg));
1749
+ }
1750
+
1622
1751
  /* ── refusals and empty states ─────────────────────────────────────────── */
1623
1752
 
1624
1753
  .ig-refusal,
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO;EACP,KAAK;;;;;;;;;;EAUL,KAAK;;;;EAIL,KAAK;;;;;;;;;EASL,KAAK;;;;;;;;;;EAUL,KAAK;;;;;;;;;;;;;EAaL,KAAK;;;;;;;;EAQL,KAAK;;;;;;;;;;;;;;;;;;EAkBL,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BL,KAAK;;;;EAIL,KAAK;EACL,KAAK;;;;;;;EAOL,KAAK;;;;;;;;;;;EAWL,KAAK;;;;;;;;;EASL,KAAK;;;;;;;;;;;;EAYL,KAAK;;;;;EAKL,KAAK;;;;;EAKL,KAAK;;;;;;;EAOL,KAAK;;;;;;;;;;;;;;;;;;;;;;;EAuBL,KAAK;EACL,KAAK;EACL,KAAK;;;;;;;;;;;;;;;;EAgBL,KAAK;;;;EAIL,KAAK;;;;;;;;;EASL,KAAK;;;;EAIL,KAAK;;;CAGN,CAAC;AACF,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqiB9B,WAAW,CAAC,gCAAgC,CAAC;;;;;;;;;;;;;EAa7C,WAAW,CAAC,kCAAkC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAm+BhD,CAAC"}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@issuegraph/viewer",
3
- "version": "0.12.0",
3
+ "version": "0.13.0",
4
4
  "description": "Render an Issuegraph document as a work order — the ordered spine with readiness stations, the five edge treatments, and three projections. Rendering only: no fetching, no mutation, no auth, and every value themeable through CSS custom properties.",
5
5
  "keywords": [
6
6
  "issuegraph",