@revikornmann/muka-ui 0.12.0 → 0.14.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 (112) hide show
  1. package/build/manifest.json +10 -0
  2. package/dist/cjs/components/AgentTaskList/AgentTaskList.js +1 -1
  3. package/dist/cjs/components/BadgeNumber/BadgeNumber.css +105 -0
  4. package/dist/cjs/components/BadgeNumber/BadgeNumber.js +19 -0
  5. package/dist/cjs/components/BadgeNumber/BadgeNumber.js.map +1 -0
  6. package/dist/cjs/components/BadgeNumber/index.js +11 -0
  7. package/dist/cjs/components/BadgeNumber/index.js.map +1 -0
  8. package/dist/cjs/components/ChatMessage/ChatMessage.css +324 -0
  9. package/dist/cjs/components/ChatMessage/ChatMessage.js +138 -0
  10. package/dist/cjs/components/ChatMessage/ChatMessage.js.map +1 -0
  11. package/dist/cjs/components/ChatMessage/index.js +7 -0
  12. package/dist/cjs/components/ChatMessage/index.js.map +1 -0
  13. package/dist/cjs/components/ChatMessageList/ChatMessageList.js +1 -1
  14. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.css +51 -0
  15. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.js +49 -0
  16. package/dist/cjs/components/ChatMessageStack/ChatMessageStack.js.map +1 -0
  17. package/dist/cjs/components/ChatMessageStack/index.js +6 -0
  18. package/dist/cjs/components/ChatMessageStack/index.js.map +1 -0
  19. package/dist/cjs/components/ChatPhotoGrid/ChatPhotoGrid.css +8 -2
  20. package/dist/cjs/components/ChatPhotoGrid/ChatPhotoGrid.js +1 -1
  21. package/dist/cjs/components/Menu/Menu.js +5 -4
  22. package/dist/cjs/components/Menu/Menu.js.map +1 -1
  23. package/dist/cjs/components/index.js +9 -5
  24. package/dist/cjs/components/index.js.map +1 -1
  25. package/dist/cjs/utils/useLongPress.js +71 -0
  26. package/dist/cjs/utils/useLongPress.js.map +1 -0
  27. package/dist/esm/components/AgentTaskList/AgentTaskList.js +1 -1
  28. package/dist/esm/components/BadgeNumber/BadgeNumber.css +105 -0
  29. package/dist/esm/components/BadgeNumber/BadgeNumber.js +15 -0
  30. package/dist/esm/components/BadgeNumber/BadgeNumber.js.map +1 -0
  31. package/dist/esm/components/BadgeNumber/index.js +3 -0
  32. package/dist/esm/components/BadgeNumber/index.js.map +1 -0
  33. package/dist/esm/components/ChatMessage/ChatMessage.css +324 -0
  34. package/dist/esm/components/ChatMessage/ChatMessage.js +134 -0
  35. package/dist/esm/components/ChatMessage/ChatMessage.js.map +1 -0
  36. package/dist/esm/components/ChatMessage/index.js +2 -0
  37. package/dist/esm/components/ChatMessage/index.js.map +1 -0
  38. package/dist/esm/components/ChatMessageList/ChatMessageList.js +1 -1
  39. package/dist/esm/components/ChatMessageStack/ChatMessageStack.css +51 -0
  40. package/dist/esm/components/ChatMessageStack/ChatMessageStack.js +42 -0
  41. package/dist/esm/components/ChatMessageStack/ChatMessageStack.js.map +1 -0
  42. package/dist/esm/components/ChatMessageStack/index.js +2 -0
  43. package/dist/esm/components/ChatMessageStack/index.js.map +1 -0
  44. package/dist/esm/components/ChatPhotoGrid/ChatPhotoGrid.css +8 -2
  45. package/dist/esm/components/ChatPhotoGrid/ChatPhotoGrid.js +1 -1
  46. package/dist/esm/components/Menu/Menu.js +5 -4
  47. package/dist/esm/components/Menu/Menu.js.map +1 -1
  48. package/dist/esm/components/index.js +3 -1
  49. package/dist/esm/components/index.js.map +1 -1
  50. package/dist/esm/utils/useLongPress.js +68 -0
  51. package/dist/esm/utils/useLongPress.js.map +1 -0
  52. package/dist/styles/components/BadgeNumber.css +105 -0
  53. package/dist/styles/components/ChatMessage.css +324 -0
  54. package/dist/styles/components/ChatMessageStack.css +51 -0
  55. package/dist/styles/components/ChatPhotoGrid.css +8 -2
  56. package/dist/styles/index.css +2694 -2475
  57. package/dist/styles/muka-dark.css +2694 -2475
  58. package/dist/styles/muka-light.css +2694 -2475
  59. package/dist/styles/tokens-bouwplan-dark.css +32 -5
  60. package/dist/styles/tokens-bouwplan-light.css +32 -5
  61. package/dist/styles/tokens-fscl-dark.css +32 -5
  62. package/dist/styles/tokens-fscl-light.css +32 -5
  63. package/dist/styles/tokens-grip-dark.css +32 -5
  64. package/dist/styles/tokens-grip-light.css +32 -5
  65. package/dist/styles/tokens-muka-dark.css +32 -5
  66. package/dist/styles/tokens-muka-light.css +32 -5
  67. package/dist/styles/tokens-wireframe-dark.css +31 -4
  68. package/dist/styles/tokens-wireframe-light.css +31 -4
  69. package/dist/styles/wireframe-dark.css +2693 -2474
  70. package/dist/styles/wireframe-light.css +2693 -2474
  71. package/dist/types/components/AgentTaskList/AgentTaskList.d.ts +1 -1
  72. package/dist/types/components/BadgeNumber/BadgeNumber.d.ts +17 -0
  73. package/dist/types/components/BadgeNumber/BadgeNumber.d.ts.map +1 -0
  74. package/dist/types/components/BadgeNumber/index.d.ts +3 -0
  75. package/dist/types/components/BadgeNumber/index.d.ts.map +1 -0
  76. package/dist/types/components/ChatMessage/ChatMessage.d.ts +127 -0
  77. package/dist/types/components/ChatMessage/ChatMessage.d.ts.map +1 -0
  78. package/dist/types/components/ChatMessage/index.d.ts +2 -0
  79. package/dist/types/components/ChatMessage/index.d.ts.map +1 -0
  80. package/dist/types/components/ChatMessageList/ChatMessageList.d.ts +2 -2
  81. package/dist/types/components/ChatMessageList/ChatMessageList.d.ts.map +1 -1
  82. package/dist/types/components/ChatMessageStack/ChatMessageStack.d.ts +46 -0
  83. package/dist/types/components/ChatMessageStack/ChatMessageStack.d.ts.map +1 -0
  84. package/dist/types/components/ChatMessageStack/index.d.ts +2 -0
  85. package/dist/types/components/ChatMessageStack/index.d.ts.map +1 -0
  86. package/dist/types/components/ChatPhotoGrid/ChatPhotoGrid.d.ts +1 -1
  87. package/dist/types/components/Menu/Menu.d.ts +12 -0
  88. package/dist/types/components/Menu/Menu.d.ts.map +1 -1
  89. package/dist/types/components/index.d.ts +3 -1
  90. package/dist/types/components/index.d.ts.map +1 -1
  91. package/dist/types/utils/useLongPress.d.ts +28 -0
  92. package/dist/types/utils/useLongPress.d.ts.map +1 -0
  93. package/package.json +1 -1
  94. package/tokens/t3-semantics/ui.json +29 -0
  95. package/tokens/t4-components/badge-number.json +48 -0
  96. package/tokens/t4-components/chatbubble.json +33 -7
  97. package/tokens/t4-components/chatphotogrid.json +2 -2
  98. package/dist/cjs/components/ChatBubble/ChatBubble.css +0 -300
  99. package/dist/cjs/components/ChatBubble/ChatBubble.js +0 -37
  100. package/dist/cjs/components/ChatBubble/ChatBubble.js.map +0 -1
  101. package/dist/cjs/components/ChatBubble/index.js +0 -6
  102. package/dist/cjs/components/ChatBubble/index.js.map +0 -1
  103. package/dist/esm/components/ChatBubble/ChatBubble.css +0 -300
  104. package/dist/esm/components/ChatBubble/ChatBubble.js +0 -33
  105. package/dist/esm/components/ChatBubble/ChatBubble.js.map +0 -1
  106. package/dist/esm/components/ChatBubble/index.js +0 -2
  107. package/dist/esm/components/ChatBubble/index.js.map +0 -1
  108. package/dist/styles/components/ChatBubble.css +0 -300
  109. package/dist/types/components/ChatBubble/ChatBubble.d.ts +0 -85
  110. package/dist/types/components/ChatBubble/ChatBubble.d.ts.map +0 -1
  111. package/dist/types/components/ChatBubble/index.d.ts +0 -2
  112. package/dist/types/components/ChatBubble/index.d.ts.map +0 -1
@@ -54,6 +54,7 @@
54
54
  "tokens/t4-components/bottombar.json",
55
55
  "tokens/t4-components/view.json",
56
56
  "tokens/t4-components/badge.json",
57
+ "tokens/t4-components/badge-number.json",
57
58
  "tokens/t4-components/table.json",
58
59
  "tokens/t4-components/datatable.json",
59
60
  "tokens/t4-components/datepicker.json",
@@ -116,6 +117,7 @@
116
117
  "tokens/t4-components/bottombar.json",
117
118
  "tokens/t4-components/view.json",
118
119
  "tokens/t4-components/badge.json",
120
+ "tokens/t4-components/badge-number.json",
119
121
  "tokens/t4-components/table.json",
120
122
  "tokens/t4-components/datatable.json",
121
123
  "tokens/t4-components/datepicker.json",
@@ -177,6 +179,7 @@
177
179
  "tokens/t4-components/bottombar.json",
178
180
  "tokens/t4-components/view.json",
179
181
  "tokens/t4-components/badge.json",
182
+ "tokens/t4-components/badge-number.json",
180
183
  "tokens/t4-components/table.json",
181
184
  "tokens/t4-components/datatable.json",
182
185
  "tokens/t4-components/datepicker.json",
@@ -238,6 +241,7 @@
238
241
  "tokens/t4-components/bottombar.json",
239
242
  "tokens/t4-components/view.json",
240
243
  "tokens/t4-components/badge.json",
244
+ "tokens/t4-components/badge-number.json",
241
245
  "tokens/t4-components/table.json",
242
246
  "tokens/t4-components/datatable.json",
243
247
  "tokens/t4-components/datepicker.json",
@@ -299,6 +303,7 @@
299
303
  "tokens/t4-components/bottombar.json",
300
304
  "tokens/t4-components/view.json",
301
305
  "tokens/t4-components/badge.json",
306
+ "tokens/t4-components/badge-number.json",
302
307
  "tokens/t4-components/table.json",
303
308
  "tokens/t4-components/datatable.json",
304
309
  "tokens/t4-components/datepicker.json",
@@ -360,6 +365,7 @@
360
365
  "tokens/t4-components/bottombar.json",
361
366
  "tokens/t4-components/view.json",
362
367
  "tokens/t4-components/badge.json",
368
+ "tokens/t4-components/badge-number.json",
363
369
  "tokens/t4-components/table.json",
364
370
  "tokens/t4-components/datatable.json",
365
371
  "tokens/t4-components/datepicker.json",
@@ -421,6 +427,7 @@
421
427
  "tokens/t4-components/bottombar.json",
422
428
  "tokens/t4-components/view.json",
423
429
  "tokens/t4-components/badge.json",
430
+ "tokens/t4-components/badge-number.json",
424
431
  "tokens/t4-components/table.json",
425
432
  "tokens/t4-components/datatable.json",
426
433
  "tokens/t4-components/datepicker.json",
@@ -482,6 +489,7 @@
482
489
  "tokens/t4-components/bottombar.json",
483
490
  "tokens/t4-components/view.json",
484
491
  "tokens/t4-components/badge.json",
492
+ "tokens/t4-components/badge-number.json",
485
493
  "tokens/t4-components/table.json",
486
494
  "tokens/t4-components/datatable.json",
487
495
  "tokens/t4-components/datepicker.json",
@@ -543,6 +551,7 @@
543
551
  "tokens/t4-components/bottombar.json",
544
552
  "tokens/t4-components/view.json",
545
553
  "tokens/t4-components/badge.json",
554
+ "tokens/t4-components/badge-number.json",
546
555
  "tokens/t4-components/table.json",
547
556
  "tokens/t4-components/datatable.json",
548
557
  "tokens/t4-components/datepicker.json",
@@ -604,6 +613,7 @@
604
613
  "tokens/t4-components/bottombar.json",
605
614
  "tokens/t4-components/view.json",
606
615
  "tokens/t4-components/badge.json",
616
+ "tokens/t4-components/badge-number.json",
607
617
  "tokens/t4-components/table.json",
608
618
  "tokens/t4-components/datatable.json",
609
619
  "tokens/t4-components/datepicker.json",
@@ -12,7 +12,7 @@ require("./AgentTaskList.css");
12
12
  * Renders a header + a vertical timeline of tasks the agent is performing
13
13
  * (e.g. searching the web, querying a database, drafting an answer).
14
14
  *
15
- * Typically rendered above the agent's final reply inside a `ChatBubble`
15
+ * Typically rendered above the agent's final reply inside a `ChatMessage`
16
16
  * with `variant="agent"`.
17
17
  */
18
18
  const AgentTaskList = ({ title, tasks, defaultOpen = true, open: controlledOpen, onOpenChange, className = '', }) => {
@@ -0,0 +1,105 @@
1
+ /* BadgeNumber Component Styles - Using Muka Design Tokens */
2
+
3
+ .muka-badge-number {
4
+ display: inline-flex;
5
+ align-items: center;
6
+ justify-content: center;
7
+ border-radius: var(--border-radius-full);
8
+ white-space: nowrap;
9
+ user-select: none;
10
+ box-sizing: border-box;
11
+ }
12
+
13
+ /*
14
+ * Sizes — fixed height, matching min-width (so a single digit renders as a
15
+ * circle), horizontal padding, and bold label typography. Vertical centering
16
+ * is handled by the fixed height + align-items: center.
17
+ */
18
+ .muka-badge-number--2xs {
19
+ height: var(--badge-number-size-2xs);
20
+ min-width: var(--badge-number-size-2xs);
21
+ padding: 0 var(--badge-number-padding-2xs);
22
+ font-family: var(--text-label-xs-bold-fontFamily);
23
+ font-weight: var(--text-label-xs-bold-fontWeight);
24
+ font-size: var(--text-label-xs-bold-fontSize);
25
+ line-height: var(--text-label-xs-bold-lineHeight);
26
+ }
27
+
28
+ .muka-badge-number--xs {
29
+ height: var(--badge-number-size-xs);
30
+ min-width: var(--badge-number-size-xs);
31
+ padding: 0 var(--badge-number-padding-xs);
32
+ font-family: var(--text-label-sm-bold-fontFamily);
33
+ font-weight: var(--text-label-sm-bold-fontWeight);
34
+ font-size: var(--text-label-sm-bold-fontSize);
35
+ line-height: var(--text-label-sm-bold-lineHeight);
36
+ }
37
+
38
+ .muka-badge-number--sm {
39
+ height: var(--badge-number-size-sm);
40
+ min-width: var(--badge-number-size-sm);
41
+ padding: 0 var(--badge-number-padding-sm);
42
+ font-family: var(--text-label-md-bold-fontFamily);
43
+ font-weight: var(--text-label-md-bold-fontWeight);
44
+ font-size: var(--text-label-md-bold-fontSize);
45
+ line-height: var(--text-label-md-bold-lineHeight);
46
+ }
47
+
48
+ .muka-badge-number--md {
49
+ height: var(--badge-number-size-md);
50
+ min-width: var(--badge-number-size-md);
51
+ padding: 0 var(--badge-number-padding-md);
52
+ font-family: var(--text-label-lg-bold-fontFamily);
53
+ font-weight: var(--text-label-lg-bold-fontWeight);
54
+ font-size: var(--text-label-lg-bold-fontSize);
55
+ line-height: var(--text-label-lg-bold-lineHeight);
56
+ }
57
+
58
+ .muka-badge-number--lg {
59
+ height: var(--badge-number-size-lg);
60
+ min-width: var(--badge-number-size-lg);
61
+ padding: 0 var(--badge-number-padding-lg);
62
+ font-family: var(--text-label-2xl-bold-fontFamily);
63
+ font-weight: var(--text-label-2xl-bold-fontWeight);
64
+ font-size: var(--text-label-2xl-bold-fontSize);
65
+ line-height: var(--text-label-2xl-bold-lineHeight);
66
+ }
67
+
68
+ .muka-badge-number__label {
69
+ /*
70
+ * The badge sets a tight line-height for compact sizing, which would clip
71
+ * glyph descenders; give the label a roomier line-height. Vertical centering
72
+ * is unaffected because the badge height is fixed and content is centered.
73
+ */
74
+ line-height: normal;
75
+ }
76
+
77
+ /* Neutral variant */
78
+ .muka-badge-number--neutral {
79
+ background-color: var(--color-surface-level1);
80
+ color: var(--color-text-default-default);
81
+ }
82
+
83
+ /* Info variant */
84
+ .muka-badge-number--info {
85
+ background-color: var(--color-state-info-contrast);
86
+ color: var(--color-text-default-inverse);
87
+ }
88
+
89
+ /* Success variant */
90
+ .muka-badge-number--success {
91
+ background-color: var(--color-state-success-contrast);
92
+ color: var(--color-text-default-inverse);
93
+ }
94
+
95
+ /* Warning variant */
96
+ .muka-badge-number--warning {
97
+ background-color: var(--color-state-warning-contrast);
98
+ color: var(--color-text-default-inverse);
99
+ }
100
+
101
+ /* Error variant */
102
+ .muka-badge-number--error {
103
+ background-color: var(--color-state-error-contrast);
104
+ color: var(--color-text-default-inverse);
105
+ }
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BadgeNumber = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ require("./BadgeNumber.css");
6
+ const BadgeNumber = ({ children, variant = 'neutral', size = '2xs', className = '', 'aria-label': ariaLabel, ...props }) => {
7
+ const classes = [
8
+ 'muka-badge-number',
9
+ `muka-badge-number--${variant}`,
10
+ `muka-badge-number--${size}`,
11
+ className,
12
+ ]
13
+ .filter(Boolean)
14
+ .join(' ');
15
+ return ((0, jsx_runtime_1.jsx)("span", { className: classes, role: "status", "aria-label": ariaLabel, ...props, children: (0, jsx_runtime_1.jsx)("span", { className: "muka-badge-number__label", children: children }) }));
16
+ };
17
+ exports.BadgeNumber = BadgeNumber;
18
+ exports.default = exports.BadgeNumber;
19
+ //# sourceMappingURL=BadgeNumber.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BadgeNumber.js","sourceRoot":"","sources":["../../../../components/BadgeNumber/BadgeNumber.tsx"],"names":[],"mappings":";;;;AACA,6BAA2B;AAepB,MAAM,WAAW,GAA+B,CAAC,EACtD,QAAQ,EACR,OAAO,GAAG,SAAS,EACnB,IAAI,GAAG,KAAK,EACZ,SAAS,GAAG,EAAE,EACd,YAAY,EAAE,SAAS,EACvB,GAAG,KAAK,EACT,EAAE,EAAE;IACH,MAAM,OAAO,GAAG;QACd,mBAAmB;QACnB,sBAAsB,OAAO,EAAE;QAC/B,sBAAsB,IAAI,EAAE;QAC5B,SAAS;KACV;SACE,MAAM,CAAC,OAAO,CAAC;SACf,IAAI,CAAC,GAAG,CAAC,CAAC;IAEb,OAAO,CACL,iCAAM,SAAS,EAAE,OAAO,EAAE,IAAI,EAAC,QAAQ,gBAAa,SAAS,KAAM,KAAK,YACtE,iCAAM,SAAS,EAAC,0BAA0B,YAAE,QAAQ,GAAQ,GACvD,CACR,CAAC;AACJ,CAAC,CAAC;AAtBW,QAAA,WAAW,eAsBtB;AAEF,kBAAe,mBAAW,CAAC"}
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = exports.BadgeNumber = void 0;
7
+ var BadgeNumber_1 = require("./BadgeNumber");
8
+ Object.defineProperty(exports, "BadgeNumber", { enumerable: true, get: function () { return BadgeNumber_1.BadgeNumber; } });
9
+ var BadgeNumber_2 = require("./BadgeNumber");
10
+ Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(BadgeNumber_2).default; } });
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../components/BadgeNumber/index.ts"],"names":[],"mappings":";;;;;;AAAA,6CAAmE;AAA1D,0GAAA,WAAW,OAAA;AACpB,6CAAwC;AAA/B,uHAAA,OAAO,OAAA"}
@@ -0,0 +1,324 @@
1
+ /* ChatMessage Component Styles */
2
+
3
+ .muka-chat-message {
4
+ display: flex;
5
+ flex-direction: column;
6
+ width: 100%;
7
+ max-width: 100%;
8
+ }
9
+
10
+ /* ─── Row: avatar rail + bubble ────────────────────────── */
11
+
12
+ .muka-chat-message__row {
13
+ display: grid;
14
+ grid-template-columns: minmax(0, 1fr);
15
+ grid-template-areas: 'bubble';
16
+ column-gap: var(--chatbubble-row-gap);
17
+ width: 100%;
18
+ }
19
+
20
+ .muka-chat-message--has-avatar .muka-chat-message__row {
21
+ grid-template-columns: auto minmax(0, 1fr);
22
+ grid-template-areas: 'rail bubble';
23
+ }
24
+
25
+ .muka-chat-message__rail {
26
+ grid-area: rail;
27
+ /* Sits on the bubble's baseline (Figma 5355:44091) */
28
+ align-self: end;
29
+ display: flex;
30
+ justify-content: center;
31
+ min-width: var(--chatbubble-avatar-size);
32
+ }
33
+
34
+ /*
35
+ * The Small size in Figma (5373:44702) halves the avatar to 32px and tightens
36
+ * the gap to the bubble. Size the avatar itself, not just the rail, so the
37
+ * bubbles keep their alignment. The header row keeps its own gap.
38
+ */
39
+ @media (max-width: 1023px) {
40
+ .muka-chat-message__row {
41
+ column-gap: var(--chatbubble-row-gap-compact);
42
+ }
43
+
44
+ .muka-chat-message__rail {
45
+ min-width: var(--chatbubble-avatar-size-compact);
46
+ }
47
+
48
+ /* Outweighs the avatar's own size class, which sets width/height directly */
49
+ .muka-chat-message .muka-chat-message__rail > * {
50
+ width: var(--chatbubble-avatar-size-compact);
51
+ height: var(--chatbubble-avatar-size-compact);
52
+ }
53
+ }
54
+
55
+ /* ─── Bubble surface ───────────────────────────────────── */
56
+
57
+ .muka-chat-message__bubble {
58
+ grid-area: bubble;
59
+ /*
60
+ * Width follows the content: a single line hugs, and once the text wraps the
61
+ * bubble fills to the shared max width. Robust to string or rich children —
62
+ * no length measuring needed (Figma `Text length` on 5355:44091).
63
+ */
64
+ width: fit-content;
65
+ max-width: var(--chatbubble-max-width);
66
+ position: relative;
67
+ display: flex;
68
+ flex-direction: column;
69
+ gap: var(--chatbubble-gap);
70
+ padding: var(--chatbubble-padding-block) var(--chatbubble-padding-inline);
71
+ border-radius: var(--chatbubble-radius);
72
+ border: var(--border-width-regular) solid transparent;
73
+ box-shadow: var(--shadow-level2);
74
+ word-break: break-word;
75
+ }
76
+
77
+ /* Media, an embed or an action stack always run the full bubble width. */
78
+ .muka-chat-message--has-blocks .muka-chat-message__bubble {
79
+ width: 100%;
80
+ }
81
+
82
+ .muka-chat-message--own .muka-chat-message__bubble {
83
+ justify-self: end;
84
+ }
85
+
86
+ .muka-chat-message--own .muka-chat-message__bubble {
87
+ background-color: var(--chatbubble-color-own-background);
88
+ border-color: var(--chatbubble-color-own-border);
89
+ color: var(--chatbubble-color-own-foreground);
90
+ }
91
+
92
+ .muka-chat-message--peer .muka-chat-message__bubble {
93
+ background-color: var(--chatbubble-color-peer-background);
94
+ border-color: var(--chatbubble-color-peer-border);
95
+ color: var(--chatbubble-color-peer-foreground);
96
+ }
97
+
98
+ .muka-chat-message--agent .muka-chat-message__bubble {
99
+ background-color: var(--chatbubble-color-agent-background);
100
+ border-color: var(--chatbubble-color-agent-border);
101
+ color: var(--chatbubble-color-agent-foreground);
102
+ }
103
+
104
+ /* ─── Header row (author · meta · time · badge) ────────── */
105
+
106
+ .muka-chat-message__header {
107
+ display: flex;
108
+ flex-flow: row wrap;
109
+ align-items: center;
110
+ gap: var(--chatbubble-row-gap);
111
+ }
112
+
113
+ .muka-chat-message__author {
114
+ font-family: var(--text-body-base-bold-fontFamily);
115
+ font-weight: var(--text-body-base-bold-fontWeight);
116
+ font-size: var(--text-body-base-bold-fontSize);
117
+ line-height: var(--text-body-base-bold-lineHeight);
118
+ }
119
+
120
+ .muka-chat-message__author-meta {
121
+ /* Inherits the variant's body colour from the bubble */
122
+ color: inherit;
123
+ font-family: var(--text-body-base-regular-fontFamily);
124
+ font-weight: var(--text-body-base-regular-fontWeight);
125
+ font-size: var(--text-body-base-regular-fontSize);
126
+ line-height: var(--text-body-base-regular-lineHeight);
127
+ }
128
+
129
+ .muka-chat-message__badge {
130
+ display: inline-flex;
131
+ align-items: center;
132
+ }
133
+
134
+ /*
135
+ * Keep the first line of content clear of the absolutely positioned menu
136
+ * button in the bubble's top-right corner.
137
+ */
138
+ .muka-chat-message--has-menu .muka-chat-message__header,
139
+ .muka-chat-message--has-menu.muka-chat-message--no-header .muka-chat-message__message {
140
+ padding-right: var(--spacing-10);
141
+ }
142
+
143
+ /* …and the last line clear of the inset timestamp in the bottom-right corner */
144
+ .muka-chat-message--has-timestamp .muka-chat-message__message {
145
+ padding-right: var(--spacing-10);
146
+ }
147
+
148
+ /* ─── Body ─────────────────────────────────────────────── */
149
+
150
+ .muka-chat-message__body {
151
+ display: flex;
152
+ flex-direction: column;
153
+ gap: var(--chatbubble-gap);
154
+ min-width: 0;
155
+ }
156
+
157
+ .muka-chat-message__media {
158
+ min-width: 0;
159
+ }
160
+
161
+ .muka-chat-message__message {
162
+ font-family: var(--text-body-base-regular-fontFamily);
163
+ font-weight: var(--text-body-base-regular-fontWeight);
164
+ font-size: var(--text-body-base-regular-fontSize);
165
+ line-height: var(--text-body-base-regular-lineHeight);
166
+ white-space: pre-wrap;
167
+ word-break: break-word;
168
+ }
169
+
170
+ /* Empty message block should not add a gap of its own */
171
+ .muka-chat-message__message:empty {
172
+ display: none;
173
+ }
174
+
175
+ /* ─── Embedded card ────────────────────────────────────── */
176
+
177
+ .muka-chat-message__embed {
178
+ position: relative;
179
+ display: flex;
180
+ flex-direction: column;
181
+ gap: var(--chatbubble-embed-gap);
182
+ /* The card is inset from the blocks above and below it (Figma 5289:40562) */
183
+ margin-block: var(--chatbubble-embed-margin-block);
184
+ padding: var(--chatbubble-embed-padding-block) var(--chatbubble-embed-padding-inline);
185
+ border-radius: var(--chatbubble-embed-radius);
186
+ border: var(--border-width-regular) solid transparent;
187
+ }
188
+
189
+ /*
190
+ * The embed sits on the raised surface of its author's role, one step apart
191
+ * from the bubble it is nested in, and reuses that role's border colour.
192
+ */
193
+ .muka-chat-message--own .muka-chat-message__embed {
194
+ background-color: var(--chatbubble-embed-color-own-background);
195
+ border-color: var(--chatbubble-embed-color-own-border);
196
+ color: var(--chatbubble-embed-color-own-foreground);
197
+ }
198
+
199
+ .muka-chat-message--peer .muka-chat-message__embed {
200
+ background-color: var(--chatbubble-embed-color-peer-background);
201
+ border-color: var(--chatbubble-embed-color-peer-border);
202
+ color: var(--chatbubble-embed-color-peer-foreground);
203
+ }
204
+
205
+ .muka-chat-message--agent .muka-chat-message__embed {
206
+ background-color: var(--chatbubble-embed-color-agent-background);
207
+ border-color: var(--chatbubble-embed-color-agent-border);
208
+ color: var(--chatbubble-embed-color-agent-foreground);
209
+ }
210
+
211
+ .muka-chat-message__embed-content {
212
+ display: flex;
213
+ flex-direction: column;
214
+ gap: var(--chatbubble-embed-gap);
215
+ min-width: 0;
216
+ }
217
+
218
+ .muka-chat-message__embed-copy {
219
+ position: absolute;
220
+ top: var(--chatbubble-embed-padding-block);
221
+ right: var(--chatbubble-embed-padding-inline);
222
+ }
223
+
224
+ /* ─── Stacked full-width action buttons ────────────────── */
225
+
226
+ .muka-chat-message__action-stack {
227
+ display: flex;
228
+ flex-direction: column;
229
+ gap: var(--chatbubble-action-stack-gap);
230
+ }
231
+
232
+ /* ─── Inset timestamp ──────────────────────────────────── */
233
+
234
+ /*
235
+ * Every author puts its timestamp in the bubble's bottom-right corner, below
236
+ * the message — never in the header row (Figma 5355:44091).
237
+ */
238
+
239
+ .muka-chat-message__timestamp {
240
+ color: var(--chatbubble-color-timestamp);
241
+ font-family: var(--text-body-xs-regular-fontFamily);
242
+ font-weight: var(--text-body-xs-regular-fontWeight);
243
+ font-size: var(--text-body-xs-regular-fontSize);
244
+ line-height: var(--text-body-xs-regular-lineHeight);
245
+ white-space: nowrap;
246
+ }
247
+
248
+ /*
249
+ * Pinned to the corner rather than stacked below the message, so a one-line
250
+ * message stays one line tall. The message reserves the width it needs.
251
+ */
252
+ .muka-chat-message__timestamp--inset {
253
+ position: absolute;
254
+ right: var(--spacing-2);
255
+ bottom: var(--spacing-1);
256
+ }
257
+
258
+ /*
259
+ * When the last block in the body is media, an embed or an action stack (not
260
+ * trailing text), it runs the full width, so reserve a line below for the inset
261
+ * timestamp. A message that ends in text clears the corner inline instead (see
262
+ * `__message` padding-right above), so it needs no extra bottom space.
263
+ */
264
+ .muka-chat-message--has-timestamp.muka-chat-message--trailing-block .muka-chat-message__body {
265
+ padding-bottom: var(--text-body-xs-regular-lineHeight);
266
+ }
267
+
268
+ /* ─── Menu affordance ──────────────────────────────────── */
269
+
270
+ /*
271
+ * Hidden at rest. Revealed on hover on pointer devices, on keyboard focus
272
+ * everywhere, and pinned while its menu is open. On touch the equivalent
273
+ * affordance is a long-press on the bubble, which opens an ActionSheet.
274
+ */
275
+ .muka-chat-message__menu {
276
+ position: absolute;
277
+ top: var(--spacing-1);
278
+ right: var(--spacing-1);
279
+ opacity: 0;
280
+ pointer-events: none;
281
+ }
282
+
283
+ .muka-chat-message__menu:focus-within,
284
+ .muka-chat-message--menu-open .muka-chat-message__menu {
285
+ opacity: 1;
286
+ pointer-events: auto;
287
+ }
288
+
289
+ @media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
290
+ .muka-chat-message__bubble:hover .muka-chat-message__menu {
291
+ opacity: 1;
292
+ pointer-events: auto;
293
+ }
294
+ }
295
+
296
+ /* Suppress iOS Safari's own callout so the long-press sheet can take over */
297
+ @media (pointer: coarse) {
298
+ .muka-chat-message--has-menu .muka-chat-message__bubble {
299
+ -webkit-touch-callout: none;
300
+ }
301
+ }
302
+
303
+ /* ─── Print ────────────────────────────────────────────── */
304
+
305
+ @media print {
306
+ .muka-chat-message__bubble {
307
+ box-shadow: none;
308
+ break-inside: avoid;
309
+ print-color-adjust: exact;
310
+ -webkit-print-color-adjust: exact;
311
+ }
312
+
313
+ .muka-chat-message__embed {
314
+ break-inside: avoid;
315
+ print-color-adjust: exact;
316
+ -webkit-print-color-adjust: exact;
317
+ }
318
+
319
+ .muka-chat-message__menu,
320
+ .muka-chat-message__embed-copy,
321
+ .muka-chat-message__action-stack {
322
+ display: none;
323
+ }
324
+ }