1:root {
2 --bg: #ffffff;
3 --chrome: #f3f3f3;
4 --panel: #f8f8f8;
5 --border: #e2e2e2;
6 --text: #1f1f1f;
7 --muted: #6b6b6b;
8 --accent: #0a66c2;
9 --hover: #ececec;
10 --selected: #d6e8fb;
11 --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
12 font-family: system-ui, -apple-system, "Segoe UI", sans-serif;
13 color: var(--text);
14}
16* {
17 box-sizing: border-box;
18}
20html,
21body,
22#root {
23 height: 100%;
24 margin: 0;
25}
27#root {
28 height: 100vh;
29}
31.app {
32 display: flex;
33 flex-direction: column;
34 height: 100%;
35 overflow: hidden;
36 background: var(--bg);
37}
39/* ── Title bar ─────────────────────────────────────────────────────────── */
40.titlebar {
41 display: flex;
42 align-items: center;
43 gap: 8px;
44 height: 40px;
45 flex-shrink: 0;
46 padding: 0 8px;
47 background: var(--chrome);
48 border-bottom: 1px solid var(--border);
49 font-size: 13px;
50}
52.app-title {
53 font-weight: 600;
54 white-space: nowrap;
55 flex-shrink: 0;
56}
58.file-name {
59 color: var(--muted);
60 font-size: 12px;
61 overflow: hidden;
62 text-overflow: ellipsis;
63 white-space: nowrap;
64 max-width: 40vw;
65}
67.spacer {
68 flex: 1;
69}
71.icon-btn,
72.text-btn {
73 font: inherit;
74 border: 1px solid transparent;
75 background: transparent;
76 color: var(--text);
77 cursor: pointer;
78 border-radius: 5px;
79 padding: 4px 8px;
80 line-height: 1;
81}
83.icon-btn {
84 font-size: 16px;
85 width: 30px;
86 height: 28px;
87 display: inline-flex;
88 align-items: center;
89 justify-content: center;
90}
92.icon-btn:hover,
93.text-btn:hover:not(:disabled) {
94 background: var(--hover);
95}
97.text-btn {
98 border-color: var(--border);
99 font-size: 12px;
100 background: #fff;
101}
103.text-btn:disabled {
104 opacity: 0.5;
105 cursor: default;
106}
108.error-bar {
109 flex-shrink: 0;
110 padding: 8px 12px;
111 background: #fdecea;
112 color: #a4231f;
113 font-size: 12.5px;
114 border-bottom: 1px solid #f3c2bf;
115}
117/* ── Empty state ───────────────────────────────────────────────────────── */
118.empty-state {
119 flex: 1;
120 display: flex;
121 align-items: center;
122 justify-content: center;
123 cursor: pointer;
124 padding: 24px;
125}
127.empty-inner {
128 border: 2px dashed #c4c4c4;
129 border-radius: 12px;
130 padding: 48px 56px;
131 text-align: center;
132 color: var(--muted);
133 max-width: 460px;
134}
136.empty-state.over .empty-inner {
137 border-color: var(--accent);
138 background: #f0f7ff;
139}
141.empty-icon {
142 font-size: 40px;
143 color: #b9b9b9;
144}
146.empty-inner h2 {
147 margin: 12px 0 6px;
148 color: var(--text);
149 font-size: 18px;
150}
152.empty-inner p {
153 margin: 4px 0;
154 font-size: 13px;
155}
157code {
158 font-family: var(--mono);
159 background: #efefef;
160 padding: 1px 5px;
161 border-radius: 4px;
162 font-size: 0.92em;
163}
165.muted {
166 color: var(--muted);
167}
168.small {
169 font-size: 12px;
170}
172/* ── Body / panels ─────────────────────────────────────────────────────── */
173.body {
174 flex: 1;
175 display: flex;
176 min-height: 0;
177 position: relative;
178}
180.panel {
181 display: flex;
182 flex-direction: column;
183 background: var(--panel);
184 min-width: 0;
185 overflow: hidden;
186}
188.panel.right {
189 background: #fbfbfb;
190}
192.panel-head {
193 display: flex;
194 align-items: center;
195 justify-content: space-between;
196 flex-shrink: 0;
197 height: 30px;
198 padding: 0 10px;
199 font-size: 11px;
200 font-weight: 600;
201 letter-spacing: 0.05em;
202 text-transform: uppercase;
203 color: var(--muted);
204 border-bottom: 1px solid var(--border);
205}
207.panel-body {
208 flex: 1;
209 overflow: auto;
210}
212.center {
213 flex: 1;
214 position: relative;
215 min-width: 0;
216 background: #fff;
217}
219.figure-host {
220 position: absolute;
221 inset: 0;
222}
224.drop-hint {
225 position: absolute;
226 inset: 0;
227 display: flex;
228 align-items: center;
229 justify-content: center;
230 background: rgba(10, 102, 194, 0.08);
231 border: 2px dashed var(--accent);
232 color: var(--accent);
233 font-weight: 600;
234 pointer-events: none;
235}
237/* ── Divider ───────────────────────────────────────────────────────────── */
238.divider {
239 width: 6px;
240 flex-shrink: 0;
241 cursor: col-resize;
242 background: transparent;
243 position: relative;
244}
246.divider::after {
247 content: "";
248 position: absolute;
249 inset: 0 2px;
250 background: var(--border);
251}
253.divider:hover::after {
254 background: var(--accent);
255}
257/* ── Tree ──────────────────────────────────────────────────────────────── */
258.tree {
259 padding: 4px 0;
260 font-size: 13px;
261 user-select: none;
262}
264.tree-row {
265 display: flex;
266 align-items: center;
267 height: 24px;
268 padding-right: 8px;
269 cursor: pointer;
270 white-space: nowrap;
271}
273.tree-row:hover {
274 background: var(--hover);
275}
277.tree-row.selected {
278 background: var(--selected);
279}
281.twisty {
282 width: 16px;
283 flex-shrink: 0;
284 text-align: center;
285 color: var(--muted);
286 font-size: 10px;
287}
289.twisty.leaf {
290 visibility: hidden;
291}
293.node-icon {
294 width: 18px;
295 flex-shrink: 0;
296 text-align: center;
297 color: var(--muted);
298}
300.icon-figure {
301 color: #7a5cc4;
302}
303.icon-axes {
304 color: #2f8f5b;
305}
306.icon-trace {
307 color: #c2731f;
308}
309.icon-dataset {
310 color: #8a8a8a;
311}
313.node-label {
314 flex: 1;
315 overflow: hidden;
316 text-overflow: ellipsis;
317}
319.tree-row.dimmed .node-label,
320.tree-row.dimmed .node-icon {
321 opacity: 0.4;
322}
324/* ── Row visibility controls ───────────────────────────────────────────── */
325.row-actions {
326 display: flex;
327 align-items: center;
328 gap: 1px;
329 margin-left: 4px;
330 flex-shrink: 0;
331 visibility: hidden;
332}
334.tree-row:hover .row-actions,
335.tree-row.selected .row-actions,
336.tree-row.el-hidden .row-actions {
337 visibility: visible;
338}
340.act-btn {
341 display: inline-flex;
342 align-items: center;
343 justify-content: center;
344 width: 22px;
345 height: 20px;
346 border: none;
347 background: transparent;
348 color: var(--muted);
349 cursor: pointer;
350 border-radius: 4px;
351 padding: 0;
352}
354.act-btn:hover {
355 background: rgba(0, 0, 0, 0.08);
356 color: var(--text);
357}
359.act-btn.active {
360 color: var(--accent);
361}
363.head-actions {
364 display: flex;
365 align-items: center;
366 gap: 6px;
367}
369.link-btn {
370 font: inherit;
371 font-size: 11px;
372 text-transform: none;
373 letter-spacing: 0;
374 border: none;
375 background: transparent;
376 color: var(--accent);
377 cursor: pointer;
378 padding: 0;
379}
381.link-btn:hover {
382 text-decoration: underline;
383}
385.center-overlay {
386 position: absolute;
387 inset: 0;
388 display: flex;
389 align-items: center;
390 justify-content: center;
391 text-align: center;
392 color: var(--muted);
393}
395.center-overlay button {
396 margin-top: 8px;
397}
399/* ── Info panel ────────────────────────────────────────────────────────── */
400.info {
401 padding: 10px 12px;
402 font-size: 13px;
403}
405.info.empty {
406 color: var(--muted);
407}
409.info-header {
410 display: flex;
411 align-items: center;
412 gap: 6px;
413 margin-bottom: 10px;
414}
416.info-title {
417 font-weight: 600;
418 word-break: break-word;
419}
421.info-kind {
422 margin-left: auto;
423 font-size: 11px;
424 color: var(--muted);
425 background: #ededed;
426 padding: 1px 7px;
427 border-radius: 10px;
428}
430table.props {
431 width: 100%;
432 border-collapse: collapse;
433}
435table.props td {
436 padding: 3px 6px;
437 vertical-align: top;
438 border-bottom: 1px solid #efefef;
439}
441td.pk {
442 color: var(--muted);
443 width: 38%;
444 font-size: 12px;
445}
447td.pv {
448 font-family: var(--mono);
449 font-size: 12px;
450 word-break: break-word;
451}
453.swatch {
454 display: inline-block;
455 width: 11px;
456 height: 11px;
457 border-radius: 2px;
458 border: 1px solid #00000022;
459 margin-right: 6px;
460 vertical-align: middle;
461}
463.preview-label {
464 margin: 12px 0 4px;
465 font-size: 11px;
466 text-transform: uppercase;
467 letter-spacing: 0.05em;
468 color: var(--muted);
469}
471.preview {
472 margin: 0;
473 font-family: var(--mono);
474 font-size: 11.5px;
475 background: #f4f4f4;
476 border: 1px solid var(--border);
477 border-radius: 6px;
478 padding: 8px;
479 white-space: pre-wrap;
480 word-break: break-word;
481 max-height: 48vh;
482 overflow: auto;
483}
485.vfooter {
486 display: flex;
487 align-items: center;
488 gap: 8px;
489 flex-wrap: wrap;
490 margin-top: 6px;
491}
493.text-btn.sm {
494 padding: 2px 8px;
495 font-size: 11px;
496}
498/* ── Mobile drawers ────────────────────────────────────────────────────── */
499.panel.drawer {
500 position: absolute;
501 top: 0;
502 bottom: 0;
503 width: min(82%, 340px);
504 z-index: 20;
505 box-shadow: 0 0 24px rgba(0, 0, 0, 0.22);
506}
508.panel.left.drawer {
509 left: 0;
510}
512.panel.right.drawer {
513 right: 0;
514}
516.backdrop {
517 position: absolute;
518 inset: 0;
519 background: rgba(0, 0, 0, 0.28);
520 z-index: 10;
521}
523/* ── Toast ─────────────────────────────────────────────────────────────── */
524.toast {
525 position: fixed;
526 left: 50%;
527 bottom: 28px;
528 transform: translateX(-50%);
529 z-index: 50;
530 max-width: 90vw;
531 padding: 9px 16px;
532 border-radius: 8px;
533 background: #2b2b2b;
534 color: #fff;
535 font-size: 13px;
536 box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
537 animation: toast-in 0.15s ease-out;
538}
540@keyframes toast-in {
541 from {
542 opacity: 0;
543 transform: translate(-50%, 6px);
544 }
545 to {
546 opacity: 1;
547 transform: translate(-50%, 0);
548 }
549}
551/* Touch / narrow screens: no hover, so always show the row controls. */
552@media (max-width: 820px) {
553 .row-actions {
554 visibility: visible;
555 }
556}
558/* Narrow screens: drop the redundant filename (shown in the tree root). */
559@media (max-width: 560px) {
560 .file-name {
561 display: none;
562 }
563}