youplot 1.0.0__py3-none-any.whl

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.
youplot/render/css.py ADDED
@@ -0,0 +1,578 @@
1
+ """
2
+ CSS generation for youplot.
3
+ All values come from the Theme — nothing hardcoded here.
4
+ Design: Precision & Density + Data & Analysis personality.
5
+ Linear/Stripe-inspired: borders-only depth, 4px grid, tabular nums for data.
6
+ """
7
+
8
+ from __future__ import annotations
9
+ from youplot.themes.base import Theme
10
+
11
+
12
+ def build_css(theme: Theme) -> str:
13
+ t = theme
14
+ return f"""
15
+ *,*::before,*::after{{box-sizing:border-box;margin:0;padding:0}}
16
+ html{{scroll-behavior:smooth}}
17
+
18
+ body{{
19
+ font-family:-apple-system,BlinkMacSystemFont,"Inter","Segoe UI",Roboto,sans-serif;
20
+ background:{t.bg_page};
21
+ color:{t.text_title};
22
+ font-size:13px;
23
+ line-height:1.5;
24
+ -webkit-font-smoothing:antialiased;
25
+ }}
26
+
27
+ /* ── Page wrapper ──────────────────────────────────────────────────────── */
28
+ .up-page{{
29
+ max-width:100%;
30
+ padding:24px 28px 48px;
31
+ }}
32
+
33
+ /* ── Chart card ────────────────────────────────────────────────────────── */
34
+ .up-card{{
35
+ background:{t.bg_chart};
36
+ border:0.5px solid {t.border};
37
+ border-radius:8px;
38
+ padding:20px 24px 16px;
39
+ margin-bottom:16px;
40
+ box-shadow:0 1px 3px rgba(0,0,0,0.04);
41
+ position:relative;
42
+ }}
43
+
44
+ /* ── Header ────────────────────────────────────────────────────────────── */
45
+ .up-header{{
46
+ margin-bottom:16px;
47
+ }}
48
+ .up-title{{
49
+ font-size:14px;
50
+ font-weight:600;
51
+ letter-spacing:-0.02em;
52
+ color:{t.text_title};
53
+ margin-bottom:2px;
54
+ }}
55
+ .up-subtitle{{
56
+ font-size:11px;
57
+ color:{t.text_subtitle};
58
+ letter-spacing:0;
59
+ }}
60
+
61
+ /* ── Legend ────────────────────────────────────────────────────────────── */
62
+ .up-legend{{
63
+ display:flex;
64
+ flex-wrap:wrap;
65
+ gap:16px;
66
+ margin-bottom:14px;
67
+ }}
68
+ .up-leg-item{{
69
+ display:flex;
70
+ align-items:center;
71
+ gap:6px;
72
+ font-size:11px;
73
+ color:{t.text_legend};
74
+ cursor:pointer;
75
+ user-select:none;
76
+ transition:opacity 0.15s;
77
+ padding:2px 0;
78
+ }}
79
+ .up-leg-item:hover{{
80
+ color:{t.text_title};
81
+ }}
82
+ .up-leg-item.up-leg-off{{
83
+ opacity:0.3;
84
+ }}
85
+ .up-leg-swatch{{
86
+ width:16px;
87
+ height:2px;
88
+ border-radius:2px;
89
+ flex-shrink:0;
90
+ transition:opacity 0.15s;
91
+ }}
92
+ .up-leg-swatch.dashed{{
93
+ background:repeating-linear-gradient(
94
+ 90deg,
95
+ currentColor 0,currentColor 4px,transparent 4px,transparent 7px
96
+ );
97
+ height:0;
98
+ border-top:2px solid;
99
+ }}
100
+ .up-leg-label{{
101
+ font-variant-numeric:tabular-nums;
102
+ }}
103
+
104
+ /* ── Chart container ───────────────────────────────────────────────────── */
105
+ #up-chart-container{{
106
+ width:100%;
107
+ overflow:hidden;
108
+ position:relative;
109
+ }}
110
+ #up-chart-container .uplot,
111
+ #up-chart-container .uplot canvas{{
112
+ width:100%!important;
113
+ }}
114
+
115
+ /* ── Toolbar (updated for right group) ─────────────────────────────────── */
116
+ .up-toolbar{{
117
+ display:flex;
118
+ align-items:center;
119
+ justify-content:space-between;
120
+ margin-bottom:12px;
121
+ flex-wrap:wrap;
122
+ gap:8px;
123
+ }}
124
+ .up-toolbar-right{{
125
+ display:flex;
126
+ gap:6px;
127
+ align-items:center;
128
+ }}
129
+ .up-btn{{
130
+ font-size:11px;
131
+ font-weight:500;
132
+ padding:4px 12px;
133
+ border-radius:5px;
134
+ border:0.5px solid {t.border};
135
+ background:transparent;
136
+ color:{t.text_subtitle};
137
+ cursor:pointer;
138
+ transition:all 0.12s;
139
+ letter-spacing:0.01em;
140
+ }}
141
+ .up-btn:hover{{
142
+ background:{t.grid_color};
143
+ color:{t.text_title};
144
+ }}
145
+ .up-zoom-hint{{
146
+ font-size:11px;
147
+ color:{t.text_subtitle};
148
+ opacity:0.6;
149
+ }}
150
+ .uplot .u-select{{
151
+ background:rgba(99,102,241,0.10);
152
+ border:1px solid rgba(99,102,241,0.35);
153
+ }}
154
+
155
+ /* ── Tooltip — glass morphism ──────────────────────────────────────────── */
156
+ .up-tooltip{{
157
+ position:fixed;
158
+ background:{t.tooltip_bg};
159
+ -webkit-backdrop-filter:blur(24px) saturate(180%);
160
+ backdrop-filter:blur(24px) saturate(180%);
161
+ border:1px solid {t.tooltip_border};
162
+ color:{t.text_title};
163
+ font-size:11.5px;
164
+ padding:11px 15px 13px;
165
+ border-radius:10px;
166
+ pointer-events:none;
167
+ display:none;
168
+ z-index:9999;
169
+ line-height:1.85;
170
+ min-width:170px;
171
+ max-width:290px;
172
+ box-shadow:{t.tooltip_shadow};
173
+ font-family:-apple-system,BlinkMacSystemFont,"Inter","Segoe UI",Roboto,sans-serif;
174
+ }}
175
+ .up-tooltip-time{{
176
+ font-size:10px;
177
+ color:{t.text_tooltip_label};
178
+ margin-bottom:8px;
179
+ font-variant-numeric:tabular-nums;
180
+ letter-spacing:0.02em;
181
+ text-transform:uppercase;
182
+ border-bottom:0.5px solid {t.tooltip_border};
183
+ padding-bottom:6px;
184
+ }}
185
+ .up-tooltip-row{{
186
+ display:flex;
187
+ align-items:center;
188
+ gap:8px;
189
+ padding:1.5px 0;
190
+ }}
191
+ .up-tooltip-dot{{
192
+ width:7px;
193
+ height:7px;
194
+ border-radius:50%;
195
+ flex-shrink:0;
196
+ box-shadow:0 0 0 2px rgba(255,255,255,0.15);
197
+ }}
198
+ .up-tooltip-name{{
199
+ color:{t.text_tooltip_label};
200
+ font-size:10.5px;
201
+ flex:1;
202
+ min-width:0;
203
+ overflow:hidden;
204
+ text-overflow:ellipsis;
205
+ white-space:nowrap;
206
+ letter-spacing:0.01em;
207
+ }}
208
+ .up-tooltip-val{{
209
+ font-weight:600;
210
+ font-variant-numeric:tabular-nums;
211
+ font-size:12px;
212
+ letter-spacing:-0.01em;
213
+ }}
214
+
215
+ /* ── Annotation labels ─────────────────────────────────────────────────── */
216
+ .up-ann-label{{
217
+ position:absolute;
218
+ font-size:10px;
219
+ font-weight:500;
220
+ color:{t.text_subtitle};
221
+ pointer-events:none;
222
+ white-space:nowrap;
223
+ letter-spacing:0.02em;
224
+ }}
225
+
226
+ /* ── Toolbar Tools ─────────────────────────────────────────────────────── */
227
+ .up-tools {{
228
+ display:flex;
229
+ gap:4px;
230
+ background:rgba(0,0,0,0.03);
231
+ padding:3px;
232
+ border-radius:6px;
233
+ border:0.5px solid {t.border};
234
+ }}
235
+ .up-tool-btn {{
236
+ border:none;
237
+ background:transparent;
238
+ }}
239
+ .up-tool-btn.active {{
240
+ background:{t.bg_chart};
241
+ box-shadow:0 1px 2px rgba(0,0,0,0.05);
242
+ color:{t.text_title};
243
+ }}
244
+
245
+ /* ── Tags — bubble style ───────────────────────────────────────────────── */
246
+ .up-tags-list {{
247
+ margin-top:14px;
248
+ }}
249
+ .up-tag-bubbles {{
250
+ display:flex;
251
+ flex-wrap:wrap;
252
+ gap:6px;
253
+ margin-top:4px;
254
+ }}
255
+ .up-tag-bubble {{
256
+ display:inline-flex;
257
+ align-items:center;
258
+ gap:5px;
259
+ padding:3px 9px 3px 10px;
260
+ border-radius:999px;
261
+ border:1px solid;
262
+ font-size:11px;
263
+ font-weight:500;
264
+ cursor:pointer;
265
+ user-select:none;
266
+ transition:filter 0.12s, transform 0.1s;
267
+ white-space:nowrap;
268
+ max-width:220px;
269
+ }}
270
+ .up-tag-bubble:hover {{
271
+ filter:brightness(1.1);
272
+ transform:translateY(-1px);
273
+ }}
274
+ .up-tag-bubble-name {{
275
+ overflow:hidden;
276
+ text-overflow:ellipsis;
277
+ white-space:nowrap;
278
+ max-width:160px;
279
+ }}
280
+ .up-tag-bubble-del {{
281
+ background:transparent;
282
+ border:none;
283
+ cursor:pointer;
284
+ font-size:13px;
285
+ line-height:1;
286
+ padding:0;
287
+ opacity:0.6;
288
+ flex-shrink:0;
289
+ color:inherit;
290
+ }}
291
+ .up-tag-bubble-del:hover {{
292
+ opacity:1;
293
+ }}
294
+
295
+ /* ── Custom Prompt ─────────────────────────────────────────────────────── */
296
+ .up-tag-prompt {{
297
+ position:absolute;
298
+ top:0; left:0; right:0; bottom:0;
299
+ background:rgba(0,0,0,0.2);
300
+ -webkit-backdrop-filter:blur(2px);
301
+ backdrop-filter:blur(2px);
302
+ display:none; /* active toggles flex */
303
+ align-items:center;
304
+ justify-content:center;
305
+ z-index:9999;
306
+ border-radius:8px;
307
+ }}
308
+ .up-tag-prompt-box {{
309
+ background:{t.bg_chart};
310
+ padding:20px;
311
+ border-radius:10px;
312
+ box-shadow:{t.tooltip_shadow};
313
+ border:1px solid {t.border};
314
+ width:260px;
315
+ }}
316
+ .up-tag-prompt-title {{
317
+ font-weight:600;
318
+ margin-bottom:12px;
319
+ font-size:13px;
320
+ color:{t.text_title};
321
+ }}
322
+ .up-tag-input {{
323
+ width:100%;
324
+ padding:8px;
325
+ border:1px solid {t.border};
326
+ border-radius:6px;
327
+ background:{t.bg_page};
328
+ color:{t.text_title};
329
+ margin-bottom:16px;
330
+ font-size:12px;
331
+ outline:none;
332
+ }}
333
+ .up-tag-input:focus {{
334
+ border-color:rgba(99,102,241,0.5);
335
+ }}
336
+ .up-tag-prompt-actions {{
337
+ display:flex;
338
+ justify-content:flex-end;
339
+ gap:8px;
340
+ }}
341
+ .up-btn-primary {{
342
+ background:rgba(99,102,241,0.1);
343
+ color:#6366f1;
344
+ border-color:rgba(99,102,241,0.3);
345
+ }}
346
+ .up-btn-primary:hover {{
347
+ background:rgba(99,102,241,0.15);
348
+ color:#4f46e5;
349
+ }}
350
+
351
+ /* ── Annotation Pins (Figma-style) ─────────────────────────────────────── */
352
+ .up-pins-layer{{
353
+ position:absolute;
354
+ pointer-events:none;
355
+ z-index:100;
356
+ }}
357
+ .up-pin{{
358
+ position:absolute;
359
+ pointer-events:all;
360
+ cursor:pointer;
361
+ z-index:101;
362
+ }}
363
+ .up-pin-icon{{
364
+ width:20px;
365
+ height:20px;
366
+ border-radius:50% 50% 50% 0;
367
+ transform:rotate(-45deg);
368
+ background:#6366f1;
369
+ display:flex;
370
+ align-items:center;
371
+ justify-content:center;
372
+ color:#fff;
373
+ font-size:9px;
374
+ font-weight:700;
375
+ box-shadow:0 2px 6px rgba(0,0,0,0.25);
376
+ transition:transform 0.15s;
377
+ }}
378
+ .up-pin:hover .up-pin-icon{{
379
+ transform:rotate(-45deg) scale(1.2);
380
+ }}
381
+ .up-pin-popup{{
382
+ display:none;
383
+ position:absolute;
384
+ left:22px;
385
+ top:-4px;
386
+ background:{t.bg_chart};
387
+ border:1px solid {t.border};
388
+ border-radius:8px;
389
+ padding:8px 12px;
390
+ min-width:160px;
391
+ max-width:240px;
392
+ box-shadow:{t.tooltip_shadow};
393
+ z-index:200;
394
+ pointer-events:none;
395
+ }}
396
+ .up-pin:hover .up-pin-popup{{
397
+ display:block;
398
+ }}
399
+ .up-pin-popup-label{{
400
+ font-weight:600;
401
+ font-size:12px;
402
+ color:{t.text_title};
403
+ margin-bottom:3px;
404
+ }}
405
+ .up-pin-popup-time{{
406
+ font-size:10px;
407
+ color:{t.text_subtitle};
408
+ font-variant-numeric:tabular-nums;
409
+ }}
410
+ .up-pin-del{{
411
+ display:none;
412
+ position:absolute;
413
+ top:-6px;
414
+ right:-6px;
415
+ width:16px;
416
+ height:16px;
417
+ border-radius:50%;
418
+ background:#f43f5e;
419
+ border:none;
420
+ color:#fff;
421
+ font-size:11px;
422
+ line-height:1;
423
+ cursor:pointer;
424
+ align-items:center;
425
+ justify-content:center;
426
+ padding:0;
427
+ z-index:202;
428
+ }}
429
+ .up-pin:hover .up-pin-del{{
430
+ display:flex;
431
+ }}
432
+
433
+
434
+ /* ── Export button ──────────────────────────────────────────────────────── */
435
+ .up-export-btn{{
436
+ font-size:11px;
437
+ }}
438
+ .up-export-btn:hover{{
439
+ background:{t.grid_color};
440
+ color:{t.text_title};
441
+ }}
442
+
443
+ /* ── Annotate mode cursor ──────────────────────────────────────────────── */
444
+ .u-over{{ cursor: default; }}
445
+
446
+ /* ── Annotation prompt ─────────────────────────────────────────────────── */
447
+ .up-ann-prompt{{
448
+ position:absolute;
449
+ top:0; left:0; right:0; bottom:0;
450
+ background:rgba(0,0,0,0.2);
451
+ -webkit-backdrop-filter:blur(2px);
452
+ backdrop-filter:blur(2px);
453
+ display:none;
454
+ align-items:center;
455
+ justify-content:center;
456
+ z-index:9999;
457
+ border-radius:8px;
458
+ }}
459
+ /* ── Annotation sticky notes ────────────────────────────────────────────── */
460
+ .up-ann-section {{
461
+ margin-top:14px;
462
+ }}
463
+ .up-list-section-label {{
464
+ font-size:10px;
465
+ font-weight:600;
466
+ letter-spacing:0.06em;
467
+ text-transform:uppercase;
468
+ color:{t.text_subtitle};
469
+ margin-bottom:8px;
470
+ padding-left:2px;
471
+ }}
472
+ .up-ann-notes-wrap {{
473
+ display:flex;
474
+ flex-wrap:wrap;
475
+ gap:8px;
476
+ align-items:flex-start;
477
+ }}
478
+ .up-ann-item {{
479
+ position:relative;
480
+ width:100px;
481
+ min-height:80px;
482
+ padding:10px 10px 18px 10px;
483
+ border-radius:2px 8px 8px 2px;
484
+ cursor:pointer;
485
+ transition:transform 0.15s, box-shadow 0.15s;
486
+ box-shadow:2px 3px 8px rgba(0,0,0,0.13), 0 1px 2px rgba(0,0,0,0.08);
487
+ /* folded corner via gradient */
488
+ background-image:linear-gradient(
489
+ 135deg,
490
+ rgba(0,0,0,0.10) 0px,
491
+ rgba(0,0,0,0.10) 12px,
492
+ transparent 12px
493
+ );
494
+ overflow:hidden;
495
+ display:flex;
496
+ flex-direction:column;
497
+ justify-content:space-between;
498
+ /* slight alternating tilt set per-item via JS */
499
+ }}
500
+ .up-ann-item:hover {{
501
+ transform:translateY(-3px) rotate(0deg) !important;
502
+ box-shadow:3px 8px 18px rgba(0,0,0,0.18), 0 2px 4px rgba(0,0,0,0.1);
503
+ z-index:10;
504
+ }}
505
+ .up-ann-item-dot {{
506
+ display:none;
507
+ }}
508
+ .up-ann-item-body {{
509
+ flex:1;
510
+ }}
511
+ .up-ann-item-label {{
512
+ font-size:11px;
513
+ font-weight:600;
514
+ line-height:1.35;
515
+ color:rgba(0,0,0,0.75);
516
+ word-break:break-word;
517
+ margin-bottom:4px;
518
+ }}
519
+ .up-ann-item-time {{
520
+ font-size:9px;
521
+ color:rgba(0,0,0,0.45);
522
+ font-variant-numeric:tabular-nums;
523
+ line-height:1.3;
524
+ }}
525
+ .up-ann-item .up-tag-del {{
526
+ position:absolute;
527
+ top:3px;
528
+ right:4px;
529
+ background:transparent;
530
+ border:none;
531
+ color:rgba(0,0,0,0.3);
532
+ font-size:13px;
533
+ padding:0;
534
+ cursor:pointer;
535
+ line-height:1;
536
+ opacity:0;
537
+ transition:opacity 0.15s;
538
+ }}
539
+ .up-ann-item:hover .up-tag-del {{
540
+ opacity:1;
541
+ }}
542
+ .up-ann-item .up-tag-del:hover {{
543
+ color:rgba(0,0,0,0.7);
544
+ }}
545
+ .up-measure-mode .u-over {{
546
+ cursor: crosshair !important;
547
+ }}
548
+ .up-measure-bar {{
549
+ background: rgba(10,10,10,0.95);
550
+ color: #fff;
551
+ padding: 8px 16px;
552
+ display: none; /* flex when active */
553
+ align-items: center;
554
+ justify-content: space-between;
555
+ border-radius: 8px;
556
+ margin-top: 8px;
557
+ margin-bottom: 8px;
558
+ font-size: 11px;
559
+ -webkit-backdrop-filter: blur(8px);
560
+ backdrop-filter: blur(8px);
561
+ }}
562
+ .up-measure-details {{
563
+ display: flex;
564
+ gap: 16px;
565
+ overflow-x: auto;
566
+ white-space: nowrap;
567
+ flex: 1;
568
+ padding-right: 16px;
569
+ scrollbar-width: none;
570
+ }}
571
+ .up-measure-details::-webkit-scrollbar {{ display: none; }}
572
+ .up-m-stat {{
573
+ display: inline-flex;
574
+ align-items: center;
575
+ gap: 4px;
576
+ }}
577
+ .up-m-val {{ font-weight: 600; font-variant-numeric: tabular-nums; }}
578
+ """