@revikornmann/muka-ui 0.12.0 → 0.13.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 (109) 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/{ChatBubble/ChatBubble.css → ChatMessage/ChatMessage.css} +133 -105
  9. package/dist/cjs/components/ChatMessage/ChatMessage.js +141 -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/{ChatBubble/ChatBubble.css → ChatMessage/ChatMessage.css} +133 -105
  34. package/dist/esm/components/ChatMessage/ChatMessage.js +137 -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/{ChatBubble.css → ChatMessage.css} +133 -105
  54. package/dist/styles/components/ChatMessageStack.css +51 -0
  55. package/dist/styles/components/ChatPhotoGrid.css +8 -2
  56. package/dist/styles/index.css +1672 -1449
  57. package/dist/styles/muka-dark.css +1672 -1449
  58. package/dist/styles/muka-light.css +1672 -1449
  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 +1671 -1448
  70. package/dist/styles/wireframe-light.css +1671 -1448
  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 +130 -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.js +0 -37
  99. package/dist/cjs/components/ChatBubble/ChatBubble.js.map +0 -1
  100. package/dist/cjs/components/ChatBubble/index.js +0 -6
  101. package/dist/cjs/components/ChatBubble/index.js.map +0 -1
  102. package/dist/esm/components/ChatBubble/ChatBubble.js +0 -33
  103. package/dist/esm/components/ChatBubble/ChatBubble.js.map +0 -1
  104. package/dist/esm/components/ChatBubble/index.js +0 -2
  105. package/dist/esm/components/ChatBubble/index.js.map +0 -1
  106. package/dist/types/components/ChatBubble/ChatBubble.d.ts +0 -85
  107. package/dist/types/components/ChatBubble/ChatBubble.d.ts.map +0 -1
  108. package/dist/types/components/ChatBubble/index.d.ts +0 -2
  109. 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"}
@@ -1,89 +1,107 @@
1
- /* ChatBubble Component Styles */
1
+ /* ChatMessage Component Styles */
2
2
 
3
- .muka-chat-bubble {
3
+ .muka-chat-message {
4
4
  display: flex;
5
5
  flex-direction: column;
6
6
  width: 100%;
7
7
  max-width: 100%;
8
8
  }
9
9
 
10
- /* ─── Row: avatar rail + bubble + action bar ───────────────
11
- *
12
- * A two-row grid rather than a flex column, so the avatar bottom-aligns to the
13
- * bubble itself and not to the action bar underneath it (Figma 5223:8520).
14
- */
10
+ /* ─── Row: avatar rail + bubble ────────────────────────── */
15
11
 
16
- .muka-chat-bubble__row {
12
+ .muka-chat-message__row {
17
13
  display: grid;
18
14
  grid-template-columns: minmax(0, 1fr);
19
- grid-template-areas:
20
- 'bubble'
21
- 'actions';
15
+ grid-template-areas: 'bubble';
22
16
  column-gap: var(--chatbubble-row-gap);
23
- row-gap: var(--chatbubble-gap);
24
17
  width: 100%;
25
18
  }
26
19
 
27
- .muka-chat-bubble--has-avatar .muka-chat-bubble__row {
20
+ .muka-chat-message--has-avatar .muka-chat-message__row {
28
21
  grid-template-columns: auto minmax(0, 1fr);
29
- grid-template-areas:
30
- 'rail bubble'
31
- '. actions';
22
+ grid-template-areas: 'rail bubble';
32
23
  }
33
24
 
34
- .muka-chat-bubble--own.muka-chat-bubble--has-avatar .muka-chat-bubble__row {
25
+ .muka-chat-message--own.muka-chat-message--has-avatar .muka-chat-message__row {
35
26
  grid-template-columns: minmax(0, 1fr) auto;
36
- grid-template-areas:
37
- 'bubble rail'
38
- 'actions .';
27
+ grid-template-areas: 'bubble rail';
39
28
  }
40
29
 
41
- .muka-chat-bubble__rail {
30
+ .muka-chat-message__rail {
42
31
  grid-area: rail;
43
- /* Sits on the bubble's baseline, above the action bar */
32
+ /* Sits on the bubble's baseline (Figma 5355:44091) */
44
33
  align-self: end;
45
34
  display: flex;
46
35
  justify-content: center;
47
36
  min-width: var(--chatbubble-avatar-size);
48
37
  }
49
38
 
39
+ /*
40
+ * The Small size in Figma (5373:44702) halves the avatar to 32px and tightens
41
+ * the gap to the bubble. Size the avatar itself, not just the rail, so the
42
+ * bubbles keep their alignment. The header row keeps its own gap.
43
+ */
44
+ @media (max-width: 1023px) {
45
+ .muka-chat-message__row {
46
+ column-gap: var(--chatbubble-row-gap-compact);
47
+ }
48
+
49
+ .muka-chat-message__rail {
50
+ min-width: var(--chatbubble-avatar-size-compact);
51
+ }
52
+
53
+ /* Outweighs the avatar's own size class, which sets width/height directly */
54
+ .muka-chat-message .muka-chat-message__rail > * {
55
+ width: var(--chatbubble-avatar-size-compact);
56
+ height: var(--chatbubble-avatar-size-compact);
57
+ }
58
+ }
59
+
50
60
  /* ─── Bubble surface ───────────────────────────────────── */
51
61
 
52
- .muka-chat-bubble__bubble {
62
+ .muka-chat-message__bubble {
53
63
  grid-area: bubble;
54
64
  max-width: var(--chatbubble-max-width);
55
65
  position: relative;
56
66
  display: flex;
57
67
  flex-direction: column;
58
68
  gap: var(--chatbubble-gap);
59
- width: 100%;
60
- padding: var(--chatbubble-padding);
69
+ padding: var(--chatbubble-padding-block) var(--chatbubble-padding-inline);
61
70
  border-radius: var(--chatbubble-radius);
62
71
  border: var(--border-width-regular) solid transparent;
72
+ box-shadow: var(--shadow-level2);
63
73
  word-break: break-word;
64
74
  }
65
75
 
66
- .muka-chat-bubble--own .muka-chat-bubble__bubble,
67
- .muka-chat-bubble--own .muka-chat-bubble__actions {
76
+ /*
77
+ * Length axis (Figma `Text length` on 5355:44091): short messages hug their
78
+ * content, long ones fill the row up to the shared max width.
79
+ */
80
+ .muka-chat-message--long .muka-chat-message__bubble {
81
+ width: 100%;
82
+ }
83
+
84
+ .muka-chat-message--short .muka-chat-message__bubble {
85
+ width: fit-content;
86
+ }
87
+
88
+ .muka-chat-message--own .muka-chat-message__bubble {
68
89
  justify-self: end;
69
90
  }
70
91
 
71
- .muka-chat-bubble--own .muka-chat-bubble__bubble {
92
+ .muka-chat-message--own .muka-chat-message__bubble {
72
93
  background-color: var(--chatbubble-color-own-background);
73
94
  border-color: var(--chatbubble-color-own-border);
74
95
  color: var(--chatbubble-color-own-foreground);
75
- /* Room for the inset timestamp in the bottom-right corner */
76
- padding-right: var(--spacing-6);
77
96
  }
78
97
 
79
- .muka-chat-bubble--peer .muka-chat-bubble__bubble {
98
+ .muka-chat-message--peer .muka-chat-message__bubble {
80
99
  background-color: var(--chatbubble-color-peer-background);
81
100
  border-color: var(--chatbubble-color-peer-border);
82
101
  color: var(--chatbubble-color-peer-foreground);
83
- box-shadow: var(--shadow-level2);
84
102
  }
85
103
 
86
- .muka-chat-bubble--agent .muka-chat-bubble__bubble {
104
+ .muka-chat-message--agent .muka-chat-message__bubble {
87
105
  background-color: var(--chatbubble-color-agent-background);
88
106
  border-color: var(--chatbubble-color-agent-border);
89
107
  color: var(--chatbubble-color-agent-foreground);
@@ -91,21 +109,21 @@
91
109
 
92
110
  /* ─── Header row (author · meta · time · badge) ────────── */
93
111
 
94
- .muka-chat-bubble__header {
112
+ .muka-chat-message__header {
95
113
  display: flex;
96
114
  flex-flow: row wrap;
97
115
  align-items: center;
98
116
  gap: var(--chatbubble-row-gap);
99
117
  }
100
118
 
101
- .muka-chat-bubble__author {
119
+ .muka-chat-message__author {
102
120
  font-family: var(--text-body-base-bold-fontFamily);
103
121
  font-weight: var(--text-body-base-bold-fontWeight);
104
122
  font-size: var(--text-body-base-bold-fontSize);
105
123
  line-height: var(--text-body-base-bold-lineHeight);
106
124
  }
107
125
 
108
- .muka-chat-bubble__author-meta {
126
+ .muka-chat-message__author-meta {
109
127
  /* Inherits the variant's body colour from the bubble */
110
128
  color: inherit;
111
129
  font-family: var(--text-body-base-regular-fontFamily);
@@ -114,7 +132,7 @@
114
132
  line-height: var(--text-body-base-regular-lineHeight);
115
133
  }
116
134
 
117
- .muka-chat-bubble__badge {
135
+ .muka-chat-message__badge {
118
136
  display: inline-flex;
119
137
  align-items: center;
120
138
  }
@@ -123,30 +141,30 @@
123
141
  * Keep the first line of content clear of the absolutely positioned menu
124
142
  * button in the bubble's top-right corner.
125
143
  */
126
- .muka-chat-bubble--has-menu .muka-chat-bubble__header,
127
- .muka-chat-bubble--has-menu.muka-chat-bubble--no-header .muka-chat-bubble__message {
128
- padding-right: var(--spacing-6);
144
+ .muka-chat-message--has-menu .muka-chat-message__header,
145
+ .muka-chat-message--has-menu.muka-chat-message--no-header .muka-chat-message__message {
146
+ padding-right: var(--spacing-10);
147
+ }
148
+
149
+ /* …and the last line clear of the inset timestamp in the bottom-right corner */
150
+ .muka-chat-message--has-timestamp .muka-chat-message__message {
151
+ padding-right: var(--spacing-10);
129
152
  }
130
153
 
131
154
  /* ─── Body ─────────────────────────────────────────────── */
132
155
 
133
- .muka-chat-bubble__body {
156
+ .muka-chat-message__body {
134
157
  display: flex;
135
158
  flex-direction: column;
136
159
  gap: var(--chatbubble-gap);
137
160
  min-width: 0;
138
161
  }
139
162
 
140
- /* The agent balloon spaces its blocks further apart (Figma 5223:8520) */
141
- .muka-chat-bubble--agent .muka-chat-bubble__body {
142
- gap: var(--chatbubble-body-gap);
143
- }
144
-
145
- .muka-chat-bubble__media {
163
+ .muka-chat-message__media {
146
164
  min-width: 0;
147
165
  }
148
166
 
149
- .muka-chat-bubble__message {
167
+ .muka-chat-message__message {
150
168
  font-family: var(--text-body-base-regular-fontFamily);
151
169
  font-weight: var(--text-body-base-regular-fontWeight);
152
170
  font-size: var(--text-body-base-regular-fontSize);
@@ -156,18 +174,20 @@
156
174
  }
157
175
 
158
176
  /* Empty message block should not add a gap of its own */
159
- .muka-chat-bubble__message:empty {
177
+ .muka-chat-message__message:empty {
160
178
  display: none;
161
179
  }
162
180
 
163
181
  /* ─── Embedded card ────────────────────────────────────── */
164
182
 
165
- .muka-chat-bubble__embed {
183
+ .muka-chat-message__embed {
166
184
  position: relative;
167
185
  display: flex;
168
186
  flex-direction: column;
169
187
  gap: var(--chatbubble-embed-gap);
170
- padding: var(--chatbubble-embed-padding);
188
+ /* The card is inset from the blocks above and below it (Figma 5289:40562) */
189
+ margin-block: var(--chatbubble-embed-margin-block);
190
+ padding: var(--chatbubble-embed-padding-block) var(--chatbubble-embed-padding-inline);
171
191
  border-radius: var(--chatbubble-embed-radius);
172
192
  border: var(--border-width-regular) solid transparent;
173
193
  }
@@ -176,125 +196,133 @@
176
196
  * The embed sits on the raised surface of its author's role, one step apart
177
197
  * from the bubble it is nested in, and reuses that role's border colour.
178
198
  */
179
- .muka-chat-bubble--own .muka-chat-bubble__embed {
199
+ .muka-chat-message--own .muka-chat-message__embed {
180
200
  background-color: var(--chatbubble-embed-color-own-background);
181
201
  border-color: var(--chatbubble-embed-color-own-border);
182
202
  color: var(--chatbubble-embed-color-own-foreground);
183
203
  }
184
204
 
185
- .muka-chat-bubble--peer .muka-chat-bubble__embed {
205
+ .muka-chat-message--peer .muka-chat-message__embed {
186
206
  background-color: var(--chatbubble-embed-color-peer-background);
187
207
  border-color: var(--chatbubble-embed-color-peer-border);
188
208
  color: var(--chatbubble-embed-color-peer-foreground);
189
209
  }
190
210
 
191
- .muka-chat-bubble--agent .muka-chat-bubble__embed {
211
+ .muka-chat-message--agent .muka-chat-message__embed {
192
212
  background-color: var(--chatbubble-embed-color-agent-background);
193
213
  border-color: var(--chatbubble-embed-color-agent-border);
194
214
  color: var(--chatbubble-embed-color-agent-foreground);
195
215
  }
196
216
 
197
- .muka-chat-bubble__embed-content {
217
+ .muka-chat-message__embed-content {
198
218
  display: flex;
199
219
  flex-direction: column;
200
220
  gap: var(--chatbubble-embed-gap);
201
221
  min-width: 0;
202
222
  }
203
223
 
204
- .muka-chat-bubble__embed-copy {
224
+ .muka-chat-message__embed-copy {
205
225
  position: absolute;
206
- top: var(--chatbubble-embed-padding);
207
- right: var(--chatbubble-embed-padding);
226
+ top: var(--chatbubble-embed-padding-block);
227
+ right: var(--chatbubble-embed-padding-inline);
208
228
  }
209
229
 
210
230
  /* ─── Stacked full-width action buttons ────────────────── */
211
231
 
212
- .muka-chat-bubble__action-stack {
232
+ .muka-chat-message__action-stack {
213
233
  display: flex;
214
234
  flex-direction: column;
215
235
  gap: var(--chatbubble-action-stack-gap);
216
236
  }
217
237
 
218
- /* ─── Inset timestamp (user variant) ───────────────────── */
238
+ /* ─── Inset timestamp ──────────────────────────────────── */
239
+
240
+ /*
241
+ * Every author puts its timestamp in the bubble's bottom-right corner, below
242
+ * the message — never in the header row (Figma 5355:44091).
243
+ */
219
244
 
220
- .muka-chat-bubble__timestamp {
245
+ .muka-chat-message__timestamp {
221
246
  color: var(--chatbubble-color-timestamp);
222
- font-family: var(--text-body-sm-regular-fontFamily);
223
- font-weight: var(--text-body-sm-regular-fontWeight);
224
- font-size: var(--text-body-sm-regular-fontSize);
225
- line-height: var(--text-body-sm-regular-lineHeight);
247
+ font-family: var(--text-body-xs-regular-fontFamily);
248
+ font-weight: var(--text-body-xs-regular-fontWeight);
249
+ font-size: var(--text-body-xs-regular-fontSize);
250
+ line-height: var(--text-body-xs-regular-lineHeight);
226
251
  white-space: nowrap;
227
252
  }
228
253
 
229
- .muka-chat-bubble__timestamp--inset {
230
- align-self: flex-end;
254
+ /*
255
+ * Pinned to the corner rather than stacked below the message, so a one-line
256
+ * message stays one line tall. The message reserves the width it needs.
257
+ */
258
+ .muka-chat-message__timestamp--inset {
259
+ position: absolute;
260
+ right: var(--spacing-2);
261
+ bottom: var(--spacing-1);
262
+ }
263
+
264
+ /*
265
+ * Media, an embed or an action stack run the full width of the bubble, so the
266
+ * corner the timestamp sits in has to be cleared for it.
267
+ */
268
+ .muka-chat-message--has-timestamp.muka-chat-message--has-blocks .muka-chat-message__body {
269
+ padding-bottom: var(--text-body-xs-regular-lineHeight);
231
270
  }
232
271
 
233
272
  /* ─── Menu affordance ──────────────────────────────────── */
234
273
 
235
- .muka-chat-bubble__menu {
274
+ /*
275
+ * Hidden at rest. Revealed on hover on pointer devices, on keyboard focus
276
+ * everywhere, and pinned while its menu is open. On touch the equivalent
277
+ * affordance is a long-press on the bubble, which opens an ActionSheet.
278
+ */
279
+ .muka-chat-message__menu {
236
280
  position: absolute;
237
281
  top: var(--spacing-1);
238
282
  right: var(--spacing-1);
283
+ opacity: 0;
284
+ pointer-events: none;
239
285
  }
240
286
 
241
- /* ─── Meta action row (below the bubble) ───────────────── */
242
-
243
- .muka-chat-bubble__actions {
244
- grid-area: actions;
245
- max-width: var(--chatbubble-max-width);
246
- display: flex;
247
- align-items: center;
248
- gap: 0;
249
- }
250
-
251
- .muka-chat-bubble--own .muka-chat-bubble__actions,
252
- .muka-chat-bubble--agent .muka-chat-bubble__actions {
253
- justify-content: flex-end;
287
+ .muka-chat-message__menu:focus-within,
288
+ .muka-chat-message--menu-open .muka-chat-message__menu {
289
+ opacity: 1;
290
+ pointer-events: auto;
254
291
  }
255
292
 
256
- /*
257
- * The meta row uses 32px icon buttons per the design. Expand the pointer/touch
258
- * target to the 44px WCAG 2.1 AA minimum without changing the visual size.
259
- */
260
- .muka-chat-bubble__actions .muka-button--icon-only {
261
- position: relative;
293
+ @media (hover: hover) and (pointer: fine) and (min-width: 1024px) {
294
+ .muka-chat-message__bubble:hover .muka-chat-message__menu {
295
+ opacity: 1;
296
+ pointer-events: auto;
297
+ }
262
298
  }
263
299
 
264
- .muka-chat-bubble__actions .muka-button--icon-only::after {
265
- content: '';
266
- position: absolute;
267
- top: 50%;
268
- left: 50%;
269
- width: 44px;
270
- height: 44px;
271
- transform: translate(-50%, -50%);
300
+ /* Suppress iOS Safari's own callout so the long-press sheet can take over */
301
+ @media (pointer: coarse) {
302
+ .muka-chat-message--has-menu .muka-chat-message__bubble {
303
+ -webkit-touch-callout: none;
304
+ }
272
305
  }
273
306
 
274
307
  /* ─── Print ────────────────────────────────────────────── */
275
308
 
276
309
  @media print {
277
- .muka-chat-bubble__bubble {
310
+ .muka-chat-message__bubble {
278
311
  box-shadow: none;
279
312
  break-inside: avoid;
280
313
  print-color-adjust: exact;
281
314
  -webkit-print-color-adjust: exact;
282
315
  }
283
316
 
284
- .muka-chat-bubble__embed {
317
+ .muka-chat-message__embed {
285
318
  break-inside: avoid;
286
319
  print-color-adjust: exact;
287
320
  -webkit-print-color-adjust: exact;
288
321
  }
289
322
 
290
- .muka-chat-bubble__menu,
291
- .muka-chat-bubble__actions,
292
- .muka-chat-bubble__embed-copy,
293
- .muka-chat-bubble__action-stack {
323
+ .muka-chat-message__menu,
324
+ .muka-chat-message__embed-copy,
325
+ .muka-chat-message__action-stack {
294
326
  display: none;
295
327
  }
296
-
297
- .muka-chat-bubble__column {
298
- max-width: 100%;
299
- }
300
328
  }