bloby-bot 0.51.5 → 0.52.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/bin/cli.js +19 -0
- package/dist-bloby/assets/{bloby-vi0Xitb-.js → bloby-CjvuL1QI.js} +77 -77
- package/dist-bloby/assets/{globals-DNO3ilRx.js → globals-UaNdQXf5.js} +3 -3
- package/dist-bloby/assets/globals-ZdFBsH0Q.css +2 -0
- package/dist-bloby/assets/{highlighted-body-OFNGDK62-DMeCY5Rc.js → highlighted-body-OFNGDK62-D0QQRXpE.js} +1 -1
- package/dist-bloby/assets/mermaid-GHXKKRXX-D9GshF2B.js +1 -0
- package/dist-bloby/assets/{onboard-D8sRPjz2.js → onboard-DU3OfA5h.js} +1 -1
- package/dist-bloby/bloby.html +3 -3
- package/dist-bloby/onboard.html +3 -3
- package/package.json +5 -3
- package/scripts/install +4 -0
- package/scripts/install.ps1 +7 -0
- package/scripts/install.sh +4 -0
- package/scripts/postinstall.js +12 -0
- package/supervisor/chat/bloby-main.tsx +40 -7
- package/supervisor/chat/src/components/Chat/MessageBubble.tsx +16 -2
- package/supervisor/chat/src/components/Chat/MessageList.tsx +7 -1
- package/supervisor/chat/src/components/Chat/NotchCard.tsx +70 -0
- package/supervisor/harnesses/claude.ts +31 -1
- package/supervisor/harnesses/codex.ts +15 -1
- package/supervisor/index.ts +31 -2
- package/worker/prompts/bloby-system-prompt.txt +1 -1
- package/workspace/skills/mac/SKILL.md +102 -22
- package/workspace/skills/mac/presets/PRESETS.md +226 -0
- package/dist-bloby/assets/globals-D60b-8LY.css +0 -2
- package/dist-bloby/assets/mermaid-GHXKKRXX-BOqNyL14.js +0 -1
package/supervisor/index.ts
CHANGED
|
@@ -31,6 +31,19 @@ import { ChannelManager } from './channels/manager.js';
|
|
|
31
31
|
const DIST_BLOBY = path.join(PKG_DIR, 'dist-bloby');
|
|
32
32
|
const SUPERVISOR_PUBLIC = path.join(PKG_DIR, 'supervisor', 'public');
|
|
33
33
|
|
|
34
|
+
// Proactive context recycling. The chat runs as one long-lived agent session per
|
|
35
|
+
// conversation (so the user can keep talking while the agent works). That session's
|
|
36
|
+
// context grows every turn and would eventually hit the wall. But continuity does NOT
|
|
37
|
+
// live in that session — every fresh session re-injects the recent messages + memory
|
|
38
|
+
// files — so when the context grows large AND the agent is idle, we end the session;
|
|
39
|
+
// the next message starts a clean one. This keeps heavy/long chats off the wall
|
|
40
|
+
// without lossy compaction, while preserving mid-turn responsiveness (we only recycle
|
|
41
|
+
// between turns). When the harness reports the model's context window we recycle at
|
|
42
|
+
// RECYCLE_FRACTION of it (adaptive to 200k vs 1M windows); otherwise we fall back to a
|
|
43
|
+
// fixed token budget. Auto-compaction stays on as the in-turn safety net.
|
|
44
|
+
const CONTEXT_RECYCLE_TOKENS = Number(process.env.BLOBY_CONTEXT_RECYCLE_TOKENS) || 140_000;
|
|
45
|
+
const CONTEXT_RECYCLE_FRACTION = Number(process.env.BLOBY_CONTEXT_RECYCLE_FRACTION) || 0.7;
|
|
46
|
+
|
|
34
47
|
// Platform assets that must survive workspace swaps — served directly by supervisor
|
|
35
48
|
const PLATFORM_ASSETS = new Set([
|
|
36
49
|
'/spritesheet.webp',
|
|
@@ -1429,7 +1442,7 @@ mint();
|
|
|
1429
1442
|
try {
|
|
1430
1443
|
const [status, recentRaw] = await Promise.all([
|
|
1431
1444
|
workerApi('/api/onboard/status'),
|
|
1432
|
-
workerApi(`/api/conversations/${convId}/messages/recent?limit=
|
|
1445
|
+
workerApi(`/api/conversations/${convId}/messages/recent?limit=30`),
|
|
1433
1446
|
]);
|
|
1434
1447
|
botName = status.agentName || 'Bloby';
|
|
1435
1448
|
humanName = status.userName || 'Human';
|
|
@@ -1894,6 +1907,22 @@ mint();
|
|
|
1894
1907
|
endConversation(convId);
|
|
1895
1908
|
runDeferredUpdate();
|
|
1896
1909
|
}
|
|
1910
|
+
|
|
1911
|
+
// Proactive session recycling (see CONTEXT_RECYCLE_TOKENS). Only when the
|
|
1912
|
+
// harness reports the session idle (no queued message) — and this handler runs
|
|
1913
|
+
// synchronously from the harness callback, so nothing can be pushed between the
|
|
1914
|
+
// idle check and endConversation. Recycling here therefore never drops a queued
|
|
1915
|
+
// message; the next user message re-injects recent history + memory.
|
|
1916
|
+
if (eventData.idle && hasConversation(convId)) {
|
|
1917
|
+
const used = typeof eventData.contextTokens === 'number' ? eventData.contextTokens : 0;
|
|
1918
|
+
const window = typeof eventData.contextWindow === 'number' ? eventData.contextWindow : 0;
|
|
1919
|
+
const recycleAt = window > 0 ? Math.floor(window * CONTEXT_RECYCLE_FRACTION) : CONTEXT_RECYCLE_TOKENS;
|
|
1920
|
+
if (used > recycleAt) {
|
|
1921
|
+
log.info(`[orchestrator] Context ~${used} tok > ${recycleAt} (window=${window || 'n/a'}) — recycling session ${convId}; next message re-injects recent + memory.`);
|
|
1922
|
+
endConversation(convId);
|
|
1923
|
+
}
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1897
1926
|
broadcastBloby('bot:idle', { conversationId: convId });
|
|
1898
1927
|
return;
|
|
1899
1928
|
}
|
|
@@ -2227,7 +2256,7 @@ mint();
|
|
|
2227
2256
|
try {
|
|
2228
2257
|
const [status, recentRaw] = await Promise.all([
|
|
2229
2258
|
workerApi('/api/onboard/status') as Promise<any>,
|
|
2230
|
-
workerApi(`/api/conversations/${convId}/messages/recent?limit=
|
|
2259
|
+
workerApi(`/api/conversations/${convId}/messages/recent?limit=30`) as Promise<any[]>,
|
|
2231
2260
|
]);
|
|
2232
2261
|
botName = status.agentName || 'Bloby';
|
|
2233
2262
|
humanName = status.userName || 'Human';
|
|
@@ -279,7 +279,7 @@ If your human asks you to update a skill's behavior, edit the files INSIDE `skil
|
|
|
279
279
|
You can communicate through several surfaces at once. The two built-in ones are:
|
|
280
280
|
|
|
281
281
|
- **`[PWA]`** — the chat bubble in the dashboard (web app / PWA). This is the main one: the floating Bloby widget your human clicks open, the conversation you're reading right now if no other tag is present. Treat it as your home base.
|
|
282
|
-
- **`[Mac]`** — the Morphy native Mac app living in the MacBook notch. Your human held a hotkey, spoke, and Morphy sent the transcript here. Screenshots of their screen may be attached. Keep replies concise — they'll be spoken aloud via TTS. No markdown, no bullet lists — plain spoken sentences only.
|
|
282
|
+
- **`[Mac]`** — the Morphy native Mac app living in the MacBook notch. Your human held a hotkey, spoke, and Morphy sent the transcript here. Screenshots of their screen may be attached. Keep replies concise — they'll be spoken aloud via TTS. No markdown, no bullet lists — plain spoken sentences only. You may **optionally** accompany the reply with a small visual card in the notch, two ways: **(1) a PRESET (preferred)** — send structured data and Morphy renders a beautiful, on-brand card for you: `<notch_card type="email">{ "from": "...", "subject": "...", "time": "...", "body": "..." }</notch_card>`. Preset types: `email`, `list`, `calendar`, `weather`, `ticker`, `stat`, `info`, `text`, `comparison` (full schemas in `skills/mac/presets/PRESETS.md`). The body is one JSON object; you never write CSS. **(2) CUSTOM (escape hatch)** — for a bespoke *visual layout* you hand-build with real markup, use `<notch_html>…</notch_html>` (lowercase, exactly that spelling — NOT `<NotchHTML>`, NOT `<notch>`). For long prose / a "read me this" / a summary, use the `text` PRESET instead — never dump plain paragraphs into `<notch_html>`, it's HTML (not a text box) and renders unstyled and edge-to-edge. Send **at most one** card block per reply (a `<notch_card>` OR a `<notch_html>`, never both). Both tags are stripped from TTS, so card contents are **never** spoken. Canvas is **fixed 383 × 147 pt, transparent over BLACK**; custom cards use light/white text, no external assets (no `<img src>`, no fonts, no JS network) and no interactive elements (clicks do nothing) — though long content IS scrollable, the user scrolls it with the trackpad, so letting content overflow is fine. **CRITICAL: never speak the contents of your card.** If the card carries a list / calendar / email / news / comparison / any structured answer, the spoken text MUST be a short lead-in ONLY ("Here are today's top five, Bruno.") and then stop — do not recite the items, the human is already looking at them. If the answer fits in one spoken sentence, send NO card. Voice and card are complementary, never redundant — pick which one carries the detail per reply, and let the other be brief or absent. When in doubt, **open `skills/mac/SKILL.md` and follow it** — it has the preset catalog, examples (including the canonical bad/good comparison of the speak-the-card duplication failure), custom templates under `skills/mac/frequentSnippets/`, and a pre-send checklist. **Mis-spelling a tag means the markup reaches TTS and gets spoken at the human** — that's a visible failure, not a silent one.
|
|
283
283
|
- **`[workspace]`** — a chat-shaped widget your human placed somewhere inside their dashboard *workspace*. It mirrors the main chat, but the context is whatever the human (or you) built it into. It could be a magic-mirror panel on a tablet on the wall, a kiosk/DAC by the front door, a desk dashboard, a car-mounted display, a kitchen screen during cooking — anything you've ever helped them assemble on the workspace that has a chat-style entry point. **Check `MEMORY.md` and the workspace files** to learn the actual purpose of the device this message came from: is this the kitchen tablet asking for a recipe? The hallway mirror asking what's on today's schedule? The garage panel asking about the car? Tailor tone, brevity, and content to that role. A magic mirror should get a short ambient answer, not a long technical paragraph. If you don't yet know what the workspace surface is for, ask once and write it to memory so future `[workspace]` turns are grounded.
|
|
284
284
|
|
|
285
285
|
Beyond those, your human can install additional channels (WhatsApp, Telegram, Discord, Alexa…) as **skills** from the Bloby Marketplace. Each channel skill teaches you the conventions for that surface.
|
|
@@ -20,21 +20,58 @@ The tag is injected by the Morphy app itself when the human pushes-to-talk throu
|
|
|
20
20
|
|
|
21
21
|
---
|
|
22
22
|
|
|
23
|
+
## Two ways to put a visual in the notch
|
|
24
|
+
|
|
25
|
+
There are **two** ways to render a card. Reach for them in this order:
|
|
26
|
+
|
|
27
|
+
1. **Preset (preferred).** Morphy ships a library of beautiful, pre-built card
|
|
28
|
+
renderers (`email`, `calendar`, `list`, `text`, `weather`, `ticker`, `stat`,
|
|
29
|
+
`info`, `comparison`). You send only **structured data** — never CSS — and
|
|
30
|
+
Morphy lays it out perfectly, on-brand, with scrolling handled for you. It's
|
|
31
|
+
the fast, pretty, low-token path. **Full data schemas + examples:
|
|
32
|
+
[`presets/PRESETS.md`](presets/PRESETS.md).**
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
<notch_card type="email">
|
|
36
|
+
{ "from": "Alex Chen", "subject": "Migration plan", "time": "2:14 PM",
|
|
37
|
+
"body": "Can we move the cutover to Tuesday?\n\nStaging looked clean." }
|
|
38
|
+
</notch_card>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. **Custom (escape hatch).** When no preset fits the shape of the answer,
|
|
42
|
+
hand-write the whole card in `<notch_html>…</notch_html>` (rules below). Cards
|
|
43
|
+
you hand-build and reuse get saved to `frequentSnippets/` so next time is
|
|
44
|
+
copy-fill-send. If a custom card gets requested a lot, tell Bruno — it's a
|
|
45
|
+
candidate to become a real shipped preset.
|
|
46
|
+
|
|
47
|
+
**Check for a preset first.** Only drop to custom HTML when the data genuinely
|
|
48
|
+
doesn't fit one of the presets.
|
|
49
|
+
|
|
50
|
+
> **Long prose / "read me this" / a summary / an explanation → use the `text`
|
|
51
|
+
> preset.** Do NOT dump raw paragraphs into `<notch_html>` — that tag is *HTML*,
|
|
52
|
+
> not a text box. Bare text there renders unstyled, edge-to-edge, with no padding.
|
|
53
|
+
> The `text` preset gives you a title, proper margins, and a scrollable body for
|
|
54
|
+
> free: `<notch_card type="text">{ "title": "…", "body": "…long text with \n\n…" }</notch_card>`.
|
|
55
|
+
> `<notch_html>` is only for a genuinely custom *visual layout* you hand-build with
|
|
56
|
+
> real markup and inline styles — never as a dumping ground for plain text.
|
|
57
|
+
|
|
23
58
|
## Output Format
|
|
24
59
|
|
|
25
60
|
Your full reply lives inside the conversation; Morphy will:
|
|
26
61
|
|
|
27
|
-
1. Strip any `<
|
|
62
|
+
1. Strip any `<notch_card …>…</notch_card>` **and** `<notch_html>…</notch_html>`
|
|
63
|
+
block before TTS — neither is **ever** spoken.
|
|
28
64
|
2. Send the remaining text to ElevenLabs and play it through the Mac.
|
|
29
|
-
3.
|
|
65
|
+
3. Render the card (preset → Morphy's renderer; custom → your HTML) and auto-open
|
|
66
|
+
the notch downward **at the same moment** the audio starts. Visual + audio land
|
|
67
|
+
together — that's the whole point.
|
|
30
68
|
|
|
31
|
-
So a reply has up to two parts
|
|
69
|
+
So a reply has up to two parts — a spoken sentence and **one** card block (either
|
|
70
|
+
a `<notch_card>` preset or a `<notch_html>` custom card, not both):
|
|
32
71
|
|
|
33
72
|
```
|
|
34
73
|
<concise spoken sentence>
|
|
35
|
-
<
|
|
36
|
-
<single rendered card>
|
|
37
|
-
</notch_html>
|
|
74
|
+
<notch_card type="…">{ …data… }</notch_card>
|
|
38
75
|
```
|
|
39
76
|
|
|
40
77
|
### Spoken text rules
|
|
@@ -44,11 +81,48 @@ So a reply has up to two parts:
|
|
|
44
81
|
- **Refer the human by name** if you know it ("Here's your calendar for today, Bruno.") — sounds personal, doesn't add length.
|
|
45
82
|
- **Acknowledge the card when you send one.** Otherwise the visual feels disconnected from the voice. "Here it is.", "I put the details up top.", "Tap to glance.".
|
|
46
83
|
|
|
47
|
-
### The
|
|
84
|
+
### 🚫 The #1 mistake: speaking the card content out loud
|
|
85
|
+
|
|
86
|
+
**This is the single most common failure mode and it ruins the UX.** If your card contains a list, a calendar, an email digest, news headlines, search results — *anything structured* — your spoken text **must NOT re-read those items**. The human is already looking at them. Reading them aloud doubles the time-to-information and makes Morphy feel broken.
|
|
87
|
+
|
|
88
|
+
When the card carries the answer, the voice's only job is the **lead-in sentence** — and then stop talking.
|
|
89
|
+
|
|
90
|
+
#### ❌ BAD — speaks the card back at the human
|
|
91
|
+
|
|
92
|
+
> *"Top five AI today, Bruno. Anthropic dropped Claude Opus 4.7 with a one-million-token window. OpenAI is rolling Sora 3 video into ChatGPT for Plus users. Meta open-sourced Llama 4 Scout at 400 billion params. Google DeepMind's Gemini 3 hit number one on the LMSys arena. And Mistral closed a five billion dollar round at a forty billion valuation."*
|
|
93
|
+
> ```
|
|
94
|
+
> <notch_html>… the same five items rendered as a list …</notch_html>
|
|
95
|
+
> ```
|
|
96
|
+
|
|
97
|
+
ElevenLabs spends 30+ seconds reciting what's already on screen. The human paid for tokens AND TTS minutes to receive identical information twice. Don't do this.
|
|
98
|
+
|
|
99
|
+
#### ✓ GOOD — lead-in only, card carries the detail
|
|
100
|
+
|
|
101
|
+
> *"Here are today's top five in AI, Bruno."*
|
|
102
|
+
> ```
|
|
103
|
+
> <notch_html>… the same five items rendered as a list …</notch_html>
|
|
104
|
+
> ```
|
|
105
|
+
|
|
106
|
+
Two seconds of speech, the eye picks up the rest, human keeps working.
|
|
107
|
+
|
|
108
|
+
#### Same rule, different shapes
|
|
109
|
+
|
|
110
|
+
| Question | Speech | Card |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| "What's on my calendar today?" | *"Here's your day, Bruno."* | day + events |
|
|
113
|
+
| "Read me my unread emails." | *"Three worth a glance, Bruno."* | sender + subject list |
|
|
114
|
+
| "Compare Postgres vs SQLite." | *"Quick side-by-side up top, Bruno."* | two-column card |
|
|
115
|
+
| "What's the weather?" | *"Pinned the forecast for you, Bruno."* | temp + conditions |
|
|
116
|
+
| "What time is it in Tokyo?" | *"It's 8:14 PM in Tokyo."* | **no card** — bare fact, voice is enough |
|
|
117
|
+
|
|
118
|
+
The rule is symmetric: if the **voice alone** is the right answer, send **no card**. If the **card** is the answer, send a **short lead-in** in voice. **Never both at full length.**
|
|
119
|
+
|
|
120
|
+
### Whether to send a card at all
|
|
48
121
|
|
|
49
122
|
- **Sometimes useful, sometimes not.** Decide per reply. A time-of-day answer doesn't need a card. A calendar, a list, a comparison, a status — those benefit from one.
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
123
|
+
- **Preset first.** If the answer is an email, a list, a calendar, a stat, a comparison, a quote/summary, weather, or a quote — there's almost certainly a preset for it (see [`presets/PRESETS.md`](presets/PRESETS.md)). Send data, not markup.
|
|
124
|
+
- **Custom only when nothing fits.** Reach for `<notch_html>` when the shape is genuinely bespoke. Pin reusable custom cards as files in `frequentSnippets/` so you can copy-swap-send instead of regenerating.
|
|
125
|
+
- **The card is display-only — but scrollable.** Don't put buttons, links, or "click to expand" — clicks do nothing and read as broken UI. But long content **is scrollable**: the user scrolls `email` / `list` / `calendar` / `text` cards with the trackpad (a thin scrollbar appears), so it's fine to let content overflow.
|
|
52
126
|
|
|
53
127
|
---
|
|
54
128
|
|
|
@@ -63,7 +137,7 @@ So a reply has up to two parts:
|
|
|
63
137
|
| **Color** | White or light. Use `rgba(255,255,255,0.x)` for tints — opacity tints read better than gray on black. |
|
|
64
138
|
| **Allowed** | HTML, CSS (incl. flexbox, grid, gradients, transitions, animations), unicode glyphs / emoji. |
|
|
65
139
|
| **Forbidden** | JS that does network or file access, `<img src="https://...">`, `<iframe>`, anything that loads external resources. The view has no network. |
|
|
66
|
-
| **Interactivity** |
|
|
140
|
+
| **Interactivity** | No clicks or hovers — they do nothing. But long content **scrolls** via the trackpad (a thin scrollbar appears), so overflow is fine. |
|
|
67
141
|
|
|
68
142
|
**383 × 147 is small.** Roughly the size of two stacked Spotlight rows. Treat each card as a single coherent idea — date + time, one event, one fact, one comparison. If you can't fit it, paginate via speech ("here's the first, ask 'next' for the rest"), don't shrink the type.
|
|
69
143
|
|
|
@@ -198,13 +272,16 @@ A bare fact doesn't earn screen real estate. Speak it, move on.
|
|
|
198
272
|
|
|
199
273
|
Before you send:
|
|
200
274
|
|
|
201
|
-
1. **Did
|
|
202
|
-
2. **Is the spoken text ≤ 2 sentences
|
|
203
|
-
3.
|
|
204
|
-
4. **
|
|
205
|
-
5. **
|
|
206
|
-
6. **
|
|
207
|
-
7. **If
|
|
275
|
+
1. **Did the tag `[Mac]` actually start the user message?** If not, don't use this skill.
|
|
276
|
+
2. **Is the spoken text ≤ 2 sentences, no markdown, no enumerations?**
|
|
277
|
+
3. **🚫 Does my spoken text recite items that are already in my card?** If yes, **rewrite the speech as a lead-in only** ("Here are the top five, Bruno."). Speaking the card aloud is the #1 failure mode of this skill. Re-read the spoken text and the card together — if you remove the card, would the voice still make sense as the standalone answer? If yes, you're double-answering. Trim the voice.
|
|
278
|
+
4. **If I'm sending a card, does it add structure the voice can't carry?** If a sentence covers it, drop the card.
|
|
279
|
+
5. **Does my voice acknowledge the card if I sent one?** ("Here it is.", "Pinned it up top.", etc.)
|
|
280
|
+
6. **Did I check for a PRESET first** ([`presets/PRESETS.md`](presets/PRESETS.md))? Only hand-write `<notch_html>` if no preset fits. (For custom, did I check `frequentSnippets/` for one I already made?)
|
|
281
|
+
7. **If it's a preset:** is the body **valid JSON**, and is `type` one of the real preset names (lowercase)?
|
|
282
|
+
8. **If it's custom:** is the card ≤ 383×147pt, transparent-on-black, white text, no external assets?
|
|
283
|
+
9. **Is the tag spelled exactly `<notch_card type="…">…</notch_card>` or `<notch_html>…</notch_html>` (lowercase, underscore)?**
|
|
284
|
+
10. **If I'm offering to save a custom card for next time, did I say so plainly?**
|
|
208
285
|
|
|
209
286
|
---
|
|
210
287
|
|
|
@@ -213,10 +290,13 @@ Before you send:
|
|
|
213
290
|
| Thing | Where / how |
|
|
214
291
|
|---|---|
|
|
215
292
|
| Tag that activates this skill | `[Mac]` at the start of the user message |
|
|
216
|
-
|
|
|
293
|
+
| **Preset card tag (preferred)** | `<notch_card type="…">{ …json… }</notch_card>` |
|
|
294
|
+
| Preset catalog + schemas | [`presets/PRESETS.md`](presets/PRESETS.md) — email, list, calendar, weather, ticker, stat, info, text, comparison |
|
|
295
|
+
| Custom card tag (escape hatch) | `<notch_html>…</notch_html>` (singular, anywhere in your reply) |
|
|
217
296
|
| Canvas size | **383 × 147 pt**, transparent over **black** |
|
|
218
|
-
|
|
|
297
|
+
| Custom snippet library | `workspace/skills/mac/frequentSnippets/*.html` |
|
|
219
298
|
| TTS engine | ElevenLabs (Morphy handles it; you just write the words) |
|
|
220
|
-
| Stripped from speech | Anything inside `<notch_html
|
|
221
|
-
|
|
|
222
|
-
| Auto-
|
|
299
|
+
| Stripped from speech | Anything inside `<notch_card …>…` or `<notch_html>…` (case-insensitive, multi-line) |
|
|
300
|
+
| Long text | **Scrollable** — the user scrolls long cards (email/list/calendar/text) with the trackpad |
|
|
301
|
+
| Auto-opens notch? | Yes — sending a card ⇒ notch slides down automatically as audio starts |
|
|
302
|
+
| Auto-clears? | When the human triggers the next push-to-talk, or after the safety timer |
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
# Notch card presets — data schemas
|
|
2
|
+
|
|
3
|
+
Morphy ships a set of **beautiful, pre-built card renderers**. You send only the
|
|
4
|
+
**data**; Morphy owns the layout, the typography, the colors, the scrolling. This
|
|
5
|
+
is the fast, pretty path — use it whenever a preset fits. You never write CSS for
|
|
6
|
+
these, and the card always looks on-brand.
|
|
7
|
+
|
|
8
|
+
## How to send a preset
|
|
9
|
+
|
|
10
|
+
Put one block anywhere in your `[Mac]` reply (it's stripped from TTS, never
|
|
11
|
+
spoken):
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
<notch_card type="PRESET_NAME">
|
|
15
|
+
{ ...JSON data for that preset... }
|
|
16
|
+
</notch_card>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- `type` is the preset name (lowercase) from the table below.
|
|
20
|
+
- The body is a **single JSON object**. Use valid JSON — double-quote keys and
|
|
21
|
+
strings, escape newlines inside strings as `\n` (multi-line text is fine and
|
|
22
|
+
encouraged for `email`/`text` bodies; it renders with real line breaks).
|
|
23
|
+
- Unknown fields are ignored. Missing optional fields just don't render.
|
|
24
|
+
- If the `type` is unknown or the JSON is malformed, Morphy shows **no card** (and
|
|
25
|
+
nothing leaks into your spoken reply) — so a typo fails safe, not loud.
|
|
26
|
+
|
|
27
|
+
The same voice rules apply as always: **don't read the card's contents aloud** —
|
|
28
|
+
the voice is a short lead-in, the card carries the detail. See `SKILL.md`.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Presets
|
|
33
|
+
|
|
34
|
+
### `stat` — one big number
|
|
35
|
+
A single hero value with a label and caption. Time, countdown, %, rate, score.
|
|
36
|
+
|
|
37
|
+
| Field | Req | Notes |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `label` | ✓ | small uppercase tag, e.g. `"TOKYO"` |
|
|
40
|
+
| `value` | ✓ | the hero string, e.g. `"8:14 PM"` |
|
|
41
|
+
| `caption` | – | muted line under it |
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
<notch_card type="stat">
|
|
45
|
+
{ "label": "TOKYO", "value": "8:14 PM", "caption": "Thursday, May 28" }
|
|
46
|
+
</notch_card>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `info` — header + two key/value tiles
|
|
50
|
+
Two metrics side by side under a title.
|
|
51
|
+
|
|
52
|
+
| Field | Req | Notes |
|
|
53
|
+
|---|---|---|
|
|
54
|
+
| `title` | ✓ | bold header |
|
|
55
|
+
| `subtitle` | – | muted line under the title |
|
|
56
|
+
| `left_label`, `left_value` | ✓ | first tile |
|
|
57
|
+
| `right_label`, `right_value` | ✓ | second tile |
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
<notch_card type="info">
|
|
61
|
+
{ "title": "Connection", "subtitle": "VPN · Frankfurt",
|
|
62
|
+
"left_label": "Latency", "left_value": "42 ms",
|
|
63
|
+
"right_label": "Loss", "right_value": "0%" }
|
|
64
|
+
</notch_card>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### `email` — a single email
|
|
68
|
+
Sender with an auto-generated initial avatar, subject, time, and a body the user
|
|
69
|
+
can **scroll** if it's long. Perfect for "read me that email."
|
|
70
|
+
|
|
71
|
+
| Field | Req | Notes |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `from` | ✓ | sender name |
|
|
74
|
+
| `body` | ✓ | full text; use `\n` for paragraphs |
|
|
75
|
+
| `subject` | – | shown under the sender, truncated |
|
|
76
|
+
| `time` | – | top-right, e.g. `"2:14 PM"` |
|
|
77
|
+
| `initial` | – | avatar letter; **auto-derived from `from`** if omitted |
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
<notch_card type="email">
|
|
81
|
+
{ "from": "Alex Chen", "time": "2:14 PM", "subject": "Migration plan",
|
|
82
|
+
"body": "Can we move the cutover to Tuesday?\n\nStaging looked clean last night." }
|
|
83
|
+
</notch_card>
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### `list` — ranked / labelled rows
|
|
87
|
+
A scrolling list. Use for unread mail, todos, news, search results, top-N.
|
|
88
|
+
|
|
89
|
+
| Field | Req | Notes |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `title` | ✓ | header |
|
|
92
|
+
| `items` | ✓ | array of objects (see below) |
|
|
93
|
+
| `page`, `pages` | – | if both set and `pages > 1`, draws page dots; say "next" in voice and resend with the next `page` |
|
|
94
|
+
|
|
95
|
+
Each item: `{ "title": ✓, "meta"?: "secondary line", "value"?: "right-aligned tag", "index"?: "1" }`
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
<notch_card type="list">
|
|
99
|
+
{ "title": "Unread mail", "page": 1, "pages": 3,
|
|
100
|
+
"items": [
|
|
101
|
+
{ "index": "1", "title": "Alex Chen", "meta": "Migration plan", "value": "2m" },
|
|
102
|
+
{ "index": "2", "title": "Figma", "meta": "3 new comments", "value": "1h" },
|
|
103
|
+
{ "index": "3", "title": "GitHub", "meta": "CI passed on main", "value": "3h" }
|
|
104
|
+
] }
|
|
105
|
+
</notch_card>
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### `calendar` — day + events
|
|
109
|
+
Day hero with a scrolling event list and a built-in empty state.
|
|
110
|
+
|
|
111
|
+
| Field | Req | Notes |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `weekday` | ✓ | e.g. `"Thu"` |
|
|
114
|
+
| `date` | ✓ | e.g. `"May 28"` |
|
|
115
|
+
| `count` | – | top-right, e.g. `"4 events"` |
|
|
116
|
+
| `events` | ✓ | array; if empty, renders "Nothing scheduled." |
|
|
117
|
+
|
|
118
|
+
Each event: `{ "time": "10:00", "title": "Stand-up", "duration"?: "30m" }`
|
|
119
|
+
|
|
120
|
+
```
|
|
121
|
+
<notch_card type="calendar">
|
|
122
|
+
{ "weekday": "Thu", "date": "May 28", "count": "3 events",
|
|
123
|
+
"events": [
|
|
124
|
+
{ "time": "10:00", "title": "Stand-up", "duration": "30m" },
|
|
125
|
+
{ "time": "14:00", "title": "Design review", "duration": "1h" },
|
|
126
|
+
{ "time": "16:30", "title": "1:1 with Sam", "duration": "30m" }
|
|
127
|
+
] }
|
|
128
|
+
</notch_card>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### `weather` — current conditions
|
|
132
|
+
Big temp, an **auto-selected line-art glyph** (from `condition`), high/low, and an
|
|
133
|
+
optional third tile.
|
|
134
|
+
|
|
135
|
+
| Field | Req | Notes |
|
|
136
|
+
|---|---|---|
|
|
137
|
+
| `location` | ✓ | uppercase label |
|
|
138
|
+
| `temp` | ✓ | number/string; a `°` is appended by the template |
|
|
139
|
+
| `condition` | ✓ | text; also picks the glyph (keywords: clear/sun, partly, cloud, rain, snow, storm/thunder, fog/mist) |
|
|
140
|
+
| `high`, `low` | ✓ | `°` appended |
|
|
141
|
+
| `extra_label`, `extra_value` | – | optional third tile (e.g. Wind) |
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
<notch_card type="weather">
|
|
145
|
+
{ "location": "San Francisco", "temp": "17", "condition": "Partly cloudy",
|
|
146
|
+
"high": "19", "low": "12", "extra_label": "Wind", "extra_value": "12mph" }
|
|
147
|
+
</notch_card>
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### `ticker` — finance quote
|
|
151
|
+
Symbol, name, price, a **color-coded change** (green ↑ / red ↓, inferred from a
|
|
152
|
+
leading `-`), and an **auto-generated sparkline** from a number array.
|
|
153
|
+
|
|
154
|
+
| Field | Req | Notes |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `symbol` | ✓ | e.g. `"TSLA"` |
|
|
157
|
+
| `price` | ✓ | e.g. `"$248.50"` |
|
|
158
|
+
| `change` | ✓ | e.g. `"+2.4%"` or `"-1.1%"` (sign drives the color) |
|
|
159
|
+
| `name` | – | company name, truncated |
|
|
160
|
+
| `points` | – | array of numbers → the sparkline chart (needs ≥ 2 values) |
|
|
161
|
+
|
|
162
|
+
> **To get the little chart, you MUST include `points`.** Without it the card
|
|
163
|
+
> renders price + change but **no chart**. Fetch ~8–30 recent values (intraday
|
|
164
|
+
> prices, or the last N daily closes) and pass them as a plain number array —
|
|
165
|
+
> exact scale doesn't matter, the sparkline auto-normalizes. If you genuinely
|
|
166
|
+
> can't get a series, omit `points` and the card still looks fine without it.
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
<notch_card type="ticker">
|
|
170
|
+
{ "symbol": "TSLA", "name": "Tesla Inc", "price": "$248.50", "change": "+2.4%",
|
|
171
|
+
"points": [241, 239, 244, 242, 247, 245, 250, 248.5] }
|
|
172
|
+
</notch_card>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### `text` — title + long body
|
|
176
|
+
A title (optional) and a body the user can **scroll** when it overflows. Use for
|
|
177
|
+
summaries, explanations, "read me this", a quote, a paragraph answer.
|
|
178
|
+
|
|
179
|
+
| Field | Req | Notes |
|
|
180
|
+
|---|---|---|
|
|
181
|
+
| `body` | ✓ | the text; `\n` for paragraphs |
|
|
182
|
+
| `title` | – | header (with a divider) if present |
|
|
183
|
+
| `tag` | – | small label top-right (e.g. `"#482"`) |
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
<notch_card type="text">
|
|
187
|
+
{ "title": "PR summary", "tag": "#482",
|
|
188
|
+
"body": "Refactors the notch pipeline into a preset renderer.\n\nAdds nine presets the user can scroll." }
|
|
189
|
+
</notch_card>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### `comparison` — two columns
|
|
193
|
+
Side-by-side options, each with a value and a note.
|
|
194
|
+
|
|
195
|
+
| Field | Req | Notes |
|
|
196
|
+
|---|---|---|
|
|
197
|
+
| `title` | ✓ | header |
|
|
198
|
+
| `left_title`, `left_value` | ✓ | first column |
|
|
199
|
+
| `right_title`, `right_value` | ✓ | second column |
|
|
200
|
+
| `left_note`, `right_note` | – | muted line under each value |
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
<notch_card type="comparison">
|
|
204
|
+
{ "title": "Postgres vs SQLite",
|
|
205
|
+
"left_title": "Postgres", "left_value": "Concurrent ✓", "left_note": "Heavier setup",
|
|
206
|
+
"right_title": "SQLite", "right_value": "Single-writer", "right_note": "Zero setup" }
|
|
207
|
+
</notch_card>
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## When no preset fits → go custom
|
|
213
|
+
|
|
214
|
+
If the answer needs a shape these don't cover, hand-write the whole card with
|
|
215
|
+
`<notch_html>…</notch_html>` instead (see `SKILL.md` → custom snippets). And if you
|
|
216
|
+
build a custom card you'll reuse, save it to `frequentSnippets/` so next time is a
|
|
217
|
+
copy-fill-send. When a custom card you've made gets requested a lot, tell Bruno —
|
|
218
|
+
it's a candidate for a real shipped preset.
|
|
219
|
+
|
|
220
|
+
## Notes
|
|
221
|
+
|
|
222
|
+
- **Scrollable.** Long `email` / `list` / `calendar` / `text` content is scrollable —
|
|
223
|
+
the user scrolls it with the trackpad (a thin scrollbar appears). For very long
|
|
224
|
+
lists you can still paginate via voice ("say next").
|
|
225
|
+
- **Keep it to one idea.** The canvas is tiny (383 × 147 pt). A `list` realistically
|
|
226
|
+
shows ~4 rows before it has to scroll — lead with the most important ones.
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
|
|
2
|
-
@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-space-x-reverse:0;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction: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-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;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-100:oklch(93.6% .032 17.717);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-red-800:oklch(44.4% .177 26.899);--color-orange-400:oklch(75% .183 55.934);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--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:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wider:.05em;--tracking-widest:.1em;--leading-tight:1.25;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--ease-out:cubic-bezier(0, 0, .2, 1);--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0, 0, .2, 1) infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--animate-bounce:bounce 1s infinite;--blur-sm:8px;--blur-md:12px;--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);--color-background:#1a1a1a;--color-foreground:#ebebeb}}@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%;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;-webkit-text-decoration:inherit;-webkit-text-decoration: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]){appearance:button}::file-selector-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-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.-top-2\.5{top:calc(var(--spacing) * -2.5)}.top-1{top:calc(var(--spacing) * 1)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-4{top:calc(var(--spacing) * 4)}.top-full{top:100%}.-right-1\.5{right:calc(var(--spacing) * -1.5)}.right-0{right:calc(var(--spacing) * 0)}.right-2{right:calc(var(--spacing) * 2)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.bottom-2{bottom:calc(var(--spacing) * 2)}.bottom-4{bottom:calc(var(--spacing) * 4)}.left-0{left:calc(var(--spacing) * 0)}.left-1\/2{left:50%}.left-2{left:calc(var(--spacing) * 2)}.left-3{left:calc(var(--spacing) * 3)}.left-4{left:calc(var(--spacing) * 4)}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[200\]{z-index:200}.z-\[300\]{z-index:300}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-4{margin-inline:calc(var(--spacing) * 4)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-3{margin-block:calc(var(--spacing) * 3)}.my-4{margin-block:calc(var(--spacing) * 4)}.my-6{margin-block:calc(var(--spacing) * 6)}.-mt-3{margin-top:calc(var(--spacing) * -3)}.-mt-10{margin-top:calc(var(--spacing) * -10)}.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)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-px{margin-top:1px}.mr-1\.5{margin-right:calc(var(--spacing) * 1.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-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)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-2\.5{margin-left:calc(var(--spacing) * 2.5)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.list-item{display:list-item}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-full{width:100%;height:100%}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.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-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-14{height:calc(var(--spacing) * 14)}.h-16{height:calc(var(--spacing) * 16)}.h-28{height:calc(var(--spacing) * 28)}.h-\[18px\]{height:18px}.h-\[22px\]{height:22px}.h-\[46px\]{height:46px}.h-\[140px\]{height:140px}.h-\[180px\]{height:180px}.h-dvh{height:100dvh}.h-full{height:100%}.max-h-32{max-height:calc(var(--spacing) * 32)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-\[85vh\]{max-height:85vh}.max-h-\[320px\]{max-height:320px}.max-h-\[500px\]{max-height:500px}.min-h-0{min-height:calc(var(--spacing) * 0)}.min-h-28{min-height:calc(var(--spacing) * 28)}.min-h-\[200px\]{min-height:200px}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.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-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-28{width:calc(var(--spacing) * 28)}.w-32{width:calc(var(--spacing) * 32)}.w-48{width:calc(var(--spacing) * 48)}.w-\[18px\]{width:18px}.w-\[140px\]{width:140px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-\[85\%\]{max-width:85%}.max-w-\[90vw\]{max-width:90vw}.max-w-\[320px\]{max-width:320px}.max-w-\[340px\]{max-width:340px}.max-w-\[360px\]{max-width:360px}.max-w-\[480px\]{max-width:480px}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-\[120px\]{min-width:120px}.min-w-\[180px\]{min-width:180px}.min-w-\[220px\]{min-width:220px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.origin-center{transform-origin:50%}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-0{--tw-translate-x:calc(var(--spacing) * 0);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-1{--tw-translate-x:calc(var(--spacing) * 1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-\[18px\]{--tw-translate-x:18px;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-bounce{animation:var(--animate-bounce)}.animate-ping{animation:var(--animate-ping)}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.list-inside{list-style-position:inside}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-start{justify-content:flex-start}.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-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-3\.5{gap:calc(var(--spacing) * 3.5)}.gap-4{gap:calc(var(--spacing) * 4)}: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)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-x-2>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * 2) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-border>:not(:last-child)){border-color:#333}.self-end{align-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.75rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[24px\]{border-radius:24px}.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-2{border-style:var(--tw-border-style);border-width:2px}.border-\[1\.5px\]{border-style:var(--tw-border-style);border-width:1.5px}.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-b-2{border-bottom-style:var(--tw-border-style);border-bottom-width:2px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-\[\#00CAFF\]\/20{border-color:oklab(78.0899% -.104231 -.105835/.2)}.border-\[\#25D366\]\/20{border-color:oklab(76.0953% -.174012 .10152/.2)}.border-\[\#AF27E3\]{border-color:#af27e3}.border-\[\#AF27E3\]\/10{border-color:oklab(57.9061% .181738 -.18985/.1)}.border-\[\#AF27E3\]\/20{border-color:oklab(57.9061% .181738 -.18985/.2)}.border-\[\#AF27E3\]\/30{border-color:oklab(57.9061% .181738 -.18985/.3)}.border-\[\#AF27E3\]\/40{border-color:oklab(57.9061% .181738 -.18985/.4)}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/20{border-color:color-mix(in oklab, var(--color-amber-500) 20%, transparent)}}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/20{border-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.border-border{border-color:#333}.border-border\/15{border-color:oklab(32.1092% 2.98023e-8 0/.15)}.border-border\/30{border-color:oklab(32.1092% 2.98023e-8 0/.3)}.border-border\/40{border-color:oklab(32.1092% 2.98023e-8 0/.4)}.border-border\/60{border-color:oklab(32.1092% 2.98023e-8 0/.6)}.border-current{border-color:currentColor}.border-emerald-500\/15{border-color:#00bb7f26}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/15{border-color:color-mix(in oklab, var(--color-emerald-500) 15%, transparent)}}.border-emerald-500\/20{border-color:#00bb7f33}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/20{border-color:color-mix(in oklab, var(--color-emerald-500) 20%, transparent)}}.border-muted-foreground\/20{border-color:oklab(68.2953% 2.98023e-8 5.96046e-8/.2)}.border-muted-foreground\/30{border-color:oklab(68.2953% 2.98023e-8 5.96046e-8/.3)}.border-red-500\/15{border-color:#fb2c3626}@supports (color:color-mix(in lab, red, red)){.border-red-500\/15{border-color:color-mix(in oklab, var(--color-red-500) 15%, transparent)}}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.border-red-500\/20{border-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.border-sidebar{border-color:#222}.border-white\/10{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.border-white\/10{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.border-white\/20{border-color:#fff3}@supports (color:color-mix(in lab, red, red)){.border-white\/20{border-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.border-white\/\[0\.04\]{border-color:#ffffff0a}@supports (color:color-mix(in lab, red, red)){.border-white\/\[0\.04\]{border-color:color-mix(in oklab, var(--color-white) 4%, transparent)}}.border-white\/\[0\.06\]{border-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.border-white\/\[0\.06\]{border-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.border-white\/\[0\.08\]{border-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.border-white\/\[0\.08\]{border-color:color-mix(in oklab, var(--color-white) 8%, transparent)}}.border-white\/\[0\.12\]{border-color:#ffffff1f}@supports (color:color-mix(in lab, red, red)){.border-white\/\[0\.12\]{border-color:color-mix(in oklab, var(--color-white) 12%, transparent)}}.border-t-\[\#04D1FE\]{border-top-color:#04d1fe}.border-t-muted-foreground\/60{border-top-color:oklab(68.2953% 2.98023e-8 5.96046e-8/.6)}.border-t-primary{border-top-color:#4c89f2}.border-t-white\/50{border-top-color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.border-t-white\/50{border-top-color:color-mix(in oklab, var(--color-white) 50%, transparent)}}.bg-\[\#00CAFF\]{background-color:#00caff}.bg-\[\#00CAFF\]\/10{background-color:oklab(78.0899% -.104231 -.105835/.1)}.bg-\[\#1c1c1e\]{background-color:#1c1c1e}.bg-\[\#007AFF\]\/15{background-color:oklab(60.2765% -.047404 -.212489/.15)}.bg-\[\#25D366\]{background-color:#25d366}.bg-\[\#25D366\]\/10{background-color:oklab(76.0953% -.174012 .10152/.1)}.bg-\[\#222\]{background-color:#222}.bg-\[\#181818\]{background-color:#181818}.bg-\[\#AF27E3\]{background-color:#af27e3}.bg-\[\#AF27E3\]\/10{background-color:oklab(57.9061% .181738 -.18985/.1)}.bg-\[\#AF27E3\]\/15{background-color:oklab(57.9061% .181738 -.18985/.15)}.bg-\[var\(--sdm-tbg\)\]{background-color:var(--sdm-tbg)}.bg-amber-500\/8{background-color:#f99c0014}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/8{background-color:color-mix(in oklab, var(--color-amber-500) 8%, transparent)}}.bg-amber-500\/15{background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/15{background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.bg-amber-600{background-color:var(--color-amber-600)}.bg-background{background-color:#1a1a1a}.bg-background\/50{background-color:oklab(21.7786% -7.45058e-9 0/.5)}.bg-background\/80{background-color:oklab(21.7786% -7.45058e-9 0/.8)}.bg-background\/90{background-color:oklab(21.7786% -7.45058e-9 0/.9)}.bg-background\/95{background-color:oklab(21.7786% -7.45058e-9 0/.95)}.bg-black\/10{background-color:#0000001a}@supports (color:color-mix(in lab, red, red)){.bg-black\/10{background-color:color-mix(in oklab, var(--color-black) 10%, transparent)}}.bg-black\/20{background-color:#0003}@supports (color:color-mix(in lab, red, red)){.bg-black\/20{background-color:color-mix(in oklab, var(--color-black) 20%, transparent)}}.bg-black\/60{background-color:#0009}@supports (color:color-mix(in lab, red, red)){.bg-black\/60{background-color:color-mix(in oklab, var(--color-black) 60%, transparent)}}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab, red, red)){.bg-black\/80{background-color:color-mix(in oklab, var(--color-black) 80%, transparent)}}.bg-black\/85{background-color:#000000d9}@supports (color:color-mix(in lab, red, red)){.bg-black\/85{background-color:color-mix(in oklab, var(--color-black) 85%, transparent)}}.bg-black\/90{background-color:#000000e6}@supports (color:color-mix(in lab, red, red)){.bg-black\/90{background-color:color-mix(in oklab, var(--color-black) 90%, transparent)}}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\/10{background-color:color-mix(in oklab, var(--color-blue-500) 10%, transparent)}}.bg-card\/50{background-color:oklab(25.1965% -7.45058e-9 0/.5)}.bg-destructive{background-color:#f04d68}.bg-destructive\/10{background-color:oklab(65.3498% .191597 .0514832/.1)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-500\/5{background-color:#00bb7f0d}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/5{background-color:color-mix(in oklab, var(--color-emerald-500) 5%, transparent)}}.bg-emerald-500\/8{background-color:#00bb7f14}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/8{background-color:color-mix(in oklab, var(--color-emerald-500) 8%, transparent)}}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-emerald-500\/15{background-color:#00bb7f26}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/15{background-color:color-mix(in oklab, var(--color-emerald-500) 15%, transparent)}}.bg-emerald-500\/20{background-color:#00bb7f33}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/20{background-color:color-mix(in oklab, var(--color-emerald-500) 20%, transparent)}}.bg-emerald-500\/\[0\.04\]{background-color:#00bb7f0a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/\[0\.04\]{background-color:color-mix(in oklab, var(--color-emerald-500) 4%, transparent)}}.bg-gray-200{background-color:var(--color-gray-200)}.bg-muted{background-color:#272727}.bg-muted-foreground\/60{background-color:oklab(68.2953% 2.98023e-8 5.96046e-8/.6)}.bg-muted\/20{background-color:oklab(27.2741% 7.45058e-8 0/.2)}.bg-muted\/30{background-color:oklab(27.2741% 7.45058e-8 0/.3)}.bg-muted\/80{background-color:oklab(27.2741% 7.45058e-8 0/.8)}.bg-orange-400{background-color:var(--color-orange-400)}.bg-popover{background-color:#252525}.bg-primary{background-color:#4c89f2}.bg-primary\/10{background-color:oklab(64.1305% -.0280459 -.167453/.1)}.bg-red-50{background-color:var(--color-red-50)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/8{background-color:#fb2c3614}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/8{background-color:color-mix(in oklab, var(--color-red-500) 8%, transparent)}}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-sidebar{background-color:#222}.bg-sidebar\/80{background-color:oklab(25.1965% -7.45058e-9 0/.8)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.bg-white\/5{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\/5{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-white\/15{background-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.bg-white\/15{background-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.bg-white\/20{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.bg-white\/20{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.bg-white\/70{background-color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.bg-white\/70{background-color:color-mix(in oklab, var(--color-white) 70%, transparent)}}.bg-white\/\[0\.02\]{background-color:#ffffff05}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.02\]{background-color:color-mix(in oklab, var(--color-white) 2%, transparent)}}.bg-white\/\[0\.03\]{background-color:#ffffff08}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.03\]{background-color:color-mix(in oklab, var(--color-white) 3%, transparent)}}.bg-white\/\[0\.04\]{background-color:#ffffff0a}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.04\]{background-color:color-mix(in oklab, var(--color-white) 4%, transparent)}}.bg-white\/\[0\.05\]{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.05\]{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.bg-white\/\[0\.06\]{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.06\]{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.bg-white\/\[0\.08\]{background-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.bg-white\/\[0\.08\]{background-color:color-mix(in oklab, var(--color-white) 8%, transparent)}}.fill-current{fill:currentColor}.fill-white{fill:var(--color-white)}.object-contain{object-fit:contain}.object-cover{object-fit:cover}.p-1{padding:calc(var(--spacing) * 1)}.p-1\.5{padding:calc(var(--spacing) * 1.5)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.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)}.px-7{padding-inline:calc(var(--spacing) * 7)}.px-8{padding-inline:calc(var(--spacing) * 8)}.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-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-0{padding-top:calc(var(--spacing) * 0)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-1\.5{padding-top:calc(var(--spacing) * 1.5)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-10{padding-right:calc(var(--spacing) * 10)}.pr-16{padding-right:calc(var(--spacing) * 16)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-5{padding-bottom:calc(var(--spacing) * 5)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pb-8{padding-bottom:calc(var(--spacing) * 8)}.pl-1{padding-left:calc(var(--spacing) * 1)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.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-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[8px\]{font-size:8px}.text-\[10\.5px\]{font-size:10.5px}.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}.text-\[17px\]{font-size:17px}.text-\[20px\]{font-size:20px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.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-\[-0\.01em\]{--tw-tracking:-.01em;letter-spacing:-.01em}.tracking-\[0\.3em\]{--tw-tracking:.3em;letter-spacing:.3em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.wrap-anywhere{overflow-wrap:anywhere}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-line{white-space:pre-line}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[\#00CAFF\]{color:#00caff}.text-\[\#4C89F2\]{color:#4c89f2}.text-\[\#007AFF\]{color:#007aff}.text-\[\#25D366\]{color:#25d366}.text-\[\#AF27E3\]{color:#af27e3}.text-\[\#AF27E3\]\/60{color:oklab(57.9061% .181738 -.18985/.6)}.text-\[var\(--sdm-c\,inherit\)\]{color:var(--sdm-c,inherit)}.text-amber-400{color:var(--color-amber-400)}.text-amber-400\/50{color:#fcbb0080}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/50{color:color-mix(in oklab, var(--color-amber-400) 50%, transparent)}}.text-amber-400\/60{color:#fcbb0099}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/60{color:color-mix(in oklab, var(--color-amber-400) 60%, transparent)}}.text-amber-400\/70{color:#fcbb00b3}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/70{color:color-mix(in oklab, var(--color-amber-400) 70%, transparent)}}.text-amber-400\/90{color:#fcbb00e6}@supports (color:color-mix(in lab, red, red)){.text-amber-400\/90{color:color-mix(in oklab, var(--color-amber-400) 90%, transparent)}}.text-blue-400{color:var(--color-blue-400)}.text-destructive{color:#f04d68}.text-destructive-foreground{color:#fff}.text-emerald-400{color:var(--color-emerald-400)}.text-emerald-400\/60{color:#00d29499}@supports (color:color-mix(in lab, red, red)){.text-emerald-400\/60{color:color-mix(in oklab, var(--color-emerald-400) 60%, transparent)}}.text-emerald-400\/70{color:#00d294b3}@supports (color:color-mix(in lab, red, red)){.text-emerald-400\/70{color:color-mix(in oklab, var(--color-emerald-400) 70%, transparent)}}.text-emerald-400\/90{color:#00d294e6}@supports (color:color-mix(in lab, red, red)){.text-emerald-400\/90{color:color-mix(in oklab, var(--color-emerald-400) 90%, transparent)}}.text-foreground{color:#ebebeb}.text-foreground\/80{color:oklab(94.007% 1.19209e-7 0/.8)}.text-gray-400{color:var(--color-gray-400)}.text-gray-900{color:var(--color-gray-900)}.text-muted-foreground{color:#999}.text-muted-foreground\/35{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.35)}.text-muted-foreground\/40{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.4)}.text-muted-foreground\/50{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.5)}.text-muted-foreground\/60{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.6)}.text-muted-foreground\/70{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.7)}.text-primary{color:#4c89f2}.text-primary-foreground{color:#fff}.text-primary-foreground\/60{color:oklab(100% 0 5.96046e-8/.6)}.text-red-400{color:var(--color-red-400)}.text-red-400\/70{color:#ff6568b3}@supports (color:color-mix(in lab, red, red)){.text-red-400\/70{color:color-mix(in oklab, var(--color-red-400) 70%, transparent)}}.text-red-400\/90{color:#ff6568e6}@supports (color:color-mix(in lab, red, red)){.text-red-400\/90{color:color-mix(in oklab, var(--color-red-400) 90%, transparent)}}.text-red-600{color:var(--color-red-600)}.text-red-700{color:var(--color-red-700)}.text-red-800{color:var(--color-red-800)}.text-white{color:var(--color-white)}.text-white\/20{color:#fff3}@supports (color:color-mix(in lab, red, red)){.text-white\/20{color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.text-white\/25{color:#ffffff40}@supports (color:color-mix(in lab, red, red)){.text-white\/25{color:color-mix(in oklab, var(--color-white) 25%, transparent)}}.text-white\/30{color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.text-white\/30{color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.text-white\/35{color:#ffffff59}@supports (color:color-mix(in lab, red, red)){.text-white\/35{color:color-mix(in oklab, var(--color-white) 35%, transparent)}}.text-white\/40{color:#fff6}@supports (color:color-mix(in lab, red, red)){.text-white\/40{color:color-mix(in oklab, var(--color-white) 40%, transparent)}}.text-white\/50{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.text-white\/50{color:color-mix(in oklab, var(--color-white) 50%, transparent)}}.text-white\/60{color:#fff9}@supports (color:color-mix(in lab, red, red)){.text-white\/60{color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.text-white\/70{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.text-white\/70{color:color-mix(in oklab, var(--color-white) 70%, transparent)}}.text-white\/80{color:#fffc}@supports (color:color-mix(in lab, red, red)){.text-white\/80{color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.decoration-\[\#4C89F2\]\/30{text-decoration-color:oklab(64.1305% -.0280459 -.167453/.3)}.underline-offset-2{text-underline-offset:2px}.accent-emerald-500{accent-color:var(--color-emerald-500)}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.opacity-100{opacity:1}.shadow{--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)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);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)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px 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)}.backdrop-blur-md{--tw-backdrop-blur:blur(var(--blur-md));-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,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-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-\[width\]{transition-property:width;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-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.will-change-transform{will-change:transform}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\[counter-increment\:line_0\]{counter-increment:line 0}.\[counter-reset\:line\]{counter-reset:line}@media (hover:hover){.group-hover\:block:is(:where(.group):hover *){display:block}.group-hover\:text-white\/60:is(:where(.group):hover *){color:#fff9}@supports (color:color-mix(in lab, red, red)){.group-hover\:text-white\/60:is(:where(.group):hover *){color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.group-hover\:opacity-100:is(:where(.group):hover *),.group-hover\/img\:opacity-100:is(:where(.group\/img):hover *){opacity:1}}.placeholder\:text-gray-400::placeholder{color:var(--color-gray-400)}.placeholder\:text-muted-foreground\/40::placeholder{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.4)}.placeholder\:text-white\/20::placeholder{color:#fff3}@supports (color:color-mix(in lab, red, red)){.placeholder\:text-white\/20::placeholder{color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.before\:mr-4:before{content:var(--tw-content);margin-right:calc(var(--spacing) * 4)}.before\:inline-block:before{content:var(--tw-content);display:inline-block}.before\:w-6:before{content:var(--tw-content);width:calc(var(--spacing) * 6)}.before\:text-right:before{content:var(--tw-content);text-align:right}.before\:font-mono:before{content:var(--tw-content);font-family:var(--font-mono)}.before\:text-\[13px\]:before{content:var(--tw-content);font-size:13px}.before\:text-muted-foreground\/50:before{content:var(--tw-content);color:oklab(68.2953% 2.98023e-8 5.96046e-8/.5)}.before\:content-\[counter\(line\)\]:before{--tw-content:counter(line);content:var(--tw-content)}.before\:select-none:before{content:var(--tw-content);-webkit-user-select:none;user-select:none}.before\:\[counter-increment\:line\]:before{content:var(--tw-content);counter-increment:line}@media (hover:hover){.hover\:border-white\/10:hover{border-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:border-white\/10:hover{border-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:border-white\/15:hover{border-color:#ffffff26}@supports (color:color-mix(in lab, red, red)){.hover\:border-white\/15:hover{border-color:color-mix(in oklab, var(--color-white) 15%, transparent)}}.hover\:bg-\[\#00CAFF\]\/15:hover{background-color:oklab(78.0899% -.104231 -.105835/.15)}.hover\:bg-\[\#25D366\]\/15:hover{background-color:oklab(76.0953% -.174012 .10152/.15)}.hover\:bg-amber-500:hover{background-color:var(--color-amber-500)}.hover\:bg-background:hover{background-color:#1a1a1a}.hover\:bg-black\/80:hover{background-color:#000c}@supports (color:color-mix(in lab, red, red)){.hover\:bg-black\/80:hover{background-color:color-mix(in oklab, var(--color-black) 80%, transparent)}}.hover\:bg-destructive\/20:hover{background-color:oklab(65.3498% .191597 .0514832/.2)}.hover\:bg-destructive\/90:hover{background-color:oklab(65.3498% .191597 .0514832/.9)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-muted:hover{background-color:#272727}.hover\:bg-muted\/40:hover{background-color:oklab(27.2741% 7.45058e-8 0/.4)}.hover\:bg-primary\/20:hover{background-color:oklab(64.1305% -.0280459 -.167453/.2)}.hover\:bg-primary\/90:hover{background-color:oklab(64.1305% -.0280459 -.167453/.9)}.hover\:bg-red-500\/20:hover{background-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.hover\:bg-red-500\/20:hover{background-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.hover\:bg-white\/20:hover{background-color:#fff3}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/20:hover{background-color:color-mix(in oklab, var(--color-white) 20%, transparent)}}.hover\:bg-white\/30:hover{background-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/30:hover{background-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.hover\:bg-white\/\[0\.1\]:hover{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.1\]:hover{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.hover\:bg-white\/\[0\.02\]:hover{background-color:#ffffff05}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.02\]:hover{background-color:color-mix(in oklab, var(--color-white) 2%, transparent)}}.hover\:bg-white\/\[0\.04\]:hover{background-color:#ffffff0a}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.04\]:hover{background-color:color-mix(in oklab, var(--color-white) 4%, transparent)}}.hover\:bg-white\/\[0\.05\]:hover{background-color:#ffffff0d}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.05\]:hover{background-color:color-mix(in oklab, var(--color-white) 5%, transparent)}}.hover\:bg-white\/\[0\.06\]:hover{background-color:#ffffff0f}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.06\]:hover{background-color:color-mix(in oklab, var(--color-white) 6%, transparent)}}.hover\:bg-white\/\[0\.07\]:hover{background-color:#ffffff12}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.07\]:hover{background-color:color-mix(in oklab, var(--color-white) 7.0%, transparent)}}.hover\:bg-white\/\[0\.08\]:hover{background-color:#ffffff14}@supports (color:color-mix(in lab, red, red)){.hover\:bg-white\/\[0\.08\]:hover{background-color:color-mix(in oklab, var(--color-white) 8%, transparent)}}.hover\:text-\[\#c44df7\]:hover{color:#c44df7}.hover\:text-foreground:hover{color:#ebebeb}.hover\:text-gray-600:hover{color:var(--color-gray-600)}.hover\:text-muted-foreground:hover{color:#999}.hover\:text-muted-foreground\/70:hover{color:oklab(68.2953% 2.98023e-8 5.96046e-8/.7)}.hover\:text-white:hover{color:var(--color-white)}.hover\:text-white\/40:hover{color:#fff6}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/40:hover{color:color-mix(in oklab, var(--color-white) 40%, transparent)}}.hover\:text-white\/50:hover{color:#ffffff80}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/50:hover{color:color-mix(in oklab, var(--color-white) 50%, transparent)}}.hover\:text-white\/55:hover{color:#ffffff8c}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/55:hover{color:color-mix(in oklab, var(--color-white) 55%, transparent)}}.hover\:text-white\/60:hover{color:#fff9}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/60:hover{color:color-mix(in oklab, var(--color-white) 60%, transparent)}}.hover\:text-white\/70:hover{color:#ffffffb3}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/70:hover{color:color-mix(in oklab, var(--color-white) 70%, transparent)}}.hover\:text-white\/80:hover{color:#fffc}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/80:hover{color:color-mix(in oklab, var(--color-white) 80%, transparent)}}.hover\:text-white\/90:hover{color:#ffffffe6}@supports (color:color-mix(in lab, red, red)){.hover\:text-white\/90:hover{color:color-mix(in oklab, var(--color-white) 90%, transparent)}}.hover\:decoration-\[\#4C89F2\]:hover{text-decoration-color:#4c89f2}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-90:hover{opacity:.9}}.focus\:border-\[\#AF27E3\]\/30:focus{border-color:oklab(57.9061% .181738 -.18985/.3)}.focus\:border-primary\/50:focus{border-color:oklab(64.1305% -.0280459 -.167453/.5)}.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-primary\/30:focus{--tw-ring-color:oklab(64.1305% -.0280459 -.167453/.3)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@supports ((-webkit-backdrop-filter:var(--tw)) or (backdrop-filter:var(--tw))){.supports-\[backdrop-filter\]\:bg-background\/70{background-color:oklab(21.7787% -7.45058e-9 0/.7)}.supports-\[backdrop-filter\]\:bg-sidebar\/70{background-color:oklab(25.1965% -7.45058e-9 0/.7)}.supports-\[backdrop-filter\]\:backdrop-blur{--tw-backdrop-blur:blur(8px);-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,)}.supports-\[backdrop-filter\]\:backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-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,)}}@media (width>=40rem){.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:items-center{align-items:center}}.dark\:bg-\[var\(--shiki-dark-bg\,var\(--sdm-tbg\)\)\]:is(.dark *){background-color:var(--shiki-dark-bg,var(--sdm-tbg))}.dark\:text-\[var\(--shiki-dark\,var\(--sdm-c\,inherit\)\)\]:is(.dark *){color:var(--shiki-dark,var(--sdm-c,inherit))}.\[\&_svg\]\:h-auto svg{height:auto}.\[\&_svg\]\:w-auto svg{width:auto}.\[\&_thead\]\:sticky thead{position:sticky}.\[\&_thead\]\:top-0 thead{top:calc(var(--spacing) * 0)}.\[\&_thead\]\:z-10 thead{z-index:10}.\[\&\>\*\:first-child\]\:mt-0>:first-child{margin-top:calc(var(--spacing) * 0)}.\[\&\>\*\:last-child\]\:mb-0>:last-child{margin-bottom:calc(var(--spacing) * 0)}.\[\&\>\*\:last-child\]\:after\:inline>:last-child:after{content:var(--tw-content);display:inline}.\[\&\>\*\:last-child\]\:after\:align-baseline>:last-child:after{content:var(--tw-content);vertical-align:baseline}.\[\&\>\*\:last-child\]\:after\:content-\[var\(--streamdown-caret\)\]>:last-child:after{--tw-content:var(--streamdown-caret);content:var(--tw-content)}.\[\&\>p\]\:inline>p{display:inline}li .\[li_\&\]\:pl-6{padding-left:calc(var(--spacing) * 6)}}html{touch-action:manipulation;-ms-touch-action:manipulation}body{background-color:var(--color-background);color:var(--color-foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;overscroll-behavior:none}::selection{background-color:#af27e340}::-webkit-scrollbar{width:6px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:#333;border-radius:3px}::-webkit-scrollbar-thumb:hover{background:#444}.text-gradient{color:#0000;-webkit-text-fill-color:transparent;background-image:linear-gradient(135deg,#04d1fe,#af27e3,#fb4072);-webkit-background-clip:text;background-clip:text}.bg-gradient-brand{background-image:linear-gradient(135deg,#04d1fe,#af27e3,#fb4072)}.glow-border{box-shadow:0 0 0 1px #af27e31a,0 0 20px -5px #af27e326}.animated-border{position:relative;overflow:hidden}.animated-border:before{content:"";background:conic-gradient(#04d1fe,#af27e3,#fb4072,#04d1fe);animation:3s linear infinite border-spin;position:absolute;inset:-150%}.animated-border>*{z-index:1;position:relative}.animated-border-slow:before{animation-duration:5s}.input-glow:focus{border-color:#af27e366;box-shadow:0 0 0 1px #af27e326,0 0 20px -5px #af27e340,0 0 4px -1px #04d1fe1a}@keyframes border-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes mic-pulse-scale{0%,to{transform:scale(1.1)translateY(-6px)}50%{transform:scale(1.15)translateY(-8px)}}@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-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-divide-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-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{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-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}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}@keyframes pulse{50%{opacity:.5}}@keyframes bounce{0%,to{animation-timing-function:cubic-bezier(.8,0,1,1);transform:translateY(-25%)}50%{animation-timing-function:cubic-bezier(0,0,.2,1);transform:none}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{i as e}from"./bloby-vi0Xitb-.js";export{e as Mermaid};
|