@jefuriiij/synthra 0.1.1 → 0.1.2
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/dist/cli/index.js +763 -35
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/index.js +762 -34
- package/dist/dashboard/index.js.map +1 -1
- package/package.json +1 -1
package/dist/dashboard/index.js
CHANGED
|
@@ -343,28 +343,39 @@ var public_default = `<!doctype html>
|
|
|
343
343
|
|
|
344
344
|
<main>
|
|
345
345
|
<section>
|
|
346
|
-
<h2>
|
|
346
|
+
<h2>
|
|
347
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 3v18h18"/><path d="M7 14l4-4 4 4 5-5"/></svg>
|
|
348
|
+
Global totals
|
|
349
|
+
<span class="muted">(all projects)</span>
|
|
350
|
+
</h2>
|
|
347
351
|
<div class="cards" id="cards"></div>
|
|
348
352
|
</section>
|
|
349
353
|
|
|
350
354
|
<section>
|
|
351
|
-
<h2>
|
|
355
|
+
<h2>
|
|
356
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
357
|
+
Projects
|
|
358
|
+
</h2>
|
|
352
359
|
<div class="projects" id="projects"></div>
|
|
353
360
|
<p class="empty hidden" id="projects-empty">No projects registered yet. Run <code>syn .</code> in any project to add it.</p>
|
|
354
361
|
</section>
|
|
355
362
|
|
|
356
363
|
<section>
|
|
357
|
-
<h2>
|
|
364
|
+
<h2>
|
|
365
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><polyline points="12 6 12 12 16 14"/></svg>
|
|
366
|
+
Recent calls
|
|
367
|
+
<span class="muted">(across all projects)</span>
|
|
368
|
+
</h2>
|
|
358
369
|
<table id="turns">
|
|
359
370
|
<thead>
|
|
360
371
|
<tr>
|
|
361
372
|
<th>Time</th>
|
|
362
373
|
<th>Project</th>
|
|
363
374
|
<th>Model</th>
|
|
364
|
-
<th class="num">Input</th>
|
|
365
|
-
<th class="num">Output</th>
|
|
366
|
-
<th class="num">Cache R / W</th>
|
|
367
|
-
<th class="num">Cost</th>
|
|
375
|
+
<th class="num"><span class="has-tooltip" data-tooltip="New (uncached) tokens you sent to Claude this turn. Usually small \u2014 most of the conversation comes from cache.">Input <span class="help-icon">i</span></span></th>
|
|
376
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Tokens Claude generated in its response. The most expensive line item \u2014 ~5\xD7 the input rate on Opus.">Output <span class="help-icon">i</span></span></th>
|
|
377
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Cache read / cache write. Reads (~10% of input rate) reuse prior context; writes (~125% of input rate) save new context for future turns.">Cache R / W <span class="help-icon">i</span></span></th>
|
|
378
|
+
<th class="num"><span class="has-tooltip" data-tooltip="Approximate USD cost for this turn \u2014 input \xD7 rate + output \xD7 5\xD7rate + cache_read \xD7 0.1\xD7rate + cache_write \xD7 1.25\xD7rate, using the turn's model.">Cost <span class="help-icon">i</span></span></th>
|
|
368
379
|
</tr>
|
|
369
380
|
</thead>
|
|
370
381
|
<tbody></tbody>
|
|
@@ -373,14 +384,17 @@ var public_default = `<!doctype html>
|
|
|
373
384
|
</section>
|
|
374
385
|
|
|
375
386
|
<section>
|
|
376
|
-
<h2>
|
|
387
|
+
<h2>
|
|
388
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
|
|
389
|
+
Recent gate decisions
|
|
390
|
+
</h2>
|
|
377
391
|
<table id="gates">
|
|
378
392
|
<thead>
|
|
379
393
|
<tr>
|
|
380
394
|
<th>Time</th>
|
|
381
395
|
<th>Project</th>
|
|
382
396
|
<th>Tool</th>
|
|
383
|
-
<th>Decision</th>
|
|
397
|
+
<th><span class="has-tooltip" data-tooltip="ALLOW = Synthra let the tool call through. BLOCK = Synthra intercepted it because the graph already had high-confidence context \u2014 Claude should use graph_continue instead.">Decision <span class="help-icon">i</span></span></th>
|
|
384
398
|
<th>Query</th>
|
|
385
399
|
</tr>
|
|
386
400
|
</thead>
|
|
@@ -391,11 +405,42 @@ var public_default = `<!doctype html>
|
|
|
391
405
|
</main>
|
|
392
406
|
|
|
393
407
|
<footer>
|
|
394
|
-
<span>Token
|
|
395
|
-
<span class="muted">Cost figures are approximate \u2014
|
|
408
|
+
<span>Synthra Token Dashboard \xB7 live polling every 2s</span>
|
|
409
|
+
<span class="muted">Cost figures are approximate \u2014 based on published Anthropic rates.</span>
|
|
396
410
|
</footer>
|
|
397
411
|
|
|
398
412
|
<script>
|
|
413
|
+
// Inline SVG icons. Each is a stroke-based icon, currentColor for the
|
|
414
|
+
// stroke, designed to inherit color from the parent's CSS.
|
|
415
|
+
const ICONS = {
|
|
416
|
+
dollar: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="1" x2="12" y2="23"/><path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/></svg>',
|
|
417
|
+
chat: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',
|
|
418
|
+
arrowDown: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="5" x2="12" y2="19"/><polyline points="19 12 12 19 5 12"/></svg>',
|
|
419
|
+
arrowUp: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="12" y1="19" x2="12" y2="5"/><polyline points="5 12 12 5 19 12"/></svg>',
|
|
420
|
+
refresh: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>',
|
|
421
|
+
save: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><polyline points="17 21 17 13 7 13 7 21"/><polyline points="7 3 7 8 15 8"/></svg>',
|
|
422
|
+
folder: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>',
|
|
423
|
+
shield: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>',
|
|
424
|
+
trending: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="23 6 13.5 15.5 8.5 10.5 1 18"/><polyline points="17 6 23 6 23 12"/></svg>',
|
|
425
|
+
ban: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"/></svg>',
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
// Classify a model name into a family for color-coding.
|
|
429
|
+
function modelFamily(model) {
|
|
430
|
+
if (!model) return 'unknown';
|
|
431
|
+
const m = model.toLowerCase();
|
|
432
|
+
if (m === '<synthetic>') return 'unknown';
|
|
433
|
+
if (m.includes('opus')) return 'opus';
|
|
434
|
+
if (m.includes('sonnet')) return 'sonnet';
|
|
435
|
+
if (m.includes('haiku')) return 'haiku';
|
|
436
|
+
return 'unknown';
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
function modelLabel(model) {
|
|
440
|
+
if (!model || model === '<synthetic>') return model === '<synthetic>' ? 'synthetic' : 'unknown';
|
|
441
|
+
return model;
|
|
442
|
+
}
|
|
443
|
+
|
|
399
444
|
const $ = (sel) => document.querySelector(sel);
|
|
400
445
|
const cardsEl = $("#cards");
|
|
401
446
|
const projectsEl = $("#projects");
|
|
@@ -438,23 +483,84 @@ var public_default = `<!doctype html>
|
|
|
438
483
|
}
|
|
439
484
|
}
|
|
440
485
|
|
|
486
|
+
// Definitions for the global-totals cards. Each: label, value-source key,
|
|
487
|
+
// icon, optional class (accent | money), tooltip text.
|
|
488
|
+
function cardConfigs(g) {
|
|
489
|
+
return [
|
|
490
|
+
{
|
|
491
|
+
label: "Total cost",
|
|
492
|
+
value: fmtCost(g.estimated_cost_usd),
|
|
493
|
+
icon: ICONS.dollar,
|
|
494
|
+
cls: "money",
|
|
495
|
+
tooltip: "Approximate USD cost across all projects. Computed from per-model pricing (Opus, Sonnet, Haiku) applied to each turn's input/output/cache. Tilde everywhere \u2014 real cost depends on Anthropic's current rates.",
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
label: "Turns",
|
|
499
|
+
value: fmt(g.total_turns),
|
|
500
|
+
icon: ICONS.chat,
|
|
501
|
+
tooltip: "Total number of back-and-forth exchanges with Claude across all projects. One turn = you send a message, Claude responds.",
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
label: "Input",
|
|
505
|
+
value: fmt(g.total_input_tokens),
|
|
506
|
+
icon: ICONS.arrowDown,
|
|
507
|
+
tooltip: "New (uncached) tokens sent to Claude across all turns. Usually small \u2014 most of the conversation comes from cache.",
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
label: "Output",
|
|
511
|
+
value: fmt(g.total_output_tokens),
|
|
512
|
+
icon: ICONS.arrowUp,
|
|
513
|
+
tooltip: "Tokens Claude generated in responses. The most expensive line item per turn (~5\xD7 input rate on Opus).",
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
label: "Cache read",
|
|
517
|
+
value: fmt(g.total_cache_read),
|
|
518
|
+
icon: ICONS.refresh,
|
|
519
|
+
tooltip: "Tokens read from Claude's prompt cache \u2014 conversation history, system prompt, Synthra's pack. Cheap: ~10% of the input rate. The bulk of every long session.",
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
label: "Cache write",
|
|
523
|
+
value: fmt(g.total_cache_create),
|
|
524
|
+
icon: ICONS.save,
|
|
525
|
+
tooltip: "Tokens newly added to the prompt cache so future turns can read them cheaply. Premium-priced (~125% of input) but pays back over the rest of the session.",
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
label: "Projects",
|
|
529
|
+
value: fmt(g.project_count),
|
|
530
|
+
icon: ICONS.folder,
|
|
531
|
+
tooltip: "Projects that have ever run \`syn .\` on this machine. Tracked in ~/.synthra/projects.json.",
|
|
532
|
+
},
|
|
533
|
+
{
|
|
534
|
+
label: "Blocked Grep / Glob",
|
|
535
|
+
value: fmt(g.blocked_count),
|
|
536
|
+
icon: ICONS.shield,
|
|
537
|
+
cls: "accent",
|
|
538
|
+
tooltip: "PreToolUse hook intercepts: Synthra blocked these Grep/Glob calls because the graph already had high-confidence context for the query. Claude pivots to graph_continue or graph_read instead.",
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
label: "Tokens saved",
|
|
542
|
+
value: fmt(g.estimated_tokens_saved),
|
|
543
|
+
icon: ICONS.trending,
|
|
544
|
+
cls: "accent",
|
|
545
|
+
tooltip: "Estimated tokens avoided by blocking exploratory Grep/Glob calls. Calculated as blocks \xD7 500 \u2014 conservative; under-counts the cache thrash you also avoid.",
|
|
546
|
+
},
|
|
547
|
+
];
|
|
548
|
+
}
|
|
549
|
+
|
|
441
550
|
function renderCards(g) {
|
|
442
551
|
cardsEl.innerHTML = "";
|
|
443
|
-
const
|
|
444
|
-
{ label: "Total cost", value: fmtCost(g.estimated_cost_usd), accent: true },
|
|
445
|
-
{ label: "Turns", value: fmt(g.total_turns) },
|
|
446
|
-
{ label: "Input", value: fmt(g.total_input_tokens) },
|
|
447
|
-
{ label: "Output", value: fmt(g.total_output_tokens) },
|
|
448
|
-
{ label: "Cache read", value: fmt(g.total_cache_read) },
|
|
449
|
-
{ label: "Cache write", value: fmt(g.total_cache_create) },
|
|
450
|
-
{ label: "Projects", value: fmt(g.project_count) },
|
|
451
|
-
{ label: "Blocked Grep / Glob", value: fmt(g.blocked_count), accent: true },
|
|
452
|
-
{ label: "Tokens saved", value: fmt(g.estimated_tokens_saved), accent: true },
|
|
453
|
-
];
|
|
454
|
-
for (const c of cards) {
|
|
552
|
+
for (const c of cardConfigs(g)) {
|
|
455
553
|
const el = document.createElement("div");
|
|
456
|
-
el.className = "card" + (c.
|
|
457
|
-
el.innerHTML =
|
|
554
|
+
el.className = "card" + (c.cls ? " " + c.cls : "");
|
|
555
|
+
el.innerHTML =
|
|
556
|
+
'<div class="card-head">' +
|
|
557
|
+
'<div class="card-label has-tooltip" data-tooltip="' + c.tooltip.replace(/"/g, '"') + '">' +
|
|
558
|
+
c.label +
|
|
559
|
+
' <span class="help-icon">i</span>' +
|
|
560
|
+
'</div>' +
|
|
561
|
+
'<span class="card-icon">' + c.icon + '</span>' +
|
|
562
|
+
'</div>' +
|
|
563
|
+
'<div class="card-value">' + c.value + '</div>';
|
|
458
564
|
cardsEl.appendChild(el);
|
|
459
565
|
}
|
|
460
566
|
}
|
|
@@ -475,7 +581,7 @@ var public_default = `<!doctype html>
|
|
|
475
581
|
row.className = "project-row";
|
|
476
582
|
row.innerHTML =
|
|
477
583
|
'<div class="project-name">' +
|
|
478
|
-
'<strong>' + p.name + '</strong>' +
|
|
584
|
+
'<strong>' + ICONS.folder + p.name + '</strong>' +
|
|
479
585
|
'<code class="project-path">' + p.path + '</code>' +
|
|
480
586
|
'</div>' +
|
|
481
587
|
'<div class="project-stats">' +
|
|
@@ -497,15 +603,12 @@ var public_default = `<!doctype html>
|
|
|
497
603
|
}
|
|
498
604
|
turnsEmpty.classList.add("hidden");
|
|
499
605
|
for (const t of turns) {
|
|
606
|
+
const family = modelFamily(t.model);
|
|
500
607
|
const tr = document.createElement("tr");
|
|
501
|
-
const modelCell =
|
|
502
|
-
t.model && t.model !== "<synthetic>"
|
|
503
|
-
? "<code>" + t.model + "</code>"
|
|
504
|
-
: '<span class="muted">' + (t.model === "<synthetic>" ? "synthetic" : "unknown") + "</span>";
|
|
505
608
|
tr.innerHTML =
|
|
506
609
|
"<td>" + fmtTs(t.ts) + "</td>" +
|
|
507
610
|
"<td><code>" + t.project_name + "</code></td>" +
|
|
508
|
-
|
|
611
|
+
'<td><span class="model-pill ' + family + '">' + modelLabel(t.model) + "</span></td>" +
|
|
509
612
|
'<td class="num">' + fmtFull(t.input) + "</td>" +
|
|
510
613
|
'<td class="num">' + fmtFull(t.output) + "</td>" +
|
|
511
614
|
'<td class="num">' + fmt(t.cache_read) + " / " + fmt(t.cache_create) + "</td>" +
|
|
@@ -523,12 +626,16 @@ var public_default = `<!doctype html>
|
|
|
523
626
|
gatesEmpty.classList.add("hidden");
|
|
524
627
|
for (const g of gates) {
|
|
525
628
|
const tr = document.createElement("tr");
|
|
526
|
-
const
|
|
629
|
+
const isBlock = g.decision === "block";
|
|
630
|
+
const cls = isBlock ? "decision-block" : "decision-allow";
|
|
631
|
+
const label = isBlock
|
|
632
|
+
? '<span class="' + cls + '">' + ICONS.ban + ' BLOCK</span>'
|
|
633
|
+
: '<span class="' + cls + '">ALLOW</span>';
|
|
527
634
|
tr.innerHTML =
|
|
528
635
|
"<td>" + fmtTs(g.ts) + "</td>" +
|
|
529
636
|
"<td><code>" + g.project_name + "</code></td>" +
|
|
530
637
|
"<td><code>" + g.tool + "</code></td>" +
|
|
531
|
-
|
|
638
|
+
"<td>" + label + "</td>" +
|
|
532
639
|
"<td><code>" + (g.query || "") + "</code></td>";
|
|
533
640
|
gatesBody.appendChild(tr);
|
|
534
641
|
}
|
|
@@ -562,7 +669,628 @@ var public_default = `<!doctype html>
|
|
|
562
669
|
`;
|
|
563
670
|
|
|
564
671
|
// src/dashboard/public/style.css
|
|
565
|
-
var style_default =
|
|
672
|
+
var style_default = `/* Synthra token dashboard \u2014 palette per project brief.
|
|
673
|
+
Base: cream-on-near-black, dark-red borders, hot-pink highlights.
|
|
674
|
+
Plus: money green for dollar amounts, per-family model colors,
|
|
675
|
+
subtle dot grid + top glow background, tooltip system, icons. */
|
|
676
|
+
|
|
677
|
+
:root {
|
|
678
|
+
/* Brand */
|
|
679
|
+
--color-heading: #ECEBD8;
|
|
680
|
+
--color-body: #EDECD9;
|
|
681
|
+
--color-bg: #000000;
|
|
682
|
+
--color-surface: #140009;
|
|
683
|
+
--color-surface-raised: #1E000D;
|
|
684
|
+
--color-border: #4D0020;
|
|
685
|
+
--color-accent: #FF0073;
|
|
686
|
+
--color-accent-darker: #EB006A;
|
|
687
|
+
--color-form-bg: #2E0014;
|
|
688
|
+
--color-muted: rgba(237, 236, 217, 0.55);
|
|
689
|
+
--color-very-muted: rgba(237, 236, 217, 0.35);
|
|
690
|
+
--color-block: #FF0073;
|
|
691
|
+
--color-allow: #ECEBD8;
|
|
692
|
+
|
|
693
|
+
/* Money green \u2014 used everywhere a $ amount appears */
|
|
694
|
+
--color-money: #36E596;
|
|
695
|
+
--color-money-darker: #00B85F;
|
|
696
|
+
--color-money-bg: rgba(54, 229, 150, 0.08);
|
|
697
|
+
|
|
698
|
+
/* Per-family model colors */
|
|
699
|
+
--color-model-opus: #C9A2FF;
|
|
700
|
+
--color-model-sonnet: #6BD0FF;
|
|
701
|
+
--color-model-haiku: #7BFFC7;
|
|
702
|
+
|
|
703
|
+
/* Background layering */
|
|
704
|
+
--bg-dot-color: rgba(237, 236, 217, 0.045);
|
|
705
|
+
--bg-glow-color: rgba(255, 0, 115, 0.07);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
* {
|
|
709
|
+
box-sizing: border-box;
|
|
710
|
+
margin: 0;
|
|
711
|
+
padding: 0;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
html, body {
|
|
715
|
+
background-color: var(--color-bg);
|
|
716
|
+
color: var(--color-body);
|
|
717
|
+
font-family:
|
|
718
|
+
ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI",
|
|
719
|
+
system-ui, sans-serif;
|
|
720
|
+
font-size: 14px;
|
|
721
|
+
line-height: 1.5;
|
|
722
|
+
min-height: 100vh;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/* Body becomes a flex column so main can grow + header/footer stay sticky
|
|
726
|
+
at the natural top/bottom of the viewport. */
|
|
727
|
+
body {
|
|
728
|
+
display: flex;
|
|
729
|
+
flex-direction: column;
|
|
730
|
+
min-height: 100vh;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
main {
|
|
734
|
+
flex: 1;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
/* Layered backdrop: dot grid + soft pink glow at the top.
|
|
738
|
+
Both are fixed so they don't repeat as you scroll. */
|
|
739
|
+
body {
|
|
740
|
+
background-image:
|
|
741
|
+
radial-gradient(ellipse 70% 40% at 50% 0%, var(--bg-glow-color), transparent 70%),
|
|
742
|
+
radial-gradient(circle at 1px 1px, var(--bg-dot-color) 1px, transparent 0);
|
|
743
|
+
background-size: 100% 100%, 22px 22px;
|
|
744
|
+
background-attachment: fixed;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
code, .num, table, .project-path {
|
|
748
|
+
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
header {
|
|
752
|
+
display: flex;
|
|
753
|
+
align-items: center;
|
|
754
|
+
gap: 1.5rem;
|
|
755
|
+
padding: 1.1rem 2rem;
|
|
756
|
+
background: linear-gradient(180deg, rgba(20, 0, 9, 0.7), rgba(20, 0, 9, 0.4));
|
|
757
|
+
backdrop-filter: blur(8px);
|
|
758
|
+
border-bottom: 1px solid var(--color-border);
|
|
759
|
+
position: sticky;
|
|
760
|
+
top: 0;
|
|
761
|
+
z-index: 5;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
header .brand {
|
|
765
|
+
display: flex;
|
|
766
|
+
align-items: baseline;
|
|
767
|
+
gap: 0.75rem;
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
header h1 {
|
|
771
|
+
color: var(--color-heading);
|
|
772
|
+
font-size: 1.35rem;
|
|
773
|
+
font-weight: 700;
|
|
774
|
+
letter-spacing: 0.02em;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
header .tag {
|
|
778
|
+
color: var(--color-muted);
|
|
779
|
+
font-size: 0.78rem;
|
|
780
|
+
text-transform: uppercase;
|
|
781
|
+
letter-spacing: 0.1em;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
header .meta {
|
|
785
|
+
margin-left: auto;
|
|
786
|
+
display: flex;
|
|
787
|
+
align-items: center;
|
|
788
|
+
gap: 0.75rem;
|
|
789
|
+
font-size: 0.78rem;
|
|
790
|
+
font-family: ui-monospace, monospace;
|
|
791
|
+
color: var(--color-muted);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
header .active-project {
|
|
795
|
+
max-width: 480px;
|
|
796
|
+
white-space: nowrap;
|
|
797
|
+
overflow: hidden;
|
|
798
|
+
text-overflow: ellipsis;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
main {
|
|
802
|
+
padding: 2rem;
|
|
803
|
+
display: flex;
|
|
804
|
+
flex-direction: column;
|
|
805
|
+
gap: 2rem;
|
|
806
|
+
max-width: 1400px;
|
|
807
|
+
margin: 0 auto;
|
|
808
|
+
width: 100%;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
section {
|
|
812
|
+
display: flex;
|
|
813
|
+
flex-direction: column;
|
|
814
|
+
gap: 0.85rem;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
h2 {
|
|
818
|
+
color: var(--color-heading);
|
|
819
|
+
font-size: 0.85rem;
|
|
820
|
+
font-weight: 600;
|
|
821
|
+
letter-spacing: 0.08em;
|
|
822
|
+
text-transform: uppercase;
|
|
823
|
+
display: flex;
|
|
824
|
+
align-items: center;
|
|
825
|
+
gap: 0.5rem;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
h2 svg {
|
|
829
|
+
width: 14px;
|
|
830
|
+
height: 14px;
|
|
831
|
+
opacity: 0.5;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
h2 .muted {
|
|
835
|
+
color: var(--color-very-muted);
|
|
836
|
+
font-size: 0.78rem;
|
|
837
|
+
font-weight: 400;
|
|
838
|
+
letter-spacing: 0.06em;
|
|
839
|
+
text-transform: none;
|
|
840
|
+
margin-left: 0.5rem;
|
|
841
|
+
}
|
|
842
|
+
|
|
843
|
+
/* ============================================================
|
|
844
|
+
Cards row (Global totals)
|
|
845
|
+
============================================================ */
|
|
846
|
+
|
|
847
|
+
.cards {
|
|
848
|
+
display: grid;
|
|
849
|
+
grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
|
|
850
|
+
gap: 0.7rem;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.card {
|
|
854
|
+
position: relative;
|
|
855
|
+
background: var(--color-surface);
|
|
856
|
+
border: 1px solid var(--color-border);
|
|
857
|
+
border-radius: 8px;
|
|
858
|
+
padding: 0.95rem 1rem 0.85rem;
|
|
859
|
+
transition: transform 120ms ease, border-color 120ms ease;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
.card:hover {
|
|
863
|
+
transform: translateY(-1px);
|
|
864
|
+
border-color: rgba(77, 0, 32, 0.85);
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
.card.accent {
|
|
868
|
+
background: var(--color-surface-raised);
|
|
869
|
+
border-color: var(--color-accent);
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
.card.money {
|
|
873
|
+
background: linear-gradient(180deg, var(--color-money-bg), transparent 80%), var(--color-surface);
|
|
874
|
+
border-color: var(--color-money-darker);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
.card.money:hover {
|
|
878
|
+
border-color: var(--color-money);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
.card-head {
|
|
882
|
+
display: flex;
|
|
883
|
+
align-items: center;
|
|
884
|
+
justify-content: space-between;
|
|
885
|
+
gap: 0.5rem;
|
|
886
|
+
margin-bottom: 0.4rem;
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
.card-label {
|
|
890
|
+
color: var(--color-muted);
|
|
891
|
+
font-size: 0.66rem;
|
|
892
|
+
text-transform: uppercase;
|
|
893
|
+
letter-spacing: 0.09em;
|
|
894
|
+
display: flex;
|
|
895
|
+
align-items: center;
|
|
896
|
+
gap: 0.35rem;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.card-icon {
|
|
900
|
+
width: 14px;
|
|
901
|
+
height: 14px;
|
|
902
|
+
color: var(--color-muted);
|
|
903
|
+
opacity: 0.65;
|
|
904
|
+
flex-shrink: 0;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
.card.accent .card-icon { color: var(--color-accent); opacity: 0.85; }
|
|
908
|
+
.card.money .card-icon { color: var(--color-money); opacity: 0.85; }
|
|
909
|
+
|
|
910
|
+
.card-value {
|
|
911
|
+
color: var(--color-heading);
|
|
912
|
+
font-family: ui-monospace, monospace;
|
|
913
|
+
font-size: 1.5rem;
|
|
914
|
+
font-weight: 600;
|
|
915
|
+
letter-spacing: -0.01em;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.card.accent .card-value { color: var(--color-accent); }
|
|
919
|
+
.card.money .card-value { color: var(--color-money); }
|
|
920
|
+
|
|
921
|
+
/* ============================================================
|
|
922
|
+
Tooltip (data-tooltip on .has-tooltip)
|
|
923
|
+
============================================================ */
|
|
924
|
+
|
|
925
|
+
.has-tooltip {
|
|
926
|
+
position: relative;
|
|
927
|
+
cursor: help;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
.has-tooltip::before,
|
|
931
|
+
.has-tooltip::after {
|
|
932
|
+
position: absolute;
|
|
933
|
+
pointer-events: none;
|
|
934
|
+
opacity: 0;
|
|
935
|
+
transition: opacity 150ms ease, transform 150ms ease;
|
|
936
|
+
z-index: 100;
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.has-tooltip::after {
|
|
940
|
+
content: attr(data-tooltip);
|
|
941
|
+
bottom: calc(100% + 10px);
|
|
942
|
+
left: 50%;
|
|
943
|
+
transform: translate(-50%, 4px);
|
|
944
|
+
background: var(--color-surface-raised);
|
|
945
|
+
color: var(--color-body);
|
|
946
|
+
border: 1px solid var(--color-border);
|
|
947
|
+
border-radius: 6px;
|
|
948
|
+
padding: 0.6rem 0.75rem;
|
|
949
|
+
font-size: 0.74rem;
|
|
950
|
+
font-weight: 400;
|
|
951
|
+
text-transform: none;
|
|
952
|
+
letter-spacing: 0;
|
|
953
|
+
white-space: normal;
|
|
954
|
+
width: 260px;
|
|
955
|
+
text-align: left;
|
|
956
|
+
line-height: 1.45;
|
|
957
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.7);
|
|
958
|
+
}
|
|
959
|
+
|
|
960
|
+
.has-tooltip::before {
|
|
961
|
+
content: "";
|
|
962
|
+
bottom: calc(100% + 4px);
|
|
963
|
+
left: 50%;
|
|
964
|
+
transform: translate(-50%, 4px);
|
|
965
|
+
border: 6px solid transparent;
|
|
966
|
+
border-top-color: var(--color-border);
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
.has-tooltip:hover::after,
|
|
970
|
+
.has-tooltip:hover::before {
|
|
971
|
+
opacity: 1;
|
|
972
|
+
transform: translate(-50%, 0);
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
/* Small \u24D8 icon used to indicate tooltips */
|
|
976
|
+
.help-icon {
|
|
977
|
+
display: inline-flex;
|
|
978
|
+
align-items: center;
|
|
979
|
+
justify-content: center;
|
|
980
|
+
width: 13px;
|
|
981
|
+
height: 13px;
|
|
982
|
+
border-radius: 50%;
|
|
983
|
+
border: 1px solid var(--color-muted);
|
|
984
|
+
color: var(--color-muted);
|
|
985
|
+
font-size: 9px;
|
|
986
|
+
font-weight: 600;
|
|
987
|
+
font-family: ui-sans-serif, sans-serif;
|
|
988
|
+
line-height: 1;
|
|
989
|
+
cursor: help;
|
|
990
|
+
user-select: none;
|
|
991
|
+
transition: color 120ms, border-color 120ms;
|
|
992
|
+
}
|
|
993
|
+
|
|
994
|
+
.has-tooltip:hover .help-icon {
|
|
995
|
+
border-color: var(--color-accent);
|
|
996
|
+
color: var(--color-accent);
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
.card.money .has-tooltip:hover .help-icon { border-color: var(--color-money); color: var(--color-money); }
|
|
1000
|
+
|
|
1001
|
+
/* ============================================================
|
|
1002
|
+
Projects list
|
|
1003
|
+
============================================================ */
|
|
1004
|
+
|
|
1005
|
+
.projects {
|
|
1006
|
+
display: flex;
|
|
1007
|
+
flex-direction: column;
|
|
1008
|
+
gap: 0.6rem;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
.project-row {
|
|
1012
|
+
display: grid;
|
|
1013
|
+
grid-template-columns: minmax(220px, 1fr) auto;
|
|
1014
|
+
grid-template-rows: auto auto;
|
|
1015
|
+
gap: 0.6rem 1.25rem;
|
|
1016
|
+
align-items: center;
|
|
1017
|
+
background: var(--color-surface);
|
|
1018
|
+
border: 1px solid var(--color-border);
|
|
1019
|
+
border-radius: 8px;
|
|
1020
|
+
padding: 0.9rem 1.2rem;
|
|
1021
|
+
transition: background 120ms ease;
|
|
1022
|
+
}
|
|
1023
|
+
|
|
1024
|
+
.project-row:hover {
|
|
1025
|
+
background: var(--color-surface-raised);
|
|
1026
|
+
}
|
|
1027
|
+
|
|
1028
|
+
.project-name {
|
|
1029
|
+
display: flex;
|
|
1030
|
+
flex-direction: column;
|
|
1031
|
+
gap: 0.15rem;
|
|
1032
|
+
overflow: hidden;
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
.project-name strong {
|
|
1036
|
+
color: var(--color-heading);
|
|
1037
|
+
font-size: 0.95rem;
|
|
1038
|
+
font-weight: 600;
|
|
1039
|
+
display: flex;
|
|
1040
|
+
align-items: center;
|
|
1041
|
+
gap: 0.4rem;
|
|
1042
|
+
}
|
|
1043
|
+
|
|
1044
|
+
.project-name strong svg {
|
|
1045
|
+
width: 13px;
|
|
1046
|
+
height: 13px;
|
|
1047
|
+
opacity: 0.65;
|
|
1048
|
+
color: var(--color-muted);
|
|
1049
|
+
flex-shrink: 0;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
.project-name .project-path {
|
|
1053
|
+
color: var(--color-very-muted);
|
|
1054
|
+
font-size: 0.72rem;
|
|
1055
|
+
white-space: nowrap;
|
|
1056
|
+
overflow: hidden;
|
|
1057
|
+
text-overflow: ellipsis;
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
.project-stats {
|
|
1061
|
+
display: flex;
|
|
1062
|
+
gap: 1.6rem;
|
|
1063
|
+
justify-self: end;
|
|
1064
|
+
text-align: right;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
.stat {
|
|
1068
|
+
display: flex;
|
|
1069
|
+
flex-direction: column;
|
|
1070
|
+
gap: 0.15rem;
|
|
1071
|
+
min-width: 70px;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
.stat-value {
|
|
1075
|
+
color: var(--color-heading);
|
|
1076
|
+
font-family: ui-monospace, monospace;
|
|
1077
|
+
font-size: 0.95rem;
|
|
1078
|
+
font-weight: 600;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
.stat-value.cost {
|
|
1082
|
+
color: var(--color-money);
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
.stat-label {
|
|
1086
|
+
color: var(--color-muted);
|
|
1087
|
+
font-size: 0.66rem;
|
|
1088
|
+
text-transform: uppercase;
|
|
1089
|
+
letter-spacing: 0.08em;
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
.bar {
|
|
1093
|
+
grid-column: 1 / -1;
|
|
1094
|
+
height: 3px;
|
|
1095
|
+
background: var(--color-form-bg);
|
|
1096
|
+
border-radius: 2px;
|
|
1097
|
+
overflow: hidden;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1100
|
+
.bar-fill {
|
|
1101
|
+
height: 100%;
|
|
1102
|
+
background: linear-gradient(90deg, var(--color-accent-darker), var(--color-accent));
|
|
1103
|
+
border-radius: 2px;
|
|
1104
|
+
transition: width 400ms ease;
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
/* ============================================================
|
|
1108
|
+
Tables
|
|
1109
|
+
============================================================ */
|
|
1110
|
+
|
|
1111
|
+
table {
|
|
1112
|
+
width: 100%;
|
|
1113
|
+
border-collapse: collapse;
|
|
1114
|
+
font-size: 0.83rem;
|
|
1115
|
+
background: var(--color-surface);
|
|
1116
|
+
border: 1px solid var(--color-border);
|
|
1117
|
+
border-radius: 8px;
|
|
1118
|
+
overflow: hidden;
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1121
|
+
table thead th {
|
|
1122
|
+
text-align: left;
|
|
1123
|
+
color: var(--color-muted);
|
|
1124
|
+
text-transform: uppercase;
|
|
1125
|
+
font-size: 0.66rem;
|
|
1126
|
+
letter-spacing: 0.08em;
|
|
1127
|
+
font-weight: 600;
|
|
1128
|
+
padding: 0.65rem 0.85rem;
|
|
1129
|
+
border-bottom: 1px solid var(--color-border);
|
|
1130
|
+
background: var(--color-surface);
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
table thead th.num {
|
|
1134
|
+
text-align: right;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
table thead th .has-tooltip {
|
|
1138
|
+
display: inline-flex;
|
|
1139
|
+
align-items: center;
|
|
1140
|
+
gap: 0.3rem;
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
table tbody td {
|
|
1144
|
+
padding: 0.55rem 0.85rem;
|
|
1145
|
+
border-bottom: 1px solid rgba(77, 0, 32, 0.4);
|
|
1146
|
+
color: var(--color-body);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
table tbody td.num {
|
|
1150
|
+
text-align: right;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
table tbody td.cost {
|
|
1154
|
+
color: var(--color-money);
|
|
1155
|
+
font-weight: 600;
|
|
1156
|
+
}
|
|
1157
|
+
|
|
1158
|
+
table tbody tr:last-child td {
|
|
1159
|
+
border-bottom: none;
|
|
1160
|
+
}
|
|
1161
|
+
|
|
1162
|
+
table tbody tr:hover {
|
|
1163
|
+
background: var(--color-surface-raised);
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
/* ============================================================
|
|
1167
|
+
Model pills \u2014 color-coded by family
|
|
1168
|
+
============================================================ */
|
|
1169
|
+
|
|
1170
|
+
.model-pill {
|
|
1171
|
+
display: inline-block;
|
|
1172
|
+
padding: 0.1rem 0.5rem;
|
|
1173
|
+
border-radius: 3px;
|
|
1174
|
+
background: var(--color-form-bg);
|
|
1175
|
+
font-family: ui-monospace, monospace;
|
|
1176
|
+
font-size: 0.82em;
|
|
1177
|
+
border: 1px solid transparent;
|
|
1178
|
+
color: var(--color-body);
|
|
1179
|
+
white-space: nowrap;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
.model-pill.opus {
|
|
1183
|
+
color: var(--color-model-opus);
|
|
1184
|
+
border-color: rgba(201, 162, 255, 0.3);
|
|
1185
|
+
background: rgba(201, 162, 255, 0.08);
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
.model-pill.sonnet {
|
|
1189
|
+
color: var(--color-model-sonnet);
|
|
1190
|
+
border-color: rgba(107, 208, 255, 0.3);
|
|
1191
|
+
background: rgba(107, 208, 255, 0.08);
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
.model-pill.haiku {
|
|
1195
|
+
color: var(--color-model-haiku);
|
|
1196
|
+
border-color: rgba(123, 255, 199, 0.3);
|
|
1197
|
+
background: rgba(123, 255, 199, 0.08);
|
|
1198
|
+
}
|
|
1199
|
+
|
|
1200
|
+
.model-pill.unknown {
|
|
1201
|
+
color: var(--color-muted);
|
|
1202
|
+
font-style: italic;
|
|
1203
|
+
border-color: rgba(237, 236, 217, 0.15);
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
/* Existing inline code in tables (project name, etc.) */
|
|
1207
|
+
code {
|
|
1208
|
+
color: var(--color-heading);
|
|
1209
|
+
background: var(--color-form-bg);
|
|
1210
|
+
padding: 0.1rem 0.4rem;
|
|
1211
|
+
border-radius: 3px;
|
|
1212
|
+
font-size: 0.85em;
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
/* ============================================================
|
|
1216
|
+
Decisions (allow / block)
|
|
1217
|
+
============================================================ */
|
|
1218
|
+
|
|
1219
|
+
.decision-block {
|
|
1220
|
+
color: var(--color-block);
|
|
1221
|
+
font-weight: 700;
|
|
1222
|
+
text-transform: uppercase;
|
|
1223
|
+
font-size: 0.72rem;
|
|
1224
|
+
letter-spacing: 0.06em;
|
|
1225
|
+
display: inline-flex;
|
|
1226
|
+
align-items: center;
|
|
1227
|
+
gap: 0.3rem;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
.decision-block svg {
|
|
1231
|
+
width: 11px;
|
|
1232
|
+
height: 11px;
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
.decision-allow {
|
|
1236
|
+
color: var(--color-allow);
|
|
1237
|
+
opacity: 0.7;
|
|
1238
|
+
text-transform: uppercase;
|
|
1239
|
+
font-size: 0.72rem;
|
|
1240
|
+
letter-spacing: 0.06em;
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
.empty {
|
|
1244
|
+
color: var(--color-muted);
|
|
1245
|
+
font-style: italic;
|
|
1246
|
+
padding: 1rem;
|
|
1247
|
+
background: var(--color-surface);
|
|
1248
|
+
border: 1px dashed var(--color-border);
|
|
1249
|
+
border-radius: 8px;
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
.hidden {
|
|
1253
|
+
display: none;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
footer {
|
|
1257
|
+
display: flex;
|
|
1258
|
+
justify-content: space-between;
|
|
1259
|
+
align-items: center;
|
|
1260
|
+
padding: 0.85rem 2rem;
|
|
1261
|
+
background: linear-gradient(0deg, rgba(20, 0, 9, 0.7), rgba(20, 0, 9, 0.4));
|
|
1262
|
+
backdrop-filter: blur(8px);
|
|
1263
|
+
border-top: 1px solid var(--color-border);
|
|
1264
|
+
color: var(--color-muted);
|
|
1265
|
+
font-size: 0.72rem;
|
|
1266
|
+
font-family: ui-monospace, monospace;
|
|
1267
|
+
position: sticky;
|
|
1268
|
+
bottom: 0;
|
|
1269
|
+
z-index: 5;
|
|
1270
|
+
}
|
|
1271
|
+
|
|
1272
|
+
footer .muted {
|
|
1273
|
+
color: var(--color-very-muted);
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
.dot {
|
|
1277
|
+
width: 8px;
|
|
1278
|
+
height: 8px;
|
|
1279
|
+
border-radius: 50%;
|
|
1280
|
+
background: var(--color-muted);
|
|
1281
|
+
transition: background 200ms ease, box-shadow 200ms ease;
|
|
1282
|
+
}
|
|
1283
|
+
|
|
1284
|
+
.dot.live {
|
|
1285
|
+
background: var(--color-money);
|
|
1286
|
+
box-shadow: 0 0 8px var(--color-money-darker);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
.dot.dead {
|
|
1290
|
+
background: var(--color-border);
|
|
1291
|
+
box-shadow: none;
|
|
1292
|
+
}
|
|
1293
|
+
`;
|
|
566
1294
|
|
|
567
1295
|
// src/dashboard/server.ts
|
|
568
1296
|
var FALLBACK_RANGE = 9;
|