dsh-token-total 1.0.3 → 1.0.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/lib/client.js +332 -123
- package/lib/index.js +47 -4
- package/lib/types/client/format.d.ts +8 -4
- package/lib/types/client/locales.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/TokenTotalPanel.module.css +259 -99
- package/src/client/TokenTotalPanel.tsx +197 -62
- package/src/client/format.ts +9 -7
- package/src/client/locales.ts +76 -0
- package/src/query.ts +53 -2
|
@@ -83,12 +83,12 @@
|
|
|
83
83
|
gap: 2px;
|
|
84
84
|
padding: 3px;
|
|
85
85
|
border: 1px solid var(--dsw-alias-border-l2);
|
|
86
|
-
border-radius:
|
|
86
|
+
border-radius: 9px;
|
|
87
87
|
background: var(--dsw-alias-bg-layer-1);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
/* A range-preset chip: ghost Button inside the group, active state tinted
|
|
91
|
-
with the
|
|
91
|
+
with the brand accent (same blue as the section bars and the total card). */
|
|
92
92
|
.segItem {
|
|
93
93
|
border-radius: 6px;
|
|
94
94
|
}
|
|
@@ -99,8 +99,9 @@
|
|
|
99
99
|
|
|
100
100
|
.segActive,
|
|
101
101
|
.segActive:hover:not(:disabled) {
|
|
102
|
-
background: var(--dsw-
|
|
103
|
-
color: var(--dsw-
|
|
102
|
+
background: color-mix(in srgb, var(--dsw-tone-1) 14%, transparent);
|
|
103
|
+
color: var(--dsw-tone-1);
|
|
104
|
+
font-weight: 600;
|
|
104
105
|
}
|
|
105
106
|
|
|
106
107
|
.customRange {
|
|
@@ -118,10 +119,24 @@
|
|
|
118
119
|
color: var(--dsw-alias-label-tertiary);
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
/* Trailing toolbar edge: the "as of" stamp sits immediately left of the
|
|
123
|
+
refresh action (it stamps the very data that button refreshes). */
|
|
124
|
+
.toolbarEnd {
|
|
125
|
+
margin-left: auto;
|
|
126
|
+
display: inline-flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
gap: 10px;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.asOf {
|
|
132
|
+
color: var(--dsw-alias-label-tertiary);
|
|
133
|
+
font-size: 12px;
|
|
134
|
+
white-space: nowrap;
|
|
135
|
+
}
|
|
136
|
+
|
|
121
137
|
/* Keep the remaining toolbar action at the trailing edge. */
|
|
122
138
|
.refresh {
|
|
123
139
|
flex: 0 0 auto;
|
|
124
|
-
margin-left: auto;
|
|
125
140
|
}
|
|
126
141
|
|
|
127
142
|
/* ── states ────────────────────────────────────────────────────────────── */
|
|
@@ -153,55 +168,97 @@
|
|
|
153
168
|
|
|
154
169
|
/* ── numeric cards ─────────────────────────────────────────────────────── */
|
|
155
170
|
|
|
156
|
-
/*
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
on one row. */
|
|
171
|
+
/* Six equal tracks: the overview row is one grid of six identical cards
|
|
172
|
+
(long value or not), so no card crowds its neighbours. At the Plugins
|
|
173
|
+
page's 960px content width that is six columns on one row. */
|
|
160
174
|
.cards {
|
|
161
175
|
display: grid;
|
|
162
|
-
grid-template-columns:
|
|
176
|
+
grid-template-columns: repeat(6, minmax(0, 1fr));
|
|
163
177
|
gap: 10px;
|
|
164
178
|
}
|
|
165
179
|
|
|
166
|
-
/* Below the width where six cards hold their own, the grid folds to
|
|
167
|
-
|
|
168
|
-
instead of degrading to the numerics' size, and each row still fills. */
|
|
180
|
+
/* Below the width where six cards hold their own, the grid folds to three
|
|
181
|
+
columns (two rows of three), then to two (three rows of two). */
|
|
169
182
|
@media (max-width: 720px) {
|
|
170
183
|
.cards {
|
|
171
|
-
grid-template-columns: repeat(
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
.cards > :first-child,
|
|
175
|
-
.cards > :last-child {
|
|
176
|
-
grid-column: span 2;
|
|
184
|
+
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
177
185
|
}
|
|
178
186
|
}
|
|
179
187
|
|
|
180
188
|
@media (max-width: 430px) {
|
|
181
189
|
.cards {
|
|
182
|
-
grid-template-columns: repeat(2, 1fr);
|
|
190
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
183
191
|
}
|
|
184
192
|
}
|
|
185
193
|
|
|
194
|
+
/* Each stat card wears one accent hue (tone 1..6 → --dsw-tone-1..6): a 3px
|
|
195
|
+
accent bar on the left edge, the icon in a tinted badge, and a whisper of
|
|
196
|
+
the hue washing the top-left corner — the overview row reads in colour
|
|
197
|
+
instead of one gray register. --card-accent is set by the .cardToneN map
|
|
198
|
+
below; content sits above the wash via a z-index layer. */
|
|
186
199
|
.card {
|
|
200
|
+
--card-accent: var(--dsw-alias-label-tertiary);
|
|
201
|
+
position: relative;
|
|
202
|
+
overflow: hidden;
|
|
187
203
|
display: flex;
|
|
188
204
|
flex-direction: column;
|
|
189
205
|
gap: 6px;
|
|
190
|
-
padding: 12px
|
|
206
|
+
padding: 14px 14px 12px 18px;
|
|
191
207
|
border: 1px solid var(--dsw-alias-border-l1);
|
|
192
|
-
border-radius:
|
|
208
|
+
border-radius: 12px;
|
|
193
209
|
background: var(--dsw-alias-bg-layer-1);
|
|
210
|
+
box-shadow: 0 1px 2px var(--dsw-alias-bg-mask-2);
|
|
194
211
|
min-width: 0;
|
|
195
212
|
}
|
|
196
213
|
|
|
214
|
+
.card::before {
|
|
215
|
+
content: "";
|
|
216
|
+
position: absolute;
|
|
217
|
+
left: 0;
|
|
218
|
+
top: 12px;
|
|
219
|
+
bottom: 12px;
|
|
220
|
+
width: 3px;
|
|
221
|
+
border-radius: 0 3px 3px 0;
|
|
222
|
+
background: var(--card-accent);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
.card::after {
|
|
226
|
+
content: "";
|
|
227
|
+
position: absolute;
|
|
228
|
+
inset: 0;
|
|
229
|
+
background: linear-gradient(135deg, color-mix(in srgb, var(--card-accent) 7%, transparent), transparent 60%);
|
|
230
|
+
pointer-events: none;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Content must paint above the corner wash (the ::after pseudo is the last
|
|
234
|
+
child, so it wins a same-layer paint order). */
|
|
235
|
+
.card > * {
|
|
236
|
+
position: relative;
|
|
237
|
+
z-index: 1;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
.cardTone1 { --card-accent: var(--dsw-tone-1); }
|
|
241
|
+
.cardTone2 { --card-accent: var(--dsw-tone-2); }
|
|
242
|
+
.cardTone3 { --card-accent: var(--dsw-tone-3); }
|
|
243
|
+
.cardTone4 { --card-accent: var(--dsw-tone-4); }
|
|
244
|
+
.cardTone5 { --card-accent: var(--dsw-tone-5); }
|
|
245
|
+
.cardTone6 { --card-accent: var(--dsw-tone-6); }
|
|
246
|
+
|
|
197
247
|
.cardHead {
|
|
198
248
|
display: flex;
|
|
199
249
|
align-items: center;
|
|
200
|
-
gap:
|
|
250
|
+
gap: 7px;
|
|
201
251
|
}
|
|
202
252
|
|
|
253
|
+
/* Icon badge: the accent hue at 12% behind its own glyph. */
|
|
203
254
|
.cardIcon {
|
|
204
|
-
|
|
255
|
+
box-sizing: border-box;
|
|
256
|
+
width: 24px;
|
|
257
|
+
height: 24px;
|
|
258
|
+
padding: 5px;
|
|
259
|
+
border-radius: 7px;
|
|
260
|
+
color: var(--card-accent);
|
|
261
|
+
background: color-mix(in srgb, var(--card-accent) 12%, transparent);
|
|
205
262
|
flex: 0 0 auto;
|
|
206
263
|
}
|
|
207
264
|
|
|
@@ -213,10 +270,15 @@
|
|
|
213
270
|
white-space: nowrap;
|
|
214
271
|
}
|
|
215
272
|
|
|
273
|
+
/* Values never wrap: a wrapped number defeats FitText's measurement (the
|
|
274
|
+
wrapped line is exactly as wide as its box) and reads as a layout break.
|
|
275
|
+
Oversized text shrinks instead — see FitText in TokenTotalPanel.tsx. */
|
|
216
276
|
.cardValue {
|
|
217
277
|
color: var(--dsw-alias-label-primary);
|
|
218
278
|
font-weight: 600;
|
|
219
279
|
line-height: 1.15;
|
|
280
|
+
white-space: nowrap;
|
|
281
|
+
overflow: hidden;
|
|
220
282
|
}
|
|
221
283
|
|
|
222
284
|
.cardValueSm {
|
|
@@ -237,11 +299,13 @@
|
|
|
237
299
|
}
|
|
238
300
|
|
|
239
301
|
/* A muted second line under a card value (the absolute cached-token volume
|
|
240
|
-
under the hit-rate percentage). */
|
|
302
|
+
under the hit-rate percentage). Same no-wrap rule as the value above. */
|
|
241
303
|
.cardSub {
|
|
242
304
|
color: var(--dsw-alias-label-tertiary);
|
|
243
305
|
font-size: 11px;
|
|
244
306
|
line-height: 1.2;
|
|
307
|
+
white-space: nowrap;
|
|
308
|
+
overflow: hidden;
|
|
245
309
|
}
|
|
246
310
|
|
|
247
311
|
/* ── sections / chart chrome ───────────────────────────────────────────── */
|
|
@@ -249,8 +313,13 @@
|
|
|
249
313
|
.section {
|
|
250
314
|
display: flex;
|
|
251
315
|
flex-direction: column;
|
|
252
|
-
gap:
|
|
316
|
+
gap: 12px;
|
|
253
317
|
min-width: 0;
|
|
318
|
+
padding: 14px 16px 16px;
|
|
319
|
+
border: 1px solid var(--dsw-alias-border-l1);
|
|
320
|
+
border-radius: 12px;
|
|
321
|
+
background: var(--dsw-alias-bg-layer-1);
|
|
322
|
+
box-shadow: 0 1px 2px var(--dsw-alias-bg-mask-2);
|
|
254
323
|
}
|
|
255
324
|
|
|
256
325
|
.sectionHead {
|
|
@@ -261,18 +330,59 @@
|
|
|
261
330
|
flex-wrap: wrap;
|
|
262
331
|
}
|
|
263
332
|
|
|
333
|
+
/* Section titles carry the same brand accent bar as the stat cards' tone
|
|
334
|
+
language, so every card heading is anchored the same way. */
|
|
264
335
|
.sectionTitle {
|
|
265
336
|
margin: 0;
|
|
337
|
+
display: flex;
|
|
338
|
+
align-items: center;
|
|
339
|
+
gap: 8px;
|
|
266
340
|
font-size: 15px;
|
|
267
341
|
font-weight: 600;
|
|
268
342
|
color: var(--dsw-alias-label-primary);
|
|
269
343
|
}
|
|
270
344
|
|
|
345
|
+
.sectionTitle::before {
|
|
346
|
+
content: "";
|
|
347
|
+
width: 3px;
|
|
348
|
+
height: 13px;
|
|
349
|
+
border-radius: 2px;
|
|
350
|
+
background: var(--dsw-tone-1);
|
|
351
|
+
flex: 0 0 auto;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* Header meta cluster right of a section title (trend cap note + curve
|
|
355
|
+
legend). Kept as one wrap-friendly row on a common baseline. */
|
|
356
|
+
.headMeta {
|
|
357
|
+
display: flex;
|
|
358
|
+
align-items: center;
|
|
359
|
+
gap: 12px;
|
|
360
|
+
flex-wrap: wrap;
|
|
361
|
+
font-size: 12px;
|
|
362
|
+
color: var(--dsw-alias-label-tertiary);
|
|
363
|
+
}
|
|
364
|
+
|
|
271
365
|
.trendNote {
|
|
272
366
|
font-size: 13px;
|
|
273
367
|
color: var(--dsw-alias-label-tertiary);
|
|
274
368
|
}
|
|
275
369
|
|
|
370
|
+
/* Heatmap and the token trend share ONE row — one card each, left and right.
|
|
371
|
+
Both columns stretch to a common height; the heatmap centres its SVG in the
|
|
372
|
+
taller partner. Below 720px the pair folds to a single column. */
|
|
373
|
+
.duo {
|
|
374
|
+
display: grid;
|
|
375
|
+
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
|
|
376
|
+
gap: 12px;
|
|
377
|
+
align-items: stretch;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
@media (max-width: 720px) {
|
|
381
|
+
.duo {
|
|
382
|
+
grid-template-columns: minmax(0, 1fr);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
|
|
276
386
|
.chartWrap {
|
|
277
387
|
position: relative;
|
|
278
388
|
min-width: 0;
|
|
@@ -287,85 +397,92 @@
|
|
|
287
397
|
right edge. */
|
|
288
398
|
overflow: hidden;
|
|
289
399
|
min-width: 0;
|
|
400
|
+
/* In the duo row the heatmap card shares height with the trend card; the
|
|
401
|
+
grid centres itself in whatever slack the partner leaves. */
|
|
402
|
+
flex: 1 1 auto;
|
|
403
|
+
display: flex;
|
|
404
|
+
align-items: center;
|
|
290
405
|
}
|
|
291
406
|
|
|
292
407
|
.heatmap {
|
|
293
408
|
display: block;
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
409
|
+
margin: 0 auto;
|
|
410
|
+
/* The ~364 day cells are flat SVG rects (no per-cell filter), so there is no
|
|
411
|
+
blur chain left to re-rasterize — but promoting the SVG onto its own
|
|
412
|
+
compositing layer still keeps the whole grid off the scroll repaint path,
|
|
413
|
+
which is what made scrolling this panel drop frames while idle was clean
|
|
414
|
+
(#4). Cheap and invisible, so it stays. Note that the promotion is what
|
|
415
|
+
does the work: `contain: paint` on its own measured no better than no
|
|
416
|
+
mitigation at all. */
|
|
302
417
|
transform: translateZ(0);
|
|
303
418
|
}
|
|
304
419
|
|
|
305
420
|
.heatLegend {
|
|
306
421
|
display: inline-flex;
|
|
307
422
|
align-items: center;
|
|
308
|
-
gap:
|
|
423
|
+
gap: 4px;
|
|
309
424
|
font-size: 13px;
|
|
310
425
|
color: var(--dsw-alias-label-tertiary);
|
|
311
426
|
}
|
|
312
427
|
|
|
428
|
+
/* Axis labels drawn inside the heatmap SVG: the weekday column on the left and
|
|
429
|
+
the month strip along the bottom. SVG <text> takes `fill`, not `color`. */
|
|
430
|
+
.heatAxis {
|
|
431
|
+
fill: var(--dsw-alias-label-tertiary);
|
|
432
|
+
font-size: 11px;
|
|
433
|
+
font-variant-numeric: tabular-nums;
|
|
434
|
+
}
|
|
435
|
+
|
|
313
436
|
.heatCell {
|
|
314
437
|
display: inline-block;
|
|
315
|
-
border-radius:
|
|
438
|
+
border-radius: 2px;
|
|
316
439
|
/* No width/height here: the SVG cells carry their size as geometry
|
|
317
440
|
attributes (x/y/width/height), and a CSS width/height would override
|
|
318
441
|
those on SVG2 rects — pinning every cell to a fixed px and widening the
|
|
319
442
|
visual gap. The legend swatches carry the same size inline, so both
|
|
320
|
-
always match the measured geom.size.
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
light and dark variants below — never the theme accent, which can read
|
|
334
|
-
near-black against the base surface in dark mode. level0 (no data) is a
|
|
335
|
-
neutral empty cell. The cells are SVG <rect>s, so the color rides `fill`
|
|
443
|
+
always match the measured geom.size.
|
|
444
|
+
No filter either: the reference chart paints each tile as a flat, matte
|
|
445
|
+
rounded square, so a sheen/under-shadow would read as a smudge at this
|
|
446
|
+
cell size rather than depth. */
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/* The five heat levels ride a fixed emerald ramp sampled pixel-for-pixel from
|
|
450
|
+
the reference chart (a GitHub-style green scale), with a darker variant for
|
|
451
|
+
dark mode below — never the theme accent, which can read near-black against
|
|
452
|
+
the base surface in dark mode. level0 (no data) is a neutral empty cell.
|
|
453
|
+
The fills are fully opaque: the reference tiles are solid, and mixing toward
|
|
454
|
+
transparent (the previous glass treatment) lightened every step and broke
|
|
455
|
+
the sampled ramp. The cells are SVG <rect>s, so the color rides `fill`
|
|
336
456
|
(background is a no-op on SVG geometry) — but the legend swatches are HTML,
|
|
337
|
-
so both declarations stay in step.
|
|
338
|
-
Each level is mixed a little toward transparent so the bed shows through;
|
|
339
|
-
the amount is deliberately modest, because the ramp is a DATA encoding and
|
|
340
|
-
washing it out would cost readability. */
|
|
457
|
+
so both declarations stay in step. */
|
|
341
458
|
.heatLevel0 {
|
|
342
|
-
fill:
|
|
343
|
-
background:
|
|
459
|
+
fill: var(--dsw-heat-0);
|
|
460
|
+
background: var(--dsw-heat-0);
|
|
344
461
|
}
|
|
345
462
|
|
|
346
463
|
.heatLevel1 {
|
|
347
|
-
fill:
|
|
348
|
-
background:
|
|
464
|
+
fill: var(--dsw-heat-1);
|
|
465
|
+
background: var(--dsw-heat-1);
|
|
349
466
|
}
|
|
350
467
|
|
|
351
468
|
.heatLevel2 {
|
|
352
|
-
fill:
|
|
353
|
-
background:
|
|
469
|
+
fill: var(--dsw-heat-2);
|
|
470
|
+
background: var(--dsw-heat-2);
|
|
354
471
|
}
|
|
355
472
|
|
|
356
473
|
.heatLevel3 {
|
|
357
|
-
fill:
|
|
358
|
-
background:
|
|
474
|
+
fill: var(--dsw-heat-3);
|
|
475
|
+
background: var(--dsw-heat-3);
|
|
359
476
|
}
|
|
360
477
|
|
|
361
478
|
.heatLevel4 {
|
|
362
|
-
fill:
|
|
363
|
-
background:
|
|
479
|
+
fill: var(--dsw-heat-4);
|
|
480
|
+
background: var(--dsw-heat-4);
|
|
364
481
|
}
|
|
365
482
|
|
|
366
483
|
.heatLevel5 {
|
|
367
|
-
fill:
|
|
368
|
-
background:
|
|
484
|
+
fill: var(--dsw-heat-5);
|
|
485
|
+
background: var(--dsw-heat-5);
|
|
369
486
|
}
|
|
370
487
|
|
|
371
488
|
/* ── daily trend ───────────────────────────────────────────────────────── */
|
|
@@ -521,7 +638,7 @@
|
|
|
521
638
|
flex-direction: column;
|
|
522
639
|
min-width: 0;
|
|
523
640
|
border: 1px solid var(--dsw-alias-border-l1);
|
|
524
|
-
border-radius:
|
|
641
|
+
border-radius: 12px;
|
|
525
642
|
background: var(--dsw-alias-bg-layer-1);
|
|
526
643
|
overflow: hidden;
|
|
527
644
|
}
|
|
@@ -573,6 +690,29 @@
|
|
|
573
690
|
border-bottom: none;
|
|
574
691
|
}
|
|
575
692
|
|
|
693
|
+
/* Share bar under a rank row's name: the row's slice of the section total,
|
|
694
|
+
drawn in the row's own colour (a 3px track, like the design mock). */
|
|
695
|
+
.rowTrack {
|
|
696
|
+
height: 3px;
|
|
697
|
+
margin-top: 2px;
|
|
698
|
+
border-radius: 2px;
|
|
699
|
+
background: var(--dsw-alias-border-l1);
|
|
700
|
+
overflow: hidden;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.rowFill {
|
|
704
|
+
display: block;
|
|
705
|
+
height: 3px;
|
|
706
|
+
border-radius: 2px;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/* Top-3 ranks read as a podium: the ordinal takes the warm accent instead of
|
|
710
|
+
the muted gray the tail ranks keep. */
|
|
711
|
+
.rankList > .modelRow:nth-child(-n + 3) .modelRank {
|
|
712
|
+
color: var(--dsw-rank-top);
|
|
713
|
+
font-weight: 700;
|
|
714
|
+
}
|
|
715
|
+
|
|
576
716
|
/* "Other" aggregate row: the entire row is clickable to expand/collapse the
|
|
577
717
|
detail list. The chevron button inside it stops propagation so
|
|
578
718
|
double-firing is avoided. */
|
|
@@ -753,11 +893,6 @@
|
|
|
753
893
|
padding-top: 4px;
|
|
754
894
|
}
|
|
755
895
|
|
|
756
|
-
.foot {
|
|
757
|
-
font-size: 13px;
|
|
758
|
-
color: var(--dsw-alias-label-tertiary);
|
|
759
|
-
}
|
|
760
|
-
|
|
761
896
|
/* ── chart palette ──────────────────────────────────────────────────────── */
|
|
762
897
|
|
|
763
898
|
/* Light variant (the theme's default): model colours are the reasonix
|
|
@@ -765,23 +900,32 @@
|
|
|
765
900
|
white veil mixed in (color-mix 30% white) — the raw hues read dark and
|
|
766
901
|
heavy on the light card surface, and the veil lifts lightness and dulls
|
|
767
902
|
saturation the way a translucent white overlay would, keeping the hues
|
|
768
|
-
colourful instead of muddy. The heatmap ramp is
|
|
769
|
-
(
|
|
770
|
-
rides the
|
|
903
|
+
colourful instead of muddy. The heatmap ramp is a fixed emerald green
|
|
904
|
+
scale (GitHub-style activity heatmap), stepping from a near-white tint to
|
|
905
|
+
a deep green; the hit-rate curve rides the brand blue.
|
|
771
906
|
Ranks 6-10 extend the reasonix five to ten (this plugin's addition): each
|
|
772
|
-
is picked to keep the ten hues apart on both themes.
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
--dsw-heat-
|
|
778
|
-
--dsw-heat-
|
|
779
|
-
--dsw-heat-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
--dsw-heat-
|
|
783
|
-
--dsw-heat-shade: rgb(0 0 0 / 0.20);
|
|
907
|
+
is picked to keep the ten hues apart on both themes.
|
|
908
|
+
The palette must ALSO live on :root: tooltips are fixed portals on
|
|
909
|
+
document.body (see ChartTip), outside the panel subtree, and the inline
|
|
910
|
+
var(--dsw-chart-N) swatches they carry only resolve from :root. */
|
|
911
|
+
:root, .panel {
|
|
912
|
+
--dsw-heat-0: #f4f5f5;
|
|
913
|
+
--dsw-heat-1: #daf6ea;
|
|
914
|
+
--dsw-heat-2: #c7f0df;
|
|
915
|
+
--dsw-heat-3: #82edc0;
|
|
916
|
+
--dsw-heat-4: #00b96b;
|
|
917
|
+
--dsw-heat-5: #00663b;
|
|
784
918
|
--dsw-trend-line: #4d6bfe;
|
|
919
|
+
/* Overview-card tone accents (stat cards 1..6) and the podium ordinal.
|
|
920
|
+
Six hues, each picked to sit apart from both the chart set and the heat
|
|
921
|
+
ramp, at full strength so 12% badge tints stay visible on white. */
|
|
922
|
+
--dsw-tone-1: #4d6bfe;
|
|
923
|
+
--dsw-tone-2: #00b96b;
|
|
924
|
+
--dsw-tone-3: #e07b39;
|
|
925
|
+
--dsw-tone-4: #975bf1;
|
|
926
|
+
--dsw-tone-5: #0d8a8a;
|
|
927
|
+
--dsw-tone-6: #d34591;
|
|
928
|
+
--dsw-rank-top: #c46212;
|
|
785
929
|
--dsw-chart-1: color-mix(in srgb, #0576ff 70%, white);
|
|
786
930
|
--dsw-chart-2: color-mix(in srgb, #2f6f37 70%, white);
|
|
787
931
|
--dsw-chart-3: color-mix(in srgb, #c46212 70%, white);
|
|
@@ -807,17 +951,23 @@
|
|
|
807
951
|
(35% — dark surfaces need the extra lift), so segments read soft and
|
|
808
952
|
bright instead of sinking into the background. */
|
|
809
953
|
@media (prefers-color-scheme: dark) {
|
|
810
|
-
.panel {
|
|
811
|
-
--dsw-heat-0: #
|
|
812
|
-
--dsw-heat-1: #
|
|
813
|
-
--dsw-heat-2: #
|
|
814
|
-
--dsw-heat-3: #
|
|
815
|
-
--dsw-heat-4: #
|
|
816
|
-
--dsw-heat-5: #
|
|
817
|
-
/* Same depth pair, recalibrated: a dark tray swallows a light shade. */
|
|
818
|
-
--dsw-heat-sheen: rgb(255 255 255 / 0.30);
|
|
819
|
-
--dsw-heat-shade: rgb(0 0 0 / 0.50);
|
|
954
|
+
:root, .panel {
|
|
955
|
+
--dsw-heat-0: #1b211e;
|
|
956
|
+
--dsw-heat-1: #123a2a;
|
|
957
|
+
--dsw-heat-2: #17553a;
|
|
958
|
+
--dsw-heat-3: #1c7a4e;
|
|
959
|
+
--dsw-heat-4: #2fbf7c;
|
|
960
|
+
--dsw-heat-5: #7ef0b4;
|
|
820
961
|
--dsw-trend-line: #7d95ff;
|
|
962
|
+
/* Dark tones are lifted versions of the light six: same identity hue,
|
|
963
|
+
brighter so 16% badge tints and 3px bars read on dark surfaces. */
|
|
964
|
+
--dsw-tone-1: #7d95ff;
|
|
965
|
+
--dsw-tone-2: #2fbf7c;
|
|
966
|
+
--dsw-tone-3: #e89a5c;
|
|
967
|
+
--dsw-tone-4: #b18cff;
|
|
968
|
+
--dsw-tone-5: #3bc5c5;
|
|
969
|
+
--dsw-tone-6: #f076ac;
|
|
970
|
+
--dsw-rank-top: #e08543;
|
|
821
971
|
--dsw-chart-1: color-mix(in srgb, #0576ff 65%, white);
|
|
822
972
|
--dsw-chart-2: color-mix(in srgb, #2f6f37 65%, white);
|
|
823
973
|
--dsw-chart-3: color-mix(in srgb, #c46212 65%, white);
|
|
@@ -836,4 +986,14 @@
|
|
|
836
986
|
--dsw-provider-5: color-mix(in srgb, #b03a5b 65%, white);
|
|
837
987
|
--dsw-provider-other: color-mix(in srgb, #576270 65%, white);
|
|
838
988
|
}
|
|
989
|
+
|
|
990
|
+
/* Dark surfaces swallow pale tints, so the card accents step up: badge
|
|
991
|
+
12% → 16%, corner wash 7% → 10%. */
|
|
992
|
+
.cardIcon {
|
|
993
|
+
background: color-mix(in srgb, var(--card-accent) 16%, transparent);
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
.card::after {
|
|
997
|
+
background: linear-gradient(135deg, color-mix(in srgb, var(--card-accent) 10%, transparent), transparent 60%);
|
|
998
|
+
}
|
|
839
999
|
}
|