@skygraph/styles 0.0.0-placeholder.0 → 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 (75) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +92 -6
  3. package/components/autocomplete.css +33 -0
  4. package/components/avatar.css +37 -0
  5. package/components/badge.css +102 -0
  6. package/components/breadcrumb.css +29 -0
  7. package/components/button.css +181 -0
  8. package/components/calendar.css +408 -0
  9. package/components/carousel.css +102 -0
  10. package/components/cascader.css +354 -0
  11. package/components/charts.css +408 -0
  12. package/components/checkbox.css +114 -0
  13. package/components/collapse.css +166 -0
  14. package/components/colorpicker.css +252 -0
  15. package/components/context-menu.css +95 -0
  16. package/components/dashboard.css +299 -0
  17. package/components/datagrid.css +86 -0
  18. package/components/datepicker.css +601 -0
  19. package/components/descriptions.css +82 -0
  20. package/components/diagram.css +435 -0
  21. package/components/drawer.css +103 -0
  22. package/components/dropdown.css +93 -0
  23. package/components/empty.css +25 -0
  24. package/components/event-timeline.css +100 -0
  25. package/components/field.css +35 -0
  26. package/components/form.css +115 -0
  27. package/components/gantt.css +166 -0
  28. package/components/inline-edit.css +113 -0
  29. package/components/input-group.css +79 -0
  30. package/components/input-number.css +76 -0
  31. package/components/input-password.css +104 -0
  32. package/components/input.css +185 -0
  33. package/components/list.css +357 -0
  34. package/components/mentions.css +54 -0
  35. package/components/menu.css +309 -0
  36. package/components/modal.css +77 -0
  37. package/components/notification.css +128 -0
  38. package/components/pagination.css +162 -0
  39. package/components/pin-input.css +71 -0
  40. package/components/popconfirm.css +95 -0
  41. package/components/progress.css +116 -0
  42. package/components/radio.css +95 -0
  43. package/components/rate.css +34 -0
  44. package/components/resource-calendar.css +224 -0
  45. package/components/result.css +45 -0
  46. package/components/schema-form-editor.css +433 -0
  47. package/components/search-input.css +112 -0
  48. package/components/segmented.css +76 -0
  49. package/components/select.css +172 -0
  50. package/components/skeleton.css +68 -0
  51. package/components/slider.css +51 -0
  52. package/components/spin.css +86 -0
  53. package/components/steps.css +185 -0
  54. package/components/switch.css +75 -0
  55. package/components/table.css +1023 -0
  56. package/components/tabs.css +117 -0
  57. package/components/tag-input.css +94 -0
  58. package/components/tag.css +61 -0
  59. package/components/textarea.css +22 -0
  60. package/components/timeline.css +169 -0
  61. package/components/timepicker.css +213 -0
  62. package/components/tooltip.css +91 -0
  63. package/components/transfer.css +140 -0
  64. package/components/tree.css +574 -0
  65. package/components/treeselect.css +219 -0
  66. package/components/upload.css +124 -0
  67. package/index.css +69 -3
  68. package/index.d.ts +9 -0
  69. package/package.json +102 -18
  70. package/print.css +88 -0
  71. package/reset.css +17 -0
  72. package/themes/dark.css +17 -0
  73. package/themes/default.css +14 -0
  74. package/tokens.css +312 -0
  75. package/transitions.css +158 -0
@@ -0,0 +1,82 @@
1
+ .sg-descriptions {
2
+ font-size: var(--sg-font-size);
3
+ color: var(--sg-color-text);
4
+ width: 100%;
5
+ }
6
+
7
+ .sg-descriptions-title {
8
+ font-size: var(--sg-font-size-lg);
9
+ font-weight: 600;
10
+ color: var(--sg-color-text);
11
+ margin-bottom: var(--sg-margin-md);
12
+ line-height: var(--sg-line-height);
13
+ }
14
+
15
+ .sg-descriptions-table {
16
+ width: 100%;
17
+ border-collapse: collapse;
18
+ table-layout: auto;
19
+ }
20
+
21
+ .sg-descriptions-row {
22
+ vertical-align: top;
23
+ }
24
+
25
+ .sg-descriptions-item-label {
26
+ font-weight: 500;
27
+ color: var(--sg-color-text-secondary);
28
+ white-space: nowrap;
29
+ text-align: left;
30
+ padding: var(--sg-padding-sm) var(--sg-padding-md) var(--sg-padding-sm) 0;
31
+ line-height: var(--sg-line-height);
32
+ }
33
+
34
+ .sg-descriptions-item-content {
35
+ color: var(--sg-color-text);
36
+ padding: var(--sg-padding-sm) var(--sg-padding-md) var(--sg-padding-sm) 0;
37
+ line-height: var(--sg-line-height);
38
+ word-break: break-word;
39
+ }
40
+
41
+ .sg-descriptions-colon {
42
+ margin-right: var(--sg-margin-sm);
43
+ }
44
+
45
+ /* Bordered */
46
+ .sg-descriptions-bordered .sg-descriptions-table {
47
+ border: 1px solid var(--sg-color-border-secondary);
48
+ border-radius: var(--sg-border-radius);
49
+ }
50
+
51
+ .sg-descriptions-bordered .sg-descriptions-item-label,
52
+ .sg-descriptions-bordered .sg-descriptions-item-content {
53
+ padding: var(--sg-padding-sm) var(--sg-padding-lg);
54
+ border-bottom: 1px solid var(--sg-color-border-secondary);
55
+ }
56
+
57
+ .sg-descriptions-bordered .sg-descriptions-item-label {
58
+ background: var(--sg-color-bg-secondary);
59
+ border-right: 1px solid var(--sg-color-border-secondary);
60
+ }
61
+
62
+ .sg-descriptions-bordered .sg-descriptions-row:last-child .sg-descriptions-item-label,
63
+ .sg-descriptions-bordered .sg-descriptions-row:last-child .sg-descriptions-item-content {
64
+ border-bottom: none;
65
+ }
66
+
67
+ /* Sizes */
68
+ .sg-descriptions-small .sg-descriptions-item-label,
69
+ .sg-descriptions-small .sg-descriptions-item-content {
70
+ padding: var(--sg-padding-xs) var(--sg-padding-sm) var(--sg-padding-xs) 0;
71
+ font-size: var(--sg-font-size-sm);
72
+ }
73
+
74
+ .sg-descriptions-small.sg-descriptions-bordered .sg-descriptions-item-label,
75
+ .sg-descriptions-small.sg-descriptions-bordered .sg-descriptions-item-content {
76
+ padding: var(--sg-padding-xs) var(--sg-padding-md);
77
+ }
78
+
79
+ .sg-descriptions-middle .sg-descriptions-item-label,
80
+ .sg-descriptions-middle .sg-descriptions-item-content {
81
+ padding: var(--sg-padding-sm) var(--sg-padding-md) var(--sg-padding-sm) 0;
82
+ }
@@ -0,0 +1,435 @@
1
+ /* Diagram — visual layer for GraphEngine.
2
+ *
3
+ * All chrome (canvas, grid, nodes, edges, lasso, hover toolbar) goes
4
+ * through `--sg-diagram-*` semantic tokens defined in `tokens.css`. Dark
5
+ * theme overrides those tokens, so every visual surface here re-themes
6
+ * automatically without per-rule duplication.
7
+ *
8
+ * Hover / selected / dragging states use existing `data-*` attributes
9
+ * emitted by `Diagram.tsx` (`data-selected`, `data-sg-dragging`,
10
+ * `data-selection-mode`). No new class names are introduced — the visual
11
+ * polish lives entirely in this file.
12
+ */
13
+
14
+ .sg-diagram {
15
+ /*
16
+ * Component-local CSS variables. `<Diagram>` overrides `--sg-grid-size`
17
+ * via inline-style (`style={{ '--sg-grid-size': '20px' }}`) when
18
+ * snap-to-grid is active so the background pattern stays in sync with
19
+ * the snap step (and the current zoom). Defaults are declared here so
20
+ * `var()` always resolves to a real value — required by `check:tokens`.
21
+ */
22
+ --sg-grid-size: 20px;
23
+
24
+ /* Local aliases that delegate to the new semantic tokens. They keep
25
+ * back-compat for any consumer who pinned to the old name and let
26
+ * us redirect the visual treatment globally by overriding the
27
+ * semantic token only. */
28
+ --sg-diagram-shadow-md: var(--sg-diagram-node-shadow-hover);
29
+ --sg-diagram-edge-hover-stroke: var(--sg-diagram-edge-color-hover);
30
+ --sg-diagram-selected-ring: var(--sg-diagram-edge-color-selected);
31
+ --sg-diagram-lasso-bg: var(--sg-diagram-lasso-fill);
32
+ --sg-diagram-lasso-border: var(--sg-diagram-lasso-stroke);
33
+
34
+ position: relative;
35
+ background-color: var(--sg-diagram-canvas-bg);
36
+ /* Subtle dot-pattern that gives the empty canvas a sense of "infinite
37
+ * surface" without the noise of full grid lines. The strong-color dot
38
+ * sits at every 32px; combined with the grid overlay (`.sg-diagram-grid`)
39
+ * this creates a clean two-tier rhythm. We use radial-gradients so the
40
+ * pattern stays pin-sharp at any zoom and never bleeds onto nodes
41
+ * (nodes have their own opaque background). */
42
+ background-image: radial-gradient(
43
+ circle at 1px 1px,
44
+ var(--sg-diagram-grid-line-color) 1px,
45
+ transparent 1.5px
46
+ );
47
+ background-size: 20px 20px;
48
+ border: 1px solid var(--sg-color-border);
49
+ border-radius: var(--sg-border-radius);
50
+ /* Make selection feedback feel snappy but not jarring on dense graphs. */
51
+ transition: border-color var(--sg-transition-medium);
52
+ }
53
+
54
+ .sg-diagram:focus-within {
55
+ border-color: var(--sg-color-primary);
56
+ }
57
+
58
+ /* While the user is mid-lasso, hint that a multi-select is in progress
59
+ * by lifting the canvas border to the primary color. */
60
+ .sg-diagram[data-selection-mode='lasso']:hover {
61
+ cursor: crosshair;
62
+ }
63
+
64
+ /* Suppress native scroll/pinch when lasso selection is active — the
65
+ * wrapper owns those gestures via Pointer Events. Single-selection
66
+ * canvases keep native scroll behaviour because they don't intercept
67
+ * empty-canvas drags. */
68
+ .sg-diagram[data-selection-mode='lasso'],
69
+ .sg-diagram[data-selection-mode='multi'] {
70
+ touch-action: none;
71
+ }
72
+
73
+ /* When the canvas accepts DnD drops (palette → canvas) and the user is
74
+ * mid-drag, highlight the border so the drop target is obvious. The
75
+ * `data-sg-drop="true"` attribute is set by `<Diagram>` whenever an
76
+ * `onDropNode` / `@drop-node` listener is attached.
77
+ *
78
+ * The wide outline uses the primary-token so dark mode inverts
79
+ * automatically. */
80
+ .sg-diagram[data-sg-drop='true'] {
81
+ /* nothing extra in the rest state — keep the diagram looking calm */
82
+ }
83
+
84
+ .sg-diagram[data-sg-drop='true'].sg-diagram-drag-over,
85
+ .sg-diagram[data-sg-drop='true']:has(.sg-diagram-drag-indicator) {
86
+ /* Reserved for future preview / drop indicator. */
87
+ }
88
+
89
+ /* Snap-to-grid hook — applied when `<Diagram snapToGrid={N}>` is set.
90
+ * The two-line gradient overlays the dot-pattern from `.sg-diagram` to
91
+ * give a proper grid reading. The strong color is used for "every Nth"
92
+ * line by relying on the larger background-size on the wrapper. */
93
+ .sg-diagram-grid {
94
+ background-image:
95
+ linear-gradient(to right, var(--sg-diagram-grid-line-color-strong) 1px, transparent 1px),
96
+ linear-gradient(to bottom, var(--sg-diagram-grid-line-color-strong) 1px, transparent 1px),
97
+ radial-gradient(circle at 1px 1px, var(--sg-diagram-grid-line-color) 1px, transparent 1.5px);
98
+ background-size:
99
+ var(--sg-grid-size) var(--sg-grid-size),
100
+ var(--sg-grid-size) var(--sg-grid-size),
101
+ calc(var(--sg-grid-size) / 2) calc(var(--sg-grid-size) / 2);
102
+ }
103
+
104
+ .sg-diagram-canvas {
105
+ /* Inner transform host — `<Diagram>` writes translate/scale here so
106
+ * pan + zoom are applied to nodes and edges as one unit. */
107
+ transform-origin: 0 0;
108
+ }
109
+
110
+ /* ─── Nodes ──────────────────────────────────────────────────────────── */
111
+
112
+ .sg-diagram-node {
113
+ background: var(--sg-color-bg-elevated);
114
+ border: 1px solid var(--sg-color-border);
115
+ border-radius: var(--sg-border-radius);
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ font-size: var(--sg-font-size);
120
+ color: var(--sg-color-text);
121
+ box-shadow: var(--sg-diagram-node-shadow);
122
+ user-select: none;
123
+ /* `touch-action: none` is essential for Pointer Events + touch: it
124
+ * tells the browser to suppress the default scroll / pinch-zoom
125
+ * gesture on this element so our drag handler keeps receiving
126
+ * `pointermove` events past the first ~10 px. Without it touchscreens
127
+ * eat the drag the moment they decide it "looks like" a scroll. */
128
+ touch-action: none;
129
+ /* `transform` is animated for the dragging-lift effect; keep the
130
+ * box-shadow + border-color transitions in lock-step so the change
131
+ * feels like a single response rather than three discrete swaps. */
132
+ transition:
133
+ box-shadow var(--sg-transition-medium),
134
+ transform var(--sg-transition-medium),
135
+ border-color var(--sg-transition-medium);
136
+ }
137
+
138
+ .sg-diagram-node:hover {
139
+ border-color: var(--sg-color-text-secondary);
140
+ box-shadow: var(--sg-diagram-node-shadow-hover);
141
+ /* Tiny lift to convey interactivity without jumping the layout. */
142
+ transform: translateY(-1px);
143
+ }
144
+
145
+ .sg-diagram-node[data-sg-dragging='true'] {
146
+ box-shadow: var(--sg-diagram-node-shadow-dragging);
147
+ cursor: grabbing;
148
+ /* Pop further out of the canvas while moving. Combined with the
149
+ * heavier shadow this reads as "this node is now floating above
150
+ * the rest". */
151
+ transform: scale(1.04) translateY(-2px);
152
+ border-color: var(--sg-color-primary);
153
+ }
154
+
155
+ .sg-diagram-node-selected,
156
+ .sg-diagram-node[data-selected='true'] {
157
+ border-color: var(--sg-diagram-selected-ring);
158
+ box-shadow: var(--sg-diagram-node-shadow-selected);
159
+ }
160
+
161
+ /* When a selected node is also being dragged, the dragging shadow wins
162
+ * (deeper elevation), but we keep the primary border so the selection
163
+ * is still legible on the moving copy. */
164
+ .sg-diagram-node-selected[data-sg-dragging='true'],
165
+ .sg-diagram-node[data-selected='true'][data-sg-dragging='true'] {
166
+ box-shadow: var(--sg-diagram-node-shadow-dragging);
167
+ border-color: var(--sg-color-primary);
168
+ }
169
+
170
+ .sg-diagram-node-rect {
171
+ /* default; nothing extra */
172
+ }
173
+
174
+ .sg-diagram-node-ellipse {
175
+ border-radius: 50%;
176
+ }
177
+
178
+ .sg-diagram-node-polygon,
179
+ .sg-diagram-node-path {
180
+ /* For non-rect outlines the bbox-sized DIV is just a label container — the
181
+ * actual shape lives in the SVG overlay (or a custom renderer). */
182
+ background: transparent;
183
+ border: 1px dashed var(--sg-color-border);
184
+ box-shadow: none;
185
+ }
186
+
187
+ .sg-diagram-node-polygon:hover,
188
+ .sg-diagram-node-path:hover {
189
+ /* The label container is purely decorative for non-rect shapes; the
190
+ * lift effect from the base rule would clip against the underlying
191
+ * SVG, so we suppress it. */
192
+ transform: none;
193
+ box-shadow: none;
194
+ border-color: var(--sg-color-text-secondary);
195
+ }
196
+
197
+ .sg-diagram-node-label {
198
+ padding: 0 var(--sg-padding-md);
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ }
203
+
204
+ .sg-diagram-node-draggable {
205
+ /* legacy hook kept for tests + back-compat — visual transitions live on
206
+ * `.sg-diagram-node` itself now so they apply equally to non-draggable
207
+ * nodes that still get hover / selected feedback. */
208
+ }
209
+
210
+ .sg-diagram-node-draggable:active {
211
+ cursor: grabbing;
212
+ }
213
+
214
+ /* ─── Edges ──────────────────────────────────────────────────────────── */
215
+
216
+ .sg-diagram-edges {
217
+ /* sits behind nodes; per-edge groups override pointer-events when
218
+ * interactivity is enabled. */
219
+ }
220
+
221
+ .sg-diagram-edge {
222
+ stroke: var(--sg-diagram-edge-color);
223
+ stroke-width: 1.5;
224
+ fill: none;
225
+ /* `linejoin: round` smooths orthogonal corners. `linecap: butt`
226
+ * means the path tip ends flush — combined with the marker-end
227
+ * sitting at `refX/refY = 0`, the arrow glyph picks up exactly
228
+ * where the line stops, with no visible "pill" cap protruding
229
+ * beyond the arrowhead. Round caps used to leak a half-circle
230
+ * over the marker base and that was visible on every screenshot
231
+ * the user shared. */
232
+ stroke-linejoin: round;
233
+ stroke-linecap: butt;
234
+ transition:
235
+ stroke var(--sg-transition-fast),
236
+ stroke-width var(--sg-transition-fast);
237
+ }
238
+
239
+ /* Bezier edges read better with a touch more weight — the curve
240
+ * naturally thins at the inflection point, which makes the same
241
+ * stroke-width look lighter than its orthogonal counterpart. */
242
+ .sg-diagram-edge-bezier {
243
+ stroke-width: 1.75;
244
+ }
245
+
246
+ /* Dashed for manual-routed waypoints — visually distinguishes a hand-
247
+ * drawn polyline from auto-routed ones. */
248
+ .sg-diagram-edge-manual {
249
+ stroke-dasharray: 6 4;
250
+ }
251
+
252
+ .sg-diagram-edge-hit:hover + .sg-diagram-edge,
253
+ g[data-edge-id]:hover .sg-diagram-edge {
254
+ stroke: var(--sg-diagram-edge-hover-stroke);
255
+ stroke-width: 2.25;
256
+ }
257
+
258
+ /* Highlight edges connected to a selected node when the selection is
259
+ * driven via the data-attr API. The DOM doesn't tag edges by selection
260
+ * (they're SVG paths), so this is best-effort: we emphasise the
261
+ * `selected` color on `:focus-within` of the SVG group. */
262
+ g[data-edge-id]:focus-within .sg-diagram-edge {
263
+ stroke: var(--sg-diagram-edge-color-selected);
264
+ stroke-width: 2.25;
265
+ }
266
+
267
+ /* ─── Arrow markers ─────────────────────────────────────────────────── */
268
+ /*
269
+ * The arrowhead is an "open V" — two strokes meeting at the marker
270
+ * anchor, not a filled triangle. That gives the arrow visual cohesion
271
+ * with the line (same stroke), keeps it readable on dense graphs, and
272
+ * matches the look used by React Flow / draw.io / Lucidchart.
273
+ *
274
+ * SVG markers don't inherit `stroke` from the path automatically. We
275
+ * use `context-stroke` in the marker so modern browsers paint the arrow
276
+ * with the line colour, and rely on `currentColor` below as a fallback
277
+ * for Firefox / Safari versions that don't yet support context-stroke.
278
+ *
279
+ * `.sg-diagram-edges { color: ... }` is the lever per-edge state hooks
280
+ * (`:hover`) modulate so the arrow lights up together with the line.
281
+ */
282
+ .sg-diagram-edges {
283
+ color: var(--sg-diagram-edge-color);
284
+ }
285
+
286
+ /* Marker glyph: stroke takes the inherited `currentColor` so old
287
+ * browsers without context-stroke still render the arrow in the right
288
+ * colour. `fill: none` is essential — the marker is an open polyline,
289
+ * not a triangle. */
290
+ .sg-diagram-arrow-fill {
291
+ stroke: currentColor;
292
+ fill: none;
293
+ }
294
+
295
+ g[data-edge-id]:hover {
296
+ color: var(--sg-diagram-edge-hover-stroke);
297
+ }
298
+
299
+ /* ─── Hover mini-toolbar ─────────────────────────────────────────────── */
300
+
301
+ .sg-diagram-hover-actions {
302
+ display: inline-flex;
303
+ align-items: center;
304
+ gap: var(--sg-padding-sm);
305
+ padding: var(--sg-padding-xs) var(--sg-padding-sm);
306
+ background: var(--sg-color-bg-elevated);
307
+ border: 1px solid var(--sg-color-border);
308
+ border-radius: var(--sg-border-radius);
309
+ box-shadow: var(--sg-shadow-lg);
310
+ font-size: var(--sg-font-size-sm);
311
+ white-space: nowrap;
312
+ /* Smooth opacity-in via the parent toolkit; transition lives here so
313
+ * appearance stays consistent across NodeHoverActions / EdgeHoverActions. */
314
+ transition: box-shadow var(--sg-transition-medium);
315
+ }
316
+
317
+ .sg-diagram-hover-action {
318
+ display: inline-flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ min-width: 24px;
322
+ height: 24px;
323
+ padding: 0 var(--sg-padding-xs);
324
+ background: transparent;
325
+ border: 1px solid transparent;
326
+ border-radius: var(--sg-border-radius);
327
+ color: var(--sg-color-text);
328
+ font: inherit;
329
+ cursor: pointer;
330
+ transition:
331
+ background var(--sg-transition-fast),
332
+ border-color var(--sg-transition-fast),
333
+ color var(--sg-transition-fast);
334
+ }
335
+
336
+ .sg-diagram-hover-action:hover {
337
+ background: var(--sg-color-bg-hover);
338
+ border-color: var(--sg-color-border);
339
+ }
340
+
341
+ .sg-diagram-hover-action:focus-visible {
342
+ outline: 2px solid var(--sg-color-primary);
343
+ outline-offset: 1px;
344
+ }
345
+
346
+ .sg-diagram-hover-action:active {
347
+ background: var(--sg-color-bg-secondary);
348
+ }
349
+
350
+ /* ─── Palette items (optional consumer hook) ─────────────────────────── */
351
+
352
+ /*
353
+ * `.sg-diagram-palette-item` is a reusable hook for "palette" entries
354
+ * that the consumer can drag onto the canvas (HTML5 DnD). The class is
355
+ * opt-in — `<Diagram>` itself doesn't render the palette, but consumers
356
+ * (`workflow-editor` showcase, etc.) can pick this up so the palette
357
+ * matches the diagram visual rhythm and behaves consistently.
358
+ *
359
+ * Combine with `draggable="true"` and `onDragStart` setting
360
+ * `dataTransfer.setData('application/x-sg-node', ...)` for the canvas
361
+ * to recognise the drop.
362
+ */
363
+ .sg-diagram-palette {
364
+ display: flex;
365
+ flex-direction: column;
366
+ gap: var(--sg-padding-xs);
367
+ }
368
+
369
+ .sg-diagram-palette-item {
370
+ display: flex;
371
+ align-items: center;
372
+ gap: var(--sg-padding-sm);
373
+ width: 100%;
374
+ padding: var(--sg-padding-sm) var(--sg-padding-md);
375
+ border: 1px solid var(--sg-color-border);
376
+ border-radius: var(--sg-border-radius);
377
+ background: var(--sg-color-bg-elevated);
378
+ color: var(--sg-color-text);
379
+ font-size: var(--sg-font-size);
380
+ text-align: left;
381
+ cursor: grab;
382
+ user-select: none;
383
+ transition:
384
+ background var(--sg-transition-fast),
385
+ border-color var(--sg-transition-fast),
386
+ box-shadow var(--sg-transition-fast),
387
+ transform var(--sg-transition-fast);
388
+ }
389
+
390
+ .sg-diagram-palette-item:hover {
391
+ border-color: var(--sg-color-primary);
392
+ background: var(--sg-color-bg-hover);
393
+ box-shadow: var(--sg-diagram-node-shadow-hover);
394
+ transform: translateY(-1px);
395
+ }
396
+
397
+ .sg-diagram-palette-item:active {
398
+ cursor: grabbing;
399
+ transform: scale(0.98);
400
+ }
401
+
402
+ .sg-diagram-palette-item:focus-visible {
403
+ outline: 2px solid var(--sg-color-primary);
404
+ outline-offset: 2px;
405
+ }
406
+
407
+ /* Icon slot inside the palette item (emoji / SVG / character glyph). */
408
+ .sg-diagram-palette-icon {
409
+ display: inline-flex;
410
+ align-items: center;
411
+ justify-content: center;
412
+ min-width: 24px;
413
+ font-size: var(--sg-font-size-lg, 16px);
414
+ color: var(--sg-color-text-secondary);
415
+ }
416
+
417
+ /* ─── Lasso rubber-band ──────────────────────────────────────────────── */
418
+
419
+ .sg-diagram-lasso {
420
+ background: var(--sg-diagram-lasso-bg);
421
+ border: 1px dashed var(--sg-diagram-lasso-border);
422
+ border-radius: 2px;
423
+ /* Backdrop blur on the lasso surface helps pick out which nodes fall
424
+ * inside on dense graphs (the desaturation gives a "cut-out" feel).
425
+ * `backdrop-filter` is gracefully ignored where unsupported — the
426
+ * dashed border + tinted fill remain the source of truth. */
427
+ backdrop-filter: saturate(0.85);
428
+ -webkit-backdrop-filter: saturate(0.85);
429
+ /* Inner glow + outer shadow add weight without hardcoding a colour:
430
+ * both reuse the primary-bg semantic token, so dark theme inverts
431
+ * automatically. */
432
+ box-shadow:
433
+ inset 0 0 0 1px var(--sg-color-primary-bg),
434
+ 0 1px 4px var(--sg-color-primary-bg);
435
+ }
@@ -0,0 +1,103 @@
1
+ .sg-drawer-root {
2
+ position: fixed;
3
+ inset: 0;
4
+ z-index: var(--sg-z-modal);
5
+ }
6
+
7
+ .sg-drawer-mask {
8
+ position: absolute;
9
+ inset: 0;
10
+ background: var(--sg-color-overlay);
11
+ animation: sg-drawer-fade-in var(--sg-transition-duration) var(--sg-transition-timing);
12
+ }
13
+
14
+ @keyframes sg-drawer-fade-in {
15
+ from { opacity: 0; }
16
+ to { opacity: 1; }
17
+ }
18
+
19
+ .sg-drawer {
20
+ position: absolute;
21
+ display: flex;
22
+ flex-direction: column;
23
+ background: var(--sg-color-bg-elevated);
24
+ box-shadow: var(--sg-shadow-lg);
25
+ }
26
+
27
+ .sg-drawer-right {
28
+ top: 0;
29
+ right: 0;
30
+ bottom: 0;
31
+ animation: sg-drawer-slide-right var(--sg-transition-duration) var(--sg-transition-timing);
32
+ }
33
+
34
+ .sg-drawer-left {
35
+ top: 0;
36
+ left: 0;
37
+ bottom: 0;
38
+ animation: sg-drawer-slide-left var(--sg-transition-duration) var(--sg-transition-timing);
39
+ }
40
+
41
+ .sg-drawer-top {
42
+ top: 0;
43
+ left: 0;
44
+ right: 0;
45
+ animation: sg-drawer-slide-top var(--sg-transition-duration) var(--sg-transition-timing);
46
+ }
47
+
48
+ .sg-drawer-bottom {
49
+ bottom: 0;
50
+ left: 0;
51
+ right: 0;
52
+ animation: sg-drawer-slide-bottom var(--sg-transition-duration) var(--sg-transition-timing);
53
+ }
54
+
55
+ @keyframes sg-drawer-slide-right {
56
+ from { transform: translateX(100%); }
57
+ to { transform: translateX(0); }
58
+ }
59
+
60
+ @keyframes sg-drawer-slide-left {
61
+ from { transform: translateX(-100%); }
62
+ to { transform: translateX(0); }
63
+ }
64
+
65
+ @keyframes sg-drawer-slide-top {
66
+ from { transform: translateY(-100%); }
67
+ to { transform: translateY(0); }
68
+ }
69
+
70
+ @keyframes sg-drawer-slide-bottom {
71
+ from { transform: translateY(100%); }
72
+ to { transform: translateY(0); }
73
+ }
74
+
75
+ .sg-drawer-header {
76
+ display: flex;
77
+ align-items: center;
78
+ justify-content: space-between;
79
+ padding: var(--sg-padding-md) var(--sg-padding-xl);
80
+ border-bottom: 1px solid var(--sg-color-border-secondary);
81
+ }
82
+
83
+ .sg-drawer-title {
84
+ font-size: var(--sg-font-size-lg);
85
+ font-weight: 500;
86
+ color: var(--sg-color-text);
87
+ }
88
+
89
+ .sg-drawer-close {
90
+ color: var(--sg-color-text-tertiary);
91
+ font-size: var(--sg-font-size-xl);
92
+ }
93
+
94
+ .sg-drawer-body {
95
+ flex: 1;
96
+ padding: var(--sg-padding-xl);
97
+ overflow: auto;
98
+ }
99
+
100
+ .sg-drawer-footer {
101
+ padding: var(--sg-padding-md) var(--sg-padding-xl);
102
+ border-top: 1px solid var(--sg-color-border-secondary);
103
+ }
@@ -0,0 +1,93 @@
1
+ .sg-dropdown-wrapper {
2
+ position: relative;
3
+ display: inline-block;
4
+ }
5
+
6
+ .sg-dropdown-trigger {
7
+ cursor: pointer;
8
+ }
9
+
10
+ .sg-dropdown {
11
+ position: absolute;
12
+ z-index: var(--sg-z-dropdown);
13
+ min-width: 120px;
14
+ padding: var(--sg-padding-xs) 0;
15
+ background: var(--sg-color-bg-elevated);
16
+ border-radius: var(--sg-border-radius-lg);
17
+ box-shadow: var(--sg-shadow-lg);
18
+ border: 1px solid var(--sg-color-border-secondary);
19
+ animation: sg-dropdown-in var(--sg-transition-duration) var(--sg-transition-timing);
20
+ }
21
+
22
+ @keyframes sg-dropdown-in {
23
+ from { opacity: 0; transform: scaleY(0.8); }
24
+ to { opacity: 1; transform: scaleY(1); }
25
+ }
26
+
27
+ /* Placement variants — both camelCase (legacy, generated as
28
+ * `sg-dropdown-${placement}` from a camelCase prop) and kebab-case (preferred
29
+ * canonical name) are accepted. Keep both selectors in sync. */
30
+ .sg-dropdown-bottomLeft,
31
+ .sg-dropdown-bottom-left {
32
+ top: calc(100% + 4px);
33
+ left: 0;
34
+ transform-origin: top left;
35
+ }
36
+
37
+ .sg-dropdown-bottomRight,
38
+ .sg-dropdown-bottom-right {
39
+ top: calc(100% + 4px);
40
+ right: 0;
41
+ transform-origin: top right;
42
+ }
43
+
44
+ .sg-dropdown-topLeft,
45
+ .sg-dropdown-top-left {
46
+ bottom: calc(100% + 4px);
47
+ left: 0;
48
+ transform-origin: bottom left;
49
+ }
50
+
51
+ .sg-dropdown-topRight,
52
+ .sg-dropdown-top-right {
53
+ bottom: calc(100% + 4px);
54
+ right: 0;
55
+ transform-origin: bottom right;
56
+ }
57
+
58
+ .sg-dropdown-item {
59
+ padding: var(--sg-padding-xs) var(--sg-padding-md);
60
+ font-size: var(--sg-font-size);
61
+ color: var(--sg-color-text);
62
+ cursor: pointer;
63
+ transition: background var(--sg-transition-duration) var(--sg-transition-timing);
64
+ line-height: var(--sg-line-height);
65
+ white-space: nowrap;
66
+ }
67
+
68
+ .sg-dropdown-item:hover {
69
+ background: var(--sg-color-bg-hover);
70
+ }
71
+
72
+ .sg-dropdown-item-disabled {
73
+ color: var(--sg-color-text-disabled);
74
+ cursor: not-allowed;
75
+ }
76
+
77
+ .sg-dropdown-item-disabled:hover {
78
+ background: none;
79
+ }
80
+
81
+ .sg-dropdown-item-danger {
82
+ color: var(--sg-color-error);
83
+ }
84
+
85
+ .sg-dropdown-item-danger:hover {
86
+ background: var(--sg-color-error-bg);
87
+ }
88
+
89
+ .sg-dropdown-divider {
90
+ height: 1px;
91
+ margin: var(--sg-margin-xs) 0;
92
+ background: var(--sg-color-border-secondary);
93
+ }