@descryy/viz 0.1.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.
@@ -0,0 +1,86 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>descry viz</title>
7
+ <link rel="stylesheet" href="/style.css" />
8
+ </head>
9
+ <body>
10
+ <header id="topbar">
11
+ <div id="brand">descry <span>viz</span></div>
12
+ <div id="searchbox">
13
+ <input id="search-input" type="text" placeholder="Search a symbol, file, or function…" autocomplete="off" />
14
+ <div id="search-results" hidden></div>
15
+ </div>
16
+ <div id="stamp"></div>
17
+ </header>
18
+
19
+ <div id="layout">
20
+ <aside id="filters">
21
+ <h2>Filters</h2>
22
+
23
+ <div class="filter-group">
24
+ <h3>Depth</h3>
25
+ <input id="depth-range" type="range" min="1" max="4" value="1" />
26
+ <span id="depth-value">1</span> hop(s)
27
+ </div>
28
+
29
+ <div class="filter-group">
30
+ <h3>Direction</h3>
31
+ <select id="direction-select">
32
+ <option value="both">Upstream + downstream</option>
33
+ <option value="in">Upstream only (who depends on this)</option>
34
+ <option value="out">Downstream only (what this depends on)</option>
35
+ </select>
36
+ </div>
37
+
38
+ <div class="filter-group">
39
+ <h3>Node type</h3>
40
+ <div id="node-type-filters" class="chip-list"></div>
41
+ </div>
42
+
43
+ <div class="filter-group">
44
+ <h3>Edge type</h3>
45
+ <div id="edge-type-filters" class="chip-list"></div>
46
+ </div>
47
+
48
+ <div class="filter-group">
49
+ <h3>Language</h3>
50
+ <div id="language-filters" class="chip-list">
51
+ <span class="chip-note">Filters the rendered view — languages seen in the current subgraph.</span>
52
+ </div>
53
+ </div>
54
+
55
+ <div class="filter-group">
56
+ <h3>Repository</h3>
57
+ <div class="chip-note" title="Repository is not a field the query layer exposes per node today — see the note in this build's report.">
58
+ Not available — no per-node repository field in the current graph schema.
59
+ </div>
60
+ </div>
61
+
62
+ <div class="filter-group">
63
+ <button id="export-btn" disabled>Export scoped view (JSON)</button>
64
+ </div>
65
+
66
+ <div id="notes"></div>
67
+ </aside>
68
+
69
+ <main id="canvas-wrap">
70
+ <canvas id="graph-canvas"></canvas>
71
+ <div id="empty-state">
72
+ <p>Search for a symbol above to see its neighbourhood.</p>
73
+ <p class="hint">This never renders the whole graph — search returns a bounded, query-driven view.</p>
74
+ </div>
75
+ <div id="hover-tooltip" hidden></div>
76
+ </main>
77
+
78
+ <aside id="inspector">
79
+ <div id="inspector-empty">Click a node or an edge to inspect it.</div>
80
+ <div id="inspector-content" hidden></div>
81
+ </aside>
82
+ </div>
83
+
84
+ <script type="module" src="/app.js"></script>
85
+ </body>
86
+ </html>
@@ -0,0 +1,266 @@
1
+ :root {
2
+ --bg: #0f1115;
3
+ --panel: #161922;
4
+ --panel-border: #262b38;
5
+ --text: #e6e8ee;
6
+ --text-dim: #8890a4;
7
+ --accent: #5da9ff;
8
+ --accent-dim: #2c4a70;
9
+ --warn: #ffb454;
10
+ --danger: #ff6b6b;
11
+ --ok: #56d364;
12
+ font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
13
+ }
14
+
15
+ * { box-sizing: border-box; }
16
+
17
+ html, body {
18
+ margin: 0;
19
+ height: 100%;
20
+ background: var(--bg);
21
+ color: var(--text);
22
+ font-size: 14px;
23
+ }
24
+
25
+ #topbar {
26
+ display: flex;
27
+ align-items: center;
28
+ gap: 16px;
29
+ padding: 10px 16px;
30
+ background: var(--panel);
31
+ border-bottom: 1px solid var(--panel-border);
32
+ height: 44px;
33
+ }
34
+
35
+ #brand {
36
+ font-weight: 600;
37
+ white-space: nowrap;
38
+ }
39
+ #brand span { color: var(--accent); }
40
+
41
+ #searchbox {
42
+ position: relative;
43
+ flex: 1;
44
+ max-width: 520px;
45
+ }
46
+
47
+ #search-input {
48
+ width: 100%;
49
+ padding: 7px 10px;
50
+ border-radius: 6px;
51
+ border: 1px solid var(--panel-border);
52
+ background: #0c0e13;
53
+ color: var(--text);
54
+ font-size: 13px;
55
+ }
56
+ #search-input:focus { outline: 1px solid var(--accent); }
57
+
58
+ #search-results {
59
+ position: absolute;
60
+ top: 34px;
61
+ left: 0;
62
+ right: 0;
63
+ max-height: 360px;
64
+ overflow-y: auto;
65
+ background: var(--panel);
66
+ border: 1px solid var(--panel-border);
67
+ border-radius: 6px;
68
+ z-index: 20;
69
+ }
70
+
71
+ .search-hit {
72
+ padding: 8px 10px;
73
+ cursor: pointer;
74
+ border-bottom: 1px solid var(--panel-border);
75
+ display: flex;
76
+ justify-content: space-between;
77
+ gap: 8px;
78
+ }
79
+ .search-hit:hover { background: #1d2230; }
80
+ .search-hit .name { font-weight: 600; }
81
+ .search-hit .meta { color: var(--text-dim); font-size: 11px; white-space: nowrap; }
82
+ .search-hit .file { color: var(--text-dim); font-size: 11px; display: block; }
83
+
84
+ #stamp {
85
+ color: var(--text-dim);
86
+ font-size: 11px;
87
+ white-space: nowrap;
88
+ }
89
+
90
+ #layout {
91
+ display: grid;
92
+ grid-template-columns: 220px 1fr 320px;
93
+ height: calc(100% - 44px);
94
+ }
95
+
96
+ #filters, #inspector {
97
+ background: var(--panel);
98
+ overflow-y: auto;
99
+ padding: 12px;
100
+ }
101
+ #filters { border-right: 1px solid var(--panel-border); }
102
+ #inspector { border-left: 1px solid var(--panel-border); }
103
+
104
+ #filters h2 {
105
+ font-size: 12px;
106
+ text-transform: uppercase;
107
+ letter-spacing: 0.06em;
108
+ color: var(--text-dim);
109
+ margin: 0 0 10px;
110
+ }
111
+
112
+ .filter-group { margin-bottom: 16px; }
113
+ .filter-group h3 {
114
+ font-size: 11px;
115
+ text-transform: uppercase;
116
+ letter-spacing: 0.04em;
117
+ color: var(--text-dim);
118
+ margin: 0 0 6px;
119
+ }
120
+
121
+ #direction-select {
122
+ width: 100%;
123
+ padding: 5px;
124
+ background: #0c0e13;
125
+ color: var(--text);
126
+ border: 1px solid var(--panel-border);
127
+ border-radius: 4px;
128
+ }
129
+
130
+ .chip-list { display: flex; flex-wrap: wrap; gap: 4px; }
131
+ .chip {
132
+ font-size: 11px;
133
+ padding: 3px 7px;
134
+ border-radius: 10px;
135
+ border: 1px solid var(--panel-border);
136
+ cursor: pointer;
137
+ user-select: none;
138
+ color: var(--text-dim);
139
+ }
140
+ .chip.active {
141
+ border-color: var(--accent);
142
+ color: var(--text);
143
+ background: var(--accent-dim);
144
+ }
145
+ .chip-note { font-size: 11px; color: var(--text-dim); line-height: 1.4; }
146
+
147
+ #export-btn {
148
+ width: 100%;
149
+ padding: 7px;
150
+ background: var(--accent-dim);
151
+ color: var(--text);
152
+ border: 1px solid var(--accent);
153
+ border-radius: 5px;
154
+ cursor: pointer;
155
+ }
156
+ #export-btn:disabled { opacity: 0.4; cursor: not-allowed; }
157
+
158
+ #notes { font-size: 11px; color: var(--warn); line-height: 1.5; }
159
+ #notes p { margin: 6px 0; }
160
+
161
+ #canvas-wrap {
162
+ position: relative;
163
+ overflow: hidden;
164
+ background:
165
+ radial-gradient(circle, #1a1e29 1px, transparent 1px) 0 0 / 22px 22px,
166
+ var(--bg);
167
+ }
168
+
169
+ #graph-canvas { display: block; width: 100%; height: 100%; cursor: grab; }
170
+ #graph-canvas.dragging { cursor: grabbing; }
171
+
172
+ #empty-state {
173
+ position: absolute;
174
+ inset: 0;
175
+ display: flex;
176
+ flex-direction: column;
177
+ align-items: center;
178
+ justify-content: center;
179
+ color: var(--text-dim);
180
+ pointer-events: none;
181
+ text-align: center;
182
+ }
183
+ #empty-state .hint { font-size: 12px; max-width: 360px; }
184
+
185
+ #hover-tooltip {
186
+ position: absolute;
187
+ pointer-events: none;
188
+ background: #05060a;
189
+ border: 1px solid var(--panel-border);
190
+ border-radius: 4px;
191
+ padding: 4px 8px;
192
+ font-size: 11px;
193
+ color: var(--text);
194
+ white-space: nowrap;
195
+ z-index: 30;
196
+ }
197
+
198
+ #inspector-empty { color: var(--text-dim); font-size: 12px; }
199
+
200
+ #inspector-content h2 {
201
+ font-size: 14px;
202
+ margin: 0 0 4px;
203
+ word-break: break-word;
204
+ }
205
+ #inspector-content .kind-badge {
206
+ display: inline-block;
207
+ font-size: 10px;
208
+ padding: 2px 6px;
209
+ border-radius: 4px;
210
+ background: var(--accent-dim);
211
+ color: var(--text);
212
+ margin-bottom: 8px;
213
+ }
214
+
215
+ .field-row {
216
+ display: flex;
217
+ justify-content: space-between;
218
+ gap: 8px;
219
+ padding: 4px 0;
220
+ border-bottom: 1px solid var(--panel-border);
221
+ font-size: 12px;
222
+ }
223
+ .field-row .k { color: var(--text-dim); }
224
+ .field-row .v { text-align: right; word-break: break-word; }
225
+
226
+ .reliability-A { color: var(--ok); }
227
+ .reliability-B { color: var(--warn); }
228
+ .reliability-C { color: var(--danger); }
229
+
230
+ #inspector-content pre {
231
+ background: #0c0e13;
232
+ border: 1px solid var(--panel-border);
233
+ border-radius: 5px;
234
+ padding: 8px;
235
+ font-size: 11px;
236
+ overflow-x: auto;
237
+ white-space: pre-wrap;
238
+ word-break: break-word;
239
+ }
240
+
241
+ .section-title {
242
+ font-size: 11px;
243
+ text-transform: uppercase;
244
+ letter-spacing: 0.04em;
245
+ color: var(--text-dim);
246
+ margin: 14px 0 6px;
247
+ }
248
+
249
+ .why-connected {
250
+ border: 1px solid var(--accent);
251
+ border-radius: 5px;
252
+ padding: 8px;
253
+ background: rgba(93, 169, 255, 0.08);
254
+ font-size: 12px;
255
+ line-height: 1.5;
256
+ }
257
+
258
+ button.link-btn {
259
+ background: none;
260
+ border: none;
261
+ color: var(--accent);
262
+ cursor: pointer;
263
+ padding: 0;
264
+ font-size: 12px;
265
+ text-decoration: underline;
266
+ }