@zhangferry-dev/tokendash 1.6.0 → 1.6.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.
Files changed (60) hide show
  1. package/README.md +146 -83
  2. package/dist/client/assets/index-Bw503sNp.css +1 -0
  3. package/dist/client/index.html +2 -2
  4. package/dist/client/popover.html +4 -3
  5. package/dist/daemon.cjs +3306 -0
  6. package/dist/daemon.cjs.map +7 -0
  7. package/dist/electron-server.cjs +1043 -27
  8. package/dist/electron-server.cjs.map +4 -4
  9. package/dist/server/daemon.d.ts +12 -0
  10. package/dist/server/daemon.js +176 -0
  11. package/dist/server/index.js +39 -13
  12. package/dist/server/insightsCalculator.d.ts +15 -0
  13. package/dist/server/insightsCalculator.js +276 -0
  14. package/dist/server/quota/adapter.d.ts +47 -0
  15. package/dist/server/quota/adapter.js +41 -0
  16. package/dist/server/quota/adapters/claude.d.ts +2 -0
  17. package/dist/server/quota/adapters/claude.js +124 -0
  18. package/dist/server/quota/adapters/codex.d.ts +2 -0
  19. package/dist/server/quota/adapters/codex.js +188 -0
  20. package/dist/server/quota/adapters/glm.d.ts +2 -0
  21. package/dist/server/quota/adapters/glm.js +133 -0
  22. package/dist/server/quota/adapters/kimi.d.ts +2 -0
  23. package/dist/server/quota/adapters/kimi.js +184 -0
  24. package/dist/server/quota/adapters/minimax.d.ts +2 -0
  25. package/dist/server/quota/adapters/minimax.js +77 -0
  26. package/dist/server/quota/cache.d.ts +20 -0
  27. package/dist/server/quota/cache.js +44 -0
  28. package/dist/server/quota/credentialsFile.d.ts +13 -0
  29. package/dist/server/quota/credentialsFile.js +23 -0
  30. package/dist/server/quota/helpers.d.ts +39 -0
  31. package/dist/server/quota/helpers.js +93 -0
  32. package/dist/server/quota/index.d.ts +5 -0
  33. package/dist/server/quota/index.js +23 -0
  34. package/dist/server/quota/quotaService.d.ts +37 -0
  35. package/dist/server/quota/quotaService.js +141 -0
  36. package/dist/server/quota/schemas.d.ts +358 -0
  37. package/dist/server/quota/schemas.js +53 -0
  38. package/dist/server/quota/types.d.ts +65 -0
  39. package/dist/server/quota/types.js +10 -0
  40. package/dist/server/routes/api.d.ts +6 -1
  41. package/dist/server/routes/api.js +26 -1
  42. package/dist/server/routes/insights.d.ts +2 -0
  43. package/dist/server/routes/insights.js +155 -0
  44. package/package.json +6 -10
  45. package/resources/icon-1024.png +0 -0
  46. package/resources/icon.icns +0 -0
  47. package/resources/icon.png +0 -0
  48. package/resources/product_menu.png +0 -0
  49. package/resources/readme-hero.png +0 -0
  50. package/dist/client/assets/index-_yA9tOzZ.css +0 -1
  51. package/electron/main.cjs +0 -490
  52. package/electron/main.js +0 -291
  53. package/electron/preload.cjs +0 -36
  54. package/electron/trayBadge.cjs +0 -27
  55. package/electron/trayBadge.js +0 -30
  56. package/electron/trayHelper +0 -0
  57. package/electron/trayHelper.swift +0 -152
  58. package/electron/updateService.cjs +0 -148
  59. package/electron-builder.yml +0 -20
  60. /package/dist/client/assets/{index-CY4G_b0x.js → index-C913wKtU.js} +0 -0
package/README.md CHANGED
@@ -1,128 +1,191 @@
1
- # tokendash
1
+ <div align="center">
2
+ # TokenDash
2
3
 
3
- A beautiful, local web dashboard for visualizing your Claude Code, Codex, OpenClaw, and OpenCode token usage statistics.
4
+ **Your local command center for AI coding usage.**
4
5
 
5
- It runs locally and parses token usage data directly from local session files, presenting it in a clean, interactive React dashboard. No external CLI dependencies required.
6
+ Track tokens, costs, models, projects, and coding-plan limits from the macOS menu bar, with a detailed local dashboard when you need to dig deeper.
6
7
 
7
- ![Web Dashboard](resources/product_screenshoot.png)
8
+ [![Latest release](https://img.shields.io/github/v/release/zhangferry/tokendash?style=flat-square)](https://github.com/zhangferry/tokendash/releases/latest)
9
+ [![npm](https://img.shields.io/npm/v/@zhangferry-dev/tokendash?style=flat-square)](https://www.npmjs.com/package/@zhangferry-dev/tokendash)
10
+ [![Test](https://img.shields.io/github/actions/workflow/status/zhangferry/tokendash/test.yml?branch=main&style=flat-square&label=tests)](https://github.com/zhangferry/tokendash/actions/workflows/test.yml)
11
+ [![License](https://img.shields.io/github/license/zhangferry/tokendash?style=flat-square)](LICENSE)
8
12
 
9
- ## Features
13
+ [Download for macOS](https://github.com/zhangferry/tokendash/releases/latest) · [Run with npx](#run-the-web-dashboard) · [Features](#what-you-get) · [Development](#development)
14
+ </div>
10
15
 
11
- - **Multi-Agent Support:** View usage for Claude Code, Codex, OpenClaw, and OpenCode.
12
- - **Direct JSONL Parsing:** Reads local session files directly — 100x faster data loading.
13
- - **Detailed Metrics:** Track total tokens, cost (USD), active days, cache hit rates, and output/input ratio.
14
- - **Today by Hour:** 24-hour token consumption panel showing hourly breakdown for the current day.
15
- - **Code Analytics:** Visualize code change trends, tool call frequency, and productivity KPIs.
16
- - **Interactive Charts:** Bar/line/area charts with tooltips, model breakdowns, and time range filtering.
17
- - **24-Hour Heatmap:** Activity distribution by hour and day of week, with timezone awareness.
18
- - **Model & Project Distribution:** See which models and projects drive your usage.
19
- - **Persistent Filters:** Your selected time range, project, and metric mode are saved automatically.
16
+ <p align="center">
17
+ <img src="resources/icon.png" width="132" alt="TokenDash app icon">
18
+ </p>
20
19
 
21
- ## macOS Menu Bar App
20
+ ![TokenDash menu bar app and web dashboard](resources/readme-hero.png)
22
21
 
23
- TokenDash ships as a native macOS menu-bar-only application — no Dock icon, no window clutter. It lives quietly in your status bar and gives you instant access to your AI token usage at a glance.
22
+ ## Why TokenDash?
24
23
 
25
- ![macOS Menu Bar](resources/product_menu.png)
24
+ AI coding tools make it easy to consume millions of tokens without a clear picture of where they went. TokenDash turns local session data into an at-a-glance view of today's activity and a deeper history of your usage.
26
25
 
27
- **Status Bar Badge**
28
- - Displays real-time token count (e.g. `1.2K`, `32.0M`) directly in the macOS status bar
29
- - Updates every 5 seconds automatically
30
- - Shows cost and cache hit rate in the tooltip on hover
31
- - Resilient badge: transient network or data errors won't clear your existing badge value
26
+ - **Glanceable by design** — see today's tokens, estimated cost, cache rate, model mix, and quota status without leaving the menu bar.
27
+ - **One view across tools** bring Claude Code, Codex, OpenClaw, and OpenCode usage into the same product.
28
+ - **Local-first** usage history is parsed directly from files already stored on your machine.
29
+ - **Useful beyond totals** — understand hourly activity, model and project distribution, cache efficiency, code changes, and tool calls.
30
+ - **No companion analytics service** the dashboard runs on your computer and does not require an account.
32
31
 
33
- **Popover Dashboard**
34
- - Click the status bar icon to open a compact popover with today's full breakdown:
35
- - Total tokens, input/output/cache metrics at a glance
36
- - Hourly consumption bar chart with peak value highlight
37
- - Agent filter dropdown (show only Claude Code, Codex, etc.)
38
- - Settings: launch at login, check for updates, quit
39
- - The popover syncs rendered totals back to the status bar badge for maximum accuracy
32
+ ## Quick Start
40
33
 
41
- **Native Integration**
42
- - Written in Swift (`trayHelper.swift`) for macOS 14+ compatibility
43
- - Menu-bar-only (`LSUIElement: true`) no Dock icon, runs silently in the background
44
- - Dark mode support with automatic theme switching
45
- - Custom app icon
46
- - Distributed as a standard macOS DMG installer
47
- - Port auto-detection with fallback — works even if port 3456 is already in use
34
+ ### macOS Menu Bar App
35
+
36
+ The native menu bar app is the recommended way to use TokenDash.
48
37
 
49
- ## Requirements
38
+ 1. Download the latest Apple silicon DMG from [GitHub Releases](https://github.com/zhangferry/tokendash/releases/latest).
39
+ 2. Open the DMG and drag **TokenDash** into **Applications**.
40
+ 3. Launch TokenDash. It will detect supported AI coding tools and start the local dashboard automatically.
50
41
 
51
- - Node.js 20 or later
52
- - npm or another Node package manager
42
+ TokenDash requires **macOS 14 or later**. It runs as a menu-bar-only app, so it does not add an icon to the Dock.
53
43
 
54
- ## Installation & Usage
44
+ ### Run the Web Dashboard
55
45
 
56
- You can run the dashboard directly using `npx` without installing it globally:
46
+ On macOS, Linux, or Windows, run the local web dashboard with Node.js 20 or later:
57
47
 
58
48
  ```bash
59
49
  npx @zhangferry-dev/tokendash
60
50
  ```
61
51
 
62
- Or install it globally:
52
+ TokenDash opens `http://localhost:3456` automatically. No global installation is required.
53
+
54
+ ## What You Get
55
+
56
+ ### A Native macOS Companion
57
+
58
+ The menu bar keeps the information you check most often close at hand:
59
+
60
+ - Live token total in the status bar
61
+ - Today's token and estimated cost summary
62
+ - Hourly consumption chart and seven-day trend
63
+ - Usage breakdown by model and token type
64
+ - Coding-plan usage with reset countdowns
65
+ - Configurable low-quota notifications
66
+ - Launch at login, light/dark appearance, and automatic update checks
67
+
68
+ <p align="center">
69
+ <img src="resources/product_menu.png" width="420" alt="TokenDash macOS menu bar popover">
70
+ </p>
71
+
72
+ ### A Detailed Local Dashboard
73
+
74
+ Open the full dashboard when you want to investigate a spike or understand longer-term patterns:
75
+
76
+ - Token and cost views across today, 7, 30, 60, or all days
77
+ - Per-project and per-model distribution
78
+ - Input, output, cache creation, and cache read metrics
79
+ - Cache efficiency and estimated savings
80
+ - Hour-by-day activity heatmap
81
+ - Daily trends and session-level breakdowns
82
+ - Code change, tool call, and productivity analytics where supported
83
+ - Persistent agent, project, time-range, and metric filters
84
+
85
+ ![TokenDash web analytics dashboard](resources/product_screenshoot.png)
86
+
87
+ ## Supported Tools
88
+
89
+ ### Usage Analytics
90
+
91
+ | Tool | Local data source | Usage history | Code analytics |
92
+ | --- | --- | :---: | :---: |
93
+ | Claude Code | `~/.claude/projects/` | Yes | Yes |
94
+ | OpenAI Codex | `~/.codex/sessions/` | Yes | — |
95
+ | OpenClaw | `~/.openclaw/sessions/` | Yes | Yes |
96
+ | OpenCode | `~/.local/share/opencode/opencode.db` | Yes | — |
97
+
98
+ TokenDash only shows tools it detects on the current machine.
99
+
100
+ ### Coding-Plan Quotas
101
+
102
+ The macOS app can also display the current limits reported by:
103
+
104
+ - Claude Code
105
+ - OpenAI Codex
106
+ - GLM Coding Plan
107
+ - MiniMax Coding Plan
108
+ - Kimi Code
109
+
110
+ Claude Code and Codex reuse their existing local authentication. Credentials entered for other providers are stored in `~/.tokendash/credentials.json` with owner-only file permissions.
111
+
112
+ ## Privacy
113
+
114
+ TokenDash is local-first:
115
+
116
+ - Session history is read and processed on your machine.
117
+ - The web dashboard and its API are served locally.
118
+ - TokenDash does not upload usage history to a TokenDash service.
119
+ - No TokenDash account, telemetry endpoint, or external analytics database is required.
120
+
121
+ When coding-plan monitoring is enabled, TokenDash contacts the corresponding provider's API to retrieve current quota information. Only the authentication and request data required by that provider is sent; your local session history is not included.
122
+
123
+ ## CLI
124
+
125
+ Install globally if you prefer a persistent command:
63
126
 
64
127
  ```bash
65
128
  npm install -g @zhangferry-dev/tokendash
66
129
  tokendash
67
130
  ```
68
131
 
69
- By default, the backend server runs on port `3456`. When running the production build or installing globally, you access the dashboard at `http://localhost:3456`.
132
+ Available options:
70
133
 
71
- During development (`npm run dev`), Vite starts a separate development server on port `5173` with hot-module replacement. You should access the dashboard at `http://localhost:5173` while developing.
134
+ ```text
135
+ tokendash [options]
72
136
 
73
- ### macOS Menu Bar App
137
+ --port <number> Port for the local server (default: 3456 or PORT)
138
+ --no-open Start without opening a browser
139
+ --version, -v Print the installed version
140
+ ```
74
141
 
75
- Download the latest `TokenDash-<version>-arm64.dmg` from [GitHub Releases](https://github.com/zhangferry/tokendash/releases). Open the DMG and drag TokenDash to your Applications folder. Launch it and the status bar icon appears immediately — no setup needed.
142
+ During development, Vite serves the frontend at `http://localhost:5173`; packaged and npm installations use the local server port.
76
143
 
77
- ### Command Line Options
144
+ ## How It Works
78
145
 
79
- ```bash
80
- tokendash [options]
146
+ TokenDash consists of three small layers:
81
147
 
82
- Options:
83
- --port <number> Port to run the server on (default: 3456 or PORT env var)
84
- --no-open Do not automatically open the browser
85
- ```
148
+ 1. **Local parsers** read each supported tool's session files or database.
149
+ 2. **An Express API** validates and caches normalized usage data.
150
+ 3. **Two interfaces** present the same data: a React analytics dashboard and a native SwiftUI macOS menu bar app.
151
+
152
+ Data is cached locally with a stale-while-revalidate strategy so the interface remains responsive while files are being reparsed.
86
153
 
87
154
  ## Development
88
155
 
89
- If you want to contribute or modify the dashboard locally:
156
+ ```bash
157
+ git clone https://github.com/zhangferry/tokendash.git
158
+ cd tokendash
159
+ npm install
160
+ npm run dev
161
+ ```
90
162
 
91
- 1. Clone the repository:
92
- ```bash
93
- git clone <repository-url>
94
- cd tokendash
95
- ```
163
+ Common commands:
96
164
 
97
- 2. Install dependencies:
98
- ```bash
99
- npm install
100
- ```
165
+ | Command | Purpose |
166
+ | --- | --- |
167
+ | `npm run dev` | Start the Express and Vite development servers |
168
+ | `npm run build` | Build the web client and server |
169
+ | `npm run build:swift` | Build the native macOS app |
170
+ | `npm run build:dmg` | Package the macOS app and DMG |
171
+ | `npm run typecheck` | Type-check the server and frontend |
172
+ | `npm test` | Run Vitest unit tests |
173
+ | `npm run test:e2e` | Run Playwright end-to-end tests |
101
174
 
102
- 3. Start the development servers (runs Vite for frontend and tsx for backend concurrently):
103
- ```bash
104
- npm run dev
105
- ```
175
+ The web client uses React, TypeScript, Tailwind CSS, Recharts, and Vite. The local server uses Express and Zod. The macOS app is built with SwiftUI and Sparkle.
106
176
 
107
- 4. Build for production:
108
- ```bash
109
- npm run build
110
- ```
177
+ ## Contributing
111
178
 
112
- 5. Run the production build locally:
113
- ```bash
114
- npm start
115
- ```
179
+ Issues and pull requests are welcome. For a new integration, keep the parser boundary consistent by implementing daily, project, and block responses, then wire detection, API routing, and the agent switcher.
116
180
 
117
- ## Architecture
181
+ Before submitting a change, run:
118
182
 
119
- - **Frontend:** React 19, Recharts, Tailwind CSS (via Vite plugin), built with Vite.
120
- - **Backend:** Express, TypeScript.
121
- - **Data Source:** All agent data is parsed directly from local session files (`~/.claude/projects/`, `~/.codex/sessions/`) and OpenCode's SQLite database (`~/.local/share/opencode/opencode.db`). No external CLI dependencies.
122
- - **Caching:** Persistent disk cache (`/tmp/tokendash-cache/`) with stale-while-revalidate pattern for snappy UI updates.
123
- - **Testing:** Vitest (unit), Playwright (E2E). Run with `npm test` and `npm run test:e2e`.
124
- - **CI:** GitHub Actions pipeline for automated testing on every push and PR.
183
+ ```bash
184
+ npm run typecheck
185
+ npm test
186
+ npm run test:e2e
187
+ ```
125
188
 
126
189
  ## License
127
190
 
128
- [MIT](./LICENSE)
191
+ TokenDash is available under the [MIT License](LICENSE).
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:"Geist", "Geist Fallback", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-mono:"Geist Mono", "Geist Mono Fallback", ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-600:oklch(57.7% .245 27.325);--color-orange-600:oklch(64.6% .222 41.116);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-100:oklch(95% .052 163.051);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-indigo-50:oklch(96.2% .018 272.314);--color-indigo-500:oklch(58.5% .233 277.117);--color-indigo-600:oklch(51.1% .262 276.966);--color-stone-50:oklch(98.5% .001 106.423);--color-stone-100:oklch(97% .001 106.424);--color-stone-200:oklch(92.3% .003 48.717);--color-stone-400:oklch(70.9% .01 56.259);--color-stone-500:oklch(55.3% .013 58.071);--color-stone-600:oklch(44.4% .011 73.639);--color-stone-700:oklch(37.4% .01 67.558);--color-stone-800:oklch(26.8% .007 34.298);--color-stone-900:oklch(21.6% .006 56.043);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--tracking-tighter:-.05em;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0, 0, .2, 1);--animate-spin:spin 1s linear infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-full{top:100%}.bottom-full{bottom:100%}.left-1\/2{left:50%}.z-20{z-index:20}.z-50{z-index:50}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-10{margin-left:calc(var(--spacing) * 10)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-8{height:calc(var(--spacing) * 8)}.h-10{height:calc(var(--spacing) * 10)}.h-20{height:calc(var(--spacing) * 20)}.h-48{height:calc(var(--spacing) * 48)}.h-64{height:calc(var(--spacing) * 64)}.h-72{height:calc(var(--spacing) * 72)}.h-\[22px\]{height:22px}.h-\[44px\]{height:44px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-dvh{min-height:100dvh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-6{width:calc(var(--spacing) * 6)}.w-8{width:calc(var(--spacing) * 8)}.w-20{width:calc(var(--spacing) * 20)}.w-48{width:calc(var(--spacing) * 48)}.w-72{width:calc(var(--spacing) * 72)}.w-\[320px\]{width:320px}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-\[1440px\]{max-width:1440px}.flex-1{flex:1}.flex-shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-spin{animation:var(--animate-spin)}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-x-auto{overflow-x:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[3px\]{border-radius:3px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-amber-200\/60{border-color:#fee68599}@supports (color:color-mix(in lab,red,red)){.border-amber-200\/60{border-color:color-mix(in oklab,var(--color-amber-200) 60%,transparent)}}.border-emerald-100\/50{border-color:#d0fae580}@supports (color:color-mix(in lab,red,red)){.border-emerald-100\/50{border-color:color-mix(in oklab,var(--color-emerald-100) 50%,transparent)}}.border-red-200\/60{border-color:#ffcaca99}@supports (color:color-mix(in lab,red,red)){.border-red-200\/60{border-color:color-mix(in oklab,var(--color-red-200) 60%,transparent)}}.border-stone-100{border-color:var(--color-stone-100)}.border-stone-200{border-color:var(--color-stone-200)}.border-stone-200\/40{border-color:#e7e5e466}@supports (color:color-mix(in lab,red,red)){.border-stone-200\/40{border-color:color-mix(in oklab,var(--color-stone-200) 40%,transparent)}}.border-stone-200\/50{border-color:#e7e5e480}@supports (color:color-mix(in lab,red,red)){.border-stone-200\/50{border-color:color-mix(in oklab,var(--color-stone-200) 50%,transparent)}}.border-stone-200\/60{border-color:#e7e5e499}@supports (color:color-mix(in lab,red,red)){.border-stone-200\/60{border-color:color-mix(in oklab,var(--color-stone-200) 60%,transparent)}}.bg-amber-50{background-color:var(--color-amber-50)}.bg-emerald-50\/50{background-color:#ecfdf580}@supports (color:color-mix(in lab,red,red)){.bg-emerald-50\/50{background-color:color-mix(in oklab,var(--color-emerald-50) 50%,transparent)}}.bg-emerald-200\/50{background-color:#a4f4cf80}@supports (color:color-mix(in lab,red,red)){.bg-emerald-200\/50{background-color:color-mix(in oklab,var(--color-emerald-200) 50%,transparent)}}.bg-indigo-50{background-color:var(--color-indigo-50)}.bg-indigo-50\/50{background-color:#eef2ff80}@supports (color:color-mix(in lab,red,red)){.bg-indigo-50\/50{background-color:color-mix(in oklab,var(--color-indigo-50) 50%,transparent)}}.bg-red-50{background-color:var(--color-red-50)}.bg-stone-50{background-color:var(--color-stone-50)}.bg-stone-50\/40{background-color:#fafaf966}@supports (color:color-mix(in lab,red,red)){.bg-stone-50\/40{background-color:color-mix(in oklab,var(--color-stone-50) 40%,transparent)}}.bg-stone-100{background-color:var(--color-stone-100)}.bg-stone-200\/50{background-color:#e7e5e480}@supports (color:color-mix(in lab,red,red)){.bg-stone-200\/50{background-color:color-mix(in oklab,var(--color-stone-200) 50%,transparent)}}.bg-stone-200\/60{background-color:#e7e5e499}@supports (color:color-mix(in lab,red,red)){.bg-stone-200\/60{background-color:color-mix(in oklab,var(--color-stone-200) 60%,transparent)}}.bg-stone-800{background-color:var(--color-stone-800)}.bg-stone-900{background-color:var(--color-stone-900)}.bg-white{background-color:var(--color-white)}.bg-\[radial-gradient\(ellipse_at_top\,\#eef2ff_0\%\,\#faf9f7_35\%\,\#faf9f7_100\%\)\]{background-image:radial-gradient(at top,#eef2ff,#faf9f7 35%,#faf9f7)}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-1{padding:calc(var(--spacing) * 1)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-tighter{--tw-tracking:var(--tracking-tighter);letter-spacing:var(--tracking-tighter)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.whitespace-nowrap{white-space:nowrap}.text-amber-400{color:var(--color-amber-400)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-600\/70{color:#009767b3}@supports (color:color-mix(in lab,red,red)){.text-emerald-600\/70{color:color-mix(in oklab,var(--color-emerald-600) 70%,transparent)}}.text-emerald-700\/80{color:#007956cc}@supports (color:color-mix(in lab,red,red)){.text-emerald-700\/80{color:color-mix(in oklab,var(--color-emerald-700) 80%,transparent)}}.text-indigo-500\/70{color:#625fffb3}@supports (color:color-mix(in lab,red,red)){.text-indigo-500\/70{color:color-mix(in oklab,var(--color-indigo-500) 70%,transparent)}}.text-indigo-600{color:var(--color-indigo-600)}.text-orange-600{color:var(--color-orange-600)}.text-red-600{color:var(--color-red-600)}.text-stone-400{color:var(--color-stone-400)}.text-stone-500{color:var(--color-stone-500)}.text-stone-600{color:var(--color-stone-600)}.text-stone-700{color:var(--color-stone-700)}.text-stone-800{color:var(--color-stone-800)}.text-stone-900{color:var(--color-stone-900)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.opacity-0{opacity:0}.opacity-25{opacity:.25}.opacity-75{opacity:.75}.shadow-\[0_1px_3px_rgba\(0\,0\,0\,0\.1\)\]{--tw-shadow:0 1px 3px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_1px_3px_rgba\(120\,113\,108\,0\.06\)\]{--tw-shadow:0 1px 3px var(--tw-shadow-color,#78716c0f);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_8px_30px_rgba\(120\,113\,108\,0\.12\)\]{--tw-shadow:0 8px 30px var(--tw-shadow-color,#78716c1f);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_8px_30px_rgba\(120\,113\,108\,0\.15\)\]{--tw-shadow:0 8px 30px var(--tw-shadow-color,#78716c26);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-stone-900\/5{--tw-ring-color:#1c19170d}@supports (color:color-mix(in lab,red,red)){.ring-stone-900\/5{--tw-ring-color:color-mix(in oklab, var(--color-stone-900) 5%, transparent)}}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:z-10:hover{z-index:10}.hover\:bg-indigo-50:hover{background-color:var(--color-indigo-50)}.hover\:bg-stone-50:hover{background-color:var(--color-stone-50)}.hover\:bg-stone-50\/60:hover{background-color:#fafaf999}@supports (color:color-mix(in lab,red,red)){.hover\:bg-stone-50\/60:hover{background-color:color-mix(in oklab,var(--color-stone-50) 60%,transparent)}}.hover\:bg-stone-200\/50:hover{background-color:#e7e5e480}@supports (color:color-mix(in lab,red,red)){.hover\:bg-stone-200\/50:hover{background-color:color-mix(in oklab,var(--color-stone-200) 50%,transparent)}}.hover\:text-indigo-600:hover{color:var(--color-indigo-600)}.hover\:text-stone-800:hover{color:var(--color-stone-800)}.hover\:shadow-\[0_4px_12px_rgba\(120\,113\,108\,0\.09\)\]:hover{--tw-shadow:0 4px 12px var(--tw-shadow-color,#78716c17);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-2:hover{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.hover\:ring-emerald-400:hover{--tw-ring-color:var(--color-emerald-400)}.hover\:ring-offset-1:hover{--tw-ring-offset-width:1px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}}.focus\:border-indigo-500:focus{border-color:var(--color-indigo-500)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-indigo-500\/20:focus{--tw-ring-color:#625fff33}@supports (color:color-mix(in lab,red,red)){.focus\:ring-indigo-500\/20:focus{--tw-ring-color:color-mix(in oklab, var(--color-indigo-500) 20%, transparent)}}@media(min-width:40rem){.sm\:block{display:block}}@media(min-width:48rem){.md\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.md\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}}@media(min-width:64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}}html,body{background-color:#faf9f7!important}@font-face{font-family:Geist;src:url(https://cdn.jsdelivr.net/npm/geist@1.3.1/dist/fonts/geist-sans/Geist-Variable.woff2)format("woff2");font-weight:100 900;font-display:swap;font-style:normal}@font-face{font-family:Geist Mono;src:url(https://cdn.jsdelivr.net/npm/geist@1.3.1/dist/fonts/geist-mono/GeistMono-Variable.woff2)format("woff2");font-weight:100 900;font-display:swap;font-style:normal}body:before{content:"";z-index:9999;pointer-events:none;opacity:.015;background-image:url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)'/%3E%3C/svg%3E");background-repeat:repeat;background-size:200px 200px;position:fixed;top:0;right:0;bottom:0;left:0}.recharts-cartesian-grid-horizontal line,.recharts-cartesian-grid-vertical line{stroke:#e7e5e4}.recharts-text{fill:#78716c;font-family:var(--font-sans);font-size:11px}.recharts-legend-item-text{color:#57534e;font-size:12px}.recharts-tooltip-wrapper{outline:none}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:#c8c4be;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#a8a29e}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.skeleton{background:linear-gradient(90deg,#e7e5e4 25%,#d6d3d1,#e7e5e4 75%) 0 0/200% 100%;animation:1.5s ease-in-out infinite shimmer}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>TokenDash</title>
7
7
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><text y='28' font-size='28'>⚡</text></svg>" />
8
- <script type="module" crossorigin src="/assets/index-CY4G_b0x.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-_yA9tOzZ.css">
8
+ <script type="module" crossorigin src="/assets/index-C913wKtU.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-Bw503sNp.css">
10
10
  </head>
11
11
  <body class="antialiased" style="background:#faf9f7">
12
12
  <div id="root"></div>
@@ -553,7 +553,8 @@
553
553
  .drawer-overlay {
554
554
  position: absolute;
555
555
  inset: 0;
556
- background: rgba(255, 255, 255, 0.76);
556
+ z-index: 20;
557
+ background: rgba(250, 252, 251, 0.96);
557
558
  border: 1px solid rgba(255, 255, 255, 0.72);
558
559
  border-radius: var(--radius-shell);
559
560
  opacity: 0;
@@ -569,7 +570,7 @@
569
570
  flex-direction: column;
570
571
  padding: 0 24px;
571
572
  border-radius: var(--radius-shell);
572
- background: linear-gradient(180deg, rgba(250, 252, 251, 0.85), rgba(244, 247, 245, 0.7));
573
+ background: linear-gradient(180deg, rgba(250, 252, 251, 0.98), rgba(244, 247, 245, 0.96));
573
574
  border: none;
574
575
  box-shadow: none;
575
576
  transform: translateY(10px);
@@ -1246,7 +1247,7 @@
1246
1247
  var label = document.createElement('span');
1247
1248
  label.className = 'x-axis-label' + (shouldLabel ? '' : ' is-unlabeled');
1248
1249
  label.style.gridColumn = String(entry.hour + 1);
1249
- label.textContent = String(entry.hour).padStart(2, '0') + ':00';
1250
+ label.textContent = String(entry.hour).padStart(2, '0');
1250
1251
  xAxis.appendChild(label);
1251
1252
  });
1252
1253
  }