@motion-proto/live-tokens 0.67.0 → 0.68.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +67 -9
  3. package/bin/generate-theme.mjs +5 -4
  4. package/dist-plugin/adjust/index.d.cts +1 -1
  5. package/dist-plugin/adjust/index.d.ts +1 -1
  6. package/dist-plugin/{chunk-T4PMCFJN.js → chunk-2UX6EVVA.js} +30 -30
  7. package/dist-plugin/{dataPaths-DZUzVv8H.d.cts → dataPaths-bJTCEO4H.d.cts} +1 -1
  8. package/dist-plugin/{dataPaths-DZUzVv8H.d.ts → dataPaths-bJTCEO4H.d.ts} +1 -1
  9. package/dist-plugin/fontPairing/index.d.cts +1 -1
  10. package/dist-plugin/fontPairing/index.d.ts +1 -1
  11. package/dist-plugin/generateColorsAndType/index.d.cts +1 -1
  12. package/dist-plugin/generateColorsAndType/index.d.ts +1 -1
  13. package/dist-plugin/index.cjs +32 -32
  14. package/dist-plugin/index.d.cts +1 -1
  15. package/dist-plugin/index.d.ts +1 -1
  16. package/dist-plugin/index.js +5 -5
  17. package/dist-plugin/migrateData/index.cjs +30 -30
  18. package/dist-plugin/migrateData/index.d.cts +1 -1
  19. package/dist-plugin/migrateData/index.d.ts +1 -1
  20. package/dist-plugin/migrateData/index.js +1 -1
  21. package/dist-plugin/tokensCssMigrations/index.d.cts +1 -1
  22. package/dist-plugin/tokensCssMigrations/index.d.ts +1 -1
  23. package/package.json +4 -4
  24. package/src/editor/bootstrap.ts +6 -6
  25. package/src/editor/component-editor/ImageLightboxEditor.svelte +1 -1
  26. package/src/editor/component-editor/scaffolding/ComponentFileManager.svelte +4 -4
  27. package/src/editor/core/fonts/fontLoader.ts +2 -2
  28. package/src/editor/core/preview/{lookPreview.ts → themePreview.ts} +27 -27
  29. package/src/editor/core/productionPulse.ts +3 -3
  30. package/src/editor/core/sketch/index.ts +52 -44
  31. package/src/editor/core/sketch/maskField.ts +9 -9
  32. package/src/editor/core/sketch/sketchLayer.ts +9 -9
  33. package/src/editor/core/sketch/sketchRegistry.ts +34 -34
  34. package/src/editor/core/sketch/sketchStore.ts +98 -83
  35. package/src/editor/core/sketch/sketchStyleService.ts +4 -4
  36. package/src/editor/core/sketch/sketchStyles.ts +28 -28
  37. package/src/editor/core/themes/colorsAndTypeService.ts +1 -1
  38. package/src/editor/core/themes/loadRows.ts +8 -8
  39. package/src/editor/core/themes/themeDocumentSync.ts +2 -2
  40. package/src/editor/core/themes/themeInit.ts +2 -2
  41. package/src/editor/core/themes/themeService.ts +17 -17
  42. package/src/editor/core/themes/{lookSummary.ts → themeSummary.ts} +9 -9
  43. package/src/editor/core/themes/themeTypes.ts +10 -6
  44. package/src/editor/docs/content/getting-started.md +1 -1
  45. package/src/editor/docs/content/sketch-mode.md +22 -17
  46. package/src/editor/docs/content/themes-workflow.md +11 -11
  47. package/src/editor/docs/content/where-themes-live.md +6 -6
  48. package/src/editor/docs/content.generated.ts +4 -4
  49. package/src/editor/index.ts +2 -2
  50. package/src/editor/ui/ThemePanel.svelte +52 -52
  51. package/src/editor/ui/sketch/SketchPreview.svelte +2 -2
  52. package/src/editor/ui/sketch/SketchTab.svelte +64 -38
  53. package/src/live-tokens/data/sketch-styles/dry.json +5 -5
  54. package/src/live-tokens/data/sketch-styles/hatched.json +9 -9
  55. package/src/live-tokens/data/sketch-styles/napkin.json +4 -4
  56. package/src/live-tokens/data/sketch-styles/pencil.json +2 -2
  57. package/src/live-tokens/data/themes/autumn.json +1 -1
  58. package/src/live-tokens/data/themes/halloween.json +1 -1
  59. package/src/live-tokens/data/themes/midnight-study.json +1 -1
  60. package/src/live-tokens/data/themes/ocean.json +1 -1
  61. package/src/live-tokens/data/themes/royal-velvet.json +1 -1
  62. package/src/live-tokens/data/themes/sketchy.json +1 -1
  63. package/src/live-tokens/data/themes/spring-meadow.json +1 -1
  64. package/src/live-tokens/data/themes/sunset.json +1 -1
  65. package/src/system/backdrop/backdrop.ts +1 -1
  66. package/src/system/components/SectionDivider.svelte +1 -1
@@ -2,7 +2,7 @@ import { liveMovedSinceBake } from '../productionPulse';
2
2
  import { openThemeSlug } from '../store/editorConfigStore';
3
3
  import { loadThemeFromApi } from '../store/editorStore';
4
4
  import { migrateColorsAndTypeFonts } from '../fonts/fontMigration';
5
- import { openThemeSketchStyle } from '../sketch/sketchStore';
5
+ import { openThemeSketchSettings } from '../sketch/sketchStore';
6
6
  import type { ApplyThemeResult } from './themeService';
7
7
 
8
8
  const CHANNEL_NAME = 'live-tokens:active-theme:v1';
@@ -43,7 +43,7 @@ export function hydrateAppliedTheme(fileName: string, result: ApplyThemeResult):
43
43
  migrateColorsAndTypeFonts(colorsAndType);
44
44
  loadThemeFromApi(colorsAndType, structuredClone(result.componentConfigs));
45
45
  openThemeSlug.set(fileName);
46
- openThemeSketchStyle(result.theme.sketchStyle);
46
+ openThemeSketchSettings(result.theme.sketchSettings);
47
47
  liveMovedSinceBake.set(false);
48
48
  if (typeof document !== 'undefined') {
49
49
  document.dispatchEvent(new CustomEvent<AppliedThemeDetail>(THEME_APPLIED_EVENT, {
@@ -65,9 +65,9 @@ export async function initializeTheme(): Promise<void> {
65
65
 
66
66
  const active = await safeFetch<Theme>(`${API_BASE}/themes/active`);
67
67
  // A failed fetch is not "the theme carries no sketchstyle": treating null as
68
- // absent would tell the panel the look is off the theme, or hand a fresh
68
+ // absent would tell the panel the sketchstyle is off the theme, or hand a fresh
69
69
  // browser a blank buffer, over a fetch that will likely succeed next time.
70
70
  // The same call a built site makes (`@motion-proto/live-tokens/sketch`), so
71
71
  // one rule decides what a theme's sketchstyle means at boot in both.
72
- if (active) seedSketchFromTheme(active.sketchStyle);
72
+ if (active) seedSketchFromTheme(active.sketchSettings);
73
73
  }
@@ -7,15 +7,15 @@ import { getActiveColorsAndType } from './colorsAndTypeService';
7
7
  import { broadcastAppliedTheme, hydrateAppliedTheme } from './themeDocumentSync';
8
8
  import { CURRENT_COMPONENT_SCHEMA_VERSION } from './migrations';
9
9
  import { THEME_SCHEMA_VERSION } from './themeTypes';
10
- import { liveSketchStyle, themeSketchStyle } from '../sketch/sketchStore';
10
+ import { liveSketchSettings, themeSketchSettings } from '../sketch/sketchStore';
11
11
 
12
12
  export type { ThemeFillReport };
13
13
 
14
14
  /**
15
15
  * REST client for theme files, the documents of the editor. A theme carries a
16
- * whole look by value: the colors and type plus a config for every component
16
+ * whole content by value: the colors and type plus a config for every component
17
17
  * this install has. One theme is open (`themes/_active.json`) and one is
18
- * published (`themes/_production.json`); the live look is the open theme plus
18
+ * published (`themes/_production.json`); the live content is the open theme plus
19
19
  * whatever the `_working` buffers hold over it.
20
20
  *
21
21
  * `default` is the protected baseline — cannot be overwritten or deleted, and
@@ -75,7 +75,7 @@ export interface ApplyThemeResult {
75
75
  * Open a theme: the server clears the `_working` buffers, points
76
76
  * `themes/_active.json` at it, and returns the resolved state in one payload.
77
77
  * Live reads then fall through to the theme's embedded layers.
78
- * Production is untouched, so trying a look cannot change what the site ships.
78
+ * Production is untouched, so trying a content cannot change what the site ships.
79
79
  * The resolved response hydrates the caller immediately, then broadcasts the
80
80
  * same typed state to every already-open same-origin host/editor document.
81
81
  * Each store renderer projects that state into its own document, so a theme
@@ -96,7 +96,7 @@ export async function applyTheme(fileName: string): Promise<ApplyThemeResult> {
96
96
  return result;
97
97
  }
98
98
 
99
- export interface AdoptLookResult {
99
+ export interface AdoptThemeResult {
100
100
  ok: boolean;
101
101
  /** The theme production now ships. */
102
102
  productionTheme: { fileName: string; name: string; updatedAt: string };
@@ -111,7 +111,7 @@ export interface AdoptLookResult {
111
111
  * Answers 409 `ACTIVE_IS_PROTECTED` while the Default theme is open, which the
112
112
  * caller recovers from by forking it under a name of the user's own.
113
113
  */
114
- export async function adoptLook(): Promise<AdoptLookResult> {
114
+ export async function adoptTheme(): Promise<AdoptThemeResult> {
115
115
  const res = await fetch(`${API_BASE}/production`, { method: 'PUT' });
116
116
  if (!res.ok) {
117
117
  const body = await res.json().catch(() => ({}));
@@ -135,7 +135,7 @@ function withoutLiveMarkers<T extends { _fileName?: string; _source?: unknown }>
135
135
  }
136
136
 
137
137
  /**
138
- * The look as it stands: the live colors and type plus the live config of
138
+ * The content as it stands: the live colors and type plus the live config of
139
139
  * every component this install has, all by value. A theme is a complete
140
140
  * document (`docs/plans/theme-completeness.md`), so the capture carries every
141
141
  * component, not just the ones off their default.
@@ -145,7 +145,7 @@ function withoutLiveMarkers<T extends { _fileName?: string; _source?: unknown }>
145
145
  * way out of `GET /colors-and-type/active`, which matters: the server trusts an
146
146
  * already-embedded copy and runs no migrations over it on write.
147
147
  */
148
- async function captureLook(): Promise<Pick<Theme, 'colorsAndType' | 'componentConfigs' | 'sketchStyle'>> {
148
+ async function captureThemeContent(): Promise<Pick<Theme, 'colorsAndType' | 'componentConfigs' | 'sketchSettings'>> {
149
149
  const liveColorsAndType = await getActiveColorsAndType();
150
150
  if (!liveColorsAndType) {
151
151
  throw new Error('No live colors and type to capture');
@@ -159,11 +159,11 @@ async function captureLook(): Promise<Pick<Theme, 'colorsAndType' | 'componentCo
159
159
  });
160
160
  // Sketchstyle has no server door of its own (RJC 8): the live buffer, not a
161
161
  // fetch, is the source of truth for what the dials currently say.
162
- return { colorsAndType: withoutLiveMarkers(liveColorsAndType), componentConfigs, sketchStyle: liveSketchStyle() };
162
+ return { colorsAndType: withoutLiveMarkers(liveColorsAndType), componentConfigs, sketchSettings: liveSketchSettings() };
163
163
  }
164
164
 
165
165
  /**
166
- * Capture the current look into a new theme file and open it. Used by the
166
+ * Capture the current content into a new theme file and open it. Used by the
167
167
  * theme panel's Save As action and by the fork-then-Adopt flow the protected
168
168
  * Default theme forces.
169
169
  */
@@ -171,7 +171,7 @@ export async function saveAsTheme(
171
171
  fileName: string,
172
172
  displayName: string,
173
173
  ): Promise<void> {
174
- const look = await captureLook();
174
+ const content = await captureThemeContent();
175
175
  const now = new Date().toISOString();
176
176
  await saveTheme(fileName, {
177
177
  name: displayName,
@@ -179,15 +179,15 @@ export async function saveAsTheme(
179
179
  updatedAt: now,
180
180
  schemaVersion: THEME_SCHEMA_VERSION,
181
181
  componentSchemaVersion: CURRENT_COMPONENT_SCHEMA_VERSION,
182
- ...look,
182
+ ...content,
183
183
  });
184
- themeSketchStyle.set(look.sketchStyle);
184
+ themeSketchSettings.set(content.sketchSettings);
185
185
  liveMovedSinceBake.set(true);
186
186
  await setActiveTheme(fileName);
187
187
  }
188
188
 
189
189
  /**
190
- * Re-capture the current look into the open theme file. Used by the theme
190
+ * Re-capture the current content into the open theme file. Used by the theme
191
191
  * panel's Save action and by both Adopt paths, which publish what is saved.
192
192
  * The server rejects with 403 while the protected `default` theme is open.
193
193
  */
@@ -196,16 +196,16 @@ export async function saveActiveTheme(displayName?: string): Promise<void> {
196
196
  if (!active || !active._fileName) {
197
197
  throw new Error('No active theme');
198
198
  }
199
- const look = await captureLook();
199
+ const content = await captureThemeContent();
200
200
  await saveTheme(active._fileName, {
201
201
  name: displayName ?? active.name,
202
202
  createdAt: active.createdAt,
203
203
  updatedAt: new Date().toISOString(),
204
204
  schemaVersion: THEME_SCHEMA_VERSION,
205
205
  componentSchemaVersion: CURRENT_COMPONENT_SCHEMA_VERSION,
206
- ...look,
206
+ ...content,
207
207
  });
208
- themeSketchStyle.set(look.sketchStyle);
208
+ themeSketchSettings.set(content.sketchSettings);
209
209
  liveMovedSinceBake.set(true);
210
210
  }
211
211
 
@@ -1,17 +1,17 @@
1
1
  import type { ComponentSummary } from '../components/componentConfigService';
2
2
 
3
- export interface LookProductionInput {
3
+ export interface ThemeProductionInput {
4
4
  /** Slug of the theme the editor has open. */
5
5
  openTheme: string;
6
6
  /** Slug of the published theme, or null while the read has not landed. */
7
7
  productionTheme: string | null;
8
- /** Live look moved past what the published theme holds: unsaved edits, or a
8
+ /** Live theme moved past what the published theme holds: unsaved edits, or a
9
9
  * save since the last Adopt. */
10
10
  unpublished: boolean;
11
11
  }
12
12
 
13
- export interface LookProductionState {
14
- /** True when production is known to ship the look on screen. */
13
+ export interface ThemeProductionState {
14
+ /** True when production is known to ship the theme on screen. */
15
15
  inProduction: boolean;
16
16
  /** True while the production theme is unread: neither claim can be made. */
17
17
  unknown: boolean;
@@ -22,9 +22,9 @@ export interface LookProductionState {
22
22
  }
23
23
 
24
24
  /**
25
- * Whether production is running the look on screen. Production is one saved
25
+ * Whether production is running the theme on screen. Production is one saved
26
26
  * theme, so the first half is an identity check against the open one; the
27
- * second half is the live look sitting ahead of what was published, which
27
+ * second half is the live theme sitting ahead of what was published, which
28
28
  * `unpublished` carries.
29
29
  *
30
30
  * A null production read is not an answer, so it is neither state: `unknown`
@@ -32,11 +32,11 @@ export interface LookProductionState {
32
32
  * neutral state, which keeps a mount from flashing the alarm without letting a
33
33
  * read that never lands read as shipped forever.
34
34
  */
35
- export function lookProductionState({
35
+ export function themeProductionState({
36
36
  openTheme,
37
37
  productionTheme,
38
38
  unpublished,
39
- }: LookProductionInput): LookProductionState {
39
+ }: ThemeProductionInput): ThemeProductionState {
40
40
  const unknown = productionTheme === null;
41
41
  const themeOff = !unknown && productionTheme !== openTheme;
42
42
  return {
@@ -48,6 +48,6 @@ export function lookProductionState({
48
48
  }
49
49
 
50
50
  /** How many components run an unsaved buffer, diverging from what the open theme carries. */
51
- export function countComponentsOffLook(components: ComponentSummary[]): number {
51
+ export function countComponentsOffTheme(components: ComponentSummary[]): number {
52
52
  return components.filter((c) => c.source === 'working').length;
53
53
  }
@@ -2,13 +2,17 @@ import type { CurveAnchor } from '../../ui/curveEngine';
2
2
  import type { GradientValue } from './parsers/gradient';
3
3
  import type { Oklch } from '../palettes/oklch';
4
4
  import type { HarmonyAxis } from '../palettes/colorHarmony';
5
- import type { SketchStyle } from '../sketch/sketchStyles';
5
+ import type { SketchStyleSettings } from '../sketch/sketchStyles';
6
6
  /** Single source of truth for the theme schema version
7
7
  * (docs/plans/theme-completeness.md, Wave 2 step 5). It lives here, on the
8
8
  * shipped side: `vite-plugin/` is build tooling and is not in the tarball, so
9
9
  * anything under `src/` that reaches into it resolves in this repo and
10
10
  * nowhere else. `normalizeTheme.ts` re-exports this. */
11
- export const THEME_SCHEMA_VERSION = 4;
11
+ /** 5 renamed the sketch field from `sketchStyle` to `sketchSettings`. The bump
12
+ * is what makes the boot pass rewrite a theme still on the old key: the read
13
+ * accepts both, but a built site reads its theme JSON raw and would see
14
+ * `undefined` until the file itself was converted. */
15
+ export const THEME_SCHEMA_VERSION = 5;
12
16
 
13
17
  /** What the completeness fill had to add to reach a whole theme. `components`
14
18
  * names each component the input carried no entry for; `aliases` counts keys
@@ -240,7 +244,7 @@ export interface ComponentConfigMeta {
240
244
  }
241
245
 
242
246
  /**
243
- * A saved look, encapsulated: the colors and type plus a config for every
247
+ * A saved theme, encapsulated: the colors and type plus a config for every
244
248
  * component this install has, all carried by value. Themes are the documents
245
249
  * of the editor. Applying one opens it by clearing the reserved `_working`
246
250
  * buffers and updating `themes/_active.json`; live reads fall through to its
@@ -267,7 +271,7 @@ export interface Theme {
267
271
  * component schema and then fills any gap from the local default, on every
268
272
  * read (Waves 1 and 2 of `docs/plans/theme-completeness.md`); both the
269
273
  * migration and the fill are persisted on the next write, so a theme is a
270
- * whole-look document rather than a diff against a moving baseline.
274
+ * whole-theme document rather than a diff against a moving baseline.
271
275
  * `component-configs/<id>/default.json` is the derivation product of that
272
276
  * component's `:global(:root)`, not a resolution layer this map defers to
273
277
  * — a config for a component this install does not have, or an alias key
@@ -280,10 +284,10 @@ export interface Theme {
280
284
  * buy no isolation. `normalizeTheme` sets this on every read; an embedded
281
285
  * config's own `schemaVersion` (if hand-authored) is ignored and stripped. */
282
286
  componentSchemaVersion: number;
283
- /** The sketchstyle this look paints, by value. Absent means the look is
287
+ /** The sketchstyle this theme paints, by value. Absent means the theme is
284
288
  * crisp: presence is the on state, so there is no separate flag that can
285
289
  * disagree with the dials beside it (RJC 1). */
286
- sketchStyle?: SketchStyle;
290
+ sketchSettings?: SketchStyleSettings;
287
291
  /** Server-attached file-name marker. Same role as `ColorsAndType._fileName`. */
288
292
  _fileName?: string;
289
293
  }
@@ -54,7 +54,7 @@ the editor swaps live.
54
54
  To ship, click **Adopt** in the Theme panel. That saves the open theme and bakes
55
55
  it into `src/live-tokens/data/tokens.generated.css`, which your build bundles
56
56
  alongside `tokens.css`. Adopt is the only action that changes what your site
57
- ships, so try any look you like first. The editor itself never reaches
57
+ ships, so try any theme you like first. The editor itself never reaches
58
58
  production.
59
59
 
60
60
  Already have a Svelte 5 + Vite app? The
@@ -22,7 +22,7 @@ separately wobbled boxes.
22
22
 
23
23
  ## The sketchstyles
24
24
 
25
- Seven looks ship with the package, and each is a complete set of dials rather
25
+ Seven sketchstyles ship with the package, and each is a complete set of dials rather
26
26
  than just a name:
27
27
 
28
28
  - **Pencil.** Two graphite passes on their own seeds, so the outline disagrees
@@ -38,8 +38,8 @@ than just a name:
38
38
  - **Napkin.** Ballpoint in a hurry. Everything loose at once.
39
39
  - **Dry marker.** Ink that ran out. One scratchy pass over a mostly eaten fill.
40
40
 
41
- All seven ship as files, one per look, under
42
- `src/live-tokens/data/sketch-styles/` in the package. There is no look that
41
+ All seven ship as files, one per sketchstyle, under
42
+ `src/live-tokens/data/sketch-styles/` in the package. There is no sketchstyle that
43
43
  exists only as code, so every one of them can be read, copied and edited.
44
44
 
45
45
  Pick one, then move whatever you like. **Save As** keeps your dials under a name
@@ -51,6 +51,11 @@ project's own copy under the same name, which takes its place in the list;
51
51
  delete that copy and the shipped file behind it comes back. Both are a
52
52
  different gesture from saving a theme; see "Where the settings live" below.
53
53
 
54
+ A theme carries its sketch settings by value, so it can hold a set that belongs
55
+ to no file. The list shows that set as **Unsaved**. It owns no file, so there is
56
+ nothing for Save to write over; **Save As** turns it into a sketchstyle like any
57
+ other, which you can then save over and delete.
58
+
54
59
  Your sketchstyles and the shipped ones are one list. A sketchstyle named after
55
60
  a shipped one replaces it, keeping its place in the list, so a project that
56
61
  wants its own Pencil saves one and every picker shows that one instead.
@@ -97,9 +102,9 @@ is disabled there; use **Save As** to fold the dials into a theme of your
97
102
  own.
98
103
 
99
104
  **Save** and **Save As** in the **Sketchstyle** view are a different gesture.
100
- They write a named sketchstyle to `src/live-tokens/data/sketch-styles/`, a look
105
+ They write a named sketchstyle to `src/live-tokens/data/sketch-styles/`, a sketchstyle
101
106
  you can pick from any theme. Neither touches the open theme, and neither marks
102
- the look off the theme.
107
+ the theme as changed.
103
108
 
104
109
  ## Shipping the layer
105
110
 
@@ -110,11 +115,11 @@ has no server to ask, so it hands the field over itself:
110
115
  import { seedSketchFromTheme } from '@motion-proto/live-tokens/sketch';
111
116
  import theme from './live-tokens/data/themes/sketchy.json';
112
117
 
113
- seedSketchFromTheme(theme.sketchStyle);
118
+ seedSketchFromTheme(theme.sketchSettings);
114
119
  await bootLiveTokens(App, '#app');
115
120
  ```
116
121
 
117
- Call it before mounting, so the look is up on the first frame. Pass the field
122
+ Call it before mounting, so the sketch layer is up on the first frame. Pass the field
118
123
  raw. A theme written against older dial names is carried forward on the way in,
119
124
  the same reconciliation the dev server runs on every theme it reads.
120
125
 
@@ -122,7 +127,7 @@ Nothing is baked. `tokens.generated.css` still holds token values only, and the
122
127
  layer stays JavaScript the page runs, because it builds an SVG filter bank
123
128
  rather than a set of custom properties.
124
129
 
125
- A visitor who has picked a look of their own keeps it, None included. The theme
130
+ A visitor who has picked a sketchstyle of their own keeps it, None included. The theme
126
131
  seeds a browser that has decided nothing and never overwrites one that has, so
127
132
  calling this on every boot is safe.
128
133
 
@@ -138,26 +143,26 @@ const files = import.meta.glob<{ name?: string; settings: unknown }>(
138
143
  );
139
144
 
140
145
  await bootLiveTokens(App, '#app', {
141
- sketchLooks: Object.entries(files).map(([path, file]) => {
146
+ sketchStyles: Object.entries(files).map(([path, file]) => {
142
147
  const id = path.split('/').pop()!.replace('.json', '');
143
148
  return { id, label: file.name || id, settings: file.settings };
144
149
  }),
145
150
  });
146
151
  ```
147
152
 
148
- Projects made with `create` ship this already. The file's slug is the look's
153
+ Projects made with `create` ship this already. The file's slug is the sketchstyle's
149
154
  id, so a sketchstyle picked in the editor keeps working once the site is built.
150
155
 
151
156
  ### Building a picker
152
157
 
153
- `sketchLooks` is every look on offer, shipped and your own, as a store. Give
154
- each row `setSketch(look.id)`, and add your own **None** row: off is a state of
155
- the effect rather than one of the looks.
158
+ `sketchStyles` is every sketchstyle on offer, shipped and your own, as a store. Give
159
+ each row `setSketch(style.id)`, and add your own **None** row: off is a state of
160
+ the effect rather than one of the sketchstyles.
156
161
 
157
- `themeSketchLook` is the theme's own look as one more row. It is null when the
158
- theme carries none, and null when what it carries is a look already in
159
- `sketchLooks`, since that row names it. Its id goes to `setSketch` like any
160
- other, so a visitor who wanders off the theme's look can come back to it.
162
+ `unsavedSketchStyle` is the settings the theme carries as one more row. It is null when the
163
+ theme carries none, and null when what it carries matches a sketchstyle already in
164
+ `sketchStyles`, since that row names it. Its id goes to `setSketch` like any
165
+ other, so a visitor who wanders off the theme's own settings can come back to it.
161
166
 
162
167
  ## Drawing your own elements
163
168
 
@@ -1,12 +1,12 @@
1
1
  # Themes
2
2
 
3
- Save your work, switch between looks, and ship one to production.
3
+ Save your work, switch between themes, and ship one to production.
4
4
 
5
5
  ## The Theme panel
6
6
 
7
- The **Theme** panel at the foot of the editor sidebar holds the whole look:
7
+ The **Theme** panel at the foot of the editor sidebar holds the whole theme:
8
8
  colors, type, a setting for every component, and the sketch layer, in one
9
- file. It carries the name the look ships under, whether production is running
9
+ file. It carries the name the theme ships under, whether production is running
10
10
  it, and **Adopt**. Three parts sit under it, each a read-out rather than a
11
11
  file to manage.
12
12
 
@@ -14,7 +14,7 @@ file to manage.
14
14
  define their appearance. It names the two faces the page is showing.
15
15
  - **Components** counts how many components have an unsaved edit that has not
16
16
  been saved into the theme, and opens the component editors.
17
- - **Sketchstyle** names the look the theme's sketch layer carries: its label, or
17
+ - **Sketchstyle** names the sketchstyle the theme's sketch layer carries: its label, or
18
18
  off the theme when what's on screen no longer matches what was saved, or
19
19
  none when the theme carries no sketch layer. It travels with the theme
20
20
  like colors and type do, but never reaches a production build.
@@ -26,7 +26,7 @@ A theme holds its own copy of every part, so one theme can never break another.
26
26
  A theme is a document, and the editor works the way any editor does.
27
27
 
28
28
  - **A theme** is a named JSON file in `src/live-tokens/data/themes/`. It carries
29
- the whole look: the colors and type, a setting for every component, and the
29
+ the whole theme: the colors and type, a setting for every component, and the
30
30
  sketch layer.
31
31
  - **The open theme** is the one the editor is working on, named in
32
32
  `themes/_active.json`. One at a time.
@@ -40,11 +40,11 @@ A theme is a document, and the editor works the way any editor does.
40
40
  Picker performs that Adopt for you.
41
41
 
42
42
  Absence is the answer for anything untouched: a buffer exists only where the
43
- live look diverges from the active theme, so a newly opened theme has none.
43
+ live theme diverges from the active theme, so a newly opened theme has none.
44
44
 
45
45
  ## Fonts
46
46
 
47
- Type is part of the look, so it saves, loads and ships with the theme rather
47
+ Type is part of the theme, so it saves, loads and ships with the theme rather
48
48
  than on its own. Four named stacks carry it:
49
49
 
50
50
  | Stack | Used by |
@@ -85,7 +85,7 @@ what writes the font imports your site ships, into `fonts.css`.
85
85
 
86
86
  In the Theme panel:
87
87
 
88
- - **Save** captures the look on screen into the open theme. Your colors and type
88
+ - **Save** captures the theme on screen into the open theme. Your colors and type
89
89
  go in as part of it, so there is nothing to save first.
90
90
  - **Save As** names a new theme. Use it for your first save and for forking.
91
91
 
@@ -104,7 +104,7 @@ to it, and the editor never overwrites it, so start your own with **Save As**.
104
104
 
105
105
  **Load**—or clicking the active theme's name—opens the Theme Picker. Picking a
106
106
  theme shows it on the page as a preview with nothing written to disk, sketch
107
- layer included, so you can try each look and compare. **Save** in that window
107
+ layer included, so you can try each theme and compare. **Save** in that window
108
108
  opens and adopts the previewed theme in one step: the active pointer changes,
109
109
  the buffers clear, the editor works on it, and production ships it. **Cancel**
110
110
  returns you to where you were, unsaved sketch dials included. Previewing alone
@@ -125,10 +125,10 @@ then bakes the colors and type plus every component the theme carries into
125
125
  it stays a preview. Fonts regenerate to match. The line under the theme name
126
126
  says whether production is running this theme.
127
127
 
128
- Production is one saved theme, so nothing else publishes. Trying a look, moving
128
+ Production is one saved theme, so nothing else publishes. Trying a theme, moving
129
129
  a token, saving a theme: all of it leaves the generated CSS alone until you
130
130
  Adopt. A component editor's Adopt runs the same save-then-bake step, because a
131
- component never ships alone. Adopting while Motion Proto is open saves your look
131
+ component never ships alone. Adopting while Motion Proto is open saves your theme
132
132
  as a theme of your own first, since the built-in one is read-only.
133
133
 
134
134
  Production builds (`npm run build`) ship only that plain CSS and your
@@ -11,8 +11,8 @@ src/live-tokens/data/
11
11
  themes/
12
12
  _active.json names the theme the editor has open
13
13
  _production.json names the theme your site ships
14
- default.json Motion Proto, the built-in look, rewritten at boot
15
- my-brand.json a saved theme: the whole look in one file
14
+ default.json Motion Proto, the built-in theme, rewritten at boot
15
+ my-brand.json a saved theme: the whole theme in one file
16
16
  colors-and-type/
17
17
  _working.json unsaved colors and type edits
18
18
  component-configs/
@@ -21,14 +21,14 @@ src/live-tokens/data/
21
21
  _working.json unsaved Button edits
22
22
  my-button.json a preset you saved from the Button editor
23
23
  sketch-styles/
24
- my-look.json a sketchstyle saved from the Sketchstyle view
24
+ my-style.json a sketchstyle saved from the Sketchstyle view
25
25
  tokens.generated.css the baked CSS your production build ships
26
26
  src/system/styles/
27
27
  tokens.css your token vocabulary, hand-authored, never written
28
28
  fonts.css font imports, rewritten when you Adopt
29
29
  ```
30
30
 
31
- A saved theme carries the whole look by value: the colors and type, a
31
+ A saved theme carries everything by value: the colors and type, a
32
32
  setting for every component, and the sketch layer. It depends on no other
33
33
  file, so deleting anything else never breaks it.
34
34
 
@@ -40,11 +40,11 @@ file, so deleting anything else never breaks it.
40
40
  components, **Save all** writes those buffers together.
41
41
  - **Save** captures the buffers into the open theme's file, along with the
42
42
  sketch layer, which has no buffer of its own and lives only in the browser
43
- until Save writes it. That file is the durable copy of your look; matching
43
+ until Save writes it. That file is the durable copy of your theme; matching
44
44
  buffers are then removed.
45
45
  - **Load** clears the buffers and points `themes/_active.json` at the theme you
46
46
  picked. Live reads fall through to that file. Nothing else changes, so trying
47
- looks is free and ordinary switching changes only the pointer.
47
+ themes is free and ordinary switching changes only the pointer.
48
48
  - **Adopt** points `themes/_production.json` at the open theme, bakes it into
49
49
  `tokens.generated.css`, and rewrites `fonts.css` to match. It is the only
50
50
  action that changes what your site ships.