@kgdiff/viewer 0.0.0-stage → 0.2.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 (155) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +52 -2
  3. package/dist/compute-loader.d.ts +13 -0
  4. package/dist/compute-loader.d.ts.map +1 -0
  5. package/dist/compute-loader.js +46 -0
  6. package/dist/compute-loader.js.map +1 -0
  7. package/dist/compute.d.ts +8 -0
  8. package/dist/compute.d.ts.map +1 -0
  9. package/dist/compute.js +8 -0
  10. package/dist/compute.js.map +1 -0
  11. package/dist/controller.d.ts +199 -0
  12. package/dist/controller.d.ts.map +1 -0
  13. package/dist/controller.js +1254 -0
  14. package/dist/controller.js.map +1 -0
  15. package/dist/dom.d.ts +32 -0
  16. package/dist/dom.d.ts.map +1 -0
  17. package/dist/dom.js +105 -0
  18. package/dist/dom.js.map +1 -0
  19. package/dist/element.d.ts +43 -0
  20. package/dist/element.d.ts.map +1 -0
  21. package/dist/element.js +656 -0
  22. package/dist/element.js.map +1 -0
  23. package/dist/framing.d.ts +45 -0
  24. package/dist/framing.d.ts.map +1 -0
  25. package/dist/framing.js +107 -0
  26. package/dist/framing.js.map +1 -0
  27. package/dist/hash-sync.d.ts +18 -0
  28. package/dist/hash-sync.d.ts.map +1 -0
  29. package/dist/hash-sync.js +45 -0
  30. package/dist/hash-sync.js.map +1 -0
  31. package/dist/i18n.d.ts +222 -0
  32. package/dist/i18n.d.ts.map +1 -0
  33. package/dist/i18n.js +434 -0
  34. package/dist/i18n.js.map +1 -0
  35. package/dist/icons.d.ts +37 -0
  36. package/dist/icons.d.ts.map +1 -0
  37. package/dist/icons.js +36 -0
  38. package/dist/icons.js.map +1 -0
  39. package/dist/index.d.ts +151 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +41 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/keyboard.d.ts +64 -0
  44. package/dist/keyboard.d.ts.map +1 -0
  45. package/dist/keyboard.js +95 -0
  46. package/dist/keyboard.js.map +1 -0
  47. package/dist/list-model.d.ts +35 -0
  48. package/dist/list-model.d.ts.map +1 -0
  49. package/dist/list-model.js +70 -0
  50. package/dist/list-model.js.map +1 -0
  51. package/dist/payload.d.ts +10 -0
  52. package/dist/payload.d.ts.map +1 -0
  53. package/dist/payload.js +138 -0
  54. package/dist/payload.js.map +1 -0
  55. package/dist/pipeline.d.ts +31 -0
  56. package/dist/pipeline.d.ts.map +1 -0
  57. package/dist/pipeline.js +122 -0
  58. package/dist/pipeline.js.map +1 -0
  59. package/dist/prefs.d.ts +18 -0
  60. package/dist/prefs.d.ts.map +1 -0
  61. package/dist/prefs.js +38 -0
  62. package/dist/prefs.js.map +1 -0
  63. package/dist/registry.d.ts +3 -0
  64. package/dist/registry.d.ts.map +1 -0
  65. package/dist/registry.js +3 -0
  66. package/dist/registry.js.map +1 -0
  67. package/dist/renderer-port.d.ts +14 -0
  68. package/dist/renderer-port.d.ts.map +1 -0
  69. package/dist/renderer-port.js +16 -0
  70. package/dist/renderer-port.js.map +1 -0
  71. package/dist/replay.d.ts +55 -0
  72. package/dist/replay.d.ts.map +1 -0
  73. package/dist/replay.js +147 -0
  74. package/dist/replay.js.map +1 -0
  75. package/dist/review-store.d.ts +30 -0
  76. package/dist/review-store.d.ts.map +1 -0
  77. package/dist/review-store.js +120 -0
  78. package/dist/review-store.js.map +1 -0
  79. package/dist/search.d.ts +25 -0
  80. package/dist/search.d.ts.map +1 -0
  81. package/dist/search.js +90 -0
  82. package/dist/search.js.map +1 -0
  83. package/dist/standalone/kgdiff-viewer-compute.js +1 -0
  84. package/dist/standalone/kgdiff-viewer.js +5 -0
  85. package/dist/standalone-compute.d.ts +2 -0
  86. package/dist/standalone-compute.d.ts.map +1 -0
  87. package/dist/standalone-compute.js +8 -0
  88. package/dist/standalone-compute.js.map +1 -0
  89. package/dist/standalone.d.ts +2 -0
  90. package/dist/standalone.d.ts.map +1 -0
  91. package/dist/standalone.js +18 -0
  92. package/dist/standalone.js.map +1 -0
  93. package/dist/styles.d.ts +11 -0
  94. package/dist/styles.d.ts.map +1 -0
  95. package/dist/styles.js +622 -0
  96. package/dist/styles.js.map +1 -0
  97. package/dist/text-diff.d.ts +44 -0
  98. package/dist/text-diff.d.ts.map +1 -0
  99. package/dist/text-diff.js +261 -0
  100. package/dist/text-diff.js.map +1 -0
  101. package/dist/ui/context.d.ts +32 -0
  102. package/dist/ui/context.d.ts.map +1 -0
  103. package/dist/ui/context.js +49 -0
  104. package/dist/ui/context.js.map +1 -0
  105. package/dist/ui/detail.d.ts +9 -0
  106. package/dist/ui/detail.d.ts.map +1 -0
  107. package/dist/ui/detail.js +609 -0
  108. package/dist/ui/detail.js.map +1 -0
  109. package/dist/ui/header.d.ts +14 -0
  110. package/dist/ui/header.d.ts.map +1 -0
  111. package/dist/ui/header.js +195 -0
  112. package/dist/ui/header.js.map +1 -0
  113. package/dist/ui/popovers.d.ts +20 -0
  114. package/dist/ui/popovers.d.ts.map +1 -0
  115. package/dist/ui/popovers.js +180 -0
  116. package/dist/ui/popovers.js.map +1 -0
  117. package/dist/ui/sidebar.d.ts +25 -0
  118. package/dist/ui/sidebar.d.ts.map +1 -0
  119. package/dist/ui/sidebar.js +609 -0
  120. package/dist/ui/sidebar.js.map +1 -0
  121. package/dist/ui/stage.d.ts +18 -0
  122. package/dist/ui/stage.d.ts.map +1 -0
  123. package/dist/ui/stage.js +664 -0
  124. package/dist/ui/stage.js.map +1 -0
  125. package/package.json +58 -3
  126. package/src/compute-loader.ts +58 -0
  127. package/src/compute.ts +7 -0
  128. package/src/controller.ts +1393 -0
  129. package/src/dom.ts +131 -0
  130. package/src/element.ts +697 -0
  131. package/src/framing.ts +150 -0
  132. package/src/hash-sync.ts +54 -0
  133. package/src/i18n.ts +467 -0
  134. package/src/icons.ts +48 -0
  135. package/src/index.ts +171 -0
  136. package/src/keyboard.ts +128 -0
  137. package/src/list-model.ts +86 -0
  138. package/src/payload.ts +165 -0
  139. package/src/pipeline.ts +179 -0
  140. package/src/prefs.ts +55 -0
  141. package/src/registry.ts +2 -0
  142. package/src/renderer-port.ts +31 -0
  143. package/src/replay.ts +163 -0
  144. package/src/review-store.ts +125 -0
  145. package/src/search.ts +113 -0
  146. package/src/standalone-compute.ts +8 -0
  147. package/src/standalone.ts +18 -0
  148. package/src/styles.ts +633 -0
  149. package/src/text-diff.ts +263 -0
  150. package/src/ui/context.ts +70 -0
  151. package/src/ui/detail.ts +929 -0
  152. package/src/ui/header.ts +278 -0
  153. package/src/ui/popovers.ts +251 -0
  154. package/src/ui/sidebar.ts +752 -0
  155. package/src/ui/stage.ts +853 -0
package/dist/styles.js ADDED
@@ -0,0 +1,622 @@
1
+ export const FAMILIES = [
2
+ 'added',
3
+ 'removed',
4
+ 'content',
5
+ 'structure',
6
+ 'identity',
7
+ ];
8
+ /** CSS custom properties for `theme` (a `:host` rule body). */
9
+ export function themeVariables(theme) {
10
+ const dark = theme.name === 'dark';
11
+ const vars = {
12
+ 'color-scheme': dark ? 'dark' : 'light',
13
+ '--kg-bg': theme.canvas.background,
14
+ '--kg-grid': theme.canvas.grid,
15
+ '--kg-panel': theme.surface.panel,
16
+ '--kg-raised': theme.surface.raised,
17
+ '--kg-overlay': theme.surface.overlay,
18
+ '--kg-border': theme.surface.border,
19
+ '--kg-border-strong': theme.surface.borderStrong,
20
+ '--kg-control-border': theme.surface.controlBorder,
21
+ '--kg-shadow': theme.surface.shadow,
22
+ '--kg-text': theme.text.primary,
23
+ '--kg-text-2': theme.text.secondary,
24
+ '--kg-text-3': theme.text.muted,
25
+ '--kg-accent': theme.accent.base,
26
+ '--kg-accent-strong': theme.accent.strong,
27
+ '--kg-accent-soft': theme.accent.soft,
28
+ '--kg-accent-text': theme.accent.text,
29
+ '--kg-neutral': theme.neutral.node,
30
+ '--kg-neutral-stroke': theme.neutral.nodeStroke,
31
+ '--kg-neutral-edge': theme.neutral.edge,
32
+ '--kg-font': theme.font.family,
33
+ '--kg-mono': theme.font.mono,
34
+ '--kg-fast': `${theme.motion.fast}ms`,
35
+ '--kg-base': `${theme.motion.base}ms`,
36
+ '--kg-slow': `${theme.motion.slow}ms`,
37
+ '--kg-ease': `cubic-bezier(${theme.motion.easing.join(', ')})`,
38
+ // Derived interaction tints (not color-coded: hover / press / inputs / scrims).
39
+ '--kg-hover': dark ? 'rgba(255,255,255,0.045)' : 'rgba(15,23,42,0.04)',
40
+ '--kg-press': dark ? 'rgba(255,255,255,0.08)' : 'rgba(15,23,42,0.07)',
41
+ '--kg-input': dark ? theme.surface.raised : '#F3F5F8',
42
+ '--kg-selected': dark ? theme.surface.raised : '#F5F7FB',
43
+ '--kg-scrim': dark ? 'rgba(5,7,11,0.56)' : 'rgba(15,23,42,0.18)',
44
+ '--kg-skeleton': dark ? 'rgba(255,255,255,0.05)' : 'rgba(15,23,42,0.05)',
45
+ '--kg-skeleton-hi': dark ? 'rgba(255,255,255,0.09)' : 'rgba(15,23,42,0.09)',
46
+ '--kg-track': dark ? 'rgba(255,255,255,0.08)' : 'rgba(15,23,42,0.08)',
47
+ '--kg-kbd': dark ? 'rgba(255,255,255,0.06)' : 'rgba(15,23,42,0.05)',
48
+ };
49
+ for (const f of FAMILIES) {
50
+ const c = theme.family[f];
51
+ vars[`--kg-${f}`] = c.base;
52
+ vars[`--kg-${f}-strong`] = c.strong;
53
+ vars[`--kg-${f}-soft`] = c.soft;
54
+ vars[`--kg-${f}-text`] = c.text;
55
+ }
56
+ return Object.entries(vars)
57
+ .map(([k, v]) => `${k}: ${v};`)
58
+ .join(' ');
59
+ }
60
+ const familyRules = [...FAMILIES, 'neutral']
61
+ .map((f) => f === 'neutral'
62
+ ? `[data-family="neutral"] { --fam-base: var(--kg-neutral); --fam-soft: var(--kg-hover); --fam-text: var(--kg-text-2); }`
63
+ : `[data-family="${f}"] { --fam-base: var(--kg-${f}); --fam-soft: var(--kg-${f}-soft); --fam-text: var(--kg-${f}-text); }`)
64
+ .join('\n');
65
+ export const STYLES = /* css */ `
66
+ :host {
67
+ all: initial;
68
+ display: block;
69
+ position: relative;
70
+ height: 100%;
71
+ min-height: 420px;
72
+ contain: content;
73
+ font-family: var(--kg-font);
74
+ font-size: 13px;
75
+ line-height: 1.45;
76
+ color: var(--kg-text);
77
+ background: var(--kg-bg);
78
+ -webkit-font-smoothing: antialiased;
79
+ }
80
+ :host([hidden]) { display: none; }
81
+ *, *::before, *::after { box-sizing: border-box; }
82
+ [hidden] { display: none !important; }
83
+ button, input { font: inherit; color: inherit; letter-spacing: inherit; }
84
+ button {
85
+ margin: 0; padding: 0; border: 0; background: none; cursor: pointer;
86
+ -webkit-tap-highlight-color: transparent;
87
+ }
88
+ button:disabled { cursor: default; opacity: 0.4; }
89
+ :focus { outline: none; }
90
+ :focus-visible { outline: 2px solid var(--kg-accent); outline-offset: 2px; }
91
+ .icon { width: 16px; height: 16px; flex: none; display: block; }
92
+ .sr-only {
93
+ position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
94
+ overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
95
+ }
96
+ kbd {
97
+ display: inline-flex; align-items: center; justify-content: center;
98
+ min-width: 20px; height: 20px; padding: 0 5px; border-radius: 5px;
99
+ font: 500 11px/1 var(--kg-mono); color: var(--kg-text-2);
100
+ background: var(--kg-kbd); box-shadow: inset 0 0 0 1px var(--kg-border), inset 0 -1px 0 var(--kg-border);
101
+ }
102
+ .scroll { overflow: auto; scrollbar-width: thin; scrollbar-color: var(--kg-border-strong) transparent; }
103
+
104
+ /* ── Root layout ─────────────────────────────────────────────────────────── */
105
+ .root {
106
+ position: absolute; inset: 0; display: flex; flex-direction: column; overflow: hidden;
107
+ background: var(--kg-bg);
108
+ }
109
+ .body { position: relative; flex: 1; min-height: 0; display: flex; }
110
+ .stage-wrap { position: relative; flex: 1; min-width: 0; min-height: 0; overflow: hidden; background: var(--kg-bg); }
111
+ .stage { position: absolute; inset: 0; }
112
+ .stage canvas { outline: none; }
113
+ .stage canvas:focus-visible { outline: 2px solid var(--kg-accent); outline-offset: -2px; }
114
+ .chrome { position: absolute; inset: 0; pointer-events: none; }
115
+ .chrome > * { pointer-events: auto; }
116
+
117
+ /* ── Buttons ─────────────────────────────────────────────────────────────── */
118
+ .icon-btn {
119
+ display: inline-flex; align-items: center; justify-content: center; flex: none;
120
+ width: 32px; height: 32px; border-radius: 8px; color: var(--kg-text-2);
121
+ transition: background var(--kg-fast) var(--kg-ease), color var(--kg-fast) var(--kg-ease);
122
+ }
123
+ .icon-btn:hover { background: var(--kg-hover); color: var(--kg-text); }
124
+ .icon-btn:active { background: var(--kg-press); }
125
+ .icon-btn[aria-pressed="true"], .icon-btn[aria-expanded="true"] { background: var(--kg-press); color: var(--kg-text); }
126
+ .icon-btn.sm { width: 28px; height: 28px; border-radius: 7px; }
127
+ .btn {
128
+ display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
129
+ border-radius: 7px; font-size: 12px; font-weight: 500; color: var(--kg-text);
130
+ background: var(--kg-hover); box-shadow: inset 0 0 0 1px var(--kg-border);
131
+ transition: background var(--kg-fast) var(--kg-ease), box-shadow var(--kg-fast) var(--kg-ease);
132
+ }
133
+ .btn:hover { background: var(--kg-press); box-shadow: inset 0 0 0 1px var(--kg-border-strong); }
134
+ .link-btn { min-height: 28px; color: var(--kg-accent-text); font-weight: 500; font-size: 12px; border-radius: 4px; }
135
+ .link-btn:hover { text-decoration: underline; text-underline-offset: 3px; }
136
+
137
+ /* ── Header ──────────────────────────────────────────────────────────────── */
138
+ .header {
139
+ position: relative; z-index: 3; flex: none; height: 52px; display: flex; align-items: center; gap: 12px;
140
+ padding: 0 10px 0 14px; background: var(--kg-panel); border-bottom: 1px solid var(--kg-border);
141
+ }
142
+ .brand { display: flex; align-items: center; gap: 8px; flex: none; color: var(--kg-text); }
143
+ .brand-mark { width: 20px; height: 20px; display: block; }
144
+ .brand-name { font-size: 14px; font-weight: 650; letter-spacing: -0.01em; }
145
+ .header-sep { width: 1px; height: 20px; background: var(--kg-border-strong); flex: none; }
146
+ .versions { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 0; font-size: 13px; overflow: hidden;
147
+ mask-image: linear-gradient(90deg, #000 calc(100% - 16px), transparent); }
148
+ .versions .name { font-weight: 550; color: var(--kg-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
149
+ .versions .arrow { color: var(--kg-text-3); flex: none; }
150
+ .versions .side { display: flex; align-items: center; gap: 6px; min-width: 0; }
151
+ .tag {
152
+ display: inline-flex; align-items: center; height: 20px; padding: 0 6px; border-radius: 5px; flex: none;
153
+ font: 500 11px/1 var(--kg-mono); color: var(--kg-text-2); background: var(--kg-hover);
154
+ box-shadow: inset 0 0 0 1px var(--kg-border); white-space: nowrap; max-width: 160px; overflow: hidden; text-overflow: ellipsis;
155
+ }
156
+ .header-center { flex: none; display: flex; justify-content: center; }
157
+ /* header="compact": no brand or names (the host shows them); the names keep their space so the
158
+ mode control stays centered. */
159
+ :host([header="compact"]) .brand, :host([header="compact"]) .header-sep { display: none; }
160
+ :host([header="compact"]) .versions { visibility: hidden; }
161
+ .header-end { display: flex; align-items: center; gap: 4px; flex: 1 0 auto; justify-content: flex-end; }
162
+ .stats { display: flex; align-items: center; gap: 4px; margin-right: 6px; }
163
+
164
+ .segmented {
165
+ position: relative; display: inline-flex; align-items: center; gap: 2px; height: 32px; padding: 2px;
166
+ border-radius: 9px; background: var(--kg-hover); box-shadow: inset 0 0 0 1px var(--kg-border);
167
+ }
168
+ .segmented .thumb {
169
+ position: absolute; top: 2px; bottom: 2px; left: 0; width: 0; border-radius: 7px;
170
+ background: var(--kg-raised); box-shadow: 0 1px 2px rgba(0,0,0,0.12), inset 0 0 0 1px var(--kg-border-strong);
171
+ transition: transform var(--kg-base) var(--kg-ease), width var(--kg-base) var(--kg-ease);
172
+ }
173
+ .seg {
174
+ position: relative; z-index: 1; display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px;
175
+ border-radius: 7px; font-size: 12.5px; font-weight: 500; color: var(--kg-text-2); white-space: nowrap;
176
+ transition: color var(--kg-fast) var(--kg-ease);
177
+ }
178
+ .seg:hover { color: var(--kg-text); }
179
+ .seg[aria-checked="true"] { color: var(--kg-text); }
180
+ .seg .icon { opacity: 0.9; }
181
+
182
+ .pill {
183
+ display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 9px; border-radius: 14px;
184
+ font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap;
185
+ transition: box-shadow var(--kg-fast) var(--kg-ease), background var(--kg-fast) var(--kg-ease), opacity var(--kg-fast) var(--kg-ease);
186
+ }
187
+ .stat { color: var(--fam-text); background: var(--fam-soft); box-shadow: inset 0 0 0 1px transparent; }
188
+ .stat:hover { box-shadow: inset 0 0 0 1px var(--fam-base); }
189
+ .stat[aria-pressed="true"] { box-shadow: inset 0 0 0 1.5px var(--fam-base); }
190
+ .stats.filtering .stat[aria-pressed="false"] { opacity: 0.55; }
191
+ .stat .glyph { font-weight: 700; }
192
+
193
+
194
+ ${familyRules}
195
+
196
+ /* ── Floating chrome ─────────────────────────────────────────────────────── */
197
+ .card {
198
+ background: var(--kg-overlay); border-radius: 12px; box-shadow: var(--kg-shadow), 0 0 0 1px var(--kg-border);
199
+ backdrop-filter: blur(16px) saturate(140%);
200
+ }
201
+ .float { position: absolute; }
202
+ .top-left { top: 12px; left: 12px; }
203
+ .bottom-left { bottom: 16px; left: 16px; }
204
+ .bottom-right { bottom: 16px; right: 16px; }
205
+ .chip {
206
+ display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px; border-radius: 8px;
207
+ font-size: 12px; font-weight: 600; color: var(--kg-text-2); letter-spacing: 0.01em;
208
+ }
209
+
210
+ .map-cluster { display: flex; align-items: flex-end; gap: 8px; }
211
+ .zoom-bar { display: flex; flex-direction: column; padding: 2px; gap: 2px; }
212
+ .zoom-bar .icon-btn { width: 30px; height: 30px; }
213
+ .minimap-host { position: relative; width: 184px; height: 128px; border-radius: 12px; box-shadow: 0 0 0 1px var(--kg-border); }
214
+ .minimap-host canvas { border-radius: 12px; }
215
+
216
+ .legend { padding: 6px; min-width: 0; }
217
+ .legend-head { display: flex; align-items: center; gap: 6px; height: 28px; padding: 0 6px 0 8px; font-size: 11px; font-weight: 600;
218
+ letter-spacing: 0.06em; text-transform: uppercase; color: var(--kg-text-3); border-radius: 7px; width: 100%; }
219
+ .legend-head:hover { color: var(--kg-text-2); background: var(--kg-hover); }
220
+ .legend-head .icon { width: 14px; height: 14px; margin-left: auto; transition: transform var(--kg-base) var(--kg-ease); }
221
+ .legend[data-open="false"] .legend-head .icon { transform: rotate(180deg); }
222
+ .legend[data-open="false"] .legend-body { display: none; }
223
+ .legend[data-open="false"] { padding: 2px; }
224
+ .legend-body { display: grid; gap: 2px; padding: 2px 4px 4px; }
225
+ .legend-row { display: grid; grid-template-columns: 22px auto; align-items: center; column-gap: 8px; height: 26px; padding: 0 10px 0 4px; border-radius: 6px; cursor: default; }
226
+ .legend-row .name { font-size: 12px; font-weight: 550; color: var(--kg-text); }
227
+ .swatch { width: 22px; height: 22px; display: block; }
228
+
229
+ .caption {
230
+ position: absolute; top: 12px; left: 50%; transform: translateX(-50%); max-width: min(560px, calc(100% - 200px));
231
+ display: flex; align-items: center; gap: 8px; height: 32px; padding: 0 12px 0 6px; font-size: 12.5px; font-weight: 550;
232
+ transition: opacity var(--kg-base) var(--kg-ease);
233
+ }
234
+ .caption .text { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
235
+ .caption .count { color: var(--kg-text-3); font-weight: 500; font-variant-numeric: tabular-nums; flex: none; }
236
+ .caption[data-empty="true"] { opacity: 0; pointer-events: none; }
237
+
238
+ .glyph-box {
239
+ display: inline-flex; align-items: center; justify-content: center; flex: none; width: 20px; height: 20px; border-radius: 6px;
240
+ font-size: 12px; font-weight: 700; line-height: 1; color: var(--fam-text); background: var(--fam-soft);
241
+ }
242
+
243
+ .stepper { display: inline-flex; align-items: center; gap: 8px; height: 38px; padding: 0 4px 0 12px; }
244
+ .stepper .label { font-size: 12px; font-weight: 550; color: var(--kg-text-2); }
245
+ .stepper .opts { display: inline-flex; gap: 2px; padding: 2px; border-radius: 8px; background: var(--kg-hover); }
246
+ .stepper .opt { width: 28px; height: 28px; border-radius: 6px; font-size: 12px; font-weight: 600; color: var(--kg-text-2); font-variant-numeric: tabular-nums; }
247
+ .stepper .opt:hover { color: var(--kg-text); }
248
+ .stepper .expand { display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px 0 8px; margin-left: 4px; border-radius: 7px; font-size: 12px; font-weight: 600; color: var(--kg-text-2); box-shadow: inset 0 0 0 1px var(--kg-border-strong); font-variant-numeric: tabular-nums; }
249
+ .stepper .expand:hover:not(:disabled) { color: var(--kg-text); background: var(--kg-hover); }
250
+ .stepper .expand .icon { width: 14px; height: 14px; }
251
+ .stepper .opt[aria-checked="true"] { background: var(--kg-raised); color: var(--kg-text); box-shadow: inset 0 0 0 1px var(--kg-border-strong); }
252
+
253
+ /* Swipe */
254
+ .swipe { position: absolute; inset: 0; pointer-events: none; }
255
+ .swipe .divider {
256
+ position: absolute; top: 0; bottom: 0; left: 0; width: 24px; margin-left: -12px; cursor: ew-resize; pointer-events: auto;
257
+ touch-action: none; display: flex; justify-content: center;
258
+ }
259
+ .swipe .divider::before { content: ''; width: 1.5px; height: 100%; background: var(--kg-accent); opacity: 0.85; box-shadow: 0 0 12px var(--kg-accent-soft); }
260
+ .swipe .handle {
261
+ position: absolute; top: 50%; left: 50%; width: 32px; height: 32px; margin: -16px 0 0 -16px; border-radius: 50%;
262
+ display: flex; align-items: center; justify-content: center; gap: 0; color: var(--kg-accent-text);
263
+ background: var(--kg-overlay); box-shadow: var(--kg-shadow), 0 0 0 1.5px var(--kg-accent);
264
+ backdrop-filter: blur(16px);
265
+ transition: transform var(--kg-fast) var(--kg-ease);
266
+ }
267
+ .swipe .handle .icon { width: 12px; height: 12px; }
268
+ .swipe .divider:hover .handle, .swipe .divider.dragging .handle { transform: scale(1.08); }
269
+ .swipe .divider:focus-visible { outline: none; }
270
+ .swipe .divider:focus-visible .handle { box-shadow: var(--kg-shadow), 0 0 0 2px var(--kg-accent), 0 0 0 5px var(--kg-accent-soft); }
271
+ .swipe .side-chip { position: absolute; top: 12px; pointer-events: none; }
272
+ .swipe .side-chip.before { left: 12px; }
273
+ .swipe .side-chip.after { right: 12px; }
274
+
275
+ /* Replay transport */
276
+ .transport {
277
+ position: absolute; left: 50%; bottom: 16px; transform: translateX(-50%); width: min(600px, calc(100% - 496px));
278
+ min-width: 360px;
279
+ display: flex; align-items: center; gap: 4px; height: 48px; padding: 0 8px;
280
+ }
281
+ .transport .play { width: 36px; height: 36px; border-radius: 10px; color: var(--kg-text); }
282
+ .transport .play .icon { width: 18px; height: 18px; }
283
+ .transport .pos { flex: none; min-width: 64px; text-align: center; font-size: 12px; font-weight: 550; color: var(--kg-text-2); font-variant-numeric: tabular-nums; }
284
+ .transport .speed { flex: none; height: 28px; min-width: 44px; padding: 0 8px; border-radius: 7px; font-size: 12px; font-weight: 600; color: var(--kg-text-2); font-variant-numeric: tabular-nums; box-shadow: inset 0 0 0 1px var(--kg-border); }
285
+ .transport .speed:hover { color: var(--kg-text); background: var(--kg-hover); }
286
+ .scrubber { position: relative; flex: 1; height: 36px; margin: 0 8px; cursor: pointer; touch-action: none; border-radius: 6px; }
287
+ .scrubber .track { position: absolute; left: 0; right: 0; top: 50%; height: 4px; margin-top: -2px; border-radius: 2px; background: var(--kg-track); overflow: hidden; }
288
+ .scrubber .fill { position: absolute; left: 0; top: 0; bottom: 0; width: 100%; transform-origin: left; background: var(--kg-accent); opacity: 0.85; }
289
+ .scrubber .ticks { position: absolute; left: 0; right: 0; top: 50%; height: 14px; margin-top: -7px; width: 100%; pointer-events: none; overflow: visible; }
290
+ .scrubber .knob {
291
+ position: absolute; top: 50%; left: 0; width: 14px; height: 14px; margin: -7px 0 0 -7px; border-radius: 50%;
292
+ background: var(--kg-text); box-shadow: 0 1px 4px rgba(0,0,0,0.35), 0 0 0 3px var(--kg-accent-soft); pointer-events: none;
293
+ }
294
+ .scrubber:focus-visible { outline-offset: 0; }
295
+ .scrub-tip {
296
+ position: absolute; bottom: 100%; margin-bottom: 10px; transform: translateX(-50%); max-width: 320px; padding: 6px 10px;
297
+ font-size: 12px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; pointer-events: none;
298
+ display: flex; align-items: center; gap: 6px;
299
+ }
300
+ .finished {
301
+ position: absolute; left: 50%; bottom: 76px; transform: translateX(-50%); display: flex; align-items: center; gap: 10px;
302
+ height: 36px; padding: 0 6px 0 12px; font-size: 12.5px; font-weight: 550; color: var(--kg-text);
303
+ animation: rise var(--kg-base) var(--kg-ease);
304
+ }
305
+ .finished .icon { color: var(--kg-accent-text); }
306
+ @keyframes rise { from { opacity: 0; transform: translate(-50%, 6px); } }
307
+
308
+ /* Tooltip */
309
+ .tooltip {
310
+ position: absolute; left: 0; top: 0; z-index: 4; width: max-content; max-width: 300px; padding: 10px 12px; pointer-events: none;
311
+ border-radius: 10px; opacity: 0; transition: opacity var(--kg-fast) var(--kg-ease);
312
+ }
313
+ .tooltip[data-open="true"] { opacity: 1; }
314
+ .tooltip .t-label { font-size: 13px; font-weight: 600; color: var(--kg-text); overflow-wrap: anywhere; }
315
+ .tooltip .t-old { font-size: 12px; color: var(--kg-text-3); text-decoration: line-through; overflow-wrap: anywhere; }
316
+ .tooltip .t-id { margin-top: 2px; font: 11px/1.4 var(--kg-mono); color: var(--kg-text-3); overflow-wrap: anywhere; }
317
+ .tooltip .t-status { margin-top: 8px; display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 550; color: var(--fam-text); }
318
+ .tooltip .t-status .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fam-base); flex: none; }
319
+ .tooltip .t-sum { margin-top: 4px; font-size: 12px; color: var(--kg-text-2); overflow-wrap: anywhere; }
320
+ .tooltip .t-hint { margin-top: 6px; font-size: 11px; color: var(--kg-text-3); }
321
+
322
+ /* States (loading / identical / error / empty) */
323
+ .state {
324
+ position: absolute; inset: 0; z-index: 2; display: flex; align-items: center; justify-content: center; padding: 24px;
325
+ pointer-events: none;
326
+ }
327
+ .state > * { pointer-events: auto; }
328
+ .state.blocking { background: var(--kg-bg); }
329
+ .state-card { width: min(380px, 100%); padding: 24px; text-align: left; }
330
+ .state-card .state-icon {
331
+ width: 36px; height: 36px; border-radius: 10px; display: flex; align-items: center; justify-content: center;
332
+ color: var(--kg-accent-text); background: var(--kg-accent-soft); margin-bottom: 16px;
333
+ }
334
+ .state-card .state-icon .icon { width: 20px; height: 20px; }
335
+ .state-card.error .state-icon { color: var(--kg-removed-text); background: var(--kg-removed-soft); }
336
+ .state-card.ok .state-icon { color: var(--kg-added-text); background: var(--kg-added-soft); }
337
+ .state-card h2 { margin: 0; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
338
+ .state-card p { margin: 6px 0 0; color: var(--kg-text-2); font-size: 13px; }
339
+ .state-card details { margin-top: 16px; font-size: 12px; color: var(--kg-text-2); }
340
+ .state-card summary { cursor: pointer; font-weight: 550; color: var(--kg-text-2); border-radius: 4px; width: max-content; }
341
+ .state-card pre {
342
+ margin: 8px 0 0; max-height: 200px; padding: 10px 12px; border-radius: 8px; background: var(--kg-input);
343
+ font: 11.5px/1.5 var(--kg-mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--kg-text-2);
344
+ box-shadow: inset 0 0 0 1px var(--kg-border);
345
+ }
346
+ .steps { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 10px; }
347
+ .steps li { display: flex; align-items: center; gap: 10px; font-size: 13px; color: var(--kg-text-3); transition: color var(--kg-base) var(--kg-ease); }
348
+ .steps li[data-state="active"] { color: var(--kg-text); font-weight: 550; }
349
+ .steps li[data-state="done"] { color: var(--kg-text-2); }
350
+ .steps .mark { width: 18px; height: 18px; flex: none; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1.5px var(--kg-border-strong); }
351
+ .steps li[data-state="done"] .mark { background: var(--kg-accent-soft); box-shadow: none; color: var(--kg-accent-text); }
352
+ .steps li[data-state="done"] .mark .icon { width: 12px; height: 12px; }
353
+ .steps li[data-state="active"] .mark { box-shadow: inset 0 0 0 1.5px var(--kg-accent-soft); border-top: 1.5px solid var(--kg-accent); animation: spin 0.8s linear infinite; }
354
+ @keyframes spin { to { transform: rotate(360deg); } }
355
+ .skeleton-grid {
356
+ position: absolute; inset: 0;
357
+ background-image: radial-gradient(var(--kg-skeleton-hi) 1.2px, transparent 1.4px); background-size: 24px 24px;
358
+ mask-image: radial-gradient(ellipse at center, #000 20%, transparent 75%);
359
+ animation: breathe 2.4s ease-in-out infinite;
360
+ }
361
+ @keyframes breathe { 50% { opacity: 0.45; } }
362
+
363
+ /* ── Sidebar ─────────────────────────────────────────────────────────────── */
364
+ .sidebar {
365
+ position: relative; z-index: 2; flex: none; width: 360px; display: flex; overflow: hidden;
366
+ background: var(--kg-panel); border-left: 1px solid var(--kg-border);
367
+ transition: width var(--kg-base) var(--kg-ease), border-color var(--kg-base) var(--kg-ease);
368
+ }
369
+ .sidebar[data-open="false"] { width: 0; border-left-color: transparent; }
370
+ .sidebar-inner { width: 360px; flex: none; display: flex; flex-direction: column; min-height: 0; }
371
+ .sheet-handle { display: none; }
372
+ .sb-head { flex: none; padding: 12px 12px 8px; display: grid; gap: 10px; border-bottom: 1px solid var(--kg-border); }
373
+ .sb-title { display: flex; align-items: center; gap: 8px; height: 24px; padding: 0 2px; }
374
+ .sb-title h2 { margin: 0; font-size: 13px; font-weight: 650; }
375
+ .count-badge {
376
+ display: inline-flex; align-items: center; height: 18px; padding: 0 6px; border-radius: 9px; font-size: 11px; font-weight: 600;
377
+ color: var(--kg-text-2); background: var(--kg-hover); box-shadow: inset 0 0 0 1px var(--kg-border); font-variant-numeric: tabular-nums;
378
+ }
379
+ .progress { margin-left: auto; display: flex; align-items: center; gap: 8px; font-size: 11.5px; color: var(--kg-text-3); font-variant-numeric: tabular-nums; }
380
+ .progress .bar { width: 64px; height: 4px; border-radius: 2px; background: var(--kg-track); overflow: hidden; }
381
+ .progress .bar > div { height: 100%; width: 100%; transform-origin: left; background: var(--kg-accent); border-radius: 2px; transition: transform var(--kg-base) var(--kg-ease); }
382
+ .progress[data-complete="true"] { color: var(--kg-accent-text); }
383
+
384
+ .search { position: relative; display: flex; align-items: center; height: 32px; border-radius: 8px; background: var(--kg-input);
385
+ box-shadow: inset 0 0 0 1px var(--kg-border); transition: box-shadow var(--kg-fast) var(--kg-ease); }
386
+ .search:focus-within { box-shadow: inset 0 0 0 1px var(--kg-accent), 0 0 0 3px var(--kg-accent-soft); }
387
+ .search > .icon { position: absolute; left: 10px; color: var(--kg-text-3); pointer-events: none; }
388
+ .search input {
389
+ flex: 1; min-width: 0; height: 100%; padding: 0 64px 0 32px; border: 0; background: transparent; font-size: 13px; color: var(--kg-text);
390
+ }
391
+ .search input::placeholder { color: var(--kg-text-3); }
392
+ .search input::-webkit-search-cancel-button { display: none; }
393
+ .search kbd { position: absolute; right: 8px; }
394
+ .search .clear { position: absolute; right: 2px; width: 28px; height: 28px; border-radius: 6px; display: flex; align-items: center; justify-content: center; color: var(--kg-text-3); }
395
+ .search .clear:hover { color: var(--kg-text); background: var(--kg-hover); }
396
+
397
+ .filters { display: flex; flex-wrap: wrap; gap: 4px; }
398
+ .fchip {
399
+ display: inline-flex; align-items: center; gap: 5px; height: 28px; padding: 0 8px 0 7px; border-radius: 14px;
400
+ font-size: 11.5px; font-weight: 550; color: var(--kg-text-2); box-shadow: inset 0 0 0 1px var(--kg-border);
401
+ transition: background var(--kg-fast) var(--kg-ease), box-shadow var(--kg-fast) var(--kg-ease), color var(--kg-fast) var(--kg-ease);
402
+ }
403
+ .fchip:hover { background: var(--kg-hover); color: var(--kg-text); }
404
+ .fchip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--fam-base); flex: none; }
405
+ .fchip .n { color: var(--kg-text-3); font-variant-numeric: tabular-nums; font-weight: 500; }
406
+ .fchip[aria-pressed="true"] { background: var(--fam-soft); color: var(--fam-text); box-shadow: inset 0 0 0 1px var(--fam-base); }
407
+ .fchip[aria-pressed="true"] .n { color: var(--fam-text); opacity: 0.8; }
408
+ .fchip:disabled { opacity: 0.35; }
409
+
410
+ .list-wrap { position: relative; flex: 1 1 50%; min-height: 96px; display: flex; flex-direction: column; }
411
+ .list { position: relative; flex: 1; min-height: 0; outline: none; }
412
+ .list:focus-visible { outline: none; }
413
+ .list:focus-visible:not(:has(.row[aria-selected="true"])) { box-shadow: inset 0 0 0 2px var(--kg-accent); }
414
+ .list:focus-visible .row[aria-selected="true"] { box-shadow: inset 0 0 0 2px var(--kg-accent); }
415
+ .list-inner { position: relative; width: 100%; }
416
+ .row {
417
+ position: absolute; left: 8px; right: 8px; height: 52px; display: flex; align-items: center; gap: 10px; padding: 0 6px 0 14px;
418
+ border-radius: 8px; cursor: pointer; user-select: none; -webkit-user-select: none;
419
+ transition: background var(--kg-fast) var(--kg-ease), box-shadow var(--kg-fast) var(--kg-ease);
420
+ }
421
+ .row::before { content: ''; position: absolute; left: 4px; top: 10px; bottom: 10px; width: 3px; border-radius: 2px; background: var(--fam-base); }
422
+ .row:hover { background: var(--kg-hover); }
423
+ .row[aria-selected="true"] { background: var(--kg-selected); box-shadow: inset 0 0 0 1px var(--kg-accent), 0 1px 2px rgba(0,0,0,0.06); }
424
+ .row .txt { flex: 1; min-width: 0; display: grid; gap: 1px; }
425
+ .row .title { font-size: 13px; font-weight: 500; color: var(--kg-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
426
+ .row .sub { font-size: 12px; color: var(--kg-text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-height: 17px; }
427
+ .row[data-reviewed="true"] .title { color: var(--kg-text-2); }
428
+ .row[data-reviewed="true"] .glyph-box { opacity: 0.7; }
429
+ .rv {
430
+ flex: none; width: 28px; height: 28px; border-radius: 50%; display: flex; align-items: center; justify-content: center; cursor: pointer;
431
+ }
432
+ .rv .ring {
433
+ width: 18px; height: 18px; border-radius: 50%; display: flex; align-items: center; justify-content: center;
434
+ box-shadow: inset 0 0 0 1.5px var(--kg-control-border); color: transparent;
435
+ transition: background var(--kg-fast) var(--kg-ease), box-shadow var(--kg-fast) var(--kg-ease), color var(--kg-fast) var(--kg-ease), transform var(--kg-fast) var(--kg-ease);
436
+ }
437
+ .rv .ring .icon { width: 12px; height: 12px; }
438
+ .rv:hover .ring { box-shadow: inset 0 0 0 1.5px var(--kg-accent); color: var(--kg-text-3); }
439
+ .rv[data-pressed="true"] .ring { background: var(--kg-accent); box-shadow: none; color: var(--kg-bg); }
440
+ .rv[data-pressed="true"]:active .ring { transform: scale(0.9); }
441
+ .group {
442
+ position: absolute; left: 0; right: 0; height: 32px; display: flex; align-items: center; gap: 8px; padding: 10px 16px 0 22px;
443
+ font-size: 11px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--kg-text-3);
444
+ }
445
+ .group .n { font-weight: 500; letter-spacing: 0; font-variant-numeric: tabular-nums; }
446
+ .sticky {
447
+ position: absolute; top: 0; left: 0; right: 0; z-index: 1; height: 32px; background: var(--kg-panel);
448
+ box-shadow: 0 1px 0 var(--kg-border); pointer-events: none;
449
+ }
450
+ .sticky .group { position: static; height: 32px; padding-top: 0; }
451
+ .sticky[data-shadow="false"] { box-shadow: none; }
452
+ .list-empty { padding: 32px 24px; text-align: center; color: var(--kg-text-3); font-size: 12.5px; display: grid; gap: 10px; justify-items: center; }
453
+ .skeleton-row { height: 52px; margin: 0 8px; padding: 0 14px; display: flex; align-items: center; gap: 10px; }
454
+ .skeleton-row .b { flex: 1; max-width: 70%; height: 10px; border-radius: 5px; background: var(--kg-skeleton); }
455
+ .skeleton-row:nth-child(even) .b { max-width: 52%; }
456
+ .skeleton-row .g { width: 20px; height: 20px; border-radius: 6px; background: var(--kg-skeleton); flex: none; }
457
+ .shimmer { animation: breathe 1.6s ease-in-out infinite; }
458
+
459
+ .results { padding: 4px 0 8px; }
460
+ .results-head { padding: 8px 16px 6px; font-size: 11px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--kg-text-3); }
461
+ .result {
462
+ display: flex; align-items: center; gap: 10px; width: calc(100% - 16px); margin: 0 8px; height: 44px; padding: 0 10px; border-radius: 8px;
463
+ text-align: left;
464
+ }
465
+ .result:hover, .result[aria-selected="true"] { background: var(--kg-hover); }
466
+ .result[aria-selected="true"] { box-shadow: inset 0 0 0 1px var(--kg-border-strong); }
467
+ .result .sdot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--fam-base); }
468
+ .result[data-family="neutral"] .sdot { background: transparent; box-shadow: inset 0 0 0 1.5px var(--kg-neutral-stroke); }
469
+ .result .txt { flex: 1; min-width: 0; display: grid; }
470
+ .result .title { font-size: 13px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
471
+ .result .sub { font: 11px/1.4 var(--kg-mono); color: var(--kg-text-3); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
472
+ .result mark { background: var(--kg-accent-soft); color: inherit; border-radius: 3px; padding: 0 1px; }
473
+ .result .status { font-size: 11.5px; color: var(--fam-text); flex: none; }
474
+
475
+ /* ── Detail panel ────────────────────────────────────────────────────────── */
476
+ .detail { flex: 0 1 auto; max-height: 58%; min-height: 0; display: flex; flex-direction: column; border-top: 1px solid var(--kg-border); background: var(--kg-panel); }
477
+ .detail[data-empty="true"] { flex: none; }
478
+ .detail-empty { padding: 16px; display: flex; align-items: center; gap: 12px; color: var(--kg-text-3); font-size: 12.5px; }
479
+ .detail-empty .icon { color: var(--kg-text-3); }
480
+ .detail-empty .sub { font-size: 11.5px; margin-top: 2px; }
481
+ .detail-scroll { flex: 1; min-height: 0; padding: 14px 16px 20px; }
482
+ .d-top { display: flex; align-items: center; gap: 6px; margin-bottom: 10px; }
483
+ .fam-pill { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px 0 6px; border-radius: 6px; font-size: 11.5px; font-weight: 600; color: var(--fam-text); background: var(--fam-soft); }
484
+ .fam-pill .g { font-weight: 700; }
485
+ .d-nav { margin-left: auto; display: flex; align-items: center; gap: 2px; }
486
+ .d-title { margin: 0; font-size: 14.5px; line-height: 1.4; font-weight: 600; letter-spacing: -0.005em; overflow-wrap: anywhere; }
487
+ .d-sub { margin-top: 4px; font-size: 12.5px; color: var(--kg-text-2); overflow-wrap: anywhere; }
488
+ .rv-btn { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 10px 0 6px; border-radius: 7px; font-size: 12px; font-weight: 550; color: var(--kg-text-2); box-shadow: inset 0 0 0 1px var(--kg-border); margin-right: 4px; }
489
+ .rv-btn:hover { color: var(--kg-text); background: var(--kg-hover); }
490
+ .rv-btn .ring { width: 16px; height: 16px; border-radius: 50%; display: flex; align-items: center; justify-content: center; box-shadow: inset 0 0 0 1.5px var(--kg-control-border); color: transparent; }
491
+ .rv-btn .ring .icon { width: 11px; height: 11px; }
492
+ .rv-btn[aria-pressed="true"] { color: var(--kg-accent-text); box-shadow: inset 0 0 0 1px var(--kg-accent); background: var(--kg-accent-soft); }
493
+ .rv-btn[aria-pressed="true"] .ring { background: var(--kg-accent); box-shadow: none; color: var(--kg-bg); }
494
+ .section { margin-top: 18px; }
495
+ .section > h3 { margin: 0 0 8px; font-size: 11px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--kg-text-3); display: flex; align-items: center; gap: 6px; }
496
+ .section > h3 .n { font-weight: 500; letter-spacing: 0; }
497
+ .kv { display: grid; grid-template-columns: 72px minmax(0, 1fr); gap: 6px 12px; font-size: 12.5px; align-items: baseline; }
498
+ .kv dt { color: var(--kg-text-3); }
499
+ .kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
500
+ .id-text { font: 12px/1.5 var(--kg-mono); color: var(--kg-text); overflow-wrap: anywhere; }
501
+ .chips { display: flex; flex-wrap: wrap; gap: 4px; }
502
+ .vchip { display: inline-flex; align-items: center; gap: 4px; min-height: 22px; padding: 2px 8px; border-radius: 6px; font-size: 12px; background: var(--kg-hover); box-shadow: inset 0 0 0 1px var(--kg-border); overflow-wrap: anywhere; }
503
+ .vchip.add { color: var(--kg-added-text); background: var(--kg-added-soft); box-shadow: none; }
504
+ .vchip.del { color: var(--kg-removed-text); background: var(--kg-removed-soft); box-shadow: none; text-decoration: line-through; text-decoration-thickness: 1px; }
505
+ .vchip .sign { font-weight: 700; text-decoration: none; display: inline-block; }
506
+ .pair { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 6px; }
507
+ .pair .b, .line.old { color: var(--kg-text-2); }
508
+ .pair .arr { color: var(--kg-text-3); }
509
+ .line { display: grid; grid-template-columns: 10px minmax(0, 1fr); gap: 6px; align-items: baseline; }
510
+ .line .sign { font: 600 12px/1 var(--kg-mono); text-align: center; }
511
+ .line.old .sign { color: var(--kg-removed-text); }
512
+ .line.new .sign { color: var(--kg-added-text); }
513
+ del.hl { text-decoration: line-through; text-decoration-color: var(--kg-removed); background: var(--kg-removed-soft); color: var(--kg-removed-text); border-radius: 3px; padding: 0 1px; }
514
+ ins.hl { text-decoration: none; background: var(--kg-added-soft); color: var(--kg-added-text); border-radius: 3px; padding: 0 1px; }
515
+ .attrs { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 12.5px; table-layout: fixed; }
516
+ .attrs td { vertical-align: baseline; padding: 6px 8px 6px 0; border-top: 1px solid var(--kg-border); overflow-wrap: anywhere; }
517
+ .attrs tr:first-child td { border-top: 0; padding-top: 0; }
518
+ .attrs td > * + * { margin-top: 4px; }
519
+ .attrs td.k { color: var(--kg-text-2); }
520
+ .attrs col.k { width: 28%; }
521
+ .val { white-space: pre-wrap; }
522
+ .val.clamped { display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
523
+ .more { margin-top: 2px; }
524
+ .disclosure { display: inline-flex; align-items: center; gap: 4px; min-height: 28px; margin-top: 4px; font-size: 12px; color: var(--kg-text-2); border-radius: 4px; }
525
+ .disclosure:hover { color: var(--kg-text); }
526
+ .disclosure .icon { width: 12px; height: 12px; transition: transform var(--kg-base) var(--kg-ease); }
527
+ .disclosure[aria-expanded="true"] .icon { transform: rotate(180deg); }
528
+ .rels { display: grid; gap: 2px; }
529
+ .rel { display: flex; align-items: baseline; gap: 8px; width: 100%; padding: 6px 8px; margin: 0 -8px; border-radius: 7px; text-align: left; font-size: 12.5px; line-height: 1.5; width: calc(100% + 16px); }
530
+ .rel:hover { background: var(--kg-hover); }
531
+ .rel .sign { flex: none; width: 12px; font: 600 12px/1.5 var(--kg-mono); color: var(--fam-text); text-align: center; }
532
+ .rel .s { min-width: 0; overflow-wrap: anywhere; }
533
+ .rel .node { font-weight: 550; }
534
+ .rel .pred { color: var(--kg-text-2); white-space: nowrap; }
535
+ .rel .was { color: var(--kg-text-3); }
536
+ .rel.removed .s { text-decoration: line-through; text-decoration-color: var(--kg-text-3); color: var(--kg-text-2); }
537
+ .nodes { display: grid; gap: 2px; }
538
+ .node-link { display: flex; align-items: center; gap: 8px; width: calc(100% + 16px); margin: 0 -8px; padding: 5px 8px; border-radius: 7px; text-align: left; font-size: 12.5px; }
539
+ .node-link:hover { background: var(--kg-hover); }
540
+ .node-link[aria-current="true"] { background: var(--kg-hover); box-shadow: inset 0 0 0 1px var(--kg-border-strong); }
541
+ .node-link .sdot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--fam-base); }
542
+ .node-link .lbl { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
543
+ .node-link .meta { flex: none; color: var(--kg-text-3); font-size: 11.5px; }
544
+ .comp { display: grid; gap: 6px; }
545
+ .comp-row { display: flex; align-items: center; gap: 8px; font-size: 12.5px; flex-wrap: wrap; }
546
+ .comp-row .arrow { color: var(--kg-text-3); }
547
+ .comp-row .note { color: var(--kg-text-3); font-size: 11.5px; }
548
+ .bars { display: grid; gap: 6px; }
549
+ .bar-row { display: grid; grid-template-columns: 84px minmax(0, 1fr) 40px; align-items: center; gap: 10px; font-size: 12px; }
550
+ .bar-row .lbl { color: var(--kg-text-2); }
551
+ .bar-row .track { height: 6px; border-radius: 3px; background: var(--kg-track); overflow: hidden; }
552
+ .bar-row .fill { height: 100%; border-radius: 3px; background: var(--kg-identity); }
553
+ .bar-row .v { text-align: right; color: var(--kg-text-2); font-variant-numeric: tabular-nums; }
554
+ .note-line { font-size: 12px; color: var(--kg-text-3); margin-top: 6px; }
555
+
556
+ /* ── Popovers ────────────────────────────────────────────────────────────── */
557
+ .menu {
558
+ position: absolute; z-index: 10; top: 48px; right: 10px; width: 240px; padding: 6px; border-radius: 12px;
559
+ animation: pop var(--kg-fast) var(--kg-ease);
560
+ }
561
+ @keyframes pop { from { opacity: 0; transform: translateY(-4px) scale(0.98); } }
562
+ .menu-group + .menu-group { margin-top: 4px; padding-top: 4px; border-top: 1px solid var(--kg-border); }
563
+ .menu-label { padding: 6px 8px 4px; font-size: 11px; font-weight: 650; letter-spacing: 0.06em; text-transform: uppercase; color: var(--kg-text-3); }
564
+ .menu-item { display: flex; align-items: center; gap: 8px; width: 100%; height: 32px; padding: 0 8px; border-radius: 7px; font-size: 13px; color: var(--kg-text); text-align: left; }
565
+ .menu-item:hover, .menu-item:focus-visible { background: var(--kg-hover); outline: none; }
566
+ .menu-item .icon { color: var(--kg-text-2); }
567
+ .menu-item .check { margin-left: auto; color: var(--kg-accent-text); opacity: 0; }
568
+ .menu-item[aria-checked="true"] .check { opacity: 1; }
569
+ .menu-item .sw { display: inline-flex; gap: 2px; }
570
+ .menu-item .sw i { width: 6px; height: 6px; border-radius: 50%; display: block; }
571
+
572
+ .overlay-scrim {
573
+ position: absolute; inset: 0; z-index: 20; display: flex; align-items: center; justify-content: center; padding: 24px;
574
+ background: var(--kg-scrim); animation: fade var(--kg-fast) var(--kg-ease);
575
+ }
576
+ @keyframes fade { from { opacity: 0; } }
577
+ .dialog { width: min(640px, 100%); max-height: 100%; display: flex; flex-direction: column; border-radius: 14px; animation: pop var(--kg-base) var(--kg-ease); }
578
+ .dialog-head { display: flex; align-items: center; gap: 10px; padding: 14px 12px 10px 20px; }
579
+ .dialog-head h2 { margin: 0; font-size: 15px; font-weight: 650; }
580
+ .dialog-head .icon-btn { margin-left: auto; }
581
+ .dialog-body { padding: 0 20px 18px; }
582
+ .keys { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 24px; }
583
+ .key-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; min-height: 34px; border-bottom: 1px solid var(--kg-border); font-size: 12.5px; color: var(--kg-text-2); }
584
+ .key-row .ks { display: inline-flex; align-items: center; gap: 3px; flex: none; color: var(--kg-text-3); font-size: 11px; }
585
+
586
+ /* ── Compact (< 760 px): bottom sheet ────────────────────────────────────── */
587
+ .root[data-compact="true"] .body { flex-direction: column; }
588
+ .root[data-compact="true"] .sidebar {
589
+ width: auto; height: var(--sheet-h, 40%); min-height: 0; border-left: 0; border-top: 1px solid var(--kg-border);
590
+ border-radius: 14px 14px 0 0; margin-top: -14px; box-shadow: 0 -8px 24px rgba(0,0,0,0.18);
591
+ transition: height var(--kg-base) var(--kg-ease);
592
+ }
593
+ .root[data-compact="true"] .sidebar.dragging { transition: none; }
594
+ .root[data-compact="true"] .sidebar[data-open="false"] { height: 0; border-top-color: transparent; box-shadow: none; }
595
+ .root[data-compact="true"] .sidebar-inner { width: 100%; }
596
+ .root[data-compact="true"] .sheet-handle {
597
+ display: flex; flex: none; justify-content: center; align-items: center; height: 28px; cursor: ns-resize; touch-action: none; border-radius: 14px 14px 0 0;
598
+ }
599
+ .root[data-compact="true"] .sheet-handle::before { content: ""; width: 36px; height: 4px; border-radius: 2px; background: var(--kg-control-border); }
600
+ .root[data-compact="true"] .sb-head { padding-top: 4px; }
601
+ .root[data-compact="true"] .seg .lbl { display: none; }
602
+ .root[data-compact="true"] .seg { padding: 0 9px; }
603
+ .root[data-compact="true"] .versions, .root[data-compact="true"] .header-sep, .root[data-compact="true"] .stats,
604
+ .root[data-compact="true"] .brand-name { display: none; }
605
+ .root[data-compact="true"] .header-center { flex: 1; justify-content: flex-start; }
606
+ .root[data-compact="true"] .header-end { flex: none; }
607
+ .root[data-compact="true"] .minimap-host, .root[data-compact="true"] .legend { display: none; }
608
+ /* Zoom controls move to the top-right corner, clear of the full-width replay transport. */
609
+ .root[data-compact="true"] .map-cluster { top: 52px; bottom: auto; right: 12px; }
610
+ .root[data-compact="true"] .transport { bottom: 24px; width: calc(100% - 24px); min-width: 0; }
611
+ .root[data-compact="true"] .transport .pos { min-width: 48px; }
612
+ .root[data-compact="true"] .detail { max-height: 50%; }
613
+ .root[data-compact="true"] .caption { max-width: calc(100% - 24px); }
614
+ .root[data-narrow="true"] .stats { display: none; }
615
+ .root[data-narrow="true"] .versions .tag, .root[data-narrow="true"] .versions .arrow { display: none; }
616
+
617
+ @media (prefers-reduced-motion: reduce) {
618
+ *, *::before, *::after { animation-duration: 1ms !important; animation-iteration-count: 1 !important; transition-duration: 1ms !important; }
619
+ .skeleton-grid, .shimmer { animation: none; }
620
+ }
621
+ `;
622
+ //# sourceMappingURL=styles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../src/styles.ts"],"names":[],"mappings":"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"}