viberoom 0.6.1 → 0.8.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.
- package/NOTICE +14 -0
- package/README.md +11 -0
- package/dist/hub.js +101 -14
- package/dist/look-lint.js +180 -0
- package/dist/looks.js +151 -0
- package/dist/mcp-skills-server.js +87 -0
- package/dist/persona.js +2 -0
- package/dist/room.js +134 -4
- package/dist/server.js +70 -0
- package/dist/skills.js +23 -2
- package/package.json +1 -1
- package/ui/app.css +142 -114
- package/ui/app.js +423 -102
- package/ui/avatars.js +7 -14
- package/ui/components.css +156 -80
- package/ui/components.js +207 -1
- package/ui/fonts/anonymous-pro-cyrillic-400.woff2 +0 -0
- package/ui/fonts/anonymous-pro-cyrillic-700.woff2 +0 -0
- package/ui/fonts/anonymous-pro-latin-400.woff2 +0 -0
- package/ui/fonts/anonymous-pro-latin-700.woff2 +0 -0
- package/ui/fonts/anonymous-pro-latin-ext-400.woff2 +0 -0
- package/ui/fonts/anonymous-pro-latin-ext-700.woff2 +0 -0
- package/ui/fonts/anonymous-pro.css +7 -0
- package/ui/fonts/cascadia-code-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/cascadia-code-cyrillic.woff2 +0 -0
- package/ui/fonts/cascadia-code-latin-ext.woff2 +0 -0
- package/ui/fonts/cascadia-code-latin.woff2 +0 -0
- package/ui/fonts/cascadia-code.css +5 -0
- package/ui/fonts/comfortaa-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/comfortaa-cyrillic.woff2 +0 -0
- package/ui/fonts/comfortaa-latin-ext.woff2 +0 -0
- package/ui/fonts/comfortaa-latin.woff2 +0 -0
- package/ui/fonts/comfortaa.css +5 -0
- package/ui/fonts/exo-2-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/exo-2-cyrillic.woff2 +0 -0
- package/ui/fonts/exo-2-latin-ext.woff2 +0 -0
- package/ui/fonts/exo-2-latin.woff2 +0 -0
- package/ui/fonts/exo-2.css +5 -0
- package/ui/fonts/golos-text-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/golos-text-cyrillic.woff2 +0 -0
- package/ui/fonts/golos-text-latin-ext.woff2 +0 -0
- package/ui/fonts/golos-text-latin.woff2 +0 -0
- package/ui/fonts/golos-text.css +5 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-ext-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-ext-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-cyrillic-ext-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-ext-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-ext-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono-latin-ext-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-mono.css +13 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-ext-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-ext-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-cyrillic-ext-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-ext-400.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-ext-600.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans-latin-ext-700.woff2 +0 -0
- package/ui/fonts/ibm-plex-sans.css +13 -0
- package/ui/fonts/manrope-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/manrope-cyrillic.woff2 +0 -0
- package/ui/fonts/manrope-latin-ext.woff2 +0 -0
- package/ui/fonts/manrope-latin.woff2 +0 -0
- package/ui/fonts/manrope.css +5 -0
- package/ui/fonts/montserrat-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/montserrat-cyrillic.woff2 +0 -0
- package/ui/fonts/montserrat-latin-ext.woff2 +0 -0
- package/ui/fonts/montserrat-latin.woff2 +0 -0
- package/ui/fonts/montserrat.css +5 -0
- package/ui/fonts/open-sans-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/open-sans-cyrillic.woff2 +0 -0
- package/ui/fonts/open-sans-latin-ext.woff2 +0 -0
- package/ui/fonts/open-sans-latin.woff2 +0 -0
- package/ui/fonts/open-sans.css +5 -0
- package/ui/fonts/pt-mono-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/pt-mono-cyrillic.woff2 +0 -0
- package/ui/fonts/pt-mono-latin-ext.woff2 +0 -0
- package/ui/fonts/pt-mono-latin.woff2 +0 -0
- package/ui/fonts/pt-mono.css +5 -0
- package/ui/fonts/rubik-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/rubik-cyrillic.woff2 +0 -0
- package/ui/fonts/rubik-latin-ext.woff2 +0 -0
- package/ui/fonts/rubik-latin.woff2 +0 -0
- package/ui/fonts/rubik.css +5 -0
- package/ui/fonts/source-sans-3-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/source-sans-3-cyrillic.woff2 +0 -0
- package/ui/fonts/source-sans-3-latin-ext.woff2 +0 -0
- package/ui/fonts/source-sans-3-latin.woff2 +0 -0
- package/ui/fonts/source-sans-3.css +5 -0
- package/ui/fonts/ubuntu-sans-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/ubuntu-sans-cyrillic.woff2 +0 -0
- package/ui/fonts/ubuntu-sans-latin-ext.woff2 +0 -0
- package/ui/fonts/ubuntu-sans-latin.woff2 +0 -0
- package/ui/fonts/ubuntu-sans.css +5 -0
- package/ui/fonts/victor-mono-cyrillic-ext.woff2 +0 -0
- package/ui/fonts/victor-mono-cyrillic.woff2 +0 -0
- package/ui/fonts/victor-mono-latin-ext.woff2 +0 -0
- package/ui/fonts/victor-mono-latin.woff2 +0 -0
- package/ui/fonts/victor-mono.css +5 -0
- package/ui/index.html +16 -6
- package/ui/looks.css +2831 -0
- package/ui/manifest.json +3 -3
- package/ui/theme.css +203 -96
- package/ui/tokens.js +800 -45
- package/ui/ui.js +2 -0
package/ui/tokens.js
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
const at = (u, v) => Math.round(u + (v - u) * t);
|
|
16
16
|
return `#${[at(x, i), at(y, j), at(z, k)].map((v) => v.toString(16).padStart(2, "0")).join("")}`;
|
|
17
17
|
};
|
|
18
|
+
const NO_SHADOW = "0 0 0 0 transparent";
|
|
18
19
|
|
|
19
20
|
const pop = {
|
|
20
21
|
primary: "#5b5bf0",
|
|
@@ -27,7 +28,7 @@
|
|
|
27
28
|
ink2: "#2c2b4a",
|
|
28
29
|
ink3: "#5c5c80",
|
|
29
30
|
indigo: "#1f1d3a",
|
|
30
|
-
muted: "#
|
|
31
|
+
muted: "#8080a3",
|
|
31
32
|
faint: "#b3b3cc",
|
|
32
33
|
placeholder: "#a3a3c0",
|
|
33
34
|
grey: "#9ca3af",
|
|
@@ -50,7 +51,7 @@
|
|
|
50
51
|
green: "#2fc97e",
|
|
51
52
|
warm: "#fff3cc",
|
|
52
53
|
warm2: "#ffeaa8",
|
|
53
|
-
warmInk: "#
|
|
54
|
+
warmInk: "#a07408",
|
|
54
55
|
bronze: "#5a4200",
|
|
55
56
|
amber: "#f5a524",
|
|
56
57
|
honey: "#ffcf8f",
|
|
@@ -92,6 +93,116 @@
|
|
|
92
93
|
magenta: "#f2b8ff",
|
|
93
94
|
};
|
|
94
95
|
|
|
96
|
+
const terminal = {
|
|
97
|
+
...pop,
|
|
98
|
+
primary: "#3ddc84", primaryLight: "#5ae69a", primaryDeep: "#2bc472", primaryDark: "#1fa85f",
|
|
99
|
+
violet: "#7ee0ff",
|
|
100
|
+
iris: "#0b0f0c",
|
|
101
|
+
ink: "#d7e3d9", ink2: "#c3d1c6", ink3: "#9fb3a5", indigo: "#e6f0e8",
|
|
102
|
+
muted: "#7c9282", faint: "#5b6f61", placeholder: "#5b6f61", grey: "#6f8276",
|
|
103
|
+
white: "#0f1411", black: "#000000",
|
|
104
|
+
bg: "#090c0a", soft: "#131a15", softer: "#10160f", lav: "#172019", lav2: "#1f2b22",
|
|
105
|
+
canvasTop: "#0a0d0b", canvasMid: "#090c0a", canvasBottom: "#080a09",
|
|
106
|
+
shadowInk: "#000000",
|
|
107
|
+
mint: "#123a26", mint2: "#164a30", mintTint: "#0f2e1f", mintInk: "#3ddc84", forest: "#8fe3bd", green: "#3ddc84",
|
|
108
|
+
warm: "#3a2f0c", warm2: "#4a3d10", warmInk: "#f5c542", bronze: "#ffe08a", amber: "#f5c542", honey: "#f5c542", spark: "#ffd166",
|
|
109
|
+
peach: "#3a2414", peach2: "#4a2d18", orange: "#ff9a3d", orangeLight: "#ffab5c", orangeDeep: "#e8782a", orangeDark: "#ffb36b", ember: "#ff8a45", emberDeep: "#f0602c",
|
|
110
|
+
rose: "#3a1512", rose2: "#4a1a16", roseInk: "#ff6b5e", roseDark: "#ff8578", pink: "#ff7ab8", pinkTint: "#2e1420",
|
|
111
|
+
sky: "#0f2a3a", blue: "#5ab0ff", blueDeep: "#7cc0ff", blueSoft: "#8cc8ff",
|
|
112
|
+
orchid: "#2a1a3a", orchidInk: "#c79bff", orchidMid: "#b58cf0",
|
|
113
|
+
periwinkle: "#233126", periwinkleDeep: "#2f4234",
|
|
114
|
+
deep: "#050705", deepGutter: "#0a0d0b", deepInk: "#d7e3d9", deepMuted: "#5b6f61", deepHead: "#c3d1c6", deepMeta: "#7c9282",
|
|
115
|
+
lavGrey: "#5f7a67", lilac: "#7ee0ff", seafoam: "#3ddc84", azure: "#5ab0ff", salmon: "#ff8578", magenta: "#ff7ab8",
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const classicDark = {
|
|
119
|
+
...pop,
|
|
120
|
+
primary: "#8a8aff", primaryLight: "#9c9cff", primaryDeep: "#7474f7", primaryDark: "#6262e6",
|
|
121
|
+
violet: "#b39cff",
|
|
122
|
+
iris: "#202142",
|
|
123
|
+
ink: "#f1efff", ink2: "#e0deff", ink3: "#c0bde6", indigo: "#f6f4ff",
|
|
124
|
+
muted: "#a4a2cc", faint: "#8583b0", placeholder: "#7f7dab", grey: "#8e90b0",
|
|
125
|
+
white: "#202142", black: "#000000",
|
|
126
|
+
bg: "#0f1024", soft: "#262848", softer: "#232445", lav: "#2c2e56", lav2: "#3a3c6e",
|
|
127
|
+
canvasTop: "#141530", canvasMid: "#111226", canvasBottom: "#0e0f21",
|
|
128
|
+
shadowInk: "#000000",
|
|
129
|
+
mint: "#1a4235", mint2: "#205241", mintTint: "#173a2f", mintInk: "#6ee8b3", forest: "#a8ecc9", green: "#4bdc98",
|
|
130
|
+
warm: "#46381a", warm2: "#54441e", warmInk: "#f5c94f", bronze: "#ffe08a", amber: "#f5b73a", honey: "#f5c974", spark: "#ffd166",
|
|
131
|
+
peach: "#3f2a1a", peach2: "#4a3020", orange: "#ff9a4d", orangeLight: "#ffab66", orangeDeep: "#f07c34", orangeDark: "#ffb36b", ember: "#ff8a55", emberDeep: "#f0603c",
|
|
132
|
+
rose: "#401c1e", rose2: "#4d2325", roseInk: "#ff7a70", roseDark: "#ff8f86", pink: "#ff8ac4", pinkTint: "#351a2a",
|
|
133
|
+
sky: "#1a2e46", blue: "#6aa4ff", blueDeep: "#8cb8ff", blueSoft: "#9fc4ff",
|
|
134
|
+
orchid: "#2e2140", orchidInk: "#c9a3ff", orchidMid: "#b48cf0",
|
|
135
|
+
periwinkle: "#34365c", periwinkleDeep: "#40437a",
|
|
136
|
+
deep: "#0f1020", deepGutter: "#0b0c1a", deepInk: "#f4f2ff", deepMuted: "#7c78ad", deepHead: "#e8e6ff", deepMeta: "#a9a5d8",
|
|
137
|
+
lavGrey: "#7c78ad", lilac: "#b9a7ff", seafoam: "#8fe3bd", azure: "#9cd2ff", salmon: "#ff9f9f", magenta: "#f2b8ff",
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
const clay = {
|
|
141
|
+
...pop,
|
|
142
|
+
primary: "#d97757", primaryLight: "#e08a6d", primaryDeep: "#c4633f", primaryDark: "#a8502f",
|
|
143
|
+
violet: "#9d76c4",
|
|
144
|
+
iris: "#d97757",
|
|
145
|
+
ink: "#1f1e1d", ink2: "#3d3929", ink3: "#5e5a4f", indigo: "#2a2622",
|
|
146
|
+
muted: "#8a8577", faint: "#b3ada0", placeholder: "#a39e90", grey: "#9c988c",
|
|
147
|
+
white: "#ffffff", black: "#000000",
|
|
148
|
+
bg: "#f0eee6", soft: "#f7f5ef", softer: "#f3f0e8", lav: "#ebe7db", lav2: "#dfd9c8",
|
|
149
|
+
canvasTop: "#faf9f5", canvasMid: "#f5f3ec", canvasBottom: "#efece3",
|
|
150
|
+
shadowInk: "#4a3f2a",
|
|
151
|
+
mint: "#dff0e1", mint2: "#cfe6d2", mintTint: "#e8f3e9", mintInk: "#2f7a4f", forest: "#1f5a3a", green: "#4caf77",
|
|
152
|
+
warm: "#fbeecf", warm2: "#f6e2a8", warmInk: "#9a6b0f", bronze: "#5a4200", amber: "#d99a2b", honey: "#f2cc8f", spark: "#f0c96b",
|
|
153
|
+
peach: "#fbe3d3", peach2: "#f8d9c4", orange: "#e67e3c", orangeLight: "#ee9256", orangeDeep: "#cf6a2c", orangeDark: "#a8502f", ember: "#e07a4d", emberDeep: "#c9553a",
|
|
154
|
+
rose: "#f9e3df", rose2: "#f4d3cd", roseInk: "#c24d43", roseDark: "#a13d34", pink: "#b0356f", pinkTint: "#fbeef3",
|
|
155
|
+
sky: "#e0ecf5", blue: "#4a7fb5", blueDeep: "#35618c", blueSoft: "#7ea6d0",
|
|
156
|
+
orchid: "#ece3f2", orchidInk: "#7a4fa3", orchidMid: "#9d76c4",
|
|
157
|
+
periwinkle: "#d8d4e6", periwinkleDeep: "#bdb7d6",
|
|
158
|
+
deep: "#2b2622", deepGutter: "#241f1c", deepInk: "#f5f1e8", deepMuted: "#8c8477", deepHead: "#efe9dc", deepMeta: "#b8b0a0",
|
|
159
|
+
lavGrey: "#cfc8b8", lilac: "#c3b1ff", seafoam: "#9ad8b6", azure: "#a9cbe8", salmon: "#f2a79a", magenta: "#e5b3e0",
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const comfort = {
|
|
163
|
+
...pop,
|
|
164
|
+
primary: "#2f6f68", primaryLight: "#3d7f78", primaryDeep: "#275e58", primaryDark: "#1f4d48",
|
|
165
|
+
violet: "#5e6b8c",
|
|
166
|
+
iris: "#2f6f68",
|
|
167
|
+
ink: "#2b2a27", ink2: "#3a3833", ink3: "#5a574f", indigo: "#2b2a27",
|
|
168
|
+
muted: "#6f6b62", faint: "#8d887c", placeholder: "#9a958a", grey: "#8f8b82",
|
|
169
|
+
white: "#f9f6ef", black: "#000000",
|
|
170
|
+
bg: "#efe9dd", soft: "#f4efe5", softer: "#f1ebe0", lav: "#e8e1d3", lav2: "#dcd3c2",
|
|
171
|
+
canvasTop: "#f2ede3", canvasMid: "#efe9dd", canvasBottom: "#ebe4d6",
|
|
172
|
+
shadowInk: "#4a4438",
|
|
173
|
+
mint: "#e0ebe2", mint2: "#d1e2d5", mintTint: "#e8f0ea", mintInk: "#2f6b4f", forest: "#244f3c", green: "#4f9a72",
|
|
174
|
+
warm: "#f4e9cf", warm2: "#ecdfb9", warmInk: "#7d5f12", bronze: "#5a4200", amber: "#c99a3c", honey: "#7d5f12", spark: "#c9a04f",
|
|
175
|
+
peach: "#f3e2d3", peach2: "#efdac8", orange: "#c2703f", orangeLight: "#cd7f50", orangeDeep: "#a85c30", orangeDark: "#8a4a26", ember: "#b8623a", emberDeep: "#9c4a2a",
|
|
176
|
+
rose: "#f2e0dc", rose2: "#ead2cc", roseInk: "#a34a3f", roseDark: "#8a3d34", pink: "#8f3d6a", pinkTint: "#f2e3ea",
|
|
177
|
+
sky: "#dfe7ee", blue: "#3f6e9a", blueDeep: "#2f587d", blueSoft: "#6f93b8",
|
|
178
|
+
orchid: "#e8e2ec", orchidInk: "#6b4f8c", orchidMid: "#8a6fa8",
|
|
179
|
+
periwinkle: "#d9dbe6", periwinkleDeep: "#b9bdd0",
|
|
180
|
+
deep: "#e9e3d6", deepGutter: "#e1dacb", deepInk: "#2b2a27", deepMuted: "#7a7468", deepHead: "#3a3833", deepMeta: "#6f6b62",
|
|
181
|
+
lavGrey: "#7a7468", lilac: "#5b4a9a", seafoam: "#1f6e5a", azure: "#2a5d8f", salmon: "#a3472f", magenta: "#8a3f7a",
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
const plush = {
|
|
185
|
+
...pop,
|
|
186
|
+
primary: "#917ad8", primaryLight: "#b4a2e6", primaryDeep: "#7f66cc", primaryDark: "#6a54b4",
|
|
187
|
+
violet: "#c9b8f0",
|
|
188
|
+
iris: "#917ad8",
|
|
189
|
+
ink: "#5a3e36", ink2: "#634840", ink3: "#8a6f64", indigo: "#5a3e36",
|
|
190
|
+
muted: "#8f7a6e", faint: "#b3a094", placeholder: "#b8a498", grey: "#b3a094",
|
|
191
|
+
white: "#f9f0e1", black: "#000000",
|
|
192
|
+
bg: "#f4e8ce", soft: "#fdf7ec", softer: "#f4e9d8", lav: "#f1e4d2", lav2: "#e8d7c1",
|
|
193
|
+
canvasTop: "#fbf3e6", canvasMid: "#f7ecdd", canvasBottom: "#f1e5ec",
|
|
194
|
+
shadowInk: "#7a5540",
|
|
195
|
+
mint: "#c9e8c4", mint2: "#b4dfae", mintTint: "#dff1dc", mintInk: "#3f7a4a", forest: "#2f6038", green: "#6fcf7a",
|
|
196
|
+
warm: "#fbe4a4", warm2: "#f7d774", warmInk: "#8a6a1c", bronze: "#5a4200", amber: "#f0c24a", honey: "#f7d774", spark: "#fbe07a",
|
|
197
|
+
peach: "#f9dcc8", peach2: "#f5cbae", orange: "#f0a06a", orangeLight: "#f4b385", orangeDeep: "#e08a50", orangeDark: "#b8673a", ember: "#ec6f9d", emberDeep: "#d8598a",
|
|
198
|
+
rose: "#f7c9d8", rose2: "#f2b3c9", roseInk: "#c2456f", roseDark: "#a63c64", pink: "#d85a8c", pinkTint: "#fbe3ec",
|
|
199
|
+
sky: "#d5f0ec", blue: "#5fbdb3", blueDeep: "#33857c", blueSoft: "#8fd6cf",
|
|
200
|
+
orchid: "#e6dff7", orchidInk: "#6a55b0", orchidMid: "#a893e2",
|
|
201
|
+
periwinkle: "#ded5f3", periwinkleDeep: "#c5b8ea",
|
|
202
|
+
deep: "#4a352e", deepGutter: "#3f2d27", deepInk: "#f9f1e4", deepMuted: "#a58f83", deepHead: "#f0e4d4", deepMeta: "#c2ada0",
|
|
203
|
+
lavGrey: "#cdbfb0", lilac: "#c9b8f0", seafoam: "#8fd6cf", azure: "#9ccbe8", salmon: "#f4b385", magenta: "#f0a0c0",
|
|
204
|
+
};
|
|
205
|
+
|
|
95
206
|
const meaningOf = (p) => ({
|
|
96
207
|
stReady: p.mint, stReadyInk: p.mintInk, stReadyDot: p.green,
|
|
97
208
|
stWaiting: p.sky, stWaitingInk: p.blueDeep, stWaitingDot: p.blueSoft,
|
|
@@ -111,8 +222,6 @@
|
|
|
111
222
|
tickMine: p.periwinkle,
|
|
112
223
|
tickMineView: p.periwinkleDeep,
|
|
113
224
|
tickFallback: p.grey,
|
|
114
|
-
unseenInk: p.pink,
|
|
115
|
-
unseenBg: p.pinkTint,
|
|
116
225
|
});
|
|
117
226
|
|
|
118
227
|
const aliasesOf = (p) => ({
|
|
@@ -161,6 +270,9 @@
|
|
|
161
270
|
shadowInset: "none",
|
|
162
271
|
shadowSoft: edge,
|
|
163
272
|
shadow: edge,
|
|
273
|
+
bevel: "none",
|
|
274
|
+
shadowRoom: "0px",
|
|
275
|
+
bevelPressed: "none",
|
|
164
276
|
};
|
|
165
277
|
};
|
|
166
278
|
|
|
@@ -174,12 +286,46 @@
|
|
|
174
286
|
sbThumbHover: alpha(p.primary, 0.45),
|
|
175
287
|
});
|
|
176
288
|
|
|
289
|
+
const fonts = {
|
|
290
|
+
text: {
|
|
291
|
+
nunito: { label: "Nunito (default)", stack: '"Nunito", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
292
|
+
inter: { label: "Inter", stack: '"Inter", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
293
|
+
"noto-sans": { label: "Noto Sans", stack: '"Noto Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
294
|
+
"open-sans": { label: "Open Sans", stack: '"Open Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
295
|
+
"source-sans-3": { label: "Source Sans 3", stack: '"Source Sans 3", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
296
|
+
"ibm-plex-sans": { label: "IBM Plex Sans", stack: '"IBM Plex Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
297
|
+
manrope: { label: "Manrope", stack: '"Manrope", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
298
|
+
rubik: { label: "Rubik", stack: '"Rubik", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
299
|
+
montserrat: { label: "Montserrat", stack: '"Montserrat", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
300
|
+
"golos-text": { label: "Golos Text", stack: '"Golos Text", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
301
|
+
"exo-2": { label: "Exo 2", stack: '"Exo 2", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
302
|
+
comfortaa: { label: "Comfortaa", stack: '"Comfortaa", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
303
|
+
"ubuntu-sans": { label: "Ubuntu Sans", stack: '"Ubuntu Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
304
|
+
arial: { label: "Arial / Helvetica (system)", stack: 'Arial, Helvetica, "Liberation Sans", sans-serif' },
|
|
305
|
+
system: { label: "System UI font", stack: 'system-ui, -apple-system, "Segoe UI", Roboto, Cantarell, sans-serif' },
|
|
306
|
+
},
|
|
307
|
+
mono: {
|
|
308
|
+
"jetbrains-mono": { label: "JetBrains Mono (default)", stack: '"JetBrains Mono", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
309
|
+
"fira-code": { label: "Fira Code", stack: '"Fira Code", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
310
|
+
"source-code-pro": { label: "Source Code Pro", stack: '"Source Code Pro", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
311
|
+
"ibm-plex-mono": { label: "IBM Plex Mono", stack: '"IBM Plex Mono", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
312
|
+
"pt-mono": { label: "PT Mono", stack: '"PT Mono", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
313
|
+
"victor-mono": { label: "Victor Mono", stack: '"Victor Mono", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
314
|
+
"anonymous-pro": { label: "Anonymous Pro", stack: '"Anonymous Pro", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
315
|
+
"cascadia-code": { label: "Cascadia Code", stack: '"Cascadia Code", ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", monospace' },
|
|
316
|
+
system: { label: "System monospace", stack: 'ui-monospace, Consolas, Menlo, "DejaVu Sans Mono", "Courier New", monospace' },
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
|
|
177
320
|
const shape = {
|
|
178
|
-
|
|
321
|
+
rScale: "1",
|
|
322
|
+
rCtlMin: "0px",
|
|
323
|
+
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
324
|
};
|
|
180
325
|
const type = {
|
|
181
326
|
font: '"Nunito", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif',
|
|
182
327
|
mono: '"JetBrains Mono", ui-monospace, Consolas, "Courier New", monospace',
|
|
328
|
+
lineHeight: "1.45",
|
|
183
329
|
fsScale: "1",
|
|
184
330
|
fsXs: "calc(11px * var(--fs-scale))",
|
|
185
331
|
fsSm: "calc(12px * var(--fs-scale))",
|
|
@@ -194,7 +340,9 @@
|
|
|
194
340
|
easePop: "cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
195
341
|
};
|
|
196
342
|
|
|
197
|
-
const elementsOf = (p) =>
|
|
343
|
+
const elementsOf = (p) => {
|
|
344
|
+
const dangerSolid = `0 8px 18px -8px ${alpha(p.roseInk, 0.8)}`;
|
|
345
|
+
return {
|
|
198
346
|
page: {
|
|
199
347
|
bg: p.bg,
|
|
200
348
|
ink: p.ink,
|
|
@@ -214,6 +362,7 @@
|
|
|
214
362
|
hoverInk: p.primary,
|
|
215
363
|
onPrimary: p.white,
|
|
216
364
|
secondaryBg: p.white,
|
|
365
|
+
secondaryHoverBg: p.white,
|
|
217
366
|
softBg: p.lav,
|
|
218
367
|
softHoverBg: p.lav2,
|
|
219
368
|
ghostInk: p.muted,
|
|
@@ -223,14 +372,14 @@
|
|
|
223
372
|
dangerHoverBg: p.rose2,
|
|
224
373
|
dangerSolidInk: p.white,
|
|
225
374
|
dangerSolidHoverBg: p.roseDark,
|
|
226
|
-
dangerSolidShadow:
|
|
375
|
+
dangerSolidShadow: dangerSolid,
|
|
227
376
|
spinnerTrack: alpha(p.white, 0.5),
|
|
228
377
|
spinnerHead: p.white,
|
|
229
378
|
spinnerTrackQuiet: p.lav2,
|
|
230
379
|
spinnerHeadQuiet: p.primary,
|
|
231
380
|
disabledOpacity: "0.45",
|
|
232
|
-
darkBg: alpha(p.
|
|
233
|
-
darkInk: p.
|
|
381
|
+
darkBg: alpha(p.deepInk, 0.12),
|
|
382
|
+
darkInk: p.deepInk,
|
|
234
383
|
darkHoverBg: p.primary,
|
|
235
384
|
warnInk: p.warmInk,
|
|
236
385
|
warnHoverBg: p.warm,
|
|
@@ -244,6 +393,23 @@
|
|
|
244
393
|
paperBg: p.white,
|
|
245
394
|
paperInk: p.ink3,
|
|
246
395
|
paperHoverBg: p.soft,
|
|
396
|
+
border: "0",
|
|
397
|
+
case: "none",
|
|
398
|
+
tracking: "0px",
|
|
399
|
+
linkUnderline: "none",
|
|
400
|
+
ghostBg: "transparent",
|
|
401
|
+
shadow: "none",
|
|
402
|
+
hoverShadow: "none",
|
|
403
|
+
hoverLift: "0px",
|
|
404
|
+
activeShadow: "none",
|
|
405
|
+
primaryActiveShadow: "var(--shadow-primary)",
|
|
406
|
+
primaryHoverFilter: "brightness(1.05)",
|
|
407
|
+
secondaryHoverShadow: "var(--shadow-tile)",
|
|
408
|
+
secondaryActiveShadow: "var(--shadow-tile)",
|
|
409
|
+
dangerSolidHoverShadow: dangerSolid,
|
|
410
|
+
dangerSolidActiveShadow: dangerSolid,
|
|
411
|
+
okShadow: "none",
|
|
412
|
+
warnShadow: "none",
|
|
247
413
|
h: "42px",
|
|
248
414
|
hSm: "34px",
|
|
249
415
|
hXs: "24px",
|
|
@@ -272,6 +438,14 @@
|
|
|
272
438
|
inlineInk: p.ink3,
|
|
273
439
|
inlineOnBg: alpha(p.primary, 0.1),
|
|
274
440
|
inlineOnInk: p.primary,
|
|
441
|
+
ghostBg: "transparent",
|
|
442
|
+
shadow: "none",
|
|
443
|
+
hoverShadow: "none",
|
|
444
|
+
hoverLift: "0px",
|
|
445
|
+
activeShadow: "none",
|
|
446
|
+
primaryShadow: "var(--shadow-primary)",
|
|
447
|
+
primaryHoverShadow: "var(--shadow-primary)",
|
|
448
|
+
primaryActiveShadow: "var(--shadow-primary)",
|
|
275
449
|
},
|
|
276
450
|
badge: {
|
|
277
451
|
bg: p.lav,
|
|
@@ -281,23 +455,37 @@
|
|
|
281
455
|
mutedBg: p.softer,
|
|
282
456
|
mutedInk: p.muted,
|
|
283
457
|
outlineBorder: p.lav2,
|
|
458
|
+
outlineW: "2px",
|
|
284
459
|
outlineInk: p.muted,
|
|
285
460
|
fsXs: "calc(10px * var(--fs-scale))",
|
|
461
|
+
fill: "100%",
|
|
462
|
+
border: "0",
|
|
463
|
+
case: "none",
|
|
464
|
+
tracking: "0px",
|
|
465
|
+
shadow: "none",
|
|
286
466
|
},
|
|
287
467
|
chip: {
|
|
288
468
|
bg: p.lav,
|
|
289
469
|
ink: p.primary,
|
|
290
470
|
hoverBg: p.lav2,
|
|
471
|
+
fill: "100%",
|
|
472
|
+
border: "0",
|
|
473
|
+
shadow: "none",
|
|
474
|
+
hoverShadow: "none",
|
|
475
|
+
hoverLift: "0px",
|
|
476
|
+
activeShadow: "none",
|
|
477
|
+
activeDrop: "0px",
|
|
291
478
|
},
|
|
292
479
|
fileCard: {
|
|
293
480
|
bg: p.deep,
|
|
294
481
|
ink: p.deepInk,
|
|
295
|
-
headBg: alpha(p.
|
|
482
|
+
headBg: alpha(p.deepInk, 0.06),
|
|
296
483
|
headInk: p.deepHead,
|
|
297
484
|
headMeta: p.deepMeta,
|
|
298
485
|
noteInk: p.roseInk,
|
|
299
|
-
imageBodyBg: alpha(p.
|
|
486
|
+
imageBodyBg: alpha(p.deepInk, 0.04),
|
|
300
487
|
imageBg: p.white,
|
|
488
|
+
shadow: "var(--edge)",
|
|
301
489
|
},
|
|
302
490
|
toolCall: {
|
|
303
491
|
readyBg: p.mint,
|
|
@@ -323,6 +511,7 @@
|
|
|
323
511
|
hoverInk: p.primary,
|
|
324
512
|
failedInk: p.roseInk,
|
|
325
513
|
fs: "calc(11px * var(--fs-scale))",
|
|
514
|
+
shadow: "none",
|
|
326
515
|
},
|
|
327
516
|
askCard: {
|
|
328
517
|
bg: p.warm,
|
|
@@ -333,6 +522,7 @@
|
|
|
333
522
|
kindFs: "calc(11px * var(--fs-scale))",
|
|
334
523
|
inputFs: "calc(11px * var(--fs-scale))",
|
|
335
524
|
outcomeFs: "calc(12px * var(--fs-scale))",
|
|
525
|
+
shadow: "none",
|
|
336
526
|
},
|
|
337
527
|
replyNote: {
|
|
338
528
|
ink: p.muted,
|
|
@@ -341,6 +531,16 @@
|
|
|
341
531
|
attentionBg: p.warm,
|
|
342
532
|
fs: "calc(12px * var(--fs-scale))",
|
|
343
533
|
},
|
|
534
|
+
lookCard: {
|
|
535
|
+
w: "150px",
|
|
536
|
+
paperH: "84px",
|
|
537
|
+
bg: p.white,
|
|
538
|
+
ink: p.ink,
|
|
539
|
+
border: p.lav2,
|
|
540
|
+
hoverBorder: p.periwinkleDeep,
|
|
541
|
+
onBorder: p.primary,
|
|
542
|
+
shadow: "none",
|
|
543
|
+
},
|
|
344
544
|
choice: {
|
|
345
545
|
bg: p.soft,
|
|
346
546
|
ink: p.ink3,
|
|
@@ -349,6 +549,13 @@
|
|
|
349
549
|
onBorder: p.primary,
|
|
350
550
|
quietInk: p.muted,
|
|
351
551
|
h: "32px",
|
|
552
|
+
border: "transparent",
|
|
553
|
+
shadow: "none",
|
|
554
|
+
hoverShadow: "none",
|
|
555
|
+
hoverLift: "0px",
|
|
556
|
+
activeShadow: "none",
|
|
557
|
+
activeDrop: "0px",
|
|
558
|
+
onShadow: "none",
|
|
352
559
|
},
|
|
353
560
|
control: {
|
|
354
561
|
knob: p.white,
|
|
@@ -357,18 +564,19 @@
|
|
|
357
564
|
tick: p.white,
|
|
358
565
|
},
|
|
359
566
|
tile: {
|
|
360
|
-
logoBg: p.white,
|
|
361
567
|
badgeBg: p.white,
|
|
362
|
-
badgeBorder: p.white,
|
|
363
|
-
ring: p.white,
|
|
364
|
-
markInk: p.white,
|
|
365
568
|
countInk: p.white,
|
|
366
569
|
},
|
|
367
570
|
roomMark: {
|
|
571
|
+
ink: p.white,
|
|
368
572
|
gradAngle: "135deg",
|
|
369
573
|
gradFrom: "72% 66%",
|
|
370
574
|
gradTo: "68% 52%",
|
|
371
575
|
emoji: "70% 93%",
|
|
576
|
+
shadow: "none",
|
|
577
|
+
radius: "calc(14px * var(--r-scale))",
|
|
578
|
+
radiusLg: "calc(16px * var(--r-scale))",
|
|
579
|
+
radiusRail: "calc(13px * var(--r-scale))",
|
|
372
580
|
},
|
|
373
581
|
pop: {
|
|
374
582
|
bg: p.white,
|
|
@@ -388,7 +596,7 @@
|
|
|
388
596
|
},
|
|
389
597
|
toast: {
|
|
390
598
|
bg: p.ink,
|
|
391
|
-
ink: p.
|
|
599
|
+
ink: p.white,
|
|
392
600
|
},
|
|
393
601
|
rail: {
|
|
394
602
|
logoShadow: `0 8px 18px -6px ${alpha(p.primary, 0.6)}`,
|
|
@@ -405,6 +613,7 @@
|
|
|
405
613
|
bubble: {
|
|
406
614
|
bg: p.white,
|
|
407
615
|
ink: p.ink2,
|
|
616
|
+
border: "transparent",
|
|
408
617
|
shadow: `0 2px 0 ${alpha(p.ink, 0.06)}, 0 1px 3px ${alpha(p.ink, 0.04)}`,
|
|
409
618
|
mineBg: `linear-gradient(135deg, ${p.primaryLight}, ${p.primaryDeep})`,
|
|
410
619
|
mineInk: p.white,
|
|
@@ -454,21 +663,21 @@
|
|
|
454
663
|
gutterInk: p.deepMuted,
|
|
455
664
|
lineMarkInk: p.honey,
|
|
456
665
|
lineMarkBg: alpha(p.honey, 0.16),
|
|
457
|
-
headBg: alpha(p.
|
|
666
|
+
headBg: alpha(p.deepInk, 0.06),
|
|
458
667
|
headInk: p.deepHead,
|
|
459
668
|
headMeta: p.deepMeta,
|
|
460
|
-
headBtnBg: alpha(p.
|
|
461
|
-
headBtnInk: p.
|
|
462
|
-
bodyBg: alpha(p.
|
|
669
|
+
headBtnBg: alpha(p.deepInk, 0.12),
|
|
670
|
+
headBtnInk: p.deepInk,
|
|
671
|
+
bodyBg: alpha(p.deepInk, 0.04),
|
|
463
672
|
sbTrack: alpha(p.black, 0.25),
|
|
464
|
-
sbThumb: alpha(p.
|
|
465
|
-
sbThumbHover: alpha(p.
|
|
466
|
-
sbFirefox: alpha(p.
|
|
673
|
+
sbThumb: alpha(p.deepInk, 0.3),
|
|
674
|
+
sbThumbHover: alpha(p.deepInk, 0.5),
|
|
675
|
+
sbFirefox: alpha(p.deepInk, 0.35),
|
|
467
676
|
findHitBg: p.honey,
|
|
468
677
|
findHitInk: p.deep,
|
|
469
678
|
},
|
|
470
679
|
syntax: {
|
|
471
|
-
comment: p.
|
|
680
|
+
comment: p.deepMuted,
|
|
472
681
|
punctuation: p.lavGrey,
|
|
473
682
|
keyword: p.lilac,
|
|
474
683
|
string: p.seafoam,
|
|
@@ -486,29 +695,81 @@
|
|
|
486
695
|
input: {
|
|
487
696
|
bg: p.white,
|
|
488
697
|
focusBorder: p.primary,
|
|
698
|
+
shadow: "none",
|
|
489
699
|
},
|
|
490
700
|
profile: {
|
|
491
701
|
bg: `linear-gradient(160deg, ${p.lav}, ${p.mintTint})`,
|
|
492
|
-
avatarBg: p.white,
|
|
493
702
|
badgeBg: p.white,
|
|
494
703
|
},
|
|
495
|
-
|
|
704
|
+
face: {
|
|
705
|
+
paper: p.white,
|
|
706
|
+
tint: "16%",
|
|
707
|
+
corner: "0.32",
|
|
708
|
+
ring: p.white,
|
|
709
|
+
meRing: p.primary,
|
|
710
|
+
dotBg: p.faint,
|
|
711
|
+
cardBg: p.white,
|
|
496
712
|
fallback: p.grey,
|
|
497
713
|
humanInk: p.indigo,
|
|
498
714
|
avatarDefault: p.primary,
|
|
499
715
|
avatarGloss: p.white,
|
|
500
716
|
avatarLabelInk: p.white,
|
|
501
|
-
|
|
717
|
+
shadow: NO_SHADOW,
|
|
718
|
+
cardShadow: "var(--shadow-pop)",
|
|
719
|
+
},
|
|
720
|
+
logoTile: {
|
|
721
|
+
bg: p.white,
|
|
722
|
+
ink: p.indigo,
|
|
723
|
+
badgeBg: p.white,
|
|
724
|
+
badgeBorder: p.white,
|
|
725
|
+
badgeInk: p.indigo,
|
|
726
|
+
mutedBg: p.warm,
|
|
727
|
+
mutedInk: p.warmInk,
|
|
728
|
+
sm: "30px",
|
|
729
|
+
md: "36px",
|
|
730
|
+
lg: "40px",
|
|
731
|
+
shadow: "var(--shadow-tile)",
|
|
732
|
+
radius: "calc(12px * var(--r-scale))",
|
|
733
|
+
radiusSm: "calc(10px * var(--r-scale))",
|
|
734
|
+
radiusLg: "calc(13px * var(--r-scale))",
|
|
735
|
+
radiusBadge: "calc(6px * var(--r-scale))",
|
|
736
|
+
},
|
|
737
|
+
unseenLine: {
|
|
738
|
+
ink: p.pink,
|
|
739
|
+
bg: p.pinkTint,
|
|
740
|
+
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`,
|
|
741
|
+
lineH: "8px",
|
|
742
|
+
lineOpacity: "0.55",
|
|
743
|
+
labelBorder: "0",
|
|
744
|
+
labelCase: "none",
|
|
745
|
+
labelTracking: "0px",
|
|
746
|
+
labelShadow: "none",
|
|
747
|
+
},
|
|
748
|
+
numberField: {
|
|
749
|
+
stepW: "22px",
|
|
750
|
+
stepInk: p.muted,
|
|
751
|
+
stepHoverBg: p.lav,
|
|
752
|
+
stepHoverInk: p.primary,
|
|
753
|
+
},
|
|
754
|
+
adjustRow: {
|
|
755
|
+
swatchBorder: p.lav2,
|
|
756
|
+
valueInk: p.muted,
|
|
757
|
+
hintInk: p.muted,
|
|
758
|
+
changedInk: p.primary,
|
|
759
|
+
backInk: p.muted,
|
|
760
|
+
backHoverBg: p.lav,
|
|
502
761
|
},
|
|
503
762
|
rowButton: {
|
|
504
763
|
size: "24px",
|
|
505
764
|
icon: "14px",
|
|
506
|
-
radius: "8px",
|
|
765
|
+
radius: "calc(8px * var(--r-scale))",
|
|
507
766
|
bg: p.softer,
|
|
508
767
|
ink: p.muted,
|
|
509
768
|
hoverBg: p.primary,
|
|
510
769
|
hoverInk: p.white,
|
|
511
770
|
disabledOpacity: "0.4",
|
|
771
|
+
shadow: "none",
|
|
772
|
+
activeShadow: "none",
|
|
512
773
|
},
|
|
513
774
|
hubRow: {
|
|
514
775
|
ink: p.muted,
|
|
@@ -518,6 +779,9 @@
|
|
|
518
779
|
actionInk: p.mintInk,
|
|
519
780
|
actionHoverBg: p.mint2,
|
|
520
781
|
faceSize: "18px",
|
|
782
|
+
prefix: "none",
|
|
783
|
+
prefixGap: "0px",
|
|
784
|
+
actionShadow: "var(--edge)",
|
|
521
785
|
},
|
|
522
786
|
hero: {
|
|
523
787
|
ink: p.white,
|
|
@@ -541,6 +805,13 @@
|
|
|
541
805
|
feature: {
|
|
542
806
|
emojiBg: alpha(p.white, 0.8),
|
|
543
807
|
peachBg: p.peach2,
|
|
808
|
+
shadow: "var(--edge)",
|
|
809
|
+
},
|
|
810
|
+
composer: {
|
|
811
|
+
shadow: "none",
|
|
812
|
+
bg: "transparent",
|
|
813
|
+
radius: "0px",
|
|
814
|
+
padX: "0px",
|
|
544
815
|
},
|
|
545
816
|
step: {
|
|
546
817
|
bg: p.white,
|
|
@@ -553,7 +824,8 @@
|
|
|
553
824
|
browser: {
|
|
554
825
|
themeColor: p.iris,
|
|
555
826
|
},
|
|
556
|
-
|
|
827
|
+
};
|
|
828
|
+
};
|
|
557
829
|
|
|
558
830
|
const popNodes = [
|
|
559
831
|
{ fill: "#e4e6fb", stroke: "#5b5bf0" },
|
|
@@ -575,22 +847,133 @@
|
|
|
575
847
|
},
|
|
576
848
|
};
|
|
577
849
|
|
|
578
|
-
const look = (id, label, scheme, palette) =>
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
850
|
+
const look = (id, label, scheme, palette, wants = {}) => {
|
|
851
|
+
const elements = elementsOf(palette);
|
|
852
|
+
for (const [group, parts] of Object.entries(wants.elements ? wants.elements(palette) : {})) elements[group] = { ...(elements[group] || {}), ...parts };
|
|
853
|
+
return {
|
|
854
|
+
id,
|
|
855
|
+
label,
|
|
856
|
+
scheme,
|
|
857
|
+
palette,
|
|
858
|
+
meaning: meaningOf(palette),
|
|
859
|
+
aliases: aliasesOf(palette),
|
|
860
|
+
elevation: { ...elevationOf(palette), ...(wants.elevation || {}) },
|
|
861
|
+
canvas: { ...canvasOf(palette), ...(wants.canvas ? wants.canvas(palette) : {}) },
|
|
862
|
+
shape: { ...shape, ...(wants.shape || {}) },
|
|
863
|
+
type: { ...type, ...(wants.type || {}) },
|
|
864
|
+
motion: { ...motion, ...(wants.motion || {}) },
|
|
865
|
+
elements,
|
|
866
|
+
wants,
|
|
867
|
+
custom: false,
|
|
868
|
+
};
|
|
869
|
+
};
|
|
870
|
+
|
|
871
|
+
const flat = Object.fromEntries(Object.keys(elevationOf(pop)).map((key) => [key, "none"]));
|
|
592
872
|
|
|
593
|
-
const looks = {
|
|
873
|
+
const looks = {
|
|
874
|
+
classic: look("classic", "VibeClassic", "light", pop),
|
|
875
|
+
"classic-dark": look("classic-dark", "VibeClassic Dark", "dark", classicDark, {
|
|
876
|
+
elements: (p) => ({ logoTile: { bg: p.lav, ink: p.ink, badgeBg: p.lav, badgeInk: p.ink }, bubble: { border: mix(p.white, p.ink, 0.14) } }),
|
|
877
|
+
}),
|
|
878
|
+
clay: look("clay", "Clay", "light", clay, {
|
|
879
|
+
type: { font: '"Inter", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif' },
|
|
880
|
+
canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
|
|
881
|
+
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 } }),
|
|
882
|
+
}),
|
|
883
|
+
comfort: look("comfort", "Eye Comfort", "light", comfort, {
|
|
884
|
+
type: { font: '"Open Sans", "Segoe UI", system-ui, -apple-system, Roboto, sans-serif', lineHeight: "1.6" },
|
|
885
|
+
canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
|
|
886
|
+
elevation: { shadowPrimary: "none", shadowGlow: "none" },
|
|
887
|
+
elements: (p) => ({
|
|
888
|
+
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) },
|
|
889
|
+
bubble: { mineBg: `linear-gradient(135deg, ${p.primaryLight}, ${p.primaryDeep})`, shadow: `0 1px 2px ${alpha(p.ink, 0.06)}`, mineShadow: "none" },
|
|
890
|
+
logoTile: { bg: p.white, ink: p.ink },
|
|
891
|
+
btn: { darkHoverBg: p.lav2 },
|
|
892
|
+
}),
|
|
893
|
+
}),
|
|
894
|
+
plush: (() => {
|
|
895
|
+
const p = plush;
|
|
896
|
+
const warm = (a) => alpha(p.shadowInk, a);
|
|
897
|
+
const light = (a) => alpha(p.white, a);
|
|
898
|
+
const dark = (a) => alpha(p.black, a);
|
|
899
|
+
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)}`;
|
|
900
|
+
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)}`;
|
|
901
|
+
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)}`;
|
|
902
|
+
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)}`;
|
|
903
|
+
const sunk = `inset 0 3px 6px ${warm(0.18)}, inset 0 -1px 2px ${light(0.8)}`;
|
|
904
|
+
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)}`;
|
|
905
|
+
return look("plush", "3D clayful", "light", plush, {
|
|
906
|
+
shape: { rScale: "1.6", rCtlMin: "var(--r-pill)" },
|
|
907
|
+
canvas: (p) => ({
|
|
908
|
+
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%)`,
|
|
909
|
+
canvasPattern: "none",
|
|
910
|
+
canvasPatternSize: "0 0",
|
|
911
|
+
}),
|
|
912
|
+
elevation: {
|
|
913
|
+
edge: panel, shadowTile: puff, shadowPop: panel, shadowPrimary: tinted, shadowDialog: frame,
|
|
914
|
+
shadowInset: sunk, shadowCtl: sunk, shadowCtlHover: lifted, shadowCard: panel, shadowSoft: tinted,
|
|
915
|
+
shadow: puff, shadow1: panel, shadow2: frame, shadowGlow: tinted,
|
|
916
|
+
bevel: `linear-gradient(180deg, ${light(0.3)} 0%, ${light(0)} 45%)`,
|
|
917
|
+
shadowRoom: "20px",
|
|
918
|
+
},
|
|
919
|
+
elements: (p) => ({
|
|
920
|
+
bubble: {
|
|
921
|
+
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)}`,
|
|
922
|
+
bg: p.soft,
|
|
923
|
+
mineBg: `linear-gradient(${p.primary}, ${p.primary})`,
|
|
924
|
+
mineCtaInk: p.primaryDark,
|
|
925
|
+
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)}`,
|
|
926
|
+
},
|
|
927
|
+
input: { shadow: sunk },
|
|
928
|
+
composer: { shadow: sunk, bg: p.softer, radius: "calc(14px * var(--r-scale))", padX: "12px" },
|
|
929
|
+
logoTile: { bg: p.soft, badgeBg: p.soft, shadow: puff, radius: "calc(8px * var(--r-scale))", radiusSm: "calc(7px * var(--r-scale))", radiusLg: "calc(9px * var(--r-scale))", radiusBadge: "calc(8px * var(--r-scale))" },
|
|
930
|
+
face: { tint: "34%", corner: "0.2", shadow: tinted, cardShadow: tinted },
|
|
931
|
+
btn: {
|
|
932
|
+
hoverInk: p.primaryDark,
|
|
933
|
+
shadow: puff, hoverShadow: lifted, hoverLift: "-1px", activeShadow: sunk,
|
|
934
|
+
primaryActiveShadow: sunk, primaryHoverFilter: "none",
|
|
935
|
+
secondaryHoverShadow: lifted, secondaryActiveShadow: sunk,
|
|
936
|
+
dangerSolidShadow: tinted, dangerSolidHoverShadow: lifted, dangerSolidActiveShadow: sunk,
|
|
937
|
+
okShadow: tinted, warnShadow: tinted,
|
|
938
|
+
ghostBg: p.softer, softBg: p.softer, secondaryBg: p.softer, paperBg: p.softer,
|
|
939
|
+
},
|
|
940
|
+
iconButton: { hoverInk: p.primaryDark, ghostInk: p.muted, shadow: puff, hoverShadow: lifted, hoverLift: "-1px", activeShadow: sunk, primaryShadow: puff, primaryHoverShadow: lifted, primaryActiveShadow: sunk, ghostBg: p.softer },
|
|
941
|
+
rowButton: { shadow: puff, activeShadow: sunk, radius: "8px" },
|
|
942
|
+
badge: { ink: p.primaryDark, shadow: tinted },
|
|
943
|
+
chip: { ink: p.primaryDark, shadow: tinted, hoverShadow: lifted, hoverLift: "-1px", activeShadow: sunk, activeDrop: "1px" },
|
|
944
|
+
choice: { shadow: tinted, hoverShadow: lifted, hoverLift: "-1px", activeShadow: sunk, activeDrop: "1px", onShadow: sunk },
|
|
945
|
+
hubRow: { actionShadow: tinted },
|
|
946
|
+
unseenLine: { labelShadow: tinted },
|
|
947
|
+
lookCard: { shadow: puff },
|
|
948
|
+
fileCard: { shadow: puff },
|
|
949
|
+
askCard: { shadow: puff },
|
|
950
|
+
toolFold: { hoverInk: p.primaryDark, shadow: puff },
|
|
951
|
+
roomMark: { shadow: tinted, radius: "calc(10px * var(--r-scale))", radiusLg: "calc(12px * var(--r-scale))", radiusRail: "calc(10px * var(--r-scale))" },
|
|
952
|
+
feature: { shadow: panel },
|
|
953
|
+
toolCall: { pendingInk: p.primaryDark }, numberField: { stepHoverInk: p.primaryDark },
|
|
954
|
+
}),
|
|
955
|
+
});
|
|
956
|
+
})(),
|
|
957
|
+
terminal: look("terminal", "Terminal", "dark", terminal, {
|
|
958
|
+
shape: { rScale: "0" },
|
|
959
|
+
type: { font: type.mono },
|
|
960
|
+
motion: { tFast: "0ms", tBase: "0ms", tSlow: "0ms" },
|
|
961
|
+
elevation: flat,
|
|
962
|
+
canvas: (p) => ({ gradCanvas: p.bg, canvasPattern: "none", canvasPatternSize: "0 0" }),
|
|
963
|
+
elements: (p) => ({
|
|
964
|
+
roomMark: { ink: p.ink, gradFrom: "38% 24%", gradTo: "34% 18%", emoji: "35% 20%" },
|
|
965
|
+
tile: { badgeBg: p.lav2 },
|
|
966
|
+
logoTile: { bg: p.lav2, ink: p.primary, badgeBg: p.lav2, badgeBorder: p.lav2, badgeInk: p.primary },
|
|
967
|
+
bubble: { border: p.lav2, shadow: NO_SHADOW, mineShadow: NO_SHADOW },
|
|
968
|
+
btn: { border: "1px solid currentColor", case: "uppercase", tracking: "0.06em", linkUnderline: "underline" },
|
|
969
|
+
badge: { fill: "0%", border: "1px solid currentColor", case: "uppercase", tracking: "0.04em", outlineBorder: "currentColor", outlineW: "1px" },
|
|
970
|
+
chip: { fill: "0%", border: "1px solid currentColor" },
|
|
971
|
+
choice: { border: "currentColor", onBorder: "currentColor" },
|
|
972
|
+
hubRow: { prefix: '">"', prefixGap: "6px" },
|
|
973
|
+
unseenLine: { ink: p.muted, bg: "transparent", line: `repeating-linear-gradient(90deg, ${p.lav2} 0 6px, transparent 6px 12px)`, lineH: "1px", lineOpacity: "1", labelBorder: "1px solid currentColor", labelCase: "uppercase", labelTracking: "0.04em" },
|
|
974
|
+
}),
|
|
975
|
+
}),
|
|
976
|
+
};
|
|
594
977
|
|
|
595
978
|
const FLAT = ["palette", "meaning", "aliases", "elevation", "canvas", "shape", "type", "motion"];
|
|
596
979
|
const kebab = (s) => s.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/([a-zA-Z])(\d)/g, "$1-$2").toLowerCase();
|
|
@@ -616,5 +999,377 @@
|
|
|
616
999
|
return Object.fromEntries(cssGroups(theme).flatMap((g) => g.entries));
|
|
617
1000
|
}
|
|
618
1001
|
|
|
619
|
-
|
|
1002
|
+
const active = () => looks[globalThis.document?.documentElement?.dataset?.look] || looks.classic;
|
|
1003
|
+
|
|
1004
|
+
const toHsl = (hex) => {
|
|
1005
|
+
const [r, g, b] = rgb(hex).map((v) => v / 255);
|
|
1006
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b), l = (max + min) / 2;
|
|
1007
|
+
if (max === min) return [0, 0, l];
|
|
1008
|
+
const d = max - min;
|
|
1009
|
+
const s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
1010
|
+
const h = max === r ? ((g - b) / d + (g < b ? 6 : 0)) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
|
|
1011
|
+
return [h * 60, s, l];
|
|
1012
|
+
};
|
|
1013
|
+
const fromHsl = (h, s, l) => {
|
|
1014
|
+
const k = (n) => (n + h / 30) % 12;
|
|
1015
|
+
const a = s * Math.min(l, 1 - l);
|
|
1016
|
+
const f = (n) => l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
|
|
1017
|
+
return `#${[f(0), f(8), f(4)].map((v) => Math.round(v * 255).toString(16).padStart(2, "0")).join("")}`;
|
|
1018
|
+
};
|
|
1019
|
+
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); };
|
|
1020
|
+
const litLine = (hex) => { const [h, s, l] = toHsl(hex); return fromHsl(h, s, Math.max(l, 0.62)); };
|
|
1021
|
+
const DIAGRAM_FILLS = ["primaryColor", "secondaryColor", "tertiaryColor", "clusterBkg", "noteBkgColor", "edgeLabelBackground"];
|
|
1022
|
+
const DIAGRAM_INKS = ["primaryTextColor", "textColor"];
|
|
1023
|
+
const DIAGRAM_LINES = ["lineColor"];
|
|
1024
|
+
diagrams.forScheme = (preset, scheme, ink) => {
|
|
1025
|
+
if (scheme !== "dark") return preset;
|
|
1026
|
+
const out = { ...preset };
|
|
1027
|
+
for (const key of DIAGRAM_FILLS) if (out[key]) out[key] = deepFill(out[key]);
|
|
1028
|
+
for (const key of DIAGRAM_INKS) if (out[key]) out[key] = ink;
|
|
1029
|
+
for (const key of DIAGRAM_LINES) if (out[key]) out[key] = litLine(out[key]);
|
|
1030
|
+
if (out.palette) out.palette = out.palette.map((c) => ({ fill: deepFill(c.fill), stroke: litLine(c.stroke) }));
|
|
1031
|
+
return out;
|
|
1032
|
+
};
|
|
1033
|
+
|
|
1034
|
+
const hexOr = (value, fallback) => (/^#[0-9a-f]{6}$/i.test(value) ? value : fallback);
|
|
1035
|
+
const adjustables = [
|
|
1036
|
+
{ 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" }) },
|
|
1037
|
+
{ 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 }) },
|
|
1038
|
+
{ key: "bubble", group: "Bubbles", label: "Reply bubble", kind: "colour", of: (l) => l.elements.bubble.bg, vars: (v) => ({ "--bubble-bg": v }) },
|
|
1039
|
+
{ key: "mine", group: "Bubbles", label: "Your bubble", kind: "colour", of: (l) => l.palette.primary, vars: (v) => ({ "--bubble-mine-bg": `linear-gradient(${v}, ${v})` }) },
|
|
1040
|
+
{ 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 }) },
|
|
1041
|
+
{ key: "ink", group: "Ink", label: "Words", kind: "colour", of: (l) => l.palette.ink, vars: (v) => ({ "--ink": v, "--ink-2": v, "--bubble-ink": v }) },
|
|
1042
|
+
{ key: "muted", group: "Ink", label: "Quiet words", hint: "times, hints, labels", kind: "colour", of: (l) => l.palette.muted, vars: (v) => ({ "--muted": v, "--faint": v }) },
|
|
1043
|
+
{ 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})` }) },
|
|
1044
|
+
{ 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 }) },
|
|
1045
|
+
{ 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 }) },
|
|
1046
|
+
{ 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 }) },
|
|
1047
|
+
{ 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 }) },
|
|
1048
|
+
];
|
|
1049
|
+
|
|
1050
|
+
|
|
1051
|
+
const SPEC_ID = /^[a-z][a-z0-9-]{0,30}$/;
|
|
1052
|
+
const HEX6 = /^#[0-9a-f]{6}$/i;
|
|
1053
|
+
const COLOUR_VALUE = /^(#[0-9a-f]{6}|#[0-9a-f]{8}|rgba?\([\d\s.,%]+\)|transparent|currentColor)$/i;
|
|
1054
|
+
const UNSAFE = /url\(|expression\(|javascript:|[<>{};\\@]/i;
|
|
1055
|
+
const FONT_STACK = /^[\w\s"',.-]+$/;
|
|
1056
|
+
const isColourDefault = (v) => COLOUR_VALUE.test(String(v).trim());
|
|
1057
|
+
|
|
1058
|
+
const hueOf = (token, palette, where) => {
|
|
1059
|
+
const t = String(token).trim();
|
|
1060
|
+
if (t.startsWith("$")) {
|
|
1061
|
+
const name = t.slice(1);
|
|
1062
|
+
if (!(name in palette)) throw new Error(`${where}: no hue "${name}" in the palette`);
|
|
1063
|
+
return palette[name];
|
|
1064
|
+
}
|
|
1065
|
+
if (HEX6.test(t)) return t.toLowerCase();
|
|
1066
|
+
throw new Error(`${where}: "${t}" is neither a hue of the palette ($name) nor a colour (#rrggbb)`);
|
|
1067
|
+
};
|
|
1068
|
+
const numberIn = (token, where, min, max) => {
|
|
1069
|
+
const n = Number(String(token).trim());
|
|
1070
|
+
if (!Number.isFinite(n) || n < min || n > max) throw new Error(`${where}: "${token}" is not a number between ${min} and ${max}`);
|
|
1071
|
+
return n;
|
|
1072
|
+
};
|
|
1073
|
+
const resolveValue = (raw, palette, where) => {
|
|
1074
|
+
if (typeof raw !== "string") throw new Error(`${where}: a value is a string`);
|
|
1075
|
+
const v = raw.trim();
|
|
1076
|
+
if (!v) throw new Error(`${where}: an empty value`);
|
|
1077
|
+
if (v.length > 400) throw new Error(`${where}: a value is at most 400 characters`);
|
|
1078
|
+
if (UNSAFE.test(v)) throw new Error(`${where}: a value may not carry url(), expression(), javascript: or < > { } ; \\ @`);
|
|
1079
|
+
const out = v
|
|
1080
|
+
.replace(/\b(alpha|mix)\(([^()]*)\)/g, (m, fn, args) => {
|
|
1081
|
+
const parts = args.split(",").map((s) => s.trim());
|
|
1082
|
+
if (fn === "alpha") {
|
|
1083
|
+
if (parts.length !== 2) throw new Error(`${where}: alpha takes a hue and a number: alpha($ink, 0.2)`);
|
|
1084
|
+
return alpha(hueOf(parts[0], palette, where), numberIn(parts[1], where, 0, 1));
|
|
1085
|
+
}
|
|
1086
|
+
if (parts.length !== 3) throw new Error(`${where}: mix takes two hues and a number: mix($white, $ink, 0.5)`);
|
|
1087
|
+
return mix(hueOf(parts[0], palette, where), hueOf(parts[1], palette, where), numberIn(parts[2], where, 0, 1));
|
|
1088
|
+
})
|
|
1089
|
+
.replace(/\$([a-zA-Z][a-zA-Z0-9]*)/g, (m, name) => hueOf(`$${name}`, palette, where));
|
|
1090
|
+
if (/\$/.test(out)) throw new Error(`${where}: a stray $ (a hue is $name)`);
|
|
1091
|
+
return out;
|
|
1092
|
+
};
|
|
1093
|
+
const checked = (defaultValue, value, where) => {
|
|
1094
|
+
if (isColourDefault(defaultValue) && !COLOUR_VALUE.test(value)) throw new Error(`${where}: a colour (the look has ${defaultValue}), not "${value}"`);
|
|
1095
|
+
return value;
|
|
1096
|
+
};
|
|
1097
|
+
const flatSection = (spec, section, defaults, baseWants, palette) => {
|
|
1098
|
+
const out = { ...(baseWants || {}) };
|
|
1099
|
+
for (const [key, raw] of Object.entries(spec || {})) {
|
|
1100
|
+
if (!(key in defaults)) throw new Error(`${section}.${key}: no such token (${Object.keys(defaults).join(", ")})`);
|
|
1101
|
+
out[key] = checked(defaults[key], resolveValue(raw, palette, `${section}.${key}`), `${section}.${key}`);
|
|
1102
|
+
}
|
|
1103
|
+
return out;
|
|
1104
|
+
};
|
|
1105
|
+
|
|
1106
|
+
function make(spec) {
|
|
1107
|
+
if (!spec || typeof spec !== "object" || Array.isArray(spec)) throw new Error("a look spec is an object");
|
|
1108
|
+
const id = String(spec.id ?? "").trim();
|
|
1109
|
+
if (!SPEC_ID.test(id)) throw new Error("id: a short lower-case id of letters, digits and hyphens (1-31), starting with a letter");
|
|
1110
|
+
if (looks[id] && !looks[id].custom) throw new Error(`id "${id}" belongs to a look viberoom ships; pick another`);
|
|
1111
|
+
const label = String(spec.label ?? "").trim();
|
|
1112
|
+
if (!label || label.length > 40) throw new Error("label: 1-40 characters, the name the picker shows");
|
|
1113
|
+
const baseId = spec.extends === undefined || spec.extends === null || spec.extends === "" ? "classic" : String(spec.extends);
|
|
1114
|
+
const base = looks[baseId];
|
|
1115
|
+
if (!base) throw new Error(`extends: no look "${baseId}" (${Object.keys(looks).filter((k) => !looks[k].custom).join(", ")})`);
|
|
1116
|
+
if (base.custom) throw new Error(`extends: "${baseId}" is a look of the human's own; a look extends one viberoom ships`);
|
|
1117
|
+
const scheme = spec.scheme === undefined || spec.scheme === null || spec.scheme === "" ? base.scheme : String(spec.scheme);
|
|
1118
|
+
if (scheme !== "light" && scheme !== "dark") throw new Error('scheme: "light" or "dark"');
|
|
1119
|
+
for (const key of Object.keys(spec)) {
|
|
1120
|
+
if (!["id", "label", "scheme", "extends", "author", "created", "updatedAt", "palette", "shape", "type", "motion", "elevation", "canvas", "elements"].includes(key)) throw new Error(`${key}: not a part of a look spec`);
|
|
1121
|
+
}
|
|
1122
|
+
const section = (name) => {
|
|
1123
|
+
const v = spec[name];
|
|
1124
|
+
if (v === undefined || v === null) return {};
|
|
1125
|
+
if (typeof v !== "object" || Array.isArray(v)) throw new Error(`${name}: an object of keys and values`);
|
|
1126
|
+
return v;
|
|
1127
|
+
};
|
|
1128
|
+
const palette = { ...base.palette };
|
|
1129
|
+
for (const [name, raw] of Object.entries(section("palette"))) {
|
|
1130
|
+
if (!(name in palette)) throw new Error(`palette.${name}: no such hue (${Object.keys(palette).join(", ")})`);
|
|
1131
|
+
const v = resolveValue(raw, palette, `palette.${name}`);
|
|
1132
|
+
if (!HEX6.test(v)) throw new Error(`palette.${name}: a hue is a flat colour #rrggbb, not "${v}"`);
|
|
1133
|
+
palette[name] = v.toLowerCase();
|
|
1134
|
+
}
|
|
1135
|
+
const baseWants = base.wants || {};
|
|
1136
|
+
const typeWants = { ...(baseWants.type || {}) };
|
|
1137
|
+
for (const [key, raw] of Object.entries(section("type"))) {
|
|
1138
|
+
if (!(key in type)) throw new Error(`type.${key}: no such token (${Object.keys(type).join(", ")})`);
|
|
1139
|
+
const v = resolveValue(raw, palette, `type.${key}`);
|
|
1140
|
+
if (key === "font" || key === "mono") {
|
|
1141
|
+
const table = key === "font" ? fonts.text : fonts.mono;
|
|
1142
|
+
if (table[v]) typeWants[key] = table[v].stack;
|
|
1143
|
+
else if (FONT_STACK.test(v)) typeWants[key] = v;
|
|
1144
|
+
else throw new Error(`type.${key}: a font id (${Object.keys(table).join(", ")}) or a family stack`);
|
|
1145
|
+
} else typeWants[key] = v;
|
|
1146
|
+
}
|
|
1147
|
+
const specCanvas = section("canvas");
|
|
1148
|
+
const specElements = section("elements");
|
|
1149
|
+
const wants = {
|
|
1150
|
+
shape: flatSection(section("shape"), "shape", shape, baseWants.shape, palette),
|
|
1151
|
+
type: typeWants,
|
|
1152
|
+
motion: flatSection(section("motion"), "motion", motion, baseWants.motion, palette),
|
|
1153
|
+
elevation: flatSection(section("elevation"), "elevation", elevationOf(palette), baseWants.elevation, palette),
|
|
1154
|
+
canvas: (p) => flatSection(specCanvas, "canvas", canvasOf(p), baseWants.canvas ? baseWants.canvas(p) : {}, p),
|
|
1155
|
+
elements: (p) => {
|
|
1156
|
+
const defaults = elementsOf(p);
|
|
1157
|
+
const out = {};
|
|
1158
|
+
const fromBase = baseWants.elements ? baseWants.elements(p) : {};
|
|
1159
|
+
for (const [group, parts] of Object.entries(fromBase)) out[group] = { ...parts };
|
|
1160
|
+
for (const [group, parts] of Object.entries(specElements)) {
|
|
1161
|
+
if (!(group in defaults)) throw new Error(`elements.${group}: no such element (${Object.keys(defaults).join(", ")})`);
|
|
1162
|
+
if (!parts || typeof parts !== "object" || Array.isArray(parts)) throw new Error(`elements.${group}: an object of keys and values`);
|
|
1163
|
+
out[group] = { ...(out[group] || {}) };
|
|
1164
|
+
for (const [key, raw] of Object.entries(parts)) {
|
|
1165
|
+
if (!(key in defaults[group])) throw new Error(`elements.${group}.${key}: no such token (${Object.keys(defaults[group]).join(", ")})`);
|
|
1166
|
+
out[group][key] = checked(defaults[group][key], resolveValue(raw, p, `elements.${group}.${key}`), `elements.${group}.${key}`);
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
return out;
|
|
1170
|
+
},
|
|
1171
|
+
};
|
|
1172
|
+
const made = look(id, label, scheme, palette, wants);
|
|
1173
|
+
made.custom = true;
|
|
1174
|
+
made.extends = base.id;
|
|
1175
|
+
made.author = spec.author === undefined || spec.author === null ? "" : String(spec.author).slice(0, 40);
|
|
1176
|
+
return made;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
const docs = {
|
|
1180
|
+
sections: {
|
|
1181
|
+
palette: "the hues of the look, named after what they look like, never after what they are for; every element is derived from them, so a hue changed here reaches every place that wears it",
|
|
1182
|
+
shape: "corners: rScale multiplies every radius in the window (0 square, 1 as designed, 1.6 very round); rCtlMin is the least radius of a button, an icon button or a chip (0px keeps each one's own, 99px makes every control a pill); rXs…rPill are the named radii, each ONE length or calc() (they are used inside calc() and max(), so a multi-corner value breaks every corner)",
|
|
1183
|
+
type: "text: font and mono are the family stacks (in a spec: an id from fonts, or a stack), lineHeight the running text's, fsScale multiplies every text size, fsXs…fs2xl are the named sizes",
|
|
1184
|
+
motion: "the durations (tFast, tBase, tSlow; 0ms for none) and easings of the transitions",
|
|
1185
|
+
elevation: "the shadows and the light: edge (a hair under a panel), shadowTile (a raised tile), shadowPop (a floating balloon), shadowPrimary (the glow under the accent), shadowDialog, shadowCard, shadowCtl and shadowCtlHover (a control at rest and under the pointer), shadowInset (a sunken thing), shadowSoft (a small raised thing), shadow / shadow1 / shadow2 (older names), bevel (a light laid over a raised surface: a gradient, or none), bevelPressed (the same when pressed), shadowRoom (room around a message for its shadow, 0px unless the shadows reach out)",
|
|
1186
|
+
canvas: "the chat's paper: gradCanvas (the paint behind the messages: a colour, or gradients), canvasPattern and canvasPatternSize (a pattern over it, or none / 0 0), gradPage (the paper behind the panels), sbW / sbThumb / sbThumbHover (the scrollbar)",
|
|
1187
|
+
elements: "every UI element and what it wears: the group is the element, the key the part (bg, ink, hoverBg, border, shadow, radius…); a key ending in Ink is written on the key of the same stem ending in Bg (or on bg), and the pair must read at 3:1 or better; a key whose value is none / 0px / transparent is structure a look may switch on (a border, a shadow, a lift, capitals)",
|
|
1188
|
+
},
|
|
1189
|
+
palette: {
|
|
1190
|
+
primary: "the one accent: buttons, links, your bubble, the ring on your face",
|
|
1191
|
+
primaryLight: "the accent a step lighter (the start of its gradient)",
|
|
1192
|
+
primaryDeep: "the accent a step deeper (the end of its gradient)",
|
|
1193
|
+
primaryDark: "the accent's darkest step: the accent as an ink on its own tint",
|
|
1194
|
+
violet: "the far end of the welcome hero's sweep",
|
|
1195
|
+
iris: "the colour the browser paints its own window frame with",
|
|
1196
|
+
ink: "the words",
|
|
1197
|
+
ink2: "the words in a bubble",
|
|
1198
|
+
ink3: "quieter words: a button's, labels",
|
|
1199
|
+
indigo: "the human's initials on their face; a vendor's mark",
|
|
1200
|
+
muted: "quiet words: times, hints",
|
|
1201
|
+
faint: "the faintest words and dots",
|
|
1202
|
+
placeholder: "a field's placeholder",
|
|
1203
|
+
grey: "a face with no colour of its own",
|
|
1204
|
+
white: "the paper of panels, cards and bubbles (on a dark look: the dark paper)",
|
|
1205
|
+
black: "black, for shadows cast in black",
|
|
1206
|
+
bg: "the paper behind everything",
|
|
1207
|
+
soft: "the paper a step off the panel's: fields, tiles",
|
|
1208
|
+
softer: "the paper two steps off: buttons at rest",
|
|
1209
|
+
lav: "the accent's tint: tiles, chips, hover",
|
|
1210
|
+
lav2: "the accent's deeper tint: borders, a pressed chip",
|
|
1211
|
+
canvasTop: "the chat paper's sweep, top",
|
|
1212
|
+
canvasMid: "the chat paper's sweep, middle",
|
|
1213
|
+
canvasBottom: "the chat paper's sweep, bottom",
|
|
1214
|
+
shadowInk: "the colour shadows are cast in",
|
|
1215
|
+
mint: "green, pale: done, ready",
|
|
1216
|
+
mint2: "green, pale, a step deeper: hover on a green thing",
|
|
1217
|
+
mintTint: "green, the faintest tint",
|
|
1218
|
+
mintInk: "green as an ink on the pale green",
|
|
1219
|
+
forest: "green, dark: words on the hero's green bubble",
|
|
1220
|
+
green: "green, bright: the ready dot",
|
|
1221
|
+
warm: "yellow, pale: thinking, attention, a note",
|
|
1222
|
+
warm2: "yellow, pale, a step deeper: hover on a note",
|
|
1223
|
+
warmInk: "yellow as an ink on the pale yellow",
|
|
1224
|
+
bronze: "yellow, dark: words on the hero's yellow bubble",
|
|
1225
|
+
amber: "amber, bright: the thinking dot, a warning",
|
|
1226
|
+
honey: "honey: the number and the found line in code",
|
|
1227
|
+
spark: "the spark on the hero",
|
|
1228
|
+
peach: "peach, pale: a welcome tile",
|
|
1229
|
+
peach2: "peach, pale, a step deeper",
|
|
1230
|
+
orange: "orange: attention",
|
|
1231
|
+
orangeLight: "orange, light: the attention gradient's start",
|
|
1232
|
+
orangeDeep: "orange, deep: the attention gradient's end",
|
|
1233
|
+
orangeDark: "orange, dark: the attention ink",
|
|
1234
|
+
ember: "ember: unread, a glow",
|
|
1235
|
+
emberDeep: "ember, deep: the unread gradient's end",
|
|
1236
|
+
rose: "red, pale: an error, a danger button",
|
|
1237
|
+
rose2: "red, pale, a step deeper: hover on a danger button",
|
|
1238
|
+
roseInk: "red as an ink: errors, the danger ink, a failed call",
|
|
1239
|
+
roseDark: "red, dark: a solid danger button pressed",
|
|
1240
|
+
pink: "pink: the unseen line",
|
|
1241
|
+
pinkTint: "pink, the faintest tint: the unseen line's label",
|
|
1242
|
+
sky: "blue, pale: waiting, info",
|
|
1243
|
+
blue: "blue: info",
|
|
1244
|
+
blueDeep: "blue, deep: the waiting ink",
|
|
1245
|
+
blueSoft: "blue, soft: the waiting dot",
|
|
1246
|
+
orchid: "violet, pale: writing",
|
|
1247
|
+
orchidInk: "violet as an ink: the writing ink",
|
|
1248
|
+
orchidMid: "violet, mid: the writing dot",
|
|
1249
|
+
periwinkle: "periwinkle: your ticks on the timeline",
|
|
1250
|
+
periwinkleDeep: "periwinkle, deep: your ticks in view",
|
|
1251
|
+
deep: "the dark surface of code blocks and the file viewer",
|
|
1252
|
+
deepGutter: "the gutter of the dark surface",
|
|
1253
|
+
deepInk: "the words on the dark surface",
|
|
1254
|
+
deepMuted: "the quiet words on the dark surface",
|
|
1255
|
+
deepHead: "the head of the dark surface",
|
|
1256
|
+
deepMeta: "the meta words in that head",
|
|
1257
|
+
lavGrey: "code: punctuation",
|
|
1258
|
+
lilac: "code: keywords",
|
|
1259
|
+
seafoam: "code: strings",
|
|
1260
|
+
azure: "code: functions",
|
|
1261
|
+
salmon: "code: tags",
|
|
1262
|
+
magenta: "code: attributes",
|
|
1263
|
+
},
|
|
1264
|
+
elements: {
|
|
1265
|
+
page: "the page itself: its paper, its ink, the selection",
|
|
1266
|
+
focus: "the ring around whatever the keyboard is on",
|
|
1267
|
+
link: "a path or a link inside a message",
|
|
1268
|
+
btn: "button: a button with words; the colours of every kind (primary, secondary, soft, ghost, danger, danger-solid, dark, warn, inverse, link, ok, paper), its sizes, and its structure (border: width style colour; case; tracking; ghostBg; the shadows at rest / on hover / pressed; hoverLift: negative lifts)",
|
|
1269
|
+
iconButton: "icon-button: a button that is only a glyph; kinds primary, danger, ghost, inline; its sizes and structure (ghostBg, shadows, hoverLift)",
|
|
1270
|
+
badge: "badge: a small label that states a fact; the state tones come from the room's meaning colours; fill (100% filled, 0% an outline in its ink), border, case, tracking, shadow",
|
|
1271
|
+
chip: "chip: a small tag that names a thing; fill, border, shadow, hoverLift, activeDrop",
|
|
1272
|
+
fileCard: "file-card: a fragment of a file or a picture under the message that names it (the dark card)",
|
|
1273
|
+
toolCall: "tool-call: a chip that opens to the call; the status colours",
|
|
1274
|
+
toolFold: "tool-fold: the calls of a finished reply, in one line",
|
|
1275
|
+
askCard: "ask-card: a decision the room puts in front of you (a permission, a proposal)",
|
|
1276
|
+
replyNote: "reply-note: a line the hub attaches to a reply, inside its bubble",
|
|
1277
|
+
lookCard: "look-card: a look as a small picture of itself (the picker)",
|
|
1278
|
+
choice: "choice: one option of a few, as a pill; border, shadows, hoverLift, activeDrop",
|
|
1279
|
+
control: "switches and checkboxes",
|
|
1280
|
+
tile: "the small marks that are not types yet: the ? badge of the life ring, the count pills",
|
|
1281
|
+
roomMark: "room-mark: a room's square mark in its own hue (ink, the recipe of the gradient, shadow, radius / radiusLg / radiusRail)",
|
|
1282
|
+
pop: "the little speech balloons the rail and the participants raise",
|
|
1283
|
+
dialog: "the glass behind a dialog",
|
|
1284
|
+
scrim: "the dark glass behind a picture or a diagram",
|
|
1285
|
+
toast: "a toast: the ink with the paper's colour on it",
|
|
1286
|
+
rail: "the main menu",
|
|
1287
|
+
timeline: "the strips beside the chat",
|
|
1288
|
+
bubble: "the message balloon: everyone else's (bg, ink, border, shadow) and your own (mineBg: always an image, a flat colour as linear-gradient(c, c); mineInk, mineShadow and the parts inside it)",
|
|
1289
|
+
quote: "a quoted message inside a balloon",
|
|
1290
|
+
attach: "pictures and file chips in a message",
|
|
1291
|
+
table: "a table in a message",
|
|
1292
|
+
code: "the file viewer and every code block",
|
|
1293
|
+
syntax: "the colours of the code itself",
|
|
1294
|
+
diagram: "a mermaid diagram opened full screen",
|
|
1295
|
+
input: "text fields (bg, focusBorder, shadow: none, or a sunken recipe)",
|
|
1296
|
+
profile: "the human's own card",
|
|
1297
|
+
face: "face: a participant's face (paper and tint of the tile, corner, rings, shadow, cardShadow)",
|
|
1298
|
+
logoTile: "logo-tile: a vendor's mark on a tile (bg, ink, the badge in a face's corner, shadow, radius / radiusSm / radiusLg / radiusBadge)",
|
|
1299
|
+
unseenLine: "unseen-line: the line above which a vibemate has seen nothing (ink, bg, the line's drawing, the label's border / case / tracking / shadow)",
|
|
1300
|
+
numberField: "number-field: a number with its own steps",
|
|
1301
|
+
adjustRow: "adjust-row: one thing the human may adjust in a look, in Settings",
|
|
1302
|
+
rowButton: "row-button: a small action on a vibemate's row",
|
|
1303
|
+
hubRow: "hub-row: a line the hub writes (ink, tones, the one that leads somewhere: actionBg / actionShadow; prefix / prefixGap: what stands before the line, none or a prompt)",
|
|
1304
|
+
hero: "the welcome screen's hero",
|
|
1305
|
+
feature: "the welcome screen's feature tiles (emojiBg, shadow)",
|
|
1306
|
+
composer: "the box you write in (shadow, bg, radius, padX: flat and bare, or sunk into the paper)",
|
|
1307
|
+
step: "the welcome screen's numbered steps",
|
|
1308
|
+
tpl: "the template list in Open a room",
|
|
1309
|
+
browser: "the colour the browser paints its window frame with",
|
|
1310
|
+
},
|
|
1311
|
+
};
|
|
1312
|
+
|
|
1313
|
+
const KIND_SYNTAX = {
|
|
1314
|
+
border: 'a CSS border: width, style and colour, e.g. "2px solid $ink" (a width alone draws nothing); 0 for none',
|
|
1315
|
+
shadow: 'a CSS box-shadow list, e.g. "3px 4px 0 $ink" or "0 2px 6px alpha($ink, 0.2)", or none',
|
|
1316
|
+
radius: "ONE length or calc(), e.g. \"calc(14px * var(--r-scale))\": the named radii are used inside calc() and max(), so a multi-corner value (four lengths, or a slash) breaks every corner",
|
|
1317
|
+
lift: 'a length the thing moves on hover: NEGATIVE lifts it ("-2px"), positive pushes it down; 0px for none',
|
|
1318
|
+
drop: 'a length the thing sinks when pressed ("1px"); 0px for none',
|
|
1319
|
+
fill: 'a percentage of the tone\'s colour: "100%" filled, "0%" an outline in the ink',
|
|
1320
|
+
prefix: 'a quoted string written before the line, e.g. "\">\"", or none',
|
|
1321
|
+
case: "none, uppercase, lowercase or capitalize",
|
|
1322
|
+
tracking: 'a letter-spacing length, e.g. "0.06em" or 0px',
|
|
1323
|
+
scale: 'a number as a string ("1", "0.5", "1.6")',
|
|
1324
|
+
length: 'a CSS length, e.g. "12px"',
|
|
1325
|
+
gradient: "a CSS gradient image (linear-gradient / radial-gradient), a flat colour, or none",
|
|
1326
|
+
bevel: "a gradient image laid over a raised face, or none",
|
|
1327
|
+
font: "a font id from fonts (text or mono), or a family stack",
|
|
1328
|
+
};
|
|
1329
|
+
const kindOf = (section, key, value) => {
|
|
1330
|
+
const v = String(value);
|
|
1331
|
+
if (COLOUR_VALUE.test(v)) return "colour";
|
|
1332
|
+
if (section === "shape") return key === "rScale" ? "scale" : "radius";
|
|
1333
|
+
if (section === "type") return key === "font" || key === "mono" ? "font" : /^fs/.test(key) ? "length" : "scale";
|
|
1334
|
+
if (section === "elevation") return /^bevel/.test(key) ? "bevel" : key === "shadowRoom" ? "length" : "shadow";
|
|
1335
|
+
if (section === "canvas") return /^grad|Pattern$/.test(key) ? "gradient" : "length";
|
|
1336
|
+
if (/[Rr]adius/.test(key)) return "radius";
|
|
1337
|
+
if (/[Ss]hadow$/.test(key)) return "shadow";
|
|
1338
|
+
if (key === "border" || /Border$/.test(key)) return "border";
|
|
1339
|
+
if (/Lift$/.test(key)) return "lift";
|
|
1340
|
+
if (/Drop$/.test(key)) return "drop";
|
|
1341
|
+
if (key === "fill") return "fill";
|
|
1342
|
+
if (key === "prefix") return "prefix";
|
|
1343
|
+
if (key === "case" || /Case$/.test(key)) return "case";
|
|
1344
|
+
if (/[Tt]racking$/.test(key)) return "tracking";
|
|
1345
|
+
if (/Bg$|^bg$|Ink$|^ink$|Color$/.test(key) || /gradient\(/.test(v)) return "gradient";
|
|
1346
|
+
return null;
|
|
1347
|
+
};
|
|
1348
|
+
|
|
1349
|
+
function describe() {
|
|
1350
|
+
const l = looks.classic;
|
|
1351
|
+
const keysOf = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [k, String(v)]));
|
|
1352
|
+
const kinds = {};
|
|
1353
|
+
const structural = (kind) => kind && kind !== "colour" && kind !== "gradient";
|
|
1354
|
+
for (const section of ["shape", "type", "elevation", "canvas"]) for (const [k, v] of Object.entries(l[section])) { const kind = kindOf(section, k, v); if (structural(kind)) kinds[`${section}.${k}`] = kind; }
|
|
1355
|
+
for (const [g, parts] of Object.entries(l.elements)) for (const [k, v] of Object.entries(parts)) { const kind = kindOf("elements", k, v); if (structural(kind)) kinds[`elements.${g}.${k}`] = kind; }
|
|
1356
|
+
return {
|
|
1357
|
+
syntax: "A look spec is { id, label, scheme?, extends?, palette?, shape?, type?, motion?, elevation?, canvas?, elements? }. It extends one of the looks viberoom ships (VibeClassic unless said) and changes only the keys it gives. A value is a string: a colour \"#1a2b3c\"; \"$name\" for a hue of the palette; \"alpha($ink, 0.14)\" for a hue at an alpha; \"mix($white, $ink, 0.5)\" for a blend; anything else (a shadow, a size, a gradient, a font) as CSS, with those forms inside it. A key the look does not have is refused; a colour key takes only a colour; no url(), no braces.",
|
|
1358
|
+
sections: docs.sections,
|
|
1359
|
+
palette: Object.fromEntries(Object.keys(l.palette).map((n) => [n, { doc: docs.palette[n] || "", classic: l.palette[n] }])),
|
|
1360
|
+
shape: keysOf(l.shape),
|
|
1361
|
+
type: keysOf(l.type),
|
|
1362
|
+
motion: keysOf(l.motion),
|
|
1363
|
+
elevation: keysOf(l.elevation),
|
|
1364
|
+
canvas: keysOf(l.canvas),
|
|
1365
|
+
elements: Object.fromEntries(Object.entries(l.elements).map(([g, parts]) => [g, { doc: docs.elements[g] || "", keys: keysOf(parts) }])),
|
|
1366
|
+
kinds,
|
|
1367
|
+
kindSyntax: KIND_SYNTAX,
|
|
1368
|
+
fonts: { text: Object.keys(fonts.text), mono: Object.keys(fonts.mono) },
|
|
1369
|
+
looks: Object.values(looks).map((x) => ({ id: x.id, label: x.label, scheme: x.scheme, custom: !!x.custom, extends: x.extends || null })),
|
|
1370
|
+
adjustables: adjustables.map((a) => ({ key: a.key, group: a.group, label: a.label, hint: a.hint || "", kind: a.kind, min: a.min, max: a.max, step: a.step })),
|
|
1371
|
+
};
|
|
1372
|
+
}
|
|
1373
|
+
|
|
1374
|
+
globalThis.VIBEROOM_TOKENS = { looks, current: looks.classic, active, diagrams, adjustables, cssGroups, cssVars, alpha, mix, kebab, fonts, make, describe, docs, kindOf };
|
|
620
1375
|
})();
|