@skygraph/styles 0.2.3 → 0.6.4

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.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # @skygraph/styles
2
2
 
3
3
  Framework-agnostic CSS for SkyGraph — design tokens, themes, transitions, print
4
- layer and 60+ component stylesheets. Zero JS, no runtime, just CSS Variables.
4
+ layer and per-component stylesheets. Zero JS, no runtime, just CSS Variables.
5
5
 
6
6
  This package is the styling foundation shared by **all** SkyGraph adapters
7
7
  (`@skygraph/react`, future `@skygraph/vue`, `@skygraph/angular`, …). The CSS
@@ -13,7 +13,7 @@
13
13
  top: 100%;
14
14
  left: 0;
15
15
  right: 0;
16
- z-index: 100;
16
+ z-index: var(--sg-z-dropdown);
17
17
  margin-top: 4px;
18
18
  padding: var(--sg-padding-xs) 0;
19
19
  background: var(--sg-color-bg-elevated);
@@ -30,4 +30,6 @@
30
30
  transition: background var(--sg-transition-duration);
31
31
  }
32
32
 
33
- .sg-autocomplete-option:hover { background: var(--sg-color-bg-hover); }
33
+ .sg-autocomplete-option:hover {
34
+ background: var(--sg-color-bg-hover);
35
+ }
@@ -20,8 +20,8 @@
20
20
  justify-content: space-between;
21
21
  /* Shares the `--sg-input-*` family with `Input` so scoped overrides
22
22
  * (height / radius / bg / border) re-skin the trigger. */
23
- min-height: var(--sg-input-height, var(--sg-height-md));
24
- padding: var(--sg-padding-xs) var(--sg-padding-md);
23
+ height: var(--sg-input-height, var(--sg-height-md));
24
+ padding: 0 var(--sg-padding-md);
25
25
  color: var(--sg-input-color, var(--sg-color-text));
26
26
  background: var(--sg-input-bg, var(--sg-color-bg-container));
27
27
  border: 1px solid var(--sg-input-border, var(--sg-color-border));
@@ -32,15 +32,29 @@
32
32
  }
33
33
 
34
34
  .sg-cascader-small .sg-cascader-selector {
35
- min-height: var(--sg-height-sm);
35
+ height: var(--sg-height-sm);
36
36
  font-size: var(--sg-font-size-sm);
37
37
  }
38
38
 
39
39
  .sg-cascader-large .sg-cascader-selector {
40
- min-height: var(--sg-height-lg);
40
+ height: var(--sg-height-lg);
41
41
  font-size: var(--sg-font-size-lg);
42
42
  }
43
43
 
44
+ .sg-cascader-multiple .sg-cascader-selector {
45
+ height: auto;
46
+ min-height: var(--sg-input-height, var(--sg-height-md));
47
+ padding: 2px var(--sg-padding-sm) 2px 4px;
48
+ }
49
+
50
+ .sg-cascader-multiple.sg-cascader-small .sg-cascader-selector {
51
+ min-height: var(--sg-height-sm);
52
+ }
53
+
54
+ .sg-cascader-multiple.sg-cascader-large .sg-cascader-selector {
55
+ min-height: var(--sg-height-lg);
56
+ }
57
+
44
58
  .sg-cascader-open .sg-cascader-selector {
45
59
  border-color: var(--sg-color-primary);
46
60
  box-shadow: 0 0 0 2px var(--sg-color-primary-bg);
@@ -177,7 +191,7 @@
177
191
  position: absolute;
178
192
  top: 100%;
179
193
  left: 0;
180
- z-index: 100;
194
+ z-index: var(--sg-z-dropdown);
181
195
  margin-top: 4px;
182
196
  background: var(--sg-color-bg-elevated);
183
197
  border-radius: var(--sg-border-radius);
@@ -195,12 +195,31 @@
195
195
  min-width: 0;
196
196
  }
197
197
 
198
+ /* Range + presets: absolute dropdown with `width: auto` shrink-fits to the
199
+ * trigger (~320px) and clips the second calendar. Size from content instead. */
200
+ .sg-dp-dropdown-range {
201
+ width: max-content;
202
+ }
203
+
204
+ .sg-dp-dropdown-range .sg-dp-dropdown-inner,
205
+ .sg-dp-dropdown-range .sg-dp-content,
206
+ .sg-dp-dropdown-range .sg-dp-range-panels,
207
+ .sg-dp-dropdown-range .sg-dp-panel {
208
+ flex-shrink: 0;
209
+ min-width: min-content;
210
+ }
211
+
198
212
  /* ── Presets sidebar ── */
199
213
 
200
214
  .sg-dp-presets {
201
215
  border-right: 1px solid var(--sg-color-border-secondary);
202
216
  padding: var(--sg-padding-sm);
203
217
  min-width: 120px;
218
+ /* Size to the widest label instead of being squeezed by the flex row —
219
+ * a squeezed column turns `overflow-y: auto` into a stray horizontal
220
+ * scrollbar. Capped so a long custom label can't blow out the popup. */
221
+ flex: 0 0 auto;
222
+ max-width: 200px;
204
223
  max-height: 320px;
205
224
  overflow-y: auto;
206
225
  }
@@ -211,7 +230,10 @@
211
230
  cursor: pointer;
212
231
  font-size: var(--sg-font-size-sm);
213
232
  color: var(--sg-color-text);
214
- white-space: nowrap;
233
+ /* Wrap long labels onto a second line rather than overflowing the column
234
+ * (which would force a horizontal scrollbar). */
235
+ white-space: normal;
236
+ overflow-wrap: anywhere;
215
237
  transition: background var(--sg-transition-duration);
216
238
  }
217
239
 
@@ -322,6 +344,7 @@ button.sg-dp-panel-title.sg-dp-panel-title-btn:hover {
322
344
  height: 28px;
323
345
  border-radius: 50%;
324
346
  font-size: var(--sg-font-size-sm);
347
+ color: var(--sg-color-text);
325
348
  transition:
326
349
  color var(--sg-transition-duration),
327
350
  background var(--sg-transition-duration),
@@ -577,6 +600,15 @@ button.sg-dp-panel-title.sg-dp-panel-title-btn:hover {
577
600
 
578
601
  .sg-dp-range-panels {
579
602
  display: flex;
603
+ flex-wrap: nowrap;
604
+ }
605
+
606
+ .sg-dp-range-panels .sg-dp-panel {
607
+ flex: 0 0 auto;
608
+ }
609
+
610
+ .sg-dp-range-panels .sg-dp-table {
611
+ width: max-content;
580
612
  }
581
613
 
582
614
  .sg-dp-range-panels .sg-dp-panel + .sg-dp-panel {
@@ -12,8 +12,12 @@
12
12
  }
13
13
 
14
14
  @keyframes sg-drawer-fade-in {
15
- from { opacity: 0; }
16
- to { opacity: 1; }
15
+ from {
16
+ opacity: 0;
17
+ }
18
+ to {
19
+ opacity: 1;
20
+ }
17
21
  }
18
22
 
19
23
  .sg-drawer {
@@ -53,23 +57,39 @@
53
57
  }
54
58
 
55
59
  @keyframes sg-drawer-slide-right {
56
- from { transform: translateX(100%); }
57
- to { transform: translateX(0); }
60
+ from {
61
+ transform: translateX(100%);
62
+ }
63
+ to {
64
+ transform: translateX(0);
65
+ }
58
66
  }
59
67
 
60
68
  @keyframes sg-drawer-slide-left {
61
- from { transform: translateX(-100%); }
62
- to { transform: translateX(0); }
69
+ from {
70
+ transform: translateX(-100%);
71
+ }
72
+ to {
73
+ transform: translateX(0);
74
+ }
63
75
  }
64
76
 
65
77
  @keyframes sg-drawer-slide-top {
66
- from { transform: translateY(-100%); }
67
- to { transform: translateY(0); }
78
+ from {
79
+ transform: translateY(-100%);
80
+ }
81
+ to {
82
+ transform: translateY(0);
83
+ }
68
84
  }
69
85
 
70
86
  @keyframes sg-drawer-slide-bottom {
71
- from { transform: translateY(100%); }
72
- to { transform: translateY(0); }
87
+ from {
88
+ transform: translateY(100%);
89
+ }
90
+ to {
91
+ transform: translateY(0);
92
+ }
73
93
  }
74
94
 
75
95
  .sg-drawer-header {
@@ -94,6 +114,7 @@
94
114
  .sg-drawer-body {
95
115
  flex: 1;
96
116
  padding: var(--sg-padding-xl);
117
+ color: var(--sg-color-text);
97
118
  overflow: auto;
98
119
  }
99
120
 
@@ -15,6 +15,11 @@
15
15
  align-items: flex-start;
16
16
  overflow-x: auto;
17
17
  padding-bottom: var(--sg-padding-md);
18
+ /* Drop the flex gap horizontally: it broke the marker rail into disjoint
19
+ * segments (one per card) which read as a dashed, glitchy line. Items carry
20
+ * their own horizontal padding for spacing instead, and the rail below is
21
+ * extended to bridge that padding so it renders as one continuous track. */
22
+ gap: 0;
18
23
  }
19
24
 
20
25
  .sg-event-timeline-group {
@@ -49,14 +54,43 @@
49
54
  /* Slightly larger dot + brighter halo when the parent item is hovered.
50
55
  * Both are driven by the new `--sg-event-timeline-dot-shadow-hover`
51
56
  * token so the affordance remains theme-correct. */
52
- transform: scale(1.20);
57
+ transform: scale(1.2);
53
58
  box-shadow: var(--sg-event-timeline-dot-shadow-hover);
54
59
  }
55
60
 
56
61
  .sg-event-timeline-horizontal .sg-event-timeline-item {
57
62
  flex-direction: column;
63
+ align-items: flex-start;
58
64
  min-width: 160px;
59
65
  padding: 0 var(--sg-padding-md);
66
+ position: relative;
67
+ }
68
+
69
+ /* Horizontal mode: lay the marker out as a full-width rail so the dots line up
70
+ * on a single track instead of floating above each card. */
71
+ .sg-event-timeline-horizontal .sg-event-timeline-marker {
72
+ width: 100%;
73
+ justify-content: flex-start;
74
+ margin-bottom: var(--sg-margin-sm);
75
+ position: relative;
76
+ }
77
+
78
+ .sg-event-timeline-horizontal .sg-event-timeline-marker::before {
79
+ content: '';
80
+ position: absolute;
81
+ top: 50%;
82
+ /* Extend across the item's own horizontal padding so adjacent items'
83
+ * rails meet edge-to-edge into one continuous line. */
84
+ left: calc(-1 * var(--sg-padding-md));
85
+ right: calc(-1 * var(--sg-padding-md));
86
+ height: 2px;
87
+ background: var(--sg-color-border-secondary);
88
+ transform: translateY(-50%);
89
+ }
90
+
91
+ .sg-event-timeline-horizontal .sg-event-timeline-dot {
92
+ position: relative;
93
+ z-index: var(--sg-z-base);
60
94
  }
61
95
 
62
96
  .sg-event-timeline-marker {
@@ -8,6 +8,11 @@
8
8
  .sg-list-bordered {
9
9
  border: 1px solid var(--sg-color-border);
10
10
  border-radius: var(--sg-border-radius);
11
+ /* Clip header / footer / first-last item backgrounds (which have square
12
+ * corners) to the rounded border. Without this the tinted header and the
13
+ * hover/selected row backgrounds bleed past the radius, so the corners
14
+ * appear to be a different colour than the rest of the outline. */
15
+ overflow: hidden;
11
16
  }
12
17
 
13
18
  .sg-list-loading {
@@ -55,7 +60,11 @@
55
60
  /* ---- Single item ---- */
56
61
  .sg-list-item {
57
62
  display: flex;
58
- align-items: flex-start;
63
+ /* Center main / actions / extra blocks on a single baseline so rows with a
64
+ * multi-line Meta block (avatar + title + description) stay visually even.
65
+ * The Meta block keeps its own `align-items: flex-start` internally so the
66
+ * avatar still tops out with the title. */
67
+ align-items: center;
59
68
  padding: var(--sg-padding-md) var(--sg-padding-lg);
60
69
  transition: background var(--sg-transition-duration);
61
70
  }
@@ -150,6 +150,23 @@
150
150
  flex-shrink: 0;
151
151
  }
152
152
 
153
+ /* First-letter fallback shown on the collapsed rail for items without an icon. */
154
+ .sg-menu-item-icon-fallback {
155
+ justify-content: center;
156
+ width: 24px;
157
+ height: 24px;
158
+ border-radius: var(--sg-border-radius-sm);
159
+ background: var(--sg-color-fill-secondary, var(--sg-color-bg-secondary));
160
+ color: var(--sg-color-text-secondary);
161
+ font-size: var(--sg-font-size-sm);
162
+ font-weight: 600;
163
+ }
164
+
165
+ .sg-menu-item-selected .sg-menu-item-icon-fallback {
166
+ background: var(--sg-color-primary-bg);
167
+ color: var(--sg-color-primary);
168
+ }
169
+
153
170
  .sg-menu-item-label {
154
171
  flex: 1;
155
172
  overflow: hidden;
@@ -11,6 +11,14 @@
11
11
  font-size: var(--sg-font-size-xl);
12
12
  }
13
13
 
14
+ /* Dark theme: the tertiary text colour already carries a low alpha, and the
15
+ * extra 0.72 symbol opacity stacked on top made empty stars nearly invisible
16
+ * on a dark surface. Use an explicit visible grey at full opacity instead. */
17
+ [data-sg-theme='dark'] .sg-rate {
18
+ --sg-rate-symbol-empty-color: rgba(255, 255, 255, 0.55);
19
+ --sg-rate-symbol-empty-opacity: 1;
20
+ }
21
+
14
22
  .sg-rate-disabled {
15
23
  pointer-events: none;
16
24
  opacity: 0.5;
@@ -64,7 +64,7 @@
64
64
  top: 100%;
65
65
  left: 0;
66
66
  right: 0;
67
- z-index: 100;
67
+ z-index: var(--sg-z-dropdown);
68
68
  margin-top: 4px;
69
69
  padding: var(--sg-padding-xs) 0;
70
70
  background: var(--sg-color-bg-elevated);
@@ -3,6 +3,8 @@
3
3
  --sg-spin-color: var(--sg-color-primary);
4
4
  --sg-spin-overlay-bg: rgba(255, 255, 255, 0.65);
5
5
  display: inline-block;
6
+ box-sizing: border-box;
7
+ flex: 0 0 auto;
6
8
  border: 3px solid var(--sg-spin-color);
7
9
  border-top-color: transparent;
8
10
  border-radius: 50%;
@@ -11,9 +13,21 @@
11
13
  }
12
14
 
13
15
  /* Size variants */
14
- .sg-spin-small { width: 12px; height: 12px; border-width: 1.5px; }
15
- .sg-spin-default { width: 24px; height: 24px; border-width: 3px; }
16
- .sg-spin-large { width: 36px; height: 36px; border-width: 4px; }
16
+ .sg-spin-small {
17
+ width: 12px;
18
+ height: 12px;
19
+ border-width: 1.5px;
20
+ }
21
+ .sg-spin-default {
22
+ width: 24px;
23
+ height: 24px;
24
+ border-width: 3px;
25
+ }
26
+ .sg-spin-large {
27
+ width: 36px;
28
+ height: 36px;
29
+ border-width: 4px;
30
+ }
17
31
 
18
32
  /* === Standalone (no children) === */
19
33
  .sg-spin-standalone {
@@ -45,8 +59,8 @@
45
59
  border-radius: var(--sg-border-radius);
46
60
  }
47
61
 
48
- [data-sg-theme="dark"] .sg-spin-overlay,
49
- [data-sg-theme="dark"] .sg-spin-fullscreen {
62
+ [data-sg-theme='dark'] .sg-spin-overlay,
63
+ [data-sg-theme='dark'] .sg-spin-fullscreen {
50
64
  --sg-spin-overlay-bg: rgba(20, 20, 20, 0.65);
51
65
  }
52
66
 
@@ -82,5 +96,7 @@
82
96
  }
83
97
 
84
98
  @keyframes sg-spin-rotate {
85
- to { transform: rotate(360deg); }
99
+ to {
100
+ transform: rotate(360deg);
101
+ }
86
102
  }
@@ -93,6 +93,15 @@
93
93
  min-width: 0;
94
94
  }
95
95
 
96
+ /* Horizontal: let the content row span the full width of its (flex:1) item
97
+ * so the connector tail inside the title — which is `flex:1` — can stretch
98
+ * across the gap to the next step. Without this the content shrinks to its
99
+ * text width, the tail collapses to its `min-width`, and the steps read as
100
+ * disconnected blobs separated by huge empty gaps. */
101
+ .sg-steps-horizontal .sg-steps-item-content {
102
+ flex: 1;
103
+ }
104
+
96
105
  .sg-steps-item-title {
97
106
  display: flex;
98
107
  align-items: center;
@@ -1,14 +1,11 @@
1
1
  .sg-table-wrapper {
2
- --sg-table-row-height: auto;
3
- --sg-table-row-bg: transparent;
4
- --sg-table-row-hover-bg: var(--sg-color-bg-hover);
5
- --sg-table-header-bg: var(--sg-color-bg-secondary);
6
- --sg-table-border-color: var(--sg-color-border);
7
- --sg-table-border-color-secondary: var(--sg-color-border-secondary);
8
- --sg-table-cell-padding: var(--sg-padding-sm) var(--sg-padding-md);
9
- /* Opaque fallback used by fixed (sticky) cells so scrolling columns
10
- don't bleed through. Override per instance for non-default backgrounds. */
11
- --sg-table-cell-solid-bg: var(--sg-color-bg);
2
+ /* NB: the `--sg-table-*` theming tokens are intentionally NOT declared here.
3
+ * Declaring them on the wrapper would make a custom value set on an *ancestor*
4
+ * (per-instance theming, e.g. `<div style={{'--sg-table-header-bg': ...}}>`)
5
+ * lose to the wrapper's own declaration, so the override would silently do
6
+ * nothing. Instead each consumer below reads the token with the global token
7
+ * as the `var(...)` fallback — that keeps both ancestor overrides AND scope
8
+ * colour theming working. */
12
9
  width: 100%;
13
10
  /* Allow shrinking below intrinsic min-content inside flex/grid parents
14
11
  * so the inner scroll container can actually overflow (or the table can
@@ -101,7 +98,7 @@
101
98
  /* Fluid mode: stretch to fill the scroll container. Overridden below
102
99
  * when the author opts into horizontal scroll via `scroll.x`. */
103
100
  min-width: 100%;
104
- background: var(--sg-table-cell-solid-bg);
101
+ background: var(--sg-table-cell-solid-bg, var(--sg-color-bg));
105
102
  }
106
103
 
107
104
  /* Horizontal-scroll mode: the grid keeps its declared `scroll.x` width
@@ -118,11 +115,11 @@
118
115
  /* ---- Header ---- */
119
116
  .sg-table-th {
120
117
  position: relative;
121
- padding: var(--sg-table-cell-padding);
118
+ padding: var(--sg-table-cell-padding, var(--sg-padding-sm) var(--sg-padding-md));
122
119
  font-weight: 600;
123
- color: var(--sg-color-text);
124
- background: var(--sg-table-header-bg);
125
- border-bottom: 1px solid var(--sg-table-border-color);
120
+ color: var(--sg-table-header-color, var(--sg-color-text));
121
+ background: var(--sg-table-header-bg, var(--sg-color-bg-secondary));
122
+ border-bottom: 1px solid var(--sg-table-border-color, var(--sg-color-border));
126
123
  user-select: none;
127
124
  display: flex;
128
125
  align-items: center;
@@ -214,7 +211,7 @@
214
211
  Opaque body/header overrides live at the end of the file where they can
215
212
  win the cascade against .sg-table-td / .sg-table-th. */
216
213
  .sg-table-cell-fixed {
217
- background: var(--sg-table-cell-solid-bg);
214
+ background: var(--sg-table-cell-solid-bg, var(--sg-color-bg));
218
215
  }
219
216
 
220
217
  /* Sticky header */
@@ -230,10 +227,10 @@
230
227
 
231
228
  /* ---- Body cells ---- */
232
229
  .sg-table-td {
233
- padding: var(--sg-table-cell-padding);
234
- min-height: var(--sg-table-row-height);
235
- background: var(--sg-table-row-bg);
236
- border-bottom: 1px solid var(--sg-table-border-color-secondary);
230
+ padding: var(--sg-table-cell-padding, var(--sg-padding-sm) var(--sg-padding-md));
231
+ min-height: var(--sg-table-row-height, auto);
232
+ background: var(--sg-table-row-bg, transparent);
233
+ border-bottom: 1px solid var(--sg-table-border-color-secondary, var(--sg-color-border-secondary));
237
234
  display: flex;
238
235
  align-items: center;
239
236
  min-width: 0;
@@ -241,7 +238,7 @@
241
238
  }
242
239
 
243
240
  .sg-table-hoverable .sg-table-row:hover .sg-table-td {
244
- background: var(--sg-table-row-hover-bg);
241
+ background: var(--sg-table-row-hover-bg, var(--sg-color-bg-hover));
245
242
  }
246
243
 
247
244
  .sg-table-row-selected .sg-table-td {
@@ -971,15 +968,15 @@
971
968
  * the row, so the "floating" effect disappears entirely.
972
969
  */
973
970
  .sg-table-td.sg-table-cell-fixed {
974
- background: var(--sg-table-cell-solid-bg);
971
+ background: var(--sg-table-cell-solid-bg, var(--sg-color-bg));
975
972
  }
976
973
 
977
974
  .sg-table-th.sg-table-cell-fixed {
978
- background: var(--sg-table-header-bg);
975
+ background: var(--sg-table-header-bg, var(--sg-color-bg-secondary));
979
976
  }
980
977
 
981
978
  .sg-table-hoverable .sg-table-row:hover .sg-table-td.sg-table-cell-fixed {
982
- background: var(--sg-table-row-hover-bg);
979
+ background: var(--sg-table-row-hover-bg, var(--sg-color-bg-hover));
983
980
  }
984
981
 
985
982
  .sg-table-row-selected .sg-table-td.sg-table-cell-fixed,
@@ -988,11 +985,15 @@
988
985
  }
989
986
 
990
987
  .sg-table-row-striped .sg-table-td.sg-table-cell-fixed {
991
- background: color-mix(in srgb, var(--sg-color-text) 2%, var(--sg-table-cell-solid-bg));
988
+ background: color-mix(
989
+ in srgb,
990
+ var(--sg-color-text) 2%,
991
+ var(--sg-table-cell-solid-bg, var(--sg-color-bg))
992
+ );
992
993
  }
993
994
 
994
995
  .sg-table-hoverable .sg-table-row-striped:hover .sg-table-td.sg-table-cell-fixed {
995
- background: var(--sg-table-row-hover-bg);
996
+ background: var(--sg-table-row-hover-bg, var(--sg-color-bg-hover));
996
997
  }
997
998
 
998
999
  /* Subtle shadow on the inner edge so the fixed column visually detaches
@@ -4,6 +4,26 @@
4
4
  font-size: var(--sg-font-size);
5
5
  }
6
6
 
7
+ /* ── Size variants ──────────────────────────────────────────────────── */
8
+
9
+ .sg-tabs-small {
10
+ font-size: var(--sg-font-size-sm);
11
+ }
12
+
13
+ /* Extra `.sg-tabs` qualifier keeps these ahead of `.sg-tabs-line/card .sg-tabs-tab`
14
+ * (same base specificity, defined later in the file). */
15
+ .sg-tabs.sg-tabs-small .sg-tabs-tab {
16
+ padding: var(--sg-padding-xs) var(--sg-padding-md);
17
+ }
18
+
19
+ .sg-tabs-large {
20
+ font-size: var(--sg-font-size-lg);
21
+ }
22
+
23
+ .sg-tabs.sg-tabs-large .sg-tabs-tab {
24
+ padding: var(--sg-padding-md) var(--sg-padding-xl);
25
+ }
26
+
7
27
  .sg-tabs-tab-disabled {
8
28
  color: var(--sg-color-text-disabled);
9
29
  cursor: not-allowed;
@@ -27,7 +27,9 @@
27
27
  min-width: 140px;
28
28
  font-size: var(--sg-font-size);
29
29
  color: var(--sg-color-text);
30
- transition: border-color var(--sg-transition-duration), box-shadow var(--sg-transition-duration);
30
+ transition:
31
+ border-color var(--sg-transition-duration),
32
+ box-shadow var(--sg-transition-duration);
31
33
  }
32
34
 
33
35
  .sg-timepicker-input:hover {
@@ -45,6 +47,14 @@
45
47
  box-shadow: 0 0 0 2px var(--sg-color-primary-bg);
46
48
  }
47
49
 
50
+ .sg-timepicker-value,
51
+ .sg-timepicker-placeholder {
52
+ min-width: 0;
53
+ overflow: hidden;
54
+ text-overflow: ellipsis;
55
+ white-space: nowrap;
56
+ }
57
+
48
58
  .sg-timepicker-placeholder {
49
59
  color: var(--sg-color-text-quaternary);
50
60
  }
@@ -201,7 +211,8 @@
201
211
  color: var(--sg-color-primary);
202
212
  font-size: var(--sg-font-size-sm);
203
213
  cursor: pointer;
204
- transition: color var(--sg-transition-duration),
214
+ transition:
215
+ color var(--sg-transition-duration),
205
216
  background var(--sg-transition-duration),
206
217
  border-color var(--sg-transition-duration),
207
218
  box-shadow var(--sg-transition-duration);
@@ -39,8 +39,9 @@
39
39
  color: var(--sg-color-text);
40
40
  font-size: var(--sg-font-size);
41
41
  outline: none;
42
- transition: border-color var(--sg-transition-duration) var(--sg-transition-timing),
43
- box-shadow var(--sg-transition-duration) var(--sg-transition-timing);
42
+ transition:
43
+ border-color var(--sg-transition-duration) var(--sg-transition-timing),
44
+ box-shadow var(--sg-transition-duration) var(--sg-transition-timing);
44
45
  box-sizing: border-box;
45
46
  }
46
47
 
@@ -71,8 +72,9 @@
71
72
  border-radius: 50%;
72
73
  padding: 0;
73
74
  line-height: 1;
74
- transition: color var(--sg-transition-duration) var(--sg-transition-timing),
75
- background var(--sg-transition-duration) var(--sg-transition-timing);
75
+ transition:
76
+ color var(--sg-transition-duration) var(--sg-transition-timing),
77
+ background var(--sg-transition-duration) var(--sg-transition-timing);
76
78
  }
77
79
 
78
80
  .sg-tree-search-clear:hover {
@@ -112,8 +114,9 @@
112
114
  border-radius: var(--sg-border-radius-sm);
113
115
  font-size: 14px;
114
116
  padding: 0;
115
- transition: color var(--sg-transition-duration) var(--sg-transition-timing),
116
- background var(--sg-transition-duration) var(--sg-transition-timing);
117
+ transition:
118
+ color var(--sg-transition-duration) var(--sg-transition-timing),
119
+ background var(--sg-transition-duration) var(--sg-transition-timing);
117
120
  }
118
121
 
119
122
  .sg-tree-toolbar-btn:hover {
@@ -259,7 +262,9 @@
259
262
  cursor: default;
260
263
  }
261
264
 
262
- .sg-tree-switcher:hover:not(.sg-tree-switcher-noop):not(.sg-tree-switcher-leaf):not(.sg-tree-switcher-loading) {
265
+ .sg-tree-switcher:hover:not(.sg-tree-switcher-noop):not(.sg-tree-switcher-leaf):not(
266
+ .sg-tree-switcher-loading
267
+ ) {
263
268
  color: var(--sg-color-primary);
264
269
  }
265
270
 
@@ -381,8 +386,9 @@
381
386
  border-radius: var(--sg-border-radius-sm);
382
387
  font-size: 12px;
383
388
  padding: 0;
384
- transition: color var(--sg-transition-duration) var(--sg-transition-timing),
385
- background var(--sg-transition-duration) var(--sg-transition-timing);
389
+ transition:
390
+ color var(--sg-transition-duration) var(--sg-transition-timing),
391
+ background var(--sg-transition-duration) var(--sg-transition-timing);
386
392
  }
387
393
 
388
394
  .sg-tree-action-btn:hover {
@@ -418,15 +424,31 @@
418
424
  flex-shrink: 0;
419
425
  }
420
426
 
421
- .sg-tree-status-success { background: var(--sg-color-success); }
422
- .sg-tree-status-warning { background: var(--sg-color-warning); }
423
- .sg-tree-status-error { background: var(--sg-color-error); }
424
- .sg-tree-status-info { background: var(--sg-color-primary); }
427
+ .sg-tree-status-success {
428
+ background: var(--sg-color-success);
429
+ }
430
+ .sg-tree-status-warning {
431
+ background: var(--sg-color-warning);
432
+ }
433
+ .sg-tree-status-error {
434
+ background: var(--sg-color-error);
435
+ }
436
+ .sg-tree-status-info {
437
+ background: var(--sg-color-primary);
438
+ }
425
439
 
426
- .sg-tree-node-status-success { border-left: 2px solid var(--sg-color-success); }
427
- .sg-tree-node-status-warning { border-left: 2px solid var(--sg-color-warning); }
428
- .sg-tree-node-status-error { border-left: 2px solid var(--sg-color-error); }
429
- .sg-tree-node-status-info { border-left: 2px solid var(--sg-color-primary); }
440
+ .sg-tree-node-status-success {
441
+ border-left: 2px solid var(--sg-color-success);
442
+ }
443
+ .sg-tree-node-status-warning {
444
+ border-left: 2px solid var(--sg-color-warning);
445
+ }
446
+ .sg-tree-node-status-error {
447
+ border-left: 2px solid var(--sg-color-error);
448
+ }
449
+ .sg-tree-node-status-info {
450
+ border-left: 2px solid var(--sg-color-primary);
451
+ }
430
452
 
431
453
  /* ═══════════════════════════════════════════
432
454
  CONNECTING LINES (tree guide lines)
@@ -514,12 +536,17 @@
514
536
  outline-offset: -1px;
515
537
  }
516
538
 
539
+ /* Drop indicators use an inset box-shadow rather than a real border so the
540
+ * node box size never changes mid-drag. A 2px border re-flowed the row on
541
+ * every `dragover`, which shifted the hit-box and made the indicator (and
542
+ * the whole tree) flicker/jitter. box-shadow paints without affecting
543
+ * layout — same 2px line, no reflow. */
517
544
  .sg-tree-node-drop-before {
518
- border-top: 2px solid var(--sg-color-primary);
545
+ box-shadow: inset 0 2px 0 var(--sg-color-primary);
519
546
  }
520
547
 
521
548
  .sg-tree-node-drop-after {
522
- border-bottom: 2px solid var(--sg-color-primary);
549
+ box-shadow: inset 0 -2px 0 var(--sg-color-primary);
523
550
  }
524
551
 
525
552
  /* ═══════════════════════════════════════════
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skygraph/styles",
3
- "version": "0.2.3",
3
+ "version": "0.6.4",
4
4
  "description": "SkyGraph framework-agnostic CSS — tokens, themes, transitions, print and 60+ component stylesheets",
5
5
  "license": "MIT",
6
6
  "type": "module",