@motion-proto/live-tokens 0.65.1 → 0.67.0

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 (39) hide show
  1. package/CHANGELOG.md +184 -0
  2. package/dist-plugin/{chunk-NDJJORKJ.js → chunk-T4PMCFJN.js} +220 -114
  3. package/dist-plugin/index.cjs +253 -129
  4. package/dist-plugin/index.js +27 -9
  5. package/dist-plugin/migrateData/index.cjs +220 -114
  6. package/dist-plugin/migrateData/index.js +1 -1
  7. package/package.json +8 -1
  8. package/src/editor/bootstrap.ts +12 -0
  9. package/src/editor/core/productionPulse.ts +1 -1
  10. package/src/editor/core/sketch/index.ts +78 -21
  11. package/src/editor/core/sketch/maskField.ts +200 -62
  12. package/src/editor/core/sketch/sketchLayer.ts +10 -4
  13. package/src/editor/core/sketch/sketchRegistry.ts +98 -0
  14. package/src/editor/core/sketch/sketchStore.ts +110 -31
  15. package/src/editor/core/sketch/sketchStyleService.ts +3 -0
  16. package/src/editor/core/sketch/sketchStyles.ts +63 -96
  17. package/src/editor/core/themes/themeInit.ts +4 -13
  18. package/src/editor/docs/content/sketch-mode.md +82 -13
  19. package/src/editor/docs/content.generated.ts +1 -1
  20. package/src/editor/ui/sketch/SketchTab.svelte +219 -74
  21. package/src/live-tokens/data/sketch-styles/dashed.json +47 -0
  22. package/src/live-tokens/data/sketch-styles/dry.json +47 -0
  23. package/src/live-tokens/data/sketch-styles/hatched.json +47 -0
  24. package/src/live-tokens/data/sketch-styles/marker.json +47 -0
  25. package/src/live-tokens/data/sketch-styles/napkin.json +47 -0
  26. package/src/live-tokens/data/sketch-styles/pencil.json +47 -0
  27. package/src/live-tokens/data/sketch-styles/whiteboard.json +47 -0
  28. package/src/live-tokens/data/themes/autumn.json +4 -4
  29. package/src/live-tokens/data/themes/halloween.json +4 -4
  30. package/src/live-tokens/data/themes/midnight-study.json +4 -4
  31. package/src/live-tokens/data/themes/ocean.json +4 -4
  32. package/src/live-tokens/data/themes/royal-velvet.json +4 -4
  33. package/src/live-tokens/data/themes/sketchy.json +4 -4
  34. package/src/live-tokens/data/themes/spring-meadow.json +4 -4
  35. package/src/live-tokens/data/themes/sunset.json +4 -4
  36. package/src/system/components/Button.svelte +2 -2
  37. package/src/system/components/IconButton.svelte +2 -2
  38. package/src/system/styles/fonts.css +6 -6
  39. package/template/src/main.ts +14 -1
@@ -268,65 +268,38 @@ var KNOWN_COMPONENT_CONFIG_KEYS = /* @__PURE__ */ new Set([
268
268
  "--sectiondivider-sm-color-family"
269
269
  ]);
270
270
 
271
- // src/editor/core/sketch/sketchStyles.ts
272
- var base = {
273
- label: "",
274
- blurb: "",
275
- fillTravel: 1.5,
276
- strokeTravel: 1.5,
277
- wobble: 45,
278
- roughness: 3,
279
- borderWavelength: 1,
280
- waveform: 1,
281
- strokeWidth: 1.5,
282
- doubleStroke: false,
283
- retraceOffset: 1.2,
284
- retracePass: "copy",
285
- fillStyle: "solid",
286
- hatchInk: 0.4,
287
- strokeStyle: "solid",
288
- pressure: 0.25,
289
- pressureMod: 0.35,
290
- pooling: 1.2,
291
- strokeInk: 1,
292
- maskOn: true,
293
- maskBlob: 100,
294
- maskOutputMin: 0.45,
295
- maskOutputMax: 1,
296
- maskOctaves: 2,
297
- maskGrain: "fractal",
298
- maskPosterize: 1,
299
- maskSoftness: 1.5,
300
- jitterX: 2.5,
301
- jitterY: 2.5,
302
- jitterRot: 0.6,
303
- jitterScale: 0.035,
304
- cornerSpread: 10,
305
- cornerTravel: 8,
306
- iconTravel: 1.25,
307
- iconWavelength: 0.625,
308
- iconMaskOn: true,
309
- iconMaskScale: 1
310
- };
311
- var SKETCH_STYLES = {
312
- pencil: {
313
- ...base,
271
+ // src/live-tokens/data/sketch-styles/pencil.json
272
+ var pencil_default = {
273
+ name: "Pencil",
274
+ settings: {
314
275
  label: "Pencil",
315
276
  blurb: "Two graphite passes on their own seeds, so the outline disagrees with itself the way a hand coming back round does. Tight grain, little else.",
316
277
  fillTravel: 0.75,
317
278
  strokeTravel: 1.25,
318
279
  wobble: 30,
319
280
  roughness: 3,
281
+ borderWavelength: 1,
320
282
  waveform: 1,
321
283
  strokeWidth: 1.25,
322
284
  doubleStroke: true,
323
- retracePass: "reseeded",
324
285
  retraceOffset: 1.5,
286
+ retracePass: "reseeded",
287
+ fillStyle: "solid",
288
+ hatchInk: 0.4,
289
+ strokeStyle: "solid",
290
+ pressure: 0.15,
291
+ pressureMod: 0.3,
292
+ pooling: 0,
325
293
  strokeInk: 0.85,
326
- maskBlob: 40,
327
- maskOutputMin: 0.62,
294
+ maskOn: true,
295
+ maskBlobX: 525,
296
+ maskBlobY: 47,
297
+ maskBlobLinked: false,
298
+ maskAngle: 67,
299
+ maskOutputMin: 0.59,
328
300
  maskOutputMax: 1,
329
301
  maskOctaves: 3,
302
+ maskGrain: "turbulence",
330
303
  maskPosterize: 1,
331
304
  maskSoftness: 0,
332
305
  jitterX: 1.5,
@@ -335,147 +308,243 @@ var SKETCH_STYLES = {
335
308
  jitterScale: 0.022,
336
309
  cornerSpread: 6,
337
310
  cornerTravel: 4.5,
338
- pressure: 0.15,
339
- pressureMod: 0.3,
340
- pooling: 0,
341
- iconTravel: 0.75
311
+ iconTravel: 0.75,
312
+ iconWavelength: 0.625,
313
+ iconMaskOn: true,
314
+ iconMaskScale: 1
342
315
  },
343
- marker: {
344
- ...base,
316
+ updatedAt: "2026-08-28T14:35:06.291Z",
317
+ createdAt: "2026-08-28T14:35:06.291Z"
318
+ };
319
+
320
+ // src/live-tokens/data/sketch-styles/marker.json
321
+ var marker_default = {
322
+ name: "Marker",
323
+ settings: {
345
324
  label: "Marker",
346
325
  blurb: "Broad translucent nib gone round twice on the same line, so the overlap darkens and the ink pools where it slows.",
347
326
  fillTravel: 2,
348
327
  strokeTravel: 1.5,
349
328
  wobble: 56,
350
- waveform: 1.4,
329
+ roughness: 3,
351
330
  borderWavelength: 1.3,
331
+ waveform: 1.4,
352
332
  strokeWidth: 4,
353
333
  doubleStroke: true,
334
+ retraceOffset: 2.2,
354
335
  retracePass: "copy",
336
+ fillStyle: "solid",
337
+ hatchInk: 0.4,
338
+ strokeStyle: "solid",
339
+ pressure: 0.2,
340
+ pressureMod: 0.25,
341
+ pooling: 2,
355
342
  strokeInk: 0.52,
356
- retraceOffset: 2.2,
357
- maskBlob: 115,
358
- maskOutputMin: 0.42,
343
+ maskOn: true,
344
+ maskBlobX: 230,
345
+ maskBlobY: 230,
346
+ maskBlobLinked: true,
347
+ maskAngle: 0,
348
+ maskOutputMin: 0.76,
359
349
  maskOutputMax: 1,
360
350
  maskOctaves: 3,
351
+ maskGrain: "fractal",
361
352
  maskPosterize: 4,
362
- maskSoftness: 4,
353
+ maskSoftness: 0,
363
354
  jitterX: 3,
364
355
  jitterY: 3,
365
356
  jitterRot: 0.8,
366
357
  jitterScale: 0.045,
367
358
  cornerSpread: 10,
368
359
  cornerTravel: 8,
369
- pressure: 0.2,
370
- pressureMod: 0.25,
371
- pooling: 2,
372
360
  iconTravel: 1.25,
361
+ iconWavelength: 0.625,
362
+ iconMaskOn: true,
373
363
  iconMaskScale: 4
374
364
  },
375
- whiteboard: {
376
- ...base,
365
+ updatedAt: "2026-08-28T14:45:04.324Z",
366
+ createdAt: "2026-08-28T14:45:04.324Z"
367
+ };
368
+
369
+ // src/live-tokens/data/sketch-styles/whiteboard.json
370
+ var whiteboard_default = {
371
+ name: "Whiteboard",
372
+ settings: {
377
373
  label: "Whiteboard",
378
374
  blurb: "The fattest nib on glass. One long smooth undulation, and a veined mask that streaks the fill like a half-wiped board.",
379
375
  fillTravel: 2.5,
380
376
  strokeTravel: 2.5,
381
377
  wobble: 90,
382
378
  roughness: 1,
383
- waveform: 1,
384
379
  borderWavelength: 1.5,
380
+ waveform: 1,
385
381
  strokeWidth: 5.5,
386
382
  doubleStroke: true,
383
+ retraceOffset: 3,
387
384
  retracePass: "copy",
385
+ fillStyle: "solid",
386
+ hatchInk: 0.4,
387
+ strokeStyle: "solid",
388
+ pressure: 0.15,
389
+ pressureMod: 0.15,
390
+ pooling: 3.5,
388
391
  strokeInk: 0.66,
389
- retraceOffset: 3,
390
- maskGrain: "turbulence",
391
- maskBlob: 180,
392
- maskOutputMin: 0.42,
392
+ maskOn: true,
393
+ maskBlobX: 180,
394
+ maskBlobY: 38,
395
+ maskBlobLinked: false,
396
+ maskAngle: 0,
397
+ maskOutputMin: 0.68,
393
398
  maskOutputMax: 1,
394
- maskOctaves: 1,
399
+ maskOctaves: 3,
400
+ maskGrain: "turbulence",
395
401
  maskPosterize: 3,
396
- maskSoftness: 8,
402
+ maskSoftness: 0,
397
403
  jitterX: 4.5,
398
404
  jitterY: 4.5,
399
- jitterRot: 1.2,
405
+ jitterRot: 3,
400
406
  jitterScale: 0.07,
401
407
  cornerSpread: 14,
402
408
  cornerTravel: 11,
403
- pressure: 0.15,
404
- pressureMod: 0.15,
405
- pooling: 3.5,
406
409
  iconTravel: 1.75,
410
+ iconWavelength: 0.625,
411
+ iconMaskOn: true,
407
412
  iconMaskScale: 1.5
408
413
  },
409
- hatched: {
410
- ...base,
414
+ updatedAt: "2026-08-28T14:46:58.140Z",
415
+ createdAt: "2026-08-28T14:46:58.140Z"
416
+ };
417
+
418
+ // src/live-tokens/data/sketch-styles/hatched.json
419
+ var hatched_default = {
420
+ name: "Hatched",
421
+ settings: {
411
422
  label: "Hatched",
412
423
  blurb: "An etching. The fill is angled shading, the outline a single hard-edged scratch that chatters along its length. No mask: the hatch is the texture.",
413
424
  fillTravel: 1.25,
414
425
  strokeTravel: 1.5,
415
426
  wobble: 24,
416
427
  roughness: 3,
428
+ borderWavelength: 1,
417
429
  waveform: 3,
418
430
  strokeWidth: 1.5,
431
+ doubleStroke: false,
432
+ retraceOffset: 1.2,
433
+ retracePass: "copy",
419
434
  fillStyle: "hatched",
420
435
  hatchInk: 0.5,
421
- doubleStroke: false,
436
+ strokeStyle: "solid",
437
+ pressure: 0.3,
438
+ pressureMod: 0.45,
439
+ pooling: 0.8,
440
+ strokeInk: 1,
422
441
  maskOn: false,
423
- iconMaskOn: false,
442
+ maskBlobX: 100,
443
+ maskBlobY: 100,
444
+ maskBlobLinked: true,
445
+ maskAngle: 0,
446
+ maskOutputMin: 0.45,
447
+ maskOutputMax: 1,
448
+ maskOctaves: 2,
449
+ maskGrain: "fractal",
450
+ maskPosterize: 1,
451
+ maskSoftness: 1.5,
424
452
  jitterX: 1.5,
425
453
  jitterY: 1.5,
426
454
  jitterRot: 0.4,
427
455
  jitterScale: 0.03,
428
456
  cornerSpread: 6,
429
457
  cornerTravel: 6,
430
- pressure: 0.3,
431
- pressureMod: 0.45,
432
- pooling: 0.8,
433
458
  iconTravel: 1.25,
434
- iconWavelength: 0.5
459
+ iconWavelength: 0.5,
460
+ iconMaskOn: false,
461
+ iconMaskScale: 1
435
462
  },
436
- dashed: {
437
- ...base,
463
+ updatedAt: "2026-08-28T15:47:36.934Z",
464
+ createdAt: "2026-08-28T15:47:36.934Z"
465
+ };
466
+
467
+ // src/live-tokens/data/sketch-styles/dashed.json
468
+ var dashed_default = {
469
+ name: "Dashed",
470
+ settings: {
438
471
  label: "Dashed",
439
472
  blurb: "A drafting outline. One slow drift along the ruler, broken into strokes, with jitter, mask and pressure all off. The clean pole.",
440
- strokeStyle: "dashed",
441
- strokeTravel: 1,
442
473
  fillTravel: 0.5,
474
+ strokeTravel: 1,
443
475
  wobble: 120,
444
476
  roughness: 1,
477
+ borderWavelength: 1,
445
478
  waveform: 1,
446
479
  strokeWidth: 1.5,
447
480
  doubleStroke: false,
481
+ retraceOffset: 1.2,
482
+ retracePass: "copy",
483
+ fillStyle: "solid",
484
+ hatchInk: 0.4,
485
+ strokeStyle: "dashed",
486
+ pressure: 0,
487
+ pressureMod: 0,
488
+ pooling: 0,
489
+ strokeInk: 1,
448
490
  maskOn: false,
449
- iconMaskOn: false,
491
+ maskBlobX: 100,
492
+ maskBlobY: 100,
493
+ maskBlobLinked: true,
494
+ maskAngle: 0,
495
+ maskOutputMin: 0.45,
496
+ maskOutputMax: 1,
497
+ maskOctaves: 2,
498
+ maskGrain: "fractal",
499
+ maskPosterize: 1,
500
+ maskSoftness: 1.5,
450
501
  jitterX: 0,
451
502
  jitterY: 0,
452
503
  jitterRot: 0,
453
504
  jitterScale: 0,
454
505
  cornerSpread: 4,
455
506
  cornerTravel: 3,
456
- pressure: 0,
457
- pressureMod: 0,
458
- pooling: 0,
459
- iconTravel: 0
507
+ iconTravel: 0,
508
+ iconWavelength: 0.625,
509
+ iconMaskOn: false,
510
+ iconMaskScale: 1
460
511
  },
461
- napkin: {
462
- ...base,
512
+ updatedAt: "2026-08-28T15:47:36.934Z",
513
+ createdAt: "2026-08-28T15:47:36.934Z"
514
+ };
515
+
516
+ // src/live-tokens/data/sketch-styles/napkin.json
517
+ var napkin_default = {
518
+ name: "Napkin",
519
+ settings: {
463
520
  label: "Napkin",
464
521
  blurb: "Ballpoint in a hurry. Everything loose at once: a square wave sends every edge to full travel, and the second pass lands wherever it lands.",
465
522
  fillTravel: 3,
466
523
  strokeTravel: 2.25,
467
524
  wobble: 50,
468
525
  roughness: 3,
526
+ borderWavelength: 1,
469
527
  waveform: 2.5,
470
528
  strokeWidth: 2.25,
471
529
  doubleStroke: true,
472
- retracePass: "reseeded",
473
530
  retraceOffset: 4,
531
+ retracePass: "reseeded",
532
+ fillStyle: "solid",
533
+ hatchInk: 0.4,
534
+ strokeStyle: "solid",
535
+ pressure: 0.45,
536
+ pressureMod: 0.6,
537
+ pooling: 2.5,
474
538
  strokeInk: 1,
475
- maskBlob: 150,
539
+ maskOn: true,
540
+ maskBlobX: 150,
541
+ maskBlobY: 150,
542
+ maskBlobLinked: true,
543
+ maskAngle: 0,
476
544
  maskOutputMin: 0.43,
477
545
  maskOutputMax: 0.95,
478
546
  maskOctaves: 2,
547
+ maskGrain: "fractal",
479
548
  maskPosterize: 2,
480
549
  maskSoftness: 10,
481
550
  jitterX: 6,
@@ -484,28 +553,47 @@ var SKETCH_STYLES = {
484
553
  jitterScale: 0.1,
485
554
  cornerSpread: 20,
486
555
  cornerTravel: 17,
487
- pressure: 0.45,
488
- pressureMod: 0.6,
489
- pooling: 2.5,
490
556
  iconTravel: 2.25,
557
+ iconWavelength: 0.625,
558
+ iconMaskOn: true,
491
559
  iconMaskScale: 3.6
492
560
  },
493
- dry: {
494
- ...base,
561
+ updatedAt: "2026-08-28T15:47:36.934Z",
562
+ createdAt: "2026-08-28T15:47:36.934Z"
563
+ };
564
+
565
+ // src/live-tokens/data/sketch-styles/dry.json
566
+ var dry_default = {
567
+ name: "Dry marker",
568
+ settings: {
495
569
  label: "Dry marker",
496
570
  blurb: "Ink that ran out. One scratchy pass that breaks up along its length, over a fill the mask has worn nearly through in patches.",
497
571
  fillTravel: 2.25,
498
572
  strokeTravel: 1.75,
499
573
  wobble: 50,
500
- waveform: 2,
574
+ roughness: 3,
501
575
  borderWavelength: 0.5,
576
+ waveform: 2,
502
577
  strokeWidth: 3.5,
503
578
  doubleStroke: false,
579
+ retraceOffset: 1.2,
580
+ retracePass: "copy",
581
+ fillStyle: "solid",
582
+ hatchInk: 0.4,
583
+ strokeStyle: "solid",
584
+ pressure: 0.4,
585
+ pressureMod: 0.8,
586
+ pooling: 1.5,
504
587
  strokeInk: 0.4,
505
- maskBlob: 150,
588
+ maskOn: true,
589
+ maskBlobX: 150,
590
+ maskBlobY: 150,
591
+ maskBlobLinked: true,
592
+ maskAngle: 0,
506
593
  maskOutputMin: 0.24,
507
594
  maskOutputMax: 0.91,
508
595
  maskOctaves: 2,
596
+ maskGrain: "fractal",
509
597
  maskPosterize: 4,
510
598
  maskSoftness: 1.75,
511
599
  jitterX: 5,
@@ -514,26 +602,34 @@ var SKETCH_STYLES = {
514
602
  jitterScale: 0.08,
515
603
  cornerSpread: 16,
516
604
  cornerTravel: 13,
517
- pressure: 0.4,
518
- pressureMod: 0.8,
519
- pooling: 1.5,
520
605
  iconTravel: 1.75,
606
+ iconWavelength: 0.625,
607
+ iconMaskOn: true,
521
608
  iconMaskScale: 3.8
522
- }
609
+ },
610
+ updatedAt: "2026-08-28T15:47:36.934Z",
611
+ createdAt: "2026-08-28T15:47:36.934Z"
523
612
  };
613
+
614
+ // src/editor/core/sketch/sketchStyles.ts
615
+ var SHIPPED_FILES = { pencil: pencil_default, marker: marker_default, whiteboard: whiteboard_default, hatched: hatched_default, dashed: dashed_default, napkin: napkin_default, dry: dry_default };
616
+ var SKETCH_STYLES = Object.fromEntries(
617
+ Object.entries(SHIPPED_FILES).map(([id, file]) => [id, file.settings])
618
+ );
524
619
  var DEFAULT_SKETCH_STYLE = "marker";
525
620
  function hydrateSketchStyle(raw) {
526
- const base2 = SKETCH_STYLES[DEFAULT_SKETCH_STYLE];
621
+ const base = SKETCH_STYLES[DEFAULT_SKETCH_STYLE];
527
622
  const stored = raw ?? {};
528
- const out = { ...base2 };
529
- for (const key of Object.keys(base2)) {
623
+ const out = { ...base };
624
+ for (const key of Object.keys(base)) {
530
625
  if (stored[key] !== void 0) out[key] = stored[key];
531
626
  }
532
- if (out.fillStyle === "none") out.fillStyle = base2.fillStyle;
627
+ if (out.fillStyle === "none") out.fillStyle = base.fillStyle;
533
628
  convertTiledMask(stored, out);
534
629
  convertCutToLevels(stored, out);
535
630
  carryLevelsToOutput(stored, out);
536
631
  halveSwingDials(stored, out);
632
+ splitBlobAxes(stored, out);
537
633
  convertCyclesToWavelength(stored, out);
538
634
  convertIconTileToScale(stored, out);
539
635
  restoreDerivedRetrace(stored, out);
@@ -565,6 +661,13 @@ function convertCyclesToWavelength(stored, out) {
565
661
  const layers = stored.octaves;
566
662
  if (typeof layers === "number") out.roughness = Math.min(3, Math.max(1, layers));
567
663
  }
664
+ function splitBlobAxes(stored, out) {
665
+ const blob = stored.maskBlob;
666
+ if (typeof blob !== "number") return;
667
+ out.maskBlobX = blob;
668
+ out.maskBlobY = blob;
669
+ out.maskBlobLinked = true;
670
+ }
568
671
  function convertIconTileToScale(stored, out) {
569
672
  const tile = stored.iconMaskTile;
570
673
  if (typeof tile !== "number") return;
@@ -580,7 +683,10 @@ function convertTiledMask(stored, out) {
580
683
  const scale = stored.maskScale;
581
684
  if (typeof scale !== "number") return;
582
685
  const freq = stored.maskFrequency;
583
- if (typeof freq === "number") out.maskBlob = Math.round(scale / (freq * LEGACY_TILE));
686
+ if (typeof freq === "number") {
687
+ out.maskBlobX = Math.round(scale / (freq * LEGACY_TILE));
688
+ out.maskBlobY = out.maskBlobX;
689
+ }
584
690
  const soft = stored.maskSoftness;
585
691
  if (typeof soft === "number") out.maskSoftness = Number((soft * scale / LEGACY_TILE).toFixed(1));
586
692
  }
@@ -693,12 +799,12 @@ function normalizeTheme(raw, resolvers) {
693
799
  }
694
800
  const filled = { components: [], aliases: 0, orphans: 0 };
695
801
  for (const comp of resolvers.listComponentNames()) {
696
- const base2 = asObject(resolvers.readComponentConfig(comp, "default"));
697
- const baseAliases = base2 ? asObject(base2.aliases) : null;
698
- if (!base2 || !baseAliases) continue;
802
+ const base = asObject(resolvers.readComponentConfig(comp, "default"));
803
+ const baseAliases = base ? asObject(base.aliases) : null;
804
+ if (!base || !baseAliases) continue;
699
805
  const entry = componentConfigs[comp];
700
806
  if (!entry) {
701
- const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(base2);
807
+ const { schemaVersion: _standaloneStamp, ...rest } = stripFileMarker(base);
702
808
  componentConfigs[comp] = structuredClone(rest);
703
809
  filled.components.push(comp);
704
810
  continue;