@personaliai/react-widget 0.1.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/LICENSE +21 -0
- package/README.md +97 -0
- package/dist/chunk-PR4QN5HX.js +43 -0
- package/dist/chunk-PR4QN5HX.js.map +1 -0
- package/dist/emoji-picker-react.esm-JCK7JWXK.js +26071 -0
- package/dist/emoji-picker-react.esm-JCK7JWXK.js.map +1 -0
- package/dist/index.cjs +98050 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +28 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.js +71952 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +259 -0
- package/package.json +57 -0
- package/src/ChatWidgetCore.tsx +1919 -0
- package/src/attach-menu.tsx +60 -0
- package/src/color-contrast.ts +186 -0
- package/src/index.ts +1 -0
- package/src/quick-emoji-picker.tsx +75 -0
- package/src/safe-markdown-link.tsx +44 -0
- package/src/voice-call-widget.tsx +564 -0
- package/src/widget-presets.css +259 -0
- package/src/widget-style.ts +88 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/* Assistant Design Presets
|
|
2
|
+
*
|
|
3
|
+
* 10 fully-designed presets, each with its own deliberately-chosen
|
|
4
|
+
* typeface, corner radius, and shadow language, ported 1:1 from a real
|
|
5
|
+
* design gallery — the colors below are each design's own curated
|
|
6
|
+
* *fallback*, not fixed: every themeable surface (header, bot bubble,
|
|
7
|
+
* user bubble, starter chip, chat input bar, send button) is driven by
|
|
8
|
+
* the business owner's "Primary Hex Color" picker via var(--primary-color,
|
|
9
|
+
* <curated-fallback>), so unset the var and a preset renders exactly as
|
|
10
|
+
* originally designed.
|
|
11
|
+
*
|
|
12
|
+
* This used to be .send-btn only — an earlier version let primaryColor
|
|
13
|
+
* drive every surface directly and caused a real bug: a hardcoded text
|
|
14
|
+
* color paired against an arbitrary chosen background went unreadable the
|
|
15
|
+
* moment someone picked a color from the wrong half of the lightness
|
|
16
|
+
* spectrum (see git history for that bug class). The fix this time isn't
|
|
17
|
+
* "touch fewer surfaces", it's computing every text color instead of
|
|
18
|
+
* hardcoding it:
|
|
19
|
+
*
|
|
20
|
+
* - Header / user bubble / send button take the FULL primaryColor as a
|
|
21
|
+
* solid fill, with --on-primary (getOnColor(primaryColor) — white or
|
|
22
|
+
* near-black, computed per bg-lightness in lib/color-contrast.ts) as
|
|
23
|
+
* text. Same mechanism send-btn already proved out.
|
|
24
|
+
* - Bot bubble / starter chip / chat input bar instead blend primaryColor
|
|
25
|
+
* partially into that surface's own curated color with CSS color-mix()
|
|
26
|
+
* (background at 15-40%, text at 20%, anchored to the pre-verified
|
|
27
|
+
* original pairing) — a flat solid fill there would read as an
|
|
28
|
+
* error/alert on a reply bubble, and a fixed "tint toward white" would
|
|
29
|
+
* break the already-dark presets (Dark Sleek, Glassmorphism); mixing
|
|
30
|
+
* toward each surface's OWN original color instead keeps every preset's
|
|
31
|
+
* light/dark character intact while still visibly reflecting the brand
|
|
32
|
+
* color, with no per-preset special-casing needed.
|
|
33
|
+
* - A few structural monochrome strokes are left alone on purpose —
|
|
34
|
+
* Neubrutalism's black ink outline, Luxury Editorial's gold rule — where
|
|
35
|
+
* the color is the design's own genre-defining identity, not a swappable
|
|
36
|
+
* accent (see the comments at each).
|
|
37
|
+
*
|
|
38
|
+
* Every bg/fg text pair's *curated fallback* is verified >= 4.5:1 WCAG AA
|
|
39
|
+
* contrast (normal text), including ::placeholder colors and, for
|
|
40
|
+
* Glassmorphism, checked against the raw gradient stops (not just the
|
|
41
|
+
* translucent overlay's nominal alpha value, which understates the
|
|
42
|
+
* effective contrast against a colorful background). A handful of the
|
|
43
|
+
* ported gallery accents originally fell short of this — e.g. Playful's
|
|
44
|
+
* #ff8a5c header/button/chip text was only 2.32:1 against white —
|
|
45
|
+
* darkened in place (same hue, lower lightness) to restore the design's
|
|
46
|
+
* character while actually being readable. An arbitrary primaryColor pick
|
|
47
|
+
* can't be pre-verified the same way — the color-mix() partial-blend
|
|
48
|
+
* approach above is what keeps that case safe in practice, not a formal
|
|
49
|
+
* guarantee for every possible hex value.
|
|
50
|
+
*
|
|
51
|
+
* Ship this file alongside ChattyWidget (import "@chatty/react-widget/styles.css")
|
|
52
|
+
* — these are plain CSS selectors keyed off classNames the component
|
|
53
|
+
* renders (.chat-header, .bot-bubble, etc.), not Tailwind-generated
|
|
54
|
+
* utilities, so nothing else needs to build or scan this package's source.
|
|
55
|
+
*/
|
|
56
|
+
|
|
57
|
+
/* 1. Minimal — clean SaaS, off-white, DM Sans. */
|
|
58
|
+
.style-minimal {
|
|
59
|
+
background-color: #f3f2ee !important;
|
|
60
|
+
color: #1c1a15 !important;
|
|
61
|
+
border: 1px solid #e6e4de !important;
|
|
62
|
+
border-radius: 18px !important;
|
|
63
|
+
box-shadow: 0 12px 32px 0 rgba(0, 0, 0, 0.1) !important;
|
|
64
|
+
font-family: var(--font-dm-sans), sans-serif !important;
|
|
65
|
+
}
|
|
66
|
+
.style-minimal .chat-header { background-color: var(--primary-color, #ffffff) !important; color: var(--on-primary, #1c1a15) !important; border-bottom: 1px solid color-mix(in srgb, var(--primary-color, #e6e4de) 40%, #e6e4de) !important; }
|
|
67
|
+
.style-minimal .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #f3f2ee) 40%, #f3f2ee) !important; color: color-mix(in srgb, var(--on-primary, #1c1a15) 20%, #1c1a15) !important; border: none !important; border-radius: 14px !important; }
|
|
68
|
+
.style-minimal .user-bubble { background-color: var(--primary-color, #1c1a15) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 14px !important; }
|
|
69
|
+
.style-minimal .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 20%, #ffffff) !important; color: color-mix(in srgb, var(--on-primary, #1c1a15) 20%, #1c1a15) !important; border-color: color-mix(in srgb, var(--primary-color, #e0ddd5) 55%, #e0ddd5) !important; border-radius: 20px !important; font-weight: 500; }
|
|
70
|
+
.style-minimal .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 15%, #ffffff) !important; color: #1c1a15 !important; border-color: color-mix(in srgb, var(--primary-color, #e6e4de) 40%, #e6e4de) !important; border-radius: 12px !important; }
|
|
71
|
+
.style-minimal .send-btn { background-color: var(--primary-color, #1c1a15) !important; color: var(--on-primary, #ffffff) !important; }
|
|
72
|
+
.dark .style-minimal { background-color: #171613 !important; color: #f3f2ee !important; border-color: #2a2822 !important; }
|
|
73
|
+
.dark .style-minimal .chat-header { background-color: var(--primary-color, #1e1c18) !important; color: var(--on-primary, #f3f2ee) !important; border-color: color-mix(in srgb, var(--primary-color, #2a2822) 40%, #2a2822) !important; }
|
|
74
|
+
.dark .style-minimal .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #221f1a) 40%, #221f1a) !important; color: color-mix(in srgb, var(--on-primary, #f3f2ee) 20%, #f3f2ee) !important; }
|
|
75
|
+
.dark .style-minimal .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #1e1c18) 15%, #1e1c18) !important; color: #f3f2ee !important; border-color: color-mix(in srgb, var(--primary-color, #2a2822) 40%, #2a2822) !important; }
|
|
76
|
+
|
|
77
|
+
/* 2. Playful — consumer app, rounded & warm, Quicksand. */
|
|
78
|
+
.style-playful {
|
|
79
|
+
background-color: #fffaf5 !important;
|
|
80
|
+
color: #2a1a10 !important;
|
|
81
|
+
border: none !important;
|
|
82
|
+
border-radius: 28px !important;
|
|
83
|
+
box-shadow: 0 16px 36px 0 rgba(255, 138, 92, 0.28) !important;
|
|
84
|
+
font-family: var(--font-quicksand), sans-serif !important;
|
|
85
|
+
}
|
|
86
|
+
.style-playful .chat-header { background-color: var(--primary-color, #d63d00) !important; color: var(--on-primary, #ffffff) !important; border-bottom: none !important; }
|
|
87
|
+
.style-playful .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #ffe6d9) 40%, #ffe6d9) !important; color: color-mix(in srgb, var(--on-primary, #7a3f24) 20%, #7a3f24) !important; border: none !important; border-radius: 20px !important; }
|
|
88
|
+
.style-playful .user-bubble { background-color: var(--primary-color, #d63d00) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 20px !important; }
|
|
89
|
+
.style-playful .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 20%, #ffffff) !important; color: color-mix(in srgb, var(--on-primary, #d63d00) 20%, #d63d00) !important; border-color: color-mix(in srgb, var(--primary-color, #ffd6c1) 55%, #ffd6c1) !important; border-radius: 24px !important; font-weight: 500; }
|
|
90
|
+
.style-playful .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #fffaf5) 15%, #fffaf5) !important; color: #7a3f24 !important; border: none !important; border-radius: 20px !important; }
|
|
91
|
+
.style-playful .send-btn { background-color: var(--primary-color, #d63d00) !important; color: var(--on-primary, #ffffff) !important; }
|
|
92
|
+
.style-playful ::placeholder { color: #a4623d !important; opacity: 1; }
|
|
93
|
+
.dark .style-playful { background-color: #2a1c14 !important; color: #ffe6d9 !important; }
|
|
94
|
+
.dark .style-playful .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #3a2618) 40%, #3a2618) !important; color: color-mix(in srgb, var(--on-primary, #ffe6d9) 20%, #ffe6d9) !important; }
|
|
95
|
+
.dark .style-playful .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #2a1c14) 15%, #2a1c14) !important; color: #ffe6d9 !important; }
|
|
96
|
+
|
|
97
|
+
/* 3. Corporate — enterprise SaaS, structured navy, Space Grotesk. */
|
|
98
|
+
.style-corporate {
|
|
99
|
+
background-color: #eef1f6 !important;
|
|
100
|
+
color: #1c2e4a !important;
|
|
101
|
+
border: 1px solid #d7dce3 !important;
|
|
102
|
+
border-radius: 10px !important;
|
|
103
|
+
box-shadow: 0 10px 26px 0 rgba(28, 46, 74, 0.14) !important;
|
|
104
|
+
font-family: var(--font-space-grotesk), sans-serif !important;
|
|
105
|
+
}
|
|
106
|
+
.style-corporate .chat-header { background-color: var(--primary-color, #1c2e4a) !important; color: var(--on-primary, #ffffff) !important; border-bottom: none !important; }
|
|
107
|
+
.style-corporate .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #eef1f6) 40%, #eef1f6) !important; color: color-mix(in srgb, var(--on-primary, #1c2e4a) 20%, #1c2e4a) !important; border: 1px solid color-mix(in srgb, var(--primary-color, #dee3ea) 40%, #dee3ea) !important; border-radius: 8px !important; }
|
|
108
|
+
.style-corporate .user-bubble { background-color: var(--primary-color, #1c2e4a) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 8px !important; }
|
|
109
|
+
.style-corporate .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 20%, #ffffff) !important; color: color-mix(in srgb, var(--on-primary, #1c2e4a) 20%, #1c2e4a) !important; border-color: color-mix(in srgb, var(--primary-color, #c7cfdb) 55%, #c7cfdb) !important; border-radius: 6px !important; font-weight: 500; }
|
|
110
|
+
.style-corporate .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #eef1f6) 15%, #eef1f6) !important; color: #1c2e4a !important; border-color: color-mix(in srgb, var(--primary-color, #dbe0e8) 40%, #dbe0e8) !important; border-radius: 6px !important; }
|
|
111
|
+
.style-corporate .send-btn { background-color: var(--primary-color, #1c2e4a) !important; color: var(--on-primary, #ffffff) !important; border-radius: 6px !important; }
|
|
112
|
+
.style-corporate ::placeholder { color: #636e80 !important; opacity: 1; }
|
|
113
|
+
.dark .style-corporate { background-color: #10151d !important; color: #dbe2ec !important; border-color: #232c38 !important; }
|
|
114
|
+
.dark .style-corporate .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #171e29) 40%, #171e29) !important; color: color-mix(in srgb, var(--on-primary, #dbe2ec) 20%, #dbe2ec) !important; border-color: color-mix(in srgb, var(--primary-color, #232c38) 40%, #232c38) !important; }
|
|
115
|
+
.dark .style-corporate .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #10151d) 15%, #10151d) !important; color: #dbe2ec !important; border-color: color-mix(in srgb, var(--primary-color, #232c38) 40%, #232c38) !important; }
|
|
116
|
+
|
|
117
|
+
/* 4. Dark Sleek — dev tool, near-black with a teal glow, Space Grotesk. */
|
|
118
|
+
.style-dark-sleek {
|
|
119
|
+
background-color: #111114 !important;
|
|
120
|
+
color: #e4e4e8 !important;
|
|
121
|
+
border: 1px solid rgba(0, 229, 199, 0.25) !important;
|
|
122
|
+
border-radius: 16px !important;
|
|
123
|
+
box-shadow: 0 0 40px 0 rgba(0, 229, 199, 0.1) !important;
|
|
124
|
+
font-family: var(--font-space-grotesk), sans-serif !important;
|
|
125
|
+
}
|
|
126
|
+
.style-dark-sleek .chat-header { background-color: var(--primary-color, #14141a) !important; color: var(--on-primary, #e4e4e8) !important; border-bottom: none !important; }
|
|
127
|
+
.style-dark-sleek .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #1c1c22) 40%, #1c1c22) !important; color: color-mix(in srgb, var(--on-primary, #e4e4e8) 20%, #e4e4e8) !important; border: 1px solid rgba(255, 255, 255, 0.05) !important; border-radius: 12px !important; }
|
|
128
|
+
.style-dark-sleek .user-bubble { background-color: var(--primary-color, #00e5c7) !important; color: var(--on-primary, #05201c) !important; border: none !important; border-radius: 12px !important; }
|
|
129
|
+
.style-dark-sleek .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #1c1c22) 20%, #1c1c22) !important; color: color-mix(in srgb, var(--on-primary, #00e5c7) 20%, #00e5c7) !important; border-color: color-mix(in srgb, var(--primary-color, rgba(0, 229, 199, 0.3)) 55%, rgba(0, 229, 199, 0.3)) !important; border-radius: 8px !important; font-weight: 500; }
|
|
130
|
+
.style-dark-sleek .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #14141a) 15%, #14141a) !important; color: #e4e4e8 !important; border-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.08)) 40%, rgba(255, 255, 255, 0.08)) !important; border-radius: 8px !important; }
|
|
131
|
+
.style-dark-sleek .send-btn { background-color: var(--primary-color, #00e5c7) !important; color: var(--on-primary, #05201c) !important; border-radius: 8px !important; }
|
|
132
|
+
.style-dark-sleek ::placeholder { color: #7e7e8b !important; opacity: 1; }
|
|
133
|
+
|
|
134
|
+
/* 5. Gradient Glow — startup, vivid purple/pink gradient, Space Grotesk. */
|
|
135
|
+
.style-gradient-glow {
|
|
136
|
+
background-color: #ffffff !important;
|
|
137
|
+
color: #2a1245 !important;
|
|
138
|
+
border: none !important;
|
|
139
|
+
border-radius: 24px !important;
|
|
140
|
+
box-shadow: 0 20px 44px 0 rgba(168, 85, 247, 0.28) !important;
|
|
141
|
+
font-family: var(--font-space-grotesk), sans-serif !important;
|
|
142
|
+
}
|
|
143
|
+
.style-gradient-glow .chat-header { background: var(--primary-color, linear-gradient(120deg, #9733f5, #e0177a)) !important; color: var(--on-primary, #ffffff) !important; border-bottom: none !important; }
|
|
144
|
+
.style-gradient-glow .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #f6effc) 40%, #f6effc) !important; color: color-mix(in srgb, var(--on-primary, #4a2467) 20%, #4a2467) !important; border: none !important; border-radius: 16px !important; }
|
|
145
|
+
.style-gradient-glow .user-bubble { background-color: var(--primary-color, #9733f5) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 16px !important; }
|
|
146
|
+
.style-gradient-glow .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #f6effc) 20%, #f6effc) !important; color: color-mix(in srgb, var(--on-primary, #9733f5) 20%, #9733f5) !important; border-color: color-mix(in srgb, var(--primary-color, #e7d7f7) 55%, #e7d7f7) !important; border-radius: 20px !important; font-weight: 500; }
|
|
147
|
+
.style-gradient-glow .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 15%, #ffffff) !important; color: #4a2467 !important; border: none !important; border-radius: 16px !important; }
|
|
148
|
+
.style-gradient-glow .send-btn { background: var(--primary-color, linear-gradient(135deg, #9733f5, #e0177a)) !important; color: var(--on-primary, #ffffff) !important; }
|
|
149
|
+
.style-gradient-glow ::placeholder { color: #9063b3 !important; opacity: 1; }
|
|
150
|
+
.dark .style-gradient-glow { background-color: #1a1025 !important; color: #f0e5fa !important; }
|
|
151
|
+
.dark .style-gradient-glow .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #261a35) 40%, #261a35) !important; color: color-mix(in srgb, var(--on-primary, #f0e5fa) 20%, #f0e5fa) !important; }
|
|
152
|
+
.dark .style-gradient-glow .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #1a1025) 15%, #1a1025) !important; color: #f0e5fa !important; }
|
|
153
|
+
|
|
154
|
+
/* 6. Glassmorphism — fintech app, frosted glass over a gradient mesh, Space Grotesk. */
|
|
155
|
+
.style-glassmorphism {
|
|
156
|
+
background: linear-gradient(135deg, #3170eb, #7d58ee 50%, #d127b3) !important;
|
|
157
|
+
color: #ffffff !important;
|
|
158
|
+
border: none !important;
|
|
159
|
+
border-radius: 20px !important;
|
|
160
|
+
box-shadow: 0 16px 40px 0 rgba(20, 20, 50, 0.25) !important;
|
|
161
|
+
font-family: var(--font-space-grotesk), sans-serif !important;
|
|
162
|
+
}
|
|
163
|
+
.style-glassmorphism .chat-header { background-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.08)) 40%, rgba(255, 255, 255, 0.08)) !important; color: var(--on-primary, #ffffff) !important; border-bottom: 1px solid rgba(255, 255, 255, 0.15) !important; }
|
|
164
|
+
.style-glassmorphism .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.18)) 30%, rgba(255, 255, 255, 0.18)) !important; color: #ffffff !important; border: 1px solid rgba(255, 255, 255, 0.25) !important; border-radius: 14px !important; backdrop-filter: blur(18px) !important; -webkit-backdrop-filter: blur(18px) !important; }
|
|
165
|
+
.style-glassmorphism .user-bubble { background-color: var(--primary-color, rgba(255, 255, 255, 0.9)) !important; color: var(--on-primary, #39396b) !important; border: none !important; border-radius: 14px !important; }
|
|
166
|
+
.style-glassmorphism .starter-chip { background-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.15)) 30%, rgba(255, 255, 255, 0.15)) !important; color: #ffffff !important; border-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.35)) 40%, rgba(255, 255, 255, 0.35)) !important; border-radius: 20px !important; font-weight: 500; }
|
|
167
|
+
.style-glassmorphism .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, rgba(255, 255, 255, 0.08)) 40%, rgba(255, 255, 255, 0.08)) !important; color: #ffffff !important; border: 1px solid rgba(255, 255, 255, 0.15) !important; }
|
|
168
|
+
.style-glassmorphism .send-btn { background-color: var(--primary-color, rgba(255, 255, 255, 0.9)) !important; color: var(--on-primary, #39396b) !important; }
|
|
169
|
+
.style-glassmorphism ::placeholder { color: rgba(255, 255, 255, 0.75) !important; opacity: 1; }
|
|
170
|
+
|
|
171
|
+
/* 7. E-commerce — online shop, teal, order-aware, DM Sans. */
|
|
172
|
+
.style-ecommerce {
|
|
173
|
+
background-color: #fdf9f2 !important;
|
|
174
|
+
color: #3a3226 !important;
|
|
175
|
+
border: 1px solid #e8ddd0 !important;
|
|
176
|
+
border-radius: 14px !important;
|
|
177
|
+
box-shadow: 0 14px 32px 0 rgba(15, 157, 140, 0.14) !important;
|
|
178
|
+
font-family: var(--font-dm-sans), sans-serif !important;
|
|
179
|
+
}
|
|
180
|
+
.style-ecommerce .chat-header { background-color: var(--primary-color, #0c8173) !important; color: var(--on-primary, #ffffff) !important; border-bottom: none !important; }
|
|
181
|
+
.style-ecommerce .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #f3efe6) 40%, #f3efe6) !important; color: color-mix(in srgb, var(--on-primary, #3a3226) 20%, #3a3226) !important; border: none !important; border-radius: 14px !important; }
|
|
182
|
+
.style-ecommerce .user-bubble { background-color: var(--primary-color, #0c8173) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 14px !important; }
|
|
183
|
+
.style-ecommerce .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 20%, #ffffff) !important; color: color-mix(in srgb, var(--on-primary, #0c8173) 20%, #0c8173) !important; border-color: color-mix(in srgb, var(--primary-color, #cfe9e4) 55%, #cfe9e4) !important; border-radius: 16px !important; font-weight: 500; }
|
|
184
|
+
.style-ecommerce .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #fdf9f2) 15%, #fdf9f2) !important; color: #3a3226 !important; border-color: color-mix(in srgb, var(--primary-color, #e8ddd0) 40%, #e8ddd0) !important; border-radius: 14px !important; }
|
|
185
|
+
.style-ecommerce .send-btn { background-color: var(--primary-color, #0c8173) !important; color: var(--on-primary, #ffffff) !important; }
|
|
186
|
+
.style-ecommerce ::placeholder { color: #7d7159 !important; opacity: 1; }
|
|
187
|
+
.dark .style-ecommerce { background-color: #1a1712 !important; color: #ede6d8 !important; border-color: #33291d !important; }
|
|
188
|
+
.dark .style-ecommerce .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #241f17) 40%, #241f17) !important; color: color-mix(in srgb, var(--on-primary, #ede6d8) 20%, #ede6d8) !important; }
|
|
189
|
+
.dark .style-ecommerce .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #1a1712) 15%, #1a1712) !important; color: #ede6d8 !important; border-color: color-mix(in srgb, var(--primary-color, #33291d) 40%, #33291d) !important; }
|
|
190
|
+
|
|
191
|
+
/* 8. Healthcare Calm — clinic, soft sage, serif (Lora). */
|
|
192
|
+
.style-healthcare-calm {
|
|
193
|
+
background-color: #fbfcf9 !important;
|
|
194
|
+
color: #2f4235 !important;
|
|
195
|
+
border: 1px solid #dde8dd !important;
|
|
196
|
+
border-radius: 18px !important;
|
|
197
|
+
box-shadow: 0 12px 28px 0 rgba(111, 156, 125, 0.16) !important;
|
|
198
|
+
font-family: var(--font-lora), serif !important;
|
|
199
|
+
}
|
|
200
|
+
.style-healthcare-calm .chat-header { background-color: var(--primary-color, #eaf1e9) !important; color: var(--on-primary, #2f4235) !important; border-bottom: none !important; }
|
|
201
|
+
.style-healthcare-calm .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #eaf1e9) 40%, #eaf1e9) !important; color: color-mix(in srgb, var(--on-primary, #2f4235) 20%, #2f4235) !important; border: none !important; border-radius: 14px !important; }
|
|
202
|
+
.style-healthcare-calm .user-bubble { background-color: var(--primary-color, #567d62) !important; color: var(--on-primary, #ffffff) !important; border: none !important; border-radius: 14px !important; }
|
|
203
|
+
.style-healthcare-calm .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #fbfcf9) 20%, #fbfcf9) !important; color: color-mix(in srgb, var(--on-primary, #4a6b52) 20%, #4a6b52) !important; border-color: color-mix(in srgb, var(--primary-color, #cfe0cf) 55%, #cfe0cf) !important; border-radius: 14px !important; font-weight: 500; }
|
|
204
|
+
.style-healthcare-calm .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #fbfcf9) 15%, #fbfcf9) !important; color: #2f4235 !important; border-color: color-mix(in srgb, var(--primary-color, #dde8dd) 40%, #dde8dd) !important; border-radius: 12px !important; }
|
|
205
|
+
.style-healthcare-calm .send-btn { background-color: var(--primary-color, #567d62) !important; color: var(--on-primary, #ffffff) !important; }
|
|
206
|
+
.style-healthcare-calm ::placeholder { color: #607b63 !important; opacity: 1; }
|
|
207
|
+
.dark .style-healthcare-calm { background-color: #131a15 !important; color: #d9e8dc !important; border-color: #263429 !important; }
|
|
208
|
+
.dark .style-healthcare-calm .chat-header { background-color: var(--primary-color, #1a2a1e) !important; color: var(--on-primary, #d9e8dc) !important; }
|
|
209
|
+
.dark .style-healthcare-calm .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #1a2a1e) 40%, #1a2a1e) !important; color: color-mix(in srgb, var(--on-primary, #d9e8dc) 20%, #d9e8dc) !important; }
|
|
210
|
+
.dark .style-healthcare-calm .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #131a15) 15%, #131a15) !important; color: #d9e8dc !important; border-color: color-mix(in srgb, var(--primary-color, #263429) 40%, #263429) !important; }
|
|
211
|
+
|
|
212
|
+
/* 9. Neubrutalism — bold brand, thick borders, hard offset shadows, DM Sans. */
|
|
213
|
+
.style-neubrutalism {
|
|
214
|
+
background-color: #ffffff !important;
|
|
215
|
+
color: #111111 !important;
|
|
216
|
+
border: 3px solid #111111 !important;
|
|
217
|
+
border-radius: 4px !important;
|
|
218
|
+
box-shadow: 10px 10px 0 0 #111111 !important;
|
|
219
|
+
font-family: var(--font-dm-sans), sans-serif !important;
|
|
220
|
+
}
|
|
221
|
+
/* Border color stays the signature solid black ink outline throughout
|
|
222
|
+
(not primaryColor-driven) — brutalism's thick black stroke is the
|
|
223
|
+
genre-defining structural language here, the same way its 3px root
|
|
224
|
+
border and 10px hard shadow above are, not an arbitrary color choice
|
|
225
|
+
that happens to currently be black. */
|
|
226
|
+
.style-neubrutalism .chat-header { background-color: var(--primary-color, #ffde59) !important; color: var(--on-primary, #111111) !important; border-bottom: 3px solid #111111 !important; }
|
|
227
|
+
.style-neubrutalism .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #f2f2f2) 40%, #f2f2f2) !important; color: color-mix(in srgb, var(--on-primary, #111111) 20%, #111111) !important; border: 2px solid #111111 !important; border-radius: 4px !important; }
|
|
228
|
+
.style-neubrutalism .user-bubble { background-color: var(--primary-color, #ea0033) !important; color: var(--on-primary, #ffffff) !important; border: 2px solid #111111 !important; border-radius: 4px !important; }
|
|
229
|
+
.style-neubrutalism .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 20%, #ffffff) !important; color: color-mix(in srgb, var(--on-primary, #111111) 20%, #111111) !important; border: 2px solid #111111 !important; border-radius: 4px !important; font-weight: 600; }
|
|
230
|
+
.style-neubrutalism .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #ffffff) 15%, #ffffff) !important; color: #111111 !important; border: 2px solid #111111 !important; border-radius: 4px !important; }
|
|
231
|
+
.style-neubrutalism .send-btn { background-color: var(--primary-color, #ea0033) !important; color: var(--on-primary, #ffffff) !important; border: 2px solid #111111 !important; border-radius: 4px !important; }
|
|
232
|
+
.style-neubrutalism ::placeholder { color: #666666 !important; opacity: 1; }
|
|
233
|
+
.dark .style-neubrutalism { background-color: #1a1a1a !important; color: #f2f2f2 !important; border-color: #f2f2f2 !important; box-shadow: 10px 10px 0 0 #f2f2f2 !important; }
|
|
234
|
+
.dark .style-neubrutalism .chat-header { border-bottom-color: #f2f2f2 !important; }
|
|
235
|
+
.dark .style-neubrutalism .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #262626) 40%, #262626) !important; color: color-mix(in srgb, var(--on-primary, #f2f2f2) 20%, #f2f2f2) !important; border-color: #f2f2f2 !important; }
|
|
236
|
+
.dark .style-neubrutalism .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #1a1a1a) 15%, #1a1a1a) !important; color: #f2f2f2 !important; border-color: #f2f2f2 !important; }
|
|
237
|
+
|
|
238
|
+
/* 10. Luxury Editorial — boutique, serif & gold, Playfair Display. */
|
|
239
|
+
.style-luxury-editorial {
|
|
240
|
+
background-color: #fbf9f5 !important;
|
|
241
|
+
color: #2a251d !important;
|
|
242
|
+
border: 1px solid #c9a86a !important;
|
|
243
|
+
border-radius: 6px !important;
|
|
244
|
+
box-shadow: 0 18px 36px 0 rgba(0, 0, 0, 0.16) !important;
|
|
245
|
+
font-family: var(--font-playfair), serif !important;
|
|
246
|
+
}
|
|
247
|
+
.style-luxury-editorial .chat-header { background-color: var(--primary-color, #161412) !important; color: var(--on-primary, #f5efe3) !important; border-bottom: none !important; }
|
|
248
|
+
.style-luxury-editorial .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #f1ebdf) 40%, #f1ebdf) !important; color: color-mix(in srgb, var(--on-primary, #2a251d) 20%, #2a251d) !important; border: none !important; border-radius: 2px !important; }
|
|
249
|
+
.style-luxury-editorial .user-bubble { background-color: var(--primary-color, #161412) !important; color: var(--on-primary, #f5efe3) !important; border: none !important; border-radius: 2px !important; }
|
|
250
|
+
/* Border stays the signature gold rule (not primaryColor-driven) — same
|
|
251
|
+
reasoning as Neubrutalism's black ink outline: gold is this design's
|
|
252
|
+
own genre-defining structural language, not a swappable color. */
|
|
253
|
+
.style-luxury-editorial .starter-chip { background-color: color-mix(in srgb, var(--primary-color, #fbf9f5) 20%, #fbf9f5) !important; color: color-mix(in srgb, var(--on-primary, #2a251d) 20%, #2a251d) !important; border-color: #c9a86a !important; border-radius: 2px !important; font-weight: 500; }
|
|
254
|
+
.style-luxury-editorial .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #fbf9f5) 15%, #fbf9f5) !important; color: #2a251d !important; border-color: #ddd1b3 !important; border-radius: 2px !important; }
|
|
255
|
+
.style-luxury-editorial .send-btn { background-color: var(--primary-color, #161412) !important; color: var(--on-primary, #f5efe3) !important; border-radius: 2px !important; }
|
|
256
|
+
.style-luxury-editorial ::placeholder { color: #7d7156 !important; opacity: 1; }
|
|
257
|
+
.dark .style-luxury-editorial { background-color: #14120f !important; color: #efe6d3 !important; border-color: #b08a3e !important; }
|
|
258
|
+
.dark .style-luxury-editorial .bot-bubble { background-color: color-mix(in srgb, var(--primary-color, #201c16) 40%, #201c16) !important; color: color-mix(in srgb, var(--on-primary, #efe6d3) 20%, #efe6d3) !important; }
|
|
259
|
+
.dark .style-luxury-editorial .chat-input-bar { background-color: color-mix(in srgb, var(--primary-color, #14120f) 15%, #14120f) !important; color: #efe6d3 !important; border-color: #4a3f2a !important; }
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps old, now-removed widget style preset IDs to their closest current
|
|
3
|
+
* equivalent. The widget style system has been redesigned twice:
|
|
4
|
+
* 1. An original 9-preset set (glassmorphism, liquid, neumorphism,
|
|
5
|
+
* brutalism, claymorphism, bento, retro, aurora, minimalist)
|
|
6
|
+
* 2. A brief 5-preset set (minimalist, elevated, frosted, bold, contrast)
|
|
7
|
+
* 3. The current 10-preset set, ported 1:1 from a real design gallery
|
|
8
|
+
* (minimal, playful, corporate, dark-sleek, gradient-glow,
|
|
9
|
+
* glassmorphism, ecommerce, healthcare-calm, neubrutalism,
|
|
10
|
+
* luxury-editorial) — see globals.css for the full rationale.
|
|
11
|
+
* Existing bots in the database may still have any of the older IDs stored
|
|
12
|
+
* in widget_style; without this mapping they'd render with no matching CSS
|
|
13
|
+
* class at all (unstyled).
|
|
14
|
+
*/
|
|
15
|
+
const LEGACY_STYLE_MAP: Record<string, string> = {
|
|
16
|
+
// Original 9-preset set
|
|
17
|
+
liquid: "glassmorphism",
|
|
18
|
+
neumorphism: "corporate",
|
|
19
|
+
claymorphism: "playful",
|
|
20
|
+
bento: "minimal",
|
|
21
|
+
brutalism: "neubrutalism",
|
|
22
|
+
retro: "dark-sleek",
|
|
23
|
+
aurora: "gradient-glow",
|
|
24
|
+
// Brief 5-preset set
|
|
25
|
+
minimalist: "minimal",
|
|
26
|
+
elevated: "corporate",
|
|
27
|
+
frosted: "glassmorphism",
|
|
28
|
+
bold: "gradient-glow",
|
|
29
|
+
contrast: "dark-sleek",
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const CURRENT_STYLES = new Set([
|
|
33
|
+
"minimal",
|
|
34
|
+
"playful",
|
|
35
|
+
"corporate",
|
|
36
|
+
"dark-sleek",
|
|
37
|
+
"gradient-glow",
|
|
38
|
+
"glassmorphism",
|
|
39
|
+
"ecommerce",
|
|
40
|
+
"healthcare-calm",
|
|
41
|
+
"neubrutalism",
|
|
42
|
+
"luxury-editorial",
|
|
43
|
+
]);
|
|
44
|
+
|
|
45
|
+
export function normalizeWidgetStyle(id: string | null | undefined): string {
|
|
46
|
+
if (!id) return "minimal";
|
|
47
|
+
if (CURRENT_STYLES.has(id)) return id;
|
|
48
|
+
return LEGACY_STYLE_MAP[id] || "minimal";
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Each design's default launcher-button look. Mirrors LAUNCHER_STYLES in
|
|
53
|
+
* public/widget.js exactly — kept in sync by hand since widget.js is a
|
|
54
|
+
* separate unbundled script that can't import from this file.
|
|
55
|
+
*/
|
|
56
|
+
export const LAUNCHER_STYLES: Record<string, { bg: string; shadow: string; dot: string }> = {
|
|
57
|
+
minimal: { bg: "#1c1a15", shadow: "0 6px 16px rgba(0,0,0,.18)", dot: "#f3f2ee" },
|
|
58
|
+
playful: { bg: "#ff8a5c", shadow: "0 8px 20px rgba(255,138,92,.45)", dot: "#ffffff" },
|
|
59
|
+
corporate: { bg: "#1c2e4a", shadow: "0 6px 16px rgba(28,46,74,.3)", dot: "#8fb0dc" },
|
|
60
|
+
"dark-sleek": { bg: "#14141a", shadow: "0 0 24px rgba(0,229,199,.35)", dot: "#00e5c7" },
|
|
61
|
+
"gradient-glow": { bg: "linear-gradient(135deg,#a855f7,#ec4899)", shadow: "0 10px 26px rgba(168,85,247,.4)", dot: "#ffffff" },
|
|
62
|
+
glassmorphism: { bg: "rgba(255,255,255,.25)", shadow: "0 8px 24px rgba(0,0,0,.2)", dot: "#ffffff" },
|
|
63
|
+
ecommerce: { bg: "#0f9d8c", shadow: "0 8px 20px rgba(15,157,140,.35)", dot: "#ffffff" },
|
|
64
|
+
"healthcare-calm": { bg: "#6f9c7d", shadow: "0 8px 20px rgba(111,156,125,.35)", dot: "#f4f7f3" },
|
|
65
|
+
neubrutalism: { bg: "#111111", shadow: "5px 5px 0 0 #111111", dot: "#ffde59" },
|
|
66
|
+
"luxury-editorial": { bg: "#161412", shadow: "0 8px 22px rgba(0,0,0,.3)", dot: "#b08a3e" },
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Each design's own chat-panel corner radius (its .style-X { border-radius }
|
|
71
|
+
* in globals.css). Mirrors PANEL_RADIUS in public/widget.js exactly — kept
|
|
72
|
+
* in sync by hand for the same reason LAUNCHER_STYLES above is. The outer
|
|
73
|
+
* host div/iframe around the embedded panel matches this exactly (instead
|
|
74
|
+
* of a flat 0px "always smaller" safety net) so there's no radius mismatch
|
|
75
|
+
* at the corner for anti-aliasing to expose as a hairline seam.
|
|
76
|
+
*/
|
|
77
|
+
export const PANEL_RADIUS: Record<string, string> = {
|
|
78
|
+
minimal: "18px",
|
|
79
|
+
playful: "28px",
|
|
80
|
+
corporate: "10px",
|
|
81
|
+
"dark-sleek": "16px",
|
|
82
|
+
"gradient-glow": "24px",
|
|
83
|
+
glassmorphism: "20px",
|
|
84
|
+
ecommerce: "14px",
|
|
85
|
+
"healthcare-calm": "18px",
|
|
86
|
+
neubrutalism: "4px",
|
|
87
|
+
"luxury-editorial": "6px",
|
|
88
|
+
};
|