@telepath-computer/television 0.1.206 → 0.1.209
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/canonical/v1/components.js +1 -258
- package/dist/canonical/v1/styles.css +372 -312
- package/dist/cli.cjs +3749 -3629
- package/dist/onboarding/README.md +17 -12
- package/dist/onboarding/business-ops/about.html +4 -8
- package/dist/onboarding/business-ops/retention-vs-releases.html +0 -9
- package/dist/onboarding/business-ops/revenue-vs-goals.html +0 -11
- package/dist/onboarding/onboarding-channels.json +114 -0
- package/dist/onboarding/productivity/about.html +4 -8
- package/dist/onboarding/productivity/company-todos/index.html +0 -3
- package/dist/onboarding/productivity/company-todos/task.css +3 -3
- package/dist/onboarding/productivity/company-todos/task.js +1 -4
- package/dist/onboarding/productivity/meeting-prep.html +0 -7
- package/dist/onboarding/productivity/priorities-today.html +0 -7
- package/dist/onboarding/productivity/todays-calendar/calendar.js +327 -643
- package/dist/onboarding/productivity/todays-calendar/index.html +0 -4
- package/dist/onboarding/research/about.html +5 -9
- package/dist/onboarding/research/open-model-research.html +0 -9
- package/dist/onboarding/research/todays-news.html +3 -10
- package/dist/onboarding/tv-guide/welcome/index.html +5 -5
- package/dist/skills/television/SKILL.md +180 -136
- package/dist/skills/tv-calendar/calendar.js +327 -643
- package/dist/skills/tv-tasks/SKILL.md +10 -9
- package/dist/skills/tv-tasks/task.css +5 -6
- package/dist/skills/tv-tasks/task.js +2 -5
- package/dist/skills/tv-theme/SKILL.md +293 -193
- package/dist/views/artifact-missing/index.html +125 -60
- package/dist/views/markdown/index.html +22 -45
- package/dist/web/assets/artifact-bridge-BXDhGuL-.js +1 -0
- package/dist/web/assets/{artifactMissing-DY3nzD0p.js → artifactMissing-9rcTXhkH.js} +1 -1
- package/dist/web/assets/main-Blg8fuaV.css +1 -0
- package/dist/web/assets/main-Dlb0E5A4.js +594 -0
- package/dist/web/assets/{urlUnsupported-B2K6eB7H.js → urlUnsupported-kgq7Zh2V.js} +1 -1
- package/dist/web/index.html +4 -3
- package/dist/web/views/artifact-missing/index.html +125 -60
- package/dist/web/views/url-unsupported/index.html +127 -74
- package/package.json +2 -2
- package/dist/onboarding/onboarding-screens.json +0 -167
- package/dist/skills/tv-calendar/THIRD-PARTY-NOTICES.txt +0 -36
- package/dist/web/assets/artifact-bridge-BhiFDvPj.js +0 -1
- package/dist/web/assets/main-5017mprd.css +0 -1
- package/dist/web/assets/main-DdeZRdEy.js +0 -865
- /package/dist/canonical/v1/fonts/{Hind-Variable.woff2 → Hind-Variable.933e9900.woff2} +0 -0
|
@@ -32,245 +32,345 @@ The split matters because Television's token surface evolves across releases. A
|
|
|
32
32
|
|
|
33
33
|
## Styling surface
|
|
34
34
|
|
|
35
|
-
Television
|
|
35
|
+
A Television theme is one CSS overlay delivered to two consumers:
|
|
36
36
|
|
|
37
|
-
|
|
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.
|
|
38
39
|
|
|
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.
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
- **`<screen-select>`** — a top-edge or corner control listing available screens; lets the user switch.
|
|
43
|
-
- **`<command-panel>`** — persistent chrome that floats over content (bottom or corner). Hosts global commands and command panel input/content. Uses paper material in dark tone by default.
|
|
44
|
-
- **`<screen-view>` → `<layout-view>`** — page container holding the scrollable canvas where artifact cards live.
|
|
45
|
-
- **`<artifact-view>`** — each artifact card. Glass-material title bar wrapping a paper-material content surface (the artifact's rendered HTML, in an iframe).
|
|
46
|
-
- **Popovers, dropdowns, modals** — paper-material panels for transient and modal UI.
|
|
42
|
+
Themes have two tools:
|
|
47
43
|
|
|
48
|
-
|
|
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.
|
|
49
46
|
|
|
50
|
-
|
|
47
|
+
### Canonical token snapshot
|
|
51
48
|
|
|
52
|
-
|
|
53
|
-
- **`tone="light" | "dark"`** — flips three things on every descendant of the surface: body text color (descendants inherit a light foreground when `tone="dark"`), hairline edge color, and the overlay hover/active tokens. Anything using `currentColor` (icons, tints, `color: inherit` headings) flips automatically. This is what makes dark mode work without per-component overrides.
|
|
54
|
-
- **`level="1" | "2" | "overlay"`** — shadow stack only. `1` = small drop-shadow (popovers, dropdowns), `2` = lifted card (artifact bodies), `overlay` = no shadow (persistent chrome bonded to viewport, like the command panel).
|
|
55
|
-
|
|
56
|
-
If you want a dark theme: set `color-scheme: dark` and rely on the existing `[tone="dark"]` rules in `materials.css` to flip foregrounds across descendants — you don't need to override every component.
|
|
57
|
-
|
|
58
|
-
### The token contract
|
|
59
|
-
|
|
60
|
-
Two source files in `packages/ui/styles/`:
|
|
61
|
-
|
|
62
|
-
- **`tokens.css`** — palette and scales. Raw values: `--neutral-50` through `--neutral-950`, color palettes (`--red-*`, `--blue-*`, etc.), `--alpha-50` through `--alpha-950`, `--tint-50` through `--tint-950`, type scale (`--text-base`, `--text-sm`, `--text-lg`), spacing (`--space-2`, `--space-4`, `--space-6`, `--space-8`, `--space-10`, `--space-12`, `--space-16`, `--space-20`, `--space-24`, `--space-32`, `--space-48`, `--space-64`), radii (`--radius-4` through `--radius-full`), control heights (`--control-height-xs/sm/md`), shadows (`--shadow-hairline`, `--shadow-control`), fonts (`--font-sans`, `--font-mono`, `--font-brand`).
|
|
63
|
-
- **`theme.css`** — semantic mappings most themes override.
|
|
64
|
-
|
|
65
|
-
Current `theme.css` content as of this skill build (always read live source for the latest — see below):
|
|
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.
|
|
66
50
|
|
|
67
51
|
```css
|
|
52
|
+
/* colors.css */
|
|
68
53
|
:root {
|
|
69
|
-
|
|
70
|
-
--
|
|
71
|
-
--
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
--
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
--
|
|
79
|
-
--
|
|
80
|
-
|
|
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. */
|
|
81
173
|
--color-text: var(--neutral-900);
|
|
82
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. */
|
|
83
203
|
--color-link: inherit;
|
|
84
|
-
|
|
85
|
-
--color-overlay-backdrop: rgb(0 0 0 / 0.5);
|
|
86
|
-
--color-highlight: rgb(255 255 255 / 0.5);
|
|
87
|
-
--color-primary: var(--blue-500);
|
|
204
|
+
/* The destructive and error role. */
|
|
88
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);
|
|
89
210
|
|
|
90
211
|
color-scheme: light;
|
|
91
212
|
}
|
|
92
|
-
```
|
|
93
213
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
+
}
|
|
99
237
|
|
|
100
|
-
|
|
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
|
+
}
|
|
101
263
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
+
}
|
|
105
273
|
```
|
|
106
274
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
Alternative — from a Television source checkout:
|
|
275
|
+
For nontrivial work, read the complete live canonical stylesheet:
|
|
110
276
|
|
|
111
277
|
```bash
|
|
112
|
-
|
|
278
|
+
# The default local server URL is http://localhost:32848.
|
|
279
|
+
curl http://localhost:32848/canonical/v1/styles.css
|
|
113
280
|
```
|
|
114
281
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
Themes have two complementary tools:
|
|
118
|
-
|
|
119
|
-
- **Override semantic tokens on `:root`** when you want a change to propagate everywhere it's relevant — every paper surface, every body text, every focus ring. One token edit, system-wide effect. Use this for the look's foundations: backgrounds, foregrounds, primary accents, border weights.
|
|
120
|
-
- **Override specific selectors** when the intent is local to a surface — the command panel input gets a special background, the artifact title bar uses a custom font, the layout canvas gets a subtle background image. Selectors give surgical control; tokens can't always express what a design wants.
|
|
121
|
-
|
|
122
|
-
Both are first-class. A typical theme uses tokens for ~80% of its effect and selector-level rules for the rest. Don't avoid selectors out of orthodoxy; use them where they fit.
|
|
123
|
-
|
|
124
|
-
The one rule for selector-level rules: **comment them with their purpose.** When Television's component structure shifts in a future release, the comment is what lets an agent re-author the rule against the new structure. Without the comment, a stale selector is just dead CSS — nobody knows what it was for.
|
|
125
|
-
|
|
126
|
-
## Surface-by-surface guidance
|
|
127
|
-
|
|
128
|
-
A theme that touches `:root` tokens will affect every surface listed below. The notes here describe what each surface consumes so you know which tokens drive which look — useful for predicting how a token change will land.
|
|
129
|
-
|
|
130
|
-
### App background and wallpaper
|
|
131
|
-
|
|
132
|
-
`<television-app>` is the root surface — the thing that fills the window. Out of the box it shows a bundled wallpaper image with a fallback background color. Two app-level tokens control this layer:
|
|
282
|
+
For another server, run `tv status`, read `serverURL` from its JSON output, and fetch `<serverURL>/canonical/v1/styles.css`.
|
|
133
283
|
|
|
134
|
-
|
|
135
|
-
- **`--app-wallpaper`** — the `background-image` value, defaulting to the bundled wallpaper `url(...)`. Set this to `none` to remove the wallpaper (so `--app-bg` shows), or to a `url(...)` (typically pointing at a theme asset) to use a custom wallpaper.
|
|
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.
|
|
136
285
|
|
|
137
|
-
|
|
286
|
+
`color-scheme: dark` controls browser-native widgets such as scrollbars and form controls. Set it when the theme uses a dark ground.
|
|
138
287
|
|
|
139
|
-
|
|
140
|
-
- Want a custom wallpaper? `:root { --app-wallpaper: url(my-bg.jpg); }` where `my-bg.jpg` is in the theme's `resources/` folder (the server will rewrite the relative URL).
|
|
141
|
-
- The default-look bundled wallpaper is `packages/web/src/assets/wallpapers/clouds.jpg` — themes don't import or reference it; they replace the variable.
|
|
288
|
+
## Current browser chrome structure
|
|
142
289
|
|
|
143
|
-
|
|
290
|
+
Use this map only for chrome-specific rules and verify the result in the running version:
|
|
144
291
|
|
|
145
|
-
|
|
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.
|
|
146
298
|
|
|
147
|
-
|
|
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.
|
|
148
300
|
|
|
149
|
-
|
|
150
|
-
- **`<button variant="ghost">`** — fully chromeless, no fill. Hover/active backgrounds use `--color-overlay-hover` / `--color-overlay-active` (semantic overlay tokens that auto-flip with the surface's `tone`). The transparent-chrome auto-tone watcher (`packages/ui/utils/button-tone.ts`) samples `[variant="ghost"]`, `[variant="glass"]`, and `[material="glass"]` when they create a new tone boundary; nested transparent chrome inherits an ancestor `tone` unless it explicitly declares its own.
|
|
151
|
-
- **`<button variant="primary">`** — emphasis button. Fills with `--color-primary` for the bg, `--white` for text.
|
|
152
|
-
- **Icon-only buttons** — `<button icon-only>` becomes a square at `--control-height-md` per side.
|
|
301
|
+
## Surface guidance
|
|
153
302
|
|
|
154
|
-
|
|
303
|
+
### Application and stage ground
|
|
155
304
|
|
|
156
|
-
-
|
|
157
|
-
- Adjust `--color-overlay-hover` / `--color-overlay-active` to change ghost-button hover intensity (these also affect dropdown items and other chromeless overlays).
|
|
158
|
-
- Adjust `--color-primary` for emphasis-button fills.
|
|
159
|
-
- Don't set `cursor: pointer` on buttons — there's a global rule in `elements.css` that sets `cursor: default` to match the macOS-native feel.
|
|
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`.
|
|
160
306
|
|
|
161
|
-
|
|
307
|
+
A theme can establish its broad palette with current role tokens:
|
|
162
308
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
- Adjust the title's font weight or letter spacing via selector-level rules on `artifact-view > header` if the design needs a non-token change (comment the rule with purpose).
|
|
175
|
-
|
|
176
|
-
### Command panel — input + content
|
|
177
|
-
|
|
178
|
-
`<command-panel>` is the persistent chrome at the bottom (or corner) of the app. It hosts the command panel input (typically a textarea) and command panel content above it. By default uses **paper** material in **dark** tone, **`level="overlay"`** (no shadow — it's bonded to the viewport).
|
|
179
|
-
|
|
180
|
-
What it consumes:
|
|
181
|
-
|
|
182
|
-
- The paper-dark surface — a near-black opaque fill defined by `materials.css` reading from the `[tone="dark"]` overrides of `--color-surface` and related tokens.
|
|
183
|
-
- `--color-text` (descendants inherit, but with `tone="dark"` flipping descendants to a light foreground).
|
|
184
|
-
- `--color-text-muted` for secondary text in the stream (timestamps, system messages).
|
|
185
|
-
- `--color-border` / `--color-border-muted` for separators between messages.
|
|
186
|
-
- The input's textarea consumes `--color-interactive` (background) and `--color-border` (rim).
|
|
187
|
-
|
|
188
|
-
Theme levers:
|
|
189
|
-
|
|
190
|
-
- Override the dark-tone surface color: target `[tone="dark"]` in your theme and set `--color-surface` (or set it on `command-panel` directly with a purpose comment).
|
|
191
|
-
- Adjust message-stream separator weight via `--color-border-muted`.
|
|
192
|
-
- Adjust the command panel input's affordance via `--color-interactive`.
|
|
193
|
-
- For dramatic looks (a saturated command panel background, a textured command panel surface), target `command-panel` directly with a purpose comment.
|
|
194
|
-
|
|
195
|
-
### Popovers and dropdowns
|
|
196
|
-
|
|
197
|
-
Anchored panels for menus and inline forms. Paper material, light tone typically, `level="1"` (small drop-shadow). Dismiss on outside click.
|
|
198
|
-
|
|
199
|
-
What they consume:
|
|
200
|
-
|
|
201
|
-
- `--color-surface` (paper fill).
|
|
202
|
-
- `--color-border` (hairline rim).
|
|
203
|
-
- `--color-text` (label text), `--color-text-muted` (secondary labels).
|
|
204
|
-
- `--color-overlay-hover` / `--color-overlay-active` for hover/active states on individual items (these are *also* used by ghost buttons, so changing them affects both surfaces — usually fine, since the relationship is semantic).
|
|
205
|
-
- `--shadow-control` for the drop shadow (defined as a soft 2-layer shadow).
|
|
206
|
-
|
|
207
|
-
Theme levers:
|
|
208
|
-
|
|
209
|
-
- Surface color via `--color-surface`.
|
|
210
|
-
- Hairline rim via `--color-border`.
|
|
211
|
-
- The overlay-hover token controls both popover-item and ghost-button hover; usually move them together.
|
|
212
|
-
|
|
213
|
-
### Modal sheets
|
|
214
|
-
|
|
215
|
-
Full-screen overlays for blocking flows. Paper material, larger than popovers, no specific level (often `level="2"`).
|
|
216
|
-
|
|
217
|
-
What they consume:
|
|
218
|
-
|
|
219
|
-
- `--color-surface` (fill).
|
|
220
|
-
- `--color-overlay-backdrop` for the scrim behind the modal (the dark veil over the rest of the app while the modal is open).
|
|
221
|
-
- All the popover tokens for internal elements.
|
|
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
|
+
```
|
|
222
320
|
|
|
223
|
-
|
|
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.
|
|
224
322
|
|
|
225
|
-
|
|
226
|
-
- The modal surface via `--color-surface`.
|
|
323
|
+
### Sidebar
|
|
227
324
|
|
|
228
|
-
|
|
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:
|
|
229
326
|
|
|
230
|
-
|
|
327
|
+
```css
|
|
328
|
+
/* Keep the channel list visually distinct from the stage with a warm paper ground. */
|
|
329
|
+
.sidebar {
|
|
330
|
+
background: #fffaf0;
|
|
331
|
+
}
|
|
332
|
+
```
|
|
231
333
|
|
|
232
|
-
|
|
334
|
+
### Stage pages and artifact frames
|
|
233
335
|
|
|
234
|
-
|
|
235
|
-
- `--color-bg-muted` if the canvas distinguishes content areas (e.g. gutter regions vs. card region).
|
|
236
|
-
- `--color-border-muted` for any grid lines, if a future debug mode shows them.
|
|
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`.
|
|
237
337
|
|
|
238
|
-
|
|
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
|
+
```
|
|
239
344
|
|
|
240
|
-
|
|
241
|
-
- `--color-bg-muted` for related secondary surfaces.
|
|
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.
|
|
242
346
|
|
|
243
|
-
###
|
|
347
|
+
### Popovers and dialogs
|
|
244
348
|
|
|
245
|
-
|
|
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.
|
|
246
350
|
|
|
247
|
-
|
|
351
|
+
### Artifact documents
|
|
248
352
|
|
|
249
|
-
|
|
250
|
-
- `<h1>`–`<h6>` use `--font-brand` (often the same as `--font-sans` unless overridden), with the type scale tokens (`--text-base`, `--text-lg`, `--text-xl`) and `--color-text` for color.
|
|
251
|
-
- `<a>` uses `--color-link` (defaults to `inherit` — links read in the body color unless a theme sets otherwise).
|
|
252
|
-
- `<code>` and `<pre>` use `--font-mono`, `--color-bg-muted` for the background, `--color-text` for content.
|
|
253
|
-
- Form controls (`<input>`, `<textarea>`, `<select>`) consume `--control-height-md`, `--color-interactive`, `--color-border`, `--color-focus-ring`.
|
|
353
|
+
Artifacts load the canonical stylesheet plus the active theme. The canonical foundation provides:
|
|
254
354
|
|
|
255
|
-
|
|
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.
|
|
256
360
|
|
|
257
|
-
|
|
258
|
-
- For a theme with a distinctive link color (e.g. a brand accent), set `--color-link: <value>`.
|
|
259
|
-
- For a theme with a custom code/pre font, override `--font-mono`.
|
|
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.
|
|
260
362
|
|
|
261
|
-
##
|
|
363
|
+
## Theme contents
|
|
262
364
|
|
|
263
|
-
|
|
264
|
-
- `@font-face` declarations for custom typography (font files in the skill's `resources/` folder; reference relatively from `theme.css`, e.g. `url(MyFont.woff2)` — the render step copies them into the theme folder).
|
|
265
|
-
- Background images, decorative images (same path — `resources/` in the skill, copied alongside `theme.css`).
|
|
266
|
-
- `@media (prefers-color-scheme: dark)` blocks if the theme should react to OS-level light/dark.
|
|
267
|
-
- Selector-level rules **with purpose comments** for design intent the tokens can't fully express.
|
|
365
|
+
A theme may contain:
|
|
268
366
|
|
|
269
|
-
|
|
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.
|
|
270
372
|
|
|
271
|
-
|
|
272
|
-
- Theme manifests with metadata beyond the SKILL.md.
|
|
273
|
-
- Multiple variants within one theme (a theme is one look; if you want a dark variant of a light theme, that's a separate theme).
|
|
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.
|
|
274
374
|
|
|
275
375
|
## Workflow
|
|
276
376
|
|
|
@@ -288,11 +388,11 @@ Theme authoring has two phases. **Iterate first** — work directly on `theme.cs
|
|
|
288
388
|
|
|
289
389
|
```css
|
|
290
390
|
/*
|
|
291
|
-
*
|
|
292
|
-
*
|
|
391
|
+
* Give the selected document's lower title band a faint warm tint as a
|
|
392
|
+
* quiet orientation cue without adding a heavier indicator.
|
|
293
393
|
*/
|
|
294
|
-
[
|
|
295
|
-
background: color-mix(in srgb, var(--color-
|
|
394
|
+
.page[selected] > .artifact-frame .artifact-title-bar {
|
|
395
|
+
background: color-mix(in srgb, var(--color-primary) 8%, transparent);
|
|
296
396
|
}
|
|
297
397
|
```
|
|
298
398
|
|
|
@@ -316,7 +416,7 @@ The SKILL.md should have:
|
|
|
316
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."*
|
|
317
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.
|
|
318
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/`.
|
|
319
|
-
- **Render instructions.** A short section telling future invocations how to render this skill: "fetch the live Television token surface
|
|
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>/`."
|
|
320
420
|
|
|
321
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.
|
|
322
422
|
|
|
@@ -327,9 +427,9 @@ When Television's token surface or component structure changes (new tokens added
|
|
|
327
427
|
Recovery procedure (the theme skill makes this possible):
|
|
328
428
|
|
|
329
429
|
1. **Read the current Television surface:**
|
|
330
|
-
- Running server: `curl http://localhost:32848/canonical/v1/styles.css
|
|
331
|
-
- Or, from a checkout: `
|
|
332
|
-
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`
|
|
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.
|
|
333
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.
|
|
334
434
|
4. **Update the skill's Style overrides section** with the revised rules (keep the purpose comments updated).
|
|
335
435
|
5. **Re-render**: write the updated CSS to `<storagePath>/themes/<name>/theme.css` and re-copy any new/changed assets from `resources/`.
|