@enigmax/dashboard 0.1.14 → 0.1.16

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 (2) hide show
  1. package/assets/index.html +92 -43
  2. package/package.json +1 -1
package/assets/index.html CHANGED
@@ -6,19 +6,34 @@
6
6
  <title>Enigma - Dashboard</title>
7
7
  <style>
8
8
  :root {
9
- --bg: #0b0e14; --surface: #151a23; --surface2: #1b2230; --border: #232a36;
10
- --text: #e6e6e6; --muted: #8a93a3; --accent: #e0a458; --accent2: #d7875f; --good: #6fcf97;
9
+ /* Core palette. --accent / --muted / --border are PINNED: the chart hardcodes
10
+ these exact values, so the dashboard and the graph always stay in sync. */
11
+ --bg: #080a10; --surface: #12161f; --surface2: #1a1f2b;
12
+ --border: #232a36; --border-soft: #1b212d;
13
+ --text: #eceef2; --muted: #8a93a3; --accent: #e0a458; --accent2: #d7875f; --good: #6fcf97;
14
+ --accent-weak: rgba(224,164,88,0.13); --good-weak: rgba(111,207,151,0.12);
11
15
  /* Type roles: a monospace "machine readout" face carries the brand, headings,
12
16
  labels and numeric data (this is a CLI tool's dashboard); sans carries prose. */
13
17
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
14
18
  --sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
15
19
  --ring: rgba(224,164,88,0.6);
20
+ --radius: 16px; --radius-sm: 10px;
21
+ /* Lit-surface system: a faint top highlight + two shadow steps give depth. */
22
+ --elev: linear-gradient(180deg, rgba(255,255,255,0.045), rgba(255,255,255,0) 42%);
23
+ --shadow-1: 0 1px 2px rgba(0,0,0,0.4);
24
+ --shadow-2: 0 18px 40px -22px rgba(0,0,0,0.75);
16
25
  }
17
26
  * { box-sizing: border-box; }
18
27
  body {
19
- margin: 0; background: var(--bg); color: var(--text);
20
- font-family: var(--sans);
21
- -webkit-font-smoothing: antialiased; padding: 24px; max-width: 2200px; margin: 0 auto;
28
+ margin: 0 auto; color: var(--text); font-family: var(--sans);
29
+ /* Atmospheric depth: a faint amber glow upper-right (the brand accent) and a
30
+ cooler one lower-left over a near-black base, fixed so the page feels lit. */
31
+ background:
32
+ radial-gradient(1100px 620px at 82% -10%, rgba(224,164,88,0.10), transparent 58%),
33
+ radial-gradient(820px 520px at 2% 2%, rgba(111,207,151,0.045), transparent 52%),
34
+ var(--bg);
35
+ background-attachment: fixed;
36
+ -webkit-font-smoothing: antialiased; padding: 30px 30px 48px; max-width: 1560px;
22
37
  }
23
38
  a { color: var(--accent2); }
24
39
  /* Quality floor: one visible keyboard-focus ring for every interactive control
@@ -33,47 +48,60 @@
33
48
  transition-duration: 0.01ms !important;
34
49
  }
35
50
  }
36
- header { display: flex; align-items: center; gap: 20px; margin-bottom: 24px; flex-wrap: wrap; }
51
+ header { display: flex; align-items: center; gap: 22px; margin-bottom: 28px; flex-wrap: wrap; }
37
52
  .brand { display: flex; flex-direction: column; gap: 3px; }
38
53
  .wordmark {
39
- font-family: var(--mono); font-size: 19px; font-weight: 600; letter-spacing: 0.5px;
40
- display: inline-flex; align-items: center;
54
+ font-family: var(--mono); font-size: 20px; font-weight: 600; letter-spacing: 0.5px;
55
+ display: inline-flex; align-items: center; color: var(--text);
41
56
  }
42
57
  /* Signature: a blinking block caret turns the wordmark into a live terminal prompt. */
43
58
  .wordmark span {
44
- display: inline-block; width: 0.46em; height: 1.05em; margin-left: 4px;
59
+ display: inline-block; width: 0.46em; height: 1.05em; margin-left: 5px;
45
60
  background: var(--accent); transform: translateY(1px); text-indent: -9999px; overflow: hidden;
46
- animation: caret 1.1s steps(1, end) infinite;
61
+ box-shadow: 0 0 12px var(--accent-weak); animation: caret 1.1s steps(1, end) infinite;
47
62
  }
48
63
  @keyframes caret { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
49
- .sub { font-family: var(--mono); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 1.4px; }
50
- .tabs { display: flex; gap: 4px; }
64
+ .sub { font-family: var(--mono); color: var(--muted); font-size: 10.5px; text-transform: uppercase; letter-spacing: 1.6px; }
65
+ /* Tabs as a segmented control: one inset track, the active tab a raised accent pill. */
66
+ .tabs { display: flex; gap: 2px; padding: 4px; background: rgba(0,0,0,0.25); border: 1px solid var(--border-soft); border-radius: 13px; }
51
67
  .tabs .tab {
52
68
  font-family: var(--mono); text-decoration: none; color: var(--muted); font-size: 12px; font-weight: 600;
53
- padding: 7px 14px; border-radius: 8px; border: 1px solid transparent; transition: background .15s, color .15s, border-color .15s;
69
+ padding: 7px 15px; border-radius: 9px; border: 1px solid transparent; transition: background .15s, color .15s, border-color .15s;
54
70
  }
55
- .tabs .tab:hover { color: var(--text); background: var(--surface); }
56
- .tabs .tab.active { color: var(--accent); background: var(--surface); border-color: var(--border); }
57
- .live { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; font-family: var(--mono); }
58
- .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); }
71
+ .tabs .tab:hover { color: var(--text); }
72
+ .tabs .tab.active { color: var(--accent); background: var(--surface2); border-color: var(--border); box-shadow: var(--shadow-1); }
73
+ .live { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 12px; font-family: var(--mono); padding: 5px 12px; background: rgba(0,0,0,0.25); border: 1px solid var(--border-soft); border-radius: 999px; }
74
+ .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px var(--good); }
59
75
  .dot.stale { background: var(--muted); box-shadow: none; }
60
- .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-bottom: 20px; }
61
- .card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 16px; transition: border-color .15s; }
62
- .card:hover { border-color: var(--surface2); }
63
- .card .label { font-family: var(--mono); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.7px; }
64
- .card .value { font-family: var(--mono); font-size: 28px; font-weight: 600; margin-top: 8px; font-variant-numeric: tabular-nums; letter-spacing: -0.5px; }
76
+ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(166px, 1fr)); gap: 14px; margin-bottom: 22px; }
77
+ .card {
78
+ position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
79
+ padding: 18px; box-shadow: var(--shadow-1); overflow: hidden;
80
+ transition: border-color .18s, transform .18s, box-shadow .18s;
81
+ }
82
+ /* A faint top-edge highlight so a card reads as a lit surface, not a flat rectangle. */
83
+ .card::before { content: ""; position: absolute; inset: 0; background: var(--elev); pointer-events: none; }
84
+ .card:hover { border-color: #2f3744; transform: translateY(-2px); box-shadow: var(--shadow-1), var(--shadow-2); }
85
+ /* Hero KPI (Money Saved): spans two columns, accent-lit - the loudest thing on the page. */
86
+ .card.hero { grid-column: span 2; border-color: rgba(224,164,88,0.35); background: linear-gradient(135deg, var(--accent-weak), transparent 62%), var(--surface); }
87
+ .card.hero .value { font-size: 42px; }
88
+ .card .label { position: relative; font-family: var(--mono); color: var(--muted); font-size: 11px; text-transform: uppercase; letter-spacing: 0.7px; }
89
+ .card .value { position: relative; font-family: var(--mono); font-size: 30px; font-weight: 600; margin-top: 10px; font-variant-numeric: tabular-nums; letter-spacing: -0.6px; }
65
90
  .card .value.accent { color: var(--accent); }
66
91
  .card .value.good { color: var(--good); }
67
- .card .foot { color: var(--muted); font-size: 12px; margin-top: 4px; }
68
- .panel { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 18px; margin-bottom: 20px; }
69
- .panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
70
- .panel h2 { font-family: var(--mono); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.8px; margin: 0; color: var(--text); }
71
- .panel h2 small { font-family: var(--sans); color: var(--muted); font-weight: 400; font-size: 12px; text-transform: none; letter-spacing: 0; margin-left: 8px; }
92
+ .card .foot { position: relative; color: var(--muted); font-size: 12px; margin-top: 5px; }
93
+ .panel { position: relative; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px 22px; margin-bottom: 18px; box-shadow: var(--shadow-1); }
94
+ .panel-head { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
95
+ /* Section heading: a mono eyebrow led by a short accent rule (structure as signal). */
96
+ .panel h2 { display: flex; align-items: center; gap: 10px; font-family: var(--mono); font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.9px; margin: 0; color: var(--text); }
97
+ .panel h2::before { content: ""; flex: 0 0 auto; width: 3px; height: 13px; border-radius: 2px; background: var(--accent); }
98
+ .panel h2 small { font-family: var(--sans); color: var(--muted); font-weight: 400; font-size: 12px; text-transform: none; letter-spacing: 0; }
72
99
  .ctrls { margin-left: auto; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
73
- .ranges { display: flex; gap: 4px; }
100
+ .ranges { display: flex; gap: 2px; padding: 3px; background: rgba(0,0,0,0.22); border: 1px solid var(--border-soft); border-radius: 9px; }
74
101
  .ranges button {
75
- background: var(--surface2); color: var(--muted); border: 1px solid var(--border);
76
- border-radius: 7px; padding: 4px 10px; font-size: 12px; cursor: pointer; font-family: inherit;
102
+ background: transparent; color: var(--muted); border: 1px solid transparent;
103
+ border-radius: 6px; padding: 4px 11px; font-size: 12px; cursor: pointer; font-family: var(--mono);
104
+ transition: color .15s, background .15s, border-color .15s;
77
105
  }
78
106
  .ranges button:hover { color: var(--text); }
79
107
  .ranges button.active { background: var(--accent); color: #1a1206; border-color: var(--accent); font-weight: 600; }
@@ -92,20 +120,22 @@
92
120
  }
93
121
  .tip .tip-d { color: var(--muted); }
94
122
  .tip .tip-v { color: var(--accent); font-weight: 600; margin-top: 2px; }
95
- .bar-row { display: flex; align-items: center; gap: 12px; margin: 10px 0; font-size: 13px; }
123
+ .bar-row { display: flex; align-items: center; gap: 12px; margin: 11px 0; font-size: 13px; }
96
124
  .bar-row .name { width: 70px; color: var(--muted); }
97
- .bar-track { flex: 1; height: 14px; background: var(--surface2); border-radius: 7px; overflow: hidden; }
98
- .bar-fill { height: 100%; border-radius: 7px; }
99
- .bar-row .num { width: 90px; text-align: right; font-variant-numeric: tabular-nums; }
100
- .bar-row .money { width: 78px; text-align: right; color: var(--good); font-variant-numeric: tabular-nums; }
125
+ .bar-track { flex: 1; height: 12px; background: rgba(0,0,0,0.32); border: 1px solid var(--border-soft); border-radius: 999px; overflow: hidden; }
126
+ .bar-fill { height: 100%; border-radius: 999px; transition: width .4s cubic-bezier(.4,0,.2,1); }
127
+ .bar-row .num { width: 90px; text-align: right; font-family: var(--mono); font-variant-numeric: tabular-nums; }
128
+ .bar-row .money { width: 78px; text-align: right; color: var(--good); font-family: var(--mono); font-variant-numeric: tabular-nums; }
101
129
  .empty { color: var(--muted); font-size: 14px; text-align: center; padding: 40px 0; }
102
130
  .tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
103
- .tbl th { text-align: left; color: var(--muted); font-weight: 500; font-size: 11px; text-transform: uppercase; letter-spacing: 0.5px; padding: 6px 10px; border-bottom: 1px solid var(--border); }
104
- .tbl td { padding: 7px 10px; border-bottom: 1px solid var(--surface2); font-variant-numeric: tabular-nums; }
131
+ .tbl th { position: sticky; top: 0; z-index: 1; text-align: left; background: var(--surface); color: var(--muted); font-family: var(--mono); font-weight: 600; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.6px; padding: 8px 10px; border-bottom: 1px solid var(--border); }
132
+ .tbl td { padding: 8px 10px; border-bottom: 1px solid var(--border-soft); font-variant-numeric: tabular-nums; }
133
+ .tbl tbody tr { transition: background .12s; }
134
+ .tbl tbody tr:hover td { background: rgba(255,255,255,0.022); }
105
135
  .tbl tr:last-child td { border-bottom: none; }
106
136
  .tbl .r { text-align: right; }
107
137
  .tbl .good { color: var(--good); }
108
- .tbl-wrap { max-height: 320px; overflow-y: auto; }
138
+ .tbl-wrap { max-height: 340px; overflow-y: auto; border: 1px solid var(--border-soft); border-radius: var(--radius-sm); }
109
139
  .stat-line { display: flex; gap: 24px; margin-bottom: 12px; flex-wrap: wrap; }
110
140
  .stat-line div { font-size: 13px; color: var(--muted); }
111
141
  .stat-line b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
@@ -126,13 +156,32 @@
126
156
  .set-ctl { flex-shrink: 0; }
127
157
  .toggle {
128
158
  background: var(--surface2); color: var(--muted); border: 1px solid var(--border);
129
- border-radius: 7px; padding: 5px 16px; font-size: 12px; cursor: pointer; font-family: inherit; min-width: 56px;
159
+ border-radius: var(--radius-sm); padding: 6px 16px; font-size: 12px; cursor: pointer; font-family: var(--mono); min-width: 56px;
160
+ transition: color .15s, background .15s, border-color .15s;
130
161
  }
131
- .toggle:hover { color: var(--text); }
162
+ .toggle:hover { color: var(--text); border-color: #2f3744; }
132
163
  .toggle.on { background: var(--good); color: #06210f; border-color: var(--good); font-weight: 600; }
164
+ /* Boolean settings render as a sliding switch. Only the bool controls carry
165
+ data-kind="bool" - action buttons reuse .toggle and stay buttons. The On/Off
166
+ text is kept for screen readers but pushed off-screen; the knob is drawn with
167
+ ::after, and the .on class (toggled by the same JS) slides it and greens the track. */
168
+ .toggle[data-kind="bool"] {
169
+ position: relative; width: 46px; min-width: 46px; height: 26px; padding: 0;
170
+ border-radius: 999px; background: var(--surface2); border: 1px solid var(--border);
171
+ color: transparent; overflow: hidden; text-indent: -999px;
172
+ transition: background .18s, border-color .18s;
173
+ }
174
+ .toggle[data-kind="bool"]::after {
175
+ content: ""; position: absolute; top: 50%; left: 3px; transform: translateY(-50%);
176
+ width: 18px; height: 18px; border-radius: 50%; background: #cdd2da;
177
+ transition: left .18s, background .18s;
178
+ }
179
+ .toggle[data-kind="bool"]:hover { border-color: #2f3744; }
180
+ .toggle[data-kind="bool"].on { background: var(--good); border-color: var(--good); }
181
+ .toggle[data-kind="bool"].on::after { left: 23px; background: #06210f; }
133
182
  select.choice {
134
183
  background: var(--surface2); color: var(--text); border: 1px solid var(--border);
135
- border-radius: 7px; padding: 5px 10px; font-size: 12px; font-family: inherit; cursor: pointer;
184
+ border-radius: var(--radius-sm); padding: 6px 10px; font-size: 12px; font-family: var(--mono); cursor: pointer;
136
185
  }
137
186
  .set-note { color: var(--accent); font-size: 12px; min-height: 16px; margin-top: 10px; }
138
187
  /* Settings: two-column grid of rows on wide screens, so a long config list stays compact. */
@@ -170,7 +219,7 @@
170
219
  .laddb:hover { border-color: var(--accent); }
171
220
  /* Claude-style usage window gauges (current session / weekly all / weekly Sonnet). */
172
221
  .wgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px; margin-bottom: 18px; }
173
- .wcard { background: var(--surface2); border: 1px solid var(--border); border-radius: 12px; padding: 16px; }
222
+ .wcard { background: var(--surface2); border: 1px solid var(--border); border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow-1); }
174
223
  .wtitle { font-size: 13px; font-weight: 600; color: var(--text); }
175
224
  .wreset { font-size: 12px; color: var(--muted); margin-top: 2px; }
176
225
  .wval { font-size: 22px; font-weight: 600; color: var(--accent); margin-top: 12px; }
@@ -241,7 +290,7 @@
241
290
 
242
291
  <main id="view-savings">
243
292
  <div class="grid">
244
- <div class="card"><div class="label">Money Saved</div><div id="money" class="value good">-</div><div id="moneyFoot" class="foot">Estimated, by source</div></div>
293
+ <div class="card hero"><div class="label">Money Saved</div><div id="money" class="value good">-</div><div id="moneyFoot" class="foot">Estimated, by source</div></div>
245
294
  <div class="card"><div class="label">Time Saved</div><div id="time" class="value accent">-</div><div id="timeFoot" class="foot">Estimated prefill time</div></div>
246
295
  <div class="card"><div class="label">Tokens Saved</div><div id="saved" class="value">-</div><div id="savedFoot" class="foot">Across all compressions</div></div>
247
296
  <div class="card"><div class="label">Savings Rate</div><div id="rate" class="value accent">-</div><div class="foot">Of input tokens removed</div></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enigmax/dashboard",
3
- "version": "0.1.14",
3
+ "version": "0.1.16",
4
4
  "description": "Local browser dashboard UI for enigma: the static page and chart assets enigma serves on its loopback dashboard (savings, real tool usage, in-browser settings). Installed on demand by enigma-cli; not a runtime dependency.",
5
5
  "type": "module",
6
6
  "files": [