sqlite-hub 0.4.0 → 0.6.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 (56) hide show
  1. package/README.md +2 -2
  2. package/changelog.md +15 -0
  3. package/frontend/assets/mockups/connections.png +0 -0
  4. package/frontend/assets/mockups/data.png +0 -0
  5. package/frontend/assets/mockups/data_row_editor.png +0 -0
  6. package/frontend/assets/mockups/home.png +0 -0
  7. package/frontend/assets/mockups/sql_editor.png +0 -0
  8. package/frontend/assets/mockups/sql_editor_querydetail.png +0 -0
  9. package/frontend/assets/mockups/structure.png +0 -0
  10. package/frontend/assets/mockups/structure_inspector.png +0 -0
  11. package/frontend/js/api.js +114 -5
  12. package/frontend/js/app.js +368 -18
  13. package/frontend/js/components/bottomTabs.js +1 -1
  14. package/frontend/js/components/dataGrid.js +3 -3
  15. package/frontend/js/components/queryEditor.js +33 -55
  16. package/frontend/js/components/queryHistoryDetail.js +263 -0
  17. package/frontend/js/components/queryHistoryPanel.js +228 -0
  18. package/frontend/js/components/queryResults.js +32 -46
  19. package/frontend/js/components/rowEditorPanel.js +73 -14
  20. package/frontend/js/components/sidebar.js +1 -0
  21. package/frontend/js/components/tableDesignerEditor.js +356 -0
  22. package/frontend/js/components/tableDesignerSidebar.js +126 -0
  23. package/frontend/js/components/tableDesignerSqlPreview.js +40 -0
  24. package/frontend/js/router.js +10 -0
  25. package/frontend/js/store.js +841 -22
  26. package/frontend/js/utils/format.js +23 -0
  27. package/frontend/js/utils/tableDesigner.js +1192 -0
  28. package/frontend/js/views/data.js +273 -250
  29. package/frontend/js/views/editor.js +34 -10
  30. package/frontend/js/views/overview.js +15 -0
  31. package/frontend/js/views/tableDesigner.js +37 -0
  32. package/frontend/styles/base.css +87 -73
  33. package/frontend/styles/components.css +841 -188
  34. package/frontend/styles/views.css +40 -0
  35. package/package.json +1 -1
  36. package/server/routes/data.js +2 -0
  37. package/server/routes/export.js +4 -1
  38. package/server/routes/overview.js +12 -0
  39. package/server/routes/sql.js +163 -5
  40. package/server/routes/tableDesigner.js +60 -0
  41. package/server/server.js +5 -1
  42. package/server/services/sqlite/dataBrowserService.js +4 -16
  43. package/server/services/sqlite/exportService.js +4 -16
  44. package/server/services/sqlite/overviewService.js +34 -0
  45. package/server/services/sqlite/sqlExecutor.js +83 -63
  46. package/server/services/sqlite/tableDesigner/changeAnalysis.js +295 -0
  47. package/server/services/sqlite/tableDesigner/schemaMapping.js +233 -0
  48. package/server/services/sqlite/tableDesigner/sql.js +63 -0
  49. package/server/services/sqlite/tableDesigner/validation.js +245 -0
  50. package/server/services/sqlite/tableDesignerService.js +181 -0
  51. package/server/services/sqlite/tableSort.js +63 -0
  52. package/server/services/storage/appStateStore.js +674 -1
  53. package/server/services/storage/queryHistoryUtils.js +169 -0
  54. package/frontend/assets/mockups/data_edit.png +0 -0
  55. package/frontend/assets/mockups/graph_visualize.png +0 -0
  56. package/frontend/assets/mockups/overview.png +0 -0
@@ -1,323 +1,976 @@
1
1
  .top-nav-shell {
2
- align-items: center;
3
- background: linear-gradient(to bottom, rgba(255, 255, 255, 0.05), transparent);
4
- display: flex;
5
- height: 100%;
6
- justify-content: space-between;
7
- padding: 0 var(--spacing-6);
2
+ align-items: center;
3
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 0.05), transparent);
4
+ display: flex;
5
+ height: 100%;
6
+ justify-content: space-between;
7
+ padding: 0 var(--spacing-6);
8
8
  }
9
9
 
10
10
  .top-nav-brand {
11
- color: var(--color-primary-container);
12
- font-family: var(--font-family-headline);
13
- font-size: 1.25rem;
14
- font-weight: 900;
15
- letter-spacing: 0.2em;
16
- text-transform: uppercase;
11
+ color: var(--color-primary-container);
12
+ font-family: var(--font-family-headline);
13
+ font-size: 1.25rem;
14
+ font-weight: 900;
15
+ letter-spacing: 0.2em;
16
+ text-transform: uppercase;
17
17
  }
18
18
 
19
19
  .top-nav-links {
20
- align-items: center;
21
- display: none;
22
- gap: var(--spacing-4);
23
- height: 100%;
20
+ align-items: center;
21
+ display: none;
22
+ gap: var(--spacing-4);
23
+ height: 100%;
24
24
  }
25
25
 
26
26
  .top-nav-link {
27
- align-items: center;
28
- color: rgba(229, 226, 225, 0.6);
29
- display: flex;
30
- font-family: var(--font-family-headline);
31
- height: 100%;
32
- letter-spacing: -0.04em;
33
- padding: 0 var(--spacing-2);
34
- text-transform: uppercase;
35
- transition: background-color var(--transition-fast), color var(--transition-fast);
27
+ align-items: center;
28
+ color: rgba(229, 226, 225, 0.6);
29
+ display: flex;
30
+ font-family: var(--font-family-headline);
31
+ height: 100%;
32
+ letter-spacing: -0.04em;
33
+ padding: 0 var(--spacing-2);
34
+ text-transform: uppercase;
35
+ transition:
36
+ background-color var(--transition-fast),
37
+ color var(--transition-fast);
36
38
  }
37
39
 
38
40
  .top-nav-link:hover {
39
- background: var(--color-surface-highest);
41
+ background: var(--color-surface-highest);
40
42
  }
41
43
 
42
44
  .top-nav-link.is-active {
43
- border-bottom: 2px solid var(--color-primary-container);
44
- color: var(--color-primary-container);
45
- padding-bottom: 1px;
45
+ border-bottom: 2px solid var(--color-primary-container);
46
+ color: var(--color-primary-container);
47
+ padding-bottom: 1px;
46
48
  }
47
49
 
48
50
  .top-nav-actions {
49
- align-items: center;
50
- display: flex;
51
- gap: var(--spacing-2);
51
+ align-items: center;
52
+ display: flex;
53
+ gap: var(--spacing-2);
52
54
  }
53
55
 
54
56
  .top-nav-icon {
55
- align-items: center;
56
- color: var(--color-primary-container);
57
- display: inline-flex;
58
- height: 2rem;
59
- justify-content: center;
60
- transition: background-color var(--transition-fast);
61
- width: 2rem;
57
+ align-items: center;
58
+ color: var(--color-primary-container);
59
+ display: inline-flex;
60
+ height: 2rem;
61
+ justify-content: center;
62
+ transition: background-color var(--transition-fast);
63
+ width: 2rem;
62
64
  }
63
65
 
64
66
  .top-nav-icon:hover {
65
- background: var(--color-surface-highest);
67
+ background: var(--color-surface-highest);
66
68
  }
67
69
 
68
70
  .sidebar-shell {
69
- background: var(--color-surface-low);
70
- box-shadow: var(--shadow-sidebar);
71
- flex-direction: column;
72
- min-height: 0;
73
- padding: var(--spacing-4) 0;
71
+ background: var(--color-surface-low);
72
+ box-shadow: var(--shadow-sidebar);
73
+ flex-direction: column;
74
+ min-height: 0;
75
+ padding: var(--spacing-4) 0;
74
76
  }
75
77
 
76
78
  .sidebar-links {
77
- display: flex;
78
- flex: 1;
79
- flex-direction: column;
80
- gap: var(--spacing-1);
81
- min-height: 0;
79
+ display: flex;
80
+ flex: 1;
81
+ flex-direction: column;
82
+ gap: var(--spacing-1);
83
+ min-height: 0;
82
84
  }
83
85
 
84
86
  .sidebar-link {
85
- align-items: center;
86
- color: rgba(229, 226, 225, 0.4);
87
- display: flex;
88
- font-family: var(--font-family-headline);
89
- font-size: 0.75rem;
90
- font-weight: 700;
91
- gap: var(--spacing-4);
92
- letter-spacing: 0.15em;
93
- padding: 0.75rem var(--spacing-6);
94
- text-transform: uppercase;
95
- transition: background-color var(--transition-fast), color var(--transition-fast),
96
- border-color var(--transition-fast);
87
+ align-items: center;
88
+ color: rgba(229, 226, 225, 0.4);
89
+ display: flex;
90
+ font-family: var(--font-family-headline);
91
+ font-size: 0.75rem;
92
+ font-weight: 700;
93
+ gap: var(--spacing-4);
94
+ letter-spacing: 0.15em;
95
+ padding: 0.75rem var(--spacing-6);
96
+ text-transform: uppercase;
97
+ transition:
98
+ background-color var(--transition-fast),
99
+ color var(--transition-fast),
100
+ border-color var(--transition-fast);
97
101
  }
98
102
 
99
103
  .sidebar-link:hover {
100
- background: var(--color-surface-container);
101
- color: var(--color-primary-container);
104
+ background: var(--color-surface-container);
105
+ color: var(--color-primary-container);
102
106
  }
103
107
 
104
108
  .sidebar-link.is-active {
105
- background: var(--color-surface-high);
106
- border-left: 2px solid var(--color-primary-container);
107
- color: var(--color-primary-container);
109
+ background: var(--color-surface-high);
110
+ border-left: 2px solid var(--color-primary-container);
111
+ color: var(--color-primary-container);
108
112
  }
109
113
 
110
114
  .sidebar-footer {
111
- margin-top: auto;
112
- padding: 0 var(--spacing-6);
115
+ margin-top: auto;
116
+ padding: 0 var(--spacing-6);
113
117
  }
114
118
 
115
119
  .sidebar-footer-card {
116
- align-items: center;
117
- background: var(--color-surface-lowest);
118
- display: flex;
119
- gap: var(--spacing-3);
120
- padding: var(--spacing-2);
120
+ align-items: center;
121
+ background: var(--color-surface-lowest);
122
+ display: flex;
123
+ gap: var(--spacing-3);
124
+ padding: var(--spacing-2);
121
125
  }
122
126
 
123
127
  .sidebar-footer-mark {
124
- align-items: center;
125
- background: var(--color-primary-container);
126
- color: var(--color-on-primary);
127
- display: flex;
128
- font-size: 0.75rem;
129
- font-weight: 900;
130
- height: 2rem;
131
- justify-content: center;
132
- width: 2rem;
128
+ align-items: center;
129
+ background: var(--color-primary-container);
130
+ color: var(--color-on-primary);
131
+ display: flex;
132
+ font-size: 0.75rem;
133
+ font-weight: 900;
134
+ height: 2rem;
135
+ justify-content: center;
136
+ width: 2rem;
133
137
  }
134
138
 
135
139
  .status-bar-shell {
136
- align-items: center;
137
- background: var(--color-surface-lowest);
138
- border-top: 1px solid rgba(75, 71, 50, 0.15);
139
- display: flex;
140
- height: 100%;
141
- justify-content: space-between;
142
- padding: 0 var(--spacing-4);
140
+ align-items: center;
141
+ background: var(--color-surface-lowest);
142
+ border-top: 1px solid rgba(75, 71, 50, 0.15);
143
+ display: flex;
144
+ height: 100%;
145
+ justify-content: space-between;
146
+ padding: 0 var(--spacing-4);
143
147
  }
144
148
 
145
149
  .status-bar-primary,
146
150
  .status-bar-secondary {
147
- align-items: center;
148
- display: flex;
149
- gap: var(--spacing-4);
151
+ align-items: center;
152
+ display: flex;
153
+ gap: var(--spacing-4);
150
154
  }
151
155
 
152
156
  .status-bar-text {
153
- color: var(--color-primary-container);
154
- font-family: var(--font-family-mono);
155
- font-size: var(--font-size-status);
156
- letter-spacing: -0.02em;
157
+ color: var(--color-primary-container);
158
+ font-family: var(--font-family-mono);
159
+ font-size: var(--font-size-status);
160
+ letter-spacing: -0.02em;
157
161
  }
158
162
 
159
163
  .status-bar-link {
160
- color: rgba(229, 226, 225, 0.3);
161
- cursor: default;
162
- font-family: var(--font-family-mono);
163
- font-size: var(--font-size-status);
164
- letter-spacing: -0.02em;
165
- text-transform: uppercase;
166
- transition: color var(--transition-fast);
164
+ color: rgba(229, 226, 225, 0.3);
165
+ cursor: default;
166
+ font-family: var(--font-family-mono);
167
+ font-size: var(--font-size-status);
168
+ letter-spacing: -0.02em;
169
+ text-transform: uppercase;
170
+ transition: color var(--transition-fast);
167
171
  }
168
172
 
169
173
  .status-bar-link:hover {
170
- color: var(--color-primary-container);
174
+ color: var(--color-primary-container);
171
175
  }
172
176
 
173
177
  .status-bar-dot {
174
- background: var(--color-success);
175
- border-radius: 9999px;
176
- box-shadow: 0 0 8px rgba(34, 197, 94, 0.6);
177
- height: 6px;
178
- width: 6px;
178
+ background: var(--color-success);
179
+ border-radius: 9999px;
180
+ box-shadow: 0 0 8px rgba(34, 197, 94, 0.6);
181
+ height: 6px;
182
+ width: 6px;
179
183
  }
180
184
 
181
185
  .shell-section {
182
- background: var(--color-surface-container);
183
- border: 1px solid rgba(75, 71, 50, 0.12);
186
+ background: var(--color-surface-container);
187
+ border: 1px solid rgba(75, 71, 50, 0.12);
184
188
  }
185
189
 
186
190
  .toolbar-button {
187
- align-items: center;
188
- display: inline-flex;
189
- gap: var(--spacing-2);
190
- justify-content: center;
191
- text-transform: uppercase;
192
- transition: background-color var(--transition-fast), box-shadow var(--transition-standard),
193
- color var(--transition-fast);
191
+ align-items: center;
192
+ display: inline-flex;
193
+ gap: var(--spacing-2);
194
+ justify-content: center;
195
+ text-transform: uppercase;
196
+ transition:
197
+ background-color var(--transition-fast),
198
+ box-shadow var(--transition-standard),
199
+ color var(--transition-fast);
194
200
  }
195
201
 
196
202
  .toolbar-button--primary:hover {
197
- box-shadow: var(--shadow-subtle-glow);
203
+ box-shadow: var(--shadow-subtle-glow);
198
204
  }
199
205
 
200
206
  .metric-card {
201
- background: var(--color-surface-low);
202
- display: flex;
203
- flex-direction: column;
204
- gap: var(--spacing-2);
205
- padding: var(--spacing-6);
207
+ background: var(--color-surface-low);
208
+ display: flex;
209
+ flex-direction: column;
210
+ gap: var(--spacing-2);
211
+ padding: var(--spacing-6);
206
212
  }
207
213
 
208
214
  .metric-card--accent {
209
- border-left: 2px solid var(--color-primary-container);
215
+ border-left: 2px solid var(--color-primary-container);
210
216
  }
211
217
 
212
218
  .status-badge {
213
- border: 1px solid transparent;
214
- display: inline-flex;
215
- font-size: var(--font-size-micro);
216
- font-weight: 700;
217
- letter-spacing: 0.12em;
218
- padding: 0.125rem 0.5rem;
219
- text-transform: uppercase;
219
+ border: 1px solid transparent;
220
+ display: inline-flex;
221
+ font-size: var(--font-size-micro);
222
+ font-weight: 700;
223
+ letter-spacing: 0.12em;
224
+ padding: 0.125rem 0.5rem;
225
+ text-transform: uppercase;
220
226
  }
221
227
 
222
228
  .status-badge--primary {
223
- background: rgba(252, 227, 0, 0.1);
224
- border-color: rgba(252, 227, 0, 0.2);
225
- color: var(--color-primary-container);
229
+ background: rgba(252, 227, 0, 0.1);
230
+ border-color: rgba(252, 227, 0, 0.2);
231
+ color: var(--color-primary-container);
226
232
  }
227
233
 
228
234
  .status-badge--muted {
229
- background: var(--color-surface-highest);
230
- border-color: rgba(75, 71, 50, 0.2);
231
- color: var(--color-on-surface-variant);
235
+ background: var(--color-surface-highest);
236
+ border-color: rgba(75, 71, 50, 0.2);
237
+ color: var(--color-on-surface-variant);
232
238
  }
233
239
 
234
240
  .status-badge--alert {
235
- background: rgba(147, 0, 10, 0.2);
236
- border-color: rgba(255, 180, 171, 0.2);
237
- color: var(--color-error);
241
+ background: rgba(147, 0, 10, 0.2);
242
+ border-color: rgba(255, 180, 171, 0.2);
243
+ color: var(--color-error);
238
244
  }
239
245
 
240
246
  .status-badge--success {
241
- background: rgba(0, 220, 225, 0.1);
242
- color: var(--color-tertiary-dim);
247
+ background: rgba(0, 220, 225, 0.1);
248
+ color: var(--color-tertiary-dim);
243
249
  }
244
250
 
245
251
  .connection-card {
246
- background: var(--color-surface-container);
247
- border-left: 2px solid transparent;
248
- cursor: pointer;
249
- display: flex;
250
- flex-direction: column;
251
- min-height: 100%;
252
- text-align: left;
253
- transition: background-color var(--transition-fast), border-color var(--transition-fast),
254
- box-shadow var(--transition-standard);
252
+ background: var(--color-surface-container);
253
+ border-left: 2px solid transparent;
254
+ cursor: pointer;
255
+ display: flex;
256
+ flex-direction: column;
257
+ min-height: 100%;
258
+ text-align: left;
259
+ transition:
260
+ background-color var(--transition-fast),
261
+ border-color var(--transition-fast),
262
+ box-shadow var(--transition-standard);
255
263
  }
256
264
 
257
265
  .connection-card:hover {
258
- background: var(--color-surface-high);
259
- border-color: var(--color-outline-variant);
266
+ background: var(--color-surface-high);
267
+ border-color: var(--color-outline-variant);
260
268
  }
261
269
 
262
270
  .connection-card.is-active {
263
- border-color: var(--color-primary-container);
264
- box-shadow: 0 0 20px rgba(252, 227, 0, 0.05);
271
+ border-color: var(--color-primary-container);
272
+ box-shadow: 0 0 20px rgba(252, 227, 0, 0.05);
265
273
  }
266
274
 
267
275
  .connection-card-footer {
268
- background: var(--color-surface-highest);
269
- height: 4px;
270
- width: 100%;
276
+ background: var(--color-surface-highest);
277
+ height: 4px;
278
+ width: 100%;
271
279
  }
272
280
 
273
281
  .bottom-tab {
274
- border-bottom: 1px solid transparent;
275
- color: rgba(205, 199, 171, 0.4);
276
- font-size: var(--font-size-status);
277
- font-weight: 700;
278
- height: 100%;
279
- letter-spacing: 0.15em;
280
- text-transform: uppercase;
282
+ border-bottom: 1px solid transparent;
283
+ color: rgba(205, 199, 171, 0.4);
284
+ font-size: var(--font-size-status);
285
+ font-weight: 700;
286
+ height: 100%;
287
+ letter-spacing: 0.15em;
288
+ text-transform: uppercase;
281
289
  }
282
290
 
283
291
  .bottom-tab.is-active {
284
- border-color: var(--color-primary-container);
285
- color: var(--color-primary-container);
292
+ border-color: var(--color-primary-container);
293
+ color: var(--color-primary-container);
286
294
  }
287
295
 
288
296
  .page-eyebrow {
289
- align-items: center;
290
- display: flex;
291
- gap: var(--spacing-2);
292
- margin-bottom: var(--spacing-2);
297
+ align-items: center;
298
+ display: flex;
299
+ gap: var(--spacing-2);
300
+ margin-bottom: var(--spacing-2);
293
301
  }
294
302
 
295
303
  .page-eyebrow-line {
296
- background: rgba(252, 227, 0, 0.3);
297
- height: 1px;
298
- width: 48px;
304
+ background: rgba(252, 227, 0, 0.3);
305
+ height: 1px;
306
+ width: 48px;
299
307
  }
300
308
 
301
309
  .empty-state-shell {
302
- max-width: 42rem;
303
- width: 100%;
310
+ max-width: 42rem;
311
+ width: 100%;
304
312
  }
305
313
 
306
314
  .view-card {
307
- background: var(--color-surface-low);
308
- border: 1px solid rgba(75, 71, 50, 0.1);
315
+ background: var(--color-surface-low);
316
+ border: 1px solid rgba(75, 71, 50, 0.1);
309
317
  }
310
318
 
311
319
  .view-card-header {
312
- align-items: center;
313
- background: var(--color-surface-highest);
314
- display: flex;
315
- justify-content: space-between;
316
- padding: var(--spacing-3) var(--spacing-4);
320
+ align-items: center;
321
+ background: var(--color-surface-highest);
322
+ display: flex;
323
+ justify-content: space-between;
324
+ padding: var(--spacing-3) var(--spacing-4);
317
325
  }
318
326
 
319
- @media (min-width: 768px) {
320
- .top-nav-links {
327
+ .query-history-panel {
328
+ display: flex;
329
+ flex: 0 0 360px;
330
+ flex-direction: column;
331
+ min-height: 0;
332
+ width: 360px;
333
+ }
334
+
335
+ .table-designer-sidebar {
336
+ background: var(--color-surface-low);
337
+ border-right: 1px solid rgba(75, 71, 50, 0.18);
338
+ display: flex;
339
+ flex: 0 0 18rem;
340
+ flex-direction: column;
341
+ max-width: 18rem;
342
+ min-height: 0;
343
+ min-width: 18rem;
344
+ width: 18rem;
345
+ }
346
+
347
+ .table-designer-sidebar__header {
348
+ border-bottom: 1px solid rgba(75, 71, 50, 0.18);
349
+ display: flex;
350
+ flex-wrap: wrap;
351
+ gap: var(--spacing-4);
352
+ justify-content: space-between;
353
+ padding: var(--spacing-5);
354
+ }
355
+
356
+ .table-designer-sidebar__header-actions {
357
+ align-items: center;
358
+ display: flex;
359
+ flex-direction: row;
360
+ gap: var(--spacing-2);
361
+ flex-wrap: wrap;
362
+ }
363
+
364
+ .table-designer-sidebar__eyebrow,
365
+ .table-designer-preview__eyebrow,
366
+ .table-designer-main__eyebrow {
367
+ color: var(--color-primary-container);
368
+ font-family: var(--font-family-mono);
369
+ font-size: var(--font-size-status);
370
+ letter-spacing: 0.18em;
371
+ text-transform: uppercase;
372
+ }
373
+
374
+ .table-designer-sidebar__title,
375
+ .table-designer-preview__title,
376
+ .table-designer-main__section-title {
377
+ color: var(--color-on-surface);
378
+ font-family: var(--font-family-headline);
379
+ font-size: 1rem;
380
+ font-weight: 700;
381
+ letter-spacing: -0.04em;
382
+ margin-top: var(--spacing-2);
383
+ }
384
+
385
+ .table-designer-sidebar__meta,
386
+ .table-designer-main__subtitle,
387
+ .table-designer-main__section-text {
388
+ color: rgba(229, 226, 225, 0.52);
389
+ font-family: var(--font-family-mono);
390
+ font-size: var(--font-size-status);
391
+ letter-spacing: 0.14em;
392
+ margin-top: var(--spacing-2);
393
+ text-transform: uppercase;
394
+ }
395
+
396
+ .table-designer-sidebar__new-button,
397
+ .table-designer-sidebar__import-button,
398
+ .table-designer-preview__copy,
399
+ .table-designer-main__secondary,
400
+ .table-designer-main__primary {
401
+ align-items: center;
402
+ border: 1px solid rgba(75, 71, 50, 0.2);
403
+ display: inline-flex;
404
+ font-family: var(--font-family-headline);
405
+ font-size: 0.75rem;
406
+ font-weight: 700;
407
+ justify-content: center;
408
+ letter-spacing: 0.12em;
409
+ min-height: 42px;
410
+ padding: 0 1rem;
411
+ text-transform: uppercase;
412
+ transition:
413
+ background-color var(--transition-fast),
414
+ border-color var(--transition-fast),
415
+ color var(--transition-fast),
416
+ opacity var(--transition-fast);
417
+ }
418
+
419
+ .table-designer-sidebar__new-button,
420
+ .table-designer-main__primary {
421
+ background: var(--color-primary-container);
422
+ border-color: rgba(252, 227, 0, 0.35);
423
+ color: var(--color-on-primary);
424
+ }
425
+
426
+ .table-designer-preview__copy,
427
+ .table-designer-sidebar__import-button,
428
+ .table-designer-main__secondary {
429
+ background: var(--color-surface-container-lowest);
430
+ color: var(--color-on-surface);
431
+ }
432
+
433
+ .table-designer-sidebar__new-button:hover,
434
+ .table-designer-main__primary:hover {
435
+ filter: brightness(1.04);
436
+ }
437
+
438
+ .table-designer-preview__copy:hover,
439
+ .table-designer-sidebar__import-button:hover,
440
+ .table-designer-main__secondary:hover {
441
+ background: var(--color-surface-highest);
442
+ border-color: rgba(252, 227, 0, 0.24);
443
+ color: var(--color-primary-container);
444
+ }
445
+
446
+ .table-designer-sidebar__file-input {
447
+ display: none;
448
+ }
449
+
450
+ .table-designer-main__primary.is-disabled,
451
+ .table-designer-main__primary:disabled {
452
+ cursor: not-allowed;
453
+ opacity: 0.45;
454
+ }
455
+
456
+ .table-designer-sidebar__search {
457
+ align-items: center;
458
+ background: var(--color-surface-container-lowest);
459
+ border: 1px solid rgba(75, 71, 50, 0.18);
460
+ margin: var(--spacing-4) var(--spacing-5) 0;
461
+ border-bottom: 1px solid rgba(75, 71, 50, 0.18);
462
+ display: flex;
463
+ gap: var(--spacing-3);
464
+ padding: 0 var(--spacing-4);
465
+ }
466
+
467
+ .table-designer-sidebar__search-input,
468
+ .table-designer-field,
469
+ .table-designer-main__name {
470
+ background: var(--color-surface-container-lowest);
471
+ border: 1px solid rgba(75, 71, 50, 0.18);
472
+ color: var(--color-on-surface);
473
+ min-width: 0;
474
+ outline: none;
475
+ }
476
+
477
+ input.table-designer-sidebar__search-input,
478
+ input.table-designer-field,
479
+ select.table-designer-field,
480
+ input.table-designer-main__name {
481
+ -webkit-appearance: none;
482
+ appearance: none;
483
+ border-radius: 0;
484
+ box-shadow: none;
485
+ }
486
+
487
+ input.table-designer-field,
488
+ select.table-designer-field {
489
+ background: var(--color-surface-container-lowest) !important;
490
+ color: var(--color-on-surface) !important;
491
+ }
492
+
493
+ .table-designer-sidebar__search-input:focus,
494
+ .table-designer-field:focus,
495
+ .table-designer-main__name:focus {
496
+ border-color: rgba(252, 227, 0, 0.35);
497
+ }
498
+
499
+ .table-designer-sidebar__search-input {
500
+ background: transparent !important;
501
+ border: none;
502
+ color: var(--color-on-surface);
503
+ flex: 1;
504
+ font-size: 0.875rem;
505
+ height: 48px;
506
+ padding: 0;
507
+ }
508
+
509
+ .table-designer-sidebar__list {
510
+ flex: 1;
511
+ min-height: 0;
512
+ overflow: auto;
513
+ padding: var(--spacing-3);
514
+ }
515
+
516
+ .table-designer-sidebar__item {
517
+ background: var(--color-surface-container-lowest);
518
+ border: 1px solid rgba(75, 71, 50, 0.14);
519
+ display: block;
520
+ margin-bottom: var(--spacing-2);
521
+ padding: var(--spacing-4);
522
+ text-align: left;
523
+ transition:
524
+ background-color var(--transition-fast),
525
+ border-color var(--transition-fast);
526
+ width: 100%;
527
+ }
528
+
529
+ .table-designer-sidebar__item:hover {
530
+ background: var(--color-surface-container);
531
+ border-color: rgba(252, 227, 0, 0.22);
532
+ }
533
+
534
+ .table-designer-sidebar__item.is-active {
535
+ background: var(--color-surface-container-high);
536
+ border-color: rgba(252, 227, 0, 0.32);
537
+ }
538
+
539
+ .table-designer-sidebar__item-name {
540
+ color: var(--color-on-surface);
541
+ font-family: var(--font-family-mono);
542
+ font-size: 0.75rem;
543
+ overflow: hidden;
544
+ white-space: nowrap;
545
+ text-overflow: ellipsis;
546
+ }
547
+
548
+ .table-designer-sidebar__item.is-active .table-designer-sidebar__item-name {
549
+ color: var(--color-primary-container);
550
+ }
551
+
552
+ .table-designer-sidebar__item-meta {
553
+ color: rgba(205, 199, 171, 0.48);
554
+ font-family: var(--font-family-mono);
555
+ font-size: var(--font-size-status);
556
+ letter-spacing: 0.12em;
557
+ margin-top: var(--spacing-2);
558
+ text-transform: uppercase;
559
+ }
560
+
561
+ .table-designer-sidebar__empty,
562
+ .table-designer-preview__empty,
563
+ .table-designer-main__empty {
564
+ align-items: center;
565
+ color: rgba(205, 199, 171, 0.55);
566
+ display: flex;
567
+ flex-direction: column;
568
+ justify-content: center;
569
+ min-height: 180px;
570
+ padding: var(--spacing-6);
571
+ text-align: center;
572
+ }
573
+
574
+ .table-designer-main__empty {
575
+ background: var(--color-surface-low);
576
+ }
577
+
578
+ .table-designer-main__empty-title {
579
+ color: var(--color-primary-container);
580
+ font-family: var(--font-family-headline);
581
+ font-size: 1.2rem;
582
+ font-weight: 700;
583
+ letter-spacing: -0.04em;
584
+ }
585
+
586
+ .table-designer-main__empty-text {
587
+ margin-top: var(--spacing-3);
588
+ max-width: 30rem;
589
+ }
590
+
591
+ .table-designer-main,
592
+ .table-designer-preview {
593
+ display: flex;
594
+ flex-direction: column;
595
+ height: 100%;
596
+ min-height: 0;
597
+ }
598
+
599
+ .table-designer-main__header,
600
+ .table-designer-preview__header {
601
+ align-items: center;
602
+ border-bottom: 1px solid rgba(75, 71, 50, 0.16);
321
603
  display: flex;
322
- }
604
+ flex-wrap: wrap;
605
+ gap: var(--spacing-4);
606
+ justify-content: space-between;
607
+ padding: var(--spacing-5);
608
+ }
609
+
610
+ .table-designer-main__title-row {
611
+ align-items: center;
612
+ display: flex;
613
+ flex-wrap: wrap;
614
+ gap: var(--spacing-3);
615
+ margin-top: var(--spacing-2);
616
+ }
617
+
618
+ .table-designer-main__name {
619
+ background: transparent !important;
620
+ border: none;
621
+ color: var(--color-primary-container);
622
+ font-family: var(--font-family-headline);
623
+ font-size: 2rem;
624
+ font-weight: 900;
625
+ letter-spacing: -0.06em;
626
+ min-width: min(28rem, 100%);
627
+ padding: 0;
628
+ }
629
+
630
+ .table-designer-main__actions {
631
+ align-items: center;
632
+ display: flex;
633
+ flex-wrap: wrap;
634
+ gap: var(--spacing-3);
635
+ }
636
+
637
+ .table-designer-fill-toggle {
638
+ align-items: center;
639
+ border: 1px solid rgba(75, 71, 50, 0.18);
640
+ color: var(--color-on-surface);
641
+ display: inline-flex;
642
+ gap: 0.75rem;
643
+ min-height: 42px;
644
+ padding: 0 0.875rem;
645
+ }
646
+
647
+ .table-designer-fill-toggle input {
648
+ accent-color: var(--color-primary-container);
649
+ }
650
+
651
+ .table-designer-fill-toggle.is-disabled {
652
+ color: rgba(229, 226, 225, 0.45);
653
+ }
654
+
655
+ .table-designer-fill-toggle__meta {
656
+ color: rgba(205, 199, 171, 0.52);
657
+ font-family: var(--font-family-mono);
658
+ font-size: var(--font-size-status);
659
+ letter-spacing: 0.1em;
660
+ text-transform: uppercase;
661
+ }
662
+
663
+ .table-designer-main__error,
664
+ .table-designer-route-error {
665
+ background: rgba(147, 0, 10, 0.16);
666
+ border: 1px solid rgba(255, 180, 171, 0.16);
667
+ color: var(--color-on-surface);
668
+ margin: var(--spacing-4);
669
+ padding: var(--spacing-4);
670
+ }
671
+
672
+ .table-designer-route-error {
673
+ margin: 0;
674
+ }
675
+
676
+ .table-designer-main__error-code,
677
+ .table-designer-route-error__code {
678
+ color: var(--color-error);
679
+ font-family: var(--font-family-mono);
680
+ font-size: var(--font-size-status);
681
+ letter-spacing: 0.16em;
682
+ text-transform: uppercase;
683
+ }
684
+
685
+ .table-designer-main__error-text,
686
+ .table-designer-route-error__text {
687
+ margin-top: var(--spacing-2);
688
+ }
689
+
690
+ .table-designer-banner {
691
+ border: 1px solid rgba(75, 71, 50, 0.16);
692
+ margin: 0 var(--spacing-4) var(--spacing-4);
693
+ padding: var(--spacing-4);
694
+ }
695
+
696
+ .table-designer-banner.is-warning {
697
+ background: rgba(252, 227, 0, 0.06);
698
+ }
699
+
700
+ .table-designer-banner.is-validation {
701
+ background: rgba(147, 0, 10, 0.12);
702
+ }
703
+
704
+ .table-designer-banner__header {
705
+ align-items: center;
706
+ display: flex;
707
+ gap: var(--spacing-3);
708
+ justify-content: space-between;
709
+ }
710
+
711
+ .table-designer-banner__title {
712
+ color: var(--color-on-surface);
713
+ font-family: var(--font-family-headline);
714
+ font-size: 0.95rem;
715
+ font-weight: 700;
716
+ }
717
+
718
+ .table-designer-banner__list {
719
+ display: flex;
720
+ flex-direction: column;
721
+ gap: var(--spacing-3);
722
+ margin-top: var(--spacing-3);
723
+ }
724
+
725
+ .table-designer-banner__item-title {
726
+ color: var(--color-on-surface);
727
+ font-size: 0.875rem;
728
+ font-weight: 600;
729
+ }
730
+
731
+ .table-designer-banner__item-text {
732
+ color: rgba(229, 226, 225, 0.68);
733
+ font-size: 0.8125rem;
734
+ margin-top: var(--spacing-1);
735
+ }
736
+
737
+ .table-designer-main__section {
738
+ display: flex;
739
+ flex: 1;
740
+ flex-direction: column;
741
+ min-height: 0;
742
+ padding: 0 var(--spacing-4) var(--spacing-4);
743
+ }
744
+
745
+ .table-designer-main__section-header {
746
+ align-items: flex-start;
747
+ display: flex;
748
+ flex-wrap: wrap;
749
+ gap: var(--spacing-4);
750
+ justify-content: space-between;
751
+ padding: var(--spacing-2) 0 var(--spacing-4);
752
+ }
753
+
754
+ .table-designer-grid {
755
+ background: var(--color-surface-container-lowest);
756
+ border: 1px solid rgba(75, 71, 50, 0.14);
757
+ flex: 1;
758
+ min-height: 0;
759
+ overflow: auto;
760
+ }
761
+
762
+ .table-designer-grid__header,
763
+ .table-designer-grid__row {
764
+ display: grid;
765
+ gap: var(--spacing-2);
766
+ grid-template-columns:
767
+ minmax(12rem, 1.5fr)
768
+ minmax(8rem, 0.9fr)
769
+ minmax(5.5rem, 0.7fr)
770
+ minmax(5.5rem, 0.7fr)
771
+ minmax(6rem, 0.7fr)
772
+ minmax(10rem, 1fr)
773
+ minmax(10rem, 1fr)
774
+ minmax(10rem, 1fr)
775
+ 44px;
776
+ min-width: 76rem;
777
+ padding: var(--spacing-3);
778
+ }
779
+
780
+ .table-designer-grid__header {
781
+ border-bottom: 1px solid rgba(75, 71, 50, 0.16);
782
+ color: rgba(205, 199, 171, 0.52);
783
+ font-family: var(--font-family-mono);
784
+ font-size: var(--font-size-status);
785
+ letter-spacing: 0.12em;
786
+ position: sticky;
787
+ text-transform: uppercase;
788
+ top: 0;
789
+ background: var(--color-surface-low);
790
+ z-index: 2;
791
+ }
792
+
793
+ .table-designer-grid__row {
794
+ border-bottom: 1px solid rgba(75, 71, 50, 0.1);
795
+ align-items: center;
796
+ }
797
+
798
+ .table-designer-field {
799
+ min-height: 42px;
800
+ padding: 0 0.75rem;
801
+ }
802
+
803
+ .table-designer-check {
804
+ align-items: center;
805
+ color: rgba(229, 226, 225, 0.75);
806
+ display: inline-flex;
807
+ font-size: 0.75rem;
808
+ gap: 0.5rem;
809
+ min-height: 42px;
810
+ }
811
+
812
+ .table-designer-check input {
813
+ accent-color: var(--color-primary-container);
814
+ }
815
+
816
+ .table-designer-delete {
817
+ align-items: center;
818
+ background: transparent;
819
+ border: 1px solid rgba(75, 71, 50, 0.18);
820
+ color: rgba(229, 226, 225, 0.65);
821
+ display: inline-flex;
822
+ height: 42px;
823
+ justify-content: center;
824
+ transition:
825
+ border-color var(--transition-fast),
826
+ color var(--transition-fast),
827
+ background-color var(--transition-fast);
828
+ width: 42px;
829
+ }
830
+
831
+ .table-designer-delete:hover {
832
+ background: rgba(147, 0, 10, 0.18);
833
+ border-color: rgba(255, 180, 171, 0.2);
834
+ color: var(--color-error);
835
+ }
836
+
837
+ .table-designer-preview__body {
838
+ color: var(--color-on-surface);
839
+ flex: 1;
840
+ font-family: var(--font-family-mono);
841
+ font-size: 0.8125rem;
842
+ line-height: 1.7;
843
+ margin: 0;
844
+ min-height: 0;
845
+ overflow: auto;
846
+ padding: var(--spacing-5);
847
+ white-space: pre-wrap;
848
+ }
849
+
850
+ @media (max-width: 1023px) {
851
+ .table-designer-sidebar {
852
+ border-bottom: 1px solid rgba(75, 71, 50, 0.18);
853
+ border-right: none;
854
+ flex-basis: auto;
855
+ }
856
+ }
857
+
858
+ .query-history-item {
859
+ align-items: stretch;
860
+ background: var(--color-surface-low);
861
+ border: 1px solid rgba(75, 71, 50, 0.16);
862
+ border-left: 2px solid transparent;
863
+ display: flex;
864
+ flex-direction: column;
865
+ min-width: 0;
866
+ transition:
867
+ background-color var(--transition-fast),
868
+ border-color var(--transition-fast),
869
+ box-shadow var(--transition-fast);
870
+ }
871
+
872
+ .query-history-item:hover {
873
+ background: var(--color-surface-high);
874
+ border-color: rgba(252, 227, 0, 0.18);
875
+ }
876
+
877
+ .query-history-item.is-active {
878
+ border-left-color: var(--color-primary-container);
879
+ box-shadow: 0 0 24px rgba(252, 227, 0, 0.06);
880
+ }
881
+
882
+ .query-history-item.is-error {
883
+ border-left-color: var(--color-error);
884
+ }
885
+
886
+ .query-history-item-hit {
887
+ background: transparent;
888
+ border: 0;
889
+ color: inherit;
890
+ display: block;
891
+ min-width: 0;
892
+ padding: var(--spacing-3);
893
+ text-align: left;
894
+ transition: background-color var(--transition-fast);
895
+ }
896
+
897
+ .query-history-item-hit.is-active {
898
+ background: rgba(252, 227, 0, 0.08);
899
+ }
900
+
901
+ .query-history-icon-button {
902
+ align-items: center;
903
+ background: transparent;
904
+ border: 0;
905
+ color: rgba(229, 226, 225, 0.6);
906
+ display: inline-flex;
907
+ height: 2rem;
908
+ justify-content: center;
909
+ transition:
910
+ color var(--transition-fast),
911
+ background-color var(--transition-fast);
912
+ width: 2rem;
913
+ }
914
+
915
+ .query-history-icon-button:hover,
916
+ .query-history-icon-button.is-active {
917
+ background: var(--color-surface-highest);
918
+ color: var(--color-primary-container);
919
+ }
920
+
921
+ .query-history-tab {
922
+ background: transparent;
923
+ border: 0;
924
+ border-bottom: 1px solid transparent;
925
+ color: rgba(205, 199, 171, 0.45);
926
+ font-family: var(--font-family-mono);
927
+ font-size: var(--font-size-status);
928
+ letter-spacing: 0.16em;
929
+ padding: 0.35rem 0;
930
+ text-transform: uppercase;
931
+ transition:
932
+ border-color var(--transition-fast),
933
+ color var(--transition-fast);
934
+ }
935
+
936
+ .query-history-tab.is-active {
937
+ border-color: var(--color-primary-container);
938
+ color: var(--color-primary-container);
939
+ }
940
+
941
+ .query-history-sql-preview {
942
+ display: -webkit-box;
943
+ -webkit-box-orient: vertical;
944
+ -webkit-line-clamp: 2;
945
+ overflow: hidden;
946
+ }
947
+
948
+ .query-history-detail-sql {
949
+ max-height: 240px;
950
+ white-space: pre-wrap;
951
+ }
952
+
953
+ @media (max-width: 1279px) {
954
+ .query-history-panel {
955
+ border-left: 0;
956
+ border-top: 1px solid rgba(75, 71, 50, 0.16);
957
+ flex: 0 0 auto;
958
+ width: 100%;
959
+ }
960
+ }
961
+
962
+ @media (min-width: 768px) {
963
+ .top-nav-links {
964
+ display: flex;
965
+ }
966
+ }
967
+
968
+ .data-headline-container {
969
+ max-width: 69%;
970
+ }
971
+
972
+ .data-headline-container h1 {
973
+ overflow: hidden;
974
+ white-space: nowrap;
975
+ text-overflow: ellipsis;
323
976
  }