@dfosco/storyboard-core 3.6.0 → 3.7.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 (50) hide show
  1. package/dist/storyboard-ui.css +1 -1
  2. package/dist/storyboard-ui.js +12274 -11387
  3. package/dist/storyboard-ui.js.map +1 -1
  4. package/dist/tailwind.css +1 -1
  5. package/package.json +1 -1
  6. package/src/CanvasZoomControl.svelte +8 -8
  7. package/src/CommentsMenuButton.svelte +7 -21
  8. package/src/CoreUIBar.svelte +19 -3
  9. package/src/CreateMenuButton.svelte +8 -12
  10. package/src/InspectorPanel.svelte +12 -15
  11. package/src/SidePanel.svelte +14 -14
  12. package/src/assets/fonts/IoskeleyMono-Bold.woff2 +0 -0
  13. package/src/assets/fonts/IoskeleyMono-Italic.woff2 +0 -0
  14. package/src/assets/fonts/IoskeleyMono-Medium.woff2 +0 -0
  15. package/src/assets/fonts/IoskeleyMono-Regular.woff2 +0 -0
  16. package/src/assets/fonts/IoskeleyMono-SemiBold.woff2 +0 -0
  17. package/src/comments/ui/AuthModal.svelte +45 -12
  18. package/src/comments/ui/authModal.js +6 -1
  19. package/src/comments/ui/comment-layout.css +15 -15
  20. package/src/comments/ui/commentWindow.js +6 -1
  21. package/src/comments/ui/comments.css +57 -57
  22. package/src/comments/ui/commentsDrawer.js +2 -0
  23. package/src/comments/ui/composer.js +7 -2
  24. package/src/comments/ui/mount.js +252 -33
  25. package/src/comments/ui/mount.test.js +138 -0
  26. package/src/core-ui-colors.css +28 -28
  27. package/src/inspector/mouseMode.js +2 -2
  28. package/src/lib/components/ui/button/button.svelte +9 -9
  29. package/src/lib/components/ui/panel/panel-content.svelte +2 -2
  30. package/src/lib/components/ui/select/select-trigger.svelte +1 -1
  31. package/src/lib/components/ui/toggle/toggle.svelte +1 -1
  32. package/src/lib/components/ui/toggle-group/toggle-group.svelte +2 -2
  33. package/src/lib/components/ui/trigger-button/trigger-button.svelte +13 -13
  34. package/src/modes.css +21 -21
  35. package/src/mountStoryboardCore.js +4 -4
  36. package/src/sidepanel.css +11 -11
  37. package/src/styles/tailwind.css +89 -1
  38. package/src/svelte-plugin-ui/components/ModeSwitch.svelte +3 -3
  39. package/src/svelte-plugin-ui/components/Viewfinder.svelte +31 -11
  40. package/src/svelte-plugin-ui/styles/base.css +41 -41
  41. package/src/workshop/features/createFlow/CreateFlowForm.svelte +187 -25
  42. package/src/workshop/features/createFlow/server.js +437 -40
  43. package/src/workshop/features/createPage/CreatePageForm.svelte +249 -0
  44. package/src/workshop/features/createPage/index.js +11 -0
  45. package/src/workshop/features/createPrototype/CreatePrototypeForm.svelte +77 -24
  46. package/src/workshop/features/createPrototype/server.js +14 -16
  47. package/src/workshop/features/registry-server.js +1 -0
  48. package/src/workshop/features/registry.js +2 -0
  49. package/src/workshop/features/templateIndex.js +155 -0
  50. package/toolbar.config.json +2 -1
@@ -25,20 +25,20 @@
25
25
  color-scheme: light;
26
26
 
27
27
  /* shadcn / Tailwind semantic tokens — pinned to light values */
28
- --color-background: hsl(0 0% 100%);
29
- --color-foreground: hsl(222.2 84% 4.9%);
30
- --color-popover: hsl(0 0% 100%);
31
- --color-popover-foreground: hsl(222.2 84% 4.9%);
32
- --color-primary: hsl(222.2 47.4% 11.2%);
33
- --color-primary-foreground: hsl(210 40% 98%);
34
- --color-secondary: hsl(210 40% 96.1%);
35
- --color-secondary-foreground: hsl(222.2 47.4% 11.2%);
36
- --color-muted: hsl(210 40% 96.1%);
37
- --color-muted-foreground: hsl(215.4 16.3% 46.9%);
38
- --color-accent: hsl(210 40% 96.1%);
39
- --color-accent-foreground: hsl(222.2 47.4% 11.2%);
40
- --color-border: hsl(214.3 31.8% 91.4%);
41
- --color-input: hsl(214.3 31.8% 91.4%);
28
+ --sb--color-background: hsl(0 0% 100%);
29
+ --sb--color-foreground: hsl(222.2 84% 4.9%);
30
+ --sb--color-popover: hsl(0 0% 100%);
31
+ --sb--color-popover-foreground: hsl(222.2 84% 4.9%);
32
+ --sb--color-primary: hsl(222.2 47.4% 11.2%);
33
+ --sb--color-primary-foreground: hsl(210 40% 98%);
34
+ --sb--color-secondary: hsl(210 40% 96.1%);
35
+ --sb--color-secondary-foreground: hsl(222.2 47.4% 11.2%);
36
+ --sb--color-muted: hsl(210 40% 96.1%);
37
+ --sb--color-muted-foreground: hsl(215.4 16.3% 46.9%);
38
+ --sb--color-accent: hsl(210 40% 96.1%);
39
+ --sb--color-accent-foreground: hsl(222.2 47.4% 11.2%);
40
+ --sb--color-border: hsl(214.3 31.8% 91.4%);
41
+ --sb--color-input: hsl(214.3 31.8% 91.4%);
42
42
  }
43
43
 
44
44
  /* Dark tokens — applied when toolbar syncs with a dark theme.
@@ -50,18 +50,18 @@
50
50
  :root[data-sb-toolbar-theme^="dark"] [data-slot="dropdown-menu-sub-content"] {
51
51
  color-scheme: dark;
52
52
 
53
- --color-background: #161b22;
54
- --color-foreground: #e6edf3;
55
- --color-popover: #161b22;
56
- --color-popover-foreground: #e6edf3;
57
- --color-primary: #e6edf3;
58
- --color-primary-foreground: #161b22;
59
- --color-secondary: #21262d;
60
- --color-secondary-foreground: #e6edf3;
61
- --color-muted: #21262d;
62
- --color-muted-foreground: #8b949e;
63
- --color-accent: #21262d;
64
- --color-accent-foreground: #e6edf3;
65
- --color-border: #30363d;
66
- --color-input: #30363d;
53
+ --sb--color-background: #161b22;
54
+ --sb--color-foreground: #e6edf3;
55
+ --sb--color-popover: #161b22;
56
+ --sb--color-popover-foreground: #e6edf3;
57
+ --sb--color-primary: #e6edf3;
58
+ --sb--color-primary-foreground: #161b22;
59
+ --sb--color-secondary: #21262d;
60
+ --sb--color-secondary-foreground: #e6edf3;
61
+ --sb--color-muted: #21262d;
62
+ --sb--color-muted-foreground: #8b949e;
63
+ --sb--color-accent: #21262d;
64
+ --sb--color-accent-foreground: #e6edf3;
65
+ --sb--color-border: #30363d;
66
+ --sb--color-input: #30363d;
67
67
  }
@@ -57,7 +57,7 @@ export function createMouseMode(options = {}) {
57
57
  position: 'fixed',
58
58
  pointerEvents: 'none',
59
59
  zIndex: '9997',
60
- border: '2px solid var(--color-purple, #7655a4)',
60
+ border: '2px solid var(--sb--color-purple, #7655a4)',
61
61
  backgroundColor: 'rgba(118, 85, 164, 0.08)',
62
62
  borderRadius: '3px',
63
63
  transition: 'top 0.06s ease, left 0.06s ease, width 0.06s ease, height 0.06s ease',
@@ -73,7 +73,7 @@ export function createMouseMode(options = {}) {
73
73
  position: 'fixed',
74
74
  pointerEvents: 'none',
75
75
  zIndex: '9997',
76
- backgroundColor: 'var(--color-purple, #7655a4)',
76
+ backgroundColor: 'var(--sb--color-purple, #7655a4)',
77
77
  color: '#fff',
78
78
  fontSize: '11px',
79
79
  fontFamily: '"Ioskeley Mono", ui-monospace, monospace',
@@ -16,14 +16,14 @@
16
16
  },
17
17
  size: {
18
18
  default: "text-sm gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2",
19
- xs: "text-xs gap-1 rounded-[min(var(--radius-md),10px)] px-2 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
20
- sm: "text-[0.8rem] gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
19
+ xs: "text-xs gap-1 rounded-[min(var(--sb--radius-md),10px)] px-2 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3",
20
+ sm: "text-[0.8rem] gap-1 rounded-[min(var(--sb--radius-md),12px)] px-2.5 in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5",
21
21
  lg: "text-sm gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3",
22
22
  xl: "text-base gap-2 px-4 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3 [&_svg:not([class*='size-'])]:size-5",
23
23
  "2xl": "text-lg gap-2.5 px-5 has-data-[icon=inline-end]:pr-4 has-data-[icon=inline-start]:pl-4 [&_svg:not([class*='size-'])]:size-6",
24
24
  icon: "text-sm",
25
- "icon-xs": "text-xs rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
26
- "icon-sm": "text-[0.8rem] rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
25
+ "icon-xs": "text-xs rounded-[min(var(--sb--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3",
26
+ "icon-sm": "text-[0.8rem] rounded-[min(var(--sb--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
27
27
  "icon-lg": "text-sm",
28
28
  "icon-xl": "text-base [&_svg:not([class*='size-'])]:size-5",
29
29
  "icon-2xl": "text-lg [&_svg:not([class*='size-'])]:size-6",
@@ -40,14 +40,14 @@
40
40
  variants: {
41
41
  size: {
42
42
  default: "h-8",
43
- xs: "h-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg",
44
- sm: "h-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
43
+ xs: "h-6 rounded-[min(var(--sb--radius-md),10px)] in-data-[slot=button-group]:rounded-lg",
44
+ sm: "h-7 rounded-[min(var(--sb--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
45
45
  lg: "h-9",
46
46
  xl: "h-11",
47
47
  "2xl": "h-14",
48
48
  icon: "size-8",
49
- "icon-xs": "size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg",
50
- "icon-sm": "size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
49
+ "icon-xs": "size-6 rounded-[min(var(--sb--radius-md),10px)] in-data-[slot=button-group]:rounded-lg",
50
+ "icon-sm": "size-7 rounded-[min(var(--sb--radius-md),12px)] in-data-[slot=button-group]:rounded-lg",
51
51
  "icon-lg": "size-9",
52
52
  "icon-xl": "size-11",
53
53
  "icon-2xl": "size-14",
@@ -78,7 +78,7 @@
78
78
  <span
79
79
  data-slot="button-wrapper"
80
80
  class={cn(wrapperVariants({ size }), wrapperClass)}
81
- style="background: var(--sc-border-color, transparent); padding: var(--sc-border-width, 0px);"
81
+ style="background: var(--sb--sc-border-color, transparent); padding: var(--sb--sc-border-width, 0px);"
82
82
  >
83
83
  {#if href}
84
84
  <a
@@ -18,9 +18,9 @@
18
18
  onInteractOutside={(e) => e.preventDefault()}
19
19
  onFocusOutside={(e) => e.preventDefault()}
20
20
  class={cn(
21
- "font-sans fixed z-[10000] bottom-28 right-6 w-[400px] max-h-[70vh] flex flex-col",
21
+ "font-sans fixed z-[10000] bottom-28 right-6 w-[400px] max-h-[90vh] flex flex-col",
22
22
  "bg-popover text-popover-foreground border-3 border-slate-400",
23
- "rounded-xl shadow-xl overflow-hidden",
23
+ "rounded-xl shadow-xl overflow-x-hidden overflow-y-auto",
24
24
  "data-open:animate-in data-open:fade-in-0 data-open:slide-in-from-bottom-4",
25
25
  "data-closed:animate-out data-closed:fade-out-0 data-closed:slide-out-to-bottom-4",
26
26
  "duration-150",
@@ -17,7 +17,7 @@
17
17
  data-slot="select-trigger"
18
18
  data-size={size}
19
19
  class={cn(
20
- "border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--radius-md),10px)] *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
20
+ "border-input data-placeholder:text-muted-foreground dark:bg-input/30 dark:hover:bg-input/50 focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:aria-invalid:border-destructive/50 gap-1.5 rounded-lg border bg-transparent py-2 pr-2 pl-2.5 text-sm transition-colors select-none focus-visible:ring-3 aria-invalid:ring-3 data-[size=default]:h-8 data-[size=sm]:h-7 data-[size=sm]:rounded-[min(var(--sb--radius-md),10px)] *:data-[slot=select-value]:flex *:data-[slot=select-value]:gap-1.5 [&_svg:not([class*='size-'])]:size-4 flex w-fit items-center justify-between whitespace-nowrap outline-none disabled:cursor-not-allowed disabled:opacity-50 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
21
21
  className
22
22
  )}
23
23
  {...restProps}
@@ -10,7 +10,7 @@
10
10
  },
11
11
  size: {
12
12
  default: "h-8 min-w-8 px-2",
13
- sm: "h-7 min-w-7 rounded-[min(var(--radius-md),12px)] px-1.5 text-[0.8rem]",
13
+ sm: "h-7 min-w-7 rounded-[min(var(--sb--radius-md),12px)] px-1.5 text-[0.8rem]",
14
14
  lg: "h-9 min-w-9 px-2.5",
15
15
  },
16
16
  },
@@ -54,9 +54,9 @@ get along, so we shut typescript up by casting `value` to `never`.
54
54
  data-variant={variant}
55
55
  data-size={size}
56
56
  data-spacing={spacing}
57
- style={`--gap: ${spacing}`}
57
+ style={`--sb--gap: ${spacing}`}
58
58
  class={cn(
59
- "rounded-lg data-[size=sm]:rounded-[min(var(--radius-md),10px)] group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--gap))] data-vertical:flex-col data-vertical:items-stretch",
59
+ "rounded-lg data-[size=sm]:rounded-[min(var(--sb--radius-md),10px)] group/toggle-group flex w-fit flex-row items-center gap-[--spacing(var(--sb--gap))] data-vertical:flex-col data-vertical:items-stretch",
60
60
  className
61
61
  )}
62
62
  {...restProps}
@@ -3,10 +3,10 @@
3
3
  First component of the core UI kit for floating menus.
4
4
 
5
5
  Themable via CSS custom properties (set on any ancestor):
6
- --trigger-bg Background color (default: slate-100)
7
- --trigger-bg-hover Background on hover/active (default: slate-200)
8
- --trigger-text Text / icon color (default: slate-600)
9
- --trigger-border Border color (default: slate-400)
6
+ --sb--trigger-bg Background color (default: slate-100)
7
+ --sb--trigger-bg-hover Background on hover/active (default: slate-200)
8
+ --sb--trigger-text Text / icon color (default: slate-600)
9
+ --sb--trigger-border Border color (default: slate-400)
10
10
  -->
11
11
 
12
12
  <script module>
@@ -17,7 +17,7 @@
17
17
  // that breaks when this source is consumed from node_modules.
18
18
  if (typeof CSS !== 'undefined' && 'paintWorklet' in CSS) {
19
19
  try {
20
- const worklet = `class P{static get inputProperties(){return["--smooth-corners"]}superellipse(a,b,nX=4,nY){if(Number.isNaN(nX))nX=4;if(typeof nY==="undefined"||Number.isNaN(nY))nY=nX;if(nX>100)nX=100;if(nY>100)nY=100;if(nX<1e-11)nX=1e-11;if(nY<1e-11)nY=1e-11;const nX2=2/nX,nY2=nY?2/nY:nX2,steps=360,step=(2*Math.PI)/steps;return Array.from({length:steps},(_,i)=>{const t=i*step,cosT=Math.cos(t),sinT=Math.sin(t);return{x:Math.abs(cosT)**nX2*a*Math.sign(cosT),y:Math.abs(sinT)**nY2*b*Math.sign(sinT)}})}paint(ctx,geom,props){const[nX,nY]=props.get("--smooth-corners").toString().replace(/ /g,"").split(",");const w=geom.width/2,h=geom.height/2,s=this.superellipse(w,h,parseFloat(nX),parseFloat(nY));ctx.fillStyle="#000";ctx.setTransform(1,0,0,1,w,h);ctx.beginPath();for(let i=0;i<s.length;i++){const{x,y}=s[i];i===0?ctx.moveTo(x,y):ctx.lineTo(x,y)}ctx.closePath();ctx.fill()}}registerPaint("smooth-corners",P);`;
20
+ const worklet = `class P{static get inputProperties(){return["--sb--smooth-corners"]}superellipse(a,b,nX=4,nY){if(Number.isNaN(nX))nX=4;if(typeof nY==="undefined"||Number.isNaN(nY))nY=nX;if(nX>100)nX=100;if(nY>100)nY=100;if(nX<1e-11)nX=1e-11;if(nY<1e-11)nY=1e-11;const nX2=2/nX,nY2=nY?2/nY:nX2,steps=360,step=(2*Math.PI)/steps;return Array.from({length:steps},(_,i)=>{const t=i*step,cosT=Math.cos(t),sinT=Math.sin(t);return{x:Math.abs(cosT)**nX2*a*Math.sign(cosT),y:Math.abs(sinT)**nY2*b*Math.sign(sinT)}})}paint(ctx,geom,props){const[nX,nY]=props.get("--sb--smooth-corners").toString().replace(/ /g,"").split(",");const w=geom.width/2,h=geom.height/2,s=this.superellipse(w,h,parseFloat(nX),parseFloat(nY));ctx.fillStyle="#000";ctx.setTransform(1,0,0,1,w,h);ctx.beginPath();for(let i=0;i<s.length;i++){const{x,y}=s[i];i===0?ctx.moveTo(x,y):ctx.lineTo(x,y)}ctx.closePath();ctx.fill()}}registerPaint("smooth-corners",P);`;
21
21
  const blob = new Blob([worklet], { type: 'application/javascript' });
22
22
  CSS.paintWorklet.addModule(URL.createObjectURL(blob));
23
23
  } catch {}
@@ -50,14 +50,14 @@
50
50
  data-inactive={inactive || undefined}
51
51
  data-dimmed={dimmed || undefined}
52
52
  data-local-only={localOnly || undefined}
53
- style:--sb-trigger-border-width={borderWidth}
53
+ style:--sb--trigger-border-width={borderWidth}
54
54
  >
55
55
  <Button
56
56
  variant="trigger"
57
57
  {size}
58
58
  disabled={inactive}
59
59
  wrapperClass={cn(
60
- "smooth-corners [--smooth-corners:4] hover:rotate-2 focus-visible:rotate-2 transition-transform",
60
+ "smooth-corners [--sb--smooth-corners:4] hover:rotate-2 focus-visible:rotate-2 transition-transform",
61
61
  active && !inactive && "rotate-2",
62
62
  wrapperClass
63
63
  )}
@@ -77,22 +77,22 @@
77
77
  position: relative;
78
78
  }
79
79
  [data-trigger-button] :global([data-slot="button-wrapper"]) {
80
- --sc-border-color: var(--trigger-border, var(--color-slate-400));
81
- --sc-border-width: var(--sb-trigger-border-width, 3px);
80
+ --sb--sc-border-color: var(--sb--trigger-border, var(--color-slate-400));
81
+ --sb--sc-border-width: var(--sb--trigger-border-width, 3px);
82
82
  }
83
83
  /* Accent-colored border/gap on focus — follows the superellipse shape */
84
84
  [data-trigger-button] :global([data-slot="button-wrapper"]:has([data-slot="button"]:focus-visible)) {
85
- --sc-border-color: hsl(212 92% 45%);
85
+ --sb--sc-border-color: hsl(212 92% 45%);
86
86
  }
87
87
  [data-trigger-button] :global([data-slot="button"]) {
88
- background-color: var(--trigger-bg, var(--color-slate-100));
89
- color: var(--trigger-text, var(--color-slate-600));
88
+ background-color: var(--sb--trigger-bg, var(--color-slate-100));
89
+ color: var(--sb--trigger-text, var(--color-slate-600));
90
90
  }
91
91
  [data-trigger-button] :global([data-slot="button"]:hover),
92
92
  [data-trigger-button] :global([data-slot="button"]:focus-visible),
93
93
  [data-trigger-button] :global([data-slot="button"][aria-expanded="true"]),
94
94
  [data-trigger-button][data-active] :global([data-slot="button"]) {
95
- background-color: var(--trigger-bg-hover, var(--color-slate-300));
95
+ background-color: var(--sb--trigger-bg-hover, var(--color-slate-300));
96
96
  }
97
97
 
98
98
  /* Inactive: disabled-looking, no interaction */
package/src/modes.css CHANGED
@@ -6,25 +6,25 @@
6
6
  */
7
7
 
8
8
  :root {
9
- --mode-color: #fcfcfc;
10
- --color-orange: #dfb490;
11
- --color-green: #2a9d8f;
12
- --color-blue: #4a7fad;
13
- --color-purple: #7655a4;
14
- --color-dark: #2a2a2a;
9
+ --sb--mode-color: #fcfcfc;
10
+ --sb--color-orange: #dfb490;
11
+ --sb--color-green: #2a9d8f;
12
+ --sb--color-blue: #4a7fad;
13
+ --sb--color-purple: #7655a4;
14
+ --sb--color-dark: #2a2a2a;
15
15
  }
16
16
 
17
- html.storyboard-mode-present { --mode-color: var(--color-green); }
18
- html.storyboard-mode-plan { --mode-color: var(--color-blue); }
19
- html.storyboard-mode-inspect { --mode-color: var(--color-purple); }
20
- html.storyboard-mode-prototype { --mode-color: var(--color-dark); }
17
+ html.storyboard-mode-present { --sb--mode-color: var(--sb--color-green); }
18
+ html.storyboard-mode-plan { --sb--mode-color: var(--sb--color-blue); }
19
+ html.storyboard-mode-inspect { --sb--mode-color: var(--sb--color-purple); }
20
+ html.storyboard-mode-prototype { --sb--mode-color: var(--sb--color-dark); }
21
21
 
22
22
  html.storyboard-mode-present,
23
23
  html.storyboard-mode-plan,
24
24
  html.storyboard-mode-prototype,
25
25
  html.storyboard-mode-inspect {
26
26
  padding: 12px;
27
- background-color: var(--mode-color);
27
+ background-color: var(--sb--mode-color);
28
28
  transition: background-color 0.2s ease, padding 0.2s ease;
29
29
  }
30
30
 
@@ -41,7 +41,7 @@ html.storyboard-mode-inspect::before {
41
41
  left: 0;
42
42
  width: 100vw;
43
43
  height: 12px;
44
- background-color: var(--mode-color);
44
+ background-color: var(--sb--mode-color);
45
45
  z-index: 99999;
46
46
  pointer-events: none;
47
47
  }
@@ -52,7 +52,7 @@ html.storyboard-mode-inspect > body > #root {
52
52
  overflow-x: hidden;
53
53
  overflow-y: hidden;
54
54
  border-radius: var(--borderRadius-default);
55
- /* box-shadow: 0 0 80px 40px var(--mode-color); */
55
+ /* box-shadow: 0 0 80px 40px var(--sb--mode-color); */
56
56
  }
57
57
 
58
58
  /* Make body transparent so the html mode-color background
@@ -83,16 +83,16 @@ html.storyboard-mode-inspect > body > #root {
83
83
  html.storyboard-mode-present,
84
84
  html.storyboard-mode-plan,
85
85
  html.storyboard-mode-inspect {
86
- --trigger-bg: color-mix(in srgb, var(--mode-color) 12%, white);
87
- --trigger-bg-hover: color-mix(in srgb, var(--mode-color) 20%, white);
88
- --trigger-text: color-mix(in srgb, var(--mode-color) 85%, black);
89
- --trigger-border: color-mix(in srgb, var(--mode-color) 45%, white);
86
+ --sb--trigger-bg: color-mix(in srgb, var(--sb--mode-color) 12%, white);
87
+ --sb--trigger-bg-hover: color-mix(in srgb, var(--sb--mode-color) 20%, white);
88
+ --sb--trigger-text: color-mix(in srgb, var(--sb--mode-color) 85%, black);
89
+ --sb--trigger-border: color-mix(in srgb, var(--sb--mode-color) 45%, white);
90
90
  }
91
91
 
92
92
  /* Dark trigger tokens — applied when toolbar follows a dark theme */
93
93
  :root[data-sb-toolbar-theme^="dark"] {
94
- --trigger-bg: #21262d;
95
- --trigger-bg-hover: #30363d;
96
- --trigger-text: #e6edf3;
97
- --trigger-border: #30363d;
94
+ --sb--trigger-bg: #21262d;
95
+ --sb--trigger-bg-hover: #30363d;
96
+ --sb--trigger-text: #e6edf3;
97
+ --sb--trigger-border: #30363d;
98
98
  }
@@ -209,12 +209,12 @@ function showToast(message, route, basePath) {
209
209
  zIndex: '10000',
210
210
  padding: '0.75rem 1rem',
211
211
  borderRadius: '0.75rem',
212
- background: 'var(--color-popover, #fff)',
213
- color: 'var(--color-foreground, #1e293b)',
212
+ background: 'var(--sb--color-popover, #fff)',
213
+ color: 'var(--sb--color-foreground, #1e293b)',
214
214
  fontSize: '0.8125rem',
215
215
  fontFamily: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif",
216
216
  boxShadow: '0 8px 24px rgba(0,0,0,0.15)',
217
- border: '1px solid var(--color-border, #cbd5e1)',
217
+ border: '1px solid var(--sb--color-border, #cbd5e1)',
218
218
  display: 'flex',
219
219
  flexDirection: 'column',
220
220
  gap: '0.25rem',
@@ -225,7 +225,7 @@ function showToast(message, route, basePath) {
225
225
 
226
226
  const href = route?.startsWith('/') ? (basePath.replace(/\/$/, '') + route) : route
227
227
  toast.innerHTML = `<span style="font-weight:500">✓ ${message.replace(/</g, '&lt;')}</span>`
228
- + (href ? `<a href="${href}" style="color:var(--color-primary, #0969da);text-decoration:underline;font-size:0.8125rem">Open canvas</a>` : '')
228
+ + (href ? `<a href="${href}" style="color:var(--sb--color-primary, #0969da);text-decoration:underline;font-size:0.8125rem">Open canvas</a>` : '')
229
229
 
230
230
  document.body.appendChild(toast)
231
231
  requestAnimationFrame(() => { toast.style.opacity = '1' })
package/src/sidepanel.css CHANGED
@@ -8,8 +8,8 @@
8
8
  */
9
9
 
10
10
  :root {
11
- --sidepanel-width: 420px;
12
- --sidepanel-height: 300px;
11
+ --sb--sidepanel-width: 420px;
12
+ --sb--sidepanel-height: 300px;
13
13
  }
14
14
 
15
15
  /* -----------------------------------------------------------------------
@@ -17,7 +17,7 @@
17
17
  ----------------------------------------------------------------------- */
18
18
 
19
19
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom) > body > #root {
20
- margin-right: var(--sidepanel-width);
20
+ margin-right: var(--sb--sidepanel-width);
21
21
  transition: margin-right 0.25s ease;
22
22
  }
23
23
 
@@ -25,7 +25,7 @@ html.sb-sidepanel-open:not(.sb-sidepanel-bottom) > body > #root {
25
25
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-present > body > #root,
26
26
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-plan > body > #root,
27
27
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom).storyboard-mode-inspect > body > #root {
28
- margin-right: calc(var(--sidepanel-width) + 12px);
28
+ margin-right: calc(var(--sb--sidepanel-width) + 12px);
29
29
  }
30
30
 
31
31
  html:not(.sb-sidepanel-open) > body > #root {
@@ -34,7 +34,7 @@ html:not(.sb-sidepanel-open) > body > #root {
34
34
 
35
35
  /* Push the CoreUIBar (fixed bottom-right) — side mode */
36
36
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom) [data-core-ui-bar] {
37
- right: calc(var(--sidepanel-width) + 24px) !important;
37
+ right: calc(var(--sb--sidepanel-width) + 24px) !important;
38
38
  transition: right 0.25s ease;
39
39
  }
40
40
 
@@ -44,7 +44,7 @@ html:not(.sb-sidepanel-open) [data-core-ui-bar] {
44
44
 
45
45
  /* Push the ModeSwitch (fixed bottom-center) — side mode */
46
46
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom) .sb-mode-switch {
47
- transform: translateX(calc(-50% - var(--sidepanel-width) / 2));
47
+ transform: translateX(calc(-50% - var(--sb--sidepanel-width) / 2));
48
48
  transition: transform 0.25s ease;
49
49
  }
50
50
 
@@ -55,7 +55,7 @@ html:not(.sb-sidepanel-open) .sb-mode-switch {
55
55
  /* When both modes collar padding AND sidepanel are active,
56
56
  the collar bottom bar should not extend under the panel + its right gap */
57
57
  html.sb-sidepanel-open:not(.sb-sidepanel-bottom)::before {
58
- width: calc(100vw - var(--sidepanel-width) - 12px);
58
+ width: calc(100vw - var(--sb--sidepanel-width) - 12px);
59
59
  }
60
60
 
61
61
  /* -----------------------------------------------------------------------
@@ -63,7 +63,7 @@ html.sb-sidepanel-open:not(.sb-sidepanel-bottom)::before {
63
63
  ----------------------------------------------------------------------- */
64
64
 
65
65
  html.sb-sidepanel-open.sb-sidepanel-bottom > body > #root {
66
- margin-bottom: var(--sidepanel-height);
66
+ margin-bottom: var(--sb--sidepanel-height);
67
67
  transition: margin-bottom 0.25s ease;
68
68
  }
69
69
 
@@ -71,17 +71,17 @@ html.sb-sidepanel-open.sb-sidepanel-bottom > body > #root {
71
71
  html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-present > body > #root,
72
72
  html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-plan > body > #root,
73
73
  html.sb-sidepanel-open.sb-sidepanel-bottom.storyboard-mode-inspect > body > #root {
74
- margin-bottom: calc(var(--sidepanel-height) + 12px);
74
+ margin-bottom: calc(var(--sb--sidepanel-height) + 12px);
75
75
  }
76
76
 
77
77
  /* Push the CoreUIBar up — bottom mode */
78
78
  html.sb-sidepanel-open.sb-sidepanel-bottom [data-core-ui-bar] {
79
- bottom: calc(var(--sidepanel-height) + 24px) !important;
79
+ bottom: calc(var(--sb--sidepanel-height) + 24px) !important;
80
80
  transition: bottom 0.25s ease;
81
81
  }
82
82
 
83
83
  /* Push the ModeSwitch up — bottom mode */
84
84
  html.sb-sidepanel-open.sb-sidepanel-bottom .sb-mode-switch {
85
- bottom: calc(var(--sidepanel-height) + 24px);
85
+ bottom: calc(var(--sb--sidepanel-height) + 24px);
86
86
  transition: bottom 0.25s ease;
87
87
  }
@@ -2,6 +2,46 @@
2
2
  @import "tw-animate-css";
3
3
  @source "../**/*.{svelte,js,ts}";
4
4
 
5
+ @font-face {
6
+ font-family: "Ioskeley Mono";
7
+ src: url("../assets/fonts/IoskeleyMono-Regular.woff2") format("woff2");
8
+ font-weight: 400;
9
+ font-style: normal;
10
+ font-display: swap;
11
+ }
12
+
13
+ @font-face {
14
+ font-family: "Ioskeley Mono";
15
+ src: url("../assets/fonts/IoskeleyMono-Italic.woff2") format("woff2");
16
+ font-weight: 400;
17
+ font-style: italic;
18
+ font-display: swap;
19
+ }
20
+
21
+ @font-face {
22
+ font-family: "Ioskeley Mono";
23
+ src: url("../assets/fonts/IoskeleyMono-Medium.woff2") format("woff2");
24
+ font-weight: 500;
25
+ font-style: normal;
26
+ font-display: swap;
27
+ }
28
+
29
+ @font-face {
30
+ font-family: "Ioskeley Mono";
31
+ src: url("../assets/fonts/IoskeleyMono-SemiBold.woff2") format("woff2");
32
+ font-weight: 600;
33
+ font-style: normal;
34
+ font-display: swap;
35
+ }
36
+
37
+ @font-face {
38
+ font-family: "Ioskeley Mono";
39
+ src: url("../assets/fonts/IoskeleyMono-Bold.woff2") format("woff2");
40
+ font-weight: 700;
41
+ font-style: normal;
42
+ font-display: swap;
43
+ }
44
+
5
45
  @custom-variant dark (&:where([data-sb-theme^="dark"], [data-sb-theme^="dark"] *));
6
46
 
7
47
  @theme {
@@ -29,6 +69,31 @@
29
69
  --radius: 0.5rem;
30
70
  --font-sans: "Ioskeley Mono", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;
31
71
  --font-mono: "Ioskeley Mono", ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace;
72
+
73
+ --sb--color-background: hsl(0 0% 100%);
74
+ --sb--color-foreground: hsl(222.2 84% 4.9%);
75
+ --sb--color-card: hsl(0 0% 100%);
76
+ --sb--color-card-foreground: hsl(222.2 84% 4.9%);
77
+ --sb--color-popover: hsl(0 0% 100%);
78
+ --sb--color-popover-foreground: hsl(222.2 84% 4.9%);
79
+ --sb--color-primary: hsl(222.2 47.4% 11.2%);
80
+ --sb--color-primary-foreground: hsl(210 40% 98%);
81
+ --sb--color-secondary: hsl(210 40% 96.1%);
82
+ --sb--color-secondary-foreground: hsl(222.2 47.4% 11.2%);
83
+ --sb--color-muted: hsl(210 40% 96.1%);
84
+ --sb--color-muted-foreground: hsl(215.4 16.3% 46.9%);
85
+ --sb--color-accent: hsl(210 40% 96.1%);
86
+ --sb--color-accent-foreground: hsl(222.2 47.4% 11.2%);
87
+ --sb--color-destructive: hsl(0 84.2% 60.2%);
88
+ --sb--color-destructive-foreground: hsl(210 40% 98%);
89
+ --sb--color-border: hsl(214.3 31.8% 91.4%);
90
+ --sb--color-input: hsl(214.3 31.8% 91.4%);
91
+ --sb--color-ring: hsl(222.2 84% 4.9%);
92
+ --sb--color-success: hsl(142 71% 36%);
93
+ --sb--color-success-foreground: hsl(0 0% 100%);
94
+ --sb--radius: var(--radius);
95
+ --sb--font-sans: var(--font-sans);
96
+ --sb--font-mono: var(--font-mono);
32
97
  }
33
98
 
34
99
  @layer base {
@@ -54,6 +119,28 @@
54
119
  --color-ring: hsl(212.7 26.8% 83.9%);
55
120
  --color-success: hsl(142 71% 45%);
56
121
  --color-success-foreground: hsl(0 0% 100%);
122
+
123
+ --sb--color-background: hsl(222.2 84% 4.9%);
124
+ --sb--color-foreground: hsl(210 40% 98%);
125
+ --sb--color-card: hsl(222.2 84% 4.9%);
126
+ --sb--color-card-foreground: hsl(210 40% 98%);
127
+ --sb--color-popover: hsl(222.2 84% 4.9%);
128
+ --sb--color-popover-foreground: hsl(210 40% 98%);
129
+ --sb--color-primary: hsl(210 40% 98%);
130
+ --sb--color-primary-foreground: hsl(222.2 47.4% 11.2%);
131
+ --sb--color-secondary: hsl(217.2 32.6% 17.5%);
132
+ --sb--color-secondary-foreground: hsl(210 40% 98%);
133
+ --sb--color-muted: hsl(217.2 32.6% 17.5%);
134
+ --sb--color-muted-foreground: hsl(215 20.2% 65.1%);
135
+ --sb--color-accent: hsl(217.2 32.6% 17.5%);
136
+ --sb--color-accent-foreground: hsl(210 40% 98%);
137
+ --sb--color-destructive: hsl(0 62.8% 30.6%);
138
+ --sb--color-destructive-foreground: hsl(210 40% 98%);
139
+ --sb--color-border: hsl(217.2 32.6% 17.5%);
140
+ --sb--color-input: hsl(217.2 32.6% 17.5%);
141
+ --sb--color-ring: hsl(212.7 26.8% 83.9%);
142
+ --sb--color-success: hsl(142 71% 45%);
143
+ --sb--color-success-foreground: hsl(0 0% 100%);
57
144
  }
58
145
  }
59
146
  @custom-variant data-open {
@@ -116,7 +203,8 @@
116
203
 
117
204
  @layer base {
118
205
  :root {
119
- --smooth-corners: 4;
206
+ --sb--smooth-corners: 4;
207
+ --sb--radius-md: var(--radius-md);
120
208
  }
121
209
  }
122
210
 
@@ -48,7 +48,7 @@
48
48
  :global(html.storyboard-mode-present) .sb-mode-switch,
49
49
  :global(html.storyboard-mode-plan) .sb-mode-switch,
50
50
  :global(html.storyboard-mode-inspect) .sb-mode-switch {
51
- background: color-mix(in srgb, var(--mode-color) 40%, black);
51
+ background: color-mix(in srgb, var(--sb--mode-color) 40%, black);
52
52
  transition: background 0.2s ease;
53
53
  }
54
54
 
@@ -103,7 +103,7 @@
103
103
  :global(html.storyboard-mode-plan) .sb-mode-btn-active,
104
104
  :global(html.storyboard-mode-inspect) .sb-mode-btn-active {
105
105
  background: rgba(255, 255, 255, 0.85);
106
- color: color-mix(in srgb, var(--mode-color) 70%, black);
106
+ color: color-mix(in srgb, var(--sb--mode-color) 70%, black);
107
107
  }
108
108
 
109
109
  :global(html.storyboard-mode-prototype) .sb-mode-btn-active:hover,
@@ -111,7 +111,7 @@
111
111
  :global(html.storyboard-mode-plan) .sb-mode-btn-active:hover,
112
112
  :global(html.storyboard-mode-inspect) .sb-mode-btn-active:hover {
113
113
  background: rgba(255, 255, 255, 0.85);
114
- color: color-mix(in srgb, var(--mode-color) 70%, black);
114
+ color: color-mix(in srgb, var(--sb--mode-color) 70%, black);
115
115
  }
116
116
 
117
117
  /* Hide when chrome is toggled off via ⌘ + . */