viberoom 0.6.0 → 0.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 (110) hide show
  1. package/NOTICE +14 -0
  2. package/dist/hub.js +45 -4
  3. package/dist/main.js +1 -1
  4. package/dist/recipes.js +2 -1
  5. package/dist/shortcuts.js +1 -1
  6. package/package.json +1 -1
  7. package/ui/app.css +131 -107
  8. package/ui/app.js +334 -87
  9. package/ui/avatars.js +7 -14
  10. package/ui/components.css +116 -21
  11. package/ui/components.js +202 -1
  12. package/ui/fonts/anonymous-pro-cyrillic-400.woff2 +0 -0
  13. package/ui/fonts/anonymous-pro-cyrillic-700.woff2 +0 -0
  14. package/ui/fonts/anonymous-pro-latin-400.woff2 +0 -0
  15. package/ui/fonts/anonymous-pro-latin-700.woff2 +0 -0
  16. package/ui/fonts/anonymous-pro-latin-ext-400.woff2 +0 -0
  17. package/ui/fonts/anonymous-pro-latin-ext-700.woff2 +0 -0
  18. package/ui/fonts/anonymous-pro.css +7 -0
  19. package/ui/fonts/cascadia-code-cyrillic-ext.woff2 +0 -0
  20. package/ui/fonts/cascadia-code-cyrillic.woff2 +0 -0
  21. package/ui/fonts/cascadia-code-latin-ext.woff2 +0 -0
  22. package/ui/fonts/cascadia-code-latin.woff2 +0 -0
  23. package/ui/fonts/cascadia-code.css +5 -0
  24. package/ui/fonts/comfortaa-cyrillic-ext.woff2 +0 -0
  25. package/ui/fonts/comfortaa-cyrillic.woff2 +0 -0
  26. package/ui/fonts/comfortaa-latin-ext.woff2 +0 -0
  27. package/ui/fonts/comfortaa-latin.woff2 +0 -0
  28. package/ui/fonts/comfortaa.css +5 -0
  29. package/ui/fonts/exo-2-cyrillic-ext.woff2 +0 -0
  30. package/ui/fonts/exo-2-cyrillic.woff2 +0 -0
  31. package/ui/fonts/exo-2-latin-ext.woff2 +0 -0
  32. package/ui/fonts/exo-2-latin.woff2 +0 -0
  33. package/ui/fonts/exo-2.css +5 -0
  34. package/ui/fonts/golos-text-cyrillic-ext.woff2 +0 -0
  35. package/ui/fonts/golos-text-cyrillic.woff2 +0 -0
  36. package/ui/fonts/golos-text-latin-ext.woff2 +0 -0
  37. package/ui/fonts/golos-text-latin.woff2 +0 -0
  38. package/ui/fonts/golos-text.css +5 -0
  39. package/ui/fonts/ibm-plex-mono-cyrillic-400.woff2 +0 -0
  40. package/ui/fonts/ibm-plex-mono-cyrillic-600.woff2 +0 -0
  41. package/ui/fonts/ibm-plex-mono-cyrillic-700.woff2 +0 -0
  42. package/ui/fonts/ibm-plex-mono-cyrillic-ext-400.woff2 +0 -0
  43. package/ui/fonts/ibm-plex-mono-cyrillic-ext-600.woff2 +0 -0
  44. package/ui/fonts/ibm-plex-mono-cyrillic-ext-700.woff2 +0 -0
  45. package/ui/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
  46. package/ui/fonts/ibm-plex-mono-latin-600.woff2 +0 -0
  47. package/ui/fonts/ibm-plex-mono-latin-700.woff2 +0 -0
  48. package/ui/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
  49. package/ui/fonts/ibm-plex-mono-latin-ext-600.woff2 +0 -0
  50. package/ui/fonts/ibm-plex-mono-latin-ext-700.woff2 +0 -0
  51. package/ui/fonts/ibm-plex-mono.css +13 -0
  52. package/ui/fonts/ibm-plex-sans-cyrillic-400.woff2 +0 -0
  53. package/ui/fonts/ibm-plex-sans-cyrillic-600.woff2 +0 -0
  54. package/ui/fonts/ibm-plex-sans-cyrillic-700.woff2 +0 -0
  55. package/ui/fonts/ibm-plex-sans-cyrillic-ext-400.woff2 +0 -0
  56. package/ui/fonts/ibm-plex-sans-cyrillic-ext-600.woff2 +0 -0
  57. package/ui/fonts/ibm-plex-sans-cyrillic-ext-700.woff2 +0 -0
  58. package/ui/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
  59. package/ui/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
  60. package/ui/fonts/ibm-plex-sans-latin-700.woff2 +0 -0
  61. package/ui/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
  62. package/ui/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
  63. package/ui/fonts/ibm-plex-sans-latin-ext-700.woff2 +0 -0
  64. package/ui/fonts/ibm-plex-sans.css +13 -0
  65. package/ui/fonts/manrope-cyrillic-ext.woff2 +0 -0
  66. package/ui/fonts/manrope-cyrillic.woff2 +0 -0
  67. package/ui/fonts/manrope-latin-ext.woff2 +0 -0
  68. package/ui/fonts/manrope-latin.woff2 +0 -0
  69. package/ui/fonts/manrope.css +5 -0
  70. package/ui/fonts/montserrat-cyrillic-ext.woff2 +0 -0
  71. package/ui/fonts/montserrat-cyrillic.woff2 +0 -0
  72. package/ui/fonts/montserrat-latin-ext.woff2 +0 -0
  73. package/ui/fonts/montserrat-latin.woff2 +0 -0
  74. package/ui/fonts/montserrat.css +5 -0
  75. package/ui/fonts/open-sans-cyrillic-ext.woff2 +0 -0
  76. package/ui/fonts/open-sans-cyrillic.woff2 +0 -0
  77. package/ui/fonts/open-sans-latin-ext.woff2 +0 -0
  78. package/ui/fonts/open-sans-latin.woff2 +0 -0
  79. package/ui/fonts/open-sans.css +5 -0
  80. package/ui/fonts/pt-mono-cyrillic-ext.woff2 +0 -0
  81. package/ui/fonts/pt-mono-cyrillic.woff2 +0 -0
  82. package/ui/fonts/pt-mono-latin-ext.woff2 +0 -0
  83. package/ui/fonts/pt-mono-latin.woff2 +0 -0
  84. package/ui/fonts/pt-mono.css +5 -0
  85. package/ui/fonts/rubik-cyrillic-ext.woff2 +0 -0
  86. package/ui/fonts/rubik-cyrillic.woff2 +0 -0
  87. package/ui/fonts/rubik-latin-ext.woff2 +0 -0
  88. package/ui/fonts/rubik-latin.woff2 +0 -0
  89. package/ui/fonts/rubik.css +5 -0
  90. package/ui/fonts/source-sans-3-cyrillic-ext.woff2 +0 -0
  91. package/ui/fonts/source-sans-3-cyrillic.woff2 +0 -0
  92. package/ui/fonts/source-sans-3-latin-ext.woff2 +0 -0
  93. package/ui/fonts/source-sans-3-latin.woff2 +0 -0
  94. package/ui/fonts/source-sans-3.css +5 -0
  95. package/ui/fonts/ubuntu-sans-cyrillic-ext.woff2 +0 -0
  96. package/ui/fonts/ubuntu-sans-cyrillic.woff2 +0 -0
  97. package/ui/fonts/ubuntu-sans-latin-ext.woff2 +0 -0
  98. package/ui/fonts/ubuntu-sans-latin.woff2 +0 -0
  99. package/ui/fonts/ubuntu-sans.css +5 -0
  100. package/ui/fonts/victor-mono-cyrillic-ext.woff2 +0 -0
  101. package/ui/fonts/victor-mono-cyrillic.woff2 +0 -0
  102. package/ui/fonts/victor-mono-latin-ext.woff2 +0 -0
  103. package/ui/fonts/victor-mono-latin.woff2 +0 -0
  104. package/ui/fonts/victor-mono.css +5 -0
  105. package/ui/index.html +15 -6
  106. package/ui/looks.css +2446 -0
  107. package/ui/manifest.json +3 -3
  108. package/ui/theme.css +114 -84
  109. package/ui/tokens.js +315 -29
  110. package/ui/ui.js +2 -0
package/ui/tokens.js CHANGED
@@ -27,7 +27,7 @@
27
27
  ink2: "#2c2b4a",
28
28
  ink3: "#5c5c80",
29
29
  indigo: "#1f1d3a",
30
- muted: "#8f8fb0",
30
+ muted: "#8080a3",
31
31
  faint: "#b3b3cc",
32
32
  placeholder: "#a3a3c0",
33
33
  grey: "#9ca3af",
@@ -50,7 +50,7 @@
50
50
  green: "#2fc97e",
51
51
  warm: "#fff3cc",
52
52
  warm2: "#ffeaa8",
53
- warmInk: "#b8860b",
53
+ warmInk: "#a07408",
54
54
  bronze: "#5a4200",
55
55
  amber: "#f5a524",
56
56
  honey: "#ffcf8f",
@@ -92,6 +92,116 @@
92
92
  magenta: "#f2b8ff",
93
93
  };
94
94
 
95
+ const terminal = {
96
+ ...pop,
97
+ primary: "#3ddc84", primaryLight: "#5ae69a", primaryDeep: "#2bc472", primaryDark: "#1fa85f",
98
+ violet: "#7ee0ff",
99
+ iris: "#0b0f0c",
100
+ ink: "#d7e3d9", ink2: "#c3d1c6", ink3: "#9fb3a5", indigo: "#e6f0e8",
101
+ muted: "#7c9282", faint: "#5b6f61", placeholder: "#5b6f61", grey: "#6f8276",
102
+ white: "#0f1411", black: "#000000",
103
+ bg: "#090c0a", soft: "#131a15", softer: "#10160f", lav: "#172019", lav2: "#1f2b22",
104
+ canvasTop: "#0a0d0b", canvasMid: "#090c0a", canvasBottom: "#080a09",
105
+ shadowInk: "#000000",
106
+ mint: "#123a26", mint2: "#164a30", mintTint: "#0f2e1f", mintInk: "#3ddc84", forest: "#8fe3bd", green: "#3ddc84",
107
+ warm: "#3a2f0c", warm2: "#4a3d10", warmInk: "#f5c542", bronze: "#ffe08a", amber: "#f5c542", honey: "#f5c542", spark: "#ffd166",
108
+ peach: "#3a2414", peach2: "#4a2d18", orange: "#ff9a3d", orangeLight: "#ffab5c", orangeDeep: "#e8782a", orangeDark: "#ffb36b", ember: "#ff8a45", emberDeep: "#f0602c",
109
+ rose: "#3a1512", rose2: "#4a1a16", roseInk: "#ff6b5e", roseDark: "#ff8578", pink: "#ff7ab8", pinkTint: "#2e1420",
110
+ sky: "#0f2a3a", blue: "#5ab0ff", blueDeep: "#7cc0ff", blueSoft: "#8cc8ff",
111
+ orchid: "#2a1a3a", orchidInk: "#c79bff", orchidMid: "#b58cf0",
112
+ periwinkle: "#233126", periwinkleDeep: "#2f4234",
113
+ deep: "#050705", deepGutter: "#0a0d0b", deepInk: "#d7e3d9", deepMuted: "#5b6f61", deepHead: "#c3d1c6", deepMeta: "#7c9282",
114
+ lavGrey: "#3a4a3e", lilac: "#7ee0ff", seafoam: "#3ddc84", azure: "#5ab0ff", salmon: "#ff8578", magenta: "#ff7ab8",
115
+ };
116
+
117
+ const classicDark = {
118
+ ...pop,
119
+ primary: "#8a8aff", primaryLight: "#9c9cff", primaryDeep: "#7474f7", primaryDark: "#6262e6",
120
+ violet: "#b39cff",
121
+ iris: "#202142",
122
+ ink: "#f1efff", ink2: "#e0deff", ink3: "#c0bde6", indigo: "#f6f4ff",
123
+ muted: "#a4a2cc", faint: "#8583b0", placeholder: "#7f7dab", grey: "#8e90b0",
124
+ white: "#202142", black: "#000000",
125
+ bg: "#0f1024", soft: "#262848", softer: "#232445", lav: "#2c2e56", lav2: "#3a3c6e",
126
+ canvasTop: "#141530", canvasMid: "#111226", canvasBottom: "#0e0f21",
127
+ shadowInk: "#000000",
128
+ mint: "#1a4235", mint2: "#205241", mintTint: "#173a2f", mintInk: "#6ee8b3", forest: "#a8ecc9", green: "#4bdc98",
129
+ warm: "#46381a", warm2: "#54441e", warmInk: "#f5c94f", bronze: "#ffe08a", amber: "#f5b73a", honey: "#f5c974", spark: "#ffd166",
130
+ peach: "#3f2a1a", peach2: "#4a3020", orange: "#ff9a4d", orangeLight: "#ffab66", orangeDeep: "#f07c34", orangeDark: "#ffb36b", ember: "#ff8a55", emberDeep: "#f0603c",
131
+ rose: "#401c1e", rose2: "#4d2325", roseInk: "#ff7a70", roseDark: "#ff8f86", pink: "#ff8ac4", pinkTint: "#351a2a",
132
+ sky: "#1a2e46", blue: "#6aa4ff", blueDeep: "#8cb8ff", blueSoft: "#9fc4ff",
133
+ orchid: "#2e2140", orchidInk: "#c9a3ff", orchidMid: "#b48cf0",
134
+ periwinkle: "#34365c", periwinkleDeep: "#40437a",
135
+ deep: "#0f1020", deepGutter: "#0b0c1a", deepInk: "#f4f2ff", deepMuted: "#7c78ad", deepHead: "#e8e6ff", deepMeta: "#a9a5d8",
136
+ lavGrey: "#4a4b70", lilac: "#b9a7ff", seafoam: "#8fe3bd", azure: "#9cd2ff", salmon: "#ff9f9f", magenta: "#f2b8ff",
137
+ };
138
+
139
+ const clay = {
140
+ ...pop,
141
+ primary: "#d97757", primaryLight: "#e08a6d", primaryDeep: "#c4633f", primaryDark: "#a8502f",
142
+ violet: "#9d76c4",
143
+ iris: "#d97757",
144
+ ink: "#1f1e1d", ink2: "#3d3929", ink3: "#5e5a4f", indigo: "#2a2622",
145
+ muted: "#8a8577", faint: "#b3ada0", placeholder: "#a39e90", grey: "#9c988c",
146
+ white: "#ffffff", black: "#000000",
147
+ bg: "#f0eee6", soft: "#f7f5ef", softer: "#f3f0e8", lav: "#ebe7db", lav2: "#dfd9c8",
148
+ canvasTop: "#faf9f5", canvasMid: "#f5f3ec", canvasBottom: "#efece3",
149
+ shadowInk: "#4a3f2a",
150
+ mint: "#dff0e1", mint2: "#cfe6d2", mintTint: "#e8f3e9", mintInk: "#2f7a4f", forest: "#1f5a3a", green: "#4caf77",
151
+ warm: "#fbeecf", warm2: "#f6e2a8", warmInk: "#9a6b0f", bronze: "#5a4200", amber: "#d99a2b", honey: "#f2cc8f", spark: "#f0c96b",
152
+ peach: "#fbe3d3", peach2: "#f8d9c4", orange: "#e67e3c", orangeLight: "#ee9256", orangeDeep: "#cf6a2c", orangeDark: "#a8502f", ember: "#e07a4d", emberDeep: "#c9553a",
153
+ rose: "#f9e3df", rose2: "#f4d3cd", roseInk: "#c24d43", roseDark: "#a13d34", pink: "#b0356f", pinkTint: "#fbeef3",
154
+ sky: "#e0ecf5", blue: "#4a7fb5", blueDeep: "#35618c", blueSoft: "#7ea6d0",
155
+ orchid: "#ece3f2", orchidInk: "#7a4fa3", orchidMid: "#9d76c4",
156
+ periwinkle: "#d8d4e6", periwinkleDeep: "#bdb7d6",
157
+ deep: "#2b2622", deepGutter: "#241f1c", deepInk: "#f5f1e8", deepMuted: "#8c8477", deepHead: "#efe9dc", deepMeta: "#b8b0a0",
158
+ lavGrey: "#cfc8b8", lilac: "#c3b1ff", seafoam: "#9ad8b6", azure: "#a9cbe8", salmon: "#f2a79a", magenta: "#e5b3e0",
159
+ };
160
+
161
+ const comfort = {
162
+ ...pop,
163
+ primary: "#2f6f68", primaryLight: "#3d7f78", primaryDeep: "#275e58", primaryDark: "#1f4d48",
164
+ violet: "#5e6b8c",
165
+ iris: "#2f6f68",
166
+ ink: "#2b2a27", ink2: "#3a3833", ink3: "#5a574f", indigo: "#2b2a27",
167
+ muted: "#6f6b62", faint: "#8d887c", placeholder: "#9a958a", grey: "#8f8b82",
168
+ white: "#f9f6ef", black: "#000000",
169
+ bg: "#efe9dd", soft: "#f4efe5", softer: "#f1ebe0", lav: "#e8e1d3", lav2: "#dcd3c2",
170
+ canvasTop: "#f2ede3", canvasMid: "#efe9dd", canvasBottom: "#ebe4d6",
171
+ shadowInk: "#4a4438",
172
+ mint: "#e0ebe2", mint2: "#d1e2d5", mintTint: "#e8f0ea", mintInk: "#2f6b4f", forest: "#244f3c", green: "#4f9a72",
173
+ warm: "#f4e9cf", warm2: "#ecdfb9", warmInk: "#7d5f12", bronze: "#5a4200", amber: "#c99a3c", honey: "#7d5f12", spark: "#c9a04f",
174
+ peach: "#f3e2d3", peach2: "#efdac8", orange: "#c2703f", orangeLight: "#cd7f50", orangeDeep: "#a85c30", orangeDark: "#8a4a26", ember: "#b8623a", emberDeep: "#9c4a2a",
175
+ rose: "#f2e0dc", rose2: "#ead2cc", roseInk: "#a34a3f", roseDark: "#8a3d34", pink: "#8f3d6a", pinkTint: "#f2e3ea",
176
+ sky: "#dfe7ee", blue: "#3f6e9a", blueDeep: "#2f587d", blueSoft: "#6f93b8",
177
+ orchid: "#e8e2ec", orchidInk: "#6b4f8c", orchidMid: "#8a6fa8",
178
+ periwinkle: "#d9dbe6", periwinkleDeep: "#b9bdd0",
179
+ deep: "#e9e3d6", deepGutter: "#e1dacb", deepInk: "#2b2a27", deepMuted: "#7a7468", deepHead: "#3a3833", deepMeta: "#6f6b62",
180
+ lavGrey: "#c9c2b3", lilac: "#5b4a9a", seafoam: "#1f6e5a", azure: "#2a5d8f", salmon: "#a3472f", magenta: "#8a3f7a",
181
+ };
182
+
183
+ const plush = {
184
+ ...pop,
185
+ primary: "#917ad8", primaryLight: "#b4a2e6", primaryDeep: "#7f66cc", primaryDark: "#6a54b4",
186
+ violet: "#c9b8f0",
187
+ iris: "#917ad8",
188
+ ink: "#5a3e36", ink2: "#634840", ink3: "#8a6f64", indigo: "#5a3e36",
189
+ muted: "#8f7a6e", faint: "#b3a094", placeholder: "#b8a498", grey: "#b3a094",
190
+ white: "#f9f0e1", black: "#000000",
191
+ bg: "#f4e8ce", soft: "#fdf7ec", softer: "#f4e9d8", lav: "#f1e4d2", lav2: "#e8d7c1",
192
+ canvasTop: "#fbf3e6", canvasMid: "#f7ecdd", canvasBottom: "#f1e5ec",
193
+ shadowInk: "#7a5540",
194
+ mint: "#c9e8c4", mint2: "#b4dfae", mintTint: "#dff1dc", mintInk: "#3f7a4a", forest: "#2f6038", green: "#6fcf7a",
195
+ warm: "#fbe4a4", warm2: "#f7d774", warmInk: "#8a6a1c", bronze: "#5a4200", amber: "#f0c24a", honey: "#f7d774", spark: "#fbe07a",
196
+ peach: "#f9dcc8", peach2: "#f5cbae", orange: "#f0a06a", orangeLight: "#f4b385", orangeDeep: "#e08a50", orangeDark: "#b8673a", ember: "#ec6f9d", emberDeep: "#d8598a",
197
+ rose: "#f7c9d8", rose2: "#f2b3c9", roseInk: "#c2456f", roseDark: "#a63c64", pink: "#d85a8c", pinkTint: "#fbe3ec",
198
+ sky: "#d5f0ec", blue: "#5fbdb3", blueDeep: "#33857c", blueSoft: "#8fd6cf",
199
+ orchid: "#e6dff7", orchidInk: "#6a55b0", orchidMid: "#a893e2",
200
+ periwinkle: "#ded5f3", periwinkleDeep: "#c5b8ea",
201
+ deep: "#4a352e", deepGutter: "#3f2d27", deepInk: "#f9f1e4", deepMuted: "#a58f83", deepHead: "#f0e4d4", deepMeta: "#c2ada0",
202
+ lavGrey: "#cdbfb0", lilac: "#c9b8f0", seafoam: "#8fd6cf", azure: "#9ccbe8", salmon: "#f4b385", magenta: "#f0a0c0",
203
+ };
204
+
95
205
  const meaningOf = (p) => ({
96
206
  stReady: p.mint, stReadyInk: p.mintInk, stReadyDot: p.green,
97
207
  stWaiting: p.sky, stWaitingInk: p.blueDeep, stWaitingDot: p.blueSoft,
@@ -111,8 +221,6 @@
111
221
  tickMine: p.periwinkle,
112
222
  tickMineView: p.periwinkleDeep,
113
223
  tickFallback: p.grey,
114
- unseenInk: p.pink,
115
- unseenBg: p.pinkTint,
116
224
  });
117
225
 
118
226
  const aliasesOf = (p) => ({
@@ -161,6 +269,8 @@
161
269
  shadowInset: "none",
162
270
  shadowSoft: edge,
163
271
  shadow: edge,
272
+ bevel: "none",
273
+ shadowRoom: "0px",
164
274
  };
165
275
  };
166
276
 
@@ -175,11 +285,13 @@
175
285
  });
176
286
 
177
287
  const shape = {
178
- rXs: "8px", rSm: "12px", rMd: "14px", rLg: "18px", rXl: "18px", rPill: "99px",
288
+ rScale: "1",
289
+ rXs: "calc(8px * var(--r-scale))", rSm: "calc(12px * var(--r-scale))", rMd: "calc(14px * var(--r-scale))", rLg: "calc(18px * var(--r-scale))", rXl: "calc(18px * var(--r-scale))", rPill: "calc(99px * var(--r-scale))",
179
290
  };
180
291
  const type = {
181
292
  font: '"Nunito", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif',
182
293
  mono: '"JetBrains Mono", ui-monospace, Consolas, "Courier New", monospace',
294
+ lineHeight: "1.45",
183
295
  fsScale: "1",
184
296
  fsXs: "calc(11px * var(--fs-scale))",
185
297
  fsSm: "calc(12px * var(--fs-scale))",
@@ -341,6 +453,15 @@
341
453
  attentionBg: p.warm,
342
454
  fs: "calc(12px * var(--fs-scale))",
343
455
  },
456
+ lookCard: {
457
+ w: "150px",
458
+ paperH: "84px",
459
+ bg: p.white,
460
+ ink: p.ink,
461
+ border: p.lav2,
462
+ hoverBorder: p.periwinkleDeep,
463
+ onBorder: p.primary,
464
+ },
344
465
  choice: {
345
466
  bg: p.soft,
346
467
  ink: p.ink3,
@@ -357,14 +478,11 @@
357
478
  tick: p.white,
358
479
  },
359
480
  tile: {
360
- logoBg: p.white,
361
481
  badgeBg: p.white,
362
- badgeBorder: p.white,
363
- ring: p.white,
364
- markInk: p.white,
365
482
  countInk: p.white,
366
483
  },
367
484
  roomMark: {
485
+ ink: p.white,
368
486
  gradAngle: "135deg",
369
487
  gradFrom: "72% 66%",
370
488
  gradTo: "68% 52%",
@@ -388,7 +506,7 @@
388
506
  },
389
507
  toast: {
390
508
  bg: p.ink,
391
- ink: p.deepInk,
509
+ ink: p.white,
392
510
  },
393
511
  rail: {
394
512
  logoShadow: `0 8px 18px -6px ${alpha(p.primary, 0.6)}`,
@@ -405,6 +523,7 @@
405
523
  bubble: {
406
524
  bg: p.white,
407
525
  ink: p.ink2,
526
+ border: "transparent",
408
527
  shadow: `0 2px 0 ${alpha(p.ink, 0.06)}, 0 1px 3px ${alpha(p.ink, 0.04)}`,
409
528
  mineBg: `linear-gradient(135deg, ${p.primaryLight}, ${p.primaryDeep})`,
410
529
  mineInk: p.white,
@@ -486,19 +605,58 @@
486
605
  input: {
487
606
  bg: p.white,
488
607
  focusBorder: p.primary,
608
+ shadow: "none",
489
609
  },
490
610
  profile: {
491
611
  bg: `linear-gradient(160deg, ${p.lav}, ${p.mintTint})`,
492
- avatarBg: p.white,
493
612
  badgeBg: p.white,
494
613
  },
495
- participant: {
614
+ face: {
615
+ paper: p.white,
616
+ tint: "16%",
617
+ corner: "0.32",
618
+ ring: p.white,
619
+ meRing: p.primary,
620
+ dotBg: p.faint,
621
+ cardBg: p.white,
496
622
  fallback: p.grey,
497
623
  humanInk: p.indigo,
498
624
  avatarDefault: p.primary,
499
625
  avatarGloss: p.white,
500
626
  avatarLabelInk: p.white,
501
- avatarBlend: p.white,
627
+ },
628
+ logoTile: {
629
+ bg: p.white,
630
+ ink: p.indigo,
631
+ badgeBg: p.white,
632
+ badgeBorder: p.white,
633
+ badgeInk: p.indigo,
634
+ mutedBg: p.warm,
635
+ mutedInk: p.warmInk,
636
+ sm: "30px",
637
+ md: "36px",
638
+ lg: "40px",
639
+ },
640
+ unseenLine: {
641
+ ink: p.pink,
642
+ bg: p.pinkTint,
643
+ line: `url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='8' viewBox='0 0 16 8'><path d='M0 4 Q4 0 8 4 T16 4' fill='none' stroke='${p.pink.replace("#", "%23")}' stroke-width='1.6'/></svg>") repeat-x center / 16px 8px`,
644
+ lineH: "8px",
645
+ lineOpacity: "0.55",
646
+ },
647
+ numberField: {
648
+ stepW: "22px",
649
+ stepInk: p.muted,
650
+ stepHoverBg: p.lav,
651
+ stepHoverInk: p.primary,
652
+ },
653
+ adjustRow: {
654
+ swatchBorder: p.lav2,
655
+ valueInk: p.muted,
656
+ hintInk: p.muted,
657
+ changedInk: p.primary,
658
+ backInk: p.muted,
659
+ backHoverBg: p.lav,
502
660
  },
503
661
  rowButton: {
504
662
  size: "24px",
@@ -575,22 +733,102 @@
575
733
  },
576
734
  };
577
735
 
578
- const look = (id, label, scheme, palette) => ({
579
- id,
580
- label,
581
- scheme,
582
- palette,
583
- meaning: meaningOf(palette),
584
- aliases: aliasesOf(palette),
585
- elevation: elevationOf(palette),
586
- canvas: canvasOf(palette),
587
- shape,
588
- type,
589
- motion,
590
- elements: elementsOf(palette),
591
- });
736
+ const look = (id, label, scheme, palette, wants = {}) => {
737
+ const elements = elementsOf(palette);
738
+ for (const [group, parts] of Object.entries(wants.elements ? wants.elements(palette) : {})) elements[group] = { ...(elements[group] || {}), ...parts };
739
+ return {
740
+ id,
741
+ label,
742
+ scheme,
743
+ palette,
744
+ meaning: meaningOf(palette),
745
+ aliases: aliasesOf(palette),
746
+ elevation: { ...elevationOf(palette), ...(wants.elevation || {}) },
747
+ canvas: { ...canvasOf(palette), ...(wants.canvas ? wants.canvas(palette) : {}) },
748
+ shape: { ...shape, ...(wants.shape || {}) },
749
+ type: { ...type, ...(wants.type || {}) },
750
+ motion: { ...motion, ...(wants.motion || {}) },
751
+ elements,
752
+ };
753
+ };
592
754
 
593
- const looks = { pop: look("pop", "Pop", "light", pop) };
755
+ const flat = Object.fromEntries(Object.keys(elevationOf(pop)).map((key) => [key, "none"]));
756
+
757
+ const looks = {
758
+ classic: look("classic", "VibeClassic", "light", pop),
759
+ "classic-dark": look("classic-dark", "VibeClassic Dark", "dark", classicDark, {
760
+ elements: (p) => ({ logoTile: { bg: p.lav, ink: p.ink, badgeBg: p.lav, badgeInk: p.ink }, bubble: { border: mix(p.white, p.ink, 0.14) } }),
761
+ }),
762
+ clay: look("clay", "Clay", "light", clay, {
763
+ type: { font: '"Inter", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
764
+ canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
765
+ elements: (p) => ({ btn: { hoverInk: p.primaryDeep }, iconButton: { hoverInk: p.primaryDeep }, badge: { ink: p.primaryDeep }, chip: { ink: p.primaryDeep }, toolCall: { pendingInk: p.primaryDeep }, toolFold: { hoverInk: p.primaryDeep }, numberField: { stepHoverInk: p.primaryDeep } }),
766
+ }),
767
+ comfort: look("comfort", "Eye Comfort", "light", comfort, {
768
+ type: { font: '"Open Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif', lineHeight: "1.6" },
769
+ canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
770
+ elevation: { shadowPrimary: "none", shadowGlow: "none" },
771
+ elements: (p) => ({
772
+ code: { headBg: alpha(p.ink, 0.04), headBtnBg: alpha(p.ink, 0.08), headBtnInk: p.ink, bodyBg: alpha(p.ink, 0.02), sbTrack: alpha(p.ink, 0.06), sbThumb: alpha(p.ink, 0.3) },
773
+ bubble: { mineBg: `linear-gradient(135deg, ${p.primaryLight}, ${p.primaryDeep})`, shadow: `0 1px 2px ${alpha(p.ink, 0.06)}`, mineShadow: "none" },
774
+ logoTile: { bg: p.white, ink: p.ink },
775
+ }),
776
+ }),
777
+ plush: look("plush", "3D clayful", "light", plush, {
778
+ shape: { rScale: "1.6" },
779
+ canvas: (p) => ({
780
+ gradCanvas: `radial-gradient(720px 480px at 100% 100%, ${alpha(p.ember, 0.14)}, transparent 70%), radial-gradient(640px 420px at 0% 0%, ${alpha(p.primaryLight, 0.16)}, transparent 70%), linear-gradient(165deg, ${p.canvasTop} 0%, ${p.canvasMid} 55%, ${p.canvasBottom} 100%)`,
781
+ canvasPattern: "none",
782
+ canvasPatternSize: "0 0",
783
+ }),
784
+ elevation: (() => {
785
+ const p = plush;
786
+ const warm = (a) => alpha(p.shadowInk, a);
787
+ const light = (a) => alpha(p.white, a);
788
+ const dark = (a) => alpha(p.black, a);
789
+ const puff = `inset 0 1.5px 2px ${light(0.95)}, inset 1px 0 1px ${light(0.5)}, inset 0 -4px 5px -2px ${warm(0.2)}, inset -1px 0 2px -1px ${warm(0.08)}, 0 0 0 1px ${warm(0.07)}, 0 1px 2px ${warm(0.14)}, 0 6px 12px -4px ${warm(0.3)}`;
790
+ const tinted = `inset 0 1.5px 2px ${light(0.6)}, inset 1px 0 1px ${light(0.35)}, inset 0 -4px 5px -2px ${dark(0.16)}, inset -1px 0 2px -1px ${dark(0.06)}, 0 0 0 1px ${warm(0.08)}, 0 1px 2px ${warm(0.16)}, 0 6px 12px -4px ${warm(0.32)}`;
791
+ const panel = `inset 0 2px 4px ${light(0.95)}, inset 0 -8px 12px -3px ${warm(0.18)}, inset 2px 0 3px -1px ${light(0.5)}, 0 3px 6px ${warm(0.1)}, 0 16px 32px -8px ${warm(0.28)}`;
792
+ const frame = `inset 0 2px 4px ${light(0.95)}, inset 0 -10px 14px -4px ${warm(0.2)}, 0 6px 10px ${warm(0.12)}, 0 30px 60px -16px ${warm(0.4)}`;
793
+ const sunk = `inset 0 3px 6px ${warm(0.18)}, inset 0 -1px 2px ${light(0.8)}`;
794
+ const lifted = `inset 0 1.5px 2px ${light(0.95)}, inset 1px 0 1px ${light(0.5)}, inset 0 -4px 5px -2px ${warm(0.2)}, inset -1px 0 2px -1px ${warm(0.08)}, 0 0 0 1px ${warm(0.07)}, 0 2px 4px ${warm(0.16)}, 0 10px 18px -5px ${warm(0.34)}`;
795
+ return {
796
+ edge: panel, shadowTile: puff, shadowPop: panel, shadowPrimary: tinted, shadowDialog: frame,
797
+ shadowInset: sunk, shadowCtl: sunk, shadowCtlHover: lifted, shadowCard: panel, shadowSoft: tinted,
798
+ shadow: puff, shadow1: panel, shadow2: frame, shadowGlow: tinted,
799
+ bevel: `linear-gradient(180deg, ${light(0.3)} 0%, ${light(0)} 45%)`,
800
+ shadowRoom: "20px",
801
+ };
802
+ })(),
803
+ elements: (p) => ({
804
+ bubble: {
805
+ shadow: `inset 0 2px 3px ${alpha(p.white, 0.95)}, inset 2px 0 2px -1px ${alpha(p.white, 0.6)}, inset 0 -6px 8px -2px ${alpha(p.shadowInk, 0.2)}, inset -2px 0 4px -2px ${alpha(p.shadowInk, 0.1)}, 0 2px 4px ${alpha(p.shadowInk, 0.12)}, 0 10px 18px -4px ${alpha(p.shadowInk, 0.26)}`,
806
+ bg: p.soft,
807
+ mineBg: p.primary,
808
+ mineCtaInk: p.primaryDark,
809
+ mineShadow: `inset 0 2px 3px ${alpha(p.white, 0.6)}, inset 2px 0 2px -1px ${alpha(p.white, 0.35)}, inset 0 -6px 8px -2px ${alpha(p.black, 0.16)}, inset -2px 0 4px -2px ${alpha(p.black, 0.06)}, 0 2px 4px ${alpha(p.shadowInk, 0.14)}, 0 10px 18px -4px ${alpha(p.shadowInk, 0.3)}`,
810
+ },
811
+ input: { shadow: `inset 0 3px 6px ${alpha(p.shadowInk, 0.18)}, inset 0 -1px 2px ${alpha(p.white, 0.8)}` },
812
+ logoTile: { bg: p.soft, badgeBg: p.soft },
813
+ face: { tint: "34%", corner: "0.2" },
814
+ btn: { hoverInk: p.primaryDark }, iconButton: { hoverInk: p.primaryDark }, badge: { ink: p.primaryDark }, chip: { ink: p.primaryDark }, toolCall: { pendingInk: p.primaryDark }, toolFold: { hoverInk: p.primaryDark }, numberField: { stepHoverInk: p.primaryDark },
815
+ }),
816
+ }),
817
+ terminal: look("terminal", "Terminal", "dark", terminal, {
818
+ shape: { rScale: "0" },
819
+ type: { font: type.mono },
820
+ motion: { tFast: "0ms", tBase: "0ms", tSlow: "0ms" },
821
+ elevation: flat,
822
+ canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
823
+ elements: (p) => ({
824
+ roomMark: { ink: p.ink, gradFrom: "38% 24%", gradTo: "34% 18%", emoji: "35% 20%" },
825
+ tile: { badgeBg: p.lav2 },
826
+ logoTile: { bg: p.lav2, ink: p.primary, badgeBg: p.lav2, badgeBorder: p.lav2, badgeInk: p.primary },
827
+ bubble: { border: p.lav2, shadow: "none", mineShadow: "none" },
828
+ unseenLine: { ink: p.muted, bg: p.soft, line: `repeating-linear-gradient(90deg, ${p.lav2} 0 6px, transparent 6px 12px)`, lineH: "1px", lineOpacity: "1" },
829
+ }),
830
+ }),
831
+ };
594
832
 
595
833
  const FLAT = ["palette", "meaning", "aliases", "elevation", "canvas", "shape", "type", "motion"];
596
834
  const kebab = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([a-zA-Z])(\d)/g, "$1-$2").toLowerCase();
@@ -616,5 +854,53 @@
616
854
  return Object.fromEntries(cssGroups(theme).flatMap((g) => g.entries));
617
855
  }
618
856
 
619
- globalThis.VIBEROOM_TOKENS = { looks, current: looks.pop, diagrams, cssGroups, cssVars, alpha, mix, kebab };
857
+ const active = () => looks[globalThis.document?.documentElement?.dataset?.look] || looks.classic;
858
+
859
+ const toHsl = (hex) => {
860
+ const [r, g, b] = rgb(hex).map((v) => v / 255);
861
+ const max = Math.max(r, g, b), min = Math.min(r, g, b), l = (max + min) / 2;
862
+ if (max === min) return [0, 0, l];
863
+ const d = max - min;
864
+ const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
865
+ const h = max === r ? ((g - b) / d + (g < b ? 6 : 0)) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
866
+ return [h * 60, s, l];
867
+ };
868
+ const fromHsl = (h, s, l) => {
869
+ const k = (n) => (n + h / 30) % 12;
870
+ const a = s * Math.min(l, 1 - l);
871
+ const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
872
+ return `#${[f(0), f(8), f(4)].map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("")}`;
873
+ };
874
+ const deepFill = (hex) => { const [h, s] = toHsl(hex); return fromHsl(h, s < 0.1 ? 0 : Math.min(0.45, Math.max(0.25, s)), 0.24); };
875
+ const litLine = (hex) => { const [h, s, l] = toHsl(hex); return fromHsl(h, s, Math.max(l, 0.62)); };
876
+ const DIAGRAM_FILLS = ["primaryColor", "secondaryColor", "tertiaryColor", "clusterBkg", "noteBkgColor", "edgeLabelBackground"];
877
+ const DIAGRAM_INKS = ["primaryTextColor", "textColor"];
878
+ const DIAGRAM_LINES = ["lineColor"];
879
+ diagrams.forScheme = (preset, scheme, ink) => {
880
+ if (scheme !== "dark") return preset;
881
+ const out = { ...preset };
882
+ for (const key of DIAGRAM_FILLS) if (out[key]) out[key] = deepFill(out[key]);
883
+ for (const key of DIAGRAM_INKS) if (out[key]) out[key] = ink;
884
+ for (const key of DIAGRAM_LINES) if (out[key]) out[key] = litLine(out[key]);
885
+ if (out.palette) out.palette = out.palette.map((c) => ({ fill: deepFill(c.fill), stroke: litLine(c.stroke) }));
886
+ return out;
887
+ };
888
+
889
+ const hexOr = (value, fallback) => (/^#[0-9a-f]{6}$/i.test(value) ? value : fallback);
890
+ const adjustables = [
891
+ { key: "canvas", group: "Paper", label: "Chat paper", hint: "behind the messages", kind: "colour", of: (l) => l.palette.bg, vars: (v) => ({ "--grad-canvas": v, "--grad-page": v, "--canvas-pattern": "none" }) },
892
+ { key: "panel", group: "Paper", label: "Panels", hint: "the rooms, the roster, the chat's frame, a vibemate's panel", kind: "colour", of: (l) => l.aliases.panel, vars: (v) => ({ "--panel": v }) },
893
+ { key: "bubble", group: "Bubbles", label: "Reply bubble", kind: "colour", of: (l) => l.elements.bubble.bg, vars: (v) => ({ "--bubble-bg": v }) },
894
+ { key: "mine", group: "Bubbles", label: "Your bubble", kind: "colour", of: (l) => l.palette.primary, vars: (v) => ({ "--bubble-mine-bg": v }) },
895
+ { key: "ring", group: "Bubbles", label: "Bubble outline", hint: "a hairline around a reply; the bubble's own colour hides it", kind: "colour", of: (l) => hexOr(l.elements.bubble.border, l.elements.bubble.bg), vars: (v) => ({ "--bubble-border": v }) },
896
+ { key: "ink", group: "Ink", label: "Words", kind: "colour", of: (l) => l.palette.ink, vars: (v) => ({ "--ink": v, "--ink-2": v, "--bubble-ink": v }) },
897
+ { key: "muted", group: "Ink", label: "Quiet words", hint: "times, hints, labels", kind: "colour", of: (l) => l.palette.muted, vars: (v) => ({ "--muted": v, "--faint": v }) },
898
+ { key: "accent", group: "Ink", label: "Accent", hint: "buttons, links, the ring on your face", kind: "colour", of: (l) => l.palette.primary, vars: (v) => ({ "--primary": v, "--grad-primary": `linear-gradient(135deg, ${v}, ${v})` }) },
899
+ { key: "face", group: "Marks", label: "Face tile", hint: "the paper a face's colour is tinted into", kind: "colour", of: (l) => l.elements.face.paper, vars: (v) => ({ "--face-paper": v }) },
900
+ { key: "logo", group: "Marks", label: "Logo tile", hint: "behind a vendor's mark", kind: "colour", of: (l) => l.elements.logoTile.bg, vars: (v) => ({ "--logo-tile-bg": v, "--logo-tile-badge-bg": v }) },
901
+ { key: "logoInk", group: "Marks", label: "Logo ink", hint: "the mark itself", kind: "colour", of: (l) => l.elements.logoTile.ink, vars: (v) => ({ "--logo-tile-ink": v, "--logo-tile-badge-ink": v }) },
902
+ { key: "corners", group: "Shape", label: "Corners", hint: "0 is square; every corner in the window scales with it", kind: "scale", min: 0, max: 1.5, step: 0.05, of: (l) => l.shape.rScale, vars: (v) => ({ "--r-scale": v }) },
903
+ ];
904
+
905
+ globalThis.VIBEROOM_TOKENS = { looks, current: looks.classic, active, diagrams, adjustables, cssGroups, cssVars, alpha, mix, kebab };
620
906
  })();
package/ui/ui.js CHANGED
@@ -47,9 +47,11 @@
47
47
  if (!/^[a-z][a-z0-9-]*$/.test(name)) throw new Error(`a UI type is named in lower-case words joined by dashes, not "${name}"`);
48
48
  if (registry.has(name)) throw new Error(`the UI type "${name}" is defined twice`);
49
49
  if (typeof spec.build !== "function") throw new Error(`the UI type "${name}" has no build function`);
50
+ if (!spec.group) throw new Error(`the UI type "${name}" names no token group`);
50
51
  registry.set(name, {
51
52
  name,
52
53
  describe: spec.describe || "",
54
+ group: spec.group,
53
55
  props: spec.props || {},
54
56
  build: spec.build,
55
57
  states: spec.states && spec.states.length ? spec.states : ["rest"],