@telepath-computer/television 0.1.216 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD-PARTY-NOTICES.txt +336 -0
- package/dist/canonical/v1/frozen.json +6 -0
- package/dist/canonical/v1/styles.css +7 -2
- package/dist/canonical/v2/components.js +1 -0
- package/dist/canonical/v2/fonts/Hind-Variable.933e9900.woff2 +0 -0
- package/dist/canonical/v2/styles.css +1241 -0
- package/dist/cli.cjs +1763 -761
- package/dist/onboarding/README.md +16 -14
- package/dist/onboarding/business-ops/about.html +4 -3
- package/dist/onboarding/business-ops/retention-vs-releases.html +25 -32
- package/dist/onboarding/business-ops/revenue-vs-goals.html +26 -31
- package/dist/onboarding/productivity/about.html +4 -3
- package/dist/onboarding/productivity/company-todos/THIRD-PARTY-NOTICES.txt +29 -0
- package/dist/onboarding/productivity/company-todos/index.html +20 -20
- package/dist/onboarding/productivity/company-todos/task.css +4 -5
- package/dist/onboarding/productivity/company-todos/task.js +1 -1
- package/dist/onboarding/productivity/meeting-prep.html +12 -12
- package/dist/onboarding/productivity/priorities-today.html +10 -10
- package/dist/onboarding/productivity/todays-calendar/calendar.css +1 -1
- package/dist/onboarding/productivity/todays-calendar/index.html +12 -14
- package/dist/onboarding/research/about.html +4 -3
- package/dist/onboarding/research/open-model-research.html +35 -35
- package/dist/onboarding/research/todays-news.html +72 -72
- package/dist/onboarding/tv-guide/welcome.html +178 -0
- package/dist/skills/television/SKILL.md +124 -67
- package/dist/skills/television/theming.md +1086 -0
- package/dist/skills/tv-calendar/SKILL.md +3 -1
- package/dist/skills/tv-calendar/calendar.css +1 -1
- package/dist/skills/tv-table/SKILL.md +5 -2
- package/dist/skills/tv-tasks/SKILL.md +19 -15
- package/dist/skills/tv-tasks/task.css +4 -26
- package/dist/skills/tv-tasks/task.js +1 -1
- package/dist/themes/README.md +5 -0
- package/dist/themes/aquarium/README.md +48 -0
- package/dist/themes/aquarium/iframe-background.js +137 -0
- package/dist/themes/aquarium/manifest.json +7 -0
- package/dist/themes/aquarium/theme.css +46 -0
- package/dist/themes/blueprint/README.md +31 -0
- package/dist/themes/blueprint/manifest.json +6 -0
- package/dist/themes/blueprint/theme.css +115 -0
- package/dist/themes/clouds/README.md +15 -0
- package/dist/themes/clouds/THIRD-PARTY-NOTICES.txt +81 -0
- package/dist/themes/clouds/manifest.json +6 -0
- package/dist/themes/clouds/theme.css +62 -0
- package/dist/themes/clouds/wallpaper-dark.webp +0 -0
- package/dist/themes/clouds/wallpaper.webp +0 -0
- package/dist/themes/crt-phosphor/README.md +31 -0
- package/dist/themes/crt-phosphor/manifest.json +6 -0
- package/dist/themes/crt-phosphor/theme.css +105 -0
- package/dist/themes/nord/README.md +9 -0
- package/dist/themes/nord/THIRD-PARTY-NOTICES.txt +29 -0
- package/dist/themes/nord/manifest.json +5 -0
- package/dist/themes/nord/theme.css +28 -0
- package/dist/themes/swiss/README.md +5 -0
- package/dist/themes/swiss/manifest.json +5 -0
- package/dist/themes/swiss/theme.css +34 -0
- package/dist/themes/tokyo-night/README.md +17 -0
- package/dist/themes/tokyo-night/THIRD-PARTY-NOTICES.txt +235 -0
- package/dist/themes/tokyo-night/manifest.json +5 -0
- package/dist/themes/tokyo-night/theme.css +31 -0
- package/dist/themes/tokyo-night/wallpaper.webp +0 -0
- package/dist/views/artifact-missing/index.html +40 -68
- package/dist/views/markdown/THIRD-PARTY-NOTICES.txt +26 -0
- package/dist/views/markdown/index.html +49 -23
- package/dist/web/THIRD-PARTY-NOTICES.txt +26 -0
- package/dist/web/assets/artifact-bridge-BEUWXKq7.js +1 -0
- package/dist/web/assets/{artifactMissing-BiK_l3Ts.js → artifactMissing-CUs1ZwDx.js} +1 -1
- package/dist/web/assets/main-Bi6QZnn7.css +1 -0
- package/dist/web/assets/main-Dw6rK_zF.js +706 -0
- package/dist/web/assets/{urlUnsupported-RGIrhMDe.js → urlUnsupported-powR79PT.js} +1 -1
- package/dist/web/index.html +40 -5
- package/dist/web/views/artifact-missing/index.html +40 -68
- package/dist/web/views/url-unsupported/index.html +40 -68
- package/package.json +1 -1
- package/dist/onboarding/tv-guide/welcome/assets/television.svg +0 -71
- package/dist/onboarding/tv-guide/welcome/index.html +0 -203
- package/dist/skills/tv-theme/SKILL.md +0 -449
- package/dist/web/assets/artifact-bridge-3Trk-B2L.js +0 -1
- package/dist/web/assets/clouds-CAYIArXj.jpg +0 -0
- package/dist/web/assets/main-Blg8fuaV.css +0 -1
- package/dist/web/assets/main-V14r9Psb.js +0 -596
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: tv-theme
|
|
3
|
-
description: Author a Television theme — capture intent as a skill, render to <storagePath>/themes/<name>/theme.css. The skill survives Television token-surface changes across releases.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# Authoring a Television theme
|
|
8
|
-
|
|
9
|
-
A theme re-skins both the Television app chrome and the artifacts it serves. This skill tells an agent how to author one.
|
|
10
|
-
|
|
11
|
-
## The two artifacts
|
|
12
|
-
|
|
13
|
-
Authoring a theme produces **two things**:
|
|
14
|
-
|
|
15
|
-
1. **A skill that describes the theme.** Captures intent, design choices, and the recipe for rendering to CSS. Lives wherever your skills live (the system that loads `SKILL.md`-style instructions for agents). This skill doesn't dictate the location — use whatever convention is in place.
|
|
16
|
-
2. **The rendered theme folder** at `<storagePath>/themes/<name>/theme.css` (plus any assets the CSS references). This is what Television actually reads at runtime.
|
|
17
|
-
|
|
18
|
-
The split matters because Television's token surface evolves across releases. A flat `theme.css` will drift; a skill that captures intent can be re-invoked to re-render `theme.css` against whatever the current surface looks like.
|
|
19
|
-
|
|
20
|
-
## How theming works in Television
|
|
21
|
-
|
|
22
|
-
- A theme folder lives at `<storagePath>/themes/<name>/`:
|
|
23
|
-
```
|
|
24
|
-
<storagePath>/themes/<name>/
|
|
25
|
-
theme.css ← required entry stylesheet
|
|
26
|
-
<other files> ← optional fonts, background images, supplementary CSS
|
|
27
|
-
```
|
|
28
|
-
- `theme.css` is a **partial overlay** — only the tokens the theme overrides. Everything else falls through to Television's defaults. A minimal theme is ~20 lines.
|
|
29
|
-
- One theme is active at a time, server-wide. Activated via `tv set-theme <name>` (or `tv set-theme default` to clear). The server broadcasts a `theme-changed` event; every connected client re-skins live.
|
|
30
|
-
- The active theme's `theme.css` is watched on disk — saving the file re-applies within ~50ms across all clients. Iteration is tight.
|
|
31
|
-
- Both surfaces (TV app chrome and rendered artifacts) re-skin from the same `theme.css`. No separate "app theme" vs "artifact theme."
|
|
32
|
-
|
|
33
|
-
## Styling surface
|
|
34
|
-
|
|
35
|
-
A Television theme is one CSS overlay delivered to two consumers:
|
|
36
|
-
|
|
37
|
-
- Artifacts receive it after the canonical v1 stylesheet at `/canonical/v1/styles.css`.
|
|
38
|
-
- The browser application fetches the same `theme.css` and adopts it after its bundled styles.
|
|
39
|
-
|
|
40
|
-
Canonical artifact styling is the stable public contract. The redesigned browser chrome also receives the overlay, but complete chrome appearance is a later theming milestone; some token or selector overrides may have no visible effect there. Verify every chrome-specific rule in the running application rather than assuming artifact coverage proves it.
|
|
41
|
-
|
|
42
|
-
Themes have two tools:
|
|
43
|
-
|
|
44
|
-
- Override custom properties on `:root` for system-wide choices such as type, spacing, color, and selection.
|
|
45
|
-
- Add narrowly targeted selector rules for a specific surface. Put a purpose comment above each such rule so the intent survives a future re-render against a changed application structure.
|
|
46
|
-
|
|
47
|
-
### Canonical token snapshot
|
|
48
|
-
|
|
49
|
-
The following build-time snapshot comes from Television's canonical foundation sources. It is useful for orientation, while the running server remains authoritative for the version being themed.
|
|
50
|
-
|
|
51
|
-
```css
|
|
52
|
-
/* colors.css */
|
|
53
|
-
:root {
|
|
54
|
-
/* Colors */
|
|
55
|
-
--black: #000000;
|
|
56
|
-
--white: #ffffff;
|
|
57
|
-
|
|
58
|
-
/* Neutral */
|
|
59
|
-
--neutral-50: oklch(98.5% 0 none);
|
|
60
|
-
--neutral-100: oklch(97% 0 none);
|
|
61
|
-
--neutral-200: oklch(92.2% 0 none);
|
|
62
|
-
--neutral-300: oklch(87% 0 none);
|
|
63
|
-
--neutral-400: oklch(70.8% 0 none);
|
|
64
|
-
--neutral-500: oklch(55.6% 0 none);
|
|
65
|
-
--neutral-600: oklch(43.9% 0 none);
|
|
66
|
-
--neutral-700: oklch(37.1% 0 none);
|
|
67
|
-
--neutral-800: oklch(26.9% 0 none);
|
|
68
|
-
--neutral-900: oklch(20.5% 0 none);
|
|
69
|
-
--neutral-950: oklch(14.5% 0 none);
|
|
70
|
-
|
|
71
|
-
/* Alpha */
|
|
72
|
-
--alpha-50: 4%;
|
|
73
|
-
--alpha-100: 8%;
|
|
74
|
-
--alpha-200: 15%;
|
|
75
|
-
--alpha-300: 22%;
|
|
76
|
-
--alpha-400: 30%;
|
|
77
|
-
--alpha-500: 40%;
|
|
78
|
-
--alpha-600: 50%;
|
|
79
|
-
--alpha-700: 65%;
|
|
80
|
-
--alpha-800: 80%;
|
|
81
|
-
--alpha-900: 90%;
|
|
82
|
-
--alpha-950: 95%;
|
|
83
|
-
|
|
84
|
-
/* Blue */
|
|
85
|
-
--blue-50: oklch(0.97 0.014 254.604);
|
|
86
|
-
--blue-100: oklch(0.932 0.032 255.585);
|
|
87
|
-
--blue-200: oklch(0.882 0.059 254.128);
|
|
88
|
-
--blue-300: oklch(0.809 0.105 251.813);
|
|
89
|
-
--blue-400: oklch(0.707 0.165 254.624);
|
|
90
|
-
--blue-500: oklch(0.623 0.214 259.815);
|
|
91
|
-
--blue-600: oklch(0.546 0.245 262.881);
|
|
92
|
-
--blue-700: oklch(0.488 0.243 264.376);
|
|
93
|
-
--blue-800: oklch(0.424 0.199 265.638);
|
|
94
|
-
--blue-900: oklch(0.379 0.146 265.522);
|
|
95
|
-
|
|
96
|
-
/* Red — the destructive and error hue: a press that destroys, a rejected
|
|
97
|
-
token, a failure line. Tailwind's red, like the blue. */
|
|
98
|
-
--red-50: oklch(0.971 0.013 17.38);
|
|
99
|
-
--red-100: oklch(0.936 0.032 17.717);
|
|
100
|
-
--red-200: oklch(0.885 0.062 18.334);
|
|
101
|
-
--red-300: oklch(0.808 0.114 19.571);
|
|
102
|
-
--red-400: oklch(0.704 0.191 22.216);
|
|
103
|
-
--red-500: oklch(0.637 0.237 25.331);
|
|
104
|
-
--red-600: oklch(0.577 0.245 27.325);
|
|
105
|
-
--red-700: oklch(0.505 0.213 27.518);
|
|
106
|
-
--red-800: oklch(0.444 0.177 26.899);
|
|
107
|
-
--red-900: oklch(0.396 0.141 25.723);
|
|
108
|
-
|
|
109
|
-
/* Yellow — the attention color: worn by things that need noticing exactly
|
|
110
|
-
while they apply (the update bell), never for emphasis, which is the key
|
|
111
|
-
color's job. */
|
|
112
|
-
--yellow-50: oklch(0.987 0.026 102.212);
|
|
113
|
-
--yellow-100: oklch(0.973 0.071 103.193);
|
|
114
|
-
--yellow-200: oklch(0.945 0.129 101.54);
|
|
115
|
-
--yellow-300: oklch(0.905 0.182 98.111);
|
|
116
|
-
--yellow-400: oklch(0.852 0.199 91.936);
|
|
117
|
-
--yellow-500: oklch(0.795 0.184 86.047);
|
|
118
|
-
--yellow-600: oklch(0.681 0.162 75.834);
|
|
119
|
-
--yellow-700: oklch(0.554 0.135 66.442);
|
|
120
|
-
--yellow-800: oklch(0.476 0.114 61.907);
|
|
121
|
-
--yellow-900: oklch(0.421 0.095 57.708);
|
|
122
|
-
--yellow-950: oklch(0.286 0.066 53.813);
|
|
123
|
-
|
|
124
|
-
/* Green, orange, purple — accent ramps. Tailwind's values, like the
|
|
125
|
-
blue. */
|
|
126
|
-
--green-50: oklch(0.982 0.018 155.826);
|
|
127
|
-
--green-100: oklch(0.962 0.044 156.743);
|
|
128
|
-
--green-200: oklch(0.925 0.084 155.995);
|
|
129
|
-
--green-300: oklch(0.871 0.15 154.449);
|
|
130
|
-
--green-400: oklch(0.792 0.209 151.711);
|
|
131
|
-
--green-500: oklch(0.723 0.219 149.579);
|
|
132
|
-
--green-600: oklch(0.627 0.194 149.214);
|
|
133
|
-
--green-700: oklch(0.527 0.154 150.069);
|
|
134
|
-
--green-800: oklch(0.448 0.119 151.328);
|
|
135
|
-
--green-900: oklch(0.393 0.095 152.535);
|
|
136
|
-
|
|
137
|
-
--orange-50: oklch(0.98 0.016 73.684);
|
|
138
|
-
--orange-100: oklch(0.954 0.038 75.164);
|
|
139
|
-
--orange-200: oklch(0.901 0.076 70.697);
|
|
140
|
-
--orange-300: oklch(0.837 0.128 66.29);
|
|
141
|
-
--orange-400: oklch(0.75 0.183 55.934);
|
|
142
|
-
--orange-500: oklch(0.705 0.213 47.604);
|
|
143
|
-
--orange-600: oklch(0.646 0.222 41.116);
|
|
144
|
-
--orange-700: oklch(0.553 0.195 38.402);
|
|
145
|
-
--orange-800: oklch(0.47 0.157 37.304);
|
|
146
|
-
--orange-900: oklch(0.408 0.123 38.172);
|
|
147
|
-
|
|
148
|
-
--purple-50: oklch(0.977 0.014 308.299);
|
|
149
|
-
--purple-100: oklch(0.946 0.033 307.174);
|
|
150
|
-
--purple-200: oklch(0.902 0.063 306.703);
|
|
151
|
-
--purple-300: oklch(0.827 0.119 306.383);
|
|
152
|
-
--purple-400: oklch(0.714 0.203 305.504);
|
|
153
|
-
--purple-500: oklch(0.627 0.265 303.9);
|
|
154
|
-
--purple-600: oklch(0.558 0.288 302.321);
|
|
155
|
-
--purple-700: oklch(0.496 0.265 301.924);
|
|
156
|
-
--purple-800: oklch(0.438 0.218 303.724);
|
|
157
|
-
--purple-900: oklch(0.381 0.176 304.987);
|
|
158
|
-
|
|
159
|
-
/* Tint */
|
|
160
|
-
--tint-50: color-mix(in srgb, currentColor var(--alpha-50), transparent);
|
|
161
|
-
--tint-100: color-mix(in srgb, currentColor var(--alpha-100), transparent);
|
|
162
|
-
--tint-200: color-mix(in srgb, currentColor var(--alpha-200), transparent);
|
|
163
|
-
--tint-300: color-mix(in srgb, currentColor var(--alpha-300), transparent);
|
|
164
|
-
--tint-400: color-mix(in srgb, currentColor var(--alpha-400), transparent);
|
|
165
|
-
--tint-500: color-mix(in srgb, currentColor var(--alpha-500), transparent);
|
|
166
|
-
--tint-600: color-mix(in srgb, currentColor var(--alpha-600), transparent);
|
|
167
|
-
--tint-700: color-mix(in srgb, currentColor var(--alpha-700), transparent);
|
|
168
|
-
--tint-800: color-mix(in srgb, currentColor var(--alpha-800), transparent);
|
|
169
|
-
--tint-900: color-mix(in srgb, currentColor var(--alpha-900), transparent);
|
|
170
|
-
--tint-950: color-mix(in srgb, currentColor var(--alpha-950), transparent);
|
|
171
|
-
|
|
172
|
-
/* Color roles — what a color is for, resolved onto the ramps above. */
|
|
173
|
-
--color-text: var(--neutral-900);
|
|
174
|
-
--color-text-muted: var(--neutral-500);
|
|
175
|
-
/* The interface's key color — what carries emphasis and marks the thing
|
|
176
|
-
you are on. Selection reads as this rather than as a heavier grey, so
|
|
177
|
-
"hovered" and "selected" differ in hue, not just in weight. */
|
|
178
|
-
--color-primary: var(--blue-600);
|
|
179
|
-
/* A fill and the text that survives on it are a pair. Naming the foreground
|
|
180
|
-
keeps the contrast a stated decision rather than something each use site
|
|
181
|
-
guesses at — white on blue-500 measures 3.76:1 and fails AA at body size. */
|
|
182
|
-
--color-on-primary: var(--white);
|
|
183
|
-
--color-selected: var(--color-primary);
|
|
184
|
-
/* What the app's own content sits on, behind the surfaces it holds. Darker
|
|
185
|
-
than those surfaces rather than lighter, so a white one reads as lifted
|
|
186
|
-
off it — a gap of background is how the app shows where its own chrome
|
|
187
|
-
ends and something it is holding begins. */
|
|
188
|
-
--color-background: var(--neutral-200);
|
|
189
|
-
/* The ground of a document or artifact the app holds. Surface vocabulary
|
|
190
|
-
belongs to that held content; the chrome's own ground stays
|
|
191
|
-
--color-background. */
|
|
192
|
-
--color-surface: var(--white);
|
|
193
|
-
/* A quiet region within a held surface: distinct without reading as a
|
|
194
|
-
second layer of app chrome. */
|
|
195
|
-
--color-surface-muted: var(--neutral-100);
|
|
196
|
-
/* The ordinary seam between surface regions. Ten percent is deliberate:
|
|
197
|
-
the alpha ramp's neighbouring steps are too faint and too strong. */
|
|
198
|
-
--color-border: rgb(0 0 0 / 10%);
|
|
199
|
-
/* A repeated or subordinate seam should organize without boxing things in;
|
|
200
|
-
six percent stays below the ordinary border without disappearing. */
|
|
201
|
-
--color-border-muted: rgb(0 0 0 / 6%);
|
|
202
|
-
/* A link follows its surrounding text unless a theme gives it an accent. */
|
|
203
|
-
--color-link: inherit;
|
|
204
|
-
/* The destructive and error role. */
|
|
205
|
-
--color-danger: var(--red-600);
|
|
206
|
-
/* The affirmative and completed-state role. */
|
|
207
|
-
--color-success: var(--green-600);
|
|
208
|
-
/* The caution and warning role. */
|
|
209
|
-
--color-warning: var(--orange-600);
|
|
210
|
-
|
|
211
|
-
color-scheme: light;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/* text.css */
|
|
215
|
-
:root {
|
|
216
|
-
/* Type */
|
|
217
|
-
/* The base the steps below compute from. */
|
|
218
|
-
--text-base: 14px;
|
|
219
|
-
--text-sm: round(calc(var(--text-md) / var(--text-scale)), 1px);
|
|
220
|
-
--text-md: var(--text-base);
|
|
221
|
-
--text-lg: round(calc(var(--text-md) * var(--text-scale)), 1px);
|
|
222
|
-
--text-xl: round(calc(var(--text-lg) * var(--text-scale)), 1px);
|
|
223
|
-
--text-2xl: round(calc(var(--text-xl) * var(--text-scale)), 1px);
|
|
224
|
-
--text-3xl: 24px;
|
|
225
|
-
--text-4xl: 30px;
|
|
226
|
-
--text-scale: 1.125;
|
|
227
|
-
--leading-base: 1.5;
|
|
228
|
-
|
|
229
|
-
/* Fonts */
|
|
230
|
-
--font-sans: "Hind", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
|
|
231
|
-
--font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;
|
|
232
|
-
--font-weight-normal: 400;
|
|
233
|
-
--font-weight-medium: 500;
|
|
234
|
-
--font-weight-body: var(--font-weight-medium);
|
|
235
|
-
--font-weight-semibold: 600;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/* spacing.css */
|
|
239
|
-
:root {
|
|
240
|
-
/* Spacing */
|
|
241
|
-
--space-2: 2px;
|
|
242
|
-
--space-4: 4px;
|
|
243
|
-
--space-6: 6px;
|
|
244
|
-
--space-8: 8px;
|
|
245
|
-
--space-10: 10px;
|
|
246
|
-
--space-12: 12px;
|
|
247
|
-
--space-16: 16px;
|
|
248
|
-
--space-20: 20px;
|
|
249
|
-
--space-24: 24px;
|
|
250
|
-
--space-32: 32px;
|
|
251
|
-
--space-48: 48px;
|
|
252
|
-
--space-64: 64px;
|
|
253
|
-
|
|
254
|
-
/* Radius */
|
|
255
|
-
--radius-4: 4px;
|
|
256
|
-
--radius-6: 6px;
|
|
257
|
-
--radius-8: 8px;
|
|
258
|
-
--radius-12: 12px;
|
|
259
|
-
--radius-16: 16px;
|
|
260
|
-
--radius-24: 24px;
|
|
261
|
-
--radius-full: 9999px; /* pill — fully rounded ends at any element size */
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/* shadows.css */
|
|
265
|
-
:root {
|
|
266
|
-
/* The elevation a floating panel lifts off the page with: a broad soft
|
|
267
|
-
throw and a tight contact shadow. A role, not a ramp — there is one
|
|
268
|
-
elevation in the system; a scale grows if more appear. */
|
|
269
|
-
--shadow-panel:
|
|
270
|
-
0 8px 24px rgba(0, 0, 0, 0.12),
|
|
271
|
-
0 2px 8px rgba(0, 0, 0, 0.06);
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
For nontrivial work, read the complete live canonical stylesheet:
|
|
276
|
-
|
|
277
|
-
```bash
|
|
278
|
-
# The default local server URL is http://localhost:32848.
|
|
279
|
-
curl http://localhost:32848/canonical/v1/styles.css
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
For another server, run `tv status`, read `serverURL` from its JSON output, and fetch `<serverURL>/canonical/v1/styles.css`.
|
|
283
|
-
|
|
284
|
-
From a Television checkout, the authored canonical foundation lives under `specs/ui/foundation/`; `colors.css`, `text.css`, `spacing.css`, and `shadows.css` define its custom properties, while `prose.css` shows how artifact documents consume them.
|
|
285
|
-
|
|
286
|
-
`color-scheme: dark` controls browser-native widgets such as scrollbars and form controls. Set it when the theme uses a dark ground.
|
|
287
|
-
|
|
288
|
-
## Current browser chrome structure
|
|
289
|
-
|
|
290
|
-
Use this map only for chrome-specific rules and verify the result in the running version:
|
|
291
|
-
|
|
292
|
-
- **`#app`** fills the window. Its `.app-sidebar` and `.app-main` children hold the sidebar and the main stage.
|
|
293
|
-
- **`.sidebar`** is the permanent channel list. `.channel[aria-current]` is the selected channel; `.sidebar-foot` holds channel creation.
|
|
294
|
-
- **`.top-bar`** holds stage navigation controls.
|
|
295
|
-
- **`.stage`** is the artifact-page viewport. `.filmstrip` contains `.page` entries, and `.page[selected]` is the selected page.
|
|
296
|
-
- **`.artifact-frame`** is the white document frame. `.artifact-content` holds the document and `.artifact-title-bar` is the quiet lower title band.
|
|
297
|
-
- **Popovers and dialogs** use ordinary `[popover]` and `dialog` elements with the application foundation's panel treatment.
|
|
298
|
-
|
|
299
|
-
These selectors are current implementation structure, not canonical artifact API. A theme skill should retain the visual purpose of each selector rule so an agent can map that purpose onto the running structure when re-rendering.
|
|
300
|
-
|
|
301
|
-
## Surface guidance
|
|
302
|
-
|
|
303
|
-
### Application and stage ground
|
|
304
|
-
|
|
305
|
-
`--color-background` is the main redesigned chrome ground behind stage pages. The sidebar and artifact frame use `--white` as their authored surface. Global text uses `--color-text` and `--color-text-muted`.
|
|
306
|
-
|
|
307
|
-
A theme can establish its broad palette with current role tokens:
|
|
308
|
-
|
|
309
|
-
```css
|
|
310
|
-
:root {
|
|
311
|
-
--color-background: var(--neutral-900);
|
|
312
|
-
--color-text: var(--neutral-100);
|
|
313
|
-
--color-text-muted: var(--neutral-400);
|
|
314
|
-
--color-primary: var(--blue-400);
|
|
315
|
-
--color-selected: var(--color-primary);
|
|
316
|
-
--color-on-primary: var(--white);
|
|
317
|
-
color-scheme: dark;
|
|
318
|
-
}
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
Changing `--white` has a wider meaning than changing a role token: canonical artifacts and several chrome surfaces use it directly. Prefer semantic roles where they express the intent, and visually inspect any raw-palette override.
|
|
322
|
-
|
|
323
|
-
### Sidebar
|
|
324
|
-
|
|
325
|
-
The selected channel uses `--color-selected` with `--color-on-primary`; group labels use `--color-text-muted`; the sidebar ground is `--white`. Local texture or typography needs a purpose-commented selector rule:
|
|
326
|
-
|
|
327
|
-
```css
|
|
328
|
-
/* Keep the channel list visually distinct from the stage with a warm paper ground. */
|
|
329
|
-
.sidebar {
|
|
330
|
-
background: #fffaf0;
|
|
331
|
-
}
|
|
332
|
-
```
|
|
333
|
-
|
|
334
|
-
### Stage pages and artifact frames
|
|
335
|
-
|
|
336
|
-
`.stage` consumes `--color-background`. A selected artifact is the `.page[selected]` entry. The frame itself is `.artifact-frame` with an inset `.artifact-content` and lower `.artifact-title-bar`.
|
|
337
|
-
|
|
338
|
-
```css
|
|
339
|
-
/* Give the selected document's lower title band a quiet orientation tint. */
|
|
340
|
-
.page[selected] > .artifact-frame .artifact-title-bar {
|
|
341
|
-
background: color-mix(in srgb, var(--color-primary) 8%, transparent);
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
The artifact document renders inside its own iframe. Style the document through canonical tokens or document markup; a chrome selector cannot cross the iframe boundary.
|
|
346
|
-
|
|
347
|
-
### Popovers and dialogs
|
|
348
|
-
|
|
349
|
-
Application popovers and dialogs share a white panel ground, radius, and `--shadow-panel`. Canonical artifact controls have their own public component and bare-element rules in the live stylesheet. Keep an app-chrome selector scoped when the change should not affect artifact documents.
|
|
350
|
-
|
|
351
|
-
### Artifact documents
|
|
352
|
-
|
|
353
|
-
Artifacts load the canonical stylesheet plus the active theme. The canonical foundation provides:
|
|
354
|
-
|
|
355
|
-
- palette and role properties such as `--neutral-*`, `--blue-*`, `--color-text`, `--color-text-muted`, `--color-primary`, and `--color-background`;
|
|
356
|
-
- typography properties such as `--font-sans`, `--font-mono`, `--text-*`, and `--font-weight-*`;
|
|
357
|
-
- spacing and radius properties such as `--space-*` and `--radius-*`;
|
|
358
|
-
- `--shadow-panel`;
|
|
359
|
-
- semantic bare-HTML prose and the canonical v1 components.
|
|
360
|
-
|
|
361
|
-
Read the live stylesheet before using a property not present in the snapshot. Theme CSS may also include `@font-face`, media queries, and rules for authored artifact markup.
|
|
362
|
-
|
|
363
|
-
## Theme contents
|
|
364
|
-
|
|
365
|
-
A theme may contain:
|
|
366
|
-
|
|
367
|
-
- CSS custom-property overrides;
|
|
368
|
-
- `@font-face` declarations, with files stored beside `theme.css`;
|
|
369
|
-
- background and decorative images stored beside `theme.css`;
|
|
370
|
-
- `@media` blocks;
|
|
371
|
-
- purpose-commented selector rules.
|
|
372
|
-
|
|
373
|
-
Themes are static CSS assets. They do not provide JavaScript hooks or a metadata manifest, and one theme name resolves to one `theme.css` overlay.
|
|
374
|
-
|
|
375
|
-
## Workflow
|
|
376
|
-
|
|
377
|
-
Theme authoring has two phases. **Iterate first** — work directly on `theme.css` with the live-reload loop, see changes immediately, refine until the user is happy. **Then export to a skill** — capture the intent so the theme survives future Television versions.
|
|
378
|
-
|
|
379
|
-
### Phase A: Iterate live on theme.css
|
|
380
|
-
|
|
381
|
-
1. **Gather intent from the user.** Aesthetic / vibe / references, palette, typography choices, any specific surfaces they care about. Don't design before understanding — clear intent saves rendering loops.
|
|
382
|
-
2. **Read the current Television token surface.** See "The token surface" section above; identify which semantic tokens map to the user's intent. Don't override tokens that don't exist in the current surface.
|
|
383
|
-
3. **Pick a name** matching `^[a-z0-9][a-z0-9-]*$` (e.g. `paperlike`, `cyberpunk-arcade`). The reserved value `default` cannot be used — it's the CLI sentinel for clearing the active theme.
|
|
384
|
-
4. **Write `<storagePath>/themes/<name>/theme.css`** with your initial overrides. Place any assets (fonts, images) alongside it.
|
|
385
|
-
5. **Activate it:** `tv set-theme <name>`. The app re-skins immediately.
|
|
386
|
-
6. **Iterate.** Edits to `theme.css` propagate within ~50ms — no PATCH, no reload. Listen to the user's feedback ("bump the primary, lower the body contrast"), edit the file, watch the result. This is where the bulk of theme work happens.
|
|
387
|
-
7. **Comment selector-level rules with their purpose.** When the look needs more than token overrides, add selector-level rules — and explain *why* each one exists in a comment above it. Television's internals can shift; the comment is what lets a future agent re-target the rule.
|
|
388
|
-
|
|
389
|
-
```css
|
|
390
|
-
/*
|
|
391
|
-
* Give the selected document's lower title band a faint warm tint as a
|
|
392
|
-
* quiet orientation cue without adding a heavier indicator.
|
|
393
|
-
*/
|
|
394
|
-
.page[selected] > .artifact-frame .artifact-title-bar {
|
|
395
|
-
background: color-mix(in srgb, var(--color-primary) 8%, transparent);
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Phase B: Export to a skill once the look is settled
|
|
400
|
-
|
|
401
|
-
When the user is happy with the theme, capture it as a skill. The skill is the durable artifact — Television's token surface evolves, components get refactored, and a flat `theme.css` from today may render incorrectly under a future version. The skill carries enough context (intent, design choices, per-rule purpose) that an agent can re-render the theme cleanly against a new surface.
|
|
402
|
-
|
|
403
|
-
Create a new skill — wherever skills live in the user's environment. Folder layout:
|
|
404
|
-
|
|
405
|
-
```
|
|
406
|
-
<theme-skill-folder>/
|
|
407
|
-
SKILL.md # intent + design choices + style overrides + render instructions
|
|
408
|
-
resources/ # assets the rendered theme.css references (fonts, images, etc.)
|
|
409
|
-
```
|
|
410
|
-
|
|
411
|
-
The SKILL.md should have:
|
|
412
|
-
|
|
413
|
-
- **Frontmatter** with `name` following the convention `tv-theme-<name>` (e.g. `tv-theme-paperlike`) and `description` (one-line aesthetic summary). The `tv-theme-` prefix scopes the skill to Television theming so it's discoverable alongside the bundled `tv-theme` meta-skill.
|
|
414
|
-
- **Intent.** 1–3 paragraphs describing the look and the user-facing pitch. Specific enough that another agent (or you, six months later) could re-author this theme from scratch from this section alone.
|
|
415
|
-
- **References.** Optional — inspirations, links, screenshots, brand/product references.
|
|
416
|
-
- **Design choices.** Bulleted list of decisions with rationale. E.g. *"Background is near-black to evoke low-light comfort"*, *"Primary accent is muted teal — saturated enough to read on dark, restrained enough not to scream."*
|
|
417
|
-
- **Style overrides.** Copy the contents of the iterated `theme.css`, comments and all. The purpose comments you wrote during iteration are what make the theme re-renderable.
|
|
418
|
-
- **Assets.** List of files in `resources/`, what each is, what `theme.css` rule references it. Copy the assets from the live theme folder into `resources/`.
|
|
419
|
-
- **Render instructions.** A short section telling future invocations how to render this skill: "fetch the live Television token surface from `/canonical/v1/styles.css` or read `<checkout>/specs/ui/foundation/{colors,text,spacing,shadows,prose}.css`; inspect the running browser structure for chrome selectors; map this skill's Intent + Design choices + Style overrides onto the current surface; emit `<storagePath>/themes/<name>/theme.css` and copy `resources/*` to `<storagePath>/themes/<name>/`."
|
|
420
|
-
|
|
421
|
-
Once exported, the iterated `<storagePath>/themes/<name>/` folder and the skill should be in sync. Future edits should happen in both — update `theme.css` for the live feedback loop, update the skill's **Style overrides** section in lockstep so the durable record stays current. If they drift, the skill is the source of truth.
|
|
422
|
-
|
|
423
|
-
## Re-rendering across Television versions
|
|
424
|
-
|
|
425
|
-
When Television's token surface or component structure changes (new tokens added, existing tokens renamed or repurposed, components renamed, selector-level rules in a theme become stale), the theme's `theme.css` may render incorrectly under the new version — variables that no longer exist do nothing, new variables that the theme should set are missed, selector-level rules may target elements that no longer exist.
|
|
426
|
-
|
|
427
|
-
Recovery procedure (the theme skill makes this possible):
|
|
428
|
-
|
|
429
|
-
1. **Read the current Television surface:**
|
|
430
|
-
- Running server: `curl http://localhost:32848/canonical/v1/styles.css` (or run `tv status`, read `serverURL`, and fetch `<serverURL>/canonical/v1/styles.css`).
|
|
431
|
-
- Or, from a checkout: read `specs/ui/foundation/{colors,text,spacing,shadows,prose}.css` for the canonical artifact contract and the current files under `packages/web/src/{elements,views}/` for any browser-chrome selector rules.
|
|
432
|
-
2. **Read the theme's skill** — especially the **Intent**, **Design choices**, and the *comments* in the **Style overrides** section. The comments are what let you re-author selector-level rules: even if `.artifact-title-bar` is absent in the running version, the comment "*selected document's lower title band gets a faint warm tint as an orientation cue*" tells you what current selector should carry that intent.
|
|
433
|
-
3. **Map the original intent onto the new surface.** Token overrides that reference tokens still present transfer directly. Renamed tokens get re-mapped. New semantic tokens added to Television may need to be set to fit the theme's vibe. Selector-level rules get re-expressed against the new structure.
|
|
434
|
-
4. **Update the skill's Style overrides section** with the revised rules (keep the purpose comments updated).
|
|
435
|
-
5. **Re-render**: write the updated CSS to `<storagePath>/themes/<name>/theme.css` and re-copy any new/changed assets from `resources/`.
|
|
436
|
-
6. **Activate and verify visually** — `tv set-theme <name>`, walk through the app.
|
|
437
|
-
|
|
438
|
-
Without the skill capturing intent and per-rule purpose comments, this would be reverse-engineering from CSS — lossy. The skill is the durable artifact; `theme.css` is the build output that may need refreshing across versions.
|
|
439
|
-
|
|
440
|
-
## Smoke test before declaring done
|
|
441
|
-
|
|
442
|
-
After authoring:
|
|
443
|
-
|
|
444
|
-
1. `tv set-theme <name>` — does the app re-skin without errors?
|
|
445
|
-
2. Open the app, navigate around — does the chrome look right? Any elements that look wrong (unreadable text, wrong contrast, broken borders)?
|
|
446
|
-
3. Look at an existing artifact — does it pick up the theme?
|
|
447
|
-
4. `tv set-theme default` — does it return to the bundled look cleanly?
|
|
448
|
-
|
|
449
|
-
If any of these fail, the theme is incomplete. Fix and re-test.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(function(){const m=document.createElement("link").relList;if(m&&m.supports&&m.supports("modulepreload"))return;for(const a of document.querySelectorAll('link[rel="modulepreload"]'))b(a);new MutationObserver(a=>{for(const g of a)if(g.type==="childList")for(const R of g.addedNodes)R.tagName==="LINK"&&R.rel==="modulepreload"&&b(R)}).observe(document,{childList:!0,subtree:!0});function S(a){const g={};return a.integrity&&(g.integrity=a.integrity),a.referrerPolicy&&(g.referrerPolicy=a.referrerPolicy),a.crossOrigin==="use-credentials"?g.credentials="include":a.crossOrigin==="anonymous"?g.credentials="omit":g.credentials="same-origin",g}function b(a){if(a.ep)return;a.ep=!0;const g=S(a);fetch(a.href,g)}})();const U="url-target-request",O="url-target",I="artifact-missing-request",P="artifact-missing",N="proxy-content-changed",C="bridge-ready",G="leaving";function K(t,m){return!(t.key==="ArrowLeft"||t.key==="ArrowRight"||t.key==="ArrowUp"||t.key==="ArrowDown")||t.isComposing||t.metaKey||t.shiftKey?!1:m==="darwin"||/^(Mac|iPhone|iPad|iPod)/i.test(m)?t.altKey&&!t.ctrlKey:t.ctrlKey&&!t.altKey}function L(t){return typeof t=="object"&&t!==null}function q(t){return!L(t)||t.type!==U?!1:!("id"in t)}function B(t){return!L(t)||t.type!==O||typeof t.url!="string"&&t.url!==null?!1:!("id"in t)}function x(t){return!L(t)||t.type!==I?!1:!("id"in t)}function Y(t){return!L(t)||t.type!==P||typeof t.title!="string"||typeof t.path!="string"?!1:!("id"in t)}function v(t){return!L(t)||t.type!==N?!1:!("id"in t)}function F(t){return!L(t)||t.type!==C||typeof t.guid!="string"?!1:!("id"in t)}function V(t){return!L(t)||t.type!==G||typeof t.guid!="string"?!1:!("id"in t)}function w(t){return!L(t)||t.type!=="navigation-request"||typeof t.url!="string"||"replace"in t&&typeof t.replace!="boolean"||"sameDocument"in t&&typeof t.sameDocument!="boolean"||"native"in t&&typeof t.native!="boolean"?!1:!("id"in t)}function W(t){return!L(t)||t.type!=="navigation-key"||t.key!=="ArrowLeft"&&t.key!=="ArrowRight"&&t.key!=="ArrowUp"&&t.key!=="ArrowDown"?!1:!("id"in t)}function X(t=window,m={}){const S=t;if(t.parent===t||S.__televisionArtifactBridgeInstalled===!0)return;S.__televisionArtifactBridgeInstalled=!0;const a=(()=>{const u=Date.now().toString(36);try{const d=t.crypto;if(d&&typeof d.getRandomValues=="function"){const c=new Uint32Array(4);return d.getRandomValues(c),`tvb-${u}-${Array.from(c,A=>A.toString(36)).join("-")}`}}catch{}return`tvb-${u}-${Math.random().toString(36).slice(2)}-${Math.random().toString(36).slice(2)}`})(),g=()=>{t.parent.postMessage({type:"bridge-ready",guid:a},"*")};t.addEventListener("pagehide",()=>{t.parent.postMessage({type:"leaving",guid:a},"*")}),t.addEventListener("pageshow",h=>{h.persisted===!0&&g()}),t.addEventListener("keydown",h=>{const i=h,u=i.key==="ArrowLeft"||i.key==="ArrowRight"||i.key==="ArrowUp"||i.key==="ArrowDown",d=t.navigator.platform,A=d==="darwin"||/^(Mac|iPhone|iPad|iPod)/i.test(d)?i.altKey&&!i.ctrlKey&&!i.metaKey&&!i.shiftKey:i.ctrlKey&&!i.altKey&&!i.metaKey&&!i.shiftKey;!u||i.isComposing||!A||(i.preventDefault(),t.parent.postMessage({type:"navigation-key",key:i.key},"*"))},!0);const R=t.location.href;if((h=>{try{const i=new URL(h);return/^\/artifact\/[0-9A-Za-z]{26}(\/|$)/.test(i.pathname)}catch{return!1}})(R)&&typeof t.fetch=="function"){const u=m.pollCadence,d=u!==void 0&&Number.isFinite(u.normalMs)&&u.normalMs>0&&Number.isFinite(u.slowMs)&&u.slowMs>=u.normalMs?u:null,c=(d==null?void 0:d.normalMs)??5e3,A=(d==null?void 0:d.slowMs)??15e3;let o=null,f=c,r=0,e=!1,s=null,n=null;const y=()=>{e&&(e=!1,r+=1,s!==null&&(t.clearTimeout(s),s=null),n==null||n.abort(),n=null)},p=()=>{if(e)return;e=!0;const l=++r,D=()=>{if(!e||l!==r)return;s=null;const M=t.AbortController,E=typeof M=="function"?new M:null;n=E,(async()=>{try{const T=await t.fetch(R,{method:"HEAD",...E?{signal:E.signal}:{}});if(!e||l!==r)return;if(!T.ok)throw new Error("Artifact poll failed");const _=T.headers.get("ETag");if(!_)throw new Error("Artifact poll missing ETag");f=c,o===null?o=_:_!==o&&(o=_,t.parent.postMessage({type:"proxy-content-changed"},"*"))}catch{e&&l===r&&(f=Math.min(A,f*2))}finally{n===E&&(n=null),e&&l===r&&(s=t.setTimeout(D,f))}})()};D()};t.addEventListener("pagehide",y),t.addEventListener("pageshow",l=>{l.persisted===!0&&p()}),p()}if(m.reportNavigation!==!1){const h=new Set(["about:","blob:","chrome-extension:","chrome:","data:","devtools:","file:","filesystem:","javascript:","view-source:"]),i=(o,f)=>{try{const r=new URL(o,f);return r.protocol==="http:"||r.protocol==="https:"||h.has(r.protocol)?null:r}catch{return null}},u=(o,f)=>{try{const r=new URL(o,f);return r.protocol==="http:"||r.protocol==="https:"?r:null}catch{return null}},d=o=>{var l;const f=o.type==="click"&&o.button===0,r=o.type==="auxclick"&&o.button===1;if(!f&&!r)return;const e=(l=t.document.defaultView)==null?void 0:l.Element;if(!e||!(o.target instanceof e))return;const s=o.target.closest("a[href]");if(!s)return;const n=i(s.href,t.document.baseURI);if(!n)return;const y=s.target.toLowerCase();!(r||o.metaKey||o.ctrlKey||o.shiftKey||o.altKey||y!==""&&y!=="_self")&&!s.hasAttribute("download")||(o.preventDefault(),t.location.href=n.href)};t.document.addEventListener("click",d,!0),t.document.addEventListener("auxclick",d,!0);const c=o=>{t.parent.postMessage({type:"navigation-request",...o},"*")};c({url:t.location.href});const A=t.navigation;if(A)A.addEventListener("navigate",o=>{var p,l;const f=o,r=(p=f.destination)==null?void 0:p.url;if(typeof r!="string")return;const e=u(r,t.location.href);if(!e)return;const s=((l=f.destination)==null?void 0:l.sameDocument)===!0,n={url:r,...f.navigationType==="replace"?{replace:!0}:{},...s?{sameDocument:!0}:{}};if(s){c(n);return}if(e.origin===t.location.origin){c({...n,native:!0});return}f.canIntercept!==!1&&f.preventDefault(),c(n)});else{t.document.addEventListener("click",r=>{var l;const e=r;if(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;const s=(l=t.document.defaultView)==null?void 0:l.Element;if(!s||!(e.target instanceof s))return;const n=e.target.closest("a[href]");if(!n||n.target&&n.target.toLowerCase()!=="_self"||n.hasAttribute("download")||!n.getAttribute("href"))return;const p=u(n.href,t.document.baseURI);if(p){if(p.origin===t.location.origin&&p.pathname===t.location.pathname&&p.search===t.location.search&&p.hash!==""){c({url:p.href,sameDocument:!0});return}e.preventDefault(),c({url:p.href})}},!0);const o=t.history.pushState.bind(t.history),f=t.history.replaceState.bind(t.history);t.history.pushState=function(...e){o(...e),c({url:t.location.href,sameDocument:!0})},t.history.replaceState=function(...e){f(...e),c({url:t.location.href,replace:!0,sameDocument:!0})},t.addEventListener("popstate",()=>{c({url:t.location.href,sameDocument:!0})}),t.addEventListener("hashchange",()=>{c({url:t.location.href,sameDocument:!0})}),t.document.addEventListener("submit",r=>{var l,D;const e=r,s=e.target,n=(l=t.document.defaultView)==null?void 0:l.HTMLFormElement;if(!n||!(s instanceof n)||s.target&&s.target.toLowerCase()!=="_self")return;const y=u(s.action||t.location.href,t.document.baseURI);if(!y)return;if(e.preventDefault(),s.method.toLowerCase()==="get"){const M=(D=t.document.defaultView)==null?void 0:D.FormData;if(!M)return;const E=new URLSearchParams;for(const[T,_]of new M(s))typeof _=="string"&&E.append(T,_);y.search=E.toString()}c({url:y.href})},!0)}}g()}export{P as A,O as U,V as a,F as b,W as c,w as d,v as e,q as f,K as g,X as h,x as i,Y as j,I as k,B as l,U as m};
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.menu{min-width:180px;padding:var(--space-4)}.menu-item{padding:var(--space-4) var(--space-10);border:0;border-radius:var(--radius-4);background:none;cursor:default}.menu-item:hover,.menu-item:focus-visible{background:var(--tint-100);outline:none}.menu-item.destructive{color:var(--red-600)}.menu-separator{border:0;border-top:1px solid var(--tint-100);margin:var(--space-4) calc(-1 * var(--space-4))}.sidebar{height:100%;box-sizing:border-box;display:flex;flex-direction:column;background:var(--white)}.sidebar-titlebar{flex:none;height:38px;padding-left:78px;-webkit-app-region:drag;border-bottom:1px solid transparent}.sidebar:has(.sidebar-body[continues-start]) .sidebar-titlebar{border-bottom-color:var(--tint-100)}.sidebar-body{flex:1;min-height:0;overflow-y:auto;padding:var(--space-4) var(--space-8) var(--space-12)}.channel-group+.channel-group{margin-top:var(--space-24)}.channel-group-label{margin:0 0 var(--space-4);padding:0 var(--space-8);font-size:var(--text-md);font-weight:var(--font-weight-medium);color:var(--color-text-muted)}.sidebar-foot{flex:none;border-top:1px solid var(--tint-100);padding:var(--space-4)}.channel-row{position:relative;overflow:clip}.channel{display:block;width:100%;padding:var(--space-4) calc(2 * var(--space-4) + 20px) var(--space-4) var(--space-8);border:1px solid transparent;background:none;text-align:left;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}:where(.channel-row:hover,.channel-row:has([popover]:popover-open)) .channel:not([aria-current]){background:var(--neutral-100)}.channel[aria-current]{background:var(--color-selected);color:var(--color-on-primary)}.channel-menu-trigger{position:absolute;top:50%;right:var(--space-4);translate:0 -50%;opacity:0}.channel-row:hover .channel-menu-trigger,.channel-menu-trigger:focus-visible,.channel-row:has([popover]:popover-open) .channel-menu-trigger,.channel-row:has(>.channel[aria-current]) .channel-menu-trigger{opacity:1}.channel-row:has(>.channel[aria-current]) .channel-menu-trigger{--color-text: var(--color-on-primary);--color-text-muted: var(--color-on-primary)}.channel-rename{display:block;width:100%;font-size:var(--text-md);line-height:18px;padding:var(--space-4) calc(2 * var(--space-4) + 20px) var(--space-4) var(--space-8);border:1px solid var(--blue-400);border-radius:var(--radius-6);background:var(--white);outline:none}.channel-rename-commit{position:absolute;top:50%;right:var(--space-4);translate:0 -50%;--color-text: var(--blue-600);--color-text-muted: var(--blue-600)}.channel-placeholder{display:block;border-radius:var(--radius-6);background:var(--tint-100)}.channel-row[dragged]{z-index:1;width:fit-content;min-width:160px;background:var(--white);border:1px solid var(--tint-200);border-radius:var(--radius-6);box-shadow:0 4px 12px #00000026}.channel-row[dragged] .channel{padding-right:var(--space-8)}.channel-drag-action{display:flex;align-items:center;gap:var(--space-4);position:absolute;top:-10px;right:-10px;height:20px;padding:0 var(--space-8) 0 var(--space-6);border-radius:10px;background:var(--white);border:1px solid var(--tint-200);box-shadow:0 1px 4px #00000026;font-size:var(--text-sm)}.channel-drag-action tv-icon{font-size:12px}.sidebar[dragging] .sidebar-body{overflow-anchor:none}.channel-group[drag-collapsed]{height:0;margin-top:0;overflow:visible}.channel-group[drag-collapsed]>.channel-group-label{display:none}.channel-group[drag-collapsed]+.channel-group{margin-top:0}.channel-group-withdrawal{position:fixed;z-index:2;margin:0;overflow:hidden;pointer-events:none}.channel-placeholder{width:100%}.channel-row[dragged]{position:fixed;z-index:3;margin:0;overflow:visible;pointer-events:none}.channel-row[dragged] :where(.channel-menu-trigger,.menu){display:none}.artifact-view .artifact-content{flex:1;min-height:0;overflow:auto;overscroll-behavior-y:contain;background:var(--white)}.artifact-view[data-embed-loaded],.artifact-view[data-embed-loaded] .artifact-content{background:transparent}.artifact-view iframe.artifact-content,.artifact-view webview.artifact-content{border:0;width:100%;border-radius:var(--frame-radius) var(--frame-radius) 0 0}.artifact-view iframe.artifact-content{display:block}.artifact-view .artifact-placeholder{display:flex;align-items:center;justify-content:center;color:var(--color-text-muted, #888);font-size:12px}.artifact-view .artifact-missing{display:grid;place-items:center;box-sizing:border-box;padding:24px;color:#222;background:#dadada}.artifact-view .artifact-missing-wrapper{width:100%;max-width:520px;margin:0 auto}.artifact-view .artifact-missing h1{margin:0 0 .75rem;font-size:1.125rem;line-height:1.25}.artifact-view .artifact-missing p{margin:0;font-size:.875rem;line-height:1.45}.artifact-view .artifact-missing-path{margin:1rem 0}.artifact-view .artifact-missing-path-label{margin-bottom:.375rem}.artifact-view .artifact-missing code{display:inline-block;max-width:100%;overflow-wrap:anywhere;padding:.125rem .3rem;border-radius:.35rem;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,monospace;font-size:.85em;color:#253040;background:#cbcbcb;-webkit-user-select:all;user-select:all}.artifact-frame{--frame-radius: var(--radius-12);display:flex;flex-direction:column;box-sizing:border-box;height:100%;min-width:0;min-height:0;overflow:hidden;background:var(--white);border:1px solid var(--tint-200);border-radius:var(--frame-radius)}.artifact-frame>iframe{flex:1;min-width:0;min-height:0;border:0}.artifact-title-bar{flex:none;display:flex;align-items:center;gap:var(--space-6);padding:var(--space-6) var(--space-10) var(--space-8);background:var(--neutral-50);border-top:1px solid var(--tint-100)}.artifact-title-bar .artifact-title{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.artifact-bar-divider{width:1px;height:14px;margin:0 var(--space-2);background:var(--tint-200)}.artifact-view{--frame-radius: var(--radius-12);display:flex;flex-direction:column;box-sizing:border-box;width:100%;height:100%;min-width:0;min-height:0;overflow:hidden;border:1px solid var(--tint-200);border-radius:var(--frame-radius);background:var(--white)}.artifact-view[data-embed-loaded]{background:var(--white)}.artifact-view>.artifact-content{flex:1;width:100%;height:auto;min-width:0;min-height:0;padding:0;border:0}.artifact-view>iframe.artifact-content{display:block}.stage{--stage-inset: var(--space-12);--stage-gap: var(--space-12);position:relative;flex:1;min-width:0;min-height:0;display:flex;container-type:size;background:transparent;overflow:hidden}.filmstrip{flex:1;min-width:0;min-height:0;overflow:hidden;overscroll-behavior:none;touch-action:none}.filmstrip-inner{height:100%;min-width:max-content;display:flex;align-items:center;gap:var(--stage-gap);padding-bottom:var(--stage-inset);transition:scale .28s ease}.filmstrip-inner[tab-held]{scale:.9}.filmstrip-inner:before,.filmstrip-inner:after{content:"";flex:none;width:50cqw}.page{flex:none;max-width:calc(100cqw - var(--stage-inset) - var(--stage-inset));max-height:calc(100cqh - var(--stage-inset))}.page[full-screen]{width:calc(100cqw - var(--stage-inset) - var(--stage-inset));height:calc(100cqh - var(--stage-inset))}.page>.artifact-frame{width:100%}.page{position:relative;transition:scale .28s ease,opacity .28s ease,width .28s ease,height .28s ease}.page:not([selected]){scale:.94;opacity:.55}.page[selected]{z-index:1}.page:not([selected]) .artifact-frame{pointer-events:none}@media (prefers-reduced-motion: reduce){.page{transition:none}}.snap-outline{position:absolute;top:0;left:var(--stage-inset);right:var(--stage-inset);bottom:var(--stage-inset);border:3px solid var(--tint-300);border-radius:var(--radius-12);pointer-events:none;z-index:2}.stage-empty{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-8);color:var(--color-text-muted)}.stage-empty tv-icon{font-size:28px}.stage-empty p{margin:0}.page>.artifact-view{width:100%;height:100%}.page:not([selected]) .artifact-view{pointer-events:none}.page-handle{position:absolute;z-index:2;touch-action:none}.page-handle.left,.page-handle.right{top:0;bottom:0;width:var(--handle-band);cursor:ew-resize}.page-handle.top,.page-handle.bottom{left:0;right:0;height:var(--handle-band);cursor:ns-resize}.page-handle.left{left:calc(var(--handle-band) / -2)}.page-handle.right{right:calc(var(--handle-band) / -2)}.page-handle.top{top:calc(var(--handle-band) / -2)}.page-handle.bottom{bottom:calc(var(--handle-band) / -2)}.page-handle.top-left,.page-handle.top-right,.page-handle.bottom-left,.page-handle.bottom-right{width:var(--handle-reach);height:var(--handle-reach);z-index:3}.page-handle.top-left{left:calc(var(--handle-thickness) / -2);top:calc(var(--handle-thickness) / -2);cursor:nwse-resize;clip-path:polygon(0 0,100% 0,100% var(--handle-thickness),var(--handle-thickness) var(--handle-thickness),var(--handle-thickness) 100%,0 100%)}.page-handle.bottom-right{right:calc(var(--handle-thickness) / -2);bottom:calc(var(--handle-thickness) / -2);cursor:nwse-resize;clip-path:polygon(calc(100% - var(--handle-thickness)) 0,100% 0,100% 100%,0 100%,0 calc(100% - var(--handle-thickness)),calc(100% - var(--handle-thickness)) calc(100% - var(--handle-thickness)))}.page-handle.top-right{right:calc(var(--handle-thickness) / -2);top:calc(var(--handle-thickness) / -2);cursor:nesw-resize;clip-path:polygon(0 0,100% 0,100% 100%,calc(100% - var(--handle-thickness)) 100%,calc(100% - var(--handle-thickness)) var(--handle-thickness),0 var(--handle-thickness))}.page-handle.bottom-left{left:calc(var(--handle-thickness) / -2);bottom:calc(var(--handle-thickness) / -2);cursor:nesw-resize;clip-path:polygon(0 0,var(--handle-thickness) 0,var(--handle-thickness) calc(100% - var(--handle-thickness)),100% calc(100% - var(--handle-thickness)),100% 100%,0 100%)}.stage[resizing] iframe,.stage[resizing] webview{pointer-events:none}.stage[resizing] .page,.stage[window-tracking] .page{transition:none}.desktop-upgrade-gate{position:fixed;top:0;right:0;bottom:0;left:0}.upgrade-gate-body{box-sizing:border-box;width:min(560px,calc(100vw - 2 * var(--space-16)));max-height:calc(100vh - 2 * var(--space-16));overflow-y:auto;padding:var(--space-32) var(--space-24)}.upgrade-gate-body h1{font-size:var(--text-xl);font-weight:var(--font-weight-semibold);margin:0 0 var(--space-12)}.upgrade-gate-body p{margin:0 0 var(--space-12)}.upgrade-gate-body pre{margin:0 0 var(--space-12);padding:var(--space-12);background:var(--neutral-100);border-radius:var(--radius-6);overflow-x:auto;font-family:var(--font-mono);font-size:var(--text-sm)}.upgrade-gate-body :last-child{margin-bottom:0}.system-modal{width:min(400px,90vw);padding:var(--space-32) var(--space-24);display:flex;flex-direction:column;align-items:center;gap:var(--space-8);text-align:center}.system-modal h2{font-size:var(--text-lg);font-weight:var(--font-weight-semibold)}.system-modal p{color:var(--color-text-muted)}.auth-form .auth-token{align-self:stretch;font:inherit;padding:var(--space-6) var(--space-8);border:1px solid var(--tint-200);border-radius:var(--radius-6);background:var(--white)}.auth-form .auth-token.invalid{border-color:var(--red-600)}.auth-form .auth-error{font-size:var(--text-sm);color:var(--red-600)}.auth-form .auth-submit{align-self:stretch}.system-modal .server-url{font-family:var(--font-mono);font-size:var(--text-sm)}.system-modal-host{display:contents}.copy-button{position:relative}.copy-button .copy-button-idle,.copy-button .copy-button-done{display:inline-flex;align-items:center;gap:var(--space-6)}.copy-button .copy-button-done{display:none}.copy-button[copied] .copy-button-idle{visibility:hidden}.copy-button[copied] .copy-button-done{display:flex;position:absolute;top:0;right:0;bottom:0;left:0;align-items:center;justify-content:center}.copy-button-status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}.update-bell{background:var(--yellow-300);border-color:#0000002e;color:var(--yellow-800);border-radius:var(--radius-full)}.update-bell:hover:not(:disabled){background:var(--yellow-400)}.update-bell:active:not(:disabled){background:var(--yellow-500)}button.update-bell[popovertarget]:not(:disabled):has(+[popover]:popover-open){background:var(--yellow-500);color:var(--yellow-950)}.update-popover{width:360px;padding:var(--space-16)}.update-actions{display:flex;justify-content:flex-end;gap:var(--space-8);margin-top:var(--space-12)}.skill-trigger{border-radius:var(--radius-full)}.skill-popover{width:500px;padding:var(--space-16)}.skill-heading{font-size:11px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--color-text);padding:0 var(--space-2) var(--space-4)}.skill-intro{margin:0;padding:0 var(--space-2) var(--space-12);font-size:12px;line-height:1.4;color:var(--color-text-muted)}.skill-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-20)}.skill-card{display:flex;flex-direction:column;min-width:0}.skill-thumb{position:relative;aspect-ratio:1 / 1;border-radius:var(--radius-8);overflow:hidden;background:var(--neutral-200)}.skill-thumb img{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;object-fit:cover;display:block}.skill-name{font-size:13px;font-weight:600;color:var(--color-text);margin-top:var(--space-6);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.skill-desc{font-size:11.5px;line-height:1.35;color:var(--color-text-muted);margin:var(--space-2) 0 var(--space-6)}.skill-card button.copy-button{align-self:flex-start;margin-top:auto;height:auto;min-height:0;padding:var(--space-2) var(--space-6);font-size:11px}.tab-strip{display:flex;align-items:center;gap:var(--space-4);overflow-x:auto;scrollbar-width:none;padding:var(--space-4);margin:calc(-1 * var(--space-4))}.tab-strip{--fade-start: 0px;--fade-end: 0px;-webkit-mask-image:linear-gradient(to right,transparent 0,black var(--fade-start),black calc(100% - var(--fade-end)),transparent 100%);mask-image:linear-gradient(to right,transparent 0,black var(--fade-start),black calc(100% - var(--fade-end)),transparent 100%)}.tab-strip[continues-start]{--fade-start: var(--space-24)}.tab-strip[continues-end]{--fade-end: var(--space-24)}.tab{display:grid;align-items:center;max-width:220px;flex:0 1 auto;padding:0 var(--space-10);background:none;color:var(--color-text-muted)}.tab[data-compression=hugging]{min-width:max-content}.tab[data-compression=capped]{min-width:100px}.tab-label{min-width:0;padding:var(--space-4) 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab:hover:not([aria-selected=true]){background:var(--neutral-300)}.tab[aria-selected=true]{background:var(--white);color:var(--color-text)}.tab-placeholder{flex:none;border-radius:var(--radius-6);background:var(--tint-100)}.tab[dragged]{position:relative;z-index:1}.tab-strip{width:100%;min-width:0}.tab-strip[tab-held]{-webkit-mask-image:none;mask-image:none}.tab-strip>.tab[dragging]{position:fixed;z-index:3;flex:none;margin:0}.top-bar{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,auto) minmax(max-content,1fr);align-items:center;gap:var(--space-8)}.top-bar>.tab-strip{grid-column:2;min-width:0;margin-inline:0}.top-bar-controls{grid-column:3;justify-self:end;display:flex;align-items:center;gap:var(--space-4)}.top-bar>.tab-strip,.top-bar>.top-bar-controls{-webkit-app-region:no-drag}:root{--app-wallpaper: none}#app{display:flex;height:100%;min-width:0}.app-sidebar{flex:none;width:260px;min-width:0}.app-main{--tab-bar-gap: var(--space-8);flex:1;min-width:0;min-height:0;display:flex;flex-direction:column;gap:var(--tab-bar-gap);padding-top:var(--tab-bar-gap);background-color:var(--color-background);background-image:var(--app-wallpaper);background-position:center;background-size:cover;background-repeat:no-repeat}.app-main>.top-bar{min-width:0;padding-inline:var(--space-12)}#app{-webkit-user-select:none;user-select:none}#app{width:100%;height:100%;min-width:0;overflow:hidden}#app>:where(.app-sidebar,.app-main){overflow:hidden}:root{--app-wallpaper: url(./clouds-CAYIArXj.jpg)}.top-bar .tab:not([aria-selected=true]){color:var(--color-text)}.top-bar .tab:hover:not([aria-selected=true]){background:var(--tint-100);border-color:var(--tint-200)}.top-bar-controls button[variant=ghost]{color:var(--color-text)}.top-bar-controls button[variant=ghost]:hover:where(:not(:disabled)):where(:not([aria-expanded=true])){background:var(--tint-100);border-color:var(--tint-200);color:var(--color-text)}*,*:before,*:after{box-sizing:border-box}html,body{margin:0;padding:0}body{font-family:var(--font-sans);font-size:var(--text-md);color:var(--color-text)}h1,h2,h3,h4,h5,h6,p,ul,ol,blockquote,pre,hr{margin:0}button,input,select,textarea{font:inherit;color:inherit}:root{--black: #000000;--white: #ffffff;--neutral-50: oklch(98.5% 0 none);--neutral-100: oklch(97% 0 none);--neutral-200: oklch(92.2% 0 none);--neutral-300: oklch(87% 0 none);--neutral-400: oklch(70.8% 0 none);--neutral-500: oklch(55.6% 0 none);--neutral-600: oklch(43.9% 0 none);--neutral-700: oklch(37.1% 0 none);--neutral-800: oklch(26.9% 0 none);--neutral-900: oklch(20.5% 0 none);--neutral-950: oklch(14.5% 0 none);--alpha-50: 4%;--alpha-100: 8%;--alpha-200: 15%;--alpha-300: 22%;--alpha-400: 30%;--alpha-500: 40%;--alpha-600: 50%;--alpha-700: 65%;--alpha-800: 80%;--alpha-900: 90%;--alpha-950: 95%;--blue-50: oklch(.97 .014 254.604);--blue-100: oklch(.932 .032 255.585);--blue-200: oklch(.882 .059 254.128);--blue-300: oklch(.809 .105 251.813);--blue-400: oklch(.707 .165 254.624);--blue-500: oklch(.623 .214 259.815);--blue-600: oklch(.546 .245 262.881);--blue-700: oklch(.488 .243 264.376);--blue-800: oklch(.424 .199 265.638);--blue-900: oklch(.379 .146 265.522);--red-50: oklch(.971 .013 17.38);--red-100: oklch(.936 .032 17.717);--red-200: oklch(.885 .062 18.334);--red-300: oklch(.808 .114 19.571);--red-400: oklch(.704 .191 22.216);--red-500: oklch(.637 .237 25.331);--red-600: oklch(.577 .245 27.325);--red-700: oklch(.505 .213 27.518);--red-800: oklch(.444 .177 26.899);--red-900: oklch(.396 .141 25.723);--yellow-50: oklch(.987 .026 102.212);--yellow-100: oklch(.973 .071 103.193);--yellow-200: oklch(.945 .129 101.54);--yellow-300: oklch(.905 .182 98.111);--yellow-400: oklch(.852 .199 91.936);--yellow-500: oklch(.795 .184 86.047);--yellow-600: oklch(.681 .162 75.834);--yellow-700: oklch(.554 .135 66.442);--yellow-800: oklch(.476 .114 61.907);--yellow-900: oklch(.421 .095 57.708);--yellow-950: oklch(.286 .066 53.813);--green-50: oklch(.982 .018 155.826);--green-100: oklch(.962 .044 156.743);--green-200: oklch(.925 .084 155.995);--green-300: oklch(.871 .15 154.449);--green-400: oklch(.792 .209 151.711);--green-500: oklch(.723 .219 149.579);--green-600: oklch(.627 .194 149.214);--green-700: oklch(.527 .154 150.069);--green-800: oklch(.448 .119 151.328);--green-900: oklch(.393 .095 152.535);--orange-50: oklch(.98 .016 73.684);--orange-100: oklch(.954 .038 75.164);--orange-200: oklch(.901 .076 70.697);--orange-300: oklch(.837 .128 66.29);--orange-400: oklch(.75 .183 55.934);--orange-500: oklch(.705 .213 47.604);--orange-600: oklch(.646 .222 41.116);--orange-700: oklch(.553 .195 38.402);--orange-800: oklch(.47 .157 37.304);--orange-900: oklch(.408 .123 38.172);--purple-50: oklch(.977 .014 308.299);--purple-100: oklch(.946 .033 307.174);--purple-200: oklch(.902 .063 306.703);--purple-300: oklch(.827 .119 306.383);--purple-400: oklch(.714 .203 305.504);--purple-500: oklch(.627 .265 303.9);--purple-600: oklch(.558 .288 302.321);--purple-700: oklch(.496 .265 301.924);--purple-800: oklch(.438 .218 303.724);--purple-900: oklch(.381 .176 304.987);--tint-50: color-mix(in srgb, currentColor var(--alpha-50), transparent);--tint-100: color-mix(in srgb, currentColor var(--alpha-100), transparent);--tint-200: color-mix(in srgb, currentColor var(--alpha-200), transparent);--tint-300: color-mix(in srgb, currentColor var(--alpha-300), transparent);--tint-400: color-mix(in srgb, currentColor var(--alpha-400), transparent);--tint-500: color-mix(in srgb, currentColor var(--alpha-500), transparent);--tint-600: color-mix(in srgb, currentColor var(--alpha-600), transparent);--tint-700: color-mix(in srgb, currentColor var(--alpha-700), transparent);--tint-800: color-mix(in srgb, currentColor var(--alpha-800), transparent);--tint-900: color-mix(in srgb, currentColor var(--alpha-900), transparent);--tint-950: color-mix(in srgb, currentColor var(--alpha-950), transparent);--color-text: var(--neutral-900);--color-text-muted: var(--neutral-500);--color-primary: var(--blue-600);--color-on-primary: var(--white);--color-selected: var(--color-primary);--color-background: var(--neutral-200);--color-surface: var(--white);--color-surface-muted: var(--neutral-100);--color-border: rgb(0 0 0 / 10%);--color-border-muted: rgb(0 0 0 / 6%);--color-link: inherit;--color-danger: var(--red-600);--color-success: var(--green-600);--color-warning: var(--orange-600);color-scheme:light}:root{--text-base: 14px;--text-sm: round(calc(var(--text-md) / var(--text-scale)), 1px);--text-md: var(--text-base);--text-lg: round(calc(var(--text-md) * var(--text-scale)), 1px);--text-xl: round(calc(var(--text-lg) * var(--text-scale)), 1px);--text-2xl: round(calc(var(--text-xl) * var(--text-scale)), 1px);--text-3xl: 24px;--text-4xl: 30px;--text-scale: 1.125;--leading-base: 1.5;--font-sans: "Hind", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;--font-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, monospace;--font-weight-normal: 400;--font-weight-medium: 500;--font-weight-body: var(--font-weight-medium);--font-weight-semibold: 600}:root{--space-2: 2px;--space-4: 4px;--space-6: 6px;--space-8: 8px;--space-10: 10px;--space-12: 12px;--space-16: 16px;--space-20: 20px;--space-24: 24px;--space-32: 32px;--space-48: 48px;--space-64: 64px;--radius-4: 4px;--radius-6: 6px;--radius-8: 8px;--radius-12: 12px;--radius-16: 16px;--radius-24: 24px;--radius-full: 9999px}:root{--shadow-panel: 0 8px 24px rgba(0, 0, 0, .12), 0 2px 8px rgba(0, 0, 0, .06)}@font-face{font-family:Hind;src:url(./Hind-Variable-C47b_dt9.woff2) format("woff2-variations");font-weight:300 700;font-display:block}:where(button){display:inline-flex;align-items:center;justify-content:center;gap:var(--space-6);padding:var(--space-4) var(--space-12);border:1px solid var(--tint-200);border-radius:var(--radius-6);background:var(--white);color:var(--color-text);cursor:default}:where(button:hover:not(:disabled):not([aria-expanded=true])){background:var(--neutral-100)}:where(button:active:not(:disabled)){background:var(--neutral-200)}:where(button:focus-visible){outline:2px solid var(--color-primary);outline-offset:1px}:where(button:disabled){opacity:.4}button[variant=ghost]{border-color:transparent;background:transparent;color:var(--color-text-muted)}button[variant=ghost]:hover:where(:not(:disabled)):where(:not([aria-expanded=true])){background:var(--tint-100);color:var(--color-text)}button[variant=ghost]:active:where(:not(:disabled)){background:var(--tint-200);color:var(--color-text)}button[variant=primary]{border-color:transparent;background:var(--color-primary);color:var(--color-on-primary)}button[variant=primary]:hover:where(:not(:disabled)):where(:not([aria-expanded=true])){background:var(--blue-700)}button[variant=primary]:active:where(:not(:disabled)){background:var(--blue-800)}button[variant=danger]{border-color:transparent;background:var(--red-600);color:var(--white)}button[variant=danger]:hover:where(:not(:disabled)):where(:not([aria-expanded=true])){background:var(--red-700)}button[variant=danger]:active:where(:not(:disabled)){background:var(--red-800)}:where(button[full-row]){justify-content:flex-start;gap:var(--space-8);width:100%;padding:var(--space-4) var(--space-8);text-align:left}button[icon-only]{padding:var(--space-4);display:inline-grid;place-items:center}button[icon-only]:before{content:"";inline-size:1lh;block-size:1lh;grid-area:1 / 1}button[icon-only]>*{grid-area:1 / 1}button[popovertarget]:not(:disabled):has(+[popover]:popover-open){background:var(--tint-200)}:where([popover][placement=top-end]){inset:auto;margin:0 0 var(--space-4);position-area:top span-left}:where([popover][placement=bottom-start]){inset:auto;margin:var(--space-4) 0 0;position-area:bottom span-right}:where([popover][placement=bottom-end]){inset:auto;margin:var(--space-4) 0 0;position-area:bottom span-left}:where(dialog){position:static}:where(.dialog-overlay){position:fixed;top:0;right:0;bottom:0;left:0;z-index:100;display:flex;align-items:center;justify-content:center;padding:var(--space-16);background:color-mix(in srgb,var(--black) var(--alpha-500),transparent)}:where(.dialog-alert){width:min(384px,90vw);box-sizing:border-box;padding:var(--space-24);display:flex;flex-direction:column;gap:var(--space-8)}:where(.dialog-alert h2){font-size:var(--text-lg);font-weight:var(--font-weight-semibold);overflow-wrap:break-word}:where(.dialog-alert p){color:var(--color-text-muted)}:where(.dialog-actions){margin-top:var(--space-16);display:flex;justify-content:flex-end;gap:var(--space-8)}:where([popover],dialog){background:var(--white);border:0;border-radius:var(--radius-8);padding:0;box-shadow:var(--shadow-panel)}button{font-size:var(--text-md);line-height:18px}button[size=sm]{font-size:var(--text-sm);line-height:14px;padding:var(--space-2) var(--space-8)}button[size=sm][icon-only]{padding:var(--space-2)}button[size=sm] tv-icon{font-size:12px}[electron-draggable]{-webkit-app-region:drag}[electron-draggable] :where(button,input,textarea,select,a,[role=button],[role=combobox]){-webkit-app-region:no-drag}:root{--color-bg: var(--neutral-200);--color-border: var(--neutral-300)}html,body{width:100%;height:100%;overflow-x:hidden;overscroll-behavior-x:none}
|