@issuegraph/viewer 0.11.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 (47) hide show
  1. package/README.md +13 -0
  2. package/dist/document.d.ts +24 -3
  3. package/dist/document.d.ts.map +1 -1
  4. package/dist/document.js +10 -0
  5. package/dist/document.js.map +1 -1
  6. package/dist/index.d.ts +5 -1
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +2 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/mount.d.ts +20 -1
  11. package/dist/mount.d.ts.map +1 -1
  12. package/dist/mount.js +228 -18
  13. package/dist/mount.js.map +1 -1
  14. package/dist/navigation.d.ts +26 -3
  15. package/dist/navigation.d.ts.map +1 -1
  16. package/dist/navigation.js +34 -2
  17. package/dist/navigation.js.map +1 -1
  18. package/dist/parts.d.ts +19 -4
  19. package/dist/parts.d.ts.map +1 -1
  20. package/dist/parts.js +83 -6
  21. package/dist/parts.js.map +1 -1
  22. package/dist/projections/graph.d.ts.map +1 -1
  23. package/dist/projections/graph.js +42 -17
  24. package/dist/projections/graph.js.map +1 -1
  25. package/dist/projections/linear.d.ts +25 -2
  26. package/dist/projections/linear.d.ts.map +1 -1
  27. package/dist/projections/linear.js +16 -8
  28. package/dist/projections/linear.js.map +1 -1
  29. package/dist/projections/tree.d.ts.map +1 -1
  30. package/dist/projections/tree.js +2 -1
  31. package/dist/projections/tree.js.map +1 -1
  32. package/dist/recede.d.ts +40 -0
  33. package/dist/recede.d.ts.map +1 -0
  34. package/dist/recede.js +67 -0
  35. package/dist/recede.js.map +1 -0
  36. package/dist/scene.d.ts +1 -1
  37. package/dist/scene.d.ts.map +1 -1
  38. package/dist/scene.js +5 -3
  39. package/dist/scene.js.map +1 -1
  40. package/dist/selection.d.ts +65 -0
  41. package/dist/selection.d.ts.map +1 -0
  42. package/dist/selection.js +127 -0
  43. package/dist/selection.js.map +1 -0
  44. package/dist/styles.d.ts.map +1 -1
  45. package/dist/styles.js +192 -13
  46. package/dist/styles.js.map +1 -1
  47. 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,QAm+C5B,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);
@@ -588,6 +592,28 @@ export const viewerStylesheet = `
588
592
  outline-offset: var(--ig-space-micro);
589
593
  }
590
594
 
595
+ /* §16g's FIRST-IMPORT BAR (#129): a track the host's share fills, in the
596
+ importing state's own gold, above the figure it repeats. Rounded at the
597
+ radius the small badge already uses. */
598
+ .ig-notice-meter {
599
+ block-size: var(--ig-space-tight);
600
+ display: block;
601
+ inline-size: 100%;
602
+ margin-block-start: var(--ig-space-snug);
603
+ }
604
+
605
+ .ig-notice-meter-track {
606
+ fill: var(--ig-surface);
607
+ }
608
+
609
+ .ig-notice-meter-fill {
610
+ fill: var(--ig-state-conflict);
611
+ }
612
+
613
+ .ig-notice-meter rect {
614
+ rx: calc(var(--ig-space-tight) / 2);
615
+ }
616
+
591
617
  .ig-notice[data-ig-condition='importing'] .ig-notice-head {
592
618
  color: var(--ig-state-conflict);
593
619
  }
@@ -596,6 +622,34 @@ export const viewerStylesheet = `
596
622
  color: var(--ig-state-failed);
597
623
  }
598
624
 
625
+ /* THE EMPTY STATE IS A CENTRED CARD, NOT A BANNER (#132). The shared rule above
626
+ is right for importing and error, whose frames sit left with the control
627
+ pushed aside; §16g's empty frame centres everything, leads with the dashed
628
+ station row, and puts its control beneath the prose. Its frame pads it 30px
629
+ by 20px: the block inset here is 2 x 16px, the nearest the space scale draws. */
630
+ .ig-notice[data-ig-condition='empty'] {
631
+ align-items: center;
632
+ flex-direction: column;
633
+ justify-content: flex-start;
634
+ padding: calc(var(--ig-space-loose) * 2) var(--ig-space-wide);
635
+ text-align: center;
636
+ }
637
+
638
+ .ig-notice[data-ig-condition='empty'] .ig-notice-text {
639
+ align-items: center;
640
+ }
641
+
642
+ .ig-notice[data-ig-condition='empty'] .ig-notice-head {
643
+ justify-content: center;
644
+ }
645
+
646
+ .ig-notice-stations {
647
+ display: flex;
648
+ gap: var(--ig-space-tight);
649
+ justify-content: center;
650
+ margin-block-end: var(--ig-space);
651
+ }
652
+
599
653
  /* ── the adoption line ─────────────────────────────────────────────────── */
600
654
 
601
655
  /* ONE QUIET LINE, which is the whole of what the design asks for here: the
@@ -847,7 +901,12 @@ ${railDensity(".ig-viewer[data-density='dense']")}
847
901
  );
848
902
  }
849
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. */
850
908
  .ig-slot[aria-current='true'] {
909
+ background-color: var(--ig-surface);
851
910
  box-shadow: inset var(--ig-band-rail) 0 0 var(--ig-accent);
852
911
  }
853
912
 
@@ -855,13 +914,20 @@ ${railDensity(".ig-viewer[data-density='dense']")}
855
914
  look — so clicking a gutter, excluded or tracker-held node set aria-current on
856
915
  the group and changed nothing a reader could see. A pointer does not normally
857
916
  raise :focus-visible either, so those selections had no visible state at all
858
- on the channel most likely to make them. Same accent the rail uses, so one
859
- 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. */
860
921
  .ig-node-group[aria-current='true'] .ig-node {
861
- stroke: var(--ig-accent);
922
+ fill: var(--ig-text);
923
+ stroke: var(--ig-text);
862
924
  stroke-width: calc(var(--ig-stroke) * 2);
863
925
  }
864
926
 
927
+ .ig-node-group[aria-current='true'] .ig-node-label {
928
+ fill: var(--ig-bg);
929
+ }
930
+
865
931
  /* The rank track: figure over dot, centred, so the title column starts at one
866
932
  x on every row whether or not the row has a number to print. */
867
933
  .ig-rank-cell {
@@ -966,16 +1032,17 @@ ${railDensity(".ig-viewer[data-density='dense']")}
966
1032
  overflow-wrap: anywhere;
967
1033
  }
968
1034
 
969
- .ig-slot[data-held='true'] .ig-title,
970
1035
  .ig-footer .ig-title {
971
1036
  color: var(--ig-text-body);
972
1037
  }
973
1038
 
974
- /* A held row's CONTENT recedes, not its position. The frame dims the body and
975
- leaves the rank track at full strength, so the row still reads as occupying
976
- the slot it would have taken. */
977
- .ig-slot[data-held='true'] .ig-row-body {
978
- 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);
979
1046
  }
980
1047
 
981
1048
  /* The isolated-issue tally sits directly on the panel, outside the padded
@@ -1280,7 +1347,7 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1280
1347
  /* THE RANKED ROW'S SELECTED BAND, and its fill: one selection, one look,
1281
1348
  whichever part of the list it was made in. */
1282
1349
  .ig-footer-row[aria-current='true'] {
1283
- background: color-mix(in srgb, var(--ig-accent) var(--ig-tint-fill), transparent);
1350
+ background: var(--ig-surface);
1284
1351
  box-shadow: inset var(--ig-band-rail) 0 0 var(--ig-accent);
1285
1352
  }
1286
1353
 
@@ -1390,7 +1457,7 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1390
1457
  .ig-card[data-column='right'] {
1391
1458
  background: transparent;
1392
1459
  border-style: dashed;
1393
- opacity: 0.8;
1460
+ color: var(--ig-text-muted);
1394
1461
  }
1395
1462
 
1396
1463
  .ig-card[data-exclusion='true'] {
@@ -1401,7 +1468,14 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1401
1468
  .ig-card[data-held='true'] {
1402
1469
  background: transparent;
1403
1470
  border-style: dashed;
1404
- 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);
1405
1479
  }
1406
1480
 
1407
1481
  .ig-card[data-now='true'] {
@@ -1414,9 +1488,23 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1414
1488
  border-color: var(--ig-accent);
1415
1489
  }
1416
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. */
1417
1496
  .ig-rail-row[aria-current='true'] .ig-card {
1418
- border-color: var(--ig-accent);
1497
+ background: var(--ig-text);
1498
+ border-color: var(--ig-text);
1499
+ border-style: solid;
1419
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);
1420
1508
  }
1421
1509
 
1422
1510
  /* The station column: a disc on the spine, carrying the rank the row would
@@ -1569,6 +1657,97 @@ ${railDensity(".ig-viewer[data-density='dense']")}
1569
1657
  .ig-terminal[data-edge='duplicate-of'] { color: var(--ig-edge-duplicate-of); }
1570
1658
  .ig-terminal[data-edge='decomposed-from'] { color: var(--ig-edge-decomposed-from); }
1571
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
+
1572
1751
  /* ── refusals and empty states ─────────────────────────────────────────── */
1573
1752
 
1574
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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmf9B,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.11.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",