@skygraph/styles 0.6.4 → 0.6.6

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 (68) hide show
  1. package/README.md +98 -98
  2. package/components/autocomplete.css +35 -35
  3. package/components/autofield.css +67 -67
  4. package/components/avatar.css +37 -37
  5. package/components/badge.css +102 -102
  6. package/components/breadcrumb.css +29 -29
  7. package/components/button.css +181 -181
  8. package/components/calendar.css +408 -408
  9. package/components/carousel.css +102 -102
  10. package/components/cascader.css +380 -380
  11. package/components/charts.css +408 -408
  12. package/components/checkbox.css +114 -114
  13. package/components/collapse.css +166 -166
  14. package/components/colorpicker.css +252 -252
  15. package/components/context-menu.css +95 -95
  16. package/components/descriptions.css +82 -82
  17. package/components/diagram.css +435 -435
  18. package/components/drawer.css +124 -124
  19. package/components/dropdown.css +110 -110
  20. package/components/empty.css +25 -25
  21. package/components/event-timeline.css +134 -134
  22. package/components/field.css +35 -35
  23. package/components/form.css +115 -115
  24. package/components/gantt.css +166 -166
  25. package/components/input-number.css +76 -76
  26. package/components/input-password.css +104 -104
  27. package/components/input.css +211 -211
  28. package/components/list.css +366 -366
  29. package/components/mentions.css +54 -54
  30. package/components/menu.css +326 -326
  31. package/components/modal.css +1 -0
  32. package/components/notification.css +128 -128
  33. package/components/pagination.css +162 -162
  34. package/components/popconfirm.css +95 -95
  35. package/components/progress.css +116 -116
  36. package/components/radio.css +95 -95
  37. package/components/rate.css +48 -48
  38. package/components/resource-calendar.css +224 -224
  39. package/components/result.css +45 -45
  40. package/components/schema-form-editor.css +433 -433
  41. package/components/search-input.css +112 -112
  42. package/components/segmented.css +76 -76
  43. package/components/select.css +181 -181
  44. package/components/skeleton.css +72 -72
  45. package/components/slider.css +51 -51
  46. package/components/spin.css +102 -102
  47. package/components/steps.css +194 -194
  48. package/components/switch.css +75 -75
  49. package/components/table.css +9 -1
  50. package/components/tabs.css +137 -137
  51. package/components/tag.css +61 -61
  52. package/components/textarea.css +22 -22
  53. package/components/timeline.css +169 -169
  54. package/components/timepicker.css +224 -224
  55. package/components/tooltip.css +91 -91
  56. package/components/transfer.css +140 -140
  57. package/components/tree.css +601 -601
  58. package/components/treeselect.css +221 -221
  59. package/components/upload.css +124 -124
  60. package/index.css +70 -70
  61. package/index.d.ts +9 -9
  62. package/package.json +1 -1
  63. package/print.css +88 -88
  64. package/reset.css +17 -17
  65. package/themes/dark.css +17 -17
  66. package/themes/default.css +14 -14
  67. package/tokens.css +310 -310
  68. package/transitions.css +158 -158
@@ -1,408 +1,408 @@
1
- /* Charts — SVG primitives.
2
- *
3
- * Stroke / fill colours are inlined per-series from JS (token references), so
4
- * theming is automatic when `--sg-color-primary`, `--sg-color-success`, ...
5
- * are overridden upstream.
6
- *
7
- * Mount / data-change animations are pure CSS (no rAF loops). Each chart
8
- * passes `--sg-chart-anim-duration` (or `animation-duration` inline) and
9
- * relies on `@keyframes` declared here.
10
- */
11
-
12
- .sg-chart {
13
- /*
14
- * Component-local default for the entry-animation duration. JS may
15
- * override per-instance via inline style (`{ '--sg-chart-anim-duration':
16
- * '400ms' }`). Declared here so `var()` always resolves to a real value
17
- * — required by `check:tokens`.
18
- */
19
- --sg-chart-anim-duration: 600ms;
20
-
21
- /* Локальные токены hover-toolbar чарта. Все цвета приходят из глобальных
22
- * `--sg-color-*` — toolbar пере-темится автоматически. Тень / подсветка
23
- * проксируются через семантические `--sg-chart-tooltip-shadow` /
24
- * `--sg-chart-legend-hover-bg`, чтобы тёмная тема не требовала
25
- * правки этого файла. */
26
- --sg-chart-toolbar-bg: var(--sg-color-bg-elevated);
27
- --sg-chart-toolbar-border: var(--sg-color-border);
28
- --sg-chart-toolbar-shadow: var(--sg-chart-tooltip-shadow);
29
- --sg-chart-toolbar-icon: var(--sg-color-text-secondary);
30
- --sg-chart-toolbar-icon-hover: var(--sg-color-text);
31
- --sg-chart-toolbar-bg-hover: var(--sg-color-bg-hover);
32
- --sg-chart-toolbar-bg-active: var(--sg-color-bg-secondary);
33
-
34
- display: block;
35
- font-family: inherit;
36
- font-size: var(--sg-font-size-sm);
37
- color: var(--sg-color-text-secondary);
38
- }
39
-
40
- /* Wrapper-обёртка вокруг SVG (legend / hover-toolbar). Позиция —
41
- * relative, чтобы абсолютный toolbar якорился за неё. */
42
- .sg-chart-wrapper {
43
- position: relative;
44
- display: inline-block;
45
- max-width: 100%;
46
- }
47
-
48
- .sg-chart-line,
49
- .sg-chart-bar {
50
- /* nothing extra */
51
- }
52
-
53
- /* Axes — opt-in via `xAxis` / `yAxis` props on Line/Bar/Area charts.
54
- * Font-size now follows the global `--sg-font-size-sm` (was hard-coded
55
- * 11px), so axis labels respect a user's font-size override. */
56
- .sg-chart-axis {
57
- pointer-events: none;
58
- font-size: var(--sg-font-size-sm);
59
- }
60
-
61
- .sg-chart-axis-grid {
62
- /* stroke + dashed pattern set inline so token references resolve in raw SVG. */
63
- }
64
-
65
- .sg-chart-axis-tick-label {
66
- fill: var(--sg-color-text-secondary);
67
- }
68
-
69
- .sg-chart-axis-label {
70
- fill: var(--sg-color-text);
71
- font-size: var(--sg-font-size-sm);
72
- font-weight: 600;
73
- /* Tighten the label tracking a hair so axis titles don't wash out
74
- * against busy series. */
75
- letter-spacing: 0.01em;
76
- }
77
-
78
- /* ─────────────────────────────────────────────────────────────────────────
79
- * Animations
80
- *
81
- * Each chart family applies its own keyframe to the per-series / per-bar
82
- * group node. `key={…}` on those groups changes whenever data changes,
83
- * which re-mounts the node and re-triggers the animation. When `animate`
84
- * is `false`, the animation classes are not applied at all.
85
- * ──────────────────────────────────────────────────────────────────────── */
86
-
87
- /* Line chart — per-segment "draw-in" via stroke-dashoffset. The exact
88
- * dasharray / offset values are set inline (we know the segment length
89
- * at render time), and per-segment delay creates a left-to-right reveal. */
90
- .sg-chart-line-segment-animate {
91
- animation-name: sg-chart-line-draw;
92
- animation-fill-mode: forwards;
93
- animation-timing-function: ease-out;
94
- }
95
-
96
- @keyframes sg-chart-line-draw {
97
- to {
98
- stroke-dashoffset: 0;
99
- }
100
- }
101
-
102
- /* Container fade for the whole series group (markers + segments). */
103
- .sg-chart-line-animate {
104
- animation: sg-chart-line-fade var(--sg-chart-anim-duration, 600ms) ease-out both;
105
- }
106
-
107
- @keyframes sg-chart-line-fade {
108
- from {
109
- opacity: 0.05;
110
- }
111
- to {
112
- opacity: 1;
113
- }
114
- }
115
-
116
- /* Bar chart — each <rect> grows from its baseline (transform-origin set
117
- * inline so positive bars rise from the bottom and negative bars descend
118
- * from the top). `transform-box: fill-box` makes pixel transform-origin
119
- * resolve relative to the SVG element itself. */
120
- .sg-chart-bar-animate {
121
- transform-box: fill-box;
122
- animation-name: sg-chart-bar-grow;
123
- animation-fill-mode: forwards;
124
- animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1);
125
- transform: scaleY(0);
126
- }
127
-
128
- @keyframes sg-chart-bar-grow {
129
- to {
130
- transform: scaleY(1);
131
- }
132
- }
133
-
134
- /* Area chart — fade + slight slide-up of the whole filled region. We avoid
135
- * clip-path (poorer SVG support across browsers) in favour of opacity +
136
- * translate, which is enough to convey the entrance without heavy paint. */
137
- .sg-chart-area-animate {
138
- animation: sg-chart-area-fade var(--sg-chart-anim-duration, 600ms) ease-out both;
139
- transform-box: fill-box;
140
- }
141
-
142
- @keyframes sg-chart-area-fade {
143
- from {
144
- opacity: 0;
145
- transform: translateY(4px);
146
- }
147
- to {
148
- opacity: 1;
149
- transform: translateY(0);
150
- }
151
- }
152
-
153
- /* Pie chart — each slice rotates from -90deg to its final angle and fades
154
- * in. `transform-origin` is set inline to the pie centre. */
155
- .sg-chart-pie-animate {
156
- transform-box: view-box;
157
- animation-name: sg-chart-pie-rotate;
158
- animation-fill-mode: forwards;
159
- animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1);
160
- opacity: 0;
161
- }
162
-
163
- @keyframes sg-chart-pie-rotate {
164
- from {
165
- transform: rotate(-90deg);
166
- opacity: 0;
167
- }
168
- to {
169
- transform: rotate(0deg);
170
- opacity: 1;
171
- }
172
- }
173
-
174
- /* Reduce-motion users get static charts. */
175
- @media (prefers-reduced-motion: reduce) {
176
- .sg-chart-line-segment-animate,
177
- .sg-chart-line-animate,
178
- .sg-chart-bar-animate,
179
- .sg-chart-area-animate,
180
- .sg-chart-pie-animate {
181
- animation: none !important;
182
- transform: none !important;
183
- opacity: 1 !important;
184
- stroke-dashoffset: 0 !important;
185
- }
186
- }
187
-
188
- /* ─────────────────────────────────────────────────────────────────────────
189
- * Crosshair
190
- *
191
- * Hover overlay rendered by `<ChartCrosshair>` (currently used by LineChart).
192
- * All visual chrome is here so theming stays token-based.
193
- * ──────────────────────────────────────────────────────────────────────── */
194
-
195
- .sg-chart-crosshair {
196
- pointer-events: none;
197
- }
198
-
199
- .sg-chart-crosshair-line {
200
- /* stroke set inline so token references resolve outside SVG; here we
201
- * only refine the blend so the line stays legible over both light and
202
- * dark series fills. `mix-blend-mode: multiply` darkens against light
203
- * backgrounds, while remaining inert on dark themes (where the
204
- * crosshair token already provides enough contrast). */
205
- mix-blend-mode: multiply;
206
- }
207
-
208
- [data-sg-theme='dark'] .sg-chart-crosshair-line {
209
- /* Dark theme: switch to `screen` blend so the bright crosshair token
210
- * lifts against dark series instead of getting absorbed. */
211
- mix-blend-mode: screen;
212
- }
213
-
214
- .sg-chart-crosshair-tooltip-bg {
215
- /* Real elevation instead of the previous flat 0 1px 2px shadow.
216
- * `drop-shadow` is preferred over `box-shadow` here — the SVG <rect>
217
- * shape is what we're shadowing, not a CSS box. */
218
- filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.18)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.1));
219
- }
220
-
221
- [data-sg-theme='dark'] .sg-chart-crosshair-tooltip-bg {
222
- filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.55)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
223
- }
224
-
225
- .sg-chart-crosshair-tooltip-title,
226
- .sg-chart-crosshair-tooltip-label,
227
- .sg-chart-crosshair-tooltip-value {
228
- font-family: inherit;
229
- }
230
-
231
- /* ─────────────────────────────────────────────────────────────────────────
232
- * Brushing
233
- *
234
- * Drag-to-select diapason overlay rendered by <ChartBrush>. The overlay rect
235
- * captures pointer events; the selection rect is non-interactive (the parent
236
- * controls the diapason via onRangeChange). Colours are token-based so the
237
- * brush re-themes via --sg-color-primary.
238
- * ──────────────────────────────────────────────────────────────────────── */
239
-
240
- .sg-chart-brush {
241
- /* Container; selection rect inside is pointer-events: none. */
242
- }
243
-
244
- .sg-chart-brush-overlay {
245
- /* fill, stroke, and cursor are inlined per-instance; no extra styling. */
246
- }
247
-
248
- .sg-chart-brush-selection {
249
- /* fill / stroke set inline so token references resolve in raw SVG.
250
- * The drop-shadow gives the selection a faint outer halo so it pops
251
- * against the chart series even when the inline fill is set very
252
- * low alpha. */
253
- pointer-events: none;
254
- filter: drop-shadow(0 1px 3px rgba(22, 119, 255, 0.2));
255
- }
256
-
257
- [data-sg-theme='dark'] .sg-chart-brush-selection {
258
- filter: drop-shadow(0 1px 4px rgba(64, 150, 255, 0.35));
259
- }
260
-
261
- /* ─────────────────────────────────────────────────────────────────────────
262
- * Hover toolbar
263
- *
264
- * Floating-панель в правом верхнем углу wrapper-а с действиями (print,
265
- * download SVG, download PNG, reset brush). Контейнер — `pointer-events:
266
- * none`, чтобы не перехватывать crosshair/brush-события на пустом
267
- * overlay; кнопки — `pointer-events: auto`. Анимация opacity — pure CSS
268
- * через `transition`, никакого JS.
269
- * ──────────────────────────────────────────────────────────────────────── */
270
-
271
- .sg-chart-toolbar {
272
- position: absolute;
273
- top: var(--sg-padding-sm);
274
- right: var(--sg-padding-sm);
275
- z-index: 1;
276
- display: inline-flex;
277
- align-items: center;
278
- gap: 2px;
279
- padding: 2px;
280
- border-radius: var(--sg-border-radius);
281
- background: var(--sg-chart-toolbar-bg);
282
- border: 1px solid var(--sg-chart-toolbar-border);
283
- box-shadow: var(--sg-chart-toolbar-shadow);
284
- opacity: 0;
285
- /* Lift slightly higher (was -2px) so the entrance reads as a "fade
286
- * down" rather than a near-instant pop. Both opacity and transform
287
- * share the same easing window so the motion stays cohesive. */
288
- transform: translateY(-4px);
289
- transition:
290
- opacity var(--sg-transition-medium),
291
- transform var(--sg-transition-medium);
292
- pointer-events: none;
293
- }
294
-
295
- .sg-chart-toolbar[data-sg-toolbar='visible'] {
296
- opacity: 1;
297
- transform: translateY(0);
298
- }
299
-
300
- .sg-chart-toolbar-button {
301
- display: inline-flex;
302
- align-items: center;
303
- justify-content: center;
304
- width: 24px;
305
- height: 24px;
306
- padding: 0;
307
- border: 0;
308
- border-radius: var(--sg-border-radius-sm);
309
- background: transparent;
310
- color: var(--sg-chart-toolbar-icon);
311
- cursor: pointer;
312
- pointer-events: auto;
313
- transition:
314
- background-color var(--sg-transition-fast),
315
- color var(--sg-transition-fast);
316
- }
317
-
318
- .sg-chart-toolbar-button:hover {
319
- background: var(--sg-chart-toolbar-bg-hover);
320
- color: var(--sg-chart-toolbar-icon-hover);
321
- }
322
-
323
- .sg-chart-toolbar-button:focus-visible {
324
- outline: 2px solid var(--sg-color-primary);
325
- outline-offset: 1px;
326
- color: var(--sg-chart-toolbar-icon-hover);
327
- }
328
-
329
- .sg-chart-toolbar-button:active {
330
- background: var(--sg-chart-toolbar-bg-active);
331
- }
332
-
333
- .sg-chart-toolbar-button > svg {
334
- display: block;
335
- pointer-events: none;
336
- }
337
-
338
- @media (prefers-reduced-motion: reduce) {
339
- .sg-chart-toolbar {
340
- transition: none;
341
- transform: none;
342
- }
343
- }
344
-
345
- /* ─────────────────────────────────────────────────────────────────────────
346
- * Legend
347
- *
348
- * `<ChartLegend>` renders inline-styled `display`, `gap`, swatch size etc.
349
- * (so the layout stays predictable in headless mode). What we add here is
350
- * purely interactivity polish: a hover affordance on each item, a soft
351
- * rounded background, and a focus ring so keyboard nav lands somewhere.
352
- * No layout properties to avoid fighting the inline styles.
353
- * ──────────────────────────────────────────────────────────────────────── */
354
-
355
- .sg-chart-legend {
356
- /* Tiny breathing room so a hover background doesn't collide with the
357
- * chart's bottom edge. */
358
- padding-top: var(--sg-padding-xs);
359
- /* Layout — moved from inline style on <ChartLegend> root. */
360
- display: flex;
361
- flex-wrap: wrap;
362
- gap: 12px;
363
- margin-top: 8px;
364
- font-size: 12px;
365
- color: var(--sg-color-text-secondary);
366
- }
367
-
368
- .sg-chart-legend-item {
369
- /* Layout — moved from inline style on each legend entry. */
370
- display: inline-flex;
371
- align-items: center;
372
- gap: 6px;
373
- /* Hover surface — purely additive (does not override inline display:
374
- * inline-flex emitted by the React component). */
375
- padding: 2px var(--sg-padding-xs);
376
- border-radius: var(--sg-border-radius-sm);
377
- cursor: default;
378
- transition:
379
- background-color var(--sg-transition-fast),
380
- color var(--sg-transition-fast);
381
- }
382
-
383
- .sg-chart-legend-item:hover {
384
- background: var(--sg-chart-legend-hover-bg);
385
- color: var(--sg-color-text);
386
- }
387
-
388
- .sg-chart-legend-item:focus-visible {
389
- outline: 2px solid var(--sg-color-primary);
390
- outline-offset: 1px;
391
- }
392
-
393
- .sg-chart-legend-swatch {
394
- /* Layout — moved from inline style on each legend swatch. The
395
- * `background` is still emitted inline by the React component since it
396
- * comes from the dynamic series colour. */
397
- display: inline-block;
398
- width: 10px;
399
- height: 10px;
400
- border-radius: 2px;
401
- /* Subtle inner ring so the swatch reads as a chip rather than a flat
402
- * square — useful when the series colour is close to the background. */
403
- box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
404
- }
405
-
406
- [data-sg-theme='dark'] .sg-chart-legend-swatch {
407
- box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
408
- }
1
+ /* Charts — SVG primitives.
2
+ *
3
+ * Stroke / fill colours are inlined per-series from JS (token references), so
4
+ * theming is automatic when `--sg-color-primary`, `--sg-color-success`, ...
5
+ * are overridden upstream.
6
+ *
7
+ * Mount / data-change animations are pure CSS (no rAF loops). Each chart
8
+ * passes `--sg-chart-anim-duration` (or `animation-duration` inline) and
9
+ * relies on `@keyframes` declared here.
10
+ */
11
+
12
+ .sg-chart {
13
+ /*
14
+ * Component-local default for the entry-animation duration. JS may
15
+ * override per-instance via inline style (`{ '--sg-chart-anim-duration':
16
+ * '400ms' }`). Declared here so `var()` always resolves to a real value
17
+ * — required by `check:tokens`.
18
+ */
19
+ --sg-chart-anim-duration: 600ms;
20
+
21
+ /* Локальные токены hover-toolbar чарта. Все цвета приходят из глобальных
22
+ * `--sg-color-*` — toolbar пере-темится автоматически. Тень / подсветка
23
+ * проксируются через семантические `--sg-chart-tooltip-shadow` /
24
+ * `--sg-chart-legend-hover-bg`, чтобы тёмная тема не требовала
25
+ * правки этого файла. */
26
+ --sg-chart-toolbar-bg: var(--sg-color-bg-elevated);
27
+ --sg-chart-toolbar-border: var(--sg-color-border);
28
+ --sg-chart-toolbar-shadow: var(--sg-chart-tooltip-shadow);
29
+ --sg-chart-toolbar-icon: var(--sg-color-text-secondary);
30
+ --sg-chart-toolbar-icon-hover: var(--sg-color-text);
31
+ --sg-chart-toolbar-bg-hover: var(--sg-color-bg-hover);
32
+ --sg-chart-toolbar-bg-active: var(--sg-color-bg-secondary);
33
+
34
+ display: block;
35
+ font-family: inherit;
36
+ font-size: var(--sg-font-size-sm);
37
+ color: var(--sg-color-text-secondary);
38
+ }
39
+
40
+ /* Wrapper-обёртка вокруг SVG (legend / hover-toolbar). Позиция —
41
+ * relative, чтобы абсолютный toolbar якорился за неё. */
42
+ .sg-chart-wrapper {
43
+ position: relative;
44
+ display: inline-block;
45
+ max-width: 100%;
46
+ }
47
+
48
+ .sg-chart-line,
49
+ .sg-chart-bar {
50
+ /* nothing extra */
51
+ }
52
+
53
+ /* Axes — opt-in via `xAxis` / `yAxis` props on Line/Bar/Area charts.
54
+ * Font-size now follows the global `--sg-font-size-sm` (was hard-coded
55
+ * 11px), so axis labels respect a user's font-size override. */
56
+ .sg-chart-axis {
57
+ pointer-events: none;
58
+ font-size: var(--sg-font-size-sm);
59
+ }
60
+
61
+ .sg-chart-axis-grid {
62
+ /* stroke + dashed pattern set inline so token references resolve in raw SVG. */
63
+ }
64
+
65
+ .sg-chart-axis-tick-label {
66
+ fill: var(--sg-color-text-secondary);
67
+ }
68
+
69
+ .sg-chart-axis-label {
70
+ fill: var(--sg-color-text);
71
+ font-size: var(--sg-font-size-sm);
72
+ font-weight: 600;
73
+ /* Tighten the label tracking a hair so axis titles don't wash out
74
+ * against busy series. */
75
+ letter-spacing: 0.01em;
76
+ }
77
+
78
+ /* ─────────────────────────────────────────────────────────────────────────
79
+ * Animations
80
+ *
81
+ * Each chart family applies its own keyframe to the per-series / per-bar
82
+ * group node. `key={…}` on those groups changes whenever data changes,
83
+ * which re-mounts the node and re-triggers the animation. When `animate`
84
+ * is `false`, the animation classes are not applied at all.
85
+ * ──────────────────────────────────────────────────────────────────────── */
86
+
87
+ /* Line chart — per-segment "draw-in" via stroke-dashoffset. The exact
88
+ * dasharray / offset values are set inline (we know the segment length
89
+ * at render time), and per-segment delay creates a left-to-right reveal. */
90
+ .sg-chart-line-segment-animate {
91
+ animation-name: sg-chart-line-draw;
92
+ animation-fill-mode: forwards;
93
+ animation-timing-function: ease-out;
94
+ }
95
+
96
+ @keyframes sg-chart-line-draw {
97
+ to {
98
+ stroke-dashoffset: 0;
99
+ }
100
+ }
101
+
102
+ /* Container fade for the whole series group (markers + segments). */
103
+ .sg-chart-line-animate {
104
+ animation: sg-chart-line-fade var(--sg-chart-anim-duration, 600ms) ease-out both;
105
+ }
106
+
107
+ @keyframes sg-chart-line-fade {
108
+ from {
109
+ opacity: 0.05;
110
+ }
111
+ to {
112
+ opacity: 1;
113
+ }
114
+ }
115
+
116
+ /* Bar chart — each <rect> grows from its baseline (transform-origin set
117
+ * inline so positive bars rise from the bottom and negative bars descend
118
+ * from the top). `transform-box: fill-box` makes pixel transform-origin
119
+ * resolve relative to the SVG element itself. */
120
+ .sg-chart-bar-animate {
121
+ transform-box: fill-box;
122
+ animation-name: sg-chart-bar-grow;
123
+ animation-fill-mode: forwards;
124
+ animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1);
125
+ transform: scaleY(0);
126
+ }
127
+
128
+ @keyframes sg-chart-bar-grow {
129
+ to {
130
+ transform: scaleY(1);
131
+ }
132
+ }
133
+
134
+ /* Area chart — fade + slight slide-up of the whole filled region. We avoid
135
+ * clip-path (poorer SVG support across browsers) in favour of opacity +
136
+ * translate, which is enough to convey the entrance without heavy paint. */
137
+ .sg-chart-area-animate {
138
+ animation: sg-chart-area-fade var(--sg-chart-anim-duration, 600ms) ease-out both;
139
+ transform-box: fill-box;
140
+ }
141
+
142
+ @keyframes sg-chart-area-fade {
143
+ from {
144
+ opacity: 0;
145
+ transform: translateY(4px);
146
+ }
147
+ to {
148
+ opacity: 1;
149
+ transform: translateY(0);
150
+ }
151
+ }
152
+
153
+ /* Pie chart — each slice rotates from -90deg to its final angle and fades
154
+ * in. `transform-origin` is set inline to the pie centre. */
155
+ .sg-chart-pie-animate {
156
+ transform-box: view-box;
157
+ animation-name: sg-chart-pie-rotate;
158
+ animation-fill-mode: forwards;
159
+ animation-timing-function: cubic-bezier(0.2, 0.8, 0.4, 1);
160
+ opacity: 0;
161
+ }
162
+
163
+ @keyframes sg-chart-pie-rotate {
164
+ from {
165
+ transform: rotate(-90deg);
166
+ opacity: 0;
167
+ }
168
+ to {
169
+ transform: rotate(0deg);
170
+ opacity: 1;
171
+ }
172
+ }
173
+
174
+ /* Reduce-motion users get static charts. */
175
+ @media (prefers-reduced-motion: reduce) {
176
+ .sg-chart-line-segment-animate,
177
+ .sg-chart-line-animate,
178
+ .sg-chart-bar-animate,
179
+ .sg-chart-area-animate,
180
+ .sg-chart-pie-animate {
181
+ animation: none !important;
182
+ transform: none !important;
183
+ opacity: 1 !important;
184
+ stroke-dashoffset: 0 !important;
185
+ }
186
+ }
187
+
188
+ /* ─────────────────────────────────────────────────────────────────────────
189
+ * Crosshair
190
+ *
191
+ * Hover overlay rendered by `<ChartCrosshair>` (currently used by LineChart).
192
+ * All visual chrome is here so theming stays token-based.
193
+ * ──────────────────────────────────────────────────────────────────────── */
194
+
195
+ .sg-chart-crosshair {
196
+ pointer-events: none;
197
+ }
198
+
199
+ .sg-chart-crosshair-line {
200
+ /* stroke set inline so token references resolve outside SVG; here we
201
+ * only refine the blend so the line stays legible over both light and
202
+ * dark series fills. `mix-blend-mode: multiply` darkens against light
203
+ * backgrounds, while remaining inert on dark themes (where the
204
+ * crosshair token already provides enough contrast). */
205
+ mix-blend-mode: multiply;
206
+ }
207
+
208
+ [data-sg-theme='dark'] .sg-chart-crosshair-line {
209
+ /* Dark theme: switch to `screen` blend so the bright crosshair token
210
+ * lifts against dark series instead of getting absorbed. */
211
+ mix-blend-mode: screen;
212
+ }
213
+
214
+ .sg-chart-crosshair-tooltip-bg {
215
+ /* Real elevation instead of the previous flat 0 1px 2px shadow.
216
+ * `drop-shadow` is preferred over `box-shadow` here — the SVG <rect>
217
+ * shape is what we're shadowing, not a CSS box. */
218
+ filter: drop-shadow(0 6px 16px rgba(0, 0, 0, 0.18)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.1));
219
+ }
220
+
221
+ [data-sg-theme='dark'] .sg-chart-crosshair-tooltip-bg {
222
+ filter: drop-shadow(0 6px 20px rgba(0, 0, 0, 0.55)) drop-shadow(0 1px 3px rgba(0, 0, 0, 0.35));
223
+ }
224
+
225
+ .sg-chart-crosshair-tooltip-title,
226
+ .sg-chart-crosshair-tooltip-label,
227
+ .sg-chart-crosshair-tooltip-value {
228
+ font-family: inherit;
229
+ }
230
+
231
+ /* ─────────────────────────────────────────────────────────────────────────
232
+ * Brushing
233
+ *
234
+ * Drag-to-select diapason overlay rendered by <ChartBrush>. The overlay rect
235
+ * captures pointer events; the selection rect is non-interactive (the parent
236
+ * controls the diapason via onRangeChange). Colours are token-based so the
237
+ * brush re-themes via --sg-color-primary.
238
+ * ──────────────────────────────────────────────────────────────────────── */
239
+
240
+ .sg-chart-brush {
241
+ /* Container; selection rect inside is pointer-events: none. */
242
+ }
243
+
244
+ .sg-chart-brush-overlay {
245
+ /* fill, stroke, and cursor are inlined per-instance; no extra styling. */
246
+ }
247
+
248
+ .sg-chart-brush-selection {
249
+ /* fill / stroke set inline so token references resolve in raw SVG.
250
+ * The drop-shadow gives the selection a faint outer halo so it pops
251
+ * against the chart series even when the inline fill is set very
252
+ * low alpha. */
253
+ pointer-events: none;
254
+ filter: drop-shadow(0 1px 3px rgba(22, 119, 255, 0.2));
255
+ }
256
+
257
+ [data-sg-theme='dark'] .sg-chart-brush-selection {
258
+ filter: drop-shadow(0 1px 4px rgba(64, 150, 255, 0.35));
259
+ }
260
+
261
+ /* ─────────────────────────────────────────────────────────────────────────
262
+ * Hover toolbar
263
+ *
264
+ * Floating-панель в правом верхнем углу wrapper-а с действиями (print,
265
+ * download SVG, download PNG, reset brush). Контейнер — `pointer-events:
266
+ * none`, чтобы не перехватывать crosshair/brush-события на пустом
267
+ * overlay; кнопки — `pointer-events: auto`. Анимация opacity — pure CSS
268
+ * через `transition`, никакого JS.
269
+ * ──────────────────────────────────────────────────────────────────────── */
270
+
271
+ .sg-chart-toolbar {
272
+ position: absolute;
273
+ top: var(--sg-padding-sm);
274
+ right: var(--sg-padding-sm);
275
+ z-index: 1;
276
+ display: inline-flex;
277
+ align-items: center;
278
+ gap: 2px;
279
+ padding: 2px;
280
+ border-radius: var(--sg-border-radius);
281
+ background: var(--sg-chart-toolbar-bg);
282
+ border: 1px solid var(--sg-chart-toolbar-border);
283
+ box-shadow: var(--sg-chart-toolbar-shadow);
284
+ opacity: 0;
285
+ /* Lift slightly higher (was -2px) so the entrance reads as a "fade
286
+ * down" rather than a near-instant pop. Both opacity and transform
287
+ * share the same easing window so the motion stays cohesive. */
288
+ transform: translateY(-4px);
289
+ transition:
290
+ opacity var(--sg-transition-medium),
291
+ transform var(--sg-transition-medium);
292
+ pointer-events: none;
293
+ }
294
+
295
+ .sg-chart-toolbar[data-sg-toolbar='visible'] {
296
+ opacity: 1;
297
+ transform: translateY(0);
298
+ }
299
+
300
+ .sg-chart-toolbar-button {
301
+ display: inline-flex;
302
+ align-items: center;
303
+ justify-content: center;
304
+ width: 24px;
305
+ height: 24px;
306
+ padding: 0;
307
+ border: 0;
308
+ border-radius: var(--sg-border-radius-sm);
309
+ background: transparent;
310
+ color: var(--sg-chart-toolbar-icon);
311
+ cursor: pointer;
312
+ pointer-events: auto;
313
+ transition:
314
+ background-color var(--sg-transition-fast),
315
+ color var(--sg-transition-fast);
316
+ }
317
+
318
+ .sg-chart-toolbar-button:hover {
319
+ background: var(--sg-chart-toolbar-bg-hover);
320
+ color: var(--sg-chart-toolbar-icon-hover);
321
+ }
322
+
323
+ .sg-chart-toolbar-button:focus-visible {
324
+ outline: 2px solid var(--sg-color-primary);
325
+ outline-offset: 1px;
326
+ color: var(--sg-chart-toolbar-icon-hover);
327
+ }
328
+
329
+ .sg-chart-toolbar-button:active {
330
+ background: var(--sg-chart-toolbar-bg-active);
331
+ }
332
+
333
+ .sg-chart-toolbar-button > svg {
334
+ display: block;
335
+ pointer-events: none;
336
+ }
337
+
338
+ @media (prefers-reduced-motion: reduce) {
339
+ .sg-chart-toolbar {
340
+ transition: none;
341
+ transform: none;
342
+ }
343
+ }
344
+
345
+ /* ─────────────────────────────────────────────────────────────────────────
346
+ * Legend
347
+ *
348
+ * `<ChartLegend>` renders inline-styled `display`, `gap`, swatch size etc.
349
+ * (so the layout stays predictable in headless mode). What we add here is
350
+ * purely interactivity polish: a hover affordance on each item, a soft
351
+ * rounded background, and a focus ring so keyboard nav lands somewhere.
352
+ * No layout properties to avoid fighting the inline styles.
353
+ * ──────────────────────────────────────────────────────────────────────── */
354
+
355
+ .sg-chart-legend {
356
+ /* Tiny breathing room so a hover background doesn't collide with the
357
+ * chart's bottom edge. */
358
+ padding-top: var(--sg-padding-xs);
359
+ /* Layout — moved from inline style on <ChartLegend> root. */
360
+ display: flex;
361
+ flex-wrap: wrap;
362
+ gap: 12px;
363
+ margin-top: 8px;
364
+ font-size: 12px;
365
+ color: var(--sg-color-text-secondary);
366
+ }
367
+
368
+ .sg-chart-legend-item {
369
+ /* Layout — moved from inline style on each legend entry. */
370
+ display: inline-flex;
371
+ align-items: center;
372
+ gap: 6px;
373
+ /* Hover surface — purely additive (does not override inline display:
374
+ * inline-flex emitted by the React component). */
375
+ padding: 2px var(--sg-padding-xs);
376
+ border-radius: var(--sg-border-radius-sm);
377
+ cursor: default;
378
+ transition:
379
+ background-color var(--sg-transition-fast),
380
+ color var(--sg-transition-fast);
381
+ }
382
+
383
+ .sg-chart-legend-item:hover {
384
+ background: var(--sg-chart-legend-hover-bg);
385
+ color: var(--sg-color-text);
386
+ }
387
+
388
+ .sg-chart-legend-item:focus-visible {
389
+ outline: 2px solid var(--sg-color-primary);
390
+ outline-offset: 1px;
391
+ }
392
+
393
+ .sg-chart-legend-swatch {
394
+ /* Layout — moved from inline style on each legend swatch. The
395
+ * `background` is still emitted inline by the React component since it
396
+ * comes from the dynamic series colour. */
397
+ display: inline-block;
398
+ width: 10px;
399
+ height: 10px;
400
+ border-radius: 2px;
401
+ /* Subtle inner ring so the swatch reads as a chip rather than a flat
402
+ * square — useful when the series colour is close to the background. */
403
+ box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
404
+ }
405
+
406
+ [data-sg-theme='dark'] .sg-chart-legend-swatch {
407
+ box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
408
+ }