@typecaast/skins 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/chunk-3WKOSJVB.js +320 -0
  2. package/dist/chunk-3WKOSJVB.js.map +1 -0
  3. package/dist/chunk-6K2ANTPJ.cjs +722 -0
  4. package/dist/chunk-6K2ANTPJ.cjs.map +1 -0
  5. package/dist/chunk-7IC3DRCQ.js +718 -0
  6. package/dist/chunk-7IC3DRCQ.js.map +1 -0
  7. package/dist/chunk-AMP2ZMTF.cjs +275 -0
  8. package/dist/chunk-AMP2ZMTF.cjs.map +1 -0
  9. package/dist/chunk-BMB4ZKAU.cjs +32 -0
  10. package/dist/chunk-BMB4ZKAU.cjs.map +1 -0
  11. package/dist/chunk-CAHWYIXY.js +272 -0
  12. package/dist/chunk-CAHWYIXY.js.map +1 -0
  13. package/dist/chunk-CCT33UVA.cjs +591 -0
  14. package/dist/chunk-CCT33UVA.cjs.map +1 -0
  15. package/dist/chunk-E5K2XXQL.cjs +469 -0
  16. package/dist/chunk-E5K2XXQL.cjs.map +1 -0
  17. package/dist/chunk-FEXZ3X5C.cjs +255 -0
  18. package/dist/chunk-FEXZ3X5C.cjs.map +1 -0
  19. package/dist/chunk-JDPMZ572.js +466 -0
  20. package/dist/chunk-JDPMZ572.js.map +1 -0
  21. package/dist/chunk-JZVM4T2A.js +29 -0
  22. package/dist/chunk-JZVM4T2A.js.map +1 -0
  23. package/dist/chunk-KTQVRSDX.cjs +323 -0
  24. package/dist/chunk-KTQVRSDX.cjs.map +1 -0
  25. package/dist/chunk-M54H2ZJJ.js +252 -0
  26. package/dist/chunk-M54H2ZJJ.js.map +1 -0
  27. package/dist/chunk-NCSI7C7I.js +561 -0
  28. package/dist/chunk-NCSI7C7I.js.map +1 -0
  29. package/dist/chunk-OC7WDISK.js +343 -0
  30. package/dist/chunk-OC7WDISK.js.map +1 -0
  31. package/dist/chunk-UC43JQYK.cjs +346 -0
  32. package/dist/chunk-UC43JQYK.cjs.map +1 -0
  33. package/dist/chunk-UFC4ODW5.js +587 -0
  34. package/dist/chunk-UFC4ODW5.js.map +1 -0
  35. package/dist/chunk-UKWBCC7E.cjs +567 -0
  36. package/dist/chunk-UKWBCC7E.cjs.map +1 -0
  37. package/dist/claude-code/index.cjs +19 -0
  38. package/dist/claude-code/index.cjs.map +1 -0
  39. package/dist/claude-code/index.d.cts +6 -0
  40. package/dist/claude-code/index.d.ts +6 -0
  41. package/dist/claude-code/index.js +4 -0
  42. package/dist/claude-code/index.js.map +1 -0
  43. package/dist/cursor/index.cjs +19 -0
  44. package/dist/cursor/index.cjs.map +1 -0
  45. package/dist/cursor/index.d.cts +6 -0
  46. package/dist/cursor/index.d.ts +6 -0
  47. package/dist/cursor/index.js +4 -0
  48. package/dist/cursor/index.js.map +1 -0
  49. package/dist/discord/index.cjs +19 -0
  50. package/dist/discord/index.cjs.map +1 -0
  51. package/dist/discord/index.d.cts +6 -0
  52. package/dist/discord/index.d.ts +6 -0
  53. package/dist/discord/index.js +4 -0
  54. package/dist/discord/index.js.map +1 -0
  55. package/dist/imessage/index.cjs +20 -0
  56. package/dist/imessage/index.cjs.map +1 -0
  57. package/dist/imessage/index.d.cts +6 -0
  58. package/dist/imessage/index.d.ts +6 -0
  59. package/dist/imessage/index.js +5 -0
  60. package/dist/imessage/index.js.map +1 -0
  61. package/dist/index.cjs +52 -2664
  62. package/dist/index.cjs.map +1 -1
  63. package/dist/index.d.cts +49 -27
  64. package/dist/index.d.ts +49 -27
  65. package/dist/index.js +20 -2656
  66. package/dist/index.js.map +1 -1
  67. package/dist/messages-macos/index.cjs +20 -0
  68. package/dist/messages-macos/index.cjs.map +1 -0
  69. package/dist/messages-macos/index.d.cts +10 -0
  70. package/dist/messages-macos/index.d.ts +10 -0
  71. package/dist/messages-macos/index.js +5 -0
  72. package/dist/messages-macos/index.js.map +1 -0
  73. package/dist/slack/index.cjs +19 -0
  74. package/dist/slack/index.cjs.map +1 -0
  75. package/dist/slack/index.d.cts +6 -0
  76. package/dist/slack/index.d.ts +6 -0
  77. package/dist/slack/index.js +4 -0
  78. package/dist/slack/index.js.map +1 -0
  79. package/dist/telegram/index.cjs +19 -0
  80. package/dist/telegram/index.cjs.map +1 -0
  81. package/dist/telegram/index.d.cts +6 -0
  82. package/dist/telegram/index.d.ts +6 -0
  83. package/dist/telegram/index.js +4 -0
  84. package/dist/telegram/index.js.map +1 -0
  85. package/dist/whatsapp/index.cjs +19 -0
  86. package/dist/whatsapp/index.cjs.map +1 -0
  87. package/dist/whatsapp/index.d.cts +6 -0
  88. package/dist/whatsapp/index.d.ts +6 -0
  89. package/dist/whatsapp/index.js +4 -0
  90. package/dist/whatsapp/index.js.map +1 -0
  91. package/package.json +49 -5
@@ -0,0 +1,587 @@
1
+ "use client";
2
+ import { z } from 'zod';
3
+ import { defineSkin, MessageContent, fadeSlideIn, popIn } from '@typecaast/skin-kit';
4
+ import { useState, useRef, useLayoutEffect } from 'react';
5
+ import { jsx, jsxs } from 'react/jsx-runtime';
6
+
7
+ // src/slack/index.ts
8
+
9
+ // src/slack/tokens.ts
10
+ var SLACK_COLORS = {
11
+ light: {
12
+ bg: "#ffffff",
13
+ text: "#1d1c1d",
14
+ subtle: "#616061",
15
+ border: "#e2e2e2",
16
+ headerBg: "#ffffff",
17
+ link: "#1264a3",
18
+ mentionText: "#1264a3",
19
+ mentionBg: "#e8f5fa",
20
+ codeText: "#e01e5a",
21
+ codeBg: "#f6f6f6",
22
+ codeBorder: "#e2e2e2",
23
+ reactionBg: "#f8f8f8",
24
+ reactionBorder: "#e2e2e2",
25
+ reactionText: "#454245",
26
+ composerBg: "#ffffff",
27
+ composerBorder: "#8d8d8d",
28
+ placeholder: "#8d8d8d",
29
+ primary: "#007a5a",
30
+ primaryText: "#ffffff",
31
+ buttonBorder: "#d1d1d1",
32
+ buttonText: "#1d1c1d",
33
+ appBadgeBg: "#e8e8e8",
34
+ appBadgeText: "#616061",
35
+ cardBar: "#dddddd",
36
+ caret: "#1264a3"
37
+ },
38
+ dark: {
39
+ bg: "#1a1d21",
40
+ text: "#d1d2d3",
41
+ subtle: "#ababad",
42
+ border: "#35373b",
43
+ headerBg: "#1a1d21",
44
+ link: "#1d9bd1",
45
+ mentionText: "#1d9bd1",
46
+ mentionBg: "rgba(29,155,209,0.12)",
47
+ codeText: "#e06c9a",
48
+ codeBg: "#222529",
49
+ codeBorder: "#35373b",
50
+ reactionBg: "#222529",
51
+ reactionBorder: "#35373b",
52
+ reactionText: "#d1d2d3",
53
+ composerBg: "#222529",
54
+ composerBorder: "#565856",
55
+ placeholder: "#9a9b9d",
56
+ primary: "#007a5a",
57
+ primaryText: "#ffffff",
58
+ buttonBorder: "#565856",
59
+ buttonText: "#d1d2d3",
60
+ appBadgeBg: "#35373b",
61
+ appBadgeText: "#ababad",
62
+ cardBar: "#35373b",
63
+ caret: "#1d9bd1"
64
+ }
65
+ };
66
+ var slackTokens = {
67
+ light: { colors: SLACK_COLORS.light },
68
+ dark: { colors: SLACK_COLORS.dark }
69
+ };
70
+
71
+ // src/slack/fonts.ts
72
+ var slackFonts = [
73
+ {
74
+ family: "Lato",
75
+ weights: [400, 700, 900],
76
+ sources: [
77
+ {
78
+ url: "https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2",
79
+ weight: 400,
80
+ format: "woff2"
81
+ },
82
+ {
83
+ url: "https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2",
84
+ weight: 700,
85
+ format: "woff2"
86
+ },
87
+ {
88
+ url: "https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2",
89
+ weight: 900,
90
+ format: "woff2"
91
+ }
92
+ ]
93
+ }
94
+ ];
95
+ var SLACK_FONT_STACK = 'Lato, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
96
+ var AVATAR_RADIUS = 8;
97
+ function joinNames(names) {
98
+ if (names.length <= 1) return names[0] ?? "";
99
+ if (names.length === 2) return `${names[0]} and ${names[1]}`;
100
+ return `${names.slice(0, -1).join(", ")}, and ${names[names.length - 1]}`;
101
+ }
102
+ function formatTime(atMs) {
103
+ const base = 9 * 3600 * 1e3;
104
+ const total = Math.floor((base + atMs) / 1e3);
105
+ const h = Math.floor(total / 3600) % 24;
106
+ const m = Math.floor(total % 3600 / 60);
107
+ const ampm = h >= 12 ? "PM" : "AM";
108
+ const hr = h % 12 === 0 ? 12 : h % 12;
109
+ return `${hr}:${String(m).padStart(2, "0")} ${ampm}`;
110
+ }
111
+ function initials(name) {
112
+ return name.split(/\s+/).map((w) => w.charAt(0)).slice(0, 2).join("").toUpperCase();
113
+ }
114
+ function markStyles(c) {
115
+ return {
116
+ link: { color: c.link, textDecoration: "none" },
117
+ mention: {
118
+ color: c.mentionText,
119
+ background: c.mentionBg,
120
+ borderRadius: 3,
121
+ padding: "0 2px",
122
+ fontWeight: 600
123
+ },
124
+ code: {
125
+ color: c.codeText,
126
+ background: c.codeBg,
127
+ border: `1px solid ${c.codeBorder}`,
128
+ borderRadius: 3,
129
+ padding: "1px 4px",
130
+ fontFamily: "Menlo, Monaco, Consolas, monospace",
131
+ fontSize: "0.85em"
132
+ }
133
+ };
134
+ }
135
+ var AppBadge = ({ c }) => /* @__PURE__ */ jsx(
136
+ "span",
137
+ {
138
+ style: {
139
+ fontSize: 10,
140
+ fontWeight: 700,
141
+ letterSpacing: 0.4,
142
+ background: c.appBadgeBg,
143
+ color: c.appBadgeText,
144
+ borderRadius: 2,
145
+ padding: "1px 4px"
146
+ },
147
+ children: "APP"
148
+ }
149
+ );
150
+ var Avatar = ({ theme, participant, size = 36 }) => {
151
+ const c = SLACK_COLORS[theme];
152
+ if (participant.avatar) {
153
+ return /* @__PURE__ */ jsx(
154
+ "img",
155
+ {
156
+ src: participant.avatar,
157
+ alt: participant.name,
158
+ width: size,
159
+ height: size,
160
+ style: {
161
+ width: size,
162
+ height: size,
163
+ borderRadius: AVATAR_RADIUS,
164
+ objectFit: "cover",
165
+ display: "block"
166
+ }
167
+ }
168
+ );
169
+ }
170
+ return /* @__PURE__ */ jsx(
171
+ "div",
172
+ {
173
+ "aria-label": participant.name,
174
+ style: {
175
+ width: size,
176
+ height: size,
177
+ borderRadius: AVATAR_RADIUS,
178
+ background: participant.color ?? "#4a154b",
179
+ color: "#ffffff",
180
+ display: "flex",
181
+ alignItems: "center",
182
+ justifyContent: "center",
183
+ fontWeight: 700,
184
+ fontSize: size * 0.4,
185
+ border: theme === "dark" ? `1px solid ${c.border}` : void 0
186
+ },
187
+ children: initials(participant.name)
188
+ }
189
+ );
190
+ };
191
+ function clippingAncestor(el) {
192
+ let node = el?.parentElement ?? null;
193
+ while (node) {
194
+ const o = getComputedStyle(node).overflow;
195
+ if (o && o !== "visible") return node;
196
+ node = node.parentElement;
197
+ }
198
+ return null;
199
+ }
200
+ var ReactionTooltip = ({
201
+ reaction
202
+ }) => {
203
+ const ref = useRef(null);
204
+ const [dx, setDx] = useState(0);
205
+ const code = reaction.shortcode;
206
+ useLayoutEffect(() => {
207
+ const el = ref.current;
208
+ if (!el) return;
209
+ const bound = clippingAncestor(el)?.getBoundingClientRect();
210
+ if (!bound) return;
211
+ const rect = el.getBoundingClientRect();
212
+ const m = 8;
213
+ let shift = 0;
214
+ if (rect.left < bound.left + m) shift = bound.left + m - rect.left;
215
+ else if (rect.right > bound.right - m) shift = bound.right - m - rect.right;
216
+ setDx(shift);
217
+ }, []);
218
+ return /* @__PURE__ */ jsxs(
219
+ "span",
220
+ {
221
+ ref,
222
+ role: "tooltip",
223
+ style: {
224
+ position: "absolute",
225
+ bottom: "calc(100% + 9px)",
226
+ left: "50%",
227
+ transform: `translateX(calc(-50% + ${dx}px))`,
228
+ zIndex: 20,
229
+ width: 220,
230
+ boxSizing: "border-box",
231
+ background: "#1a1d21",
232
+ color: "#e8e8e8",
233
+ borderRadius: 12,
234
+ padding: "16px 16px 14px",
235
+ textAlign: "center",
236
+ fontSize: 15,
237
+ lineHeight: 1.4,
238
+ boxShadow: "0 4px 14px rgba(0,0,0,0.4)",
239
+ pointerEvents: "none"
240
+ },
241
+ children: [
242
+ /* @__PURE__ */ jsx("span", { style: { display: "block", fontSize: 36, marginBottom: 8 }, children: reaction.emoji }),
243
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 700 }, children: joinNames(reaction.byNames) }),
244
+ /* @__PURE__ */ jsx("span", { style: { color: "#ababad" }, children: " reacted with " }),
245
+ /* @__PURE__ */ jsx("span", { style: { color: "#ababad" }, children: code ? `:${code}:` : reaction.emoji }),
246
+ /* @__PURE__ */ jsx(
247
+ "span",
248
+ {
249
+ style: {
250
+ position: "absolute",
251
+ top: "100%",
252
+ left: `calc(50% - ${dx}px)`,
253
+ transform: "translateX(-50%)",
254
+ width: 0,
255
+ height: 0,
256
+ borderLeft: "7px solid transparent",
257
+ borderRight: "7px solid transparent",
258
+ borderTop: "7px solid #1a1d21"
259
+ }
260
+ }
261
+ )
262
+ ]
263
+ }
264
+ );
265
+ };
266
+ var Reaction = ({ theme, reaction }) => {
267
+ const c = SLACK_COLORS[theme];
268
+ const [hover, setHover] = useState(false);
269
+ const hasReactors = reaction.byNames.length > 0;
270
+ return /* @__PURE__ */ jsxs(
271
+ "span",
272
+ {
273
+ style: {
274
+ position: "relative",
275
+ display: "inline-flex",
276
+ ...popIn(reaction.progress)
277
+ },
278
+ onMouseEnter: () => setHover(true),
279
+ onMouseLeave: () => setHover(false),
280
+ children: [
281
+ /* @__PURE__ */ jsxs(
282
+ "span",
283
+ {
284
+ style: {
285
+ display: "inline-flex",
286
+ alignItems: "center",
287
+ gap: 4,
288
+ background: c.reactionBg,
289
+ border: `1px solid ${c.reactionBorder}`,
290
+ color: c.reactionText,
291
+ borderRadius: 12,
292
+ padding: "1px 7px",
293
+ height: 22,
294
+ fontSize: 12,
295
+ cursor: hasReactors ? "pointer" : "default"
296
+ },
297
+ children: [
298
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 13 }, children: reaction.emoji }),
299
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 600, fontVariantNumeric: "tabular-nums" }, children: reaction.count })
300
+ ]
301
+ }
302
+ ),
303
+ hover && hasReactors ? /* @__PURE__ */ jsx(ReactionTooltip, { reaction }) : null
304
+ ]
305
+ }
306
+ );
307
+ };
308
+ var TypingIndicator = ({ theme, author }) => {
309
+ const c = SLACK_COLORS[theme];
310
+ return /* @__PURE__ */ jsx(
311
+ "div",
312
+ {
313
+ style: {
314
+ display: "flex",
315
+ alignItems: "center",
316
+ padding: "2px 16px 4px 60px",
317
+ color: c.subtle,
318
+ fontSize: 12,
319
+ fontStyle: "italic"
320
+ },
321
+ children: /* @__PURE__ */ jsxs("span", { children: [
322
+ author.name,
323
+ " is typing\u2026"
324
+ ] })
325
+ }
326
+ );
327
+ };
328
+ var Caret = ({ color }) => /* @__PURE__ */ jsx(
329
+ "span",
330
+ {
331
+ style: {
332
+ display: "inline-block",
333
+ width: 1.5,
334
+ height: "1.05em",
335
+ background: color,
336
+ marginLeft: 1,
337
+ verticalAlign: "text-bottom"
338
+ }
339
+ }
340
+ );
341
+ var Composer = ({ theme, composer }) => {
342
+ const c = SLACK_COLORS[theme];
343
+ const hasText = composer.text.length > 0;
344
+ return /* @__PURE__ */ jsx("div", { style: { flex: "0 0 auto", padding: "4px 16px 14px" }, children: /* @__PURE__ */ jsx(
345
+ "div",
346
+ {
347
+ style: {
348
+ border: `1px solid ${c.composerBorder}`,
349
+ borderRadius: 8,
350
+ background: c.composerBg,
351
+ padding: "9px 12px",
352
+ minHeight: 22,
353
+ fontSize: 15,
354
+ color: c.text
355
+ },
356
+ children: hasText ? /* @__PURE__ */ jsxs("span", { children: [
357
+ composer.text,
358
+ /* @__PURE__ */ jsx(Caret, { color: c.caret })
359
+ ] }) : /* @__PURE__ */ jsx("span", { style: { color: c.placeholder }, children: "Reply\u2026" })
360
+ }
361
+ ) });
362
+ };
363
+ function buttonStyle(c, primary) {
364
+ const base = {
365
+ borderRadius: 4,
366
+ padding: "7px 12px",
367
+ fontWeight: 700,
368
+ fontSize: 13,
369
+ cursor: "default",
370
+ fontFamily: "inherit",
371
+ lineHeight: 1
372
+ };
373
+ return primary ? { ...base, background: c.primary, color: c.primaryText, border: "none" } : {
374
+ ...base,
375
+ background: "transparent",
376
+ color: c.buttonText,
377
+ border: `1px solid ${c.buttonBorder}`
378
+ };
379
+ }
380
+ var SystemMessage = ({ theme, message, author }) => {
381
+ const c = SLACK_COLORS[theme];
382
+ const actions = message.system?.actions ?? [];
383
+ return /* @__PURE__ */ jsxs(
384
+ "div",
385
+ {
386
+ style: {
387
+ display: "flex",
388
+ gap: 8,
389
+ padding: "8px 16px 2px",
390
+ ...fadeSlideIn(message.revealProgress)
391
+ },
392
+ children: [
393
+ /* @__PURE__ */ jsx("div", { style: { flex: "0 0 36px", width: 36 }, children: author ? /* @__PURE__ */ jsx(Avatar, { theme, participant: author, size: 36 }) : null }),
394
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
395
+ /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
396
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, color: c.text }, children: author?.name ?? "App" }),
397
+ /* @__PURE__ */ jsx(AppBadge, { c }),
398
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: c.subtle }, children: formatTime(message.atMs) })
399
+ ] }),
400
+ /* @__PURE__ */ jsxs(
401
+ "div",
402
+ {
403
+ style: {
404
+ marginTop: 4,
405
+ borderLeft: `4px solid ${c.cardBar}`,
406
+ borderRadius: 2,
407
+ paddingLeft: 12
408
+ },
409
+ children: [
410
+ /* @__PURE__ */ jsx("div", { style: { color: c.text }, children: /* @__PURE__ */ jsx(MessageContent, { nodes: message.content, styles: markStyles(c) }) }),
411
+ actions.length > 0 ? /* @__PURE__ */ jsx("div", { style: { display: "flex", gap: 8, marginTop: 8 }, children: actions.map((a, i) => /* @__PURE__ */ jsx("button", { type: "button", style: buttonStyle(c, i === 0), children: a.label }, i)) }) : null
412
+ ]
413
+ }
414
+ )
415
+ ] })
416
+ ]
417
+ }
418
+ );
419
+ };
420
+ var Message = ({ theme, message, author }) => {
421
+ const c = SLACK_COLORS[theme];
422
+ const grouped = message.isGrouped;
423
+ return /* @__PURE__ */ jsxs(
424
+ "div",
425
+ {
426
+ style: {
427
+ display: "flex",
428
+ gap: 8,
429
+ padding: grouped ? "2px 16px" : "8px 16px 2px",
430
+ ...fadeSlideIn(message.revealProgress)
431
+ },
432
+ children: [
433
+ /* @__PURE__ */ jsx("div", { style: { flex: "0 0 36px", width: 36 }, children: grouped ? null : /* @__PURE__ */ jsx(Avatar, { theme, participant: author, size: 36 }) }),
434
+ /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [
435
+ grouped ? null : /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "baseline", gap: 6 }, children: [
436
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 700, color: c.text }, children: author.name }),
437
+ author.kind === "app" ? /* @__PURE__ */ jsx(AppBadge, { c }) : null,
438
+ /* @__PURE__ */ jsx("span", { style: { fontSize: 12, color: c.subtle, marginLeft: 2 }, children: formatTime(message.atMs) })
439
+ ] }),
440
+ /* @__PURE__ */ jsx("div", { style: { color: c.text, wordBreak: "break-word" }, children: /* @__PURE__ */ jsx(
441
+ MessageContent,
442
+ {
443
+ nodes: message.content,
444
+ styles: markStyles(c),
445
+ imageStyle: {
446
+ borderRadius: 8,
447
+ marginTop: 4,
448
+ border: `1px solid ${c.border}`,
449
+ maxWidth: 360
450
+ }
451
+ }
452
+ ) }),
453
+ message.reactions.length > 0 ? /* @__PURE__ */ jsx(
454
+ "div",
455
+ {
456
+ style: {
457
+ display: "flex",
458
+ gap: 4,
459
+ marginTop: 4,
460
+ flexWrap: "wrap"
461
+ },
462
+ children: message.reactions.map((r, i) => /* @__PURE__ */ jsx(Reaction, { theme, reaction: r }, i))
463
+ }
464
+ ) : null
465
+ ] })
466
+ ]
467
+ }
468
+ );
469
+ };
470
+ var Frame = ({
471
+ theme,
472
+ options,
473
+ children
474
+ }) => {
475
+ const c = SLACK_COLORS[theme];
476
+ const channel = typeof options?.channel === "string" ? options.channel : "#general";
477
+ return /* @__PURE__ */ jsxs(
478
+ "div",
479
+ {
480
+ style: {
481
+ fontFamily: SLACK_FONT_STACK,
482
+ background: c.bg,
483
+ color: c.text,
484
+ display: "flex",
485
+ flexDirection: "column",
486
+ height: "100%",
487
+ width: "100%",
488
+ fontSize: 15,
489
+ lineHeight: 1.46668,
490
+ WebkitFontSmoothing: "antialiased"
491
+ },
492
+ children: [
493
+ /* @__PURE__ */ jsxs(
494
+ "header",
495
+ {
496
+ style: {
497
+ flex: "0 0 auto",
498
+ padding: "10px 16px",
499
+ borderBottom: `1px solid ${c.border}`,
500
+ display: "flex",
501
+ alignItems: "baseline",
502
+ gap: 8
503
+ },
504
+ children: [
505
+ /* @__PURE__ */ jsx("span", { style: { fontWeight: 900, fontSize: 18, color: c.text }, children: "Thread" }),
506
+ /* @__PURE__ */ jsx("span", { style: { color: c.subtle, fontSize: 13 }, children: channel })
507
+ ]
508
+ }
509
+ ),
510
+ /* @__PURE__ */ jsx(
511
+ "div",
512
+ {
513
+ style: {
514
+ flex: "1 1 auto",
515
+ minHeight: 0,
516
+ display: "flex",
517
+ flexDirection: "column",
518
+ // Breathing room so the last message/card never touches the bottom edge.
519
+ paddingBottom: 12
520
+ },
521
+ children
522
+ }
523
+ )
524
+ ]
525
+ }
526
+ );
527
+ };
528
+ var slackComponents = {
529
+ Frame,
530
+ Message,
531
+ TypingIndicator,
532
+ Reaction,
533
+ Composer,
534
+ SystemMessage,
535
+ Avatar
536
+ };
537
+
538
+ // src/slack/capabilities.ts
539
+ var slackCapabilities = {
540
+ events: {
541
+ message: "native",
542
+ reaction: "native",
543
+ typing: "native",
544
+ // "X is typing…"
545
+ composerType: "native",
546
+ send: "native",
547
+ edit: "native",
548
+ delete: "native",
549
+ readReceipt: "unsupported",
550
+ // Slack has no per-message read receipts in threads
551
+ system: "native",
552
+ // app/PR cards
553
+ beat: "native"
554
+ },
555
+ content: {
556
+ text: true,
557
+ image: true
558
+ },
559
+ reactions: true,
560
+ threads: true,
561
+ readReceipts: false
562
+ };
563
+
564
+ // src/slack/index.ts
565
+ var slackOptionsSchema = z.object({
566
+ /** Channel label shown in the thread header (e.g. `"#alerts"`). */
567
+ channel: z.string().optional(),
568
+ showThreadHeader: z.boolean().optional()
569
+ });
570
+ var slack = defineSkin({
571
+ id: "slack",
572
+ meta: {
573
+ name: "Slack",
574
+ defaultCanvas: { width: 880, height: 720 },
575
+ supportsThemes: ["light", "dark"],
576
+ capabilities: slackCapabilities,
577
+ optionsSchema: slackOptionsSchema,
578
+ fonts: slackFonts
579
+ },
580
+ components: slackComponents,
581
+ tokens: slackTokens
582
+ });
583
+ var slack_default = slack;
584
+
585
+ export { SLACK_COLORS, slack, slack_default };
586
+ //# sourceMappingURL=chunk-UFC4ODW5.js.map
587
+ //# sourceMappingURL=chunk-UFC4ODW5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/slack/tokens.ts","../src/slack/fonts.ts","../src/slack/components.tsx","../src/slack/capabilities.ts","../src/slack/index.ts"],"names":[],"mappings":"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","file":"chunk-UFC4ODW5.js","sourcesContent":["import type { ResolvedTheme } from \"@typecaast/core\";\nimport type { SkinTokens } from \"@typecaast/skin-kit\";\n\n/** The Slack-style palette per theme (matched to the real app's spacing/color). */\nexport interface SlackColors {\n bg: string;\n text: string;\n subtle: string;\n border: string;\n headerBg: string;\n link: string;\n mentionText: string;\n mentionBg: string;\n codeText: string;\n codeBg: string;\n codeBorder: string;\n reactionBg: string;\n reactionBorder: string;\n reactionText: string;\n composerBg: string;\n composerBorder: string;\n placeholder: string;\n primary: string;\n primaryText: string;\n buttonBorder: string;\n buttonText: string;\n appBadgeBg: string;\n appBadgeText: string;\n cardBar: string;\n caret: string;\n}\n\nexport const SLACK_COLORS: Record<ResolvedTheme, SlackColors> = {\n light: {\n bg: \"#ffffff\",\n text: \"#1d1c1d\",\n subtle: \"#616061\",\n border: \"#e2e2e2\",\n headerBg: \"#ffffff\",\n link: \"#1264a3\",\n mentionText: \"#1264a3\",\n mentionBg: \"#e8f5fa\",\n codeText: \"#e01e5a\",\n codeBg: \"#f6f6f6\",\n codeBorder: \"#e2e2e2\",\n reactionBg: \"#f8f8f8\",\n reactionBorder: \"#e2e2e2\",\n reactionText: \"#454245\",\n composerBg: \"#ffffff\",\n composerBorder: \"#8d8d8d\",\n placeholder: \"#8d8d8d\",\n primary: \"#007a5a\",\n primaryText: \"#ffffff\",\n buttonBorder: \"#d1d1d1\",\n buttonText: \"#1d1c1d\",\n appBadgeBg: \"#e8e8e8\",\n appBadgeText: \"#616061\",\n cardBar: \"#dddddd\",\n caret: \"#1264a3\",\n },\n dark: {\n bg: \"#1a1d21\",\n text: \"#d1d2d3\",\n subtle: \"#ababad\",\n border: \"#35373b\",\n headerBg: \"#1a1d21\",\n link: \"#1d9bd1\",\n mentionText: \"#1d9bd1\",\n mentionBg: \"rgba(29,155,209,0.12)\",\n codeText: \"#e06c9a\",\n codeBg: \"#222529\",\n codeBorder: \"#35373b\",\n reactionBg: \"#222529\",\n reactionBorder: \"#35373b\",\n reactionText: \"#d1d2d3\",\n composerBg: \"#222529\",\n composerBorder: \"#565856\",\n placeholder: \"#9a9b9d\",\n primary: \"#007a5a\",\n primaryText: \"#ffffff\",\n buttonBorder: \"#565856\",\n buttonText: \"#d1d2d3\",\n appBadgeBg: \"#35373b\",\n appBadgeText: \"#ababad\",\n cardBar: \"#35373b\",\n caret: \"#1d9bd1\",\n },\n};\n\n/** Pack the color sets into the generic `SkinTokens` shape for the contract. */\nexport const slackTokens: { light: SkinTokens; dark: SkinTokens } = {\n light: { colors: SLACK_COLORS.light as unknown as Record<string, string> },\n dark: { colors: SLACK_COLORS.dark as unknown as Record<string, string> },\n};\n","import type { FontDeclaration } from \"@typecaast/skin-kit\";\n\n/**\n * Slack uses **Lato** (OFL, bundleable) — the real font, not a substitute\n * (PLAN §19). Sources point at the OFL woff2 files; real bundling/pinning of\n * the font assets lands with the font-map gate (M3a / video runtime).\n */\nexport const slackFonts: FontDeclaration[] = [\n {\n family: \"Lato\",\n weights: [400, 700, 900],\n sources: [\n {\n url: \"https://fonts.gstatic.com/s/lato/v24/S6uyw4BMUTPHjx4wXiWtFCc.woff2\",\n weight: 400,\n format: \"woff2\",\n },\n {\n url: \"https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2\",\n weight: 700,\n format: \"woff2\",\n },\n {\n url: \"https://fonts.gstatic.com/s/lato/v24/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2\",\n weight: 900,\n format: \"woff2\",\n },\n ],\n },\n];\n\n/** The CSS font stack the skin renders with (declared font first). */\nexport const SLACK_FONT_STACK =\n 'Lato, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif';\n","import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type FC,\n type ReactNode,\n} from \"react\";\nimport type {\n AvatarProps,\n ComposerProps,\n FrameProps,\n MessageProps,\n ReactionProps,\n SystemProps,\n TypingProps,\n} from \"@typecaast/core\";\nimport {\n fadeSlideIn,\n MessageContent,\n popIn,\n type ContentStyles,\n} from \"@typecaast/skin-kit\";\nimport { SLACK_COLORS, type SlackColors } from \"./tokens.js\";\nimport { SLACK_FONT_STACK } from \"./fonts.js\";\n\nconst AVATAR_RADIUS = 8;\n\n/** Join reactor names the way Slack does (\"A\", \"A and B\", \"A, B, and C\"). */\nfunction joinNames(names: string[]): string {\n if (names.length <= 1) return names[0] ?? \"\";\n if (names.length === 2) return `${names[0]} and ${names[1]}`;\n return `${names.slice(0, -1).join(\", \")}, and ${names[names.length - 1]}`;\n}\n\n/** Fabricate a stable wall-clock time from a timeline offset (sim starts 9:00am). */\nfunction formatTime(atMs: number): string {\n const base = 9 * 3600 * 1000;\n const total = Math.floor((base + atMs) / 1000);\n const h = Math.floor(total / 3600) % 24;\n const m = Math.floor((total % 3600) / 60);\n const ampm = h >= 12 ? \"PM\" : \"AM\";\n const hr = h % 12 === 0 ? 12 : h % 12;\n return `${hr}:${String(m).padStart(2, \"0\")} ${ampm}`;\n}\n\nfunction initials(name: string): string {\n return name\n .split(/\\s+/)\n .map((w) => w.charAt(0))\n .slice(0, 2)\n .join(\"\")\n .toUpperCase();\n}\n\nfunction markStyles(c: SlackColors): ContentStyles {\n return {\n link: { color: c.link, textDecoration: \"none\" },\n mention: {\n color: c.mentionText,\n background: c.mentionBg,\n borderRadius: 3,\n padding: \"0 2px\",\n fontWeight: 600,\n },\n code: {\n color: c.codeText,\n background: c.codeBg,\n border: `1px solid ${c.codeBorder}`,\n borderRadius: 3,\n padding: \"1px 4px\",\n fontFamily: \"Menlo, Monaco, Consolas, monospace\",\n fontSize: \"0.85em\",\n },\n };\n}\n\nconst AppBadge: FC<{ c: SlackColors }> = ({ c }) => (\n <span\n style={{\n fontSize: 10,\n fontWeight: 700,\n letterSpacing: 0.4,\n background: c.appBadgeBg,\n color: c.appBadgeText,\n borderRadius: 2,\n padding: \"1px 4px\",\n }}\n >\n APP\n </span>\n);\n\nconst Avatar: FC<AvatarProps> = ({ theme, participant, size = 36 }) => {\n const c = SLACK_COLORS[theme];\n if (participant.avatar) {\n return (\n <img\n src={participant.avatar}\n alt={participant.name}\n width={size}\n height={size}\n style={{\n width: size,\n height: size,\n borderRadius: AVATAR_RADIUS,\n objectFit: \"cover\",\n display: \"block\",\n }}\n />\n );\n }\n return (\n <div\n aria-label={participant.name}\n style={{\n width: size,\n height: size,\n borderRadius: AVATAR_RADIUS,\n background: participant.color ?? \"#4a154b\",\n color: \"#ffffff\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n fontWeight: 700,\n fontSize: size * 0.4,\n border: theme === \"dark\" ? `1px solid ${c.border}` : undefined,\n }}\n >\n {initials(participant.name)}\n </div>\n );\n};\n\n/** Nearest ancestor that clips overflow — the bound to keep the tooltip inside. */\nfunction clippingAncestor(el: HTMLElement | null): HTMLElement | null {\n let node = el?.parentElement ?? null;\n while (node) {\n const o = getComputedStyle(node).overflow;\n if (o && o !== \"visible\") return node;\n node = node.parentElement;\n }\n return null;\n}\n\n/**\n * Slack's custom hover tooltip: big emoji over \"<names> reacted with :code:\",\n * with a tail pointing at the reaction. Centered, but **clamped** to stay\n * inside the sim viewport (like Slack clamps to the window) — the tail tracks\n * the reaction so it still points correctly after a shift.\n */\nconst ReactionTooltip: FC<{ reaction: ReactionProps[\"reaction\"] }> = ({\n reaction,\n}) => {\n const ref = useRef<HTMLSpanElement>(null);\n const [dx, setDx] = useState(0);\n const code = reaction.shortcode;\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n const bound = clippingAncestor(el)?.getBoundingClientRect();\n if (!bound) return;\n const rect = el.getBoundingClientRect();\n const m = 8;\n let shift = 0;\n if (rect.left < bound.left + m) shift = bound.left + m - rect.left;\n else if (rect.right > bound.right - m) shift = bound.right - m - rect.right;\n setDx(shift);\n }, []);\n\n return (\n <span\n ref={ref}\n role=\"tooltip\"\n style={{\n position: \"absolute\",\n bottom: \"calc(100% + 9px)\",\n left: \"50%\",\n transform: `translateX(calc(-50% + ${dx}px))`,\n zIndex: 20,\n width: 220,\n boxSizing: \"border-box\",\n background: \"#1a1d21\",\n color: \"#e8e8e8\",\n borderRadius: 12,\n padding: \"16px 16px 14px\",\n textAlign: \"center\",\n fontSize: 15,\n lineHeight: 1.4,\n boxShadow: \"0 4px 14px rgba(0,0,0,0.4)\",\n pointerEvents: \"none\",\n }}\n >\n <span style={{ display: \"block\", fontSize: 36, marginBottom: 8 }}>\n {reaction.emoji}\n </span>\n <span style={{ fontWeight: 700 }}>{joinNames(reaction.byNames)}</span>\n <span style={{ color: \"#ababad\" }}> reacted with </span>\n <span style={{ color: \"#ababad\" }}>\n {code ? `:${code}:` : reaction.emoji}\n </span>\n {/* downward tail — offset opposite the clamp shift so it stays on the chip */}\n <span\n style={{\n position: \"absolute\",\n top: \"100%\",\n left: `calc(50% - ${dx}px)`,\n transform: \"translateX(-50%)\",\n width: 0,\n height: 0,\n borderLeft: \"7px solid transparent\",\n borderRight: \"7px solid transparent\",\n borderTop: \"7px solid #1a1d21\",\n }}\n />\n </span>\n );\n};\n\nconst Reaction: FC<ReactionProps> = ({ theme, reaction }) => {\n const c = SLACK_COLORS[theme];\n const [hover, setHover] = useState(false);\n const hasReactors = reaction.byNames.length > 0;\n return (\n <span\n style={{\n position: \"relative\",\n display: \"inline-flex\",\n ...popIn(reaction.progress),\n }}\n onMouseEnter={() => setHover(true)}\n onMouseLeave={() => setHover(false)}\n >\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n gap: 4,\n background: c.reactionBg,\n border: `1px solid ${c.reactionBorder}`,\n color: c.reactionText,\n borderRadius: 12,\n padding: \"1px 7px\",\n height: 22,\n fontSize: 12,\n cursor: hasReactors ? \"pointer\" : \"default\",\n }}\n >\n <span style={{ fontSize: 13 }}>{reaction.emoji}</span>\n <span style={{ fontWeight: 600, fontVariantNumeric: \"tabular-nums\" }}>\n {reaction.count}\n </span>\n </span>\n {hover && hasReactors ? <ReactionTooltip reaction={reaction} /> : null}\n </span>\n );\n};\n\n// Slack shows a plain italicized \"<name> is typing…\" line — no bouncing dots\n// (those are an iMessage/WhatsApp idiom, not Slack's).\nconst TypingIndicator: FC<TypingProps> = ({ theme, author }) => {\n const c = SLACK_COLORS[theme];\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n padding: \"2px 16px 4px 60px\",\n color: c.subtle,\n fontSize: 12,\n fontStyle: \"italic\",\n }}\n >\n <span>{author.name} is typing…</span>\n </div>\n );\n};\n\nconst Caret: FC<{ color: string }> = ({ color }) => (\n <span\n style={{\n display: \"inline-block\",\n width: 1.5,\n height: \"1.05em\",\n background: color,\n marginLeft: 1,\n verticalAlign: \"text-bottom\",\n }}\n />\n);\n\nconst Composer: FC<ComposerProps> = ({ theme, composer }) => {\n const c = SLACK_COLORS[theme];\n const hasText = composer.text.length > 0;\n return (\n <div style={{ flex: \"0 0 auto\", padding: \"4px 16px 14px\" }}>\n <div\n style={{\n border: `1px solid ${c.composerBorder}`,\n borderRadius: 8,\n background: c.composerBg,\n padding: \"9px 12px\",\n minHeight: 22,\n fontSize: 15,\n color: c.text,\n }}\n >\n {hasText ? (\n <span>\n {composer.text}\n <Caret color={c.caret} />\n </span>\n ) : (\n <span style={{ color: c.placeholder }}>Reply…</span>\n )}\n </div>\n </div>\n );\n};\n\nfunction buttonStyle(c: SlackColors, primary: boolean): CSSProperties {\n const base: CSSProperties = {\n borderRadius: 4,\n padding: \"7px 12px\",\n fontWeight: 700,\n fontSize: 13,\n cursor: \"default\",\n fontFamily: \"inherit\",\n lineHeight: 1,\n };\n return primary\n ? { ...base, background: c.primary, color: c.primaryText, border: \"none\" }\n : {\n ...base,\n background: \"transparent\",\n color: c.buttonText,\n border: `1px solid ${c.buttonBorder}`,\n };\n}\n\nconst SystemMessage: FC<SystemProps> = ({ theme, message, author }) => {\n const c = SLACK_COLORS[theme];\n const actions = message.system?.actions ?? [];\n return (\n <div\n style={{\n display: \"flex\",\n gap: 8,\n padding: \"8px 16px 2px\",\n ...fadeSlideIn(message.revealProgress),\n }}\n >\n <div style={{ flex: \"0 0 36px\", width: 36 }}>\n {author ? (\n <Avatar theme={theme} participant={author} size={36} />\n ) : null}\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: 6 }}>\n <span style={{ fontWeight: 700, color: c.text }}>\n {author?.name ?? \"App\"}\n </span>\n <AppBadge c={c} />\n <span style={{ fontSize: 12, color: c.subtle }}>\n {formatTime(message.atMs)}\n </span>\n </div>\n <div\n style={{\n marginTop: 4,\n borderLeft: `4px solid ${c.cardBar}`,\n borderRadius: 2,\n paddingLeft: 12,\n }}\n >\n <div style={{ color: c.text }}>\n <MessageContent nodes={message.content} styles={markStyles(c)} />\n </div>\n {actions.length > 0 ? (\n <div style={{ display: \"flex\", gap: 8, marginTop: 8 }}>\n {actions.map((a, i) => (\n <button key={i} type=\"button\" style={buttonStyle(c, i === 0)}>\n {a.label}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n </div>\n </div>\n );\n};\n\nconst Message: FC<MessageProps> = ({ theme, message, author }) => {\n const c = SLACK_COLORS[theme];\n const grouped = message.isGrouped;\n return (\n <div\n style={{\n display: \"flex\",\n gap: 8,\n padding: grouped ? \"2px 16px\" : \"8px 16px 2px\",\n ...fadeSlideIn(message.revealProgress),\n }}\n >\n <div style={{ flex: \"0 0 36px\", width: 36 }}>\n {grouped ? null : (\n <Avatar theme={theme} participant={author} size={36} />\n )}\n </div>\n <div style={{ flex: 1, minWidth: 0 }}>\n {grouped ? null : (\n <div style={{ display: \"flex\", alignItems: \"baseline\", gap: 6 }}>\n <span style={{ fontWeight: 700, color: c.text }}>\n {author.name}\n </span>\n {author.kind === \"app\" ? <AppBadge c={c} /> : null}\n <span style={{ fontSize: 12, color: c.subtle, marginLeft: 2 }}>\n {formatTime(message.atMs)}\n </span>\n </div>\n )}\n <div style={{ color: c.text, wordBreak: \"break-word\" }}>\n <MessageContent\n nodes={message.content}\n styles={markStyles(c)}\n imageStyle={{\n borderRadius: 8,\n marginTop: 4,\n border: `1px solid ${c.border}`,\n maxWidth: 360,\n }}\n />\n </div>\n {message.reactions.length > 0 ? (\n <div\n style={{\n display: \"flex\",\n gap: 4,\n marginTop: 4,\n flexWrap: \"wrap\",\n }}\n >\n {message.reactions.map((r, i) => (\n <Reaction key={i} theme={theme} reaction={r} />\n ))}\n </div>\n ) : null}\n </div>\n </div>\n );\n};\n\nconst Frame: FC<FrameProps & { children?: ReactNode }> = ({\n theme,\n options,\n children,\n}) => {\n const c = SLACK_COLORS[theme];\n const channel =\n typeof options?.channel === \"string\" ? options.channel : \"#general\";\n return (\n <div\n style={{\n fontFamily: SLACK_FONT_STACK,\n background: c.bg,\n color: c.text,\n display: \"flex\",\n flexDirection: \"column\",\n height: \"100%\",\n width: \"100%\",\n fontSize: 15,\n lineHeight: 1.46668,\n WebkitFontSmoothing: \"antialiased\",\n }}\n >\n <header\n style={{\n flex: \"0 0 auto\",\n padding: \"10px 16px\",\n borderBottom: `1px solid ${c.border}`,\n display: \"flex\",\n alignItems: \"baseline\",\n gap: 8,\n }}\n >\n <span style={{ fontWeight: 900, fontSize: 18, color: c.text }}>\n Thread\n </span>\n <span style={{ color: c.subtle, fontSize: 13 }}>{channel}</span>\n </header>\n <div\n style={{\n flex: \"1 1 auto\",\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n // Breathing room so the last message/card never touches the bottom edge.\n paddingBottom: 12,\n }}\n >\n {children}\n </div>\n </div>\n );\n};\n\nexport const slackComponents = {\n Frame,\n Message,\n TypingIndicator,\n Reaction,\n Composer,\n SystemMessage,\n Avatar,\n};\n","import type { Capabilities } from \"@typecaast/skin-kit\";\n\n/** What the Slack skin supports and how it represents each event/content type. */\nexport const slackCapabilities: Capabilities = {\n events: {\n message: \"native\",\n reaction: \"native\",\n typing: \"native\", // \"X is typing…\"\n composerType: \"native\",\n send: \"native\",\n edit: \"native\",\n delete: \"native\",\n readReceipt: \"unsupported\", // Slack has no per-message read receipts in threads\n system: \"native\", // app/PR cards\n beat: \"native\",\n },\n content: {\n text: true,\n image: true,\n },\n reactions: true,\n threads: true,\n readReceipts: false,\n};\n","import { z } from \"zod\";\nimport { defineSkin } from \"@typecaast/skin-kit\";\nimport { slackComponents } from \"./components.js\";\nimport { slackCapabilities } from \"./capabilities.js\";\nimport { slackFonts } from \"./fonts.js\";\nimport { slackTokens } from \"./tokens.js\";\n\nconst slackOptionsSchema = z.object({\n /** Channel label shown in the thread header (e.g. `\"#alerts\"`). */\n channel: z.string().optional(),\n showThreadHeader: z.boolean().optional(),\n});\n\n/** A Slack-style thread skin (light + dark). Pixel-faithful, inert chrome. */\nexport const slack = defineSkin({\n id: \"slack\",\n meta: {\n name: \"Slack\",\n defaultCanvas: { width: 880, height: 720 },\n supportsThemes: [\"light\", \"dark\"],\n capabilities: slackCapabilities,\n optionsSchema: slackOptionsSchema,\n fonts: slackFonts,\n },\n components: slackComponents,\n tokens: slackTokens,\n});\n\n/** Default export so `@typecaast/skins/slack` can be lazy-imported uniformly. */\nexport default slack;\n"]}